]> git.tdb.fi Git - libs/gltk.git/blob - source/layout.h
Comment and style updates
[libs/gltk.git] / source / layout.h
1 #ifndef MSP_GLTK_LAYOUT_H_
2 #define MSP_GLTK_LAYOUT_H_
3
4 #include <list>
5 #include <set>
6 #include <sigc++/trackable.h>
7 #include "geometry.h"
8
9 namespace Msp {
10 namespace GLtk {
11
12 class Container;
13 class Widget;
14
15 /**
16 Positions Widgets inside a Container.
17
18 A layout operates on constraints, which are used to form a linear program that
19 is then solved to obtain positions and dimensions that fulfill the constraints.
20 There are three kinds of constraints available: ordering, alignment and
21 dimension matching.
22
23 Ordering constraints specify that the widgets should be placed next to each
24 other along X or Y axis.  These operate on one axis at a time, so a widget
25 could be "right of" another even if they are separated by hundreds of pixels
26 vertically.  The widgets will be separated by a spacing value, which is
27 settable on a per-layout basis.
28
29 Alignment constraints make the corresponding edges of two widgets be on the
30 same line.  These are incompatible with ordering constraints, so only one or
31 the other should be used between any pair of widgets for the same axis.
32
33 Dimension matching constraints force the two widgets to have the same dimension
34 along the relevant axis.
35
36 In addition to constraints, there are some other properties that can be set on
37 widgets to determine how they are laid out.  Gravity affects which edge of the
38 container the widget should be placed at.  This is a relatively weak hint and
39 will be overridden by many other things.  Margins can also be specified to
40 prevent widgets from getting too close to the container's edges.
41
42 Usually widgets are made as small as their content allows.  Setting the expand
43 flag for a widget causes it to use as much space as possible.  If multiple co-
44 dependent widgets have the expand flag set, the results are currently
45 undefined.
46
47 Since specifiyng constraints manually can be quite tedious, there are some
48 derived Layout classes that implement common positioning patterns.  See Row,
49 Column, MixedRows and Grid.
50 */
51 class Layout
52 {
53 private:
54         enum
55         {
56                 HORIZONTAL = 0,
57                 VERTICAL = 1,
58                 SELF_POS = 2,
59                 SELF_DIM = 4,
60                 TARGET_POS = 8,
61                 TARGET_DIM = 16,
62                 SPACING = 32
63         };
64
65 public:
66         enum ConstraintType
67         {
68                 ABOVE = VERTICAL|SELF_POS|TARGET_POS|TARGET_DIM|SPACING,
69                 BELOW = VERTICAL|SELF_POS|SELF_DIM|TARGET_POS|SPACING,
70                 RIGHT_OF = HORIZONTAL|SELF_POS|TARGET_POS|TARGET_DIM|SPACING,
71                 LEFT_OF = HORIZONTAL|SELF_POS|SELF_DIM|TARGET_POS|SPACING,
72                 ALIGN_TOP = VERTICAL|SELF_POS|SELF_DIM|TARGET_POS|TARGET_DIM,
73                 ALIGN_BOTTOM = VERTICAL|SELF_POS|TARGET_POS,
74                 ALIGN_RIGHT = HORIZONTAL|SELF_POS|SELF_DIM|TARGET_POS|TARGET_DIM,
75                 ALIGN_LEFT = HORIZONTAL|SELF_POS|TARGET_POS,
76                 COPY_WIDTH = HORIZONTAL|SELF_DIM|TARGET_DIM,
77                 COPY_HEIGHT = VERTICAL|SELF_DIM|TARGET_DIM
78         };
79
80 protected:
81         struct Slot;
82
83         struct Constraint
84         {
85                 ConstraintType type;
86                 Slot &target;
87                 int spacing;
88
89                 Constraint(ConstraintType, Slot &);
90         };
91
92         struct Packing
93         {
94                 int gravity;
95                 bool expand;
96
97                 Packing();
98         };
99
100         struct Slot: public sigc::trackable
101         {
102                 Layout &layout;
103                 int index;
104                 Widget &widget;
105                 Geometry autosize_geom;
106                 Geometry geom;
107                 std::list<Constraint> constraints;
108                 Packing horiz_pack;
109                 Packing vert_pack;
110
111                 Slot(Layout &, Widget &);
112                 virtual ~Slot() { }
113
114                 void autosize_changed();
115                 void visibility_changed(bool);
116         };
117
118         enum SolveMode
119         {
120                 UPDATE,
121                 AUTOSIZE
122         };
123
124         class LinearProgram;
125         struct Pointers;
126
127         Container *container;
128         std::list<Slot *> slots;
129         unsigned n_active_slots;
130         Sides margin;
131         unsigned row_spacing;
132         unsigned col_spacing;
133         Geometry autosize_geom;
134
135         static Pointers pointers[2];
136
137 public:
138         Layout();
139         virtual ~Layout();
140
141         void set_container(Container &);
142         void set_margin(const Sides &);
143
144         /** Sets the default spacing between widgets in bothg directions. */
145         void set_spacing(unsigned);
146
147         /** Sets the default vertical spacing between widgets.  Affects the ABOVE
148         and BELOW constraints. */
149         void set_row_spacing(unsigned);
150
151         /** Sets the default horizontal spacing between widgets.  Affects the
152         LEFT_OF and RIGHT_OF constraints. */
153         void set_column_spacing(unsigned);
154
155         void add_widget(Widget &);
156         void remove_widget(Widget &);
157 protected:
158         virtual Slot *create_slot(Widget &);
159         void update_slot_indices();
160         Slot &get_slot_for_widget(Widget &);
161         static ConstraintType complement(ConstraintType);
162         void create_constraint(Widget &, ConstraintType, Widget &, int);
163
164 public:
165         /** Adds a constraint between two widgets. */
166         void add_constraint(Widget &src, ConstraintType type, Widget &tgt);
167
168         /** Adds a constraint between two widgets, overriding the default spacing.
169         Not all constraint types use a spacing. */
170         void add_constraint(Widget &src, ConstraintType type, Widget &tgt, unsigned);
171
172         void set_gravity(Widget &, int, int);
173         void set_expand(Widget &, bool, bool);
174
175         void update();
176         void autosize();
177
178 protected:
179         void solve_constraints(int, SolveMode);
180 };
181
182 } // namespace GLtk
183 } // namespace Msp
184
185 #endif