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