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.value().requestedFont.resolveMask());
1049 return font;
1050}
1051
1052void QQuickControl::setFont(const QFont &font)
1053{
1054 Q_D(QQuickControl);
1055 if (d->extra.value().requestedFont.resolveMask() == font.resolveMask() && d->extra.value().requestedFont == font)
1056 return;
1057
1058 d->extra.value().requestedFont = font;
1059 d->resolveFont();
1060}
1061
1062void QQuickControl::resetFont()
1063{
1064 setFont(QFont());
1065}
1066
1067/*!
1068 \qmlproperty real QtQuick.Controls::Control::availableWidth
1069 \readonly
1070
1071 This property holds the width available to the \l contentItem after
1072 deducting horizontal padding from the \l {Item::}{width} of the control.
1073
1074 \sa {Control Layout}, padding, leftPadding, rightPadding
1075*/
1076qreal QQuickControl::availableWidth() const
1077{
1078 return qMax<qreal>(0.0, width() - leftPadding() - rightPadding());
1079}
1080
1081/*!
1082 \qmlproperty real QtQuick.Controls::Control::availableHeight
1083 \readonly
1084
1085 This property holds the height available to the \l contentItem after
1086 deducting vertical padding from the \l {Item::}{height} of the control.
1087
1088 \sa {Control Layout}, padding, topPadding, bottomPadding
1089*/
1090qreal QQuickControl::availableHeight() const
1091{
1092 return qMax<qreal>(0.0, height() - topPadding() - bottomPadding());
1093}
1094
1095/*!
1096 \qmlproperty real QtQuick.Controls::Control::padding
1097
1098 This property holds the default padding.
1099
1100 Padding adds a space between each edge of the content item and the
1101 background item, effectively controlling the size of the content item. To
1102 specify a padding value for a specific edge of the control, set its
1103 relevant property:
1104
1105 \list
1106 \li \l {Control::}{leftPadding}
1107 \li \l {Control::}{rightPadding}
1108 \li \l {Control::}{topPadding}
1109 \li \l {Control::}{bottomPadding}
1110 \endlist
1111
1112 \note Different styles may specify the default padding for certain controls
1113 in different ways, and these ways may change over time as the design
1114 guidelines that the style is based on evolve. To ensure that these changes
1115 don't affect the padding values you have specified, it is best to use the
1116 most specific properties available. For example, rather than setting
1117 the \l padding property:
1118
1119 \code
1120 padding: 0
1121 \endcode
1122
1123 set each specific property instead:
1124
1125 \code
1126 leftPadding: 0
1127 rightPadding: 0
1128 topPadding: 0
1129 bottomPadding: 0
1130 \endcode
1131
1132 \sa {Control Layout}, availableWidth, availableHeight, topPadding, leftPadding, rightPadding, bottomPadding
1133*/
1134qreal QQuickControl::padding() const
1135{
1136 Q_D(const QQuickControl);
1137 return d->padding;
1138}
1139
1140void QQuickControl::setPadding(qreal padding)
1141{
1142 Q_D(QQuickControl);
1143 if (qFuzzyCompare(d->padding, padding))
1144 return;
1145
1146 const QMarginsF oldPadding = d->getPadding();
1147 const qreal oldVerticalPadding = d->getVerticalPadding();
1148 const qreal oldHorizontalPadding = d->getHorizontalPadding();
1149
1150 d->padding = padding;
1151 emit paddingChanged();
1152
1153 const QMarginsF newPadding = d->getPadding();
1154 const qreal newVerticalPadding = d->getVerticalPadding();
1155 const qreal newHorizontalPadding = d->getHorizontalPadding();
1156
1157 if (!qFuzzyCompare(newPadding.top(), oldPadding.top()))
1158 emit topPaddingChanged();
1159 if (!qFuzzyCompare(newPadding.left(), oldPadding.left()))
1160 emit leftPaddingChanged();
1161 if (!qFuzzyCompare(newPadding.right(), oldPadding.right()))
1162 emit rightPaddingChanged();
1163 if (!qFuzzyCompare(newPadding.bottom(), oldPadding.bottom()))
1164 emit bottomPaddingChanged();
1165 if (!qFuzzyCompare(newVerticalPadding, oldVerticalPadding))
1166 emit verticalPaddingChanged();
1167 if (!qFuzzyCompare(newHorizontalPadding, oldHorizontalPadding))
1168 emit horizontalPaddingChanged();
1169 if (!qFuzzyCompare(newPadding.top(), oldPadding.top()) || !qFuzzyCompare(newPadding.bottom(), oldPadding.bottom()))
1170 emit availableHeightChanged();
1171 if (!qFuzzyCompare(newPadding.left(), oldPadding.left()) || !qFuzzyCompare(newPadding.right(), oldPadding.right()))
1172 emit availableWidthChanged();
1173
1174 paddingChange(newPadding, oldPadding);
1175}
1176
1177void QQuickControl::resetPadding()
1178{
1179 setPadding(0);
1180}
1181
1182/*!
1183 \qmlproperty real QtQuick.Controls::Control::topPadding
1184
1185 This property holds the top padding. Unless explicitly set, the value
1186 is equal to \c verticalPadding.
1187
1188 \sa {Control Layout}, padding, bottomPadding, verticalPadding, availableHeight
1189*/
1190qreal QQuickControl::topPadding() const
1191{
1192 Q_D(const QQuickControl);
1193 return d->getTopPadding();
1194}
1195
1196void QQuickControl::setTopPadding(qreal padding)
1197{
1198 Q_D(QQuickControl);
1199 d->setTopPadding(padding);
1200}
1201
1202void QQuickControl::resetTopPadding()
1203{
1204 Q_D(QQuickControl);
1205 d->setTopPadding(0, true);
1206}
1207
1208/*!
1209 \qmlproperty real QtQuick.Controls::Control::leftPadding
1210
1211 This property holds the left padding. Unless explicitly set, the value
1212 is equal to \c horizontalPadding.
1213
1214 \sa {Control Layout}, padding, rightPadding, horizontalPadding, availableWidth
1215*/
1216qreal QQuickControl::leftPadding() const
1217{
1218 Q_D(const QQuickControl);
1219 return d->getLeftPadding();
1220}
1221
1222void QQuickControl::setLeftPadding(qreal padding)
1223{
1224 Q_D(QQuickControl);
1225 d->setLeftPadding(padding);
1226}
1227
1228void QQuickControl::resetLeftPadding()
1229{
1230 Q_D(QQuickControl);
1231 d->setLeftPadding(0, true);
1232}
1233
1234/*!
1235 \qmlproperty real QtQuick.Controls::Control::rightPadding
1236
1237 This property holds the right padding. Unless explicitly set, the value
1238 is equal to \c horizontalPadding.
1239
1240 \sa {Control Layout}, padding, leftPadding, horizontalPadding, availableWidth
1241*/
1242qreal QQuickControl::rightPadding() const
1243{
1244 Q_D(const QQuickControl);
1245 return d->getRightPadding();
1246}
1247
1248void QQuickControl::setRightPadding(qreal padding)
1249{
1250 Q_D(QQuickControl);
1251 d->setRightPadding(padding);
1252}
1253
1254void QQuickControl::resetRightPadding()
1255{
1256 Q_D(QQuickControl);
1257 d->setRightPadding(0, true);
1258}
1259
1260/*!
1261 \qmlproperty real QtQuick.Controls::Control::bottomPadding
1262
1263 This property holds the bottom padding. Unless explicitly set, the value
1264 is equal to \c verticalPadding.
1265
1266 \sa {Control Layout}, padding, topPadding, verticalPadding, availableHeight
1267*/
1268qreal QQuickControl::bottomPadding() const
1269{
1270 Q_D(const QQuickControl);
1271 return d->getBottomPadding();
1272}
1273
1274void QQuickControl::setBottomPadding(qreal padding)
1275{
1276 Q_D(QQuickControl);
1277 d->setBottomPadding(padding);
1278}
1279
1280void QQuickControl::resetBottomPadding()
1281{
1282 Q_D(QQuickControl);
1283 d->setBottomPadding(0, true);
1284}
1285
1286/*!
1287 \qmlproperty real QtQuick.Controls::Control::spacing
1288
1289 This property holds the spacing.
1290
1291 Spacing is useful for controls that have multiple or repetitive building
1292 blocks. For example, some styles use spacing to determine the distance
1293 between the text and indicator of \l CheckBox. Spacing is not enforced by
1294 Control, so each style may interpret it differently, and some may ignore it
1295 altogether.
1296*/
1297qreal QQuickControl::spacing() const
1298{
1299 Q_D(const QQuickControl);
1300 return d->spacing;
1301}
1302
1303void QQuickControl::setSpacing(qreal spacing)
1304{
1305 Q_D(QQuickControl);
1306 if (qFuzzyCompare(d->spacing, spacing))
1307 return;
1308
1309 qreal oldSpacing = d->spacing;
1310 d->spacing = spacing;
1311 emit spacingChanged();
1312 spacingChange(spacing, oldSpacing);
1313}
1314
1315void QQuickControl::resetSpacing()
1316{
1317 setSpacing(0);
1318}
1319
1320/*!
1321 \qmlproperty Locale QtQuick.Controls::Control::locale
1322
1323 This property holds the locale of the control.
1324
1325 It contains locale specific properties for formatting data and numbers.
1326 Unless a special locale has been set, this is either the parent's locale
1327 or the default locale.
1328
1329 Control propagates the locale from parent to children. If you change the
1330 control's locale, that locale propagates to all of the control's children,
1331 overriding the system default locale.
1332
1333 \sa mirrored
1334*/
1335QLocale QQuickControl::locale() const
1336{
1337 Q_D(const QQuickControl);
1338 return d->locale;
1339}
1340
1341void QQuickControl::setLocale(const QLocale &locale)
1342{
1343 Q_D(QQuickControl);
1344 if (d->hasLocale && d->locale == locale)
1345 return;
1346
1347 d->updateLocale(locale, true); // explicit=true
1348}
1349
1350void QQuickControl::resetLocale()
1351{
1352 Q_D(QQuickControl);
1353 if (!d->hasLocale)
1354 return;
1355
1356 d->hasLocale = false;
1357 d->updateLocale(QQuickControlPrivate::calcLocale(d->parentItem), false); // explicit=false
1358}
1359
1360/*!
1361 \qmlproperty bool QtQuick.Controls::Control::mirrored
1362 \readonly
1363
1364 This property holds whether the control is mirrored.
1365
1366 This property is provided for convenience. A control is considered mirrored
1367 when its visual layout direction is right-to-left; that is, when
1368 \l {LayoutMirroring::enabled}{LayoutMirroring.enabled} is \c true.
1369
1370 As of Qt 6.2, the \l locale property no longer affects this property.
1371
1372 \sa {LayoutMirroring}{LayoutMirroring}, {Right-to-left User Interfaces}
1373*/
1374bool QQuickControl::isMirrored() const
1375{
1376 Q_D(const QQuickControl);
1377 return d->isMirrored();
1378}
1379
1380// ### Qt 7: replace with signal parameter: QTBUG-117596
1381/*!
1382 \qmlproperty enumeration QtQuick.Controls::Control::focusReason
1383
1384 This property holds the reason of the last focus change.
1385
1386 The value of this property is modified by Qt whenever focus is transferred,
1387 and you should never have to set this property yourself.
1388
1389 \note This property does not indicate whether the item has \l {Item::activeFocus}
1390 {active focus}, but the reason why the item either gained or lost focus.
1391
1392 \value Qt.MouseFocusReason A mouse action occurred.
1393 \value Qt.TabFocusReason The Tab key was pressed.
1394 \value Qt.BacktabFocusReason A Backtab occurred. The input for this may include the Shift or Control keys; e.g. Shift+Tab.
1395 \value Qt.ActiveWindowFocusReason The window system made this window either active or inactive.
1396 \value Qt.PopupFocusReason The application opened/closed a pop-up that grabbed/released the keyboard focus.
1397 \value Qt.ShortcutFocusReason The user typed a label's buddy shortcut
1398 \value Qt.MenuBarFocusReason The menu bar took focus.
1399 \value Qt.OtherFocusReason Another reason, usually application-specific.
1400
1401 \sa Item::activeFocus
1402
1403 \sa visualFocus
1404*/
1405Qt::FocusReason QQuickControl::focusReason() const
1406{
1407 Q_D(const QQuickControl);
1408 return d->lastFocusChangeReason();
1409}
1410
1411void QQuickControl::setFocusReason(Qt::FocusReason reason)
1412{
1413 Q_D(QQuickControl);
1414 d->setLastFocusChangeReason(reason);
1415}
1416
1417/*!
1418 \qmlproperty bool QtQuick.Controls::Control::visualFocus
1419 \readonly
1420
1421 This property holds whether the control has visual focus. This property
1422 is \c true when the control has active focus and the focus reason is either
1423 \c Qt.TabFocusReason, \c Qt.BacktabFocusReason, or \c Qt.ShortcutFocusReason.
1424
1425 In general, for visualizing key focus, this property is preferred over
1426 \l Item::activeFocus. This ensures that key focus is only visualized when
1427 interacting with keys - not when interacting via touch or mouse.
1428
1429 \sa focusReason, Item::activeFocus
1430*/
1431bool QQuickControl::hasVisualFocus() const
1432{
1433 Q_D(const QQuickControl);
1434 return d->activeFocus && isKeyFocusReason(static_cast<Qt::FocusReason>(d->focusReason));
1435}
1436
1437/*!
1438 \qmlproperty bool QtQuick.Controls::Control::hovered
1439 \readonly
1440
1441 This property holds whether the control is hovered.
1442
1443 \sa hoverEnabled
1444*/
1445bool QQuickControl::isHovered() const
1446{
1447#if QT_CONFIG(quicktemplates2_hover)
1448 Q_D(const QQuickControl);
1449 return d->hovered;
1450#else
1451 return false;
1452#endif
1453}
1454
1455void QQuickControl::setHovered(bool hovered)
1456{
1457#if QT_CONFIG(quicktemplates2_hover)
1458 Q_D(QQuickControl);
1459 if (hovered == d->hovered)
1460 return;
1461
1462 d->hovered = hovered;
1463 emit hoveredChanged();
1464 hoverChange();
1465#else
1466 Q_UNUSED(hovered);
1467#endif
1468}
1469
1470/*!
1471 \qmlproperty bool QtQuick.Controls::Control::hoverEnabled
1472
1473 This property determines whether the control accepts hover events. The default value
1474 is \c Application.styleHints.useHoverEffects.
1475
1476 Setting this property propagates the value to all child controls that do not have
1477 \c hoverEnabled explicitly set.
1478
1479 You can also enable or disable hover effects for all Qt Quick Controls applications
1480 by setting the \c QT_QUICK_CONTROLS_HOVER_ENABLED \l {Supported Environment Variables
1481 in Qt Quick Controls}{environment variable}.
1482
1483 \sa hovered
1484*/
1485bool QQuickControl::isHoverEnabled() const
1486{
1487#if QT_CONFIG(quicktemplates2_hover)
1488 Q_D(const QQuickControl);
1489 return d->hoverEnabled;
1490#else
1491 return false;
1492#endif
1493}
1494
1495void QQuickControl::setHoverEnabled(bool enabled)
1496{
1497#if QT_CONFIG(quicktemplates2_hover)
1498 Q_D(QQuickControl);
1499 if (d->explicitHoverEnabled && enabled == d->hoverEnabled)
1500 return;
1501
1502 d->updateHoverEnabled(enabled, true); // explicit=true
1503#else
1504 Q_UNUSED(enabled);
1505#endif
1506}
1507
1508void QQuickControl::resetHoverEnabled()
1509{
1510#if QT_CONFIG(quicktemplates2_hover)
1511 Q_D(QQuickControl);
1512 if (!d->explicitHoverEnabled)
1513 return;
1514
1515 d->explicitHoverEnabled = false;
1516 d->updateHoverEnabled(QQuickControlPrivate::calcHoverEnabled(d->parentItem), false); // explicit=false
1517#endif
1518}
1519
1520/*!
1521 \qmlproperty bool QtQuick.Controls::Control::wheelEnabled
1522
1523 This property determines whether the control handles wheel events. The default value is \c false.
1524
1525 \note Care must be taken when enabling wheel events for controls within scrollable items such
1526 as \l Flickable, as the control will consume the events and hence interrupt scrolling of the
1527 Flickable.
1528*/
1529bool QQuickControl::isWheelEnabled() const
1530{
1531 Q_D(const QQuickControl);
1532 return d->wheelEnabled;
1533}
1534
1535void QQuickControl::setWheelEnabled(bool enabled)
1536{
1537 Q_D(QQuickControl);
1538 if (d->wheelEnabled == enabled)
1539 return;
1540
1541 d->wheelEnabled = enabled;
1542 emit wheelEnabledChanged();
1543}
1544
1545/*!
1546 \qmlproperty Item QtQuick.Controls::Control::background
1547
1548 This property holds the background item.
1549
1550 \code
1551 Button {
1552 id: control
1553 text: qsTr("Button")
1554 background: Rectangle {
1555 implicitWidth: 100
1556 implicitHeight: 40
1557 opacity: enabled ? 1 : 0.3
1558 color: control.down ? "#d0d0d0" : "#e0e0e0"
1559 }
1560 }
1561 \endcode
1562
1563 \input qquickcontrol-background.qdocinc notes
1564
1565 \sa {Control Layout}
1566*/
1567QQuickItem *QQuickControl::background() const
1568{
1569 QQuickControlPrivate *d = const_cast<QQuickControlPrivate *>(d_func());
1570 if (!d->background)
1571 d->executeBackground();
1572 return d->background;
1573}
1574
1575void QQuickControl::setBackground(QQuickItem *background)
1576{
1577 Q_D(QQuickControl);
1578 if (d->background == background)
1579 return;
1580
1581 QQuickControlPrivate::warnIfCustomizationNotSupported(this, background, QStringLiteral("background"));
1582
1583 if (!d->background.isExecuting())
1584 d->cancelBackground();
1585
1586 const qreal oldImplicitBackgroundWidth = implicitBackgroundWidth();
1587 const qreal oldImplicitBackgroundHeight = implicitBackgroundHeight();
1588
1589 if (d->extra.isAllocated()) {
1590 d->extra.value().hasBackgroundWidth = false;
1591 d->extra.value().hasBackgroundHeight = false;
1592 }
1593
1594 d->removeImplicitSizeListener(d->background, QQuickControlPrivate::ImplicitSizeChanges | QQuickItemPrivate::Geometry);
1595 QQuickControlPrivate::hideOldItem(d->background);
1596 d->background = background;
1597
1598 if (background) {
1599 background->setParentItem(this);
1600 if (qFuzzyIsNull(background->z()))
1601 background->setZ(-1);
1602 QQuickItemPrivate *p = QQuickItemPrivate::get(background);
1603 if (p->widthValid() || p->heightValid()) {
1604 d->extra.value().hasBackgroundWidth = p->widthValid();
1605 d->extra.value().hasBackgroundHeight = p->heightValid();
1606 }
1607 if (isComponentComplete())
1608 d->resizeBackground();
1609 d->addImplicitSizeListener(background, QQuickControlPrivate::ImplicitSizeChanges | QQuickItemPrivate::Geometry);
1610 }
1611
1612 if (!qFuzzyCompare(oldImplicitBackgroundWidth, implicitBackgroundWidth()))
1613 emit implicitBackgroundWidthChanged();
1614 if (!qFuzzyCompare(oldImplicitBackgroundHeight, implicitBackgroundHeight()))
1615 emit implicitBackgroundHeightChanged();
1616 if (!d->background.isExecuting())
1617 emit backgroundChanged();
1618}
1619
1620/*!
1621 \qmlproperty Item QtQuick.Controls::Control::contentItem
1622
1623 This property holds the visual content item.
1624
1625 \code
1626 Button {
1627 id: control
1628 text: qsTr("Button")
1629 contentItem: Label {
1630 text: control.text
1631 verticalAlignment: Text.AlignVCenter
1632 }
1633 }
1634 \endcode
1635
1636 \note The content item is automatically positioned and resized to fit
1637 within the \l padding of the control. Bindings to the
1638 \l[QtQuick]{Item::}{x}, \l[QtQuick]{Item::}{y},
1639 \l[QtQuick]{Item::}{width}, and \l[QtQuick]{Item::}{height}
1640 properties of the contentItem are not respected.
1641
1642 \note Most controls use the implicit size of the content item to calculate
1643 the implicit size of the control itself. If you replace the content item
1644 with a custom one, you should also consider providing a sensible implicit
1645 size for it (unless it is an item like \l Text which has its own implicit
1646 size).
1647
1648 \sa {Control Layout}, padding
1649*/
1650QQuickItem *QQuickControl::contentItem() const
1651{
1652 QQuickControlPrivate *d = const_cast<QQuickControlPrivate *>(d_func());
1653 if (!d->contentItem)
1654 d->setContentItem_helper(d->getContentItem(), false);
1655 return d->contentItem;
1656}
1657
1658void QQuickControl::setContentItem(QQuickItem *item)
1659{
1660 Q_D(QQuickControl);
1661 d->setContentItem_helper(item, true);
1662}
1663
1664qreal QQuickControl::baselineOffset() const
1665{
1666 Q_D(const QQuickControl);
1667 return d->baselineOffset;
1668}
1669
1670void QQuickControl::setBaselineOffset(qreal offset)
1671{
1672 Q_D(QQuickControl);
1673 d->extra.value().hasBaselineOffset = true;
1674 QQuickItem::setBaselineOffset(offset);
1675}
1676
1677void QQuickControl::resetBaselineOffset()
1678{
1679 Q_D(QQuickControl);
1680 if (!d->extra.isAllocated() || !d->extra.value().hasBaselineOffset)
1681 return;
1682
1683 if (d->extra.isAllocated())
1684 d->extra.value().hasBaselineOffset = false;
1685 d->updateBaselineOffset();
1686}
1687
1688/*!
1689 \since QtQuick.Controls 2.5 (Qt 5.12)
1690 \qmlproperty real QtQuick.Controls::Control::horizontalPadding
1691
1692 This property holds the horizontal padding. Unless explicitly set, the value
1693 is equal to \c padding.
1694
1695 \sa {Control Layout}, padding, leftPadding, rightPadding, verticalPadding
1696*/
1697qreal QQuickControl::horizontalPadding() const
1698{
1699 Q_D(const QQuickControl);
1700 return d->getHorizontalPadding();
1701}
1702
1703void QQuickControl::setHorizontalPadding(qreal padding)
1704{
1705 Q_D(QQuickControl);
1706 d->setHorizontalPadding(padding);
1707}
1708
1709void QQuickControl::resetHorizontalPadding()
1710{
1711 Q_D(QQuickControl);
1712 d->setHorizontalPadding(0, true);
1713}
1714
1715/*!
1716 \since QtQuick.Controls 2.5 (Qt 5.12)
1717 \qmlproperty real QtQuick.Controls::Control::verticalPadding
1718
1719 This property holds the vertical padding. Unless explicitly set, the value
1720 is equal to \c padding.
1721
1722 \sa {Control Layout}, padding, topPadding, bottomPadding, horizontalPadding
1723*/
1724qreal QQuickControl::verticalPadding() const
1725{
1726 Q_D(const QQuickControl);
1727 return d->getVerticalPadding();
1728}
1729
1730void QQuickControl::setVerticalPadding(qreal padding)
1731{
1732 Q_D(QQuickControl);
1733 d->setVerticalPadding(padding);
1734}
1735
1736void QQuickControl::resetVerticalPadding()
1737{
1738 Q_D(QQuickControl);
1739 d->setVerticalPadding(0, true);
1740}
1741
1742/*!
1743 \since QtQuick.Controls 2.5 (Qt 5.12)
1744 \qmlproperty real QtQuick.Controls::Control::implicitContentWidth
1745 \readonly
1746
1747 This property holds the implicit content width.
1748
1749 For basic controls, the value is equal to \c {contentItem ? contentItem.implicitWidth : 0}.
1750 For types that inherit Container or Pane, the value is calculated based on the content children.
1751
1752 This is typically used, together with \l implicitBackgroundWidth, to calculate
1753 the \l {Item::}{implicitWidth}:
1754
1755 \code
1756 Control {
1757 implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
1758 implicitContentWidth + leftPadding + rightPadding)
1759 }
1760 \endcode
1761
1762 \sa implicitContentHeight, implicitBackgroundWidth
1763*/
1764qreal QQuickControl::implicitContentWidth() const
1765{
1766 Q_D(const QQuickControl);
1767
1768 if (auto *safeArea = static_cast<QQuickSafeArea*>(
1769 qmlAttachedPropertiesObject<QQuickSafeArea>(this, false))) {
1770 // If the control's padding is tied to the safe area we may in
1771 // some cases end up with a binding loop if the implicit size
1772 // moves the control further into the non-safe area. Detect this
1773 // and break the binding loop by returning a constrained content
1774 // size based on an earlier known good implicit size.
1775 static constexpr auto kLastKnownGoodImplicitWidth = "_q_lastKnownGoodImplicitWidth";
1776 if (safeArea->detectedPossibleBindingLoop) {
1777 const auto lastImplicitWidth = safeArea->property(kLastKnownGoodImplicitWidth).value<int>();
1778 return lastImplicitWidth - leftPadding() - rightPadding();
1779 } else {
1780 safeArea->setProperty(kLastKnownGoodImplicitWidth, implicitWidth());
1781 }
1782 }
1783
1784 return d->implicitContentWidth;
1785}
1786
1787/*!
1788 \since QtQuick.Controls 2.5 (Qt 5.12)
1789 \qmlproperty real QtQuick.Controls::Control::implicitContentHeight
1790 \readonly
1791
1792 This property holds the implicit content height.
1793
1794 For basic controls, the value is equal to \c {contentItem ? contentItem.implicitHeight : 0}.
1795 For types that inherit Container or Pane, the value is calculated based on the content children.
1796
1797 This is typically used, together with \l implicitBackgroundHeight, to calculate
1798 the \l {Item::}{implicitHeight}:
1799
1800 \code
1801 Control {
1802 implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
1803 implicitContentHeight + topPadding + bottomPadding)
1804 }
1805 \endcode
1806
1807 \sa implicitContentWidth, implicitBackgroundHeight
1808*/
1809qreal QQuickControl::implicitContentHeight() const
1810{
1811 Q_D(const QQuickControl);
1812
1813 if (auto *safeArea = static_cast<QQuickSafeArea*>(
1814 qmlAttachedPropertiesObject<QQuickSafeArea>(this, false))) {
1815 // If the control's padding is tied to the safe area we may in
1816 // some cases end up with a binding loop if the implicit size
1817 // moves the control further into the non-safe area. Detect this
1818 // and break the binding loop by returning a constrained content
1819 // size based on an earlier known good implicit size.
1820 static constexpr auto kLastKnownGoodImplicitHeight = "_q_lastKnownGoodImplicitHeight";
1821 if (safeArea->detectedPossibleBindingLoop) {
1822 const auto lastImplicitHeight = safeArea->property(kLastKnownGoodImplicitHeight).value<int>();
1823 return lastImplicitHeight - topPadding() - bottomPadding();
1824 } else {
1825 safeArea->setProperty(kLastKnownGoodImplicitHeight, implicitHeight());
1826 }
1827 }
1828
1829 return d->implicitContentHeight;
1830}
1831
1832/*!
1833 \since QtQuick.Controls 2.5 (Qt 5.12)
1834 \qmlproperty real QtQuick.Controls::Control::implicitBackgroundWidth
1835 \readonly
1836
1837 This property holds the implicit background width.
1838
1839 The value is equal to \c {background ? background.implicitWidth : 0}.
1840
1841 This is typically used, together with \l implicitContentWidth, to calculate
1842 the \l {Item::}{implicitWidth}:
1843
1844 \code
1845 Control {
1846 implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
1847 implicitContentWidth + leftPadding + rightPadding)
1848 }
1849 \endcode
1850
1851 \sa implicitBackgroundHeight, implicitContentWidth
1852*/
1853qreal QQuickControl::implicitBackgroundWidth() const
1854{
1855 Q_D(const QQuickControl);
1856 if (!d->background)
1857 return 0;
1858 return d->background->implicitWidth();
1859}
1860
1861/*!
1862 \since QtQuick.Controls 2.5 (Qt 5.12)
1863 \qmlproperty real QtQuick.Controls::Control::implicitBackgroundHeight
1864 \readonly
1865
1866 This property holds the implicit background height.
1867
1868 The value is equal to \c {background ? background.implicitHeight : 0}.
1869
1870 This is typically used, together with \l implicitContentHeight, to calculate
1871 the \l {Item::}{implicitHeight}:
1872
1873 \code
1874 Control {
1875 implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
1876 implicitContentHeight + topPadding + bottomPadding)
1877 }
1878 \endcode
1879
1880 \sa implicitBackgroundWidth, implicitContentHeight
1881*/
1882qreal QQuickControl::implicitBackgroundHeight() const
1883{
1884 Q_D(const QQuickControl);
1885 if (!d->background)
1886 return 0;
1887 return d->background->implicitHeight();
1888}
1889
1890/*!
1891 \since QtQuick.Controls 2.5 (Qt 5.12)
1892 \qmlproperty real QtQuick.Controls::Control::topInset
1893
1894 This property holds the top inset for the background.
1895
1896 \sa {Control Layout}, bottomInset
1897*/
1898qreal QQuickControl::topInset() const
1899{
1900 Q_D(const QQuickControl);
1901 return d->getTopInset();
1902}
1903
1904void QQuickControl::setTopInset(qreal inset)
1905{
1906 Q_D(QQuickControl);
1907 d->setTopInset(inset);
1908}
1909
1910void QQuickControl::resetTopInset()
1911{
1912 Q_D(QQuickControl);
1913 d->setTopInset(0, true);
1914}
1915
1916/*!
1917 \since QtQuick.Controls 2.5 (Qt 5.12)
1918 \qmlproperty real QtQuick.Controls::Control::leftInset
1919
1920 This property holds the left inset for the background.
1921
1922 \sa {Control Layout}, rightInset
1923*/
1924qreal QQuickControl::leftInset() const
1925{
1926 Q_D(const QQuickControl);
1927 return d->getLeftInset();
1928}
1929
1930void QQuickControl::setLeftInset(qreal inset)
1931{
1932 Q_D(QQuickControl);
1933 d->setLeftInset(inset);
1934}
1935
1936void QQuickControl::resetLeftInset()
1937{
1938 Q_D(QQuickControl);
1939 d->setLeftInset(0, true);
1940}
1941
1942/*!
1943 \since QtQuick.Controls 2.5 (Qt 5.12)
1944 \qmlproperty real QtQuick.Controls::Control::rightInset
1945
1946 This property holds the right inset for the background.
1947
1948 \sa {Control Layout}, leftInset
1949*/
1950qreal QQuickControl::rightInset() const
1951{
1952 Q_D(const QQuickControl);
1953 return d->getRightInset();
1954}
1955
1956void QQuickControl::setRightInset(qreal inset)
1957{
1958 Q_D(QQuickControl);
1959 d->setRightInset(inset);
1960}
1961
1962void QQuickControl::resetRightInset()
1963{
1964 Q_D(QQuickControl);
1965 d->setRightInset(0, true);
1966}
1967
1968/*!
1969 \since QtQuick.Controls 2.5 (Qt 5.12)
1970 \qmlproperty real QtQuick.Controls::Control::bottomInset
1971
1972 This property holds the bottom inset for the background.
1973
1974 \sa {Control Layout}, topInset
1975*/
1976qreal QQuickControl::bottomInset() const
1977{
1978 Q_D(const QQuickControl);
1979 return d->getBottomInset();
1980}
1981
1982void QQuickControl::setBottomInset(qreal inset)
1983{
1984 Q_D(QQuickControl);
1985 d->setBottomInset(inset);
1986}
1987
1988void QQuickControl::resetBottomInset()
1989{
1990 Q_D(QQuickControl);
1991 d->setBottomInset(0, true);
1992}
1993
1994void QQuickControl::classBegin()
1995{
1996 Q_D(QQuickControl);
1997 QQuickItem::classBegin();
1998 d->resolveFont();
1999}
2000
2001void QQuickControl::componentComplete()
2002{
2003 Q_D(QQuickControl);
2004 d->executeBackground(true);
2005 d->executeContentItem(true);
2006 QQuickItem::componentComplete();
2007 d->resizeBackground();
2008 d->resizeContent();
2009 d->updateBaselineOffset();
2010 if (!d->hasLocale)
2011 d->locale = QQuickControlPrivate::calcLocale(d->parentItem);
2012#if QT_CONFIG(quicktemplates2_hover)
2013 if (!d->explicitHoverEnabled)
2014 setAcceptHoverEvents(QQuickControlPrivate::calcHoverEnabled(d->parentItem));
2015#endif
2016#if QT_CONFIG(accessibility)
2017 if (QAccessible::isActive())
2018 accessibilityActiveChanged(true);
2019#endif
2020}
2021
2022QFont QQuickControl::defaultFont() const
2023{
2024 return QQuickTheme::font(QQuickTheme::System);
2025}
2026
2027void QQuickControl::focusInEvent(QFocusEvent *event)
2028{
2029 QQuickItem::focusInEvent(event);
2030}
2031
2032void QQuickControl::focusOutEvent(QFocusEvent *event)
2033{
2034 QQuickItem::focusOutEvent(event);
2035}
2036
2037#if QT_CONFIG(quicktemplates2_hover)
2038void QQuickControl::hoverEnterEvent(QHoverEvent *event)
2039{
2040 Q_D(QQuickControl);
2041 setHovered(d->hoverEnabled);
2042 event->ignore();
2043}
2044
2045void QQuickControl::hoverMoveEvent(QHoverEvent *event)
2046{
2047 Q_D(QQuickControl);
2048 setHovered(d->hoverEnabled && contains(event->position()));
2049 event->ignore();
2050}
2051
2052void QQuickControl::hoverLeaveEvent(QHoverEvent *event)
2053{
2054 setHovered(false);
2055 event->ignore();
2056}
2057#endif
2058
2059void QQuickControl::mousePressEvent(QMouseEvent *event)
2060{
2061 Q_D(QQuickControl);
2062 event->setAccepted(d->handlePress(event->position(), event->timestamp()));
2063}
2064
2065void QQuickControl::mouseMoveEvent(QMouseEvent *event)
2066{
2067 Q_D(QQuickControl);
2068 event->setAccepted(d->handleMove(event->position(), event->timestamp()));
2069}
2070
2071void QQuickControl::mouseReleaseEvent(QMouseEvent *event)
2072{
2073 Q_D(QQuickControl);
2074 event->setAccepted(d->handleRelease(event->position(), event->timestamp()));
2075}
2076
2077void QQuickControl::mouseUngrabEvent()
2078{
2079 Q_D(QQuickControl);
2080 d->handleUngrab();
2081}
2082
2083#if QT_CONFIG(quicktemplates2_multitouch)
2084void QQuickControl::touchEvent(QTouchEvent *event)
2085{
2086 Q_D(QQuickControl);
2087 switch (event->type()) {
2088 case QEvent::TouchBegin:
2089 case QEvent::TouchUpdate:
2090 case QEvent::TouchEnd:
2091 for (const QTouchEvent::TouchPoint &point : event->points()) {
2092 if (!d->acceptTouch(point))
2093 continue;
2094
2095 switch (point.state()) {
2096 case QEventPoint::Pressed:
2097 d->handlePress(point.position(), event->timestamp());
2098 break;
2099 case QEventPoint::Updated:
2100 d->handleMove(point.position(), event->timestamp());
2101 break;
2102 case QEventPoint::Released:
2103 d->handleRelease(point.position(), event->timestamp());
2104 break;
2105 default:
2106 break;
2107 }
2108 }
2109 break;
2110
2111 case QEvent::TouchCancel:
2112 d->handleUngrab();
2113 break;
2114
2115 default:
2116 QQuickItem::touchEvent(event);
2117 break;
2118 }
2119}
2120
2121void QQuickControl::touchUngrabEvent()
2122{
2123 Q_D(QQuickControl);
2124 d->handleUngrab();
2125}
2126#endif
2127
2128#if QT_CONFIG(wheelevent)
2129void QQuickControl::wheelEvent(QWheelEvent *event)
2130{
2131 Q_D(QQuickControl);
2132 event->setAccepted(d->wheelEnabled);
2133}
2134#endif
2135
2136void QQuickControl::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry)
2137{
2138 Q_D(QQuickControl);
2139 QQuickItem::geometryChange(newGeometry, oldGeometry);
2140 d->resizeBackground();
2141 d->resizeContent();
2142 if (!qFuzzyCompare(newGeometry.width(), oldGeometry.width()))
2143 emit availableWidthChanged();
2144 if (!qFuzzyCompare(newGeometry.height(), oldGeometry.height()))
2145 emit availableHeightChanged();
2146}
2147
2148void QQuickControl::enabledChange()
2149{
2150}
2151
2152void QQuickControl::fontChange(const QFont &newFont, const QFont &oldFont)
2153{
2154 Q_UNUSED(newFont);
2155 Q_UNUSED(oldFont);
2156}
2157
2158#if QT_CONFIG(quicktemplates2_hover)
2159void QQuickControl::hoverChange()
2160{
2161 QQuickToolTipAttachedPrivate::maybeSetVisibleImplicitly(this, isHovered());
2162}
2163#endif
2164
2165void QQuickControl::mirrorChange()
2166{
2167 emit mirroredChanged();
2168}
2169
2170void QQuickControl::spacingChange(qreal newSpacing, qreal oldSpacing)
2171{
2172 Q_UNUSED(newSpacing);
2173 Q_UNUSED(oldSpacing);
2174}
2175
2176void QQuickControl::paddingChange(const QMarginsF &newPadding, const QMarginsF &oldPadding)
2177{
2178 Q_D(QQuickControl);
2179 Q_UNUSED(newPadding);
2180 Q_UNUSED(oldPadding);
2181 d->resizeContent();
2182 d->updateBaselineOffset();
2183}
2184
2185void QQuickControl::contentItemChange(QQuickItem *newItem, QQuickItem *oldItem)
2186{
2187 Q_UNUSED(newItem);
2188 Q_UNUSED(oldItem);
2189}
2190
2191void QQuickControl::localeChange(const QLocale &newLocale, const QLocale &oldLocale)
2192{
2193 Q_UNUSED(newLocale);
2194 Q_UNUSED(oldLocale);
2195}
2196
2197void QQuickControl::insetChange(const QMarginsF &newInset, const QMarginsF &oldInset)
2198{
2199 Q_D(QQuickControl);
2200 Q_UNUSED(newInset);
2201 Q_UNUSED(oldInset);
2202 d->resizeBackground();
2203}
2204
2205#if QT_CONFIG(accessibility)
2206QAccessible::Role QQuickControl::accessibleRole() const
2207{
2208 return QAccessible::NoRole;
2209}
2210
2211void QQuickControl::accessibilityActiveChanged(bool active)
2212{
2213 Q_D(QQuickControl);
2214 if (!active)
2215 return;
2216
2217 QQuickAccessibleAttached *accessibleAttached = qobject_cast<QQuickAccessibleAttached *>(qmlAttachedPropertiesObject<QQuickAccessibleAttached>(this, true));
2218 Q_ASSERT(accessibleAttached);
2219 accessibleAttached->setRole(d->effectiveAccessibleRole());
2220}
2221#endif
2222
2223QString QQuickControl::accessibleName() const
2224{
2225#if QT_CONFIG(accessibility)
2226 if (QQuickAccessibleAttached *accessibleAttached = QQuickControlPrivate::accessibleAttached(this))
2227 return accessibleAttached->name();
2228#endif
2229 return QString();
2230}
2231
2232void QQuickControl::maybeSetAccessibleName(const QString &name)
2233{
2234#if QT_CONFIG(accessibility)
2235 if (QQuickAccessibleAttached *accessibleAttached = QQuickControlPrivate::accessibleAttached(this)) {
2236 if (!accessibleAttached->wasNameExplicitlySet())
2237 accessibleAttached->setNameImplicitly(name);
2238 }
2239#else
2240 Q_UNUSED(name);
2241#endif
2242}
2243
2244QVariant QQuickControl::accessibleProperty(const char *propertyName)
2245{
2246#if QT_CONFIG(accessibility)
2247 if (QAccessible::isActive())
2248 return QQuickAccessibleAttached::property(this, propertyName);
2249#endif
2250 Q_UNUSED(propertyName);
2251 return QVariant();
2252}
2253
2254bool QQuickControl::setAccessibleProperty(const char *propertyName, const QVariant &value)
2255{
2256#if QT_CONFIG(accessibility)
2257 if (QAccessible::isActive())
2258 return QQuickAccessibleAttached::setProperty(this, propertyName, value);
2259#endif
2260 Q_UNUSED(propertyName);
2261 Q_UNUSED(value);
2262 return false;
2263}
2264
2265QT_END_NAMESPACE
2266
2267#include "moc_qquickcontrol_p.cpp"
Combined button and popup list for selecting options.
static bool isKeyFocusReason(Qt::FocusReason reason)
static QString contentItemName()