Pass Qt::ImQueryInput instead of Qt::CursorRectangle in QSgItem::updateMicroFocus...
[profile/ivi/qtdeclarative.git] / src / declarative / items / qsgitem.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the QtDeclarative module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 **
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 **
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
29 **
30 ** Other Usage
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "qsgitem.h"
43
44 #include "qsgcanvas.h"
45 #include <QtDeclarative/qjsengine.h>
46 #include "qsgcanvas_p.h"
47 #include "qsgevent.h"
48
49 #include "qsgevents_p_p.h"
50
51 #include <QtDeclarative/qdeclarativeengine.h>
52 #include <QtDeclarative/qdeclarativecomponent.h>
53 #include <QtDeclarative/qdeclarativeinfo.h>
54 #include <QtGui/qpen.h>
55 #include <QtGui/qcursor.h>
56 #include <QtGui/qguiapplication.h>
57 #include <QtGui/qinputpanel.h>
58 #include <QtCore/qdebug.h>
59 #include <QtCore/qcoreevent.h>
60 #include <QtCore/qnumeric.h>
61
62 #include <private/qdeclarativeengine_p.h>
63 #include <private/qdeclarativestategroup_p.h>
64 #include <private/qdeclarativeopenmetaobject_p.h>
65 #include <private/qdeclarativestate_p.h>
66 #include <private/qlistmodelinterface_p.h>
67 #include <private/qsgitem_p.h>
68
69 #include <float.h>
70
71 // XXX todo Readd parentNotifier for faster parent bindings
72 // XXX todo Check that elements that create items handle memory correctly after visual ownership change
73
74 QT_BEGIN_NAMESPACE
75
76 /*!
77     \qmlclass Transform QSGTransform
78     \inqmlmodule QtQuick 2
79     \ingroup qml-transform-elements
80     \brief The Transform elements provide a way of building advanced transformations on Items.
81
82     The Transform element is a base type which cannot be instantiated directly.
83     The following concrete Transform types are available:
84
85     \list
86     \o \l Rotation
87     \o \l Scale
88     \o \l Translate
89     \endlist
90
91     The Transform elements let you create and control advanced transformations that can be configured
92     independently using specialized properties.
93
94     You can assign any number of Transform elements to an \l Item. Each Transform is applied in order,
95     one at a time.
96 */
97
98 /*!
99     \qmlclass Translate QSGTranslate
100     \inqmlmodule QtQuick 2
101     \ingroup qml-transform-elements
102     \brief The Translate object provides a way to move an Item without changing its x or y properties.
103
104     The Translate object provides independent control over position in addition to the Item's x and y properties.
105
106     The following example moves the Y axis of the \l Rectangle elements while still allowing the \l Row element
107     to lay the items out as if they had not been transformed:
108     \qml
109     import QtQuick 1.0
110
111     Row {
112         Rectangle {
113             width: 100; height: 100
114             color: "blue"
115             transform: Translate { y: 20 }
116         }
117         Rectangle {
118             width: 100; height: 100
119             color: "red"
120             transform: Translate { y: -20 }
121         }
122     }
123     \endqml
124
125     \image translate.png
126 */
127
128 /*!
129     \qmlproperty real QtQuick2::Translate::x
130
131     The translation along the X axis.
132 */
133
134 /*!
135     \qmlproperty real QtQuick2::Translate::y
136
137     The translation along the Y axis.
138 */
139
140 /*!
141     \qmlclass Scale QSGScale
142     \inqmlmodule QtQuick 2
143     \ingroup qml-transform-elements
144     \brief The Scale element provides a way to scale an Item.
145
146     The Scale element gives more control over scaling than using \l Item's \l{Item::scale}{scale} property. Specifically,
147     it allows a different scale for the x and y axes, and allows the scale to be relative to an
148     arbitrary point.
149
150     The following example scales the X axis of the Rectangle, relative to its interior point 25, 25:
151     \qml
152     Rectangle {
153         width: 100; height: 100
154         color: "blue"
155         transform: Scale { origin.x: 25; origin.y: 25; xScale: 3}
156     }
157     \endqml
158
159     \sa Rotation, Translate
160 */
161
162 /*!
163     \qmlproperty real QtQuick2::Scale::origin.x
164     \qmlproperty real QtQuick2::Scale::origin.y
165
166     The point that the item is scaled from (i.e., the point that stays fixed relative to the parent as
167     the rest of the item grows). By default the origin is 0, 0.
168 */
169
170 /*!
171     \qmlproperty real QtQuick2::Scale::xScale
172
173     The scaling factor for the X axis.
174 */
175
176 /*!
177     \qmlproperty real QtQuick2::Scale::yScale
178
179     The scaling factor for the Y axis.
180 */
181
182 /*!
183     \qmlclass Rotation QSGRotation
184     \inqmlmodule QtQuick 2
185     \ingroup qml-transform-elements
186     \brief The Rotation object provides a way to rotate an Item.
187
188     The Rotation object gives more control over rotation than using \l Item's \l{Item::rotation}{rotation} property.
189     Specifically, it allows (z axis) rotation to be relative to an arbitrary point.
190
191     The following example rotates a Rectangle around its interior point 25, 25:
192     \qml
193     Rectangle {
194         width: 100; height: 100
195         color: "blue"
196         transform: Rotation { origin.x: 25; origin.y: 25; angle: 45}
197     }
198     \endqml
199
200     Rotation also provides a way to specify 3D-like rotations for Items. For these types of
201     rotations you must specify the axis to rotate around in addition to the origin point.
202
203     The following example shows various 3D-like rotations applied to an \l Image.
204     \snippet doc/src/snippets/declarative/rotation.qml 0
205
206     \image axisrotation.png
207
208     \sa {declarative/ui-components/dialcontrol}{Dial Control example}, {declarative/toys/clocks}{Clocks example}
209 */
210
211 /*!
212     \qmlproperty real QtQuick2::Rotation::origin.x
213     \qmlproperty real QtQuick2::Rotation::origin.y
214
215     The origin point of the rotation (i.e., the point that stays fixed relative to the parent as
216     the rest of the item rotates). By default the origin is 0, 0.
217 */
218
219 /*!
220     \qmlproperty real QtQuick2::Rotation::axis.x
221     \qmlproperty real QtQuick2::Rotation::axis.y
222     \qmlproperty real QtQuick2::Rotation::axis.z
223
224     The axis to rotate around. For simple (2D) rotation around a point, you do not need to specify an axis,
225     as the default axis is the z axis (\c{ axis { x: 0; y: 0; z: 1 } }).
226
227     For a typical 3D-like rotation you will usually specify both the origin and the axis.
228
229     \image 3d-rotation-axis.png
230 */
231
232 /*!
233     \qmlproperty real QtQuick2::Rotation::angle
234
235     The angle to rotate, in degrees clockwise.
236 */
237
238 QSGTransformPrivate::QSGTransformPrivate()
239 {
240 }
241
242 QSGTransform::QSGTransform(QObject *parent)
243 : QObject(*(new QSGTransformPrivate), parent)
244 {
245 }
246
247 QSGTransform::QSGTransform(QSGTransformPrivate &dd, QObject *parent)
248 : QObject(dd, parent)
249 {
250 }
251
252 QSGTransform::~QSGTransform()
253 {
254     Q_D(QSGTransform);
255     for (int ii = 0; ii < d->items.count(); ++ii) {
256         QSGItemPrivate *p = QSGItemPrivate::get(d->items.at(ii));
257         p->transforms.removeOne(this);
258         p->dirty(QSGItemPrivate::Transform);
259     }
260 }
261
262 void QSGTransform::update()
263 {
264     Q_D(QSGTransform);
265     for (int ii = 0; ii < d->items.count(); ++ii) {
266         QSGItemPrivate *p = QSGItemPrivate::get(d->items.at(ii));
267         p->dirty(QSGItemPrivate::Transform);
268     }
269 }
270
271 QSGContents::QSGContents(QSGItem *item)
272 : m_item(item), m_x(0), m_y(0), m_width(0), m_height(0)
273 {
274     //### optimize
275     connect(this, SIGNAL(rectChanged(QRectF)), m_item, SIGNAL(childrenRectChanged(QRectF)));
276 }
277
278 QSGContents::~QSGContents()
279 {
280     QList<QSGItem *> children = m_item->childItems();
281     for (int i = 0; i < children.count(); ++i) {
282         QSGItem *child = children.at(i);
283         QSGItemPrivate::get(child)->removeItemChangeListener(this, QSGItemPrivate::Geometry | QSGItemPrivate::Destroyed);
284     }
285 }
286
287 QRectF QSGContents::rectF() const
288 {
289     return QRectF(m_x, m_y, m_width, m_height);
290 }
291
292 void QSGContents::calcHeight(QSGItem *changed)
293 {
294     qreal oldy = m_y;
295     qreal oldheight = m_height;
296
297     if (changed) {
298         qreal top = oldy;
299         qreal bottom = oldy + oldheight;
300         qreal y = changed->y();
301         if (y + changed->height() > bottom)
302             bottom = y + changed->height();
303         if (y < top)
304             top = y;
305         m_y = top;
306         m_height = bottom - top;
307     } else {
308         qreal top = FLT_MAX;
309         qreal bottom = 0;
310         QList<QSGItem *> children = m_item->childItems();
311         for (int i = 0; i < children.count(); ++i) {
312             QSGItem *child = children.at(i);
313             qreal y = child->y();
314             if (y + child->height() > bottom)
315                 bottom = y + child->height();
316             if (y < top)
317                 top = y;
318         }
319         if (!children.isEmpty())
320             m_y = top;
321         m_height = qMax(bottom - top, qreal(0.0));
322     }
323
324     if (m_height != oldheight || m_y != oldy)
325         emit rectChanged(rectF());
326 }
327
328 void QSGContents::calcWidth(QSGItem *changed)
329 {
330     qreal oldx = m_x;
331     qreal oldwidth = m_width;
332
333     if (changed) {
334         qreal left = oldx;
335         qreal right = oldx + oldwidth;
336         qreal x = changed->x();
337         if (x + changed->width() > right)
338             right = x + changed->width();
339         if (x < left)
340             left = x;
341         m_x = left;
342         m_width = right - left;
343     } else {
344         qreal left = FLT_MAX;
345         qreal right = 0;
346         QList<QSGItem *> children = m_item->childItems();
347         for (int i = 0; i < children.count(); ++i) {
348             QSGItem *child = children.at(i);
349             qreal x = child->x();
350             if (x + child->width() > right)
351                 right = x + child->width();
352             if (x < left)
353                 left = x;
354         }
355         if (!children.isEmpty())
356             m_x = left;
357         m_width = qMax(right - left, qreal(0.0));
358     }
359
360     if (m_width != oldwidth || m_x != oldx)
361         emit rectChanged(rectF());
362 }
363
364 void QSGContents::complete()
365 {
366     QList<QSGItem *> children = m_item->childItems();
367     for (int i = 0; i < children.count(); ++i) {
368         QSGItem *child = children.at(i);
369         QSGItemPrivate::get(child)->addItemChangeListener(this, QSGItemPrivate::Geometry | QSGItemPrivate::Destroyed);
370         //###what about changes to visibility?
371     }
372
373     calcGeometry();
374 }
375
376 void QSGContents::itemGeometryChanged(QSGItem *changed, const QRectF &newGeometry, const QRectF &oldGeometry)
377 {
378     Q_UNUSED(changed)
379     //### we can only pass changed if the left edge has moved left, or the right edge has moved right
380     if (newGeometry.width() != oldGeometry.width() || newGeometry.x() != oldGeometry.x())
381         calcWidth(/*changed*/);
382     if (newGeometry.height() != oldGeometry.height() || newGeometry.y() != oldGeometry.y())
383         calcHeight(/*changed*/);
384 }
385
386 void QSGContents::itemDestroyed(QSGItem *item)
387 {
388     if (item)
389         QSGItemPrivate::get(item)->removeItemChangeListener(this, QSGItemPrivate::Geometry | QSGItemPrivate::Destroyed);
390     calcGeometry();
391 }
392
393 void QSGContents::childRemoved(QSGItem *item)
394 {
395     if (item)
396         QSGItemPrivate::get(item)->removeItemChangeListener(this, QSGItemPrivate::Geometry | QSGItemPrivate::Destroyed);
397     calcGeometry();
398 }
399
400 void QSGContents::childAdded(QSGItem *item)
401 {
402     if (item)
403         QSGItemPrivate::get(item)->addItemChangeListener(this, QSGItemPrivate::Geometry | QSGItemPrivate::Destroyed);
404     calcWidth(item);
405     calcHeight(item);
406 }
407
408 QSGItemKeyFilter::QSGItemKeyFilter(QSGItem *item)
409 : m_processPost(false), m_next(0)
410 {
411     QSGItemPrivate *p = item?QSGItemPrivate::get(item):0;
412     if (p) {
413         m_next = p->keyHandler;
414         p->keyHandler = this;
415     }
416 }
417
418 QSGItemKeyFilter::~QSGItemKeyFilter()
419 {
420 }
421
422 void QSGItemKeyFilter::keyPressed(QKeyEvent *event, bool post)
423 {
424     if (m_next) m_next->keyPressed(event, post);
425 }
426
427 void QSGItemKeyFilter::keyReleased(QKeyEvent *event, bool post)
428 {
429     if (m_next) m_next->keyReleased(event, post);
430 }
431
432 void QSGItemKeyFilter::inputMethodEvent(QInputMethodEvent *event, bool post)
433 {
434     if (m_next)
435         m_next->inputMethodEvent(event, post);
436     else
437         event->ignore();
438 }
439
440 QVariant QSGItemKeyFilter::inputMethodQuery(Qt::InputMethodQuery query) const
441 {
442     if (m_next) return m_next->inputMethodQuery(query);
443     return QVariant();
444 }
445
446 void QSGItemKeyFilter::componentComplete()
447 {
448     if (m_next) m_next->componentComplete();
449 }
450 /*!
451     \qmlclass KeyNavigation QSGKeyNavigationAttached
452     \inqmlmodule QtQuick 2
453     \ingroup qml-basic-interaction-elements
454     \brief The KeyNavigation attached property supports key navigation by arrow keys.
455
456     Key-based user interfaces commonly allow the use of arrow keys to navigate between
457     focusable items.  The KeyNavigation attached property enables this behavior by providing a
458     convenient way to specify the item that should gain focus when an arrow or tab key is pressed.
459
460     The following example provides key navigation for a 2x2 grid of items:
461
462     \snippet doc/src/snippets/declarative/keynavigation.qml 0
463
464     The top-left item initially receives focus by setting \l {Item::}{focus} to
465     \c true. When an arrow key is pressed, the focus will move to the
466     appropriate item, as defined by the value that has been set for
467     the KeyNavigation \l left, \l right, \l up or \l down properties.
468
469     Note that if a KeyNavigation attached property receives the key press and release
470     events for a requested arrow or tab key, the event is accepted and does not
471     propagate any further.
472
473     By default, KeyNavigation receives key events after the item to which it is attached.
474     If the item accepts the key event, the KeyNavigation attached property will not
475     receive an event for that key.  Setting the \l priority property to
476     \c KeyNavigation.BeforeItem allows the event to be used for key navigation
477     before the item, rather than after.
478
479     If item to which the focus is switching is not enabled or visible, an attempt will
480     be made to skip this item and focus on the next. This is possible if there are
481     a chain of items with the same KeyNavigation handler. If multiple items in a row are not enabled
482     or visible, they will also be skipped.
483
484     KeyNavigation will implicitly set the other direction to return focus to this item. So if you set
485     \l left to another item, \l right will be set on that item's KeyNavigation to set focus back to this
486     item. However, if that item's KeyNavigation has had right explicitly set then no change will occur.
487     This means that the above example could have been written, with the same behaviour, without specifing
488     KeyNavigation.right or KeyNavigation.down for any of the items.
489
490     \sa {Keys}{Keys attached property}
491 */
492
493 /*!
494     \qmlproperty Item QtQuick2::KeyNavigation::left
495     \qmlproperty Item QtQuick2::KeyNavigation::right
496     \qmlproperty Item QtQuick2::KeyNavigation::up
497     \qmlproperty Item QtQuick2::KeyNavigation::down
498     \qmlproperty Item QtQuick2::KeyNavigation::tab
499     \qmlproperty Item QtQuick2::KeyNavigation::backtab
500
501     These properties hold the item to assign focus to
502     when the left, right, up or down cursor keys, or the
503     tab key are pressed.
504 */
505
506 /*!
507     \qmlproperty Item QtQuick2::KeyNavigation::tab
508     \qmlproperty Item QtQuick2::KeyNavigation::backtab
509
510     These properties hold the item to assign focus to
511     when the Tab key or Shift+Tab key combination (Backtab) are pressed.
512 */
513
514 QSGKeyNavigationAttached::QSGKeyNavigationAttached(QObject *parent)
515 : QObject(*(new QSGKeyNavigationAttachedPrivate), parent),
516   QSGItemKeyFilter(qobject_cast<QSGItem*>(parent))
517 {
518     m_processPost = true;
519 }
520
521 QSGKeyNavigationAttached *
522 QSGKeyNavigationAttached::qmlAttachedProperties(QObject *obj)
523 {
524     return new QSGKeyNavigationAttached(obj);
525 }
526
527 QSGItem *QSGKeyNavigationAttached::left() const
528 {
529     Q_D(const QSGKeyNavigationAttached);
530     return d->left;
531 }
532
533 void QSGKeyNavigationAttached::setLeft(QSGItem *i)
534 {
535     Q_D(QSGKeyNavigationAttached);
536     if (d->left == i)
537         return;
538     d->left = i;
539     d->leftSet = true;
540     QSGKeyNavigationAttached* other =
541             qobject_cast<QSGKeyNavigationAttached*>(qmlAttachedPropertiesObject<QSGKeyNavigationAttached>(i));
542     if (other && !other->d_func()->rightSet){
543         other->d_func()->right = qobject_cast<QSGItem*>(parent());
544         emit other->rightChanged();
545     }
546     emit leftChanged();
547 }
548
549 QSGItem *QSGKeyNavigationAttached::right() const
550 {
551     Q_D(const QSGKeyNavigationAttached);
552     return d->right;
553 }
554
555 void QSGKeyNavigationAttached::setRight(QSGItem *i)
556 {
557     Q_D(QSGKeyNavigationAttached);
558     if (d->right == i)
559         return;
560     d->right = i;
561     d->rightSet = true;
562     QSGKeyNavigationAttached* other =
563             qobject_cast<QSGKeyNavigationAttached*>(qmlAttachedPropertiesObject<QSGKeyNavigationAttached>(i));
564     if (other && !other->d_func()->leftSet){
565         other->d_func()->left = qobject_cast<QSGItem*>(parent());
566         emit other->leftChanged();
567     }
568     emit rightChanged();
569 }
570
571 QSGItem *QSGKeyNavigationAttached::up() const
572 {
573     Q_D(const QSGKeyNavigationAttached);
574     return d->up;
575 }
576
577 void QSGKeyNavigationAttached::setUp(QSGItem *i)
578 {
579     Q_D(QSGKeyNavigationAttached);
580     if (d->up == i)
581         return;
582     d->up = i;
583     d->upSet = true;
584     QSGKeyNavigationAttached* other =
585             qobject_cast<QSGKeyNavigationAttached*>(qmlAttachedPropertiesObject<QSGKeyNavigationAttached>(i));
586     if (other && !other->d_func()->downSet){
587         other->d_func()->down = qobject_cast<QSGItem*>(parent());
588         emit other->downChanged();
589     }
590     emit upChanged();
591 }
592
593 QSGItem *QSGKeyNavigationAttached::down() const
594 {
595     Q_D(const QSGKeyNavigationAttached);
596     return d->down;
597 }
598
599 void QSGKeyNavigationAttached::setDown(QSGItem *i)
600 {
601     Q_D(QSGKeyNavigationAttached);
602     if (d->down == i)
603         return;
604     d->down = i;
605     d->downSet = true;
606     QSGKeyNavigationAttached* other =
607             qobject_cast<QSGKeyNavigationAttached*>(qmlAttachedPropertiesObject<QSGKeyNavigationAttached>(i));
608     if(other && !other->d_func()->upSet){
609         other->d_func()->up = qobject_cast<QSGItem*>(parent());
610         emit other->upChanged();
611     }
612     emit downChanged();
613 }
614
615 QSGItem *QSGKeyNavigationAttached::tab() const
616 {
617     Q_D(const QSGKeyNavigationAttached);
618     return d->tab;
619 }
620
621 void QSGKeyNavigationAttached::setTab(QSGItem *i)
622 {
623     Q_D(QSGKeyNavigationAttached);
624     if (d->tab == i)
625         return;
626     d->tab = i;
627     d->tabSet = true;
628     QSGKeyNavigationAttached* other =
629             qobject_cast<QSGKeyNavigationAttached*>(qmlAttachedPropertiesObject<QSGKeyNavigationAttached>(i));
630     if(other && !other->d_func()->backtabSet){
631         other->d_func()->backtab = qobject_cast<QSGItem*>(parent());
632         emit other->backtabChanged();
633     }
634     emit tabChanged();
635 }
636
637 QSGItem *QSGKeyNavigationAttached::backtab() const
638 {
639     Q_D(const QSGKeyNavigationAttached);
640     return d->backtab;
641 }
642
643 void QSGKeyNavigationAttached::setBacktab(QSGItem *i)
644 {
645     Q_D(QSGKeyNavigationAttached);
646     if (d->backtab == i)
647         return;
648     d->backtab = i;
649     d->backtabSet = true;
650     QSGKeyNavigationAttached* other =
651             qobject_cast<QSGKeyNavigationAttached*>(qmlAttachedPropertiesObject<QSGKeyNavigationAttached>(i));
652     if(other && !other->d_func()->tabSet){
653         other->d_func()->tab = qobject_cast<QSGItem*>(parent());
654         emit other->tabChanged();
655     }
656     emit backtabChanged();
657 }
658
659 /*!
660     \qmlproperty enumeration QtQuick2::KeyNavigation::priority
661
662     This property determines whether the keys are processed before
663     or after the attached item's own key handling.
664
665     \list
666     \o KeyNavigation.BeforeItem - process the key events before normal
667     item key processing.  If the event is used for key navigation, it will be accepted and will not
668     be passed on to the item.
669     \o KeyNavigation.AfterItem (default) - process the key events after normal item key
670     handling.  If the item accepts the key event it will not be
671     handled by the KeyNavigation attached property handler.
672     \endlist
673 */
674 QSGKeyNavigationAttached::Priority QSGKeyNavigationAttached::priority() const
675 {
676     return m_processPost ? AfterItem : BeforeItem;
677 }
678
679 void QSGKeyNavigationAttached::setPriority(Priority order)
680 {
681     bool processPost = order == AfterItem;
682     if (processPost != m_processPost) {
683         m_processPost = processPost;
684         emit priorityChanged();
685     }
686 }
687
688 void QSGKeyNavigationAttached::keyPressed(QKeyEvent *event, bool post)
689 {
690     Q_D(QSGKeyNavigationAttached);
691     event->ignore();
692
693     if (post != m_processPost) {
694         QSGItemKeyFilter::keyPressed(event, post);
695         return;
696     }
697
698     bool mirror = false;
699     switch(event->key()) {
700     case Qt::Key_Left: {
701         if (QSGItem *parentItem = qobject_cast<QSGItem*>(parent()))
702             mirror = QSGItemPrivate::get(parentItem)->effectiveLayoutMirror;
703         QSGItem* leftItem = mirror ? d->right : d->left;
704         if (leftItem) {
705             setFocusNavigation(leftItem, mirror ? "right" : "left");
706             event->accept();
707         }
708         break;
709     }
710     case Qt::Key_Right: {
711         if (QSGItem *parentItem = qobject_cast<QSGItem*>(parent()))
712             mirror = QSGItemPrivate::get(parentItem)->effectiveLayoutMirror;
713         QSGItem* rightItem = mirror ? d->left : d->right;
714         if (rightItem) {
715             setFocusNavigation(rightItem, mirror ? "left" : "right");
716             event->accept();
717         }
718         break;
719     }
720     case Qt::Key_Up:
721         if (d->up) {
722             setFocusNavigation(d->up, "up");
723             event->accept();
724         }
725         break;
726     case Qt::Key_Down:
727         if (d->down) {
728             setFocusNavigation(d->down, "down");
729             event->accept();
730         }
731         break;
732     case Qt::Key_Tab:
733         if (d->tab) {
734             setFocusNavigation(d->tab, "tab");
735             event->accept();
736         }
737         break;
738     case Qt::Key_Backtab:
739         if (d->backtab) {
740             setFocusNavigation(d->backtab, "backtab");
741             event->accept();
742         }
743         break;
744     default:
745         break;
746     }
747
748     if (!event->isAccepted()) QSGItemKeyFilter::keyPressed(event, post);
749 }
750
751 void QSGKeyNavigationAttached::keyReleased(QKeyEvent *event, bool post)
752 {
753     Q_D(QSGKeyNavigationAttached);
754     event->ignore();
755
756     if (post != m_processPost) {
757         QSGItemKeyFilter::keyReleased(event, post);
758         return;
759     }
760
761     bool mirror = false;
762     switch(event->key()) {
763     case Qt::Key_Left:
764         if (QSGItem *parentItem = qobject_cast<QSGItem*>(parent()))
765             mirror = QSGItemPrivate::get(parentItem)->effectiveLayoutMirror;
766         if (mirror ? d->right : d->left)
767             event->accept();
768         break;
769     case Qt::Key_Right:
770         if (QSGItem *parentItem = qobject_cast<QSGItem*>(parent()))
771             mirror = QSGItemPrivate::get(parentItem)->effectiveLayoutMirror;
772         if (mirror ? d->left : d->right)
773             event->accept();
774         break;
775     case Qt::Key_Up:
776         if (d->up) {
777             event->accept();
778         }
779         break;
780     case Qt::Key_Down:
781         if (d->down) {
782             event->accept();
783         }
784         break;
785     case Qt::Key_Tab:
786         if (d->tab) {
787             event->accept();
788         }
789         break;
790     case Qt::Key_Backtab:
791         if (d->backtab) {
792             event->accept();
793         }
794         break;
795     default:
796         break;
797     }
798
799     if (!event->isAccepted()) QSGItemKeyFilter::keyReleased(event, post);
800 }
801
802 void QSGKeyNavigationAttached::setFocusNavigation(QSGItem *currentItem, const char *dir)
803 {
804     QSGItem *initialItem = currentItem;
805     bool isNextItem = false;
806     do {
807         isNextItem = false;
808         if (currentItem->isVisible() && currentItem->isEnabled()) {
809             currentItem->setFocus(true);
810         } else {
811             QObject *attached =
812                 qmlAttachedPropertiesObject<QSGKeyNavigationAttached>(currentItem, false);
813             if (attached) {
814                 QSGItem *tempItem = qvariant_cast<QSGItem*>(attached->property(dir));
815                 if (tempItem) {
816                     currentItem = tempItem;
817                     isNextItem = true;
818                 }
819             }
820         }
821     }
822     while (currentItem != initialItem && isNextItem);
823 }
824
825 const QSGKeysAttached::SigMap QSGKeysAttached::sigMap[] = {
826     { Qt::Key_Left, "leftPressed" },
827     { Qt::Key_Right, "rightPressed" },
828     { Qt::Key_Up, "upPressed" },
829     { Qt::Key_Down, "downPressed" },
830     { Qt::Key_Tab, "tabPressed" },
831     { Qt::Key_Backtab, "backtabPressed" },
832     { Qt::Key_Asterisk, "asteriskPressed" },
833     { Qt::Key_NumberSign, "numberSignPressed" },
834     { Qt::Key_Escape, "escapePressed" },
835     { Qt::Key_Return, "returnPressed" },
836     { Qt::Key_Enter, "enterPressed" },
837     { Qt::Key_Delete, "deletePressed" },
838     { Qt::Key_Space, "spacePressed" },
839     { Qt::Key_Back, "backPressed" },
840     { Qt::Key_Cancel, "cancelPressed" },
841     { Qt::Key_Select, "selectPressed" },
842     { Qt::Key_Yes, "yesPressed" },
843     { Qt::Key_No, "noPressed" },
844     { Qt::Key_Context1, "context1Pressed" },
845     { Qt::Key_Context2, "context2Pressed" },
846     { Qt::Key_Context3, "context3Pressed" },
847     { Qt::Key_Context4, "context4Pressed" },
848     { Qt::Key_Call, "callPressed" },
849     { Qt::Key_Hangup, "hangupPressed" },
850     { Qt::Key_Flip, "flipPressed" },
851     { Qt::Key_Menu, "menuPressed" },
852     { Qt::Key_VolumeUp, "volumeUpPressed" },
853     { Qt::Key_VolumeDown, "volumeDownPressed" },
854     { 0, 0 }
855 };
856
857 bool QSGKeysAttachedPrivate::isConnected(const char *signalName)
858 {
859     return isSignalConnected(signalIndex(signalName));
860 }
861
862 /*!
863     \qmlclass Keys QSGKeysAttached
864     \inqmlmodule QtQuick 2
865     \ingroup qml-basic-interaction-elements
866     \brief The Keys attached property provides key handling to Items.
867
868     All visual primitives support key handling via the Keys
869     attached property.  Keys can be handled via the onPressed
870     and onReleased signal properties.
871
872     The signal properties have a \l KeyEvent parameter, named
873     \e event which contains details of the event.  If a key is
874     handled \e event.accepted should be set to true to prevent the
875     event from propagating up the item hierarchy.
876
877     \section1 Example Usage
878
879     The following example shows how the general onPressed handler can
880     be used to test for a certain key; in this case, the left cursor
881     key:
882
883     \snippet doc/src/snippets/declarative/keys/keys-pressed.qml key item
884
885     Some keys may alternatively be handled via specific signal properties,
886     for example \e onSelectPressed.  These handlers automatically set
887     \e event.accepted to true.
888
889     \snippet doc/src/snippets/declarative/keys/keys-handler.qml key item
890
891     See \l{Qt::Key}{Qt.Key} for the list of keyboard codes.
892
893     \section1 Key Handling Priorities
894
895     The Keys attached property can be configured to handle key events
896     before or after the item it is attached to. This makes it possible
897     to intercept events in order to override an item's default behavior,
898     or act as a fallback for keys not handled by the item.
899
900     If \l priority is Keys.BeforeItem (default) the order of key event processing is:
901
902     \list 1
903     \o Items specified in \c forwardTo
904     \o specific key handlers, e.g. onReturnPressed
905     \o onKeyPress, onKeyRelease handlers
906     \o Item specific key handling, e.g. TextInput key handling
907     \o parent item
908     \endlist
909
910     If priority is Keys.AfterItem the order of key event processing is:
911
912     \list 1
913     \o Item specific key handling, e.g. TextInput key handling
914     \o Items specified in \c forwardTo
915     \o specific key handlers, e.g. onReturnPressed
916     \o onKeyPress, onKeyRelease handlers
917     \o parent item
918     \endlist
919
920     If the event is accepted during any of the above steps, key
921     propagation stops.
922
923     \sa KeyEvent, {KeyNavigation}{KeyNavigation attached property}
924 */
925
926 /*!
927     \qmlproperty bool QtQuick2::Keys::enabled
928
929     This flags enables key handling if true (default); otherwise
930     no key handlers will be called.
931 */
932
933 /*!
934     \qmlproperty enumeration QtQuick2::Keys::priority
935
936     This property determines whether the keys are processed before
937     or after the attached item's own key handling.
938
939     \list
940     \o Keys.BeforeItem (default) - process the key events before normal
941     item key processing.  If the event is accepted it will not
942     be passed on to the item.
943     \o Keys.AfterItem - process the key events after normal item key
944     handling.  If the item accepts the key event it will not be
945     handled by the Keys attached property handler.
946     \endlist
947 */
948
949 /*!
950     \qmlproperty list<Object> QtQuick2::Keys::forwardTo
951
952     This property provides a way to forward key presses, key releases, and keyboard input
953     coming from input methods to other items. This can be useful when you want
954     one item to handle some keys (e.g. the up and down arrow keys), and another item to
955     handle other keys (e.g. the left and right arrow keys).  Once an item that has been
956     forwarded keys accepts the event it is no longer forwarded to items later in the
957     list.
958
959     This example forwards key events to two lists:
960     \qml
961     Item {
962         ListView {
963             id: list1
964             // ...
965         }
966         ListView {
967             id: list2
968             // ...
969         }
970         Keys.forwardTo: [list1, list2]
971         focus: true
972     }
973     \endqml
974 */
975
976 /*!
977     \qmlsignal QtQuick2::Keys::onPressed(KeyEvent event)
978
979     This handler is called when a key has been pressed. The \a event
980     parameter provides information about the event.
981 */
982
983 /*!
984     \qmlsignal QtQuick2::Keys::onReleased(KeyEvent event)
985
986     This handler is called when a key has been released. The \a event
987     parameter provides information about the event.
988 */
989
990 /*!
991     \qmlsignal QtQuick2::Keys::onDigit0Pressed(KeyEvent event)
992
993     This handler is called when the digit '0' has been pressed. The \a event
994     parameter provides information about the event.
995 */
996
997 /*!
998     \qmlsignal QtQuick2::Keys::onDigit1Pressed(KeyEvent event)
999
1000     This handler is called when the digit '1' has been pressed. The \a event
1001     parameter provides information about the event.
1002 */
1003
1004 /*!
1005     \qmlsignal QtQuick2::Keys::onDigit2Pressed(KeyEvent event)
1006
1007     This handler is called when the digit '2' has been pressed. The \a event
1008     parameter provides information about the event.
1009 */
1010
1011 /*!
1012     \qmlsignal QtQuick2::Keys::onDigit3Pressed(KeyEvent event)
1013
1014     This handler is called when the digit '3' has been pressed. The \a event
1015     parameter provides information about the event.
1016 */
1017
1018 /*!
1019     \qmlsignal QtQuick2::Keys::onDigit4Pressed(KeyEvent event)
1020
1021     This handler is called when the digit '4' has been pressed. The \a event
1022     parameter provides information about the event.
1023 */
1024
1025 /*!
1026     \qmlsignal QtQuick2::Keys::onDigit5Pressed(KeyEvent event)
1027
1028     This handler is called when the digit '5' has been pressed. The \a event
1029     parameter provides information about the event.
1030 */
1031
1032 /*!
1033     \qmlsignal QtQuick2::Keys::onDigit6Pressed(KeyEvent event)
1034
1035     This handler is called when the digit '6' has been pressed. The \a event
1036     parameter provides information about the event.
1037 */
1038
1039 /*!
1040     \qmlsignal QtQuick2::Keys::onDigit7Pressed(KeyEvent event)
1041
1042     This handler is called when the digit '7' has been pressed. The \a event
1043     parameter provides information about the event.
1044 */
1045
1046 /*!
1047     \qmlsignal QtQuick2::Keys::onDigit8Pressed(KeyEvent event)
1048
1049     This handler is called when the digit '8' has been pressed. The \a event
1050     parameter provides information about the event.
1051 */
1052
1053 /*!
1054     \qmlsignal QtQuick2::Keys::onDigit9Pressed(KeyEvent event)
1055
1056     This handler is called when the digit '9' has been pressed. The \a event
1057     parameter provides information about the event.
1058 */
1059
1060 /*!
1061     \qmlsignal QtQuick2::Keys::onLeftPressed(KeyEvent event)
1062
1063     This handler is called when the Left arrow has been pressed. The \a event
1064     parameter provides information about the event.
1065 */
1066
1067 /*!
1068     \qmlsignal QtQuick2::Keys::onRightPressed(KeyEvent event)
1069
1070     This handler is called when the Right arrow has been pressed. The \a event
1071     parameter provides information about the event.
1072 */
1073
1074 /*!
1075     \qmlsignal QtQuick2::Keys::onUpPressed(KeyEvent event)
1076
1077     This handler is called when the Up arrow has been pressed. The \a event
1078     parameter provides information about the event.
1079 */
1080
1081 /*!
1082     \qmlsignal QtQuick2::Keys::onDownPressed(KeyEvent event)
1083
1084     This handler is called when the Down arrow has been pressed. The \a event
1085     parameter provides information about the event.
1086 */
1087
1088 /*!
1089     \qmlsignal QtQuick2::Keys::onTabPressed(KeyEvent event)
1090
1091     This handler is called when the Tab key has been pressed. The \a event
1092     parameter provides information about the event.
1093 */
1094
1095 /*!
1096     \qmlsignal QtQuick2::Keys::onBacktabPressed(KeyEvent event)
1097
1098     This handler is called when the Shift+Tab key combination (Backtab) has
1099     been pressed. The \a event parameter provides information about the event.
1100 */
1101
1102 /*!
1103     \qmlsignal QtQuick2::Keys::onAsteriskPressed(KeyEvent event)
1104
1105     This handler is called when the Asterisk '*' has been pressed. The \a event
1106     parameter provides information about the event.
1107 */
1108
1109 /*!
1110     \qmlsignal QtQuick2::Keys::onEscapePressed(KeyEvent event)
1111
1112     This handler is called when the Escape key has been pressed. The \a event
1113     parameter provides information about the event.
1114 */
1115
1116 /*!
1117     \qmlsignal QtQuick2::Keys::onReturnPressed(KeyEvent event)
1118
1119     This handler is called when the Return key has been pressed. The \a event
1120     parameter provides information about the event.
1121 */
1122
1123 /*!
1124     \qmlsignal QtQuick2::Keys::onEnterPressed(KeyEvent event)
1125
1126     This handler is called when the Enter key has been pressed. The \a event
1127     parameter provides information about the event.
1128 */
1129
1130 /*!
1131     \qmlsignal QtQuick2::Keys::onDeletePressed(KeyEvent event)
1132
1133     This handler is called when the Delete key has been pressed. The \a event
1134     parameter provides information about the event.
1135 */
1136
1137 /*!
1138     \qmlsignal QtQuick2::Keys::onSpacePressed(KeyEvent event)
1139
1140     This handler is called when the Space key has been pressed. The \a event
1141     parameter provides information about the event.
1142 */
1143
1144 /*!
1145     \qmlsignal QtQuick2::Keys::onBackPressed(KeyEvent event)
1146
1147     This handler is called when the Back key has been pressed. The \a event
1148     parameter provides information about the event.
1149 */
1150
1151 /*!
1152     \qmlsignal QtQuick2::Keys::onCancelPressed(KeyEvent event)
1153
1154     This handler is called when the Cancel key has been pressed. The \a event
1155     parameter provides information about the event.
1156 */
1157
1158 /*!
1159     \qmlsignal QtQuick2::Keys::onSelectPressed(KeyEvent event)
1160
1161     This handler is called when the Select key has been pressed. The \a event
1162     parameter provides information about the event.
1163 */
1164
1165 /*!
1166     \qmlsignal QtQuick2::Keys::onYesPressed(KeyEvent event)
1167
1168     This handler is called when the Yes key has been pressed. The \a event
1169     parameter provides information about the event.
1170 */
1171
1172 /*!
1173     \qmlsignal QtQuick2::Keys::onNoPressed(KeyEvent event)
1174
1175     This handler is called when the No key has been pressed. The \a event
1176     parameter provides information about the event.
1177 */
1178
1179 /*!
1180     \qmlsignal QtQuick2::Keys::onContext1Pressed(KeyEvent event)
1181
1182     This handler is called when the Context1 key has been pressed. The \a event
1183     parameter provides information about the event.
1184 */
1185
1186 /*!
1187     \qmlsignal QtQuick2::Keys::onContext2Pressed(KeyEvent event)
1188
1189     This handler is called when the Context2 key has been pressed. The \a event
1190     parameter provides information about the event.
1191 */
1192
1193 /*!
1194     \qmlsignal QtQuick2::Keys::onContext3Pressed(KeyEvent event)
1195
1196     This handler is called when the Context3 key has been pressed. The \a event
1197     parameter provides information about the event.
1198 */
1199
1200 /*!
1201     \qmlsignal QtQuick2::Keys::onContext4Pressed(KeyEvent event)
1202
1203     This handler is called when the Context4 key has been pressed. The \a event
1204     parameter provides information about the event.
1205 */
1206
1207 /*!
1208     \qmlsignal QtQuick2::Keys::onCallPressed(KeyEvent event)
1209
1210     This handler is called when the Call key has been pressed. The \a event
1211     parameter provides information about the event.
1212 */
1213
1214 /*!
1215     \qmlsignal QtQuick2::Keys::onHangupPressed(KeyEvent event)
1216
1217     This handler is called when the Hangup key has been pressed. The \a event
1218     parameter provides information about the event.
1219 */
1220
1221 /*!
1222     \qmlsignal QtQuick2::Keys::onFlipPressed(KeyEvent event)
1223
1224     This handler is called when the Flip key has been pressed. The \a event
1225     parameter provides information about the event.
1226 */
1227
1228 /*!
1229     \qmlsignal QtQuick2::Keys::onMenuPressed(KeyEvent event)
1230
1231     This handler is called when the Menu key has been pressed. The \a event
1232     parameter provides information about the event.
1233 */
1234
1235 /*!
1236     \qmlsignal QtQuick2::Keys::onVolumeUpPressed(KeyEvent event)
1237
1238     This handler is called when the VolumeUp key has been pressed. The \a event
1239     parameter provides information about the event.
1240 */
1241
1242 /*!
1243     \qmlsignal QtQuick2::Keys::onVolumeDownPressed(KeyEvent event)
1244
1245     This handler is called when the VolumeDown key has been pressed. The \a event
1246     parameter provides information about the event.
1247 */
1248
1249 QSGKeysAttached::QSGKeysAttached(QObject *parent)
1250 : QObject(*(new QSGKeysAttachedPrivate), parent),
1251   QSGItemKeyFilter(qobject_cast<QSGItem*>(parent))
1252 {
1253     Q_D(QSGKeysAttached);
1254     m_processPost = false;
1255     d->item = qobject_cast<QSGItem*>(parent);
1256 }
1257
1258 QSGKeysAttached::~QSGKeysAttached()
1259 {
1260 }
1261
1262 QSGKeysAttached::Priority QSGKeysAttached::priority() const
1263 {
1264     return m_processPost ? AfterItem : BeforeItem;
1265 }
1266
1267 void QSGKeysAttached::setPriority(Priority order)
1268 {
1269     bool processPost = order == AfterItem;
1270     if (processPost != m_processPost) {
1271         m_processPost = processPost;
1272         emit priorityChanged();
1273     }
1274 }
1275
1276 void QSGKeysAttached::componentComplete()
1277 {
1278     Q_D(QSGKeysAttached);
1279     if (d->item) {
1280         for (int ii = 0; ii < d->targets.count(); ++ii) {
1281             QSGItem *targetItem = d->targets.at(ii);
1282             if (targetItem && (targetItem->flags() & QSGItem::ItemAcceptsInputMethod)) {
1283                 d->item->setFlag(QSGItem::ItemAcceptsInputMethod);
1284                 break;
1285             }
1286         }
1287     }
1288 }
1289
1290 void QSGKeysAttached::keyPressed(QKeyEvent *event, bool post)
1291 {
1292     Q_D(QSGKeysAttached);
1293     if (post != m_processPost || !d->enabled || d->inPress) {
1294         event->ignore();
1295         QSGItemKeyFilter::keyPressed(event, post);
1296         return;
1297     }
1298
1299     // first process forwards
1300     if (d->item && d->item->canvas()) {
1301         d->inPress = true;
1302         for (int ii = 0; ii < d->targets.count(); ++ii) {
1303             QSGItem *i = d->targets.at(ii);
1304             if (i && i->isVisible()) {
1305                 d->item->canvas()->sendEvent(i, event);
1306                 if (event->isAccepted()) {
1307                     d->inPress = false;
1308                     return;
1309                 }
1310             }
1311         }
1312         d->inPress = false;
1313     }
1314
1315     QSGKeyEvent ke(*event);
1316     QByteArray keySignal = keyToSignal(event->key());
1317     if (!keySignal.isEmpty()) {
1318         keySignal += "(QSGKeyEvent*)";
1319         if (d->isConnected(keySignal)) {
1320             // If we specifically handle a key then default to accepted
1321             ke.setAccepted(true);
1322             int idx = QSGKeysAttached::staticMetaObject.indexOfSignal(keySignal);
1323             metaObject()->method(idx).invoke(this, Qt::DirectConnection, Q_ARG(QSGKeyEvent*, &ke));
1324         }
1325     }
1326     if (!ke.isAccepted())
1327         emit pressed(&ke);
1328     event->setAccepted(ke.isAccepted());
1329
1330     if (!event->isAccepted()) QSGItemKeyFilter::keyPressed(event, post);
1331 }
1332
1333 void QSGKeysAttached::keyReleased(QKeyEvent *event, bool post)
1334 {
1335     Q_D(QSGKeysAttached);
1336     if (post != m_processPost || !d->enabled || d->inRelease) {
1337         event->ignore();
1338         QSGItemKeyFilter::keyReleased(event, post);
1339         return;
1340     }
1341
1342     if (d->item && d->item->canvas()) {
1343         d->inRelease = true;
1344         for (int ii = 0; ii < d->targets.count(); ++ii) {
1345             QSGItem *i = d->targets.at(ii);
1346             if (i && i->isVisible()) {
1347                 d->item->canvas()->sendEvent(i, event);
1348                 if (event->isAccepted()) {
1349                     d->inRelease = false;
1350                     return;
1351                 }
1352             }
1353         }
1354         d->inRelease = false;
1355     }
1356
1357     QSGKeyEvent ke(*event);
1358     emit released(&ke);
1359     event->setAccepted(ke.isAccepted());
1360
1361     if (!event->isAccepted()) QSGItemKeyFilter::keyReleased(event, post);
1362 }
1363
1364 void QSGKeysAttached::inputMethodEvent(QInputMethodEvent *event, bool post)
1365 {
1366     Q_D(QSGKeysAttached);
1367     if (post == m_processPost && d->item && !d->inIM && d->item->canvas()) {
1368         d->inIM = true;
1369         for (int ii = 0; ii < d->targets.count(); ++ii) {
1370             QSGItem *i = d->targets.at(ii);
1371             if (i && i->isVisible() && (i->flags() & QSGItem::ItemAcceptsInputMethod)) {
1372                 d->item->canvas()->sendEvent(i, event);
1373                 if (event->isAccepted()) {
1374                     d->imeItem = i;
1375                     d->inIM = false;
1376                     return;
1377                 }
1378             }
1379         }
1380         d->inIM = false;
1381     }
1382     QSGItemKeyFilter::inputMethodEvent(event, post);
1383 }
1384
1385 QVariant QSGKeysAttached::inputMethodQuery(Qt::InputMethodQuery query) const
1386 {
1387     Q_D(const QSGKeysAttached);
1388     if (d->item) {
1389         for (int ii = 0; ii < d->targets.count(); ++ii) {
1390             QSGItem *i = d->targets.at(ii);
1391             if (i && i->isVisible() && (i->flags() & QSGItem::ItemAcceptsInputMethod) && i == d->imeItem) {
1392                 //### how robust is i == d->imeItem check?
1393                 QVariant v = i->inputMethodQuery(query);
1394                 if (v.userType() == QVariant::RectF)
1395                     v = d->item->mapRectFromItem(i, v.toRectF());  //### cost?
1396                 return v;
1397             }
1398         }
1399     }
1400     return QSGItemKeyFilter::inputMethodQuery(query);
1401 }
1402
1403 QSGKeysAttached *QSGKeysAttached::qmlAttachedProperties(QObject *obj)
1404 {
1405     return new QSGKeysAttached(obj);
1406 }
1407
1408 /*!
1409     \qmlclass LayoutMirroring QSGLayoutMirroringAttached
1410     \inqmlmodule QtQuick 2
1411     \ingroup qml-utility-elements
1412     \brief The LayoutMirroring attached property is used to mirror layout behavior.
1413
1414     The LayoutMirroring attached property is used to horizontally mirror \l {anchor-layout}{Item anchors},
1415     \l{Using QML Positioner and Repeater Items}{positioner} elements (such as \l Row and \l Grid)
1416     and views (such as \l GridView and horizontal \l ListView). Mirroring is a visual change: left
1417     anchors become right anchors, and positioner elements like \l Grid and \l Row reverse the
1418     horizontal layout of child items.
1419
1420     Mirroring is enabled for an item by setting the \l enabled property to true. By default, this
1421     only affects the item itself; setting the \l childrenInherit property to true propagates the mirroring
1422     behavior to all child elements as well. If the \c LayoutMirroring attached property has not been defined
1423     for an item, mirroring is not enabled.
1424
1425     The following example shows mirroring in action. The \l Row below is specified as being anchored
1426     to the left of its parent. However, since mirroring has been enabled, the anchor is horizontally
1427     reversed and it is now anchored to the right. Also, since items in a \l Row are positioned
1428     from left to right by default, they are now positioned from right to left instead, as demonstrated
1429     by the numbering and opacity of the items:
1430
1431     \snippet doc/src/snippets/declarative/layoutmirroring.qml 0
1432
1433     \image layoutmirroring.png
1434
1435     Layout mirroring is useful when it is necessary to support both left-to-right and right-to-left
1436     layout versions of an application to target different language areas. The \l childrenInherit
1437     property allows layout mirroring to be applied without manually setting layout configurations
1438     for every item in an application. Keep in mind, however, that mirroring does not affect any
1439     positioning that is defined by the \l Item \l {Item::}{x} coordinate value, so even with
1440     mirroring enabled, it will often be necessary to apply some layout fixes to support the
1441     desired layout direction. Also, it may be necessary to disable the mirroring of individual
1442     child items (by setting \l {enabled}{LayoutMirroring.enabled} to false for such items) if
1443     mirroring is not the desired behavior, or if the child item already implements mirroring in
1444     some custom way.
1445
1446     See \l {QML Right-to-left User Interfaces} for further details on using \c LayoutMirroring and
1447     other related features to implement right-to-left support for an application.
1448 */
1449
1450 /*!
1451     \qmlproperty bool QtQuick2::LayoutMirroring::enabled
1452
1453     This property holds whether the item's layout is mirrored horizontally. Setting this to true
1454     horizontally reverses \l {anchor-layout}{anchor} settings such that left anchors become right,
1455     and right anchors become left. For \l{Using QML Positioner and Repeater Items}{positioner} elements
1456     (such as \l Row and \l Grid) and view elements (such as \l {GridView}{GridView} and \l {ListView}{ListView})
1457     this also mirrors the horizontal layout direction of the item.
1458
1459     The default value is false.
1460 */
1461
1462 /*!
1463     \qmlproperty bool QtQuick2::LayoutMirroring::childrenInherit
1464
1465     This property holds whether the \l {enabled}{LayoutMirroring.enabled} value for this item
1466     is inherited by its children.
1467
1468     The default value is false.
1469 */
1470
1471
1472 QSGLayoutMirroringAttached::QSGLayoutMirroringAttached(QObject *parent) : QObject(parent), itemPrivate(0)
1473 {
1474     if (QSGItem *item = qobject_cast<QSGItem*>(parent)) {
1475         itemPrivate = QSGItemPrivate::get(item);
1476         itemPrivate->attachedLayoutDirection = this;
1477     } else
1478         qmlInfo(parent) << tr("LayoutDirection attached property only works with Items");
1479 }
1480
1481 QSGLayoutMirroringAttached * QSGLayoutMirroringAttached::qmlAttachedProperties(QObject *object)
1482 {
1483     return new QSGLayoutMirroringAttached(object);
1484 }
1485
1486 bool QSGLayoutMirroringAttached::enabled() const
1487 {
1488     return itemPrivate ? itemPrivate->effectiveLayoutMirror : false;
1489 }
1490
1491 void QSGLayoutMirroringAttached::setEnabled(bool enabled)
1492 {
1493     if (!itemPrivate)
1494         return;
1495
1496     itemPrivate->isMirrorImplicit = false;
1497     if (enabled != itemPrivate->effectiveLayoutMirror) {
1498         itemPrivate->setLayoutMirror(enabled);
1499         if (itemPrivate->inheritMirrorFromItem)
1500              itemPrivate->resolveLayoutMirror();
1501     }
1502 }
1503
1504 void QSGLayoutMirroringAttached::resetEnabled()
1505 {
1506     if (itemPrivate && !itemPrivate->isMirrorImplicit) {
1507         itemPrivate->isMirrorImplicit = true;
1508         itemPrivate->resolveLayoutMirror();
1509     }
1510 }
1511
1512 bool QSGLayoutMirroringAttached::childrenInherit() const
1513 {
1514     return itemPrivate ? itemPrivate->inheritMirrorFromItem : false;
1515 }
1516
1517 void QSGLayoutMirroringAttached::setChildrenInherit(bool childrenInherit) {
1518     if (itemPrivate && childrenInherit != itemPrivate->inheritMirrorFromItem) {
1519         itemPrivate->inheritMirrorFromItem = childrenInherit;
1520         itemPrivate->resolveLayoutMirror();
1521         childrenInheritChanged();
1522     }
1523 }
1524
1525 void QSGItemPrivate::resolveLayoutMirror()
1526 {
1527     Q_Q(QSGItem);
1528     if (QSGItem *parentItem = q->parentItem()) {
1529         QSGItemPrivate *parentPrivate = QSGItemPrivate::get(parentItem);
1530         setImplicitLayoutMirror(parentPrivate->inheritedLayoutMirror, parentPrivate->inheritMirrorFromParent);
1531     } else {
1532         setImplicitLayoutMirror(isMirrorImplicit ? false : effectiveLayoutMirror, inheritMirrorFromItem);
1533     }
1534 }
1535
1536 void QSGItemPrivate::setImplicitLayoutMirror(bool mirror, bool inherit)
1537 {
1538     inherit = inherit || inheritMirrorFromItem;
1539     if (!isMirrorImplicit && inheritMirrorFromItem)
1540         mirror = effectiveLayoutMirror;
1541     if (mirror == inheritedLayoutMirror && inherit == inheritMirrorFromParent)
1542         return;
1543
1544     inheritMirrorFromParent = inherit;
1545     inheritedLayoutMirror = inheritMirrorFromParent ? mirror : false;
1546
1547     if (isMirrorImplicit)
1548         setLayoutMirror(inherit ? inheritedLayoutMirror : false);
1549     for (int i = 0; i < childItems.count(); ++i) {
1550         if (QSGItem *child = qobject_cast<QSGItem *>(childItems.at(i))) {
1551             QSGItemPrivate *childPrivate = QSGItemPrivate::get(child);
1552             childPrivate->setImplicitLayoutMirror(inheritedLayoutMirror, inheritMirrorFromParent);
1553         }
1554     }
1555 }
1556
1557 void QSGItemPrivate::setLayoutMirror(bool mirror)
1558 {
1559     if (mirror != effectiveLayoutMirror) {
1560         effectiveLayoutMirror = mirror;
1561         if (_anchors) {
1562             QSGAnchorsPrivate *anchor_d = QSGAnchorsPrivate::get(_anchors);
1563             anchor_d->fillChanged();
1564             anchor_d->centerInChanged();
1565             anchor_d->updateHorizontalAnchors();
1566             emit _anchors->mirroredChanged();
1567         }
1568         mirrorChange();
1569         if (attachedLayoutDirection) {
1570             emit attachedLayoutDirection->enabledChanged();
1571         }
1572     }
1573 }
1574
1575 /*!
1576     \class QSGItem
1577     \brief The QSGItem class provides the most basic of all visual items in QML.
1578
1579     All visual items in Qt Declarative inherit from QSGItem.  Although QSGItem
1580     has no visual appearance, it defines all the properties that are
1581     common across visual items - such as the x and y position, the
1582     width and height, \l {anchor-layout}{anchoring} and key handling.
1583
1584     You can subclass QSGItem to provide your own custom visual item that inherits
1585     these features. Note that, because it does not draw anything, QSGItem sets the
1586     QGraphicsItem::ItemHasNoContents flag. If you subclass QSGItem to create a visual
1587     item, you will need to unset this flag.
1588
1589 */
1590
1591 /*!
1592     \qmlclass Item QSGItem
1593     \inqmlmodule QtQuick 2
1594     \ingroup qml-basic-visual-elements
1595     \brief The Item is the most basic of all visual items in QML.
1596
1597     All visual items in Qt Declarative inherit from Item.  Although Item
1598     has no visual appearance, it defines all the properties that are
1599     common across visual items - such as the x and y position, the
1600     width and height, \l {anchor-layout}{anchoring} and key handling.
1601
1602     Item is also useful for grouping items together.
1603
1604     \qml
1605     Item {
1606         Image {
1607             source: "tile.png"
1608         }
1609         Image {
1610             x: 80
1611             width: 100
1612             height: 100
1613             source: "tile.png"
1614         }
1615         Image {
1616             x: 190
1617             width: 100
1618             height: 100
1619             fillMode: Image.Tile
1620             source: "tile.png"
1621         }
1622     }
1623     \endqml
1624
1625
1626     \section1 Key Handling
1627
1628     Key handling is available to all Item-based visual elements via the \l {Keys}{Keys}
1629     attached property.  The \e Keys attached property provides basic handlers such
1630     as \l {Keys::onPressed}{onPressed} and \l {Keys::onReleased}{onReleased},
1631     as well as handlers for specific keys, such as
1632     \l {Keys::onCancelPressed}{onCancelPressed}.  The example below
1633     assigns \l {qmlfocus}{focus} to the item and handles
1634     the Left key via the general \e onPressed handler and the Select key via the
1635     onSelectPressed handler:
1636
1637     \qml
1638     Item {
1639         focus: true
1640         Keys.onPressed: {
1641             if (event.key == Qt.Key_Left) {
1642                 console.log("move left");
1643                 event.accepted = true;
1644             }
1645         }
1646         Keys.onSelectPressed: console.log("Selected");
1647     }
1648     \endqml
1649
1650     See the \l {Keys}{Keys} attached property for detailed documentation.
1651
1652     \section1 Layout Mirroring
1653
1654     Item layouts can be mirrored using the \l {LayoutMirroring}{LayoutMirroring} attached property.
1655
1656 */
1657
1658 /*!
1659     \fn void QSGItem::childrenRectChanged(const QRectF &)
1660     \internal
1661 */
1662
1663 /*!
1664     \fn void QSGItem::baselineOffsetChanged(qreal)
1665     \internal
1666 */
1667
1668 /*!
1669     \fn void QSGItem::stateChanged(const QString &state)
1670     \internal
1671 */
1672
1673 /*!
1674     \fn void QSGItem::parentChanged(QSGItem *)
1675     \internal
1676 */
1677
1678 /*!
1679     \fn void QSGItem::smoothChanged(bool)
1680     \internal
1681 */
1682
1683 /*!
1684     \fn void QSGItem::clipChanged(bool)
1685     \internal
1686 */
1687
1688 /*! \fn void QSGItem::transformOriginChanged(TransformOrigin)
1689   \internal
1690 */
1691
1692 /*!
1693     \fn void QSGItem::focusChanged(bool)
1694     \internal
1695 */
1696
1697 /*!
1698     \fn void QSGItem::activeFocusChanged(bool)
1699     \internal
1700 */
1701 /*!
1702     \fn QSGItem::QSGItem(QSGItem *parent)
1703
1704     Constructs a QSGItem with the given \a parent.
1705 */
1706 QSGItem::QSGItem(QSGItem* parent)
1707 : QObject(*(new QSGItemPrivate), parent)
1708 {
1709     Q_D(QSGItem);
1710     d->init(parent);
1711 }
1712
1713 /*! \internal
1714 */
1715 QSGItem::QSGItem(QSGItemPrivate &dd, QSGItem *parent)
1716 : QObject(dd, parent)
1717 {
1718     Q_D(QSGItem);
1719     d->init(parent);
1720 }
1721
1722 #ifndef QT_NO_DEBUG
1723 static int qt_item_count = 0;
1724
1725 static void qt_print_item_count()
1726 {
1727     qDebug("Number of leaked items: %i", qt_item_count);
1728     qt_item_count = -1;
1729 }
1730 #endif
1731
1732 /*!
1733     Destroys the QSGItem.
1734 */
1735 QSGItem::~QSGItem()
1736 {
1737 #ifndef QT_NO_DEBUG
1738     --qt_item_count;
1739     if (qt_item_count < 0)
1740         qDebug("Item destroyed after qt_print_item_count() was called.");
1741 #endif
1742
1743     Q_D(QSGItem);
1744
1745     if (d->parentItem)
1746         setParentItem(0);
1747     else if (d->canvas && d->itemNodeInstance)
1748         QSGCanvasPrivate::get(d->canvas)->cleanup(d->itemNodeInstance); // cleanup root
1749     // XXX todo - optimize
1750     while (!d->childItems.isEmpty())
1751         d->childItems.first()->setParentItem(0);
1752
1753     for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
1754         QSGAnchorsPrivate *anchor = d->changeListeners.at(ii).listener->anchorPrivate();
1755         if (anchor)
1756             anchor->clearItem(this);
1757     }
1758
1759     // XXX todo - the original checks if the parent is being destroyed
1760     for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
1761         QSGAnchorsPrivate *anchor = d->changeListeners.at(ii).listener->anchorPrivate();
1762         if (anchor && anchor->item && anchor->item->parent() != this) //child will be deleted anyway
1763             anchor->updateOnComplete();
1764     }
1765
1766     for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
1767         const QSGItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
1768         if (change.types & QSGItemPrivate::Destroyed)
1769             change.listener->itemDestroyed(this);
1770     }
1771     d->changeListeners.clear();
1772     delete d->_anchorLines; d->_anchorLines = 0;
1773     delete d->_anchors; d->_anchors = 0;
1774     delete d->_stateGroup; d->_stateGroup = 0;
1775     delete d->_contents; d->_contents = 0;
1776 }
1777
1778 /*!
1779     \qmlproperty enumeration QtQuick2::Item::transformOrigin
1780     This property holds the origin point around which scale and rotation transform.
1781
1782     Nine transform origins are available, as shown in the image below.
1783
1784     \image declarative-transformorigin.png
1785
1786     This example rotates an image around its bottom-right corner.
1787     \qml
1788     Image {
1789         source: "myimage.png"
1790         transformOrigin: Item.BottomRight
1791         rotation: 45
1792     }
1793     \endqml
1794
1795     The default transform origin is \c Item.Center.
1796
1797     To set an arbitrary transform origin point use the \l Scale or \l Rotation
1798     transform elements.
1799 */
1800
1801 /*!
1802     \qmlproperty Item QtQuick2::Item::parent
1803     This property holds the parent of the item.
1804 */
1805
1806 /*!
1807     \property QSGItem::parent
1808     This property holds the parent of the item.
1809 */
1810 void QSGItem::setParentItem(QSGItem *parentItem)
1811 {
1812     Q_D(QSGItem);
1813     if (parentItem == d->parentItem)
1814         return;
1815
1816     d->removeFromDirtyList();
1817
1818     QSGItem *oldParentItem = d->parentItem;
1819     QSGItem *scopeFocusedItem = 0;
1820
1821     if (oldParentItem) {
1822         QSGItemPrivate *op = QSGItemPrivate::get(oldParentItem);
1823
1824         QSGItem *scopeItem = 0;
1825
1826         if (d->canvas && hasFocus()) {
1827             scopeItem = oldParentItem;
1828             while (!scopeItem->isFocusScope()) scopeItem = scopeItem->parentItem();
1829             scopeFocusedItem = this;
1830         } else if (d->canvas && !isFocusScope() && d->subFocusItem) {
1831             scopeItem = oldParentItem;
1832             while (!scopeItem->isFocusScope()) scopeItem = scopeItem->parentItem();
1833             scopeFocusedItem = d->subFocusItem;
1834         }
1835
1836         if (scopeFocusedItem)
1837             QSGCanvasPrivate::get(d->canvas)->clearFocusInScope(scopeItem, scopeFocusedItem,
1838                                                                 QSGCanvasPrivate::DontChangeFocusProperty);
1839
1840         op->removeChild(this);
1841     }
1842
1843     d->parentItem = parentItem;
1844
1845     QSGCanvas *parentCanvas = parentItem?QSGItemPrivate::get(parentItem)->canvas:0;
1846     if (d->canvas != parentCanvas) {
1847         QSGItemPrivate::InitializationState initState;
1848         initState.clear();
1849         d->initCanvas(&initState, parentCanvas);
1850     }
1851
1852     d->dirty(QSGItemPrivate::ParentChanged);
1853
1854     if (d->parentItem)
1855         QSGItemPrivate::get(d->parentItem)->addChild(this);
1856
1857     d->setEffectiveVisibleRecur(d->calcEffectiveVisible());
1858     d->setEffectiveEnableRecur(d->calcEffectiveEnable());
1859
1860     if (scopeFocusedItem && d->parentItem && d->canvas) {
1861         // We need to test whether this item becomes scope focused
1862         QSGItem *scopeItem = 0;
1863         scopeItem = d->parentItem;
1864         while (!scopeItem->isFocusScope()) scopeItem = scopeItem->parentItem();
1865
1866         if (scopeItem->scopedFocusItem()) {
1867             QSGItemPrivate::get(scopeFocusedItem)->focus = false;
1868             emit scopeFocusedItem->focusChanged(false);
1869         } else {
1870             QSGCanvasPrivate::get(d->canvas)->setFocusInScope(scopeItem, scopeFocusedItem,
1871                                                               QSGCanvasPrivate::DontChangeFocusProperty);
1872         }
1873     }
1874
1875     d->resolveLayoutMirror();
1876
1877     d->itemChange(ItemParentHasChanged, d->parentItem);
1878
1879     emit parentChanged(d->parentItem);
1880 }
1881
1882 void QSGItem::stackBefore(const QSGItem *sibling)
1883 {
1884     Q_D(QSGItem);
1885     if (!sibling || sibling == this || !d->parentItem || d->parentItem != QSGItemPrivate::get(sibling)->parentItem) {
1886         qWarning("QSGItem::stackBefore: Cannot stack before %p, which must be a sibling", sibling);
1887         return;
1888     }
1889
1890     QSGItemPrivate *parentPrivate = QSGItemPrivate::get(d->parentItem);
1891
1892     int myIndex = parentPrivate->childItems.indexOf(this);
1893     int siblingIndex = parentPrivate->childItems.indexOf(const_cast<QSGItem *>(sibling));
1894
1895     Q_ASSERT(myIndex != -1 && siblingIndex != -1);
1896
1897     if (myIndex == siblingIndex - 1)
1898         return;
1899
1900     parentPrivate->childItems.removeAt(myIndex);
1901
1902     if (myIndex < siblingIndex) --siblingIndex;
1903
1904     parentPrivate->childItems.insert(siblingIndex, this);
1905
1906     parentPrivate->dirty(QSGItemPrivate::ChildrenStackingChanged);
1907
1908     for (int ii = qMin(siblingIndex, myIndex); ii < parentPrivate->childItems.count(); ++ii)
1909         QSGItemPrivate::get(parentPrivate->childItems.at(ii))->siblingOrderChanged();
1910 }
1911
1912 void QSGItem::stackAfter(const QSGItem *sibling)
1913 {
1914     Q_D(QSGItem);
1915     if (!sibling || sibling == this || !d->parentItem || d->parentItem != QSGItemPrivate::get(sibling)->parentItem) {
1916         qWarning("QSGItem::stackAfter: Cannot stack after %p, which must be a sibling", sibling);
1917         return;
1918     }
1919
1920     QSGItemPrivate *parentPrivate = QSGItemPrivate::get(d->parentItem);
1921
1922     int myIndex = parentPrivate->childItems.indexOf(this);
1923     int siblingIndex = parentPrivate->childItems.indexOf(const_cast<QSGItem *>(sibling));
1924
1925     Q_ASSERT(myIndex != -1 && siblingIndex != -1);
1926
1927     if (myIndex == siblingIndex + 1)
1928         return;
1929
1930     parentPrivate->childItems.removeAt(myIndex);
1931
1932     if (myIndex < siblingIndex) --siblingIndex;
1933
1934     parentPrivate->childItems.insert(siblingIndex + 1, this);
1935
1936     parentPrivate->dirty(QSGItemPrivate::ChildrenStackingChanged);
1937
1938     for (int ii = qMin(myIndex, siblingIndex + 1); ii < parentPrivate->childItems.count(); ++ii)
1939         QSGItemPrivate::get(parentPrivate->childItems.at(ii))->siblingOrderChanged();
1940 }
1941
1942 /*!
1943     Returns the QSGItem parent of this item.
1944 */
1945 QSGItem *QSGItem::parentItem() const
1946 {
1947     Q_D(const QSGItem);
1948     return d->parentItem;
1949 }
1950
1951 QSGEngine *QSGItem::sceneGraphEngine() const
1952 {
1953     return canvas()->sceneGraphEngine();
1954 }
1955
1956 QSGCanvas *QSGItem::canvas() const
1957 {
1958     Q_D(const QSGItem);
1959     return d->canvas;
1960 }
1961
1962 static bool itemZOrder_sort(QSGItem *lhs, QSGItem *rhs)
1963 {
1964     return lhs->z() < rhs->z();
1965 }
1966
1967 QList<QSGItem *> QSGItemPrivate::paintOrderChildItems() const
1968 {
1969     // XXX todo - optimize, don't sort and return items that are
1970     // ignored anyway, like invisible or disabled items.
1971     QList<QSGItem *> items = childItems;
1972     qStableSort(items.begin(), items.end(), itemZOrder_sort);
1973     return items;
1974 }
1975
1976 void QSGItemPrivate::addChild(QSGItem *child)
1977 {
1978     Q_Q(QSGItem);
1979
1980     Q_ASSERT(!childItems.contains(child));
1981
1982     childItems.append(child);
1983
1984     dirty(QSGItemPrivate::ChildrenChanged);
1985
1986     itemChange(QSGItem::ItemChildAddedChange, child);
1987
1988     emit q->childrenChanged();
1989 }
1990
1991 void QSGItemPrivate::removeChild(QSGItem *child)
1992 {
1993     Q_Q(QSGItem);
1994
1995     Q_ASSERT(child);
1996     Q_ASSERT(childItems.contains(child));
1997     childItems.removeOne(child);
1998     Q_ASSERT(!childItems.contains(child));
1999
2000     dirty(QSGItemPrivate::ChildrenChanged);
2001
2002     itemChange(QSGItem::ItemChildRemovedChange, child);
2003
2004     emit q->childrenChanged();
2005 }
2006
2007 void QSGItemPrivate::InitializationState::clear()
2008 {
2009     focusScope = 0;
2010 }
2011
2012 void QSGItemPrivate::InitializationState::clear(QSGItem *fs)
2013 {
2014     focusScope = fs;
2015 }
2016
2017 QSGItem *QSGItemPrivate::InitializationState::getFocusScope(QSGItem *item)
2018 {
2019     if (!focusScope) {
2020         QSGItem *fs = item->parentItem();
2021         while (!fs->isFocusScope())
2022             fs = fs->parentItem();
2023         focusScope = fs;
2024     }
2025     return focusScope;
2026 }
2027
2028 void QSGItemPrivate::initCanvas(InitializationState *state, QSGCanvas *c)
2029 {
2030     Q_Q(QSGItem);
2031
2032     if (canvas) {
2033         removeFromDirtyList();
2034         QSGCanvasPrivate *c = QSGCanvasPrivate::get(canvas);
2035         if (polishScheduled)
2036             c->itemsToPolish.remove(q);
2037         if (c->mouseGrabberItem == q)
2038             c->mouseGrabberItem = 0;
2039         if ( hoverEnabled )
2040             c->hoverItems.removeAll(q);
2041         if (itemNodeInstance)
2042             c->cleanup(itemNodeInstance);
2043     }
2044
2045     canvas = c;
2046
2047     if (canvas && polishScheduled)
2048         QSGCanvasPrivate::get(canvas)->itemsToPolish.insert(q);
2049
2050     itemNodeInstance = 0;
2051     opacityNode = 0;
2052     clipNode = 0;
2053     rootNode = 0;
2054     groupNode = 0;
2055     paintNode = 0;
2056     beforePaintNode = 0;
2057
2058     InitializationState _dummy;
2059     InitializationState *childState = state;
2060
2061     if (c && q->isFocusScope()) {
2062         _dummy.clear(q);
2063         childState = &_dummy;
2064     }
2065
2066     for (int ii = 0; ii < childItems.count(); ++ii) {
2067         QSGItem *child = childItems.at(ii);
2068         QSGItemPrivate::get(child)->initCanvas(childState, c);
2069     }
2070
2071     if (c && focus) {
2072         // Fixup
2073         if (state->getFocusScope(q)->scopedFocusItem()) {
2074             focus = false;
2075             emit q->focusChanged(false);
2076         } else {
2077             QSGCanvasPrivate::get(canvas)->setFocusInScope(state->getFocusScope(q), q);
2078         }
2079     }
2080
2081     dirty(Canvas);
2082
2083     itemChange(QSGItem::ItemSceneChange, c);
2084 }
2085
2086 /*!
2087 Returns a transform that maps points from canvas space into item space.
2088 */
2089 QTransform QSGItemPrivate::canvasToItemTransform() const
2090 {
2091     // XXX todo - optimize
2092     return itemToCanvasTransform().inverted();
2093 }
2094
2095 /*!
2096 Returns a transform that maps points from item space into canvas space.
2097 */
2098 QTransform QSGItemPrivate::itemToCanvasTransform() const
2099 {
2100     // XXX todo
2101     QTransform rv = parentItem?QSGItemPrivate::get(parentItem)->itemToCanvasTransform():QTransform();
2102     itemToParentTransform(rv);
2103     return rv;
2104 }
2105
2106 /*!
2107 Motifies \a t with this items local transform relative to its parent.
2108 */
2109 void QSGItemPrivate::itemToParentTransform(QTransform &t) const
2110 {
2111     if (x || y)
2112         t.translate(x, y);
2113
2114     if (!transforms.isEmpty()) {
2115         QMatrix4x4 m(t);
2116         for (int ii = transforms.count() - 1; ii >= 0; --ii)
2117             transforms.at(ii)->applyTo(&m);
2118         t = m.toTransform();
2119     }
2120
2121     if (scale != 1. || rotation != 0.) {
2122         QPointF tp = computeTransformOrigin();
2123         t.translate(tp.x(), tp.y());
2124         t.scale(scale, scale);
2125         t.rotate(rotation);
2126         t.translate(-tp.x(), -tp.y());
2127     }
2128 }
2129
2130
2131 /*!
2132     \qmlproperty real QtQuick2::Item::childrenRect.x
2133     \qmlproperty real QtQuick2::Item::childrenRect.y
2134     \qmlproperty real QtQuick2::Item::childrenRect.width
2135     \qmlproperty real QtQuick2::Item::childrenRect.height
2136
2137     The childrenRect properties allow an item access to the geometry of its
2138     children. This property is useful if you have an item that needs to be
2139     sized to fit its children.
2140 */
2141
2142
2143 /*!
2144     \qmlproperty list<Item> QtQuick2::Item::children
2145     \qmlproperty list<Object> QtQuick2::Item::resources
2146
2147     The children property contains the list of visual children of this item.
2148     The resources property contains non-visual resources that you want to
2149     reference by name.
2150
2151     Generally you can rely on Item's default property to handle all this for
2152     you, but it can come in handy in some cases.
2153
2154     \qml
2155     Item {
2156         children: [
2157             Text {},
2158             Rectangle {}
2159         ]
2160         resources: [
2161             Component {
2162                 id: myComponent
2163                 Text {}
2164             }
2165         ]
2166     }
2167     \endqml
2168 */
2169
2170 /*!
2171     Returns true if construction of the QML component is complete; otherwise
2172     returns false.
2173
2174     It is often desirable to delay some processing until the component is
2175     completed.
2176
2177     \sa componentComplete()
2178 */
2179 bool QSGItem::isComponentComplete() const
2180 {
2181     Q_D(const QSGItem);
2182     return d->componentComplete;
2183 }
2184
2185 QSGItemPrivate::QSGItemPrivate()
2186 : _anchors(0), _contents(0), baselineOffset(0), _anchorLines(0), _stateGroup(0), origin(QSGItem::Center),
2187
2188   flags(0), widthValid(false), heightValid(false), componentComplete(true),
2189   keepMouse(false), hoverEnabled(false), smooth(false), focus(false), activeFocus(false), notifiedFocus(false),
2190   notifiedActiveFocus(false), filtersChildMouseEvents(false), explicitVisible(true),
2191   effectiveVisible(true), explicitEnable(true), effectiveEnable(true), polishScheduled(false),
2192   inheritedLayoutMirror(false), effectiveLayoutMirror(false), isMirrorImplicit(true),
2193   inheritMirrorFromParent(false), inheritMirrorFromItem(false), childrenDoNotOverlap(false),
2194
2195   canvas(0), parentItem(0),
2196
2197   subFocusItem(0),
2198
2199   x(0), y(0), width(0), height(0), implicitWidth(0), implicitHeight(0),
2200   z(0), scale(1), rotation(0), opacity(1),
2201
2202   attachedLayoutDirection(0), acceptedMouseButtons(0),
2203   imHints(Qt::ImhMultiLine),
2204
2205   keyHandler(0),
2206
2207   dirtyAttributes(0), nextDirtyItem(0), prevDirtyItem(0),
2208
2209   itemNodeInstance(0), opacityNode(0), clipNode(0), rootNode(0), groupNode(0), paintNode(0)
2210   , beforePaintNode(0), effectRefCount(0), hideRefCount(0)
2211 {
2212 }
2213
2214 void QSGItemPrivate::init(QSGItem *parent)
2215 {
2216 #ifndef QT_NO_DEBUG
2217     ++qt_item_count;
2218     static bool atexit_registered = false;
2219     if (!atexit_registered) {
2220         atexit(qt_print_item_count);
2221         atexit_registered = true;
2222     }
2223 #endif
2224
2225     Q_Q(QSGItem);
2226     baselineOffset.invalidate();
2227
2228     if (parent) {
2229         q->setParentItem(parent);
2230         QSGItemPrivate *parentPrivate = QSGItemPrivate::get(parent);
2231         setImplicitLayoutMirror(parentPrivate->inheritedLayoutMirror, parentPrivate->inheritMirrorFromParent);
2232     }
2233 }
2234
2235 void QSGItemPrivate::data_append(QDeclarativeListProperty<QObject> *prop, QObject *o)
2236 {
2237     if (!o)
2238         return;
2239
2240     QSGItem *that = static_cast<QSGItem *>(prop->object);
2241
2242     // This test is measurably (albeit only slightly) faster than qobject_cast<>()
2243     const QMetaObject *mo = o->metaObject();
2244     while (mo && mo != &QSGItem::staticMetaObject) {
2245         mo = mo->d.superdata;
2246     }
2247
2248     if (mo) {
2249         QSGItem *item = static_cast<QSGItem *>(o);
2250         item->setParentItem(that);
2251     } else {
2252         if (o->inherits("QGraphicsItem"))
2253             qWarning("Cannot add a QtQuick 1.0 item (%s) into a QtQuick 2.0 scene!", o->metaObject()->className());
2254
2255         // XXX todo - do we really want this behavior?
2256         o->setParent(that);
2257     }
2258 }
2259
2260 /*!
2261     \qmlproperty list<Object> QtQuick2::Item::data
2262     \default
2263
2264     The data property allows you to freely mix visual children and resources
2265     in an item.  If you assign a visual item to the data list it becomes
2266     a child and if you assign any other object type, it is added as a resource.
2267
2268     So you can write:
2269     \qml
2270     Item {
2271         Text {}
2272         Rectangle {}
2273         Timer {}
2274     }
2275     \endqml
2276
2277     instead of:
2278     \qml
2279     Item {
2280         children: [
2281             Text {},
2282             Rectangle {}
2283         ]
2284         resources: [
2285             Timer {}
2286         ]
2287     }
2288     \endqml
2289
2290     data is a behind-the-scenes property: you should never need to explicitly
2291     specify it.
2292  */
2293
2294 int QSGItemPrivate::data_count(QDeclarativeListProperty<QObject> *prop)
2295 {
2296     Q_UNUSED(prop);
2297     // XXX todo
2298     return 0;
2299 }
2300
2301 QObject *QSGItemPrivate::data_at(QDeclarativeListProperty<QObject> *prop, int i)
2302 {
2303     Q_UNUSED(prop);
2304     Q_UNUSED(i);
2305     // XXX todo
2306     return 0;
2307 }
2308
2309 void QSGItemPrivate::data_clear(QDeclarativeListProperty<QObject> *prop)
2310 {
2311     Q_UNUSED(prop);
2312     // XXX todo
2313 }
2314
2315 QObject *QSGItemPrivate::resources_at(QDeclarativeListProperty<QObject> *prop, int index)
2316 {
2317     const QObjectList children = prop->object->children();
2318     if (index < children.count())
2319         return children.at(index);
2320     else
2321         return 0;
2322 }
2323
2324 void QSGItemPrivate::resources_append(QDeclarativeListProperty<QObject> *prop, QObject *o)
2325 {
2326     // XXX todo - do we really want this behavior?
2327     o->setParent(prop->object);
2328 }
2329
2330 int QSGItemPrivate::resources_count(QDeclarativeListProperty<QObject> *prop)
2331 {
2332     return prop->object->children().count();
2333 }
2334
2335 void QSGItemPrivate::resources_clear(QDeclarativeListProperty<QObject> *prop)
2336 {
2337     // XXX todo - do we really want this behavior?
2338     const QObjectList children = prop->object->children();
2339     for (int index = 0; index < children.count(); index++)
2340         children.at(index)->setParent(0);
2341 }
2342
2343 QSGItem *QSGItemPrivate::children_at(QDeclarativeListProperty<QSGItem> *prop, int index)
2344 {
2345     QSGItemPrivate *p = QSGItemPrivate::get(static_cast<QSGItem *>(prop->object));
2346     if (index >= p->childItems.count() || index < 0)
2347         return 0;
2348     else
2349         return p->childItems.at(index);
2350 }
2351
2352 void QSGItemPrivate::children_append(QDeclarativeListProperty<QSGItem> *prop, QSGItem *o)
2353 {
2354     if (!o)
2355         return;
2356
2357     QSGItem *that = static_cast<QSGItem *>(prop->object);
2358     if (o->parentItem() == that)
2359         o->setParentItem(0);
2360
2361     o->setParentItem(that);
2362 }
2363
2364 int QSGItemPrivate::children_count(QDeclarativeListProperty<QSGItem> *prop)
2365 {
2366     QSGItemPrivate *p = QSGItemPrivate::get(static_cast<QSGItem *>(prop->object));
2367     return p->childItems.count();
2368 }
2369
2370 void QSGItemPrivate::children_clear(QDeclarativeListProperty<QSGItem> *prop)
2371 {
2372     QSGItem *that = static_cast<QSGItem *>(prop->object);
2373     QSGItemPrivate *p = QSGItemPrivate::get(that);
2374     while (!p->childItems.isEmpty())
2375         p->childItems.at(0)->setParentItem(0);
2376 }
2377
2378 int QSGItemPrivate::transform_count(QDeclarativeListProperty<QSGTransform> *prop)
2379 {
2380     QSGItem *that = static_cast<QSGItem *>(prop->object);
2381     return QSGItemPrivate::get(that)->transforms.count();
2382 }
2383
2384 void QSGTransform::appendToItem(QSGItem *item)
2385 {
2386     Q_D(QSGTransform);
2387     if (!item)
2388         return;
2389
2390     QSGItemPrivate *p = QSGItemPrivate::get(item);
2391
2392     if (!d->items.isEmpty() && !p->transforms.isEmpty() && p->transforms.contains(this)) {
2393         p->transforms.removeOne(this);
2394         p->transforms.append(this);
2395     } else {
2396         p->transforms.append(this);
2397         d->items.append(item);
2398     }
2399
2400     p->dirty(QSGItemPrivate::Transform);
2401 }
2402
2403 void QSGTransform::prependToItem(QSGItem *item)
2404 {
2405     Q_D(QSGTransform);
2406     if (!item)
2407         return;
2408
2409     QSGItemPrivate *p = QSGItemPrivate::get(item);
2410
2411     if (!d->items.isEmpty() && !p->transforms.isEmpty() && p->transforms.contains(this)) {
2412         p->transforms.removeOne(this);
2413         p->transforms.prepend(this);
2414     } else {
2415         p->transforms.prepend(this);
2416         d->items.append(item);
2417     }
2418
2419     p->dirty(QSGItemPrivate::Transform);
2420 }
2421
2422 void QSGItemPrivate::transform_append(QDeclarativeListProperty<QSGTransform> *prop, QSGTransform *transform)
2423 {
2424     if (!transform)
2425         return;
2426
2427     QSGItem *that = static_cast<QSGItem *>(prop->object);
2428     transform->appendToItem(that);
2429 }
2430
2431 QSGTransform *QSGItemPrivate::transform_at(QDeclarativeListProperty<QSGTransform> *prop, int idx)
2432 {
2433     QSGItem *that = static_cast<QSGItem *>(prop->object);
2434     QSGItemPrivate *p = QSGItemPrivate::get(that);
2435
2436     if (idx < 0 || idx >= p->transforms.count())
2437         return 0;
2438     else
2439         return p->transforms.at(idx);
2440 }
2441
2442 void QSGItemPrivate::transform_clear(QDeclarativeListProperty<QSGTransform> *prop)
2443 {
2444     QSGItem *that = static_cast<QSGItem *>(prop->object);
2445     QSGItemPrivate *p = QSGItemPrivate::get(that);
2446
2447     for (int ii = 0; ii < p->transforms.count(); ++ii) {
2448         QSGTransform *t = p->transforms.at(ii);
2449         QSGTransformPrivate *tp = QSGTransformPrivate::get(t);
2450         tp->items.removeOne(that);
2451     }
2452
2453     p->transforms.clear();
2454
2455     p->dirty(QSGItemPrivate::Transform);
2456 }
2457
2458 /*!
2459     \property QSGItem::childrenRect
2460     \brief The geometry of an item's children.
2461
2462     This property holds the (collective) position and size of the item's children.
2463 */
2464
2465 /*!
2466   \qmlproperty real QtQuick2::Item::x
2467   \qmlproperty real QtQuick2::Item::y
2468   \qmlproperty real QtQuick2::Item::width
2469   \qmlproperty real QtQuick2::Item::height
2470
2471   Defines the item's position and size relative to its parent.
2472
2473   \qml
2474   Item { x: 100; y: 100; width: 100; height: 100 }
2475   \endqml
2476  */
2477
2478 /*!
2479   \qmlproperty real QtQuick2::Item::z
2480
2481   Sets the stacking order of sibling items.  By default the stacking order is 0.
2482
2483   Items with a higher stacking value are drawn on top of siblings with a
2484   lower stacking order.  Items with the same stacking value are drawn
2485   bottom up in the order they appear.  Items with a negative stacking
2486   value are drawn under their parent's content.
2487
2488   The following example shows the various effects of stacking order.
2489
2490   \table
2491   \row
2492   \o \image declarative-item_stacking1.png
2493   \o Same \c z - later children above earlier children:
2494   \qml
2495   Item {
2496       Rectangle {
2497           color: "red"
2498           width: 100; height: 100
2499       }
2500       Rectangle {
2501           color: "blue"
2502           x: 50; y: 50; width: 100; height: 100
2503       }
2504   }
2505   \endqml
2506   \row
2507   \o \image declarative-item_stacking2.png
2508   \o Higher \c z on top:
2509   \qml
2510   Item {
2511       Rectangle {
2512           z: 1
2513           color: "red"
2514           width: 100; height: 100
2515       }
2516       Rectangle {
2517           color: "blue"
2518           x: 50; y: 50; width: 100; height: 100
2519       }
2520   }
2521   \endqml
2522   \row
2523   \o \image declarative-item_stacking3.png
2524   \o Same \c z - children above parents:
2525   \qml
2526   Item {
2527       Rectangle {
2528           color: "red"
2529           width: 100; height: 100
2530           Rectangle {
2531               color: "blue"
2532               x: 50; y: 50; width: 100; height: 100
2533           }
2534       }
2535   }
2536   \endqml
2537   \row
2538   \o \image declarative-item_stacking4.png
2539   \o Lower \c z below:
2540   \qml
2541   Item {
2542       Rectangle {
2543           color: "red"
2544           width: 100; height: 100
2545           Rectangle {
2546               z: -1
2547               color: "blue"
2548               x: 50; y: 50; width: 100; height: 100
2549           }
2550       }
2551   }
2552   \endqml
2553   \endtable
2554  */
2555
2556 /*!
2557     \qmlproperty bool QtQuick2::Item::visible
2558
2559     This property holds whether the item is visible. By default this is true.
2560
2561     Setting this property directly affects the \c visible value of child
2562     items. When set to \c false, the \c visible values of all child items also
2563     become \c false. When set to \c true, the \c visible values of child items
2564     are returned to \c true, unless they have explicitly been set to \c false.
2565
2566     (Because of this flow-on behavior, using the \c visible property may not
2567     have the intended effect if a property binding should only respond to
2568     explicit property changes. In such cases it may be better to use the
2569     \l opacity property instead.)
2570
2571     Setting this property to \c false automatically causes \l focus to be set
2572     to \c false, and this item will longer receive mouse and keyboard events.
2573     (In contrast, setting the \l opacity to 0 does not affect the \l focus
2574     property and the receiving of key events.)
2575
2576     \note This property's value is only affected by changes to this property or
2577     the parent's \c visible property. It does not change, for example, if this
2578     item moves off-screen, or if the \l opacity changes to 0.
2579 */
2580
2581
2582 /*!
2583   \qmlproperty AnchorLine QtQuick2::Item::anchors.top
2584   \qmlproperty AnchorLine QtQuick2::Item::anchors.bottom
2585   \qmlproperty AnchorLine QtQuick2::Item::anchors.left
2586   \qmlproperty AnchorLine QtQuick2::Item::anchors.right
2587   \qmlproperty AnchorLine QtQuick2::Item::anchors.horizontalCenter
2588   \qmlproperty AnchorLine QtQuick2::Item::anchors.verticalCenter
2589   \qmlproperty AnchorLine QtQuick2::Item::anchors.baseline
2590
2591   \qmlproperty Item QtQuick2::Item::anchors.fill
2592   \qmlproperty Item QtQuick2::Item::anchors.centerIn
2593
2594   \qmlproperty real QtQuick2::Item::anchors.margins
2595   \qmlproperty real QtQuick2::Item::anchors.topMargin
2596   \qmlproperty real QtQuick2::Item::anchors.bottomMargin
2597   \qmlproperty real QtQuick2::Item::anchors.leftMargin
2598   \qmlproperty real QtQuick2::Item::anchors.rightMargin
2599   \qmlproperty real QtQuick2::Item::anchors.horizontalCenterOffset
2600   \qmlproperty real QtQuick2::Item::anchors.verticalCenterOffset
2601   \qmlproperty real QtQuick2::Item::anchors.baselineOffset
2602
2603   \qmlproperty bool QtQuick2::Item::anchors.mirrored
2604
2605   Anchors provide a way to position an item by specifying its
2606   relationship with other items.
2607
2608   Margins apply to top, bottom, left, right, and fill anchors.
2609   The \c anchors.margins property can be used to set all of the various margins at once, to the same value.
2610   Note that margins are anchor-specific and are not applied if an item does not
2611   use anchors.
2612
2613   Offsets apply for horizontal center, vertical center, and baseline anchors.
2614
2615   \table
2616   \row
2617   \o \image declarative-anchors_example.png
2618   \o Text anchored to Image, horizontally centered and vertically below, with a margin.
2619   \qml
2620   Item {
2621       Image {
2622           id: pic
2623           // ...
2624       }
2625       Text {
2626           id: label
2627           anchors.horizontalCenter: pic.horizontalCenter
2628           anchors.top: pic.bottom
2629           anchors.topMargin: 5
2630           // ...
2631       }
2632   }
2633   \endqml
2634   \row
2635   \o \image declarative-anchors_example2.png
2636   \o
2637   Left of Text anchored to right of Image, with a margin. The y
2638   property of both defaults to 0.
2639
2640   \qml
2641   Item {
2642       Image {
2643           id: pic
2644           // ...
2645       }
2646       Text {
2647           id: label
2648           anchors.left: pic.right
2649           anchors.leftMargin: 5
2650           // ...
2651       }
2652   }
2653   \endqml
2654   \endtable
2655
2656   \c anchors.fill provides a convenient way for one item to have the
2657   same geometry as another item, and is equivalent to connecting all
2658   four directional anchors.
2659
2660   To clear an anchor value, set it to \c undefined.
2661
2662   \c anchors.mirrored returns true it the layout has been \l {LayoutMirroring}{mirrored}.
2663
2664   \note You can only anchor an item to siblings or a parent.
2665
2666   For more information see \l {anchor-layout}{Anchor Layouts}.
2667 */
2668
2669 /*!
2670   \property QSGItem::baselineOffset
2671   \brief The position of the item's baseline in local coordinates.
2672
2673   The baseline of a \l Text item is the imaginary line on which the text
2674   sits. Controls containing text usually set their baseline to the
2675   baseline of their text.
2676
2677   For non-text items, a default baseline offset of 0 is used.
2678 */
2679 QSGAnchors *QSGItemPrivate::anchors() const
2680 {
2681     if (!_anchors) {
2682         Q_Q(const QSGItem);
2683         _anchors = new QSGAnchors(const_cast<QSGItem *>(q));
2684         if (!componentComplete)
2685             _anchors->classBegin();
2686     }
2687     return _anchors;
2688 }
2689
2690 QSGItemPrivate::AnchorLines *QSGItemPrivate::anchorLines() const
2691 {
2692     Q_Q(const QSGItem);
2693     if (!_anchorLines) _anchorLines =
2694         new AnchorLines(const_cast<QSGItem *>(q));
2695     return _anchorLines;
2696 }
2697
2698 void QSGItemPrivate::siblingOrderChanged()
2699 {
2700     Q_Q(QSGItem);
2701     for(int ii = 0; ii < changeListeners.count(); ++ii) {
2702         const QSGItemPrivate::ChangeListener &change = changeListeners.at(ii);
2703         if (change.types & QSGItemPrivate::SiblingOrder) {
2704             change.listener->itemSiblingOrderChanged(q);
2705         }
2706     }
2707 }
2708
2709 QDeclarativeListProperty<QObject> QSGItemPrivate::data()
2710 {
2711     return QDeclarativeListProperty<QObject>(q_func(), 0, QSGItemPrivate::data_append,
2712                                              QSGItemPrivate::data_count,
2713                                              QSGItemPrivate::data_at,
2714                                              QSGItemPrivate::data_clear);
2715 }
2716
2717 QRectF QSGItem::childrenRect()
2718 {
2719     Q_D(QSGItem);
2720     if (!d->_contents) {
2721         d->_contents = new QSGContents(this);
2722         if (d->componentComplete)
2723             d->_contents->complete();
2724     }
2725     return d->_contents->rectF();
2726 }
2727
2728 QList<QSGItem *> QSGItem::childItems() const
2729 {
2730     Q_D(const QSGItem);
2731     return d->childItems;
2732 }
2733
2734 bool QSGItem::clip() const
2735 {
2736     return flags() & ItemClipsChildrenToShape;
2737 }
2738
2739 void QSGItem::setClip(bool c)
2740 {
2741     if (clip() == c)
2742         return;
2743
2744     setFlag(ItemClipsChildrenToShape, c);
2745
2746     emit clipChanged(c);
2747 }
2748
2749
2750 /*!
2751   This function is called to handle this item's changes in
2752   geometry from \a oldGeometry to \a newGeometry. If the two
2753   geometries are the same, it doesn't do anything.
2754  */
2755 void QSGItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
2756 {
2757     Q_D(QSGItem);
2758
2759     if (d->_anchors)
2760         QSGAnchorsPrivate::get(d->_anchors)->updateMe();
2761
2762     for(int ii = 0; ii < d->changeListeners.count(); ++ii) {
2763         const QSGItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
2764         if (change.types & QSGItemPrivate::Geometry)
2765             change.listener->itemGeometryChanged(this, newGeometry, oldGeometry);
2766     }
2767
2768     if (newGeometry.x() != oldGeometry.x())
2769         emit xChanged();
2770     if (newGeometry.y() != oldGeometry.y())
2771         emit yChanged();
2772     if (newGeometry.width() != oldGeometry.width())
2773         emit widthChanged();
2774     if (newGeometry.height() != oldGeometry.height())
2775         emit heightChanged();
2776 }
2777
2778 /*!
2779     Called by the rendering thread when it is time to sync the state of the QML objects with the
2780     scene graph objects. The function should return the root of the scene graph subtree for
2781     this item. \a oldNode is the node that was returned the last time the function was called.
2782
2783     The main thread is blocked while this function is executed so it is safe to read
2784     values from the QSGItem instance and other objects in the main thread.
2785
2786     \warning This is the only function in which it is allowed to make use of scene graph
2787     objects from the main thread. Use of scene graph objects outside this function will
2788     result in race conditions and potential crashes.
2789  */
2790
2791 QSGNode *QSGItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
2792 {
2793     delete oldNode;
2794     return 0;
2795 }
2796
2797 QSGTransformNode *QSGItemPrivate::createTransformNode()
2798 {
2799     return new QSGTransformNode;
2800 }
2801
2802 void QSGItem::updatePolish()
2803 {
2804 }
2805
2806 void QSGItemPrivate::removeItemChangeListener(QSGItemChangeListener *listener, ChangeTypes types)
2807 {
2808     ChangeListener change(listener, types);
2809     changeListeners.removeOne(change);
2810 }
2811
2812 void QSGItem::keyPressEvent(QKeyEvent *event)
2813 {
2814     event->ignore();
2815 }
2816
2817 void QSGItem::keyReleaseEvent(QKeyEvent *event)
2818 {
2819     event->ignore();
2820 }
2821
2822 void QSGItem::inputMethodEvent(QInputMethodEvent *event)
2823 {
2824     event->ignore();
2825 }
2826
2827 void QSGItem::focusInEvent(QFocusEvent *)
2828 {
2829 }
2830
2831 void QSGItem::focusOutEvent(QFocusEvent *)
2832 {
2833 }
2834
2835 void QSGItem::mousePressEvent(QMouseEvent *event)
2836 {
2837     event->ignore();
2838 }
2839
2840 void QSGItem::mouseMoveEvent(QMouseEvent *event)
2841 {
2842     event->ignore();
2843 }
2844
2845 void QSGItem::mouseReleaseEvent(QMouseEvent *event)
2846 {
2847     event->ignore();
2848 }
2849
2850 void QSGItem::mouseDoubleClickEvent(QMouseEvent *event)
2851 {
2852     mousePressEvent(event);
2853 }
2854
2855 void QSGItem::mouseUngrabEvent()
2856 {
2857     // XXX todo
2858 }
2859
2860 void QSGItem::wheelEvent(QWheelEvent *event)
2861 {
2862     event->ignore();
2863 }
2864
2865 void QSGItem::touchEvent(QTouchEvent *event)
2866 {
2867     event->ignore();
2868 }
2869
2870 void QSGItem::hoverEnterEvent(QHoverEvent *event)
2871 {
2872     Q_UNUSED(event);
2873 }
2874
2875 void QSGItem::hoverMoveEvent(QHoverEvent *event)
2876 {
2877     Q_UNUSED(event);
2878 }
2879
2880 void QSGItem::hoverLeaveEvent(QHoverEvent *event)
2881 {
2882     Q_UNUSED(event);
2883 }
2884
2885 void QSGItem::dragMoveEvent(QSGDragEvent *event)
2886 {
2887     event->setAccepted(false);
2888 }
2889
2890 void QSGItem::dragEnterEvent(QSGDragEvent *event)
2891 {
2892     event->setAccepted(false);
2893 }
2894
2895 void QSGItem::dragExitEvent(QSGDragEvent *event)
2896 {
2897     event->setAccepted(false);
2898 }
2899
2900 void QSGItem::dragDropEvent(QSGDragEvent *event)
2901 {
2902     event->setAccepted(false);
2903 }
2904
2905 bool QSGItem::childMouseEventFilter(QSGItem *, QEvent *)
2906 {
2907     return false;
2908 }
2909
2910 void QSGItem::windowDeactivateEvent()
2911 {
2912     foreach (QSGItem* item, childItems()) {
2913         item->windowDeactivateEvent();
2914     }
2915 }
2916
2917 Qt::InputMethodHints QSGItem::inputMethodHints() const
2918 {
2919     Q_D(const QSGItem);
2920     return d->imHints;
2921 }
2922
2923 void QSGItem::setInputMethodHints(Qt::InputMethodHints hints)
2924 {
2925     Q_D(QSGItem);
2926     d->imHints = hints;
2927
2928     if (!d->canvas || d->canvas->activeFocusItem() != this)
2929         return;
2930
2931     QInputPanel *p = qApp->inputPanel();
2932     if (p->inputItem() == this)
2933         qApp->inputPanel()->update(Qt::ImHints);
2934 }
2935
2936 void QSGItem::updateMicroFocus()
2937 {
2938     QInputPanel *p = qApp->inputPanel();
2939     if (p->inputItem() == this)
2940         qApp->inputPanel()->update(Qt::ImQueryInput);
2941 }
2942
2943 QVariant QSGItem::inputMethodQuery(Qt::InputMethodQuery query) const
2944 {
2945     Q_D(const QSGItem);
2946     QVariant v;
2947
2948     switch (query) {
2949     case Qt::ImEnabled:
2950         v = (bool)(flags() & ItemAcceptsInputMethod);
2951         break;
2952     case Qt::ImHints:
2953         v = (int)inputMethodHints();
2954         break;
2955     case Qt::ImCursorRectangle:
2956     case Qt::ImFont:
2957     case Qt::ImCursorPosition:
2958     case Qt::ImSurroundingText:
2959     case Qt::ImCurrentSelection:
2960     case Qt::ImMaximumTextLength:
2961     case Qt::ImAnchorPosition:
2962     case Qt::ImPreferredLanguage:
2963         if (d->keyHandler)
2964             v = d->keyHandler->inputMethodQuery(query);
2965     default:
2966         break;
2967     }
2968
2969     return v;
2970 }
2971
2972 QSGAnchorLine QSGItemPrivate::left() const
2973 {
2974     return anchorLines()->left;
2975 }
2976
2977 QSGAnchorLine QSGItemPrivate::right() const
2978 {
2979     return anchorLines()->right;
2980 }
2981
2982 QSGAnchorLine QSGItemPrivate::horizontalCenter() const
2983 {
2984     return anchorLines()->hCenter;
2985 }
2986
2987 QSGAnchorLine QSGItemPrivate::top() const
2988 {
2989     return anchorLines()->top;
2990 }
2991
2992 QSGAnchorLine QSGItemPrivate::bottom() const
2993 {
2994     return anchorLines()->bottom;
2995 }
2996
2997 QSGAnchorLine QSGItemPrivate::verticalCenter() const
2998 {
2999     return anchorLines()->vCenter;
3000 }
3001
3002 QSGAnchorLine QSGItemPrivate::baseline() const
3003 {
3004     return anchorLines()->baseline;
3005 }
3006
3007 qreal QSGItem::baselineOffset() const
3008 {
3009     Q_D(const QSGItem);
3010     if (!d->baselineOffset.isValid()) {
3011         return 0.0;
3012     } else
3013         return d->baselineOffset;
3014 }
3015
3016 void QSGItem::setBaselineOffset(qreal offset)
3017 {
3018     Q_D(QSGItem);
3019     if (offset == d->baselineOffset)
3020         return;
3021
3022     d->baselineOffset = offset;
3023
3024     for(int ii = 0; ii < d->changeListeners.count(); ++ii) {
3025         const QSGItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
3026         if (change.types & QSGItemPrivate::Geometry) {
3027             QSGAnchorsPrivate *anchor = change.listener->anchorPrivate();
3028             if (anchor)
3029                 anchor->updateVerticalAnchors();
3030         }
3031     }
3032     emit baselineOffsetChanged(offset);
3033 }
3034
3035 void QSGItem::update()
3036 {
3037     Q_D(QSGItem);
3038     Q_ASSERT(flags() & ItemHasContents);
3039     d->dirty(QSGItemPrivate::Content);
3040 }
3041
3042 void QSGItem::polish()
3043 {
3044     Q_D(QSGItem);
3045     if (!d->polishScheduled) {
3046         d->polishScheduled = true;
3047         if (d->canvas) {
3048             QSGCanvasPrivate *p = QSGCanvasPrivate::get(d->canvas);
3049             bool maybeupdate = p->itemsToPolish.isEmpty();
3050             p->itemsToPolish.insert(this);
3051             if (maybeupdate) d->canvas->maybeUpdate();
3052         }
3053     }
3054 }
3055
3056 void QSGItem::mapFromItem(QDeclarativeV8Function *args) const
3057 {
3058     if (args->Length() != 0) {
3059         v8::Local<v8::Value> item = (*args)[0];
3060         QV8Engine *engine = args->engine();
3061
3062         QSGItem *itemObj = 0;
3063         if (!item->IsNull())
3064             itemObj = qobject_cast<QSGItem*>(engine->toQObject(item));
3065
3066         if (!itemObj && !item->IsNull()) {
3067             qmlInfo(this) << "mapFromItem() given argument \"" << engine->toString(item->ToString())
3068                           << "\" which is neither null nor an Item";
3069             return;
3070         }
3071
3072         v8::Local<v8::Object> rv = v8::Object::New();
3073         args->returnValue(rv);
3074
3075         qreal x = (args->Length() > 1)?(*args)[1]->NumberValue():0;
3076         qreal y = (args->Length() > 2)?(*args)[2]->NumberValue():0;
3077
3078         QPointF p = mapFromItem(itemObj, QPointF(x, y));
3079
3080         rv->Set(v8::String::New("x"), v8::Number::New(p.x()));
3081         rv->Set(v8::String::New("y"), v8::Number::New(p.y()));
3082     }
3083 }
3084
3085 QTransform QSGItem::itemTransform(QSGItem *other, bool *ok) const
3086 {
3087     Q_D(const QSGItem);
3088
3089     // XXX todo - we need to be able to handle common parents better and detect
3090     // invalid cases
3091     if (ok) *ok = true;
3092
3093     QTransform t = d->itemToCanvasTransform();
3094     if (other) t *= QSGItemPrivate::get(other)->canvasToItemTransform();
3095
3096     return t;
3097 }
3098
3099 void QSGItem::mapToItem(QDeclarativeV8Function *args) const
3100 {
3101     if (args->Length() != 0) {
3102         v8::Local<v8::Value> item = (*args)[0];
3103         QV8Engine *engine = args->engine();
3104
3105         QSGItem *itemObj = 0;
3106         if (!item->IsNull())
3107             itemObj = qobject_cast<QSGItem*>(engine->toQObject(item));
3108
3109         if (!itemObj && !item->IsNull()) {
3110             qmlInfo(this) << "mapToItem() given argument \"" << engine->toString(item->ToString())
3111                           << "\" which is neither null nor an Item";
3112             return;
3113         }
3114
3115         v8::Local<v8::Object> rv = v8::Object::New();
3116         args->returnValue(rv);
3117
3118         qreal x = (args->Length() > 1)?(*args)[1]->NumberValue():0;
3119         qreal y = (args->Length() > 2)?(*args)[2]->NumberValue():0;
3120
3121         QPointF p = mapToItem(itemObj, QPointF(x, y));
3122
3123         rv->Set(v8::String::New("x"), v8::Number::New(p.x()));
3124         rv->Set(v8::String::New("y"), v8::Number::New(p.y()));
3125     }
3126 }
3127
3128 void QSGItem::forceActiveFocus()
3129 {
3130     setFocus(true);
3131     QSGItem *parent = parentItem();
3132     while (parent) {
3133         if (parent->flags() & QSGItem::ItemIsFocusScope) {
3134             parent->setFocus(true);
3135         }
3136         parent = parent->parentItem();
3137     }
3138 }
3139
3140 QSGItem *QSGItem::childAt(qreal x, qreal y) const
3141 {
3142     // XXX todo - should this include transform etc.?
3143     const QList<QSGItem *> children = childItems();
3144     for (int i = children.count()-1; i >= 0; --i) {
3145         QSGItem *child = children.at(i);
3146         if (child->isVisible() && child->x() <= x
3147                 && child->x() + child->width() >= x
3148                 && child->y() <= y
3149                 && child->y() + child->height() >= y)
3150             return child;
3151     }
3152     return 0;
3153 }
3154
3155 QDeclarativeListProperty<QObject> QSGItemPrivate::resources()
3156 {
3157     return QDeclarativeListProperty<QObject>(q_func(), 0, QSGItemPrivate::resources_append,
3158                                              QSGItemPrivate::resources_count,
3159                                              QSGItemPrivate::resources_at,
3160                                              QSGItemPrivate::resources_clear);
3161 }
3162
3163 QDeclarativeListProperty<QSGItem> QSGItemPrivate::children()
3164 {
3165     return QDeclarativeListProperty<QSGItem>(q_func(), 0, QSGItemPrivate::children_append,
3166                                              QSGItemPrivate::children_count,
3167                                              QSGItemPrivate::children_at,
3168                                              QSGItemPrivate::children_clear);
3169
3170 }
3171
3172 QDeclarativeListProperty<QDeclarativeState> QSGItemPrivate::states()
3173 {
3174     return _states()->statesProperty();
3175 }
3176
3177 QDeclarativeListProperty<QDeclarativeTransition> QSGItemPrivate::transitions()
3178 {
3179     return _states()->transitionsProperty();
3180 }
3181
3182 QString QSGItemPrivate::state() const
3183 {
3184     if (!_stateGroup)
3185         return QString();
3186     else
3187         return _stateGroup->state();
3188 }
3189
3190 void QSGItemPrivate::setState(const QString &state)
3191 {
3192     _states()->setState(state);
3193 }
3194
3195 QString QSGItem::state() const
3196 {
3197     Q_D(const QSGItem);
3198     return d->state();
3199 }
3200
3201 void QSGItem::setState(const QString &state)
3202 {
3203     Q_D(QSGItem);
3204     d->setState(state);
3205 }
3206
3207 QDeclarativeListProperty<QSGTransform> QSGItem::transform()
3208 {
3209     Q_D(QSGItem);
3210     return QDeclarativeListProperty<QSGTransform>(this, 0, d->transform_append, d->transform_count,
3211                                                   d->transform_at, d->transform_clear);
3212 }
3213
3214 void QSGItem::classBegin()
3215 {
3216     Q_D(QSGItem);
3217     d->componentComplete = false;
3218     if (d->_stateGroup)
3219         d->_stateGroup->classBegin();
3220     if (d->_anchors)
3221         d->_anchors->classBegin();
3222 }
3223
3224 void QSGItem::componentComplete()
3225 {
3226     Q_D(QSGItem);
3227     d->componentComplete = true;
3228     if (d->_stateGroup)
3229         d->_stateGroup->componentComplete();
3230     if (d->_anchors) {
3231         d->_anchors->componentComplete();
3232         QSGAnchorsPrivate::get(d->_anchors)->updateOnComplete();
3233     }
3234     if (d->keyHandler)
3235         d->keyHandler->componentComplete();
3236     if (d->_contents)
3237         d->_contents->complete();
3238 }
3239
3240 QDeclarativeStateGroup *QSGItemPrivate::_states()
3241 {
3242     Q_Q(QSGItem);
3243     if (!_stateGroup) {
3244         _stateGroup = new QDeclarativeStateGroup;
3245         if (!componentComplete)
3246             _stateGroup->classBegin();
3247         QObject::connect(_stateGroup, SIGNAL(stateChanged(QString)),
3248                          q, SIGNAL(stateChanged(QString)));
3249     }
3250
3251     return _stateGroup;
3252 }
3253
3254 QSGItemPrivate::AnchorLines::AnchorLines(QSGItem *q)
3255 {
3256     left.item = q;
3257     left.anchorLine = QSGAnchorLine::Left;
3258     right.item = q;
3259     right.anchorLine = QSGAnchorLine::Right;
3260     hCenter.item = q;
3261     hCenter.anchorLine = QSGAnchorLine::HCenter;
3262     top.item = q;
3263     top.anchorLine = QSGAnchorLine::Top;
3264     bottom.item = q;
3265     bottom.anchorLine = QSGAnchorLine::Bottom;
3266     vCenter.item = q;
3267     vCenter.anchorLine = QSGAnchorLine::VCenter;
3268     baseline.item = q;
3269     baseline.anchorLine = QSGAnchorLine::Baseline;
3270 }
3271
3272 QPointF QSGItemPrivate::computeTransformOrigin() const
3273 {
3274     switch(origin) {
3275     default:
3276     case QSGItem::TopLeft:
3277         return QPointF(0, 0);
3278     case QSGItem::Top:
3279         return QPointF(width / 2., 0);
3280     case QSGItem::TopRight:
3281         return QPointF(width, 0);
3282     case QSGItem::Left:
3283         return QPointF(0, height / 2.);
3284     case QSGItem::Center:
3285         return QPointF(width / 2., height / 2.);
3286     case QSGItem::Right:
3287         return QPointF(width, height / 2.);
3288     case QSGItem::BottomLeft:
3289         return QPointF(0, height);
3290     case QSGItem::Bottom:
3291         return QPointF(width / 2., height);
3292     case QSGItem::BottomRight:
3293         return QPointF(width, height);
3294     }
3295 }
3296
3297 void QSGItemPrivate::transformChanged()
3298 {
3299 }
3300
3301 void QSGItemPrivate::deliverKeyEvent(QKeyEvent *e)
3302 {
3303     Q_Q(QSGItem);
3304
3305     Q_ASSERT(e->isAccepted());
3306     if (keyHandler) {
3307         if (e->type() == QEvent::KeyPress)
3308             keyHandler->keyPressed(e, false);
3309         else
3310             keyHandler->keyReleased(e, false);
3311
3312         if (e->isAccepted())
3313             return;
3314         else
3315             e->accept();
3316     }
3317
3318     if (e->type() == QEvent::KeyPress)
3319         q->keyPressEvent(e);
3320     else
3321         q->keyReleaseEvent(e);
3322
3323     if (e->isAccepted())
3324         return;
3325
3326     if (keyHandler) {
3327         e->accept();
3328
3329         if (e->type() == QEvent::KeyPress)
3330             keyHandler->keyPressed(e, true);
3331         else
3332             keyHandler->keyReleased(e, true);
3333     }
3334 }
3335
3336 void QSGItemPrivate::deliverInputMethodEvent(QInputMethodEvent *e)
3337 {
3338     Q_Q(QSGItem);
3339
3340     Q_ASSERT(e->isAccepted());
3341     if (keyHandler) {
3342         keyHandler->inputMethodEvent(e, false);
3343
3344         if (e->isAccepted())
3345             return;
3346         else
3347             e->accept();
3348     }
3349
3350     q->inputMethodEvent(e);
3351
3352     if (e->isAccepted())
3353         return;
3354
3355     if (keyHandler) {
3356         e->accept();
3357
3358         keyHandler->inputMethodEvent(e, true);
3359     }
3360 }
3361
3362 void QSGItemPrivate::deliverFocusEvent(QFocusEvent *e)
3363 {
3364     Q_Q(QSGItem);
3365
3366     if (e->type() == QEvent::FocusIn) {
3367         q->focusInEvent(e);
3368     } else {
3369         q->focusOutEvent(e);
3370     }
3371 }
3372
3373 void QSGItemPrivate::deliverMouseEvent(QMouseEvent *e)
3374 {
3375     Q_Q(QSGItem);
3376
3377     Q_ASSERT(e->isAccepted());
3378
3379     switch(e->type()) {
3380     default:
3381         Q_ASSERT(!"Unknown event type");
3382     case QEvent::MouseMove:
3383         q->mouseMoveEvent(e);
3384         break;
3385     case QEvent::MouseButtonPress:
3386         q->mousePressEvent(e);
3387         break;
3388     case QEvent::MouseButtonRelease:
3389         q->mouseReleaseEvent(e);
3390         break;
3391     case QEvent::MouseButtonDblClick:
3392         q->mouseDoubleClickEvent(e);
3393         break;
3394     }
3395 }
3396
3397 void QSGItemPrivate::deliverWheelEvent(QWheelEvent *e)
3398 {
3399     Q_Q(QSGItem);
3400     q->wheelEvent(e);
3401 }
3402
3403 void QSGItemPrivate::deliverTouchEvent(QTouchEvent *e)
3404 {
3405     Q_Q(QSGItem);
3406     q->touchEvent(e);
3407 }
3408
3409 void QSGItemPrivate::deliverHoverEvent(QHoverEvent *e)
3410 {
3411     Q_Q(QSGItem);
3412     switch(e->type()) {
3413     default:
3414         Q_ASSERT(!"Unknown event type");
3415     case QEvent::HoverEnter:
3416         q->hoverEnterEvent(e);
3417         break;
3418     case QEvent::HoverLeave:
3419         q->hoverLeaveEvent(e);
3420         break;
3421     case QEvent::HoverMove:
3422         q->hoverMoveEvent(e);
3423         break;
3424     }
3425 }
3426
3427 void QSGItemPrivate::deliverDragEvent(QSGDragEvent *e)
3428 {
3429     Q_Q(QSGItem);
3430     switch (e->type()) {
3431     default:
3432         Q_ASSERT(!"Unknown event type");
3433     case QSGEvent::SGDragEnter:
3434         q->dragEnterEvent(e);
3435         break;
3436     case QSGEvent::SGDragExit:
3437         q->dragExitEvent(e);
3438         break;
3439     case QSGEvent::SGDragMove:
3440         q->dragMoveEvent(e);
3441         break;
3442     case QSGEvent::SGDragDrop:
3443         q->dragDropEvent(e);
3444         break;
3445     }
3446 }
3447
3448 void QSGItem::itemChange(ItemChange change, const ItemChangeData &value)
3449 {
3450     Q_UNUSED(change);
3451     Q_UNUSED(value);
3452 }
3453
3454 /*! \internal */
3455 // XXX todo - do we want/need this anymore?
3456 // Note that it's now used for varying clip rect
3457 QRectF QSGItem::boundingRect() const
3458 {
3459     Q_D(const QSGItem);
3460     return QRectF(0, 0, d->width, d->height);
3461 }
3462
3463 QSGItem::TransformOrigin QSGItem::transformOrigin() const
3464 {
3465     Q_D(const QSGItem);
3466     return d->origin;
3467 }
3468
3469 void QSGItem::setTransformOrigin(TransformOrigin origin)
3470 {
3471     Q_D(QSGItem);
3472     if (origin == d->origin)
3473         return;
3474
3475     d->origin = origin;
3476     d->dirty(QSGItemPrivate::TransformOrigin);
3477
3478     emit transformOriginChanged(d->origin);
3479 }
3480
3481 QPointF QSGItem::transformOriginPoint() const
3482 {
3483     Q_D(const QSGItem);
3484     if (!d->transformOriginPoint.isNull())
3485         return d->transformOriginPoint;
3486     return d->computeTransformOrigin();
3487 }
3488
3489 void QSGItem::setTransformOriginPoint(const QPointF &point)
3490 {
3491     Q_D(QSGItem);
3492     if (d->transformOriginPoint == point)
3493         return;
3494
3495     d->transformOriginPoint = point;
3496     d->dirty(QSGItemPrivate::TransformOrigin);
3497 }
3498
3499 qreal QSGItem::z() const
3500 {
3501     Q_D(const QSGItem);
3502     return d->z;
3503 }
3504
3505 void QSGItem::setZ(qreal v)
3506 {
3507     Q_D(QSGItem);
3508     if (d->z == v)
3509         return;
3510
3511     d->z = v;
3512
3513     d->dirty(QSGItemPrivate::ZValue);
3514     if (d->parentItem)
3515         QSGItemPrivate::get(d->parentItem)->dirty(QSGItemPrivate::ChildrenStackingChanged);
3516
3517     emit zChanged();
3518 }
3519
3520
3521 /*!
3522   \qmlproperty real QtQuick2::Item::rotation
3523   This property holds the rotation of the item in degrees clockwise.
3524
3525   This specifies how many degrees to rotate the item around its transformOrigin.
3526   The default rotation is 0 degrees (i.e. not rotated at all).
3527
3528   \table
3529   \row
3530   \o \image declarative-rotation.png
3531   \o
3532   \qml
3533   Rectangle {
3534       color: "blue"
3535       width: 100; height: 100
3536       Rectangle {
3537           color: "red"
3538           x: 25; y: 25; width: 50; height: 50
3539           rotation: 30
3540       }
3541   }
3542   \endqml
3543   \endtable
3544
3545   \sa transform, Rotation
3546 */
3547
3548 /*!
3549   \qmlproperty real QtQuick2::Item::scale
3550   This property holds the scale of the item.
3551
3552   A scale of less than 1 means the item will be displayed smaller than
3553   normal, and a scale of greater than 1 means the item will be
3554   displayed larger than normal.  A negative scale means the item will
3555   be mirrored.
3556
3557   By default, items are displayed at a scale of 1 (i.e. at their
3558   normal size).
3559
3560   Scaling is from the item's transformOrigin.
3561
3562   \table
3563   \row
3564   \o \image declarative-scale.png
3565   \o
3566   \qml
3567   Rectangle {
3568       color: "blue"
3569       width: 100; height: 100
3570       Rectangle {
3571           color: "green"
3572           width: 25; height: 25
3573       }
3574       Rectangle {
3575           color: "red"
3576           x: 25; y: 25; width: 50; height: 50
3577           scale: 1.4
3578       }
3579   }
3580   \endqml
3581   \endtable
3582
3583   \sa transform, Scale
3584 */
3585
3586 /*!
3587   \qmlproperty real QtQuick2::Item::opacity
3588
3589   This property holds the opacity of the item.  Opacity is specified as a
3590   number between 0 (fully transparent) and 1 (fully opaque).  The default is 1.
3591
3592   When this property is set, the specified opacity is also applied
3593   individually to child items.  In almost all cases this is what you want,
3594   but in some cases it may produce undesired results. For example in the
3595   second set of rectangles below, the red rectangle has specified an opacity
3596   of 0.5, which affects the opacity of its blue child rectangle even though
3597   the child has not specified an opacity.
3598
3599   \table
3600   \row
3601   \o \image declarative-item_opacity1.png
3602   \o
3603   \qml
3604     Item {
3605         Rectangle {
3606             color: "red"
3607             width: 100; height: 100
3608             Rectangle {
3609                 color: "blue"
3610                 x: 50; y: 50; width: 100; height: 100
3611             }
3612         }
3613     }
3614   \endqml
3615   \row
3616   \o \image declarative-item_opacity2.png
3617   \o
3618   \qml
3619     Item {
3620         Rectangle {
3621             opacity: 0.5
3622             color: "red"
3623             width: 100; height: 100
3624             Rectangle {
3625                 color: "blue"
3626                 x: 50; y: 50; width: 100; height: 100
3627             }
3628         }
3629     }
3630   \endqml
3631   \endtable
3632
3633   If an item's opacity is set to 0, the item will no longer receive mouse
3634   events, but will continue to receive key events and will retain the keyboard
3635   \l focus if it has been set. (In contrast, setting the \l visible property
3636   to \c false stops both mouse and keyboard events, and also removes focus
3637   from the item.)
3638 */
3639
3640 /*!
3641   Returns a value indicating whether mouse input should
3642   remain with this item exclusively.
3643
3644   \sa setKeepMouseGrab()
3645  */
3646
3647 qreal QSGItem::rotation() const
3648 {
3649     Q_D(const QSGItem);
3650     return d->rotation;
3651 }
3652
3653 void QSGItem::setRotation(qreal r)
3654 {
3655     Q_D(QSGItem);
3656     if (d->rotation == r)
3657         return;
3658
3659     d->rotation = r;
3660
3661     d->dirty(QSGItemPrivate::BasicTransform);
3662
3663     d->itemChange(ItemRotationHasChanged, r);
3664
3665     emit rotationChanged();
3666 }
3667
3668 qreal QSGItem::scale() const
3669 {
3670     Q_D(const QSGItem);
3671     return d->scale;
3672 }
3673
3674 void QSGItem::setScale(qreal s)
3675 {
3676     Q_D(QSGItem);
3677     if (d->scale == s)
3678         return;
3679
3680     d->scale = s;
3681
3682     d->dirty(QSGItemPrivate::BasicTransform);
3683
3684     emit scaleChanged();
3685 }
3686
3687 qreal QSGItem::opacity() const
3688 {
3689     Q_D(const QSGItem);
3690     return d->opacity;
3691 }
3692
3693 void QSGItem::setOpacity(qreal o)
3694 {
3695     Q_D(QSGItem);
3696     if (d->opacity == o)
3697         return;
3698
3699     d->opacity = o;
3700
3701     d->dirty(QSGItemPrivate::OpacityValue);
3702
3703     d->itemChange(ItemOpacityHasChanged, o);
3704
3705     emit opacityChanged();
3706 }
3707
3708 bool QSGItem::isVisible() const
3709 {
3710     Q_D(const QSGItem);
3711     return d->effectiveVisible;
3712 }
3713
3714 void QSGItem::setVisible(bool v)
3715 {
3716     Q_D(QSGItem);
3717     if (v == d->explicitVisible)
3718         return;
3719
3720     d->explicitVisible = v;
3721
3722     d->setEffectiveVisibleRecur(d->calcEffectiveVisible());
3723 }
3724
3725 bool QSGItem::isEnabled() const
3726 {
3727     Q_D(const QSGItem);
3728     return d->effectiveEnable;
3729 }
3730
3731 void QSGItem::setEnabled(bool e)
3732 {
3733     Q_D(QSGItem);
3734     if (e == d->explicitEnable)
3735         return;
3736
3737     d->explicitEnable = e;
3738
3739     d->setEffectiveEnableRecur(d->calcEffectiveEnable());
3740 }
3741
3742 bool QSGItemPrivate::calcEffectiveVisible() const
3743 {
3744     // XXX todo - Should the effective visible of an element with no parent just be the current
3745     // effective visible?  This would prevent pointless re-processing in the case of an element
3746     // moving to/from a no-parent situation, but it is different from what graphics view does.
3747     return explicitVisible && (!parentItem || QSGItemPrivate::get(parentItem)->effectiveVisible);
3748 }
3749
3750 void QSGItemPrivate::setEffectiveVisibleRecur(bool newEffectiveVisible)
3751 {
3752     Q_Q(QSGItem);
3753
3754     if (newEffectiveVisible && !explicitVisible) {
3755         // This item locally overrides visibility
3756         return;
3757     }
3758
3759     if (newEffectiveVisible == effectiveVisible) {
3760         // No change necessary
3761         return;
3762     }
3763
3764     effectiveVisible = newEffectiveVisible;
3765     dirty(Visible);
3766     if (parentItem) QSGItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
3767
3768     if (canvas) {
3769         QSGCanvasPrivate *canvasPriv = QSGCanvasPrivate::get(canvas);
3770         if (canvasPriv->mouseGrabberItem == q)
3771             q->ungrabMouse();
3772     }
3773
3774     for (int ii = 0; ii < childItems.count(); ++ii)
3775         QSGItemPrivate::get(childItems.at(ii))->setEffectiveVisibleRecur(newEffectiveVisible);
3776
3777     for(int ii = 0; ii < changeListeners.count(); ++ii) {
3778         const QSGItemPrivate::ChangeListener &change = changeListeners.at(ii);
3779         if (change.types & QSGItemPrivate::Visibility)
3780             change.listener->itemVisibilityChanged(q);
3781     }
3782
3783     emit q->visibleChanged();
3784 }
3785
3786 bool QSGItemPrivate::calcEffectiveEnable() const
3787 {
3788     // XXX todo - Should the effective enable of an element with no parent just be the current
3789     // effective enable?  This would prevent pointless re-processing in the case of an element
3790     // moving to/from a no-parent situation, but it is different from what graphics view does.
3791     return explicitEnable && (!parentItem || QSGItemPrivate::get(parentItem)->effectiveEnable);
3792 }
3793
3794 void QSGItemPrivate::setEffectiveEnableRecur(bool newEffectiveEnable)
3795 {
3796     Q_Q(QSGItem);
3797
3798     // XXX todo - need to fixup focus
3799
3800     if (newEffectiveEnable && !explicitEnable) {
3801         // This item locally overrides enable
3802         return;
3803     }
3804
3805     if (newEffectiveEnable == effectiveEnable) {
3806         // No change necessary
3807         return;
3808     }
3809
3810     effectiveEnable = newEffectiveEnable;
3811
3812     if (canvas) {
3813         QSGCanvasPrivate *canvasPriv = QSGCanvasPrivate::get(canvas);
3814         if (canvasPriv->mouseGrabberItem == q)
3815             q->ungrabMouse();
3816     }
3817
3818     for (int ii = 0; ii < childItems.count(); ++ii)
3819         QSGItemPrivate::get(childItems.at(ii))->setEffectiveEnableRecur(newEffectiveEnable);
3820
3821     emit q->enabledChanged();
3822 }
3823
3824 QString QSGItemPrivate::dirtyToString() const
3825 {
3826 #define DIRTY_TO_STRING(value) if (dirtyAttributes & value) { \
3827     if (!rv.isEmpty()) \
3828         rv.append(QLatin1String("|")); \
3829     rv.append(QLatin1String(#value)); \
3830 }
3831
3832 //    QString rv = QLatin1String("0x") + QString::number(dirtyAttributes, 16);
3833     QString rv;
3834
3835     DIRTY_TO_STRING(TransformOrigin);
3836     DIRTY_TO_STRING(Transform);
3837     DIRTY_TO_STRING(BasicTransform);
3838     DIRTY_TO_STRING(Position);
3839     DIRTY_TO_STRING(Size);
3840     DIRTY_TO_STRING(ZValue);
3841     DIRTY_TO_STRING(Content);
3842     DIRTY_TO_STRING(Smooth);
3843     DIRTY_TO_STRING(OpacityValue);
3844     DIRTY_TO_STRING(ChildrenChanged);
3845     DIRTY_TO_STRING(ChildrenStackingChanged);
3846     DIRTY_TO_STRING(ParentChanged);
3847     DIRTY_TO_STRING(Clip);
3848     DIRTY_TO_STRING(Canvas);
3849     DIRTY_TO_STRING(EffectReference);
3850     DIRTY_TO_STRING(Visible);
3851     DIRTY_TO_STRING(HideReference);
3852
3853     return rv;
3854 }
3855
3856 void QSGItemPrivate::dirty(DirtyType type)
3857 {
3858     Q_Q(QSGItem);
3859     if (type & (TransformOrigin | Transform | BasicTransform | Position | Size))
3860         transformChanged();
3861
3862     if (!(dirtyAttributes & type) || (canvas && !prevDirtyItem)) {
3863         dirtyAttributes |= type;
3864         if (canvas) {
3865             addToDirtyList();
3866             QSGCanvasPrivate::get(canvas)->dirtyItem(q);
3867         }
3868     }
3869 }
3870
3871 void QSGItemPrivate::addToDirtyList()
3872 {
3873     Q_Q(QSGItem);
3874
3875     Q_ASSERT(canvas);
3876     if (!prevDirtyItem) {
3877         Q_ASSERT(!nextDirtyItem);
3878
3879         QSGCanvasPrivate *p = QSGCanvasPrivate::get(canvas);
3880         nextDirtyItem = p->dirtyItemList;
3881         if (nextDirtyItem) QSGItemPrivate::get(nextDirtyItem)->prevDirtyItem = &nextDirtyItem;
3882         prevDirtyItem = &p->dirtyItemList;
3883         p->dirtyItemList = q;
3884         p->dirtyItem(q);
3885     }
3886     Q_ASSERT(prevDirtyItem);
3887 }
3888
3889 void QSGItemPrivate::removeFromDirtyList()
3890 {
3891     if (prevDirtyItem) {
3892         if (nextDirtyItem) QSGItemPrivate::get(nextDirtyItem)->prevDirtyItem = prevDirtyItem;
3893         *prevDirtyItem = nextDirtyItem;
3894         prevDirtyItem = 0;
3895         nextDirtyItem = 0;
3896     }
3897     Q_ASSERT(!prevDirtyItem);
3898     Q_ASSERT(!nextDirtyItem);
3899 }
3900
3901 void QSGItemPrivate::refFromEffectItem(bool hide)
3902 {
3903     ++effectRefCount;
3904     if (1 == effectRefCount) {
3905         dirty(EffectReference);
3906         if (parentItem) QSGItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
3907     }
3908     if (hide) {
3909         if (++hideRefCount == 1)
3910             dirty(HideReference);
3911     }
3912 }
3913
3914 void QSGItemPrivate::derefFromEffectItem(bool unhide)
3915 {
3916     Q_ASSERT(effectRefCount);
3917     --effectRefCount;
3918     if (0 == effectRefCount) {
3919         dirty(EffectReference);
3920         if (parentItem) QSGItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
3921     }
3922     if (unhide) {
3923         if (--hideRefCount == 0)
3924             dirty(HideReference);
3925     }
3926 }
3927
3928 void QSGItemPrivate::itemChange(QSGItem::ItemChange change, const QSGItem::ItemChangeData &data)
3929 {
3930     Q_Q(QSGItem);
3931     switch(change) {
3932     case QSGItem::ItemChildAddedChange:
3933         q->itemChange(change, data);
3934         if (_contents && componentComplete)
3935             _contents->childAdded(data.item);
3936         for(int ii = 0; ii < changeListeners.count(); ++ii) {
3937             const QSGItemPrivate::ChangeListener &change = changeListeners.at(ii);
3938             if (change.types & QSGItemPrivate::Children) {
3939                 change.listener->itemChildAdded(q, data.item);
3940             }
3941         }
3942         break;
3943     case QSGItem::ItemChildRemovedChange:
3944         q->itemChange(change, data);
3945         if (_contents && componentComplete)
3946             _contents->childRemoved(data.item);
3947         for(int ii = 0; ii < changeListeners.count(); ++ii) {
3948             const QSGItemPrivate::ChangeListener &change = changeListeners.at(ii);
3949             if (change.types & QSGItemPrivate::Children) {
3950                 change.listener->itemChildRemoved(q, data.item);
3951             }
3952         }
3953         break;
3954     case QSGItem::ItemSceneChange:
3955         q->itemChange(change, data);
3956         break;
3957     case QSGItem::ItemVisibleHasChanged:
3958         q->itemChange(change, data);
3959         for(int ii = 0; ii < changeListeners.count(); ++ii) {
3960             const QSGItemPrivate::ChangeListener &change = changeListeners.at(ii);
3961             if (change.types & QSGItemPrivate::Visibility) {
3962                 change.listener->itemVisibilityChanged(q);
3963             }
3964         }
3965         break;
3966     case QSGItem::ItemParentHasChanged:
3967         q->itemChange(change, data);
3968         for(int ii = 0; ii < changeListeners.count(); ++ii) {
3969             const QSGItemPrivate::ChangeListener &change = changeListeners.at(ii);
3970             if (change.types & QSGItemPrivate::Parent) {
3971                 change.listener->itemParentChanged(q, data.item);
3972             }
3973         }
3974         break;
3975     case QSGItem::ItemOpacityHasChanged:
3976         q->itemChange(change, data);
3977         for(int ii = 0; ii < changeListeners.count(); ++ii) {
3978             const QSGItemPrivate::ChangeListener &change = changeListeners.at(ii);
3979             if (change.types & QSGItemPrivate::Opacity) {
3980                 change.listener->itemOpacityChanged(q);
3981             }
3982         }
3983         break;
3984     case QSGItem::ItemActiveFocusHasChanged:
3985         q->itemChange(change, data);
3986         break;
3987     case QSGItem::ItemRotationHasChanged:
3988         q->itemChange(change, data);
3989         for(int ii = 0; ii < changeListeners.count(); ++ii) {
3990             const QSGItemPrivate::ChangeListener &change = changeListeners.at(ii);
3991             if (change.types & QSGItemPrivate::Rotation) {
3992                 change.listener->itemRotationChanged(q);
3993             }
3994         }
3995         break;
3996     }
3997 }
3998
3999 /*!
4000     \property QSGItem::smooth
4001     \brief whether the item is smoothly transformed.
4002
4003     This property is provided purely for the purpose of optimization. Turning
4004     smooth transforms off is faster, but looks worse; turning smooth
4005     transformations on is slower, but looks better.
4006
4007     By default smooth transformations are off.
4008 */
4009
4010 /*!
4011     Returns true if the item should be drawn with antialiasing and
4012     smooth pixmap filtering, false otherwise.
4013
4014     The default is false.
4015
4016     \sa setSmooth()
4017 */
4018 bool QSGItem::smooth() const
4019 {
4020     Q_D(const QSGItem);
4021     return d->smooth;
4022 }
4023
4024 /*!
4025     Sets whether the item should be drawn with antialiasing and
4026     smooth pixmap filtering to \a smooth.
4027
4028     \sa smooth()
4029 */
4030 void QSGItem::setSmooth(bool smooth)
4031 {
4032     Q_D(QSGItem);
4033     if (d->smooth == smooth)
4034         return;
4035
4036     d->smooth = smooth;
4037     d->dirty(QSGItemPrivate::Smooth);
4038
4039     emit smoothChanged(smooth);
4040 }
4041
4042 QSGItem::Flags QSGItem::flags() const
4043 {
4044     Q_D(const QSGItem);
4045     return (QSGItem::Flags)d->flags;
4046 }
4047
4048 void QSGItem::setFlag(Flag flag, bool enabled)
4049 {
4050     Q_D(QSGItem);
4051     if (enabled)
4052         setFlags((Flags)(d->flags | (quint32)flag));
4053     else
4054         setFlags((Flags)(d->flags & ~(quint32)flag));
4055 }
4056
4057 void QSGItem::setFlags(Flags flags)
4058 {
4059     Q_D(QSGItem);
4060
4061     if ((flags & ItemIsFocusScope) != (d->flags & ItemIsFocusScope)) {
4062         if (flags & ItemIsFocusScope && !d->childItems.isEmpty() && d->canvas) {
4063             qWarning("QSGItem: Cannot set FocusScope once item has children and is in a canvas.");
4064             flags &= ~ItemIsFocusScope;
4065         } else if (d->flags & ItemIsFocusScope) {
4066             qWarning("QSGItem: Cannot unset FocusScope flag.");
4067             flags |= ItemIsFocusScope;
4068         }
4069     }
4070
4071     if ((flags & ItemClipsChildrenToShape ) != (d->flags & ItemClipsChildrenToShape))
4072         d->dirty(QSGItemPrivate::Clip);
4073
4074     d->flags = flags;
4075 }
4076
4077 qreal QSGItem::x() const
4078 {
4079     Q_D(const QSGItem);
4080     return d->x;
4081 }
4082
4083 qreal QSGItem::y() const
4084 {
4085     Q_D(const QSGItem);
4086     return d->y;
4087 }
4088
4089 QPointF QSGItem::pos() const
4090 {
4091     Q_D(const QSGItem);
4092     return QPointF(d->x, d->y);
4093 }
4094
4095 void QSGItem::setX(qreal v)
4096 {
4097     Q_D(QSGItem);
4098     if (d->x == v)
4099         return;
4100
4101     qreal oldx = d->x;
4102     d->x = v;
4103
4104     d->dirty(QSGItemPrivate::Position);
4105
4106     geometryChanged(QRectF(x(), y(), width(), height()),
4107                     QRectF(oldx, y(), width(), height()));
4108 }
4109
4110 void QSGItem::setY(qreal v)
4111 {
4112     Q_D(QSGItem);
4113     if (d->y == v)
4114         return;
4115
4116     qreal oldy = d->y;
4117     d->y = v;
4118
4119     d->dirty(QSGItemPrivate::Position);
4120
4121     geometryChanged(QRectF(x(), y(), width(), height()),
4122                     QRectF(x(), oldy, width(), height()));
4123 }
4124
4125 void QSGItem::setPos(const QPointF &pos)
4126 {
4127     Q_D(QSGItem);
4128     if (QPointF(d->x, d->y) == pos)
4129         return;
4130
4131     qreal oldx = d->x;
4132     qreal oldy = d->y;
4133
4134     d->x = pos.x();
4135     d->y = pos.y();
4136
4137     d->dirty(QSGItemPrivate::Position);
4138
4139     geometryChanged(QRectF(x(), y(), width(), height()),
4140                     QRectF(oldx, oldy, width(), height()));
4141 }
4142
4143 qreal QSGItem::width() const
4144 {
4145     Q_D(const QSGItem);
4146     return d->width;
4147 }
4148
4149 void QSGItem::setWidth(qreal w)
4150 {
4151     Q_D(QSGItem);
4152     if (qIsNaN(w))
4153         return;
4154
4155     d->widthValid = true;
4156     if (d->width == w)
4157         return;
4158
4159     qreal oldWidth = d->width;
4160     d->width = w;
4161
4162     d->dirty(QSGItemPrivate::Size);
4163
4164     geometryChanged(QRectF(x(), y(), width(), height()),
4165                     QRectF(x(), y(), oldWidth, height()));
4166 }
4167
4168 void QSGItem::resetWidth()
4169 {
4170     Q_D(QSGItem);
4171     d->widthValid = false;
4172     setImplicitWidth(implicitWidth());
4173 }
4174
4175 void QSGItemPrivate::implicitWidthChanged()
4176 {
4177     Q_Q(QSGItem);
4178     emit q->implicitWidthChanged();
4179 }
4180
4181 qreal QSGItemPrivate::getImplicitWidth() const
4182 {
4183     return implicitWidth;
4184 }
4185 /*!
4186     Returns the width of the item that is implied by other properties that determine the content.
4187 */
4188 qreal QSGItem::implicitWidth() const
4189 {
4190     Q_D(const QSGItem);
4191     return d->getImplicitWidth();
4192 }
4193
4194 /*!
4195     \qmlproperty real QtQuick2::Item::implicitWidth
4196     \qmlproperty real QtQuick2::Item::implicitHeight
4197
4198     Defines the natural width or height of the Item if no \l width or \l height is specified.
4199
4200     The default implicit size for most items is 0x0, however some elements have an inherent
4201     implicit size which cannot be overridden, e.g. Image, Text.
4202
4203     Setting the implicit size is useful for defining components that have a preferred size
4204     based on their content, for example:
4205
4206     \qml
4207     // Label.qml
4208     import QtQuick 1.1
4209
4210     Item {
4211         property alias icon: image.source
4212         property alias label: text.text
4213         implicitWidth: text.implicitWidth + image.implicitWidth
4214         implicitHeight: Math.max(text.implicitHeight, image.implicitHeight)
4215         Image { id: image }
4216         Text {
4217             id: text
4218             wrapMode: Text.Wrap
4219             anchors.left: image.right; anchors.right: parent.right
4220             anchors.verticalCenter: parent.verticalCenter
4221         }
4222     }
4223     \endqml
4224
4225     \bold Note: using implicitWidth of Text or TextEdit and setting the width explicitly
4226     incurs a performance penalty as the text must be laid out twice.
4227 */
4228
4229 /*!
4230     Sets the implied width of the item to \a w.
4231     This is the width implied by other properties that determine the content.
4232 */
4233 void QSGItem::setImplicitWidth(qreal w)
4234 {
4235     Q_D(QSGItem);
4236     bool changed = w != d->implicitWidth;
4237     d->implicitWidth = w;
4238     if (d->width == w || widthValid()) {
4239         if (changed)
4240             d->implicitWidthChanged();
4241         return;
4242     }
4243
4244     qreal oldWidth = d->width;
4245     d->width = w;
4246
4247     d->dirty(QSGItemPrivate::Size);
4248
4249     geometryChanged(QRectF(x(), y(), width(), height()),
4250                     QRectF(x(), y(), oldWidth, height()));
4251
4252     if (changed)
4253         d->implicitWidthChanged();
4254 }
4255
4256 /*!
4257     Returns whether the width property has been set explicitly.
4258 */
4259 bool QSGItem::widthValid() const
4260 {
4261     Q_D(const QSGItem);
4262     return d->widthValid;
4263 }
4264
4265 qreal QSGItem::height() const
4266 {
4267     Q_D(const QSGItem);
4268     return d->height;
4269 }
4270
4271 void QSGItem::setHeight(qreal h)
4272 {
4273     Q_D(QSGItem);
4274     if (qIsNaN(h))
4275         return;
4276
4277     d->heightValid = true;
4278     if (d->height == h)
4279         return;
4280
4281     qreal oldHeight = d->height;
4282     d->height = h;
4283
4284     d->dirty(QSGItemPrivate::Size);
4285
4286     geometryChanged(QRectF(x(), y(), width(), height()),
4287                     QRectF(x(), y(), width(), oldHeight));
4288 }
4289
4290 void QSGItem::resetHeight()
4291 {
4292     Q_D(QSGItem);
4293     d->heightValid = false;
4294     setImplicitHeight(implicitHeight());
4295 }
4296
4297 void QSGItemPrivate::implicitHeightChanged()
4298 {
4299     Q_Q(QSGItem);
4300     emit q->implicitHeightChanged();
4301 }
4302
4303 qreal QSGItemPrivate::getImplicitHeight() const
4304 {
4305     return implicitHeight;
4306 }
4307
4308 /*!
4309     Returns the height of the item that is implied by other properties that determine the content.
4310 */
4311 qreal QSGItem::implicitHeight() const
4312 {
4313     Q_D(const QSGItem);
4314     return d->getImplicitHeight();
4315 }
4316
4317
4318 /*!
4319     Sets the implied height of the item to \a h.
4320     This is the height implied by other properties that determine the content.
4321 */
4322 void QSGItem::setImplicitHeight(qreal h)
4323 {
4324     Q_D(QSGItem);
4325     bool changed = h != d->implicitHeight;
4326     d->implicitHeight = h;
4327     if (d->height == h || heightValid()) {
4328         if (changed)
4329             d->implicitHeightChanged();
4330         return;
4331     }
4332
4333     qreal oldHeight = d->height;
4334     d->height = h;
4335
4336     d->dirty(QSGItemPrivate::Size);
4337
4338     geometryChanged(QRectF(x(), y(), width(), height()),
4339                     QRectF(x(), y(), width(), oldHeight));
4340
4341     if (changed)
4342         d->implicitHeightChanged();
4343 }
4344
4345 /*!
4346     Returns whether the height property has been set explicitly.
4347 */
4348 bool QSGItem::heightValid() const
4349 {
4350     Q_D(const QSGItem);
4351     return d->heightValid;
4352 }
4353
4354 void QSGItem::setSize(const QSizeF &size)
4355 {
4356     Q_D(QSGItem);
4357     d->heightValid = true;
4358     d->widthValid = true;
4359
4360     if (QSizeF(d->width, d->height) == size)
4361         return;
4362
4363     qreal oldHeight = d->height;
4364     qreal oldWidth = d->width;
4365     d->height = size.height();
4366     d->width = size.width();
4367
4368     d->dirty(QSGItemPrivate::Size);
4369
4370     geometryChanged(QRectF(x(), y(), width(), height()),
4371                     QRectF(x(), y(), oldWidth, oldHeight));
4372 }
4373
4374 bool QSGItem::hasActiveFocus() const
4375 {
4376     Q_D(const QSGItem);
4377     return d->activeFocus;
4378 }
4379
4380 bool QSGItem::hasFocus() const
4381 {
4382     Q_D(const QSGItem);
4383     return d->focus;
4384 }
4385
4386 void QSGItem::setFocus(bool focus)
4387 {
4388     Q_D(QSGItem);
4389     if (d->focus == focus)
4390         return;
4391
4392     if (d->canvas) {
4393         // Need to find our nearest focus scope
4394         QSGItem *scope = parentItem();
4395         while (scope && !scope->isFocusScope())
4396             scope = scope->parentItem();
4397         if (focus)
4398             QSGCanvasPrivate::get(d->canvas)->setFocusInScope(scope, this);
4399         else
4400             QSGCanvasPrivate::get(d->canvas)->clearFocusInScope(scope, this);
4401     } else {
4402         d->focus = focus;
4403         emit focusChanged(focus);
4404     }
4405 }
4406
4407 bool QSGItem::isFocusScope() const
4408 {
4409     return flags() & ItemIsFocusScope;
4410 }
4411
4412 QSGItem *QSGItem::scopedFocusItem() const
4413 {
4414     Q_D(const QSGItem);
4415     if (!isFocusScope())
4416         return 0;
4417     else
4418         return d->subFocusItem;
4419 }
4420
4421
4422 Qt::MouseButtons QSGItem::acceptedMouseButtons() const
4423 {
4424     Q_D(const QSGItem);
4425     return d->acceptedMouseButtons;
4426 }
4427
4428 void QSGItem::setAcceptedMouseButtons(Qt::MouseButtons buttons)
4429 {
4430     Q_D(QSGItem);
4431     d->acceptedMouseButtons = buttons;
4432 }
4433
4434 bool QSGItem::filtersChildMouseEvents() const
4435 {
4436     Q_D(const QSGItem);
4437     return d->filtersChildMouseEvents;
4438 }
4439
4440 void QSGItem::setFiltersChildMouseEvents(bool filter)
4441 {
4442     Q_D(QSGItem);
4443     d->filtersChildMouseEvents = filter;
4444 }
4445
4446 bool QSGItem::isUnderMouse() const
4447 {
4448     Q_D(const QSGItem);
4449     if (!d->canvas)
4450         return false;
4451
4452     QPoint cursorPos = QCursor::pos();
4453     if (QRectF(0, 0, width(), height()).contains(mapFromScene(cursorPos))) // ### refactor: d->canvas->mapFromGlobal(cursorPos))))
4454         return true;
4455     return false;
4456 }
4457
4458 bool QSGItem::acceptHoverEvents() const
4459 {
4460     Q_D(const QSGItem);
4461     return d->hoverEnabled;
4462 }
4463
4464 void QSGItem::setAcceptHoverEvents(bool enabled)
4465 {
4466     Q_D(QSGItem);
4467     d->hoverEnabled = enabled;
4468 }
4469
4470 void QSGItem::grabMouse() 
4471 {
4472     Q_D(QSGItem);
4473     if (!d->canvas)
4474         return;
4475     QSGCanvasPrivate *canvasPriv = QSGCanvasPrivate::get(d->canvas);
4476     if (canvasPriv->mouseGrabberItem == this)
4477         return;
4478
4479     QSGItem *oldGrabber = canvasPriv->mouseGrabberItem;
4480     canvasPriv->mouseGrabberItem = this;
4481     if (oldGrabber)
4482         oldGrabber->mouseUngrabEvent();
4483 }
4484
4485 void QSGItem::ungrabMouse()
4486 {
4487     Q_D(QSGItem);
4488     if (!d->canvas)
4489         return;
4490     QSGCanvasPrivate *canvasPriv = QSGCanvasPrivate::get(d->canvas);
4491     if (canvasPriv->mouseGrabberItem != this) {
4492         qWarning("QSGItem::ungrabMouse(): Item is not the mouse grabber.");
4493         return;
4494     }
4495
4496     canvasPriv->mouseGrabberItem = 0;
4497     mouseUngrabEvent();
4498 }
4499
4500 bool QSGItem::keepMouseGrab() const
4501 {
4502     Q_D(const QSGItem);
4503     return d->keepMouse;
4504 }
4505
4506 /*!
4507   The flag indicating whether the mouse should remain
4508   with this item is set to \a keep.
4509
4510   This is useful for items that wish to grab and keep mouse
4511   interaction following a predefined gesture.  For example,
4512   an item that is interested in horizontal mouse movement
4513   may set keepMouseGrab to true once a threshold has been
4514   exceeded.  Once keepMouseGrab has been set to true, filtering
4515   items will not react to mouse events.
4516
4517   If the item does not indicate that it wishes to retain mouse grab,
4518   a filtering item may steal the grab. For example, Flickable may attempt
4519   to steal a mouse grab if it detects that the user has begun to
4520   move the viewport.
4521
4522   \sa keepMouseGrab()
4523  */
4524 void QSGItem::setKeepMouseGrab(bool keep)
4525 {
4526     Q_D(QSGItem);
4527     d->keepMouse = keep;
4528 }
4529
4530 /*!
4531     \qmlmethod object QtQuick2::Item::mapFromItem(Item item, real x, real y)
4532
4533     Maps the point (\a x, \a y), which is in \a item's coordinate system, to
4534     this item's coordinate system, and returns an object with \c x and \c y
4535     properties matching the mapped cooordinate.
4536
4537     If \a item is a \c null value, this maps the point from the coordinate
4538     system of the root QML view.
4539 */
4540 /*!
4541     \qmlmethod object QtQuick2::Item::mapToItem(Item item, real x, real y)
4542
4543     Maps the point (\a x, \a y), which is in this item's coordinate system, to
4544     \a item's coordinate system, and returns an object with \c x and \c y
4545     properties matching the mapped cooordinate.
4546
4547     If \a item is a \c null value, this maps \a x and \a y to the coordinate
4548     system of the root QML view.
4549 */
4550 QPointF QSGItem::mapToItem(const QSGItem *item, const QPointF &point) const
4551 {
4552     QPointF p = mapToScene(point);
4553     if (item)
4554         p = item->mapFromScene(p);
4555     return p;
4556 }
4557
4558 QPointF QSGItem::mapToScene(const QPointF &point) const
4559 {
4560     Q_D(const QSGItem);
4561     return d->itemToCanvasTransform().map(point);
4562 }
4563
4564 QRectF QSGItem::mapRectToItem(const QSGItem *item, const QRectF &rect) const
4565 {
4566     Q_D(const QSGItem);
4567     QTransform t = d->itemToCanvasTransform();
4568     if (item)
4569         t *= QSGItemPrivate::get(item)->canvasToItemTransform();
4570     return t.mapRect(rect);
4571 }
4572
4573 QRectF QSGItem::mapRectToScene(const QRectF &rect) const
4574 {
4575     Q_D(const QSGItem);
4576     return d->itemToCanvasTransform().mapRect(rect);
4577 }
4578
4579 QPointF QSGItem::mapFromItem(const QSGItem *item, const QPointF &point) const
4580 {
4581     QPointF p = item?item->mapToScene(point):point;
4582     return mapFromScene(p);
4583 }
4584
4585 QPointF QSGItem::mapFromScene(const QPointF &point) const
4586 {
4587     Q_D(const QSGItem);
4588     return d->canvasToItemTransform().map(point);
4589 }
4590
4591 QRectF QSGItem::mapRectFromItem(const QSGItem *item, const QRectF &rect) const
4592 {
4593     Q_D(const QSGItem);
4594     QTransform t = item?QSGItemPrivate::get(item)->itemToCanvasTransform():QTransform();
4595     t *= d->canvasToItemTransform();
4596     return t.mapRect(rect);
4597 }
4598
4599 QRectF QSGItem::mapRectFromScene(const QRectF &rect) const
4600 {
4601     Q_D(const QSGItem);
4602     return d->canvasToItemTransform().mapRect(rect);
4603 }
4604
4605
4606 /*!
4607     \qmlmethod QtQuick2::Item::forceActiveFocus()
4608
4609     Forces active focus on the item.
4610
4611     This method sets focus on the item and makes sure that all the focus scopes
4612     higher in the object hierarchy are also given the focus.
4613 */
4614
4615 /*!
4616     Forces active focus on the item.
4617
4618     This method sets focus on the item and makes sure that all the focus scopes
4619     higher in the object hierarchy are also given the focus.
4620 */
4621
4622 /*!
4623   \qmlmethod QtQuick2::Item::childAt(real x, real y)
4624
4625   Returns the visible child item at point (\a x, \a y), which is in this
4626   item's coordinate system, or \c null if there is no such item.
4627 */
4628
4629 /*!
4630   Returns the visible child item at point (\a x, \a y), which is in this
4631   item's coordinate system, or 0 if there is no such item.
4632 */
4633
4634 /*!
4635   \qmlproperty list<State> QtQuick2::Item::states
4636   This property holds a list of states defined by the item.
4637
4638   \qml
4639   Item {
4640       states: [
4641           State {
4642               // ...
4643           },
4644           State {
4645               // ...
4646           }
4647           // ...
4648       ]
4649   }
4650   \endqml
4651
4652   \sa {qmlstate}{States}
4653 */
4654 /*!
4655   \qmlproperty list<Transition> QtQuick2::Item::transitions
4656   This property holds a list of transitions defined by the item.
4657
4658   \qml
4659   Item {
4660       transitions: [
4661           Transition {
4662               // ...
4663           },
4664           Transition {
4665               // ...
4666           }
4667           // ...
4668       ]
4669   }
4670   \endqml
4671
4672   \sa {QML Animation and Transitions}{Transitions}
4673 */
4674 /*
4675   \qmlproperty list<Filter> QtQuick2::Item::filter
4676   This property holds a list of graphical filters to be applied to the item.
4677
4678   \l {Filter}{Filters} include things like \l {Blur}{blurring}
4679   the item, or giving it a \l Reflection.  Some
4680   filters may not be available on all canvases; if a filter is not
4681   available on a certain canvas, it will simply not be applied for
4682   that canvas (but the QML will still be considered valid).
4683
4684   \qml
4685   Item {
4686       filter: [
4687           Blur {
4688               // ...
4689           },
4690           Reflection {
4691               // ...
4692           }
4693           // ...
4694       ]
4695   }
4696   \endqml
4697 */
4698
4699 /*!
4700   \qmlproperty bool QtQuick2::Item::clip
4701   This property holds whether clipping is enabled. The default clip value is \c false.
4702
4703   If clipping is enabled, an item will clip its own painting, as well
4704   as the painting of its children, to its bounding rectangle.
4705
4706   Non-rectangular clipping regions are not supported for performance reasons.
4707 */
4708
4709 /*!
4710   \property QSGItem::clip
4711   This property holds whether clipping is enabled. The default clip value is \c false.
4712
4713   If clipping is enabled, an item will clip its own painting, as well
4714   as the painting of its children, to its bounding rectangle. If you set
4715   clipping during an item's paint operation, remember to re-set it to
4716   prevent clipping the rest of your scene.
4717
4718   Non-rectangular clipping regions are not supported for performance reasons.
4719 */
4720
4721 /*!
4722   \qmlproperty string QtQuick2::Item::state
4723
4724   This property holds the name of the current state of the item.
4725
4726   This property is often used in scripts to change between states. For
4727   example:
4728
4729   \js
4730   function toggle() {
4731       if (button.state == 'On')
4732           button.state = 'Off';
4733       else
4734           button.state = 'On';
4735   }
4736   \endjs
4737
4738   If the item is in its base state (i.e. no explicit state has been
4739   set), \c state will be a blank string. Likewise, you can return an
4740   item to its base state by setting its current state to \c ''.
4741
4742   \sa {qmlstates}{States}
4743 */
4744
4745 /*!
4746   \qmlproperty list<Transform> QtQuick2::Item::transform
4747   This property holds the list of transformations to apply.
4748
4749   For more information see \l Transform.
4750 */
4751
4752 /*!
4753     \enum QSGItem::TransformOrigin
4754
4755     Controls the point about which simple transforms like scale apply.
4756
4757     \value TopLeft The top-left corner of the item.
4758     \value Top The center point of the top of the item.
4759     \value TopRight The top-right corner of the item.
4760     \value Left The left most point of the vertical middle.
4761     \value Center The center of the item.
4762     \value Right The right most point of the vertical middle.
4763     \value BottomLeft The bottom-left corner of the item.
4764     \value Bottom The center point of the bottom of the item.
4765     \value BottomRight The bottom-right corner of the item.
4766 */
4767
4768
4769 /*!
4770   \qmlproperty bool QtQuick2::Item::activeFocus
4771
4772   This property indicates whether the item has active focus.
4773
4774   An item with active focus will receive keyboard input,
4775   or is a FocusScope ancestor of the item that will receive keyboard input.
4776
4777   Usually, activeFocus is gained by setting focus on an item and its enclosing
4778   FocusScopes. In the following example \c input will have activeFocus.
4779   \qml
4780   Rectangle {
4781       FocusScope {
4782           focus: true
4783           TextInput {
4784               id: input
4785               focus: true
4786           }
4787       }
4788   }
4789   \endqml
4790
4791   \sa focus, {qmlfocus}{Keyboard Focus}
4792 */
4793
4794 /*!
4795   \qmlproperty bool QtQuick2::Item::focus
4796   This property indicates whether the item has focus within the enclosing focus scope. If true, this item
4797   will gain active focus when the enclosing focus scope gains active focus.
4798   In the following example, \c input will be given active focus when \c scope gains active focus.
4799   \qml
4800   Rectangle {
4801       FocusScope {
4802           id: scope
4803           TextInput {
4804               id: input
4805               focus: true
4806           }
4807       }
4808   }
4809   \endqml
4810
4811   For the purposes of this property, the scene as a whole is assumed to act like a focus scope.
4812   On a practical level, that means the following QML will give active focus to \c input on startup.
4813
4814   \qml
4815   Rectangle {
4816       TextInput {
4817           id: input
4818           focus: true
4819       }
4820   }
4821   \endqml
4822
4823   \sa activeFocus, {qmlfocus}{Keyboard Focus}
4824 */
4825
4826
4827 /*!
4828   \property QSGItem::anchors
4829   \internal
4830 */
4831
4832 /*!
4833   \property QSGItem::left
4834   \internal
4835 */
4836
4837 /*!
4838   \property QSGItem::right
4839   \internal
4840 */
4841
4842 /*!
4843   \property QSGItem::horizontalCenter
4844   \internal
4845 */
4846
4847 /*!
4848   \property QSGItem::top
4849   \internal
4850 */
4851
4852 /*!
4853   \property QSGItem::bottom
4854   \internal
4855 */
4856
4857 /*!
4858   \property QSGItem::verticalCenter
4859   \internal
4860 */
4861
4862 /*!
4863   \property QSGItem::focus
4864   \internal
4865 */
4866
4867 /*!
4868   \property QSGItem::transform
4869   \internal
4870 */
4871
4872 /*!
4873   \property QSGItem::transformOrigin
4874   \internal
4875 */
4876
4877 /*!
4878   \property QSGItem::activeFocus
4879   \internal
4880 */
4881
4882 /*!
4883   \property QSGItem::baseline
4884   \internal
4885 */
4886
4887 /*!
4888   \property QSGItem::data
4889   \internal
4890 */
4891
4892 /*!
4893   \property QSGItem::resources
4894   \internal
4895 */
4896
4897 /*!
4898   \property QSGItem::state
4899   \internal
4900 */
4901
4902 /*!
4903   \property QSGItem::states
4904   \internal
4905 */
4906
4907 /*!
4908   \property QSGItem::transformOriginPoint
4909   \internal
4910 */
4911
4912 /*!
4913   \property QSGItem::transitions
4914   \internal
4915 */
4916
4917 bool QSGItem::event(QEvent *ev)
4918 {
4919 #if 0
4920     if (ev->type() == QEvent::PolishRequest) {
4921         Q_D(QSGItem);
4922         d->polishScheduled = false;
4923         updatePolish();
4924         return true;
4925     } else {
4926         return QObject::event(ev);
4927     }
4928 #endif
4929     if (ev->type() == QEvent::InputMethodQuery) {
4930         QInputMethodQueryEvent *query = static_cast<QInputMethodQueryEvent *>(ev);
4931         Qt::InputMethodQueries queries = query->queries();
4932         for (uint i = 0; i < 32; ++i) {
4933             Qt::InputMethodQuery q = (Qt::InputMethodQuery)(int)(queries & (1<<i));
4934             if (q) {
4935                 QVariant v = inputMethodQuery(q);
4936                 query->setValue(q, v);
4937             }
4938         }
4939         query->accept();
4940         return true;
4941     } else if (ev->type() == QEvent::InputMethod) {
4942         inputMethodEvent(static_cast<QInputMethodEvent *>(ev));
4943         return true;
4944     }
4945     return QObject::event(ev);
4946 }
4947
4948 #ifndef QT_NO_DEBUG_STREAM
4949 QDebug operator<<(QDebug debug, QSGItem *item)
4950 {
4951     if (!item) {
4952         debug << "QSGItem(0)";
4953         return debug;
4954     }
4955
4956     debug << item->metaObject()->className() << "(this =" << ((void*)item)
4957           << ", name=" << item->objectName()
4958           << ", parent =" << ((void*)item->parentItem())
4959           << ", geometry =" << QRectF(item->pos(), QSizeF(item->width(), item->height()))
4960           << ", z =" << item->z() << ')';
4961     return debug;
4962 }
4963 #endif
4964
4965 qint64 QSGItemPrivate::consistentTime = -1;
4966 void QSGItemPrivate::setConsistentTime(qint64 t)
4967 {
4968     consistentTime = t;
4969 }
4970
4971 class QElapsedTimerConsistentTimeHack
4972 {
4973 public:
4974     void start() {
4975         t1 = QSGItemPrivate::consistentTime;
4976         t2 = 0;
4977     }
4978     qint64 elapsed() {
4979         return QSGItemPrivate::consistentTime - t1;
4980     }
4981     qint64 restart() {
4982         qint64 val = QSGItemPrivate::consistentTime - t1;
4983         t1 = QSGItemPrivate::consistentTime;
4984         t2 = 0;
4985         return val;
4986     }
4987
4988 private:
4989     qint64 t1;
4990     qint64 t2;
4991 };
4992
4993 void QSGItemPrivate::start(QElapsedTimer &t)
4994 {
4995     if (QSGItemPrivate::consistentTime == -1)
4996         t.start();
4997     else
4998         ((QElapsedTimerConsistentTimeHack*)&t)->start();
4999 }
5000
5001 qint64 QSGItemPrivate::elapsed(QElapsedTimer &t)
5002 {
5003     if (QSGItemPrivate::consistentTime == -1)
5004         return t.elapsed();
5005     else
5006         return ((QElapsedTimerConsistentTimeHack*)&t)->elapsed();
5007 }
5008
5009 qint64 QSGItemPrivate::restart(QElapsedTimer &t)
5010 {
5011     if (QSGItemPrivate::consistentTime == -1)
5012         return t.restart();
5013     else
5014         return ((QElapsedTimerConsistentTimeHack*)&t)->restart();
5015 }
5016
5017 /*!
5018     \fn bool QSGItem::isTextureProvider() const
5019
5020     Returns true if this item is a texture provider. The default
5021     implementation returns false.
5022
5023     This function can be called from any thread.
5024  */
5025
5026 /*!
5027     \fn QSGTextureProvider *QSGItem::textureProvider() const
5028
5029     Returns the texture provider for an item. The default implementation
5030     returns 0.
5031
5032     This function may only be called on the rendering thread.
5033  */
5034
5035 QT_END_NAMESPACE
5036
5037 #include <moc_qsgitem.cpp>