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 "qquickcontrol_p.h"
5#include "qquickcontrol_p_p.h"
6
7#include <QtGui/qstylehints.h>
8#include <QtGui/qguiapplication.h>
9#include "qquicklabel_p.h"
10#include "qquicklabel_p_p.h"
11#include "qquicktextarea_p.h"
12#include "qquicktextarea_p_p.h"
13#include "qquicktextfield_p.h"
14#include "qquicktextfield_p_p.h"
15#include "qquickpopup_p.h"
16#include "qquickpopupitem_p_p.h"
17#include "qquickapplicationwindow_p.h"
18#include "qquickdeferredexecute_p_p.h"
19#include "qquickcontentitem_p.h"
20
21#if QT_CONFIG(accessibility)
22#include <QtQuick/private/qquickaccessibleattached_p.h>
23#endif
24
25QT_BEGIN_NAMESPACE
26
27Q_LOGGING_CATEGORY(lcItemManagement, "qt.quick.controls.control.itemmanagement")
28
29/*!
30 \qmltype Control
31 \inherits Item
32//! \instantiates QQuickControl
33 \inqmlmodule QtQuick.Controls
34 \since 5.7
35 \brief Abstract base type providing functionality common to all controls.
36
37 Control is the base type of user interface controls. It receives input
38 events from the window system, and paints a representation of itself on
39 the screen.
40
41 \section1 Control Layout
42
43 The following diagram illustrates the layout of a typical control:
44
45 \image qtquickcontrols-control.png
46
47 The \l {Item::}{implicitWidth} and \l {Item::}{implicitHeight} of a control
48 are typically based on the implicit sizes of the background and the content
49 item plus any insets and paddings. These properties determine how large
50 the control will be when no explicit \l {Item::}{width} or
51 \l {Item::}{height} is specified.
52
53 The geometry of the \l {Control::}{contentItem} is determined by the padding.
54 The following example reserves 10px padding between the boundaries of the
55 control and its content:
56
57 \code
58 Control {
59 padding: 10
60
61 contentItem: Text {
62 text: "Content"
63 }
64 }
65 \endcode
66
67 The \l {Control::}{background} item fills the entire width and height of the
68 control, unless insets or an explicit size have been given for it. Background
69 insets are useful for extending the touchable/interactive area of a control
70 without affecting its visual size. This is often used on touch devices to
71 ensure that a control is not too small to be interacted with by the user.
72 Insets affect the size of the control, and hence will affect how much space
73 they take up in a layout, for example.
74
75 Negative insets can be used to make the background larger than the control.
76 The following example uses negative insets to place a shadow outside the
77 control's boundaries:
78
79 \code
80 Control {
81 topInset: -2
82 leftInset: -2
83 rightInset: -6
84 bottomInset: -6
85
86 background: BorderImage {
87 source: ":/images/shadowed-background.png"
88 }
89 }
90 \endcode
91
92 \section1 Event Handling
93
94 All controls, except non-interactive indicators, do not let clicks and
95 touches through to items below them. For example, the \c console.log()
96 call in the example below will never be executed when clicking on the
97 Pane, because the \l MouseArea is below it in the scene:
98
99 \code
100 MouseArea {
101 anchors.fill: parent
102 onClicked: console.log("MouseArea was clicked")
103
104 Pane {
105 anchors.fill: parent
106 }
107 }
108 \endcode
109
110 Wheel events are consumed by controls if \l wheelEnabled is \c true.
111
112 \sa ApplicationWindow, Container, {Using Qt Quick Controls types in
113 property declarations}
114*/
115
116const QQuickItemPrivate::ChangeTypes QQuickControlPrivate::ImplicitSizeChanges = QQuickItemPrivate::ImplicitWidth | QQuickItemPrivate::ImplicitHeight | QQuickItemPrivate::Destroyed;
117
118static bool isKeyFocusReason(Qt::FocusReason reason)
119{
120 return reason == Qt::TabFocusReason || reason == Qt::BacktabFocusReason || reason == Qt::ShortcutFocusReason;
121}
122
123QQuickControlPrivate::QQuickControlPrivate()
124{
125#if QT_CONFIG(accessibility)
126 QAccessible::installActivationObserver(this);
127#endif
128}
129
130QQuickControlPrivate::~QQuickControlPrivate()
131{
132}
133
134void QQuickControlPrivate::init()
135{
136 Q_Q(QQuickControl);
137 QObject::connect(sender: q, signal: &QQuickItem::baselineOffsetChanged, context: q, slot: &QQuickControl::baselineOffsetChanged);
138}
139
140#if QT_CONFIG(quicktemplates2_multitouch)
141bool QQuickControlPrivate::acceptTouch(const QTouchEvent::TouchPoint &point)
142{
143 if (point.id() == touchId)
144 return true;
145
146 if (touchId == -1 && point.state() == QEventPoint::Pressed) {
147 touchId = point.id();
148 return true;
149 }
150
151 return false;
152}
153#endif
154
155static void setActiveFocus(QQuickControl *control, Qt::FocusReason reason)
156{
157 QQuickControlPrivate *d = QQuickControlPrivate::get(control);
158 if (d->subFocusItem && d->window && d->flags & QQuickItem::ItemIsFocusScope)
159 QQuickWindowPrivate::get(c: d->window)->clearFocusInScope(scope: control, item: d->subFocusItem, reason);
160 control->forceActiveFocus(reason);
161}
162
163bool QQuickControlPrivate::handlePress(const QPointF &, ulong)
164{
165 Q_Q(QQuickControl);
166 if ((focusPolicy & Qt::ClickFocus) == Qt::ClickFocus && !QGuiApplication::styleHints()->setFocusOnTouchRelease()) {
167 setActiveFocus(control: q, reason: Qt::MouseFocusReason);
168 return true;
169 }
170 return true;
171}
172
173bool QQuickControlPrivate::handleMove(const QPointF &point, ulong)
174{
175#if QT_CONFIG(quicktemplates2_hover)
176 Q_Q(QQuickControl);
177 q->setHovered(hoverEnabled && q->contains(point));
178#else
179 Q_UNUSED(point);
180#endif
181 return true;
182}
183
184bool QQuickControlPrivate::handleRelease(const QPointF &, ulong)
185{
186 Q_Q(QQuickControl);
187 bool accepted = true;
188 if ((focusPolicy & Qt::ClickFocus) == Qt::ClickFocus && QGuiApplication::styleHints()->setFocusOnTouchRelease()) {
189 setActiveFocus(control: q, reason: Qt::MouseFocusReason);
190 accepted = true;
191 }
192 touchId = -1;
193 return accepted;
194}
195
196void QQuickControlPrivate::handleUngrab()
197{
198 touchId = -1;
199}
200
201void QQuickControlPrivate::mirrorChange()
202{
203 Q_Q(QQuickControl);
204 q->mirrorChange();
205}
206
207void QQuickControlPrivate::setTopPadding(qreal value, bool reset)
208{
209 Q_Q(QQuickControl);
210 const QMarginsF oldPadding = getPadding();
211 extra.value().topPadding = value;
212 extra.value().hasTopPadding = !reset;
213 if ((!reset && !qFuzzyCompare(p1: oldPadding.top(), p2: value)) || (reset && !qFuzzyCompare(p1: oldPadding.top(), p2: getVerticalPadding()))) {
214 emit q->topPaddingChanged();
215 emit q->availableHeightChanged();
216 q->paddingChange(newPadding: getPadding(), oldPadding);
217 }
218}
219
220void QQuickControlPrivate::setLeftPadding(qreal value, bool reset)
221{
222 Q_Q(QQuickControl);
223 const QMarginsF oldPadding = getPadding();
224 extra.value().leftPadding = value;
225 extra.value().hasLeftPadding = !reset;
226 if ((!reset && !qFuzzyCompare(p1: oldPadding.left(), p2: value)) || (reset && !qFuzzyCompare(p1: oldPadding.left(), p2: getHorizontalPadding()))) {
227 emit q->leftPaddingChanged();
228 emit q->availableWidthChanged();
229 q->paddingChange(newPadding: getPadding(), oldPadding);
230 }
231}
232
233void QQuickControlPrivate::setRightPadding(qreal value, bool reset)
234{
235 Q_Q(QQuickControl);
236 const QMarginsF oldPadding = getPadding();
237 extra.value().rightPadding = value;
238 extra.value().hasRightPadding = !reset;
239 if ((!reset && !qFuzzyCompare(p1: oldPadding.right(), p2: value)) || (reset && !qFuzzyCompare(p1: oldPadding.right(), p2: getHorizontalPadding()))) {
240 emit q->rightPaddingChanged();
241 emit q->availableWidthChanged();
242 q->paddingChange(newPadding: getPadding(), oldPadding);
243 }
244}
245
246void QQuickControlPrivate::setBottomPadding(qreal value, bool reset)
247{
248 Q_Q(QQuickControl);
249 const QMarginsF oldPadding = getPadding();
250 extra.value().bottomPadding = value;
251 extra.value().hasBottomPadding = !reset;
252 if ((!reset && !qFuzzyCompare(p1: oldPadding.bottom(), p2: value)) || (reset && !qFuzzyCompare(p1: oldPadding.bottom(), p2: getVerticalPadding()))) {
253 emit q->bottomPaddingChanged();
254 emit q->availableHeightChanged();
255 q->paddingChange(newPadding: getPadding(), oldPadding);
256 }
257}
258
259void QQuickControlPrivate::setHorizontalPadding(qreal value, bool reset)
260{
261 Q_Q(QQuickControl);
262 const QMarginsF oldPadding = getPadding();
263 const qreal oldHorizontalPadding = getHorizontalPadding();
264 horizontalPadding = value;
265 hasHorizontalPadding = !reset;
266 if ((!reset && !qFuzzyCompare(p1: oldHorizontalPadding, p2: value)) || (reset && !qFuzzyCompare(p1: oldHorizontalPadding, p2: padding))) {
267 const QMarginsF newPadding = getPadding();
268 if (!qFuzzyCompare(p1: newPadding.left(), p2: oldPadding.left()))
269 emit q->leftPaddingChanged();
270 if (!qFuzzyCompare(p1: newPadding.right(), p2: oldPadding.right()))
271 emit q->rightPaddingChanged();
272 emit q->horizontalPaddingChanged();
273 emit q->availableWidthChanged();
274 q->paddingChange(newPadding, oldPadding);
275 }
276}
277
278void QQuickControlPrivate::setVerticalPadding(qreal value, bool reset)
279{
280 Q_Q(QQuickControl);
281 const QMarginsF oldPadding = getPadding();
282 const qreal oldVerticalPadding = getVerticalPadding();
283 verticalPadding = value;
284 hasVerticalPadding = !reset;
285 if ((!reset && !qFuzzyCompare(p1: oldVerticalPadding, p2: value)) || (reset && !qFuzzyCompare(p1: oldVerticalPadding, p2: padding))) {
286 const QMarginsF newPadding = getPadding();
287 if (!qFuzzyCompare(p1: newPadding.top(), p2: oldPadding.top()))
288 emit q->topPaddingChanged();
289 if (!qFuzzyCompare(p1: newPadding.bottom(), p2: oldPadding.bottom()))
290 emit q->bottomPaddingChanged();
291 emit q->verticalPaddingChanged();
292 emit q->availableHeightChanged();
293 q->paddingChange(newPadding, oldPadding);
294 }
295}
296
297void QQuickControlPrivate::setTopInset(qreal value, bool reset)
298{
299 Q_Q(QQuickControl);
300 const QMarginsF oldInset = getInset();
301 extra.value().topInset = value;
302 extra.value().hasTopInset = !reset;
303 if (!qFuzzyCompare(p1: oldInset.top(), p2: value)) {
304 emit q->topInsetChanged();
305 q->insetChange(newInset: getInset(), oldInset);
306 }
307}
308
309void QQuickControlPrivate::setLeftInset(qreal value, bool reset)
310{
311 Q_Q(QQuickControl);
312 const QMarginsF oldInset = getInset();
313 extra.value().leftInset = value;
314 extra.value().hasLeftInset = !reset;
315 if (!qFuzzyCompare(p1: oldInset.left(), p2: value)) {
316 emit q->leftInsetChanged();
317 q->insetChange(newInset: getInset(), oldInset);
318 }
319}
320
321void QQuickControlPrivate::setRightInset(qreal value, bool reset)
322{
323 Q_Q(QQuickControl);
324 const QMarginsF oldInset = getInset();
325 extra.value().rightInset = value;
326 extra.value().hasRightInset = !reset;
327 if (!qFuzzyCompare(p1: oldInset.right(), p2: value)) {
328 emit q->rightInsetChanged();
329 q->insetChange(newInset: getInset(), oldInset);
330 }
331}
332
333void QQuickControlPrivate::setBottomInset(qreal value, bool reset)
334{
335 Q_Q(QQuickControl);
336 const QMarginsF oldInset = getInset();
337 extra.value().bottomInset = value;
338 extra.value().hasBottomInset = !reset;
339 if (!qFuzzyCompare(p1: oldInset.bottom(), p2: value)) {
340 emit q->bottomInsetChanged();
341 q->insetChange(newInset: getInset(), oldInset);
342 }
343}
344
345void QQuickControlPrivate::resizeBackground()
346{
347 if (!background)
348 return;
349
350 resizingBackground = true;
351
352 QQuickItemPrivate *p = QQuickItemPrivate::get(item: background);
353 bool changeWidth = false;
354 bool changeHeight = false;
355 if (((!p->widthValid() || !extra.isAllocated() || !extra->hasBackgroundWidth) && qFuzzyIsNull(d: background->x()))
356 || (extra.isAllocated() && (extra->hasLeftInset || extra->hasRightInset))) {
357 background->setX(getLeftInset());
358 changeWidth = !p->width.hasBinding();
359 }
360 if (((!p->heightValid() || !extra.isAllocated() || !extra->hasBackgroundHeight) && qFuzzyIsNull(d: background->y()))
361 || (extra.isAllocated() && (extra->hasTopInset || extra->hasBottomInset))) {
362 background->setY(getTopInset());
363 changeHeight = !p->height.hasBinding();
364 }
365 if (changeHeight || changeWidth) {
366 auto newWidth = changeWidth ?
367 width.valueBypassingBindings() - getLeftInset() - getRightInset() :
368 p->width.valueBypassingBindings();
369 auto newHeight = changeHeight ?
370 height.valueBypassingBindings() - getTopInset() - getBottomInset() :
371 p->height.valueBypassingBindings();
372 background->setSize({newWidth, newHeight});
373 }
374
375 resizingBackground = false;
376}
377
378void QQuickControlPrivate::resizeContent()
379{
380 Q_Q(QQuickControl);
381 if (contentItem) {
382 contentItem->setPosition(QPointF(q->leftPadding(), q->topPadding()));
383 contentItem->setSize(QSizeF(q->availableWidth(), q->availableHeight()));
384 }
385}
386
387QQuickItem *QQuickControlPrivate::getContentItem()
388{
389 if (!contentItem)
390 executeContentItem();
391 return contentItem;
392}
393
394void QQuickControlPrivate::setContentItem_helper(QQuickItem *item, bool notify)
395{
396 Q_Q(QQuickControl);
397 if (contentItem == item)
398 return;
399
400 if (notify)
401 warnIfCustomizationNotSupported(control: q, item, QStringLiteral("contentItem"));
402
403 if (!contentItem.isExecuting())
404 cancelContentItem();
405
406 QQuickItem *oldContentItem = contentItem;
407 if (oldContentItem) {
408 disconnect(sender: oldContentItem, signal: &QQuickItem::baselineOffsetChanged, receiverPrivate: this, slot: &QQuickControlPrivate::updateBaselineOffset);
409 if (oldContentItem)
410 QQuickItemPrivate::get(item: oldContentItem)->removeItemChangeListener(this, types: QQuickControlPrivate::Focus);
411 removeImplicitSizeListener(item: oldContentItem);
412 }
413
414 contentItem = item;
415 q->contentItemChange(newItem: item, oldItem: oldContentItem);
416 QQuickControlPrivate::hideOldItem(item: oldContentItem);
417
418 if (item) {
419 connect(sender: contentItem.data(), signal: &QQuickItem::baselineOffsetChanged, receiverPrivate: this, slot: &QQuickControlPrivate::updateBaselineOffset);
420 // We need to update the control's focusReason when the contentItem receives or loses focus. Since focusPolicy
421 // (or other properties impacting focus handling, like QQuickItem::activeFocusOnTab) might change later, and
422 // since the content item might also change focus programmatically, we always have to listen for those events.
423 QQuickItemPrivate::get(item)->addItemChangeListener(listener: this, types: QQuickControlPrivate::Focus);
424 if (!item->parentItem())
425 item->setParentItem(q);
426 if (componentComplete)
427 resizeContent();
428 addImplicitSizeListener(item: contentItem);
429 }
430
431 updateImplicitContentSize();
432 updateBaselineOffset();
433
434 if (notify && !contentItem.isExecuting())
435 emit q->contentItemChanged();
436}
437
438qreal QQuickControlPrivate::getContentWidth() const
439{
440 return contentItem ? contentItem->implicitWidth() : 0;
441}
442
443qreal QQuickControlPrivate::getContentHeight() const
444{
445 return contentItem ? contentItem->implicitHeight() : 0;
446}
447
448void QQuickControlPrivate::updateImplicitContentWidth()
449{
450 Q_Q(QQuickControl);
451 const qreal oldWidth = implicitContentWidth;
452 implicitContentWidth = getContentWidth();
453 if (!qFuzzyCompare(p1: implicitContentWidth, p2: oldWidth))
454 emit q->implicitContentWidthChanged();
455}
456
457void QQuickControlPrivate::updateImplicitContentHeight()
458{
459 Q_Q(QQuickControl);
460 const qreal oldHeight = implicitContentHeight;
461 implicitContentHeight = getContentHeight();
462 if (!qFuzzyCompare(p1: implicitContentHeight, p2: oldHeight))
463 emit q->implicitContentHeightChanged();
464}
465
466void QQuickControlPrivate::updateImplicitContentSize()
467{
468 Q_Q(QQuickControl);
469 const qreal oldWidth = implicitContentWidth;
470 const qreal oldHeight = implicitContentHeight;
471 implicitContentWidth = getContentWidth();
472 implicitContentHeight = getContentHeight();
473 if (!qFuzzyCompare(p1: implicitContentWidth, p2: oldWidth))
474 emit q->implicitContentWidthChanged();
475 if (!qFuzzyCompare(p1: implicitContentHeight, p2: oldHeight))
476 emit q->implicitContentHeightChanged();
477}
478
479QPalette QQuickControlPrivate::defaultPalette() const
480{
481 return QQuickTheme::palette(scope: QQuickTheme::System);
482}
483
484#if QT_CONFIG(accessibility)
485void QQuickControlPrivate::accessibilityActiveChanged(bool active)
486{
487 Q_Q(QQuickControl);
488 return q->accessibilityActiveChanged(active);
489}
490
491QAccessible::Role QQuickControlPrivate::accessibleRole() const
492{
493 Q_Q(const QQuickControl);
494 return q->accessibleRole();
495}
496
497QQuickAccessibleAttached *QQuickControlPrivate::accessibleAttached(const QObject *object)
498{
499 if (!QAccessible::isActive())
500 return nullptr;
501 return QQuickAccessibleAttached::attachedProperties(obj: object);
502}
503#endif
504
505/*!
506 \internal
507
508 Returns the font that the control \a item inherits from its ancestors and
509 QGuiApplication::font.
510*/
511QFont QQuickControlPrivate::parentFont(const QQuickItem *item)
512{
513 QQuickItem *p = item->parentItem();
514 while (p) {
515 if (QQuickControl *control = qobject_cast<QQuickControl *>(object: p))
516 return QQuickControlPrivate::get(control)->resolvedFont;
517 else if (QQuickLabel *label = qobject_cast<QQuickLabel *>(object: p))
518 return label->QQuickText::font();
519 else if (QQuickTextField *textField = qobject_cast<QQuickTextField *>(object: p))
520 return textField->QQuickTextInput::font();
521 else if (QQuickTextArea *textArea = qobject_cast<QQuickTextArea *>(object: p))
522 return textArea->QQuickTextEdit::font();
523
524 p = p->parentItem();
525 }
526
527 if (QQuickApplicationWindow *window = qobject_cast<QQuickApplicationWindow *>(object: item->window()))
528 return window->font();
529
530 return QQuickTheme::font(scope: QQuickTheme::System);
531}
532
533/*!
534 \internal
535
536 Determine which font is implicitly imposed on this control by its ancestors
537 and QGuiApplication::font, resolve this against its own font (attributes from
538 the implicit font are copied over). Then propagate this font to this
539 control's children.
540*/
541void QQuickControlPrivate::resolveFont()
542{
543 Q_Q(QQuickControl);
544 inheritFont(font: parentFont(item: q));
545}
546
547void QQuickControlPrivate::inheritFont(const QFont &font)
548{
549 Q_Q(QQuickControl);
550 QFont parentFont = extra.isAllocated() ? extra->requestedFont.resolve(font) : font;
551 parentFont.setResolveMask(extra.isAllocated() ? extra->requestedFont.resolveMask() | font.resolveMask() : font.resolveMask());
552
553 const QFont defaultFont = q->defaultFont();
554 QFont resolvedFont = parentFont.resolve(defaultFont);
555
556 setFont_helper(resolvedFont);
557}
558
559/*!
560 \internal
561
562 Assign \a font to this control, and propagate it to all children.
563*/
564void QQuickControlPrivate::updateFont(const QFont &font)
565{
566 Q_Q(QQuickControl);
567 QFont oldFont = resolvedFont;
568 resolvedFont = font;
569
570 if (oldFont != font)
571 q->fontChange(newFont: font, oldFont);
572
573 QQuickControlPrivate::updateFontRecur(item: q, font);
574
575 if (oldFont != font)
576 emit q->fontChanged();
577}
578
579void QQuickControlPrivate::updateFontRecur(QQuickItem *item, const QFont &font)
580{
581 const auto childItems = item->childItems();
582 for (QQuickItem *child : childItems) {
583 if (QQuickControl *control = qobject_cast<QQuickControl *>(object: child))
584 QQuickControlPrivate::get(control)->inheritFont(font);
585 else if (QQuickLabel *label = qobject_cast<QQuickLabel *>(object: child))
586 QQuickLabelPrivate::get(item: label)->inheritFont(font);
587 else if (QQuickTextArea *textArea = qobject_cast<QQuickTextArea *>(object: child))
588 QQuickTextAreaPrivate::get(item: textArea)->inheritFont(font);
589 else if (QQuickTextField *textField = qobject_cast<QQuickTextField *>(object: child))
590 QQuickTextFieldPrivate::get(item: textField)->inheritFont(font);
591 else
592 QQuickControlPrivate::updateFontRecur(item: child, font);
593 }
594}
595
596QLocale QQuickControlPrivate::calcLocale(const QQuickItem *item)
597{
598 const QQuickItem *p = item;
599 while (p) {
600 if (const QQuickControl *control = qobject_cast<const QQuickControl *>(object: p))
601 return control->locale();
602
603 QVariant v = p->property(name: "locale");
604 if (v.isValid() && v.userType() == QMetaType::QLocale)
605 return v.toLocale();
606
607 p = p->parentItem();
608 }
609
610 if (item) {
611 if (QQuickApplicationWindow *window = qobject_cast<QQuickApplicationWindow *>(object: item->window()))
612 return window->locale();
613 }
614
615 return QLocale();
616}
617
618/*!
619 \internal
620
621 Warns if \a control has a \c __notCustomizable property which is set to \c true,
622 unless \a item has an \c __ignoreNotCustomizable property.
623
624 If \c __notCustomizable is \c true, it means that the style that provides the
625 control does not support customization. If \c __ignoreNotCustomizable is true,
626 it means that the item is an internal implementation detail and shouldn't be
627 subject to the warning.
628
629 We take a QObject for \c control instead of QQuickControl or QQuickItem
630 because not all relevant types derive from QQuickControl - e.g. TextField,
631 TextArea, QQuickIndicatorButton, etc.
632*/
633void QQuickControlPrivate::warnIfCustomizationNotSupported(QObject *control, QQuickItem *item, const QString &propertyName)
634{
635 static const bool ignoreWarnings = [](){
636 return qEnvironmentVariableIntValue(varName: "QT_QUICK_CONTROLS_IGNORE_CUSTOMIZATION_WARNINGS");
637 }();
638 if (ignoreWarnings)
639 return;
640
641 if (!control->property(name: "__notCustomizable").toBool()
642 || (item && item->property(name: "__ignoreNotCustomizable").toBool()))
643 return;
644
645 qmlWarning(me: item ? item : control).nospace() << "The current style does not support customization of this control "
646 << "(property: " << propertyName << " item: " << item << "). "
647 "Please customize a non-native style (such as Basic, Fusion, Material, etc). For more information, see: "
648 "https://doc.qt.io/qt-6/qtquickcontrols2-customize.html#customization-reference";
649}
650
651void QQuickControlPrivate::updateLocale(const QLocale &l, bool e)
652{
653 Q_Q(QQuickControl);
654 if (!e && hasLocale)
655 return;
656
657 QLocale old = q->locale();
658 hasLocale = e;
659 if (old != l) {
660 locale = l;
661 q->localeChange(newLocale: l, oldLocale: old);
662 QQuickControlPrivate::updateLocaleRecur(item: q, l);
663 emit q->localeChanged();
664 }
665}
666
667void QQuickControlPrivate::updateLocaleRecur(QQuickItem *item, const QLocale &l)
668{
669 const auto childItems = item->childItems();
670 for (QQuickItem *child : childItems) {
671 if (QQuickControl *control = qobject_cast<QQuickControl *>(object: child))
672 QQuickControlPrivate::get(control)->updateLocale(l, e: false);
673 else
674 updateLocaleRecur(item: child, l);
675 }
676}
677
678#if QT_CONFIG(quicktemplates2_hover)
679void QQuickControlPrivate::updateHoverEnabled(bool enabled, bool xplicit)
680{
681 Q_Q(QQuickControl);
682 if (!xplicit && explicitHoverEnabled)
683 return;
684
685 bool wasEnabled = q->isHoverEnabled();
686 explicitHoverEnabled = xplicit;
687 if (wasEnabled != enabled) {
688 q->setAcceptHoverEvents(enabled);
689 QQuickControlPrivate::updateHoverEnabledRecur(item: q, enabled);
690 emit q->hoverEnabledChanged();
691 }
692}
693
694void QQuickControlPrivate::updateHoverEnabledRecur(QQuickItem *item, bool enabled)
695{
696 const auto childItems = item->childItems();
697 for (QQuickItem *child : childItems) {
698 if (QQuickControl *control = qobject_cast<QQuickControl *>(object: child))
699 QQuickControlPrivate::get(control)->updateHoverEnabled(enabled, xplicit: false);
700 else
701 updateHoverEnabledRecur(item: child, enabled);
702 }
703}
704
705bool QQuickControlPrivate::calcHoverEnabled(const QQuickItem *item)
706{
707 const QQuickItem *p = item;
708 while (p) {
709 // QQuickPopupItem accepts hover events to avoid leaking them through.
710 // Don't inherit that to the children of the popup, but fallback to the
711 // environment variable or style hint.
712 if (qobject_cast<const QQuickPopupItem *>(object: p))
713 break;
714
715 if (const QQuickControl *control = qobject_cast<const QQuickControl *>(object: p))
716 return control->isHoverEnabled();
717
718 QVariant v = p->property(name: "hoverEnabled");
719 if (v.isValid() && v.userType() == QMetaType::Bool)
720 return v.toBool();
721
722 p = p->parentItem();
723 }
724
725 bool ok = false;
726 int env = qEnvironmentVariableIntValue(varName: "QT_QUICK_CONTROLS_HOVER_ENABLED", ok: &ok);
727 if (ok)
728 return env != 0;
729
730 // TODO: QQuickApplicationWindow::isHoverEnabled()
731
732 return QGuiApplication::styleHints()->useHoverEffects();
733}
734#endif
735
736static inline QString contentItemName() { return QStringLiteral("contentItem"); }
737
738void QQuickControlPrivate::cancelContentItem()
739{
740 Q_Q(QQuickControl);
741 quickCancelDeferred(object: q, property: contentItemName());
742}
743
744void QQuickControlPrivate::executeContentItem(bool complete)
745{
746 Q_Q(QQuickControl);
747 if (contentItem.wasExecuted())
748 return;
749
750 if (!contentItem || complete)
751 quickBeginDeferred(object: q, property: contentItemName(), delegate&: contentItem);
752 if (complete)
753 quickCompleteDeferred(object: q, property: contentItemName(), delegate&: contentItem);
754}
755
756void QQuickControlPrivate::cancelBackground()
757{
758 Q_Q(QQuickControl);
759 quickCancelDeferred(object: q, property: backgroundName());
760}
761
762void QQuickControlPrivate::executeBackground(bool complete)
763{
764 Q_Q(QQuickControl);
765 if (background.wasExecuted())
766 return;
767
768 if (!background || complete)
769 quickBeginDeferred(object: q, property: backgroundName(), delegate&: background);
770 if (complete)
771 quickCompleteDeferred(object: q, property: backgroundName(), delegate&: background);
772}
773
774/*
775 \internal
776
777 Hides an item that was replaced by a newer one, rather than
778 deleting it, as the item is typically created in QML and hence
779 we don't own it.
780*/
781void QQuickControlPrivate::hideOldItem(QQuickItem *item)
782{
783 if (!item)
784 return;
785
786 qCDebug(lcItemManagement) << "hiding old item" << item;
787
788 item->setVisible(false);
789 item->setParentItem(nullptr);
790
791#if QT_CONFIG(accessibility)
792 // Remove the item from the accessibility tree.
793 QQuickAccessibleAttached *accessible = accessibleAttached(object: item);
794 if (accessible)
795 accessible->setIgnored(true);
796#endif
797}
798
799/*
800 \internal
801
802 Named "unhide" because it's used for cases where an item
803 that was previously hidden by \l hideOldItem() wants to be
804 shown by a control again, such as a ScrollBar in ScrollView.
805
806 \a visibility controls the visibility of \a item, as there
807 may have been bindings that controlled visibility, such as
808 with a typical ScrollBar.qml implementation:
809
810 \code
811 visible: control.policy !== T.ScrollBar.AlwaysOff
812 \endcode
813
814 In the future we could try to save the binding for the visible
815 property (using e.g. QQmlAnyBinding::takeFrom), but for now we
816 keep it simple and just allow restoring an equivalent literal value.
817*/
818void QQuickControlPrivate::unhideOldItem(QQuickControl *control, QQuickItem *item, UnhideVisibility visibility)
819{
820 Q_ASSERT(item);
821 qCDebug(lcItemManagement) << "unhiding old item" << item;
822
823 item->setVisible(visibility == UnhideVisibility::Show);
824 item->setParentItem(control);
825
826#if QT_CONFIG(accessibility)
827 // Add the item back in to the accessibility tree.
828 QQuickAccessibleAttached *accessible = accessibleAttached(object: item);
829 if (accessible)
830 accessible->setIgnored(false);
831#endif
832}
833
834void QQuickControlPrivate::updateBaselineOffset()
835{
836 Q_Q(QQuickControl);
837 if (extra.isAllocated() && extra.value().hasBaselineOffset)
838 return;
839
840 if (!contentItem)
841 q->QQuickItem::setBaselineOffset(0);
842 else
843 q->QQuickItem::setBaselineOffset(getTopPadding() + contentItem->baselineOffset());
844}
845
846void QQuickControlPrivate::addImplicitSizeListener(QQuickItem *item, ChangeTypes changes)
847{
848 addImplicitSizeListener(item, listener: this, changes);
849}
850
851void QQuickControlPrivate::removeImplicitSizeListener(QQuickItem *item, ChangeTypes changes)
852{
853 removeImplicitSizeListener(item, listener: this, changes);
854}
855
856void QQuickControlPrivate::addImplicitSizeListener(QQuickItem *item, QQuickItemChangeListener *listener, ChangeTypes changes)
857{
858 if (!item || !listener)
859 return;
860 QQuickItemPrivate::get(item)->addItemChangeListener(listener, types: changes);
861}
862
863void QQuickControlPrivate::removeImplicitSizeListener(QQuickItem *item, QQuickItemChangeListener *listener, ChangeTypes changes)
864{
865 if (!item || !listener)
866 return;
867 QQuickItemPrivate::get(item)->removeItemChangeListener(listener, types: changes);
868}
869
870void QQuickControlPrivate::itemImplicitWidthChanged(QQuickItem *item)
871{
872 Q_Q(QQuickControl);
873 if (item == background)
874 emit q->implicitBackgroundWidthChanged();
875 else if (item == contentItem)
876 updateImplicitContentWidth();
877}
878
879void QQuickControlPrivate::itemImplicitHeightChanged(QQuickItem *item)
880{
881 Q_Q(QQuickControl);
882 if (item == background)
883 emit q->implicitBackgroundHeightChanged();
884 else if (item == contentItem)
885 updateImplicitContentHeight();
886}
887
888void QQuickControlPrivate::itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &diff)
889{
890 Q_UNUSED(diff);
891 if (resizingBackground || item != background || !change.sizeChange())
892 return;
893
894 QQuickItemPrivate *p = QQuickItemPrivate::get(item);
895 // Only set hasBackgroundWidth/Height if it was a width/height change,
896 // otherwise we're prevented from setting a width/height in the future.
897 if (change.widthChange())
898 extra.value().hasBackgroundWidth = p->widthValid();
899 if (change.heightChange())
900 extra.value().hasBackgroundHeight = p->heightValid();
901 resizeBackground();
902}
903
904void QQuickControlPrivate::itemDestroyed(QQuickItem *item)
905{
906 Q_Q(QQuickControl);
907 if (item == background) {
908 background = nullptr;
909 emit q->implicitBackgroundWidthChanged();
910 emit q->implicitBackgroundHeightChanged();
911 } else if (item == contentItem) {
912 contentItem = nullptr;
913 updateImplicitContentSize();
914 }
915}
916
917void QQuickControlPrivate::itemFocusChanged(QQuickItem *item, Qt::FocusReason reason)
918{
919 Q_Q(QQuickControl);
920 if (item == contentItem || item == q)
921 q->setFocusReason(reason);
922}
923
924QQuickControl::QQuickControl(QQuickItem *parent)
925 : QQuickItem(*(new QQuickControlPrivate), parent)
926{
927 Q_D(QQuickControl);
928 d->init();
929}
930
931QQuickControl::QQuickControl(QQuickControlPrivate &dd, QQuickItem *parent)
932 : QQuickItem(dd, parent)
933{
934 Q_D(QQuickControl);
935 d->init();
936}
937
938QQuickControl::~QQuickControl()
939{
940 Q_D(QQuickControl);
941 d->removeImplicitSizeListener(item: d->background, changes: QQuickControlPrivate::ImplicitSizeChanges | QQuickItemPrivate::Geometry);
942 d->removeImplicitSizeListener(item: d->contentItem);
943 if (d->contentItem)
944 QQuickItemPrivate::get(item: d->contentItem)->removeItemChangeListener(d, types: QQuickItemPrivate::Focus);
945#if QT_CONFIG(accessibility)
946 QAccessible::removeActivationObserver(d);
947#endif
948}
949
950void QQuickControl::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &value)
951{
952 Q_D(QQuickControl);
953 QQuickItem::itemChange(change, value);
954 switch (change) {
955 case ItemEnabledHasChanged:
956 enabledChange();
957 break;
958 case ItemVisibleHasChanged:
959#if QT_CONFIG(quicktemplates2_hover)
960 if (!value.boolValue)
961 setHovered(false);
962#endif
963 break;
964 case ItemSceneChange:
965 case ItemParentHasChanged:
966 if ((change == ItemParentHasChanged && value.item) || (change == ItemSceneChange && value.window)) {
967 d->resolveFont();
968 if (!d->hasLocale)
969 d->updateLocale(l: QQuickControlPrivate::calcLocale(item: d->parentItem), e: false); // explicit=false
970#if QT_CONFIG(quicktemplates2_hover)
971 if (!d->explicitHoverEnabled)
972 d->updateHoverEnabled(enabled: QQuickControlPrivate::calcHoverEnabled(item: d->parentItem), xplicit: false); // explicit=false
973#endif
974 }
975 break;
976 case ItemActiveFocusHasChanged:
977 if (isKeyFocusReason(reason: d->focusReason))
978 emit visualFocusChanged();
979 break;
980 default:
981 break;
982 }
983}
984
985/*!
986 \qmlproperty font QtQuick.Controls::Control::font
987
988 This property holds the font currently set for the control.
989
990 This property describes the control's requested font. The font is used by the control's
991 style when rendering standard components, and is available as a means to ensure that custom
992 controls can maintain consistency with the native platform's native look and feel. It's common
993 that different platforms, or different styles, define different fonts for an application.
994
995 The default font depends on the system environment. ApplicationWindow maintains a system/theme
996 font which serves as a default for all controls. There may also be special font defaults for
997 certain types of controls. You can also set the default font for controls by either:
998
999 \list
1000 \li passing a custom font to QGuiApplication::setFont(), before loading the QML; or
1001 \li specifying the fonts in the \l {Qt Quick Controls 2 Configuration File}{qtquickcontrols2.conf file}.
1002 \endlist
1003
1004 Finally, the font is matched against Qt's font database to find the best match.
1005
1006 Control propagates explicit font properties from parent to children. If you change a specific
1007 property on a control's font, that property propagates to all of the control's children,
1008 overriding any system defaults for that property.
1009
1010 \code
1011 Page {
1012 font.family: "Courier"
1013
1014 Column {
1015 Label {
1016 text: qsTr("This will use Courier...")
1017 }
1018
1019 Switch {
1020 text: qsTr("... and so will this")
1021 }
1022 }
1023 }
1024 \endcode
1025
1026 For the full list of available font properties, see the
1027 \l [QtQuick]{font}{font QML Value Type} documentation.
1028*/
1029QFont QQuickControl::font() const
1030{
1031 Q_D(const QQuickControl);
1032 QFont font = d->resolvedFont;
1033 // The resolveMask should inherit from the requestedFont
1034 font.setResolveMask(d->extra.value().requestedFont.resolveMask());
1035 return font;
1036}
1037
1038void QQuickControl::setFont(const QFont &font)
1039{
1040 Q_D(QQuickControl);
1041 if (d->extra.value().requestedFont.resolveMask() == font.resolveMask() && d->extra.value().requestedFont == font)
1042 return;
1043
1044 d->extra.value().requestedFont = font;
1045 d->resolveFont();
1046}
1047
1048void QQuickControl::resetFont()
1049{
1050 setFont(QFont());
1051}
1052
1053/*!
1054 \qmlproperty real QtQuick.Controls::Control::availableWidth
1055 \readonly
1056
1057 This property holds the width available to the \l contentItem after
1058 deducting horizontal padding from the \l {Item::}{width} of the control.
1059
1060 \sa {Control Layout}, padding, leftPadding, rightPadding
1061*/
1062qreal QQuickControl::availableWidth() const
1063{
1064 return qMax<qreal>(a: 0.0, b: width() - leftPadding() - rightPadding());
1065}
1066
1067/*!
1068 \qmlproperty real QtQuick.Controls::Control::availableHeight
1069 \readonly
1070
1071 This property holds the height available to the \l contentItem after
1072 deducting vertical padding from the \l {Item::}{height} of the control.
1073
1074 \sa {Control Layout}, padding, topPadding, bottomPadding
1075*/
1076qreal QQuickControl::availableHeight() const
1077{
1078 return qMax<qreal>(a: 0.0, b: height() - topPadding() - bottomPadding());
1079}
1080
1081/*!
1082 \qmlproperty real QtQuick.Controls::Control::padding
1083
1084 This property holds the default padding.
1085
1086 Padding adds a space between each edge of the content item and the
1087 background item, effectively controlling the size of the content item. To
1088 specify a padding value for a specific edge of the control, set its
1089 relevant property:
1090
1091 \list
1092 \li \l {Control::}{leftPadding}
1093 \li \l {Control::}{rightPadding}
1094 \li \l {Control::}{topPadding}
1095 \li \l {Control::}{bottomPadding}
1096 \endlist
1097
1098 \note Different styles may specify the default padding for certain controls
1099 in different ways, and these ways may change over time as the design
1100 guidelines that the style is based on evolve. To ensure that these changes
1101 don't affect the padding values you have specified, it is best to use the
1102 most specific properties available. For example, rather than setting
1103 the \l padding property:
1104
1105 \code
1106 padding: 0
1107 \endcode
1108
1109 set each specific property instead:
1110
1111 \code
1112 leftPadding: 0
1113 rightPadding: 0
1114 topPadding: 0
1115 bottomPadding: 0
1116 \endcode
1117
1118 \sa {Control Layout}, availableWidth, availableHeight, topPadding, leftPadding, rightPadding, bottomPadding
1119*/
1120qreal QQuickControl::padding() const
1121{
1122 Q_D(const QQuickControl);
1123 return d->padding;
1124}
1125
1126void QQuickControl::setPadding(qreal padding)
1127{
1128 Q_D(QQuickControl);
1129 if (qFuzzyCompare(p1: d->padding, p2: padding))
1130 return;
1131
1132 const QMarginsF oldPadding = d->getPadding();
1133 const qreal oldVerticalPadding = d->getVerticalPadding();
1134 const qreal oldHorizontalPadding = d->getHorizontalPadding();
1135
1136 d->padding = padding;
1137 emit paddingChanged();
1138
1139 const QMarginsF newPadding = d->getPadding();
1140 const qreal newVerticalPadding = d->getVerticalPadding();
1141 const qreal newHorizontalPadding = d->getHorizontalPadding();
1142
1143 if (!qFuzzyCompare(p1: newPadding.top(), p2: oldPadding.top()))
1144 emit topPaddingChanged();
1145 if (!qFuzzyCompare(p1: newPadding.left(), p2: oldPadding.left()))
1146 emit leftPaddingChanged();
1147 if (!qFuzzyCompare(p1: newPadding.right(), p2: oldPadding.right()))
1148 emit rightPaddingChanged();
1149 if (!qFuzzyCompare(p1: newPadding.bottom(), p2: oldPadding.bottom()))
1150 emit bottomPaddingChanged();
1151 if (!qFuzzyCompare(p1: newVerticalPadding, p2: oldVerticalPadding))
1152 emit verticalPaddingChanged();
1153 if (!qFuzzyCompare(p1: newHorizontalPadding, p2: oldHorizontalPadding))
1154 emit horizontalPaddingChanged();
1155 if (!qFuzzyCompare(p1: newPadding.top(), p2: oldPadding.top()) || !qFuzzyCompare(p1: newPadding.bottom(), p2: oldPadding.bottom()))
1156 emit availableHeightChanged();
1157 if (!qFuzzyCompare(p1: newPadding.left(), p2: oldPadding.left()) || !qFuzzyCompare(p1: newPadding.right(), p2: oldPadding.right()))
1158 emit availableWidthChanged();
1159
1160 paddingChange(newPadding, oldPadding);
1161}
1162
1163void QQuickControl::resetPadding()
1164{
1165 setPadding(0);
1166}
1167
1168/*!
1169 \qmlproperty real QtQuick.Controls::Control::topPadding
1170
1171 This property holds the top padding. Unless explicitly set, the value
1172 is equal to \c verticalPadding.
1173
1174 \sa {Control Layout}, padding, bottomPadding, verticalPadding, availableHeight
1175*/
1176qreal QQuickControl::topPadding() const
1177{
1178 Q_D(const QQuickControl);
1179 return d->getTopPadding();
1180}
1181
1182void QQuickControl::setTopPadding(qreal padding)
1183{
1184 Q_D(QQuickControl);
1185 d->setTopPadding(value: padding);
1186}
1187
1188void QQuickControl::resetTopPadding()
1189{
1190 Q_D(QQuickControl);
1191 d->setTopPadding(value: 0, reset: true);
1192}
1193
1194/*!
1195 \qmlproperty real QtQuick.Controls::Control::leftPadding
1196
1197 This property holds the left padding. Unless explicitly set, the value
1198 is equal to \c horizontalPadding.
1199
1200 \sa {Control Layout}, padding, rightPadding, horizontalPadding, availableWidth
1201*/
1202qreal QQuickControl::leftPadding() const
1203{
1204 Q_D(const QQuickControl);
1205 return d->getLeftPadding();
1206}
1207
1208void QQuickControl::setLeftPadding(qreal padding)
1209{
1210 Q_D(QQuickControl);
1211 d->setLeftPadding(value: padding);
1212}
1213
1214void QQuickControl::resetLeftPadding()
1215{
1216 Q_D(QQuickControl);
1217 d->setLeftPadding(value: 0, reset: true);
1218}
1219
1220/*!
1221 \qmlproperty real QtQuick.Controls::Control::rightPadding
1222
1223 This property holds the right padding. Unless explicitly set, the value
1224 is equal to \c horizontalPadding.
1225
1226 \sa {Control Layout}, padding, leftPadding, horizontalPadding, availableWidth
1227*/
1228qreal QQuickControl::rightPadding() const
1229{
1230 Q_D(const QQuickControl);
1231 return d->getRightPadding();
1232}
1233
1234void QQuickControl::setRightPadding(qreal padding)
1235{
1236 Q_D(QQuickControl);
1237 d->setRightPadding(value: padding);
1238}
1239
1240void QQuickControl::resetRightPadding()
1241{
1242 Q_D(QQuickControl);
1243 d->setRightPadding(value: 0, reset: true);
1244}
1245
1246/*!
1247 \qmlproperty real QtQuick.Controls::Control::bottomPadding
1248
1249 This property holds the bottom padding. Unless explicitly set, the value
1250 is equal to \c verticalPadding.
1251
1252 \sa {Control Layout}, padding, topPadding, verticalPadding, availableHeight
1253*/
1254qreal QQuickControl::bottomPadding() const
1255{
1256 Q_D(const QQuickControl);
1257 return d->getBottomPadding();
1258}
1259
1260void QQuickControl::setBottomPadding(qreal padding)
1261{
1262 Q_D(QQuickControl);
1263 d->setBottomPadding(value: padding);
1264}
1265
1266void QQuickControl::resetBottomPadding()
1267{
1268 Q_D(QQuickControl);
1269 d->setBottomPadding(value: 0, reset: true);
1270}
1271
1272/*!
1273 \qmlproperty real QtQuick.Controls::Control::spacing
1274
1275 This property holds the spacing.
1276
1277 Spacing is useful for controls that have multiple or repetitive building
1278 blocks. For example, some styles use spacing to determine the distance
1279 between the text and indicator of \l CheckBox. Spacing is not enforced by
1280 Control, so each style may interpret it differently, and some may ignore it
1281 altogether.
1282*/
1283qreal QQuickControl::spacing() const
1284{
1285 Q_D(const QQuickControl);
1286 return d->spacing;
1287}
1288
1289void QQuickControl::setSpacing(qreal spacing)
1290{
1291 Q_D(QQuickControl);
1292 if (qFuzzyCompare(p1: d->spacing, p2: spacing))
1293 return;
1294
1295 qreal oldSpacing = d->spacing;
1296 d->spacing = spacing;
1297 emit spacingChanged();
1298 spacingChange(newSpacing: spacing, oldSpacing);
1299}
1300
1301void QQuickControl::resetSpacing()
1302{
1303 setSpacing(0);
1304}
1305
1306/*!
1307 \qmlproperty Locale QtQuick.Controls::Control::locale
1308
1309 This property holds the locale of the control.
1310
1311 It contains locale specific properties for formatting data and numbers.
1312 Unless a special locale has been set, this is either the parent's locale
1313 or the default locale.
1314
1315 Control propagates the locale from parent to children. If you change the
1316 control's locale, that locale propagates to all of the control's children,
1317 overriding the system default locale.
1318
1319 \sa mirrored
1320*/
1321QLocale QQuickControl::locale() const
1322{
1323 Q_D(const QQuickControl);
1324 return d->locale;
1325}
1326
1327void QQuickControl::setLocale(const QLocale &locale)
1328{
1329 Q_D(QQuickControl);
1330 if (d->hasLocale && d->locale == locale)
1331 return;
1332
1333 d->updateLocale(l: locale, e: true); // explicit=true
1334}
1335
1336void QQuickControl::resetLocale()
1337{
1338 Q_D(QQuickControl);
1339 if (!d->hasLocale)
1340 return;
1341
1342 d->hasLocale = false;
1343 d->updateLocale(l: QQuickControlPrivate::calcLocale(item: d->parentItem), e: false); // explicit=false
1344}
1345
1346/*!
1347 \qmlproperty bool QtQuick.Controls::Control::mirrored
1348 \readonly
1349
1350 This property holds whether the control is mirrored.
1351
1352 This property is provided for convenience. A control is considered mirrored
1353 when its visual layout direction is right-to-left; that is, when
1354 \l {LayoutMirroring::enabled}{LayoutMirroring.enabled} is \c true.
1355
1356 As of Qt 6.2, the \l locale property no longer affects this property.
1357
1358 \sa {LayoutMirroring}{LayoutMirroring}, {Right-to-left User Interfaces}
1359*/
1360bool QQuickControl::isMirrored() const
1361{
1362 Q_D(const QQuickControl);
1363 return d->isMirrored();
1364}
1365
1366/*!
1367 \qmlproperty enumeration QtQuick.Controls::Control::focusPolicy
1368
1369 This property determines the way the control accepts focus.
1370
1371 \value Qt.TabFocus The control accepts focus by tabbing.
1372 \value Qt.ClickFocus The control accepts focus by clicking.
1373 \value Qt.StrongFocus The control accepts focus by both tabbing and clicking.
1374 \value Qt.WheelFocus The control accepts focus by tabbing, clicking, and using the mouse wheel.
1375 \value Qt.NoFocus The control does not accept focus.
1376*/
1377Qt::FocusPolicy QQuickControl::focusPolicy() const
1378{
1379 Q_D(const QQuickControl);
1380 uint policy = d->focusPolicy;
1381 if (activeFocusOnTab())
1382 policy |= Qt::TabFocus;
1383 return static_cast<Qt::FocusPolicy>(policy);
1384}
1385
1386void QQuickControl::setFocusPolicy(Qt::FocusPolicy policy)
1387{
1388 Q_D(QQuickControl);
1389 if (d->focusPolicy == policy)
1390 return;
1391
1392 d->focusPolicy = policy;
1393 setActiveFocusOnTab(policy & Qt::TabFocus);
1394 emit focusPolicyChanged();
1395}
1396
1397/*!
1398 \qmlproperty enumeration QtQuick.Controls::Control::focusReason
1399 \readonly
1400
1401 \include qquickcontrol-focusreason.qdocinc
1402
1403 \sa visualFocus
1404*/
1405Qt::FocusReason QQuickControl::focusReason() const
1406{
1407 Q_D(const QQuickControl);
1408 return d->focusReason;
1409}
1410
1411void QQuickControl::setFocusReason(Qt::FocusReason reason)
1412{
1413 Q_D(QQuickControl);
1414 if (d->focusReason == reason)
1415 return;
1416
1417 Qt::FocusReason oldReason = d->focusReason;
1418 d->focusReason = reason;
1419 emit focusReasonChanged();
1420 if (isKeyFocusReason(reason: oldReason) != isKeyFocusReason(reason))
1421 emit visualFocusChanged();
1422}
1423
1424/*!
1425 \qmlproperty bool QtQuick.Controls::Control::visualFocus
1426 \readonly
1427
1428 This property holds whether the control has visual focus. This property
1429 is \c true when the control has active focus and the focus reason is either
1430 \c Qt.TabFocusReason, \c Qt.BacktabFocusReason, or \c Qt.ShortcutFocusReason.
1431
1432 In general, for visualizing key focus, this property is preferred over
1433 \l Item::activeFocus. This ensures that key focus is only visualized when
1434 interacting with keys - not when interacting via touch or mouse.
1435
1436 \sa focusReason, Item::activeFocus
1437*/
1438bool QQuickControl::hasVisualFocus() const
1439{
1440 Q_D(const QQuickControl);
1441 return d->activeFocus && isKeyFocusReason(reason: d->focusReason);
1442}
1443
1444/*!
1445 \qmlproperty bool QtQuick.Controls::Control::hovered
1446 \readonly
1447
1448 This property holds whether the control is hovered.
1449
1450 \sa hoverEnabled
1451*/
1452bool QQuickControl::isHovered() const
1453{
1454#if QT_CONFIG(quicktemplates2_hover)
1455 Q_D(const QQuickControl);
1456 return d->hovered;
1457#else
1458 return false;
1459#endif
1460}
1461
1462void QQuickControl::setHovered(bool hovered)
1463{
1464#if QT_CONFIG(quicktemplates2_hover)
1465 Q_D(QQuickControl);
1466 if (hovered == d->hovered)
1467 return;
1468
1469 d->hovered = hovered;
1470 emit hoveredChanged();
1471 hoverChange();
1472#else
1473 Q_UNUSED(hovered);
1474#endif
1475}
1476
1477/*!
1478 \qmlproperty bool QtQuick.Controls::Control::hoverEnabled
1479
1480 This property determines whether the control accepts hover events. The default value
1481 is \c Qt.styleHints.useHoverEffects.
1482
1483 Setting this property propagates the value to all child controls that do not have
1484 \c hoverEnabled explicitly set.
1485
1486 You can also enable or disable hover effects for all Qt Quick Controls applications
1487 by setting the \c QT_QUICK_CONTROLS_HOVER_ENABLED \l {Supported Environment Variables
1488 in Qt Quick Controls}{environment variable}.
1489
1490 \sa hovered
1491*/
1492bool QQuickControl::isHoverEnabled() const
1493{
1494#if QT_CONFIG(quicktemplates2_hover)
1495 Q_D(const QQuickControl);
1496 return d->hoverEnabled;
1497#else
1498 return false;
1499#endif
1500}
1501
1502void QQuickControl::setHoverEnabled(bool enabled)
1503{
1504#if QT_CONFIG(quicktemplates2_hover)
1505 Q_D(QQuickControl);
1506 if (d->explicitHoverEnabled && enabled == d->hoverEnabled)
1507 return;
1508
1509 d->updateHoverEnabled(enabled, xplicit: true); // explicit=true
1510#else
1511 Q_UNUSED(enabled);
1512#endif
1513}
1514
1515void QQuickControl::resetHoverEnabled()
1516{
1517#if QT_CONFIG(quicktemplates2_hover)
1518 Q_D(QQuickControl);
1519 if (!d->explicitHoverEnabled)
1520 return;
1521
1522 d->explicitHoverEnabled = false;
1523 d->updateHoverEnabled(enabled: QQuickControlPrivate::calcHoverEnabled(item: d->parentItem), xplicit: false); // explicit=false
1524#endif
1525}
1526
1527/*!
1528 \qmlproperty bool QtQuick.Controls::Control::wheelEnabled
1529
1530 This property determines whether the control handles wheel events. The default value is \c false.
1531
1532 \note Care must be taken when enabling wheel events for controls within scrollable items such
1533 as \l Flickable, as the control will consume the events and hence interrupt scrolling of the
1534 Flickable.
1535*/
1536bool QQuickControl::isWheelEnabled() const
1537{
1538 Q_D(const QQuickControl);
1539 return d->wheelEnabled;
1540}
1541
1542void QQuickControl::setWheelEnabled(bool enabled)
1543{
1544 Q_D(QQuickControl);
1545 if (d->wheelEnabled == enabled)
1546 return;
1547
1548 d->wheelEnabled = enabled;
1549 emit wheelEnabledChanged();
1550}
1551
1552/*!
1553 \qmlproperty Item QtQuick.Controls::Control::background
1554
1555 This property holds the background item.
1556
1557 \code
1558 Button {
1559 id: control
1560 text: qsTr("Button")
1561 background: Rectangle {
1562 implicitWidth: 100
1563 implicitHeight: 40
1564 opacity: enabled ? 1 : 0.3
1565 color: control.down ? "#d0d0d0" : "#e0e0e0"
1566 }
1567 }
1568 \endcode
1569
1570 \input qquickcontrol-background.qdocinc notes
1571
1572 \sa {Control Layout}
1573*/
1574QQuickItem *QQuickControl::background() const
1575{
1576 QQuickControlPrivate *d = const_cast<QQuickControlPrivate *>(d_func());
1577 if (!d->background)
1578 d->executeBackground();
1579 return d->background;
1580}
1581
1582void QQuickControl::setBackground(QQuickItem *background)
1583{
1584 Q_D(QQuickControl);
1585 if (d->background == background)
1586 return;
1587
1588 QQuickControlPrivate::warnIfCustomizationNotSupported(control: this, item: background, QStringLiteral("background"));
1589
1590 if (!d->background.isExecuting())
1591 d->cancelBackground();
1592
1593 const qreal oldImplicitBackgroundWidth = implicitBackgroundWidth();
1594 const qreal oldImplicitBackgroundHeight = implicitBackgroundHeight();
1595
1596 if (d->extra.isAllocated()) {
1597 d->extra.value().hasBackgroundWidth = false;
1598 d->extra.value().hasBackgroundHeight = false;
1599 }
1600
1601 d->removeImplicitSizeListener(item: d->background, changes: QQuickControlPrivate::ImplicitSizeChanges | QQuickItemPrivate::Geometry);
1602 QQuickControlPrivate::hideOldItem(item: d->background);
1603 d->background = background;
1604
1605 if (background) {
1606 background->setParentItem(this);
1607 if (qFuzzyIsNull(d: background->z()))
1608 background->setZ(-1);
1609 QQuickItemPrivate *p = QQuickItemPrivate::get(item: background);
1610 if (p->widthValid() || p->heightValid()) {
1611 d->extra.value().hasBackgroundWidth = p->widthValid();
1612 d->extra.value().hasBackgroundHeight = p->heightValid();
1613 }
1614 if (isComponentComplete())
1615 d->resizeBackground();
1616 d->addImplicitSizeListener(item: background, changes: QQuickControlPrivate::ImplicitSizeChanges | QQuickItemPrivate::Geometry);
1617 }
1618
1619 if (!qFuzzyCompare(p1: oldImplicitBackgroundWidth, p2: implicitBackgroundWidth()))
1620 emit implicitBackgroundWidthChanged();
1621 if (!qFuzzyCompare(p1: oldImplicitBackgroundHeight, p2: implicitBackgroundHeight()))
1622 emit implicitBackgroundHeightChanged();
1623 if (!d->background.isExecuting())
1624 emit backgroundChanged();
1625}
1626
1627/*!
1628 \qmlproperty Item QtQuick.Controls::Control::contentItem
1629
1630 This property holds the visual content item.
1631
1632 \code
1633 Button {
1634 id: control
1635 text: qsTr("Button")
1636 contentItem: Label {
1637 text: control.text
1638 verticalAlignment: Text.AlignVCenter
1639 }
1640 }
1641 \endcode
1642
1643 \note The content item is automatically positioned and resized to fit
1644 within the \l padding of the control. Bindings to the
1645 \l[QtQuick]{Item::}{x}, \l[QtQuick]{Item::}{y},
1646 \l[QtQuick]{Item::}{width}, and \l[QtQuick]{Item::}{height}
1647 properties of the contentItem are not respected.
1648
1649 \note Most controls use the implicit size of the content item to calculate
1650 the implicit size of the control itself. If you replace the content item
1651 with a custom one, you should also consider providing a sensible implicit
1652 size for it (unless it is an item like \l Text which has its own implicit
1653 size).
1654
1655 \sa {Control Layout}, padding
1656*/
1657QQuickItem *QQuickControl::contentItem() const
1658{
1659 QQuickControlPrivate *d = const_cast<QQuickControlPrivate *>(d_func());
1660 if (!d->contentItem)
1661 d->setContentItem_helper(item: d->getContentItem(), notify: false);
1662 return d->contentItem;
1663}
1664
1665void QQuickControl::setContentItem(QQuickItem *item)
1666{
1667 Q_D(QQuickControl);
1668 d->setContentItem_helper(item, notify: true);
1669}
1670
1671qreal QQuickControl::baselineOffset() const
1672{
1673 Q_D(const QQuickControl);
1674 return d->baselineOffset;
1675}
1676
1677void QQuickControl::setBaselineOffset(qreal offset)
1678{
1679 Q_D(QQuickControl);
1680 d->extra.value().hasBaselineOffset = true;
1681 QQuickItem::setBaselineOffset(offset);
1682}
1683
1684void QQuickControl::resetBaselineOffset()
1685{
1686 Q_D(QQuickControl);
1687 if (!d->extra.isAllocated() || !d->extra.value().hasBaselineOffset)
1688 return;
1689
1690 if (d->extra.isAllocated())
1691 d->extra.value().hasBaselineOffset = false;
1692 d->updateBaselineOffset();
1693}
1694
1695/*!
1696 \since QtQuick.Controls 2.5 (Qt 5.12)
1697 \qmlproperty real QtQuick.Controls::Control::horizontalPadding
1698
1699 This property holds the horizontal padding. Unless explicitly set, the value
1700 is equal to \c padding.
1701
1702 \sa {Control Layout}, padding, leftPadding, rightPadding, verticalPadding
1703*/
1704qreal QQuickControl::horizontalPadding() const
1705{
1706 Q_D(const QQuickControl);
1707 return d->getHorizontalPadding();
1708}
1709
1710void QQuickControl::setHorizontalPadding(qreal padding)
1711{
1712 Q_D(QQuickControl);
1713 d->setHorizontalPadding(value: padding);
1714}
1715
1716void QQuickControl::resetHorizontalPadding()
1717{
1718 Q_D(QQuickControl);
1719 d->setHorizontalPadding(value: 0, reset: true);
1720}
1721
1722/*!
1723 \since QtQuick.Controls 2.5 (Qt 5.12)
1724 \qmlproperty real QtQuick.Controls::Control::verticalPadding
1725
1726 This property holds the vertical padding. Unless explicitly set, the value
1727 is equal to \c padding.
1728
1729 \sa {Control Layout}, padding, topPadding, bottomPadding, horizontalPadding
1730*/
1731qreal QQuickControl::verticalPadding() const
1732{
1733 Q_D(const QQuickControl);
1734 return d->getVerticalPadding();
1735}
1736
1737void QQuickControl::setVerticalPadding(qreal padding)
1738{
1739 Q_D(QQuickControl);
1740 d->setVerticalPadding(value: padding);
1741}
1742
1743void QQuickControl::resetVerticalPadding()
1744{
1745 Q_D(QQuickControl);
1746 d->setVerticalPadding(value: 0, reset: true);
1747}
1748
1749/*!
1750 \since QtQuick.Controls 2.5 (Qt 5.12)
1751 \qmlproperty real QtQuick.Controls::Control::implicitContentWidth
1752 \readonly
1753
1754 This property holds the implicit content width.
1755
1756 For basic controls, the value is equal to \c {contentItem ? contentItem.implicitWidth : 0}.
1757 For types that inherit Container or Pane, the value is calculated based on the content children.
1758
1759 This is typically used, together with \l implicitBackgroundWidth, to calculate
1760 the \l {Item::}{implicitWidth}:
1761
1762 \code
1763 Control {
1764 implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
1765 implicitContentWidth + leftPadding + rightPadding)
1766 }
1767 \endcode
1768
1769 \sa implicitContentHeight, implicitBackgroundWidth
1770*/
1771qreal QQuickControl::implicitContentWidth() const
1772{
1773 Q_D(const QQuickControl);
1774 return d->implicitContentWidth;
1775}
1776
1777/*!
1778 \since QtQuick.Controls 2.5 (Qt 5.12)
1779 \qmlproperty real QtQuick.Controls::Control::implicitContentHeight
1780 \readonly
1781
1782 This property holds the implicit content height.
1783
1784 For basic controls, the value is equal to \c {contentItem ? contentItem.implicitHeight : 0}.
1785 For types that inherit Container or Pane, the value is calculated based on the content children.
1786
1787 This is typically used, together with \l implicitBackgroundHeight, to calculate
1788 the \l {Item::}{implicitHeight}:
1789
1790 \code
1791 Control {
1792 implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
1793 implicitContentHeight + topPadding + bottomPadding)
1794 }
1795 \endcode
1796
1797 \sa implicitContentWidth, implicitBackgroundHeight
1798*/
1799qreal QQuickControl::implicitContentHeight() const
1800{
1801 Q_D(const QQuickControl);
1802 return d->implicitContentHeight;
1803}
1804
1805/*!
1806 \since QtQuick.Controls 2.5 (Qt 5.12)
1807 \qmlproperty real QtQuick.Controls::Control::implicitBackgroundWidth
1808 \readonly
1809
1810 This property holds the implicit background width.
1811
1812 The value is equal to \c {background ? background.implicitWidth : 0}.
1813
1814 This is typically used, together with \l implicitContentWidth, to calculate
1815 the \l {Item::}{implicitWidth}:
1816
1817 \code
1818 Control {
1819 implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
1820 implicitContentWidth + leftPadding + rightPadding)
1821 }
1822 \endcode
1823
1824 \sa implicitBackgroundHeight, implicitContentWidth
1825*/
1826qreal QQuickControl::implicitBackgroundWidth() const
1827{
1828 Q_D(const QQuickControl);
1829 if (!d->background)
1830 return 0;
1831 return d->background->implicitWidth();
1832}
1833
1834/*!
1835 \since QtQuick.Controls 2.5 (Qt 5.12)
1836 \qmlproperty real QtQuick.Controls::Control::implicitBackgroundHeight
1837 \readonly
1838
1839 This property holds the implicit background height.
1840
1841 The value is equal to \c {background ? background.implicitHeight : 0}.
1842
1843 This is typically used, together with \l implicitContentHeight, to calculate
1844 the \l {Item::}{implicitHeight}:
1845
1846 \code
1847 Control {
1848 implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
1849 implicitContentHeight + topPadding + bottomPadding)
1850 }
1851 \endcode
1852
1853 \sa implicitBackgroundWidth, implicitContentHeight
1854*/
1855qreal QQuickControl::implicitBackgroundHeight() const
1856{
1857 Q_D(const QQuickControl);
1858 if (!d->background)
1859 return 0;
1860 return d->background->implicitHeight();
1861}
1862
1863/*!
1864 \since QtQuick.Controls 2.5 (Qt 5.12)
1865 \qmlproperty real QtQuick.Controls::Control::topInset
1866
1867 This property holds the top inset for the background.
1868
1869 \sa {Control Layout}, bottomInset
1870*/
1871qreal QQuickControl::topInset() const
1872{
1873 Q_D(const QQuickControl);
1874 return d->getTopInset();
1875}
1876
1877void QQuickControl::setTopInset(qreal inset)
1878{
1879 Q_D(QQuickControl);
1880 d->setTopInset(value: inset);
1881}
1882
1883void QQuickControl::resetTopInset()
1884{
1885 Q_D(QQuickControl);
1886 d->setTopInset(value: 0, reset: true);
1887}
1888
1889/*!
1890 \since QtQuick.Controls 2.5 (Qt 5.12)
1891 \qmlproperty real QtQuick.Controls::Control::leftInset
1892
1893 This property holds the left inset for the background.
1894
1895 \sa {Control Layout}, rightInset
1896*/
1897qreal QQuickControl::leftInset() const
1898{
1899 Q_D(const QQuickControl);
1900 return d->getLeftInset();
1901}
1902
1903void QQuickControl::setLeftInset(qreal inset)
1904{
1905 Q_D(QQuickControl);
1906 d->setLeftInset(value: inset);
1907}
1908
1909void QQuickControl::resetLeftInset()
1910{
1911 Q_D(QQuickControl);
1912 d->setLeftInset(value: 0, reset: true);
1913}
1914
1915/*!
1916 \since QtQuick.Controls 2.5 (Qt 5.12)
1917 \qmlproperty real QtQuick.Controls::Control::rightInset
1918
1919 This property holds the right inset for the background.
1920
1921 \sa {Control Layout}, leftInset
1922*/
1923qreal QQuickControl::rightInset() const
1924{
1925 Q_D(const QQuickControl);
1926 return d->getRightInset();
1927}
1928
1929void QQuickControl::setRightInset(qreal inset)
1930{
1931 Q_D(QQuickControl);
1932 d->setRightInset(value: inset);
1933}
1934
1935void QQuickControl::resetRightInset()
1936{
1937 Q_D(QQuickControl);
1938 d->setRightInset(value: 0, reset: true);
1939}
1940
1941/*!
1942 \since QtQuick.Controls 2.5 (Qt 5.12)
1943 \qmlproperty real QtQuick.Controls::Control::bottomInset
1944
1945 This property holds the bottom inset for the background.
1946
1947 \sa {Control Layout}, topInset
1948*/
1949qreal QQuickControl::bottomInset() const
1950{
1951 Q_D(const QQuickControl);
1952 return d->getBottomInset();
1953}
1954
1955void QQuickControl::setBottomInset(qreal inset)
1956{
1957 Q_D(QQuickControl);
1958 d->setBottomInset(value: inset);
1959}
1960
1961void QQuickControl::resetBottomInset()
1962{
1963 Q_D(QQuickControl);
1964 d->setBottomInset(value: 0, reset: true);
1965}
1966
1967void QQuickControl::classBegin()
1968{
1969 Q_D(QQuickControl);
1970 QQuickItem::classBegin();
1971 d->resolveFont();
1972}
1973
1974void QQuickControl::componentComplete()
1975{
1976 Q_D(QQuickControl);
1977 d->executeBackground(complete: true);
1978 d->executeContentItem(complete: true);
1979 QQuickItem::componentComplete();
1980 d->resizeBackground();
1981 d->resizeContent();
1982 d->updateBaselineOffset();
1983 if (!d->hasLocale)
1984 d->locale = QQuickControlPrivate::calcLocale(item: d->parentItem);
1985#if QT_CONFIG(quicktemplates2_hover)
1986 if (!d->explicitHoverEnabled)
1987 setAcceptHoverEvents(QQuickControlPrivate::calcHoverEnabled(item: d->parentItem));
1988#endif
1989#if QT_CONFIG(accessibility)
1990 if (QAccessible::isActive())
1991 accessibilityActiveChanged(active: true);
1992#endif
1993}
1994
1995QFont QQuickControl::defaultFont() const
1996{
1997 return QQuickTheme::font(scope: QQuickTheme::System);
1998}
1999
2000void QQuickControl::focusInEvent(QFocusEvent *event)
2001{
2002 QQuickItem::focusInEvent(event);
2003 setFocusReason(event->reason());
2004}
2005
2006void QQuickControl::focusOutEvent(QFocusEvent *event)
2007{
2008 QQuickItem::focusOutEvent(event);
2009 setFocusReason(event->reason());
2010}
2011
2012#if QT_CONFIG(quicktemplates2_hover)
2013void QQuickControl::hoverEnterEvent(QHoverEvent *event)
2014{
2015 Q_D(QQuickControl);
2016 setHovered(d->hoverEnabled);
2017 event->ignore();
2018}
2019
2020void QQuickControl::hoverMoveEvent(QHoverEvent *event)
2021{
2022 Q_D(QQuickControl);
2023 setHovered(d->hoverEnabled && contains(point: event->position()));
2024 event->ignore();
2025}
2026
2027void QQuickControl::hoverLeaveEvent(QHoverEvent *event)
2028{
2029 setHovered(false);
2030 event->ignore();
2031}
2032#endif
2033
2034void QQuickControl::mousePressEvent(QMouseEvent *event)
2035{
2036 Q_D(QQuickControl);
2037 event->setAccepted(d->handlePress(event->position(), event->timestamp()));
2038}
2039
2040void QQuickControl::mouseMoveEvent(QMouseEvent *event)
2041{
2042 Q_D(QQuickControl);
2043 event->setAccepted(d->handleMove(point: event->position(), event->timestamp()));
2044}
2045
2046void QQuickControl::mouseReleaseEvent(QMouseEvent *event)
2047{
2048 Q_D(QQuickControl);
2049 event->setAccepted(d->handleRelease(event->position(), event->timestamp()));
2050}
2051
2052void QQuickControl::mouseUngrabEvent()
2053{
2054 Q_D(QQuickControl);
2055 d->handleUngrab();
2056}
2057
2058#if QT_CONFIG(quicktemplates2_multitouch)
2059void QQuickControl::touchEvent(QTouchEvent *event)
2060{
2061 Q_D(QQuickControl);
2062 switch (event->type()) {
2063 case QEvent::TouchBegin:
2064 case QEvent::TouchUpdate:
2065 case QEvent::TouchEnd:
2066 for (const QTouchEvent::TouchPoint &point : event->points()) {
2067 if (!d->acceptTouch(point))
2068 continue;
2069
2070 switch (point.state()) {
2071 case QEventPoint::Pressed:
2072 d->handlePress(point.position(), event->timestamp());
2073 break;
2074 case QEventPoint::Updated:
2075 d->handleMove(point: point.position(), event->timestamp());
2076 break;
2077 case QEventPoint::Released:
2078 d->handleRelease(point.position(), event->timestamp());
2079 break;
2080 default:
2081 break;
2082 }
2083 }
2084 break;
2085
2086 case QEvent::TouchCancel:
2087 d->handleUngrab();
2088 break;
2089
2090 default:
2091 QQuickItem::touchEvent(event);
2092 break;
2093 }
2094}
2095
2096void QQuickControl::touchUngrabEvent()
2097{
2098 Q_D(QQuickControl);
2099 d->handleUngrab();
2100}
2101#endif
2102
2103#if QT_CONFIG(wheelevent)
2104void QQuickControl::wheelEvent(QWheelEvent *event)
2105{
2106 Q_D(QQuickControl);
2107 if ((d->focusPolicy & Qt::WheelFocus) == Qt::WheelFocus)
2108 setActiveFocus(control: this, reason: Qt::MouseFocusReason);
2109
2110 event->setAccepted(d->wheelEnabled);
2111}
2112#endif
2113
2114void QQuickControl::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry)
2115{
2116 Q_D(QQuickControl);
2117 QQuickItem::geometryChange(newGeometry, oldGeometry);
2118 d->resizeBackground();
2119 d->resizeContent();
2120 if (!qFuzzyCompare(p1: newGeometry.width(), p2: oldGeometry.width()))
2121 emit availableWidthChanged();
2122 if (!qFuzzyCompare(p1: newGeometry.height(), p2: oldGeometry.height()))
2123 emit availableHeightChanged();
2124}
2125
2126void QQuickControl::enabledChange()
2127{
2128}
2129
2130void QQuickControl::fontChange(const QFont &newFont, const QFont &oldFont)
2131{
2132 Q_UNUSED(newFont);
2133 Q_UNUSED(oldFont);
2134}
2135
2136#if QT_CONFIG(quicktemplates2_hover)
2137void QQuickControl::hoverChange()
2138{
2139}
2140#endif
2141
2142void QQuickControl::mirrorChange()
2143{
2144 emit mirroredChanged();
2145}
2146
2147void QQuickControl::spacingChange(qreal newSpacing, qreal oldSpacing)
2148{
2149 Q_UNUSED(newSpacing);
2150 Q_UNUSED(oldSpacing);
2151}
2152
2153void QQuickControl::paddingChange(const QMarginsF &newPadding, const QMarginsF &oldPadding)
2154{
2155 Q_D(QQuickControl);
2156 Q_UNUSED(newPadding);
2157 Q_UNUSED(oldPadding);
2158 d->resizeContent();
2159 d->updateBaselineOffset();
2160}
2161
2162void QQuickControl::contentItemChange(QQuickItem *newItem, QQuickItem *oldItem)
2163{
2164 Q_UNUSED(newItem);
2165 Q_UNUSED(oldItem);
2166}
2167
2168void QQuickControl::localeChange(const QLocale &newLocale, const QLocale &oldLocale)
2169{
2170 Q_UNUSED(newLocale);
2171 Q_UNUSED(oldLocale);
2172}
2173
2174void QQuickControl::insetChange(const QMarginsF &newInset, const QMarginsF &oldInset)
2175{
2176 Q_D(QQuickControl);
2177 Q_UNUSED(newInset);
2178 Q_UNUSED(oldInset);
2179 d->resizeBackground();
2180}
2181
2182#if QT_CONFIG(accessibility)
2183QAccessible::Role QQuickControl::accessibleRole() const
2184{
2185 return QAccessible::NoRole;
2186}
2187
2188void QQuickControl::accessibilityActiveChanged(bool active)
2189{
2190 Q_D(QQuickControl);
2191 if (!active)
2192 return;
2193
2194 QQuickAccessibleAttached *accessibleAttached = qobject_cast<QQuickAccessibleAttached *>(object: qmlAttachedPropertiesObject<QQuickAccessibleAttached>(obj: this, create: true));
2195 Q_ASSERT(accessibleAttached);
2196 accessibleAttached->setRole(d->effectiveAccessibleRole());
2197}
2198#endif
2199
2200QString QQuickControl::accessibleName() const
2201{
2202#if QT_CONFIG(accessibility)
2203 if (QQuickAccessibleAttached *accessibleAttached = QQuickControlPrivate::accessibleAttached(object: this))
2204 return accessibleAttached->name();
2205#endif
2206 return QString();
2207}
2208
2209void QQuickControl::maybeSetAccessibleName(const QString &name)
2210{
2211#if QT_CONFIG(accessibility)
2212 if (QQuickAccessibleAttached *accessibleAttached = QQuickControlPrivate::accessibleAttached(object: this)) {
2213 if (!accessibleAttached->wasNameExplicitlySet())
2214 accessibleAttached->setNameImplicitly(name);
2215 }
2216#else
2217 Q_UNUSED(name);
2218#endif
2219}
2220
2221QVariant QQuickControl::accessibleProperty(const char *propertyName)
2222{
2223#if QT_CONFIG(accessibility)
2224 if (QAccessible::isActive())
2225 return QQuickAccessibleAttached::property(object: this, propertyName);
2226#endif
2227 Q_UNUSED(propertyName);
2228 return QVariant();
2229}
2230
2231bool QQuickControl::setAccessibleProperty(const char *propertyName, const QVariant &value)
2232{
2233#if QT_CONFIG(accessibility)
2234 if (QAccessible::isActive())
2235 return QQuickAccessibleAttached::setProperty(object: this, propertyName, value);
2236#endif
2237 Q_UNUSED(propertyName);
2238 Q_UNUSED(value);
2239 return false;
2240}
2241
2242QT_END_NAMESPACE
2243
2244#include "moc_qquickcontrol_p.cpp"
2245

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