]> git.mxchange.org Git - simgear.git/blob - simgear/canvas/layout/LayoutItem.hxx
canvas::Layout: support for alignment.
[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     AlignFill = 0,            //!< Use all available space
93
94     AlignLeft = 0x01,         //!< Align with left edge
95     AlignRight = 0x02,        //!< Align with right edge
96     AlignHCenter = 0x04,      //!< Center horizontally in available space
97
98     AlignTop = 0x20,          //!< Align with top edge
99     AlignBottom = 0x40,       //!< Align with bottom edge
100     AlignVCenter = 0x80,      //!< Center vertically in available space
101
102     AlignCenter = AlignVCenter  //!< Center both vertically and horizontally
103                 | AlignHCenter,
104
105     AlignHorizontal_Mask = AlignLeft
106                          | AlignRight
107                          | AlignHCenter,
108     AlignVertical_Mask = AlignTop
109                        | AlignBottom
110                        | AlignVCenter
111   };
112
113   /**
114    * Base class for all layouting elements. Specializations either implement a
115    * layouting algorithm or a widget.
116    */
117   class LayoutItem:
118     public virtual SGVirtualWeakReferenced
119   {
120     public:
121
122       /** Maximum item size (indicating no limit) */
123       static const SGVec2i MAX_SIZE;
124
125       LayoutItem();
126       virtual ~LayoutItem();
127
128       /**
129        * Set the margins to use by the layout system around the item.
130        *
131        * The margins define the size of the clear area around an item. It
132        * increases the size hints and reduces the size of the geometry()
133        * available to child layouts and widgets.
134        *
135        * @see Margins
136        */
137       void setContentsMargins(const Margins& margins);
138
139       /**
140        * Set the individual margins.
141        *
142        * @see setContentsMargins(const Margins&)
143        */
144       void setContentsMargins(int left, int top, int right, int bottom);
145
146       /**
147        * Set all margins to the same value.
148        *
149        * @see setContentsMargins(const Margins&)
150        */
151       void setContentsMargin(int margin);
152
153       /**
154        * Get the currently used margins.
155        *
156        * @see setContentsMargins(const Margins&)
157        * @see Margins
158        */
159       Margins getContentsMargins() const;
160
161       /**
162        * Get the area available to the contents.
163        *
164        * This is equal to the geometry() reduced by the sizes of the margins.
165        *
166        * @see setContentsMargins(const Margins&)
167        * @see geometry()
168        */
169       SGRecti contentsRect() const;
170
171       /**
172        * Get the preferred size of this item.
173        */
174       SGVec2i sizeHint() const;
175
176       /**
177        * Get the minimum amount of the space this item requires.
178        */
179       SGVec2i minimumSize() const;
180
181       /**
182        * Get the maximum amount of space this item can use.
183        */
184       SGVec2i maximumSize() const;
185
186       /**
187        * Returns true if this items preferred and minimum height depend on its
188        * width.
189        *
190        * The default implementation returns false. Reimplement for items
191        * providing height for width.
192        *
193        * @see heightForWidth()
194        * @see minimumHeightForWidth()
195        */
196       virtual bool hasHeightForWidth() const;
197
198       /**
199        * Returns the preferred height for the given width @a w.
200        *
201        * Reimplement heightForWidthImpl() for items providing height for width.
202        *
203        * @see hasHeightForWidth()
204        */
205       int heightForWidth(int w) const;
206
207       /**
208        * Returns the minimum height for the given width @a w.
209        *
210        * Reimplement minimumHeightForWidthImpl() for items providing height for
211        * width.
212        *
213        * @see hasHeightForWidth()
214        */
215       int minimumHeightForWidth(int w) const;
216
217       /**
218        * Set alignment of item within @link{Layout Layouts}.
219        *
220        * @param alignment Bitwise combination of vertical and horizontal
221        *                  alignment flags.
222        * @see AlignmentFlag
223        */
224       void setAlignment(uint8_t alignment);
225
226       /**
227        * Get all alignment flags.
228        *
229        * @see AlignmentFlag
230        */
231       uint8_t alignment() const;
232
233       virtual void setVisible(bool visible);
234       virtual bool isVisible() const;
235
236       bool isExplicitlyHidden() const;
237
238       void show() { setVisible(true); }
239       void hide() { setVisible(false); }
240
241       /**
242        * Mark all cached data as invalid and require it to be recalculated.
243        */
244       virtual void invalidate();
245
246       /**
247        * Mark all cached data of parent item as invalid (if the parent is set).
248        */
249       void invalidateParent();
250
251       /**
252        * Apply any changes not applied yet.
253        */
254       void update();
255
256       /**
257        * Set position and size of this element. For layouts this triggers a
258        * recalculation of the layout.
259        */
260       virtual void setGeometry(const SGRecti& geom);
261
262       /**
263        * Get position and size of this element.
264        */
265       virtual SGRecti geometry() const;
266
267       /**
268        * Get the actual geometry of this item given the rectangle \a geom
269        * taking into account the alignment flags and size hints.
270        *
271        * @param geom    Area available to this item.
272        * @return The resulting geometry for this item.
273        *
274        * @see setAlignment()
275        * @see minimumSize()
276        * @see maximumSize()
277        * @see sizeHint()
278        */
279       virtual SGRecti alignmentRect(const SGRecti& geom) const;
280
281       /**
282        * Set the canvas this item is attached to.
283        */
284       virtual void setCanvas(const CanvasWeakPtr& canvas);
285
286       /**
287        * Get the canvas this item is attached to.
288        */
289       CanvasPtr getCanvas() const;
290
291       /**
292        * Set the parent layout item (usually this is a layout).
293        */
294       void setParent(const LayoutItemWeakRef& parent);
295
296       /**
297        * Get the parent layout.
298        */
299       LayoutItemRef getParent() const;
300
301       /// Called before item is removed from a layout
302       virtual void onRemove() {}
303
304     protected:
305
306       friend class Canvas;
307
308       enum Flags
309       {
310         SIZE_HINT_DIRTY = 1,
311         MINIMUM_SIZE_DIRTY = SIZE_HINT_DIRTY << 1,
312         MAXIMUM_SIZE_DIRTY = MINIMUM_SIZE_DIRTY << 1,
313         SIZE_INFO_DIRTY = SIZE_HINT_DIRTY
314                         | MINIMUM_SIZE_DIRTY
315                         | MAXIMUM_SIZE_DIRTY,
316         EXPLICITLY_HIDDEN = MAXIMUM_SIZE_DIRTY << 1,
317         VISIBLE = EXPLICITLY_HIDDEN << 1,
318         LAYOUT_DIRTY = VISIBLE << 1,
319         LAST_FLAG = LAYOUT_DIRTY
320       };
321
322       CanvasWeakPtr     _canvas;
323       LayoutItemWeakRef _parent;
324
325       SGRecti           _geometry;
326       Margins           _margins;
327       uint8_t           _alignment;
328
329       mutable uint32_t  _flags;
330       mutable SGVec2i   _size_hint,
331                         _min_size,
332                         _max_size;
333
334       virtual SGVec2i sizeHintImpl() const;
335       virtual SGVec2i minimumSizeImpl() const;
336       virtual SGVec2i maximumSizeImpl() const;
337
338       /**
339        * Returns the preferred height for the given width @a w.
340        *
341        * The default implementation returns -1, indicating that the preferred
342        * height is independent of the given width.
343        *
344        * Reimplement this function for items supporting height for width.
345        *
346        * @note Do not take margins into account, as this is already handled
347        *       before calling this function.
348        *
349        * @see hasHeightForWidth()
350        */
351       virtual int heightForWidthImpl(int w) const;
352
353       /**
354        * Returns the minimum height for the given width @a w.
355        *
356        * The default implementation returns -1, indicating that the minimum
357        * height is independent of the given width.
358        *
359        * Reimplement this function for items supporting height for width.
360        *
361        * @note Do not take margins into account, as this is already handled
362        *       before calling this function.
363        *
364        * @see hasHeightForWidth()
365        */
366       virtual int minimumHeightForWidthImpl(int w) const;
367
368       /**
369        * @return whether the visibility has changed.
370        */
371       void setVisibleInternal(bool visible);
372
373       virtual void contentsRectChanged(const SGRecti& rect) {};
374
375       virtual void visibilityChanged(bool visible) {}
376
377       /**
378        * Allow calling the protected setVisibleImpl from derived classes
379        */
380       static void callSetVisibleInternal(LayoutItem* item, bool visible);
381
382   };
383
384 } // namespace canvas
385 } // namespace simgear
386
387 #endif /* SG_CANVAS_LAYOUT_ITEM_HXX_ */