Doc: Sanitized QML types
[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 For specifying 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 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 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 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 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(qmlobject_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 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(qmlobject_cast<QQuickItem*>(parent))
1309 {
1310     Q_D(QQuickKeysAttached);
1311     m_processPost = false;
1312     d->item = qmlobject_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 Property 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 = qmlobject_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 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 A basic visual QML type
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     if (QQuickItem *item = qmlobject_cast<QQuickItem *>(o)) {
2500         item->setParentItem(that);
2501     } else {
2502         if (o->inherits("QGraphicsItem"))
2503             qWarning("Cannot add a QtQuick 1.0 item (%s) into a QtQuick 2.0 scene!", o->metaObject()->className());
2504
2505         // XXX todo - do we really want this behavior?
2506         o->setParent(that);
2507     }
2508 }
2509
2510 /*!
2511     \qmlproperty list<Object> QtQuick2::Item::data
2512     \default
2513
2514     The data property allows you to freely mix visual children and resources
2515     in an item.  If you assign a visual item to the data list it becomes
2516     a child and if you assign any other object type, it is added as a resource.
2517
2518     So you can write:
2519     \qml
2520     Item {
2521         Text {}
2522         Rectangle {}
2523         Timer {}
2524     }
2525     \endqml
2526
2527     instead of:
2528     \qml
2529     Item {
2530         children: [
2531             Text {},
2532             Rectangle {}
2533         ]
2534         resources: [
2535             Timer {}
2536         ]
2537     }
2538     \endqml
2539
2540     data is a behind-the-scenes property: you should never need to explicitly
2541     specify it.
2542  */
2543
2544 int QQuickItemPrivate::data_count(QQmlListProperty<QObject> *prop)
2545 {
2546     Q_UNUSED(prop);
2547     // XXX todo
2548     return 0;
2549 }
2550
2551 QObject *QQuickItemPrivate::data_at(QQmlListProperty<QObject> *prop, int i)
2552 {
2553     Q_UNUSED(prop);
2554     Q_UNUSED(i);
2555     // XXX todo
2556     return 0;
2557 }
2558
2559 void QQuickItemPrivate::data_clear(QQmlListProperty<QObject> *prop)
2560 {
2561     Q_UNUSED(prop);
2562     // XXX todo
2563 }
2564
2565 QObject *QQuickItemPrivate::resources_at(QQmlListProperty<QObject> *prop, int index)
2566 {
2567     const QObjectList children = prop->object->children();
2568     if (index < children.count())
2569         return children.at(index);
2570     else
2571         return 0;
2572 }
2573
2574 void QQuickItemPrivate::resources_append(QQmlListProperty<QObject> *prop, QObject *o)
2575 {
2576     // XXX todo - do we really want this behavior?
2577     o->setParent(prop->object);
2578 }
2579
2580 int QQuickItemPrivate::resources_count(QQmlListProperty<QObject> *prop)
2581 {
2582     return prop->object->children().count();
2583 }
2584
2585 void QQuickItemPrivate::resources_clear(QQmlListProperty<QObject> *prop)
2586 {
2587     // XXX todo - do we really want this behavior?
2588     const QObjectList children = prop->object->children();
2589     for (int index = 0; index < children.count(); index++)
2590         children.at(index)->setParent(0);
2591 }
2592
2593 QQuickItem *QQuickItemPrivate::children_at(QQmlListProperty<QQuickItem> *prop, int index)
2594 {
2595     QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2596     if (index >= p->childItems.count() || index < 0)
2597         return 0;
2598     else
2599         return p->childItems.at(index);
2600 }
2601
2602 void QQuickItemPrivate::children_append(QQmlListProperty<QQuickItem> *prop, QQuickItem *o)
2603 {
2604     if (!o)
2605         return;
2606
2607     QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2608     if (o->parentItem() == that)
2609         o->setParentItem(0);
2610
2611     o->setParentItem(that);
2612 }
2613
2614 int QQuickItemPrivate::children_count(QQmlListProperty<QQuickItem> *prop)
2615 {
2616     QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2617     return p->childItems.count();
2618 }
2619
2620 void QQuickItemPrivate::children_clear(QQmlListProperty<QQuickItem> *prop)
2621 {
2622     QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2623     QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2624     while (!p->childItems.isEmpty())
2625         p->childItems.at(0)->setParentItem(0);
2626 }
2627
2628 void QQuickItemPrivate::visibleChildren_append(QQmlListProperty<QQuickItem>*, QQuickItem *self)
2629 {
2630     // do nothing
2631     qmlInfo(self) << "QQuickItem: visibleChildren property is readonly and cannot be assigned to.";
2632 }
2633
2634 int QQuickItemPrivate::visibleChildren_count(QQmlListProperty<QQuickItem> *prop)
2635 {
2636     QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2637     int visibleCount = 0;
2638     int c = p->childItems.count();
2639     while (c--) {
2640         if (p->childItems.at(c)->isVisible()) visibleCount++;
2641     }
2642
2643     return visibleCount;
2644 }
2645
2646 QQuickItem *QQuickItemPrivate::visibleChildren_at(QQmlListProperty<QQuickItem> *prop, int index)
2647 {
2648     QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2649     const int childCount = p->childItems.count();
2650     if (index >= childCount || index < 0)
2651         return 0;
2652
2653     int visibleCount = -1;
2654     for (int i = 0; i < childCount; i++) {
2655         if (p->childItems.at(i)->isVisible()) visibleCount++;
2656         if (visibleCount == index) return p->childItems.at(i);
2657     }
2658     return 0;
2659 }
2660
2661 int QQuickItemPrivate::transform_count(QQmlListProperty<QQuickTransform> *prop)
2662 {
2663     QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2664     QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2665
2666     return p->transforms.count();
2667 }
2668
2669 void QQuickTransform::appendToItem(QQuickItem *item)
2670 {
2671     Q_D(QQuickTransform);
2672     if (!item)
2673         return;
2674
2675     QQuickItemPrivate *p = QQuickItemPrivate::get(item);
2676
2677     if (!d->items.isEmpty() && !p->transforms.isEmpty() && p->transforms.contains(this)) {
2678         p->transforms.removeOne(this);
2679         p->transforms.append(this);
2680     } else {
2681         p->transforms.append(this);
2682         d->items.append(item);
2683     }
2684
2685     p->dirty(QQuickItemPrivate::Transform);
2686 }
2687
2688 void QQuickTransform::prependToItem(QQuickItem *item)
2689 {
2690     Q_D(QQuickTransform);
2691     if (!item)
2692         return;
2693
2694     QQuickItemPrivate *p = QQuickItemPrivate::get(item);
2695
2696     if (!d->items.isEmpty() && !p->transforms.isEmpty() && p->transforms.contains(this)) {
2697         p->transforms.removeOne(this);
2698         p->transforms.prepend(this);
2699     } else {
2700         p->transforms.prepend(this);
2701         d->items.append(item);
2702     }
2703
2704     p->dirty(QQuickItemPrivate::Transform);
2705 }
2706
2707 void QQuickItemPrivate::transform_append(QQmlListProperty<QQuickTransform> *prop, QQuickTransform *transform)
2708 {
2709     if (!transform)
2710         return;
2711
2712     QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2713     transform->appendToItem(that);
2714 }
2715
2716 QQuickTransform *QQuickItemPrivate::transform_at(QQmlListProperty<QQuickTransform> *prop, int idx)
2717 {
2718     QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2719     QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2720
2721     if (idx < 0 || idx >= p->transforms.count())
2722         return 0;
2723     else
2724         return p->transforms.at(idx);
2725 }
2726
2727 void QQuickItemPrivate::transform_clear(QQmlListProperty<QQuickTransform> *prop)
2728 {
2729     QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2730     QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2731
2732     for (int ii = 0; ii < p->transforms.count(); ++ii) {
2733         QQuickTransform *t = p->transforms.at(ii);
2734         QQuickTransformPrivate *tp = QQuickTransformPrivate::get(t);
2735         tp->items.removeOne(that);
2736     }
2737
2738     p->transforms.clear();
2739
2740     p->dirty(QQuickItemPrivate::Transform);
2741 }
2742
2743 /*!
2744     \property QQuickItem::childrenRect
2745     \brief Specifies the geometry of an item's children
2746
2747     This property holds the (collective) position and size of the item's children.
2748 */
2749
2750 /*!
2751   \qmlproperty real QtQuick2::Item::x
2752   \qmlproperty real QtQuick2::Item::y
2753   \qmlproperty real QtQuick2::Item::width
2754   \qmlproperty real QtQuick2::Item::height
2755
2756   Defines the item's position and size relative to its parent.
2757
2758   \qml
2759   Item { x: 100; y: 100; width: 100; height: 100 }
2760   \endqml
2761  */
2762
2763 /*!
2764   \qmlproperty real QtQuick2::Item::z
2765
2766   Sets the stacking order of sibling items.  By default the stacking order is 0.
2767
2768   Items with a higher stacking value are drawn on top of siblings with a
2769   lower stacking order.  Items with the same stacking value are drawn
2770   bottom up in the order they appear.  Items with a negative stacking
2771   value are drawn under their parent's content.
2772
2773   The following example shows the various effects of stacking order.
2774
2775   \table
2776   \row
2777   \li \image declarative-item_stacking1.png
2778   \li Same \c z - later children above earlier children:
2779   \qml
2780   Item {
2781       Rectangle {
2782           color: "red"
2783           width: 100; height: 100
2784       }
2785       Rectangle {
2786           color: "blue"
2787           x: 50; y: 50; width: 100; height: 100
2788       }
2789   }
2790   \endqml
2791   \row
2792   \li \image declarative-item_stacking2.png
2793   \li Higher \c z on top:
2794   \qml
2795   Item {
2796       Rectangle {
2797           z: 1
2798           color: "red"
2799           width: 100; height: 100
2800       }
2801       Rectangle {
2802           color: "blue"
2803           x: 50; y: 50; width: 100; height: 100
2804       }
2805   }
2806   \endqml
2807   \row
2808   \li \image declarative-item_stacking3.png
2809   \li Same \c z - children above parents:
2810   \qml
2811   Item {
2812       Rectangle {
2813           color: "red"
2814           width: 100; height: 100
2815           Rectangle {
2816               color: "blue"
2817               x: 50; y: 50; width: 100; height: 100
2818           }
2819       }
2820   }
2821   \endqml
2822   \row
2823   \li \image declarative-item_stacking4.png
2824   \li Lower \c z below:
2825   \qml
2826   Item {
2827       Rectangle {
2828           color: "red"
2829           width: 100; height: 100
2830           Rectangle {
2831               z: -1
2832               color: "blue"
2833               x: 50; y: 50; width: 100; height: 100
2834           }
2835       }
2836   }
2837   \endqml
2838   \endtable
2839  */
2840
2841 /*!
2842     \qmlproperty bool QtQuick2::Item::visible
2843
2844     This property holds whether the item is visible. By default this is true.
2845
2846     Setting this property directly affects the \c visible value of child
2847     items. When set to \c false, the \c visible values of all child items also
2848     become \c false. When set to \c true, the \c visible values of child items
2849     are returned to \c true, unless they have explicitly been set to \c false.
2850
2851     (Because of this flow-on behavior, using the \c visible property may not
2852     have the intended effect if a property binding should only respond to
2853     explicit property changes. In such cases it may be better to use the
2854     \l opacity property instead.)
2855
2856     Setting this property to \c false automatically causes \l focus to be set
2857     to \c false, and this item will longer receive mouse and keyboard events.
2858     (In contrast, setting the \l opacity to 0 does not affect the \l focus
2859     property and the receiving of key events.)
2860
2861     \note This property's value is only affected by changes to this property or
2862     the parent's \c visible property. It does not change, for example, if this
2863     item moves off-screen, or if the \l opacity changes to 0.
2864 */
2865
2866
2867 /*!
2868   \qmlproperty AnchorLine QtQuick2::Item::anchors.top
2869   \qmlproperty AnchorLine QtQuick2::Item::anchors.bottom
2870   \qmlproperty AnchorLine QtQuick2::Item::anchors.left
2871   \qmlproperty AnchorLine QtQuick2::Item::anchors.right
2872   \qmlproperty AnchorLine QtQuick2::Item::anchors.horizontalCenter
2873   \qmlproperty AnchorLine QtQuick2::Item::anchors.verticalCenter
2874   \qmlproperty AnchorLine QtQuick2::Item::anchors.baseline
2875
2876   \qmlproperty Item QtQuick2::Item::anchors.fill
2877   \qmlproperty Item QtQuick2::Item::anchors.centerIn
2878
2879   \qmlproperty real QtQuick2::Item::anchors.margins
2880   \qmlproperty real QtQuick2::Item::anchors.topMargin
2881   \qmlproperty real QtQuick2::Item::anchors.bottomMargin
2882   \qmlproperty real QtQuick2::Item::anchors.leftMargin
2883   \qmlproperty real QtQuick2::Item::anchors.rightMargin
2884   \qmlproperty real QtQuick2::Item::anchors.horizontalCenterOffset
2885   \qmlproperty real QtQuick2::Item::anchors.verticalCenterOffset
2886   \qmlproperty real QtQuick2::Item::anchors.baselineOffset
2887
2888   \qmlproperty bool QtQuick2::Item::anchors.mirrored
2889   \qmlproperty bool QtQuick2::Item::anchors.alignWhenCentered
2890
2891   Anchors provide a way to position an item by specifying its
2892   relationship with other items.
2893
2894   Margins apply to top, bottom, left, right, and fill anchors.
2895   The \c anchors.margins property can be used to set all of the various margins at once, to the same value.
2896   Note that margins are anchor-specific and are not applied if an item does not
2897   use anchors.
2898
2899   Offsets apply for horizontal center, vertical center, and baseline anchors.
2900
2901   \table
2902   \row
2903   \li \image declarative-anchors_example.png
2904   \li Text anchored to Image, horizontally centered and vertically below, with a margin.
2905   \qml
2906   Item {
2907       Image {
2908           id: pic
2909           // ...
2910       }
2911       Text {
2912           id: label
2913           anchors.horizontalCenter: pic.horizontalCenter
2914           anchors.top: pic.bottom
2915           anchors.topMargin: 5
2916           // ...
2917       }
2918   }
2919   \endqml
2920   \row
2921   \li \image declarative-anchors_example2.png
2922   \li
2923   Left of Text anchored to right of Image, with a margin. The y
2924   property of both defaults to 0.
2925
2926   \qml
2927   Item {
2928       Image {
2929           id: pic
2930           // ...
2931       }
2932       Text {
2933           id: label
2934           anchors.left: pic.right
2935           anchors.leftMargin: 5
2936           // ...
2937       }
2938   }
2939   \endqml
2940   \endtable
2941
2942   \c anchors.fill provides a convenient way for one item to have the
2943   same geometry as another item, and is equivalent to connecting all
2944   four directional anchors.
2945
2946   To clear an anchor value, set it to \c undefined.
2947
2948   \c anchors.mirrored returns true it the layout has been \l {LayoutMirroring}{mirrored}.
2949
2950   \c anchors.alignWhenCentered (default true) forces centered anchors to align to a
2951   whole pixel, i.e. if the item being centered has an odd width/height the item
2952   will be positioned on a whole pixel rather than being placed on a half-pixel.
2953   This ensures the item is painted crisply.  There are cases where this is not
2954   desirable, for example when rotating the item jitters may be apparent as the
2955   center is rounded.
2956
2957   \note You can only anchor an item to siblings or a parent.
2958
2959   For more information see \l {anchor-layout}{Anchor Layouts}.
2960 */
2961
2962 /*!
2963   \property QQuickItem::baselineOffset
2964   \brief Speciifies the position of the item's baseline in local coordinates
2965
2966   The baseline of a \l Text item is the imaginary line on which the text
2967   sits. Controls containing text usually set their baseline to the
2968   baseline of their text.
2969
2970   For non-text items, a default baseline offset of 0 is used.
2971 */
2972 QQuickAnchors *QQuickItemPrivate::anchors() const
2973 {
2974     if (!_anchors) {
2975         Q_Q(const QQuickItem);
2976         _anchors = new QQuickAnchors(const_cast<QQuickItem *>(q));
2977         if (!componentComplete)
2978             _anchors->classBegin();
2979     }
2980     return _anchors;
2981 }
2982
2983 void QQuickItemPrivate::siblingOrderChanged()
2984 {
2985     Q_Q(QQuickItem);
2986     for (int ii = 0; ii < changeListeners.count(); ++ii) {
2987         const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
2988         if (change.types & QQuickItemPrivate::SiblingOrder) {
2989             change.listener->itemSiblingOrderChanged(q);
2990         }
2991     }
2992 }
2993
2994 QQmlListProperty<QObject> QQuickItemPrivate::data()
2995 {
2996     return QQmlListProperty<QObject>(q_func(), 0, QQuickItemPrivate::data_append,
2997                                              QQuickItemPrivate::data_count,
2998                                              QQuickItemPrivate::data_at,
2999                                              QQuickItemPrivate::data_clear);
3000 }
3001
3002 QRectF QQuickItem::childrenRect()
3003 {
3004     Q_D(QQuickItem);
3005     if (!d->extra.isAllocated() || !d->extra->contents) {
3006         d->extra.value().contents = new QQuickContents(this);
3007         if (d->componentComplete)
3008             d->extra->contents->complete();
3009     }
3010     return d->extra->contents->rectF();
3011 }
3012
3013 QList<QQuickItem *> QQuickItem::childItems() const
3014 {
3015     Q_D(const QQuickItem);
3016     return d->childItems;
3017 }
3018
3019 bool QQuickItem::clip() const
3020 {
3021     return flags() & ItemClipsChildrenToShape;
3022 }
3023
3024 void QQuickItem::setClip(bool c)
3025 {
3026     if (clip() == c)
3027         return;
3028
3029     setFlag(ItemClipsChildrenToShape, c);
3030
3031     emit clipChanged(c);
3032 }
3033
3034
3035 /*!
3036   This function is called to handle this item's changes in
3037   geometry from \a oldGeometry to \a newGeometry. If the two
3038   geometries are the same, it doesn't do anything.
3039  */
3040 void QQuickItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
3041 {
3042     Q_D(QQuickItem);
3043
3044     if (d->_anchors)
3045         QQuickAnchorsPrivate::get(d->_anchors)->updateMe();
3046
3047     bool xChange = (newGeometry.x() != oldGeometry.x());
3048     bool yChange = (newGeometry.y() != oldGeometry.y());
3049     bool widthChange = (newGeometry.width() != oldGeometry.width());
3050     bool heightChange = (newGeometry.height() != oldGeometry.height());
3051
3052     for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
3053         const QQuickItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
3054         if (change.types & QQuickItemPrivate::Geometry) {
3055             if (change.gTypes == QQuickItemPrivate::GeometryChange) {
3056                 change.listener->itemGeometryChanged(this, newGeometry, oldGeometry);
3057             } else if ((xChange && (change.gTypes & QQuickItemPrivate::XChange)) ||
3058                        (yChange && (change.gTypes & QQuickItemPrivate::YChange)) ||
3059                        (widthChange && (change.gTypes & QQuickItemPrivate::WidthChange)) ||
3060                        (heightChange && (change.gTypes & QQuickItemPrivate::HeightChange))) {
3061                 change.listener->itemGeometryChanged(this, newGeometry, oldGeometry);
3062             }
3063         }
3064     }
3065
3066     if (xChange)
3067         emit xChanged();
3068     if (yChange)
3069         emit yChanged();
3070     if (widthChange)
3071         emit widthChanged();
3072     if (heightChange)
3073         emit heightChanged();
3074 }
3075
3076 /*!
3077     Called by the rendering thread, as a result of
3078     QQuickItem::update(), when it is time to sync the state of the QML
3079     objects with the scene graph objects.
3080
3081     The function should return the root of the scene graph subtree for
3082     this item. Most implementations will return a single
3083     QSGGeometryNode containing the visual representation of this item.
3084     \a oldNode is the node that was returned the last time the
3085     function was called.
3086
3087     \code
3088     QSGNode *MyItem::updatePaintNode(QSGNode *node, UpdatePaintNodeData *)
3089     {
3090         QSGSimpleRectNode *n = static_cast<QSGSimpleRectNode *>(node);
3091         if (!n) {
3092             n = new QSGSimpleRectNode();
3093             n->setColor(Qt::red);
3094         }
3095         n->setRect(boundingRect());
3096         return n;
3097     }
3098     \endcode
3099
3100     The main thread is blocked while this function is executed so it is safe to read
3101     values from the QQuickItem instance and other objects in the main thread.
3102
3103     If no call to QQuickItem::updatePaintNode() result in actual scene graph
3104     changes, like QSGNode::markDirty() or adding and removing nodes, then
3105     the underlying implementation may decide to not render the scene again as
3106     the visual outcome is identical.
3107
3108     \warning It is crucial that OpenGL operations and interaction with
3109     the scene graph happens exclusively on the rendering thread,
3110     primarily during the QQuickItem::updatePaintNode() call. The best
3111     rule of thumb is to only use classes with the "QSG" prefix inside
3112     the QQuickItem::updatePaintNode() function.
3113
3114     \sa QSGMaterial, QSGSimpleMaterial, QSGGeometryNode, QSGGeometry,
3115     QSGFlatColorMaterial, QSGTextureMaterial, QSGNode::markDirty()
3116  */
3117
3118 QSGNode *QQuickItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
3119 {
3120     delete oldNode;
3121     return 0;
3122 }
3123
3124 /*!
3125     This function is called when the item's scene graph resources are no longer needed.
3126     It allows items to free its resources, for instance textures, that are not owned by scene graph
3127     nodes. Note that scene graph nodes are managed by QQuickCanvas and should not be deleted by
3128     this function. Scene graph resources are no longer needed when the parent is set to null and
3129     the item is not used by any \l ShaderEffect or \l ShaderEffectSource.
3130
3131     This function is called from the main thread. Therefore, resources used by the scene graph
3132     should not be deleted directly, but by calling \l QObject::deleteLater().
3133
3134     \note The item destructor still needs to free its scene graph resources if not already done.
3135  */
3136
3137 void QQuickItem::releaseResources()
3138 {
3139 }
3140
3141 QSGTransformNode *QQuickItemPrivate::createTransformNode()
3142 {
3143     return new QSGTransformNode;
3144 }
3145
3146 void QQuickItem::updatePolish()
3147 {
3148 }
3149
3150 void QQuickItemPrivate::addItemChangeListener(QQuickItemChangeListener *listener, ChangeTypes types)
3151 {
3152     changeListeners.append(ChangeListener(listener, types));
3153 }
3154
3155 void QQuickItemPrivate::removeItemChangeListener(QQuickItemChangeListener *listener, ChangeTypes types)
3156 {
3157     ChangeListener change(listener, types);
3158     changeListeners.removeOne(change);
3159 }
3160
3161 void QQuickItemPrivate::updateOrAddGeometryChangeListener(QQuickItemChangeListener *listener, GeometryChangeTypes types)
3162 {
3163     ChangeListener change(listener, types);
3164     int index = changeListeners.find(change);
3165     if (index > -1)
3166         changeListeners[index].gTypes = change.gTypes;  //we may have different GeometryChangeTypes
3167     else
3168         changeListeners.append(change);
3169 }
3170
3171 void QQuickItemPrivate::updateOrRemoveGeometryChangeListener(QQuickItemChangeListener *listener,
3172                                                              GeometryChangeTypes types)
3173 {
3174     ChangeListener change(listener, types);
3175     if (types == NoChange) {
3176         changeListeners.removeOne(change);
3177     } else {
3178         int index = changeListeners.find(change);
3179         if (index > -1)
3180             changeListeners[index].gTypes = change.gTypes;  //we may have different GeometryChangeTypes
3181     }
3182 }
3183
3184 void QQuickItem::keyPressEvent(QKeyEvent *event)
3185 {
3186     event->ignore();
3187 }
3188
3189 void QQuickItem::keyReleaseEvent(QKeyEvent *event)
3190 {
3191     event->ignore();
3192 }
3193
3194 void QQuickItem::inputMethodEvent(QInputMethodEvent *event)
3195 {
3196     event->ignore();
3197 }
3198
3199 void QQuickItem::focusInEvent(QFocusEvent *)
3200 {
3201 #ifndef QT_NO_ACCESSIBILITY
3202     QAccessibleEvent ev(this, QAccessible::Focus);
3203     QAccessible::updateAccessibility(&ev);
3204 #endif
3205 }
3206
3207 void QQuickItem::focusOutEvent(QFocusEvent *)
3208 {
3209 }
3210
3211 void QQuickItem::mousePressEvent(QMouseEvent *event)
3212 {
3213     event->ignore();
3214 }
3215
3216 void QQuickItem::mouseMoveEvent(QMouseEvent *event)
3217 {
3218     event->ignore();
3219 }
3220
3221 void QQuickItem::mouseReleaseEvent(QMouseEvent *event)
3222 {
3223     event->ignore();
3224 }
3225
3226 void QQuickItem::mouseDoubleClickEvent(QMouseEvent *)
3227 {
3228 }
3229
3230 void QQuickItem::mouseUngrabEvent()
3231 {
3232     // XXX todo
3233 }
3234
3235 void QQuickItem::touchUngrabEvent()
3236 {
3237     // XXX todo
3238 }
3239
3240 void QQuickItem::wheelEvent(QWheelEvent *event)
3241 {
3242     event->ignore();
3243 }
3244
3245 void QQuickItem::touchEvent(QTouchEvent *event)
3246 {
3247     event->ignore();
3248 }
3249
3250 void QQuickItem::hoverEnterEvent(QHoverEvent *event)
3251 {
3252     Q_UNUSED(event);
3253 }
3254
3255 void QQuickItem::hoverMoveEvent(QHoverEvent *event)
3256 {
3257     Q_UNUSED(event);
3258 }
3259
3260 void QQuickItem::hoverLeaveEvent(QHoverEvent *event)
3261 {
3262     Q_UNUSED(event);
3263 }
3264
3265 void QQuickItem::dragEnterEvent(QDragEnterEvent *event)
3266 {
3267     Q_UNUSED(event);
3268 }
3269
3270 void QQuickItem::dragMoveEvent(QDragMoveEvent *event)
3271 {
3272
3273     Q_UNUSED(event);
3274 }
3275
3276 void QQuickItem::dragLeaveEvent(QDragLeaveEvent *event)
3277 {
3278
3279     Q_UNUSED(event);
3280 }
3281
3282 void QQuickItem::dropEvent(QDropEvent *event)
3283 {
3284     Q_UNUSED(event);
3285 }
3286
3287 bool QQuickItem::childMouseEventFilter(QQuickItem *, QEvent *)
3288 {
3289     return false;
3290 }
3291
3292 void QQuickItem::windowDeactivateEvent()
3293 {
3294     foreach (QQuickItem* item, childItems()) {
3295         item->windowDeactivateEvent();
3296     }
3297 }
3298
3299 QVariant QQuickItem::inputMethodQuery(Qt::InputMethodQuery query) const
3300 {
3301     Q_D(const QQuickItem);
3302     QVariant v;
3303
3304     switch (query) {
3305     case Qt::ImEnabled:
3306         v = (bool)(flags() & ItemAcceptsInputMethod);
3307         break;
3308     case Qt::ImHints:
3309     case Qt::ImCursorRectangle:
3310     case Qt::ImFont:
3311     case Qt::ImCursorPosition:
3312     case Qt::ImSurroundingText:
3313     case Qt::ImCurrentSelection:
3314     case Qt::ImMaximumTextLength:
3315     case Qt::ImAnchorPosition:
3316     case Qt::ImPreferredLanguage:
3317         if (d->extra.isAllocated() && d->extra->keyHandler)
3318             v = d->extra->keyHandler->inputMethodQuery(query);
3319     default:
3320         break;
3321     }
3322
3323     return v;
3324 }
3325
3326 QQuickAnchorLine QQuickItemPrivate::left() const
3327 {
3328     Q_Q(const QQuickItem);
3329     return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Left);
3330 }
3331
3332 QQuickAnchorLine QQuickItemPrivate::right() const
3333 {
3334     Q_Q(const QQuickItem);
3335     return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Right);
3336 }
3337
3338 QQuickAnchorLine QQuickItemPrivate::horizontalCenter() const
3339 {
3340     Q_Q(const QQuickItem);
3341     return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::HCenter);
3342 }
3343
3344 QQuickAnchorLine QQuickItemPrivate::top() const
3345 {
3346     Q_Q(const QQuickItem);
3347     return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Top);
3348 }
3349
3350 QQuickAnchorLine QQuickItemPrivate::bottom() const
3351 {
3352     Q_Q(const QQuickItem);
3353     return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Bottom);
3354 }
3355
3356 QQuickAnchorLine QQuickItemPrivate::verticalCenter() const
3357 {
3358     Q_Q(const QQuickItem);
3359     return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::VCenter);
3360 }
3361
3362 QQuickAnchorLine QQuickItemPrivate::baseline() const
3363 {
3364     Q_Q(const QQuickItem);
3365     return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Baseline);
3366 }
3367
3368 qreal QQuickItem::baselineOffset() const
3369 {
3370     Q_D(const QQuickItem);
3371     if (d->baselineOffsetValid) {
3372         return d->baselineOffset;
3373     } else {
3374         return 0.0;
3375     }
3376 }
3377
3378 void QQuickItem::setBaselineOffset(qreal offset)
3379 {
3380     Q_D(QQuickItem);
3381     if (offset == d->baselineOffset)
3382         return;
3383
3384     d->baselineOffset = offset;
3385     d->baselineOffsetValid = true;
3386
3387     for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
3388         const QQuickItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
3389         if (change.types & QQuickItemPrivate::Geometry) {
3390             QQuickAnchorsPrivate *anchor = change.listener->anchorPrivate();
3391             if (anchor)
3392                 anchor->updateVerticalAnchors();
3393         }
3394     }
3395
3396     if (d->_anchors && (d->_anchors->usedAnchors() & QQuickAnchors::BaselineAnchor))
3397         QQuickAnchorsPrivate::get(d->_anchors)->updateVerticalAnchors();
3398
3399     emit baselineOffsetChanged(offset);
3400 }
3401
3402
3403 /*!
3404  * Schedules a call to updatePaintNode() for this item.
3405  *
3406  * The call to QQuickItem::updatePaintNode() will always happen if the
3407  * item is showing in a QQuickCanvas.
3408  *
3409  * Only items which specifies QQuickItem::ItemHasContents are allowed
3410  * to call QQuickItem::update().
3411  */
3412 void QQuickItem::update()
3413 {
3414     Q_D(QQuickItem);
3415     Q_ASSERT(flags() & ItemHasContents);
3416     d->dirty(QQuickItemPrivate::Content);
3417 }
3418
3419 void QQuickItem::polish()
3420 {
3421     Q_D(QQuickItem);
3422     if (!d->polishScheduled) {
3423         d->polishScheduled = true;
3424         if (d->canvas) {
3425             QQuickCanvasPrivate *p = QQuickCanvasPrivate::get(d->canvas);
3426             bool maybeupdate = p->itemsToPolish.isEmpty();
3427             p->itemsToPolish.insert(this);
3428             if (maybeupdate) d->canvas->maybeUpdate();
3429         }
3430     }
3431 }
3432
3433 /*!
3434     \qmlmethod object QtQuick2::Item::mapFromItem(Item item, real x, real y)
3435     \qmlmethod object QtQuick2::Item::mapFromItem(Item item, real x, real y, real width, real height)
3436
3437     Maps the point (\a x, \a y) or rect (\a x, \a y, \a width, \a height), which is in \a
3438     item's coordinate system, to this item's coordinate system, and returns an object with \c x and
3439     \c y (and optionally \c width and \c height) properties matching the mapped coordinate.
3440
3441     If \a item is a \c null value, this maps the point or rect from the coordinate system of
3442     the root QML view.
3443 */
3444 void QQuickItem::mapFromItem(QQmlV8Function *args) const
3445 {
3446     if (args->Length() != 0) {
3447         v8::Local<v8::Value> item = (*args)[0];
3448         QV8Engine *engine = args->engine();
3449
3450         QQuickItem *itemObj = 0;
3451         if (!item->IsNull())
3452             itemObj = qobject_cast<QQuickItem*>(engine->toQObject(item));
3453
3454         if (!itemObj && !item->IsNull()) {
3455             qmlInfo(this) << "mapFromItem() given argument \"" << engine->toString(item->ToString())
3456                           << "\" which is neither null nor an Item";
3457             return;
3458         }
3459
3460         v8::Local<v8::Object> rv = v8::Object::New();
3461         args->returnValue(rv);
3462
3463         qreal x = (args->Length() > 1)?(*args)[1]->NumberValue():0;
3464         qreal y = (args->Length() > 2)?(*args)[2]->NumberValue():0;
3465
3466         if (args->Length() > 3) {
3467             qreal w = (*args)[3]->NumberValue();
3468             qreal h = (args->Length() > 4)?(*args)[4]->NumberValue():0;
3469
3470             QRectF r = mapRectFromItem(itemObj, QRectF(x, y, w, h));
3471
3472             rv->Set(v8::String::New("x"), v8::Number::New(r.x()));
3473             rv->Set(v8::String::New("y"), v8::Number::New(r.y()));
3474             rv->Set(v8::String::New("width"), v8::Number::New(r.width()));
3475             rv->Set(v8::String::New("height"), v8::Number::New(r.height()));
3476         } else {
3477             QPointF p = mapFromItem(itemObj, QPointF(x, y));
3478
3479             rv->Set(v8::String::New("x"), v8::Number::New(p.x()));
3480             rv->Set(v8::String::New("y"), v8::Number::New(p.y()));
3481         }
3482     }
3483 }
3484
3485 QTransform QQuickItem::itemTransform(QQuickItem *other, bool *ok) const
3486 {
3487     Q_D(const QQuickItem);
3488
3489     // XXX todo - we need to be able to handle common parents better and detect
3490     // invalid cases
3491     if (ok) *ok = true;
3492
3493     QTransform t = d->itemToCanvasTransform();
3494     if (other) t *= QQuickItemPrivate::get(other)->canvasToItemTransform();
3495
3496     return t;
3497 }
3498
3499 /*!
3500     \qmlmethod object QtQuick2::Item::mapToItem(Item item, real x, real y)
3501     \qmlmethod object QtQuick2::Item::mapToItem(Item item, real x, real y, real width, real height)
3502
3503     Maps the point (\a x, \a y) or rect (\a x, \a y, \a width, \a height), which is in this
3504     item's coordinate system, to \a item's coordinate system, and returns an object with \c x and
3505     \c y (and optionally \c width and \c height) properties matching the mapped coordinate.
3506
3507     If \a item is a \c null value, this maps the point or rect to the coordinate system of the
3508     root QML view.
3509 */
3510 void QQuickItem::mapToItem(QQmlV8Function *args) const
3511 {
3512     if (args->Length() != 0) {
3513         v8::Local<v8::Value> item = (*args)[0];
3514         QV8Engine *engine = args->engine();
3515
3516         QQuickItem *itemObj = 0;
3517         if (!item->IsNull())
3518             itemObj = qobject_cast<QQuickItem*>(engine->toQObject(item));
3519
3520         if (!itemObj && !item->IsNull()) {
3521             qmlInfo(this) << "mapToItem() given argument \"" << engine->toString(item->ToString())
3522                           << "\" which is neither null nor an Item";
3523             return;
3524         }
3525
3526         v8::Local<v8::Object> rv = v8::Object::New();
3527         args->returnValue(rv);
3528
3529         qreal x = (args->Length() > 1)?(*args)[1]->NumberValue():0;
3530         qreal y = (args->Length() > 2)?(*args)[2]->NumberValue():0;
3531
3532         if (args->Length() > 3) {
3533             qreal w = (*args)[3]->NumberValue();
3534             qreal h = (args->Length() > 4)?(*args)[4]->NumberValue():0;
3535
3536             QRectF r = mapRectToItem(itemObj, QRectF(x, y, w, h));
3537
3538             rv->Set(v8::String::New("x"), v8::Number::New(r.x()));
3539             rv->Set(v8::String::New("y"), v8::Number::New(r.y()));
3540             rv->Set(v8::String::New("width"), v8::Number::New(r.width()));
3541             rv->Set(v8::String::New("height"), v8::Number::New(r.height()));
3542         } else {
3543             QPointF p = mapToItem(itemObj, QPointF(x, y));
3544
3545             rv->Set(v8::String::New("x"), v8::Number::New(p.x()));
3546             rv->Set(v8::String::New("y"), v8::Number::New(p.y()));
3547         }
3548     }
3549 }
3550
3551 void QQuickItem::forceActiveFocus()
3552 {
3553     setFocus(true);
3554     QQuickItem *parent = parentItem();
3555     while (parent) {
3556         if (parent->flags() & QQuickItem::ItemIsFocusScope) {
3557             parent->setFocus(true);
3558         }
3559         parent = parent->parentItem();
3560     }
3561 }
3562
3563 QQuickItem *QQuickItem::childAt(qreal x, qreal y) const
3564 {
3565     // XXX todo - should this include transform etc.?
3566     const QList<QQuickItem *> children = childItems();
3567     for (int i = children.count()-1; i >= 0; --i) {
3568         QQuickItem *child = children.at(i);
3569         if (child->isVisible() && child->x() <= x
3570                 && child->x() + child->width() >= x
3571                 && child->y() <= y
3572                 && child->y() + child->height() >= y)
3573             return child;
3574     }
3575     return 0;
3576 }
3577
3578 QQmlListProperty<QObject> QQuickItemPrivate::resources()
3579 {
3580     return QQmlListProperty<QObject>(q_func(), 0, QQuickItemPrivate::resources_append,
3581                                              QQuickItemPrivate::resources_count,
3582                                              QQuickItemPrivate::resources_at,
3583                                              QQuickItemPrivate::resources_clear);
3584 }
3585
3586 QQmlListProperty<QQuickItem> QQuickItemPrivate::children()
3587 {
3588     return QQmlListProperty<QQuickItem>(q_func(), 0, QQuickItemPrivate::children_append,
3589                                              QQuickItemPrivate::children_count,
3590                                              QQuickItemPrivate::children_at,
3591                                              QQuickItemPrivate::children_clear);
3592
3593 }
3594
3595 /*!
3596   \qmlproperty real QtQuick2::Item::visibleChildren
3597   This read-only property lists all of the item's children that are currently visible.
3598   Note that a child's visibility may have changed explicitly, or because the visibility
3599   of this (it's parent) item or another grandparent changed.
3600 */
3601 QQmlListProperty<QQuickItem> QQuickItemPrivate::visibleChildren()
3602 {
3603     return QQmlListProperty<QQuickItem>(q_func(), 0, QQuickItemPrivate::visibleChildren_append,
3604                                              QQuickItemPrivate::visibleChildren_count,
3605                                              QQuickItemPrivate::visibleChildren_at);
3606
3607 }
3608
3609 QQmlListProperty<QQuickState> QQuickItemPrivate::states()
3610 {
3611     return _states()->statesProperty();
3612 }
3613
3614 QQmlListProperty<QQuickTransition> QQuickItemPrivate::transitions()
3615 {
3616     return _states()->transitionsProperty();
3617 }
3618
3619 QString QQuickItemPrivate::state() const
3620 {
3621     if (!_stateGroup)
3622         return QString();
3623     else
3624         return _stateGroup->state();
3625 }
3626
3627 void QQuickItemPrivate::setState(const QString &state)
3628 {
3629     _states()->setState(state);
3630 }
3631
3632 QString QQuickItem::state() const
3633 {
3634     Q_D(const QQuickItem);
3635     return d->state();
3636 }
3637
3638 void QQuickItem::setState(const QString &state)
3639 {
3640     Q_D(QQuickItem);
3641     d->setState(state);
3642 }
3643
3644 QQmlListProperty<QQuickTransform> QQuickItem::transform()
3645 {
3646     return QQmlListProperty<QQuickTransform>(this, 0, QQuickItemPrivate::transform_append,
3647                                                      QQuickItemPrivate::transform_count,
3648                                                      QQuickItemPrivate::transform_at,
3649                                                      QQuickItemPrivate::transform_clear);
3650 }
3651
3652 void QQuickItem::classBegin()
3653 {
3654     Q_D(QQuickItem);
3655     d->componentComplete = false;
3656     if (d->_stateGroup)
3657         d->_stateGroup->classBegin();
3658     if (d->_anchors)
3659         d->_anchors->classBegin();
3660     if (d->extra.isAllocated() && d->extra->layer)
3661         d->extra->layer->classBegin();
3662 }
3663
3664 void QQuickItem::componentComplete()
3665 {
3666     Q_D(QQuickItem);
3667     d->componentComplete = true;
3668     if (d->_stateGroup)
3669         d->_stateGroup->componentComplete();
3670     if (d->_anchors) {
3671         d->_anchors->componentComplete();
3672         QQuickAnchorsPrivate::get(d->_anchors)->updateOnComplete();
3673     }
3674
3675     if (d->extra.isAllocated() && d->extra->layer)
3676         d->extra->layer->componentComplete();
3677
3678     if (d->extra.isAllocated() && d->extra->keyHandler)
3679         d->extra->keyHandler->componentComplete();
3680
3681     if (d->extra.isAllocated() && d->extra->contents)
3682         d->extra->contents->complete();
3683 }
3684
3685 QQuickStateGroup *QQuickItemPrivate::_states()
3686 {
3687     Q_Q(QQuickItem);
3688     if (!_stateGroup) {
3689         _stateGroup = new QQuickStateGroup;
3690         if (!componentComplete)
3691             _stateGroup->classBegin();
3692         qmlobject_connect(_stateGroup, QQuickStateGroup, SIGNAL(stateChanged(QString)),
3693                           q, QQuickItem, SIGNAL(stateChanged(QString)))
3694     }
3695
3696     return _stateGroup;
3697 }
3698
3699 QPointF QQuickItemPrivate::computeTransformOrigin() const
3700 {
3701     switch (origin()) {
3702     default:
3703     case QQuickItem::TopLeft:
3704         return QPointF(0, 0);
3705     case QQuickItem::Top:
3706         return QPointF(width / 2., 0);
3707     case QQuickItem::TopRight:
3708         return QPointF(width, 0);
3709     case QQuickItem::Left:
3710         return QPointF(0, height / 2.);
3711     case QQuickItem::Center:
3712         return QPointF(width / 2., height / 2.);
3713     case QQuickItem::Right:
3714         return QPointF(width, height / 2.);
3715     case QQuickItem::BottomLeft:
3716         return QPointF(0, height);
3717     case QQuickItem::Bottom:
3718         return QPointF(width / 2., height);
3719     case QQuickItem::BottomRight:
3720         return QPointF(width, height);
3721     }
3722 }
3723
3724 void QQuickItemPrivate::transformChanged()
3725 {
3726     if (extra.isAllocated() && extra->layer)
3727         extra->layer->updateMatrix();
3728 }
3729
3730 void QQuickItemPrivate::deliverKeyEvent(QKeyEvent *e)
3731 {
3732     Q_Q(QQuickItem);
3733
3734     Q_ASSERT(e->isAccepted());
3735     if (extra.isAllocated() && extra->keyHandler) {
3736         if (e->type() == QEvent::KeyPress)
3737             extra->keyHandler->keyPressed(e, false);
3738         else
3739             extra->keyHandler->keyReleased(e, false);
3740
3741         if (e->isAccepted())
3742             return;
3743         else
3744             e->accept();
3745     }
3746
3747     if (e->type() == QEvent::KeyPress)
3748         q->keyPressEvent(e);
3749     else
3750         q->keyReleaseEvent(e);
3751
3752     if (e->isAccepted())
3753         return;
3754
3755     if (extra.isAllocated() && extra->keyHandler) {
3756         e->accept();
3757
3758         if (e->type() == QEvent::KeyPress)
3759             extra->keyHandler->keyPressed(e, true);
3760         else
3761             extra->keyHandler->keyReleased(e, true);
3762     }
3763 }
3764
3765 void QQuickItemPrivate::deliverInputMethodEvent(QInputMethodEvent *e)
3766 {
3767     Q_Q(QQuickItem);
3768
3769     Q_ASSERT(e->isAccepted());
3770     if (extra.isAllocated() && extra->keyHandler) {
3771         extra->keyHandler->inputMethodEvent(e, false);
3772
3773         if (e->isAccepted())
3774             return;
3775         else
3776             e->accept();
3777     }
3778
3779     q->inputMethodEvent(e);
3780
3781     if (e->isAccepted())
3782         return;
3783
3784     if (extra.isAllocated() && extra->keyHandler) {
3785         e->accept();
3786
3787         extra->keyHandler->inputMethodEvent(e, true);
3788     }
3789 }
3790
3791 void QQuickItemPrivate::deliverFocusEvent(QFocusEvent *e)
3792 {
3793     Q_Q(QQuickItem);
3794
3795     if (e->type() == QEvent::FocusIn) {
3796         q->focusInEvent(e);
3797     } else {
3798         q->focusOutEvent(e);
3799     }
3800 }
3801
3802 void QQuickItemPrivate::deliverMouseEvent(QMouseEvent *e)
3803 {
3804     Q_Q(QQuickItem);
3805
3806     Q_ASSERT(e->isAccepted());
3807
3808     switch (e->type()) {
3809     default:
3810         Q_ASSERT(!"Unknown event type");
3811     case QEvent::MouseMove:
3812         q->mouseMoveEvent(e);
3813         break;
3814     case QEvent::MouseButtonPress:
3815         q->mousePressEvent(e);
3816         break;
3817     case QEvent::MouseButtonRelease:
3818         q->mouseReleaseEvent(e);
3819         break;
3820     case QEvent::MouseButtonDblClick:
3821         q->mouseDoubleClickEvent(e);
3822         break;
3823     }
3824 }
3825
3826 void QQuickItemPrivate::deliverWheelEvent(QWheelEvent *e)
3827 {
3828     Q_Q(QQuickItem);
3829     q->wheelEvent(e);
3830 }
3831
3832 void QQuickItemPrivate::deliverTouchEvent(QTouchEvent *e)
3833 {
3834     Q_Q(QQuickItem);
3835     q->touchEvent(e);
3836 }
3837
3838 void QQuickItemPrivate::deliverHoverEvent(QHoverEvent *e)
3839 {
3840     Q_Q(QQuickItem);
3841     switch (e->type()) {
3842     default:
3843         Q_ASSERT(!"Unknown event type");
3844     case QEvent::HoverEnter:
3845         q->hoverEnterEvent(e);
3846         break;
3847     case QEvent::HoverLeave:
3848         q->hoverLeaveEvent(e);
3849         break;
3850     case QEvent::HoverMove:
3851         q->hoverMoveEvent(e);
3852         break;
3853     }
3854 }
3855
3856 void QQuickItemPrivate::deliverDragEvent(QEvent *e)
3857 {
3858     Q_Q(QQuickItem);
3859     switch (e->type()) {
3860     default:
3861         Q_ASSERT(!"Unknown event type");
3862     case QEvent::DragEnter:
3863         q->dragEnterEvent(static_cast<QDragEnterEvent *>(e));
3864         break;
3865     case QEvent::DragLeave:
3866         q->dragLeaveEvent(static_cast<QDragLeaveEvent *>(e));
3867         break;
3868     case QEvent::DragMove:
3869         q->dragMoveEvent(static_cast<QDragMoveEvent *>(e));
3870         break;
3871     case QEvent::Drop:
3872         q->dropEvent(static_cast<QDropEvent *>(e));
3873         break;
3874     }
3875 }
3876
3877 void QQuickItem::itemChange(ItemChange change, const ItemChangeData &value)
3878 {
3879     Q_UNUSED(change);
3880     Q_UNUSED(value);
3881 }
3882
3883 /*!
3884     Notify input method on updated query values if needed. \a indicates changed attributes.
3885 */
3886 void QQuickItem::updateInputMethod(Qt::InputMethodQueries queries)
3887 {
3888     if (hasActiveFocus())
3889         qApp->inputMethod()->update(queries);
3890 }
3891
3892 /*! \internal */
3893 // XXX todo - do we want/need this anymore?
3894 QRectF QQuickItem::boundingRect() const
3895 {
3896     Q_D(const QQuickItem);
3897     return QRectF(0, 0, d->width, d->height);
3898 }
3899
3900 /*! \internal */
3901 QRectF QQuickItem::clipRect() const
3902 {
3903     Q_D(const QQuickItem);
3904     return QRectF(0, 0, d->width, d->height);
3905 }
3906
3907
3908 QQuickItem::TransformOrigin QQuickItem::transformOrigin() const
3909 {
3910     Q_D(const QQuickItem);
3911     return d->origin();
3912 }
3913
3914 void QQuickItem::setTransformOrigin(TransformOrigin origin)
3915 {
3916     Q_D(QQuickItem);
3917     if (origin == d->origin())
3918         return;
3919
3920     d->extra.value().origin = origin;
3921     d->dirty(QQuickItemPrivate::TransformOrigin);
3922
3923     emit transformOriginChanged(d->origin());
3924 }
3925
3926 QPointF QQuickItem::transformOriginPoint() const
3927 {
3928     Q_D(const QQuickItem);
3929     if (d->extra.isAllocated() && !d->extra->userTransformOriginPoint.isNull())
3930         return d->extra->userTransformOriginPoint;
3931     return d->computeTransformOrigin();
3932 }
3933
3934 void QQuickItem::setTransformOriginPoint(const QPointF &point)
3935 {
3936     Q_D(QQuickItem);
3937     if (d->extra.value().userTransformOriginPoint == point)
3938         return;
3939
3940     d->extra->userTransformOriginPoint = point;
3941     d->dirty(QQuickItemPrivate::TransformOrigin);
3942 }
3943
3944 qreal QQuickItem::z() const
3945 {
3946     Q_D(const QQuickItem);
3947     return d->z();
3948 }
3949
3950 void QQuickItem::setZ(qreal v)
3951 {
3952     Q_D(QQuickItem);
3953     if (d->z() == v)
3954         return;
3955
3956     d->extra.value().z = v;
3957
3958     d->dirty(QQuickItemPrivate::ZValue);
3959     if (d->parentItem) {
3960         QQuickItemPrivate::get(d->parentItem)->dirty(QQuickItemPrivate::ChildrenStackingChanged);
3961         QQuickItemPrivate::get(d->parentItem)->markSortedChildrenDirty(this);
3962     }
3963
3964     emit zChanged();
3965
3966     if (d->extra.isAllocated() && d->extra->layer)
3967         d->extra->layer->updateZ();
3968 }
3969
3970
3971 /*!
3972   \qmlproperty real QtQuick2::Item::rotation
3973   This property holds the rotation of the item in degrees clockwise.
3974
3975   This specifies how many degrees to rotate the item around its transformOrigin.
3976   The default rotation is 0 degrees (i.e. not rotated at all).
3977
3978   \table
3979   \row
3980   \li \image declarative-rotation.png
3981   \li
3982   \qml
3983   Rectangle {
3984       color: "blue"
3985       width: 100; height: 100
3986       Rectangle {
3987           color: "red"
3988           x: 25; y: 25; width: 50; height: 50
3989           rotation: 30
3990       }
3991   }
3992   \endqml
3993   \endtable
3994
3995   \sa transform, Rotation
3996 */
3997
3998 /*!
3999   \qmlproperty real QtQuick2::Item::scale
4000   This property holds the scale of the item.
4001
4002   A scale of less than 1 means the item will be displayed smaller than
4003   normal, and a scale of greater than 1 means the item will be
4004   displayed larger than normal.  A negative scale means the item will
4005   be mirrored.
4006
4007   By default, items are displayed at a scale of 1 (i.e. at their
4008   normal size).
4009
4010   Scaling is from the item's transformOrigin.
4011
4012   \table
4013   \row
4014   \li \image declarative-scale.png
4015   \li
4016   \qml
4017   Rectangle {
4018       color: "blue"
4019       width: 100; height: 100
4020       Rectangle {
4021           color: "green"
4022           width: 25; height: 25
4023       }
4024       Rectangle {
4025           color: "red"
4026           x: 25; y: 25; width: 50; height: 50
4027           scale: 1.4
4028       }
4029   }
4030   \endqml
4031   \endtable
4032
4033   \sa transform, Scale
4034 */
4035
4036 /*!
4037   \qmlproperty real QtQuick2::Item::opacity
4038
4039   This property holds the opacity of the item.  Opacity is specified as a
4040   number between 0 (fully transparent) and 1 (fully opaque).  The default is 1.
4041
4042   When this property is set, the specified opacity is also applied
4043   individually to child items.  In almost all cases this is what you want,
4044   but in some cases it may produce undesired results. For example in the
4045   second set of rectangles below, the red rectangle has specified an opacity
4046   of 0.5, which affects the opacity of its blue child rectangle even though
4047   the child has not specified an opacity.
4048
4049   \table
4050   \row
4051   \li \image declarative-item_opacity1.png
4052   \li
4053   \qml
4054     Item {
4055         Rectangle {
4056             color: "red"
4057             width: 100; height: 100
4058             Rectangle {
4059                 color: "blue"
4060                 x: 50; y: 50; width: 100; height: 100
4061             }
4062         }
4063     }
4064   \endqml
4065   \row
4066   \li \image declarative-item_opacity2.png
4067   \li
4068   \qml
4069     Item {
4070         Rectangle {
4071             opacity: 0.5
4072             color: "red"
4073             width: 100; height: 100
4074             Rectangle {
4075                 color: "blue"
4076                 x: 50; y: 50; width: 100; height: 100
4077             }
4078         }
4079     }
4080   \endqml
4081   \endtable
4082
4083   If an item's opacity is set to 0, the item will no longer receive mouse
4084   events, but will continue to receive key events and will retain the keyboard
4085   \l focus if it has been set. (In contrast, setting the \l visible property
4086   to \c false stops both mouse and keyboard events, and also removes focus
4087   from the item.)
4088 */
4089
4090 /*!
4091   Returns a value indicating whether mouse input should
4092   remain with this item exclusively.
4093
4094   \sa setKeepMouseGrab()
4095  */
4096
4097 qreal QQuickItem::rotation() const
4098 {
4099     Q_D(const QQuickItem);
4100     return d->rotation();
4101 }
4102
4103 void QQuickItem::setRotation(qreal r)
4104 {
4105     Q_D(QQuickItem);
4106     if (d->rotation() == r)
4107         return;
4108
4109     d->extra.value().rotation = r;
4110
4111     d->dirty(QQuickItemPrivate::BasicTransform);
4112
4113     d->itemChange(ItemRotationHasChanged, r);
4114
4115     emit rotationChanged();
4116 }
4117
4118 qreal QQuickItem::scale() const
4119 {
4120     Q_D(const QQuickItem);
4121     return d->scale();
4122 }
4123
4124 void QQuickItem::setScale(qreal s)
4125 {
4126     Q_D(QQuickItem);
4127     if (d->scale() == s)
4128         return;
4129
4130     d->extra.value().scale = s;
4131
4132     d->dirty(QQuickItemPrivate::BasicTransform);
4133
4134     emit scaleChanged();
4135 }
4136
4137 qreal QQuickItem::opacity() const
4138 {
4139     Q_D(const QQuickItem);
4140     return d->opacity();
4141 }
4142
4143 void QQuickItem::setOpacity(qreal o)
4144 {
4145     Q_D(QQuickItem);
4146     if (d->opacity() == o)
4147         return;
4148
4149     d->extra.value().opacity = o;
4150
4151     d->dirty(QQuickItemPrivate::OpacityValue);
4152
4153     d->itemChange(ItemOpacityHasChanged, o);
4154
4155     emit opacityChanged();
4156 }
4157
4158 bool QQuickItem::isVisible() const
4159 {
4160     Q_D(const QQuickItem);
4161     return d->effectiveVisible;
4162 }
4163
4164 void QQuickItem::setVisible(bool v)
4165 {
4166     Q_D(QQuickItem);
4167     if (v == d->explicitVisible)
4168         return;
4169
4170     d->explicitVisible = v;
4171     if (!v)
4172         d->dirty(QQuickItemPrivate::Visible);
4173
4174     const bool childVisibilityChanged = d->setEffectiveVisibleRecur(d->calcEffectiveVisible());
4175     if (childVisibilityChanged && d->parentItem)
4176         emit d->parentItem->visibleChildrenChanged();   // signal the parent, not this!
4177 }
4178
4179 bool QQuickItem::isEnabled() const
4180 {
4181     Q_D(const QQuickItem);
4182     return d->effectiveEnable;
4183 }
4184
4185 void QQuickItem::setEnabled(bool e)
4186 {
4187     Q_D(QQuickItem);
4188     if (e == d->explicitEnable)
4189         return;
4190
4191     d->explicitEnable = e;
4192
4193     QQuickItem *scope = parentItem();
4194     while (scope && !scope->isFocusScope())
4195         scope = scope->parentItem();
4196
4197     d->setEffectiveEnableRecur(scope, d->calcEffectiveEnable());
4198 }
4199
4200 bool QQuickItemPrivate::calcEffectiveVisible() const
4201 {
4202     // XXX todo - Should the effective visible of an element with no parent just be the current
4203     // effective visible?  This would prevent pointless re-processing in the case of an element
4204     // moving to/from a no-parent situation, but it is different from what graphics view does.
4205     return explicitVisible && (!parentItem || QQuickItemPrivate::get(parentItem)->effectiveVisible);
4206 }
4207
4208 bool QQuickItemPrivate::setEffectiveVisibleRecur(bool newEffectiveVisible)
4209 {
4210     Q_Q(QQuickItem);
4211
4212     if (newEffectiveVisible && !explicitVisible) {
4213         // This item locally overrides visibility
4214         return false;   // effective visibility didn't change
4215     }
4216
4217     if (newEffectiveVisible == effectiveVisible) {
4218         // No change necessary
4219         return false;   // effective visibility didn't change
4220     }
4221
4222     effectiveVisible = newEffectiveVisible;
4223     dirty(Visible);
4224     if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
4225
4226     if (canvas) {
4227         QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(canvas);
4228         if (canvasPriv->mouseGrabberItem == q)
4229             q->ungrabMouse();
4230     }
4231
4232     bool childVisibilityChanged = false;
4233     for (int ii = 0; ii < childItems.count(); ++ii)
4234         childVisibilityChanged |= QQuickItemPrivate::get(childItems.at(ii))->setEffectiveVisibleRecur(newEffectiveVisible);
4235
4236     itemChange(QQuickItem::ItemVisibleHasChanged, effectiveVisible);
4237 #ifndef QT_NO_ACCESSIBILITY
4238     if (isAccessible) {
4239         QAccessibleEvent ev(q, effectiveVisible ? QAccessible::ObjectShow : QAccessible::ObjectHide);
4240         QAccessible::updateAccessibility(&ev);
4241     }
4242 #endif
4243     emit q->visibleChanged();
4244     if (childVisibilityChanged)
4245         emit q->visibleChildrenChanged();
4246
4247     return true;    // effective visibility DID change
4248 }
4249
4250 bool QQuickItemPrivate::calcEffectiveEnable() const
4251 {
4252     // XXX todo - Should the effective enable of an element with no parent just be the current
4253     // effective enable?  This would prevent pointless re-processing in the case of an element
4254     // moving to/from a no-parent situation, but it is different from what graphics view does.
4255     return explicitEnable && (!parentItem || QQuickItemPrivate::get(parentItem)->effectiveEnable);
4256 }
4257
4258 void QQuickItemPrivate::setEffectiveEnableRecur(QQuickItem *scope, bool newEffectiveEnable)
4259 {
4260     Q_Q(QQuickItem);
4261
4262     if (newEffectiveEnable && !explicitEnable) {
4263         // This item locally overrides enable
4264         return;
4265     }
4266
4267     if (newEffectiveEnable == effectiveEnable) {
4268         // No change necessary
4269         return;
4270     }
4271
4272     effectiveEnable = newEffectiveEnable;
4273
4274     if (canvas) {
4275         QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(canvas);
4276         if (canvasPriv->mouseGrabberItem == q)
4277             q->ungrabMouse();
4278         if (scope && !effectiveEnable && activeFocus) {
4279             canvasPriv->clearFocusInScope(
4280                     scope, q,  QQuickCanvasPrivate::DontChangeFocusProperty | QQuickCanvasPrivate::DontChangeSubFocusItem);
4281         }
4282     }
4283
4284     for (int ii = 0; ii < childItems.count(); ++ii) {
4285         QQuickItemPrivate::get(childItems.at(ii))->setEffectiveEnableRecur(
4286                 (flags & QQuickItem::ItemIsFocusScope) && scope ? q : scope, newEffectiveEnable);
4287     }
4288
4289     if (canvas && scope && effectiveEnable && focus) {
4290         QQuickCanvasPrivate::get(canvas)->setFocusInScope(
4291                 scope, q, QQuickCanvasPrivate::DontChangeFocusProperty | QQuickCanvasPrivate::DontChangeSubFocusItem);
4292     }
4293
4294     emit q->enabledChanged();
4295 }
4296
4297 QString QQuickItemPrivate::dirtyToString() const
4298 {
4299 #define DIRTY_TO_STRING(value) if (dirtyAttributes & value) { \
4300     if (!rv.isEmpty()) \
4301         rv.append(QLatin1String("|")); \
4302     rv.append(QLatin1String(#value)); \
4303 }
4304
4305 //    QString rv = QLatin1String("0x") + QString::number(dirtyAttributes, 16);
4306     QString rv;
4307
4308     DIRTY_TO_STRING(TransformOrigin);
4309     DIRTY_TO_STRING(Transform);
4310     DIRTY_TO_STRING(BasicTransform);
4311     DIRTY_TO_STRING(Position);
4312     DIRTY_TO_STRING(Size);
4313     DIRTY_TO_STRING(ZValue);
4314     DIRTY_TO_STRING(Content);
4315     DIRTY_TO_STRING(Smooth);
4316     DIRTY_TO_STRING(OpacityValue);
4317     DIRTY_TO_STRING(ChildrenChanged);
4318     DIRTY_TO_STRING(ChildrenStackingChanged);
4319     DIRTY_TO_STRING(ParentChanged);
4320     DIRTY_TO_STRING(Clip);
4321     DIRTY_TO_STRING(Canvas);
4322     DIRTY_TO_STRING(EffectReference);
4323     DIRTY_TO_STRING(Visible);
4324     DIRTY_TO_STRING(HideReference);
4325     DIRTY_TO_STRING(PerformanceHints);
4326
4327     return rv;
4328 }
4329
4330 void QQuickItemPrivate::dirty(DirtyType type)
4331 {
4332     Q_Q(QQuickItem);
4333     if (type & (TransformOrigin | Transform | BasicTransform | Position | Size))
4334         transformChanged();
4335
4336     if (!(dirtyAttributes & type) || (canvas && !prevDirtyItem)) {
4337         dirtyAttributes |= type;
4338         if (canvas) {
4339             addToDirtyList();
4340             QQuickCanvasPrivate::get(canvas)->dirtyItem(q);
4341         }
4342     }
4343 }
4344
4345 void QQuickItemPrivate::addToDirtyList()
4346 {
4347     Q_Q(QQuickItem);
4348
4349     Q_ASSERT(canvas);
4350     if (!prevDirtyItem) {
4351         Q_ASSERT(!nextDirtyItem);
4352
4353         QQuickCanvasPrivate *p = QQuickCanvasPrivate::get(canvas);
4354         nextDirtyItem = p->dirtyItemList;
4355         if (nextDirtyItem) QQuickItemPrivate::get(nextDirtyItem)->prevDirtyItem = &nextDirtyItem;
4356         prevDirtyItem = &p->dirtyItemList;
4357         p->dirtyItemList = q;
4358         p->dirtyItem(q);
4359     }
4360     Q_ASSERT(prevDirtyItem);
4361 }
4362
4363 void QQuickItemPrivate::removeFromDirtyList()
4364 {
4365     if (prevDirtyItem) {
4366         if (nextDirtyItem) QQuickItemPrivate::get(nextDirtyItem)->prevDirtyItem = prevDirtyItem;
4367         *prevDirtyItem = nextDirtyItem;
4368         prevDirtyItem = 0;
4369         nextDirtyItem = 0;
4370     }
4371     Q_ASSERT(!prevDirtyItem);
4372     Q_ASSERT(!nextDirtyItem);
4373 }
4374
4375 void QQuickItemPrivate::refFromEffectItem(bool hide)
4376 {
4377     ++extra.value().effectRefCount;
4378     if (1 == extra->effectRefCount) {
4379         dirty(EffectReference);
4380         if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
4381     }
4382     if (hide) {
4383         if (++extra->hideRefCount == 1)
4384             dirty(HideReference);
4385     }
4386 }
4387
4388 void QQuickItemPrivate::derefFromEffectItem(bool unhide)
4389 {
4390     Q_ASSERT(extra->effectRefCount);
4391     --extra->effectRefCount;
4392     if (0 == extra->effectRefCount) {
4393         dirty(EffectReference);
4394         if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
4395     }
4396     if (unhide) {
4397         if (--extra->hideRefCount == 0)
4398             dirty(HideReference);
4399     }
4400 }
4401
4402 void QQuickItemPrivate::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data)
4403 {
4404     Q_Q(QQuickItem);
4405     switch (change) {
4406     case QQuickItem::ItemChildAddedChange:
4407         q->itemChange(change, data);
4408         for (int ii = 0; ii < changeListeners.count(); ++ii) {
4409             const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4410             if (change.types & QQuickItemPrivate::Children) {
4411                 change.listener->itemChildAdded(q, data.item);
4412             }
4413         }
4414         break;
4415     case QQuickItem::ItemChildRemovedChange:
4416         q->itemChange(change, data);
4417         for (int ii = 0; ii < changeListeners.count(); ++ii) {
4418             const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4419             if (change.types & QQuickItemPrivate::Children) {
4420                 change.listener->itemChildRemoved(q, data.item);
4421             }
4422         }
4423         break;
4424     case QQuickItem::ItemSceneChange:
4425         q->itemChange(change, data);
4426         break;
4427     case QQuickItem::ItemVisibleHasChanged:
4428         q->itemChange(change, data);
4429         for (int ii = 0; ii < changeListeners.count(); ++ii) {
4430             const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4431             if (change.types & QQuickItemPrivate::Visibility) {
4432                 change.listener->itemVisibilityChanged(q);
4433             }
4434         }
4435         break;
4436     case QQuickItem::ItemParentHasChanged:
4437         q->itemChange(change, data);
4438         for (int ii = 0; ii < changeListeners.count(); ++ii) {
4439             const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4440             if (change.types & QQuickItemPrivate::Parent) {
4441                 change.listener->itemParentChanged(q, data.item);
4442             }
4443         }
4444         break;
4445     case QQuickItem::ItemOpacityHasChanged:
4446         q->itemChange(change, data);
4447         for (int ii = 0; ii < changeListeners.count(); ++ii) {
4448             const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4449             if (change.types & QQuickItemPrivate::Opacity) {
4450                 change.listener->itemOpacityChanged(q);
4451             }
4452         }
4453         break;
4454     case QQuickItem::ItemActiveFocusHasChanged:
4455         q->itemChange(change, data);
4456         break;
4457     case QQuickItem::ItemRotationHasChanged:
4458         q->itemChange(change, data);
4459         for (int ii = 0; ii < changeListeners.count(); ++ii) {
4460             const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4461             if (change.types & QQuickItemPrivate::Rotation) {
4462                 change.listener->itemRotationChanged(q);
4463             }
4464         }
4465         break;
4466     }
4467 }
4468
4469 /*!
4470     \property QQuickItem::smooth
4471     \brief Specifies whether the item is smoothed or not
4472
4473     Primarily used in image based elements to decide if the item should use smooth
4474     sampling or not. Smooth sampling is performed using linear interpolation, while
4475     non-smooth is performed using nearest neighbor.
4476
4477     In Qt Quick 2.0, this property has minimal impact on performance.
4478
4479     By default is true.
4480 */
4481
4482 /*!
4483     Returns true if the item should be drawn with antialiasing and
4484     smooth pixmap filtering, false otherwise.
4485
4486     The default is false.
4487
4488     \sa setSmooth()
4489 */
4490 bool QQuickItem::smooth() const
4491 {
4492     Q_D(const QQuickItem);
4493     return d->smooth;
4494 }
4495
4496 /*!
4497     Sets whether the item should be drawn with antialiasing and
4498     smooth pixmap filtering to \a smooth.
4499
4500     \sa smooth()
4501 */
4502 void QQuickItem::setSmooth(bool smooth)
4503 {
4504     Q_D(QQuickItem);
4505     if (d->smooth == smooth)
4506         return;
4507
4508     d->smooth = smooth;
4509     d->dirty(QQuickItemPrivate::Smooth);
4510
4511     emit smoothChanged(smooth);
4512 }
4513
4514 QQuickItem::Flags QQuickItem::flags() const
4515 {
4516     Q_D(const QQuickItem);
4517     return (QQuickItem::Flags)d->flags;
4518 }
4519
4520 void QQuickItem::setFlag(Flag flag, bool enabled)
4521 {
4522     Q_D(QQuickItem);
4523     if (enabled)
4524         setFlags((Flags)(d->flags | (quint32)flag));
4525     else
4526         setFlags((Flags)(d->flags & ~(quint32)flag));
4527 }
4528
4529 void QQuickItem::setFlags(Flags flags)
4530 {
4531     Q_D(QQuickItem);
4532
4533     if ((flags & ItemIsFocusScope) != (d->flags & ItemIsFocusScope)) {
4534         if (flags & ItemIsFocusScope && !d->childItems.isEmpty() && d->canvas) {
4535             qWarning("QQuickItem: Cannot set FocusScope once item has children and is in a canvas.");
4536             flags &= ~ItemIsFocusScope;
4537         } else if (d->flags & ItemIsFocusScope) {
4538             qWarning("QQuickItem: Cannot unset FocusScope flag.");
4539             flags |= ItemIsFocusScope;
4540         }
4541     }
4542
4543     if ((flags & ItemClipsChildrenToShape ) != (d->flags & ItemClipsChildrenToShape))
4544         d->dirty(QQuickItemPrivate::Clip);
4545
4546     d->flags = flags;
4547 }
4548
4549 qreal QQuickItem::x() const
4550 {
4551     Q_D(const QQuickItem);
4552     return d->x;
4553 }
4554
4555 qreal QQuickItem::y() const
4556 {
4557     Q_D(const QQuickItem);
4558     return d->y;
4559 }
4560
4561 QPointF QQuickItem::pos() const
4562 {
4563     Q_D(const QQuickItem);
4564     return QPointF(d->x, d->y);
4565 }
4566
4567 void QQuickItem::setX(qreal v)
4568 {
4569     Q_D(QQuickItem);
4570     if (d->x == v)
4571         return;
4572
4573     qreal oldx = d->x;
4574     d->x = v;
4575
4576     d->dirty(QQuickItemPrivate::Position);
4577
4578     geometryChanged(QRectF(x(), y(), width(), height()),
4579                     QRectF(oldx, y(), width(), height()));
4580 }
4581
4582 void QQuickItem::setY(qreal v)
4583 {
4584     Q_D(QQuickItem);
4585     if (d->y == v)
4586         return;
4587
4588     qreal oldy = d->y;
4589     d->y = v;
4590
4591     d->dirty(QQuickItemPrivate::Position);
4592
4593     geometryChanged(QRectF(x(), y(), width(), height()),
4594                     QRectF(x(), oldy, width(), height()));
4595 }
4596
4597 void QQuickItem::setPos(const QPointF &pos)
4598 {
4599     Q_D(QQuickItem);
4600     if (QPointF(d->x, d->y) == pos)
4601         return;
4602
4603     qreal oldx = d->x;
4604     qreal oldy = d->y;
4605
4606     d->x = pos.x();
4607     d->y = pos.y();
4608
4609     d->dirty(QQuickItemPrivate::Position);
4610
4611     geometryChanged(QRectF(x(), y(), width(), height()),
4612                     QRectF(oldx, oldy, width(), height()));
4613 }
4614
4615 qreal QQuickItem::width() const
4616 {
4617     Q_D(const QQuickItem);
4618     return d->width;
4619 }
4620
4621 void QQuickItem::setWidth(qreal w)
4622 {
4623     Q_D(QQuickItem);
4624     if (qIsNaN(w))
4625         return;
4626
4627     d->widthValid = true;
4628     if (d->width == w)
4629         return;
4630
4631     qreal oldWidth = d->width;
4632     d->width = w;
4633
4634     d->dirty(QQuickItemPrivate::Size);
4635
4636     geometryChanged(QRectF(x(), y(), width(), height()),
4637                     QRectF(x(), y(), oldWidth, height()));
4638 }
4639
4640 void QQuickItem::resetWidth()
4641 {
4642     Q_D(QQuickItem);
4643     d->widthValid = false;
4644     setImplicitWidth(implicitWidth());
4645 }
4646
4647 void QQuickItemPrivate::implicitWidthChanged()
4648 {
4649     Q_Q(QQuickItem);
4650     for (int ii = 0; ii < changeListeners.count(); ++ii) {
4651         const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4652         if (change.types & QQuickItemPrivate::ImplicitWidth) {
4653             change.listener->itemImplicitWidthChanged(q);
4654         }
4655     }
4656     emit q->implicitWidthChanged();
4657 }
4658
4659 qreal QQuickItemPrivate::getImplicitWidth() const
4660 {
4661     return implicitWidth;
4662 }
4663 /*!
4664     Returns the width of the item that is implied by other properties that determine the content.
4665 */
4666 qreal QQuickItem::implicitWidth() const
4667 {
4668     Q_D(const QQuickItem);
4669     return d->getImplicitWidth();
4670 }
4671
4672 /*!
4673     \qmlproperty real QtQuick2::Item::implicitWidth
4674     \qmlproperty real QtQuick2::Item::implicitHeight
4675
4676     Defines the natural width or height of the Item if no \l width or \l height is specified.
4677
4678     The default implicit size for most items is 0x0, however some elements have an inherent
4679     implicit size which cannot be overridden, e.g. Image, Text.
4680
4681     Setting the implicit size is useful for defining components that have a preferred size
4682     based on their content, for example:
4683
4684     \qml
4685     // Label.qml
4686     import QtQuick 2.0
4687
4688     Item {
4689         property alias icon: image.source
4690         property alias label: text.text
4691         implicitWidth: text.implicitWidth + image.implicitWidth
4692         implicitHeight: Math.max(text.implicitHeight, image.implicitHeight)
4693         Image { id: image }
4694         Text {
4695             id: text
4696             wrapMode: Text.Wrap
4697             anchors.left: image.right; anchors.right: parent.right
4698             anchors.verticalCenter: parent.verticalCenter
4699         }
4700     }
4701     \endqml
4702
4703     \b Note: using implicitWidth of Text or TextEdit and setting the width explicitly
4704     incurs a performance penalty as the text must be laid out twice.
4705 */
4706
4707 /*!
4708     Sets the implied width of the item to \a w.
4709     This is the width implied by other properties that determine the content.
4710 */
4711 void QQuickItem::setImplicitWidth(qreal w)
4712 {
4713     Q_D(QQuickItem);
4714     bool changed = w != d->implicitWidth;
4715     d->implicitWidth = w;
4716     if (d->width == w || widthValid()) {
4717         if (changed)
4718             d->implicitWidthChanged();
4719         if (d->width == w || widthValid())
4720             return;
4721         changed = false;
4722     }
4723
4724     qreal oldWidth = d->width;
4725     d->width = w;
4726
4727     d->dirty(QQuickItemPrivate::Size);
4728
4729     geometryChanged(QRectF(x(), y(), width(), height()),
4730                     QRectF(x(), y(), oldWidth, height()));
4731
4732     if (changed)
4733         d->implicitWidthChanged();
4734 }
4735
4736 /*!
4737     Returns whether the width property has been set explicitly.
4738 */
4739 bool QQuickItem::widthValid() const
4740 {
4741     Q_D(const QQuickItem);
4742     return d->widthValid;
4743 }
4744
4745 qreal QQuickItem::height() const
4746 {
4747     Q_D(const QQuickItem);
4748     return d->height;
4749 }
4750
4751 void QQuickItem::setHeight(qreal h)
4752 {
4753     Q_D(QQuickItem);
4754     if (qIsNaN(h))
4755         return;
4756
4757     d->heightValid = true;
4758     if (d->height == h)
4759         return;
4760
4761     qreal oldHeight = d->height;
4762     d->height = h;
4763
4764     d->dirty(QQuickItemPrivate::Size);
4765
4766     geometryChanged(QRectF(x(), y(), width(), height()),
4767                     QRectF(x(), y(), width(), oldHeight));
4768 }
4769
4770 void QQuickItem::resetHeight()
4771 {
4772     Q_D(QQuickItem);
4773     d->heightValid = false;
4774     setImplicitHeight(implicitHeight());
4775 }
4776
4777 void QQuickItemPrivate::implicitHeightChanged()
4778 {
4779     Q_Q(QQuickItem);
4780     for (int ii = 0; ii < changeListeners.count(); ++ii) {
4781         const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4782         if (change.types & QQuickItemPrivate::ImplicitHeight) {
4783             change.listener->itemImplicitHeightChanged(q);
4784         }
4785     }
4786     emit q->implicitHeightChanged();
4787 }
4788
4789 qreal QQuickItemPrivate::getImplicitHeight() const
4790 {
4791     return implicitHeight;
4792 }
4793
4794 /*!
4795     Returns the height of the item that is implied by other properties that determine the content.
4796 */
4797 qreal QQuickItem::implicitHeight() const
4798 {
4799     Q_D(const QQuickItem);
4800     return d->getImplicitHeight();
4801 }
4802
4803
4804 /*!
4805     Sets the implied height of the item to \a h.
4806     This is the height implied by other properties that determine the content.
4807 */
4808 void QQuickItem::setImplicitHeight(qreal h)
4809 {
4810     Q_D(QQuickItem);
4811     bool changed = h != d->implicitHeight;
4812     d->implicitHeight = h;
4813     if (d->height == h || heightValid()) {
4814         if (changed)
4815             d->implicitHeightChanged();
4816         if (d->height == h || heightValid())
4817             return;
4818         changed = false;
4819     }
4820
4821     qreal oldHeight = d->height;
4822     d->height = h;
4823
4824     d->dirty(QQuickItemPrivate::Size);
4825
4826     geometryChanged(QRectF(x(), y(), width(), height()),
4827                     QRectF(x(), y(), width(), oldHeight));
4828
4829     if (changed)
4830         d->implicitHeightChanged();
4831 }
4832
4833 void QQuickItem::setImplicitSize(qreal w, qreal h)
4834 {
4835     Q_D(QQuickItem);
4836     bool wChanged = w != d->implicitWidth;
4837     bool hChanged = h != d->implicitHeight;
4838
4839     d->implicitWidth = w;
4840     d->implicitHeight = h;
4841
4842     bool wDone = false;
4843     bool hDone = false;
4844     if (d->width == w || widthValid()) {
4845         if (wChanged)
4846             d->implicitWidthChanged();
4847         wDone = d->width == w || widthValid();
4848         wChanged = false;
4849     }
4850     if (d->height == h || heightValid()) {
4851         if (hChanged)
4852             d->implicitHeightChanged();
4853         hDone = d->height == h || heightValid();
4854         hChanged = false;
4855     }
4856     if (wDone && hDone)
4857         return;
4858
4859     qreal oldWidth = d->width;
4860     qreal oldHeight = d->height;
4861     if (!wDone)
4862         d->width = w;
4863     if (!hDone)
4864         d->height = h;
4865
4866     d->dirty(QQuickItemPrivate::Size);
4867
4868     geometryChanged(QRectF(x(), y(), width(), height()),
4869                     QRectF(x(), y(), oldWidth, oldHeight));
4870
4871     if (!wDone && wChanged)
4872         d->implicitWidthChanged();
4873     if (!hDone && hChanged)
4874         d->implicitHeightChanged();
4875 }
4876
4877 /*!
4878     Returns whether the height property has been set explicitly.
4879 */
4880 bool QQuickItem::heightValid() const
4881 {
4882     Q_D(const QQuickItem);
4883     return d->heightValid;
4884 }
4885
4886 void QQuickItem::setSize(const QSizeF &size)
4887 {
4888     Q_D(QQuickItem);
4889     d->heightValid = true;
4890     d->widthValid = true;
4891
4892     if (QSizeF(d->width, d->height) == size)
4893         return;
4894
4895     qreal oldHeight = d->height;
4896     qreal oldWidth = d->width;
4897     d->height = size.height();
4898     d->width = size.width();
4899
4900     d->dirty(QQuickItemPrivate::Size);
4901
4902     geometryChanged(QRectF(x(), y(), width(), height()),
4903                     QRectF(x(), y(), oldWidth, oldHeight));
4904 }
4905
4906 bool QQuickItem::hasActiveFocus() const
4907 {
4908     Q_D(const QQuickItem);
4909     return d->activeFocus;
4910 }
4911
4912 bool QQuickItem::hasFocus() const
4913 {
4914     Q_D(const QQuickItem);
4915     return d->focus;
4916 }
4917
4918 void QQuickItem::setFocus(bool focus)
4919 {
4920     Q_D(QQuickItem);
4921     if (d->focus == focus)
4922         return;
4923
4924     if (d->canvas || d->parentItem) {
4925         // Need to find our nearest focus scope
4926         QQuickItem *scope = parentItem();
4927         while (scope && !scope->isFocusScope() && scope->parentItem())
4928             scope = scope->parentItem();
4929         if (d->canvas) {
4930             if (focus)
4931                 QQuickCanvasPrivate::get(d->canvas)->setFocusInScope(scope, this);
4932             else
4933                 QQuickCanvasPrivate::get(d->canvas)->clearFocusInScope(scope, this);
4934         } else {
4935             // do the focus changes from setFocusInScope/clearFocusInScope that are
4936             // unrelated to a canvas
4937             QVarLengthArray<QQuickItem *, 20> changed;
4938             QQuickItem *oldSubFocusItem = QQuickItemPrivate::get(scope)->subFocusItem;
4939             if (oldSubFocusItem) {
4940                 QQuickItemPrivate::get(oldSubFocusItem)->updateSubFocusItem(scope, false);
4941                 QQuickItemPrivate::get(oldSubFocusItem)->focus = false;
4942                 changed << oldSubFocusItem;
4943             }
4944             d->updateSubFocusItem(scope, focus);
4945
4946             d->focus = focus;
4947             changed << this;
4948             emit focusChanged(focus);
4949
4950             QQuickCanvasPrivate::notifyFocusChangesRecur(changed.data(), changed.count() - 1);
4951         }
4952     } else {
4953         d->focus = focus;
4954         emit focusChanged(focus);
4955     }
4956 }
4957
4958 bool QQuickItem::isFocusScope() const
4959 {
4960     return flags() & ItemIsFocusScope;
4961 }
4962
4963 QQuickItem *QQuickItem::scopedFocusItem() const
4964 {
4965     Q_D(const QQuickItem);
4966     if (!isFocusScope())
4967         return 0;
4968     else
4969         return d->subFocusItem;
4970 }
4971
4972
4973 Qt::MouseButtons QQuickItem::acceptedMouseButtons() const
4974 {
4975     Q_D(const QQuickItem);
4976     return d->acceptedMouseButtons();
4977 }
4978
4979 void QQuickItem::setAcceptedMouseButtons(Qt::MouseButtons buttons)
4980 {
4981     Q_D(QQuickItem);
4982     if (buttons & Qt::LeftButton)
4983         d->extra.setFlag();
4984     else
4985         d->extra.clearFlag();
4986
4987     buttons &= ~Qt::LeftButton;
4988     if (buttons || d->extra.isAllocated())
4989         d->extra.value().acceptedMouseButtons = buttons;
4990 }
4991
4992 bool QQuickItem::filtersChildMouseEvents() const
4993 {
4994     Q_D(const QQuickItem);
4995     return d->filtersChildMouseEvents;
4996 }
4997
4998 void QQuickItem::setFiltersChildMouseEvents(bool filter)
4999 {
5000     Q_D(QQuickItem);
5001     d->filtersChildMouseEvents = filter;
5002 }
5003
5004 bool QQuickItem::isUnderMouse() const
5005 {
5006     Q_D(const QQuickItem);
5007     if (!d->canvas)
5008         return false;
5009
5010     QPointF cursorPos = QGuiApplicationPrivate::lastCursorPosition;
5011     return contains(mapFromScene(cursorPos)); // ### refactor: d->canvas->mapFromGlobal(cursorPos))))
5012 }
5013
5014 bool QQuickItem::acceptHoverEvents() const
5015 {
5016     Q_D(const QQuickItem);
5017     return d->hoverEnabled;
5018 }
5019
5020 void QQuickItem::setAcceptHoverEvents(bool enabled)
5021 {
5022     Q_D(QQuickItem);
5023     d->hoverEnabled = enabled;
5024 }
5025
5026 void QQuickItem::grabMouse()
5027 {
5028     Q_D(QQuickItem);
5029     if (!d->canvas)
5030         return;
5031     QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
5032     if (canvasPriv->mouseGrabberItem == this)
5033         return;
5034
5035     QQuickItem *oldGrabber = canvasPriv->mouseGrabberItem;
5036     canvasPriv->mouseGrabberItem = this;
5037     if (oldGrabber) {
5038         QEvent ev(QEvent::UngrabMouse);
5039         d->canvas->sendEvent(oldGrabber, &ev);
5040     }
5041 }
5042
5043 void QQuickItem::ungrabMouse()
5044 {
5045     Q_D(QQuickItem);
5046     if (!d->canvas)
5047         return;
5048     QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
5049     if (canvasPriv->mouseGrabberItem != this) {
5050         qWarning("QQuickItem::ungrabMouse(): Item is not the mouse grabber.");
5051         return;
5052     }
5053
5054     canvasPriv->mouseGrabberItem = 0;
5055
5056     QEvent ev(QEvent::UngrabMouse);
5057     d->canvas->sendEvent(this, &ev);
5058 }
5059
5060 bool QQuickItem::keepMouseGrab() const
5061 {
5062     Q_D(const QQuickItem);
5063     return d->keepMouse;
5064 }
5065
5066 /*!
5067   The flag indicating whether the mouse should remain
5068   with this item is set to \a keep.
5069
5070   This is useful for items that wish to grab and keep mouse
5071   interaction following a predefined gesture.  For example,
5072   an item that is interested in horizontal mouse movement
5073   may set keepMouseGrab to true once a threshold has been
5074   exceeded.  Once keepMouseGrab has been set to true, filtering
5075   items will not react to mouse events.
5076
5077   If the item does not indicate that it wishes to retain mouse grab,
5078   a filtering item may steal the grab. For example, Flickable may attempt
5079   to steal a mouse grab if it detects that the user has begun to
5080   move the viewport.
5081
5082   \sa keepMouseGrab()
5083  */
5084 void QQuickItem::setKeepMouseGrab(bool keep)
5085 {
5086     Q_D(QQuickItem);
5087     d->keepMouse = keep;
5088 }
5089
5090 /*!
5091     Grabs the touch points specified by \a ids.
5092
5093     These touch points will be owned by the item until
5094     they are released. Alternatively, the grab can be stolen
5095     by a filtering item like Flickable. Use setKeepTouchGrab()
5096     to prevent the grab from being stolen.
5097
5098     \sa ungrabTouchPoints(), setKeepTouchGrab()
5099 */
5100 void QQuickItem::grabTouchPoints(const QList<int> &ids)
5101 {
5102     Q_D(QQuickItem);
5103     if (!d->canvas)
5104         return;
5105     QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
5106
5107     QSet<QQuickItem*> ungrab;
5108     for (int i = 0; i < ids.count(); ++i) {
5109         QQuickItem *oldGrabber = canvasPriv->itemForTouchPointId.value(ids.at(i));
5110         if (oldGrabber == this)
5111             return;
5112
5113         canvasPriv->itemForTouchPointId[ids.at(i)] = this;
5114         if (oldGrabber)
5115             ungrab.insert(oldGrabber);
5116     }
5117     foreach (QQuickItem *oldGrabber, ungrab)
5118         oldGrabber->touchUngrabEvent();
5119 }
5120
5121 /*!
5122     Ungrabs the touch points owned by this item.
5123
5124     \sa grabTouchPoints()
5125 */
5126 void QQuickItem::ungrabTouchPoints()
5127 {
5128     Q_D(QQuickItem);
5129     if (!d->canvas)
5130         return;
5131     QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
5132
5133     QMutableHashIterator<int, QQuickItem*> i(canvasPriv->itemForTouchPointId);
5134     while (i.hasNext()) {
5135         i.next();
5136         if (i.value() == this)
5137             i.remove();
5138     }
5139     touchUngrabEvent();
5140 }
5141
5142 /*!
5143     Returns a value indicating whether the touch points grabbed by this item
5144     should remain with this item exclusively.
5145
5146     \sa setKeepTouchGrab(), keepMouseGrab()
5147 */
5148 bool QQuickItem::keepTouchGrab() const
5149 {
5150     Q_D(const QQuickItem);
5151     return d->keepTouch;
5152 }
5153
5154 /*!
5155   The flag indicating whether the touch points grabbed
5156   by this item should remain with this item is set to \a keep.
5157
5158   This is useful for items that wish to grab and keep specific touch
5159   points following a predefined gesture.  For example,
5160   an item that is interested in horizontal touch point movement
5161   may set setKeepTouchGrab to true once a threshold has been
5162   exceeded.  Once setKeepTouchGrab has been set to true, filtering
5163   items will not react to the relevant touch points.
5164
5165   If the item does not indicate that it wishes to retain touch point grab,
5166   a filtering item may steal the grab. For example, Flickable may attempt
5167   to steal a touch point grab if it detects that the user has begun to
5168   move the viewport.
5169
5170   \sa keepTouchGrab(), setKeepMouseGrab()
5171  */
5172 void QQuickItem::setKeepTouchGrab(bool keep)
5173 {
5174     Q_D(QQuickItem);
5175     d->keepTouch = keep;
5176 }
5177
5178 /*!
5179   Returns true if this item contains \a point, which is in local coordinates;
5180   returns false otherwise.
5181
5182   This function can be overwritten in order to handle point collisions in items
5183   with custom shapes. The default implementation checks if the point is inside
5184   the item's bounding rect.
5185
5186   Note that it's normally used to check if the item is under the mouse cursor,
5187   and for that reason, the implementation of this function should be as light-weight
5188   as possible.
5189 */
5190 bool QQuickItem::contains(const QPointF &point) const
5191 {
5192     Q_D(const QQuickItem);
5193     return QRectF(0, 0, d->width, d->height).contains(point);
5194 }
5195
5196 QPointF QQuickItem::mapToItem(const QQuickItem *item, const QPointF &point) const
5197 {
5198     QPointF p = mapToScene(point);
5199     if (item)
5200         p = item->mapFromScene(p);
5201     return p;
5202 }
5203
5204 QPointF QQuickItem::mapToScene(const QPointF &point) const
5205 {
5206     Q_D(const QQuickItem);
5207     return d->itemToCanvasTransform().map(point);
5208 }
5209
5210 QRectF QQuickItem::mapRectToItem(const QQuickItem *item, const QRectF &rect) const
5211 {
5212     Q_D(const QQuickItem);
5213     QTransform t = d->itemToCanvasTransform();
5214     if (item)
5215         t *= QQuickItemPrivate::get(item)->canvasToItemTransform();
5216     return t.mapRect(rect);
5217 }
5218
5219 QRectF QQuickItem::mapRectToScene(const QRectF &rect) const
5220 {
5221     Q_D(const QQuickItem);
5222     return d->itemToCanvasTransform().mapRect(rect);
5223 }
5224
5225 QPointF QQuickItem::mapFromItem(const QQuickItem *item, const QPointF &point) const
5226 {
5227     QPointF p = item?item->mapToScene(point):point;
5228     return mapFromScene(p);
5229 }
5230
5231 QPointF QQuickItem::mapFromScene(const QPointF &point) const
5232 {
5233     Q_D(const QQuickItem);
5234     return d->canvasToItemTransform().map(point);
5235 }
5236
5237 QRectF QQuickItem::mapRectFromItem(const QQuickItem *item, const QRectF &rect) const
5238 {
5239     Q_D(const QQuickItem);
5240     QTransform t = item?QQuickItemPrivate::get(item)->itemToCanvasTransform():QTransform();
5241     t *= d->canvasToItemTransform();
5242     return t.mapRect(rect);
5243 }
5244
5245 QRectF QQuickItem::mapRectFromScene(const QRectF &rect) const
5246 {
5247     Q_D(const QQuickItem);
5248     return d->canvasToItemTransform().mapRect(rect);
5249 }
5250
5251
5252 /*!
5253     \qmlmethod QtQuick2::Item::forceActiveFocus()
5254
5255     Forces active focus on the item.
5256
5257     This method sets focus on the item and makes sure that all the focus scopes
5258     higher in the object hierarchy are also given the focus.
5259 */
5260
5261 /*!
5262     Forces active focus on the item.
5263
5264     This method sets focus on the item and makes sure that all the focus scopes
5265     higher in the object hierarchy are also given the focus.
5266 */
5267
5268 /*!
5269   \qmlmethod QtQuick2::Item::childAt(real x, real y)
5270
5271   Returns the visible child item at point (\a x, \a y), which is in this
5272   item's coordinate system, or \c null if there is no such item.
5273 */
5274
5275 /*!
5276   Returns the visible child item at point (\a x, \a y), which is in this
5277   item's coordinate system, or 0 if there is no such item.
5278 */
5279
5280 /*!
5281   \qmlproperty list<State> QtQuick2::Item::states
5282   This property holds a list of states defined by the item.
5283
5284   \qml
5285   Item {
5286       states: [
5287           State {
5288               // ...
5289           },
5290           State {
5291               // ...
5292           }
5293           // ...
5294       ]
5295   }
5296   \endqml
5297
5298   \sa {qmlstate}{States}
5299 */
5300 /*!
5301   \qmlproperty list<Transition> QtQuick2::Item::transitions
5302   This property holds a list of transitions defined by the item.
5303
5304   \qml
5305   Item {
5306       transitions: [
5307           Transition {
5308               // ...
5309           },
5310           Transition {
5311               // ...
5312           }
5313           // ...
5314       ]
5315   }
5316   \endqml
5317
5318   \sa {QML Animation and Transitions}{Transitions}
5319 */
5320 /*
5321   \qmlproperty list<Filter> QtQuick2::Item::filter
5322   This property holds a list of graphical filters to be applied to the item.
5323
5324   \l {Filter}{Filters} include things like \l {Blur}{blurring}
5325   the item, or giving it a \l Reflection.  Some
5326   filters may not be available on all canvases; if a filter is not
5327   available on a certain canvas, it will simply not be applied for
5328   that canvas (but the QML will still be considered valid).
5329
5330   \qml
5331   Item {
5332       filter: [
5333           Blur {
5334               // ...
5335           },
5336           Reflection {
5337               // ...
5338           }
5339           // ...
5340       ]
5341   }
5342   \endqml
5343 */
5344
5345 /*!
5346   \qmlproperty bool QtQuick2::Item::clip
5347   This property holds whether clipping is enabled. The default clip value is \c false.
5348
5349   If clipping is enabled, an item will clip its own painting, as well
5350   as the painting of its children, to its bounding rectangle.
5351
5352   Non-rectangular clipping regions are not supported for performance reasons.
5353 */
5354
5355 /*!
5356   \property QQuickItem::clip
5357   This property holds whether clipping is enabled. The default clip value is \c false.
5358
5359   If clipping is enabled, an item will clip its own painting, as well
5360   as the painting of its children, to its bounding rectangle. If you set
5361   clipping during an item's paint operation, remember to re-set it to
5362   prevent clipping the rest of your scene.
5363
5364   Non-rectangular clipping regions are not supported for performance reasons.
5365 */
5366
5367 /*!
5368   \qmlproperty string QtQuick2::Item::state
5369
5370   This property holds the name of the current state of the item.
5371
5372   This property is often used in scripts to change between states. For
5373   example:
5374
5375   \js
5376   function toggle() {
5377       if (button.state == 'On')
5378           button.state = 'Off';
5379       else
5380           button.state = 'On';
5381   }
5382   \endjs
5383
5384   If the item is in its base state (i.e. no explicit state has been
5385   set), \c state will be a blank string. Likewise, you can return an
5386   item to its base state by setting its current state to \c ''.
5387
5388   \sa {qmlstates}{States}
5389 */
5390
5391 /*!
5392   \qmlproperty list<Transform> QtQuick2::Item::transform
5393   This property holds the list of transformations to apply.
5394
5395   For more information see \l Transform.
5396 */
5397
5398 /*!
5399     \enum QQuickItem::TransformOrigin
5400
5401     Controls the point about which simple transforms like scale apply.
5402
5403     \value TopLeft The top-left corner of the item.
5404     \value Top The center point of the top of the item.
5405     \value TopRight The top-right corner of the item.
5406     \value Left The left most point of the vertical middle.
5407     \value Center The center of the item.
5408     \value Right The right most point of the vertical middle.
5409     \value BottomLeft The bottom-left corner of the item.
5410     \value Bottom The center point of the bottom of the item.
5411     \value BottomRight The bottom-right corner of the item.
5412 */
5413
5414
5415 /*!
5416   \qmlproperty bool QtQuick2::Item::activeFocus
5417
5418   This property indicates whether the item has active focus.
5419
5420   An item with active focus will receive keyboard input,
5421   or is a FocusScope ancestor of the item that will receive keyboard input.
5422
5423   Usually, activeFocus is gained by setting focus on an item and its enclosing
5424   FocusScopes. In the following example \c input will have activeFocus.
5425   \qml
5426   Rectangle {
5427       FocusScope {
5428           focus: true
5429           TextInput {
5430               id: input
5431               focus: true
5432           }
5433       }
5434   }
5435   \endqml
5436
5437   \sa focus, {qmlfocus}{Keyboard Focus}
5438 */
5439
5440 /*!
5441   \qmlproperty bool QtQuick2::Item::focus
5442   This property indicates whether the item has focus within the enclosing focus scope. If true, this item
5443   will gain active focus when the enclosing focus scope gains active focus.
5444   In the following example, \c input will be given active focus when \c scope gains active focus.
5445   \qml
5446   Rectangle {
5447       FocusScope {
5448           id: scope
5449           TextInput {
5450               id: input
5451               focus: true
5452           }
5453       }
5454   }
5455   \endqml
5456
5457   For the purposes of this property, the scene as a whole is assumed to act like a focus scope.
5458   On a practical level, that means the following QML will give active focus to \c input on startup.
5459
5460   \qml
5461   Rectangle {
5462       TextInput {
5463           id: input
5464           focus: true
5465       }
5466   }
5467   \endqml
5468
5469   \sa activeFocus, {qmlfocus}{Keyboard Focus}
5470 */
5471
5472
5473 /*!
5474   \property QQuickItem::anchors
5475   \internal
5476 */
5477
5478 /*!
5479   \property QQuickItem::left
5480   \internal
5481 */
5482
5483 /*!
5484   \property QQuickItem::right
5485   \internal
5486 */
5487
5488 /*!
5489   \property QQuickItem::horizontalCenter
5490   \internal
5491 */
5492
5493 /*!
5494   \property QQuickItem::top
5495   \internal
5496 */
5497
5498 /*!
5499   \property QQuickItem::bottom
5500   \internal
5501 */
5502
5503 /*!
5504   \property QQuickItem::verticalCenter
5505   \internal
5506 */
5507
5508 /*!
5509   \property QQuickItem::focus
5510   \internal
5511 */
5512
5513 /*!
5514   \property QQuickItem::transform
5515   \internal
5516 */
5517
5518 /*!
5519   \property QQuickItem::transformOrigin
5520   \internal
5521 */
5522
5523 /*!
5524   \property QQuickItem::activeFocus
5525   \internal
5526 */
5527
5528 /*!
5529   \property QQuickItem::baseline
5530   \internal
5531 */
5532
5533 /*!
5534   \property QQuickItem::data
5535   \internal
5536 */
5537
5538 /*!
5539   \property QQuickItem::resources
5540   \internal
5541 */
5542
5543 /*!
5544   \property QQuickItem::state
5545   \internal
5546 */
5547
5548 /*!
5549   \property QQuickItem::states
5550   \internal
5551 */
5552
5553 /*!
5554   \property QQuickItem::transformOriginPoint
5555   \internal
5556 */
5557
5558 /*!
5559   \property QQuickItem::transitions
5560   \internal
5561 */
5562
5563 bool QQuickItem::event(QEvent *ev)
5564 {
5565 #if 0
5566     if (ev->type() == QEvent::PolishRequest) {
5567         Q_D(QQuickItem);
5568         d->polishScheduled = false;
5569         updatePolish();
5570         return true;
5571     } else {
5572         return QObject::event(ev);
5573     }
5574 #endif
5575     if (ev->type() == QEvent::InputMethodQuery) {
5576         QInputMethodQueryEvent *query = static_cast<QInputMethodQueryEvent *>(ev);
5577         Qt::InputMethodQueries queries = query->queries();
5578         for (uint i = 0; i < 32; ++i) {
5579             Qt::InputMethodQuery q = (Qt::InputMethodQuery)(int)(queries & (1<<i));
5580             if (q) {
5581                 QVariant v = inputMethodQuery(q);
5582                 query->setValue(q, v);
5583             }
5584         }
5585         query->accept();
5586         return true;
5587     } else if (ev->type() == QEvent::InputMethod) {
5588         inputMethodEvent(static_cast<QInputMethodEvent *>(ev));
5589         return true;
5590     }
5591     return QObject::event(ev);
5592 }
5593
5594 #ifndef QT_NO_DEBUG_STREAM
5595 QDebug operator<<(QDebug debug, QQuickItem *item)
5596 {
5597     if (!item) {
5598         debug << "QQuickItem(0)";
5599         return debug;
5600     }
5601
5602     debug << item->metaObject()->className() << "(this =" << ((void*)item)
5603           << ", name=" << item->objectName()
5604           << ", parent =" << ((void*)item->parentItem())
5605           << ", geometry =" << QRectF(item->pos(), QSizeF(item->width(), item->height()))
5606           << ", z =" << item->z() << ')';
5607     return debug;
5608 }
5609 #endif
5610
5611 qint64 QQuickItemPrivate::consistentTime = -1;
5612 void QQuickItemPrivate::setConsistentTime(qint64 t)
5613 {
5614     consistentTime = t;
5615 }
5616
5617 class QElapsedTimerConsistentTimeHack
5618 {
5619 public:
5620     void start() {
5621         t1 = QQuickItemPrivate::consistentTime;
5622         t2 = 0;
5623     }
5624     qint64 elapsed() {
5625         return QQuickItemPrivate::consistentTime - t1;
5626     }
5627     qint64 restart() {
5628         qint64 val = QQuickItemPrivate::consistentTime - t1;
5629         t1 = QQuickItemPrivate::consistentTime;
5630         t2 = 0;
5631         return val;
5632     }
5633
5634 private:
5635     qint64 t1;
5636     qint64 t2;
5637 };
5638
5639 void QQuickItemPrivate::start(QElapsedTimer &t)
5640 {
5641     if (QQuickItemPrivate::consistentTime == -1)
5642         t.start();
5643     else
5644         ((QElapsedTimerConsistentTimeHack*)&t)->start();
5645 }
5646
5647 qint64 QQuickItemPrivate::elapsed(QElapsedTimer &t)
5648 {
5649     if (QQuickItemPrivate::consistentTime == -1)
5650         return t.elapsed();
5651     else
5652         return ((QElapsedTimerConsistentTimeHack*)&t)->elapsed();
5653 }
5654
5655 qint64 QQuickItemPrivate::restart(QElapsedTimer &t)
5656 {
5657     if (QQuickItemPrivate::consistentTime == -1)
5658         return t.restart();
5659     else
5660         return ((QElapsedTimerConsistentTimeHack*)&t)->restart();
5661 }
5662
5663 /*!
5664     \fn bool QQuickItem::isTextureProvider() const
5665
5666     Returns true if this item is a texture provider. The default
5667     implementation returns false.
5668
5669     This function can be called from any thread.
5670  */
5671
5672 bool QQuickItem::isTextureProvider() const
5673 {
5674     Q_D(const QQuickItem);
5675     return d->extra.isAllocated() && d->extra->layer && d->extra->layer->effectSource() ?
5676            d->extra->layer->effectSource()->isTextureProvider() : false;
5677 }
5678
5679 /*!
5680     \fn QSGTextureProvider *QQuickItem::textureProvider() const
5681
5682     Returns the texture provider for an item. The default implementation
5683     returns 0.
5684
5685     This function may only be called on the rendering thread.
5686  */
5687
5688 QSGTextureProvider *QQuickItem::textureProvider() const
5689 {
5690     Q_D(const QQuickItem);
5691     return d->extra.isAllocated() && d->extra->layer && d->extra->layer->effectSource() ?
5692            d->extra->layer->effectSource()->textureProvider() : 0;
5693 }
5694
5695 QQuickItemLayer *QQuickItemPrivate::layer() const
5696 {
5697     if (!extra.isAllocated() || !extra->layer) {
5698         extra.value().layer = new QQuickItemLayer(const_cast<QQuickItem *>(q_func()));
5699         if (!componentComplete)
5700             extra->layer->classBegin();
5701     }
5702     return extra->layer;
5703 }
5704
5705 QQuickItemLayer::QQuickItemLayer(QQuickItem *item)
5706     : m_item(item)
5707     , m_enabled(false)
5708     , m_mipmap(false)
5709     , m_smooth(false)
5710     , m_componentComplete(true)
5711     , m_wrapMode(QQuickShaderEffectSource::ClampToEdge)
5712     , m_format(QQuickShaderEffectSource::RGBA)
5713     , m_name("source")
5714     , m_effectComponent(0)
5715     , m_effect(0)
5716     , m_effectSource(0)
5717 {
5718 }
5719
5720 QQuickItemLayer::~QQuickItemLayer()
5721 {
5722     delete m_effectSource;
5723     delete m_effect;
5724 }
5725
5726
5727
5728 /*!
5729     \qmlproperty bool QtQuick2::Item::layer.enabled
5730
5731     Holds wether the item is layered or not. Layering is disabled by default.
5732
5733     A layered item is rendered into an offscreen surface and cached until
5734     it is changed. Enabling layering for complex QML item hierarchies can
5735     some times be an optimization.
5736
5737     None of the other layer properties have any effect when the layer
5738     is disabled.
5739  */
5740
5741 void QQuickItemLayer::setEnabled(bool e)
5742 {
5743     if (e == m_enabled)
5744         return;
5745     m_enabled = e;
5746     if (m_componentComplete) {
5747         if (m_enabled)
5748             activate();
5749         else
5750             deactivate();
5751     }
5752
5753     emit enabledChanged(e);
5754 }
5755
5756 void QQuickItemLayer::classBegin()
5757 {
5758     Q_ASSERT(!m_effectSource);
5759     Q_ASSERT(!m_effect);
5760     m_componentComplete = false;
5761 }
5762
5763 void QQuickItemLayer::componentComplete()
5764 {
5765     Q_ASSERT(!m_componentComplete);
5766     m_componentComplete = true;
5767     if (m_enabled)
5768         activate();
5769 }
5770
5771 void QQuickItemLayer::activate()
5772 {
5773     Q_ASSERT(!m_effectSource);
5774     m_effectSource = new QQuickShaderEffectSource();
5775
5776     QQuickItem *parentItem = m_item->parentItem();
5777     if (parentItem) {
5778         m_effectSource->setParentItem(parentItem);
5779         m_effectSource->stackAfter(m_item);
5780     }
5781
5782     m_effectSource->setSourceItem(m_item);
5783     m_effectSource->setHideSource(true);
5784     m_effectSource->setSmooth(m_smooth);
5785     m_effectSource->setTextureSize(m_size);
5786     m_effectSource->setSourceRect(m_sourceRect);
5787     m_effectSource->setMipmap(m_mipmap);
5788     m_effectSource->setWrapMode(m_wrapMode);
5789     m_effectSource->setFormat(m_format);
5790
5791     if (m_effectComponent)
5792         activateEffect();
5793
5794     m_effectSource->setVisible(m_item->isVisible() && !m_effect);
5795
5796     updateZ();
5797     updateGeometry();
5798     updateOpacity();
5799     updateMatrix();
5800
5801     QQuickItemPrivate *id = QQuickItemPrivate::get(m_item);
5802     id->addItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Opacity | QQuickItemPrivate::Parent | QQuickItemPrivate::Visibility | QQuickItemPrivate::SiblingOrder);
5803 }
5804
5805 void QQuickItemLayer::deactivate()
5806 {
5807     Q_ASSERT(m_effectSource);
5808
5809     if (m_effectComponent)
5810         deactivateEffect();
5811
5812     delete m_effectSource;
5813     m_effectSource = 0;
5814
5815     QQuickItemPrivate *id = QQuickItemPrivate::get(m_item);
5816     id->removeItemChangeListener(this,  QQuickItemPrivate::Geometry | QQuickItemPrivate::Opacity | QQuickItemPrivate::Parent | QQuickItemPrivate::Visibility | QQuickItemPrivate::SiblingOrder);
5817 }
5818
5819 void QQuickItemLayer::activateEffect()
5820 {
5821     Q_ASSERT(m_effectSource);
5822     Q_ASSERT(m_effectComponent);
5823     Q_ASSERT(!m_effect);
5824
5825     QObject *created = m_effectComponent->beginCreate(m_effectComponent->creationContext());
5826     m_effect = qobject_cast<QQuickItem *>(created);
5827     if (!m_effect) {
5828         qWarning("Item: layer.effect is not a QML Item.");
5829         m_effectComponent->completeCreate();
5830         delete created;
5831         return;
5832     }
5833     QQuickItem *parentItem = m_item->parentItem();
5834     if (parentItem) {
5835         m_effect->setParentItem(parentItem);
5836         m_effect->stackAfter(m_effectSource);
5837     }
5838     m_effect->setVisible(m_item->isVisible());
5839     m_effect->setProperty(m_name, qVariantFromValue<QObject *>(m_effectSource));
5840     m_effectComponent->completeCreate();
5841 }
5842
5843 void QQuickItemLayer::deactivateEffect()
5844 {
5845     Q_ASSERT(m_effectSource);
5846     Q_ASSERT(m_effectComponent);
5847
5848     delete m_effect;
5849     m_effect = 0;
5850 }
5851
5852
5853 /*!
5854     \qmlproperty Component QtQuick2::Item::layer.effect
5855
5856     Holds the effect that is applied to this layer.
5857
5858     The effect is typically a \l ShaderEffect component, although any \l Item component can be
5859     assigned. The effect should have a source texture property with a name matching \l samplerName.
5860
5861     \sa samplerName
5862  */
5863
5864 void QQuickItemLayer::setEffect(QQmlComponent *component)
5865 {
5866     if (component == m_effectComponent)
5867         return;
5868
5869     bool updateNeeded = false;
5870     if (m_effectSource && m_effectComponent) {
5871         deactivateEffect();
5872         updateNeeded = true;
5873     }
5874
5875     m_effectComponent = component;
5876
5877     if (m_effectSource && m_effectComponent) {
5878         activateEffect();
5879         updateNeeded = true;
5880     }
5881
5882     if (updateNeeded) {
5883         updateZ();
5884         updateGeometry();
5885         updateOpacity();
5886         updateMatrix();
5887         m_effectSource->setVisible(m_item->isVisible() && !m_effect);
5888     }
5889
5890     emit effectChanged(component);
5891 }
5892
5893
5894 /*!
5895     \qmlproperty bool QtQuick2::Item::layer.mipmap
5896
5897     If this property is true, mipmaps are generated for the texture.
5898
5899     \note Some OpenGL ES 2 implementations do not support mipmapping of
5900     non-power-of-two textures.
5901  */
5902
5903 void QQuickItemLayer::setMipmap(bool mipmap)
5904 {
5905     if (mipmap == m_mipmap)
5906         return;
5907     m_mipmap = mipmap;
5908
5909     if (m_effectSource)
5910         m_effectSource->setMipmap(m_mipmap);
5911
5912     emit mipmapChanged(mipmap);
5913 }
5914
5915
5916 /*!
5917     \qmlproperty enumeration QtQuick2::Item::layer.format
5918
5919     This property defines the internal OpenGL format of the texture.
5920     Modifying this property makes most sense when the \a layer.effect is also
5921     specified. Depending on the OpenGL implementation, this property might
5922     allow you to save some texture memory.
5923
5924     \list
5925     \li ShaderEffectSource.Alpha - GL_ALPHA
5926     \li ShaderEffectSource.RGB - GL_RGB
5927     \li ShaderEffectSource.RGBA - GL_RGBA
5928     \endlist
5929
5930     \note Some OpenGL implementations do not support the GL_ALPHA format.
5931  */
5932
5933 void QQuickItemLayer::setFormat(QQuickShaderEffectSource::Format f)
5934 {
5935     if (f == m_format)
5936         return;
5937     m_format = f;
5938
5939     if (m_effectSource)
5940         m_effectSource->setFormat(m_format);
5941
5942     emit formatChanged(m_format);
5943 }
5944
5945
5946 /*!
5947     \qmlproperty enumeration QtQuick2::Item::layer.sourceRect
5948
5949     This property defines which rectangular area of the \l sourceItem to
5950     render into the texture. The source rectangle can be larger than
5951     \l sourceItem itself. If the rectangle is null, which is the default,
5952     the whole \l sourceItem is rendered to texture.
5953  */
5954
5955 void QQuickItemLayer::setSourceRect(const QRectF &sourceRect)
5956 {
5957     if (sourceRect == m_sourceRect)
5958         return;
5959     m_sourceRect = sourceRect;
5960
5961     if (m_effectSource)
5962         m_effectSource->setSourceRect(m_sourceRect);
5963
5964     emit sourceRectChanged(sourceRect);
5965 }
5966
5967
5968
5969 /*!
5970     \qmlproperty bool QtQuick2::Item::layer.smooth
5971
5972     Holds whether the layer is smoothly transformed.
5973  */
5974
5975 void QQuickItemLayer::setSmooth(bool s)
5976 {
5977     if (m_smooth == s)
5978         return;
5979     m_smooth = s;
5980
5981     if (m_effectSource)
5982         m_effectSource->setSmooth(m_smooth);
5983
5984     emit smoothChanged(s);
5985 }
5986
5987
5988
5989 /*!
5990     \qmlproperty size QtQuick2::Item::layer.textureSize
5991
5992     This property holds the requested pixel size of the layers texture. If it is empty,
5993     which is the default, the size of the item is used.
5994
5995     \note Some platforms have a limit on how small framebuffer objects can be,
5996     which means the actual texture size might be larger than the requested
5997     size.
5998  */
5999
6000 void QQuickItemLayer::setSize(const QSize &size)
6001 {
6002     if (size == m_size)
6003         return;
6004     m_size = size;
6005
6006     if (m_effectSource)
6007         m_effectSource->setTextureSize(size);
6008
6009     emit sizeChanged(size);
6010 }
6011
6012
6013
6014 /*!
6015     \qmlproperty enumeration QtQuick2::Item::layer.wrapMode
6016
6017     This property defines the OpenGL wrap modes associated with the texture.
6018     Modifying this property makes most sense when the \a layer.effect is
6019     specified.
6020
6021     \list
6022     \li ShaderEffectSource.ClampToEdge - GL_CLAMP_TO_EDGE both horizontally and vertically
6023     \li ShaderEffectSource.RepeatHorizontally - GL_REPEAT horizontally, GL_CLAMP_TO_EDGE vertically
6024     \li ShaderEffectSource.RepeatVertically - GL_CLAMP_TO_EDGE horizontally, GL_REPEAT vertically
6025     \li ShaderEffectSource.Repeat - GL_REPEAT both horizontally and vertically
6026     \endlist
6027
6028     \note Some OpenGL ES 2 implementations do not support the GL_REPEAT
6029     wrap mode with non-power-of-two textures.
6030  */
6031
6032 void QQuickItemLayer::setWrapMode(QQuickShaderEffectSource::WrapMode mode)
6033 {
6034     if (mode == m_wrapMode)
6035         return;
6036     m_wrapMode = mode;
6037
6038     if (m_effectSource)
6039         m_effectSource->setWrapMode(m_wrapMode);
6040
6041     emit wrapModeChanged(mode);
6042 }
6043
6044 /*!
6045     \qmlproperty string QtQuick2::Item::layer.samplerName
6046
6047     Holds the name of the effect's source texture property.
6048
6049     samplerName needs to match the name of the effect's source texture property
6050     so that the Item can pass the layer's offscreen surface to the effect correctly.
6051
6052     \sa effect, ShaderEffect
6053  */
6054
6055 void QQuickItemLayer::setName(const QByteArray &name) {
6056     if (m_name == name)
6057         return;
6058     if (m_effect) {
6059         m_effect->setProperty(m_name, QVariant());
6060         m_effect->setProperty(name, qVariantFromValue<QObject *>(m_effectSource));
6061     }
6062     m_name = name;
6063     emit nameChanged(name);
6064 }
6065
6066 void QQuickItemLayer::itemOpacityChanged(QQuickItem *item)
6067 {
6068     Q_UNUSED(item)
6069     updateOpacity();
6070 }
6071
6072 void QQuickItemLayer::itemGeometryChanged(QQuickItem *, const QRectF &, const QRectF &)
6073 {
6074     updateGeometry();
6075 }
6076
6077 void QQuickItemLayer::itemParentChanged(QQuickItem *item, QQuickItem *parent)
6078 {
6079     Q_UNUSED(item)
6080     Q_ASSERT(item == m_item);
6081     Q_ASSERT(parent != m_effectSource);
6082     Q_ASSERT(parent == 0 || parent != m_effect);
6083
6084     m_effectSource->setParentItem(parent);
6085     if (parent)
6086         m_effectSource->stackAfter(m_item);
6087
6088     if (m_effect) {
6089         m_effect->setParentItem(parent);
6090         if (parent)
6091             m_effect->stackAfter(m_effectSource);
6092     }
6093 }
6094
6095 void QQuickItemLayer::itemSiblingOrderChanged(QQuickItem *)
6096 {
6097     m_effectSource->stackAfter(m_item);
6098     if (m_effect)
6099         m_effect->stackAfter(m_effectSource);
6100 }
6101
6102 void QQuickItemLayer::itemVisibilityChanged(QQuickItem *)
6103 {
6104     QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
6105     Q_ASSERT(l);
6106     l->setVisible(m_item->isVisible());
6107 }
6108
6109 void QQuickItemLayer::updateZ()
6110 {
6111     if (!m_componentComplete || !m_enabled)
6112         return;
6113     QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
6114     Q_ASSERT(l);
6115     l->setZ(m_item->z());
6116 }
6117
6118 void QQuickItemLayer::updateOpacity()
6119 {
6120     QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
6121     Q_ASSERT(l);
6122     l->setOpacity(m_item->opacity());
6123 }
6124
6125 void QQuickItemLayer::updateGeometry()
6126 {
6127     QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
6128     Q_ASSERT(l);
6129     QRectF bounds = m_item->clipRect();
6130     l->setWidth(bounds.width());
6131     l->setHeight(bounds.height());
6132     l->setX(bounds.x() + m_item->x());
6133     l->setY(bounds.y() + m_item->y());
6134 }
6135
6136 void QQuickItemLayer::updateMatrix()
6137 {
6138     // Called directly from transformChanged(), so needs some extra
6139     // checks.
6140     if (!m_componentComplete || !m_enabled)
6141         return;
6142     QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
6143     Q_ASSERT(l);
6144     QQuickItemPrivate *ld = QQuickItemPrivate::get(l);
6145     l->setScale(m_item->scale());
6146     l->setRotation(m_item->rotation());
6147     ld->transforms = QQuickItemPrivate::get(m_item)->transforms;
6148     if (ld->origin() != QQuickItemPrivate::get(m_item)->origin())
6149         ld->extra.value().origin = QQuickItemPrivate::get(m_item)->origin();
6150     ld->dirty(QQuickItemPrivate::Transform);
6151 }
6152
6153 QQuickItemPrivate::ExtraData::ExtraData()
6154 : z(0), scale(1), rotation(0), opacity(1),
6155   contents(0), screenAttached(0), layoutDirectionAttached(0),
6156   keyHandler(0), layer(0), effectRefCount(0), hideRefCount(0),
6157   opacityNode(0), clipNode(0), rootNode(0), beforePaintNode(0),
6158   acceptedMouseButtons(0), origin(QQuickItem::Center)
6159 {
6160 }
6161
6162 QT_END_NAMESPACE
6163
6164 #include <moc_qquickitem.cpp>