aboutsummaryrefslogtreecommitdiffstats
path: root/src/declarative/items/qquickitem.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/declarative/items/qquickitem.cpp')
-rw-r--r--src/declarative/items/qquickitem.cpp5038
1 files changed, 5038 insertions, 0 deletions
diff --git a/src/declarative/items/qquickitem.cpp b/src/declarative/items/qquickitem.cpp
new file mode 100644
index 0000000000..b6951d9a77
--- /dev/null
+++ b/src/declarative/items/qquickitem.cpp
@@ -0,0 +1,5038 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickitem.h"
+
+#include "qquickcanvas.h"
+#include <QtDeclarative/qjsengine.h>
+#include "qquickcanvas_p.h"
+
+#include "qquickevents_p_p.h"
+
+#include <QtDeclarative/qdeclarativeengine.h>
+#include <QtDeclarative/qdeclarativecomponent.h>
+#include <QtDeclarative/qdeclarativeinfo.h>
+#include <QtGui/qpen.h>
+#include <QtGui/qcursor.h>
+#include <QtGui/qguiapplication.h>
+#include <QtGui/qinputpanel.h>
+#include <QtCore/qdebug.h>
+#include <QtCore/qcoreevent.h>
+#include <QtCore/qnumeric.h>
+
+#include <private/qdeclarativeengine_p.h>
+#include <private/qdeclarativestategroup_p.h>
+#include <private/qdeclarativeopenmetaobject_p.h>
+#include <private/qdeclarativestate_p.h>
+#include <private/qlistmodelinterface_p.h>
+#include <private/qquickitem_p.h>
+
+#include <float.h>
+
+// XXX todo Readd parentNotifier for faster parent bindings
+// XXX todo Check that elements that create items handle memory correctly after visual ownership change
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \qmlclass Transform QQuickTransform
+ \inqmlmodule QtQuick 2
+ \ingroup qml-transform-elements
+ \brief The Transform elements provide a way of building advanced transformations on Items.
+
+ The Transform element is a base type which cannot be instantiated directly.
+ The following concrete Transform types are available:
+
+ \list
+ \o \l Rotation
+ \o \l Scale
+ \o \l Translate
+ \endlist
+
+ The Transform elements let you create and control advanced transformations that can be configured
+ independently using specialized properties.
+
+ You can assign any number of Transform elements to an \l Item. Each Transform is applied in order,
+ one at a time.
+*/
+
+/*!
+ \qmlclass Translate QQuickTranslate
+ \inqmlmodule QtQuick 2
+ \ingroup qml-transform-elements
+ \brief The Translate object provides a way to move an Item without changing its x or y properties.
+
+ The Translate object provides independent control over position in addition to the Item's x and y properties.
+
+ The following example moves the Y axis of the \l Rectangle elements while still allowing the \l Row element
+ to lay the items out as if they had not been transformed:
+ \qml
+ import QtQuick 1.0
+
+ Row {
+ Rectangle {
+ width: 100; height: 100
+ color: "blue"
+ transform: Translate { y: 20 }
+ }
+ Rectangle {
+ width: 100; height: 100
+ color: "red"
+ transform: Translate { y: -20 }
+ }
+ }
+ \endqml
+
+ \image translate.png
+*/
+
+/*!
+ \qmlproperty real QtQuick2::Translate::x
+
+ The translation along the X axis.
+*/
+
+/*!
+ \qmlproperty real QtQuick2::Translate::y
+
+ The translation along the Y axis.
+*/
+
+/*!
+ \qmlclass Scale QQuickScale
+ \inqmlmodule QtQuick 2
+ \ingroup qml-transform-elements
+ \brief The Scale element provides a way to scale an Item.
+
+ The Scale element gives more control over scaling than using \l Item's \l{Item::scale}{scale} property. Specifically,
+ it allows a different scale for the x and y axes, and allows the scale to be relative to an
+ arbitrary point.
+
+ The following example scales the X axis of the Rectangle, relative to its interior point 25, 25:
+ \qml
+ Rectangle {
+ width: 100; height: 100
+ color: "blue"
+ transform: Scale { origin.x: 25; origin.y: 25; xScale: 3}
+ }
+ \endqml
+
+ \sa Rotation, Translate
+*/
+
+/*!
+ \qmlproperty real QtQuick2::Scale::origin.x
+ \qmlproperty real QtQuick2::Scale::origin.y
+
+ The point that the item is scaled from (i.e., the point that stays fixed relative to the parent as
+ the rest of the item grows). By default the origin is 0, 0.
+*/
+
+/*!
+ \qmlproperty real QtQuick2::Scale::xScale
+
+ The scaling factor for the X axis.
+*/
+
+/*!
+ \qmlproperty real QtQuick2::Scale::yScale
+
+ The scaling factor for the Y axis.
+*/
+
+/*!
+ \qmlclass Rotation QQuickRotation
+ \inqmlmodule QtQuick 2
+ \ingroup qml-transform-elements
+ \brief The Rotation object provides a way to rotate an Item.
+
+ The Rotation object gives more control over rotation than using \l Item's \l{Item::rotation}{rotation} property.
+ Specifically, it allows (z axis) rotation to be relative to an arbitrary point.
+
+ The following example rotates a Rectangle around its interior point 25, 25:
+ \qml
+ Rectangle {
+ width: 100; height: 100
+ color: "blue"
+ transform: Rotation { origin.x: 25; origin.y: 25; angle: 45}
+ }
+ \endqml
+
+ Rotation also provides a way to specify 3D-like rotations for Items. For these types of
+ rotations you must specify the axis to rotate around in addition to the origin point.
+
+ The following example shows various 3D-like rotations applied to an \l Image.
+ \snippet doc/src/snippets/declarative/rotation.qml 0
+
+ \image axisrotation.png
+
+ \sa {declarative/ui-components/dialcontrol}{Dial Control example}, {declarative/toys/clocks}{Clocks example}
+*/
+
+/*!
+ \qmlproperty real QtQuick2::Rotation::origin.x
+ \qmlproperty real QtQuick2::Rotation::origin.y
+
+ The origin point of the rotation (i.e., the point that stays fixed relative to the parent as
+ the rest of the item rotates). By default the origin is 0, 0.
+*/
+
+/*!
+ \qmlproperty real QtQuick2::Rotation::axis.x
+ \qmlproperty real QtQuick2::Rotation::axis.y
+ \qmlproperty real QtQuick2::Rotation::axis.z
+
+ The axis to rotate around. For simple (2D) rotation around a point, you do not need to specify an axis,
+ as the default axis is the z axis (\c{ axis { x: 0; y: 0; z: 1 } }).
+
+ For a typical 3D-like rotation you will usually specify both the origin and the axis.
+
+ \image 3d-rotation-axis.png
+*/
+
+/*!
+ \qmlproperty real QtQuick2::Rotation::angle
+
+ The angle to rotate, in degrees clockwise.
+*/
+
+QQuickTransformPrivate::QQuickTransformPrivate()
+{
+}
+
+QQuickTransform::QQuickTransform(QObject *parent)
+: QObject(*(new QQuickTransformPrivate), parent)
+{
+}
+
+QQuickTransform::QQuickTransform(QQuickTransformPrivate &dd, QObject *parent)
+: QObject(dd, parent)
+{
+}
+
+QQuickTransform::~QQuickTransform()
+{
+ Q_D(QQuickTransform);
+ for (int ii = 0; ii < d->items.count(); ++ii) {
+ QQuickItemPrivate *p = QQuickItemPrivate::get(d->items.at(ii));
+ p->transforms.removeOne(this);
+ p->dirty(QQuickItemPrivate::Transform);
+ }
+}
+
+void QQuickTransform::update()
+{
+ Q_D(QQuickTransform);
+ for (int ii = 0; ii < d->items.count(); ++ii) {
+ QQuickItemPrivate *p = QQuickItemPrivate::get(d->items.at(ii));
+ p->dirty(QQuickItemPrivate::Transform);
+ }
+}
+
+QQuickContents::QQuickContents(QQuickItem *item)
+: m_item(item), m_x(0), m_y(0), m_width(0), m_height(0)
+{
+ //### optimize
+ connect(this, SIGNAL(rectChanged(QRectF)), m_item, SIGNAL(childrenRectChanged(QRectF)));
+}
+
+QQuickContents::~QQuickContents()
+{
+ QList<QQuickItem *> children = m_item->childItems();
+ for (int i = 0; i < children.count(); ++i) {
+ QQuickItem *child = children.at(i);
+ QQuickItemPrivate::get(child)->removeItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed);
+ }
+}
+
+QRectF QQuickContents::rectF() const
+{
+ return QRectF(m_x, m_y, m_width, m_height);
+}
+
+void QQuickContents::calcHeight(QQuickItem *changed)
+{
+ qreal oldy = m_y;
+ qreal oldheight = m_height;
+
+ if (changed) {
+ qreal top = oldy;
+ qreal bottom = oldy + oldheight;
+ qreal y = changed->y();
+ if (y + changed->height() > bottom)
+ bottom = y + changed->height();
+ if (y < top)
+ top = y;
+ m_y = top;
+ m_height = bottom - top;
+ } else {
+ qreal top = FLT_MAX;
+ qreal bottom = 0;
+ QList<QQuickItem *> children = m_item->childItems();
+ for (int i = 0; i < children.count(); ++i) {
+ QQuickItem *child = children.at(i);
+ qreal y = child->y();
+ if (y + child->height() > bottom)
+ bottom = y + child->height();
+ if (y < top)
+ top = y;
+ }
+ if (!children.isEmpty())
+ m_y = top;
+ m_height = qMax(bottom - top, qreal(0.0));
+ }
+
+ if (m_height != oldheight || m_y != oldy)
+ emit rectChanged(rectF());
+}
+
+void QQuickContents::calcWidth(QQuickItem *changed)
+{
+ qreal oldx = m_x;
+ qreal oldwidth = m_width;
+
+ if (changed) {
+ qreal left = oldx;
+ qreal right = oldx + oldwidth;
+ qreal x = changed->x();
+ if (x + changed->width() > right)
+ right = x + changed->width();
+ if (x < left)
+ left = x;
+ m_x = left;
+ m_width = right - left;
+ } else {
+ qreal left = FLT_MAX;
+ qreal right = 0;
+ QList<QQuickItem *> children = m_item->childItems();
+ for (int i = 0; i < children.count(); ++i) {
+ QQuickItem *child = children.at(i);
+ qreal x = child->x();
+ if (x + child->width() > right)
+ right = x + child->width();
+ if (x < left)
+ left = x;
+ }
+ if (!children.isEmpty())
+ m_x = left;
+ m_width = qMax(right - left, qreal(0.0));
+ }
+
+ if (m_width != oldwidth || m_x != oldx)
+ emit rectChanged(rectF());
+}
+
+void QQuickContents::complete()
+{
+ QList<QQuickItem *> children = m_item->childItems();
+ for (int i = 0; i < children.count(); ++i) {
+ QQuickItem *child = children.at(i);
+ QQuickItemPrivate::get(child)->addItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed);
+ //###what about changes to visibility?
+ }
+
+ calcGeometry();
+}
+
+void QQuickContents::itemGeometryChanged(QQuickItem *changed, const QRectF &newGeometry, const QRectF &oldGeometry)
+{
+ Q_UNUSED(changed)
+ //### we can only pass changed if the left edge has moved left, or the right edge has moved right
+ if (newGeometry.width() != oldGeometry.width() || newGeometry.x() != oldGeometry.x())
+ calcWidth(/*changed*/);
+ if (newGeometry.height() != oldGeometry.height() || newGeometry.y() != oldGeometry.y())
+ calcHeight(/*changed*/);
+}
+
+void QQuickContents::itemDestroyed(QQuickItem *item)
+{
+ if (item)
+ QQuickItemPrivate::get(item)->removeItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed);
+ calcGeometry();
+}
+
+void QQuickContents::childRemoved(QQuickItem *item)
+{
+ if (item)
+ QQuickItemPrivate::get(item)->removeItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed);
+ calcGeometry();
+}
+
+void QQuickContents::childAdded(QQuickItem *item)
+{
+ if (item)
+ QQuickItemPrivate::get(item)->addItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed);
+ calcWidth(item);
+ calcHeight(item);
+}
+
+QQuickItemKeyFilter::QQuickItemKeyFilter(QQuickItem *item)
+: m_processPost(false), m_next(0)
+{
+ QQuickItemPrivate *p = item?QQuickItemPrivate::get(item):0;
+ if (p) {
+ m_next = p->keyHandler;
+ p->keyHandler = this;
+ }
+}
+
+QQuickItemKeyFilter::~QQuickItemKeyFilter()
+{
+}
+
+void QQuickItemKeyFilter::keyPressed(QKeyEvent *event, bool post)
+{
+ if (m_next) m_next->keyPressed(event, post);
+}
+
+void QQuickItemKeyFilter::keyReleased(QKeyEvent *event, bool post)
+{
+ if (m_next) m_next->keyReleased(event, post);
+}
+
+void QQuickItemKeyFilter::inputMethodEvent(QInputMethodEvent *event, bool post)
+{
+ if (m_next)
+ m_next->inputMethodEvent(event, post);
+ else
+ event->ignore();
+}
+
+QVariant QQuickItemKeyFilter::inputMethodQuery(Qt::InputMethodQuery query) const
+{
+ if (m_next) return m_next->inputMethodQuery(query);
+ return QVariant();
+}
+
+void QQuickItemKeyFilter::componentComplete()
+{
+ if (m_next) m_next->componentComplete();
+}
+/*!
+ \qmlclass KeyNavigation QQuickKeyNavigationAttached
+ \inqmlmodule QtQuick 2
+ \ingroup qml-basic-interaction-elements
+ \brief The KeyNavigation attached property supports key navigation by arrow keys.
+
+ Key-based user interfaces commonly allow the use of arrow keys to navigate between
+ focusable items. The KeyNavigation attached property enables this behavior by providing a
+ convenient way to specify the item that should gain focus when an arrow or tab key is pressed.
+
+ The following example provides key navigation for a 2x2 grid of items:
+
+ \snippet doc/src/snippets/declarative/keynavigation.qml 0
+
+ The top-left item initially receives focus by setting \l {Item::}{focus} to
+ \c true. When an arrow key is pressed, the focus will move to the
+ appropriate item, as defined by the value that has been set for
+ the KeyNavigation \l left, \l right, \l up or \l down properties.
+
+ Note that if a KeyNavigation attached property receives the key press and release
+ events for a requested arrow or tab key, the event is accepted and does not
+ propagate any further.
+
+ By default, KeyNavigation receives key events after the item to which it is attached.
+ If the item accepts the key event, the KeyNavigation attached property will not
+ receive an event for that key. Setting the \l priority property to
+ \c KeyNavigation.BeforeItem allows the event to be used for key navigation
+ before the item, rather than after.
+
+ If item to which the focus is switching is not enabled or visible, an attempt will
+ be made to skip this item and focus on the next. This is possible if there are
+ a chain of items with the same KeyNavigation handler. If multiple items in a row are not enabled
+ or visible, they will also be skipped.
+
+ KeyNavigation will implicitly set the other direction to return focus to this item. So if you set
+ \l left to another item, \l right will be set on that item's KeyNavigation to set focus back to this
+ item. However, if that item's KeyNavigation has had right explicitly set then no change will occur.
+ This means that the above example could have been written, with the same behaviour, without specifing
+ KeyNavigation.right or KeyNavigation.down for any of the items.
+
+ \sa {Keys}{Keys attached property}
+*/
+
+/*!
+ \qmlproperty Item QtQuick2::KeyNavigation::left
+ \qmlproperty Item QtQuick2::KeyNavigation::right
+ \qmlproperty Item QtQuick2::KeyNavigation::up
+ \qmlproperty Item QtQuick2::KeyNavigation::down
+ \qmlproperty Item QtQuick2::KeyNavigation::tab
+ \qmlproperty Item QtQuick2::KeyNavigation::backtab
+
+ These properties hold the item to assign focus to
+ when the left, right, up or down cursor keys, or the
+ tab key are pressed.
+*/
+
+/*!
+ \qmlproperty Item QtQuick2::KeyNavigation::tab
+ \qmlproperty Item QtQuick2::KeyNavigation::backtab
+
+ These properties hold the item to assign focus to
+ when the Tab key or Shift+Tab key combination (Backtab) are pressed.
+*/
+
+QQuickKeyNavigationAttached::QQuickKeyNavigationAttached(QObject *parent)
+: QObject(*(new QQuickKeyNavigationAttachedPrivate), parent),
+ QQuickItemKeyFilter(qobject_cast<QQuickItem*>(parent))
+{
+ m_processPost = true;
+}
+
+QQuickKeyNavigationAttached *
+QQuickKeyNavigationAttached::qmlAttachedProperties(QObject *obj)
+{
+ return new QQuickKeyNavigationAttached(obj);
+}
+
+QQuickItem *QQuickKeyNavigationAttached::left() const
+{
+ Q_D(const QQuickKeyNavigationAttached);
+ return d->left;
+}
+
+void QQuickKeyNavigationAttached::setLeft(QQuickItem *i)
+{
+ Q_D(QQuickKeyNavigationAttached);
+ if (d->left == i)
+ return;
+ d->left = i;
+ d->leftSet = true;
+ QQuickKeyNavigationAttached* other =
+ qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
+ if (other && !other->d_func()->rightSet){
+ other->d_func()->right = qobject_cast<QQuickItem*>(parent());
+ emit other->rightChanged();
+ }
+ emit leftChanged();
+}
+
+QQuickItem *QQuickKeyNavigationAttached::right() const
+{
+ Q_D(const QQuickKeyNavigationAttached);
+ return d->right;
+}
+
+void QQuickKeyNavigationAttached::setRight(QQuickItem *i)
+{
+ Q_D(QQuickKeyNavigationAttached);
+ if (d->right == i)
+ return;
+ d->right = i;
+ d->rightSet = true;
+ QQuickKeyNavigationAttached* other =
+ qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
+ if (other && !other->d_func()->leftSet){
+ other->d_func()->left = qobject_cast<QQuickItem*>(parent());
+ emit other->leftChanged();
+ }
+ emit rightChanged();
+}
+
+QQuickItem *QQuickKeyNavigationAttached::up() const
+{
+ Q_D(const QQuickKeyNavigationAttached);
+ return d->up;
+}
+
+void QQuickKeyNavigationAttached::setUp(QQuickItem *i)
+{
+ Q_D(QQuickKeyNavigationAttached);
+ if (d->up == i)
+ return;
+ d->up = i;
+ d->upSet = true;
+ QQuickKeyNavigationAttached* other =
+ qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
+ if (other && !other->d_func()->downSet){
+ other->d_func()->down = qobject_cast<QQuickItem*>(parent());
+ emit other->downChanged();
+ }
+ emit upChanged();
+}
+
+QQuickItem *QQuickKeyNavigationAttached::down() const
+{
+ Q_D(const QQuickKeyNavigationAttached);
+ return d->down;
+}
+
+void QQuickKeyNavigationAttached::setDown(QQuickItem *i)
+{
+ Q_D(QQuickKeyNavigationAttached);
+ if (d->down == i)
+ return;
+ d->down = i;
+ d->downSet = true;
+ QQuickKeyNavigationAttached* other =
+ qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
+ if (other && !other->d_func()->upSet) {
+ other->d_func()->up = qobject_cast<QQuickItem*>(parent());
+ emit other->upChanged();
+ }
+ emit downChanged();
+}
+
+QQuickItem *QQuickKeyNavigationAttached::tab() const
+{
+ Q_D(const QQuickKeyNavigationAttached);
+ return d->tab;
+}
+
+void QQuickKeyNavigationAttached::setTab(QQuickItem *i)
+{
+ Q_D(QQuickKeyNavigationAttached);
+ if (d->tab == i)
+ return;
+ d->tab = i;
+ d->tabSet = true;
+ QQuickKeyNavigationAttached* other =
+ qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
+ if (other && !other->d_func()->backtabSet) {
+ other->d_func()->backtab = qobject_cast<QQuickItem*>(parent());
+ emit other->backtabChanged();
+ }
+ emit tabChanged();
+}
+
+QQuickItem *QQuickKeyNavigationAttached::backtab() const
+{
+ Q_D(const QQuickKeyNavigationAttached);
+ return d->backtab;
+}
+
+void QQuickKeyNavigationAttached::setBacktab(QQuickItem *i)
+{
+ Q_D(QQuickKeyNavigationAttached);
+ if (d->backtab == i)
+ return;
+ d->backtab = i;
+ d->backtabSet = true;
+ QQuickKeyNavigationAttached* other =
+ qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
+ if (other && !other->d_func()->tabSet) {
+ other->d_func()->tab = qobject_cast<QQuickItem*>(parent());
+ emit other->tabChanged();
+ }
+ emit backtabChanged();
+}
+
+/*!
+ \qmlproperty enumeration QtQuick2::KeyNavigation::priority
+
+ This property determines whether the keys are processed before
+ or after the attached item's own key handling.
+
+ \list
+ \o KeyNavigation.BeforeItem - process the key events before normal
+ item key processing. If the event is used for key navigation, it will be accepted and will not
+ be passed on to the item.
+ \o KeyNavigation.AfterItem (default) - process the key events after normal item key
+ handling. If the item accepts the key event it will not be
+ handled by the KeyNavigation attached property handler.
+ \endlist
+*/
+QQuickKeyNavigationAttached::Priority QQuickKeyNavigationAttached::priority() const
+{
+ return m_processPost ? AfterItem : BeforeItem;
+}
+
+void QQuickKeyNavigationAttached::setPriority(Priority order)
+{
+ bool processPost = order == AfterItem;
+ if (processPost != m_processPost) {
+ m_processPost = processPost;
+ emit priorityChanged();
+ }
+}
+
+void QQuickKeyNavigationAttached::keyPressed(QKeyEvent *event, bool post)
+{
+ Q_D(QQuickKeyNavigationAttached);
+ event->ignore();
+
+ if (post != m_processPost) {
+ QQuickItemKeyFilter::keyPressed(event, post);
+ return;
+ }
+
+ bool mirror = false;
+ switch (event->key()) {
+ case Qt::Key_Left: {
+ if (QQuickItem *parentItem = qobject_cast<QQuickItem*>(parent()))
+ mirror = QQuickItemPrivate::get(parentItem)->effectiveLayoutMirror;
+ QQuickItem* leftItem = mirror ? d->right : d->left;
+ if (leftItem) {
+ setFocusNavigation(leftItem, mirror ? "right" : "left");
+ event->accept();
+ }
+ break;
+ }
+ case Qt::Key_Right: {
+ if (QQuickItem *parentItem = qobject_cast<QQuickItem*>(parent()))
+ mirror = QQuickItemPrivate::get(parentItem)->effectiveLayoutMirror;
+ QQuickItem* rightItem = mirror ? d->left : d->right;
+ if (rightItem) {
+ setFocusNavigation(rightItem, mirror ? "left" : "right");
+ event->accept();
+ }
+ break;
+ }
+ case Qt::Key_Up:
+ if (d->up) {
+ setFocusNavigation(d->up, "up");
+ event->accept();
+ }
+ break;
+ case Qt::Key_Down:
+ if (d->down) {
+ setFocusNavigation(d->down, "down");
+ event->accept();
+ }
+ break;
+ case Qt::Key_Tab:
+ if (d->tab) {
+ setFocusNavigation(d->tab, "tab");
+ event->accept();
+ }
+ break;
+ case Qt::Key_Backtab:
+ if (d->backtab) {
+ setFocusNavigation(d->backtab, "backtab");
+ event->accept();
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (!event->isAccepted()) QQuickItemKeyFilter::keyPressed(event, post);
+}
+
+void QQuickKeyNavigationAttached::keyReleased(QKeyEvent *event, bool post)
+{
+ Q_D(QQuickKeyNavigationAttached);
+ event->ignore();
+
+ if (post != m_processPost) {
+ QQuickItemKeyFilter::keyReleased(event, post);
+ return;
+ }
+
+ bool mirror = false;
+ switch (event->key()) {
+ case Qt::Key_Left:
+ if (QQuickItem *parentItem = qobject_cast<QQuickItem*>(parent()))
+ mirror = QQuickItemPrivate::get(parentItem)->effectiveLayoutMirror;
+ if (mirror ? d->right : d->left)
+ event->accept();
+ break;
+ case Qt::Key_Right:
+ if (QQuickItem *parentItem = qobject_cast<QQuickItem*>(parent()))
+ mirror = QQuickItemPrivate::get(parentItem)->effectiveLayoutMirror;
+ if (mirror ? d->left : d->right)
+ event->accept();
+ break;
+ case Qt::Key_Up:
+ if (d->up) {
+ event->accept();
+ }
+ break;
+ case Qt::Key_Down:
+ if (d->down) {
+ event->accept();
+ }
+ break;
+ case Qt::Key_Tab:
+ if (d->tab) {
+ event->accept();
+ }
+ break;
+ case Qt::Key_Backtab:
+ if (d->backtab) {
+ event->accept();
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (!event->isAccepted()) QQuickItemKeyFilter::keyReleased(event, post);
+}
+
+void QQuickKeyNavigationAttached::setFocusNavigation(QQuickItem *currentItem, const char *dir)
+{
+ QQuickItem *initialItem = currentItem;
+ bool isNextItem = false;
+ do {
+ isNextItem = false;
+ if (currentItem->isVisible() && currentItem->isEnabled()) {
+ currentItem->setFocus(true);
+ } else {
+ QObject *attached =
+ qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(currentItem, false);
+ if (attached) {
+ QQuickItem *tempItem = qvariant_cast<QQuickItem*>(attached->property(dir));
+ if (tempItem) {
+ currentItem = tempItem;
+ isNextItem = true;
+ }
+ }
+ }
+ }
+ while (currentItem != initialItem && isNextItem);
+}
+
+const QQuickKeysAttached::SigMap QQuickKeysAttached::sigMap[] = {
+ { Qt::Key_Left, "leftPressed" },
+ { Qt::Key_Right, "rightPressed" },
+ { Qt::Key_Up, "upPressed" },
+ { Qt::Key_Down, "downPressed" },
+ { Qt::Key_Tab, "tabPressed" },
+ { Qt::Key_Backtab, "backtabPressed" },
+ { Qt::Key_Asterisk, "asteriskPressed" },
+ { Qt::Key_NumberSign, "numberSignPressed" },
+ { Qt::Key_Escape, "escapePressed" },
+ { Qt::Key_Return, "returnPressed" },
+ { Qt::Key_Enter, "enterPressed" },
+ { Qt::Key_Delete, "deletePressed" },
+ { Qt::Key_Space, "spacePressed" },
+ { Qt::Key_Back, "backPressed" },
+ { Qt::Key_Cancel, "cancelPressed" },
+ { Qt::Key_Select, "selectPressed" },
+ { Qt::Key_Yes, "yesPressed" },
+ { Qt::Key_No, "noPressed" },
+ { Qt::Key_Context1, "context1Pressed" },
+ { Qt::Key_Context2, "context2Pressed" },
+ { Qt::Key_Context3, "context3Pressed" },
+ { Qt::Key_Context4, "context4Pressed" },
+ { Qt::Key_Call, "callPressed" },
+ { Qt::Key_Hangup, "hangupPressed" },
+ { Qt::Key_Flip, "flipPressed" },
+ { Qt::Key_Menu, "menuPressed" },
+ { Qt::Key_VolumeUp, "volumeUpPressed" },
+ { Qt::Key_VolumeDown, "volumeDownPressed" },
+ { 0, 0 }
+};
+
+bool QQuickKeysAttachedPrivate::isConnected(const char *signalName)
+{
+ return isSignalConnected(signalIndex(signalName));
+}
+
+/*!
+ \qmlclass Keys QQuickKeysAttached
+ \inqmlmodule QtQuick 2
+ \ingroup qml-basic-interaction-elements
+ \brief The Keys attached property provides key handling to Items.
+
+ All visual primitives support key handling via the Keys
+ attached property. Keys can be handled via the onPressed
+ and onReleased signal properties.
+
+ The signal properties have a \l KeyEvent parameter, named
+ \e event which contains details of the event. If a key is
+ handled \e event.accepted should be set to true to prevent the
+ event from propagating up the item hierarchy.
+
+ \section1 Example Usage
+
+ The following example shows how the general onPressed handler can
+ be used to test for a certain key; in this case, the left cursor
+ key:
+
+ \snippet doc/src/snippets/declarative/keys/keys-pressed.qml key item
+
+ Some keys may alternatively be handled via specific signal properties,
+ for example \e onSelectPressed. These handlers automatically set
+ \e event.accepted to true.
+
+ \snippet doc/src/snippets/declarative/keys/keys-handler.qml key item
+
+ See \l{Qt::Key}{Qt.Key} for the list of keyboard codes.
+
+ \section1 Key Handling Priorities
+
+ The Keys attached property can be configured to handle key events
+ before or after the item it is attached to. This makes it possible
+ to intercept events in order to override an item's default behavior,
+ or act as a fallback for keys not handled by the item.
+
+ If \l priority is Keys.BeforeItem (default) the order of key event processing is:
+
+ \list 1
+ \o Items specified in \c forwardTo
+ \o specific key handlers, e.g. onReturnPressed
+ \o onKeyPress, onKeyRelease handlers
+ \o Item specific key handling, e.g. TextInput key handling
+ \o parent item
+ \endlist
+
+ If priority is Keys.AfterItem the order of key event processing is:
+
+ \list 1
+ \o Item specific key handling, e.g. TextInput key handling
+ \o Items specified in \c forwardTo
+ \o specific key handlers, e.g. onReturnPressed
+ \o onKeyPress, onKeyRelease handlers
+ \o parent item
+ \endlist
+
+ If the event is accepted during any of the above steps, key
+ propagation stops.
+
+ \sa KeyEvent, {KeyNavigation}{KeyNavigation attached property}
+*/
+
+/*!
+ \qmlproperty bool QtQuick2::Keys::enabled
+
+ This flags enables key handling if true (default); otherwise
+ no key handlers will be called.
+*/
+
+/*!
+ \qmlproperty enumeration QtQuick2::Keys::priority
+
+ This property determines whether the keys are processed before
+ or after the attached item's own key handling.
+
+ \list
+ \o Keys.BeforeItem (default) - process the key events before normal
+ item key processing. If the event is accepted it will not
+ be passed on to the item.
+ \o Keys.AfterItem - process the key events after normal item key
+ handling. If the item accepts the key event it will not be
+ handled by the Keys attached property handler.
+ \endlist
+*/
+
+/*!
+ \qmlproperty list<Object> QtQuick2::Keys::forwardTo
+
+ This property provides a way to forward key presses, key releases, and keyboard input
+ coming from input methods to other items. This can be useful when you want
+ one item to handle some keys (e.g. the up and down arrow keys), and another item to
+ handle other keys (e.g. the left and right arrow keys). Once an item that has been
+ forwarded keys accepts the event it is no longer forwarded to items later in the
+ list.
+
+ This example forwards key events to two lists:
+ \qml
+ Item {
+ ListView {
+ id: list1
+ // ...
+ }
+ ListView {
+ id: list2
+ // ...
+ }
+ Keys.forwardTo: [list1, list2]
+ focus: true
+ }
+ \endqml
+*/
+
+/*!
+ \qmlsignal QtQuick2::Keys::onPressed(KeyEvent event)
+
+ This handler is called when a key has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal QtQuick2::Keys::onReleased(KeyEvent event)
+
+ This handler is called when a key has been released. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal QtQuick2::Keys::onDigit0Pressed(KeyEvent event)
+
+ This handler is called when the digit '0' has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal QtQuick2::Keys::onDigit1Pressed(KeyEvent event)
+
+ This handler is called when the digit '1' has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal QtQuick2::Keys::onDigit2Pressed(KeyEvent event)
+
+ This handler is called when the digit '2' has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal QtQuick2::Keys::onDigit3Pressed(KeyEvent event)
+
+ This handler is called when the digit '3' has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal QtQuick2::Keys::onDigit4Pressed(KeyEvent event)
+
+ This handler is called when the digit '4' has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal QtQuick2::Keys::onDigit5Pressed(KeyEvent event)
+
+ This handler is called when the digit '5' has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal QtQuick2::Keys::onDigit6Pressed(KeyEvent event)
+
+ This handler is called when the digit '6' has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal QtQuick2::Keys::onDigit7Pressed(KeyEvent event)
+
+ This handler is called when the digit '7' has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal QtQuick2::Keys::onDigit8Pressed(KeyEvent event)
+
+ This handler is called when the digit '8' has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal QtQuick2::Keys::onDigit9Pressed(KeyEvent event)
+
+ This handler is called when the digit '9' has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal QtQuick2::Keys::onLeftPressed(KeyEvent event)
+
+ This handler is called when the Left arrow has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal QtQuick2::Keys::onRightPressed(KeyEvent event)
+
+ This handler is called when the Right arrow has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal QtQuick2::Keys::onUpPressed(KeyEvent event)
+
+ This handler is called when the Up arrow has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal QtQuick2::Keys::onDownPressed(KeyEvent event)
+
+ This handler is called when the Down arrow has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal QtQuick2::Keys::onTabPressed(KeyEvent event)
+
+ This handler is called when the Tab key has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal QtQuick2::Keys::onBacktabPressed(KeyEvent event)
+
+ This handler is called when the Shift+Tab key combination (Backtab) has
+ been pressed. The \a event parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal QtQuick2::Keys::onAsteriskPressed(KeyEvent event)
+
+ This handler is called when the Asterisk '*' has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal QtQuick2::Keys::onEscapePressed(KeyEvent event)
+
+ This handler is called when the Escape key has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal QtQuick2::Keys::onReturnPressed(KeyEvent event)
+
+ This handler is called when the Return key has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal QtQuick2::Keys::onEnterPressed(KeyEvent event)
+
+ This handler is called when the Enter key has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal QtQuick2::Keys::onDeletePressed(KeyEvent event)
+
+ This handler is called when the Delete key has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal QtQuick2::Keys::onSpacePressed(KeyEvent event)
+
+ This handler is called when the Space key has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal QtQuick2::Keys::onBackPressed(KeyEvent event)
+
+ This handler is called when the Back key has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal QtQuick2::Keys::onCancelPressed(KeyEvent event)
+
+ This handler is called when the Cancel key has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal QtQuick2::Keys::onSelectPressed(KeyEvent event)
+
+ This handler is called when the Select key has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal QtQuick2::Keys::onYesPressed(KeyEvent event)
+
+ This handler is called when the Yes key has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal QtQuick2::Keys::onNoPressed(KeyEvent event)
+
+ This handler is called when the No key has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal QtQuick2::Keys::onContext1Pressed(KeyEvent event)
+
+ This handler is called when the Context1 key has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal QtQuick2::Keys::onContext2Pressed(KeyEvent event)
+
+ This handler is called when the Context2 key has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal QtQuick2::Keys::onContext3Pressed(KeyEvent event)
+
+ This handler is called when the Context3 key has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal QtQuick2::Keys::onContext4Pressed(KeyEvent event)
+
+ This handler is called when the Context4 key has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal QtQuick2::Keys::onCallPressed(KeyEvent event)
+
+ This handler is called when the Call key has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal QtQuick2::Keys::onHangupPressed(KeyEvent event)
+
+ This handler is called when the Hangup key has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal QtQuick2::Keys::onFlipPressed(KeyEvent event)
+
+ This handler is called when the Flip key has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal QtQuick2::Keys::onMenuPressed(KeyEvent event)
+
+ This handler is called when the Menu key has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal QtQuick2::Keys::onVolumeUpPressed(KeyEvent event)
+
+ This handler is called when the VolumeUp key has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+/*!
+ \qmlsignal QtQuick2::Keys::onVolumeDownPressed(KeyEvent event)
+
+ This handler is called when the VolumeDown key has been pressed. The \a event
+ parameter provides information about the event.
+*/
+
+QQuickKeysAttached::QQuickKeysAttached(QObject *parent)
+: QObject(*(new QQuickKeysAttachedPrivate), parent),
+ QQuickItemKeyFilter(qobject_cast<QQuickItem*>(parent))
+{
+ Q_D(QQuickKeysAttached);
+ m_processPost = false;
+ d->item = qobject_cast<QQuickItem*>(parent);
+}
+
+QQuickKeysAttached::~QQuickKeysAttached()
+{
+}
+
+QQuickKeysAttached::Priority QQuickKeysAttached::priority() const
+{
+ return m_processPost ? AfterItem : BeforeItem;
+}
+
+void QQuickKeysAttached::setPriority(Priority order)
+{
+ bool processPost = order == AfterItem;
+ if (processPost != m_processPost) {
+ m_processPost = processPost;
+ emit priorityChanged();
+ }
+}
+
+void QQuickKeysAttached::componentComplete()
+{
+ Q_D(QQuickKeysAttached);
+ if (d->item) {
+ for (int ii = 0; ii < d->targets.count(); ++ii) {
+ QQuickItem *targetItem = d->targets.at(ii);
+ if (targetItem && (targetItem->flags() & QQuickItem::ItemAcceptsInputMethod)) {
+ d->item->setFlag(QQuickItem::ItemAcceptsInputMethod);
+ break;
+ }
+ }
+ }
+}
+
+void QQuickKeysAttached::keyPressed(QKeyEvent *event, bool post)
+{
+ Q_D(QQuickKeysAttached);
+ if (post != m_processPost || !d->enabled || d->inPress) {
+ event->ignore();
+ QQuickItemKeyFilter::keyPressed(event, post);
+ return;
+ }
+
+ // first process forwards
+ if (d->item && d->item->canvas()) {
+ d->inPress = true;
+ for (int ii = 0; ii < d->targets.count(); ++ii) {
+ QQuickItem *i = d->targets.at(ii);
+ if (i && i->isVisible()) {
+ d->item->canvas()->sendEvent(i, event);
+ if (event->isAccepted()) {
+ d->inPress = false;
+ return;
+ }
+ }
+ }
+ d->inPress = false;
+ }
+
+ QQuickKeyEvent ke(*event);
+ QByteArray keySignal = keyToSignal(event->key());
+ if (!keySignal.isEmpty()) {
+ keySignal += "(QQuickKeyEvent*)";
+ if (d->isConnected(keySignal)) {
+ // If we specifically handle a key then default to accepted
+ ke.setAccepted(true);
+ int idx = QQuickKeysAttached::staticMetaObject.indexOfSignal(keySignal);
+ metaObject()->method(idx).invoke(this, Qt::DirectConnection, Q_ARG(QQuickKeyEvent*, &ke));
+ }
+ }
+ if (!ke.isAccepted())
+ emit pressed(&ke);
+ event->setAccepted(ke.isAccepted());
+
+ if (!event->isAccepted()) QQuickItemKeyFilter::keyPressed(event, post);
+}
+
+void QQuickKeysAttached::keyReleased(QKeyEvent *event, bool post)
+{
+ Q_D(QQuickKeysAttached);
+ if (post != m_processPost || !d->enabled || d->inRelease) {
+ event->ignore();
+ QQuickItemKeyFilter::keyReleased(event, post);
+ return;
+ }
+
+ if (d->item && d->item->canvas()) {
+ d->inRelease = true;
+ for (int ii = 0; ii < d->targets.count(); ++ii) {
+ QQuickItem *i = d->targets.at(ii);
+ if (i && i->isVisible()) {
+ d->item->canvas()->sendEvent(i, event);
+ if (event->isAccepted()) {
+ d->inRelease = false;
+ return;
+ }
+ }
+ }
+ d->inRelease = false;
+ }
+
+ QQuickKeyEvent ke(*event);
+ emit released(&ke);
+ event->setAccepted(ke.isAccepted());
+
+ if (!event->isAccepted()) QQuickItemKeyFilter::keyReleased(event, post);
+}
+
+void QQuickKeysAttached::inputMethodEvent(QInputMethodEvent *event, bool post)
+{
+ Q_D(QQuickKeysAttached);
+ if (post == m_processPost && d->item && !d->inIM && d->item->canvas()) {
+ d->inIM = true;
+ for (int ii = 0; ii < d->targets.count(); ++ii) {
+ QQuickItem *i = d->targets.at(ii);
+ if (i && i->isVisible() && (i->flags() & QQuickItem::ItemAcceptsInputMethod)) {
+ d->item->canvas()->sendEvent(i, event);
+ if (event->isAccepted()) {
+ d->imeItem = i;
+ d->inIM = false;
+ return;
+ }
+ }
+ }
+ d->inIM = false;
+ }
+ QQuickItemKeyFilter::inputMethodEvent(event, post);
+}
+
+QVariant QQuickKeysAttached::inputMethodQuery(Qt::InputMethodQuery query) const
+{
+ Q_D(const QQuickKeysAttached);
+ if (d->item) {
+ for (int ii = 0; ii < d->targets.count(); ++ii) {
+ QQuickItem *i = d->targets.at(ii);
+ if (i && i->isVisible() && (i->flags() & QQuickItem::ItemAcceptsInputMethod) && i == d->imeItem) {
+ //### how robust is i == d->imeItem check?
+ QVariant v = i->inputMethodQuery(query);
+ if (v.userType() == QVariant::RectF)
+ v = d->item->mapRectFromItem(i, v.toRectF()); //### cost?
+ return v;
+ }
+ }
+ }
+ return QQuickItemKeyFilter::inputMethodQuery(query);
+}
+
+QQuickKeysAttached *QQuickKeysAttached::qmlAttachedProperties(QObject *obj)
+{
+ return new QQuickKeysAttached(obj);
+}
+
+/*!
+ \qmlclass LayoutMirroring QQuickLayoutMirroringAttached
+ \inqmlmodule QtQuick 2
+ \ingroup qml-utility-elements
+ \brief The LayoutMirroring attached property is used to mirror layout behavior.
+
+ The LayoutMirroring attached property is used to horizontally mirror \l {anchor-layout}{Item anchors},
+ \l{Using QML Positioner and Repeater Items}{positioner} elements (such as \l Row and \l Grid)
+ and views (such as \l GridView and horizontal \l ListView). Mirroring is a visual change: left
+ anchors become right anchors, and positioner elements like \l Grid and \l Row reverse the
+ horizontal layout of child items.
+
+ Mirroring is enabled for an item by setting the \l enabled property to true. By default, this
+ only affects the item itself; setting the \l childrenInherit property to true propagates the mirroring
+ behavior to all child elements as well. If the \c LayoutMirroring attached property has not been defined
+ for an item, mirroring is not enabled.
+
+ The following example shows mirroring in action. The \l Row below is specified as being anchored
+ to the left of its parent. However, since mirroring has been enabled, the anchor is horizontally
+ reversed and it is now anchored to the right. Also, since items in a \l Row are positioned
+ from left to right by default, they are now positioned from right to left instead, as demonstrated
+ by the numbering and opacity of the items:
+
+ \snippet doc/src/snippets/declarative/layoutmirroring.qml 0
+
+ \image layoutmirroring.png
+
+ Layout mirroring is useful when it is necessary to support both left-to-right and right-to-left
+ layout versions of an application to target different language areas. The \l childrenInherit
+ property allows layout mirroring to be applied without manually setting layout configurations
+ for every item in an application. Keep in mind, however, that mirroring does not affect any
+ positioning that is defined by the \l Item \l {Item::}{x} coordinate value, so even with
+ mirroring enabled, it will often be necessary to apply some layout fixes to support the
+ desired layout direction. Also, it may be necessary to disable the mirroring of individual
+ child items (by setting \l {enabled}{LayoutMirroring.enabled} to false for such items) if
+ mirroring is not the desired behavior, or if the child item already implements mirroring in
+ some custom way.
+
+ See \l {QML Right-to-left User Interfaces} for further details on using \c LayoutMirroring and
+ other related features to implement right-to-left support for an application.
+*/
+
+/*!
+ \qmlproperty bool QtQuick2::LayoutMirroring::enabled
+
+ This property holds whether the item's layout is mirrored horizontally. Setting this to true
+ horizontally reverses \l {anchor-layout}{anchor} settings such that left anchors become right,
+ and right anchors become left. For \l{Using QML Positioner and Repeater Items}{positioner} elements
+ (such as \l Row and \l Grid) and view elements (such as \l {GridView}{GridView} and \l {ListView}{ListView})
+ this also mirrors the horizontal layout direction of the item.
+
+ The default value is false.
+*/
+
+/*!
+ \qmlproperty bool QtQuick2::LayoutMirroring::childrenInherit
+
+ This property holds whether the \l {enabled}{LayoutMirroring.enabled} value for this item
+ is inherited by its children.
+
+ The default value is false.
+*/
+
+
+QQuickLayoutMirroringAttached::QQuickLayoutMirroringAttached(QObject *parent) : QObject(parent), itemPrivate(0)
+{
+ if (QQuickItem *item = qobject_cast<QQuickItem*>(parent)) {
+ itemPrivate = QQuickItemPrivate::get(item);
+ itemPrivate->attachedLayoutDirection = this;
+ } else
+ qmlInfo(parent) << tr("LayoutDirection attached property only works with Items");
+}
+
+QQuickLayoutMirroringAttached * QQuickLayoutMirroringAttached::qmlAttachedProperties(QObject *object)
+{
+ return new QQuickLayoutMirroringAttached(object);
+}
+
+bool QQuickLayoutMirroringAttached::enabled() const
+{
+ return itemPrivate ? itemPrivate->effectiveLayoutMirror : false;
+}
+
+void QQuickLayoutMirroringAttached::setEnabled(bool enabled)
+{
+ if (!itemPrivate)
+ return;
+
+ itemPrivate->isMirrorImplicit = false;
+ if (enabled != itemPrivate->effectiveLayoutMirror) {
+ itemPrivate->setLayoutMirror(enabled);
+ if (itemPrivate->inheritMirrorFromItem)
+ itemPrivate->resolveLayoutMirror();
+ }
+}
+
+void QQuickLayoutMirroringAttached::resetEnabled()
+{
+ if (itemPrivate && !itemPrivate->isMirrorImplicit) {
+ itemPrivate->isMirrorImplicit = true;
+ itemPrivate->resolveLayoutMirror();
+ }
+}
+
+bool QQuickLayoutMirroringAttached::childrenInherit() const
+{
+ return itemPrivate ? itemPrivate->inheritMirrorFromItem : false;
+}
+
+void QQuickLayoutMirroringAttached::setChildrenInherit(bool childrenInherit) {
+ if (itemPrivate && childrenInherit != itemPrivate->inheritMirrorFromItem) {
+ itemPrivate->inheritMirrorFromItem = childrenInherit;
+ itemPrivate->resolveLayoutMirror();
+ childrenInheritChanged();
+ }
+}
+
+void QQuickItemPrivate::resolveLayoutMirror()
+{
+ Q_Q(QQuickItem);
+ if (QQuickItem *parentItem = q->parentItem()) {
+ QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(parentItem);
+ setImplicitLayoutMirror(parentPrivate->inheritedLayoutMirror, parentPrivate->inheritMirrorFromParent);
+ } else {
+ setImplicitLayoutMirror(isMirrorImplicit ? false : effectiveLayoutMirror, inheritMirrorFromItem);
+ }
+}
+
+void QQuickItemPrivate::setImplicitLayoutMirror(bool mirror, bool inherit)
+{
+ inherit = inherit || inheritMirrorFromItem;
+ if (!isMirrorImplicit && inheritMirrorFromItem)
+ mirror = effectiveLayoutMirror;
+ if (mirror == inheritedLayoutMirror && inherit == inheritMirrorFromParent)
+ return;
+
+ inheritMirrorFromParent = inherit;
+ inheritedLayoutMirror = inheritMirrorFromParent ? mirror : false;
+
+ if (isMirrorImplicit)
+ setLayoutMirror(inherit ? inheritedLayoutMirror : false);
+ for (int i = 0; i < childItems.count(); ++i) {
+ if (QQuickItem *child = qobject_cast<QQuickItem *>(childItems.at(i))) {
+ QQuickItemPrivate *childPrivate = QQuickItemPrivate::get(child);
+ childPrivate->setImplicitLayoutMirror(inheritedLayoutMirror, inheritMirrorFromParent);
+ }
+ }
+}
+
+void QQuickItemPrivate::setLayoutMirror(bool mirror)
+{
+ if (mirror != effectiveLayoutMirror) {
+ effectiveLayoutMirror = mirror;
+ if (_anchors) {
+ QQuickAnchorsPrivate *anchor_d = QQuickAnchorsPrivate::get(_anchors);
+ anchor_d->fillChanged();
+ anchor_d->centerInChanged();
+ anchor_d->updateHorizontalAnchors();
+ emit _anchors->mirroredChanged();
+ }
+ mirrorChange();
+ if (attachedLayoutDirection) {
+ emit attachedLayoutDirection->enabledChanged();
+ }
+ }
+}
+
+/*!
+ \class QQuickItem
+ \brief The QQuickItem class provides the most basic of all visual items in QML.
+
+ All visual items in Qt Declarative inherit from QQuickItem. Although QQuickItem
+ has no visual appearance, it defines all the properties that are
+ common across visual items - such as the x and y position, the
+ width and height, \l {anchor-layout}{anchoring} and key handling.
+
+ You can subclass QQuickItem to provide your own custom visual item that inherits
+ these features. Note that, because it does not draw anything, QQuickItem sets the
+ QGraphicsItem::ItemHasNoContents flag. If you subclass QQuickItem to create a visual
+ item, you will need to unset this flag.
+
+*/
+
+/*!
+ \qmlclass Item QQuickItem
+ \inqmlmodule QtQuick 2
+ \ingroup qml-basic-visual-elements
+ \brief The Item is the most basic of all visual items in QML.
+
+ All visual items in Qt Declarative inherit from Item. Although Item
+ has no visual appearance, it defines all the properties that are
+ common across visual items - such as the x and y position, the
+ width and height, \l {anchor-layout}{anchoring} and key handling.
+
+ Item is also useful for grouping items together.
+
+ \qml
+ Item {
+ Image {
+ source: "tile.png"
+ }
+ Image {
+ x: 80
+ width: 100
+ height: 100
+ source: "tile.png"
+ }
+ Image {
+ x: 190
+ width: 100
+ height: 100
+ fillMode: Image.Tile
+ source: "tile.png"
+ }
+ }
+ \endqml
+
+
+ \section1 Key Handling
+
+ Key handling is available to all Item-based visual elements via the \l {Keys}{Keys}
+ attached property. The \e Keys attached property provides basic handlers such
+ as \l {Keys::onPressed}{onPressed} and \l {Keys::onReleased}{onReleased},
+ as well as handlers for specific keys, such as
+ \l {Keys::onCancelPressed}{onCancelPressed}. The example below
+ assigns \l {qmlfocus}{focus} to the item and handles
+ the Left key via the general \e onPressed handler and the Select key via the
+ onSelectPressed handler:
+
+ \qml
+ Item {
+ focus: true
+ Keys.onPressed: {
+ if (event.key == Qt.Key_Left) {
+ console.log("move left");
+ event.accepted = true;
+ }
+ }
+ Keys.onSelectPressed: console.log("Selected");
+ }
+ \endqml
+
+ See the \l {Keys}{Keys} attached property for detailed documentation.
+
+ \section1 Layout Mirroring
+
+ Item layouts can be mirrored using the \l {LayoutMirroring}{LayoutMirroring} attached property.
+
+*/
+
+/*!
+ \fn void QQuickItem::childrenRectChanged(const QRectF &)
+ \internal
+*/
+
+/*!
+ \fn void QQuickItem::baselineOffsetChanged(qreal)
+ \internal
+*/
+
+/*!
+ \fn void QQuickItem::stateChanged(const QString &state)
+ \internal
+*/
+
+/*!
+ \fn void QQuickItem::parentChanged(QQuickItem *)
+ \internal
+*/
+
+/*!
+ \fn void QQuickItem::smoothChanged(bool)
+ \internal
+*/
+
+/*!
+ \fn void QQuickItem::clipChanged(bool)
+ \internal
+*/
+
+/*! \fn void QQuickItem::transformOriginChanged(TransformOrigin)
+ \internal
+*/
+
+/*!
+ \fn void QQuickItem::focusChanged(bool)
+ \internal
+*/
+
+/*!
+ \fn void QQuickItem::activeFocusChanged(bool)
+ \internal
+*/
+/*!
+ \fn QQuickItem::QQuickItem(QQuickItem *parent)
+
+ Constructs a QQuickItem with the given \a parent.
+*/
+QQuickItem::QQuickItem(QQuickItem* parent)
+: QObject(*(new QQuickItemPrivate), parent)
+{
+ Q_D(QQuickItem);
+ d->init(parent);
+}
+
+/*! \internal
+*/
+QQuickItem::QQuickItem(QQuickItemPrivate &dd, QQuickItem *parent)
+: QObject(dd, parent)
+{
+ Q_D(QQuickItem);
+ d->init(parent);
+}
+
+#ifndef QT_NO_DEBUG
+static int qt_item_count = 0;
+
+static void qt_print_item_count()
+{
+ qDebug("Number of leaked items: %i", qt_item_count);
+ qt_item_count = -1;
+}
+#endif
+
+/*!
+ Destroys the QQuickItem.
+*/
+QQuickItem::~QQuickItem()
+{
+#ifndef QT_NO_DEBUG
+ --qt_item_count;
+ if (qt_item_count < 0)
+ qDebug("Item destroyed after qt_print_item_count() was called.");
+#endif
+
+ Q_D(QQuickItem);
+
+ if (d->parentItem)
+ setParentItem(0);
+ else if (d->canvas && d->itemNodeInstance)
+ QQuickCanvasPrivate::get(d->canvas)->cleanup(d->itemNodeInstance); // cleanup root
+ // XXX todo - optimize
+ while (!d->childItems.isEmpty())
+ d->childItems.first()->setParentItem(0);
+
+ for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
+ QQuickAnchorsPrivate *anchor = d->changeListeners.at(ii).listener->anchorPrivate();
+ if (anchor)
+ anchor->clearItem(this);
+ }
+
+ // XXX todo - the original checks if the parent is being destroyed
+ for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
+ QQuickAnchorsPrivate *anchor = d->changeListeners.at(ii).listener->anchorPrivate();
+ if (anchor && anchor->item && anchor->item->parent() != this) //child will be deleted anyway
+ anchor->updateOnComplete();
+ }
+
+ for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
+ const QQuickItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
+ if (change.types & QQuickItemPrivate::Destroyed)
+ change.listener->itemDestroyed(this);
+ }
+ d->changeListeners.clear();
+ delete d->_anchorLines; d->_anchorLines = 0;
+ delete d->_anchors; d->_anchors = 0;
+ delete d->_stateGroup; d->_stateGroup = 0;
+ delete d->_contents; d->_contents = 0;
+}
+
+/*!
+ \qmlproperty enumeration QtQuick2::Item::transformOrigin
+ This property holds the origin point around which scale and rotation transform.
+
+ Nine transform origins are available, as shown in the image below.
+
+ \image declarative-transformorigin.png
+
+ This example rotates an image around its bottom-right corner.
+ \qml
+ Image {
+ source: "myimage.png"
+ transformOrigin: Item.BottomRight
+ rotation: 45
+ }
+ \endqml
+
+ The default transform origin is \c Item.Center.
+
+ To set an arbitrary transform origin point use the \l Scale or \l Rotation
+ transform elements.
+*/
+
+/*!
+ \qmlproperty Item QtQuick2::Item::parent
+ This property holds the parent of the item.
+*/
+
+/*!
+ \property QQuickItem::parent
+ This property holds the parent of the item.
+*/
+void QQuickItem::setParentItem(QQuickItem *parentItem)
+{
+ Q_D(QQuickItem);
+ if (parentItem == d->parentItem)
+ return;
+
+ d->removeFromDirtyList();
+
+ QQuickItem *oldParentItem = d->parentItem;
+ QQuickItem *scopeFocusedItem = 0;
+
+ if (oldParentItem) {
+ QQuickItemPrivate *op = QQuickItemPrivate::get(oldParentItem);
+
+ QQuickItem *scopeItem = 0;
+
+ if (d->canvas && hasFocus()) {
+ scopeItem = oldParentItem;
+ while (!scopeItem->isFocusScope()) scopeItem = scopeItem->parentItem();
+ scopeFocusedItem = this;
+ } else if (d->canvas && !isFocusScope() && d->subFocusItem) {
+ scopeItem = oldParentItem;
+ while (!scopeItem->isFocusScope()) scopeItem = scopeItem->parentItem();
+ scopeFocusedItem = d->subFocusItem;
+ }
+
+ if (scopeFocusedItem)
+ QQuickCanvasPrivate::get(d->canvas)->clearFocusInScope(scopeItem, scopeFocusedItem,
+ QQuickCanvasPrivate::DontChangeFocusProperty);
+
+ op->removeChild(this);
+ }
+
+ d->parentItem = parentItem;
+
+ QQuickCanvas *parentCanvas = parentItem?QQuickItemPrivate::get(parentItem)->canvas:0;
+ if (d->canvas != parentCanvas) {
+ QQuickItemPrivate::InitializationState initState;
+ initState.clear();
+ d->initCanvas(&initState, parentCanvas);
+ }
+
+ d->dirty(QQuickItemPrivate::ParentChanged);
+
+ if (d->parentItem)
+ QQuickItemPrivate::get(d->parentItem)->addChild(this);
+
+ d->setEffectiveVisibleRecur(d->calcEffectiveVisible());
+ d->setEffectiveEnableRecur(d->calcEffectiveEnable());
+
+ if (scopeFocusedItem && d->parentItem && d->canvas) {
+ // We need to test whether this item becomes scope focused
+ QQuickItem *scopeItem = 0;
+ scopeItem = d->parentItem;
+ while (!scopeItem->isFocusScope()) scopeItem = scopeItem->parentItem();
+
+ if (scopeItem->scopedFocusItem()) {
+ QQuickItemPrivate::get(scopeFocusedItem)->focus = false;
+ emit scopeFocusedItem->focusChanged(false);
+ } else {
+ QQuickCanvasPrivate::get(d->canvas)->setFocusInScope(scopeItem, scopeFocusedItem,
+ QQuickCanvasPrivate::DontChangeFocusProperty);
+ }
+ }
+
+ d->resolveLayoutMirror();
+
+ d->itemChange(ItemParentHasChanged, d->parentItem);
+
+ emit parentChanged(d->parentItem);
+}
+
+void QQuickItem::stackBefore(const QQuickItem *sibling)
+{
+ Q_D(QQuickItem);
+ if (!sibling || sibling == this || !d->parentItem || d->parentItem != QQuickItemPrivate::get(sibling)->parentItem) {
+ qWarning("QQuickItem::stackBefore: Cannot stack before %p, which must be a sibling", sibling);
+ return;
+ }
+
+ QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(d->parentItem);
+
+ int myIndex = parentPrivate->childItems.indexOf(this);
+ int siblingIndex = parentPrivate->childItems.indexOf(const_cast<QQuickItem *>(sibling));
+
+ Q_ASSERT(myIndex != -1 && siblingIndex != -1);
+
+ if (myIndex == siblingIndex - 1)
+ return;
+
+ parentPrivate->childItems.removeAt(myIndex);
+
+ if (myIndex < siblingIndex) --siblingIndex;
+
+ parentPrivate->childItems.insert(siblingIndex, this);
+
+ parentPrivate->dirty(QQuickItemPrivate::ChildrenStackingChanged);
+
+ for (int ii = qMin(siblingIndex, myIndex); ii < parentPrivate->childItems.count(); ++ii)
+ QQuickItemPrivate::get(parentPrivate->childItems.at(ii))->siblingOrderChanged();
+}
+
+void QQuickItem::stackAfter(const QQuickItem *sibling)
+{
+ Q_D(QQuickItem);
+ if (!sibling || sibling == this || !d->parentItem || d->parentItem != QQuickItemPrivate::get(sibling)->parentItem) {
+ qWarning("QQuickItem::stackAfter: Cannot stack after %p, which must be a sibling", sibling);
+ return;
+ }
+
+ QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(d->parentItem);
+
+ int myIndex = parentPrivate->childItems.indexOf(this);
+ int siblingIndex = parentPrivate->childItems.indexOf(const_cast<QQuickItem *>(sibling));
+
+ Q_ASSERT(myIndex != -1 && siblingIndex != -1);
+
+ if (myIndex == siblingIndex + 1)
+ return;
+
+ parentPrivate->childItems.removeAt(myIndex);
+
+ if (myIndex < siblingIndex) --siblingIndex;
+
+ parentPrivate->childItems.insert(siblingIndex + 1, this);
+
+ parentPrivate->dirty(QQuickItemPrivate::ChildrenStackingChanged);
+
+ for (int ii = qMin(myIndex, siblingIndex + 1); ii < parentPrivate->childItems.count(); ++ii)
+ QQuickItemPrivate::get(parentPrivate->childItems.at(ii))->siblingOrderChanged();
+}
+
+/*!
+ Returns the QQuickItem parent of this item.
+*/
+QQuickItem *QQuickItem::parentItem() const
+{
+ Q_D(const QQuickItem);
+ return d->parentItem;
+}
+
+QSGEngine *QQuickItem::sceneGraphEngine() const
+{
+ return canvas()->sceneGraphEngine();
+}
+
+QQuickCanvas *QQuickItem::canvas() const
+{
+ Q_D(const QQuickItem);
+ return d->canvas;
+}
+
+static bool itemZOrder_sort(QQuickItem *lhs, QQuickItem *rhs)
+{
+ return lhs->z() < rhs->z();
+}
+
+QList<QQuickItem *> QQuickItemPrivate::paintOrderChildItems() const
+{
+ // XXX todo - optimize, don't sort and return items that are
+ // ignored anyway, like invisible or disabled items.
+ QList<QQuickItem *> items = childItems;
+ qStableSort(items.begin(), items.end(), itemZOrder_sort);
+ return items;
+}
+
+void QQuickItemPrivate::addChild(QQuickItem *child)
+{
+ Q_Q(QQuickItem);
+
+ Q_ASSERT(!childItems.contains(child));
+
+ childItems.append(child);
+
+ dirty(QQuickItemPrivate::ChildrenChanged);
+
+ itemChange(QQuickItem::ItemChildAddedChange, child);
+
+ emit q->childrenChanged();
+}
+
+void QQuickItemPrivate::removeChild(QQuickItem *child)
+{
+ Q_Q(QQuickItem);
+
+ Q_ASSERT(child);
+ Q_ASSERT(childItems.contains(child));
+ childItems.removeOne(child);
+ Q_ASSERT(!childItems.contains(child));
+
+ dirty(QQuickItemPrivate::ChildrenChanged);
+
+ itemChange(QQuickItem::ItemChildRemovedChange, child);
+
+ emit q->childrenChanged();
+}
+
+void QQuickItemPrivate::InitializationState::clear()
+{
+ focusScope = 0;
+}
+
+void QQuickItemPrivate::InitializationState::clear(QQuickItem *fs)
+{
+ focusScope = fs;
+}
+
+QQuickItem *QQuickItemPrivate::InitializationState::getFocusScope(QQuickItem *item)
+{
+ if (!focusScope) {
+ QQuickItem *fs = item->parentItem();
+ while (!fs->isFocusScope())
+ fs = fs->parentItem();
+ focusScope = fs;
+ }
+ return focusScope;
+}
+
+void QQuickItemPrivate::initCanvas(InitializationState *state, QQuickCanvas *c)
+{
+ Q_Q(QQuickItem);
+
+ if (canvas) {
+ removeFromDirtyList();
+ QQuickCanvasPrivate *c = QQuickCanvasPrivate::get(canvas);
+ if (polishScheduled)
+ c->itemsToPolish.remove(q);
+ if (c->mouseGrabberItem == q)
+ c->mouseGrabberItem = 0;
+ if ( hoverEnabled )
+ c->hoverItems.removeAll(q);
+ if (itemNodeInstance)
+ c->cleanup(itemNodeInstance);
+ }
+
+ canvas = c;
+
+ if (canvas && polishScheduled)
+ QQuickCanvasPrivate::get(canvas)->itemsToPolish.insert(q);
+
+ itemNodeInstance = 0;
+ opacityNode = 0;
+ clipNode = 0;
+ rootNode = 0;
+ groupNode = 0;
+ paintNode = 0;
+ beforePaintNode = 0;
+
+ InitializationState _dummy;
+ InitializationState *childState = state;
+
+ if (c && q->isFocusScope()) {
+ _dummy.clear(q);
+ childState = &_dummy;
+ }
+
+ for (int ii = 0; ii < childItems.count(); ++ii) {
+ QQuickItem *child = childItems.at(ii);
+ QQuickItemPrivate::get(child)->initCanvas(childState, c);
+ }
+
+ if (c && focus) {
+ // Fixup
+ if (state->getFocusScope(q)->scopedFocusItem()) {
+ focus = false;
+ emit q->focusChanged(false);
+ } else {
+ QQuickCanvasPrivate::get(canvas)->setFocusInScope(state->getFocusScope(q), q);
+ }
+ }
+
+ dirty(Canvas);
+
+ itemChange(QQuickItem::ItemSceneChange, c);
+}
+
+/*!
+Returns a transform that maps points from canvas space into item space.
+*/
+QTransform QQuickItemPrivate::canvasToItemTransform() const
+{
+ // XXX todo - optimize
+ return itemToCanvasTransform().inverted();
+}
+
+/*!
+Returns a transform that maps points from item space into canvas space.
+*/
+QTransform QQuickItemPrivate::itemToCanvasTransform() const
+{
+ // XXX todo
+ QTransform rv = parentItem?QQuickItemPrivate::get(parentItem)->itemToCanvasTransform():QTransform();
+ itemToParentTransform(rv);
+ return rv;
+}
+
+/*!
+Motifies \a t with this items local transform relative to its parent.
+*/
+void QQuickItemPrivate::itemToParentTransform(QTransform &t) const
+{
+ if (x || y)
+ t.translate(x, y);
+
+ if (!transforms.isEmpty()) {
+ QMatrix4x4 m(t);
+ for (int ii = transforms.count() - 1; ii >= 0; --ii)
+ transforms.at(ii)->applyTo(&m);
+ t = m.toTransform();
+ }
+
+ if (scale != 1. || rotation != 0.) {
+ QPointF tp = computeTransformOrigin();
+ t.translate(tp.x(), tp.y());
+ t.scale(scale, scale);
+ t.rotate(rotation);
+ t.translate(-tp.x(), -tp.y());
+ }
+}
+
+
+/*!
+ \qmlproperty real QtQuick2::Item::childrenRect.x
+ \qmlproperty real QtQuick2::Item::childrenRect.y
+ \qmlproperty real QtQuick2::Item::childrenRect.width
+ \qmlproperty real QtQuick2::Item::childrenRect.height
+
+ The childrenRect properties allow an item access to the geometry of its
+ children. This property is useful if you have an item that needs to be
+ sized to fit its children.
+*/
+
+
+/*!
+ \qmlproperty list<Item> QtQuick2::Item::children
+ \qmlproperty list<Object> QtQuick2::Item::resources
+
+ The children property contains the list of visual children of this item.
+ The resources property contains non-visual resources that you want to
+ reference by name.
+
+ Generally you can rely on Item's default property to handle all this for
+ you, but it can come in handy in some cases.
+
+ \qml
+ Item {
+ children: [
+ Text {},
+ Rectangle {}
+ ]
+ resources: [
+ Component {
+ id: myComponent
+ Text {}
+ }
+ ]
+ }
+ \endqml
+*/
+
+/*!
+ Returns true if construction of the QML component is complete; otherwise
+ returns false.
+
+ It is often desirable to delay some processing until the component is
+ completed.
+
+ \sa componentComplete()
+*/
+bool QQuickItem::isComponentComplete() const
+{
+ Q_D(const QQuickItem);
+ return d->componentComplete;
+}
+
+QQuickItemPrivate::QQuickItemPrivate()
+: _anchors(0), _contents(0), baselineOffset(0), _anchorLines(0), _stateGroup(0), origin(QQuickItem::Center),
+
+ flags(0), widthValid(false), heightValid(false), componentComplete(true),
+ keepMouse(false), hoverEnabled(false), smooth(false), focus(false), activeFocus(false), notifiedFocus(false),
+ notifiedActiveFocus(false), filtersChildMouseEvents(false), explicitVisible(true),
+ effectiveVisible(true), explicitEnable(true), effectiveEnable(true), polishScheduled(false),
+ inheritedLayoutMirror(false), effectiveLayoutMirror(false), isMirrorImplicit(true),
+ inheritMirrorFromParent(false), inheritMirrorFromItem(false), childrenDoNotOverlap(false),
+
+ canvas(0), parentItem(0),
+
+ subFocusItem(0),
+
+ x(0), y(0), width(0), height(0), implicitWidth(0), implicitHeight(0),
+ z(0), scale(1), rotation(0), opacity(1),
+
+ attachedLayoutDirection(0), acceptedMouseButtons(0),
+ imHints(Qt::ImhMultiLine),
+
+ keyHandler(0),
+
+ dirtyAttributes(0), nextDirtyItem(0), prevDirtyItem(0),
+
+ itemNodeInstance(0), opacityNode(0), clipNode(0), rootNode(0), groupNode(0), paintNode(0)
+ , beforePaintNode(0), effectRefCount(0), hideRefCount(0)
+{
+}
+
+void QQuickItemPrivate::init(QQuickItem *parent)
+{
+#ifndef QT_NO_DEBUG
+ ++qt_item_count;
+ static bool atexit_registered = false;
+ if (!atexit_registered) {
+ atexit(qt_print_item_count);
+ atexit_registered = true;
+ }
+#endif
+
+ Q_Q(QQuickItem);
+ baselineOffset.invalidate();
+
+ if (parent) {
+ q->setParentItem(parent);
+ QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(parent);
+ setImplicitLayoutMirror(parentPrivate->inheritedLayoutMirror, parentPrivate->inheritMirrorFromParent);
+ }
+}
+
+void QQuickItemPrivate::data_append(QDeclarativeListProperty<QObject> *prop, QObject *o)
+{
+ if (!o)
+ return;
+
+ QQuickItem *that = static_cast<QQuickItem *>(prop->object);
+
+ // This test is measurably (albeit only slightly) faster than qobject_cast<>()
+ const QMetaObject *mo = o->metaObject();
+ while (mo && mo != &QQuickItem::staticMetaObject) {
+ mo = mo->d.superdata;
+ }
+
+ if (mo) {
+ QQuickItem *item = static_cast<QQuickItem *>(o);
+ item->setParentItem(that);
+ } else {
+ if (o->inherits("QGraphicsItem"))
+ qWarning("Cannot add a QtQuick 1.0 item (%s) into a QtQuick 2.0 scene!", o->metaObject()->className());
+
+ // XXX todo - do we really want this behavior?
+ o->setParent(that);
+ }
+}
+
+/*!
+ \qmlproperty list<Object> QtQuick2::Item::data
+ \default
+
+ The data property allows you to freely mix visual children and resources
+ in an item. If you assign a visual item to the data list it becomes
+ a child and if you assign any other object type, it is added as a resource.
+
+ So you can write:
+ \qml
+ Item {
+ Text {}
+ Rectangle {}
+ Timer {}
+ }
+ \endqml
+
+ instead of:
+ \qml
+ Item {
+ children: [
+ Text {},
+ Rectangle {}
+ ]
+ resources: [
+ Timer {}
+ ]
+ }
+ \endqml
+
+ data is a behind-the-scenes property: you should never need to explicitly
+ specify it.
+ */
+
+int QQuickItemPrivate::data_count(QDeclarativeListProperty<QObject> *prop)
+{
+ Q_UNUSED(prop);
+ // XXX todo
+ return 0;
+}
+
+QObject *QQuickItemPrivate::data_at(QDeclarativeListProperty<QObject> *prop, int i)
+{
+ Q_UNUSED(prop);
+ Q_UNUSED(i);
+ // XXX todo
+ return 0;
+}
+
+void QQuickItemPrivate::data_clear(QDeclarativeListProperty<QObject> *prop)
+{
+ Q_UNUSED(prop);
+ // XXX todo
+}
+
+QObject *QQuickItemPrivate::resources_at(QDeclarativeListProperty<QObject> *prop, int index)
+{
+ const QObjectList children = prop->object->children();
+ if (index < children.count())
+ return children.at(index);
+ else
+ return 0;
+}
+
+void QQuickItemPrivate::resources_append(QDeclarativeListProperty<QObject> *prop, QObject *o)
+{
+ // XXX todo - do we really want this behavior?
+ o->setParent(prop->object);
+}
+
+int QQuickItemPrivate::resources_count(QDeclarativeListProperty<QObject> *prop)
+{
+ return prop->object->children().count();
+}
+
+void QQuickItemPrivate::resources_clear(QDeclarativeListProperty<QObject> *prop)
+{
+ // XXX todo - do we really want this behavior?
+ const QObjectList children = prop->object->children();
+ for (int index = 0; index < children.count(); index++)
+ children.at(index)->setParent(0);
+}
+
+QQuickItem *QQuickItemPrivate::children_at(QDeclarativeListProperty<QQuickItem> *prop, int index)
+{
+ QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
+ if (index >= p->childItems.count() || index < 0)
+ return 0;
+ else
+ return p->childItems.at(index);
+}
+
+void QQuickItemPrivate::children_append(QDeclarativeListProperty<QQuickItem> *prop, QQuickItem *o)
+{
+ if (!o)
+ return;
+
+ QQuickItem *that = static_cast<QQuickItem *>(prop->object);
+ if (o->parentItem() == that)
+ o->setParentItem(0);
+
+ o->setParentItem(that);
+}
+
+int QQuickItemPrivate::children_count(QDeclarativeListProperty<QQuickItem> *prop)
+{
+ QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
+ return p->childItems.count();
+}
+
+void QQuickItemPrivate::children_clear(QDeclarativeListProperty<QQuickItem> *prop)
+{
+ QQuickItem *that = static_cast<QQuickItem *>(prop->object);
+ QQuickItemPrivate *p = QQuickItemPrivate::get(that);
+ while (!p->childItems.isEmpty())
+ p->childItems.at(0)->setParentItem(0);
+}
+
+int QQuickItemPrivate::transform_count(QDeclarativeListProperty<QQuickTransform> *prop)
+{
+ QQuickItem *that = static_cast<QQuickItem *>(prop->object);
+ return QQuickItemPrivate::get(that)->transforms.count();
+}
+
+void QQuickTransform::appendToItem(QQuickItem *item)
+{
+ Q_D(QQuickTransform);
+ if (!item)
+ return;
+
+ QQuickItemPrivate *p = QQuickItemPrivate::get(item);
+
+ if (!d->items.isEmpty() && !p->transforms.isEmpty() && p->transforms.contains(this)) {
+ p->transforms.removeOne(this);
+ p->transforms.append(this);
+ } else {
+ p->transforms.append(this);
+ d->items.append(item);
+ }
+
+ p->dirty(QQuickItemPrivate::Transform);
+}
+
+void QQuickTransform::prependToItem(QQuickItem *item)
+{
+ Q_D(QQuickTransform);
+ if (!item)
+ return;
+
+ QQuickItemPrivate *p = QQuickItemPrivate::get(item);
+
+ if (!d->items.isEmpty() && !p->transforms.isEmpty() && p->transforms.contains(this)) {
+ p->transforms.removeOne(this);
+ p->transforms.prepend(this);
+ } else {
+ p->transforms.prepend(this);
+ d->items.append(item);
+ }
+
+ p->dirty(QQuickItemPrivate::Transform);
+}
+
+void QQuickItemPrivate::transform_append(QDeclarativeListProperty<QQuickTransform> *prop, QQuickTransform *transform)
+{
+ if (!transform)
+ return;
+
+ QQuickItem *that = static_cast<QQuickItem *>(prop->object);
+ transform->appendToItem(that);
+}
+
+QQuickTransform *QQuickItemPrivate::transform_at(QDeclarativeListProperty<QQuickTransform> *prop, int idx)
+{
+ QQuickItem *that = static_cast<QQuickItem *>(prop->object);
+ QQuickItemPrivate *p = QQuickItemPrivate::get(that);
+
+ if (idx < 0 || idx >= p->transforms.count())
+ return 0;
+ else
+ return p->transforms.at(idx);
+}
+
+void QQuickItemPrivate::transform_clear(QDeclarativeListProperty<QQuickTransform> *prop)
+{
+ QQuickItem *that = static_cast<QQuickItem *>(prop->object);
+ QQuickItemPrivate *p = QQuickItemPrivate::get(that);
+
+ for (int ii = 0; ii < p->transforms.count(); ++ii) {
+ QQuickTransform *t = p->transforms.at(ii);
+ QQuickTransformPrivate *tp = QQuickTransformPrivate::get(t);
+ tp->items.removeOne(that);
+ }
+
+ p->transforms.clear();
+
+ p->dirty(QQuickItemPrivate::Transform);
+}
+
+/*!
+ \property QQuickItem::childrenRect
+ \brief The geometry of an item's children.
+
+ This property holds the (collective) position and size of the item's children.
+*/
+
+/*!
+ \qmlproperty real QtQuick2::Item::x
+ \qmlproperty real QtQuick2::Item::y
+ \qmlproperty real QtQuick2::Item::width
+ \qmlproperty real QtQuick2::Item::height
+
+ Defines the item's position and size relative to its parent.
+
+ \qml
+ Item { x: 100; y: 100; width: 100; height: 100 }
+ \endqml
+ */
+
+/*!
+ \qmlproperty real QtQuick2::Item::z
+
+ Sets the stacking order of sibling items. By default the stacking order is 0.
+
+ Items with a higher stacking value are drawn on top of siblings with a
+ lower stacking order. Items with the same stacking value are drawn
+ bottom up in the order they appear. Items with a negative stacking
+ value are drawn under their parent's content.
+
+ The following example shows the various effects of stacking order.
+
+ \table
+ \row
+ \o \image declarative-item_stacking1.png
+ \o Same \c z - later children above earlier children:
+ \qml
+ Item {
+ Rectangle {
+ color: "red"
+ width: 100; height: 100
+ }
+ Rectangle {
+ color: "blue"
+ x: 50; y: 50; width: 100; height: 100
+ }
+ }
+ \endqml
+ \row
+ \o \image declarative-item_stacking2.png
+ \o Higher \c z on top:
+ \qml
+ Item {
+ Rectangle {
+ z: 1
+ color: "red"
+ width: 100; height: 100
+ }
+ Rectangle {
+ color: "blue"
+ x: 50; y: 50; width: 100; height: 100
+ }
+ }
+ \endqml
+ \row
+ \o \image declarative-item_stacking3.png
+ \o Same \c z - children above parents:
+ \qml
+ Item {
+ Rectangle {
+ color: "red"
+ width: 100; height: 100
+ Rectangle {
+ color: "blue"
+ x: 50; y: 50; width: 100; height: 100
+ }
+ }
+ }
+ \endqml
+ \row
+ \o \image declarative-item_stacking4.png
+ \o Lower \c z below:
+ \qml
+ Item {
+ Rectangle {
+ color: "red"
+ width: 100; height: 100
+ Rectangle {
+ z: -1
+ color: "blue"
+ x: 50; y: 50; width: 100; height: 100
+ }
+ }
+ }
+ \endqml
+ \endtable
+ */
+
+/*!
+ \qmlproperty bool QtQuick2::Item::visible
+
+ This property holds whether the item is visible. By default this is true.
+
+ Setting this property directly affects the \c visible value of child
+ items. When set to \c false, the \c visible values of all child items also
+ become \c false. When set to \c true, the \c visible values of child items
+ are returned to \c true, unless they have explicitly been set to \c false.
+
+ (Because of this flow-on behavior, using the \c visible property may not
+ have the intended effect if a property binding should only respond to
+ explicit property changes. In such cases it may be better to use the
+ \l opacity property instead.)
+
+ Setting this property to \c false automatically causes \l focus to be set
+ to \c false, and this item will longer receive mouse and keyboard events.
+ (In contrast, setting the \l opacity to 0 does not affect the \l focus
+ property and the receiving of key events.)
+
+ \note This property's value is only affected by changes to this property or
+ the parent's \c visible property. It does not change, for example, if this
+ item moves off-screen, or if the \l opacity changes to 0.
+*/
+
+
+/*!
+ \qmlproperty AnchorLine QtQuick2::Item::anchors.top
+ \qmlproperty AnchorLine QtQuick2::Item::anchors.bottom
+ \qmlproperty AnchorLine QtQuick2::Item::anchors.left
+ \qmlproperty AnchorLine QtQuick2::Item::anchors.right
+ \qmlproperty AnchorLine QtQuick2::Item::anchors.horizontalCenter
+ \qmlproperty AnchorLine QtQuick2::Item::anchors.verticalCenter
+ \qmlproperty AnchorLine QtQuick2::Item::anchors.baseline
+
+ \qmlproperty Item QtQuick2::Item::anchors.fill
+ \qmlproperty Item QtQuick2::Item::anchors.centerIn
+
+ \qmlproperty real QtQuick2::Item::anchors.margins
+ \qmlproperty real QtQuick2::Item::anchors.topMargin
+ \qmlproperty real QtQuick2::Item::anchors.bottomMargin
+ \qmlproperty real QtQuick2::Item::anchors.leftMargin
+ \qmlproperty real QtQuick2::Item::anchors.rightMargin
+ \qmlproperty real QtQuick2::Item::anchors.horizontalCenterOffset
+ \qmlproperty real QtQuick2::Item::anchors.verticalCenterOffset
+ \qmlproperty real QtQuick2::Item::anchors.baselineOffset
+
+ \qmlproperty bool QtQuick2::Item::anchors.mirrored
+
+ Anchors provide a way to position an item by specifying its
+ relationship with other items.
+
+ Margins apply to top, bottom, left, right, and fill anchors.
+ The \c anchors.margins property can be used to set all of the various margins at once, to the same value.
+ Note that margins are anchor-specific and are not applied if an item does not
+ use anchors.
+
+ Offsets apply for horizontal center, vertical center, and baseline anchors.
+
+ \table
+ \row
+ \o \image declarative-anchors_example.png
+ \o Text anchored to Image, horizontally centered and vertically below, with a margin.
+ \qml
+ Item {
+ Image {
+ id: pic
+ // ...
+ }
+ Text {
+ id: label
+ anchors.horizontalCenter: pic.horizontalCenter
+ anchors.top: pic.bottom
+ anchors.topMargin: 5
+ // ...
+ }
+ }
+ \endqml
+ \row
+ \o \image declarative-anchors_example2.png
+ \o
+ Left of Text anchored to right of Image, with a margin. The y
+ property of both defaults to 0.
+
+ \qml
+ Item {
+ Image {
+ id: pic
+ // ...
+ }
+ Text {
+ id: label
+ anchors.left: pic.right
+ anchors.leftMargin: 5
+ // ...
+ }
+ }
+ \endqml
+ \endtable
+
+ \c anchors.fill provides a convenient way for one item to have the
+ same geometry as another item, and is equivalent to connecting all
+ four directional anchors.
+
+ To clear an anchor value, set it to \c undefined.
+
+ \c anchors.mirrored returns true it the layout has been \l {LayoutMirroring}{mirrored}.
+
+ \note You can only anchor an item to siblings or a parent.
+
+ For more information see \l {anchor-layout}{Anchor Layouts}.
+*/
+
+/*!
+ \property QQuickItem::baselineOffset
+ \brief The position of the item's baseline in local coordinates.
+
+ The baseline of a \l Text item is the imaginary line on which the text
+ sits. Controls containing text usually set their baseline to the
+ baseline of their text.
+
+ For non-text items, a default baseline offset of 0 is used.
+*/
+QQuickAnchors *QQuickItemPrivate::anchors() const
+{
+ if (!_anchors) {
+ Q_Q(const QQuickItem);
+ _anchors = new QQuickAnchors(const_cast<QQuickItem *>(q));
+ if (!componentComplete)
+ _anchors->classBegin();
+ }
+ return _anchors;
+}
+
+QQuickItemPrivate::AnchorLines *QQuickItemPrivate::anchorLines() const
+{
+ Q_Q(const QQuickItem);
+ if (!_anchorLines) _anchorLines =
+ new AnchorLines(const_cast<QQuickItem *>(q));
+ return _anchorLines;
+}
+
+void QQuickItemPrivate::siblingOrderChanged()
+{
+ Q_Q(QQuickItem);
+ for (int ii = 0; ii < changeListeners.count(); ++ii) {
+ const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
+ if (change.types & QQuickItemPrivate::SiblingOrder) {
+ change.listener->itemSiblingOrderChanged(q);
+ }
+ }
+}
+
+QDeclarativeListProperty<QObject> QQuickItemPrivate::data()
+{
+ return QDeclarativeListProperty<QObject>(q_func(), 0, QQuickItemPrivate::data_append,
+ QQuickItemPrivate::data_count,
+ QQuickItemPrivate::data_at,
+ QQuickItemPrivate::data_clear);
+}
+
+QRectF QQuickItem::childrenRect()
+{
+ Q_D(QQuickItem);
+ if (!d->_contents) {
+ d->_contents = new QQuickContents(this);
+ if (d->componentComplete)
+ d->_contents->complete();
+ }
+ return d->_contents->rectF();
+}
+
+QList<QQuickItem *> QQuickItem::childItems() const
+{
+ Q_D(const QQuickItem);
+ return d->childItems;
+}
+
+bool QQuickItem::clip() const
+{
+ return flags() & ItemClipsChildrenToShape;
+}
+
+void QQuickItem::setClip(bool c)
+{
+ if (clip() == c)
+ return;
+
+ setFlag(ItemClipsChildrenToShape, c);
+
+ emit clipChanged(c);
+}
+
+
+/*!
+ This function is called to handle this item's changes in
+ geometry from \a oldGeometry to \a newGeometry. If the two
+ geometries are the same, it doesn't do anything.
+ */
+void QQuickItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
+{
+ Q_D(QQuickItem);
+
+ if (d->_anchors)
+ QQuickAnchorsPrivate::get(d->_anchors)->updateMe();
+
+ for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
+ const QQuickItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
+ if (change.types & QQuickItemPrivate::Geometry)
+ change.listener->itemGeometryChanged(this, newGeometry, oldGeometry);
+ }
+
+ if (newGeometry.x() != oldGeometry.x())
+ emit xChanged();
+ if (newGeometry.y() != oldGeometry.y())
+ emit yChanged();
+ if (newGeometry.width() != oldGeometry.width())
+ emit widthChanged();
+ if (newGeometry.height() != oldGeometry.height())
+ emit heightChanged();
+}
+
+/*!
+ Called by the rendering thread when it is time to sync the state of the QML objects with the
+ scene graph objects. The function should return the root of the scene graph subtree for
+ this item. \a oldNode is the node that was returned the last time the function was called.
+
+ The main thread is blocked while this function is executed so it is safe to read
+ values from the QQuickItem instance and other objects in the main thread.
+
+ \warning This is the only function in which it is allowed to make use of scene graph
+ objects from the main thread. Use of scene graph objects outside this function will
+ result in race conditions and potential crashes.
+ */
+
+QSGNode *QQuickItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
+{
+ delete oldNode;
+ return 0;
+}
+
+QSGTransformNode *QQuickItemPrivate::createTransformNode()
+{
+ return new QSGTransformNode;
+}
+
+void QQuickItem::updatePolish()
+{
+}
+
+void QQuickItemPrivate::removeItemChangeListener(QQuickItemChangeListener *listener, ChangeTypes types)
+{
+ ChangeListener change(listener, types);
+ changeListeners.removeOne(change);
+}
+
+void QQuickItem::keyPressEvent(QKeyEvent *event)
+{
+ event->ignore();
+}
+
+void QQuickItem::keyReleaseEvent(QKeyEvent *event)
+{
+ event->ignore();
+}
+
+void QQuickItem::inputMethodEvent(QInputMethodEvent *event)
+{
+ event->ignore();
+}
+
+void QQuickItem::focusInEvent(QFocusEvent *)
+{
+}
+
+void QQuickItem::focusOutEvent(QFocusEvent *)
+{
+}
+
+void QQuickItem::mousePressEvent(QMouseEvent *event)
+{
+ event->ignore();
+}
+
+void QQuickItem::mouseMoveEvent(QMouseEvent *event)
+{
+ event->ignore();
+}
+
+void QQuickItem::mouseReleaseEvent(QMouseEvent *event)
+{
+ event->ignore();
+}
+
+void QQuickItem::mouseDoubleClickEvent(QMouseEvent *event)
+{
+ mousePressEvent(event);
+}
+
+void QQuickItem::mouseUngrabEvent()
+{
+ // XXX todo
+}
+
+void QQuickItem::wheelEvent(QWheelEvent *event)
+{
+ event->ignore();
+}
+
+void QQuickItem::touchEvent(QTouchEvent *event)
+{
+ event->ignore();
+}
+
+void QQuickItem::hoverEnterEvent(QHoverEvent *event)
+{
+ Q_UNUSED(event);
+}
+
+void QQuickItem::hoverMoveEvent(QHoverEvent *event)
+{
+ Q_UNUSED(event);
+}
+
+void QQuickItem::hoverLeaveEvent(QHoverEvent *event)
+{
+ Q_UNUSED(event);
+}
+
+void QQuickItem::dragEnterEvent(QDragEnterEvent *event)
+{
+ Q_UNUSED(event);
+}
+
+void QQuickItem::dragMoveEvent(QDragMoveEvent *event)
+{
+
+ Q_UNUSED(event);
+}
+
+void QQuickItem::dragLeaveEvent(QDragLeaveEvent *event)
+{
+
+ Q_UNUSED(event);
+}
+
+void QQuickItem::dropEvent(QDropEvent *event)
+{
+ Q_UNUSED(event);
+}
+
+bool QQuickItem::childMouseEventFilter(QQuickItem *, QEvent *)
+{
+ return false;
+}
+
+void QQuickItem::windowDeactivateEvent()
+{
+ foreach (QQuickItem* item, childItems()) {
+ item->windowDeactivateEvent();
+ }
+}
+
+Qt::InputMethodHints QQuickItem::inputMethodHints() const
+{
+ Q_D(const QQuickItem);
+ return d->imHints;
+}
+
+void QQuickItem::setInputMethodHints(Qt::InputMethodHints hints)
+{
+ Q_D(QQuickItem);
+ d->imHints = hints;
+
+ if (!d->canvas || d->canvas->activeFocusItem() != this)
+ return;
+
+ QInputPanel *p = qApp->inputPanel();
+ if (p->inputItem() == this)
+ qApp->inputPanel()->update(Qt::ImHints);
+}
+
+void QQuickItem::updateMicroFocus()
+{
+ QInputPanel *p = qApp->inputPanel();
+ if (p->inputItem() == this)
+ qApp->inputPanel()->update(Qt::ImQueryInput);
+}
+
+QVariant QQuickItem::inputMethodQuery(Qt::InputMethodQuery query) const
+{
+ Q_D(const QQuickItem);
+ QVariant v;
+
+ switch (query) {
+ case Qt::ImEnabled:
+ v = (bool)(flags() & ItemAcceptsInputMethod);
+ break;
+ case Qt::ImHints:
+ v = (int)inputMethodHints();
+ break;
+ case Qt::ImCursorRectangle:
+ case Qt::ImFont:
+ case Qt::ImCursorPosition:
+ case Qt::ImSurroundingText:
+ case Qt::ImCurrentSelection:
+ case Qt::ImMaximumTextLength:
+ case Qt::ImAnchorPosition:
+ case Qt::ImPreferredLanguage:
+ if (d->keyHandler)
+ v = d->keyHandler->inputMethodQuery(query);
+ default:
+ break;
+ }
+
+ return v;
+}
+
+QQuickAnchorLine QQuickItemPrivate::left() const
+{
+ return anchorLines()->left;
+}
+
+QQuickAnchorLine QQuickItemPrivate::right() const
+{
+ return anchorLines()->right;
+}
+
+QQuickAnchorLine QQuickItemPrivate::horizontalCenter() const
+{
+ return anchorLines()->hCenter;
+}
+
+QQuickAnchorLine QQuickItemPrivate::top() const
+{
+ return anchorLines()->top;
+}
+
+QQuickAnchorLine QQuickItemPrivate::bottom() const
+{
+ return anchorLines()->bottom;
+}
+
+QQuickAnchorLine QQuickItemPrivate::verticalCenter() const
+{
+ return anchorLines()->vCenter;
+}
+
+QQuickAnchorLine QQuickItemPrivate::baseline() const
+{
+ return anchorLines()->baseline;
+}
+
+qreal QQuickItem::baselineOffset() const
+{
+ Q_D(const QQuickItem);
+ if (!d->baselineOffset.isValid()) {
+ return 0.0;
+ } else
+ return d->baselineOffset;
+}
+
+void QQuickItem::setBaselineOffset(qreal offset)
+{
+ Q_D(QQuickItem);
+ if (offset == d->baselineOffset)
+ return;
+
+ d->baselineOffset = offset;
+
+ for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
+ const QQuickItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
+ if (change.types & QQuickItemPrivate::Geometry) {
+ QQuickAnchorsPrivate *anchor = change.listener->anchorPrivate();
+ if (anchor)
+ anchor->updateVerticalAnchors();
+ }
+ }
+ emit baselineOffsetChanged(offset);
+}
+
+void QQuickItem::update()
+{
+ Q_D(QQuickItem);
+ Q_ASSERT(flags() & ItemHasContents);
+ d->dirty(QQuickItemPrivate::Content);
+}
+
+void QQuickItem::polish()
+{
+ Q_D(QQuickItem);
+ if (!d->polishScheduled) {
+ d->polishScheduled = true;
+ if (d->canvas) {
+ QQuickCanvasPrivate *p = QQuickCanvasPrivate::get(d->canvas);
+ bool maybeupdate = p->itemsToPolish.isEmpty();
+ p->itemsToPolish.insert(this);
+ if (maybeupdate) d->canvas->maybeUpdate();
+ }
+ }
+}
+
+void QQuickItem::mapFromItem(QDeclarativeV8Function *args) const
+{
+ if (args->Length() != 0) {
+ v8::Local<v8::Value> item = (*args)[0];
+ QV8Engine *engine = args->engine();
+
+ QQuickItem *itemObj = 0;
+ if (!item->IsNull())
+ itemObj = qobject_cast<QQuickItem*>(engine->toQObject(item));
+
+ if (!itemObj && !item->IsNull()) {
+ qmlInfo(this) << "mapFromItem() given argument \"" << engine->toString(item->ToString())
+ << "\" which is neither null nor an Item";
+ return;
+ }
+
+ v8::Local<v8::Object> rv = v8::Object::New();
+ args->returnValue(rv);
+
+ qreal x = (args->Length() > 1)?(*args)[1]->NumberValue():0;
+ qreal y = (args->Length() > 2)?(*args)[2]->NumberValue():0;
+
+ QPointF p = mapFromItem(itemObj, QPointF(x, y));
+
+ rv->Set(v8::String::New("x"), v8::Number::New(p.x()));
+ rv->Set(v8::String::New("y"), v8::Number::New(p.y()));
+ }
+}
+
+QTransform QQuickItem::itemTransform(QQuickItem *other, bool *ok) const
+{
+ Q_D(const QQuickItem);
+
+ // XXX todo - we need to be able to handle common parents better and detect
+ // invalid cases
+ if (ok) *ok = true;
+
+ QTransform t = d->itemToCanvasTransform();
+ if (other) t *= QQuickItemPrivate::get(other)->canvasToItemTransform();
+
+ return t;
+}
+
+void QQuickItem::mapToItem(QDeclarativeV8Function *args) const
+{
+ if (args->Length() != 0) {
+ v8::Local<v8::Value> item = (*args)[0];
+ QV8Engine *engine = args->engine();
+
+ QQuickItem *itemObj = 0;
+ if (!item->IsNull())
+ itemObj = qobject_cast<QQuickItem*>(engine->toQObject(item));
+
+ if (!itemObj && !item->IsNull()) {
+ qmlInfo(this) << "mapToItem() given argument \"" << engine->toString(item->ToString())
+ << "\" which is neither null nor an Item";
+ return;
+ }
+
+ v8::Local<v8::Object> rv = v8::Object::New();
+ args->returnValue(rv);
+
+ qreal x = (args->Length() > 1)?(*args)[1]->NumberValue():0;
+ qreal y = (args->Length() > 2)?(*args)[2]->NumberValue():0;
+
+ QPointF p = mapToItem(itemObj, QPointF(x, y));
+
+ rv->Set(v8::String::New("x"), v8::Number::New(p.x()));
+ rv->Set(v8::String::New("y"), v8::Number::New(p.y()));
+ }
+}
+
+void QQuickItem::forceActiveFocus()
+{
+ setFocus(true);
+ QQuickItem *parent = parentItem();
+ while (parent) {
+ if (parent->flags() & QQuickItem::ItemIsFocusScope) {
+ parent->setFocus(true);
+ }
+ parent = parent->parentItem();
+ }
+}
+
+QQuickItem *QQuickItem::childAt(qreal x, qreal y) const
+{
+ // XXX todo - should this include transform etc.?
+ const QList<QQuickItem *> children = childItems();
+ for (int i = children.count()-1; i >= 0; --i) {
+ QQuickItem *child = children.at(i);
+ if (child->isVisible() && child->x() <= x
+ && child->x() + child->width() >= x
+ && child->y() <= y
+ && child->y() + child->height() >= y)
+ return child;
+ }
+ return 0;
+}
+
+QDeclarativeListProperty<QObject> QQuickItemPrivate::resources()
+{
+ return QDeclarativeListProperty<QObject>(q_func(), 0, QQuickItemPrivate::resources_append,
+ QQuickItemPrivate::resources_count,
+ QQuickItemPrivate::resources_at,
+ QQuickItemPrivate::resources_clear);
+}
+
+QDeclarativeListProperty<QQuickItem> QQuickItemPrivate::children()
+{
+ return QDeclarativeListProperty<QQuickItem>(q_func(), 0, QQuickItemPrivate::children_append,
+ QQuickItemPrivate::children_count,
+ QQuickItemPrivate::children_at,
+ QQuickItemPrivate::children_clear);
+
+}
+
+QDeclarativeListProperty<QDeclarativeState> QQuickItemPrivate::states()
+{
+ return _states()->statesProperty();
+}
+
+QDeclarativeListProperty<QDeclarativeTransition> QQuickItemPrivate::transitions()
+{
+ return _states()->transitionsProperty();
+}
+
+QString QQuickItemPrivate::state() const
+{
+ if (!_stateGroup)
+ return QString();
+ else
+ return _stateGroup->state();
+}
+
+void QQuickItemPrivate::setState(const QString &state)
+{
+ _states()->setState(state);
+}
+
+QString QQuickItem::state() const
+{
+ Q_D(const QQuickItem);
+ return d->state();
+}
+
+void QQuickItem::setState(const QString &state)
+{
+ Q_D(QQuickItem);
+ d->setState(state);
+}
+
+QDeclarativeListProperty<QQuickTransform> QQuickItem::transform()
+{
+ Q_D(QQuickItem);
+ return QDeclarativeListProperty<QQuickTransform>(this, 0, d->transform_append, d->transform_count,
+ d->transform_at, d->transform_clear);
+}
+
+void QQuickItem::classBegin()
+{
+ Q_D(QQuickItem);
+ d->componentComplete = false;
+ if (d->_stateGroup)
+ d->_stateGroup->classBegin();
+ if (d->_anchors)
+ d->_anchors->classBegin();
+}
+
+void QQuickItem::componentComplete()
+{
+ Q_D(QQuickItem);
+ d->componentComplete = true;
+ if (d->_stateGroup)
+ d->_stateGroup->componentComplete();
+ if (d->_anchors) {
+ d->_anchors->componentComplete();
+ QQuickAnchorsPrivate::get(d->_anchors)->updateOnComplete();
+ }
+ if (d->keyHandler)
+ d->keyHandler->componentComplete();
+ if (d->_contents)
+ d->_contents->complete();
+}
+
+QDeclarativeStateGroup *QQuickItemPrivate::_states()
+{
+ Q_Q(QQuickItem);
+ if (!_stateGroup) {
+ _stateGroup = new QDeclarativeStateGroup;
+ if (!componentComplete)
+ _stateGroup->classBegin();
+ FAST_CONNECT(_stateGroup, SIGNAL(stateChanged(QString)),
+ q, SIGNAL(stateChanged(QString)))
+ }
+
+ return _stateGroup;
+}
+
+QQuickItemPrivate::AnchorLines::AnchorLines(QQuickItem *q)
+{
+ left.item = q;
+ left.anchorLine = QQuickAnchorLine::Left;
+ right.item = q;
+ right.anchorLine = QQuickAnchorLine::Right;
+ hCenter.item = q;
+ hCenter.anchorLine = QQuickAnchorLine::HCenter;
+ top.item = q;
+ top.anchorLine = QQuickAnchorLine::Top;
+ bottom.item = q;
+ bottom.anchorLine = QQuickAnchorLine::Bottom;
+ vCenter.item = q;
+ vCenter.anchorLine = QQuickAnchorLine::VCenter;
+ baseline.item = q;
+ baseline.anchorLine = QQuickAnchorLine::Baseline;
+}
+
+QPointF QQuickItemPrivate::computeTransformOrigin() const
+{
+ switch (origin) {
+ default:
+ case QQuickItem::TopLeft:
+ return QPointF(0, 0);
+ case QQuickItem::Top:
+ return QPointF(width / 2., 0);
+ case QQuickItem::TopRight:
+ return QPointF(width, 0);
+ case QQuickItem::Left:
+ return QPointF(0, height / 2.);
+ case QQuickItem::Center:
+ return QPointF(width / 2., height / 2.);
+ case QQuickItem::Right:
+ return QPointF(width, height / 2.);
+ case QQuickItem::BottomLeft:
+ return QPointF(0, height);
+ case QQuickItem::Bottom:
+ return QPointF(width / 2., height);
+ case QQuickItem::BottomRight:
+ return QPointF(width, height);
+ }
+}
+
+void QQuickItemPrivate::transformChanged()
+{
+}
+
+void QQuickItemPrivate::deliverKeyEvent(QKeyEvent *e)
+{
+ Q_Q(QQuickItem);
+
+ Q_ASSERT(e->isAccepted());
+ if (keyHandler) {
+ if (e->type() == QEvent::KeyPress)
+ keyHandler->keyPressed(e, false);
+ else
+ keyHandler->keyReleased(e, false);
+
+ if (e->isAccepted())
+ return;
+ else
+ e->accept();
+ }
+
+ if (e->type() == QEvent::KeyPress)
+ q->keyPressEvent(e);
+ else
+ q->keyReleaseEvent(e);
+
+ if (e->isAccepted())
+ return;
+
+ if (keyHandler) {
+ e->accept();
+
+ if (e->type() == QEvent::KeyPress)
+ keyHandler->keyPressed(e, true);
+ else
+ keyHandler->keyReleased(e, true);
+ }
+}
+
+void QQuickItemPrivate::deliverInputMethodEvent(QInputMethodEvent *e)
+{
+ Q_Q(QQuickItem);
+
+ Q_ASSERT(e->isAccepted());
+ if (keyHandler) {
+ keyHandler->inputMethodEvent(e, false);
+
+ if (e->isAccepted())
+ return;
+ else
+ e->accept();
+ }
+
+ q->inputMethodEvent(e);
+
+ if (e->isAccepted())
+ return;
+
+ if (keyHandler) {
+ e->accept();
+
+ keyHandler->inputMethodEvent(e, true);
+ }
+}
+
+void QQuickItemPrivate::deliverFocusEvent(QFocusEvent *e)
+{
+ Q_Q(QQuickItem);
+
+ if (e->type() == QEvent::FocusIn) {
+ q->focusInEvent(e);
+ } else {
+ q->focusOutEvent(e);
+ }
+}
+
+void QQuickItemPrivate::deliverMouseEvent(QMouseEvent *e)
+{
+ Q_Q(QQuickItem);
+
+ Q_ASSERT(e->isAccepted());
+
+ switch (e->type()) {
+ default:
+ Q_ASSERT(!"Unknown event type");
+ case QEvent::MouseMove:
+ q->mouseMoveEvent(e);
+ break;
+ case QEvent::MouseButtonPress:
+ q->mousePressEvent(e);
+ break;
+ case QEvent::MouseButtonRelease:
+ q->mouseReleaseEvent(e);
+ break;
+ case QEvent::MouseButtonDblClick:
+ q->mouseDoubleClickEvent(e);
+ break;
+ }
+}
+
+void QQuickItemPrivate::deliverWheelEvent(QWheelEvent *e)
+{
+ Q_Q(QQuickItem);
+ q->wheelEvent(e);
+}
+
+void QQuickItemPrivate::deliverTouchEvent(QTouchEvent *e)
+{
+ Q_Q(QQuickItem);
+ q->touchEvent(e);
+}
+
+void QQuickItemPrivate::deliverHoverEvent(QHoverEvent *e)
+{
+ Q_Q(QQuickItem);
+ switch (e->type()) {
+ default:
+ Q_ASSERT(!"Unknown event type");
+ case QEvent::HoverEnter:
+ q->hoverEnterEvent(e);
+ break;
+ case QEvent::HoverLeave:
+ q->hoverLeaveEvent(e);
+ break;
+ case QEvent::HoverMove:
+ q->hoverMoveEvent(e);
+ break;
+ }
+}
+
+void QQuickItemPrivate::deliverDragEvent(QEvent *e)
+{
+ Q_Q(QQuickItem);
+ switch (e->type()) {
+ default:
+ Q_ASSERT(!"Unknown event type");
+ case QEvent::DragEnter:
+ q->dragEnterEvent(static_cast<QDragEnterEvent *>(e));
+ break;
+ case QEvent::DragLeave:
+ q->dragLeaveEvent(static_cast<QDragLeaveEvent *>(e));
+ break;
+ case QEvent::DragMove:
+ q->dragMoveEvent(static_cast<QDragMoveEvent *>(e));
+ break;
+ case QEvent::Drop:
+ q->dropEvent(static_cast<QDropEvent *>(e));
+ break;
+ }
+}
+
+void QQuickItem::itemChange(ItemChange change, const ItemChangeData &value)
+{
+ Q_UNUSED(change);
+ Q_UNUSED(value);
+}
+
+/*! \internal */
+// XXX todo - do we want/need this anymore?
+// Note that it's now used for varying clip rect
+QRectF QQuickItem::boundingRect() const
+{
+ Q_D(const QQuickItem);
+ return QRectF(0, 0, d->width, d->height);
+}
+
+QQuickItem::TransformOrigin QQuickItem::transformOrigin() const
+{
+ Q_D(const QQuickItem);
+ return d->origin;
+}
+
+void QQuickItem::setTransformOrigin(TransformOrigin origin)
+{
+ Q_D(QQuickItem);
+ if (origin == d->origin)
+ return;
+
+ d->origin = origin;
+ d->dirty(QQuickItemPrivate::TransformOrigin);
+
+ emit transformOriginChanged(d->origin);
+}
+
+QPointF QQuickItem::transformOriginPoint() const
+{
+ Q_D(const QQuickItem);
+ if (!d->transformOriginPoint.isNull())
+ return d->transformOriginPoint;
+ return d->computeTransformOrigin();
+}
+
+void QQuickItem::setTransformOriginPoint(const QPointF &point)
+{
+ Q_D(QQuickItem);
+ if (d->transformOriginPoint == point)
+ return;
+
+ d->transformOriginPoint = point;
+ d->dirty(QQuickItemPrivate::TransformOrigin);
+}
+
+qreal QQuickItem::z() const
+{
+ Q_D(const QQuickItem);
+ return d->z;
+}
+
+void QQuickItem::setZ(qreal v)
+{
+ Q_D(QQuickItem);
+ if (d->z == v)
+ return;
+
+ d->z = v;
+
+ d->dirty(QQuickItemPrivate::ZValue);
+ if (d->parentItem)
+ QQuickItemPrivate::get(d->parentItem)->dirty(QQuickItemPrivate::ChildrenStackingChanged);
+
+ emit zChanged();
+}
+
+
+/*!
+ \qmlproperty real QtQuick2::Item::rotation
+ This property holds the rotation of the item in degrees clockwise.
+
+ This specifies how many degrees to rotate the item around its transformOrigin.
+ The default rotation is 0 degrees (i.e. not rotated at all).
+
+ \table
+ \row
+ \o \image declarative-rotation.png
+ \o
+ \qml
+ Rectangle {
+ color: "blue"
+ width: 100; height: 100
+ Rectangle {
+ color: "red"
+ x: 25; y: 25; width: 50; height: 50
+ rotation: 30
+ }
+ }
+ \endqml
+ \endtable
+
+ \sa transform, Rotation
+*/
+
+/*!
+ \qmlproperty real QtQuick2::Item::scale
+ This property holds the scale of the item.
+
+ A scale of less than 1 means the item will be displayed smaller than
+ normal, and a scale of greater than 1 means the item will be
+ displayed larger than normal. A negative scale means the item will
+ be mirrored.
+
+ By default, items are displayed at a scale of 1 (i.e. at their
+ normal size).
+
+ Scaling is from the item's transformOrigin.
+
+ \table
+ \row
+ \o \image declarative-scale.png
+ \o
+ \qml
+ Rectangle {
+ color: "blue"
+ width: 100; height: 100
+ Rectangle {
+ color: "green"
+ width: 25; height: 25
+ }
+ Rectangle {
+ color: "red"
+ x: 25; y: 25; width: 50; height: 50
+ scale: 1.4
+ }
+ }
+ \endqml
+ \endtable
+
+ \sa transform, Scale
+*/
+
+/*!
+ \qmlproperty real QtQuick2::Item::opacity
+
+ This property holds the opacity of the item. Opacity is specified as a
+ number between 0 (fully transparent) and 1 (fully opaque). The default is 1.
+
+ When this property is set, the specified opacity is also applied
+ individually to child items. In almost all cases this is what you want,
+ but in some cases it may produce undesired results. For example in the
+ second set of rectangles below, the red rectangle has specified an opacity
+ of 0.5, which affects the opacity of its blue child rectangle even though
+ the child has not specified an opacity.
+
+ \table
+ \row
+ \o \image declarative-item_opacity1.png
+ \o
+ \qml
+ Item {
+ Rectangle {
+ color: "red"
+ width: 100; height: 100
+ Rectangle {
+ color: "blue"
+ x: 50; y: 50; width: 100; height: 100
+ }
+ }
+ }
+ \endqml
+ \row
+ \o \image declarative-item_opacity2.png
+ \o
+ \qml
+ Item {
+ Rectangle {
+ opacity: 0.5
+ color: "red"
+ width: 100; height: 100
+ Rectangle {
+ color: "blue"
+ x: 50; y: 50; width: 100; height: 100
+ }
+ }
+ }
+ \endqml
+ \endtable
+
+ If an item's opacity is set to 0, the item will no longer receive mouse
+ events, but will continue to receive key events and will retain the keyboard
+ \l focus if it has been set. (In contrast, setting the \l visible property
+ to \c false stops both mouse and keyboard events, and also removes focus
+ from the item.)
+*/
+
+/*!
+ Returns a value indicating whether mouse input should
+ remain with this item exclusively.
+
+ \sa setKeepMouseGrab()
+ */
+
+qreal QQuickItem::rotation() const
+{
+ Q_D(const QQuickItem);
+ return d->rotation;
+}
+
+void QQuickItem::setRotation(qreal r)
+{
+ Q_D(QQuickItem);
+ if (d->rotation == r)
+ return;
+
+ d->rotation = r;
+
+ d->dirty(QQuickItemPrivate::BasicTransform);
+
+ d->itemChange(ItemRotationHasChanged, r);
+
+ emit rotationChanged();
+}
+
+qreal QQuickItem::scale() const
+{
+ Q_D(const QQuickItem);
+ return d->scale;
+}
+
+void QQuickItem::setScale(qreal s)
+{
+ Q_D(QQuickItem);
+ if (d->scale == s)
+ return;
+
+ d->scale = s;
+
+ d->dirty(QQuickItemPrivate::BasicTransform);
+
+ emit scaleChanged();
+}
+
+qreal QQuickItem::opacity() const
+{
+ Q_D(const QQuickItem);
+ return d->opacity;
+}
+
+void QQuickItem::setOpacity(qreal o)
+{
+ Q_D(QQuickItem);
+ if (d->opacity == o)
+ return;
+
+ d->opacity = o;
+
+ d->dirty(QQuickItemPrivate::OpacityValue);
+
+ d->itemChange(ItemOpacityHasChanged, o);
+
+ emit opacityChanged();
+}
+
+bool QQuickItem::isVisible() const
+{
+ Q_D(const QQuickItem);
+ return d->effectiveVisible;
+}
+
+void QQuickItem::setVisible(bool v)
+{
+ Q_D(QQuickItem);
+ if (v == d->explicitVisible)
+ return;
+
+ d->explicitVisible = v;
+
+ d->setEffectiveVisibleRecur(d->calcEffectiveVisible());
+}
+
+bool QQuickItem::isEnabled() const
+{
+ Q_D(const QQuickItem);
+ return d->effectiveEnable;
+}
+
+void QQuickItem::setEnabled(bool e)
+{
+ Q_D(QQuickItem);
+ if (e == d->explicitEnable)
+ return;
+
+ d->explicitEnable = e;
+
+ d->setEffectiveEnableRecur(d->calcEffectiveEnable());
+}
+
+bool QQuickItemPrivate::calcEffectiveVisible() const
+{
+ // XXX todo - Should the effective visible of an element with no parent just be the current
+ // effective visible? This would prevent pointless re-processing in the case of an element
+ // moving to/from a no-parent situation, but it is different from what graphics view does.
+ return explicitVisible && (!parentItem || QQuickItemPrivate::get(parentItem)->effectiveVisible);
+}
+
+void QQuickItemPrivate::setEffectiveVisibleRecur(bool newEffectiveVisible)
+{
+ Q_Q(QQuickItem);
+
+ if (newEffectiveVisible && !explicitVisible) {
+ // This item locally overrides visibility
+ return;
+ }
+
+ if (newEffectiveVisible == effectiveVisible) {
+ // No change necessary
+ return;
+ }
+
+ effectiveVisible = newEffectiveVisible;
+ dirty(Visible);
+ if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
+
+ if (canvas) {
+ QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(canvas);
+ if (canvasPriv->mouseGrabberItem == q)
+ q->ungrabMouse();
+ }
+
+ for (int ii = 0; ii < childItems.count(); ++ii)
+ QQuickItemPrivate::get(childItems.at(ii))->setEffectiveVisibleRecur(newEffectiveVisible);
+
+ for (int ii = 0; ii < changeListeners.count(); ++ii) {
+ const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
+ if (change.types & QQuickItemPrivate::Visibility)
+ change.listener->itemVisibilityChanged(q);
+ }
+
+ emit q->visibleChanged();
+}
+
+bool QQuickItemPrivate::calcEffectiveEnable() const
+{
+ // XXX todo - Should the effective enable of an element with no parent just be the current
+ // effective enable? This would prevent pointless re-processing in the case of an element
+ // moving to/from a no-parent situation, but it is different from what graphics view does.
+ return explicitEnable && (!parentItem || QQuickItemPrivate::get(parentItem)->effectiveEnable);
+}
+
+void QQuickItemPrivate::setEffectiveEnableRecur(bool newEffectiveEnable)
+{
+ Q_Q(QQuickItem);
+
+ // XXX todo - need to fixup focus
+
+ if (newEffectiveEnable && !explicitEnable) {
+ // This item locally overrides enable
+ return;
+ }
+
+ if (newEffectiveEnable == effectiveEnable) {
+ // No change necessary
+ return;
+ }
+
+ effectiveEnable = newEffectiveEnable;
+
+ if (canvas) {
+ QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(canvas);
+ if (canvasPriv->mouseGrabberItem == q)
+ q->ungrabMouse();
+ }
+
+ for (int ii = 0; ii < childItems.count(); ++ii)
+ QQuickItemPrivate::get(childItems.at(ii))->setEffectiveEnableRecur(newEffectiveEnable);
+
+ emit q->enabledChanged();
+}
+
+QString QQuickItemPrivate::dirtyToString() const
+{
+#define DIRTY_TO_STRING(value) if (dirtyAttributes & value) { \
+ if (!rv.isEmpty()) \
+ rv.append(QLatin1String("|")); \
+ rv.append(QLatin1String(#value)); \
+}
+
+// QString rv = QLatin1String("0x") + QString::number(dirtyAttributes, 16);
+ QString rv;
+
+ DIRTY_TO_STRING(TransformOrigin);
+ DIRTY_TO_STRING(Transform);
+ DIRTY_TO_STRING(BasicTransform);
+ DIRTY_TO_STRING(Position);
+ DIRTY_TO_STRING(Size);
+ DIRTY_TO_STRING(ZValue);
+ DIRTY_TO_STRING(Content);
+ DIRTY_TO_STRING(Smooth);
+ DIRTY_TO_STRING(OpacityValue);
+ DIRTY_TO_STRING(ChildrenChanged);
+ DIRTY_TO_STRING(ChildrenStackingChanged);
+ DIRTY_TO_STRING(ParentChanged);
+ DIRTY_TO_STRING(Clip);
+ DIRTY_TO_STRING(Canvas);
+ DIRTY_TO_STRING(EffectReference);
+ DIRTY_TO_STRING(Visible);
+ DIRTY_TO_STRING(HideReference);
+
+ return rv;
+}
+
+void QQuickItemPrivate::dirty(DirtyType type)
+{
+ Q_Q(QQuickItem);
+ if (type & (TransformOrigin | Transform | BasicTransform | Position | Size))
+ transformChanged();
+
+ if (!(dirtyAttributes & type) || (canvas && !prevDirtyItem)) {
+ dirtyAttributes |= type;
+ if (canvas) {
+ addToDirtyList();
+ QQuickCanvasPrivate::get(canvas)->dirtyItem(q);
+ }
+ }
+}
+
+void QQuickItemPrivate::addToDirtyList()
+{
+ Q_Q(QQuickItem);
+
+ Q_ASSERT(canvas);
+ if (!prevDirtyItem) {
+ Q_ASSERT(!nextDirtyItem);
+
+ QQuickCanvasPrivate *p = QQuickCanvasPrivate::get(canvas);
+ nextDirtyItem = p->dirtyItemList;
+ if (nextDirtyItem) QQuickItemPrivate::get(nextDirtyItem)->prevDirtyItem = &nextDirtyItem;
+ prevDirtyItem = &p->dirtyItemList;
+ p->dirtyItemList = q;
+ p->dirtyItem(q);
+ }
+ Q_ASSERT(prevDirtyItem);
+}
+
+void QQuickItemPrivate::removeFromDirtyList()
+{
+ if (prevDirtyItem) {
+ if (nextDirtyItem) QQuickItemPrivate::get(nextDirtyItem)->prevDirtyItem = prevDirtyItem;
+ *prevDirtyItem = nextDirtyItem;
+ prevDirtyItem = 0;
+ nextDirtyItem = 0;
+ }
+ Q_ASSERT(!prevDirtyItem);
+ Q_ASSERT(!nextDirtyItem);
+}
+
+void QQuickItemPrivate::refFromEffectItem(bool hide)
+{
+ ++effectRefCount;
+ if (1 == effectRefCount) {
+ dirty(EffectReference);
+ if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
+ }
+ if (hide) {
+ if (++hideRefCount == 1)
+ dirty(HideReference);
+ }
+}
+
+void QQuickItemPrivate::derefFromEffectItem(bool unhide)
+{
+ Q_ASSERT(effectRefCount);
+ --effectRefCount;
+ if (0 == effectRefCount) {
+ dirty(EffectReference);
+ if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
+ }
+ if (unhide) {
+ if (--hideRefCount == 0)
+ dirty(HideReference);
+ }
+}
+
+void QQuickItemPrivate::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data)
+{
+ Q_Q(QQuickItem);
+ switch (change) {
+ case QQuickItem::ItemChildAddedChange:
+ q->itemChange(change, data);
+ if (_contents && componentComplete)
+ _contents->childAdded(data.item);
+ for (int ii = 0; ii < changeListeners.count(); ++ii) {
+ const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
+ if (change.types & QQuickItemPrivate::Children) {
+ change.listener->itemChildAdded(q, data.item);
+ }
+ }
+ break;
+ case QQuickItem::ItemChildRemovedChange:
+ q->itemChange(change, data);
+ if (_contents && componentComplete)
+ _contents->childRemoved(data.item);
+ for (int ii = 0; ii < changeListeners.count(); ++ii) {
+ const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
+ if (change.types & QQuickItemPrivate::Children) {
+ change.listener->itemChildRemoved(q, data.item);
+ }
+ }
+ break;
+ case QQuickItem::ItemSceneChange:
+ q->itemChange(change, data);
+ break;
+ case QQuickItem::ItemVisibleHasChanged:
+ q->itemChange(change, data);
+ for (int ii = 0; ii < changeListeners.count(); ++ii) {
+ const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
+ if (change.types & QQuickItemPrivate::Visibility) {
+ change.listener->itemVisibilityChanged(q);
+ }
+ }
+ break;
+ case QQuickItem::ItemParentHasChanged:
+ q->itemChange(change, data);
+ for (int ii = 0; ii < changeListeners.count(); ++ii) {
+ const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
+ if (change.types & QQuickItemPrivate::Parent) {
+ change.listener->itemParentChanged(q, data.item);
+ }
+ }
+ break;
+ case QQuickItem::ItemOpacityHasChanged:
+ q->itemChange(change, data);
+ for (int ii = 0; ii < changeListeners.count(); ++ii) {
+ const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
+ if (change.types & QQuickItemPrivate::Opacity) {
+ change.listener->itemOpacityChanged(q);
+ }
+ }
+ break;
+ case QQuickItem::ItemActiveFocusHasChanged:
+ q->itemChange(change, data);
+ break;
+ case QQuickItem::ItemRotationHasChanged:
+ q->itemChange(change, data);
+ for (int ii = 0; ii < changeListeners.count(); ++ii) {
+ const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
+ if (change.types & QQuickItemPrivate::Rotation) {
+ change.listener->itemRotationChanged(q);
+ }
+ }
+ break;
+ }
+}
+
+/*!
+ \property QQuickItem::smooth
+ \brief whether the item is smoothly transformed.
+
+ This property is provided purely for the purpose of optimization. Turning
+ smooth transforms off is faster, but looks worse; turning smooth
+ transformations on is slower, but looks better.
+
+ By default smooth transformations are off.
+*/
+
+/*!
+ Returns true if the item should be drawn with antialiasing and
+ smooth pixmap filtering, false otherwise.
+
+ The default is false.
+
+ \sa setSmooth()
+*/
+bool QQuickItem::smooth() const
+{
+ Q_D(const QQuickItem);
+ return d->smooth;
+}
+
+/*!
+ Sets whether the item should be drawn with antialiasing and
+ smooth pixmap filtering to \a smooth.
+
+ \sa smooth()
+*/
+void QQuickItem::setSmooth(bool smooth)
+{
+ Q_D(QQuickItem);
+ if (d->smooth == smooth)
+ return;
+
+ d->smooth = smooth;
+ d->dirty(QQuickItemPrivate::Smooth);
+
+ emit smoothChanged(smooth);
+}
+
+QQuickItem::Flags QQuickItem::flags() const
+{
+ Q_D(const QQuickItem);
+ return (QQuickItem::Flags)d->flags;
+}
+
+void QQuickItem::setFlag(Flag flag, bool enabled)
+{
+ Q_D(QQuickItem);
+ if (enabled)
+ setFlags((Flags)(d->flags | (quint32)flag));
+ else
+ setFlags((Flags)(d->flags & ~(quint32)flag));
+}
+
+void QQuickItem::setFlags(Flags flags)
+{
+ Q_D(QQuickItem);
+
+ if ((flags & ItemIsFocusScope) != (d->flags & ItemIsFocusScope)) {
+ if (flags & ItemIsFocusScope && !d->childItems.isEmpty() && d->canvas) {
+ qWarning("QQuickItem: Cannot set FocusScope once item has children and is in a canvas.");
+ flags &= ~ItemIsFocusScope;
+ } else if (d->flags & ItemIsFocusScope) {
+ qWarning("QQuickItem: Cannot unset FocusScope flag.");
+ flags |= ItemIsFocusScope;
+ }
+ }
+
+ if ((flags & ItemClipsChildrenToShape ) != (d->flags & ItemClipsChildrenToShape))
+ d->dirty(QQuickItemPrivate::Clip);
+
+ d->flags = flags;
+}
+
+qreal QQuickItem::x() const
+{
+ Q_D(const QQuickItem);
+ return d->x;
+}
+
+qreal QQuickItem::y() const
+{
+ Q_D(const QQuickItem);
+ return d->y;
+}
+
+QPointF QQuickItem::pos() const
+{
+ Q_D(const QQuickItem);
+ return QPointF(d->x, d->y);
+}
+
+void QQuickItem::setX(qreal v)
+{
+ Q_D(QQuickItem);
+ if (d->x == v)
+ return;
+
+ qreal oldx = d->x;
+ d->x = v;
+
+ d->dirty(QQuickItemPrivate::Position);
+
+ geometryChanged(QRectF(x(), y(), width(), height()),
+ QRectF(oldx, y(), width(), height()));
+}
+
+void QQuickItem::setY(qreal v)
+{
+ Q_D(QQuickItem);
+ if (d->y == v)
+ return;
+
+ qreal oldy = d->y;
+ d->y = v;
+
+ d->dirty(QQuickItemPrivate::Position);
+
+ geometryChanged(QRectF(x(), y(), width(), height()),
+ QRectF(x(), oldy, width(), height()));
+}
+
+void QQuickItem::setPos(const QPointF &pos)
+{
+ Q_D(QQuickItem);
+ if (QPointF(d->x, d->y) == pos)
+ return;
+
+ qreal oldx = d->x;
+ qreal oldy = d->y;
+
+ d->x = pos.x();
+ d->y = pos.y();
+
+ d->dirty(QQuickItemPrivate::Position);
+
+ geometryChanged(QRectF(x(), y(), width(), height()),
+ QRectF(oldx, oldy, width(), height()));
+}
+
+qreal QQuickItem::width() const
+{
+ Q_D(const QQuickItem);
+ return d->width;
+}
+
+void QQuickItem::setWidth(qreal w)
+{
+ Q_D(QQuickItem);
+ if (qIsNaN(w))
+ return;
+
+ d->widthValid = true;
+ if (d->width == w)
+ return;
+
+ qreal oldWidth = d->width;
+ d->width = w;
+
+ d->dirty(QQuickItemPrivate::Size);
+
+ geometryChanged(QRectF(x(), y(), width(), height()),
+ QRectF(x(), y(), oldWidth, height()));
+}
+
+void QQuickItem::resetWidth()
+{
+ Q_D(QQuickItem);
+ d->widthValid = false;
+ setImplicitWidth(implicitWidth());
+}
+
+void QQuickItemPrivate::implicitWidthChanged()
+{
+ Q_Q(QQuickItem);
+ emit q->implicitWidthChanged();
+}
+
+qreal QQuickItemPrivate::getImplicitWidth() const
+{
+ return implicitWidth;
+}
+/*!
+ Returns the width of the item that is implied by other properties that determine the content.
+*/
+qreal QQuickItem::implicitWidth() const
+{
+ Q_D(const QQuickItem);
+ return d->getImplicitWidth();
+}
+
+/*!
+ \qmlproperty real QtQuick2::Item::implicitWidth
+ \qmlproperty real QtQuick2::Item::implicitHeight
+
+ Defines the natural width or height of the Item if no \l width or \l height is specified.
+
+ The default implicit size for most items is 0x0, however some elements have an inherent
+ implicit size which cannot be overridden, e.g. Image, Text.
+
+ Setting the implicit size is useful for defining components that have a preferred size
+ based on their content, for example:
+
+ \qml
+ // Label.qml
+ import QtQuick 1.1
+
+ Item {
+ property alias icon: image.source
+ property alias label: text.text
+ implicitWidth: text.implicitWidth + image.implicitWidth
+ implicitHeight: Math.max(text.implicitHeight, image.implicitHeight)
+ Image { id: image }
+ Text {
+ id: text
+ wrapMode: Text.Wrap
+ anchors.left: image.right; anchors.right: parent.right
+ anchors.verticalCenter: parent.verticalCenter
+ }
+ }
+ \endqml
+
+ \bold Note: using implicitWidth of Text or TextEdit and setting the width explicitly
+ incurs a performance penalty as the text must be laid out twice.
+*/
+
+/*!
+ Sets the implied width of the item to \a w.
+ This is the width implied by other properties that determine the content.
+*/
+void QQuickItem::setImplicitWidth(qreal w)
+{
+ Q_D(QQuickItem);
+ bool changed = w != d->implicitWidth;
+ d->implicitWidth = w;
+ if (d->width == w || widthValid()) {
+ if (changed)
+ d->implicitWidthChanged();
+ return;
+ }
+
+ qreal oldWidth = d->width;
+ d->width = w;
+
+ d->dirty(QQuickItemPrivate::Size);
+
+ geometryChanged(QRectF(x(), y(), width(), height()),
+ QRectF(x(), y(), oldWidth, height()));
+
+ if (changed)
+ d->implicitWidthChanged();
+}
+
+/*!
+ Returns whether the width property has been set explicitly.
+*/
+bool QQuickItem::widthValid() const
+{
+ Q_D(const QQuickItem);
+ return d->widthValid;
+}
+
+qreal QQuickItem::height() const
+{
+ Q_D(const QQuickItem);
+ return d->height;
+}
+
+void QQuickItem::setHeight(qreal h)
+{
+ Q_D(QQuickItem);
+ if (qIsNaN(h))
+ return;
+
+ d->heightValid = true;
+ if (d->height == h)
+ return;
+
+ qreal oldHeight = d->height;
+ d->height = h;
+
+ d->dirty(QQuickItemPrivate::Size);
+
+ geometryChanged(QRectF(x(), y(), width(), height()),
+ QRectF(x(), y(), width(), oldHeight));
+}
+
+void QQuickItem::resetHeight()
+{
+ Q_D(QQuickItem);
+ d->heightValid = false;
+ setImplicitHeight(implicitHeight());
+}
+
+void QQuickItemPrivate::implicitHeightChanged()
+{
+ Q_Q(QQuickItem);
+ emit q->implicitHeightChanged();
+}
+
+qreal QQuickItemPrivate::getImplicitHeight() const
+{
+ return implicitHeight;
+}
+
+/*!
+ Returns the height of the item that is implied by other properties that determine the content.
+*/
+qreal QQuickItem::implicitHeight() const
+{
+ Q_D(const QQuickItem);
+ return d->getImplicitHeight();
+}
+
+
+/*!
+ Sets the implied height of the item to \a h.
+ This is the height implied by other properties that determine the content.
+*/
+void QQuickItem::setImplicitHeight(qreal h)
+{
+ Q_D(QQuickItem);
+ bool changed = h != d->implicitHeight;
+ d->implicitHeight = h;
+ if (d->height == h || heightValid()) {
+ if (changed)
+ d->implicitHeightChanged();
+ return;
+ }
+
+ qreal oldHeight = d->height;
+ d->height = h;
+
+ d->dirty(QQuickItemPrivate::Size);
+
+ geometryChanged(QRectF(x(), y(), width(), height()),
+ QRectF(x(), y(), width(), oldHeight));
+
+ if (changed)
+ d->implicitHeightChanged();
+}
+
+/*!
+ Returns whether the height property has been set explicitly.
+*/
+bool QQuickItem::heightValid() const
+{
+ Q_D(const QQuickItem);
+ return d->heightValid;
+}
+
+void QQuickItem::setSize(const QSizeF &size)
+{
+ Q_D(QQuickItem);
+ d->heightValid = true;
+ d->widthValid = true;
+
+ if (QSizeF(d->width, d->height) == size)
+ return;
+
+ qreal oldHeight = d->height;
+ qreal oldWidth = d->width;
+ d->height = size.height();
+ d->width = size.width();
+
+ d->dirty(QQuickItemPrivate::Size);
+
+ geometryChanged(QRectF(x(), y(), width(), height()),
+ QRectF(x(), y(), oldWidth, oldHeight));
+}
+
+bool QQuickItem::hasActiveFocus() const
+{
+ Q_D(const QQuickItem);
+ return d->activeFocus;
+}
+
+bool QQuickItem::hasFocus() const
+{
+ Q_D(const QQuickItem);
+ return d->focus;
+}
+
+void QQuickItem::setFocus(bool focus)
+{
+ Q_D(QQuickItem);
+ if (d->focus == focus)
+ return;
+
+ if (d->canvas) {
+ // Need to find our nearest focus scope
+ QQuickItem *scope = parentItem();
+ while (scope && !scope->isFocusScope())
+ scope = scope->parentItem();
+ if (focus)
+ QQuickCanvasPrivate::get(d->canvas)->setFocusInScope(scope, this);
+ else
+ QQuickCanvasPrivate::get(d->canvas)->clearFocusInScope(scope, this);
+ } else {
+ d->focus = focus;
+ emit focusChanged(focus);
+ }
+}
+
+bool QQuickItem::isFocusScope() const
+{
+ return flags() & ItemIsFocusScope;
+}
+
+QQuickItem *QQuickItem::scopedFocusItem() const
+{
+ Q_D(const QQuickItem);
+ if (!isFocusScope())
+ return 0;
+ else
+ return d->subFocusItem;
+}
+
+
+Qt::MouseButtons QQuickItem::acceptedMouseButtons() const
+{
+ Q_D(const QQuickItem);
+ return d->acceptedMouseButtons;
+}
+
+void QQuickItem::setAcceptedMouseButtons(Qt::MouseButtons buttons)
+{
+ Q_D(QQuickItem);
+ d->acceptedMouseButtons = buttons;
+}
+
+bool QQuickItem::filtersChildMouseEvents() const
+{
+ Q_D(const QQuickItem);
+ return d->filtersChildMouseEvents;
+}
+
+void QQuickItem::setFiltersChildMouseEvents(bool filter)
+{
+ Q_D(QQuickItem);
+ d->filtersChildMouseEvents = filter;
+}
+
+bool QQuickItem::isUnderMouse() const
+{
+ Q_D(const QQuickItem);
+ if (!d->canvas)
+ return false;
+
+ QPoint cursorPos = QCursor::pos();
+ if (QRectF(0, 0, width(), height()).contains(mapFromScene(cursorPos))) // ### refactor: d->canvas->mapFromGlobal(cursorPos))))
+ return true;
+ return false;
+}
+
+bool QQuickItem::acceptHoverEvents() const
+{
+ Q_D(const QQuickItem);
+ return d->hoverEnabled;
+}
+
+void QQuickItem::setAcceptHoverEvents(bool enabled)
+{
+ Q_D(QQuickItem);
+ d->hoverEnabled = enabled;
+}
+
+void QQuickItem::grabMouse()
+{
+ Q_D(QQuickItem);
+ if (!d->canvas)
+ return;
+ QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
+ if (canvasPriv->mouseGrabberItem == this)
+ return;
+
+ QQuickItem *oldGrabber = canvasPriv->mouseGrabberItem;
+ canvasPriv->mouseGrabberItem = this;
+ if (oldGrabber)
+ oldGrabber->mouseUngrabEvent();
+}
+
+void QQuickItem::ungrabMouse()
+{
+ Q_D(QQuickItem);
+ if (!d->canvas)
+ return;
+ QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
+ if (canvasPriv->mouseGrabberItem != this) {
+ qWarning("QQuickItem::ungrabMouse(): Item is not the mouse grabber.");
+ return;
+ }
+
+ canvasPriv->mouseGrabberItem = 0;
+ mouseUngrabEvent();
+}
+
+bool QQuickItem::keepMouseGrab() const
+{
+ Q_D(const QQuickItem);
+ return d->keepMouse;
+}
+
+/*!
+ The flag indicating whether the mouse should remain
+ with this item is set to \a keep.
+
+ This is useful for items that wish to grab and keep mouse
+ interaction following a predefined gesture. For example,
+ an item that is interested in horizontal mouse movement
+ may set keepMouseGrab to true once a threshold has been
+ exceeded. Once keepMouseGrab has been set to true, filtering
+ items will not react to mouse events.
+
+ If the item does not indicate that it wishes to retain mouse grab,
+ a filtering item may steal the grab. For example, Flickable may attempt
+ to steal a mouse grab if it detects that the user has begun to
+ move the viewport.
+
+ \sa keepMouseGrab()
+ */
+void QQuickItem::setKeepMouseGrab(bool keep)
+{
+ Q_D(QQuickItem);
+ d->keepMouse = keep;
+}
+
+/*!
+ \qmlmethod object QtQuick2::Item::mapFromItem(Item item, real x, real y)
+
+ Maps the point (\a x, \a y), which is in \a item's coordinate system, to
+ this item's coordinate system, and returns an object with \c x and \c y
+ properties matching the mapped cooordinate.
+
+ If \a item is a \c null value, this maps the point from the coordinate
+ system of the root QML view.
+*/
+/*!
+ \qmlmethod object QtQuick2::Item::mapToItem(Item item, real x, real y)
+
+ Maps the point (\a x, \a y), which is in this item's coordinate system, to
+ \a item's coordinate system, and returns an object with \c x and \c y
+ properties matching the mapped cooordinate.
+
+ If \a item is a \c null value, this maps \a x and \a y to the coordinate
+ system of the root QML view.
+*/
+QPointF QQuickItem::mapToItem(const QQuickItem *item, const QPointF &point) const
+{
+ QPointF p = mapToScene(point);
+ if (item)
+ p = item->mapFromScene(p);
+ return p;
+}
+
+QPointF QQuickItem::mapToScene(const QPointF &point) const
+{
+ Q_D(const QQuickItem);
+ return d->itemToCanvasTransform().map(point);
+}
+
+QRectF QQuickItem::mapRectToItem(const QQuickItem *item, const QRectF &rect) const
+{
+ Q_D(const QQuickItem);
+ QTransform t = d->itemToCanvasTransform();
+ if (item)
+ t *= QQuickItemPrivate::get(item)->canvasToItemTransform();
+ return t.mapRect(rect);
+}
+
+QRectF QQuickItem::mapRectToScene(const QRectF &rect) const
+{
+ Q_D(const QQuickItem);
+ return d->itemToCanvasTransform().mapRect(rect);
+}
+
+QPointF QQuickItem::mapFromItem(const QQuickItem *item, const QPointF &point) const
+{
+ QPointF p = item?item->mapToScene(point):point;
+ return mapFromScene(p);
+}
+
+QPointF QQuickItem::mapFromScene(const QPointF &point) const
+{
+ Q_D(const QQuickItem);
+ return d->canvasToItemTransform().map(point);
+}
+
+QRectF QQuickItem::mapRectFromItem(const QQuickItem *item, const QRectF &rect) const
+{
+ Q_D(const QQuickItem);
+ QTransform t = item?QQuickItemPrivate::get(item)->itemToCanvasTransform():QTransform();
+ t *= d->canvasToItemTransform();
+ return t.mapRect(rect);
+}
+
+QRectF QQuickItem::mapRectFromScene(const QRectF &rect) const
+{
+ Q_D(const QQuickItem);
+ return d->canvasToItemTransform().mapRect(rect);
+}
+
+
+/*!
+ \qmlmethod QtQuick2::Item::forceActiveFocus()
+
+ Forces active focus on the item.
+
+ This method sets focus on the item and makes sure that all the focus scopes
+ higher in the object hierarchy are also given the focus.
+*/
+
+/*!
+ Forces active focus on the item.
+
+ This method sets focus on the item and makes sure that all the focus scopes
+ higher in the object hierarchy are also given the focus.
+*/
+
+/*!
+ \qmlmethod QtQuick2::Item::childAt(real x, real y)
+
+ Returns the visible child item at point (\a x, \a y), which is in this
+ item's coordinate system, or \c null if there is no such item.
+*/
+
+/*!
+ Returns the visible child item at point (\a x, \a y), which is in this
+ item's coordinate system, or 0 if there is no such item.
+*/
+
+/*!
+ \qmlproperty list<State> QtQuick2::Item::states
+ This property holds a list of states defined by the item.
+
+ \qml
+ Item {
+ states: [
+ State {
+ // ...
+ },
+ State {
+ // ...
+ }
+ // ...
+ ]
+ }
+ \endqml
+
+ \sa {qmlstate}{States}
+*/
+/*!
+ \qmlproperty list<Transition> QtQuick2::Item::transitions
+ This property holds a list of transitions defined by the item.
+
+ \qml
+ Item {
+ transitions: [
+ Transition {
+ // ...
+ },
+ Transition {
+ // ...
+ }
+ // ...
+ ]
+ }
+ \endqml
+
+ \sa {QML Animation and Transitions}{Transitions}
+*/
+/*
+ \qmlproperty list<Filter> QtQuick2::Item::filter
+ This property holds a list of graphical filters to be applied to the item.
+
+ \l {Filter}{Filters} include things like \l {Blur}{blurring}
+ the item, or giving it a \l Reflection. Some
+ filters may not be available on all canvases; if a filter is not
+ available on a certain canvas, it will simply not be applied for
+ that canvas (but the QML will still be considered valid).
+
+ \qml
+ Item {
+ filter: [
+ Blur {
+ // ...
+ },
+ Reflection {
+ // ...
+ }
+ // ...
+ ]
+ }
+ \endqml
+*/
+
+/*!
+ \qmlproperty bool QtQuick2::Item::clip
+ This property holds whether clipping is enabled. The default clip value is \c false.
+
+ If clipping is enabled, an item will clip its own painting, as well
+ as the painting of its children, to its bounding rectangle.
+
+ Non-rectangular clipping regions are not supported for performance reasons.
+*/
+
+/*!
+ \property QQuickItem::clip
+ This property holds whether clipping is enabled. The default clip value is \c false.
+
+ If clipping is enabled, an item will clip its own painting, as well
+ as the painting of its children, to its bounding rectangle. If you set
+ clipping during an item's paint operation, remember to re-set it to
+ prevent clipping the rest of your scene.
+
+ Non-rectangular clipping regions are not supported for performance reasons.
+*/
+
+/*!
+ \qmlproperty string QtQuick2::Item::state
+
+ This property holds the name of the current state of the item.
+
+ This property is often used in scripts to change between states. For
+ example:
+
+ \js
+ function toggle() {
+ if (button.state == 'On')
+ button.state = 'Off';
+ else
+ button.state = 'On';
+ }
+ \endjs
+
+ If the item is in its base state (i.e. no explicit state has been
+ set), \c state will be a blank string. Likewise, you can return an
+ item to its base state by setting its current state to \c ''.
+
+ \sa {qmlstates}{States}
+*/
+
+/*!
+ \qmlproperty list<Transform> QtQuick2::Item::transform
+ This property holds the list of transformations to apply.
+
+ For more information see \l Transform.
+*/
+
+/*!
+ \enum QQuickItem::TransformOrigin
+
+ Controls the point about which simple transforms like scale apply.
+
+ \value TopLeft The top-left corner of the item.
+ \value Top The center point of the top of the item.
+ \value TopRight The top-right corner of the item.
+ \value Left The left most point of the vertical middle.
+ \value Center The center of the item.
+ \value Right The right most point of the vertical middle.
+ \value BottomLeft The bottom-left corner of the item.
+ \value Bottom The center point of the bottom of the item.
+ \value BottomRight The bottom-right corner of the item.
+*/
+
+
+/*!
+ \qmlproperty bool QtQuick2::Item::activeFocus
+
+ This property indicates whether the item has active focus.
+
+ An item with active focus will receive keyboard input,
+ or is a FocusScope ancestor of the item that will receive keyboard input.
+
+ Usually, activeFocus is gained by setting focus on an item and its enclosing
+ FocusScopes. In the following example \c input will have activeFocus.
+ \qml
+ Rectangle {
+ FocusScope {
+ focus: true
+ TextInput {
+ id: input
+ focus: true
+ }
+ }
+ }
+ \endqml
+
+ \sa focus, {qmlfocus}{Keyboard Focus}
+*/
+
+/*!
+ \qmlproperty bool QtQuick2::Item::focus
+ This property indicates whether the item has focus within the enclosing focus scope. If true, this item
+ will gain active focus when the enclosing focus scope gains active focus.
+ In the following example, \c input will be given active focus when \c scope gains active focus.
+ \qml
+ Rectangle {
+ FocusScope {
+ id: scope
+ TextInput {
+ id: input
+ focus: true
+ }
+ }
+ }
+ \endqml
+
+ For the purposes of this property, the scene as a whole is assumed to act like a focus scope.
+ On a practical level, that means the following QML will give active focus to \c input on startup.
+
+ \qml
+ Rectangle {
+ TextInput {
+ id: input
+ focus: true
+ }
+ }
+ \endqml
+
+ \sa activeFocus, {qmlfocus}{Keyboard Focus}
+*/
+
+
+/*!
+ \property QQuickItem::anchors
+ \internal
+*/
+
+/*!
+ \property QQuickItem::left
+ \internal
+*/
+
+/*!
+ \property QQuickItem::right
+ \internal
+*/
+
+/*!
+ \property QQuickItem::horizontalCenter
+ \internal
+*/
+
+/*!
+ \property QQuickItem::top
+ \internal
+*/
+
+/*!
+ \property QQuickItem::bottom
+ \internal
+*/
+
+/*!
+ \property QQuickItem::verticalCenter
+ \internal
+*/
+
+/*!
+ \property QQuickItem::focus
+ \internal
+*/
+
+/*!
+ \property QQuickItem::transform
+ \internal
+*/
+
+/*!
+ \property QQuickItem::transformOrigin
+ \internal
+*/
+
+/*!
+ \property QQuickItem::activeFocus
+ \internal
+*/
+
+/*!
+ \property QQuickItem::baseline
+ \internal
+*/
+
+/*!
+ \property QQuickItem::data
+ \internal
+*/
+
+/*!
+ \property QQuickItem::resources
+ \internal
+*/
+
+/*!
+ \property QQuickItem::state
+ \internal
+*/
+
+/*!
+ \property QQuickItem::states
+ \internal
+*/
+
+/*!
+ \property QQuickItem::transformOriginPoint
+ \internal
+*/
+
+/*!
+ \property QQuickItem::transitions
+ \internal
+*/
+
+bool QQuickItem::event(QEvent *ev)
+{
+#if 0
+ if (ev->type() == QEvent::PolishRequest) {
+ Q_D(QQuickItem);
+ d->polishScheduled = false;
+ updatePolish();
+ return true;
+ } else {
+ return QObject::event(ev);
+ }
+#endif
+ if (ev->type() == QEvent::InputMethodQuery) {
+ QInputMethodQueryEvent *query = static_cast<QInputMethodQueryEvent *>(ev);
+ Qt::InputMethodQueries queries = query->queries();
+ for (uint i = 0; i < 32; ++i) {
+ Qt::InputMethodQuery q = (Qt::InputMethodQuery)(int)(queries & (1<<i));
+ if (q) {
+ QVariant v = inputMethodQuery(q);
+ query->setValue(q, v);
+ }
+ }
+ query->accept();
+ return true;
+ } else if (ev->type() == QEvent::InputMethod) {
+ inputMethodEvent(static_cast<QInputMethodEvent *>(ev));
+ return true;
+ }
+ return QObject::event(ev);
+}
+
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug debug, QQuickItem *item)
+{
+ if (!item) {
+ debug << "QQuickItem(0)";
+ return debug;
+ }
+
+ debug << item->metaObject()->className() << "(this =" << ((void*)item)
+ << ", name=" << item->objectName()
+ << ", parent =" << ((void*)item->parentItem())
+ << ", geometry =" << QRectF(item->pos(), QSizeF(item->width(), item->height()))
+ << ", z =" << item->z() << ')';
+ return debug;
+}
+#endif
+
+qint64 QQuickItemPrivate::consistentTime = -1;
+void QQuickItemPrivate::setConsistentTime(qint64 t)
+{
+ consistentTime = t;
+}
+
+class QElapsedTimerConsistentTimeHack
+{
+public:
+ void start() {
+ t1 = QQuickItemPrivate::consistentTime;
+ t2 = 0;
+ }
+ qint64 elapsed() {
+ return QQuickItemPrivate::consistentTime - t1;
+ }
+ qint64 restart() {
+ qint64 val = QQuickItemPrivate::consistentTime - t1;
+ t1 = QQuickItemPrivate::consistentTime;
+ t2 = 0;
+ return val;
+ }
+
+private:
+ qint64 t1;
+ qint64 t2;
+};
+
+void QQuickItemPrivate::start(QElapsedTimer &t)
+{
+ if (QQuickItemPrivate::consistentTime == -1)
+ t.start();
+ else
+ ((QElapsedTimerConsistentTimeHack*)&t)->start();
+}
+
+qint64 QQuickItemPrivate::elapsed(QElapsedTimer &t)
+{
+ if (QQuickItemPrivate::consistentTime == -1)
+ return t.elapsed();
+ else
+ return ((QElapsedTimerConsistentTimeHack*)&t)->elapsed();
+}
+
+qint64 QQuickItemPrivate::restart(QElapsedTimer &t)
+{
+ if (QQuickItemPrivate::consistentTime == -1)
+ return t.restart();
+ else
+ return ((QElapsedTimerConsistentTimeHack*)&t)->restart();
+}
+
+/*!
+ \fn bool QQuickItem::isTextureProvider() const
+
+ Returns true if this item is a texture provider. The default
+ implementation returns false.
+
+ This function can be called from any thread.
+ */
+
+/*!
+ \fn QSGTextureProvider *QQuickItem::textureProvider() const
+
+ Returns the texture provider for an item. The default implementation
+ returns 0.
+
+ This function may only be called on the rendering thread.
+ */
+
+QT_END_NAMESPACE
+
+#include <moc_qquickitem.cpp>