/* * Copyright 2009, Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT License. */ #ifndef _LAYOUT_BUILDER_H #define _LAYOUT_BUILDER_H #include #include #include #include #include #include #include #include #include namespace BLayoutBuilder { template class Base; template class Group; template class Grid; template class Split; template class Base { protected: inline Base(); public: inline void SetParent(ParentBuilder* parent); // conceptually private inline ParentBuilder& End(); protected: ParentBuilder* fParent; }; template class Group : public Base { public: typedef Group ThisBuilder; typedef Group GroupBuilder; typedef Grid GridBuilder; typedef Split SplitBuilder; public: inline Group(enum orientation orientation = B_HORIZONTAL, float spacing = 0.0f); inline Group(BWindow* window, enum orientation orientation = B_HORIZONTAL, float spacing = 0.0f); 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(enum orientation orientation, float spacing = 0.0f, float weight = 1.0f); inline GridBuilder AddGrid(float horizontalSpacing = 0.0f, float verticalSpacing = 0.0f, float weight = 1.0f); inline SplitBuilder AddSplit(enum orientation orientation, float spacing = 0.0f, 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 operator BGroupLayout*(); inline operator BView*(); private: BGroupLayout* fLayout; }; template class Grid : public Base { public: typedef Grid ThisBuilder; typedef Group GroupBuilder; typedef Grid GridBuilder; typedef Split SplitBuilder; public: inline Grid(float horizontalSpacing = 0.0f, float verticalSpacing = 0.0f); inline Grid(BWindow* window, float horizontalSpacing = 0.0f, float verticalSpacing = 0.0f); 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 columnCount = 1, int32 rowCount = 1); inline ThisBuilder& AddTextControl(BTextControl* textControl, int32 column, int32 row, alignment labelAlignment = B_ALIGN_HORIZONTAL_UNSET, int32 columnCount = 1, int32 rowCount = 1); inline GroupBuilder AddGroup(enum orientation orientation, float spacing, 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 SplitBuilder AddSplit(enum orientation orientation, float spacing, int32 column, int32 row, int32 columnCount = 1, int32 rowCount = 1); 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 operator BGridLayout*(); inline operator BView*(); private: BGridLayout* fLayout; }; template class Split : public Base { public: typedef Split ThisBuilder; typedef Group GroupBuilder; typedef Grid GridBuilder; typedef Split SplitBuilder; public: inline Split(enum orientation orientation = B_HORIZONTAL, float spacing = 0.0f); inline Split(BSplitView* view); inline BSplitView* View() const; inline ThisBuilder& GetView(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(enum orientation orientation, float spacing = 0.0f, float weight = 1.0f); inline GridBuilder AddGrid(float horizontalSpacing = 0.0f, float verticalSpacing = 0.0f, float weight = 1.0f); inline SplitBuilder AddSplit(enum orientation orientation, float spacing = 0.0f, 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 operator BSplitView*(); private: BSplitView* fView; }; // #pragma mark - Base template Base::Base() : fParent(NULL) { } template void Base::SetParent(ParentBuilder* parent) { fParent = parent; } template ParentBuilder& Base::End() { return *fParent; } // #pragma mark - Group template Group::Group(enum orientation orientation, float spacing) : fLayout((new BGroupView(orientation, spacing))->GroupLayout()) { } template Group::Group(BWindow* window, enum orientation orientation, float spacing) : fLayout((new BGroupView(orientation, spacing))->GroupLayout()) { window->SetLayout(fLayout); } template Group::Group(BGroupLayout* layout) : fLayout(layout) { } template Group::Group(BGroupView* view) : fLayout(view->GroupLayout()) { } template BGroupLayout* Group::Layout() const { return fLayout; } template BView* Group::View() const { return fLayout->View(); } template typename Group::ThisBuilder& Group::GetLayout(BGroupLayout** _layout) { *_layout = fLayout; return *this; } template typename Group::ThisBuilder& Group::GetView(BView** _view) { *_view = fLayout->View(); return *this; } template typename Group::ThisBuilder& Group::Add(BView* view) { fLayout->AddView(view); return *this; } template typename Group::ThisBuilder& Group::Add(BView* view, float weight) { fLayout->AddView(view, weight); return *this; } template typename Group::ThisBuilder& Group::Add(BLayoutItem* item) { fLayout->AddItem(item); return *this; } template typename Group::ThisBuilder& Group::Add(BLayoutItem* item, float weight) { fLayout->AddItem(item, weight); return *this; } template typename Group::GroupBuilder Group::AddGroup(enum orientation orientation, float spacing, float weight) { GroupBuilder builder(orientation, spacing); builder.SetParent(this); fLayout->AddView(builder.View(), weight); return builder; } template typename Group::GridBuilder Group::AddGrid(float horizontalSpacing, float verticalSpacing, float weight) { GridBuilder builder(horizontalSpacing, verticalSpacing); builder.SetParent(this); fLayout->AddView(builder.View(), weight); return builder; } template typename Group::SplitBuilder Group::AddSplit(enum orientation orientation, float spacing, float weight) { SplitBuilder builder(orientation, spacing); builder.SetParent(this); fLayout->AddView(builder.View(), weight); return builder; } template typename Group::ThisBuilder& Group::AddGlue(float weight) { fLayout->AddItem(BSpaceLayoutItem::CreateGlue(), weight); return *this; } template typename Group::ThisBuilder& Group::AddStrut(float size) { if (fLayout->Orientation() == B_HORIZONTAL) fLayout->AddItem(BSpaceLayoutItem::CreateHorizontalStrut(size)); else fLayout->AddItem(BSpaceLayoutItem::CreateVerticalStrut(size)); return *this; } template typename Group::ThisBuilder& Group::SetInsets(float left, float top, float right, float bottom) { fLayout->SetInsets(left, top, right, bottom); return *this; } template Group::operator BGroupLayout*() { return fLayout; } template Group::operator BView*() { return fLayout->View(); } // #pragma mark - Grid template Grid::Grid(float horizontalSpacing, float verticalSpacing) : fLayout((new BGridView(horizontalSpacing, verticalSpacing))->GridLayout()) { } template Grid::Grid(BWindow* window, float horizontalSpacing, float verticalSpacing) : fLayout((new BGridView(horizontalSpacing, verticalSpacing))->GridLayout()) { window->SetLayout(fLayout); } template Grid::Grid(BGridLayout* layout) : fLayout(layout) { } template Grid::Grid(BGridView* view) : fLayout(view->GridLayout()) { } template BGridLayout* Grid::Layout() const { return fLayout; } template BView* Grid::View() const { return fLayout->View(); } template typename Grid::ThisBuilder& Grid::GetLayout(BGridLayout** _layout) { *_layout = fLayout; return *this; } template typename Grid::ThisBuilder& Grid::GetView(BView** _view) { *_view = fLayout->View(); return *this; } template typename Grid::ThisBuilder& Grid::Add(BView* view, int32 column, int32 row, int32 columnCount, int32 rowCount) { fLayout->AddView(view, column, row, columnCount, rowCount); return *this; } template typename Grid::ThisBuilder& Grid::Add(BLayoutItem* item, int32 column, int32 row, int32 columnCount, int32 rowCount) { fLayout->AddItem(item, column, row, columnCount, rowCount); return *this; } template typename Grid::ThisBuilder& Grid::AddMenuField(BMenuField* menuField, int32 column, int32 row, alignment labelAlignment, int32 columnCount, int32 rowCount) { BLayoutItem* item = menuField->CreateLabelLayoutItem(); item->SetExplicitAlignment( BAlignment(labelAlignment, B_ALIGN_VERTICAL_UNSET)); fLayout->AddItem(item, column, row, columnCount, rowCount); fLayout->AddItem(menuField->CreateMenuBarLayoutItem(), column + columnCount, row, columnCount, rowCount); return *this; } template typename Grid::ThisBuilder& Grid::AddTextControl(BTextControl* textControl, int32 column, int32 row, alignment labelAlignment, int32 columnCount, int32 rowCount) { BLayoutItem* item = textControl->CreateLabelLayoutItem(); item->SetExplicitAlignment( BAlignment(labelAlignment, B_ALIGN_VERTICAL_UNSET)); fLayout->AddItem(item, column, row, columnCount, rowCount); fLayout->AddItem(textControl->CreateTextViewLayoutItem(), column + columnCount, row, columnCount, rowCount); return *this; } template typename Grid::GroupBuilder Grid::AddGroup(enum orientation orientation, float spacing, int32 column, int32 row, int32 columnCount, int32 rowCount) { GroupBuilder builder(orientation, spacing); builder.SetParent(this); fLayout->AddView(builder.View(), column, row, columnCount, rowCount); return builder; } template typename Grid::GridBuilder Grid::AddGrid(float horizontalSpacing, float verticalSpacing, int32 column, int32 row, int32 columnCount, int32 rowCount) { GridBuilder builder(horizontalSpacing, verticalSpacing); builder.SetParent(this); fLayout->AddView(builder.View(), column, row, columnCount, rowCount); return builder; } template typename Grid::SplitBuilder Grid::AddSplit(enum 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 Grid::ThisBuilder& Grid::SetColumnWeight(int32 column, float weight) { fLayout->SetColumnWeight(column, weight); return *this; } template typename Grid::ThisBuilder& Grid::SetRowWeight(int32 row, float weight) { fLayout->SetRowWeight(row, weight); return *this; } template typename Grid::ThisBuilder& Grid::SetInsets(float left, float top, float right, float bottom) { fLayout->SetInsets(left, top, right, bottom); return *this; } template Grid::operator BGridLayout*() { return fLayout; } template Grid::operator BView*() { return fLayout->View(); } // #pragma mark - Split template Split::Split(enum orientation orientation, float spacing) : fView(new BSplitView(orientation, spacing)) { } template Split::Split(BSplitView* view) : fView(view) { } template BSplitView* Split::View() const { return fView; } template typename Split::ThisBuilder& Split::GetView(BSplitView** _view) { *_view = fView; return *this; } template typename Split::ThisBuilder& Split::Add(BView* view) { fView->AddChild(view); return *this; } template typename Split::ThisBuilder& Split::Add(BView* view, float weight) { fView->AddChild(view, weight); return *this; } template typename Split::ThisBuilder& Split::Add(BLayoutItem* item) { fView->AddChild(item); return *this; } template typename Split::ThisBuilder& Split::Add(BLayoutItem* item, float weight) { fView->AddChild(item, weight); return *this; } template typename Split::GroupBuilder Split::AddGroup(enum orientation orientation, float spacing, float weight) { GroupBuilder builder(orientation, spacing); builder.SetParent(this); fView->AddChild(builder.View(), weight); return builder; } template typename Split::GridBuilder Split::AddGrid(float horizontalSpacing, float verticalSpacing, float weight) { GridBuilder builder(horizontalSpacing, verticalSpacing); builder.SetParent(this); fView->AddChild(builder.View(), weight); return builder; } template typename Split::SplitBuilder Split::AddSplit(enum orientation orientation, float spacing, float weight) { SplitBuilder builder(orientation, spacing); builder.SetParent(this); fView->AddChild(builder.View(), weight); return builder; } template typename Split::ThisBuilder& Split::SetCollapsible(bool collapsible) { fView->SetCollapsible(collapsible); return *this; } template typename Split::ThisBuilder& Split::SetCollapsible(int32 index, bool collapsible) { fView->SetCollapsible(index, collapsible); return *this; } template typename Split::ThisBuilder& Split::SetCollapsible(int32 first, int32 last, bool collapsible) { fView->SetCollapsible(first, last, collapsible); return *this; } template typename Split::ThisBuilder& Split::SetInsets(float left, float top, float right, float bottom) { fView->SetInsets(left, top, right, bottom); return *this; } template Split::operator BSplitView*() { return fView; } } // namespace BLayoutBuilder #endif // _LAYOUT_BUILDER_H