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