aboutsummaryrefslogtreecommitdiffstats
path: root/src/labs/stylekit/qqstylekitcontrols.cpp
blob: 21c8e48a2f1ad3eebd553f3ca79f6a4c072cb650 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
// Copyright (C) 2025 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only

#include "qqstylekitcontrols_p.h"
#include "qqstylekitcontrol_p.h"
#include "qqstylekitvariation_p.h"
#include "qqstylekitcustomcontrol_p.h"

QT_BEGIN_NAMESPACE

using namespace Qt::StringLiterals;

QQStyleKitControls::QQStyleKitControls(QObject *parent)
    : QObject(parent)
{
}

QQmlListProperty<QObject> QQStyleKitControls::data()
{
    return QQmlListProperty<QObject>(this, &m_data);
}

const QList<QObject *> QQStyleKitControls::children() const
{
    return m_data;
}

/* Lazy-create the controls that the style is actually using, when accessed
 * them from the style/application (e.g from Style or Theme). We don't lazy
 * create any controls while resolving style properties, as undefined controls would
 * anyway not contain any property overrides. The properties have setters too, to
 * allow the style/application to share custom StyleKitControls the classical
 * way, e.g button: StyleKitControl { id: button }. */
QQStyleKitControl* QQStyleKitControls::getControl(int controlType) const
{
    if (!m_controls.contains(controlType))
        return nullptr;
    return m_controls[controlType];
}


QList<QQStyleKitVariation *> QQStyleKitControls::variations() const
{
    QList<QQStyleKitVariation *> list;
    for (auto *obj : children()) {
        if (auto *variation = qobject_cast<QQStyleKitVariation *>(obj))
            list.append(variation);
    }
    return list;
}

#define IMPLEMENT_ACCESSORS(NAME, TYPE) \
QQStyleKitControl *QQStyleKitControls::NAME() const \
{ \
    if (!m_controls.contains(TYPE)) { \
        auto *self = const_cast<QQStyleKitControls *>(this); \
        auto *control = new QQStyleKitControl(self); \
        self->m_controls.insert(TYPE, control); \
    } \
    return m_controls[TYPE]; \
} \
void QQStyleKitControls::set_ ## NAME(QQStyleKitControl *control) \
{ \
    m_controls.insert(TYPE, control); \
}

IMPLEMENT_ACCESSORS(abstractButton, QQStyleKitReader::ControlType::AbstractButton)
IMPLEMENT_ACCESSORS(control, QQStyleKitReader::ControlType::Control)
IMPLEMENT_ACCESSORS(button, QQStyleKitReader::ControlType::Button)
IMPLEMENT_ACCESSORS(flatButton, QQStyleKitReader::ControlType::FlatButton)
IMPLEMENT_ACCESSORS(checkBox, QQStyleKitReader::ControlType::CheckBox)
IMPLEMENT_ACCESSORS(comboBox, QQStyleKitReader::ControlType::ComboBox)
IMPLEMENT_ACCESSORS(slider, QQStyleKitReader::ControlType::Slider)
IMPLEMENT_ACCESSORS(spinBox, QQStyleKitReader::ControlType::SpinBox)
IMPLEMENT_ACCESSORS(switchControl, QQStyleKitReader::ControlType::SwitchControl)
IMPLEMENT_ACCESSORS(textField, QQStyleKitReader::ControlType::TextField)
IMPLEMENT_ACCESSORS(textInput, QQStyleKitReader::ControlType::TextInput)
IMPLEMENT_ACCESSORS(radioButton, QQStyleKitReader::ControlType::RadioButton)
IMPLEMENT_ACCESSORS(itemDelegate, QQStyleKitReader::ControlType::ItemDelegate)
IMPLEMENT_ACCESSORS(popup, QQStyleKitReader::ControlType::Popup)
IMPLEMENT_ACCESSORS(pane, QQStyleKitReader::ControlType::Pane)
IMPLEMENT_ACCESSORS(page, QQStyleKitReader::ControlType::Page)
IMPLEMENT_ACCESSORS(frame, QQStyleKitReader::ControlType::Frame)

#undef IMPLEMENT_ACCESSORS

void QQStyleKitControls::componentComplete()
{
    for (auto *obj : children()) {
        if (auto *customControl = qobject_cast<QQStyleKitCustomControl *>(obj)) {
            const int type = customControl->controlType();
            const int reserved = int(QQStyleKitReader::ControlType::Unspecified);
            if (type >= reserved)
                qmlWarning(this) << "CustomControls must use a controlType less than " << reserved;
            if (m_controls.contains(type))
                qmlWarning(this) << "CustomControl registered more than once: " << type;
            m_controls.insert(type, customControl);
        }
    }
}

QT_END_NAMESPACE

#include "moc_qqstylekitcontrols_p.cpp"