1// Copyright (C) 2016 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#ifndef QQUICKITEM_P_H
5#define QQUICKITEM_P_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists purely as an
12// implementation detail. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include <QtQuick/private/qquickanchors_p.h>
19#include <QtQuick/private/qquickanchors_p_p.h>
20#include <QtQuick/private/qquickitemchangelistener_p.h>
21#include <QtQuick/private/qquickevents_p_p.h>
22#include <QtQuick/private/qquickclipnode_p.h>
23#include <QtQuick/private/qquickstate_p.h>
24#include <QtQuick/private/qquickpaletteproviderprivatebase_p.h>
25#include <QtQuick/private/qquickwindow_p.h>
26#include <QtCore/private/qproperty_p.h>
27
28#if QT_CONFIG(quick_shadereffect)
29#include <QtQuick/private/qquickshadereffectsource_p.h>
30#endif
31
32#include <QtQuick/qquickitem.h>
33#include <QtQuick/qsgnode.h>
34
35#include <QtQml/private/qqmlnullablevalue_p.h>
36#include <QtQml/private/qqmlnotifier_p.h>
37#include <QtQml/private/qqmlglobal_p.h>
38#include <QtQml/private/qlazilyallocated_p.h>
39#include <QtQml/qqml.h>
40#include <QtQml/qqmlcontext.h>
41
42#include <QtCore/qlist.h>
43#include <QtCore/qdebug.h>
44#include <QtCore/qelapsedtimer.h>
45#include <QtCore/qpointer.h>
46
47#include <QtGui/private/qlayoutpolicy_p.h>
48#if QT_CONFIG(accessibility)
49#include <QtGui/qaccessible_base.h>
50#endif
51
52QT_BEGIN_NAMESPACE
53
54Q_DECLARE_LOGGING_CATEGORY(lcHandlerParent)
55Q_DECLARE_LOGGING_CATEGORY(lcVP)
56
57class QNetworkReply;
58class QQuickItemKeyFilter;
59class QQuickLayoutMirroringAttached;
60class QQuickEnterKeyAttached;
61class QQuickScreenAttached;
62class QQuickPointerHandler;
63
64class QQuickContents : public QSafeQuickItemChangeListener<QQuickContents>
65{
66 Q_DISABLE_COPY(QQuickContents)
67public:
68 QQuickContents(QQuickItem *item);
69 ~QQuickContents() override;
70
71 QRectF rectF() const { return m_contents; }
72
73 inline void calcGeometry(QQuickItem *changed = nullptr);
74 void complete();
75
76 bool inDestructor = false;
77
78protected:
79 void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &) override;
80 void itemDestroyed(QQuickItem *item) override;
81 void itemChildAdded(QQuickItem *, QQuickItem *) override;
82 void itemChildRemoved(QQuickItem *, QQuickItem *) override;
83 //void itemVisibilityChanged(QQuickItem *item)
84
85private:
86 bool calcHeight(QQuickItem *changed = nullptr);
87 bool calcWidth(QQuickItem *changed = nullptr);
88 void updateRect();
89
90 QQuickItem *m_item;
91 QRectF m_contents;
92};
93
94void QQuickContents::calcGeometry(QQuickItem *changed)
95{
96 bool wChanged = calcWidth(changed);
97 bool hChanged = calcHeight(changed);
98 if (wChanged || hChanged)
99 updateRect();
100}
101
102class QQuickTransformPrivate : public QObjectPrivate
103{
104 Q_DECLARE_PUBLIC(QQuickTransform)
105public:
106 static QQuickTransformPrivate* get(QQuickTransform *transform) { return transform->d_func(); }
107
108 QQuickTransformPrivate();
109
110 QList<QQuickItem *> items;
111};
112
113#if QT_CONFIG(quick_shadereffect)
114
115class Q_QUICK_EXPORT QQuickItemLayer : public QObject,
116 public QSafeQuickItemChangeListener<QQuickItemLayer>
117{
118 Q_OBJECT
119 Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged FINAL)
120 Q_PROPERTY(QSize textureSize READ size WRITE setSize NOTIFY sizeChanged FINAL)
121 Q_PROPERTY(QRectF sourceRect READ sourceRect WRITE setSourceRect NOTIFY sourceRectChanged FINAL)
122 Q_PROPERTY(bool mipmap READ mipmap WRITE setMipmap NOTIFY mipmapChanged FINAL)
123 Q_PROPERTY(bool smooth READ smooth WRITE setSmooth NOTIFY smoothChanged FINAL)
124 Q_PROPERTY(bool live READ live WRITE setLive NOTIFY liveChanged REVISION(6, 5) FINAL)
125 Q_PROPERTY(QQuickShaderEffectSource::WrapMode wrapMode READ wrapMode WRITE setWrapMode NOTIFY wrapModeChanged FINAL)
126 Q_PROPERTY(QQuickShaderEffectSource::Format format READ format WRITE setFormat NOTIFY formatChanged FINAL)
127 Q_PROPERTY(QByteArray samplerName READ name WRITE setName NOTIFY nameChanged FINAL)
128 Q_PROPERTY(QQmlComponent *effect READ effect WRITE setEffect NOTIFY effectChanged FINAL)
129 Q_PROPERTY(QQuickShaderEffectSource::TextureMirroring textureMirroring READ textureMirroring WRITE setTextureMirroring NOTIFY textureMirroringChanged FINAL)
130 Q_PROPERTY(int samples READ samples WRITE setSamples NOTIFY samplesChanged FINAL)
131 QML_ANONYMOUS
132 QML_ADDED_IN_VERSION(2, 0)
133
134public:
135 QQuickItemLayer(QQuickItem *item);
136 ~QQuickItemLayer() override;
137
138 void classBegin();
139 void componentComplete();
140
141 bool enabled() const { return m_enabled; }
142 void setEnabled(bool enabled);
143
144 bool mipmap() const { return m_mipmap; }
145 void setMipmap(bool mipmap);
146
147 bool smooth() const { return m_smooth; }
148 void setSmooth(bool s);
149
150 bool live() const { return m_live; }
151 void setLive(bool live);
152
153 QSize size() const { return m_size; }
154 void setSize(const QSize &size);
155
156 QQuickShaderEffectSource::Format format() const { return m_format; }
157 void setFormat(QQuickShaderEffectSource::Format f);
158
159 QRectF sourceRect() const { return m_sourceRect; }
160 void setSourceRect(const QRectF &sourceRect);
161
162 QQuickShaderEffectSource::WrapMode wrapMode() const { return m_wrapMode; }
163 void setWrapMode(QQuickShaderEffectSource::WrapMode mode);
164
165 QByteArray name() const { return m_name; }
166 void setName(const QByteArray &name);
167
168 QQmlComponent *effect() const { return m_effectComponent; }
169 void setEffect(QQmlComponent *effect);
170
171 QQuickShaderEffectSource::TextureMirroring textureMirroring() const { return m_textureMirroring; }
172 void setTextureMirroring(QQuickShaderEffectSource::TextureMirroring mirroring);
173
174 int samples() const { return m_samples; }
175 void setSamples(int count);
176
177 QQuickShaderEffectSource *effectSource() const { return m_effectSource; }
178
179 void itemGeometryChanged(QQuickItem *, QQuickGeometryChange, const QRectF &) override;
180 void itemOpacityChanged(QQuickItem *) override;
181 void itemParentChanged(QQuickItem *, QQuickItem *) override;
182 void itemSiblingOrderChanged(QQuickItem *) override;
183 void itemVisibilityChanged(QQuickItem *) override;
184
185 void updateMatrix();
186 void updateGeometry();
187 void updateOpacity();
188 void updateZ();
189
190Q_SIGNALS:
191 void enabledChanged(bool enabled);
192 void sizeChanged(const QSize &size);
193 void mipmapChanged(bool mipmap);
194 void wrapModeChanged(QQuickShaderEffectSource::WrapMode mode);
195 void nameChanged(const QByteArray &name);
196 void effectChanged(QQmlComponent *component);
197 void smoothChanged(bool smooth);
198 void liveChanged(bool live);
199 void formatChanged(QQuickShaderEffectSource::Format format);
200 void sourceRectChanged(const QRectF &sourceRect);
201 void textureMirroringChanged(QQuickShaderEffectSource::TextureMirroring mirroring);
202 void samplesChanged(int count);
203
204private:
205 friend class QQuickTransformAnimatorJob;
206 friend class QQuickOpacityAnimatorJob;
207
208 void activate();
209 void deactivate();
210 void activateEffect();
211 void deactivateEffect();
212
213 QQuickItem *m_item;
214 bool m_enabled;
215 bool m_mipmap;
216 bool m_smooth;
217 bool m_live;
218 bool m_componentComplete;
219 QQuickShaderEffectSource::WrapMode m_wrapMode;
220 QQuickShaderEffectSource::Format m_format;
221 QSize m_size;
222 QRectF m_sourceRect;
223 QByteArray m_name;
224 QQmlComponent *m_effectComponent;
225 QQuickItem *m_effect;
226 QQuickShaderEffectSource *m_effectSource;
227 QQuickShaderEffectSource::TextureMirroring m_textureMirroring;
228 int m_samples;
229};
230
231#endif
232
233class Q_QUICK_EXPORT QQuickItemPrivate
234 : public QObjectPrivate
235 , public QQuickPaletteProviderPrivateBase<QQuickItem, QQuickItemPrivate>
236{
237 Q_DECLARE_PUBLIC(QQuickItem)
238
239public:
240 static QQuickItemPrivate* get(QQuickItem *item) { return item->d_func(); }
241 static const QQuickItemPrivate* get(const QQuickItem *item) { return item->d_func(); }
242
243 QQuickItemPrivate();
244 ~QQuickItemPrivate() override;
245 void init(QQuickItem *parent);
246
247 QQmlListProperty<QObject> data();
248 QQmlListProperty<QObject> resources();
249 QQmlListProperty<QQuickItem> children();
250 QQmlListProperty<QQuickItem> visibleChildren();
251
252 QQmlListProperty<QQuickState> states();
253 QQmlListProperty<QQuickTransition> transitions();
254
255 QString state() const;
256 void setState(const QString &);
257
258 QQuickAnchorLine left() const;
259 QQuickAnchorLine right() const;
260 QQuickAnchorLine horizontalCenter() const;
261 QQuickAnchorLine top() const;
262 QQuickAnchorLine bottom() const;
263 QQuickAnchorLine verticalCenter() const;
264 QQuickAnchorLine baseline() const;
265
266#if QT_CONFIG(quick_shadereffect)
267 QQuickItemLayer *layer() const;
268#endif
269
270 void localizedTouchEvent(const QTouchEvent *event, bool isFiltering, QMutableTouchEvent *localized);
271 bool hasPointerHandlers() const;
272 bool hasEnabledHoverHandlers() const;
273 virtual void addPointerHandler(QQuickPointerHandler *h);
274 virtual void removePointerHandler(QQuickPointerHandler *h);
275
276 QObject *setContextMenu(QObject *menu);
277
278 // data property
279 static void data_append(QQmlListProperty<QObject> *, QObject *);
280 static qsizetype data_count(QQmlListProperty<QObject> *);
281 static QObject *data_at(QQmlListProperty<QObject> *, qsizetype);
282 static void data_clear(QQmlListProperty<QObject> *);
283 static void data_removeLast(QQmlListProperty<QObject> *);
284
285 // resources property
286 static QObject *resources_at(QQmlListProperty<QObject> *, qsizetype);
287 static void resources_append(QQmlListProperty<QObject> *, QObject *);
288 static qsizetype resources_count(QQmlListProperty<QObject> *);
289 static void resources_clear(QQmlListProperty<QObject> *);
290 static void resources_removeLast(QQmlListProperty<QObject> *);
291
292 // children property
293 static void children_append(QQmlListProperty<QQuickItem> *, QQuickItem *);
294 static qsizetype children_count(QQmlListProperty<QQuickItem> *);
295 static QQuickItem *children_at(QQmlListProperty<QQuickItem> *, qsizetype);
296 static void children_clear(QQmlListProperty<QQuickItem> *);
297 static void children_removeLast(QQmlListProperty<QQuickItem> *);
298
299 // visibleChildren property
300 static qsizetype visibleChildren_count(QQmlListProperty<QQuickItem> *prop);
301 static QQuickItem *visibleChildren_at(QQmlListProperty<QQuickItem> *prop, qsizetype index);
302
303 // transform property
304 static qsizetype transform_count(QQmlListProperty<QQuickTransform> *list);
305 static void transform_append(QQmlListProperty<QQuickTransform> *list, QQuickTransform *);
306 static QQuickTransform *transform_at(QQmlListProperty<QQuickTransform> *list, qsizetype);
307 static void transform_clear(QQmlListProperty<QQuickTransform> *list);
308
309 void _q_resourceObjectDeleted(QObject *);
310 quint64 _q_createJSWrapper(QQmlV4ExecutionEnginePtr engine);
311
312 enum ChangeType {
313 Geometry = 0x01,
314 SiblingOrder = 0x02,
315 Visibility = 0x04,
316 Opacity = 0x08,
317 Destroyed = 0x10,
318 Parent = 0x20,
319 Children = 0x40,
320 Rotation = 0x80,
321 ImplicitWidth = 0x100,
322 ImplicitHeight = 0x200,
323 Enabled = 0x400,
324 Focus = 0x800,
325 Scale = 0x1000,
326 Matrix = 0x2000,
327 AllChanges = 0xFFFFFFFF
328 };
329
330 Q_DECLARE_FLAGS(ChangeTypes, ChangeType)
331 friend inline QDebug &operator<<(QDebug &dbg, QQuickItemPrivate::ChangeTypes types) {
332#define CHANGETYPE_OUTPUT(Type) if (types & QQuickItemPrivate::Type) { dbg << first << #Type ; first = '|'; }
333 QDebugStateSaver state(dbg);
334 dbg.noquote().nospace();
335 if (types == QQuickItemPrivate::AllChanges) {
336 dbg << " AllChanges";
337 } else {
338 char first = ' ';
339 CHANGETYPE_OUTPUT(Geometry);
340 CHANGETYPE_OUTPUT(SiblingOrder);
341 CHANGETYPE_OUTPUT(Visibility);
342 CHANGETYPE_OUTPUT(Opacity);
343 CHANGETYPE_OUTPUT(Destroyed);
344 CHANGETYPE_OUTPUT(Parent);
345 CHANGETYPE_OUTPUT(Children);
346 CHANGETYPE_OUTPUT(Rotation);
347 CHANGETYPE_OUTPUT(ImplicitWidth);
348 CHANGETYPE_OUTPUT(ImplicitHeight);
349 CHANGETYPE_OUTPUT(Enabled);
350 CHANGETYPE_OUTPUT(Focus);
351 CHANGETYPE_OUTPUT(Scale);
352 CHANGETYPE_OUTPUT(Matrix);
353#undef CHANGETYPE_OUTPUT
354 }
355 return dbg;
356 }
357
358 struct ChangeListener {
359 using ChangeTypes = QQuickItemPrivate::ChangeTypes;
360
361 ChangeListener(QQuickItemChangeListener *l = nullptr, ChangeTypes t = { })
362 : listener(l)
363 , types(t)
364 , gTypes(QQuickGeometryChange::All)
365 {}
366
367 ChangeListener(QQuickItemChangeListener *l, QQuickGeometryChange gt)
368 : listener(l)
369 , types(Geometry)
370 , gTypes(gt)
371 {}
372
373 bool operator==(const ChangeListener &other) const
374 { return listener == other.listener && types == other.types; }
375
376 QQuickItemChangeListener *listener;
377 ChangeTypes types;
378 QQuickGeometryChange gTypes; //NOTE: not used for ==
379
380#ifndef QT_NO_DEBUG_STREAM
381 private:
382 friend QDebug operator<<(QDebug debug, const QQuickItemPrivate::ChangeListener &listener);
383#endif // QT_NO_DEBUG_STREAM
384 };
385
386 // call QQuickItemChangeListener
387 template <typename Fn, typename ...Args>
388 void notifyChangeListeners(QQuickItemPrivate::ChangeTypes changeTypes, Fn &&function, Args &&...args)
389 {
390 Q_Q(QQuickItem);
391 if (changeListeners.isEmpty())
392 return;
393
394 const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732)
395 for (const QQuickItemPrivate::ChangeListener &change : listeners) {
396 Q_ASSERT(change.listener);
397 if (change.types & changeTypes) {
398#ifdef QT_BUILD_INTERNAL
399 if (changeTypes == AllChanges && change.listener->anchorPrivate() == nullptr) {
400 // Nothing to worry about as long as the lambdas in ~QQuickItem
401 // don't mess around with the change.listener directly!
402 } else if (change.listener->baseDeleted(caller: q)) {
403 auto output = qCritical();
404 output.noquote();
405 output << "Listener already tagged as destroyed when called!"
406 << "\n\tListener:" << change.listener->debugName()
407 << "\n\tChanges:" << change.types
408 << "\n\tCaller: " << q
409 << "\n\tChanges:" << changeTypes;
410 }
411#endif
412 if constexpr (std::is_member_function_pointer_v<Fn>)
413 (change.listener->*function)(args...);
414 else
415 function(change, args...);
416 }
417 if (changeTypes & QQuickItemPrivate::Destroyed)
418 change.listener->removeSourceItem(q);
419 }
420 }
421
422 struct ExtraData {
423 Q_QUICK_EXPORT ExtraData();
424
425 qreal z;
426 qreal scale;
427 qreal rotation;
428 qreal opacity;
429
430 QQuickContents *contents;
431 QQuickScreenAttached *screenAttached;
432 QQuickLayoutMirroringAttached* layoutDirectionAttached;
433 QQuickEnterKeyAttached *enterKeyAttached;
434 QQuickItemKeyFilter *keyHandler;
435 QVector<QQuickPointerHandler *> pointerHandlers;
436 QObject *contextMenu;
437#if QT_CONFIG(quick_shadereffect)
438 mutable QQuickItemLayer *layer;
439#endif
440#if QT_CONFIG(cursor)
441 QCursor cursor;
442#endif
443 QPointF userTransformOriginPoint;
444
445 // these do not include child items
446 int effectRefCount;
447 int hideRefCount;
448 // updated recursively for child items as well
449 int recursiveEffectRefCount;
450 // Mask contains() method index
451 int maskContainsIndex;
452
453 // Contains mask
454 QPointer<QObject> mask;
455
456 QSGOpacityNode *opacityNode;
457 QQuickDefaultClipNode *clipNode;
458 QSGRootNode *rootNode;
459 // subsceneDeliveryAgent is set only if this item is the root of a subscene, not on all items within.
460 QQuickDeliveryAgent *subsceneDeliveryAgent = nullptr;
461
462 QObjectList resourcesList;
463
464 // Although acceptedMouseButtons is inside ExtraData, we actually store
465 // the LeftButton flag in the extra.tag() bit. This is because it is
466 // extremely common to set acceptedMouseButtons to LeftButton, but very
467 // rare to use any of the other buttons.
468 Qt::MouseButtons acceptedMouseButtons;
469 Qt::MouseButtons acceptedMouseButtonsWithoutHandlers;
470
471 uint origin:5; // QQuickItem::TransformOrigin
472 uint transparentForPositioner : 1;
473
474 // 26 bits padding
475 };
476
477 enum ExtraDataTag {
478 NoTag = 0x1,
479 LeftMouseButtonAccepted = 0x2
480 };
481 Q_DECLARE_FLAGS(ExtraDataTags, ExtraDataTag)
482
483 QLazilyAllocated<ExtraData, ExtraDataTags> extra;
484 // If the mask is an Item, inform it that it's being used as a mask (true) or is no longer being used (false)
485 virtual void registerAsContainmentMask(QQuickItem * /* maskedItem */, bool /* set */) { }
486
487 QQuickAnchors *anchors() const;
488 mutable QQuickAnchors *_anchors;
489
490 inline Qt::MouseButtons acceptedMouseButtons() const;
491
492 QVector<QQuickItemPrivate::ChangeListener> changeListeners;
493
494 void addItemChangeListener(QQuickItemChangeListener *listener, ChangeTypes types);
495 void updateOrAddItemChangeListener(QQuickItemChangeListener *listener, ChangeTypes types);
496 void removeItemChangeListener(QQuickItemChangeListener *, ChangeTypes types);
497 void updateOrAddGeometryChangeListener(QQuickItemChangeListener *listener, QQuickGeometryChange types);
498 void updateOrRemoveGeometryChangeListener(QQuickItemChangeListener *listener, QQuickGeometryChange types);
499
500 QQuickStateGroup *_states();
501 QQuickStateGroup *_stateGroup;
502
503 inline QQuickItem::TransformOrigin origin() const;
504
505 // Bit 0
506 quint32 flags:7;
507 quint32 widthValidFlag:1;
508 quint32 heightValidFlag:1;
509 quint32 componentComplete:1;
510 quint32 keepMouse:1;
511 quint32 keepTouch:1;
512 quint32 hoverEnabled:1;
513 quint32 smooth:1;
514 quint32 antialiasing:1;
515 quint32 focus:1;
516 // Bit 16
517 quint32 activeFocus:1;
518 quint32 notifiedFocus:1;
519 quint32 notifiedActiveFocus:1;
520 quint32 filtersChildMouseEvents:1;
521 quint32 explicitVisible:1;
522 quint32 effectiveVisible:1;
523 quint32 explicitEnable:1;
524 quint32 effectiveEnable:1;
525 quint32 polishScheduled:1;
526 quint32 inheritedLayoutMirror:1;
527 quint32 effectiveLayoutMirror:1;
528 quint32 isMirrorImplicit:1;
529 quint32 inheritMirrorFromParent:1;
530 quint32 inheritMirrorFromItem:1;
531 quint32 isAccessible:1;
532 quint32 culled:1;
533 // Bit 32
534 quint32 hasCursor:1;
535 quint32 subtreeCursorEnabled:1;
536 quint32 subtreeHoverEnabled:1;
537 quint32 activeFocusOnTab:1;
538 quint32 implicitAntialiasing:1;
539 quint32 antialiasingValid:1;
540 // isTabFence: When true, the item acts as a fence within the tab focus chain.
541 // This means that the item and its children will be skipped from the tab focus
542 // chain when navigating from its parent or any of its siblings. Similarly,
543 // when any of the item's descendants gets focus, the item constrains the tab
544 // focus chain and prevents tabbing outside.
545 quint32 isTabFence:1;
546 quint32 replayingPressEvent:1;
547 // Bit 40
548 quint32 touchEnabled:1;
549 quint32 hasCursorHandler:1;
550 // set true when this item does not expect events via a subscene delivery agent; false otherwise
551 quint32 maybeHasSubsceneDeliveryAgent:1;
552 // set true if this item or any child wants QQuickItemPrivate::transformChanged() to visit all children
553 // (e.g. when parent has ItemIsViewport and child has ItemObservesViewport)
554 quint32 subtreeTransformChangedEnabled:1;
555 quint32 inDestructor:1; // has entered ~QQuickItem
556 quint32 focusReason:4;
557 quint32 focusPolicy:4;
558 // Bit 53
559
560 enum DirtyType {
561 TransformOrigin = 0x00000001,
562 Transform = 0x00000002,
563 BasicTransform = 0x00000004,
564 Position = 0x00000008,
565 Size = 0x00000010,
566
567 ZValue = 0x00000020,
568 Content = 0x00000040,
569 Smooth = 0x00000080,
570 OpacityValue = 0x00000100,
571 ChildrenChanged = 0x00000200,
572 ChildrenStackingChanged = 0x00000400,
573 ParentChanged = 0x00000800,
574
575 Clip = 0x00001000,
576 Window = 0x00002000,
577
578 EffectReference = 0x00008000,
579 Visible = 0x00010000,
580 HideReference = 0x00020000,
581 Antialiasing = 0x00040000,
582 // When you add an attribute here, don't forget to update
583 // dirtyToString()
584
585 TransformUpdateMask = TransformOrigin | Transform | BasicTransform | Position |
586 Window,
587 ComplexTransformUpdateMask = Transform | Window,
588 ContentUpdateMask = Size | Content | Smooth | Window | Antialiasing,
589 ChildrenUpdateMask = ChildrenChanged | ChildrenStackingChanged | EffectReference | Window
590 };
591
592 quint32 dirtyAttributes;
593 QString dirtyToString() const;
594 void dirty(DirtyType);
595 void addToDirtyList();
596 void removeFromDirtyList();
597 QQuickItem *nextDirtyItem;
598 QQuickItem**prevDirtyItem;
599
600 void setCulled(bool);
601
602 QQuickWindow *window;
603 int windowRefCount;
604 inline QSGContext *sceneGraphContext() const;
605 inline QSGRenderContext *sceneGraphRenderContext() const;
606
607 QQuickItem *parentItem;
608
609 QList<QQuickItem *> childItems;
610 mutable QList<QQuickItem *> *sortedChildItems;
611 QList<QQuickItem *> paintOrderChildItems() const;
612 void addChild(QQuickItem *);
613 void removeChild(QQuickItem *);
614 void siblingOrderChanged();
615
616 inline void markSortedChildrenDirty(QQuickItem *child);
617
618 void refWindow(QQuickWindow *);
619 void derefWindow();
620
621 qreal effectiveDevicePixelRatio() const;
622
623 QPointer<QQuickItem> subFocusItem;
624 void updateSubFocusItem(QQuickItem *scope, bool focus);
625
626 bool setFocusIfNeeded(QEvent::Type);
627 Qt::FocusReason lastFocusChangeReason() const;
628 virtual bool setLastFocusChangeReason(Qt::FocusReason reason);
629
630 QTransform windowToItemTransform() const;
631 QTransform itemToWindowTransform() const;
632 void itemToParentTransform(QTransform *) const;
633
634 static bool focusNextPrev(QQuickItem *item, bool forward);
635 static QQuickItem *nextTabChildItem(const QQuickItem *item, int start);
636 static QQuickItem *prevTabChildItem(const QQuickItem *item, int start);
637 static QQuickItem *nextPrevItemInTabFocusChain(QQuickItem *item, bool forward, bool wrap = true);
638
639 static bool canAcceptTabFocus(QQuickItem *item);
640
641 void setX(qreal x) {q_func()->setX(x);}
642 void xChanged() { Q_EMIT q_func()->xChanged(); }
643 Q_OBJECT_COMPAT_PROPERTY(QQuickItemPrivate, qreal, x, &QQuickItemPrivate::setX, &QQuickItemPrivate::xChanged);
644 void setY(qreal y) {q_func()->setY(y);}
645 void yChanged() { Q_EMIT q_func()->yChanged(); }
646 Q_OBJECT_COMPAT_PROPERTY(QQuickItemPrivate, qreal, y, &QQuickItemPrivate::setY, &QQuickItemPrivate::yChanged);
647 void setWidth(qreal width) {q_func()->setWidth(width);}
648 void widthChanged() { Q_EMIT q_func()->widthChanged(); }
649 Q_OBJECT_COMPAT_PROPERTY(QQuickItemPrivate, qreal, width, &QQuickItemPrivate::setWidth, &QQuickItemPrivate::widthChanged);
650 void setHeight(qreal height) {q_func()->setHeight(height);}
651 void heightChanged() { Q_EMIT q_func()->heightChanged(); }
652 Q_OBJECT_COMPAT_PROPERTY(QQuickItemPrivate, qreal, height, &QQuickItemPrivate::setHeight, &QQuickItemPrivate::heightChanged);
653 qreal implicitWidth;
654 qreal implicitHeight;
655
656 bool widthValid() const { return widthValidFlag || (width.hasBinding() && !QQmlPropertyBinding::isUndefined(binding: width.binding()) ); }
657 bool heightValid() const { return heightValidFlag || (height.hasBinding() && !QQmlPropertyBinding::isUndefined(binding: height.binding()) ); }
658
659 qreal baselineOffset;
660
661 QList<QQuickTransform *> transforms;
662
663 inline qreal z() const { return extra.isAllocated()?extra->z:0; }
664 inline qreal scale() const { return extra.isAllocated()?extra->scale:1; }
665 inline qreal rotation() const { return extra.isAllocated()?extra->rotation:0; }
666 inline qreal opacity() const { return extra.isAllocated()?extra->opacity:1; }
667
668 void setAccessible();
669
670 virtual qreal getImplicitWidth() const;
671 virtual qreal getImplicitHeight() const;
672 virtual void implicitWidthChanged();
673 virtual void implicitHeightChanged();
674
675#if QT_CONFIG(accessibility)
676 QAccessible::Role effectiveAccessibleRole() const;
677private:
678 virtual QAccessible::Role accessibleRole() const;
679public:
680#endif
681
682 void setImplicitAntialiasing(bool antialiasing);
683
684 void resolveLayoutMirror();
685 void setImplicitLayoutMirror(bool mirror, bool inherit);
686 void setLayoutMirror(bool mirror);
687 bool isMirrored() const {
688 return effectiveLayoutMirror;
689 }
690
691 void emitChildrenRectChanged(const QRectF &rect) {
692 Q_Q(QQuickItem);
693 Q_EMIT q->childrenRectChanged(rect);
694 }
695
696 QPointF computeTransformOrigin() const;
697 virtual bool transformChanged(QQuickItem *transformedItem);
698
699 QPointF adjustedPosForTransform(const QPointF &centroid,
700 const QPointF &startPos, const QVector2D &activeTranslatation,
701 qreal startScale, qreal activeScale,
702 qreal startRotation, qreal activeRotation);
703
704 QQuickDeliveryAgent *deliveryAgent();
705 QQuickDeliveryAgentPrivate *deliveryAgentPrivate();
706 QQuickDeliveryAgent *ensureSubsceneDeliveryAgent();
707
708 void deliverKeyEvent(QKeyEvent *);
709 bool filterKeyEvent(QKeyEvent *, bool post);
710#if QT_CONFIG(im)
711 void deliverInputMethodEvent(QInputMethodEvent *);
712#endif
713 void deliverShortcutOverrideEvent(QKeyEvent *);
714
715 void deliverPointerEvent(QEvent *);
716
717 bool anyPointerHandlerWants(const QPointerEvent *event, const QEventPoint &point) const;
718 virtual bool handlePointerEvent(QPointerEvent *, bool avoidGrabbers = false);
719#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
720 virtual bool handleContextMenuEvent(QContextMenuEvent *event);
721#endif
722
723 virtual void setVisible(bool visible);
724
725 bool isTransparentForPositioner() const;
726 void setTransparentForPositioner(bool trans);
727
728 bool calcEffectiveVisible() const;
729 bool setEffectiveVisibleRecur(bool);
730 bool calcEffectiveEnable() const;
731 void setEffectiveEnableRecur(QQuickItem *scope, bool);
732
733
734 inline QSGTransformNode *itemNode();
735 inline QSGNode *childContainerNode();
736
737 /*
738 QSGNode order is:
739 - itemNode
740 - (opacityNode)
741 - (clipNode)
742 - (rootNode) (shader effect source's root node)
743 */
744
745 QSGOpacityNode *opacityNode() const { return extra.isAllocated()?extra->opacityNode:nullptr; }
746 QQuickDefaultClipNode *clipNode() const { return extra.isAllocated()?extra->clipNode:nullptr; }
747 QSGRootNode *rootNode() const { return extra.isAllocated()?extra->rootNode:nullptr; }
748
749 QSGTransformNode *itemNodeInstance;
750 QSGNode *paintNode;
751
752 virtual QSGTransformNode *createTransformNode();
753
754 // A reference from an effect item means that this item is used by the effect, so
755 // it should insert a root node.
756 void refFromEffectItem(bool hide);
757 void recursiveRefFromEffectItem(int refs);
758 void derefFromEffectItem(bool unhide);
759
760 void itemChange(QQuickItem::ItemChange, const QQuickItem::ItemChangeData &);
761
762 void enableSubtreeChangeNotificationsForParentHierachy();
763
764 virtual void mirrorChange() {}
765
766 void setHasCursorInChild(bool hasCursor);
767 void setHasHoverInChild(bool hasHover);
768#if QT_CONFIG(cursor)
769 QCursor effectiveCursor(const QQuickPointerHandler *handler) const;
770 QQuickPointerHandler *effectiveCursorHandler() const;
771#endif
772
773 virtual void updatePolish() { }
774 virtual void dumpItemTree(int indent) const;
775
776 QLayoutPolicy sizePolicy() const;
777 void setSizePolicy(const QLayoutPolicy::Policy &horizontalPolicy, const QLayoutPolicy::Policy &verticalPolicy);
778 QLayoutPolicy szPolicy;
779};
780
781Q_DECLARE_OPERATORS_FOR_FLAGS(QQuickItemPrivate::ExtraDataTags)
782
783/*
784 Key filters can be installed on a QQuickItem, but not removed. Currently they
785 are only used by attached objects (which are only destroyed on Item
786 destruction), so this isn't a problem. If in future this becomes any form
787 of public API, they will have to support removal too.
788*/
789class QQuickItemKeyFilter
790{
791public:
792 QQuickItemKeyFilter(QQuickItem * = nullptr);
793 virtual ~QQuickItemKeyFilter();
794
795 virtual void keyPressed(QKeyEvent *event, bool post);
796 virtual void keyReleased(QKeyEvent *event, bool post);
797#if QT_CONFIG(im)
798 virtual void inputMethodEvent(QInputMethodEvent *event, bool post);
799 virtual QVariant inputMethodQuery(Qt::InputMethodQuery query) const;
800#endif
801 virtual void shortcutOverrideEvent(QKeyEvent *event);
802 virtual void componentComplete();
803
804 bool m_processPost;
805
806private:
807 QQuickItemKeyFilter *m_next;
808};
809
810class QQuickKeyNavigationAttachedPrivate : public QObjectPrivate
811{
812public:
813 QQuickKeyNavigationAttachedPrivate()
814 : leftSet(false), rightSet(false), upSet(false), downSet(false),
815 tabSet(false), backtabSet(false) {}
816
817 QPointer<QQuickItem> left;
818 QPointer<QQuickItem> right;
819 QPointer<QQuickItem> up;
820 QPointer<QQuickItem> down;
821 QPointer<QQuickItem> tab;
822 QPointer<QQuickItem> backtab;
823 bool leftSet : 1;
824 bool rightSet : 1;
825 bool upSet : 1;
826 bool downSet : 1;
827 bool tabSet : 1;
828 bool backtabSet : 1;
829};
830
831class Q_QUICK_EXPORT QQuickKeyNavigationAttached : public QObject, public QQuickItemKeyFilter
832{
833 Q_OBJECT
834 Q_DECLARE_PRIVATE(QQuickKeyNavigationAttached)
835
836 Q_PROPERTY(QQuickItem *left READ left WRITE setLeft NOTIFY leftChanged FINAL)
837 Q_PROPERTY(QQuickItem *right READ right WRITE setRight NOTIFY rightChanged FINAL)
838 Q_PROPERTY(QQuickItem *up READ up WRITE setUp NOTIFY upChanged FINAL)
839 Q_PROPERTY(QQuickItem *down READ down WRITE setDown NOTIFY downChanged FINAL)
840 Q_PROPERTY(QQuickItem *tab READ tab WRITE setTab NOTIFY tabChanged FINAL)
841 Q_PROPERTY(QQuickItem *backtab READ backtab WRITE setBacktab NOTIFY backtabChanged FINAL)
842 Q_PROPERTY(Priority priority READ priority WRITE setPriority NOTIFY priorityChanged FINAL)
843
844 QML_NAMED_ELEMENT(KeyNavigation)
845 QML_ADDED_IN_VERSION(2, 0)
846 QML_UNCREATABLE("KeyNavigation is only available via attached properties.")
847 QML_ATTACHED(QQuickKeyNavigationAttached)
848
849public:
850 QQuickKeyNavigationAttached(QObject * = nullptr);
851
852 QQuickItem *left() const;
853 void setLeft(QQuickItem *);
854 QQuickItem *right() const;
855 void setRight(QQuickItem *);
856 QQuickItem *up() const;
857 void setUp(QQuickItem *);
858 QQuickItem *down() const;
859 void setDown(QQuickItem *);
860 QQuickItem *tab() const;
861 void setTab(QQuickItem *);
862 QQuickItem *backtab() const;
863 void setBacktab(QQuickItem *);
864
865 enum Priority { BeforeItem, AfterItem };
866 Q_ENUM(Priority)
867 Priority priority() const;
868 void setPriority(Priority);
869
870 static QQuickKeyNavigationAttached *qmlAttachedProperties(QObject *);
871
872Q_SIGNALS:
873 void leftChanged();
874 void rightChanged();
875 void upChanged();
876 void downChanged();
877 void tabChanged();
878 void backtabChanged();
879 void priorityChanged();
880
881private:
882 void keyPressed(QKeyEvent *event, bool post) override;
883 void keyReleased(QKeyEvent *event, bool post) override;
884 void setFocusNavigation(QQuickItem *currentItem, const char *dir,
885 Qt::FocusReason reason = Qt::OtherFocusReason);
886};
887
888class QQuickLayoutMirroringAttached : public QObject
889{
890 Q_OBJECT
891 Q_PROPERTY(bool enabled READ enabled WRITE setEnabled RESET resetEnabled NOTIFY enabledChanged FINAL)
892 Q_PROPERTY(bool childrenInherit READ childrenInherit WRITE setChildrenInherit NOTIFY childrenInheritChanged FINAL)
893
894 QML_NAMED_ELEMENT(LayoutMirroring)
895 QML_ADDED_IN_VERSION(2, 0)
896 QML_UNCREATABLE("LayoutMirroring is only available via attached properties.")
897 QML_ATTACHED(QQuickLayoutMirroringAttached)
898
899public:
900 explicit QQuickLayoutMirroringAttached(QObject *parent = nullptr);
901
902 bool enabled() const;
903 void setEnabled(bool);
904 void resetEnabled();
905
906 bool childrenInherit() const;
907 void setChildrenInherit(bool);
908
909 static QQuickLayoutMirroringAttached *qmlAttachedProperties(QObject *);
910Q_SIGNALS:
911 void enabledChanged();
912 void childrenInheritChanged();
913private:
914 friend class QQuickItemPrivate;
915 QQuickItemPrivate *itemPrivate;
916};
917
918class QQuickEnterKeyAttached : public QObject
919{
920 Q_OBJECT
921 Q_PROPERTY(Qt::EnterKeyType type READ type WRITE setType NOTIFY typeChanged FINAL)
922
923 QML_NAMED_ELEMENT(EnterKey)
924 QML_UNCREATABLE("EnterKey is only available via attached properties")
925 QML_ADDED_IN_VERSION(2, 6)
926 QML_ATTACHED(QQuickEnterKeyAttached)
927
928public:
929 explicit QQuickEnterKeyAttached(QObject *parent = nullptr);
930
931 Qt::EnterKeyType type() const;
932 void setType(Qt::EnterKeyType type);
933
934 static QQuickEnterKeyAttached *qmlAttachedProperties(QObject *);
935Q_SIGNALS:
936 void typeChanged();
937private:
938 friend class QQuickItemPrivate;
939 QQuickItemPrivate *itemPrivate;
940
941 Qt::EnterKeyType keyType;
942};
943
944class QQuickKeysAttachedPrivate : public QObjectPrivate
945{
946public:
947 QQuickKeysAttachedPrivate()
948 : inPress(false), inRelease(false), inIM(false), enabled(true)
949 {}
950
951 //loop detection
952 bool inPress:1;
953 bool inRelease:1;
954 bool inIM:1;
955
956 bool enabled : 1;
957
958 QQuickItem *imeItem = nullptr;
959 QList<QQuickItem *> targets;
960 QQuickItem *item = nullptr;
961 QQuickKeyEvent theKeyEvent;
962};
963
964class Q_QUICK_EXPORT QQuickKeysAttached : public QObject, public QQuickItemKeyFilter
965{
966 Q_OBJECT
967 Q_DECLARE_PRIVATE(QQuickKeysAttached)
968
969 Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged FINAL)
970 Q_PROPERTY(QQmlListProperty<QQuickItem> forwardTo READ forwardTo FINAL)
971 Q_PROPERTY(Priority priority READ priority WRITE setPriority NOTIFY priorityChanged FINAL)
972
973 QML_NAMED_ELEMENT(Keys)
974 QML_ADDED_IN_VERSION(2, 0)
975 QML_UNCREATABLE("Keys is only available via attached properties")
976 QML_ATTACHED(QQuickKeysAttached)
977
978public:
979 QQuickKeysAttached(QObject *parent=nullptr);
980 ~QQuickKeysAttached() override;
981
982 bool enabled() const { Q_D(const QQuickKeysAttached); return d->enabled; }
983 void setEnabled(bool enabled) {
984 Q_D(QQuickKeysAttached);
985 if (enabled != d->enabled) {
986 d->enabled = enabled;
987 Q_EMIT enabledChanged();
988 }
989 }
990
991 enum Priority { BeforeItem, AfterItem};
992 Q_ENUM(Priority)
993 Priority priority() const;
994 void setPriority(Priority);
995
996 QQmlListProperty<QQuickItem> forwardTo() {
997 Q_D(QQuickKeysAttached);
998 return QQmlListProperty<QQuickItem>(this, &(d->targets));
999 }
1000
1001 void componentComplete() override;
1002
1003 static QQuickKeysAttached *qmlAttachedProperties(QObject *);
1004
1005Q_SIGNALS:
1006 void enabledChanged();
1007 void priorityChanged();
1008 void pressed(QQuickKeyEvent *event);
1009 void released(QQuickKeyEvent *event);
1010 void shortcutOverride(QQuickKeyEvent *event);
1011 void digit0Pressed(QQuickKeyEvent *event);
1012 void digit1Pressed(QQuickKeyEvent *event);
1013 void digit2Pressed(QQuickKeyEvent *event);
1014 void digit3Pressed(QQuickKeyEvent *event);
1015 void digit4Pressed(QQuickKeyEvent *event);
1016 void digit5Pressed(QQuickKeyEvent *event);
1017 void digit6Pressed(QQuickKeyEvent *event);
1018 void digit7Pressed(QQuickKeyEvent *event);
1019 void digit8Pressed(QQuickKeyEvent *event);
1020 void digit9Pressed(QQuickKeyEvent *event);
1021
1022 void leftPressed(QQuickKeyEvent *event);
1023 void rightPressed(QQuickKeyEvent *event);
1024 void upPressed(QQuickKeyEvent *event);
1025 void downPressed(QQuickKeyEvent *event);
1026 void tabPressed(QQuickKeyEvent *event);
1027 void backtabPressed(QQuickKeyEvent *event);
1028
1029 void asteriskPressed(QQuickKeyEvent *event);
1030 void numberSignPressed(QQuickKeyEvent *event);
1031 void escapePressed(QQuickKeyEvent *event);
1032 void returnPressed(QQuickKeyEvent *event);
1033 void enterPressed(QQuickKeyEvent *event);
1034 void deletePressed(QQuickKeyEvent *event);
1035 void spacePressed(QQuickKeyEvent *event);
1036 void backPressed(QQuickKeyEvent *event);
1037 void cancelPressed(QQuickKeyEvent *event);
1038 void selectPressed(QQuickKeyEvent *event);
1039 void yesPressed(QQuickKeyEvent *event);
1040 void noPressed(QQuickKeyEvent *event);
1041 void context1Pressed(QQuickKeyEvent *event);
1042 void context2Pressed(QQuickKeyEvent *event);
1043 void context3Pressed(QQuickKeyEvent *event);
1044 void context4Pressed(QQuickKeyEvent *event);
1045 void callPressed(QQuickKeyEvent *event);
1046 void hangupPressed(QQuickKeyEvent *event);
1047 void flipPressed(QQuickKeyEvent *event);
1048 void menuPressed(QQuickKeyEvent *event);
1049 void volumeUpPressed(QQuickKeyEvent *event);
1050 void volumeDownPressed(QQuickKeyEvent *event);
1051
1052private:
1053 void keyPressed(QKeyEvent *event, bool post) override;
1054 void keyReleased(QKeyEvent *event, bool post) override;
1055#if QT_CONFIG(im)
1056 void inputMethodEvent(QInputMethodEvent *, bool post) override;
1057 QVariant inputMethodQuery(Qt::InputMethodQuery query) const override;
1058#endif
1059 void shortcutOverrideEvent(QKeyEvent *event) override;
1060 static QByteArray keyToSignal(int key);
1061
1062 bool isConnected(const char *signalName) const;
1063};
1064
1065Qt::MouseButtons QQuickItemPrivate::acceptedMouseButtons() const
1066{
1067 return ((extra.tag().testFlag(flag: LeftMouseButtonAccepted) ? Qt::LeftButton : Qt::MouseButton(0)) |
1068 (extra.isAllocated() ? extra->acceptedMouseButtons : Qt::MouseButtons{}));
1069}
1070
1071QSGContext *QQuickItemPrivate::sceneGraphContext() const
1072{
1073 Q_ASSERT(window);
1074 return static_cast<QQuickWindowPrivate *>(QObjectPrivate::get(o: window))->context->sceneGraphContext();
1075}
1076
1077QSGRenderContext *QQuickItemPrivate::sceneGraphRenderContext() const
1078{
1079 Q_ASSERT(window);
1080 return static_cast<QQuickWindowPrivate *>(QObjectPrivate::get(o: window))->context;
1081}
1082
1083void QQuickItemPrivate::markSortedChildrenDirty(QQuickItem *child)
1084{
1085 // If sortedChildItems == &childItems then all in childItems have z == 0
1086 // and we don't need to invalidate if the changed item also has z == 0.
1087 if (child->z() != 0. || sortedChildItems != &childItems) {
1088 if (sortedChildItems != &childItems)
1089 delete sortedChildItems;
1090 sortedChildItems = nullptr;
1091 }
1092}
1093
1094QQuickItem::TransformOrigin QQuickItemPrivate::origin() const
1095{
1096 return extra.isAllocated() ? QQuickItem::TransformOrigin(extra->origin)
1097 : QQuickItem::Center;
1098}
1099
1100QSGTransformNode *QQuickItemPrivate::itemNode()
1101{
1102 if (!itemNodeInstance) {
1103 itemNodeInstance = createTransformNode();
1104 itemNodeInstance->setFlag(QSGNode::OwnedByParent, false);
1105#ifdef QSG_RUNTIME_DESCRIPTION
1106 Q_Q(QQuickItem);
1107 qsgnode_set_description(node: itemNodeInstance, description: QString::fromLatin1(ba: "QQuickItem(%1:%2)").arg(a: QString::fromLatin1(ba: q->metaObject()->className())).arg(a: q->objectName()));
1108#endif
1109 }
1110 return itemNodeInstance;
1111}
1112
1113QSGNode *QQuickItemPrivate::childContainerNode()
1114{
1115 if (rootNode())
1116 return rootNode();
1117 else if (clipNode())
1118 return clipNode();
1119 else if (opacityNode())
1120 return opacityNode();
1121 else
1122 return itemNode();
1123}
1124
1125Q_DECLARE_OPERATORS_FOR_FLAGS(QQuickItemPrivate::ChangeTypes)
1126Q_DECLARE_TYPEINFO(QQuickItemPrivate::ChangeListener, Q_PRIMITIVE_TYPE);
1127
1128QT_END_NAMESPACE
1129
1130#endif // QQUICKITEM_P_H
1131

source code of qtdeclarative/src/quick/items/qquickitem_p.h