/* * Copyright 2009-2015, Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT License. */ #ifndef _LAYOUT_BUILDER_H #define _LAYOUT_BUILDER_H #include <new> #include <CardLayout.h> #include <CardView.h> #include <GridLayout.h> #include <GridView.h> #include <GroupLayout.h> #include <GroupView.h> #include <Menu.h> #include <MenuField.h> #include <MenuItem.h> #include <SpaceLayoutItem.h> #include <SplitView.h> #include <TextControl.h> #include <Window.h> namespace BLayoutBuilder { template<typename ParentBuilder> class Base; template<typename ParentBuilder = void*> class Group; template<typename ParentBuilder = void*> class Grid; template<typename ParentBuilder = void*> class Split; template<typename ParentBuilder = void*> class Cards; template<typename ParentBuilder = void*> class Menu; template<typename ParentBuilder = void*> class MenuItem; template<typename ParentBuilder> class Base { protected: inline Base(); public: inline void SetParent(ParentBuilder* parent); // conceptually private inline ParentBuilder& End(); protected: ParentBuilder* fParent; }; template<typename ParentBuilder> class Group : public Base<ParentBuilder> { public: typedef Group<ParentBuilder> ThisBuilder; typedef Group<ThisBuilder> GroupBuilder; typedef Grid<ThisBuilder> GridBuilder; typedef Split<ThisBuilder> SplitBuilder; typedef Cards<ThisBuilder> CardBuilder; public: inline Group(orientation orientation = B_HORIZONTAL, float spacing = B_USE_DEFAULT_SPACING); inline Group(BWindow* window, orientation orientation = B_HORIZONTAL, float spacing = B_USE_DEFAULT_SPACING); inline Group(BView* view, orientation orientation = B_HORIZONTAL, float spacing = B_USE_DEFAULT_SPACING); inline Group(BGroupLayout* layout); inline Group(BGroupView* view); inline BGroupLayout* Layout() const; inline BView* View() const; inline ThisBuilder& GetLayout(BGroupLayout** _layout); inline ThisBuilder& GetView(BView** _view); inline ThisBuilder& Add(BView* view); inline ThisBuilder& Add(BView* view, float weight); inline ThisBuilder& Add(BLayoutItem* item); inline ThisBuilder& Add(BLayoutItem* item, float weight); inline GroupBuilder AddGroup(orientation orientation, float spacing = B_USE_DEFAULT_SPACING, float weight = 1.0f); inline GroupBuilder AddGroup(BGroupView* groupView, float weight = 1.0f); inline GroupBuilder AddGroup(BGroupLayout* groupLayout, float weight = 1.0f); inline GridBuilder AddGrid(float horizontal = B_USE_DEFAULT_SPACING, float vertical = B_USE_DEFAULT_SPACING, float weight = 1.0f); inline GridBuilder AddGrid(BGridLayout* gridLayout, float weight = 1.0f); inline GridBuilder AddGrid(BGridView* gridView, float weight = 1.0f); inline SplitBuilder AddSplit(orientation orientation, float spacing = B_USE_DEFAULT_SPACING, float weight = 1.0f); inline SplitBuilder AddSplit(BSplitView* splitView, float weight = 1.0f); inline CardBuilder AddCards(float weight = 1.0f); inline CardBuilder AddCards(BCardLayout* cardLayout, float weight = 1.0f); inline CardBuilder AddCards(BCardView* cardView, float weight = 1.0f); inline ThisBuilder& AddGlue(float weight = 1.0f); inline ThisBuilder& AddStrut(float size); inline ThisBuilder& SetInsets(float left, float top, float right, float bottom); inline ThisBuilder& SetInsets(float horizontal, float vertical); inline ThisBuilder& SetInsets(float insets); inline ThisBuilder& SetExplicitMinSize(BSize size); inline ThisBuilder& SetExplicitMaxSize(BSize size); inline ThisBuilder& SetExplicitPreferredSize(BSize size); inline ThisBuilder& SetExplicitAlignment(BAlignment alignment); inline operator BGroupLayout*(); private: BGroupLayout* fLayout; }; template<typename ParentBuilder> class Grid : public Base<ParentBuilder> { public: typedef Grid<ParentBuilder> ThisBuilder; typedef Group<ThisBuilder> GroupBuilder; typedef Grid<ThisBuilder> GridBuilder; typedef Split<ThisBuilder> SplitBuilder; typedef Cards<ThisBuilder> CardBuilder; public: inline Grid(float horizontal = B_USE_DEFAULT_SPACING, float vertical = B_USE_DEFAULT_SPACING); inline Grid(BWindow* window, float horizontal = B_USE_DEFAULT_SPACING, float vertical = B_USE_DEFAULT_SPACING); inline Grid(BView* view, float horizontal = B_USE_DEFAULT_SPACING, float vertical = B_USE_DEFAULT_SPACING); inline Grid(BGridLayout* layout); inline Grid(BGridView* view); inline BGridLayout* Layout() const; inline BView* View() const; inline ThisBuilder& GetLayout(BGridLayout** _layout); inline ThisBuilder& GetView(BView** _view); inline ThisBuilder& Add(BView* view, int32 column, int32 row, int32 columnCount = 1, int32 rowCount = 1); inline ThisBuilder& Add(BLayoutItem* item, int32 column, int32 row, int32 columnCount = 1, int32 rowCount = 1); inline ThisBuilder& AddMenuField(BMenuField* menuField, int32 column, int32 row, alignment labelAlignment = B_ALIGN_HORIZONTAL_UNSET, int32 labelColumnCount = 1, int32 fieldColumnCount = 1, int32 rowCount = 1); inline ThisBuilder& AddTextControl(BTextControl* textControl, int32 column, int32 row, alignment labelAlignment = B_ALIGN_HORIZONTAL_UNSET, int32 labelColumnCount = 1, int32 textColumnCount = 1, int32 rowCount = 1); inline GroupBuilder AddGroup(orientation orientation, float spacing, int32 column, int32 row, int32 columnCount = 1, int32 rowCount = 1); inline GroupBuilder AddGroup(BGroupView* groupView, int32 column, int32 row, int32 columnCount = 1, int32 rowCount = 1); inline GroupBuilder AddGroup(BGroupLayout* groupLayout, int32 column, int32 row, int32 columnCount = 1, int32 rowCount = 1); inline GridBuilder AddGrid(float horizontalSpacing, float verticalSpacing, int32 column, int32 row, int32 columnCount = 1, int32 rowCount = 1); inline GridBuilder AddGrid(BGridLayout* gridLayout, int32 column, int32 row, int32 columnCount = 1, int32 rowCount = 1); inline GridBuilder AddGrid(BGridView* gridView, int32 column, int32 row, int32 columnCount = 1, int32 rowCount = 1); inline SplitBuilder AddSplit(orientation orientation, float spacing, int32 column, int32 row, int32 columnCount = 1, int32 rowCount = 1); inline SplitBuilder AddSplit(BSplitView* splitView, int32 column, int32 row, int32 columnCount = 1, int32 rowCount = 1); inline CardBuilder AddCards(int32 column, int32 row, int32 columnCount = 1, int32 rowCount = 1); inline CardBuilder AddCards(BCardLayout* cardLayout, int32 column, int32 row, int32 columnCount = 1, int32 rowCount = 1); inline CardBuilder AddCards(BCardView* cardView, int32 column, int32 row, int32 columnCount = 1, int32 rowCount = 1); inline ThisBuilder& AddGlue(int32 column, int32 row, int32 columnCount = 1, int32 rowCount = 1); inline ThisBuilder& SetHorizontalSpacing(float spacing); inline ThisBuilder& SetVerticalSpacing(float spacing); inline ThisBuilder& SetSpacing(float horizontal, float vertical); inline ThisBuilder& SetColumnWeight(int32 column, float weight); inline ThisBuilder& SetRowWeight(int32 row, float weight); inline ThisBuilder& SetInsets(float left, float top, float right, float bottom); inline ThisBuilder& SetInsets(float horizontal, float vertical); inline ThisBuilder& SetInsets(float insets); inline ThisBuilder& SetExplicitMinSize(BSize size); inline ThisBuilder& SetExplicitMaxSize(BSize size); inline ThisBuilder& SetExplicitPreferredSize(BSize size); inline ThisBuilder& SetExplicitAlignment(BAlignment alignment); inline operator BGridLayout*(); private: BGridLayout* fLayout; }; template<typename ParentBuilder> class Split : public Base<ParentBuilder> { public: typedef Split<ParentBuilder> ThisBuilder; typedef Group<ThisBuilder> GroupBuilder; typedef Grid<ThisBuilder> GridBuilder; typedef Split<ThisBuilder> SplitBuilder; typedef Cards<ThisBuilder> CardBuilder; public: inline Split(orientation orientation = B_HORIZONTAL, float spacing = B_USE_DEFAULT_SPACING); inline Split(BSplitView* view); inline BSplitView* View() const; inline ThisBuilder& GetView(BView** _view); inline ThisBuilder& GetSplitView(BSplitView** _view); inline ThisBuilder& Add(BView* view); inline ThisBuilder& Add(BView* view, float weight); inline ThisBuilder& Add(BLayoutItem* item); inline ThisBuilder& Add(BLayoutItem* item, float weight); inline GroupBuilder AddGroup(orientation orientation, float spacing = B_USE_DEFAULT_SPACING, float weight = 1.0f); inline GroupBuilder AddGroup(BGroupView* groupView, float weight = 1.0f); inline GroupBuilder AddGroup(BGroupLayout* groupLayout, float weight = 1.0f); inline GridBuilder AddGrid(float horizontal = B_USE_DEFAULT_SPACING, float vertical = B_USE_DEFAULT_SPACING, float weight = 1.0f); inline GridBuilder AddGrid(BGridView* gridView, float weight = 1.0f); inline GridBuilder AddGrid(BGridLayout* gridLayout, float weight = 1.0f); inline SplitBuilder AddSplit(orientation orientation, float spacing = B_USE_DEFAULT_SPACING, float weight = 1.0f); inline SplitBuilder AddSplit(BSplitView* splitView, float weight = 1.0f); inline CardBuilder AddCards(float weight = 1.0f); inline CardBuilder AddCards(BCardLayout* cardLayout, float weight = 1.0f); inline CardBuilder AddCards(BCardView* cardView, float weight = 1.0f); inline ThisBuilder& SetCollapsible(bool collapsible); inline ThisBuilder& SetCollapsible(int32 index, bool collapsible); inline ThisBuilder& SetCollapsible(int32 first, int32 last, bool collapsible); inline ThisBuilder& SetInsets(float left, float top, float right, float bottom); inline ThisBuilder& SetInsets(float horizontal, float vertical); inline ThisBuilder& SetInsets(float insets); inline operator BSplitView*(); private: BSplitView* fView; }; template<typename ParentBuilder> class Cards : public Base<ParentBuilder> { public: typedef Cards<ParentBuilder> ThisBuilder; typedef Group<ThisBuilder> GroupBuilder; typedef Grid<ThisBuilder> GridBuilder; typedef Split<ThisBuilder> SplitBuilder; typedef Cards<ThisBuilder> CardBuilder; public: inline Cards(); inline Cards(BWindow* window); inline Cards(BView* view); inline Cards(BCardLayout* layout); inline Cards(BCardView* view); inline BCardLayout* Layout() const; inline BView* View() const; inline ThisBuilder& GetLayout(BCardLayout** _layout); inline ThisBuilder& GetView(BView** _view); inline ThisBuilder& Add(BView* view); inline ThisBuilder& Add(BLayoutItem* item); inline GroupBuilder AddGroup(orientation orientation, float spacing = B_USE_DEFAULT_SPACING); inline GroupBuilder AddGroup(BGroupView* groupView); inline GroupBuilder AddGroup(BGroupLayout* groupLayout); inline GridBuilder AddGrid(float horizontal = B_USE_DEFAULT_SPACING, float vertical = B_USE_DEFAULT_SPACING); inline GridBuilder AddGrid(BGridLayout* gridLayout); inline GridBuilder AddGrid(BGridView* gridView); inline SplitBuilder AddSplit(orientation orientation, float spacing = B_USE_DEFAULT_SPACING); inline SplitBuilder AddSplit(BSplitView* splitView); inline CardBuilder AddCards(); inline CardBuilder AddCards(BCardLayout* cardLayout); inline CardBuilder AddCards(BCardView* cardView); inline ThisBuilder& SetExplicitMinSize(BSize size); inline ThisBuilder& SetExplicitMaxSize(BSize size); inline ThisBuilder& SetExplicitPreferredSize(BSize size); inline ThisBuilder& SetExplicitAlignment(BAlignment alignment); inline ThisBuilder& SetVisibleItem(int32 index); inline operator BCardLayout*(); private: BCardLayout* fLayout; }; template<typename ParentBuilder> class Menu : public Base<ParentBuilder> { public: typedef Menu<ParentBuilder> ThisBuilder; typedef MenuItem<ParentBuilder> ItemBuilder; typedef Menu<ThisBuilder> MenuBuilder; public: inline Menu(BMenu* menu); inline ThisBuilder& GetMenu(BMenu*& _menu); inline ItemBuilder AddItem(BMenuItem* item); inline ItemBuilder AddItem(BMenu* menu); inline ItemBuilder AddItem(const char* label, BMessage* message, char shortcut = 0, uint32 modifiers = 0); inline ItemBuilder AddItem(const char* label, uint32 messageWhat, char shortcut = 0, uint32 modifiers = 0); inline MenuBuilder AddMenu(BMenu* menu); inline MenuBuilder AddMenu(const char* title, menu_layout layout = B_ITEMS_IN_COLUMN); inline ThisBuilder& AddSeparator(); private: BMenu* fMenu; }; template<typename ParentBuilder> class MenuItem : public Menu<ParentBuilder> { public: typedef MenuItem<ParentBuilder> ThisBuilder; public: inline MenuItem(ParentBuilder* parentBuilder, BMenu* menu, BMenuItem* item); inline ThisBuilder& GetItem(BMenuItem*& _item); inline ThisBuilder& SetEnabled(bool enabled); private: BMenuItem* fMenuItem; }; // #pragma mark - Base template<typename ParentBuilder> Base<ParentBuilder>::Base() : fParent(NULL) { } template<typename ParentBuilder> void Base<ParentBuilder>::SetParent(ParentBuilder* parent) { fParent = parent; } template<typename ParentBuilder> ParentBuilder& Base<ParentBuilder>::End() { return *fParent; } // #pragma mark - Group template<typename ParentBuilder> Group<ParentBuilder>::Group(orientation orientation, float spacing) : fLayout((new BGroupView(orientation, spacing))->GroupLayout()) { } template<typename ParentBuilder> Group<ParentBuilder>::Group(BWindow* window, orientation orientation, float spacing) : fLayout(new BGroupLayout(orientation, spacing)) { window->SetLayout(fLayout); fLayout->Owner()->AdoptSystemColors(); } template<typename ParentBuilder> Group<ParentBuilder>::Group(BView* view, orientation orientation, float spacing) : fLayout(new BGroupLayout(orientation, spacing)) { if (view->HasDefaultColors()) view->AdoptSystemColors(); view->SetLayout(fLayout); } template<typename ParentBuilder> Group<ParentBuilder>::Group(BGroupLayout* layout) : fLayout(layout) { } template<typename ParentBuilder> Group<ParentBuilder>::Group(BGroupView* view) : fLayout(view->GroupLayout()) { } template<typename ParentBuilder> BGroupLayout* Group<ParentBuilder>::Layout() const { return fLayout; } template<typename ParentBuilder> BView* Group<ParentBuilder>::View() const { return fLayout->Owner(); } template<typename ParentBuilder> typename Group<ParentBuilder>::ThisBuilder& Group<ParentBuilder>::GetLayout(BGroupLayout** _layout) { *_layout = fLayout; return *this; } template<typename ParentBuilder> typename Group<ParentBuilder>::ThisBuilder& Group<ParentBuilder>::GetView(BView** _view) { *_view = fLayout->Owner(); return *this; } template<typename ParentBuilder> typename Group<ParentBuilder>::ThisBuilder& Group<ParentBuilder>::Add(BView* view) { fLayout->AddView(view); return *this; } template<typename ParentBuilder> typename Group<ParentBuilder>::ThisBuilder& Group<ParentBuilder>::Add(BView* view, float weight) { fLayout->AddView(view, weight); return *this; } template<typename ParentBuilder> typename Group<ParentBuilder>::ThisBuilder& Group<ParentBuilder>::Add(BLayoutItem* item) { fLayout->AddItem(item); return *this; } template<typename ParentBuilder> typename Group<ParentBuilder>::ThisBuilder& Group<ParentBuilder>::Add(BLayoutItem* item, float weight) { fLayout->AddItem(item, weight); return *this; } template<typename ParentBuilder> typename Group<ParentBuilder>::GroupBuilder Group<ParentBuilder>::AddGroup(orientation orientation, float spacing, float weight) { GroupBuilder builder(new BGroupLayout(orientation, spacing)); builder.SetParent(this); fLayout->AddItem(builder.Layout(), weight); return builder; } template<typename ParentBuilder> typename Group<ParentBuilder>::GroupBuilder Group<ParentBuilder>::AddGroup(BGroupView* groupView, float weight) { GroupBuilder builder(groupView); builder.SetParent(this); fLayout->AddItem(builder.Layout(), weight); return builder; } template<typename ParentBuilder> typename Group<ParentBuilder>::GroupBuilder Group<ParentBuilder>::AddGroup(BGroupLayout* groupLayout, float weight) { GroupBuilder builder(groupLayout); builder.SetParent(this); fLayout->AddItem(builder.Layout(), weight); return builder; } template<typename ParentBuilder> typename Group<ParentBuilder>::GridBuilder Group<ParentBuilder>::AddGrid(float horizontalSpacing, float verticalSpacing, float weight) { GridBuilder builder(new BGridLayout(horizontalSpacing, verticalSpacing)); builder.SetParent(this); fLayout->AddItem(builder.Layout(), weight); return builder; } template<typename ParentBuilder> typename Group<ParentBuilder>::GridBuilder Group<ParentBuilder>::AddGrid(BGridLayout* gridLayout, float weight) { GridBuilder builder(gridLayout); builder.SetParent(this); fLayout->AddItem(builder.Layout(), weight); return builder; } template<typename ParentBuilder> typename Group<ParentBuilder>::GridBuilder Group<ParentBuilder>::AddGrid(BGridView* gridView, float weight) { GridBuilder builder(gridView); builder.SetParent(this); fLayout->AddItem(builder.Layout(), weight); return builder; } template<typename ParentBuilder> typename Group<ParentBuilder>::SplitBuilder Group<ParentBuilder>::AddSplit(orientation orientation, float spacing, float weight) { SplitBuilder builder(orientation, spacing); builder.SetParent(this); fLayout->AddView(builder.View(), weight); return builder; } template<typename ParentBuilder> typename Group<ParentBuilder>::SplitBuilder Group<ParentBuilder>::AddSplit(BSplitView* splitView, float weight) { SplitBuilder builder(splitView); builder.SetParent(this); fLayout->AddView(builder.View(), weight); return builder; } template<typename ParentBuilder> typename Group<ParentBuilder>::CardBuilder Group<ParentBuilder>::AddCards(float weight) { CardBuilder builder; builder.SetParent(this); fLayout->AddView(builder.View(), weight); return builder; } template<typename ParentBuilder> typename Group<ParentBuilder>::CardBuilder Group<ParentBuilder>::AddCards(BCardLayout* cardLayout, float weight) { CardBuilder builder(cardLayout); builder.SetParent(this); fLayout->AddView(builder.View(), weight); return builder; } template<typename ParentBuilder> typename Group<ParentBuilder>::CardBuilder Group<ParentBuilder>::AddCards(BCardView* cardView, float weight) { CardBuilder builder(cardView); builder.SetParent(this); fLayout->AddView(builder.View(), weight); return builder; } template<typename ParentBuilder> typename Group<ParentBuilder>::ThisBuilder& Group<ParentBuilder>::AddGlue(float weight) { fLayout->AddItem(BSpaceLayoutItem::CreateGlue(), weight); return *this; } template<typename ParentBuilder> typename Group<ParentBuilder>::ThisBuilder& Group<ParentBuilder>::AddStrut(float size) { if (fLayout->Orientation() == B_HORIZONTAL) fLayout->AddItem(BSpaceLayoutItem::CreateHorizontalStrut(size)); else fLayout->AddItem(BSpaceLayoutItem::CreateVerticalStrut(size)); return *this; } template<typename ParentBuilder> typename Group<ParentBuilder>::ThisBuilder& Group<ParentBuilder>::SetInsets(float left, float top, float right, float bottom) { fLayout->SetInsets(left, top, right, bottom); return *this; } template<typename ParentBuilder> typename Group<ParentBuilder>::ThisBuilder& Group<ParentBuilder>::SetInsets(float horizontal, float vertical) { fLayout->SetInsets(horizontal, vertical); return *this; } template<typename ParentBuilder> typename Group<ParentBuilder>::ThisBuilder& Group<ParentBuilder>::SetInsets(float insets) { fLayout->SetInsets(insets); return *this; } template<typename ParentBuilder> typename Group<ParentBuilder>::ThisBuilder& Group<ParentBuilder>::SetExplicitMinSize(BSize size) { fLayout->SetExplicitMinSize(size); return *this; } template<typename ParentBuilder> typename Group<ParentBuilder>::ThisBuilder& Group<ParentBuilder>::SetExplicitMaxSize(BSize size) { fLayout->SetExplicitMaxSize(size); return *this; } template<typename ParentBuilder> typename Group<ParentBuilder>::ThisBuilder& Group<ParentBuilder>::SetExplicitPreferredSize(BSize size) { fLayout->SetExplicitPreferredSize(size); return *this; } template<typename ParentBuilder> typename Group<ParentBuilder>::ThisBuilder& Group<ParentBuilder>::SetExplicitAlignment(BAlignment alignment) { fLayout->SetExplicitAlignment(alignment); return *this; } template<typename ParentBuilder> Group<ParentBuilder>::operator BGroupLayout*() { return fLayout; } // #pragma mark - Grid template<typename ParentBuilder> Grid<ParentBuilder>::Grid(float horizontalSpacing, float verticalSpacing) : fLayout((new BGridView(horizontalSpacing, verticalSpacing))->GridLayout()) { } template<typename ParentBuilder> Grid<ParentBuilder>::Grid(BWindow* window, float horizontalSpacing, float verticalSpacing) : fLayout(new BGridLayout(horizontalSpacing, verticalSpacing)) { window->SetLayout(fLayout); fLayout->Owner()->AdoptSystemColors(); } template<typename ParentBuilder> Grid<ParentBuilder>::Grid(BView* view, float horizontalSpacing, float verticalSpacing) : fLayout(new BGridLayout(horizontalSpacing, verticalSpacing)) { if (view->HasDefaultColors()) view->AdoptSystemColors(); view->SetLayout(fLayout); } template<typename ParentBuilder> Grid<ParentBuilder>::Grid(BGridLayout* layout) : fLayout(layout) { } template<typename ParentBuilder> Grid<ParentBuilder>::Grid(BGridView* view) : fLayout(view->GridLayout()) { } template<typename ParentBuilder> BGridLayout* Grid<ParentBuilder>::Layout() const { return fLayout; } template<typename ParentBuilder> BView* Grid<ParentBuilder>::View() const { return fLayout->Owner(); } template<typename ParentBuilder> typename Grid<ParentBuilder>::ThisBuilder& Grid<ParentBuilder>::GetLayout(BGridLayout** _layout) { *_layout = fLayout; return *this; } template<typename ParentBuilder> typename Grid<ParentBuilder>::ThisBuilder& Grid<ParentBuilder>::GetView(BView** _view) { *_view = fLayout->Owner(); return *this; } template<typename ParentBuilder> typename Grid<ParentBuilder>::ThisBuilder& Grid<ParentBuilder>::Add(BView* view, int32 column, int32 row, int32 columnCount, int32 rowCount) { fLayout->AddView(view, column, row, columnCount, rowCount); return *this; } template<typename ParentBuilder> typename Grid<ParentBuilder>::ThisBuilder& Grid<ParentBuilder>::Add(BLayoutItem* item, int32 column, int32 row, int32 columnCount, int32 rowCount) { fLayout->AddItem(item, column, row, columnCount, rowCount); return *this; } template<typename ParentBuilder> typename Grid<ParentBuilder>::ThisBuilder& Grid<ParentBuilder>::AddMenuField(BMenuField* menuField, int32 column, int32 row, alignment labelAlignment, int32 labelColumnCount, int32 fieldColumnCount, int32 rowCount) { BLayoutItem* item = menuField->CreateLabelLayoutItem(); item->SetExplicitAlignment( BAlignment(labelAlignment, B_ALIGN_VERTICAL_UNSET)); fLayout->AddItem(item, column, row, labelColumnCount, rowCount); fLayout->AddItem(menuField->CreateMenuBarLayoutItem(), column + labelColumnCount, row, fieldColumnCount, rowCount); return *this; } template<typename ParentBuilder> typename Grid<ParentBuilder>::ThisBuilder& Grid<ParentBuilder>::AddTextControl(BTextControl* textControl, int32 column, int32 row, alignment labelAlignment, int32 labelColumnCount, int32 textColumnCount, int32 rowCount) { BLayoutItem* item = textControl->CreateLabelLayoutItem(); item->SetExplicitAlignment( BAlignment(labelAlignment, B_ALIGN_VERTICAL_UNSET)); fLayout->AddItem(item, column, row, labelColumnCount, rowCount); fLayout->AddItem(textControl->CreateTextViewLayoutItem(), column + labelColumnCount, row, textColumnCount, rowCount); return *this; } template<typename ParentBuilder> typename Grid<ParentBuilder>::GroupBuilder Grid<ParentBuilder>::AddGroup(orientation orientation, float spacing, int32 column, int32 row, int32 columnCount, int32 rowCount) { GroupBuilder builder(new BGroupLayout(orientation, spacing)); builder.SetParent(this); fLayout->AddItem(builder.Layout(), column, row, columnCount, rowCount); return builder; } template<typename ParentBuilder> typename Grid<ParentBuilder>::GroupBuilder Grid<ParentBuilder>::AddGroup(BGroupView* groupView, int32 column, int32 row, int32 columnCount, int32 rowCount) { GroupBuilder builder(groupView); builder.SetParent(this); fLayout->AddItem(builder.Layout(), column, row, columnCount, rowCount); return builder; } template<typename ParentBuilder> typename Grid<ParentBuilder>::GroupBuilder Grid<ParentBuilder>::AddGroup(BGroupLayout* groupLayout, int32 column, int32 row, int32 columnCount, int32 rowCount) { GroupBuilder builder(groupLayout); builder.SetParent(this); fLayout->AddItem(builder.Layout(), column, row, columnCount, rowCount); return builder; } template<typename ParentBuilder> typename Grid<ParentBuilder>::GridBuilder Grid<ParentBuilder>::AddGrid(float horizontalSpacing, float verticalSpacing, int32 column, int32 row, int32 columnCount, int32 rowCount) { GridBuilder builder(new BGridLayout(horizontalSpacing, verticalSpacing)); builder.SetParent(this); fLayout->AddItem(builder.Layout(), column, row, columnCount, rowCount); return builder; } template<typename ParentBuilder> typename Grid<ParentBuilder>::GridBuilder Grid<ParentBuilder>::AddGrid(BGridView* gridView, int32 column, int32 row, int32 columnCount, int32 rowCount) { GridBuilder builder(gridView); builder.SetParent(this); fLayout->AddView(builder.View(), column, row, columnCount, rowCount); return builder; } template<typename ParentBuilder> typename Grid<ParentBuilder>::SplitBuilder Grid<ParentBuilder>::AddSplit(orientation orientation, float spacing, int32 column, int32 row, int32 columnCount, int32 rowCount) { SplitBuilder builder(orientation, spacing); builder.SetParent(this); fLayout->AddView(builder.View(), column, row, columnCount, rowCount); return builder; } template<typename ParentBuilder> typename Grid<ParentBuilder>::SplitBuilder Grid<ParentBuilder>::AddSplit(BSplitView* splitView, int32 column, int32 row, int32 columnCount, int32 rowCount) { SplitBuilder builder(splitView); builder.SetParent(this); fLayout->AddView(builder.View(), column, row, columnCount, rowCount); return builder; } template<typename ParentBuilder> typename Grid<ParentBuilder>::CardBuilder Grid<ParentBuilder>::AddCards(int32 column, int32 row, int32 columnCount, int32 rowCount) { CardBuilder builder; builder.SetParent(this); fLayout->AddView(builder.View(), column, row, columnCount, rowCount); return builder; } template<typename ParentBuilder> typename Grid<ParentBuilder>::CardBuilder Grid<ParentBuilder>::AddCards(BCardLayout* cardLayout, int32 column, int32 row, int32 columnCount, int32 rowCount) { CardBuilder builder(cardLayout); builder.SetParent(this); fLayout->AddView(builder.View(), column, row, columnCount, rowCount); return builder; } template<typename ParentBuilder> typename Grid<ParentBuilder>::CardBuilder Grid<ParentBuilder>::AddCards(BCardView* cardView, int32 column, int32 row, int32 columnCount, int32 rowCount) { CardBuilder builder(cardView); builder.SetParent(this); fLayout->AddView(builder.View(), column, row, columnCount, rowCount); return builder; } template<typename ParentBuilder> typename Grid<ParentBuilder>::ThisBuilder& Grid<ParentBuilder>::AddGlue(int32 column, int32 row, int32 columnCount, int32 rowCount) { fLayout->AddItem(BSpaceLayoutItem::CreateGlue(), column, row, columnCount, rowCount); return *this; } template<typename ParentBuilder> typename Grid<ParentBuilder>::ThisBuilder& Grid<ParentBuilder>::SetHorizontalSpacing(float spacing) { fLayout->SetHorizontalSpacing(spacing); return *this; } template<typename ParentBuilder> typename Grid<ParentBuilder>::ThisBuilder& Grid<ParentBuilder>::SetVerticalSpacing(float spacing) { fLayout->SetVerticalSpacing(spacing); return *this; } template<typename ParentBuilder> typename Grid<ParentBuilder>::ThisBuilder& Grid<ParentBuilder>::SetSpacing(float horizontal, float vertical) { fLayout->SetSpacing(horizontal, vertical); return *this; } template<typename ParentBuilder> typename Grid<ParentBuilder>::ThisBuilder& Grid<ParentBuilder>::SetColumnWeight(int32 column, float weight) { fLayout->SetColumnWeight(column, weight); return *this; } template<typename ParentBuilder> typename Grid<ParentBuilder>::ThisBuilder& Grid<ParentBuilder>::SetRowWeight(int32 row, float weight) { fLayout->SetRowWeight(row, weight); return *this; } template<typename ParentBuilder> typename Grid<ParentBuilder>::ThisBuilder& Grid<ParentBuilder>::SetInsets(float left, float top, float right, float bottom) { fLayout->SetInsets(left, top, right, bottom); return *this; } template<typename ParentBuilder> typename Grid<ParentBuilder>::ThisBuilder& Grid<ParentBuilder>::SetInsets(float horizontal, float vertical) { fLayout->SetInsets(horizontal, vertical); return *this; } template<typename ParentBuilder> typename Grid<ParentBuilder>::ThisBuilder& Grid<ParentBuilder>::SetInsets(float insets) { fLayout->SetInsets(insets); return *this; } template<typename ParentBuilder> typename Grid<ParentBuilder>::ThisBuilder& Grid<ParentBuilder>::SetExplicitMinSize(BSize size) { fLayout->SetExplicitMinSize(size); return *this; } template<typename ParentBuilder> typename Grid<ParentBuilder>::ThisBuilder& Grid<ParentBuilder>::SetExplicitMaxSize(BSize size) { fLayout->SetExplicitMaxSize(size); return *this; } template<typename ParentBuilder> typename Grid<ParentBuilder>::ThisBuilder& Grid<ParentBuilder>::SetExplicitPreferredSize(BSize size) { fLayout->SetExplicitPreferredSize(size); return *this; } template<typename ParentBuilder> typename Grid<ParentBuilder>::ThisBuilder& Grid<ParentBuilder>::SetExplicitAlignment(BAlignment alignment) { fLayout->SetExplicitAlignment(alignment); return *this; } template<typename ParentBuilder> Grid<ParentBuilder>::operator BGridLayout*() { return fLayout; } // #pragma mark - Split template<typename ParentBuilder> Split<ParentBuilder>::Split(orientation orientation, float spacing) : fView(new BSplitView(orientation, spacing)) { } template<typename ParentBuilder> Split<ParentBuilder>::Split(BSplitView* view) : fView(view) { } template<typename ParentBuilder> BSplitView* Split<ParentBuilder>::View() const { return fView; } template<typename ParentBuilder> typename Split<ParentBuilder>::ThisBuilder& Split<ParentBuilder>::GetView(BView** _view) { *_view = fView; return *this; } template<typename ParentBuilder> typename Split<ParentBuilder>::ThisBuilder& Split<ParentBuilder>::GetSplitView(BSplitView** _view) { *_view = fView; return *this; } template<typename ParentBuilder> typename Split<ParentBuilder>::ThisBuilder& Split<ParentBuilder>::Add(BView* view) { fView->AddChild(view); return *this; } template<typename ParentBuilder> typename Split<ParentBuilder>::ThisBuilder& Split<ParentBuilder>::Add(BView* view, float weight) { fView->AddChild(view, weight); return *this; } template<typename ParentBuilder> typename Split<ParentBuilder>::ThisBuilder& Split<ParentBuilder>::Add(BLayoutItem* item) { fView->AddChild(item); return *this; } template<typename ParentBuilder> typename Split<ParentBuilder>::ThisBuilder& Split<ParentBuilder>::Add(BLayoutItem* item, float weight) { fView->AddChild(item, weight); return *this; } template<typename ParentBuilder> typename Split<ParentBuilder>::GroupBuilder Split<ParentBuilder>::AddGroup(orientation orientation, float spacing, float weight) { GroupBuilder builder(new BGroupLayout(orientation, spacing)); builder.SetParent(this); fView->AddChild(builder.Layout(), weight); return builder; } template<typename ParentBuilder> typename Split<ParentBuilder>::GroupBuilder Split<ParentBuilder>::AddGroup(BGroupView* groupView, float weight) { GroupBuilder builder(groupView); builder.SetParent(this); fView->AddChild(builder.Layout(), weight); return builder; } template<typename ParentBuilder> typename Split<ParentBuilder>::GroupBuilder Split<ParentBuilder>::AddGroup(BGroupLayout* groupLayout, float weight) { GroupBuilder builder(groupLayout); builder.SetParent(this); fView->AddChild(builder.Layout(), weight); return builder; } template<typename ParentBuilder> typename Split<ParentBuilder>::GridBuilder Split<ParentBuilder>::AddGrid(float horizontalSpacing, float verticalSpacing, float weight) { GridBuilder builder(new BGridLayout(horizontalSpacing, verticalSpacing)); builder.SetParent(this); fView->AddChild(builder.Layout(), weight); return builder; } template<typename ParentBuilder> typename Split<ParentBuilder>::GridBuilder Split<ParentBuilder>::AddGrid(BGridView* gridView, float weight) { GridBuilder builder(gridView); builder.SetParent(this); fView->AddChild(builder.Layout(), weight); return builder; } template<typename ParentBuilder> typename Split<ParentBuilder>::GridBuilder Split<ParentBuilder>::AddGrid(BGridLayout* layout, float weight) { GridBuilder builder(layout); builder.SetParent(this); fView->AddChild(builder.Layout(), weight); return builder; } template<typename ParentBuilder> typename Split<ParentBuilder>::SplitBuilder Split<ParentBuilder>::AddSplit(orientation orientation, float spacing, float weight) { SplitBuilder builder(orientation, spacing); builder.SetParent(this); fView->AddChild(builder.View(), weight); return builder; } template<typename ParentBuilder> typename Split<ParentBuilder>::CardBuilder Split<ParentBuilder>::AddCards(float weight) { CardBuilder builder; builder.SetParent(this); fView->AddChild(builder.View(), weight); return builder; } template<typename ParentBuilder> typename Split<ParentBuilder>::CardBuilder Split<ParentBuilder>::AddCards(BCardLayout* cardLayout, float weight) { CardBuilder builder(cardLayout); builder.SetParent(this); fView->AddChild(builder.View(), weight); return builder; } template<typename ParentBuilder> typename Split<ParentBuilder>::CardBuilder Split<ParentBuilder>::AddCards(BCardView* cardView, float weight) { CardBuilder builder(cardView); builder.SetParent(this); fView->AddChild(builder.View(), weight); return builder; } template<typename ParentBuilder> typename Split<ParentBuilder>::ThisBuilder& Split<ParentBuilder>::SetCollapsible(bool collapsible) { fView->SetCollapsible(collapsible); return *this; } template<typename ParentBuilder> typename Split<ParentBuilder>::ThisBuilder& Split<ParentBuilder>::SetCollapsible(int32 index, bool collapsible) { fView->SetCollapsible(index, collapsible); return *this; } template<typename ParentBuilder> typename Split<ParentBuilder>::ThisBuilder& Split<ParentBuilder>::SetCollapsible(int32 first, int32 last, bool collapsible) { fView->SetCollapsible(first, last, collapsible); return *this; } template<typename ParentBuilder> typename Split<ParentBuilder>::ThisBuilder& Split<ParentBuilder>::SetInsets(float left, float top, float right, float bottom) { fView->SetInsets(left, top, right, bottom); return *this; } template<typename ParentBuilder> typename Split<ParentBuilder>::ThisBuilder& Split<ParentBuilder>::SetInsets(float horizontal, float vertical) { fView->SetInsets(horizontal, vertical); return *this; } template<typename ParentBuilder> typename Split<ParentBuilder>::ThisBuilder& Split<ParentBuilder>::SetInsets(float insets) { fView->SetInsets(insets); return *this; } template<typename ParentBuilder> Split<ParentBuilder>::operator BSplitView*() { return fView; } // #pragma mark - Cards template<typename ParentBuilder> Cards<ParentBuilder>::Cards() : fLayout((new BCardView())->CardLayout()) { } template<typename ParentBuilder> Cards<ParentBuilder>::Cards(BWindow* window) : fLayout(new BCardLayout()) { window->SetLayout(fLayout); fLayout->Owner()->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); } template<typename ParentBuilder> Cards<ParentBuilder>::Cards(BView* view) : fLayout(new BCardLayout()) { view->SetLayout(fLayout); view->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); } template<typename ParentBuilder> Cards<ParentBuilder>::Cards(BCardLayout* layout) : fLayout(layout) { } template<typename ParentBuilder> Cards<ParentBuilder>::Cards(BCardView* view) : fLayout(view->CardLayout()) { } template<typename ParentBuilder> BCardLayout* Cards<ParentBuilder>::Layout() const { return fLayout; } template<typename ParentBuilder> BView* Cards<ParentBuilder>::View() const { return fLayout->Owner(); } template<typename ParentBuilder> typename Cards<ParentBuilder>::ThisBuilder& Cards<ParentBuilder>::GetLayout(BCardLayout** _layout) { *_layout = fLayout; return *this; } template<typename ParentBuilder> typename Cards<ParentBuilder>::ThisBuilder& Cards<ParentBuilder>::GetView(BView** _view) { *_view = fLayout->Owner(); return *this; } template<typename ParentBuilder> typename Cards<ParentBuilder>::ThisBuilder& Cards<ParentBuilder>::Add(BView* view) { fLayout->AddView(view); return *this; } template<typename ParentBuilder> typename Cards<ParentBuilder>::ThisBuilder& Cards<ParentBuilder>::Add(BLayoutItem* item) { fLayout->AddItem(item); return *this; } template<typename ParentBuilder> typename Cards<ParentBuilder>::GroupBuilder Cards<ParentBuilder>::AddGroup(orientation orientation, float spacing) { GroupBuilder builder(new BGroupLayout(orientation, spacing)); builder.SetParent(this); fLayout->AddItem(builder.Layout()); return builder; } template<typename ParentBuilder> typename Cards<ParentBuilder>::GroupBuilder Cards<ParentBuilder>::AddGroup(BGroupView* groupView) { GroupBuilder builder(groupView); builder.SetParent(this); fLayout->AddItem(builder.Layout()); return builder; } template<typename ParentBuilder> typename Cards<ParentBuilder>::GroupBuilder Cards<ParentBuilder>::AddGroup(BGroupLayout* groupLayout) { GroupBuilder builder(groupLayout); builder.SetParent(this); fLayout->AddItem(builder.Layout()); return builder; } template<typename ParentBuilder> typename Cards<ParentBuilder>::GridBuilder Cards<ParentBuilder>::AddGrid(float horizontal, float vertical) { GridBuilder builder(horizontal, vertical); builder.SetParent(this); fLayout->AddItem(builder.Layout()); return builder; } template<typename ParentBuilder> typename Cards<ParentBuilder>::GridBuilder Cards<ParentBuilder>::AddGrid(BGridLayout* gridLayout) { GridBuilder builder(gridLayout); builder.SetParent(this); fLayout->AddItem(builder.Layout()); return builder; } template<typename ParentBuilder> typename Cards<ParentBuilder>::GridBuilder Cards<ParentBuilder>::AddGrid(BGridView* gridView) { GridBuilder builder(gridView); builder.SetParent(this); fLayout->AddItem(builder.Layout()); return builder; } template<typename ParentBuilder> typename Cards<ParentBuilder>::SplitBuilder Cards<ParentBuilder>::AddSplit(orientation orientation, float spacing) { SplitBuilder builder(orientation, spacing); builder.SetParent(this); fLayout->AddView(builder.View()); return builder; } template<typename ParentBuilder> typename Cards<ParentBuilder>::SplitBuilder Cards<ParentBuilder>::AddSplit(BSplitView* splitView) { SplitBuilder builder(splitView); builder.SetParent(this); fLayout->AddView(builder.View()); return builder; } template<typename ParentBuilder> typename Cards<ParentBuilder>::CardBuilder Cards<ParentBuilder>::AddCards() { CardBuilder builder; builder.SetParent(this); fLayout->AddView(builder.View()); return builder; } template<typename ParentBuilder> typename Cards<ParentBuilder>::CardBuilder Cards<ParentBuilder>::AddCards(BCardLayout* cardLayout) { CardBuilder builder(cardLayout); builder.SetParent(this); fLayout->AddView(builder.View()); return builder; } template<typename ParentBuilder> typename Cards<ParentBuilder>::CardBuilder Cards<ParentBuilder>::AddCards(BCardView* cardView) { CardBuilder builder(cardView); builder.SetParent(this); fLayout->AddView(builder.View()); return builder; } template<typename ParentBuilder> typename Cards<ParentBuilder>::ThisBuilder& Cards<ParentBuilder>::SetExplicitMinSize(BSize size) { fLayout->SetExplicitMinSize(size); return *this; } template<typename ParentBuilder> typename Cards<ParentBuilder>::ThisBuilder& Cards<ParentBuilder>::SetExplicitMaxSize(BSize size) { fLayout->SetExplicitMaxSize(size); return *this; } template<typename ParentBuilder> typename Cards<ParentBuilder>::ThisBuilder& Cards<ParentBuilder>::SetExplicitPreferredSize(BSize size) { fLayout->SetExplicitPreferredSize(size); return *this; } template<typename ParentBuilder> typename Cards<ParentBuilder>::ThisBuilder& Cards<ParentBuilder>::SetExplicitAlignment(BAlignment alignment) { fLayout->SetExplicitAlignment(alignment); return *this; } template<typename ParentBuilder> typename Cards<ParentBuilder>::ThisBuilder& Cards<ParentBuilder>::SetVisibleItem(int32 item) { fLayout->SetVisibleItem(item); return *this; } template<typename ParentBuilder> Cards<ParentBuilder>::operator BCardLayout*() { return fLayout; } // #pragma mark - Menu template<typename ParentBuilder> Menu<ParentBuilder>::Menu(BMenu* menu) : fMenu(menu) { } template<typename ParentBuilder> typename Menu<ParentBuilder>::ThisBuilder& Menu<ParentBuilder>::GetMenu(BMenu*& _menu) { _menu = fMenu; return *this; } template<typename ParentBuilder> typename Menu<ParentBuilder>::ItemBuilder Menu<ParentBuilder>::AddItem(BMenuItem* item) { fMenu->AddItem(item); return MenuItem<ParentBuilder>(this->fParent, fMenu, item); } template<typename ParentBuilder> typename Menu<ParentBuilder>::ItemBuilder Menu<ParentBuilder>::AddItem(BMenu* menu) { if (!fMenu->AddItem(menu)) throw std::bad_alloc(); return MenuItem<ParentBuilder>(this->fParent, fMenu, fMenu->ItemAt(fMenu->CountItems() - 1)); } template<typename ParentBuilder> typename Menu<ParentBuilder>::ItemBuilder Menu<ParentBuilder>::AddItem(const char* label, BMessage* message, char shortcut, uint32 modifiers) { BMenuItem* item = new BMenuItem(label, message, shortcut, modifiers); if (!fMenu->AddItem(item)) { delete item; item = NULL; } return MenuItem<ParentBuilder>(this->fParent, fMenu, item); } template<typename ParentBuilder> typename Menu<ParentBuilder>::ItemBuilder Menu<ParentBuilder>::AddItem(const char* label, uint32 messageWhat, char shortcut, uint32 modifiers) { BMessage* message = new BMessage(messageWhat); BMenuItem* item; try { item = new BMenuItem(label, message, shortcut, modifiers); } catch (...) { delete message; throw; } if (!fMenu->AddItem(item)) { delete item; item = NULL; } return MenuItem<ParentBuilder>(this->fParent, fMenu, item); } template<typename ParentBuilder> typename Menu<ParentBuilder>::ThisBuilder& Menu<ParentBuilder>::AddSeparator() { fMenu->AddSeparatorItem(); return *this; } template<typename ParentBuilder> typename Menu<ParentBuilder>::MenuBuilder Menu<ParentBuilder>::AddMenu(BMenu* menu) { if (!fMenu->AddItem(menu)) throw std::bad_alloc(); MenuBuilder builder(menu); builder.SetParent(this); return builder; } template<typename ParentBuilder> typename Menu<ParentBuilder>::MenuBuilder Menu<ParentBuilder>::AddMenu(const char* title, menu_layout layout) { BMenu* menu = new BMenu(title, layout); if (!fMenu->AddItem(menu)) { delete menu; throw std::bad_alloc(); } MenuBuilder builder(menu); builder.SetParent(this); return builder; } // #pragma mark - MenuItem template<typename ParentBuilder> MenuItem<ParentBuilder>::MenuItem(ParentBuilder* parentBuilder, BMenu* menu, BMenuItem* item) : Menu<ParentBuilder>(menu), fMenuItem(item) { this->SetParent(parentBuilder); } template<typename ParentBuilder> typename MenuItem<ParentBuilder>::ThisBuilder& MenuItem<ParentBuilder>::GetItem(BMenuItem*& _item) { _item = fMenuItem; return *this; } template<typename ParentBuilder> typename MenuItem<ParentBuilder>::ThisBuilder& MenuItem<ParentBuilder>::SetEnabled(bool enabled) { fMenuItem->SetEnabled(enabled); return *this; } } // namespace BLayoutBuilder #endif // _LAYOUT_BUILDER_H