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