ScummVM API documentation
ThemeLayout.h
1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program. If not, see <http://www.gnu.org/licenses/>.
19  *
20  */
21 
22 #ifndef THEME_LAYOUT_H
23 #define THEME_LAYOUT_H
24 
25 #include "common/array.h"
26 #include "common/rect.h"
27 #include "graphics/font.h"
28 
29 //#define LAYOUT_DEBUG_DIALOG "Dialog.Launcher"
30 
31 #ifdef LAYOUT_DEBUG_DIALOG
32 namespace Graphics {
33 struct Surface;
34 }
35 #endif
36 
37 namespace GUI {
38 
39 class Widget;
40 
41 class ThemeLayout {
42  friend class ThemeLayoutMain;
43  friend class ThemeLayoutStacked;
44  friend class ThemeLayoutSpacing;
45  friend class ThemeLayoutWidget;
46 public:
47  enum LayoutType {
48  kLayoutMain,
49  kLayoutVertical,
50  kLayoutHorizontal,
51  kLayoutWidget,
52  kLayoutTabWidget,
53  kLayoutScrollContainerWidget,
54  kLayoutSpace
55  };
56 
58  enum ItemAlign {
62  kItemAlignStretch
63  };
64 
66  _parent(p), _x(0), _y(0), _w(-1), _h(-1),
67  _defaultW(-1), _defaultH(-1),
68  _textHAlign(Graphics::kTextAlignInvalid), _useRTL(true) {}
69 
70  virtual ~ThemeLayout() {
71  for (uint i = 0; i < _children.size(); ++i)
72  delete _children[i];
73  }
74 
75  virtual void reflowLayout(Widget *widgetChain) = 0;
76  virtual void resetLayout();
77 
78  void addChild(ThemeLayout *child) { _children.push_back(child); }
79 
80  void setPadding(int16 left, int16 right, int16 top, int16 bottom) {
81  _padding.left = left;
82  _padding.right = right;
83  _padding.top = top;
84  _padding.bottom = bottom;
85  }
86 
87 protected:
88  int16 getWidth() { return _w; }
89  int16 getHeight() { return _h; }
90 
91  void offsetX(int newX) {
92  _x += newX;
93  for (uint i = 0; i < _children.size(); ++i)
94  _children[i]->offsetX(newX);
95  }
96 
97  void offsetY(int newY) {
98  _y += newY;
99  for (uint i = 0; i < _children.size(); ++i)
100  _children[i]->offsetY(newY);
101  }
102 
103  void setWidth(int16 width) { _w = width; }
104  void setHeight(int16 height) { _h = height; }
105  void setTextHAlign(Graphics::TextAlign align) { _textHAlign = align; }
106 
112  virtual bool isBound(Widget *widgetChain) const { return true; }
113 
114  virtual LayoutType getLayoutType() const = 0;
115 
116  virtual ThemeLayout *makeClone(ThemeLayout *newParent) = 0;
117 
118 public:
119  virtual bool getWidgetData(const Common::String &name, int16 &x, int16 &y, int16 &w, int16 &h, bool &useRTL);
120  bool getUseRTL() { return _useRTL; }
121 
122  virtual Graphics::TextAlign getWidgetTextHAlign(const Common::String &name);
123 
124  void importLayout(ThemeLayout *layout);
125 
126  Graphics::TextAlign getTextHAlign() { return _textHAlign; }
127 
128 #ifdef LAYOUT_DEBUG_DIALOG
129  void debugDraw(Graphics::ManagedSurface *screen, const Graphics::Font *font);
130 #endif
131  virtual const char *getName() const { return "<override-me>"; }
132 
133 protected:
134  ThemeLayout *_parent;
135  int16 _x, _y, _w, _h;
136  bool _useRTL;
137  Common::Rect _padding;
139  int16 _defaultW, _defaultH;
140  Graphics::TextAlign _textHAlign;
141 };
142 
143 class ThemeLayoutMain : public ThemeLayout {
144 public:
145  ThemeLayoutMain(const Common::String &name, const Common::String &overlays, int16 width, int16 height, int inset) :
146  ThemeLayout(nullptr),
147  _name(name),
148  _overlays(overlays),
149  _inset(inset) {
150  _w = _defaultW = width;
151  _h = _defaultH = height;
152  _x = _defaultX = -1;
153  _y = _defaultY = -1;
154  }
155  void reflowLayout(Widget *widgetChain) override;
156 
157  void resetLayout() override {
158  ThemeLayout::resetLayout();
159  _x = _defaultX;
160  _y = _defaultY;
161  }
162 
163  virtual const char *getName() const override { return _name.c_str(); }
164 
165 protected:
166  LayoutType getLayoutType() const override { return kLayoutMain; }
167  ThemeLayout *makeClone(ThemeLayout *newParent) override { assert(!"Do not copy Main Layouts!"); return nullptr; }
168 
169  int16 _defaultX;
170  int16 _defaultY;
171 
172  Common::String _name;
173  Common::String _overlays;
174  int _inset;
175 };
176 
178 public:
179  ThemeLayoutStacked(ThemeLayout *p, LayoutType type, int spacing, ItemAlign itemAlign) :
180  ThemeLayout(p), _type(type), _itemAlign(itemAlign) {
181  assert((type == kLayoutVertical) || (type == kLayoutHorizontal));
182  _spacing = spacing;
183  }
184 
185  void reflowLayout(Widget *widgetChain) override {
186  if (_type == kLayoutVertical)
187  reflowLayoutVertical(widgetChain);
188  else
189  reflowLayoutHorizontal(widgetChain);
190  }
191 
192  void reflowLayoutHorizontal(Widget *widgetChain);
193  void reflowLayoutVertical(Widget *widgetChain);
194 
195 #ifdef LAYOUT_DEBUG_DIALOG
196  const char *getName() const override {
197  return (_type == kLayoutVertical)
198  ? "Vertical Layout" : "Horizontal Layout";
199  }
200 #endif
201 
202 protected:
203  int16 getParentWidth();
204  int16 getParentHeight();
205 
206  LayoutType getLayoutType() const override { return _type; }
207 
208  ThemeLayout *makeClone(ThemeLayout *newParent) override {
209  ThemeLayoutStacked *n = new ThemeLayoutStacked(*this);
210  n->_parent = newParent;
211 
212  for (uint i = 0; i < n->_children.size(); ++i)
213  n->_children[i] = n->_children[i]->makeClone(n);
214 
215  return n;
216  }
217 
218  const LayoutType _type;
219  ItemAlign _itemAlign;
220  int8 _spacing;
221 };
222 
224 public:
225  ThemeLayoutWidget(ThemeLayout *p, const Common::String &name, int16 w, int16 h, Graphics::TextAlign align, bool useRTL) : ThemeLayout(p), _name(name) {
226  _w = _defaultW = w;
227  _h = _defaultH = h;
228  _useRTL = useRTL;
229 
230  setTextHAlign(align);
231  }
232 
233  bool getWidgetData(const Common::String &name, int16 &x, int16 &y, int16 &w, int16 &h, bool &useRTL) override;
234  Graphics::TextAlign getWidgetTextHAlign(const Common::String &name) override;
235 
236  void reflowLayout(Widget *widgetChain) override;
237 
238  virtual const char *getName() const override { return _name.c_str(); }
239 
240 protected:
241  LayoutType getLayoutType() const override { return kLayoutWidget; }
242 
243  bool isBound(Widget *widgetChain) const override;
244  Widget *getWidget(Widget *widgetChain) const;
245 
246  ThemeLayout *makeClone(ThemeLayout *newParent) override {
247  ThemeLayout *n = new ThemeLayoutWidget(*this);
248  n->_parent = newParent;
249  return n;
250  }
251 
252  Common::String _name;
253 };
254 
256  int _tabHeight;
257 
258 public:
259  ThemeLayoutTabWidget(ThemeLayout *p, const Common::String &name, int16 w, int16 h, Graphics::TextAlign align, int tabHeight):
260  ThemeLayoutWidget(p, name, w, h, align, p->getUseRTL()) {
261  _tabHeight = tabHeight;
262  }
263 
264  void reflowLayout(Widget *widgetChain) override {
265  for (uint i = 0; i < _children.size(); ++i) {
266  _children[i]->reflowLayout(widgetChain);
267  }
268  }
269 
270  bool getWidgetData(const Common::String &name, int16 &x, int16 &y, int16 &w, int16 &h, bool &useRTL) override {
271  if (ThemeLayoutWidget::getWidgetData(name, x, y, w, h, useRTL)) {
272  h -= _tabHeight;
273  return true;
274  }
275 
276  return false;
277  }
278 
279 protected:
280  LayoutType getLayoutType() const override { return kLayoutTabWidget; }
281 
282  ThemeLayout *makeClone(ThemeLayout *newParent) override {
284  n->_parent = newParent;
285  return n;
286  }
287 };
288 
290  int _scrollWidth;
291 
292 public:
293  ThemeLayoutScrollContainerWidget(ThemeLayout *p, const Common::String &name, int16 w, int16 h, Graphics::TextAlign align, int scrollWidth):
294  ThemeLayoutWidget(p, name, w, h, align, p->getUseRTL()) {
295  _scrollWidth = scrollWidth;
296  }
297 
298  void reflowLayout(Widget *widgetChain) override {
299  for (uint i = 0; i < _children.size(); ++i) {
300  _children[i]->reflowLayout(widgetChain);
301  }
302  }
303 
304  bool getWidgetData(const Common::String &name, int16 &x, int16 &y, int16 &w, int16 &h, bool &useRTL) override {
305  if (ThemeLayoutWidget::getWidgetData(name, x, y, w, h, useRTL)) {
306  w -= _scrollWidth;
307  return true;
308  }
309 
310  return false;
311  }
312 
313 protected:
314  LayoutType getLayoutType() const override { return kLayoutScrollContainerWidget; }
315 
316  ThemeLayout *makeClone(ThemeLayout *newParent) override {
318  n->_parent = newParent;
319  return n;
320  }
321 };
322 
324 public:
325  ThemeLayoutSpacing(ThemeLayout *p, int size) : ThemeLayout(p) {
326  if (p->getLayoutType() == kLayoutHorizontal) {
327  _w = _defaultW = size;
328  _h = _defaultH = 1;
329  } else if (p->getLayoutType() == kLayoutVertical) {
330  _w = _defaultW = 1;
331  _h = _defaultH = size;
332  }
333  }
334 
335  bool getWidgetData(const Common::String &name, int16 &x, int16 &y, int16 &w, int16 &h, bool &useRTL) override { return false; }
336  void reflowLayout(Widget *widgetChain) override {}
337 #ifdef LAYOUT_DEBUG_DIALOG
338  const char *getName() const override { return "SPACE"; }
339 #endif
340 
341 protected:
342  LayoutType getLayoutType() const override { return kLayoutSpace; }
343 
344  ThemeLayout *makeClone(ThemeLayout *newParent) override {
345  ThemeLayout *n = new ThemeLayoutSpacing(*this);
346  n->_parent = newParent;
347  return n;
348  }
349 };
350 
351 }
352 
353 #endif
Definition: ThemeLayout.h:323
Definition: managed_surface.h:51
Definition: str.h:59
Definition: font.h:82
TextAlign
Definition: font.h:48
Items are centered in the container.
Definition: ThemeLayout.h:60
Definition: ThemeLayout.h:289
Definition: array.h:52
Indicates invalid alignment.
Definition: font.h:49
Definition: rect.h:144
Definition: ThemeLayout.h:223
Definition: system.h:46
Items are aligned to the left for vertical layouts or to the top for horizontal layouts.
Definition: ThemeLayout.h:59
Definition: ThemeLayout.h:143
Definition: formatinfo.h:28
Definition: ThemeLayout.h:177
Definition: ThemeLayout.h:255
virtual bool isBound(Widget *widgetChain) const
Definition: ThemeLayout.h:112
Definition: widget.h:101
Items are aligned to the right for vertical layouts or to the bottom for horizontal layouts...
Definition: ThemeLayout.h:61
Definition: ThemeLayout.h:41
ItemAlign
Cross-direction alignment of layout children.
Definition: ThemeLayout.h:58