Utils: Start decoupling LayoutBuilder from Aspects

Makes it easier reusable elsewhere.

Change-Id: I86ff9f40229a33690f854f5fda692bc06d6976ef
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
This commit is contained in:
hjk
2023-04-24 16:40:01 +02:00
parent 6738616378
commit 72d72251d8
6 changed files with 121 additions and 115 deletions

View File

@@ -421,10 +421,17 @@ QAction *BaseAspect::action()
Adds the visual representation of this aspect to a layout using Adds the visual representation of this aspect to a layout using
a layout builder. a layout builder.
*/ */
void BaseAspect::addToLayout(Layouting::LayoutBuilder &) void BaseAspect::addToLayout(LayoutBuilder &)
{ {
} }
void doLayout(const BaseAspect &aspect, LayoutBuilder &builder)
{
const_cast<BaseAspect &>(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. Updates this aspect's value from user-initiated changes in the widget.

View File

@@ -25,7 +25,11 @@ namespace Utils {
class AspectContainer; class AspectContainer;
class BoolAspect; class BoolAspect;
namespace Layouting { class LayoutBuilder; }
namespace Layouting {
class LayoutBuilder;
class LayoutItem;
} // Layouting
namespace Internal { namespace Internal {
class AspectContainerPrivate; class AspectContainerPrivate;
@@ -206,6 +210,8 @@ private:
std::unique_ptr<Internal::BaseAspectPrivate> d; std::unique_ptr<Internal::BaseAspectPrivate> d;
}; };
QTCREATOR_UTILS_EXPORT void doLayout(const BaseAspect &aspect, Layouting::LayoutBuilder &builder);
class QTCREATOR_UTILS_EXPORT BoolAspect : public BaseAspect class QTCREATOR_UTILS_EXPORT BoolAspect : public BaseAspect
{ {
Q_OBJECT Q_OBJECT

View File

@@ -9,12 +9,12 @@
#include <QFormLayout> #include <QFormLayout>
#include <QGridLayout> #include <QGridLayout>
#include <QGroupBox> #include <QGroupBox>
#include <QLabel>
#include <QPushButton> #include <QPushButton>
#include <QStackedLayout> #include <QStackedLayout>
#include <QSplitter> #include <QSplitter>
#include <QStyle> #include <QStyle>
#include <QTabWidget> #include <QTabWidget>
#include <QWidget>
namespace Utils::Layouting { namespace Utils::Layouting {
@@ -51,42 +51,23 @@ LayoutItem::LayoutItem()
/*! /*!
Constructs a layout item proxy for \a layout. \fn template <class T> 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 *LayoutBuilder::createLayout() const
{ {
QLayout *layout = nullptr; QLayout *layout = nullptr;
@@ -276,7 +257,7 @@ static void doLayoutHelper(QLayout *layout,
/*! /*!
Constructs a layout item from the contents of another LayoutBuilder Constructs a layout item from the contents of another LayoutBuilder
*/ */
LayoutItem::LayoutItem(const LayoutBuilder &builder) void LayoutItem::setBuilder(const LayoutBuilder &builder)
{ {
layout = builder.createLayout(); layout = builder.createLayout();
doLayoutHelper(layout, builder.m_items, Layouting::WithoutMargins); doLayoutHelper(layout, builder.m_items, Layouting::WithoutMargins);
@@ -357,10 +338,8 @@ LayoutBuilder &LayoutBuilder::addRow(const LayoutItems &items)
*/ */
LayoutBuilder &LayoutBuilder::addItem(const LayoutItem &item) LayoutBuilder &LayoutBuilder::addItem(const LayoutItem &item)
{ {
if (item.aspect) { if (item.onAdd) {
item.aspect->addToLayout(*this); item.onAdd(*this);
if (m_layoutType == FormLayout || m_layoutType == VBoxLayout)
finishRow();
} else { } else {
m_items.push_back(item); m_items.push_back(item);
} }
@@ -427,29 +406,6 @@ LayoutExtender::~LayoutExtender()
// Special items // 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) Tab::Tab(const QString &tabName, const LayoutBuilder &item)
{ {
text = tabName; text = tabName;
@@ -457,11 +413,6 @@ Tab::Tab(const QString &tabName, const LayoutBuilder &item)
item.attachTo(widget); item.attachTo(widget);
} }
HorizontalRule::HorizontalRule()
{
specialType = SpecialType::HorizontalRule;
}
// "Widgets" // "Widgets"
static void applyItems(QWidget *widget, const QList<LayoutItem> &items) static void applyItems(QWidget *widget, const QList<LayoutItem> &items)

View File

@@ -18,10 +18,7 @@ class QTabWidget;
class QWidget; class QWidget;
QT_END_NAMESPACE QT_END_NAMESPACE
namespace Utils { namespace Utils { class BoolAspect; }
class BaseAspect;
class BoolAspect;
} // Utils
namespace Utils::Layouting { namespace Utils::Layouting {
@@ -32,6 +29,43 @@ enum AttachType {
}; };
class LayoutBuilder; 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 // LayoutItem
@@ -52,18 +86,49 @@ public:
}; };
using Setter = std::function<void(QObject *target)>; using Setter = std::function<void(QObject *target)>;
using OnAdder = std::function<void(LayoutBuilder &)>;
LayoutItem(); LayoutItem();
LayoutItem(QLayout *layout);
LayoutItem(QWidget *widget); template <class T> LayoutItem(const T &t)
LayoutItem(BaseAspect *aspect); // Remove {
LayoutItem(BaseAspect &aspect); if constexpr (std::is_same_v<QString, T>) {
LayoutItem(const QString &text); text = t;
LayoutItem(const LayoutBuilder &builder); } else if constexpr (std::is_same_v<Space, T>) {
LayoutItem(const Setter &setter) { this->setter = setter; } specialType = LayoutItem::SpecialType::Space;
specialValue = t.space;
} else if constexpr (std::is_same_v<Stretch, T>) {
specialType = LayoutItem::SpecialType::Stretch;
specialValue = t.stretch;
} else if constexpr (std::is_same_v<Break, T>) {
specialType = LayoutItem::SpecialType::Break;
} else if constexpr (std::is_same_v<Span, T>) {
LayoutItem::operator=(t.item);
span = t.span;
} else if constexpr (std::is_same_v<HorizontalRule, T>) {
specialType = SpecialType::HorizontalRule;
} else if constexpr (std::is_base_of_v<LayoutBuilder, T>) {
setBuilder(t);
} else if constexpr (std::is_base_of_v<LayoutItem, T>) {
LayoutItem::operator=(t);
} else if constexpr (std::is_base_of_v<Setter, T>) {
setter = t;
} else if constexpr (std::is_base_of_v<QLayout, std::remove_pointer_t<T>>) {
layout = t;
} else if constexpr (std::is_base_of_v<QWidget, std::remove_pointer_t<T>>) {
widget = t;
} else if constexpr (std::is_pointer_v<T>) {
onAdd = [t](LayoutBuilder &builder) { doLayout(*t, builder); };
} else {
onAdd = [&t](LayoutBuilder &builder) { doLayout(t, builder); };
}
}
void setBuilder(const LayoutBuilder &builder);
QLayout *layout = nullptr; QLayout *layout = nullptr;
QWidget *widget = nullptr; QWidget *widget = nullptr;
BaseAspect *aspect = nullptr; OnAdder onAdd;
QString text; // FIXME: Use specialValue for that QString text; // FIXME: Use specialValue for that
int span = 1; int span = 1;
@@ -73,42 +138,12 @@ public:
QVariant specialValue; 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 class QTCREATOR_UTILS_EXPORT Tab : public LayoutItem
{ {
public: public:
Tab(const QString &tabName, const LayoutBuilder &item); 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 class QTCREATOR_UTILS_EXPORT Group : public LayoutItem
{ {
public: public:

View File

@@ -184,7 +184,11 @@ Tasking::WorkflowPolicy GroupWidget::workflowPolicy() const
return m_workflowPolicy; return m_workflowPolicy;
} }
TaskGroup::TaskGroup(QWidget *group, std::initializer_list<LayoutItem> items)
: Row({ group, Group { Column { items } } }) void doLayout(const TaskGroup &taskGroup, LayoutBuilder &builder)
{} {
builder.addItem(taskGroup.group);
builder.addItem(Group { taskGroup.items });
builder.finishRow();
}

View File

@@ -76,8 +76,11 @@ private:
Utils::Tasking::WorkflowPolicy m_workflowPolicy = Utils::Tasking::WorkflowPolicy::StopOnError; Utils::Tasking::WorkflowPolicy m_workflowPolicy = Utils::Tasking::WorkflowPolicy::StopOnError;
}; };
class TaskGroup : public Utils::Layouting::Row class TaskGroup
{ {
public: public:
TaskGroup(QWidget *group, std::initializer_list<Utils::Layouting::LayoutItem> items); QWidget *group;
Utils::Layouting::Column items;
}; };
void doLayout(const TaskGroup &taskGroup, Utils::Layouting::LayoutBuilder &builder);