libpromeki 1.0.0-alpha
PROfessional MEdia toolKIt
 
Loading...
Searching...
No Matches
layout.h
Go to the documentation of this file.
1
8#pragma once
9
10
11#include <promeki/config.h>
12#if PROMEKI_ENABLE_CORE
13#include <promeki/namespace.h>
14#include <promeki/objectbase.h>
15#include <promeki/rect.h>
16#include <promeki/size2d.h>
17#include <promeki/list.h>
18#include <promeki/map.h>
19
20PROMEKI_NAMESPACE_BEGIN
21
22class Widget;
23
34class Layout : public ObjectBase {
35 PROMEKI_OBJECT(Layout, ObjectBase)
36 public:
37 Layout(ObjectBase *parent = nullptr);
38 virtual ~Layout();
39
41 virtual void addWidget(Widget *widget);
42
44 void removeWidget(Widget *widget);
45
47 virtual void addLayout(Layout *layout);
48
50 void setMargins(int top, int right, int bottom, int left);
51
53 void setMargins(int margin) { setMargins(margin, margin, margin, margin); }
54
56 void setSpacing(int spacing) { _spacing = spacing; }
57
59 int spacing() const { return _spacing; }
60
62 void margins(int &top, int &right, int &bottom, int &left) const {
63 top = _marginTop;
64 right = _marginRight;
65 bottom = _marginBottom;
66 left = _marginLeft;
67 }
68
73 virtual void calculateLayout(const Rect2Di32 &available) = 0;
74
78 virtual Size2Di32 sizeHint() const;
79
81 const List<Widget *> &widgets() const { return _widgets; }
82
84 const List<Layout *> &layouts() const { return _layouts; }
85
86 protected:
90 Rect2Di32 contentRect(const Rect2Di32 &available) const;
91
92 List<Widget *> _widgets;
93 List<Layout *> _layouts;
94
95 private:
96 int _spacing = 0;
97 int _marginTop = 0;
98 int _marginRight = 0;
99 int _marginBottom = 0;
100 int _marginLeft = 0;
101};
102
107enum BoxDirection {
108 LeftToRight,
109 RightToLeft,
110 TopToBottom,
111 BottomToTop
112};
113
122class BoxLayout : public Layout {
123 PROMEKI_OBJECT(BoxLayout, Layout)
124 public:
130 BoxLayout(BoxDirection direction, ObjectBase *parent = nullptr);
131
133 BoxDirection direction() const { return _direction; }
134
136 void addWidget(Widget *widget) override;
137
139 void addLayout(Layout *layout) override;
140
142 void addStretch(int factor = 1);
143
145 void setStretch(int index, int factor);
146
148 void calculateLayout(const Rect2Di32 &available) override;
149
151 Size2Di32 sizeHint() const override;
152
153 private:
155 struct Item {
156 enum Type {
157 WidgetItem,
158 LayoutItem,
159 StretchItem
160 };
161 Type type;
162 Widget *widget = nullptr;
163 Layout *layout = nullptr;
164 int stretchFactor = 0;
165 };
166
167 BoxDirection _direction;
168 List<Item> _items;
169};
170
175class HBoxLayout : public BoxLayout {
176 PROMEKI_OBJECT(HBoxLayout, BoxLayout)
177 public:
178 HBoxLayout(ObjectBase *parent = nullptr) : BoxLayout(LeftToRight, parent) {}
179};
180
185class VBoxLayout : public BoxLayout {
186 PROMEKI_OBJECT(VBoxLayout, BoxLayout)
187 public:
188 VBoxLayout(ObjectBase *parent = nullptr) : BoxLayout(TopToBottom, parent) {}
189};
190
195class GridLayout : public Layout {
196 PROMEKI_OBJECT(GridLayout, Layout)
197 public:
198 GridLayout(ObjectBase *parent = nullptr);
199
200 // Bring the base-class single-arg addWidget(Widget*) back into
201 // scope so the row/col overload below doesn't hide it.
202 using Layout::addWidget;
203
207 void addWidget(Widget *widget, int row, int col, int rowSpan = 1, int colSpan = 1);
208
210 void setRowStretch(int row, int factor);
211
213 void setColumnStretch(int col, int factor);
214
216 void setRowMinimumHeight(int row, int height);
217
219 void setColumnMinimumWidth(int col, int width);
220
222 void calculateLayout(const Rect2Di32 &available) override;
223
224 private:
225 struct GridItem {
226 Widget *widget;
227 int row;
228 int col;
229 int rowSpan;
230 int colSpan;
231 };
232 List<GridItem> _items;
233 Map<int, int> _rowStretch;
234 Map<int, int> _colStretch;
235 Map<int, int> _rowMinHeight;
236 Map<int, int> _colMinWidth;
237 int _rowCount = 0;
238 int _colCount = 0;
239};
240
241PROMEKI_NAMESPACE_END
242
243#endif // PROMEKI_ENABLE_CORE