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 QQuickKeysAttachedPrivate::isConnected(const char *signalName)
912 return isSignalConnected(signalIndex(signalName));
916 \qmlclass Keys QQuickKeysAttached
917 \inqmlmodule QtQuick 2
918 \ingroup qml-basic-interaction-elements
919 \brief The Keys attached property provides key handling to Items.
921 All visual primitives support key handling via the Keys
922 attached property. Keys can be handled via the onPressed
923 and onReleased signal properties.
925 The signal properties have a \l KeyEvent parameter, named
926 \e event which contains details of the event. If a key is
927 handled \e event.accepted should be set to true to prevent the
928 event from propagating up the item hierarchy.
930 \section1 Example Usage
932 The following example shows how the general onPressed handler can
933 be used to test for a certain key; in this case, the left cursor
936 \snippet doc/src/snippets/qml/keys/keys-pressed.qml key item
938 Some keys may alternatively be handled via specific signal properties,
939 for example \e onSelectPressed. These handlers automatically set
940 \e event.accepted to true.
942 \snippet doc/src/snippets/qml/keys/keys-handler.qml key item
944 See \l{Qt::Key}{Qt.Key} for the list of keyboard codes.
946 \section1 Key Handling Priorities
948 The Keys attached property can be configured to handle key events
949 before or after the item it is attached to. This makes it possible
950 to intercept events in order to override an item's default behavior,
951 or act as a fallback for keys not handled by the item.
953 If \l priority is Keys.BeforeItem (default) the order of key event processing is:
956 \li Items specified in \c forwardTo
957 \li specific key handlers, e.g. onReturnPressed
958 \li onKeyPress, onKeyRelease handlers
959 \li Item specific key handling, e.g. TextInput key handling
963 If priority is Keys.AfterItem the order of key event processing is:
966 \li Item specific key handling, e.g. TextInput key handling
967 \li Items specified in \c forwardTo
968 \li specific key handlers, e.g. onReturnPressed
969 \li onKeyPress, onKeyRelease handlers
973 If the event is accepted during any of the above steps, key
976 \sa KeyEvent, {KeyNavigation}{KeyNavigation attached property}
980 \qmlproperty bool QtQuick2::Keys::enabled
982 This flags enables key handling if true (default); otherwise
983 no key handlers will be called.
987 \qmlproperty enumeration QtQuick2::Keys::priority
989 This property determines whether the keys are processed before
990 or after the attached item's own key handling.
993 \li Keys.BeforeItem (default) - process the key events before normal
994 item key processing. If the event is accepted it will not
995 be passed on to the item.
996 \li Keys.AfterItem - process the key events after normal item key
997 handling. If the item accepts the key event it will not be
998 handled by the Keys attached property handler.
1003 \qmlproperty list<Object> QtQuick2::Keys::forwardTo
1005 This property provides a way to forward key presses, key releases, and keyboard input
1006 coming from input methods to other items. This can be useful when you want
1007 one item to handle some keys (e.g. the up and down arrow keys), and another item to
1008 handle other keys (e.g. the left and right arrow keys). Once an item that has been
1009 forwarded keys accepts the event it is no longer forwarded to items later in the
1012 This example forwards key events to two lists:
1023 Keys.forwardTo: [list1, list2]
1030 \qmlsignal QtQuick2::Keys::onPressed(KeyEvent event)
1032 This handler is called when a key has been pressed. The \a event
1033 parameter provides information about the event.
1037 \qmlsignal QtQuick2::Keys::onReleased(KeyEvent event)
1039 This handler is called when a key has been released. The \a event
1040 parameter provides information about the event.
1044 \qmlsignal QtQuick2::Keys::onDigit0Pressed(KeyEvent event)
1046 This handler is called when the digit '0' has been pressed. The \a event
1047 parameter provides information about the event.
1051 \qmlsignal QtQuick2::Keys::onDigit1Pressed(KeyEvent event)
1053 This handler is called when the digit '1' has been pressed. The \a event
1054 parameter provides information about the event.
1058 \qmlsignal QtQuick2::Keys::onDigit2Pressed(KeyEvent event)
1060 This handler is called when the digit '2' has been pressed. The \a event
1061 parameter provides information about the event.
1065 \qmlsignal QtQuick2::Keys::onDigit3Pressed(KeyEvent event)
1067 This handler is called when the digit '3' has been pressed. The \a event
1068 parameter provides information about the event.
1072 \qmlsignal QtQuick2::Keys::onDigit4Pressed(KeyEvent event)
1074 This handler is called when the digit '4' has been pressed. The \a event
1075 parameter provides information about the event.
1079 \qmlsignal QtQuick2::Keys::onDigit5Pressed(KeyEvent event)
1081 This handler is called when the digit '5' has been pressed. The \a event
1082 parameter provides information about the event.
1086 \qmlsignal QtQuick2::Keys::onDigit6Pressed(KeyEvent event)
1088 This handler is called when the digit '6' has been pressed. The \a event
1089 parameter provides information about the event.
1093 \qmlsignal QtQuick2::Keys::onDigit7Pressed(KeyEvent event)
1095 This handler is called when the digit '7' has been pressed. The \a event
1096 parameter provides information about the event.
1100 \qmlsignal QtQuick2::Keys::onDigit8Pressed(KeyEvent event)
1102 This handler is called when the digit '8' has been pressed. The \a event
1103 parameter provides information about the event.
1107 \qmlsignal QtQuick2::Keys::onDigit9Pressed(KeyEvent event)
1109 This handler is called when the digit '9' has been pressed. The \a event
1110 parameter provides information about the event.
1114 \qmlsignal QtQuick2::Keys::onLeftPressed(KeyEvent event)
1116 This handler is called when the Left arrow has been pressed. The \a event
1117 parameter provides information about the event.
1121 \qmlsignal QtQuick2::Keys::onRightPressed(KeyEvent event)
1123 This handler is called when the Right arrow has been pressed. The \a event
1124 parameter provides information about the event.
1128 \qmlsignal QtQuick2::Keys::onUpPressed(KeyEvent event)
1130 This handler is called when the Up arrow has been pressed. The \a event
1131 parameter provides information about the event.
1135 \qmlsignal QtQuick2::Keys::onDownPressed(KeyEvent event)
1137 This handler is called when the Down arrow has been pressed. The \a event
1138 parameter provides information about the event.
1142 \qmlsignal QtQuick2::Keys::onTabPressed(KeyEvent event)
1144 This handler is called when the Tab key has been pressed. The \a event
1145 parameter provides information about the event.
1149 \qmlsignal QtQuick2::Keys::onBacktabPressed(KeyEvent event)
1151 This handler is called when the Shift+Tab key combination (Backtab) has
1152 been pressed. The \a event parameter provides information about the event.
1156 \qmlsignal QtQuick2::Keys::onAsteriskPressed(KeyEvent event)
1158 This handler is called when the Asterisk '*' has been pressed. The \a event
1159 parameter provides information about the event.
1163 \qmlsignal QtQuick2::Keys::onEscapePressed(KeyEvent event)
1165 This handler is called when the Escape key has been pressed. The \a event
1166 parameter provides information about the event.
1170 \qmlsignal QtQuick2::Keys::onReturnPressed(KeyEvent event)
1172 This handler is called when the Return key has been pressed. The \a event
1173 parameter provides information about the event.
1177 \qmlsignal QtQuick2::Keys::onEnterPressed(KeyEvent event)
1179 This handler is called when the Enter key has been pressed. The \a event
1180 parameter provides information about the event.
1184 \qmlsignal QtQuick2::Keys::onDeletePressed(KeyEvent event)
1186 This handler is called when the Delete key has been pressed. The \a event
1187 parameter provides information about the event.
1191 \qmlsignal QtQuick2::Keys::onSpacePressed(KeyEvent event)
1193 This handler is called when the Space key has been pressed. The \a event
1194 parameter provides information about the event.
1198 \qmlsignal QtQuick2::Keys::onBackPressed(KeyEvent event)
1200 This handler is called when the Back key has been pressed. The \a event
1201 parameter provides information about the event.
1205 \qmlsignal QtQuick2::Keys::onCancelPressed(KeyEvent event)
1207 This handler is called when the Cancel key has been pressed. The \a event
1208 parameter provides information about the event.
1212 \qmlsignal QtQuick2::Keys::onSelectPressed(KeyEvent event)
1214 This handler is called when the Select key has been pressed. The \a event
1215 parameter provides information about the event.
1219 \qmlsignal QtQuick2::Keys::onYesPressed(KeyEvent event)
1221 This handler is called when the Yes key has been pressed. The \a event
1222 parameter provides information about the event.
1226 \qmlsignal QtQuick2::Keys::onNoPressed(KeyEvent event)
1228 This handler is called when the No key has been pressed. The \a event
1229 parameter provides information about the event.
1233 \qmlsignal QtQuick2::Keys::onContext1Pressed(KeyEvent event)
1235 This handler is called when the Context1 key has been pressed. The \a event
1236 parameter provides information about the event.
1240 \qmlsignal QtQuick2::Keys::onContext2Pressed(KeyEvent event)
1242 This handler is called when the Context2 key has been pressed. The \a event
1243 parameter provides information about the event.
1247 \qmlsignal QtQuick2::Keys::onContext3Pressed(KeyEvent event)
1249 This handler is called when the Context3 key has been pressed. The \a event
1250 parameter provides information about the event.
1254 \qmlsignal QtQuick2::Keys::onContext4Pressed(KeyEvent event)
1256 This handler is called when the Context4 key has been pressed. The \a event
1257 parameter provides information about the event.
1261 \qmlsignal QtQuick2::Keys::onCallPressed(KeyEvent event)
1263 This handler is called when the Call key has been pressed. The \a event
1264 parameter provides information about the event.
1268 \qmlsignal QtQuick2::Keys::onHangupPressed(KeyEvent event)
1270 This handler is called when the Hangup key has been pressed. The \a event
1271 parameter provides information about the event.
1275 \qmlsignal QtQuick2::Keys::onFlipPressed(KeyEvent event)
1277 This handler is called when the Flip key has been pressed. The \a event
1278 parameter provides information about the event.
1282 \qmlsignal QtQuick2::Keys::onMenuPressed(KeyEvent event)
1284 This handler is called when the Menu key has been pressed. The \a event
1285 parameter provides information about the event.
1289 \qmlsignal QtQuick2::Keys::onVolumeUpPressed(KeyEvent event)
1291 This handler is called when the VolumeUp key has been pressed. The \a event
1292 parameter provides information about the event.
1296 \qmlsignal QtQuick2::Keys::onVolumeDownPressed(KeyEvent event)
1298 This handler is called when the VolumeDown key has been pressed. The \a event
1299 parameter provides information about the event.
1302 QQuickKeysAttached::QQuickKeysAttached(QObject *parent)
1303 : QObject(*(new QQuickKeysAttachedPrivate), parent),
1304 QQuickItemKeyFilter(qobject_cast<QQuickItem*>(parent))
1306 Q_D(QQuickKeysAttached);
1307 m_processPost = false;
1308 d->item = qobject_cast<QQuickItem*>(parent);
1311 QQuickKeysAttached::~QQuickKeysAttached()
1315 QQuickKeysAttached::Priority QQuickKeysAttached::priority() const
1317 return m_processPost ? AfterItem : BeforeItem;
1320 void QQuickKeysAttached::setPriority(Priority order)
1322 bool processPost = order == AfterItem;
1323 if (processPost != m_processPost) {
1324 m_processPost = processPost;
1325 emit priorityChanged();
1329 void QQuickKeysAttached::componentComplete()
1331 Q_D(QQuickKeysAttached);
1333 for (int ii = 0; ii < d->targets.count(); ++ii) {
1334 QQuickItem *targetItem = d->targets.at(ii);
1335 if (targetItem && (targetItem->flags() & QQuickItem::ItemAcceptsInputMethod)) {
1336 d->item->setFlag(QQuickItem::ItemAcceptsInputMethod);
1343 void QQuickKeysAttached::keyPressed(QKeyEvent *event, bool post)
1345 Q_D(QQuickKeysAttached);
1346 if (post != m_processPost || !d->enabled || d->inPress) {
1348 QQuickItemKeyFilter::keyPressed(event, post);
1352 // first process forwards
1353 if (d->item && d->item->canvas()) {
1355 for (int ii = 0; ii < d->targets.count(); ++ii) {
1356 QQuickItem *i = d->targets.at(ii);
1357 if (i && i->isVisible()) {
1358 d->item->canvas()->sendEvent(i, event);
1359 if (event->isAccepted()) {
1368 QQuickKeyEvent ke(*event);
1369 QByteArray keySignal = keyToSignal(event->key());
1370 if (!keySignal.isEmpty()) {
1371 keySignal += "(QQuickKeyEvent*)";
1372 if (d->isConnected(keySignal)) {
1373 // If we specifically handle a key then default to accepted
1374 ke.setAccepted(true);
1375 int idx = QQuickKeysAttached::staticMetaObject.indexOfSignal(keySignal);
1376 metaObject()->method(idx).invoke(this, Qt::DirectConnection, Q_ARG(QQuickKeyEvent*, &ke));
1379 if (!ke.isAccepted())
1381 event->setAccepted(ke.isAccepted());
1383 if (!event->isAccepted()) QQuickItemKeyFilter::keyPressed(event, post);
1386 void QQuickKeysAttached::keyReleased(QKeyEvent *event, bool post)
1388 Q_D(QQuickKeysAttached);
1389 if (post != m_processPost || !d->enabled || d->inRelease) {
1391 QQuickItemKeyFilter::keyReleased(event, post);
1395 if (d->item && d->item->canvas()) {
1396 d->inRelease = true;
1397 for (int ii = 0; ii < d->targets.count(); ++ii) {
1398 QQuickItem *i = d->targets.at(ii);
1399 if (i && i->isVisible()) {
1400 d->item->canvas()->sendEvent(i, event);
1401 if (event->isAccepted()) {
1402 d->inRelease = false;
1407 d->inRelease = false;
1410 QQuickKeyEvent ke(*event);
1412 event->setAccepted(ke.isAccepted());
1414 if (!event->isAccepted()) QQuickItemKeyFilter::keyReleased(event, post);
1417 void QQuickKeysAttached::inputMethodEvent(QInputMethodEvent *event, bool post)
1419 Q_D(QQuickKeysAttached);
1420 if (post == m_processPost && d->item && !d->inIM && d->item->canvas()) {
1422 for (int ii = 0; ii < d->targets.count(); ++ii) {
1423 QQuickItem *i = d->targets.at(ii);
1424 if (i && i->isVisible() && (i->flags() & QQuickItem::ItemAcceptsInputMethod)) {
1425 d->item->canvas()->sendEvent(i, event);
1426 if (event->isAccepted()) {
1435 QQuickItemKeyFilter::inputMethodEvent(event, post);
1438 QVariant QQuickKeysAttached::inputMethodQuery(Qt::InputMethodQuery query) const
1440 Q_D(const QQuickKeysAttached);
1442 for (int ii = 0; ii < d->targets.count(); ++ii) {
1443 QQuickItem *i = d->targets.at(ii);
1444 if (i && i->isVisible() && (i->flags() & QQuickItem::ItemAcceptsInputMethod) && i == d->imeItem) {
1445 //### how robust is i == d->imeItem check?
1446 QVariant v = i->inputMethodQuery(query);
1447 if (v.userType() == QVariant::RectF)
1448 v = d->item->mapRectFromItem(i, v.toRectF()); //### cost?
1453 return QQuickItemKeyFilter::inputMethodQuery(query);
1456 QQuickKeysAttached *QQuickKeysAttached::qmlAttachedProperties(QObject *obj)
1458 return new QQuickKeysAttached(obj);
1462 \qmlclass LayoutMirroring QQuickLayoutMirroringAttached
1463 \inqmlmodule QtQuick 2
1464 \ingroup qml-utility-elements
1465 \brief The LayoutMirroring attached property is used to mirror layout behavior.
1467 The LayoutMirroring attached property is used to horizontally mirror \l {anchor-layout}{Item anchors},
1468 \l{Using QML Positioner and Repeater Items}{positioner} elements (such as \l Row and \l Grid)
1469 and views (such as \l GridView and horizontal \l ListView). Mirroring is a visual change: left
1470 anchors become right anchors, and positioner elements like \l Grid and \l Row reverse the
1471 horizontal layout of child items.
1473 Mirroring is enabled for an item by setting the \l enabled property to true. By default, this
1474 only affects the item itself; setting the \l childrenInherit property to true propagates the mirroring
1475 behavior to all child elements as well. If the \c LayoutMirroring attached property has not been defined
1476 for an item, mirroring is not enabled.
1478 The following example shows mirroring in action. The \l Row below is specified as being anchored
1479 to the left of its parent. However, since mirroring has been enabled, the anchor is horizontally
1480 reversed and it is now anchored to the right. Also, since items in a \l Row are positioned
1481 from left to right by default, they are now positioned from right to left instead, as demonstrated
1482 by the numbering and opacity of the items:
1484 \snippet doc/src/snippets/qml/layoutmirroring.qml 0
1486 \image layoutmirroring.png
1488 Layout mirroring is useful when it is necessary to support both left-to-right and right-to-left
1489 layout versions of an application to target different language areas. The \l childrenInherit
1490 property allows layout mirroring to be applied without manually setting layout configurations
1491 for every item in an application. Keep in mind, however, that mirroring does not affect any
1492 positioning that is defined by the \l Item \l {Item::}{x} coordinate value, so even with
1493 mirroring enabled, it will often be necessary to apply some layout fixes to support the
1494 desired layout direction. Also, it may be necessary to disable the mirroring of individual
1495 child items (by setting \l {enabled}{LayoutMirroring.enabled} to false for such items) if
1496 mirroring is not the desired behavior, or if the child item already implements mirroring in
1499 See \l {QML Right-to-left User Interfaces} for further details on using \c LayoutMirroring and
1500 other related features to implement right-to-left support for an application.
1504 \qmlproperty bool QtQuick2::LayoutMirroring::enabled
1506 This property holds whether the item's layout is mirrored horizontally. Setting this to true
1507 horizontally reverses \l {anchor-layout}{anchor} settings such that left anchors become right,
1508 and right anchors become left. For \l{Using QML Positioner and Repeater Items}{positioner} elements
1509 (such as \l Row and \l Grid) and view elements (such as \l {GridView}{GridView} and \l {ListView}{ListView})
1510 this also mirrors the horizontal layout direction of the item.
1512 The default value is false.
1516 \qmlproperty bool QtQuick2::LayoutMirroring::childrenInherit
1518 This property holds whether the \l {enabled}{LayoutMirroring.enabled} value for this item
1519 is inherited by its children.
1521 The default value is false.
1525 QQuickLayoutMirroringAttached::QQuickLayoutMirroringAttached(QObject *parent) : QObject(parent), itemPrivate(0)
1527 if (QQuickItem *item = qobject_cast<QQuickItem*>(parent)) {
1528 itemPrivate = QQuickItemPrivate::get(item);
1529 itemPrivate->extra.value().layoutDirectionAttached = this;
1531 qmlInfo(parent) << tr("LayoutDirection attached property only works with Items");
1534 QQuickLayoutMirroringAttached * QQuickLayoutMirroringAttached::qmlAttachedProperties(QObject *object)
1536 return new QQuickLayoutMirroringAttached(object);
1539 bool QQuickLayoutMirroringAttached::enabled() const
1541 return itemPrivate ? itemPrivate->effectiveLayoutMirror : false;
1544 void QQuickLayoutMirroringAttached::setEnabled(bool enabled)
1549 itemPrivate->isMirrorImplicit = false;
1550 if (enabled != itemPrivate->effectiveLayoutMirror) {
1551 itemPrivate->setLayoutMirror(enabled);
1552 if (itemPrivate->inheritMirrorFromItem)
1553 itemPrivate->resolveLayoutMirror();
1557 void QQuickLayoutMirroringAttached::resetEnabled()
1559 if (itemPrivate && !itemPrivate->isMirrorImplicit) {
1560 itemPrivate->isMirrorImplicit = true;
1561 itemPrivate->resolveLayoutMirror();
1565 bool QQuickLayoutMirroringAttached::childrenInherit() const
1567 return itemPrivate ? itemPrivate->inheritMirrorFromItem : false;
1570 void QQuickLayoutMirroringAttached::setChildrenInherit(bool childrenInherit) {
1571 if (itemPrivate && childrenInherit != itemPrivate->inheritMirrorFromItem) {
1572 itemPrivate->inheritMirrorFromItem = childrenInherit;
1573 itemPrivate->resolveLayoutMirror();
1574 childrenInheritChanged();
1578 void QQuickItemPrivate::resolveLayoutMirror()
1581 if (QQuickItem *parentItem = q->parentItem()) {
1582 QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(parentItem);
1583 setImplicitLayoutMirror(parentPrivate->inheritedLayoutMirror, parentPrivate->inheritMirrorFromParent);
1585 setImplicitLayoutMirror(isMirrorImplicit ? false : effectiveLayoutMirror, inheritMirrorFromItem);
1589 void QQuickItemPrivate::setImplicitLayoutMirror(bool mirror, bool inherit)
1591 inherit = inherit || inheritMirrorFromItem;
1592 if (!isMirrorImplicit && inheritMirrorFromItem)
1593 mirror = effectiveLayoutMirror;
1594 if (mirror == inheritedLayoutMirror && inherit == inheritMirrorFromParent)
1597 inheritMirrorFromParent = inherit;
1598 inheritedLayoutMirror = inheritMirrorFromParent ? mirror : false;
1600 if (isMirrorImplicit)
1601 setLayoutMirror(inherit ? inheritedLayoutMirror : false);
1602 for (int i = 0; i < childItems.count(); ++i) {
1603 if (QQuickItem *child = qobject_cast<QQuickItem *>(childItems.at(i))) {
1604 QQuickItemPrivate *childPrivate = QQuickItemPrivate::get(child);
1605 childPrivate->setImplicitLayoutMirror(inheritedLayoutMirror, inheritMirrorFromParent);
1610 void QQuickItemPrivate::setLayoutMirror(bool mirror)
1612 if (mirror != effectiveLayoutMirror) {
1613 effectiveLayoutMirror = mirror;
1615 QQuickAnchorsPrivate *anchor_d = QQuickAnchorsPrivate::get(_anchors);
1616 anchor_d->fillChanged();
1617 anchor_d->centerInChanged();
1618 anchor_d->updateHorizontalAnchors();
1619 emit _anchors->mirroredChanged();
1622 if (extra.isAllocated() && extra->layoutDirectionAttached) {
1623 emit extra->layoutDirectionAttached->enabledChanged();
1628 void QQuickItemPrivate::setAccessibleFlagAndListener()
1631 QQuickItem *item = q;
1633 if (item->d_func()->isAccessible)
1634 break; // already set - grandparents should have the flag set as well.
1636 if (item->canvas() && item->canvas()->rootItem() == item)
1637 break; // don't add a listener to the canvas root item
1639 item->d_func()->isAccessible = true;
1640 item = item->d_func()->parentItem;
1644 void QQuickItemPrivate::updateSubFocusItem(QQuickItem *scope, bool focus)
1649 QQuickItemPrivate *scopePrivate = QQuickItemPrivate::get(scope);
1651 QQuickItem *oldSubFocusItem = scopePrivate->subFocusItem;
1652 // Correct focus chain in scope
1653 if (oldSubFocusItem) {
1654 QQuickItem *sfi = scopePrivate->subFocusItem->parentItem();
1655 while (sfi && sfi != scope) {
1656 QQuickItemPrivate::get(sfi)->subFocusItem = 0;
1657 sfi = sfi->parentItem();
1662 scopePrivate->subFocusItem = q;
1663 QQuickItem *sfi = scopePrivate->subFocusItem->parentItem();
1664 while (sfi && sfi != scope) {
1665 QQuickItemPrivate::get(sfi)->subFocusItem = q;
1666 sfi = sfi->parentItem();
1669 scopePrivate->subFocusItem = 0;
1676 \brief The QQuickItem class provides the most basic of all visual items in QML.
1680 All visual items in Qt Quick inherit from QQuickItem. Although QQuickItem
1681 has no visual appearance, it defines all the properties that are
1682 common across visual items - such as the x and y position, the
1683 width and height, \l {anchor-layout}{anchoring} and key handling.
1685 You can subclass QQuickItem to provide your own custom visual item that inherits
1686 these features. Note that, because it does not draw anything, QQuickItem sets the
1687 QGraphicsItem::ItemHasNoContents flag. If you subclass QQuickItem to create a visual
1688 item, you will need to unset this flag.
1693 \qmlclass Item QQuickItem
1695 \inqmlmodule QtQuick 2
1696 \ingroup qml-basic-visual-elements
1697 \brief The Item is the most basic of all visual items in QML.
1699 All visual items in Qt Quick inherit from Item. Although Item
1700 has no visual appearance, it defines all the properties that are
1701 common across visual items - such as the x and y position, the
1702 width and height, \l {anchor-layout}{anchoring} and key handling.
1704 Item is also useful for grouping items together.
1721 fillMode: Image.Tile
1728 \section1 Key Handling
1730 Key handling is available to all Item-based visual elements via the \l {Keys}{Keys}
1731 attached property. The \e Keys attached property provides basic handlers such
1732 as \l {Keys::onPressed}{onPressed} and \l {Keys::onReleased}{onReleased},
1733 as well as handlers for specific keys, such as
1734 \l {Keys::onCancelPressed}{onCancelPressed}. The example below
1735 assigns \l {qmlfocus}{focus} to the item and handles
1736 the Left key via the general \e onPressed handler and the Select key via the
1737 onSelectPressed handler:
1743 if (event.key == Qt.Key_Left) {
1744 console.log("move left");
1745 event.accepted = true;
1748 Keys.onSelectPressed: console.log("Selected");
1752 See the \l {Keys}{Keys} attached property for detailed documentation.
1754 \section1 Layout Mirroring
1756 Item layouts can be mirrored using the \l {LayoutMirroring}{LayoutMirroring} attached property.
1761 \fn void QQuickItem::childrenRectChanged(const QRectF &)
1766 \fn void QQuickItem::baselineOffsetChanged(qreal)
1771 \fn void QQuickItem::stateChanged(const QString &state)
1776 \fn void QQuickItem::parentChanged(QQuickItem *)
1781 \fn void QQuickItem::smoothChanged(bool)
1786 \fn void QQuickItem::clipChanged(bool)
1790 /*! \fn void QQuickItem::transformOriginChanged(TransformOrigin)
1795 \fn void QQuickItem::focusChanged(bool)
1800 \fn void QQuickItem::activeFocusChanged(bool)
1804 \fn QQuickItem::QQuickItem(QQuickItem *parent)
1806 Constructs a QQuickItem with the given \a parent.
1808 QQuickItem::QQuickItem(QQuickItem* parent)
1809 : QObject(*(new QQuickItemPrivate), parent)
1817 QQuickItem::QQuickItem(QQuickItemPrivate &dd, QQuickItem *parent)
1818 : QObject(dd, parent)
1825 static int qt_item_count = 0;
1827 static void qt_print_item_count()
1829 qDebug("Number of leaked items: %i", qt_item_count);
1835 Destroys the QQuickItem.
1837 QQuickItem::~QQuickItem()
1841 if (qt_item_count < 0)
1842 qDebug("Item destroyed after qt_print_item_count() was called.");
1847 if (d->canvasRefCount > 1)
1848 d->canvasRefCount = 1; // Make sure canvas is set to null in next call to derefCanvas().
1854 // XXX todo - optimize
1855 while (!d->childItems.isEmpty())
1856 d->childItems.first()->setParentItem(0);
1858 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
1859 QQuickAnchorsPrivate *anchor = d->changeListeners.at(ii).listener->anchorPrivate();
1861 anchor->clearItem(this);
1865 update item anchors that depended on us unless they are our child (and will also be destroyed),
1866 or our sibling, and our parent is also being destroyed.
1868 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
1869 QQuickAnchorsPrivate *anchor = d->changeListeners.at(ii).listener->anchorPrivate();
1870 if (anchor && anchor->item && anchor->item->parentItem() && anchor->item->parentItem() != this)
1874 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
1875 const QQuickItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
1876 if (change.types & QQuickItemPrivate::Destroyed)
1877 change.listener->itemDestroyed(this);
1880 d->changeListeners.clear();
1882 if (d->extra.isAllocated()) {
1883 delete d->extra->contents; d->extra->contents = 0;
1884 delete d->extra->layer; d->extra->layer = 0;
1887 delete d->_anchors; d->_anchors = 0;
1888 delete d->_stateGroup; d->_stateGroup = 0;
1892 \qmlproperty enumeration QtQuick2::Item::transformOrigin
1893 This property holds the origin point around which scale and rotation transform.
1895 Nine transform origins are available, as shown in the image below.
1897 \image declarative-transformorigin.png
1899 This example rotates an image around its bottom-right corner.
1902 source: "myimage.png"
1903 transformOrigin: Item.BottomRight
1908 The default transform origin is \c Item.Center.
1910 To set an arbitrary transform origin point use the \l Scale or \l Rotation
1915 \qmlproperty Item QtQuick2::Item::parent
1916 This property holds the parent of the item.
1920 \property QQuickItem::parent
1921 This property holds the parent of the item.
1923 void QQuickItem::setParentItem(QQuickItem *parentItem)
1926 if (parentItem == d->parentItem)
1930 QQuickItem *itemAncestor = parentItem->parentItem();
1931 while (itemAncestor != 0) {
1932 if (itemAncestor == this) {
1933 qWarning("QQuickItem::setParentItem: Parent is already part of this items subtree.");
1936 itemAncestor = itemAncestor->parentItem();
1940 d->removeFromDirtyList();
1942 QQuickItem *oldParentItem = d->parentItem;
1943 QQuickItem *scopeFocusedItem = 0;
1945 if (oldParentItem) {
1946 QQuickItemPrivate *op = QQuickItemPrivate::get(oldParentItem);
1948 QQuickItem *scopeItem = 0;
1951 scopeFocusedItem = this;
1952 else if (!isFocusScope() && d->subFocusItem)
1953 scopeFocusedItem = d->subFocusItem;
1955 if (scopeFocusedItem) {
1956 scopeItem = oldParentItem;
1957 while (!scopeItem->isFocusScope() && scopeItem->parentItem())
1958 scopeItem = scopeItem->parentItem();
1960 QQuickCanvasPrivate::get(d->canvas)->clearFocusInScope(scopeItem, scopeFocusedItem,
1961 QQuickCanvasPrivate::DontChangeFocusProperty);
1962 if (scopeFocusedItem != this)
1963 QQuickItemPrivate::get(scopeFocusedItem)->updateSubFocusItem(this, true);
1965 QQuickItemPrivate::get(scopeFocusedItem)->updateSubFocusItem(scopeItem, false);
1969 const bool wasVisible = isVisible();
1970 op->removeChild(this);
1972 emit oldParentItem->visibleChildrenChanged();
1974 } else if (d->canvas) {
1975 QQuickCanvasPrivate::get(d->canvas)->parentlessItems.remove(this);
1978 QQuickCanvas *oldParentCanvas = oldParentItem ? QQuickItemPrivate::get(oldParentItem)->canvas : 0;
1979 QQuickCanvas *parentCanvas = parentItem ? QQuickItemPrivate::get(parentItem)->canvas : 0;
1980 if (oldParentCanvas == parentCanvas) {
1981 // Avoid freeing and reallocating resources if the canvas stays the same.
1982 d->parentItem = parentItem;
1984 if (oldParentCanvas)
1986 d->parentItem = parentItem;
1988 d->refCanvas(parentCanvas);
1991 d->dirty(QQuickItemPrivate::ParentChanged);
1994 QQuickItemPrivate::get(d->parentItem)->addChild(this);
1996 QQuickCanvasPrivate::get(d->canvas)->parentlessItems.insert(this);
1998 d->setEffectiveVisibleRecur(d->calcEffectiveVisible());
1999 d->setEffectiveEnableRecur(0, d->calcEffectiveEnable());
2001 if (d->parentItem) {
2002 if (!scopeFocusedItem) {
2004 scopeFocusedItem = this;
2005 else if (!isFocusScope() && d->subFocusItem)
2006 scopeFocusedItem = d->subFocusItem;
2009 if (scopeFocusedItem) {
2010 // We need to test whether this item becomes scope focused
2011 QQuickItem *scopeItem = d->parentItem;
2012 while (!scopeItem->isFocusScope() && scopeItem->parentItem())
2013 scopeItem = scopeItem->parentItem();
2015 if (QQuickItemPrivate::get(scopeItem)->subFocusItem
2016 || (!scopeItem->isFocusScope() && scopeItem->hasFocus())) {
2017 if (scopeFocusedItem != this)
2018 QQuickItemPrivate::get(scopeFocusedItem)->updateSubFocusItem(this, false);
2019 QQuickItemPrivate::get(scopeFocusedItem)->focus = false;
2020 emit scopeFocusedItem->focusChanged(false);
2023 QQuickCanvasPrivate::get(d->canvas)->setFocusInScope(scopeItem, scopeFocusedItem,
2024 QQuickCanvasPrivate::DontChangeFocusProperty);
2026 QQuickItemPrivate::get(scopeFocusedItem)->updateSubFocusItem(scopeItem, true);
2032 d->resolveLayoutMirror();
2034 d->itemChange(ItemParentHasChanged, d->parentItem);
2036 d->parentNotifier.notify();
2037 if (d->isAccessible && d->parentItem) {
2038 d->parentItem->d_func()->setAccessibleFlagAndListener();
2041 emit parentChanged(d->parentItem);
2042 if (isVisible() && d->parentItem)
2043 emit d->parentItem->visibleChildrenChanged();
2046 void QQuickItem::stackBefore(const QQuickItem *sibling)
2049 if (!sibling || sibling == this || !d->parentItem || d->parentItem != QQuickItemPrivate::get(sibling)->parentItem) {
2050 qWarning("QQuickItem::stackBefore: Cannot stack before %p, which must be a sibling", sibling);
2054 QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(d->parentItem);
2056 int myIndex = parentPrivate->childItems.indexOf(this);
2057 int siblingIndex = parentPrivate->childItems.indexOf(const_cast<QQuickItem *>(sibling));
2059 Q_ASSERT(myIndex != -1 && siblingIndex != -1);
2061 if (myIndex == siblingIndex - 1)
2064 parentPrivate->childItems.removeAt(myIndex);
2066 if (myIndex < siblingIndex) --siblingIndex;
2068 parentPrivate->childItems.insert(siblingIndex, this);
2070 parentPrivate->dirty(QQuickItemPrivate::ChildrenStackingChanged);
2071 parentPrivate->markSortedChildrenDirty(this);
2073 for (int ii = qMin(siblingIndex, myIndex); ii < parentPrivate->childItems.count(); ++ii)
2074 QQuickItemPrivate::get(parentPrivate->childItems.at(ii))->siblingOrderChanged();
2077 void QQuickItem::stackAfter(const QQuickItem *sibling)
2080 if (!sibling || sibling == this || !d->parentItem || d->parentItem != QQuickItemPrivate::get(sibling)->parentItem) {
2081 qWarning("QQuickItem::stackAfter: Cannot stack after %p, which must be a sibling", sibling);
2085 QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(d->parentItem);
2087 int myIndex = parentPrivate->childItems.indexOf(this);
2088 int siblingIndex = parentPrivate->childItems.indexOf(const_cast<QQuickItem *>(sibling));
2090 Q_ASSERT(myIndex != -1 && siblingIndex != -1);
2092 if (myIndex == siblingIndex + 1)
2095 parentPrivate->childItems.removeAt(myIndex);
2097 if (myIndex < siblingIndex) --siblingIndex;
2099 parentPrivate->childItems.insert(siblingIndex + 1, this);
2101 parentPrivate->dirty(QQuickItemPrivate::ChildrenStackingChanged);
2102 parentPrivate->markSortedChildrenDirty(this);
2104 for (int ii = qMin(myIndex, siblingIndex + 1); ii < parentPrivate->childItems.count(); ++ii)
2105 QQuickItemPrivate::get(parentPrivate->childItems.at(ii))->siblingOrderChanged();
2109 Returns the QQuickItem parent of this item.
2111 QQuickItem *QQuickItem::parentItem() const
2113 Q_D(const QQuickItem);
2114 return d->parentItem;
2117 QSGEngine *QQuickItem::sceneGraphEngine() const
2119 return canvas()->sceneGraphEngine();
2122 QQuickCanvas *QQuickItem::canvas() const
2124 Q_D(const QQuickItem);
2128 static bool itemZOrder_sort(QQuickItem *lhs, QQuickItem *rhs)
2130 return lhs->z() < rhs->z();
2133 QList<QQuickItem *> QQuickItemPrivate::paintOrderChildItems() const
2135 if (sortedChildItems)
2136 return *sortedChildItems;
2138 // If none of the items have set Z then the paint order list is the same as
2139 // the childItems list. This is by far the most common case.
2141 for (int i = 0; i < childItems.count(); ++i) {
2142 if (QQuickItemPrivate::get(childItems.at(i))->z() != 0.) {
2148 sortedChildItems = new QList<QQuickItem*>(childItems);
2149 qStableSort(sortedChildItems->begin(), sortedChildItems->end(), itemZOrder_sort);
2150 return *sortedChildItems;
2153 sortedChildItems = const_cast<QList<QQuickItem*>*>(&childItems);
2158 void QQuickItemPrivate::addChild(QQuickItem *child)
2162 Q_ASSERT(!childItems.contains(child));
2164 childItems.append(child);
2166 markSortedChildrenDirty(child);
2167 dirty(QQuickItemPrivate::ChildrenChanged);
2169 itemChange(QQuickItem::ItemChildAddedChange, child);
2171 emit q->childrenChanged();
2174 void QQuickItemPrivate::removeChild(QQuickItem *child)
2179 Q_ASSERT(childItems.contains(child));
2180 childItems.removeOne(child);
2181 Q_ASSERT(!childItems.contains(child));
2183 markSortedChildrenDirty(child);
2184 dirty(QQuickItemPrivate::ChildrenChanged);
2186 itemChange(QQuickItem::ItemChildRemovedChange, child);
2188 emit q->childrenChanged();
2191 void QQuickItemPrivate::InitializationState::clear()
2196 void QQuickItemPrivate::InitializationState::clear(QQuickItem *fs)
2201 QQuickItem *QQuickItemPrivate::InitializationState::getFocusScope(QQuickItem *item)
2204 QQuickItem *fs = item->parentItem();
2205 while (fs->parentItem() && !fs->isFocusScope())
2206 fs = fs->parentItem();
2212 void QQuickItemPrivate::refCanvas(InitializationState *state, QQuickCanvas *c)
2214 // An item needs a canvas if it is referenced by another item which has a canvas.
2215 // Typically the item is referenced by a parent, but can also be referenced by a
2216 // ShaderEffect or ShaderEffectSource. 'canvasRefCount' counts how many items with
2217 // a canvas is referencing this item. When the reference count goes from zero to one,
2218 // or one to zero, the canvas of this item is updated and propagated to the children.
2219 // As long as the reference count stays above zero, the canvas is unchanged.
2220 // refCanvas() increments the reference count.
2221 // derefCanvas() decrements the reference count.
2224 Q_ASSERT((canvas != 0) == (canvasRefCount > 0));
2226 if (++canvasRefCount > 1) {
2228 qWarning("QQuickItem: Cannot use same item on different canvases at the same time.");
2229 return; // Canvas already set.
2232 Q_ASSERT(canvas == 0);
2235 if (polishScheduled)
2236 QQuickCanvasPrivate::get(canvas)->itemsToPolish.insert(q);
2238 InitializationState _dummy;
2239 InitializationState *childState = state;
2241 if (q->isFocusScope()) {
2243 childState = &_dummy;
2247 QQuickCanvasPrivate::get(canvas)->parentlessItems.insert(q);
2249 for (int ii = 0; ii < childItems.count(); ++ii) {
2250 QQuickItem *child = childItems.at(ii);
2251 QQuickItemPrivate::get(child)->refCanvas(childState, c);
2256 if (extra.isAllocated() && extra->screenAttached)
2257 extra->screenAttached->canvasChanged(c);
2258 itemChange(QQuickItem::ItemSceneChange, c);
2261 void QQuickItemPrivate::derefCanvas()
2264 Q_ASSERT((canvas != 0) == (canvasRefCount > 0));
2267 return; // This can happen when destroying recursive shader effect sources.
2269 if (--canvasRefCount > 0)
2270 return; // There are still other references, so don't set canvas to null yet.
2272 q->releaseResources();
2273 removeFromDirtyList();
2274 QQuickCanvasPrivate *c = QQuickCanvasPrivate::get(canvas);
2275 if (polishScheduled)
2276 c->itemsToPolish.remove(q);
2277 if (c->mouseGrabberItem == q)
2278 c->mouseGrabberItem = 0;
2280 c->hoverItems.removeAll(q);
2281 if (itemNodeInstance)
2282 c->cleanup(itemNodeInstance);
2284 c->parentlessItems.remove(q);
2288 itemNodeInstance = 0;
2290 if (extra.isAllocated()) {
2291 extra->opacityNode = 0;
2292 extra->clipNode = 0;
2293 extra->rootNode = 0;
2294 extra->beforePaintNode = 0;
2300 for (int ii = 0; ii < childItems.count(); ++ii) {
2301 QQuickItem *child = childItems.at(ii);
2302 QQuickItemPrivate::get(child)->derefCanvas();
2307 if (extra.isAllocated() && extra->screenAttached)
2308 extra->screenAttached->canvasChanged(0);
2309 itemChange(QQuickItem::ItemSceneChange, (QQuickCanvas *)0);
2314 Returns a transform that maps points from canvas space into item space.
2316 QTransform QQuickItemPrivate::canvasToItemTransform() const
2318 // XXX todo - optimize
2319 return itemToCanvasTransform().inverted();
2323 Returns a transform that maps points from item space into canvas space.
2325 QTransform QQuickItemPrivate::itemToCanvasTransform() const
2328 QTransform rv = parentItem?QQuickItemPrivate::get(parentItem)->itemToCanvasTransform():QTransform();
2329 itemToParentTransform(rv);
2334 Motifies \a t with this items local transform relative to its parent.
2336 void QQuickItemPrivate::itemToParentTransform(QTransform &t) const
2341 if (!transforms.isEmpty()) {
2343 for (int ii = transforms.count() - 1; ii >= 0; --ii)
2344 transforms.at(ii)->applyTo(&m);
2345 t = m.toTransform();
2348 if (scale() != 1. || rotation() != 0.) {
2349 QPointF tp = computeTransformOrigin();
2350 t.translate(tp.x(), tp.y());
2351 t.scale(scale(), scale());
2352 t.rotate(rotation());
2353 t.translate(-tp.x(), -tp.y());
2359 \qmlproperty real QtQuick2::Item::childrenRect.x
2360 \qmlproperty real QtQuick2::Item::childrenRect.y
2361 \qmlproperty real QtQuick2::Item::childrenRect.width
2362 \qmlproperty real QtQuick2::Item::childrenRect.height
2364 The childrenRect properties allow an item access to the geometry of its
2365 children. This property is useful if you have an item that needs to be
2366 sized to fit its children.
2371 \qmlproperty list<Item> QtQuick2::Item::children
2372 \qmlproperty list<Object> QtQuick2::Item::resources
2374 The children property contains the list of visual children of this item.
2375 The resources property contains non-visual resources that you want to
2378 Generally you can rely on Item's default property to handle all this for
2379 you, but it can come in handy in some cases.
2398 Returns true if construction of the QML component is complete; otherwise
2401 It is often desirable to delay some processing until the component is
2404 \sa componentComplete()
2406 bool QQuickItem::isComponentComplete() const
2408 Q_D(const QQuickItem);
2409 return d->componentComplete;
2412 QQuickItemPrivate::QQuickItemPrivate()
2413 : _anchors(0), _stateGroup(0),
2414 flags(0), widthValid(false), heightValid(false), baselineOffsetValid(false), componentComplete(true),
2415 keepMouse(false), keepTouch(false), hoverEnabled(false), smooth(true), focus(false), activeFocus(false), notifiedFocus(false),
2416 notifiedActiveFocus(false), filtersChildMouseEvents(false), explicitVisible(true),
2417 effectiveVisible(true), explicitEnable(true), effectiveEnable(true), polishScheduled(false),
2418 inheritedLayoutMirror(false), effectiveLayoutMirror(false), isMirrorImplicit(true),
2419 inheritMirrorFromParent(false), inheritMirrorFromItem(false), childrenDoNotOverlap(false),
2420 staticSubtreeGeometry(false),
2421 isAccessible(false),
2423 dirtyAttributes(0), nextDirtyItem(0), prevDirtyItem(0),
2425 canvas(0), canvasRefCount(0), parentItem(0), sortedChildItems(&childItems),
2429 x(0), y(0), width(0), height(0), implicitWidth(0), implicitHeight(0),
2433 itemNodeInstance(0), groupNode(0), paintNode(0)
2437 QQuickItemPrivate::~QQuickItemPrivate()
2439 if (sortedChildItems != &childItems)
2440 delete sortedChildItems;
2443 void QQuickItemPrivate::init(QQuickItem *parent)
2447 static bool atexit_registered = false;
2448 if (!atexit_registered) {
2449 atexit(qt_print_item_count);
2450 atexit_registered = true;
2456 registerAccessorProperties();
2458 baselineOffsetValid = false;
2461 q->setParentItem(parent);
2462 QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(parent);
2463 setImplicitLayoutMirror(parentPrivate->inheritedLayoutMirror, parentPrivate->inheritMirrorFromParent);
2467 void QQuickItemPrivate::data_append(QQmlListProperty<QObject> *prop, QObject *o)
2472 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2474 // This test is measurably (albeit only slightly) faster than qobject_cast<>()
2475 const QMetaObject *mo = o->metaObject();
2476 while (mo && mo != &QQuickItem::staticMetaObject) {
2477 mo = mo->d.superdata;
2481 QQuickItem *item = static_cast<QQuickItem *>(o);
2482 item->setParentItem(that);
2484 if (o->inherits("QGraphicsItem"))
2485 qWarning("Cannot add a QtQuick 1.0 item (%s) into a QtQuick 2.0 scene!", o->metaObject()->className());
2487 // XXX todo - do we really want this behavior?
2493 \qmlproperty list<Object> QtQuick2::Item::data
2496 The data property allows you to freely mix visual children and resources
2497 in an item. If you assign a visual item to the data list it becomes
2498 a child and if you assign any other object type, it is added as a resource.
2522 data is a behind-the-scenes property: you should never need to explicitly
2526 int QQuickItemPrivate::data_count(QQmlListProperty<QObject> *prop)
2533 QObject *QQuickItemPrivate::data_at(QQmlListProperty<QObject> *prop, int i)
2541 void QQuickItemPrivate::data_clear(QQmlListProperty<QObject> *prop)
2547 QObject *QQuickItemPrivate::resources_at(QQmlListProperty<QObject> *prop, int index)
2549 const QObjectList children = prop->object->children();
2550 if (index < children.count())
2551 return children.at(index);
2556 void QQuickItemPrivate::resources_append(QQmlListProperty<QObject> *prop, QObject *o)
2558 // XXX todo - do we really want this behavior?
2559 o->setParent(prop->object);
2562 int QQuickItemPrivate::resources_count(QQmlListProperty<QObject> *prop)
2564 return prop->object->children().count();
2567 void QQuickItemPrivate::resources_clear(QQmlListProperty<QObject> *prop)
2569 // XXX todo - do we really want this behavior?
2570 const QObjectList children = prop->object->children();
2571 for (int index = 0; index < children.count(); index++)
2572 children.at(index)->setParent(0);
2575 QQuickItem *QQuickItemPrivate::children_at(QQmlListProperty<QQuickItem> *prop, int index)
2577 QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2578 if (index >= p->childItems.count() || index < 0)
2581 return p->childItems.at(index);
2584 void QQuickItemPrivate::children_append(QQmlListProperty<QQuickItem> *prop, QQuickItem *o)
2589 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2590 if (o->parentItem() == that)
2591 o->setParentItem(0);
2593 o->setParentItem(that);
2596 int QQuickItemPrivate::children_count(QQmlListProperty<QQuickItem> *prop)
2598 QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2599 return p->childItems.count();
2602 void QQuickItemPrivate::children_clear(QQmlListProperty<QQuickItem> *prop)
2604 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2605 QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2606 while (!p->childItems.isEmpty())
2607 p->childItems.at(0)->setParentItem(0);
2610 void QQuickItemPrivate::visibleChildren_append(QQmlListProperty<QQuickItem>*, QQuickItem *self)
2613 qmlInfo(self) << "QQuickItem: visibleChildren property is readonly and cannot be assigned to.";
2616 int QQuickItemPrivate::visibleChildren_count(QQmlListProperty<QQuickItem> *prop)
2618 QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2619 int visibleCount = 0;
2620 int c = p->childItems.count();
2622 if (p->childItems.at(c)->isVisible()) visibleCount++;
2625 return visibleCount;
2628 QQuickItem *QQuickItemPrivate::visibleChildren_at(QQmlListProperty<QQuickItem> *prop, int index)
2630 QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2631 const int childCount = p->childItems.count();
2632 if (index >= childCount || index < 0)
2635 int visibleCount = -1;
2636 for (int i = 0; i < childCount; i++) {
2637 if (p->childItems.at(i)->isVisible()) visibleCount++;
2638 if (visibleCount == index) return p->childItems.at(i);
2643 int QQuickItemPrivate::transform_count(QQmlListProperty<QQuickTransform> *prop)
2645 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2646 QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2648 return p->transforms.count();
2651 void QQuickTransform::appendToItem(QQuickItem *item)
2653 Q_D(QQuickTransform);
2657 QQuickItemPrivate *p = QQuickItemPrivate::get(item);
2659 if (!d->items.isEmpty() && !p->transforms.isEmpty() && p->transforms.contains(this)) {
2660 p->transforms.removeOne(this);
2661 p->transforms.append(this);
2663 p->transforms.append(this);
2664 d->items.append(item);
2667 p->dirty(QQuickItemPrivate::Transform);
2670 void QQuickTransform::prependToItem(QQuickItem *item)
2672 Q_D(QQuickTransform);
2676 QQuickItemPrivate *p = QQuickItemPrivate::get(item);
2678 if (!d->items.isEmpty() && !p->transforms.isEmpty() && p->transforms.contains(this)) {
2679 p->transforms.removeOne(this);
2680 p->transforms.prepend(this);
2682 p->transforms.prepend(this);
2683 d->items.append(item);
2686 p->dirty(QQuickItemPrivate::Transform);
2689 void QQuickItemPrivate::transform_append(QQmlListProperty<QQuickTransform> *prop, QQuickTransform *transform)
2694 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2695 transform->appendToItem(that);
2698 QQuickTransform *QQuickItemPrivate::transform_at(QQmlListProperty<QQuickTransform> *prop, int idx)
2700 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2701 QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2703 if (idx < 0 || idx >= p->transforms.count())
2706 return p->transforms.at(idx);
2709 void QQuickItemPrivate::transform_clear(QQmlListProperty<QQuickTransform> *prop)
2711 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2712 QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2714 for (int ii = 0; ii < p->transforms.count(); ++ii) {
2715 QQuickTransform *t = p->transforms.at(ii);
2716 QQuickTransformPrivate *tp = QQuickTransformPrivate::get(t);
2717 tp->items.removeOne(that);
2720 p->transforms.clear();
2722 p->dirty(QQuickItemPrivate::Transform);
2726 \property QQuickItem::childrenRect
2727 \brief The geometry of an item's children.
2729 This property holds the (collective) position and size of the item's children.
2733 \qmlproperty real QtQuick2::Item::x
2734 \qmlproperty real QtQuick2::Item::y
2735 \qmlproperty real QtQuick2::Item::width
2736 \qmlproperty real QtQuick2::Item::height
2738 Defines the item's position and size relative to its parent.
2741 Item { x: 100; y: 100; width: 100; height: 100 }
2746 \qmlproperty real QtQuick2::Item::z
2748 Sets the stacking order of sibling items. By default the stacking order is 0.
2750 Items with a higher stacking value are drawn on top of siblings with a
2751 lower stacking order. Items with the same stacking value are drawn
2752 bottom up in the order they appear. Items with a negative stacking
2753 value are drawn under their parent's content.
2755 The following example shows the various effects of stacking order.
2759 \li \image declarative-item_stacking1.png
2760 \li Same \c z - later children above earlier children:
2765 width: 100; height: 100
2769 x: 50; y: 50; width: 100; height: 100
2774 \li \image declarative-item_stacking2.png
2775 \li Higher \c z on top:
2781 width: 100; height: 100
2785 x: 50; y: 50; width: 100; height: 100
2790 \li \image declarative-item_stacking3.png
2791 \li Same \c z - children above parents:
2796 width: 100; height: 100
2799 x: 50; y: 50; width: 100; height: 100
2805 \li \image declarative-item_stacking4.png
2806 \li Lower \c z below:
2811 width: 100; height: 100
2815 x: 50; y: 50; width: 100; height: 100
2824 \qmlproperty bool QtQuick2::Item::visible
2826 This property holds whether the item is visible. By default this is true.
2828 Setting this property directly affects the \c visible value of child
2829 items. When set to \c false, the \c visible values of all child items also
2830 become \c false. When set to \c true, the \c visible values of child items
2831 are returned to \c true, unless they have explicitly been set to \c false.
2833 (Because of this flow-on behavior, using the \c visible property may not
2834 have the intended effect if a property binding should only respond to
2835 explicit property changes. In such cases it may be better to use the
2836 \l opacity property instead.)
2838 Setting this property to \c false automatically causes \l focus to be set
2839 to \c false, and this item will longer receive mouse and keyboard events.
2840 (In contrast, setting the \l opacity to 0 does not affect the \l focus
2841 property and the receiving of key events.)
2843 \note This property's value is only affected by changes to this property or
2844 the parent's \c visible property. It does not change, for example, if this
2845 item moves off-screen, or if the \l opacity changes to 0.
2850 \qmlproperty AnchorLine QtQuick2::Item::anchors.top
2851 \qmlproperty AnchorLine QtQuick2::Item::anchors.bottom
2852 \qmlproperty AnchorLine QtQuick2::Item::anchors.left
2853 \qmlproperty AnchorLine QtQuick2::Item::anchors.right
2854 \qmlproperty AnchorLine QtQuick2::Item::anchors.horizontalCenter
2855 \qmlproperty AnchorLine QtQuick2::Item::anchors.verticalCenter
2856 \qmlproperty AnchorLine QtQuick2::Item::anchors.baseline
2858 \qmlproperty Item QtQuick2::Item::anchors.fill
2859 \qmlproperty Item QtQuick2::Item::anchors.centerIn
2861 \qmlproperty real QtQuick2::Item::anchors.margins
2862 \qmlproperty real QtQuick2::Item::anchors.topMargin
2863 \qmlproperty real QtQuick2::Item::anchors.bottomMargin
2864 \qmlproperty real QtQuick2::Item::anchors.leftMargin
2865 \qmlproperty real QtQuick2::Item::anchors.rightMargin
2866 \qmlproperty real QtQuick2::Item::anchors.horizontalCenterOffset
2867 \qmlproperty real QtQuick2::Item::anchors.verticalCenterOffset
2868 \qmlproperty real QtQuick2::Item::anchors.baselineOffset
2870 \qmlproperty bool QtQuick2::Item::anchors.mirrored
2872 Anchors provide a way to position an item by specifying its
2873 relationship with other items.
2875 Margins apply to top, bottom, left, right, and fill anchors.
2876 The \c anchors.margins property can be used to set all of the various margins at once, to the same value.
2877 Note that margins are anchor-specific and are not applied if an item does not
2880 Offsets apply for horizontal center, vertical center, and baseline anchors.
2884 \li \image declarative-anchors_example.png
2885 \li Text anchored to Image, horizontally centered and vertically below, with a margin.
2894 anchors.horizontalCenter: pic.horizontalCenter
2895 anchors.top: pic.bottom
2896 anchors.topMargin: 5
2902 \li \image declarative-anchors_example2.png
2904 Left of Text anchored to right of Image, with a margin. The y
2905 property of both defaults to 0.
2915 anchors.left: pic.right
2916 anchors.leftMargin: 5
2923 \c anchors.fill provides a convenient way for one item to have the
2924 same geometry as another item, and is equivalent to connecting all
2925 four directional anchors.
2927 To clear an anchor value, set it to \c undefined.
2929 \c anchors.mirrored returns true it the layout has been \l {LayoutMirroring}{mirrored}.
2931 \note You can only anchor an item to siblings or a parent.
2933 For more information see \l {anchor-layout}{Anchor Layouts}.
2937 \property QQuickItem::baselineOffset
2938 \brief The position of the item's baseline in local coordinates.
2940 The baseline of a \l Text item is the imaginary line on which the text
2941 sits. Controls containing text usually set their baseline to the
2942 baseline of their text.
2944 For non-text items, a default baseline offset of 0 is used.
2946 QQuickAnchors *QQuickItemPrivate::anchors() const
2949 Q_Q(const QQuickItem);
2950 _anchors = new QQuickAnchors(const_cast<QQuickItem *>(q));
2951 if (!componentComplete)
2952 _anchors->classBegin();
2957 void QQuickItemPrivate::siblingOrderChanged()
2960 for (int ii = 0; ii < changeListeners.count(); ++ii) {
2961 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
2962 if (change.types & QQuickItemPrivate::SiblingOrder) {
2963 change.listener->itemSiblingOrderChanged(q);
2968 QQmlListProperty<QObject> QQuickItemPrivate::data()
2970 return QQmlListProperty<QObject>(q_func(), 0, QQuickItemPrivate::data_append,
2971 QQuickItemPrivate::data_count,
2972 QQuickItemPrivate::data_at,
2973 QQuickItemPrivate::data_clear);
2976 QRectF QQuickItem::childrenRect()
2979 if (!d->extra.isAllocated() || !d->extra->contents) {
2980 d->extra.value().contents = new QQuickContents(this);
2981 if (d->componentComplete)
2982 d->extra->contents->complete();
2984 return d->extra->contents->rectF();
2987 QList<QQuickItem *> QQuickItem::childItems() const
2989 Q_D(const QQuickItem);
2990 return d->childItems;
2993 bool QQuickItem::clip() const
2995 return flags() & ItemClipsChildrenToShape;
2998 void QQuickItem::setClip(bool c)
3003 setFlag(ItemClipsChildrenToShape, c);
3005 emit clipChanged(c);
3010 This function is called to handle this item's changes in
3011 geometry from \a oldGeometry to \a newGeometry. If the two
3012 geometries are the same, it doesn't do anything.
3014 void QQuickItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
3019 QQuickAnchorsPrivate::get(d->_anchors)->updateMe();
3021 bool xChange = (newGeometry.x() != oldGeometry.x());
3022 bool yChange = (newGeometry.y() != oldGeometry.y());
3023 bool widthChange = (newGeometry.width() != oldGeometry.width());
3024 bool heightChange = (newGeometry.height() != oldGeometry.height());
3026 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
3027 const QQuickItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
3028 if (change.types & QQuickItemPrivate::Geometry) {
3029 if (change.gTypes == QQuickItemPrivate::GeometryChange) {
3030 change.listener->itemGeometryChanged(this, newGeometry, oldGeometry);
3031 } else if ((xChange && (change.gTypes & QQuickItemPrivate::XChange)) ||
3032 (yChange && (change.gTypes & QQuickItemPrivate::YChange)) ||
3033 (widthChange && (change.gTypes & QQuickItemPrivate::WidthChange)) ||
3034 (heightChange && (change.gTypes & QQuickItemPrivate::HeightChange))) {
3035 change.listener->itemGeometryChanged(this, newGeometry, oldGeometry);
3045 emit widthChanged();
3047 emit heightChanged();
3051 Called by the rendering thread when it is time to sync the state of the QML objects with the
3052 scene graph objects. The function should return the root of the scene graph subtree for
3053 this item. \a oldNode is the node that was returned the last time the function was called.
3055 The main thread is blocked while this function is executed so it is safe to read
3056 values from the QQuickItem instance and other objects in the main thread.
3058 \warning This is the only function in which it is allowed to make use of scene graph
3059 objects from the main thread. Use of scene graph objects outside this function will
3060 result in race conditions and potential crashes.
3063 QSGNode *QQuickItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
3070 This function is called when the item's scene graph resources are no longer needed.
3071 It allows items to free its resources, for instance textures, that are not owned by scene graph
3072 nodes. Note that scene graph nodes are managed by QQuickCanvas and should not be deleted by
3073 this function. Scene graph resources are no longer needed when the parent is set to null and
3074 the item is not used by any \l ShaderEffect or \l ShaderEffectSource.
3076 This function is called from the main thread. Therefore, resources used by the scene graph
3077 should not be deleted directly, but by calling \l QObject::deleteLater().
3079 \note The item destructor still needs to free its scene graph resources if not already done.
3082 void QQuickItem::releaseResources()
3086 QSGTransformNode *QQuickItemPrivate::createTransformNode()
3088 return new QSGTransformNode;
3091 void QQuickItem::updatePolish()
3095 void QQuickItemPrivate::addItemChangeListener(QQuickItemChangeListener *listener, ChangeTypes types)
3097 changeListeners.append(ChangeListener(listener, types));
3100 void QQuickItemPrivate::removeItemChangeListener(QQuickItemChangeListener *listener, ChangeTypes types)
3102 ChangeListener change(listener, types);
3103 changeListeners.removeOne(change);
3106 void QQuickItemPrivate::updateOrAddGeometryChangeListener(QQuickItemChangeListener *listener, GeometryChangeTypes types)
3108 ChangeListener change(listener, types);
3109 int index = changeListeners.find(change);
3111 changeListeners[index].gTypes = change.gTypes; //we may have different GeometryChangeTypes
3113 changeListeners.append(change);
3116 void QQuickItemPrivate::updateOrRemoveGeometryChangeListener(QQuickItemChangeListener *listener,
3117 GeometryChangeTypes types)
3119 ChangeListener change(listener, types);
3120 if (types == NoChange) {
3121 changeListeners.removeOne(change);
3123 int index = changeListeners.find(change);
3125 changeListeners[index].gTypes = change.gTypes; //we may have different GeometryChangeTypes
3129 void QQuickItem::keyPressEvent(QKeyEvent *event)
3134 void QQuickItem::keyReleaseEvent(QKeyEvent *event)
3139 void QQuickItem::inputMethodEvent(QInputMethodEvent *event)
3144 void QQuickItem::focusInEvent(QFocusEvent *)
3146 #ifndef QT_NO_ACCESSIBILITY
3147 QAccessibleEvent ev(this, QAccessible::Focus);
3148 QAccessible::updateAccessibility(&ev);
3152 void QQuickItem::focusOutEvent(QFocusEvent *)
3156 void QQuickItem::mousePressEvent(QMouseEvent *event)
3161 void QQuickItem::mouseMoveEvent(QMouseEvent *event)
3166 void QQuickItem::mouseReleaseEvent(QMouseEvent *event)
3171 void QQuickItem::mouseDoubleClickEvent(QMouseEvent *)
3175 void QQuickItem::mouseUngrabEvent()
3180 void QQuickItem::touchUngrabEvent()
3185 void QQuickItem::wheelEvent(QWheelEvent *event)
3190 void QQuickItem::touchEvent(QTouchEvent *event)
3195 void QQuickItem::hoverEnterEvent(QHoverEvent *event)
3200 void QQuickItem::hoverMoveEvent(QHoverEvent *event)
3205 void QQuickItem::hoverLeaveEvent(QHoverEvent *event)
3210 void QQuickItem::dragEnterEvent(QDragEnterEvent *event)
3215 void QQuickItem::dragMoveEvent(QDragMoveEvent *event)
3221 void QQuickItem::dragLeaveEvent(QDragLeaveEvent *event)
3227 void QQuickItem::dropEvent(QDropEvent *event)
3232 bool QQuickItem::childMouseEventFilter(QQuickItem *, QEvent *)
3237 void QQuickItem::windowDeactivateEvent()
3239 foreach (QQuickItem* item, childItems()) {
3240 item->windowDeactivateEvent();
3244 QVariant QQuickItem::inputMethodQuery(Qt::InputMethodQuery query) const
3246 Q_D(const QQuickItem);
3251 v = (bool)(flags() & ItemAcceptsInputMethod);
3254 case Qt::ImCursorRectangle:
3256 case Qt::ImCursorPosition:
3257 case Qt::ImSurroundingText:
3258 case Qt::ImCurrentSelection:
3259 case Qt::ImMaximumTextLength:
3260 case Qt::ImAnchorPosition:
3261 case Qt::ImPreferredLanguage:
3262 if (d->extra.isAllocated() && d->extra->keyHandler)
3263 v = d->extra->keyHandler->inputMethodQuery(query);
3271 QQuickAnchorLine QQuickItemPrivate::left() const
3273 Q_Q(const QQuickItem);
3274 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Left);
3277 QQuickAnchorLine QQuickItemPrivate::right() const
3279 Q_Q(const QQuickItem);
3280 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Right);
3283 QQuickAnchorLine QQuickItemPrivate::horizontalCenter() const
3285 Q_Q(const QQuickItem);
3286 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::HCenter);
3289 QQuickAnchorLine QQuickItemPrivate::top() const
3291 Q_Q(const QQuickItem);
3292 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Top);
3295 QQuickAnchorLine QQuickItemPrivate::bottom() const
3297 Q_Q(const QQuickItem);
3298 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Bottom);
3301 QQuickAnchorLine QQuickItemPrivate::verticalCenter() const
3303 Q_Q(const QQuickItem);
3304 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::VCenter);
3307 QQuickAnchorLine QQuickItemPrivate::baseline() const
3309 Q_Q(const QQuickItem);
3310 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Baseline);
3313 qreal QQuickItem::baselineOffset() const
3315 Q_D(const QQuickItem);
3316 if (d->baselineOffsetValid) {
3317 return d->baselineOffset;
3323 void QQuickItem::setBaselineOffset(qreal offset)
3326 if (offset == d->baselineOffset)
3329 d->baselineOffset = offset;
3330 d->baselineOffsetValid = true;
3332 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
3333 const QQuickItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
3334 if (change.types & QQuickItemPrivate::Geometry) {
3335 QQuickAnchorsPrivate *anchor = change.listener->anchorPrivate();
3337 anchor->updateVerticalAnchors();
3341 if (d->_anchors && (d->_anchors->usedAnchors() & QQuickAnchors::BaselineAnchor))
3342 QQuickAnchorsPrivate::get(d->_anchors)->updateVerticalAnchors();
3344 emit baselineOffsetChanged(offset);
3347 void QQuickItem::update()
3350 Q_ASSERT(flags() & ItemHasContents);
3351 d->dirty(QQuickItemPrivate::Content);
3354 void QQuickItem::polish()
3357 if (!d->polishScheduled) {
3358 d->polishScheduled = true;
3360 QQuickCanvasPrivate *p = QQuickCanvasPrivate::get(d->canvas);
3361 bool maybeupdate = p->itemsToPolish.isEmpty();
3362 p->itemsToPolish.insert(this);
3363 if (maybeupdate) d->canvas->maybeUpdate();
3368 void QQuickItem::mapFromItem(QQmlV8Function *args) const
3370 if (args->Length() != 0) {
3371 v8::Local<v8::Value> item = (*args)[0];
3372 QV8Engine *engine = args->engine();
3374 QQuickItem *itemObj = 0;
3375 if (!item->IsNull())
3376 itemObj = qobject_cast<QQuickItem*>(engine->toQObject(item));
3378 if (!itemObj && !item->IsNull()) {
3379 qmlInfo(this) << "mapFromItem() given argument \"" << engine->toString(item->ToString())
3380 << "\" which is neither null nor an Item";
3384 v8::Local<v8::Object> rv = v8::Object::New();
3385 args->returnValue(rv);
3387 qreal x = (args->Length() > 1)?(*args)[1]->NumberValue():0;
3388 qreal y = (args->Length() > 2)?(*args)[2]->NumberValue():0;
3390 QPointF p = mapFromItem(itemObj, QPointF(x, y));
3392 rv->Set(v8::String::New("x"), v8::Number::New(p.x()));
3393 rv->Set(v8::String::New("y"), v8::Number::New(p.y()));
3397 QTransform QQuickItem::itemTransform(QQuickItem *other, bool *ok) const
3399 Q_D(const QQuickItem);
3401 // XXX todo - we need to be able to handle common parents better and detect
3405 QTransform t = d->itemToCanvasTransform();
3406 if (other) t *= QQuickItemPrivate::get(other)->canvasToItemTransform();
3411 void QQuickItem::mapToItem(QQmlV8Function *args) const
3413 if (args->Length() != 0) {
3414 v8::Local<v8::Value> item = (*args)[0];
3415 QV8Engine *engine = args->engine();
3417 QQuickItem *itemObj = 0;
3418 if (!item->IsNull())
3419 itemObj = qobject_cast<QQuickItem*>(engine->toQObject(item));
3421 if (!itemObj && !item->IsNull()) {
3422 qmlInfo(this) << "mapToItem() given argument \"" << engine->toString(item->ToString())
3423 << "\" which is neither null nor an Item";
3427 v8::Local<v8::Object> rv = v8::Object::New();
3428 args->returnValue(rv);
3430 qreal x = (args->Length() > 1)?(*args)[1]->NumberValue():0;
3431 qreal y = (args->Length() > 2)?(*args)[2]->NumberValue():0;
3433 QPointF p = mapToItem(itemObj, QPointF(x, y));
3435 rv->Set(v8::String::New("x"), v8::Number::New(p.x()));
3436 rv->Set(v8::String::New("y"), v8::Number::New(p.y()));
3440 void QQuickItem::forceActiveFocus()
3443 QQuickItem *parent = parentItem();
3445 if (parent->flags() & QQuickItem::ItemIsFocusScope) {
3446 parent->setFocus(true);
3448 parent = parent->parentItem();
3452 QQuickItem *QQuickItem::childAt(qreal x, qreal y) const
3454 // XXX todo - should this include transform etc.?
3455 const QList<QQuickItem *> children = childItems();
3456 for (int i = children.count()-1; i >= 0; --i) {
3457 QQuickItem *child = children.at(i);
3458 if (child->isVisible() && child->x() <= x
3459 && child->x() + child->width() >= x
3461 && child->y() + child->height() >= y)
3467 QQmlListProperty<QObject> QQuickItemPrivate::resources()
3469 return QQmlListProperty<QObject>(q_func(), 0, QQuickItemPrivate::resources_append,
3470 QQuickItemPrivate::resources_count,
3471 QQuickItemPrivate::resources_at,
3472 QQuickItemPrivate::resources_clear);
3475 QQmlListProperty<QQuickItem> QQuickItemPrivate::children()
3477 return QQmlListProperty<QQuickItem>(q_func(), 0, QQuickItemPrivate::children_append,
3478 QQuickItemPrivate::children_count,
3479 QQuickItemPrivate::children_at,
3480 QQuickItemPrivate::children_clear);
3485 \qmlproperty real QtQuick2::Item::visibleChildren
3486 This read-only property lists all of the item's children that are currently visible.
3487 Note that a child's visibility may have changed explicitly, or because the visibility
3488 of this (it's parent) item or another grandparent changed.
3490 QQmlListProperty<QQuickItem> QQuickItemPrivate::visibleChildren()
3492 return QQmlListProperty<QQuickItem>(q_func(), 0, QQuickItemPrivate::visibleChildren_append,
3493 QQuickItemPrivate::visibleChildren_count,
3494 QQuickItemPrivate::visibleChildren_at);
3498 QQmlListProperty<QQuickState> QQuickItemPrivate::states()
3500 return _states()->statesProperty();
3503 QQmlListProperty<QQuickTransition> QQuickItemPrivate::transitions()
3505 return _states()->transitionsProperty();
3508 QString QQuickItemPrivate::state() const
3513 return _stateGroup->state();
3516 void QQuickItemPrivate::setState(const QString &state)
3518 _states()->setState(state);
3521 QString QQuickItem::state() const
3523 Q_D(const QQuickItem);
3527 void QQuickItem::setState(const QString &state)
3533 QQmlListProperty<QQuickTransform> QQuickItem::transform()
3535 return QQmlListProperty<QQuickTransform>(this, 0, QQuickItemPrivate::transform_append,
3536 QQuickItemPrivate::transform_count,
3537 QQuickItemPrivate::transform_at,
3538 QQuickItemPrivate::transform_clear);
3541 void QQuickItem::classBegin()
3544 d->componentComplete = false;
3546 d->_stateGroup->classBegin();
3548 d->_anchors->classBegin();
3549 if (d->extra.isAllocated() && d->extra->layer)
3550 d->extra->layer->classBegin();
3553 void QQuickItem::componentComplete()
3556 d->componentComplete = true;
3558 d->_stateGroup->componentComplete();
3560 d->_anchors->componentComplete();
3561 QQuickAnchorsPrivate::get(d->_anchors)->updateOnComplete();
3564 if (d->extra.isAllocated() && d->extra->layer)
3565 d->extra->layer->componentComplete();
3567 if (d->extra.isAllocated() && d->extra->keyHandler)
3568 d->extra->keyHandler->componentComplete();
3570 if (d->extra.isAllocated() && d->extra->contents)
3571 d->extra->contents->complete();
3574 QQuickStateGroup *QQuickItemPrivate::_states()
3578 _stateGroup = new QQuickStateGroup;
3579 if (!componentComplete)
3580 _stateGroup->classBegin();
3581 FAST_CONNECT(_stateGroup, SIGNAL(stateChanged(QString)),
3582 q, SIGNAL(stateChanged(QString)))
3588 QPointF QQuickItemPrivate::computeTransformOrigin() const
3592 case QQuickItem::TopLeft:
3593 return QPointF(0, 0);
3594 case QQuickItem::Top:
3595 return QPointF(width / 2., 0);
3596 case QQuickItem::TopRight:
3597 return QPointF(width, 0);
3598 case QQuickItem::Left:
3599 return QPointF(0, height / 2.);
3600 case QQuickItem::Center:
3601 return QPointF(width / 2., height / 2.);
3602 case QQuickItem::Right:
3603 return QPointF(width, height / 2.);
3604 case QQuickItem::BottomLeft:
3605 return QPointF(0, height);
3606 case QQuickItem::Bottom:
3607 return QPointF(width / 2., height);
3608 case QQuickItem::BottomRight:
3609 return QPointF(width, height);
3613 void QQuickItemPrivate::transformChanged()
3615 if (extra.isAllocated() && extra->layer)
3616 extra->layer->updateMatrix();
3619 void QQuickItemPrivate::deliverKeyEvent(QKeyEvent *e)
3623 Q_ASSERT(e->isAccepted());
3624 if (extra.isAllocated() && extra->keyHandler) {
3625 if (e->type() == QEvent::KeyPress)
3626 extra->keyHandler->keyPressed(e, false);
3628 extra->keyHandler->keyReleased(e, false);
3630 if (e->isAccepted())
3636 if (e->type() == QEvent::KeyPress)
3637 q->keyPressEvent(e);
3639 q->keyReleaseEvent(e);
3641 if (e->isAccepted())
3644 if (extra.isAllocated() && extra->keyHandler) {
3647 if (e->type() == QEvent::KeyPress)
3648 extra->keyHandler->keyPressed(e, true);
3650 extra->keyHandler->keyReleased(e, true);
3654 void QQuickItemPrivate::deliverInputMethodEvent(QInputMethodEvent *e)
3658 Q_ASSERT(e->isAccepted());
3659 if (extra.isAllocated() && extra->keyHandler) {
3660 extra->keyHandler->inputMethodEvent(e, false);
3662 if (e->isAccepted())
3668 q->inputMethodEvent(e);
3670 if (e->isAccepted())
3673 if (extra.isAllocated() && extra->keyHandler) {
3676 extra->keyHandler->inputMethodEvent(e, true);
3680 void QQuickItemPrivate::deliverFocusEvent(QFocusEvent *e)
3684 if (e->type() == QEvent::FocusIn) {
3687 q->focusOutEvent(e);
3691 void QQuickItemPrivate::deliverMouseEvent(QMouseEvent *e)
3695 Q_ASSERT(e->isAccepted());
3697 switch (e->type()) {
3699 Q_ASSERT(!"Unknown event type");
3700 case QEvent::MouseMove:
3701 q->mouseMoveEvent(e);
3703 case QEvent::MouseButtonPress:
3704 q->mousePressEvent(e);
3706 case QEvent::MouseButtonRelease:
3707 q->mouseReleaseEvent(e);
3709 case QEvent::MouseButtonDblClick:
3710 q->mouseDoubleClickEvent(e);
3715 void QQuickItemPrivate::deliverWheelEvent(QWheelEvent *e)
3721 void QQuickItemPrivate::deliverTouchEvent(QTouchEvent *e)
3727 void QQuickItemPrivate::deliverHoverEvent(QHoverEvent *e)
3730 switch (e->type()) {
3732 Q_ASSERT(!"Unknown event type");
3733 case QEvent::HoverEnter:
3734 q->hoverEnterEvent(e);
3736 case QEvent::HoverLeave:
3737 q->hoverLeaveEvent(e);
3739 case QEvent::HoverMove:
3740 q->hoverMoveEvent(e);
3745 void QQuickItemPrivate::deliverDragEvent(QEvent *e)
3748 switch (e->type()) {
3750 Q_ASSERT(!"Unknown event type");
3751 case QEvent::DragEnter:
3752 q->dragEnterEvent(static_cast<QDragEnterEvent *>(e));
3754 case QEvent::DragLeave:
3755 q->dragLeaveEvent(static_cast<QDragLeaveEvent *>(e));
3757 case QEvent::DragMove:
3758 q->dragMoveEvent(static_cast<QDragMoveEvent *>(e));
3761 q->dropEvent(static_cast<QDropEvent *>(e));
3766 void QQuickItem::itemChange(ItemChange change, const ItemChangeData &value)
3773 Notify input method on updated query values if needed. \a indicates changed attributes.
3775 void QQuickItem::updateInputMethod(Qt::InputMethodQueries queries)
3777 if (hasActiveFocus())
3778 qApp->inputMethod()->update(queries);
3782 // XXX todo - do we want/need this anymore?
3783 // Note that it's now used for varying clip rect
3784 QRectF QQuickItem::boundingRect() const
3786 Q_D(const QQuickItem);
3787 return QRectF(0, 0, d->width, d->height);
3790 QQuickItem::TransformOrigin QQuickItem::transformOrigin() const
3792 Q_D(const QQuickItem);
3796 void QQuickItem::setTransformOrigin(TransformOrigin origin)
3799 if (origin == d->origin())
3802 d->extra.value().origin = origin;
3803 d->dirty(QQuickItemPrivate::TransformOrigin);
3805 emit transformOriginChanged(d->origin());
3808 QPointF QQuickItem::transformOriginPoint() const
3810 Q_D(const QQuickItem);
3811 if (d->extra.isAllocated() && !d->extra->userTransformOriginPoint.isNull())
3812 return d->extra->userTransformOriginPoint;
3813 return d->computeTransformOrigin();
3816 void QQuickItem::setTransformOriginPoint(const QPointF &point)
3819 if (d->extra.value().userTransformOriginPoint == point)
3822 d->extra->userTransformOriginPoint = point;
3823 d->dirty(QQuickItemPrivate::TransformOrigin);
3826 qreal QQuickItem::z() const
3828 Q_D(const QQuickItem);
3832 void QQuickItem::setZ(qreal v)
3838 d->extra.value().z = v;
3840 d->dirty(QQuickItemPrivate::ZValue);
3841 if (d->parentItem) {
3842 QQuickItemPrivate::get(d->parentItem)->dirty(QQuickItemPrivate::ChildrenStackingChanged);
3843 QQuickItemPrivate::get(d->parentItem)->markSortedChildrenDirty(this);
3848 if (d->extra.isAllocated() && d->extra->layer)
3849 d->extra->layer->updateZ();
3854 \qmlproperty real QtQuick2::Item::rotation
3855 This property holds the rotation of the item in degrees clockwise.
3857 This specifies how many degrees to rotate the item around its transformOrigin.
3858 The default rotation is 0 degrees (i.e. not rotated at all).
3862 \li \image declarative-rotation.png
3867 width: 100; height: 100
3870 x: 25; y: 25; width: 50; height: 50
3877 \sa transform, Rotation
3881 \qmlproperty real QtQuick2::Item::scale
3882 This property holds the scale of the item.
3884 A scale of less than 1 means the item will be displayed smaller than
3885 normal, and a scale of greater than 1 means the item will be
3886 displayed larger than normal. A negative scale means the item will
3889 By default, items are displayed at a scale of 1 (i.e. at their
3892 Scaling is from the item's transformOrigin.
3896 \li \image declarative-scale.png
3901 width: 100; height: 100
3904 width: 25; height: 25
3908 x: 25; y: 25; width: 50; height: 50
3915 \sa transform, Scale
3919 \qmlproperty real QtQuick2::Item::opacity
3921 This property holds the opacity of the item. Opacity is specified as a
3922 number between 0 (fully transparent) and 1 (fully opaque). The default is 1.
3924 When this property is set, the specified opacity is also applied
3925 individually to child items. In almost all cases this is what you want,
3926 but in some cases it may produce undesired results. For example in the
3927 second set of rectangles below, the red rectangle has specified an opacity
3928 of 0.5, which affects the opacity of its blue child rectangle even though
3929 the child has not specified an opacity.
3933 \li \image declarative-item_opacity1.png
3939 width: 100; height: 100
3942 x: 50; y: 50; width: 100; height: 100
3948 \li \image declarative-item_opacity2.png
3955 width: 100; height: 100
3958 x: 50; y: 50; width: 100; height: 100
3965 If an item's opacity is set to 0, the item will no longer receive mouse
3966 events, but will continue to receive key events and will retain the keyboard
3967 \l focus if it has been set. (In contrast, setting the \l visible property
3968 to \c false stops both mouse and keyboard events, and also removes focus
3973 Returns a value indicating whether mouse input should
3974 remain with this item exclusively.
3976 \sa setKeepMouseGrab()
3979 qreal QQuickItem::rotation() const
3981 Q_D(const QQuickItem);
3982 return d->rotation();
3985 void QQuickItem::setRotation(qreal r)
3988 if (d->rotation() == r)
3991 d->extra.value().rotation = r;
3993 d->dirty(QQuickItemPrivate::BasicTransform);
3995 d->itemChange(ItemRotationHasChanged, r);
3997 emit rotationChanged();
4000 qreal QQuickItem::scale() const
4002 Q_D(const QQuickItem);
4006 void QQuickItem::setScale(qreal s)
4009 if (d->scale() == s)
4012 d->extra.value().scale = s;
4014 d->dirty(QQuickItemPrivate::BasicTransform);
4016 emit scaleChanged();
4019 qreal QQuickItem::opacity() const
4021 Q_D(const QQuickItem);
4022 return d->opacity();
4025 void QQuickItem::setOpacity(qreal o)
4028 if (d->opacity() == o)
4031 d->extra.value().opacity = o;
4033 d->dirty(QQuickItemPrivate::OpacityValue);
4035 d->itemChange(ItemOpacityHasChanged, o);
4037 emit opacityChanged();
4040 bool QQuickItem::isVisible() const
4042 Q_D(const QQuickItem);
4043 return d->effectiveVisible;
4046 void QQuickItem::setVisible(bool v)
4049 if (v == d->explicitVisible)
4052 d->explicitVisible = v;
4054 const bool childVisibilityChanged = d->setEffectiveVisibleRecur(d->calcEffectiveVisible());
4055 if (childVisibilityChanged && d->parentItem)
4056 emit d->parentItem->visibleChildrenChanged(); // signal the parent, not this!
4059 bool QQuickItem::isEnabled() const
4061 Q_D(const QQuickItem);
4062 return d->effectiveEnable;
4065 void QQuickItem::setEnabled(bool e)
4068 if (e == d->explicitEnable)
4071 d->explicitEnable = e;
4073 QQuickItem *scope = parentItem();
4074 while (scope && !scope->isFocusScope())
4075 scope = scope->parentItem();
4077 d->setEffectiveEnableRecur(scope, d->calcEffectiveEnable());
4080 bool QQuickItemPrivate::calcEffectiveVisible() const
4082 // XXX todo - Should the effective visible of an element with no parent just be the current
4083 // effective visible? This would prevent pointless re-processing in the case of an element
4084 // moving to/from a no-parent situation, but it is different from what graphics view does.
4085 return explicitVisible && (!parentItem || QQuickItemPrivate::get(parentItem)->effectiveVisible);
4088 bool QQuickItemPrivate::setEffectiveVisibleRecur(bool newEffectiveVisible)
4092 if (newEffectiveVisible && !explicitVisible) {
4093 // This item locally overrides visibility
4094 return false; // effective visibility didn't change
4097 if (newEffectiveVisible == effectiveVisible) {
4098 // No change necessary
4099 return false; // effective visibility didn't change
4102 effectiveVisible = newEffectiveVisible;
4104 if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
4107 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(canvas);
4108 if (canvasPriv->mouseGrabberItem == q)
4112 bool childVisibilityChanged = false;
4113 for (int ii = 0; ii < childItems.count(); ++ii)
4114 childVisibilityChanged |= QQuickItemPrivate::get(childItems.at(ii))->setEffectiveVisibleRecur(newEffectiveVisible);
4116 itemChange(QQuickItem::ItemVisibleHasChanged, effectiveVisible);
4117 #ifndef QT_NO_ACCESSIBILITY
4119 QAccessibleEvent ev(q, effectiveVisible ? QAccessible::ObjectShow : QAccessible::ObjectHide);
4120 QAccessible::updateAccessibility(&ev);
4123 emit q->visibleChanged();
4124 if (childVisibilityChanged)
4125 emit q->visibleChildrenChanged();
4127 return true; // effective visibility DID change
4130 bool QQuickItemPrivate::calcEffectiveEnable() const
4132 // XXX todo - Should the effective enable of an element with no parent just be the current
4133 // effective enable? This would prevent pointless re-processing in the case of an element
4134 // moving to/from a no-parent situation, but it is different from what graphics view does.
4135 return explicitEnable && (!parentItem || QQuickItemPrivate::get(parentItem)->effectiveEnable);
4138 void QQuickItemPrivate::setEffectiveEnableRecur(QQuickItem *scope, bool newEffectiveEnable)
4142 if (newEffectiveEnable && !explicitEnable) {
4143 // This item locally overrides enable
4147 if (newEffectiveEnable == effectiveEnable) {
4148 // No change necessary
4152 effectiveEnable = newEffectiveEnable;
4155 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(canvas);
4156 if (canvasPriv->mouseGrabberItem == q)
4158 if (scope && !effectiveEnable && activeFocus) {
4159 canvasPriv->clearFocusInScope(
4160 scope, q, QQuickCanvasPrivate::DontChangeFocusProperty | QQuickCanvasPrivate::DontChangeSubFocusItem);
4164 for (int ii = 0; ii < childItems.count(); ++ii) {
4165 QQuickItemPrivate::get(childItems.at(ii))->setEffectiveEnableRecur(
4166 (flags & QQuickItem::ItemIsFocusScope) && scope ? q : scope, newEffectiveEnable);
4169 if (canvas && scope && effectiveEnable && focus) {
4170 QQuickCanvasPrivate::get(canvas)->setFocusInScope(
4171 scope, q, QQuickCanvasPrivate::DontChangeFocusProperty | QQuickCanvasPrivate::DontChangeSubFocusItem);
4174 emit q->enabledChanged();
4177 QString QQuickItemPrivate::dirtyToString() const
4179 #define DIRTY_TO_STRING(value) if (dirtyAttributes & value) { \
4180 if (!rv.isEmpty()) \
4181 rv.append(QLatin1String("|")); \
4182 rv.append(QLatin1String(#value)); \
4185 // QString rv = QLatin1String("0x") + QString::number(dirtyAttributes, 16);
4188 DIRTY_TO_STRING(TransformOrigin);
4189 DIRTY_TO_STRING(Transform);
4190 DIRTY_TO_STRING(BasicTransform);
4191 DIRTY_TO_STRING(Position);
4192 DIRTY_TO_STRING(Size);
4193 DIRTY_TO_STRING(ZValue);
4194 DIRTY_TO_STRING(Content);
4195 DIRTY_TO_STRING(Smooth);
4196 DIRTY_TO_STRING(OpacityValue);
4197 DIRTY_TO_STRING(ChildrenChanged);
4198 DIRTY_TO_STRING(ChildrenStackingChanged);
4199 DIRTY_TO_STRING(ParentChanged);
4200 DIRTY_TO_STRING(Clip);
4201 DIRTY_TO_STRING(Canvas);
4202 DIRTY_TO_STRING(EffectReference);
4203 DIRTY_TO_STRING(Visible);
4204 DIRTY_TO_STRING(HideReference);
4205 DIRTY_TO_STRING(PerformanceHints);
4210 void QQuickItemPrivate::dirty(DirtyType type)
4213 if (type & (TransformOrigin | Transform | BasicTransform | Position | Size))
4216 if (!(dirtyAttributes & type) || (canvas && !prevDirtyItem)) {
4217 dirtyAttributes |= type;
4220 QQuickCanvasPrivate::get(canvas)->dirtyItem(q);
4225 void QQuickItemPrivate::addToDirtyList()
4230 if (!prevDirtyItem) {
4231 Q_ASSERT(!nextDirtyItem);
4233 QQuickCanvasPrivate *p = QQuickCanvasPrivate::get(canvas);
4234 nextDirtyItem = p->dirtyItemList;
4235 if (nextDirtyItem) QQuickItemPrivate::get(nextDirtyItem)->prevDirtyItem = &nextDirtyItem;
4236 prevDirtyItem = &p->dirtyItemList;
4237 p->dirtyItemList = q;
4240 Q_ASSERT(prevDirtyItem);
4243 void QQuickItemPrivate::removeFromDirtyList()
4245 if (prevDirtyItem) {
4246 if (nextDirtyItem) QQuickItemPrivate::get(nextDirtyItem)->prevDirtyItem = prevDirtyItem;
4247 *prevDirtyItem = nextDirtyItem;
4251 Q_ASSERT(!prevDirtyItem);
4252 Q_ASSERT(!nextDirtyItem);
4255 void QQuickItemPrivate::refFromEffectItem(bool hide)
4257 ++extra.value().effectRefCount;
4258 if (1 == extra->effectRefCount) {
4259 dirty(EffectReference);
4260 if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
4263 if (++extra->hideRefCount == 1)
4264 dirty(HideReference);
4268 void QQuickItemPrivate::derefFromEffectItem(bool unhide)
4270 Q_ASSERT(extra->effectRefCount);
4271 --extra->effectRefCount;
4272 if (0 == extra->effectRefCount) {
4273 dirty(EffectReference);
4274 if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
4277 if (--extra->hideRefCount == 0)
4278 dirty(HideReference);
4282 void QQuickItemPrivate::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data)
4286 case QQuickItem::ItemChildAddedChange:
4287 q->itemChange(change, data);
4288 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4289 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4290 if (change.types & QQuickItemPrivate::Children) {
4291 change.listener->itemChildAdded(q, data.item);
4295 case QQuickItem::ItemChildRemovedChange:
4296 q->itemChange(change, data);
4297 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4298 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4299 if (change.types & QQuickItemPrivate::Children) {
4300 change.listener->itemChildRemoved(q, data.item);
4304 case QQuickItem::ItemSceneChange:
4305 q->itemChange(change, data);
4307 case QQuickItem::ItemVisibleHasChanged:
4308 q->itemChange(change, data);
4309 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4310 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4311 if (change.types & QQuickItemPrivate::Visibility) {
4312 change.listener->itemVisibilityChanged(q);
4316 case QQuickItem::ItemParentHasChanged:
4317 q->itemChange(change, data);
4318 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4319 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4320 if (change.types & QQuickItemPrivate::Parent) {
4321 change.listener->itemParentChanged(q, data.item);
4325 case QQuickItem::ItemOpacityHasChanged:
4326 q->itemChange(change, data);
4327 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4328 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4329 if (change.types & QQuickItemPrivate::Opacity) {
4330 change.listener->itemOpacityChanged(q);
4334 case QQuickItem::ItemActiveFocusHasChanged:
4335 q->itemChange(change, data);
4337 case QQuickItem::ItemRotationHasChanged:
4338 q->itemChange(change, data);
4339 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4340 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4341 if (change.types & QQuickItemPrivate::Rotation) {
4342 change.listener->itemRotationChanged(q);
4350 \property QQuickItem::smooth
4351 \brief whether the item is smoothed or not.
4353 Primarily used in image based elements to decide if the item should use smooth
4354 sampling or not. Smooth sampling is performed using linear interpolation, while
4355 non-smooth is performed using nearest neighbor.
4357 In Qt Quick 2.0, this property has minimal impact on performance.
4363 Returns true if the item should be drawn with antialiasing and
4364 smooth pixmap filtering, false otherwise.
4366 The default is false.
4370 bool QQuickItem::smooth() const
4372 Q_D(const QQuickItem);
4377 Sets whether the item should be drawn with antialiasing and
4378 smooth pixmap filtering to \a smooth.
4382 void QQuickItem::setSmooth(bool smooth)
4385 if (d->smooth == smooth)
4389 d->dirty(QQuickItemPrivate::Smooth);
4391 emit smoothChanged(smooth);
4394 QQuickItem::Flags QQuickItem::flags() const
4396 Q_D(const QQuickItem);
4397 return (QQuickItem::Flags)d->flags;
4400 void QQuickItem::setFlag(Flag flag, bool enabled)
4404 setFlags((Flags)(d->flags | (quint32)flag));
4406 setFlags((Flags)(d->flags & ~(quint32)flag));
4409 void QQuickItem::setFlags(Flags flags)
4413 if ((flags & ItemIsFocusScope) != (d->flags & ItemIsFocusScope)) {
4414 if (flags & ItemIsFocusScope && !d->childItems.isEmpty() && d->canvas) {
4415 qWarning("QQuickItem: Cannot set FocusScope once item has children and is in a canvas.");
4416 flags &= ~ItemIsFocusScope;
4417 } else if (d->flags & ItemIsFocusScope) {
4418 qWarning("QQuickItem: Cannot unset FocusScope flag.");
4419 flags |= ItemIsFocusScope;
4423 if ((flags & ItemClipsChildrenToShape ) != (d->flags & ItemClipsChildrenToShape))
4424 d->dirty(QQuickItemPrivate::Clip);
4429 qreal QQuickItem::x() const
4431 Q_D(const QQuickItem);
4435 qreal QQuickItem::y() const
4437 Q_D(const QQuickItem);
4441 QPointF QQuickItem::pos() const
4443 Q_D(const QQuickItem);
4444 return QPointF(d->x, d->y);
4447 void QQuickItem::setX(qreal v)
4456 d->dirty(QQuickItemPrivate::Position);
4458 geometryChanged(QRectF(x(), y(), width(), height()),
4459 QRectF(oldx, y(), width(), height()));
4462 void QQuickItem::setY(qreal v)
4471 d->dirty(QQuickItemPrivate::Position);
4473 geometryChanged(QRectF(x(), y(), width(), height()),
4474 QRectF(x(), oldy, width(), height()));
4477 void QQuickItem::setPos(const QPointF &pos)
4480 if (QPointF(d->x, d->y) == pos)
4489 d->dirty(QQuickItemPrivate::Position);
4491 geometryChanged(QRectF(x(), y(), width(), height()),
4492 QRectF(oldx, oldy, width(), height()));
4495 qreal QQuickItem::width() const
4497 Q_D(const QQuickItem);
4501 void QQuickItem::setWidth(qreal w)
4507 d->widthValid = true;
4511 qreal oldWidth = d->width;
4514 d->dirty(QQuickItemPrivate::Size);
4516 geometryChanged(QRectF(x(), y(), width(), height()),
4517 QRectF(x(), y(), oldWidth, height()));
4520 void QQuickItem::resetWidth()
4523 d->widthValid = false;
4524 setImplicitWidth(implicitWidth());
4527 void QQuickItemPrivate::implicitWidthChanged()
4530 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4531 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4532 if (change.types & QQuickItemPrivate::ImplicitWidth) {
4533 change.listener->itemImplicitWidthChanged(q);
4536 emit q->implicitWidthChanged();
4539 qreal QQuickItemPrivate::getImplicitWidth() const
4541 return implicitWidth;
4544 Returns the width of the item that is implied by other properties that determine the content.
4546 qreal QQuickItem::implicitWidth() const
4548 Q_D(const QQuickItem);
4549 return d->getImplicitWidth();
4553 \qmlproperty real QtQuick2::Item::implicitWidth
4554 \qmlproperty real QtQuick2::Item::implicitHeight
4556 Defines the natural width or height of the Item if no \l width or \l height is specified.
4558 The default implicit size for most items is 0x0, however some elements have an inherent
4559 implicit size which cannot be overridden, e.g. Image, Text.
4561 Setting the implicit size is useful for defining components that have a preferred size
4562 based on their content, for example:
4569 property alias icon: image.source
4570 property alias label: text.text
4571 implicitWidth: text.implicitWidth + image.implicitWidth
4572 implicitHeight: Math.max(text.implicitHeight, image.implicitHeight)
4577 anchors.left: image.right; anchors.right: parent.right
4578 anchors.verticalCenter: parent.verticalCenter
4583 \b Note: using implicitWidth of Text or TextEdit and setting the width explicitly
4584 incurs a performance penalty as the text must be laid out twice.
4588 Sets the implied width of the item to \a w.
4589 This is the width implied by other properties that determine the content.
4591 void QQuickItem::setImplicitWidth(qreal w)
4594 bool changed = w != d->implicitWidth;
4595 d->implicitWidth = w;
4596 if (d->width == w || widthValid()) {
4598 d->implicitWidthChanged();
4602 qreal oldWidth = d->width;
4605 d->dirty(QQuickItemPrivate::Size);
4607 geometryChanged(QRectF(x(), y(), width(), height()),
4608 QRectF(x(), y(), oldWidth, height()));
4611 d->implicitWidthChanged();
4615 Returns whether the width property has been set explicitly.
4617 bool QQuickItem::widthValid() const
4619 Q_D(const QQuickItem);
4620 return d->widthValid;
4623 qreal QQuickItem::height() const
4625 Q_D(const QQuickItem);
4629 void QQuickItem::setHeight(qreal h)
4635 d->heightValid = true;
4639 qreal oldHeight = d->height;
4642 d->dirty(QQuickItemPrivate::Size);
4644 geometryChanged(QRectF(x(), y(), width(), height()),
4645 QRectF(x(), y(), width(), oldHeight));
4648 void QQuickItem::resetHeight()
4651 d->heightValid = false;
4652 setImplicitHeight(implicitHeight());
4655 void QQuickItemPrivate::implicitHeightChanged()
4658 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4659 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4660 if (change.types & QQuickItemPrivate::ImplicitHeight) {
4661 change.listener->itemImplicitHeightChanged(q);
4664 emit q->implicitHeightChanged();
4667 qreal QQuickItemPrivate::getImplicitHeight() const
4669 return implicitHeight;
4673 Returns the height of the item that is implied by other properties that determine the content.
4675 qreal QQuickItem::implicitHeight() const
4677 Q_D(const QQuickItem);
4678 return d->getImplicitHeight();
4683 Sets the implied height of the item to \a h.
4684 This is the height implied by other properties that determine the content.
4686 void QQuickItem::setImplicitHeight(qreal h)
4689 bool changed = h != d->implicitHeight;
4690 d->implicitHeight = h;
4691 if (d->height == h || heightValid()) {
4693 d->implicitHeightChanged();
4697 qreal oldHeight = d->height;
4700 d->dirty(QQuickItemPrivate::Size);
4702 geometryChanged(QRectF(x(), y(), width(), height()),
4703 QRectF(x(), y(), width(), oldHeight));
4706 d->implicitHeightChanged();
4709 void QQuickItem::setImplicitSize(qreal w, qreal h)
4712 bool wChanged = w != d->implicitWidth;
4713 bool hChanged = h != d->implicitHeight;
4715 d->implicitWidth = w;
4716 d->implicitHeight = h;
4720 if (d->width == w || widthValid()) {
4722 d->implicitWidthChanged();
4725 if (d->height == h || heightValid()) {
4727 d->implicitHeightChanged();
4733 qreal oldWidth = d->width;
4734 qreal oldHeight = d->height;
4740 d->dirty(QQuickItemPrivate::Size);
4742 geometryChanged(QRectF(x(), y(), width(), height()),
4743 QRectF(x(), y(), oldWidth, oldHeight));
4745 if (!wDone && wChanged)
4746 d->implicitWidthChanged();
4747 if (!hDone && hChanged)
4748 d->implicitHeightChanged();
4752 Returns whether the height property has been set explicitly.
4754 bool QQuickItem::heightValid() const
4756 Q_D(const QQuickItem);
4757 return d->heightValid;
4760 void QQuickItem::setSize(const QSizeF &size)
4763 d->heightValid = true;
4764 d->widthValid = true;
4766 if (QSizeF(d->width, d->height) == size)
4769 qreal oldHeight = d->height;
4770 qreal oldWidth = d->width;
4771 d->height = size.height();
4772 d->width = size.width();
4774 d->dirty(QQuickItemPrivate::Size);
4776 geometryChanged(QRectF(x(), y(), width(), height()),
4777 QRectF(x(), y(), oldWidth, oldHeight));
4780 bool QQuickItem::hasActiveFocus() const
4782 Q_D(const QQuickItem);
4783 return d->activeFocus;
4786 bool QQuickItem::hasFocus() const
4788 Q_D(const QQuickItem);
4792 void QQuickItem::setFocus(bool focus)
4795 if (d->focus == focus)
4798 if (d->canvas || d->parentItem) {
4799 // Need to find our nearest focus scope
4800 QQuickItem *scope = parentItem();
4801 while (scope && !scope->isFocusScope() && scope->parentItem())
4802 scope = scope->parentItem();
4805 QQuickCanvasPrivate::get(d->canvas)->setFocusInScope(scope, this);
4807 QQuickCanvasPrivate::get(d->canvas)->clearFocusInScope(scope, this);
4809 // do the focus changes from setFocusInScope/clearFocusInScope that are
4810 // unrelated to a canvas
4811 QVarLengthArray<QQuickItem *, 20> changed;
4812 QQuickItem *oldSubFocusItem = QQuickItemPrivate::get(scope)->subFocusItem;
4813 if (oldSubFocusItem) {
4814 QQuickItemPrivate::get(oldSubFocusItem)->updateSubFocusItem(scope, false);
4815 QQuickItemPrivate::get(oldSubFocusItem)->focus = false;
4816 changed << oldSubFocusItem;
4818 d->updateSubFocusItem(scope, focus);
4822 emit focusChanged(focus);
4824 QQuickCanvasPrivate::notifyFocusChangesRecur(changed.data(), changed.count() - 1);
4828 emit focusChanged(focus);
4832 bool QQuickItem::isFocusScope() const
4834 return flags() & ItemIsFocusScope;
4837 QQuickItem *QQuickItem::scopedFocusItem() const
4839 Q_D(const QQuickItem);
4840 if (!isFocusScope())
4843 return d->subFocusItem;
4847 Qt::MouseButtons QQuickItem::acceptedMouseButtons() const
4849 Q_D(const QQuickItem);
4850 return d->acceptedMouseButtons();
4853 void QQuickItem::setAcceptedMouseButtons(Qt::MouseButtons buttons)
4856 if (buttons & Qt::LeftButton)
4859 d->extra.clearFlag();
4861 buttons &= ~Qt::LeftButton;
4862 if (buttons || d->extra.isAllocated())
4863 d->extra.value().acceptedMouseButtons = buttons;
4866 bool QQuickItem::filtersChildMouseEvents() const
4868 Q_D(const QQuickItem);
4869 return d->filtersChildMouseEvents;
4872 void QQuickItem::setFiltersChildMouseEvents(bool filter)
4875 d->filtersChildMouseEvents = filter;
4878 bool QQuickItem::isUnderMouse() const
4880 Q_D(const QQuickItem);
4884 QPointF cursorPos = QGuiApplicationPrivate::lastCursorPosition;
4885 if (QRectF(0, 0, width(), height()).contains(mapFromScene(cursorPos))) // ### refactor: d->canvas->mapFromGlobal(cursorPos))))
4890 bool QQuickItem::acceptHoverEvents() const
4892 Q_D(const QQuickItem);
4893 return d->hoverEnabled;
4896 void QQuickItem::setAcceptHoverEvents(bool enabled)
4899 d->hoverEnabled = enabled;
4902 void QQuickItem::grabMouse()
4907 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
4908 if (canvasPriv->mouseGrabberItem == this)
4911 QQuickItem *oldGrabber = canvasPriv->mouseGrabberItem;
4912 canvasPriv->mouseGrabberItem = this;
4914 QEvent ev(QEvent::UngrabMouse);
4915 d->canvas->sendEvent(oldGrabber, &ev);
4919 void QQuickItem::ungrabMouse()
4924 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
4925 if (canvasPriv->mouseGrabberItem != this) {
4926 qWarning("QQuickItem::ungrabMouse(): Item is not the mouse grabber.");
4930 canvasPriv->mouseGrabberItem = 0;
4932 QEvent ev(QEvent::UngrabMouse);
4933 d->canvas->sendEvent(this, &ev);
4936 bool QQuickItem::keepMouseGrab() const
4938 Q_D(const QQuickItem);
4939 return d->keepMouse;
4943 The flag indicating whether the mouse should remain
4944 with this item is set to \a keep.
4946 This is useful for items that wish to grab and keep mouse
4947 interaction following a predefined gesture. For example,
4948 an item that is interested in horizontal mouse movement
4949 may set keepMouseGrab to true once a threshold has been
4950 exceeded. Once keepMouseGrab has been set to true, filtering
4951 items will not react to mouse events.
4953 If the item does not indicate that it wishes to retain mouse grab,
4954 a filtering item may steal the grab. For example, Flickable may attempt
4955 to steal a mouse grab if it detects that the user has begun to
4960 void QQuickItem::setKeepMouseGrab(bool keep)
4963 d->keepMouse = keep;
4967 Grabs the touch points specified by \a ids.
4969 These touch points will be owned by the item until
4970 they are released. Alternatively, the grab can be stolen
4971 by a filtering item like Flickable. Use setKeepTouchGrab()
4972 to prevent the grab from being stolen.
4974 \sa ungrabTouchPoints(), setKeepTouchGrab()
4976 void QQuickItem::grabTouchPoints(const QList<int> &ids)
4981 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
4983 QSet<QQuickItem*> ungrab;
4984 for (int i = 0; i < ids.count(); ++i) {
4985 QQuickItem *oldGrabber = canvasPriv->itemForTouchPointId.value(ids.at(i));
4986 if (oldGrabber == this)
4989 canvasPriv->itemForTouchPointId[ids.at(i)] = this;
4991 ungrab.insert(oldGrabber);
4993 foreach (QQuickItem *oldGrabber, ungrab)
4994 oldGrabber->touchUngrabEvent();
4998 Ungrabs the touch points owned by this item.
5000 \sa grabTouchPoints()
5002 void QQuickItem::ungrabTouchPoints()
5007 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
5009 QMutableHashIterator<int, QQuickItem*> i(canvasPriv->itemForTouchPointId);
5010 while (i.hasNext()) {
5012 if (i.value() == this)
5019 Returns a value indicating whether the touch points grabbed by this item
5020 should remain with this item exclusively.
5022 \sa setKeepTouchGrab(), keepMouseGrab()
5024 bool QQuickItem::keepTouchGrab() const
5026 Q_D(const QQuickItem);
5027 return d->keepTouch;
5031 The flag indicating whether the touch points grabbed
5032 by this item should remain with this item is set to \a keep.
5034 This is useful for items that wish to grab and keep specific touch
5035 points following a predefined gesture. For example,
5036 an item that is interested in horizontal touch point movement
5037 may set setKeepTouchGrab to true once a threshold has been
5038 exceeded. Once setKeepTouchGrab has been set to true, filtering
5039 items will not react to the relevant touch points.
5041 If the item does not indicate that it wishes to retain touch point grab,
5042 a filtering item may steal the grab. For example, Flickable may attempt
5043 to steal a touch point grab if it detects that the user has begun to
5046 \sa keepTouchGrab(), setKeepMouseGrab()
5048 void QQuickItem::setKeepTouchGrab(bool keep)
5051 d->keepTouch = keep;
5055 \qmlmethod object QtQuick2::Item::mapFromItem(Item item, real x, real y)
5057 Maps the point (\a x, \a y), which is in \a item's coordinate system, to
5058 this item's coordinate system, and returns an object with \c x and \c y
5059 properties matching the mapped coordinate.
5061 If \a item is a \c null value, this maps the point from the coordinate
5062 system of the root QML view.
5065 \qmlmethod object QtQuick2::Item::mapToItem(Item item, real x, real y)
5067 Maps the point (\a x, \a y), which is in this item's coordinate system, to
5068 \a item's coordinate system, and returns an object with \c x and \c y
5069 properties matching the mapped coordinate.
5071 If \a item is a \c null value, this maps \a x and \a y to the coordinate
5072 system of the root QML view.
5074 QPointF QQuickItem::mapToItem(const QQuickItem *item, const QPointF &point) const
5076 QPointF p = mapToScene(point);
5078 p = item->mapFromScene(p);
5082 QPointF QQuickItem::mapToScene(const QPointF &point) const
5084 Q_D(const QQuickItem);
5085 return d->itemToCanvasTransform().map(point);
5088 QRectF QQuickItem::mapRectToItem(const QQuickItem *item, const QRectF &rect) const
5090 Q_D(const QQuickItem);
5091 QTransform t = d->itemToCanvasTransform();
5093 t *= QQuickItemPrivate::get(item)->canvasToItemTransform();
5094 return t.mapRect(rect);
5097 QRectF QQuickItem::mapRectToScene(const QRectF &rect) const
5099 Q_D(const QQuickItem);
5100 return d->itemToCanvasTransform().mapRect(rect);
5103 QPointF QQuickItem::mapFromItem(const QQuickItem *item, const QPointF &point) const
5105 QPointF p = item?item->mapToScene(point):point;
5106 return mapFromScene(p);
5109 QPointF QQuickItem::mapFromScene(const QPointF &point) const
5111 Q_D(const QQuickItem);
5112 return d->canvasToItemTransform().map(point);
5115 QRectF QQuickItem::mapRectFromItem(const QQuickItem *item, const QRectF &rect) const
5117 Q_D(const QQuickItem);
5118 QTransform t = item?QQuickItemPrivate::get(item)->itemToCanvasTransform():QTransform();
5119 t *= d->canvasToItemTransform();
5120 return t.mapRect(rect);
5123 QRectF QQuickItem::mapRectFromScene(const QRectF &rect) const
5125 Q_D(const QQuickItem);
5126 return d->canvasToItemTransform().mapRect(rect);
5131 \qmlmethod QtQuick2::Item::forceActiveFocus()
5133 Forces active focus on the item.
5135 This method sets focus on the item and makes sure that all the focus scopes
5136 higher in the object hierarchy are also given the focus.
5140 Forces active focus on the item.
5142 This method sets focus on the item and makes sure that all the focus scopes
5143 higher in the object hierarchy are also given the focus.
5147 \qmlmethod QtQuick2::Item::childAt(real x, real y)
5149 Returns the visible child item at point (\a x, \a y), which is in this
5150 item's coordinate system, or \c null if there is no such item.
5154 Returns the visible child item at point (\a x, \a y), which is in this
5155 item's coordinate system, or 0 if there is no such item.
5159 \qmlproperty list<State> QtQuick2::Item::states
5160 This property holds a list of states defined by the item.
5176 \sa {qmlstate}{States}
5179 \qmlproperty list<Transition> QtQuick2::Item::transitions
5180 This property holds a list of transitions defined by the item.
5196 \sa {QML Animation and Transitions}{Transitions}
5199 \qmlproperty list<Filter> QtQuick2::Item::filter
5200 This property holds a list of graphical filters to be applied to the item.
5202 \l {Filter}{Filters} include things like \l {Blur}{blurring}
5203 the item, or giving it a \l Reflection. Some
5204 filters may not be available on all canvases; if a filter is not
5205 available on a certain canvas, it will simply not be applied for
5206 that canvas (but the QML will still be considered valid).
5224 \qmlproperty bool QtQuick2::Item::clip
5225 This property holds whether clipping is enabled. The default clip value is \c false.
5227 If clipping is enabled, an item will clip its own painting, as well
5228 as the painting of its children, to its bounding rectangle.
5230 Non-rectangular clipping regions are not supported for performance reasons.
5234 \property QQuickItem::clip
5235 This property holds whether clipping is enabled. The default clip value is \c false.
5237 If clipping is enabled, an item will clip its own painting, as well
5238 as the painting of its children, to its bounding rectangle. If you set
5239 clipping during an item's paint operation, remember to re-set it to
5240 prevent clipping the rest of your scene.
5242 Non-rectangular clipping regions are not supported for performance reasons.
5246 \qmlproperty string QtQuick2::Item::state
5248 This property holds the name of the current state of the item.
5250 This property is often used in scripts to change between states. For
5255 if (button.state == 'On')
5256 button.state = 'Off';
5258 button.state = 'On';
5262 If the item is in its base state (i.e. no explicit state has been
5263 set), \c state will be a blank string. Likewise, you can return an
5264 item to its base state by setting its current state to \c ''.
5266 \sa {qmlstates}{States}
5270 \qmlproperty list<Transform> QtQuick2::Item::transform
5271 This property holds the list of transformations to apply.
5273 For more information see \l Transform.
5277 \enum QQuickItem::TransformOrigin
5279 Controls the point about which simple transforms like scale apply.
5281 \value TopLeft The top-left corner of the item.
5282 \value Top The center point of the top of the item.
5283 \value TopRight The top-right corner of the item.
5284 \value Left The left most point of the vertical middle.
5285 \value Center The center of the item.
5286 \value Right The right most point of the vertical middle.
5287 \value BottomLeft The bottom-left corner of the item.
5288 \value Bottom The center point of the bottom of the item.
5289 \value BottomRight The bottom-right corner of the item.
5294 \qmlproperty bool QtQuick2::Item::activeFocus
5296 This property indicates whether the item has active focus.
5298 An item with active focus will receive keyboard input,
5299 or is a FocusScope ancestor of the item that will receive keyboard input.
5301 Usually, activeFocus is gained by setting focus on an item and its enclosing
5302 FocusScopes. In the following example \c input will have activeFocus.
5315 \sa focus, {qmlfocus}{Keyboard Focus}
5319 \qmlproperty bool QtQuick2::Item::focus
5320 This property indicates whether the item has focus within the enclosing focus scope. If true, this item
5321 will gain active focus when the enclosing focus scope gains active focus.
5322 In the following example, \c input will be given active focus when \c scope gains active focus.
5335 For the purposes of this property, the scene as a whole is assumed to act like a focus scope.
5336 On a practical level, that means the following QML will give active focus to \c input on startup.
5347 \sa activeFocus, {qmlfocus}{Keyboard Focus}
5352 \property QQuickItem::anchors
5357 \property QQuickItem::left
5362 \property QQuickItem::right
5367 \property QQuickItem::horizontalCenter
5372 \property QQuickItem::top
5377 \property QQuickItem::bottom
5382 \property QQuickItem::verticalCenter
5387 \property QQuickItem::focus
5392 \property QQuickItem::transform
5397 \property QQuickItem::transformOrigin
5402 \property QQuickItem::activeFocus
5407 \property QQuickItem::baseline
5412 \property QQuickItem::data
5417 \property QQuickItem::resources
5422 \property QQuickItem::state
5427 \property QQuickItem::states
5432 \property QQuickItem::transformOriginPoint
5437 \property QQuickItem::transitions
5441 bool QQuickItem::event(QEvent *ev)
5444 if (ev->type() == QEvent::PolishRequest) {
5446 d->polishScheduled = false;
5450 return QObject::event(ev);
5453 if (ev->type() == QEvent::InputMethodQuery) {
5454 QInputMethodQueryEvent *query = static_cast<QInputMethodQueryEvent *>(ev);
5455 Qt::InputMethodQueries queries = query->queries();
5456 for (uint i = 0; i < 32; ++i) {
5457 Qt::InputMethodQuery q = (Qt::InputMethodQuery)(int)(queries & (1<<i));
5459 QVariant v = inputMethodQuery(q);
5460 query->setValue(q, v);
5465 } else if (ev->type() == QEvent::InputMethod) {
5466 inputMethodEvent(static_cast<QInputMethodEvent *>(ev));
5469 return QObject::event(ev);
5472 #ifndef QT_NO_DEBUG_STREAM
5473 QDebug operator<<(QDebug debug, QQuickItem *item)
5476 debug << "QQuickItem(0)";
5480 debug << item->metaObject()->className() << "(this =" << ((void*)item)
5481 << ", name=" << item->objectName()
5482 << ", parent =" << ((void*)item->parentItem())
5483 << ", geometry =" << QRectF(item->pos(), QSizeF(item->width(), item->height()))
5484 << ", z =" << item->z() << ')';
5489 qint64 QQuickItemPrivate::consistentTime = -1;
5490 void QQuickItemPrivate::setConsistentTime(qint64 t)
5495 class QElapsedTimerConsistentTimeHack
5499 t1 = QQuickItemPrivate::consistentTime;
5503 return QQuickItemPrivate::consistentTime - t1;
5506 qint64 val = QQuickItemPrivate::consistentTime - t1;
5507 t1 = QQuickItemPrivate::consistentTime;
5517 void QQuickItemPrivate::start(QElapsedTimer &t)
5519 if (QQuickItemPrivate::consistentTime == -1)
5522 ((QElapsedTimerConsistentTimeHack*)&t)->start();
5525 qint64 QQuickItemPrivate::elapsed(QElapsedTimer &t)
5527 if (QQuickItemPrivate::consistentTime == -1)
5530 return ((QElapsedTimerConsistentTimeHack*)&t)->elapsed();
5533 qint64 QQuickItemPrivate::restart(QElapsedTimer &t)
5535 if (QQuickItemPrivate::consistentTime == -1)
5538 return ((QElapsedTimerConsistentTimeHack*)&t)->restart();
5542 \fn bool QQuickItem::isTextureProvider() const
5544 Returns true if this item is a texture provider. The default
5545 implementation returns false.
5547 This function can be called from any thread.
5550 bool QQuickItem::isTextureProvider() const
5552 Q_D(const QQuickItem);
5553 return d->extra.isAllocated() && d->extra->layer && d->extra->layer->effectSource() ?
5554 d->extra->layer->effectSource()->isTextureProvider() : false;
5558 \fn QSGTextureProvider *QQuickItem::textureProvider() const
5560 Returns the texture provider for an item. The default implementation
5563 This function may only be called on the rendering thread.
5566 QSGTextureProvider *QQuickItem::textureProvider() const
5568 Q_D(const QQuickItem);
5569 return d->extra.isAllocated() && d->extra->layer && d->extra->layer->effectSource() ?
5570 d->extra->layer->effectSource()->textureProvider() : 0;
5573 QQuickItemLayer *QQuickItemPrivate::layer() const
5575 if (!extra.isAllocated() || !extra->layer) {
5576 extra.value().layer = new QQuickItemLayer(const_cast<QQuickItem *>(q_func()));
5577 if (!componentComplete)
5578 extra->layer->classBegin();
5580 return extra->layer;
5583 QQuickItemLayer::QQuickItemLayer(QQuickItem *item)
5588 , m_componentComplete(true)
5589 , m_wrapMode(QQuickShaderEffectSource::ClampToEdge)
5590 , m_format(QQuickShaderEffectSource::RGBA)
5592 , m_effectComponent(0)
5598 QQuickItemLayer::~QQuickItemLayer()
5600 delete m_effectSource;
5607 \qmlproperty bool QtQuick2::Item::layer.enabled
5609 Holds wether the item is layered or not. Layering is disabled by default.
5611 A layered item is rendered into an offscreen surface and cached until
5612 it is changed. Enabling layering for complex QML item hierarchies can
5613 some times be an optimization.
5615 None of the other layer properties have any effect when the layer
5619 void QQuickItemLayer::setEnabled(bool e)
5624 if (m_componentComplete) {
5631 emit enabledChanged(e);
5634 void QQuickItemLayer::classBegin()
5636 Q_ASSERT(!m_effectSource);
5637 Q_ASSERT(!m_effect);
5638 m_componentComplete = false;
5641 void QQuickItemLayer::componentComplete()
5643 Q_ASSERT(!m_componentComplete);
5644 m_componentComplete = true;
5649 void QQuickItemLayer::activate()
5651 Q_ASSERT(!m_effectSource);
5652 m_effectSource = new QQuickShaderEffectSource();
5654 QQuickItem *parentItem = m_item->parentItem();
5656 m_effectSource->setParentItem(parentItem);
5657 m_effectSource->stackAfter(m_item);
5660 m_effectSource->setSourceItem(m_item);
5661 m_effectSource->setHideSource(true);
5662 m_effectSource->setSmooth(m_smooth);
5663 m_effectSource->setTextureSize(m_size);
5664 m_effectSource->setSourceRect(m_sourceRect);
5665 m_effectSource->setMipmap(m_mipmap);
5666 m_effectSource->setWrapMode(m_wrapMode);
5667 m_effectSource->setFormat(m_format);
5669 if (m_effectComponent)
5672 m_effectSource->setVisible(m_item->isVisible() && !m_effect);
5679 QQuickItemPrivate *id = QQuickItemPrivate::get(m_item);
5680 id->addItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Opacity | QQuickItemPrivate::Parent | QQuickItemPrivate::Visibility | QQuickItemPrivate::SiblingOrder);
5683 void QQuickItemLayer::deactivate()
5685 Q_ASSERT(m_effectSource);
5687 if (m_effectComponent)
5690 delete m_effectSource;
5693 QQuickItemPrivate *id = QQuickItemPrivate::get(m_item);
5694 id->removeItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Opacity | QQuickItemPrivate::Parent | QQuickItemPrivate::Visibility | QQuickItemPrivate::SiblingOrder);
5697 void QQuickItemLayer::activateEffect()
5699 Q_ASSERT(m_effectSource);
5700 Q_ASSERT(m_effectComponent);
5701 Q_ASSERT(!m_effect);
5703 QObject *created = m_effectComponent->beginCreate(m_effectComponent->creationContext());
5704 m_effect = qobject_cast<QQuickItem *>(created);
5706 qWarning("Item: layer.effect is not a QML Item.");
5707 m_effectComponent->completeCreate();
5711 QQuickItem *parentItem = m_item->parentItem();
5713 m_effect->setParentItem(parentItem);
5714 m_effect->stackAfter(m_effectSource);
5716 m_effect->setVisible(m_item->isVisible());
5717 m_effect->setProperty(m_name, qVariantFromValue<QObject *>(m_effectSource));
5718 m_effectComponent->completeCreate();
5721 void QQuickItemLayer::deactivateEffect()
5723 Q_ASSERT(m_effectSource);
5724 Q_ASSERT(m_effectComponent);
5732 \qmlproperty Component QtQuick2::Item::layer.effect
5734 Holds the effect that is applied to this layer.
5736 The effect is typically a \l ShaderEffect component, although any \l Item component can be
5737 assigned. The effect should have a source texture property with a name matching \l samplerName.
5742 void QQuickItemLayer::setEffect(QQmlComponent *component)
5744 if (component == m_effectComponent)
5747 bool updateNeeded = false;
5748 if (m_effectSource && m_effectComponent) {
5750 updateNeeded = true;
5753 m_effectComponent = component;
5755 if (m_effectSource && m_effectComponent) {
5757 updateNeeded = true;
5765 m_effectSource->setVisible(m_item->isVisible() && !m_effect);
5768 emit effectChanged(component);
5773 \qmlproperty bool QtQuick2::Item::layer.mipmap
5775 If this property is true, mipmaps are generated for the texture.
5777 \note Some OpenGL ES 2 implementations do not support mipmapping of
5778 non-power-of-two textures.
5781 void QQuickItemLayer::setMipmap(bool mipmap)
5783 if (mipmap == m_mipmap)
5788 m_effectSource->setMipmap(m_mipmap);
5790 emit mipmapChanged(mipmap);
5795 \qmlproperty enumeration QtQuick2::Item::layer.format
5797 This property defines the internal OpenGL format of the texture.
5798 Modifying this property makes most sense when the \a layer.effect is also
5799 specified. Depending on the OpenGL implementation, this property might
5800 allow you to save some texture memory.
5803 \li ShaderEffectSource.Alpha - GL_ALPHA
5804 \li ShaderEffectSource.RGB - GL_RGB
5805 \li ShaderEffectSource.RGBA - GL_RGBA
5808 \note Some OpenGL implementations do not support the GL_ALPHA format.
5811 void QQuickItemLayer::setFormat(QQuickShaderEffectSource::Format f)
5818 m_effectSource->setFormat(m_format);
5820 emit formatChanged(m_format);
5825 \qmlproperty enumeration QtQuick2::Item::layer.sourceRect
5827 This property defines which rectangular area of the \l sourceItem to
5828 render into the texture. The source rectangle can be larger than
5829 \l sourceItem itself. If the rectangle is null, which is the default,
5830 the whole \l sourceItem is rendered to texture.
5833 void QQuickItemLayer::setSourceRect(const QRectF &sourceRect)
5835 if (sourceRect == m_sourceRect)
5837 m_sourceRect = sourceRect;
5840 m_effectSource->setSourceRect(m_sourceRect);
5842 emit sourceRectChanged(sourceRect);
5848 \qmlproperty bool QtQuick2::Item::layer.smooth
5850 Holds whether the layer is smoothly transformed.
5853 void QQuickItemLayer::setSmooth(bool s)
5860 m_effectSource->setSmooth(m_smooth);
5862 emit smoothChanged(s);
5868 \qmlproperty size QtQuick2::Item::layer.textureSize
5870 This property holds the requested pixel size of the layers texture. If it is empty,
5871 which is the default, the size of the item is used.
5873 \note Some platforms have a limit on how small framebuffer objects can be,
5874 which means the actual texture size might be larger than the requested
5878 void QQuickItemLayer::setSize(const QSize &size)
5885 m_effectSource->setTextureSize(size);
5887 emit sizeChanged(size);
5893 \qmlproperty enumeration QtQuick2::Item::layer.wrapMode
5895 This property defines the OpenGL wrap modes associated with the texture.
5896 Modifying this property makes most sense when the \a layer.effect is
5900 \li ShaderEffectSource.ClampToEdge - GL_CLAMP_TO_EDGE both horizontally and vertically
5901 \li ShaderEffectSource.RepeatHorizontally - GL_REPEAT horizontally, GL_CLAMP_TO_EDGE vertically
5902 \li ShaderEffectSource.RepeatVertically - GL_CLAMP_TO_EDGE horizontally, GL_REPEAT vertically
5903 \li ShaderEffectSource.Repeat - GL_REPEAT both horizontally and vertically
5906 \note Some OpenGL ES 2 implementations do not support the GL_REPEAT
5907 wrap mode with non-power-of-two textures.
5910 void QQuickItemLayer::setWrapMode(QQuickShaderEffectSource::WrapMode mode)
5912 if (mode == m_wrapMode)
5917 m_effectSource->setWrapMode(m_wrapMode);
5919 emit wrapModeChanged(mode);
5923 \qmlproperty string QtQuick2::Item::layer.samplerName
5925 Holds the name of the effect's source texture property.
5927 samplerName needs to match the name of the effect's source texture property
5928 so that the Item can pass the layer's offscreen surface to the effect correctly.
5930 \sa effect, ShaderEffect
5933 void QQuickItemLayer::setName(const QByteArray &name) {
5937 m_effect->setProperty(m_name, QVariant());
5938 m_effect->setProperty(name, qVariantFromValue<QObject *>(m_effectSource));
5941 emit nameChanged(name);
5944 void QQuickItemLayer::itemOpacityChanged(QQuickItem *item)
5950 void QQuickItemLayer::itemGeometryChanged(QQuickItem *, const QRectF &, const QRectF &)
5955 void QQuickItemLayer::itemParentChanged(QQuickItem *item, QQuickItem *parent)
5958 Q_ASSERT(item == m_item);
5959 Q_ASSERT(parent != m_effectSource);
5960 Q_ASSERT(parent == 0 || parent != m_effect);
5962 m_effectSource->setParentItem(parent);
5964 m_effectSource->stackAfter(m_item);
5967 m_effect->setParentItem(parent);
5969 m_effect->stackAfter(m_effectSource);
5973 void QQuickItemLayer::itemSiblingOrderChanged(QQuickItem *)
5975 m_effectSource->stackAfter(m_item);
5977 m_effect->stackAfter(m_effectSource);
5980 void QQuickItemLayer::itemVisibilityChanged(QQuickItem *)
5982 QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
5984 l->setVisible(m_item->isVisible());
5987 void QQuickItemLayer::updateZ()
5989 if (!m_componentComplete || !m_enabled)
5991 QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
5993 l->setZ(m_item->z());
5996 void QQuickItemLayer::updateOpacity()
5998 QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
6000 l->setOpacity(m_item->opacity());
6003 void QQuickItemLayer::updateGeometry()
6005 QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
6007 QRectF bounds = m_item->boundingRect();
6008 l->setWidth(bounds.width());
6009 l->setHeight(bounds.height());
6010 l->setX(bounds.x() + m_item->x());
6011 l->setY(bounds.y() + m_item->y());
6014 void QQuickItemLayer::updateMatrix()
6016 // Called directly from transformChanged(), so needs some extra
6018 if (!m_componentComplete || !m_enabled)
6020 QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
6022 QQuickItemPrivate *ld = QQuickItemPrivate::get(l);
6023 l->setScale(m_item->scale());
6024 l->setRotation(m_item->rotation());
6025 ld->transforms = QQuickItemPrivate::get(m_item)->transforms;
6026 if (ld->origin() != QQuickItemPrivate::get(m_item)->origin())
6027 ld->extra.value().origin = QQuickItemPrivate::get(m_item)->origin();
6028 ld->dirty(QQuickItemPrivate::Transform);
6031 QQuickItemPrivate::ExtraData::ExtraData()
6032 : z(0), scale(1), rotation(0), opacity(1),
6033 contents(0), screenAttached(0), layoutDirectionAttached(0),
6034 keyHandler(0), layer(0), effectRefCount(0), hideRefCount(0),
6035 opacityNode(0), clipNode(0), rootNode(0), beforePaintNode(0),
6036 acceptedMouseButtons(0), origin(QQuickItem::Center)
6042 #include <moc_qquickitem.cpp>