bin/pc: Mark non-returning function as void
[haiku.git] / docs / user / interface / _layout_intro.dox
blobd0482201fe7931bfc956c33321c77aed3bbbf1e6
1 /*
2  * Copyright 2010-2015 Haiku, Inc. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *              Alex Wilson, yourpalal2@gmail.com
7  *              Augustin Cavalier <waddlesplash>
8  */
11 /*!
12         \page layout_intro Introducing the Layout API.
14         Haiku's Layout API is centered around the BLayoutItem and BLayout classes.
15         The BLayoutItem class represents thing that can be managed by a BLayout,
16         which is itself a BLayoutItem. Before we go any further, it is a good idea
17         to familiarize yourself with the different BLayout classes available in
18         Haiku:
19                 \li BGroupLayout
20                 \li BGridLayout
21                 \li BCardLayout
22                 \li BSplitView
24         You'll notice that BSplitView is not actually a BLayout, but a BView. The
25         BSplitView class uses a custom BLayout behind the scenes, but because it
26         must also be able to draw, a BView is required. Other BLayout objects have
27         BView objects that can be used for convenience.
28                 \li BGroupLayout : BGroupView
29                 \li BGridLayout : BGridView
30                 \li BCardLayout : BTabView (also provides on-screen tabs)
32         Although it is not necessary to use these classes to make use of the
33         corresponding layouts, it does make things easier.
35         Once you have an understanding of what each BLayout does, you can start
36         designing an interface with them. Let's consider a very simple window,
37         with a single item in the center. For this, any of the layouts mentioned
38         above would work, but we'll use a BGroupLayout, because it suits this
39         purpose the best.
41         The BGroupLayout constructor is:
43 \code
44 BGroupLayout(orientation orientation, float spacing = B_USE_DEFAULT_SPACING)
45 \endcode
47         Because we only have one item in this layout, \c orientation and \c spacing
48         become irrelevant. Let's choose B_VERTICAL for \c orientation, and leave
49         \c spacing at its default.
51 \code
52 BGroupLayout* group = new BGroupLayout(B_VERTICAL);
53 BWindow* window = MakeWindow();
54 window->SetLayout(group);
55 \endcode
57         Before we can add anything to our layout, we must attach it to something,
58         and here we've used the BWindow::SetLayout() method to accomplish that.
59         By doing this, \c window takes ownership of \c group, so there is no need
60         to manually <tt>delete group</tt> when we're done with it.
62         Now that we've got our BGroupLayout in place, we can start adding things
63         to it, so let's add a BStringView.
65 \code
66 group->AddView(MakeStringView("Haiku rocks!"));
67 \endcode
69         Now we've got a BWindow with a horizontal BGroupLayout holding
70         a single BView. However, if we want to ensure that our BStringView is always
71         centered in the window, we should give it an explicit BAlignment. So the
72         last line becomes:
74 \code
75 BLayoutItem* stringView = group->AddView(MakeStringView("Haiku rocks!"));
76 stringView->SetExplicitAlignment(BAlignment(B_ALIGN_HORIZONTAL_CENTER,
77         B_ALIGN_VERTICAL_CENTER);
78 \endcode
80         Now our BStringView will always be right in the middle of the space
81         allotted to it, which at the moment is the whole of \c window.
83         Now let's add a BMenuBar:
85 \code
86 group->AddView(0, MakeMenuBar());
87 group->SetInsets(0, 0, 0, 0);
88 \endcode
90         Because we want our BMenuBar to appear at the very top of the window, we
91         have to insert it at index \c 0, above the BStringView we added earlier.
92         We also use BTwoDimensionalLayout::SetInsets() to make sure that our
93         BMenuBar is flush to the edges of \c window. We also want a bit of
94         space between our BMenuBar and our BStringView, but \c group's spacing has
95         already been set by the BGroupLayout constructor, so we don't need to do
96         that.
98         Now that we've put our BGroupLayout to good use, we can rest easy, assured
99         that GUI will always look nice, no matter what font is used, or how big or
100         little \c window is stretched. Of course, very few interfaces are as simple
101         as this one.
103         The layout classes can deal with complex layouts. Suppose, for
104         example, that we wanted to add a grid of BButtons under our BStringView.
105         We could use a BGridLayout for this. The BGridLayout constructor is:
107 \code
108 BGridLayout(float horizontal = B_USE_DEFAULT_SPACING,
109         float vertical = B_USE_DEFAULT_SPACING);
110 \endcode
112         Because we want a bit of breathing room between our buttons, we'll leave
113         vertical and horizontal spacing as is.
115 \code
116 BGridLayout* grid = new BGridLayout();
117 group->AddItem(grid);
118 \endcode
120         You'll notice that we've added \c grid directly to \c group. This means that
121         any BView objects we add to \c grid will become children of \c window, but
122         will be positioned by \c grid.
124 \code
125 grid->AddView(MakeSmallButton(), 0, 0);
126 grid->AddView(MakeSmallButton(), 1, 0);
127 grid->AddView(MakeBigButton(), 0, 1, 2, 1);
128 grid->AddView(MakeSmallButton(), 1, 2);
129 \endcode
131         Now we've got a nice grid of BButton objects, 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.
138         One of the features you'll find incredibly handy in the layout API is the
139         builders in LayoutBuilder.h. Here's how our whole layout would look if it
140         were done with these builders:
142 \code
143 BLayoutBuilder::Group<>(window, B_VERTICAL)
144         .SetInsets(0, 0, 0, 0)
145         .Add(MakeMenuBar())
146         .Add(MakeStringView("Haiku rocks!"))
147         .AddGrid()
148                 .Add(MakeSmallButton(), 0, 0)
149                 .Add(MakeSmallButton(), 1, 0)
150                 .Add(MakeBigButton(), 0, 1, 2, 1)
151                 .Add(MakeSmallButton(), 1, 2);
152 \endcode
154         This is only one way that you could build this layout, but it is probably
155         the most succinct. Functionally, this is equivalent to all the previous
156         code in this introduction.
158 \par Special Handling for BBox
159         BBox is a "container" view that can contain other views.
160         The use of the layout manager within an
161         instance of BBox is a special case.  Code such as is shown below is
162         necessary to automatically layout views within a BBox.
164 \code
165 BBox *box = new BBox("box-example");
166 BGroupLayout *boxLayout = BLayoutBuilder::Group<>(B_HORIZONTAL)
167         .Add(button1)
168         .Add(button2);
170 box->AddChild(boxLayout->View());
171 \endcode