Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qquickitem.cpp
Go to the documentation of this file.
1// Copyright (C) 2021 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 "qquickitem.h"
5
6#include "qquickwindow.h"
8#include <QtQml/qjsengine.h>
9#include "qquickwindow_p.h"
10
11#include "qquickevents_p_p.h"
12#include "qquickscreen_p.h"
13
14#include <QtQml/qqmlengine.h>
15#include <QtQml/qqmlcomponent.h>
16#include <QtQml/qqmlinfo.h>
17#include <QtGui/qpen.h>
18#include <QtGui/qguiapplication.h>
19#include <QtGui/qstylehints.h>
20#include <QtGui/private/qeventpoint_p.h>
21#include <QtGui/private/qguiapplication_p.h>
22#include <QtGui/private/qpointingdevice_p.h>
23#include <QtGui/qinputmethod.h>
24#include <QtCore/qcoreevent.h>
25#include <QtCore/private/qnumeric_p.h>
26#include <QtGui/qpa/qplatformtheme.h>
27#include <QtCore/qloggingcategory.h>
28#include <QtCore/private/qduplicatetracker_p.h>
29
30#include <private/qqmlglobal_p.h>
31#include <private/qqmlengine_p.h>
32#include <QtQuick/private/qquickstategroup_p.h>
33#include <private/qqmlopenmetaobject_p.h>
34#include <QtQuick/private/qquickstate_p.h>
35#include <private/qquickitem_p.h>
36#include <QtQuick/private/qquickaccessibleattached_p.h>
37#include <QtQuick/private/qquickhoverhandler_p.h>
38#include <QtQuick/private/qquickpointerhandler_p.h>
39#include <QtQuick/private/qquickpointerhandler_p_p.h>
40
41#include <private/qv4engine_p.h>
42#include <private/qv4object_p.h>
43#include <private/qv4qobjectwrapper_p.h>
44#include <private/qdebug_p.h>
45#include <private/qqmlvaluetypewrapper_p.h>
46
47#if QT_CONFIG(cursor)
48# include <QtGui/qcursor.h>
49#endif
50
51#include <algorithm>
52#include <limits>
53
54// XXX todo Check that elements that create items handle memory correctly after visual ownership change
55
57
58Q_DECLARE_LOGGING_CATEGORY(lcMouseTarget)
62Q_LOGGING_CATEGORY(lcHandlerParent, "qt.quick.handler.parent")
63Q_LOGGING_CATEGORY(lcVP, "qt.quick.viewport")
64Q_LOGGING_CATEGORY(lcChangeListeners, "qt.quick.item.changelisteners")
65
66// after 100ms, a mouse/non-mouse cursor conflict is resolved in favor of the mouse handler
68
69void debugFocusTree(QQuickItem *item, QQuickItem *scope = nullptr, int depth = 1)
70{
71 if (lcFocus().isEnabled(QtDebugMsg)) {
72 qCDebug(lcFocus)
73 << QByteArray(depth, '\t').constData()
74 << (scope && QQuickItemPrivate::get(scope)->subFocusItem == item ? '*' : ' ')
75 << item->hasFocus()
76 << item->hasActiveFocus()
77 << item->isFocusScope()
78 << item;
79 const auto childItems = item->childItems();
80 for (QQuickItem *child : childItems) {
82 child,
83 item->isFocusScope() || !scope ? item : scope,
84 item->isFocusScope() || !scope ? depth + 1 : depth);
85 }
86 }
87}
88
113{
114}
115
118{
119}
120
122: QObject(dd, parent)
123{
124}
125
127{
128 Q_D(QQuickTransform);
129 for (int ii = 0; ii < d->items.size(); ++ii) {
131 p->transforms.removeOne(this);
133 }
134}
135
137{
138 Q_D(QQuickTransform);
139 for (int ii = 0; ii < d->items.size(); ++ii) {
142 }
143}
144
146: m_item(item)
147{
148}
149
151{
152 QList<QQuickItem *> children = m_item->childItems();
153 for (int i = 0; i < children.size(); ++i) {
154 QQuickItem *child = children.at(i);
156 }
157}
158
159bool QQuickContents::calcHeight(QQuickItem *changed)
160{
161 qreal oldy = m_contents.y();
162 qreal oldheight = m_contents.height();
163
164 if (changed) {
165 qreal top = oldy;
166 qreal bottom = oldy + oldheight;
167 qreal y = changed->y();
168 if (y + changed->height() > bottom)
169 bottom = y + changed->height();
170 if (y < top)
171 top = y;
172 m_contents.setY(top);
173 m_contents.setHeight(bottom - top);
174 } else {
175 qreal top = std::numeric_limits<qreal>::max();
176 qreal bottom = -std::numeric_limits<qreal>::max();
177 QList<QQuickItem *> children = m_item->childItems();
178 for (int i = 0; i < children.size(); ++i) {
179 QQuickItem *child = children.at(i);
180 qreal y = child->y();
181 if (y + child->height() > bottom)
182 bottom = y + child->height();
183 if (y < top)
184 top = y;
185 }
186 if (!children.isEmpty())
187 m_contents.setY(top);
188 m_contents.setHeight(qMax(bottom - top, qreal(0.0)));
189 }
190
191 return (m_contents.height() != oldheight || m_contents.y() != oldy);
192}
193
194bool QQuickContents::calcWidth(QQuickItem *changed)
195{
196 qreal oldx = m_contents.x();
197 qreal oldwidth = m_contents.width();
198
199 if (changed) {
200 qreal left = oldx;
201 qreal right = oldx + oldwidth;
202 qreal x = changed->x();
203 if (x + changed->width() > right)
204 right = x + changed->width();
205 if (x < left)
206 left = x;
207 m_contents.setX(left);
208 m_contents.setWidth(right - left);
209 } else {
210 qreal left = std::numeric_limits<qreal>::max();
211 qreal right = -std::numeric_limits<qreal>::max();
212 QList<QQuickItem *> children = m_item->childItems();
213 for (int i = 0; i < children.size(); ++i) {
214 QQuickItem *child = children.at(i);
215 qreal x = child->x();
216 if (x + child->width() > right)
217 right = x + child->width();
218 if (x < left)
219 left = x;
220 }
221 if (!children.isEmpty())
222 m_contents.setX(left);
223 m_contents.setWidth(qMax(right - left, qreal(0.0)));
224 }
225
226 return (m_contents.width() != oldwidth || m_contents.x() != oldx);
227}
228
230{
232
233 QList<QQuickItem *> children = m_item->childItems();
234 for (int i = 0; i < children.size(); ++i) {
235 QQuickItem *child = children.at(i);
237 //###what about changes to visibility?
238 }
239 calcGeometry();
240}
241
242void QQuickContents::updateRect()
243{
245}
246
248{
249 Q_UNUSED(changed);
250 bool wChanged = false;
251 bool hChanged = false;
252 //### we can only pass changed if the left edge has moved left, or the right edge has moved right
253 if (change.horizontalChange())
254 wChanged = calcWidth(/*changed*/);
255 if (change.verticalChange())
256 hChanged = calcHeight(/*changed*/);
257 if (wChanged || hChanged)
258 updateRect();
259}
260
262{
263 if (item)
265 calcGeometry();
266}
267
269{
270 if (item)
272 calcGeometry();
273}
274
276{
277 if (item)
280}
281
283: m_processPost(false), m_next(nullptr)
284{
286 if (p) {
287 m_next = p->extra.value().keyHandler;
288 p->extra->keyHandler = this;
289 }
290}
291
293{
294}
295
297{
298 if (m_next) m_next->keyPressed(event, post);
299}
300
302{
303 if (m_next) m_next->keyReleased(event, post);
304}
305
306#if QT_CONFIG(im)
307void QQuickItemKeyFilter::inputMethodEvent(QInputMethodEvent *event, bool post)
308{
309 if (m_next)
310 m_next->inputMethodEvent(event, post);
311 else
312 event->ignore();
313}
314
315QVariant QQuickItemKeyFilter::inputMethodQuery(Qt::InputMethodQuery query) const
316{
317 if (m_next) return m_next->inputMethodQuery(query);
318 return QVariant();
319}
320#endif // im
321
323{
324 if (m_next)
326 else
327 event->ignore();
328}
329
331{
332 if (m_next) m_next->componentComplete();
333}
423{
424 m_processPost = true;
425}
426
429{
431}
432
434{
436 return d->left;
437}
438
440{
442 if (d->leftSet && d->left == i)
443 return;
444 d->leftSet = d->left != i;
445 d->left = i;
447 qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
448 if (other && !other->d_func()->rightSet){
449 other->d_func()->right = qobject_cast<QQuickItem*>(parent());
450 emit other->rightChanged();
451 }
453}
454
456{
458 return d->right;
459}
460
462{
464 if (d->rightSet && d->right == i)
465 return;
466 d->rightSet = d->right != i;
467 d->right = i;
469 qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
470 if (other && !other->d_func()->leftSet){
471 other->d_func()->left = qobject_cast<QQuickItem*>(parent());
472 emit other->leftChanged();
473 }
475}
476
478{
480 return d->up;
481}
482
484{
486 if (d->upSet && d->up == i)
487 return;
488 d->upSet = d->up != i;
489 d->up = i;
491 qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
492 if (other && !other->d_func()->downSet){
493 other->d_func()->down = qobject_cast<QQuickItem*>(parent());
494 emit other->downChanged();
495 }
496 emit upChanged();
497}
498
500{
502 return d->down;
503}
504
506{
508 if (d->downSet && d->down == i)
509 return;
510 d->downSet = d->down != i;
511 d->down = i;
513 qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
514 if (other && !other->d_func()->upSet) {
515 other->d_func()->up = qobject_cast<QQuickItem*>(parent());
516 emit other->upChanged();
517 }
519}
520
522{
524 return d->tab;
525}
526
528{
530 if (d->tabSet && d->tab == i)
531 return;
532 d->tabSet = d->tab != i;
533 d->tab = i;
535 qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
536 if (other && !other->d_func()->backtabSet) {
537 other->d_func()->backtab = qobject_cast<QQuickItem*>(parent());
538 emit other->backtabChanged();
539 }
541}
542
544{
546 return d->backtab;
547}
548
550{
552 if (d->backtabSet && d->backtab == i)
553 return;
554 d->backtabSet = d->backtab != i;
555 d->backtab = i;
557 qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
558 if (other && !other->d_func()->tabSet) {
559 other->d_func()->tab = qobject_cast<QQuickItem*>(parent());
560 emit other->tabChanged();
561 }
563}
564
579{
581}
582
584{
585 bool processPost = order == AfterItem;
586 if (processPost != m_processPost) {
587 m_processPost = processPost;
589 }
590}
591
593{
595 event->ignore();
596
597 if (post != m_processPost) {
599 return;
600 }
601
602 bool mirror = false;
603 switch (event->key()) {
604 case Qt::Key_Left: {
605 if (QQuickItem *parentItem = qobject_cast<QQuickItem*>(parent()))
606 mirror = QQuickItemPrivate::get(parentItem)->effectiveLayoutMirror;
607 QQuickItem* leftItem = mirror ? d->right : d->left;
608 if (leftItem) {
609 setFocusNavigation(leftItem, mirror ? "right" : "left", mirror ? Qt::TabFocusReason : Qt::BacktabFocusReason);
610 event->accept();
611 }
612 break;
613 }
614 case Qt::Key_Right: {
615 if (QQuickItem *parentItem = qobject_cast<QQuickItem*>(parent()))
616 mirror = QQuickItemPrivate::get(parentItem)->effectiveLayoutMirror;
617 QQuickItem* rightItem = mirror ? d->left : d->right;
618 if (rightItem) {
619 setFocusNavigation(rightItem, mirror ? "left" : "right", mirror ? Qt::BacktabFocusReason : Qt::TabFocusReason);
620 event->accept();
621 }
622 break;
623 }
624 case Qt::Key_Up:
625 if (d->up) {
626 setFocusNavigation(d->up, "up", Qt::BacktabFocusReason);
627 event->accept();
628 }
629 break;
630 case Qt::Key_Down:
631 if (d->down) {
632 setFocusNavigation(d->down, "down", Qt::TabFocusReason);
633 event->accept();
634 }
635 break;
636 case Qt::Key_Tab:
637 if (d->tab) {
638 setFocusNavigation(d->tab, "tab", Qt::TabFocusReason);
639 event->accept();
640 }
641 break;
642 case Qt::Key_Backtab:
643 if (d->backtab) {
644 setFocusNavigation(d->backtab, "backtab", Qt::BacktabFocusReason);
645 event->accept();
646 }
647 break;
648 default:
649 break;
650 }
651
652 if (!event->isAccepted()) QQuickItemKeyFilter::keyPressed(event, post);
653}
654
656{
658 event->ignore();
659
660 if (post != m_processPost) {
662 return;
663 }
664
665 bool mirror = false;
666 switch (event->key()) {
667 case Qt::Key_Left:
668 if (QQuickItem *parentItem = qobject_cast<QQuickItem*>(parent()))
669 mirror = QQuickItemPrivate::get(parentItem)->effectiveLayoutMirror;
670 if (mirror ? d->right : d->left)
671 event->accept();
672 break;
673 case Qt::Key_Right:
674 if (QQuickItem *parentItem = qobject_cast<QQuickItem*>(parent()))
675 mirror = QQuickItemPrivate::get(parentItem)->effectiveLayoutMirror;
676 if (mirror ? d->left : d->right)
677 event->accept();
678 break;
679 case Qt::Key_Up:
680 if (d->up) {
681 event->accept();
682 }
683 break;
684 case Qt::Key_Down:
685 if (d->down) {
686 event->accept();
687 }
688 break;
689 case Qt::Key_Tab:
690 if (d->tab) {
691 event->accept();
692 }
693 break;
694 case Qt::Key_Backtab:
695 if (d->backtab) {
696 event->accept();
697 }
698 break;
699 default:
700 break;
701 }
702
703 if (!event->isAccepted()) QQuickItemKeyFilter::keyReleased(event, post);
704}
705
706void QQuickKeyNavigationAttached::setFocusNavigation(QQuickItem *currentItem, const char *dir,
707 Qt::FocusReason reason)
708{
709 QQuickItem *initialItem = currentItem;
710 bool isNextItem = false;
711 QVector<QQuickItem *> visitedItems;
712 do {
713 isNextItem = false;
714 if (currentItem->isVisible() && currentItem->isEnabled()) {
715 currentItem->forceActiveFocus(reason);
716 } else {
717 QObject *attached =
718 qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(currentItem, false);
719 if (attached) {
720 QQuickItem *tempItem = qvariant_cast<QQuickItem*>(attached->property(dir));
721 if (tempItem) {
722 visitedItems.append(currentItem);
723 currentItem = tempItem;
724 isNextItem = true;
725 }
726 }
727 }
728 }
729 while (currentItem != initialItem && isNextItem && !visitedItems.contains(currentItem));
730}
731
732struct SigMap {
733 int key;
734 const char *sig;
735};
736
737const SigMap sigMap[] = {
738 { Qt::Key_Left, "leftPressed" },
739 { Qt::Key_Right, "rightPressed" },
740 { Qt::Key_Up, "upPressed" },
741 { Qt::Key_Down, "downPressed" },
742 { Qt::Key_Tab, "tabPressed" },
743 { Qt::Key_Backtab, "backtabPressed" },
744 { Qt::Key_Asterisk, "asteriskPressed" },
745 { Qt::Key_NumberSign, "numberSignPressed" },
746 { Qt::Key_Escape, "escapePressed" },
747 { Qt::Key_Return, "returnPressed" },
748 { Qt::Key_Enter, "enterPressed" },
749 { Qt::Key_Delete, "deletePressed" },
750 { Qt::Key_Space, "spacePressed" },
751 { Qt::Key_Back, "backPressed" },
752 { Qt::Key_Cancel, "cancelPressed" },
753 { Qt::Key_Select, "selectPressed" },
754 { Qt::Key_Yes, "yesPressed" },
755 { Qt::Key_No, "noPressed" },
756 { Qt::Key_Context1, "context1Pressed" },
757 { Qt::Key_Context2, "context2Pressed" },
758 { Qt::Key_Context3, "context3Pressed" },
759 { Qt::Key_Context4, "context4Pressed" },
760 { Qt::Key_Call, "callPressed" },
761 { Qt::Key_Hangup, "hangupPressed" },
762 { Qt::Key_Flip, "flipPressed" },
763 { Qt::Key_Menu, "menuPressed" },
764 { Qt::Key_VolumeUp, "volumeUpPressed" },
765 { Qt::Key_VolumeDown, "volumeDownPressed" },
766 { 0, nullptr }
767};
768
769QByteArray QQuickKeysAttached::keyToSignal(int key)
770{
771 QByteArray keySignal;
772 if (key >= Qt::Key_0 && key <= Qt::Key_9) {
773 keySignal = "digit0Pressed";
774 keySignal[5] = '0' + (key - Qt::Key_0);
775 } else {
776 int i = 0;
777 while (sigMap[i].key && sigMap[i].key != key)
778 ++i;
779 keySignal = sigMap[i].sig;
780 }
781 return keySignal;
782}
783
784bool QQuickKeysAttached::isConnected(const char *signalName) const
785{
786 Q_D(const QQuickKeysAttached);
787 int signal_index = d->signalIndex(signalName);
788 return d->isSignalConnected(signal_index);
789}
790
1222{
1223 Q_D(QQuickKeysAttached);
1224 m_processPost = false;
1226 if (d->item != parent)
1227 qWarning() << "Could not attach Keys property to: " << parent << " is not an Item";
1228}
1229
1231{
1232}
1233
1235{
1237}
1238
1240{
1241 bool processPost = order == AfterItem;
1242 if (processPost != m_processPost) {
1243 m_processPost = processPost;
1245 }
1246}
1247
1249{
1250#if QT_CONFIG(im)
1251 Q_D(QQuickKeysAttached);
1252 if (d->item) {
1253 for (int ii = 0; ii < d->targets.size(); ++ii) {
1254 QQuickItem *targetItem = d->targets.at(ii);
1255 if (targetItem && (targetItem->flags() & QQuickItem::ItemAcceptsInputMethod)) {
1256 d->item->setFlag(QQuickItem::ItemAcceptsInputMethod);
1257 break;
1258 }
1259 }
1260 }
1261#endif
1262}
1263
1265{
1266 Q_D(QQuickKeysAttached);
1267 if (post != m_processPost || !d->enabled || d->inPress) {
1268 event->ignore();
1270 return;
1271 }
1272
1273 // first process forwards
1274 if (d->item && d->item->window()) {
1275 d->inPress = true;
1276 for (int ii = 0; ii < d->targets.size(); ++ii) {
1277 QQuickItem *i = d->targets.at(ii);
1278 if (i && i->isVisible()) {
1279 event->accept();
1281 if (event->isAccepted()) {
1282 d->inPress = false;
1283 return;
1284 }
1285 }
1286 }
1287 d->inPress = false;
1288 }
1289
1290 QQuickKeyEvent &ke = d->theKeyEvent;
1291 ke.reset(*event);
1292 QByteArray keySignal = keyToSignal(event->key());
1293 if (!keySignal.isEmpty()) {
1294 keySignal += "(QQuickKeyEvent*)";
1295 if (isConnected(keySignal)) {
1296 // If we specifically handle a key then default to accepted
1297 ke.setAccepted(true);
1298 int idx = QQuickKeysAttached::staticMetaObject.indexOfSignal(keySignal);
1299 metaObject()->method(idx).invoke(this, Qt::DirectConnection, Q_ARG(QQuickKeyEvent*, &ke));
1300 }
1301 }
1302 if (!ke.isAccepted())
1303 emit pressed(&ke);
1304 event->setAccepted(ke.isAccepted());
1305
1306 if (!event->isAccepted()) QQuickItemKeyFilter::keyPressed(event, post);
1307}
1308
1310{
1311 Q_D(QQuickKeysAttached);
1312 if (post != m_processPost || !d->enabled || d->inRelease) {
1313 event->ignore();
1315 return;
1316 }
1317
1318 if (d->item && d->item->window()) {
1319 d->inRelease = true;
1320 for (int ii = 0; ii < d->targets.size(); ++ii) {
1321 QQuickItem *i = d->targets.at(ii);
1322 if (i && i->isVisible()) {
1323 event->accept();
1325 if (event->isAccepted()) {
1326 d->inRelease = false;
1327 return;
1328 }
1329 }
1330 }
1331 d->inRelease = false;
1332 }
1333
1334 QQuickKeyEvent &ke = d->theKeyEvent;
1335 ke.reset(*event);
1336 emit released(&ke);
1337 event->setAccepted(ke.isAccepted());
1338
1339 if (!event->isAccepted()) QQuickItemKeyFilter::keyReleased(event, post);
1340}
1341
1342#if QT_CONFIG(im)
1343void QQuickKeysAttached::inputMethodEvent(QInputMethodEvent *event, bool post)
1344{
1345 Q_D(QQuickKeysAttached);
1346 if (post == m_processPost && d->item && !d->inIM && d->item->window()) {
1347 d->inIM = true;
1348 for (int ii = 0; ii < d->targets.size(); ++ii) {
1349 QQuickItem *targetItem = d->targets.at(ii);
1350 if (targetItem && targetItem->isVisible() && (targetItem->flags() & QQuickItem::ItemAcceptsInputMethod)) {
1352 if (event->isAccepted()) {
1353 d->imeItem = targetItem;
1354 d->inIM = false;
1355 return;
1356 }
1357 }
1358 }
1359 d->inIM = false;
1360 }
1361 QQuickItemKeyFilter::inputMethodEvent(event, post);
1362}
1363
1364QVariant QQuickKeysAttached::inputMethodQuery(Qt::InputMethodQuery query) const
1365{
1366 Q_D(const QQuickKeysAttached);
1367 if (d->item) {
1368 for (int ii = 0; ii < d->targets.size(); ++ii) {
1369 QQuickItem *i = d->targets.at(ii);
1370 if (i && i->isVisible() && (i->flags() & QQuickItem::ItemAcceptsInputMethod) && i == d->imeItem) {
1371 //### how robust is i == d->imeItem check?
1372 QVariant v = i->inputMethodQuery(query);
1373 if (v.userType() == QMetaType::QRectF)
1374 v = d->item->mapRectFromItem(i, v.toRectF()); //### cost?
1375 return v;
1376 }
1377 }
1378 }
1379 return QQuickItemKeyFilter::inputMethodQuery(query);
1380}
1381#endif // im
1382
1384{
1385 Q_D(QQuickKeysAttached);
1386 QQuickKeyEvent &keyEvent = d->theKeyEvent;
1387 keyEvent.reset(*event);
1388 emit shortcutOverride(&keyEvent);
1389
1390 event->setAccepted(keyEvent.isAccepted());
1391}
1392
1394{
1395 return new QQuickKeysAttached(obj);
1396}
1397
1475{
1477 itemPrivate = QQuickItemPrivate::get(item);
1478 else if (QQuickWindow *window = qobject_cast<QQuickWindow *>(parent))
1479 itemPrivate = QQuickItemPrivate::get(window->contentItem());
1480
1481 if (itemPrivate)
1482 itemPrivate->extra.value().layoutDirectionAttached = this;
1483 else
1484 qmlWarning(parent) << tr("LayoutDirection attached property only works with Items and Windows");
1485}
1486
1488{
1489 return new QQuickLayoutMirroringAttached(object);
1490}
1491
1493{
1494 return itemPrivate ? itemPrivate->effectiveLayoutMirror : false;
1495}
1496
1498{
1499 if (!itemPrivate)
1500 return;
1501
1502 itemPrivate->isMirrorImplicit = false;
1503 if (enabled != itemPrivate->effectiveLayoutMirror) {
1504 itemPrivate->setLayoutMirror(enabled);
1505 if (itemPrivate->inheritMirrorFromItem)
1506 itemPrivate->resolveLayoutMirror();
1507 }
1508}
1509
1511{
1512 if (itemPrivate && !itemPrivate->isMirrorImplicit) {
1513 itemPrivate->isMirrorImplicit = true;
1514 itemPrivate->resolveLayoutMirror();
1515 }
1516}
1517
1519{
1520 return itemPrivate ? itemPrivate->inheritMirrorFromItem : false;
1521}
1522
1524 if (itemPrivate && childrenInherit != itemPrivate->inheritMirrorFromItem) {
1526 itemPrivate->resolveLayoutMirror();
1528 }
1529}
1530
1532{
1533 Q_Q(QQuickItem);
1534 if (QQuickItem *parentItem = q->parentItem()) {
1537 } else {
1539 }
1540}
1541
1542void QQuickItemPrivate::setImplicitLayoutMirror(bool mirror, bool inherit)
1543{
1544 inherit = inherit || inheritMirrorFromItem;
1546 mirror = effectiveLayoutMirror;
1547 if (mirror == inheritedLayoutMirror && inherit == inheritMirrorFromParent)
1548 return;
1549
1550 inheritMirrorFromParent = inherit;
1552
1553 if (isMirrorImplicit)
1554 setLayoutMirror(inherit ? inheritedLayoutMirror : false);
1555 for (int i = 0; i < childItems.size(); ++i) {
1559 }
1560 }
1561}
1562
1564{
1565 if (mirror != effectiveLayoutMirror) {
1566 effectiveLayoutMirror = mirror;
1567 if (_anchors) {
1569 anchor_d->fillChanged();
1570 anchor_d->centerInChanged();
1571 anchor_d->updateHorizontalAnchors();
1572 }
1573 mirrorChange();
1574 if (extra.isAllocated() && extra->layoutDirectionAttached) {
1575 emit extra->layoutDirectionAttached->enabledChanged();
1576 }
1577 }
1578}
1579
1628 : QObject(parent), itemPrivate(nullptr), keyType(Qt::EnterKeyDefault)
1629{
1631 itemPrivate = QQuickItemPrivate::get(item);
1632 itemPrivate->extra.value().enterKeyAttached = this;
1633 } else
1634 qmlWarning(parent) << tr("EnterKey attached property only works with Items");
1635}
1636
1638{
1639 return new QQuickEnterKeyAttached(object);
1640}
1641
1643{
1644 return keyType;
1645}
1646
1648{
1649 if (keyType != type) {
1650 keyType = type;
1651#if QT_CONFIG(im)
1652 if (itemPrivate && itemPrivate->activeFocus)
1654#endif
1655 typeChanged();
1656 }
1657}
1658
1660{
1661 isAccessible = true;
1662}
1663
1670{
1671 Q_Q(QQuickItem);
1672 Q_ASSERT(scope);
1673
1674 QQuickItemPrivate *scopePrivate = QQuickItemPrivate::get(scope);
1675
1676 QQuickItem *oldSubFocusItem = scopePrivate->subFocusItem;
1677 // Correct focus chain in scope
1678 if (oldSubFocusItem) {
1679 QQuickItem *sfi = scopePrivate->subFocusItem->parentItem();
1680 while (sfi && sfi != scope) {
1681 QQuickItemPrivate::get(sfi)->subFocusItem = nullptr;
1682 sfi = sfi->parentItem();
1683 }
1684 }
1685
1686 if (focus) {
1687 scopePrivate->subFocusItem = q;
1688 QQuickItem *sfi = scopePrivate->subFocusItem->parentItem();
1689 while (sfi && sfi != scope) {
1691 sfi = sfi->parentItem();
1692 }
1693 } else {
1694 scopePrivate->subFocusItem = nullptr;
1695 }
1696}
1697
2293{
2294 Q_D(QQuickItem);
2295 d->init(parent);
2296}
2297
2301: QObject(dd, parent)
2302{
2303 Q_D(QQuickItem);
2304 d->init(parent);
2305}
2306
2311{
2312 Q_D(QQuickItem);
2313 d->inDestructor = true;
2314
2315 if (d->windowRefCount > 1)
2316 d->windowRefCount = 1; // Make sure window is set to null in next call to derefWindow().
2317 if (d->parentItem)
2318 setParentItem(nullptr);
2319 else if (d->window)
2320 d->derefWindow();
2321
2322 for (QQuickItem *child : std::as_const(d->childItems))
2323 child->setParentItem(nullptr);
2324 d->childItems.clear();
2325
2326 d->notifyChangeListeners(QQuickItemPrivate::AllChanges, [this](const QQuickItemPrivate::ChangeListener &change){
2327 QQuickAnchorsPrivate *anchor = change.listener->anchorPrivate();
2328 if (anchor)
2329 anchor->clearItem(this);
2330 });
2331 /*
2332 update item anchors that depended on us unless they are our child (and will also be destroyed),
2333 or our sibling, and our parent is also being destroyed.
2334 */
2335 d->notifyChangeListeners(QQuickItemPrivate::AllChanges, [this](const QQuickItemPrivate::ChangeListener &change){
2336 QQuickAnchorsPrivate *anchor = change.listener->anchorPrivate();
2337 if (anchor && anchor->item && anchor->item->parentItem() && anchor->item->parentItem() != this)
2338 anchor->update();
2339 });
2341 d->changeListeners.clear();
2342
2343 /*
2344 Remove any references our transforms have to us, in case they try to
2345 remove themselves from our list of transforms when that list has already
2346 been destroyed after ~QQuickItem() has run.
2347 */
2348 for (int ii = 0; ii < d->transforms.size(); ++ii) {
2349 QQuickTransform *t = d->transforms.at(ii);
2351 tp->items.removeOne(this);
2352 }
2353
2354 if (d->extra.isAllocated()) {
2355 delete d->extra->contents; d->extra->contents = nullptr;
2356#if QT_CONFIG(quick_shadereffect)
2357 delete d->extra->layer; d->extra->layer = nullptr;
2358#endif
2359 }
2360
2361 delete d->_anchors; d->_anchors = nullptr;
2362 delete d->_stateGroup; d->_stateGroup = nullptr;
2363
2364 d->isQuickItem = false;
2365}
2366
2371{
2372 if (!item->window())
2373 return false;
2374
2375 if (item == item->window()->contentItem())
2376 return true;
2377
2378#if QT_CONFIG(accessibility)
2379 QAccessible::Role role = QQuickItemPrivate::get(item)->effectiveAccessibleRole();
2380 if (role == QAccessible::EditableText || role == QAccessible::Table || role == QAccessible::List) {
2381 return true;
2382 } else if (role == QAccessible::ComboBox || role == QAccessible::SpinBox) {
2383 if (QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(item))
2384 return iface->state().editable;
2385 }
2386#endif
2387
2388 QVariant editable = item->property("editable");
2389 if (editable.isValid())
2390 return editable.toBool();
2391
2392 QVariant readonly = item->property("readOnly");
2393 if (readonly.isValid() && !readonly.toBool() && item->property("text").isValid())
2394 return true;
2395
2396 return false;
2397}
2398
2410{
2412
2413 if (next == item)
2414 return false;
2415
2416 next->forceActiveFocus(forward ? Qt::TabFocusReason : Qt::BacktabFocusReason);
2417
2418 return true;
2419}
2420
2422{
2423 if (!item) {
2424 qWarning() << "QQuickItemPrivate::nextTabChildItem called with null item.";
2425 return nullptr;
2426 }
2428 const int count = children.size();
2429 if (start < 0 || start >= count) {
2430 qWarning() << "QQuickItemPrivate::nextTabChildItem: Start index value out of range for item" << item;
2431 return nullptr;
2432 }
2433 while (start < count) {
2435 if (!child->d_func()->isTabFence)
2436 return child;
2437 ++start;
2438 }
2439 return nullptr;
2440}
2441
2443{
2444 if (!item) {
2445 qWarning() << "QQuickItemPrivate::prevTabChildItem called with null item.";
2446 return nullptr;
2447 }
2449 const int count = children.size();
2450 if (start == -1)
2451 start = count - 1;
2452 if (start < 0 || start >= count) {
2453 qWarning() << "QQuickItemPrivate::prevTabChildItem: Start index value out of range for item" << item;
2454 return nullptr;
2455 }
2456 while (start >= 0) {
2458 if (!child->d_func()->isTabFence)
2459 return child;
2460 --start;
2461 }
2462 return nullptr;
2463}
2464
2466{
2467 Q_ASSERT(item);
2468 qCDebug(lcFocus) << "QQuickItemPrivate::nextPrevItemInTabFocusChain: item:" << item << ", forward:" << forward;
2469
2470 if (!item->window())
2471 return item;
2472 const QQuickItem * const contentItem = item->window()->contentItem();
2473 if (!contentItem)
2474 return item;
2475
2477
2478 QQuickItem *from = nullptr;
2479 bool isTabFence = item->d_func()->isTabFence;
2480 if (forward) {
2481 if (!isTabFence)
2482 from = item->parentItem();
2483 } else {
2484 if (!item->childItems().isEmpty())
2485 from = item->d_func()->childItems.constFirst();
2486 else if (!isTabFence)
2487 from = item->parentItem();
2488 }
2489 bool skip = false;
2490
2491 QQuickItem *startItem = item;
2492 QQuickItem *originalStartItem = startItem;
2493 // Protect from endless loop:
2494 // If we start on an invisible item we will not find it again.
2495 // If there is no other item which can become the focus item, we have a forever loop,
2496 // since the protection only works if we encounter the first item again.
2497 while (startItem && !startItem->isVisible()) {
2498 startItem = startItem->parentItem();
2499 }
2500 if (!startItem)
2501 return item;
2502
2503 QQuickItem *firstFromItem = from;
2504 QQuickItem *current = item;
2505 qCDebug(lcFocus) << "QQuickItemPrivate::nextPrevItemInTabFocusChain: startItem:" << startItem;
2506 qCDebug(lcFocus) << "QQuickItemPrivate::nextPrevItemInTabFocusChain: firstFromItem:" << firstFromItem;
2507 QDuplicateTracker<QQuickItem *> cycleDetector;
2508 do {
2509 qCDebug(lcFocus) << "QQuickItemPrivate::nextPrevItemInTabFocusChain: current:" << current;
2510 qCDebug(lcFocus) << "QQuickItemPrivate::nextPrevItemInTabFocusChain: from:" << from;
2511 skip = false;
2512 QQuickItem *last = current;
2513
2514 bool hasChildren = !current->childItems().isEmpty() && current->isEnabled() && current->isVisible();
2515 QQuickItem *firstChild = nullptr;
2516 QQuickItem *lastChild = nullptr;
2517 if (hasChildren) {
2518 firstChild = nextTabChildItem(current, 0);
2519 if (!firstChild)
2520 hasChildren = false;
2521 else
2522 lastChild = prevTabChildItem(current, -1);
2523 }
2524 isTabFence = current->d_func()->isTabFence;
2525 if (isTabFence && !hasChildren)
2526 return current;
2527
2528 // coming from parent: check children
2529 if (hasChildren && from == current->parentItem()) {
2530 if (forward) {
2531 current = firstChild;
2532 } else {
2533 current = lastChild;
2534 if (!current->childItems().isEmpty())
2535 skip = true;
2536 }
2537 } else if (hasChildren && forward && from != lastChild) {
2538 // not last child going forwards
2539 int nextChild = current->childItems().indexOf(from) + 1;
2540 current = nextTabChildItem(current, nextChild);
2541 } else if (hasChildren && !forward && from != firstChild) {
2542 // not first child going backwards
2543 int prevChild = current->childItems().indexOf(from) - 1;
2544 current = prevTabChildItem(current, prevChild);
2545 if (!current->childItems().isEmpty())
2546 skip = true;
2547 // back to the parent
2548 } else if (QQuickItem *parent = !isTabFence ? current->parentItem() : nullptr) {
2549 // we would evaluate the parent twice, thus we skip
2550 if (forward) {
2551 skip = true;
2552 } else if (QQuickItem *firstSibling = !forward ? nextTabChildItem(parent, 0) : nullptr) {
2553 if (last != firstSibling
2554 || (parent->isFocusScope() && parent->activeFocusOnTab() && parent->hasActiveFocus()))
2555 skip = true;
2556 }
2557 current = parent;
2558 } else if (hasChildren) {
2559 // Wrap around after checking all items forward
2560 if (forward) {
2561 current = firstChild;
2562 } else {
2563 current = lastChild;
2564 if (!current->childItems().isEmpty())
2565 skip = true;
2566 }
2567 }
2568 from = last;
2569 // if [from] item is equal to [firstFromItem], means we have traversed one path and
2570 // jump back to parent of the chain, and then we have to check whether we have
2571 // traversed all of the chain (by compare the [current] item with [startItem])
2572 // Since the [startItem] might be promoted to its parent if it is invisible,
2573 // we still have to check [current] item with original start item
2574 // We might also run into a cycle before we reach firstFromItem again
2575 // but note that we have to ignore current if we are meant to skip it
2576 if (((current == startItem || current == originalStartItem) && from == firstFromItem) ||
2577 (!skip && cycleDetector.hasSeen(current))) {
2578 // wrapped around, avoid endless loops
2579 if (item == contentItem) {
2580 qCDebug(lcFocus) << "QQuickItemPrivate::nextPrevItemInTabFocusChain: looped, return contentItem";
2581 return item;
2582 } else {
2583 qCDebug(lcFocus) << "QQuickItemPrivate::nextPrevItemInTabFocusChain: looped, return " << startItem;
2584 return startItem;
2585 }
2586 }
2587 if (!firstFromItem) {
2588 if (startItem->d_func()->isTabFence) {
2589 if (current == startItem)
2590 firstFromItem = from;
2591 } else { //start from root
2592 startItem = current;
2593 firstFromItem = from;
2594 }
2595 }
2596 } while (skip || !current->activeFocusOnTab() || !current->isEnabled() || !current->isVisible()
2597 || !(all || QQuickItemPrivate::canAcceptTabFocus(current)));
2598
2599 return current;
2600}
2601
2627{
2628 Q_D(const QQuickItem);
2629 return d->parentItem;
2630}
2631
2633{
2634 Q_D(QQuickItem);
2635 if (parentItem == d->parentItem)
2636 return;
2637
2638 if (parentItem) {
2639 QQuickItem *itemAncestor = parentItem;
2640 while (itemAncestor != nullptr) {
2641 if (Q_UNLIKELY(itemAncestor == this)) {
2642 qWarning() << "QQuickItem::setParentItem: Parent" << parentItem << "is already part of the subtree of" << this;
2643 return;
2644 }
2645 itemAncestor = itemAncestor->parentItem();
2646 }
2647 }
2648
2649 d->removeFromDirtyList();
2650
2651 QQuickItem *oldParentItem = d->parentItem;
2652 QQuickItem *scopeFocusedItem = nullptr;
2653
2654 if (oldParentItem) {
2655 QQuickItemPrivate *op = QQuickItemPrivate::get(oldParentItem);
2656
2657 QQuickItem *scopeItem = nullptr;
2658
2659 if (hasFocus() || op->subFocusItem == this)
2660 scopeFocusedItem = this;
2661 else if (!isFocusScope() && d->subFocusItem)
2662 scopeFocusedItem = d->subFocusItem;
2663
2664 if (scopeFocusedItem) {
2665 scopeItem = oldParentItem;
2666 while (!scopeItem->isFocusScope() && scopeItem->parentItem())
2667 scopeItem = scopeItem->parentItem();
2668 if (d->window) {
2669 d->deliveryAgentPrivate()->
2670 clearFocusInScope(scopeItem, scopeFocusedItem, Qt::OtherFocusReason,
2672 if (scopeFocusedItem != this)
2673 QQuickItemPrivate::get(scopeFocusedItem)->updateSubFocusItem(this, true);
2674 } else {
2675 QQuickItemPrivate::get(scopeFocusedItem)->updateSubFocusItem(scopeItem, false);
2676 }
2677 }
2678
2679 const bool wasVisible = isVisible();
2680 op->removeChild(this);
2681 if (wasVisible && !op->inDestructor)
2682 emit oldParentItem->visibleChildrenChanged();
2683 } else if (d->window) {
2685 }
2686
2687 QQuickWindow *parentWindow = parentItem ? QQuickItemPrivate::get(parentItem)->window : nullptr;
2688 bool alreadyAddedChild = false;
2689 if (d->window == parentWindow) {
2690 // Avoid freeing and reallocating resources if the window stays the same.
2691 d->parentItem = parentItem;
2692 } else {
2693 auto oldParentItem = d->parentItem;
2694 d->parentItem = parentItem;
2695 if (d->parentItem) {
2696 QQuickItemPrivate::get(d->parentItem)->addChild(this);
2697 alreadyAddedChild = true;
2698 }
2699 if (d->window) {
2700 d->derefWindow();
2701 // as we potentially changed d->parentWindow above
2702 // the check in derefWindow could not work
2703 // thus, we redo it here with the old parent
2704 // Also, the window may have been deleted by derefWindow()
2705 if (!oldParentItem && d->window) {
2707 }
2708 }
2709 if (parentWindow)
2710 d->refWindow(parentWindow);
2711 }
2712
2714
2715 if (d->parentItem && !alreadyAddedChild)
2716 QQuickItemPrivate::get(d->parentItem)->addChild(this);
2717 else if (d->window && !alreadyAddedChild)
2719
2720 d->setEffectiveVisibleRecur(d->calcEffectiveVisible());
2721 d->setEffectiveEnableRecur(nullptr, d->calcEffectiveEnable());
2722
2723 if (d->parentItem) {
2724 if (!scopeFocusedItem) {
2725 if (hasFocus())
2726 scopeFocusedItem = this;
2727 else if (!isFocusScope() && d->subFocusItem)
2728 scopeFocusedItem = d->subFocusItem;
2729 }
2730
2731 if (scopeFocusedItem) {
2732 // We need to test whether this item becomes scope focused
2733 QQuickItem *scopeItem = d->parentItem;
2734 while (!scopeItem->isFocusScope() && scopeItem->parentItem())
2735 scopeItem = scopeItem->parentItem();
2736
2737 if (QQuickItemPrivate::get(scopeItem)->subFocusItem
2738 || (!scopeItem->isFocusScope() && scopeItem->hasFocus())) {
2739 if (scopeFocusedItem != this)
2740 QQuickItemPrivate::get(scopeFocusedItem)->updateSubFocusItem(this, false);
2741 QQuickItemPrivate::get(scopeFocusedItem)->focus = false;
2742 emit scopeFocusedItem->focusChanged(false);
2743 } else {
2744 if (d->window) {
2745 d->deliveryAgentPrivate()->
2746 setFocusInScope(scopeItem, scopeFocusedItem, Qt::OtherFocusReason,
2748 } else {
2749 QQuickItemPrivate::get(scopeFocusedItem)->updateSubFocusItem(scopeItem, true);
2750 }
2751 }
2752 }
2753 }
2754
2755 if (d->parentItem)
2756 d->resolveLayoutMirror();
2757
2758 d->itemChange(ItemParentHasChanged, d->parentItem);
2759
2760 if (!d->inDestructor)
2761 emit parentChanged(d->parentItem);
2762 if (isVisible() && d->parentItem && !QQuickItemPrivate::get(d->parentItem)->inDestructor)
2763 emit d->parentItem->visibleChildrenChanged();
2764}
2765
2784{
2785 Q_D(QQuickItem);
2786 if (!sibling || sibling == this || !d->parentItem || d->parentItem != QQuickItemPrivate::get(sibling)->parentItem) {
2787 qWarning().nospace() << "QQuickItem::stackBefore: Cannot stack "
2788 << this << " before " << sibling << ", which must be a sibling";
2789 return;
2790 }
2791
2792 QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(d->parentItem);
2793
2794 int myIndex = parentPrivate->childItems.lastIndexOf(this);
2795 int siblingIndex = parentPrivate->childItems.lastIndexOf(const_cast<QQuickItem *>(sibling));
2796
2797 Q_ASSERT(myIndex != -1 && siblingIndex != -1);
2798
2799 if (myIndex == siblingIndex - 1)
2800 return;
2801
2802 parentPrivate->childItems.move(myIndex, myIndex < siblingIndex ? siblingIndex - 1 : siblingIndex);
2803
2805 parentPrivate->markSortedChildrenDirty(this);
2806
2807 for (int ii = qMin(siblingIndex, myIndex); ii < parentPrivate->childItems.size(); ++ii)
2808 QQuickItemPrivate::get(parentPrivate->childItems.at(ii))->siblingOrderChanged();
2809}
2810
2829{
2830 Q_D(QQuickItem);
2831 if (!sibling || sibling == this || !d->parentItem || d->parentItem != QQuickItemPrivate::get(sibling)->parentItem) {
2832 qWarning().nospace() << "QQuickItem::stackAfter: Cannot stack "
2833 << this << " after " << sibling << ", which must be a sibling";
2834 return;
2835 }
2836
2837 QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(d->parentItem);
2838
2839 int myIndex = parentPrivate->childItems.lastIndexOf(this);
2840 int siblingIndex = parentPrivate->childItems.lastIndexOf(const_cast<QQuickItem *>(sibling));
2841
2842 Q_ASSERT(myIndex != -1 && siblingIndex != -1);
2843
2844 if (myIndex == siblingIndex + 1)
2845 return;
2846
2847 parentPrivate->childItems.move(myIndex, myIndex > siblingIndex ? siblingIndex + 1 : siblingIndex);
2848
2850 parentPrivate->markSortedChildrenDirty(this);
2851
2852 for (int ii = qMin(myIndex, siblingIndex + 1); ii < parentPrivate->childItems.size(); ++ii)
2853 QQuickItemPrivate::get(parentPrivate->childItems.at(ii))->siblingOrderChanged();
2854}
2855
2868{
2869 Q_D(const QQuickItem);
2870 return d->window;
2871}
2872
2874{
2875 return lhs->z() < rhs->z();
2876}
2877
2879{
2880 if (sortedChildItems)
2881 return *sortedChildItems;
2882
2883 // If none of the items have set Z then the paint order list is the same as
2884 // the childItems list. This is by far the most common case.
2885 bool haveZ = false;
2886 for (int i = 0; i < childItems.size(); ++i) {
2887 if (QQuickItemPrivate::get(childItems.at(i))->z() != 0.) {
2888 haveZ = true;
2889 break;
2890 }
2891 }
2892 if (haveZ) {
2894 std::stable_sort(sortedChildItems->begin(), sortedChildItems->end(), itemZOrder_sort);
2895 return *sortedChildItems;
2896 }
2897
2899
2900 return childItems;
2901}
2902
2904{
2905 Q_Q(QQuickItem);
2906
2908
2910
2912
2913#if QT_CONFIG(cursor)
2914 // if the added child has a cursor and we do not currently have any children
2915 // with cursors, bubble the notification up
2916 if (childPrivate->subtreeCursorEnabled && !subtreeCursorEnabled)
2917 setHasCursorInChild(true);
2918#endif
2919
2920 if (childPrivate->subtreeHoverEnabled && !subtreeHoverEnabled)
2921 setHasHoverInChild(true);
2922
2923 childPrivate->recursiveRefFromEffectItem(extra.value().recursiveEffectRefCount);
2926
2928
2929 emit q->childrenChanged();
2930}
2931
2933{
2934 Q_Q(QQuickItem);
2935
2936 Q_ASSERT(child);
2937 if (!inDestructor) {
2938 // if we are getting destroyed, then the destructor will clear the list
2942 }
2943
2945
2946#if QT_CONFIG(cursor)
2947 // turn it off, if nothing else is using it
2948 if (childPrivate->subtreeCursorEnabled && subtreeCursorEnabled)
2949 setHasCursorInChild(false);
2950#endif
2951
2952 if (childPrivate->subtreeHoverEnabled && subtreeHoverEnabled)
2953 setHasHoverInChild(false);
2954
2955 childPrivate->recursiveRefFromEffectItem(-extra.value().recursiveEffectRefCount);
2956 if (!inDestructor) {
2959 }
2960
2962
2963 if (!inDestructor)
2964 emit q->childrenChanged();
2965}
2966
2968{
2969 // An item needs a window if it is referenced by another item which has a window.
2970 // Typically the item is referenced by a parent, but can also be referenced by a
2971 // ShaderEffect or ShaderEffectSource. 'windowRefCount' counts how many items with
2972 // a window is referencing this item. When the reference count goes from zero to one,
2973 // or one to zero, the window of this item is updated and propagated to the children.
2974 // As long as the reference count stays above zero, the window is unchanged.
2975 // refWindow() increments the reference count.
2976 // derefWindow() decrements the reference count.
2977
2978 Q_Q(QQuickItem);
2979 Q_ASSERT((window != nullptr) == (windowRefCount > 0));
2980 Q_ASSERT(c);
2981 if (++windowRefCount > 1) {
2982 if (c != window)
2983 qWarning("QQuickItem: Cannot use same item on different windows at the same time.");
2984 return; // Window already set.
2985 }
2986
2987 Q_ASSERT(window == nullptr);
2988 window = c;
2989
2990 if (polishScheduled)
2992
2993 if (!parentItem)
2995
2996 for (int ii = 0; ii < childItems.size(); ++ii) {
2999 }
3000
3001 dirty(Window);
3002
3003 if (extra.isAllocated() && extra->screenAttached)
3004 extra->screenAttached->windowChanged(c);
3006}
3007
3009{
3010 Q_Q(QQuickItem);
3011 Q_ASSERT((window != nullptr) == (windowRefCount > 0));
3012
3013 if (!window)
3014 return; // This can happen when destroying recursive shader effect sources.
3015
3016 if (--windowRefCount > 0)
3017 return; // There are still other references, so don't set window to null yet.
3018
3019 q->releaseResources();
3022 if (polishScheduled)
3023 c->itemsToPolish.removeOne(q);
3024#if QT_CONFIG(cursor)
3025 if (c->cursorItem == q) {
3026 c->cursorItem = nullptr;
3027 window->unsetCursor();
3028 }
3029#endif
3030 if (itemNodeInstance)
3031 c->cleanup(itemNodeInstance);
3032 if (!parentItem)
3033 c->parentlessItems.remove(q);
3034
3035 window = nullptr;
3036
3037 itemNodeInstance = nullptr;
3038
3039 if (extra.isAllocated()) {
3040 extra->opacityNode = nullptr;
3041 extra->clipNode = nullptr;
3042 extra->rootNode = nullptr;
3043 }
3044
3045 paintNode = nullptr;
3046
3047 for (int ii = 0; ii < childItems.size(); ++ii) {
3050 }
3051
3052 dirty(Window);
3053
3054 if (extra.isAllocated() && extra->screenAttached)
3055 extra->screenAttached->windowChanged(nullptr);
3057}
3058
3059
3064{
3065 // XXX todo - optimize
3067}
3068
3073{
3074 // item's parent must not be itself, otherwise calling itemToWindowTransform() on it is infinite recursion
3078 return rv;
3079}
3080
3085{
3086 /* Read the current x and y values. As this is an internal method,
3087 we don't care about it being usable in bindings. Instead, we
3088 care about performance here, and thus we read the value with
3089 valueBypassingBindings. This avoids any checks whether we are
3090 in a binding (which sholdn't be too expensive, but can add up).
3091 */
3092
3093 qreal x = this->x.valueBypassingBindings();
3094 qreal y = this->y.valueBypassingBindings();
3095 if (x || y)
3096 t->translate(x, y);
3097
3098 if (!transforms.isEmpty()) {
3099 QMatrix4x4 m(*t);
3100 for (int ii = transforms.size() - 1; ii >= 0; --ii)
3101 transforms.at(ii)->applyTo(&m);
3102 *t = m.toTransform();
3103 }
3104
3105 if (scale() != 1. || rotation() != 0.) {
3107 t->translate(tp.x(), tp.y());
3108 t->scale(scale(), scale());
3109 t->rotate(rotation());
3110 t->translate(-tp.x(), -tp.y());
3111 }
3112}
3113
3118{
3119 if (Q_UNLIKELY(window == nullptr))
3120 return QTransform();
3121
3122 QPoint quickWidgetOffset;
3123 QWindow *renderWindow = QQuickRenderControl::renderWindowFor(window, &quickWidgetOffset);
3124 QPointF pos = (renderWindow ? renderWindow : window)->mapToGlobal(quickWidgetOffset);
3125 return QTransform::fromTranslate(pos.x(), pos.y());
3126}
3127
3132{
3133 if (Q_UNLIKELY(window == nullptr))
3134 return QTransform();
3135
3136 QPoint quickWidgetOffset;
3137 QWindow *renderWindow = QQuickRenderControl::renderWindowFor(window, &quickWidgetOffset);
3138 QPointF pos = (renderWindow ? renderWindow : window)->mapToGlobal(quickWidgetOffset);
3139 return QTransform::fromTranslate(-pos.x(), -pos.y());
3140}
3141
3152{
3153 Q_D(const QQuickItem);
3154 return d->componentComplete;
3155}
3156
3158 : _anchors(nullptr)
3159 , _stateGroup(nullptr)
3160 , flags(0)
3161 , widthValidFlag(false)
3162 , heightValidFlag(false)
3163 , componentComplete(true)
3164 , keepMouse(false)
3165 , keepTouch(false)
3166 , hoverEnabled(false)
3167 , smooth(true)
3168 , antialiasing(false)
3169 , focus(false)
3170 , activeFocus(false)
3171 , notifiedFocus(false)
3172 , notifiedActiveFocus(false)
3173 , filtersChildMouseEvents(false)
3174 , explicitVisible(true)
3175 , effectiveVisible(true)
3176 , explicitEnable(true)
3177 , effectiveEnable(true)
3178 , polishScheduled(false)
3179 , inheritedLayoutMirror(false)
3180 , effectiveLayoutMirror(false)
3181 , isMirrorImplicit(true)
3182 , inheritMirrorFromParent(false)
3183 , inheritMirrorFromItem(false)
3184 , isAccessible(false)
3185 , culled(false)
3186 , hasCursor(false)
3187 , subtreeCursorEnabled(false)
3188 , subtreeHoverEnabled(false)
3189 , activeFocusOnTab(false)
3190 , implicitAntialiasing(false)
3191 , antialiasingValid(false)
3192 , isTabFence(false)
3193 , replayingPressEvent(false)
3194 , touchEnabled(false)
3195 , hasCursorHandler(false)
3196 , maybeHasSubsceneDeliveryAgent(true)
3197 , subtreeTransformChangedEnabled(true)
3198 , inDestructor(false)
3199 , dirtyAttributes(0)
3200 , nextDirtyItem(nullptr)
3201 , prevDirtyItem(nullptr)
3202 , window(nullptr)
3203 , windowRefCount(0)
3204 , parentItem(nullptr)
3205 , sortedChildItems(&childItems)
3206 , subFocusItem(nullptr)
3207 , x(0)
3208 , y(0)
3209 , width(0)
3210 , height(0)
3211 , implicitWidth(0)
3212 , implicitHeight(0)
3213 , baselineOffset(0)
3214 , itemNodeInstance(nullptr)
3215 , paintNode(nullptr)
3216{
3217}
3218
3220{
3222 delete sortedChildItems;
3223}
3224
3226{
3227 Q_Q(QQuickItem);
3228
3229 isQuickItem = true;
3230
3231 baselineOffset = 0.0;
3232
3233 if (parent) {
3234 q->setParentItem(parent);
3237 }
3238}
3239
3241{
3242 if (!o)
3243 return;
3244
3245 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
3246
3248 item->setParentItem(that);
3249 } else {
3250 if (QQuickPointerHandler *pointerHandler = qmlobject_cast<QQuickPointerHandler *>(o)) {
3251 if (pointerHandler->parent() != that) {
3252 qCDebug(lcHandlerParent) << "reparenting handler" << pointerHandler << ":" << pointerHandler->parent() << "->" << that;
3253 pointerHandler->setParent(that);
3254 }
3255 QQuickItemPrivate::get(that)->addPointerHandler(pointerHandler);
3256 } else {
3257 QQuickWindow *thisWindow = qmlobject_cast<QQuickWindow *>(o);
3258 QQuickItem *item = that;
3259 QQuickWindow *itemWindow = that->window();
3260 while (!itemWindow && item && item->parentItem()) {
3261 item = item->parentItem();
3262 itemWindow = item->window();
3263 }
3264
3265 if (thisWindow) {
3266 if (itemWindow) {
3267 qCDebug(lcTransient) << thisWindow << "is transient for" << itemWindow;
3268 thisWindow->setTransientParent(itemWindow);
3269 } else {
3270 QObject::connect(item, SIGNAL(windowChanged(QQuickWindow*)),
3271 thisWindow, SLOT(setTransientParent_helper(QQuickWindow*)));
3272 }
3273 }
3274 o->setParent(that);
3275 resources_append(prop, o);
3276 }
3277 }
3278}
3279
3316{
3317 QQuickItem *item = static_cast<QQuickItem*>(property->object);
3319 QQmlListProperty<QObject> resourcesProperty = privateItem->resources();
3320 QQmlListProperty<QQuickItem> childrenProperty = privateItem->children();
3321
3322 return resources_count(&resourcesProperty) + children_count(&childrenProperty);
3323}
3324
3326{
3327 QQuickItem *item = static_cast<QQuickItem*>(property->object);
3329 QQmlListProperty<QObject> resourcesProperty = privateItem->resources();
3330 QQmlListProperty<QQuickItem> childrenProperty = privateItem->children();
3331
3332 qsizetype resourcesCount = resources_count(&resourcesProperty);
3333 if (i < resourcesCount)
3334 return resources_at(&resourcesProperty, i);
3335 const qsizetype j = i - resourcesCount;
3336 if (j < children_count(&childrenProperty))
3337 return children_at(&childrenProperty, j);
3338 return nullptr;
3339}
3340
3342{
3343 QQuickItem *item = static_cast<QQuickItem*>(property->object);
3345 QQmlListProperty<QObject> resourcesProperty = privateItem->resources();
3346 QQmlListProperty<QQuickItem> childrenProperty = privateItem->children();
3347
3348 resources_clear(&resourcesProperty);
3349 children_clear(&childrenProperty);
3350}
3351
3353{
3354 QQuickItem *item = static_cast<QQuickItem*>(property->object);
3356
3357 QQmlListProperty<QQuickItem> childrenProperty = privateItem->children();
3358 if (children_count(&childrenProperty) > 0) {
3359 children_removeLast(&childrenProperty);
3360 return;
3361 }
3362
3363 QQmlListProperty<QObject> resourcesProperty = privateItem->resources();
3364 if (resources_count(&resourcesProperty) > 0)
3365 resources_removeLast(&resourcesProperty);
3366}
3367
3369{
3370 QQuickItemPrivate *quickItemPrivate = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
3371 return quickItemPrivate->extra.isAllocated() ? quickItemPrivate->extra->resourcesList.value(index) : 0;
3372}
3373
3375{
3376 QQuickItem *quickItem = static_cast<QQuickItem *>(prop->object);
3377 QQuickItemPrivate *quickItemPrivate = QQuickItemPrivate::get(quickItem);
3378 if (!quickItemPrivate->extra.value().resourcesList.contains(object)) {
3379 quickItemPrivate->extra.value().resourcesList.append(object);
3380 qmlobject_connect(object, QObject, SIGNAL(destroyed(QObject*)),
3382 }
3383}
3384
3386{
3387 QQuickItemPrivate *quickItemPrivate = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
3388 return quickItemPrivate->extra.isAllocated() ? quickItemPrivate->extra->resourcesList.size() : 0;
3389}
3390
3392{
3393 QQuickItem *quickItem = static_cast<QQuickItem *>(prop->object);
3394 QQuickItemPrivate *quickItemPrivate = QQuickItemPrivate::get(quickItem);
3395 if (quickItemPrivate->extra.isAllocated()) {//If extra is not allocated resources is empty.
3396 for (QObject *object : std::as_const(quickItemPrivate->extra->resourcesList)) {
3397 qmlobject_disconnect(object, QObject, SIGNAL(destroyed(QObject*)),
3399 }
3400 quickItemPrivate->extra->resourcesList.clear();
3401 }
3402}
3403
3405{
3406 QQuickItem *quickItem = static_cast<QQuickItem *>(prop->object);
3407 QQuickItemPrivate *quickItemPrivate = QQuickItemPrivate::get(quickItem);
3408 if (quickItemPrivate->extra.isAllocated()) {//If extra is not allocated resources is empty.
3409 QList<QObject *> *resources = &quickItemPrivate->extra->resourcesList;
3410 if (resources->isEmpty())
3411 return;
3412
3413 qmlobject_disconnect(resources->last(), QObject, SIGNAL(destroyed(QObject*)),
3416 }
3417}
3418
3420{
3422 if (index >= p->childItems.size() || index < 0)
3423 return nullptr;
3424 else
3425 return p->childItems.at(index);
3426}
3427
3429{
3430 if (!o)
3431 return;
3432
3433 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
3434 if (o->parentItem() == that)
3435 o->setParentItem(nullptr);
3436
3437 o->setParentItem(that);
3438}
3439
3441{
3443 return p->childItems.size();
3444}
3445
3447{
3448 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
3450 while (!p->childItems.isEmpty())
3451 p->childItems.at(0)->setParentItem(nullptr);
3452}
3453
3455{
3456 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
3458 if (!p->childItems.isEmpty())
3459 p->childItems.last()->setParentItem(nullptr);
3460}
3461
3463{
3465 qsizetype visibleCount = 0;
3466 qsizetype c = p->childItems.size();
3467 while (c--) {
3468 if (p->childItems.at(c)->isVisible()) visibleCount++;
3469 }
3470
3471 return visibleCount;
3472}
3473
3475{
3477 const qsizetype childCount = p->childItems.size();
3478 if (index >= childCount || index < 0)
3479 return nullptr;
3480
3481 qsizetype visibleCount = -1;
3482 for (qsizetype i = 0; i < childCount; i++) {
3483 if (p->childItems.at(i)->isVisible()) visibleCount++;
3484 if (visibleCount == index) return p->childItems.at(i);
3485 }
3486 return nullptr;
3487}
3488
3490{
3491 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
3493
3494 return p->transforms.size();
3495}
3496
3498{
3499 Q_D(QQuickTransform);
3500 if (!item)
3501 return;
3502
3504
3505 if (!d->items.isEmpty() && !p->transforms.isEmpty() && p->transforms.contains(this)) {
3506 p->transforms.removeOne(this);
3507 p->transforms.append(this);
3508 } else {
3509 p->transforms.append(this);
3510 d->items.append(item);
3511 }
3512
3514}
3515
3517{
3518 Q_D(QQuickTransform);
3519 if (!item)
3520 return;
3521
3523
3524 if (!d->items.isEmpty() && !p->transforms.isEmpty() && p->transforms.contains(this)) {
3525 p->transforms.removeOne(this);
3526 p->transforms.prepend(this);
3527 } else {
3528 p->transforms.prepend(this);
3529 d->items.append(item);
3530 }
3531
3533}
3534
3536{
3537 if (!transform)
3538 return;
3539
3540 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
3541 transform->appendToItem(that);
3542}
3543
3545{
3546 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
3548
3549 if (idx < 0 || idx >= p->transforms.size())
3550 return nullptr;
3551 else
3552 return p->transforms.at(idx);
3553}
3554
3556{
3557 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
3559
3560 for (qsizetype ii = 0; ii < p->transforms.size(); ++ii) {
3561 QQuickTransform *t = p->transforms.at(ii);
3563 tp->items.removeOne(that);
3564 }
3565
3566 p->transforms.clear();
3567
3569}
3570
3572{
3573 if (extra.isAllocated() && extra->resourcesList.contains(object))
3574 extra->resourcesList.removeAll(object);
3575}
3576
3672{
3673 if (!_anchors) {
3674 Q_Q(const QQuickItem);
3675 _anchors = new QQuickAnchors(const_cast<QQuickItem *>(q));
3676 if (!componentComplete)
3678 }
3679 return _anchors;
3680}
3681
3683{
3684 Q_Q(QQuickItem);
3686}
3687
3689{
3690 // Do not synthesize replace().
3691 // It would be extremely expensive and wouldn't work with most methods.
3693 result.object = q_func();
3699 return result;
3700}
3701
3734{
3735 Q_D(QQuickItem);
3736 if (!d->extra.isAllocated() || !d->extra->contents) {
3737 d->extra.value().contents = new QQuickContents(this);
3738 if (d->componentComplete)
3739 d->extra->contents->complete();
3740 }
3741 return d->extra->contents->rectF();
3742}
3743
3748{
3749 Q_D(const QQuickItem);
3750 return d->childItems;
3751}
3752
3782{
3784}
3785
3787{
3788 if (clip() == c)
3789 return;
3790
3792 if (c)
3794 else if (!(inherits("QQuickFlickable") || inherits("QQuickRootItem")))
3795 setFlag(ItemIsViewport, false);
3796
3798}
3799
3809void QQuickItem::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry)
3810{
3811 Q_D(QQuickItem);
3812
3813 if (d->_anchors)
3814 QQuickAnchorsPrivate::get(d->_anchors)->updateMe();
3815
3816 QQuickGeometryChange change;
3817 change.setXChange(newGeometry.x() != oldGeometry.x());
3818 change.setYChange(newGeometry.y() != oldGeometry.y());
3819 change.setWidthChange(newGeometry.width() != oldGeometry.width());
3820 change.setHeightChange(newGeometry.height() != oldGeometry.height());
3821
3822 d->notifyChangeListeners(QQuickItemPrivate::Geometry, [&](const QQuickItemPrivate::ChangeListener &listener){
3823 if (change.matches(listener.gTypes))
3824 listener.listener->itemGeometryChanged(this, change, oldGeometry);
3825 });
3826
3827 // The notify method takes care of emitting the signal, and also notifies any
3828 // property observers.
3829 if (change.xChange())
3830 d->x.notify();
3831 if (change.yChange())
3832 d->y.notify();
3833 if (change.widthChange())
3834 d->width.notify();
3835 if (change.heightChange())
3836 d->height.notify();
3837#if QT_CONFIG(accessibility)
3838 if (QAccessible::isActive()) {
3839 if (QObject *acc = QQuickAccessibleAttached::findAccessible(this)) {
3840 QAccessibleEvent ev(acc, QAccessible::LocationChanged);
3841 QAccessible::updateAccessibility(&ev);
3842 }
3843 }
3844#endif
3845}
3846
3902{
3903 Q_UNUSED(updatePaintNodeData);
3904 delete oldNode;
3905 return nullptr;
3906}
3907
3908QQuickItem::UpdatePaintNodeData::UpdatePaintNodeData()
3909: transformNode(nullptr)
3910{
3911}
3912
3931{
3932}
3933
3935{
3936 return new QSGTransformNode;
3937}
3938
3950{
3951}
3952
3953#define PRINT_LISTENERS() \
3954do { \
3955 qDebug().nospace() << q_func() << " (" << this \
3956 << ") now has the following listeners:"; \
3957 for (const auto &listener : std::as_const(changeListeners)) { \
3958 const auto objectPrivate = dynamic_cast<QObjectPrivate*>(listener.listener); \
3959 qDebug().nospace() << "- " << listener << " (QObject: " << (objectPrivate ? objectPrivate->q_func() : nullptr) << ")"; \
3960 } \
3961} \
3962while (false)
3963
3965{
3966 changeListeners.append(ChangeListener(listener, types));
3967
3968 if (lcChangeListeners().isDebugEnabled())
3970}
3971
3973{
3974 const ChangeListener changeListener(listener, types);
3975 const int index = changeListeners.indexOf(changeListener);
3976 if (index > -1)
3977 changeListeners[index].types = changeListener.types;
3978 else
3979 changeListeners.append(changeListener);
3980
3981 if (lcChangeListeners().isDebugEnabled())
3983}
3984
3986{
3987 ChangeListener change(listener, types);
3988 changeListeners.removeOne(change);
3989
3990 if (lcChangeListeners().isDebugEnabled())
3992}
3993
3996{
3997 ChangeListener change(listener, types);
3998 int index = changeListeners.indexOf(change);
3999 if (index > -1)
4000 changeListeners[index].gTypes = change.gTypes; //we may have different GeometryChangeTypes
4001 else
4002 changeListeners.append(change);
4003
4004 if (lcChangeListeners().isDebugEnabled())
4006}
4007
4010{
4011 ChangeListener change(listener, types);
4012 if (types.noChange()) {
4013 changeListeners.removeOne(change);
4014 } else {
4015 int index = changeListeners.indexOf(change);
4016 if (index > -1)
4017 changeListeners[index].gTypes = change.gTypes; //we may have different GeometryChangeTypes
4018 }
4019
4020 if (lcChangeListeners().isDebugEnabled())
4022}
4023
4032{
4033 event->ignore();
4034}
4035
4044{
4045 event->ignore();
4046}
4047
4048#if QT_CONFIG(im)
4056void QQuickItem::inputMethodEvent(QInputMethodEvent *event)
4057{
4058 event->ignore();
4059}
4060#endif // im
4061
4073{
4074#if QT_CONFIG(accessibility)
4075 if (QAccessible::isActive()) {
4076 if (QObject *acc = QQuickAccessibleAttached::findAccessible(this)) {
4077 QAccessibleEvent ev(acc, QAccessible::Focus);
4078 QAccessible::updateAccessibility(&ev);
4079 }
4080 }
4081#endif
4082}
4083
4092{
4093}
4094
4106{
4107 event->ignore();
4108}
4109
4122{
4123 event->ignore();
4124}
4125
4138{
4139 event->ignore();
4140}
4141
4150{
4151 event->ignore();
4152}
4153
4159{
4160 // XXX todo
4161}
4162
4168{
4169 // XXX todo
4170}
4171
4172#if QT_CONFIG(wheelevent)
4180void QQuickItem::wheelEvent(QWheelEvent *event)
4181{
4182 event->ignore();
4183}
4184#endif
4185
4194{
4195 event->ignore();
4196}
4197
4208{
4209 event->ignore();
4210}
4211
4222{
4223 event->ignore();
4224}
4225
4236{
4237 event->ignore();
4238}
4239
4240#if QT_CONFIG(quick_draganddrop)
4253void QQuickItem::dragEnterEvent(QDragEnterEvent *event)
4254{
4255 Q_UNUSED(event);
4256}
4257
4270void QQuickItem::dragMoveEvent(QDragMoveEvent *event)
4271{
4272 Q_UNUSED(event);
4273}
4274
4287void QQuickItem::dragLeaveEvent(QDragLeaveEvent *event)
4288{
4289 Q_UNUSED(event);
4290}
4291
4304void QQuickItem::dropEvent(QDropEvent *event)
4305{
4306 Q_UNUSED(event);
4307}
4308#endif // quick_draganddrop
4309
4337{
4338 Q_UNUSED(item);
4339 Q_UNUSED(event);
4340 return false;
4341}
4342
4343#if QT_CONFIG(im)
4352QVariant QQuickItem::inputMethodQuery(Qt::InputMethodQuery query) const
4353{
4354 Q_D(const QQuickItem);
4355 QVariant v;
4356
4357 switch (query) {
4358 case Qt::ImEnabled:
4359 v = (bool)(flags() & ItemAcceptsInputMethod);
4360 break;
4361 case Qt::ImHints:
4364 case Qt::ImFont:
4371 case Qt::ImReadOnly:
4372 if (d->extra.isAllocated() && d->extra->keyHandler)
4373 v = d->extra->keyHandler->inputMethodQuery(query);
4374 break;
4375 case Qt::ImEnterKeyType:
4376 if (d->extra.isAllocated() && d->extra->enterKeyAttached)
4377 v = d->extra->enterKeyAttached->type();
4378 break;
4380 if (!(!window() ||!isVisible() || qFuzzyIsNull(opacity()))) {
4381 QRectF rect = QRectF(0,0, width(), height());
4382 const QQuickItem *par = this;
4383 while (QQuickItem *parpar = par->parentItem()) {
4384 rect = parpar->mapRectFromItem(par, rect);
4385 if (parpar->clip())
4386 rect = rect.intersected(parpar->clipRect());
4387 par = parpar;
4388 }
4389 rect = par->mapRectToScene(rect);
4390 // once we have the rect in scene coordinates, clip to window
4391 rect = rect.intersected(QRectF(QPoint(0,0), window()->size()));
4392 // map it back to local coordinates
4394 }
4395 break;
4396 default:
4397 break;
4398 }
4399
4400 return v;
4401}
4402#endif // im
4403
4405{
4406 Q_Q(const QQuickItem);
4408}
4409
4411{
4412 Q_Q(const QQuickItem);
4414}
4415
4417{
4418 Q_Q(const QQuickItem);
4420}
4421
4423{
4424 Q_Q(const QQuickItem);
4425 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchors::TopAnchor);
4426}
4427
4429{
4430 Q_Q(const QQuickItem);
4432}
4433
4435{
4436 Q_Q(const QQuickItem);
4438}
4439
4441{
4442 Q_Q(const QQuickItem);
4444}
4445
4469{
4470 Q_D(const QQuickItem);
4471 return d->baselineOffset;
4472}
4473
4475{
4476 Q_D(QQuickItem);
4477 if (offset == d->baselineOffset)
4478 return;
4479
4480 d->baselineOffset = offset;
4481
4482 d->notifyChangeListeners(QQuickItemPrivate::Geometry, [](const QQuickItemPrivate::ChangeListener &change){
4483 QQuickAnchorsPrivate *anchor = change.listener->anchorPrivate();
4484 if (anchor)
4485 anchor->updateVerticalAnchors();
4486 });
4487
4488 if (d->_anchors && (d->_anchors->usedAnchors() & QQuickAnchors::BaselineAnchor))
4490
4492}
4493
4494
4505{
4506 Q_D(QQuickItem);
4507 if (!(flags() & ItemHasContents)) {
4508#ifndef QT_NO_DEBUG
4509 qWarning() << metaObject()->className() << ": Update called for a item without content";
4510#endif
4511 return;
4512 }
4514}
4515
4525{
4526 Q_D(QQuickItem);
4527 if (!d->polishScheduled) {
4528 d->polishScheduled = true;
4529 if (d->window) {
4531 bool maybeupdate = p->itemsToPolish.isEmpty();
4532 p->itemsToPolish.append(this);
4533 if (maybeupdate) d->window->maybeUpdate();
4534 }
4535 }
4536}
4537
4553void QQuickItem::ensurePolished()
4554{
4555 updatePolish();
4556}
4557
4558#if QT_DEPRECATED_SINCE(6, 5)
4559static bool unwrapMapFromToFromItemArgs(QQmlV4Function *args, const QQuickItem *itemForWarning, const QString &functionNameForWarning,
4560 QQuickItem **itemObj, qreal *x, qreal *y, qreal *w, qreal *h, bool *isRect)
4561{
4562 QV4::ExecutionEngine *v4 = args->v4engine();
4563 if (args->length() != 2 && args->length() != 3 && args->length() != 5) {
4564 v4->throwTypeError();
4565 return false;
4566 }
4567
4568 QV4::Scope scope(v4);
4569 QV4::ScopedValue item(scope, (*args)[0]);
4570
4571 *itemObj = nullptr;
4572 if (!item->isNull()) {
4573 QV4::Scoped<QV4::QObjectWrapper> qobjectWrapper(scope, item->as<QV4::QObjectWrapper>());
4574 if (qobjectWrapper)
4575 *itemObj = qobject_cast<QQuickItem*>(qobjectWrapper->object());
4576 }
4577
4578 if (!(*itemObj) && !item->isNull()) {
4579 qmlWarning(itemForWarning) << functionNameForWarning << " given argument \"" << item->toQStringNoThrow()
4580 << "\" which is neither null nor an Item";
4581 v4->throwTypeError();
4582 return false;
4583 }
4584
4585 *isRect = false;
4586
4587 if (args->length() == 2) {
4588 QV4::ScopedValue sv(scope, (*args)[1]);
4589 if (sv->isNull()) {
4590 qmlWarning(itemForWarning) << functionNameForWarning << "given argument \"" << sv->toQStringNoThrow()
4591 << "\" which is neither a point nor a rect";
4592 v4->throwTypeError();
4593 return false;
4594 }
4595 const QV4::Scoped<QV4::QQmlValueTypeWrapper> variantWrapper(scope, sv->as<QV4::QQmlValueTypeWrapper>());
4596 const QVariant v = variantWrapper ? variantWrapper->toVariant() : QVariant();
4597 if (v.canConvert<QPointF>()) {
4598 const QPointF p = v.toPointF();
4599 *x = p.x();
4600 *y = p.y();
4601 } else if (v.canConvert<QRectF>()) {
4602 const QRectF r = v.toRectF();
4603 *x = r.x();
4604 *y = r.y();
4605 *w = r.width();
4606 *h = r.height();
4607 *isRect = true;
4608 } else {
4609 qmlWarning(itemForWarning) << functionNameForWarning << "given argument \"" << sv->toQStringNoThrow()
4610 << "\" which is neither a point nor a rect";
4611 v4->throwTypeError();
4612 return false;
4613 }
4614 } else {
4615 QV4::ScopedValue vx(scope, (*args)[1]);
4616 QV4::ScopedValue vy(scope, (*args)[2]);
4617
4618 if (!vx->isNumber() || !vy->isNumber()) {
4619 v4->throwTypeError();
4620 return false;
4621 }
4622
4623 *x = vx->asDouble();
4624 *y = vy->asDouble();
4625
4626 if (args->length() > 3) {
4627 QV4::ScopedValue vw(scope, (*args)[3]);
4628 QV4::ScopedValue vh(scope, (*args)[4]);
4629 if (!vw->isNumber() || !vh->isNumber()) {
4630 v4->throwTypeError();
4631 return false;
4632 }
4633 *w = vw->asDouble();
4634 *h = vh->asDouble();
4635 *isRect = true;
4636 }
4637 }
4638
4639 return true;
4640}
4641#endif
4642
4661#if QT_DEPRECATED_SINCE(6, 5)
4666{
4667 QV4::ExecutionEngine *v4 = args->v4engine();
4668 QV4::Scope scope(v4);
4669
4670 qreal x, y, w, h;
4671 bool isRect;
4672 QQuickItem *itemObj;
4673 if (!unwrapMapFromToFromItemArgs(args, this, QStringLiteral("mapFromItem()"), &itemObj, &x, &y, &w, &h, &isRect))
4674 return;
4675
4676 const QVariant result = isRect ? QVariant(mapRectFromItem(itemObj, QRectF(x, y, w, h)))
4677 : QVariant(mapFromItem(itemObj, QPointF(x, y)));
4678
4679 QV4::ScopedObject rv(scope, v4->fromVariant(result));
4680 args->setReturnValue(rv.asReturnedValue());
4681}
4682#endif
4683
4688{
4689 Q_D(const QQuickItem);
4690
4691 // XXX todo - we need to be able to handle common parents better and detect
4692 // invalid cases
4693 if (ok) *ok = true;
4694
4695 QTransform t = d->itemToWindowTransform();
4697
4698 return t;
4699}
4700
4719#if QT_DEPRECATED_SINCE(6, 5)
4724{
4725 QV4::ExecutionEngine *v4 = args->v4engine();
4726 QV4::Scope scope(v4);
4727
4728 qreal x, y, w, h;
4729 bool isRect;
4730 QQuickItem *itemObj;
4731 if (!unwrapMapFromToFromItemArgs(args, this, QStringLiteral("mapToItem()"), &itemObj, &x, &y, &w, &h, &isRect))
4732 return;
4733
4734 const QVariant result = isRect ? QVariant(mapRectToItem(itemObj, QRectF(x, y, w, h)))
4735 : QVariant(mapToItem(itemObj, QPointF(x, y)));
4736
4737 QV4::ScopedObject rv(scope, v4->fromVariant(result));
4738 args->setReturnValue(rv.asReturnedValue());
4739}
4740
4741static bool unwrapMapFromToFromGlobalArgs(QQmlV4Function *args, const QQuickItem *itemForWarning, const QString &functionNameForWarning, qreal *x, qreal *y)
4742{
4743 QV4::ExecutionEngine *v4 = args->v4engine();
4744 if (args->length() != 1 && args->length() != 2) {
4745 v4->throwTypeError();
4746 return false;
4747 }
4748
4749 QV4::Scope scope(v4);
4750
4751 if (args->length() == 1) {
4752 QV4::ScopedValue sv(scope, (*args)[0]);
4753 if (sv->isNull()) {
4754 qmlWarning(itemForWarning) << functionNameForWarning << "given argument \"" << sv->toQStringNoThrow()
4755 << "\" which is not a point";
4756 v4->throwTypeError();
4757 return false;
4758 }
4759 const QV4::Scoped<QV4::QQmlValueTypeWrapper> variantWrapper(scope, sv->as<QV4::QQmlValueTypeWrapper>());
4760 const QVariant v = variantWrapper ? variantWrapper->toVariant() : QVariant();
4761 if (v.canConvert<QPointF>()) {
4762 const QPointF p = v.toPointF();
4763 *x = p.x();
4764 *y = p.y();
4765 } else {
4766 qmlWarning(itemForWarning) << functionNameForWarning << "given argument \"" << sv->toQStringNoThrow()
4767 << "\" which is not a point";
4768 v4->throwTypeError();
4769 return false;
4770 }
4771 } else {
4772 QV4::ScopedValue vx(scope, (*args)[0]);
4773 QV4::ScopedValue vy(scope, (*args)[1]);
4774
4775 if (!vx->isNumber() || !vy->isNumber()) {
4776 v4->throwTypeError();
4777 return false;
4778 }
4779
4780 *x = vx->asDouble();
4781 *y = vy->asDouble();
4782 }
4783
4784 return true;
4785}
4786
4799void QQuickItem::mapFromGlobal(QQmlV4Function *args) const
4800{
4801 QV4::ExecutionEngine *v4 = args->v4engine();
4802 QV4::Scope scope(v4);
4803
4804 qreal x, y;
4805 if (!unwrapMapFromToFromGlobalArgs(args, this, QStringLiteral("mapFromGlobal()"), &x, &y))
4806 return;
4807
4808 QVariant result = mapFromGlobal(QPointF(x, y));
4809
4810 QV4::ScopedObject rv(scope, v4->fromVariant(result));
4811 args->setReturnValue(rv.asReturnedValue());
4812}
4813#endif
4814
4825#if QT_DEPRECATED_SINCE(6, 5)
4829void QQuickItem::mapToGlobal(QQmlV4Function *args) const
4830{
4831 QV4::ExecutionEngine *v4 = args->v4engine();
4832 QV4::Scope scope(v4);
4833
4834 qreal x, y;
4835 if (!unwrapMapFromToFromGlobalArgs(args, this, QStringLiteral("mapFromGlobal()"), &x, &y))
4836 return;
4837
4838 QVariant result = mapToGlobal(QPointF(x, y));
4839
4840 QV4::ScopedObject rv(scope, v4->fromVariant(result));
4841 args->setReturnValue(rv.asReturnedValue());
4842}
4843#endif
4844
4872{
4874}
4875
4902{
4903 Q_D(QQuickItem);
4904 setFocus(true, reason);
4906 QQuickItem *scope = nullptr;
4907 while (parent) {
4909 parent->setFocus(true, reason);
4910 if (!scope)
4911 scope = parent;
4912 }
4914 }
4915 // In certain reparenting scenarios, d->focus might be true and the scope
4916 // might also have focus, so that setFocus() returns early without actually
4917 // acquiring active focus, because it thinks it already has it. In that
4918 // case, try to set the DeliveryAgent's active focus. (QTBUG-89736).
4919 if (scope && !d->activeFocus) {
4920 if (auto da = d->deliveryAgentPrivate())
4921 da->setFocusInScope(scope, this, Qt::OtherFocusReason);
4922 }
4923}
4924
4942QQuickItem *QQuickItem::nextItemInFocusChain(bool forward)
4943{
4945}
4946
4962{
4964 for (int i = children.size()-1; i >= 0; --i) {
4966 // Map coordinates to the child element's coordinate space
4967 QPointF point = mapToItem(child, QPointF(x, y));
4968 if (child->isVisible() && child->contains(point))
4969 return child;
4970 }
4971 return nullptr;
4972}
4973
5015void QQuickItem::dumpItemTree() const
5016{
5017 Q_D(const QQuickItem);
5018 d->dumpItemTree(0);
5019}
5020
5022{
5023 Q_Q(const QQuickItem);
5024
5025 const auto indentStr = QString(indent * 4, QLatin1Char(' '));
5026 qDebug().nospace().noquote() << indentStr <<
5027#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
5028 const_cast<QQuickItem *>(q);
5029#else
5030 q;
5031#endif
5032 if (extra.isAllocated()) {
5033 for (const auto handler : extra->pointerHandlers)
5034 qDebug().nospace().noquote() << indentStr << u" \u26ee " << handler;
5035 }
5036 for (const QQuickItem *ch : childItems) {
5037 auto itemPriv = QQuickItemPrivate::get(ch);
5038 itemPriv->dumpItemTree(indent + 1);
5039 }
5040}
5041
5043{
5044 // Do not synthesize replace().
5045 // It would be extremely expensive and wouldn't work with most methods.
5047 result.object = q_func();
5053 return result;
5054}
5055
5074{
5075 // Do not synthesize replace().
5076 // It would be extremely expensive and wouldn't work with most methods.
5078 result.object = q_func();
5084 return result;
5085}
5086
5098{
5099 return QQmlListProperty<QQuickItem>(q_func(),
5100 nullptr,
5103
5104}
5105
5147{
5148 return _states()->statesProperty();
5149}
5150
5184{
5185 return _states()->transitionsProperty();
5186}
5187
5189{
5190 if (!_stateGroup)
5191 return QString();
5192 else
5193 return _stateGroup->state();
5194}
5195
5197{
5199}
5200
5224{
5225 Q_D(const QQuickItem);
5226 return d->state();
5227}
5228
5230{
5231 Q_D(QQuickItem);
5232 d->setState(state);
5233}
5234
5249{
5254}
5255
5262{
5263 Q_D(QQuickItem);
5264 d->componentComplete = false;
5265 if (d->_stateGroup)
5266 d->_stateGroup->classBegin();
5267 if (d->_anchors)
5268 d->_anchors->classBegin();
5269#if QT_CONFIG(quick_shadereffect)
5270 if (d->extra.isAllocated() && d->extra->layer)
5271 d->extra->layer->classBegin();
5272#endif
5273}
5274
5281{
5282 Q_D(QQuickItem);
5283 d->componentComplete = true;
5284 if (d->_stateGroup)
5285 d->_stateGroup->componentComplete();
5286 if (d->_anchors) {
5287 d->_anchors->componentComplete();
5289 }
5290
5291 if (d->extra.isAllocated()) {
5292#if QT_CONFIG(quick_shadereffect)
5293 if (d->extra->layer)
5294 d->extra->layer->componentComplete();
5295#endif
5296
5297 if (d->extra->keyHandler)
5298 d->extra->keyHandler->componentComplete();
5299
5300 if (d->extra->contents)
5301 d->extra->contents->complete();
5302 }
5303
5304 if (d->window && d->dirtyAttributes) {
5305 d->addToDirtyList();
5306 QQuickWindowPrivate::get(d->window)->dirtyItem(this);
5307 }
5308
5309#if QT_CONFIG(accessibility)
5310 if (d->isAccessible && d->effectiveVisible) {
5311 QAccessibleEvent ev(this, QAccessible::ObjectShow);
5312 QAccessible::updateAccessibility(&ev);
5313 }
5314#endif
5315}
5316
5318{
5319 Q_Q(QQuickItem);
5320 if (!_stateGroup) {
5322 if (!componentComplete)
5325 q, QQuickItem, SIGNAL(stateChanged(QString)));
5326 }
5327
5328 return _stateGroup;
5329}
5330
5332{
5333 switch (origin()) {
5334 default:
5336 return QPointF(0, 0);
5337 case QQuickItem::Top:
5338 return QPointF(width / 2., 0);
5340 return QPointF(width, 0);
5341 case QQuickItem::Left:
5342 return QPointF(0, height / 2.);
5343 case QQuickItem::Center:
5344 return QPointF(width / 2., height / 2.);
5345 case QQuickItem::Right:
5346 return QPointF(width, height / 2.);
5348 return QPointF(0, height);
5349 case QQuickItem::Bottom:
5350 return QPointF(width / 2., height);
5352 return QPointF(width, height);
5353 }
5354}
5355
5371{
5372 Q_Q(QQuickItem);
5373
5374 bool childWantsIt = false;
5376 // Inform the children in paint order: by the time we visit leaf items,
5377 // they can see any consequences in their parents
5378 for (auto child : paintOrderChildItems())
5379 childWantsIt |= QQuickItemPrivate::get(child)->transformChanged(transformedItem);
5380 }
5381
5382#if QT_CONFIG(quick_shadereffect)
5383 if (q == transformedItem) {
5384 if (extra.isAllocated() && extra->layer)
5385 extra->layer->updateMatrix();
5386 }
5387#endif
5388 const bool thisWantsIt = q->flags().testFlag(QQuickItem::ItemObservesViewport);
5389 const bool ret = childWantsIt || thisWantsIt;
5391 qCDebug(lcVP) << "turned off subtree transformChanged notification after checking all children of" << q;
5393 }
5394 // If ItemObservesViewport, clipRect() calculates the intersection with the viewport;
5395 // so each time the item moves in the viewport, its clipnode needs to be updated.
5396 if (thisWantsIt && q->clip())
5398 return ret;
5399}
5400
5419 const QPointF &startPos,
5420 const QVector2D &activeTranslation,
5421 qreal startScale,
5422 qreal activeScale,
5423 qreal startRotation,
5424 qreal activeRotation)
5425{
5426 Q_Q(QQuickItem);
5427 QVector3D xformOrigin(q->transformOriginPoint());
5428 QMatrix4x4 startMatrix;
5429 startMatrix.translate(float(startPos.x()), float(startPos.y()));
5430 startMatrix.translate(xformOrigin);
5431 startMatrix.scale(float(startScale));
5432 startMatrix.rotate(float(startRotation), 0, 0, -1);
5433 startMatrix.translate(-xformOrigin);
5434
5435 const QVector3D centroidParentVector(centroidParentPos);
5436 QMatrix4x4 mat;
5437 mat.translate(centroidParentVector);
5438 mat.rotate(float(activeRotation), 0, 0, 1);
5439 mat.scale(float(activeScale));
5440 mat.translate(-centroidParentVector);
5441 mat.translate(QVector3D(activeTranslation));
5442
5443 mat = mat * startMatrix;
5444
5445 QPointF xformOriginPoint = q->transformOriginPoint();
5446 QPointF pos = mat.map(xformOriginPoint);
5447 pos -= xformOriginPoint;
5448
5449 return pos;
5450}
5451
5475{
5476 Q_Q(QQuickItem);
5478 QQuickItemPrivate *p = this;
5479 do {
5480 if (qmlobject_cast<QQuickRootItem *>(p->q_ptr)) {
5481 // found the root item without finding a different DA:
5482 // it means we don't need to repeat this search next time.
5483 // TODO maybe optimize further: make this function recursive, and
5484 // set it to false on each item that we visit in the tail
5486 break;
5487 }
5488 if (p->extra.isAllocated()) {
5489 if (auto da = p->extra->subsceneDeliveryAgent)
5490 return da;
5491 }
5492 p = p->parentItem ? QQuickItemPrivate::get(p->parentItem) : nullptr;
5493 } while (p);
5494 // arriving here is somewhat unexpected: a detached root can easily be created (just set an item's parent to null),
5495 // but why would we deliver events to that subtree? only if root got detached while an item in that subtree still has a grab?
5496 qCDebug(lcPtr) << "detached root of" << q << "is not a QQuickRootItem and also does not have its own DeliveryAgent";
5497 }
5498 if (window)
5500 return nullptr;
5501}
5502
5504{
5505 auto da = deliveryAgent();
5506 return da ? static_cast<QQuickDeliveryAgentPrivate *>(QQuickDeliveryAgentPrivate::get(da)) : nullptr;
5507}
5508
5518{
5519 Q_Q(QQuickItem);
5520 // We are (about to be) sure that it has one now; but just to save space,
5521 // we avoid storing a DA pointer in each item; so deliveryAgent() always needs to
5522 // go up the hierarchy to find it. maybeHasSubsceneDeliveryAgent tells it to do that.
5524 if (extra.isAllocated() && extra->subsceneDeliveryAgent)
5525 return extra->subsceneDeliveryAgent;
5526 extra.value().subsceneDeliveryAgent = new QQuickDeliveryAgent(q);
5527 qCDebug(lcPtr) << "created new" << extra->subsceneDeliveryAgent;
5528 // every subscene root needs to be a focus scope so that when QQuickItem::forceActiveFocus()
5529 // goes up the parent hierarchy, it finds the subscene root and calls setFocus() on it
5531 return extra->subsceneDeliveryAgent;
5532}
5533
5535{
5536 if (!extra.isAllocated() || !extra->keyHandler)
5537 return false;
5538
5539 if (post)
5540 e->accept();
5541
5542 if (e->type() == QEvent::KeyPress)
5543 extra->keyHandler->keyPressed(e, post);
5544 else
5545 extra->keyHandler->keyReleased(e, post);
5546
5547 return e->isAccepted();
5548}
5549
5551{
5552 Q_Q(QQuickItem);
5553
5554 Q_ASSERT(e->isAccepted());
5555 if (filterKeyEvent(e, false))
5556 return;
5557 else
5558 e->accept();
5559
5560 if (e->type() == QEvent::KeyPress)
5561 q->keyPressEvent(e);
5562 else
5563 q->keyReleaseEvent(e);
5564
5565 if (e->isAccepted())
5566 return;
5567
5568 if (filterKeyEvent(e, true) || !q->window())
5569 return;
5570
5571 //only care about KeyPress now
5572 if (e->type() == QEvent::KeyPress &&
5573 (q == q->window()->contentItem() || q->activeFocusOnTab())) {
5574 bool res = false;
5575 if (!(e->modifiers() & (Qt::ControlModifier | Qt::AltModifier))) { //### Add MetaModifier?
5576 if (e->key() == Qt::Key_Backtab
5577 || (e->key() == Qt::Key_Tab && (e->modifiers() & Qt::ShiftModifier)))
5579 else if (e->key() == Qt::Key_Tab)
5581 if (res)
5582 e->setAccepted(true);
5583 }
5584 }
5585}
5586
5587#if QT_CONFIG(im)
5588void QQuickItemPrivate::deliverInputMethodEvent(QInputMethodEvent *e)
5589{
5590 Q_Q(QQuickItem);
5591
5592 Q_ASSERT(e->isAccepted());
5593 if (extra.isAllocated() && extra->keyHandler) {
5594 extra->keyHandler->inputMethodEvent(e, false);
5595
5596 if (e->isAccepted())
5597 return;
5598 else
5599 e->accept();
5600 }
5601
5602 q->inputMethodEvent(e);
5603
5604 if (e->isAccepted())
5605 return;
5606
5607 if (extra.isAllocated() && extra->keyHandler) {
5608 e->accept();
5609
5610 extra->keyHandler->inputMethodEvent(e, true);
5611 }
5612}
5613#endif // im
5614
5616{
5617 if (extra.isAllocated() && extra->keyHandler)
5618 extra->keyHandler->shortcutOverrideEvent(event);
5619 else
5620 event->ignore();
5621}
5622
5624{
5625 if (!hasPointerHandlers())
5626 return false;
5627 for (QQuickPointerHandler *handler : extra->pointerHandlers) {
5628 if (handler->wantsEventPoint(event, point))
5629 return true;
5630 }
5631 return false;
5632}
5633
5645{
5646 bool delivered = false;
5647 if (extra.isAllocated()) {
5648 for (QQuickPointerHandler *handler : extra->pointerHandlers) {
5649 bool avoidThisHandler = false;
5651 qmlobject_cast<const QQuickHoverHandler *>(handler)) {
5652 avoidThisHandler = true;
5653 } else if (avoidGrabbers) {
5654 for (auto &p : event->points()) {
5655 if (event->exclusiveGrabber(p) == handler || event->passiveGrabbers(p).contains(handler)) {
5656 avoidThisHandler = true;
5657 break;
5658 }
5659 }
5660 }
5661 if (!avoidThisHandler &&
5662 !QQuickPointerHandlerPrivate::deviceDeliveryTargets(event->device()).contains(handler)) {
5663 handler->handlePointerEvent(event);
5664 delivered = true;
5665 }
5666 }
5667 }
5668 return delivered;
5669}
5670
5685{
5686 if (change == ItemSceneChange)
5687 emit windowChanged(value.window);
5688}
5689
5690#if QT_CONFIG(im)
5695void QQuickItem::updateInputMethod(Qt::InputMethodQueries queries)
5696{
5697 if (hasActiveFocus())
5699}
5700#endif // im
5701
5707{
5708 Q_D(const QQuickItem);
5709 return QRectF(0, 0, d->width, d->height);
5710}
5711
5734{
5735 Q_D(const QQuickItem);
5736 QRectF ret(0, 0, d->width, d->height);
5738 if (QQuickItem *viewport = viewportItem()) {
5739 // if the viewport is already "this", there's nothing to intersect;
5740 // and don't call clipRect() again, to avoid infinite recursion
5741 if (viewport == this)
5742 return ret;
5743 const auto mappedViewportRect = mapRectFromItem(viewport, viewport->clipRect());
5744 qCDebug(lcVP) << this << "intersecting" << viewport << mappedViewportRect << ret << "->" << mappedViewportRect.intersected(ret);
5745 return mappedViewportRect.intersected(ret);
5746 }
5747 }
5748 return ret;
5749}
5750
5763{
5765 QQuickItem *par = parentItem();
5766 while (par) {
5767 if (par->flags().testFlag(QQuickItem::ItemIsViewport))
5768 return par;
5769 par = par->parentItem();
5770 }
5771 }
5772 return (window() ? window()->contentItem() : nullptr);
5773}
5774
5806{
5807 Q_D(const QQuickItem);
5808 return d->origin();
5809}
5810
5812{
5813 Q_D(QQuickItem);
5814 if (origin == d->origin())
5815 return;
5816
5817 d->extra.value().origin = origin;
5819
5820 emit transformOriginChanged(d->origin());
5821}
5822
5831{
5832 Q_D(const QQuickItem);
5833 if (d->extra.isAllocated() && !d->extra->userTransformOriginPoint.isNull())
5834 return d->extra->userTransformOriginPoint;
5835 return d->computeTransformOrigin();
5836}
5837
5842{
5843 Q_D(QQuickItem);
5844 if (d->extra.value().userTransformOriginPoint == point)
5845 return;
5846
5847 d->extra->userTransformOriginPoint = point;
5849}
5850
6006{
6007 Q_D(const QQuickItem);
6008 return d->z();
6009}
6010
6012{
6013 Q_D(QQuickItem);
6014 if (d->z() == v)
6015 return;
6016
6017 d->extra.value().z = v;
6018
6020 if (d->parentItem) {
6023 }
6024
6025 emit zChanged();
6026
6027#if QT_CONFIG(quick_shadereffect)
6028 if (d->extra.isAllocated() && d->extra->layer)
6029 d->extra->layer->updateZ();
6030#endif
6031}
6032
6086{
6087 Q_D(const QQuickItem);
6088 return d->rotation();
6089}
6090
6092{
6093 Q_D(QQuickItem);
6094 if (d->rotation() == r)
6095 return;
6096
6097 d->extra.value().rotation = r;
6098
6100
6101 d->itemChange(ItemRotationHasChanged, r);
6102
6104}
6105
6186{
6187 Q_D(const QQuickItem);
6188 return d->scale();
6189}
6190
6192{
6193 Q_D(QQuickItem);
6194 if (d->scale() == s)
6195 return;
6196
6197 d->extra.value().scale = s;
6198
6200
6202}
6203
6315{
6316 Q_D(const QQuickItem);
6317 return d->opacity();
6318}
6319
6321{
6322 Q_D(QQuickItem);
6323 qreal o = qBound<qreal>(0, newOpacity, 1);
6324 if (d->opacity() == o)
6325 return;
6326
6327 d->extra.value().opacity = o;
6328
6330
6331 d->itemChange(ItemOpacityHasChanged, o);
6332
6334}
6335
6401{
6402 Q_D(const QQuickItem);
6403 return d->effectiveVisible;
6404}
6405
6407{
6408 if (visible == explicitVisible)
6409 return;
6410
6411 explicitVisible = visible;
6412 if (!visible)
6414
6415 const bool childVisibilityChanged = setEffectiveVisibleRecur(calcEffectiveVisible());
6416 if (childVisibilityChanged && parentItem)
6417 emit parentItem->visibleChildrenChanged(); // signal the parent, not this!
6418}
6419
6421{
6422 Q_D(QQuickItem);
6423 d->setVisible(v);
6424}
6425
6468{
6469 Q_D(const QQuickItem);
6470 return d->effectiveEnable;
6471}
6472
6474{
6475 Q_D(QQuickItem);
6476 if (e == d->explicitEnable)
6477 return;
6478
6479 d->explicitEnable = e;
6480
6481 QQuickItem *scope = parentItem();
6482 while (scope && !scope->isFocusScope())
6483 scope = scope->parentItem();
6484
6485 d->setEffectiveEnableRecur(scope, d->calcEffectiveEnable());
6486}
6487
6489{
6490 // An item is visible if it is a child of a visible parent, and not explicitly hidden.
6492}
6493
6495{
6496 Q_Q(QQuickItem);
6497
6498 if (newEffectiveVisible && !explicitVisible) {
6499 // This item locally overrides visibility
6500 return false; // effective visibility didn't change
6501 }
6502
6503 if (newEffectiveVisible == effectiveVisible) {
6504 // No change necessary
6505 return false; // effective visibility didn't change
6506 }
6507
6508 effectiveVisible = newEffectiveVisible;
6509 dirty(Visible);
6510 if (parentItem)
6512 if (window)
6513 if (auto agent = deliveryAgentPrivate(); agent)
6514 agent->removeGrabber(q, true, true, true);
6515
6516 bool childVisibilityChanged = false;
6517 for (int ii = 0; ii < childItems.size(); ++ii)
6518 childVisibilityChanged |= QQuickItemPrivate::get(childItems.at(ii))->setEffectiveVisibleRecur(newEffectiveVisible);
6519
6521#if QT_CONFIG(accessibility)
6522 if (isAccessible) {
6523 QAccessibleEvent ev(q, effectiveVisible ? QAccessible::ObjectShow : QAccessible::ObjectHide);
6524 QAccessible::updateAccessibility(&ev);
6525 }
6526#endif
6527 if (!inDestructor) {
6528 emit q->visibleChanged();
6529 if (childVisibilityChanged)
6530 emit q->visibleChildrenChanged();
6531 }
6532
6533 return true; // effective visibility DID change
6534}
6535
6537{
6538 // XXX todo - Should the effective enable of an element with no parent just be the current
6539 // effective enable? This would prevent pointless re-processing in the case of an element
6540 // moving to/from a no-parent situation, but it is different from what graphics view does.
6542}
6543
6544void QQuickItemPrivate::setEffectiveEnableRecur(QQuickItem *scope, bool newEffectiveEnable)
6545{
6546 Q_Q(QQuickItem);
6547
6548 if (newEffectiveEnable && !explicitEnable) {
6549 // This item locally overrides enable
6550 return;
6551 }
6552
6553 if (newEffectiveEnable == effectiveEnable) {
6554 // No change necessary
6555 return;
6556 }
6557
6558 effectiveEnable = newEffectiveEnable;
6559
6561 if (da) {
6562 da->removeGrabber(q, true, true, true);
6563 if (scope && !effectiveEnable && activeFocus) {
6567 }
6568 }
6569
6570 for (int ii = 0; ii < childItems.size(); ++ii) {
6572 (flags & QQuickItem::ItemIsFocusScope) && scope ? q : scope, newEffectiveEnable);
6573 }
6574
6575 if (scope && effectiveEnable && focus && da) {
6579 }
6580
6582#if QT_CONFIG(accessibility)
6583 if (isAccessible) {
6584 QAccessible::State changedState;
6585 changedState.disabled = true;
6586 changedState.focusable = true;
6587 QAccessibleStateChangeEvent ev(q, changedState);
6588 QAccessible::updateAccessibility(&ev);
6589 }
6590#endif
6591 emit q->enabledChanged();
6592}
6593
6595{
6596 return extra.isAllocated() && extra.value().transparentForPositioner;
6597}
6598
6600{
6601 extra.value().transparentForPositioner = transparent;
6602}
6603
6604
6606{
6607#define DIRTY_TO_STRING(value) if (dirtyAttributes & value) { \
6608 if (!rv.isEmpty()) \
6609 rv.append(QLatin1Char('|')); \
6610 rv.append(QLatin1String(#value)); \
6611}
6612
6613// QString rv = QLatin1String("0x") + QString::number(dirtyAttributes, 16);
6614 QString rv;
6615
6619 DIRTY_TO_STRING(Position);
6634
6635 return rv;
6636}
6637
6639{
6640 Q_Q(QQuickItem);
6641 if (type & (TransformOrigin | Transform | BasicTransform | Position | Size))
6643
6644 if (!(dirtyAttributes & type) || (window && !prevDirtyItem)) {
6646 if (window && componentComplete) {
6649 }
6650 }
6651}
6652
6654{
6655 Q_Q(QQuickItem);
6656
6658 if (!prevDirtyItem) {
6660
6662 nextDirtyItem = p->dirtyItemList;
6664 prevDirtyItem = &p->dirtyItemList;
6665 p->dirtyItemList = q;
6666 p->dirtyItem(q);
6667 }
6669}
6670
6672{
6673 if (prevDirtyItem) {
6676 prevDirtyItem = nullptr;
6677 nextDirtyItem = nullptr;
6678 }
6681}
6682
6684{
6685 ++extra.value().effectRefCount;
6686 if (extra->effectRefCount == 1) {
6688 if (parentItem)
6690 }
6691 if (hide) {
6692 if (++extra->hideRefCount == 1)
6694 }
6696}
6697
6699{
6700 Q_Q(QQuickItem);
6701 if (!refs)
6702 return;
6703 extra.value().recursiveEffectRefCount += refs;
6704 for (int ii = 0; ii < childItems.size(); ++ii) {
6707 }
6708 // Polish may rely on the effect ref count so trigger one, if item is not visible
6709 // (if visible, it will be triggered automatically).
6710 if (!effectiveVisible && refs > 0 && extra.value().recursiveEffectRefCount == 1) // it wasn't referenced, now it's referenced
6711 q->polish();
6712}
6713
6715{
6716 Q_ASSERT(extra->effectRefCount);
6717 --extra->effectRefCount;
6718 if (extra->effectRefCount == 0) {
6720 if (parentItem)
6722 }
6723 if (unhide) {
6724 if (--extra->hideRefCount == 0)
6726 }
6728}
6729
6731{
6732 if (cull == culled)
6733 return;
6734
6735 culled = cull;
6736 if ((cull && ++extra.value().hideRefCount == 1) || (!cull && --extra.value().hideRefCount == 0))
6738}
6739
6741{
6742 Q_Q(QQuickItem);
6743 switch (change) {
6745 q->itemChange(change, data);
6749 break;
6750 }
6752 q->itemChange(change, data);
6754 break;
6755 }
6757 q->itemChange(change, data);
6758 break;
6760 q->itemChange(change, data);
6762 break;
6763 }
6765 q->itemChange(change, data);
6767 break;
6768 }
6770 q->itemChange(change, data);
6772 break;
6773 }
6775 q->itemChange(change, data);
6777 break;
6778 }
6780 q->itemChange(change, data);
6781 break;
6783 q->itemChange(change, data);
6785 break;
6786 }
6788 // fall through
6790 q->itemChange(change, data);
6791 break;
6792 }
6793}
6794
6819{
6820 Q_D(const QQuickItem);
6821 return d->smooth;
6822}
6823void QQuickItem::setSmooth(bool smooth)
6824{
6825 Q_D(QQuickItem);
6826 if (d->smooth == smooth)
6827 return;
6828
6829 d->smooth = smooth;
6831
6833}
6834
6860{
6861 Q_D(const QQuickItem);
6862 return d->activeFocusOnTab;
6863}
6864void QQuickItem::setActiveFocusOnTab(bool activeFocusOnTab)
6865{
6866 Q_D(QQuickItem);
6867 if (d->activeFocusOnTab == activeFocusOnTab)
6868 return;
6869
6870 if (window()) {
6871 if ((this == window()->activeFocusItem()) && this != window()->contentItem() && !activeFocusOnTab) {
6872 qWarning("QQuickItem: Cannot set activeFocusOnTab to false once item is the active focus item.");
6873 return;
6874 }
6875 }
6876
6877 d->activeFocusOnTab = activeFocusOnTab;
6878
6879 emit activeFocusOnTabChanged(activeFocusOnTab);
6880}
6881
6902{
6903 Q_D(const QQuickItem);
6904 return d->antialiasingValid ? d->antialiasing : d->implicitAntialiasing;
6905}
6906
6908{
6909 Q_D(QQuickItem);
6910
6911 if (!d->antialiasingValid) {
6912 d->antialiasingValid = true;
6913 d->antialiasing = d->implicitAntialiasing;
6914 }
6915
6916 if (aa == d->antialiasing)
6917 return;
6918
6919 d->antialiasing = aa;
6921
6922 d->itemChange(ItemAntialiasingHasChanged, bool(d->antialiasing));
6923
6925}
6926
6928{
6929 Q_D(QQuickItem);
6930 if (!d->antialiasingValid)
6931 return;
6932
6933 d->antialiasingValid = false;
6934
6935 if (d->implicitAntialiasing != d->antialiasing)
6937}
6938
6940{
6941 Q_Q(QQuickItem);
6942 bool prev = q->antialiasing();
6944 if (componentComplete && (q->antialiasing() != prev))
6945 emit q->antialiasingChanged(q->antialiasing());
6946}
6947
6953QQuickItem::Flags QQuickItem::flags() const
6954{
6955 Q_D(const QQuickItem);
6956 return (QQuickItem::Flags)d->flags;
6957}
6958
6968{
6969 Q_D(QQuickItem);
6970 if (enabled)
6971 setFlags((Flags)(d->flags | (quint32)flag));
6972 else
6973 setFlags((Flags)(d->flags & ~(quint32)flag));
6974
6975 if (enabled && flag == ItemObservesViewport) {
6976 QQuickItem *par = parentItem();
6977 while (par) {
6978 auto parPriv = QQuickItemPrivate::get(par);
6979 if (!parPriv->subtreeTransformChangedEnabled)
6980 qCDebug(lcVP) << "turned on transformChanged notification for subtree of" << par;
6981 parPriv->subtreeTransformChangedEnabled = true;
6982 par = par->parentItem();
6983 }
6984 }
6985}
6986
6993{
6994 Q_D(QQuickItem);
6995
6996 if (int(flags & ItemIsFocusScope) != int(d->flags & ItemIsFocusScope)) {
6997 if (flags & ItemIsFocusScope && !d->childItems.isEmpty() && d->window) {
6998 qWarning("QQuickItem: Cannot set FocusScope once item has children and is in a window.");
6999 flags &= ~ItemIsFocusScope;
7000 } else if (d->flags & ItemIsFocusScope) {
7001 qWarning("QQuickItem: Cannot unset FocusScope flag.");
7003 }
7004 }
7005
7006 if (int(flags & ItemClipsChildrenToShape) != int(d->flags & ItemClipsChildrenToShape))
7007 d->dirty(QQuickItemPrivate::Clip);
7008
7009 d->flags = flags;
7010}
7011
7038{
7039 Q_D(const QQuickItem);
7040 return d->x;
7041}
7042
7044{
7045 Q_D(const QQuickItem);
7046 return d->y;
7047}
7048
7053{
7054 Q_D(const QQuickItem);
7055 return QPointF(d->x, d->y);
7056}
7057
7059{
7060 Q_D(QQuickItem);
7061 /* There are two ways in which this function might be called:
7062 a) Either directly by the user, or
7063 b) when a binding has evaluated to a new value and it writes
7064 the value back
7065 In the first case, we want to remove an existing binding, in
7066 the second case, we don't want to remove the binding which
7067 just wrote the value.
7068 removeBindingUnlessInWrapper takes care of this.
7069 */
7070 d->x.removeBindingUnlessInWrapper();
7071 if (qt_is_nan(v))
7072 return;
7073
7074 const qreal oldx = d->x;
7075 if (oldx == v)
7076 return;
7077
7078 d->x = v;
7079
7081
7082 const qreal y = d->y, w = d->width, h = d->height;
7083 geometryChange(QRectF(v, y, w, h), QRectF(oldx, y, w, h));
7084}
7085
7087{
7088 Q_D(QQuickItem);
7089 d->y.removeBindingUnlessInWrapper();
7090 if (qt_is_nan(v))
7091 return;
7092
7093 const qreal oldy = d->y;
7094 if (oldy == v)
7095 return;
7096
7097 d->y = v;
7098
7100
7101 // we use v instead of d->y, as that avoid a method call
7102 // and we have v anyway in scope
7103 const qreal x = d->x, w = d->width, h = d->height;
7104 geometryChange(QRectF(x, v, w, h), QRectF(x, oldy, w, h));
7105}
7106
7111{
7112 Q_D(QQuickItem);
7113 if (QPointF(d->x, d->y) == pos)
7114 return;
7115
7116 const qreal oldx = d->x;
7117 const qreal oldy = d->y;
7118
7119 /* This preserves the bindings, because that was what the code used to do
7120 The effect of this is that you can have
7121 Item {
7122 Rectangle {
7123 x: someValue; y: someValue
7124 DragHandler {}
7125 }
7126 }
7127 and you can move the rectangle around; once someValue changes, the position gets
7128 reset again (even when a drag is currently ongoing).
7129 Whether we want this is up to discussion.
7130 */
7131
7132 d->x.setValueBypassingBindings(pos.x()); //TODO: investigate whether to break binding here or not
7133 d->y.setValueBypassingBindings(pos.y());
7134
7136
7137 const qreal w = d->width, h = d->height;
7138 geometryChange(QRectF(pos.x(), pos.y(), w, h), QRectF(oldx, oldy, w, h));
7139}
7140
7141/* The bindable methods return an object which supports inspection (hasBinding) and
7142 modification (setBinding, removeBinding) of the properties bindable state.
7143*/
7145{
7146 return QBindable<qreal>(&d_func()->x);
7147}
7148
7150{
7151 return QBindable<qreal>(&d_func()->y);
7152}
7153
7160{
7161 Q_D(const QQuickItem);
7162 return d->width;
7163}
7164
7166{
7167 Q_D(QQuickItem);
7168 d->width.removeBindingUnlessInWrapper();
7169 if (qt_is_nan(w))
7170 return;
7171
7172 d->widthValidFlag = true;
7173 const qreal oldWidth = d->width;
7174 if (oldWidth == w)
7175 return;
7176
7177 d->width = w;
7178
7179 d->dirty(QQuickItemPrivate::Size);
7180
7181 const qreal x = d->x, y = d->y, h = d->height;
7182 geometryChange(QRectF(x, y, w, h), QRectF(x, y, oldWidth, h));
7183}
7184
7186{
7187 Q_D(QQuickItem);
7188 d->width.takeBinding();
7189 d->widthValidFlag = false;
7191}
7192
7194{
7195 Q_Q(QQuickItem);
7197 emit q->implicitWidthChanged();
7198}
7199
7201{
7202 return implicitWidth;
7203}
7208{
7209 Q_D(const QQuickItem);
7210 return d->getImplicitWidth();
7211}
7212
7214{
7215 return QBindable<qreal>(&d_func()->width);
7216}
7217
7301{
7302 Q_D(QQuickItem);
7303 bool changed = w != d->implicitWidth;
7304 d->implicitWidth = w;
7305 // this uses valueBypassingBindings simply to avoid repeated "am I in a binding" checks
7306 if (d->width.valueBypassingBindings() == w || widthValid()) {
7307 if (changed)
7308 d->implicitWidthChanged();
7309 if (d->width.valueBypassingBindings() == w || widthValid())
7310 return;
7311 changed = false;
7312 }
7313
7314 const qreal oldWidth = d->width.valueBypassingBindings();
7315 Q_ASSERT(!d->width.hasBinding() || QQmlPropertyBinding::isUndefined(d->width.binding()));
7316 // we need to keep the binding if its undefined (therefore we can't use operator=/setValue)
7317 d->width.setValueBypassingBindings(w);
7318
7319 d->dirty(QQuickItemPrivate::Size);
7320
7321 const qreal x = d->x.valueBypassingBindings();
7322 const qreal y = d->y.valueBypassingBindings();
7323 const qreal width = w;
7324 const qreal height = d->height.valueBypassingBindings();
7325 geometryChange(QRectF(x, y, width, height), QRectF(x, y, oldWidth, height));
7326
7327 if (changed)
7328 d->implicitWidthChanged();
7329}
7330
7335{
7336 Q_D(const QQuickItem);
7337 /* Logic: The width is valid if we assigned a value
7338 or a binding to it. Note that a binding evaluation to
7339 undefined (and thus calling resetWidth) is detached [1];
7340 hasBinding will thus return false for it, which is
7341 what we want here, as resetting width should mean that
7342 width is invalid (until the binding evaluates to a
7343 non-undefined value again).
7344
7345 [1]: A detached binding is a binding which is not set on a property.
7346 In the case of QQmlPropertyBinding and resettable properties, it
7347 still gets reevaluated when it was detached due to the binding
7348 returning undefined, and it gets re-attached, once the binding changes
7349 to a non-undefined value (unless another binding has beenset in the
7350 meantime).
7351 See QQmlPropertyBinding::isUndefined and handleUndefinedAssignment
7352 */
7353
7354 return d->widthValid();
7355}
7356
7363{
7364 Q_D(const QQuickItem);
7365 return d->height;
7366}
7367
7369{
7370 Q_D(QQuickItem);
7371 // Note that we call removeUnlessInWrapper before returning in the
7372 // NaN and equal value cases; that ensures that an explicit setHeight
7373 // always removes the binding
7374 d->height.removeBindingUnlessInWrapper();
7375 if (qt_is_nan(h))
7376 return;
7377
7378 d->heightValidFlag = true;
7379 const qreal oldHeight = d->height;
7380 if (oldHeight == h)
7381 return;
7382
7383 d->height = h;
7384
7385 d->dirty(QQuickItemPrivate::Size);
7386
7387 const qreal x = d->x, y = d->y, w = d->width;
7388 geometryChange(QRectF(x, y, w, h), QRectF(x, y, w, oldHeight));
7389}
7390
7392{
7393 Q_D(QQuickItem);
7394 // using takeBinding, we remove any existing binding from the
7395 // property, but preserve the existing value (and avoid some overhead
7396 // compared to calling setHeight(height())
7397 d->height.takeBinding();
7398 d->heightValidFlag = false;
7400}
7401
7403{
7404 Q_Q(QQuickItem);
7406 emit q->implicitHeightChanged();
7407}
7408
7410{
7411 return implicitHeight;
7412}
7413
7415{
7416 Q_D(const QQuickItem);
7417 return d->getImplicitHeight();
7418}
7419
7421{
7422 return QBindable<qreal>(&d_func()->height);
7423}
7424
7426{
7427 Q_D(QQuickItem);
7428 bool changed = h != d->implicitHeight;
7429 d->implicitHeight = h;
7430 if (d->height.valueBypassingBindings() == h || heightValid()) {
7431 if (changed)
7432 d->implicitHeightChanged();
7433 if (d->height.valueBypassingBindings() == h || heightValid())
7434 return;
7435 changed = false;
7436 }
7437
7438 const qreal oldHeight = d->height.valueBypassingBindings();
7439 Q_ASSERT(!d->height.hasBinding() || QQmlPropertyBinding::isUndefined(d->height.binding()));
7440 // we need to keep the binding if its undefined (therefore we can't use operator=/setValue)
7441 d->height.setValueBypassingBindings(h);
7442
7443 d->dirty(QQuickItemPrivate::Size);
7444
7445 const qreal x = d->x.valueBypassingBindings();
7446 const qreal y = d->y.valueBypassingBindings();
7447 const qreal width = d->width.valueBypassingBindings();
7448 const qreal height = d->height.valueBypassingBindings();
7450 QRectF(x, y, width, oldHeight));
7451
7452 if (changed)
7453 d->implicitHeightChanged();
7454}
7455
7460{
7461 Q_D(QQuickItem);
7462 bool wChanged = w != d->implicitWidth;
7463 bool hChanged = h != d->implicitHeight;
7464
7465 d->implicitWidth = w;
7466 d->implicitHeight = h;
7467
7468 bool wDone = false;
7469 bool hDone = false;
7470 qreal width = d->width.valueBypassingBindings();
7471 qreal height = d->height.valueBypassingBindings();
7472 if (width == w || widthValid()) {
7473 if (wChanged)
7474 d->implicitWidthChanged();
7475 wDone = width == w || widthValid();
7476 wChanged = false;
7477 }
7478 if (height == h || heightValid()) {
7479 if (hChanged)
7480 d->implicitHeightChanged();
7481 hDone = height == h || heightValid();
7482 hChanged = false;
7483 }
7484 if (wDone && hDone)
7485 return;
7486
7487 const qreal oldWidth = width;
7488 const qreal oldHeight = height;
7489 if (!wDone) {
7490 width = w;
7491 d->width = w;
7492 }
7493 if (!hDone) {
7494 height = h;
7495 d->height = h;
7496 }
7497
7498 d->dirty(QQuickItemPrivate::Size);
7499
7500 const qreal x = d->x.valueBypassingBindings();
7501 const qreal y = d->y.valueBypassingBindings();
7503 QRectF(x, y, oldWidth, oldHeight));
7504
7505 if (!wDone && wChanged)
7506 d->implicitWidthChanged();
7507 if (!hDone && hChanged)
7508 d->implicitHeightChanged();
7509}
7510
7515{
7516 Q_D(const QQuickItem);
7517 return d->heightValid();
7518}
7519
7529{
7530 Q_D(const QQuickItem);
7531 return QSizeF(d->width, d->height);
7532}
7533
7534
7546{
7547 Q_D(QQuickItem);
7548 d->heightValidFlag = true;
7549 d->widthValidFlag = true;
7550
7551 if (d->width == size.width() && d->height == size.height())
7552 return;
7553
7554 const qreal oldHeight = d->height;
7555 const qreal oldWidth = d->width;
7556 d->height.setValueBypassingBindings(size.height());
7557 d->width.setValueBypassingBindings(size.width());
7558
7559 d->dirty(QQuickItemPrivate::Size);
7560
7561 const qreal x = d->x, y = d->y;
7562 geometryChange(QRectF(x, y, size.width(), size.height()), QRectF(x, y, oldWidth, oldHeight));
7563}
7564
7635{
7636 Q_D(const QQuickItem);
7637 return d->activeFocus;
7638}
7639
7729{
7730 Q_D(const QQuickItem);
7731 return d->focus;
7732}
7733
7735{
7737}
7738
7740{
7741 Q_D(QQuickItem);
7742 if (d->focus == focus)
7743 return;
7744
7745 bool notifyListeners = false;
7746 if (d->window || d->parentItem) {
7747 // Need to find our nearest focus scope
7748 QQuickItem *scope = parentItem();
7749 while (scope && !scope->isFocusScope() && scope->parentItem())
7750 scope = scope->parentItem();
7751 if (d->window) {
7752 auto da = d->deliveryAgentPrivate();
7753 Q_ASSERT(da);
7754 if (focus)
7755 da->setFocusInScope(scope, this, reason);
7756 else
7757 da->clearFocusInScope(scope, this, reason);
7758 } else {
7759 // do the focus changes from setFocusInScope/clearFocusInScope that are
7760 // unrelated to a window
7762 QQuickItem *oldSubFocusItem = QQuickItemPrivate::get(scope)->subFocusItem;
7763 if (oldSubFocusItem) {
7764 QQuickItemPrivate::get(oldSubFocusItem)->updateSubFocusItem(scope, false);
7765 QQuickItemPrivate::get(oldSubFocusItem)->focus = false;
7766 changed << oldSubFocusItem;
7767 } else if (!scope->isFocusScope() && scope->hasFocus()) {
7768 QQuickItemPrivate::get(scope)->focus = false;
7769 changed << scope;
7770 }
7771 d->updateSubFocusItem(scope, focus);
7772
7773 d->focus = focus;
7774 changed << this;
7775 notifyListeners = true;
7777
7778 QQuickDeliveryAgentPrivate::notifyFocusChangesRecur(changed.data(), changed.size() - 1, reason);
7779 }
7780 } else {
7782 QQuickItem *oldSubFocusItem = d->subFocusItem;
7783 if (!isFocusScope() && oldSubFocusItem) {
7784 QQuickItemPrivate::get(oldSubFocusItem)->updateSubFocusItem(this, false);
7785 QQuickItemPrivate::get(oldSubFocusItem)->focus = false;
7786 changed << oldSubFocusItem;
7787 }
7788
7789 d->focus = focus;
7790 changed << this;
7791 notifyListeners = true;
7793
7794 QQuickDeliveryAgentPrivate::notifyFocusChangesRecur(changed.data(), changed.size() - 1, reason);
7795 }
7796 if (notifyListeners)
7797 d->notifyChangeListeners(QQuickItemPrivate::Focus, &QQuickItemChangeListener::itemFocusChanged, this, reason);
7798}
7799
7804{
7805 return flags() & ItemIsFocusScope;
7806}
7807
7815{
7816 Q_D(const QQuickItem);
7817 if (!isFocusScope())
7818 return nullptr;
7819 else
7820 return d->subFocusItem;
7821}
7822
7832{
7833 if (!child || child == this)
7834 return false;
7835 const QQuickItem *ancestor = child;
7836 while ((ancestor = ancestor->parentItem())) {
7837 if (ancestor == this)
7838 return true;
7839 }
7840 return false;
7841}
7842
7854Qt::MouseButtons QQuickItem::acceptedMouseButtons() const
7855{
7856 Q_D(const QQuickItem);
7857 return d->acceptedMouseButtons();
7858}
7859
7869void QQuickItem::setAcceptedMouseButtons(Qt::MouseButtons buttons)
7870{
7871 Q_D(QQuickItem);
7872 d->extra.setTag(d->extra.tag().setFlag(QQuickItemPrivate::LeftMouseButtonAccepted, buttons & Qt::LeftButton));
7873
7874 buttons &= ~Qt::LeftButton;
7875 if (buttons || d->extra.isAllocated()) {
7876 d->extra.value().acceptedMouseButtonsWithoutHandlers = buttons;
7877 d->extra.value().acceptedMouseButtons = d->extra->pointerHandlers.isEmpty() ? buttons : Qt::AllButtons;
7878 }
7879}
7880
7893{
7894 Q_D(const QQuickItem);
7895 return d->filtersChildMouseEvents;
7896}
7897
7908{
7909 Q_D(QQuickItem);
7910 d->filtersChildMouseEvents = filter;
7911}
7912
7917{
7918 Q_D(const QQuickItem);
7919 if (!d->window)
7920 return false;
7921
7922 // QQuickWindow handles QEvent::Leave to reset the lastMousePosition
7923 // FIXME: Using QPointF() as the reset value means an item will not be
7924 // under the mouse if the mouse is at 0,0 of the window.
7925 if (const_cast<QQuickItemPrivate *>(d)->deliveryAgentPrivate()->lastMousePosition == QPointF())
7926 return false;
7927
7929 return contains(mapFromScene(d->window->mapFromGlobal(cursorPos)));
7930}
7931
7941{
7942 Q_D(const QQuickItem);
7943 return d->hoverEnabled;
7944}
7945
7953{
7954 Q_D(QQuickItem);
7955 d->hoverEnabled = enabled;
7956 d->setHasHoverInChild(enabled);
7957 // The DA needs to resolve which items and handlers should now be hovered or unhovered.
7958 // Marking this item dirty ensures that flushFrameSynchronousEvents() will be called from the render loop,
7959 // even if this change is not in response to a mouse event and no item has already marked itself dirty.
7961}
7962
7974{
7975 Q_D(const QQuickItem);
7976 return d->touchEnabled;
7977}
7978
7988{
7989 Q_D(QQuickItem);
7990 d->touchEnabled = enabled;
7991}
7992
7994{
7995#if QT_CONFIG(cursor)
7996 Q_Q(QQuickItem);
7997
7998 // if we're asked to turn it off (because of an unsetcursor call, or a node
7999 // removal) then we should make sure it's really ok to turn it off.
8000 if (!hc && subtreeCursorEnabled) {
8001 if (hasCursor)
8002 return; // nope! sorry, I have a cursor myself
8003 for (QQuickItem *otherChild : std::as_const(childItems)) {
8004 QQuickItemPrivate *otherChildPrivate = QQuickItemPrivate::get(otherChild);
8005 if (otherChildPrivate->subtreeCursorEnabled || otherChildPrivate->hasCursor)
8006 return; // nope! sorry, something else wants it kept on.
8007 }
8008 }
8009
8011 QQuickItem *parent = q->parentItem();
8012 if (parent) {
8014 parentPrivate->setHasCursorInChild(hc);
8015 }
8016#else
8017 Q_UNUSED(hc);
8018#endif
8019}
8020
8022{
8023 Q_Q(QQuickItem);
8024
8025 // if we're asked to turn it off (because of a setAcceptHoverEvents call, or a node
8026 // removal) then we should make sure it's really ok to turn it off.
8027 if (!hasHover && subtreeHoverEnabled) {
8028 if (hoverEnabled)
8029 return; // nope! sorry, I need hover myself
8031 return; // nope! sorry, this item has enabled HoverHandlers
8032
8033 for (QQuickItem *otherChild : std::as_const(childItems)) {
8034 QQuickItemPrivate *otherChildPrivate = QQuickItemPrivate::get(otherChild);
8035 if (otherChildPrivate->subtreeHoverEnabled || otherChildPrivate->hoverEnabled)
8036 return; // nope! sorry, something else wants it kept on.
8037 if (otherChildPrivate->hasEnabledHoverHandlers())
8038 return; // nope! sorry, we have pointer handlers which are interested.
8039 }
8040 }
8041
8042 qCDebug(lcHoverTrace) << q << subtreeHoverEnabled << "->" << hasHover;
8043 subtreeHoverEnabled = hasHover;
8044 QQuickItem *parent = q->parentItem();
8045 if (parent) {
8047 parentPrivate->setHasHoverInChild(hasHover);
8048 }
8049}
8050
8051#if QT_CONFIG(cursor)
8052
8067QCursor QQuickItem::cursor() const
8068{
8069 Q_D(const QQuickItem);
8070 return d->extra.isAllocated()
8071 ? d->extra->cursor
8072 : QCursor();
8073}
8074
8081void QQuickItem::setCursor(const QCursor &cursor)
8082{
8083 Q_D(QQuickItem);
8084
8085 Qt::CursorShape oldShape = d->extra.isAllocated() ? d->extra->cursor.shape() : Qt::ArrowCursor;
8086 qCDebug(lcHoverTrace) << oldShape << "->" << cursor.shape();
8087
8088 if (oldShape != cursor.shape() || oldShape >= Qt::LastCursor || cursor.shape() >= Qt::LastCursor) {
8089 d->extra.value().cursor = cursor;
8090 if (d->window) {
8091 QWindow *renderWindow = QQuickRenderControl::renderWindowFor(d->window);
8092 QWindow *window = renderWindow ? renderWindow : d->window; // this may not be a QQuickWindow
8093 if (QQuickWindowPrivate::get(d->window)->cursorItem == this)
8094 window->setCursor(cursor);
8095 }
8096 }
8097
8098 QPointF updateCursorPos;
8099 if (!d->hasCursor) {
8100 d->hasCursor = true;
8101 if (d->window) {
8102 QWindow *renderWindow = QQuickRenderControl::renderWindowFor(d->window);
8103 QWindow *window = renderWindow ? renderWindow : d->window;
8106 updateCursorPos = pos;
8107 }
8108 }
8109 d->setHasCursorInChild(d->hasCursor || d->hasCursorHandler);
8110 if (!updateCursorPos.isNull())
8111 QQuickWindowPrivate::get(d->window)->updateCursor(updateCursorPos);
8112}
8113
8120void QQuickItem::unsetCursor()
8121{
8122 Q_D(QQuickItem);
8123 qCDebug(lcHoverTrace) << "clearing cursor";
8124 if (!d->hasCursor)
8125 return;
8126 d->hasCursor = false;
8127 d->setHasCursorInChild(d->hasCursorHandler);
8128 if (d->extra.isAllocated())
8129 d->extra->cursor = QCursor();
8130
8131 if (d->window) {
8132 QQuickWindowPrivate *windowPrivate = QQuickWindowPrivate::get(d->window);
8133 if (windowPrivate->cursorItem == this) {
8134 QPointF pos = d->window->mapFromGlobal(QGuiApplicationPrivate::lastCursorPosition);
8135 windowPrivate->updateCursor(pos);
8136 }
8137 }
8138}
8139
8147QCursor QQuickItemPrivate::effectiveCursor(const QQuickPointerHandler *handler) const
8148{
8149 Q_Q(const QQuickItem);
8150 if (!handler)
8151 return q->cursor();
8152 bool hoverCursorSet = false;
8153 QCursor hoverCursor;
8154 bool activeCursorSet = false;
8155 QCursor activeCursor;
8156 if (const QQuickHoverHandler *hoverHandler = qobject_cast<const QQuickHoverHandler *>(handler)) {
8157 hoverCursorSet = hoverHandler->isCursorShapeExplicitlySet();
8158 hoverCursor = hoverHandler->cursorShape();
8159 } else if (handler->active()) {
8160 activeCursorSet = handler->isCursorShapeExplicitlySet();
8161 activeCursor = handler->cursorShape();
8162 }
8163 if (activeCursorSet)
8164 return activeCursor;
8165 if (hoverCursorSet)
8166 return hoverCursor;
8167 return q->cursor();
8168}
8169
8190QQuickPointerHandler *QQuickItemPrivate::effectiveCursorHandler() const
8191{
8192 if (!hasPointerHandlers())
8193 return nullptr;
8194 QQuickPointerHandler* activeHandler = nullptr;
8195 QQuickPointerHandler* mouseHandler = nullptr;
8196 QQuickPointerHandler* nonMouseHandler = nullptr;
8197 for (QQuickPointerHandler *h : extra->pointerHandlers) {
8198 if (!h->isCursorShapeExplicitlySet())
8199 continue;
8200 QQuickHoverHandler *hoverHandler = qmlobject_cast<QQuickHoverHandler *>(h);
8201 // Prioritize any HoverHandler that is reacting to a non-mouse device.
8202 // Otherwise, choose the first hovered handler that is found.
8203 // TODO maybe: there was an idea to add QPointerDevice* as argument to this function
8204 // and check the device type, but why? HoverHandler already does that.
8205 if (!activeHandler && hoverHandler && hoverHandler->isHovered()) {
8206 qCDebug(lcHoverTrace) << hoverHandler << hoverHandler->acceptedDevices() << "wants to set cursor" << hoverHandler->cursorShape();
8207 if (hoverHandler->acceptedDevices().testFlag(QPointingDevice::DeviceType::Mouse)) {
8208 // If there's a conflict, the last-added HoverHandler wins. Maybe the user is overriding a default...
8209 if (mouseHandler && mouseHandler->cursorShape() != hoverHandler->cursorShape()) {
8210 qCDebug(lcHoverTrace) << "mouse cursor conflict:" << mouseHandler << "wants" << mouseHandler->cursorShape()
8211 << "but" << hoverHandler << "wants" << hoverHandler->cursorShape();
8212 }
8213 mouseHandler = hoverHandler;
8214 } else {
8215 // If there's a conflict, the last-added HoverHandler wins.
8216 if (nonMouseHandler && nonMouseHandler->cursorShape() != hoverHandler->cursorShape()) {
8217 qCDebug(lcHoverTrace) << "non-mouse cursor conflict:" << nonMouseHandler << "wants" << nonMouseHandler->cursorShape()
8218 << "but" << hoverHandler << "wants" << hoverHandler->cursorShape();
8219 }
8220 nonMouseHandler = hoverHandler;
8221 }
8222 }
8223 if (!hoverHandler && h->active())
8224 activeHandler = h;
8225 }
8226 if (activeHandler) {
8227 qCDebug(lcHoverTrace) << "active handler choosing cursor" << activeHandler << activeHandler->cursorShape();
8228 return activeHandler;
8229 }
8230 // Mouse events are often synthetic; so if a HoverHandler for a non-mouse device wanted to set the cursor,
8231 // let it win, unless more than kCursorOverrideTimeout ms have passed
8232 // since the last time the non-mouse handler actually reacted to an event.
8233 // We could miss the fact that a tablet stylus has left proximity, because we don't deliver proximity events to windows.
8234 if (nonMouseHandler) {
8235 if (mouseHandler) {
8236 const bool beforeTimeout =
8239 QQuickPointerHandler *winner = (beforeTimeout ? nonMouseHandler : mouseHandler);
8240 qCDebug(lcHoverTrace) << "non-mouse handler reacted last time:" << QQuickPointerHandlerPrivate::get(nonMouseHandler)->lastEventTime
8241 << "and mouse handler reacted at time:" << QQuickPointerHandlerPrivate::get(mouseHandler)->lastEventTime
8242 << "choosing cursor according to" << winner << winner->cursorShape();
8243 return winner;
8244 }
8245 qCDebug(lcHoverTrace) << "non-mouse handler choosing cursor" << nonMouseHandler << nonMouseHandler->cursorShape();
8246 return nonMouseHandler;
8247 }
8248 if (mouseHandler)
8249 qCDebug(lcHoverTrace) << "mouse handler choosing cursor" << mouseHandler << mouseHandler->cursorShape();
8250 return mouseHandler;
8251}
8252
8253#endif
8254
8270{
8271 Q_D(QQuickItem);
8272 if (!d->window)
8273 return;
8274 auto da = d->deliveryAgentPrivate();
8275 Q_ASSERT(da);
8276 auto eventInDelivery = da->eventInDelivery();
8277 if (!eventInDelivery) {
8278 qWarning() << "cannot grab mouse: no event is currently being delivered";
8279 return;
8280 }
8281 auto epd = da->mousePointData();
8282 eventInDelivery->setExclusiveGrabber(epd->eventPoint, this);
8283}
8284
8297{
8298 Q_D(QQuickItem);
8299 if (!d->window)
8300 return;
8301 auto da = d->deliveryAgentPrivate();
8302 Q_ASSERT(da);
8303 auto eventInDelivery = da->eventInDelivery();
8304 if (!eventInDelivery) {
8305 // do it the expensive way
8306 da->removeGrabber(this);
8307 return;
8308 }
8309 const auto &eventPoint = da->mousePointData()->eventPoint;
8310 if (eventInDelivery->exclusiveGrabber(eventPoint) == this)
8311 eventInDelivery->setExclusiveGrabber(eventPoint, nullptr);
8312}
8313
8320{
8321 Q_D(const QQuickItem);
8322 return d->keepMouse;
8323}
8324
8342{
8343 Q_D(QQuickItem);
8344 d->keepMouse = keep;
8345}
8346
8357{
8358 Q_D(QQuickItem);
8359 auto event = d->deliveryAgentPrivate()->eventInDelivery();
8360 if (Q_UNLIKELY(!event)) {
8361 qWarning() << "cannot grab: no event is currently being delivered";
8362 return;
8363 }
8364 for (auto pt : event->points()) {
8365 if (ids.contains(pt.id()))
8366 event->setExclusiveGrabber(pt, this);
8367 }
8368}
8369
8375{
8376 Q_D(QQuickItem);
8377 if (!d->window)
8378 return;
8379 d->deliveryAgentPrivate()->removeGrabber(this, false, true);
8380}
8381
8389{
8390 Q_D(const QQuickItem);
8391 return d->keepTouch;
8392}
8393
8412{
8413 Q_D(QQuickItem);
8414 d->keepTouch = keep;
8415}
8416
8436bool QQuickItem::contains(const QPointF &point) const
8437{
8438 Q_D(const QQuickItem);
8439 if (d->extra.isAllocated() && d->extra->mask) {
8440 if (auto quickMask = qobject_cast<QQuickItem *>(d->extra->mask))
8441 return quickMask->contains(point - quickMask->position());
8442
8443 bool res = false;
8444 QMetaMethod maskContains = d->extra->mask->metaObject()->method(d->extra->maskContainsIndex);
8445 maskContains.invoke(d->extra->mask,
8447 Q_RETURN_ARG(bool, res),
8448 Q_ARG(QPointF, point));
8449 return res;
8450 }
8451
8452 qreal x = point.x();
8453 qreal y = point.y();
8454 return x >= 0 && y >= 0 && x < d->width && y < d->height;
8455}
8456
8521{
8522 Q_D(const QQuickItem);
8523 if (!d->extra.isAllocated())
8524 return nullptr;
8525 return d->extra->mask.data();
8526}
8527
8529{
8530 Q_D(QQuickItem);
8531 const bool extraDataExists = d->extra.isAllocated();
8532 // an Item can't mask itself (to prevent infinite loop in contains())
8533 if (mask == static_cast<QObject *>(this))
8534 return;
8535 // mask is null, and we had no mask
8536 if (!extraDataExists && !mask)
8537 return;
8538 // mask is non-null and the same
8539 if (extraDataExists && d->extra->mask == mask)
8540 return;
8541
8542 QQuickItem *quickMask = d->extra.isAllocated() ? qobject_cast<QQuickItem *>(d->extra->mask)
8543 : nullptr;
8544 if (quickMask) {
8545 QQuickItemPrivate *maskPrivate = QQuickItemPrivate::get(quickMask);
8546 maskPrivate->registerAsContainmentMask(this, false); // removed from use as my mask
8547 }
8548
8549 if (!extraDataExists)
8550 d->extra.value(); // ensure extra exists
8551 if (mask) {
8552 int methodIndex = mask->metaObject()->indexOfMethod(QByteArrayLiteral("contains(QPointF)"));
8553 if (methodIndex < 0) {
8554 qmlWarning(this) << QStringLiteral("QQuickItem: Object set as mask does not have an invokable contains method, ignoring it.");
8555 return;
8556 }
8557 d->extra->maskContainsIndex = methodIndex;
8558 }
8559 d->extra->mask = mask;
8560 quickMask = qobject_cast<QQuickItem *>(mask);
8561 if (quickMask) {
8562 QQuickItemPrivate *maskPrivate = QQuickItemPrivate::get(quickMask);
8563 maskPrivate->registerAsContainmentMask(this, true); // telling maskPrivate that "this" is using it as mask
8564 }
8565 emit containmentMaskChanged();
8566}
8567
8581{
8582 QPointF p = mapToScene(point);
8583 if (item)
8584 p = item->mapFromScene(p);
8585 return p;
8586}
8587
8598{
8599 Q_D(const QQuickItem);
8600 return d->itemToWindowTransform().map(point);
8601}
8602
8620QPointF QQuickItem::mapToGlobal(const QPointF &point) const
8621{
8622 Q_D(const QQuickItem);
8623 return d->windowToGlobalTransform().map(mapToScene(point));
8624}
8625
8639{
8640 Q_D(const QQuickItem);
8641 QTransform t = d->itemToWindowTransform();
8642 if (item)
8644 return t.mapRect(rect);
8645}
8646
8657{
8658 Q_D(const QQuickItem);
8659 return d->itemToWindowTransform().mapRect(rect);
8660}
8661
8675{
8676 QPointF p = item?item->mapToScene(point):point;
8677 return mapFromScene(p);
8678}
8679
8690{
8691 Q_D(const QQuickItem);
8692 return d->windowToItemTransform().map(point);
8693}
8694
8718QPointF QQuickItem::mapFromGlobal(const QPointF &point) const
8719{
8720 Q_D(const QQuickItem);
8721 QPointF scenePoint = d->globalToWindowTransform().map(point);
8723 if (auto sceneTransform = da->sceneTransform())
8724 scenePoint = sceneTransform->map(scenePoint);
8725 }
8726 return mapFromScene(scenePoint);
8727}
8728
8742{
8743 Q_D(const QQuickItem);
8745 t *= d->windowToItemTransform();
8746 return t.mapRect(rect);
8747}
8748
8759{
8760 Q_D(const QQuickItem);
8761 return d->windowToItemTransform().mapRect(rect);
8762}
8763
8818{
8819 Q_D(QQuickItem);
8820
8821 switch (ev->type()) {
8822#if QT_CONFIG(im)
8825 Qt::InputMethodQueries queries = query->queries();
8826 for (uint i = 0; i < 32; ++i) {
8827 Qt::InputMethodQuery q = (Qt::InputMethodQuery)(int)(queries & (1<<i));
8828 if (q) {
8829 QVariant v = inputMethodQuery(q);
8830 query->setValue(q, v);
8831 }
8832 }
8833 query->accept();
8834 break;
8835 }
8837 inputMethodEvent(static_cast<QInputMethodEvent *>(ev));
8838 break;
8839#endif // im
8840 case QEvent::TouchBegin:
8842 case QEvent::TouchEnd:
8844 touchEvent(static_cast<QTouchEvent*>(ev));
8845 break;
8847 if (isVisible()) {
8848 ev->accept();
8849 update();
8850 }
8851 break;
8852 case QEvent::HoverEnter:
8853 hoverEnterEvent(static_cast<QHoverEvent*>(ev));
8854 break;
8855 case QEvent::HoverLeave:
8856 hoverLeaveEvent(static_cast<QHoverEvent*>(ev));
8857 break;
8858 case QEvent::HoverMove:
8859 hoverMoveEvent(static_cast<QHoverEvent*>(ev));
8860 break;
8861 case QEvent::KeyPress:
8862 case QEvent::KeyRelease:
8863 d->deliverKeyEvent(static_cast<QKeyEvent*>(ev));
8864 break;
8866 d->deliverShortcutOverrideEvent(static_cast<QKeyEvent*>(ev));
8867 break;
8868 case QEvent::FocusIn:
8869 focusInEvent(static_cast<QFocusEvent*>(ev));
8870 break;
8871 case QEvent::FocusOut:
8872 focusOutEvent(static_cast<QFocusEvent*>(ev));
8873 break;
8874 case QEvent::MouseMove:
8875 mouseMoveEvent(static_cast<QMouseEvent*>(ev));
8876 break;
8878 mousePressEvent(static_cast<QMouseEvent*>(ev));
8879 break;
8881 mouseReleaseEvent(static_cast<QMouseEvent*>(ev));
8882 break;
8884 mouseDoubleClickEvent(static_cast<QMouseEvent*>(ev));
8885 break;
8886#if QT_CONFIG(wheelevent)
8887 case QEvent::Wheel:
8888 wheelEvent(static_cast<QWheelEvent*>(ev));
8889 break;
8890#endif
8891#if QT_CONFIG(quick_draganddrop)
8892 case QEvent::DragEnter:
8893 dragEnterEvent(static_cast<QDragEnterEvent*>(ev));
8894 break;
8895 case QEvent::DragLeave:
8896 dragLeaveEvent(static_cast<QDragLeaveEvent*>(ev));
8897 break;
8898 case QEvent::DragMove:
8899 dragMoveEvent(static_cast<QDragMoveEvent*>(ev));
8900 break;
8901 case QEvent::Drop:
8902 dropEvent(static_cast<QDropEvent*>(ev));
8903 break;
8904#endif // quick_draganddrop
8905#if QT_CONFIG(gestures)
8907 ev->ignore();
8908 break;
8909#endif // gestures
8912 for (QQuickItem *item : std::as_const(d->childItems))
8914 break;
8917 if (d->providesPalette())
8918 d->setCurrentColorGroup();
8919 for (QQuickItem *item : std::as_const(d->childItems))
8921 break;
8923 for (QQuickItem *item : std::as_const(d->childItems))
8925 break;
8926 default:
8927 return QObject::event(ev);
8928 }
8929
8930 return true;
8931}
8932
8933#ifndef QT_NO_DEBUG_STREAM
8935#if QT_VERSION >= QT_VERSION_CHECK(7, 0, 0)
8936 const
8937#endif
8939{
8940 QDebugStateSaver saver(debug);
8941 debug.nospace();
8942 if (!item) {
8943 debug << "QQuickItem(nullptr)";
8944 return debug;
8945 }
8946
8947 const QRectF rect(item->position(), QSizeF(item->width(), item->height()));
8948
8949 debug << item->metaObject()->className() << '(' << static_cast<void *>(item);
8950 if (!item->objectName().isEmpty())
8951 debug << ", name=" << item->objectName();
8952 debug << ", parent=" << static_cast<void *>(item->parentItem())
8953 << ", geometry=";
8955 if (const qreal z = item->z())
8956 debug << ", z=" << z;
8957 if (item->flags().testFlag(QQuickItem::ItemIsViewport))
8958 debug << " \U0001f5bc"; // frame with picture
8960 debug << " \u23ff"; // observer eye
8961 debug << ')';
8962 return debug;
8963}
8964#endif // QT_NO_DEBUG_STREAM
8965
8976{
8977#if QT_CONFIG(quick_shadereffect)
8978 Q_D(const QQuickItem);
8979 return d->extra.isAllocated() && d->extra->layer && d->extra->layer->effectSource() ?
8980 d->extra->layer->effectSource()->isTextureProvider() : false;
8981#else
8982 return false;
8983#endif
8984}
8985
8996{
8997#if QT_CONFIG(quick_shadereffect)
8998 Q_D(const QQuickItem);
8999 return d->extra.isAllocated() && d->extra->layer && d->extra->layer->effectSource() ?
9000 d->extra->layer->effectSource()->textureProvider() : nullptr;
9001#else
9002 return 0;
9003#endif
9004}
9005
9048#if QT_CONFIG(quick_shadereffect)
9053QQuickItemLayer *QQuickItemPrivate::layer() const
9054{
9055 if (!extra.isAllocated() || !extra->layer) {
9056 extra.value().layer = new QQuickItemLayer(const_cast<QQuickItem *>(q_func()));
9057 if (!componentComplete)
9058 extra->layer->classBegin();
9059 }
9060 return extra->layer;
9061}
9062#endif
9063
9082{
9083 Q_Q(QQuickItem);
9084 QList<QEventPoint> touchPoints;
9085 QEventPoint::States eventStates;
9086
9087 bool anyPressOrReleaseInside = false;
9088 bool anyGrabber = false;
9089 for (auto &p : event->points()) {
9090 if (p.isAccepted())
9091 continue;
9092
9093 // include points where item is the grabber, or if any of its handlers is the grabber while some parent is filtering
9094 auto pointGrabber = event->exclusiveGrabber(p);
9095 bool isGrabber = (pointGrabber == q);
9096 if (!isGrabber && pointGrabber && isFiltering) {
9097 auto handlerGrabber = qmlobject_cast<QQuickPointerHandler *>(pointGrabber);
9098 if (handlerGrabber && handlerGrabber->parentItem() == q)
9099 isGrabber = true;
9100 }
9101 if (isGrabber)
9102 anyGrabber = true;
9103
9104 // include points inside the bounds if no other item is the grabber or if the item is filtering
9105 const auto localPos = q->mapFromScene(p.scenePosition());
9106 bool isInside = q->contains(localPos);
9107 bool hasAnotherGrabber = pointGrabber && pointGrabber != q;
9108 // if there's no exclusive grabber, look for passive grabbers during filtering
9109 if (isFiltering && !pointGrabber) {
9110 auto pg = event->passiveGrabbers(p);
9111 if (!pg.isEmpty()) {
9112 // It seems unlikely to have multiple passive grabbers of one eventpoint with different grandparents.
9113 // So hopefully if we start from one passive grabber and go up the parent chain from there,
9114 // we will find any filtering parent items that exist.
9115 auto handler = qmlobject_cast<QQuickPointerHandler *>(pg.first());
9116 if (handler)
9117 pointGrabber = handler->parentItem();
9118 }
9119 }
9120
9121 // filtering: (childMouseEventFilter) include points that are grabbed by children of the target item
9122 bool grabberIsChild = false;
9123 auto parent = qobject_cast<QQuickItem*>(pointGrabber);
9124 while (isFiltering && parent) {
9125 if (parent == q) {
9126 grabberIsChild = true;
9127 break;
9128 }
9129 parent = parent->parentItem();
9130 }
9131
9132 bool filterRelevant = isFiltering && grabberIsChild;
9133 if (!(isGrabber || (isInside && (!hasAnotherGrabber || isFiltering)) || filterRelevant))
9134 continue;
9135 if ((p.state() == QEventPoint::State::Pressed || p.state() == QEventPoint::State::Released) && isInside)
9136 anyPressOrReleaseInside = true;
9137 QEventPoint pCopy(p);
9138 eventStates |= p.state();
9139 if (p.state() == QEventPoint::State::Released)
9141 QMutableEventPoint::setPosition(pCopy, localPos);
9142 touchPoints.append(std::move(pCopy));
9143 }
9144
9145 // Now touchPoints will have only points which are inside the item.
9146 // But if none of them were just pressed inside, and the item has no other reason to care, ignore them anyway.
9147 if (touchPoints.isEmpty() || (!anyPressOrReleaseInside && !anyGrabber && !isFiltering)) {
9148 *localized = QMutableTouchEvent(QEvent::None);
9149 return;
9150 }
9151
9152 // if all points have the same state, set the event type accordingly
9153 QEvent::Type eventType = event->type();
9154 switch (eventStates) {
9156 eventType = QEvent::TouchBegin;
9157 break;
9159 eventType = QEvent::TouchEnd;
9160 break;
9161 default:
9162 eventType = QEvent::TouchUpdate;
9163 break;
9164 }
9165
9166 QMutableTouchEvent ret(eventType, event->pointingDevice(), event->modifiers(), touchPoints);
9167 ret.setTarget(q);
9168 ret.setTimestamp(event->timestamp());
9169 ret.accept();
9170 *localized = ret;
9171}
9172
9174{
9175 return extra.isAllocated() && !extra->pointerHandlers.isEmpty();
9176}
9177
9179{
9180 if (!hasPointerHandlers())
9181 return false;
9182 for (QQuickPointerHandler *h : extra->pointerHandlers)
9183 if (auto *hh = qmlobject_cast<QQuickHoverHandler *>(h); hh && hh->enabled())
9184 return true;
9185 return false;
9186}
9187
9189{
9190 Q_ASSERT(h);
9191 Q_Q(QQuickItem);
9192 // Accept all buttons, and leave filtering to pointerEvent() and/or user JS,
9193 // because there can be multiple handlers...
9194 extra.value().acceptedMouseButtons = Qt::AllButtons;
9195 auto &handlers = extra.value().pointerHandlers;
9196 if (!handlers.contains(h))
9197 handlers.prepend(h);
9198 auto &res = extra.value().resourcesList;
9199 if (!res.contains(h)) {
9200 res.append(h);
9203 });
9204 }
9205}
9206
9208{
9209 Q_ASSERT(h);
9210 Q_Q(QQuickItem);
9211 auto &handlers = extra.value().pointerHandlers;
9212 handlers.removeOne(h);
9213 auto &res = extra.value().resourcesList;
9214 res.removeOne(h);
9216 if (handlers.isEmpty())
9217 extra.value().acceptedMouseButtons = extra.value().acceptedMouseButtonsWithoutHandlers;
9218}
9219
9220#if QT_CONFIG(quick_shadereffect)
9221QQuickItemLayer::QQuickItemLayer(QQuickItem *item)
9222 : m_item(item)
9223 , m_enabled(false)
9224 , m_mipmap(false)
9225 , m_smooth(false)
9226 , m_live(true)
9227 , m_componentComplete(true)
9229 , m_format(QQuickShaderEffectSource::RGBA8)
9230 , m_name("source")
9231 , m_effectComponent(nullptr)
9232 , m_effect(nullptr)
9233 , m_effectSource(nullptr)
9234 , m_textureMirroring(QQuickShaderEffectSource::MirrorVertically)
9235 , m_samples(0)
9236{
9237}
9238
9239QQuickItemLayer::~QQuickItemLayer()
9240{
9241 delete m_effectSource;
9242 delete m_effect;
9243}
9244
9259void QQuickItemLayer::setEnabled(bool e)
9260{
9261 if (e == m_enabled)
9262 return;
9263 m_enabled = e;
9264 if (m_componentComplete) {
9265 if (m_enabled)
9266 activate();
9267 else
9268 deactivate();
9269 }
9270
9271 emit enabledChanged(e);
9272}
9273
9274void QQuickItemLayer::classBegin()
9275{
9276 Q_ASSERT(!m_effectSource);
9277 Q_ASSERT(!m_effect);
9278 m_componentComplete = false;
9279}
9280
9281void QQuickItemLayer::componentComplete()
9282{
9283 Q_ASSERT(!m_componentComplete);
9284 m_componentComplete = true;
9285 if (m_enabled)
9286 activate();
9287}
9288
9289void QQuickItemLayer::activate()
9290{
9291 Q_ASSERT(!m_effectSource);
9292 m_effectSource = new QQuickShaderEffectSource();
9294
9295 QQuickItem *parentItem = m_item->parentItem();
9296 if (parentItem) {
9297 m_effectSource->setParentItem(parentItem);
9298 m_effectSource->stackAfter(m_item);
9299 }
9300
9301 m_effectSource->setSourceItem(m_item);
9302 m_effectSource->setHideSource(true);
9303 m_effectSource->setSmooth(m_smooth);
9304 m_effectSource->setLive(m_live);
9305 m_effectSource->setTextureSize(m_size);
9306 m_effectSource->setSourceRect(m_sourceRect);
9307 m_effectSource->setMipmap(m_mipmap);
9308 m_effectSource->setWrapMode(m_wrapMode);
9309 m_effectSource->setFormat(m_format);
9310 m_effectSource->setTextureMirroring(m_textureMirroring);
9311 m_effectSource->setSamples(m_samples);
9312
9313 if (m_effectComponent)
9314 activateEffect();
9315
9316 m_effectSource->setVisible(m_item->isVisible() && !m_effect);
9317
9318 updateZ();
9319 updateGeometry();
9320 updateOpacity();
9321 updateMatrix();
9322
9325}
9326
9327void QQuickItemLayer::deactivate()
9328{
9329 Q_ASSERT(m_effectSource);
9330
9331 if (m_effectComponent)
9332 deactivateEffect();
9333
9334 delete m_effectSource;
9335 m_effectSource = nullptr;
9336
9339}
9340
9341void QQuickItemLayer::activateEffect()
9342{
9343 Q_ASSERT(m_effectSource);
9344 Q_ASSERT(m_effectComponent);
9345 Q_ASSERT(!m_effect);
9346
9347 QObject *created = m_effectComponent->beginCreate(m_effectComponent->creationContext());
9348 m_effect = qobject_cast<QQuickItem *>(created);
9349 if (!m_effect) {
9350 qWarning("Item: layer.effect is not a QML Item.");
9351 m_effectComponent->completeCreate();
9352 delete created;
9353 return;
9354 }
9355 QQuickItem *parentItem = m_item->parentItem();
9356 if (parentItem) {
9357 m_effect->setParentItem(parentItem);
9358 m_effect->stackAfter(m_effectSource);
9359 }
9360 m_effect->setVisible(m_item->isVisible());
9361 m_effect->setProperty(m_name, QVariant::fromValue<QObject *>(m_effectSource));
9363 m_effectComponent->completeCreate();
9364}
9365
9366void QQuickItemLayer::deactivateEffect()
9367{
9368 Q_ASSERT(m_effectSource);
9369 Q_ASSERT(m_effectComponent);
9370
9371 delete m_effect;
9372 m_effect = nullptr;
9373}
9374
9375
9387void QQuickItemLayer::setEffect(QQmlComponent *component)
9388{
9389 if (component == m_effectComponent)
9390 return;
9391
9392 bool updateNeeded = false;
9393 if (m_effectSource && m_effectComponent) {
9394 deactivateEffect();
9395 updateNeeded = true;
9396 }
9397
9398 m_effectComponent = component;
9399
9400 if (m_effectSource && m_effectComponent) {
9401 activateEffect();
9402 updateNeeded = true;
9403 }
9404
9405 if (updateNeeded) {
9406 updateZ();
9407 updateGeometry();
9408 updateOpacity();
9409 updateMatrix();
9410 m_effectSource->setVisible(m_item->isVisible() && !m_effect);
9411 }
9412
9413 emit effectChanged(component);
9414}
9415
9416
9428void QQuickItemLayer::setMipmap(bool mipmap)
9429{
9430 if (mipmap == m_mipmap)
9431 return;
9432 m_mipmap = mipmap;
9433
9434 if (m_effectSource)
9435 m_effectSource->setMipmap(m_mipmap);
9436
9437 emit mipmapChanged(mipmap);
9438}
9439
9440
9458void QQuickItemLayer::setFormat(QQuickShaderEffectSource::Format f)
9459{
9460 if (f == m_format)
9461 return;
9462 m_format = f;
9463
9464 if (m_effectSource)
9465 m_effectSource->setFormat(m_format);
9466
9467 emit formatChanged(m_format);
9468}
9469
9470
9482void QQuickItemLayer::setSourceRect(const QRectF &sourceRect)
9483{
9484 if (sourceRect == m_sourceRect)
9485 return;
9486 m_sourceRect = sourceRect;
9487
9488 if (m_effectSource)
9489 m_effectSource->setSourceRect(m_sourceRect);
9490
9491 emit sourceRectChanged(sourceRect);
9492}
9493
9506void QQuickItemLayer::setSmooth(bool s)
9507{
9508 if (m_smooth == s)
9509 return;
9510 m_smooth = s;
9511
9512 if (m_effectSource)
9513 m_effectSource->setSmooth(m_smooth);
9514
9515 emit smoothChanged(s);
9516}
9517
9530void QQuickItemLayer::setLive(bool live)
9531{
9532 if (m_live == live)
9533 return;
9534 m_live = live;
9535
9536 if (m_effectSource)
9537 m_effectSource->setLive(m_live);
9538
9539 emit liveChanged(live);
9540}
9541
9555void QQuickItemLayer::setSize(const QSize &size)
9556{
9557 if (size == m_size)
9558 return;
9559 m_size = size;
9560
9561 if (m_effectSource)
9562 m_effectSource->setTextureSize(size);
9563
9564 emit sizeChanged(size);
9565}
9566
9585void QQuickItemLayer::setWrapMode(QQuickShaderEffectSource::WrapMode mode)
9586{
9587 if (mode == m_wrapMode)
9588 return;
9589 m_wrapMode = mode;
9590
9591 if (m_effectSource)
9592 m_effectSource->setWrapMode(m_wrapMode);
9593
9594 emit wrapModeChanged(mode);
9595}
9596
9612void QQuickItemLayer::setTextureMirroring(QQuickShaderEffectSource::TextureMirroring mirroring)
9613{
9614 if (mirroring == m_textureMirroring)
9615 return;
9616 m_textureMirroring = mirroring;
9617
9618 if (m_effectSource)
9619 m_effectSource->setTextureMirroring(m_textureMirroring);
9620
9621 emit textureMirroringChanged(mirroring);
9622}
9623
9649void QQuickItemLayer::setSamples(int count)
9650{
9651 if (m_samples == count)
9652 return;
9653
9654 m_samples = count;
9655
9656 if (m_effectSource)
9657 m_effectSource->setSamples(m_samples);
9658
9659 emit samplesChanged(count);
9660}
9661
9673void QQuickItemLayer::setName(const QByteArray &name) {
9674 if (m_name == name)
9675 return;
9676 if (m_effect) {
9677 m_effect->setProperty(m_name, QVariant());
9678 m_effect->setProperty(name, QVariant::fromValue<QObject *>(m_effectSource));
9679 }
9680 m_name = name;
9681 emit nameChanged(name);
9682}
9683
9684void QQuickItemLayer::itemOpacityChanged(QQuickItem *item)
9685{
9686 Q_UNUSED(item);
9687 updateOpacity();
9688}
9689
9690void QQuickItemLayer::itemGeometryChanged(QQuickItem *, QQuickGeometryChange, const QRectF &)
9691{
9692 updateGeometry();
9693}
9694
9695void QQuickItemLayer::itemParentChanged(QQuickItem *item, QQuickItem *parent)
9696{
9697 Q_UNUSED(item);
9698 Q_ASSERT(item == m_item);
9699 Q_ASSERT(parent != m_effectSource);
9700 Q_ASSERT(parent == nullptr || parent != m_effect);
9701
9702 m_effectSource->setParentItem(parent);
9703 if (parent)
9704 m_effectSource->stackAfter(m_item);
9705
9706 if (m_effect) {
9707 m_effect->setParentItem(parent);
9708 if (parent)
9709 m_effect->stackAfter(m_effectSource);
9710 }
9711}
9712
9713void QQuickItemLayer::itemSiblingOrderChanged(QQuickItem *)
9714{
9715 m_effectSource->stackAfter(m_item);
9716 if (m_effect)
9717 m_effect->stackAfter(m_effectSource);
9718}
9719
9720void QQuickItemLayer::itemVisibilityChanged(QQuickItem *)
9721{
9722 QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
9723 if (!l)
9724 return;
9725 l->setVisible(m_item->isVisible());
9726}
9727
9728void QQuickItemLayer::updateZ()
9729{
9730 if (!m_componentComplete || !m_enabled)
9731 return;
9732 QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
9733 if (!l)
9734 return;
9735 l->setZ(m_item->z());
9736}
9737
9738void QQuickItemLayer::updateOpacity()
9739{
9740 QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
9741 if (!l)
9742 return;
9743 l->setOpacity(m_item->opacity());
9744}
9745
9746void QQuickItemLayer::updateGeometry()
9747{
9748 QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
9749 if (!l)
9750 return;
9751 // Avoid calling QQuickImage::boundingRect() or other overrides
9752 // which may not be up-to-date at this time (QTBUG-104442, 104536)
9753 QRectF bounds = m_item->QQuickItem::boundingRect();
9754 l->setSize(bounds.size());
9755 l->setPosition(bounds.topLeft() + m_item->position());
9756}
9757
9758void QQuickItemLayer::updateMatrix()
9759{
9760 // Called directly from transformChanged(), so needs some extra
9761 // checks.
9762 if (!m_componentComplete || !m_enabled)
9763 return;
9764 QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
9765 if (!l)
9766 return;
9768 l->setScale(m_item->scale());
9769 l->setRotation(m_item->rotation());
9771 if (ld->origin() != QQuickItemPrivate::get(m_item)->origin())
9772 ld->extra.value().origin = QQuickItemPrivate::get(m_item)->origin();
9774}
9775#endif // quick_shadereffect
9776
9778: z(0), scale(1), rotation(0), opacity(1),
9779 contents(nullptr), screenAttached(nullptr), layoutDirectionAttached(nullptr),
9780 enterKeyAttached(nullptr),
9781 keyHandler(nullptr),
9782#if QT_CONFIG(quick_shadereffect)
9783 layer(nullptr),
9784#endif
9785 effectRefCount(0), hideRefCount(0),
9786 recursiveEffectRefCount(0),
9787 opacityNode(nullptr), clipNode(nullptr), rootNode(nullptr),
9788 origin(QQuickItem::Center),
9789 transparentForPositioner(false)
9790{
9791}
9792
9793
9794#if QT_CONFIG(accessibility)
9795QAccessible::Role QQuickItemPrivate::effectiveAccessibleRole() const
9796{
9797 Q_Q(const QQuickItem);
9798 auto *attached = qmlAttachedPropertiesObject<QQuickAccessibleAttached>(q, false);
9799 auto role = QAccessible::NoRole;
9800 if (auto *accessibleAttached = qobject_cast<QQuickAccessibleAttached *>(attached))
9801 role = accessibleAttached->role();
9802 if (role == QAccessible::NoRole)
9803 role = accessibleRole();
9804 return role;
9805}
9806
9807QAccessible::Role QQuickItemPrivate::accessibleRole() const
9808{
9809 return QAccessible::NoRole;
9810}
9811#endif
9812
9813// helper code to let a visual parent mark its visual children for the garbage collector
9814
9815namespace QV4 {
9816namespace Heap {
9818 static void markObjects(QV4::Heap::Base *that, QV4::MarkStack *markStack);
9819};
9820}
9821}
9822
9825};
9826
9828
9830{
9831 QObjectWrapper *This = static_cast<QObjectWrapper *>(that);
9832 if (QQuickItem *item = static_cast<QQuickItem*>(This->object())) {
9833 for (QQuickItem *child : std::as_const(QQuickItemPrivate::get(item)->childItems))
9835 }
9836 QObjectWrapper::markObjects(that, markStack);
9837}
9838
9840{
9841 return (engine->memoryManager->allocate<QQuickItemWrapper>(q_func()))->asReturnedValue();
9842}
9843
9845{
9846 QDebugStateSaver stateSaver(debug);
9847 debug.nospace() << "ChangeListener listener=" << listener.listener << " types=" << listener.types;
9848 return debug;
9849}
9850
9853{ return mapFromItem(item, QPointF(x, y) ); }
9854
9857{ return mapRectFromItem(item, rect); }
9858
9861{ return mapFromItem(item, QRectF(x, y, width, height)); }
9862
9865{ return mapToItem(item, QPoint(x, y)); }
9866
9869{ return mapRectToItem(item, rect); }
9870
9873{ return mapToItem(item, QRectF(x, y, width, height)); }
9874
9876QPointF QQuickItem::mapToGlobal(qreal x, qreal y) const
9877{ return mapToGlobal(QPointF(x, y)); }
9878
9880QPointF QQuickItem::mapFromGlobal(qreal x, qreal y) const
9881{ return mapFromGlobal(QPointF(x, y)); }
9882
9885
9887
9888#include <moc_qquickitem.cpp>
9889
9890#include "moc_qquickitem_p.cpp"
\inmodule QtGui
\inmodule QtCore
Definition qproperty.h:809
\inmodule QtCore
Definition qbytearray.h:57
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
Definition qbytearray.h:122
bool isEmpty() const noexcept
Returns true if the byte array has size 0; otherwise returns false.
Definition qbytearray.h:106
static bool sendEvent(QObject *receiver, QEvent *event)
Sends event event directly to receiver receiver, using the notify() function.
The QCursor class provides a mouse cursor with an arbitrary shape.
Definition qcursor.h:45
Qt::CursorShape shape() const
Returns the cursor shape identifier.
Definition qcursor.cpp:499
\inmodule QtCore
\inmodule QtCore
bool hasSeen(const T &s)
The QEventPoint class provides information about a point in a QPointerEvent.
Definition qeventpoint.h:20
\inmodule QtCore
Definition qcoreevent.h:45
Type
This enum type defines the valid event types in Qt.
Definition qcoreevent.h:51
@ ApplicationPaletteChange
Definition qcoreevent.h:93
@ ShortcutOverride
Definition qcoreevent.h:158
@ FocusOut
Definition qcoreevent.h:67
@ InputMethod
Definition qcoreevent.h:120
@ NativeGesture
Definition qcoreevent.h:246
@ DragEnter
Definition qcoreevent.h:101
@ LocaleChange
Definition qcoreevent.h:122
@ InputMethodQuery
Definition qcoreevent.h:261
@ KeyRelease
Definition qcoreevent.h:65
@ MouseMove
Definition qcoreevent.h:63
@ KeyPress
Definition qcoreevent.h:64
@ StyleAnimationUpdate
Definition qcoreevent.h:272
@ FocusIn
Definition qcoreevent.h:66
@ TouchCancel
Definition qcoreevent.h:264
@ MouseButtonPress
Definition qcoreevent.h:60
@ TouchUpdate
Definition qcoreevent.h:242
@ TouchBegin
Definition qcoreevent.h:241
@ HoverLeave
Definition qcoreevent.h:176
@ HoverEnter
Definition qcoreevent.h:175
@ WindowActivate
Definition qcoreevent.h:83
@ LanguageChange
Definition qcoreevent.h:123
@ DragLeave
Definition qcoreevent.h:103
@ HoverMove
Definition qcoreevent.h:177
@ MouseButtonDblClick
Definition qcoreevent.h:62
@ WindowDeactivate
Definition qcoreevent.h:84
@ MouseButtonRelease
Definition qcoreevent.h:61
Type type() const
Returns the event type.
Definition qcoreevent.h:299
void ignore()
Clears the accept flag parameter of the event object, the equivalent of calling setAccepted(false).
Definition qcoreevent.h:306
void accept()
Sets the accept flag of the event object, the equivalent of calling setAccepted(true).
Definition qcoreevent.h:305
The QFocusEvent class contains event parameters for widget focus events.
Definition qevent.h:469
QList< QGraphicsItem * > childItems() const
QGraphicsWidget * window() const
bool hasFocus() const
Returns true if this item is active, and it or its \l{focusProxy()}{focus proxy} has keyboard input f...
void setParentItem(QGraphicsItem *parent)
Sets this item's parent item to newParent.
QPointF mapToScene(const QPointF &point) const
Maps the point point, which is in this item's coordinate system, to the scene's coordinate system,...
QGraphicsItem * parentItem() const
Returns a pointer to this item's parent item.
GraphicsItemFlags flags() const
Returns this item's flags.
QPointF mapFromScene(const QPointF &point) const
Maps the point point, which is in this item's scene's coordinate system, to this item's coordinate sy...
static struct QGuiApplicationPrivate::QLastCursorPosition lastCursorPosition
static QStyleHints * styleHints()
Returns the application's style hints.
static QInputMethod * inputMethod()
returns the input method.
\inmodule QtGui
Definition qevent.h:245
The QInputMethodEvent class provides parameters for input method events.
Definition qevent.h:624
The QInputMethodQueryEvent class provides an event sent by the input context to input objects.
Definition qevent.h:678
Qt::InputMethodQueries queries() const
Returns the properties queried by the event.
Definition qevent.h:683
void update(Qt::InputMethodQueries queries)
Called by the input item to inform the platform input methods when there has been state changes in ed...
The QKeyEvent class describes a key event.
Definition qevent.h:423
Definition qlist.h:74
qsizetype size() const noexcept
Definition qlist.h:386
bool isEmpty() const noexcept
Definition qlist.h:390
bool removeOne(const AT &t)
Definition qlist.h:581
iterator end()
Definition qlist.h:609
qsizetype length() const noexcept
Definition qlist.h:388
const_reference at(qsizetype i) const noexcept
Definition qlist.h:429
void move(qsizetype from, qsizetype to)
Definition qlist.h:593
iterator begin()
Definition qlist.h:608
const T & constFirst() const noexcept
Definition qlist.h:630
void append(parameter_type t)
Definition qlist.h:441
The QMatrix4x4 class represents a 4x4 transformation matrix in 3D space.
Definition qmatrix4x4.h:25
void rotate(float angle, const QVector3D &vector)
Multiples this matrix by another that rotates coordinates through angle degrees about vector.
void scale(const QVector3D &vector)
Multiplies this matrix by another that scales coordinates by the components of vector.
QPoint map(const QPoint &point) const
Maps point by multiplying this matrix by point.
Definition qmatrix4x4.h:908
void translate(const QVector3D &vector)
Multiplies this matrix by another that translates coordinates by the components of vector.
\inmodule QtCore
Definition qmetaobject.h:18
bool invoke(QObject *object, Qt::ConnectionType connectionType, QGenericReturnArgument returnValue, QGenericArgument val0=QGenericArgument(nullptr), QGenericArgument val1=QGenericArgument(), QGenericArgument val2=QGenericArgument(), QGenericArgument val3=QGenericArgument(), QGenericArgument val4=QGenericArgument(), QGenericArgument val5=QGenericArgument(), QGenericArgument val6=QGenericArgument(), QGenericArgument val7=QGenericArgument(), QGenericArgument val8=QGenericArgument(), QGenericArgument val9=QGenericArgument()) const
\obsolete [6.5] Please use the variadic overload of this function
\inmodule QtGui
Definition qevent.h:195
static Q_GUI_EXPORT void detach(QEventPoint &p)
uint isQuickItem
Definition qobject.h:72
QObject * parent
Definition qobject.h:61
static QObjectPrivate * get(QObject *o)
Definition qobject_p.h:153
\inmodule QtCore
Definition qobject.h:90
const QObjectList & children() const
Returns a list of child objects.
Definition qobject.h:171
QObject * parent() const
Returns a pointer to the parent object.
Definition qobject.h:311
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2823
virtual bool event(QEvent *event)
This virtual function receives events to an object and should return true if the event e was recogniz...
Definition qobject.cpp:1363
void setParent(QObject *parent)
Makes the object a child of parent.
Definition qobject.cpp:2142
static bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *member)
\threadsafe
Definition qobject.cpp:3099
QVariant property(const char *name) const
Returns the value of the object's name property.
Definition qobject.cpp:4187
bool inherits(const char *classname) const
Returns true if this object is an instance of a class that inherits className or a QObject subclass t...
Definition qobject.h:313
void destroyed(QObject *=nullptr)
This signal is emitted immediately before the object obj is destroyed, after any instances of QPointe...
\inmodule QtCore\reentrant
Definition qpoint.h:214
constexpr qreal x() const noexcept
Returns the x coordinate of this point.
Definition qpoint.h:333
constexpr qreal y() const noexcept
Returns the y coordinate of this point.
Definition qpoint.h:338
bool isNull() const noexcept
Returns true if both the x and y coordinates are set to 0.0 (ignoring the sign); otherwise returns fa...
Definition qpoint.h:328
\inmodule QtCore\reentrant
Definition qpoint.h:23
A base class for pointer events.
Definition qevent.h:73
The QQmlComponent class encapsulates a QML component definition.
The QQmlListProperty class allows applications to expose list-like properties of QObject-derived clas...
Definition qqmllist.h:24
QObject * object
Definition qqmllist.h:81
RemoveLastFunction removeLast
Definition qqmllist.h:89
void clearItem(QQuickItem *)
static QQuickAnchorsPrivate * get(QQuickAnchors *o)
~QQuickContents() override
QQuickContents(QQuickItem *item)
void calcGeometry(QQuickItem *changed=nullptr)
void itemChildRemoved(QQuickItem *, QQuickItem *) override
void itemChildAdded(QQuickItem *, QQuickItem *) override
QRectF rectF() const
void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &) override
void itemDestroyed(QQuickItem *item) override
void removeGrabber(QQuickItem *grabber, bool mouse=true, bool touch=true, bool cancel=false)
Ungrabs all touchpoint grabs and/or the mouse grab from the given item grabber.
static bool isMouseOrWheelEvent(const QPointerEvent *ev)
static void notifyFocusChangesRecur(QQuickItem **item, int remaining, Qt::FocusReason reason)
static QQuickDeliveryAgent * currentOrItemDeliveryAgent(const QQuickItem *item)
void setFocusInScope(QQuickItem *scope, QQuickItem *item, Qt::FocusReason reason, FocusOptions={ })
Set the focus inside scope to be item.
void clearFocusInScope(QQuickItem *scope, QQuickItem *item, Qt::FocusReason reason, FocusOptions={ })
Qt::EnterKeyType type
QQuickEnterKeyAttached(QObject *parent=nullptr)
\qmltype EnterKey \instantiates QQuickEnterKeyAttached \inqmlmodule QtQuick
void setType(Qt::EnterKeyType type)
static QQuickEnterKeyAttached * qmlAttachedProperties(QObject *)
bool matches(QQuickGeometryChange other) const
virtual void itemParentChanged(QQuickItem *, QQuickItem *)
virtual void itemSiblingOrderChanged(QQuickItem *)
virtual void itemChildAdded(QQuickItem *, QQuickItem *)
virtual ~QQuickItemChangeListener()
virtual void itemRotationChanged(QQuickItem *)
virtual void itemEnabledChanged(QQuickItem *)
virtual void itemOpacityChanged(QQuickItem *)
virtual void itemGeometryChanged(QQuickItem *, QQuickGeometryChange, const QRectF &)
virtual void itemImplicitWidthChanged(QQuickItem *)
virtual void itemChildRemoved(QQuickItem *, QQuickItem *)
virtual QQuickAnchorsPrivate * anchorPrivate()
virtual void itemDestroyed(QQuickItem *)
virtual void itemVisibilityChanged(QQuickItem *)
virtual void itemImplicitHeightChanged(QQuickItem *)
virtual void itemFocusChanged(QQuickItem *, Qt::FocusReason)
virtual void keyReleased(QKeyEvent *event, bool post)
virtual void componentComplete()
QQuickItemKeyFilter(QQuickItem *=nullptr)
virtual void shortcutOverrideEvent(QKeyEvent *event)
virtual void keyPressed(QKeyEvent *event, bool post)
virtual ~QQuickItemKeyFilter()
bool calcEffectiveVisible() const
QQuickItem ** prevDirtyItem
void updateOrRemoveGeometryChangeListener(QQuickItemChangeListener *listener, QQuickGeometryChange types)
void updateOrAddGeometryChangeListener(QQuickItemChangeListener *listener, QQuickGeometryChange types)
QQuickAnchors * _anchors
QQuickAnchorLine verticalCenter() const
QTransform windowToItemTransform() const
Returns a transform that maps points from window space into item space.
static void data_clear(QQmlListProperty< QObject > *)
QQmlListProperty< QQuickTransition > transitions()
QLazilyAllocated< ExtraData, ExtraDataTags > extra
virtual void registerAsContainmentMask(QQuickItem *, bool)
static void children_removeLast(QQmlListProperty< QQuickItem > *)
void notifyChangeListeners(QQuickItemPrivate::ChangeTypes changeTypes, Fn &&function, Args &&...args)
QList< QQuickItem * > paintOrderChildItems() const
quint64 _q_createJSWrapper(QV4::ExecutionEngine *engine)
static QQuickItem * visibleChildren_at(QQmlListProperty< QQuickItem > *prop, qsizetype index)
quint32 subtreeCursorEnabled
void init(QQuickItem *parent)
QQuickDeliveryAgent * deliveryAgent()
virtual bool handlePointerEvent(QPointerEvent *, bool avoidGrabbers=false)
quint32 maybeHasSubsceneDeliveryAgent
virtual bool transformChanged(QQuickItem *transformedItem)
static QQuickItem * prevTabChildItem(const QQuickItem *item, int start)
quint32 effectiveLayoutMirror
~QQuickItemPrivate() override
QQuickAnchors * anchors() const
\qmlpropertygroup QtQuick::Item::anchors \qmlproperty AnchorLine QtQuick::Item::anchors....
QSGTransformNode * itemNodeInstance
bool hasPointerHandlers() const
static qsizetype children_count(QQmlListProperty< QQuickItem > *)
void setLayoutMirror(bool mirror)
quint32 subtreeHoverEnabled
QPointer< QQuickItem > subFocusItem
QString dirtyToString() const
void removeItemChangeListener(QQuickItemChangeListener *, ChangeTypes types)
void removeChild(QQuickItem *)
static void children_clear(QQmlListProperty< QQuickItem > *)
static qsizetype transform_count(QQmlListProperty< QQuickTransform > *list)
QQmlListProperty< QObject > resources()
static qsizetype data_count(QQmlListProperty< QObject > *)
\qmlproperty list<QtObject> QtQuick::Item::data \qmldefault
void derefFromEffectItem(bool unhide)
static QQuickItem * children_at(QQmlListProperty< QQuickItem > *, qsizetype)
static qsizetype resources_count(QQmlListProperty< QObject > *)
QTransform itemToWindowTransform() const
Returns a transform that maps points from item space into window space.
quint32 inheritMirrorFromItem
void itemChange(QQuickItem::ItemChange, const QQuickItem::ItemChangeData &)
void itemToParentTransform(QTransform *) const
Modifies t with this item's local transform relative to its parent.
virtual void implicitHeightChanged()
static void data_removeLast(QQmlListProperty< QObject > *)
QList< QQuickItem * > * sortedChildItems
QQmlListProperty< QQuickItem > visibleChildren()
static QObject * resources_at(QQmlListProperty< QObject > *, qsizetype)
virtual void mirrorChange()
QQmlListProperty< QQuickState > states()
void updateOrAddItemChangeListener(QQuickItemChangeListener *listener, ChangeTypes types)
QQuickStateGroup * _stateGroup
QVector< QQuickItemPrivate::ChangeListener > changeListeners
QQuickItem * parentItem
void addChild(QQuickItem *)
bool calcEffectiveEnable() const
static QQuickTransform * transform_at(QQmlListProperty< QQuickTransform > *list, qsizetype)
void deliverKeyEvent(QKeyEvent *)
static void resources_removeLast(QQmlListProperty< QObject > *)
QQuickAnchorLine right() const
QQuickItem * nextDirtyItem
static QObject * data_at(QQmlListProperty< QObject > *, qsizetype)
QString state() const
void setTransparentForPositioner(bool trans)
void dirty(DirtyType)
bool filterKeyEvent(QKeyEvent *, bool post)
void setImplicitAntialiasing(bool antialiasing)
static QQuickItem * nextTabChildItem(const QQuickItem *item, int start)
qreal z() const
QQuickAnchorLine bottom() const
static void children_append(QQmlListProperty< QQuickItem > *, QQuickItem *)
static qsizetype visibleChildren_count(QQmlListProperty< QQuickItem > *prop)
qreal rotation() const
void localizedTouchEvent(const QTouchEvent *event, bool isFiltering, QMutableTouchEvent *localized)
virtual void dumpItemTree(int indent) const
virtual void removePointerHandler(QQuickPointerHandler *h)
quint32 inheritMirrorFromParent
void recursiveRefFromEffectItem(int refs)
quint32 subtreeTransformChangedEnabled
static bool focusNextPrev(QQuickItem *item, bool forward)
QQuickItemPrivate::focusNextPrev focuses the next/prev item in the tab-focus-chain.
void setEffectiveEnableRecur(QQuickItem *scope, bool)
QTransform windowToGlobalTransform() const
Returns a transform that maps points from window space into global space.
void addItemChangeListener(QQuickItemChangeListener *listener, ChangeTypes types)
QList< QQuickTransform * > transforms
QQuickWindow * window
virtual qreal getImplicitWidth() const
static void resources_append(QQmlListProperty< QObject > *, QObject *)
static bool canAcceptTabFocus(QQuickItem *item)
void deliverShortcutOverrideEvent(QKeyEvent *)
void setHasCursorInChild(bool hasCursor)
QQuickItem::TransformOrigin origin() const
qreal scale() const
bool setEffectiveVisibleRecur(bool)
void refWindow(QQuickWindow *)
QQuickAnchorLine left() const
virtual void setVisible(bool visible)
QQuickAnchorLine top() const
quint32 componentComplete
void markSortedChildrenDirty(QQuickItem *child)
QQuickDeliveryAgentPrivate * deliveryAgentPrivate()
virtual void addPointerHandler(QQuickPointerHandler *h)
bool hasEnabledHoverHandlers() const
quint32 inheritedLayoutMirror
QQmlListProperty< QQuickItem > children()
void refFromEffectItem(bool hide)
QQuickDeliveryAgent * ensureSubsceneDeliveryAgent()
QQuickAnchorLine horizontalCenter() const
void setState(const QString &)
QTransform globalToWindowTransform() const
Returns a transform that maps points from global space into window space.
void updateSubFocusItem(QQuickItem *scope, bool focus)
Clears all sub focus items from scope.
QPointF computeTransformOrigin() const
quint32 implicitAntialiasing
void _q_resourceObjectDeleted(QObject *)
QQuickStateGroup * _states()
virtual qreal getImplicitHeight() const
bool anyPointerHandlerWants(const QPointerEvent *event, const QEventPoint &point) const
static QQuickItem * nextPrevItemInTabFocusChain(QQuickItem *item, bool forward)
QQmlListProperty< QObject > data()
static void data_append(QQmlListProperty< QObject > *, QObject *)
static void transform_clear(QQmlListProperty< QQuickTransform > *list)
virtual QSGTransformNode * createTransformNode()
static QQuickItemPrivate * get(QQuickItem *item)
void setHasHoverInChild(bool hasHover)
bool isTransparentForPositioner() const
static void transform_append(QQmlListProperty< QQuickTransform > *list, QQuickTransform *)
QPointF adjustedPosForTransform(const QPointF &centroid, const QPointF &startPos, const QVector2D &activeTranslatation, qreal startScale, qreal activeScale, qreal startRotation, qreal activeRotation)
static void resources_clear(QQmlListProperty< QObject > *)
virtual void implicitWidthChanged()
QList< QQuickItem * > childItems
void setImplicitLayoutMirror(bool mirror, bool inherit)
void emitChildrenRectChanged(const QRectF &rect)
QQuickAnchorLine baseline() const
The QQuickItem class provides the most basic of all visual items in \l {Qt Quick}.
Definition qquickitem.h:64
QPointF mapToScene(const QPointF &point) const
Maps the given point in this item's coordinate system to the equivalent point within the scene's coor...
QBindable< qreal > bindableWidth()
bool event(QEvent *) override
\reimp
void parentChanged(QQuickItem *)
void resetHeight()
virtual void focusOutEvent(QFocusEvent *)
This event handler can be reimplemented in a subclass to receive focus-out events for an item.
void setFiltersChildMouseEvents(bool filter)
Sets whether pointer events intended for this item's children should be filtered through this item.
virtual void mouseReleaseEvent(QMouseEvent *event)
This event handler can be reimplemented in a subclass to receive mouse release events for an item.
void zChanged()
void baselineOffsetChanged(qreal)
virtual QSGNode * updatePaintNode(QSGNode *, UpdatePaintNodeData *)
Called on the render thread when it is time to sync the state of the item with the scene graph.
virtual void hoverEnterEvent(QHoverEvent *event)
This event handler can be reimplemented in a subclass to receive hover-enter events for an item.
Flags flags() const
Returns the item flags for this item.
void setKeepTouchGrab(bool)
Sets whether the touch points grabbed by this item should remain exclusively with this item.
void classBegin() override
\reimp Derived classes should call the base class method before adding their own action to perform at...
void setTransformOriginPoint(const QPointF &)
QRectF mapRectToItem(const QQuickItem *item, const QRectF &rect) const
Maps the given rect in this item's coordinate system to the equivalent rectangular area within item's...
QList< QQuickItem * > childItems() const
Returns the children of this item.
Q_INVOKABLE QPointF mapFromItem(const QQuickItem *item, const QPointF &point) const
Maps the given point in item's coordinate system to the equivalent point within this item's coordinat...
void setAntialiasing(bool)
void setOpacity(qreal)
void setFocus(bool)
void setSize(const QSizeF &size)
void rotationChanged()
bool acceptTouchEvents() const
Returns whether touch events are accepted by this item.
TransformOrigin
\variable QQuickItem::ItemChangeData::realValue The numeric value that has changed: \l {QQuickItem::o...
Definition qquickitem.h:170
QQuickItem * viewportItem() const
If the \l ItemObservesViewport flag is set, returns the nearest parent with the \l ItemIsViewport fla...
void scaleChanged()
void setScale(qreal)
void setSmooth(bool)
void setRotation(qreal)
virtual void mouseDoubleClickEvent(QMouseEvent *event)
This event handler can be reimplemented in a subclass to receive mouse double-click events for an ite...
Qt::MouseButtons acceptedMouseButtons() const
Returns the mouse buttons accepted by this item.
void setFlag(Flag flag, bool enabled=true)
Enables the specified flag for this item if enabled is true; if enabled is false, the flag is disable...
void smoothChanged(bool)
void resetWidth()
void antialiasingChanged(bool)
virtual void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry)
bool isFocusScope() const
Returns true if this item is a focus scope, and false otherwise.
qreal implicitWidth
Definition qquickitem.h:113
virtual void mouseUngrabEvent()
This event handler can be reimplemented in a subclass to be notified when a mouse ungrab event has oc...
virtual void keyPressEvent(QKeyEvent *event)
This event handler can be reimplemented in a subclass to receive key press events for an item.
Q_INVOKABLE QPointF mapToItem(const QQuickItem *item, const QPointF &point) const
Maps the given point in this item's coordinate system to the equivalent point within item's coordinat...
qreal x
\qmlproperty real QtQuick::Item::x \qmlproperty real QtQuick::Item::y \qmlproperty real QtQuick::Item...
Definition qquickitem.h:73
void setParentItem(QQuickItem *parent)
qreal z
\qmlproperty real QtQuick::Item::z
Definition qquickitem.h:75
void componentComplete() override
\reimp Derived classes should call the base class method before adding their own actions to perform a...
void setAcceptHoverEvents(bool enabled)
If enabled is true, this sets the item to accept hover events; otherwise, hover events are not accept...
QBindable< qreal > bindableY()
void opacityChanged()
QPointF mapFromScene(const QPointF &point) const
Maps the given point in the scene's coordinate system to the equivalent point within this item's coor...
QString state() const
\qmlproperty string QtQuick::Item::state
virtual void hoverMoveEvent(QHoverEvent *event)
This event handler can be reimplemented in a subclass to receive hover-move events for an item.
void ungrabTouchPoints()
void setState(const QString &)
qreal y
Defines the item's y position relative to its parent.
Definition qquickitem.h:74
bool activeFocusOnTab() const
\qmlproperty bool QtQuick::Item::activeFocusOnTab
bool hasActiveFocus() const
void setAcceptTouchEvents(bool accept)
If enabled is true, this sets the item to accept touch events; otherwise, touch events are not accept...
bool isVisible() const
qreal baselineOffset() const
\qmlproperty int QtQuick::Item::baselineOffset
Q_INVOKABLE QQuickItem * childAt(qreal x, qreal y) const
\qmlmethod QtQuick::Item::childAt(real x, real y)
TransformOrigin transformOrigin
\qmlproperty enumeration QtQuick::Item::transformOrigin This property holds the origin point around w...
Definition qquickitem.h:107
virtual QSGTextureProvider * textureProvider() const
Returns the texture provider for an item.
QRectF childrenRect()
\qmlpropertygroup QtQuick::Item::childrenRect \qmlproperty real QtQuick::Item::childrenRect....
void setHeight(qreal)
bool hasFocus() const
virtual Q_INVOKABLE bool contains(const QPointF &point) const
\qmlmethod bool QtQuick::Item::contains(point point)
void setEnabled(bool)
QObject * containmentMask
\qmlproperty QObject* QtQuick::Item::containmentMask
Definition qquickitem.h:115
virtual QRectF boundingRect() const
Returns the extents of the item in its own coordinate system: a rectangle from {0,...
void setAcceptedMouseButtons(Qt::MouseButtons buttons)
Sets the mouse buttons accepted by this item to buttons.
void ungrabMouse()
QSizeF size() const
bool keepTouchGrab() const
Returns whether the touch points grabbed by this item should exclusively remain with this item.
void setFlags(Flags flags)
Enables the specified flags for this item.
QQuickWindow * window() const
Returns the window in which this item is rendered.
void setContainmentMask(QObject *mask)
virtual void mousePressEvent(QMouseEvent *event)
This event handler can be reimplemented in a subclass to receive mouse press events for an item.
~QQuickItem() override
Destroys the QQuickItem.
void setBaselineOffset(qreal)
bool acceptHoverEvents() const
Returns whether hover events are accepted by this item.
qreal width
This property holds the width of this item.
Definition qquickitem.h:76
QQuickItem * scopedFocusItem() const
If this item is a focus scope, this returns the item in its focus chain that currently has focus.
QQuickItem * parentItem() const
bool filtersChildMouseEvents() const
Returns whether pointer events intended for this item's children should be filtered through this item...
QRectF mapRectFromItem(const QQuickItem *item, const QRectF &rect) const
Maps the given rect in item's coordinate system to the equivalent rectangular area within this item's...
void stackAfter(const QQuickItem *)
Moves the specified sibling item to the index after this item within the list of children.
void setVisible(bool)
virtual void itemChange(ItemChange, const ItemChangeData &)
Called when change occurs for this item.
void clipChanged(bool)
bool isComponentComplete() const
Returns true if construction of the QML component is complete; otherwise returns false.
QQuickItem * parent
\qmlproperty Item QtQuick::Item::parent This property holds the visual parent of the item.
Definition qquickitem.h:68
QTransform itemTransform(QQuickItem *, bool *) const
\qmlmethod point QtQuick::Item::mapFromItem(Item item, real x, real y) \qmlmethod point QtQuick::Item...
virtual void touchUngrabEvent()
This event handler can be reimplemented in a subclass to be notified when a touch ungrab event has oc...
void grabTouchPoints(const QList< int > &ids)
qreal implicitHeight
Definition qquickitem.h:114
bool clip() const
\qmlproperty bool QtQuick::Item::clip This property holds whether clipping is enabled.
QBindable< qreal > bindableHeight()
void setImplicitHeight(qreal)
bool keepMouseGrab() const
Returns whether mouse input should exclusively remain with this item.
QPointF position() const
bool isEnabled() const
bool heightValid() const
Returns whether the height property has been set explicitly.
void setKeepMouseGrab(bool)
Sets whether the mouse input should remain exclusively with this item.
Q_INVOKABLE void forceActiveFocus()
\qmlmethod point QtQuick::Item::mapToItem(Item item, real x, real y) \qmlmethod point QtQuick::Item::...
bool antialiasing
\qmlproperty bool QtQuick::Item::antialiasing
Definition qquickitem.h:112
bool smooth
\qmlproperty bool QtQuick::Item::smooth
Definition qquickitem.h:111
qreal rotation
\qmlproperty real QtQuick::Item::rotation This property holds the rotation of the item in degrees clo...
Definition qquickitem.h:105
void grabMouse()
bool widthValid() const
Returns whether the width property has been set explicitly.
virtual void touchEvent(QTouchEvent *event)
This event handler can be reimplemented in a subclass to receive touch events for an item.
qreal height
This property holds the height of this item.
Definition qquickitem.h:77
virtual bool childMouseEventFilter(QQuickItem *, QEvent *)
Reimplement this method to filter the pointer events that are received by this item's children.
virtual void updatePolish()
This function should perform any layout as required for this item.
void setPosition(const QPointF &)
void setZ(qreal)
virtual void releaseResources()
This function is called when an item should release graphics resources which are not already managed ...
virtual void keyReleaseEvent(QKeyEvent *event)
This event handler can be reimplemented in a subclass to receive key release events for an item.
void setWidth(qreal)
QQuickItem(QQuickItem *parent=nullptr)
Constructs a QQuickItem with the given parent.
QRectF mapRectToScene(const QRectF &rect) const
Maps the given rect in this item's coordinate system to the equivalent rectangular area within the sc...
virtual QRectF clipRect() const
Returns the rectangular area within this item that is currently visible in \l viewportItem(),...
qreal scale
\qmlproperty real QtQuick::Item::scale This property holds the scale factor for this item.
Definition qquickitem.h:106
ItemChange
Used in conjunction with QQuickItem::itemChange() to notify the item about certain types of changes.
Definition qquickitem.h:143
@ ItemVisibleHasChanged
Definition qquickitem.h:147
@ ItemActiveFocusHasChanged
Definition qquickitem.h:150
@ ItemAntialiasingHasChanged
Definition qquickitem.h:152
@ ItemEnabledHasChanged
Definition qquickitem.h:154
@ ItemRotationHasChanged
Definition qquickitem.h:151
@ ItemOpacityHasChanged
Definition qquickitem.h:149
@ ItemParentHasChanged
Definition qquickitem.h:148
@ ItemChildAddedChange
Definition qquickitem.h:144
@ ItemChildRemovedChange
Definition qquickitem.h:145
@ ItemDevicePixelRatioHasChanged
Definition qquickitem.h:153
virtual void focusInEvent(QFocusEvent *)
This event handler can be reimplemented in a subclass to receive focus-in events for an item.
void setTransformOrigin(TransformOrigin)
void visibleChildrenChanged()
qreal opacity
\qmlproperty real QtQuick::Item::opacity
Definition qquickitem.h:79
bool isUnderMouse() const
void setX(qreal)
QRectF mapRectFromScene(const QRectF &rect) const
Maps the given rect in the scene's coordinate system to the equivalent rectangular area within this i...
@ ItemObservesViewport
Definition qquickitem.h:137
@ ItemClipsChildrenToShape
Definition qquickitem.h:129
bool enabled
\qmlproperty bool QtQuick::Item::enabled
Definition qquickitem.h:80
bool isAncestorOf(const QQuickItem *child) const
Returns true if this item is an ancestor of child (i.e., if this item is child's parent,...
QBindable< qreal > bindableX()
void transformOriginChanged(TransformOrigin)
void resetAntialiasing()
void setClip(bool)
void focusChanged(bool)
void setImplicitWidth(qreal)
virtual void hoverLeaveEvent(QHoverEvent *event)
This event handler can be reimplemented in a subclass to receive hover-leave events for an item.
void setY(qreal)
void update()
Schedules a call to updatePaintNode() for this item.
void stackBefore(const QQuickItem *)
Moves the specified sibling item to the index before this item within the list of children.
QQmlListProperty< QQuickTransform > transform
\qmlproperty list<Transform> QtQuick::Item::transform This property holds the list of transformations...
Definition qquickitem.h:109
void polish()
Schedules a polish event for this item.
virtual bool isTextureProvider() const
Returns true if this item is a texture provider.
virtual void mouseMoveEvent(QMouseEvent *event)
This event handler can be reimplemented in a subclass to receive mouse move events for an item.
void setActiveFocusOnTab(bool)
void setImplicitSize(qreal, qreal)
QPointF transformOriginPoint
Definition qquickitem.h:108
void setAccepted(bool accepted)
void reset(QEvent::Type type, int key, Qt::KeyboardModifiers modifiers, const QString &text=QString(), bool autorep=false, ushort count=1)
void setUp(QQuickItem *)
void setLeft(QQuickItem *)
static QQuickKeyNavigationAttached * qmlAttachedProperties(QObject *)
void setTab(QQuickItem *)
QQuickKeyNavigationAttached(QObject *=nullptr)
\qmltype KeyNavigation \instantiates QQuickKeyNavigationAttached \inqmlmodule QtQuick
void setBacktab(QQuickItem *)
void keyReleased(QKeyEvent *event, bool post) override
void keyPressed(QKeyEvent *event, bool post) override
void setRight(QQuickItem *)
void setDown(QQuickItem *)
~QQuickKeysAttached() override
void keyPressed(QKeyEvent *event, bool post) override
static QQuickKeysAttached * qmlAttachedProperties(QObject *)
void keyReleased(QKeyEvent *event, bool post) override
QQuickKeysAttached(QObject *parent=nullptr)
\qmltype Keys \instantiates QQuickKeysAttached \inqmlmodule QtQuick
void released(QQuickKeyEvent *event)
void setPriority(Priority)
void pressed(QQuickKeyEvent *event)
void shortcutOverride(QQuickKeyEvent *event)
void shortcutOverrideEvent(QKeyEvent *event) override
void componentComplete() override
static QQuickLayoutMirroringAttached * qmlAttachedProperties(QObject *)
QQuickLayoutMirroringAttached(QObject *parent=nullptr)
\qmltype LayoutMirroring \instantiates QQuickLayoutMirroringAttached \inqmlmodule QtQuick
QInputDevice::DeviceTypes acceptedDevices
static QQuickPointerHandlerPrivate * get(QQuickPointerHandler *q)
static QVector< QObject * > & deviceDeliveryTargets(const QInputDevice *device)
QQuickItem * parentItem() const
\qmlproperty Item QtQuick::PointerHandler::parent
static QWindow * renderWindowFor(QQuickWindow *win, QPoint *offset=nullptr)
Returns the real window that win is being rendered to, if any.
QQmlListProperty< QQuickTransition > transitionsProperty()
\qmlproperty list<Transition> QtQuick::StateGroup::transitions This property holds a list of transiti...
void setState(const QString &)
QQmlListProperty< QQuickState > statesProperty()
\qmlproperty list<State> QtQuick::StateGroup::states This property holds a list of states defined by ...
void classBegin() override
Invoked after class creation, but before any properties have been set.
static QQuickTransformPrivate * get(QQuickTransform *transform)
QQuickTransformPrivate()
\qmltype Transform \instantiates QQuickTransform \inqmlmodule QtQuick
QList< QQuickItem * > items
void prependToItem(QQuickItem *)
QQuickTransform(QObject *parent=nullptr)
virtual void applyTo(QMatrix4x4 *matrix) const =0
void appendToItem(QQuickItem *)
~QQuickTransform() override
void dirtyItem(QQuickItem *)
static QQuickWindowPrivate * get(QQuickWindow *c)
QVector< QQuickItem * > itemsToPolish
QSet< QQuickItem * > parentlessItems
QQuickDeliveryAgent * deliveryAgent
\qmltype Window \instantiates QQuickWindow \inqmlmodule QtQuick
\inmodule QtCore\reentrant
Definition qrect.h:483
constexpr qreal y() const noexcept
Returns the y-coordinate of the rectangle's top edge.
Definition qrect.h:658
constexpr qreal height() const noexcept
Returns the height of the rectangle.
Definition qrect.h:718
constexpr qreal width() const noexcept
Returns the width of the rectangle.
Definition qrect.h:715
constexpr qreal x() const noexcept
Returns the x-coordinate of the rectangle's left edge.
Definition qrect.h:655
constexpr void setY(qreal pos) noexcept
Sets the top edge of the rectangle to the given finite y coordinate.
Definition qrect.h:508
constexpr void setWidth(qreal w) noexcept
Sets the width of the rectangle to the given finite width.
Definition qrect.h:804
constexpr QPointF topLeft() const noexcept
Returns the position of the rectangle's top-left corner.
Definition qrect.h:510
constexpr QSizeF size() const noexcept
Returns the size of the rectangle.
Definition qrect.h:721
constexpr void setHeight(qreal h) noexcept
Sets the height of the rectangle to the given finite height.
Definition qrect.h:807
constexpr void setX(qreal pos) noexcept
Sets the left edge of the rectangle to the given finite x coordinate.
Definition qrect.h:507
\group qtquick-scenegraph-nodes \title Qt Quick Scene Graph Node classes
Definition qsgnode.h:37
The QSGTextureProvider class encapsulates texture based entities in QML.
The QSGTransformNode class implements transformations in the scene graph.
Definition qsgnode.h:244
bool remove(const T &value)
Definition qset.h:63
iterator insert(const T &value)
Definition qset.h:155
\inmodule QtCore
Definition qsize.h:207
\inmodule QtCore
Definition qsize.h:25
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
Qt::TabFocusBehavior tabFocusBehavior
The focus behavior on press of the tab key.
Definition qstylehints.h:44
The QTouchEvent class contains parameters that describe a touch event.
Definition qevent.h:916
The QTransform class specifies 2D transformations of a coordinate system.
Definition qtransform.h:20
static QTransform fromTranslate(qreal dx, qreal dy)
Creates a matrix which corresponds to a translation of dx along the x axis and dy along the y axis.
QTransform inverted(bool *invertible=nullptr) const
Returns an inverted copy of this matrix.
QRect mapRect(const QRect &) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
constexpr size_type size() const noexcept
T * data() noexcept
\inmodule QtCore
Definition qvariant.h:64
bool isValid() const
Returns true if the storage type of this variant is not QMetaType::UnknownType; otherwise returns fal...
Definition qvariant.h:707
bool toBool() const
Returns the variant as a bool if the variant has userType() Bool.
The QVector2D class represents a vector or vertex in 2D space.
Definition qvectornd.h:31
The QVector3D class represents a vector or vertex in 3D space.
Definition qvectornd.h:171
\inmodule QtGui
Definition qwindow.h:63
[Window class with invokable method]
Definition window.h:11
bool focus
[0]
QCursor cursor
double e
rect
[4]
else opt state
[0]
short next
Definition keywords.cpp:445
Combined button and popup list for selecting options.
\qmltype Particle \inqmlmodule QtQuick.Particles
static void formatQRect(QDebug &debug, const Rect &rect)
Definition qdebug_p.h:45
InputMethodQuery
@ ImMaximumTextLength
@ ImAnchorRectangle
@ ImSurroundingText
@ ImInputItemClipRectangle
@ ImCursorPosition
@ ImEnterKeyType
@ ImCurrentSelection
@ ImReadOnly
@ ImPreferredLanguage
@ ImFont
@ ImAnchorPosition
@ ImCursorRectangle
@ ImHints
@ ImEnabled
@ TabFocusAllControls
Definition qnamespace.h:117
@ LeftButton
Definition qnamespace.h:57
@ AllButtons
Definition qnamespace.h:89
CursorShape
@ LastCursor
@ ArrowCursor
@ Key_Escape
Definition qnamespace.h:658
@ Key_Yes
@ Key_Tab
Definition qnamespace.h:659
@ Key_Select
@ Key_Return
Definition qnamespace.h:662
@ Key_9
Definition qnamespace.h:538
@ Key_Context2
@ Key_Context1
@ Key_Right
Definition qnamespace.h:674
@ Key_Enter
Definition qnamespace.h:663
@ Key_Cancel
@ Key_Space
Definition qnamespace.h:512
@ Key_Hangup
@ Key_Context3
@ Key_VolumeUp
Definition qnamespace.h:847
@ Key_Backtab
Definition qnamespace.h:660
@ Key_VolumeDown
Definition qnamespace.h:845
@ Key_Left
Definition qnamespace.h:672
@ Key_NumberSign
Definition qnamespace.h:516
@ Key_0
Definition qnamespace.h:529
@ Key_Up
Definition qnamespace.h:673
@ Key_Down
Definition qnamespace.h:675
@ Key_Delete
Definition qnamespace.h:665
@ Key_Menu
Definition qnamespace.h:722
@ Key_Back
Definition qnamespace.h:841
@ Key_Context4
@ Key_Call
@ Key_Asterisk
Definition qnamespace.h:523
@ Key_No
@ Key_Flip
@ ShiftModifier
@ ControlModifier
@ AltModifier
@ DirectConnection
EnterKeyType
FocusReason
@ BacktabFocusReason
@ OtherFocusReason
@ TabFocusReason
#define QByteArrayLiteral(str)
Definition qbytearray.h:52
#define Q_UNLIKELY(x)
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
EGLOutputLayerEXT layer
bool qFuzzyIsNull(qfloat16 f) noexcept
Definition qfloat16.h:303
Flags
#define qDebug
[1]
Definition qlogging.h:160
@ QtDebugMsg
Definition qlogging.h:30
#define qWarning
Definition qlogging.h:162
#define Q_LOGGING_CATEGORY(name,...)
#define qCDebug(category,...)
#define Q_DECLARE_LOGGING_CATEGORY(name)
return ret
constexpr const T & qMin(const T &a, const T &b)
Definition qminmax.h:40
constexpr const T & qMax(const T &a, const T &b)
Definition qminmax.h:42
static Q_DECL_CONST_FUNCTION bool qt_is_nan(double d)
Definition qnumeric_p.h:106
#define SLOT(a)
Definition qobjectdefs.h:51
#define Q_RETURN_ARG(Type, data)
Definition qobjectdefs.h:63
#define Q_ARG(Type, data)
Definition qobjectdefs.h:62
#define SIGNAL(a)
Definition qobjectdefs.h:52
GLsizei const GLfloat * v
[13]
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat z
GLint GLint GLint GLint GLint x
[0]
GLint GLenum GLsizei GLsizei GLsizei depth
GLenum mode
const GLfloat * m
GLuint64 key
GLfloat GLfloat GLfloat w
[0]
GLint GLsizei GLsizei height
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLuint index
[2]
GLboolean r
[2]
GLenum GLenum GLsizei const GLuint * ids
GLsizei GLenum GLenum * types
GLdouble GLdouble GLdouble GLdouble top
GLenum GLenum GLsizei count
GLdouble GLdouble right
GLenum GLenum GLsizei const GLuint GLboolean enabled
GLfloat GLfloat f
GLint GLsizei width
GLint left
GLenum type
GLint GLint bottom
GLbitfield flags
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLuint start
GLenum GLuint GLintptr offset
GLuint name
GLint GLint GLint GLint GLint GLint GLint GLbitfield mask
GLint y
GLfloat GLfloat GLfloat GLfloat h
struct _cl_event * event
GLuint GLenum GLenum transform
GLhandleARB obj
[2]
GLenum query
GLuint res
const GLubyte * c
GLdouble GLdouble t
Definition qopenglext.h:243
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
GLuint64EXT * result
[6]
GLdouble s
[6]
Definition qopenglext.h:235
GLfloat GLfloat p
[1]
GLfixed GLfixed GLint GLint order
GLenum GLenum GLenum GLenum GLenum scale
static qreal component(const QPointF &point, unsigned int i)
#define qmlobject_disconnect(Sender, SenderType, Signal, Receiver, ReceiverType, Method)
Disconnect Signal of Sender from Method of Receiver.
#define qmlobject_connect(Sender, SenderType, Signal, Receiver, ReceiverType, Method)
Connect Signal of Sender to Method of Receiver.
T qmlobject_cast(QObject *object)
This method is identical to qobject_cast<T>() except that it does not require lazy QMetaObjects to be...
QQuickItem * qmlobject_cast< QQuickItem * >(QObject *object)
Q_QML_EXPORT QQmlInfo qmlWarning(const QObject *me)
#define PRINT_LISTENERS()
QDebug operator<<(QDebug debug, const QQuickItem *item)
static bool itemZOrder_sort(QQuickItem *lhs, QQuickItem *rhs)
#define DIRTY_TO_STRING(value)
void debugFocusTree(QQuickItem *item, QQuickItem *scope=nullptr, int depth=1)
const SigMap sigMap[]
static QT_BEGIN_NAMESPACE const quint64 kCursorOverrideTimeout
QQuickItem * qobject_cast< QQuickItem * >(QObject *o)
Definition qquickitem.h:483
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
#define QStringLiteral(str)
#define QT_CONFIG(feature)
#define tr(X)
#define emit
#define Q_UNUSED(x)
#define QT_VERSION_CHECK(major, minor, patch)
#define QT_VERSION
unsigned int quint32
Definition qtypes.h:45
unsigned long long quint64
Definition qtypes.h:56
ptrdiff_t qsizetype
Definition qtypes.h:70
unsigned int uint
Definition qtypes.h:29
double qreal
Definition qtypes.h:92
#define DEFINE_OBJECT_VTABLE(classname)
#define V4_OBJECT2(DataClass, superClass)
bool testFlag(MaskType mask, FlagType flag)
const char property[13]
Definition qwizard.cpp:101
if(qFloatDistance(a, b)<(1<< 7))
[0]
QDataStream & operator<<(QDataStream &out, const MyClass &myObj)
[4]
obj metaObject() -> className()
QObject::connect nullptr
QSharedPointer< T > other(t)
[5]
QString dir
[11]
rect sceneTransform().map(QPointF(0
QGraphicsItem * item
view viewport() -> scroll(dx, dy, deviceRect)
edit hide()
QLayoutItem * child
[0]
aWidget window() -> setWindowTitle("New Window Title")
[2]
QJSValueList args
QJSEngine engine
[0]
\inmodule QtCore \reentrant
Definition qchar.h:17
qsizetype indexOf(const AT &t, qsizetype from=0) const noexcept
Definition qlist.h:955
bool contains(const AT &t) const noexcept
Definition qlist.h:44
qsizetype lastIndexOf(const AT &t, qsizetype from=-1) const noexcept
Definition qlist.h:962
QQuickItemChangeListener * listener
QV4::ReturnedValue fromVariant(const QVariant &)
ReturnedValue throwTypeError()
static void markObjects(QV4::Heap::Base *that, QV4::MarkStack *markStack)
static void markWrapper(QObject *object, MarkStack *markStack)
const char * sig
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent
\inmodule QtQuick
Definition qquickitem.h:158