]> git.mxchange.org Git - simgear.git/blob - simgear/canvas/layout/LayoutItem.hxx
Move canvas::AlignmentFlag to separate file.
[simgear.git] / simgear / canvas / layout / LayoutItem.hxx
1 ///@file
2 /// Basic element for layouting canvas elements.
3 //
4 // Copyright (C) 2014  Thomas Geymayer <tomgey@gmail.com>
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Library General Public
8 // License as published by the Free Software Foundation; either
9 // version 2 of the License, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Library General Public License for more details.
15 //
16 // You should have received a copy of the GNU Library General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA
19
20 #ifndef SG_CANVAS_LAYOUT_ITEM_HXX_
21 #define SG_CANVAS_LAYOUT_ITEM_HXX_
22
23 #include <simgear/canvas/canvas_fwd.hxx>
24 #include <simgear/math/SGMath.hxx>
25 #include <simgear/math/SGRect.hxx>
26 #include <simgear/misc/stdint.hxx>
27 #include <simgear/structure/SGWeakReferenced.hxx>
28 #include <simgear/structure/SGSharedPtr.hxx>
29
30 namespace simgear
31 {
32 namespace canvas
33 {
34   class LayoutItem;
35   typedef SGSharedPtr<LayoutItem> LayoutItemRef;
36   typedef SGWeakPtr<LayoutItem> LayoutItemWeakRef;
37
38   /**
39    * Holds the four margins for a rectangle.
40    */
41   struct Margins
42   {
43     int l, t, r, b;
44
45     /**
46      * Set all margins to the same value @a m.
47      */
48     explicit Margins(int m = 0);
49
50     /**
51      * Set horizontal and vertical margins to the same values @a h and @a v
52      * respectively.
53      *
54      * @param h Horizontal margins
55      * @param v Vertical margins
56      */
57     Margins(int h, int v);
58
59     /**
60      * Set the margins to the given values.
61      */
62     Margins(int left, int top, int right, int bottom);
63
64     /**
65      * Get the total horizontal margin (sum of left and right margin).
66      */
67     int horiz() const;
68
69     /**
70      * Get the total vertical margin (sum of top and bottom margin).
71      */
72     int vert() const;
73
74     /**
75      * Get total horizontal and vertical margin as vector.
76      */
77     SGVec2i size() const;
78
79     /**
80      * Returns true if all margins are 0.
81      */
82     bool isNull() const;
83   };
84
85   /**
86    * Flags for LayoutItem alignment inside Layouts.
87    *
88    * @note You can only use one horizontal and one vertical flag at the same.
89    */
90   enum AlignmentFlag
91   {
92 #define ALIGN_ENUM_MAPPING(key, val, comment) key = val, /*!< comment */
93 #  include "AlignFlag_values.hxx"
94 #undef ALIGN_ENUM_MAPPING
95   };
96
97   /**
98    * Base class for all layouting elements. Specializations either implement a
99    * layouting algorithm or a widget.
100    */
101   class LayoutItem:
102     public virtual SGVirtualWeakReferenced
103   {
104     public:
105
106       /** Maximum item size (indicating no limit) */
107       static const SGVec2i MAX_SIZE;
108
109       LayoutItem();
110       virtual ~LayoutItem();
111
112       /**
113        * Set the margins to use by the layout system around the item.
114        *
115        * The margins define the size of the clear area around an item. It
116        * increases the size hints and reduces the size of the geometry()
117        * available to child layouts and widgets.
118        *
119        * @see Margins
120        */
121       void setContentsMargins(const Margins& margins);
122
123       /**
124        * Set the individual margins.
125        *
126        * @see setContentsMargins(const Margins&)
127        */
128       void setContentsMargins(int left, int top, int right, int bottom);
129
130       /**
131        * Set all margins to the same value.
132        *
133        * @see setContentsMargins(const Margins&)
134        */
135       void setContentsMargin(int margin);
136
137       /**
138        * Get the currently used margins.
139        *
140        * @see setContentsMargins(const Margins&)
141        * @see Margins
142        */
143       Margins getContentsMargins() const;
144
145       /**
146        * Get the area available to the contents.
147        *
148        * This is equal to the geometry() reduced by the sizes of the margins.
149        *
150        * @see setContentsMargins(const Margins&)
151        * @see geometry()
152        */
153       SGRecti contentsRect() const;
154
155       /**
156        * Get the preferred size of this item.
157        */
158       SGVec2i sizeHint() const;
159
160       /**
161        * Get the minimum amount of the space this item requires.
162        */
163       SGVec2i minimumSize() const;
164
165       /**
166        * Get the maximum amount of space this item can use.
167        */
168       SGVec2i maximumSize() const;
169
170       /**
171        * Returns true if this items preferred and minimum height depend on its
172        * width.
173        *
174        * The default implementation returns false. Reimplement for items
175        * providing height for width.
176        *
177        * @see heightForWidth()
178        * @see minimumHeightForWidth()
179        */
180       virtual bool hasHeightForWidth() const;
181
182       /**
183        * Returns the preferred height for the given width @a w.
184        *
185        * Reimplement heightForWidthImpl() for items providing height for width.
186        *
187        * @see hasHeightForWidth()
188        */
189       int heightForWidth(int w) const;
190
191       /**
192        * Returns the minimum height for the given width @a w.
193        *
194        * Reimplement minimumHeightForWidthImpl() for items providing height for
195        * width.
196        *
197        * @see hasHeightForWidth()
198        */
199       int minimumHeightForWidth(int w) const;
200
201       /**
202        * Set alignment of item within @link{Layout Layouts}.
203        *
204        * @param alignment Bitwise combination of vertical and horizontal
205        *                  alignment flags.
206        * @see AlignmentFlag
207        */
208       void setAlignment(uint8_t alignment);
209
210       /**
211        * Get all alignment flags.
212        *
213        * @see AlignmentFlag
214        */
215       uint8_t alignment() const;
216
217       virtual void setVisible(bool visible);
218       virtual bool isVisible() const;
219
220       bool isExplicitlyHidden() const;
221
222       void show() { setVisible(true); }
223       void hide() { setVisible(false); }
224
225       /**
226        * Mark all cached data as invalid and require it to be recalculated.
227        */
228       virtual void invalidate();
229
230       /**
231        * Mark all cached data of parent item as invalid (if the parent is set).
232        */
233       void invalidateParent();
234
235       /**
236        * Apply any changes not applied yet.
237        */
238       void update();
239
240       /**
241        * Set position and size of this element. For layouts this triggers a
242        * recalculation of the layout.
243        */
244       virtual void setGeometry(const SGRecti& geom);
245
246       /**
247        * Get position and size of this element.
248        */
249       virtual SGRecti geometry() const;
250
251       /**
252        * Get the actual geometry of this item given the rectangle \a geom
253        * taking into account the alignment flags and size hints.
254        *
255        * @param geom    Area available to this item.
256        * @return The resulting geometry for this item.
257        *
258        * @see setAlignment()
259        * @see minimumSize()
260        * @see maximumSize()
261        * @see sizeHint()
262        */
263       virtual SGRecti alignmentRect(const SGRecti& geom) const;
264
265       /**
266        * Set the canvas this item is attached to.
267        */
268       virtual void setCanvas(const CanvasWeakPtr& canvas);
269
270       /**
271        * Get the canvas this item is attached to.
272        */
273       CanvasPtr getCanvas() const;
274
275       /**
276        * Set the parent layout item (usually this is a layout).
277        */
278       void setParent(const LayoutItemWeakRef& parent);
279
280       /**
281        * Get the parent layout.
282        */
283       LayoutItemRef getParent() const;
284
285       /// Called before item is removed from a layout
286       virtual void onRemove() {}
287
288     protected:
289
290       friend class Canvas;
291
292       enum Flags
293       {
294         SIZE_HINT_DIRTY = 1,
295         MINIMUM_SIZE_DIRTY = SIZE_HINT_DIRTY << 1,
296         MAXIMUM_SIZE_DIRTY = MINIMUM_SIZE_DIRTY << 1,
297         SIZE_INFO_DIRTY = SIZE_HINT_DIRTY
298                         | MINIMUM_SIZE_DIRTY
299                         | MAXIMUM_SIZE_DIRTY,
300         EXPLICITLY_HIDDEN = MAXIMUM_SIZE_DIRTY << 1,
301         VISIBLE = EXPLICITLY_HIDDEN << 1,
302         LAYOUT_DIRTY = VISIBLE << 1,
303         LAST_FLAG = LAYOUT_DIRTY
304       };
305
306       CanvasWeakPtr     _canvas;
307       LayoutItemWeakRef _parent;
308
309       SGRecti           _geometry;
310       Margins           _margins;
311       uint8_t           _alignment;
312
313       mutable uint32_t  _flags;
314       mutable SGVec2i   _size_hint,
315                         _min_size,
316                         _max_size;
317
318       virtual SGVec2i sizeHintImpl() const;
319       virtual SGVec2i minimumSizeImpl() const;
320       virtual SGVec2i maximumSizeImpl() const;
321
322       /**
323        * Returns the preferred height for the given width @a w.
324        *
325        * The default implementation returns -1, indicating that the preferred
326        * height is independent of the given width.
327        *
328        * Reimplement this function for items supporting height for width.
329        *
330        * @note Do not take margins into account, as this is already handled
331        *       before calling this function.
332        *
333        * @see hasHeightForWidth()
334        */
335       virtual int heightForWidthImpl(int w) const;
336
337       /**
338        * Returns the minimum height for the given width @a w.
339        *
340        * The default implementation returns -1, indicating that the minimum
341        * height is independent of the given width.
342        *
343        * Reimplement this function for items supporting height for width.
344        *
345        * @note Do not take margins into account, as this is already handled
346        *       before calling this function.
347        *
348        * @see hasHeightForWidth()
349        */
350       virtual int minimumHeightForWidthImpl(int w) const;
351
352       /**
353        * @return whether the visibility has changed.
354        */
355       void setVisibleInternal(bool visible);
356
357       virtual void contentsRectChanged(const SGRecti& rect) {};
358
359       virtual void visibilityChanged(bool visible) {}
360
361       /**
362        * Allow calling the protected setVisibleImpl from derived classes
363        */
364       static void callSetVisibleInternal(LayoutItem* item, bool visible);
365
366   };
367
368 } // namespace canvas
369 } // namespace simgear
370
371 #endif /* SG_CANVAS_LAYOUT_ITEM_HXX_ */