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