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