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