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

source code of qtquickcontrols2/src/quicktemplates2/qquickgroupbox.cpp