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 "qquickgroupbox_p.h"
5#include "qquickframe_p_p.h"
6#include "qquickdeferredexecute_p_p.h"
7
8#include <QtGui/qpa/qplatformtheme.h>
9
10QT_BEGIN_NAMESPACE
11
12/*!
13 \qmltype GroupBox
14 \inherits Frame
15//! \nativetype QQuickGroupBox
16 \inqmlmodule QtQuick.Controls
17 \since 5.7
18 \ingroup qtquickcontrols-containers
19 \brief Visual frame and title for a logical group of controls.
20
21 GroupBox is used to layout a logical group of controls together, within
22 a \l {title}{titled} visual frame. GroupBox does not provide a layout of its own, but
23 requires you to position its contents, for instance by creating a \l RowLayout
24 or a \l ColumnLayout.
25
26 Items declared as children of a GroupBox are automatically parented to the
27 GroupBox's \l {Control::}{contentItem}. Items created dynamically need to be
28 explicitly parented to the contentItem.
29
30 If only a single item is used within a GroupBox, it will resize to fit the
31 implicit size of its contained item. This makes it particularly suitable
32 for use together with layouts.
33
34 \image qtquickcontrols-groupbox.png
35
36 \snippet qtquickcontrols-groupbox.qml 1
37
38 \section2 Checkable GroupBox
39
40 Even though GroupBox has no built-in check box, it is straightforward
41 to create a checkable GroupBox by pairing it with a CheckBox.
42
43 \image qtquickcontrols-groupbox-checkable.png
44
45 It is a common pattern to enable or disable the groupbox's children when
46 its checkbox is toggled on or off, but it is up to the application to decide
47 on the behavior of the checkbox.
48
49 \snippet qtquickcontrols-groupbox-checkable.qml 1
50
51 \sa CheckBox, {Customizing GroupBox}, {Container Controls}
52*/
53
54class QQuickGroupBoxPrivate : public QQuickFramePrivate
55{
56 Q_DECLARE_PUBLIC(QQuickGroupBox)
57
58public:
59 void cancelLabel();
60 void executeLabel(bool complete = false);
61
62 void itemImplicitWidthChanged(QQuickItem *item) override;
63 void itemImplicitHeightChanged(QQuickItem *item) override;
64 void itemDestroyed(QQuickItem *item) override;
65
66 QPalette defaultPalette() const override { return QQuickTheme::palette(scope: QQuickTheme::GroupBox); }
67
68 QString title;
69 QQuickDeferredPointer<QQuickItem> label;
70};
71
72static inline QString labelName() { return QStringLiteral("label"); }
73
74void QQuickGroupBoxPrivate::cancelLabel()
75{
76 Q_Q(QQuickGroupBox);
77 quickCancelDeferred(object: q, property: labelName());
78}
79
80void QQuickGroupBoxPrivate::executeLabel(bool complete)
81{
82 Q_Q(QQuickGroupBox);
83 if (label.wasExecuted())
84 return;
85
86 if (!label || complete)
87 quickBeginDeferred(object: q, property: labelName(), delegate&: label);
88 if (complete)
89 quickCompleteDeferred(object: q, property: labelName(), delegate&: label);
90}
91
92void QQuickGroupBoxPrivate::itemImplicitWidthChanged(QQuickItem *item)
93{
94 Q_Q(QQuickGroupBox);
95 QQuickFramePrivate::itemImplicitWidthChanged(item);
96 if (item == label)
97 emit q->implicitLabelWidthChanged();
98}
99
100void QQuickGroupBoxPrivate::itemImplicitHeightChanged(QQuickItem *item)
101{
102 Q_Q(QQuickGroupBox);
103 QQuickFramePrivate::itemImplicitHeightChanged(item);
104 if (item == label)
105 emit q->implicitLabelHeightChanged();
106}
107
108void QQuickGroupBoxPrivate::itemDestroyed(QQuickItem *item)
109{
110 Q_Q(QQuickGroupBox);
111 QQuickFramePrivate::itemDestroyed(item);
112 if (item == label) {
113 label = nullptr;
114 emit q->labelChanged();
115 }
116}
117
118QQuickGroupBox::QQuickGroupBox(QQuickItem *parent)
119 : QQuickFrame(*(new QQuickGroupBoxPrivate), parent)
120{
121}
122
123QQuickGroupBox::~QQuickGroupBox()
124{
125 Q_D(QQuickGroupBox);
126 d->removeImplicitSizeListener(item: d->label);
127}
128
129/*!
130 \qmlproperty string QtQuick.Controls::GroupBox::title
131
132 This property holds the title.
133
134 The title is typically displayed above the groupbox to
135 summarize its contents.
136*/
137QString QQuickGroupBox::title() const
138{
139 Q_D(const QQuickGroupBox);
140 return d->title;
141}
142
143void QQuickGroupBox::setTitle(const QString &title)
144{
145 Q_D(QQuickGroupBox);
146 if (d->title == title)
147 return;
148
149 d->title = title;
150 maybeSetAccessibleName(name: title);
151 emit titleChanged();
152}
153
154/*!
155 \qmlproperty Item QtQuick.Controls::GroupBox::label
156
157 This property holds the label item that visualizes \l title.
158
159 \sa {Customizing GroupBox}
160*/
161QQuickItem *QQuickGroupBox::label() const
162{
163 QQuickGroupBoxPrivate *d = const_cast<QQuickGroupBoxPrivate *>(d_func());
164 if (!d->label)
165 d->executeLabel();
166 return d->label;
167}
168
169void QQuickGroupBox::setLabel(QQuickItem *label)
170{
171 Q_D(QQuickGroupBox);
172 if (d->label == label)
173 return;
174
175 QQuickControlPrivate::warnIfCustomizationNotSupported(control: this, item: label, QStringLiteral("label"));
176
177 if (!d->label.isExecuting())
178 d->cancelLabel();
179
180 const qreal oldImplicitLabelWidth = implicitLabelWidth();
181 const qreal oldImplicitLabelHeight = implicitLabelHeight();
182
183 d->removeImplicitSizeListener(item: d->label);
184 QQuickControlPrivate::hideOldItem(item: d->label);
185 d->label = label;
186
187 if (label) {
188 if (!label->parentItem())
189 label->setParentItem(this);
190 d->addImplicitSizeListener(item: label);
191 }
192
193 if (!qFuzzyCompare(p1: oldImplicitLabelWidth, p2: implicitLabelWidth()))
194 emit implicitLabelWidthChanged();
195 if (!qFuzzyCompare(p1: oldImplicitLabelHeight, p2: implicitLabelHeight()))
196 emit implicitLabelHeightChanged();
197 if (!d->label.isExecuting())
198 emit labelChanged();
199}
200
201/*!
202 \since QtQuick.Controls 2.5 (Qt 5.12)
203 \qmlproperty real QtQuick.Controls::GroupBox::implicitLabelWidth
204 \readonly
205
206 This property holds the implicit label width.
207
208 The value is equal to \c {label ? label.implicitWidth : 0}.
209
210 \sa implicitLabelHeight
211*/
212qreal QQuickGroupBox::implicitLabelWidth() const
213{
214 Q_D(const QQuickGroupBox);
215 if (!d->label)
216 return 0;
217 return d->label->implicitWidth();
218}
219
220/*!
221 \since QtQuick.Controls 2.5 (Qt 5.12)
222 \qmlproperty real QtQuick.Controls::GroupBox::implicitLabelHeight
223 \readonly
224
225 This property holds the implicit label height.
226
227 The value is equal to \c {label ? label.implicitHeight : 0}.
228
229 \sa implicitLabelWidth
230*/
231qreal QQuickGroupBox::implicitLabelHeight() const
232{
233 Q_D(const QQuickGroupBox);
234 if (!d->label)
235 return 0;
236 return d->label->implicitHeight();
237}
238
239void QQuickGroupBox::componentComplete()
240{
241 Q_D(QQuickGroupBox);
242 d->executeLabel(complete: true);
243 QQuickFrame::componentComplete();
244}
245
246QFont QQuickGroupBox::defaultFont() const
247{
248 return QQuickTheme::font(scope: QQuickTheme::GroupBox);
249}
250
251#if QT_CONFIG(accessibility)
252QAccessible::Role QQuickGroupBox::accessibleRole() const
253{
254 return QAccessible::Grouping;
255}
256
257void QQuickGroupBox::accessibilityActiveChanged(bool active)
258{
259 Q_D(QQuickGroupBox);
260 QQuickFrame::accessibilityActiveChanged(active);
261
262 if (active)
263 maybeSetAccessibleName(name: d->title);
264}
265#endif
266
267QT_END_NAMESPACE
268
269#include "moc_qquickgroupbox_p.cpp"
270

Provided by KDAB

Privacy Policy
Learn Advanced QML with KDAB
Find out more

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