Mercurial > hg > pub > prymula > com
diff DPF-Prymula-audioplugins/dpf/dgl/src/Layout.cpp @ 3:84e66ea83026
DPF-Prymula-audioplugins-0.231015-2
author | prymula <prymula76@outlook.com> |
---|---|
date | Mon, 16 Oct 2023 21:53:34 +0200 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DPF-Prymula-audioplugins/dpf/dgl/src/Layout.cpp Mon Oct 16 21:53:34 2023 +0200 @@ -0,0 +1,201 @@ +/* + * DISTRHO Plugin Framework (DPF) + * Copyright (C) 2012-2022 Filipe Coelho <falktx@falktx.com> + * + * Permission to use, copy, modify, and/or distribute this software for any purpose with + * or without fee is hereby granted, provided that the above copyright notice and this + * permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD + * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "../Layout.hpp" +#include "../SubWidget.hpp" + +START_NAMESPACE_DGL + +typedef std::list<SubWidgetWithSizeHint>::iterator SubWidgetWithSizeHintIterator; +typedef std::list<HorizontalLayout*>::iterator HorizontalLayoutIterator; +typedef std::list<VerticalLayout*>::iterator VerticalLayoutIterator; + +// -------------------------------------------------------------------------------------------------------------------- + +template<> // horizontal +uint Layout<true>::setAbsolutePos(int x, const int y, const uint padding) +{ + uint maxHeight = 0; + + for (SubWidgetWithSizeHintIterator it=widgets.begin(), end=widgets.end(); it != end; ++it) + { + SubWidgetWithSizeHint& s(*it); + maxHeight = std::max(maxHeight, s.widget->getHeight()); + s.widget->setAbsolutePos(x, y); + x += s.widget->getWidth(); + x += padding; + } + + return maxHeight; +} + +template<> // vertical +uint Layout<false>::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<true>::setSize(const uint width, const uint padding) +{ + uint maxHeight = 0; + uint nonFixedWidth = width; + uint numDynamiclySizedWidgets = 0; + + for (SubWidgetWithSizeHintIterator it=widgets.begin(), end=widgets.end(); it != end; ++it) + { + SubWidgetWithSizeHint& s(*it); + maxHeight = std::max(maxHeight, s.widget->getHeight()); + + if (s.sizeHint == Fixed) + nonFixedWidth -= s.widget->getWidth(); + else + ++numDynamiclySizedWidgets; + } + + 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) + { + SubWidgetWithSizeHint& s(*it); + if (s.sizeHint != Fixed) + s.widget->setSize(widthPerWidget, maxHeight); + else + s.widget->setHeight(maxHeight); + } +} + +template<> // vertical +void Layout<false>::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); + } +} + +// -------------------------------------------------------------------------------------------------------------------- + +/* 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<uint> 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* const l(*it); + uint width = 0; + uint height = 0; + + for (SubWidgetWithSizeHintIterator it=l->widgets.begin(), end=l->widgets.end(); it != end; ++it) + { + SubWidgetWithSizeHint& s(*it); + + 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<uint>(biggestWidth, totalHeight); +} + +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); + y += l->setAbsolutePos(x, y, padding); + y += padding; + } +} + +// -------------------------------------------------------------------------------------------------------------------- + +END_NAMESPACE_DGL