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