1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the QtQml module of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #include "qquickitem.h"
44 #include "qquickcanvas.h"
45 #include <QtQml/qjsengine.h>
46 #include "qquickcanvas_p.h"
48 #include "qquickevents_p_p.h"
49 #include "qquickscreen_p.h"
51 #include <QtQml/qqmlengine.h>
52 #include <QtQml/qqmlcomponent.h>
53 #include <QtQml/qqmlinfo.h>
54 #include <QtGui/qpen.h>
55 #include <QtGui/qguiapplication.h>
56 #include <QtGui/private/qguiapplication_p.h>
57 #include <QtGui/qinputmethod.h>
58 #include <QtCore/qdebug.h>
59 #include <QtCore/qcoreevent.h>
60 #include <QtCore/qnumeric.h>
62 #include <private/qqmlglobal_p.h>
63 #include <private/qqmlengine_p.h>
64 #include <QtQuick/private/qquickstategroup_p.h>
65 #include <private/qqmlopenmetaobject_p.h>
66 #include <QtQuick/private/qquickstate_p.h>
67 #include <private/qlistmodelinterface_p.h>
68 #include <private/qquickitem_p.h>
69 #include <private/qqmlaccessors_p.h>
70 #include <QtQuick/private/qquickaccessibleattached_p.h>
74 // XXX todo Check that elements that create items handle memory correctly after visual ownership change
79 void printFocusTree(QQuickItem *item, QQuickItem *scope = 0, int depth = 1);
80 void printFocusTree(QQuickItem *item, QQuickItem *scope, int depth)
83 << QByteArray(depth, '\t').constData()
84 << (scope && QQuickItemPrivate::get(scope)->subFocusItem == item ? '*' : ' ')
86 << item->hasActiveFocus()
87 << item->isFocusScope()
89 foreach (QQuickItem *child, item->childItems()) {
92 item->isFocusScope() || !scope ? item : scope,
93 item->isFocusScope() || !scope ? depth + 1 : depth);
98 static void QQuickItem_parentNotifier(QObject *o, intptr_t, QQmlNotifier **n)
100 QQuickItemPrivate *d = QQuickItemPrivate::get(static_cast<QQuickItem *>(o));
101 *n = &d->parentNotifier;
104 QML_PRIVATE_ACCESSOR(QQuickItem, QQuickItem *, parent, parentItem)
105 QML_PRIVATE_ACCESSOR(QQuickItem, qreal, x, x)
106 QML_PRIVATE_ACCESSOR(QQuickItem, qreal, y, y)
107 QML_PRIVATE_ACCESSOR(QQuickItem, qreal, width, width)
108 QML_PRIVATE_ACCESSOR(QQuickItem, qreal, height, height)
110 static QQmlAccessors QQuickItem_parent = { QQuickItem_parentRead, QQuickItem_parentNotifier };
111 static QQmlAccessors QQuickItem_x = { QQuickItem_xRead, 0 };
112 static QQmlAccessors QQuickItem_y = { QQuickItem_yRead, 0 };
113 static QQmlAccessors QQuickItem_width = { QQuickItem_widthRead, 0 };
114 static QQmlAccessors QQuickItem_height = { QQuickItem_heightRead, 0 };
116 QML_DECLARE_PROPERTIES(QQuickItem) {
117 { QML_PROPERTY_NAME(parent), 0, &QQuickItem_parent },
118 { QML_PROPERTY_NAME(x), 0, &QQuickItem_x },
119 { QML_PROPERTY_NAME(y), 0, &QQuickItem_y },
120 { QML_PROPERTY_NAME(width), 0, &QQuickItem_width },
121 { QML_PROPERTY_NAME(height), 0, &QQuickItem_height }
124 void QQuickItemPrivate::registerAccessorProperties()
126 QML_DEFINE_PROPERTIES(QQuickItem);
130 \qmlclass Transform QQuickTransform
131 \inqmlmodule QtQuick 2
132 \ingroup qml-transform-elements
133 \brief The Transform elements provide a way of building advanced transformations on Items.
135 The Transform element is a base type which cannot be instantiated directly.
136 The following concrete Transform types are available:
144 The Transform elements let you create and control advanced transformations that can be configured
145 independently using specialized properties.
147 You can assign any number of Transform elements to an \l Item. Each Transform is applied in order,
152 \qmlclass Translate QQuickTranslate
153 \inqmlmodule QtQuick 2
154 \ingroup qml-transform-elements
155 \brief The Translate object provides a way to move an Item without changing its x or y properties.
157 The Translate object provides independent control over position in addition to the Item's x and y properties.
159 The following example moves the Y axis of the \l Rectangle elements while still allowing the \l Row element
160 to lay the items out as if they had not been transformed:
166 width: 100; height: 100
168 transform: Translate { y: 20 }
171 width: 100; height: 100
173 transform: Translate { y: -20 }
182 \qmlproperty real QtQuick2::Translate::x
184 The translation along the X axis.
188 \qmlproperty real QtQuick2::Translate::y
190 The translation along the Y axis.
194 \qmlclass Scale QQuickScale
195 \inqmlmodule QtQuick 2
196 \ingroup qml-transform-elements
197 \brief The Scale element provides a way to scale an Item.
199 The Scale element gives more control over scaling than using \l Item's \l{Item::scale}{scale} property. Specifically,
200 it allows a different scale for the x and y axes, and allows the scale to be relative to an
203 The following example scales the X axis of the Rectangle, relative to its interior point 25, 25:
206 width: 100; height: 100
208 transform: Scale { origin.x: 25; origin.y: 25; xScale: 3}
212 \sa Rotation, Translate
216 \qmlproperty real QtQuick2::Scale::origin.x
217 \qmlproperty real QtQuick2::Scale::origin.y
219 The point that the item is scaled from (i.e., the point that stays fixed relative to the parent as
220 the rest of the item grows). By default the origin is 0, 0.
224 \qmlproperty real QtQuick2::Scale::xScale
226 The scaling factor for the X axis.
230 \qmlproperty real QtQuick2::Scale::yScale
232 The scaling factor for the Y axis.
236 \qmlclass Rotation QQuickRotation
237 \inqmlmodule QtQuick 2
238 \ingroup qml-transform-elements
239 \brief The Rotation object provides a way to rotate an Item.
241 The Rotation object gives more control over rotation than using \l Item's \l{Item::rotation}{rotation} property.
242 Specifically, it allows (z axis) rotation to be relative to an arbitrary point.
244 The following example rotates a Rectangle around its interior point 25, 25:
247 width: 100; height: 100
249 transform: Rotation { origin.x: 25; origin.y: 25; angle: 45}
253 Rotation also provides a way to specify 3D-like rotations for Items. For these types of
254 rotations you must specify the axis to rotate around in addition to the origin point.
256 The following example shows various 3D-like rotations applied to an \l Image.
257 \snippet doc/snippets/qml/rotation.qml 0
259 \image axisrotation.png
261 \sa {declarative/ui-components/dialcontrol}{Dial Control example}, {declarative/toys/clocks}{Clocks example}
265 \qmlproperty real QtQuick2::Rotation::origin.x
266 \qmlproperty real QtQuick2::Rotation::origin.y
268 The origin point of the rotation (i.e., the point that stays fixed relative to the parent as
269 the rest of the item rotates). By default the origin is 0, 0.
273 \qmlproperty real QtQuick2::Rotation::axis.x
274 \qmlproperty real QtQuick2::Rotation::axis.y
275 \qmlproperty real QtQuick2::Rotation::axis.z
277 The axis to rotate around. For simple (2D) rotation around a point, you do not need to specify an axis,
278 as the default axis is the z axis (\c{ axis { x: 0; y: 0; z: 1 } }).
280 For a typical 3D-like rotation you will usually specify both the origin and the axis.
282 \image 3d-rotation-axis.png
286 \qmlproperty real QtQuick2::Rotation::angle
288 The angle to rotate, in degrees clockwise.
291 QQuickTransformPrivate::QQuickTransformPrivate()
295 QQuickTransform::QQuickTransform(QObject *parent)
296 : QObject(*(new QQuickTransformPrivate), parent)
300 QQuickTransform::QQuickTransform(QQuickTransformPrivate &dd, QObject *parent)
301 : QObject(dd, parent)
305 QQuickTransform::~QQuickTransform()
307 Q_D(QQuickTransform);
308 for (int ii = 0; ii < d->items.count(); ++ii) {
309 QQuickItemPrivate *p = QQuickItemPrivate::get(d->items.at(ii));
310 p->transforms.removeOne(this);
311 p->dirty(QQuickItemPrivate::Transform);
315 void QQuickTransform::update()
317 Q_D(QQuickTransform);
318 for (int ii = 0; ii < d->items.count(); ++ii) {
319 QQuickItemPrivate *p = QQuickItemPrivate::get(d->items.at(ii));
320 p->dirty(QQuickItemPrivate::Transform);
324 QQuickContents::QQuickContents(QQuickItem *item)
325 : m_item(item), m_x(0), m_y(0), m_width(0), m_height(0)
329 QQuickContents::~QQuickContents()
331 QList<QQuickItem *> children = m_item->childItems();
332 for (int i = 0; i < children.count(); ++i) {
333 QQuickItem *child = children.at(i);
334 QQuickItemPrivate::get(child)->removeItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed);
338 bool QQuickContents::calcHeight(QQuickItem *changed)
341 qreal oldheight = m_height;
345 qreal bottom = oldy + oldheight;
346 qreal y = changed->y();
347 if (y + changed->height() > bottom)
348 bottom = y + changed->height();
352 m_height = bottom - top;
356 QList<QQuickItem *> children = m_item->childItems();
357 for (int i = 0; i < children.count(); ++i) {
358 QQuickItem *child = children.at(i);
359 qreal y = child->y();
360 if (y + child->height() > bottom)
361 bottom = y + child->height();
365 if (!children.isEmpty())
367 m_height = qMax(bottom - top, qreal(0.0));
370 return (m_height != oldheight || m_y != oldy);
373 bool QQuickContents::calcWidth(QQuickItem *changed)
376 qreal oldwidth = m_width;
380 qreal right = oldx + oldwidth;
381 qreal x = changed->x();
382 if (x + changed->width() > right)
383 right = x + changed->width();
387 m_width = right - left;
389 qreal left = FLT_MAX;
391 QList<QQuickItem *> children = m_item->childItems();
392 for (int i = 0; i < children.count(); ++i) {
393 QQuickItem *child = children.at(i);
394 qreal x = child->x();
395 if (x + child->width() > right)
396 right = x + child->width();
400 if (!children.isEmpty())
402 m_width = qMax(right - left, qreal(0.0));
405 return (m_width != oldwidth || m_x != oldx);
408 void QQuickContents::complete()
410 QQuickItemPrivate::get(m_item)->addItemChangeListener(this, QQuickItemPrivate::Children);
412 QList<QQuickItem *> children = m_item->childItems();
413 for (int i = 0; i < children.count(); ++i) {
414 QQuickItem *child = children.at(i);
415 QQuickItemPrivate::get(child)->addItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed);
416 //###what about changes to visibility?
421 void QQuickContents::updateRect()
423 QQuickItemPrivate::get(m_item)->emitChildrenRectChanged(rectF());
426 void QQuickContents::itemGeometryChanged(QQuickItem *changed, const QRectF &newGeometry, const QRectF &oldGeometry)
429 bool wChanged = false;
430 bool hChanged = false;
431 //### we can only pass changed if the left edge has moved left, or the right edge has moved right
432 if (newGeometry.width() != oldGeometry.width() || newGeometry.x() != oldGeometry.x())
433 wChanged = calcWidth(/*changed*/);
434 if (newGeometry.height() != oldGeometry.height() || newGeometry.y() != oldGeometry.y())
435 hChanged = calcHeight(/*changed*/);
436 if (wChanged || hChanged)
440 void QQuickContents::itemDestroyed(QQuickItem *item)
443 QQuickItemPrivate::get(item)->removeItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed);
447 void QQuickContents::itemChildRemoved(QQuickItem *, QQuickItem *item)
450 QQuickItemPrivate::get(item)->removeItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed);
454 void QQuickContents::itemChildAdded(QQuickItem *, QQuickItem *item)
457 QQuickItemPrivate::get(item)->addItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed);
461 QQuickItemKeyFilter::QQuickItemKeyFilter(QQuickItem *item)
462 : m_processPost(false), m_next(0)
464 QQuickItemPrivate *p = item?QQuickItemPrivate::get(item):0;
466 m_next = p->extra.value().keyHandler;
467 p->extra->keyHandler = this;
471 QQuickItemKeyFilter::~QQuickItemKeyFilter()
475 void QQuickItemKeyFilter::keyPressed(QKeyEvent *event, bool post)
477 if (m_next) m_next->keyPressed(event, post);
480 void QQuickItemKeyFilter::keyReleased(QKeyEvent *event, bool post)
482 if (m_next) m_next->keyReleased(event, post);
485 void QQuickItemKeyFilter::inputMethodEvent(QInputMethodEvent *event, bool post)
488 m_next->inputMethodEvent(event, post);
493 QVariant QQuickItemKeyFilter::inputMethodQuery(Qt::InputMethodQuery query) const
495 if (m_next) return m_next->inputMethodQuery(query);
499 void QQuickItemKeyFilter::componentComplete()
501 if (m_next) m_next->componentComplete();
504 \qmlclass KeyNavigation QQuickKeyNavigationAttached
505 \inqmlmodule QtQuick 2
506 \ingroup qml-basic-interaction-elements
507 \brief The KeyNavigation attached property supports key navigation by arrow keys.
509 Key-based user interfaces commonly allow the use of arrow keys to navigate between
510 focusable items. The KeyNavigation attached property enables this behavior by providing a
511 convenient way to specify the item that should gain focus when an arrow or tab key is pressed.
513 The following example provides key navigation for a 2x2 grid of items:
515 \snippet doc/snippets/qml/keynavigation.qml 0
517 The top-left item initially receives focus by setting \l {Item::}{focus} to
518 \c true. When an arrow key is pressed, the focus will move to the
519 appropriate item, as defined by the value that has been set for
520 the KeyNavigation \l left, \l right, \l up or \l down properties.
522 Note that if a KeyNavigation attached property receives the key press and release
523 events for a requested arrow or tab key, the event is accepted and does not
524 propagate any further.
526 By default, KeyNavigation receives key events after the item to which it is attached.
527 If the item accepts the key event, the KeyNavigation attached property will not
528 receive an event for that key. Setting the \l priority property to
529 \c KeyNavigation.BeforeItem allows the event to be used for key navigation
530 before the item, rather than after.
532 If item to which the focus is switching is not enabled or visible, an attempt will
533 be made to skip this item and focus on the next. This is possible if there are
534 a chain of items with the same KeyNavigation handler. If multiple items in a row are not enabled
535 or visible, they will also be skipped.
537 KeyNavigation will implicitly set the other direction to return focus to this item. So if you set
538 \l left to another item, \l right will be set on that item's KeyNavigation to set focus back to this
539 item. However, if that item's KeyNavigation has had right explicitly set then no change will occur.
540 This means that the above example could have been written, with the same behaviour, without specifing
541 KeyNavigation.right or KeyNavigation.down for any of the items.
543 \sa {Keys}{Keys attached property}
547 \qmlproperty Item QtQuick2::KeyNavigation::left
548 \qmlproperty Item QtQuick2::KeyNavigation::right
549 \qmlproperty Item QtQuick2::KeyNavigation::up
550 \qmlproperty Item QtQuick2::KeyNavigation::down
551 \qmlproperty Item QtQuick2::KeyNavigation::tab
552 \qmlproperty Item QtQuick2::KeyNavigation::backtab
554 These properties hold the item to assign focus to
555 when the left, right, up or down cursor keys, or the
560 \qmlproperty Item QtQuick2::KeyNavigation::tab
561 \qmlproperty Item QtQuick2::KeyNavigation::backtab
563 These properties hold the item to assign focus to
564 when the Tab key or Shift+Tab key combination (Backtab) are pressed.
567 QQuickKeyNavigationAttached::QQuickKeyNavigationAttached(QObject *parent)
568 : QObject(*(new QQuickKeyNavigationAttachedPrivate), parent),
569 QQuickItemKeyFilter(qobject_cast<QQuickItem*>(parent))
571 m_processPost = true;
574 QQuickKeyNavigationAttached *
575 QQuickKeyNavigationAttached::qmlAttachedProperties(QObject *obj)
577 return new QQuickKeyNavigationAttached(obj);
580 QQuickItem *QQuickKeyNavigationAttached::left() const
582 Q_D(const QQuickKeyNavigationAttached);
586 void QQuickKeyNavigationAttached::setLeft(QQuickItem *i)
588 Q_D(QQuickKeyNavigationAttached);
593 QQuickKeyNavigationAttached* other =
594 qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
595 if (other && !other->d_func()->rightSet){
596 other->d_func()->right = qobject_cast<QQuickItem*>(parent());
597 emit other->rightChanged();
602 QQuickItem *QQuickKeyNavigationAttached::right() const
604 Q_D(const QQuickKeyNavigationAttached);
608 void QQuickKeyNavigationAttached::setRight(QQuickItem *i)
610 Q_D(QQuickKeyNavigationAttached);
615 QQuickKeyNavigationAttached* other =
616 qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
617 if (other && !other->d_func()->leftSet){
618 other->d_func()->left = qobject_cast<QQuickItem*>(parent());
619 emit other->leftChanged();
624 QQuickItem *QQuickKeyNavigationAttached::up() const
626 Q_D(const QQuickKeyNavigationAttached);
630 void QQuickKeyNavigationAttached::setUp(QQuickItem *i)
632 Q_D(QQuickKeyNavigationAttached);
637 QQuickKeyNavigationAttached* other =
638 qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
639 if (other && !other->d_func()->downSet){
640 other->d_func()->down = qobject_cast<QQuickItem*>(parent());
641 emit other->downChanged();
646 QQuickItem *QQuickKeyNavigationAttached::down() const
648 Q_D(const QQuickKeyNavigationAttached);
652 void QQuickKeyNavigationAttached::setDown(QQuickItem *i)
654 Q_D(QQuickKeyNavigationAttached);
659 QQuickKeyNavigationAttached* other =
660 qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
661 if (other && !other->d_func()->upSet) {
662 other->d_func()->up = qobject_cast<QQuickItem*>(parent());
663 emit other->upChanged();
668 QQuickItem *QQuickKeyNavigationAttached::tab() const
670 Q_D(const QQuickKeyNavigationAttached);
674 void QQuickKeyNavigationAttached::setTab(QQuickItem *i)
676 Q_D(QQuickKeyNavigationAttached);
681 QQuickKeyNavigationAttached* other =
682 qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
683 if (other && !other->d_func()->backtabSet) {
684 other->d_func()->backtab = qobject_cast<QQuickItem*>(parent());
685 emit other->backtabChanged();
690 QQuickItem *QQuickKeyNavigationAttached::backtab() const
692 Q_D(const QQuickKeyNavigationAttached);
696 void QQuickKeyNavigationAttached::setBacktab(QQuickItem *i)
698 Q_D(QQuickKeyNavigationAttached);
702 d->backtabSet = true;
703 QQuickKeyNavigationAttached* other =
704 qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
705 if (other && !other->d_func()->tabSet) {
706 other->d_func()->tab = qobject_cast<QQuickItem*>(parent());
707 emit other->tabChanged();
709 emit backtabChanged();
713 \qmlproperty enumeration QtQuick2::KeyNavigation::priority
715 This property determines whether the keys are processed before
716 or after the attached item's own key handling.
719 \li KeyNavigation.BeforeItem - process the key events before normal
720 item key processing. If the event is used for key navigation, it will be accepted and will not
721 be passed on to the item.
722 \li KeyNavigation.AfterItem (default) - process the key events after normal item key
723 handling. If the item accepts the key event it will not be
724 handled by the KeyNavigation attached property handler.
727 QQuickKeyNavigationAttached::Priority QQuickKeyNavigationAttached::priority() const
729 return m_processPost ? AfterItem : BeforeItem;
732 void QQuickKeyNavigationAttached::setPriority(Priority order)
734 bool processPost = order == AfterItem;
735 if (processPost != m_processPost) {
736 m_processPost = processPost;
737 emit priorityChanged();
741 void QQuickKeyNavigationAttached::keyPressed(QKeyEvent *event, bool post)
743 Q_D(QQuickKeyNavigationAttached);
746 if (post != m_processPost) {
747 QQuickItemKeyFilter::keyPressed(event, post);
752 switch (event->key()) {
754 if (QQuickItem *parentItem = qobject_cast<QQuickItem*>(parent()))
755 mirror = QQuickItemPrivate::get(parentItem)->effectiveLayoutMirror;
756 QQuickItem* leftItem = mirror ? d->right : d->left;
758 setFocusNavigation(leftItem, mirror ? "right" : "left");
763 case Qt::Key_Right: {
764 if (QQuickItem *parentItem = qobject_cast<QQuickItem*>(parent()))
765 mirror = QQuickItemPrivate::get(parentItem)->effectiveLayoutMirror;
766 QQuickItem* rightItem = mirror ? d->left : d->right;
768 setFocusNavigation(rightItem, mirror ? "left" : "right");
775 setFocusNavigation(d->up, "up");
781 setFocusNavigation(d->down, "down");
787 setFocusNavigation(d->tab, "tab");
791 case Qt::Key_Backtab:
793 setFocusNavigation(d->backtab, "backtab");
801 if (!event->isAccepted()) QQuickItemKeyFilter::keyPressed(event, post);
804 void QQuickKeyNavigationAttached::keyReleased(QKeyEvent *event, bool post)
806 Q_D(QQuickKeyNavigationAttached);
809 if (post != m_processPost) {
810 QQuickItemKeyFilter::keyReleased(event, post);
815 switch (event->key()) {
817 if (QQuickItem *parentItem = qobject_cast<QQuickItem*>(parent()))
818 mirror = QQuickItemPrivate::get(parentItem)->effectiveLayoutMirror;
819 if (mirror ? d->right : d->left)
823 if (QQuickItem *parentItem = qobject_cast<QQuickItem*>(parent()))
824 mirror = QQuickItemPrivate::get(parentItem)->effectiveLayoutMirror;
825 if (mirror ? d->left : d->right)
843 case Qt::Key_Backtab:
852 if (!event->isAccepted()) QQuickItemKeyFilter::keyReleased(event, post);
855 void QQuickKeyNavigationAttached::setFocusNavigation(QQuickItem *currentItem, const char *dir)
857 QQuickItem *initialItem = currentItem;
858 bool isNextItem = false;
861 if (currentItem->isVisible() && currentItem->isEnabled()) {
862 currentItem->setFocus(true);
865 qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(currentItem, false);
867 QQuickItem *tempItem = qvariant_cast<QQuickItem*>(attached->property(dir));
869 currentItem = tempItem;
875 while (currentItem != initialItem && isNextItem);
878 const QQuickKeysAttached::SigMap QQuickKeysAttached::sigMap[] = {
879 { Qt::Key_Left, "leftPressed" },
880 { Qt::Key_Right, "rightPressed" },
881 { Qt::Key_Up, "upPressed" },
882 { Qt::Key_Down, "downPressed" },
883 { Qt::Key_Tab, "tabPressed" },
884 { Qt::Key_Backtab, "backtabPressed" },
885 { Qt::Key_Asterisk, "asteriskPressed" },
886 { Qt::Key_NumberSign, "numberSignPressed" },
887 { Qt::Key_Escape, "escapePressed" },
888 { Qt::Key_Return, "returnPressed" },
889 { Qt::Key_Enter, "enterPressed" },
890 { Qt::Key_Delete, "deletePressed" },
891 { Qt::Key_Space, "spacePressed" },
892 { Qt::Key_Back, "backPressed" },
893 { Qt::Key_Cancel, "cancelPressed" },
894 { Qt::Key_Select, "selectPressed" },
895 { Qt::Key_Yes, "yesPressed" },
896 { Qt::Key_No, "noPressed" },
897 { Qt::Key_Context1, "context1Pressed" },
898 { Qt::Key_Context2, "context2Pressed" },
899 { Qt::Key_Context3, "context3Pressed" },
900 { Qt::Key_Context4, "context4Pressed" },
901 { Qt::Key_Call, "callPressed" },
902 { Qt::Key_Hangup, "hangupPressed" },
903 { Qt::Key_Flip, "flipPressed" },
904 { Qt::Key_Menu, "menuPressed" },
905 { Qt::Key_VolumeUp, "volumeUpPressed" },
906 { Qt::Key_VolumeDown, "volumeDownPressed" },
910 bool QQuickKeysAttached::isConnected(const char *signalName)
912 Q_D(QQuickKeysAttached);
913 //### doing two string-based lookups isn't ideal
914 int signal_index = d->signalIndex(signalName);
915 int index = metaObject()->indexOfSignal(signalName);
916 return QQml_isSignalConnected(this, signal_index, index);
920 \qmlclass Keys QQuickKeysAttached
921 \inqmlmodule QtQuick 2
922 \ingroup qml-basic-interaction-elements
923 \brief The Keys attached property provides key handling to Items.
925 All visual primitives support key handling via the Keys
926 attached property. Keys can be handled via the onPressed
927 and onReleased signal properties.
929 The signal properties have a \l KeyEvent parameter, named
930 \e event which contains details of the event. If a key is
931 handled \e event.accepted should be set to true to prevent the
932 event from propagating up the item hierarchy.
934 \section1 Example Usage
936 The following example shows how the general onPressed handler can
937 be used to test for a certain key; in this case, the left cursor
940 \snippet doc/snippets/qml/keys/keys-pressed.qml key item
942 Some keys may alternatively be handled via specific signal properties,
943 for example \e onSelectPressed. These handlers automatically set
944 \e event.accepted to true.
946 \snippet doc/snippets/qml/keys/keys-handler.qml key item
948 See \l{Qt::Key}{Qt.Key} for the list of keyboard codes.
950 \section1 Key Handling Priorities
952 The Keys attached property can be configured to handle key events
953 before or after the item it is attached to. This makes it possible
954 to intercept events in order to override an item's default behavior,
955 or act as a fallback for keys not handled by the item.
957 If \l priority is Keys.BeforeItem (default) the order of key event processing is:
960 \li Items specified in \c forwardTo
961 \li specific key handlers, e.g. onReturnPressed
962 \li onKeyPress, onKeyRelease handlers
963 \li Item specific key handling, e.g. TextInput key handling
967 If priority is Keys.AfterItem the order of key event processing is:
970 \li Item specific key handling, e.g. TextInput key handling
971 \li Items specified in \c forwardTo
972 \li specific key handlers, e.g. onReturnPressed
973 \li onKeyPress, onKeyRelease handlers
977 If the event is accepted during any of the above steps, key
980 \sa KeyEvent, {KeyNavigation}{KeyNavigation attached property}
984 \qmlproperty bool QtQuick2::Keys::enabled
986 This flags enables key handling if true (default); otherwise
987 no key handlers will be called.
991 \qmlproperty enumeration QtQuick2::Keys::priority
993 This property determines whether the keys are processed before
994 or after the attached item's own key handling.
997 \li Keys.BeforeItem (default) - process the key events before normal
998 item key processing. If the event is accepted it will not
999 be passed on to the item.
1000 \li Keys.AfterItem - process the key events after normal item key
1001 handling. If the item accepts the key event it will not be
1002 handled by the Keys attached property handler.
1007 \qmlproperty list<Object> QtQuick2::Keys::forwardTo
1009 This property provides a way to forward key presses, key releases, and keyboard input
1010 coming from input methods to other items. This can be useful when you want
1011 one item to handle some keys (e.g. the up and down arrow keys), and another item to
1012 handle other keys (e.g. the left and right arrow keys). Once an item that has been
1013 forwarded keys accepts the event it is no longer forwarded to items later in the
1016 This example forwards key events to two lists:
1027 Keys.forwardTo: [list1, list2]
1034 \qmlsignal QtQuick2::Keys::onPressed(KeyEvent event)
1036 This handler is called when a key has been pressed. The \a event
1037 parameter provides information about the event.
1041 \qmlsignal QtQuick2::Keys::onReleased(KeyEvent event)
1043 This handler is called when a key has been released. The \a event
1044 parameter provides information about the event.
1048 \qmlsignal QtQuick2::Keys::onDigit0Pressed(KeyEvent event)
1050 This handler is called when the digit '0' has been pressed. The \a event
1051 parameter provides information about the event.
1055 \qmlsignal QtQuick2::Keys::onDigit1Pressed(KeyEvent event)
1057 This handler is called when the digit '1' has been pressed. The \a event
1058 parameter provides information about the event.
1062 \qmlsignal QtQuick2::Keys::onDigit2Pressed(KeyEvent event)
1064 This handler is called when the digit '2' has been pressed. The \a event
1065 parameter provides information about the event.
1069 \qmlsignal QtQuick2::Keys::onDigit3Pressed(KeyEvent event)
1071 This handler is called when the digit '3' has been pressed. The \a event
1072 parameter provides information about the event.
1076 \qmlsignal QtQuick2::Keys::onDigit4Pressed(KeyEvent event)
1078 This handler is called when the digit '4' has been pressed. The \a event
1079 parameter provides information about the event.
1083 \qmlsignal QtQuick2::Keys::onDigit5Pressed(KeyEvent event)
1085 This handler is called when the digit '5' has been pressed. The \a event
1086 parameter provides information about the event.
1090 \qmlsignal QtQuick2::Keys::onDigit6Pressed(KeyEvent event)
1092 This handler is called when the digit '6' has been pressed. The \a event
1093 parameter provides information about the event.
1097 \qmlsignal QtQuick2::Keys::onDigit7Pressed(KeyEvent event)
1099 This handler is called when the digit '7' has been pressed. The \a event
1100 parameter provides information about the event.
1104 \qmlsignal QtQuick2::Keys::onDigit8Pressed(KeyEvent event)
1106 This handler is called when the digit '8' has been pressed. The \a event
1107 parameter provides information about the event.
1111 \qmlsignal QtQuick2::Keys::onDigit9Pressed(KeyEvent event)
1113 This handler is called when the digit '9' has been pressed. The \a event
1114 parameter provides information about the event.
1118 \qmlsignal QtQuick2::Keys::onLeftPressed(KeyEvent event)
1120 This handler is called when the Left arrow has been pressed. The \a event
1121 parameter provides information about the event.
1125 \qmlsignal QtQuick2::Keys::onRightPressed(KeyEvent event)
1127 This handler is called when the Right arrow has been pressed. The \a event
1128 parameter provides information about the event.
1132 \qmlsignal QtQuick2::Keys::onUpPressed(KeyEvent event)
1134 This handler is called when the Up arrow has been pressed. The \a event
1135 parameter provides information about the event.
1139 \qmlsignal QtQuick2::Keys::onDownPressed(KeyEvent event)
1141 This handler is called when the Down arrow has been pressed. The \a event
1142 parameter provides information about the event.
1146 \qmlsignal QtQuick2::Keys::onTabPressed(KeyEvent event)
1148 This handler is called when the Tab key has been pressed. The \a event
1149 parameter provides information about the event.
1153 \qmlsignal QtQuick2::Keys::onBacktabPressed(KeyEvent event)
1155 This handler is called when the Shift+Tab key combination (Backtab) has
1156 been pressed. The \a event parameter provides information about the event.
1160 \qmlsignal QtQuick2::Keys::onAsteriskPressed(KeyEvent event)
1162 This handler is called when the Asterisk '*' has been pressed. The \a event
1163 parameter provides information about the event.
1167 \qmlsignal QtQuick2::Keys::onEscapePressed(KeyEvent event)
1169 This handler is called when the Escape key has been pressed. The \a event
1170 parameter provides information about the event.
1174 \qmlsignal QtQuick2::Keys::onReturnPressed(KeyEvent event)
1176 This handler is called when the Return key has been pressed. The \a event
1177 parameter provides information about the event.
1181 \qmlsignal QtQuick2::Keys::onEnterPressed(KeyEvent event)
1183 This handler is called when the Enter key has been pressed. The \a event
1184 parameter provides information about the event.
1188 \qmlsignal QtQuick2::Keys::onDeletePressed(KeyEvent event)
1190 This handler is called when the Delete key has been pressed. The \a event
1191 parameter provides information about the event.
1195 \qmlsignal QtQuick2::Keys::onSpacePressed(KeyEvent event)
1197 This handler is called when the Space key has been pressed. The \a event
1198 parameter provides information about the event.
1202 \qmlsignal QtQuick2::Keys::onBackPressed(KeyEvent event)
1204 This handler is called when the Back key has been pressed. The \a event
1205 parameter provides information about the event.
1209 \qmlsignal QtQuick2::Keys::onCancelPressed(KeyEvent event)
1211 This handler is called when the Cancel key has been pressed. The \a event
1212 parameter provides information about the event.
1216 \qmlsignal QtQuick2::Keys::onSelectPressed(KeyEvent event)
1218 This handler is called when the Select key has been pressed. The \a event
1219 parameter provides information about the event.
1223 \qmlsignal QtQuick2::Keys::onYesPressed(KeyEvent event)
1225 This handler is called when the Yes key has been pressed. The \a event
1226 parameter provides information about the event.
1230 \qmlsignal QtQuick2::Keys::onNoPressed(KeyEvent event)
1232 This handler is called when the No key has been pressed. The \a event
1233 parameter provides information about the event.
1237 \qmlsignal QtQuick2::Keys::onContext1Pressed(KeyEvent event)
1239 This handler is called when the Context1 key has been pressed. The \a event
1240 parameter provides information about the event.
1244 \qmlsignal QtQuick2::Keys::onContext2Pressed(KeyEvent event)
1246 This handler is called when the Context2 key has been pressed. The \a event
1247 parameter provides information about the event.
1251 \qmlsignal QtQuick2::Keys::onContext3Pressed(KeyEvent event)
1253 This handler is called when the Context3 key has been pressed. The \a event
1254 parameter provides information about the event.
1258 \qmlsignal QtQuick2::Keys::onContext4Pressed(KeyEvent event)
1260 This handler is called when the Context4 key has been pressed. The \a event
1261 parameter provides information about the event.
1265 \qmlsignal QtQuick2::Keys::onCallPressed(KeyEvent event)
1267 This handler is called when the Call key has been pressed. The \a event
1268 parameter provides information about the event.
1272 \qmlsignal QtQuick2::Keys::onHangupPressed(KeyEvent event)
1274 This handler is called when the Hangup key has been pressed. The \a event
1275 parameter provides information about the event.
1279 \qmlsignal QtQuick2::Keys::onFlipPressed(KeyEvent event)
1281 This handler is called when the Flip key has been pressed. The \a event
1282 parameter provides information about the event.
1286 \qmlsignal QtQuick2::Keys::onMenuPressed(KeyEvent event)
1288 This handler is called when the Menu key has been pressed. The \a event
1289 parameter provides information about the event.
1293 \qmlsignal QtQuick2::Keys::onVolumeUpPressed(KeyEvent event)
1295 This handler is called when the VolumeUp key has been pressed. The \a event
1296 parameter provides information about the event.
1300 \qmlsignal QtQuick2::Keys::onVolumeDownPressed(KeyEvent event)
1302 This handler is called when the VolumeDown key has been pressed. The \a event
1303 parameter provides information about the event.
1306 QQuickKeysAttached::QQuickKeysAttached(QObject *parent)
1307 : QObject(*(new QQuickKeysAttachedPrivate), parent),
1308 QQuickItemKeyFilter(qobject_cast<QQuickItem*>(parent))
1310 Q_D(QQuickKeysAttached);
1311 m_processPost = false;
1312 d->item = qobject_cast<QQuickItem*>(parent);
1315 QQuickKeysAttached::~QQuickKeysAttached()
1319 QQuickKeysAttached::Priority QQuickKeysAttached::priority() const
1321 return m_processPost ? AfterItem : BeforeItem;
1324 void QQuickKeysAttached::setPriority(Priority order)
1326 bool processPost = order == AfterItem;
1327 if (processPost != m_processPost) {
1328 m_processPost = processPost;
1329 emit priorityChanged();
1333 void QQuickKeysAttached::componentComplete()
1335 Q_D(QQuickKeysAttached);
1337 for (int ii = 0; ii < d->targets.count(); ++ii) {
1338 QQuickItem *targetItem = d->targets.at(ii);
1339 if (targetItem && (targetItem->flags() & QQuickItem::ItemAcceptsInputMethod)) {
1340 d->item->setFlag(QQuickItem::ItemAcceptsInputMethod);
1347 void QQuickKeysAttached::keyPressed(QKeyEvent *event, bool post)
1349 Q_D(QQuickKeysAttached);
1350 if (post != m_processPost || !d->enabled || d->inPress) {
1352 QQuickItemKeyFilter::keyPressed(event, post);
1356 // first process forwards
1357 if (d->item && d->item->canvas()) {
1359 for (int ii = 0; ii < d->targets.count(); ++ii) {
1360 QQuickItem *i = d->targets.at(ii);
1361 if (i && i->isVisible()) {
1362 d->item->canvas()->sendEvent(i, event);
1363 if (event->isAccepted()) {
1372 QQuickKeyEvent ke(*event);
1373 QByteArray keySignal = keyToSignal(event->key());
1374 if (!keySignal.isEmpty()) {
1375 keySignal += "(QQuickKeyEvent*)";
1376 if (isConnected(keySignal)) {
1377 // If we specifically handle a key then default to accepted
1378 ke.setAccepted(true);
1379 int idx = QQuickKeysAttached::staticMetaObject.indexOfSignal(keySignal);
1380 metaObject()->method(idx).invoke(this, Qt::DirectConnection, Q_ARG(QQuickKeyEvent*, &ke));
1383 if (!ke.isAccepted())
1385 event->setAccepted(ke.isAccepted());
1387 if (!event->isAccepted()) QQuickItemKeyFilter::keyPressed(event, post);
1390 void QQuickKeysAttached::keyReleased(QKeyEvent *event, bool post)
1392 Q_D(QQuickKeysAttached);
1393 if (post != m_processPost || !d->enabled || d->inRelease) {
1395 QQuickItemKeyFilter::keyReleased(event, post);
1399 if (d->item && d->item->canvas()) {
1400 d->inRelease = true;
1401 for (int ii = 0; ii < d->targets.count(); ++ii) {
1402 QQuickItem *i = d->targets.at(ii);
1403 if (i && i->isVisible()) {
1404 d->item->canvas()->sendEvent(i, event);
1405 if (event->isAccepted()) {
1406 d->inRelease = false;
1411 d->inRelease = false;
1414 QQuickKeyEvent ke(*event);
1416 event->setAccepted(ke.isAccepted());
1418 if (!event->isAccepted()) QQuickItemKeyFilter::keyReleased(event, post);
1421 void QQuickKeysAttached::inputMethodEvent(QInputMethodEvent *event, bool post)
1423 Q_D(QQuickKeysAttached);
1424 if (post == m_processPost && d->item && !d->inIM && d->item->canvas()) {
1426 for (int ii = 0; ii < d->targets.count(); ++ii) {
1427 QQuickItem *i = d->targets.at(ii);
1428 if (i && i->isVisible() && (i->flags() & QQuickItem::ItemAcceptsInputMethod)) {
1429 d->item->canvas()->sendEvent(i, event);
1430 if (event->isAccepted()) {
1439 QQuickItemKeyFilter::inputMethodEvent(event, post);
1442 QVariant QQuickKeysAttached::inputMethodQuery(Qt::InputMethodQuery query) const
1444 Q_D(const QQuickKeysAttached);
1446 for (int ii = 0; ii < d->targets.count(); ++ii) {
1447 QQuickItem *i = d->targets.at(ii);
1448 if (i && i->isVisible() && (i->flags() & QQuickItem::ItemAcceptsInputMethod) && i == d->imeItem) {
1449 //### how robust is i == d->imeItem check?
1450 QVariant v = i->inputMethodQuery(query);
1451 if (v.userType() == QVariant::RectF)
1452 v = d->item->mapRectFromItem(i, v.toRectF()); //### cost?
1457 return QQuickItemKeyFilter::inputMethodQuery(query);
1460 QQuickKeysAttached *QQuickKeysAttached::qmlAttachedProperties(QObject *obj)
1462 return new QQuickKeysAttached(obj);
1466 \qmlclass LayoutMirroring QQuickLayoutMirroringAttached
1467 \inqmlmodule QtQuick 2
1468 \ingroup qml-utility-elements
1469 \brief The LayoutMirroring attached property is used to mirror layout behavior.
1471 The LayoutMirroring attached property is used to horizontally mirror \l {anchor-layout}{Item anchors},
1472 \l{Using QML Positioner and Repeater Items}{positioner} elements (such as \l Row and \l Grid)
1473 and views (such as \l GridView and horizontal \l ListView). Mirroring is a visual change: left
1474 anchors become right anchors, and positioner elements like \l Grid and \l Row reverse the
1475 horizontal layout of child items.
1477 Mirroring is enabled for an item by setting the \l enabled property to true. By default, this
1478 only affects the item itself; setting the \l childrenInherit property to true propagates the mirroring
1479 behavior to all child elements as well. If the \c LayoutMirroring attached property has not been defined
1480 for an item, mirroring is not enabled.
1482 The following example shows mirroring in action. The \l Row below is specified as being anchored
1483 to the left of its parent. However, since mirroring has been enabled, the anchor is horizontally
1484 reversed and it is now anchored to the right. Also, since items in a \l Row are positioned
1485 from left to right by default, they are now positioned from right to left instead, as demonstrated
1486 by the numbering and opacity of the items:
1488 \snippet doc/snippets/qml/layoutmirroring.qml 0
1490 \image layoutmirroring.png
1492 Layout mirroring is useful when it is necessary to support both left-to-right and right-to-left
1493 layout versions of an application to target different language areas. The \l childrenInherit
1494 property allows layout mirroring to be applied without manually setting layout configurations
1495 for every item in an application. Keep in mind, however, that mirroring does not affect any
1496 positioning that is defined by the \l Item \l {Item::}{x} coordinate value, so even with
1497 mirroring enabled, it will often be necessary to apply some layout fixes to support the
1498 desired layout direction. Also, it may be necessary to disable the mirroring of individual
1499 child items (by setting \l {enabled}{LayoutMirroring.enabled} to false for such items) if
1500 mirroring is not the desired behavior, or if the child item already implements mirroring in
1503 See \l {QML Right-to-left User Interfaces} for further details on using \c LayoutMirroring and
1504 other related features to implement right-to-left support for an application.
1508 \qmlproperty bool QtQuick2::LayoutMirroring::enabled
1510 This property holds whether the item's layout is mirrored horizontally. Setting this to true
1511 horizontally reverses \l {anchor-layout}{anchor} settings such that left anchors become right,
1512 and right anchors become left. For \l{Using QML Positioner and Repeater Items}{positioner} elements
1513 (such as \l Row and \l Grid) and view elements (such as \l {GridView}{GridView} and \l {ListView}{ListView})
1514 this also mirrors the horizontal layout direction of the item.
1516 The default value is false.
1520 \qmlproperty bool QtQuick2::LayoutMirroring::childrenInherit
1522 This property holds whether the \l {enabled}{LayoutMirroring.enabled} value for this item
1523 is inherited by its children.
1525 The default value is false.
1529 QQuickLayoutMirroringAttached::QQuickLayoutMirroringAttached(QObject *parent) : QObject(parent), itemPrivate(0)
1531 if (QQuickItem *item = qobject_cast<QQuickItem*>(parent)) {
1532 itemPrivate = QQuickItemPrivate::get(item);
1533 itemPrivate->extra.value().layoutDirectionAttached = this;
1535 qmlInfo(parent) << tr("LayoutDirection attached property only works with Items");
1538 QQuickLayoutMirroringAttached * QQuickLayoutMirroringAttached::qmlAttachedProperties(QObject *object)
1540 return new QQuickLayoutMirroringAttached(object);
1543 bool QQuickLayoutMirroringAttached::enabled() const
1545 return itemPrivate ? itemPrivate->effectiveLayoutMirror : false;
1548 void QQuickLayoutMirroringAttached::setEnabled(bool enabled)
1553 itemPrivate->isMirrorImplicit = false;
1554 if (enabled != itemPrivate->effectiveLayoutMirror) {
1555 itemPrivate->setLayoutMirror(enabled);
1556 if (itemPrivate->inheritMirrorFromItem)
1557 itemPrivate->resolveLayoutMirror();
1561 void QQuickLayoutMirroringAttached::resetEnabled()
1563 if (itemPrivate && !itemPrivate->isMirrorImplicit) {
1564 itemPrivate->isMirrorImplicit = true;
1565 itemPrivate->resolveLayoutMirror();
1569 bool QQuickLayoutMirroringAttached::childrenInherit() const
1571 return itemPrivate ? itemPrivate->inheritMirrorFromItem : false;
1574 void QQuickLayoutMirroringAttached::setChildrenInherit(bool childrenInherit) {
1575 if (itemPrivate && childrenInherit != itemPrivate->inheritMirrorFromItem) {
1576 itemPrivate->inheritMirrorFromItem = childrenInherit;
1577 itemPrivate->resolveLayoutMirror();
1578 childrenInheritChanged();
1582 void QQuickItemPrivate::resolveLayoutMirror()
1585 if (QQuickItem *parentItem = q->parentItem()) {
1586 QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(parentItem);
1587 setImplicitLayoutMirror(parentPrivate->inheritedLayoutMirror, parentPrivate->inheritMirrorFromParent);
1589 setImplicitLayoutMirror(isMirrorImplicit ? false : effectiveLayoutMirror, inheritMirrorFromItem);
1593 void QQuickItemPrivate::setImplicitLayoutMirror(bool mirror, bool inherit)
1595 inherit = inherit || inheritMirrorFromItem;
1596 if (!isMirrorImplicit && inheritMirrorFromItem)
1597 mirror = effectiveLayoutMirror;
1598 if (mirror == inheritedLayoutMirror && inherit == inheritMirrorFromParent)
1601 inheritMirrorFromParent = inherit;
1602 inheritedLayoutMirror = inheritMirrorFromParent ? mirror : false;
1604 if (isMirrorImplicit)
1605 setLayoutMirror(inherit ? inheritedLayoutMirror : false);
1606 for (int i = 0; i < childItems.count(); ++i) {
1607 if (QQuickItem *child = qobject_cast<QQuickItem *>(childItems.at(i))) {
1608 QQuickItemPrivate *childPrivate = QQuickItemPrivate::get(child);
1609 childPrivate->setImplicitLayoutMirror(inheritedLayoutMirror, inheritMirrorFromParent);
1614 void QQuickItemPrivate::setLayoutMirror(bool mirror)
1616 if (mirror != effectiveLayoutMirror) {
1617 effectiveLayoutMirror = mirror;
1619 QQuickAnchorsPrivate *anchor_d = QQuickAnchorsPrivate::get(_anchors);
1620 anchor_d->fillChanged();
1621 anchor_d->centerInChanged();
1622 anchor_d->updateHorizontalAnchors();
1623 emit _anchors->mirroredChanged();
1626 if (extra.isAllocated() && extra->layoutDirectionAttached) {
1627 emit extra->layoutDirectionAttached->enabledChanged();
1632 void QQuickItemPrivate::setAccessibleFlagAndListener()
1635 QQuickItem *item = q;
1637 if (item->d_func()->isAccessible)
1638 break; // already set - grandparents should have the flag set as well.
1640 item->d_func()->isAccessible = true;
1641 item = item->d_func()->parentItem;
1645 void QQuickItemPrivate::updateSubFocusItem(QQuickItem *scope, bool focus)
1650 QQuickItemPrivate *scopePrivate = QQuickItemPrivate::get(scope);
1652 QQuickItem *oldSubFocusItem = scopePrivate->subFocusItem;
1653 // Correct focus chain in scope
1654 if (oldSubFocusItem) {
1655 QQuickItem *sfi = scopePrivate->subFocusItem->parentItem();
1656 while (sfi && sfi != scope) {
1657 QQuickItemPrivate::get(sfi)->subFocusItem = 0;
1658 sfi = sfi->parentItem();
1663 scopePrivate->subFocusItem = q;
1664 QQuickItem *sfi = scopePrivate->subFocusItem->parentItem();
1665 while (sfi && sfi != scope) {
1666 QQuickItemPrivate::get(sfi)->subFocusItem = q;
1667 sfi = sfi->parentItem();
1670 scopePrivate->subFocusItem = 0;
1677 \brief The QQuickItem class provides the most basic of all visual items in QML.
1681 All visual items in Qt Quick inherit from QQuickItem. Although QQuickItem
1682 has no visual appearance, it defines all the properties that are
1683 common across visual items - such as the x and y position, the
1684 width and height, \l {anchor-layout}{anchoring} and key handling.
1686 You can subclass QQuickItem to provide your own custom visual item
1687 that inherits these features.
1689 \section1 Custom Items using Scene Graph
1691 All visual QML items are rendered using the scene graph, a
1692 low-level, high-performance rendering stack, closely tied to
1693 OpenGL. It is possible for subclasses of QQuickItem to add their
1694 own custom content into the scene graph by setting the
1695 QQuickItem::ItemHasContents flag and reimplementing the
1696 QQuickItem::updatePaintNode() function.
1698 \warning It is crucial that OpenGL operations and interaction with
1699 the scene graph happens exclusively on the rendering thread,
1700 primarily during the updatePaintNode() call. The best rule of
1701 thumb is to only use classes with the "QSG" prefix inside the
1702 QQuickItem::updatePaintNode() function.
1704 To read more about how the scene graph rendering works, see
1705 \l{Scene Graph and Rendering}
1707 \section1 Custom Items using QPainter
1709 The QQuickItem provides a subclass, QQuickPaintedItem, which
1710 allows the users to render content using QPainter.
1712 \warning Using QQuickPaintedItem uses an indirect 2D surface to
1713 render its content, either using software rasterization or using
1714 an OpenGL framebuffer object (FBO), so the rendering is a two-step
1715 operation. First rasterize the surface, then draw the
1716 surface. Using scene graph API directly is always significantly
1719 \sa QQuickCanvas, QQuickPaintedItem
1723 \qmlclass Item QQuickItem
1725 \inqmlmodule QtQuick 2
1726 \ingroup qml-basic-visual-elements
1727 \brief The Item is the most basic of all visual items in QML.
1729 All visual items in Qt Quick inherit from Item. Although Item
1730 has no visual appearance, it defines all the properties that are
1731 common across visual items - such as the x and y position, the
1732 width and height, \l {anchor-layout}{anchoring} and key handling.
1734 Item is also useful for grouping items together.
1751 fillMode: Image.Tile
1758 \section1 Key Handling
1760 Key handling is available to all Item-based visual elements via the \l {Keys}{Keys}
1761 attached property. The \e Keys attached property provides basic handlers such
1762 as \l {Keys::onPressed}{onPressed} and \l {Keys::onReleased}{onReleased},
1763 as well as handlers for specific keys, such as
1764 \l {Keys::onCancelPressed}{onCancelPressed}. The example below
1765 assigns \l {qmlfocus}{focus} to the item and handles
1766 the Left key via the general \e onPressed handler and the Select key via the
1767 onSelectPressed handler:
1773 if (event.key == Qt.Key_Left) {
1774 console.log("move left");
1775 event.accepted = true;
1778 Keys.onSelectPressed: console.log("Selected");
1782 See the \l {Keys}{Keys} attached property for detailed documentation.
1784 \section1 Layout Mirroring
1786 Item layouts can be mirrored using the \l {LayoutMirroring}{LayoutMirroring} attached property.
1791 \fn void QQuickItem::childrenRectChanged(const QRectF &)
1796 \fn void QQuickItem::baselineOffsetChanged(qreal)
1801 \fn void QQuickItem::stateChanged(const QString &state)
1806 \fn void QQuickItem::parentChanged(QQuickItem *)
1811 \fn void QQuickItem::smoothChanged(bool)
1816 \fn void QQuickItem::clipChanged(bool)
1820 /*! \fn void QQuickItem::transformOriginChanged(TransformOrigin)
1825 \fn void QQuickItem::focusChanged(bool)
1830 \fn void QQuickItem::activeFocusChanged(bool)
1834 \fn QQuickItem::QQuickItem(QQuickItem *parent)
1836 Constructs a QQuickItem with the given \a parent.
1838 QQuickItem::QQuickItem(QQuickItem* parent)
1839 : QObject(*(new QQuickItemPrivate), parent)
1847 QQuickItem::QQuickItem(QQuickItemPrivate &dd, QQuickItem *parent)
1848 : QObject(dd, parent)
1855 static int qt_item_count = 0;
1857 static void qt_print_item_count()
1859 qDebug("Number of leaked items: %i", qt_item_count);
1865 Destroys the QQuickItem.
1867 QQuickItem::~QQuickItem()
1871 if (qt_item_count < 0)
1872 qDebug("Item destroyed after qt_print_item_count() was called.");
1877 if (d->canvasRefCount > 1)
1878 d->canvasRefCount = 1; // Make sure canvas is set to null in next call to derefCanvas().
1884 // XXX todo - optimize
1885 while (!d->childItems.isEmpty())
1886 d->childItems.first()->setParentItem(0);
1888 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
1889 QQuickAnchorsPrivate *anchor = d->changeListeners.at(ii).listener->anchorPrivate();
1891 anchor->clearItem(this);
1895 update item anchors that depended on us unless they are our child (and will also be destroyed),
1896 or our sibling, and our parent is also being destroyed.
1898 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
1899 QQuickAnchorsPrivate *anchor = d->changeListeners.at(ii).listener->anchorPrivate();
1900 if (anchor && anchor->item && anchor->item->parentItem() && anchor->item->parentItem() != this)
1904 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
1905 const QQuickItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
1906 if (change.types & QQuickItemPrivate::Destroyed)
1907 change.listener->itemDestroyed(this);
1910 d->changeListeners.clear();
1912 if (d->extra.isAllocated()) {
1913 delete d->extra->contents; d->extra->contents = 0;
1914 delete d->extra->layer; d->extra->layer = 0;
1917 delete d->_anchors; d->_anchors = 0;
1918 delete d->_stateGroup; d->_stateGroup = 0;
1922 \qmlproperty enumeration QtQuick2::Item::transformOrigin
1923 This property holds the origin point around which scale and rotation transform.
1925 Nine transform origins are available, as shown in the image below.
1927 \image declarative-transformorigin.png
1929 This example rotates an image around its bottom-right corner.
1932 source: "myimage.png"
1933 transformOrigin: Item.BottomRight
1938 The default transform origin is \c Item.Center.
1940 To set an arbitrary transform origin point use the \l Scale or \l Rotation
1945 \qmlproperty Item QtQuick2::Item::parent
1946 This property holds the parent of the item.
1950 \property QQuickItem::parent
1951 This property holds the parent of the item.
1953 void QQuickItem::setParentItem(QQuickItem *parentItem)
1956 if (parentItem == d->parentItem)
1960 QQuickItem *itemAncestor = parentItem->parentItem();
1961 while (itemAncestor != 0) {
1962 if (itemAncestor == this) {
1963 qWarning("QQuickItem::setParentItem: Parent is already part of this items subtree.");
1966 itemAncestor = itemAncestor->parentItem();
1970 d->removeFromDirtyList();
1972 QQuickItem *oldParentItem = d->parentItem;
1973 QQuickItem *scopeFocusedItem = 0;
1975 if (oldParentItem) {
1976 QQuickItemPrivate *op = QQuickItemPrivate::get(oldParentItem);
1978 QQuickItem *scopeItem = 0;
1981 scopeFocusedItem = this;
1982 else if (!isFocusScope() && d->subFocusItem)
1983 scopeFocusedItem = d->subFocusItem;
1985 if (scopeFocusedItem) {
1986 scopeItem = oldParentItem;
1987 while (!scopeItem->isFocusScope() && scopeItem->parentItem())
1988 scopeItem = scopeItem->parentItem();
1990 QQuickCanvasPrivate::get(d->canvas)->clearFocusInScope(scopeItem, scopeFocusedItem,
1991 QQuickCanvasPrivate::DontChangeFocusProperty);
1992 if (scopeFocusedItem != this)
1993 QQuickItemPrivate::get(scopeFocusedItem)->updateSubFocusItem(this, true);
1995 QQuickItemPrivate::get(scopeFocusedItem)->updateSubFocusItem(scopeItem, false);
1999 const bool wasVisible = isVisible();
2000 op->removeChild(this);
2002 emit oldParentItem->visibleChildrenChanged();
2004 } else if (d->canvas) {
2005 QQuickCanvasPrivate::get(d->canvas)->parentlessItems.remove(this);
2008 QQuickCanvas *oldParentCanvas = oldParentItem ? QQuickItemPrivate::get(oldParentItem)->canvas : 0;
2009 QQuickCanvas *parentCanvas = parentItem ? QQuickItemPrivate::get(parentItem)->canvas : 0;
2010 if (oldParentCanvas == parentCanvas) {
2011 // Avoid freeing and reallocating resources if the canvas stays the same.
2012 d->parentItem = parentItem;
2014 if (oldParentCanvas)
2016 d->parentItem = parentItem;
2018 d->refCanvas(parentCanvas);
2021 d->dirty(QQuickItemPrivate::ParentChanged);
2024 QQuickItemPrivate::get(d->parentItem)->addChild(this);
2026 QQuickCanvasPrivate::get(d->canvas)->parentlessItems.insert(this);
2028 d->setEffectiveVisibleRecur(d->calcEffectiveVisible());
2029 d->setEffectiveEnableRecur(0, d->calcEffectiveEnable());
2031 if (d->parentItem) {
2032 if (!scopeFocusedItem) {
2034 scopeFocusedItem = this;
2035 else if (!isFocusScope() && d->subFocusItem)
2036 scopeFocusedItem = d->subFocusItem;
2039 if (scopeFocusedItem) {
2040 // We need to test whether this item becomes scope focused
2041 QQuickItem *scopeItem = d->parentItem;
2042 while (!scopeItem->isFocusScope() && scopeItem->parentItem())
2043 scopeItem = scopeItem->parentItem();
2045 if (QQuickItemPrivate::get(scopeItem)->subFocusItem
2046 || (!scopeItem->isFocusScope() && scopeItem->hasFocus())) {
2047 if (scopeFocusedItem != this)
2048 QQuickItemPrivate::get(scopeFocusedItem)->updateSubFocusItem(this, false);
2049 QQuickItemPrivate::get(scopeFocusedItem)->focus = false;
2050 emit scopeFocusedItem->focusChanged(false);
2053 QQuickCanvasPrivate::get(d->canvas)->setFocusInScope(scopeItem, scopeFocusedItem,
2054 QQuickCanvasPrivate::DontChangeFocusProperty);
2056 QQuickItemPrivate::get(scopeFocusedItem)->updateSubFocusItem(scopeItem, true);
2062 d->resolveLayoutMirror();
2064 d->itemChange(ItemParentHasChanged, d->parentItem);
2066 d->parentNotifier.notify();
2067 if (d->isAccessible && d->parentItem) {
2068 d->parentItem->d_func()->setAccessibleFlagAndListener();
2071 emit parentChanged(d->parentItem);
2072 if (isVisible() && d->parentItem)
2073 emit d->parentItem->visibleChildrenChanged();
2076 void QQuickItem::stackBefore(const QQuickItem *sibling)
2079 if (!sibling || sibling == this || !d->parentItem || d->parentItem != QQuickItemPrivate::get(sibling)->parentItem) {
2080 qWarning("QQuickItem::stackBefore: Cannot stack before %p, which must be a sibling", sibling);
2084 QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(d->parentItem);
2086 int myIndex = parentPrivate->childItems.indexOf(this);
2087 int siblingIndex = parentPrivate->childItems.indexOf(const_cast<QQuickItem *>(sibling));
2089 Q_ASSERT(myIndex != -1 && siblingIndex != -1);
2091 if (myIndex == siblingIndex - 1)
2094 parentPrivate->childItems.removeAt(myIndex);
2096 if (myIndex < siblingIndex) --siblingIndex;
2098 parentPrivate->childItems.insert(siblingIndex, this);
2100 parentPrivate->dirty(QQuickItemPrivate::ChildrenStackingChanged);
2101 parentPrivate->markSortedChildrenDirty(this);
2103 for (int ii = qMin(siblingIndex, myIndex); ii < parentPrivate->childItems.count(); ++ii)
2104 QQuickItemPrivate::get(parentPrivate->childItems.at(ii))->siblingOrderChanged();
2107 void QQuickItem::stackAfter(const QQuickItem *sibling)
2110 if (!sibling || sibling == this || !d->parentItem || d->parentItem != QQuickItemPrivate::get(sibling)->parentItem) {
2111 qWarning("QQuickItem::stackAfter: Cannot stack after %p, which must be a sibling", sibling);
2115 QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(d->parentItem);
2117 int myIndex = parentPrivate->childItems.indexOf(this);
2118 int siblingIndex = parentPrivate->childItems.indexOf(const_cast<QQuickItem *>(sibling));
2120 Q_ASSERT(myIndex != -1 && siblingIndex != -1);
2122 if (myIndex == siblingIndex + 1)
2125 parentPrivate->childItems.removeAt(myIndex);
2127 if (myIndex < siblingIndex) --siblingIndex;
2129 parentPrivate->childItems.insert(siblingIndex + 1, this);
2131 parentPrivate->dirty(QQuickItemPrivate::ChildrenStackingChanged);
2132 parentPrivate->markSortedChildrenDirty(this);
2134 for (int ii = qMin(myIndex, siblingIndex + 1); ii < parentPrivate->childItems.count(); ++ii)
2135 QQuickItemPrivate::get(parentPrivate->childItems.at(ii))->siblingOrderChanged();
2139 Returns the QQuickItem parent of this item.
2141 QQuickItem *QQuickItem::parentItem() const
2143 Q_D(const QQuickItem);
2144 return d->parentItem;
2147 QQuickCanvas *QQuickItem::canvas() const
2149 Q_D(const QQuickItem);
2153 static bool itemZOrder_sort(QQuickItem *lhs, QQuickItem *rhs)
2155 return lhs->z() < rhs->z();
2158 QList<QQuickItem *> QQuickItemPrivate::paintOrderChildItems() const
2160 if (sortedChildItems)
2161 return *sortedChildItems;
2163 // If none of the items have set Z then the paint order list is the same as
2164 // the childItems list. This is by far the most common case.
2166 for (int i = 0; i < childItems.count(); ++i) {
2167 if (QQuickItemPrivate::get(childItems.at(i))->z() != 0.) {
2173 sortedChildItems = new QList<QQuickItem*>(childItems);
2174 qStableSort(sortedChildItems->begin(), sortedChildItems->end(), itemZOrder_sort);
2175 return *sortedChildItems;
2178 sortedChildItems = const_cast<QList<QQuickItem*>*>(&childItems);
2183 void QQuickItemPrivate::addChild(QQuickItem *child)
2187 Q_ASSERT(!childItems.contains(child));
2189 childItems.append(child);
2191 markSortedChildrenDirty(child);
2192 dirty(QQuickItemPrivate::ChildrenChanged);
2194 itemChange(QQuickItem::ItemChildAddedChange, child);
2196 emit q->childrenChanged();
2199 void QQuickItemPrivate::removeChild(QQuickItem *child)
2204 Q_ASSERT(childItems.contains(child));
2205 childItems.removeOne(child);
2206 Q_ASSERT(!childItems.contains(child));
2208 markSortedChildrenDirty(child);
2209 dirty(QQuickItemPrivate::ChildrenChanged);
2211 itemChange(QQuickItem::ItemChildRemovedChange, child);
2213 emit q->childrenChanged();
2216 void QQuickItemPrivate::InitializationState::clear()
2221 void QQuickItemPrivate::InitializationState::clear(QQuickItem *fs)
2226 QQuickItem *QQuickItemPrivate::InitializationState::getFocusScope(QQuickItem *item)
2229 QQuickItem *fs = item->parentItem();
2230 while (fs->parentItem() && !fs->isFocusScope())
2231 fs = fs->parentItem();
2237 void QQuickItemPrivate::refCanvas(InitializationState *state, QQuickCanvas *c)
2239 // An item needs a canvas if it is referenced by another item which has a canvas.
2240 // Typically the item is referenced by a parent, but can also be referenced by a
2241 // ShaderEffect or ShaderEffectSource. 'canvasRefCount' counts how many items with
2242 // a canvas is referencing this item. When the reference count goes from zero to one,
2243 // or one to zero, the canvas of this item is updated and propagated to the children.
2244 // As long as the reference count stays above zero, the canvas is unchanged.
2245 // refCanvas() increments the reference count.
2246 // derefCanvas() decrements the reference count.
2249 Q_ASSERT((canvas != 0) == (canvasRefCount > 0));
2251 if (++canvasRefCount > 1) {
2253 qWarning("QQuickItem: Cannot use same item on different canvases at the same time.");
2254 return; // Canvas already set.
2257 Q_ASSERT(canvas == 0);
2260 if (polishScheduled)
2261 QQuickCanvasPrivate::get(canvas)->itemsToPolish.insert(q);
2263 InitializationState _dummy;
2264 InitializationState *childState = state;
2266 if (q->isFocusScope()) {
2268 childState = &_dummy;
2272 QQuickCanvasPrivate::get(canvas)->parentlessItems.insert(q);
2274 for (int ii = 0; ii < childItems.count(); ++ii) {
2275 QQuickItem *child = childItems.at(ii);
2276 QQuickItemPrivate::get(child)->refCanvas(childState, c);
2281 if (extra.isAllocated() && extra->screenAttached)
2282 extra->screenAttached->canvasChanged(c);
2283 itemChange(QQuickItem::ItemSceneChange, c);
2286 void QQuickItemPrivate::derefCanvas()
2289 Q_ASSERT((canvas != 0) == (canvasRefCount > 0));
2292 return; // This can happen when destroying recursive shader effect sources.
2294 if (--canvasRefCount > 0)
2295 return; // There are still other references, so don't set canvas to null yet.
2297 q->releaseResources();
2298 removeFromDirtyList();
2299 QQuickCanvasPrivate *c = QQuickCanvasPrivate::get(canvas);
2300 if (polishScheduled)
2301 c->itemsToPolish.remove(q);
2302 if (c->mouseGrabberItem == q)
2303 c->mouseGrabberItem = 0;
2305 c->hoverItems.removeAll(q);
2306 if (itemNodeInstance)
2307 c->cleanup(itemNodeInstance);
2309 c->parentlessItems.remove(q);
2313 itemNodeInstance = 0;
2315 if (extra.isAllocated()) {
2316 extra->opacityNode = 0;
2317 extra->clipNode = 0;
2318 extra->rootNode = 0;
2319 extra->beforePaintNode = 0;
2325 for (int ii = 0; ii < childItems.count(); ++ii) {
2326 QQuickItem *child = childItems.at(ii);
2327 QQuickItemPrivate::get(child)->derefCanvas();
2332 if (extra.isAllocated() && extra->screenAttached)
2333 extra->screenAttached->canvasChanged(0);
2334 itemChange(QQuickItem::ItemSceneChange, (QQuickCanvas *)0);
2339 Returns a transform that maps points from canvas space into item space.
2341 QTransform QQuickItemPrivate::canvasToItemTransform() const
2343 // XXX todo - optimize
2344 return itemToCanvasTransform().inverted();
2348 Returns a transform that maps points from item space into canvas space.
2350 QTransform QQuickItemPrivate::itemToCanvasTransform() const
2353 QTransform rv = parentItem?QQuickItemPrivate::get(parentItem)->itemToCanvasTransform():QTransform();
2354 itemToParentTransform(rv);
2359 Motifies \a t with this items local transform relative to its parent.
2361 void QQuickItemPrivate::itemToParentTransform(QTransform &t) const
2366 if (!transforms.isEmpty()) {
2368 for (int ii = transforms.count() - 1; ii >= 0; --ii)
2369 transforms.at(ii)->applyTo(&m);
2370 t = m.toTransform();
2373 if (scale() != 1. || rotation() != 0.) {
2374 QPointF tp = computeTransformOrigin();
2375 t.translate(tp.x(), tp.y());
2376 t.scale(scale(), scale());
2377 t.rotate(rotation());
2378 t.translate(-tp.x(), -tp.y());
2384 \qmlproperty real QtQuick2::Item::childrenRect.x
2385 \qmlproperty real QtQuick2::Item::childrenRect.y
2386 \qmlproperty real QtQuick2::Item::childrenRect.width
2387 \qmlproperty real QtQuick2::Item::childrenRect.height
2389 The childrenRect properties allow an item access to the geometry of its
2390 children. This property is useful if you have an item that needs to be
2391 sized to fit its children.
2396 \qmlproperty list<Item> QtQuick2::Item::children
2397 \qmlproperty list<Object> QtQuick2::Item::resources
2399 The children property contains the list of visual children of this item.
2400 The resources property contains non-visual resources that you want to
2403 Generally you can rely on Item's default property to handle all this for
2404 you, but it can come in handy in some cases.
2423 Returns true if construction of the QML component is complete; otherwise
2426 It is often desirable to delay some processing until the component is
2429 \sa componentComplete()
2431 bool QQuickItem::isComponentComplete() const
2433 Q_D(const QQuickItem);
2434 return d->componentComplete;
2437 QQuickItemPrivate::QQuickItemPrivate()
2438 : _anchors(0), _stateGroup(0),
2439 flags(0), widthValid(false), heightValid(false), baselineOffsetValid(false), componentComplete(true),
2440 keepMouse(false), keepTouch(false), hoverEnabled(false), smooth(true), focus(false), activeFocus(false), notifiedFocus(false),
2441 notifiedActiveFocus(false), filtersChildMouseEvents(false), explicitVisible(true),
2442 effectiveVisible(true), explicitEnable(true), effectiveEnable(true), polishScheduled(false),
2443 inheritedLayoutMirror(false), effectiveLayoutMirror(false), isMirrorImplicit(true),
2444 inheritMirrorFromParent(false), inheritMirrorFromItem(false), childrenDoNotOverlap(false),
2445 staticSubtreeGeometry(false),
2446 isAccessible(false),
2448 dirtyAttributes(0), nextDirtyItem(0), prevDirtyItem(0),
2450 canvas(0), canvasRefCount(0), parentItem(0), sortedChildItems(&childItems),
2454 x(0), y(0), width(0), height(0), implicitWidth(0), implicitHeight(0),
2458 itemNodeInstance(0), groupNode(0), paintNode(0)
2462 QQuickItemPrivate::~QQuickItemPrivate()
2464 if (sortedChildItems != &childItems)
2465 delete sortedChildItems;
2468 void QQuickItemPrivate::init(QQuickItem *parent)
2472 static bool atexit_registered = false;
2473 if (!atexit_registered) {
2474 atexit(qt_print_item_count);
2475 atexit_registered = true;
2481 registerAccessorProperties();
2483 baselineOffsetValid = false;
2486 q->setParentItem(parent);
2487 QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(parent);
2488 setImplicitLayoutMirror(parentPrivate->inheritedLayoutMirror, parentPrivate->inheritMirrorFromParent);
2492 void QQuickItemPrivate::data_append(QQmlListProperty<QObject> *prop, QObject *o)
2497 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2499 // This test is measurably (albeit only slightly) faster than qobject_cast<>()
2500 const QMetaObject *mo = o->metaObject();
2501 while (mo && mo != &QQuickItem::staticMetaObject) {
2502 mo = mo->d.superdata;
2506 QQuickItem *item = static_cast<QQuickItem *>(o);
2507 item->setParentItem(that);
2509 if (o->inherits("QGraphicsItem"))
2510 qWarning("Cannot add a QtQuick 1.0 item (%s) into a QtQuick 2.0 scene!", o->metaObject()->className());
2512 // XXX todo - do we really want this behavior?
2518 \qmlproperty list<Object> QtQuick2::Item::data
2521 The data property allows you to freely mix visual children and resources
2522 in an item. If you assign a visual item to the data list it becomes
2523 a child and if you assign any other object type, it is added as a resource.
2547 data is a behind-the-scenes property: you should never need to explicitly
2551 int QQuickItemPrivate::data_count(QQmlListProperty<QObject> *prop)
2558 QObject *QQuickItemPrivate::data_at(QQmlListProperty<QObject> *prop, int i)
2566 void QQuickItemPrivate::data_clear(QQmlListProperty<QObject> *prop)
2572 QObject *QQuickItemPrivate::resources_at(QQmlListProperty<QObject> *prop, int index)
2574 const QObjectList children = prop->object->children();
2575 if (index < children.count())
2576 return children.at(index);
2581 void QQuickItemPrivate::resources_append(QQmlListProperty<QObject> *prop, QObject *o)
2583 // XXX todo - do we really want this behavior?
2584 o->setParent(prop->object);
2587 int QQuickItemPrivate::resources_count(QQmlListProperty<QObject> *prop)
2589 return prop->object->children().count();
2592 void QQuickItemPrivate::resources_clear(QQmlListProperty<QObject> *prop)
2594 // XXX todo - do we really want this behavior?
2595 const QObjectList children = prop->object->children();
2596 for (int index = 0; index < children.count(); index++)
2597 children.at(index)->setParent(0);
2600 QQuickItem *QQuickItemPrivate::children_at(QQmlListProperty<QQuickItem> *prop, int index)
2602 QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2603 if (index >= p->childItems.count() || index < 0)
2606 return p->childItems.at(index);
2609 void QQuickItemPrivate::children_append(QQmlListProperty<QQuickItem> *prop, QQuickItem *o)
2614 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2615 if (o->parentItem() == that)
2616 o->setParentItem(0);
2618 o->setParentItem(that);
2621 int QQuickItemPrivate::children_count(QQmlListProperty<QQuickItem> *prop)
2623 QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2624 return p->childItems.count();
2627 void QQuickItemPrivate::children_clear(QQmlListProperty<QQuickItem> *prop)
2629 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2630 QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2631 while (!p->childItems.isEmpty())
2632 p->childItems.at(0)->setParentItem(0);
2635 void QQuickItemPrivate::visibleChildren_append(QQmlListProperty<QQuickItem>*, QQuickItem *self)
2638 qmlInfo(self) << "QQuickItem: visibleChildren property is readonly and cannot be assigned to.";
2641 int QQuickItemPrivate::visibleChildren_count(QQmlListProperty<QQuickItem> *prop)
2643 QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2644 int visibleCount = 0;
2645 int c = p->childItems.count();
2647 if (p->childItems.at(c)->isVisible()) visibleCount++;
2650 return visibleCount;
2653 QQuickItem *QQuickItemPrivate::visibleChildren_at(QQmlListProperty<QQuickItem> *prop, int index)
2655 QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2656 const int childCount = p->childItems.count();
2657 if (index >= childCount || index < 0)
2660 int visibleCount = -1;
2661 for (int i = 0; i < childCount; i++) {
2662 if (p->childItems.at(i)->isVisible()) visibleCount++;
2663 if (visibleCount == index) return p->childItems.at(i);
2668 int QQuickItemPrivate::transform_count(QQmlListProperty<QQuickTransform> *prop)
2670 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2671 QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2673 return p->transforms.count();
2676 void QQuickTransform::appendToItem(QQuickItem *item)
2678 Q_D(QQuickTransform);
2682 QQuickItemPrivate *p = QQuickItemPrivate::get(item);
2684 if (!d->items.isEmpty() && !p->transforms.isEmpty() && p->transforms.contains(this)) {
2685 p->transforms.removeOne(this);
2686 p->transforms.append(this);
2688 p->transforms.append(this);
2689 d->items.append(item);
2692 p->dirty(QQuickItemPrivate::Transform);
2695 void QQuickTransform::prependToItem(QQuickItem *item)
2697 Q_D(QQuickTransform);
2701 QQuickItemPrivate *p = QQuickItemPrivate::get(item);
2703 if (!d->items.isEmpty() && !p->transforms.isEmpty() && p->transforms.contains(this)) {
2704 p->transforms.removeOne(this);
2705 p->transforms.prepend(this);
2707 p->transforms.prepend(this);
2708 d->items.append(item);
2711 p->dirty(QQuickItemPrivate::Transform);
2714 void QQuickItemPrivate::transform_append(QQmlListProperty<QQuickTransform> *prop, QQuickTransform *transform)
2719 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2720 transform->appendToItem(that);
2723 QQuickTransform *QQuickItemPrivate::transform_at(QQmlListProperty<QQuickTransform> *prop, int idx)
2725 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2726 QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2728 if (idx < 0 || idx >= p->transforms.count())
2731 return p->transforms.at(idx);
2734 void QQuickItemPrivate::transform_clear(QQmlListProperty<QQuickTransform> *prop)
2736 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2737 QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2739 for (int ii = 0; ii < p->transforms.count(); ++ii) {
2740 QQuickTransform *t = p->transforms.at(ii);
2741 QQuickTransformPrivate *tp = QQuickTransformPrivate::get(t);
2742 tp->items.removeOne(that);
2745 p->transforms.clear();
2747 p->dirty(QQuickItemPrivate::Transform);
2751 \property QQuickItem::childrenRect
2752 \brief The geometry of an item's children.
2754 This property holds the (collective) position and size of the item's children.
2758 \qmlproperty real QtQuick2::Item::x
2759 \qmlproperty real QtQuick2::Item::y
2760 \qmlproperty real QtQuick2::Item::width
2761 \qmlproperty real QtQuick2::Item::height
2763 Defines the item's position and size relative to its parent.
2766 Item { x: 100; y: 100; width: 100; height: 100 }
2771 \qmlproperty real QtQuick2::Item::z
2773 Sets the stacking order of sibling items. By default the stacking order is 0.
2775 Items with a higher stacking value are drawn on top of siblings with a
2776 lower stacking order. Items with the same stacking value are drawn
2777 bottom up in the order they appear. Items with a negative stacking
2778 value are drawn under their parent's content.
2780 The following example shows the various effects of stacking order.
2784 \li \image declarative-item_stacking1.png
2785 \li Same \c z - later children above earlier children:
2790 width: 100; height: 100
2794 x: 50; y: 50; width: 100; height: 100
2799 \li \image declarative-item_stacking2.png
2800 \li Higher \c z on top:
2806 width: 100; height: 100
2810 x: 50; y: 50; width: 100; height: 100
2815 \li \image declarative-item_stacking3.png
2816 \li Same \c z - children above parents:
2821 width: 100; height: 100
2824 x: 50; y: 50; width: 100; height: 100
2830 \li \image declarative-item_stacking4.png
2831 \li Lower \c z below:
2836 width: 100; height: 100
2840 x: 50; y: 50; width: 100; height: 100
2849 \qmlproperty bool QtQuick2::Item::visible
2851 This property holds whether the item is visible. By default this is true.
2853 Setting this property directly affects the \c visible value of child
2854 items. When set to \c false, the \c visible values of all child items also
2855 become \c false. When set to \c true, the \c visible values of child items
2856 are returned to \c true, unless they have explicitly been set to \c false.
2858 (Because of this flow-on behavior, using the \c visible property may not
2859 have the intended effect if a property binding should only respond to
2860 explicit property changes. In such cases it may be better to use the
2861 \l opacity property instead.)
2863 Setting this property to \c false automatically causes \l focus to be set
2864 to \c false, and this item will longer receive mouse and keyboard events.
2865 (In contrast, setting the \l opacity to 0 does not affect the \l focus
2866 property and the receiving of key events.)
2868 \note This property's value is only affected by changes to this property or
2869 the parent's \c visible property. It does not change, for example, if this
2870 item moves off-screen, or if the \l opacity changes to 0.
2875 \qmlproperty AnchorLine QtQuick2::Item::anchors.top
2876 \qmlproperty AnchorLine QtQuick2::Item::anchors.bottom
2877 \qmlproperty AnchorLine QtQuick2::Item::anchors.left
2878 \qmlproperty AnchorLine QtQuick2::Item::anchors.right
2879 \qmlproperty AnchorLine QtQuick2::Item::anchors.horizontalCenter
2880 \qmlproperty AnchorLine QtQuick2::Item::anchors.verticalCenter
2881 \qmlproperty AnchorLine QtQuick2::Item::anchors.baseline
2883 \qmlproperty Item QtQuick2::Item::anchors.fill
2884 \qmlproperty Item QtQuick2::Item::anchors.centerIn
2886 \qmlproperty real QtQuick2::Item::anchors.margins
2887 \qmlproperty real QtQuick2::Item::anchors.topMargin
2888 \qmlproperty real QtQuick2::Item::anchors.bottomMargin
2889 \qmlproperty real QtQuick2::Item::anchors.leftMargin
2890 \qmlproperty real QtQuick2::Item::anchors.rightMargin
2891 \qmlproperty real QtQuick2::Item::anchors.horizontalCenterOffset
2892 \qmlproperty real QtQuick2::Item::anchors.verticalCenterOffset
2893 \qmlproperty real QtQuick2::Item::anchors.baselineOffset
2895 \qmlproperty bool QtQuick2::Item::anchors.mirrored
2896 \qmlproperty bool QtQuick2::Item::anchors.alignWhenCentered
2898 Anchors provide a way to position an item by specifying its
2899 relationship with other items.
2901 Margins apply to top, bottom, left, right, and fill anchors.
2902 The \c anchors.margins property can be used to set all of the various margins at once, to the same value.
2903 Note that margins are anchor-specific and are not applied if an item does not
2906 Offsets apply for horizontal center, vertical center, and baseline anchors.
2910 \li \image declarative-anchors_example.png
2911 \li Text anchored to Image, horizontally centered and vertically below, with a margin.
2920 anchors.horizontalCenter: pic.horizontalCenter
2921 anchors.top: pic.bottom
2922 anchors.topMargin: 5
2928 \li \image declarative-anchors_example2.png
2930 Left of Text anchored to right of Image, with a margin. The y
2931 property of both defaults to 0.
2941 anchors.left: pic.right
2942 anchors.leftMargin: 5
2949 \c anchors.fill provides a convenient way for one item to have the
2950 same geometry as another item, and is equivalent to connecting all
2951 four directional anchors.
2953 To clear an anchor value, set it to \c undefined.
2955 \c anchors.mirrored returns true it the layout has been \l {LayoutMirroring}{mirrored}.
2957 \c anchors.alignWhenCentered (default true) forces centered anchors to align to a
2958 whole pixel, i.e. if the item being centered has an odd width/height the item
2959 will be positioned on a whole pixel rather than being placed on a half-pixel.
2960 This ensures the item is painted crisply. There are cases where this is not
2961 desirable, for example when rotating the item jitters may be apparent as the
2964 \note You can only anchor an item to siblings or a parent.
2966 For more information see \l {anchor-layout}{Anchor Layouts}.
2970 \property QQuickItem::baselineOffset
2971 \brief The position of the item's baseline in local coordinates.
2973 The baseline of a \l Text item is the imaginary line on which the text
2974 sits. Controls containing text usually set their baseline to the
2975 baseline of their text.
2977 For non-text items, a default baseline offset of 0 is used.
2979 QQuickAnchors *QQuickItemPrivate::anchors() const
2982 Q_Q(const QQuickItem);
2983 _anchors = new QQuickAnchors(const_cast<QQuickItem *>(q));
2984 if (!componentComplete)
2985 _anchors->classBegin();
2990 void QQuickItemPrivate::siblingOrderChanged()
2993 for (int ii = 0; ii < changeListeners.count(); ++ii) {
2994 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
2995 if (change.types & QQuickItemPrivate::SiblingOrder) {
2996 change.listener->itemSiblingOrderChanged(q);
3001 QQmlListProperty<QObject> QQuickItemPrivate::data()
3003 return QQmlListProperty<QObject>(q_func(), 0, QQuickItemPrivate::data_append,
3004 QQuickItemPrivate::data_count,
3005 QQuickItemPrivate::data_at,
3006 QQuickItemPrivate::data_clear);
3009 QRectF QQuickItem::childrenRect()
3012 if (!d->extra.isAllocated() || !d->extra->contents) {
3013 d->extra.value().contents = new QQuickContents(this);
3014 if (d->componentComplete)
3015 d->extra->contents->complete();
3017 return d->extra->contents->rectF();
3020 QList<QQuickItem *> QQuickItem::childItems() const
3022 Q_D(const QQuickItem);
3023 return d->childItems;
3026 bool QQuickItem::clip() const
3028 return flags() & ItemClipsChildrenToShape;
3031 void QQuickItem::setClip(bool c)
3036 setFlag(ItemClipsChildrenToShape, c);
3038 emit clipChanged(c);
3043 This function is called to handle this item's changes in
3044 geometry from \a oldGeometry to \a newGeometry. If the two
3045 geometries are the same, it doesn't do anything.
3047 void QQuickItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
3052 QQuickAnchorsPrivate::get(d->_anchors)->updateMe();
3054 bool xChange = (newGeometry.x() != oldGeometry.x());
3055 bool yChange = (newGeometry.y() != oldGeometry.y());
3056 bool widthChange = (newGeometry.width() != oldGeometry.width());
3057 bool heightChange = (newGeometry.height() != oldGeometry.height());
3059 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
3060 const QQuickItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
3061 if (change.types & QQuickItemPrivate::Geometry) {
3062 if (change.gTypes == QQuickItemPrivate::GeometryChange) {
3063 change.listener->itemGeometryChanged(this, newGeometry, oldGeometry);
3064 } else if ((xChange && (change.gTypes & QQuickItemPrivate::XChange)) ||
3065 (yChange && (change.gTypes & QQuickItemPrivate::YChange)) ||
3066 (widthChange && (change.gTypes & QQuickItemPrivate::WidthChange)) ||
3067 (heightChange && (change.gTypes & QQuickItemPrivate::HeightChange))) {
3068 change.listener->itemGeometryChanged(this, newGeometry, oldGeometry);
3078 emit widthChanged();
3080 emit heightChanged();
3084 Called by the rendering thread, as a result of
3085 QQuickItem::update(), when it is time to sync the state of the QML
3086 objects with the scene graph objects.
3088 The function should return the root of the scene graph subtree for
3089 this item. Most implementations will return a single
3090 QSGGeometryNode containing the visual representation of this item.
3091 \a oldNode is the node that was returned the last time the
3092 function was called.
3095 QSGNode *MyItem::updatePaintNode(QSGNode *node, UpdatePaintNodeData *)
3097 QSGSimpleRectNode *n = static_cast<QSGSimpleRectNode *>(node);
3099 n = new QSGSimpleRectNode();
3100 n->setColor(Qt::red);
3102 n->setRect(boundingRect());
3107 The main thread is blocked while this function is executed so it is safe to read
3108 values from the QQuickItem instance and other objects in the main thread.
3110 If no call to QQuickItem::updatePaintNode() result in actual scene graph
3111 changes, like QSGNode::markDirty() or adding and removing nodes, then
3112 the underlying implementation may decide to not render the scene again as
3113 the visual outcome is identical.
3115 \warning It is crucial that OpenGL operations and interaction with
3116 the scene graph happens exclusively on the rendering thread,
3117 primarily during the QQuickItem::updatePaintNode() call. The best
3118 rule of thumb is to only use classes with the "QSG" prefix inside
3119 the QQuickItem::updatePaintNode() function.
3121 \sa QSGMaterial, QSGSimpleMaterial, QSGGeometryNode, QSGGeometry,
3122 QSGFlatColorMaterial, QSGTextureMaterial, QSGNode::markDirty()
3125 QSGNode *QQuickItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
3132 This function is called when the item's scene graph resources are no longer needed.
3133 It allows items to free its resources, for instance textures, that are not owned by scene graph
3134 nodes. Note that scene graph nodes are managed by QQuickCanvas and should not be deleted by
3135 this function. Scene graph resources are no longer needed when the parent is set to null and
3136 the item is not used by any \l ShaderEffect or \l ShaderEffectSource.
3138 This function is called from the main thread. Therefore, resources used by the scene graph
3139 should not be deleted directly, but by calling \l QObject::deleteLater().
3141 \note The item destructor still needs to free its scene graph resources if not already done.
3144 void QQuickItem::releaseResources()
3148 QSGTransformNode *QQuickItemPrivate::createTransformNode()
3150 return new QSGTransformNode;
3153 void QQuickItem::updatePolish()
3157 void QQuickItemPrivate::addItemChangeListener(QQuickItemChangeListener *listener, ChangeTypes types)
3159 changeListeners.append(ChangeListener(listener, types));
3162 void QQuickItemPrivate::removeItemChangeListener(QQuickItemChangeListener *listener, ChangeTypes types)
3164 ChangeListener change(listener, types);
3165 changeListeners.removeOne(change);
3168 void QQuickItemPrivate::updateOrAddGeometryChangeListener(QQuickItemChangeListener *listener, GeometryChangeTypes types)
3170 ChangeListener change(listener, types);
3171 int index = changeListeners.find(change);
3173 changeListeners[index].gTypes = change.gTypes; //we may have different GeometryChangeTypes
3175 changeListeners.append(change);
3178 void QQuickItemPrivate::updateOrRemoveGeometryChangeListener(QQuickItemChangeListener *listener,
3179 GeometryChangeTypes types)
3181 ChangeListener change(listener, types);
3182 if (types == NoChange) {
3183 changeListeners.removeOne(change);
3185 int index = changeListeners.find(change);
3187 changeListeners[index].gTypes = change.gTypes; //we may have different GeometryChangeTypes
3191 void QQuickItem::keyPressEvent(QKeyEvent *event)
3196 void QQuickItem::keyReleaseEvent(QKeyEvent *event)
3201 void QQuickItem::inputMethodEvent(QInputMethodEvent *event)
3206 void QQuickItem::focusInEvent(QFocusEvent *)
3208 #ifndef QT_NO_ACCESSIBILITY
3209 QAccessibleEvent ev(this, QAccessible::Focus);
3210 QAccessible::updateAccessibility(&ev);
3214 void QQuickItem::focusOutEvent(QFocusEvent *)
3218 void QQuickItem::mousePressEvent(QMouseEvent *event)
3223 void QQuickItem::mouseMoveEvent(QMouseEvent *event)
3228 void QQuickItem::mouseReleaseEvent(QMouseEvent *event)
3233 void QQuickItem::mouseDoubleClickEvent(QMouseEvent *)
3237 void QQuickItem::mouseUngrabEvent()
3242 void QQuickItem::touchUngrabEvent()
3247 void QQuickItem::wheelEvent(QWheelEvent *event)
3252 void QQuickItem::touchEvent(QTouchEvent *event)
3257 void QQuickItem::hoverEnterEvent(QHoverEvent *event)
3262 void QQuickItem::hoverMoveEvent(QHoverEvent *event)
3267 void QQuickItem::hoverLeaveEvent(QHoverEvent *event)
3272 void QQuickItem::dragEnterEvent(QDragEnterEvent *event)
3277 void QQuickItem::dragMoveEvent(QDragMoveEvent *event)
3283 void QQuickItem::dragLeaveEvent(QDragLeaveEvent *event)
3289 void QQuickItem::dropEvent(QDropEvent *event)
3294 bool QQuickItem::childMouseEventFilter(QQuickItem *, QEvent *)
3299 void QQuickItem::windowDeactivateEvent()
3301 foreach (QQuickItem* item, childItems()) {
3302 item->windowDeactivateEvent();
3306 QVariant QQuickItem::inputMethodQuery(Qt::InputMethodQuery query) const
3308 Q_D(const QQuickItem);
3313 v = (bool)(flags() & ItemAcceptsInputMethod);
3316 case Qt::ImCursorRectangle:
3318 case Qt::ImCursorPosition:
3319 case Qt::ImSurroundingText:
3320 case Qt::ImCurrentSelection:
3321 case Qt::ImMaximumTextLength:
3322 case Qt::ImAnchorPosition:
3323 case Qt::ImPreferredLanguage:
3324 if (d->extra.isAllocated() && d->extra->keyHandler)
3325 v = d->extra->keyHandler->inputMethodQuery(query);
3333 QQuickAnchorLine QQuickItemPrivate::left() const
3335 Q_Q(const QQuickItem);
3336 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Left);
3339 QQuickAnchorLine QQuickItemPrivate::right() const
3341 Q_Q(const QQuickItem);
3342 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Right);
3345 QQuickAnchorLine QQuickItemPrivate::horizontalCenter() const
3347 Q_Q(const QQuickItem);
3348 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::HCenter);
3351 QQuickAnchorLine QQuickItemPrivate::top() const
3353 Q_Q(const QQuickItem);
3354 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Top);
3357 QQuickAnchorLine QQuickItemPrivate::bottom() const
3359 Q_Q(const QQuickItem);
3360 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Bottom);
3363 QQuickAnchorLine QQuickItemPrivate::verticalCenter() const
3365 Q_Q(const QQuickItem);
3366 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::VCenter);
3369 QQuickAnchorLine QQuickItemPrivate::baseline() const
3371 Q_Q(const QQuickItem);
3372 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Baseline);
3375 qreal QQuickItem::baselineOffset() const
3377 Q_D(const QQuickItem);
3378 if (d->baselineOffsetValid) {
3379 return d->baselineOffset;
3385 void QQuickItem::setBaselineOffset(qreal offset)
3388 if (offset == d->baselineOffset)
3391 d->baselineOffset = offset;
3392 d->baselineOffsetValid = true;
3394 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
3395 const QQuickItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
3396 if (change.types & QQuickItemPrivate::Geometry) {
3397 QQuickAnchorsPrivate *anchor = change.listener->anchorPrivate();
3399 anchor->updateVerticalAnchors();
3403 if (d->_anchors && (d->_anchors->usedAnchors() & QQuickAnchors::BaselineAnchor))
3404 QQuickAnchorsPrivate::get(d->_anchors)->updateVerticalAnchors();
3406 emit baselineOffsetChanged(offset);
3411 * Schedules a call to updatePaintNode() for this item.
3413 * The call to QQuickItem::updatePaintNode() will always happen if the
3414 * item is showing in a QQuickCanvas.
3416 * Only items which specifies QQuickItem::ItemHasContents are allowed
3417 * to call QQuickItem::update().
3419 void QQuickItem::update()
3422 Q_ASSERT(flags() & ItemHasContents);
3423 d->dirty(QQuickItemPrivate::Content);
3426 void QQuickItem::polish()
3429 if (!d->polishScheduled) {
3430 d->polishScheduled = true;
3432 QQuickCanvasPrivate *p = QQuickCanvasPrivate::get(d->canvas);
3433 bool maybeupdate = p->itemsToPolish.isEmpty();
3434 p->itemsToPolish.insert(this);
3435 if (maybeupdate) d->canvas->maybeUpdate();
3441 \qmlmethod object QtQuick2::Item::mapFromItem(Item item, real x, real y)
3442 \qmlmethod object QtQuick2::Item::mapFromItem(Item item, real x, real y, real width, real height)
3444 Maps the point (\a x, \a y) or rect (\a x, \a y, \a width, \a height), which is in \a
3445 item's coordinate system, to this item's coordinate system, and returns an object with \c x and
3446 \c y (and optionally \c width and \c height) properties matching the mapped coordinate.
3448 If \a item is a \c null value, this maps the point or rect from the coordinate system of
3451 void QQuickItem::mapFromItem(QQmlV8Function *args) const
3453 if (args->Length() != 0) {
3454 v8::Local<v8::Value> item = (*args)[0];
3455 QV8Engine *engine = args->engine();
3457 QQuickItem *itemObj = 0;
3458 if (!item->IsNull())
3459 itemObj = qobject_cast<QQuickItem*>(engine->toQObject(item));
3461 if (!itemObj && !item->IsNull()) {
3462 qmlInfo(this) << "mapFromItem() given argument \"" << engine->toString(item->ToString())
3463 << "\" which is neither null nor an Item";
3467 v8::Local<v8::Object> rv = v8::Object::New();
3468 args->returnValue(rv);
3470 qreal x = (args->Length() > 1)?(*args)[1]->NumberValue():0;
3471 qreal y = (args->Length() > 2)?(*args)[2]->NumberValue():0;
3473 if (args->Length() > 3) {
3474 qreal w = (*args)[3]->NumberValue();
3475 qreal h = (args->Length() > 4)?(*args)[4]->NumberValue():0;
3477 QRectF r = mapRectFromItem(itemObj, QRectF(x, y, w, h));
3479 rv->Set(v8::String::New("x"), v8::Number::New(r.x()));
3480 rv->Set(v8::String::New("y"), v8::Number::New(r.y()));
3481 rv->Set(v8::String::New("width"), v8::Number::New(r.width()));
3482 rv->Set(v8::String::New("height"), v8::Number::New(r.height()));
3484 QPointF p = mapFromItem(itemObj, QPointF(x, y));
3486 rv->Set(v8::String::New("x"), v8::Number::New(p.x()));
3487 rv->Set(v8::String::New("y"), v8::Number::New(p.y()));
3492 QTransform QQuickItem::itemTransform(QQuickItem *other, bool *ok) const
3494 Q_D(const QQuickItem);
3496 // XXX todo - we need to be able to handle common parents better and detect
3500 QTransform t = d->itemToCanvasTransform();
3501 if (other) t *= QQuickItemPrivate::get(other)->canvasToItemTransform();
3507 \qmlmethod object QtQuick2::Item::mapToItem(Item item, real x, real y)
3508 \qmlmethod object QtQuick2::Item::mapToItem(Item item, real x, real y, real width, real height)
3510 Maps the point (\a x, \a y) or rect (\a x, \a y, \a width, \a height), which is in this
3511 item's coordinate system, to \a item's coordinate system, and returns an object with \c x and
3512 \c y (and optionally \c width and \c height) properties matching the mapped coordinate.
3514 If \a item is a \c null value, this maps the point or rect to the coordinate system of the
3517 void QQuickItem::mapToItem(QQmlV8Function *args) const
3519 if (args->Length() != 0) {
3520 v8::Local<v8::Value> item = (*args)[0];
3521 QV8Engine *engine = args->engine();
3523 QQuickItem *itemObj = 0;
3524 if (!item->IsNull())
3525 itemObj = qobject_cast<QQuickItem*>(engine->toQObject(item));
3527 if (!itemObj && !item->IsNull()) {
3528 qmlInfo(this) << "mapToItem() given argument \"" << engine->toString(item->ToString())
3529 << "\" which is neither null nor an Item";
3533 v8::Local<v8::Object> rv = v8::Object::New();
3534 args->returnValue(rv);
3536 qreal x = (args->Length() > 1)?(*args)[1]->NumberValue():0;
3537 qreal y = (args->Length() > 2)?(*args)[2]->NumberValue():0;
3539 if (args->Length() > 3) {
3540 qreal w = (*args)[3]->NumberValue();
3541 qreal h = (args->Length() > 4)?(*args)[4]->NumberValue():0;
3543 QRectF r = mapRectToItem(itemObj, QRectF(x, y, w, h));
3545 rv->Set(v8::String::New("x"), v8::Number::New(r.x()));
3546 rv->Set(v8::String::New("y"), v8::Number::New(r.y()));
3547 rv->Set(v8::String::New("width"), v8::Number::New(r.width()));
3548 rv->Set(v8::String::New("height"), v8::Number::New(r.height()));
3550 QPointF p = mapToItem(itemObj, QPointF(x, y));
3552 rv->Set(v8::String::New("x"), v8::Number::New(p.x()));
3553 rv->Set(v8::String::New("y"), v8::Number::New(p.y()));
3558 void QQuickItem::forceActiveFocus()
3561 QQuickItem *parent = parentItem();
3563 if (parent->flags() & QQuickItem::ItemIsFocusScope) {
3564 parent->setFocus(true);
3566 parent = parent->parentItem();
3570 QQuickItem *QQuickItem::childAt(qreal x, qreal y) const
3572 // XXX todo - should this include transform etc.?
3573 const QList<QQuickItem *> children = childItems();
3574 for (int i = children.count()-1; i >= 0; --i) {
3575 QQuickItem *child = children.at(i);
3576 if (child->isVisible() && child->x() <= x
3577 && child->x() + child->width() >= x
3579 && child->y() + child->height() >= y)
3585 QQmlListProperty<QObject> QQuickItemPrivate::resources()
3587 return QQmlListProperty<QObject>(q_func(), 0, QQuickItemPrivate::resources_append,
3588 QQuickItemPrivate::resources_count,
3589 QQuickItemPrivate::resources_at,
3590 QQuickItemPrivate::resources_clear);
3593 QQmlListProperty<QQuickItem> QQuickItemPrivate::children()
3595 return QQmlListProperty<QQuickItem>(q_func(), 0, QQuickItemPrivate::children_append,
3596 QQuickItemPrivate::children_count,
3597 QQuickItemPrivate::children_at,
3598 QQuickItemPrivate::children_clear);
3603 \qmlproperty real QtQuick2::Item::visibleChildren
3604 This read-only property lists all of the item's children that are currently visible.
3605 Note that a child's visibility may have changed explicitly, or because the visibility
3606 of this (it's parent) item or another grandparent changed.
3608 QQmlListProperty<QQuickItem> QQuickItemPrivate::visibleChildren()
3610 return QQmlListProperty<QQuickItem>(q_func(), 0, QQuickItemPrivate::visibleChildren_append,
3611 QQuickItemPrivate::visibleChildren_count,
3612 QQuickItemPrivate::visibleChildren_at);
3616 QQmlListProperty<QQuickState> QQuickItemPrivate::states()
3618 return _states()->statesProperty();
3621 QQmlListProperty<QQuickTransition> QQuickItemPrivate::transitions()
3623 return _states()->transitionsProperty();
3626 QString QQuickItemPrivate::state() const
3631 return _stateGroup->state();
3634 void QQuickItemPrivate::setState(const QString &state)
3636 _states()->setState(state);
3639 QString QQuickItem::state() const
3641 Q_D(const QQuickItem);
3645 void QQuickItem::setState(const QString &state)
3651 QQmlListProperty<QQuickTransform> QQuickItem::transform()
3653 return QQmlListProperty<QQuickTransform>(this, 0, QQuickItemPrivate::transform_append,
3654 QQuickItemPrivate::transform_count,
3655 QQuickItemPrivate::transform_at,
3656 QQuickItemPrivate::transform_clear);
3659 void QQuickItem::classBegin()
3662 d->componentComplete = false;
3664 d->_stateGroup->classBegin();
3666 d->_anchors->classBegin();
3667 if (d->extra.isAllocated() && d->extra->layer)
3668 d->extra->layer->classBegin();
3671 void QQuickItem::componentComplete()
3674 d->componentComplete = true;
3676 d->_stateGroup->componentComplete();
3678 d->_anchors->componentComplete();
3679 QQuickAnchorsPrivate::get(d->_anchors)->updateOnComplete();
3682 if (d->extra.isAllocated() && d->extra->layer)
3683 d->extra->layer->componentComplete();
3685 if (d->extra.isAllocated() && d->extra->keyHandler)
3686 d->extra->keyHandler->componentComplete();
3688 if (d->extra.isAllocated() && d->extra->contents)
3689 d->extra->contents->complete();
3692 QQuickStateGroup *QQuickItemPrivate::_states()
3696 _stateGroup = new QQuickStateGroup;
3697 if (!componentComplete)
3698 _stateGroup->classBegin();
3699 FAST_CONNECT(_stateGroup, SIGNAL(stateChanged(QString)),
3700 q, SIGNAL(stateChanged(QString)))
3706 QPointF QQuickItemPrivate::computeTransformOrigin() const
3710 case QQuickItem::TopLeft:
3711 return QPointF(0, 0);
3712 case QQuickItem::Top:
3713 return QPointF(width / 2., 0);
3714 case QQuickItem::TopRight:
3715 return QPointF(width, 0);
3716 case QQuickItem::Left:
3717 return QPointF(0, height / 2.);
3718 case QQuickItem::Center:
3719 return QPointF(width / 2., height / 2.);
3720 case QQuickItem::Right:
3721 return QPointF(width, height / 2.);
3722 case QQuickItem::BottomLeft:
3723 return QPointF(0, height);
3724 case QQuickItem::Bottom:
3725 return QPointF(width / 2., height);
3726 case QQuickItem::BottomRight:
3727 return QPointF(width, height);
3731 void QQuickItemPrivate::transformChanged()
3733 if (extra.isAllocated() && extra->layer)
3734 extra->layer->updateMatrix();
3737 void QQuickItemPrivate::deliverKeyEvent(QKeyEvent *e)
3741 Q_ASSERT(e->isAccepted());
3742 if (extra.isAllocated() && extra->keyHandler) {
3743 if (e->type() == QEvent::KeyPress)
3744 extra->keyHandler->keyPressed(e, false);
3746 extra->keyHandler->keyReleased(e, false);
3748 if (e->isAccepted())
3754 if (e->type() == QEvent::KeyPress)
3755 q->keyPressEvent(e);
3757 q->keyReleaseEvent(e);
3759 if (e->isAccepted())
3762 if (extra.isAllocated() && extra->keyHandler) {
3765 if (e->type() == QEvent::KeyPress)
3766 extra->keyHandler->keyPressed(e, true);
3768 extra->keyHandler->keyReleased(e, true);
3772 void QQuickItemPrivate::deliverInputMethodEvent(QInputMethodEvent *e)
3776 Q_ASSERT(e->isAccepted());
3777 if (extra.isAllocated() && extra->keyHandler) {
3778 extra->keyHandler->inputMethodEvent(e, false);
3780 if (e->isAccepted())
3786 q->inputMethodEvent(e);
3788 if (e->isAccepted())
3791 if (extra.isAllocated() && extra->keyHandler) {
3794 extra->keyHandler->inputMethodEvent(e, true);
3798 void QQuickItemPrivate::deliverFocusEvent(QFocusEvent *e)
3802 if (e->type() == QEvent::FocusIn) {
3805 q->focusOutEvent(e);
3809 void QQuickItemPrivate::deliverMouseEvent(QMouseEvent *e)
3813 Q_ASSERT(e->isAccepted());
3815 switch (e->type()) {
3817 Q_ASSERT(!"Unknown event type");
3818 case QEvent::MouseMove:
3819 q->mouseMoveEvent(e);
3821 case QEvent::MouseButtonPress:
3822 q->mousePressEvent(e);
3824 case QEvent::MouseButtonRelease:
3825 q->mouseReleaseEvent(e);
3827 case QEvent::MouseButtonDblClick:
3828 q->mouseDoubleClickEvent(e);
3833 void QQuickItemPrivate::deliverWheelEvent(QWheelEvent *e)
3839 void QQuickItemPrivate::deliverTouchEvent(QTouchEvent *e)
3845 void QQuickItemPrivate::deliverHoverEvent(QHoverEvent *e)
3848 switch (e->type()) {
3850 Q_ASSERT(!"Unknown event type");
3851 case QEvent::HoverEnter:
3852 q->hoverEnterEvent(e);
3854 case QEvent::HoverLeave:
3855 q->hoverLeaveEvent(e);
3857 case QEvent::HoverMove:
3858 q->hoverMoveEvent(e);
3863 void QQuickItemPrivate::deliverDragEvent(QEvent *e)
3866 switch (e->type()) {
3868 Q_ASSERT(!"Unknown event type");
3869 case QEvent::DragEnter:
3870 q->dragEnterEvent(static_cast<QDragEnterEvent *>(e));
3872 case QEvent::DragLeave:
3873 q->dragLeaveEvent(static_cast<QDragLeaveEvent *>(e));
3875 case QEvent::DragMove:
3876 q->dragMoveEvent(static_cast<QDragMoveEvent *>(e));
3879 q->dropEvent(static_cast<QDropEvent *>(e));
3884 void QQuickItem::itemChange(ItemChange change, const ItemChangeData &value)
3891 Notify input method on updated query values if needed. \a indicates changed attributes.
3893 void QQuickItem::updateInputMethod(Qt::InputMethodQueries queries)
3895 if (hasActiveFocus())
3896 qApp->inputMethod()->update(queries);
3900 // XXX todo - do we want/need this anymore?
3901 QRectF QQuickItem::boundingRect() const
3903 Q_D(const QQuickItem);
3904 return QRectF(0, 0, d->width, d->height);
3908 QRectF QQuickItem::clipRect() const
3910 Q_D(const QQuickItem);
3911 return QRectF(0, 0, d->width, d->height);
3915 QQuickItem::TransformOrigin QQuickItem::transformOrigin() const
3917 Q_D(const QQuickItem);
3921 void QQuickItem::setTransformOrigin(TransformOrigin origin)
3924 if (origin == d->origin())
3927 d->extra.value().origin = origin;
3928 d->dirty(QQuickItemPrivate::TransformOrigin);
3930 emit transformOriginChanged(d->origin());
3933 QPointF QQuickItem::transformOriginPoint() const
3935 Q_D(const QQuickItem);
3936 if (d->extra.isAllocated() && !d->extra->userTransformOriginPoint.isNull())
3937 return d->extra->userTransformOriginPoint;
3938 return d->computeTransformOrigin();
3941 void QQuickItem::setTransformOriginPoint(const QPointF &point)
3944 if (d->extra.value().userTransformOriginPoint == point)
3947 d->extra->userTransformOriginPoint = point;
3948 d->dirty(QQuickItemPrivate::TransformOrigin);
3951 qreal QQuickItem::z() const
3953 Q_D(const QQuickItem);
3957 void QQuickItem::setZ(qreal v)
3963 d->extra.value().z = v;
3965 d->dirty(QQuickItemPrivate::ZValue);
3966 if (d->parentItem) {
3967 QQuickItemPrivate::get(d->parentItem)->dirty(QQuickItemPrivate::ChildrenStackingChanged);
3968 QQuickItemPrivate::get(d->parentItem)->markSortedChildrenDirty(this);
3973 if (d->extra.isAllocated() && d->extra->layer)
3974 d->extra->layer->updateZ();
3979 \qmlproperty real QtQuick2::Item::rotation
3980 This property holds the rotation of the item in degrees clockwise.
3982 This specifies how many degrees to rotate the item around its transformOrigin.
3983 The default rotation is 0 degrees (i.e. not rotated at all).
3987 \li \image declarative-rotation.png
3992 width: 100; height: 100
3995 x: 25; y: 25; width: 50; height: 50
4002 \sa transform, Rotation
4006 \qmlproperty real QtQuick2::Item::scale
4007 This property holds the scale of the item.
4009 A scale of less than 1 means the item will be displayed smaller than
4010 normal, and a scale of greater than 1 means the item will be
4011 displayed larger than normal. A negative scale means the item will
4014 By default, items are displayed at a scale of 1 (i.e. at their
4017 Scaling is from the item's transformOrigin.
4021 \li \image declarative-scale.png
4026 width: 100; height: 100
4029 width: 25; height: 25
4033 x: 25; y: 25; width: 50; height: 50
4040 \sa transform, Scale
4044 \qmlproperty real QtQuick2::Item::opacity
4046 This property holds the opacity of the item. Opacity is specified as a
4047 number between 0 (fully transparent) and 1 (fully opaque). The default is 1.
4049 When this property is set, the specified opacity is also applied
4050 individually to child items. In almost all cases this is what you want,
4051 but in some cases it may produce undesired results. For example in the
4052 second set of rectangles below, the red rectangle has specified an opacity
4053 of 0.5, which affects the opacity of its blue child rectangle even though
4054 the child has not specified an opacity.
4058 \li \image declarative-item_opacity1.png
4064 width: 100; height: 100
4067 x: 50; y: 50; width: 100; height: 100
4073 \li \image declarative-item_opacity2.png
4080 width: 100; height: 100
4083 x: 50; y: 50; width: 100; height: 100
4090 If an item's opacity is set to 0, the item will no longer receive mouse
4091 events, but will continue to receive key events and will retain the keyboard
4092 \l focus if it has been set. (In contrast, setting the \l visible property
4093 to \c false stops both mouse and keyboard events, and also removes focus
4098 Returns a value indicating whether mouse input should
4099 remain with this item exclusively.
4101 \sa setKeepMouseGrab()
4104 qreal QQuickItem::rotation() const
4106 Q_D(const QQuickItem);
4107 return d->rotation();
4110 void QQuickItem::setRotation(qreal r)
4113 if (d->rotation() == r)
4116 d->extra.value().rotation = r;
4118 d->dirty(QQuickItemPrivate::BasicTransform);
4120 d->itemChange(ItemRotationHasChanged, r);
4122 emit rotationChanged();
4125 qreal QQuickItem::scale() const
4127 Q_D(const QQuickItem);
4131 void QQuickItem::setScale(qreal s)
4134 if (d->scale() == s)
4137 d->extra.value().scale = s;
4139 d->dirty(QQuickItemPrivate::BasicTransform);
4141 emit scaleChanged();
4144 qreal QQuickItem::opacity() const
4146 Q_D(const QQuickItem);
4147 return d->opacity();
4150 void QQuickItem::setOpacity(qreal o)
4153 if (d->opacity() == o)
4156 d->extra.value().opacity = o;
4158 d->dirty(QQuickItemPrivate::OpacityValue);
4160 d->itemChange(ItemOpacityHasChanged, o);
4162 emit opacityChanged();
4165 bool QQuickItem::isVisible() const
4167 Q_D(const QQuickItem);
4168 return d->effectiveVisible;
4171 void QQuickItem::setVisible(bool v)
4174 if (v == d->explicitVisible)
4177 d->explicitVisible = v;
4179 d->dirty(QQuickItemPrivate::Visible);
4181 const bool childVisibilityChanged = d->setEffectiveVisibleRecur(d->calcEffectiveVisible());
4182 if (childVisibilityChanged && d->parentItem)
4183 emit d->parentItem->visibleChildrenChanged(); // signal the parent, not this!
4186 bool QQuickItem::isEnabled() const
4188 Q_D(const QQuickItem);
4189 return d->effectiveEnable;
4192 void QQuickItem::setEnabled(bool e)
4195 if (e == d->explicitEnable)
4198 d->explicitEnable = e;
4200 QQuickItem *scope = parentItem();
4201 while (scope && !scope->isFocusScope())
4202 scope = scope->parentItem();
4204 d->setEffectiveEnableRecur(scope, d->calcEffectiveEnable());
4207 bool QQuickItemPrivate::calcEffectiveVisible() const
4209 // XXX todo - Should the effective visible of an element with no parent just be the current
4210 // effective visible? This would prevent pointless re-processing in the case of an element
4211 // moving to/from a no-parent situation, but it is different from what graphics view does.
4212 return explicitVisible && (!parentItem || QQuickItemPrivate::get(parentItem)->effectiveVisible);
4215 bool QQuickItemPrivate::setEffectiveVisibleRecur(bool newEffectiveVisible)
4219 if (newEffectiveVisible && !explicitVisible) {
4220 // This item locally overrides visibility
4221 return false; // effective visibility didn't change
4224 if (newEffectiveVisible == effectiveVisible) {
4225 // No change necessary
4226 return false; // effective visibility didn't change
4229 effectiveVisible = newEffectiveVisible;
4231 if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
4234 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(canvas);
4235 if (canvasPriv->mouseGrabberItem == q)
4239 bool childVisibilityChanged = false;
4240 for (int ii = 0; ii < childItems.count(); ++ii)
4241 childVisibilityChanged |= QQuickItemPrivate::get(childItems.at(ii))->setEffectiveVisibleRecur(newEffectiveVisible);
4243 itemChange(QQuickItem::ItemVisibleHasChanged, effectiveVisible);
4244 #ifndef QT_NO_ACCESSIBILITY
4246 QAccessibleEvent ev(q, effectiveVisible ? QAccessible::ObjectShow : QAccessible::ObjectHide);
4247 QAccessible::updateAccessibility(&ev);
4250 emit q->visibleChanged();
4251 if (childVisibilityChanged)
4252 emit q->visibleChildrenChanged();
4254 return true; // effective visibility DID change
4257 bool QQuickItemPrivate::calcEffectiveEnable() const
4259 // XXX todo - Should the effective enable of an element with no parent just be the current
4260 // effective enable? This would prevent pointless re-processing in the case of an element
4261 // moving to/from a no-parent situation, but it is different from what graphics view does.
4262 return explicitEnable && (!parentItem || QQuickItemPrivate::get(parentItem)->effectiveEnable);
4265 void QQuickItemPrivate::setEffectiveEnableRecur(QQuickItem *scope, bool newEffectiveEnable)
4269 if (newEffectiveEnable && !explicitEnable) {
4270 // This item locally overrides enable
4274 if (newEffectiveEnable == effectiveEnable) {
4275 // No change necessary
4279 effectiveEnable = newEffectiveEnable;
4282 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(canvas);
4283 if (canvasPriv->mouseGrabberItem == q)
4285 if (scope && !effectiveEnable && activeFocus) {
4286 canvasPriv->clearFocusInScope(
4287 scope, q, QQuickCanvasPrivate::DontChangeFocusProperty | QQuickCanvasPrivate::DontChangeSubFocusItem);
4291 for (int ii = 0; ii < childItems.count(); ++ii) {
4292 QQuickItemPrivate::get(childItems.at(ii))->setEffectiveEnableRecur(
4293 (flags & QQuickItem::ItemIsFocusScope) && scope ? q : scope, newEffectiveEnable);
4296 if (canvas && scope && effectiveEnable && focus) {
4297 QQuickCanvasPrivate::get(canvas)->setFocusInScope(
4298 scope, q, QQuickCanvasPrivate::DontChangeFocusProperty | QQuickCanvasPrivate::DontChangeSubFocusItem);
4301 emit q->enabledChanged();
4304 QString QQuickItemPrivate::dirtyToString() const
4306 #define DIRTY_TO_STRING(value) if (dirtyAttributes & value) { \
4307 if (!rv.isEmpty()) \
4308 rv.append(QLatin1String("|")); \
4309 rv.append(QLatin1String(#value)); \
4312 // QString rv = QLatin1String("0x") + QString::number(dirtyAttributes, 16);
4315 DIRTY_TO_STRING(TransformOrigin);
4316 DIRTY_TO_STRING(Transform);
4317 DIRTY_TO_STRING(BasicTransform);
4318 DIRTY_TO_STRING(Position);
4319 DIRTY_TO_STRING(Size);
4320 DIRTY_TO_STRING(ZValue);
4321 DIRTY_TO_STRING(Content);
4322 DIRTY_TO_STRING(Smooth);
4323 DIRTY_TO_STRING(OpacityValue);
4324 DIRTY_TO_STRING(ChildrenChanged);
4325 DIRTY_TO_STRING(ChildrenStackingChanged);
4326 DIRTY_TO_STRING(ParentChanged);
4327 DIRTY_TO_STRING(Clip);
4328 DIRTY_TO_STRING(Canvas);
4329 DIRTY_TO_STRING(EffectReference);
4330 DIRTY_TO_STRING(Visible);
4331 DIRTY_TO_STRING(HideReference);
4332 DIRTY_TO_STRING(PerformanceHints);
4337 void QQuickItemPrivate::dirty(DirtyType type)
4340 if (type & (TransformOrigin | Transform | BasicTransform | Position | Size))
4343 if (!(dirtyAttributes & type) || (canvas && !prevDirtyItem)) {
4344 dirtyAttributes |= type;
4347 QQuickCanvasPrivate::get(canvas)->dirtyItem(q);
4352 void QQuickItemPrivate::addToDirtyList()
4357 if (!prevDirtyItem) {
4358 Q_ASSERT(!nextDirtyItem);
4360 QQuickCanvasPrivate *p = QQuickCanvasPrivate::get(canvas);
4361 nextDirtyItem = p->dirtyItemList;
4362 if (nextDirtyItem) QQuickItemPrivate::get(nextDirtyItem)->prevDirtyItem = &nextDirtyItem;
4363 prevDirtyItem = &p->dirtyItemList;
4364 p->dirtyItemList = q;
4367 Q_ASSERT(prevDirtyItem);
4370 void QQuickItemPrivate::removeFromDirtyList()
4372 if (prevDirtyItem) {
4373 if (nextDirtyItem) QQuickItemPrivate::get(nextDirtyItem)->prevDirtyItem = prevDirtyItem;
4374 *prevDirtyItem = nextDirtyItem;
4378 Q_ASSERT(!prevDirtyItem);
4379 Q_ASSERT(!nextDirtyItem);
4382 void QQuickItemPrivate::refFromEffectItem(bool hide)
4384 ++extra.value().effectRefCount;
4385 if (1 == extra->effectRefCount) {
4386 dirty(EffectReference);
4387 if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
4390 if (++extra->hideRefCount == 1)
4391 dirty(HideReference);
4395 void QQuickItemPrivate::derefFromEffectItem(bool unhide)
4397 Q_ASSERT(extra->effectRefCount);
4398 --extra->effectRefCount;
4399 if (0 == extra->effectRefCount) {
4400 dirty(EffectReference);
4401 if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
4404 if (--extra->hideRefCount == 0)
4405 dirty(HideReference);
4409 void QQuickItemPrivate::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data)
4413 case QQuickItem::ItemChildAddedChange:
4414 q->itemChange(change, data);
4415 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4416 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4417 if (change.types & QQuickItemPrivate::Children) {
4418 change.listener->itemChildAdded(q, data.item);
4422 case QQuickItem::ItemChildRemovedChange:
4423 q->itemChange(change, data);
4424 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4425 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4426 if (change.types & QQuickItemPrivate::Children) {
4427 change.listener->itemChildRemoved(q, data.item);
4431 case QQuickItem::ItemSceneChange:
4432 q->itemChange(change, data);
4434 case QQuickItem::ItemVisibleHasChanged:
4435 q->itemChange(change, data);
4436 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4437 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4438 if (change.types & QQuickItemPrivate::Visibility) {
4439 change.listener->itemVisibilityChanged(q);
4443 case QQuickItem::ItemParentHasChanged:
4444 q->itemChange(change, data);
4445 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4446 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4447 if (change.types & QQuickItemPrivate::Parent) {
4448 change.listener->itemParentChanged(q, data.item);
4452 case QQuickItem::ItemOpacityHasChanged:
4453 q->itemChange(change, data);
4454 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4455 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4456 if (change.types & QQuickItemPrivate::Opacity) {
4457 change.listener->itemOpacityChanged(q);
4461 case QQuickItem::ItemActiveFocusHasChanged:
4462 q->itemChange(change, data);
4464 case QQuickItem::ItemRotationHasChanged:
4465 q->itemChange(change, data);
4466 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4467 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4468 if (change.types & QQuickItemPrivate::Rotation) {
4469 change.listener->itemRotationChanged(q);
4477 \property QQuickItem::smooth
4478 \brief whether the item is smoothed or not.
4480 Primarily used in image based elements to decide if the item should use smooth
4481 sampling or not. Smooth sampling is performed using linear interpolation, while
4482 non-smooth is performed using nearest neighbor.
4484 In Qt Quick 2.0, this property has minimal impact on performance.
4490 Returns true if the item should be drawn with antialiasing and
4491 smooth pixmap filtering, false otherwise.
4493 The default is false.
4497 bool QQuickItem::smooth() const
4499 Q_D(const QQuickItem);
4504 Sets whether the item should be drawn with antialiasing and
4505 smooth pixmap filtering to \a smooth.
4509 void QQuickItem::setSmooth(bool smooth)
4512 if (d->smooth == smooth)
4516 d->dirty(QQuickItemPrivate::Smooth);
4518 emit smoothChanged(smooth);
4521 QQuickItem::Flags QQuickItem::flags() const
4523 Q_D(const QQuickItem);
4524 return (QQuickItem::Flags)d->flags;
4527 void QQuickItem::setFlag(Flag flag, bool enabled)
4531 setFlags((Flags)(d->flags | (quint32)flag));
4533 setFlags((Flags)(d->flags & ~(quint32)flag));
4536 void QQuickItem::setFlags(Flags flags)
4540 if ((flags & ItemIsFocusScope) != (d->flags & ItemIsFocusScope)) {
4541 if (flags & ItemIsFocusScope && !d->childItems.isEmpty() && d->canvas) {
4542 qWarning("QQuickItem: Cannot set FocusScope once item has children and is in a canvas.");
4543 flags &= ~ItemIsFocusScope;
4544 } else if (d->flags & ItemIsFocusScope) {
4545 qWarning("QQuickItem: Cannot unset FocusScope flag.");
4546 flags |= ItemIsFocusScope;
4550 if ((flags & ItemClipsChildrenToShape ) != (d->flags & ItemClipsChildrenToShape))
4551 d->dirty(QQuickItemPrivate::Clip);
4556 qreal QQuickItem::x() const
4558 Q_D(const QQuickItem);
4562 qreal QQuickItem::y() const
4564 Q_D(const QQuickItem);
4568 QPointF QQuickItem::pos() const
4570 Q_D(const QQuickItem);
4571 return QPointF(d->x, d->y);
4574 void QQuickItem::setX(qreal v)
4583 d->dirty(QQuickItemPrivate::Position);
4585 geometryChanged(QRectF(x(), y(), width(), height()),
4586 QRectF(oldx, y(), width(), height()));
4589 void QQuickItem::setY(qreal v)
4598 d->dirty(QQuickItemPrivate::Position);
4600 geometryChanged(QRectF(x(), y(), width(), height()),
4601 QRectF(x(), oldy, width(), height()));
4604 void QQuickItem::setPos(const QPointF &pos)
4607 if (QPointF(d->x, d->y) == pos)
4616 d->dirty(QQuickItemPrivate::Position);
4618 geometryChanged(QRectF(x(), y(), width(), height()),
4619 QRectF(oldx, oldy, width(), height()));
4622 qreal QQuickItem::width() const
4624 Q_D(const QQuickItem);
4628 void QQuickItem::setWidth(qreal w)
4634 d->widthValid = true;
4638 qreal oldWidth = d->width;
4641 d->dirty(QQuickItemPrivate::Size);
4643 geometryChanged(QRectF(x(), y(), width(), height()),
4644 QRectF(x(), y(), oldWidth, height()));
4647 void QQuickItem::resetWidth()
4650 d->widthValid = false;
4651 setImplicitWidth(implicitWidth());
4654 void QQuickItemPrivate::implicitWidthChanged()
4657 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4658 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4659 if (change.types & QQuickItemPrivate::ImplicitWidth) {
4660 change.listener->itemImplicitWidthChanged(q);
4663 emit q->implicitWidthChanged();
4666 qreal QQuickItemPrivate::getImplicitWidth() const
4668 return implicitWidth;
4671 Returns the width of the item that is implied by other properties that determine the content.
4673 qreal QQuickItem::implicitWidth() const
4675 Q_D(const QQuickItem);
4676 return d->getImplicitWidth();
4680 \qmlproperty real QtQuick2::Item::implicitWidth
4681 \qmlproperty real QtQuick2::Item::implicitHeight
4683 Defines the natural width or height of the Item if no \l width or \l height is specified.
4685 The default implicit size for most items is 0x0, however some elements have an inherent
4686 implicit size which cannot be overridden, e.g. Image, Text.
4688 Setting the implicit size is useful for defining components that have a preferred size
4689 based on their content, for example:
4696 property alias icon: image.source
4697 property alias label: text.text
4698 implicitWidth: text.implicitWidth + image.implicitWidth
4699 implicitHeight: Math.max(text.implicitHeight, image.implicitHeight)
4704 anchors.left: image.right; anchors.right: parent.right
4705 anchors.verticalCenter: parent.verticalCenter
4710 \b Note: using implicitWidth of Text or TextEdit and setting the width explicitly
4711 incurs a performance penalty as the text must be laid out twice.
4715 Sets the implied width of the item to \a w.
4716 This is the width implied by other properties that determine the content.
4718 void QQuickItem::setImplicitWidth(qreal w)
4721 bool changed = w != d->implicitWidth;
4722 d->implicitWidth = w;
4723 if (d->width == w || widthValid()) {
4725 d->implicitWidthChanged();
4726 if (d->width == w || widthValid())
4731 qreal oldWidth = d->width;
4734 d->dirty(QQuickItemPrivate::Size);
4736 geometryChanged(QRectF(x(), y(), width(), height()),
4737 QRectF(x(), y(), oldWidth, height()));
4740 d->implicitWidthChanged();
4744 Returns whether the width property has been set explicitly.
4746 bool QQuickItem::widthValid() const
4748 Q_D(const QQuickItem);
4749 return d->widthValid;
4752 qreal QQuickItem::height() const
4754 Q_D(const QQuickItem);
4758 void QQuickItem::setHeight(qreal h)
4764 d->heightValid = true;
4768 qreal oldHeight = d->height;
4771 d->dirty(QQuickItemPrivate::Size);
4773 geometryChanged(QRectF(x(), y(), width(), height()),
4774 QRectF(x(), y(), width(), oldHeight));
4777 void QQuickItem::resetHeight()
4780 d->heightValid = false;
4781 setImplicitHeight(implicitHeight());
4784 void QQuickItemPrivate::implicitHeightChanged()
4787 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4788 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4789 if (change.types & QQuickItemPrivate::ImplicitHeight) {
4790 change.listener->itemImplicitHeightChanged(q);
4793 emit q->implicitHeightChanged();
4796 qreal QQuickItemPrivate::getImplicitHeight() const
4798 return implicitHeight;
4802 Returns the height of the item that is implied by other properties that determine the content.
4804 qreal QQuickItem::implicitHeight() const
4806 Q_D(const QQuickItem);
4807 return d->getImplicitHeight();
4812 Sets the implied height of the item to \a h.
4813 This is the height implied by other properties that determine the content.
4815 void QQuickItem::setImplicitHeight(qreal h)
4818 bool changed = h != d->implicitHeight;
4819 d->implicitHeight = h;
4820 if (d->height == h || heightValid()) {
4822 d->implicitHeightChanged();
4823 if (d->height == h || heightValid())
4828 qreal oldHeight = d->height;
4831 d->dirty(QQuickItemPrivate::Size);
4833 geometryChanged(QRectF(x(), y(), width(), height()),
4834 QRectF(x(), y(), width(), oldHeight));
4837 d->implicitHeightChanged();
4840 void QQuickItem::setImplicitSize(qreal w, qreal h)
4843 bool wChanged = w != d->implicitWidth;
4844 bool hChanged = h != d->implicitHeight;
4846 d->implicitWidth = w;
4847 d->implicitHeight = h;
4851 if (d->width == w || widthValid()) {
4853 d->implicitWidthChanged();
4854 wDone = d->width == w || widthValid();
4857 if (d->height == h || heightValid()) {
4859 d->implicitHeightChanged();
4860 hDone = d->height == h || heightValid();
4866 qreal oldWidth = d->width;
4867 qreal oldHeight = d->height;
4873 d->dirty(QQuickItemPrivate::Size);
4875 geometryChanged(QRectF(x(), y(), width(), height()),
4876 QRectF(x(), y(), oldWidth, oldHeight));
4878 if (!wDone && wChanged)
4879 d->implicitWidthChanged();
4880 if (!hDone && hChanged)
4881 d->implicitHeightChanged();
4885 Returns whether the height property has been set explicitly.
4887 bool QQuickItem::heightValid() const
4889 Q_D(const QQuickItem);
4890 return d->heightValid;
4893 void QQuickItem::setSize(const QSizeF &size)
4896 d->heightValid = true;
4897 d->widthValid = true;
4899 if (QSizeF(d->width, d->height) == size)
4902 qreal oldHeight = d->height;
4903 qreal oldWidth = d->width;
4904 d->height = size.height();
4905 d->width = size.width();
4907 d->dirty(QQuickItemPrivate::Size);
4909 geometryChanged(QRectF(x(), y(), width(), height()),
4910 QRectF(x(), y(), oldWidth, oldHeight));
4913 bool QQuickItem::hasActiveFocus() const
4915 Q_D(const QQuickItem);
4916 return d->activeFocus;
4919 bool QQuickItem::hasFocus() const
4921 Q_D(const QQuickItem);
4925 void QQuickItem::setFocus(bool focus)
4928 if (d->focus == focus)
4931 if (d->canvas || d->parentItem) {
4932 // Need to find our nearest focus scope
4933 QQuickItem *scope = parentItem();
4934 while (scope && !scope->isFocusScope() && scope->parentItem())
4935 scope = scope->parentItem();
4938 QQuickCanvasPrivate::get(d->canvas)->setFocusInScope(scope, this);
4940 QQuickCanvasPrivate::get(d->canvas)->clearFocusInScope(scope, this);
4942 // do the focus changes from setFocusInScope/clearFocusInScope that are
4943 // unrelated to a canvas
4944 QVarLengthArray<QQuickItem *, 20> changed;
4945 QQuickItem *oldSubFocusItem = QQuickItemPrivate::get(scope)->subFocusItem;
4946 if (oldSubFocusItem) {
4947 QQuickItemPrivate::get(oldSubFocusItem)->updateSubFocusItem(scope, false);
4948 QQuickItemPrivate::get(oldSubFocusItem)->focus = false;
4949 changed << oldSubFocusItem;
4951 d->updateSubFocusItem(scope, focus);
4955 emit focusChanged(focus);
4957 QQuickCanvasPrivate::notifyFocusChangesRecur(changed.data(), changed.count() - 1);
4961 emit focusChanged(focus);
4965 bool QQuickItem::isFocusScope() const
4967 return flags() & ItemIsFocusScope;
4970 QQuickItem *QQuickItem::scopedFocusItem() const
4972 Q_D(const QQuickItem);
4973 if (!isFocusScope())
4976 return d->subFocusItem;
4980 Qt::MouseButtons QQuickItem::acceptedMouseButtons() const
4982 Q_D(const QQuickItem);
4983 return d->acceptedMouseButtons();
4986 void QQuickItem::setAcceptedMouseButtons(Qt::MouseButtons buttons)
4989 if (buttons & Qt::LeftButton)
4992 d->extra.clearFlag();
4994 buttons &= ~Qt::LeftButton;
4995 if (buttons || d->extra.isAllocated())
4996 d->extra.value().acceptedMouseButtons = buttons;
4999 bool QQuickItem::filtersChildMouseEvents() const
5001 Q_D(const QQuickItem);
5002 return d->filtersChildMouseEvents;
5005 void QQuickItem::setFiltersChildMouseEvents(bool filter)
5008 d->filtersChildMouseEvents = filter;
5011 bool QQuickItem::isUnderMouse() const
5013 Q_D(const QQuickItem);
5017 QPointF cursorPos = QGuiApplicationPrivate::lastCursorPosition;
5018 return contains(mapFromScene(cursorPos)); // ### refactor: d->canvas->mapFromGlobal(cursorPos))))
5021 bool QQuickItem::acceptHoverEvents() const
5023 Q_D(const QQuickItem);
5024 return d->hoverEnabled;
5027 void QQuickItem::setAcceptHoverEvents(bool enabled)
5030 d->hoverEnabled = enabled;
5033 void QQuickItem::grabMouse()
5038 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
5039 if (canvasPriv->mouseGrabberItem == this)
5042 QQuickItem *oldGrabber = canvasPriv->mouseGrabberItem;
5043 canvasPriv->mouseGrabberItem = this;
5045 QEvent ev(QEvent::UngrabMouse);
5046 d->canvas->sendEvent(oldGrabber, &ev);
5050 void QQuickItem::ungrabMouse()
5055 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
5056 if (canvasPriv->mouseGrabberItem != this) {
5057 qWarning("QQuickItem::ungrabMouse(): Item is not the mouse grabber.");
5061 canvasPriv->mouseGrabberItem = 0;
5063 QEvent ev(QEvent::UngrabMouse);
5064 d->canvas->sendEvent(this, &ev);
5067 bool QQuickItem::keepMouseGrab() const
5069 Q_D(const QQuickItem);
5070 return d->keepMouse;
5074 The flag indicating whether the mouse should remain
5075 with this item is set to \a keep.
5077 This is useful for items that wish to grab and keep mouse
5078 interaction following a predefined gesture. For example,
5079 an item that is interested in horizontal mouse movement
5080 may set keepMouseGrab to true once a threshold has been
5081 exceeded. Once keepMouseGrab has been set to true, filtering
5082 items will not react to mouse events.
5084 If the item does not indicate that it wishes to retain mouse grab,
5085 a filtering item may steal the grab. For example, Flickable may attempt
5086 to steal a mouse grab if it detects that the user has begun to
5091 void QQuickItem::setKeepMouseGrab(bool keep)
5094 d->keepMouse = keep;
5098 Grabs the touch points specified by \a ids.
5100 These touch points will be owned by the item until
5101 they are released. Alternatively, the grab can be stolen
5102 by a filtering item like Flickable. Use setKeepTouchGrab()
5103 to prevent the grab from being stolen.
5105 \sa ungrabTouchPoints(), setKeepTouchGrab()
5107 void QQuickItem::grabTouchPoints(const QList<int> &ids)
5112 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
5114 QSet<QQuickItem*> ungrab;
5115 for (int i = 0; i < ids.count(); ++i) {
5116 QQuickItem *oldGrabber = canvasPriv->itemForTouchPointId.value(ids.at(i));
5117 if (oldGrabber == this)
5120 canvasPriv->itemForTouchPointId[ids.at(i)] = this;
5122 ungrab.insert(oldGrabber);
5124 foreach (QQuickItem *oldGrabber, ungrab)
5125 oldGrabber->touchUngrabEvent();
5129 Ungrabs the touch points owned by this item.
5131 \sa grabTouchPoints()
5133 void QQuickItem::ungrabTouchPoints()
5138 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
5140 QMutableHashIterator<int, QQuickItem*> i(canvasPriv->itemForTouchPointId);
5141 while (i.hasNext()) {
5143 if (i.value() == this)
5150 Returns a value indicating whether the touch points grabbed by this item
5151 should remain with this item exclusively.
5153 \sa setKeepTouchGrab(), keepMouseGrab()
5155 bool QQuickItem::keepTouchGrab() const
5157 Q_D(const QQuickItem);
5158 return d->keepTouch;
5162 The flag indicating whether the touch points grabbed
5163 by this item should remain with this item is set to \a keep.
5165 This is useful for items that wish to grab and keep specific touch
5166 points following a predefined gesture. For example,
5167 an item that is interested in horizontal touch point movement
5168 may set setKeepTouchGrab to true once a threshold has been
5169 exceeded. Once setKeepTouchGrab has been set to true, filtering
5170 items will not react to the relevant touch points.
5172 If the item does not indicate that it wishes to retain touch point grab,
5173 a filtering item may steal the grab. For example, Flickable may attempt
5174 to steal a touch point grab if it detects that the user has begun to
5177 \sa keepTouchGrab(), setKeepMouseGrab()
5179 void QQuickItem::setKeepTouchGrab(bool keep)
5182 d->keepTouch = keep;
5186 Returns true if this item contains \a point, which is in local coordinates;
5187 returns false otherwise.
5189 This function can be overwritten in order to handle point collisions in items
5190 with custom shapes. The default implementation checks if the point is inside
5191 the item's bounding rect.
5193 Note that it's normally used to check if the item is under the mouse cursor,
5194 and for that reason, the implementation of this function should be as light-weight
5197 bool QQuickItem::contains(const QPointF &point) const
5199 Q_D(const QQuickItem);
5200 return QRectF(0, 0, d->width, d->height).contains(point);
5203 QPointF QQuickItem::mapToItem(const QQuickItem *item, const QPointF &point) const
5205 QPointF p = mapToScene(point);
5207 p = item->mapFromScene(p);
5211 QPointF QQuickItem::mapToScene(const QPointF &point) const
5213 Q_D(const QQuickItem);
5214 return d->itemToCanvasTransform().map(point);
5217 QRectF QQuickItem::mapRectToItem(const QQuickItem *item, const QRectF &rect) const
5219 Q_D(const QQuickItem);
5220 QTransform t = d->itemToCanvasTransform();
5222 t *= QQuickItemPrivate::get(item)->canvasToItemTransform();
5223 return t.mapRect(rect);
5226 QRectF QQuickItem::mapRectToScene(const QRectF &rect) const
5228 Q_D(const QQuickItem);
5229 return d->itemToCanvasTransform().mapRect(rect);
5232 QPointF QQuickItem::mapFromItem(const QQuickItem *item, const QPointF &point) const
5234 QPointF p = item?item->mapToScene(point):point;
5235 return mapFromScene(p);
5238 QPointF QQuickItem::mapFromScene(const QPointF &point) const
5240 Q_D(const QQuickItem);
5241 return d->canvasToItemTransform().map(point);
5244 QRectF QQuickItem::mapRectFromItem(const QQuickItem *item, const QRectF &rect) const
5246 Q_D(const QQuickItem);
5247 QTransform t = item?QQuickItemPrivate::get(item)->itemToCanvasTransform():QTransform();
5248 t *= d->canvasToItemTransform();
5249 return t.mapRect(rect);
5252 QRectF QQuickItem::mapRectFromScene(const QRectF &rect) const
5254 Q_D(const QQuickItem);
5255 return d->canvasToItemTransform().mapRect(rect);
5260 \qmlmethod QtQuick2::Item::forceActiveFocus()
5262 Forces active focus on the item.
5264 This method sets focus on the item and makes sure that all the focus scopes
5265 higher in the object hierarchy are also given the focus.
5269 Forces active focus on the item.
5271 This method sets focus on the item and makes sure that all the focus scopes
5272 higher in the object hierarchy are also given the focus.
5276 \qmlmethod QtQuick2::Item::childAt(real x, real y)
5278 Returns the visible child item at point (\a x, \a y), which is in this
5279 item's coordinate system, or \c null if there is no such item.
5283 Returns the visible child item at point (\a x, \a y), which is in this
5284 item's coordinate system, or 0 if there is no such item.
5288 \qmlproperty list<State> QtQuick2::Item::states
5289 This property holds a list of states defined by the item.
5305 \sa {qmlstate}{States}
5308 \qmlproperty list<Transition> QtQuick2::Item::transitions
5309 This property holds a list of transitions defined by the item.
5325 \sa {QML Animation and Transitions}{Transitions}
5328 \qmlproperty list<Filter> QtQuick2::Item::filter
5329 This property holds a list of graphical filters to be applied to the item.
5331 \l {Filter}{Filters} include things like \l {Blur}{blurring}
5332 the item, or giving it a \l Reflection. Some
5333 filters may not be available on all canvases; if a filter is not
5334 available on a certain canvas, it will simply not be applied for
5335 that canvas (but the QML will still be considered valid).
5353 \qmlproperty bool QtQuick2::Item::clip
5354 This property holds whether clipping is enabled. The default clip value is \c false.
5356 If clipping is enabled, an item will clip its own painting, as well
5357 as the painting of its children, to its bounding rectangle.
5359 Non-rectangular clipping regions are not supported for performance reasons.
5363 \property QQuickItem::clip
5364 This property holds whether clipping is enabled. The default clip value is \c false.
5366 If clipping is enabled, an item will clip its own painting, as well
5367 as the painting of its children, to its bounding rectangle. If you set
5368 clipping during an item's paint operation, remember to re-set it to
5369 prevent clipping the rest of your scene.
5371 Non-rectangular clipping regions are not supported for performance reasons.
5375 \qmlproperty string QtQuick2::Item::state
5377 This property holds the name of the current state of the item.
5379 This property is often used in scripts to change between states. For
5384 if (button.state == 'On')
5385 button.state = 'Off';
5387 button.state = 'On';
5391 If the item is in its base state (i.e. no explicit state has been
5392 set), \c state will be a blank string. Likewise, you can return an
5393 item to its base state by setting its current state to \c ''.
5395 \sa {qmlstates}{States}
5399 \qmlproperty list<Transform> QtQuick2::Item::transform
5400 This property holds the list of transformations to apply.
5402 For more information see \l Transform.
5406 \enum QQuickItem::TransformOrigin
5408 Controls the point about which simple transforms like scale apply.
5410 \value TopLeft The top-left corner of the item.
5411 \value Top The center point of the top of the item.
5412 \value TopRight The top-right corner of the item.
5413 \value Left The left most point of the vertical middle.
5414 \value Center The center of the item.
5415 \value Right The right most point of the vertical middle.
5416 \value BottomLeft The bottom-left corner of the item.
5417 \value Bottom The center point of the bottom of the item.
5418 \value BottomRight The bottom-right corner of the item.
5423 \qmlproperty bool QtQuick2::Item::activeFocus
5425 This property indicates whether the item has active focus.
5427 An item with active focus will receive keyboard input,
5428 or is a FocusScope ancestor of the item that will receive keyboard input.
5430 Usually, activeFocus is gained by setting focus on an item and its enclosing
5431 FocusScopes. In the following example \c input will have activeFocus.
5444 \sa focus, {qmlfocus}{Keyboard Focus}
5448 \qmlproperty bool QtQuick2::Item::focus
5449 This property indicates whether the item has focus within the enclosing focus scope. If true, this item
5450 will gain active focus when the enclosing focus scope gains active focus.
5451 In the following example, \c input will be given active focus when \c scope gains active focus.
5464 For the purposes of this property, the scene as a whole is assumed to act like a focus scope.
5465 On a practical level, that means the following QML will give active focus to \c input on startup.
5476 \sa activeFocus, {qmlfocus}{Keyboard Focus}
5481 \property QQuickItem::anchors
5486 \property QQuickItem::left
5491 \property QQuickItem::right
5496 \property QQuickItem::horizontalCenter
5501 \property QQuickItem::top
5506 \property QQuickItem::bottom
5511 \property QQuickItem::verticalCenter
5516 \property QQuickItem::focus
5521 \property QQuickItem::transform
5526 \property QQuickItem::transformOrigin
5531 \property QQuickItem::activeFocus
5536 \property QQuickItem::baseline
5541 \property QQuickItem::data
5546 \property QQuickItem::resources
5551 \property QQuickItem::state
5556 \property QQuickItem::states
5561 \property QQuickItem::transformOriginPoint
5566 \property QQuickItem::transitions
5570 bool QQuickItem::event(QEvent *ev)
5573 if (ev->type() == QEvent::PolishRequest) {
5575 d->polishScheduled = false;
5579 return QObject::event(ev);
5582 if (ev->type() == QEvent::InputMethodQuery) {
5583 QInputMethodQueryEvent *query = static_cast<QInputMethodQueryEvent *>(ev);
5584 Qt::InputMethodQueries queries = query->queries();
5585 for (uint i = 0; i < 32; ++i) {
5586 Qt::InputMethodQuery q = (Qt::InputMethodQuery)(int)(queries & (1<<i));
5588 QVariant v = inputMethodQuery(q);
5589 query->setValue(q, v);
5594 } else if (ev->type() == QEvent::InputMethod) {
5595 inputMethodEvent(static_cast<QInputMethodEvent *>(ev));
5598 return QObject::event(ev);
5601 #ifndef QT_NO_DEBUG_STREAM
5602 QDebug operator<<(QDebug debug, QQuickItem *item)
5605 debug << "QQuickItem(0)";
5609 debug << item->metaObject()->className() << "(this =" << ((void*)item)
5610 << ", name=" << item->objectName()
5611 << ", parent =" << ((void*)item->parentItem())
5612 << ", geometry =" << QRectF(item->pos(), QSizeF(item->width(), item->height()))
5613 << ", z =" << item->z() << ')';
5618 qint64 QQuickItemPrivate::consistentTime = -1;
5619 void QQuickItemPrivate::setConsistentTime(qint64 t)
5624 class QElapsedTimerConsistentTimeHack
5628 t1 = QQuickItemPrivate::consistentTime;
5632 return QQuickItemPrivate::consistentTime - t1;
5635 qint64 val = QQuickItemPrivate::consistentTime - t1;
5636 t1 = QQuickItemPrivate::consistentTime;
5646 void QQuickItemPrivate::start(QElapsedTimer &t)
5648 if (QQuickItemPrivate::consistentTime == -1)
5651 ((QElapsedTimerConsistentTimeHack*)&t)->start();
5654 qint64 QQuickItemPrivate::elapsed(QElapsedTimer &t)
5656 if (QQuickItemPrivate::consistentTime == -1)
5659 return ((QElapsedTimerConsistentTimeHack*)&t)->elapsed();
5662 qint64 QQuickItemPrivate::restart(QElapsedTimer &t)
5664 if (QQuickItemPrivate::consistentTime == -1)
5667 return ((QElapsedTimerConsistentTimeHack*)&t)->restart();
5671 \fn bool QQuickItem::isTextureProvider() const
5673 Returns true if this item is a texture provider. The default
5674 implementation returns false.
5676 This function can be called from any thread.
5679 bool QQuickItem::isTextureProvider() const
5681 Q_D(const QQuickItem);
5682 return d->extra.isAllocated() && d->extra->layer && d->extra->layer->effectSource() ?
5683 d->extra->layer->effectSource()->isTextureProvider() : false;
5687 \fn QSGTextureProvider *QQuickItem::textureProvider() const
5689 Returns the texture provider for an item. The default implementation
5692 This function may only be called on the rendering thread.
5695 QSGTextureProvider *QQuickItem::textureProvider() const
5697 Q_D(const QQuickItem);
5698 return d->extra.isAllocated() && d->extra->layer && d->extra->layer->effectSource() ?
5699 d->extra->layer->effectSource()->textureProvider() : 0;
5702 QQuickItemLayer *QQuickItemPrivate::layer() const
5704 if (!extra.isAllocated() || !extra->layer) {
5705 extra.value().layer = new QQuickItemLayer(const_cast<QQuickItem *>(q_func()));
5706 if (!componentComplete)
5707 extra->layer->classBegin();
5709 return extra->layer;
5712 QQuickItemLayer::QQuickItemLayer(QQuickItem *item)
5717 , m_componentComplete(true)
5718 , m_wrapMode(QQuickShaderEffectSource::ClampToEdge)
5719 , m_format(QQuickShaderEffectSource::RGBA)
5721 , m_effectComponent(0)
5727 QQuickItemLayer::~QQuickItemLayer()
5729 delete m_effectSource;
5736 \qmlproperty bool QtQuick2::Item::layer.enabled
5738 Holds wether the item is layered or not. Layering is disabled by default.
5740 A layered item is rendered into an offscreen surface and cached until
5741 it is changed. Enabling layering for complex QML item hierarchies can
5742 some times be an optimization.
5744 None of the other layer properties have any effect when the layer
5748 void QQuickItemLayer::setEnabled(bool e)
5753 if (m_componentComplete) {
5760 emit enabledChanged(e);
5763 void QQuickItemLayer::classBegin()
5765 Q_ASSERT(!m_effectSource);
5766 Q_ASSERT(!m_effect);
5767 m_componentComplete = false;
5770 void QQuickItemLayer::componentComplete()
5772 Q_ASSERT(!m_componentComplete);
5773 m_componentComplete = true;
5778 void QQuickItemLayer::activate()
5780 Q_ASSERT(!m_effectSource);
5781 m_effectSource = new QQuickShaderEffectSource();
5783 QQuickItem *parentItem = m_item->parentItem();
5785 m_effectSource->setParentItem(parentItem);
5786 m_effectSource->stackAfter(m_item);
5789 m_effectSource->setSourceItem(m_item);
5790 m_effectSource->setHideSource(true);
5791 m_effectSource->setSmooth(m_smooth);
5792 m_effectSource->setTextureSize(m_size);
5793 m_effectSource->setSourceRect(m_sourceRect);
5794 m_effectSource->setMipmap(m_mipmap);
5795 m_effectSource->setWrapMode(m_wrapMode);
5796 m_effectSource->setFormat(m_format);
5798 if (m_effectComponent)
5801 m_effectSource->setVisible(m_item->isVisible() && !m_effect);
5808 QQuickItemPrivate *id = QQuickItemPrivate::get(m_item);
5809 id->addItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Opacity | QQuickItemPrivate::Parent | QQuickItemPrivate::Visibility | QQuickItemPrivate::SiblingOrder);
5812 void QQuickItemLayer::deactivate()
5814 Q_ASSERT(m_effectSource);
5816 if (m_effectComponent)
5819 delete m_effectSource;
5822 QQuickItemPrivate *id = QQuickItemPrivate::get(m_item);
5823 id->removeItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Opacity | QQuickItemPrivate::Parent | QQuickItemPrivate::Visibility | QQuickItemPrivate::SiblingOrder);
5826 void QQuickItemLayer::activateEffect()
5828 Q_ASSERT(m_effectSource);
5829 Q_ASSERT(m_effectComponent);
5830 Q_ASSERT(!m_effect);
5832 QObject *created = m_effectComponent->beginCreate(m_effectComponent->creationContext());
5833 m_effect = qobject_cast<QQuickItem *>(created);
5835 qWarning("Item: layer.effect is not a QML Item.");
5836 m_effectComponent->completeCreate();
5840 QQuickItem *parentItem = m_item->parentItem();
5842 m_effect->setParentItem(parentItem);
5843 m_effect->stackAfter(m_effectSource);
5845 m_effect->setVisible(m_item->isVisible());
5846 m_effect->setProperty(m_name, qVariantFromValue<QObject *>(m_effectSource));
5847 m_effectComponent->completeCreate();
5850 void QQuickItemLayer::deactivateEffect()
5852 Q_ASSERT(m_effectSource);
5853 Q_ASSERT(m_effectComponent);
5861 \qmlproperty Component QtQuick2::Item::layer.effect
5863 Holds the effect that is applied to this layer.
5865 The effect is typically a \l ShaderEffect component, although any \l Item component can be
5866 assigned. The effect should have a source texture property with a name matching \l samplerName.
5871 void QQuickItemLayer::setEffect(QQmlComponent *component)
5873 if (component == m_effectComponent)
5876 bool updateNeeded = false;
5877 if (m_effectSource && m_effectComponent) {
5879 updateNeeded = true;
5882 m_effectComponent = component;
5884 if (m_effectSource && m_effectComponent) {
5886 updateNeeded = true;
5894 m_effectSource->setVisible(m_item->isVisible() && !m_effect);
5897 emit effectChanged(component);
5902 \qmlproperty bool QtQuick2::Item::layer.mipmap
5904 If this property is true, mipmaps are generated for the texture.
5906 \note Some OpenGL ES 2 implementations do not support mipmapping of
5907 non-power-of-two textures.
5910 void QQuickItemLayer::setMipmap(bool mipmap)
5912 if (mipmap == m_mipmap)
5917 m_effectSource->setMipmap(m_mipmap);
5919 emit mipmapChanged(mipmap);
5924 \qmlproperty enumeration QtQuick2::Item::layer.format
5926 This property defines the internal OpenGL format of the texture.
5927 Modifying this property makes most sense when the \a layer.effect is also
5928 specified. Depending on the OpenGL implementation, this property might
5929 allow you to save some texture memory.
5932 \li ShaderEffectSource.Alpha - GL_ALPHA
5933 \li ShaderEffectSource.RGB - GL_RGB
5934 \li ShaderEffectSource.RGBA - GL_RGBA
5937 \note Some OpenGL implementations do not support the GL_ALPHA format.
5940 void QQuickItemLayer::setFormat(QQuickShaderEffectSource::Format f)
5947 m_effectSource->setFormat(m_format);
5949 emit formatChanged(m_format);
5954 \qmlproperty enumeration QtQuick2::Item::layer.sourceRect
5956 This property defines which rectangular area of the \l sourceItem to
5957 render into the texture. The source rectangle can be larger than
5958 \l sourceItem itself. If the rectangle is null, which is the default,
5959 the whole \l sourceItem is rendered to texture.
5962 void QQuickItemLayer::setSourceRect(const QRectF &sourceRect)
5964 if (sourceRect == m_sourceRect)
5966 m_sourceRect = sourceRect;
5969 m_effectSource->setSourceRect(m_sourceRect);
5971 emit sourceRectChanged(sourceRect);
5977 \qmlproperty bool QtQuick2::Item::layer.smooth
5979 Holds whether the layer is smoothly transformed.
5982 void QQuickItemLayer::setSmooth(bool s)
5989 m_effectSource->setSmooth(m_smooth);
5991 emit smoothChanged(s);
5997 \qmlproperty size QtQuick2::Item::layer.textureSize
5999 This property holds the requested pixel size of the layers texture. If it is empty,
6000 which is the default, the size of the item is used.
6002 \note Some platforms have a limit on how small framebuffer objects can be,
6003 which means the actual texture size might be larger than the requested
6007 void QQuickItemLayer::setSize(const QSize &size)
6014 m_effectSource->setTextureSize(size);
6016 emit sizeChanged(size);
6022 \qmlproperty enumeration QtQuick2::Item::layer.wrapMode
6024 This property defines the OpenGL wrap modes associated with the texture.
6025 Modifying this property makes most sense when the \a layer.effect is
6029 \li ShaderEffectSource.ClampToEdge - GL_CLAMP_TO_EDGE both horizontally and vertically
6030 \li ShaderEffectSource.RepeatHorizontally - GL_REPEAT horizontally, GL_CLAMP_TO_EDGE vertically
6031 \li ShaderEffectSource.RepeatVertically - GL_CLAMP_TO_EDGE horizontally, GL_REPEAT vertically
6032 \li ShaderEffectSource.Repeat - GL_REPEAT both horizontally and vertically
6035 \note Some OpenGL ES 2 implementations do not support the GL_REPEAT
6036 wrap mode with non-power-of-two textures.
6039 void QQuickItemLayer::setWrapMode(QQuickShaderEffectSource::WrapMode mode)
6041 if (mode == m_wrapMode)
6046 m_effectSource->setWrapMode(m_wrapMode);
6048 emit wrapModeChanged(mode);
6052 \qmlproperty string QtQuick2::Item::layer.samplerName
6054 Holds the name of the effect's source texture property.
6056 samplerName needs to match the name of the effect's source texture property
6057 so that the Item can pass the layer's offscreen surface to the effect correctly.
6059 \sa effect, ShaderEffect
6062 void QQuickItemLayer::setName(const QByteArray &name) {
6066 m_effect->setProperty(m_name, QVariant());
6067 m_effect->setProperty(name, qVariantFromValue<QObject *>(m_effectSource));
6070 emit nameChanged(name);
6073 void QQuickItemLayer::itemOpacityChanged(QQuickItem *item)
6079 void QQuickItemLayer::itemGeometryChanged(QQuickItem *, const QRectF &, const QRectF &)
6084 void QQuickItemLayer::itemParentChanged(QQuickItem *item, QQuickItem *parent)
6087 Q_ASSERT(item == m_item);
6088 Q_ASSERT(parent != m_effectSource);
6089 Q_ASSERT(parent == 0 || parent != m_effect);
6091 m_effectSource->setParentItem(parent);
6093 m_effectSource->stackAfter(m_item);
6096 m_effect->setParentItem(parent);
6098 m_effect->stackAfter(m_effectSource);
6102 void QQuickItemLayer::itemSiblingOrderChanged(QQuickItem *)
6104 m_effectSource->stackAfter(m_item);
6106 m_effect->stackAfter(m_effectSource);
6109 void QQuickItemLayer::itemVisibilityChanged(QQuickItem *)
6111 QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
6113 l->setVisible(m_item->isVisible());
6116 void QQuickItemLayer::updateZ()
6118 if (!m_componentComplete || !m_enabled)
6120 QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
6122 l->setZ(m_item->z());
6125 void QQuickItemLayer::updateOpacity()
6127 QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
6129 l->setOpacity(m_item->opacity());
6132 void QQuickItemLayer::updateGeometry()
6134 QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
6136 QRectF bounds = m_item->clipRect();
6137 l->setWidth(bounds.width());
6138 l->setHeight(bounds.height());
6139 l->setX(bounds.x() + m_item->x());
6140 l->setY(bounds.y() + m_item->y());
6143 void QQuickItemLayer::updateMatrix()
6145 // Called directly from transformChanged(), so needs some extra
6147 if (!m_componentComplete || !m_enabled)
6149 QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
6151 QQuickItemPrivate *ld = QQuickItemPrivate::get(l);
6152 l->setScale(m_item->scale());
6153 l->setRotation(m_item->rotation());
6154 ld->transforms = QQuickItemPrivate::get(m_item)->transforms;
6155 if (ld->origin() != QQuickItemPrivate::get(m_item)->origin())
6156 ld->extra.value().origin = QQuickItemPrivate::get(m_item)->origin();
6157 ld->dirty(QQuickItemPrivate::Transform);
6160 QQuickItemPrivate::ExtraData::ExtraData()
6161 : z(0), scale(1), rotation(0), opacity(1),
6162 contents(0), screenAttached(0), layoutDirectionAttached(0),
6163 keyHandler(0), layer(0), effectRefCount(0), hideRefCount(0),
6164 opacityNode(0), clipNode(0), rootNode(0), beforePaintNode(0),
6165 acceptedMouseButtons(0), origin(QQuickItem::Center)
6171 #include <moc_qquickitem.cpp>