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 94 95/*! 96 \fn void BLayoutBuilder::Base<ParentBuilder>::SetParent(ParentBuilder* 97 parent) 98 Internal method for use by BLayoutBuilder::Base subclasses, this is 99 essential to the builder stack semantics 100*/ 101 102 103/*! 104 \fn ParentBuilder& BLayoutBuilder::Base<ParentBuilder>::End() 105 \brief Returns this builder's parent. 106*/ 107 108 109 110/* 111 112 113template<typename ParentBuilder> 114class Grid : public Base<ParentBuilder> { 115public: 116 typedef Grid<ParentBuilder> ThisBuilder; 117 typedef Group<ThisBuilder> GroupBuilder; 118 typedef Grid<ThisBuilder> GridBuilder; 119 typedef Split<ThisBuilder> SplitBuilder; 120 121public: 122 inline Grid(float horizontalSpacing = 0.0f, 123 float verticalSpacing = 0.0f); 124 inline Grid(BWindow* window, 125 float horizontalSpacing = 0.0f, 126 float verticalSpacing = 0.0f); 127 inline Grid(BGridLayout* layout); 128 inline Grid(BGridView* view); 129 130 inline BGridLayout* Layout() const; 131 inline BView* View() const; 132 inline ThisBuilder& GetLayout(BGridLayout** _layout); 133 inline ThisBuilder& GetView(BView** _view); 134 135 inline ThisBuilder& Add(BView* view, int32 column, int32 row, 136 int32 columnCount = 1, int32 rowCount = 1); 137 inline ThisBuilder& Add(BLayoutItem* item, int32 column, int32 row, 138 int32 columnCount = 1, int32 rowCount = 1); 139 inline ThisBuilder& AddMenuField(BMenuField* menuField, 140 int32 column, int32 row, 141 alignment labelAlignment 142 = B_ALIGN_HORIZONTAL_UNSET, 143 int32 columnCount = 1, int32 rowCount = 1); 144 inline ThisBuilder& AddTextControl(BTextControl* textControl, 145 int32 column, int32 row, 146 alignment labelAlignment 147 = B_ALIGN_HORIZONTAL_UNSET, 148 int32 columnCount = 1, int32 rowCount = 1); 149 150 inline GroupBuilder AddGroup(orientation orientation, 151 float spacing, int32 column, int32 row, 152 int32 columnCount = 1, int32 rowCount = 1); 153 inline GroupBuilder AddGroup(BGroupView* groupView, int32 column, 154 int32 row, int32 columnCount = 1, 155 int32 rowCount = 1); 156 inline GroupBuilder AddGroup(BGroupLayout* groupLayout, 157 int32 column, int32 row, 158 int32 columnCount = 1, int32 rowCount = 1); 159 160 inline GridBuilder AddGrid(float horizontalSpacing, 161 float verticalSpacing, int32 column, 162 int32 row, int32 columnCount = 1, 163 int32 rowCount = 1); 164 inline GridBuilder AddGrid(BGridLayout* gridLayout, 165 int32 column, int32 row, 166 int32 columnCount = 1, int32 rowCount = 1); 167 inline GridBuilder AddGrid(BGridView* gridView, 168 int32 column, int32 row, 169 int32 columnCount = 1, int32 rowCount = 1); 170 171 inline SplitBuilder AddSplit(orientation orientation, 172 float spacing, int32 column, int32 row, 173 int32 columnCount = 1, int32 rowCount = 1); 174 inline SplitBuilder AddSplit(BSplitView* splitView, int32 column, 175 int32 row, int32 columnCount = 1, 176 int32 rowCount = 1); 177 178 inline ThisBuilder& SetColumnWeight(int32 column, float weight); 179 inline ThisBuilder& SetRowWeight(int32 row, float weight); 180 181 inline ThisBuilder& SetInsets(float left, float top, float right, 182 float bottom); 183 184 inline operator BGridLayout*(); 185 186private: 187 BGridLayout* fLayout; 188}; 189 190 191template<typename ParentBuilder> 192class Split : public Base<ParentBuilder> { 193public: 194 typedef Split<ParentBuilder> ThisBuilder; 195 typedef Group<ThisBuilder> GroupBuilder; 196 typedef Grid<ThisBuilder> GridBuilder; 197 typedef Split<ThisBuilder> SplitBuilder; 198 199public: 200 inline Split(orientation orientation = B_HORIZONTAL, 201 float spacing = 0.0f); 202 inline Split(BSplitView* view); 203 204 inline BSplitView* View() const; 205 inline ThisBuilder& GetView(BView** _view); 206 inline ThisBuilder& GetSplitView(BSplitView** _view); 207 208 inline ThisBuilder& Add(BView* view); 209 inline ThisBuilder& Add(BView* view, float weight); 210 inline ThisBuilder& Add(BLayoutItem* item); 211 inline ThisBuilder& Add(BLayoutItem* item, float weight); 212 213 inline GroupBuilder AddGroup(orientation orientation, 214 float spacing = 0.0f, float weight = 1.0f); 215 inline GroupBuilder AddGroup(BGroupView* groupView, 216 float weight = 1.0f); 217 inline GroupBuilder AddGroup(BGroupLayout* groupLayout, 218 float weight = 1.0f); 219 220 inline GridBuilder AddGrid(float horizontalSpacing = 0.0f, 221 float verticalSpacing = 0.0f, 222 float weight = 1.0f); 223 inline GridBuilder AddGrid(BGridView* gridView, 224 float weight = 1.0f); 225 inline GridBuilder AddGrid(BGridLayout* gridLayout, 226 float weight = 1.0f); 227 228 inline SplitBuilder AddSplit(orientation orientation, 229 float spacing = 0.0f, float weight = 1.0f); 230 inline SplitBuilder AddSplit(BSplitView* splitView, 231 float weight = 1.0f); 232 233 inline ThisBuilder& SetCollapsible(bool collapsible); 234 inline ThisBuilder& SetCollapsible(int32 index, bool collapsible); 235 inline ThisBuilder& SetCollapsible(int32 first, int32 last, 236 bool collapsible); 237 238 inline ThisBuilder& SetInsets(float left, float top, float right, 239 float bottom); 240 241 inline operator BSplitView*(); 242 243private: 244 BSplitView* fView; 245}; 246