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