From 72d72251d84c0393eef8a30dab7839a66009dd1a Mon Sep 17 00:00:00 2001 From: hjk Date: Mon, 24 Apr 2023 16:40:01 +0200 Subject: [PATCH] Utils: Start decoupling LayoutBuilder from Aspects Makes it easier reusable elsewhere. Change-Id: I86ff9f40229a33690f854f5fda692bc06d6976ef Reviewed-by: Eike Ziller --- src/libs/utils/aspects.cpp | 9 +- src/libs/utils/aspects.h | 8 +- src/libs/utils/layoutbuilder.cpp | 83 ++++--------------- src/libs/utils/layoutbuilder.h | 119 +++++++++++++++++---------- tests/manual/tasktree/taskwidget.cpp | 10 ++- tests/manual/tasktree/taskwidget.h | 7 +- 6 files changed, 121 insertions(+), 115 deletions(-) diff --git a/src/libs/utils/aspects.cpp b/src/libs/utils/aspects.cpp index aed8c851d17..28de4dd4cab 100644 --- a/src/libs/utils/aspects.cpp +++ b/src/libs/utils/aspects.cpp @@ -421,10 +421,17 @@ QAction *BaseAspect::action() Adds the visual representation of this aspect to a layout using a layout builder. */ -void BaseAspect::addToLayout(Layouting::LayoutBuilder &) +void BaseAspect::addToLayout(LayoutBuilder &) { } +void doLayout(const BaseAspect &aspect, LayoutBuilder &builder) +{ + const_cast(aspect).addToLayout(builder); + if (builder.layoutType() == LayoutBuilder::FormLayout || builder.layoutType() == LayoutBuilder::VBoxLayout) + builder.finishRow(); +} + /*! Updates this aspect's value from user-initiated changes in the widget. diff --git a/src/libs/utils/aspects.h b/src/libs/utils/aspects.h index 0b9a5606596..1e58c737736 100644 --- a/src/libs/utils/aspects.h +++ b/src/libs/utils/aspects.h @@ -25,7 +25,11 @@ namespace Utils { class AspectContainer; class BoolAspect; -namespace Layouting { class LayoutBuilder; } + +namespace Layouting { +class LayoutBuilder; +class LayoutItem; +} // Layouting namespace Internal { class AspectContainerPrivate; @@ -206,6 +210,8 @@ private: std::unique_ptr d; }; +QTCREATOR_UTILS_EXPORT void doLayout(const BaseAspect &aspect, Layouting::LayoutBuilder &builder); + class QTCREATOR_UTILS_EXPORT BoolAspect : public BaseAspect { Q_OBJECT diff --git a/src/libs/utils/layoutbuilder.cpp b/src/libs/utils/layoutbuilder.cpp index f4b1dda3ee6..99b726ec4ce 100644 --- a/src/libs/utils/layoutbuilder.cpp +++ b/src/libs/utils/layoutbuilder.cpp @@ -9,12 +9,12 @@ #include #include #include +#include #include #include #include #include #include -#include namespace Utils::Layouting { @@ -51,42 +51,23 @@ LayoutItem::LayoutItem() /*! - Constructs a layout item proxy for \a layout. + \fn template LayoutItem(const T &t) + + Constructs a layout item proxy for \a t. + + T could be + \list + \li \c {QString} + \li \c {QWidget *} + \li \c {QLayout *} + \endlist */ -LayoutItem::LayoutItem(QLayout *layout) - : layout(layout) -{} + /*! - Constructs a layout item proxy for \a widget. + Constructs a layout item representing something that knows how to add it + to a layout by itself. */ -LayoutItem::LayoutItem(QWidget *widget) - : widget(widget) -{} - -/*! - Constructs a layout item representing a \c BaseAspect. - - This ultimately uses the \a aspect's \c addToLayout(LayoutBuilder &) function, - which in turn can add one or more layout items to the target layout. - - \sa BaseAspect::addToLayout() - */ -LayoutItem::LayoutItem(BaseAspect &aspect) - : aspect(&aspect) -{} - -LayoutItem::LayoutItem(BaseAspect *aspect) - : aspect(aspect) -{} - -/*! - Constructs a layout item containing some static \a text. - */ -LayoutItem::LayoutItem(const QString &text) - : text(text) -{} - QLayout *LayoutBuilder::createLayout() const { QLayout *layout = nullptr; @@ -276,7 +257,7 @@ static void doLayoutHelper(QLayout *layout, /*! Constructs a layout item from the contents of another LayoutBuilder */ -LayoutItem::LayoutItem(const LayoutBuilder &builder) +void LayoutItem::setBuilder(const LayoutBuilder &builder) { layout = builder.createLayout(); doLayoutHelper(layout, builder.m_items, Layouting::WithoutMargins); @@ -357,10 +338,8 @@ LayoutBuilder &LayoutBuilder::addRow(const LayoutItems &items) */ LayoutBuilder &LayoutBuilder::addItem(const LayoutItem &item) { - if (item.aspect) { - item.aspect->addToLayout(*this); - if (m_layoutType == FormLayout || m_layoutType == VBoxLayout) - finishRow(); + if (item.onAdd) { + item.onAdd(*this); } else { m_items.push_back(item); } @@ -427,29 +406,6 @@ LayoutExtender::~LayoutExtender() // Special items -Break::Break() -{ - specialType = SpecialType::Break; -} - -Stretch::Stretch(int stretch) -{ - specialType = SpecialType::Stretch; - specialValue = stretch; -} - -Space::Space(int space) -{ - specialType = SpecialType::Space; - specialValue = space; -} - -Span::Span(int span_, const LayoutItem &item) -{ - LayoutItem::operator=(item); - span = span_; -} - Tab::Tab(const QString &tabName, const LayoutBuilder &item) { text = tabName; @@ -457,11 +413,6 @@ Tab::Tab(const QString &tabName, const LayoutBuilder &item) item.attachTo(widget); } -HorizontalRule::HorizontalRule() -{ - specialType = SpecialType::HorizontalRule; -} - // "Widgets" static void applyItems(QWidget *widget, const QList &items) diff --git a/src/libs/utils/layoutbuilder.h b/src/libs/utils/layoutbuilder.h index b32668e22d3..76106ffc76d 100644 --- a/src/libs/utils/layoutbuilder.h +++ b/src/libs/utils/layoutbuilder.h @@ -18,10 +18,7 @@ class QTabWidget; class QWidget; QT_END_NAMESPACE -namespace Utils { -class BaseAspect; -class BoolAspect; -} // Utils +namespace Utils { class BoolAspect; } namespace Utils::Layouting { @@ -32,6 +29,43 @@ enum AttachType { }; class LayoutBuilder; +class LayoutItem; + +// Special items + +class QTCREATOR_UTILS_EXPORT Space +{ +public: + explicit Space(int space) : space(space) {} + const int space; +}; + +class QTCREATOR_UTILS_EXPORT Stretch +{ +public: + explicit Stretch(int stretch = 1) : stretch(stretch) {} + const int stretch; +}; + +class QTCREATOR_UTILS_EXPORT Break +{ +public: + Break() {} +}; + +class QTCREATOR_UTILS_EXPORT Span +{ +public: + Span(int span, const LayoutItem &item) : span(span), item(item) {} + const int span; + const LayoutItem &item; +}; + +class QTCREATOR_UTILS_EXPORT HorizontalRule +{ +public: + HorizontalRule() {} +}; // LayoutItem @@ -52,18 +86,49 @@ public: }; using Setter = std::function; + using OnAdder = std::function; + LayoutItem(); - LayoutItem(QLayout *layout); - LayoutItem(QWidget *widget); - LayoutItem(BaseAspect *aspect); // Remove - LayoutItem(BaseAspect &aspect); - LayoutItem(const QString &text); - LayoutItem(const LayoutBuilder &builder); - LayoutItem(const Setter &setter) { this->setter = setter; } + + template LayoutItem(const T &t) + { + if constexpr (std::is_same_v) { + text = t; + } else if constexpr (std::is_same_v) { + specialType = LayoutItem::SpecialType::Space; + specialValue = t.space; + } else if constexpr (std::is_same_v) { + specialType = LayoutItem::SpecialType::Stretch; + specialValue = t.stretch; + } else if constexpr (std::is_same_v) { + specialType = LayoutItem::SpecialType::Break; + } else if constexpr (std::is_same_v) { + LayoutItem::operator=(t.item); + span = t.span; + } else if constexpr (std::is_same_v) { + specialType = SpecialType::HorizontalRule; + } else if constexpr (std::is_base_of_v) { + setBuilder(t); + } else if constexpr (std::is_base_of_v) { + LayoutItem::operator=(t); + } else if constexpr (std::is_base_of_v) { + setter = t; + } else if constexpr (std::is_base_of_v>) { + layout = t; + } else if constexpr (std::is_base_of_v>) { + widget = t; + } else if constexpr (std::is_pointer_v) { + onAdd = [t](LayoutBuilder &builder) { doLayout(*t, builder); }; + } else { + onAdd = [&t](LayoutBuilder &builder) { doLayout(t, builder); }; + } + } + + void setBuilder(const LayoutBuilder &builder); QLayout *layout = nullptr; QWidget *widget = nullptr; - BaseAspect *aspect = nullptr; + OnAdder onAdd; QString text; // FIXME: Use specialValue for that int span = 1; @@ -73,42 +138,12 @@ public: QVariant specialValue; }; -class QTCREATOR_UTILS_EXPORT Space : public LayoutItem -{ -public: - explicit Space(int space); -}; - -class QTCREATOR_UTILS_EXPORT Span : public LayoutItem -{ -public: - Span(int span, const LayoutItem &item); -}; - -class QTCREATOR_UTILS_EXPORT Stretch : public LayoutItem -{ -public: - explicit Stretch(int stretch = 1); -}; - class QTCREATOR_UTILS_EXPORT Tab : public LayoutItem { public: Tab(const QString &tabName, const LayoutBuilder &item); }; -class QTCREATOR_UTILS_EXPORT Break : public LayoutItem -{ -public: - Break(); -}; - -class QTCREATOR_UTILS_EXPORT HorizontalRule : public LayoutItem -{ -public: - HorizontalRule(); -}; - class QTCREATOR_UTILS_EXPORT Group : public LayoutItem { public: diff --git a/tests/manual/tasktree/taskwidget.cpp b/tests/manual/tasktree/taskwidget.cpp index cca5394bbba..d5420defe59 100644 --- a/tests/manual/tasktree/taskwidget.cpp +++ b/tests/manual/tasktree/taskwidget.cpp @@ -184,7 +184,11 @@ Tasking::WorkflowPolicy GroupWidget::workflowPolicy() const return m_workflowPolicy; } -TaskGroup::TaskGroup(QWidget *group, std::initializer_list items) - : Row({ group, Group { Column { items } } }) -{} + +void doLayout(const TaskGroup &taskGroup, LayoutBuilder &builder) +{ + builder.addItem(taskGroup.group); + builder.addItem(Group { taskGroup.items }); + builder.finishRow(); +} diff --git a/tests/manual/tasktree/taskwidget.h b/tests/manual/tasktree/taskwidget.h index 1f867dfeaec..8dbaded738a 100644 --- a/tests/manual/tasktree/taskwidget.h +++ b/tests/manual/tasktree/taskwidget.h @@ -76,8 +76,11 @@ private: Utils::Tasking::WorkflowPolicy m_workflowPolicy = Utils::Tasking::WorkflowPolicy::StopOnError; }; -class TaskGroup : public Utils::Layouting::Row +class TaskGroup { public: - TaskGroup(QWidget *group, std::initializer_list items); + QWidget *group; + Utils::Layouting::Column items; }; + +void doLayout(const TaskGroup &taskGroup, Utils::Layouting::LayoutBuilder &builder);