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