xref: /haiku/docs/user/interface/_layout_intro.dox (revision 99d027cd0238c1d86da86d7c3f4200509ccc61a6)
1/*
2 * Copyright 2010, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
4 *
5 * Documentation by:
6 *		Alex Wilson <yourpalal2@gmail.com>
7 */
8
9
10/*!
11	\page layout_intro Introducing the Layout API.
12
13	Haiku's Layout API is centered around the BLayoutItem and BLayout classes.
14	The BLayoutItem class represents thing that can be managed by a BLayout,
15	which is itself a BLayoutItem. Before we go any further, it is a good idea
16	to familiarize yourself with the different BLayouts available in Haiku:
17		\li BGroupLayout
18		\li BGridLayout
19		\li BCardLayout
20		\li BSplitView
21
22	You'll notice that BSplitView is not actually a BLayout, but a BView. The
23	BSplitView class uses a custom BLayout behind the scenes, but because it
24	must also be able to draw, a BView is required. Other BLayouts have
25	BViews that can be used for convenience.
26		\li BGroupLayout : BGroupView
27		\li BGridLayout : BGridView
28		\li BCardLayout : BTabView (also provides on-screen tabs)
29
30	Although it is not necessary to use these classes to make use of the
31	coresponding layouts, it does make things easier.
32
33	Once you have an understanding of what each BLayout does, you can start
34	designing an interface with them. Let's consider a very simple window,
35	with a single item in the center. For this, any of the layouts mentioned
36	above would work, but we'll use a BGroupLayout, because it suits this
37	purpose the best.
38
39	So, let's review the BGroupLayout constructor:
40
41\code
42BGroupLayout(enum orientation orientation, float spacing
43		= B_USE_DEFAULT_SPACING)
44\endcode
45
46	Because we only have one item in this layout, \c orientation and \c spacing
47	become irrelevant. Let's choose B_VERTICAL for \c orientation, and leave
48	\c spacing at its default.
49
50\code
51BGroupLayout* group = new BGroupLayout(B_VERTICAL);
52BWindow* window = MakeWindow();
53window->SetLayout(group);
54\endcode
55
56	Before we can add anything to our layout, we must attach it to something,
57	and here we've used the BWindow::SetLayout() method to accomplish that.
58	By doing this, \c window takes ownership of \c group, so there is no need
59	to manually  <tt> delete group </tt> when we're done with it.
60
61	Now that we've got our BGroupLayout in place, we can start adding things
62	to it, let's add a BStringView.
63
64\code
65group->AddView(MakeStringView("Haiku rocks!"));
66\endcode
67
68	That does it! Now we've got a BWindow with a horizontal BGroupLayout holding
69	a single BView. However, if we want to ensure that our BStringView is always
70	centered in the window, we should give it an explict BAlignment. So that
71	last line becomes:
72
73\code
74BLayoutItem* stringView = group->AddView(MakeStringView("Haiku rocks!"));
75stringView->SetExplicitAlignment(BAlignment(B_ALIGN_HORIZONTAL_CENTER,
76		B_ALIGN_VERTICAL_CENTER);
77\endcode
78
79	Now our BStringView will always be right in the middle of the space
80	alloted to it, which at the moment is the whole of \c window.
81
82	Now let's take things one step further, and add a BMenuBar into the mix.
83
84\code
85group->AddView(0, MakeMenuBar());
86group->SetInsets(0, 0, 0, 0);
87\endcode
88
89	Because we want our BMenuBar to appear at the very top of the window, we
90	have to insert it at index \c 0, above the BStringView we added earlier.
91	We also use BTwoDimensionalLayout::SetInsets() to make sure that our
92	BMenuBar is flush to the edges of \c window. We also want a bit of
93	space between our BMenuBar and our BStringView, but \c group's spacing has
94	already been set by the BGroupLayout constructor, so we don't need to do
95	that.
96
97	Now that we've put our BGroupLayout to good use, we can rest easy, assured
98	that GUI will always look nice, no matter what font is used, or how big or
99	little \c window is stretched. Of course, very few interfaces are as simple
100	as this one.
101
102	Luckily, the layout classes can deal with complex layouts. Suppose, for
103	example, that we wanted to add a grid of BButtons under our BStringView.
104	We could use a BGridLayout for this. Let's review the BGridLayout
105	constructor:
106
107\code
108BGridLayout(float horizontal = B_USE_DEFAULT_SPACING,
109	float vertical = B_USE_DEFAULT_SPACING);
110\endcode
111
112	Because we want a bit of breathing room between our buttons, we'll leave
113	vertical and horizontal spacing as is.
114
115\code
116BGridLayout* grid = new BGridLayout();
117group->AddItem(grid);
118\endcode
119
120	You'll notice that we've added \c grid directly to \c group. This means that
121	any BViews we add to \c grid will become children of \c window, but will be
122	positioned by \c grid.
123
124\code
125grid->AddView(MakeSmallButton(), 0, 0);
126grid->AddView(MakeSmallButton(), 1, 0);
127grid->AddView(MakeBigButton(), 0, 1, 2, 1);
128grid->AddView(MakeSmallButton(), 1, 2);
129\endcode
130
131	Now we've got a nice grid of BButtons, let's go over it quickly:
132		\li \c grid has two columns and three rows.
133		\li The cells (0, 0), (1, 0), and (1, 2) hold small buttons
134		\li The cells (0, 1) and (1, 1) hold a single button that spans both
135			cells.
136		\li The cell (0, 2) is empty.
137
138	How easy was that? Very easy!
139
140	One of the features you'll find incredibly handy in the layout API is the
141	builders in LayoutBuilder.h. Here's how our whole layout would look if it
142	were done with these builders:
143
144\code
145BLayoutBuilder::Group<>(window, B_VERTICAL)
146	.SetInsets(0, 0, 0, 0)
147	.Add(MakeMenuBar())
148	.Add(MakeStringView("Haiku rocks!"))
149	.AddGrid()
150		.Add(MakeSmallButton(), 0, 0)
151		.Add(MakeSmallButton(), 1, 0)
152		.Add(MakeBigButton(), 0, 1, 2, 1)
153		.Add(MakeSmallButton(), 1, 2);
154\endcode
155
156	This is only one way that you could build this layout, but it is probably
157	the most succinct. Functionally, this is equivalent to all the previous
158	code in this introduction.
159
160*/
161
162