Also check notifier endpoints when checking whether a signal is connected.
[profile/ivi/qtdeclarative.git] / src / quick / items / qquickitem_p.h
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the QtQml module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20 **
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
28 **
29 ** Other Usage
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #ifndef QQUICKITEM_P_H
43 #define QQUICKITEM_P_H
44
45 //
46 //  W A R N I N G
47 //  -------------
48 //
49 // This file is not part of the Qt API.  It exists purely as an
50 // implementation detail.  This header file may change from version to
51 // version without notice, or even be removed.
52 //
53 // We mean it.
54 //
55
56 #include "qquickitem.h"
57
58 #include "qquickanchors_p.h"
59 #include "qquickanchors_p_p.h"
60 #include "qquickitemchangelistener_p.h"
61
62 #include "qquickcanvas_p.h"
63
64 #include <QtQuick/qsgnode.h>
65 #include "qquickclipnode_p.h"
66
67 #include <private/qpodvector_p.h>
68 #include <QtQuick/private/qquickstate_p.h>
69 #include <private/qqmlnullablevalue_p_p.h>
70 #include <private/qqmlnotifier_p.h>
71 #include <private/qqmlglobal_p.h>
72 #include <private/qlazilyallocated_p.h>
73
74 #include <qqml.h>
75 #include <qqmlcontext.h>
76
77 #include <QtCore/qlist.h>
78 #include <QtCore/qdebug.h>
79 #include <QtCore/qelapsedtimer.h>
80
81 #include <QtQuick/private/qquickshadereffectsource_p.h>
82 #include <QtQuick/private/qquickshadereffect_p.h>
83
84 QT_BEGIN_NAMESPACE
85
86 class QNetworkReply;
87 class QQuickItemKeyFilter;
88 class QQuickLayoutMirroringAttached;
89 class QQuickScreenAttached;
90
91 class QQuickContents : public QQuickItemChangeListener
92 {
93 public:
94     QQuickContents(QQuickItem *item);
95     ~QQuickContents();
96
97     QRectF rectF() const { return QRectF(m_x, m_y, m_width, m_height); }
98
99     inline void calcGeometry(QQuickItem *changed = 0);
100     void complete();
101
102 protected:
103     void itemGeometryChanged(QQuickItem *item, const QRectF &newGeometry, const QRectF &oldGeometry);
104     void itemDestroyed(QQuickItem *item);
105     void itemChildAdded(QQuickItem *, QQuickItem *);
106     void itemChildRemoved(QQuickItem *, QQuickItem *);
107     //void itemVisibilityChanged(QQuickItem *item)
108
109 private:
110     bool calcHeight(QQuickItem *changed = 0);
111     bool calcWidth(QQuickItem *changed = 0);
112     void updateRect();
113
114     QQuickItem *m_item;
115     qreal m_x;
116     qreal m_y;
117     qreal m_width;
118     qreal m_height;
119 };
120
121 void QQuickContents::calcGeometry(QQuickItem *changed)
122 {
123     bool wChanged = calcWidth(changed);
124     bool hChanged = calcHeight(changed);
125     if (wChanged || hChanged)
126         updateRect();
127 }
128
129 class QQuickTransformPrivate : public QObjectPrivate
130 {
131     Q_DECLARE_PUBLIC(QQuickTransform);
132 public:
133     static QQuickTransformPrivate* get(QQuickTransform *transform) { return transform->d_func(); }
134
135     QQuickTransformPrivate();
136
137     QList<QQuickItem *> items;
138 };
139
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 public:
154     QQuickItemLayer(QQuickItem *item);
155     ~QQuickItemLayer();
156
157     void classBegin();
158     void componentComplete();
159
160     bool enabled() const { return m_enabled; }
161     void setEnabled(bool enabled);
162
163     bool mipmap() const { return m_mipmap; }
164     void setMipmap(bool mipmap);
165
166     bool smooth() const { return m_smooth; }
167     void setSmooth(bool s);
168
169     QSize size() const { return m_size; }
170     void setSize(const QSize &size);
171
172     QQuickShaderEffectSource::Format format() const { return m_format; }
173     void setFormat(QQuickShaderEffectSource::Format f);
174
175     QRectF sourceRect() const { return m_sourceRect; }
176     void setSourceRect(const QRectF &sourceRect);
177
178     QQuickShaderEffectSource::WrapMode wrapMode() const { return m_wrapMode; }
179     void setWrapMode(QQuickShaderEffectSource::WrapMode mode);
180
181     QByteArray name() const { return m_name; }
182     void setName(const QByteArray &name);
183
184     QQmlComponent *effect() const { return m_effectComponent; }
185     void setEffect(QQmlComponent *effect);
186
187     QQuickShaderEffectSource *effectSource() const { return m_effectSource; }
188
189     void itemGeometryChanged(QQuickItem *, const QRectF &, const QRectF &);
190     void itemOpacityChanged(QQuickItem *);
191     void itemParentChanged(QQuickItem *, QQuickItem *);
192     void itemSiblingOrderChanged(QQuickItem *);
193     void itemVisibilityChanged(QQuickItem *);
194
195     void updateMatrix();
196     void updateGeometry();
197     void updateOpacity();
198     void updateZ();
199
200 signals:
201     void enabledChanged(bool enabled);
202     void sizeChanged(const QSize &size);
203     void mipmapChanged(bool mipmap);
204     void wrapModeChanged(QQuickShaderEffectSource::WrapMode mode);
205     void nameChanged(const QByteArray &name);
206     void effectChanged(QQmlComponent *component);
207     void smoothChanged(bool smooth);
208     void formatChanged(QQuickShaderEffectSource::Format format);
209     void sourceRectChanged(const QRectF &sourceRect);
210
211 private:
212     void activate();
213     void deactivate();
214     void activateEffect();
215     void deactivateEffect();
216
217     QQuickItem *m_item;
218     bool m_enabled;
219     bool m_mipmap;
220     bool m_smooth;
221     bool m_componentComplete;
222     QQuickShaderEffectSource::WrapMode m_wrapMode;
223     QQuickShaderEffectSource::Format m_format;
224     QSize m_size;
225     QRectF m_sourceRect;
226     QByteArray m_name;
227     QQmlComponent *m_effectComponent;
228     QQuickItem *m_effect;
229     QQuickShaderEffectSource *m_effectSource;
230 };
231
232 class Q_QUICK_EXPORT QQuickItemPrivate : public QObjectPrivate
233 {
234     Q_DECLARE_PUBLIC(QQuickItem)
235
236 public:
237     static QQuickItemPrivate* get(QQuickItem *item) { return item->d_func(); }
238     static const QQuickItemPrivate* get(const QQuickItem *item) { return item->d_func(); }
239
240     static void registerAccessorProperties();
241
242     QQuickItemPrivate();
243     ~QQuickItemPrivate();
244     void init(QQuickItem *parent);
245
246     QQmlListProperty<QObject> data();
247     QQmlListProperty<QObject> resources();
248     QQmlListProperty<QQuickItem> children();
249     QQmlListProperty<QQuickItem> visibleChildren();
250
251     QQmlListProperty<QQuickState> states();
252     QQmlListProperty<QQuickTransition> transitions();
253
254     QString state() const;
255     void setState(const QString &);
256
257     QQuickAnchorLine left() const;
258     QQuickAnchorLine right() const;
259     QQuickAnchorLine horizontalCenter() const;
260     QQuickAnchorLine top() const;
261     QQuickAnchorLine bottom() const;
262     QQuickAnchorLine verticalCenter() const;
263     QQuickAnchorLine baseline() const;
264
265     QQuickItemLayer *layer() const;
266
267     // data property
268     static void data_append(QQmlListProperty<QObject> *, QObject *);
269     static int data_count(QQmlListProperty<QObject> *);
270     static QObject *data_at(QQmlListProperty<QObject> *, int);
271     static void data_clear(QQmlListProperty<QObject> *);
272
273     // resources property
274     static QObject *resources_at(QQmlListProperty<QObject> *, int);
275     static void resources_append(QQmlListProperty<QObject> *, QObject *);
276     static int resources_count(QQmlListProperty<QObject> *);
277     static void resources_clear(QQmlListProperty<QObject> *);
278
279     // children property
280     static void children_append(QQmlListProperty<QQuickItem> *, QQuickItem *);
281     static int children_count(QQmlListProperty<QQuickItem> *);
282     static QQuickItem *children_at(QQmlListProperty<QQuickItem> *, int);
283     static void children_clear(QQmlListProperty<QQuickItem> *);
284
285     // visibleChildren property
286     static void visibleChildren_append(QQmlListProperty<QQuickItem> *prop, QQuickItem *o);
287     static int visibleChildren_count(QQmlListProperty<QQuickItem> *prop);
288     static QQuickItem *visibleChildren_at(QQmlListProperty<QQuickItem> *prop, int index);
289
290     // transform property
291     static int transform_count(QQmlListProperty<QQuickTransform> *list);
292     static void transform_append(QQmlListProperty<QQuickTransform> *list, QQuickTransform *);
293     static QQuickTransform *transform_at(QQmlListProperty<QQuickTransform> *list, int);
294     static void transform_clear(QQmlListProperty<QQuickTransform> *list);
295
296     enum ChangeType {
297         Geometry = 0x01,
298         SiblingOrder = 0x02,
299         Visibility = 0x04,
300         Opacity = 0x08,
301         Destroyed = 0x10,
302         Parent = 0x20,
303         Children = 0x40,
304         Rotation = 0x80,
305         ImplicitWidth = 0x100,
306         ImplicitHeight = 0x200
307     };
308
309     Q_DECLARE_FLAGS(ChangeTypes, ChangeType)
310
311     enum GeometryChangeType {
312         NoChange = 0,
313         XChange = 0x01,
314         YChange = 0x02,
315         WidthChange = 0x04,
316         HeightChange = 0x08,
317         SizeChange = WidthChange | HeightChange,
318         GeometryChange = XChange | YChange | SizeChange
319     };
320
321     Q_DECLARE_FLAGS(GeometryChangeTypes, GeometryChangeType)
322
323     struct ChangeListener {
324         ChangeListener(QQuickItemChangeListener *l, QQuickItemPrivate::ChangeTypes t) : listener(l), types(t), gTypes(GeometryChange) {}
325         ChangeListener(QQuickItemChangeListener *l, QQuickItemPrivate::GeometryChangeTypes gt) : listener(l), types(Geometry), gTypes(gt) {}
326         QQuickItemChangeListener *listener;
327         QQuickItemPrivate::ChangeTypes types;
328         QQuickItemPrivate::GeometryChangeTypes gTypes;  //NOTE: not used for ==
329         bool operator==(const ChangeListener &other) const { return listener == other.listener && types == other.types; }
330     };
331
332     struct ExtraData {
333         ExtraData();
334
335         qreal z;
336         qreal scale;
337         qreal rotation;
338         qreal opacity;
339
340         QQuickContents *contents;
341         QQuickScreenAttached *screenAttached;
342         QQuickLayoutMirroringAttached* layoutDirectionAttached;
343         QQuickItemKeyFilter *keyHandler;
344         mutable QQuickItemLayer *layer;
345         QPointF userTransformOriginPoint;
346
347         int effectRefCount;
348         int hideRefCount;
349
350         QSGOpacityNode *opacityNode;
351         QQuickDefaultClipNode *clipNode;
352         QSGRootNode *rootNode;
353         QSGNode *beforePaintNode;
354
355         // Although acceptedMouseButtons is inside ExtraData, we actually store
356         // the LeftButton flag in the extra.flag() bit.  This is because it is
357         // extremely common to set acceptedMouseButtons to LeftButton, but very
358         // rare to use any of the other buttons.
359         Qt::MouseButtons acceptedMouseButtons;
360
361         QQuickItem::TransformOrigin origin:5;
362     };
363     QLazilyAllocated<ExtraData> extra;
364
365     QQuickAnchors *anchors() const;
366     mutable QQuickAnchors *_anchors;
367
368     inline Qt::MouseButtons acceptedMouseButtons() const;
369
370     QPODVector<QQuickItemPrivate::ChangeListener,4> changeListeners;
371
372     void addItemChangeListener(QQuickItemChangeListener *listener, ChangeTypes types);
373     void removeItemChangeListener(QQuickItemChangeListener *, ChangeTypes types);
374     void updateOrAddGeometryChangeListener(QQuickItemChangeListener *listener, GeometryChangeTypes types);
375     void updateOrRemoveGeometryChangeListener(QQuickItemChangeListener *listener, GeometryChangeTypes types);
376
377     QQuickStateGroup *_states();
378     QQuickStateGroup *_stateGroup;
379
380     inline QQuickItem::TransformOrigin origin() const;
381
382     // Bit 0
383     quint32 flags:5;
384     bool widthValid:1;
385     bool heightValid:1;
386     bool baselineOffsetValid:1;
387     bool componentComplete:1;
388     bool keepMouse:1;
389     bool keepTouch:1;
390     bool hoverEnabled:1;
391     bool smooth:1;
392     bool focus:1;
393     bool activeFocus:1;
394     bool notifiedFocus:1;
395     // Bit 16
396     bool notifiedActiveFocus:1;
397     bool filtersChildMouseEvents:1;
398     bool explicitVisible:1;
399     bool effectiveVisible:1;
400     bool explicitEnable:1;
401     bool effectiveEnable:1;
402     bool polishScheduled:1;
403     bool inheritedLayoutMirror:1;
404     bool effectiveLayoutMirror:1;
405     bool isMirrorImplicit:1;
406     bool inheritMirrorFromParent:1;
407     bool inheritMirrorFromItem:1;
408     bool childrenDoNotOverlap:1;
409     bool staticSubtreeGeometry:1;
410     bool isAccessible:1;
411     // bool dummy:1
412     // Bit 32
413
414     enum DirtyType {
415         TransformOrigin         = 0x00000001,
416         Transform               = 0x00000002,
417         BasicTransform          = 0x00000004,
418         Position                = 0x00000008,
419         Size                    = 0x00000010,
420
421         ZValue                  = 0x00000020,
422         Content                 = 0x00000040,
423         Smooth                  = 0x00000080,
424         OpacityValue            = 0x00000100,
425         ChildrenChanged         = 0x00000200,
426         ChildrenStackingChanged = 0x00000400,
427         ParentChanged           = 0x00000800,
428
429         Clip                    = 0x00001000,
430         Canvas                  = 0x00002000,
431
432         EffectReference         = 0x00008000,
433         Visible                 = 0x00010000,
434         HideReference           = 0x00020000,
435         PerformanceHints        = 0x00040000,
436         // When you add an attribute here, don't forget to update
437         // dirtyToString()
438
439         TransformUpdateMask     = TransformOrigin | Transform | BasicTransform | Position |
440                                   Size | Canvas,
441         ComplexTransformUpdateMask     = Transform | Canvas,
442         ContentUpdateMask       = Size | Content | Smooth | Canvas,
443         ChildrenUpdateMask      = ChildrenChanged | ChildrenStackingChanged | EffectReference | Canvas
444     };
445
446     quint32 dirtyAttributes;
447     QString dirtyToString() const;
448     void dirty(DirtyType);
449     void addToDirtyList();
450     void removeFromDirtyList();
451     QQuickItem *nextDirtyItem;
452     QQuickItem**prevDirtyItem;
453
454     QQuickCanvas *canvas;
455     int canvasRefCount;
456     inline QSGContext *sceneGraphContext() const;
457
458     QQuickItem *parentItem;
459     QQmlNotifier parentNotifier;
460
461     QList<QQuickItem *> childItems;
462     mutable QList<QQuickItem *> *sortedChildItems;
463     QList<QQuickItem *> paintOrderChildItems() const;
464     void addChild(QQuickItem *);
465     void removeChild(QQuickItem *);
466     void siblingOrderChanged();
467
468     inline void markSortedChildrenDirty(QQuickItem *child);
469
470     class InitializationState {
471     public:
472         QQuickItem *getFocusScope(QQuickItem *item);
473         void clear();
474         void clear(QQuickItem *focusScope);
475     private:
476         QQuickItem *focusScope;
477     };
478
479     void refCanvas(QQuickCanvas *);
480     void refCanvas(InitializationState *, QQuickCanvas *);
481     void derefCanvas();
482
483     QQuickItem *subFocusItem;
484     void updateSubFocusItem(QQuickItem *scope, bool focus);
485
486     QTransform canvasToItemTransform() const;
487     QTransform itemToCanvasTransform() const;
488     void itemToParentTransform(QTransform &) const;
489
490     qreal x;
491     qreal y;
492     qreal width;
493     qreal height;
494     qreal implicitWidth;
495     qreal implicitHeight;
496
497     qreal baselineOffset;
498
499     QList<QQuickTransform *> transforms;
500
501     inline qreal z() const { return extra.isAllocated()?extra->z:0; }
502     inline qreal scale() const { return extra.isAllocated()?extra->scale:1; }
503     inline qreal rotation() const { return extra.isAllocated()?extra->rotation:0; }
504     inline qreal opacity() const { return extra.isAllocated()?extra->opacity:1; }
505
506     void setAccessibleFlagAndListener();
507
508     virtual qreal getImplicitWidth() const;
509     virtual qreal getImplicitHeight() const;
510     virtual void implicitWidthChanged();
511     virtual void implicitHeightChanged();
512
513     void resolveLayoutMirror();
514     void setImplicitLayoutMirror(bool mirror, bool inherit);
515     void setLayoutMirror(bool mirror);
516     bool isMirrored() const {
517         return effectiveLayoutMirror;
518     }
519
520     void emitChildrenRectChanged(const QRectF &rect) {
521         Q_Q(QQuickItem);
522         emit q->childrenRectChanged(rect);
523     }
524
525     QPointF computeTransformOrigin() const;
526     virtual void transformChanged();
527
528     void deliverKeyEvent(QKeyEvent *);
529     void deliverInputMethodEvent(QInputMethodEvent *);
530     void deliverFocusEvent(QFocusEvent *);
531     void deliverMouseEvent(QMouseEvent *);
532     void deliverWheelEvent(QWheelEvent *);
533     void deliverTouchEvent(QTouchEvent *);
534     void deliverHoverEvent(QHoverEvent *);
535     void deliverDragEvent(QEvent *);
536
537     bool calcEffectiveVisible() const;
538     bool setEffectiveVisibleRecur(bool);
539     bool calcEffectiveEnable() const;
540     void setEffectiveEnableRecur(QQuickItem *scope, bool);
541
542
543     inline QSGTransformNode *itemNode();
544     inline QSGNode *childContainerNode();
545
546     /*
547       QSGNode order is:
548          - itemNode
549          - (opacityNode)
550          - (clipNode)
551          - (effectNode)
552          - groupNode
553      */
554
555     QSGOpacityNode *opacityNode() const { return extra.isAllocated()?extra->opacityNode:0; }
556     QQuickDefaultClipNode *clipNode() const { return extra.isAllocated()?extra->clipNode:0; }
557     QSGRootNode *rootNode() const { return extra.isAllocated()?extra->rootNode:0; }
558
559     QSGTransformNode *itemNodeInstance;
560     QSGNode *groupNode;
561     QSGNode *paintNode;
562
563     virtual QSGTransformNode *createTransformNode();
564
565     // A reference from an effect item means that this item is used by the effect, so
566     // it should insert a root node.
567     void refFromEffectItem(bool hide);
568     void derefFromEffectItem(bool unhide);
569
570     void itemChange(QQuickItem::ItemChange, const QQuickItem::ItemChangeData &);
571
572     virtual void mirrorChange() {}
573
574     static qint64 consistentTime;
575     static void setConsistentTime(qint64 t);
576     static void start(QElapsedTimer &);
577     static qint64 elapsed(QElapsedTimer &);
578     static qint64 restart(QElapsedTimer &);
579 };
580
581 /*
582     Key filters can be installed on a QQuickItem, but not removed.  Currently they
583     are only used by attached objects (which are only destroyed on Item
584     destruction), so this isn't a problem.  If in future this becomes any form
585     of public API, they will have to support removal too.
586 */
587 class QQuickItemKeyFilter
588 {
589 public:
590     QQuickItemKeyFilter(QQuickItem * = 0);
591     virtual ~QQuickItemKeyFilter();
592
593     virtual void keyPressed(QKeyEvent *event, bool post);
594     virtual void keyReleased(QKeyEvent *event, bool post);
595     virtual void inputMethodEvent(QInputMethodEvent *event, bool post);
596     virtual QVariant inputMethodQuery(Qt::InputMethodQuery query) const;
597     virtual void componentComplete();
598
599     bool m_processPost;
600
601 private:
602     QQuickItemKeyFilter *m_next;
603 };
604
605 class QQuickKeyNavigationAttachedPrivate : public QObjectPrivate
606 {
607 public:
608     QQuickKeyNavigationAttachedPrivate()
609         : QObjectPrivate(),
610           left(0), right(0), up(0), down(0), tab(0), backtab(0),
611           leftSet(false), rightSet(false), upSet(false), downSet(false),
612           tabSet(false), backtabSet(false) {}
613
614     QQuickItem *left;
615     QQuickItem *right;
616     QQuickItem *up;
617     QQuickItem *down;
618     QQuickItem *tab;
619     QQuickItem *backtab;
620     bool leftSet : 1;
621     bool rightSet : 1;
622     bool upSet : 1;
623     bool downSet : 1;
624     bool tabSet : 1;
625     bool backtabSet : 1;
626 };
627
628 class QQuickKeyNavigationAttached : public QObject, public QQuickItemKeyFilter
629 {
630     Q_OBJECT
631     Q_DECLARE_PRIVATE(QQuickKeyNavigationAttached)
632
633     Q_PROPERTY(QQuickItem *left READ left WRITE setLeft NOTIFY leftChanged)
634     Q_PROPERTY(QQuickItem *right READ right WRITE setRight NOTIFY rightChanged)
635     Q_PROPERTY(QQuickItem *up READ up WRITE setUp NOTIFY upChanged)
636     Q_PROPERTY(QQuickItem *down READ down WRITE setDown NOTIFY downChanged)
637     Q_PROPERTY(QQuickItem *tab READ tab WRITE setTab NOTIFY tabChanged)
638     Q_PROPERTY(QQuickItem *backtab READ backtab WRITE setBacktab NOTIFY backtabChanged)
639     Q_PROPERTY(Priority priority READ priority WRITE setPriority NOTIFY priorityChanged)
640
641     Q_ENUMS(Priority)
642
643 public:
644     QQuickKeyNavigationAttached(QObject * = 0);
645
646     QQuickItem *left() const;
647     void setLeft(QQuickItem *);
648     QQuickItem *right() const;
649     void setRight(QQuickItem *);
650     QQuickItem *up() const;
651     void setUp(QQuickItem *);
652     QQuickItem *down() const;
653     void setDown(QQuickItem *);
654     QQuickItem *tab() const;
655     void setTab(QQuickItem *);
656     QQuickItem *backtab() const;
657     void setBacktab(QQuickItem *);
658
659     enum Priority { BeforeItem, AfterItem };
660     Priority priority() const;
661     void setPriority(Priority);
662
663     static QQuickKeyNavigationAttached *qmlAttachedProperties(QObject *);
664
665 Q_SIGNALS:
666     void leftChanged();
667     void rightChanged();
668     void upChanged();
669     void downChanged();
670     void tabChanged();
671     void backtabChanged();
672     void priorityChanged();
673
674 private:
675     virtual void keyPressed(QKeyEvent *event, bool post);
676     virtual void keyReleased(QKeyEvent *event, bool post);
677     void setFocusNavigation(QQuickItem *currentItem, const char *dir);
678 };
679
680 class QQuickLayoutMirroringAttached : public QObject
681 {
682     Q_OBJECT
683     Q_PROPERTY(bool enabled READ enabled WRITE setEnabled RESET resetEnabled NOTIFY enabledChanged)
684     Q_PROPERTY(bool childrenInherit READ childrenInherit WRITE setChildrenInherit NOTIFY childrenInheritChanged)
685
686 public:
687     explicit QQuickLayoutMirroringAttached(QObject *parent = 0);
688
689     bool enabled() const;
690     void setEnabled(bool);
691     void resetEnabled();
692
693     bool childrenInherit() const;
694     void setChildrenInherit(bool);
695
696     static QQuickLayoutMirroringAttached *qmlAttachedProperties(QObject *);
697 Q_SIGNALS:
698     void enabledChanged();
699     void childrenInheritChanged();
700 private:
701     friend class QQuickItemPrivate;
702     QQuickItemPrivate *itemPrivate;
703 };
704
705 class QQuickKeysAttachedPrivate : public QObjectPrivate
706 {
707 public:
708     QQuickKeysAttachedPrivate()
709         : QObjectPrivate(), inPress(false), inRelease(false)
710         , inIM(false), enabled(true), imeItem(0), item(0)
711     {}
712
713     //loop detection
714     bool inPress:1;
715     bool inRelease:1;
716     bool inIM:1;
717
718     bool enabled : 1;
719
720     QQuickItem *imeItem;
721     QList<QQuickItem *> targets;
722     QQuickItem *item;
723 };
724
725 class QQuickKeysAttached : public QObject, public QQuickItemKeyFilter
726 {
727     Q_OBJECT
728     Q_DECLARE_PRIVATE(QQuickKeysAttached)
729
730     Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged)
731     Q_PROPERTY(QQmlListProperty<QQuickItem> forwardTo READ forwardTo)
732     Q_PROPERTY(Priority priority READ priority WRITE setPriority NOTIFY priorityChanged)
733
734     Q_ENUMS(Priority)
735
736 public:
737     QQuickKeysAttached(QObject *parent=0);
738     ~QQuickKeysAttached();
739
740     bool enabled() const { Q_D(const QQuickKeysAttached); return d->enabled; }
741     void setEnabled(bool enabled) {
742         Q_D(QQuickKeysAttached);
743         if (enabled != d->enabled) {
744             d->enabled = enabled;
745             emit enabledChanged();
746         }
747     }
748
749     enum Priority { BeforeItem, AfterItem};
750     Priority priority() const;
751     void setPriority(Priority);
752
753     QQmlListProperty<QQuickItem> forwardTo() {
754         Q_D(QQuickKeysAttached);
755         return QQmlListProperty<QQuickItem>(this, d->targets);
756     }
757
758     virtual void componentComplete();
759
760     static QQuickKeysAttached *qmlAttachedProperties(QObject *);
761
762 Q_SIGNALS:
763     void enabledChanged();
764     void priorityChanged();
765     void pressed(QQuickKeyEvent *event);
766     void released(QQuickKeyEvent *event);
767     void digit0Pressed(QQuickKeyEvent *event);
768     void digit1Pressed(QQuickKeyEvent *event);
769     void digit2Pressed(QQuickKeyEvent *event);
770     void digit3Pressed(QQuickKeyEvent *event);
771     void digit4Pressed(QQuickKeyEvent *event);
772     void digit5Pressed(QQuickKeyEvent *event);
773     void digit6Pressed(QQuickKeyEvent *event);
774     void digit7Pressed(QQuickKeyEvent *event);
775     void digit8Pressed(QQuickKeyEvent *event);
776     void digit9Pressed(QQuickKeyEvent *event);
777
778     void leftPressed(QQuickKeyEvent *event);
779     void rightPressed(QQuickKeyEvent *event);
780     void upPressed(QQuickKeyEvent *event);
781     void downPressed(QQuickKeyEvent *event);
782     void tabPressed(QQuickKeyEvent *event);
783     void backtabPressed(QQuickKeyEvent *event);
784
785     void asteriskPressed(QQuickKeyEvent *event);
786     void numberSignPressed(QQuickKeyEvent *event);
787     void escapePressed(QQuickKeyEvent *event);
788     void returnPressed(QQuickKeyEvent *event);
789     void enterPressed(QQuickKeyEvent *event);
790     void deletePressed(QQuickKeyEvent *event);
791     void spacePressed(QQuickKeyEvent *event);
792     void backPressed(QQuickKeyEvent *event);
793     void cancelPressed(QQuickKeyEvent *event);
794     void selectPressed(QQuickKeyEvent *event);
795     void yesPressed(QQuickKeyEvent *event);
796     void noPressed(QQuickKeyEvent *event);
797     void context1Pressed(QQuickKeyEvent *event);
798     void context2Pressed(QQuickKeyEvent *event);
799     void context3Pressed(QQuickKeyEvent *event);
800     void context4Pressed(QQuickKeyEvent *event);
801     void callPressed(QQuickKeyEvent *event);
802     void hangupPressed(QQuickKeyEvent *event);
803     void flipPressed(QQuickKeyEvent *event);
804     void menuPressed(QQuickKeyEvent *event);
805     void volumeUpPressed(QQuickKeyEvent *event);
806     void volumeDownPressed(QQuickKeyEvent *event);
807
808 private:
809     virtual void keyPressed(QKeyEvent *event, bool post);
810     virtual void keyReleased(QKeyEvent *event, bool post);
811     virtual void inputMethodEvent(QInputMethodEvent *, bool post);
812     virtual QVariant inputMethodQuery(Qt::InputMethodQuery query) const;
813
814     const QByteArray keyToSignal(int key) {
815         QByteArray keySignal;
816         if (key >= Qt::Key_0 && key <= Qt::Key_9) {
817             keySignal = "digit0Pressed";
818             keySignal[5] = '0' + (key - Qt::Key_0);
819         } else {
820             int i = 0;
821             while (sigMap[i].key && sigMap[i].key != key)
822                 ++i;
823             keySignal = sigMap[i].sig;
824         }
825         return keySignal;
826     }
827
828     bool isConnected(const char *signalName);
829
830     struct SigMap {
831         int key;
832         const char *sig;
833     };
834
835     static const SigMap sigMap[];
836 };
837
838 Qt::MouseButtons QQuickItemPrivate::acceptedMouseButtons() const
839 {
840     return ((extra.flag() ? Qt::LeftButton : Qt::MouseButton(0)) |
841             (extra.isAllocated() ? extra->acceptedMouseButtons : Qt::MouseButtons(0)));
842 }
843
844 QSGContext *QQuickItemPrivate::sceneGraphContext() const
845 {
846     Q_ASSERT(canvas);
847     return static_cast<QQuickCanvasPrivate *>(QObjectPrivate::get(canvas))->context;
848 }
849
850 void QQuickItemPrivate::markSortedChildrenDirty(QQuickItem *child)
851 {
852     // If sortedChildItems == &childItems then all in childItems have z == 0
853     // and we don't need to invalidate if the changed item also has z == 0.
854     if (child->z() != 0. || sortedChildItems != &childItems) {
855         if (sortedChildItems != &childItems)
856             delete sortedChildItems;
857         sortedChildItems = 0;
858     }
859 }
860
861 QQuickItem::TransformOrigin QQuickItemPrivate::origin() const
862 {
863     return extra.isAllocated()?extra->origin:QQuickItem::Center;
864 }
865
866 inline void QQuickItemPrivate::refCanvas(QQuickCanvas *c)
867 {
868     QQuickItemPrivate::InitializationState initState;
869     initState.clear();
870     refCanvas(&initState, c);
871 }
872
873 QSGTransformNode *QQuickItemPrivate::itemNode()
874 {
875     if (!itemNodeInstance) {
876         itemNodeInstance = createTransformNode();
877         itemNodeInstance->setFlag(QSGNode::OwnedByParent, false);
878 #ifdef QML_RUNTIME_TESTING
879         Q_Q(QQuickItem);
880         itemNodeInstance->description = QString::fromLatin1("QQuickItem(%1)").arg(QString::fromLatin1(q->metaObject()->className()));
881 #endif
882     }
883     return itemNodeInstance;
884 }
885
886 QSGNode *QQuickItemPrivate::childContainerNode()
887 {
888     if (!groupNode) {
889         groupNode = new QSGNode();
890         if (rootNode())
891             rootNode()->appendChildNode(groupNode);
892         else if (clipNode())
893             clipNode()->appendChildNode(groupNode);
894         else if (opacityNode())
895             opacityNode()->appendChildNode(groupNode);
896         else
897             itemNode()->appendChildNode(groupNode);
898         groupNode->setFlag(QSGNode::ChildrenDoNotOverlap, childrenDoNotOverlap);
899         groupNode->setFlag(QSGNode::StaticSubtreeGeometry, staticSubtreeGeometry);
900 #ifdef QML_RUNTIME_TESTING
901         groupNode->description = QLatin1String("group");
902 #endif
903     }
904     return groupNode;
905 }
906
907 Q_DECLARE_OPERATORS_FOR_FLAGS(QQuickItemPrivate::ChangeTypes);
908
909 QT_END_NAMESPACE
910
911 QML_DECLARE_TYPE(QQuickItemLayer)
912 QML_DECLARE_TYPE(QQuickKeysAttached)
913 QML_DECLARE_TYPEINFO(QQuickKeysAttached, QML_HAS_ATTACHED_PROPERTIES)
914 QML_DECLARE_TYPE(QQuickKeyNavigationAttached)
915 QML_DECLARE_TYPEINFO(QQuickKeyNavigationAttached, QML_HAS_ATTACHED_PROPERTIES)
916 QML_DECLARE_TYPE(QQuickLayoutMirroringAttached)
917 QML_DECLARE_TYPEINFO(QQuickLayoutMirroringAttached, QML_HAS_ATTACHED_PROPERTIES)
918
919 #endif // QQUICKITEM_P_H