1// Copyright (C) 2017 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qquickcheckbox_p.h"
5#include "qquickabstractbutton_p_p.h"
6
7#include <QtGui/qpa/qplatformtheme.h>
8#include <QtQml/qjsvalue.h>
9
10QT_BEGIN_NAMESPACE
11
12/*!
13 \qmltype CheckBox
14 \inherits AbstractButton
15//! \instantiates QQuickCheckBox
16 \inqmlmodule QtQuick.Controls
17 \since 5.7
18 \ingroup qtquickcontrols-buttons
19 \brief Check button that can be toggled on or off.
20
21 \image qtquickcontrols-checkbox.gif
22
23 CheckBox presents an option button that can be toggled on (checked) or
24 off (unchecked). Check boxes are typically used to select one or more
25 options from a set of options. For larger sets of options, such as those
26 in a list, consider using \l CheckDelegate instead.
27
28 CheckBox inherits its API from \l AbstractButton. For instance, the
29 state of the checkbox can be set with the \l {AbstractButton::}{checked} property.
30
31 In addition to the checked and unchecked states, there is a third state:
32 partially checked. The partially checked state can be enabled using the
33 \l tristate property. This state indicates that the regular checked/unchecked
34 state can not be determined; generally because of other states that affect
35 the checkbox. This state is useful when several child nodes are selected
36 in a treeview, for example.
37
38 \code
39 ColumnLayout {
40 CheckBox {
41 checked: true
42 text: qsTr("First")
43 }
44 CheckBox {
45 text: qsTr("Second")
46 }
47 CheckBox {
48 checked: true
49 text: qsTr("Third")
50 }
51 }
52 \endcode
53
54 Hierarchical checkbox groups can be managed with a non-exclusive
55 \l ButtonGroup.
56
57 \image qtquickcontrols-checkbox-group.png
58
59 The following example illustrates how the combined check state of
60 children can be bound to the check state of the parent checkbox:
61
62 \snippet qtquickcontrols-checkbox-group.qml 1
63
64 \sa {Customizing CheckBox}, ButtonGroup, {Button Controls}
65*/
66
67class QQuickCheckBoxPrivate : public QQuickAbstractButtonPrivate
68{
69 Q_DECLARE_PUBLIC(QQuickCheckBox)
70
71public:
72 void setNextCheckState(const QJSValue &callback);
73
74 QPalette defaultPalette() const override { return QQuickTheme::palette(scope: QQuickTheme::CheckBox); }
75
76 bool tristate = false;
77 Qt::CheckState checkState = Qt::Unchecked;
78 QJSValue nextCheckState;
79};
80
81void QQuickCheckBoxPrivate::setNextCheckState(const QJSValue &callback)
82{
83 Q_Q(QQuickCheckBox);
84 nextCheckState = callback;
85 emit q->nextCheckStateChanged();
86}
87
88QQuickCheckBox::QQuickCheckBox(QQuickItem *parent)
89 : QQuickAbstractButton(*(new QQuickCheckBoxPrivate), parent)
90{
91 setCheckable(true);
92}
93
94/*!
95 \qmlproperty bool QtQuick.Controls::CheckBox::tristate
96
97 This property holds whether the checkbox is a tri-state checkbox.
98
99 In the animation below, the first checkbox is tri-state:
100
101 \image qtquickcontrols-checkbox-tristate.gif
102
103 The default is \c false, i.e., the checkbox has only two states.
104*/
105bool QQuickCheckBox::isTristate() const
106{
107 Q_D(const QQuickCheckBox);
108 return d->tristate;
109}
110
111void QQuickCheckBox::setTristate(bool tristate)
112{
113 Q_D(QQuickCheckBox);
114 if (d->tristate == tristate)
115 return;
116
117 d->tristate = tristate;
118 emit tristateChanged();
119}
120
121/*!
122 \qmlproperty enumeration QtQuick.Controls::CheckBox::checkState
123
124 This property holds the check state of the checkbox.
125
126 Available states:
127 \value Qt.Unchecked The checkbox is unchecked.
128 \value Qt.PartiallyChecked The checkbox is partially checked. This state is only used when \l tristate is enabled.
129 \value Qt.Checked The checkbox is checked.
130
131 \sa tristate, {AbstractButton::checked}{checked}
132*/
133Qt::CheckState QQuickCheckBox::checkState() const
134{
135 Q_D(const QQuickCheckBox);
136 return d->checkState;
137}
138
139void QQuickCheckBox::setCheckState(Qt::CheckState state)
140{
141 Q_D(QQuickCheckBox);
142 if (d->checkState == state)
143 return;
144
145 bool wasChecked = isChecked();
146 d->checked = state == Qt::Checked;
147 d->checkState = state;
148 emit checkStateChanged();
149 if (d->checked != wasChecked)
150 emit checkedChanged();
151}
152
153QFont QQuickCheckBox::defaultFont() const
154{
155 return QQuickTheme::font(scope: QQuickTheme::CheckBox);
156}
157
158void QQuickCheckBox::buttonChange(ButtonChange change)
159{
160 if (change == ButtonCheckedChange)
161 setCheckState(isChecked() ? Qt::Checked : Qt::Unchecked);
162 else
163 QQuickAbstractButton::buttonChange(change);
164}
165
166/*!
167 \since QtQuick.Controls 2.4 (Qt 5.11)
168 \qmlproperty function QtQuick.Controls::CheckBox::nextCheckState
169
170 This property holds a callback function that is called to determine
171 the next check state whenever the checkbox is interactively toggled
172 by the user via touch, mouse, or keyboard.
173
174 By default, a normal checkbox cycles between \c Qt.Unchecked and
175 \c Qt.Checked states, and a tri-state checkbox cycles between
176 \c Qt.Unchecked, \c Qt.PartiallyChecked, and \c Qt.Checked states.
177
178 The \c nextCheckState callback function can override the default behavior.
179 The following example implements a tri-state checkbox that can present
180 a partially checked state depending on external conditions, but never
181 cycles to the partially checked state when interactively toggled by
182 the user.
183
184 \code
185 CheckBox {
186 tristate: true
187 checkState: allChildrenChecked ? Qt.Checked :
188 anyChildChecked ? Qt.PartiallyChecked : Qt.Unchecked
189
190 nextCheckState: function() {
191 if (checkState === Qt.Checked)
192 return Qt.Unchecked
193 else
194 return Qt.Checked
195 }
196 }
197 \endcode
198*/
199void QQuickCheckBox::nextCheckState()
200{
201 Q_D(QQuickCheckBox);
202 if (d->nextCheckState.isCallable())
203 setCheckState(static_cast<Qt::CheckState>(d->nextCheckState.call().toInt()));
204 else if (d->tristate)
205 setCheckState(static_cast<Qt::CheckState>((d->checkState + 1) % 3));
206 else
207 QQuickAbstractButton::nextCheckState();
208}
209
210QT_END_NAMESPACE
211
212#include "moc_qquickcheckbox_p.cpp"
213

source code of qtdeclarative/src/quicktemplates/qquickcheckbox.cpp