aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarcus Tillmanns <marcus.tillmanns@qt.io>2023-10-12 10:39:25 +0200
committerMarcus Tillmanns <marcus.tillmanns@qt.io>2023-10-12 10:32:56 +0000
commit413fda678fc3c13b00f5f26c3867a62160f5abad (patch)
treecfdadb05ba567c2ae96df2b4c674cde332c945e8
parentdb8d82e51e03a8e8675b7f9c29dada636c478078 (diff)
Utils: Add "layouting" widgets to layoutbuilder
This allows us to handle widgets that have an "addWidget" function. Change-Id: Id1b63bae7032403fdd3c5e6ba60283cf56cc1cfe Reviewed-by: hjk <hjk@qt.io>
-rw-r--r--src/libs/utils/layoutbuilder.cpp74
-rw-r--r--tests/manual/widgets/layoutbuilder/tst_manual_widgets_layoutbuilder.cpp7
2 files changed, 38 insertions, 43 deletions
diff --git a/src/libs/utils/layoutbuilder.cpp b/src/libs/utils/layoutbuilder.cpp
index 23def250e2..31c67e4d0f 100644
--- a/src/libs/utils/layoutbuilder.cpp
+++ b/src/libs/utils/layoutbuilder.cpp
@@ -238,7 +238,7 @@ struct Slice
{
Slice() = default;
Slice(QLayout *l) : layout(l) {}
- Slice(QWidget *w) : widget(w) {}
+ Slice(QWidget *w, bool isLayouting=false) : widget(w), isLayouting(isLayouting) {}
QLayout *layout = nullptr;
QWidget *widget = nullptr;
@@ -249,6 +249,7 @@ struct Slice
int currentGridColumn = 0;
int currentGridRow = 0;
bool isFormAlignment = false;
+ bool isLayouting = false;
Qt::Alignment align = {}; // Can be changed to
// Grid or Form
@@ -397,18 +398,6 @@ void Slice::flush()
for (const ResultItem &item : std::as_const(pendingItems))
addItemToFlowLayout(flowLayout, item);
- } else if (auto stackWidget = qobject_cast<QStackedWidget *>(widget)) {
- for (const ResultItem &item : std::as_const(pendingItems)) {
- if (item.widget)
- stackWidget->addWidget(item.widget);
- else if (item.layout) {
- auto w = new QWidget();
- w->setLayout(item.layout);
- stackWidget->addWidget(w);
- } else {
- QTC_CHECK(false);
- }
- }
} else {
QTC_CHECK(false);
}
@@ -606,12 +595,32 @@ static void layoutExit(LayoutBuilder &builder)
QLayout *layout = builder.stack.last().layout;
builder.stack.pop_back();
- if (QWidget *widget = builder.stack.last().widget)
+ if (builder.stack.last().isLayouting) {
+ builder.stack.last().pendingItems.append(ResultItem(layout));
+ } else if (QWidget *widget = builder.stack.last().widget) {
widget->setLayout(layout);
- else
+ } else
builder.stack.last().pendingItems.append(ResultItem(layout));
}
+template<class T>
+static void layoutingWidgetExit(LayoutBuilder &builder)
+{
+ const Slice slice = builder.stack.last();
+ T *w = qobject_cast<T *>(slice.widget);
+ for (const ResultItem &ri : slice.pendingItems) {
+ if (ri.widget) {
+ w->addWidget(ri.widget);
+ } else if (ri.layout) {
+ auto child = new QWidget;
+ child->setLayout(ri.layout);
+ w->addWidget(child);
+ }
+ }
+ builder.stack.pop_back();
+ builder.stack.last().pendingItems.append(ResultItem(w));
+}
+
static void widgetExit(LayoutBuilder &builder)
{
QWidget *widget = builder.stack.last().widget;
@@ -758,13 +767,10 @@ Stack::Stack(std::initializer_list<LayoutItem> items)
// "setVisible()" when a child is added, which can lead to the widget being spawned as a
// top-level widget. This can lead to the focus shifting away from the main application.
subItems = items;
- onAdd = [](LayoutBuilder &builder) { builder.stack.append(new QStackedWidget); };
- onExit = [](LayoutBuilder &builder) {
- QWidget *widget = builder.stack.last().widget;
- builder.stack.last().flush();
- builder.stack.pop_back();
- builder.stack.last().pendingItems.append(ResultItem(widget));
+ onAdd = [](LayoutBuilder &builder) {
+ builder.stack.append(Slice(new QStackedWidget, true));
};
+ onExit = layoutingWidgetExit<QStackedWidget>;
}
PushButton::PushButton(std::initializer_list<LayoutItem> items)
@@ -791,18 +797,9 @@ Splitter::Splitter(std::initializer_list<LayoutItem> items)
onAdd = [](LayoutBuilder &builder) {
auto splitter = new QSplitter;
splitter->setOrientation(Qt::Vertical);
- builder.stack.append(splitter);
- };
- onExit = [](LayoutBuilder &builder) {
- const Slice slice = builder.stack.last();
- QSplitter *splitter = qobject_cast<QSplitter *>(slice.widget);
- for (const ResultItem &ri : slice.pendingItems) {
- if (ri.widget)
- splitter->addWidget(ri.widget);
- }
- builder.stack.pop_back();
- builder.stack.last().pendingItems.append(ResultItem(splitter));
+ builder.stack.append(Slice(splitter, true));
};
+ onExit = layoutingWidgetExit<QSplitter>;
}
ToolBar::ToolBar(std::initializer_list<LayoutItem> items)
@@ -811,18 +808,9 @@ ToolBar::ToolBar(std::initializer_list<LayoutItem> items)
onAdd = [](LayoutBuilder &builder) {
auto toolbar = new QToolBar;
toolbar->setOrientation(Qt::Horizontal);
- builder.stack.append(toolbar);
- };
- onExit = [](LayoutBuilder &builder) {
- const Slice slice = builder.stack.last();
- QToolBar *toolBar = qobject_cast<QToolBar *>(slice.widget);
- for (const ResultItem &ri : slice.pendingItems) {
- if (ri.widget)
- toolBar->addWidget(ri.widget);
- }
- builder.stack.pop_back();
- builder.stack.last().pendingItems.append(ResultItem(toolBar));
+ builder.stack.append(Slice(toolbar, true));
};
+ onExit = layoutingWidgetExit<QToolBar>;
}
TabWidget::TabWidget(std::initializer_list<LayoutItem> items)
diff --git a/tests/manual/widgets/layoutbuilder/tst_manual_widgets_layoutbuilder.cpp b/tests/manual/widgets/layoutbuilder/tst_manual_widgets_layoutbuilder.cpp
index 26ffe7f80f..343c500c28 100644
--- a/tests/manual/widgets/layoutbuilder/tst_manual_widgets_layoutbuilder.cpp
+++ b/tests/manual/widgets/layoutbuilder/tst_manual_widgets_layoutbuilder.cpp
@@ -49,5 +49,12 @@ int main(int argc, char *argv[])
}
}.emerge()->show();
+
+ Splitter {
+ windowTitle("Splitter with sub layouts"),
+ Column {"First Widget"},
+ Row {"Second Widget"},
+ }.emerge()->show();
+
return app.exec();
}