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