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

Provided by KDAB

Privacy Policy
Learn to use CMake with our Intro Training
Find out more

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