forked from qt-creator/qt-creator
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>
This commit is contained in:
@@ -238,7 +238,7 @@ struct Slice
|
|||||||
{
|
{
|
||||||
Slice() = default;
|
Slice() = default;
|
||||||
Slice(QLayout *l) : layout(l) {}
|
Slice(QLayout *l) : layout(l) {}
|
||||||
Slice(QWidget *w) : widget(w) {}
|
Slice(QWidget *w, bool isLayouting=false) : widget(w), isLayouting(isLayouting) {}
|
||||||
|
|
||||||
QLayout *layout = nullptr;
|
QLayout *layout = nullptr;
|
||||||
QWidget *widget = nullptr;
|
QWidget *widget = nullptr;
|
||||||
@@ -249,6 +249,7 @@ struct Slice
|
|||||||
int currentGridColumn = 0;
|
int currentGridColumn = 0;
|
||||||
int currentGridRow = 0;
|
int currentGridRow = 0;
|
||||||
bool isFormAlignment = false;
|
bool isFormAlignment = false;
|
||||||
|
bool isLayouting = false;
|
||||||
Qt::Alignment align = {}; // Can be changed to
|
Qt::Alignment align = {}; // Can be changed to
|
||||||
|
|
||||||
// Grid or Form
|
// Grid or Form
|
||||||
@@ -397,18 +398,6 @@ void Slice::flush()
|
|||||||
for (const ResultItem &item : std::as_const(pendingItems))
|
for (const ResultItem &item : std::as_const(pendingItems))
|
||||||
addItemToFlowLayout(flowLayout, item);
|
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 {
|
} else {
|
||||||
QTC_CHECK(false);
|
QTC_CHECK(false);
|
||||||
}
|
}
|
||||||
@@ -606,10 +595,30 @@ static void layoutExit(LayoutBuilder &builder)
|
|||||||
QLayout *layout = builder.stack.last().layout;
|
QLayout *layout = builder.stack.last().layout;
|
||||||
builder.stack.pop_back();
|
builder.stack.pop_back();
|
||||||
|
|
||||||
if (QWidget *widget = builder.stack.last().widget)
|
if (builder.stack.last().isLayouting) {
|
||||||
widget->setLayout(layout);
|
|
||||||
else
|
|
||||||
builder.stack.last().pendingItems.append(ResultItem(layout));
|
builder.stack.last().pendingItems.append(ResultItem(layout));
|
||||||
|
} else if (QWidget *widget = builder.stack.last().widget) {
|
||||||
|
widget->setLayout(layout);
|
||||||
|
} 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)
|
static void widgetExit(LayoutBuilder &builder)
|
||||||
@@ -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
|
// "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.
|
// top-level widget. This can lead to the focus shifting away from the main application.
|
||||||
subItems = items;
|
subItems = items;
|
||||||
onAdd = [](LayoutBuilder &builder) { builder.stack.append(new QStackedWidget); };
|
onAdd = [](LayoutBuilder &builder) {
|
||||||
onExit = [](LayoutBuilder &builder) {
|
builder.stack.append(Slice(new QStackedWidget, true));
|
||||||
QWidget *widget = builder.stack.last().widget;
|
|
||||||
builder.stack.last().flush();
|
|
||||||
builder.stack.pop_back();
|
|
||||||
builder.stack.last().pendingItems.append(ResultItem(widget));
|
|
||||||
};
|
};
|
||||||
|
onExit = layoutingWidgetExit<QStackedWidget>;
|
||||||
}
|
}
|
||||||
|
|
||||||
PushButton::PushButton(std::initializer_list<LayoutItem> items)
|
PushButton::PushButton(std::initializer_list<LayoutItem> items)
|
||||||
@@ -791,18 +797,9 @@ Splitter::Splitter(std::initializer_list<LayoutItem> items)
|
|||||||
onAdd = [](LayoutBuilder &builder) {
|
onAdd = [](LayoutBuilder &builder) {
|
||||||
auto splitter = new QSplitter;
|
auto splitter = new QSplitter;
|
||||||
splitter->setOrientation(Qt::Vertical);
|
splitter->setOrientation(Qt::Vertical);
|
||||||
builder.stack.append(splitter);
|
builder.stack.append(Slice(splitter, true));
|
||||||
};
|
|
||||||
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));
|
|
||||||
};
|
};
|
||||||
|
onExit = layoutingWidgetExit<QSplitter>;
|
||||||
}
|
}
|
||||||
|
|
||||||
ToolBar::ToolBar(std::initializer_list<LayoutItem> items)
|
ToolBar::ToolBar(std::initializer_list<LayoutItem> items)
|
||||||
@@ -811,18 +808,9 @@ ToolBar::ToolBar(std::initializer_list<LayoutItem> items)
|
|||||||
onAdd = [](LayoutBuilder &builder) {
|
onAdd = [](LayoutBuilder &builder) {
|
||||||
auto toolbar = new QToolBar;
|
auto toolbar = new QToolBar;
|
||||||
toolbar->setOrientation(Qt::Horizontal);
|
toolbar->setOrientation(Qt::Horizontal);
|
||||||
builder.stack.append(toolbar);
|
builder.stack.append(Slice(toolbar, true));
|
||||||
};
|
|
||||||
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));
|
|
||||||
};
|
};
|
||||||
|
onExit = layoutingWidgetExit<QToolBar>;
|
||||||
}
|
}
|
||||||
|
|
||||||
TabWidget::TabWidget(std::initializer_list<LayoutItem> items)
|
TabWidget::TabWidget(std::initializer_list<LayoutItem> items)
|
||||||
|
@@ -49,5 +49,12 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
}.emerge()->show();
|
}.emerge()->show();
|
||||||
|
|
||||||
|
|
||||||
|
Splitter {
|
||||||
|
windowTitle("Splitter with sub layouts"),
|
||||||
|
Column {"First Widget"},
|
||||||
|
Row {"Second Widget"},
|
||||||
|
}.emerge()->show();
|
||||||
|
|
||||||
return app.exec();
|
return app.exec();
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user