1/* 2 * Copyright 2009-2012, Haiku, Inc. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 */ 5#ifndef _LAYOUT_BUILDER_H 6#define _LAYOUT_BUILDER_H 7 8 9#include <new> 10 11#include <GridLayout.h> 12#include <GridView.h> 13#include <GroupLayout.h> 14#include <GroupView.h> 15#include <Menu.h> 16#include <MenuField.h> 17#include <MenuItem.h> 18#include <SpaceLayoutItem.h> 19#include <SplitView.h> 20#include <TextControl.h> 21#include <Window.h> 22 23 24namespace BLayoutBuilder { 25 26template<typename ParentBuilder> class Base; 27template<typename ParentBuilder = void*> class Group; 28template<typename ParentBuilder = void*> class Grid; 29template<typename ParentBuilder = void*> class Split; 30template<typename ParentBuilder = void*> class Menu; 31template<typename ParentBuilder = void*> class MenuItem; 32 33 34template<typename ParentBuilder> 35class Base { 36protected: 37 inline Base(); 38 39public: 40 inline void SetParent(ParentBuilder* parent); 41 // conceptually private 42 inline ParentBuilder& End(); 43 44protected: 45 ParentBuilder* fParent; 46}; 47 48 49template<typename ParentBuilder> 50class Group : public Base<ParentBuilder> { 51public: 52 typedef Group<ParentBuilder> ThisBuilder; 53 typedef Group<ThisBuilder> GroupBuilder; 54 typedef Grid<ThisBuilder> GridBuilder; 55 typedef Split<ThisBuilder> SplitBuilder; 56 57public: 58 inline Group(enum orientation orientation 59 = B_HORIZONTAL, 60 float spacing = B_USE_DEFAULT_SPACING); 61 inline Group(BWindow* window, 62 enum orientation orientation = B_HORIZONTAL, 63 float spacing = B_USE_DEFAULT_SPACING); 64 inline Group(BView* view, 65 enum orientation orientation = B_HORIZONTAL, 66 float spacing = B_USE_DEFAULT_SPACING); 67 inline Group(BGroupLayout* layout); 68 inline Group(BGroupView* view); 69 70 inline BGroupLayout* Layout() const; 71 inline BView* View() const; 72 inline ThisBuilder& GetLayout(BGroupLayout** _layout); 73 inline ThisBuilder& GetView(BView** _view); 74 75 inline ThisBuilder& Add(BView* view); 76 inline ThisBuilder& Add(BView* view, float weight); 77 inline ThisBuilder& Add(BLayoutItem* item); 78 inline ThisBuilder& Add(BLayoutItem* item, float weight); 79 80 inline GroupBuilder AddGroup(enum orientation orientation, 81 float spacing = B_USE_DEFAULT_SPACING, 82 float weight = 1.0f); 83 inline GroupBuilder AddGroup(BGroupView* groupView, 84 float weight = 1.0f); 85 inline GroupBuilder AddGroup(BGroupLayout* groupLayout, 86 float weight = 1.0f); 87 88 inline GridBuilder AddGrid(float horizontal 89 = B_USE_DEFAULT_SPACING, 90 float vertical = B_USE_DEFAULT_SPACING, 91 float weight = 1.0f); 92 inline GridBuilder AddGrid(BGridLayout* gridLayout, 93 float weight = 1.0f); 94 inline GridBuilder AddGrid(BGridView* gridView, 95 float weight = 1.0f); 96 97 inline SplitBuilder AddSplit(enum orientation orientation, 98 float spacing = B_USE_DEFAULT_SPACING, 99 float weight = 1.0f); 100 inline SplitBuilder AddSplit(BSplitView* splitView, 101 float weight = 1.0f); 102 103 inline ThisBuilder& AddGlue(float weight = 1.0f); 104 inline ThisBuilder& AddStrut(float size); 105 106 inline ThisBuilder& SetInsets(float left, float top, float right, 107 float bottom); 108 inline ThisBuilder& SetInsets(float horizontal, float vertical); 109 inline ThisBuilder& SetInsets(float insets); 110 111 inline ThisBuilder& SetExplicitMinSize(BSize size); 112 inline ThisBuilder& SetExplicitMaxSize(BSize size); 113 inline ThisBuilder& SetExplicitPreferredSize(BSize size); 114 inline ThisBuilder& SetExplicitAlignment(BAlignment alignment); 115 116 inline operator BGroupLayout*(); 117 118private: 119 BGroupLayout* fLayout; 120}; 121 122 123template<typename ParentBuilder> 124class Grid : public Base<ParentBuilder> { 125public: 126 typedef Grid<ParentBuilder> ThisBuilder; 127 typedef Group<ThisBuilder> GroupBuilder; 128 typedef Grid<ThisBuilder> GridBuilder; 129 typedef Split<ThisBuilder> SplitBuilder; 130 131public: 132 inline Grid(float horizontal 133 = B_USE_DEFAULT_SPACING, 134 float vertical = B_USE_DEFAULT_SPACING); 135 inline Grid(BWindow* window, 136 float horizontal = B_USE_DEFAULT_SPACING, 137 float vertical = B_USE_DEFAULT_SPACING); 138 inline Grid(BView* view, 139 float horizontal = B_USE_DEFAULT_SPACING, 140 float vertical = B_USE_DEFAULT_SPACING); 141 inline Grid(BGridLayout* layout); 142 inline Grid(BGridView* view); 143 144 inline BGridLayout* Layout() const; 145 inline BView* View() const; 146 inline ThisBuilder& GetLayout(BGridLayout** _layout); 147 inline ThisBuilder& GetView(BView** _view); 148 149 inline ThisBuilder& Add(BView* view, int32 column, int32 row, 150 int32 columnCount = 1, int32 rowCount = 1); 151 inline ThisBuilder& Add(BLayoutItem* item, int32 column, int32 row, 152 int32 columnCount = 1, int32 rowCount = 1); 153 inline ThisBuilder& AddMenuField(BMenuField* menuField, 154 int32 column, int32 row, 155 alignment labelAlignment 156 = B_ALIGN_HORIZONTAL_UNSET, 157 int32 labelColumnCount = 1, 158 int32 fieldColumnCount = 1, 159 int32 rowCount = 1); 160 inline ThisBuilder& AddTextControl(BTextControl* textControl, 161 int32 column, int32 row, 162 alignment labelAlignment 163 = B_ALIGN_HORIZONTAL_UNSET, 164 int32 labelColumnCount = 1, 165 int32 textColumnCount = 1, 166 int32 rowCount = 1); 167 168 inline GroupBuilder AddGroup(enum 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(enum 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& AddGlue(int32 column, int32 row, 197 int32 columnCount = 1, int32 rowCount = 1); 198 199 inline ThisBuilder& SetColumnWeight(int32 column, float weight); 200 inline ThisBuilder& SetRowWeight(int32 row, float weight); 201 202 inline ThisBuilder& SetInsets(float left, float top, float right, 203 float bottom); 204 inline ThisBuilder& SetInsets(float horizontal, float vertical); 205 inline ThisBuilder& SetInsets(float insets); 206 207 inline ThisBuilder& SetExplicitMinSize(BSize size); 208 inline ThisBuilder& SetExplicitMaxSize(BSize size); 209 inline ThisBuilder& SetExplicitPreferredSize(BSize size); 210 inline ThisBuilder& SetExplicitAlignment(BAlignment alignment); 211 212 inline operator BGridLayout*(); 213 214private: 215 BGridLayout* fLayout; 216}; 217 218 219template<typename ParentBuilder> 220class Split : public Base<ParentBuilder> { 221public: 222 typedef Split<ParentBuilder> ThisBuilder; 223 typedef Group<ThisBuilder> GroupBuilder; 224 typedef Grid<ThisBuilder> GridBuilder; 225 typedef Split<ThisBuilder> SplitBuilder; 226 227public: 228 inline Split(enum orientation orientation 229 = B_HORIZONTAL, 230 float spacing = B_USE_DEFAULT_SPACING); 231 inline Split(BSplitView* view); 232 233 inline BSplitView* View() const; 234 inline ThisBuilder& GetView(BView** _view); 235 inline ThisBuilder& GetSplitView(BSplitView** _view); 236 237 inline ThisBuilder& Add(BView* view); 238 inline ThisBuilder& Add(BView* view, float weight); 239 inline ThisBuilder& Add(BLayoutItem* item); 240 inline ThisBuilder& Add(BLayoutItem* item, float weight); 241 242 inline GroupBuilder AddGroup(enum orientation orientation, 243 float spacing = B_USE_DEFAULT_SPACING, 244 float weight = 1.0f); 245 inline GroupBuilder AddGroup(BGroupView* groupView, 246 float weight = 1.0f); 247 inline GroupBuilder AddGroup(BGroupLayout* groupLayout, 248 float weight = 1.0f); 249 250 inline GridBuilder AddGrid(float horizontal 251 = B_USE_DEFAULT_SPACING, 252 float vertical = B_USE_DEFAULT_SPACING, 253 float weight = 1.0f); 254 inline GridBuilder AddGrid(BGridView* gridView, 255 float weight = 1.0f); 256 inline GridBuilder AddGrid(BGridLayout* gridLayout, 257 float weight = 1.0f); 258 259 inline SplitBuilder AddSplit(enum orientation orientation, 260 float spacing = B_USE_DEFAULT_SPACING, 261 float weight = 1.0f); 262 inline SplitBuilder AddSplit(BSplitView* splitView, 263 float weight = 1.0f); 264 265 inline ThisBuilder& SetCollapsible(bool collapsible); 266 inline ThisBuilder& SetCollapsible(int32 index, bool collapsible); 267 inline ThisBuilder& SetCollapsible(int32 first, int32 last, 268 bool collapsible); 269 270 inline ThisBuilder& SetInsets(float left, float top, float right, 271 float bottom); 272 inline ThisBuilder& SetInsets(float horizontal, float vertical); 273 inline ThisBuilder& SetInsets(float insets); 274 275 inline operator BSplitView*(); 276 277private: 278 BSplitView* fView; 279}; 280 281 282template<typename ParentBuilder> 283class Menu : public Base<ParentBuilder> { 284public: 285 typedef Menu<ParentBuilder> ThisBuilder; 286 typedef MenuItem<ParentBuilder> ItemBuilder; 287 typedef Menu<ThisBuilder> MenuBuilder; 288 289public: 290 inline Menu(BMenu* menu); 291 292 inline ThisBuilder& GetMenu(BMenu*& _menu); 293 294 inline ItemBuilder AddItem(BMenuItem* item); 295 inline ItemBuilder AddItem(BMenu* menu); 296 inline ItemBuilder AddItem(const char* label, BMessage* message, 297 char shortcut = 0, uint32 modifiers = 0); 298 inline ItemBuilder AddItem(const char* label, uint32 messageWhat, 299 char shortcut = 0, uint32 modifiers = 0); 300 301 inline MenuBuilder AddMenu(BMenu* menu); 302 inline MenuBuilder AddMenu(const char* title, 303 menu_layout layout = B_ITEMS_IN_COLUMN); 304 305 inline ThisBuilder& AddSeparator(); 306 307private: 308 BMenu* fMenu; 309}; 310 311 312template<typename ParentBuilder> 313class MenuItem : public Menu<ParentBuilder> { 314public: 315 typedef MenuItem<ParentBuilder> ThisBuilder; 316 317public: 318 inline MenuItem(ParentBuilder* parentBuilder, 319 BMenu* menu, BMenuItem* item); 320 321 inline ThisBuilder& GetItem(BMenuItem*& _item); 322 323 inline ThisBuilder& SetEnabled(bool enabled); 324 325private: 326 BMenuItem* fMenuItem; 327}; 328 329 330// #pragma mark - Base 331 332 333template<typename ParentBuilder> 334Base<ParentBuilder>::Base() 335 : 336 fParent(NULL) 337{ 338} 339 340 341template<typename ParentBuilder> 342void 343Base<ParentBuilder>::SetParent(ParentBuilder* parent) 344{ 345 fParent = parent; 346} 347 348 349template<typename ParentBuilder> 350ParentBuilder& 351Base<ParentBuilder>::End() 352{ 353 return *fParent; 354} 355 356 357// #pragma mark - Group 358 359 360template<typename ParentBuilder> 361Group<ParentBuilder>::Group(enum orientation orientation, float spacing) 362 : 363 fLayout((new BGroupView(orientation, spacing))->GroupLayout()) 364{ 365} 366 367 368template<typename ParentBuilder> 369Group<ParentBuilder>::Group(BWindow* window, enum orientation orientation, 370 float spacing) 371 : 372 fLayout(new BGroupLayout(orientation, spacing)) 373{ 374 window->SetLayout(fLayout); 375 376 fLayout->Owner()->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 377 // TODO: we get a white background if we don't do this 378} 379 380 381template<typename ParentBuilder> 382Group<ParentBuilder>::Group(BView* view, enum orientation orientation, 383 float spacing) 384 : 385 fLayout(new BGroupLayout(orientation, spacing)) 386{ 387 view->SetLayout(fLayout); 388 view->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 389 // TODO: we get a white background if we don't do this 390} 391 392 393template<typename ParentBuilder> 394Group<ParentBuilder>::Group(BGroupLayout* layout) 395 : 396 fLayout(layout) 397{ 398} 399 400 401template<typename ParentBuilder> 402Group<ParentBuilder>::Group(BGroupView* view) 403 : 404 fLayout(view->GroupLayout()) 405{ 406} 407 408 409template<typename ParentBuilder> 410BGroupLayout* 411Group<ParentBuilder>::Layout() const 412{ 413 return fLayout; 414} 415 416 417template<typename ParentBuilder> 418BView* 419Group<ParentBuilder>::View() const 420{ 421 return fLayout->Owner(); 422} 423 424 425template<typename ParentBuilder> 426typename Group<ParentBuilder>::ThisBuilder& 427Group<ParentBuilder>::GetLayout(BGroupLayout** _layout) 428{ 429 *_layout = fLayout; 430 return *this; 431} 432 433 434template<typename ParentBuilder> 435typename Group<ParentBuilder>::ThisBuilder& 436Group<ParentBuilder>::GetView(BView** _view) 437{ 438 *_view = fLayout->Owner(); 439 return *this; 440} 441 442 443template<typename ParentBuilder> 444typename Group<ParentBuilder>::ThisBuilder& 445Group<ParentBuilder>::Add(BView* view) 446{ 447 fLayout->AddView(view); 448 return *this; 449} 450 451 452template<typename ParentBuilder> 453typename Group<ParentBuilder>::ThisBuilder& 454Group<ParentBuilder>::Add(BView* view, float weight) 455{ 456 fLayout->AddView(view, weight); 457 return *this; 458} 459 460 461template<typename ParentBuilder> 462typename Group<ParentBuilder>::ThisBuilder& 463Group<ParentBuilder>::Add(BLayoutItem* item) 464{ 465 fLayout->AddItem(item); 466 return *this; 467} 468 469 470template<typename ParentBuilder> 471typename Group<ParentBuilder>::ThisBuilder& 472Group<ParentBuilder>::Add(BLayoutItem* item, float weight) 473{ 474 fLayout->AddItem(item, weight); 475 return *this; 476} 477 478 479template<typename ParentBuilder> 480typename Group<ParentBuilder>::GroupBuilder 481Group<ParentBuilder>::AddGroup(enum orientation orientation, float spacing, 482 float weight) 483{ 484 GroupBuilder builder(new BGroupLayout(orientation, spacing)); 485 builder.SetParent(this); 486 fLayout->AddItem(builder.Layout(), weight); 487 return builder; 488} 489 490 491template<typename ParentBuilder> 492typename Group<ParentBuilder>::GroupBuilder 493Group<ParentBuilder>::AddGroup(BGroupView* groupView, float weight) 494{ 495 GroupBuilder builder(groupView); 496 builder.SetParent(this); 497 fLayout->AddItem(builder.Layout(), weight); 498 return builder; 499} 500 501 502template<typename ParentBuilder> 503typename Group<ParentBuilder>::GroupBuilder 504Group<ParentBuilder>::AddGroup(BGroupLayout* groupLayout, float weight) 505{ 506 GroupBuilder builder(groupLayout); 507 builder.SetParent(this); 508 fLayout->AddItem(builder.Layout(), weight); 509 return builder; 510} 511 512 513template<typename ParentBuilder> 514typename Group<ParentBuilder>::GridBuilder 515Group<ParentBuilder>::AddGrid(float horizontalSpacing, 516 float verticalSpacing, float weight) 517{ 518 GridBuilder builder(new BGridLayout(horizontalSpacing, verticalSpacing)); 519 builder.SetParent(this); 520 fLayout->AddItem(builder.Layout(), weight); 521 return builder; 522} 523 524 525template<typename ParentBuilder> 526typename Group<ParentBuilder>::GridBuilder 527Group<ParentBuilder>::AddGrid(BGridLayout* gridLayout, float weight) 528{ 529 GridBuilder builder(gridLayout); 530 builder.SetParent(this); 531 fLayout->AddItem(builder.Layout(), weight); 532 return builder; 533} 534 535 536template<typename ParentBuilder> 537typename Group<ParentBuilder>::GridBuilder 538Group<ParentBuilder>::AddGrid(BGridView* gridView, float weight) 539{ 540 GridBuilder builder(gridView); 541 builder.SetParent(this); 542 fLayout->AddItem(builder.Layout(), weight); 543 return builder; 544} 545 546 547template<typename ParentBuilder> 548typename Group<ParentBuilder>::SplitBuilder 549Group<ParentBuilder>::AddSplit(enum orientation orientation, float spacing, 550 float weight) 551{ 552 SplitBuilder builder(orientation, spacing); 553 builder.SetParent(this); 554 fLayout->AddView(builder.View(), weight); 555 return builder; 556} 557 558 559template<typename ParentBuilder> 560typename Group<ParentBuilder>::SplitBuilder 561Group<ParentBuilder>::AddSplit(BSplitView* splitView, float weight) 562{ 563 SplitBuilder builder(splitView); 564 builder.SetParent(this); 565 fLayout->AddView(builder.View(), weight); 566 return builder; 567} 568 569 570template<typename ParentBuilder> 571typename Group<ParentBuilder>::ThisBuilder& 572Group<ParentBuilder>::AddGlue(float weight) 573{ 574 fLayout->AddItem(BSpaceLayoutItem::CreateGlue(), weight); 575 return *this; 576} 577 578 579template<typename ParentBuilder> 580typename Group<ParentBuilder>::ThisBuilder& 581Group<ParentBuilder>::AddStrut(float size) 582{ 583 if (fLayout->Orientation() == B_HORIZONTAL) 584 fLayout->AddItem(BSpaceLayoutItem::CreateHorizontalStrut(size)); 585 else 586 fLayout->AddItem(BSpaceLayoutItem::CreateVerticalStrut(size)); 587 588 return *this; 589} 590 591 592template<typename ParentBuilder> 593typename Group<ParentBuilder>::ThisBuilder& 594Group<ParentBuilder>::SetInsets(float left, float top, float right, 595 float bottom) 596{ 597 fLayout->SetInsets(left, top, right, bottom); 598 return *this; 599} 600 601 602template<typename ParentBuilder> 603typename Group<ParentBuilder>::ThisBuilder& 604Group<ParentBuilder>::SetInsets(float horizontal, float vertical) 605{ 606 fLayout->SetInsets(horizontal, vertical); 607 return *this; 608} 609 610 611template<typename ParentBuilder> 612typename Group<ParentBuilder>::ThisBuilder& 613Group<ParentBuilder>::SetInsets(float insets) 614{ 615 fLayout->SetInsets(insets); 616 return *this; 617} 618 619 620template<typename ParentBuilder> 621typename Group<ParentBuilder>::ThisBuilder& 622Group<ParentBuilder>::SetExplicitMinSize(BSize size) 623{ 624 fLayout->SetExplicitMinSize(size); 625 return *this; 626} 627 628 629template<typename ParentBuilder> 630typename Group<ParentBuilder>::ThisBuilder& 631Group<ParentBuilder>::SetExplicitMaxSize(BSize size) 632{ 633 fLayout->SetExplicitMaxSize(size); 634 return *this; 635} 636 637 638template<typename ParentBuilder> 639typename Group<ParentBuilder>::ThisBuilder& 640Group<ParentBuilder>::SetExplicitPreferredSize(BSize size) 641{ 642 fLayout->SetExplicitPreferredSize(size); 643 return *this; 644} 645 646 647template<typename ParentBuilder> 648typename Group<ParentBuilder>::ThisBuilder& 649Group<ParentBuilder>::SetExplicitAlignment(BAlignment alignment) 650{ 651 fLayout->SetExplicitAlignment(alignment); 652 return *this; 653} 654 655 656template<typename ParentBuilder> 657Group<ParentBuilder>::operator BGroupLayout*() 658{ 659 return fLayout; 660} 661 662 663// #pragma mark - Grid 664 665 666template<typename ParentBuilder> 667Grid<ParentBuilder>::Grid(float horizontalSpacing, float verticalSpacing) 668 : 669 fLayout((new BGridView(horizontalSpacing, verticalSpacing))->GridLayout()) 670{ 671} 672 673 674template<typename ParentBuilder> 675Grid<ParentBuilder>::Grid(BWindow* window, float horizontalSpacing, 676 float verticalSpacing) 677 : 678 fLayout(new BGridLayout(horizontalSpacing, verticalSpacing)) 679{ 680 window->SetLayout(fLayout); 681 682 fLayout->Owner()->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 683 // TODO: we get a white background if we don't do this 684} 685 686 687template<typename ParentBuilder> 688Grid<ParentBuilder>::Grid(BView* view, float horizontalSpacing, 689 float verticalSpacing) 690 : 691 fLayout(new BGridLayout(horizontalSpacing, verticalSpacing)) 692{ 693 view->SetLayout(fLayout); 694 view->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 695 // TODO: we get a white background if we don't do this 696} 697 698 699template<typename ParentBuilder> 700Grid<ParentBuilder>::Grid(BGridLayout* layout) 701 : 702 fLayout(layout) 703{ 704} 705 706 707template<typename ParentBuilder> 708Grid<ParentBuilder>::Grid(BGridView* view) 709 : 710 fLayout(view->GridLayout()) 711{ 712} 713 714 715template<typename ParentBuilder> 716BGridLayout* 717Grid<ParentBuilder>::Layout() const 718{ 719 return fLayout; 720} 721 722 723template<typename ParentBuilder> 724BView* 725Grid<ParentBuilder>::View() const 726{ 727 return fLayout->Owner(); 728} 729 730 731template<typename ParentBuilder> 732typename Grid<ParentBuilder>::ThisBuilder& 733Grid<ParentBuilder>::GetLayout(BGridLayout** _layout) 734{ 735 *_layout = fLayout; 736 return *this; 737} 738 739 740template<typename ParentBuilder> 741typename Grid<ParentBuilder>::ThisBuilder& 742Grid<ParentBuilder>::GetView(BView** _view) 743{ 744 *_view = fLayout->Owner(); 745 return *this; 746} 747 748 749template<typename ParentBuilder> 750typename Grid<ParentBuilder>::ThisBuilder& 751Grid<ParentBuilder>::Add(BView* view, int32 column, int32 row, 752 int32 columnCount, int32 rowCount) 753{ 754 fLayout->AddView(view, column, row, columnCount, rowCount); 755 return *this; 756} 757 758 759template<typename ParentBuilder> 760typename Grid<ParentBuilder>::ThisBuilder& 761Grid<ParentBuilder>::Add(BLayoutItem* item, int32 column, int32 row, 762 int32 columnCount, int32 rowCount) 763{ 764 fLayout->AddItem(item, column, row, columnCount, rowCount); 765 return *this; 766} 767 768 769template<typename ParentBuilder> 770typename Grid<ParentBuilder>::ThisBuilder& 771Grid<ParentBuilder>::AddMenuField(BMenuField* menuField, int32 column, 772 int32 row, alignment labelAlignment, int32 labelColumnCount, 773 int32 fieldColumnCount, int32 rowCount) 774{ 775 BLayoutItem* item = menuField->CreateLabelLayoutItem(); 776 item->SetExplicitAlignment( 777 BAlignment(labelAlignment, B_ALIGN_VERTICAL_UNSET)); 778 fLayout->AddItem(item, column, row, labelColumnCount, rowCount); 779 fLayout->AddItem(menuField->CreateMenuBarLayoutItem(), 780 column + labelColumnCount, row, fieldColumnCount, rowCount); 781 return *this; 782} 783 784 785template<typename ParentBuilder> 786typename Grid<ParentBuilder>::ThisBuilder& 787Grid<ParentBuilder>::AddTextControl(BTextControl* textControl, int32 column, 788 int32 row, alignment labelAlignment, int32 labelColumnCount, 789 int32 textColumnCount, int32 rowCount) 790{ 791 BLayoutItem* item = textControl->CreateLabelLayoutItem(); 792 item->SetExplicitAlignment( 793 BAlignment(labelAlignment, B_ALIGN_VERTICAL_UNSET)); 794 fLayout->AddItem(item, column, row, labelColumnCount, rowCount); 795 fLayout->AddItem(textControl->CreateTextViewLayoutItem(), 796 column + labelColumnCount, row, textColumnCount, rowCount); 797 return *this; 798} 799 800 801template<typename ParentBuilder> 802typename Grid<ParentBuilder>::GroupBuilder 803Grid<ParentBuilder>::AddGroup(enum orientation orientation, float spacing, 804 int32 column, int32 row, int32 columnCount, int32 rowCount) 805{ 806 GroupBuilder builder(new BGroupLayout(orientation, spacing)); 807 builder.SetParent(this); 808 fLayout->AddItem(builder.Layout(), column, row, columnCount, rowCount); 809 return builder; 810} 811 812 813template<typename ParentBuilder> 814typename Grid<ParentBuilder>::GroupBuilder 815Grid<ParentBuilder>::AddGroup(BGroupView* groupView, int32 column, int32 row, 816 int32 columnCount, int32 rowCount) 817{ 818 GroupBuilder builder(groupView); 819 builder.SetParent(this); 820 fLayout->AddItem(builder.Layout(), column, row, columnCount, rowCount); 821 return builder; 822} 823 824 825template<typename ParentBuilder> 826typename Grid<ParentBuilder>::GroupBuilder 827Grid<ParentBuilder>::AddGroup(BGroupLayout* groupLayout, int32 column, 828 int32 row, int32 columnCount, int32 rowCount) 829{ 830 GroupBuilder builder(groupLayout); 831 builder.SetParent(this); 832 fLayout->AddItem(builder.Layout(), column, row, columnCount, rowCount); 833 return builder; 834} 835 836 837template<typename ParentBuilder> 838typename Grid<ParentBuilder>::GridBuilder 839Grid<ParentBuilder>::AddGrid(float horizontalSpacing, float verticalSpacing, 840 int32 column, int32 row, int32 columnCount, int32 rowCount) 841{ 842 GridBuilder builder(new BGridLayout(horizontalSpacing, verticalSpacing)); 843 builder.SetParent(this); 844 fLayout->AddItem(builder.Layout(), column, row, columnCount, rowCount); 845 return builder; 846} 847 848 849template<typename ParentBuilder> 850typename Grid<ParentBuilder>::GridBuilder 851Grid<ParentBuilder>::AddGrid(BGridView* gridView, int32 column, int32 row, 852 int32 columnCount, int32 rowCount) 853{ 854 GridBuilder builder(gridView); 855 builder.SetParent(this); 856 fLayout->AddView(builder.View(), column, row, columnCount, rowCount); 857 return builder; 858} 859 860 861template<typename ParentBuilder> 862typename Grid<ParentBuilder>::SplitBuilder 863Grid<ParentBuilder>::AddSplit(enum orientation orientation, float spacing, 864 int32 column, int32 row, int32 columnCount, int32 rowCount) 865{ 866 SplitBuilder builder(orientation, spacing); 867 builder.SetParent(this); 868 fLayout->AddView(builder.View(), column, row, columnCount, rowCount); 869 return builder; 870} 871 872 873template<typename ParentBuilder> 874typename Grid<ParentBuilder>::SplitBuilder 875Grid<ParentBuilder>::AddSplit(BSplitView* splitView, int32 column, int32 row, 876 int32 columnCount, int32 rowCount) 877{ 878 SplitBuilder builder(splitView); 879 builder.SetParent(this); 880 fLayout->AddView(builder.View(), column, row, columnCount, rowCount); 881 return builder; 882} 883 884 885template<typename ParentBuilder> 886typename Grid<ParentBuilder>::ThisBuilder& 887Grid<ParentBuilder>::AddGlue(int32 column, int32 row, int32 columnCount, 888 int32 rowCount) 889{ 890 fLayout->AddItem(BSpaceLayoutItem::CreateGlue(), column, row, columnCount, 891 rowCount); 892 return *this; 893} 894 895 896template<typename ParentBuilder> 897typename Grid<ParentBuilder>::ThisBuilder& 898Grid<ParentBuilder>::SetColumnWeight(int32 column, float weight) 899{ 900 fLayout->SetColumnWeight(column, weight); 901 return *this; 902} 903 904 905template<typename ParentBuilder> 906typename Grid<ParentBuilder>::ThisBuilder& 907Grid<ParentBuilder>::SetRowWeight(int32 row, float weight) 908{ 909 fLayout->SetRowWeight(row, weight); 910 return *this; 911} 912 913 914template<typename ParentBuilder> 915typename Grid<ParentBuilder>::ThisBuilder& 916Grid<ParentBuilder>::SetInsets(float left, float top, float right, 917 float bottom) 918{ 919 fLayout->SetInsets(left, top, right, bottom); 920 return *this; 921} 922 923 924template<typename ParentBuilder> 925typename Grid<ParentBuilder>::ThisBuilder& 926Grid<ParentBuilder>::SetInsets(float horizontal, float vertical) 927{ 928 fLayout->SetInsets(horizontal, vertical); 929 return *this; 930} 931 932 933template<typename ParentBuilder> 934typename Grid<ParentBuilder>::ThisBuilder& 935Grid<ParentBuilder>::SetInsets(float insets) 936{ 937 fLayout->SetInsets(insets); 938 return *this; 939} 940 941 942template<typename ParentBuilder> 943typename Grid<ParentBuilder>::ThisBuilder& 944Grid<ParentBuilder>::SetExplicitMinSize(BSize size) 945{ 946 fLayout->SetExplicitMinSize(size); 947 return *this; 948} 949 950 951template<typename ParentBuilder> 952typename Grid<ParentBuilder>::ThisBuilder& 953Grid<ParentBuilder>::SetExplicitMaxSize(BSize size) 954{ 955 fLayout->SetExplicitMaxSize(size); 956 return *this; 957} 958 959 960template<typename ParentBuilder> 961typename Grid<ParentBuilder>::ThisBuilder& 962Grid<ParentBuilder>::SetExplicitPreferredSize(BSize size) 963{ 964 fLayout->SetExplicitPreferredSize(size); 965 return *this; 966} 967 968 969template<typename ParentBuilder> 970typename Grid<ParentBuilder>::ThisBuilder& 971Grid<ParentBuilder>::SetExplicitAlignment(BAlignment alignment) 972{ 973 fLayout->SetExplicitAlignment(alignment); 974 return *this; 975} 976 977 978template<typename ParentBuilder> 979Grid<ParentBuilder>::operator BGridLayout*() 980{ 981 return fLayout; 982} 983 984 985// #pragma mark - Split 986 987 988template<typename ParentBuilder> 989Split<ParentBuilder>::Split(enum orientation orientation, float spacing) 990 : 991 fView(new BSplitView(orientation, spacing)) 992{ 993} 994 995 996template<typename ParentBuilder> 997Split<ParentBuilder>::Split(BSplitView* view) 998 : 999 fView(view) 1000{ 1001} 1002 1003 1004template<typename ParentBuilder> 1005BSplitView* 1006Split<ParentBuilder>::View() const 1007{ 1008 return fView; 1009} 1010 1011 1012template<typename ParentBuilder> 1013typename Split<ParentBuilder>::ThisBuilder& 1014Split<ParentBuilder>::GetView(BView** _view) 1015{ 1016 *_view = fView; 1017 return *this; 1018} 1019 1020 1021template<typename ParentBuilder> 1022typename Split<ParentBuilder>::ThisBuilder& 1023Split<ParentBuilder>::GetSplitView(BSplitView** _view) 1024{ 1025 *_view = fView; 1026 return *this; 1027} 1028 1029 1030template<typename ParentBuilder> 1031typename Split<ParentBuilder>::ThisBuilder& 1032Split<ParentBuilder>::Add(BView* view) 1033{ 1034 fView->AddChild(view); 1035 return *this; 1036} 1037 1038 1039template<typename ParentBuilder> 1040typename Split<ParentBuilder>::ThisBuilder& 1041Split<ParentBuilder>::Add(BView* view, float weight) 1042{ 1043 fView->AddChild(view, weight); 1044 return *this; 1045} 1046 1047 1048template<typename ParentBuilder> 1049typename Split<ParentBuilder>::ThisBuilder& 1050Split<ParentBuilder>::Add(BLayoutItem* item) 1051{ 1052 fView->AddChild(item); 1053 return *this; 1054} 1055 1056 1057template<typename ParentBuilder> 1058typename Split<ParentBuilder>::ThisBuilder& 1059Split<ParentBuilder>::Add(BLayoutItem* item, float weight) 1060{ 1061 fView->AddChild(item, weight); 1062 return *this; 1063} 1064 1065 1066template<typename ParentBuilder> 1067typename Split<ParentBuilder>::GroupBuilder 1068Split<ParentBuilder>::AddGroup(enum orientation orientation, float spacing, 1069 float weight) 1070{ 1071 GroupBuilder builder(new BGroupLayout(orientation, spacing)); 1072 builder.SetParent(this); 1073 fView->AddChild(builder.Layout(), weight); 1074 return builder; 1075} 1076 1077 1078template<typename ParentBuilder> 1079typename Split<ParentBuilder>::GroupBuilder 1080Split<ParentBuilder>::AddGroup(BGroupView* groupView, float weight) 1081{ 1082 GroupBuilder builder(groupView); 1083 builder.SetParent(this); 1084 fView->AddChild(builder.Layout(), weight); 1085 return builder; 1086} 1087 1088 1089template<typename ParentBuilder> 1090typename Split<ParentBuilder>::GroupBuilder 1091Split<ParentBuilder>::AddGroup(BGroupLayout* groupLayout, float weight) 1092{ 1093 GroupBuilder builder(groupLayout); 1094 builder.SetParent(this); 1095 fView->AddChild(builder.Layout(), weight); 1096 return builder; 1097} 1098 1099 1100template<typename ParentBuilder> 1101typename Split<ParentBuilder>::GridBuilder 1102Split<ParentBuilder>::AddGrid(float horizontalSpacing, float verticalSpacing, 1103 float weight) 1104{ 1105 GridBuilder builder(new BGridLayout(horizontalSpacing, verticalSpacing)); 1106 builder.SetParent(this); 1107 fView->AddChild(builder.Layout(), weight); 1108 return builder; 1109} 1110 1111 1112template<typename ParentBuilder> 1113typename Split<ParentBuilder>::GridBuilder 1114Split<ParentBuilder>::AddGrid(BGridView* gridView, float weight) 1115{ 1116 GridBuilder builder(gridView); 1117 builder.SetParent(this); 1118 fView->AddChild(builder.Layout(), weight); 1119 return builder; 1120} 1121 1122 1123template<typename ParentBuilder> 1124typename Split<ParentBuilder>::GridBuilder 1125Split<ParentBuilder>::AddGrid(BGridLayout* layout, float weight) 1126{ 1127 GridBuilder builder(layout); 1128 builder.SetParent(this); 1129 fView->AddChild(builder.Layout(), weight); 1130 return builder; 1131} 1132 1133 1134template<typename ParentBuilder> 1135typename Split<ParentBuilder>::SplitBuilder 1136Split<ParentBuilder>::AddSplit(enum orientation orientation, float spacing, 1137 float weight) 1138{ 1139 SplitBuilder builder(orientation, spacing); 1140 builder.SetParent(this); 1141 fView->AddChild(builder.View(), weight); 1142 return builder; 1143} 1144 1145 1146template<typename ParentBuilder> 1147typename Split<ParentBuilder>::ThisBuilder& 1148Split<ParentBuilder>::SetCollapsible(bool collapsible) 1149{ 1150 fView->SetCollapsible(collapsible); 1151 return *this; 1152} 1153 1154 1155template<typename ParentBuilder> 1156typename Split<ParentBuilder>::ThisBuilder& 1157Split<ParentBuilder>::SetCollapsible(int32 index, bool collapsible) 1158{ 1159 fView->SetCollapsible(index, collapsible); 1160 return *this; 1161} 1162 1163 1164template<typename ParentBuilder> 1165typename Split<ParentBuilder>::ThisBuilder& 1166Split<ParentBuilder>::SetCollapsible(int32 first, int32 last, bool collapsible) 1167{ 1168 fView->SetCollapsible(first, last, collapsible); 1169 return *this; 1170} 1171 1172 1173template<typename ParentBuilder> 1174typename Split<ParentBuilder>::ThisBuilder& 1175Split<ParentBuilder>::SetInsets(float left, float top, float right, 1176 float bottom) 1177{ 1178 fView->SetInsets(left, top, right, bottom); 1179 return *this; 1180} 1181 1182 1183template<typename ParentBuilder> 1184typename Split<ParentBuilder>::ThisBuilder& 1185Split<ParentBuilder>::SetInsets(float horizontal, float vertical) 1186{ 1187 fView->SetInsets(horizontal, vertical); 1188 return *this; 1189} 1190 1191 1192template<typename ParentBuilder> 1193typename Split<ParentBuilder>::ThisBuilder& 1194Split<ParentBuilder>::SetInsets(float insets) 1195{ 1196 fView->SetInsets(insets); 1197 return *this; 1198} 1199 1200 1201template<typename ParentBuilder> 1202Split<ParentBuilder>::operator BSplitView*() 1203{ 1204 return fView; 1205} 1206 1207 1208// #pragma mark - Menu 1209 1210 1211template<typename ParentBuilder> 1212Menu<ParentBuilder>::Menu(BMenu* menu) 1213 : 1214 fMenu(menu) 1215{ 1216} 1217 1218 1219template<typename ParentBuilder> 1220typename Menu<ParentBuilder>::ThisBuilder& 1221Menu<ParentBuilder>::GetMenu(BMenu*& _menu) 1222{ 1223 _menu = fMenu; 1224 return *this; 1225} 1226 1227 1228template<typename ParentBuilder> 1229typename Menu<ParentBuilder>::ItemBuilder 1230Menu<ParentBuilder>::AddItem(BMenuItem* item) 1231{ 1232 fMenu->AddItem(item); 1233 return MenuItem<ParentBuilder>(this->fParent, fMenu, item); 1234} 1235 1236 1237template<typename ParentBuilder> 1238typename Menu<ParentBuilder>::ItemBuilder 1239Menu<ParentBuilder>::AddItem(BMenu* menu) 1240{ 1241 if (!fMenu->AddItem(menu)) 1242 throw std::bad_alloc(); 1243 1244 return MenuItem<ParentBuilder>(this->fParent, fMenu, 1245 fMenu->ItemAt(fMenu->CountItems() - 1)); 1246} 1247 1248 1249template<typename ParentBuilder> 1250typename Menu<ParentBuilder>::ItemBuilder 1251Menu<ParentBuilder>::AddItem(const char* label, BMessage* message, 1252 char shortcut, uint32 modifiers) 1253{ 1254 BMenuItem* item = new BMenuItem(label, message, shortcut, modifiers); 1255 if (!fMenu->AddItem(item)) 1256 delete item; 1257 1258 return MenuItem<ParentBuilder>(this->fParent, fMenu, item); 1259} 1260 1261 1262template<typename ParentBuilder> 1263typename Menu<ParentBuilder>::ItemBuilder 1264Menu<ParentBuilder>::AddItem(const char* label, uint32 messageWhat, 1265 char shortcut, uint32 modifiers) 1266{ 1267 BMessage* message = new BMessage(messageWhat); 1268 BMenuItem* item; 1269 try { 1270 item = new BMenuItem(label, message, shortcut, modifiers); 1271 } catch (...) { 1272 delete message; 1273 throw; 1274 } 1275 1276 if (!fMenu->AddItem(item)) 1277 delete item; 1278 1279 return MenuItem<ParentBuilder>(this->fParent, fMenu, item); 1280} 1281 1282 1283template<typename ParentBuilder> 1284typename Menu<ParentBuilder>::ThisBuilder& 1285Menu<ParentBuilder>::AddSeparator() 1286{ 1287 fMenu->AddSeparatorItem(); 1288 return *this; 1289} 1290 1291 1292template<typename ParentBuilder> 1293typename Menu<ParentBuilder>::MenuBuilder 1294Menu<ParentBuilder>::AddMenu(BMenu* menu) 1295{ 1296 if (!fMenu->AddItem(menu)) 1297 throw std::bad_alloc(); 1298 1299 MenuBuilder builder(menu); 1300 builder.SetParent(this); 1301 return builder; 1302} 1303 1304 1305template<typename ParentBuilder> 1306typename Menu<ParentBuilder>::MenuBuilder 1307Menu<ParentBuilder>::AddMenu(const char* title, menu_layout layout) 1308{ 1309 BMenu* menu = new BMenu(title, layout); 1310 if (!fMenu->AddItem(menu)) { 1311 delete menu; 1312 throw std::bad_alloc(); 1313 } 1314 1315 MenuBuilder builder(menu); 1316 builder.SetParent(this); 1317 return builder; 1318} 1319 1320 1321// #pragma mark - MenuItem 1322 1323 1324template<typename ParentBuilder> 1325MenuItem<ParentBuilder>::MenuItem(ParentBuilder* parentBuilder, BMenu* menu, 1326 BMenuItem* item) 1327 : 1328 Menu<ParentBuilder>(menu), 1329 fMenuItem(item) 1330{ 1331 this->SetParent(parentBuilder); 1332} 1333 1334 1335template<typename ParentBuilder> 1336typename MenuItem<ParentBuilder>::ThisBuilder& 1337MenuItem<ParentBuilder>::GetItem(BMenuItem*& _item) 1338{ 1339 _item = fMenuItem; 1340 return *this; 1341} 1342 1343 1344template<typename ParentBuilder> 1345typename MenuItem<ParentBuilder>::ThisBuilder& 1346MenuItem<ParentBuilder>::SetEnabled(bool enabled) 1347{ 1348 fMenuItem->SetEnabled(enabled); 1349 return *this; 1350} 1351 1352 1353} // namespace BLayoutBuilder 1354 1355 1356#endif // _LAYOUT_BUILDER_H 1357