diff --git a/headers/libs/alm/ALMLayout.h b/headers/libs/alm/ALMLayout.h index 9447e1cfc5..8cb1aec4a9 100644 --- a/headers/libs/alm/ALMLayout.h +++ b/headers/libs/alm/ALMLayout.h @@ -69,6 +69,10 @@ public: YTab* BottomOf(const BView* view) const; YTab* BottomOf(const BLayoutItem* item) const; + void BuildLayout(GroupItem& item, XTab* left = NULL, + YTab* top = NULL, XTab* right = NULL, + YTab* bottom = NULL); + virtual BLayoutItem* AddView(BView* child); virtual BLayoutItem* AddView(int32 index, BView* child); virtual Area* AddView(BView* view, XTab* left, YTab* top, @@ -127,6 +131,8 @@ private: BSize _CalculateMaxSize(); BSize _CalculatePreferredSize(); + void _ParseGroupItem(GroupItem& item, XTab* left, + YTab* top, XTab* right, YTab* bottom); LinearSpec fSolver; diff --git a/headers/libs/alm/Area.h b/headers/libs/alm/Area.h index 8c431ef91a..c9b1cabc6e 100644 --- a/headers/libs/alm/Area.h +++ b/headers/libs/alm/Area.h @@ -6,6 +6,8 @@ #define AREA_H +#include + #include #include #include @@ -24,6 +26,35 @@ class Constraint; namespace BALM { +class GroupItem { +public: + GroupItem(BLayoutItem* item); + GroupItem(BView* view); + + BLayoutItem* LayoutItem(); + BView* View(); + + const std::vector& GroupItems(); + enum orientation Orientation(); + + GroupItem& operator|(const GroupItem& right); + GroupItem& operator/(const GroupItem& bottom); +private: + GroupItem(); + + void _Init(BLayoutItem* item, BView* view, + enum orientation orien = B_HORIZONTAL); + GroupItem& _AddItem(const GroupItem& item, + enum orientation orien); + + BLayoutItem* fLayoutItem; + BView* fView; + + std::vector fGroupItems; + enum orientation fOrientation; +}; + + /** * Rectangular area in the GUI, defined by a tab on each side. */ @@ -122,6 +153,7 @@ public: } // namespace BALM using BALM::Area; +using BALM::GroupItem; #endif // AREA_H diff --git a/src/libs/alm/ALMLayout.cpp b/src/libs/alm/ALMLayout.cpp index 302869b395..10a996cd83 100644 --- a/src/libs/alm/ALMLayout.cpp +++ b/src/libs/alm/ALMLayout.cpp @@ -248,6 +248,53 @@ BALMLayout::BottomOf(const BLayoutItem* item) const } +void +BALMLayout::BuildLayout(GroupItem& item, XTab* left, YTab* top, XTab* right, + YTab* bottom) +{ + if (!left) + left = Left(); + if (!top) + top = Top(); + if (!right) + right = Right(); + if (!bottom) + bottom = Bottom(); + + _ParseGroupItem(item, left, top, right, bottom); +} + + +void +BALMLayout::_ParseGroupItem(GroupItem& item, XTab* left, YTab* top, XTab* right, + YTab* bottom) +{ + if (item.LayoutItem()) + AddItem(item.LayoutItem(), left, top, right, bottom); + else if (item.View()) { + AddView(item.View(), left, top, right, bottom); + } + else { + for (unsigned int i = 0; i < item.GroupItems().size(); i++) { + GroupItem& current = const_cast( + item.GroupItems().at(i)); + if (item.Orientation() == B_HORIZONTAL) { + XTab* r = (i == item.GroupItems().size() - 1) ? right + : AddXTab(); + _ParseGroupItem(current, left, top, r, bottom); + left = r; + } + else { + YTab* b = (i == item.GroupItems().size() - 1) ? bottom + : AddYTab(); + _ParseGroupItem(current, left, top, right, b); + top = b; + } + } + } +} + + BLayoutItem* BALMLayout::AddView(BView* child) { diff --git a/src/libs/alm/Area.cpp b/src/libs/alm/Area.cpp index e0b68aaf2e..22778bcba3 100644 --- a/src/libs/alm/Area.cpp +++ b/src/libs/alm/Area.cpp @@ -22,6 +22,93 @@ using namespace std; +GroupItem::GroupItem(BLayoutItem* item) +{ + _Init(item, NULL); +} + + +GroupItem::GroupItem(BView* view) +{ + _Init(NULL, view); +} + + +BLayoutItem* +GroupItem::LayoutItem() +{ + return fLayoutItem; +} + + +BView* +GroupItem::View() +{ + return fView; +} + + +const std::vector& +GroupItem::GroupItems() +{ + return fGroupItems; +} + + +enum orientation +GroupItem::Orientation() +{ + return fOrientation; +} + + +GroupItem& +GroupItem::operator|(const GroupItem& right) +{ + return _AddItem(right, B_HORIZONTAL); +} + + +GroupItem& +GroupItem::operator/(const GroupItem& bottom) +{ + return _AddItem(bottom, B_VERTICAL); +} + + +GroupItem::GroupItem() +{ + _Init(NULL, NULL); +} + + +void +GroupItem::_Init(BLayoutItem* item, BView* view, enum orientation orien) +{ + fLayoutItem = item; + fView = view; + fOrientation = orien; +} + + +GroupItem& +GroupItem::_AddItem(const GroupItem& item, enum orientation orien) +{ + if (fGroupItems.size() == 0) + fGroupItems.push_back(*this); + else if (fOrientation != orien) { + GroupItem clone = *this; + fGroupItems.clear(); + _Init(NULL, NULL, orien); + fGroupItems.push_back(clone); + } + + _Init(NULL, NULL, orien); + fGroupItems.push_back(item); + return *this; +} + + BView* Area::View() { diff --git a/src/libs/alm/Jamfile b/src/libs/alm/Jamfile index f1d4d0334a..cd17f88565 100644 --- a/src/libs/alm/Jamfile +++ b/src/libs/alm/Jamfile @@ -13,5 +13,5 @@ SharedLibrary libalm.so : ALMLayout.cpp Row.cpp : - be liblpsolve55.so liblinprog.so $(TARGET_LIBSUPC++) + be liblpsolve55.so liblinprog.so $(TARGET_LIBSTDC++) ; diff --git a/src/tests/libs/alm/Jamfile b/src/tests/libs/alm/Jamfile index 77ca180dec..2a1d71ed96 100644 --- a/src/tests/libs/alm/Jamfile +++ b/src/tests/libs/alm/Jamfile @@ -36,3 +36,8 @@ Application ALMTableDemo : be liblpsolve55.so be liblinprog.so libalm.so $(TARGET_LIBSUPC++) ; +Application ALMOperator : + OperatorLayout.cpp + : + be liblpsolve55.so be liblinprog.so libalm.so $(TARGET_LIBSTDC++) +; diff --git a/src/tests/libs/alm/OperatorLayout.cpp b/src/tests/libs/alm/OperatorLayout.cpp new file mode 100644 index 0000000000..c6783fca05 --- /dev/null +++ b/src/tests/libs/alm/OperatorLayout.cpp @@ -0,0 +1,66 @@ +/* + * Copyright 2010, Clemens Zeidler + * Distributed under the terms of the MIT License. + */ + + +#include +#include +#include +#include +#include + +#include "ALMLayout.h" + + +class OperatorWindow : public BWindow { +public: + OperatorWindow(BRect frame) + : + BWindow(frame, "ALM Operator", B_TITLED_WINDOW, B_QUIT_ON_WINDOW_CLOSE) + { + BButton* button1 = new BButton("1"); + BButton* button2 = new BButton("2"); + BButton* button3 = new BButton("3"); + BButton* button4 = new BButton("4"); + BButton* button5 = new BButton("5"); + + button1->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNLIMITED)); + button2->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNLIMITED)); + button3->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNLIMITED)); + button4->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNLIMITED)); + button5->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNLIMITED)); + + // create a new BALMLayout and use it for this window + float spacing = be_control_look->DefaultItemSpacing(); + BALMLayout* layout = new BALMLayout(spacing); + SetLayout(layout); + layout->SetInset(spacing); + + GroupItem item = GroupItem(button1) | (GroupItem(button2) + / (GroupItem(button3) | GroupItem(BSpaceLayoutItem::CreateGlue()) + | GroupItem(button4)) + / GroupItem(button5)); + layout->BuildLayout(item); + + // test size limits + BSize min = layout->MinSize(); + BSize max = layout->MaxSize(); + SetSizeLimits(min.Width(), max.Width(), min.Height(), max.Height()); + } + +}; + + +int +main() +{ + BApplication app("application/x-vnd.haiku.ALMOperator"); + + OperatorWindow* window = new OperatorWindow(BRect(100, 100, 300, 300)); + window->Show(); + + app.Run(); + return 0; +} + diff --git a/src/tests/libs/alm/Views.cpp b/src/tests/libs/alm/Views.cpp index 29da0b1d62..1b69f86f54 100644 --- a/src/tests/libs/alm/Views.cpp +++ b/src/tests/libs/alm/Views.cpp @@ -24,7 +24,7 @@ class ViewsWindow : public BWindow { public: ViewsWindow(BRect frame) : - BWindow(frame, "ALM Two Views", B_TITLED_WINDOW, B_QUIT_ON_WINDOW_CLOSE) + BWindow(frame, "ALM Views", B_TITLED_WINDOW, B_QUIT_ON_WINDOW_CLOSE) { BButton* button1 = new BButton("BButton"); BRadioButton* radioButton = new BRadioButton("BRadioButton", NULL);