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