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, int depth)
82 << QByteArray(depth, '\t').constData()
83 << (scope && QQuickItemPrivate::get(scope)->subFocusItem == item ? '*' : ' ')
85 << item->hasActiveFocus()
86 << item->isFocusScope()
88 foreach (QQuickItem *child, item->childItems()) {
91 item->isFocusScope() || !scope ? item : scope,
92 item->isFocusScope() || !scope ? depth + 1 : depth);
97 static void QQuickItem_parentNotifier(QObject *o, intptr_t, QQmlNotifier **n)
99 QQuickItemPrivate *d = QQuickItemPrivate::get(static_cast<QQuickItem *>(o));
100 *n = &d->parentNotifier;
103 QML_PRIVATE_ACCESSOR(QQuickItem, QQuickItem *, parent, parentItem)
104 QML_PRIVATE_ACCESSOR(QQuickItem, qreal, x, x)
105 QML_PRIVATE_ACCESSOR(QQuickItem, qreal, y, y)
106 QML_PRIVATE_ACCESSOR(QQuickItem, qreal, width, width)
107 QML_PRIVATE_ACCESSOR(QQuickItem, qreal, height, height)
109 static QQmlAccessors QQuickItem_parent = { QQuickItem_parentRead, QQuickItem_parentNotifier };
110 static QQmlAccessors QQuickItem_x = { QQuickItem_xRead, 0 };
111 static QQmlAccessors QQuickItem_y = { QQuickItem_yRead, 0 };
112 static QQmlAccessors QQuickItem_width = { QQuickItem_widthRead, 0 };
113 static QQmlAccessors QQuickItem_height = { QQuickItem_heightRead, 0 };
115 QML_DECLARE_PROPERTIES(QQuickItem) {
116 { QML_PROPERTY_NAME(parent), 0, &QQuickItem_parent },
117 { QML_PROPERTY_NAME(x), 0, &QQuickItem_x },
118 { QML_PROPERTY_NAME(y), 0, &QQuickItem_y },
119 { QML_PROPERTY_NAME(width), 0, &QQuickItem_width },
120 { QML_PROPERTY_NAME(height), 0, &QQuickItem_height }
123 void QQuickItemPrivate::registerAccessorProperties()
125 QML_DEFINE_PROPERTIES(QQuickItem);
129 \qmlclass Transform QQuickTransform
130 \inqmlmodule QtQuick 2
131 \ingroup qml-transform-elements
132 \brief The Transform elements provide a way of building advanced transformations on Items.
134 The Transform element is a base type which cannot be instantiated directly.
135 The following concrete Transform types are available:
143 The Transform elements let you create and control advanced transformations that can be configured
144 independently using specialized properties.
146 You can assign any number of Transform elements to an \l Item. Each Transform is applied in order,
151 \qmlclass Translate QQuickTranslate
152 \inqmlmodule QtQuick 2
153 \ingroup qml-transform-elements
154 \brief The Translate object provides a way to move an Item without changing its x or y properties.
156 The Translate object provides independent control over position in addition to the Item's x and y properties.
158 The following example moves the Y axis of the \l Rectangle elements while still allowing the \l Row element
159 to lay the items out as if they had not been transformed:
165 width: 100; height: 100
167 transform: Translate { y: 20 }
170 width: 100; height: 100
172 transform: Translate { y: -20 }
181 \qmlproperty real QtQuick2::Translate::x
183 The translation along the X axis.
187 \qmlproperty real QtQuick2::Translate::y
189 The translation along the Y axis.
193 \qmlclass Scale QQuickScale
194 \inqmlmodule QtQuick 2
195 \ingroup qml-transform-elements
196 \brief The Scale element provides a way to scale an Item.
198 The Scale element gives more control over scaling than using \l Item's \l{Item::scale}{scale} property. Specifically,
199 it allows a different scale for the x and y axes, and allows the scale to be relative to an
202 The following example scales the X axis of the Rectangle, relative to its interior point 25, 25:
205 width: 100; height: 100
207 transform: Scale { origin.x: 25; origin.y: 25; xScale: 3}
211 \sa Rotation, Translate
215 \qmlproperty real QtQuick2::Scale::origin.x
216 \qmlproperty real QtQuick2::Scale::origin.y
218 The point that the item is scaled from (i.e., the point that stays fixed relative to the parent as
219 the rest of the item grows). By default the origin is 0, 0.
223 \qmlproperty real QtQuick2::Scale::xScale
225 The scaling factor for the X axis.
229 \qmlproperty real QtQuick2::Scale::yScale
231 The scaling factor for the Y axis.
235 \qmlclass Rotation QQuickRotation
236 \inqmlmodule QtQuick 2
237 \ingroup qml-transform-elements
238 \brief The Rotation object provides a way to rotate an Item.
240 The Rotation object gives more control over rotation than using \l Item's \l{Item::rotation}{rotation} property.
241 Specifically, it allows (z axis) rotation to be relative to an arbitrary point.
243 The following example rotates a Rectangle around its interior point 25, 25:
246 width: 100; height: 100
248 transform: Rotation { origin.x: 25; origin.y: 25; angle: 45}
252 Rotation also provides a way to specify 3D-like rotations for Items. For these types of
253 rotations you must specify the axis to rotate around in addition to the origin point.
255 The following example shows various 3D-like rotations applied to an \l Image.
256 \snippet doc/src/snippets/qml/rotation.qml 0
258 \image axisrotation.png
260 \sa {declarative/ui-components/dialcontrol}{Dial Control example}, {declarative/toys/clocks}{Clocks example}
264 \qmlproperty real QtQuick2::Rotation::origin.x
265 \qmlproperty real QtQuick2::Rotation::origin.y
267 The origin point of the rotation (i.e., the point that stays fixed relative to the parent as
268 the rest of the item rotates). By default the origin is 0, 0.
272 \qmlproperty real QtQuick2::Rotation::axis.x
273 \qmlproperty real QtQuick2::Rotation::axis.y
274 \qmlproperty real QtQuick2::Rotation::axis.z
276 The axis to rotate around. For simple (2D) rotation around a point, you do not need to specify an axis,
277 as the default axis is the z axis (\c{ axis { x: 0; y: 0; z: 1 } }).
279 For a typical 3D-like rotation you will usually specify both the origin and the axis.
281 \image 3d-rotation-axis.png
285 \qmlproperty real QtQuick2::Rotation::angle
287 The angle to rotate, in degrees clockwise.
290 QQuickTransformPrivate::QQuickTransformPrivate()
294 QQuickTransform::QQuickTransform(QObject *parent)
295 : QObject(*(new QQuickTransformPrivate), parent)
299 QQuickTransform::QQuickTransform(QQuickTransformPrivate &dd, QObject *parent)
300 : QObject(dd, parent)
304 QQuickTransform::~QQuickTransform()
306 Q_D(QQuickTransform);
307 for (int ii = 0; ii < d->items.count(); ++ii) {
308 QQuickItemPrivate *p = QQuickItemPrivate::get(d->items.at(ii));
309 p->transforms.removeOne(this);
310 p->dirty(QQuickItemPrivate::Transform);
314 void QQuickTransform::update()
316 Q_D(QQuickTransform);
317 for (int ii = 0; ii < d->items.count(); ++ii) {
318 QQuickItemPrivate *p = QQuickItemPrivate::get(d->items.at(ii));
319 p->dirty(QQuickItemPrivate::Transform);
323 QQuickContents::QQuickContents(QQuickItem *item)
324 : m_item(item), m_x(0), m_y(0), m_width(0), m_height(0)
328 QQuickContents::~QQuickContents()
330 QList<QQuickItem *> children = m_item->childItems();
331 for (int i = 0; i < children.count(); ++i) {
332 QQuickItem *child = children.at(i);
333 QQuickItemPrivate::get(child)->removeItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed);
337 bool QQuickContents::calcHeight(QQuickItem *changed)
340 qreal oldheight = m_height;
344 qreal bottom = oldy + oldheight;
345 qreal y = changed->y();
346 if (y + changed->height() > bottom)
347 bottom = y + changed->height();
351 m_height = bottom - top;
355 QList<QQuickItem *> children = m_item->childItems();
356 for (int i = 0; i < children.count(); ++i) {
357 QQuickItem *child = children.at(i);
358 qreal y = child->y();
359 if (y + child->height() > bottom)
360 bottom = y + child->height();
364 if (!children.isEmpty())
366 m_height = qMax(bottom - top, qreal(0.0));
369 return (m_height != oldheight || m_y != oldy);
372 bool QQuickContents::calcWidth(QQuickItem *changed)
375 qreal oldwidth = m_width;
379 qreal right = oldx + oldwidth;
380 qreal x = changed->x();
381 if (x + changed->width() > right)
382 right = x + changed->width();
386 m_width = right - left;
388 qreal left = FLT_MAX;
390 QList<QQuickItem *> children = m_item->childItems();
391 for (int i = 0; i < children.count(); ++i) {
392 QQuickItem *child = children.at(i);
393 qreal x = child->x();
394 if (x + child->width() > right)
395 right = x + child->width();
399 if (!children.isEmpty())
401 m_width = qMax(right - left, qreal(0.0));
404 return (m_width != oldwidth || m_x != oldx);
407 void QQuickContents::complete()
409 QQuickItemPrivate::get(m_item)->addItemChangeListener(this, QQuickItemPrivate::Children);
411 QList<QQuickItem *> children = m_item->childItems();
412 for (int i = 0; i < children.count(); ++i) {
413 QQuickItem *child = children.at(i);
414 QQuickItemPrivate::get(child)->addItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed);
415 //###what about changes to visibility?
420 void QQuickContents::updateRect()
422 QQuickItemPrivate::get(m_item)->emitChildrenRectChanged(rectF());
425 void QQuickContents::itemGeometryChanged(QQuickItem *changed, const QRectF &newGeometry, const QRectF &oldGeometry)
428 bool wChanged = false;
429 bool hChanged = false;
430 //### we can only pass changed if the left edge has moved left, or the right edge has moved right
431 if (newGeometry.width() != oldGeometry.width() || newGeometry.x() != oldGeometry.x())
432 wChanged = calcWidth(/*changed*/);
433 if (newGeometry.height() != oldGeometry.height() || newGeometry.y() != oldGeometry.y())
434 hChanged = calcHeight(/*changed*/);
435 if (wChanged || hChanged)
439 void QQuickContents::itemDestroyed(QQuickItem *item)
442 QQuickItemPrivate::get(item)->removeItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed);
446 void QQuickContents::itemChildRemoved(QQuickItem *, QQuickItem *item)
449 QQuickItemPrivate::get(item)->removeItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed);
453 void QQuickContents::itemChildAdded(QQuickItem *, QQuickItem *item)
456 QQuickItemPrivate::get(item)->addItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed);
460 QQuickItemKeyFilter::QQuickItemKeyFilter(QQuickItem *item)
461 : m_processPost(false), m_next(0)
463 QQuickItemPrivate *p = item?QQuickItemPrivate::get(item):0;
465 m_next = p->extra.value().keyHandler;
466 p->extra->keyHandler = this;
470 QQuickItemKeyFilter::~QQuickItemKeyFilter()
474 void QQuickItemKeyFilter::keyPressed(QKeyEvent *event, bool post)
476 if (m_next) m_next->keyPressed(event, post);
479 void QQuickItemKeyFilter::keyReleased(QKeyEvent *event, bool post)
481 if (m_next) m_next->keyReleased(event, post);
484 void QQuickItemKeyFilter::inputMethodEvent(QInputMethodEvent *event, bool post)
487 m_next->inputMethodEvent(event, post);
492 QVariant QQuickItemKeyFilter::inputMethodQuery(Qt::InputMethodQuery query) const
494 if (m_next) return m_next->inputMethodQuery(query);
498 void QQuickItemKeyFilter::componentComplete()
500 if (m_next) m_next->componentComplete();
503 \qmlclass KeyNavigation QQuickKeyNavigationAttached
504 \inqmlmodule QtQuick 2
505 \ingroup qml-basic-interaction-elements
506 \brief The KeyNavigation attached property supports key navigation by arrow keys.
508 Key-based user interfaces commonly allow the use of arrow keys to navigate between
509 focusable items. The KeyNavigation attached property enables this behavior by providing a
510 convenient way to specify the item that should gain focus when an arrow or tab key is pressed.
512 The following example provides key navigation for a 2x2 grid of items:
514 \snippet doc/src/snippets/qml/keynavigation.qml 0
516 The top-left item initially receives focus by setting \l {Item::}{focus} to
517 \c true. When an arrow key is pressed, the focus will move to the
518 appropriate item, as defined by the value that has been set for
519 the KeyNavigation \l left, \l right, \l up or \l down properties.
521 Note that if a KeyNavigation attached property receives the key press and release
522 events for a requested arrow or tab key, the event is accepted and does not
523 propagate any further.
525 By default, KeyNavigation receives key events after the item to which it is attached.
526 If the item accepts the key event, the KeyNavigation attached property will not
527 receive an event for that key. Setting the \l priority property to
528 \c KeyNavigation.BeforeItem allows the event to be used for key navigation
529 before the item, rather than after.
531 If item to which the focus is switching is not enabled or visible, an attempt will
532 be made to skip this item and focus on the next. This is possible if there are
533 a chain of items with the same KeyNavigation handler. If multiple items in a row are not enabled
534 or visible, they will also be skipped.
536 KeyNavigation will implicitly set the other direction to return focus to this item. So if you set
537 \l left to another item, \l right will be set on that item's KeyNavigation to set focus back to this
538 item. However, if that item's KeyNavigation has had right explicitly set then no change will occur.
539 This means that the above example could have been written, with the same behaviour, without specifing
540 KeyNavigation.right or KeyNavigation.down for any of the items.
542 \sa {Keys}{Keys attached property}
546 \qmlproperty Item QtQuick2::KeyNavigation::left
547 \qmlproperty Item QtQuick2::KeyNavigation::right
548 \qmlproperty Item QtQuick2::KeyNavigation::up
549 \qmlproperty Item QtQuick2::KeyNavigation::down
550 \qmlproperty Item QtQuick2::KeyNavigation::tab
551 \qmlproperty Item QtQuick2::KeyNavigation::backtab
553 These properties hold the item to assign focus to
554 when the left, right, up or down cursor keys, or the
559 \qmlproperty Item QtQuick2::KeyNavigation::tab
560 \qmlproperty Item QtQuick2::KeyNavigation::backtab
562 These properties hold the item to assign focus to
563 when the Tab key or Shift+Tab key combination (Backtab) are pressed.
566 QQuickKeyNavigationAttached::QQuickKeyNavigationAttached(QObject *parent)
567 : QObject(*(new QQuickKeyNavigationAttachedPrivate), parent),
568 QQuickItemKeyFilter(qobject_cast<QQuickItem*>(parent))
570 m_processPost = true;
573 QQuickKeyNavigationAttached *
574 QQuickKeyNavigationAttached::qmlAttachedProperties(QObject *obj)
576 return new QQuickKeyNavigationAttached(obj);
579 QQuickItem *QQuickKeyNavigationAttached::left() const
581 Q_D(const QQuickKeyNavigationAttached);
585 void QQuickKeyNavigationAttached::setLeft(QQuickItem *i)
587 Q_D(QQuickKeyNavigationAttached);
592 QQuickKeyNavigationAttached* other =
593 qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
594 if (other && !other->d_func()->rightSet){
595 other->d_func()->right = qobject_cast<QQuickItem*>(parent());
596 emit other->rightChanged();
601 QQuickItem *QQuickKeyNavigationAttached::right() const
603 Q_D(const QQuickKeyNavigationAttached);
607 void QQuickKeyNavigationAttached::setRight(QQuickItem *i)
609 Q_D(QQuickKeyNavigationAttached);
614 QQuickKeyNavigationAttached* other =
615 qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
616 if (other && !other->d_func()->leftSet){
617 other->d_func()->left = qobject_cast<QQuickItem*>(parent());
618 emit other->leftChanged();
623 QQuickItem *QQuickKeyNavigationAttached::up() const
625 Q_D(const QQuickKeyNavigationAttached);
629 void QQuickKeyNavigationAttached::setUp(QQuickItem *i)
631 Q_D(QQuickKeyNavigationAttached);
636 QQuickKeyNavigationAttached* other =
637 qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
638 if (other && !other->d_func()->downSet){
639 other->d_func()->down = qobject_cast<QQuickItem*>(parent());
640 emit other->downChanged();
645 QQuickItem *QQuickKeyNavigationAttached::down() const
647 Q_D(const QQuickKeyNavigationAttached);
651 void QQuickKeyNavigationAttached::setDown(QQuickItem *i)
653 Q_D(QQuickKeyNavigationAttached);
658 QQuickKeyNavigationAttached* other =
659 qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
660 if (other && !other->d_func()->upSet) {
661 other->d_func()->up = qobject_cast<QQuickItem*>(parent());
662 emit other->upChanged();
667 QQuickItem *QQuickKeyNavigationAttached::tab() const
669 Q_D(const QQuickKeyNavigationAttached);
673 void QQuickKeyNavigationAttached::setTab(QQuickItem *i)
675 Q_D(QQuickKeyNavigationAttached);
680 QQuickKeyNavigationAttached* other =
681 qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
682 if (other && !other->d_func()->backtabSet) {
683 other->d_func()->backtab = qobject_cast<QQuickItem*>(parent());
684 emit other->backtabChanged();
689 QQuickItem *QQuickKeyNavigationAttached::backtab() const
691 Q_D(const QQuickKeyNavigationAttached);
695 void QQuickKeyNavigationAttached::setBacktab(QQuickItem *i)
697 Q_D(QQuickKeyNavigationAttached);
701 d->backtabSet = true;
702 QQuickKeyNavigationAttached* other =
703 qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
704 if (other && !other->d_func()->tabSet) {
705 other->d_func()->tab = qobject_cast<QQuickItem*>(parent());
706 emit other->tabChanged();
708 emit backtabChanged();
712 \qmlproperty enumeration QtQuick2::KeyNavigation::priority
714 This property determines whether the keys are processed before
715 or after the attached item's own key handling.
718 \li KeyNavigation.BeforeItem - process the key events before normal
719 item key processing. If the event is used for key navigation, it will be accepted and will not
720 be passed on to the item.
721 \li KeyNavigation.AfterItem (default) - process the key events after normal item key
722 handling. If the item accepts the key event it will not be
723 handled by the KeyNavigation attached property handler.
726 QQuickKeyNavigationAttached::Priority QQuickKeyNavigationAttached::priority() const
728 return m_processPost ? AfterItem : BeforeItem;
731 void QQuickKeyNavigationAttached::setPriority(Priority order)
733 bool processPost = order == AfterItem;
734 if (processPost != m_processPost) {
735 m_processPost = processPost;
736 emit priorityChanged();
740 void QQuickKeyNavigationAttached::keyPressed(QKeyEvent *event, bool post)
742 Q_D(QQuickKeyNavigationAttached);
745 if (post != m_processPost) {
746 QQuickItemKeyFilter::keyPressed(event, post);
751 switch (event->key()) {
753 if (QQuickItem *parentItem = qobject_cast<QQuickItem*>(parent()))
754 mirror = QQuickItemPrivate::get(parentItem)->effectiveLayoutMirror;
755 QQuickItem* leftItem = mirror ? d->right : d->left;
757 setFocusNavigation(leftItem, mirror ? "right" : "left");
762 case Qt::Key_Right: {
763 if (QQuickItem *parentItem = qobject_cast<QQuickItem*>(parent()))
764 mirror = QQuickItemPrivate::get(parentItem)->effectiveLayoutMirror;
765 QQuickItem* rightItem = mirror ? d->left : d->right;
767 setFocusNavigation(rightItem, mirror ? "left" : "right");
774 setFocusNavigation(d->up, "up");
780 setFocusNavigation(d->down, "down");
786 setFocusNavigation(d->tab, "tab");
790 case Qt::Key_Backtab:
792 setFocusNavigation(d->backtab, "backtab");
800 if (!event->isAccepted()) QQuickItemKeyFilter::keyPressed(event, post);
803 void QQuickKeyNavigationAttached::keyReleased(QKeyEvent *event, bool post)
805 Q_D(QQuickKeyNavigationAttached);
808 if (post != m_processPost) {
809 QQuickItemKeyFilter::keyReleased(event, post);
814 switch (event->key()) {
816 if (QQuickItem *parentItem = qobject_cast<QQuickItem*>(parent()))
817 mirror = QQuickItemPrivate::get(parentItem)->effectiveLayoutMirror;
818 if (mirror ? d->right : d->left)
822 if (QQuickItem *parentItem = qobject_cast<QQuickItem*>(parent()))
823 mirror = QQuickItemPrivate::get(parentItem)->effectiveLayoutMirror;
824 if (mirror ? d->left : d->right)
842 case Qt::Key_Backtab:
851 if (!event->isAccepted()) QQuickItemKeyFilter::keyReleased(event, post);
854 void QQuickKeyNavigationAttached::setFocusNavigation(QQuickItem *currentItem, const char *dir)
856 QQuickItem *initialItem = currentItem;
857 bool isNextItem = false;
860 if (currentItem->isVisible() && currentItem->isEnabled()) {
861 currentItem->setFocus(true);
864 qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(currentItem, false);
866 QQuickItem *tempItem = qvariant_cast<QQuickItem*>(attached->property(dir));
868 currentItem = tempItem;
874 while (currentItem != initialItem && isNextItem);
877 const QQuickKeysAttached::SigMap QQuickKeysAttached::sigMap[] = {
878 { Qt::Key_Left, "leftPressed" },
879 { Qt::Key_Right, "rightPressed" },
880 { Qt::Key_Up, "upPressed" },
881 { Qt::Key_Down, "downPressed" },
882 { Qt::Key_Tab, "tabPressed" },
883 { Qt::Key_Backtab, "backtabPressed" },
884 { Qt::Key_Asterisk, "asteriskPressed" },
885 { Qt::Key_NumberSign, "numberSignPressed" },
886 { Qt::Key_Escape, "escapePressed" },
887 { Qt::Key_Return, "returnPressed" },
888 { Qt::Key_Enter, "enterPressed" },
889 { Qt::Key_Delete, "deletePressed" },
890 { Qt::Key_Space, "spacePressed" },
891 { Qt::Key_Back, "backPressed" },
892 { Qt::Key_Cancel, "cancelPressed" },
893 { Qt::Key_Select, "selectPressed" },
894 { Qt::Key_Yes, "yesPressed" },
895 { Qt::Key_No, "noPressed" },
896 { Qt::Key_Context1, "context1Pressed" },
897 { Qt::Key_Context2, "context2Pressed" },
898 { Qt::Key_Context3, "context3Pressed" },
899 { Qt::Key_Context4, "context4Pressed" },
900 { Qt::Key_Call, "callPressed" },
901 { Qt::Key_Hangup, "hangupPressed" },
902 { Qt::Key_Flip, "flipPressed" },
903 { Qt::Key_Menu, "menuPressed" },
904 { Qt::Key_VolumeUp, "volumeUpPressed" },
905 { Qt::Key_VolumeDown, "volumeDownPressed" },
909 bool QQuickKeysAttachedPrivate::isConnected(const char *signalName)
911 return isSignalConnected(signalIndex(signalName));
915 \qmlclass Keys QQuickKeysAttached
916 \inqmlmodule QtQuick 2
917 \ingroup qml-basic-interaction-elements
918 \brief The Keys attached property provides key handling to Items.
920 All visual primitives support key handling via the Keys
921 attached property. Keys can be handled via the onPressed
922 and onReleased signal properties.
924 The signal properties have a \l KeyEvent parameter, named
925 \e event which contains details of the event. If a key is
926 handled \e event.accepted should be set to true to prevent the
927 event from propagating up the item hierarchy.
929 \section1 Example Usage
931 The following example shows how the general onPressed handler can
932 be used to test for a certain key; in this case, the left cursor
935 \snippet doc/src/snippets/qml/keys/keys-pressed.qml key item
937 Some keys may alternatively be handled via specific signal properties,
938 for example \e onSelectPressed. These handlers automatically set
939 \e event.accepted to true.
941 \snippet doc/src/snippets/qml/keys/keys-handler.qml key item
943 See \l{Qt::Key}{Qt.Key} for the list of keyboard codes.
945 \section1 Key Handling Priorities
947 The Keys attached property can be configured to handle key events
948 before or after the item it is attached to. This makes it possible
949 to intercept events in order to override an item's default behavior,
950 or act as a fallback for keys not handled by the item.
952 If \l priority is Keys.BeforeItem (default) the order of key event processing is:
955 \li Items specified in \c forwardTo
956 \li specific key handlers, e.g. onReturnPressed
957 \li onKeyPress, onKeyRelease handlers
958 \li Item specific key handling, e.g. TextInput key handling
962 If priority is Keys.AfterItem the order of key event processing is:
965 \li Item specific key handling, e.g. TextInput key handling
966 \li Items specified in \c forwardTo
967 \li specific key handlers, e.g. onReturnPressed
968 \li onKeyPress, onKeyRelease handlers
972 If the event is accepted during any of the above steps, key
975 \sa KeyEvent, {KeyNavigation}{KeyNavigation attached property}
979 \qmlproperty bool QtQuick2::Keys::enabled
981 This flags enables key handling if true (default); otherwise
982 no key handlers will be called.
986 \qmlproperty enumeration QtQuick2::Keys::priority
988 This property determines whether the keys are processed before
989 or after the attached item's own key handling.
992 \li Keys.BeforeItem (default) - process the key events before normal
993 item key processing. If the event is accepted it will not
994 be passed on to the item.
995 \li Keys.AfterItem - process the key events after normal item key
996 handling. If the item accepts the key event it will not be
997 handled by the Keys attached property handler.
1002 \qmlproperty list<Object> QtQuick2::Keys::forwardTo
1004 This property provides a way to forward key presses, key releases, and keyboard input
1005 coming from input methods to other items. This can be useful when you want
1006 one item to handle some keys (e.g. the up and down arrow keys), and another item to
1007 handle other keys (e.g. the left and right arrow keys). Once an item that has been
1008 forwarded keys accepts the event it is no longer forwarded to items later in the
1011 This example forwards key events to two lists:
1022 Keys.forwardTo: [list1, list2]
1029 \qmlsignal QtQuick2::Keys::onPressed(KeyEvent event)
1031 This handler is called when a key has been pressed. The \a event
1032 parameter provides information about the event.
1036 \qmlsignal QtQuick2::Keys::onReleased(KeyEvent event)
1038 This handler is called when a key has been released. The \a event
1039 parameter provides information about the event.
1043 \qmlsignal QtQuick2::Keys::onDigit0Pressed(KeyEvent event)
1045 This handler is called when the digit '0' has been pressed. The \a event
1046 parameter provides information about the event.
1050 \qmlsignal QtQuick2::Keys::onDigit1Pressed(KeyEvent event)
1052 This handler is called when the digit '1' has been pressed. The \a event
1053 parameter provides information about the event.
1057 \qmlsignal QtQuick2::Keys::onDigit2Pressed(KeyEvent event)
1059 This handler is called when the digit '2' has been pressed. The \a event
1060 parameter provides information about the event.
1064 \qmlsignal QtQuick2::Keys::onDigit3Pressed(KeyEvent event)
1066 This handler is called when the digit '3' has been pressed. The \a event
1067 parameter provides information about the event.
1071 \qmlsignal QtQuick2::Keys::onDigit4Pressed(KeyEvent event)
1073 This handler is called when the digit '4' has been pressed. The \a event
1074 parameter provides information about the event.
1078 \qmlsignal QtQuick2::Keys::onDigit5Pressed(KeyEvent event)
1080 This handler is called when the digit '5' has been pressed. The \a event
1081 parameter provides information about the event.
1085 \qmlsignal QtQuick2::Keys::onDigit6Pressed(KeyEvent event)
1087 This handler is called when the digit '6' has been pressed. The \a event
1088 parameter provides information about the event.
1092 \qmlsignal QtQuick2::Keys::onDigit7Pressed(KeyEvent event)
1094 This handler is called when the digit '7' has been pressed. The \a event
1095 parameter provides information about the event.
1099 \qmlsignal QtQuick2::Keys::onDigit8Pressed(KeyEvent event)
1101 This handler is called when the digit '8' has been pressed. The \a event
1102 parameter provides information about the event.
1106 \qmlsignal QtQuick2::Keys::onDigit9Pressed(KeyEvent event)
1108 This handler is called when the digit '9' has been pressed. The \a event
1109 parameter provides information about the event.
1113 \qmlsignal QtQuick2::Keys::onLeftPressed(KeyEvent event)
1115 This handler is called when the Left arrow has been pressed. The \a event
1116 parameter provides information about the event.
1120 \qmlsignal QtQuick2::Keys::onRightPressed(KeyEvent event)
1122 This handler is called when the Right arrow has been pressed. The \a event
1123 parameter provides information about the event.
1127 \qmlsignal QtQuick2::Keys::onUpPressed(KeyEvent event)
1129 This handler is called when the Up arrow has been pressed. The \a event
1130 parameter provides information about the event.
1134 \qmlsignal QtQuick2::Keys::onDownPressed(KeyEvent event)
1136 This handler is called when the Down arrow has been pressed. The \a event
1137 parameter provides information about the event.
1141 \qmlsignal QtQuick2::Keys::onTabPressed(KeyEvent event)
1143 This handler is called when the Tab key has been pressed. The \a event
1144 parameter provides information about the event.
1148 \qmlsignal QtQuick2::Keys::onBacktabPressed(KeyEvent event)
1150 This handler is called when the Shift+Tab key combination (Backtab) has
1151 been pressed. The \a event parameter provides information about the event.
1155 \qmlsignal QtQuick2::Keys::onAsteriskPressed(KeyEvent event)
1157 This handler is called when the Asterisk '*' has been pressed. The \a event
1158 parameter provides information about the event.
1162 \qmlsignal QtQuick2::Keys::onEscapePressed(KeyEvent event)
1164 This handler is called when the Escape key has been pressed. The \a event
1165 parameter provides information about the event.
1169 \qmlsignal QtQuick2::Keys::onReturnPressed(KeyEvent event)
1171 This handler is called when the Return key has been pressed. The \a event
1172 parameter provides information about the event.
1176 \qmlsignal QtQuick2::Keys::onEnterPressed(KeyEvent event)
1178 This handler is called when the Enter key has been pressed. The \a event
1179 parameter provides information about the event.
1183 \qmlsignal QtQuick2::Keys::onDeletePressed(KeyEvent event)
1185 This handler is called when the Delete key has been pressed. The \a event
1186 parameter provides information about the event.
1190 \qmlsignal QtQuick2::Keys::onSpacePressed(KeyEvent event)
1192 This handler is called when the Space key has been pressed. The \a event
1193 parameter provides information about the event.
1197 \qmlsignal QtQuick2::Keys::onBackPressed(KeyEvent event)
1199 This handler is called when the Back key has been pressed. The \a event
1200 parameter provides information about the event.
1204 \qmlsignal QtQuick2::Keys::onCancelPressed(KeyEvent event)
1206 This handler is called when the Cancel key has been pressed. The \a event
1207 parameter provides information about the event.
1211 \qmlsignal QtQuick2::Keys::onSelectPressed(KeyEvent event)
1213 This handler is called when the Select key has been pressed. The \a event
1214 parameter provides information about the event.
1218 \qmlsignal QtQuick2::Keys::onYesPressed(KeyEvent event)
1220 This handler is called when the Yes key has been pressed. The \a event
1221 parameter provides information about the event.
1225 \qmlsignal QtQuick2::Keys::onNoPressed(KeyEvent event)
1227 This handler is called when the No key has been pressed. The \a event
1228 parameter provides information about the event.
1232 \qmlsignal QtQuick2::Keys::onContext1Pressed(KeyEvent event)
1234 This handler is called when the Context1 key has been pressed. The \a event
1235 parameter provides information about the event.
1239 \qmlsignal QtQuick2::Keys::onContext2Pressed(KeyEvent event)
1241 This handler is called when the Context2 key has been pressed. The \a event
1242 parameter provides information about the event.
1246 \qmlsignal QtQuick2::Keys::onContext3Pressed(KeyEvent event)
1248 This handler is called when the Context3 key has been pressed. The \a event
1249 parameter provides information about the event.
1253 \qmlsignal QtQuick2::Keys::onContext4Pressed(KeyEvent event)
1255 This handler is called when the Context4 key has been pressed. The \a event
1256 parameter provides information about the event.
1260 \qmlsignal QtQuick2::Keys::onCallPressed(KeyEvent event)
1262 This handler is called when the Call key has been pressed. The \a event
1263 parameter provides information about the event.
1267 \qmlsignal QtQuick2::Keys::onHangupPressed(KeyEvent event)
1269 This handler is called when the Hangup key has been pressed. The \a event
1270 parameter provides information about the event.
1274 \qmlsignal QtQuick2::Keys::onFlipPressed(KeyEvent event)
1276 This handler is called when the Flip key has been pressed. The \a event
1277 parameter provides information about the event.
1281 \qmlsignal QtQuick2::Keys::onMenuPressed(KeyEvent event)
1283 This handler is called when the Menu key has been pressed. The \a event
1284 parameter provides information about the event.
1288 \qmlsignal QtQuick2::Keys::onVolumeUpPressed(KeyEvent event)
1290 This handler is called when the VolumeUp key has been pressed. The \a event
1291 parameter provides information about the event.
1295 \qmlsignal QtQuick2::Keys::onVolumeDownPressed(KeyEvent event)
1297 This handler is called when the VolumeDown key has been pressed. The \a event
1298 parameter provides information about the event.
1301 QQuickKeysAttached::QQuickKeysAttached(QObject *parent)
1302 : QObject(*(new QQuickKeysAttachedPrivate), parent),
1303 QQuickItemKeyFilter(qobject_cast<QQuickItem*>(parent))
1305 Q_D(QQuickKeysAttached);
1306 m_processPost = false;
1307 d->item = qobject_cast<QQuickItem*>(parent);
1310 QQuickKeysAttached::~QQuickKeysAttached()
1314 QQuickKeysAttached::Priority QQuickKeysAttached::priority() const
1316 return m_processPost ? AfterItem : BeforeItem;
1319 void QQuickKeysAttached::setPriority(Priority order)
1321 bool processPost = order == AfterItem;
1322 if (processPost != m_processPost) {
1323 m_processPost = processPost;
1324 emit priorityChanged();
1328 void QQuickKeysAttached::componentComplete()
1330 Q_D(QQuickKeysAttached);
1332 for (int ii = 0; ii < d->targets.count(); ++ii) {
1333 QQuickItem *targetItem = d->targets.at(ii);
1334 if (targetItem && (targetItem->flags() & QQuickItem::ItemAcceptsInputMethod)) {
1335 d->item->setFlag(QQuickItem::ItemAcceptsInputMethod);
1342 void QQuickKeysAttached::keyPressed(QKeyEvent *event, bool post)
1344 Q_D(QQuickKeysAttached);
1345 if (post != m_processPost || !d->enabled || d->inPress) {
1347 QQuickItemKeyFilter::keyPressed(event, post);
1351 // first process forwards
1352 if (d->item && d->item->canvas()) {
1354 for (int ii = 0; ii < d->targets.count(); ++ii) {
1355 QQuickItem *i = d->targets.at(ii);
1356 if (i && i->isVisible()) {
1357 d->item->canvas()->sendEvent(i, event);
1358 if (event->isAccepted()) {
1367 QQuickKeyEvent ke(*event);
1368 QByteArray keySignal = keyToSignal(event->key());
1369 if (!keySignal.isEmpty()) {
1370 keySignal += "(QQuickKeyEvent*)";
1371 if (d->isConnected(keySignal)) {
1372 // If we specifically handle a key then default to accepted
1373 ke.setAccepted(true);
1374 int idx = QQuickKeysAttached::staticMetaObject.indexOfSignal(keySignal);
1375 metaObject()->method(idx).invoke(this, Qt::DirectConnection, Q_ARG(QQuickKeyEvent*, &ke));
1378 if (!ke.isAccepted())
1380 event->setAccepted(ke.isAccepted());
1382 if (!event->isAccepted()) QQuickItemKeyFilter::keyPressed(event, post);
1385 void QQuickKeysAttached::keyReleased(QKeyEvent *event, bool post)
1387 Q_D(QQuickKeysAttached);
1388 if (post != m_processPost || !d->enabled || d->inRelease) {
1390 QQuickItemKeyFilter::keyReleased(event, post);
1394 if (d->item && d->item->canvas()) {
1395 d->inRelease = true;
1396 for (int ii = 0; ii < d->targets.count(); ++ii) {
1397 QQuickItem *i = d->targets.at(ii);
1398 if (i && i->isVisible()) {
1399 d->item->canvas()->sendEvent(i, event);
1400 if (event->isAccepted()) {
1401 d->inRelease = false;
1406 d->inRelease = false;
1409 QQuickKeyEvent ke(*event);
1411 event->setAccepted(ke.isAccepted());
1413 if (!event->isAccepted()) QQuickItemKeyFilter::keyReleased(event, post);
1416 void QQuickKeysAttached::inputMethodEvent(QInputMethodEvent *event, bool post)
1418 Q_D(QQuickKeysAttached);
1419 if (post == m_processPost && d->item && !d->inIM && d->item->canvas()) {
1421 for (int ii = 0; ii < d->targets.count(); ++ii) {
1422 QQuickItem *i = d->targets.at(ii);
1423 if (i && i->isVisible() && (i->flags() & QQuickItem::ItemAcceptsInputMethod)) {
1424 d->item->canvas()->sendEvent(i, event);
1425 if (event->isAccepted()) {
1434 QQuickItemKeyFilter::inputMethodEvent(event, post);
1437 QVariant QQuickKeysAttached::inputMethodQuery(Qt::InputMethodQuery query) const
1439 Q_D(const QQuickKeysAttached);
1441 for (int ii = 0; ii < d->targets.count(); ++ii) {
1442 QQuickItem *i = d->targets.at(ii);
1443 if (i && i->isVisible() && (i->flags() & QQuickItem::ItemAcceptsInputMethod) && i == d->imeItem) {
1444 //### how robust is i == d->imeItem check?
1445 QVariant v = i->inputMethodQuery(query);
1446 if (v.userType() == QVariant::RectF)
1447 v = d->item->mapRectFromItem(i, v.toRectF()); //### cost?
1452 return QQuickItemKeyFilter::inputMethodQuery(query);
1455 QQuickKeysAttached *QQuickKeysAttached::qmlAttachedProperties(QObject *obj)
1457 return new QQuickKeysAttached(obj);
1461 \qmlclass LayoutMirroring QQuickLayoutMirroringAttached
1462 \inqmlmodule QtQuick 2
1463 \ingroup qml-utility-elements
1464 \brief The LayoutMirroring attached property is used to mirror layout behavior.
1466 The LayoutMirroring attached property is used to horizontally mirror \l {anchor-layout}{Item anchors},
1467 \l{Using QML Positioner and Repeater Items}{positioner} elements (such as \l Row and \l Grid)
1468 and views (such as \l GridView and horizontal \l ListView). Mirroring is a visual change: left
1469 anchors become right anchors, and positioner elements like \l Grid and \l Row reverse the
1470 horizontal layout of child items.
1472 Mirroring is enabled for an item by setting the \l enabled property to true. By default, this
1473 only affects the item itself; setting the \l childrenInherit property to true propagates the mirroring
1474 behavior to all child elements as well. If the \c LayoutMirroring attached property has not been defined
1475 for an item, mirroring is not enabled.
1477 The following example shows mirroring in action. The \l Row below is specified as being anchored
1478 to the left of its parent. However, since mirroring has been enabled, the anchor is horizontally
1479 reversed and it is now anchored to the right. Also, since items in a \l Row are positioned
1480 from left to right by default, they are now positioned from right to left instead, as demonstrated
1481 by the numbering and opacity of the items:
1483 \snippet doc/src/snippets/qml/layoutmirroring.qml 0
1485 \image layoutmirroring.png
1487 Layout mirroring is useful when it is necessary to support both left-to-right and right-to-left
1488 layout versions of an application to target different language areas. The \l childrenInherit
1489 property allows layout mirroring to be applied without manually setting layout configurations
1490 for every item in an application. Keep in mind, however, that mirroring does not affect any
1491 positioning that is defined by the \l Item \l {Item::}{x} coordinate value, so even with
1492 mirroring enabled, it will often be necessary to apply some layout fixes to support the
1493 desired layout direction. Also, it may be necessary to disable the mirroring of individual
1494 child items (by setting \l {enabled}{LayoutMirroring.enabled} to false for such items) if
1495 mirroring is not the desired behavior, or if the child item already implements mirroring in
1498 See \l {QML Right-to-left User Interfaces} for further details on using \c LayoutMirroring and
1499 other related features to implement right-to-left support for an application.
1503 \qmlproperty bool QtQuick2::LayoutMirroring::enabled
1505 This property holds whether the item's layout is mirrored horizontally. Setting this to true
1506 horizontally reverses \l {anchor-layout}{anchor} settings such that left anchors become right,
1507 and right anchors become left. For \l{Using QML Positioner and Repeater Items}{positioner} elements
1508 (such as \l Row and \l Grid) and view elements (such as \l {GridView}{GridView} and \l {ListView}{ListView})
1509 this also mirrors the horizontal layout direction of the item.
1511 The default value is false.
1515 \qmlproperty bool QtQuick2::LayoutMirroring::childrenInherit
1517 This property holds whether the \l {enabled}{LayoutMirroring.enabled} value for this item
1518 is inherited by its children.
1520 The default value is false.
1524 QQuickLayoutMirroringAttached::QQuickLayoutMirroringAttached(QObject *parent) : QObject(parent), itemPrivate(0)
1526 if (QQuickItem *item = qobject_cast<QQuickItem*>(parent)) {
1527 itemPrivate = QQuickItemPrivate::get(item);
1528 itemPrivate->extra.value().layoutDirectionAttached = this;
1530 qmlInfo(parent) << tr("LayoutDirection attached property only works with Items");
1533 QQuickLayoutMirroringAttached * QQuickLayoutMirroringAttached::qmlAttachedProperties(QObject *object)
1535 return new QQuickLayoutMirroringAttached(object);
1538 bool QQuickLayoutMirroringAttached::enabled() const
1540 return itemPrivate ? itemPrivate->effectiveLayoutMirror : false;
1543 void QQuickLayoutMirroringAttached::setEnabled(bool enabled)
1548 itemPrivate->isMirrorImplicit = false;
1549 if (enabled != itemPrivate->effectiveLayoutMirror) {
1550 itemPrivate->setLayoutMirror(enabled);
1551 if (itemPrivate->inheritMirrorFromItem)
1552 itemPrivate->resolveLayoutMirror();
1556 void QQuickLayoutMirroringAttached::resetEnabled()
1558 if (itemPrivate && !itemPrivate->isMirrorImplicit) {
1559 itemPrivate->isMirrorImplicit = true;
1560 itemPrivate->resolveLayoutMirror();
1564 bool QQuickLayoutMirroringAttached::childrenInherit() const
1566 return itemPrivate ? itemPrivate->inheritMirrorFromItem : false;
1569 void QQuickLayoutMirroringAttached::setChildrenInherit(bool childrenInherit) {
1570 if (itemPrivate && childrenInherit != itemPrivate->inheritMirrorFromItem) {
1571 itemPrivate->inheritMirrorFromItem = childrenInherit;
1572 itemPrivate->resolveLayoutMirror();
1573 childrenInheritChanged();
1577 void QQuickItemPrivate::resolveLayoutMirror()
1580 if (QQuickItem *parentItem = q->parentItem()) {
1581 QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(parentItem);
1582 setImplicitLayoutMirror(parentPrivate->inheritedLayoutMirror, parentPrivate->inheritMirrorFromParent);
1584 setImplicitLayoutMirror(isMirrorImplicit ? false : effectiveLayoutMirror, inheritMirrorFromItem);
1588 void QQuickItemPrivate::setImplicitLayoutMirror(bool mirror, bool inherit)
1590 inherit = inherit || inheritMirrorFromItem;
1591 if (!isMirrorImplicit && inheritMirrorFromItem)
1592 mirror = effectiveLayoutMirror;
1593 if (mirror == inheritedLayoutMirror && inherit == inheritMirrorFromParent)
1596 inheritMirrorFromParent = inherit;
1597 inheritedLayoutMirror = inheritMirrorFromParent ? mirror : false;
1599 if (isMirrorImplicit)
1600 setLayoutMirror(inherit ? inheritedLayoutMirror : false);
1601 for (int i = 0; i < childItems.count(); ++i) {
1602 if (QQuickItem *child = qobject_cast<QQuickItem *>(childItems.at(i))) {
1603 QQuickItemPrivate *childPrivate = QQuickItemPrivate::get(child);
1604 childPrivate->setImplicitLayoutMirror(inheritedLayoutMirror, inheritMirrorFromParent);
1609 void QQuickItemPrivate::setLayoutMirror(bool mirror)
1611 if (mirror != effectiveLayoutMirror) {
1612 effectiveLayoutMirror = mirror;
1614 QQuickAnchorsPrivate *anchor_d = QQuickAnchorsPrivate::get(_anchors);
1615 anchor_d->fillChanged();
1616 anchor_d->centerInChanged();
1617 anchor_d->updateHorizontalAnchors();
1618 emit _anchors->mirroredChanged();
1621 if (extra.isAllocated() && extra->layoutDirectionAttached) {
1622 emit extra->layoutDirectionAttached->enabledChanged();
1627 void QQuickItemPrivate::setAccessibleFlagAndListener()
1630 QQuickItem *item = q;
1632 if (item->d_func()->isAccessible)
1633 break; // already set - grandparents should have the flag set as well.
1635 if (item->canvas() && item->canvas()->rootItem() == item)
1636 break; // don't add a listener to the canvas root item
1638 item->d_func()->isAccessible = true;
1639 item = item->d_func()->parentItem;
1643 void QQuickItemPrivate::updateSubFocusItem(QQuickItem *scope, bool focus)
1648 QQuickItemPrivate *scopePrivate = QQuickItemPrivate::get(scope);
1650 QQuickItem *oldSubFocusItem = scopePrivate->subFocusItem;
1651 // Correct focus chain in scope
1652 if (oldSubFocusItem) {
1653 QQuickItem *sfi = scopePrivate->subFocusItem->parentItem();
1654 while (sfi && sfi != scope) {
1655 QQuickItemPrivate::get(sfi)->subFocusItem = 0;
1656 sfi = sfi->parentItem();
1661 scopePrivate->subFocusItem = q;
1662 QQuickItem *sfi = scopePrivate->subFocusItem->parentItem();
1663 while (sfi && sfi != scope) {
1664 QQuickItemPrivate::get(sfi)->subFocusItem = q;
1665 sfi = sfi->parentItem();
1668 scopePrivate->subFocusItem = 0;
1675 \brief The QQuickItem class provides the most basic of all visual items in QML.
1679 All visual items in Qt Quick inherit from QQuickItem. Although QQuickItem
1680 has no visual appearance, it defines all the properties that are
1681 common across visual items - such as the x and y position, the
1682 width and height, \l {anchor-layout}{anchoring} and key handling.
1684 You can subclass QQuickItem to provide your own custom visual item that inherits
1685 these features. Note that, because it does not draw anything, QQuickItem sets the
1686 QGraphicsItem::ItemHasNoContents flag. If you subclass QQuickItem to create a visual
1687 item, you will need to unset this flag.
1692 \qmlclass Item QQuickItem
1694 \inqmlmodule QtQuick 2
1695 \ingroup qml-basic-visual-elements
1696 \brief The Item is the most basic of all visual items in QML.
1698 All visual items in Qt Quick inherit from Item. Although Item
1699 has no visual appearance, it defines all the properties that are
1700 common across visual items - such as the x and y position, the
1701 width and height, \l {anchor-layout}{anchoring} and key handling.
1703 Item is also useful for grouping items together.
1720 fillMode: Image.Tile
1727 \section1 Key Handling
1729 Key handling is available to all Item-based visual elements via the \l {Keys}{Keys}
1730 attached property. The \e Keys attached property provides basic handlers such
1731 as \l {Keys::onPressed}{onPressed} and \l {Keys::onReleased}{onReleased},
1732 as well as handlers for specific keys, such as
1733 \l {Keys::onCancelPressed}{onCancelPressed}. The example below
1734 assigns \l {qmlfocus}{focus} to the item and handles
1735 the Left key via the general \e onPressed handler and the Select key via the
1736 onSelectPressed handler:
1742 if (event.key == Qt.Key_Left) {
1743 console.log("move left");
1744 event.accepted = true;
1747 Keys.onSelectPressed: console.log("Selected");
1751 See the \l {Keys}{Keys} attached property for detailed documentation.
1753 \section1 Layout Mirroring
1755 Item layouts can be mirrored using the \l {LayoutMirroring}{LayoutMirroring} attached property.
1760 \fn void QQuickItem::childrenRectChanged(const QRectF &)
1765 \fn void QQuickItem::baselineOffsetChanged(qreal)
1770 \fn void QQuickItem::stateChanged(const QString &state)
1775 \fn void QQuickItem::parentChanged(QQuickItem *)
1780 \fn void QQuickItem::smoothChanged(bool)
1785 \fn void QQuickItem::clipChanged(bool)
1789 /*! \fn void QQuickItem::transformOriginChanged(TransformOrigin)
1794 \fn void QQuickItem::focusChanged(bool)
1799 \fn void QQuickItem::activeFocusChanged(bool)
1803 \fn QQuickItem::QQuickItem(QQuickItem *parent)
1805 Constructs a QQuickItem with the given \a parent.
1807 QQuickItem::QQuickItem(QQuickItem* parent)
1808 : QObject(*(new QQuickItemPrivate), parent)
1816 QQuickItem::QQuickItem(QQuickItemPrivate &dd, QQuickItem *parent)
1817 : QObject(dd, parent)
1824 static int qt_item_count = 0;
1826 static void qt_print_item_count()
1828 qDebug("Number of leaked items: %i", qt_item_count);
1834 Destroys the QQuickItem.
1836 QQuickItem::~QQuickItem()
1840 if (qt_item_count < 0)
1841 qDebug("Item destroyed after qt_print_item_count() was called.");
1846 if (d->canvasRefCount > 1)
1847 d->canvasRefCount = 1; // Make sure canvas is set to null in next call to derefCanvas().
1853 // XXX todo - optimize
1854 while (!d->childItems.isEmpty())
1855 d->childItems.first()->setParentItem(0);
1857 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
1858 QQuickAnchorsPrivate *anchor = d->changeListeners.at(ii).listener->anchorPrivate();
1860 anchor->clearItem(this);
1864 update item anchors that depended on us unless they are our child (and will also be destroyed),
1865 or our sibling, and our parent is also being destroyed.
1867 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
1868 QQuickAnchorsPrivate *anchor = d->changeListeners.at(ii).listener->anchorPrivate();
1869 if (anchor && anchor->item && anchor->item->parentItem() && anchor->item->parentItem() != this)
1873 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
1874 const QQuickItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
1875 if (change.types & QQuickItemPrivate::Destroyed)
1876 change.listener->itemDestroyed(this);
1879 d->changeListeners.clear();
1881 if (d->extra.isAllocated()) {
1882 delete d->extra->contents; d->extra->contents = 0;
1883 delete d->extra->layer; d->extra->layer = 0;
1886 delete d->_anchors; d->_anchors = 0;
1887 delete d->_stateGroup; d->_stateGroup = 0;
1891 \qmlproperty enumeration QtQuick2::Item::transformOrigin
1892 This property holds the origin point around which scale and rotation transform.
1894 Nine transform origins are available, as shown in the image below.
1896 \image declarative-transformorigin.png
1898 This example rotates an image around its bottom-right corner.
1901 source: "myimage.png"
1902 transformOrigin: Item.BottomRight
1907 The default transform origin is \c Item.Center.
1909 To set an arbitrary transform origin point use the \l Scale or \l Rotation
1914 \qmlproperty Item QtQuick2::Item::parent
1915 This property holds the parent of the item.
1919 \property QQuickItem::parent
1920 This property holds the parent of the item.
1922 void QQuickItem::setParentItem(QQuickItem *parentItem)
1925 if (parentItem == d->parentItem)
1929 QQuickItem *itemAncestor = parentItem->parentItem();
1930 while (itemAncestor != 0) {
1931 if (itemAncestor == this) {
1932 qWarning("QQuickItem::setParentItem: Parent is already part of this items subtree.");
1935 itemAncestor = itemAncestor->parentItem();
1939 d->removeFromDirtyList();
1941 QQuickItem *oldParentItem = d->parentItem;
1942 QQuickItem *scopeFocusedItem = 0;
1944 if (oldParentItem) {
1945 QQuickItemPrivate *op = QQuickItemPrivate::get(oldParentItem);
1947 QQuickItem *scopeItem = 0;
1950 scopeFocusedItem = this;
1951 else if (!isFocusScope() && d->subFocusItem)
1952 scopeFocusedItem = d->subFocusItem;
1954 if (scopeFocusedItem) {
1955 scopeItem = oldParentItem;
1956 while (!scopeItem->isFocusScope() && scopeItem->parentItem())
1957 scopeItem = scopeItem->parentItem();
1959 QQuickCanvasPrivate::get(d->canvas)->clearFocusInScope(scopeItem, scopeFocusedItem,
1960 QQuickCanvasPrivate::DontChangeFocusProperty);
1962 QQuickItemPrivate::get(scopeFocusedItem)->updateSubFocusItem(scopeItem, false);
1966 const bool wasVisible = isVisible();
1967 op->removeChild(this);
1969 emit oldParentItem->visibleChildrenChanged();
1971 } else if (d->canvas) {
1972 QQuickCanvasPrivate::get(d->canvas)->parentlessItems.remove(this);
1975 QQuickCanvas *oldParentCanvas = oldParentItem ? QQuickItemPrivate::get(oldParentItem)->canvas : 0;
1976 QQuickCanvas *parentCanvas = parentItem ? QQuickItemPrivate::get(parentItem)->canvas : 0;
1977 if (oldParentCanvas == parentCanvas) {
1978 // Avoid freeing and reallocating resources if the canvas stays the same.
1979 d->parentItem = parentItem;
1981 if (oldParentCanvas)
1983 d->parentItem = parentItem;
1985 d->refCanvas(parentCanvas);
1988 d->dirty(QQuickItemPrivate::ParentChanged);
1991 QQuickItemPrivate::get(d->parentItem)->addChild(this);
1993 QQuickCanvasPrivate::get(d->canvas)->parentlessItems.insert(this);
1995 d->setEffectiveVisibleRecur(d->calcEffectiveVisible());
1996 d->setEffectiveEnableRecur(0, d->calcEffectiveEnable());
1998 if (d->parentItem) {
1999 if (!scopeFocusedItem) {
2001 scopeFocusedItem = this;
2002 else if (!isFocusScope() && d->subFocusItem)
2003 scopeFocusedItem = d->subFocusItem;
2006 if (scopeFocusedItem) {
2007 // We need to test whether this item becomes scope focused
2008 QQuickItem *scopeItem = d->parentItem;
2009 while (!scopeItem->isFocusScope() && scopeItem->parentItem())
2010 scopeItem = scopeItem->parentItem();
2012 if (QQuickItemPrivate::get(scopeItem)->subFocusItem
2013 || (!scopeItem->isFocusScope() && scopeItem->hasFocus())) {
2014 if (scopeFocusedItem != this)
2015 QQuickItemPrivate::get(scopeFocusedItem)->updateSubFocusItem(this, false);
2016 QQuickItemPrivate::get(scopeFocusedItem)->focus = false;
2017 emit scopeFocusedItem->focusChanged(false);
2020 QQuickCanvasPrivate::get(d->canvas)->setFocusInScope(scopeItem, scopeFocusedItem,
2021 QQuickCanvasPrivate::DontChangeFocusProperty);
2023 QQuickItemPrivate::get(scopeFocusedItem)->updateSubFocusItem(scopeItem, true);
2029 d->resolveLayoutMirror();
2031 d->itemChange(ItemParentHasChanged, d->parentItem);
2033 d->parentNotifier.notify();
2034 if (d->isAccessible && d->parentItem) {
2035 d->parentItem->d_func()->setAccessibleFlagAndListener();
2038 emit parentChanged(d->parentItem);
2039 if (isVisible() && d->parentItem)
2040 emit d->parentItem->visibleChildrenChanged();
2043 void QQuickItem::stackBefore(const QQuickItem *sibling)
2046 if (!sibling || sibling == this || !d->parentItem || d->parentItem != QQuickItemPrivate::get(sibling)->parentItem) {
2047 qWarning("QQuickItem::stackBefore: Cannot stack before %p, which must be a sibling", sibling);
2051 QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(d->parentItem);
2053 int myIndex = parentPrivate->childItems.indexOf(this);
2054 int siblingIndex = parentPrivate->childItems.indexOf(const_cast<QQuickItem *>(sibling));
2056 Q_ASSERT(myIndex != -1 && siblingIndex != -1);
2058 if (myIndex == siblingIndex - 1)
2061 parentPrivate->childItems.removeAt(myIndex);
2063 if (myIndex < siblingIndex) --siblingIndex;
2065 parentPrivate->childItems.insert(siblingIndex, this);
2067 parentPrivate->dirty(QQuickItemPrivate::ChildrenStackingChanged);
2068 parentPrivate->markSortedChildrenDirty(this);
2070 for (int ii = qMin(siblingIndex, myIndex); ii < parentPrivate->childItems.count(); ++ii)
2071 QQuickItemPrivate::get(parentPrivate->childItems.at(ii))->siblingOrderChanged();
2074 void QQuickItem::stackAfter(const QQuickItem *sibling)
2077 if (!sibling || sibling == this || !d->parentItem || d->parentItem != QQuickItemPrivate::get(sibling)->parentItem) {
2078 qWarning("QQuickItem::stackAfter: Cannot stack after %p, which must be a sibling", sibling);
2082 QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(d->parentItem);
2084 int myIndex = parentPrivate->childItems.indexOf(this);
2085 int siblingIndex = parentPrivate->childItems.indexOf(const_cast<QQuickItem *>(sibling));
2087 Q_ASSERT(myIndex != -1 && siblingIndex != -1);
2089 if (myIndex == siblingIndex + 1)
2092 parentPrivate->childItems.removeAt(myIndex);
2094 if (myIndex < siblingIndex) --siblingIndex;
2096 parentPrivate->childItems.insert(siblingIndex + 1, this);
2098 parentPrivate->dirty(QQuickItemPrivate::ChildrenStackingChanged);
2099 parentPrivate->markSortedChildrenDirty(this);
2101 for (int ii = qMin(myIndex, siblingIndex + 1); ii < parentPrivate->childItems.count(); ++ii)
2102 QQuickItemPrivate::get(parentPrivate->childItems.at(ii))->siblingOrderChanged();
2106 Returns the QQuickItem parent of this item.
2108 QQuickItem *QQuickItem::parentItem() const
2110 Q_D(const QQuickItem);
2111 return d->parentItem;
2114 QSGEngine *QQuickItem::sceneGraphEngine() const
2116 return canvas()->sceneGraphEngine();
2119 QQuickCanvas *QQuickItem::canvas() const
2121 Q_D(const QQuickItem);
2125 static bool itemZOrder_sort(QQuickItem *lhs, QQuickItem *rhs)
2127 return lhs->z() < rhs->z();
2130 QList<QQuickItem *> QQuickItemPrivate::paintOrderChildItems() const
2132 if (sortedChildItems)
2133 return *sortedChildItems;
2135 // If none of the items have set Z then the paint order list is the same as
2136 // the childItems list. This is by far the most common case.
2138 for (int i = 0; i < childItems.count(); ++i) {
2139 if (QQuickItemPrivate::get(childItems.at(i))->z() != 0.) {
2145 sortedChildItems = new QList<QQuickItem*>(childItems);
2146 qStableSort(sortedChildItems->begin(), sortedChildItems->end(), itemZOrder_sort);
2147 return *sortedChildItems;
2150 sortedChildItems = const_cast<QList<QQuickItem*>*>(&childItems);
2155 void QQuickItemPrivate::addChild(QQuickItem *child)
2159 Q_ASSERT(!childItems.contains(child));
2161 childItems.append(child);
2163 markSortedChildrenDirty(child);
2164 dirty(QQuickItemPrivate::ChildrenChanged);
2166 itemChange(QQuickItem::ItemChildAddedChange, child);
2168 emit q->childrenChanged();
2171 void QQuickItemPrivate::removeChild(QQuickItem *child)
2176 Q_ASSERT(childItems.contains(child));
2177 childItems.removeOne(child);
2178 Q_ASSERT(!childItems.contains(child));
2180 markSortedChildrenDirty(child);
2181 dirty(QQuickItemPrivate::ChildrenChanged);
2183 itemChange(QQuickItem::ItemChildRemovedChange, child);
2185 emit q->childrenChanged();
2188 void QQuickItemPrivate::InitializationState::clear()
2193 void QQuickItemPrivate::InitializationState::clear(QQuickItem *fs)
2198 QQuickItem *QQuickItemPrivate::InitializationState::getFocusScope(QQuickItem *item)
2201 QQuickItem *fs = item->parentItem();
2202 while (fs->parentItem() && !fs->isFocusScope())
2203 fs = fs->parentItem();
2209 void QQuickItemPrivate::refCanvas(InitializationState *state, QQuickCanvas *c)
2211 // An item needs a canvas if it is referenced by another item which has a canvas.
2212 // Typically the item is referenced by a parent, but can also be referenced by a
2213 // ShaderEffect or ShaderEffectSource. 'canvasRefCount' counts how many items with
2214 // a canvas is referencing this item. When the reference count goes from zero to one,
2215 // or one to zero, the canvas of this item is updated and propagated to the children.
2216 // As long as the reference count stays above zero, the canvas is unchanged.
2217 // refCanvas() increments the reference count.
2218 // derefCanvas() decrements the reference count.
2221 Q_ASSERT((canvas != 0) == (canvasRefCount > 0));
2223 if (++canvasRefCount > 1) {
2225 qWarning("QQuickItem: Cannot use same item on different canvases at the same time.");
2226 return; // Canvas already set.
2229 Q_ASSERT(canvas == 0);
2232 if (polishScheduled)
2233 QQuickCanvasPrivate::get(canvas)->itemsToPolish.insert(q);
2235 InitializationState _dummy;
2236 InitializationState *childState = state;
2238 if (q->isFocusScope()) {
2240 childState = &_dummy;
2244 QQuickCanvasPrivate::get(canvas)->parentlessItems.insert(q);
2246 for (int ii = 0; ii < childItems.count(); ++ii) {
2247 QQuickItem *child = childItems.at(ii);
2248 QQuickItemPrivate::get(child)->refCanvas(childState, c);
2253 if (extra.isAllocated() && extra->screenAttached)
2254 extra->screenAttached->canvasChanged(c);
2255 itemChange(QQuickItem::ItemSceneChange, c);
2258 void QQuickItemPrivate::derefCanvas()
2261 Q_ASSERT((canvas != 0) == (canvasRefCount > 0));
2264 return; // This can happen when destroying recursive shader effect sources.
2266 if (--canvasRefCount > 0)
2267 return; // There are still other references, so don't set canvas to null yet.
2269 q->releaseResources();
2270 removeFromDirtyList();
2271 QQuickCanvasPrivate *c = QQuickCanvasPrivate::get(canvas);
2272 if (polishScheduled)
2273 c->itemsToPolish.remove(q);
2274 if (c->mouseGrabberItem == q)
2275 c->mouseGrabberItem = 0;
2277 c->hoverItems.removeAll(q);
2278 if (itemNodeInstance)
2279 c->cleanup(itemNodeInstance);
2281 c->parentlessItems.remove(q);
2285 itemNodeInstance = 0;
2287 if (extra.isAllocated()) {
2288 extra->opacityNode = 0;
2289 extra->clipNode = 0;
2290 extra->rootNode = 0;
2291 extra->beforePaintNode = 0;
2297 for (int ii = 0; ii < childItems.count(); ++ii) {
2298 QQuickItem *child = childItems.at(ii);
2299 QQuickItemPrivate::get(child)->derefCanvas();
2304 if (extra.isAllocated() && extra->screenAttached)
2305 extra->screenAttached->canvasChanged(0);
2306 itemChange(QQuickItem::ItemSceneChange, (QQuickCanvas *)0);
2311 Returns a transform that maps points from canvas space into item space.
2313 QTransform QQuickItemPrivate::canvasToItemTransform() const
2315 // XXX todo - optimize
2316 return itemToCanvasTransform().inverted();
2320 Returns a transform that maps points from item space into canvas space.
2322 QTransform QQuickItemPrivate::itemToCanvasTransform() const
2325 QTransform rv = parentItem?QQuickItemPrivate::get(parentItem)->itemToCanvasTransform():QTransform();
2326 itemToParentTransform(rv);
2331 Motifies \a t with this items local transform relative to its parent.
2333 void QQuickItemPrivate::itemToParentTransform(QTransform &t) const
2338 if (!transforms.isEmpty()) {
2340 for (int ii = transforms.count() - 1; ii >= 0; --ii)
2341 transforms.at(ii)->applyTo(&m);
2342 t = m.toTransform();
2345 if (scale() != 1. || rotation() != 0.) {
2346 QPointF tp = computeTransformOrigin();
2347 t.translate(tp.x(), tp.y());
2348 t.scale(scale(), scale());
2349 t.rotate(rotation());
2350 t.translate(-tp.x(), -tp.y());
2356 \qmlproperty real QtQuick2::Item::childrenRect.x
2357 \qmlproperty real QtQuick2::Item::childrenRect.y
2358 \qmlproperty real QtQuick2::Item::childrenRect.width
2359 \qmlproperty real QtQuick2::Item::childrenRect.height
2361 The childrenRect properties allow an item access to the geometry of its
2362 children. This property is useful if you have an item that needs to be
2363 sized to fit its children.
2368 \qmlproperty list<Item> QtQuick2::Item::children
2369 \qmlproperty list<Object> QtQuick2::Item::resources
2371 The children property contains the list of visual children of this item.
2372 The resources property contains non-visual resources that you want to
2375 Generally you can rely on Item's default property to handle all this for
2376 you, but it can come in handy in some cases.
2395 Returns true if construction of the QML component is complete; otherwise
2398 It is often desirable to delay some processing until the component is
2401 \sa componentComplete()
2403 bool QQuickItem::isComponentComplete() const
2405 Q_D(const QQuickItem);
2406 return d->componentComplete;
2409 QQuickItemPrivate::QQuickItemPrivate()
2410 : _anchors(0), _stateGroup(0),
2411 flags(0), widthValid(false), heightValid(false), baselineOffsetValid(false), componentComplete(true),
2412 keepMouse(false), keepTouch(false), hoverEnabled(false), smooth(true), focus(false), activeFocus(false), notifiedFocus(false),
2413 notifiedActiveFocus(false), filtersChildMouseEvents(false), explicitVisible(true),
2414 effectiveVisible(true), explicitEnable(true), effectiveEnable(true), polishScheduled(false),
2415 inheritedLayoutMirror(false), effectiveLayoutMirror(false), isMirrorImplicit(true),
2416 inheritMirrorFromParent(false), inheritMirrorFromItem(false), childrenDoNotOverlap(false),
2417 staticSubtreeGeometry(false),
2418 isAccessible(false),
2420 dirtyAttributes(0), nextDirtyItem(0), prevDirtyItem(0),
2422 canvas(0), canvasRefCount(0), parentItem(0), sortedChildItems(&childItems),
2426 x(0), y(0), width(0), height(0), implicitWidth(0), implicitHeight(0),
2430 itemNodeInstance(0), groupNode(0), paintNode(0)
2434 QQuickItemPrivate::~QQuickItemPrivate()
2436 if (sortedChildItems != &childItems)
2437 delete sortedChildItems;
2440 void QQuickItemPrivate::init(QQuickItem *parent)
2444 static bool atexit_registered = false;
2445 if (!atexit_registered) {
2446 atexit(qt_print_item_count);
2447 atexit_registered = true;
2453 registerAccessorProperties();
2455 baselineOffsetValid = false;
2458 q->setParentItem(parent);
2459 QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(parent);
2460 setImplicitLayoutMirror(parentPrivate->inheritedLayoutMirror, parentPrivate->inheritMirrorFromParent);
2464 void QQuickItemPrivate::data_append(QQmlListProperty<QObject> *prop, QObject *o)
2469 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2471 // This test is measurably (albeit only slightly) faster than qobject_cast<>()
2472 const QMetaObject *mo = o->metaObject();
2473 while (mo && mo != &QQuickItem::staticMetaObject) {
2474 mo = mo->d.superdata;
2478 QQuickItem *item = static_cast<QQuickItem *>(o);
2479 item->setParentItem(that);
2481 if (o->inherits("QGraphicsItem"))
2482 qWarning("Cannot add a QtQuick 1.0 item (%s) into a QtQuick 2.0 scene!", o->metaObject()->className());
2484 // XXX todo - do we really want this behavior?
2490 \qmlproperty list<Object> QtQuick2::Item::data
2493 The data property allows you to freely mix visual children and resources
2494 in an item. If you assign a visual item to the data list it becomes
2495 a child and if you assign any other object type, it is added as a resource.
2519 data is a behind-the-scenes property: you should never need to explicitly
2523 int QQuickItemPrivate::data_count(QQmlListProperty<QObject> *prop)
2530 QObject *QQuickItemPrivate::data_at(QQmlListProperty<QObject> *prop, int i)
2538 void QQuickItemPrivate::data_clear(QQmlListProperty<QObject> *prop)
2544 QObject *QQuickItemPrivate::resources_at(QQmlListProperty<QObject> *prop, int index)
2546 const QObjectList children = prop->object->children();
2547 if (index < children.count())
2548 return children.at(index);
2553 void QQuickItemPrivate::resources_append(QQmlListProperty<QObject> *prop, QObject *o)
2555 // XXX todo - do we really want this behavior?
2556 o->setParent(prop->object);
2559 int QQuickItemPrivate::resources_count(QQmlListProperty<QObject> *prop)
2561 return prop->object->children().count();
2564 void QQuickItemPrivate::resources_clear(QQmlListProperty<QObject> *prop)
2566 // XXX todo - do we really want this behavior?
2567 const QObjectList children = prop->object->children();
2568 for (int index = 0; index < children.count(); index++)
2569 children.at(index)->setParent(0);
2572 QQuickItem *QQuickItemPrivate::children_at(QQmlListProperty<QQuickItem> *prop, int index)
2574 QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2575 if (index >= p->childItems.count() || index < 0)
2578 return p->childItems.at(index);
2581 void QQuickItemPrivate::children_append(QQmlListProperty<QQuickItem> *prop, QQuickItem *o)
2586 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2587 if (o->parentItem() == that)
2588 o->setParentItem(0);
2590 o->setParentItem(that);
2593 int QQuickItemPrivate::children_count(QQmlListProperty<QQuickItem> *prop)
2595 QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2596 return p->childItems.count();
2599 void QQuickItemPrivate::children_clear(QQmlListProperty<QQuickItem> *prop)
2601 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2602 QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2603 while (!p->childItems.isEmpty())
2604 p->childItems.at(0)->setParentItem(0);
2607 void QQuickItemPrivate::visibleChildren_append(QQmlListProperty<QQuickItem>*, QQuickItem *self)
2610 qmlInfo(self) << "QQuickItem: visibleChildren property is readonly and cannot be assigned to.";
2613 int QQuickItemPrivate::visibleChildren_count(QQmlListProperty<QQuickItem> *prop)
2615 QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2616 int visibleCount = 0;
2617 int c = p->childItems.count();
2619 if (p->childItems.at(c)->isVisible()) visibleCount++;
2622 return visibleCount;
2625 QQuickItem *QQuickItemPrivate::visibleChildren_at(QQmlListProperty<QQuickItem> *prop, int index)
2627 QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2628 const int childCount = p->childItems.count();
2629 if (index >= childCount || index < 0)
2632 int visibleCount = -1;
2633 for (int i = 0; i < childCount; i++) {
2634 if (p->childItems.at(i)->isVisible()) visibleCount++;
2635 if (visibleCount == index) return p->childItems.at(i);
2640 int QQuickItemPrivate::transform_count(QQmlListProperty<QQuickTransform> *prop)
2642 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2643 QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2645 return p->transforms.count();
2648 void QQuickTransform::appendToItem(QQuickItem *item)
2650 Q_D(QQuickTransform);
2654 QQuickItemPrivate *p = QQuickItemPrivate::get(item);
2656 if (!d->items.isEmpty() && !p->transforms.isEmpty() && p->transforms.contains(this)) {
2657 p->transforms.removeOne(this);
2658 p->transforms.append(this);
2660 p->transforms.append(this);
2661 d->items.append(item);
2664 p->dirty(QQuickItemPrivate::Transform);
2667 void QQuickTransform::prependToItem(QQuickItem *item)
2669 Q_D(QQuickTransform);
2673 QQuickItemPrivate *p = QQuickItemPrivate::get(item);
2675 if (!d->items.isEmpty() && !p->transforms.isEmpty() && p->transforms.contains(this)) {
2676 p->transforms.removeOne(this);
2677 p->transforms.prepend(this);
2679 p->transforms.prepend(this);
2680 d->items.append(item);
2683 p->dirty(QQuickItemPrivate::Transform);
2686 void QQuickItemPrivate::transform_append(QQmlListProperty<QQuickTransform> *prop, QQuickTransform *transform)
2691 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2692 transform->appendToItem(that);
2695 QQuickTransform *QQuickItemPrivate::transform_at(QQmlListProperty<QQuickTransform> *prop, int idx)
2697 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2698 QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2700 if (idx < 0 || idx >= p->transforms.count())
2703 return p->transforms.at(idx);
2706 void QQuickItemPrivate::transform_clear(QQmlListProperty<QQuickTransform> *prop)
2708 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2709 QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2711 for (int ii = 0; ii < p->transforms.count(); ++ii) {
2712 QQuickTransform *t = p->transforms.at(ii);
2713 QQuickTransformPrivate *tp = QQuickTransformPrivate::get(t);
2714 tp->items.removeOne(that);
2717 p->transforms.clear();
2719 p->dirty(QQuickItemPrivate::Transform);
2723 \property QQuickItem::childrenRect
2724 \brief The geometry of an item's children.
2726 This property holds the (collective) position and size of the item's children.
2730 \qmlproperty real QtQuick2::Item::x
2731 \qmlproperty real QtQuick2::Item::y
2732 \qmlproperty real QtQuick2::Item::width
2733 \qmlproperty real QtQuick2::Item::height
2735 Defines the item's position and size relative to its parent.
2738 Item { x: 100; y: 100; width: 100; height: 100 }
2743 \qmlproperty real QtQuick2::Item::z
2745 Sets the stacking order of sibling items. By default the stacking order is 0.
2747 Items with a higher stacking value are drawn on top of siblings with a
2748 lower stacking order. Items with the same stacking value are drawn
2749 bottom up in the order they appear. Items with a negative stacking
2750 value are drawn under their parent's content.
2752 The following example shows the various effects of stacking order.
2756 \li \image declarative-item_stacking1.png
2757 \li Same \c z - later children above earlier children:
2762 width: 100; height: 100
2766 x: 50; y: 50; width: 100; height: 100
2771 \li \image declarative-item_stacking2.png
2772 \li Higher \c z on top:
2778 width: 100; height: 100
2782 x: 50; y: 50; width: 100; height: 100
2787 \li \image declarative-item_stacking3.png
2788 \li Same \c z - children above parents:
2793 width: 100; height: 100
2796 x: 50; y: 50; width: 100; height: 100
2802 \li \image declarative-item_stacking4.png
2803 \li Lower \c z below:
2808 width: 100; height: 100
2812 x: 50; y: 50; width: 100; height: 100
2821 \qmlproperty bool QtQuick2::Item::visible
2823 This property holds whether the item is visible. By default this is true.
2825 Setting this property directly affects the \c visible value of child
2826 items. When set to \c false, the \c visible values of all child items also
2827 become \c false. When set to \c true, the \c visible values of child items
2828 are returned to \c true, unless they have explicitly been set to \c false.
2830 (Because of this flow-on behavior, using the \c visible property may not
2831 have the intended effect if a property binding should only respond to
2832 explicit property changes. In such cases it may be better to use the
2833 \l opacity property instead.)
2835 Setting this property to \c false automatically causes \l focus to be set
2836 to \c false, and this item will longer receive mouse and keyboard events.
2837 (In contrast, setting the \l opacity to 0 does not affect the \l focus
2838 property and the receiving of key events.)
2840 \note This property's value is only affected by changes to this property or
2841 the parent's \c visible property. It does not change, for example, if this
2842 item moves off-screen, or if the \l opacity changes to 0.
2847 \qmlproperty AnchorLine QtQuick2::Item::anchors.top
2848 \qmlproperty AnchorLine QtQuick2::Item::anchors.bottom
2849 \qmlproperty AnchorLine QtQuick2::Item::anchors.left
2850 \qmlproperty AnchorLine QtQuick2::Item::anchors.right
2851 \qmlproperty AnchorLine QtQuick2::Item::anchors.horizontalCenter
2852 \qmlproperty AnchorLine QtQuick2::Item::anchors.verticalCenter
2853 \qmlproperty AnchorLine QtQuick2::Item::anchors.baseline
2855 \qmlproperty Item QtQuick2::Item::anchors.fill
2856 \qmlproperty Item QtQuick2::Item::anchors.centerIn
2858 \qmlproperty real QtQuick2::Item::anchors.margins
2859 \qmlproperty real QtQuick2::Item::anchors.topMargin
2860 \qmlproperty real QtQuick2::Item::anchors.bottomMargin
2861 \qmlproperty real QtQuick2::Item::anchors.leftMargin
2862 \qmlproperty real QtQuick2::Item::anchors.rightMargin
2863 \qmlproperty real QtQuick2::Item::anchors.horizontalCenterOffset
2864 \qmlproperty real QtQuick2::Item::anchors.verticalCenterOffset
2865 \qmlproperty real QtQuick2::Item::anchors.baselineOffset
2867 \qmlproperty bool QtQuick2::Item::anchors.mirrored
2869 Anchors provide a way to position an item by specifying its
2870 relationship with other items.
2872 Margins apply to top, bottom, left, right, and fill anchors.
2873 The \c anchors.margins property can be used to set all of the various margins at once, to the same value.
2874 Note that margins are anchor-specific and are not applied if an item does not
2877 Offsets apply for horizontal center, vertical center, and baseline anchors.
2881 \li \image declarative-anchors_example.png
2882 \li Text anchored to Image, horizontally centered and vertically below, with a margin.
2891 anchors.horizontalCenter: pic.horizontalCenter
2892 anchors.top: pic.bottom
2893 anchors.topMargin: 5
2899 \li \image declarative-anchors_example2.png
2901 Left of Text anchored to right of Image, with a margin. The y
2902 property of both defaults to 0.
2912 anchors.left: pic.right
2913 anchors.leftMargin: 5
2920 \c anchors.fill provides a convenient way for one item to have the
2921 same geometry as another item, and is equivalent to connecting all
2922 four directional anchors.
2924 To clear an anchor value, set it to \c undefined.
2926 \c anchors.mirrored returns true it the layout has been \l {LayoutMirroring}{mirrored}.
2928 \note You can only anchor an item to siblings or a parent.
2930 For more information see \l {anchor-layout}{Anchor Layouts}.
2934 \property QQuickItem::baselineOffset
2935 \brief The position of the item's baseline in local coordinates.
2937 The baseline of a \l Text item is the imaginary line on which the text
2938 sits. Controls containing text usually set their baseline to the
2939 baseline of their text.
2941 For non-text items, a default baseline offset of 0 is used.
2943 QQuickAnchors *QQuickItemPrivate::anchors() const
2946 Q_Q(const QQuickItem);
2947 _anchors = new QQuickAnchors(const_cast<QQuickItem *>(q));
2948 if (!componentComplete)
2949 _anchors->classBegin();
2954 void QQuickItemPrivate::siblingOrderChanged()
2957 for (int ii = 0; ii < changeListeners.count(); ++ii) {
2958 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
2959 if (change.types & QQuickItemPrivate::SiblingOrder) {
2960 change.listener->itemSiblingOrderChanged(q);
2965 QQmlListProperty<QObject> QQuickItemPrivate::data()
2967 return QQmlListProperty<QObject>(q_func(), 0, QQuickItemPrivate::data_append,
2968 QQuickItemPrivate::data_count,
2969 QQuickItemPrivate::data_at,
2970 QQuickItemPrivate::data_clear);
2973 QRectF QQuickItem::childrenRect()
2976 if (!d->extra.isAllocated() || !d->extra->contents) {
2977 d->extra.value().contents = new QQuickContents(this);
2978 if (d->componentComplete)
2979 d->extra->contents->complete();
2981 return d->extra->contents->rectF();
2984 QList<QQuickItem *> QQuickItem::childItems() const
2986 Q_D(const QQuickItem);
2987 return d->childItems;
2990 bool QQuickItem::clip() const
2992 return flags() & ItemClipsChildrenToShape;
2995 void QQuickItem::setClip(bool c)
3000 setFlag(ItemClipsChildrenToShape, c);
3002 emit clipChanged(c);
3007 This function is called to handle this item's changes in
3008 geometry from \a oldGeometry to \a newGeometry. If the two
3009 geometries are the same, it doesn't do anything.
3011 void QQuickItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
3016 QQuickAnchorsPrivate::get(d->_anchors)->updateMe();
3018 bool xChange = (newGeometry.x() != oldGeometry.x());
3019 bool yChange = (newGeometry.y() != oldGeometry.y());
3020 bool widthChange = (newGeometry.width() != oldGeometry.width());
3021 bool heightChange = (newGeometry.height() != oldGeometry.height());
3023 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
3024 const QQuickItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
3025 if (change.types & QQuickItemPrivate::Geometry) {
3026 if (change.gTypes == QQuickItemPrivate::GeometryChange) {
3027 change.listener->itemGeometryChanged(this, newGeometry, oldGeometry);
3028 } else if ((xChange && (change.gTypes & QQuickItemPrivate::XChange)) ||
3029 (yChange && (change.gTypes & QQuickItemPrivate::YChange)) ||
3030 (widthChange && (change.gTypes & QQuickItemPrivate::WidthChange)) ||
3031 (heightChange && (change.gTypes & QQuickItemPrivate::HeightChange))) {
3032 change.listener->itemGeometryChanged(this, newGeometry, oldGeometry);
3042 emit widthChanged();
3044 emit heightChanged();
3048 Called by the rendering thread when it is time to sync the state of the QML objects with the
3049 scene graph objects. The function should return the root of the scene graph subtree for
3050 this item. \a oldNode is the node that was returned the last time the function was called.
3052 The main thread is blocked while this function is executed so it is safe to read
3053 values from the QQuickItem instance and other objects in the main thread.
3055 \warning This is the only function in which it is allowed to make use of scene graph
3056 objects from the main thread. Use of scene graph objects outside this function will
3057 result in race conditions and potential crashes.
3060 QSGNode *QQuickItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
3067 This function is called when the item's scene graph resources are no longer needed.
3068 It allows items to free its resources, for instance textures, that are not owned by scene graph
3069 nodes. Note that scene graph nodes are managed by QQuickCanvas and should not be deleted by
3070 this function. Scene graph resources are no longer needed when the parent is set to null and
3071 the item is not used by any \l ShaderEffect or \l ShaderEffectSource.
3073 This function is called from the main thread. Therefore, resources used by the scene graph
3074 should not be deleted directly, but by calling \l QObject::deleteLater().
3076 \note The item destructor still needs to free its scene graph resources if not already done.
3079 void QQuickItem::releaseResources()
3083 QSGTransformNode *QQuickItemPrivate::createTransformNode()
3085 return new QSGTransformNode;
3088 void QQuickItem::updatePolish()
3092 void QQuickItemPrivate::addItemChangeListener(QQuickItemChangeListener *listener, ChangeTypes types)
3094 changeListeners.append(ChangeListener(listener, types));
3097 void QQuickItemPrivate::removeItemChangeListener(QQuickItemChangeListener *listener, ChangeTypes types)
3099 ChangeListener change(listener, types);
3100 changeListeners.removeOne(change);
3103 void QQuickItemPrivate::updateOrAddGeometryChangeListener(QQuickItemChangeListener *listener, GeometryChangeTypes types)
3105 ChangeListener change(listener, types);
3106 int index = changeListeners.find(change);
3108 changeListeners[index].gTypes = change.gTypes; //we may have different GeometryChangeTypes
3110 changeListeners.append(change);
3113 void QQuickItemPrivate::updateOrRemoveGeometryChangeListener(QQuickItemChangeListener *listener,
3114 GeometryChangeTypes types)
3116 ChangeListener change(listener, types);
3117 if (types == NoChange) {
3118 changeListeners.removeOne(change);
3120 int index = changeListeners.find(change);
3122 changeListeners[index].gTypes = change.gTypes; //we may have different GeometryChangeTypes
3126 void QQuickItem::keyPressEvent(QKeyEvent *event)
3131 void QQuickItem::keyReleaseEvent(QKeyEvent *event)
3136 void QQuickItem::inputMethodEvent(QInputMethodEvent *event)
3141 void QQuickItem::focusInEvent(QFocusEvent *)
3143 #ifndef QT_NO_ACCESSIBILITY
3144 QAccessibleEvent ev(this, QAccessible::Focus);
3145 QAccessible::updateAccessibility(&ev);
3149 void QQuickItem::focusOutEvent(QFocusEvent *)
3153 void QQuickItem::mousePressEvent(QMouseEvent *event)
3158 void QQuickItem::mouseMoveEvent(QMouseEvent *event)
3163 void QQuickItem::mouseReleaseEvent(QMouseEvent *event)
3168 void QQuickItem::mouseDoubleClickEvent(QMouseEvent *)
3172 void QQuickItem::mouseUngrabEvent()
3177 void QQuickItem::touchUngrabEvent()
3182 void QQuickItem::wheelEvent(QWheelEvent *event)
3187 void QQuickItem::touchEvent(QTouchEvent *event)
3192 void QQuickItem::hoverEnterEvent(QHoverEvent *event)
3197 void QQuickItem::hoverMoveEvent(QHoverEvent *event)
3202 void QQuickItem::hoverLeaveEvent(QHoverEvent *event)
3207 void QQuickItem::dragEnterEvent(QDragEnterEvent *event)
3212 void QQuickItem::dragMoveEvent(QDragMoveEvent *event)
3218 void QQuickItem::dragLeaveEvent(QDragLeaveEvent *event)
3224 void QQuickItem::dropEvent(QDropEvent *event)
3229 bool QQuickItem::childMouseEventFilter(QQuickItem *, QEvent *)
3234 void QQuickItem::windowDeactivateEvent()
3236 foreach (QQuickItem* item, childItems()) {
3237 item->windowDeactivateEvent();
3241 QVariant QQuickItem::inputMethodQuery(Qt::InputMethodQuery query) const
3243 Q_D(const QQuickItem);
3248 v = (bool)(flags() & ItemAcceptsInputMethod);
3251 case Qt::ImCursorRectangle:
3253 case Qt::ImCursorPosition:
3254 case Qt::ImSurroundingText:
3255 case Qt::ImCurrentSelection:
3256 case Qt::ImMaximumTextLength:
3257 case Qt::ImAnchorPosition:
3258 case Qt::ImPreferredLanguage:
3259 if (d->extra.isAllocated() && d->extra->keyHandler)
3260 v = d->extra->keyHandler->inputMethodQuery(query);
3268 QQuickAnchorLine QQuickItemPrivate::left() const
3270 Q_Q(const QQuickItem);
3271 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Left);
3274 QQuickAnchorLine QQuickItemPrivate::right() const
3276 Q_Q(const QQuickItem);
3277 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Right);
3280 QQuickAnchorLine QQuickItemPrivate::horizontalCenter() const
3282 Q_Q(const QQuickItem);
3283 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::HCenter);
3286 QQuickAnchorLine QQuickItemPrivate::top() const
3288 Q_Q(const QQuickItem);
3289 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Top);
3292 QQuickAnchorLine QQuickItemPrivate::bottom() const
3294 Q_Q(const QQuickItem);
3295 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Bottom);
3298 QQuickAnchorLine QQuickItemPrivate::verticalCenter() const
3300 Q_Q(const QQuickItem);
3301 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::VCenter);
3304 QQuickAnchorLine QQuickItemPrivate::baseline() const
3306 Q_Q(const QQuickItem);
3307 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Baseline);
3310 qreal QQuickItem::baselineOffset() const
3312 Q_D(const QQuickItem);
3313 if (d->baselineOffsetValid) {
3314 return d->baselineOffset;
3320 void QQuickItem::setBaselineOffset(qreal offset)
3323 if (offset == d->baselineOffset)
3326 d->baselineOffset = offset;
3327 d->baselineOffsetValid = true;
3329 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
3330 const QQuickItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
3331 if (change.types & QQuickItemPrivate::Geometry) {
3332 QQuickAnchorsPrivate *anchor = change.listener->anchorPrivate();
3334 anchor->updateVerticalAnchors();
3338 if (d->_anchors && (d->_anchors->usedAnchors() & QQuickAnchors::BaselineAnchor))
3339 QQuickAnchorsPrivate::get(d->_anchors)->updateVerticalAnchors();
3341 emit baselineOffsetChanged(offset);
3344 void QQuickItem::update()
3347 Q_ASSERT(flags() & ItemHasContents);
3348 d->dirty(QQuickItemPrivate::Content);
3351 void QQuickItem::polish()
3354 if (!d->polishScheduled) {
3355 d->polishScheduled = true;
3357 QQuickCanvasPrivate *p = QQuickCanvasPrivate::get(d->canvas);
3358 bool maybeupdate = p->itemsToPolish.isEmpty();
3359 p->itemsToPolish.insert(this);
3360 if (maybeupdate) d->canvas->maybeUpdate();
3365 void QQuickItem::mapFromItem(QQmlV8Function *args) const
3367 if (args->Length() != 0) {
3368 v8::Local<v8::Value> item = (*args)[0];
3369 QV8Engine *engine = args->engine();
3371 QQuickItem *itemObj = 0;
3372 if (!item->IsNull())
3373 itemObj = qobject_cast<QQuickItem*>(engine->toQObject(item));
3375 if (!itemObj && !item->IsNull()) {
3376 qmlInfo(this) << "mapFromItem() given argument \"" << engine->toString(item->ToString())
3377 << "\" which is neither null nor an Item";
3381 v8::Local<v8::Object> rv = v8::Object::New();
3382 args->returnValue(rv);
3384 qreal x = (args->Length() > 1)?(*args)[1]->NumberValue():0;
3385 qreal y = (args->Length() > 2)?(*args)[2]->NumberValue():0;
3387 QPointF p = mapFromItem(itemObj, QPointF(x, y));
3389 rv->Set(v8::String::New("x"), v8::Number::New(p.x()));
3390 rv->Set(v8::String::New("y"), v8::Number::New(p.y()));
3394 QTransform QQuickItem::itemTransform(QQuickItem *other, bool *ok) const
3396 Q_D(const QQuickItem);
3398 // XXX todo - we need to be able to handle common parents better and detect
3402 QTransform t = d->itemToCanvasTransform();
3403 if (other) t *= QQuickItemPrivate::get(other)->canvasToItemTransform();
3408 void QQuickItem::mapToItem(QQmlV8Function *args) const
3410 if (args->Length() != 0) {
3411 v8::Local<v8::Value> item = (*args)[0];
3412 QV8Engine *engine = args->engine();
3414 QQuickItem *itemObj = 0;
3415 if (!item->IsNull())
3416 itemObj = qobject_cast<QQuickItem*>(engine->toQObject(item));
3418 if (!itemObj && !item->IsNull()) {
3419 qmlInfo(this) << "mapToItem() given argument \"" << engine->toString(item->ToString())
3420 << "\" which is neither null nor an Item";
3424 v8::Local<v8::Object> rv = v8::Object::New();
3425 args->returnValue(rv);
3427 qreal x = (args->Length() > 1)?(*args)[1]->NumberValue():0;
3428 qreal y = (args->Length() > 2)?(*args)[2]->NumberValue():0;
3430 QPointF p = mapToItem(itemObj, QPointF(x, y));
3432 rv->Set(v8::String::New("x"), v8::Number::New(p.x()));
3433 rv->Set(v8::String::New("y"), v8::Number::New(p.y()));
3437 void QQuickItem::forceActiveFocus()
3440 QQuickItem *parent = parentItem();
3442 if (parent->flags() & QQuickItem::ItemIsFocusScope) {
3443 parent->setFocus(true);
3445 parent = parent->parentItem();
3449 QQuickItem *QQuickItem::childAt(qreal x, qreal y) const
3451 // XXX todo - should this include transform etc.?
3452 const QList<QQuickItem *> children = childItems();
3453 for (int i = children.count()-1; i >= 0; --i) {
3454 QQuickItem *child = children.at(i);
3455 if (child->isVisible() && child->x() <= x
3456 && child->x() + child->width() >= x
3458 && child->y() + child->height() >= y)
3464 QQmlListProperty<QObject> QQuickItemPrivate::resources()
3466 return QQmlListProperty<QObject>(q_func(), 0, QQuickItemPrivate::resources_append,
3467 QQuickItemPrivate::resources_count,
3468 QQuickItemPrivate::resources_at,
3469 QQuickItemPrivate::resources_clear);
3472 QQmlListProperty<QQuickItem> QQuickItemPrivate::children()
3474 return QQmlListProperty<QQuickItem>(q_func(), 0, QQuickItemPrivate::children_append,
3475 QQuickItemPrivate::children_count,
3476 QQuickItemPrivate::children_at,
3477 QQuickItemPrivate::children_clear);
3482 \qmlproperty real QtQuick2::Item::visibleChildren
3483 This read-only property lists all of the item's children that are currently visible.
3484 Note that a child's visibility may have changed explicitly, or because the visibility
3485 of this (it's parent) item or another grandparent changed.
3487 QQmlListProperty<QQuickItem> QQuickItemPrivate::visibleChildren()
3489 return QQmlListProperty<QQuickItem>(q_func(), 0, QQuickItemPrivate::visibleChildren_append,
3490 QQuickItemPrivate::visibleChildren_count,
3491 QQuickItemPrivate::visibleChildren_at);
3495 QQmlListProperty<QQuickState> QQuickItemPrivate::states()
3497 return _states()->statesProperty();
3500 QQmlListProperty<QQuickTransition> QQuickItemPrivate::transitions()
3502 return _states()->transitionsProperty();
3505 QString QQuickItemPrivate::state() const
3510 return _stateGroup->state();
3513 void QQuickItemPrivate::setState(const QString &state)
3515 _states()->setState(state);
3518 QString QQuickItem::state() const
3520 Q_D(const QQuickItem);
3524 void QQuickItem::setState(const QString &state)
3530 QQmlListProperty<QQuickTransform> QQuickItem::transform()
3532 return QQmlListProperty<QQuickTransform>(this, 0, QQuickItemPrivate::transform_append,
3533 QQuickItemPrivate::transform_count,
3534 QQuickItemPrivate::transform_at,
3535 QQuickItemPrivate::transform_clear);
3538 void QQuickItem::classBegin()
3541 d->componentComplete = false;
3543 d->_stateGroup->classBegin();
3545 d->_anchors->classBegin();
3546 if (d->extra.isAllocated() && d->extra->layer)
3547 d->extra->layer->classBegin();
3550 void QQuickItem::componentComplete()
3553 d->componentComplete = true;
3555 d->_stateGroup->componentComplete();
3557 d->_anchors->componentComplete();
3558 QQuickAnchorsPrivate::get(d->_anchors)->updateOnComplete();
3561 if (d->extra.isAllocated() && d->extra->layer)
3562 d->extra->layer->componentComplete();
3564 if (d->extra.isAllocated() && d->extra->keyHandler)
3565 d->extra->keyHandler->componentComplete();
3567 if (d->extra.isAllocated() && d->extra->contents)
3568 d->extra->contents->complete();
3571 QQuickStateGroup *QQuickItemPrivate::_states()
3575 _stateGroup = new QQuickStateGroup;
3576 if (!componentComplete)
3577 _stateGroup->classBegin();
3578 FAST_CONNECT(_stateGroup, SIGNAL(stateChanged(QString)),
3579 q, SIGNAL(stateChanged(QString)))
3585 QPointF QQuickItemPrivate::computeTransformOrigin() const
3589 case QQuickItem::TopLeft:
3590 return QPointF(0, 0);
3591 case QQuickItem::Top:
3592 return QPointF(width / 2., 0);
3593 case QQuickItem::TopRight:
3594 return QPointF(width, 0);
3595 case QQuickItem::Left:
3596 return QPointF(0, height / 2.);
3597 case QQuickItem::Center:
3598 return QPointF(width / 2., height / 2.);
3599 case QQuickItem::Right:
3600 return QPointF(width, height / 2.);
3601 case QQuickItem::BottomLeft:
3602 return QPointF(0, height);
3603 case QQuickItem::Bottom:
3604 return QPointF(width / 2., height);
3605 case QQuickItem::BottomRight:
3606 return QPointF(width, height);
3610 void QQuickItemPrivate::transformChanged()
3612 if (extra.isAllocated() && extra->layer)
3613 extra->layer->updateMatrix();
3616 void QQuickItemPrivate::deliverKeyEvent(QKeyEvent *e)
3620 Q_ASSERT(e->isAccepted());
3621 if (extra.isAllocated() && extra->keyHandler) {
3622 if (e->type() == QEvent::KeyPress)
3623 extra->keyHandler->keyPressed(e, false);
3625 extra->keyHandler->keyReleased(e, false);
3627 if (e->isAccepted())
3633 if (e->type() == QEvent::KeyPress)
3634 q->keyPressEvent(e);
3636 q->keyReleaseEvent(e);
3638 if (e->isAccepted())
3641 if (extra.isAllocated() && extra->keyHandler) {
3644 if (e->type() == QEvent::KeyPress)
3645 extra->keyHandler->keyPressed(e, true);
3647 extra->keyHandler->keyReleased(e, true);
3651 void QQuickItemPrivate::deliverInputMethodEvent(QInputMethodEvent *e)
3655 Q_ASSERT(e->isAccepted());
3656 if (extra.isAllocated() && extra->keyHandler) {
3657 extra->keyHandler->inputMethodEvent(e, false);
3659 if (e->isAccepted())
3665 q->inputMethodEvent(e);
3667 if (e->isAccepted())
3670 if (extra.isAllocated() && extra->keyHandler) {
3673 extra->keyHandler->inputMethodEvent(e, true);
3677 void QQuickItemPrivate::deliverFocusEvent(QFocusEvent *e)
3681 if (e->type() == QEvent::FocusIn) {
3684 q->focusOutEvent(e);
3688 void QQuickItemPrivate::deliverMouseEvent(QMouseEvent *e)
3692 Q_ASSERT(e->isAccepted());
3694 switch (e->type()) {
3696 Q_ASSERT(!"Unknown event type");
3697 case QEvent::MouseMove:
3698 q->mouseMoveEvent(e);
3700 case QEvent::MouseButtonPress:
3701 q->mousePressEvent(e);
3703 case QEvent::MouseButtonRelease:
3704 q->mouseReleaseEvent(e);
3706 case QEvent::MouseButtonDblClick:
3707 q->mouseDoubleClickEvent(e);
3712 void QQuickItemPrivate::deliverWheelEvent(QWheelEvent *e)
3718 void QQuickItemPrivate::deliverTouchEvent(QTouchEvent *e)
3724 void QQuickItemPrivate::deliverHoverEvent(QHoverEvent *e)
3727 switch (e->type()) {
3729 Q_ASSERT(!"Unknown event type");
3730 case QEvent::HoverEnter:
3731 q->hoverEnterEvent(e);
3733 case QEvent::HoverLeave:
3734 q->hoverLeaveEvent(e);
3736 case QEvent::HoverMove:
3737 q->hoverMoveEvent(e);
3742 void QQuickItemPrivate::deliverDragEvent(QEvent *e)
3745 switch (e->type()) {
3747 Q_ASSERT(!"Unknown event type");
3748 case QEvent::DragEnter:
3749 q->dragEnterEvent(static_cast<QDragEnterEvent *>(e));
3751 case QEvent::DragLeave:
3752 q->dragLeaveEvent(static_cast<QDragLeaveEvent *>(e));
3754 case QEvent::DragMove:
3755 q->dragMoveEvent(static_cast<QDragMoveEvent *>(e));
3758 q->dropEvent(static_cast<QDropEvent *>(e));
3763 void QQuickItem::itemChange(ItemChange change, const ItemChangeData &value)
3770 Notify input method on updated query values if needed. \a indicates changed attributes.
3772 void QQuickItem::updateInputMethod(Qt::InputMethodQueries queries)
3774 if (hasActiveFocus())
3775 qApp->inputMethod()->update(queries);
3779 // XXX todo - do we want/need this anymore?
3780 // Note that it's now used for varying clip rect
3781 QRectF QQuickItem::boundingRect() const
3783 Q_D(const QQuickItem);
3784 return QRectF(0, 0, d->width, d->height);
3787 QQuickItem::TransformOrigin QQuickItem::transformOrigin() const
3789 Q_D(const QQuickItem);
3793 void QQuickItem::setTransformOrigin(TransformOrigin origin)
3796 if (origin == d->origin())
3799 d->extra.value().origin = origin;
3800 d->dirty(QQuickItemPrivate::TransformOrigin);
3802 emit transformOriginChanged(d->origin());
3805 QPointF QQuickItem::transformOriginPoint() const
3807 Q_D(const QQuickItem);
3808 if (d->extra.isAllocated() && !d->extra->userTransformOriginPoint.isNull())
3809 return d->extra->userTransformOriginPoint;
3810 return d->computeTransformOrigin();
3813 void QQuickItem::setTransformOriginPoint(const QPointF &point)
3816 if (d->extra.value().userTransformOriginPoint == point)
3819 d->extra->userTransformOriginPoint = point;
3820 d->dirty(QQuickItemPrivate::TransformOrigin);
3823 qreal QQuickItem::z() const
3825 Q_D(const QQuickItem);
3829 void QQuickItem::setZ(qreal v)
3835 d->extra.value().z = v;
3837 d->dirty(QQuickItemPrivate::ZValue);
3838 if (d->parentItem) {
3839 QQuickItemPrivate::get(d->parentItem)->dirty(QQuickItemPrivate::ChildrenStackingChanged);
3840 QQuickItemPrivate::get(d->parentItem)->markSortedChildrenDirty(this);
3845 if (d->extra.isAllocated() && d->extra->layer)
3846 d->extra->layer->updateZ();
3851 \qmlproperty real QtQuick2::Item::rotation
3852 This property holds the rotation of the item in degrees clockwise.
3854 This specifies how many degrees to rotate the item around its transformOrigin.
3855 The default rotation is 0 degrees (i.e. not rotated at all).
3859 \li \image declarative-rotation.png
3864 width: 100; height: 100
3867 x: 25; y: 25; width: 50; height: 50
3874 \sa transform, Rotation
3878 \qmlproperty real QtQuick2::Item::scale
3879 This property holds the scale of the item.
3881 A scale of less than 1 means the item will be displayed smaller than
3882 normal, and a scale of greater than 1 means the item will be
3883 displayed larger than normal. A negative scale means the item will
3886 By default, items are displayed at a scale of 1 (i.e. at their
3889 Scaling is from the item's transformOrigin.
3893 \li \image declarative-scale.png
3898 width: 100; height: 100
3901 width: 25; height: 25
3905 x: 25; y: 25; width: 50; height: 50
3912 \sa transform, Scale
3916 \qmlproperty real QtQuick2::Item::opacity
3918 This property holds the opacity of the item. Opacity is specified as a
3919 number between 0 (fully transparent) and 1 (fully opaque). The default is 1.
3921 When this property is set, the specified opacity is also applied
3922 individually to child items. In almost all cases this is what you want,
3923 but in some cases it may produce undesired results. For example in the
3924 second set of rectangles below, the red rectangle has specified an opacity
3925 of 0.5, which affects the opacity of its blue child rectangle even though
3926 the child has not specified an opacity.
3930 \li \image declarative-item_opacity1.png
3936 width: 100; height: 100
3939 x: 50; y: 50; width: 100; height: 100
3945 \li \image declarative-item_opacity2.png
3952 width: 100; height: 100
3955 x: 50; y: 50; width: 100; height: 100
3962 If an item's opacity is set to 0, the item will no longer receive mouse
3963 events, but will continue to receive key events and will retain the keyboard
3964 \l focus if it has been set. (In contrast, setting the \l visible property
3965 to \c false stops both mouse and keyboard events, and also removes focus
3970 Returns a value indicating whether mouse input should
3971 remain with this item exclusively.
3973 \sa setKeepMouseGrab()
3976 qreal QQuickItem::rotation() const
3978 Q_D(const QQuickItem);
3979 return d->rotation();
3982 void QQuickItem::setRotation(qreal r)
3985 if (d->rotation() == r)
3988 d->extra.value().rotation = r;
3990 d->dirty(QQuickItemPrivate::BasicTransform);
3992 d->itemChange(ItemRotationHasChanged, r);
3994 emit rotationChanged();
3997 qreal QQuickItem::scale() const
3999 Q_D(const QQuickItem);
4003 void QQuickItem::setScale(qreal s)
4006 if (d->scale() == s)
4009 d->extra.value().scale = s;
4011 d->dirty(QQuickItemPrivate::BasicTransform);
4013 emit scaleChanged();
4016 qreal QQuickItem::opacity() const
4018 Q_D(const QQuickItem);
4019 return d->opacity();
4022 void QQuickItem::setOpacity(qreal o)
4025 if (d->opacity() == o)
4028 d->extra.value().opacity = o;
4030 d->dirty(QQuickItemPrivate::OpacityValue);
4032 d->itemChange(ItemOpacityHasChanged, o);
4034 emit opacityChanged();
4037 bool QQuickItem::isVisible() const
4039 Q_D(const QQuickItem);
4040 return d->effectiveVisible;
4043 void QQuickItem::setVisible(bool v)
4046 if (v == d->explicitVisible)
4049 d->explicitVisible = v;
4051 const bool childVisibilityChanged = d->setEffectiveVisibleRecur(d->calcEffectiveVisible());
4052 if (childVisibilityChanged && d->parentItem)
4053 emit d->parentItem->visibleChildrenChanged(); // signal the parent, not this!
4056 bool QQuickItem::isEnabled() const
4058 Q_D(const QQuickItem);
4059 return d->effectiveEnable;
4062 void QQuickItem::setEnabled(bool e)
4065 if (e == d->explicitEnable)
4068 d->explicitEnable = e;
4070 QQuickItem *scope = parentItem();
4071 while (scope && !scope->isFocusScope())
4072 scope = scope->parentItem();
4074 d->setEffectiveEnableRecur(scope, d->calcEffectiveEnable());
4077 bool QQuickItemPrivate::calcEffectiveVisible() const
4079 // XXX todo - Should the effective visible of an element with no parent just be the current
4080 // effective visible? This would prevent pointless re-processing in the case of an element
4081 // moving to/from a no-parent situation, but it is different from what graphics view does.
4082 return explicitVisible && (!parentItem || QQuickItemPrivate::get(parentItem)->effectiveVisible);
4085 bool QQuickItemPrivate::setEffectiveVisibleRecur(bool newEffectiveVisible)
4089 if (newEffectiveVisible && !explicitVisible) {
4090 // This item locally overrides visibility
4091 return false; // effective visibility didn't change
4094 if (newEffectiveVisible == effectiveVisible) {
4095 // No change necessary
4096 return false; // effective visibility didn't change
4099 effectiveVisible = newEffectiveVisible;
4101 if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
4104 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(canvas);
4105 if (canvasPriv->mouseGrabberItem == q)
4109 bool childVisibilityChanged = false;
4110 for (int ii = 0; ii < childItems.count(); ++ii)
4111 childVisibilityChanged |= QQuickItemPrivate::get(childItems.at(ii))->setEffectiveVisibleRecur(newEffectiveVisible);
4113 itemChange(QQuickItem::ItemVisibleHasChanged, effectiveVisible);
4114 #ifndef QT_NO_ACCESSIBILITY
4116 QAccessibleEvent ev(q, effectiveVisible ? QAccessible::ObjectShow : QAccessible::ObjectHide);
4117 QAccessible::updateAccessibility(&ev);
4120 emit q->visibleChanged();
4121 if (childVisibilityChanged)
4122 emit q->visibleChildrenChanged();
4124 return true; // effective visibility DID change
4127 bool QQuickItemPrivate::calcEffectiveEnable() const
4129 // XXX todo - Should the effective enable of an element with no parent just be the current
4130 // effective enable? This would prevent pointless re-processing in the case of an element
4131 // moving to/from a no-parent situation, but it is different from what graphics view does.
4132 return explicitEnable && (!parentItem || QQuickItemPrivate::get(parentItem)->effectiveEnable);
4135 void QQuickItemPrivate::setEffectiveEnableRecur(QQuickItem *scope, bool newEffectiveEnable)
4139 if (newEffectiveEnable && !explicitEnable) {
4140 // This item locally overrides enable
4144 if (newEffectiveEnable == effectiveEnable) {
4145 // No change necessary
4149 effectiveEnable = newEffectiveEnable;
4152 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(canvas);
4153 if (canvasPriv->mouseGrabberItem == q)
4155 if (scope && !effectiveEnable && activeFocus) {
4156 canvasPriv->clearFocusInScope(
4157 scope, q, QQuickCanvasPrivate::DontChangeFocusProperty | QQuickCanvasPrivate::DontChangeSubFocusItem);
4161 for (int ii = 0; ii < childItems.count(); ++ii) {
4162 QQuickItemPrivate::get(childItems.at(ii))->setEffectiveEnableRecur(
4163 flags & QQuickItem::ItemIsFocusScope ? q : scope, newEffectiveEnable);
4166 if (canvas && scope && effectiveEnable && focus) {
4167 QQuickCanvasPrivate::get(canvas)->setFocusInScope(
4168 scope, q, QQuickCanvasPrivate::DontChangeFocusProperty | QQuickCanvasPrivate::DontChangeSubFocusItem);
4171 emit q->enabledChanged();
4174 QString QQuickItemPrivate::dirtyToString() const
4176 #define DIRTY_TO_STRING(value) if (dirtyAttributes & value) { \
4177 if (!rv.isEmpty()) \
4178 rv.append(QLatin1String("|")); \
4179 rv.append(QLatin1String(#value)); \
4182 // QString rv = QLatin1String("0x") + QString::number(dirtyAttributes, 16);
4185 DIRTY_TO_STRING(TransformOrigin);
4186 DIRTY_TO_STRING(Transform);
4187 DIRTY_TO_STRING(BasicTransform);
4188 DIRTY_TO_STRING(Position);
4189 DIRTY_TO_STRING(Size);
4190 DIRTY_TO_STRING(ZValue);
4191 DIRTY_TO_STRING(Content);
4192 DIRTY_TO_STRING(Smooth);
4193 DIRTY_TO_STRING(OpacityValue);
4194 DIRTY_TO_STRING(ChildrenChanged);
4195 DIRTY_TO_STRING(ChildrenStackingChanged);
4196 DIRTY_TO_STRING(ParentChanged);
4197 DIRTY_TO_STRING(Clip);
4198 DIRTY_TO_STRING(Canvas);
4199 DIRTY_TO_STRING(EffectReference);
4200 DIRTY_TO_STRING(Visible);
4201 DIRTY_TO_STRING(HideReference);
4202 DIRTY_TO_STRING(PerformanceHints);
4207 void QQuickItemPrivate::dirty(DirtyType type)
4210 if (type & (TransformOrigin | Transform | BasicTransform | Position | Size))
4213 if (!(dirtyAttributes & type) || (canvas && !prevDirtyItem)) {
4214 dirtyAttributes |= type;
4217 QQuickCanvasPrivate::get(canvas)->dirtyItem(q);
4222 void QQuickItemPrivate::addToDirtyList()
4227 if (!prevDirtyItem) {
4228 Q_ASSERT(!nextDirtyItem);
4230 QQuickCanvasPrivate *p = QQuickCanvasPrivate::get(canvas);
4231 nextDirtyItem = p->dirtyItemList;
4232 if (nextDirtyItem) QQuickItemPrivate::get(nextDirtyItem)->prevDirtyItem = &nextDirtyItem;
4233 prevDirtyItem = &p->dirtyItemList;
4234 p->dirtyItemList = q;
4237 Q_ASSERT(prevDirtyItem);
4240 void QQuickItemPrivate::removeFromDirtyList()
4242 if (prevDirtyItem) {
4243 if (nextDirtyItem) QQuickItemPrivate::get(nextDirtyItem)->prevDirtyItem = prevDirtyItem;
4244 *prevDirtyItem = nextDirtyItem;
4248 Q_ASSERT(!prevDirtyItem);
4249 Q_ASSERT(!nextDirtyItem);
4252 void QQuickItemPrivate::refFromEffectItem(bool hide)
4254 ++extra.value().effectRefCount;
4255 if (1 == extra->effectRefCount) {
4256 dirty(EffectReference);
4257 if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
4260 if (++extra->hideRefCount == 1)
4261 dirty(HideReference);
4265 void QQuickItemPrivate::derefFromEffectItem(bool unhide)
4267 Q_ASSERT(extra->effectRefCount);
4268 --extra->effectRefCount;
4269 if (0 == extra->effectRefCount) {
4270 dirty(EffectReference);
4271 if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
4274 if (--extra->hideRefCount == 0)
4275 dirty(HideReference);
4279 void QQuickItemPrivate::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data)
4283 case QQuickItem::ItemChildAddedChange:
4284 q->itemChange(change, data);
4285 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4286 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4287 if (change.types & QQuickItemPrivate::Children) {
4288 change.listener->itemChildAdded(q, data.item);
4292 case QQuickItem::ItemChildRemovedChange:
4293 q->itemChange(change, data);
4294 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4295 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4296 if (change.types & QQuickItemPrivate::Children) {
4297 change.listener->itemChildRemoved(q, data.item);
4301 case QQuickItem::ItemSceneChange:
4302 q->itemChange(change, data);
4304 case QQuickItem::ItemVisibleHasChanged:
4305 q->itemChange(change, data);
4306 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4307 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4308 if (change.types & QQuickItemPrivate::Visibility) {
4309 change.listener->itemVisibilityChanged(q);
4313 case QQuickItem::ItemParentHasChanged:
4314 q->itemChange(change, data);
4315 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4316 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4317 if (change.types & QQuickItemPrivate::Parent) {
4318 change.listener->itemParentChanged(q, data.item);
4322 case QQuickItem::ItemOpacityHasChanged:
4323 q->itemChange(change, data);
4324 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4325 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4326 if (change.types & QQuickItemPrivate::Opacity) {
4327 change.listener->itemOpacityChanged(q);
4331 case QQuickItem::ItemActiveFocusHasChanged:
4332 q->itemChange(change, data);
4334 case QQuickItem::ItemRotationHasChanged:
4335 q->itemChange(change, data);
4336 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4337 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4338 if (change.types & QQuickItemPrivate::Rotation) {
4339 change.listener->itemRotationChanged(q);
4347 \property QQuickItem::smooth
4348 \brief whether the item is smoothed or not.
4350 Primarily used in image based elements to decide if the item should use smooth
4351 sampling or not. Smooth sampling is performed using linear interpolation, while
4352 non-smooth is performed using nearest neighbor.
4354 In Qt Quick 2.0, this property has minimal impact on performance.
4360 Returns true if the item should be drawn with antialiasing and
4361 smooth pixmap filtering, false otherwise.
4363 The default is false.
4367 bool QQuickItem::smooth() const
4369 Q_D(const QQuickItem);
4374 Sets whether the item should be drawn with antialiasing and
4375 smooth pixmap filtering to \a smooth.
4379 void QQuickItem::setSmooth(bool smooth)
4382 if (d->smooth == smooth)
4386 d->dirty(QQuickItemPrivate::Smooth);
4388 emit smoothChanged(smooth);
4391 QQuickItem::Flags QQuickItem::flags() const
4393 Q_D(const QQuickItem);
4394 return (QQuickItem::Flags)d->flags;
4397 void QQuickItem::setFlag(Flag flag, bool enabled)
4401 setFlags((Flags)(d->flags | (quint32)flag));
4403 setFlags((Flags)(d->flags & ~(quint32)flag));
4406 void QQuickItem::setFlags(Flags flags)
4410 if ((flags & ItemIsFocusScope) != (d->flags & ItemIsFocusScope)) {
4411 if (flags & ItemIsFocusScope && !d->childItems.isEmpty() && d->canvas) {
4412 qWarning("QQuickItem: Cannot set FocusScope once item has children and is in a canvas.");
4413 flags &= ~ItemIsFocusScope;
4414 } else if (d->flags & ItemIsFocusScope) {
4415 qWarning("QQuickItem: Cannot unset FocusScope flag.");
4416 flags |= ItemIsFocusScope;
4420 if ((flags & ItemClipsChildrenToShape ) != (d->flags & ItemClipsChildrenToShape))
4421 d->dirty(QQuickItemPrivate::Clip);
4426 qreal QQuickItem::x() const
4428 Q_D(const QQuickItem);
4432 qreal QQuickItem::y() const
4434 Q_D(const QQuickItem);
4438 QPointF QQuickItem::pos() const
4440 Q_D(const QQuickItem);
4441 return QPointF(d->x, d->y);
4444 void QQuickItem::setX(qreal v)
4453 d->dirty(QQuickItemPrivate::Position);
4455 geometryChanged(QRectF(x(), y(), width(), height()),
4456 QRectF(oldx, y(), width(), height()));
4459 void QQuickItem::setY(qreal v)
4468 d->dirty(QQuickItemPrivate::Position);
4470 geometryChanged(QRectF(x(), y(), width(), height()),
4471 QRectF(x(), oldy, width(), height()));
4474 void QQuickItem::setPos(const QPointF &pos)
4477 if (QPointF(d->x, d->y) == pos)
4486 d->dirty(QQuickItemPrivate::Position);
4488 geometryChanged(QRectF(x(), y(), width(), height()),
4489 QRectF(oldx, oldy, width(), height()));
4492 qreal QQuickItem::width() const
4494 Q_D(const QQuickItem);
4498 void QQuickItem::setWidth(qreal w)
4504 d->widthValid = true;
4508 qreal oldWidth = d->width;
4511 d->dirty(QQuickItemPrivate::Size);
4513 geometryChanged(QRectF(x(), y(), width(), height()),
4514 QRectF(x(), y(), oldWidth, height()));
4517 void QQuickItem::resetWidth()
4520 d->widthValid = false;
4521 setImplicitWidth(implicitWidth());
4524 void QQuickItemPrivate::implicitWidthChanged()
4527 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4528 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4529 if (change.types & QQuickItemPrivate::ImplicitWidth) {
4530 change.listener->itemImplicitWidthChanged(q);
4533 emit q->implicitWidthChanged();
4536 qreal QQuickItemPrivate::getImplicitWidth() const
4538 return implicitWidth;
4541 Returns the width of the item that is implied by other properties that determine the content.
4543 qreal QQuickItem::implicitWidth() const
4545 Q_D(const QQuickItem);
4546 return d->getImplicitWidth();
4550 \qmlproperty real QtQuick2::Item::implicitWidth
4551 \qmlproperty real QtQuick2::Item::implicitHeight
4553 Defines the natural width or height of the Item if no \l width or \l height is specified.
4555 The default implicit size for most items is 0x0, however some elements have an inherent
4556 implicit size which cannot be overridden, e.g. Image, Text.
4558 Setting the implicit size is useful for defining components that have a preferred size
4559 based on their content, for example:
4566 property alias icon: image.source
4567 property alias label: text.text
4568 implicitWidth: text.implicitWidth + image.implicitWidth
4569 implicitHeight: Math.max(text.implicitHeight, image.implicitHeight)
4574 anchors.left: image.right; anchors.right: parent.right
4575 anchors.verticalCenter: parent.verticalCenter
4580 \b Note: using implicitWidth of Text or TextEdit and setting the width explicitly
4581 incurs a performance penalty as the text must be laid out twice.
4585 Sets the implied width of the item to \a w.
4586 This is the width implied by other properties that determine the content.
4588 void QQuickItem::setImplicitWidth(qreal w)
4591 bool changed = w != d->implicitWidth;
4592 d->implicitWidth = w;
4593 if (d->width == w || widthValid()) {
4595 d->implicitWidthChanged();
4599 qreal oldWidth = d->width;
4602 d->dirty(QQuickItemPrivate::Size);
4604 geometryChanged(QRectF(x(), y(), width(), height()),
4605 QRectF(x(), y(), oldWidth, height()));
4608 d->implicitWidthChanged();
4612 Returns whether the width property has been set explicitly.
4614 bool QQuickItem::widthValid() const
4616 Q_D(const QQuickItem);
4617 return d->widthValid;
4620 qreal QQuickItem::height() const
4622 Q_D(const QQuickItem);
4626 void QQuickItem::setHeight(qreal h)
4632 d->heightValid = true;
4636 qreal oldHeight = d->height;
4639 d->dirty(QQuickItemPrivate::Size);
4641 geometryChanged(QRectF(x(), y(), width(), height()),
4642 QRectF(x(), y(), width(), oldHeight));
4645 void QQuickItem::resetHeight()
4648 d->heightValid = false;
4649 setImplicitHeight(implicitHeight());
4652 void QQuickItemPrivate::implicitHeightChanged()
4655 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4656 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4657 if (change.types & QQuickItemPrivate::ImplicitHeight) {
4658 change.listener->itemImplicitHeightChanged(q);
4661 emit q->implicitHeightChanged();
4664 qreal QQuickItemPrivate::getImplicitHeight() const
4666 return implicitHeight;
4670 Returns the height of the item that is implied by other properties that determine the content.
4672 qreal QQuickItem::implicitHeight() const
4674 Q_D(const QQuickItem);
4675 return d->getImplicitHeight();
4680 Sets the implied height of the item to \a h.
4681 This is the height implied by other properties that determine the content.
4683 void QQuickItem::setImplicitHeight(qreal h)
4686 bool changed = h != d->implicitHeight;
4687 d->implicitHeight = h;
4688 if (d->height == h || heightValid()) {
4690 d->implicitHeightChanged();
4694 qreal oldHeight = d->height;
4697 d->dirty(QQuickItemPrivate::Size);
4699 geometryChanged(QRectF(x(), y(), width(), height()),
4700 QRectF(x(), y(), width(), oldHeight));
4703 d->implicitHeightChanged();
4706 void QQuickItem::setImplicitSize(qreal w, qreal h)
4709 bool wChanged = w != d->implicitWidth;
4710 bool hChanged = h != d->implicitHeight;
4712 d->implicitWidth = w;
4713 d->implicitHeight = h;
4717 if (d->width == w || widthValid()) {
4719 d->implicitWidthChanged();
4722 if (d->height == h || heightValid()) {
4724 d->implicitHeightChanged();
4730 qreal oldWidth = d->width;
4731 qreal oldHeight = d->height;
4737 d->dirty(QQuickItemPrivate::Size);
4739 geometryChanged(QRectF(x(), y(), width(), height()),
4740 QRectF(x(), y(), oldWidth, oldHeight));
4742 if (!wDone && wChanged)
4743 d->implicitWidthChanged();
4744 if (!hDone && hChanged)
4745 d->implicitHeightChanged();
4749 Returns whether the height property has been set explicitly.
4751 bool QQuickItem::heightValid() const
4753 Q_D(const QQuickItem);
4754 return d->heightValid;
4757 void QQuickItem::setSize(const QSizeF &size)
4760 d->heightValid = true;
4761 d->widthValid = true;
4763 if (QSizeF(d->width, d->height) == size)
4766 qreal oldHeight = d->height;
4767 qreal oldWidth = d->width;
4768 d->height = size.height();
4769 d->width = size.width();
4771 d->dirty(QQuickItemPrivate::Size);
4773 geometryChanged(QRectF(x(), y(), width(), height()),
4774 QRectF(x(), y(), oldWidth, oldHeight));
4777 bool QQuickItem::hasActiveFocus() const
4779 Q_D(const QQuickItem);
4780 return d->activeFocus;
4783 bool QQuickItem::hasFocus() const
4785 Q_D(const QQuickItem);
4789 void QQuickItem::setFocus(bool focus)
4792 if (d->focus == focus)
4795 if (d->canvas || d->parentItem) {
4796 // Need to find our nearest focus scope
4797 QQuickItem *scope = parentItem();
4798 while (scope && !scope->isFocusScope() && scope->parentItem())
4799 scope = scope->parentItem();
4802 QQuickCanvasPrivate::get(d->canvas)->setFocusInScope(scope, this);
4804 QQuickCanvasPrivate::get(d->canvas)->clearFocusInScope(scope, this);
4806 // do the focus changes from setFocusInScope/clearFocusInScope that are
4807 // unrelated to a canvas
4808 QVarLengthArray<QQuickItem *, 20> changed;
4809 QQuickItem *oldSubFocusItem = QQuickItemPrivate::get(scope)->subFocusItem;
4810 if (oldSubFocusItem) {
4811 QQuickItemPrivate::get(oldSubFocusItem)->focus = false;
4812 changed << oldSubFocusItem;
4814 d->updateSubFocusItem(scope, focus);
4818 emit focusChanged(focus);
4820 QQuickCanvasPrivate::notifyFocusChangesRecur(changed.data(), changed.count() - 1);
4824 emit focusChanged(focus);
4828 bool QQuickItem::isFocusScope() const
4830 return flags() & ItemIsFocusScope;
4833 QQuickItem *QQuickItem::scopedFocusItem() const
4835 Q_D(const QQuickItem);
4836 if (!isFocusScope())
4839 return d->subFocusItem;
4843 Qt::MouseButtons QQuickItem::acceptedMouseButtons() const
4845 Q_D(const QQuickItem);
4846 return d->acceptedMouseButtons();
4849 void QQuickItem::setAcceptedMouseButtons(Qt::MouseButtons buttons)
4852 if (buttons & Qt::LeftButton)
4855 d->extra.clearFlag();
4857 buttons &= ~Qt::LeftButton;
4858 if (buttons || d->extra.isAllocated())
4859 d->extra.value().acceptedMouseButtons = buttons;
4862 bool QQuickItem::filtersChildMouseEvents() const
4864 Q_D(const QQuickItem);
4865 return d->filtersChildMouseEvents;
4868 void QQuickItem::setFiltersChildMouseEvents(bool filter)
4871 d->filtersChildMouseEvents = filter;
4874 bool QQuickItem::isUnderMouse() const
4876 Q_D(const QQuickItem);
4880 QPointF cursorPos = QGuiApplicationPrivate::lastCursorPosition;
4881 if (QRectF(0, 0, width(), height()).contains(mapFromScene(cursorPos))) // ### refactor: d->canvas->mapFromGlobal(cursorPos))))
4886 bool QQuickItem::acceptHoverEvents() const
4888 Q_D(const QQuickItem);
4889 return d->hoverEnabled;
4892 void QQuickItem::setAcceptHoverEvents(bool enabled)
4895 d->hoverEnabled = enabled;
4898 void QQuickItem::grabMouse()
4903 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
4904 if (canvasPriv->mouseGrabberItem == this)
4907 QQuickItem *oldGrabber = canvasPriv->mouseGrabberItem;
4908 canvasPriv->mouseGrabberItem = this;
4910 QEvent ev(QEvent::UngrabMouse);
4911 d->canvas->sendEvent(oldGrabber, &ev);
4915 void QQuickItem::ungrabMouse()
4920 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
4921 if (canvasPriv->mouseGrabberItem != this) {
4922 qWarning("QQuickItem::ungrabMouse(): Item is not the mouse grabber.");
4926 canvasPriv->mouseGrabberItem = 0;
4928 QEvent ev(QEvent::UngrabMouse);
4929 d->canvas->sendEvent(this, &ev);
4932 bool QQuickItem::keepMouseGrab() const
4934 Q_D(const QQuickItem);
4935 return d->keepMouse;
4939 The flag indicating whether the mouse should remain
4940 with this item is set to \a keep.
4942 This is useful for items that wish to grab and keep mouse
4943 interaction following a predefined gesture. For example,
4944 an item that is interested in horizontal mouse movement
4945 may set keepMouseGrab to true once a threshold has been
4946 exceeded. Once keepMouseGrab has been set to true, filtering
4947 items will not react to mouse events.
4949 If the item does not indicate that it wishes to retain mouse grab,
4950 a filtering item may steal the grab. For example, Flickable may attempt
4951 to steal a mouse grab if it detects that the user has begun to
4956 void QQuickItem::setKeepMouseGrab(bool keep)
4959 d->keepMouse = keep;
4963 Grabs the touch points specified by \a ids.
4965 These touch points will be owned by the item until
4966 they are released. Alternatively, the grab can be stolen
4967 by a filtering item like Flickable. Use setKeepTouchGrab()
4968 to prevent the grab from being stolen.
4970 \sa ungrabTouchPoints(), setKeepTouchGrab()
4972 void QQuickItem::grabTouchPoints(const QList<int> &ids)
4977 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
4979 QSet<QQuickItem*> ungrab;
4980 for (int i = 0; i < ids.count(); ++i) {
4981 QQuickItem *oldGrabber = canvasPriv->itemForTouchPointId.value(ids.at(i));
4982 if (oldGrabber == this)
4985 canvasPriv->itemForTouchPointId[ids.at(i)] = this;
4987 ungrab.insert(oldGrabber);
4989 foreach (QQuickItem *oldGrabber, ungrab)
4990 oldGrabber->touchUngrabEvent();
4994 Ungrabs the touch points owned by this item.
4996 \sa grabTouchPoints()
4998 void QQuickItem::ungrabTouchPoints()
5003 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
5005 QMutableHashIterator<int, QQuickItem*> i(canvasPriv->itemForTouchPointId);
5006 while (i.hasNext()) {
5008 if (i.value() == this)
5015 Returns a value indicating whether the touch points grabbed by this item
5016 should remain with this item exclusively.
5018 \sa setKeepTouchGrab(), keepMouseGrab()
5020 bool QQuickItem::keepTouchGrab() const
5022 Q_D(const QQuickItem);
5023 return d->keepTouch;
5027 The flag indicating whether the touch points grabbed
5028 by this item should remain with this item is set to \a keep.
5030 This is useful for items that wish to grab and keep specific touch
5031 points following a predefined gesture. For example,
5032 an item that is interested in horizontal touch point movement
5033 may set setKeepTouchGrab to true once a threshold has been
5034 exceeded. Once setKeepTouchGrab has been set to true, filtering
5035 items will not react to the relevant touch points.
5037 If the item does not indicate that it wishes to retain touch point grab,
5038 a filtering item may steal the grab. For example, Flickable may attempt
5039 to steal a touch point grab if it detects that the user has begun to
5042 \sa keepTouchGrab(), setKeepMouseGrab()
5044 void QQuickItem::setKeepTouchGrab(bool keep)
5047 d->keepTouch = keep;
5051 \qmlmethod object QtQuick2::Item::mapFromItem(Item item, real x, real y)
5053 Maps the point (\a x, \a y), which is in \a item's coordinate system, to
5054 this item's coordinate system, and returns an object with \c x and \c y
5055 properties matching the mapped coordinate.
5057 If \a item is a \c null value, this maps the point from the coordinate
5058 system of the root QML view.
5061 \qmlmethod object QtQuick2::Item::mapToItem(Item item, real x, real y)
5063 Maps the point (\a x, \a y), which is in this item's coordinate system, to
5064 \a item's coordinate system, and returns an object with \c x and \c y
5065 properties matching the mapped coordinate.
5067 If \a item is a \c null value, this maps \a x and \a y to the coordinate
5068 system of the root QML view.
5070 QPointF QQuickItem::mapToItem(const QQuickItem *item, const QPointF &point) const
5072 QPointF p = mapToScene(point);
5074 p = item->mapFromScene(p);
5078 QPointF QQuickItem::mapToScene(const QPointF &point) const
5080 Q_D(const QQuickItem);
5081 return d->itemToCanvasTransform().map(point);
5084 QRectF QQuickItem::mapRectToItem(const QQuickItem *item, const QRectF &rect) const
5086 Q_D(const QQuickItem);
5087 QTransform t = d->itemToCanvasTransform();
5089 t *= QQuickItemPrivate::get(item)->canvasToItemTransform();
5090 return t.mapRect(rect);
5093 QRectF QQuickItem::mapRectToScene(const QRectF &rect) const
5095 Q_D(const QQuickItem);
5096 return d->itemToCanvasTransform().mapRect(rect);
5099 QPointF QQuickItem::mapFromItem(const QQuickItem *item, const QPointF &point) const
5101 QPointF p = item?item->mapToScene(point):point;
5102 return mapFromScene(p);
5105 QPointF QQuickItem::mapFromScene(const QPointF &point) const
5107 Q_D(const QQuickItem);
5108 return d->canvasToItemTransform().map(point);
5111 QRectF QQuickItem::mapRectFromItem(const QQuickItem *item, const QRectF &rect) const
5113 Q_D(const QQuickItem);
5114 QTransform t = item?QQuickItemPrivate::get(item)->itemToCanvasTransform():QTransform();
5115 t *= d->canvasToItemTransform();
5116 return t.mapRect(rect);
5119 QRectF QQuickItem::mapRectFromScene(const QRectF &rect) const
5121 Q_D(const QQuickItem);
5122 return d->canvasToItemTransform().mapRect(rect);
5127 \qmlmethod QtQuick2::Item::forceActiveFocus()
5129 Forces active focus on the item.
5131 This method sets focus on the item and makes sure that all the focus scopes
5132 higher in the object hierarchy are also given the focus.
5136 Forces active focus on the item.
5138 This method sets focus on the item and makes sure that all the focus scopes
5139 higher in the object hierarchy are also given the focus.
5143 \qmlmethod QtQuick2::Item::childAt(real x, real y)
5145 Returns the visible child item at point (\a x, \a y), which is in this
5146 item's coordinate system, or \c null if there is no such item.
5150 Returns the visible child item at point (\a x, \a y), which is in this
5151 item's coordinate system, or 0 if there is no such item.
5155 \qmlproperty list<State> QtQuick2::Item::states
5156 This property holds a list of states defined by the item.
5172 \sa {qmlstate}{States}
5175 \qmlproperty list<Transition> QtQuick2::Item::transitions
5176 This property holds a list of transitions defined by the item.
5192 \sa {QML Animation and Transitions}{Transitions}
5195 \qmlproperty list<Filter> QtQuick2::Item::filter
5196 This property holds a list of graphical filters to be applied to the item.
5198 \l {Filter}{Filters} include things like \l {Blur}{blurring}
5199 the item, or giving it a \l Reflection. Some
5200 filters may not be available on all canvases; if a filter is not
5201 available on a certain canvas, it will simply not be applied for
5202 that canvas (but the QML will still be considered valid).
5220 \qmlproperty bool QtQuick2::Item::clip
5221 This property holds whether clipping is enabled. The default clip value is \c false.
5223 If clipping is enabled, an item will clip its own painting, as well
5224 as the painting of its children, to its bounding rectangle.
5226 Non-rectangular clipping regions are not supported for performance reasons.
5230 \property QQuickItem::clip
5231 This property holds whether clipping is enabled. The default clip value is \c false.
5233 If clipping is enabled, an item will clip its own painting, as well
5234 as the painting of its children, to its bounding rectangle. If you set
5235 clipping during an item's paint operation, remember to re-set it to
5236 prevent clipping the rest of your scene.
5238 Non-rectangular clipping regions are not supported for performance reasons.
5242 \qmlproperty string QtQuick2::Item::state
5244 This property holds the name of the current state of the item.
5246 This property is often used in scripts to change between states. For
5251 if (button.state == 'On')
5252 button.state = 'Off';
5254 button.state = 'On';
5258 If the item is in its base state (i.e. no explicit state has been
5259 set), \c state will be a blank string. Likewise, you can return an
5260 item to its base state by setting its current state to \c ''.
5262 \sa {qmlstates}{States}
5266 \qmlproperty list<Transform> QtQuick2::Item::transform
5267 This property holds the list of transformations to apply.
5269 For more information see \l Transform.
5273 \enum QQuickItem::TransformOrigin
5275 Controls the point about which simple transforms like scale apply.
5277 \value TopLeft The top-left corner of the item.
5278 \value Top The center point of the top of the item.
5279 \value TopRight The top-right corner of the item.
5280 \value Left The left most point of the vertical middle.
5281 \value Center The center of the item.
5282 \value Right The right most point of the vertical middle.
5283 \value BottomLeft The bottom-left corner of the item.
5284 \value Bottom The center point of the bottom of the item.
5285 \value BottomRight The bottom-right corner of the item.
5290 \qmlproperty bool QtQuick2::Item::activeFocus
5292 This property indicates whether the item has active focus.
5294 An item with active focus will receive keyboard input,
5295 or is a FocusScope ancestor of the item that will receive keyboard input.
5297 Usually, activeFocus is gained by setting focus on an item and its enclosing
5298 FocusScopes. In the following example \c input will have activeFocus.
5311 \sa focus, {qmlfocus}{Keyboard Focus}
5315 \qmlproperty bool QtQuick2::Item::focus
5316 This property indicates whether the item has focus within the enclosing focus scope. If true, this item
5317 will gain active focus when the enclosing focus scope gains active focus.
5318 In the following example, \c input will be given active focus when \c scope gains active focus.
5331 For the purposes of this property, the scene as a whole is assumed to act like a focus scope.
5332 On a practical level, that means the following QML will give active focus to \c input on startup.
5343 \sa activeFocus, {qmlfocus}{Keyboard Focus}
5348 \property QQuickItem::anchors
5353 \property QQuickItem::left
5358 \property QQuickItem::right
5363 \property QQuickItem::horizontalCenter
5368 \property QQuickItem::top
5373 \property QQuickItem::bottom
5378 \property QQuickItem::verticalCenter
5383 \property QQuickItem::focus
5388 \property QQuickItem::transform
5393 \property QQuickItem::transformOrigin
5398 \property QQuickItem::activeFocus
5403 \property QQuickItem::baseline
5408 \property QQuickItem::data
5413 \property QQuickItem::resources
5418 \property QQuickItem::state
5423 \property QQuickItem::states
5428 \property QQuickItem::transformOriginPoint
5433 \property QQuickItem::transitions
5437 bool QQuickItem::event(QEvent *ev)
5440 if (ev->type() == QEvent::PolishRequest) {
5442 d->polishScheduled = false;
5446 return QObject::event(ev);
5449 if (ev->type() == QEvent::InputMethodQuery) {
5450 QInputMethodQueryEvent *query = static_cast<QInputMethodQueryEvent *>(ev);
5451 Qt::InputMethodQueries queries = query->queries();
5452 for (uint i = 0; i < 32; ++i) {
5453 Qt::InputMethodQuery q = (Qt::InputMethodQuery)(int)(queries & (1<<i));
5455 QVariant v = inputMethodQuery(q);
5456 query->setValue(q, v);
5461 } else if (ev->type() == QEvent::InputMethod) {
5462 inputMethodEvent(static_cast<QInputMethodEvent *>(ev));
5465 return QObject::event(ev);
5468 #ifndef QT_NO_DEBUG_STREAM
5469 QDebug operator<<(QDebug debug, QQuickItem *item)
5472 debug << "QQuickItem(0)";
5476 debug << item->metaObject()->className() << "(this =" << ((void*)item)
5477 << ", name=" << item->objectName()
5478 << ", parent =" << ((void*)item->parentItem())
5479 << ", geometry =" << QRectF(item->pos(), QSizeF(item->width(), item->height()))
5480 << ", z =" << item->z() << ')';
5485 qint64 QQuickItemPrivate::consistentTime = -1;
5486 void QQuickItemPrivate::setConsistentTime(qint64 t)
5491 class QElapsedTimerConsistentTimeHack
5495 t1 = QQuickItemPrivate::consistentTime;
5499 return QQuickItemPrivate::consistentTime - t1;
5502 qint64 val = QQuickItemPrivate::consistentTime - t1;
5503 t1 = QQuickItemPrivate::consistentTime;
5513 void QQuickItemPrivate::start(QElapsedTimer &t)
5515 if (QQuickItemPrivate::consistentTime == -1)
5518 ((QElapsedTimerConsistentTimeHack*)&t)->start();
5521 qint64 QQuickItemPrivate::elapsed(QElapsedTimer &t)
5523 if (QQuickItemPrivate::consistentTime == -1)
5526 return ((QElapsedTimerConsistentTimeHack*)&t)->elapsed();
5529 qint64 QQuickItemPrivate::restart(QElapsedTimer &t)
5531 if (QQuickItemPrivate::consistentTime == -1)
5534 return ((QElapsedTimerConsistentTimeHack*)&t)->restart();
5538 \fn bool QQuickItem::isTextureProvider() const
5540 Returns true if this item is a texture provider. The default
5541 implementation returns false.
5543 This function can be called from any thread.
5546 bool QQuickItem::isTextureProvider() const
5548 Q_D(const QQuickItem);
5549 return d->extra.isAllocated() && d->extra->layer && d->extra->layer->effectSource() ?
5550 d->extra->layer->effectSource()->isTextureProvider() : false;
5554 \fn QSGTextureProvider *QQuickItem::textureProvider() const
5556 Returns the texture provider for an item. The default implementation
5559 This function may only be called on the rendering thread.
5562 QSGTextureProvider *QQuickItem::textureProvider() const
5564 Q_D(const QQuickItem);
5565 return d->extra.isAllocated() && d->extra->layer && d->extra->layer->effectSource() ?
5566 d->extra->layer->effectSource()->textureProvider() : 0;
5569 QQuickItemLayer *QQuickItemPrivate::layer() const
5571 if (!extra.isAllocated() || !extra->layer) {
5572 extra.value().layer = new QQuickItemLayer(const_cast<QQuickItem *>(q_func()));
5573 if (!componentComplete)
5574 extra->layer->classBegin();
5576 return extra->layer;
5579 QQuickItemLayer::QQuickItemLayer(QQuickItem *item)
5584 , m_componentComplete(true)
5585 , m_wrapMode(QQuickShaderEffectSource::ClampToEdge)
5586 , m_format(QQuickShaderEffectSource::RGBA)
5588 , m_effectComponent(0)
5594 QQuickItemLayer::~QQuickItemLayer()
5596 delete m_effectSource;
5603 \qmlproperty bool QtQuick2::Item::layer.enabled
5605 Holds wether the item is layered or not. Layering is disabled by default.
5607 A layered item is rendered into an offscreen surface and cached until
5608 it is changed. Enabling layering for complex QML item hierarchies can
5609 some times be an optimization.
5611 None of the other layer properties have any effect when the layer
5615 void QQuickItemLayer::setEnabled(bool e)
5620 if (m_componentComplete) {
5627 emit enabledChanged(e);
5630 void QQuickItemLayer::classBegin()
5632 Q_ASSERT(!m_effectSource);
5633 Q_ASSERT(!m_effect);
5634 m_componentComplete = false;
5637 void QQuickItemLayer::componentComplete()
5639 Q_ASSERT(!m_componentComplete);
5640 m_componentComplete = true;
5645 void QQuickItemLayer::activate()
5647 Q_ASSERT(!m_effectSource);
5648 m_effectSource = new QQuickShaderEffectSource();
5650 QQuickItem *parentItem = m_item->parentItem();
5652 m_effectSource->setParentItem(parentItem);
5653 m_effectSource->stackAfter(m_item);
5656 m_effectSource->setSourceItem(m_item);
5657 m_effectSource->setHideSource(true);
5658 m_effectSource->setSmooth(m_smooth);
5659 m_effectSource->setTextureSize(m_size);
5660 m_effectSource->setSourceRect(m_sourceRect);
5661 m_effectSource->setMipmap(m_mipmap);
5662 m_effectSource->setWrapMode(m_wrapMode);
5663 m_effectSource->setFormat(m_format);
5665 if (m_effectComponent)
5668 m_effectSource->setVisible(m_item->isVisible() && !m_effect);
5675 QQuickItemPrivate *id = QQuickItemPrivate::get(m_item);
5676 id->addItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Opacity | QQuickItemPrivate::Parent | QQuickItemPrivate::Visibility | QQuickItemPrivate::SiblingOrder);
5679 void QQuickItemLayer::deactivate()
5681 Q_ASSERT(m_effectSource);
5683 if (m_effectComponent)
5686 delete m_effectSource;
5689 QQuickItemPrivate *id = QQuickItemPrivate::get(m_item);
5690 id->removeItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Opacity | QQuickItemPrivate::Parent | QQuickItemPrivate::Visibility | QQuickItemPrivate::SiblingOrder);
5693 void QQuickItemLayer::activateEffect()
5695 Q_ASSERT(m_effectSource);
5696 Q_ASSERT(m_effectComponent);
5697 Q_ASSERT(!m_effect);
5699 QObject *created = m_effectComponent->create();
5700 m_effect = qobject_cast<QQuickItem *>(created);
5702 qWarning("Item: layer.effect is not a QML Item.");
5706 QQuickItem *parentItem = m_item->parentItem();
5708 m_effect->setParentItem(parentItem);
5709 m_effect->stackAfter(m_effectSource);
5711 m_effect->setVisible(m_item->isVisible());
5712 m_effect->setProperty(m_name, qVariantFromValue<QObject *>(m_effectSource));
5715 void QQuickItemLayer::deactivateEffect()
5717 Q_ASSERT(m_effectSource);
5718 Q_ASSERT(m_effectComponent);
5726 \qmlproperty Component QtQuick2::Item::layer.effect
5728 Holds the effect that is applied to this layer.
5730 The effect is typically a \l ShaderEffect component, although any \l Item component can be
5731 assigned. The effect should have a source texture property with a name matching \l samplerName.
5736 void QQuickItemLayer::setEffect(QQmlComponent *component)
5738 if (component == m_effectComponent)
5741 bool updateNeeded = false;
5742 if (m_effectSource && m_effectComponent) {
5744 updateNeeded = true;
5747 m_effectComponent = component;
5749 if (m_effectSource && m_effectComponent) {
5751 updateNeeded = true;
5759 m_effectSource->setVisible(m_item->isVisible() && !m_effect);
5762 emit effectChanged(component);
5767 \qmlproperty bool QtQuick2::Item::layer.mipmap
5769 If this property is true, mipmaps are generated for the texture.
5771 \note Some OpenGL ES 2 implementations do not support mipmapping of
5772 non-power-of-two textures.
5775 void QQuickItemLayer::setMipmap(bool mipmap)
5777 if (mipmap == m_mipmap)
5782 m_effectSource->setMipmap(m_mipmap);
5784 emit mipmapChanged(mipmap);
5789 \qmlproperty enumeration QtQuick2::Item::layer.format
5791 This property defines the internal OpenGL format of the texture.
5792 Modifying this property makes most sense when the \a layer.effect is also
5793 specified. Depending on the OpenGL implementation, this property might
5794 allow you to save some texture memory.
5797 \li ShaderEffectSource.Alpha - GL_ALPHA
5798 \li ShaderEffectSource.RGB - GL_RGB
5799 \li ShaderEffectSource.RGBA - GL_RGBA
5802 \note Some OpenGL implementations do not support the GL_ALPHA format.
5805 void QQuickItemLayer::setFormat(QQuickShaderEffectSource::Format f)
5812 m_effectSource->setFormat(m_format);
5814 emit formatChanged(m_format);
5819 \qmlproperty enumeration QtQuick2::Item::layer.sourceRect
5821 This property defines which rectangular area of the \l sourceItem to
5822 render into the texture. The source rectangle can be larger than
5823 \l sourceItem itself. If the rectangle is null, which is the default,
5824 the whole \l sourceItem is rendered to texture.
5827 void QQuickItemLayer::setSourceRect(const QRectF &sourceRect)
5829 if (sourceRect == m_sourceRect)
5831 m_sourceRect = sourceRect;
5834 m_effectSource->setSourceRect(m_sourceRect);
5836 emit sourceRectChanged(sourceRect);
5842 \qmlproperty bool QtQuick2::Item::layer.smooth
5844 Holds whether the layer is smoothly transformed.
5847 void QQuickItemLayer::setSmooth(bool s)
5854 m_effectSource->setSmooth(m_smooth);
5856 emit smoothChanged(s);
5862 \qmlproperty size QtQuick2::Item::layer.textureSize
5864 This property holds the requested pixel size of the layers texture. If it is empty,
5865 which is the default, the size of the item is used.
5867 \note Some platforms have a limit on how small framebuffer objects can be,
5868 which means the actual texture size might be larger than the requested
5872 void QQuickItemLayer::setSize(const QSize &size)
5879 m_effectSource->setTextureSize(size);
5881 emit sizeChanged(size);
5887 \qmlproperty enumeration QtQuick2::Item::layer.wrapMode
5889 This property defines the OpenGL wrap modes associated with the texture.
5890 Modifying this property makes most sense when the \a layer.effect is
5894 \li ShaderEffectSource.ClampToEdge - GL_CLAMP_TO_EDGE both horizontally and vertically
5895 \li ShaderEffectSource.RepeatHorizontally - GL_REPEAT horizontally, GL_CLAMP_TO_EDGE vertically
5896 \li ShaderEffectSource.RepeatVertically - GL_CLAMP_TO_EDGE horizontally, GL_REPEAT vertically
5897 \li ShaderEffectSource.Repeat - GL_REPEAT both horizontally and vertically
5900 \note Some OpenGL ES 2 implementations do not support the GL_REPEAT
5901 wrap mode with non-power-of-two textures.
5904 void QQuickItemLayer::setWrapMode(QQuickShaderEffectSource::WrapMode mode)
5906 if (mode == m_wrapMode)
5911 m_effectSource->setWrapMode(m_wrapMode);
5913 emit wrapModeChanged(mode);
5917 \qmlproperty string QtQuick2::Item::layer.samplerName
5919 Holds the name of the effect's source texture property.
5921 samplerName needs to match the name of the effect's source texture property
5922 so that the Item can pass the layer's offscreen surface to the effect correctly.
5924 \sa effect, ShaderEffect
5927 void QQuickItemLayer::setName(const QByteArray &name) {
5931 m_effect->setProperty(m_name, QVariant());
5932 m_effect->setProperty(name, qVariantFromValue<QObject *>(m_effectSource));
5935 emit nameChanged(name);
5938 void QQuickItemLayer::itemOpacityChanged(QQuickItem *item)
5944 void QQuickItemLayer::itemGeometryChanged(QQuickItem *, const QRectF &, const QRectF &)
5949 void QQuickItemLayer::itemParentChanged(QQuickItem *item, QQuickItem *parent)
5952 Q_ASSERT(item == m_item);
5953 Q_ASSERT(parent != m_effectSource);
5954 Q_ASSERT(parent == 0 || parent != m_effect);
5956 m_effectSource->setParentItem(parent);
5958 m_effectSource->stackAfter(m_item);
5961 m_effect->setParentItem(parent);
5963 m_effect->stackAfter(m_effectSource);
5967 void QQuickItemLayer::itemSiblingOrderChanged(QQuickItem *)
5969 m_effectSource->stackAfter(m_item);
5971 m_effect->stackAfter(m_effectSource);
5974 void QQuickItemLayer::itemVisibilityChanged(QQuickItem *)
5976 QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
5978 l->setVisible(m_item->isVisible());
5981 void QQuickItemLayer::updateZ()
5983 if (!m_componentComplete || !m_enabled)
5985 QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
5987 l->setZ(m_item->z());
5990 void QQuickItemLayer::updateOpacity()
5992 QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
5994 l->setOpacity(m_item->opacity());
5997 void QQuickItemLayer::updateGeometry()
5999 QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
6001 QRectF bounds = m_item->boundingRect();
6002 l->setWidth(bounds.width());
6003 l->setHeight(bounds.height());
6004 l->setX(bounds.x() + m_item->x());
6005 l->setY(bounds.y() + m_item->y());
6008 void QQuickItemLayer::updateMatrix()
6010 // Called directly from transformChanged(), so needs some extra
6012 if (!m_componentComplete || !m_enabled)
6014 QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
6016 QQuickItemPrivate *ld = QQuickItemPrivate::get(l);
6017 l->setScale(m_item->scale());
6018 l->setRotation(m_item->rotation());
6019 ld->transforms = QQuickItemPrivate::get(m_item)->transforms;
6020 if (ld->origin() != QQuickItemPrivate::get(m_item)->origin())
6021 ld->extra.value().origin = QQuickItemPrivate::get(m_item)->origin();
6022 ld->dirty(QQuickItemPrivate::Transform);
6025 QQuickItemPrivate::ExtraData::ExtraData()
6026 : z(0), scale(1), rotation(0), opacity(1),
6027 contents(0), screenAttached(0), layoutDirectionAttached(0),
6028 keyHandler(0), layer(0), effectRefCount(0), hideRefCount(0),
6029 opacityNode(0), clipNode(0), rootNode(0), beforePaintNode(0),
6030 acceptedMouseButtons(0), origin(QQuickItem::Center)
6036 #include <moc_qquickitem.cpp>