xref: /haiku/docs/user/interface/LayoutBuilder.dox (revision 3995592cdf304335132305e27c40cbb0b1ac46e3)
1/*
2 * Copyright 2010 Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 *		Alex Wilson, yourpalal2@gmail.com
7 *
8 * Corresponds to:
9 *		headers/os/interface/LayoutBuilder.h	rev 38207
10 *		src/kits/interface/LayoutBuilder.cpp	rev 38207
11 */
12
13
14/*!
15	\file LayoutBuilder.h
16	\ingroup layout
17	\ingroup libbe
18	\brief Defines the BLayoutBuilder templates.
19*/
20
21
22/*!
23	\class BLayoutBuilder::Base<>
24	\ingroup layout
25	\brief Base for all other layout builders in the BLayoutBuilder namespace.
26
27	This class provides the stack-like semantics for its subclasses. The
28	BLayoutBuilder::Group, BLayoutBuilder::Grid and BLayoutBuilder::Split all
29	provide methods such as AddGrid() AddGroup() and AddSplit(), which
30	make a new builder, place it on top of your builder stack and return it.
31	Now you are operating on the new builder. When you call	the End() method on
32	the new builder, you are returned the one you had previously been using. At
33	any point, you are calling methods on whatever builder currently resides on
34	the top of the stack. Here's an example of how these classes work.
35
36\code
37BLayoutBuilder::Group<>(B_HORIZONTAL)
38\endcode
39
40	At this point our stack just contains a single builder, it looks like this:
41		\li Group<>
42
43\code
44	.AddGrid()
45\endcode
46
47	Now there is a Grid builder on top of the stack, so it looks like this \li Group<>::GridBuilder
48		\li Group<>
49
50	Notice that the Grid on top of the stack is not a plain Grid<>, but a nested
51	type from the Group<> class. This is an essential part of the builder
52	classes, as this is what allows you to pop builders off the stack and get
53	the correct type in return.
54
55\code
56		.AddSplit()
57\endcode
58
59	Now our stack looks like this:
60		\li Group<>::GridBuilder::SplitBuilder
61		\li Group<>::GridBuilder
62		\li Group<>
63
64	This could continue ad. nauseam, but at some point, you may finish with a
65	builder, and you might want to continue manipulating the builder below it
66	on the stack. To do this, you simply call the End() method like so:
67
68\code
69			.End()
70\endcode
71
72	And now the stack is back to this:
73		\li Group<>::GridBuilder
74		\li Group<>
75
76	So you are again working with the grid builder. You can add more
77	BLayoutItems or BViews, or even more builders. Here's how it will all look
78	together.
79
80\code
81BLayoutBuilder::Group<>(B_HORIZONTAL)
82	// working with the Group builder
83	.AddGrid()
84		// working with the Group<>::GridBuilder
85		.AddSplit()
86			// working with the Group<>::GridBuilder::SplitBuilder
87		.End()
88		// back to the Group<>::GridBuilder
89\endcode
90
91	Note that the C++ language does not impose any sequence points in such
92	method chains. This means the arguments to all calls may be evaluated in an
93	unexpected order. For exemple, the following code may not result in adding
94	the 3 views in rows 0, 1 and 2 in the target grid:
95
96\code
97	// Don't do this!
98	int row = 0;
99	BLayoutBuilder::Grid<>(target)
100		.Add(viewA, row++)
101		.Add(viewB, row++)
102		.Add(viewC, row++);
103\endcode
104
105	\since Haiku R1
106*/
107
108
109/*!
110	\fn void BLayoutBuilder::Base<ParentBuilder>::SetParent(ParentBuilder*
111		parent)
112	\brief Internal method for use by BLayoutBuilder::Base subclasses,
113	       this is essential to the builder stack semantics.
114
115	\since Haiku R1
116*/
117
118
119/*!
120	\fn ParentBuilder& BLayoutBuilder::Base<ParentBuilder>::End()
121	\brief Returns this builder's parent.
122
123	\since Haiku R1
124*/
125
126
127
128/*
129
130
131template<typename ParentBuilder>
132class Grid : public Base<ParentBuilder> {
133public:
134	typedef Grid<ParentBuilder>		ThisBuilder;
135	typedef Group<ThisBuilder>		GroupBuilder;
136	typedef Grid<ThisBuilder>		GridBuilder;
137	typedef Split<ThisBuilder>		SplitBuilder;
138
139public:
140	inline						Grid(float horizontalSpacing = 0.0f,
141									float verticalSpacing = 0.0f);
142	inline						Grid(BWindow* window,
143									float horizontalSpacing = 0.0f,
144									float verticalSpacing = 0.0f);
145	inline						Grid(BGridLayout* layout);
146	inline						Grid(BGridView* view);
147
148	inline	BGridLayout*		Layout() const;
149	inline	BView*				View() const;
150	inline	ThisBuilder&		GetLayout(BGridLayout** _layout);
151	inline	ThisBuilder&		GetView(BView** _view);
152
153	inline	ThisBuilder&		Add(BView* view, int32 column, int32 row,
154									int32 columnCount = 1, int32 rowCount = 1);
155	inline	ThisBuilder&		Add(BLayoutItem* item, int32 column, int32 row,
156									int32 columnCount = 1, int32 rowCount = 1);
157	inline	ThisBuilder&		AddMenuField(BMenuField* menuField,
158									int32 column, int32 row,
159									alignment labelAlignment
160										= B_ALIGN_HORIZONTAL_UNSET,
161									int32 columnCount = 1, int32 rowCount = 1);
162	inline	ThisBuilder&		AddTextControl(BTextControl* textControl,
163									int32 column, int32 row,
164									alignment labelAlignment
165										= B_ALIGN_HORIZONTAL_UNSET,
166									int32 columnCount = 1, int32 rowCount = 1);
167
168	inline	GroupBuilder		AddGroup(orientation orientation,
169									float spacing, int32 column, int32 row,
170									int32 columnCount = 1, int32 rowCount = 1);
171	inline	GroupBuilder		AddGroup(BGroupView* groupView,	int32 column,
172									int32 row, int32 columnCount = 1,
173									int32 rowCount = 1);
174	inline	GroupBuilder		AddGroup(BGroupLayout* groupLayout,
175									int32 column, int32 row,
176									int32 columnCount = 1, int32 rowCount = 1);
177
178	inline	GridBuilder			AddGrid(float horizontalSpacing,
179									float verticalSpacing, int32 column,
180									int32 row, int32 columnCount = 1,
181									int32 rowCount = 1);
182	inline	GridBuilder			AddGrid(BGridLayout* gridLayout,
183									int32 column, int32 row,
184									int32 columnCount = 1, int32 rowCount = 1);
185	inline	GridBuilder			AddGrid(BGridView* gridView,
186									int32 column, int32 row,
187									int32 columnCount = 1, int32 rowCount = 1);
188
189	inline	SplitBuilder		AddSplit(orientation orientation,
190									float spacing, int32 column, int32 row,
191									int32 columnCount = 1, int32 rowCount = 1);
192	inline	SplitBuilder		AddSplit(BSplitView* splitView, int32 column,
193									int32 row, int32 columnCount = 1,
194									int32 rowCount = 1);
195
196	inline	ThisBuilder&		SetColumnWeight(int32 column, float weight);
197	inline	ThisBuilder&		SetRowWeight(int32 row, float weight);
198
199	inline	ThisBuilder&		SetInsets(float left, float top, float right,
200									float bottom);
201
202	inline						operator BGridLayout*();
203
204private:
205			BGridLayout*		fLayout;
206};
207
208
209template<typename ParentBuilder>
210class Split : public Base<ParentBuilder> {
211public:
212	typedef Split<ParentBuilder>	ThisBuilder;
213	typedef Group<ThisBuilder>		GroupBuilder;
214	typedef Grid<ThisBuilder>		GridBuilder;
215	typedef Split<ThisBuilder>		SplitBuilder;
216
217public:
218	inline						Split(orientation orientation = B_HORIZONTAL,
219									float spacing = 0.0f);
220	inline						Split(BSplitView* view);
221
222	inline	BSplitView*			View() const;
223	inline	ThisBuilder&		GetView(BView** _view);
224	inline	ThisBuilder&		GetSplitView(BSplitView** _view);
225
226	inline	ThisBuilder&		Add(BView* view);
227	inline	ThisBuilder&		Add(BView* view, float weight);
228	inline	ThisBuilder&		Add(BLayoutItem* item);
229	inline	ThisBuilder&		Add(BLayoutItem* item, float weight);
230
231	inline	GroupBuilder		AddGroup(orientation orientation,
232									float spacing = 0.0f, float weight = 1.0f);
233	inline	GroupBuilder		AddGroup(BGroupView* groupView,
234									float weight = 1.0f);
235	inline	GroupBuilder		AddGroup(BGroupLayout* groupLayout,
236									float weight = 1.0f);
237
238	inline	GridBuilder			AddGrid(float horizontalSpacing = 0.0f,
239									float verticalSpacing = 0.0f,
240									float weight = 1.0f);
241	inline	GridBuilder			AddGrid(BGridView* gridView,
242									float weight = 1.0f);
243	inline	GridBuilder			AddGrid(BGridLayout* gridLayout,
244									float weight = 1.0f);
245
246	inline	SplitBuilder		AddSplit(orientation orientation,
247									float spacing = 0.0f, float weight = 1.0f);
248	inline	SplitBuilder		AddSplit(BSplitView* splitView,
249									float weight = 1.0f);
250
251	inline	ThisBuilder&		SetCollapsible(bool collapsible);
252	inline	ThisBuilder&		SetCollapsible(int32 index, bool collapsible);
253	inline	ThisBuilder&		SetCollapsible(int32 first, int32 last,
254									bool collapsible);
255
256	inline	ThisBuilder&		SetInsets(float left, float top, float right,
257									float bottom);
258
259	inline						operator BSplitView*();
260
261private:
262			BSplitView*			fView;
263};
264