diff --git a/dgl/Layout.hpp b/dgl/Layout.hpp index 6a0a964a..e4cfc3df 100644 --- a/dgl/Layout.hpp +++ b/dgl/Layout.hpp @@ -17,7 +17,7 @@ #ifndef DGL_LAYOUT_HPP_INCLUDED #define DGL_LAYOUT_HPP_INCLUDED -#include "Base.hpp" +#include "Geometry.hpp" #include @@ -50,11 +50,18 @@ struct Layout typedef Layout HorizontalLayout; typedef Layout VerticalLayout; +struct HorizontallyStackedVerticalLayout +{ + std::list items; + Size adjustSize(uint padding); // TODO + void setAbsolutePos(int x, int y, uint padding); +}; + struct VerticallyStackedHorizontalLayout { std::list items; + Size adjustSize(uint padding); void setAbsolutePos(int x, int y, uint padding); - void setWidth(uint width, uint padding); }; // -------------------------------------------------------------------------------------------------------------------- diff --git a/dgl/src/Layout.cpp b/dgl/src/Layout.cpp index 7db64672..1c9458e1 100644 --- a/dgl/src/Layout.cpp +++ b/dgl/src/Layout.cpp @@ -21,6 +21,7 @@ START_NAMESPACE_DGL typedef std::list::iterator SubWidgetWithSizeHintIterator; typedef std::list::iterator HorizontalLayoutIterator; +typedef std::list::iterator VerticalLayoutIterator; // -------------------------------------------------------------------------------------------------------------------- @@ -41,6 +42,23 @@ uint Layout::setAbsolutePos(int x, const int y, const uint padding) return maxHeight; } +template<> // vertical +uint Layout::setAbsolutePos(const int x, int y, const uint padding) +{ + uint maxWidth = 0; + + for (SubWidgetWithSizeHintIterator it=widgets.begin(), end=widgets.end(); it != end; ++it) + { + SubWidgetWithSizeHint& s(*it); + maxWidth = std::max(maxWidth, s.widget->getWidth()); + s.widget->setAbsolutePos(x, y); + y += s.widget->getHeight(); + y += padding; + } + + return maxWidth; +} + template<> // horizontal void Layout::setSize(const uint width, const uint padding) { @@ -59,9 +77,10 @@ void Layout::setSize(const uint width, const uint padding) ++numDynamiclySizedWidgets; } - const uint widthPerWidget = numDynamiclySizedWidgets != 0 - ? (nonFixedWidth - padding * numDynamiclySizedWidgets) / numDynamiclySizedWidgets - : 0; + if (const size_t numWidgets = widgets.size()) + nonFixedWidth -= padding * (numWidgets - 1); + + const uint widthPerWidget = numDynamiclySizedWidgets != 0 ? nonFixedWidth / numDynamiclySizedWidgets : 0; for (SubWidgetWithSizeHintIterator it=widgets.begin(), end=widgets.end(); it != end; ++it) { @@ -73,24 +92,105 @@ void Layout::setSize(const uint width, const uint padding) } } +template<> // vertical +void Layout::setSize(const uint height, const uint padding) +{ + uint biggestWidth = 0; + uint nonFixedHeight = height; + uint numDynamiclySizedWidgets = 0; + + for (SubWidgetWithSizeHintIterator it=widgets.begin(), end=widgets.end(); it != end; ++it) + { + SubWidgetWithSizeHint& s(*it); + biggestWidth = std::max(biggestWidth, s.widget->getWidth()); + + if (s.sizeHint == Fixed) + nonFixedHeight -= s.widget->getHeight(); + else + ++numDynamiclySizedWidgets; + } + + if (const size_t numWidgets = widgets.size()) + nonFixedHeight -= padding * (numWidgets - 1); + + const uint heightPerWidget = numDynamiclySizedWidgets != 0 ? nonFixedHeight / numDynamiclySizedWidgets : 0; + + for (SubWidgetWithSizeHintIterator it=widgets.begin(), end=widgets.end(); it != end; ++it) + { + SubWidgetWithSizeHint& s(*it); + if (s.sizeHint != Fixed) + s.widget->setSize(biggestWidth, heightPerWidget); + else + s.widget->setWidth(biggestWidth); + } +} + // -------------------------------------------------------------------------------------------------------------------- -void VerticallyStackedHorizontalLayout::setAbsolutePos(const int x, int y, const uint padding) +/* TODO +void HorizontallyStackedVerticalLayout::adjustSize(const uint padding) +{ +} +*/ + +void HorizontallyStackedVerticalLayout::setAbsolutePos(int x, const int y, const uint padding) +{ + for (VerticalLayoutIterator it=items.begin(), end=items.end(); it != end; ++it) + { + VerticalLayout* l(*it); + x += l->setAbsolutePos(x, y, padding); + x += padding; + } +} + +// -------------------------------------------------------------------------------------------------------------------- + +Size VerticallyStackedHorizontalLayout::adjustSize(const uint padding) { + uint biggestWidth = 0; + uint totalHeight = 0; + + // iterate all widgets to find which one is the biggest (horizontally) for (HorizontalLayoutIterator it=items.begin(), end=items.end(); it != end; ++it) { - HorizontalLayout* l(*it); - y += l->setAbsolutePos(x, y, padding); - y += padding; + HorizontalLayout* const l(*it); + uint width = 0; + uint height = 0; + + for (SubWidgetWithSizeHint& s : l->widgets) + { + if (width != 0) + width += padding; + + width += s.widget->getWidth(); + height = std::max(height, s.widget->getHeight()); + } + + biggestWidth = std::max(biggestWidth, width); + + if (totalHeight != 0) + totalHeight += padding; + + totalHeight += height; } + + // now make all horizontal lines the same width + for (HorizontalLayoutIterator it=items.begin(), end=items.end(); it != end; ++it) + { + HorizontalLayout* const l(*it); + l->setSize(biggestWidth, padding); + } + + return Size(biggestWidth, totalHeight); } -void VerticallyStackedHorizontalLayout::setWidth(const uint width, const uint padding) +void VerticallyStackedHorizontalLayout::setAbsolutePos(const int x, int y, const uint padding) { for (HorizontalLayoutIterator it=items.begin(), end=items.end(); it != end; ++it) { HorizontalLayout* l(*it); - l->setSize(width, padding); + y += l->setAbsolutePos(x, y, padding); + y += padding; } }