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 For specifying 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 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 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 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 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 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 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(qmlobject_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 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 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 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(qmlobject_cast<QQuickItem*>(parent))
1310 Q_D(QQuickKeysAttached);
1311 m_processPost = false;
1312 d->item = qmlobject_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 Property 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 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 = qmlobject_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 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 A basic visual QML type
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.lastIndexOf(this);
2087 int siblingIndex = parentPrivate->childItems.lastIndexOf(const_cast<QQuickItem *>(sibling));
2089 Q_ASSERT(myIndex != -1 && siblingIndex != -1);
2091 if (myIndex == siblingIndex - 1)
2094 parentPrivate->childItems.move(myIndex, myIndex < siblingIndex ? siblingIndex - 1 : siblingIndex);
2096 parentPrivate->dirty(QQuickItemPrivate::ChildrenStackingChanged);
2097 parentPrivate->markSortedChildrenDirty(this);
2099 for (int ii = qMin(siblingIndex, myIndex); ii < parentPrivate->childItems.count(); ++ii)
2100 QQuickItemPrivate::get(parentPrivate->childItems.at(ii))->siblingOrderChanged();
2103 void QQuickItem::stackAfter(const QQuickItem *sibling)
2106 if (!sibling || sibling == this || !d->parentItem || d->parentItem != QQuickItemPrivate::get(sibling)->parentItem) {
2107 qWarning("QQuickItem::stackAfter: Cannot stack after %p, which must be a sibling", sibling);
2111 QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(d->parentItem);
2113 int myIndex = parentPrivate->childItems.lastIndexOf(this);
2114 int siblingIndex = parentPrivate->childItems.lastIndexOf(const_cast<QQuickItem *>(sibling));
2116 Q_ASSERT(myIndex != -1 && siblingIndex != -1);
2118 if (myIndex == siblingIndex + 1)
2121 parentPrivate->childItems.move(myIndex, myIndex > siblingIndex ? siblingIndex + 1 : siblingIndex);
2123 parentPrivate->dirty(QQuickItemPrivate::ChildrenStackingChanged);
2124 parentPrivate->markSortedChildrenDirty(this);
2126 for (int ii = qMin(myIndex, siblingIndex + 1); ii < parentPrivate->childItems.count(); ++ii)
2127 QQuickItemPrivate::get(parentPrivate->childItems.at(ii))->siblingOrderChanged();
2131 Returns the QQuickItem parent of this item.
2133 QQuickItem *QQuickItem::parentItem() const
2135 Q_D(const QQuickItem);
2136 return d->parentItem;
2139 QQuickCanvas *QQuickItem::canvas() const
2141 Q_D(const QQuickItem);
2145 static bool itemZOrder_sort(QQuickItem *lhs, QQuickItem *rhs)
2147 return lhs->z() < rhs->z();
2150 QList<QQuickItem *> QQuickItemPrivate::paintOrderChildItems() const
2152 if (sortedChildItems)
2153 return *sortedChildItems;
2155 // If none of the items have set Z then the paint order list is the same as
2156 // the childItems list. This is by far the most common case.
2158 for (int i = 0; i < childItems.count(); ++i) {
2159 if (QQuickItemPrivate::get(childItems.at(i))->z() != 0.) {
2165 sortedChildItems = new QList<QQuickItem*>(childItems);
2166 qStableSort(sortedChildItems->begin(), sortedChildItems->end(), itemZOrder_sort);
2167 return *sortedChildItems;
2170 sortedChildItems = const_cast<QList<QQuickItem*>*>(&childItems);
2175 void QQuickItemPrivate::addChild(QQuickItem *child)
2179 Q_ASSERT(!childItems.contains(child));
2181 childItems.append(child);
2183 markSortedChildrenDirty(child);
2184 dirty(QQuickItemPrivate::ChildrenChanged);
2186 itemChange(QQuickItem::ItemChildAddedChange, child);
2188 emit q->childrenChanged();
2191 void QQuickItemPrivate::removeChild(QQuickItem *child)
2196 Q_ASSERT(childItems.contains(child));
2197 childItems.removeOne(child);
2198 Q_ASSERT(!childItems.contains(child));
2200 markSortedChildrenDirty(child);
2201 dirty(QQuickItemPrivate::ChildrenChanged);
2203 itemChange(QQuickItem::ItemChildRemovedChange, child);
2205 emit q->childrenChanged();
2208 void QQuickItemPrivate::InitializationState::clear()
2213 void QQuickItemPrivate::InitializationState::clear(QQuickItem *fs)
2218 QQuickItem *QQuickItemPrivate::InitializationState::getFocusScope(QQuickItem *item)
2221 QQuickItem *fs = item->parentItem();
2222 while (fs->parentItem() && !fs->isFocusScope())
2223 fs = fs->parentItem();
2229 void QQuickItemPrivate::refCanvas(InitializationState *state, QQuickCanvas *c)
2231 // An item needs a canvas if it is referenced by another item which has a canvas.
2232 // Typically the item is referenced by a parent, but can also be referenced by a
2233 // ShaderEffect or ShaderEffectSource. 'canvasRefCount' counts how many items with
2234 // a canvas is referencing this item. When the reference count goes from zero to one,
2235 // or one to zero, the canvas of this item is updated and propagated to the children.
2236 // As long as the reference count stays above zero, the canvas is unchanged.
2237 // refCanvas() increments the reference count.
2238 // derefCanvas() decrements the reference count.
2241 Q_ASSERT((canvas != 0) == (canvasRefCount > 0));
2243 if (++canvasRefCount > 1) {
2245 qWarning("QQuickItem: Cannot use same item on different canvases at the same time.");
2246 return; // Canvas already set.
2249 Q_ASSERT(canvas == 0);
2252 if (polishScheduled)
2253 QQuickCanvasPrivate::get(canvas)->itemsToPolish.insert(q);
2255 InitializationState _dummy;
2256 InitializationState *childState = state;
2258 if (q->isFocusScope()) {
2260 childState = &_dummy;
2264 QQuickCanvasPrivate::get(canvas)->parentlessItems.insert(q);
2266 for (int ii = 0; ii < childItems.count(); ++ii) {
2267 QQuickItem *child = childItems.at(ii);
2268 QQuickItemPrivate::get(child)->refCanvas(childState, c);
2273 if (extra.isAllocated() && extra->screenAttached)
2274 extra->screenAttached->canvasChanged(c);
2275 itemChange(QQuickItem::ItemSceneChange, c);
2278 void QQuickItemPrivate::derefCanvas()
2281 Q_ASSERT((canvas != 0) == (canvasRefCount > 0));
2284 return; // This can happen when destroying recursive shader effect sources.
2286 if (--canvasRefCount > 0)
2287 return; // There are still other references, so don't set canvas to null yet.
2289 q->releaseResources();
2290 removeFromDirtyList();
2291 QQuickCanvasPrivate *c = QQuickCanvasPrivate::get(canvas);
2292 if (polishScheduled)
2293 c->itemsToPolish.remove(q);
2294 if (c->mouseGrabberItem == q)
2295 c->mouseGrabberItem = 0;
2297 c->hoverItems.removeAll(q);
2298 if (itemNodeInstance)
2299 c->cleanup(itemNodeInstance);
2301 c->parentlessItems.remove(q);
2305 itemNodeInstance = 0;
2307 if (extra.isAllocated()) {
2308 extra->opacityNode = 0;
2309 extra->clipNode = 0;
2310 extra->rootNode = 0;
2311 extra->beforePaintNode = 0;
2317 for (int ii = 0; ii < childItems.count(); ++ii) {
2318 QQuickItem *child = childItems.at(ii);
2319 QQuickItemPrivate::get(child)->derefCanvas();
2324 if (extra.isAllocated() && extra->screenAttached)
2325 extra->screenAttached->canvasChanged(0);
2326 itemChange(QQuickItem::ItemSceneChange, (QQuickCanvas *)0);
2331 Returns a transform that maps points from canvas space into item space.
2333 QTransform QQuickItemPrivate::canvasToItemTransform() const
2335 // XXX todo - optimize
2336 return itemToCanvasTransform().inverted();
2340 Returns a transform that maps points from item space into canvas space.
2342 QTransform QQuickItemPrivate::itemToCanvasTransform() const
2345 QTransform rv = parentItem?QQuickItemPrivate::get(parentItem)->itemToCanvasTransform():QTransform();
2346 itemToParentTransform(rv);
2351 Motifies \a t with this items local transform relative to its parent.
2353 void QQuickItemPrivate::itemToParentTransform(QTransform &t) const
2358 if (!transforms.isEmpty()) {
2360 for (int ii = transforms.count() - 1; ii >= 0; --ii)
2361 transforms.at(ii)->applyTo(&m);
2362 t = m.toTransform();
2365 if (scale() != 1. || rotation() != 0.) {
2366 QPointF tp = computeTransformOrigin();
2367 t.translate(tp.x(), tp.y());
2368 t.scale(scale(), scale());
2369 t.rotate(rotation());
2370 t.translate(-tp.x(), -tp.y());
2376 \qmlproperty real QtQuick2::Item::childrenRect.x
2377 \qmlproperty real QtQuick2::Item::childrenRect.y
2378 \qmlproperty real QtQuick2::Item::childrenRect.width
2379 \qmlproperty real QtQuick2::Item::childrenRect.height
2381 The childrenRect properties allow an item access to the geometry of its
2382 children. This property is useful if you have an item that needs to be
2383 sized to fit its children.
2388 \qmlproperty list<Item> QtQuick2::Item::children
2389 \qmlproperty list<Object> QtQuick2::Item::resources
2391 The children property contains the list of visual children of this item.
2392 The resources property contains non-visual resources that you want to
2395 Generally you can rely on Item's default property to handle all this for
2396 you, but it can come in handy in some cases.
2415 Returns true if construction of the QML component is complete; otherwise
2418 It is often desirable to delay some processing until the component is
2421 \sa componentComplete()
2423 bool QQuickItem::isComponentComplete() const
2425 Q_D(const QQuickItem);
2426 return d->componentComplete;
2429 QQuickItemPrivate::QQuickItemPrivate()
2430 : _anchors(0), _stateGroup(0),
2431 flags(0), widthValid(false), heightValid(false), baselineOffsetValid(false), componentComplete(true),
2432 keepMouse(false), keepTouch(false), hoverEnabled(false), smooth(true), focus(false), activeFocus(false), notifiedFocus(false),
2433 notifiedActiveFocus(false), filtersChildMouseEvents(false), explicitVisible(true),
2434 effectiveVisible(true), explicitEnable(true), effectiveEnable(true), polishScheduled(false),
2435 inheritedLayoutMirror(false), effectiveLayoutMirror(false), isMirrorImplicit(true),
2436 inheritMirrorFromParent(false), inheritMirrorFromItem(false),
2437 isAccessible(false),
2439 dirtyAttributes(0), nextDirtyItem(0), prevDirtyItem(0),
2441 canvas(0), canvasRefCount(0), parentItem(0), sortedChildItems(&childItems),
2445 x(0), y(0), width(0), height(0), implicitWidth(0), implicitHeight(0),
2449 itemNodeInstance(0), groupNode(0), paintNode(0)
2453 QQuickItemPrivate::~QQuickItemPrivate()
2455 if (sortedChildItems != &childItems)
2456 delete sortedChildItems;
2459 void QQuickItemPrivate::init(QQuickItem *parent)
2463 static bool atexit_registered = false;
2464 if (!atexit_registered) {
2465 atexit(qt_print_item_count);
2466 atexit_registered = true;
2472 registerAccessorProperties();
2474 baselineOffsetValid = false;
2477 q->setParentItem(parent);
2478 QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(parent);
2479 setImplicitLayoutMirror(parentPrivate->inheritedLayoutMirror, parentPrivate->inheritMirrorFromParent);
2483 void QQuickItemPrivate::data_append(QQmlListProperty<QObject> *prop, QObject *o)
2488 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2490 if (QQuickItem *item = qmlobject_cast<QQuickItem *>(o)) {
2491 item->setParentItem(that);
2493 if (o->inherits("QGraphicsItem"))
2494 qWarning("Cannot add a QtQuick 1.0 item (%s) into a QtQuick 2.0 scene!", o->metaObject()->className());
2496 // XXX todo - do we really want this behavior?
2502 \qmlproperty list<Object> QtQuick2::Item::data
2505 The data property allows you to freely mix visual children and resources
2506 in an item. If you assign a visual item to the data list it becomes
2507 a child and if you assign any other object type, it is added as a resource.
2531 data is a behind-the-scenes property: you should never need to explicitly
2535 int QQuickItemPrivate::data_count(QQmlListProperty<QObject> *prop)
2542 QObject *QQuickItemPrivate::data_at(QQmlListProperty<QObject> *prop, int i)
2550 void QQuickItemPrivate::data_clear(QQmlListProperty<QObject> *prop)
2556 QObject *QQuickItemPrivate::resources_at(QQmlListProperty<QObject> *prop, int index)
2558 const QObjectList children = prop->object->children();
2559 if (index < children.count())
2560 return children.at(index);
2565 void QQuickItemPrivate::resources_append(QQmlListProperty<QObject> *prop, QObject *o)
2567 // XXX todo - do we really want this behavior?
2568 o->setParent(prop->object);
2571 int QQuickItemPrivate::resources_count(QQmlListProperty<QObject> *prop)
2573 return prop->object->children().count();
2576 void QQuickItemPrivate::resources_clear(QQmlListProperty<QObject> *prop)
2578 // XXX todo - do we really want this behavior?
2579 const QObjectList children = prop->object->children();
2580 for (int index = 0; index < children.count(); index++)
2581 children.at(index)->setParent(0);
2584 QQuickItem *QQuickItemPrivate::children_at(QQmlListProperty<QQuickItem> *prop, int index)
2586 QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2587 if (index >= p->childItems.count() || index < 0)
2590 return p->childItems.at(index);
2593 void QQuickItemPrivate::children_append(QQmlListProperty<QQuickItem> *prop, QQuickItem *o)
2598 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2599 if (o->parentItem() == that)
2600 o->setParentItem(0);
2602 o->setParentItem(that);
2605 int QQuickItemPrivate::children_count(QQmlListProperty<QQuickItem> *prop)
2607 QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2608 return p->childItems.count();
2611 void QQuickItemPrivate::children_clear(QQmlListProperty<QQuickItem> *prop)
2613 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2614 QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2615 while (!p->childItems.isEmpty())
2616 p->childItems.at(0)->setParentItem(0);
2619 void QQuickItemPrivate::visibleChildren_append(QQmlListProperty<QQuickItem>*, QQuickItem *self)
2622 qmlInfo(self) << "QQuickItem: visibleChildren property is readonly and cannot be assigned to.";
2625 int QQuickItemPrivate::visibleChildren_count(QQmlListProperty<QQuickItem> *prop)
2627 QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2628 int visibleCount = 0;
2629 int c = p->childItems.count();
2631 if (p->childItems.at(c)->isVisible()) visibleCount++;
2634 return visibleCount;
2637 QQuickItem *QQuickItemPrivate::visibleChildren_at(QQmlListProperty<QQuickItem> *prop, int index)
2639 QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2640 const int childCount = p->childItems.count();
2641 if (index >= childCount || index < 0)
2644 int visibleCount = -1;
2645 for (int i = 0; i < childCount; i++) {
2646 if (p->childItems.at(i)->isVisible()) visibleCount++;
2647 if (visibleCount == index) return p->childItems.at(i);
2652 int QQuickItemPrivate::transform_count(QQmlListProperty<QQuickTransform> *prop)
2654 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2655 QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2657 return p->transforms.count();
2660 void QQuickTransform::appendToItem(QQuickItem *item)
2662 Q_D(QQuickTransform);
2666 QQuickItemPrivate *p = QQuickItemPrivate::get(item);
2668 if (!d->items.isEmpty() && !p->transforms.isEmpty() && p->transforms.contains(this)) {
2669 p->transforms.removeOne(this);
2670 p->transforms.append(this);
2672 p->transforms.append(this);
2673 d->items.append(item);
2676 p->dirty(QQuickItemPrivate::Transform);
2679 void QQuickTransform::prependToItem(QQuickItem *item)
2681 Q_D(QQuickTransform);
2685 QQuickItemPrivate *p = QQuickItemPrivate::get(item);
2687 if (!d->items.isEmpty() && !p->transforms.isEmpty() && p->transforms.contains(this)) {
2688 p->transforms.removeOne(this);
2689 p->transforms.prepend(this);
2691 p->transforms.prepend(this);
2692 d->items.append(item);
2695 p->dirty(QQuickItemPrivate::Transform);
2698 void QQuickItemPrivate::transform_append(QQmlListProperty<QQuickTransform> *prop, QQuickTransform *transform)
2703 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2704 transform->appendToItem(that);
2707 QQuickTransform *QQuickItemPrivate::transform_at(QQmlListProperty<QQuickTransform> *prop, int idx)
2709 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2710 QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2712 if (idx < 0 || idx >= p->transforms.count())
2715 return p->transforms.at(idx);
2718 void QQuickItemPrivate::transform_clear(QQmlListProperty<QQuickTransform> *prop)
2720 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2721 QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2723 for (int ii = 0; ii < p->transforms.count(); ++ii) {
2724 QQuickTransform *t = p->transforms.at(ii);
2725 QQuickTransformPrivate *tp = QQuickTransformPrivate::get(t);
2726 tp->items.removeOne(that);
2729 p->transforms.clear();
2731 p->dirty(QQuickItemPrivate::Transform);
2735 \property QQuickItem::childrenRect
2736 \brief Specifies the geometry of an item's children
2738 This property holds the (collective) position and size of the item's children.
2742 \qmlproperty real QtQuick2::Item::x
2743 \qmlproperty real QtQuick2::Item::y
2744 \qmlproperty real QtQuick2::Item::width
2745 \qmlproperty real QtQuick2::Item::height
2747 Defines the item's position and size relative to its parent.
2750 Item { x: 100; y: 100; width: 100; height: 100 }
2755 \qmlproperty real QtQuick2::Item::z
2757 Sets the stacking order of sibling items. By default the stacking order is 0.
2759 Items with a higher stacking value are drawn on top of siblings with a
2760 lower stacking order. Items with the same stacking value are drawn
2761 bottom up in the order they appear. Items with a negative stacking
2762 value are drawn under their parent's content.
2764 The following example shows the various effects of stacking order.
2768 \li \image declarative-item_stacking1.png
2769 \li Same \c z - later children above earlier children:
2774 width: 100; height: 100
2778 x: 50; y: 50; width: 100; height: 100
2783 \li \image declarative-item_stacking2.png
2784 \li Higher \c z on top:
2790 width: 100; height: 100
2794 x: 50; y: 50; width: 100; height: 100
2799 \li \image declarative-item_stacking3.png
2800 \li Same \c z - children above parents:
2805 width: 100; height: 100
2808 x: 50; y: 50; width: 100; height: 100
2814 \li \image declarative-item_stacking4.png
2815 \li Lower \c z below:
2820 width: 100; height: 100
2824 x: 50; y: 50; width: 100; height: 100
2833 \qmlproperty bool QtQuick2::Item::visible
2835 This property holds whether the item is visible. By default this is true.
2837 Setting this property directly affects the \c visible value of child
2838 items. When set to \c false, the \c visible values of all child items also
2839 become \c false. When set to \c true, the \c visible values of child items
2840 are returned to \c true, unless they have explicitly been set to \c false.
2842 (Because of this flow-on behavior, using the \c visible property may not
2843 have the intended effect if a property binding should only respond to
2844 explicit property changes. In such cases it may be better to use the
2845 \l opacity property instead.)
2847 Setting this property to \c false automatically causes \l focus to be set
2848 to \c false, and this item will longer receive mouse and keyboard events.
2849 (In contrast, setting the \l opacity to 0 does not affect the \l focus
2850 property and the receiving of key events.)
2852 \note This property's value is only affected by changes to this property or
2853 the parent's \c visible property. It does not change, for example, if this
2854 item moves off-screen, or if the \l opacity changes to 0.
2859 \qmlproperty AnchorLine QtQuick2::Item::anchors.top
2860 \qmlproperty AnchorLine QtQuick2::Item::anchors.bottom
2861 \qmlproperty AnchorLine QtQuick2::Item::anchors.left
2862 \qmlproperty AnchorLine QtQuick2::Item::anchors.right
2863 \qmlproperty AnchorLine QtQuick2::Item::anchors.horizontalCenter
2864 \qmlproperty AnchorLine QtQuick2::Item::anchors.verticalCenter
2865 \qmlproperty AnchorLine QtQuick2::Item::anchors.baseline
2867 \qmlproperty Item QtQuick2::Item::anchors.fill
2868 \qmlproperty Item QtQuick2::Item::anchors.centerIn
2870 \qmlproperty real QtQuick2::Item::anchors.margins
2871 \qmlproperty real QtQuick2::Item::anchors.topMargin
2872 \qmlproperty real QtQuick2::Item::anchors.bottomMargin
2873 \qmlproperty real QtQuick2::Item::anchors.leftMargin
2874 \qmlproperty real QtQuick2::Item::anchors.rightMargin
2875 \qmlproperty real QtQuick2::Item::anchors.horizontalCenterOffset
2876 \qmlproperty real QtQuick2::Item::anchors.verticalCenterOffset
2877 \qmlproperty real QtQuick2::Item::anchors.baselineOffset
2879 \qmlproperty bool QtQuick2::Item::anchors.mirrored
2880 \qmlproperty bool QtQuick2::Item::anchors.alignWhenCentered
2882 Anchors provide a way to position an item by specifying its
2883 relationship with other items.
2885 Margins apply to top, bottom, left, right, and fill anchors.
2886 The \c anchors.margins property can be used to set all of the various margins at once, to the same value.
2887 Note that margins are anchor-specific and are not applied if an item does not
2890 Offsets apply for horizontal center, vertical center, and baseline anchors.
2894 \li \image declarative-anchors_example.png
2895 \li Text anchored to Image, horizontally centered and vertically below, with a margin.
2904 anchors.horizontalCenter: pic.horizontalCenter
2905 anchors.top: pic.bottom
2906 anchors.topMargin: 5
2912 \li \image declarative-anchors_example2.png
2914 Left of Text anchored to right of Image, with a margin. The y
2915 property of both defaults to 0.
2925 anchors.left: pic.right
2926 anchors.leftMargin: 5
2933 \c anchors.fill provides a convenient way for one item to have the
2934 same geometry as another item, and is equivalent to connecting all
2935 four directional anchors.
2937 To clear an anchor value, set it to \c undefined.
2939 \c anchors.mirrored returns true it the layout has been \l {LayoutMirroring}{mirrored}.
2941 \c anchors.alignWhenCentered (default true) forces centered anchors to align to a
2942 whole pixel, i.e. if the item being centered has an odd width/height the item
2943 will be positioned on a whole pixel rather than being placed on a half-pixel.
2944 This ensures the item is painted crisply. There are cases where this is not
2945 desirable, for example when rotating the item jitters may be apparent as the
2948 \note You can only anchor an item to siblings or a parent.
2950 For more information see \l {anchor-layout}{Anchor Layouts}.
2954 \property QQuickItem::baselineOffset
2955 \brief Speciifies the position of the item's baseline in local coordinates
2957 The baseline of a \l Text item is the imaginary line on which the text
2958 sits. Controls containing text usually set their baseline to the
2959 baseline of their text.
2961 For non-text items, a default baseline offset of 0 is used.
2963 QQuickAnchors *QQuickItemPrivate::anchors() const
2966 Q_Q(const QQuickItem);
2967 _anchors = new QQuickAnchors(const_cast<QQuickItem *>(q));
2968 if (!componentComplete)
2969 _anchors->classBegin();
2974 void QQuickItemPrivate::siblingOrderChanged()
2977 for (int ii = 0; ii < changeListeners.count(); ++ii) {
2978 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
2979 if (change.types & QQuickItemPrivate::SiblingOrder) {
2980 change.listener->itemSiblingOrderChanged(q);
2985 QQmlListProperty<QObject> QQuickItemPrivate::data()
2987 return QQmlListProperty<QObject>(q_func(), 0, QQuickItemPrivate::data_append,
2988 QQuickItemPrivate::data_count,
2989 QQuickItemPrivate::data_at,
2990 QQuickItemPrivate::data_clear);
2993 QRectF QQuickItem::childrenRect()
2996 if (!d->extra.isAllocated() || !d->extra->contents) {
2997 d->extra.value().contents = new QQuickContents(this);
2998 if (d->componentComplete)
2999 d->extra->contents->complete();
3001 return d->extra->contents->rectF();
3004 QList<QQuickItem *> QQuickItem::childItems() const
3006 Q_D(const QQuickItem);
3007 return d->childItems;
3010 bool QQuickItem::clip() const
3012 return flags() & ItemClipsChildrenToShape;
3015 void QQuickItem::setClip(bool c)
3020 setFlag(ItemClipsChildrenToShape, c);
3022 emit clipChanged(c);
3027 This function is called to handle this item's changes in
3028 geometry from \a oldGeometry to \a newGeometry. If the two
3029 geometries are the same, it doesn't do anything.
3031 void QQuickItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
3036 QQuickAnchorsPrivate::get(d->_anchors)->updateMe();
3038 bool xChange = (newGeometry.x() != oldGeometry.x());
3039 bool yChange = (newGeometry.y() != oldGeometry.y());
3040 bool widthChange = (newGeometry.width() != oldGeometry.width());
3041 bool heightChange = (newGeometry.height() != oldGeometry.height());
3043 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
3044 const QQuickItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
3045 if (change.types & QQuickItemPrivate::Geometry) {
3046 if (change.gTypes == QQuickItemPrivate::GeometryChange) {
3047 change.listener->itemGeometryChanged(this, newGeometry, oldGeometry);
3048 } else if ((xChange && (change.gTypes & QQuickItemPrivate::XChange)) ||
3049 (yChange && (change.gTypes & QQuickItemPrivate::YChange)) ||
3050 (widthChange && (change.gTypes & QQuickItemPrivate::WidthChange)) ||
3051 (heightChange && (change.gTypes & QQuickItemPrivate::HeightChange))) {
3052 change.listener->itemGeometryChanged(this, newGeometry, oldGeometry);
3062 emit widthChanged();
3064 emit heightChanged();
3068 Called by the rendering thread, as a result of
3069 QQuickItem::update(), when it is time to sync the state of the QML
3070 objects with the scene graph objects.
3072 The function should return the root of the scene graph subtree for
3073 this item. Most implementations will return a single
3074 QSGGeometryNode containing the visual representation of this item.
3075 \a oldNode is the node that was returned the last time the
3076 function was called.
3079 QSGNode *MyItem::updatePaintNode(QSGNode *node, UpdatePaintNodeData *)
3081 QSGSimpleRectNode *n = static_cast<QSGSimpleRectNode *>(node);
3083 n = new QSGSimpleRectNode();
3084 n->setColor(Qt::red);
3086 n->setRect(boundingRect());
3091 The main thread is blocked while this function is executed so it is safe to read
3092 values from the QQuickItem instance and other objects in the main thread.
3094 If no call to QQuickItem::updatePaintNode() result in actual scene graph
3095 changes, like QSGNode::markDirty() or adding and removing nodes, then
3096 the underlying implementation may decide to not render the scene again as
3097 the visual outcome is identical.
3099 \warning It is crucial that OpenGL operations and interaction with
3100 the scene graph happens exclusively on the rendering thread,
3101 primarily during the QQuickItem::updatePaintNode() call. The best
3102 rule of thumb is to only use classes with the "QSG" prefix inside
3103 the QQuickItem::updatePaintNode() function.
3105 \sa QSGMaterial, QSGSimpleMaterial, QSGGeometryNode, QSGGeometry,
3106 QSGFlatColorMaterial, QSGTextureMaterial, QSGNode::markDirty()
3109 QSGNode *QQuickItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
3116 This function is called when the item's scene graph resources are no longer needed.
3117 It allows items to free its resources, for instance textures, that are not owned by scene graph
3118 nodes. Note that scene graph nodes are managed by QQuickCanvas and should not be deleted by
3119 this function. Scene graph resources are no longer needed when the parent is set to null and
3120 the item is not used by any \l ShaderEffect or \l ShaderEffectSource.
3122 This function is called from the main thread. Therefore, resources used by the scene graph
3123 should not be deleted directly, but by calling \l QObject::deleteLater().
3125 \note The item destructor still needs to free its scene graph resources if not already done.
3128 void QQuickItem::releaseResources()
3132 QSGTransformNode *QQuickItemPrivate::createTransformNode()
3134 return new QSGTransformNode;
3137 void QQuickItem::updatePolish()
3141 void QQuickItemPrivate::addItemChangeListener(QQuickItemChangeListener *listener, ChangeTypes types)
3143 changeListeners.append(ChangeListener(listener, types));
3146 void QQuickItemPrivate::removeItemChangeListener(QQuickItemChangeListener *listener, ChangeTypes types)
3148 ChangeListener change(listener, types);
3149 changeListeners.removeOne(change);
3152 void QQuickItemPrivate::updateOrAddGeometryChangeListener(QQuickItemChangeListener *listener, GeometryChangeTypes types)
3154 ChangeListener change(listener, types);
3155 int index = changeListeners.find(change);
3157 changeListeners[index].gTypes = change.gTypes; //we may have different GeometryChangeTypes
3159 changeListeners.append(change);
3162 void QQuickItemPrivate::updateOrRemoveGeometryChangeListener(QQuickItemChangeListener *listener,
3163 GeometryChangeTypes types)
3165 ChangeListener change(listener, types);
3166 if (types == NoChange) {
3167 changeListeners.removeOne(change);
3169 int index = changeListeners.find(change);
3171 changeListeners[index].gTypes = change.gTypes; //we may have different GeometryChangeTypes
3175 void QQuickItem::keyPressEvent(QKeyEvent *event)
3180 void QQuickItem::keyReleaseEvent(QKeyEvent *event)
3185 void QQuickItem::inputMethodEvent(QInputMethodEvent *event)
3190 void QQuickItem::focusInEvent(QFocusEvent *)
3192 #ifndef QT_NO_ACCESSIBILITY
3193 QAccessibleEvent ev(this, QAccessible::Focus);
3194 QAccessible::updateAccessibility(&ev);
3198 void QQuickItem::focusOutEvent(QFocusEvent *)
3202 void QQuickItem::mousePressEvent(QMouseEvent *event)
3207 void QQuickItem::mouseMoveEvent(QMouseEvent *event)
3212 void QQuickItem::mouseReleaseEvent(QMouseEvent *event)
3217 void QQuickItem::mouseDoubleClickEvent(QMouseEvent *)
3221 void QQuickItem::mouseUngrabEvent()
3226 void QQuickItem::touchUngrabEvent()
3231 void QQuickItem::wheelEvent(QWheelEvent *event)
3236 void QQuickItem::touchEvent(QTouchEvent *event)
3241 void QQuickItem::hoverEnterEvent(QHoverEvent *event)
3246 void QQuickItem::hoverMoveEvent(QHoverEvent *event)
3251 void QQuickItem::hoverLeaveEvent(QHoverEvent *event)
3256 void QQuickItem::dragEnterEvent(QDragEnterEvent *event)
3261 void QQuickItem::dragMoveEvent(QDragMoveEvent *event)
3267 void QQuickItem::dragLeaveEvent(QDragLeaveEvent *event)
3273 void QQuickItem::dropEvent(QDropEvent *event)
3278 bool QQuickItem::childMouseEventFilter(QQuickItem *, QEvent *)
3283 void QQuickItem::windowDeactivateEvent()
3285 foreach (QQuickItem* item, childItems()) {
3286 item->windowDeactivateEvent();
3290 QVariant QQuickItem::inputMethodQuery(Qt::InputMethodQuery query) const
3292 Q_D(const QQuickItem);
3297 v = (bool)(flags() & ItemAcceptsInputMethod);
3300 case Qt::ImCursorRectangle:
3302 case Qt::ImCursorPosition:
3303 case Qt::ImSurroundingText:
3304 case Qt::ImCurrentSelection:
3305 case Qt::ImMaximumTextLength:
3306 case Qt::ImAnchorPosition:
3307 case Qt::ImPreferredLanguage:
3308 if (d->extra.isAllocated() && d->extra->keyHandler)
3309 v = d->extra->keyHandler->inputMethodQuery(query);
3317 QQuickAnchorLine QQuickItemPrivate::left() const
3319 Q_Q(const QQuickItem);
3320 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Left);
3323 QQuickAnchorLine QQuickItemPrivate::right() const
3325 Q_Q(const QQuickItem);
3326 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Right);
3329 QQuickAnchorLine QQuickItemPrivate::horizontalCenter() const
3331 Q_Q(const QQuickItem);
3332 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::HCenter);
3335 QQuickAnchorLine QQuickItemPrivate::top() const
3337 Q_Q(const QQuickItem);
3338 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Top);
3341 QQuickAnchorLine QQuickItemPrivate::bottom() const
3343 Q_Q(const QQuickItem);
3344 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Bottom);
3347 QQuickAnchorLine QQuickItemPrivate::verticalCenter() const
3349 Q_Q(const QQuickItem);
3350 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::VCenter);
3353 QQuickAnchorLine QQuickItemPrivate::baseline() const
3355 Q_Q(const QQuickItem);
3356 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Baseline);
3359 qreal QQuickItem::baselineOffset() const
3361 Q_D(const QQuickItem);
3362 if (d->baselineOffsetValid) {
3363 return d->baselineOffset;
3369 void QQuickItem::setBaselineOffset(qreal offset)
3372 if (offset == d->baselineOffset)
3375 d->baselineOffset = offset;
3376 d->baselineOffsetValid = true;
3378 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
3379 const QQuickItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
3380 if (change.types & QQuickItemPrivate::Geometry) {
3381 QQuickAnchorsPrivate *anchor = change.listener->anchorPrivate();
3383 anchor->updateVerticalAnchors();
3387 if (d->_anchors && (d->_anchors->usedAnchors() & QQuickAnchors::BaselineAnchor))
3388 QQuickAnchorsPrivate::get(d->_anchors)->updateVerticalAnchors();
3390 emit baselineOffsetChanged(offset);
3395 * Schedules a call to updatePaintNode() for this item.
3397 * The call to QQuickItem::updatePaintNode() will always happen if the
3398 * item is showing in a QQuickCanvas.
3400 * Only items which specifies QQuickItem::ItemHasContents are allowed
3401 * to call QQuickItem::update().
3403 void QQuickItem::update()
3406 Q_ASSERT(flags() & ItemHasContents);
3407 d->dirty(QQuickItemPrivate::Content);
3410 void QQuickItem::polish()
3413 if (!d->polishScheduled) {
3414 d->polishScheduled = true;
3416 QQuickCanvasPrivate *p = QQuickCanvasPrivate::get(d->canvas);
3417 bool maybeupdate = p->itemsToPolish.isEmpty();
3418 p->itemsToPolish.insert(this);
3419 if (maybeupdate) d->canvas->maybeUpdate();
3425 \qmlmethod object QtQuick2::Item::mapFromItem(Item item, real x, real y)
3426 \qmlmethod object QtQuick2::Item::mapFromItem(Item item, real x, real y, real width, real height)
3428 Maps the point (\a x, \a y) or rect (\a x, \a y, \a width, \a height), which is in \a
3429 item's coordinate system, to this item's coordinate system, and returns an object with \c x and
3430 \c y (and optionally \c width and \c height) properties matching the mapped coordinate.
3432 If \a item is a \c null value, this maps the point or rect from the coordinate system of
3435 void QQuickItem::mapFromItem(QQmlV8Function *args) const
3437 if (args->Length() != 0) {
3438 v8::Local<v8::Value> item = (*args)[0];
3439 QV8Engine *engine = args->engine();
3441 QQuickItem *itemObj = 0;
3442 if (!item->IsNull())
3443 itemObj = qobject_cast<QQuickItem*>(engine->toQObject(item));
3445 if (!itemObj && !item->IsNull()) {
3446 qmlInfo(this) << "mapFromItem() given argument \"" << engine->toString(item->ToString())
3447 << "\" which is neither null nor an Item";
3451 v8::Local<v8::Object> rv = v8::Object::New();
3452 args->returnValue(rv);
3454 qreal x = (args->Length() > 1)?(*args)[1]->NumberValue():0;
3455 qreal y = (args->Length() > 2)?(*args)[2]->NumberValue():0;
3457 if (args->Length() > 3) {
3458 qreal w = (*args)[3]->NumberValue();
3459 qreal h = (args->Length() > 4)?(*args)[4]->NumberValue():0;
3461 QRectF r = mapRectFromItem(itemObj, QRectF(x, y, w, h));
3463 rv->Set(v8::String::New("x"), v8::Number::New(r.x()));
3464 rv->Set(v8::String::New("y"), v8::Number::New(r.y()));
3465 rv->Set(v8::String::New("width"), v8::Number::New(r.width()));
3466 rv->Set(v8::String::New("height"), v8::Number::New(r.height()));
3468 QPointF p = mapFromItem(itemObj, QPointF(x, y));
3470 rv->Set(v8::String::New("x"), v8::Number::New(p.x()));
3471 rv->Set(v8::String::New("y"), v8::Number::New(p.y()));
3476 QTransform QQuickItem::itemTransform(QQuickItem *other, bool *ok) const
3478 Q_D(const QQuickItem);
3480 // XXX todo - we need to be able to handle common parents better and detect
3484 QTransform t = d->itemToCanvasTransform();
3485 if (other) t *= QQuickItemPrivate::get(other)->canvasToItemTransform();
3491 \qmlmethod object QtQuick2::Item::mapToItem(Item item, real x, real y)
3492 \qmlmethod object QtQuick2::Item::mapToItem(Item item, real x, real y, real width, real height)
3494 Maps the point (\a x, \a y) or rect (\a x, \a y, \a width, \a height), which is in this
3495 item's coordinate system, to \a item's coordinate system, and returns an object with \c x and
3496 \c y (and optionally \c width and \c height) properties matching the mapped coordinate.
3498 If \a item is a \c null value, this maps the point or rect to the coordinate system of the
3501 void QQuickItem::mapToItem(QQmlV8Function *args) const
3503 if (args->Length() != 0) {
3504 v8::Local<v8::Value> item = (*args)[0];
3505 QV8Engine *engine = args->engine();
3507 QQuickItem *itemObj = 0;
3508 if (!item->IsNull())
3509 itemObj = qobject_cast<QQuickItem*>(engine->toQObject(item));
3511 if (!itemObj && !item->IsNull()) {
3512 qmlInfo(this) << "mapToItem() given argument \"" << engine->toString(item->ToString())
3513 << "\" which is neither null nor an Item";
3517 v8::Local<v8::Object> rv = v8::Object::New();
3518 args->returnValue(rv);
3520 qreal x = (args->Length() > 1)?(*args)[1]->NumberValue():0;
3521 qreal y = (args->Length() > 2)?(*args)[2]->NumberValue():0;
3523 if (args->Length() > 3) {
3524 qreal w = (*args)[3]->NumberValue();
3525 qreal h = (args->Length() > 4)?(*args)[4]->NumberValue():0;
3527 QRectF r = mapRectToItem(itemObj, QRectF(x, y, w, h));
3529 rv->Set(v8::String::New("x"), v8::Number::New(r.x()));
3530 rv->Set(v8::String::New("y"), v8::Number::New(r.y()));
3531 rv->Set(v8::String::New("width"), v8::Number::New(r.width()));
3532 rv->Set(v8::String::New("height"), v8::Number::New(r.height()));
3534 QPointF p = mapToItem(itemObj, QPointF(x, y));
3536 rv->Set(v8::String::New("x"), v8::Number::New(p.x()));
3537 rv->Set(v8::String::New("y"), v8::Number::New(p.y()));
3542 void QQuickItem::forceActiveFocus()
3545 QQuickItem *parent = parentItem();
3547 if (parent->flags() & QQuickItem::ItemIsFocusScope) {
3548 parent->setFocus(true);
3550 parent = parent->parentItem();
3554 QQuickItem *QQuickItem::childAt(qreal x, qreal y) const
3556 // XXX todo - should this include transform etc.?
3557 const QList<QQuickItem *> children = childItems();
3558 for (int i = children.count()-1; i >= 0; --i) {
3559 QQuickItem *child = children.at(i);
3560 if (child->isVisible() && child->x() <= x
3561 && child->x() + child->width() >= x
3563 && child->y() + child->height() >= y)
3569 QQmlListProperty<QObject> QQuickItemPrivate::resources()
3571 return QQmlListProperty<QObject>(q_func(), 0, QQuickItemPrivate::resources_append,
3572 QQuickItemPrivate::resources_count,
3573 QQuickItemPrivate::resources_at,
3574 QQuickItemPrivate::resources_clear);
3577 QQmlListProperty<QQuickItem> QQuickItemPrivate::children()
3579 return QQmlListProperty<QQuickItem>(q_func(), 0, QQuickItemPrivate::children_append,
3580 QQuickItemPrivate::children_count,
3581 QQuickItemPrivate::children_at,
3582 QQuickItemPrivate::children_clear);
3587 \qmlproperty real QtQuick2::Item::visibleChildren
3588 This read-only property lists all of the item's children that are currently visible.
3589 Note that a child's visibility may have changed explicitly, or because the visibility
3590 of this (it's parent) item or another grandparent changed.
3592 QQmlListProperty<QQuickItem> QQuickItemPrivate::visibleChildren()
3594 return QQmlListProperty<QQuickItem>(q_func(), 0, QQuickItemPrivate::visibleChildren_append,
3595 QQuickItemPrivate::visibleChildren_count,
3596 QQuickItemPrivate::visibleChildren_at);
3600 QQmlListProperty<QQuickState> QQuickItemPrivate::states()
3602 return _states()->statesProperty();
3605 QQmlListProperty<QQuickTransition> QQuickItemPrivate::transitions()
3607 return _states()->transitionsProperty();
3610 QString QQuickItemPrivate::state() const
3615 return _stateGroup->state();
3618 void QQuickItemPrivate::setState(const QString &state)
3620 _states()->setState(state);
3623 QString QQuickItem::state() const
3625 Q_D(const QQuickItem);
3629 void QQuickItem::setState(const QString &state)
3635 QQmlListProperty<QQuickTransform> QQuickItem::transform()
3637 return QQmlListProperty<QQuickTransform>(this, 0, QQuickItemPrivate::transform_append,
3638 QQuickItemPrivate::transform_count,
3639 QQuickItemPrivate::transform_at,
3640 QQuickItemPrivate::transform_clear);
3643 void QQuickItem::classBegin()
3646 d->componentComplete = false;
3648 d->_stateGroup->classBegin();
3650 d->_anchors->classBegin();
3651 if (d->extra.isAllocated() && d->extra->layer)
3652 d->extra->layer->classBegin();
3655 void QQuickItem::componentComplete()
3658 d->componentComplete = true;
3660 d->_stateGroup->componentComplete();
3662 d->_anchors->componentComplete();
3663 QQuickAnchorsPrivate::get(d->_anchors)->updateOnComplete();
3666 if (d->extra.isAllocated() && d->extra->layer)
3667 d->extra->layer->componentComplete();
3669 if (d->extra.isAllocated() && d->extra->keyHandler)
3670 d->extra->keyHandler->componentComplete();
3672 if (d->extra.isAllocated() && d->extra->contents)
3673 d->extra->contents->complete();
3676 QQuickStateGroup *QQuickItemPrivate::_states()
3680 _stateGroup = new QQuickStateGroup;
3681 if (!componentComplete)
3682 _stateGroup->classBegin();
3683 qmlobject_connect(_stateGroup, QQuickStateGroup, SIGNAL(stateChanged(QString)),
3684 q, QQuickItem, SIGNAL(stateChanged(QString)))
3690 QPointF QQuickItemPrivate::computeTransformOrigin() const
3694 case QQuickItem::TopLeft:
3695 return QPointF(0, 0);
3696 case QQuickItem::Top:
3697 return QPointF(width / 2., 0);
3698 case QQuickItem::TopRight:
3699 return QPointF(width, 0);
3700 case QQuickItem::Left:
3701 return QPointF(0, height / 2.);
3702 case QQuickItem::Center:
3703 return QPointF(width / 2., height / 2.);
3704 case QQuickItem::Right:
3705 return QPointF(width, height / 2.);
3706 case QQuickItem::BottomLeft:
3707 return QPointF(0, height);
3708 case QQuickItem::Bottom:
3709 return QPointF(width / 2., height);
3710 case QQuickItem::BottomRight:
3711 return QPointF(width, height);
3715 void QQuickItemPrivate::transformChanged()
3717 if (extra.isAllocated() && extra->layer)
3718 extra->layer->updateMatrix();
3721 void QQuickItemPrivate::deliverKeyEvent(QKeyEvent *e)
3725 Q_ASSERT(e->isAccepted());
3726 if (extra.isAllocated() && extra->keyHandler) {
3727 if (e->type() == QEvent::KeyPress)
3728 extra->keyHandler->keyPressed(e, false);
3730 extra->keyHandler->keyReleased(e, false);
3732 if (e->isAccepted())
3738 if (e->type() == QEvent::KeyPress)
3739 q->keyPressEvent(e);
3741 q->keyReleaseEvent(e);
3743 if (e->isAccepted())
3746 if (extra.isAllocated() && extra->keyHandler) {
3749 if (e->type() == QEvent::KeyPress)
3750 extra->keyHandler->keyPressed(e, true);
3752 extra->keyHandler->keyReleased(e, true);
3756 void QQuickItemPrivate::deliverInputMethodEvent(QInputMethodEvent *e)
3760 Q_ASSERT(e->isAccepted());
3761 if (extra.isAllocated() && extra->keyHandler) {
3762 extra->keyHandler->inputMethodEvent(e, false);
3764 if (e->isAccepted())
3770 q->inputMethodEvent(e);
3772 if (e->isAccepted())
3775 if (extra.isAllocated() && extra->keyHandler) {
3778 extra->keyHandler->inputMethodEvent(e, true);
3782 void QQuickItemPrivate::deliverFocusEvent(QFocusEvent *e)
3786 if (e->type() == QEvent::FocusIn) {
3789 q->focusOutEvent(e);
3793 void QQuickItemPrivate::deliverMouseEvent(QMouseEvent *e)
3797 Q_ASSERT(e->isAccepted());
3799 switch (e->type()) {
3801 Q_ASSERT(!"Unknown event type");
3802 case QEvent::MouseMove:
3803 q->mouseMoveEvent(e);
3805 case QEvent::MouseButtonPress:
3806 q->mousePressEvent(e);
3808 case QEvent::MouseButtonRelease:
3809 q->mouseReleaseEvent(e);
3811 case QEvent::MouseButtonDblClick:
3812 q->mouseDoubleClickEvent(e);
3817 void QQuickItemPrivate::deliverWheelEvent(QWheelEvent *e)
3823 void QQuickItemPrivate::deliverTouchEvent(QTouchEvent *e)
3829 void QQuickItemPrivate::deliverHoverEvent(QHoverEvent *e)
3832 switch (e->type()) {
3834 Q_ASSERT(!"Unknown event type");
3835 case QEvent::HoverEnter:
3836 q->hoverEnterEvent(e);
3838 case QEvent::HoverLeave:
3839 q->hoverLeaveEvent(e);
3841 case QEvent::HoverMove:
3842 q->hoverMoveEvent(e);
3847 void QQuickItemPrivate::deliverDragEvent(QEvent *e)
3850 switch (e->type()) {
3852 Q_ASSERT(!"Unknown event type");
3853 case QEvent::DragEnter:
3854 q->dragEnterEvent(static_cast<QDragEnterEvent *>(e));
3856 case QEvent::DragLeave:
3857 q->dragLeaveEvent(static_cast<QDragLeaveEvent *>(e));
3859 case QEvent::DragMove:
3860 q->dragMoveEvent(static_cast<QDragMoveEvent *>(e));
3863 q->dropEvent(static_cast<QDropEvent *>(e));
3868 void QQuickItem::itemChange(ItemChange change, const ItemChangeData &value)
3875 Notify input method on updated query values if needed. \a indicates changed attributes.
3877 void QQuickItem::updateInputMethod(Qt::InputMethodQueries queries)
3879 if (hasActiveFocus())
3880 qApp->inputMethod()->update(queries);
3884 // XXX todo - do we want/need this anymore?
3885 QRectF QQuickItem::boundingRect() const
3887 Q_D(const QQuickItem);
3888 return QRectF(0, 0, d->width, d->height);
3892 QRectF QQuickItem::clipRect() const
3894 Q_D(const QQuickItem);
3895 return QRectF(0, 0, d->width, d->height);
3899 QQuickItem::TransformOrigin QQuickItem::transformOrigin() const
3901 Q_D(const QQuickItem);
3905 void QQuickItem::setTransformOrigin(TransformOrigin origin)
3908 if (origin == d->origin())
3911 d->extra.value().origin = origin;
3912 d->dirty(QQuickItemPrivate::TransformOrigin);
3914 emit transformOriginChanged(d->origin());
3917 QPointF QQuickItem::transformOriginPoint() const
3919 Q_D(const QQuickItem);
3920 if (d->extra.isAllocated() && !d->extra->userTransformOriginPoint.isNull())
3921 return d->extra->userTransformOriginPoint;
3922 return d->computeTransformOrigin();
3925 void QQuickItem::setTransformOriginPoint(const QPointF &point)
3928 if (d->extra.value().userTransformOriginPoint == point)
3931 d->extra->userTransformOriginPoint = point;
3932 d->dirty(QQuickItemPrivate::TransformOrigin);
3935 qreal QQuickItem::z() const
3937 Q_D(const QQuickItem);
3941 void QQuickItem::setZ(qreal v)
3947 d->extra.value().z = v;
3949 d->dirty(QQuickItemPrivate::ZValue);
3950 if (d->parentItem) {
3951 QQuickItemPrivate::get(d->parentItem)->dirty(QQuickItemPrivate::ChildrenStackingChanged);
3952 QQuickItemPrivate::get(d->parentItem)->markSortedChildrenDirty(this);
3957 if (d->extra.isAllocated() && d->extra->layer)
3958 d->extra->layer->updateZ();
3963 \qmlproperty real QtQuick2::Item::rotation
3964 This property holds the rotation of the item in degrees clockwise.
3966 This specifies how many degrees to rotate the item around its transformOrigin.
3967 The default rotation is 0 degrees (i.e. not rotated at all).
3971 \li \image declarative-rotation.png
3976 width: 100; height: 100
3979 x: 25; y: 25; width: 50; height: 50
3986 \sa transform, Rotation
3990 \qmlproperty real QtQuick2::Item::scale
3991 This property holds the scale of the item.
3993 A scale of less than 1 means the item will be displayed smaller than
3994 normal, and a scale of greater than 1 means the item will be
3995 displayed larger than normal. A negative scale means the item will
3998 By default, items are displayed at a scale of 1 (i.e. at their
4001 Scaling is from the item's transformOrigin.
4005 \li \image declarative-scale.png
4010 width: 100; height: 100
4013 width: 25; height: 25
4017 x: 25; y: 25; width: 50; height: 50
4024 \sa transform, Scale
4028 \qmlproperty real QtQuick2::Item::opacity
4030 This property holds the opacity of the item. Opacity is specified as a
4031 number between 0 (fully transparent) and 1 (fully opaque). The default is 1.
4033 When this property is set, the specified opacity is also applied
4034 individually to child items. In almost all cases this is what you want,
4035 but in some cases it may produce undesired results. For example in the
4036 second set of rectangles below, the red rectangle has specified an opacity
4037 of 0.5, which affects the opacity of its blue child rectangle even though
4038 the child has not specified an opacity.
4042 \li \image declarative-item_opacity1.png
4048 width: 100; height: 100
4051 x: 50; y: 50; width: 100; height: 100
4057 \li \image declarative-item_opacity2.png
4064 width: 100; height: 100
4067 x: 50; y: 50; width: 100; height: 100
4074 If an item's opacity is set to 0, the item will no longer receive mouse
4075 events, but will continue to receive key events and will retain the keyboard
4076 \l focus if it has been set. (In contrast, setting the \l visible property
4077 to \c false stops both mouse and keyboard events, and also removes focus
4082 Returns a value indicating whether mouse input should
4083 remain with this item exclusively.
4085 \sa setKeepMouseGrab()
4088 qreal QQuickItem::rotation() const
4090 Q_D(const QQuickItem);
4091 return d->rotation();
4094 void QQuickItem::setRotation(qreal r)
4097 if (d->rotation() == r)
4100 d->extra.value().rotation = r;
4102 d->dirty(QQuickItemPrivate::BasicTransform);
4104 d->itemChange(ItemRotationHasChanged, r);
4106 emit rotationChanged();
4109 qreal QQuickItem::scale() const
4111 Q_D(const QQuickItem);
4115 void QQuickItem::setScale(qreal s)
4118 if (d->scale() == s)
4121 d->extra.value().scale = s;
4123 d->dirty(QQuickItemPrivate::BasicTransform);
4125 emit scaleChanged();
4128 qreal QQuickItem::opacity() const
4130 Q_D(const QQuickItem);
4131 return d->opacity();
4134 void QQuickItem::setOpacity(qreal o)
4137 if (d->opacity() == o)
4140 d->extra.value().opacity = o;
4142 d->dirty(QQuickItemPrivate::OpacityValue);
4144 d->itemChange(ItemOpacityHasChanged, o);
4146 emit opacityChanged();
4149 bool QQuickItem::isVisible() const
4151 Q_D(const QQuickItem);
4152 return d->effectiveVisible;
4155 void QQuickItem::setVisible(bool v)
4158 if (v == d->explicitVisible)
4161 d->explicitVisible = v;
4163 d->dirty(QQuickItemPrivate::Visible);
4165 const bool childVisibilityChanged = d->setEffectiveVisibleRecur(d->calcEffectiveVisible());
4166 if (childVisibilityChanged && d->parentItem)
4167 emit d->parentItem->visibleChildrenChanged(); // signal the parent, not this!
4170 bool QQuickItem::isEnabled() const
4172 Q_D(const QQuickItem);
4173 return d->effectiveEnable;
4176 void QQuickItem::setEnabled(bool e)
4179 if (e == d->explicitEnable)
4182 d->explicitEnable = e;
4184 QQuickItem *scope = parentItem();
4185 while (scope && !scope->isFocusScope())
4186 scope = scope->parentItem();
4188 d->setEffectiveEnableRecur(scope, d->calcEffectiveEnable());
4191 bool QQuickItemPrivate::calcEffectiveVisible() const
4193 // XXX todo - Should the effective visible of an element with no parent just be the current
4194 // effective visible? This would prevent pointless re-processing in the case of an element
4195 // moving to/from a no-parent situation, but it is different from what graphics view does.
4196 return explicitVisible && (!parentItem || QQuickItemPrivate::get(parentItem)->effectiveVisible);
4199 bool QQuickItemPrivate::setEffectiveVisibleRecur(bool newEffectiveVisible)
4203 if (newEffectiveVisible && !explicitVisible) {
4204 // This item locally overrides visibility
4205 return false; // effective visibility didn't change
4208 if (newEffectiveVisible == effectiveVisible) {
4209 // No change necessary
4210 return false; // effective visibility didn't change
4213 effectiveVisible = newEffectiveVisible;
4215 if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
4218 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(canvas);
4219 if (canvasPriv->mouseGrabberItem == q)
4223 bool childVisibilityChanged = false;
4224 for (int ii = 0; ii < childItems.count(); ++ii)
4225 childVisibilityChanged |= QQuickItemPrivate::get(childItems.at(ii))->setEffectiveVisibleRecur(newEffectiveVisible);
4227 itemChange(QQuickItem::ItemVisibleHasChanged, effectiveVisible);
4228 #ifndef QT_NO_ACCESSIBILITY
4230 QAccessibleEvent ev(q, effectiveVisible ? QAccessible::ObjectShow : QAccessible::ObjectHide);
4231 QAccessible::updateAccessibility(&ev);
4234 emit q->visibleChanged();
4235 if (childVisibilityChanged)
4236 emit q->visibleChildrenChanged();
4238 return true; // effective visibility DID change
4241 bool QQuickItemPrivate::calcEffectiveEnable() const
4243 // XXX todo - Should the effective enable of an element with no parent just be the current
4244 // effective enable? This would prevent pointless re-processing in the case of an element
4245 // moving to/from a no-parent situation, but it is different from what graphics view does.
4246 return explicitEnable && (!parentItem || QQuickItemPrivate::get(parentItem)->effectiveEnable);
4249 void QQuickItemPrivate::setEffectiveEnableRecur(QQuickItem *scope, bool newEffectiveEnable)
4253 if (newEffectiveEnable && !explicitEnable) {
4254 // This item locally overrides enable
4258 if (newEffectiveEnable == effectiveEnable) {
4259 // No change necessary
4263 effectiveEnable = newEffectiveEnable;
4266 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(canvas);
4267 if (canvasPriv->mouseGrabberItem == q)
4269 if (scope && !effectiveEnable && activeFocus) {
4270 canvasPriv->clearFocusInScope(
4271 scope, q, QQuickCanvasPrivate::DontChangeFocusProperty | QQuickCanvasPrivate::DontChangeSubFocusItem);
4275 for (int ii = 0; ii < childItems.count(); ++ii) {
4276 QQuickItemPrivate::get(childItems.at(ii))->setEffectiveEnableRecur(
4277 (flags & QQuickItem::ItemIsFocusScope) && scope ? q : scope, newEffectiveEnable);
4280 if (canvas && scope && effectiveEnable && focus) {
4281 QQuickCanvasPrivate::get(canvas)->setFocusInScope(
4282 scope, q, QQuickCanvasPrivate::DontChangeFocusProperty | QQuickCanvasPrivate::DontChangeSubFocusItem);
4285 emit q->enabledChanged();
4288 QString QQuickItemPrivate::dirtyToString() const
4290 #define DIRTY_TO_STRING(value) if (dirtyAttributes & value) { \
4291 if (!rv.isEmpty()) \
4292 rv.append(QLatin1String("|")); \
4293 rv.append(QLatin1String(#value)); \
4296 // QString rv = QLatin1String("0x") + QString::number(dirtyAttributes, 16);
4299 DIRTY_TO_STRING(TransformOrigin);
4300 DIRTY_TO_STRING(Transform);
4301 DIRTY_TO_STRING(BasicTransform);
4302 DIRTY_TO_STRING(Position);
4303 DIRTY_TO_STRING(Size);
4304 DIRTY_TO_STRING(ZValue);
4305 DIRTY_TO_STRING(Content);
4306 DIRTY_TO_STRING(Smooth);
4307 DIRTY_TO_STRING(OpacityValue);
4308 DIRTY_TO_STRING(ChildrenChanged);
4309 DIRTY_TO_STRING(ChildrenStackingChanged);
4310 DIRTY_TO_STRING(ParentChanged);
4311 DIRTY_TO_STRING(Clip);
4312 DIRTY_TO_STRING(Canvas);
4313 DIRTY_TO_STRING(EffectReference);
4314 DIRTY_TO_STRING(Visible);
4315 DIRTY_TO_STRING(HideReference);
4320 void QQuickItemPrivate::dirty(DirtyType type)
4323 if (type & (TransformOrigin | Transform | BasicTransform | Position | Size))
4326 if (!(dirtyAttributes & type) || (canvas && !prevDirtyItem)) {
4327 dirtyAttributes |= type;
4330 QQuickCanvasPrivate::get(canvas)->dirtyItem(q);
4335 void QQuickItemPrivate::addToDirtyList()
4340 if (!prevDirtyItem) {
4341 Q_ASSERT(!nextDirtyItem);
4343 QQuickCanvasPrivate *p = QQuickCanvasPrivate::get(canvas);
4344 nextDirtyItem = p->dirtyItemList;
4345 if (nextDirtyItem) QQuickItemPrivate::get(nextDirtyItem)->prevDirtyItem = &nextDirtyItem;
4346 prevDirtyItem = &p->dirtyItemList;
4347 p->dirtyItemList = q;
4350 Q_ASSERT(prevDirtyItem);
4353 void QQuickItemPrivate::removeFromDirtyList()
4355 if (prevDirtyItem) {
4356 if (nextDirtyItem) QQuickItemPrivate::get(nextDirtyItem)->prevDirtyItem = prevDirtyItem;
4357 *prevDirtyItem = nextDirtyItem;
4361 Q_ASSERT(!prevDirtyItem);
4362 Q_ASSERT(!nextDirtyItem);
4365 void QQuickItemPrivate::refFromEffectItem(bool hide)
4367 ++extra.value().effectRefCount;
4368 if (1 == extra->effectRefCount) {
4369 dirty(EffectReference);
4370 if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
4373 if (++extra->hideRefCount == 1)
4374 dirty(HideReference);
4378 void QQuickItemPrivate::derefFromEffectItem(bool unhide)
4380 Q_ASSERT(extra->effectRefCount);
4381 --extra->effectRefCount;
4382 if (0 == extra->effectRefCount) {
4383 dirty(EffectReference);
4384 if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
4387 if (--extra->hideRefCount == 0)
4388 dirty(HideReference);
4392 void QQuickItemPrivate::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data)
4396 case QQuickItem::ItemChildAddedChange:
4397 q->itemChange(change, data);
4398 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4399 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4400 if (change.types & QQuickItemPrivate::Children) {
4401 change.listener->itemChildAdded(q, data.item);
4405 case QQuickItem::ItemChildRemovedChange:
4406 q->itemChange(change, data);
4407 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4408 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4409 if (change.types & QQuickItemPrivate::Children) {
4410 change.listener->itemChildRemoved(q, data.item);
4414 case QQuickItem::ItemSceneChange:
4415 q->itemChange(change, data);
4417 case QQuickItem::ItemVisibleHasChanged:
4418 q->itemChange(change, data);
4419 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4420 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4421 if (change.types & QQuickItemPrivate::Visibility) {
4422 change.listener->itemVisibilityChanged(q);
4426 case QQuickItem::ItemParentHasChanged:
4427 q->itemChange(change, data);
4428 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4429 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4430 if (change.types & QQuickItemPrivate::Parent) {
4431 change.listener->itemParentChanged(q, data.item);
4435 case QQuickItem::ItemOpacityHasChanged:
4436 q->itemChange(change, data);
4437 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4438 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4439 if (change.types & QQuickItemPrivate::Opacity) {
4440 change.listener->itemOpacityChanged(q);
4444 case QQuickItem::ItemActiveFocusHasChanged:
4445 q->itemChange(change, data);
4447 case QQuickItem::ItemRotationHasChanged:
4448 q->itemChange(change, data);
4449 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4450 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4451 if (change.types & QQuickItemPrivate::Rotation) {
4452 change.listener->itemRotationChanged(q);
4460 \property QQuickItem::smooth
4461 \brief Specifies whether the item is smoothed or not
4463 Primarily used in image based elements to decide if the item should use smooth
4464 sampling or not. Smooth sampling is performed using linear interpolation, while
4465 non-smooth is performed using nearest neighbor.
4467 In Qt Quick 2.0, this property has minimal impact on performance.
4473 Returns true if the item should be drawn with antialiasing and
4474 smooth pixmap filtering, false otherwise.
4476 The default is false.
4480 bool QQuickItem::smooth() const
4482 Q_D(const QQuickItem);
4487 Sets whether the item should be drawn with antialiasing and
4488 smooth pixmap filtering to \a smooth.
4492 void QQuickItem::setSmooth(bool smooth)
4495 if (d->smooth == smooth)
4499 d->dirty(QQuickItemPrivate::Smooth);
4501 emit smoothChanged(smooth);
4504 QQuickItem::Flags QQuickItem::flags() const
4506 Q_D(const QQuickItem);
4507 return (QQuickItem::Flags)d->flags;
4510 void QQuickItem::setFlag(Flag flag, bool enabled)
4514 setFlags((Flags)(d->flags | (quint32)flag));
4516 setFlags((Flags)(d->flags & ~(quint32)flag));
4519 void QQuickItem::setFlags(Flags flags)
4523 if ((flags & ItemIsFocusScope) != (d->flags & ItemIsFocusScope)) {
4524 if (flags & ItemIsFocusScope && !d->childItems.isEmpty() && d->canvas) {
4525 qWarning("QQuickItem: Cannot set FocusScope once item has children and is in a canvas.");
4526 flags &= ~ItemIsFocusScope;
4527 } else if (d->flags & ItemIsFocusScope) {
4528 qWarning("QQuickItem: Cannot unset FocusScope flag.");
4529 flags |= ItemIsFocusScope;
4533 if ((flags & ItemClipsChildrenToShape ) != (d->flags & ItemClipsChildrenToShape))
4534 d->dirty(QQuickItemPrivate::Clip);
4539 qreal QQuickItem::x() const
4541 Q_D(const QQuickItem);
4545 qreal QQuickItem::y() const
4547 Q_D(const QQuickItem);
4551 QPointF QQuickItem::pos() const
4553 Q_D(const QQuickItem);
4554 return QPointF(d->x, d->y);
4557 void QQuickItem::setX(qreal v)
4566 d->dirty(QQuickItemPrivate::Position);
4568 geometryChanged(QRectF(x(), y(), width(), height()),
4569 QRectF(oldx, y(), width(), height()));
4572 void QQuickItem::setY(qreal v)
4581 d->dirty(QQuickItemPrivate::Position);
4583 geometryChanged(QRectF(x(), y(), width(), height()),
4584 QRectF(x(), oldy, width(), height()));
4587 void QQuickItem::setPos(const QPointF &pos)
4590 if (QPointF(d->x, d->y) == pos)
4599 d->dirty(QQuickItemPrivate::Position);
4601 geometryChanged(QRectF(x(), y(), width(), height()),
4602 QRectF(oldx, oldy, width(), height()));
4605 qreal QQuickItem::width() const
4607 Q_D(const QQuickItem);
4611 void QQuickItem::setWidth(qreal w)
4617 d->widthValid = true;
4621 qreal oldWidth = d->width;
4624 d->dirty(QQuickItemPrivate::Size);
4626 geometryChanged(QRectF(x(), y(), width(), height()),
4627 QRectF(x(), y(), oldWidth, height()));
4630 void QQuickItem::resetWidth()
4633 d->widthValid = false;
4634 setImplicitWidth(implicitWidth());
4637 void QQuickItemPrivate::implicitWidthChanged()
4640 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4641 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4642 if (change.types & QQuickItemPrivate::ImplicitWidth) {
4643 change.listener->itemImplicitWidthChanged(q);
4646 emit q->implicitWidthChanged();
4649 qreal QQuickItemPrivate::getImplicitWidth() const
4651 return implicitWidth;
4654 Returns the width of the item that is implied by other properties that determine the content.
4656 qreal QQuickItem::implicitWidth() const
4658 Q_D(const QQuickItem);
4659 return d->getImplicitWidth();
4663 \qmlproperty real QtQuick2::Item::implicitWidth
4664 \qmlproperty real QtQuick2::Item::implicitHeight
4666 Defines the natural width or height of the Item if no \l width or \l height is specified.
4668 The default implicit size for most items is 0x0, however some elements have an inherent
4669 implicit size which cannot be overridden, e.g. Image, Text.
4671 Setting the implicit size is useful for defining components that have a preferred size
4672 based on their content, for example:
4679 property alias icon: image.source
4680 property alias label: text.text
4681 implicitWidth: text.implicitWidth + image.implicitWidth
4682 implicitHeight: Math.max(text.implicitHeight, image.implicitHeight)
4687 anchors.left: image.right; anchors.right: parent.right
4688 anchors.verticalCenter: parent.verticalCenter
4693 \b Note: using implicitWidth of Text or TextEdit and setting the width explicitly
4694 incurs a performance penalty as the text must be laid out twice.
4698 Sets the implied width of the item to \a w.
4699 This is the width implied by other properties that determine the content.
4701 void QQuickItem::setImplicitWidth(qreal w)
4704 bool changed = w != d->implicitWidth;
4705 d->implicitWidth = w;
4706 if (d->width == w || widthValid()) {
4708 d->implicitWidthChanged();
4709 if (d->width == w || widthValid())
4714 qreal oldWidth = d->width;
4717 d->dirty(QQuickItemPrivate::Size);
4719 geometryChanged(QRectF(x(), y(), width(), height()),
4720 QRectF(x(), y(), oldWidth, height()));
4723 d->implicitWidthChanged();
4727 Returns whether the width property has been set explicitly.
4729 bool QQuickItem::widthValid() const
4731 Q_D(const QQuickItem);
4732 return d->widthValid;
4735 qreal QQuickItem::height() const
4737 Q_D(const QQuickItem);
4741 void QQuickItem::setHeight(qreal h)
4747 d->heightValid = true;
4751 qreal oldHeight = d->height;
4754 d->dirty(QQuickItemPrivate::Size);
4756 geometryChanged(QRectF(x(), y(), width(), height()),
4757 QRectF(x(), y(), width(), oldHeight));
4760 void QQuickItem::resetHeight()
4763 d->heightValid = false;
4764 setImplicitHeight(implicitHeight());
4767 void QQuickItemPrivate::implicitHeightChanged()
4770 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4771 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4772 if (change.types & QQuickItemPrivate::ImplicitHeight) {
4773 change.listener->itemImplicitHeightChanged(q);
4776 emit q->implicitHeightChanged();
4779 qreal QQuickItemPrivate::getImplicitHeight() const
4781 return implicitHeight;
4785 Returns the height of the item that is implied by other properties that determine the content.
4787 qreal QQuickItem::implicitHeight() const
4789 Q_D(const QQuickItem);
4790 return d->getImplicitHeight();
4795 Sets the implied height of the item to \a h.
4796 This is the height implied by other properties that determine the content.
4798 void QQuickItem::setImplicitHeight(qreal h)
4801 bool changed = h != d->implicitHeight;
4802 d->implicitHeight = h;
4803 if (d->height == h || heightValid()) {
4805 d->implicitHeightChanged();
4806 if (d->height == h || heightValid())
4811 qreal oldHeight = d->height;
4814 d->dirty(QQuickItemPrivate::Size);
4816 geometryChanged(QRectF(x(), y(), width(), height()),
4817 QRectF(x(), y(), width(), oldHeight));
4820 d->implicitHeightChanged();
4823 void QQuickItem::setImplicitSize(qreal w, qreal h)
4826 bool wChanged = w != d->implicitWidth;
4827 bool hChanged = h != d->implicitHeight;
4829 d->implicitWidth = w;
4830 d->implicitHeight = h;
4834 if (d->width == w || widthValid()) {
4836 d->implicitWidthChanged();
4837 wDone = d->width == w || widthValid();
4840 if (d->height == h || heightValid()) {
4842 d->implicitHeightChanged();
4843 hDone = d->height == h || heightValid();
4849 qreal oldWidth = d->width;
4850 qreal oldHeight = d->height;
4856 d->dirty(QQuickItemPrivate::Size);
4858 geometryChanged(QRectF(x(), y(), width(), height()),
4859 QRectF(x(), y(), oldWidth, oldHeight));
4861 if (!wDone && wChanged)
4862 d->implicitWidthChanged();
4863 if (!hDone && hChanged)
4864 d->implicitHeightChanged();
4868 Returns whether the height property has been set explicitly.
4870 bool QQuickItem::heightValid() const
4872 Q_D(const QQuickItem);
4873 return d->heightValid;
4876 void QQuickItem::setSize(const QSizeF &size)
4879 d->heightValid = true;
4880 d->widthValid = true;
4882 if (QSizeF(d->width, d->height) == size)
4885 qreal oldHeight = d->height;
4886 qreal oldWidth = d->width;
4887 d->height = size.height();
4888 d->width = size.width();
4890 d->dirty(QQuickItemPrivate::Size);
4892 geometryChanged(QRectF(x(), y(), width(), height()),
4893 QRectF(x(), y(), oldWidth, oldHeight));
4896 bool QQuickItem::hasActiveFocus() const
4898 Q_D(const QQuickItem);
4899 return d->activeFocus;
4902 bool QQuickItem::hasFocus() const
4904 Q_D(const QQuickItem);
4908 void QQuickItem::setFocus(bool focus)
4911 if (d->focus == focus)
4914 if (d->canvas || d->parentItem) {
4915 // Need to find our nearest focus scope
4916 QQuickItem *scope = parentItem();
4917 while (scope && !scope->isFocusScope() && scope->parentItem())
4918 scope = scope->parentItem();
4921 QQuickCanvasPrivate::get(d->canvas)->setFocusInScope(scope, this);
4923 QQuickCanvasPrivate::get(d->canvas)->clearFocusInScope(scope, this);
4925 // do the focus changes from setFocusInScope/clearFocusInScope that are
4926 // unrelated to a canvas
4927 QVarLengthArray<QQuickItem *, 20> changed;
4928 QQuickItem *oldSubFocusItem = QQuickItemPrivate::get(scope)->subFocusItem;
4929 if (oldSubFocusItem) {
4930 QQuickItemPrivate::get(oldSubFocusItem)->updateSubFocusItem(scope, false);
4931 QQuickItemPrivate::get(oldSubFocusItem)->focus = false;
4932 changed << oldSubFocusItem;
4934 d->updateSubFocusItem(scope, focus);
4938 emit focusChanged(focus);
4940 QQuickCanvasPrivate::notifyFocusChangesRecur(changed.data(), changed.count() - 1);
4944 emit focusChanged(focus);
4948 bool QQuickItem::isFocusScope() const
4950 return flags() & ItemIsFocusScope;
4953 QQuickItem *QQuickItem::scopedFocusItem() const
4955 Q_D(const QQuickItem);
4956 if (!isFocusScope())
4959 return d->subFocusItem;
4963 Qt::MouseButtons QQuickItem::acceptedMouseButtons() const
4965 Q_D(const QQuickItem);
4966 return d->acceptedMouseButtons();
4969 void QQuickItem::setAcceptedMouseButtons(Qt::MouseButtons buttons)
4972 if (buttons & Qt::LeftButton)
4975 d->extra.clearFlag();
4977 buttons &= ~Qt::LeftButton;
4978 if (buttons || d->extra.isAllocated())
4979 d->extra.value().acceptedMouseButtons = buttons;
4982 bool QQuickItem::filtersChildMouseEvents() const
4984 Q_D(const QQuickItem);
4985 return d->filtersChildMouseEvents;
4988 void QQuickItem::setFiltersChildMouseEvents(bool filter)
4991 d->filtersChildMouseEvents = filter;
4994 bool QQuickItem::isUnderMouse() const
4996 Q_D(const QQuickItem);
5000 QPointF cursorPos = QGuiApplicationPrivate::lastCursorPosition;
5001 return contains(mapFromScene(cursorPos)); // ### refactor: d->canvas->mapFromGlobal(cursorPos))))
5004 bool QQuickItem::acceptHoverEvents() const
5006 Q_D(const QQuickItem);
5007 return d->hoverEnabled;
5010 void QQuickItem::setAcceptHoverEvents(bool enabled)
5013 d->hoverEnabled = enabled;
5016 void QQuickItem::grabMouse()
5021 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
5022 if (canvasPriv->mouseGrabberItem == this)
5025 QQuickItem *oldGrabber = canvasPriv->mouseGrabberItem;
5026 canvasPriv->mouseGrabberItem = this;
5028 QEvent ev(QEvent::UngrabMouse);
5029 d->canvas->sendEvent(oldGrabber, &ev);
5033 void QQuickItem::ungrabMouse()
5038 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
5039 if (canvasPriv->mouseGrabberItem != this) {
5040 qWarning("QQuickItem::ungrabMouse(): Item is not the mouse grabber.");
5044 canvasPriv->mouseGrabberItem = 0;
5046 QEvent ev(QEvent::UngrabMouse);
5047 d->canvas->sendEvent(this, &ev);
5050 bool QQuickItem::keepMouseGrab() const
5052 Q_D(const QQuickItem);
5053 return d->keepMouse;
5057 The flag indicating whether the mouse should remain
5058 with this item is set to \a keep.
5060 This is useful for items that wish to grab and keep mouse
5061 interaction following a predefined gesture. For example,
5062 an item that is interested in horizontal mouse movement
5063 may set keepMouseGrab to true once a threshold has been
5064 exceeded. Once keepMouseGrab has been set to true, filtering
5065 items will not react to mouse events.
5067 If the item does not indicate that it wishes to retain mouse grab,
5068 a filtering item may steal the grab. For example, Flickable may attempt
5069 to steal a mouse grab if it detects that the user has begun to
5074 void QQuickItem::setKeepMouseGrab(bool keep)
5077 d->keepMouse = keep;
5081 Grabs the touch points specified by \a ids.
5083 These touch points will be owned by the item until
5084 they are released. Alternatively, the grab can be stolen
5085 by a filtering item like Flickable. Use setKeepTouchGrab()
5086 to prevent the grab from being stolen.
5088 \sa ungrabTouchPoints(), setKeepTouchGrab()
5090 void QQuickItem::grabTouchPoints(const QList<int> &ids)
5095 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
5097 QSet<QQuickItem*> ungrab;
5098 for (int i = 0; i < ids.count(); ++i) {
5099 QQuickItem *oldGrabber = canvasPriv->itemForTouchPointId.value(ids.at(i));
5100 if (oldGrabber == this)
5103 canvasPriv->itemForTouchPointId[ids.at(i)] = this;
5105 ungrab.insert(oldGrabber);
5107 foreach (QQuickItem *oldGrabber, ungrab)
5108 oldGrabber->touchUngrabEvent();
5112 Ungrabs the touch points owned by this item.
5114 \sa grabTouchPoints()
5116 void QQuickItem::ungrabTouchPoints()
5121 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
5123 QMutableHashIterator<int, QQuickItem*> i(canvasPriv->itemForTouchPointId);
5124 while (i.hasNext()) {
5126 if (i.value() == this)
5133 Returns a value indicating whether the touch points grabbed by this item
5134 should remain with this item exclusively.
5136 \sa setKeepTouchGrab(), keepMouseGrab()
5138 bool QQuickItem::keepTouchGrab() const
5140 Q_D(const QQuickItem);
5141 return d->keepTouch;
5145 The flag indicating whether the touch points grabbed
5146 by this item should remain with this item is set to \a keep.
5148 This is useful for items that wish to grab and keep specific touch
5149 points following a predefined gesture. For example,
5150 an item that is interested in horizontal touch point movement
5151 may set setKeepTouchGrab to true once a threshold has been
5152 exceeded. Once setKeepTouchGrab has been set to true, filtering
5153 items will not react to the relevant touch points.
5155 If the item does not indicate that it wishes to retain touch point grab,
5156 a filtering item may steal the grab. For example, Flickable may attempt
5157 to steal a touch point grab if it detects that the user has begun to
5160 \sa keepTouchGrab(), setKeepMouseGrab()
5162 void QQuickItem::setKeepTouchGrab(bool keep)
5165 d->keepTouch = keep;
5169 Returns true if this item contains \a point, which is in local coordinates;
5170 returns false otherwise.
5172 This function can be overwritten in order to handle point collisions in items
5173 with custom shapes. The default implementation checks if the point is inside
5174 the item's bounding rect.
5176 Note that it's normally used to check if the item is under the mouse cursor,
5177 and for that reason, the implementation of this function should be as light-weight
5180 bool QQuickItem::contains(const QPointF &point) const
5182 Q_D(const QQuickItem);
5183 return QRectF(0, 0, d->width, d->height).contains(point);
5186 QPointF QQuickItem::mapToItem(const QQuickItem *item, const QPointF &point) const
5188 QPointF p = mapToScene(point);
5190 p = item->mapFromScene(p);
5194 QPointF QQuickItem::mapToScene(const QPointF &point) const
5196 Q_D(const QQuickItem);
5197 return d->itemToCanvasTransform().map(point);
5200 QRectF QQuickItem::mapRectToItem(const QQuickItem *item, const QRectF &rect) const
5202 Q_D(const QQuickItem);
5203 QTransform t = d->itemToCanvasTransform();
5205 t *= QQuickItemPrivate::get(item)->canvasToItemTransform();
5206 return t.mapRect(rect);
5209 QRectF QQuickItem::mapRectToScene(const QRectF &rect) const
5211 Q_D(const QQuickItem);
5212 return d->itemToCanvasTransform().mapRect(rect);
5215 QPointF QQuickItem::mapFromItem(const QQuickItem *item, const QPointF &point) const
5217 QPointF p = item?item->mapToScene(point):point;
5218 return mapFromScene(p);
5221 QPointF QQuickItem::mapFromScene(const QPointF &point) const
5223 Q_D(const QQuickItem);
5224 return d->canvasToItemTransform().map(point);
5227 QRectF QQuickItem::mapRectFromItem(const QQuickItem *item, const QRectF &rect) const
5229 Q_D(const QQuickItem);
5230 QTransform t = item?QQuickItemPrivate::get(item)->itemToCanvasTransform():QTransform();
5231 t *= d->canvasToItemTransform();
5232 return t.mapRect(rect);
5235 QRectF QQuickItem::mapRectFromScene(const QRectF &rect) const
5237 Q_D(const QQuickItem);
5238 return d->canvasToItemTransform().mapRect(rect);
5243 \qmlmethod QtQuick2::Item::forceActiveFocus()
5245 Forces active focus on the item.
5247 This method sets focus on the item and makes sure that all the focus scopes
5248 higher in the object hierarchy are also given the focus.
5252 Forces active focus on the item.
5254 This method sets focus on the item and makes sure that all the focus scopes
5255 higher in the object hierarchy are also given the focus.
5259 \qmlmethod QtQuick2::Item::childAt(real x, real y)
5261 Returns the visible child item at point (\a x, \a y), which is in this
5262 item's coordinate system, or \c null if there is no such item.
5266 Returns the visible child item at point (\a x, \a y), which is in this
5267 item's coordinate system, or 0 if there is no such item.
5271 \qmlproperty list<State> QtQuick2::Item::states
5272 This property holds a list of states defined by the item.
5288 \sa {qmlstate}{States}
5291 \qmlproperty list<Transition> QtQuick2::Item::transitions
5292 This property holds a list of transitions defined by the item.
5308 \sa {QML Animation and Transitions}{Transitions}
5311 \qmlproperty list<Filter> QtQuick2::Item::filter
5312 This property holds a list of graphical filters to be applied to the item.
5314 \l {Filter}{Filters} include things like \l {Blur}{blurring}
5315 the item, or giving it a \l Reflection. Some
5316 filters may not be available on all canvases; if a filter is not
5317 available on a certain canvas, it will simply not be applied for
5318 that canvas (but the QML will still be considered valid).
5336 \qmlproperty bool QtQuick2::Item::clip
5337 This property holds whether clipping is enabled. The default clip value is \c false.
5339 If clipping is enabled, an item will clip its own painting, as well
5340 as the painting of its children, to its bounding rectangle.
5342 Non-rectangular clipping regions are not supported for performance reasons.
5346 \property QQuickItem::clip
5347 This property holds whether clipping is enabled. The default clip value is \c false.
5349 If clipping is enabled, an item will clip its own painting, as well
5350 as the painting of its children, to its bounding rectangle. If you set
5351 clipping during an item's paint operation, remember to re-set it to
5352 prevent clipping the rest of your scene.
5354 Non-rectangular clipping regions are not supported for performance reasons.
5358 \qmlproperty string QtQuick2::Item::state
5360 This property holds the name of the current state of the item.
5362 This property is often used in scripts to change between states. For
5367 if (button.state == 'On')
5368 button.state = 'Off';
5370 button.state = 'On';
5374 If the item is in its base state (i.e. no explicit state has been
5375 set), \c state will be a blank string. Likewise, you can return an
5376 item to its base state by setting its current state to \c ''.
5378 \sa {qmlstates}{States}
5382 \qmlproperty list<Transform> QtQuick2::Item::transform
5383 This property holds the list of transformations to apply.
5385 For more information see \l Transform.
5389 \enum QQuickItem::TransformOrigin
5391 Controls the point about which simple transforms like scale apply.
5393 \value TopLeft The top-left corner of the item.
5394 \value Top The center point of the top of the item.
5395 \value TopRight The top-right corner of the item.
5396 \value Left The left most point of the vertical middle.
5397 \value Center The center of the item.
5398 \value Right The right most point of the vertical middle.
5399 \value BottomLeft The bottom-left corner of the item.
5400 \value Bottom The center point of the bottom of the item.
5401 \value BottomRight The bottom-right corner of the item.
5406 \qmlproperty bool QtQuick2::Item::activeFocus
5408 This property indicates whether the item has active focus.
5410 An item with active focus will receive keyboard input,
5411 or is a FocusScope ancestor of the item that will receive keyboard input.
5413 Usually, activeFocus is gained by setting focus on an item and its enclosing
5414 FocusScopes. In the following example \c input will have activeFocus.
5427 \sa focus, {qmlfocus}{Keyboard Focus}
5431 \qmlproperty bool QtQuick2::Item::focus
5432 This property indicates whether the item has focus within the enclosing focus scope. If true, this item
5433 will gain active focus when the enclosing focus scope gains active focus.
5434 In the following example, \c input will be given active focus when \c scope gains active focus.
5447 For the purposes of this property, the scene as a whole is assumed to act like a focus scope.
5448 On a practical level, that means the following QML will give active focus to \c input on startup.
5459 \sa activeFocus, {qmlfocus}{Keyboard Focus}
5464 \property QQuickItem::anchors
5469 \property QQuickItem::left
5474 \property QQuickItem::right
5479 \property QQuickItem::horizontalCenter
5484 \property QQuickItem::top
5489 \property QQuickItem::bottom
5494 \property QQuickItem::verticalCenter
5499 \property QQuickItem::focus
5504 \property QQuickItem::transform
5509 \property QQuickItem::transformOrigin
5514 \property QQuickItem::activeFocus
5519 \property QQuickItem::baseline
5524 \property QQuickItem::data
5529 \property QQuickItem::resources
5534 \property QQuickItem::state
5539 \property QQuickItem::states
5544 \property QQuickItem::transformOriginPoint
5549 \property QQuickItem::transitions
5553 bool QQuickItem::event(QEvent *ev)
5556 if (ev->type() == QEvent::PolishRequest) {
5558 d->polishScheduled = false;
5562 return QObject::event(ev);
5565 if (ev->type() == QEvent::InputMethodQuery) {
5566 QInputMethodQueryEvent *query = static_cast<QInputMethodQueryEvent *>(ev);
5567 Qt::InputMethodQueries queries = query->queries();
5568 for (uint i = 0; i < 32; ++i) {
5569 Qt::InputMethodQuery q = (Qt::InputMethodQuery)(int)(queries & (1<<i));
5571 QVariant v = inputMethodQuery(q);
5572 query->setValue(q, v);
5577 } else if (ev->type() == QEvent::InputMethod) {
5578 inputMethodEvent(static_cast<QInputMethodEvent *>(ev));
5581 return QObject::event(ev);
5584 #ifndef QT_NO_DEBUG_STREAM
5585 QDebug operator<<(QDebug debug, QQuickItem *item)
5588 debug << "QQuickItem(0)";
5592 debug << item->metaObject()->className() << "(this =" << ((void*)item)
5593 << ", name=" << item->objectName()
5594 << ", parent =" << ((void*)item->parentItem())
5595 << ", geometry =" << QRectF(item->pos(), QSizeF(item->width(), item->height()))
5596 << ", z =" << item->z() << ')';
5601 qint64 QQuickItemPrivate::consistentTime = -1;
5602 void QQuickItemPrivate::setConsistentTime(qint64 t)
5607 class QElapsedTimerConsistentTimeHack
5611 t1 = QQuickItemPrivate::consistentTime;
5615 return QQuickItemPrivate::consistentTime - t1;
5618 qint64 val = QQuickItemPrivate::consistentTime - t1;
5619 t1 = QQuickItemPrivate::consistentTime;
5629 void QQuickItemPrivate::start(QElapsedTimer &t)
5631 if (QQuickItemPrivate::consistentTime == -1)
5634 ((QElapsedTimerConsistentTimeHack*)&t)->start();
5637 qint64 QQuickItemPrivate::elapsed(QElapsedTimer &t)
5639 if (QQuickItemPrivate::consistentTime == -1)
5642 return ((QElapsedTimerConsistentTimeHack*)&t)->elapsed();
5645 qint64 QQuickItemPrivate::restart(QElapsedTimer &t)
5647 if (QQuickItemPrivate::consistentTime == -1)
5650 return ((QElapsedTimerConsistentTimeHack*)&t)->restart();
5654 \fn bool QQuickItem::isTextureProvider() const
5656 Returns true if this item is a texture provider. The default
5657 implementation returns false.
5659 This function can be called from any thread.
5662 bool QQuickItem::isTextureProvider() const
5664 Q_D(const QQuickItem);
5665 return d->extra.isAllocated() && d->extra->layer && d->extra->layer->effectSource() ?
5666 d->extra->layer->effectSource()->isTextureProvider() : false;
5670 \fn QSGTextureProvider *QQuickItem::textureProvider() const
5672 Returns the texture provider for an item. The default implementation
5675 This function may only be called on the rendering thread.
5678 QSGTextureProvider *QQuickItem::textureProvider() const
5680 Q_D(const QQuickItem);
5681 return d->extra.isAllocated() && d->extra->layer && d->extra->layer->effectSource() ?
5682 d->extra->layer->effectSource()->textureProvider() : 0;
5685 QQuickItemLayer *QQuickItemPrivate::layer() const
5687 if (!extra.isAllocated() || !extra->layer) {
5688 extra.value().layer = new QQuickItemLayer(const_cast<QQuickItem *>(q_func()));
5689 if (!componentComplete)
5690 extra->layer->classBegin();
5692 return extra->layer;
5695 QQuickItemLayer::QQuickItemLayer(QQuickItem *item)
5700 , m_componentComplete(true)
5701 , m_wrapMode(QQuickShaderEffectSource::ClampToEdge)
5702 , m_format(QQuickShaderEffectSource::RGBA)
5704 , m_effectComponent(0)
5710 QQuickItemLayer::~QQuickItemLayer()
5712 delete m_effectSource;
5719 \qmlproperty bool QtQuick2::Item::layer.enabled
5721 Holds wether the item is layered or not. Layering is disabled by default.
5723 A layered item is rendered into an offscreen surface and cached until
5724 it is changed. Enabling layering for complex QML item hierarchies can
5725 some times be an optimization.
5727 None of the other layer properties have any effect when the layer
5731 void QQuickItemLayer::setEnabled(bool e)
5736 if (m_componentComplete) {
5743 emit enabledChanged(e);
5746 void QQuickItemLayer::classBegin()
5748 Q_ASSERT(!m_effectSource);
5749 Q_ASSERT(!m_effect);
5750 m_componentComplete = false;
5753 void QQuickItemLayer::componentComplete()
5755 Q_ASSERT(!m_componentComplete);
5756 m_componentComplete = true;
5761 void QQuickItemLayer::activate()
5763 Q_ASSERT(!m_effectSource);
5764 m_effectSource = new QQuickShaderEffectSource();
5766 QQuickItem *parentItem = m_item->parentItem();
5768 m_effectSource->setParentItem(parentItem);
5769 m_effectSource->stackAfter(m_item);
5772 m_effectSource->setSourceItem(m_item);
5773 m_effectSource->setHideSource(true);
5774 m_effectSource->setSmooth(m_smooth);
5775 m_effectSource->setTextureSize(m_size);
5776 m_effectSource->setSourceRect(m_sourceRect);
5777 m_effectSource->setMipmap(m_mipmap);
5778 m_effectSource->setWrapMode(m_wrapMode);
5779 m_effectSource->setFormat(m_format);
5781 if (m_effectComponent)
5784 m_effectSource->setVisible(m_item->isVisible() && !m_effect);
5791 QQuickItemPrivate *id = QQuickItemPrivate::get(m_item);
5792 id->addItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Opacity | QQuickItemPrivate::Parent | QQuickItemPrivate::Visibility | QQuickItemPrivate::SiblingOrder);
5795 void QQuickItemLayer::deactivate()
5797 Q_ASSERT(m_effectSource);
5799 if (m_effectComponent)
5802 delete m_effectSource;
5805 QQuickItemPrivate *id = QQuickItemPrivate::get(m_item);
5806 id->removeItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Opacity | QQuickItemPrivate::Parent | QQuickItemPrivate::Visibility | QQuickItemPrivate::SiblingOrder);
5809 void QQuickItemLayer::activateEffect()
5811 Q_ASSERT(m_effectSource);
5812 Q_ASSERT(m_effectComponent);
5813 Q_ASSERT(!m_effect);
5815 QObject *created = m_effectComponent->beginCreate(m_effectComponent->creationContext());
5816 m_effect = qobject_cast<QQuickItem *>(created);
5818 qWarning("Item: layer.effect is not a QML Item.");
5819 m_effectComponent->completeCreate();
5823 QQuickItem *parentItem = m_item->parentItem();
5825 m_effect->setParentItem(parentItem);
5826 m_effect->stackAfter(m_effectSource);
5828 m_effect->setVisible(m_item->isVisible());
5829 m_effect->setProperty(m_name, qVariantFromValue<QObject *>(m_effectSource));
5830 m_effectComponent->completeCreate();
5833 void QQuickItemLayer::deactivateEffect()
5835 Q_ASSERT(m_effectSource);
5836 Q_ASSERT(m_effectComponent);
5844 \qmlproperty Component QtQuick2::Item::layer.effect
5846 Holds the effect that is applied to this layer.
5848 The effect is typically a \l ShaderEffect component, although any \l Item component can be
5849 assigned. The effect should have a source texture property with a name matching \l samplerName.
5854 void QQuickItemLayer::setEffect(QQmlComponent *component)
5856 if (component == m_effectComponent)
5859 bool updateNeeded = false;
5860 if (m_effectSource && m_effectComponent) {
5862 updateNeeded = true;
5865 m_effectComponent = component;
5867 if (m_effectSource && m_effectComponent) {
5869 updateNeeded = true;
5877 m_effectSource->setVisible(m_item->isVisible() && !m_effect);
5880 emit effectChanged(component);
5885 \qmlproperty bool QtQuick2::Item::layer.mipmap
5887 If this property is true, mipmaps are generated for the texture.
5889 \note Some OpenGL ES 2 implementations do not support mipmapping of
5890 non-power-of-two textures.
5893 void QQuickItemLayer::setMipmap(bool mipmap)
5895 if (mipmap == m_mipmap)
5900 m_effectSource->setMipmap(m_mipmap);
5902 emit mipmapChanged(mipmap);
5907 \qmlproperty enumeration QtQuick2::Item::layer.format
5909 This property defines the internal OpenGL format of the texture.
5910 Modifying this property makes most sense when the \a layer.effect is also
5911 specified. Depending on the OpenGL implementation, this property might
5912 allow you to save some texture memory.
5915 \li ShaderEffectSource.Alpha - GL_ALPHA
5916 \li ShaderEffectSource.RGB - GL_RGB
5917 \li ShaderEffectSource.RGBA - GL_RGBA
5920 \note Some OpenGL implementations do not support the GL_ALPHA format.
5923 void QQuickItemLayer::setFormat(QQuickShaderEffectSource::Format f)
5930 m_effectSource->setFormat(m_format);
5932 emit formatChanged(m_format);
5937 \qmlproperty enumeration QtQuick2::Item::layer.sourceRect
5939 This property defines which rectangular area of the \l sourceItem to
5940 render into the texture. The source rectangle can be larger than
5941 \l sourceItem itself. If the rectangle is null, which is the default,
5942 the whole \l sourceItem is rendered to texture.
5945 void QQuickItemLayer::setSourceRect(const QRectF &sourceRect)
5947 if (sourceRect == m_sourceRect)
5949 m_sourceRect = sourceRect;
5952 m_effectSource->setSourceRect(m_sourceRect);
5954 emit sourceRectChanged(sourceRect);
5960 \qmlproperty bool QtQuick2::Item::layer.smooth
5962 Holds whether the layer is smoothly transformed.
5965 void QQuickItemLayer::setSmooth(bool s)
5972 m_effectSource->setSmooth(m_smooth);
5974 emit smoothChanged(s);
5980 \qmlproperty size QtQuick2::Item::layer.textureSize
5982 This property holds the requested pixel size of the layers texture. If it is empty,
5983 which is the default, the size of the item is used.
5985 \note Some platforms have a limit on how small framebuffer objects can be,
5986 which means the actual texture size might be larger than the requested
5990 void QQuickItemLayer::setSize(const QSize &size)
5997 m_effectSource->setTextureSize(size);
5999 emit sizeChanged(size);
6005 \qmlproperty enumeration QtQuick2::Item::layer.wrapMode
6007 This property defines the OpenGL wrap modes associated with the texture.
6008 Modifying this property makes most sense when the \a layer.effect is
6012 \li ShaderEffectSource.ClampToEdge - GL_CLAMP_TO_EDGE both horizontally and vertically
6013 \li ShaderEffectSource.RepeatHorizontally - GL_REPEAT horizontally, GL_CLAMP_TO_EDGE vertically
6014 \li ShaderEffectSource.RepeatVertically - GL_CLAMP_TO_EDGE horizontally, GL_REPEAT vertically
6015 \li ShaderEffectSource.Repeat - GL_REPEAT both horizontally and vertically
6018 \note Some OpenGL ES 2 implementations do not support the GL_REPEAT
6019 wrap mode with non-power-of-two textures.
6022 void QQuickItemLayer::setWrapMode(QQuickShaderEffectSource::WrapMode mode)
6024 if (mode == m_wrapMode)
6029 m_effectSource->setWrapMode(m_wrapMode);
6031 emit wrapModeChanged(mode);
6035 \qmlproperty string QtQuick2::Item::layer.samplerName
6037 Holds the name of the effect's source texture property.
6039 samplerName needs to match the name of the effect's source texture property
6040 so that the Item can pass the layer's offscreen surface to the effect correctly.
6042 \sa effect, ShaderEffect
6045 void QQuickItemLayer::setName(const QByteArray &name) {
6049 m_effect->setProperty(m_name, QVariant());
6050 m_effect->setProperty(name, qVariantFromValue<QObject *>(m_effectSource));
6053 emit nameChanged(name);
6056 void QQuickItemLayer::itemOpacityChanged(QQuickItem *item)
6062 void QQuickItemLayer::itemGeometryChanged(QQuickItem *, const QRectF &, const QRectF &)
6067 void QQuickItemLayer::itemParentChanged(QQuickItem *item, QQuickItem *parent)
6070 Q_ASSERT(item == m_item);
6071 Q_ASSERT(parent != m_effectSource);
6072 Q_ASSERT(parent == 0 || parent != m_effect);
6074 m_effectSource->setParentItem(parent);
6076 m_effectSource->stackAfter(m_item);
6079 m_effect->setParentItem(parent);
6081 m_effect->stackAfter(m_effectSource);
6085 void QQuickItemLayer::itemSiblingOrderChanged(QQuickItem *)
6087 m_effectSource->stackAfter(m_item);
6089 m_effect->stackAfter(m_effectSource);
6092 void QQuickItemLayer::itemVisibilityChanged(QQuickItem *)
6094 QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
6096 l->setVisible(m_item->isVisible());
6099 void QQuickItemLayer::updateZ()
6101 if (!m_componentComplete || !m_enabled)
6103 QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
6105 l->setZ(m_item->z());
6108 void QQuickItemLayer::updateOpacity()
6110 QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
6112 l->setOpacity(m_item->opacity());
6115 void QQuickItemLayer::updateGeometry()
6117 QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
6119 QRectF bounds = m_item->clipRect();
6120 l->setWidth(bounds.width());
6121 l->setHeight(bounds.height());
6122 l->setX(bounds.x() + m_item->x());
6123 l->setY(bounds.y() + m_item->y());
6126 void QQuickItemLayer::updateMatrix()
6128 // Called directly from transformChanged(), so needs some extra
6130 if (!m_componentComplete || !m_enabled)
6132 QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
6134 QQuickItemPrivate *ld = QQuickItemPrivate::get(l);
6135 l->setScale(m_item->scale());
6136 l->setRotation(m_item->rotation());
6137 ld->transforms = QQuickItemPrivate::get(m_item)->transforms;
6138 if (ld->origin() != QQuickItemPrivate::get(m_item)->origin())
6139 ld->extra.value().origin = QQuickItemPrivate::get(m_item)->origin();
6140 ld->dirty(QQuickItemPrivate::Transform);
6143 QQuickItemPrivate::ExtraData::ExtraData()
6144 : z(0), scale(1), rotation(0), opacity(1),
6145 contents(0), screenAttached(0), layoutDirectionAttached(0),
6146 keyHandler(0), layer(0), effectRefCount(0), hideRefCount(0),
6147 opacityNode(0), clipNode(0), rootNode(0), beforePaintNode(0),
6148 acceptedMouseButtons(0), origin(QQuickItem::Center)
6154 #include <moc_qquickitem.cpp>