1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the QtDeclarative module of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #include "qquickitem.h"
44 #include "qquickcanvas.h"
45 #include <QtDeclarative/qjsengine.h>
46 #include "qquickcanvas_p.h"
48 #include "qquickevents_p_p.h"
49 #include "qquickscreen_p.h"
51 #include <QtDeclarative/qdeclarativeengine.h>
52 #include <QtDeclarative/qdeclarativecomponent.h>
53 #include <QtDeclarative/qdeclarativeinfo.h>
54 #include <QtGui/qpen.h>
55 #include <QtGui/qcursor.h>
56 #include <QtGui/qguiapplication.h>
57 #include <QtGui/qinputpanel.h>
58 #include <QtCore/qdebug.h>
59 #include <QtCore/qcoreevent.h>
60 #include <QtCore/qnumeric.h>
62 #include <private/qdeclarativeengine_p.h>
63 #include <QtQuick/private/qdeclarativestategroup_p.h>
64 #include <private/qdeclarativeopenmetaobject_p.h>
65 #include <QtQuick/private/qdeclarativestate_p.h>
66 #include <private/qlistmodelinterface_p.h>
67 #include <private/qquickitem_p.h>
68 #include <private/qdeclarativeaccessors_p.h>
69 #include <QtQuick/private/qquickaccessibleattached_p.h>
73 // XXX todo Check that elements that create items handle memory correctly after visual ownership change
77 static void QQuickItem_parentNotifier(QObject *o, intptr_t, QDeclarativeNotifier **n)
79 QQuickItemPrivate *d = QQuickItemPrivate::get(static_cast<QQuickItem *>(o));
80 *n = &d->parentNotifier;
83 QML_PRIVATE_ACCESSOR(QQuickItem, QQuickItem *, parent, parentItem)
84 QML_PRIVATE_ACCESSOR(QQuickItem, qreal, x, x)
85 QML_PRIVATE_ACCESSOR(QQuickItem, qreal, y, y)
86 QML_PRIVATE_ACCESSOR(QQuickItem, qreal, width, width)
87 QML_PRIVATE_ACCESSOR(QQuickItem, qreal, height, height)
89 static QDeclarativeAccessors QQuickItem_parent = { QQuickItem_parentRead, QQuickItem_parentNotifier };
90 static QDeclarativeAccessors QQuickItem_x = { QQuickItem_xRead, 0 };
91 static QDeclarativeAccessors QQuickItem_y = { QQuickItem_yRead, 0 };
92 static QDeclarativeAccessors QQuickItem_width = { QQuickItem_widthRead, 0 };
93 static QDeclarativeAccessors QQuickItem_height = { QQuickItem_heightRead, 0 };
95 QML_DECLARE_PROPERTIES(QQuickItem) {
96 { QML_PROPERTY_NAME(parent), 0, &QQuickItem_parent },
97 { QML_PROPERTY_NAME(x), 0, &QQuickItem_x },
98 { QML_PROPERTY_NAME(y), 0, &QQuickItem_y },
99 { QML_PROPERTY_NAME(width), 0, &QQuickItem_width },
100 { QML_PROPERTY_NAME(height), 0, &QQuickItem_height }
103 void QQuickItemPrivate::registerAccessorProperties()
105 QML_DEFINE_PROPERTIES(QQuickItem);
109 \qmlclass Transform QQuickTransform
110 \inqmlmodule QtQuick 2
111 \ingroup qml-transform-elements
112 \brief The Transform elements provide a way of building advanced transformations on Items.
114 The Transform element is a base type which cannot be instantiated directly.
115 The following concrete Transform types are available:
123 The Transform elements let you create and control advanced transformations that can be configured
124 independently using specialized properties.
126 You can assign any number of Transform elements to an \l Item. Each Transform is applied in order,
131 \qmlclass Translate QQuickTranslate
132 \inqmlmodule QtQuick 2
133 \ingroup qml-transform-elements
134 \brief The Translate object provides a way to move an Item without changing its x or y properties.
136 The Translate object provides independent control over position in addition to the Item's x and y properties.
138 The following example moves the Y axis of the \l Rectangle elements while still allowing the \l Row element
139 to lay the items out as if they had not been transformed:
145 width: 100; height: 100
147 transform: Translate { y: 20 }
150 width: 100; height: 100
152 transform: Translate { y: -20 }
161 \qmlproperty real QtQuick2::Translate::x
163 The translation along the X axis.
167 \qmlproperty real QtQuick2::Translate::y
169 The translation along the Y axis.
173 \qmlclass Scale QQuickScale
174 \inqmlmodule QtQuick 2
175 \ingroup qml-transform-elements
176 \brief The Scale element provides a way to scale an Item.
178 The Scale element gives more control over scaling than using \l Item's \l{Item::scale}{scale} property. Specifically,
179 it allows a different scale for the x and y axes, and allows the scale to be relative to an
182 The following example scales the X axis of the Rectangle, relative to its interior point 25, 25:
185 width: 100; height: 100
187 transform: Scale { origin.x: 25; origin.y: 25; xScale: 3}
191 \sa Rotation, Translate
195 \qmlproperty real QtQuick2::Scale::origin.x
196 \qmlproperty real QtQuick2::Scale::origin.y
198 The point that the item is scaled from (i.e., the point that stays fixed relative to the parent as
199 the rest of the item grows). By default the origin is 0, 0.
203 \qmlproperty real QtQuick2::Scale::xScale
205 The scaling factor for the X axis.
209 \qmlproperty real QtQuick2::Scale::yScale
211 The scaling factor for the Y axis.
215 \qmlclass Rotation QQuickRotation
216 \inqmlmodule QtQuick 2
217 \ingroup qml-transform-elements
218 \brief The Rotation object provides a way to rotate an Item.
220 The Rotation object gives more control over rotation than using \l Item's \l{Item::rotation}{rotation} property.
221 Specifically, it allows (z axis) rotation to be relative to an arbitrary point.
223 The following example rotates a Rectangle around its interior point 25, 25:
226 width: 100; height: 100
228 transform: Rotation { origin.x: 25; origin.y: 25; angle: 45}
232 Rotation also provides a way to specify 3D-like rotations for Items. For these types of
233 rotations you must specify the axis to rotate around in addition to the origin point.
235 The following example shows various 3D-like rotations applied to an \l Image.
236 \snippet doc/src/snippets/declarative/rotation.qml 0
238 \image axisrotation.png
240 \sa {declarative/ui-components/dialcontrol}{Dial Control example}, {declarative/toys/clocks}{Clocks example}
244 \qmlproperty real QtQuick2::Rotation::origin.x
245 \qmlproperty real QtQuick2::Rotation::origin.y
247 The origin point of the rotation (i.e., the point that stays fixed relative to the parent as
248 the rest of the item rotates). By default the origin is 0, 0.
252 \qmlproperty real QtQuick2::Rotation::axis.x
253 \qmlproperty real QtQuick2::Rotation::axis.y
254 \qmlproperty real QtQuick2::Rotation::axis.z
256 The axis to rotate around. For simple (2D) rotation around a point, you do not need to specify an axis,
257 as the default axis is the z axis (\c{ axis { x: 0; y: 0; z: 1 } }).
259 For a typical 3D-like rotation you will usually specify both the origin and the axis.
261 \image 3d-rotation-axis.png
265 \qmlproperty real QtQuick2::Rotation::angle
267 The angle to rotate, in degrees clockwise.
270 QQuickTransformPrivate::QQuickTransformPrivate()
274 QQuickTransform::QQuickTransform(QObject *parent)
275 : QObject(*(new QQuickTransformPrivate), parent)
279 QQuickTransform::QQuickTransform(QQuickTransformPrivate &dd, QObject *parent)
280 : QObject(dd, parent)
284 QQuickTransform::~QQuickTransform()
286 Q_D(QQuickTransform);
287 for (int ii = 0; ii < d->items.count(); ++ii) {
288 QQuickItemPrivate *p = QQuickItemPrivate::get(d->items.at(ii));
289 p->transforms.removeOne(this);
290 p->dirty(QQuickItemPrivate::Transform);
294 void QQuickTransform::update()
296 Q_D(QQuickTransform);
297 for (int ii = 0; ii < d->items.count(); ++ii) {
298 QQuickItemPrivate *p = QQuickItemPrivate::get(d->items.at(ii));
299 p->dirty(QQuickItemPrivate::Transform);
303 QQuickContents::QQuickContents(QQuickItem *item)
304 : m_item(item), m_x(0), m_y(0), m_width(0), m_height(0)
308 QQuickContents::~QQuickContents()
310 QList<QQuickItem *> children = m_item->childItems();
311 for (int i = 0; i < children.count(); ++i) {
312 QQuickItem *child = children.at(i);
313 QQuickItemPrivate::get(child)->removeItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed);
317 bool QQuickContents::calcHeight(QQuickItem *changed)
320 qreal oldheight = m_height;
324 qreal bottom = oldy + oldheight;
325 qreal y = changed->y();
326 if (y + changed->height() > bottom)
327 bottom = y + changed->height();
331 m_height = bottom - top;
335 QList<QQuickItem *> children = m_item->childItems();
336 for (int i = 0; i < children.count(); ++i) {
337 QQuickItem *child = children.at(i);
338 qreal y = child->y();
339 if (y + child->height() > bottom)
340 bottom = y + child->height();
344 if (!children.isEmpty())
346 m_height = qMax(bottom - top, qreal(0.0));
349 return (m_height != oldheight || m_y != oldy);
352 bool QQuickContents::calcWidth(QQuickItem *changed)
355 qreal oldwidth = m_width;
359 qreal right = oldx + oldwidth;
360 qreal x = changed->x();
361 if (x + changed->width() > right)
362 right = x + changed->width();
366 m_width = right - left;
368 qreal left = FLT_MAX;
370 QList<QQuickItem *> children = m_item->childItems();
371 for (int i = 0; i < children.count(); ++i) {
372 QQuickItem *child = children.at(i);
373 qreal x = child->x();
374 if (x + child->width() > right)
375 right = x + child->width();
379 if (!children.isEmpty())
381 m_width = qMax(right - left, qreal(0.0));
384 return (m_width != oldwidth || m_x != oldx);
387 void QQuickContents::complete()
389 QQuickItemPrivate::get(m_item)->addItemChangeListener(this, QQuickItemPrivate::Children);
391 QList<QQuickItem *> children = m_item->childItems();
392 for (int i = 0; i < children.count(); ++i) {
393 QQuickItem *child = children.at(i);
394 QQuickItemPrivate::get(child)->addItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed);
395 //###what about changes to visibility?
400 void QQuickContents::updateRect()
402 QQuickItemPrivate::get(m_item)->emitChildrenRectChanged(rectF());
405 void QQuickContents::itemGeometryChanged(QQuickItem *changed, const QRectF &newGeometry, const QRectF &oldGeometry)
408 bool wChanged = false;
409 bool hChanged = false;
410 //### we can only pass changed if the left edge has moved left, or the right edge has moved right
411 if (newGeometry.width() != oldGeometry.width() || newGeometry.x() != oldGeometry.x())
412 wChanged = calcWidth(/*changed*/);
413 if (newGeometry.height() != oldGeometry.height() || newGeometry.y() != oldGeometry.y())
414 hChanged = calcHeight(/*changed*/);
415 if (wChanged || hChanged)
419 void QQuickContents::itemDestroyed(QQuickItem *item)
422 QQuickItemPrivate::get(item)->removeItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed);
426 void QQuickContents::itemChildRemoved(QQuickItem *, QQuickItem *item)
429 QQuickItemPrivate::get(item)->removeItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed);
433 void QQuickContents::itemChildAdded(QQuickItem *, QQuickItem *item)
436 QQuickItemPrivate::get(item)->addItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed);
440 QQuickItemKeyFilter::QQuickItemKeyFilter(QQuickItem *item)
441 : m_processPost(false), m_next(0)
443 QQuickItemPrivate *p = item?QQuickItemPrivate::get(item):0;
445 m_next = p->keyHandler;
446 p->keyHandler = this;
450 QQuickItemKeyFilter::~QQuickItemKeyFilter()
454 void QQuickItemKeyFilter::keyPressed(QKeyEvent *event, bool post)
456 if (m_next) m_next->keyPressed(event, post);
459 void QQuickItemKeyFilter::keyReleased(QKeyEvent *event, bool post)
461 if (m_next) m_next->keyReleased(event, post);
464 void QQuickItemKeyFilter::inputMethodEvent(QInputMethodEvent *event, bool post)
467 m_next->inputMethodEvent(event, post);
472 QVariant QQuickItemKeyFilter::inputMethodQuery(Qt::InputMethodQuery query) const
474 if (m_next) return m_next->inputMethodQuery(query);
478 void QQuickItemKeyFilter::componentComplete()
480 if (m_next) m_next->componentComplete();
483 \qmlclass KeyNavigation QQuickKeyNavigationAttached
484 \inqmlmodule QtQuick 2
485 \ingroup qml-basic-interaction-elements
486 \brief The KeyNavigation attached property supports key navigation by arrow keys.
488 Key-based user interfaces commonly allow the use of arrow keys to navigate between
489 focusable items. The KeyNavigation attached property enables this behavior by providing a
490 convenient way to specify the item that should gain focus when an arrow or tab key is pressed.
492 The following example provides key navigation for a 2x2 grid of items:
494 \snippet doc/src/snippets/declarative/keynavigation.qml 0
496 The top-left item initially receives focus by setting \l {Item::}{focus} to
497 \c true. When an arrow key is pressed, the focus will move to the
498 appropriate item, as defined by the value that has been set for
499 the KeyNavigation \l left, \l right, \l up or \l down properties.
501 Note that if a KeyNavigation attached property receives the key press and release
502 events for a requested arrow or tab key, the event is accepted and does not
503 propagate any further.
505 By default, KeyNavigation receives key events after the item to which it is attached.
506 If the item accepts the key event, the KeyNavigation attached property will not
507 receive an event for that key. Setting the \l priority property to
508 \c KeyNavigation.BeforeItem allows the event to be used for key navigation
509 before the item, rather than after.
511 If item to which the focus is switching is not enabled or visible, an attempt will
512 be made to skip this item and focus on the next. This is possible if there are
513 a chain of items with the same KeyNavigation handler. If multiple items in a row are not enabled
514 or visible, they will also be skipped.
516 KeyNavigation will implicitly set the other direction to return focus to this item. So if you set
517 \l left to another item, \l right will be set on that item's KeyNavigation to set focus back to this
518 item. However, if that item's KeyNavigation has had right explicitly set then no change will occur.
519 This means that the above example could have been written, with the same behaviour, without specifing
520 KeyNavigation.right or KeyNavigation.down for any of the items.
522 \sa {Keys}{Keys attached property}
526 \qmlproperty Item QtQuick2::KeyNavigation::left
527 \qmlproperty Item QtQuick2::KeyNavigation::right
528 \qmlproperty Item QtQuick2::KeyNavigation::up
529 \qmlproperty Item QtQuick2::KeyNavigation::down
530 \qmlproperty Item QtQuick2::KeyNavigation::tab
531 \qmlproperty Item QtQuick2::KeyNavigation::backtab
533 These properties hold the item to assign focus to
534 when the left, right, up or down cursor keys, or the
539 \qmlproperty Item QtQuick2::KeyNavigation::tab
540 \qmlproperty Item QtQuick2::KeyNavigation::backtab
542 These properties hold the item to assign focus to
543 when the Tab key or Shift+Tab key combination (Backtab) are pressed.
546 QQuickKeyNavigationAttached::QQuickKeyNavigationAttached(QObject *parent)
547 : QObject(*(new QQuickKeyNavigationAttachedPrivate), parent),
548 QQuickItemKeyFilter(qobject_cast<QQuickItem*>(parent))
550 m_processPost = true;
553 QQuickKeyNavigationAttached *
554 QQuickKeyNavigationAttached::qmlAttachedProperties(QObject *obj)
556 return new QQuickKeyNavigationAttached(obj);
559 QQuickItem *QQuickKeyNavigationAttached::left() const
561 Q_D(const QQuickKeyNavigationAttached);
565 void QQuickKeyNavigationAttached::setLeft(QQuickItem *i)
567 Q_D(QQuickKeyNavigationAttached);
572 QQuickKeyNavigationAttached* other =
573 qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
574 if (other && !other->d_func()->rightSet){
575 other->d_func()->right = qobject_cast<QQuickItem*>(parent());
576 emit other->rightChanged();
581 QQuickItem *QQuickKeyNavigationAttached::right() const
583 Q_D(const QQuickKeyNavigationAttached);
587 void QQuickKeyNavigationAttached::setRight(QQuickItem *i)
589 Q_D(QQuickKeyNavigationAttached);
594 QQuickKeyNavigationAttached* other =
595 qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
596 if (other && !other->d_func()->leftSet){
597 other->d_func()->left = qobject_cast<QQuickItem*>(parent());
598 emit other->leftChanged();
603 QQuickItem *QQuickKeyNavigationAttached::up() const
605 Q_D(const QQuickKeyNavigationAttached);
609 void QQuickKeyNavigationAttached::setUp(QQuickItem *i)
611 Q_D(QQuickKeyNavigationAttached);
616 QQuickKeyNavigationAttached* other =
617 qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
618 if (other && !other->d_func()->downSet){
619 other->d_func()->down = qobject_cast<QQuickItem*>(parent());
620 emit other->downChanged();
625 QQuickItem *QQuickKeyNavigationAttached::down() const
627 Q_D(const QQuickKeyNavigationAttached);
631 void QQuickKeyNavigationAttached::setDown(QQuickItem *i)
633 Q_D(QQuickKeyNavigationAttached);
638 QQuickKeyNavigationAttached* other =
639 qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
640 if (other && !other->d_func()->upSet) {
641 other->d_func()->up = qobject_cast<QQuickItem*>(parent());
642 emit other->upChanged();
647 QQuickItem *QQuickKeyNavigationAttached::tab() const
649 Q_D(const QQuickKeyNavigationAttached);
653 void QQuickKeyNavigationAttached::setTab(QQuickItem *i)
655 Q_D(QQuickKeyNavigationAttached);
660 QQuickKeyNavigationAttached* other =
661 qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
662 if (other && !other->d_func()->backtabSet) {
663 other->d_func()->backtab = qobject_cast<QQuickItem*>(parent());
664 emit other->backtabChanged();
669 QQuickItem *QQuickKeyNavigationAttached::backtab() const
671 Q_D(const QQuickKeyNavigationAttached);
675 void QQuickKeyNavigationAttached::setBacktab(QQuickItem *i)
677 Q_D(QQuickKeyNavigationAttached);
681 d->backtabSet = true;
682 QQuickKeyNavigationAttached* other =
683 qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
684 if (other && !other->d_func()->tabSet) {
685 other->d_func()->tab = qobject_cast<QQuickItem*>(parent());
686 emit other->tabChanged();
688 emit backtabChanged();
692 \qmlproperty enumeration QtQuick2::KeyNavigation::priority
694 This property determines whether the keys are processed before
695 or after the attached item's own key handling.
698 \o KeyNavigation.BeforeItem - process the key events before normal
699 item key processing. If the event is used for key navigation, it will be accepted and will not
700 be passed on to the item.
701 \o KeyNavigation.AfterItem (default) - process the key events after normal item key
702 handling. If the item accepts the key event it will not be
703 handled by the KeyNavigation attached property handler.
706 QQuickKeyNavigationAttached::Priority QQuickKeyNavigationAttached::priority() const
708 return m_processPost ? AfterItem : BeforeItem;
711 void QQuickKeyNavigationAttached::setPriority(Priority order)
713 bool processPost = order == AfterItem;
714 if (processPost != m_processPost) {
715 m_processPost = processPost;
716 emit priorityChanged();
720 void QQuickKeyNavigationAttached::keyPressed(QKeyEvent *event, bool post)
722 Q_D(QQuickKeyNavigationAttached);
725 if (post != m_processPost) {
726 QQuickItemKeyFilter::keyPressed(event, post);
731 switch (event->key()) {
733 if (QQuickItem *parentItem = qobject_cast<QQuickItem*>(parent()))
734 mirror = QQuickItemPrivate::get(parentItem)->effectiveLayoutMirror;
735 QQuickItem* leftItem = mirror ? d->right : d->left;
737 setFocusNavigation(leftItem, mirror ? "right" : "left");
742 case Qt::Key_Right: {
743 if (QQuickItem *parentItem = qobject_cast<QQuickItem*>(parent()))
744 mirror = QQuickItemPrivate::get(parentItem)->effectiveLayoutMirror;
745 QQuickItem* rightItem = mirror ? d->left : d->right;
747 setFocusNavigation(rightItem, mirror ? "left" : "right");
754 setFocusNavigation(d->up, "up");
760 setFocusNavigation(d->down, "down");
766 setFocusNavigation(d->tab, "tab");
770 case Qt::Key_Backtab:
772 setFocusNavigation(d->backtab, "backtab");
780 if (!event->isAccepted()) QQuickItemKeyFilter::keyPressed(event, post);
783 void QQuickKeyNavigationAttached::keyReleased(QKeyEvent *event, bool post)
785 Q_D(QQuickKeyNavigationAttached);
788 if (post != m_processPost) {
789 QQuickItemKeyFilter::keyReleased(event, post);
794 switch (event->key()) {
796 if (QQuickItem *parentItem = qobject_cast<QQuickItem*>(parent()))
797 mirror = QQuickItemPrivate::get(parentItem)->effectiveLayoutMirror;
798 if (mirror ? d->right : d->left)
802 if (QQuickItem *parentItem = qobject_cast<QQuickItem*>(parent()))
803 mirror = QQuickItemPrivate::get(parentItem)->effectiveLayoutMirror;
804 if (mirror ? d->left : d->right)
822 case Qt::Key_Backtab:
831 if (!event->isAccepted()) QQuickItemKeyFilter::keyReleased(event, post);
834 void QQuickKeyNavigationAttached::setFocusNavigation(QQuickItem *currentItem, const char *dir)
836 QQuickItem *initialItem = currentItem;
837 bool isNextItem = false;
840 if (currentItem->isVisible() && currentItem->isEnabled()) {
841 currentItem->setFocus(true);
844 qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(currentItem, false);
846 QQuickItem *tempItem = qvariant_cast<QQuickItem*>(attached->property(dir));
848 currentItem = tempItem;
854 while (currentItem != initialItem && isNextItem);
857 const QQuickKeysAttached::SigMap QQuickKeysAttached::sigMap[] = {
858 { Qt::Key_Left, "leftPressed" },
859 { Qt::Key_Right, "rightPressed" },
860 { Qt::Key_Up, "upPressed" },
861 { Qt::Key_Down, "downPressed" },
862 { Qt::Key_Tab, "tabPressed" },
863 { Qt::Key_Backtab, "backtabPressed" },
864 { Qt::Key_Asterisk, "asteriskPressed" },
865 { Qt::Key_NumberSign, "numberSignPressed" },
866 { Qt::Key_Escape, "escapePressed" },
867 { Qt::Key_Return, "returnPressed" },
868 { Qt::Key_Enter, "enterPressed" },
869 { Qt::Key_Delete, "deletePressed" },
870 { Qt::Key_Space, "spacePressed" },
871 { Qt::Key_Back, "backPressed" },
872 { Qt::Key_Cancel, "cancelPressed" },
873 { Qt::Key_Select, "selectPressed" },
874 { Qt::Key_Yes, "yesPressed" },
875 { Qt::Key_No, "noPressed" },
876 { Qt::Key_Context1, "context1Pressed" },
877 { Qt::Key_Context2, "context2Pressed" },
878 { Qt::Key_Context3, "context3Pressed" },
879 { Qt::Key_Context4, "context4Pressed" },
880 { Qt::Key_Call, "callPressed" },
881 { Qt::Key_Hangup, "hangupPressed" },
882 { Qt::Key_Flip, "flipPressed" },
883 { Qt::Key_Menu, "menuPressed" },
884 { Qt::Key_VolumeUp, "volumeUpPressed" },
885 { Qt::Key_VolumeDown, "volumeDownPressed" },
889 bool QQuickKeysAttachedPrivate::isConnected(const char *signalName)
891 return isSignalConnected(signalIndex(signalName));
895 \qmlclass Keys QQuickKeysAttached
896 \inqmlmodule QtQuick 2
897 \ingroup qml-basic-interaction-elements
898 \brief The Keys attached property provides key handling to Items.
900 All visual primitives support key handling via the Keys
901 attached property. Keys can be handled via the onPressed
902 and onReleased signal properties.
904 The signal properties have a \l KeyEvent parameter, named
905 \e event which contains details of the event. If a key is
906 handled \e event.accepted should be set to true to prevent the
907 event from propagating up the item hierarchy.
909 \section1 Example Usage
911 The following example shows how the general onPressed handler can
912 be used to test for a certain key; in this case, the left cursor
915 \snippet doc/src/snippets/declarative/keys/keys-pressed.qml key item
917 Some keys may alternatively be handled via specific signal properties,
918 for example \e onSelectPressed. These handlers automatically set
919 \e event.accepted to true.
921 \snippet doc/src/snippets/declarative/keys/keys-handler.qml key item
923 See \l{Qt::Key}{Qt.Key} for the list of keyboard codes.
925 \section1 Key Handling Priorities
927 The Keys attached property can be configured to handle key events
928 before or after the item it is attached to. This makes it possible
929 to intercept events in order to override an item's default behavior,
930 or act as a fallback for keys not handled by the item.
932 If \l priority is Keys.BeforeItem (default) the order of key event processing is:
935 \o Items specified in \c forwardTo
936 \o specific key handlers, e.g. onReturnPressed
937 \o onKeyPress, onKeyRelease handlers
938 \o Item specific key handling, e.g. TextInput key handling
942 If priority is Keys.AfterItem the order of key event processing is:
945 \o Item specific key handling, e.g. TextInput key handling
946 \o Items specified in \c forwardTo
947 \o specific key handlers, e.g. onReturnPressed
948 \o onKeyPress, onKeyRelease handlers
952 If the event is accepted during any of the above steps, key
955 \sa KeyEvent, {KeyNavigation}{KeyNavigation attached property}
959 \qmlproperty bool QtQuick2::Keys::enabled
961 This flags enables key handling if true (default); otherwise
962 no key handlers will be called.
966 \qmlproperty enumeration QtQuick2::Keys::priority
968 This property determines whether the keys are processed before
969 or after the attached item's own key handling.
972 \o Keys.BeforeItem (default) - process the key events before normal
973 item key processing. If the event is accepted it will not
974 be passed on to the item.
975 \o Keys.AfterItem - process the key events after normal item key
976 handling. If the item accepts the key event it will not be
977 handled by the Keys attached property handler.
982 \qmlproperty list<Object> QtQuick2::Keys::forwardTo
984 This property provides a way to forward key presses, key releases, and keyboard input
985 coming from input methods to other items. This can be useful when you want
986 one item to handle some keys (e.g. the up and down arrow keys), and another item to
987 handle other keys (e.g. the left and right arrow keys). Once an item that has been
988 forwarded keys accepts the event it is no longer forwarded to items later in the
991 This example forwards key events to two lists:
1002 Keys.forwardTo: [list1, list2]
1009 \qmlsignal QtQuick2::Keys::onPressed(KeyEvent event)
1011 This handler is called when a key has been pressed. The \a event
1012 parameter provides information about the event.
1016 \qmlsignal QtQuick2::Keys::onReleased(KeyEvent event)
1018 This handler is called when a key has been released. The \a event
1019 parameter provides information about the event.
1023 \qmlsignal QtQuick2::Keys::onDigit0Pressed(KeyEvent event)
1025 This handler is called when the digit '0' has been pressed. The \a event
1026 parameter provides information about the event.
1030 \qmlsignal QtQuick2::Keys::onDigit1Pressed(KeyEvent event)
1032 This handler is called when the digit '1' has been pressed. The \a event
1033 parameter provides information about the event.
1037 \qmlsignal QtQuick2::Keys::onDigit2Pressed(KeyEvent event)
1039 This handler is called when the digit '2' has been pressed. The \a event
1040 parameter provides information about the event.
1044 \qmlsignal QtQuick2::Keys::onDigit3Pressed(KeyEvent event)
1046 This handler is called when the digit '3' has been pressed. The \a event
1047 parameter provides information about the event.
1051 \qmlsignal QtQuick2::Keys::onDigit4Pressed(KeyEvent event)
1053 This handler is called when the digit '4' has been pressed. The \a event
1054 parameter provides information about the event.
1058 \qmlsignal QtQuick2::Keys::onDigit5Pressed(KeyEvent event)
1060 This handler is called when the digit '5' has been pressed. The \a event
1061 parameter provides information about the event.
1065 \qmlsignal QtQuick2::Keys::onDigit6Pressed(KeyEvent event)
1067 This handler is called when the digit '6' has been pressed. The \a event
1068 parameter provides information about the event.
1072 \qmlsignal QtQuick2::Keys::onDigit7Pressed(KeyEvent event)
1074 This handler is called when the digit '7' has been pressed. The \a event
1075 parameter provides information about the event.
1079 \qmlsignal QtQuick2::Keys::onDigit8Pressed(KeyEvent event)
1081 This handler is called when the digit '8' has been pressed. The \a event
1082 parameter provides information about the event.
1086 \qmlsignal QtQuick2::Keys::onDigit9Pressed(KeyEvent event)
1088 This handler is called when the digit '9' has been pressed. The \a event
1089 parameter provides information about the event.
1093 \qmlsignal QtQuick2::Keys::onLeftPressed(KeyEvent event)
1095 This handler is called when the Left arrow has been pressed. The \a event
1096 parameter provides information about the event.
1100 \qmlsignal QtQuick2::Keys::onRightPressed(KeyEvent event)
1102 This handler is called when the Right arrow has been pressed. The \a event
1103 parameter provides information about the event.
1107 \qmlsignal QtQuick2::Keys::onUpPressed(KeyEvent event)
1109 This handler is called when the Up arrow has been pressed. The \a event
1110 parameter provides information about the event.
1114 \qmlsignal QtQuick2::Keys::onDownPressed(KeyEvent event)
1116 This handler is called when the Down arrow has been pressed. The \a event
1117 parameter provides information about the event.
1121 \qmlsignal QtQuick2::Keys::onTabPressed(KeyEvent event)
1123 This handler is called when the Tab key has been pressed. The \a event
1124 parameter provides information about the event.
1128 \qmlsignal QtQuick2::Keys::onBacktabPressed(KeyEvent event)
1130 This handler is called when the Shift+Tab key combination (Backtab) has
1131 been pressed. The \a event parameter provides information about the event.
1135 \qmlsignal QtQuick2::Keys::onAsteriskPressed(KeyEvent event)
1137 This handler is called when the Asterisk '*' has been pressed. The \a event
1138 parameter provides information about the event.
1142 \qmlsignal QtQuick2::Keys::onEscapePressed(KeyEvent event)
1144 This handler is called when the Escape key has been pressed. The \a event
1145 parameter provides information about the event.
1149 \qmlsignal QtQuick2::Keys::onReturnPressed(KeyEvent event)
1151 This handler is called when the Return key has been pressed. The \a event
1152 parameter provides information about the event.
1156 \qmlsignal QtQuick2::Keys::onEnterPressed(KeyEvent event)
1158 This handler is called when the Enter key has been pressed. The \a event
1159 parameter provides information about the event.
1163 \qmlsignal QtQuick2::Keys::onDeletePressed(KeyEvent event)
1165 This handler is called when the Delete key has been pressed. The \a event
1166 parameter provides information about the event.
1170 \qmlsignal QtQuick2::Keys::onSpacePressed(KeyEvent event)
1172 This handler is called when the Space key has been pressed. The \a event
1173 parameter provides information about the event.
1177 \qmlsignal QtQuick2::Keys::onBackPressed(KeyEvent event)
1179 This handler is called when the Back key has been pressed. The \a event
1180 parameter provides information about the event.
1184 \qmlsignal QtQuick2::Keys::onCancelPressed(KeyEvent event)
1186 This handler is called when the Cancel key has been pressed. The \a event
1187 parameter provides information about the event.
1191 \qmlsignal QtQuick2::Keys::onSelectPressed(KeyEvent event)
1193 This handler is called when the Select key has been pressed. The \a event
1194 parameter provides information about the event.
1198 \qmlsignal QtQuick2::Keys::onYesPressed(KeyEvent event)
1200 This handler is called when the Yes key has been pressed. The \a event
1201 parameter provides information about the event.
1205 \qmlsignal QtQuick2::Keys::onNoPressed(KeyEvent event)
1207 This handler is called when the No key has been pressed. The \a event
1208 parameter provides information about the event.
1212 \qmlsignal QtQuick2::Keys::onContext1Pressed(KeyEvent event)
1214 This handler is called when the Context1 key has been pressed. The \a event
1215 parameter provides information about the event.
1219 \qmlsignal QtQuick2::Keys::onContext2Pressed(KeyEvent event)
1221 This handler is called when the Context2 key has been pressed. The \a event
1222 parameter provides information about the event.
1226 \qmlsignal QtQuick2::Keys::onContext3Pressed(KeyEvent event)
1228 This handler is called when the Context3 key has been pressed. The \a event
1229 parameter provides information about the event.
1233 \qmlsignal QtQuick2::Keys::onContext4Pressed(KeyEvent event)
1235 This handler is called when the Context4 key has been pressed. The \a event
1236 parameter provides information about the event.
1240 \qmlsignal QtQuick2::Keys::onCallPressed(KeyEvent event)
1242 This handler is called when the Call key has been pressed. The \a event
1243 parameter provides information about the event.
1247 \qmlsignal QtQuick2::Keys::onHangupPressed(KeyEvent event)
1249 This handler is called when the Hangup key has been pressed. The \a event
1250 parameter provides information about the event.
1254 \qmlsignal QtQuick2::Keys::onFlipPressed(KeyEvent event)
1256 This handler is called when the Flip key has been pressed. The \a event
1257 parameter provides information about the event.
1261 \qmlsignal QtQuick2::Keys::onMenuPressed(KeyEvent event)
1263 This handler is called when the Menu key has been pressed. The \a event
1264 parameter provides information about the event.
1268 \qmlsignal QtQuick2::Keys::onVolumeUpPressed(KeyEvent event)
1270 This handler is called when the VolumeUp key has been pressed. The \a event
1271 parameter provides information about the event.
1275 \qmlsignal QtQuick2::Keys::onVolumeDownPressed(KeyEvent event)
1277 This handler is called when the VolumeDown key has been pressed. The \a event
1278 parameter provides information about the event.
1281 QQuickKeysAttached::QQuickKeysAttached(QObject *parent)
1282 : QObject(*(new QQuickKeysAttachedPrivate), parent),
1283 QQuickItemKeyFilter(qobject_cast<QQuickItem*>(parent))
1285 Q_D(QQuickKeysAttached);
1286 m_processPost = false;
1287 d->item = qobject_cast<QQuickItem*>(parent);
1290 QQuickKeysAttached::~QQuickKeysAttached()
1294 QQuickKeysAttached::Priority QQuickKeysAttached::priority() const
1296 return m_processPost ? AfterItem : BeforeItem;
1299 void QQuickKeysAttached::setPriority(Priority order)
1301 bool processPost = order == AfterItem;
1302 if (processPost != m_processPost) {
1303 m_processPost = processPost;
1304 emit priorityChanged();
1308 void QQuickKeysAttached::componentComplete()
1310 Q_D(QQuickKeysAttached);
1312 for (int ii = 0; ii < d->targets.count(); ++ii) {
1313 QQuickItem *targetItem = d->targets.at(ii);
1314 if (targetItem && (targetItem->flags() & QQuickItem::ItemAcceptsInputMethod)) {
1315 d->item->setFlag(QQuickItem::ItemAcceptsInputMethod);
1322 void QQuickKeysAttached::keyPressed(QKeyEvent *event, bool post)
1324 Q_D(QQuickKeysAttached);
1325 if (post != m_processPost || !d->enabled || d->inPress) {
1327 QQuickItemKeyFilter::keyPressed(event, post);
1331 // first process forwards
1332 if (d->item && d->item->canvas()) {
1334 for (int ii = 0; ii < d->targets.count(); ++ii) {
1335 QQuickItem *i = d->targets.at(ii);
1336 if (i && i->isVisible()) {
1337 d->item->canvas()->sendEvent(i, event);
1338 if (event->isAccepted()) {
1347 QQuickKeyEvent ke(*event);
1348 QByteArray keySignal = keyToSignal(event->key());
1349 if (!keySignal.isEmpty()) {
1350 keySignal += "(QQuickKeyEvent*)";
1351 if (d->isConnected(keySignal)) {
1352 // If we specifically handle a key then default to accepted
1353 ke.setAccepted(true);
1354 int idx = QQuickKeysAttached::staticMetaObject.indexOfSignal(keySignal);
1355 metaObject()->method(idx).invoke(this, Qt::DirectConnection, Q_ARG(QQuickKeyEvent*, &ke));
1358 if (!ke.isAccepted())
1360 event->setAccepted(ke.isAccepted());
1362 if (!event->isAccepted()) QQuickItemKeyFilter::keyPressed(event, post);
1365 void QQuickKeysAttached::keyReleased(QKeyEvent *event, bool post)
1367 Q_D(QQuickKeysAttached);
1368 if (post != m_processPost || !d->enabled || d->inRelease) {
1370 QQuickItemKeyFilter::keyReleased(event, post);
1374 if (d->item && d->item->canvas()) {
1375 d->inRelease = true;
1376 for (int ii = 0; ii < d->targets.count(); ++ii) {
1377 QQuickItem *i = d->targets.at(ii);
1378 if (i && i->isVisible()) {
1379 d->item->canvas()->sendEvent(i, event);
1380 if (event->isAccepted()) {
1381 d->inRelease = false;
1386 d->inRelease = false;
1389 QQuickKeyEvent ke(*event);
1391 event->setAccepted(ke.isAccepted());
1393 if (!event->isAccepted()) QQuickItemKeyFilter::keyReleased(event, post);
1396 void QQuickKeysAttached::inputMethodEvent(QInputMethodEvent *event, bool post)
1398 Q_D(QQuickKeysAttached);
1399 if (post == m_processPost && d->item && !d->inIM && d->item->canvas()) {
1401 for (int ii = 0; ii < d->targets.count(); ++ii) {
1402 QQuickItem *i = d->targets.at(ii);
1403 if (i && i->isVisible() && (i->flags() & QQuickItem::ItemAcceptsInputMethod)) {
1404 d->item->canvas()->sendEvent(i, event);
1405 if (event->isAccepted()) {
1414 QQuickItemKeyFilter::inputMethodEvent(event, post);
1417 QVariant QQuickKeysAttached::inputMethodQuery(Qt::InputMethodQuery query) const
1419 Q_D(const QQuickKeysAttached);
1421 for (int ii = 0; ii < d->targets.count(); ++ii) {
1422 QQuickItem *i = d->targets.at(ii);
1423 if (i && i->isVisible() && (i->flags() & QQuickItem::ItemAcceptsInputMethod) && i == d->imeItem) {
1424 //### how robust is i == d->imeItem check?
1425 QVariant v = i->inputMethodQuery(query);
1426 if (v.userType() == QVariant::RectF)
1427 v = d->item->mapRectFromItem(i, v.toRectF()); //### cost?
1432 return QQuickItemKeyFilter::inputMethodQuery(query);
1435 QQuickKeysAttached *QQuickKeysAttached::qmlAttachedProperties(QObject *obj)
1437 return new QQuickKeysAttached(obj);
1441 \qmlclass LayoutMirroring QQuickLayoutMirroringAttached
1442 \inqmlmodule QtQuick 2
1443 \ingroup qml-utility-elements
1444 \brief The LayoutMirroring attached property is used to mirror layout behavior.
1446 The LayoutMirroring attached property is used to horizontally mirror \l {anchor-layout}{Item anchors},
1447 \l{Using QML Positioner and Repeater Items}{positioner} elements (such as \l Row and \l Grid)
1448 and views (such as \l GridView and horizontal \l ListView). Mirroring is a visual change: left
1449 anchors become right anchors, and positioner elements like \l Grid and \l Row reverse the
1450 horizontal layout of child items.
1452 Mirroring is enabled for an item by setting the \l enabled property to true. By default, this
1453 only affects the item itself; setting the \l childrenInherit property to true propagates the mirroring
1454 behavior to all child elements as well. If the \c LayoutMirroring attached property has not been defined
1455 for an item, mirroring is not enabled.
1457 The following example shows mirroring in action. The \l Row below is specified as being anchored
1458 to the left of its parent. However, since mirroring has been enabled, the anchor is horizontally
1459 reversed and it is now anchored to the right. Also, since items in a \l Row are positioned
1460 from left to right by default, they are now positioned from right to left instead, as demonstrated
1461 by the numbering and opacity of the items:
1463 \snippet doc/src/snippets/declarative/layoutmirroring.qml 0
1465 \image layoutmirroring.png
1467 Layout mirroring is useful when it is necessary to support both left-to-right and right-to-left
1468 layout versions of an application to target different language areas. The \l childrenInherit
1469 property allows layout mirroring to be applied without manually setting layout configurations
1470 for every item in an application. Keep in mind, however, that mirroring does not affect any
1471 positioning that is defined by the \l Item \l {Item::}{x} coordinate value, so even with
1472 mirroring enabled, it will often be necessary to apply some layout fixes to support the
1473 desired layout direction. Also, it may be necessary to disable the mirroring of individual
1474 child items (by setting \l {enabled}{LayoutMirroring.enabled} to false for such items) if
1475 mirroring is not the desired behavior, or if the child item already implements mirroring in
1478 See \l {QML Right-to-left User Interfaces} for further details on using \c LayoutMirroring and
1479 other related features to implement right-to-left support for an application.
1483 \qmlproperty bool QtQuick2::LayoutMirroring::enabled
1485 This property holds whether the item's layout is mirrored horizontally. Setting this to true
1486 horizontally reverses \l {anchor-layout}{anchor} settings such that left anchors become right,
1487 and right anchors become left. For \l{Using QML Positioner and Repeater Items}{positioner} elements
1488 (such as \l Row and \l Grid) and view elements (such as \l {GridView}{GridView} and \l {ListView}{ListView})
1489 this also mirrors the horizontal layout direction of the item.
1491 The default value is false.
1495 \qmlproperty bool QtQuick2::LayoutMirroring::childrenInherit
1497 This property holds whether the \l {enabled}{LayoutMirroring.enabled} value for this item
1498 is inherited by its children.
1500 The default value is false.
1504 QQuickLayoutMirroringAttached::QQuickLayoutMirroringAttached(QObject *parent) : QObject(parent), itemPrivate(0)
1506 if (QQuickItem *item = qobject_cast<QQuickItem*>(parent)) {
1507 itemPrivate = QQuickItemPrivate::get(item);
1508 itemPrivate->attachedLayoutDirection = this;
1510 qmlInfo(parent) << tr("LayoutDirection attached property only works with Items");
1513 QQuickLayoutMirroringAttached * QQuickLayoutMirroringAttached::qmlAttachedProperties(QObject *object)
1515 return new QQuickLayoutMirroringAttached(object);
1518 bool QQuickLayoutMirroringAttached::enabled() const
1520 return itemPrivate ? itemPrivate->effectiveLayoutMirror : false;
1523 void QQuickLayoutMirroringAttached::setEnabled(bool enabled)
1528 itemPrivate->isMirrorImplicit = false;
1529 if (enabled != itemPrivate->effectiveLayoutMirror) {
1530 itemPrivate->setLayoutMirror(enabled);
1531 if (itemPrivate->inheritMirrorFromItem)
1532 itemPrivate->resolveLayoutMirror();
1536 void QQuickLayoutMirroringAttached::resetEnabled()
1538 if (itemPrivate && !itemPrivate->isMirrorImplicit) {
1539 itemPrivate->isMirrorImplicit = true;
1540 itemPrivate->resolveLayoutMirror();
1544 bool QQuickLayoutMirroringAttached::childrenInherit() const
1546 return itemPrivate ? itemPrivate->inheritMirrorFromItem : false;
1549 void QQuickLayoutMirroringAttached::setChildrenInherit(bool childrenInherit) {
1550 if (itemPrivate && childrenInherit != itemPrivate->inheritMirrorFromItem) {
1551 itemPrivate->inheritMirrorFromItem = childrenInherit;
1552 itemPrivate->resolveLayoutMirror();
1553 childrenInheritChanged();
1557 void QQuickItemPrivate::resolveLayoutMirror()
1560 if (QQuickItem *parentItem = q->parentItem()) {
1561 QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(parentItem);
1562 setImplicitLayoutMirror(parentPrivate->inheritedLayoutMirror, parentPrivate->inheritMirrorFromParent);
1564 setImplicitLayoutMirror(isMirrorImplicit ? false : effectiveLayoutMirror, inheritMirrorFromItem);
1568 void QQuickItemPrivate::setImplicitLayoutMirror(bool mirror, bool inherit)
1570 inherit = inherit || inheritMirrorFromItem;
1571 if (!isMirrorImplicit && inheritMirrorFromItem)
1572 mirror = effectiveLayoutMirror;
1573 if (mirror == inheritedLayoutMirror && inherit == inheritMirrorFromParent)
1576 inheritMirrorFromParent = inherit;
1577 inheritedLayoutMirror = inheritMirrorFromParent ? mirror : false;
1579 if (isMirrorImplicit)
1580 setLayoutMirror(inherit ? inheritedLayoutMirror : false);
1581 for (int i = 0; i < childItems.count(); ++i) {
1582 if (QQuickItem *child = qobject_cast<QQuickItem *>(childItems.at(i))) {
1583 QQuickItemPrivate *childPrivate = QQuickItemPrivate::get(child);
1584 childPrivate->setImplicitLayoutMirror(inheritedLayoutMirror, inheritMirrorFromParent);
1589 void QQuickItemPrivate::setLayoutMirror(bool mirror)
1591 if (mirror != effectiveLayoutMirror) {
1592 effectiveLayoutMirror = mirror;
1594 QQuickAnchorsPrivate *anchor_d = QQuickAnchorsPrivate::get(_anchors);
1595 anchor_d->fillChanged();
1596 anchor_d->centerInChanged();
1597 anchor_d->updateHorizontalAnchors();
1598 emit _anchors->mirroredChanged();
1601 if (attachedLayoutDirection) {
1602 emit attachedLayoutDirection->enabledChanged();
1607 void QQuickItemPrivate::setAccessibleFlagAndListener()
1610 QQuickItem *item = q;
1612 if (item->d_func()->isAccessible)
1613 break; // already set - grandparents should have the flag set as well.
1615 if (item->canvas() && item->canvas()->rootItem() == item)
1616 break; // don't add a listener to the canvas root item
1618 item->d_func()->isAccessible = true;
1619 item = item->d_func()->parentItem;
1625 \brief The QQuickItem class provides the most basic of all visual items in QML.
1629 All visual items in Qt Declarative inherit from QQuickItem. Although QQuickItem
1630 has no visual appearance, it defines all the properties that are
1631 common across visual items - such as the x and y position, the
1632 width and height, \l {anchor-layout}{anchoring} and key handling.
1634 You can subclass QQuickItem to provide your own custom visual item that inherits
1635 these features. Note that, because it does not draw anything, QQuickItem sets the
1636 QGraphicsItem::ItemHasNoContents flag. If you subclass QQuickItem to create a visual
1637 item, you will need to unset this flag.
1642 \qmlclass Item QQuickItem
1643 \inqmlmodule QtQuick 2
1644 \ingroup qml-basic-visual-elements
1645 \brief The Item is the most basic of all visual items in QML.
1647 All visual items in Qt Declarative inherit from Item. Although Item
1648 has no visual appearance, it defines all the properties that are
1649 common across visual items - such as the x and y position, the
1650 width and height, \l {anchor-layout}{anchoring} and key handling.
1652 Item is also useful for grouping items together.
1669 fillMode: Image.Tile
1676 \section1 Key Handling
1678 Key handling is available to all Item-based visual elements via the \l {Keys}{Keys}
1679 attached property. The \e Keys attached property provides basic handlers such
1680 as \l {Keys::onPressed}{onPressed} and \l {Keys::onReleased}{onReleased},
1681 as well as handlers for specific keys, such as
1682 \l {Keys::onCancelPressed}{onCancelPressed}. The example below
1683 assigns \l {qmlfocus}{focus} to the item and handles
1684 the Left key via the general \e onPressed handler and the Select key via the
1685 onSelectPressed handler:
1691 if (event.key == Qt.Key_Left) {
1692 console.log("move left");
1693 event.accepted = true;
1696 Keys.onSelectPressed: console.log("Selected");
1700 See the \l {Keys}{Keys} attached property for detailed documentation.
1702 \section1 Layout Mirroring
1704 Item layouts can be mirrored using the \l {LayoutMirroring}{LayoutMirroring} attached property.
1709 \fn void QQuickItem::childrenRectChanged(const QRectF &)
1714 \fn void QQuickItem::baselineOffsetChanged(qreal)
1719 \fn void QQuickItem::stateChanged(const QString &state)
1724 \fn void QQuickItem::parentChanged(QQuickItem *)
1729 \fn void QQuickItem::smoothChanged(bool)
1734 \fn void QQuickItem::clipChanged(bool)
1738 /*! \fn void QQuickItem::transformOriginChanged(TransformOrigin)
1743 \fn void QQuickItem::focusChanged(bool)
1748 \fn void QQuickItem::activeFocusChanged(bool)
1752 \fn QQuickItem::QQuickItem(QQuickItem *parent)
1754 Constructs a QQuickItem with the given \a parent.
1756 QQuickItem::QQuickItem(QQuickItem* parent)
1757 : QObject(*(new QQuickItemPrivate), parent)
1765 QQuickItem::QQuickItem(QQuickItemPrivate &dd, QQuickItem *parent)
1766 : QObject(dd, parent)
1773 static int qt_item_count = 0;
1775 static void qt_print_item_count()
1777 qDebug("Number of leaked items: %i", qt_item_count);
1783 Destroys the QQuickItem.
1785 QQuickItem::~QQuickItem()
1789 if (qt_item_count < 0)
1790 qDebug("Item destroyed after qt_print_item_count() was called.");
1797 else if (d->canvas && d->itemNodeInstance)
1798 QQuickCanvasPrivate::get(d->canvas)->cleanup(d->itemNodeInstance); // cleanup root
1799 // XXX todo - optimize
1800 while (!d->childItems.isEmpty())
1801 d->childItems.first()->setParentItem(0);
1803 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
1804 QQuickAnchorsPrivate *anchor = d->changeListeners.at(ii).listener->anchorPrivate();
1806 anchor->clearItem(this);
1810 update item anchors that depended on us unless they are our child (and will also be destroyed),
1811 or our sibling, and our parent is also being destroyed.
1813 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
1814 QQuickAnchorsPrivate *anchor = d->changeListeners.at(ii).listener->anchorPrivate();
1815 if (anchor && anchor->item && anchor->item->parentItem() && anchor->item->parentItem() != this)
1819 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
1820 const QQuickItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
1821 if (change.types & QQuickItemPrivate::Destroyed)
1822 change.listener->itemDestroyed(this);
1825 d->changeListeners.clear();
1826 delete d->_anchorLines; d->_anchorLines = 0;
1827 delete d->_anchors; d->_anchors = 0;
1828 delete d->_stateGroup; d->_stateGroup = 0;
1829 delete d->_contents; d->_contents = 0;
1833 \qmlproperty enumeration QtQuick2::Item::transformOrigin
1834 This property holds the origin point around which scale and rotation transform.
1836 Nine transform origins are available, as shown in the image below.
1838 \image declarative-transformorigin.png
1840 This example rotates an image around its bottom-right corner.
1843 source: "myimage.png"
1844 transformOrigin: Item.BottomRight
1849 The default transform origin is \c Item.Center.
1851 To set an arbitrary transform origin point use the \l Scale or \l Rotation
1856 \qmlproperty Item QtQuick2::Item::parent
1857 This property holds the parent of the item.
1861 \property QQuickItem::parent
1862 This property holds the parent of the item.
1864 void QQuickItem::setParentItem(QQuickItem *parentItem)
1867 if (parentItem == d->parentItem)
1870 d->removeFromDirtyList();
1872 QQuickItem *oldParentItem = d->parentItem;
1873 QQuickItem *scopeFocusedItem = 0;
1875 if (oldParentItem) {
1876 QQuickItemPrivate *op = QQuickItemPrivate::get(oldParentItem);
1878 QQuickItem *scopeItem = 0;
1880 if (d->canvas && hasFocus()) {
1881 scopeItem = oldParentItem;
1882 while (!scopeItem->isFocusScope()) scopeItem = scopeItem->parentItem();
1883 scopeFocusedItem = this;
1884 } else if (d->canvas && !isFocusScope() && d->subFocusItem) {
1885 scopeItem = oldParentItem;
1886 while (!scopeItem->isFocusScope()) scopeItem = scopeItem->parentItem();
1887 scopeFocusedItem = d->subFocusItem;
1890 if (scopeFocusedItem)
1891 QQuickCanvasPrivate::get(d->canvas)->clearFocusInScope(scopeItem, scopeFocusedItem,
1892 QQuickCanvasPrivate::DontChangeFocusProperty);
1894 op->removeChild(this);
1895 } else if (d->canvas) {
1896 QQuickCanvasPrivate::get(d->canvas)->parentlessItems.remove(this);
1899 d->parentItem = parentItem;
1901 QQuickCanvas *parentCanvas = parentItem?QQuickItemPrivate::get(parentItem)->canvas:0;
1902 if (d->canvas != parentCanvas) {
1903 QQuickItemPrivate::InitializationState initState;
1905 d->initCanvas(&initState, parentCanvas);
1908 d->dirty(QQuickItemPrivate::ParentChanged);
1911 QQuickItemPrivate::get(d->parentItem)->addChild(this);
1913 d->setEffectiveVisibleRecur(d->calcEffectiveVisible());
1914 d->setEffectiveEnableRecur(d->calcEffectiveEnable());
1916 if (scopeFocusedItem && d->parentItem && d->canvas) {
1917 // We need to test whether this item becomes scope focused
1918 QQuickItem *scopeItem = 0;
1919 scopeItem = d->parentItem;
1920 while (!scopeItem->isFocusScope()) scopeItem = scopeItem->parentItem();
1922 if (scopeItem->scopedFocusItem()) {
1923 QQuickItemPrivate::get(scopeFocusedItem)->focus = false;
1924 emit scopeFocusedItem->focusChanged(false);
1926 QQuickCanvasPrivate::get(d->canvas)->setFocusInScope(scopeItem, scopeFocusedItem,
1927 QQuickCanvasPrivate::DontChangeFocusProperty);
1931 d->resolveLayoutMirror();
1933 d->itemChange(ItemParentHasChanged, d->parentItem);
1935 d->parentNotifier.notify();
1936 if (d->isAccessible && d->parentItem) {
1937 d->parentItem->d_func()->setAccessibleFlagAndListener();
1940 emit parentChanged(d->parentItem);
1943 void QQuickItem::stackBefore(const QQuickItem *sibling)
1946 if (!sibling || sibling == this || !d->parentItem || d->parentItem != QQuickItemPrivate::get(sibling)->parentItem) {
1947 qWarning("QQuickItem::stackBefore: Cannot stack before %p, which must be a sibling", sibling);
1951 QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(d->parentItem);
1953 int myIndex = parentPrivate->childItems.indexOf(this);
1954 int siblingIndex = parentPrivate->childItems.indexOf(const_cast<QQuickItem *>(sibling));
1956 Q_ASSERT(myIndex != -1 && siblingIndex != -1);
1958 if (myIndex == siblingIndex - 1)
1961 parentPrivate->childItems.removeAt(myIndex);
1963 if (myIndex < siblingIndex) --siblingIndex;
1965 parentPrivate->childItems.insert(siblingIndex, this);
1967 parentPrivate->dirty(QQuickItemPrivate::ChildrenStackingChanged);
1968 parentPrivate->markSortedChildrenDirty(this);
1970 for (int ii = qMin(siblingIndex, myIndex); ii < parentPrivate->childItems.count(); ++ii)
1971 QQuickItemPrivate::get(parentPrivate->childItems.at(ii))->siblingOrderChanged();
1974 void QQuickItem::stackAfter(const QQuickItem *sibling)
1977 if (!sibling || sibling == this || !d->parentItem || d->parentItem != QQuickItemPrivate::get(sibling)->parentItem) {
1978 qWarning("QQuickItem::stackAfter: Cannot stack after %p, which must be a sibling", sibling);
1982 QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(d->parentItem);
1984 int myIndex = parentPrivate->childItems.indexOf(this);
1985 int siblingIndex = parentPrivate->childItems.indexOf(const_cast<QQuickItem *>(sibling));
1987 Q_ASSERT(myIndex != -1 && siblingIndex != -1);
1989 if (myIndex == siblingIndex + 1)
1992 parentPrivate->childItems.removeAt(myIndex);
1994 if (myIndex < siblingIndex) --siblingIndex;
1996 parentPrivate->childItems.insert(siblingIndex + 1, this);
1998 parentPrivate->dirty(QQuickItemPrivate::ChildrenStackingChanged);
1999 parentPrivate->markSortedChildrenDirty(this);
2001 for (int ii = qMin(myIndex, siblingIndex + 1); ii < parentPrivate->childItems.count(); ++ii)
2002 QQuickItemPrivate::get(parentPrivate->childItems.at(ii))->siblingOrderChanged();
2006 Returns the QQuickItem parent of this item.
2008 QQuickItem *QQuickItem::parentItem() const
2010 Q_D(const QQuickItem);
2011 return d->parentItem;
2014 QSGEngine *QQuickItem::sceneGraphEngine() const
2016 return canvas()->sceneGraphEngine();
2019 QQuickCanvas *QQuickItem::canvas() const
2021 Q_D(const QQuickItem);
2025 static bool itemZOrder_sort(QQuickItem *lhs, QQuickItem *rhs)
2027 return lhs->z() < rhs->z();
2030 QList<QQuickItem *> QQuickItemPrivate::paintOrderChildItems() const
2032 if (sortedChildItems)
2033 return *sortedChildItems;
2035 // If none of the items have set Z then the paint order list is the same as
2036 // the childItems list. This is by far the most common case.
2038 for (int i = 0; i < childItems.count(); ++i) {
2039 if (QQuickItemPrivate::get(childItems.at(i))->z != 0.) {
2045 sortedChildItems = new QList<QQuickItem*>(childItems);
2046 qStableSort(sortedChildItems->begin(), sortedChildItems->end(), itemZOrder_sort);
2047 return *sortedChildItems;
2050 sortedChildItems = const_cast<QList<QQuickItem*>*>(&childItems);
2055 void QQuickItemPrivate::addChild(QQuickItem *child)
2059 Q_ASSERT(!childItems.contains(child));
2061 childItems.append(child);
2063 markSortedChildrenDirty(child);
2064 dirty(QQuickItemPrivate::ChildrenChanged);
2066 itemChange(QQuickItem::ItemChildAddedChange, child);
2068 emit q->childrenChanged();
2071 void QQuickItemPrivate::removeChild(QQuickItem *child)
2076 Q_ASSERT(childItems.contains(child));
2077 childItems.removeOne(child);
2078 Q_ASSERT(!childItems.contains(child));
2080 markSortedChildrenDirty(child);
2081 dirty(QQuickItemPrivate::ChildrenChanged);
2083 itemChange(QQuickItem::ItemChildRemovedChange, child);
2085 emit q->childrenChanged();
2088 void QQuickItemPrivate::InitializationState::clear()
2093 void QQuickItemPrivate::InitializationState::clear(QQuickItem *fs)
2098 QQuickItem *QQuickItemPrivate::InitializationState::getFocusScope(QQuickItem *item)
2101 QQuickItem *fs = item->parentItem();
2102 while (!fs->isFocusScope())
2103 fs = fs->parentItem();
2109 void QQuickItemPrivate::initCanvas(InitializationState *state, QQuickCanvas *c)
2114 removeFromDirtyList();
2115 QQuickCanvasPrivate *c = QQuickCanvasPrivate::get(canvas);
2116 if (polishScheduled)
2117 c->itemsToPolish.remove(q);
2118 if (c->mouseGrabberItem == q)
2119 c->mouseGrabberItem = 0;
2121 c->hoverItems.removeAll(q);
2122 if (itemNodeInstance)
2123 c->cleanup(itemNodeInstance);
2125 c->parentlessItems.remove(q);
2130 if (canvas && polishScheduled)
2131 QQuickCanvasPrivate::get(canvas)->itemsToPolish.insert(q);
2133 itemNodeInstance = 0;
2139 beforePaintNode = 0;
2141 InitializationState _dummy;
2142 InitializationState *childState = state;
2144 if (c && q->isFocusScope()) {
2146 childState = &_dummy;
2149 if (!parentItem && canvas)
2150 QQuickCanvasPrivate::get(canvas)->parentlessItems.insert(q);
2152 for (int ii = 0; ii < childItems.count(); ++ii) {
2153 QQuickItem *child = childItems.at(ii);
2154 QQuickItemPrivate::get(child)->initCanvas(childState, c);
2159 if (state->getFocusScope(q)->scopedFocusItem()) {
2161 emit q->focusChanged(false);
2163 QQuickCanvasPrivate::get(canvas)->setFocusInScope(state->getFocusScope(q), q);
2170 screenAttached->canvasChanged(c);
2171 itemChange(QQuickItem::ItemSceneChange, c);
2175 Returns a transform that maps points from canvas space into item space.
2177 QTransform QQuickItemPrivate::canvasToItemTransform() const
2179 // XXX todo - optimize
2180 return itemToCanvasTransform().inverted();
2184 Returns a transform that maps points from item space into canvas space.
2186 QTransform QQuickItemPrivate::itemToCanvasTransform() const
2189 QTransform rv = parentItem?QQuickItemPrivate::get(parentItem)->itemToCanvasTransform():QTransform();
2190 itemToParentTransform(rv);
2195 Motifies \a t with this items local transform relative to its parent.
2197 void QQuickItemPrivate::itemToParentTransform(QTransform &t) const
2202 if (!transforms.isEmpty()) {
2204 for (int ii = transforms.count() - 1; ii >= 0; --ii)
2205 transforms.at(ii)->applyTo(&m);
2206 t = m.toTransform();
2209 if (scale != 1. || rotation != 0.) {
2210 QPointF tp = computeTransformOrigin();
2211 t.translate(tp.x(), tp.y());
2212 t.scale(scale, scale);
2214 t.translate(-tp.x(), -tp.y());
2220 \qmlproperty real QtQuick2::Item::childrenRect.x
2221 \qmlproperty real QtQuick2::Item::childrenRect.y
2222 \qmlproperty real QtQuick2::Item::childrenRect.width
2223 \qmlproperty real QtQuick2::Item::childrenRect.height
2225 The childrenRect properties allow an item access to the geometry of its
2226 children. This property is useful if you have an item that needs to be
2227 sized to fit its children.
2232 \qmlproperty list<Item> QtQuick2::Item::children
2233 \qmlproperty list<Object> QtQuick2::Item::resources
2235 The children property contains the list of visual children of this item.
2236 The resources property contains non-visual resources that you want to
2239 Generally you can rely on Item's default property to handle all this for
2240 you, but it can come in handy in some cases.
2259 Returns true if construction of the QML component is complete; otherwise
2262 It is often desirable to delay some processing until the component is
2265 \sa componentComplete()
2267 bool QQuickItem::isComponentComplete() const
2269 Q_D(const QQuickItem);
2270 return d->componentComplete;
2273 QQuickItemPrivate::QQuickItemPrivate()
2274 : _anchors(0), _contents(0), baselineOffset(0), _anchorLines(0), _stateGroup(0), origin(QQuickItem::Center),
2276 flags(0), widthValid(false), heightValid(false), componentComplete(true),
2277 keepMouse(false), keepTouch(false), hoverEnabled(false), smooth(false), focus(false), activeFocus(false), notifiedFocus(false),
2278 notifiedActiveFocus(false), filtersChildMouseEvents(false), explicitVisible(true),
2279 effectiveVisible(true), explicitEnable(true), effectiveEnable(true), polishScheduled(false),
2280 inheritedLayoutMirror(false), effectiveLayoutMirror(false), isMirrorImplicit(true),
2281 inheritMirrorFromParent(false), inheritMirrorFromItem(false), childrenDoNotOverlap(false),
2282 staticSubtreeGeometry(false),
2283 isAccessible(false),
2285 canvas(0), parentItem(0), sortedChildItems(&childItems),
2289 x(0), y(0), width(0), height(0), implicitWidth(0), implicitHeight(0),
2290 z(0), scale(1), rotation(0), opacity(1),
2292 attachedLayoutDirection(0), acceptedMouseButtons(0),
2293 imHints(Qt::ImhMultiLine),
2297 dirtyAttributes(0), nextDirtyItem(0), prevDirtyItem(0),
2299 itemNodeInstance(0), opacityNode(0), clipNode(0), rootNode(0), groupNode(0), paintNode(0)
2300 , beforePaintNode(0), effectRefCount(0), hideRefCount(0)
2305 QQuickItemPrivate::~QQuickItemPrivate()
2307 if (sortedChildItems != &childItems)
2308 delete sortedChildItems;
2311 void QQuickItemPrivate::init(QQuickItem *parent)
2315 static bool atexit_registered = false;
2316 if (!atexit_registered) {
2317 atexit(qt_print_item_count);
2318 atexit_registered = true;
2324 registerAccessorProperties();
2326 baselineOffset.invalidate();
2329 q->setParentItem(parent);
2330 QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(parent);
2331 setImplicitLayoutMirror(parentPrivate->inheritedLayoutMirror, parentPrivate->inheritMirrorFromParent);
2335 void QQuickItemPrivate::data_append(QDeclarativeListProperty<QObject> *prop, QObject *o)
2340 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2342 // This test is measurably (albeit only slightly) faster than qobject_cast<>()
2343 const QMetaObject *mo = o->metaObject();
2344 while (mo && mo != &QQuickItem::staticMetaObject) {
2345 mo = mo->d.superdata;
2349 QQuickItem *item = static_cast<QQuickItem *>(o);
2350 item->setParentItem(that);
2352 if (o->inherits("QGraphicsItem"))
2353 qWarning("Cannot add a QtQuick 1.0 item (%s) into a QtQuick 2.0 scene!", o->metaObject()->className());
2355 // XXX todo - do we really want this behavior?
2361 \qmlproperty list<Object> QtQuick2::Item::data
2364 The data property allows you to freely mix visual children and resources
2365 in an item. If you assign a visual item to the data list it becomes
2366 a child and if you assign any other object type, it is added as a resource.
2390 data is a behind-the-scenes property: you should never need to explicitly
2394 int QQuickItemPrivate::data_count(QDeclarativeListProperty<QObject> *prop)
2401 QObject *QQuickItemPrivate::data_at(QDeclarativeListProperty<QObject> *prop, int i)
2409 void QQuickItemPrivate::data_clear(QDeclarativeListProperty<QObject> *prop)
2415 QObject *QQuickItemPrivate::resources_at(QDeclarativeListProperty<QObject> *prop, int index)
2417 const QObjectList children = prop->object->children();
2418 if (index < children.count())
2419 return children.at(index);
2424 void QQuickItemPrivate::resources_append(QDeclarativeListProperty<QObject> *prop, QObject *o)
2426 // XXX todo - do we really want this behavior?
2427 o->setParent(prop->object);
2430 int QQuickItemPrivate::resources_count(QDeclarativeListProperty<QObject> *prop)
2432 return prop->object->children().count();
2435 void QQuickItemPrivate::resources_clear(QDeclarativeListProperty<QObject> *prop)
2437 // XXX todo - do we really want this behavior?
2438 const QObjectList children = prop->object->children();
2439 for (int index = 0; index < children.count(); index++)
2440 children.at(index)->setParent(0);
2443 QQuickItem *QQuickItemPrivate::children_at(QDeclarativeListProperty<QQuickItem> *prop, int index)
2445 QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2446 if (index >= p->childItems.count() || index < 0)
2449 return p->childItems.at(index);
2452 void QQuickItemPrivate::children_append(QDeclarativeListProperty<QQuickItem> *prop, QQuickItem *o)
2457 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2458 if (o->parentItem() == that)
2459 o->setParentItem(0);
2461 o->setParentItem(that);
2464 int QQuickItemPrivate::children_count(QDeclarativeListProperty<QQuickItem> *prop)
2466 QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2467 return p->childItems.count();
2470 void QQuickItemPrivate::children_clear(QDeclarativeListProperty<QQuickItem> *prop)
2472 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2473 QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2474 while (!p->childItems.isEmpty())
2475 p->childItems.at(0)->setParentItem(0);
2478 int QQuickItemPrivate::transform_count(QDeclarativeListProperty<QQuickTransform> *prop)
2480 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2481 return QQuickItemPrivate::get(that)->transforms.count();
2484 void QQuickTransform::appendToItem(QQuickItem *item)
2486 Q_D(QQuickTransform);
2490 QQuickItemPrivate *p = QQuickItemPrivate::get(item);
2492 if (!d->items.isEmpty() && !p->transforms.isEmpty() && p->transforms.contains(this)) {
2493 p->transforms.removeOne(this);
2494 p->transforms.append(this);
2496 p->transforms.append(this);
2497 d->items.append(item);
2500 p->dirty(QQuickItemPrivate::Transform);
2503 void QQuickTransform::prependToItem(QQuickItem *item)
2505 Q_D(QQuickTransform);
2509 QQuickItemPrivate *p = QQuickItemPrivate::get(item);
2511 if (!d->items.isEmpty() && !p->transforms.isEmpty() && p->transforms.contains(this)) {
2512 p->transforms.removeOne(this);
2513 p->transforms.prepend(this);
2515 p->transforms.prepend(this);
2516 d->items.append(item);
2519 p->dirty(QQuickItemPrivate::Transform);
2522 void QQuickItemPrivate::transform_append(QDeclarativeListProperty<QQuickTransform> *prop, QQuickTransform *transform)
2527 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2528 transform->appendToItem(that);
2531 QQuickTransform *QQuickItemPrivate::transform_at(QDeclarativeListProperty<QQuickTransform> *prop, int idx)
2533 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2534 QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2536 if (idx < 0 || idx >= p->transforms.count())
2539 return p->transforms.at(idx);
2542 void QQuickItemPrivate::transform_clear(QDeclarativeListProperty<QQuickTransform> *prop)
2544 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2545 QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2547 for (int ii = 0; ii < p->transforms.count(); ++ii) {
2548 QQuickTransform *t = p->transforms.at(ii);
2549 QQuickTransformPrivate *tp = QQuickTransformPrivate::get(t);
2550 tp->items.removeOne(that);
2553 p->transforms.clear();
2555 p->dirty(QQuickItemPrivate::Transform);
2559 \property QQuickItem::childrenRect
2560 \brief The geometry of an item's children.
2562 This property holds the (collective) position and size of the item's children.
2566 \qmlproperty real QtQuick2::Item::x
2567 \qmlproperty real QtQuick2::Item::y
2568 \qmlproperty real QtQuick2::Item::width
2569 \qmlproperty real QtQuick2::Item::height
2571 Defines the item's position and size relative to its parent.
2574 Item { x: 100; y: 100; width: 100; height: 100 }
2579 \qmlproperty real QtQuick2::Item::z
2581 Sets the stacking order of sibling items. By default the stacking order is 0.
2583 Items with a higher stacking value are drawn on top of siblings with a
2584 lower stacking order. Items with the same stacking value are drawn
2585 bottom up in the order they appear. Items with a negative stacking
2586 value are drawn under their parent's content.
2588 The following example shows the various effects of stacking order.
2592 \o \image declarative-item_stacking1.png
2593 \o Same \c z - later children above earlier children:
2598 width: 100; height: 100
2602 x: 50; y: 50; width: 100; height: 100
2607 \o \image declarative-item_stacking2.png
2608 \o Higher \c z on top:
2614 width: 100; height: 100
2618 x: 50; y: 50; width: 100; height: 100
2623 \o \image declarative-item_stacking3.png
2624 \o Same \c z - children above parents:
2629 width: 100; height: 100
2632 x: 50; y: 50; width: 100; height: 100
2638 \o \image declarative-item_stacking4.png
2639 \o Lower \c z below:
2644 width: 100; height: 100
2648 x: 50; y: 50; width: 100; height: 100
2657 \qmlproperty bool QtQuick2::Item::visible
2659 This property holds whether the item is visible. By default this is true.
2661 Setting this property directly affects the \c visible value of child
2662 items. When set to \c false, the \c visible values of all child items also
2663 become \c false. When set to \c true, the \c visible values of child items
2664 are returned to \c true, unless they have explicitly been set to \c false.
2666 (Because of this flow-on behavior, using the \c visible property may not
2667 have the intended effect if a property binding should only respond to
2668 explicit property changes. In such cases it may be better to use the
2669 \l opacity property instead.)
2671 Setting this property to \c false automatically causes \l focus to be set
2672 to \c false, and this item will longer receive mouse and keyboard events.
2673 (In contrast, setting the \l opacity to 0 does not affect the \l focus
2674 property and the receiving of key events.)
2676 \note This property's value is only affected by changes to this property or
2677 the parent's \c visible property. It does not change, for example, if this
2678 item moves off-screen, or if the \l opacity changes to 0.
2683 \qmlproperty AnchorLine QtQuick2::Item::anchors.top
2684 \qmlproperty AnchorLine QtQuick2::Item::anchors.bottom
2685 \qmlproperty AnchorLine QtQuick2::Item::anchors.left
2686 \qmlproperty AnchorLine QtQuick2::Item::anchors.right
2687 \qmlproperty AnchorLine QtQuick2::Item::anchors.horizontalCenter
2688 \qmlproperty AnchorLine QtQuick2::Item::anchors.verticalCenter
2689 \qmlproperty AnchorLine QtQuick2::Item::anchors.baseline
2691 \qmlproperty Item QtQuick2::Item::anchors.fill
2692 \qmlproperty Item QtQuick2::Item::anchors.centerIn
2694 \qmlproperty real QtQuick2::Item::anchors.margins
2695 \qmlproperty real QtQuick2::Item::anchors.topMargin
2696 \qmlproperty real QtQuick2::Item::anchors.bottomMargin
2697 \qmlproperty real QtQuick2::Item::anchors.leftMargin
2698 \qmlproperty real QtQuick2::Item::anchors.rightMargin
2699 \qmlproperty real QtQuick2::Item::anchors.horizontalCenterOffset
2700 \qmlproperty real QtQuick2::Item::anchors.verticalCenterOffset
2701 \qmlproperty real QtQuick2::Item::anchors.baselineOffset
2703 \qmlproperty bool QtQuick2::Item::anchors.mirrored
2705 Anchors provide a way to position an item by specifying its
2706 relationship with other items.
2708 Margins apply to top, bottom, left, right, and fill anchors.
2709 The \c anchors.margins property can be used to set all of the various margins at once, to the same value.
2710 Note that margins are anchor-specific and are not applied if an item does not
2713 Offsets apply for horizontal center, vertical center, and baseline anchors.
2717 \o \image declarative-anchors_example.png
2718 \o Text anchored to Image, horizontally centered and vertically below, with a margin.
2727 anchors.horizontalCenter: pic.horizontalCenter
2728 anchors.top: pic.bottom
2729 anchors.topMargin: 5
2735 \o \image declarative-anchors_example2.png
2737 Left of Text anchored to right of Image, with a margin. The y
2738 property of both defaults to 0.
2748 anchors.left: pic.right
2749 anchors.leftMargin: 5
2756 \c anchors.fill provides a convenient way for one item to have the
2757 same geometry as another item, and is equivalent to connecting all
2758 four directional anchors.
2760 To clear an anchor value, set it to \c undefined.
2762 \c anchors.mirrored returns true it the layout has been \l {LayoutMirroring}{mirrored}.
2764 \note You can only anchor an item to siblings or a parent.
2766 For more information see \l {anchor-layout}{Anchor Layouts}.
2770 \property QQuickItem::baselineOffset
2771 \brief The position of the item's baseline in local coordinates.
2773 The baseline of a \l Text item is the imaginary line on which the text
2774 sits. Controls containing text usually set their baseline to the
2775 baseline of their text.
2777 For non-text items, a default baseline offset of 0 is used.
2779 QQuickAnchors *QQuickItemPrivate::anchors() const
2782 Q_Q(const QQuickItem);
2783 _anchors = new QQuickAnchors(const_cast<QQuickItem *>(q));
2784 if (!componentComplete)
2785 _anchors->classBegin();
2790 QQuickItemPrivate::AnchorLines *QQuickItemPrivate::anchorLines() const
2792 Q_Q(const QQuickItem);
2793 if (!_anchorLines) _anchorLines =
2794 new AnchorLines(const_cast<QQuickItem *>(q));
2795 return _anchorLines;
2798 void QQuickItemPrivate::siblingOrderChanged()
2801 for (int ii = 0; ii < changeListeners.count(); ++ii) {
2802 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
2803 if (change.types & QQuickItemPrivate::SiblingOrder) {
2804 change.listener->itemSiblingOrderChanged(q);
2809 QDeclarativeListProperty<QObject> QQuickItemPrivate::data()
2811 return QDeclarativeListProperty<QObject>(q_func(), 0, QQuickItemPrivate::data_append,
2812 QQuickItemPrivate::data_count,
2813 QQuickItemPrivate::data_at,
2814 QQuickItemPrivate::data_clear);
2817 QRectF QQuickItem::childrenRect()
2820 if (!d->_contents) {
2821 d->_contents = new QQuickContents(this);
2822 if (d->componentComplete)
2823 d->_contents->complete();
2825 return d->_contents->rectF();
2828 QList<QQuickItem *> QQuickItem::childItems() const
2830 Q_D(const QQuickItem);
2831 return d->childItems;
2834 bool QQuickItem::clip() const
2836 return flags() & ItemClipsChildrenToShape;
2839 void QQuickItem::setClip(bool c)
2844 setFlag(ItemClipsChildrenToShape, c);
2846 emit clipChanged(c);
2851 This function is called to handle this item's changes in
2852 geometry from \a oldGeometry to \a newGeometry. If the two
2853 geometries are the same, it doesn't do anything.
2855 void QQuickItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
2860 QQuickAnchorsPrivate::get(d->_anchors)->updateMe();
2862 bool xChange = (newGeometry.x() != oldGeometry.x());
2863 bool yChange = (newGeometry.y() != oldGeometry.y());
2864 bool widthChange = (newGeometry.width() != oldGeometry.width());
2865 bool heightChange = (newGeometry.height() != oldGeometry.height());
2867 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
2868 const QQuickItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
2869 if (change.types & QQuickItemPrivate::Geometry) {
2870 if (change.gTypes == QQuickItemPrivate::GeometryChange) {
2871 change.listener->itemGeometryChanged(this, newGeometry, oldGeometry);
2872 } else if ((xChange && (change.gTypes & QQuickItemPrivate::XChange)) ||
2873 (yChange && (change.gTypes & QQuickItemPrivate::YChange)) ||
2874 (widthChange && (change.gTypes & QQuickItemPrivate::WidthChange)) ||
2875 (heightChange && (change.gTypes & QQuickItemPrivate::HeightChange))) {
2876 change.listener->itemGeometryChanged(this, newGeometry, oldGeometry);
2886 emit widthChanged();
2888 emit heightChanged();
2892 Called by the rendering thread when it is time to sync the state of the QML objects with the
2893 scene graph objects. The function should return the root of the scene graph subtree for
2894 this item. \a oldNode is the node that was returned the last time the function was called.
2896 The main thread is blocked while this function is executed so it is safe to read
2897 values from the QQuickItem instance and other objects in the main thread.
2899 \warning This is the only function in which it is allowed to make use of scene graph
2900 objects from the main thread. Use of scene graph objects outside this function will
2901 result in race conditions and potential crashes.
2904 QSGNode *QQuickItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
2910 QSGTransformNode *QQuickItemPrivate::createTransformNode()
2912 return new QSGTransformNode;
2915 void QQuickItem::updatePolish()
2919 void QQuickItem::sendAccessibilityUpdate()
2924 void QQuickItemPrivate::removeItemChangeListener(QQuickItemChangeListener *listener, ChangeTypes types)
2926 ChangeListener change(listener, types);
2927 changeListeners.removeOne(change);
2930 void QQuickItemPrivate::updateOrAddGeometryChangeListener(QQuickItemChangeListener *listener, GeometryChangeTypes types)
2932 ChangeListener change(listener, types);
2933 int index = changeListeners.find(change);
2935 changeListeners[index].gTypes = change.gTypes; //we may have different GeometryChangeTypes
2937 changeListeners.append(change);
2940 void QQuickItemPrivate::updateOrRemoveGeometryChangeListener(QQuickItemChangeListener *listener, GeometryChangeTypes types)
2942 ChangeListener change(listener, types);
2943 if (types == NoChange) {
2944 changeListeners.removeOne(change);
2946 int index = changeListeners.find(change);
2948 changeListeners[index].gTypes = change.gTypes; //we may have different GeometryChangeTypes
2952 void QQuickItem::keyPressEvent(QKeyEvent *event)
2957 void QQuickItem::keyReleaseEvent(QKeyEvent *event)
2962 void QQuickItem::inputMethodEvent(QInputMethodEvent *event)
2967 void QQuickItem::focusInEvent(QFocusEvent *)
2969 QAccessible::updateAccessibility(this, 0, QAccessible::Focus);
2972 void QQuickItem::focusOutEvent(QFocusEvent *)
2976 void QQuickItem::mousePressEvent(QMouseEvent *event)
2981 void QQuickItem::mouseMoveEvent(QMouseEvent *event)
2986 void QQuickItem::mouseReleaseEvent(QMouseEvent *event)
2991 void QQuickItem::mouseDoubleClickEvent(QMouseEvent *event)
2993 mousePressEvent(event);
2996 void QQuickItem::mouseUngrabEvent()
3001 void QQuickItem::touchUngrabEvent()
3006 void QQuickItem::wheelEvent(QWheelEvent *event)
3011 void QQuickItem::touchEvent(QTouchEvent *event)
3016 void QQuickItem::hoverEnterEvent(QHoverEvent *event)
3021 void QQuickItem::hoverMoveEvent(QHoverEvent *event)
3026 void QQuickItem::hoverLeaveEvent(QHoverEvent *event)
3031 void QQuickItem::dragEnterEvent(QDragEnterEvent *event)
3036 void QQuickItem::dragMoveEvent(QDragMoveEvent *event)
3042 void QQuickItem::dragLeaveEvent(QDragLeaveEvent *event)
3048 void QQuickItem::dropEvent(QDropEvent *event)
3053 bool QQuickItem::childMouseEventFilter(QQuickItem *, QEvent *)
3058 void QQuickItem::windowDeactivateEvent()
3060 foreach (QQuickItem* item, childItems()) {
3061 item->windowDeactivateEvent();
3065 Qt::InputMethodHints QQuickItem::inputMethodHints() const
3067 Q_D(const QQuickItem);
3071 void QQuickItem::setInputMethodHints(Qt::InputMethodHints hints)
3076 if (!d->canvas || d->canvas->activeFocusItem() != this)
3079 QInputPanel *p = qApp->inputPanel();
3080 if (p->inputItem() == this)
3081 qApp->inputPanel()->update(Qt::ImHints);
3084 void QQuickItem::updateMicroFocus()
3086 QInputPanel *p = qApp->inputPanel();
3087 if (p->inputItem() == this)
3088 qApp->inputPanel()->update(Qt::ImQueryInput);
3091 QVariant QQuickItem::inputMethodQuery(Qt::InputMethodQuery query) const
3093 Q_D(const QQuickItem);
3098 v = (bool)(flags() & ItemAcceptsInputMethod);
3101 v = (int)inputMethodHints();
3103 case Qt::ImCursorRectangle:
3105 case Qt::ImCursorPosition:
3106 case Qt::ImSurroundingText:
3107 case Qt::ImCurrentSelection:
3108 case Qt::ImMaximumTextLength:
3109 case Qt::ImAnchorPosition:
3110 case Qt::ImPreferredLanguage:
3112 v = d->keyHandler->inputMethodQuery(query);
3120 QQuickAnchorLine QQuickItemPrivate::left() const
3122 return anchorLines()->left;
3125 QQuickAnchorLine QQuickItemPrivate::right() const
3127 return anchorLines()->right;
3130 QQuickAnchorLine QQuickItemPrivate::horizontalCenter() const
3132 return anchorLines()->hCenter;
3135 QQuickAnchorLine QQuickItemPrivate::top() const
3137 return anchorLines()->top;
3140 QQuickAnchorLine QQuickItemPrivate::bottom() const
3142 return anchorLines()->bottom;
3145 QQuickAnchorLine QQuickItemPrivate::verticalCenter() const
3147 return anchorLines()->vCenter;
3150 QQuickAnchorLine QQuickItemPrivate::baseline() const
3152 return anchorLines()->baseline;
3155 qreal QQuickItem::baselineOffset() const
3157 Q_D(const QQuickItem);
3158 if (!d->baselineOffset.isValid()) {
3161 return d->baselineOffset;
3164 void QQuickItem::setBaselineOffset(qreal offset)
3167 if (offset == d->baselineOffset)
3170 d->baselineOffset = offset;
3172 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
3173 const QQuickItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
3174 if (change.types & QQuickItemPrivate::Geometry) {
3175 QQuickAnchorsPrivate *anchor = change.listener->anchorPrivate();
3177 anchor->updateVerticalAnchors();
3180 emit baselineOffsetChanged(offset);
3183 void QQuickItem::update()
3186 Q_ASSERT(flags() & ItemHasContents);
3187 d->dirty(QQuickItemPrivate::Content);
3190 void QQuickItem::polish()
3193 if (!d->polishScheduled) {
3194 d->polishScheduled = true;
3196 QQuickCanvasPrivate *p = QQuickCanvasPrivate::get(d->canvas);
3197 bool maybeupdate = p->itemsToPolish.isEmpty();
3198 p->itemsToPolish.insert(this);
3199 if (maybeupdate) d->canvas->maybeUpdate();
3204 void QQuickItem::mapFromItem(QDeclarativeV8Function *args) const
3206 if (args->Length() != 0) {
3207 v8::Local<v8::Value> item = (*args)[0];
3208 QV8Engine *engine = args->engine();
3210 QQuickItem *itemObj = 0;
3211 if (!item->IsNull())
3212 itemObj = qobject_cast<QQuickItem*>(engine->toQObject(item));
3214 if (!itemObj && !item->IsNull()) {
3215 qmlInfo(this) << "mapFromItem() given argument \"" << engine->toString(item->ToString())
3216 << "\" which is neither null nor an Item";
3220 v8::Local<v8::Object> rv = v8::Object::New();
3221 args->returnValue(rv);
3223 qreal x = (args->Length() > 1)?(*args)[1]->NumberValue():0;
3224 qreal y = (args->Length() > 2)?(*args)[2]->NumberValue():0;
3226 QPointF p = mapFromItem(itemObj, QPointF(x, y));
3228 rv->Set(v8::String::New("x"), v8::Number::New(p.x()));
3229 rv->Set(v8::String::New("y"), v8::Number::New(p.y()));
3233 QTransform QQuickItem::itemTransform(QQuickItem *other, bool *ok) const
3235 Q_D(const QQuickItem);
3237 // XXX todo - we need to be able to handle common parents better and detect
3241 QTransform t = d->itemToCanvasTransform();
3242 if (other) t *= QQuickItemPrivate::get(other)->canvasToItemTransform();
3247 void QQuickItem::mapToItem(QDeclarativeV8Function *args) const
3249 if (args->Length() != 0) {
3250 v8::Local<v8::Value> item = (*args)[0];
3251 QV8Engine *engine = args->engine();
3253 QQuickItem *itemObj = 0;
3254 if (!item->IsNull())
3255 itemObj = qobject_cast<QQuickItem*>(engine->toQObject(item));
3257 if (!itemObj && !item->IsNull()) {
3258 qmlInfo(this) << "mapToItem() given argument \"" << engine->toString(item->ToString())
3259 << "\" which is neither null nor an Item";
3263 v8::Local<v8::Object> rv = v8::Object::New();
3264 args->returnValue(rv);
3266 qreal x = (args->Length() > 1)?(*args)[1]->NumberValue():0;
3267 qreal y = (args->Length() > 2)?(*args)[2]->NumberValue():0;
3269 QPointF p = mapToItem(itemObj, QPointF(x, y));
3271 rv->Set(v8::String::New("x"), v8::Number::New(p.x()));
3272 rv->Set(v8::String::New("y"), v8::Number::New(p.y()));
3276 void QQuickItem::forceActiveFocus()
3279 QQuickItem *parent = parentItem();
3281 if (parent->flags() & QQuickItem::ItemIsFocusScope) {
3282 parent->setFocus(true);
3284 parent = parent->parentItem();
3288 QQuickItem *QQuickItem::childAt(qreal x, qreal y) const
3290 // XXX todo - should this include transform etc.?
3291 const QList<QQuickItem *> children = childItems();
3292 for (int i = children.count()-1; i >= 0; --i) {
3293 QQuickItem *child = children.at(i);
3294 if (child->isVisible() && child->x() <= x
3295 && child->x() + child->width() >= x
3297 && child->y() + child->height() >= y)
3303 QDeclarativeListProperty<QObject> QQuickItemPrivate::resources()
3305 return QDeclarativeListProperty<QObject>(q_func(), 0, QQuickItemPrivate::resources_append,
3306 QQuickItemPrivate::resources_count,
3307 QQuickItemPrivate::resources_at,
3308 QQuickItemPrivate::resources_clear);
3311 QDeclarativeListProperty<QQuickItem> QQuickItemPrivate::children()
3313 return QDeclarativeListProperty<QQuickItem>(q_func(), 0, QQuickItemPrivate::children_append,
3314 QQuickItemPrivate::children_count,
3315 QQuickItemPrivate::children_at,
3316 QQuickItemPrivate::children_clear);
3320 QDeclarativeListProperty<QDeclarativeState> QQuickItemPrivate::states()
3322 return _states()->statesProperty();
3325 QDeclarativeListProperty<QDeclarativeTransition> QQuickItemPrivate::transitions()
3327 return _states()->transitionsProperty();
3330 QString QQuickItemPrivate::state() const
3335 return _stateGroup->state();
3338 void QQuickItemPrivate::setState(const QString &state)
3340 _states()->setState(state);
3343 QString QQuickItem::state() const
3345 Q_D(const QQuickItem);
3349 void QQuickItem::setState(const QString &state)
3355 QDeclarativeListProperty<QQuickTransform> QQuickItem::transform()
3357 return QDeclarativeListProperty<QQuickTransform>(this, 0, QQuickItemPrivate::transform_append,
3358 QQuickItemPrivate::transform_count,
3359 QQuickItemPrivate::transform_at,
3360 QQuickItemPrivate::transform_clear);
3363 void QQuickItem::classBegin()
3366 d->componentComplete = false;
3368 d->_stateGroup->classBegin();
3370 d->_anchors->classBegin();
3373 void QQuickItem::componentComplete()
3376 d->componentComplete = true;
3378 d->_stateGroup->componentComplete();
3380 d->_anchors->componentComplete();
3381 QQuickAnchorsPrivate::get(d->_anchors)->updateOnComplete();
3384 d->keyHandler->componentComplete();
3386 d->_contents->complete();
3389 QDeclarativeStateGroup *QQuickItemPrivate::_states()
3393 _stateGroup = new QDeclarativeStateGroup;
3394 if (!componentComplete)
3395 _stateGroup->classBegin();
3396 FAST_CONNECT(_stateGroup, SIGNAL(stateChanged(QString)),
3397 q, SIGNAL(stateChanged(QString)))
3403 QQuickItemPrivate::AnchorLines::AnchorLines(QQuickItem *q)
3406 left.anchorLine = QQuickAnchorLine::Left;
3408 right.anchorLine = QQuickAnchorLine::Right;
3410 hCenter.anchorLine = QQuickAnchorLine::HCenter;
3412 top.anchorLine = QQuickAnchorLine::Top;
3414 bottom.anchorLine = QQuickAnchorLine::Bottom;
3416 vCenter.anchorLine = QQuickAnchorLine::VCenter;
3418 baseline.anchorLine = QQuickAnchorLine::Baseline;
3421 QPointF QQuickItemPrivate::computeTransformOrigin() const
3425 case QQuickItem::TopLeft:
3426 return QPointF(0, 0);
3427 case QQuickItem::Top:
3428 return QPointF(width / 2., 0);
3429 case QQuickItem::TopRight:
3430 return QPointF(width, 0);
3431 case QQuickItem::Left:
3432 return QPointF(0, height / 2.);
3433 case QQuickItem::Center:
3434 return QPointF(width / 2., height / 2.);
3435 case QQuickItem::Right:
3436 return QPointF(width, height / 2.);
3437 case QQuickItem::BottomLeft:
3438 return QPointF(0, height);
3439 case QQuickItem::Bottom:
3440 return QPointF(width / 2., height);
3441 case QQuickItem::BottomRight:
3442 return QPointF(width, height);
3446 void QQuickItemPrivate::transformChanged()
3450 void QQuickItemPrivate::deliverKeyEvent(QKeyEvent *e)
3454 Q_ASSERT(e->isAccepted());
3456 if (e->type() == QEvent::KeyPress)
3457 keyHandler->keyPressed(e, false);
3459 keyHandler->keyReleased(e, false);
3461 if (e->isAccepted())
3467 if (e->type() == QEvent::KeyPress)
3468 q->keyPressEvent(e);
3470 q->keyReleaseEvent(e);
3472 if (e->isAccepted())
3478 if (e->type() == QEvent::KeyPress)
3479 keyHandler->keyPressed(e, true);
3481 keyHandler->keyReleased(e, true);
3485 void QQuickItemPrivate::deliverInputMethodEvent(QInputMethodEvent *e)
3489 Q_ASSERT(e->isAccepted());
3491 keyHandler->inputMethodEvent(e, false);
3493 if (e->isAccepted())
3499 q->inputMethodEvent(e);
3501 if (e->isAccepted())
3507 keyHandler->inputMethodEvent(e, true);
3511 void QQuickItemPrivate::deliverFocusEvent(QFocusEvent *e)
3515 if (e->type() == QEvent::FocusIn) {
3518 q->focusOutEvent(e);
3522 void QQuickItemPrivate::deliverMouseEvent(QMouseEvent *e)
3526 Q_ASSERT(e->isAccepted());
3528 switch (e->type()) {
3530 Q_ASSERT(!"Unknown event type");
3531 case QEvent::MouseMove:
3532 q->mouseMoveEvent(e);
3534 case QEvent::MouseButtonPress:
3535 q->mousePressEvent(e);
3537 case QEvent::MouseButtonRelease:
3538 q->mouseReleaseEvent(e);
3540 case QEvent::MouseButtonDblClick:
3541 q->mouseDoubleClickEvent(e);
3546 void QQuickItemPrivate::deliverWheelEvent(QWheelEvent *e)
3552 void QQuickItemPrivate::deliverTouchEvent(QTouchEvent *e)
3558 void QQuickItemPrivate::deliverHoverEvent(QHoverEvent *e)
3561 switch (e->type()) {
3563 Q_ASSERT(!"Unknown event type");
3564 case QEvent::HoverEnter:
3565 q->hoverEnterEvent(e);
3567 case QEvent::HoverLeave:
3568 q->hoverLeaveEvent(e);
3570 case QEvent::HoverMove:
3571 q->hoverMoveEvent(e);
3576 void QQuickItemPrivate::deliverDragEvent(QEvent *e)
3579 switch (e->type()) {
3581 Q_ASSERT(!"Unknown event type");
3582 case QEvent::DragEnter:
3583 q->dragEnterEvent(static_cast<QDragEnterEvent *>(e));
3585 case QEvent::DragLeave:
3586 q->dragLeaveEvent(static_cast<QDragLeaveEvent *>(e));
3588 case QEvent::DragMove:
3589 q->dragMoveEvent(static_cast<QDragMoveEvent *>(e));
3592 q->dropEvent(static_cast<QDropEvent *>(e));
3597 void QQuickItem::itemChange(ItemChange change, const ItemChangeData &value)
3604 // XXX todo - do we want/need this anymore?
3605 // Note that it's now used for varying clip rect
3606 QRectF QQuickItem::boundingRect() const
3608 Q_D(const QQuickItem);
3609 return QRectF(0, 0, d->width, d->height);
3612 QQuickItem::TransformOrigin QQuickItem::transformOrigin() const
3614 Q_D(const QQuickItem);
3618 void QQuickItem::setTransformOrigin(TransformOrigin origin)
3621 if (origin == d->origin)
3625 d->dirty(QQuickItemPrivate::TransformOrigin);
3627 emit transformOriginChanged(d->origin);
3630 QPointF QQuickItem::transformOriginPoint() const
3632 Q_D(const QQuickItem);
3633 if (!d->transformOriginPoint.isNull())
3634 return d->transformOriginPoint;
3635 return d->computeTransformOrigin();
3638 void QQuickItem::setTransformOriginPoint(const QPointF &point)
3641 if (d->transformOriginPoint == point)
3644 d->transformOriginPoint = point;
3645 d->dirty(QQuickItemPrivate::TransformOrigin);
3648 qreal QQuickItem::z() const
3650 Q_D(const QQuickItem);
3654 void QQuickItem::setZ(qreal v)
3662 d->dirty(QQuickItemPrivate::ZValue);
3663 if (d->parentItem) {
3664 QQuickItemPrivate::get(d->parentItem)->dirty(QQuickItemPrivate::ChildrenStackingChanged);
3665 QQuickItemPrivate::get(d->parentItem)->markSortedChildrenDirty(this);
3673 \qmlproperty real QtQuick2::Item::rotation
3674 This property holds the rotation of the item in degrees clockwise.
3676 This specifies how many degrees to rotate the item around its transformOrigin.
3677 The default rotation is 0 degrees (i.e. not rotated at all).
3681 \o \image declarative-rotation.png
3686 width: 100; height: 100
3689 x: 25; y: 25; width: 50; height: 50
3696 \sa transform, Rotation
3700 \qmlproperty real QtQuick2::Item::scale
3701 This property holds the scale of the item.
3703 A scale of less than 1 means the item will be displayed smaller than
3704 normal, and a scale of greater than 1 means the item will be
3705 displayed larger than normal. A negative scale means the item will
3708 By default, items are displayed at a scale of 1 (i.e. at their
3711 Scaling is from the item's transformOrigin.
3715 \o \image declarative-scale.png
3720 width: 100; height: 100
3723 width: 25; height: 25
3727 x: 25; y: 25; width: 50; height: 50
3734 \sa transform, Scale
3738 \qmlproperty real QtQuick2::Item::opacity
3740 This property holds the opacity of the item. Opacity is specified as a
3741 number between 0 (fully transparent) and 1 (fully opaque). The default is 1.
3743 When this property is set, the specified opacity is also applied
3744 individually to child items. In almost all cases this is what you want,
3745 but in some cases it may produce undesired results. For example in the
3746 second set of rectangles below, the red rectangle has specified an opacity
3747 of 0.5, which affects the opacity of its blue child rectangle even though
3748 the child has not specified an opacity.
3752 \o \image declarative-item_opacity1.png
3758 width: 100; height: 100
3761 x: 50; y: 50; width: 100; height: 100
3767 \o \image declarative-item_opacity2.png
3774 width: 100; height: 100
3777 x: 50; y: 50; width: 100; height: 100
3784 If an item's opacity is set to 0, the item will no longer receive mouse
3785 events, but will continue to receive key events and will retain the keyboard
3786 \l focus if it has been set. (In contrast, setting the \l visible property
3787 to \c false stops both mouse and keyboard events, and also removes focus
3792 Returns a value indicating whether mouse input should
3793 remain with this item exclusively.
3795 \sa setKeepMouseGrab()
3798 qreal QQuickItem::rotation() const
3800 Q_D(const QQuickItem);
3804 void QQuickItem::setRotation(qreal r)
3807 if (d->rotation == r)
3812 d->dirty(QQuickItemPrivate::BasicTransform);
3814 d->itemChange(ItemRotationHasChanged, r);
3816 emit rotationChanged();
3819 qreal QQuickItem::scale() const
3821 Q_D(const QQuickItem);
3825 void QQuickItem::setScale(qreal s)
3833 d->dirty(QQuickItemPrivate::BasicTransform);
3835 emit scaleChanged();
3838 qreal QQuickItem::opacity() const
3840 Q_D(const QQuickItem);
3844 void QQuickItem::setOpacity(qreal o)
3847 if (d->opacity == o)
3852 d->dirty(QQuickItemPrivate::OpacityValue);
3854 d->itemChange(ItemOpacityHasChanged, o);
3856 emit opacityChanged();
3859 bool QQuickItem::isVisible() const
3861 Q_D(const QQuickItem);
3862 return d->effectiveVisible;
3865 void QQuickItem::setVisible(bool v)
3868 if (v == d->explicitVisible)
3871 d->explicitVisible = v;
3873 d->setEffectiveVisibleRecur(d->calcEffectiveVisible());
3876 bool QQuickItem::isEnabled() const
3878 Q_D(const QQuickItem);
3879 return d->effectiveEnable;
3882 void QQuickItem::setEnabled(bool e)
3885 if (e == d->explicitEnable)
3888 d->explicitEnable = e;
3890 d->setEffectiveEnableRecur(d->calcEffectiveEnable());
3893 bool QQuickItemPrivate::calcEffectiveVisible() const
3895 // XXX todo - Should the effective visible of an element with no parent just be the current
3896 // effective visible? This would prevent pointless re-processing in the case of an element
3897 // moving to/from a no-parent situation, but it is different from what graphics view does.
3898 return explicitVisible && (!parentItem || QQuickItemPrivate::get(parentItem)->effectiveVisible);
3901 void QQuickItemPrivate::setEffectiveVisibleRecur(bool newEffectiveVisible)
3905 if (newEffectiveVisible && !explicitVisible) {
3906 // This item locally overrides visibility
3910 if (newEffectiveVisible == effectiveVisible) {
3911 // No change necessary
3915 effectiveVisible = newEffectiveVisible;
3917 if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
3920 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(canvas);
3921 if (canvasPriv->mouseGrabberItem == q)
3925 for (int ii = 0; ii < childItems.count(); ++ii)
3926 QQuickItemPrivate::get(childItems.at(ii))->setEffectiveVisibleRecur(newEffectiveVisible);
3928 for (int ii = 0; ii < changeListeners.count(); ++ii) {
3929 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
3930 if (change.types & QQuickItemPrivate::Visibility)
3931 change.listener->itemVisibilityChanged(q);
3935 QAccessible::updateAccessibility(q, 0, effectiveVisible ? QAccessible::ObjectShow : QAccessible::ObjectHide );
3937 emit q->visibleChanged();
3940 bool QQuickItemPrivate::calcEffectiveEnable() const
3942 // XXX todo - Should the effective enable of an element with no parent just be the current
3943 // effective enable? This would prevent pointless re-processing in the case of an element
3944 // moving to/from a no-parent situation, but it is different from what graphics view does.
3945 return explicitEnable && (!parentItem || QQuickItemPrivate::get(parentItem)->effectiveEnable);
3948 void QQuickItemPrivate::setEffectiveEnableRecur(bool newEffectiveEnable)
3952 // XXX todo - need to fixup focus
3954 if (newEffectiveEnable && !explicitEnable) {
3955 // This item locally overrides enable
3959 if (newEffectiveEnable == effectiveEnable) {
3960 // No change necessary
3964 effectiveEnable = newEffectiveEnable;
3967 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(canvas);
3968 if (canvasPriv->mouseGrabberItem == q)
3972 for (int ii = 0; ii < childItems.count(); ++ii)
3973 QQuickItemPrivate::get(childItems.at(ii))->setEffectiveEnableRecur(newEffectiveEnable);
3975 emit q->enabledChanged();
3978 QString QQuickItemPrivate::dirtyToString() const
3980 #define DIRTY_TO_STRING(value) if (dirtyAttributes & value) { \
3981 if (!rv.isEmpty()) \
3982 rv.append(QLatin1String("|")); \
3983 rv.append(QLatin1String(#value)); \
3986 // QString rv = QLatin1String("0x") + QString::number(dirtyAttributes, 16);
3989 DIRTY_TO_STRING(TransformOrigin);
3990 DIRTY_TO_STRING(Transform);
3991 DIRTY_TO_STRING(BasicTransform);
3992 DIRTY_TO_STRING(Position);
3993 DIRTY_TO_STRING(Size);
3994 DIRTY_TO_STRING(ZValue);
3995 DIRTY_TO_STRING(Content);
3996 DIRTY_TO_STRING(Smooth);
3997 DIRTY_TO_STRING(OpacityValue);
3998 DIRTY_TO_STRING(ChildrenChanged);
3999 DIRTY_TO_STRING(ChildrenStackingChanged);
4000 DIRTY_TO_STRING(ParentChanged);
4001 DIRTY_TO_STRING(Clip);
4002 DIRTY_TO_STRING(Canvas);
4003 DIRTY_TO_STRING(EffectReference);
4004 DIRTY_TO_STRING(Visible);
4005 DIRTY_TO_STRING(HideReference);
4006 DIRTY_TO_STRING(PerformanceHints);
4011 void QQuickItemPrivate::dirty(DirtyType type)
4014 if (type & (TransformOrigin | Transform | BasicTransform | Position | Size))
4017 if (!(dirtyAttributes & type) || (canvas && !prevDirtyItem)) {
4018 dirtyAttributes |= type;
4021 QQuickCanvasPrivate::get(canvas)->dirtyItem(q);
4026 void QQuickItemPrivate::addToDirtyList()
4031 if (!prevDirtyItem) {
4032 Q_ASSERT(!nextDirtyItem);
4034 QQuickCanvasPrivate *p = QQuickCanvasPrivate::get(canvas);
4035 nextDirtyItem = p->dirtyItemList;
4036 if (nextDirtyItem) QQuickItemPrivate::get(nextDirtyItem)->prevDirtyItem = &nextDirtyItem;
4037 prevDirtyItem = &p->dirtyItemList;
4038 p->dirtyItemList = q;
4041 Q_ASSERT(prevDirtyItem);
4044 void QQuickItemPrivate::removeFromDirtyList()
4046 if (prevDirtyItem) {
4047 if (nextDirtyItem) QQuickItemPrivate::get(nextDirtyItem)->prevDirtyItem = prevDirtyItem;
4048 *prevDirtyItem = nextDirtyItem;
4052 Q_ASSERT(!prevDirtyItem);
4053 Q_ASSERT(!nextDirtyItem);
4056 void QQuickItemPrivate::refFromEffectItem(bool hide)
4059 if (1 == effectRefCount) {
4060 dirty(EffectReference);
4061 if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
4064 if (++hideRefCount == 1)
4065 dirty(HideReference);
4069 void QQuickItemPrivate::derefFromEffectItem(bool unhide)
4071 Q_ASSERT(effectRefCount);
4073 if (0 == effectRefCount) {
4074 dirty(EffectReference);
4075 if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
4078 if (--hideRefCount == 0)
4079 dirty(HideReference);
4083 void QQuickItemPrivate::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data)
4087 case QQuickItem::ItemChildAddedChange:
4088 q->itemChange(change, data);
4089 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4090 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4091 if (change.types & QQuickItemPrivate::Children) {
4092 change.listener->itemChildAdded(q, data.item);
4096 case QQuickItem::ItemChildRemovedChange:
4097 q->itemChange(change, data);
4098 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4099 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4100 if (change.types & QQuickItemPrivate::Children) {
4101 change.listener->itemChildRemoved(q, data.item);
4105 case QQuickItem::ItemSceneChange:
4106 q->itemChange(change, data);
4108 case QQuickItem::ItemVisibleHasChanged:
4109 q->itemChange(change, data);
4110 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4111 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4112 if (change.types & QQuickItemPrivate::Visibility) {
4113 change.listener->itemVisibilityChanged(q);
4117 case QQuickItem::ItemParentHasChanged:
4118 q->itemChange(change, data);
4119 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4120 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4121 if (change.types & QQuickItemPrivate::Parent) {
4122 change.listener->itemParentChanged(q, data.item);
4126 case QQuickItem::ItemOpacityHasChanged:
4127 q->itemChange(change, data);
4128 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4129 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4130 if (change.types & QQuickItemPrivate::Opacity) {
4131 change.listener->itemOpacityChanged(q);
4135 case QQuickItem::ItemActiveFocusHasChanged:
4136 q->itemChange(change, data);
4138 case QQuickItem::ItemRotationHasChanged:
4139 q->itemChange(change, data);
4140 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4141 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4142 if (change.types & QQuickItemPrivate::Rotation) {
4143 change.listener->itemRotationChanged(q);
4151 \property QQuickItem::smooth
4152 \brief whether the item is smoothly transformed.
4154 This property is provided purely for the purpose of optimization. Turning
4155 smooth transforms off is faster, but looks worse; turning smooth
4156 transformations on is slower, but looks better.
4158 By default smooth transformations are off.
4162 Returns true if the item should be drawn with antialiasing and
4163 smooth pixmap filtering, false otherwise.
4165 The default is false.
4169 bool QQuickItem::smooth() const
4171 Q_D(const QQuickItem);
4176 Sets whether the item should be drawn with antialiasing and
4177 smooth pixmap filtering to \a smooth.
4181 void QQuickItem::setSmooth(bool smooth)
4184 if (d->smooth == smooth)
4188 d->dirty(QQuickItemPrivate::Smooth);
4190 emit smoothChanged(smooth);
4193 QQuickItem::Flags QQuickItem::flags() const
4195 Q_D(const QQuickItem);
4196 return (QQuickItem::Flags)d->flags;
4199 void QQuickItem::setFlag(Flag flag, bool enabled)
4203 setFlags((Flags)(d->flags | (quint32)flag));
4205 setFlags((Flags)(d->flags & ~(quint32)flag));
4208 void QQuickItem::setFlags(Flags flags)
4212 if ((flags & ItemIsFocusScope) != (d->flags & ItemIsFocusScope)) {
4213 if (flags & ItemIsFocusScope && !d->childItems.isEmpty() && d->canvas) {
4214 qWarning("QQuickItem: Cannot set FocusScope once item has children and is in a canvas.");
4215 flags &= ~ItemIsFocusScope;
4216 } else if (d->flags & ItemIsFocusScope) {
4217 qWarning("QQuickItem: Cannot unset FocusScope flag.");
4218 flags |= ItemIsFocusScope;
4222 if ((flags & ItemClipsChildrenToShape ) != (d->flags & ItemClipsChildrenToShape))
4223 d->dirty(QQuickItemPrivate::Clip);
4228 qreal QQuickItem::x() const
4230 Q_D(const QQuickItem);
4234 qreal QQuickItem::y() const
4236 Q_D(const QQuickItem);
4240 QPointF QQuickItem::pos() const
4242 Q_D(const QQuickItem);
4243 return QPointF(d->x, d->y);
4246 void QQuickItem::setX(qreal v)
4255 d->dirty(QQuickItemPrivate::Position);
4257 geometryChanged(QRectF(x(), y(), width(), height()),
4258 QRectF(oldx, y(), width(), height()));
4261 void QQuickItem::setY(qreal v)
4270 d->dirty(QQuickItemPrivate::Position);
4272 geometryChanged(QRectF(x(), y(), width(), height()),
4273 QRectF(x(), oldy, width(), height()));
4276 void QQuickItem::setPos(const QPointF &pos)
4279 if (QPointF(d->x, d->y) == pos)
4288 d->dirty(QQuickItemPrivate::Position);
4290 geometryChanged(QRectF(x(), y(), width(), height()),
4291 QRectF(oldx, oldy, width(), height()));
4294 qreal QQuickItem::width() const
4296 Q_D(const QQuickItem);
4300 void QQuickItem::setWidth(qreal w)
4306 d->widthValid = true;
4310 qreal oldWidth = d->width;
4313 d->dirty(QQuickItemPrivate::Size);
4315 geometryChanged(QRectF(x(), y(), width(), height()),
4316 QRectF(x(), y(), oldWidth, height()));
4319 void QQuickItem::resetWidth()
4322 d->widthValid = false;
4323 setImplicitWidth(implicitWidth());
4326 void QQuickItemPrivate::implicitWidthChanged()
4329 emit q->implicitWidthChanged();
4332 qreal QQuickItemPrivate::getImplicitWidth() const
4334 return implicitWidth;
4337 Returns the width of the item that is implied by other properties that determine the content.
4339 qreal QQuickItem::implicitWidth() const
4341 Q_D(const QQuickItem);
4342 return d->getImplicitWidth();
4346 \qmlproperty real QtQuick2::Item::implicitWidth
4347 \qmlproperty real QtQuick2::Item::implicitHeight
4349 Defines the natural width or height of the Item if no \l width or \l height is specified.
4351 The default implicit size for most items is 0x0, however some elements have an inherent
4352 implicit size which cannot be overridden, e.g. Image, Text.
4354 Setting the implicit size is useful for defining components that have a preferred size
4355 based on their content, for example:
4362 property alias icon: image.source
4363 property alias label: text.text
4364 implicitWidth: text.implicitWidth + image.implicitWidth
4365 implicitHeight: Math.max(text.implicitHeight, image.implicitHeight)
4370 anchors.left: image.right; anchors.right: parent.right
4371 anchors.verticalCenter: parent.verticalCenter
4376 \bold Note: using implicitWidth of Text or TextEdit and setting the width explicitly
4377 incurs a performance penalty as the text must be laid out twice.
4381 Sets the implied width of the item to \a w.
4382 This is the width implied by other properties that determine the content.
4384 void QQuickItem::setImplicitWidth(qreal w)
4387 bool changed = w != d->implicitWidth;
4388 d->implicitWidth = w;
4389 if (d->width == w || widthValid()) {
4391 d->implicitWidthChanged();
4395 qreal oldWidth = d->width;
4398 d->dirty(QQuickItemPrivate::Size);
4400 geometryChanged(QRectF(x(), y(), width(), height()),
4401 QRectF(x(), y(), oldWidth, height()));
4404 d->implicitWidthChanged();
4408 Returns whether the width property has been set explicitly.
4410 bool QQuickItem::widthValid() const
4412 Q_D(const QQuickItem);
4413 return d->widthValid;
4416 qreal QQuickItem::height() const
4418 Q_D(const QQuickItem);
4422 void QQuickItem::setHeight(qreal h)
4428 d->heightValid = true;
4432 qreal oldHeight = d->height;
4435 d->dirty(QQuickItemPrivate::Size);
4437 geometryChanged(QRectF(x(), y(), width(), height()),
4438 QRectF(x(), y(), width(), oldHeight));
4441 void QQuickItem::resetHeight()
4444 d->heightValid = false;
4445 setImplicitHeight(implicitHeight());
4448 void QQuickItemPrivate::implicitHeightChanged()
4451 emit q->implicitHeightChanged();
4454 qreal QQuickItemPrivate::getImplicitHeight() const
4456 return implicitHeight;
4460 Returns the height of the item that is implied by other properties that determine the content.
4462 qreal QQuickItem::implicitHeight() const
4464 Q_D(const QQuickItem);
4465 return d->getImplicitHeight();
4470 Sets the implied height of the item to \a h.
4471 This is the height implied by other properties that determine the content.
4473 void QQuickItem::setImplicitHeight(qreal h)
4476 bool changed = h != d->implicitHeight;
4477 d->implicitHeight = h;
4478 if (d->height == h || heightValid()) {
4480 d->implicitHeightChanged();
4484 qreal oldHeight = d->height;
4487 d->dirty(QQuickItemPrivate::Size);
4489 geometryChanged(QRectF(x(), y(), width(), height()),
4490 QRectF(x(), y(), width(), oldHeight));
4493 d->implicitHeightChanged();
4496 void QQuickItem::setImplicitSize(qreal w, qreal h)
4499 bool wChanged = w != d->implicitWidth;
4500 bool hChanged = h != d->implicitHeight;
4502 d->implicitWidth = w;
4503 d->implicitHeight = h;
4507 if (d->width == w || widthValid()) {
4509 d->implicitWidthChanged();
4512 if (d->height == h || heightValid()) {
4514 d->implicitHeightChanged();
4520 qreal oldWidth = d->width;
4521 qreal oldHeight = d->height;
4527 d->dirty(QQuickItemPrivate::Size);
4529 geometryChanged(QRectF(x(), y(), width(), height()),
4530 QRectF(x(), y(), oldWidth, oldHeight));
4532 if (!wDone && wChanged)
4533 d->implicitWidthChanged();
4534 if (!hDone && hChanged)
4535 d->implicitHeightChanged();
4539 Returns whether the height property has been set explicitly.
4541 bool QQuickItem::heightValid() const
4543 Q_D(const QQuickItem);
4544 return d->heightValid;
4547 void QQuickItem::setSize(const QSizeF &size)
4550 d->heightValid = true;
4551 d->widthValid = true;
4553 if (QSizeF(d->width, d->height) == size)
4556 qreal oldHeight = d->height;
4557 qreal oldWidth = d->width;
4558 d->height = size.height();
4559 d->width = size.width();
4561 d->dirty(QQuickItemPrivate::Size);
4563 geometryChanged(QRectF(x(), y(), width(), height()),
4564 QRectF(x(), y(), oldWidth, oldHeight));
4567 bool QQuickItem::hasActiveFocus() const
4569 Q_D(const QQuickItem);
4570 return d->activeFocus;
4573 bool QQuickItem::hasFocus() const
4575 Q_D(const QQuickItem);
4579 void QQuickItem::setFocus(bool focus)
4582 if (d->focus == focus)
4586 // Need to find our nearest focus scope
4587 QQuickItem *scope = parentItem();
4588 while (scope && !scope->isFocusScope())
4589 scope = scope->parentItem();
4591 QQuickCanvasPrivate::get(d->canvas)->setFocusInScope(scope, this);
4593 QQuickCanvasPrivate::get(d->canvas)->clearFocusInScope(scope, this);
4596 emit focusChanged(focus);
4600 bool QQuickItem::isFocusScope() const
4602 return flags() & ItemIsFocusScope;
4605 QQuickItem *QQuickItem::scopedFocusItem() const
4607 Q_D(const QQuickItem);
4608 if (!isFocusScope())
4611 return d->subFocusItem;
4615 Qt::MouseButtons QQuickItem::acceptedMouseButtons() const
4617 Q_D(const QQuickItem);
4618 return d->acceptedMouseButtons;
4621 void QQuickItem::setAcceptedMouseButtons(Qt::MouseButtons buttons)
4624 d->acceptedMouseButtons = buttons;
4627 bool QQuickItem::filtersChildMouseEvents() const
4629 Q_D(const QQuickItem);
4630 return d->filtersChildMouseEvents;
4633 void QQuickItem::setFiltersChildMouseEvents(bool filter)
4636 d->filtersChildMouseEvents = filter;
4639 bool QQuickItem::isUnderMouse() const
4641 Q_D(const QQuickItem);
4645 QPoint cursorPos = QCursor::pos();
4646 if (QRectF(0, 0, width(), height()).contains(mapFromScene(cursorPos))) // ### refactor: d->canvas->mapFromGlobal(cursorPos))))
4651 bool QQuickItem::acceptHoverEvents() const
4653 Q_D(const QQuickItem);
4654 return d->hoverEnabled;
4657 void QQuickItem::setAcceptHoverEvents(bool enabled)
4660 d->hoverEnabled = enabled;
4663 void QQuickItem::grabMouse()
4668 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
4669 if (canvasPriv->mouseGrabberItem == this)
4672 QQuickItem *oldGrabber = canvasPriv->mouseGrabberItem;
4673 canvasPriv->mouseGrabberItem = this;
4675 oldGrabber->mouseUngrabEvent();
4678 void QQuickItem::ungrabMouse()
4683 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
4684 if (canvasPriv->mouseGrabberItem != this) {
4685 qWarning("QQuickItem::ungrabMouse(): Item is not the mouse grabber.");
4689 canvasPriv->mouseGrabberItem = 0;
4693 bool QQuickItem::keepMouseGrab() const
4695 Q_D(const QQuickItem);
4696 return d->keepMouse;
4700 The flag indicating whether the mouse should remain
4701 with this item is set to \a keep.
4703 This is useful for items that wish to grab and keep mouse
4704 interaction following a predefined gesture. For example,
4705 an item that is interested in horizontal mouse movement
4706 may set keepMouseGrab to true once a threshold has been
4707 exceeded. Once keepMouseGrab has been set to true, filtering
4708 items will not react to mouse events.
4710 If the item does not indicate that it wishes to retain mouse grab,
4711 a filtering item may steal the grab. For example, Flickable may attempt
4712 to steal a mouse grab if it detects that the user has begun to
4717 void QQuickItem::setKeepMouseGrab(bool keep)
4720 d->keepMouse = keep;
4724 Grabs the touch points specified by \a ids.
4726 These touch points will be owned by the item until
4727 they are released. Alternatively, the grab can be stolen
4728 by a filtering item like Flickable. Use setKeepTouchGrab()
4729 to prevent the grab from being stolen.
4731 \sa ungrabTouchPoints(), setKeepTouchGrab()
4733 void QQuickItem::grabTouchPoints(const QList<int> &ids)
4738 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
4740 QSet<QQuickItem*> ungrab;
4741 for (int i = 0; i < ids.count(); ++i) {
4742 QQuickItem *oldGrabber = canvasPriv->itemForTouchPointId.value(ids.at(i));
4743 if (oldGrabber == this)
4746 canvasPriv->itemForTouchPointId[ids.at(i)] = this;
4748 ungrab.insert(oldGrabber);
4750 foreach (QQuickItem *oldGrabber, ungrab)
4751 oldGrabber->touchUngrabEvent();
4755 Ungrabs the touch points owned by this item.
4757 \sa grabTouchPoints()
4759 void QQuickItem::ungrabTouchPoints()
4764 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
4766 QMutableHashIterator<int, QQuickItem*> i(canvasPriv->itemForTouchPointId);
4767 while (i.hasNext()) {
4769 if (i.value() == this)
4776 Returns a value indicating whether the touch points grabbed by this item
4777 should remain with this item exclusively.
4779 \sa setKeepTouchGrab(), keepMouseGrab()
4781 bool QQuickItem::keepTouchGrab() const
4783 Q_D(const QQuickItem);
4784 return d->keepTouch;
4788 The flag indicating whether the touch points grabbed
4789 by this item should remain with this item is set to \a keep.
4791 This is useful for items that wish to grab and keep specific touch
4792 points following a predefined gesture. For example,
4793 an item that is interested in horizontal touch point movement
4794 may set setKeepTouchGrab to true once a threshold has been
4795 exceeded. Once setKeepTouchGrab has been set to true, filtering
4796 items will not react to the relevant touch points.
4798 If the item does not indicate that it wishes to retain touch point grab,
4799 a filtering item may steal the grab. For example, Flickable may attempt
4800 to steal a touch point grab if it detects that the user has begun to
4803 \sa keepTouchGrab(), setKeepMouseGrab()
4805 void QQuickItem::setKeepTouchGrab(bool keep)
4808 d->keepTouch = keep;
4812 \qmlmethod object QtQuick2::Item::mapFromItem(Item item, real x, real y)
4814 Maps the point (\a x, \a y), which is in \a item's coordinate system, to
4815 this item's coordinate system, and returns an object with \c x and \c y
4816 properties matching the mapped coordinate.
4818 If \a item is a \c null value, this maps the point from the coordinate
4819 system of the root QML view.
4822 \qmlmethod object QtQuick2::Item::mapToItem(Item item, real x, real y)
4824 Maps the point (\a x, \a y), which is in this item's coordinate system, to
4825 \a item's coordinate system, and returns an object with \c x and \c y
4826 properties matching the mapped coordinate.
4828 If \a item is a \c null value, this maps \a x and \a y to the coordinate
4829 system of the root QML view.
4831 QPointF QQuickItem::mapToItem(const QQuickItem *item, const QPointF &point) const
4833 QPointF p = mapToScene(point);
4835 p = item->mapFromScene(p);
4839 QPointF QQuickItem::mapToScene(const QPointF &point) const
4841 Q_D(const QQuickItem);
4842 return d->itemToCanvasTransform().map(point);
4845 QRectF QQuickItem::mapRectToItem(const QQuickItem *item, const QRectF &rect) const
4847 Q_D(const QQuickItem);
4848 QTransform t = d->itemToCanvasTransform();
4850 t *= QQuickItemPrivate::get(item)->canvasToItemTransform();
4851 return t.mapRect(rect);
4854 QRectF QQuickItem::mapRectToScene(const QRectF &rect) const
4856 Q_D(const QQuickItem);
4857 return d->itemToCanvasTransform().mapRect(rect);
4860 QPointF QQuickItem::mapFromItem(const QQuickItem *item, const QPointF &point) const
4862 QPointF p = item?item->mapToScene(point):point;
4863 return mapFromScene(p);
4866 QPointF QQuickItem::mapFromScene(const QPointF &point) const
4868 Q_D(const QQuickItem);
4869 return d->canvasToItemTransform().map(point);
4872 QRectF QQuickItem::mapRectFromItem(const QQuickItem *item, const QRectF &rect) const
4874 Q_D(const QQuickItem);
4875 QTransform t = item?QQuickItemPrivate::get(item)->itemToCanvasTransform():QTransform();
4876 t *= d->canvasToItemTransform();
4877 return t.mapRect(rect);
4880 QRectF QQuickItem::mapRectFromScene(const QRectF &rect) const
4882 Q_D(const QQuickItem);
4883 return d->canvasToItemTransform().mapRect(rect);
4888 \qmlmethod QtQuick2::Item::forceActiveFocus()
4890 Forces active focus on the item.
4892 This method sets focus on the item and makes sure that all the focus scopes
4893 higher in the object hierarchy are also given the focus.
4897 Forces active focus on the item.
4899 This method sets focus on the item and makes sure that all the focus scopes
4900 higher in the object hierarchy are also given the focus.
4904 \qmlmethod QtQuick2::Item::childAt(real x, real y)
4906 Returns the visible child item at point (\a x, \a y), which is in this
4907 item's coordinate system, or \c null if there is no such item.
4911 Returns the visible child item at point (\a x, \a y), which is in this
4912 item's coordinate system, or 0 if there is no such item.
4916 \qmlproperty list<State> QtQuick2::Item::states
4917 This property holds a list of states defined by the item.
4933 \sa {qmlstate}{States}
4936 \qmlproperty list<Transition> QtQuick2::Item::transitions
4937 This property holds a list of transitions defined by the item.
4953 \sa {QML Animation and Transitions}{Transitions}
4956 \qmlproperty list<Filter> QtQuick2::Item::filter
4957 This property holds a list of graphical filters to be applied to the item.
4959 \l {Filter}{Filters} include things like \l {Blur}{blurring}
4960 the item, or giving it a \l Reflection. Some
4961 filters may not be available on all canvases; if a filter is not
4962 available on a certain canvas, it will simply not be applied for
4963 that canvas (but the QML will still be considered valid).
4981 \qmlproperty bool QtQuick2::Item::clip
4982 This property holds whether clipping is enabled. The default clip value is \c false.
4984 If clipping is enabled, an item will clip its own painting, as well
4985 as the painting of its children, to its bounding rectangle.
4987 Non-rectangular clipping regions are not supported for performance reasons.
4991 \property QQuickItem::clip
4992 This property holds whether clipping is enabled. The default clip value is \c false.
4994 If clipping is enabled, an item will clip its own painting, as well
4995 as the painting of its children, to its bounding rectangle. If you set
4996 clipping during an item's paint operation, remember to re-set it to
4997 prevent clipping the rest of your scene.
4999 Non-rectangular clipping regions are not supported for performance reasons.
5003 \qmlproperty string QtQuick2::Item::state
5005 This property holds the name of the current state of the item.
5007 This property is often used in scripts to change between states. For
5012 if (button.state == 'On')
5013 button.state = 'Off';
5015 button.state = 'On';
5019 If the item is in its base state (i.e. no explicit state has been
5020 set), \c state will be a blank string. Likewise, you can return an
5021 item to its base state by setting its current state to \c ''.
5023 \sa {qmlstates}{States}
5027 \qmlproperty list<Transform> QtQuick2::Item::transform
5028 This property holds the list of transformations to apply.
5030 For more information see \l Transform.
5034 \enum QQuickItem::TransformOrigin
5036 Controls the point about which simple transforms like scale apply.
5038 \value TopLeft The top-left corner of the item.
5039 \value Top The center point of the top of the item.
5040 \value TopRight The top-right corner of the item.
5041 \value Left The left most point of the vertical middle.
5042 \value Center The center of the item.
5043 \value Right The right most point of the vertical middle.
5044 \value BottomLeft The bottom-left corner of the item.
5045 \value Bottom The center point of the bottom of the item.
5046 \value BottomRight The bottom-right corner of the item.
5051 \qmlproperty bool QtQuick2::Item::activeFocus
5053 This property indicates whether the item has active focus.
5055 An item with active focus will receive keyboard input,
5056 or is a FocusScope ancestor of the item that will receive keyboard input.
5058 Usually, activeFocus is gained by setting focus on an item and its enclosing
5059 FocusScopes. In the following example \c input will have activeFocus.
5072 \sa focus, {qmlfocus}{Keyboard Focus}
5076 \qmlproperty bool QtQuick2::Item::focus
5077 This property indicates whether the item has focus within the enclosing focus scope. If true, this item
5078 will gain active focus when the enclosing focus scope gains active focus.
5079 In the following example, \c input will be given active focus when \c scope gains active focus.
5092 For the purposes of this property, the scene as a whole is assumed to act like a focus scope.
5093 On a practical level, that means the following QML will give active focus to \c input on startup.
5104 \sa activeFocus, {qmlfocus}{Keyboard Focus}
5109 \property QQuickItem::anchors
5114 \property QQuickItem::left
5119 \property QQuickItem::right
5124 \property QQuickItem::horizontalCenter
5129 \property QQuickItem::top
5134 \property QQuickItem::bottom
5139 \property QQuickItem::verticalCenter
5144 \property QQuickItem::focus
5149 \property QQuickItem::transform
5154 \property QQuickItem::transformOrigin
5159 \property QQuickItem::activeFocus
5164 \property QQuickItem::baseline
5169 \property QQuickItem::data
5174 \property QQuickItem::resources
5179 \property QQuickItem::state
5184 \property QQuickItem::states
5189 \property QQuickItem::transformOriginPoint
5194 \property QQuickItem::transitions
5198 bool QQuickItem::event(QEvent *ev)
5201 if (ev->type() == QEvent::PolishRequest) {
5203 d->polishScheduled = false;
5207 return QObject::event(ev);
5210 if (ev->type() == QEvent::InputMethodQuery) {
5211 QInputMethodQueryEvent *query = static_cast<QInputMethodQueryEvent *>(ev);
5212 Qt::InputMethodQueries queries = query->queries();
5213 for (uint i = 0; i < 32; ++i) {
5214 Qt::InputMethodQuery q = (Qt::InputMethodQuery)(int)(queries & (1<<i));
5216 QVariant v = inputMethodQuery(q);
5217 query->setValue(q, v);
5222 } else if (ev->type() == QEvent::InputMethod) {
5223 inputMethodEvent(static_cast<QInputMethodEvent *>(ev));
5226 return QObject::event(ev);
5229 #ifndef QT_NO_DEBUG_STREAM
5230 QDebug operator<<(QDebug debug, QQuickItem *item)
5233 debug << "QQuickItem(0)";
5237 debug << item->metaObject()->className() << "(this =" << ((void*)item)
5238 << ", name=" << item->objectName()
5239 << ", parent =" << ((void*)item->parentItem())
5240 << ", geometry =" << QRectF(item->pos(), QSizeF(item->width(), item->height()))
5241 << ", z =" << item->z() << ')';
5246 qint64 QQuickItemPrivate::consistentTime = -1;
5247 void QQuickItemPrivate::setConsistentTime(qint64 t)
5252 class QElapsedTimerConsistentTimeHack
5256 t1 = QQuickItemPrivate::consistentTime;
5260 return QQuickItemPrivate::consistentTime - t1;
5263 qint64 val = QQuickItemPrivate::consistentTime - t1;
5264 t1 = QQuickItemPrivate::consistentTime;
5274 void QQuickItemPrivate::start(QElapsedTimer &t)
5276 if (QQuickItemPrivate::consistentTime == -1)
5279 ((QElapsedTimerConsistentTimeHack*)&t)->start();
5282 qint64 QQuickItemPrivate::elapsed(QElapsedTimer &t)
5284 if (QQuickItemPrivate::consistentTime == -1)
5287 return ((QElapsedTimerConsistentTimeHack*)&t)->elapsed();
5290 qint64 QQuickItemPrivate::restart(QElapsedTimer &t)
5292 if (QQuickItemPrivate::consistentTime == -1)
5295 return ((QElapsedTimerConsistentTimeHack*)&t)->restart();
5299 \fn bool QQuickItem::isTextureProvider() const
5301 Returns true if this item is a texture provider. The default
5302 implementation returns false.
5304 This function can be called from any thread.
5308 \fn QSGTextureProvider *QQuickItem::textureProvider() const
5310 Returns the texture provider for an item. The default implementation
5313 This function may only be called on the rendering thread.
5318 #include <moc_qquickitem.cpp>