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