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

source code of qtdeclarative/src/quicktemplates/qquickcontrol.cpp