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