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 qtquick-visual-transforms
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 qtquick-visual-transforms
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 qtquick-visual-transforms
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 qtquick-visual-transforms
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 qtquick-input
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 int signal_index = d->signalIndex(signalName);
914 return d->isSignalConnected(signal_index);
918 \qmlclass Keys QQuickKeysAttached
919 \inqmlmodule QtQuick 2
920 \ingroup qtquick-input
921 \brief Provides key handling to Items
923 All visual primitives support key handling via the Keys
924 attached property. Keys can be handled via the onPressed
925 and onReleased signal properties.
927 The signal properties have a \l KeyEvent parameter, named
928 \e event which contains details of the event. If a key is
929 handled \e event.accepted should be set to true to prevent the
930 event from propagating up the item hierarchy.
932 \section1 Example Usage
934 The following example shows how the general onPressed handler can
935 be used to test for a certain key; in this case, the left cursor
938 \snippet qml/keys/keys-pressed.qml key item
940 Some keys may alternatively be handled via specific signal properties,
941 for example \e onSelectPressed. These handlers automatically set
942 \e event.accepted to true.
944 \snippet qml/keys/keys-handler.qml key item
946 See \l{Qt::Key}{Qt.Key} for the list of keyboard codes.
948 \section1 Key Handling Priorities
950 The Keys attached property can be configured to handle key events
951 before or after the item it is attached to. This makes it possible
952 to intercept events in order to override an item's default behavior,
953 or act as a fallback for keys not handled by the item.
955 If \l priority is Keys.BeforeItem (default) the order of key event processing is:
958 \li Items specified in \c forwardTo
959 \li specific key handlers, e.g. onReturnPressed
960 \li onKeyPress, onKeyRelease handlers
961 \li Item specific key handling, e.g. TextInput key handling
965 If priority is Keys.AfterItem the order of key event processing is:
968 \li Item specific key handling, e.g. TextInput key handling
969 \li Items specified in \c forwardTo
970 \li specific key handlers, e.g. onReturnPressed
971 \li onKeyPress, onKeyRelease handlers
975 If the event is accepted during any of the above steps, key
978 \sa KeyEvent, {KeyNavigation}{KeyNavigation attached property}
982 \qmlproperty bool QtQuick2::Keys::enabled
984 This flags enables key handling if true (default); otherwise
985 no key handlers will be called.
989 \qmlproperty enumeration QtQuick2::Keys::priority
991 This property determines whether the keys are processed before
992 or after the attached item's own key handling.
995 \li Keys.BeforeItem (default) - process the key events before normal
996 item key processing. If the event is accepted it will not
997 be passed on to the item.
998 \li Keys.AfterItem - process the key events after normal item key
999 handling. If the item accepts the key event it will not be
1000 handled by the Keys attached property handler.
1005 \qmlproperty list<Object> QtQuick2::Keys::forwardTo
1007 This property provides a way to forward key presses, key releases, and keyboard input
1008 coming from input methods to other items. This can be useful when you want
1009 one item to handle some keys (e.g. the up and down arrow keys), and another item to
1010 handle other keys (e.g. the left and right arrow keys). Once an item that has been
1011 forwarded keys accepts the event it is no longer forwarded to items later in the
1014 This example forwards key events to two lists:
1025 Keys.forwardTo: [list1, list2]
1032 \qmlsignal QtQuick2::Keys::onPressed(KeyEvent event)
1034 This handler is called when a key has been pressed. The \a event
1035 parameter provides information about the event.
1039 \qmlsignal QtQuick2::Keys::onReleased(KeyEvent event)
1041 This handler is called when a key has been released. The \a event
1042 parameter provides information about the event.
1046 \qmlsignal QtQuick2::Keys::onDigit0Pressed(KeyEvent event)
1048 This handler is called when the digit '0' has been pressed. The \a event
1049 parameter provides information about the event.
1053 \qmlsignal QtQuick2::Keys::onDigit1Pressed(KeyEvent event)
1055 This handler is called when the digit '1' has been pressed. The \a event
1056 parameter provides information about the event.
1060 \qmlsignal QtQuick2::Keys::onDigit2Pressed(KeyEvent event)
1062 This handler is called when the digit '2' has been pressed. The \a event
1063 parameter provides information about the event.
1067 \qmlsignal QtQuick2::Keys::onDigit3Pressed(KeyEvent event)
1069 This handler is called when the digit '3' has been pressed. The \a event
1070 parameter provides information about the event.
1074 \qmlsignal QtQuick2::Keys::onDigit4Pressed(KeyEvent event)
1076 This handler is called when the digit '4' has been pressed. The \a event
1077 parameter provides information about the event.
1081 \qmlsignal QtQuick2::Keys::onDigit5Pressed(KeyEvent event)
1083 This handler is called when the digit '5' has been pressed. The \a event
1084 parameter provides information about the event.
1088 \qmlsignal QtQuick2::Keys::onDigit6Pressed(KeyEvent event)
1090 This handler is called when the digit '6' has been pressed. The \a event
1091 parameter provides information about the event.
1095 \qmlsignal QtQuick2::Keys::onDigit7Pressed(KeyEvent event)
1097 This handler is called when the digit '7' has been pressed. The \a event
1098 parameter provides information about the event.
1102 \qmlsignal QtQuick2::Keys::onDigit8Pressed(KeyEvent event)
1104 This handler is called when the digit '8' has been pressed. The \a event
1105 parameter provides information about the event.
1109 \qmlsignal QtQuick2::Keys::onDigit9Pressed(KeyEvent event)
1111 This handler is called when the digit '9' has been pressed. The \a event
1112 parameter provides information about the event.
1116 \qmlsignal QtQuick2::Keys::onLeftPressed(KeyEvent event)
1118 This handler is called when the Left arrow has been pressed. The \a event
1119 parameter provides information about the event.
1123 \qmlsignal QtQuick2::Keys::onRightPressed(KeyEvent event)
1125 This handler is called when the Right arrow has been pressed. The \a event
1126 parameter provides information about the event.
1130 \qmlsignal QtQuick2::Keys::onUpPressed(KeyEvent event)
1132 This handler is called when the Up arrow has been pressed. The \a event
1133 parameter provides information about the event.
1137 \qmlsignal QtQuick2::Keys::onDownPressed(KeyEvent event)
1139 This handler is called when the Down arrow has been pressed. The \a event
1140 parameter provides information about the event.
1144 \qmlsignal QtQuick2::Keys::onTabPressed(KeyEvent event)
1146 This handler is called when the Tab key has been pressed. The \a event
1147 parameter provides information about the event.
1151 \qmlsignal QtQuick2::Keys::onBacktabPressed(KeyEvent event)
1153 This handler is called when the Shift+Tab key combination (Backtab) has
1154 been pressed. The \a event parameter provides information about the event.
1158 \qmlsignal QtQuick2::Keys::onAsteriskPressed(KeyEvent event)
1160 This handler is called when the Asterisk '*' has been pressed. The \a event
1161 parameter provides information about the event.
1165 \qmlsignal QtQuick2::Keys::onEscapePressed(KeyEvent event)
1167 This handler is called when the Escape key has been pressed. The \a event
1168 parameter provides information about the event.
1172 \qmlsignal QtQuick2::Keys::onReturnPressed(KeyEvent event)
1174 This handler is called when the Return key has been pressed. The \a event
1175 parameter provides information about the event.
1179 \qmlsignal QtQuick2::Keys::onEnterPressed(KeyEvent event)
1181 This handler is called when the Enter key has been pressed. The \a event
1182 parameter provides information about the event.
1186 \qmlsignal QtQuick2::Keys::onDeletePressed(KeyEvent event)
1188 This handler is called when the Delete key has been pressed. The \a event
1189 parameter provides information about the event.
1193 \qmlsignal QtQuick2::Keys::onSpacePressed(KeyEvent event)
1195 This handler is called when the Space key has been pressed. The \a event
1196 parameter provides information about the event.
1200 \qmlsignal QtQuick2::Keys::onBackPressed(KeyEvent event)
1202 This handler is called when the Back key has been pressed. The \a event
1203 parameter provides information about the event.
1207 \qmlsignal QtQuick2::Keys::onCancelPressed(KeyEvent event)
1209 This handler is called when the Cancel key has been pressed. The \a event
1210 parameter provides information about the event.
1214 \qmlsignal QtQuick2::Keys::onSelectPressed(KeyEvent event)
1216 This handler is called when the Select key has been pressed. The \a event
1217 parameter provides information about the event.
1221 \qmlsignal QtQuick2::Keys::onYesPressed(KeyEvent event)
1223 This handler is called when the Yes key has been pressed. The \a event
1224 parameter provides information about the event.
1228 \qmlsignal QtQuick2::Keys::onNoPressed(KeyEvent event)
1230 This handler is called when the No key has been pressed. The \a event
1231 parameter provides information about the event.
1235 \qmlsignal QtQuick2::Keys::onContext1Pressed(KeyEvent event)
1237 This handler is called when the Context1 key has been pressed. The \a event
1238 parameter provides information about the event.
1242 \qmlsignal QtQuick2::Keys::onContext2Pressed(KeyEvent event)
1244 This handler is called when the Context2 key has been pressed. The \a event
1245 parameter provides information about the event.
1249 \qmlsignal QtQuick2::Keys::onContext3Pressed(KeyEvent event)
1251 This handler is called when the Context3 key has been pressed. The \a event
1252 parameter provides information about the event.
1256 \qmlsignal QtQuick2::Keys::onContext4Pressed(KeyEvent event)
1258 This handler is called when the Context4 key has been pressed. The \a event
1259 parameter provides information about the event.
1263 \qmlsignal QtQuick2::Keys::onCallPressed(KeyEvent event)
1265 This handler is called when the Call key has been pressed. The \a event
1266 parameter provides information about the event.
1270 \qmlsignal QtQuick2::Keys::onHangupPressed(KeyEvent event)
1272 This handler is called when the Hangup key has been pressed. The \a event
1273 parameter provides information about the event.
1277 \qmlsignal QtQuick2::Keys::onFlipPressed(KeyEvent event)
1279 This handler is called when the Flip key has been pressed. The \a event
1280 parameter provides information about the event.
1284 \qmlsignal QtQuick2::Keys::onMenuPressed(KeyEvent event)
1286 This handler is called when the Menu key has been pressed. The \a event
1287 parameter provides information about the event.
1291 \qmlsignal QtQuick2::Keys::onVolumeUpPressed(KeyEvent event)
1293 This handler is called when the VolumeUp key has been pressed. The \a event
1294 parameter provides information about the event.
1298 \qmlsignal QtQuick2::Keys::onVolumeDownPressed(KeyEvent event)
1300 This handler is called when the VolumeDown key has been pressed. The \a event
1301 parameter provides information about the event.
1304 QQuickKeysAttached::QQuickKeysAttached(QObject *parent)
1305 : QObject(*(new QQuickKeysAttachedPrivate), parent),
1306 QQuickItemKeyFilter(qmlobject_cast<QQuickItem*>(parent))
1308 Q_D(QQuickKeysAttached);
1309 m_processPost = false;
1310 d->item = qmlobject_cast<QQuickItem*>(parent);
1313 QQuickKeysAttached::~QQuickKeysAttached()
1317 QQuickKeysAttached::Priority QQuickKeysAttached::priority() const
1319 return m_processPost ? AfterItem : BeforeItem;
1322 void QQuickKeysAttached::setPriority(Priority order)
1324 bool processPost = order == AfterItem;
1325 if (processPost != m_processPost) {
1326 m_processPost = processPost;
1327 emit priorityChanged();
1331 void QQuickKeysAttached::componentComplete()
1333 Q_D(QQuickKeysAttached);
1335 for (int ii = 0; ii < d->targets.count(); ++ii) {
1336 QQuickItem *targetItem = d->targets.at(ii);
1337 if (targetItem && (targetItem->flags() & QQuickItem::ItemAcceptsInputMethod)) {
1338 d->item->setFlag(QQuickItem::ItemAcceptsInputMethod);
1345 void QQuickKeysAttached::keyPressed(QKeyEvent *event, bool post)
1347 Q_D(QQuickKeysAttached);
1348 if (post != m_processPost || !d->enabled || d->inPress) {
1350 QQuickItemKeyFilter::keyPressed(event, post);
1354 // first process forwards
1355 if (d->item && d->item->canvas()) {
1357 for (int ii = 0; ii < d->targets.count(); ++ii) {
1358 QQuickItem *i = d->targets.at(ii);
1359 if (i && i->isVisible()) {
1360 d->item->canvas()->sendEvent(i, event);
1361 if (event->isAccepted()) {
1370 QQuickKeyEvent ke(*event);
1371 QByteArray keySignal = keyToSignal(event->key());
1372 if (!keySignal.isEmpty()) {
1373 keySignal += "(QQuickKeyEvent*)";
1374 if (isConnected(keySignal)) {
1375 // If we specifically handle a key then default to accepted
1376 ke.setAccepted(true);
1377 int idx = QQuickKeysAttached::staticMetaObject.indexOfSignal(keySignal);
1378 metaObject()->method(idx).invoke(this, Qt::DirectConnection, Q_ARG(QQuickKeyEvent*, &ke));
1381 if (!ke.isAccepted())
1383 event->setAccepted(ke.isAccepted());
1385 if (!event->isAccepted()) QQuickItemKeyFilter::keyPressed(event, post);
1388 void QQuickKeysAttached::keyReleased(QKeyEvent *event, bool post)
1390 Q_D(QQuickKeysAttached);
1391 if (post != m_processPost || !d->enabled || d->inRelease) {
1393 QQuickItemKeyFilter::keyReleased(event, post);
1397 if (d->item && d->item->canvas()) {
1398 d->inRelease = true;
1399 for (int ii = 0; ii < d->targets.count(); ++ii) {
1400 QQuickItem *i = d->targets.at(ii);
1401 if (i && i->isVisible()) {
1402 d->item->canvas()->sendEvent(i, event);
1403 if (event->isAccepted()) {
1404 d->inRelease = false;
1409 d->inRelease = false;
1412 QQuickKeyEvent ke(*event);
1414 event->setAccepted(ke.isAccepted());
1416 if (!event->isAccepted()) QQuickItemKeyFilter::keyReleased(event, post);
1419 void QQuickKeysAttached::inputMethodEvent(QInputMethodEvent *event, bool post)
1421 Q_D(QQuickKeysAttached);
1422 if (post == m_processPost && d->item && !d->inIM && d->item->canvas()) {
1424 for (int ii = 0; ii < d->targets.count(); ++ii) {
1425 QQuickItem *i = d->targets.at(ii);
1426 if (i && i->isVisible() && (i->flags() & QQuickItem::ItemAcceptsInputMethod)) {
1427 d->item->canvas()->sendEvent(i, event);
1428 if (event->isAccepted()) {
1437 QQuickItemKeyFilter::inputMethodEvent(event, post);
1440 QVariant QQuickKeysAttached::inputMethodQuery(Qt::InputMethodQuery query) const
1442 Q_D(const QQuickKeysAttached);
1444 for (int ii = 0; ii < d->targets.count(); ++ii) {
1445 QQuickItem *i = d->targets.at(ii);
1446 if (i && i->isVisible() && (i->flags() & QQuickItem::ItemAcceptsInputMethod) && i == d->imeItem) {
1447 //### how robust is i == d->imeItem check?
1448 QVariant v = i->inputMethodQuery(query);
1449 if (v.userType() == QVariant::RectF)
1450 v = d->item->mapRectFromItem(i, v.toRectF()); //### cost?
1455 return QQuickItemKeyFilter::inputMethodQuery(query);
1458 QQuickKeysAttached *QQuickKeysAttached::qmlAttachedProperties(QObject *obj)
1460 return new QQuickKeysAttached(obj);
1464 \qmlclass LayoutMirroring QQuickLayoutMirroringAttached
1465 \inqmlmodule QtQuick 2
1466 \ingroup qtquick-positioners
1467 \ingroup qml-utility-elements
1468 \brief Property used to mirror layout behavior
1470 The LayoutMirroring attached property is used to horizontally mirror \l {anchor-layout}{Item anchors},
1471 \l{Using QML Positioner and Repeater Items}{positioner} elements (such as \l Row and \l Grid)
1472 and views (such as \l GridView and horizontal \l ListView). Mirroring is a visual change: left
1473 anchors become right anchors, and positioner elements like \l Grid and \l Row reverse the
1474 horizontal layout of child items.
1476 Mirroring is enabled for an item by setting the \l enabled property to true. By default, this
1477 only affects the item itself; setting the \l childrenInherit property to true propagates the mirroring
1478 behavior to all child elements as well. If the \c LayoutMirroring attached property has not been defined
1479 for an item, mirroring is not enabled.
1481 The following example shows mirroring in action. The \l Row below is specified as being anchored
1482 to the left of its parent. However, since mirroring has been enabled, the anchor is horizontally
1483 reversed and it is now anchored to the right. Also, since items in a \l Row are positioned
1484 from left to right by default, they are now positioned from right to left instead, as demonstrated
1485 by the numbering and opacity of the items:
1487 \snippet qml/layoutmirroring.qml 0
1489 \image layoutmirroring.png
1491 Layout mirroring is useful when it is necessary to support both left-to-right and right-to-left
1492 layout versions of an application to target different language areas. The \l childrenInherit
1493 property allows layout mirroring to be applied without manually setting layout configurations
1494 for every item in an application. Keep in mind, however, that mirroring does not affect any
1495 positioning that is defined by the \l Item \l {Item::}{x} coordinate value, so even with
1496 mirroring enabled, it will often be necessary to apply some layout fixes to support the
1497 desired layout direction. Also, it may be necessary to disable the mirroring of individual
1498 child items (by setting \l {enabled}{LayoutMirroring.enabled} to false for such items) if
1499 mirroring is not the desired behavior, or if the child item already implements mirroring in
1502 See \l {QML Right-to-left User Interfaces} for further details on using \c LayoutMirroring and
1503 other related features to implement right-to-left support for an application.
1507 \qmlproperty bool QtQuick2::LayoutMirroring::enabled
1509 This property holds whether the item's layout is mirrored horizontally. Setting this to true
1510 horizontally reverses \l {anchor-layout}{anchor} settings such that left anchors become right,
1511 and right anchors become left. For \l{Using QML Positioner and Repeater Items}{positioner} elements
1512 (such as \l Row and \l Grid) and view elements (such as \l {GridView}{GridView} and \l {ListView}{ListView})
1513 this also mirrors the horizontal layout direction of the item.
1515 The default value is false.
1519 \qmlproperty bool QtQuick2::LayoutMirroring::childrenInherit
1521 This property holds whether the \l {enabled}{LayoutMirroring.enabled} value for this item
1522 is inherited by its children.
1524 The default value is false.
1528 QQuickLayoutMirroringAttached::QQuickLayoutMirroringAttached(QObject *parent) : QObject(parent), itemPrivate(0)
1530 if (QQuickItem *item = qobject_cast<QQuickItem*>(parent)) {
1531 itemPrivate = QQuickItemPrivate::get(item);
1532 itemPrivate->extra.value().layoutDirectionAttached = this;
1534 qmlInfo(parent) << tr("LayoutDirection attached property only works with Items");
1537 QQuickLayoutMirroringAttached * QQuickLayoutMirroringAttached::qmlAttachedProperties(QObject *object)
1539 return new QQuickLayoutMirroringAttached(object);
1542 bool QQuickLayoutMirroringAttached::enabled() const
1544 return itemPrivate ? itemPrivate->effectiveLayoutMirror : false;
1547 void QQuickLayoutMirroringAttached::setEnabled(bool enabled)
1552 itemPrivate->isMirrorImplicit = false;
1553 if (enabled != itemPrivate->effectiveLayoutMirror) {
1554 itemPrivate->setLayoutMirror(enabled);
1555 if (itemPrivate->inheritMirrorFromItem)
1556 itemPrivate->resolveLayoutMirror();
1560 void QQuickLayoutMirroringAttached::resetEnabled()
1562 if (itemPrivate && !itemPrivate->isMirrorImplicit) {
1563 itemPrivate->isMirrorImplicit = true;
1564 itemPrivate->resolveLayoutMirror();
1568 bool QQuickLayoutMirroringAttached::childrenInherit() const
1570 return itemPrivate ? itemPrivate->inheritMirrorFromItem : false;
1573 void QQuickLayoutMirroringAttached::setChildrenInherit(bool childrenInherit) {
1574 if (itemPrivate && childrenInherit != itemPrivate->inheritMirrorFromItem) {
1575 itemPrivate->inheritMirrorFromItem = childrenInherit;
1576 itemPrivate->resolveLayoutMirror();
1577 childrenInheritChanged();
1581 void QQuickItemPrivate::resolveLayoutMirror()
1584 if (QQuickItem *parentItem = q->parentItem()) {
1585 QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(parentItem);
1586 setImplicitLayoutMirror(parentPrivate->inheritedLayoutMirror, parentPrivate->inheritMirrorFromParent);
1588 setImplicitLayoutMirror(isMirrorImplicit ? false : effectiveLayoutMirror, inheritMirrorFromItem);
1592 void QQuickItemPrivate::setImplicitLayoutMirror(bool mirror, bool inherit)
1594 inherit = inherit || inheritMirrorFromItem;
1595 if (!isMirrorImplicit && inheritMirrorFromItem)
1596 mirror = effectiveLayoutMirror;
1597 if (mirror == inheritedLayoutMirror && inherit == inheritMirrorFromParent)
1600 inheritMirrorFromParent = inherit;
1601 inheritedLayoutMirror = inheritMirrorFromParent ? mirror : false;
1603 if (isMirrorImplicit)
1604 setLayoutMirror(inherit ? inheritedLayoutMirror : false);
1605 for (int i = 0; i < childItems.count(); ++i) {
1606 if (QQuickItem *child = qmlobject_cast<QQuickItem *>(childItems.at(i))) {
1607 QQuickItemPrivate *childPrivate = QQuickItemPrivate::get(child);
1608 childPrivate->setImplicitLayoutMirror(inheritedLayoutMirror, inheritMirrorFromParent);
1613 void QQuickItemPrivate::setLayoutMirror(bool mirror)
1615 if (mirror != effectiveLayoutMirror) {
1616 effectiveLayoutMirror = mirror;
1618 QQuickAnchorsPrivate *anchor_d = QQuickAnchorsPrivate::get(_anchors);
1619 anchor_d->fillChanged();
1620 anchor_d->centerInChanged();
1621 anchor_d->updateHorizontalAnchors();
1622 emit _anchors->mirroredChanged();
1625 if (extra.isAllocated() && extra->layoutDirectionAttached) {
1626 emit extra->layoutDirectionAttached->enabledChanged();
1631 void QQuickItemPrivate::setAccessibleFlagAndListener()
1634 QQuickItem *item = q;
1636 if (item->d_func()->isAccessible)
1637 break; // already set - grandparents should have the flag set as well.
1639 item->d_func()->isAccessible = true;
1640 item = item->d_func()->parentItem;
1644 void QQuickItemPrivate::updateSubFocusItem(QQuickItem *scope, bool focus)
1649 QQuickItemPrivate *scopePrivate = QQuickItemPrivate::get(scope);
1651 QQuickItem *oldSubFocusItem = scopePrivate->subFocusItem;
1652 // Correct focus chain in scope
1653 if (oldSubFocusItem) {
1654 QQuickItem *sfi = scopePrivate->subFocusItem->parentItem();
1655 while (sfi && sfi != scope) {
1656 QQuickItemPrivate::get(sfi)->subFocusItem = 0;
1657 sfi = sfi->parentItem();
1662 scopePrivate->subFocusItem = q;
1663 QQuickItem *sfi = scopePrivate->subFocusItem->parentItem();
1664 while (sfi && sfi != scope) {
1665 QQuickItemPrivate::get(sfi)->subFocusItem = q;
1666 sfi = sfi->parentItem();
1669 scopePrivate->subFocusItem = 0;
1676 \brief The QQuickItem class provides the most basic of all visual items in QML
1680 All visual items in Qt Quick inherit from QQuickItem. Although QQuickItem
1681 has no visual appearance, it defines all the properties that are
1682 common across visual items - such as the x and y position, the
1683 width and height, \l {anchor-layout}{anchoring} and key handling.
1685 You can subclass QQuickItem to provide your own custom visual item
1686 that inherits these features.
1688 \section1 Custom Items using Scene Graph
1690 All visual QML items are rendered using the scene graph, a
1691 low-level, high-performance rendering stack, closely tied to
1692 OpenGL. It is possible for subclasses of QQuickItem to add their
1693 own custom content into the scene graph by setting the
1694 QQuickItem::ItemHasContents flag and reimplementing the
1695 QQuickItem::updatePaintNode() function.
1697 \warning It is crucial that OpenGL operations and interaction with
1698 the scene graph happens exclusively on the rendering thread,
1699 primarily during the updatePaintNode() call. The best rule of
1700 thumb is to only use classes with the "QSG" prefix inside the
1701 QQuickItem::updatePaintNode() function.
1703 To read more about how the scene graph rendering works, see
1704 \l{Scene Graph and Rendering}
1706 \section1 Custom Items using QPainter
1708 The QQuickItem provides a subclass, QQuickPaintedItem, which
1709 allows the users to render content using QPainter.
1711 \warning Using QQuickPaintedItem uses an indirect 2D surface to
1712 render its content, either using software rasterization or using
1713 an OpenGL framebuffer object (FBO), so the rendering is a two-step
1714 operation. First rasterize the surface, then draw the
1715 surface. Using scene graph API directly is always significantly
1718 \sa QQuickCanvas, QQuickPaintedItem
1722 \qmlclass Item QQuickItem
1724 \inqmlmodule QtQuick 2
1725 \ingroup qtquick-visual
1726 \brief A basic visual QML type
1728 All visual items in Qt Quick inherit from Item. Although Item
1729 has no visual appearance, it defines all the properties that are
1730 common across visual items - such as the x and y position, the
1731 width and height, \l {anchor-layout}{anchoring} and key handling.
1733 Item is also useful for grouping items together.
1750 fillMode: Image.Tile
1757 \section1 Key Handling
1759 Key handling is available to all Item-based visual elements via the \l {Keys}{Keys}
1760 attached property. The \e Keys attached property provides basic handlers such
1761 as \l {Keys::onPressed}{onPressed} and \l {Keys::onReleased}{onReleased},
1762 as well as handlers for specific keys, such as
1763 \l {Keys::onCancelPressed}{onCancelPressed}. The example below
1764 assigns \l {qmlfocus}{focus} to the item and handles
1765 the Left key via the general \e onPressed handler and the Select key via the
1766 onSelectPressed handler:
1772 if (event.key == Qt.Key_Left) {
1773 console.log("move left");
1774 event.accepted = true;
1777 Keys.onSelectPressed: console.log("Selected");
1781 See the \l {Keys}{Keys} attached property for detailed documentation.
1783 \section1 Layout Mirroring
1785 Item layouts can be mirrored using the \l {LayoutMirroring}{LayoutMirroring} attached property.
1790 \fn void QQuickItem::childrenRectChanged(const QRectF &)
1795 \fn void QQuickItem::baselineOffsetChanged(qreal)
1800 \fn void QQuickItem::stateChanged(const QString &state)
1805 \fn void QQuickItem::parentChanged(QQuickItem *)
1810 \fn void QQuickItem::smoothChanged(bool)
1815 \fn void QQuickItem::clipChanged(bool)
1819 /*! \fn void QQuickItem::transformOriginChanged(TransformOrigin)
1824 \fn void QQuickItem::focusChanged(bool)
1829 \fn void QQuickItem::activeFocusChanged(bool)
1833 \fn QQuickItem::QQuickItem(QQuickItem *parent)
1835 Constructs a QQuickItem with the given \a parent.
1837 QQuickItem::QQuickItem(QQuickItem* parent)
1838 : QObject(*(new QQuickItemPrivate), parent)
1846 QQuickItem::QQuickItem(QQuickItemPrivate &dd, QQuickItem *parent)
1847 : QObject(dd, parent)
1854 static int qt_item_count = 0;
1856 static void qt_print_item_count()
1858 qDebug("Number of leaked items: %i", qt_item_count);
1864 Destroys the QQuickItem.
1866 QQuickItem::~QQuickItem()
1870 if (qt_item_count < 0)
1871 qDebug("Item destroyed after qt_print_item_count() was called.");
1876 if (d->canvasRefCount > 1)
1877 d->canvasRefCount = 1; // Make sure canvas is set to null in next call to derefCanvas().
1883 // XXX todo - optimize
1884 while (!d->childItems.isEmpty())
1885 d->childItems.first()->setParentItem(0);
1887 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
1888 QQuickAnchorsPrivate *anchor = d->changeListeners.at(ii).listener->anchorPrivate();
1890 anchor->clearItem(this);
1894 update item anchors that depended on us unless they are our child (and will also be destroyed),
1895 or our sibling, and our parent is also being destroyed.
1897 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
1898 QQuickAnchorsPrivate *anchor = d->changeListeners.at(ii).listener->anchorPrivate();
1899 if (anchor && anchor->item && anchor->item->parentItem() && anchor->item->parentItem() != this)
1903 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
1904 const QQuickItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
1905 if (change.types & QQuickItemPrivate::Destroyed)
1906 change.listener->itemDestroyed(this);
1909 d->changeListeners.clear();
1911 if (d->extra.isAllocated()) {
1912 delete d->extra->contents; d->extra->contents = 0;
1913 delete d->extra->layer; d->extra->layer = 0;
1916 delete d->_anchors; d->_anchors = 0;
1917 delete d->_stateGroup; d->_stateGroup = 0;
1921 \qmlproperty enumeration QtQuick2::Item::transformOrigin
1922 This property holds the origin point around which scale and rotation transform.
1924 Nine transform origins are available, as shown in the image below.
1926 \image declarative-transformorigin.png
1928 This example rotates an image around its bottom-right corner.
1931 source: "myimage.png"
1932 transformOrigin: Item.BottomRight
1937 The default transform origin is \c Item.Center.
1939 To set an arbitrary transform origin point use the \l Scale or \l Rotation
1944 \qmlproperty Item QtQuick2::Item::parent
1945 This property holds the parent of the item.
1949 \property QQuickItem::parent
1950 This property holds the parent of the item.
1952 void QQuickItem::setParentItem(QQuickItem *parentItem)
1955 if (parentItem == d->parentItem)
1959 QQuickItem *itemAncestor = parentItem->parentItem();
1960 while (itemAncestor != 0) {
1961 if (itemAncestor == this) {
1962 qWarning("QQuickItem::setParentItem: Parent is already part of this items subtree.");
1965 itemAncestor = itemAncestor->parentItem();
1969 d->removeFromDirtyList();
1971 QQuickItem *oldParentItem = d->parentItem;
1972 QQuickItem *scopeFocusedItem = 0;
1974 if (oldParentItem) {
1975 QQuickItemPrivate *op = QQuickItemPrivate::get(oldParentItem);
1977 QQuickItem *scopeItem = 0;
1980 scopeFocusedItem = this;
1981 else if (!isFocusScope() && d->subFocusItem)
1982 scopeFocusedItem = d->subFocusItem;
1984 if (scopeFocusedItem) {
1985 scopeItem = oldParentItem;
1986 while (!scopeItem->isFocusScope() && scopeItem->parentItem())
1987 scopeItem = scopeItem->parentItem();
1989 QQuickCanvasPrivate::get(d->canvas)->clearFocusInScope(scopeItem, scopeFocusedItem,
1990 QQuickCanvasPrivate::DontChangeFocusProperty);
1991 if (scopeFocusedItem != this)
1992 QQuickItemPrivate::get(scopeFocusedItem)->updateSubFocusItem(this, true);
1994 QQuickItemPrivate::get(scopeFocusedItem)->updateSubFocusItem(scopeItem, false);
1998 const bool wasVisible = isVisible();
1999 op->removeChild(this);
2001 emit oldParentItem->visibleChildrenChanged();
2003 } else if (d->canvas) {
2004 QQuickCanvasPrivate::get(d->canvas)->parentlessItems.remove(this);
2007 QQuickCanvas *oldParentCanvas = oldParentItem ? QQuickItemPrivate::get(oldParentItem)->canvas : 0;
2008 QQuickCanvas *parentCanvas = parentItem ? QQuickItemPrivate::get(parentItem)->canvas : 0;
2009 if (oldParentCanvas == parentCanvas) {
2010 // Avoid freeing and reallocating resources if the canvas stays the same.
2011 d->parentItem = parentItem;
2013 if (oldParentCanvas)
2015 d->parentItem = parentItem;
2017 d->refCanvas(parentCanvas);
2020 d->dirty(QQuickItemPrivate::ParentChanged);
2023 QQuickItemPrivate::get(d->parentItem)->addChild(this);
2025 QQuickCanvasPrivate::get(d->canvas)->parentlessItems.insert(this);
2027 d->setEffectiveVisibleRecur(d->calcEffectiveVisible());
2028 d->setEffectiveEnableRecur(0, d->calcEffectiveEnable());
2030 if (d->parentItem) {
2031 if (!scopeFocusedItem) {
2033 scopeFocusedItem = this;
2034 else if (!isFocusScope() && d->subFocusItem)
2035 scopeFocusedItem = d->subFocusItem;
2038 if (scopeFocusedItem) {
2039 // We need to test whether this item becomes scope focused
2040 QQuickItem *scopeItem = d->parentItem;
2041 while (!scopeItem->isFocusScope() && scopeItem->parentItem())
2042 scopeItem = scopeItem->parentItem();
2044 if (QQuickItemPrivate::get(scopeItem)->subFocusItem
2045 || (!scopeItem->isFocusScope() && scopeItem->hasFocus())) {
2046 if (scopeFocusedItem != this)
2047 QQuickItemPrivate::get(scopeFocusedItem)->updateSubFocusItem(this, false);
2048 QQuickItemPrivate::get(scopeFocusedItem)->focus = false;
2049 emit scopeFocusedItem->focusChanged(false);
2052 QQuickCanvasPrivate::get(d->canvas)->setFocusInScope(scopeItem, scopeFocusedItem,
2053 QQuickCanvasPrivate::DontChangeFocusProperty);
2055 QQuickItemPrivate::get(scopeFocusedItem)->updateSubFocusItem(scopeItem, true);
2061 d->resolveLayoutMirror();
2063 d->itemChange(ItemParentHasChanged, d->parentItem);
2065 d->parentNotifier.notify();
2066 if (d->isAccessible && d->parentItem) {
2067 d->parentItem->d_func()->setAccessibleFlagAndListener();
2070 emit parentChanged(d->parentItem);
2071 if (isVisible() && d->parentItem)
2072 emit d->parentItem->visibleChildrenChanged();
2075 void QQuickItem::stackBefore(const QQuickItem *sibling)
2078 if (!sibling || sibling == this || !d->parentItem || d->parentItem != QQuickItemPrivate::get(sibling)->parentItem) {
2079 qWarning("QQuickItem::stackBefore: Cannot stack before %p, which must be a sibling", sibling);
2083 QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(d->parentItem);
2085 int myIndex = parentPrivate->childItems.lastIndexOf(this);
2086 int siblingIndex = parentPrivate->childItems.lastIndexOf(const_cast<QQuickItem *>(sibling));
2088 Q_ASSERT(myIndex != -1 && siblingIndex != -1);
2090 if (myIndex == siblingIndex - 1)
2093 parentPrivate->childItems.move(myIndex, myIndex < siblingIndex ? siblingIndex - 1 : siblingIndex);
2095 parentPrivate->dirty(QQuickItemPrivate::ChildrenStackingChanged);
2096 parentPrivate->markSortedChildrenDirty(this);
2098 for (int ii = qMin(siblingIndex, myIndex); ii < parentPrivate->childItems.count(); ++ii)
2099 QQuickItemPrivate::get(parentPrivate->childItems.at(ii))->siblingOrderChanged();
2102 void QQuickItem::stackAfter(const QQuickItem *sibling)
2105 if (!sibling || sibling == this || !d->parentItem || d->parentItem != QQuickItemPrivate::get(sibling)->parentItem) {
2106 qWarning("QQuickItem::stackAfter: Cannot stack after %p, which must be a sibling", sibling);
2110 QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(d->parentItem);
2112 int myIndex = parentPrivate->childItems.lastIndexOf(this);
2113 int siblingIndex = parentPrivate->childItems.lastIndexOf(const_cast<QQuickItem *>(sibling));
2115 Q_ASSERT(myIndex != -1 && siblingIndex != -1);
2117 if (myIndex == siblingIndex + 1)
2120 parentPrivate->childItems.move(myIndex, myIndex > siblingIndex ? siblingIndex + 1 : siblingIndex);
2122 parentPrivate->dirty(QQuickItemPrivate::ChildrenStackingChanged);
2123 parentPrivate->markSortedChildrenDirty(this);
2125 for (int ii = qMin(myIndex, siblingIndex + 1); ii < parentPrivate->childItems.count(); ++ii)
2126 QQuickItemPrivate::get(parentPrivate->childItems.at(ii))->siblingOrderChanged();
2130 Returns the QQuickItem parent of this item.
2132 QQuickItem *QQuickItem::parentItem() const
2134 Q_D(const QQuickItem);
2135 return d->parentItem;
2138 QQuickCanvas *QQuickItem::canvas() const
2140 Q_D(const QQuickItem);
2144 static bool itemZOrder_sort(QQuickItem *lhs, QQuickItem *rhs)
2146 return lhs->z() < rhs->z();
2149 QList<QQuickItem *> QQuickItemPrivate::paintOrderChildItems() const
2151 if (sortedChildItems)
2152 return *sortedChildItems;
2154 // If none of the items have set Z then the paint order list is the same as
2155 // the childItems list. This is by far the most common case.
2157 for (int i = 0; i < childItems.count(); ++i) {
2158 if (QQuickItemPrivate::get(childItems.at(i))->z() != 0.) {
2164 sortedChildItems = new QList<QQuickItem*>(childItems);
2165 qStableSort(sortedChildItems->begin(), sortedChildItems->end(), itemZOrder_sort);
2166 return *sortedChildItems;
2169 sortedChildItems = const_cast<QList<QQuickItem*>*>(&childItems);
2174 void QQuickItemPrivate::addChild(QQuickItem *child)
2178 Q_ASSERT(!childItems.contains(child));
2180 childItems.append(child);
2182 markSortedChildrenDirty(child);
2183 dirty(QQuickItemPrivate::ChildrenChanged);
2185 itemChange(QQuickItem::ItemChildAddedChange, child);
2187 emit q->childrenChanged();
2190 void QQuickItemPrivate::removeChild(QQuickItem *child)
2195 Q_ASSERT(childItems.contains(child));
2196 childItems.removeOne(child);
2197 Q_ASSERT(!childItems.contains(child));
2199 markSortedChildrenDirty(child);
2200 dirty(QQuickItemPrivate::ChildrenChanged);
2202 itemChange(QQuickItem::ItemChildRemovedChange, child);
2204 emit q->childrenChanged();
2207 void QQuickItemPrivate::InitializationState::clear()
2212 void QQuickItemPrivate::InitializationState::clear(QQuickItem *fs)
2217 QQuickItem *QQuickItemPrivate::InitializationState::getFocusScope(QQuickItem *item)
2220 QQuickItem *fs = item->parentItem();
2221 while (fs->parentItem() && !fs->isFocusScope())
2222 fs = fs->parentItem();
2228 void QQuickItemPrivate::refCanvas(InitializationState *state, QQuickCanvas *c)
2230 // An item needs a canvas if it is referenced by another item which has a canvas.
2231 // Typically the item is referenced by a parent, but can also be referenced by a
2232 // ShaderEffect or ShaderEffectSource. 'canvasRefCount' counts how many items with
2233 // a canvas is referencing this item. When the reference count goes from zero to one,
2234 // or one to zero, the canvas of this item is updated and propagated to the children.
2235 // As long as the reference count stays above zero, the canvas is unchanged.
2236 // refCanvas() increments the reference count.
2237 // derefCanvas() decrements the reference count.
2240 Q_ASSERT((canvas != 0) == (canvasRefCount > 0));
2242 if (++canvasRefCount > 1) {
2244 qWarning("QQuickItem: Cannot use same item on different canvases at the same time.");
2245 return; // Canvas already set.
2248 Q_ASSERT(canvas == 0);
2251 if (polishScheduled)
2252 QQuickCanvasPrivate::get(canvas)->itemsToPolish.insert(q);
2254 InitializationState _dummy;
2255 InitializationState *childState = state;
2257 if (q->isFocusScope()) {
2259 childState = &_dummy;
2263 QQuickCanvasPrivate::get(canvas)->parentlessItems.insert(q);
2265 for (int ii = 0; ii < childItems.count(); ++ii) {
2266 QQuickItem *child = childItems.at(ii);
2267 QQuickItemPrivate::get(child)->refCanvas(childState, c);
2272 if (extra.isAllocated() && extra->screenAttached)
2273 extra->screenAttached->canvasChanged(c);
2274 itemChange(QQuickItem::ItemSceneChange, c);
2277 void QQuickItemPrivate::derefCanvas()
2280 Q_ASSERT((canvas != 0) == (canvasRefCount > 0));
2283 return; // This can happen when destroying recursive shader effect sources.
2285 if (--canvasRefCount > 0)
2286 return; // There are still other references, so don't set canvas to null yet.
2288 q->releaseResources();
2289 removeFromDirtyList();
2290 QQuickCanvasPrivate *c = QQuickCanvasPrivate::get(canvas);
2291 if (polishScheduled)
2292 c->itemsToPolish.remove(q);
2293 QMutableHashIterator<int, QQuickItem *> itemTouchMapIt(c->itemForTouchPointId);
2294 while (itemTouchMapIt.hasNext()) {
2295 if (itemTouchMapIt.next().value() == q)
2296 itemTouchMapIt.remove();
2298 if (c->mouseGrabberItem == q)
2299 c->mouseGrabberItem = 0;
2301 c->hoverItems.removeAll(q);
2302 if (itemNodeInstance)
2303 c->cleanup(itemNodeInstance);
2305 c->parentlessItems.remove(q);
2309 itemNodeInstance = 0;
2311 if (extra.isAllocated()) {
2312 extra->opacityNode = 0;
2313 extra->clipNode = 0;
2314 extra->rootNode = 0;
2315 extra->beforePaintNode = 0;
2321 for (int ii = 0; ii < childItems.count(); ++ii) {
2322 QQuickItem *child = childItems.at(ii);
2323 QQuickItemPrivate::get(child)->derefCanvas();
2328 if (extra.isAllocated() && extra->screenAttached)
2329 extra->screenAttached->canvasChanged(0);
2330 itemChange(QQuickItem::ItemSceneChange, (QQuickCanvas *)0);
2335 Returns a transform that maps points from canvas space into item space.
2337 QTransform QQuickItemPrivate::canvasToItemTransform() const
2339 // XXX todo - optimize
2340 return itemToCanvasTransform().inverted();
2344 Returns a transform that maps points from item space into canvas space.
2346 QTransform QQuickItemPrivate::itemToCanvasTransform() const
2349 QTransform rv = parentItem?QQuickItemPrivate::get(parentItem)->itemToCanvasTransform():QTransform();
2350 itemToParentTransform(rv);
2355 Motifies \a t with this items local transform relative to its parent.
2357 void QQuickItemPrivate::itemToParentTransform(QTransform &t) const
2362 if (!transforms.isEmpty()) {
2364 for (int ii = transforms.count() - 1; ii >= 0; --ii)
2365 transforms.at(ii)->applyTo(&m);
2366 t = m.toTransform();
2369 if (scale() != 1. || rotation() != 0.) {
2370 QPointF tp = computeTransformOrigin();
2371 t.translate(tp.x(), tp.y());
2372 t.scale(scale(), scale());
2373 t.rotate(rotation());
2374 t.translate(-tp.x(), -tp.y());
2380 \qmlproperty real QtQuick2::Item::childrenRect.x
2381 \qmlproperty real QtQuick2::Item::childrenRect.y
2382 \qmlproperty real QtQuick2::Item::childrenRect.width
2383 \qmlproperty real QtQuick2::Item::childrenRect.height
2385 The childrenRect properties allow an item access to the geometry of its
2386 children. This property is useful if you have an item that needs to be
2387 sized to fit its children.
2392 \qmlproperty list<Item> QtQuick2::Item::children
2393 \qmlproperty list<Object> QtQuick2::Item::resources
2395 The children property contains the list of visual children of this item.
2396 The resources property contains non-visual resources that you want to
2399 Generally you can rely on Item's default property to handle all this for
2400 you, but it can come in handy in some cases.
2419 Returns true if construction of the QML component is complete; otherwise
2422 It is often desirable to delay some processing until the component is
2425 \sa componentComplete()
2427 bool QQuickItem::isComponentComplete() const
2429 Q_D(const QQuickItem);
2430 return d->componentComplete;
2433 QQuickItemPrivate::QQuickItemPrivate()
2434 : _anchors(0), _stateGroup(0),
2435 flags(0), widthValid(false), heightValid(false), baselineOffsetValid(false), componentComplete(true),
2436 keepMouse(false), keepTouch(false), hoverEnabled(false), smooth(true), focus(false), activeFocus(false), notifiedFocus(false),
2437 notifiedActiveFocus(false), filtersChildMouseEvents(false), explicitVisible(true),
2438 effectiveVisible(true), explicitEnable(true), effectiveEnable(true), polishScheduled(false),
2439 inheritedLayoutMirror(false), effectiveLayoutMirror(false), isMirrorImplicit(true),
2440 inheritMirrorFromParent(false), inheritMirrorFromItem(false),
2441 isAccessible(false), culled(false),
2443 dirtyAttributes(0), nextDirtyItem(0), prevDirtyItem(0),
2445 canvas(0), canvasRefCount(0), parentItem(0), sortedChildItems(&childItems),
2449 x(0), y(0), width(0), height(0), implicitWidth(0), implicitHeight(0),
2453 itemNodeInstance(0), groupNode(0), paintNode(0)
2457 QQuickItemPrivate::~QQuickItemPrivate()
2459 if (sortedChildItems != &childItems)
2460 delete sortedChildItems;
2463 void QQuickItemPrivate::init(QQuickItem *parent)
2467 static bool atexit_registered = false;
2468 if (!atexit_registered) {
2469 atexit(qt_print_item_count);
2470 atexit_registered = true;
2476 registerAccessorProperties();
2478 baselineOffsetValid = false;
2481 q->setParentItem(parent);
2482 QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(parent);
2483 setImplicitLayoutMirror(parentPrivate->inheritedLayoutMirror, parentPrivate->inheritMirrorFromParent);
2487 void QQuickItemPrivate::data_append(QQmlListProperty<QObject> *prop, QObject *o)
2492 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2494 if (QQuickItem *item = qmlobject_cast<QQuickItem *>(o)) {
2495 item->setParentItem(that);
2497 if (o->inherits("QGraphicsItem"))
2498 qWarning("Cannot add a QtQuick 1.0 item (%s) into a QtQuick 2.0 scene!", o->metaObject()->className());
2500 // XXX todo - do we really want this behavior?
2506 \qmlproperty list<Object> QtQuick2::Item::data
2509 The data property allows you to freely mix visual children and resources
2510 in an item. If you assign a visual item to the data list it becomes
2511 a child and if you assign any other object type, it is added as a resource.
2535 data is a behind-the-scenes property: you should never need to explicitly
2539 int QQuickItemPrivate::data_count(QQmlListProperty<QObject> *prop)
2546 QObject *QQuickItemPrivate::data_at(QQmlListProperty<QObject> *prop, int i)
2554 void QQuickItemPrivate::data_clear(QQmlListProperty<QObject> *prop)
2560 QObject *QQuickItemPrivate::resources_at(QQmlListProperty<QObject> *prop, int index)
2562 const QObjectList children = prop->object->children();
2563 if (index < children.count())
2564 return children.at(index);
2569 void QQuickItemPrivate::resources_append(QQmlListProperty<QObject> *prop, QObject *o)
2571 // XXX todo - do we really want this behavior?
2572 o->setParent(prop->object);
2575 int QQuickItemPrivate::resources_count(QQmlListProperty<QObject> *prop)
2577 return prop->object->children().count();
2580 void QQuickItemPrivate::resources_clear(QQmlListProperty<QObject> *prop)
2582 // XXX todo - do we really want this behavior?
2583 const QObjectList children = prop->object->children();
2584 for (int index = 0; index < children.count(); index++)
2585 children.at(index)->setParent(0);
2588 QQuickItem *QQuickItemPrivate::children_at(QQmlListProperty<QQuickItem> *prop, int index)
2590 QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2591 if (index >= p->childItems.count() || index < 0)
2594 return p->childItems.at(index);
2597 void QQuickItemPrivate::children_append(QQmlListProperty<QQuickItem> *prop, QQuickItem *o)
2602 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2603 if (o->parentItem() == that)
2604 o->setParentItem(0);
2606 o->setParentItem(that);
2609 int QQuickItemPrivate::children_count(QQmlListProperty<QQuickItem> *prop)
2611 QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2612 return p->childItems.count();
2615 void QQuickItemPrivate::children_clear(QQmlListProperty<QQuickItem> *prop)
2617 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2618 QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2619 while (!p->childItems.isEmpty())
2620 p->childItems.at(0)->setParentItem(0);
2623 void QQuickItemPrivate::visibleChildren_append(QQmlListProperty<QQuickItem>*, QQuickItem *self)
2626 qmlInfo(self) << "QQuickItem: visibleChildren property is readonly and cannot be assigned to.";
2629 int QQuickItemPrivate::visibleChildren_count(QQmlListProperty<QQuickItem> *prop)
2631 QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2632 int visibleCount = 0;
2633 int c = p->childItems.count();
2635 if (p->childItems.at(c)->isVisible()) visibleCount++;
2638 return visibleCount;
2641 QQuickItem *QQuickItemPrivate::visibleChildren_at(QQmlListProperty<QQuickItem> *prop, int index)
2643 QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2644 const int childCount = p->childItems.count();
2645 if (index >= childCount || index < 0)
2648 int visibleCount = -1;
2649 for (int i = 0; i < childCount; i++) {
2650 if (p->childItems.at(i)->isVisible()) visibleCount++;
2651 if (visibleCount == index) return p->childItems.at(i);
2656 int QQuickItemPrivate::transform_count(QQmlListProperty<QQuickTransform> *prop)
2658 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2659 QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2661 return p->transforms.count();
2664 void QQuickTransform::appendToItem(QQuickItem *item)
2666 Q_D(QQuickTransform);
2670 QQuickItemPrivate *p = QQuickItemPrivate::get(item);
2672 if (!d->items.isEmpty() && !p->transforms.isEmpty() && p->transforms.contains(this)) {
2673 p->transforms.removeOne(this);
2674 p->transforms.append(this);
2676 p->transforms.append(this);
2677 d->items.append(item);
2680 p->dirty(QQuickItemPrivate::Transform);
2683 void QQuickTransform::prependToItem(QQuickItem *item)
2685 Q_D(QQuickTransform);
2689 QQuickItemPrivate *p = QQuickItemPrivate::get(item);
2691 if (!d->items.isEmpty() && !p->transforms.isEmpty() && p->transforms.contains(this)) {
2692 p->transforms.removeOne(this);
2693 p->transforms.prepend(this);
2695 p->transforms.prepend(this);
2696 d->items.append(item);
2699 p->dirty(QQuickItemPrivate::Transform);
2702 void QQuickItemPrivate::transform_append(QQmlListProperty<QQuickTransform> *prop, QQuickTransform *transform)
2707 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2708 transform->appendToItem(that);
2711 QQuickTransform *QQuickItemPrivate::transform_at(QQmlListProperty<QQuickTransform> *prop, int idx)
2713 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2714 QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2716 if (idx < 0 || idx >= p->transforms.count())
2719 return p->transforms.at(idx);
2722 void QQuickItemPrivate::transform_clear(QQmlListProperty<QQuickTransform> *prop)
2724 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2725 QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2727 for (int ii = 0; ii < p->transforms.count(); ++ii) {
2728 QQuickTransform *t = p->transforms.at(ii);
2729 QQuickTransformPrivate *tp = QQuickTransformPrivate::get(t);
2730 tp->items.removeOne(that);
2733 p->transforms.clear();
2735 p->dirty(QQuickItemPrivate::Transform);
2739 \property QQuickItem::childrenRect
2740 \brief Specifies the geometry of an item's children
2742 This property holds the (collective) position and size of the item's children.
2746 \qmlproperty real QtQuick2::Item::x
2747 \qmlproperty real QtQuick2::Item::y
2748 \qmlproperty real QtQuick2::Item::width
2749 \qmlproperty real QtQuick2::Item::height
2751 Defines the item's position and size relative to its parent.
2754 Item { x: 100; y: 100; width: 100; height: 100 }
2759 \qmlproperty real QtQuick2::Item::z
2761 Sets the stacking order of sibling items. By default the stacking order is 0.
2763 Items with a higher stacking value are drawn on top of siblings with a
2764 lower stacking order. Items with the same stacking value are drawn
2765 bottom up in the order they appear. Items with a negative stacking
2766 value are drawn under their parent's content.
2768 The following example shows the various effects of stacking order.
2772 \li \image declarative-item_stacking1.png
2773 \li Same \c z - later children above earlier children:
2778 width: 100; height: 100
2782 x: 50; y: 50; width: 100; height: 100
2787 \li \image declarative-item_stacking2.png
2788 \li Higher \c z on top:
2794 width: 100; height: 100
2798 x: 50; y: 50; width: 100; height: 100
2803 \li \image declarative-item_stacking3.png
2804 \li Same \c z - children above parents:
2809 width: 100; height: 100
2812 x: 50; y: 50; width: 100; height: 100
2818 \li \image declarative-item_stacking4.png
2819 \li Lower \c z below:
2824 width: 100; height: 100
2828 x: 50; y: 50; width: 100; height: 100
2837 \qmlproperty bool QtQuick2::Item::visible
2839 This property holds whether the item is visible. By default this is true.
2841 Setting this property directly affects the \c visible value of child
2842 items. When set to \c false, the \c visible values of all child items also
2843 become \c false. When set to \c true, the \c visible values of child items
2844 are returned to \c true, unless they have explicitly been set to \c false.
2846 (Because of this flow-on behavior, using the \c visible property may not
2847 have the intended effect if a property binding should only respond to
2848 explicit property changes. In such cases it may be better to use the
2849 \l opacity property instead.)
2851 Setting this property to \c false automatically causes \l focus to be set
2852 to \c false, and this item will longer receive mouse and keyboard events.
2853 (In contrast, setting the \l opacity to 0 does not affect the \l focus
2854 property and the receiving of key events.)
2856 \note This property's value is only affected by changes to this property or
2857 the parent's \c visible property. It does not change, for example, if this
2858 item moves off-screen, or if the \l opacity changes to 0.
2863 \qmlproperty AnchorLine QtQuick2::Item::anchors.top
2864 \qmlproperty AnchorLine QtQuick2::Item::anchors.bottom
2865 \qmlproperty AnchorLine QtQuick2::Item::anchors.left
2866 \qmlproperty AnchorLine QtQuick2::Item::anchors.right
2867 \qmlproperty AnchorLine QtQuick2::Item::anchors.horizontalCenter
2868 \qmlproperty AnchorLine QtQuick2::Item::anchors.verticalCenter
2869 \qmlproperty AnchorLine QtQuick2::Item::anchors.baseline
2871 \qmlproperty Item QtQuick2::Item::anchors.fill
2872 \qmlproperty Item QtQuick2::Item::anchors.centerIn
2874 \qmlproperty real QtQuick2::Item::anchors.margins
2875 \qmlproperty real QtQuick2::Item::anchors.topMargin
2876 \qmlproperty real QtQuick2::Item::anchors.bottomMargin
2877 \qmlproperty real QtQuick2::Item::anchors.leftMargin
2878 \qmlproperty real QtQuick2::Item::anchors.rightMargin
2879 \qmlproperty real QtQuick2::Item::anchors.horizontalCenterOffset
2880 \qmlproperty real QtQuick2::Item::anchors.verticalCenterOffset
2881 \qmlproperty real QtQuick2::Item::anchors.baselineOffset
2883 \qmlproperty bool QtQuick2::Item::anchors.mirrored
2884 \qmlproperty bool QtQuick2::Item::anchors.alignWhenCentered
2886 Anchors provide a way to position an item by specifying its
2887 relationship with other items.
2889 Margins apply to top, bottom, left, right, and fill anchors.
2890 The \c anchors.margins property can be used to set all of the various margins at once, to the same value.
2891 Note that margins are anchor-specific and are not applied if an item does not
2894 Offsets apply for horizontal center, vertical center, and baseline anchors.
2898 \li \image declarative-anchors_example.png
2899 \li Text anchored to Image, horizontally centered and vertically below, with a margin.
2908 anchors.horizontalCenter: pic.horizontalCenter
2909 anchors.top: pic.bottom
2910 anchors.topMargin: 5
2916 \li \image declarative-anchors_example2.png
2918 Left of Text anchored to right of Image, with a margin. The y
2919 property of both defaults to 0.
2929 anchors.left: pic.right
2930 anchors.leftMargin: 5
2937 \c anchors.fill provides a convenient way for one item to have the
2938 same geometry as another item, and is equivalent to connecting all
2939 four directional anchors.
2941 To clear an anchor value, set it to \c undefined.
2943 \c anchors.mirrored returns true it the layout has been \l {LayoutMirroring}{mirrored}.
2945 \c anchors.alignWhenCentered (default true) forces centered anchors to align to a
2946 whole pixel, i.e. if the item being centered has an odd width/height the item
2947 will be positioned on a whole pixel rather than being placed on a half-pixel.
2948 This ensures the item is painted crisply. There are cases where this is not
2949 desirable, for example when rotating the item jitters may be apparent as the
2952 \note You can only anchor an item to siblings or a parent.
2954 For more information see \l {anchor-layout}{Anchor Layouts}.
2958 \property QQuickItem::baselineOffset
2959 \brief Speciifies the position of the item's baseline in local coordinates
2961 The baseline of a \l Text item is the imaginary line on which the text
2962 sits. Controls containing text usually set their baseline to the
2963 baseline of their text.
2965 For non-text items, a default baseline offset of 0 is used.
2967 QQuickAnchors *QQuickItemPrivate::anchors() const
2970 Q_Q(const QQuickItem);
2971 _anchors = new QQuickAnchors(const_cast<QQuickItem *>(q));
2972 if (!componentComplete)
2973 _anchors->classBegin();
2978 void QQuickItemPrivate::siblingOrderChanged()
2981 for (int ii = 0; ii < changeListeners.count(); ++ii) {
2982 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
2983 if (change.types & QQuickItemPrivate::SiblingOrder) {
2984 change.listener->itemSiblingOrderChanged(q);
2989 QQmlListProperty<QObject> QQuickItemPrivate::data()
2991 return QQmlListProperty<QObject>(q_func(), 0, QQuickItemPrivate::data_append,
2992 QQuickItemPrivate::data_count,
2993 QQuickItemPrivate::data_at,
2994 QQuickItemPrivate::data_clear);
2997 QRectF QQuickItem::childrenRect()
3000 if (!d->extra.isAllocated() || !d->extra->contents) {
3001 d->extra.value().contents = new QQuickContents(this);
3002 if (d->componentComplete)
3003 d->extra->contents->complete();
3005 return d->extra->contents->rectF();
3008 QList<QQuickItem *> QQuickItem::childItems() const
3010 Q_D(const QQuickItem);
3011 return d->childItems;
3014 bool QQuickItem::clip() const
3016 return flags() & ItemClipsChildrenToShape;
3019 void QQuickItem::setClip(bool c)
3024 setFlag(ItemClipsChildrenToShape, c);
3026 emit clipChanged(c);
3031 This function is called to handle this item's changes in
3032 geometry from \a oldGeometry to \a newGeometry. If the two
3033 geometries are the same, it doesn't do anything.
3035 Derived classes must call the base class method within their implementation.
3037 void QQuickItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
3042 QQuickAnchorsPrivate::get(d->_anchors)->updateMe();
3044 bool xChange = (newGeometry.x() != oldGeometry.x());
3045 bool yChange = (newGeometry.y() != oldGeometry.y());
3046 bool widthChange = (newGeometry.width() != oldGeometry.width());
3047 bool heightChange = (newGeometry.height() != oldGeometry.height());
3049 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
3050 const QQuickItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
3051 if (change.types & QQuickItemPrivate::Geometry) {
3052 if (change.gTypes == QQuickItemPrivate::GeometryChange) {
3053 change.listener->itemGeometryChanged(this, newGeometry, oldGeometry);
3054 } else if ((xChange && (change.gTypes & QQuickItemPrivate::XChange)) ||
3055 (yChange && (change.gTypes & QQuickItemPrivate::YChange)) ||
3056 (widthChange && (change.gTypes & QQuickItemPrivate::WidthChange)) ||
3057 (heightChange && (change.gTypes & QQuickItemPrivate::HeightChange))) {
3058 change.listener->itemGeometryChanged(this, newGeometry, oldGeometry);
3068 emit widthChanged();
3070 emit heightChanged();
3074 Called by the rendering thread, as a result of
3075 QQuickItem::update(), when it is time to sync the state of the QML
3076 objects with the scene graph objects.
3078 The function should return the root of the scene graph subtree for
3079 this item. Most implementations will return a single
3080 QSGGeometryNode containing the visual representation of this item.
3081 \a oldNode is the node that was returned the last time the
3082 function was called.
3085 QSGNode *MyItem::updatePaintNode(QSGNode *node, UpdatePaintNodeData *)
3087 QSGSimpleRectNode *n = static_cast<QSGSimpleRectNode *>(node);
3089 n = new QSGSimpleRectNode();
3090 n->setColor(Qt::red);
3092 n->setRect(boundingRect());
3097 The main thread is blocked while this function is executed so it is safe to read
3098 values from the QQuickItem instance and other objects in the main thread.
3100 If no call to QQuickItem::updatePaintNode() result in actual scene graph
3101 changes, like QSGNode::markDirty() or adding and removing nodes, then
3102 the underlying implementation may decide to not render the scene again as
3103 the visual outcome is identical.
3105 \warning It is crucial that OpenGL operations and interaction with
3106 the scene graph happens exclusively on the rendering thread,
3107 primarily during the QQuickItem::updatePaintNode() call. The best
3108 rule of thumb is to only use classes with the "QSG" prefix inside
3109 the QQuickItem::updatePaintNode() function.
3111 \sa QSGMaterial, QSGSimpleMaterial, QSGGeometryNode, QSGGeometry,
3112 QSGFlatColorMaterial, QSGTextureMaterial, QSGNode::markDirty()
3115 QSGNode *QQuickItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
3122 This function is called when the item's scene graph resources are no longer needed.
3123 It allows items to free its resources, for instance textures, that are not owned by scene graph
3124 nodes. Note that scene graph nodes are managed by QQuickCanvas and should not be deleted by
3125 this function. Scene graph resources are no longer needed when the parent is set to null and
3126 the item is not used by any \l ShaderEffect or \l ShaderEffectSource.
3128 This function is called from the main thread. Therefore, resources used by the scene graph
3129 should not be deleted directly, but by calling \l QObject::deleteLater().
3131 \note The item destructor still needs to free its scene graph resources if not already done.
3134 void QQuickItem::releaseResources()
3138 QSGTransformNode *QQuickItemPrivate::createTransformNode()
3140 return new QSGTransformNode;
3143 void QQuickItem::updatePolish()
3147 void QQuickItemPrivate::addItemChangeListener(QQuickItemChangeListener *listener, ChangeTypes types)
3149 changeListeners.append(ChangeListener(listener, types));
3152 void QQuickItemPrivate::removeItemChangeListener(QQuickItemChangeListener *listener, ChangeTypes types)
3154 ChangeListener change(listener, types);
3155 changeListeners.removeOne(change);
3158 void QQuickItemPrivate::updateOrAddGeometryChangeListener(QQuickItemChangeListener *listener, GeometryChangeTypes types)
3160 ChangeListener change(listener, types);
3161 int index = changeListeners.find(change);
3163 changeListeners[index].gTypes = change.gTypes; //we may have different GeometryChangeTypes
3165 changeListeners.append(change);
3168 void QQuickItemPrivate::updateOrRemoveGeometryChangeListener(QQuickItemChangeListener *listener,
3169 GeometryChangeTypes types)
3171 ChangeListener change(listener, types);
3172 if (types == NoChange) {
3173 changeListeners.removeOne(change);
3175 int index = changeListeners.find(change);
3177 changeListeners[index].gTypes = change.gTypes; //we may have different GeometryChangeTypes
3181 void QQuickItem::keyPressEvent(QKeyEvent *event)
3186 void QQuickItem::keyReleaseEvent(QKeyEvent *event)
3191 void QQuickItem::inputMethodEvent(QInputMethodEvent *event)
3196 void QQuickItem::focusInEvent(QFocusEvent *)
3198 #ifndef QT_NO_ACCESSIBILITY
3199 QAccessibleEvent ev(this, QAccessible::Focus);
3200 QAccessible::updateAccessibility(&ev);
3204 void QQuickItem::focusOutEvent(QFocusEvent *)
3208 void QQuickItem::mousePressEvent(QMouseEvent *event)
3213 void QQuickItem::mouseMoveEvent(QMouseEvent *event)
3218 void QQuickItem::mouseReleaseEvent(QMouseEvent *event)
3223 void QQuickItem::mouseDoubleClickEvent(QMouseEvent *)
3227 void QQuickItem::mouseUngrabEvent()
3232 void QQuickItem::touchUngrabEvent()
3237 void QQuickItem::wheelEvent(QWheelEvent *event)
3242 void QQuickItem::touchEvent(QTouchEvent *event)
3247 void QQuickItem::hoverEnterEvent(QHoverEvent *event)
3252 void QQuickItem::hoverMoveEvent(QHoverEvent *event)
3257 void QQuickItem::hoverLeaveEvent(QHoverEvent *event)
3262 #ifndef QT_NO_DRAGANDDROP
3263 void QQuickItem::dragEnterEvent(QDragEnterEvent *event)
3268 void QQuickItem::dragMoveEvent(QDragMoveEvent *event)
3274 void QQuickItem::dragLeaveEvent(QDragLeaveEvent *event)
3280 void QQuickItem::dropEvent(QDropEvent *event)
3284 #endif // QT_NO_DRAGANDDROP
3286 bool QQuickItem::childMouseEventFilter(QQuickItem *, QEvent *)
3291 void QQuickItem::windowDeactivateEvent()
3293 foreach (QQuickItem* item, childItems()) {
3294 item->windowDeactivateEvent();
3298 QVariant QQuickItem::inputMethodQuery(Qt::InputMethodQuery query) const
3300 Q_D(const QQuickItem);
3305 v = (bool)(flags() & ItemAcceptsInputMethod);
3308 case Qt::ImCursorRectangle:
3310 case Qt::ImCursorPosition:
3311 case Qt::ImSurroundingText:
3312 case Qt::ImCurrentSelection:
3313 case Qt::ImMaximumTextLength:
3314 case Qt::ImAnchorPosition:
3315 case Qt::ImPreferredLanguage:
3316 if (d->extra.isAllocated() && d->extra->keyHandler)
3317 v = d->extra->keyHandler->inputMethodQuery(query);
3325 QQuickAnchorLine QQuickItemPrivate::left() const
3327 Q_Q(const QQuickItem);
3328 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Left);
3331 QQuickAnchorLine QQuickItemPrivate::right() const
3333 Q_Q(const QQuickItem);
3334 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Right);
3337 QQuickAnchorLine QQuickItemPrivate::horizontalCenter() const
3339 Q_Q(const QQuickItem);
3340 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::HCenter);
3343 QQuickAnchorLine QQuickItemPrivate::top() const
3345 Q_Q(const QQuickItem);
3346 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Top);
3349 QQuickAnchorLine QQuickItemPrivate::bottom() const
3351 Q_Q(const QQuickItem);
3352 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Bottom);
3355 QQuickAnchorLine QQuickItemPrivate::verticalCenter() const
3357 Q_Q(const QQuickItem);
3358 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::VCenter);
3361 QQuickAnchorLine QQuickItemPrivate::baseline() const
3363 Q_Q(const QQuickItem);
3364 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Baseline);
3367 qreal QQuickItem::baselineOffset() const
3369 Q_D(const QQuickItem);
3370 if (d->baselineOffsetValid) {
3371 return d->baselineOffset;
3377 void QQuickItem::setBaselineOffset(qreal offset)
3380 if (offset == d->baselineOffset)
3383 d->baselineOffset = offset;
3384 d->baselineOffsetValid = true;
3386 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
3387 const QQuickItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
3388 if (change.types & QQuickItemPrivate::Geometry) {
3389 QQuickAnchorsPrivate *anchor = change.listener->anchorPrivate();
3391 anchor->updateVerticalAnchors();
3395 if (d->_anchors && (d->_anchors->usedAnchors() & QQuickAnchors::BaselineAnchor))
3396 QQuickAnchorsPrivate::get(d->_anchors)->updateVerticalAnchors();
3398 emit baselineOffsetChanged(offset);
3403 * Schedules a call to updatePaintNode() for this item.
3405 * The call to QQuickItem::updatePaintNode() will always happen if the
3406 * item is showing in a QQuickCanvas.
3408 * Only items which specifies QQuickItem::ItemHasContents are allowed
3409 * to call QQuickItem::update().
3411 void QQuickItem::update()
3414 Q_ASSERT(flags() & ItemHasContents);
3415 d->dirty(QQuickItemPrivate::Content);
3418 void QQuickItem::polish()
3421 if (!d->polishScheduled) {
3422 d->polishScheduled = true;
3424 QQuickCanvasPrivate *p = QQuickCanvasPrivate::get(d->canvas);
3425 bool maybeupdate = p->itemsToPolish.isEmpty();
3426 p->itemsToPolish.insert(this);
3427 if (maybeupdate) d->canvas->maybeUpdate();
3433 \qmlmethod object QtQuick2::Item::mapFromItem(Item item, real x, real y)
3434 \qmlmethod object QtQuick2::Item::mapFromItem(Item item, real x, real y, real width, real height)
3436 Maps the point (\a x, \a y) or rect (\a x, \a y, \a width, \a height), which is in \a
3437 item's coordinate system, to this item's coordinate system, and returns an object with \c x and
3438 \c y (and optionally \c width and \c height) properties matching the mapped coordinate.
3440 If \a item is a \c null value, this maps the point or rect from the coordinate system of
3443 void QQuickItem::mapFromItem(QQmlV8Function *args) const
3445 if (args->Length() != 0) {
3446 v8::Local<v8::Value> item = (*args)[0];
3447 QV8Engine *engine = args->engine();
3449 QQuickItem *itemObj = 0;
3450 if (!item->IsNull())
3451 itemObj = qobject_cast<QQuickItem*>(engine->toQObject(item));
3453 if (!itemObj && !item->IsNull()) {
3454 qmlInfo(this) << "mapFromItem() given argument \"" << engine->toString(item->ToString())
3455 << "\" which is neither null nor an Item";
3459 v8::Local<v8::Object> rv = v8::Object::New();
3460 args->returnValue(rv);
3462 qreal x = (args->Length() > 1)?(*args)[1]->NumberValue():0;
3463 qreal y = (args->Length() > 2)?(*args)[2]->NumberValue():0;
3465 if (args->Length() > 3) {
3466 qreal w = (*args)[3]->NumberValue();
3467 qreal h = (args->Length() > 4)?(*args)[4]->NumberValue():0;
3469 QRectF r = mapRectFromItem(itemObj, QRectF(x, y, w, h));
3471 rv->Set(v8::String::New("x"), v8::Number::New(r.x()));
3472 rv->Set(v8::String::New("y"), v8::Number::New(r.y()));
3473 rv->Set(v8::String::New("width"), v8::Number::New(r.width()));
3474 rv->Set(v8::String::New("height"), v8::Number::New(r.height()));
3476 QPointF p = mapFromItem(itemObj, QPointF(x, y));
3478 rv->Set(v8::String::New("x"), v8::Number::New(p.x()));
3479 rv->Set(v8::String::New("y"), v8::Number::New(p.y()));
3484 QTransform QQuickItem::itemTransform(QQuickItem *other, bool *ok) const
3486 Q_D(const QQuickItem);
3488 // XXX todo - we need to be able to handle common parents better and detect
3492 QTransform t = d->itemToCanvasTransform();
3493 if (other) t *= QQuickItemPrivate::get(other)->canvasToItemTransform();
3499 \qmlmethod object QtQuick2::Item::mapToItem(Item item, real x, real y)
3500 \qmlmethod object QtQuick2::Item::mapToItem(Item item, real x, real y, real width, real height)
3502 Maps the point (\a x, \a y) or rect (\a x, \a y, \a width, \a height), which is in this
3503 item's coordinate system, to \a item's coordinate system, and returns an object with \c x and
3504 \c y (and optionally \c width and \c height) properties matching the mapped coordinate.
3506 If \a item is a \c null value, this maps the point or rect to the coordinate system of the
3509 void QQuickItem::mapToItem(QQmlV8Function *args) const
3511 if (args->Length() != 0) {
3512 v8::Local<v8::Value> item = (*args)[0];
3513 QV8Engine *engine = args->engine();
3515 QQuickItem *itemObj = 0;
3516 if (!item->IsNull())
3517 itemObj = qobject_cast<QQuickItem*>(engine->toQObject(item));
3519 if (!itemObj && !item->IsNull()) {
3520 qmlInfo(this) << "mapToItem() given argument \"" << engine->toString(item->ToString())
3521 << "\" which is neither null nor an Item";
3525 v8::Local<v8::Object> rv = v8::Object::New();
3526 args->returnValue(rv);
3528 qreal x = (args->Length() > 1)?(*args)[1]->NumberValue():0;
3529 qreal y = (args->Length() > 2)?(*args)[2]->NumberValue():0;
3531 if (args->Length() > 3) {
3532 qreal w = (*args)[3]->NumberValue();
3533 qreal h = (args->Length() > 4)?(*args)[4]->NumberValue():0;
3535 QRectF r = mapRectToItem(itemObj, QRectF(x, y, w, h));
3537 rv->Set(v8::String::New("x"), v8::Number::New(r.x()));
3538 rv->Set(v8::String::New("y"), v8::Number::New(r.y()));
3539 rv->Set(v8::String::New("width"), v8::Number::New(r.width()));
3540 rv->Set(v8::String::New("height"), v8::Number::New(r.height()));
3542 QPointF p = mapToItem(itemObj, QPointF(x, y));
3544 rv->Set(v8::String::New("x"), v8::Number::New(p.x()));
3545 rv->Set(v8::String::New("y"), v8::Number::New(p.y()));
3550 void QQuickItem::forceActiveFocus()
3553 QQuickItem *parent = parentItem();
3555 if (parent->flags() & QQuickItem::ItemIsFocusScope) {
3556 parent->setFocus(true);
3558 parent = parent->parentItem();
3562 QQuickItem *QQuickItem::childAt(qreal x, qreal y) const
3564 // XXX todo - should this include transform etc.?
3565 const QList<QQuickItem *> children = childItems();
3566 for (int i = children.count()-1; i >= 0; --i) {
3567 QQuickItem *child = children.at(i);
3568 if (child->isVisible() && child->x() <= x
3569 && child->x() + child->width() >= x
3571 && child->y() + child->height() >= y)
3577 QQmlListProperty<QObject> QQuickItemPrivate::resources()
3579 return QQmlListProperty<QObject>(q_func(), 0, QQuickItemPrivate::resources_append,
3580 QQuickItemPrivate::resources_count,
3581 QQuickItemPrivate::resources_at,
3582 QQuickItemPrivate::resources_clear);
3585 QQmlListProperty<QQuickItem> QQuickItemPrivate::children()
3587 return QQmlListProperty<QQuickItem>(q_func(), 0, QQuickItemPrivate::children_append,
3588 QQuickItemPrivate::children_count,
3589 QQuickItemPrivate::children_at,
3590 QQuickItemPrivate::children_clear);
3595 \qmlproperty real QtQuick2::Item::visibleChildren
3596 This read-only property lists all of the item's children that are currently visible.
3597 Note that a child's visibility may have changed explicitly, or because the visibility
3598 of this (it's parent) item or another grandparent changed.
3600 QQmlListProperty<QQuickItem> QQuickItemPrivate::visibleChildren()
3602 return QQmlListProperty<QQuickItem>(q_func(), 0, QQuickItemPrivate::visibleChildren_append,
3603 QQuickItemPrivate::visibleChildren_count,
3604 QQuickItemPrivate::visibleChildren_at);
3608 QQmlListProperty<QQuickState> QQuickItemPrivate::states()
3610 return _states()->statesProperty();
3613 QQmlListProperty<QQuickTransition> QQuickItemPrivate::transitions()
3615 return _states()->transitionsProperty();
3618 QString QQuickItemPrivate::state() const
3623 return _stateGroup->state();
3626 void QQuickItemPrivate::setState(const QString &state)
3628 _states()->setState(state);
3631 QString QQuickItem::state() const
3633 Q_D(const QQuickItem);
3637 void QQuickItem::setState(const QString &state)
3643 QQmlListProperty<QQuickTransform> QQuickItem::transform()
3645 return QQmlListProperty<QQuickTransform>(this, 0, QQuickItemPrivate::transform_append,
3646 QQuickItemPrivate::transform_count,
3647 QQuickItemPrivate::transform_at,
3648 QQuickItemPrivate::transform_clear);
3653 Derived classes should call the base class method before adding their own action to
3654 perform at classBegin.
3656 void QQuickItem::classBegin()
3659 d->componentComplete = false;
3661 d->_stateGroup->classBegin();
3663 d->_anchors->classBegin();
3664 if (d->extra.isAllocated() && d->extra->layer)
3665 d->extra->layer->classBegin();
3670 Derived classes should call the base class method before adding their own actions to
3671 perform at componentComplete.
3673 void QQuickItem::componentComplete()
3676 d->componentComplete = true;
3678 d->_stateGroup->componentComplete();
3680 d->_anchors->componentComplete();
3681 QQuickAnchorsPrivate::get(d->_anchors)->updateOnComplete();
3684 if (d->extra.isAllocated() && d->extra->layer)
3685 d->extra->layer->componentComplete();
3687 if (d->extra.isAllocated() && d->extra->keyHandler)
3688 d->extra->keyHandler->componentComplete();
3690 if (d->extra.isAllocated() && d->extra->contents)
3691 d->extra->contents->complete();
3693 if (d->canvas && d->dirtyAttributes) {
3694 d->addToDirtyList();
3695 QQuickCanvasPrivate::get(d->canvas)->dirtyItem(this);
3699 QQuickStateGroup *QQuickItemPrivate::_states()
3703 _stateGroup = new QQuickStateGroup;
3704 if (!componentComplete)
3705 _stateGroup->classBegin();
3706 qmlobject_connect(_stateGroup, QQuickStateGroup, SIGNAL(stateChanged(QString)),
3707 q, QQuickItem, SIGNAL(stateChanged(QString)))
3713 QPointF QQuickItemPrivate::computeTransformOrigin() const
3717 case QQuickItem::TopLeft:
3718 return QPointF(0, 0);
3719 case QQuickItem::Top:
3720 return QPointF(width / 2., 0);
3721 case QQuickItem::TopRight:
3722 return QPointF(width, 0);
3723 case QQuickItem::Left:
3724 return QPointF(0, height / 2.);
3725 case QQuickItem::Center:
3726 return QPointF(width / 2., height / 2.);
3727 case QQuickItem::Right:
3728 return QPointF(width, height / 2.);
3729 case QQuickItem::BottomLeft:
3730 return QPointF(0, height);
3731 case QQuickItem::Bottom:
3732 return QPointF(width / 2., height);
3733 case QQuickItem::BottomRight:
3734 return QPointF(width, height);
3738 void QQuickItemPrivate::transformChanged()
3740 if (extra.isAllocated() && extra->layer)
3741 extra->layer->updateMatrix();
3744 void QQuickItemPrivate::deliverKeyEvent(QKeyEvent *e)
3748 Q_ASSERT(e->isAccepted());
3749 if (extra.isAllocated() && extra->keyHandler) {
3750 if (e->type() == QEvent::KeyPress)
3751 extra->keyHandler->keyPressed(e, false);
3753 extra->keyHandler->keyReleased(e, false);
3755 if (e->isAccepted())
3761 if (e->type() == QEvent::KeyPress)
3762 q->keyPressEvent(e);
3764 q->keyReleaseEvent(e);
3766 if (e->isAccepted())
3769 if (extra.isAllocated() && extra->keyHandler) {
3772 if (e->type() == QEvent::KeyPress)
3773 extra->keyHandler->keyPressed(e, true);
3775 extra->keyHandler->keyReleased(e, true);
3779 void QQuickItemPrivate::deliverInputMethodEvent(QInputMethodEvent *e)
3783 Q_ASSERT(e->isAccepted());
3784 if (extra.isAllocated() && extra->keyHandler) {
3785 extra->keyHandler->inputMethodEvent(e, false);
3787 if (e->isAccepted())
3793 q->inputMethodEvent(e);
3795 if (e->isAccepted())
3798 if (extra.isAllocated() && extra->keyHandler) {
3801 extra->keyHandler->inputMethodEvent(e, true);
3805 void QQuickItemPrivate::deliverFocusEvent(QFocusEvent *e)
3809 if (e->type() == QEvent::FocusIn) {
3812 q->focusOutEvent(e);
3816 void QQuickItemPrivate::deliverMouseEvent(QMouseEvent *e)
3820 Q_ASSERT(e->isAccepted());
3822 switch (e->type()) {
3824 Q_ASSERT(!"Unknown event type");
3825 case QEvent::MouseMove:
3826 q->mouseMoveEvent(e);
3828 case QEvent::MouseButtonPress:
3829 q->mousePressEvent(e);
3831 case QEvent::MouseButtonRelease:
3832 q->mouseReleaseEvent(e);
3834 case QEvent::MouseButtonDblClick:
3835 q->mouseDoubleClickEvent(e);
3840 void QQuickItemPrivate::deliverWheelEvent(QWheelEvent *e)
3846 void QQuickItemPrivate::deliverTouchEvent(QTouchEvent *e)
3852 void QQuickItemPrivate::deliverHoverEvent(QHoverEvent *e)
3855 switch (e->type()) {
3857 Q_ASSERT(!"Unknown event type");
3858 case QEvent::HoverEnter:
3859 q->hoverEnterEvent(e);
3861 case QEvent::HoverLeave:
3862 q->hoverLeaveEvent(e);
3864 case QEvent::HoverMove:
3865 q->hoverMoveEvent(e);
3870 #ifndef QT_NO_DRAGANDDROP
3871 void QQuickItemPrivate::deliverDragEvent(QEvent *e)
3874 switch (e->type()) {
3876 Q_ASSERT(!"Unknown event type");
3877 case QEvent::DragEnter:
3878 q->dragEnterEvent(static_cast<QDragEnterEvent *>(e));
3880 case QEvent::DragLeave:
3881 q->dragLeaveEvent(static_cast<QDragLeaveEvent *>(e));
3883 case QEvent::DragMove:
3884 q->dragMoveEvent(static_cast<QDragMoveEvent *>(e));
3887 q->dropEvent(static_cast<QDropEvent *>(e));
3891 #endif // QT_NO_DRAGANDDROP
3893 void QQuickItem::itemChange(ItemChange change, const ItemChangeData &value)
3900 Notify input method on updated query values if needed. \a indicates changed attributes.
3902 void QQuickItem::updateInputMethod(Qt::InputMethodQueries queries)
3904 if (hasActiveFocus())
3905 qApp->inputMethod()->update(queries);
3909 // XXX todo - do we want/need this anymore?
3910 QRectF QQuickItem::boundingRect() const
3912 Q_D(const QQuickItem);
3913 return QRectF(0, 0, d->width, d->height);
3917 QRectF QQuickItem::clipRect() const
3919 Q_D(const QQuickItem);
3920 return QRectF(0, 0, d->width, d->height);
3924 QQuickItem::TransformOrigin QQuickItem::transformOrigin() const
3926 Q_D(const QQuickItem);
3930 void QQuickItem::setTransformOrigin(TransformOrigin origin)
3933 if (origin == d->origin())
3936 d->extra.value().origin = origin;
3937 d->dirty(QQuickItemPrivate::TransformOrigin);
3939 emit transformOriginChanged(d->origin());
3942 QPointF QQuickItem::transformOriginPoint() const
3944 Q_D(const QQuickItem);
3945 if (d->extra.isAllocated() && !d->extra->userTransformOriginPoint.isNull())
3946 return d->extra->userTransformOriginPoint;
3947 return d->computeTransformOrigin();
3950 void QQuickItem::setTransformOriginPoint(const QPointF &point)
3953 if (d->extra.value().userTransformOriginPoint == point)
3956 d->extra->userTransformOriginPoint = point;
3957 d->dirty(QQuickItemPrivate::TransformOrigin);
3960 qreal QQuickItem::z() const
3962 Q_D(const QQuickItem);
3966 void QQuickItem::setZ(qreal v)
3972 d->extra.value().z = v;
3974 d->dirty(QQuickItemPrivate::ZValue);
3975 if (d->parentItem) {
3976 QQuickItemPrivate::get(d->parentItem)->dirty(QQuickItemPrivate::ChildrenStackingChanged);
3977 QQuickItemPrivate::get(d->parentItem)->markSortedChildrenDirty(this);
3982 if (d->extra.isAllocated() && d->extra->layer)
3983 d->extra->layer->updateZ();
3988 \qmlproperty real QtQuick2::Item::rotation
3989 This property holds the rotation of the item in degrees clockwise.
3991 This specifies how many degrees to rotate the item around its transformOrigin.
3992 The default rotation is 0 degrees (i.e. not rotated at all).
3996 \li \image declarative-rotation.png
4001 width: 100; height: 100
4004 x: 25; y: 25; width: 50; height: 50
4011 \sa transform, Rotation
4015 \qmlproperty real QtQuick2::Item::scale
4016 This property holds the scale of the item.
4018 A scale of less than 1 means the item will be displayed smaller than
4019 normal, and a scale of greater than 1 means the item will be
4020 displayed larger than normal. A negative scale means the item will
4023 By default, items are displayed at a scale of 1 (i.e. at their
4026 Scaling is from the item's transformOrigin.
4030 \li \image declarative-scale.png
4035 width: 100; height: 100
4038 width: 25; height: 25
4042 x: 25; y: 25; width: 50; height: 50
4049 \sa transform, Scale
4053 \qmlproperty real QtQuick2::Item::opacity
4055 This property holds the opacity of the item. Opacity is specified as a
4056 number between 0 (fully transparent) and 1 (fully opaque). The default is 1.
4058 When this property is set, the specified opacity is also applied
4059 individually to child items. In almost all cases this is what you want,
4060 but in some cases it may produce undesired results. For example in the
4061 second set of rectangles below, the red rectangle has specified an opacity
4062 of 0.5, which affects the opacity of its blue child rectangle even though
4063 the child has not specified an opacity.
4067 \li \image declarative-item_opacity1.png
4073 width: 100; height: 100
4076 x: 50; y: 50; width: 100; height: 100
4082 \li \image declarative-item_opacity2.png
4089 width: 100; height: 100
4092 x: 50; y: 50; width: 100; height: 100
4099 If an item's opacity is set to 0, the item will no longer receive mouse
4100 events, but will continue to receive key events and will retain the keyboard
4101 \l focus if it has been set. (In contrast, setting the \l visible property
4102 to \c false stops both mouse and keyboard events, and also removes focus
4107 Returns a value indicating whether mouse input should
4108 remain with this item exclusively.
4110 \sa setKeepMouseGrab()
4113 qreal QQuickItem::rotation() const
4115 Q_D(const QQuickItem);
4116 return d->rotation();
4119 void QQuickItem::setRotation(qreal r)
4122 if (d->rotation() == r)
4125 d->extra.value().rotation = r;
4127 d->dirty(QQuickItemPrivate::BasicTransform);
4129 d->itemChange(ItemRotationHasChanged, r);
4131 emit rotationChanged();
4134 qreal QQuickItem::scale() const
4136 Q_D(const QQuickItem);
4140 void QQuickItem::setScale(qreal s)
4143 if (d->scale() == s)
4146 d->extra.value().scale = s;
4148 d->dirty(QQuickItemPrivate::BasicTransform);
4150 emit scaleChanged();
4153 qreal QQuickItem::opacity() const
4155 Q_D(const QQuickItem);
4156 return d->opacity();
4159 void QQuickItem::setOpacity(qreal o)
4162 if (d->opacity() == o)
4165 d->extra.value().opacity = o;
4167 d->dirty(QQuickItemPrivate::OpacityValue);
4169 d->itemChange(ItemOpacityHasChanged, o);
4171 emit opacityChanged();
4174 bool QQuickItem::isVisible() const
4176 Q_D(const QQuickItem);
4177 return d->effectiveVisible;
4180 void QQuickItem::setVisible(bool v)
4183 if (v == d->explicitVisible)
4186 d->explicitVisible = v;
4188 d->dirty(QQuickItemPrivate::Visible);
4190 const bool childVisibilityChanged = d->setEffectiveVisibleRecur(d->calcEffectiveVisible());
4191 if (childVisibilityChanged && d->parentItem)
4192 emit d->parentItem->visibleChildrenChanged(); // signal the parent, not this!
4195 bool QQuickItem::isEnabled() const
4197 Q_D(const QQuickItem);
4198 return d->effectiveEnable;
4201 void QQuickItem::setEnabled(bool e)
4204 if (e == d->explicitEnable)
4207 d->explicitEnable = e;
4209 QQuickItem *scope = parentItem();
4210 while (scope && !scope->isFocusScope())
4211 scope = scope->parentItem();
4213 d->setEffectiveEnableRecur(scope, d->calcEffectiveEnable());
4216 bool QQuickItemPrivate::calcEffectiveVisible() const
4218 // XXX todo - Should the effective visible of an element with no parent just be the current
4219 // effective visible? This would prevent pointless re-processing in the case of an element
4220 // moving to/from a no-parent situation, but it is different from what graphics view does.
4221 return explicitVisible && (!parentItem || QQuickItemPrivate::get(parentItem)->effectiveVisible);
4224 bool QQuickItemPrivate::setEffectiveVisibleRecur(bool newEffectiveVisible)
4228 if (newEffectiveVisible && !explicitVisible) {
4229 // This item locally overrides visibility
4230 return false; // effective visibility didn't change
4233 if (newEffectiveVisible == effectiveVisible) {
4234 // No change necessary
4235 return false; // effective visibility didn't change
4238 effectiveVisible = newEffectiveVisible;
4240 if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
4243 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(canvas);
4244 if (canvasPriv->mouseGrabberItem == q)
4248 bool childVisibilityChanged = false;
4249 for (int ii = 0; ii < childItems.count(); ++ii)
4250 childVisibilityChanged |= QQuickItemPrivate::get(childItems.at(ii))->setEffectiveVisibleRecur(newEffectiveVisible);
4252 itemChange(QQuickItem::ItemVisibleHasChanged, effectiveVisible);
4253 #ifndef QT_NO_ACCESSIBILITY
4255 QAccessibleEvent ev(q, effectiveVisible ? QAccessible::ObjectShow : QAccessible::ObjectHide);
4256 QAccessible::updateAccessibility(&ev);
4259 emit q->visibleChanged();
4260 if (childVisibilityChanged)
4261 emit q->visibleChildrenChanged();
4263 return true; // effective visibility DID change
4266 bool QQuickItemPrivate::calcEffectiveEnable() const
4268 // XXX todo - Should the effective enable of an element with no parent just be the current
4269 // effective enable? This would prevent pointless re-processing in the case of an element
4270 // moving to/from a no-parent situation, but it is different from what graphics view does.
4271 return explicitEnable && (!parentItem || QQuickItemPrivate::get(parentItem)->effectiveEnable);
4274 void QQuickItemPrivate::setEffectiveEnableRecur(QQuickItem *scope, bool newEffectiveEnable)
4278 if (newEffectiveEnable && !explicitEnable) {
4279 // This item locally overrides enable
4283 if (newEffectiveEnable == effectiveEnable) {
4284 // No change necessary
4288 effectiveEnable = newEffectiveEnable;
4291 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(canvas);
4292 if (canvasPriv->mouseGrabberItem == q)
4294 if (scope && !effectiveEnable && activeFocus) {
4295 canvasPriv->clearFocusInScope(
4296 scope, q, QQuickCanvasPrivate::DontChangeFocusProperty | QQuickCanvasPrivate::DontChangeSubFocusItem);
4300 for (int ii = 0; ii < childItems.count(); ++ii) {
4301 QQuickItemPrivate::get(childItems.at(ii))->setEffectiveEnableRecur(
4302 (flags & QQuickItem::ItemIsFocusScope) && scope ? q : scope, newEffectiveEnable);
4305 if (canvas && scope && effectiveEnable && focus) {
4306 QQuickCanvasPrivate::get(canvas)->setFocusInScope(
4307 scope, q, QQuickCanvasPrivate::DontChangeFocusProperty | QQuickCanvasPrivate::DontChangeSubFocusItem);
4310 emit q->enabledChanged();
4313 QString QQuickItemPrivate::dirtyToString() const
4315 #define DIRTY_TO_STRING(value) if (dirtyAttributes & value) { \
4316 if (!rv.isEmpty()) \
4317 rv.append(QLatin1String("|")); \
4318 rv.append(QLatin1String(#value)); \
4321 // QString rv = QLatin1String("0x") + QString::number(dirtyAttributes, 16);
4324 DIRTY_TO_STRING(TransformOrigin);
4325 DIRTY_TO_STRING(Transform);
4326 DIRTY_TO_STRING(BasicTransform);
4327 DIRTY_TO_STRING(Position);
4328 DIRTY_TO_STRING(Size);
4329 DIRTY_TO_STRING(ZValue);
4330 DIRTY_TO_STRING(Content);
4331 DIRTY_TO_STRING(Smooth);
4332 DIRTY_TO_STRING(OpacityValue);
4333 DIRTY_TO_STRING(ChildrenChanged);
4334 DIRTY_TO_STRING(ChildrenStackingChanged);
4335 DIRTY_TO_STRING(ParentChanged);
4336 DIRTY_TO_STRING(Clip);
4337 DIRTY_TO_STRING(Canvas);
4338 DIRTY_TO_STRING(EffectReference);
4339 DIRTY_TO_STRING(Visible);
4340 DIRTY_TO_STRING(HideReference);
4345 void QQuickItemPrivate::dirty(DirtyType type)
4348 if (type & (TransformOrigin | Transform | BasicTransform | Position | Size))
4351 if (!(dirtyAttributes & type) || (canvas && !prevDirtyItem)) {
4352 dirtyAttributes |= type;
4353 if (canvas && componentComplete) {
4355 QQuickCanvasPrivate::get(canvas)->dirtyItem(q);
4360 void QQuickItemPrivate::addToDirtyList()
4365 if (!prevDirtyItem) {
4366 Q_ASSERT(!nextDirtyItem);
4368 QQuickCanvasPrivate *p = QQuickCanvasPrivate::get(canvas);
4369 nextDirtyItem = p->dirtyItemList;
4370 if (nextDirtyItem) QQuickItemPrivate::get(nextDirtyItem)->prevDirtyItem = &nextDirtyItem;
4371 prevDirtyItem = &p->dirtyItemList;
4372 p->dirtyItemList = q;
4375 Q_ASSERT(prevDirtyItem);
4378 void QQuickItemPrivate::removeFromDirtyList()
4380 if (prevDirtyItem) {
4381 if (nextDirtyItem) QQuickItemPrivate::get(nextDirtyItem)->prevDirtyItem = prevDirtyItem;
4382 *prevDirtyItem = nextDirtyItem;
4386 Q_ASSERT(!prevDirtyItem);
4387 Q_ASSERT(!nextDirtyItem);
4390 void QQuickItemPrivate::refFromEffectItem(bool hide)
4392 ++extra.value().effectRefCount;
4393 if (1 == extra->effectRefCount) {
4394 dirty(EffectReference);
4395 if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
4398 if (++extra->hideRefCount == 1)
4399 dirty(HideReference);
4403 void QQuickItemPrivate::derefFromEffectItem(bool unhide)
4405 Q_ASSERT(extra->effectRefCount);
4406 --extra->effectRefCount;
4407 if (0 == extra->effectRefCount) {
4408 dirty(EffectReference);
4409 if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
4412 if (--extra->hideRefCount == 0)
4413 dirty(HideReference);
4417 void QQuickItemPrivate::setCulled(bool cull)
4423 if ((cull && ++extra->hideRefCount == 1) || (!cull && --extra->hideRefCount == 0))
4424 dirty(HideReference);
4427 void QQuickItemPrivate::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data)
4431 case QQuickItem::ItemChildAddedChange:
4432 q->itemChange(change, data);
4433 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4434 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4435 if (change.types & QQuickItemPrivate::Children) {
4436 change.listener->itemChildAdded(q, data.item);
4440 case QQuickItem::ItemChildRemovedChange:
4441 q->itemChange(change, data);
4442 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4443 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4444 if (change.types & QQuickItemPrivate::Children) {
4445 change.listener->itemChildRemoved(q, data.item);
4449 case QQuickItem::ItemSceneChange:
4450 q->itemChange(change, data);
4452 case QQuickItem::ItemVisibleHasChanged:
4453 q->itemChange(change, data);
4454 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4455 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4456 if (change.types & QQuickItemPrivate::Visibility) {
4457 change.listener->itemVisibilityChanged(q);
4461 case QQuickItem::ItemParentHasChanged:
4462 q->itemChange(change, data);
4463 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4464 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4465 if (change.types & QQuickItemPrivate::Parent) {
4466 change.listener->itemParentChanged(q, data.item);
4470 case QQuickItem::ItemOpacityHasChanged:
4471 q->itemChange(change, data);
4472 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4473 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4474 if (change.types & QQuickItemPrivate::Opacity) {
4475 change.listener->itemOpacityChanged(q);
4479 case QQuickItem::ItemActiveFocusHasChanged:
4480 q->itemChange(change, data);
4482 case QQuickItem::ItemRotationHasChanged:
4483 q->itemChange(change, data);
4484 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4485 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4486 if (change.types & QQuickItemPrivate::Rotation) {
4487 change.listener->itemRotationChanged(q);
4495 \property QQuickItem::smooth
4496 \brief Specifies whether the item is smoothed or not
4498 Primarily used in image based elements to decide if the item should use smooth
4499 sampling or not. Smooth sampling is performed using linear interpolation, while
4500 non-smooth is performed using nearest neighbor.
4502 In Qt Quick 2.0, this property has minimal impact on performance.
4508 Returns true if the item should be drawn with antialiasing and
4509 smooth pixmap filtering, false otherwise.
4511 The default is false.
4515 bool QQuickItem::smooth() const
4517 Q_D(const QQuickItem);
4522 Sets whether the item should be drawn with antialiasing and
4523 smooth pixmap filtering to \a smooth.
4527 void QQuickItem::setSmooth(bool smooth)
4530 if (d->smooth == smooth)
4534 d->dirty(QQuickItemPrivate::Smooth);
4536 emit smoothChanged(smooth);
4539 QQuickItem::Flags QQuickItem::flags() const
4541 Q_D(const QQuickItem);
4542 return (QQuickItem::Flags)d->flags;
4545 void QQuickItem::setFlag(Flag flag, bool enabled)
4549 setFlags((Flags)(d->flags | (quint32)flag));
4551 setFlags((Flags)(d->flags & ~(quint32)flag));
4554 void QQuickItem::setFlags(Flags flags)
4558 if ((flags & ItemIsFocusScope) != (d->flags & ItemIsFocusScope)) {
4559 if (flags & ItemIsFocusScope && !d->childItems.isEmpty() && d->canvas) {
4560 qWarning("QQuickItem: Cannot set FocusScope once item has children and is in a canvas.");
4561 flags &= ~ItemIsFocusScope;
4562 } else if (d->flags & ItemIsFocusScope) {
4563 qWarning("QQuickItem: Cannot unset FocusScope flag.");
4564 flags |= ItemIsFocusScope;
4568 if ((flags & ItemClipsChildrenToShape ) != (d->flags & ItemClipsChildrenToShape))
4569 d->dirty(QQuickItemPrivate::Clip);
4574 qreal QQuickItem::x() const
4576 Q_D(const QQuickItem);
4580 qreal QQuickItem::y() const
4582 Q_D(const QQuickItem);
4586 QPointF QQuickItem::pos() const
4588 Q_D(const QQuickItem);
4589 return QPointF(d->x, d->y);
4592 void QQuickItem::setX(qreal v)
4601 d->dirty(QQuickItemPrivate::Position);
4603 geometryChanged(QRectF(x(), y(), width(), height()),
4604 QRectF(oldx, y(), width(), height()));
4607 void QQuickItem::setY(qreal v)
4616 d->dirty(QQuickItemPrivate::Position);
4618 geometryChanged(QRectF(x(), y(), width(), height()),
4619 QRectF(x(), oldy, width(), height()));
4622 void QQuickItem::setPos(const QPointF &pos)
4625 if (QPointF(d->x, d->y) == pos)
4634 d->dirty(QQuickItemPrivate::Position);
4636 geometryChanged(QRectF(x(), y(), width(), height()),
4637 QRectF(oldx, oldy, width(), height()));
4640 qreal QQuickItem::width() const
4642 Q_D(const QQuickItem);
4646 void QQuickItem::setWidth(qreal w)
4652 d->widthValid = true;
4656 qreal oldWidth = d->width;
4659 d->dirty(QQuickItemPrivate::Size);
4661 geometryChanged(QRectF(x(), y(), width(), height()),
4662 QRectF(x(), y(), oldWidth, height()));
4665 void QQuickItem::resetWidth()
4668 d->widthValid = false;
4669 setImplicitWidth(implicitWidth());
4672 void QQuickItemPrivate::implicitWidthChanged()
4675 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4676 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4677 if (change.types & QQuickItemPrivate::ImplicitWidth) {
4678 change.listener->itemImplicitWidthChanged(q);
4681 emit q->implicitWidthChanged();
4684 qreal QQuickItemPrivate::getImplicitWidth() const
4686 return implicitWidth;
4689 Returns the width of the item that is implied by other properties that determine the content.
4691 qreal QQuickItem::implicitWidth() const
4693 Q_D(const QQuickItem);
4694 return d->getImplicitWidth();
4698 \qmlproperty real QtQuick2::Item::implicitWidth
4699 \qmlproperty real QtQuick2::Item::implicitHeight
4701 Defines the natural width or height of the Item if no \l width or \l height is specified.
4703 The default implicit size for most items is 0x0, however some elements have an inherent
4704 implicit size which cannot be overridden, e.g. Image, Text.
4706 Setting the implicit size is useful for defining components that have a preferred size
4707 based on their content, for example:
4714 property alias icon: image.source
4715 property alias label: text.text
4716 implicitWidth: text.implicitWidth + image.implicitWidth
4717 implicitHeight: Math.max(text.implicitHeight, image.implicitHeight)
4722 anchors.left: image.right; anchors.right: parent.right
4723 anchors.verticalCenter: parent.verticalCenter
4728 \b Note: using implicitWidth of Text or TextEdit and setting the width explicitly
4729 incurs a performance penalty as the text must be laid out twice.
4733 Sets the implied width of the item to \a w.
4734 This is the width implied by other properties that determine the content.
4736 void QQuickItem::setImplicitWidth(qreal w)
4739 bool changed = w != d->implicitWidth;
4740 d->implicitWidth = w;
4741 if (d->width == w || widthValid()) {
4743 d->implicitWidthChanged();
4744 if (d->width == w || widthValid())
4749 qreal oldWidth = d->width;
4752 d->dirty(QQuickItemPrivate::Size);
4754 geometryChanged(QRectF(x(), y(), width(), height()),
4755 QRectF(x(), y(), oldWidth, height()));
4758 d->implicitWidthChanged();
4762 Returns whether the width property has been set explicitly.
4764 bool QQuickItem::widthValid() const
4766 Q_D(const QQuickItem);
4767 return d->widthValid;
4770 qreal QQuickItem::height() const
4772 Q_D(const QQuickItem);
4776 void QQuickItem::setHeight(qreal h)
4782 d->heightValid = true;
4786 qreal oldHeight = d->height;
4789 d->dirty(QQuickItemPrivate::Size);
4791 geometryChanged(QRectF(x(), y(), width(), height()),
4792 QRectF(x(), y(), width(), oldHeight));
4795 void QQuickItem::resetHeight()
4798 d->heightValid = false;
4799 setImplicitHeight(implicitHeight());
4802 void QQuickItemPrivate::implicitHeightChanged()
4805 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4806 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4807 if (change.types & QQuickItemPrivate::ImplicitHeight) {
4808 change.listener->itemImplicitHeightChanged(q);
4811 emit q->implicitHeightChanged();
4814 qreal QQuickItemPrivate::getImplicitHeight() const
4816 return implicitHeight;
4820 Returns the height of the item that is implied by other properties that determine the content.
4822 qreal QQuickItem::implicitHeight() const
4824 Q_D(const QQuickItem);
4825 return d->getImplicitHeight();
4830 Sets the implied height of the item to \a h.
4831 This is the height implied by other properties that determine the content.
4833 void QQuickItem::setImplicitHeight(qreal h)
4836 bool changed = h != d->implicitHeight;
4837 d->implicitHeight = h;
4838 if (d->height == h || heightValid()) {
4840 d->implicitHeightChanged();
4841 if (d->height == h || heightValid())
4846 qreal oldHeight = d->height;
4849 d->dirty(QQuickItemPrivate::Size);
4851 geometryChanged(QRectF(x(), y(), width(), height()),
4852 QRectF(x(), y(), width(), oldHeight));
4855 d->implicitHeightChanged();
4858 void QQuickItem::setImplicitSize(qreal w, qreal h)
4861 bool wChanged = w != d->implicitWidth;
4862 bool hChanged = h != d->implicitHeight;
4864 d->implicitWidth = w;
4865 d->implicitHeight = h;
4869 if (d->width == w || widthValid()) {
4871 d->implicitWidthChanged();
4872 wDone = d->width == w || widthValid();
4875 if (d->height == h || heightValid()) {
4877 d->implicitHeightChanged();
4878 hDone = d->height == h || heightValid();
4884 qreal oldWidth = d->width;
4885 qreal oldHeight = d->height;
4891 d->dirty(QQuickItemPrivate::Size);
4893 geometryChanged(QRectF(x(), y(), width(), height()),
4894 QRectF(x(), y(), oldWidth, oldHeight));
4896 if (!wDone && wChanged)
4897 d->implicitWidthChanged();
4898 if (!hDone && hChanged)
4899 d->implicitHeightChanged();
4903 Returns whether the height property has been set explicitly.
4905 bool QQuickItem::heightValid() const
4907 Q_D(const QQuickItem);
4908 return d->heightValid;
4911 void QQuickItem::setSize(const QSizeF &size)
4914 d->heightValid = true;
4915 d->widthValid = true;
4917 if (QSizeF(d->width, d->height) == size)
4920 qreal oldHeight = d->height;
4921 qreal oldWidth = d->width;
4922 d->height = size.height();
4923 d->width = size.width();
4925 d->dirty(QQuickItemPrivate::Size);
4927 geometryChanged(QRectF(x(), y(), width(), height()),
4928 QRectF(x(), y(), oldWidth, oldHeight));
4931 bool QQuickItem::hasActiveFocus() const
4933 Q_D(const QQuickItem);
4934 return d->activeFocus;
4937 bool QQuickItem::hasFocus() const
4939 Q_D(const QQuickItem);
4943 void QQuickItem::setFocus(bool focus)
4946 if (d->focus == focus)
4949 if (d->canvas || d->parentItem) {
4950 // Need to find our nearest focus scope
4951 QQuickItem *scope = parentItem();
4952 while (scope && !scope->isFocusScope() && scope->parentItem())
4953 scope = scope->parentItem();
4956 QQuickCanvasPrivate::get(d->canvas)->setFocusInScope(scope, this);
4958 QQuickCanvasPrivate::get(d->canvas)->clearFocusInScope(scope, this);
4960 // do the focus changes from setFocusInScope/clearFocusInScope that are
4961 // unrelated to a canvas
4962 QVarLengthArray<QQuickItem *, 20> changed;
4963 QQuickItem *oldSubFocusItem = QQuickItemPrivate::get(scope)->subFocusItem;
4964 if (oldSubFocusItem) {
4965 QQuickItemPrivate::get(oldSubFocusItem)->updateSubFocusItem(scope, false);
4966 QQuickItemPrivate::get(oldSubFocusItem)->focus = false;
4967 changed << oldSubFocusItem;
4968 } else if (!scope->isFocusScope() && scope->hasFocus()) {
4969 QQuickItemPrivate::get(scope)->focus = false;
4972 d->updateSubFocusItem(scope, focus);
4976 emit focusChanged(focus);
4978 QQuickCanvasPrivate::notifyFocusChangesRecur(changed.data(), changed.count() - 1);
4981 QVarLengthArray<QQuickItem *, 20> changed;
4982 QQuickItem *oldSubFocusItem = d->subFocusItem;
4983 if (!isFocusScope() && oldSubFocusItem) {
4984 QQuickItemPrivate::get(oldSubFocusItem)->updateSubFocusItem(this, false);
4985 QQuickItemPrivate::get(oldSubFocusItem)->focus = false;
4986 changed << oldSubFocusItem;
4991 emit focusChanged(focus);
4993 QQuickCanvasPrivate::notifyFocusChangesRecur(changed.data(), changed.count() - 1);
4997 bool QQuickItem::isFocusScope() const
4999 return flags() & ItemIsFocusScope;
5002 QQuickItem *QQuickItem::scopedFocusItem() const
5004 Q_D(const QQuickItem);
5005 if (!isFocusScope())
5008 return d->subFocusItem;
5012 Qt::MouseButtons QQuickItem::acceptedMouseButtons() const
5014 Q_D(const QQuickItem);
5015 return d->acceptedMouseButtons();
5018 void QQuickItem::setAcceptedMouseButtons(Qt::MouseButtons buttons)
5021 if (buttons & Qt::LeftButton)
5024 d->extra.clearFlag();
5026 buttons &= ~Qt::LeftButton;
5027 if (buttons || d->extra.isAllocated())
5028 d->extra.value().acceptedMouseButtons = buttons;
5031 bool QQuickItem::filtersChildMouseEvents() const
5033 Q_D(const QQuickItem);
5034 return d->filtersChildMouseEvents;
5037 void QQuickItem::setFiltersChildMouseEvents(bool filter)
5040 d->filtersChildMouseEvents = filter;
5043 bool QQuickItem::isUnderMouse() const
5045 Q_D(const QQuickItem);
5049 QPointF cursorPos = QGuiApplicationPrivate::lastCursorPosition;
5050 return contains(mapFromScene(cursorPos)); // ### refactor: d->canvas->mapFromGlobal(cursorPos))))
5053 bool QQuickItem::acceptHoverEvents() const
5055 Q_D(const QQuickItem);
5056 return d->hoverEnabled;
5059 void QQuickItem::setAcceptHoverEvents(bool enabled)
5062 d->hoverEnabled = enabled;
5065 void QQuickItem::grabMouse()
5070 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
5071 if (canvasPriv->mouseGrabberItem == this)
5074 QQuickItem *oldGrabber = canvasPriv->mouseGrabberItem;
5075 canvasPriv->mouseGrabberItem = this;
5077 QEvent ev(QEvent::UngrabMouse);
5078 d->canvas->sendEvent(oldGrabber, &ev);
5082 void QQuickItem::ungrabMouse()
5087 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
5088 if (canvasPriv->mouseGrabberItem != this) {
5089 qWarning("QQuickItem::ungrabMouse(): Item is not the mouse grabber.");
5093 canvasPriv->mouseGrabberItem = 0;
5095 QEvent ev(QEvent::UngrabMouse);
5096 d->canvas->sendEvent(this, &ev);
5099 bool QQuickItem::keepMouseGrab() const
5101 Q_D(const QQuickItem);
5102 return d->keepMouse;
5106 The flag indicating whether the mouse should remain
5107 with this item is set to \a keep.
5109 This is useful for items that wish to grab and keep mouse
5110 interaction following a predefined gesture. For example,
5111 an item that is interested in horizontal mouse movement
5112 may set keepMouseGrab to true once a threshold has been
5113 exceeded. Once keepMouseGrab has been set to true, filtering
5114 items will not react to mouse events.
5116 If the item does not indicate that it wishes to retain mouse grab,
5117 a filtering item may steal the grab. For example, Flickable may attempt
5118 to steal a mouse grab if it detects that the user has begun to
5123 void QQuickItem::setKeepMouseGrab(bool keep)
5126 d->keepMouse = keep;
5130 Grabs the touch points specified by \a ids.
5132 These touch points will be owned by the item until
5133 they are released. Alternatively, the grab can be stolen
5134 by a filtering item like Flickable. Use setKeepTouchGrab()
5135 to prevent the grab from being stolen.
5137 \sa ungrabTouchPoints(), setKeepTouchGrab()
5139 void QQuickItem::grabTouchPoints(const QVector<int> &ids)
5144 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
5146 QSet<QQuickItem*> ungrab;
5147 for (int i = 0; i < ids.count(); ++i) {
5148 QQuickItem *oldGrabber = canvasPriv->itemForTouchPointId.value(ids.at(i));
5149 if (oldGrabber == this)
5152 canvasPriv->itemForTouchPointId[ids.at(i)] = this;
5154 ungrab.insert(oldGrabber);
5156 foreach (QQuickItem *oldGrabber, ungrab)
5157 oldGrabber->touchUngrabEvent();
5161 Ungrabs the touch points owned by this item.
5163 \sa grabTouchPoints()
5165 void QQuickItem::ungrabTouchPoints()
5170 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
5172 QMutableHashIterator<int, QQuickItem*> i(canvasPriv->itemForTouchPointId);
5173 while (i.hasNext()) {
5175 if (i.value() == this)
5182 Returns a value indicating whether the touch points grabbed by this item
5183 should remain with this item exclusively.
5185 \sa setKeepTouchGrab(), keepMouseGrab()
5187 bool QQuickItem::keepTouchGrab() const
5189 Q_D(const QQuickItem);
5190 return d->keepTouch;
5194 The flag indicating whether the touch points grabbed
5195 by this item should remain with this item is set to \a keep.
5197 This is useful for items that wish to grab and keep specific touch
5198 points following a predefined gesture. For example,
5199 an item that is interested in horizontal touch point movement
5200 may set setKeepTouchGrab to true once a threshold has been
5201 exceeded. Once setKeepTouchGrab has been set to true, filtering
5202 items will not react to the relevant touch points.
5204 If the item does not indicate that it wishes to retain touch point grab,
5205 a filtering item may steal the grab. For example, Flickable may attempt
5206 to steal a touch point grab if it detects that the user has begun to
5209 \sa keepTouchGrab(), setKeepMouseGrab()
5211 void QQuickItem::setKeepTouchGrab(bool keep)
5214 d->keepTouch = keep;
5218 Returns true if this item contains \a point, which is in local coordinates;
5219 returns false otherwise.
5221 This function can be overwritten in order to handle point collisions in items
5222 with custom shapes. The default implementation checks if the point is inside
5223 the item's bounding rect.
5225 Note that it's normally used to check if the item is under the mouse cursor,
5226 and for that reason, the implementation of this function should be as light-weight
5229 bool QQuickItem::contains(const QPointF &point) const
5231 Q_D(const QQuickItem);
5232 return QRectF(0, 0, d->width, d->height).contains(point);
5235 QPointF QQuickItem::mapToItem(const QQuickItem *item, const QPointF &point) const
5237 QPointF p = mapToScene(point);
5239 p = item->mapFromScene(p);
5243 QPointF QQuickItem::mapToScene(const QPointF &point) const
5245 Q_D(const QQuickItem);
5246 return d->itemToCanvasTransform().map(point);
5249 QRectF QQuickItem::mapRectToItem(const QQuickItem *item, const QRectF &rect) const
5251 Q_D(const QQuickItem);
5252 QTransform t = d->itemToCanvasTransform();
5254 t *= QQuickItemPrivate::get(item)->canvasToItemTransform();
5255 return t.mapRect(rect);
5258 QRectF QQuickItem::mapRectToScene(const QRectF &rect) const
5260 Q_D(const QQuickItem);
5261 return d->itemToCanvasTransform().mapRect(rect);
5264 QPointF QQuickItem::mapFromItem(const QQuickItem *item, const QPointF &point) const
5266 QPointF p = item?item->mapToScene(point):point;
5267 return mapFromScene(p);
5270 QPointF QQuickItem::mapFromScene(const QPointF &point) const
5272 Q_D(const QQuickItem);
5273 return d->canvasToItemTransform().map(point);
5276 QRectF QQuickItem::mapRectFromItem(const QQuickItem *item, const QRectF &rect) const
5278 Q_D(const QQuickItem);
5279 QTransform t = item?QQuickItemPrivate::get(item)->itemToCanvasTransform():QTransform();
5280 t *= d->canvasToItemTransform();
5281 return t.mapRect(rect);
5284 QRectF QQuickItem::mapRectFromScene(const QRectF &rect) const
5286 Q_D(const QQuickItem);
5287 return d->canvasToItemTransform().mapRect(rect);
5292 \qmlmethod QtQuick2::Item::forceActiveFocus()
5294 Forces active focus on the item.
5296 This method sets focus on the item and makes sure that all the focus scopes
5297 higher in the object hierarchy are also given the focus.
5301 Forces active focus on the item.
5303 This method sets focus on the item and makes sure that all the focus scopes
5304 higher in the object hierarchy are also given the focus.
5308 \qmlmethod QtQuick2::Item::childAt(real x, real y)
5310 Returns the visible child item at point (\a x, \a y), which is in this
5311 item's coordinate system, or \c null if there is no such item.
5315 Returns the visible child item at point (\a x, \a y), which is in this
5316 item's coordinate system, or 0 if there is no such item.
5320 \qmlproperty list<State> QtQuick2::Item::states
5321 This property holds a list of states defined by the item.
5337 \sa {qmlstate}{States}
5340 \qmlproperty list<Transition> QtQuick2::Item::transitions
5341 This property holds a list of transitions defined by the item.
5357 \sa {QML Animation and Transitions}{Transitions}
5360 \qmlproperty list<Filter> QtQuick2::Item::filter
5361 This property holds a list of graphical filters to be applied to the item.
5363 \l {Filter}{Filters} include things like \l {Blur}{blurring}
5364 the item, or giving it a \l Reflection. Some
5365 filters may not be available on all canvases; if a filter is not
5366 available on a certain canvas, it will simply not be applied for
5367 that canvas (but the QML will still be considered valid).
5385 \qmlproperty bool QtQuick2::Item::clip
5386 This property holds whether clipping is enabled. The default clip value is \c false.
5388 If clipping is enabled, an item will clip its own painting, as well
5389 as the painting of its children, to its bounding rectangle.
5391 Non-rectangular clipping regions are not supported for performance reasons.
5395 \property QQuickItem::clip
5396 This property holds whether clipping is enabled. The default clip value is \c false.
5398 If clipping is enabled, an item will clip its own painting, as well
5399 as the painting of its children, to its bounding rectangle. If you set
5400 clipping during an item's paint operation, remember to re-set it to
5401 prevent clipping the rest of your scene.
5403 Non-rectangular clipping regions are not supported for performance reasons.
5407 \qmlproperty string QtQuick2::Item::state
5409 This property holds the name of the current state of the item.
5411 This property is often used in scripts to change between states. For
5416 if (button.state == 'On')
5417 button.state = 'Off';
5419 button.state = 'On';
5423 If the item is in its base state (i.e. no explicit state has been
5424 set), \c state will be a blank string. Likewise, you can return an
5425 item to its base state by setting its current state to \c ''.
5427 \sa {qmlstates}{States}
5431 \qmlproperty list<Transform> QtQuick2::Item::transform
5432 This property holds the list of transformations to apply.
5434 For more information see \l Transform.
5438 \enum QQuickItem::TransformOrigin
5440 Controls the point about which simple transforms like scale apply.
5442 \value TopLeft The top-left corner of the item.
5443 \value Top The center point of the top of the item.
5444 \value TopRight The top-right corner of the item.
5445 \value Left The left most point of the vertical middle.
5446 \value Center The center of the item.
5447 \value Right The right most point of the vertical middle.
5448 \value BottomLeft The bottom-left corner of the item.
5449 \value Bottom The center point of the bottom of the item.
5450 \value BottomRight The bottom-right corner of the item.
5455 \qmlproperty bool QtQuick2::Item::activeFocus
5457 This property indicates whether the item has active focus.
5459 An item with active focus will receive keyboard input,
5460 or is a FocusScope ancestor of the item that will receive keyboard input.
5462 Usually, activeFocus is gained by setting focus on an item and its enclosing
5463 FocusScopes. In the following example \c input will have activeFocus.
5476 \sa focus, {qmlfocus}{Keyboard Focus}
5480 \qmlproperty bool QtQuick2::Item::focus
5481 This property indicates whether the item has focus within the enclosing focus scope. If true, this item
5482 will gain active focus when the enclosing focus scope gains active focus.
5483 In the following example, \c input will be given active focus when \c scope gains active focus.
5496 For the purposes of this property, the scene as a whole is assumed to act like a focus scope.
5497 On a practical level, that means the following QML will give active focus to \c input on startup.
5508 \sa activeFocus, {qmlfocus}{Keyboard Focus}
5513 \property QQuickItem::anchors
5518 \property QQuickItem::left
5523 \property QQuickItem::right
5528 \property QQuickItem::horizontalCenter
5533 \property QQuickItem::top
5538 \property QQuickItem::bottom
5543 \property QQuickItem::verticalCenter
5548 \property QQuickItem::focus
5553 \property QQuickItem::transform
5558 \property QQuickItem::transformOrigin
5563 \property QQuickItem::activeFocus
5568 \property QQuickItem::baseline
5573 \property QQuickItem::data
5578 \property QQuickItem::resources
5583 \property QQuickItem::state
5588 \property QQuickItem::states
5593 \property QQuickItem::transformOriginPoint
5598 \property QQuickItem::transitions
5602 bool QQuickItem::event(QEvent *ev)
5605 if (ev->type() == QEvent::PolishRequest) {
5607 d->polishScheduled = false;
5611 return QObject::event(ev);
5614 if (ev->type() == QEvent::InputMethodQuery) {
5615 QInputMethodQueryEvent *query = static_cast<QInputMethodQueryEvent *>(ev);
5616 Qt::InputMethodQueries queries = query->queries();
5617 for (uint i = 0; i < 32; ++i) {
5618 Qt::InputMethodQuery q = (Qt::InputMethodQuery)(int)(queries & (1<<i));
5620 QVariant v = inputMethodQuery(q);
5621 query->setValue(q, v);
5626 } else if (ev->type() == QEvent::InputMethod) {
5627 inputMethodEvent(static_cast<QInputMethodEvent *>(ev));
5630 return QObject::event(ev);
5633 #ifndef QT_NO_DEBUG_STREAM
5634 QDebug operator<<(QDebug debug, QQuickItem *item)
5637 debug << "QQuickItem(0)";
5641 debug << item->metaObject()->className() << "(this =" << ((void*)item)
5642 << ", name=" << item->objectName()
5643 << ", parent =" << ((void*)item->parentItem())
5644 << ", geometry =" << QRectF(item->pos(), QSizeF(item->width(), item->height()))
5645 << ", z =" << item->z() << ')';
5650 qint64 QQuickItemPrivate::consistentTime = -1;
5651 void QQuickItemPrivate::setConsistentTime(qint64 t)
5656 class QElapsedTimerConsistentTimeHack
5660 t1 = QQuickItemPrivate::consistentTime;
5664 return QQuickItemPrivate::consistentTime - t1;
5667 qint64 val = QQuickItemPrivate::consistentTime - t1;
5668 t1 = QQuickItemPrivate::consistentTime;
5678 void QQuickItemPrivate::start(QElapsedTimer &t)
5680 if (QQuickItemPrivate::consistentTime == -1)
5683 ((QElapsedTimerConsistentTimeHack*)&t)->start();
5686 qint64 QQuickItemPrivate::elapsed(QElapsedTimer &t)
5688 if (QQuickItemPrivate::consistentTime == -1)
5691 return ((QElapsedTimerConsistentTimeHack*)&t)->elapsed();
5694 qint64 QQuickItemPrivate::restart(QElapsedTimer &t)
5696 if (QQuickItemPrivate::consistentTime == -1)
5699 return ((QElapsedTimerConsistentTimeHack*)&t)->restart();
5703 \fn bool QQuickItem::isTextureProvider() const
5705 Returns true if this item is a texture provider. The default
5706 implementation returns false.
5708 This function can be called from any thread.
5711 bool QQuickItem::isTextureProvider() const
5713 Q_D(const QQuickItem);
5714 return d->extra.isAllocated() && d->extra->layer && d->extra->layer->effectSource() ?
5715 d->extra->layer->effectSource()->isTextureProvider() : false;
5719 \fn QSGTextureProvider *QQuickItem::textureProvider() const
5721 Returns the texture provider for an item. The default implementation
5724 This function may only be called on the rendering thread.
5727 QSGTextureProvider *QQuickItem::textureProvider() const
5729 Q_D(const QQuickItem);
5730 return d->extra.isAllocated() && d->extra->layer && d->extra->layer->effectSource() ?
5731 d->extra->layer->effectSource()->textureProvider() : 0;
5734 QQuickItemLayer *QQuickItemPrivate::layer() const
5736 if (!extra.isAllocated() || !extra->layer) {
5737 extra.value().layer = new QQuickItemLayer(const_cast<QQuickItem *>(q_func()));
5738 if (!componentComplete)
5739 extra->layer->classBegin();
5741 return extra->layer;
5744 QQuickItemLayer::QQuickItemLayer(QQuickItem *item)
5749 , m_componentComplete(true)
5750 , m_wrapMode(QQuickShaderEffectSource::ClampToEdge)
5751 , m_format(QQuickShaderEffectSource::RGBA)
5753 , m_effectComponent(0)
5759 QQuickItemLayer::~QQuickItemLayer()
5761 delete m_effectSource;
5768 \qmlproperty bool QtQuick2::Item::layer.enabled
5770 Holds wether the item is layered or not. Layering is disabled by default.
5772 A layered item is rendered into an offscreen surface and cached until
5773 it is changed. Enabling layering for complex QML item hierarchies can
5774 some times be an optimization.
5776 None of the other layer properties have any effect when the layer
5780 void QQuickItemLayer::setEnabled(bool e)
5785 if (m_componentComplete) {
5792 emit enabledChanged(e);
5795 void QQuickItemLayer::classBegin()
5797 Q_ASSERT(!m_effectSource);
5798 Q_ASSERT(!m_effect);
5799 m_componentComplete = false;
5802 void QQuickItemLayer::componentComplete()
5804 Q_ASSERT(!m_componentComplete);
5805 m_componentComplete = true;
5810 void QQuickItemLayer::activate()
5812 Q_ASSERT(!m_effectSource);
5813 m_effectSource = new QQuickShaderEffectSource();
5815 QQuickItem *parentItem = m_item->parentItem();
5817 m_effectSource->setParentItem(parentItem);
5818 m_effectSource->stackAfter(m_item);
5821 m_effectSource->setSourceItem(m_item);
5822 m_effectSource->setHideSource(true);
5823 m_effectSource->setSmooth(m_smooth);
5824 m_effectSource->setTextureSize(m_size);
5825 m_effectSource->setSourceRect(m_sourceRect);
5826 m_effectSource->setMipmap(m_mipmap);
5827 m_effectSource->setWrapMode(m_wrapMode);
5828 m_effectSource->setFormat(m_format);
5830 if (m_effectComponent)
5833 m_effectSource->setVisible(m_item->isVisible() && !m_effect);
5840 QQuickItemPrivate *id = QQuickItemPrivate::get(m_item);
5841 id->addItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Opacity | QQuickItemPrivate::Parent | QQuickItemPrivate::Visibility | QQuickItemPrivate::SiblingOrder);
5844 void QQuickItemLayer::deactivate()
5846 Q_ASSERT(m_effectSource);
5848 if (m_effectComponent)
5851 delete m_effectSource;
5854 QQuickItemPrivate *id = QQuickItemPrivate::get(m_item);
5855 id->removeItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Opacity | QQuickItemPrivate::Parent | QQuickItemPrivate::Visibility | QQuickItemPrivate::SiblingOrder);
5858 void QQuickItemLayer::activateEffect()
5860 Q_ASSERT(m_effectSource);
5861 Q_ASSERT(m_effectComponent);
5862 Q_ASSERT(!m_effect);
5864 QObject *created = m_effectComponent->beginCreate(m_effectComponent->creationContext());
5865 m_effect = qobject_cast<QQuickItem *>(created);
5867 qWarning("Item: layer.effect is not a QML Item.");
5868 m_effectComponent->completeCreate();
5872 QQuickItem *parentItem = m_item->parentItem();
5874 m_effect->setParentItem(parentItem);
5875 m_effect->stackAfter(m_effectSource);
5877 m_effect->setVisible(m_item->isVisible());
5878 m_effect->setProperty(m_name, qVariantFromValue<QObject *>(m_effectSource));
5879 m_effectComponent->completeCreate();
5882 void QQuickItemLayer::deactivateEffect()
5884 Q_ASSERT(m_effectSource);
5885 Q_ASSERT(m_effectComponent);
5893 \qmlproperty Component QtQuick2::Item::layer.effect
5895 Holds the effect that is applied to this layer.
5897 The effect is typically a \l ShaderEffect component, although any \l Item component can be
5898 assigned. The effect should have a source texture property with a name matching \l samplerName.
5903 void QQuickItemLayer::setEffect(QQmlComponent *component)
5905 if (component == m_effectComponent)
5908 bool updateNeeded = false;
5909 if (m_effectSource && m_effectComponent) {
5911 updateNeeded = true;
5914 m_effectComponent = component;
5916 if (m_effectSource && m_effectComponent) {
5918 updateNeeded = true;
5926 m_effectSource->setVisible(m_item->isVisible() && !m_effect);
5929 emit effectChanged(component);
5934 \qmlproperty bool QtQuick2::Item::layer.mipmap
5936 If this property is true, mipmaps are generated for the texture.
5938 \note Some OpenGL ES 2 implementations do not support mipmapping of
5939 non-power-of-two textures.
5942 void QQuickItemLayer::setMipmap(bool mipmap)
5944 if (mipmap == m_mipmap)
5949 m_effectSource->setMipmap(m_mipmap);
5951 emit mipmapChanged(mipmap);
5956 \qmlproperty enumeration QtQuick2::Item::layer.format
5958 This property defines the internal OpenGL format of the texture.
5959 Modifying this property makes most sense when the \a layer.effect is also
5960 specified. Depending on the OpenGL implementation, this property might
5961 allow you to save some texture memory.
5964 \li ShaderEffectSource.Alpha - GL_ALPHA
5965 \li ShaderEffectSource.RGB - GL_RGB
5966 \li ShaderEffectSource.RGBA - GL_RGBA
5969 \note Some OpenGL implementations do not support the GL_ALPHA format.
5972 void QQuickItemLayer::setFormat(QQuickShaderEffectSource::Format f)
5979 m_effectSource->setFormat(m_format);
5981 emit formatChanged(m_format);
5986 \qmlproperty enumeration QtQuick2::Item::layer.sourceRect
5988 This property defines which rectangular area of the \l sourceItem to
5989 render into the texture. The source rectangle can be larger than
5990 \l sourceItem itself. If the rectangle is null, which is the default,
5991 the whole \l sourceItem is rendered to texture.
5994 void QQuickItemLayer::setSourceRect(const QRectF &sourceRect)
5996 if (sourceRect == m_sourceRect)
5998 m_sourceRect = sourceRect;
6001 m_effectSource->setSourceRect(m_sourceRect);
6003 emit sourceRectChanged(sourceRect);
6009 \qmlproperty bool QtQuick2::Item::layer.smooth
6011 Holds whether the layer is smoothly transformed.
6014 void QQuickItemLayer::setSmooth(bool s)
6021 m_effectSource->setSmooth(m_smooth);
6023 emit smoothChanged(s);
6029 \qmlproperty size QtQuick2::Item::layer.textureSize
6031 This property holds the requested pixel size of the layers texture. If it is empty,
6032 which is the default, the size of the item is used.
6034 \note Some platforms have a limit on how small framebuffer objects can be,
6035 which means the actual texture size might be larger than the requested
6039 void QQuickItemLayer::setSize(const QSize &size)
6046 m_effectSource->setTextureSize(size);
6048 emit sizeChanged(size);
6054 \qmlproperty enumeration QtQuick2::Item::layer.wrapMode
6056 This property defines the OpenGL wrap modes associated with the texture.
6057 Modifying this property makes most sense when the \a layer.effect is
6061 \li ShaderEffectSource.ClampToEdge - GL_CLAMP_TO_EDGE both horizontally and vertically
6062 \li ShaderEffectSource.RepeatHorizontally - GL_REPEAT horizontally, GL_CLAMP_TO_EDGE vertically
6063 \li ShaderEffectSource.RepeatVertically - GL_CLAMP_TO_EDGE horizontally, GL_REPEAT vertically
6064 \li ShaderEffectSource.Repeat - GL_REPEAT both horizontally and vertically
6067 \note Some OpenGL ES 2 implementations do not support the GL_REPEAT
6068 wrap mode with non-power-of-two textures.
6071 void QQuickItemLayer::setWrapMode(QQuickShaderEffectSource::WrapMode mode)
6073 if (mode == m_wrapMode)
6078 m_effectSource->setWrapMode(m_wrapMode);
6080 emit wrapModeChanged(mode);
6084 \qmlproperty string QtQuick2::Item::layer.samplerName
6086 Holds the name of the effect's source texture property.
6088 samplerName needs to match the name of the effect's source texture property
6089 so that the Item can pass the layer's offscreen surface to the effect correctly.
6091 \sa effect, ShaderEffect
6094 void QQuickItemLayer::setName(const QByteArray &name) {
6098 m_effect->setProperty(m_name, QVariant());
6099 m_effect->setProperty(name, qVariantFromValue<QObject *>(m_effectSource));
6102 emit nameChanged(name);
6105 void QQuickItemLayer::itemOpacityChanged(QQuickItem *item)
6111 void QQuickItemLayer::itemGeometryChanged(QQuickItem *, const QRectF &, const QRectF &)
6116 void QQuickItemLayer::itemParentChanged(QQuickItem *item, QQuickItem *parent)
6119 Q_ASSERT(item == m_item);
6120 Q_ASSERT(parent != m_effectSource);
6121 Q_ASSERT(parent == 0 || parent != m_effect);
6123 m_effectSource->setParentItem(parent);
6125 m_effectSource->stackAfter(m_item);
6128 m_effect->setParentItem(parent);
6130 m_effect->stackAfter(m_effectSource);
6134 void QQuickItemLayer::itemSiblingOrderChanged(QQuickItem *)
6136 m_effectSource->stackAfter(m_item);
6138 m_effect->stackAfter(m_effectSource);
6141 void QQuickItemLayer::itemVisibilityChanged(QQuickItem *)
6143 QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
6145 l->setVisible(m_item->isVisible());
6148 void QQuickItemLayer::updateZ()
6150 if (!m_componentComplete || !m_enabled)
6152 QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
6154 l->setZ(m_item->z());
6157 void QQuickItemLayer::updateOpacity()
6159 QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
6161 l->setOpacity(m_item->opacity());
6164 void QQuickItemLayer::updateGeometry()
6166 QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
6168 QRectF bounds = m_item->clipRect();
6169 l->setWidth(bounds.width());
6170 l->setHeight(bounds.height());
6171 l->setX(bounds.x() + m_item->x());
6172 l->setY(bounds.y() + m_item->y());
6175 void QQuickItemLayer::updateMatrix()
6177 // Called directly from transformChanged(), so needs some extra
6179 if (!m_componentComplete || !m_enabled)
6181 QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
6183 QQuickItemPrivate *ld = QQuickItemPrivate::get(l);
6184 l->setScale(m_item->scale());
6185 l->setRotation(m_item->rotation());
6186 ld->transforms = QQuickItemPrivate::get(m_item)->transforms;
6187 if (ld->origin() != QQuickItemPrivate::get(m_item)->origin())
6188 ld->extra.value().origin = QQuickItemPrivate::get(m_item)->origin();
6189 ld->dirty(QQuickItemPrivate::Transform);
6192 QQuickItemPrivate::ExtraData::ExtraData()
6193 : z(0), scale(1), rotation(0), opacity(1),
6194 contents(0), screenAttached(0), layoutDirectionAttached(0),
6195 keyHandler(0), layer(0), effectRefCount(0), hideRefCount(0),
6196 opacityNode(0), clipNode(0), rootNode(0), beforePaintNode(0),
6197 acceptedMouseButtons(0), origin(QQuickItem::Center)
6203 #include <moc_qquickitem.cpp>