Utils: Separate non-widget related base code from layoutbuilder

Change-Id: Ie7e7d413ed8cd4af8cdfc88c35fbdd9944d5e8b4
Reviewed-by: Jarek Kobus <jaroslaw.kobus@qt.io>
This commit is contained in:
hjk
2024-07-03 13:23:08 +02:00
parent 2c40765e86
commit f92cb1ad7d
4 changed files with 150 additions and 130 deletions

View File

@@ -19,6 +19,7 @@ add_qtc_library(Utils
basetreeview.cpp basetreeview.h basetreeview.cpp basetreeview.h
benchmarker.cpp benchmarker.h benchmarker.cpp benchmarker.h
buildablehelperlibrary.cpp buildablehelperlibrary.h buildablehelperlibrary.cpp buildablehelperlibrary.h
builderutils.h
camelcasecursor.cpp camelcasecursor.h camelcasecursor.cpp camelcasecursor.h
categorysortfiltermodel.cpp categorysortfiltermodel.h categorysortfiltermodel.cpp categorysortfiltermodel.h
changeset.cpp changeset.h changeset.cpp changeset.h

View File

@@ -0,0 +1,111 @@
// Copyright (C) 2020 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#pragma once
#include <functional>
#if defined(UTILS_LIBRARY)
# define QTCREATOR_UTILS_EXPORT Q_DECL_EXPORT
#elif defined(UTILS_STATIC_LIBRARY)
# define QTCREATOR_UTILS_EXPORT
#else
# define QTCREATOR_UTILS_EXPORT Q_DECL_IMPORT
#endif
namespace Building {
class NestId {};
template <typename Id, typename Arg>
class IdAndArg
{
public:
IdAndArg(Id, const Arg &arg) : arg(arg) {}
const Arg arg; // FIXME: Could be const &, but this would currently break bindTo().
};
template<typename T1, typename T2>
struct Arg2
{
Arg2(const T1 &a1, const T2 &a2)
: p1(a1)
, p2(a2)
{}
const T1 p1;
const T2 p2;
};
template<typename T1, typename T2, typename T3>
struct Arg3
{
Arg3(const T1 &a1, const T2 &a2, const T3 &a3)
: p1(a1)
, p2(a2)
, p3(a3)
{}
const T1 p1;
const T2 p2;
const T3 p3;
};
template<typename T1, typename T2, typename T3, typename T4>
struct Arg4
{
Arg4(const T1 &a1, const T2 &a2, const T3 &a3, const T4 &a4)
: p1(a1)
, p2(a2)
, p3(a3)
, p4(a4)
{}
const T1 p1;
const T2 p2;
const T3 p3;
const T4 p4;
};
// The main dispatcher
void doit(auto x, auto id, auto p);
template <typename X> class BuilderItem
{
public:
// Property setter
template <typename Id, typename Arg>
BuilderItem(IdAndArg<Id, Arg> && idarg)
{
apply = [&idarg](X *x) { doit(x, Id{}, idarg.arg); };
}
// Nested child object
template <typename Inner>
BuilderItem(Inner && p)
{
apply = [&p](X *x) { doit(x, NestId{}, std::forward<Inner>(p)); };
}
std::function<void(X *)> apply;
};
#define QTC_DEFINE_BUILDER_SETTER(name, setter) \
class name##_TAG {}; \
inline auto name(auto p) { return Building::IdAndArg{name##_TAG{}, p}; } \
inline void doit(auto x, name##_TAG, auto p) { x->setter(p); }
#define QTC_DEFINE_BUILDER_SETTER2(name, setter) \
class name##_TAG {}; \
inline auto name(auto p1, auto p2) { return Building::IdAndArg{name##_TAG{}, Building::Arg2{p1, p2}}; } \
inline void doit(auto x, name##_TAG, auto p) { x->setter(p.p1, p.p2); }
#define QTC_DEFINE_BUILDER_SETTER3(name, setter) \
class name##_TAG {}; \
inline auto name(auto p1, auto p2, auto p3) { return Building::IdAndArg{name##_TAG{}, Building::Arg3{p1, p2, p3}}; } \
inline void doit(auto x, name##_TAG, auto p) { x->setter(p.p1, p.p2, p.p3); }
#define QTC_DEFINE_BUILDER_SETTER4(name, setter) \
class name##_TAG {}; \
inline auto name(auto p1, auto p2, auto p3, auto p4) { return Building::IdAndArg{name##_TAG{}, Building::Arg4{p1, p2, p3, p4}}; } \
inline void doit(auto x, name##_TAG, auto p) { x->setter(p.p1, p.p2, p.p3, p.p4); }
} // Building

View File

@@ -3,9 +3,10 @@
#pragma once #pragma once
#include "builderutils.h"
#include <QString> #include <QString>
#include <functional>
#include <initializer_list> #include <initializer_list>
#include <vector> #include <vector>
@@ -39,80 +40,6 @@ QT_END_NAMESPACE
namespace Layouting { namespace Layouting {
class NestId {};
template <typename Id, typename Arg>
class IdAndArg
{
public:
IdAndArg(Id, const Arg &arg) : arg(arg) {}
const Arg arg; // FIXME: Could be const &, but this would currently break bindTo().
};
template<typename T1, typename T2>
struct Arg2
{
Arg2(const T1 &a1, const T2 &a2)
: p1(a1)
, p2(a2)
{}
const T1 p1;
const T2 p2;
};
template<typename T1, typename T2, typename T3>
struct Arg3
{
Arg3(const T1 &a1, const T2 &a2, const T3 &a3)
: p1(a1)
, p2(a2)
, p3(a3)
{}
const T1 p1;
const T2 p2;
const T3 p3;
};
template<typename T1, typename T2, typename T3, typename T4>
struct Arg4
{
Arg4(const T1 &a1, const T2 &a2, const T3 &a3, const T4 &a4)
: p1(a1)
, p2(a2)
, p3(a3)
, p4(a4)
{}
const T1 p1;
const T2 p2;
const T3 p3;
const T4 p4;
};
// The main dispatcher
void doit(auto x, auto id, auto p);
template <typename X> class BuilderItem
{
public:
// Nested child object
template <typename Inner>
BuilderItem(Inner && p)
{
apply = [&p](X *x) { doit(x, NestId{}, std::forward<Inner>(p)); };
}
// Property setter
template <typename Id, typename Arg>
BuilderItem(IdAndArg<Id, Arg> && idarg)
{
apply = [&idarg](X *x) { doit(x, Id{}, idarg.arg); };
}
std::function<void(X *)> apply;
};
////////////////////////////////////////////// //////////////////////////////////////////////
// //
@@ -129,7 +56,7 @@ class QTCREATOR_UTILS_EXPORT Object : public Thing
{ {
public: public:
using Implementation = QObject; using Implementation = QObject;
using I = BuilderItem<Object>; using I = Building::BuilderItem<Object>;
Object() = default; Object() = default;
Object(std::initializer_list<I> ps); Object(std::initializer_list<I> ps);
@@ -165,7 +92,7 @@ class QTCREATOR_UTILS_EXPORT Layout : public Object
{ {
public: public:
using Implementation = QLayout; using Implementation = QLayout;
using I = BuilderItem<Layout>; using I = Building::BuilderItem<Layout>;
Layout() = default; Layout() = default;
Layout(Implementation *w) { ptr = w; } Layout(Implementation *w) { ptr = w; }
@@ -210,7 +137,7 @@ class QTCREATOR_UTILS_EXPORT Column : public Layout
{ {
public: public:
using Implementation = QVBoxLayout; using Implementation = QVBoxLayout;
using I = BuilderItem<Column>; using I = Building::BuilderItem<Column>;
Column(std::initializer_list<I> ps); Column(std::initializer_list<I> ps);
}; };
@@ -219,7 +146,7 @@ class QTCREATOR_UTILS_EXPORT Row : public Layout
{ {
public: public:
using Implementation = QHBoxLayout; using Implementation = QHBoxLayout;
using I = BuilderItem<Row>; using I = Building::BuilderItem<Row>;
Row(std::initializer_list<I> ps); Row(std::initializer_list<I> ps);
}; };
@@ -228,7 +155,7 @@ class QTCREATOR_UTILS_EXPORT Form : public Layout
{ {
public: public:
using Implementation = QFormLayout; using Implementation = QFormLayout;
using I = BuilderItem<Form>; using I = Building::BuilderItem<Form>;
Form(); Form();
Form(std::initializer_list<I> ps); Form(std::initializer_list<I> ps);
@@ -238,7 +165,7 @@ class QTCREATOR_UTILS_EXPORT Grid : public Layout
{ {
public: public:
using Implementation = QGridLayout; using Implementation = QGridLayout;
using I = BuilderItem<Grid>; using I = Building::BuilderItem<Grid>;
Grid(); Grid();
Grid(std::initializer_list<I> ps); Grid(std::initializer_list<I> ps);
@@ -285,7 +212,7 @@ class QTCREATOR_UTILS_EXPORT Widget : public Object
{ {
public: public:
using Implementation = QWidget; using Implementation = QWidget;
using I = BuilderItem<Widget>; using I = Building::BuilderItem<Widget>;
Widget() = default; Widget() = default;
Widget(std::initializer_list<I> ps); Widget(std::initializer_list<I> ps);
@@ -307,7 +234,7 @@ class QTCREATOR_UTILS_EXPORT Label : public Widget
{ {
public: public:
using Implementation = QLabel; using Implementation = QLabel;
using I = BuilderItem<Label>; using I = Building::BuilderItem<Label>;
Label(std::initializer_list<I> ps); Label(std::initializer_list<I> ps);
Label(const QString &text); Label(const QString &text);
@@ -324,7 +251,7 @@ class QTCREATOR_UTILS_EXPORT Group : public Widget
{ {
public: public:
using Implementation = QGroupBox; using Implementation = QGroupBox;
using I = BuilderItem<Group>; using I = Building::BuilderItem<Group>;
Group(std::initializer_list<I> ps); Group(std::initializer_list<I> ps);
@@ -336,7 +263,7 @@ class QTCREATOR_UTILS_EXPORT SpinBox : public Widget
{ {
public: public:
using Implementation = QSpinBox; using Implementation = QSpinBox;
using I = BuilderItem<SpinBox>; using I = Building::BuilderItem<SpinBox>;
SpinBox(std::initializer_list<I> ps); SpinBox(std::initializer_list<I> ps);
@@ -348,7 +275,7 @@ class QTCREATOR_UTILS_EXPORT PushButton : public Widget
{ {
public: public:
using Implementation = QPushButton; using Implementation = QPushButton;
using I = BuilderItem<PushButton>; using I = Building::BuilderItem<PushButton>;
PushButton(std::initializer_list<I> ps); PushButton(std::initializer_list<I> ps);
@@ -360,7 +287,7 @@ class QTCREATOR_UTILS_EXPORT TextEdit : public Widget
{ {
public: public:
using Implementation = QTextEdit; using Implementation = QTextEdit;
using I = BuilderItem<TextEdit>; using I = Building::BuilderItem<TextEdit>;
using Id = Implementation *; using Id = Implementation *;
TextEdit(std::initializer_list<I> ps); TextEdit(std::initializer_list<I> ps);
@@ -372,7 +299,7 @@ class QTCREATOR_UTILS_EXPORT Splitter : public Widget
{ {
public: public:
using Implementation = QSplitter; using Implementation = QSplitter;
using I = BuilderItem<Splitter>; using I = Building::BuilderItem<Splitter>;
Splitter(std::initializer_list<I> items); Splitter(std::initializer_list<I> items);
}; };
@@ -381,7 +308,7 @@ class QTCREATOR_UTILS_EXPORT Stack : public Widget
{ {
public: public:
using Implementation = QStackedWidget; using Implementation = QStackedWidget;
using I = BuilderItem<Stack>; using I = Building::BuilderItem<Stack>;
Stack() : Stack({}) {} Stack() : Stack({}) {}
Stack(std::initializer_list<I> items); Stack(std::initializer_list<I> items);
@@ -402,7 +329,7 @@ class QTCREATOR_UTILS_EXPORT TabWidget : public Widget
{ {
public: public:
using Implementation = QTabWidget; using Implementation = QTabWidget;
using I = BuilderItem<TabWidget>; using I = Building::BuilderItem<TabWidget>;
TabWidget(std::initializer_list<I> items); TabWidget(std::initializer_list<I> items);
}; };
@@ -411,7 +338,7 @@ class QTCREATOR_UTILS_EXPORT ToolBar : public Widget
{ {
public: public:
using Implementation = QToolBar; using Implementation = QToolBar;
using I = Layouting::BuilderItem<ToolBar>; using I = Building::BuilderItem<ToolBar>;
ToolBar(std::initializer_list<I> items); ToolBar(std::initializer_list<I> items);
}; };
@@ -453,7 +380,7 @@ class BindToId {};
template <typename T> template <typename T>
auto bindTo(T **p) auto bindTo(T **p)
{ {
return IdAndArg{BindToId{}, p}; return Building::IdAndArg{BindToId{}, p};
} }
template <typename Interface> template <typename Interface>
@@ -463,7 +390,7 @@ void doit(Interface *x, BindToId, auto p)
} }
class IdId {}; class IdId {};
auto id(auto p) { return IdAndArg{IdId{}, p}; } auto id(auto p) { return Building::IdAndArg{IdId{}, p}; }
template <typename Interface> template <typename Interface>
void doit(Interface *x, IdId, auto p) void doit(Interface *x, IdId, auto p)
@@ -473,42 +400,22 @@ void doit(Interface *x, IdId, auto p)
// Setter dispatchers // Setter dispatchers
#define QTCREATOR_SETTER(name, setter) \ QTC_DEFINE_BUILDER_SETTER(fieldGrowthPolicy, setFieldGrowthPolicy)
class name##_TAG {}; \ QTC_DEFINE_BUILDER_SETTER(groupChecker, setGroupChecker)
inline auto name(auto p) { return IdAndArg{name##_TAG{}, p}; } \ QTC_DEFINE_BUILDER_SETTER(openExternalLinks, setOpenExternalLinks)
inline void doit(auto x, name##_TAG, auto p) { x->setter(p); } QTC_DEFINE_BUILDER_SETTER(size, setSize)
QTC_DEFINE_BUILDER_SETTER(text, setText)
#define QTCREATOR_SETTER2(name, setter) \ QTC_DEFINE_BUILDER_SETTER(textFormat, setTextFormat)
class name##_TAG {}; \ QTC_DEFINE_BUILDER_SETTER(textInteractionFlags, setTextInteractionFlags)
inline auto name(auto p1, auto p2) { return IdAndArg{name##_TAG{}, Arg2{p1, p2}}; } \ QTC_DEFINE_BUILDER_SETTER(title, setTitle)
inline void doit(auto x, name##_TAG, auto p) { x->setter(p.p1, p.p2); } QTC_DEFINE_BUILDER_SETTER(toolTip, setToolTip)
QTC_DEFINE_BUILDER_SETTER(windowTitle, setWindowTitle)
#define QTCREATOR_SETTER3(name, setter) \ QTC_DEFINE_BUILDER_SETTER(wordWrap, setWordWrap);
class name##_TAG {}; \ QTC_DEFINE_BUILDER_SETTER2(columnStretch, setColumnStretch)
inline auto name(auto p1, auto p2, auto p3) { return IdAndArg{name##_TAG{}, Arg3{p1, p2, p3}}; } \ QTC_DEFINE_BUILDER_SETTER2(onClicked, onClicked)
inline void doit(auto x, name##_TAG, auto p) { x->setter(p.p1, p.p2, p.p3); } QTC_DEFINE_BUILDER_SETTER2(onLinkHovered, onLinkHovered)
QTC_DEFINE_BUILDER_SETTER2(onTextChanged, onTextChanged)
#define QTCREATOR_SETTER4(name, setter) \ QTC_DEFINE_BUILDER_SETTER4(customMargins, setContentsMargins)
class name##_TAG {}; \
inline auto name(auto p1, auto p2, auto p3, auto p4) { return IdAndArg{name##_TAG{}, Arg4{p1, p2, p3, p4}}; } \
inline void doit(auto x, name##_TAG, auto p) { x->setter(p.p1, p.p2, p.p3, p.p4); }
QTCREATOR_SETTER(fieldGrowthPolicy, setFieldGrowthPolicy);
QTCREATOR_SETTER(groupChecker, setGroupChecker);
QTCREATOR_SETTER(openExternalLinks, setOpenExternalLinks);
QTCREATOR_SETTER2(size, setSize)
QTCREATOR_SETTER(text, setText)
QTCREATOR_SETTER(textFormat, setTextFormat);
QTCREATOR_SETTER(textInteractionFlags, setTextInteractionFlags);
QTCREATOR_SETTER(title, setTitle)
QTCREATOR_SETTER(toolTip, setToolTip);
QTCREATOR_SETTER(windowTitle, setWindowTitle);
QTCREATOR_SETTER(wordWrap, setWordWrap);
QTCREATOR_SETTER2(columnStretch, setColumnStretch);
QTCREATOR_SETTER2(onClicked, onClicked);
QTCREATOR_SETTER2(onLinkHovered, onLinkHovered);
QTCREATOR_SETTER2(onTextChanged, onTextChanged);
QTCREATOR_SETTER4(customMargins, setContentsMargins);
// Nesting dispatchers // Nesting dispatchers
@@ -563,7 +470,7 @@ void doit_nested(Splitter *outer, auto inner)
} }
template <class Inner> template <class Inner>
void doit(auto outer, NestId, Inner && inner) void doit(auto outer, Building::NestId, Inner && inner)
{ {
doit_nested(outer, std::forward<Inner>(inner)); doit_nested(outer, std::forward<Inner>(inner));
} }

View File

@@ -54,6 +54,7 @@ QtcLibrary {
"benchmarker.h", "benchmarker.h",
"buildablehelperlibrary.cpp", "buildablehelperlibrary.cpp",
"buildablehelperlibrary.h", "buildablehelperlibrary.h",
"builderutils.h",
"camelcasecursor.cpp", "camelcasecursor.cpp",
"camelcasecursor.h", "camelcasecursor.h",
"categorysortfiltermodel.cpp", "categorysortfiltermodel.cpp",