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