From 14d3fc3fb185bffba255b3b101da8f0659f35c11 Mon Sep 17 00:00:00 2001 From: Rene Hansen Date: Sat, 16 Mar 2024 21:28:01 +0100 Subject: [PATCH 1/9] Implementation of an AutoLayout --- vstgui/lib/crowcolumnview.cpp | 222 ++++++++++++++++++ vstgui/lib/crowcolumnview.h | 12 +- .../viewcreator/rowcolumnviewcreator.cpp | 7 +- .../viewcreator/rowcolumnviewcreator.h | 10 +- 4 files changed, 243 insertions(+), 8 deletions(-) diff --git a/vstgui/lib/crowcolumnview.cpp b/vstgui/lib/crowcolumnview.cpp index 90eda08b2..935d47e0d 100644 --- a/vstgui/lib/crowcolumnview.cpp +++ b/vstgui/lib/crowcolumnview.cpp @@ -5,8 +5,213 @@ #include "crowcolumnview.h" #include "animation/animations.h" #include "animation/timingfunctions.h" +#include namespace VSTGUI { +namespace Layouting { +//-------------------------------------------------------------------------------- +using CRects = std::vector; + +enum class Alignment +{ + kTopLeft, + kTopCenter, + kTopRight, + kMiddleLeft, + kMiddleCenter, + kMiddleRight, + kBottomLeft, + kBottomCenter, + kBottomRight +}; + +enum class Style +{ + kRow, + kColumn +}; + +//-------------------------------------------------------------------------------- +Alignment translate (const CRowColumnView::LayoutStyle layoutStyle) +{ + switch (layoutStyle) + { + case CRowColumnView::LayoutStyle::kTopLeft: + return Alignment::kTopLeft; + case CRowColumnView::LayoutStyle::kTopCenter: + return Alignment::kTopCenter; + case CRowColumnView::LayoutStyle::kTopRight: + return Alignment::kTopRight; + case CRowColumnView::LayoutStyle::kMiddleLeft: + return Alignment::kMiddleLeft; + case CRowColumnView::LayoutStyle::kMiddleCenter: + return Alignment::kMiddleCenter; + case CRowColumnView::LayoutStyle::kMiddleRight: + return Alignment::kMiddleRight; + case CRowColumnView::LayoutStyle::kBottomLeft: + return Alignment::kBottomLeft; + case CRowColumnView::LayoutStyle::kBottomCenter: + return Alignment::kBottomCenter; + case CRowColumnView::LayoutStyle::kBottomRight: + return Alignment::kBottomRight; + default: + return Alignment::kTopLeft; + } +} + +//-------------------------------------------------------------------------------- +Style translate (const CRowColumnView::Style style) +{ + switch (style) + { + case CRowColumnView::Style::kRowStyle: + return Style::kRow; + case CRowColumnView::Style::kColumnStyle: + return Style::kColumn; + default: + return Style::kRow; + } +} + +//-------------------------------------------------------------------------------- +CPoint computeRectOffset (const CPoint& parent, const CPoint& rect, const Alignment alignment) +{ + CPoint offset (0., 0.); + switch (alignment) + { + case Alignment::kTopLeft: + { + offset = CPoint (0., 0.); + break; + } + case Alignment::kTopCenter: + { + offset = CPoint ((parent.x - rect.x) / 2., 0.); + break; + } + case Alignment::kTopRight: + { + offset = CPoint (parent.x - rect.x, 0.); + break; + } + case Alignment::kMiddleLeft: + { + offset = CPoint (0., (parent.y - rect.y) / 2.); + break; + } + case Alignment::kMiddleCenter: + { + offset = CPoint ((parent.x - rect.x) / 2., (parent.y - rect.y) / 2.); + break; + } + case Alignment::kMiddleRight: + { + offset = CPoint (parent.x - rect.x, (parent.y - rect.y) / 2.); + break; + } + case Alignment::kBottomLeft: + { + offset = CPoint (0., parent.y - rect.y); + break; + } + case Alignment::kBottomCenter: + { + offset = CPoint ((parent.x - rect.x) / 2., parent.y - rect.y); + break; + } + case Alignment::kBottomRight: + { + offset = CPoint (parent.x - rect.x, parent.y - rect.y); + break; + } + default: + break; + } + + return offset; +} + +//-------------------------------------------------------------------------------- +CRect computeHelperRect (const CRect& parent, const CRects& rects, const Alignment alignment, + const Style style, double spacing) +{ + CRect helperRect; + if (style == Style::kRow) + { + for (const auto& rect : rects) + { + if (helperRect.getWidth () < rect.getWidth ()) + helperRect.setWidth (rect.getWidth ()); + + auto h = helperRect.getHeight () + rect.getHeight (); + helperRect.setHeight (h); + } + helperRect.setHeight (helperRect.getHeight () + (rects.size () - 1) * spacing); + } + else + { + for (const auto& rect : rects) + { + if (helperRect.getHeight () < rect.getHeight ()) + helperRect.setHeight (rect.getHeight ()); + + auto w = helperRect.getWidth () + rect.getWidth (); + helperRect.setWidth (w); + } + helperRect.setWidth (helperRect.getWidth () + (rects.size () - 1) * spacing); + } + + const CPoint& offset = computeRectOffset (parent.getSize (), helperRect.getSize (), alignment); + return helperRect.offset (offset); +} + +//-------------------------------------------------------------------------------- +CRect computeHelperRect (const CViewContainer& parent, const Alignment alignment, const Style style, + const double spacing) +{ + CRects childrenViewSizes; + parent.forEachChild ( + [&] (const CView* child) { childrenViewSizes.push_back (child->getViewSize ()); }); + + return computeHelperRect (parent.getViewSize (), childrenViewSizes, alignment, style, spacing); +} + +//-------------------------------------------------------------------------------- +// AutoLayout +//-------------------------------------------------------------------------------- +class AutoLayout +{ +public: + //-------------------------------------------------------------------------------- + AutoLayout (const CViewContainer& parent, const Alignment alignment, const Style style, + const double spacing) + : alignment (alignment), style (style) + { + helperRect = Layouting::computeHelperRect (parent, alignment, style, spacing); + } + + auto moveRect (CRect& viewSize) -> CRect& + { + const CPoint offset = + Layouting::computeRectOffset (helperRect.getSize (), viewSize.getSize (), alignment); + if (style == Style::kRow) + viewSize.offset (offset.x, 0.); + else + viewSize.offset (0., offset.y); + + return viewSize.offset (helperRect.getTopLeft ()); + } + + //-------------------------------------------------------------------------------- +private: + const Alignment alignment = Alignment::kTopLeft; + const Style style = Style::kRow; + CRect helperRect; +}; + +//-------------------------------------------------------------------------------- + +} //-------------------------------------------------------------------------------- CRowColumnView::CRowColumnView (const CRect& size, Style style, LayoutStyle layoutStyle, CCoord spacing, const CRect& margin) @@ -127,6 +332,10 @@ void CRowColumnView::layoutViewsEqualSize () maxSize.x = getViewSize ().getWidth () - (margin.right + margin.left); else maxSize.y = getViewSize ().getHeight () - (margin.top + margin.bottom); + + Layouting::AutoLayout layout (*this, Layouting::translate (layoutStyle), + Layouting::translate (style), spacing); + CPoint location = margin.getTopLeft (); forEachChild ([&] (CView* view) { CRect viewSize = view->getViewSize (); @@ -154,6 +363,19 @@ void CRowColumnView::layoutViewsEqualSize () viewSize.offset (diffX, diffY); break; } + case kTopLeft: + case kTopCenter: + case kTopRight: + case kMiddleLeft: + case kMiddleCenter: + case kMiddleRight: + case kBottomLeft: + case kBottomCenter: + case kBottomRight: + { + layout.moveRect (viewSize); + break; + } default: break; } diff --git a/vstgui/lib/crowcolumnview.h b/vstgui/lib/crowcolumnview.h index 0eee783be..427f98e98 100644 --- a/vstgui/lib/crowcolumnview.h +++ b/vstgui/lib/crowcolumnview.h @@ -54,7 +54,17 @@ class CRowColumnView : public CAutoLayoutContainerView /** subviews have the same right or bottom position */ kRightBottomEqualy, /** stretch subviews to the same width and height */ - kStretchEqualy + kStretchEqualy, + + kTopLeft, + kTopCenter, + kTopRight, + kMiddleLeft, + kMiddleCenter, + kMiddleRight, + kBottomLeft, + kBottomCenter, + kBottomRight }; CRowColumnView (const CRect& size, Style style = kRowStyle, LayoutStyle layoutStyle = kLeftTopEqualy, CCoord spacing = 0., const CRect& margin = CRect (0., 0., 0., 0.)); diff --git a/vstgui/uidescription/viewcreator/rowcolumnviewcreator.cpp b/vstgui/uidescription/viewcreator/rowcolumnviewcreator.cpp index 9fb0fde48..be188a1b8 100644 --- a/vstgui/uidescription/viewcreator/rowcolumnviewcreator.cpp +++ b/vstgui/uidescription/viewcreator/rowcolumnviewcreator.cpp @@ -18,7 +18,10 @@ namespace UIViewCreator { //------------------------------------------------------------------------ auto RowColumnViewCreator::layoutStrings () -> LayoutStrings& { - static LayoutStrings strings = {"left-top", "center", "right-bottom", "stretch"}; + static LayoutStrings strings = { + "left-top", "center", "right-bottom", "stretch", "top-left", + "top-center", "top-right", "middle-left", "middle-center", "middle-right", + "bottom-left", "bottom-center", "bottom-right"}; return strings; } @@ -81,7 +84,7 @@ bool RowColumnViewCreator::apply (CView* view, const UIAttributes& attributes, attr = attributes.getAttributeValue (kAttrEqualSizeLayout); if (attr) { - for (auto index = 0u; index <= CRowColumnView::kStretchEqualy; ++index) + for (auto index = 0u; index <= CRowColumnView::kBottomRight; ++index) { if (*attr == layoutStrings ()[index]) { diff --git a/vstgui/uidescription/viewcreator/rowcolumnviewcreator.h b/vstgui/uidescription/viewcreator/rowcolumnviewcreator.h index be9e626d7..7ca2a28ae 100644 --- a/vstgui/uidescription/viewcreator/rowcolumnviewcreator.h +++ b/vstgui/uidescription/viewcreator/rowcolumnviewcreator.h @@ -19,18 +19,18 @@ struct RowColumnViewCreator : ViewCreatorAdapter IdStringPtr getBaseViewName () const override; UTF8StringPtr getDisplayName () const override; CView* create (const UIAttributes& attributes, - const IUIDescription* description) const override; + const IUIDescription* description) const override; bool apply (CView* view, const UIAttributes& attributes, - const IUIDescription* description) const override; + const IUIDescription* description) const override; bool getAttributeNames (StringList& attributeNames) const override; AttrType getAttributeType (const string& attributeName) const override; bool getAttributeValue (CView* view, const string& attributeName, string& stringValue, - const IUIDescription* desc) const override; + const IUIDescription* desc) const override; bool getPossibleListValues (const string& attributeName, - ConstStringPtrList& values) const override; + ConstStringPtrList& values) const override; private: - using LayoutStrings = std::array; + using LayoutStrings = std::array; static LayoutStrings& layoutStrings (); }; From 9ceb031dc5ad749576a06dfd26d6eac6ddcdcf8e Mon Sep 17 00:00:00 2001 From: Rene Hansen Date: Sun, 17 Mar 2024 08:22:08 +0100 Subject: [PATCH 2/9] Repair unit tests for CRowColumnViewCreatorTest --- .../crowcolumnviewcreator_test.cpp | 42 ++++++++++--------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/vstgui/tests/unittest/uidescription/uiviewcreator/crowcolumnviewcreator_test.cpp b/vstgui/tests/unittest/uidescription/uiviewcreator/crowcolumnviewcreator_test.cpp index 60a3f1fe4..a83b8bff9 100644 --- a/vstgui/tests/unittest/uidescription/uiviewcreator/crowcolumnviewcreator_test.cpp +++ b/vstgui/tests/unittest/uidescription/uiviewcreator/crowcolumnviewcreator_test.cpp @@ -16,82 +16,84 @@ using namespace UIViewCreator; TEST_CASE (CRowColumnViewCreatorTest, RowStyle) { testAttribute ( - kCRowColumnView, kAttrRowStyle, true, nullptr, - [] (CRowColumnView* v) { return v->getStyle () == CRowColumnView::kRowStyle; }); + kCRowColumnView, kAttrRowStyle, true, nullptr, + [] (CRowColumnView* v) { return v->getStyle () == CRowColumnView::kRowStyle; }); } TEST_CASE (CRowColumnViewCreatorTest, ColumnStyle) { testAttribute ( - kCRowColumnView, kAttrRowStyle, false, nullptr, - [] (CRowColumnView* v) { return v->getStyle () == CRowColumnView::kColumnStyle; }); + kCRowColumnView, kAttrRowStyle, false, nullptr, + [] (CRowColumnView* v) { return v->getStyle () == CRowColumnView::kColumnStyle; }); } TEST_CASE (CRowColumnViewCreatorTest, Spacing) { testAttribute (kCRowColumnView, kAttrSpacing, 5., nullptr, - [] (CRowColumnView* v) { return v->getSpacing () == 5.; }); + [] (CRowColumnView* v) { return v->getSpacing () == 5.; }); } TEST_CASE (CRowColumnViewCreatorTest, Margin) { CRect margin (5, 6, 7, 8); testAttribute (kCRowColumnView, kAttrMargin, margin, nullptr, - [&] (CRowColumnView* v) { return v->getMargin () == margin; }); + [&] (CRowColumnView* v) { return v->getMargin () == margin; }); } TEST_CASE (CRowColumnViewCreatorTest, AnimateViewResizing) { testAttribute (kCRowColumnView, kAttrAnimateViewResizing, true, nullptr, - [] (CRowColumnView* v) { return v->isAnimateViewResizing (); }); + [] (CRowColumnView* v) { return v->isAnimateViewResizing (); }); } TEST_CASE (CRowColumnViewCreatorTest, EqualSizeLayoutStretch) { testAttribute ( - kCRowColumnView, kAttrEqualSizeLayout, "stretch", nullptr, - [] (CRowColumnView* v) { return v->getLayoutStyle () == CRowColumnView::kStretchEqualy; }); + kCRowColumnView, kAttrEqualSizeLayout, "stretch", nullptr, + [] (CRowColumnView* v) { return v->getLayoutStyle () == CRowColumnView::kStretchEqualy; }); } TEST_CASE (CRowColumnViewCreatorTest, EqualSizeLayoutCenter) { testAttribute ( - kCRowColumnView, kAttrEqualSizeLayout, "center", nullptr, - [] (CRowColumnView* v) { return v->getLayoutStyle () == CRowColumnView::kCenterEqualy; }); + kCRowColumnView, kAttrEqualSizeLayout, "center", nullptr, + [] (CRowColumnView* v) { return v->getLayoutStyle () == CRowColumnView::kCenterEqualy; }); } TEST_CASE (CRowColumnViewCreatorTest, EqualSizeLayoutRightBottom) { testAttribute ( - kCRowColumnView, kAttrEqualSizeLayout, "right-bottom", nullptr, [] (CRowColumnView* v) { - return v->getLayoutStyle () == CRowColumnView::kRightBottomEqualy; - }); + kCRowColumnView, kAttrEqualSizeLayout, "right-bottom", nullptr, [] (CRowColumnView* v) { + return v->getLayoutStyle () == CRowColumnView::kRightBottomEqualy; + }); } TEST_CASE (CRowColumnViewCreatorTest, EqualSizeLayoutLeftTop) { testAttribute ( - kCRowColumnView, kAttrEqualSizeLayout, "left-top", nullptr, - [] (CRowColumnView* v) { return v->getLayoutStyle () == CRowColumnView::kLeftTopEqualy; }); + kCRowColumnView, kAttrEqualSizeLayout, "left-top", nullptr, + [] (CRowColumnView* v) { return v->getLayoutStyle () == CRowColumnView::kLeftTopEqualy; }); } TEST_CASE (CRowColumnViewCreatorTest, AnimationTime) { testAttribute ( - kCRowColumnView, kAttrViewResizeAnimationTime, 100, nullptr, - [] (CRowColumnView* v) { return v->getViewResizeAnimationTime () == 100; }); + kCRowColumnView, kAttrViewResizeAnimationTime, 100, nullptr, + [] (CRowColumnView* v) { return v->getViewResizeAnimationTime () == 100; }); } TEST_CASE (CRowColumnViewCreatorTest, EqualSizeLayoutValues) { testPossibleValues (kCRowColumnView, kAttrEqualSizeLayout, nullptr, - {"left-top", "stretch", "center", "right-bottom"}); + {"left-top", "stretch", "center", "right-bottom", "top-left", "top-center", + "top-right", "middle-left", "middle-center", "middle-right", "bottom-left", + "bottom-center", "bottom-right"}); } TEST_CASE (CRowColumnViewCreatorTest, HideClippedSubviews) { testAttribute (kCRowColumnView, kAttrHideClippedSubviews, true, nullptr, - [] (CRowColumnView* v) { return v->hideClippedSubviews (); }); + [] (CRowColumnView* v) { return v->hideClippedSubviews (); }); } } // VSTGUI From 40525118df30c7bb26443e03e79ef50eb279479e Mon Sep 17 00:00:00 2001 From: Rene Hansen Date: Sun, 17 Mar 2024 10:52:08 +0100 Subject: [PATCH 3/9] Add CRowColumnView layout tests --- .../unittest/lib/crowcolumnview_test.cpp | 158 ++++++++++++++++++ 1 file changed, 158 insertions(+) create mode 100644 vstgui/tests/unittest/lib/crowcolumnview_test.cpp diff --git a/vstgui/tests/unittest/lib/crowcolumnview_test.cpp b/vstgui/tests/unittest/lib/crowcolumnview_test.cpp new file mode 100644 index 000000000..d41a75f87 --- /dev/null +++ b/vstgui/tests/unittest/lib/crowcolumnview_test.cpp @@ -0,0 +1,158 @@ +// This file is part of VSTGUI. It is subject to the license terms +// in the LICENSE file found in the top-level directory of this +// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE + +#include "../../../lib/crowcolumnview.h" +#include "../unittests.h" +#include +#include + +namespace VSTGUI { + +using Rects = std::vector; + +static const CRect templateSize (0., 0., 100., 100.); +static const CRect layoutSize (0., 0., 80., 80.); + +static const Rects childrenDefaultSizes = { + {0., 0., 10., 10.}, + {0., 0., 20., 20.}, + {0., 0., 30., 30.} +}; + +static const std::map kChildrenResultSizes = { + { + CRowColumnView::kTopLeft, { + {0., 0., 10., 10.}, + {0., 10., 20., 30.}, + {0., 30., 30., 60.} + } + }, + { + CRowColumnView::kTopCenter, { + {35., 0., 45., 10.}, + {30., 10., 50., 30.}, + {25., 30., 55., 60.} + } + }, + { + CRowColumnView::kTopRight, { + {70., 0., 80., 10.}, + {60., 10., 80., 30.}, + {50., 30., 80., 60.} + } + }, + { + CRowColumnView::kMiddleLeft, { + {0., 10., 10., 20.}, + {0., 20., 20., 40.}, + {0., 40., 30., 70.} + } + }, + { + CRowColumnView::kMiddleCenter, { + {35., 10., 45., 20.}, + {30., 20., 50., 40.}, + {25., 40., 55., 70.} + } + }, + { + CRowColumnView::kMiddleRight, { + {70., 10., 80., 20.}, + {60., 20., 80., 40.}, + {50., 40., 80., 70.} + } + }, + { + CRowColumnView::kBottomLeft, { + {0., 20., 10., 30.}, + {0., 30., 20., 50.}, + {0., 50., 30., 80.} + } + }, + { + CRowColumnView::kBottomCenter, { + {35., 20., 45., 30.}, + {30., 30., 50., 50.}, + {25., 50., 55., 80.} + } + }, + { + CRowColumnView::kBottomRight, { + {70., 20., 80., 30.}, + {60., 30., 80., 50.}, + {50., 50., 80., 80.} + } + } +}; + +auto testWithLayoutStyle(const CRowColumnView::LayoutStyle layoutStyle) -> void +{ + auto rowColumnView = owned (new CRowColumnView(layoutSize)); + rowColumnView->setStyle(CRowColumnView::kRowStyle); + rowColumnView->setLayoutStyle(layoutStyle); + + for(auto& rect : childrenDefaultSizes) + { + auto child = new CView(rect); + rowColumnView->CViewContainer::addView(child); + rowColumnView->layoutViews(); + } + + //rowColumnView->layoutViews(); + size_t i = 0; + rowColumnView->forEachChild([&](CView* child){ + const auto& results = kChildrenResultSizes.find(layoutStyle); + const auto& childrenResults = results->second; + auto viewSize = child->getViewSize(); + EXPECT (viewSize == childrenResults.at(i)) + i++; + }); +} + +TEST_CASE (CRowColumnViewTest, LayoutTopLeftStyle) +{ + //testWithLayoutStyle(CRowColumnView::kTopLeft); +} + +TEST_CASE (CRowColumnViewTest, LayoutTopCenterStyle) +{ + testWithLayoutStyle(CRowColumnView::kTopCenter); +} + +TEST_CASE (CRowColumnViewTest, LayoutTopRightStyle) +{ + testWithLayoutStyle(CRowColumnView::kTopRight); +} + +TEST_CASE (CRowColumnViewTest, LayoutMiddleLeftStyle) +{ + testWithLayoutStyle(CRowColumnView::kMiddleLeft); +} + +TEST_CASE (CRowColumnViewTest, LayoutMiddleCenterStyle) +{ + testWithLayoutStyle(CRowColumnView::kMiddleCenter); +} + +TEST_CASE (CRowColumnViewTest, LayoutMiddleRightStyle) +{ + testWithLayoutStyle(CRowColumnView::kMiddleRight); +} + +TEST_CASE (CRowColumnViewTest, LayoutBottomLeftStyle) +{ + testWithLayoutStyle(CRowColumnView::kBottomLeft); +} + +TEST_CASE (CRowColumnViewTest, LayoutBottomCenterStyle) +{ + testWithLayoutStyle(CRowColumnView::kBottomCenter); +} + +TEST_CASE (CRowColumnViewTest, LayoutBottomRightStyle) +{ + testWithLayoutStyle(CRowColumnView::kBottomRight); +} + +} // VSTGUI From aad679ce0b69fc4342f022e21677d2e4ccfc63b1 Mon Sep 17 00:00:00 2001 From: Rene Hansen Date: Sun, 17 Mar 2024 10:54:08 +0100 Subject: [PATCH 4/9] Clang format without results map --- .../unittest/lib/crowcolumnview_test.cpp | 62 ++++++++++--------- 1 file changed, 32 insertions(+), 30 deletions(-) diff --git a/vstgui/tests/unittest/lib/crowcolumnview_test.cpp b/vstgui/tests/unittest/lib/crowcolumnview_test.cpp index d41a75f87..aea5a19dd 100644 --- a/vstgui/tests/unittest/lib/crowcolumnview_test.cpp +++ b/vstgui/tests/unittest/lib/crowcolumnview_test.cpp @@ -14,6 +14,7 @@ using Rects = std::vector; static const CRect templateSize (0., 0., 100., 100.); static const CRect layoutSize (0., 0., 80., 80.); +// clang-format off static const Rects childrenDefaultSizes = { {0., 0., 10., 10.}, {0., 0., 20., 20.}, @@ -85,74 +86,75 @@ static const std::map kChildrenResultSizes = } } }; +// clang-format on -auto testWithLayoutStyle(const CRowColumnView::LayoutStyle layoutStyle) -> void +auto testWithLayoutStyle (const CRowColumnView::LayoutStyle layoutStyle) -> void { - auto rowColumnView = owned (new CRowColumnView(layoutSize)); - rowColumnView->setStyle(CRowColumnView::kRowStyle); - rowColumnView->setLayoutStyle(layoutStyle); - - for(auto& rect : childrenDefaultSizes) - { - auto child = new CView(rect); - rowColumnView->CViewContainer::addView(child); - rowColumnView->layoutViews(); - } - - //rowColumnView->layoutViews(); - size_t i = 0; - rowColumnView->forEachChild([&](CView* child){ - const auto& results = kChildrenResultSizes.find(layoutStyle); - const auto& childrenResults = results->second; - auto viewSize = child->getViewSize(); - EXPECT (viewSize == childrenResults.at(i)) - i++; - }); + auto rowColumnView = owned (new CRowColumnView (layoutSize)); + rowColumnView->setStyle (CRowColumnView::kRowStyle); + rowColumnView->setLayoutStyle (layoutStyle); + + for (auto& rect : childrenDefaultSizes) + { + auto child = new CView (rect); + rowColumnView->CViewContainer::addView (child); + rowColumnView->layoutViews (); + } + + // rowColumnView->layoutViews(); + size_t i = 0; + rowColumnView->forEachChild ([&] (CView* child) { + const auto& results = kChildrenResultSizes.find (layoutStyle); + const auto& childrenResults = results->second; + auto viewSize = child->getViewSize (); + EXPECT (viewSize == childrenResults.at (i)) + i++; + }); } TEST_CASE (CRowColumnViewTest, LayoutTopLeftStyle) { - //testWithLayoutStyle(CRowColumnView::kTopLeft); + // testWithLayoutStyle(CRowColumnView::kTopLeft); } TEST_CASE (CRowColumnViewTest, LayoutTopCenterStyle) { - testWithLayoutStyle(CRowColumnView::kTopCenter); + testWithLayoutStyle (CRowColumnView::kTopCenter); } TEST_CASE (CRowColumnViewTest, LayoutTopRightStyle) { - testWithLayoutStyle(CRowColumnView::kTopRight); + testWithLayoutStyle (CRowColumnView::kTopRight); } TEST_CASE (CRowColumnViewTest, LayoutMiddleLeftStyle) { - testWithLayoutStyle(CRowColumnView::kMiddleLeft); + testWithLayoutStyle (CRowColumnView::kMiddleLeft); } TEST_CASE (CRowColumnViewTest, LayoutMiddleCenterStyle) { - testWithLayoutStyle(CRowColumnView::kMiddleCenter); + testWithLayoutStyle (CRowColumnView::kMiddleCenter); } TEST_CASE (CRowColumnViewTest, LayoutMiddleRightStyle) { - testWithLayoutStyle(CRowColumnView::kMiddleRight); + testWithLayoutStyle (CRowColumnView::kMiddleRight); } TEST_CASE (CRowColumnViewTest, LayoutBottomLeftStyle) { - testWithLayoutStyle(CRowColumnView::kBottomLeft); + testWithLayoutStyle (CRowColumnView::kBottomLeft); } TEST_CASE (CRowColumnViewTest, LayoutBottomCenterStyle) { - testWithLayoutStyle(CRowColumnView::kBottomCenter); + testWithLayoutStyle (CRowColumnView::kBottomCenter); } TEST_CASE (CRowColumnViewTest, LayoutBottomRightStyle) { - testWithLayoutStyle(CRowColumnView::kBottomRight); + testWithLayoutStyle (CRowColumnView::kBottomRight); } } // VSTGUI From 996b0ab255afe276a4d2a8282fbeb7a9a5f24cd4 Mon Sep 17 00:00:00 2001 From: Rene Hansen Date: Sun, 17 Mar 2024 11:09:20 +0100 Subject: [PATCH 5/9] Add layout test with spacing --- .../unittest/lib/crowcolumnview_test.cpp | 23 +++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/vstgui/tests/unittest/lib/crowcolumnview_test.cpp b/vstgui/tests/unittest/lib/crowcolumnview_test.cpp index aea5a19dd..67ae5f608 100644 --- a/vstgui/tests/unittest/lib/crowcolumnview_test.cpp +++ b/vstgui/tests/unittest/lib/crowcolumnview_test.cpp @@ -86,13 +86,28 @@ static const std::map kChildrenResultSizes = } } }; + +static const std::map kChildrenResultSizesWithSpacing = { + { + CRowColumnView::kMiddleCenter, { + {35., 6., 45., 16.}, + {30., 20., 50., 40.}, + {25., 44., 55., 74.} + } + } +}; // clang-format on -auto testWithLayoutStyle (const CRowColumnView::LayoutStyle layoutStyle) -> void +auto testWithLayoutStyle (const CRowColumnView::LayoutStyle layoutStyle, + double spacing = 0.) -> void { + const auto& results = spacing == 0. ? kChildrenResultSizes.find (layoutStyle) + : kChildrenResultSizesWithSpacing.find (layoutStyle); + auto rowColumnView = owned (new CRowColumnView (layoutSize)); rowColumnView->setStyle (CRowColumnView::kRowStyle); rowColumnView->setLayoutStyle (layoutStyle); + rowColumnView->setSpacing (spacing); for (auto& rect : childrenDefaultSizes) { @@ -104,7 +119,6 @@ auto testWithLayoutStyle (const CRowColumnView::LayoutStyle layoutStyle) -> void // rowColumnView->layoutViews(); size_t i = 0; rowColumnView->forEachChild ([&] (CView* child) { - const auto& results = kChildrenResultSizes.find (layoutStyle); const auto& childrenResults = results->second; auto viewSize = child->getViewSize (); EXPECT (viewSize == childrenResults.at (i)) @@ -157,4 +171,9 @@ TEST_CASE (CRowColumnViewTest, LayoutBottomRightStyle) testWithLayoutStyle (CRowColumnView::kBottomRight); } +TEST_CASE (CRowColumnViewTest, LayoutMiddleCenterStyleWithSpacing) +{ + testWithLayoutStyle (CRowColumnView::kMiddleCenter, 4.); +} + } // VSTGUI From 88dc8565615dceb338a00748565fa0db7ae622ab Mon Sep 17 00:00:00 2001 From: Rene Hansen Date: Sun, 17 Mar 2024 17:06:17 +0100 Subject: [PATCH 6/9] Add column layout unit tests --- .../unittest/lib/crowcolumnview_test.cpp | 200 +++++++++++++++--- 1 file changed, 168 insertions(+), 32 deletions(-) diff --git a/vstgui/tests/unittest/lib/crowcolumnview_test.cpp b/vstgui/tests/unittest/lib/crowcolumnview_test.cpp index 67ae5f608..ca842e4bb 100644 --- a/vstgui/tests/unittest/lib/crowcolumnview_test.cpp +++ b/vstgui/tests/unittest/lib/crowcolumnview_test.cpp @@ -21,7 +21,9 @@ static const Rects childrenDefaultSizes = { {0., 0., 30., 30.} }; -static const std::map kChildrenResultSizes = { +using ExpectedResults = std::map; + +static const ExpectedResults kRowLayoutChildrenResultSizes = { { CRowColumnView::kTopLeft, { {0., 0., 10., 10.}, @@ -87,7 +89,73 @@ static const std::map kChildrenResultSizes = } }; -static const std::map kChildrenResultSizesWithSpacing = { +static const ExpectedResults kColumnLayoutChildrenResultSizes = { + { + CRowColumnView::kTopLeft, { + {0., 0., 10., 10.}, + {10., 0., 30., 20.}, + {30., 0., 60., 30.} + } + }, + { + CRowColumnView::kTopCenter, { + {10., 0., 20., 10.}, + {20., 0., 40., 20.}, + {40., 0., 70., 30.} + } + }, + { + CRowColumnView::kTopRight, { + {20., 0., 30., 10.}, + {30., 0., 50., 20.}, + {50., 0., 80., 30.} + } + }, + { + CRowColumnView::kMiddleLeft, { + {0., 35., 10., 45.}, + {10., 30., 30., 50.}, + {30., 25., 60., 55.} + } + }, + { + CRowColumnView::kMiddleCenter, { + {10., 35., 20., 45.}, + {20., 30., 40., 50.}, + {40., 25., 70., 55.} + } + }, + { + CRowColumnView::kMiddleRight, { + {20., 35., 30., 45.}, + {30., 30., 50., 50.}, + {50., 25., 80., 55.} + } + }, + { + CRowColumnView::kBottomLeft, { + {0., 70., 10., 80.}, + {10., 60., 30., 80.}, + {30., 50., 60., 80.} + } + }, + { + CRowColumnView::kBottomCenter, { + {10., 70., 20., 80.}, + {20., 60., 40., 80.}, + {40., 50., 70., 80.} + } + }, + { + CRowColumnView::kBottomRight, { + {20., 70., 30., 80.}, + {30., 60., 50., 80.}, + {50., 50., 80., 80.} + } + } +}; + +static const ExpectedResults kRowLayoutChildrenResultSizesWithSpacing = { { CRowColumnView::kMiddleCenter, { {35., 6., 45., 16.}, @@ -98,16 +166,21 @@ static const std::map kChildrenResultSizesWi }; // clang-format on -auto testWithLayoutStyle (const CRowColumnView::LayoutStyle layoutStyle, - double spacing = 0.) -> void +struct TestData { - const auto& results = spacing == 0. ? kChildrenResultSizes.find (layoutStyle) - : kChildrenResultSizesWithSpacing.find (layoutStyle); + CRowColumnView::LayoutStyle layoutStyle = CRowColumnView::LayoutStyle::kTopLeft; + CRowColumnView::Style style = CRowColumnView::Style::kRowStyle; + double spacing = 0.; + ExpectedResults expected; +}; +auto testWithLayoutStyle (const TestData& testData) -> void +{ + const auto& expected = testData.expected.find (testData.layoutStyle)->second; auto rowColumnView = owned (new CRowColumnView (layoutSize)); - rowColumnView->setStyle (CRowColumnView::kRowStyle); - rowColumnView->setLayoutStyle (layoutStyle); - rowColumnView->setSpacing (spacing); + rowColumnView->setStyle (testData.style); + rowColumnView->setLayoutStyle (testData.layoutStyle); + rowColumnView->setSpacing (testData.spacing); for (auto& rect : childrenDefaultSizes) { @@ -116,64 +189,127 @@ auto testWithLayoutStyle (const CRowColumnView::LayoutStyle layoutStyle, rowColumnView->layoutViews (); } - // rowColumnView->layoutViews(); size_t i = 0; rowColumnView->forEachChild ([&] (CView* child) { - const auto& childrenResults = results->second; + const auto& childrenResults = testData.expected.find (testData.layoutStyle); auto viewSize = child->getViewSize (); - EXPECT (viewSize == childrenResults.at (i)) + EXPECT (viewSize == expected.at (i)) i++; }); } -TEST_CASE (CRowColumnViewTest, LayoutTopLeftStyle) +TEST_CASE (CRowColumnViewTest, RowLayoutTopLeftStyle) +{ + testWithLayoutStyle ( + {CRowColumnView::kTopLeft, CRowColumnView::kRowStyle, 0., kRowLayoutChildrenResultSizes}); +} + +TEST_CASE (CRowColumnViewTest, RowLayoutTopCenterStyle) +{ + testWithLayoutStyle ( + {CRowColumnView::kTopCenter, CRowColumnView::kRowStyle, 0., kRowLayoutChildrenResultSizes}); +} + +TEST_CASE (CRowColumnViewTest, RowLayoutTopRightStyle) +{ + testWithLayoutStyle ( + {CRowColumnView::kTopRight, CRowColumnView::kRowStyle, 0., kRowLayoutChildrenResultSizes}); +} + +TEST_CASE (CRowColumnViewTest, RowLayoutMiddleLeftStyle) +{ + testWithLayoutStyle ({CRowColumnView::kMiddleLeft, CRowColumnView::kRowStyle, 0., + kRowLayoutChildrenResultSizes}); +} + +TEST_CASE (CRowColumnViewTest, RowLayoutMiddleCenterStyle) +{ + testWithLayoutStyle ({CRowColumnView::kMiddleCenter, CRowColumnView::kRowStyle, 0., + kRowLayoutChildrenResultSizes}); +} + +TEST_CASE (CRowColumnViewTest, RowLayoutMiddleRightStyle) +{ + testWithLayoutStyle ({CRowColumnView::kMiddleRight, CRowColumnView::kRowStyle, 0., + kRowLayoutChildrenResultSizes}); +} + +TEST_CASE (CRowColumnViewTest, RowLayoutBottomLeftStyle) +{ + testWithLayoutStyle ({CRowColumnView::kBottomLeft, CRowColumnView::kRowStyle, 0., + kRowLayoutChildrenResultSizes}); +} + +TEST_CASE (CRowColumnViewTest, RowLayoutBottomCenterStyle) +{ + testWithLayoutStyle ({CRowColumnView::kBottomCenter, CRowColumnView::kRowStyle, 0., + kRowLayoutChildrenResultSizes}); +} + +TEST_CASE (CRowColumnViewTest, RowLayoutBottomRightStyle) +{ + testWithLayoutStyle ({CRowColumnView::kBottomRight, CRowColumnView::kRowStyle, 0., + kRowLayoutChildrenResultSizes}); +} + +TEST_CASE (CRowColumnViewTest, ColumnLayoutTopLeftStyle) { - // testWithLayoutStyle(CRowColumnView::kTopLeft); + testWithLayoutStyle ({CRowColumnView::kTopLeft, CRowColumnView::kColumnStyle, 0., + kColumnLayoutChildrenResultSizes}); } -TEST_CASE (CRowColumnViewTest, LayoutTopCenterStyle) +TEST_CASE (CRowColumnViewTest, ColumnLayoutTopCenterStyle) { - testWithLayoutStyle (CRowColumnView::kTopCenter); + testWithLayoutStyle ({CRowColumnView::kTopCenter, CRowColumnView::kColumnStyle, 0., + kColumnLayoutChildrenResultSizes}); } -TEST_CASE (CRowColumnViewTest, LayoutTopRightStyle) +TEST_CASE (CRowColumnViewTest, ColumnLayoutTopRightStyle) { - testWithLayoutStyle (CRowColumnView::kTopRight); + testWithLayoutStyle ({CRowColumnView::kTopRight, CRowColumnView::kColumnStyle, 0., + kColumnLayoutChildrenResultSizes}); } -TEST_CASE (CRowColumnViewTest, LayoutMiddleLeftStyle) +TEST_CASE (CRowColumnViewTest, ColumnLayoutMiddleLeftStyle) { - testWithLayoutStyle (CRowColumnView::kMiddleLeft); + testWithLayoutStyle ({CRowColumnView::kMiddleLeft, CRowColumnView::kColumnStyle, 0., + kColumnLayoutChildrenResultSizes}); } -TEST_CASE (CRowColumnViewTest, LayoutMiddleCenterStyle) +TEST_CASE (CRowColumnViewTest, ColumnLayoutMiddleCenterStyle) { - testWithLayoutStyle (CRowColumnView::kMiddleCenter); + testWithLayoutStyle ({CRowColumnView::kMiddleCenter, CRowColumnView::kColumnStyle, 0., + kColumnLayoutChildrenResultSizes}); } -TEST_CASE (CRowColumnViewTest, LayoutMiddleRightStyle) +TEST_CASE (CRowColumnViewTest, ColumnLayoutMiddleRightStyle) { - testWithLayoutStyle (CRowColumnView::kMiddleRight); + testWithLayoutStyle ({CRowColumnView::kMiddleRight, CRowColumnView::kColumnStyle, 0., + kColumnLayoutChildrenResultSizes}); } -TEST_CASE (CRowColumnViewTest, LayoutBottomLeftStyle) +TEST_CASE (CRowColumnViewTest, ColumnLayoutBottomLeftStyle) { - testWithLayoutStyle (CRowColumnView::kBottomLeft); + testWithLayoutStyle ({CRowColumnView::kBottomLeft, CRowColumnView::kColumnStyle, 0., + kColumnLayoutChildrenResultSizes}); } -TEST_CASE (CRowColumnViewTest, LayoutBottomCenterStyle) +TEST_CASE (CRowColumnViewTest, ColumnLayoutBottomCenterStyle) { - testWithLayoutStyle (CRowColumnView::kBottomCenter); + testWithLayoutStyle ({CRowColumnView::kBottomCenter, CRowColumnView::kColumnStyle, 0., + kColumnLayoutChildrenResultSizes}); } -TEST_CASE (CRowColumnViewTest, LayoutBottomRightStyle) +TEST_CASE (CRowColumnViewTest, ColumnLayoutBottomRightStyle) { - testWithLayoutStyle (CRowColumnView::kBottomRight); + testWithLayoutStyle ({CRowColumnView::kBottomRight, CRowColumnView::kColumnStyle, 0., + kColumnLayoutChildrenResultSizes}); } -TEST_CASE (CRowColumnViewTest, LayoutMiddleCenterStyleWithSpacing) +TEST_CASE (CRowColumnViewTest, RowLayoutMiddleCenterStyleWithSpacing) { - testWithLayoutStyle (CRowColumnView::kMiddleCenter, 4.); + testWithLayoutStyle ({CRowColumnView::kMiddleCenter, CRowColumnView::kRowStyle, 4., + kRowLayoutChildrenResultSizesWithSpacing}); } } // VSTGUI From 9323713ffa858b3071e984f5107beae6f9a37123 Mon Sep 17 00:00:00 2001 From: Rene Hansen Date: Sun, 17 Mar 2024 17:28:11 +0100 Subject: [PATCH 7/9] Use Cpoint instead of CRect to improve code --- vstgui/lib/crowcolumnview.cpp | 81 +++++++++++++++++++---------------- 1 file changed, 44 insertions(+), 37 deletions(-) diff --git a/vstgui/lib/crowcolumnview.cpp b/vstgui/lib/crowcolumnview.cpp index 935d47e0d..fc8905cc9 100644 --- a/vstgui/lib/crowcolumnview.cpp +++ b/vstgui/lib/crowcolumnview.cpp @@ -132,37 +132,41 @@ CPoint computeRectOffset (const CPoint& parent, const CPoint& rect, const Alignm } //-------------------------------------------------------------------------------- -CRect computeHelperRect (const CRect& parent, const CRects& rects, const Alignment alignment, +CRect computeHelperRect (const CRect& parent, const CRects& children, const Alignment alignment, const Style style, double spacing) { - CRect helperRect; - if (style == Style::kRow) - { - for (const auto& rect : rects) - { - if (helperRect.getWidth () < rect.getWidth ()) - helperRect.setWidth (rect.getWidth ()); - - auto h = helperRect.getHeight () + rect.getHeight (); - helperRect.setHeight (h); - } - helperRect.setHeight (helperRect.getHeight () + (rects.size () - 1) * spacing); - } - else - { - for (const auto& rect : rects) - { - if (helperRect.getHeight () < rect.getHeight ()) - helperRect.setHeight (rect.getHeight ()); - - auto w = helperRect.getWidth () + rect.getWidth (); - helperRect.setWidth (w); - } - helperRect.setWidth (helperRect.getWidth () + (rects.size () - 1) * spacing); - } - - const CPoint& offset = computeRectOffset (parent.getSize (), helperRect.getSize (), alignment); - return helperRect.offset (offset); + CPoint maxSize; + if (style == Style::kRow) + { + for (const auto& rect : children) + { + if (maxSize.x < rect.getWidth ()) + maxSize.x = rect.getWidth (); + + maxSize.y = maxSize.y + rect.getHeight () + spacing; + } + + // Remove the last spacing again + if (!children.empty()) + maxSize.y -= spacing; + } + else + { + for (const auto& rect : children) + { + if (maxSize.y < rect.getHeight ()) + maxSize.y = rect.getHeight (); + + maxSize.x = maxSize.x + rect.getWidth () + spacing; + } + + // Remove the last spacing again + if (!children.empty()) + maxSize.x -= spacing; + } + + const auto offset = computeRectOffset (parent.getSize (), maxSize, alignment); + return CRect().setSize(maxSize).offset(offset); } //-------------------------------------------------------------------------------- @@ -192,14 +196,17 @@ class AutoLayout auto moveRect (CRect& viewSize) -> CRect& { - const CPoint offset = - Layouting::computeRectOffset (helperRect.getSize (), viewSize.getSize (), alignment); - if (style == Style::kRow) - viewSize.offset (offset.x, 0.); - else - viewSize.offset (0., offset.y); - - return viewSize.offset (helperRect.getTopLeft ()); + // Offset the viewSize inside the helperRect... + const CPoint offset = + Layouting::computeRectOffset (helperRect.getSize (), viewSize.getSize (), alignment); + if (style == Style::kRow) + viewSize.offset (offset.x, 0.); + else + viewSize.offset (0., offset.y); + + //...and offset by topLeft of the helperRect afterwards, in order to align with the + // 'real' parent. + return viewSize.offset (helperRect.getTopLeft ()); } //-------------------------------------------------------------------------------- From b011bd3ea83b9b13c5f829d86075019c6d41b60a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Hansen?= Date: Sat, 13 Apr 2024 10:55:09 +0200 Subject: [PATCH 8/9] Rename to GroupRect for better explanation --- vstgui/lib/crowcolumnview.cpp | 36 +++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/vstgui/lib/crowcolumnview.cpp b/vstgui/lib/crowcolumnview.cpp index fc8905cc9..5fa4c0953 100644 --- a/vstgui/lib/crowcolumnview.cpp +++ b/vstgui/lib/crowcolumnview.cpp @@ -132,8 +132,8 @@ CPoint computeRectOffset (const CPoint& parent, const CPoint& rect, const Alignm } //-------------------------------------------------------------------------------- -CRect computeHelperRect (const CRect& parent, const CRects& children, const Alignment alignment, - const Style style, double spacing) +CRect computeGroupRect (const CRect& parent, const CRects& children, const Alignment alignment, + const Style style, double spacing) { CPoint maxSize; if (style == Style::kRow) @@ -170,14 +170,14 @@ CRect computeHelperRect (const CRect& parent, const CRects& children, const Alig } //-------------------------------------------------------------------------------- -CRect computeHelperRect (const CViewContainer& parent, const Alignment alignment, const Style style, - const double spacing) +CRect computeGroupRect (const CViewContainer& parent, const Alignment alignment, const Style style, + const double spacing) { CRects childrenViewSizes; parent.forEachChild ( [&] (const CView* child) { childrenViewSizes.push_back (child->getViewSize ()); }); - return computeHelperRect (parent.getViewSize (), childrenViewSizes, alignment, style, spacing); + return computeGroupRect (parent.getViewSize (), childrenViewSizes, alignment, style, spacing); } //-------------------------------------------------------------------------------- @@ -191,29 +191,29 @@ class AutoLayout const double spacing) : alignment (alignment), style (style) { - helperRect = Layouting::computeHelperRect (parent, alignment, style, spacing); + groupRect = Layouting::computeGroupRect (parent, alignment, style, spacing); } auto moveRect (CRect& viewSize) -> CRect& { - // Offset the viewSize inside the helperRect... - const CPoint offset = - Layouting::computeRectOffset (helperRect.getSize (), viewSize.getSize (), alignment); - if (style == Style::kRow) - viewSize.offset (offset.x, 0.); - else - viewSize.offset (0., offset.y); - - //...and offset by topLeft of the helperRect afterwards, in order to align with the - // 'real' parent. - return viewSize.offset (helperRect.getTopLeft ()); + // Offset the viewSize inside the groupRect... + const CPoint offset = + Layouting::computeRectOffset (groupRect.getSize (), viewSize.getSize (), alignment); + if (style == Style::kRow) + viewSize.offset (offset.x, 0.); + else + viewSize.offset (0., offset.y); + + //...and offset by topLeft of the groupRect afterwards, in order to align with the + // 'real' parent. + return viewSize.offset (groupRect.getTopLeft ()); } //-------------------------------------------------------------------------------- private: const Alignment alignment = Alignment::kTopLeft; const Style style = Style::kRow; - CRect helperRect; + CRect groupRect; }; //-------------------------------------------------------------------------------- From ccf6abe8994020af1bd96b21314a83e05250e892 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Hansen?= Date: Sat, 13 Apr 2024 12:01:18 +0200 Subject: [PATCH 9/9] Add some documentation for AutoLayout --- vstgui/lib/crowcolumnview.cpp | 11 ++++++++++- vstgui/lib/crowcolumnview.h | 1 + 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/vstgui/lib/crowcolumnview.cpp b/vstgui/lib/crowcolumnview.cpp index 5fa4c0953..a795892f6 100644 --- a/vstgui/lib/crowcolumnview.cpp +++ b/vstgui/lib/crowcolumnview.cpp @@ -181,7 +181,15 @@ CRect computeGroupRect (const CViewContainer& parent, const Alignment alignment, } //-------------------------------------------------------------------------------- -// AutoLayout +// AutoLayout Declaration +/// @brief An auto layout feature for the CRowColumnView +/// +/// The AutoLayout flexibly layouts the children of a CRowColumnView. The children are grouped and +/// aligned among themselves depending on whether the style is a row (left to right) or a +/// column (top to bottom). The group is moved inside the parent to either of the nine +/// positions (top-left, top-center, top-right, middle-left, middle-center, middle-right, +/// bottom-left, bottom-center or bottom-right). If the size of the parent is changed, the layout +/// and alignment of the group is always retained. //-------------------------------------------------------------------------------- class AutoLayout { @@ -194,6 +202,7 @@ class AutoLayout groupRect = Layouting::computeGroupRect (parent, alignment, style, spacing); } + /** moves the child rect to the calculated position (inside the group and inside the parent) */ auto moveRect (CRect& viewSize) -> CRect& { // Offset the viewSize inside the groupRect... diff --git a/vstgui/lib/crowcolumnview.h b/vstgui/lib/crowcolumnview.h index 427f98e98..8658cb299 100644 --- a/vstgui/lib/crowcolumnview.h +++ b/vstgui/lib/crowcolumnview.h @@ -56,6 +56,7 @@ class CRowColumnView : public CAutoLayoutContainerView /** stretch subviews to the same width and height */ kStretchEqualy, + /** options for the auto layout feature */ kTopLeft, kTopCenter, kTopRight,