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

source code of qtquickcontrols2/src/quicktemplates2/qquickcontrol.cpp