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(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 118 private: 119 BGroupLayout* fLayout; 120 }; 121 122 123 template<typename ParentBuilder> 124 class Grid : public Base<ParentBuilder> { 125 public: 126 typedef Grid<ParentBuilder> ThisBuilder; 127 typedef Group<ThisBuilder> GroupBuilder; 128 typedef Grid<ThisBuilder> GridBuilder; 129 typedef Split<ThisBuilder> SplitBuilder; 130 131 public: 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 214 private: 215 BGridLayout* fLayout; 216 }; 217 218 219 template<typename ParentBuilder> 220 class Split : public Base<ParentBuilder> { 221 public: 222 typedef Split<ParentBuilder> ThisBuilder; 223 typedef Group<ThisBuilder> GroupBuilder; 224 typedef Grid<ThisBuilder> GridBuilder; 225 typedef Split<ThisBuilder> SplitBuilder; 226 227 public: 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 277 private: 278 BSplitView* fView; 279 }; 280 281 282 template<typename ParentBuilder> 283 class Menu : public Base<ParentBuilder> { 284 public: 285 typedef Menu<ParentBuilder> ThisBuilder; 286 typedef MenuItem<ParentBuilder> ItemBuilder; 287 typedef Menu<ThisBuilder> MenuBuilder; 288 289 public: 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 307 private: 308 BMenu* fMenu; 309 }; 310 311 312 template<typename ParentBuilder> 313 class MenuItem : public Menu<ParentBuilder> { 314 public: 315 typedef MenuItem<ParentBuilder> ThisBuilder; 316 317 public: 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 325 private: 326 BMenuItem* fMenuItem; 327 }; 328 329 330 // #pragma mark - Base 331 332 333 template<typename ParentBuilder> 334 Base<ParentBuilder>::Base() 335 : 336 fParent(NULL) 337 { 338 } 339 340 341 template<typename ParentBuilder> 342 void 343 Base<ParentBuilder>::SetParent(ParentBuilder* parent) 344 { 345 fParent = parent; 346 } 347 348 349 template<typename ParentBuilder> 350 ParentBuilder& 351 Base<ParentBuilder>::End() 352 { 353 return *fParent; 354 } 355 356 357 // #pragma mark - Group 358 359 360 template<typename ParentBuilder> 361 Group<ParentBuilder>::Group(enum orientation orientation, float spacing) 362 : 363 fLayout((new BGroupView(orientation, spacing))->GroupLayout()) 364 { 365 } 366 367 368 template<typename ParentBuilder> 369 Group<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 381 template<typename ParentBuilder> 382 Group<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 393 template<typename ParentBuilder> 394 Group<ParentBuilder>::Group(BGroupLayout* layout) 395 : 396 fLayout(layout) 397 { 398 } 399 400 401 template<typename ParentBuilder> 402 Group<ParentBuilder>::Group(BGroupView* view) 403 : 404 fLayout(view->GroupLayout()) 405 { 406 } 407 408 409 template<typename ParentBuilder> 410 BGroupLayout* 411 Group<ParentBuilder>::Layout() const 412 { 413 return fLayout; 414 } 415 416 417 template<typename ParentBuilder> 418 BView* 419 Group<ParentBuilder>::View() const 420 { 421 return fLayout->Owner(); 422 } 423 424 425 template<typename ParentBuilder> 426 typename Group<ParentBuilder>::ThisBuilder& 427 Group<ParentBuilder>::GetLayout(BGroupLayout** _layout) 428 { 429 *_layout = fLayout; 430 return *this; 431 } 432 433 434 template<typename ParentBuilder> 435 typename Group<ParentBuilder>::ThisBuilder& 436 Group<ParentBuilder>::GetView(BView** _view) 437 { 438 *_view = fLayout->Owner(); 439 return *this; 440 } 441 442 443 template<typename ParentBuilder> 444 typename Group<ParentBuilder>::ThisBuilder& 445 Group<ParentBuilder>::Add(BView* view) 446 { 447 fLayout->AddView(view); 448 return *this; 449 } 450 451 452 template<typename ParentBuilder> 453 typename Group<ParentBuilder>::ThisBuilder& 454 Group<ParentBuilder>::Add(BView* view, float weight) 455 { 456 fLayout->AddView(view, weight); 457 return *this; 458 } 459 460 461 template<typename ParentBuilder> 462 typename Group<ParentBuilder>::ThisBuilder& 463 Group<ParentBuilder>::Add(BLayoutItem* item) 464 { 465 fLayout->AddItem(item); 466 return *this; 467 } 468 469 470 template<typename ParentBuilder> 471 typename Group<ParentBuilder>::ThisBuilder& 472 Group<ParentBuilder>::Add(BLayoutItem* item, float weight) 473 { 474 fLayout->AddItem(item, weight); 475 return *this; 476 } 477 478 479 template<typename ParentBuilder> 480 typename Group<ParentBuilder>::GroupBuilder 481 Group<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 491 template<typename ParentBuilder> 492 typename Group<ParentBuilder>::GroupBuilder 493 Group<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 502 template<typename ParentBuilder> 503 typename Group<ParentBuilder>::GroupBuilder 504 Group<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 513 template<typename ParentBuilder> 514 typename Group<ParentBuilder>::GridBuilder 515 Group<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 525 template<typename ParentBuilder> 526 typename Group<ParentBuilder>::GridBuilder 527 Group<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 536 template<typename ParentBuilder> 537 typename Group<ParentBuilder>::GridBuilder 538 Group<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 547 template<typename ParentBuilder> 548 typename Group<ParentBuilder>::SplitBuilder 549 Group<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 559 template<typename ParentBuilder> 560 typename Group<ParentBuilder>::SplitBuilder 561 Group<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 570 template<typename ParentBuilder> 571 typename Group<ParentBuilder>::ThisBuilder& 572 Group<ParentBuilder>::AddGlue(float weight) 573 { 574 fLayout->AddItem(BSpaceLayoutItem::CreateGlue(), weight); 575 return *this; 576 } 577 578 579 template<typename ParentBuilder> 580 typename Group<ParentBuilder>::ThisBuilder& 581 Group<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 592 template<typename ParentBuilder> 593 typename Group<ParentBuilder>::ThisBuilder& 594 Group<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 602 template<typename ParentBuilder> 603 typename Group<ParentBuilder>::ThisBuilder& 604 Group<ParentBuilder>::SetInsets(float horizontal, float vertical) 605 { 606 fLayout->SetInsets(horizontal, vertical); 607 return *this; 608 } 609 610 611 template<typename ParentBuilder> 612 typename Group<ParentBuilder>::ThisBuilder& 613 Group<ParentBuilder>::SetInsets(float insets) 614 { 615 fLayout->SetInsets(insets); 616 return *this; 617 } 618 619 620 template<typename ParentBuilder> 621 typename Group<ParentBuilder>::ThisBuilder& 622 Group<ParentBuilder>::SetExplicitMinSize(BSize size) 623 { 624 fLayout->SetExplicitMinSize(size); 625 return *this; 626 } 627 628 629 template<typename ParentBuilder> 630 typename Group<ParentBuilder>::ThisBuilder& 631 Group<ParentBuilder>::SetExplicitMaxSize(BSize size) 632 { 633 fLayout->SetExplicitMaxSize(size); 634 return *this; 635 } 636 637 638 template<typename ParentBuilder> 639 typename Group<ParentBuilder>::ThisBuilder& 640 Group<ParentBuilder>::SetExplicitPreferredSize(BSize size) 641 { 642 fLayout->SetExplicitPreferredSize(size); 643 return *this; 644 } 645 646 647 template<typename ParentBuilder> 648 typename Group<ParentBuilder>::ThisBuilder& 649 Group<ParentBuilder>::SetExplicitAlignment(BAlignment alignment) 650 { 651 fLayout->SetExplicitAlignment(alignment); 652 return *this; 653 } 654 655 656 template<typename ParentBuilder> 657 Group<ParentBuilder>::operator BGroupLayout*() 658 { 659 return fLayout; 660 } 661 662 663 // #pragma mark - Grid 664 665 666 template<typename ParentBuilder> 667 Grid<ParentBuilder>::Grid(float horizontalSpacing, float verticalSpacing) 668 : 669 fLayout((new BGridView(horizontalSpacing, verticalSpacing))->GridLayout()) 670 { 671 } 672 673 674 template<typename ParentBuilder> 675 Grid<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 687 template<typename ParentBuilder> 688 Grid<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 699 template<typename ParentBuilder> 700 Grid<ParentBuilder>::Grid(BGridLayout* layout) 701 : 702 fLayout(layout) 703 { 704 } 705 706 707 template<typename ParentBuilder> 708 Grid<ParentBuilder>::Grid(BGridView* view) 709 : 710 fLayout(view->GridLayout()) 711 { 712 } 713 714 715 template<typename ParentBuilder> 716 BGridLayout* 717 Grid<ParentBuilder>::Layout() const 718 { 719 return fLayout; 720 } 721 722 723 template<typename ParentBuilder> 724 BView* 725 Grid<ParentBuilder>::View() const 726 { 727 return fLayout->Owner(); 728 } 729 730 731 template<typename ParentBuilder> 732 typename Grid<ParentBuilder>::ThisBuilder& 733 Grid<ParentBuilder>::GetLayout(BGridLayout** _layout) 734 { 735 *_layout = fLayout; 736 return *this; 737 } 738 739 740 template<typename ParentBuilder> 741 typename Grid<ParentBuilder>::ThisBuilder& 742 Grid<ParentBuilder>::GetView(BView** _view) 743 { 744 *_view = fLayout->Owner(); 745 return *this; 746 } 747 748 749 template<typename ParentBuilder> 750 typename Grid<ParentBuilder>::ThisBuilder& 751 Grid<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 759 template<typename ParentBuilder> 760 typename Grid<ParentBuilder>::ThisBuilder& 761 Grid<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 769 template<typename ParentBuilder> 770 typename Grid<ParentBuilder>::ThisBuilder& 771 Grid<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 785 template<typename ParentBuilder> 786 typename Grid<ParentBuilder>::ThisBuilder& 787 Grid<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 801 template<typename ParentBuilder> 802 typename Grid<ParentBuilder>::GroupBuilder 803 Grid<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 813 template<typename ParentBuilder> 814 typename Grid<ParentBuilder>::GroupBuilder 815 Grid<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 825 template<typename ParentBuilder> 826 typename Grid<ParentBuilder>::GroupBuilder 827 Grid<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 837 template<typename ParentBuilder> 838 typename Grid<ParentBuilder>::GridBuilder 839 Grid<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 849 template<typename ParentBuilder> 850 typename Grid<ParentBuilder>::GridBuilder 851 Grid<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 861 template<typename ParentBuilder> 862 typename Grid<ParentBuilder>::SplitBuilder 863 Grid<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 873 template<typename ParentBuilder> 874 typename Grid<ParentBuilder>::SplitBuilder 875 Grid<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 885 template<typename ParentBuilder> 886 typename Grid<ParentBuilder>::ThisBuilder& 887 Grid<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 896 template<typename ParentBuilder> 897 typename Grid<ParentBuilder>::ThisBuilder& 898 Grid<ParentBuilder>::SetColumnWeight(int32 column, float weight) 899 { 900 fLayout->SetColumnWeight(column, weight); 901 return *this; 902 } 903 904 905 template<typename ParentBuilder> 906 typename Grid<ParentBuilder>::ThisBuilder& 907 Grid<ParentBuilder>::SetRowWeight(int32 row, float weight) 908 { 909 fLayout->SetRowWeight(row, weight); 910 return *this; 911 } 912 913 914 template<typename ParentBuilder> 915 typename Grid<ParentBuilder>::ThisBuilder& 916 Grid<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 924 template<typename ParentBuilder> 925 typename Grid<ParentBuilder>::ThisBuilder& 926 Grid<ParentBuilder>::SetInsets(float horizontal, float vertical) 927 { 928 fLayout->SetInsets(horizontal, vertical); 929 return *this; 930 } 931 932 933 template<typename ParentBuilder> 934 typename Grid<ParentBuilder>::ThisBuilder& 935 Grid<ParentBuilder>::SetInsets(float insets) 936 { 937 fLayout->SetInsets(insets); 938 return *this; 939 } 940 941 942 template<typename ParentBuilder> 943 typename Grid<ParentBuilder>::ThisBuilder& 944 Grid<ParentBuilder>::SetExplicitMinSize(BSize size) 945 { 946 fLayout->SetExplicitMinSize(size); 947 return *this; 948 } 949 950 951 template<typename ParentBuilder> 952 typename Grid<ParentBuilder>::ThisBuilder& 953 Grid<ParentBuilder>::SetExplicitMaxSize(BSize size) 954 { 955 fLayout->SetExplicitMaxSize(size); 956 return *this; 957 } 958 959 960 template<typename ParentBuilder> 961 typename Grid<ParentBuilder>::ThisBuilder& 962 Grid<ParentBuilder>::SetExplicitPreferredSize(BSize size) 963 { 964 fLayout->SetExplicitPreferredSize(size); 965 return *this; 966 } 967 968 969 template<typename ParentBuilder> 970 typename Grid<ParentBuilder>::ThisBuilder& 971 Grid<ParentBuilder>::SetExplicitAlignment(BAlignment alignment) 972 { 973 fLayout->SetExplicitAlignment(alignment); 974 return *this; 975 } 976 977 978 template<typename ParentBuilder> 979 Grid<ParentBuilder>::operator BGridLayout*() 980 { 981 return fLayout; 982 } 983 984 985 // #pragma mark - Split 986 987 988 template<typename ParentBuilder> 989 Split<ParentBuilder>::Split(enum orientation orientation, float spacing) 990 : 991 fView(new BSplitView(orientation, spacing)) 992 { 993 } 994 995 996 template<typename ParentBuilder> 997 Split<ParentBuilder>::Split(BSplitView* view) 998 : 999 fView(view) 1000 { 1001 } 1002 1003 1004 template<typename ParentBuilder> 1005 BSplitView* 1006 Split<ParentBuilder>::View() const 1007 { 1008 return fView; 1009 } 1010 1011 1012 template<typename ParentBuilder> 1013 typename Split<ParentBuilder>::ThisBuilder& 1014 Split<ParentBuilder>::GetView(BView** _view) 1015 { 1016 *_view = fView; 1017 return *this; 1018 } 1019 1020 1021 template<typename ParentBuilder> 1022 typename Split<ParentBuilder>::ThisBuilder& 1023 Split<ParentBuilder>::GetSplitView(BSplitView** _view) 1024 { 1025 *_view = fView; 1026 return *this; 1027 } 1028 1029 1030 template<typename ParentBuilder> 1031 typename Split<ParentBuilder>::ThisBuilder& 1032 Split<ParentBuilder>::Add(BView* view) 1033 { 1034 fView->AddChild(view); 1035 return *this; 1036 } 1037 1038 1039 template<typename ParentBuilder> 1040 typename Split<ParentBuilder>::ThisBuilder& 1041 Split<ParentBuilder>::Add(BView* view, float weight) 1042 { 1043 fView->AddChild(view, weight); 1044 return *this; 1045 } 1046 1047 1048 template<typename ParentBuilder> 1049 typename Split<ParentBuilder>::ThisBuilder& 1050 Split<ParentBuilder>::Add(BLayoutItem* item) 1051 { 1052 fView->AddChild(item); 1053 return *this; 1054 } 1055 1056 1057 template<typename ParentBuilder> 1058 typename Split<ParentBuilder>::ThisBuilder& 1059 Split<ParentBuilder>::Add(BLayoutItem* item, float weight) 1060 { 1061 fView->AddChild(item, weight); 1062 return *this; 1063 } 1064 1065 1066 template<typename ParentBuilder> 1067 typename Split<ParentBuilder>::GroupBuilder 1068 Split<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 1078 template<typename ParentBuilder> 1079 typename Split<ParentBuilder>::GroupBuilder 1080 Split<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 1089 template<typename ParentBuilder> 1090 typename Split<ParentBuilder>::GroupBuilder 1091 Split<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 1100 template<typename ParentBuilder> 1101 typename Split<ParentBuilder>::GridBuilder 1102 Split<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 1112 template<typename ParentBuilder> 1113 typename Split<ParentBuilder>::GridBuilder 1114 Split<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 1123 template<typename ParentBuilder> 1124 typename Split<ParentBuilder>::GridBuilder 1125 Split<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 1134 template<typename ParentBuilder> 1135 typename Split<ParentBuilder>::SplitBuilder 1136 Split<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 1146 template<typename ParentBuilder> 1147 typename Split<ParentBuilder>::ThisBuilder& 1148 Split<ParentBuilder>::SetCollapsible(bool collapsible) 1149 { 1150 fView->SetCollapsible(collapsible); 1151 return *this; 1152 } 1153 1154 1155 template<typename ParentBuilder> 1156 typename Split<ParentBuilder>::ThisBuilder& 1157 Split<ParentBuilder>::SetCollapsible(int32 index, bool collapsible) 1158 { 1159 fView->SetCollapsible(index, collapsible); 1160 return *this; 1161 } 1162 1163 1164 template<typename ParentBuilder> 1165 typename Split<ParentBuilder>::ThisBuilder& 1166 Split<ParentBuilder>::SetCollapsible(int32 first, int32 last, bool collapsible) 1167 { 1168 fView->SetCollapsible(first, last, collapsible); 1169 return *this; 1170 } 1171 1172 1173 template<typename ParentBuilder> 1174 typename Split<ParentBuilder>::ThisBuilder& 1175 Split<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 1183 template<typename ParentBuilder> 1184 typename Split<ParentBuilder>::ThisBuilder& 1185 Split<ParentBuilder>::SetInsets(float horizontal, float vertical) 1186 { 1187 fView->SetInsets(horizontal, vertical); 1188 return *this; 1189 } 1190 1191 1192 template<typename ParentBuilder> 1193 typename Split<ParentBuilder>::ThisBuilder& 1194 Split<ParentBuilder>::SetInsets(float insets) 1195 { 1196 fView->SetInsets(insets); 1197 return *this; 1198 } 1199 1200 1201 template<typename ParentBuilder> 1202 Split<ParentBuilder>::operator BSplitView*() 1203 { 1204 return fView; 1205 } 1206 1207 1208 // #pragma mark - Menu 1209 1210 1211 template<typename ParentBuilder> 1212 Menu<ParentBuilder>::Menu(BMenu* menu) 1213 : 1214 fMenu(menu) 1215 { 1216 } 1217 1218 1219 template<typename ParentBuilder> 1220 typename Menu<ParentBuilder>::ThisBuilder& 1221 Menu<ParentBuilder>::GetMenu(BMenu*& _menu) 1222 { 1223 _menu = fMenu; 1224 return *this; 1225 } 1226 1227 1228 template<typename ParentBuilder> 1229 typename Menu<ParentBuilder>::ItemBuilder 1230 Menu<ParentBuilder>::AddItem(BMenuItem* item) 1231 { 1232 fMenu->AddItem(item); 1233 return MenuItem<ParentBuilder>(this->fParent, fMenu, item); 1234 } 1235 1236 1237 template<typename ParentBuilder> 1238 typename Menu<ParentBuilder>::ItemBuilder 1239 Menu<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 1249 template<typename ParentBuilder> 1250 typename Menu<ParentBuilder>::ItemBuilder 1251 Menu<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 1262 template<typename ParentBuilder> 1263 typename Menu<ParentBuilder>::ItemBuilder 1264 Menu<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 1283 template<typename ParentBuilder> 1284 typename Menu<ParentBuilder>::ThisBuilder& 1285 Menu<ParentBuilder>::AddSeparator() 1286 { 1287 fMenu->AddSeparatorItem(); 1288 return *this; 1289 } 1290 1291 1292 template<typename ParentBuilder> 1293 typename Menu<ParentBuilder>::MenuBuilder 1294 Menu<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 1305 template<typename ParentBuilder> 1306 typename Menu<ParentBuilder>::MenuBuilder 1307 Menu<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 1324 template<typename ParentBuilder> 1325 MenuItem<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 1335 template<typename ParentBuilder> 1336 typename MenuItem<ParentBuilder>::ThisBuilder& 1337 MenuItem<ParentBuilder>::GetItem(BMenuItem*& _item) 1338 { 1339 _item = fMenuItem; 1340 return *this; 1341 } 1342 1343 1344 template<typename ParentBuilder> 1345 typename MenuItem<ParentBuilder>::ThisBuilder& 1346 MenuItem<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