diff options
author | Marcus Tillmanns <marcus.tillmanns@qt.io> | 2023-10-12 10:39:25 +0200 |
---|---|---|
committer | Marcus Tillmanns <marcus.tillmanns@qt.io> | 2023-10-12 10:32:56 +0000 |
commit | 413fda678fc3c13b00f5f26c3867a62160f5abad (patch) | |
tree | cfdadb05ba567c2ae96df2b4c674cde332c945e8 | |
parent | db8d82e51e03a8e8675b7f9c29dada636c478078 (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.cpp | 74 | ||||
-rw-r--r-- | tests/manual/widgets/layoutbuilder/tst_manual_widgets_layoutbuilder.cpp | 7 |
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(); } |