Layouting: Introduce a 'bindTo' LayoutItem

... to 'export' the widget being operated on.

The 'Tab' related changes are related, as they affect the order
of execution.

Change-Id: I7aa079f12e49a1dab7c6a49acfae9dc684cfb479
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Alessandro Portale <alessandro.portale@qt.io>
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
This commit is contained in:
hjk
2023-04-25 17:21:39 +02:00
parent c192536b64
commit 1c2b29b31a
4 changed files with 72 additions and 53 deletions

View File

@@ -418,16 +418,22 @@ Tab::Tab(const QString &tabName, const LayoutBuilder &item)
text = tabName; text = tabName;
widget = new QWidget; widget = new QWidget;
item.attachTo(widget); item.attachTo(widget);
specialType = LayoutItem::SpecialType::Tab;
} }
// "Widgets" // "Widgets"
static void applyItems(QWidget *widget, const QList<LayoutItem> &items) static void applyItems(LayoutItem *owner, QWidget *widget, const QList<LayoutItem> &items)
{ {
owner->widget = widget;
bool hadLayout = false; bool hadLayout = false;
for (const LayoutItem &item : items) { for (const LayoutItem &item : items) {
if (item.setter) { if (item.setter) {
item.setter(widget); item.setter(widget);
} else if (item.specialType == LayoutItem::SpecialType::Tab) {
auto tabWidget = qobject_cast<QTabWidget *>(widget);
QTC_ASSERT(tabWidget, continue);
tabWidget->addTab(item.widget, item.text);
} else if (item.layout && !hadLayout) { } else if (item.layout && !hadLayout) {
hadLayout = true; hadLayout = true;
widget->setLayout(item.layout); widget->setLayout(item.layout);
@@ -439,70 +445,65 @@ static void applyItems(QWidget *widget, const QList<LayoutItem> &items)
Group::Group(std::initializer_list<LayoutItem> items) Group::Group(std::initializer_list<LayoutItem> items)
{ {
widget = new QGroupBox; applyItems(this, new QGroupBox, items);
applyItems(widget, items);
} }
PushButton::PushButton(std::initializer_list<LayoutItem> items) PushButton::PushButton(std::initializer_list<LayoutItem> items)
{ {
widget = new QPushButton; applyItems(this, new QPushButton, items);
applyItems(widget, items);
} }
TextEdit::TextEdit(std::initializer_list<LayoutItem> items) TextEdit::TextEdit(std::initializer_list<LayoutItem> items)
{ {
widget = new QTextEdit; applyItems(this, new QTextEdit, items);
applyItems(widget, items);
} }
Splitter::Splitter(std::initializer_list<LayoutItem> items) Splitter::Splitter(std::initializer_list<LayoutItem> items)
: Splitter(new QSplitter(Qt::Vertical), items) {}
Splitter::Splitter(QSplitter *splitter, std::initializer_list<LayoutItem> items)
{ {
widget = splitter; applyItems(this, new QSplitter(Qt::Vertical), items);
for (const LayoutItem &item : items) }
splitter->addWidget(item.widget);
}
TabWidget::TabWidget(std::initializer_list<Tab> tabs)
: TabWidget(new QTabWidget, tabs) {}
TabWidget::TabWidget(QTabWidget *tabWidget, std::initializer_list<Tab> tabs) TabWidget::TabWidget(std::initializer_list<LayoutItem> items)
{ {
widget = tabWidget; applyItems(this, new QTabWidget, items);
for (const Tab &tab : tabs)
tabWidget->addTab(tab.widget, tab.text);
} }
// "Properties" // "Properties"
LayoutItem::Setter title(const QString &title) static LayoutItem setter(const LayoutItem::Setter &setter)
{ {
return [title](QObject *target) { LayoutItem item;
item.setter = setter;
return item;
}
LayoutItem title(const QString &title)
{
return setter([title](QObject *target) {
if (auto groupBox = qobject_cast<QGroupBox *>(target)) { if (auto groupBox = qobject_cast<QGroupBox *>(target)) {
groupBox->setTitle(title); groupBox->setTitle(title);
groupBox->setObjectName(title); groupBox->setObjectName(title);
} else { } else {
QTC_CHECK(false); QTC_CHECK(false);
} }
}; });
} }
LayoutItem::Setter onClicked(const std::function<void ()> &func, QObject *guard) LayoutItem onClicked(const std::function<void ()> &func, QObject *guard)
{ {
return [func, guard](QObject *target) { return setter([func, guard](QObject *target) {
if (auto button = qobject_cast<QAbstractButton *>(target)) { if (auto button = qobject_cast<QAbstractButton *>(target)) {
QObject::connect(button, &QAbstractButton::clicked, guard ? guard : target, func); QObject::connect(button, &QAbstractButton::clicked, guard ? guard : target, func);
} else { } else {
QTC_CHECK(false); QTC_CHECK(false);
} }
}; });
} }
LayoutItem::Setter text(const QString &text) LayoutItem text(const QString &text)
{ {
return [text](QObject *target) { return setter([text](QObject *target) {
if (auto button = qobject_cast<QAbstractButton *>(target)) { if (auto button = qobject_cast<QAbstractButton *>(target)) {
button->setText(text); button->setText(text);
} else if (auto textEdit = qobject_cast<QTextEdit *>(target)) { } else if (auto textEdit = qobject_cast<QTextEdit *>(target)) {
@@ -510,18 +511,32 @@ LayoutItem::Setter text(const QString &text)
} else { } else {
QTC_CHECK(false); QTC_CHECK(false);
} }
}; });
} }
LayoutItem::Setter tooltip(const QString &toolTip) LayoutItem tooltip(const QString &toolTip)
{ {
return [toolTip](QObject *target) { return setter([toolTip](QObject *target) {
if (auto widget = qobject_cast<QWidget *>(target)) { if (auto widget = qobject_cast<QWidget *>(target)) {
widget->setToolTip(toolTip); widget->setToolTip(toolTip);
} else { } else {
QTC_CHECK(false); QTC_CHECK(false);
} }
}; });
}
LayoutItem bindTo(QSplitter **out)
{
return setter([out](QObject *target) {
*out = qobject_cast<QSplitter *>(target);
});
}
LayoutItem bindTo(QTabWidget **out)
{
return setter([out](QObject *target) {
*out = qobject_cast<QTabWidget *>(target);
});
} }
QWidget *createHr(QWidget *parent) QWidget *createHr(QWidget *parent)

View File

@@ -87,6 +87,7 @@ public:
Stretch, Stretch,
Break, Break,
HorizontalRule, HorizontalRule,
Tab,
}; };
using Setter = std::function<void(QObject *target)>; using Setter = std::function<void(QObject *target)>;
@@ -170,14 +171,12 @@ class QTCREATOR_UTILS_EXPORT Splitter : public LayoutItem
{ {
public: public:
Splitter(std::initializer_list<LayoutItem> items); Splitter(std::initializer_list<LayoutItem> items);
Splitter(QSplitter *splitter, std::initializer_list<LayoutItem> items);
}; };
class QTCREATOR_UTILS_EXPORT TabWidget : public LayoutItem class QTCREATOR_UTILS_EXPORT TabWidget : public LayoutItem
{ {
public: public:
TabWidget(std::initializer_list<Tab> tabs); TabWidget(std::initializer_list<LayoutItem> items);
TabWidget(QTabWidget *tabWidget, std::initializer_list<Tab> tabs);
}; };
// Singleton items. // Singleton items.
@@ -189,10 +188,13 @@ QTCREATOR_UTILS_EXPORT extern HorizontalRule hr;
// "Properties" // "Properties"
QTCREATOR_UTILS_EXPORT LayoutItem::Setter title(const QString &title); QTCREATOR_UTILS_EXPORT LayoutItem bindTo(QTabWidget **);
QTCREATOR_UTILS_EXPORT LayoutItem::Setter text(const QString &text); QTCREATOR_UTILS_EXPORT LayoutItem bindTo(QSplitter **);
QTCREATOR_UTILS_EXPORT LayoutItem::Setter tooltip(const QString &toolTip);
QTCREATOR_UTILS_EXPORT LayoutItem::Setter onClicked(const std::function<void()> &func, QTCREATOR_UTILS_EXPORT LayoutItem title(const QString &title);
QTCREATOR_UTILS_EXPORT LayoutItem text(const QString &text);
QTCREATOR_UTILS_EXPORT LayoutItem tooltip(const QString &toolTip);
QTCREATOR_UTILS_EXPORT LayoutItem onClicked(const std::function<void()> &func,
QObject *guard = nullptr); QObject *guard = nullptr);

View File

@@ -1429,7 +1429,9 @@ CppCodeModelInspectorDialog::CppCodeModelInspectorDialog(QWidget *parent)
m_workingCopyView->setModel(m_proxyWorkingCopyModel); m_workingCopyView->setModel(m_proxyWorkingCopyModel);
using namespace Layouting; using namespace Layouting;
m_projectPartTab = qobject_cast<QTabWidget*>(TabWidget{
TabWidget projectPart {
bindTo(&m_projectPartTab),
Tab("&General", Tab("&General",
Row { Row {
m_partGeneralView, m_partGeneralView,
@@ -1454,10 +1456,10 @@ CppCodeModelInspectorDialog::CppCodeModelInspectorDialog(QWidget *parent)
), ),
Tab("&Header Paths", Column{ projectHeaderPathsView }), Tab("&Header Paths", Column{ projectHeaderPathsView }),
Tab("Pre&compiled Headers", Column{ m_partPrecompiledHeadersEdit }), Tab("Pre&compiled Headers", Column{ m_partPrecompiledHeadersEdit }),
}.widget); };
QTC_CHECK(m_projectPartTab);
m_docTab = qobject_cast<QTabWidget*>(TabWidget{ TabWidget docTab {
bindTo(&m_docTab),
Tab("&General", Column { m_docGeneralView }), Tab("&General", Column { m_docGeneralView }),
Tab("&Includes", Column { m_docIncludesView }), Tab("&Includes", Column { m_docIncludesView }),
Tab("&Diagnostic Messages", Column { m_docDiagnosticMessagesView }), Tab("&Diagnostic Messages", Column { m_docDiagnosticMessagesView }),
@@ -1465,8 +1467,7 @@ CppCodeModelInspectorDialog::CppCodeModelInspectorDialog(QWidget *parent)
Tab("P&reprocessed Source", Column { m_docPreprocessedSourceEdit }), Tab("P&reprocessed Source", Column { m_docPreprocessedSourceEdit }),
Tab("&Symbols", Column { m_docSymbolsView }), Tab("&Symbols", Column { m_docSymbolsView }),
Tab("&Tokens", Column { m_docTokensView }), Tab("&Tokens", Column { m_docTokensView }),
}.widget); };
QTC_CHECK(m_docTab);
Column { Column {
TabWidget { TabWidget {
@@ -1474,7 +1475,7 @@ CppCodeModelInspectorDialog::CppCodeModelInspectorDialog(QWidget *parent)
Column { Column {
Splitter { Splitter {
m_projectPartsView, m_projectPartsView,
m_projectPartTab, projectPart,
}, },
} }
), ),
@@ -1485,7 +1486,7 @@ CppCodeModelInspectorDialog::CppCodeModelInspectorDialog(QWidget *parent)
Form { QString("Sn&apshot:"), m_snapshotSelector }, Form { QString("Sn&apshot:"), m_snapshotSelector },
m_snapshotView, m_snapshotView,
}.emerge(Layouting::WithoutMargins), }.emerge(Layouting::WithoutMargins),
m_docTab, docTab,
}, },
} }
), ),
@@ -1506,6 +1507,7 @@ CppCodeModelInspectorDialog::CppCodeModelInspectorDialog(QWidget *parent)
} }
}.attachTo(this); }.attachTo(this);
QTC_CHECK(m_projectPartTab);
m_projectPartTab->setCurrentIndex(3); m_projectPartTab->setCurrentIndex(3);
connect(m_snapshotView->selectionModel(), connect(m_snapshotView->selectionModel(),

View File

@@ -162,11 +162,8 @@ public:
, m_bindStarToLeftSpecifier(createCheckBox(Tr::tr("Left const/volatile"))) , m_bindStarToLeftSpecifier(createCheckBox(Tr::tr("Left const/volatile")))
, m_bindStarToRightSpecifier(createCheckBox(Tr::tr("Right const/volatile"), , m_bindStarToRightSpecifier(createCheckBox(Tr::tr("Right const/volatile"),
Tr::tr("This does not apply to references."))) Tr::tr("This does not apply to references.")))
, m_categoryTab(new QTabWidget)
, m_tabSettingsWidget(new TabSettingsWidget) , m_tabSettingsWidget(new TabSettingsWidget)
{ {
m_categoryTab->setProperty("_q_custom_style_disabled", true);
QSizePolicy sizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred); QSizePolicy sizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
sizePolicy.setHorizontalStretch(0); sizePolicy.setHorizontalStretch(0);
sizePolicy.setVerticalStretch(0); sizePolicy.setVerticalStretch(0);
@@ -234,7 +231,8 @@ public:
}; };
Row { Row {
TabWidget { m_categoryTab, { TabWidget {
bindTo(&m_categoryTab),
Tab { Tr::tr("General"), Tab { Tr::tr("General"),
Row { Column { m_tabSettingsWidget, st }, createPreview(0) } Row { Column { m_tabSettingsWidget, st }, createPreview(0) }
}, },
@@ -243,9 +241,11 @@ public:
Tab { Tr::tr("\"switch\""), Row { switchGroup, createPreview(3) } }, Tab { Tr::tr("\"switch\""), Row { switchGroup, createPreview(3) } },
Tab { Tr::tr("Alignment"), Row { alignmentGroup, createPreview(4) } }, Tab { Tr::tr("Alignment"), Row { alignmentGroup, createPreview(4) } },
Tab { Tr::tr("Pointers and References"), Row { typesGroup, createPreview(5) } } Tab { Tr::tr("Pointers and References"), Row { typesGroup, createPreview(5) } }
} } }
}.attachTo(q); }.attachTo(q);
m_categoryTab->setProperty("_q_custom_style_disabled", true);
m_controllers.append(m_tabSettingsWidget); m_controllers.append(m_tabSettingsWidget);
m_controllers.append(contentGroup.widget); m_controllers.append(contentGroup.widget);
m_controllers.append(bracesGroup.widget); m_controllers.append(bracesGroup.widget);