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