231 lines
7.7 KiB
C++
Executable File
231 lines
7.7 KiB
C++
Executable File
// ----------------------------------------------------------------------------
|
|
// - Open3D: www.open3d.org -
|
|
// ----------------------------------------------------------------------------
|
|
// Copyright (c) 2018-2023 www.open3d.org
|
|
// SPDX-License-Identifier: MIT
|
|
// ----------------------------------------------------------------------------
|
|
|
|
#pragma once
|
|
|
|
#include "open3d/visualization/gui/Widget.h"
|
|
|
|
namespace open3d {
|
|
namespace visualization {
|
|
namespace gui {
|
|
|
|
struct Margins {
|
|
int left;
|
|
int top;
|
|
int right;
|
|
int bottom;
|
|
|
|
/// Margins are specified in pixels, which are not the same size on all
|
|
/// monitors. It is best to use a multiple of
|
|
/// Window::GetTheme().fontSize to specify margins. Theme::fontSize,
|
|
/// represents 1em and is scaled according to the scaling factor of the
|
|
/// window. For example, 0.5em (that is, 0.5 * theme.fontSize) is typically
|
|
/// a good size for a margin.
|
|
Margins(); // all values zero
|
|
Margins(int px);
|
|
Margins(int horiz_px, int vert_px);
|
|
Margins(int left_px, int top_px, int right_px, int bottom_px);
|
|
|
|
/// Convenience function that returns left + right
|
|
int GetHoriz() const;
|
|
/// Convenience function that returns top + bottom
|
|
int GetVert() const;
|
|
};
|
|
|
|
/// Lays out widgets either horizontally or vertically.
|
|
/// Base class for Vert and Horiz.
|
|
class Layout1D : public Widget {
|
|
using Super = Widget;
|
|
|
|
public:
|
|
enum Dir { VERT, HORIZ };
|
|
|
|
static void debug_PrintPreferredSizes(Layout1D* layout,
|
|
const LayoutContext& context,
|
|
const Constraints& constraints,
|
|
int depth = 0);
|
|
|
|
/// Spacing is in pixels; see the comment in Margin(). 1em is typically
|
|
/// a good value for spacing.
|
|
Layout1D(Dir dir,
|
|
int spacing,
|
|
const Margins& margins,
|
|
const std::vector<std::shared_ptr<Widget>>& children);
|
|
virtual ~Layout1D();
|
|
|
|
int GetSpacing() const;
|
|
const Margins& GetMargins() const;
|
|
/// Sets spacing. Need to signal a relayout after calling (unless it is
|
|
/// before a layout that will happen, such as before adding as a child).
|
|
void SetSpacing(int spacing);
|
|
/// Sets margins. Need to signal a relayout after calling (unless it is
|
|
/// before a layout that will happen, such as before adding as a child).
|
|
void SetMargins(const Margins& margins);
|
|
|
|
Size CalcPreferredSize(const LayoutContext& context,
|
|
const Constraints& constraints) const override;
|
|
void Layout(const LayoutContext& context) override;
|
|
|
|
/// Adds a fixed number of pixels after the previously added widget.
|
|
void AddFixed(int size);
|
|
/// Adds a virtual widget that takes up as much space as possible.
|
|
/// This is useful for centering widgets: { stretch, w1, w2, stretch }
|
|
/// or for aligning widgets to one side or the other:
|
|
/// { stretch, ok, cancel }.
|
|
void AddStretch();
|
|
|
|
public:
|
|
class Fixed : public Widget {
|
|
public:
|
|
Fixed(int size, Dir dir);
|
|
Size CalcPreferredSize(const LayoutContext& context,
|
|
const Constraints& constraints) const override;
|
|
|
|
private:
|
|
int size_;
|
|
Dir dir_;
|
|
};
|
|
|
|
class Stretch : public Widget {
|
|
Size CalcPreferredSize(const LayoutContext& context,
|
|
const Constraints& constraints) const override;
|
|
};
|
|
|
|
protected:
|
|
int GetMinorAxisPreferredSize() const;
|
|
void SetMinorAxisPreferredSize(int size);
|
|
|
|
Margins& GetMutableMargins();
|
|
std::vector<std::shared_ptr<Widget>> GetVisibleChildren() const;
|
|
|
|
private:
|
|
struct Impl;
|
|
std::unique_ptr<Impl> impl_;
|
|
};
|
|
|
|
/// Lays out widgets vertically.
|
|
class Vert : public Layout1D {
|
|
public:
|
|
static std::shared_ptr<Layout1D::Fixed> MakeFixed(int size);
|
|
static std::shared_ptr<Layout1D::Stretch> MakeStretch();
|
|
|
|
Vert();
|
|
/// Spacing is in pixels; see the comment in Margin(). 1em is typically
|
|
/// a good value for spacing.
|
|
Vert(int spacing, const Margins& margins = Margins());
|
|
Vert(int spacing,
|
|
const Margins& margins,
|
|
const std::vector<std::shared_ptr<Widget>>& children);
|
|
virtual ~Vert();
|
|
|
|
int GetPreferredWidth() const;
|
|
void SetPreferredWidth(int w);
|
|
};
|
|
|
|
/// This is a vertical layout with a twisty + title that can be clicked on
|
|
/// to expand or collapse the layout. Collapsing the layout will hide all
|
|
/// the items and shrink the size of the layout to the height of the title.
|
|
class CollapsableVert : public Vert {
|
|
using Super = Vert;
|
|
|
|
public:
|
|
CollapsableVert(const char* text);
|
|
CollapsableVert(const char* text,
|
|
int spacing,
|
|
const Margins& margins = Margins());
|
|
virtual ~CollapsableVert();
|
|
|
|
/// You will need to call Window::SetNeedsLayout() after this.
|
|
/// (If you call this before the widnows is displayed everything
|
|
/// will work out fine, as layout will automatically be called when
|
|
/// the window is shown.)
|
|
void SetIsOpen(bool is_open);
|
|
|
|
/// Returns true if open and false if collapsed.
|
|
bool GetIsOpen();
|
|
|
|
FontId GetFontId() const;
|
|
void SetFontId(FontId font_id);
|
|
|
|
Size CalcPreferredSize(const LayoutContext& context,
|
|
const Constraints& constraints) const override;
|
|
void Layout(const LayoutContext& context) override;
|
|
Widget::DrawResult Draw(const DrawContext& context) override;
|
|
|
|
private:
|
|
struct Impl;
|
|
std::unique_ptr<Impl> impl_;
|
|
};
|
|
|
|
/// This a vertical layout that scrolls if it is smaller than its contents
|
|
class ScrollableVert : public Vert {
|
|
using Super = Vert;
|
|
|
|
public:
|
|
ScrollableVert();
|
|
ScrollableVert(int spacing, const Margins& margins = Margins());
|
|
ScrollableVert(int spacing,
|
|
const Margins& margins,
|
|
const std::vector<std::shared_ptr<Widget>>& children);
|
|
virtual ~ScrollableVert();
|
|
|
|
Widget::DrawResult Draw(const DrawContext& context) override;
|
|
|
|
private:
|
|
struct Impl;
|
|
std::unique_ptr<Impl> impl_;
|
|
};
|
|
|
|
/// Lays out widgets horizontally.
|
|
class Horiz : public Layout1D {
|
|
public:
|
|
static std::shared_ptr<Layout1D::Fixed> MakeFixed(int size);
|
|
static std::shared_ptr<Layout1D::Stretch> MakeStretch();
|
|
static std::shared_ptr<Horiz> MakeCentered(std::shared_ptr<Widget> w);
|
|
|
|
Horiz();
|
|
/// Spacing is in pixels; see the comment in Margin(). 1em is typically
|
|
/// a good value for spacing.
|
|
Horiz(int spacing, const Margins& margins = Margins());
|
|
Horiz(int spacing,
|
|
const Margins& margins,
|
|
const std::vector<std::shared_ptr<Widget>>& children);
|
|
~Horiz();
|
|
|
|
int GetPreferredHeight() const;
|
|
void SetPreferredHeight(int h);
|
|
};
|
|
|
|
/// Lays out widgets in a grid. The widgets are assigned to the next
|
|
/// horizontal column, and when all the columns in a row are used, a new
|
|
/// row will be created.
|
|
class VGrid : public Widget {
|
|
using Super = Widget;
|
|
|
|
public:
|
|
VGrid(int num_cols, int spacing = 0, const Margins& margins = Margins());
|
|
virtual ~VGrid();
|
|
|
|
int GetSpacing() const;
|
|
const Margins& GetMargins() const;
|
|
|
|
int GetPreferredWidth() const;
|
|
void SetPreferredWidth(int w);
|
|
|
|
Size CalcPreferredSize(const LayoutContext& context,
|
|
const Constraints& constraints) const override;
|
|
void Layout(const LayoutContext& context) override;
|
|
|
|
private:
|
|
struct Impl;
|
|
std::unique_ptr<Impl> impl_;
|
|
};
|
|
|
|
} // namespace gui
|
|
} // namespace visualization
|
|
} // namespace open3d
|