1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the QtQml module of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #include "qquickitem.h"
44 #include "qquickcanvas.h"
45 #include <QtQml/qjsengine.h>
46 #include "qquickcanvas_p.h"
48 #include "qquickevents_p_p.h"
49 #include "qquickscreen_p.h"
51 #include <QtQml/qqmlengine.h>
52 #include <QtQml/qqmlcomponent.h>
53 #include <QtQml/qqmlinfo.h>
54 #include <QtGui/qpen.h>
55 #include <QtGui/qguiapplication.h>
56 #include <QtGui/private/qguiapplication_p.h>
57 #include <QtGui/qinputmethod.h>
58 #include <QtCore/qdebug.h>
59 #include <QtCore/qcoreevent.h>
60 #include <QtCore/qnumeric.h>
62 #include <private/qqmlglobal_p.h>
63 #include <private/qqmlengine_p.h>
64 #include <QtQuick/private/qquickstategroup_p.h>
65 #include <private/qqmlopenmetaobject_p.h>
66 #include <QtQuick/private/qquickstate_p.h>
67 #include <private/qlistmodelinterface_p.h>
68 #include <private/qquickitem_p.h>
69 #include <private/qqmlaccessors_p.h>
70 #include <QtQuick/private/qquickaccessibleattached_p.h>
74 // XXX todo Check that elements that create items handle memory correctly after visual ownership change
79 void printFocusTree(QQuickItem *item, QQuickItem *scope = 0, int depth = 1);
80 void printFocusTree(QQuickItem *item, QQuickItem *scope, int depth)
83 << QByteArray(depth, '\t').constData()
84 << (scope && QQuickItemPrivate::get(scope)->subFocusItem == item ? '*' : ' ')
86 << item->hasActiveFocus()
87 << item->isFocusScope()
89 foreach (QQuickItem *child, item->childItems()) {
92 item->isFocusScope() || !scope ? item : scope,
93 item->isFocusScope() || !scope ? depth + 1 : depth);
98 static void QQuickItem_parentNotifier(QObject *o, intptr_t, QQmlNotifier **n)
100 QQuickItemPrivate *d = QQuickItemPrivate::get(static_cast<QQuickItem *>(o));
101 *n = &d->parentNotifier;
104 QML_PRIVATE_ACCESSOR(QQuickItem, QQuickItem *, parent, parentItem)
105 QML_PRIVATE_ACCESSOR(QQuickItem, qreal, x, x)
106 QML_PRIVATE_ACCESSOR(QQuickItem, qreal, y, y)
107 QML_PRIVATE_ACCESSOR(QQuickItem, qreal, width, width)
108 QML_PRIVATE_ACCESSOR(QQuickItem, qreal, height, height)
110 static QQmlAccessors QQuickItem_parent = { QQuickItem_parentRead, QQuickItem_parentNotifier };
111 static QQmlAccessors QQuickItem_x = { QQuickItem_xRead, 0 };
112 static QQmlAccessors QQuickItem_y = { QQuickItem_yRead, 0 };
113 static QQmlAccessors QQuickItem_width = { QQuickItem_widthRead, 0 };
114 static QQmlAccessors QQuickItem_height = { QQuickItem_heightRead, 0 };
116 QML_DECLARE_PROPERTIES(QQuickItem) {
117 { QML_PROPERTY_NAME(parent), 0, &QQuickItem_parent },
118 { QML_PROPERTY_NAME(x), 0, &QQuickItem_x },
119 { QML_PROPERTY_NAME(y), 0, &QQuickItem_y },
120 { QML_PROPERTY_NAME(width), 0, &QQuickItem_width },
121 { QML_PROPERTY_NAME(height), 0, &QQuickItem_height }
124 void QQuickItemPrivate::registerAccessorProperties()
126 QML_DEFINE_PROPERTIES(QQuickItem);
130 \qmlclass Transform QQuickTransform
131 \inqmlmodule QtQuick 2
132 \ingroup qml-transform-elements
133 \brief The Transform elements provide a way of building advanced transformations on Items.
135 The Transform element is a base type which cannot be instantiated directly.
136 The following concrete Transform types are available:
144 The Transform elements let you create and control advanced transformations that can be configured
145 independently using specialized properties.
147 You can assign any number of Transform elements to an \l Item. Each Transform is applied in order,
152 \qmlclass Translate QQuickTranslate
153 \inqmlmodule QtQuick 2
154 \ingroup qml-transform-elements
155 \brief The Translate object provides a way to move an Item without changing its x or y properties.
157 The Translate object provides independent control over position in addition to the Item's x and y properties.
159 The following example moves the Y axis of the \l Rectangle elements while still allowing the \l Row element
160 to lay the items out as if they had not been transformed:
166 width: 100; height: 100
168 transform: Translate { y: 20 }
171 width: 100; height: 100
173 transform: Translate { y: -20 }
182 \qmlproperty real QtQuick2::Translate::x
184 The translation along the X axis.
188 \qmlproperty real QtQuick2::Translate::y
190 The translation along the Y axis.
194 \qmlclass Scale QQuickScale
195 \inqmlmodule QtQuick 2
196 \ingroup qml-transform-elements
197 \brief The Scale element provides a way to scale an Item.
199 The Scale element gives more control over scaling than using \l Item's \l{Item::scale}{scale} property. Specifically,
200 it allows a different scale for the x and y axes, and allows the scale to be relative to an
203 The following example scales the X axis of the Rectangle, relative to its interior point 25, 25:
206 width: 100; height: 100
208 transform: Scale { origin.x: 25; origin.y: 25; xScale: 3}
212 \sa Rotation, Translate
216 \qmlproperty real QtQuick2::Scale::origin.x
217 \qmlproperty real QtQuick2::Scale::origin.y
219 The point that the item is scaled from (i.e., the point that stays fixed relative to the parent as
220 the rest of the item grows). By default the origin is 0, 0.
224 \qmlproperty real QtQuick2::Scale::xScale
226 The scaling factor for the X axis.
230 \qmlproperty real QtQuick2::Scale::yScale
232 The scaling factor for the Y axis.
236 \qmlclass Rotation QQuickRotation
237 \inqmlmodule QtQuick 2
238 \ingroup qml-transform-elements
239 \brief The Rotation object provides a way to rotate an Item.
241 The Rotation object gives more control over rotation than using \l Item's \l{Item::rotation}{rotation} property.
242 Specifically, it allows (z axis) rotation to be relative to an arbitrary point.
244 The following example rotates a Rectangle around its interior point 25, 25:
247 width: 100; height: 100
249 transform: Rotation { origin.x: 25; origin.y: 25; angle: 45}
253 Rotation also provides a way to specify 3D-like rotations for Items. For these types of
254 rotations you must specify the axis to rotate around in addition to the origin point.
256 The following example shows various 3D-like rotations applied to an \l Image.
257 \snippet doc/src/snippets/qml/rotation.qml 0
259 \image axisrotation.png
261 \sa {declarative/ui-components/dialcontrol}{Dial Control example}, {declarative/toys/clocks}{Clocks example}
265 \qmlproperty real QtQuick2::Rotation::origin.x
266 \qmlproperty real QtQuick2::Rotation::origin.y
268 The origin point of the rotation (i.e., the point that stays fixed relative to the parent as
269 the rest of the item rotates). By default the origin is 0, 0.
273 \qmlproperty real QtQuick2::Rotation::axis.x
274 \qmlproperty real QtQuick2::Rotation::axis.y
275 \qmlproperty real QtQuick2::Rotation::axis.z
277 The axis to rotate around. For simple (2D) rotation around a point, you do not need to specify an axis,
278 as the default axis is the z axis (\c{ axis { x: 0; y: 0; z: 1 } }).
280 For a typical 3D-like rotation you will usually specify both the origin and the axis.
282 \image 3d-rotation-axis.png
286 \qmlproperty real QtQuick2::Rotation::angle
288 The angle to rotate, in degrees clockwise.
291 QQuickTransformPrivate::QQuickTransformPrivate()
295 QQuickTransform::QQuickTransform(QObject *parent)
296 : QObject(*(new QQuickTransformPrivate), parent)
300 QQuickTransform::QQuickTransform(QQuickTransformPrivate &dd, QObject *parent)
301 : QObject(dd, parent)
305 QQuickTransform::~QQuickTransform()
307 Q_D(QQuickTransform);
308 for (int ii = 0; ii < d->items.count(); ++ii) {
309 QQuickItemPrivate *p = QQuickItemPrivate::get(d->items.at(ii));
310 p->transforms.removeOne(this);
311 p->dirty(QQuickItemPrivate::Transform);
315 void QQuickTransform::update()
317 Q_D(QQuickTransform);
318 for (int ii = 0; ii < d->items.count(); ++ii) {
319 QQuickItemPrivate *p = QQuickItemPrivate::get(d->items.at(ii));
320 p->dirty(QQuickItemPrivate::Transform);
324 QQuickContents::QQuickContents(QQuickItem *item)
325 : m_item(item), m_x(0), m_y(0), m_width(0), m_height(0)
329 QQuickContents::~QQuickContents()
331 QList<QQuickItem *> children = m_item->childItems();
332 for (int i = 0; i < children.count(); ++i) {
333 QQuickItem *child = children.at(i);
334 QQuickItemPrivate::get(child)->removeItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed);
338 bool QQuickContents::calcHeight(QQuickItem *changed)
341 qreal oldheight = m_height;
345 qreal bottom = oldy + oldheight;
346 qreal y = changed->y();
347 if (y + changed->height() > bottom)
348 bottom = y + changed->height();
352 m_height = bottom - top;
356 QList<QQuickItem *> children = m_item->childItems();
357 for (int i = 0; i < children.count(); ++i) {
358 QQuickItem *child = children.at(i);
359 qreal y = child->y();
360 if (y + child->height() > bottom)
361 bottom = y + child->height();
365 if (!children.isEmpty())
367 m_height = qMax(bottom - top, qreal(0.0));
370 return (m_height != oldheight || m_y != oldy);
373 bool QQuickContents::calcWidth(QQuickItem *changed)
376 qreal oldwidth = m_width;
380 qreal right = oldx + oldwidth;
381 qreal x = changed->x();
382 if (x + changed->width() > right)
383 right = x + changed->width();
387 m_width = right - left;
389 qreal left = FLT_MAX;
391 QList<QQuickItem *> children = m_item->childItems();
392 for (int i = 0; i < children.count(); ++i) {
393 QQuickItem *child = children.at(i);
394 qreal x = child->x();
395 if (x + child->width() > right)
396 right = x + child->width();
400 if (!children.isEmpty())
402 m_width = qMax(right - left, qreal(0.0));
405 return (m_width != oldwidth || m_x != oldx);
408 void QQuickContents::complete()
410 QQuickItemPrivate::get(m_item)->addItemChangeListener(this, QQuickItemPrivate::Children);
412 QList<QQuickItem *> children = m_item->childItems();
413 for (int i = 0; i < children.count(); ++i) {
414 QQuickItem *child = children.at(i);
415 QQuickItemPrivate::get(child)->addItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed);
416 //###what about changes to visibility?
421 void QQuickContents::updateRect()
423 QQuickItemPrivate::get(m_item)->emitChildrenRectChanged(rectF());
426 void QQuickContents::itemGeometryChanged(QQuickItem *changed, const QRectF &newGeometry, const QRectF &oldGeometry)
429 bool wChanged = false;
430 bool hChanged = false;
431 //### we can only pass changed if the left edge has moved left, or the right edge has moved right
432 if (newGeometry.width() != oldGeometry.width() || newGeometry.x() != oldGeometry.x())
433 wChanged = calcWidth(/*changed*/);
434 if (newGeometry.height() != oldGeometry.height() || newGeometry.y() != oldGeometry.y())
435 hChanged = calcHeight(/*changed*/);
436 if (wChanged || hChanged)
440 void QQuickContents::itemDestroyed(QQuickItem *item)
443 QQuickItemPrivate::get(item)->removeItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed);
447 void QQuickContents::itemChildRemoved(QQuickItem *, QQuickItem *item)
450 QQuickItemPrivate::get(item)->removeItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed);
454 void QQuickContents::itemChildAdded(QQuickItem *, QQuickItem *item)
457 QQuickItemPrivate::get(item)->addItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed);
461 QQuickItemKeyFilter::QQuickItemKeyFilter(QQuickItem *item)
462 : m_processPost(false), m_next(0)
464 QQuickItemPrivate *p = item?QQuickItemPrivate::get(item):0;
466 m_next = p->extra.value().keyHandler;
467 p->extra->keyHandler = this;
471 QQuickItemKeyFilter::~QQuickItemKeyFilter()
475 void QQuickItemKeyFilter::keyPressed(QKeyEvent *event, bool post)
477 if (m_next) m_next->keyPressed(event, post);
480 void QQuickItemKeyFilter::keyReleased(QKeyEvent *event, bool post)
482 if (m_next) m_next->keyReleased(event, post);
485 void QQuickItemKeyFilter::inputMethodEvent(QInputMethodEvent *event, bool post)
488 m_next->inputMethodEvent(event, post);
493 QVariant QQuickItemKeyFilter::inputMethodQuery(Qt::InputMethodQuery query) const
495 if (m_next) return m_next->inputMethodQuery(query);
499 void QQuickItemKeyFilter::componentComplete()
501 if (m_next) m_next->componentComplete();
504 \qmlclass KeyNavigation QQuickKeyNavigationAttached
505 \inqmlmodule QtQuick 2
506 \ingroup qml-basic-interaction-elements
507 \brief The KeyNavigation attached property supports key navigation by arrow keys.
509 Key-based user interfaces commonly allow the use of arrow keys to navigate between
510 focusable items. The KeyNavigation attached property enables this behavior by providing a
511 convenient way to specify the item that should gain focus when an arrow or tab key is pressed.
513 The following example provides key navigation for a 2x2 grid of items:
515 \snippet doc/src/snippets/qml/keynavigation.qml 0
517 The top-left item initially receives focus by setting \l {Item::}{focus} to
518 \c true. When an arrow key is pressed, the focus will move to the
519 appropriate item, as defined by the value that has been set for
520 the KeyNavigation \l left, \l right, \l up or \l down properties.
522 Note that if a KeyNavigation attached property receives the key press and release
523 events for a requested arrow or tab key, the event is accepted and does not
524 propagate any further.
526 By default, KeyNavigation receives key events after the item to which it is attached.
527 If the item accepts the key event, the KeyNavigation attached property will not
528 receive an event for that key. Setting the \l priority property to
529 \c KeyNavigation.BeforeItem allows the event to be used for key navigation
530 before the item, rather than after.
532 If item to which the focus is switching is not enabled or visible, an attempt will
533 be made to skip this item and focus on the next. This is possible if there are
534 a chain of items with the same KeyNavigation handler. If multiple items in a row are not enabled
535 or visible, they will also be skipped.
537 KeyNavigation will implicitly set the other direction to return focus to this item. So if you set
538 \l left to another item, \l right will be set on that item's KeyNavigation to set focus back to this
539 item. However, if that item's KeyNavigation has had right explicitly set then no change will occur.
540 This means that the above example could have been written, with the same behaviour, without specifing
541 KeyNavigation.right or KeyNavigation.down for any of the items.
543 \sa {Keys}{Keys attached property}
547 \qmlproperty Item QtQuick2::KeyNavigation::left
548 \qmlproperty Item QtQuick2::KeyNavigation::right
549 \qmlproperty Item QtQuick2::KeyNavigation::up
550 \qmlproperty Item QtQuick2::KeyNavigation::down
551 \qmlproperty Item QtQuick2::KeyNavigation::tab
552 \qmlproperty Item QtQuick2::KeyNavigation::backtab
554 These properties hold the item to assign focus to
555 when the left, right, up or down cursor keys, or the
560 \qmlproperty Item QtQuick2::KeyNavigation::tab
561 \qmlproperty Item QtQuick2::KeyNavigation::backtab
563 These properties hold the item to assign focus to
564 when the Tab key or Shift+Tab key combination (Backtab) are pressed.
567 QQuickKeyNavigationAttached::QQuickKeyNavigationAttached(QObject *parent)
568 : QObject(*(new QQuickKeyNavigationAttachedPrivate), parent),
569 QQuickItemKeyFilter(qobject_cast<QQuickItem*>(parent))
571 m_processPost = true;
574 QQuickKeyNavigationAttached *
575 QQuickKeyNavigationAttached::qmlAttachedProperties(QObject *obj)
577 return new QQuickKeyNavigationAttached(obj);
580 QQuickItem *QQuickKeyNavigationAttached::left() const
582 Q_D(const QQuickKeyNavigationAttached);
586 void QQuickKeyNavigationAttached::setLeft(QQuickItem *i)
588 Q_D(QQuickKeyNavigationAttached);
593 QQuickKeyNavigationAttached* other =
594 qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
595 if (other && !other->d_func()->rightSet){
596 other->d_func()->right = qobject_cast<QQuickItem*>(parent());
597 emit other->rightChanged();
602 QQuickItem *QQuickKeyNavigationAttached::right() const
604 Q_D(const QQuickKeyNavigationAttached);
608 void QQuickKeyNavigationAttached::setRight(QQuickItem *i)
610 Q_D(QQuickKeyNavigationAttached);
615 QQuickKeyNavigationAttached* other =
616 qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
617 if (other && !other->d_func()->leftSet){
618 other->d_func()->left = qobject_cast<QQuickItem*>(parent());
619 emit other->leftChanged();
624 QQuickItem *QQuickKeyNavigationAttached::up() const
626 Q_D(const QQuickKeyNavigationAttached);
630 void QQuickKeyNavigationAttached::setUp(QQuickItem *i)
632 Q_D(QQuickKeyNavigationAttached);
637 QQuickKeyNavigationAttached* other =
638 qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
639 if (other && !other->d_func()->downSet){
640 other->d_func()->down = qobject_cast<QQuickItem*>(parent());
641 emit other->downChanged();
646 QQuickItem *QQuickKeyNavigationAttached::down() const
648 Q_D(const QQuickKeyNavigationAttached);
652 void QQuickKeyNavigationAttached::setDown(QQuickItem *i)
654 Q_D(QQuickKeyNavigationAttached);
659 QQuickKeyNavigationAttached* other =
660 qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
661 if (other && !other->d_func()->upSet) {
662 other->d_func()->up = qobject_cast<QQuickItem*>(parent());
663 emit other->upChanged();
668 QQuickItem *QQuickKeyNavigationAttached::tab() const
670 Q_D(const QQuickKeyNavigationAttached);
674 void QQuickKeyNavigationAttached::setTab(QQuickItem *i)
676 Q_D(QQuickKeyNavigationAttached);
681 QQuickKeyNavigationAttached* other =
682 qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
683 if (other && !other->d_func()->backtabSet) {
684 other->d_func()->backtab = qobject_cast<QQuickItem*>(parent());
685 emit other->backtabChanged();
690 QQuickItem *QQuickKeyNavigationAttached::backtab() const
692 Q_D(const QQuickKeyNavigationAttached);
696 void QQuickKeyNavigationAttached::setBacktab(QQuickItem *i)
698 Q_D(QQuickKeyNavigationAttached);
702 d->backtabSet = true;
703 QQuickKeyNavigationAttached* other =
704 qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
705 if (other && !other->d_func()->tabSet) {
706 other->d_func()->tab = qobject_cast<QQuickItem*>(parent());
707 emit other->tabChanged();
709 emit backtabChanged();
713 \qmlproperty enumeration QtQuick2::KeyNavigation::priority
715 This property determines whether the keys are processed before
716 or after the attached item's own key handling.
719 \li KeyNavigation.BeforeItem - process the key events before normal
720 item key processing. If the event is used for key navigation, it will be accepted and will not
721 be passed on to the item.
722 \li KeyNavigation.AfterItem (default) - process the key events after normal item key
723 handling. If the item accepts the key event it will not be
724 handled by the KeyNavigation attached property handler.
727 QQuickKeyNavigationAttached::Priority QQuickKeyNavigationAttached::priority() const
729 return m_processPost ? AfterItem : BeforeItem;
732 void QQuickKeyNavigationAttached::setPriority(Priority order)
734 bool processPost = order == AfterItem;
735 if (processPost != m_processPost) {
736 m_processPost = processPost;
737 emit priorityChanged();
741 void QQuickKeyNavigationAttached::keyPressed(QKeyEvent *event, bool post)
743 Q_D(QQuickKeyNavigationAttached);
746 if (post != m_processPost) {
747 QQuickItemKeyFilter::keyPressed(event, post);
752 switch (event->key()) {
754 if (QQuickItem *parentItem = qobject_cast<QQuickItem*>(parent()))
755 mirror = QQuickItemPrivate::get(parentItem)->effectiveLayoutMirror;
756 QQuickItem* leftItem = mirror ? d->right : d->left;
758 setFocusNavigation(leftItem, mirror ? "right" : "left");
763 case Qt::Key_Right: {
764 if (QQuickItem *parentItem = qobject_cast<QQuickItem*>(parent()))
765 mirror = QQuickItemPrivate::get(parentItem)->effectiveLayoutMirror;
766 QQuickItem* rightItem = mirror ? d->left : d->right;
768 setFocusNavigation(rightItem, mirror ? "left" : "right");
775 setFocusNavigation(d->up, "up");
781 setFocusNavigation(d->down, "down");
787 setFocusNavigation(d->tab, "tab");
791 case Qt::Key_Backtab:
793 setFocusNavigation(d->backtab, "backtab");
801 if (!event->isAccepted()) QQuickItemKeyFilter::keyPressed(event, post);
804 void QQuickKeyNavigationAttached::keyReleased(QKeyEvent *event, bool post)
806 Q_D(QQuickKeyNavigationAttached);
809 if (post != m_processPost) {
810 QQuickItemKeyFilter::keyReleased(event, post);
815 switch (event->key()) {
817 if (QQuickItem *parentItem = qobject_cast<QQuickItem*>(parent()))
818 mirror = QQuickItemPrivate::get(parentItem)->effectiveLayoutMirror;
819 if (mirror ? d->right : d->left)
823 if (QQuickItem *parentItem = qobject_cast<QQuickItem*>(parent()))
824 mirror = QQuickItemPrivate::get(parentItem)->effectiveLayoutMirror;
825 if (mirror ? d->left : d->right)
843 case Qt::Key_Backtab:
852 if (!event->isAccepted()) QQuickItemKeyFilter::keyReleased(event, post);
855 void QQuickKeyNavigationAttached::setFocusNavigation(QQuickItem *currentItem, const char *dir)
857 QQuickItem *initialItem = currentItem;
858 bool isNextItem = false;
861 if (currentItem->isVisible() && currentItem->isEnabled()) {
862 currentItem->setFocus(true);
865 qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(currentItem, false);
867 QQuickItem *tempItem = qvariant_cast<QQuickItem*>(attached->property(dir));
869 currentItem = tempItem;
875 while (currentItem != initialItem && isNextItem);
878 const QQuickKeysAttached::SigMap QQuickKeysAttached::sigMap[] = {
879 { Qt::Key_Left, "leftPressed" },
880 { Qt::Key_Right, "rightPressed" },
881 { Qt::Key_Up, "upPressed" },
882 { Qt::Key_Down, "downPressed" },
883 { Qt::Key_Tab, "tabPressed" },
884 { Qt::Key_Backtab, "backtabPressed" },
885 { Qt::Key_Asterisk, "asteriskPressed" },
886 { Qt::Key_NumberSign, "numberSignPressed" },
887 { Qt::Key_Escape, "escapePressed" },
888 { Qt::Key_Return, "returnPressed" },
889 { Qt::Key_Enter, "enterPressed" },
890 { Qt::Key_Delete, "deletePressed" },
891 { Qt::Key_Space, "spacePressed" },
892 { Qt::Key_Back, "backPressed" },
893 { Qt::Key_Cancel, "cancelPressed" },
894 { Qt::Key_Select, "selectPressed" },
895 { Qt::Key_Yes, "yesPressed" },
896 { Qt::Key_No, "noPressed" },
897 { Qt::Key_Context1, "context1Pressed" },
898 { Qt::Key_Context2, "context2Pressed" },
899 { Qt::Key_Context3, "context3Pressed" },
900 { Qt::Key_Context4, "context4Pressed" },
901 { Qt::Key_Call, "callPressed" },
902 { Qt::Key_Hangup, "hangupPressed" },
903 { Qt::Key_Flip, "flipPressed" },
904 { Qt::Key_Menu, "menuPressed" },
905 { Qt::Key_VolumeUp, "volumeUpPressed" },
906 { Qt::Key_VolumeDown, "volumeDownPressed" },
910 bool QQuickKeysAttached::isConnected(const char *signalName)
912 Q_D(QQuickKeysAttached);
913 //### doing two string-based lookups isn't ideal
914 int signal_index = d->signalIndex(signalName);
915 int index = metaObject()->indexOfSignal(signalName);
916 return QQml_isSignalConnected(this, signal_index, index);
920 \qmlclass Keys QQuickKeysAttached
921 \inqmlmodule QtQuick 2
922 \ingroup qml-basic-interaction-elements
923 \brief The Keys attached property provides key handling to Items.
925 All visual primitives support key handling via the Keys
926 attached property. Keys can be handled via the onPressed
927 and onReleased signal properties.
929 The signal properties have a \l KeyEvent parameter, named
930 \e event which contains details of the event. If a key is
931 handled \e event.accepted should be set to true to prevent the
932 event from propagating up the item hierarchy.
934 \section1 Example Usage
936 The following example shows how the general onPressed handler can
937 be used to test for a certain key; in this case, the left cursor
940 \snippet doc/src/snippets/qml/keys/keys-pressed.qml key item
942 Some keys may alternatively be handled via specific signal properties,
943 for example \e onSelectPressed. These handlers automatically set
944 \e event.accepted to true.
946 \snippet doc/src/snippets/qml/keys/keys-handler.qml key item
948 See \l{Qt::Key}{Qt.Key} for the list of keyboard codes.
950 \section1 Key Handling Priorities
952 The Keys attached property can be configured to handle key events
953 before or after the item it is attached to. This makes it possible
954 to intercept events in order to override an item's default behavior,
955 or act as a fallback for keys not handled by the item.
957 If \l priority is Keys.BeforeItem (default) the order of key event processing is:
960 \li Items specified in \c forwardTo
961 \li specific key handlers, e.g. onReturnPressed
962 \li onKeyPress, onKeyRelease handlers
963 \li Item specific key handling, e.g. TextInput key handling
967 If priority is Keys.AfterItem the order of key event processing is:
970 \li Item specific key handling, e.g. TextInput key handling
971 \li Items specified in \c forwardTo
972 \li specific key handlers, e.g. onReturnPressed
973 \li onKeyPress, onKeyRelease handlers
977 If the event is accepted during any of the above steps, key
980 \sa KeyEvent, {KeyNavigation}{KeyNavigation attached property}
984 \qmlproperty bool QtQuick2::Keys::enabled
986 This flags enables key handling if true (default); otherwise
987 no key handlers will be called.
991 \qmlproperty enumeration QtQuick2::Keys::priority
993 This property determines whether the keys are processed before
994 or after the attached item's own key handling.
997 \li Keys.BeforeItem (default) - process the key events before normal
998 item key processing. If the event is accepted it will not
999 be passed on to the item.
1000 \li Keys.AfterItem - process the key events after normal item key
1001 handling. If the item accepts the key event it will not be
1002 handled by the Keys attached property handler.
1007 \qmlproperty list<Object> QtQuick2::Keys::forwardTo
1009 This property provides a way to forward key presses, key releases, and keyboard input
1010 coming from input methods to other items. This can be useful when you want
1011 one item to handle some keys (e.g. the up and down arrow keys), and another item to
1012 handle other keys (e.g. the left and right arrow keys). Once an item that has been
1013 forwarded keys accepts the event it is no longer forwarded to items later in the
1016 This example forwards key events to two lists:
1027 Keys.forwardTo: [list1, list2]
1034 \qmlsignal QtQuick2::Keys::onPressed(KeyEvent event)
1036 This handler is called when a key has been pressed. The \a event
1037 parameter provides information about the event.
1041 \qmlsignal QtQuick2::Keys::onReleased(KeyEvent event)
1043 This handler is called when a key has been released. The \a event
1044 parameter provides information about the event.
1048 \qmlsignal QtQuick2::Keys::onDigit0Pressed(KeyEvent event)
1050 This handler is called when the digit '0' has been pressed. The \a event
1051 parameter provides information about the event.
1055 \qmlsignal QtQuick2::Keys::onDigit1Pressed(KeyEvent event)
1057 This handler is called when the digit '1' has been pressed. The \a event
1058 parameter provides information about the event.
1062 \qmlsignal QtQuick2::Keys::onDigit2Pressed(KeyEvent event)
1064 This handler is called when the digit '2' has been pressed. The \a event
1065 parameter provides information about the event.
1069 \qmlsignal QtQuick2::Keys::onDigit3Pressed(KeyEvent event)
1071 This handler is called when the digit '3' has been pressed. The \a event
1072 parameter provides information about the event.
1076 \qmlsignal QtQuick2::Keys::onDigit4Pressed(KeyEvent event)
1078 This handler is called when the digit '4' has been pressed. The \a event
1079 parameter provides information about the event.
1083 \qmlsignal QtQuick2::Keys::onDigit5Pressed(KeyEvent event)
1085 This handler is called when the digit '5' has been pressed. The \a event
1086 parameter provides information about the event.
1090 \qmlsignal QtQuick2::Keys::onDigit6Pressed(KeyEvent event)
1092 This handler is called when the digit '6' has been pressed. The \a event
1093 parameter provides information about the event.
1097 \qmlsignal QtQuick2::Keys::onDigit7Pressed(KeyEvent event)
1099 This handler is called when the digit '7' has been pressed. The \a event
1100 parameter provides information about the event.
1104 \qmlsignal QtQuick2::Keys::onDigit8Pressed(KeyEvent event)
1106 This handler is called when the digit '8' has been pressed. The \a event
1107 parameter provides information about the event.
1111 \qmlsignal QtQuick2::Keys::onDigit9Pressed(KeyEvent event)
1113 This handler is called when the digit '9' has been pressed. The \a event
1114 parameter provides information about the event.
1118 \qmlsignal QtQuick2::Keys::onLeftPressed(KeyEvent event)
1120 This handler is called when the Left arrow has been pressed. The \a event
1121 parameter provides information about the event.
1125 \qmlsignal QtQuick2::Keys::onRightPressed(KeyEvent event)
1127 This handler is called when the Right arrow has been pressed. The \a event
1128 parameter provides information about the event.
1132 \qmlsignal QtQuick2::Keys::onUpPressed(KeyEvent event)
1134 This handler is called when the Up arrow has been pressed. The \a event
1135 parameter provides information about the event.
1139 \qmlsignal QtQuick2::Keys::onDownPressed(KeyEvent event)
1141 This handler is called when the Down arrow has been pressed. The \a event
1142 parameter provides information about the event.
1146 \qmlsignal QtQuick2::Keys::onTabPressed(KeyEvent event)
1148 This handler is called when the Tab key has been pressed. The \a event
1149 parameter provides information about the event.
1153 \qmlsignal QtQuick2::Keys::onBacktabPressed(KeyEvent event)
1155 This handler is called when the Shift+Tab key combination (Backtab) has
1156 been pressed. The \a event parameter provides information about the event.
1160 \qmlsignal QtQuick2::Keys::onAsteriskPressed(KeyEvent event)
1162 This handler is called when the Asterisk '*' has been pressed. The \a event
1163 parameter provides information about the event.
1167 \qmlsignal QtQuick2::Keys::onEscapePressed(KeyEvent event)
1169 This handler is called when the Escape key has been pressed. The \a event
1170 parameter provides information about the event.
1174 \qmlsignal QtQuick2::Keys::onReturnPressed(KeyEvent event)
1176 This handler is called when the Return key has been pressed. The \a event
1177 parameter provides information about the event.
1181 \qmlsignal QtQuick2::Keys::onEnterPressed(KeyEvent event)
1183 This handler is called when the Enter key has been pressed. The \a event
1184 parameter provides information about the event.
1188 \qmlsignal QtQuick2::Keys::onDeletePressed(KeyEvent event)
1190 This handler is called when the Delete key has been pressed. The \a event
1191 parameter provides information about the event.
1195 \qmlsignal QtQuick2::Keys::onSpacePressed(KeyEvent event)
1197 This handler is called when the Space key has been pressed. The \a event
1198 parameter provides information about the event.
1202 \qmlsignal QtQuick2::Keys::onBackPressed(KeyEvent event)
1204 This handler is called when the Back key has been pressed. The \a event
1205 parameter provides information about the event.
1209 \qmlsignal QtQuick2::Keys::onCancelPressed(KeyEvent event)
1211 This handler is called when the Cancel key has been pressed. The \a event
1212 parameter provides information about the event.
1216 \qmlsignal QtQuick2::Keys::onSelectPressed(KeyEvent event)
1218 This handler is called when the Select key has been pressed. The \a event
1219 parameter provides information about the event.
1223 \qmlsignal QtQuick2::Keys::onYesPressed(KeyEvent event)
1225 This handler is called when the Yes key has been pressed. The \a event
1226 parameter provides information about the event.
1230 \qmlsignal QtQuick2::Keys::onNoPressed(KeyEvent event)
1232 This handler is called when the No key has been pressed. The \a event
1233 parameter provides information about the event.
1237 \qmlsignal QtQuick2::Keys::onContext1Pressed(KeyEvent event)
1239 This handler is called when the Context1 key has been pressed. The \a event
1240 parameter provides information about the event.
1244 \qmlsignal QtQuick2::Keys::onContext2Pressed(KeyEvent event)
1246 This handler is called when the Context2 key has been pressed. The \a event
1247 parameter provides information about the event.
1251 \qmlsignal QtQuick2::Keys::onContext3Pressed(KeyEvent event)
1253 This handler is called when the Context3 key has been pressed. The \a event
1254 parameter provides information about the event.
1258 \qmlsignal QtQuick2::Keys::onContext4Pressed(KeyEvent event)
1260 This handler is called when the Context4 key has been pressed. The \a event
1261 parameter provides information about the event.
1265 \qmlsignal QtQuick2::Keys::onCallPressed(KeyEvent event)
1267 This handler is called when the Call key has been pressed. The \a event
1268 parameter provides information about the event.
1272 \qmlsignal QtQuick2::Keys::onHangupPressed(KeyEvent event)
1274 This handler is called when the Hangup key has been pressed. The \a event
1275 parameter provides information about the event.
1279 \qmlsignal QtQuick2::Keys::onFlipPressed(KeyEvent event)
1281 This handler is called when the Flip key has been pressed. The \a event
1282 parameter provides information about the event.
1286 \qmlsignal QtQuick2::Keys::onMenuPressed(KeyEvent event)
1288 This handler is called when the Menu key has been pressed. The \a event
1289 parameter provides information about the event.
1293 \qmlsignal QtQuick2::Keys::onVolumeUpPressed(KeyEvent event)
1295 This handler is called when the VolumeUp key has been pressed. The \a event
1296 parameter provides information about the event.
1300 \qmlsignal QtQuick2::Keys::onVolumeDownPressed(KeyEvent event)
1302 This handler is called when the VolumeDown key has been pressed. The \a event
1303 parameter provides information about the event.
1306 QQuickKeysAttached::QQuickKeysAttached(QObject *parent)
1307 : QObject(*(new QQuickKeysAttachedPrivate), parent),
1308 QQuickItemKeyFilter(qobject_cast<QQuickItem*>(parent))
1310 Q_D(QQuickKeysAttached);
1311 m_processPost = false;
1312 d->item = qobject_cast<QQuickItem*>(parent);
1315 QQuickKeysAttached::~QQuickKeysAttached()
1319 QQuickKeysAttached::Priority QQuickKeysAttached::priority() const
1321 return m_processPost ? AfterItem : BeforeItem;
1324 void QQuickKeysAttached::setPriority(Priority order)
1326 bool processPost = order == AfterItem;
1327 if (processPost != m_processPost) {
1328 m_processPost = processPost;
1329 emit priorityChanged();
1333 void QQuickKeysAttached::componentComplete()
1335 Q_D(QQuickKeysAttached);
1337 for (int ii = 0; ii < d->targets.count(); ++ii) {
1338 QQuickItem *targetItem = d->targets.at(ii);
1339 if (targetItem && (targetItem->flags() & QQuickItem::ItemAcceptsInputMethod)) {
1340 d->item->setFlag(QQuickItem::ItemAcceptsInputMethod);
1347 void QQuickKeysAttached::keyPressed(QKeyEvent *event, bool post)
1349 Q_D(QQuickKeysAttached);
1350 if (post != m_processPost || !d->enabled || d->inPress) {
1352 QQuickItemKeyFilter::keyPressed(event, post);
1356 // first process forwards
1357 if (d->item && d->item->canvas()) {
1359 for (int ii = 0; ii < d->targets.count(); ++ii) {
1360 QQuickItem *i = d->targets.at(ii);
1361 if (i && i->isVisible()) {
1362 d->item->canvas()->sendEvent(i, event);
1363 if (event->isAccepted()) {
1372 QQuickKeyEvent ke(*event);
1373 QByteArray keySignal = keyToSignal(event->key());
1374 if (!keySignal.isEmpty()) {
1375 keySignal += "(QQuickKeyEvent*)";
1376 if (isConnected(keySignal)) {
1377 // If we specifically handle a key then default to accepted
1378 ke.setAccepted(true);
1379 int idx = QQuickKeysAttached::staticMetaObject.indexOfSignal(keySignal);
1380 metaObject()->method(idx).invoke(this, Qt::DirectConnection, Q_ARG(QQuickKeyEvent*, &ke));
1383 if (!ke.isAccepted())
1385 event->setAccepted(ke.isAccepted());
1387 if (!event->isAccepted()) QQuickItemKeyFilter::keyPressed(event, post);
1390 void QQuickKeysAttached::keyReleased(QKeyEvent *event, bool post)
1392 Q_D(QQuickKeysAttached);
1393 if (post != m_processPost || !d->enabled || d->inRelease) {
1395 QQuickItemKeyFilter::keyReleased(event, post);
1399 if (d->item && d->item->canvas()) {
1400 d->inRelease = true;
1401 for (int ii = 0; ii < d->targets.count(); ++ii) {
1402 QQuickItem *i = d->targets.at(ii);
1403 if (i && i->isVisible()) {
1404 d->item->canvas()->sendEvent(i, event);
1405 if (event->isAccepted()) {
1406 d->inRelease = false;
1411 d->inRelease = false;
1414 QQuickKeyEvent ke(*event);
1416 event->setAccepted(ke.isAccepted());
1418 if (!event->isAccepted()) QQuickItemKeyFilter::keyReleased(event, post);
1421 void QQuickKeysAttached::inputMethodEvent(QInputMethodEvent *event, bool post)
1423 Q_D(QQuickKeysAttached);
1424 if (post == m_processPost && d->item && !d->inIM && d->item->canvas()) {
1426 for (int ii = 0; ii < d->targets.count(); ++ii) {
1427 QQuickItem *i = d->targets.at(ii);
1428 if (i && i->isVisible() && (i->flags() & QQuickItem::ItemAcceptsInputMethod)) {
1429 d->item->canvas()->sendEvent(i, event);
1430 if (event->isAccepted()) {
1439 QQuickItemKeyFilter::inputMethodEvent(event, post);
1442 QVariant QQuickKeysAttached::inputMethodQuery(Qt::InputMethodQuery query) const
1444 Q_D(const QQuickKeysAttached);
1446 for (int ii = 0; ii < d->targets.count(); ++ii) {
1447 QQuickItem *i = d->targets.at(ii);
1448 if (i && i->isVisible() && (i->flags() & QQuickItem::ItemAcceptsInputMethod) && i == d->imeItem) {
1449 //### how robust is i == d->imeItem check?
1450 QVariant v = i->inputMethodQuery(query);
1451 if (v.userType() == QVariant::RectF)
1452 v = d->item->mapRectFromItem(i, v.toRectF()); //### cost?
1457 return QQuickItemKeyFilter::inputMethodQuery(query);
1460 QQuickKeysAttached *QQuickKeysAttached::qmlAttachedProperties(QObject *obj)
1462 return new QQuickKeysAttached(obj);
1466 \qmlclass LayoutMirroring QQuickLayoutMirroringAttached
1467 \inqmlmodule QtQuick 2
1468 \ingroup qml-utility-elements
1469 \brief The LayoutMirroring attached property is used to mirror layout behavior.
1471 The LayoutMirroring attached property is used to horizontally mirror \l {anchor-layout}{Item anchors},
1472 \l{Using QML Positioner and Repeater Items}{positioner} elements (such as \l Row and \l Grid)
1473 and views (such as \l GridView and horizontal \l ListView). Mirroring is a visual change: left
1474 anchors become right anchors, and positioner elements like \l Grid and \l Row reverse the
1475 horizontal layout of child items.
1477 Mirroring is enabled for an item by setting the \l enabled property to true. By default, this
1478 only affects the item itself; setting the \l childrenInherit property to true propagates the mirroring
1479 behavior to all child elements as well. If the \c LayoutMirroring attached property has not been defined
1480 for an item, mirroring is not enabled.
1482 The following example shows mirroring in action. The \l Row below is specified as being anchored
1483 to the left of its parent. However, since mirroring has been enabled, the anchor is horizontally
1484 reversed and it is now anchored to the right. Also, since items in a \l Row are positioned
1485 from left to right by default, they are now positioned from right to left instead, as demonstrated
1486 by the numbering and opacity of the items:
1488 \snippet doc/src/snippets/qml/layoutmirroring.qml 0
1490 \image layoutmirroring.png
1492 Layout mirroring is useful when it is necessary to support both left-to-right and right-to-left
1493 layout versions of an application to target different language areas. The \l childrenInherit
1494 property allows layout mirroring to be applied without manually setting layout configurations
1495 for every item in an application. Keep in mind, however, that mirroring does not affect any
1496 positioning that is defined by the \l Item \l {Item::}{x} coordinate value, so even with
1497 mirroring enabled, it will often be necessary to apply some layout fixes to support the
1498 desired layout direction. Also, it may be necessary to disable the mirroring of individual
1499 child items (by setting \l {enabled}{LayoutMirroring.enabled} to false for such items) if
1500 mirroring is not the desired behavior, or if the child item already implements mirroring in
1503 See \l {QML Right-to-left User Interfaces} for further details on using \c LayoutMirroring and
1504 other related features to implement right-to-left support for an application.
1508 \qmlproperty bool QtQuick2::LayoutMirroring::enabled
1510 This property holds whether the item's layout is mirrored horizontally. Setting this to true
1511 horizontally reverses \l {anchor-layout}{anchor} settings such that left anchors become right,
1512 and right anchors become left. For \l{Using QML Positioner and Repeater Items}{positioner} elements
1513 (such as \l Row and \l Grid) and view elements (such as \l {GridView}{GridView} and \l {ListView}{ListView})
1514 this also mirrors the horizontal layout direction of the item.
1516 The default value is false.
1520 \qmlproperty bool QtQuick2::LayoutMirroring::childrenInherit
1522 This property holds whether the \l {enabled}{LayoutMirroring.enabled} value for this item
1523 is inherited by its children.
1525 The default value is false.
1529 QQuickLayoutMirroringAttached::QQuickLayoutMirroringAttached(QObject *parent) : QObject(parent), itemPrivate(0)
1531 if (QQuickItem *item = qobject_cast<QQuickItem*>(parent)) {
1532 itemPrivate = QQuickItemPrivate::get(item);
1533 itemPrivate->extra.value().layoutDirectionAttached = this;
1535 qmlInfo(parent) << tr("LayoutDirection attached property only works with Items");
1538 QQuickLayoutMirroringAttached * QQuickLayoutMirroringAttached::qmlAttachedProperties(QObject *object)
1540 return new QQuickLayoutMirroringAttached(object);
1543 bool QQuickLayoutMirroringAttached::enabled() const
1545 return itemPrivate ? itemPrivate->effectiveLayoutMirror : false;
1548 void QQuickLayoutMirroringAttached::setEnabled(bool enabled)
1553 itemPrivate->isMirrorImplicit = false;
1554 if (enabled != itemPrivate->effectiveLayoutMirror) {
1555 itemPrivate->setLayoutMirror(enabled);
1556 if (itemPrivate->inheritMirrorFromItem)
1557 itemPrivate->resolveLayoutMirror();
1561 void QQuickLayoutMirroringAttached::resetEnabled()
1563 if (itemPrivate && !itemPrivate->isMirrorImplicit) {
1564 itemPrivate->isMirrorImplicit = true;
1565 itemPrivate->resolveLayoutMirror();
1569 bool QQuickLayoutMirroringAttached::childrenInherit() const
1571 return itemPrivate ? itemPrivate->inheritMirrorFromItem : false;
1574 void QQuickLayoutMirroringAttached::setChildrenInherit(bool childrenInherit) {
1575 if (itemPrivate && childrenInherit != itemPrivate->inheritMirrorFromItem) {
1576 itemPrivate->inheritMirrorFromItem = childrenInherit;
1577 itemPrivate->resolveLayoutMirror();
1578 childrenInheritChanged();
1582 void QQuickItemPrivate::resolveLayoutMirror()
1585 if (QQuickItem *parentItem = q->parentItem()) {
1586 QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(parentItem);
1587 setImplicitLayoutMirror(parentPrivate->inheritedLayoutMirror, parentPrivate->inheritMirrorFromParent);
1589 setImplicitLayoutMirror(isMirrorImplicit ? false : effectiveLayoutMirror, inheritMirrorFromItem);
1593 void QQuickItemPrivate::setImplicitLayoutMirror(bool mirror, bool inherit)
1595 inherit = inherit || inheritMirrorFromItem;
1596 if (!isMirrorImplicit && inheritMirrorFromItem)
1597 mirror = effectiveLayoutMirror;
1598 if (mirror == inheritedLayoutMirror && inherit == inheritMirrorFromParent)
1601 inheritMirrorFromParent = inherit;
1602 inheritedLayoutMirror = inheritMirrorFromParent ? mirror : false;
1604 if (isMirrorImplicit)
1605 setLayoutMirror(inherit ? inheritedLayoutMirror : false);
1606 for (int i = 0; i < childItems.count(); ++i) {
1607 if (QQuickItem *child = qobject_cast<QQuickItem *>(childItems.at(i))) {
1608 QQuickItemPrivate *childPrivate = QQuickItemPrivate::get(child);
1609 childPrivate->setImplicitLayoutMirror(inheritedLayoutMirror, inheritMirrorFromParent);
1614 void QQuickItemPrivate::setLayoutMirror(bool mirror)
1616 if (mirror != effectiveLayoutMirror) {
1617 effectiveLayoutMirror = mirror;
1619 QQuickAnchorsPrivate *anchor_d = QQuickAnchorsPrivate::get(_anchors);
1620 anchor_d->fillChanged();
1621 anchor_d->centerInChanged();
1622 anchor_d->updateHorizontalAnchors();
1623 emit _anchors->mirroredChanged();
1626 if (extra.isAllocated() && extra->layoutDirectionAttached) {
1627 emit extra->layoutDirectionAttached->enabledChanged();
1632 void QQuickItemPrivate::setAccessibleFlagAndListener()
1635 QQuickItem *item = q;
1637 if (item->d_func()->isAccessible)
1638 break; // already set - grandparents should have the flag set as well.
1640 item->d_func()->isAccessible = true;
1641 item = item->d_func()->parentItem;
1645 void QQuickItemPrivate::updateSubFocusItem(QQuickItem *scope, bool focus)
1650 QQuickItemPrivate *scopePrivate = QQuickItemPrivate::get(scope);
1652 QQuickItem *oldSubFocusItem = scopePrivate->subFocusItem;
1653 // Correct focus chain in scope
1654 if (oldSubFocusItem) {
1655 QQuickItem *sfi = scopePrivate->subFocusItem->parentItem();
1656 while (sfi && sfi != scope) {
1657 QQuickItemPrivate::get(sfi)->subFocusItem = 0;
1658 sfi = sfi->parentItem();
1663 scopePrivate->subFocusItem = q;
1664 QQuickItem *sfi = scopePrivate->subFocusItem->parentItem();
1665 while (sfi && sfi != scope) {
1666 QQuickItemPrivate::get(sfi)->subFocusItem = q;
1667 sfi = sfi->parentItem();
1670 scopePrivate->subFocusItem = 0;
1677 \brief The QQuickItem class provides the most basic of all visual items in QML.
1681 All visual items in Qt Quick inherit from QQuickItem. Although QQuickItem
1682 has no visual appearance, it defines all the properties that are
1683 common across visual items - such as the x and y position, the
1684 width and height, \l {anchor-layout}{anchoring} and key handling.
1686 You can subclass QQuickItem to provide your own custom visual item that inherits
1687 these features. Note that, because it does not draw anything, QQuickItem sets the
1688 QGraphicsItem::ItemHasNoContents flag. If you subclass QQuickItem to create a visual
1689 item, you will need to unset this flag.
1694 \qmlclass Item QQuickItem
1696 \inqmlmodule QtQuick 2
1697 \ingroup qml-basic-visual-elements
1698 \brief The Item is the most basic of all visual items in QML.
1700 All visual items in Qt Quick inherit from Item. Although Item
1701 has no visual appearance, it defines all the properties that are
1702 common across visual items - such as the x and y position, the
1703 width and height, \l {anchor-layout}{anchoring} and key handling.
1705 Item is also useful for grouping items together.
1722 fillMode: Image.Tile
1729 \section1 Key Handling
1731 Key handling is available to all Item-based visual elements via the \l {Keys}{Keys}
1732 attached property. The \e Keys attached property provides basic handlers such
1733 as \l {Keys::onPressed}{onPressed} and \l {Keys::onReleased}{onReleased},
1734 as well as handlers for specific keys, such as
1735 \l {Keys::onCancelPressed}{onCancelPressed}. The example below
1736 assigns \l {qmlfocus}{focus} to the item and handles
1737 the Left key via the general \e onPressed handler and the Select key via the
1738 onSelectPressed handler:
1744 if (event.key == Qt.Key_Left) {
1745 console.log("move left");
1746 event.accepted = true;
1749 Keys.onSelectPressed: console.log("Selected");
1753 See the \l {Keys}{Keys} attached property for detailed documentation.
1755 \section1 Layout Mirroring
1757 Item layouts can be mirrored using the \l {LayoutMirroring}{LayoutMirroring} attached property.
1762 \fn void QQuickItem::childrenRectChanged(const QRectF &)
1767 \fn void QQuickItem::baselineOffsetChanged(qreal)
1772 \fn void QQuickItem::stateChanged(const QString &state)
1777 \fn void QQuickItem::parentChanged(QQuickItem *)
1782 \fn void QQuickItem::smoothChanged(bool)
1787 \fn void QQuickItem::clipChanged(bool)
1791 /*! \fn void QQuickItem::transformOriginChanged(TransformOrigin)
1796 \fn void QQuickItem::focusChanged(bool)
1801 \fn void QQuickItem::activeFocusChanged(bool)
1805 \fn QQuickItem::QQuickItem(QQuickItem *parent)
1807 Constructs a QQuickItem with the given \a parent.
1809 QQuickItem::QQuickItem(QQuickItem* parent)
1810 : QObject(*(new QQuickItemPrivate), parent)
1818 QQuickItem::QQuickItem(QQuickItemPrivate &dd, QQuickItem *parent)
1819 : QObject(dd, parent)
1826 static int qt_item_count = 0;
1828 static void qt_print_item_count()
1830 qDebug("Number of leaked items: %i", qt_item_count);
1836 Destroys the QQuickItem.
1838 QQuickItem::~QQuickItem()
1842 if (qt_item_count < 0)
1843 qDebug("Item destroyed after qt_print_item_count() was called.");
1848 if (d->canvasRefCount > 1)
1849 d->canvasRefCount = 1; // Make sure canvas is set to null in next call to derefCanvas().
1855 // XXX todo - optimize
1856 while (!d->childItems.isEmpty())
1857 d->childItems.first()->setParentItem(0);
1859 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
1860 QQuickAnchorsPrivate *anchor = d->changeListeners.at(ii).listener->anchorPrivate();
1862 anchor->clearItem(this);
1866 update item anchors that depended on us unless they are our child (and will also be destroyed),
1867 or our sibling, and our parent is also being destroyed.
1869 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
1870 QQuickAnchorsPrivate *anchor = d->changeListeners.at(ii).listener->anchorPrivate();
1871 if (anchor && anchor->item && anchor->item->parentItem() && anchor->item->parentItem() != this)
1875 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
1876 const QQuickItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
1877 if (change.types & QQuickItemPrivate::Destroyed)
1878 change.listener->itemDestroyed(this);
1881 d->changeListeners.clear();
1883 if (d->extra.isAllocated()) {
1884 delete d->extra->contents; d->extra->contents = 0;
1885 delete d->extra->layer; d->extra->layer = 0;
1888 delete d->_anchors; d->_anchors = 0;
1889 delete d->_stateGroup; d->_stateGroup = 0;
1893 \qmlproperty enumeration QtQuick2::Item::transformOrigin
1894 This property holds the origin point around which scale and rotation transform.
1896 Nine transform origins are available, as shown in the image below.
1898 \image declarative-transformorigin.png
1900 This example rotates an image around its bottom-right corner.
1903 source: "myimage.png"
1904 transformOrigin: Item.BottomRight
1909 The default transform origin is \c Item.Center.
1911 To set an arbitrary transform origin point use the \l Scale or \l Rotation
1916 \qmlproperty Item QtQuick2::Item::parent
1917 This property holds the parent of the item.
1921 \property QQuickItem::parent
1922 This property holds the parent of the item.
1924 void QQuickItem::setParentItem(QQuickItem *parentItem)
1927 if (parentItem == d->parentItem)
1931 QQuickItem *itemAncestor = parentItem->parentItem();
1932 while (itemAncestor != 0) {
1933 if (itemAncestor == this) {
1934 qWarning("QQuickItem::setParentItem: Parent is already part of this items subtree.");
1937 itemAncestor = itemAncestor->parentItem();
1941 d->removeFromDirtyList();
1943 QQuickItem *oldParentItem = d->parentItem;
1944 QQuickItem *scopeFocusedItem = 0;
1946 if (oldParentItem) {
1947 QQuickItemPrivate *op = QQuickItemPrivate::get(oldParentItem);
1949 QQuickItem *scopeItem = 0;
1952 scopeFocusedItem = this;
1953 else if (!isFocusScope() && d->subFocusItem)
1954 scopeFocusedItem = d->subFocusItem;
1956 if (scopeFocusedItem) {
1957 scopeItem = oldParentItem;
1958 while (!scopeItem->isFocusScope() && scopeItem->parentItem())
1959 scopeItem = scopeItem->parentItem();
1961 QQuickCanvasPrivate::get(d->canvas)->clearFocusInScope(scopeItem, scopeFocusedItem,
1962 QQuickCanvasPrivate::DontChangeFocusProperty);
1963 if (scopeFocusedItem != this)
1964 QQuickItemPrivate::get(scopeFocusedItem)->updateSubFocusItem(this, true);
1966 QQuickItemPrivate::get(scopeFocusedItem)->updateSubFocusItem(scopeItem, false);
1970 const bool wasVisible = isVisible();
1971 op->removeChild(this);
1973 emit oldParentItem->visibleChildrenChanged();
1975 } else if (d->canvas) {
1976 QQuickCanvasPrivate::get(d->canvas)->parentlessItems.remove(this);
1979 QQuickCanvas *oldParentCanvas = oldParentItem ? QQuickItemPrivate::get(oldParentItem)->canvas : 0;
1980 QQuickCanvas *parentCanvas = parentItem ? QQuickItemPrivate::get(parentItem)->canvas : 0;
1981 if (oldParentCanvas == parentCanvas) {
1982 // Avoid freeing and reallocating resources if the canvas stays the same.
1983 d->parentItem = parentItem;
1985 if (oldParentCanvas)
1987 d->parentItem = parentItem;
1989 d->refCanvas(parentCanvas);
1992 d->dirty(QQuickItemPrivate::ParentChanged);
1995 QQuickItemPrivate::get(d->parentItem)->addChild(this);
1997 QQuickCanvasPrivate::get(d->canvas)->parentlessItems.insert(this);
1999 d->setEffectiveVisibleRecur(d->calcEffectiveVisible());
2000 d->setEffectiveEnableRecur(0, d->calcEffectiveEnable());
2002 if (d->parentItem) {
2003 if (!scopeFocusedItem) {
2005 scopeFocusedItem = this;
2006 else if (!isFocusScope() && d->subFocusItem)
2007 scopeFocusedItem = d->subFocusItem;
2010 if (scopeFocusedItem) {
2011 // We need to test whether this item becomes scope focused
2012 QQuickItem *scopeItem = d->parentItem;
2013 while (!scopeItem->isFocusScope() && scopeItem->parentItem())
2014 scopeItem = scopeItem->parentItem();
2016 if (QQuickItemPrivate::get(scopeItem)->subFocusItem
2017 || (!scopeItem->isFocusScope() && scopeItem->hasFocus())) {
2018 if (scopeFocusedItem != this)
2019 QQuickItemPrivate::get(scopeFocusedItem)->updateSubFocusItem(this, false);
2020 QQuickItemPrivate::get(scopeFocusedItem)->focus = false;
2021 emit scopeFocusedItem->focusChanged(false);
2024 QQuickCanvasPrivate::get(d->canvas)->setFocusInScope(scopeItem, scopeFocusedItem,
2025 QQuickCanvasPrivate::DontChangeFocusProperty);
2027 QQuickItemPrivate::get(scopeFocusedItem)->updateSubFocusItem(scopeItem, true);
2033 d->resolveLayoutMirror();
2035 d->itemChange(ItemParentHasChanged, d->parentItem);
2037 d->parentNotifier.notify();
2038 if (d->isAccessible && d->parentItem) {
2039 d->parentItem->d_func()->setAccessibleFlagAndListener();
2042 emit parentChanged(d->parentItem);
2043 if (isVisible() && d->parentItem)
2044 emit d->parentItem->visibleChildrenChanged();
2047 void QQuickItem::stackBefore(const QQuickItem *sibling)
2050 if (!sibling || sibling == this || !d->parentItem || d->parentItem != QQuickItemPrivate::get(sibling)->parentItem) {
2051 qWarning("QQuickItem::stackBefore: Cannot stack before %p, which must be a sibling", sibling);
2055 QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(d->parentItem);
2057 int myIndex = parentPrivate->childItems.indexOf(this);
2058 int siblingIndex = parentPrivate->childItems.indexOf(const_cast<QQuickItem *>(sibling));
2060 Q_ASSERT(myIndex != -1 && siblingIndex != -1);
2062 if (myIndex == siblingIndex - 1)
2065 parentPrivate->childItems.removeAt(myIndex);
2067 if (myIndex < siblingIndex) --siblingIndex;
2069 parentPrivate->childItems.insert(siblingIndex, this);
2071 parentPrivate->dirty(QQuickItemPrivate::ChildrenStackingChanged);
2072 parentPrivate->markSortedChildrenDirty(this);
2074 for (int ii = qMin(siblingIndex, myIndex); ii < parentPrivate->childItems.count(); ++ii)
2075 QQuickItemPrivate::get(parentPrivate->childItems.at(ii))->siblingOrderChanged();
2078 void QQuickItem::stackAfter(const QQuickItem *sibling)
2081 if (!sibling || sibling == this || !d->parentItem || d->parentItem != QQuickItemPrivate::get(sibling)->parentItem) {
2082 qWarning("QQuickItem::stackAfter: Cannot stack after %p, which must be a sibling", sibling);
2086 QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(d->parentItem);
2088 int myIndex = parentPrivate->childItems.indexOf(this);
2089 int siblingIndex = parentPrivate->childItems.indexOf(const_cast<QQuickItem *>(sibling));
2091 Q_ASSERT(myIndex != -1 && siblingIndex != -1);
2093 if (myIndex == siblingIndex + 1)
2096 parentPrivate->childItems.removeAt(myIndex);
2098 if (myIndex < siblingIndex) --siblingIndex;
2100 parentPrivate->childItems.insert(siblingIndex + 1, this);
2102 parentPrivate->dirty(QQuickItemPrivate::ChildrenStackingChanged);
2103 parentPrivate->markSortedChildrenDirty(this);
2105 for (int ii = qMin(myIndex, siblingIndex + 1); ii < parentPrivate->childItems.count(); ++ii)
2106 QQuickItemPrivate::get(parentPrivate->childItems.at(ii))->siblingOrderChanged();
2110 Returns the QQuickItem parent of this item.
2112 QQuickItem *QQuickItem::parentItem() const
2114 Q_D(const QQuickItem);
2115 return d->parentItem;
2118 QSGEngine *QQuickItem::sceneGraphEngine() const
2120 return canvas()->sceneGraphEngine();
2123 QQuickCanvas *QQuickItem::canvas() const
2125 Q_D(const QQuickItem);
2129 static bool itemZOrder_sort(QQuickItem *lhs, QQuickItem *rhs)
2131 return lhs->z() < rhs->z();
2134 QList<QQuickItem *> QQuickItemPrivate::paintOrderChildItems() const
2136 if (sortedChildItems)
2137 return *sortedChildItems;
2139 // If none of the items have set Z then the paint order list is the same as
2140 // the childItems list. This is by far the most common case.
2142 for (int i = 0; i < childItems.count(); ++i) {
2143 if (QQuickItemPrivate::get(childItems.at(i))->z() != 0.) {
2149 sortedChildItems = new QList<QQuickItem*>(childItems);
2150 qStableSort(sortedChildItems->begin(), sortedChildItems->end(), itemZOrder_sort);
2151 return *sortedChildItems;
2154 sortedChildItems = const_cast<QList<QQuickItem*>*>(&childItems);
2159 void QQuickItemPrivate::addChild(QQuickItem *child)
2163 Q_ASSERT(!childItems.contains(child));
2165 childItems.append(child);
2167 markSortedChildrenDirty(child);
2168 dirty(QQuickItemPrivate::ChildrenChanged);
2170 itemChange(QQuickItem::ItemChildAddedChange, child);
2172 emit q->childrenChanged();
2175 void QQuickItemPrivate::removeChild(QQuickItem *child)
2180 Q_ASSERT(childItems.contains(child));
2181 childItems.removeOne(child);
2182 Q_ASSERT(!childItems.contains(child));
2184 markSortedChildrenDirty(child);
2185 dirty(QQuickItemPrivate::ChildrenChanged);
2187 itemChange(QQuickItem::ItemChildRemovedChange, child);
2189 emit q->childrenChanged();
2192 void QQuickItemPrivate::InitializationState::clear()
2197 void QQuickItemPrivate::InitializationState::clear(QQuickItem *fs)
2202 QQuickItem *QQuickItemPrivate::InitializationState::getFocusScope(QQuickItem *item)
2205 QQuickItem *fs = item->parentItem();
2206 while (fs->parentItem() && !fs->isFocusScope())
2207 fs = fs->parentItem();
2213 void QQuickItemPrivate::refCanvas(InitializationState *state, QQuickCanvas *c)
2215 // An item needs a canvas if it is referenced by another item which has a canvas.
2216 // Typically the item is referenced by a parent, but can also be referenced by a
2217 // ShaderEffect or ShaderEffectSource. 'canvasRefCount' counts how many items with
2218 // a canvas is referencing this item. When the reference count goes from zero to one,
2219 // or one to zero, the canvas of this item is updated and propagated to the children.
2220 // As long as the reference count stays above zero, the canvas is unchanged.
2221 // refCanvas() increments the reference count.
2222 // derefCanvas() decrements the reference count.
2225 Q_ASSERT((canvas != 0) == (canvasRefCount > 0));
2227 if (++canvasRefCount > 1) {
2229 qWarning("QQuickItem: Cannot use same item on different canvases at the same time.");
2230 return; // Canvas already set.
2233 Q_ASSERT(canvas == 0);
2236 if (polishScheduled)
2237 QQuickCanvasPrivate::get(canvas)->itemsToPolish.insert(q);
2239 InitializationState _dummy;
2240 InitializationState *childState = state;
2242 if (q->isFocusScope()) {
2244 childState = &_dummy;
2248 QQuickCanvasPrivate::get(canvas)->parentlessItems.insert(q);
2250 for (int ii = 0; ii < childItems.count(); ++ii) {
2251 QQuickItem *child = childItems.at(ii);
2252 QQuickItemPrivate::get(child)->refCanvas(childState, c);
2257 if (extra.isAllocated() && extra->screenAttached)
2258 extra->screenAttached->canvasChanged(c);
2259 itemChange(QQuickItem::ItemSceneChange, c);
2262 void QQuickItemPrivate::derefCanvas()
2265 Q_ASSERT((canvas != 0) == (canvasRefCount > 0));
2268 return; // This can happen when destroying recursive shader effect sources.
2270 if (--canvasRefCount > 0)
2271 return; // There are still other references, so don't set canvas to null yet.
2273 q->releaseResources();
2274 removeFromDirtyList();
2275 QQuickCanvasPrivate *c = QQuickCanvasPrivate::get(canvas);
2276 if (polishScheduled)
2277 c->itemsToPolish.remove(q);
2278 if (c->mouseGrabberItem == q)
2279 c->mouseGrabberItem = 0;
2281 c->hoverItems.removeAll(q);
2282 if (itemNodeInstance)
2283 c->cleanup(itemNodeInstance);
2285 c->parentlessItems.remove(q);
2289 itemNodeInstance = 0;
2291 if (extra.isAllocated()) {
2292 extra->opacityNode = 0;
2293 extra->clipNode = 0;
2294 extra->rootNode = 0;
2295 extra->beforePaintNode = 0;
2301 for (int ii = 0; ii < childItems.count(); ++ii) {
2302 QQuickItem *child = childItems.at(ii);
2303 QQuickItemPrivate::get(child)->derefCanvas();
2308 if (extra.isAllocated() && extra->screenAttached)
2309 extra->screenAttached->canvasChanged(0);
2310 itemChange(QQuickItem::ItemSceneChange, (QQuickCanvas *)0);
2315 Returns a transform that maps points from canvas space into item space.
2317 QTransform QQuickItemPrivate::canvasToItemTransform() const
2319 // XXX todo - optimize
2320 return itemToCanvasTransform().inverted();
2324 Returns a transform that maps points from item space into canvas space.
2326 QTransform QQuickItemPrivate::itemToCanvasTransform() const
2329 QTransform rv = parentItem?QQuickItemPrivate::get(parentItem)->itemToCanvasTransform():QTransform();
2330 itemToParentTransform(rv);
2335 Motifies \a t with this items local transform relative to its parent.
2337 void QQuickItemPrivate::itemToParentTransform(QTransform &t) const
2342 if (!transforms.isEmpty()) {
2344 for (int ii = transforms.count() - 1; ii >= 0; --ii)
2345 transforms.at(ii)->applyTo(&m);
2346 t = m.toTransform();
2349 if (scale() != 1. || rotation() != 0.) {
2350 QPointF tp = computeTransformOrigin();
2351 t.translate(tp.x(), tp.y());
2352 t.scale(scale(), scale());
2353 t.rotate(rotation());
2354 t.translate(-tp.x(), -tp.y());
2360 \qmlproperty real QtQuick2::Item::childrenRect.x
2361 \qmlproperty real QtQuick2::Item::childrenRect.y
2362 \qmlproperty real QtQuick2::Item::childrenRect.width
2363 \qmlproperty real QtQuick2::Item::childrenRect.height
2365 The childrenRect properties allow an item access to the geometry of its
2366 children. This property is useful if you have an item that needs to be
2367 sized to fit its children.
2372 \qmlproperty list<Item> QtQuick2::Item::children
2373 \qmlproperty list<Object> QtQuick2::Item::resources
2375 The children property contains the list of visual children of this item.
2376 The resources property contains non-visual resources that you want to
2379 Generally you can rely on Item's default property to handle all this for
2380 you, but it can come in handy in some cases.
2399 Returns true if construction of the QML component is complete; otherwise
2402 It is often desirable to delay some processing until the component is
2405 \sa componentComplete()
2407 bool QQuickItem::isComponentComplete() const
2409 Q_D(const QQuickItem);
2410 return d->componentComplete;
2413 QQuickItemPrivate::QQuickItemPrivate()
2414 : _anchors(0), _stateGroup(0),
2415 flags(0), widthValid(false), heightValid(false), baselineOffsetValid(false), componentComplete(true),
2416 keepMouse(false), keepTouch(false), hoverEnabled(false), smooth(true), focus(false), activeFocus(false), notifiedFocus(false),
2417 notifiedActiveFocus(false), filtersChildMouseEvents(false), explicitVisible(true),
2418 effectiveVisible(true), explicitEnable(true), effectiveEnable(true), polishScheduled(false),
2419 inheritedLayoutMirror(false), effectiveLayoutMirror(false), isMirrorImplicit(true),
2420 inheritMirrorFromParent(false), inheritMirrorFromItem(false), childrenDoNotOverlap(false),
2421 staticSubtreeGeometry(false),
2422 isAccessible(false),
2424 dirtyAttributes(0), nextDirtyItem(0), prevDirtyItem(0),
2426 canvas(0), canvasRefCount(0), parentItem(0), sortedChildItems(&childItems),
2430 x(0), y(0), width(0), height(0), implicitWidth(0), implicitHeight(0),
2434 itemNodeInstance(0), groupNode(0), paintNode(0)
2438 QQuickItemPrivate::~QQuickItemPrivate()
2440 if (sortedChildItems != &childItems)
2441 delete sortedChildItems;
2444 void QQuickItemPrivate::init(QQuickItem *parent)
2448 static bool atexit_registered = false;
2449 if (!atexit_registered) {
2450 atexit(qt_print_item_count);
2451 atexit_registered = true;
2457 registerAccessorProperties();
2459 baselineOffsetValid = false;
2462 q->setParentItem(parent);
2463 QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(parent);
2464 setImplicitLayoutMirror(parentPrivate->inheritedLayoutMirror, parentPrivate->inheritMirrorFromParent);
2468 void QQuickItemPrivate::data_append(QQmlListProperty<QObject> *prop, QObject *o)
2473 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2475 // This test is measurably (albeit only slightly) faster than qobject_cast<>()
2476 const QMetaObject *mo = o->metaObject();
2477 while (mo && mo != &QQuickItem::staticMetaObject) {
2478 mo = mo->d.superdata;
2482 QQuickItem *item = static_cast<QQuickItem *>(o);
2483 item->setParentItem(that);
2485 if (o->inherits("QGraphicsItem"))
2486 qWarning("Cannot add a QtQuick 1.0 item (%s) into a QtQuick 2.0 scene!", o->metaObject()->className());
2488 // XXX todo - do we really want this behavior?
2494 \qmlproperty list<Object> QtQuick2::Item::data
2497 The data property allows you to freely mix visual children and resources
2498 in an item. If you assign a visual item to the data list it becomes
2499 a child and if you assign any other object type, it is added as a resource.
2523 data is a behind-the-scenes property: you should never need to explicitly
2527 int QQuickItemPrivate::data_count(QQmlListProperty<QObject> *prop)
2534 QObject *QQuickItemPrivate::data_at(QQmlListProperty<QObject> *prop, int i)
2542 void QQuickItemPrivate::data_clear(QQmlListProperty<QObject> *prop)
2548 QObject *QQuickItemPrivate::resources_at(QQmlListProperty<QObject> *prop, int index)
2550 const QObjectList children = prop->object->children();
2551 if (index < children.count())
2552 return children.at(index);
2557 void QQuickItemPrivate::resources_append(QQmlListProperty<QObject> *prop, QObject *o)
2559 // XXX todo - do we really want this behavior?
2560 o->setParent(prop->object);
2563 int QQuickItemPrivate::resources_count(QQmlListProperty<QObject> *prop)
2565 return prop->object->children().count();
2568 void QQuickItemPrivate::resources_clear(QQmlListProperty<QObject> *prop)
2570 // XXX todo - do we really want this behavior?
2571 const QObjectList children = prop->object->children();
2572 for (int index = 0; index < children.count(); index++)
2573 children.at(index)->setParent(0);
2576 QQuickItem *QQuickItemPrivate::children_at(QQmlListProperty<QQuickItem> *prop, int index)
2578 QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2579 if (index >= p->childItems.count() || index < 0)
2582 return p->childItems.at(index);
2585 void QQuickItemPrivate::children_append(QQmlListProperty<QQuickItem> *prop, QQuickItem *o)
2590 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2591 if (o->parentItem() == that)
2592 o->setParentItem(0);
2594 o->setParentItem(that);
2597 int QQuickItemPrivate::children_count(QQmlListProperty<QQuickItem> *prop)
2599 QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2600 return p->childItems.count();
2603 void QQuickItemPrivate::children_clear(QQmlListProperty<QQuickItem> *prop)
2605 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2606 QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2607 while (!p->childItems.isEmpty())
2608 p->childItems.at(0)->setParentItem(0);
2611 void QQuickItemPrivate::visibleChildren_append(QQmlListProperty<QQuickItem>*, QQuickItem *self)
2614 qmlInfo(self) << "QQuickItem: visibleChildren property is readonly and cannot be assigned to.";
2617 int QQuickItemPrivate::visibleChildren_count(QQmlListProperty<QQuickItem> *prop)
2619 QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2620 int visibleCount = 0;
2621 int c = p->childItems.count();
2623 if (p->childItems.at(c)->isVisible()) visibleCount++;
2626 return visibleCount;
2629 QQuickItem *QQuickItemPrivate::visibleChildren_at(QQmlListProperty<QQuickItem> *prop, int index)
2631 QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2632 const int childCount = p->childItems.count();
2633 if (index >= childCount || index < 0)
2636 int visibleCount = -1;
2637 for (int i = 0; i < childCount; i++) {
2638 if (p->childItems.at(i)->isVisible()) visibleCount++;
2639 if (visibleCount == index) return p->childItems.at(i);
2644 int QQuickItemPrivate::transform_count(QQmlListProperty<QQuickTransform> *prop)
2646 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2647 QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2649 return p->transforms.count();
2652 void QQuickTransform::appendToItem(QQuickItem *item)
2654 Q_D(QQuickTransform);
2658 QQuickItemPrivate *p = QQuickItemPrivate::get(item);
2660 if (!d->items.isEmpty() && !p->transforms.isEmpty() && p->transforms.contains(this)) {
2661 p->transforms.removeOne(this);
2662 p->transforms.append(this);
2664 p->transforms.append(this);
2665 d->items.append(item);
2668 p->dirty(QQuickItemPrivate::Transform);
2671 void QQuickTransform::prependToItem(QQuickItem *item)
2673 Q_D(QQuickTransform);
2677 QQuickItemPrivate *p = QQuickItemPrivate::get(item);
2679 if (!d->items.isEmpty() && !p->transforms.isEmpty() && p->transforms.contains(this)) {
2680 p->transforms.removeOne(this);
2681 p->transforms.prepend(this);
2683 p->transforms.prepend(this);
2684 d->items.append(item);
2687 p->dirty(QQuickItemPrivate::Transform);
2690 void QQuickItemPrivate::transform_append(QQmlListProperty<QQuickTransform> *prop, QQuickTransform *transform)
2695 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2696 transform->appendToItem(that);
2699 QQuickTransform *QQuickItemPrivate::transform_at(QQmlListProperty<QQuickTransform> *prop, int idx)
2701 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2702 QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2704 if (idx < 0 || idx >= p->transforms.count())
2707 return p->transforms.at(idx);
2710 void QQuickItemPrivate::transform_clear(QQmlListProperty<QQuickTransform> *prop)
2712 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2713 QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2715 for (int ii = 0; ii < p->transforms.count(); ++ii) {
2716 QQuickTransform *t = p->transforms.at(ii);
2717 QQuickTransformPrivate *tp = QQuickTransformPrivate::get(t);
2718 tp->items.removeOne(that);
2721 p->transforms.clear();
2723 p->dirty(QQuickItemPrivate::Transform);
2727 \property QQuickItem::childrenRect
2728 \brief The geometry of an item's children.
2730 This property holds the (collective) position and size of the item's children.
2734 \qmlproperty real QtQuick2::Item::x
2735 \qmlproperty real QtQuick2::Item::y
2736 \qmlproperty real QtQuick2::Item::width
2737 \qmlproperty real QtQuick2::Item::height
2739 Defines the item's position and size relative to its parent.
2742 Item { x: 100; y: 100; width: 100; height: 100 }
2747 \qmlproperty real QtQuick2::Item::z
2749 Sets the stacking order of sibling items. By default the stacking order is 0.
2751 Items with a higher stacking value are drawn on top of siblings with a
2752 lower stacking order. Items with the same stacking value are drawn
2753 bottom up in the order they appear. Items with a negative stacking
2754 value are drawn under their parent's content.
2756 The following example shows the various effects of stacking order.
2760 \li \image declarative-item_stacking1.png
2761 \li Same \c z - later children above earlier children:
2766 width: 100; height: 100
2770 x: 50; y: 50; width: 100; height: 100
2775 \li \image declarative-item_stacking2.png
2776 \li Higher \c z on top:
2782 width: 100; height: 100
2786 x: 50; y: 50; width: 100; height: 100
2791 \li \image declarative-item_stacking3.png
2792 \li Same \c z - children above parents:
2797 width: 100; height: 100
2800 x: 50; y: 50; width: 100; height: 100
2806 \li \image declarative-item_stacking4.png
2807 \li Lower \c z below:
2812 width: 100; height: 100
2816 x: 50; y: 50; width: 100; height: 100
2825 \qmlproperty bool QtQuick2::Item::visible
2827 This property holds whether the item is visible. By default this is true.
2829 Setting this property directly affects the \c visible value of child
2830 items. When set to \c false, the \c visible values of all child items also
2831 become \c false. When set to \c true, the \c visible values of child items
2832 are returned to \c true, unless they have explicitly been set to \c false.
2834 (Because of this flow-on behavior, using the \c visible property may not
2835 have the intended effect if a property binding should only respond to
2836 explicit property changes. In such cases it may be better to use the
2837 \l opacity property instead.)
2839 Setting this property to \c false automatically causes \l focus to be set
2840 to \c false, and this item will longer receive mouse and keyboard events.
2841 (In contrast, setting the \l opacity to 0 does not affect the \l focus
2842 property and the receiving of key events.)
2844 \note This property's value is only affected by changes to this property or
2845 the parent's \c visible property. It does not change, for example, if this
2846 item moves off-screen, or if the \l opacity changes to 0.
2851 \qmlproperty AnchorLine QtQuick2::Item::anchors.top
2852 \qmlproperty AnchorLine QtQuick2::Item::anchors.bottom
2853 \qmlproperty AnchorLine QtQuick2::Item::anchors.left
2854 \qmlproperty AnchorLine QtQuick2::Item::anchors.right
2855 \qmlproperty AnchorLine QtQuick2::Item::anchors.horizontalCenter
2856 \qmlproperty AnchorLine QtQuick2::Item::anchors.verticalCenter
2857 \qmlproperty AnchorLine QtQuick2::Item::anchors.baseline
2859 \qmlproperty Item QtQuick2::Item::anchors.fill
2860 \qmlproperty Item QtQuick2::Item::anchors.centerIn
2862 \qmlproperty real QtQuick2::Item::anchors.margins
2863 \qmlproperty real QtQuick2::Item::anchors.topMargin
2864 \qmlproperty real QtQuick2::Item::anchors.bottomMargin
2865 \qmlproperty real QtQuick2::Item::anchors.leftMargin
2866 \qmlproperty real QtQuick2::Item::anchors.rightMargin
2867 \qmlproperty real QtQuick2::Item::anchors.horizontalCenterOffset
2868 \qmlproperty real QtQuick2::Item::anchors.verticalCenterOffset
2869 \qmlproperty real QtQuick2::Item::anchors.baselineOffset
2871 \qmlproperty bool QtQuick2::Item::anchors.mirrored
2873 Anchors provide a way to position an item by specifying its
2874 relationship with other items.
2876 Margins apply to top, bottom, left, right, and fill anchors.
2877 The \c anchors.margins property can be used to set all of the various margins at once, to the same value.
2878 Note that margins are anchor-specific and are not applied if an item does not
2881 Offsets apply for horizontal center, vertical center, and baseline anchors.
2885 \li \image declarative-anchors_example.png
2886 \li Text anchored to Image, horizontally centered and vertically below, with a margin.
2895 anchors.horizontalCenter: pic.horizontalCenter
2896 anchors.top: pic.bottom
2897 anchors.topMargin: 5
2903 \li \image declarative-anchors_example2.png
2905 Left of Text anchored to right of Image, with a margin. The y
2906 property of both defaults to 0.
2916 anchors.left: pic.right
2917 anchors.leftMargin: 5
2924 \c anchors.fill provides a convenient way for one item to have the
2925 same geometry as another item, and is equivalent to connecting all
2926 four directional anchors.
2928 To clear an anchor value, set it to \c undefined.
2930 \c anchors.mirrored returns true it the layout has been \l {LayoutMirroring}{mirrored}.
2932 \note You can only anchor an item to siblings or a parent.
2934 For more information see \l {anchor-layout}{Anchor Layouts}.
2938 \property QQuickItem::baselineOffset
2939 \brief The position of the item's baseline in local coordinates.
2941 The baseline of a \l Text item is the imaginary line on which the text
2942 sits. Controls containing text usually set their baseline to the
2943 baseline of their text.
2945 For non-text items, a default baseline offset of 0 is used.
2947 QQuickAnchors *QQuickItemPrivate::anchors() const
2950 Q_Q(const QQuickItem);
2951 _anchors = new QQuickAnchors(const_cast<QQuickItem *>(q));
2952 if (!componentComplete)
2953 _anchors->classBegin();
2958 void QQuickItemPrivate::siblingOrderChanged()
2961 for (int ii = 0; ii < changeListeners.count(); ++ii) {
2962 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
2963 if (change.types & QQuickItemPrivate::SiblingOrder) {
2964 change.listener->itemSiblingOrderChanged(q);
2969 QQmlListProperty<QObject> QQuickItemPrivate::data()
2971 return QQmlListProperty<QObject>(q_func(), 0, QQuickItemPrivate::data_append,
2972 QQuickItemPrivate::data_count,
2973 QQuickItemPrivate::data_at,
2974 QQuickItemPrivate::data_clear);
2977 QRectF QQuickItem::childrenRect()
2980 if (!d->extra.isAllocated() || !d->extra->contents) {
2981 d->extra.value().contents = new QQuickContents(this);
2982 if (d->componentComplete)
2983 d->extra->contents->complete();
2985 return d->extra->contents->rectF();
2988 QList<QQuickItem *> QQuickItem::childItems() const
2990 Q_D(const QQuickItem);
2991 return d->childItems;
2994 bool QQuickItem::clip() const
2996 return flags() & ItemClipsChildrenToShape;
2999 void QQuickItem::setClip(bool c)
3004 setFlag(ItemClipsChildrenToShape, c);
3006 emit clipChanged(c);
3011 This function is called to handle this item's changes in
3012 geometry from \a oldGeometry to \a newGeometry. If the two
3013 geometries are the same, it doesn't do anything.
3015 void QQuickItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
3020 QQuickAnchorsPrivate::get(d->_anchors)->updateMe();
3022 bool xChange = (newGeometry.x() != oldGeometry.x());
3023 bool yChange = (newGeometry.y() != oldGeometry.y());
3024 bool widthChange = (newGeometry.width() != oldGeometry.width());
3025 bool heightChange = (newGeometry.height() != oldGeometry.height());
3027 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
3028 const QQuickItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
3029 if (change.types & QQuickItemPrivate::Geometry) {
3030 if (change.gTypes == QQuickItemPrivate::GeometryChange) {
3031 change.listener->itemGeometryChanged(this, newGeometry, oldGeometry);
3032 } else if ((xChange && (change.gTypes & QQuickItemPrivate::XChange)) ||
3033 (yChange && (change.gTypes & QQuickItemPrivate::YChange)) ||
3034 (widthChange && (change.gTypes & QQuickItemPrivate::WidthChange)) ||
3035 (heightChange && (change.gTypes & QQuickItemPrivate::HeightChange))) {
3036 change.listener->itemGeometryChanged(this, newGeometry, oldGeometry);
3046 emit widthChanged();
3048 emit heightChanged();
3052 Called by the rendering thread when it is time to sync the state of the QML objects with the
3053 scene graph objects. The function should return the root of the scene graph subtree for
3054 this item. \a oldNode is the node that was returned the last time the function was called.
3056 The main thread is blocked while this function is executed so it is safe to read
3057 values from the QQuickItem instance and other objects in the main thread.
3059 \warning This is the only function in which it is allowed to make use of scene graph
3060 objects from the main thread. Use of scene graph objects outside this function will
3061 result in race conditions and potential crashes.
3064 QSGNode *QQuickItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
3071 This function is called when the item's scene graph resources are no longer needed.
3072 It allows items to free its resources, for instance textures, that are not owned by scene graph
3073 nodes. Note that scene graph nodes are managed by QQuickCanvas and should not be deleted by
3074 this function. Scene graph resources are no longer needed when the parent is set to null and
3075 the item is not used by any \l ShaderEffect or \l ShaderEffectSource.
3077 This function is called from the main thread. Therefore, resources used by the scene graph
3078 should not be deleted directly, but by calling \l QObject::deleteLater().
3080 \note The item destructor still needs to free its scene graph resources if not already done.
3083 void QQuickItem::releaseResources()
3087 QSGTransformNode *QQuickItemPrivate::createTransformNode()
3089 return new QSGTransformNode;
3092 void QQuickItem::updatePolish()
3096 void QQuickItemPrivate::addItemChangeListener(QQuickItemChangeListener *listener, ChangeTypes types)
3098 changeListeners.append(ChangeListener(listener, types));
3101 void QQuickItemPrivate::removeItemChangeListener(QQuickItemChangeListener *listener, ChangeTypes types)
3103 ChangeListener change(listener, types);
3104 changeListeners.removeOne(change);
3107 void QQuickItemPrivate::updateOrAddGeometryChangeListener(QQuickItemChangeListener *listener, GeometryChangeTypes types)
3109 ChangeListener change(listener, types);
3110 int index = changeListeners.find(change);
3112 changeListeners[index].gTypes = change.gTypes; //we may have different GeometryChangeTypes
3114 changeListeners.append(change);
3117 void QQuickItemPrivate::updateOrRemoveGeometryChangeListener(QQuickItemChangeListener *listener,
3118 GeometryChangeTypes types)
3120 ChangeListener change(listener, types);
3121 if (types == NoChange) {
3122 changeListeners.removeOne(change);
3124 int index = changeListeners.find(change);
3126 changeListeners[index].gTypes = change.gTypes; //we may have different GeometryChangeTypes
3130 void QQuickItem::keyPressEvent(QKeyEvent *event)
3135 void QQuickItem::keyReleaseEvent(QKeyEvent *event)
3140 void QQuickItem::inputMethodEvent(QInputMethodEvent *event)
3145 void QQuickItem::focusInEvent(QFocusEvent *)
3147 #ifndef QT_NO_ACCESSIBILITY
3148 QAccessibleEvent ev(this, QAccessible::Focus);
3149 QAccessible::updateAccessibility(&ev);
3153 void QQuickItem::focusOutEvent(QFocusEvent *)
3157 void QQuickItem::mousePressEvent(QMouseEvent *event)
3162 void QQuickItem::mouseMoveEvent(QMouseEvent *event)
3167 void QQuickItem::mouseReleaseEvent(QMouseEvent *event)
3172 void QQuickItem::mouseDoubleClickEvent(QMouseEvent *)
3176 void QQuickItem::mouseUngrabEvent()
3181 void QQuickItem::touchUngrabEvent()
3186 void QQuickItem::wheelEvent(QWheelEvent *event)
3191 void QQuickItem::touchEvent(QTouchEvent *event)
3196 void QQuickItem::hoverEnterEvent(QHoverEvent *event)
3201 void QQuickItem::hoverMoveEvent(QHoverEvent *event)
3206 void QQuickItem::hoverLeaveEvent(QHoverEvent *event)
3211 void QQuickItem::dragEnterEvent(QDragEnterEvent *event)
3216 void QQuickItem::dragMoveEvent(QDragMoveEvent *event)
3222 void QQuickItem::dragLeaveEvent(QDragLeaveEvent *event)
3228 void QQuickItem::dropEvent(QDropEvent *event)
3233 bool QQuickItem::childMouseEventFilter(QQuickItem *, QEvent *)
3238 void QQuickItem::windowDeactivateEvent()
3240 foreach (QQuickItem* item, childItems()) {
3241 item->windowDeactivateEvent();
3245 QVariant QQuickItem::inputMethodQuery(Qt::InputMethodQuery query) const
3247 Q_D(const QQuickItem);
3252 v = (bool)(flags() & ItemAcceptsInputMethod);
3255 case Qt::ImCursorRectangle:
3257 case Qt::ImCursorPosition:
3258 case Qt::ImSurroundingText:
3259 case Qt::ImCurrentSelection:
3260 case Qt::ImMaximumTextLength:
3261 case Qt::ImAnchorPosition:
3262 case Qt::ImPreferredLanguage:
3263 if (d->extra.isAllocated() && d->extra->keyHandler)
3264 v = d->extra->keyHandler->inputMethodQuery(query);
3272 QQuickAnchorLine QQuickItemPrivate::left() const
3274 Q_Q(const QQuickItem);
3275 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Left);
3278 QQuickAnchorLine QQuickItemPrivate::right() const
3280 Q_Q(const QQuickItem);
3281 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Right);
3284 QQuickAnchorLine QQuickItemPrivate::horizontalCenter() const
3286 Q_Q(const QQuickItem);
3287 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::HCenter);
3290 QQuickAnchorLine QQuickItemPrivate::top() const
3292 Q_Q(const QQuickItem);
3293 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Top);
3296 QQuickAnchorLine QQuickItemPrivate::bottom() const
3298 Q_Q(const QQuickItem);
3299 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Bottom);
3302 QQuickAnchorLine QQuickItemPrivate::verticalCenter() const
3304 Q_Q(const QQuickItem);
3305 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::VCenter);
3308 QQuickAnchorLine QQuickItemPrivate::baseline() const
3310 Q_Q(const QQuickItem);
3311 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Baseline);
3314 qreal QQuickItem::baselineOffset() const
3316 Q_D(const QQuickItem);
3317 if (d->baselineOffsetValid) {
3318 return d->baselineOffset;
3324 void QQuickItem::setBaselineOffset(qreal offset)
3327 if (offset == d->baselineOffset)
3330 d->baselineOffset = offset;
3331 d->baselineOffsetValid = true;
3333 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
3334 const QQuickItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
3335 if (change.types & QQuickItemPrivate::Geometry) {
3336 QQuickAnchorsPrivate *anchor = change.listener->anchorPrivate();
3338 anchor->updateVerticalAnchors();
3342 if (d->_anchors && (d->_anchors->usedAnchors() & QQuickAnchors::BaselineAnchor))
3343 QQuickAnchorsPrivate::get(d->_anchors)->updateVerticalAnchors();
3345 emit baselineOffsetChanged(offset);
3348 void QQuickItem::update()
3351 Q_ASSERT(flags() & ItemHasContents);
3352 d->dirty(QQuickItemPrivate::Content);
3355 void QQuickItem::polish()
3358 if (!d->polishScheduled) {
3359 d->polishScheduled = true;
3361 QQuickCanvasPrivate *p = QQuickCanvasPrivate::get(d->canvas);
3362 bool maybeupdate = p->itemsToPolish.isEmpty();
3363 p->itemsToPolish.insert(this);
3364 if (maybeupdate) d->canvas->maybeUpdate();
3369 void QQuickItem::mapFromItem(QQmlV8Function *args) const
3371 if (args->Length() != 0) {
3372 v8::Local<v8::Value> item = (*args)[0];
3373 QV8Engine *engine = args->engine();
3375 QQuickItem *itemObj = 0;
3376 if (!item->IsNull())
3377 itemObj = qobject_cast<QQuickItem*>(engine->toQObject(item));
3379 if (!itemObj && !item->IsNull()) {
3380 qmlInfo(this) << "mapFromItem() given argument \"" << engine->toString(item->ToString())
3381 << "\" which is neither null nor an Item";
3385 v8::Local<v8::Object> rv = v8::Object::New();
3386 args->returnValue(rv);
3388 qreal x = (args->Length() > 1)?(*args)[1]->NumberValue():0;
3389 qreal y = (args->Length() > 2)?(*args)[2]->NumberValue():0;
3391 QPointF p = mapFromItem(itemObj, QPointF(x, y));
3393 rv->Set(v8::String::New("x"), v8::Number::New(p.x()));
3394 rv->Set(v8::String::New("y"), v8::Number::New(p.y()));
3398 QTransform QQuickItem::itemTransform(QQuickItem *other, bool *ok) const
3400 Q_D(const QQuickItem);
3402 // XXX todo - we need to be able to handle common parents better and detect
3406 QTransform t = d->itemToCanvasTransform();
3407 if (other) t *= QQuickItemPrivate::get(other)->canvasToItemTransform();
3412 void QQuickItem::mapToItem(QQmlV8Function *args) const
3414 if (args->Length() != 0) {
3415 v8::Local<v8::Value> item = (*args)[0];
3416 QV8Engine *engine = args->engine();
3418 QQuickItem *itemObj = 0;
3419 if (!item->IsNull())
3420 itemObj = qobject_cast<QQuickItem*>(engine->toQObject(item));
3422 if (!itemObj && !item->IsNull()) {
3423 qmlInfo(this) << "mapToItem() given argument \"" << engine->toString(item->ToString())
3424 << "\" which is neither null nor an Item";
3428 v8::Local<v8::Object> rv = v8::Object::New();
3429 args->returnValue(rv);
3431 qreal x = (args->Length() > 1)?(*args)[1]->NumberValue():0;
3432 qreal y = (args->Length() > 2)?(*args)[2]->NumberValue():0;
3434 QPointF p = mapToItem(itemObj, QPointF(x, y));
3436 rv->Set(v8::String::New("x"), v8::Number::New(p.x()));
3437 rv->Set(v8::String::New("y"), v8::Number::New(p.y()));
3441 void QQuickItem::forceActiveFocus()
3444 QQuickItem *parent = parentItem();
3446 if (parent->flags() & QQuickItem::ItemIsFocusScope) {
3447 parent->setFocus(true);
3449 parent = parent->parentItem();
3453 QQuickItem *QQuickItem::childAt(qreal x, qreal y) const
3455 // XXX todo - should this include transform etc.?
3456 const QList<QQuickItem *> children = childItems();
3457 for (int i = children.count()-1; i >= 0; --i) {
3458 QQuickItem *child = children.at(i);
3459 if (child->isVisible() && child->x() <= x
3460 && child->x() + child->width() >= x
3462 && child->y() + child->height() >= y)
3468 QQmlListProperty<QObject> QQuickItemPrivate::resources()
3470 return QQmlListProperty<QObject>(q_func(), 0, QQuickItemPrivate::resources_append,
3471 QQuickItemPrivate::resources_count,
3472 QQuickItemPrivate::resources_at,
3473 QQuickItemPrivate::resources_clear);
3476 QQmlListProperty<QQuickItem> QQuickItemPrivate::children()
3478 return QQmlListProperty<QQuickItem>(q_func(), 0, QQuickItemPrivate::children_append,
3479 QQuickItemPrivate::children_count,
3480 QQuickItemPrivate::children_at,
3481 QQuickItemPrivate::children_clear);
3486 \qmlproperty real QtQuick2::Item::visibleChildren
3487 This read-only property lists all of the item's children that are currently visible.
3488 Note that a child's visibility may have changed explicitly, or because the visibility
3489 of this (it's parent) item or another grandparent changed.
3491 QQmlListProperty<QQuickItem> QQuickItemPrivate::visibleChildren()
3493 return QQmlListProperty<QQuickItem>(q_func(), 0, QQuickItemPrivate::visibleChildren_append,
3494 QQuickItemPrivate::visibleChildren_count,
3495 QQuickItemPrivate::visibleChildren_at);
3499 QQmlListProperty<QQuickState> QQuickItemPrivate::states()
3501 return _states()->statesProperty();
3504 QQmlListProperty<QQuickTransition> QQuickItemPrivate::transitions()
3506 return _states()->transitionsProperty();
3509 QString QQuickItemPrivate::state() const
3514 return _stateGroup->state();
3517 void QQuickItemPrivate::setState(const QString &state)
3519 _states()->setState(state);
3522 QString QQuickItem::state() const
3524 Q_D(const QQuickItem);
3528 void QQuickItem::setState(const QString &state)
3534 QQmlListProperty<QQuickTransform> QQuickItem::transform()
3536 return QQmlListProperty<QQuickTransform>(this, 0, QQuickItemPrivate::transform_append,
3537 QQuickItemPrivate::transform_count,
3538 QQuickItemPrivate::transform_at,
3539 QQuickItemPrivate::transform_clear);
3542 void QQuickItem::classBegin()
3545 d->componentComplete = false;
3547 d->_stateGroup->classBegin();
3549 d->_anchors->classBegin();
3550 if (d->extra.isAllocated() && d->extra->layer)
3551 d->extra->layer->classBegin();
3554 void QQuickItem::componentComplete()
3557 d->componentComplete = true;
3559 d->_stateGroup->componentComplete();
3561 d->_anchors->componentComplete();
3562 QQuickAnchorsPrivate::get(d->_anchors)->updateOnComplete();
3565 if (d->extra.isAllocated() && d->extra->layer)
3566 d->extra->layer->componentComplete();
3568 if (d->extra.isAllocated() && d->extra->keyHandler)
3569 d->extra->keyHandler->componentComplete();
3571 if (d->extra.isAllocated() && d->extra->contents)
3572 d->extra->contents->complete();
3575 QQuickStateGroup *QQuickItemPrivate::_states()
3579 _stateGroup = new QQuickStateGroup;
3580 if (!componentComplete)
3581 _stateGroup->classBegin();
3582 FAST_CONNECT(_stateGroup, SIGNAL(stateChanged(QString)),
3583 q, SIGNAL(stateChanged(QString)))
3589 QPointF QQuickItemPrivate::computeTransformOrigin() const
3593 case QQuickItem::TopLeft:
3594 return QPointF(0, 0);
3595 case QQuickItem::Top:
3596 return QPointF(width / 2., 0);
3597 case QQuickItem::TopRight:
3598 return QPointF(width, 0);
3599 case QQuickItem::Left:
3600 return QPointF(0, height / 2.);
3601 case QQuickItem::Center:
3602 return QPointF(width / 2., height / 2.);
3603 case QQuickItem::Right:
3604 return QPointF(width, height / 2.);
3605 case QQuickItem::BottomLeft:
3606 return QPointF(0, height);
3607 case QQuickItem::Bottom:
3608 return QPointF(width / 2., height);
3609 case QQuickItem::BottomRight:
3610 return QPointF(width, height);
3614 void QQuickItemPrivate::transformChanged()
3616 if (extra.isAllocated() && extra->layer)
3617 extra->layer->updateMatrix();
3620 void QQuickItemPrivate::deliverKeyEvent(QKeyEvent *e)
3624 Q_ASSERT(e->isAccepted());
3625 if (extra.isAllocated() && extra->keyHandler) {
3626 if (e->type() == QEvent::KeyPress)
3627 extra->keyHandler->keyPressed(e, false);
3629 extra->keyHandler->keyReleased(e, false);
3631 if (e->isAccepted())
3637 if (e->type() == QEvent::KeyPress)
3638 q->keyPressEvent(e);
3640 q->keyReleaseEvent(e);
3642 if (e->isAccepted())
3645 if (extra.isAllocated() && extra->keyHandler) {
3648 if (e->type() == QEvent::KeyPress)
3649 extra->keyHandler->keyPressed(e, true);
3651 extra->keyHandler->keyReleased(e, true);
3655 void QQuickItemPrivate::deliverInputMethodEvent(QInputMethodEvent *e)
3659 Q_ASSERT(e->isAccepted());
3660 if (extra.isAllocated() && extra->keyHandler) {
3661 extra->keyHandler->inputMethodEvent(e, false);
3663 if (e->isAccepted())
3669 q->inputMethodEvent(e);
3671 if (e->isAccepted())
3674 if (extra.isAllocated() && extra->keyHandler) {
3677 extra->keyHandler->inputMethodEvent(e, true);
3681 void QQuickItemPrivate::deliverFocusEvent(QFocusEvent *e)
3685 if (e->type() == QEvent::FocusIn) {
3688 q->focusOutEvent(e);
3692 void QQuickItemPrivate::deliverMouseEvent(QMouseEvent *e)
3696 Q_ASSERT(e->isAccepted());
3698 switch (e->type()) {
3700 Q_ASSERT(!"Unknown event type");
3701 case QEvent::MouseMove:
3702 q->mouseMoveEvent(e);
3704 case QEvent::MouseButtonPress:
3705 q->mousePressEvent(e);
3707 case QEvent::MouseButtonRelease:
3708 q->mouseReleaseEvent(e);
3710 case QEvent::MouseButtonDblClick:
3711 q->mouseDoubleClickEvent(e);
3716 void QQuickItemPrivate::deliverWheelEvent(QWheelEvent *e)
3722 void QQuickItemPrivate::deliverTouchEvent(QTouchEvent *e)
3728 void QQuickItemPrivate::deliverHoverEvent(QHoverEvent *e)
3731 switch (e->type()) {
3733 Q_ASSERT(!"Unknown event type");
3734 case QEvent::HoverEnter:
3735 q->hoverEnterEvent(e);
3737 case QEvent::HoverLeave:
3738 q->hoverLeaveEvent(e);
3740 case QEvent::HoverMove:
3741 q->hoverMoveEvent(e);
3746 void QQuickItemPrivate::deliverDragEvent(QEvent *e)
3749 switch (e->type()) {
3751 Q_ASSERT(!"Unknown event type");
3752 case QEvent::DragEnter:
3753 q->dragEnterEvent(static_cast<QDragEnterEvent *>(e));
3755 case QEvent::DragLeave:
3756 q->dragLeaveEvent(static_cast<QDragLeaveEvent *>(e));
3758 case QEvent::DragMove:
3759 q->dragMoveEvent(static_cast<QDragMoveEvent *>(e));
3762 q->dropEvent(static_cast<QDropEvent *>(e));
3767 void QQuickItem::itemChange(ItemChange change, const ItemChangeData &value)
3774 Notify input method on updated query values if needed. \a indicates changed attributes.
3776 void QQuickItem::updateInputMethod(Qt::InputMethodQueries queries)
3778 if (hasActiveFocus())
3779 qApp->inputMethod()->update(queries);
3783 // XXX todo - do we want/need this anymore?
3784 QRectF QQuickItem::boundingRect() const
3786 Q_D(const QQuickItem);
3787 return QRectF(0, 0, d->width, d->height);
3791 QRectF QQuickItem::clipRect() const
3793 Q_D(const QQuickItem);
3794 return QRectF(0, 0, d->width, d->height);
3798 QQuickItem::TransformOrigin QQuickItem::transformOrigin() const
3800 Q_D(const QQuickItem);
3804 void QQuickItem::setTransformOrigin(TransformOrigin origin)
3807 if (origin == d->origin())
3810 d->extra.value().origin = origin;
3811 d->dirty(QQuickItemPrivate::TransformOrigin);
3813 emit transformOriginChanged(d->origin());
3816 QPointF QQuickItem::transformOriginPoint() const
3818 Q_D(const QQuickItem);
3819 if (d->extra.isAllocated() && !d->extra->userTransformOriginPoint.isNull())
3820 return d->extra->userTransformOriginPoint;
3821 return d->computeTransformOrigin();
3824 void QQuickItem::setTransformOriginPoint(const QPointF &point)
3827 if (d->extra.value().userTransformOriginPoint == point)
3830 d->extra->userTransformOriginPoint = point;
3831 d->dirty(QQuickItemPrivate::TransformOrigin);
3834 qreal QQuickItem::z() const
3836 Q_D(const QQuickItem);
3840 void QQuickItem::setZ(qreal v)
3846 d->extra.value().z = v;
3848 d->dirty(QQuickItemPrivate::ZValue);
3849 if (d->parentItem) {
3850 QQuickItemPrivate::get(d->parentItem)->dirty(QQuickItemPrivate::ChildrenStackingChanged);
3851 QQuickItemPrivate::get(d->parentItem)->markSortedChildrenDirty(this);
3856 if (d->extra.isAllocated() && d->extra->layer)
3857 d->extra->layer->updateZ();
3862 \qmlproperty real QtQuick2::Item::rotation
3863 This property holds the rotation of the item in degrees clockwise.
3865 This specifies how many degrees to rotate the item around its transformOrigin.
3866 The default rotation is 0 degrees (i.e. not rotated at all).
3870 \li \image declarative-rotation.png
3875 width: 100; height: 100
3878 x: 25; y: 25; width: 50; height: 50
3885 \sa transform, Rotation
3889 \qmlproperty real QtQuick2::Item::scale
3890 This property holds the scale of the item.
3892 A scale of less than 1 means the item will be displayed smaller than
3893 normal, and a scale of greater than 1 means the item will be
3894 displayed larger than normal. A negative scale means the item will
3897 By default, items are displayed at a scale of 1 (i.e. at their
3900 Scaling is from the item's transformOrigin.
3904 \li \image declarative-scale.png
3909 width: 100; height: 100
3912 width: 25; height: 25
3916 x: 25; y: 25; width: 50; height: 50
3923 \sa transform, Scale
3927 \qmlproperty real QtQuick2::Item::opacity
3929 This property holds the opacity of the item. Opacity is specified as a
3930 number between 0 (fully transparent) and 1 (fully opaque). The default is 1.
3932 When this property is set, the specified opacity is also applied
3933 individually to child items. In almost all cases this is what you want,
3934 but in some cases it may produce undesired results. For example in the
3935 second set of rectangles below, the red rectangle has specified an opacity
3936 of 0.5, which affects the opacity of its blue child rectangle even though
3937 the child has not specified an opacity.
3941 \li \image declarative-item_opacity1.png
3947 width: 100; height: 100
3950 x: 50; y: 50; width: 100; height: 100
3956 \li \image declarative-item_opacity2.png
3963 width: 100; height: 100
3966 x: 50; y: 50; width: 100; height: 100
3973 If an item's opacity is set to 0, the item will no longer receive mouse
3974 events, but will continue to receive key events and will retain the keyboard
3975 \l focus if it has been set. (In contrast, setting the \l visible property
3976 to \c false stops both mouse and keyboard events, and also removes focus
3981 Returns a value indicating whether mouse input should
3982 remain with this item exclusively.
3984 \sa setKeepMouseGrab()
3987 qreal QQuickItem::rotation() const
3989 Q_D(const QQuickItem);
3990 return d->rotation();
3993 void QQuickItem::setRotation(qreal r)
3996 if (d->rotation() == r)
3999 d->extra.value().rotation = r;
4001 d->dirty(QQuickItemPrivate::BasicTransform);
4003 d->itemChange(ItemRotationHasChanged, r);
4005 emit rotationChanged();
4008 qreal QQuickItem::scale() const
4010 Q_D(const QQuickItem);
4014 void QQuickItem::setScale(qreal s)
4017 if (d->scale() == s)
4020 d->extra.value().scale = s;
4022 d->dirty(QQuickItemPrivate::BasicTransform);
4024 emit scaleChanged();
4027 qreal QQuickItem::opacity() const
4029 Q_D(const QQuickItem);
4030 return d->opacity();
4033 void QQuickItem::setOpacity(qreal o)
4036 if (d->opacity() == o)
4039 d->extra.value().opacity = o;
4041 d->dirty(QQuickItemPrivate::OpacityValue);
4043 d->itemChange(ItemOpacityHasChanged, o);
4045 emit opacityChanged();
4048 bool QQuickItem::isVisible() const
4050 Q_D(const QQuickItem);
4051 return d->effectiveVisible;
4054 void QQuickItem::setVisible(bool v)
4057 if (v == d->explicitVisible)
4060 d->explicitVisible = v;
4062 const bool childVisibilityChanged = d->setEffectiveVisibleRecur(d->calcEffectiveVisible());
4063 if (childVisibilityChanged && d->parentItem)
4064 emit d->parentItem->visibleChildrenChanged(); // signal the parent, not this!
4067 bool QQuickItem::isEnabled() const
4069 Q_D(const QQuickItem);
4070 return d->effectiveEnable;
4073 void QQuickItem::setEnabled(bool e)
4076 if (e == d->explicitEnable)
4079 d->explicitEnable = e;
4081 QQuickItem *scope = parentItem();
4082 while (scope && !scope->isFocusScope())
4083 scope = scope->parentItem();
4085 d->setEffectiveEnableRecur(scope, d->calcEffectiveEnable());
4088 bool QQuickItemPrivate::calcEffectiveVisible() const
4090 // XXX todo - Should the effective visible of an element with no parent just be the current
4091 // effective visible? This would prevent pointless re-processing in the case of an element
4092 // moving to/from a no-parent situation, but it is different from what graphics view does.
4093 return explicitVisible && (!parentItem || QQuickItemPrivate::get(parentItem)->effectiveVisible);
4096 bool QQuickItemPrivate::setEffectiveVisibleRecur(bool newEffectiveVisible)
4100 if (newEffectiveVisible && !explicitVisible) {
4101 // This item locally overrides visibility
4102 return false; // effective visibility didn't change
4105 if (newEffectiveVisible == effectiveVisible) {
4106 // No change necessary
4107 return false; // effective visibility didn't change
4110 effectiveVisible = newEffectiveVisible;
4112 if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
4115 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(canvas);
4116 if (canvasPriv->mouseGrabberItem == q)
4120 bool childVisibilityChanged = false;
4121 for (int ii = 0; ii < childItems.count(); ++ii)
4122 childVisibilityChanged |= QQuickItemPrivate::get(childItems.at(ii))->setEffectiveVisibleRecur(newEffectiveVisible);
4124 itemChange(QQuickItem::ItemVisibleHasChanged, effectiveVisible);
4125 #ifndef QT_NO_ACCESSIBILITY
4127 QAccessibleEvent ev(q, effectiveVisible ? QAccessible::ObjectShow : QAccessible::ObjectHide);
4128 QAccessible::updateAccessibility(&ev);
4131 emit q->visibleChanged();
4132 if (childVisibilityChanged)
4133 emit q->visibleChildrenChanged();
4135 return true; // effective visibility DID change
4138 bool QQuickItemPrivate::calcEffectiveEnable() const
4140 // XXX todo - Should the effective enable of an element with no parent just be the current
4141 // effective enable? This would prevent pointless re-processing in the case of an element
4142 // moving to/from a no-parent situation, but it is different from what graphics view does.
4143 return explicitEnable && (!parentItem || QQuickItemPrivate::get(parentItem)->effectiveEnable);
4146 void QQuickItemPrivate::setEffectiveEnableRecur(QQuickItem *scope, bool newEffectiveEnable)
4150 if (newEffectiveEnable && !explicitEnable) {
4151 // This item locally overrides enable
4155 if (newEffectiveEnable == effectiveEnable) {
4156 // No change necessary
4160 effectiveEnable = newEffectiveEnable;
4163 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(canvas);
4164 if (canvasPriv->mouseGrabberItem == q)
4166 if (scope && !effectiveEnable && activeFocus) {
4167 canvasPriv->clearFocusInScope(
4168 scope, q, QQuickCanvasPrivate::DontChangeFocusProperty | QQuickCanvasPrivate::DontChangeSubFocusItem);
4172 for (int ii = 0; ii < childItems.count(); ++ii) {
4173 QQuickItemPrivate::get(childItems.at(ii))->setEffectiveEnableRecur(
4174 (flags & QQuickItem::ItemIsFocusScope) && scope ? q : scope, newEffectiveEnable);
4177 if (canvas && scope && effectiveEnable && focus) {
4178 QQuickCanvasPrivate::get(canvas)->setFocusInScope(
4179 scope, q, QQuickCanvasPrivate::DontChangeFocusProperty | QQuickCanvasPrivate::DontChangeSubFocusItem);
4182 emit q->enabledChanged();
4185 QString QQuickItemPrivate::dirtyToString() const
4187 #define DIRTY_TO_STRING(value) if (dirtyAttributes & value) { \
4188 if (!rv.isEmpty()) \
4189 rv.append(QLatin1String("|")); \
4190 rv.append(QLatin1String(#value)); \
4193 // QString rv = QLatin1String("0x") + QString::number(dirtyAttributes, 16);
4196 DIRTY_TO_STRING(TransformOrigin);
4197 DIRTY_TO_STRING(Transform);
4198 DIRTY_TO_STRING(BasicTransform);
4199 DIRTY_TO_STRING(Position);
4200 DIRTY_TO_STRING(Size);
4201 DIRTY_TO_STRING(ZValue);
4202 DIRTY_TO_STRING(Content);
4203 DIRTY_TO_STRING(Smooth);
4204 DIRTY_TO_STRING(OpacityValue);
4205 DIRTY_TO_STRING(ChildrenChanged);
4206 DIRTY_TO_STRING(ChildrenStackingChanged);
4207 DIRTY_TO_STRING(ParentChanged);
4208 DIRTY_TO_STRING(Clip);
4209 DIRTY_TO_STRING(Canvas);
4210 DIRTY_TO_STRING(EffectReference);
4211 DIRTY_TO_STRING(Visible);
4212 DIRTY_TO_STRING(HideReference);
4213 DIRTY_TO_STRING(PerformanceHints);
4218 void QQuickItemPrivate::dirty(DirtyType type)
4221 if (type & (TransformOrigin | Transform | BasicTransform | Position | Size))
4224 if (!(dirtyAttributes & type) || (canvas && !prevDirtyItem)) {
4225 dirtyAttributes |= type;
4228 QQuickCanvasPrivate::get(canvas)->dirtyItem(q);
4233 void QQuickItemPrivate::addToDirtyList()
4238 if (!prevDirtyItem) {
4239 Q_ASSERT(!nextDirtyItem);
4241 QQuickCanvasPrivate *p = QQuickCanvasPrivate::get(canvas);
4242 nextDirtyItem = p->dirtyItemList;
4243 if (nextDirtyItem) QQuickItemPrivate::get(nextDirtyItem)->prevDirtyItem = &nextDirtyItem;
4244 prevDirtyItem = &p->dirtyItemList;
4245 p->dirtyItemList = q;
4248 Q_ASSERT(prevDirtyItem);
4251 void QQuickItemPrivate::removeFromDirtyList()
4253 if (prevDirtyItem) {
4254 if (nextDirtyItem) QQuickItemPrivate::get(nextDirtyItem)->prevDirtyItem = prevDirtyItem;
4255 *prevDirtyItem = nextDirtyItem;
4259 Q_ASSERT(!prevDirtyItem);
4260 Q_ASSERT(!nextDirtyItem);
4263 void QQuickItemPrivate::refFromEffectItem(bool hide)
4265 ++extra.value().effectRefCount;
4266 if (1 == extra->effectRefCount) {
4267 dirty(EffectReference);
4268 if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
4271 if (++extra->hideRefCount == 1)
4272 dirty(HideReference);
4276 void QQuickItemPrivate::derefFromEffectItem(bool unhide)
4278 Q_ASSERT(extra->effectRefCount);
4279 --extra->effectRefCount;
4280 if (0 == extra->effectRefCount) {
4281 dirty(EffectReference);
4282 if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
4285 if (--extra->hideRefCount == 0)
4286 dirty(HideReference);
4290 void QQuickItemPrivate::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data)
4294 case QQuickItem::ItemChildAddedChange:
4295 q->itemChange(change, data);
4296 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4297 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4298 if (change.types & QQuickItemPrivate::Children) {
4299 change.listener->itemChildAdded(q, data.item);
4303 case QQuickItem::ItemChildRemovedChange:
4304 q->itemChange(change, data);
4305 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4306 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4307 if (change.types & QQuickItemPrivate::Children) {
4308 change.listener->itemChildRemoved(q, data.item);
4312 case QQuickItem::ItemSceneChange:
4313 q->itemChange(change, data);
4315 case QQuickItem::ItemVisibleHasChanged:
4316 q->itemChange(change, data);
4317 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4318 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4319 if (change.types & QQuickItemPrivate::Visibility) {
4320 change.listener->itemVisibilityChanged(q);
4324 case QQuickItem::ItemParentHasChanged:
4325 q->itemChange(change, data);
4326 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4327 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4328 if (change.types & QQuickItemPrivate::Parent) {
4329 change.listener->itemParentChanged(q, data.item);
4333 case QQuickItem::ItemOpacityHasChanged:
4334 q->itemChange(change, data);
4335 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4336 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4337 if (change.types & QQuickItemPrivate::Opacity) {
4338 change.listener->itemOpacityChanged(q);
4342 case QQuickItem::ItemActiveFocusHasChanged:
4343 q->itemChange(change, data);
4345 case QQuickItem::ItemRotationHasChanged:
4346 q->itemChange(change, data);
4347 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4348 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4349 if (change.types & QQuickItemPrivate::Rotation) {
4350 change.listener->itemRotationChanged(q);
4358 \property QQuickItem::smooth
4359 \brief whether the item is smoothed or not.
4361 Primarily used in image based elements to decide if the item should use smooth
4362 sampling or not. Smooth sampling is performed using linear interpolation, while
4363 non-smooth is performed using nearest neighbor.
4365 In Qt Quick 2.0, this property has minimal impact on performance.
4371 Returns true if the item should be drawn with antialiasing and
4372 smooth pixmap filtering, false otherwise.
4374 The default is false.
4378 bool QQuickItem::smooth() const
4380 Q_D(const QQuickItem);
4385 Sets whether the item should be drawn with antialiasing and
4386 smooth pixmap filtering to \a smooth.
4390 void QQuickItem::setSmooth(bool smooth)
4393 if (d->smooth == smooth)
4397 d->dirty(QQuickItemPrivate::Smooth);
4399 emit smoothChanged(smooth);
4402 QQuickItem::Flags QQuickItem::flags() const
4404 Q_D(const QQuickItem);
4405 return (QQuickItem::Flags)d->flags;
4408 void QQuickItem::setFlag(Flag flag, bool enabled)
4412 setFlags((Flags)(d->flags | (quint32)flag));
4414 setFlags((Flags)(d->flags & ~(quint32)flag));
4417 void QQuickItem::setFlags(Flags flags)
4421 if ((flags & ItemIsFocusScope) != (d->flags & ItemIsFocusScope)) {
4422 if (flags & ItemIsFocusScope && !d->childItems.isEmpty() && d->canvas) {
4423 qWarning("QQuickItem: Cannot set FocusScope once item has children and is in a canvas.");
4424 flags &= ~ItemIsFocusScope;
4425 } else if (d->flags & ItemIsFocusScope) {
4426 qWarning("QQuickItem: Cannot unset FocusScope flag.");
4427 flags |= ItemIsFocusScope;
4431 if ((flags & ItemClipsChildrenToShape ) != (d->flags & ItemClipsChildrenToShape))
4432 d->dirty(QQuickItemPrivate::Clip);
4437 qreal QQuickItem::x() const
4439 Q_D(const QQuickItem);
4443 qreal QQuickItem::y() const
4445 Q_D(const QQuickItem);
4449 QPointF QQuickItem::pos() const
4451 Q_D(const QQuickItem);
4452 return QPointF(d->x, d->y);
4455 void QQuickItem::setX(qreal v)
4464 d->dirty(QQuickItemPrivate::Position);
4466 geometryChanged(QRectF(x(), y(), width(), height()),
4467 QRectF(oldx, y(), width(), height()));
4470 void QQuickItem::setY(qreal v)
4479 d->dirty(QQuickItemPrivate::Position);
4481 geometryChanged(QRectF(x(), y(), width(), height()),
4482 QRectF(x(), oldy, width(), height()));
4485 void QQuickItem::setPos(const QPointF &pos)
4488 if (QPointF(d->x, d->y) == pos)
4497 d->dirty(QQuickItemPrivate::Position);
4499 geometryChanged(QRectF(x(), y(), width(), height()),
4500 QRectF(oldx, oldy, width(), height()));
4503 qreal QQuickItem::width() const
4505 Q_D(const QQuickItem);
4509 void QQuickItem::setWidth(qreal w)
4515 d->widthValid = true;
4519 qreal oldWidth = d->width;
4522 d->dirty(QQuickItemPrivate::Size);
4524 geometryChanged(QRectF(x(), y(), width(), height()),
4525 QRectF(x(), y(), oldWidth, height()));
4528 void QQuickItem::resetWidth()
4531 d->widthValid = false;
4532 setImplicitWidth(implicitWidth());
4535 void QQuickItemPrivate::implicitWidthChanged()
4538 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4539 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4540 if (change.types & QQuickItemPrivate::ImplicitWidth) {
4541 change.listener->itemImplicitWidthChanged(q);
4544 emit q->implicitWidthChanged();
4547 qreal QQuickItemPrivate::getImplicitWidth() const
4549 return implicitWidth;
4552 Returns the width of the item that is implied by other properties that determine the content.
4554 qreal QQuickItem::implicitWidth() const
4556 Q_D(const QQuickItem);
4557 return d->getImplicitWidth();
4561 \qmlproperty real QtQuick2::Item::implicitWidth
4562 \qmlproperty real QtQuick2::Item::implicitHeight
4564 Defines the natural width or height of the Item if no \l width or \l height is specified.
4566 The default implicit size for most items is 0x0, however some elements have an inherent
4567 implicit size which cannot be overridden, e.g. Image, Text.
4569 Setting the implicit size is useful for defining components that have a preferred size
4570 based on their content, for example:
4577 property alias icon: image.source
4578 property alias label: text.text
4579 implicitWidth: text.implicitWidth + image.implicitWidth
4580 implicitHeight: Math.max(text.implicitHeight, image.implicitHeight)
4585 anchors.left: image.right; anchors.right: parent.right
4586 anchors.verticalCenter: parent.verticalCenter
4591 \b Note: using implicitWidth of Text or TextEdit and setting the width explicitly
4592 incurs a performance penalty as the text must be laid out twice.
4596 Sets the implied width of the item to \a w.
4597 This is the width implied by other properties that determine the content.
4599 void QQuickItem::setImplicitWidth(qreal w)
4602 bool changed = w != d->implicitWidth;
4603 d->implicitWidth = w;
4604 if (d->width == w || widthValid()) {
4606 d->implicitWidthChanged();
4607 if (d->width == w || widthValid())
4612 qreal oldWidth = d->width;
4615 d->dirty(QQuickItemPrivate::Size);
4617 geometryChanged(QRectF(x(), y(), width(), height()),
4618 QRectF(x(), y(), oldWidth, height()));
4621 d->implicitWidthChanged();
4625 Returns whether the width property has been set explicitly.
4627 bool QQuickItem::widthValid() const
4629 Q_D(const QQuickItem);
4630 return d->widthValid;
4633 qreal QQuickItem::height() const
4635 Q_D(const QQuickItem);
4639 void QQuickItem::setHeight(qreal h)
4645 d->heightValid = true;
4649 qreal oldHeight = d->height;
4652 d->dirty(QQuickItemPrivate::Size);
4654 geometryChanged(QRectF(x(), y(), width(), height()),
4655 QRectF(x(), y(), width(), oldHeight));
4658 void QQuickItem::resetHeight()
4661 d->heightValid = false;
4662 setImplicitHeight(implicitHeight());
4665 void QQuickItemPrivate::implicitHeightChanged()
4668 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4669 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4670 if (change.types & QQuickItemPrivate::ImplicitHeight) {
4671 change.listener->itemImplicitHeightChanged(q);
4674 emit q->implicitHeightChanged();
4677 qreal QQuickItemPrivate::getImplicitHeight() const
4679 return implicitHeight;
4683 Returns the height of the item that is implied by other properties that determine the content.
4685 qreal QQuickItem::implicitHeight() const
4687 Q_D(const QQuickItem);
4688 return d->getImplicitHeight();
4693 Sets the implied height of the item to \a h.
4694 This is the height implied by other properties that determine the content.
4696 void QQuickItem::setImplicitHeight(qreal h)
4699 bool changed = h != d->implicitHeight;
4700 d->implicitHeight = h;
4701 if (d->height == h || heightValid()) {
4703 d->implicitHeightChanged();
4704 if (d->height == h || heightValid())
4709 qreal oldHeight = d->height;
4712 d->dirty(QQuickItemPrivate::Size);
4714 geometryChanged(QRectF(x(), y(), width(), height()),
4715 QRectF(x(), y(), width(), oldHeight));
4718 d->implicitHeightChanged();
4721 void QQuickItem::setImplicitSize(qreal w, qreal h)
4724 bool wChanged = w != d->implicitWidth;
4725 bool hChanged = h != d->implicitHeight;
4727 d->implicitWidth = w;
4728 d->implicitHeight = h;
4732 if (d->width == w || widthValid()) {
4734 d->implicitWidthChanged();
4735 wDone = d->width == w || widthValid();
4738 if (d->height == h || heightValid()) {
4740 d->implicitHeightChanged();
4741 hDone = d->height == h || heightValid();
4747 qreal oldWidth = d->width;
4748 qreal oldHeight = d->height;
4754 d->dirty(QQuickItemPrivate::Size);
4756 geometryChanged(QRectF(x(), y(), width(), height()),
4757 QRectF(x(), y(), oldWidth, oldHeight));
4759 if (!wDone && wChanged)
4760 d->implicitWidthChanged();
4761 if (!hDone && hChanged)
4762 d->implicitHeightChanged();
4766 Returns whether the height property has been set explicitly.
4768 bool QQuickItem::heightValid() const
4770 Q_D(const QQuickItem);
4771 return d->heightValid;
4774 void QQuickItem::setSize(const QSizeF &size)
4777 d->heightValid = true;
4778 d->widthValid = true;
4780 if (QSizeF(d->width, d->height) == size)
4783 qreal oldHeight = d->height;
4784 qreal oldWidth = d->width;
4785 d->height = size.height();
4786 d->width = size.width();
4788 d->dirty(QQuickItemPrivate::Size);
4790 geometryChanged(QRectF(x(), y(), width(), height()),
4791 QRectF(x(), y(), oldWidth, oldHeight));
4794 bool QQuickItem::hasActiveFocus() const
4796 Q_D(const QQuickItem);
4797 return d->activeFocus;
4800 bool QQuickItem::hasFocus() const
4802 Q_D(const QQuickItem);
4806 void QQuickItem::setFocus(bool focus)
4809 if (d->focus == focus)
4812 if (d->canvas || d->parentItem) {
4813 // Need to find our nearest focus scope
4814 QQuickItem *scope = parentItem();
4815 while (scope && !scope->isFocusScope() && scope->parentItem())
4816 scope = scope->parentItem();
4819 QQuickCanvasPrivate::get(d->canvas)->setFocusInScope(scope, this);
4821 QQuickCanvasPrivate::get(d->canvas)->clearFocusInScope(scope, this);
4823 // do the focus changes from setFocusInScope/clearFocusInScope that are
4824 // unrelated to a canvas
4825 QVarLengthArray<QQuickItem *, 20> changed;
4826 QQuickItem *oldSubFocusItem = QQuickItemPrivate::get(scope)->subFocusItem;
4827 if (oldSubFocusItem) {
4828 QQuickItemPrivate::get(oldSubFocusItem)->updateSubFocusItem(scope, false);
4829 QQuickItemPrivate::get(oldSubFocusItem)->focus = false;
4830 changed << oldSubFocusItem;
4832 d->updateSubFocusItem(scope, focus);
4836 emit focusChanged(focus);
4838 QQuickCanvasPrivate::notifyFocusChangesRecur(changed.data(), changed.count() - 1);
4842 emit focusChanged(focus);
4846 bool QQuickItem::isFocusScope() const
4848 return flags() & ItemIsFocusScope;
4851 QQuickItem *QQuickItem::scopedFocusItem() const
4853 Q_D(const QQuickItem);
4854 if (!isFocusScope())
4857 return d->subFocusItem;
4861 Qt::MouseButtons QQuickItem::acceptedMouseButtons() const
4863 Q_D(const QQuickItem);
4864 return d->acceptedMouseButtons();
4867 void QQuickItem::setAcceptedMouseButtons(Qt::MouseButtons buttons)
4870 if (buttons & Qt::LeftButton)
4873 d->extra.clearFlag();
4875 buttons &= ~Qt::LeftButton;
4876 if (buttons || d->extra.isAllocated())
4877 d->extra.value().acceptedMouseButtons = buttons;
4880 bool QQuickItem::filtersChildMouseEvents() const
4882 Q_D(const QQuickItem);
4883 return d->filtersChildMouseEvents;
4886 void QQuickItem::setFiltersChildMouseEvents(bool filter)
4889 d->filtersChildMouseEvents = filter;
4892 bool QQuickItem::isUnderMouse() const
4894 Q_D(const QQuickItem);
4898 QPointF cursorPos = QGuiApplicationPrivate::lastCursorPosition;
4899 return contains(mapFromScene(cursorPos)); // ### refactor: d->canvas->mapFromGlobal(cursorPos))))
4902 bool QQuickItem::acceptHoverEvents() const
4904 Q_D(const QQuickItem);
4905 return d->hoverEnabled;
4908 void QQuickItem::setAcceptHoverEvents(bool enabled)
4911 d->hoverEnabled = enabled;
4914 void QQuickItem::grabMouse()
4919 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
4920 if (canvasPriv->mouseGrabberItem == this)
4923 QQuickItem *oldGrabber = canvasPriv->mouseGrabberItem;
4924 canvasPriv->mouseGrabberItem = this;
4926 QEvent ev(QEvent::UngrabMouse);
4927 d->canvas->sendEvent(oldGrabber, &ev);
4931 void QQuickItem::ungrabMouse()
4936 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
4937 if (canvasPriv->mouseGrabberItem != this) {
4938 qWarning("QQuickItem::ungrabMouse(): Item is not the mouse grabber.");
4942 canvasPriv->mouseGrabberItem = 0;
4944 QEvent ev(QEvent::UngrabMouse);
4945 d->canvas->sendEvent(this, &ev);
4948 bool QQuickItem::keepMouseGrab() const
4950 Q_D(const QQuickItem);
4951 return d->keepMouse;
4955 The flag indicating whether the mouse should remain
4956 with this item is set to \a keep.
4958 This is useful for items that wish to grab and keep mouse
4959 interaction following a predefined gesture. For example,
4960 an item that is interested in horizontal mouse movement
4961 may set keepMouseGrab to true once a threshold has been
4962 exceeded. Once keepMouseGrab has been set to true, filtering
4963 items will not react to mouse events.
4965 If the item does not indicate that it wishes to retain mouse grab,
4966 a filtering item may steal the grab. For example, Flickable may attempt
4967 to steal a mouse grab if it detects that the user has begun to
4972 void QQuickItem::setKeepMouseGrab(bool keep)
4975 d->keepMouse = keep;
4979 Grabs the touch points specified by \a ids.
4981 These touch points will be owned by the item until
4982 they are released. Alternatively, the grab can be stolen
4983 by a filtering item like Flickable. Use setKeepTouchGrab()
4984 to prevent the grab from being stolen.
4986 \sa ungrabTouchPoints(), setKeepTouchGrab()
4988 void QQuickItem::grabTouchPoints(const QList<int> &ids)
4993 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
4995 QSet<QQuickItem*> ungrab;
4996 for (int i = 0; i < ids.count(); ++i) {
4997 QQuickItem *oldGrabber = canvasPriv->itemForTouchPointId.value(ids.at(i));
4998 if (oldGrabber == this)
5001 canvasPriv->itemForTouchPointId[ids.at(i)] = this;
5003 ungrab.insert(oldGrabber);
5005 foreach (QQuickItem *oldGrabber, ungrab)
5006 oldGrabber->touchUngrabEvent();
5010 Ungrabs the touch points owned by this item.
5012 \sa grabTouchPoints()
5014 void QQuickItem::ungrabTouchPoints()
5019 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
5021 QMutableHashIterator<int, QQuickItem*> i(canvasPriv->itemForTouchPointId);
5022 while (i.hasNext()) {
5024 if (i.value() == this)
5031 Returns a value indicating whether the touch points grabbed by this item
5032 should remain with this item exclusively.
5034 \sa setKeepTouchGrab(), keepMouseGrab()
5036 bool QQuickItem::keepTouchGrab() const
5038 Q_D(const QQuickItem);
5039 return d->keepTouch;
5043 The flag indicating whether the touch points grabbed
5044 by this item should remain with this item is set to \a keep.
5046 This is useful for items that wish to grab and keep specific touch
5047 points following a predefined gesture. For example,
5048 an item that is interested in horizontal touch point movement
5049 may set setKeepTouchGrab to true once a threshold has been
5050 exceeded. Once setKeepTouchGrab has been set to true, filtering
5051 items will not react to the relevant touch points.
5053 If the item does not indicate that it wishes to retain touch point grab,
5054 a filtering item may steal the grab. For example, Flickable may attempt
5055 to steal a touch point grab if it detects that the user has begun to
5058 \sa keepTouchGrab(), setKeepMouseGrab()
5060 void QQuickItem::setKeepTouchGrab(bool keep)
5063 d->keepTouch = keep;
5067 Returns true if this item contains \a point, which is in local coordinates;
5068 returns false otherwise.
5070 This function can be overwritten in order to handle point collisions in items
5071 with custom shapes. The default implementation checks if the point is inside
5072 the item's bounding rect.
5074 Note that it's normally used to check if the item is under the mouse cursor,
5075 and for that reason, the implementation of this function should be as light-weight
5078 bool QQuickItem::contains(const QPointF &point) const
5080 Q_D(const QQuickItem);
5081 return QRectF(0, 0, d->width, d->height).contains(point);
5085 \qmlmethod object QtQuick2::Item::mapFromItem(Item item, real x, real y)
5087 Maps the point (\a x, \a y), which is in \a item's coordinate system, to
5088 this item's coordinate system, and returns an object with \c x and \c y
5089 properties matching the mapped coordinate.
5091 If \a item is a \c null value, this maps the point from the coordinate
5092 system of the root QML view.
5095 \qmlmethod object QtQuick2::Item::mapToItem(Item item, real x, real y)
5097 Maps the point (\a x, \a y), which is in this item's coordinate system, to
5098 \a item's coordinate system, and returns an object with \c x and \c y
5099 properties matching the mapped coordinate.
5101 If \a item is a \c null value, this maps \a x and \a y to the coordinate
5102 system of the root QML view.
5104 QPointF QQuickItem::mapToItem(const QQuickItem *item, const QPointF &point) const
5106 QPointF p = mapToScene(point);
5108 p = item->mapFromScene(p);
5112 QPointF QQuickItem::mapToScene(const QPointF &point) const
5114 Q_D(const QQuickItem);
5115 return d->itemToCanvasTransform().map(point);
5118 QRectF QQuickItem::mapRectToItem(const QQuickItem *item, const QRectF &rect) const
5120 Q_D(const QQuickItem);
5121 QTransform t = d->itemToCanvasTransform();
5123 t *= QQuickItemPrivate::get(item)->canvasToItemTransform();
5124 return t.mapRect(rect);
5127 QRectF QQuickItem::mapRectToScene(const QRectF &rect) const
5129 Q_D(const QQuickItem);
5130 return d->itemToCanvasTransform().mapRect(rect);
5133 QPointF QQuickItem::mapFromItem(const QQuickItem *item, const QPointF &point) const
5135 QPointF p = item?item->mapToScene(point):point;
5136 return mapFromScene(p);
5139 QPointF QQuickItem::mapFromScene(const QPointF &point) const
5141 Q_D(const QQuickItem);
5142 return d->canvasToItemTransform().map(point);
5145 QRectF QQuickItem::mapRectFromItem(const QQuickItem *item, const QRectF &rect) const
5147 Q_D(const QQuickItem);
5148 QTransform t = item?QQuickItemPrivate::get(item)->itemToCanvasTransform():QTransform();
5149 t *= d->canvasToItemTransform();
5150 return t.mapRect(rect);
5153 QRectF QQuickItem::mapRectFromScene(const QRectF &rect) const
5155 Q_D(const QQuickItem);
5156 return d->canvasToItemTransform().mapRect(rect);
5161 \qmlmethod QtQuick2::Item::forceActiveFocus()
5163 Forces active focus on the item.
5165 This method sets focus on the item and makes sure that all the focus scopes
5166 higher in the object hierarchy are also given the focus.
5170 Forces active focus on the item.
5172 This method sets focus on the item and makes sure that all the focus scopes
5173 higher in the object hierarchy are also given the focus.
5177 \qmlmethod QtQuick2::Item::childAt(real x, real y)
5179 Returns the visible child item at point (\a x, \a y), which is in this
5180 item's coordinate system, or \c null if there is no such item.
5184 Returns the visible child item at point (\a x, \a y), which is in this
5185 item's coordinate system, or 0 if there is no such item.
5189 \qmlproperty list<State> QtQuick2::Item::states
5190 This property holds a list of states defined by the item.
5206 \sa {qmlstate}{States}
5209 \qmlproperty list<Transition> QtQuick2::Item::transitions
5210 This property holds a list of transitions defined by the item.
5226 \sa {QML Animation and Transitions}{Transitions}
5229 \qmlproperty list<Filter> QtQuick2::Item::filter
5230 This property holds a list of graphical filters to be applied to the item.
5232 \l {Filter}{Filters} include things like \l {Blur}{blurring}
5233 the item, or giving it a \l Reflection. Some
5234 filters may not be available on all canvases; if a filter is not
5235 available on a certain canvas, it will simply not be applied for
5236 that canvas (but the QML will still be considered valid).
5254 \qmlproperty bool QtQuick2::Item::clip
5255 This property holds whether clipping is enabled. The default clip value is \c false.
5257 If clipping is enabled, an item will clip its own painting, as well
5258 as the painting of its children, to its bounding rectangle.
5260 Non-rectangular clipping regions are not supported for performance reasons.
5264 \property QQuickItem::clip
5265 This property holds whether clipping is enabled. The default clip value is \c false.
5267 If clipping is enabled, an item will clip its own painting, as well
5268 as the painting of its children, to its bounding rectangle. If you set
5269 clipping during an item's paint operation, remember to re-set it to
5270 prevent clipping the rest of your scene.
5272 Non-rectangular clipping regions are not supported for performance reasons.
5276 \qmlproperty string QtQuick2::Item::state
5278 This property holds the name of the current state of the item.
5280 This property is often used in scripts to change between states. For
5285 if (button.state == 'On')
5286 button.state = 'Off';
5288 button.state = 'On';
5292 If the item is in its base state (i.e. no explicit state has been
5293 set), \c state will be a blank string. Likewise, you can return an
5294 item to its base state by setting its current state to \c ''.
5296 \sa {qmlstates}{States}
5300 \qmlproperty list<Transform> QtQuick2::Item::transform
5301 This property holds the list of transformations to apply.
5303 For more information see \l Transform.
5307 \enum QQuickItem::TransformOrigin
5309 Controls the point about which simple transforms like scale apply.
5311 \value TopLeft The top-left corner of the item.
5312 \value Top The center point of the top of the item.
5313 \value TopRight The top-right corner of the item.
5314 \value Left The left most point of the vertical middle.
5315 \value Center The center of the item.
5316 \value Right The right most point of the vertical middle.
5317 \value BottomLeft The bottom-left corner of the item.
5318 \value Bottom The center point of the bottom of the item.
5319 \value BottomRight The bottom-right corner of the item.
5324 \qmlproperty bool QtQuick2::Item::activeFocus
5326 This property indicates whether the item has active focus.
5328 An item with active focus will receive keyboard input,
5329 or is a FocusScope ancestor of the item that will receive keyboard input.
5331 Usually, activeFocus is gained by setting focus on an item and its enclosing
5332 FocusScopes. In the following example \c input will have activeFocus.
5345 \sa focus, {qmlfocus}{Keyboard Focus}
5349 \qmlproperty bool QtQuick2::Item::focus
5350 This property indicates whether the item has focus within the enclosing focus scope. If true, this item
5351 will gain active focus when the enclosing focus scope gains active focus.
5352 In the following example, \c input will be given active focus when \c scope gains active focus.
5365 For the purposes of this property, the scene as a whole is assumed to act like a focus scope.
5366 On a practical level, that means the following QML will give active focus to \c input on startup.
5377 \sa activeFocus, {qmlfocus}{Keyboard Focus}
5382 \property QQuickItem::anchors
5387 \property QQuickItem::left
5392 \property QQuickItem::right
5397 \property QQuickItem::horizontalCenter
5402 \property QQuickItem::top
5407 \property QQuickItem::bottom
5412 \property QQuickItem::verticalCenter
5417 \property QQuickItem::focus
5422 \property QQuickItem::transform
5427 \property QQuickItem::transformOrigin
5432 \property QQuickItem::activeFocus
5437 \property QQuickItem::baseline
5442 \property QQuickItem::data
5447 \property QQuickItem::resources
5452 \property QQuickItem::state
5457 \property QQuickItem::states
5462 \property QQuickItem::transformOriginPoint
5467 \property QQuickItem::transitions
5471 bool QQuickItem::event(QEvent *ev)
5474 if (ev->type() == QEvent::PolishRequest) {
5476 d->polishScheduled = false;
5480 return QObject::event(ev);
5483 if (ev->type() == QEvent::InputMethodQuery) {
5484 QInputMethodQueryEvent *query = static_cast<QInputMethodQueryEvent *>(ev);
5485 Qt::InputMethodQueries queries = query->queries();
5486 for (uint i = 0; i < 32; ++i) {
5487 Qt::InputMethodQuery q = (Qt::InputMethodQuery)(int)(queries & (1<<i));
5489 QVariant v = inputMethodQuery(q);
5490 query->setValue(q, v);
5495 } else if (ev->type() == QEvent::InputMethod) {
5496 inputMethodEvent(static_cast<QInputMethodEvent *>(ev));
5499 return QObject::event(ev);
5502 #ifndef QT_NO_DEBUG_STREAM
5503 QDebug operator<<(QDebug debug, QQuickItem *item)
5506 debug << "QQuickItem(0)";
5510 debug << item->metaObject()->className() << "(this =" << ((void*)item)
5511 << ", name=" << item->objectName()
5512 << ", parent =" << ((void*)item->parentItem())
5513 << ", geometry =" << QRectF(item->pos(), QSizeF(item->width(), item->height()))
5514 << ", z =" << item->z() << ')';
5519 qint64 QQuickItemPrivate::consistentTime = -1;
5520 void QQuickItemPrivate::setConsistentTime(qint64 t)
5525 class QElapsedTimerConsistentTimeHack
5529 t1 = QQuickItemPrivate::consistentTime;
5533 return QQuickItemPrivate::consistentTime - t1;
5536 qint64 val = QQuickItemPrivate::consistentTime - t1;
5537 t1 = QQuickItemPrivate::consistentTime;
5547 void QQuickItemPrivate::start(QElapsedTimer &t)
5549 if (QQuickItemPrivate::consistentTime == -1)
5552 ((QElapsedTimerConsistentTimeHack*)&t)->start();
5555 qint64 QQuickItemPrivate::elapsed(QElapsedTimer &t)
5557 if (QQuickItemPrivate::consistentTime == -1)
5560 return ((QElapsedTimerConsistentTimeHack*)&t)->elapsed();
5563 qint64 QQuickItemPrivate::restart(QElapsedTimer &t)
5565 if (QQuickItemPrivate::consistentTime == -1)
5568 return ((QElapsedTimerConsistentTimeHack*)&t)->restart();
5572 \fn bool QQuickItem::isTextureProvider() const
5574 Returns true if this item is a texture provider. The default
5575 implementation returns false.
5577 This function can be called from any thread.
5580 bool QQuickItem::isTextureProvider() const
5582 Q_D(const QQuickItem);
5583 return d->extra.isAllocated() && d->extra->layer && d->extra->layer->effectSource() ?
5584 d->extra->layer->effectSource()->isTextureProvider() : false;
5588 \fn QSGTextureProvider *QQuickItem::textureProvider() const
5590 Returns the texture provider for an item. The default implementation
5593 This function may only be called on the rendering thread.
5596 QSGTextureProvider *QQuickItem::textureProvider() const
5598 Q_D(const QQuickItem);
5599 return d->extra.isAllocated() && d->extra->layer && d->extra->layer->effectSource() ?
5600 d->extra->layer->effectSource()->textureProvider() : 0;
5603 QQuickItemLayer *QQuickItemPrivate::layer() const
5605 if (!extra.isAllocated() || !extra->layer) {
5606 extra.value().layer = new QQuickItemLayer(const_cast<QQuickItem *>(q_func()));
5607 if (!componentComplete)
5608 extra->layer->classBegin();
5610 return extra->layer;
5613 QQuickItemLayer::QQuickItemLayer(QQuickItem *item)
5618 , m_componentComplete(true)
5619 , m_wrapMode(QQuickShaderEffectSource::ClampToEdge)
5620 , m_format(QQuickShaderEffectSource::RGBA)
5622 , m_effectComponent(0)
5628 QQuickItemLayer::~QQuickItemLayer()
5630 delete m_effectSource;
5637 \qmlproperty bool QtQuick2::Item::layer.enabled
5639 Holds wether the item is layered or not. Layering is disabled by default.
5641 A layered item is rendered into an offscreen surface and cached until
5642 it is changed. Enabling layering for complex QML item hierarchies can
5643 some times be an optimization.
5645 None of the other layer properties have any effect when the layer
5649 void QQuickItemLayer::setEnabled(bool e)
5654 if (m_componentComplete) {
5661 emit enabledChanged(e);
5664 void QQuickItemLayer::classBegin()
5666 Q_ASSERT(!m_effectSource);
5667 Q_ASSERT(!m_effect);
5668 m_componentComplete = false;
5671 void QQuickItemLayer::componentComplete()
5673 Q_ASSERT(!m_componentComplete);
5674 m_componentComplete = true;
5679 void QQuickItemLayer::activate()
5681 Q_ASSERT(!m_effectSource);
5682 m_effectSource = new QQuickShaderEffectSource();
5684 QQuickItem *parentItem = m_item->parentItem();
5686 m_effectSource->setParentItem(parentItem);
5687 m_effectSource->stackAfter(m_item);
5690 m_effectSource->setSourceItem(m_item);
5691 m_effectSource->setHideSource(true);
5692 m_effectSource->setSmooth(m_smooth);
5693 m_effectSource->setTextureSize(m_size);
5694 m_effectSource->setSourceRect(m_sourceRect);
5695 m_effectSource->setMipmap(m_mipmap);
5696 m_effectSource->setWrapMode(m_wrapMode);
5697 m_effectSource->setFormat(m_format);
5699 if (m_effectComponent)
5702 m_effectSource->setVisible(m_item->isVisible() && !m_effect);
5709 QQuickItemPrivate *id = QQuickItemPrivate::get(m_item);
5710 id->addItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Opacity | QQuickItemPrivate::Parent | QQuickItemPrivate::Visibility | QQuickItemPrivate::SiblingOrder);
5713 void QQuickItemLayer::deactivate()
5715 Q_ASSERT(m_effectSource);
5717 if (m_effectComponent)
5720 delete m_effectSource;
5723 QQuickItemPrivate *id = QQuickItemPrivate::get(m_item);
5724 id->removeItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Opacity | QQuickItemPrivate::Parent | QQuickItemPrivate::Visibility | QQuickItemPrivate::SiblingOrder);
5727 void QQuickItemLayer::activateEffect()
5729 Q_ASSERT(m_effectSource);
5730 Q_ASSERT(m_effectComponent);
5731 Q_ASSERT(!m_effect);
5733 QObject *created = m_effectComponent->beginCreate(m_effectComponent->creationContext());
5734 m_effect = qobject_cast<QQuickItem *>(created);
5736 qWarning("Item: layer.effect is not a QML Item.");
5737 m_effectComponent->completeCreate();
5741 QQuickItem *parentItem = m_item->parentItem();
5743 m_effect->setParentItem(parentItem);
5744 m_effect->stackAfter(m_effectSource);
5746 m_effect->setVisible(m_item->isVisible());
5747 m_effect->setProperty(m_name, qVariantFromValue<QObject *>(m_effectSource));
5748 m_effectComponent->completeCreate();
5751 void QQuickItemLayer::deactivateEffect()
5753 Q_ASSERT(m_effectSource);
5754 Q_ASSERT(m_effectComponent);
5762 \qmlproperty Component QtQuick2::Item::layer.effect
5764 Holds the effect that is applied to this layer.
5766 The effect is typically a \l ShaderEffect component, although any \l Item component can be
5767 assigned. The effect should have a source texture property with a name matching \l samplerName.
5772 void QQuickItemLayer::setEffect(QQmlComponent *component)
5774 if (component == m_effectComponent)
5777 bool updateNeeded = false;
5778 if (m_effectSource && m_effectComponent) {
5780 updateNeeded = true;
5783 m_effectComponent = component;
5785 if (m_effectSource && m_effectComponent) {
5787 updateNeeded = true;
5795 m_effectSource->setVisible(m_item->isVisible() && !m_effect);
5798 emit effectChanged(component);
5803 \qmlproperty bool QtQuick2::Item::layer.mipmap
5805 If this property is true, mipmaps are generated for the texture.
5807 \note Some OpenGL ES 2 implementations do not support mipmapping of
5808 non-power-of-two textures.
5811 void QQuickItemLayer::setMipmap(bool mipmap)
5813 if (mipmap == m_mipmap)
5818 m_effectSource->setMipmap(m_mipmap);
5820 emit mipmapChanged(mipmap);
5825 \qmlproperty enumeration QtQuick2::Item::layer.format
5827 This property defines the internal OpenGL format of the texture.
5828 Modifying this property makes most sense when the \a layer.effect is also
5829 specified. Depending on the OpenGL implementation, this property might
5830 allow you to save some texture memory.
5833 \li ShaderEffectSource.Alpha - GL_ALPHA
5834 \li ShaderEffectSource.RGB - GL_RGB
5835 \li ShaderEffectSource.RGBA - GL_RGBA
5838 \note Some OpenGL implementations do not support the GL_ALPHA format.
5841 void QQuickItemLayer::setFormat(QQuickShaderEffectSource::Format f)
5848 m_effectSource->setFormat(m_format);
5850 emit formatChanged(m_format);
5855 \qmlproperty enumeration QtQuick2::Item::layer.sourceRect
5857 This property defines which rectangular area of the \l sourceItem to
5858 render into the texture. The source rectangle can be larger than
5859 \l sourceItem itself. If the rectangle is null, which is the default,
5860 the whole \l sourceItem is rendered to texture.
5863 void QQuickItemLayer::setSourceRect(const QRectF &sourceRect)
5865 if (sourceRect == m_sourceRect)
5867 m_sourceRect = sourceRect;
5870 m_effectSource->setSourceRect(m_sourceRect);
5872 emit sourceRectChanged(sourceRect);
5878 \qmlproperty bool QtQuick2::Item::layer.smooth
5880 Holds whether the layer is smoothly transformed.
5883 void QQuickItemLayer::setSmooth(bool s)
5890 m_effectSource->setSmooth(m_smooth);
5892 emit smoothChanged(s);
5898 \qmlproperty size QtQuick2::Item::layer.textureSize
5900 This property holds the requested pixel size of the layers texture. If it is empty,
5901 which is the default, the size of the item is used.
5903 \note Some platforms have a limit on how small framebuffer objects can be,
5904 which means the actual texture size might be larger than the requested
5908 void QQuickItemLayer::setSize(const QSize &size)
5915 m_effectSource->setTextureSize(size);
5917 emit sizeChanged(size);
5923 \qmlproperty enumeration QtQuick2::Item::layer.wrapMode
5925 This property defines the OpenGL wrap modes associated with the texture.
5926 Modifying this property makes most sense when the \a layer.effect is
5930 \li ShaderEffectSource.ClampToEdge - GL_CLAMP_TO_EDGE both horizontally and vertically
5931 \li ShaderEffectSource.RepeatHorizontally - GL_REPEAT horizontally, GL_CLAMP_TO_EDGE vertically
5932 \li ShaderEffectSource.RepeatVertically - GL_CLAMP_TO_EDGE horizontally, GL_REPEAT vertically
5933 \li ShaderEffectSource.Repeat - GL_REPEAT both horizontally and vertically
5936 \note Some OpenGL ES 2 implementations do not support the GL_REPEAT
5937 wrap mode with non-power-of-two textures.
5940 void QQuickItemLayer::setWrapMode(QQuickShaderEffectSource::WrapMode mode)
5942 if (mode == m_wrapMode)
5947 m_effectSource->setWrapMode(m_wrapMode);
5949 emit wrapModeChanged(mode);
5953 \qmlproperty string QtQuick2::Item::layer.samplerName
5955 Holds the name of the effect's source texture property.
5957 samplerName needs to match the name of the effect's source texture property
5958 so that the Item can pass the layer's offscreen surface to the effect correctly.
5960 \sa effect, ShaderEffect
5963 void QQuickItemLayer::setName(const QByteArray &name) {
5967 m_effect->setProperty(m_name, QVariant());
5968 m_effect->setProperty(name, qVariantFromValue<QObject *>(m_effectSource));
5971 emit nameChanged(name);
5974 void QQuickItemLayer::itemOpacityChanged(QQuickItem *item)
5980 void QQuickItemLayer::itemGeometryChanged(QQuickItem *, const QRectF &, const QRectF &)
5985 void QQuickItemLayer::itemParentChanged(QQuickItem *item, QQuickItem *parent)
5988 Q_ASSERT(item == m_item);
5989 Q_ASSERT(parent != m_effectSource);
5990 Q_ASSERT(parent == 0 || parent != m_effect);
5992 m_effectSource->setParentItem(parent);
5994 m_effectSource->stackAfter(m_item);
5997 m_effect->setParentItem(parent);
5999 m_effect->stackAfter(m_effectSource);
6003 void QQuickItemLayer::itemSiblingOrderChanged(QQuickItem *)
6005 m_effectSource->stackAfter(m_item);
6007 m_effect->stackAfter(m_effectSource);
6010 void QQuickItemLayer::itemVisibilityChanged(QQuickItem *)
6012 QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
6014 l->setVisible(m_item->isVisible());
6017 void QQuickItemLayer::updateZ()
6019 if (!m_componentComplete || !m_enabled)
6021 QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
6023 l->setZ(m_item->z());
6026 void QQuickItemLayer::updateOpacity()
6028 QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
6030 l->setOpacity(m_item->opacity());
6033 void QQuickItemLayer::updateGeometry()
6035 QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
6037 QRectF bounds = m_item->clipRect();
6038 l->setWidth(bounds.width());
6039 l->setHeight(bounds.height());
6040 l->setX(bounds.x() + m_item->x());
6041 l->setY(bounds.y() + m_item->y());
6044 void QQuickItemLayer::updateMatrix()
6046 // Called directly from transformChanged(), so needs some extra
6048 if (!m_componentComplete || !m_enabled)
6050 QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
6052 QQuickItemPrivate *ld = QQuickItemPrivate::get(l);
6053 l->setScale(m_item->scale());
6054 l->setRotation(m_item->rotation());
6055 ld->transforms = QQuickItemPrivate::get(m_item)->transforms;
6056 if (ld->origin() != QQuickItemPrivate::get(m_item)->origin())
6057 ld->extra.value().origin = QQuickItemPrivate::get(m_item)->origin();
6058 ld->dirty(QQuickItemPrivate::Transform);
6061 QQuickItemPrivate::ExtraData::ExtraData()
6062 : z(0), scale(1), rotation(0), opacity(1),
6063 contents(0), screenAttached(0), layoutDirectionAttached(0),
6064 keyHandler(0), layer(0), effectRefCount(0), hideRefCount(0),
6065 opacityNode(0), clipNode(0), rootNode(0), beforePaintNode(0),
6066 acceptedMouseButtons(0), origin(QQuickItem::Center)
6072 #include <moc_qquickitem.cpp>