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 QtDeclarative 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 <QtDeclarative/qjsengine.h>
46 #include "qquickcanvas_p.h"
48 #include "qquickevents_p_p.h"
49 #include "qquickscreen_p.h"
51 #include <QtDeclarative/qdeclarativeengine.h>
52 #include <QtDeclarative/qdeclarativecomponent.h>
53 #include <QtDeclarative/qdeclarativeinfo.h>
54 #include <QtGui/qpen.h>
55 #include <QtGui/qcursor.h>
56 #include <QtGui/qguiapplication.h>
57 #include <QtGui/qinputmethod.h>
58 #include <QtCore/qdebug.h>
59 #include <QtCore/qcoreevent.h>
60 #include <QtCore/qnumeric.h>
62 #include <private/qdeclarativeengine_p.h>
63 #include <QtQuick/private/qdeclarativestategroup_p.h>
64 #include <private/qdeclarativeopenmetaobject_p.h>
65 #include <QtQuick/private/qdeclarativestate_p.h>
66 #include <private/qlistmodelinterface_p.h>
67 #include <private/qquickitem_p.h>
68 #include <private/qdeclarativeaccessors_p.h>
69 #include <QtQuick/private/qquickaccessibleattached_p.h>
73 // XXX todo Check that elements that create items handle memory correctly after visual ownership change
77 static void QQuickItem_parentNotifier(QObject *o, intptr_t, QDeclarativeNotifier **n)
79 QQuickItemPrivate *d = QQuickItemPrivate::get(static_cast<QQuickItem *>(o));
80 *n = &d->parentNotifier;
83 QML_PRIVATE_ACCESSOR(QQuickItem, QQuickItem *, parent, parentItem)
84 QML_PRIVATE_ACCESSOR(QQuickItem, qreal, x, x)
85 QML_PRIVATE_ACCESSOR(QQuickItem, qreal, y, y)
86 QML_PRIVATE_ACCESSOR(QQuickItem, qreal, width, width)
87 QML_PRIVATE_ACCESSOR(QQuickItem, qreal, height, height)
89 static QDeclarativeAccessors QQuickItem_parent = { QQuickItem_parentRead, QQuickItem_parentNotifier };
90 static QDeclarativeAccessors QQuickItem_x = { QQuickItem_xRead, 0 };
91 static QDeclarativeAccessors QQuickItem_y = { QQuickItem_yRead, 0 };
92 static QDeclarativeAccessors QQuickItem_width = { QQuickItem_widthRead, 0 };
93 static QDeclarativeAccessors QQuickItem_height = { QQuickItem_heightRead, 0 };
95 QML_DECLARE_PROPERTIES(QQuickItem) {
96 { QML_PROPERTY_NAME(parent), 0, &QQuickItem_parent },
97 { QML_PROPERTY_NAME(x), 0, &QQuickItem_x },
98 { QML_PROPERTY_NAME(y), 0, &QQuickItem_y },
99 { QML_PROPERTY_NAME(width), 0, &QQuickItem_width },
100 { QML_PROPERTY_NAME(height), 0, &QQuickItem_height }
103 void QQuickItemPrivate::registerAccessorProperties()
105 QML_DEFINE_PROPERTIES(QQuickItem);
109 \qmlclass Transform QQuickTransform
110 \inqmlmodule QtQuick 2
111 \ingroup qml-transform-elements
112 \brief The Transform elements provide a way of building advanced transformations on Items.
114 The Transform element is a base type which cannot be instantiated directly.
115 The following concrete Transform types are available:
123 The Transform elements let you create and control advanced transformations that can be configured
124 independently using specialized properties.
126 You can assign any number of Transform elements to an \l Item. Each Transform is applied in order,
131 \qmlclass Translate QQuickTranslate
132 \inqmlmodule QtQuick 2
133 \ingroup qml-transform-elements
134 \brief The Translate object provides a way to move an Item without changing its x or y properties.
136 The Translate object provides independent control over position in addition to the Item's x and y properties.
138 The following example moves the Y axis of the \l Rectangle elements while still allowing the \l Row element
139 to lay the items out as if they had not been transformed:
145 width: 100; height: 100
147 transform: Translate { y: 20 }
150 width: 100; height: 100
152 transform: Translate { y: -20 }
161 \qmlproperty real QtQuick2::Translate::x
163 The translation along the X axis.
167 \qmlproperty real QtQuick2::Translate::y
169 The translation along the Y axis.
173 \qmlclass Scale QQuickScale
174 \inqmlmodule QtQuick 2
175 \ingroup qml-transform-elements
176 \brief The Scale element provides a way to scale an Item.
178 The Scale element gives more control over scaling than using \l Item's \l{Item::scale}{scale} property. Specifically,
179 it allows a different scale for the x and y axes, and allows the scale to be relative to an
182 The following example scales the X axis of the Rectangle, relative to its interior point 25, 25:
185 width: 100; height: 100
187 transform: Scale { origin.x: 25; origin.y: 25; xScale: 3}
191 \sa Rotation, Translate
195 \qmlproperty real QtQuick2::Scale::origin.x
196 \qmlproperty real QtQuick2::Scale::origin.y
198 The point that the item is scaled from (i.e., the point that stays fixed relative to the parent as
199 the rest of the item grows). By default the origin is 0, 0.
203 \qmlproperty real QtQuick2::Scale::xScale
205 The scaling factor for the X axis.
209 \qmlproperty real QtQuick2::Scale::yScale
211 The scaling factor for the Y axis.
215 \qmlclass Rotation QQuickRotation
216 \inqmlmodule QtQuick 2
217 \ingroup qml-transform-elements
218 \brief The Rotation object provides a way to rotate an Item.
220 The Rotation object gives more control over rotation than using \l Item's \l{Item::rotation}{rotation} property.
221 Specifically, it allows (z axis) rotation to be relative to an arbitrary point.
223 The following example rotates a Rectangle around its interior point 25, 25:
226 width: 100; height: 100
228 transform: Rotation { origin.x: 25; origin.y: 25; angle: 45}
232 Rotation also provides a way to specify 3D-like rotations for Items. For these types of
233 rotations you must specify the axis to rotate around in addition to the origin point.
235 The following example shows various 3D-like rotations applied to an \l Image.
236 \snippet doc/src/snippets/declarative/rotation.qml 0
238 \image axisrotation.png
240 \sa {declarative/ui-components/dialcontrol}{Dial Control example}, {declarative/toys/clocks}{Clocks example}
244 \qmlproperty real QtQuick2::Rotation::origin.x
245 \qmlproperty real QtQuick2::Rotation::origin.y
247 The origin point of the rotation (i.e., the point that stays fixed relative to the parent as
248 the rest of the item rotates). By default the origin is 0, 0.
252 \qmlproperty real QtQuick2::Rotation::axis.x
253 \qmlproperty real QtQuick2::Rotation::axis.y
254 \qmlproperty real QtQuick2::Rotation::axis.z
256 The axis to rotate around. For simple (2D) rotation around a point, you do not need to specify an axis,
257 as the default axis is the z axis (\c{ axis { x: 0; y: 0; z: 1 } }).
259 For a typical 3D-like rotation you will usually specify both the origin and the axis.
261 \image 3d-rotation-axis.png
265 \qmlproperty real QtQuick2::Rotation::angle
267 The angle to rotate, in degrees clockwise.
270 QQuickTransformPrivate::QQuickTransformPrivate()
274 QQuickTransform::QQuickTransform(QObject *parent)
275 : QObject(*(new QQuickTransformPrivate), parent)
279 QQuickTransform::QQuickTransform(QQuickTransformPrivate &dd, QObject *parent)
280 : QObject(dd, parent)
284 QQuickTransform::~QQuickTransform()
286 Q_D(QQuickTransform);
287 for (int ii = 0; ii < d->items.count(); ++ii) {
288 QQuickItemPrivate *p = QQuickItemPrivate::get(d->items.at(ii));
289 p->transforms.removeOne(this);
290 p->dirty(QQuickItemPrivate::Transform);
294 void QQuickTransform::update()
296 Q_D(QQuickTransform);
297 for (int ii = 0; ii < d->items.count(); ++ii) {
298 QQuickItemPrivate *p = QQuickItemPrivate::get(d->items.at(ii));
299 p->dirty(QQuickItemPrivate::Transform);
303 QQuickContents::QQuickContents(QQuickItem *item)
304 : m_item(item), m_x(0), m_y(0), m_width(0), m_height(0)
308 QQuickContents::~QQuickContents()
310 QList<QQuickItem *> children = m_item->childItems();
311 for (int i = 0; i < children.count(); ++i) {
312 QQuickItem *child = children.at(i);
313 QQuickItemPrivate::get(child)->removeItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed);
317 bool QQuickContents::calcHeight(QQuickItem *changed)
320 qreal oldheight = m_height;
324 qreal bottom = oldy + oldheight;
325 qreal y = changed->y();
326 if (y + changed->height() > bottom)
327 bottom = y + changed->height();
331 m_height = bottom - top;
335 QList<QQuickItem *> children = m_item->childItems();
336 for (int i = 0; i < children.count(); ++i) {
337 QQuickItem *child = children.at(i);
338 qreal y = child->y();
339 if (y + child->height() > bottom)
340 bottom = y + child->height();
344 if (!children.isEmpty())
346 m_height = qMax(bottom - top, qreal(0.0));
349 return (m_height != oldheight || m_y != oldy);
352 bool QQuickContents::calcWidth(QQuickItem *changed)
355 qreal oldwidth = m_width;
359 qreal right = oldx + oldwidth;
360 qreal x = changed->x();
361 if (x + changed->width() > right)
362 right = x + changed->width();
366 m_width = right - left;
368 qreal left = FLT_MAX;
370 QList<QQuickItem *> children = m_item->childItems();
371 for (int i = 0; i < children.count(); ++i) {
372 QQuickItem *child = children.at(i);
373 qreal x = child->x();
374 if (x + child->width() > right)
375 right = x + child->width();
379 if (!children.isEmpty())
381 m_width = qMax(right - left, qreal(0.0));
384 return (m_width != oldwidth || m_x != oldx);
387 void QQuickContents::complete()
389 QQuickItemPrivate::get(m_item)->addItemChangeListener(this, QQuickItemPrivate::Children);
391 QList<QQuickItem *> children = m_item->childItems();
392 for (int i = 0; i < children.count(); ++i) {
393 QQuickItem *child = children.at(i);
394 QQuickItemPrivate::get(child)->addItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed);
395 //###what about changes to visibility?
400 void QQuickContents::updateRect()
402 QQuickItemPrivate::get(m_item)->emitChildrenRectChanged(rectF());
405 void QQuickContents::itemGeometryChanged(QQuickItem *changed, const QRectF &newGeometry, const QRectF &oldGeometry)
408 bool wChanged = false;
409 bool hChanged = false;
410 //### we can only pass changed if the left edge has moved left, or the right edge has moved right
411 if (newGeometry.width() != oldGeometry.width() || newGeometry.x() != oldGeometry.x())
412 wChanged = calcWidth(/*changed*/);
413 if (newGeometry.height() != oldGeometry.height() || newGeometry.y() != oldGeometry.y())
414 hChanged = calcHeight(/*changed*/);
415 if (wChanged || hChanged)
419 void QQuickContents::itemDestroyed(QQuickItem *item)
422 QQuickItemPrivate::get(item)->removeItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed);
426 void QQuickContents::itemChildRemoved(QQuickItem *, QQuickItem *item)
429 QQuickItemPrivate::get(item)->removeItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed);
433 void QQuickContents::itemChildAdded(QQuickItem *, QQuickItem *item)
436 QQuickItemPrivate::get(item)->addItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed);
440 QQuickItemKeyFilter::QQuickItemKeyFilter(QQuickItem *item)
441 : m_processPost(false), m_next(0)
443 QQuickItemPrivate *p = item?QQuickItemPrivate::get(item):0;
445 m_next = p->extra.value().keyHandler;
446 p->extra->keyHandler = this;
450 QQuickItemKeyFilter::~QQuickItemKeyFilter()
454 void QQuickItemKeyFilter::keyPressed(QKeyEvent *event, bool post)
456 if (m_next) m_next->keyPressed(event, post);
459 void QQuickItemKeyFilter::keyReleased(QKeyEvent *event, bool post)
461 if (m_next) m_next->keyReleased(event, post);
464 void QQuickItemKeyFilter::inputMethodEvent(QInputMethodEvent *event, bool post)
467 m_next->inputMethodEvent(event, post);
472 QVariant QQuickItemKeyFilter::inputMethodQuery(Qt::InputMethodQuery query) const
474 if (m_next) return m_next->inputMethodQuery(query);
478 void QQuickItemKeyFilter::componentComplete()
480 if (m_next) m_next->componentComplete();
483 \qmlclass KeyNavigation QQuickKeyNavigationAttached
484 \inqmlmodule QtQuick 2
485 \ingroup qml-basic-interaction-elements
486 \brief The KeyNavigation attached property supports key navigation by arrow keys.
488 Key-based user interfaces commonly allow the use of arrow keys to navigate between
489 focusable items. The KeyNavigation attached property enables this behavior by providing a
490 convenient way to specify the item that should gain focus when an arrow or tab key is pressed.
492 The following example provides key navigation for a 2x2 grid of items:
494 \snippet doc/src/snippets/declarative/keynavigation.qml 0
496 The top-left item initially receives focus by setting \l {Item::}{focus} to
497 \c true. When an arrow key is pressed, the focus will move to the
498 appropriate item, as defined by the value that has been set for
499 the KeyNavigation \l left, \l right, \l up or \l down properties.
501 Note that if a KeyNavigation attached property receives the key press and release
502 events for a requested arrow or tab key, the event is accepted and does not
503 propagate any further.
505 By default, KeyNavigation receives key events after the item to which it is attached.
506 If the item accepts the key event, the KeyNavigation attached property will not
507 receive an event for that key. Setting the \l priority property to
508 \c KeyNavigation.BeforeItem allows the event to be used for key navigation
509 before the item, rather than after.
511 If item to which the focus is switching is not enabled or visible, an attempt will
512 be made to skip this item and focus on the next. This is possible if there are
513 a chain of items with the same KeyNavigation handler. If multiple items in a row are not enabled
514 or visible, they will also be skipped.
516 KeyNavigation will implicitly set the other direction to return focus to this item. So if you set
517 \l left to another item, \l right will be set on that item's KeyNavigation to set focus back to this
518 item. However, if that item's KeyNavigation has had right explicitly set then no change will occur.
519 This means that the above example could have been written, with the same behaviour, without specifing
520 KeyNavigation.right or KeyNavigation.down for any of the items.
522 \sa {Keys}{Keys attached property}
526 \qmlproperty Item QtQuick2::KeyNavigation::left
527 \qmlproperty Item QtQuick2::KeyNavigation::right
528 \qmlproperty Item QtQuick2::KeyNavigation::up
529 \qmlproperty Item QtQuick2::KeyNavigation::down
530 \qmlproperty Item QtQuick2::KeyNavigation::tab
531 \qmlproperty Item QtQuick2::KeyNavigation::backtab
533 These properties hold the item to assign focus to
534 when the left, right, up or down cursor keys, or the
539 \qmlproperty Item QtQuick2::KeyNavigation::tab
540 \qmlproperty Item QtQuick2::KeyNavigation::backtab
542 These properties hold the item to assign focus to
543 when the Tab key or Shift+Tab key combination (Backtab) are pressed.
546 QQuickKeyNavigationAttached::QQuickKeyNavigationAttached(QObject *parent)
547 : QObject(*(new QQuickKeyNavigationAttachedPrivate), parent),
548 QQuickItemKeyFilter(qobject_cast<QQuickItem*>(parent))
550 m_processPost = true;
553 QQuickKeyNavigationAttached *
554 QQuickKeyNavigationAttached::qmlAttachedProperties(QObject *obj)
556 return new QQuickKeyNavigationAttached(obj);
559 QQuickItem *QQuickKeyNavigationAttached::left() const
561 Q_D(const QQuickKeyNavigationAttached);
565 void QQuickKeyNavigationAttached::setLeft(QQuickItem *i)
567 Q_D(QQuickKeyNavigationAttached);
572 QQuickKeyNavigationAttached* other =
573 qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
574 if (other && !other->d_func()->rightSet){
575 other->d_func()->right = qobject_cast<QQuickItem*>(parent());
576 emit other->rightChanged();
581 QQuickItem *QQuickKeyNavigationAttached::right() const
583 Q_D(const QQuickKeyNavigationAttached);
587 void QQuickKeyNavigationAttached::setRight(QQuickItem *i)
589 Q_D(QQuickKeyNavigationAttached);
594 QQuickKeyNavigationAttached* other =
595 qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
596 if (other && !other->d_func()->leftSet){
597 other->d_func()->left = qobject_cast<QQuickItem*>(parent());
598 emit other->leftChanged();
603 QQuickItem *QQuickKeyNavigationAttached::up() const
605 Q_D(const QQuickKeyNavigationAttached);
609 void QQuickKeyNavigationAttached::setUp(QQuickItem *i)
611 Q_D(QQuickKeyNavigationAttached);
616 QQuickKeyNavigationAttached* other =
617 qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
618 if (other && !other->d_func()->downSet){
619 other->d_func()->down = qobject_cast<QQuickItem*>(parent());
620 emit other->downChanged();
625 QQuickItem *QQuickKeyNavigationAttached::down() const
627 Q_D(const QQuickKeyNavigationAttached);
631 void QQuickKeyNavigationAttached::setDown(QQuickItem *i)
633 Q_D(QQuickKeyNavigationAttached);
638 QQuickKeyNavigationAttached* other =
639 qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
640 if (other && !other->d_func()->upSet) {
641 other->d_func()->up = qobject_cast<QQuickItem*>(parent());
642 emit other->upChanged();
647 QQuickItem *QQuickKeyNavigationAttached::tab() const
649 Q_D(const QQuickKeyNavigationAttached);
653 void QQuickKeyNavigationAttached::setTab(QQuickItem *i)
655 Q_D(QQuickKeyNavigationAttached);
660 QQuickKeyNavigationAttached* other =
661 qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
662 if (other && !other->d_func()->backtabSet) {
663 other->d_func()->backtab = qobject_cast<QQuickItem*>(parent());
664 emit other->backtabChanged();
669 QQuickItem *QQuickKeyNavigationAttached::backtab() const
671 Q_D(const QQuickKeyNavigationAttached);
675 void QQuickKeyNavigationAttached::setBacktab(QQuickItem *i)
677 Q_D(QQuickKeyNavigationAttached);
681 d->backtabSet = true;
682 QQuickKeyNavigationAttached* other =
683 qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
684 if (other && !other->d_func()->tabSet) {
685 other->d_func()->tab = qobject_cast<QQuickItem*>(parent());
686 emit other->tabChanged();
688 emit backtabChanged();
692 \qmlproperty enumeration QtQuick2::KeyNavigation::priority
694 This property determines whether the keys are processed before
695 or after the attached item's own key handling.
698 \o KeyNavigation.BeforeItem - process the key events before normal
699 item key processing. If the event is used for key navigation, it will be accepted and will not
700 be passed on to the item.
701 \o KeyNavigation.AfterItem (default) - process the key events after normal item key
702 handling. If the item accepts the key event it will not be
703 handled by the KeyNavigation attached property handler.
706 QQuickKeyNavigationAttached::Priority QQuickKeyNavigationAttached::priority() const
708 return m_processPost ? AfterItem : BeforeItem;
711 void QQuickKeyNavigationAttached::setPriority(Priority order)
713 bool processPost = order == AfterItem;
714 if (processPost != m_processPost) {
715 m_processPost = processPost;
716 emit priorityChanged();
720 void QQuickKeyNavigationAttached::keyPressed(QKeyEvent *event, bool post)
722 Q_D(QQuickKeyNavigationAttached);
725 if (post != m_processPost) {
726 QQuickItemKeyFilter::keyPressed(event, post);
731 switch (event->key()) {
733 if (QQuickItem *parentItem = qobject_cast<QQuickItem*>(parent()))
734 mirror = QQuickItemPrivate::get(parentItem)->effectiveLayoutMirror;
735 QQuickItem* leftItem = mirror ? d->right : d->left;
737 setFocusNavigation(leftItem, mirror ? "right" : "left");
742 case Qt::Key_Right: {
743 if (QQuickItem *parentItem = qobject_cast<QQuickItem*>(parent()))
744 mirror = QQuickItemPrivate::get(parentItem)->effectiveLayoutMirror;
745 QQuickItem* rightItem = mirror ? d->left : d->right;
747 setFocusNavigation(rightItem, mirror ? "left" : "right");
754 setFocusNavigation(d->up, "up");
760 setFocusNavigation(d->down, "down");
766 setFocusNavigation(d->tab, "tab");
770 case Qt::Key_Backtab:
772 setFocusNavigation(d->backtab, "backtab");
780 if (!event->isAccepted()) QQuickItemKeyFilter::keyPressed(event, post);
783 void QQuickKeyNavigationAttached::keyReleased(QKeyEvent *event, bool post)
785 Q_D(QQuickKeyNavigationAttached);
788 if (post != m_processPost) {
789 QQuickItemKeyFilter::keyReleased(event, post);
794 switch (event->key()) {
796 if (QQuickItem *parentItem = qobject_cast<QQuickItem*>(parent()))
797 mirror = QQuickItemPrivate::get(parentItem)->effectiveLayoutMirror;
798 if (mirror ? d->right : d->left)
802 if (QQuickItem *parentItem = qobject_cast<QQuickItem*>(parent()))
803 mirror = QQuickItemPrivate::get(parentItem)->effectiveLayoutMirror;
804 if (mirror ? d->left : d->right)
822 case Qt::Key_Backtab:
831 if (!event->isAccepted()) QQuickItemKeyFilter::keyReleased(event, post);
834 void QQuickKeyNavigationAttached::setFocusNavigation(QQuickItem *currentItem, const char *dir)
836 QQuickItem *initialItem = currentItem;
837 bool isNextItem = false;
840 if (currentItem->isVisible() && currentItem->isEnabled()) {
841 currentItem->setFocus(true);
844 qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(currentItem, false);
846 QQuickItem *tempItem = qvariant_cast<QQuickItem*>(attached->property(dir));
848 currentItem = tempItem;
854 while (currentItem != initialItem && isNextItem);
857 const QQuickKeysAttached::SigMap QQuickKeysAttached::sigMap[] = {
858 { Qt::Key_Left, "leftPressed" },
859 { Qt::Key_Right, "rightPressed" },
860 { Qt::Key_Up, "upPressed" },
861 { Qt::Key_Down, "downPressed" },
862 { Qt::Key_Tab, "tabPressed" },
863 { Qt::Key_Backtab, "backtabPressed" },
864 { Qt::Key_Asterisk, "asteriskPressed" },
865 { Qt::Key_NumberSign, "numberSignPressed" },
866 { Qt::Key_Escape, "escapePressed" },
867 { Qt::Key_Return, "returnPressed" },
868 { Qt::Key_Enter, "enterPressed" },
869 { Qt::Key_Delete, "deletePressed" },
870 { Qt::Key_Space, "spacePressed" },
871 { Qt::Key_Back, "backPressed" },
872 { Qt::Key_Cancel, "cancelPressed" },
873 { Qt::Key_Select, "selectPressed" },
874 { Qt::Key_Yes, "yesPressed" },
875 { Qt::Key_No, "noPressed" },
876 { Qt::Key_Context1, "context1Pressed" },
877 { Qt::Key_Context2, "context2Pressed" },
878 { Qt::Key_Context3, "context3Pressed" },
879 { Qt::Key_Context4, "context4Pressed" },
880 { Qt::Key_Call, "callPressed" },
881 { Qt::Key_Hangup, "hangupPressed" },
882 { Qt::Key_Flip, "flipPressed" },
883 { Qt::Key_Menu, "menuPressed" },
884 { Qt::Key_VolumeUp, "volumeUpPressed" },
885 { Qt::Key_VolumeDown, "volumeDownPressed" },
889 bool QQuickKeysAttachedPrivate::isConnected(const char *signalName)
891 return isSignalConnected(signalIndex(signalName));
895 \qmlclass Keys QQuickKeysAttached
896 \inqmlmodule QtQuick 2
897 \ingroup qml-basic-interaction-elements
898 \brief The Keys attached property provides key handling to Items.
900 All visual primitives support key handling via the Keys
901 attached property. Keys can be handled via the onPressed
902 and onReleased signal properties.
904 The signal properties have a \l KeyEvent parameter, named
905 \e event which contains details of the event. If a key is
906 handled \e event.accepted should be set to true to prevent the
907 event from propagating up the item hierarchy.
909 \section1 Example Usage
911 The following example shows how the general onPressed handler can
912 be used to test for a certain key; in this case, the left cursor
915 \snippet doc/src/snippets/declarative/keys/keys-pressed.qml key item
917 Some keys may alternatively be handled via specific signal properties,
918 for example \e onSelectPressed. These handlers automatically set
919 \e event.accepted to true.
921 \snippet doc/src/snippets/declarative/keys/keys-handler.qml key item
923 See \l{Qt::Key}{Qt.Key} for the list of keyboard codes.
925 \section1 Key Handling Priorities
927 The Keys attached property can be configured to handle key events
928 before or after the item it is attached to. This makes it possible
929 to intercept events in order to override an item's default behavior,
930 or act as a fallback for keys not handled by the item.
932 If \l priority is Keys.BeforeItem (default) the order of key event processing is:
935 \o Items specified in \c forwardTo
936 \o specific key handlers, e.g. onReturnPressed
937 \o onKeyPress, onKeyRelease handlers
938 \o Item specific key handling, e.g. TextInput key handling
942 If priority is Keys.AfterItem the order of key event processing is:
945 \o Item specific key handling, e.g. TextInput key handling
946 \o Items specified in \c forwardTo
947 \o specific key handlers, e.g. onReturnPressed
948 \o onKeyPress, onKeyRelease handlers
952 If the event is accepted during any of the above steps, key
955 \sa KeyEvent, {KeyNavigation}{KeyNavigation attached property}
959 \qmlproperty bool QtQuick2::Keys::enabled
961 This flags enables key handling if true (default); otherwise
962 no key handlers will be called.
966 \qmlproperty enumeration QtQuick2::Keys::priority
968 This property determines whether the keys are processed before
969 or after the attached item's own key handling.
972 \o Keys.BeforeItem (default) - process the key events before normal
973 item key processing. If the event is accepted it will not
974 be passed on to the item.
975 \o Keys.AfterItem - process the key events after normal item key
976 handling. If the item accepts the key event it will not be
977 handled by the Keys attached property handler.
982 \qmlproperty list<Object> QtQuick2::Keys::forwardTo
984 This property provides a way to forward key presses, key releases, and keyboard input
985 coming from input methods to other items. This can be useful when you want
986 one item to handle some keys (e.g. the up and down arrow keys), and another item to
987 handle other keys (e.g. the left and right arrow keys). Once an item that has been
988 forwarded keys accepts the event it is no longer forwarded to items later in the
991 This example forwards key events to two lists:
1002 Keys.forwardTo: [list1, list2]
1009 \qmlsignal QtQuick2::Keys::onPressed(KeyEvent event)
1011 This handler is called when a key has been pressed. The \a event
1012 parameter provides information about the event.
1016 \qmlsignal QtQuick2::Keys::onReleased(KeyEvent event)
1018 This handler is called when a key has been released. The \a event
1019 parameter provides information about the event.
1023 \qmlsignal QtQuick2::Keys::onDigit0Pressed(KeyEvent event)
1025 This handler is called when the digit '0' has been pressed. The \a event
1026 parameter provides information about the event.
1030 \qmlsignal QtQuick2::Keys::onDigit1Pressed(KeyEvent event)
1032 This handler is called when the digit '1' has been pressed. The \a event
1033 parameter provides information about the event.
1037 \qmlsignal QtQuick2::Keys::onDigit2Pressed(KeyEvent event)
1039 This handler is called when the digit '2' has been pressed. The \a event
1040 parameter provides information about the event.
1044 \qmlsignal QtQuick2::Keys::onDigit3Pressed(KeyEvent event)
1046 This handler is called when the digit '3' has been pressed. The \a event
1047 parameter provides information about the event.
1051 \qmlsignal QtQuick2::Keys::onDigit4Pressed(KeyEvent event)
1053 This handler is called when the digit '4' has been pressed. The \a event
1054 parameter provides information about the event.
1058 \qmlsignal QtQuick2::Keys::onDigit5Pressed(KeyEvent event)
1060 This handler is called when the digit '5' has been pressed. The \a event
1061 parameter provides information about the event.
1065 \qmlsignal QtQuick2::Keys::onDigit6Pressed(KeyEvent event)
1067 This handler is called when the digit '6' has been pressed. The \a event
1068 parameter provides information about the event.
1072 \qmlsignal QtQuick2::Keys::onDigit7Pressed(KeyEvent event)
1074 This handler is called when the digit '7' has been pressed. The \a event
1075 parameter provides information about the event.
1079 \qmlsignal QtQuick2::Keys::onDigit8Pressed(KeyEvent event)
1081 This handler is called when the digit '8' has been pressed. The \a event
1082 parameter provides information about the event.
1086 \qmlsignal QtQuick2::Keys::onDigit9Pressed(KeyEvent event)
1088 This handler is called when the digit '9' has been pressed. The \a event
1089 parameter provides information about the event.
1093 \qmlsignal QtQuick2::Keys::onLeftPressed(KeyEvent event)
1095 This handler is called when the Left arrow has been pressed. The \a event
1096 parameter provides information about the event.
1100 \qmlsignal QtQuick2::Keys::onRightPressed(KeyEvent event)
1102 This handler is called when the Right arrow has been pressed. The \a event
1103 parameter provides information about the event.
1107 \qmlsignal QtQuick2::Keys::onUpPressed(KeyEvent event)
1109 This handler is called when the Up arrow has been pressed. The \a event
1110 parameter provides information about the event.
1114 \qmlsignal QtQuick2::Keys::onDownPressed(KeyEvent event)
1116 This handler is called when the Down arrow has been pressed. The \a event
1117 parameter provides information about the event.
1121 \qmlsignal QtQuick2::Keys::onTabPressed(KeyEvent event)
1123 This handler is called when the Tab key has been pressed. The \a event
1124 parameter provides information about the event.
1128 \qmlsignal QtQuick2::Keys::onBacktabPressed(KeyEvent event)
1130 This handler is called when the Shift+Tab key combination (Backtab) has
1131 been pressed. The \a event parameter provides information about the event.
1135 \qmlsignal QtQuick2::Keys::onAsteriskPressed(KeyEvent event)
1137 This handler is called when the Asterisk '*' has been pressed. The \a event
1138 parameter provides information about the event.
1142 \qmlsignal QtQuick2::Keys::onEscapePressed(KeyEvent event)
1144 This handler is called when the Escape key has been pressed. The \a event
1145 parameter provides information about the event.
1149 \qmlsignal QtQuick2::Keys::onReturnPressed(KeyEvent event)
1151 This handler is called when the Return key has been pressed. The \a event
1152 parameter provides information about the event.
1156 \qmlsignal QtQuick2::Keys::onEnterPressed(KeyEvent event)
1158 This handler is called when the Enter key has been pressed. The \a event
1159 parameter provides information about the event.
1163 \qmlsignal QtQuick2::Keys::onDeletePressed(KeyEvent event)
1165 This handler is called when the Delete key has been pressed. The \a event
1166 parameter provides information about the event.
1170 \qmlsignal QtQuick2::Keys::onSpacePressed(KeyEvent event)
1172 This handler is called when the Space key has been pressed. The \a event
1173 parameter provides information about the event.
1177 \qmlsignal QtQuick2::Keys::onBackPressed(KeyEvent event)
1179 This handler is called when the Back key has been pressed. The \a event
1180 parameter provides information about the event.
1184 \qmlsignal QtQuick2::Keys::onCancelPressed(KeyEvent event)
1186 This handler is called when the Cancel key has been pressed. The \a event
1187 parameter provides information about the event.
1191 \qmlsignal QtQuick2::Keys::onSelectPressed(KeyEvent event)
1193 This handler is called when the Select key has been pressed. The \a event
1194 parameter provides information about the event.
1198 \qmlsignal QtQuick2::Keys::onYesPressed(KeyEvent event)
1200 This handler is called when the Yes key has been pressed. The \a event
1201 parameter provides information about the event.
1205 \qmlsignal QtQuick2::Keys::onNoPressed(KeyEvent event)
1207 This handler is called when the No key has been pressed. The \a event
1208 parameter provides information about the event.
1212 \qmlsignal QtQuick2::Keys::onContext1Pressed(KeyEvent event)
1214 This handler is called when the Context1 key has been pressed. The \a event
1215 parameter provides information about the event.
1219 \qmlsignal QtQuick2::Keys::onContext2Pressed(KeyEvent event)
1221 This handler is called when the Context2 key has been pressed. The \a event
1222 parameter provides information about the event.
1226 \qmlsignal QtQuick2::Keys::onContext3Pressed(KeyEvent event)
1228 This handler is called when the Context3 key has been pressed. The \a event
1229 parameter provides information about the event.
1233 \qmlsignal QtQuick2::Keys::onContext4Pressed(KeyEvent event)
1235 This handler is called when the Context4 key has been pressed. The \a event
1236 parameter provides information about the event.
1240 \qmlsignal QtQuick2::Keys::onCallPressed(KeyEvent event)
1242 This handler is called when the Call key has been pressed. The \a event
1243 parameter provides information about the event.
1247 \qmlsignal QtQuick2::Keys::onHangupPressed(KeyEvent event)
1249 This handler is called when the Hangup key has been pressed. The \a event
1250 parameter provides information about the event.
1254 \qmlsignal QtQuick2::Keys::onFlipPressed(KeyEvent event)
1256 This handler is called when the Flip key has been pressed. The \a event
1257 parameter provides information about the event.
1261 \qmlsignal QtQuick2::Keys::onMenuPressed(KeyEvent event)
1263 This handler is called when the Menu key has been pressed. The \a event
1264 parameter provides information about the event.
1268 \qmlsignal QtQuick2::Keys::onVolumeUpPressed(KeyEvent event)
1270 This handler is called when the VolumeUp key has been pressed. The \a event
1271 parameter provides information about the event.
1275 \qmlsignal QtQuick2::Keys::onVolumeDownPressed(KeyEvent event)
1277 This handler is called when the VolumeDown key has been pressed. The \a event
1278 parameter provides information about the event.
1281 QQuickKeysAttached::QQuickKeysAttached(QObject *parent)
1282 : QObject(*(new QQuickKeysAttachedPrivate), parent),
1283 QQuickItemKeyFilter(qobject_cast<QQuickItem*>(parent))
1285 Q_D(QQuickKeysAttached);
1286 m_processPost = false;
1287 d->item = qobject_cast<QQuickItem*>(parent);
1290 QQuickKeysAttached::~QQuickKeysAttached()
1294 QQuickKeysAttached::Priority QQuickKeysAttached::priority() const
1296 return m_processPost ? AfterItem : BeforeItem;
1299 void QQuickKeysAttached::setPriority(Priority order)
1301 bool processPost = order == AfterItem;
1302 if (processPost != m_processPost) {
1303 m_processPost = processPost;
1304 emit priorityChanged();
1308 void QQuickKeysAttached::componentComplete()
1310 Q_D(QQuickKeysAttached);
1312 for (int ii = 0; ii < d->targets.count(); ++ii) {
1313 QQuickItem *targetItem = d->targets.at(ii);
1314 if (targetItem && (targetItem->flags() & QQuickItem::ItemAcceptsInputMethod)) {
1315 d->item->setFlag(QQuickItem::ItemAcceptsInputMethod);
1322 void QQuickKeysAttached::keyPressed(QKeyEvent *event, bool post)
1324 Q_D(QQuickKeysAttached);
1325 if (post != m_processPost || !d->enabled || d->inPress) {
1327 QQuickItemKeyFilter::keyPressed(event, post);
1331 // first process forwards
1332 if (d->item && d->item->canvas()) {
1334 for (int ii = 0; ii < d->targets.count(); ++ii) {
1335 QQuickItem *i = d->targets.at(ii);
1336 if (i && i->isVisible()) {
1337 d->item->canvas()->sendEvent(i, event);
1338 if (event->isAccepted()) {
1347 QQuickKeyEvent ke(*event);
1348 QByteArray keySignal = keyToSignal(event->key());
1349 if (!keySignal.isEmpty()) {
1350 keySignal += "(QQuickKeyEvent*)";
1351 if (d->isConnected(keySignal)) {
1352 // If we specifically handle a key then default to accepted
1353 ke.setAccepted(true);
1354 int idx = QQuickKeysAttached::staticMetaObject.indexOfSignal(keySignal);
1355 metaObject()->method(idx).invoke(this, Qt::DirectConnection, Q_ARG(QQuickKeyEvent*, &ke));
1358 if (!ke.isAccepted())
1360 event->setAccepted(ke.isAccepted());
1362 if (!event->isAccepted()) QQuickItemKeyFilter::keyPressed(event, post);
1365 void QQuickKeysAttached::keyReleased(QKeyEvent *event, bool post)
1367 Q_D(QQuickKeysAttached);
1368 if (post != m_processPost || !d->enabled || d->inRelease) {
1370 QQuickItemKeyFilter::keyReleased(event, post);
1374 if (d->item && d->item->canvas()) {
1375 d->inRelease = true;
1376 for (int ii = 0; ii < d->targets.count(); ++ii) {
1377 QQuickItem *i = d->targets.at(ii);
1378 if (i && i->isVisible()) {
1379 d->item->canvas()->sendEvent(i, event);
1380 if (event->isAccepted()) {
1381 d->inRelease = false;
1386 d->inRelease = false;
1389 QQuickKeyEvent ke(*event);
1391 event->setAccepted(ke.isAccepted());
1393 if (!event->isAccepted()) QQuickItemKeyFilter::keyReleased(event, post);
1396 void QQuickKeysAttached::inputMethodEvent(QInputMethodEvent *event, bool post)
1398 Q_D(QQuickKeysAttached);
1399 if (post == m_processPost && d->item && !d->inIM && d->item->canvas()) {
1401 for (int ii = 0; ii < d->targets.count(); ++ii) {
1402 QQuickItem *i = d->targets.at(ii);
1403 if (i && i->isVisible() && (i->flags() & QQuickItem::ItemAcceptsInputMethod)) {
1404 d->item->canvas()->sendEvent(i, event);
1405 if (event->isAccepted()) {
1414 QQuickItemKeyFilter::inputMethodEvent(event, post);
1417 QVariant QQuickKeysAttached::inputMethodQuery(Qt::InputMethodQuery query) const
1419 Q_D(const QQuickKeysAttached);
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) && i == d->imeItem) {
1424 //### how robust is i == d->imeItem check?
1425 QVariant v = i->inputMethodQuery(query);
1426 if (v.userType() == QVariant::RectF)
1427 v = d->item->mapRectFromItem(i, v.toRectF()); //### cost?
1432 return QQuickItemKeyFilter::inputMethodQuery(query);
1435 QQuickKeysAttached *QQuickKeysAttached::qmlAttachedProperties(QObject *obj)
1437 return new QQuickKeysAttached(obj);
1441 \qmlclass LayoutMirroring QQuickLayoutMirroringAttached
1442 \inqmlmodule QtQuick 2
1443 \ingroup qml-utility-elements
1444 \brief The LayoutMirroring attached property is used to mirror layout behavior.
1446 The LayoutMirroring attached property is used to horizontally mirror \l {anchor-layout}{Item anchors},
1447 \l{Using QML Positioner and Repeater Items}{positioner} elements (such as \l Row and \l Grid)
1448 and views (such as \l GridView and horizontal \l ListView). Mirroring is a visual change: left
1449 anchors become right anchors, and positioner elements like \l Grid and \l Row reverse the
1450 horizontal layout of child items.
1452 Mirroring is enabled for an item by setting the \l enabled property to true. By default, this
1453 only affects the item itself; setting the \l childrenInherit property to true propagates the mirroring
1454 behavior to all child elements as well. If the \c LayoutMirroring attached property has not been defined
1455 for an item, mirroring is not enabled.
1457 The following example shows mirroring in action. The \l Row below is specified as being anchored
1458 to the left of its parent. However, since mirroring has been enabled, the anchor is horizontally
1459 reversed and it is now anchored to the right. Also, since items in a \l Row are positioned
1460 from left to right by default, they are now positioned from right to left instead, as demonstrated
1461 by the numbering and opacity of the items:
1463 \snippet doc/src/snippets/declarative/layoutmirroring.qml 0
1465 \image layoutmirroring.png
1467 Layout mirroring is useful when it is necessary to support both left-to-right and right-to-left
1468 layout versions of an application to target different language areas. The \l childrenInherit
1469 property allows layout mirroring to be applied without manually setting layout configurations
1470 for every item in an application. Keep in mind, however, that mirroring does not affect any
1471 positioning that is defined by the \l Item \l {Item::}{x} coordinate value, so even with
1472 mirroring enabled, it will often be necessary to apply some layout fixes to support the
1473 desired layout direction. Also, it may be necessary to disable the mirroring of individual
1474 child items (by setting \l {enabled}{LayoutMirroring.enabled} to false for such items) if
1475 mirroring is not the desired behavior, or if the child item already implements mirroring in
1478 See \l {QML Right-to-left User Interfaces} for further details on using \c LayoutMirroring and
1479 other related features to implement right-to-left support for an application.
1483 \qmlproperty bool QtQuick2::LayoutMirroring::enabled
1485 This property holds whether the item's layout is mirrored horizontally. Setting this to true
1486 horizontally reverses \l {anchor-layout}{anchor} settings such that left anchors become right,
1487 and right anchors become left. For \l{Using QML Positioner and Repeater Items}{positioner} elements
1488 (such as \l Row and \l Grid) and view elements (such as \l {GridView}{GridView} and \l {ListView}{ListView})
1489 this also mirrors the horizontal layout direction of the item.
1491 The default value is false.
1495 \qmlproperty bool QtQuick2::LayoutMirroring::childrenInherit
1497 This property holds whether the \l {enabled}{LayoutMirroring.enabled} value for this item
1498 is inherited by its children.
1500 The default value is false.
1504 QQuickLayoutMirroringAttached::QQuickLayoutMirroringAttached(QObject *parent) : QObject(parent), itemPrivate(0)
1506 if (QQuickItem *item = qobject_cast<QQuickItem*>(parent)) {
1507 itemPrivate = QQuickItemPrivate::get(item);
1508 itemPrivate->extra.value().layoutDirectionAttached = this;
1510 qmlInfo(parent) << tr("LayoutDirection attached property only works with Items");
1513 QQuickLayoutMirroringAttached * QQuickLayoutMirroringAttached::qmlAttachedProperties(QObject *object)
1515 return new QQuickLayoutMirroringAttached(object);
1518 bool QQuickLayoutMirroringAttached::enabled() const
1520 return itemPrivate ? itemPrivate->effectiveLayoutMirror : false;
1523 void QQuickLayoutMirroringAttached::setEnabled(bool enabled)
1528 itemPrivate->isMirrorImplicit = false;
1529 if (enabled != itemPrivate->effectiveLayoutMirror) {
1530 itemPrivate->setLayoutMirror(enabled);
1531 if (itemPrivate->inheritMirrorFromItem)
1532 itemPrivate->resolveLayoutMirror();
1536 void QQuickLayoutMirroringAttached::resetEnabled()
1538 if (itemPrivate && !itemPrivate->isMirrorImplicit) {
1539 itemPrivate->isMirrorImplicit = true;
1540 itemPrivate->resolveLayoutMirror();
1544 bool QQuickLayoutMirroringAttached::childrenInherit() const
1546 return itemPrivate ? itemPrivate->inheritMirrorFromItem : false;
1549 void QQuickLayoutMirroringAttached::setChildrenInherit(bool childrenInherit) {
1550 if (itemPrivate && childrenInherit != itemPrivate->inheritMirrorFromItem) {
1551 itemPrivate->inheritMirrorFromItem = childrenInherit;
1552 itemPrivate->resolveLayoutMirror();
1553 childrenInheritChanged();
1557 void QQuickItemPrivate::resolveLayoutMirror()
1560 if (QQuickItem *parentItem = q->parentItem()) {
1561 QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(parentItem);
1562 setImplicitLayoutMirror(parentPrivate->inheritedLayoutMirror, parentPrivate->inheritMirrorFromParent);
1564 setImplicitLayoutMirror(isMirrorImplicit ? false : effectiveLayoutMirror, inheritMirrorFromItem);
1568 void QQuickItemPrivate::setImplicitLayoutMirror(bool mirror, bool inherit)
1570 inherit = inherit || inheritMirrorFromItem;
1571 if (!isMirrorImplicit && inheritMirrorFromItem)
1572 mirror = effectiveLayoutMirror;
1573 if (mirror == inheritedLayoutMirror && inherit == inheritMirrorFromParent)
1576 inheritMirrorFromParent = inherit;
1577 inheritedLayoutMirror = inheritMirrorFromParent ? mirror : false;
1579 if (isMirrorImplicit)
1580 setLayoutMirror(inherit ? inheritedLayoutMirror : false);
1581 for (int i = 0; i < childItems.count(); ++i) {
1582 if (QQuickItem *child = qobject_cast<QQuickItem *>(childItems.at(i))) {
1583 QQuickItemPrivate *childPrivate = QQuickItemPrivate::get(child);
1584 childPrivate->setImplicitLayoutMirror(inheritedLayoutMirror, inheritMirrorFromParent);
1589 void QQuickItemPrivate::setLayoutMirror(bool mirror)
1591 if (mirror != effectiveLayoutMirror) {
1592 effectiveLayoutMirror = mirror;
1594 QQuickAnchorsPrivate *anchor_d = QQuickAnchorsPrivate::get(_anchors);
1595 anchor_d->fillChanged();
1596 anchor_d->centerInChanged();
1597 anchor_d->updateHorizontalAnchors();
1598 emit _anchors->mirroredChanged();
1601 if (extra.isAllocated() && extra->layoutDirectionAttached) {
1602 emit extra->layoutDirectionAttached->enabledChanged();
1607 void QQuickItemPrivate::setAccessibleFlagAndListener()
1610 QQuickItem *item = q;
1612 if (item->d_func()->isAccessible)
1613 break; // already set - grandparents should have the flag set as well.
1615 if (item->canvas() && item->canvas()->rootItem() == item)
1616 break; // don't add a listener to the canvas root item
1618 item->d_func()->isAccessible = true;
1619 item = item->d_func()->parentItem;
1625 \brief The QQuickItem class provides the most basic of all visual items in QML.
1629 All visual items in Qt Declarative inherit from QQuickItem. Although QQuickItem
1630 has no visual appearance, it defines all the properties that are
1631 common across visual items - such as the x and y position, the
1632 width and height, \l {anchor-layout}{anchoring} and key handling.
1634 You can subclass QQuickItem to provide your own custom visual item that inherits
1635 these features. Note that, because it does not draw anything, QQuickItem sets the
1636 QGraphicsItem::ItemHasNoContents flag. If you subclass QQuickItem to create a visual
1637 item, you will need to unset this flag.
1642 \qmlclass Item QQuickItem
1644 \inqmlmodule QtQuick 2
1645 \ingroup qml-basic-visual-elements
1646 \brief The Item is the most basic of all visual items in QML.
1648 All visual items in Qt Declarative inherit from Item. Although Item
1649 has no visual appearance, it defines all the properties that are
1650 common across visual items - such as the x and y position, the
1651 width and height, \l {anchor-layout}{anchoring} and key handling.
1653 Item is also useful for grouping items together.
1670 fillMode: Image.Tile
1677 \section1 Key Handling
1679 Key handling is available to all Item-based visual elements via the \l {Keys}{Keys}
1680 attached property. The \e Keys attached property provides basic handlers such
1681 as \l {Keys::onPressed}{onPressed} and \l {Keys::onReleased}{onReleased},
1682 as well as handlers for specific keys, such as
1683 \l {Keys::onCancelPressed}{onCancelPressed}. The example below
1684 assigns \l {qmlfocus}{focus} to the item and handles
1685 the Left key via the general \e onPressed handler and the Select key via the
1686 onSelectPressed handler:
1692 if (event.key == Qt.Key_Left) {
1693 console.log("move left");
1694 event.accepted = true;
1697 Keys.onSelectPressed: console.log("Selected");
1701 See the \l {Keys}{Keys} attached property for detailed documentation.
1703 \section1 Layout Mirroring
1705 Item layouts can be mirrored using the \l {LayoutMirroring}{LayoutMirroring} attached property.
1710 \fn void QQuickItem::childrenRectChanged(const QRectF &)
1715 \fn void QQuickItem::baselineOffsetChanged(qreal)
1720 \fn void QQuickItem::stateChanged(const QString &state)
1725 \fn void QQuickItem::parentChanged(QQuickItem *)
1730 \fn void QQuickItem::smoothChanged(bool)
1735 \fn void QQuickItem::clipChanged(bool)
1739 /*! \fn void QQuickItem::transformOriginChanged(TransformOrigin)
1744 \fn void QQuickItem::focusChanged(bool)
1749 \fn void QQuickItem::activeFocusChanged(bool)
1753 \fn QQuickItem::QQuickItem(QQuickItem *parent)
1755 Constructs a QQuickItem with the given \a parent.
1757 QQuickItem::QQuickItem(QQuickItem* parent)
1758 : QObject(*(new QQuickItemPrivate), parent)
1766 QQuickItem::QQuickItem(QQuickItemPrivate &dd, QQuickItem *parent)
1767 : QObject(dd, parent)
1774 static int qt_item_count = 0;
1776 static void qt_print_item_count()
1778 qDebug("Number of leaked items: %i", qt_item_count);
1784 Destroys the QQuickItem.
1786 QQuickItem::~QQuickItem()
1790 if (qt_item_count < 0)
1791 qDebug("Item destroyed after qt_print_item_count() was called.");
1798 else if (d->canvas && d->itemNodeInstance)
1799 QQuickCanvasPrivate::get(d->canvas)->cleanup(d->itemNodeInstance); // cleanup root
1800 // XXX todo - optimize
1801 while (!d->childItems.isEmpty())
1802 d->childItems.first()->setParentItem(0);
1804 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
1805 QQuickAnchorsPrivate *anchor = d->changeListeners.at(ii).listener->anchorPrivate();
1807 anchor->clearItem(this);
1811 update item anchors that depended on us unless they are our child (and will also be destroyed),
1812 or our sibling, and our parent is also being destroyed.
1814 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
1815 QQuickAnchorsPrivate *anchor = d->changeListeners.at(ii).listener->anchorPrivate();
1816 if (anchor && anchor->item && anchor->item->parentItem() && anchor->item->parentItem() != this)
1820 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
1821 const QQuickItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
1822 if (change.types & QQuickItemPrivate::Destroyed)
1823 change.listener->itemDestroyed(this);
1826 d->changeListeners.clear();
1828 if (d->extra.isAllocated()) {
1829 delete d->extra->contents; d->extra->contents = 0;
1830 delete d->extra->layer; d->extra->layer = 0;
1833 delete d->_anchors; d->_anchors = 0;
1834 delete d->_stateGroup; d->_stateGroup = 0;
1838 \qmlproperty enumeration QtQuick2::Item::transformOrigin
1839 This property holds the origin point around which scale and rotation transform.
1841 Nine transform origins are available, as shown in the image below.
1843 \image declarative-transformorigin.png
1845 This example rotates an image around its bottom-right corner.
1848 source: "myimage.png"
1849 transformOrigin: Item.BottomRight
1854 The default transform origin is \c Item.Center.
1856 To set an arbitrary transform origin point use the \l Scale or \l Rotation
1861 \qmlproperty Item QtQuick2::Item::parent
1862 This property holds the parent of the item.
1866 \property QQuickItem::parent
1867 This property holds the parent of the item.
1869 void QQuickItem::setParentItem(QQuickItem *parentItem)
1872 if (parentItem == d->parentItem)
1876 QQuickItem *itemAncestor = parentItem->parentItem();
1877 while (itemAncestor != 0) {
1878 if (itemAncestor == this) {
1879 qWarning("QQuickItem::setParentItem: Parent is already part of this items subtree.");
1882 itemAncestor = itemAncestor->parentItem();
1886 d->removeFromDirtyList();
1888 QQuickItem *oldParentItem = d->parentItem;
1889 QQuickItem *scopeFocusedItem = 0;
1891 if (oldParentItem) {
1892 QQuickItemPrivate *op = QQuickItemPrivate::get(oldParentItem);
1894 QQuickItem *scopeItem = 0;
1896 if (d->canvas && hasFocus()) {
1897 scopeItem = oldParentItem;
1898 while (!scopeItem->isFocusScope()) scopeItem = scopeItem->parentItem();
1899 scopeFocusedItem = this;
1900 } else if (d->canvas && !isFocusScope() && d->subFocusItem) {
1901 scopeItem = oldParentItem;
1902 while (!scopeItem->isFocusScope()) scopeItem = scopeItem->parentItem();
1903 scopeFocusedItem = d->subFocusItem;
1906 if (scopeFocusedItem)
1907 QQuickCanvasPrivate::get(d->canvas)->clearFocusInScope(scopeItem, scopeFocusedItem,
1908 QQuickCanvasPrivate::DontChangeFocusProperty);
1910 const bool wasVisible = isVisible();
1911 op->removeChild(this);
1913 emit oldParentItem->visibleChildrenChanged();
1915 } else if (d->canvas) {
1916 QQuickCanvasPrivate::get(d->canvas)->parentlessItems.remove(this);
1919 d->parentItem = parentItem;
1921 QQuickCanvas *parentCanvas = parentItem?QQuickItemPrivate::get(parentItem)->canvas:0;
1922 if (d->canvas != parentCanvas) {
1923 QQuickItemPrivate::InitializationState initState;
1925 d->initCanvas(&initState, parentCanvas);
1928 d->dirty(QQuickItemPrivate::ParentChanged);
1931 QQuickItemPrivate::get(d->parentItem)->addChild(this);
1933 d->setEffectiveVisibleRecur(d->calcEffectiveVisible());
1934 d->setEffectiveEnableRecur(0, d->calcEffectiveEnable());
1936 if (scopeFocusedItem && d->parentItem && d->canvas) {
1937 // We need to test whether this item becomes scope focused
1938 QQuickItem *scopeItem = 0;
1939 scopeItem = d->parentItem;
1940 while (!scopeItem->isFocusScope()) scopeItem = scopeItem->parentItem();
1942 if (scopeItem->scopedFocusItem()) {
1943 QQuickItemPrivate::get(scopeFocusedItem)->focus = false;
1944 emit scopeFocusedItem->focusChanged(false);
1946 QQuickCanvasPrivate::get(d->canvas)->setFocusInScope(scopeItem, scopeFocusedItem,
1947 QQuickCanvasPrivate::DontChangeFocusProperty);
1951 d->resolveLayoutMirror();
1953 d->itemChange(ItemParentHasChanged, d->parentItem);
1955 d->parentNotifier.notify();
1956 if (d->isAccessible && d->parentItem) {
1957 d->parentItem->d_func()->setAccessibleFlagAndListener();
1960 emit parentChanged(d->parentItem);
1961 if (isVisible() && d->parentItem)
1962 emit d->parentItem->visibleChildrenChanged();
1965 void QQuickItem::stackBefore(const QQuickItem *sibling)
1968 if (!sibling || sibling == this || !d->parentItem || d->parentItem != QQuickItemPrivate::get(sibling)->parentItem) {
1969 qWarning("QQuickItem::stackBefore: Cannot stack before %p, which must be a sibling", sibling);
1973 QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(d->parentItem);
1975 int myIndex = parentPrivate->childItems.indexOf(this);
1976 int siblingIndex = parentPrivate->childItems.indexOf(const_cast<QQuickItem *>(sibling));
1978 Q_ASSERT(myIndex != -1 && siblingIndex != -1);
1980 if (myIndex == siblingIndex - 1)
1983 parentPrivate->childItems.removeAt(myIndex);
1985 if (myIndex < siblingIndex) --siblingIndex;
1987 parentPrivate->childItems.insert(siblingIndex, this);
1989 parentPrivate->dirty(QQuickItemPrivate::ChildrenStackingChanged);
1990 parentPrivate->markSortedChildrenDirty(this);
1992 for (int ii = qMin(siblingIndex, myIndex); ii < parentPrivate->childItems.count(); ++ii)
1993 QQuickItemPrivate::get(parentPrivate->childItems.at(ii))->siblingOrderChanged();
1996 void QQuickItem::stackAfter(const QQuickItem *sibling)
1999 if (!sibling || sibling == this || !d->parentItem || d->parentItem != QQuickItemPrivate::get(sibling)->parentItem) {
2000 qWarning("QQuickItem::stackAfter: Cannot stack after %p, which must be a sibling", sibling);
2004 QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(d->parentItem);
2006 int myIndex = parentPrivate->childItems.indexOf(this);
2007 int siblingIndex = parentPrivate->childItems.indexOf(const_cast<QQuickItem *>(sibling));
2009 Q_ASSERT(myIndex != -1 && siblingIndex != -1);
2011 if (myIndex == siblingIndex + 1)
2014 parentPrivate->childItems.removeAt(myIndex);
2016 if (myIndex < siblingIndex) --siblingIndex;
2018 parentPrivate->childItems.insert(siblingIndex + 1, this);
2020 parentPrivate->dirty(QQuickItemPrivate::ChildrenStackingChanged);
2021 parentPrivate->markSortedChildrenDirty(this);
2023 for (int ii = qMin(myIndex, siblingIndex + 1); ii < parentPrivate->childItems.count(); ++ii)
2024 QQuickItemPrivate::get(parentPrivate->childItems.at(ii))->siblingOrderChanged();
2028 Returns the QQuickItem parent of this item.
2030 QQuickItem *QQuickItem::parentItem() const
2032 Q_D(const QQuickItem);
2033 return d->parentItem;
2036 QSGEngine *QQuickItem::sceneGraphEngine() const
2038 return canvas()->sceneGraphEngine();
2041 QQuickCanvas *QQuickItem::canvas() const
2043 Q_D(const QQuickItem);
2047 static bool itemZOrder_sort(QQuickItem *lhs, QQuickItem *rhs)
2049 return lhs->z() < rhs->z();
2052 QList<QQuickItem *> QQuickItemPrivate::paintOrderChildItems() const
2054 if (sortedChildItems)
2055 return *sortedChildItems;
2057 // If none of the items have set Z then the paint order list is the same as
2058 // the childItems list. This is by far the most common case.
2060 for (int i = 0; i < childItems.count(); ++i) {
2061 if (QQuickItemPrivate::get(childItems.at(i))->z() != 0.) {
2067 sortedChildItems = new QList<QQuickItem*>(childItems);
2068 qStableSort(sortedChildItems->begin(), sortedChildItems->end(), itemZOrder_sort);
2069 return *sortedChildItems;
2072 sortedChildItems = const_cast<QList<QQuickItem*>*>(&childItems);
2077 void QQuickItemPrivate::addChild(QQuickItem *child)
2081 Q_ASSERT(!childItems.contains(child));
2083 childItems.append(child);
2085 markSortedChildrenDirty(child);
2086 dirty(QQuickItemPrivate::ChildrenChanged);
2088 itemChange(QQuickItem::ItemChildAddedChange, child);
2090 emit q->childrenChanged();
2093 void QQuickItemPrivate::removeChild(QQuickItem *child)
2098 Q_ASSERT(childItems.contains(child));
2099 childItems.removeOne(child);
2100 Q_ASSERT(!childItems.contains(child));
2102 markSortedChildrenDirty(child);
2103 dirty(QQuickItemPrivate::ChildrenChanged);
2105 itemChange(QQuickItem::ItemChildRemovedChange, child);
2107 emit q->childrenChanged();
2110 void QQuickItemPrivate::InitializationState::clear()
2115 void QQuickItemPrivate::InitializationState::clear(QQuickItem *fs)
2120 QQuickItem *QQuickItemPrivate::InitializationState::getFocusScope(QQuickItem *item)
2123 QQuickItem *fs = item->parentItem();
2124 while (fs->parentItem() && !fs->isFocusScope())
2125 fs = fs->parentItem();
2131 void QQuickItemPrivate::initCanvas(InitializationState *state, QQuickCanvas *c)
2136 removeFromDirtyList();
2137 QQuickCanvasPrivate *c = QQuickCanvasPrivate::get(canvas);
2138 if (polishScheduled)
2139 c->itemsToPolish.remove(q);
2140 if (c->mouseGrabberItem == q)
2141 c->mouseGrabberItem = 0;
2143 c->hoverItems.removeAll(q);
2144 if (itemNodeInstance)
2145 c->cleanup(itemNodeInstance);
2147 c->parentlessItems.remove(q);
2152 if (canvas && polishScheduled)
2153 QQuickCanvasPrivate::get(canvas)->itemsToPolish.insert(q);
2155 itemNodeInstance = 0;
2157 if (extra.isAllocated()) {
2158 extra->opacityNode = 0;
2159 extra->clipNode = 0;
2160 extra->rootNode = 0;
2161 extra->beforePaintNode = 0;
2167 InitializationState _dummy;
2168 InitializationState *childState = state;
2170 if (c && q->isFocusScope()) {
2172 childState = &_dummy;
2175 if (!parentItem && canvas)
2176 QQuickCanvasPrivate::get(canvas)->parentlessItems.insert(q);
2178 for (int ii = 0; ii < childItems.count(); ++ii) {
2179 QQuickItem *child = childItems.at(ii);
2180 QQuickItemPrivate::get(child)->initCanvas(childState, c);
2185 if (state->getFocusScope(q)->scopedFocusItem()) {
2187 emit q->focusChanged(false);
2189 QQuickCanvasPrivate::get(canvas)->setFocusInScope(state->getFocusScope(q), q);
2195 if (extra.isAllocated() && extra->screenAttached)
2196 extra->screenAttached->canvasChanged(c);
2197 itemChange(QQuickItem::ItemSceneChange, c);
2201 Returns a transform that maps points from canvas space into item space.
2203 QTransform QQuickItemPrivate::canvasToItemTransform() const
2205 // XXX todo - optimize
2206 return itemToCanvasTransform().inverted();
2210 Returns a transform that maps points from item space into canvas space.
2212 QTransform QQuickItemPrivate::itemToCanvasTransform() const
2215 QTransform rv = parentItem?QQuickItemPrivate::get(parentItem)->itemToCanvasTransform():QTransform();
2216 itemToParentTransform(rv);
2221 Motifies \a t with this items local transform relative to its parent.
2223 void QQuickItemPrivate::itemToParentTransform(QTransform &t) const
2228 if (!transforms.isEmpty()) {
2230 for (int ii = transforms.count() - 1; ii >= 0; --ii)
2231 transforms.at(ii)->applyTo(&m);
2232 t = m.toTransform();
2235 if (scale() != 1. || rotation() != 0.) {
2236 QPointF tp = computeTransformOrigin();
2237 t.translate(tp.x(), tp.y());
2238 t.scale(scale(), scale());
2239 t.rotate(rotation());
2240 t.translate(-tp.x(), -tp.y());
2246 \qmlproperty real QtQuick2::Item::childrenRect.x
2247 \qmlproperty real QtQuick2::Item::childrenRect.y
2248 \qmlproperty real QtQuick2::Item::childrenRect.width
2249 \qmlproperty real QtQuick2::Item::childrenRect.height
2251 The childrenRect properties allow an item access to the geometry of its
2252 children. This property is useful if you have an item that needs to be
2253 sized to fit its children.
2258 \qmlproperty list<Item> QtQuick2::Item::children
2259 \qmlproperty list<Object> QtQuick2::Item::resources
2261 The children property contains the list of visual children of this item.
2262 The resources property contains non-visual resources that you want to
2265 Generally you can rely on Item's default property to handle all this for
2266 you, but it can come in handy in some cases.
2285 Returns true if construction of the QML component is complete; otherwise
2288 It is often desirable to delay some processing until the component is
2291 \sa componentComplete()
2293 bool QQuickItem::isComponentComplete() const
2295 Q_D(const QQuickItem);
2296 return d->componentComplete;
2299 QQuickItemPrivate::QQuickItemPrivate()
2300 : _anchors(0), _stateGroup(0),
2301 flags(0), widthValid(false), heightValid(false), baselineOffsetValid(false), componentComplete(true),
2302 keepMouse(false), keepTouch(false), hoverEnabled(false), smooth(false), focus(false), activeFocus(false), notifiedFocus(false),
2303 notifiedActiveFocus(false), filtersChildMouseEvents(false), explicitVisible(true),
2304 effectiveVisible(true), explicitEnable(true), effectiveEnable(true), polishScheduled(false),
2305 inheritedLayoutMirror(false), effectiveLayoutMirror(false), isMirrorImplicit(true),
2306 inheritMirrorFromParent(false), inheritMirrorFromItem(false), childrenDoNotOverlap(false),
2307 staticSubtreeGeometry(false),
2308 isAccessible(false),
2310 dirtyAttributes(0), nextDirtyItem(0), prevDirtyItem(0),
2312 canvas(0), parentItem(0), sortedChildItems(&childItems),
2316 x(0), y(0), width(0), height(0), implicitWidth(0), implicitHeight(0),
2320 itemNodeInstance(0), groupNode(0), paintNode(0)
2324 QQuickItemPrivate::~QQuickItemPrivate()
2326 if (sortedChildItems != &childItems)
2327 delete sortedChildItems;
2330 void QQuickItemPrivate::init(QQuickItem *parent)
2334 static bool atexit_registered = false;
2335 if (!atexit_registered) {
2336 atexit(qt_print_item_count);
2337 atexit_registered = true;
2343 registerAccessorProperties();
2345 baselineOffsetValid = false;
2348 q->setParentItem(parent);
2349 QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(parent);
2350 setImplicitLayoutMirror(parentPrivate->inheritedLayoutMirror, parentPrivate->inheritMirrorFromParent);
2354 void QQuickItemPrivate::data_append(QDeclarativeListProperty<QObject> *prop, QObject *o)
2359 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2361 // This test is measurably (albeit only slightly) faster than qobject_cast<>()
2362 const QMetaObject *mo = o->metaObject();
2363 while (mo && mo != &QQuickItem::staticMetaObject) {
2364 mo = mo->d.superdata;
2368 QQuickItem *item = static_cast<QQuickItem *>(o);
2369 item->setParentItem(that);
2371 if (o->inherits("QGraphicsItem"))
2372 qWarning("Cannot add a QtQuick 1.0 item (%s) into a QtQuick 2.0 scene!", o->metaObject()->className());
2374 // XXX todo - do we really want this behavior?
2380 \qmlproperty list<Object> QtQuick2::Item::data
2383 The data property allows you to freely mix visual children and resources
2384 in an item. If you assign a visual item to the data list it becomes
2385 a child and if you assign any other object type, it is added as a resource.
2409 data is a behind-the-scenes property: you should never need to explicitly
2413 int QQuickItemPrivate::data_count(QDeclarativeListProperty<QObject> *prop)
2420 QObject *QQuickItemPrivate::data_at(QDeclarativeListProperty<QObject> *prop, int i)
2428 void QQuickItemPrivate::data_clear(QDeclarativeListProperty<QObject> *prop)
2434 QObject *QQuickItemPrivate::resources_at(QDeclarativeListProperty<QObject> *prop, int index)
2436 const QObjectList children = prop->object->children();
2437 if (index < children.count())
2438 return children.at(index);
2443 void QQuickItemPrivate::resources_append(QDeclarativeListProperty<QObject> *prop, QObject *o)
2445 // XXX todo - do we really want this behavior?
2446 o->setParent(prop->object);
2449 int QQuickItemPrivate::resources_count(QDeclarativeListProperty<QObject> *prop)
2451 return prop->object->children().count();
2454 void QQuickItemPrivate::resources_clear(QDeclarativeListProperty<QObject> *prop)
2456 // XXX todo - do we really want this behavior?
2457 const QObjectList children = prop->object->children();
2458 for (int index = 0; index < children.count(); index++)
2459 children.at(index)->setParent(0);
2462 QQuickItem *QQuickItemPrivate::children_at(QDeclarativeListProperty<QQuickItem> *prop, int index)
2464 QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2465 if (index >= p->childItems.count() || index < 0)
2468 return p->childItems.at(index);
2471 void QQuickItemPrivate::children_append(QDeclarativeListProperty<QQuickItem> *prop, QQuickItem *o)
2476 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2477 if (o->parentItem() == that)
2478 o->setParentItem(0);
2480 o->setParentItem(that);
2483 int QQuickItemPrivate::children_count(QDeclarativeListProperty<QQuickItem> *prop)
2485 QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2486 return p->childItems.count();
2489 void QQuickItemPrivate::children_clear(QDeclarativeListProperty<QQuickItem> *prop)
2491 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2492 QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2493 while (!p->childItems.isEmpty())
2494 p->childItems.at(0)->setParentItem(0);
2497 void QQuickItemPrivate::visibleChildren_append(QDeclarativeListProperty<QQuickItem>*, QQuickItem *self)
2500 qmlInfo(self) << "QQuickItem: visibleChildren property is readonly and cannot be assigned to.";
2503 int QQuickItemPrivate::visibleChildren_count(QDeclarativeListProperty<QQuickItem> *prop)
2505 QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2506 int visibleCount = 0;
2507 int c = p->childItems.count();
2509 if (p->childItems.at(c)->isVisible()) visibleCount++;
2512 return visibleCount;
2515 QQuickItem *QQuickItemPrivate::visibleChildren_at(QDeclarativeListProperty<QQuickItem> *prop, int index)
2517 QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2518 const int childCount = p->childItems.count();
2519 if (index >= childCount || index < 0)
2522 int visibleCount = -1;
2523 for (int i = 0; i < childCount; i++) {
2524 if (p->childItems.at(i)->isVisible()) visibleCount++;
2525 if (visibleCount == index) return p->childItems.at(i);
2530 int QQuickItemPrivate::transform_count(QDeclarativeListProperty<QQuickTransform> *prop)
2532 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2533 QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2535 return p->transforms.count();
2538 void QQuickTransform::appendToItem(QQuickItem *item)
2540 Q_D(QQuickTransform);
2544 QQuickItemPrivate *p = QQuickItemPrivate::get(item);
2546 if (!d->items.isEmpty() && !p->transforms.isEmpty() && p->transforms.contains(this)) {
2547 p->transforms.removeOne(this);
2548 p->transforms.append(this);
2550 p->transforms.append(this);
2551 d->items.append(item);
2554 p->dirty(QQuickItemPrivate::Transform);
2557 void QQuickTransform::prependToItem(QQuickItem *item)
2559 Q_D(QQuickTransform);
2563 QQuickItemPrivate *p = QQuickItemPrivate::get(item);
2565 if (!d->items.isEmpty() && !p->transforms.isEmpty() && p->transforms.contains(this)) {
2566 p->transforms.removeOne(this);
2567 p->transforms.prepend(this);
2569 p->transforms.prepend(this);
2570 d->items.append(item);
2573 p->dirty(QQuickItemPrivate::Transform);
2576 void QQuickItemPrivate::transform_append(QDeclarativeListProperty<QQuickTransform> *prop, QQuickTransform *transform)
2581 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2582 transform->appendToItem(that);
2585 QQuickTransform *QQuickItemPrivate::transform_at(QDeclarativeListProperty<QQuickTransform> *prop, int idx)
2587 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2588 QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2590 if (idx < 0 || idx >= p->transforms.count())
2593 return p->transforms.at(idx);
2596 void QQuickItemPrivate::transform_clear(QDeclarativeListProperty<QQuickTransform> *prop)
2598 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2599 QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2601 for (int ii = 0; ii < p->transforms.count(); ++ii) {
2602 QQuickTransform *t = p->transforms.at(ii);
2603 QQuickTransformPrivate *tp = QQuickTransformPrivate::get(t);
2604 tp->items.removeOne(that);
2607 p->transforms.clear();
2609 p->dirty(QQuickItemPrivate::Transform);
2613 \property QQuickItem::childrenRect
2614 \brief The geometry of an item's children.
2616 This property holds the (collective) position and size of the item's children.
2620 \qmlproperty real QtQuick2::Item::x
2621 \qmlproperty real QtQuick2::Item::y
2622 \qmlproperty real QtQuick2::Item::width
2623 \qmlproperty real QtQuick2::Item::height
2625 Defines the item's position and size relative to its parent.
2628 Item { x: 100; y: 100; width: 100; height: 100 }
2633 \qmlproperty real QtQuick2::Item::z
2635 Sets the stacking order of sibling items. By default the stacking order is 0.
2637 Items with a higher stacking value are drawn on top of siblings with a
2638 lower stacking order. Items with the same stacking value are drawn
2639 bottom up in the order they appear. Items with a negative stacking
2640 value are drawn under their parent's content.
2642 The following example shows the various effects of stacking order.
2646 \o \image declarative-item_stacking1.png
2647 \o Same \c z - later children above earlier children:
2652 width: 100; height: 100
2656 x: 50; y: 50; width: 100; height: 100
2661 \o \image declarative-item_stacking2.png
2662 \o Higher \c z on top:
2668 width: 100; height: 100
2672 x: 50; y: 50; width: 100; height: 100
2677 \o \image declarative-item_stacking3.png
2678 \o Same \c z - children above parents:
2683 width: 100; height: 100
2686 x: 50; y: 50; width: 100; height: 100
2692 \o \image declarative-item_stacking4.png
2693 \o Lower \c z below:
2698 width: 100; height: 100
2702 x: 50; y: 50; width: 100; height: 100
2711 \qmlproperty bool QtQuick2::Item::visible
2713 This property holds whether the item is visible. By default this is true.
2715 Setting this property directly affects the \c visible value of child
2716 items. When set to \c false, the \c visible values of all child items also
2717 become \c false. When set to \c true, the \c visible values of child items
2718 are returned to \c true, unless they have explicitly been set to \c false.
2720 (Because of this flow-on behavior, using the \c visible property may not
2721 have the intended effect if a property binding should only respond to
2722 explicit property changes. In such cases it may be better to use the
2723 \l opacity property instead.)
2725 Setting this property to \c false automatically causes \l focus to be set
2726 to \c false, and this item will longer receive mouse and keyboard events.
2727 (In contrast, setting the \l opacity to 0 does not affect the \l focus
2728 property and the receiving of key events.)
2730 \note This property's value is only affected by changes to this property or
2731 the parent's \c visible property. It does not change, for example, if this
2732 item moves off-screen, or if the \l opacity changes to 0.
2737 \qmlproperty AnchorLine QtQuick2::Item::anchors.top
2738 \qmlproperty AnchorLine QtQuick2::Item::anchors.bottom
2739 \qmlproperty AnchorLine QtQuick2::Item::anchors.left
2740 \qmlproperty AnchorLine QtQuick2::Item::anchors.right
2741 \qmlproperty AnchorLine QtQuick2::Item::anchors.horizontalCenter
2742 \qmlproperty AnchorLine QtQuick2::Item::anchors.verticalCenter
2743 \qmlproperty AnchorLine QtQuick2::Item::anchors.baseline
2745 \qmlproperty Item QtQuick2::Item::anchors.fill
2746 \qmlproperty Item QtQuick2::Item::anchors.centerIn
2748 \qmlproperty real QtQuick2::Item::anchors.margins
2749 \qmlproperty real QtQuick2::Item::anchors.topMargin
2750 \qmlproperty real QtQuick2::Item::anchors.bottomMargin
2751 \qmlproperty real QtQuick2::Item::anchors.leftMargin
2752 \qmlproperty real QtQuick2::Item::anchors.rightMargin
2753 \qmlproperty real QtQuick2::Item::anchors.horizontalCenterOffset
2754 \qmlproperty real QtQuick2::Item::anchors.verticalCenterOffset
2755 \qmlproperty real QtQuick2::Item::anchors.baselineOffset
2757 \qmlproperty bool QtQuick2::Item::anchors.mirrored
2759 Anchors provide a way to position an item by specifying its
2760 relationship with other items.
2762 Margins apply to top, bottom, left, right, and fill anchors.
2763 The \c anchors.margins property can be used to set all of the various margins at once, to the same value.
2764 Note that margins are anchor-specific and are not applied if an item does not
2767 Offsets apply for horizontal center, vertical center, and baseline anchors.
2771 \o \image declarative-anchors_example.png
2772 \o Text anchored to Image, horizontally centered and vertically below, with a margin.
2781 anchors.horizontalCenter: pic.horizontalCenter
2782 anchors.top: pic.bottom
2783 anchors.topMargin: 5
2789 \o \image declarative-anchors_example2.png
2791 Left of Text anchored to right of Image, with a margin. The y
2792 property of both defaults to 0.
2802 anchors.left: pic.right
2803 anchors.leftMargin: 5
2810 \c anchors.fill provides a convenient way for one item to have the
2811 same geometry as another item, and is equivalent to connecting all
2812 four directional anchors.
2814 To clear an anchor value, set it to \c undefined.
2816 \c anchors.mirrored returns true it the layout has been \l {LayoutMirroring}{mirrored}.
2818 \note You can only anchor an item to siblings or a parent.
2820 For more information see \l {anchor-layout}{Anchor Layouts}.
2824 \property QQuickItem::baselineOffset
2825 \brief The position of the item's baseline in local coordinates.
2827 The baseline of a \l Text item is the imaginary line on which the text
2828 sits. Controls containing text usually set their baseline to the
2829 baseline of their text.
2831 For non-text items, a default baseline offset of 0 is used.
2833 QQuickAnchors *QQuickItemPrivate::anchors() const
2836 Q_Q(const QQuickItem);
2837 _anchors = new QQuickAnchors(const_cast<QQuickItem *>(q));
2838 if (!componentComplete)
2839 _anchors->classBegin();
2844 void QQuickItemPrivate::siblingOrderChanged()
2847 for (int ii = 0; ii < changeListeners.count(); ++ii) {
2848 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
2849 if (change.types & QQuickItemPrivate::SiblingOrder) {
2850 change.listener->itemSiblingOrderChanged(q);
2855 QDeclarativeListProperty<QObject> QQuickItemPrivate::data()
2857 return QDeclarativeListProperty<QObject>(q_func(), 0, QQuickItemPrivate::data_append,
2858 QQuickItemPrivate::data_count,
2859 QQuickItemPrivate::data_at,
2860 QQuickItemPrivate::data_clear);
2863 QRectF QQuickItem::childrenRect()
2866 if (!d->extra.isAllocated() || !d->extra->contents) {
2867 d->extra.value().contents = new QQuickContents(this);
2868 if (d->componentComplete)
2869 d->extra->contents->complete();
2871 return d->extra->contents->rectF();
2874 QList<QQuickItem *> QQuickItem::childItems() const
2876 Q_D(const QQuickItem);
2877 return d->childItems;
2880 bool QQuickItem::clip() const
2882 return flags() & ItemClipsChildrenToShape;
2885 void QQuickItem::setClip(bool c)
2890 setFlag(ItemClipsChildrenToShape, c);
2892 emit clipChanged(c);
2897 This function is called to handle this item's changes in
2898 geometry from \a oldGeometry to \a newGeometry. If the two
2899 geometries are the same, it doesn't do anything.
2901 void QQuickItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
2906 QQuickAnchorsPrivate::get(d->_anchors)->updateMe();
2908 bool xChange = (newGeometry.x() != oldGeometry.x());
2909 bool yChange = (newGeometry.y() != oldGeometry.y());
2910 bool widthChange = (newGeometry.width() != oldGeometry.width());
2911 bool heightChange = (newGeometry.height() != oldGeometry.height());
2913 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
2914 const QQuickItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
2915 if (change.types & QQuickItemPrivate::Geometry) {
2916 if (change.gTypes == QQuickItemPrivate::GeometryChange) {
2917 change.listener->itemGeometryChanged(this, newGeometry, oldGeometry);
2918 } else if ((xChange && (change.gTypes & QQuickItemPrivate::XChange)) ||
2919 (yChange && (change.gTypes & QQuickItemPrivate::YChange)) ||
2920 (widthChange && (change.gTypes & QQuickItemPrivate::WidthChange)) ||
2921 (heightChange && (change.gTypes & QQuickItemPrivate::HeightChange))) {
2922 change.listener->itemGeometryChanged(this, newGeometry, oldGeometry);
2932 emit widthChanged();
2934 emit heightChanged();
2938 Called by the rendering thread when it is time to sync the state of the QML objects with the
2939 scene graph objects. The function should return the root of the scene graph subtree for
2940 this item. \a oldNode is the node that was returned the last time the function was called.
2942 The main thread is blocked while this function is executed so it is safe to read
2943 values from the QQuickItem instance and other objects in the main thread.
2945 \warning This is the only function in which it is allowed to make use of scene graph
2946 objects from the main thread. Use of scene graph objects outside this function will
2947 result in race conditions and potential crashes.
2950 QSGNode *QQuickItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
2956 QSGTransformNode *QQuickItemPrivate::createTransformNode()
2958 return new QSGTransformNode;
2961 void QQuickItem::updatePolish()
2965 void QQuickItem::sendAccessibilityUpdate()
2969 void QQuickItemPrivate::addItemChangeListener(QQuickItemChangeListener *listener, ChangeTypes types)
2971 changeListeners.append(ChangeListener(listener, types));
2974 void QQuickItemPrivate::removeItemChangeListener(QQuickItemChangeListener *listener, ChangeTypes types)
2976 ChangeListener change(listener, types);
2977 changeListeners.removeOne(change);
2980 void QQuickItemPrivate::updateOrAddGeometryChangeListener(QQuickItemChangeListener *listener, GeometryChangeTypes types)
2982 ChangeListener change(listener, types);
2983 int index = changeListeners.find(change);
2985 changeListeners[index].gTypes = change.gTypes; //we may have different GeometryChangeTypes
2987 changeListeners.append(change);
2990 void QQuickItemPrivate::updateOrRemoveGeometryChangeListener(QQuickItemChangeListener *listener,
2991 GeometryChangeTypes types)
2993 ChangeListener change(listener, types);
2994 if (types == NoChange) {
2995 changeListeners.removeOne(change);
2997 int index = changeListeners.find(change);
2999 changeListeners[index].gTypes = change.gTypes; //we may have different GeometryChangeTypes
3003 void QQuickItem::keyPressEvent(QKeyEvent *event)
3008 void QQuickItem::keyReleaseEvent(QKeyEvent *event)
3013 void QQuickItem::inputMethodEvent(QInputMethodEvent *event)
3018 void QQuickItem::focusInEvent(QFocusEvent *)
3020 QAccessible::updateAccessibility(QAccessibleEvent(QAccessible::Focus, this, 0));
3023 void QQuickItem::focusOutEvent(QFocusEvent *)
3027 void QQuickItem::mousePressEvent(QMouseEvent *event)
3032 void QQuickItem::mouseMoveEvent(QMouseEvent *event)
3037 void QQuickItem::mouseReleaseEvent(QMouseEvent *event)
3042 void QQuickItem::mouseDoubleClickEvent(QMouseEvent *event)
3044 mousePressEvent(event);
3047 void QQuickItem::mouseUngrabEvent()
3052 void QQuickItem::touchUngrabEvent()
3057 void QQuickItem::wheelEvent(QWheelEvent *event)
3062 void QQuickItem::touchEvent(QTouchEvent *event)
3067 void QQuickItem::hoverEnterEvent(QHoverEvent *event)
3072 void QQuickItem::hoverMoveEvent(QHoverEvent *event)
3077 void QQuickItem::hoverLeaveEvent(QHoverEvent *event)
3082 void QQuickItem::dragEnterEvent(QDragEnterEvent *event)
3087 void QQuickItem::dragMoveEvent(QDragMoveEvent *event)
3093 void QQuickItem::dragLeaveEvent(QDragLeaveEvent *event)
3099 void QQuickItem::dropEvent(QDropEvent *event)
3104 bool QQuickItem::childMouseEventFilter(QQuickItem *, QEvent *)
3109 void QQuickItem::windowDeactivateEvent()
3111 foreach (QQuickItem* item, childItems()) {
3112 item->windowDeactivateEvent();
3116 QVariant QQuickItem::inputMethodQuery(Qt::InputMethodQuery query) const
3118 Q_D(const QQuickItem);
3123 v = (bool)(flags() & ItemAcceptsInputMethod);
3126 case Qt::ImCursorRectangle:
3128 case Qt::ImCursorPosition:
3129 case Qt::ImSurroundingText:
3130 case Qt::ImCurrentSelection:
3131 case Qt::ImMaximumTextLength:
3132 case Qt::ImAnchorPosition:
3133 case Qt::ImPreferredLanguage:
3134 if (d->extra.isAllocated() && d->extra->keyHandler)
3135 v = d->extra->keyHandler->inputMethodQuery(query);
3143 QQuickAnchorLine QQuickItemPrivate::left() const
3145 Q_Q(const QQuickItem);
3146 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Left);
3149 QQuickAnchorLine QQuickItemPrivate::right() const
3151 Q_Q(const QQuickItem);
3152 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Right);
3155 QQuickAnchorLine QQuickItemPrivate::horizontalCenter() const
3157 Q_Q(const QQuickItem);
3158 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::HCenter);
3161 QQuickAnchorLine QQuickItemPrivate::top() const
3163 Q_Q(const QQuickItem);
3164 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Top);
3167 QQuickAnchorLine QQuickItemPrivate::bottom() const
3169 Q_Q(const QQuickItem);
3170 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Bottom);
3173 QQuickAnchorLine QQuickItemPrivate::verticalCenter() const
3175 Q_Q(const QQuickItem);
3176 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::VCenter);
3179 QQuickAnchorLine QQuickItemPrivate::baseline() const
3181 Q_Q(const QQuickItem);
3182 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Baseline);
3185 qreal QQuickItem::baselineOffset() const
3187 Q_D(const QQuickItem);
3188 if (d->baselineOffsetValid) {
3189 return d->baselineOffset;
3195 void QQuickItem::setBaselineOffset(qreal offset)
3198 if (offset == d->baselineOffset)
3201 d->baselineOffset = offset;
3202 d->baselineOffsetValid = true;
3204 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
3205 const QQuickItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
3206 if (change.types & QQuickItemPrivate::Geometry) {
3207 QQuickAnchorsPrivate *anchor = change.listener->anchorPrivate();
3209 anchor->updateVerticalAnchors();
3212 emit baselineOffsetChanged(offset);
3215 void QQuickItem::update()
3218 Q_ASSERT(flags() & ItemHasContents);
3219 d->dirty(QQuickItemPrivate::Content);
3222 void QQuickItem::polish()
3225 if (!d->polishScheduled) {
3226 d->polishScheduled = true;
3228 QQuickCanvasPrivate *p = QQuickCanvasPrivate::get(d->canvas);
3229 bool maybeupdate = p->itemsToPolish.isEmpty();
3230 p->itemsToPolish.insert(this);
3231 if (maybeupdate) d->canvas->maybeUpdate();
3236 void QQuickItem::mapFromItem(QDeclarativeV8Function *args) const
3238 if (args->Length() != 0) {
3239 v8::Local<v8::Value> item = (*args)[0];
3240 QV8Engine *engine = args->engine();
3242 QQuickItem *itemObj = 0;
3243 if (!item->IsNull())
3244 itemObj = qobject_cast<QQuickItem*>(engine->toQObject(item));
3246 if (!itemObj && !item->IsNull()) {
3247 qmlInfo(this) << "mapFromItem() given argument \"" << engine->toString(item->ToString())
3248 << "\" which is neither null nor an Item";
3252 v8::Local<v8::Object> rv = v8::Object::New();
3253 args->returnValue(rv);
3255 qreal x = (args->Length() > 1)?(*args)[1]->NumberValue():0;
3256 qreal y = (args->Length() > 2)?(*args)[2]->NumberValue():0;
3258 QPointF p = mapFromItem(itemObj, QPointF(x, y));
3260 rv->Set(v8::String::New("x"), v8::Number::New(p.x()));
3261 rv->Set(v8::String::New("y"), v8::Number::New(p.y()));
3265 QTransform QQuickItem::itemTransform(QQuickItem *other, bool *ok) const
3267 Q_D(const QQuickItem);
3269 // XXX todo - we need to be able to handle common parents better and detect
3273 QTransform t = d->itemToCanvasTransform();
3274 if (other) t *= QQuickItemPrivate::get(other)->canvasToItemTransform();
3279 void QQuickItem::mapToItem(QDeclarativeV8Function *args) const
3281 if (args->Length() != 0) {
3282 v8::Local<v8::Value> item = (*args)[0];
3283 QV8Engine *engine = args->engine();
3285 QQuickItem *itemObj = 0;
3286 if (!item->IsNull())
3287 itemObj = qobject_cast<QQuickItem*>(engine->toQObject(item));
3289 if (!itemObj && !item->IsNull()) {
3290 qmlInfo(this) << "mapToItem() given argument \"" << engine->toString(item->ToString())
3291 << "\" which is neither null nor an Item";
3295 v8::Local<v8::Object> rv = v8::Object::New();
3296 args->returnValue(rv);
3298 qreal x = (args->Length() > 1)?(*args)[1]->NumberValue():0;
3299 qreal y = (args->Length() > 2)?(*args)[2]->NumberValue():0;
3301 QPointF p = mapToItem(itemObj, QPointF(x, y));
3303 rv->Set(v8::String::New("x"), v8::Number::New(p.x()));
3304 rv->Set(v8::String::New("y"), v8::Number::New(p.y()));
3308 void QQuickItem::forceActiveFocus()
3311 QQuickItem *parent = parentItem();
3313 if (parent->flags() & QQuickItem::ItemIsFocusScope) {
3314 parent->setFocus(true);
3316 parent = parent->parentItem();
3320 QQuickItem *QQuickItem::childAt(qreal x, qreal y) const
3322 // XXX todo - should this include transform etc.?
3323 const QList<QQuickItem *> children = childItems();
3324 for (int i = children.count()-1; i >= 0; --i) {
3325 QQuickItem *child = children.at(i);
3326 if (child->isVisible() && child->x() <= x
3327 && child->x() + child->width() >= x
3329 && child->y() + child->height() >= y)
3335 QDeclarativeListProperty<QObject> QQuickItemPrivate::resources()
3337 return QDeclarativeListProperty<QObject>(q_func(), 0, QQuickItemPrivate::resources_append,
3338 QQuickItemPrivate::resources_count,
3339 QQuickItemPrivate::resources_at,
3340 QQuickItemPrivate::resources_clear);
3343 QDeclarativeListProperty<QQuickItem> QQuickItemPrivate::children()
3345 return QDeclarativeListProperty<QQuickItem>(q_func(), 0, QQuickItemPrivate::children_append,
3346 QQuickItemPrivate::children_count,
3347 QQuickItemPrivate::children_at,
3348 QQuickItemPrivate::children_clear);
3353 \qmlproperty real QtQuick2::Item::visibleChildren
3354 This read-only property lists all of the item's children that are currently visible.
3355 Note that a child's visibility may have changed explicitly, or because the visibility
3356 of this (it's parent) item or another grandparent changed.
3358 QDeclarativeListProperty<QQuickItem> QQuickItemPrivate::visibleChildren()
3360 return QDeclarativeListProperty<QQuickItem>(q_func(), 0, QQuickItemPrivate::visibleChildren_append,
3361 QQuickItemPrivate::visibleChildren_count,
3362 QQuickItemPrivate::visibleChildren_at);
3366 QDeclarativeListProperty<QDeclarativeState> QQuickItemPrivate::states()
3368 return _states()->statesProperty();
3371 QDeclarativeListProperty<QDeclarativeTransition> QQuickItemPrivate::transitions()
3373 return _states()->transitionsProperty();
3376 QString QQuickItemPrivate::state() const
3381 return _stateGroup->state();
3384 void QQuickItemPrivate::setState(const QString &state)
3386 _states()->setState(state);
3389 QString QQuickItem::state() const
3391 Q_D(const QQuickItem);
3395 void QQuickItem::setState(const QString &state)
3401 QDeclarativeListProperty<QQuickTransform> QQuickItem::transform()
3403 return QDeclarativeListProperty<QQuickTransform>(this, 0, QQuickItemPrivate::transform_append,
3404 QQuickItemPrivate::transform_count,
3405 QQuickItemPrivate::transform_at,
3406 QQuickItemPrivate::transform_clear);
3409 void QQuickItem::classBegin()
3412 d->componentComplete = false;
3414 d->_stateGroup->classBegin();
3416 d->_anchors->classBegin();
3417 if (d->extra.isAllocated() && d->extra->layer)
3418 d->extra->layer->classBegin();
3421 void QQuickItem::componentComplete()
3424 d->componentComplete = true;
3426 d->_stateGroup->componentComplete();
3428 d->_anchors->componentComplete();
3429 QQuickAnchorsPrivate::get(d->_anchors)->updateOnComplete();
3432 if (d->extra.isAllocated() && d->extra->layer)
3433 d->extra->layer->componentComplete();
3435 if (d->extra.isAllocated() && d->extra->keyHandler)
3436 d->extra->keyHandler->componentComplete();
3438 if (d->extra.isAllocated() && d->extra->contents)
3439 d->extra->contents->complete();
3442 QDeclarativeStateGroup *QQuickItemPrivate::_states()
3446 _stateGroup = new QDeclarativeStateGroup;
3447 if (!componentComplete)
3448 _stateGroup->classBegin();
3449 FAST_CONNECT(_stateGroup, SIGNAL(stateChanged(QString)),
3450 q, SIGNAL(stateChanged(QString)))
3456 QPointF QQuickItemPrivate::computeTransformOrigin() const
3460 case QQuickItem::TopLeft:
3461 return QPointF(0, 0);
3462 case QQuickItem::Top:
3463 return QPointF(width / 2., 0);
3464 case QQuickItem::TopRight:
3465 return QPointF(width, 0);
3466 case QQuickItem::Left:
3467 return QPointF(0, height / 2.);
3468 case QQuickItem::Center:
3469 return QPointF(width / 2., height / 2.);
3470 case QQuickItem::Right:
3471 return QPointF(width, height / 2.);
3472 case QQuickItem::BottomLeft:
3473 return QPointF(0, height);
3474 case QQuickItem::Bottom:
3475 return QPointF(width / 2., height);
3476 case QQuickItem::BottomRight:
3477 return QPointF(width, height);
3481 void QQuickItemPrivate::transformChanged()
3483 if (extra.isAllocated() && extra->layer)
3484 extra->layer->updateMatrix();
3487 void QQuickItemPrivate::deliverKeyEvent(QKeyEvent *e)
3491 Q_ASSERT(e->isAccepted());
3492 if (extra.isAllocated() && extra->keyHandler) {
3493 if (e->type() == QEvent::KeyPress)
3494 extra->keyHandler->keyPressed(e, false);
3496 extra->keyHandler->keyReleased(e, false);
3498 if (e->isAccepted())
3504 if (e->type() == QEvent::KeyPress)
3505 q->keyPressEvent(e);
3507 q->keyReleaseEvent(e);
3509 if (e->isAccepted())
3512 if (extra.isAllocated() && extra->keyHandler) {
3515 if (e->type() == QEvent::KeyPress)
3516 extra->keyHandler->keyPressed(e, true);
3518 extra->keyHandler->keyReleased(e, true);
3522 void QQuickItemPrivate::deliverInputMethodEvent(QInputMethodEvent *e)
3526 Q_ASSERT(e->isAccepted());
3527 if (extra.isAllocated() && extra->keyHandler) {
3528 extra->keyHandler->inputMethodEvent(e, false);
3530 if (e->isAccepted())
3536 q->inputMethodEvent(e);
3538 if (e->isAccepted())
3541 if (extra.isAllocated() && extra->keyHandler) {
3544 extra->keyHandler->inputMethodEvent(e, true);
3548 void QQuickItemPrivate::deliverFocusEvent(QFocusEvent *e)
3552 if (e->type() == QEvent::FocusIn) {
3555 q->focusOutEvent(e);
3559 void QQuickItemPrivate::deliverMouseEvent(QMouseEvent *e)
3563 Q_ASSERT(e->isAccepted());
3565 switch (e->type()) {
3567 Q_ASSERT(!"Unknown event type");
3568 case QEvent::MouseMove:
3569 q->mouseMoveEvent(e);
3571 case QEvent::MouseButtonPress:
3572 q->mousePressEvent(e);
3574 case QEvent::MouseButtonRelease:
3575 q->mouseReleaseEvent(e);
3577 case QEvent::MouseButtonDblClick:
3578 q->mouseDoubleClickEvent(e);
3583 void QQuickItemPrivate::deliverWheelEvent(QWheelEvent *e)
3589 void QQuickItemPrivate::deliverTouchEvent(QTouchEvent *e)
3595 void QQuickItemPrivate::deliverHoverEvent(QHoverEvent *e)
3598 switch (e->type()) {
3600 Q_ASSERT(!"Unknown event type");
3601 case QEvent::HoverEnter:
3602 q->hoverEnterEvent(e);
3604 case QEvent::HoverLeave:
3605 q->hoverLeaveEvent(e);
3607 case QEvent::HoverMove:
3608 q->hoverMoveEvent(e);
3613 void QQuickItemPrivate::deliverDragEvent(QEvent *e)
3616 switch (e->type()) {
3618 Q_ASSERT(!"Unknown event type");
3619 case QEvent::DragEnter:
3620 q->dragEnterEvent(static_cast<QDragEnterEvent *>(e));
3622 case QEvent::DragLeave:
3623 q->dragLeaveEvent(static_cast<QDragLeaveEvent *>(e));
3625 case QEvent::DragMove:
3626 q->dragMoveEvent(static_cast<QDragMoveEvent *>(e));
3629 q->dropEvent(static_cast<QDropEvent *>(e));
3634 void QQuickItem::itemChange(ItemChange change, const ItemChangeData &value)
3641 Notify input method on updated query values if needed. \a indicates changed attributes.
3643 void QQuickItem::updateInputMethod(Qt::InputMethodQueries queries)
3645 if (hasActiveFocus())
3646 qApp->inputMethod()->update(queries);
3650 // XXX todo - do we want/need this anymore?
3651 // Note that it's now used for varying clip rect
3652 QRectF QQuickItem::boundingRect() const
3654 Q_D(const QQuickItem);
3655 return QRectF(0, 0, d->width, d->height);
3658 QQuickItem::TransformOrigin QQuickItem::transformOrigin() const
3660 Q_D(const QQuickItem);
3664 void QQuickItem::setTransformOrigin(TransformOrigin origin)
3667 if (origin == d->origin())
3670 d->extra.value().origin = origin;
3671 d->dirty(QQuickItemPrivate::TransformOrigin);
3673 emit transformOriginChanged(d->origin());
3676 QPointF QQuickItem::transformOriginPoint() const
3678 Q_D(const QQuickItem);
3679 if (d->extra.isAllocated() && !d->extra->userTransformOriginPoint.isNull())
3680 return d->extra->userTransformOriginPoint;
3681 return d->computeTransformOrigin();
3684 void QQuickItem::setTransformOriginPoint(const QPointF &point)
3687 if (d->extra.value().userTransformOriginPoint == point)
3690 d->extra->userTransformOriginPoint = point;
3691 d->dirty(QQuickItemPrivate::TransformOrigin);
3694 qreal QQuickItem::z() const
3696 Q_D(const QQuickItem);
3700 void QQuickItem::setZ(qreal v)
3706 d->extra.value().z = v;
3708 d->dirty(QQuickItemPrivate::ZValue);
3709 if (d->parentItem) {
3710 QQuickItemPrivate::get(d->parentItem)->dirty(QQuickItemPrivate::ChildrenStackingChanged);
3711 QQuickItemPrivate::get(d->parentItem)->markSortedChildrenDirty(this);
3716 if (d->extra.isAllocated() && d->extra->layer)
3717 d->extra->layer->updateZ();
3722 \qmlproperty real QtQuick2::Item::rotation
3723 This property holds the rotation of the item in degrees clockwise.
3725 This specifies how many degrees to rotate the item around its transformOrigin.
3726 The default rotation is 0 degrees (i.e. not rotated at all).
3730 \o \image declarative-rotation.png
3735 width: 100; height: 100
3738 x: 25; y: 25; width: 50; height: 50
3745 \sa transform, Rotation
3749 \qmlproperty real QtQuick2::Item::scale
3750 This property holds the scale of the item.
3752 A scale of less than 1 means the item will be displayed smaller than
3753 normal, and a scale of greater than 1 means the item will be
3754 displayed larger than normal. A negative scale means the item will
3757 By default, items are displayed at a scale of 1 (i.e. at their
3760 Scaling is from the item's transformOrigin.
3764 \o \image declarative-scale.png
3769 width: 100; height: 100
3772 width: 25; height: 25
3776 x: 25; y: 25; width: 50; height: 50
3783 \sa transform, Scale
3787 \qmlproperty real QtQuick2::Item::opacity
3789 This property holds the opacity of the item. Opacity is specified as a
3790 number between 0 (fully transparent) and 1 (fully opaque). The default is 1.
3792 When this property is set, the specified opacity is also applied
3793 individually to child items. In almost all cases this is what you want,
3794 but in some cases it may produce undesired results. For example in the
3795 second set of rectangles below, the red rectangle has specified an opacity
3796 of 0.5, which affects the opacity of its blue child rectangle even though
3797 the child has not specified an opacity.
3801 \o \image declarative-item_opacity1.png
3807 width: 100; height: 100
3810 x: 50; y: 50; width: 100; height: 100
3816 \o \image declarative-item_opacity2.png
3823 width: 100; height: 100
3826 x: 50; y: 50; width: 100; height: 100
3833 If an item's opacity is set to 0, the item will no longer receive mouse
3834 events, but will continue to receive key events and will retain the keyboard
3835 \l focus if it has been set. (In contrast, setting the \l visible property
3836 to \c false stops both mouse and keyboard events, and also removes focus
3841 Returns a value indicating whether mouse input should
3842 remain with this item exclusively.
3844 \sa setKeepMouseGrab()
3847 qreal QQuickItem::rotation() const
3849 Q_D(const QQuickItem);
3850 return d->rotation();
3853 void QQuickItem::setRotation(qreal r)
3856 if (d->rotation() == r)
3859 d->extra.value().rotation = r;
3861 d->dirty(QQuickItemPrivate::BasicTransform);
3863 d->itemChange(ItemRotationHasChanged, r);
3865 emit rotationChanged();
3868 qreal QQuickItem::scale() const
3870 Q_D(const QQuickItem);
3874 void QQuickItem::setScale(qreal s)
3877 if (d->scale() == s)
3880 d->extra.value().scale = s;
3882 d->dirty(QQuickItemPrivate::BasicTransform);
3884 emit scaleChanged();
3887 qreal QQuickItem::opacity() const
3889 Q_D(const QQuickItem);
3890 return d->opacity();
3893 void QQuickItem::setOpacity(qreal o)
3896 if (d->opacity() == o)
3899 d->extra.value().opacity = o;
3901 d->dirty(QQuickItemPrivate::OpacityValue);
3903 d->itemChange(ItemOpacityHasChanged, o);
3905 emit opacityChanged();
3908 bool QQuickItem::isVisible() const
3910 Q_D(const QQuickItem);
3911 return d->effectiveVisible;
3914 void QQuickItem::setVisible(bool v)
3917 if (v == d->explicitVisible)
3920 d->explicitVisible = v;
3922 const bool childVisibilityChanged = d->setEffectiveVisibleRecur(d->calcEffectiveVisible());
3923 if (childVisibilityChanged && d->parentItem)
3924 emit d->parentItem->visibleChildrenChanged(); // signal the parent, not this!
3927 bool QQuickItem::isEnabled() const
3929 Q_D(const QQuickItem);
3930 return d->effectiveEnable;
3933 void QQuickItem::setEnabled(bool e)
3936 if (e == d->explicitEnable)
3939 d->explicitEnable = e;
3941 QQuickItem *scope = parentItem();
3942 while (scope && !scope->isFocusScope())
3943 scope = scope->parentItem();
3945 d->setEffectiveEnableRecur(scope, d->calcEffectiveEnable());
3948 bool QQuickItemPrivate::calcEffectiveVisible() const
3950 // XXX todo - Should the effective visible of an element with no parent just be the current
3951 // effective visible? This would prevent pointless re-processing in the case of an element
3952 // moving to/from a no-parent situation, but it is different from what graphics view does.
3953 return explicitVisible && (!parentItem || QQuickItemPrivate::get(parentItem)->effectiveVisible);
3956 bool QQuickItemPrivate::setEffectiveVisibleRecur(bool newEffectiveVisible)
3960 if (newEffectiveVisible && !explicitVisible) {
3961 // This item locally overrides visibility
3962 return false; // effective visibility didn't change
3965 if (newEffectiveVisible == effectiveVisible) {
3966 // No change necessary
3967 return false; // effective visibility didn't change
3970 effectiveVisible = newEffectiveVisible;
3972 if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
3975 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(canvas);
3976 if (canvasPriv->mouseGrabberItem == q)
3980 bool childVisibilityChanged = false;
3981 for (int ii = 0; ii < childItems.count(); ++ii)
3982 childVisibilityChanged |= QQuickItemPrivate::get(childItems.at(ii))->setEffectiveVisibleRecur(newEffectiveVisible);
3984 itemChange(QQuickItem::ItemVisibleHasChanged, effectiveVisible);
3987 QAccessible::updateAccessibility(QAccessibleEvent(effectiveVisible ? QAccessible::ObjectShow : QAccessible::ObjectHide, q, 0));
3989 emit q->visibleChanged();
3990 if (childVisibilityChanged)
3991 emit q->visibleChildrenChanged();
3993 return true; // effective visibility DID change
3996 bool QQuickItemPrivate::calcEffectiveEnable() const
3998 // XXX todo - Should the effective enable of an element with no parent just be the current
3999 // effective enable? This would prevent pointless re-processing in the case of an element
4000 // moving to/from a no-parent situation, but it is different from what graphics view does.
4001 return explicitEnable && (!parentItem || QQuickItemPrivate::get(parentItem)->effectiveEnable);
4004 void QQuickItemPrivate::setEffectiveEnableRecur(QQuickItem *scope, bool newEffectiveEnable)
4008 if (newEffectiveEnable && !explicitEnable) {
4009 // This item locally overrides enable
4013 if (newEffectiveEnable == effectiveEnable) {
4014 // No change necessary
4018 effectiveEnable = newEffectiveEnable;
4021 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(canvas);
4022 if (canvasPriv->mouseGrabberItem == q)
4024 if (scope && !effectiveEnable && activeFocus) {
4025 canvasPriv->clearFocusInScope(
4026 scope, q, QQuickCanvasPrivate::DontChangeFocusProperty | QQuickCanvasPrivate::DontChangeSubFocusItem);
4030 for (int ii = 0; ii < childItems.count(); ++ii) {
4031 QQuickItemPrivate::get(childItems.at(ii))->setEffectiveEnableRecur(
4032 flags & QQuickItem::ItemIsFocusScope ? q : scope, newEffectiveEnable);
4035 if (canvas && scope && effectiveEnable && focus) {
4036 QQuickCanvasPrivate::get(canvas)->setFocusInScope(
4037 scope, q, QQuickCanvasPrivate::DontChangeFocusProperty | QQuickCanvasPrivate::DontChangeSubFocusItem);
4040 emit q->enabledChanged();
4043 QString QQuickItemPrivate::dirtyToString() const
4045 #define DIRTY_TO_STRING(value) if (dirtyAttributes & value) { \
4046 if (!rv.isEmpty()) \
4047 rv.append(QLatin1String("|")); \
4048 rv.append(QLatin1String(#value)); \
4051 // QString rv = QLatin1String("0x") + QString::number(dirtyAttributes, 16);
4054 DIRTY_TO_STRING(TransformOrigin);
4055 DIRTY_TO_STRING(Transform);
4056 DIRTY_TO_STRING(BasicTransform);
4057 DIRTY_TO_STRING(Position);
4058 DIRTY_TO_STRING(Size);
4059 DIRTY_TO_STRING(ZValue);
4060 DIRTY_TO_STRING(Content);
4061 DIRTY_TO_STRING(Smooth);
4062 DIRTY_TO_STRING(OpacityValue);
4063 DIRTY_TO_STRING(ChildrenChanged);
4064 DIRTY_TO_STRING(ChildrenStackingChanged);
4065 DIRTY_TO_STRING(ParentChanged);
4066 DIRTY_TO_STRING(Clip);
4067 DIRTY_TO_STRING(Canvas);
4068 DIRTY_TO_STRING(EffectReference);
4069 DIRTY_TO_STRING(Visible);
4070 DIRTY_TO_STRING(HideReference);
4071 DIRTY_TO_STRING(PerformanceHints);
4076 void QQuickItemPrivate::dirty(DirtyType type)
4079 if (type & (TransformOrigin | Transform | BasicTransform | Position | Size))
4082 if (!(dirtyAttributes & type) || (canvas && !prevDirtyItem)) {
4083 dirtyAttributes |= type;
4086 QQuickCanvasPrivate::get(canvas)->dirtyItem(q);
4091 void QQuickItemPrivate::addToDirtyList()
4096 if (!prevDirtyItem) {
4097 Q_ASSERT(!nextDirtyItem);
4099 QQuickCanvasPrivate *p = QQuickCanvasPrivate::get(canvas);
4100 nextDirtyItem = p->dirtyItemList;
4101 if (nextDirtyItem) QQuickItemPrivate::get(nextDirtyItem)->prevDirtyItem = &nextDirtyItem;
4102 prevDirtyItem = &p->dirtyItemList;
4103 p->dirtyItemList = q;
4106 Q_ASSERT(prevDirtyItem);
4109 void QQuickItemPrivate::removeFromDirtyList()
4111 if (prevDirtyItem) {
4112 if (nextDirtyItem) QQuickItemPrivate::get(nextDirtyItem)->prevDirtyItem = prevDirtyItem;
4113 *prevDirtyItem = nextDirtyItem;
4117 Q_ASSERT(!prevDirtyItem);
4118 Q_ASSERT(!nextDirtyItem);
4121 void QQuickItemPrivate::refFromEffectItem(bool hide)
4123 ++extra.value().effectRefCount;
4124 if (1 == extra->effectRefCount) {
4125 dirty(EffectReference);
4126 if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
4129 if (++extra->hideRefCount == 1)
4130 dirty(HideReference);
4134 void QQuickItemPrivate::derefFromEffectItem(bool unhide)
4136 Q_ASSERT(extra->effectRefCount);
4137 --extra->effectRefCount;
4138 if (0 == extra->effectRefCount) {
4139 dirty(EffectReference);
4140 if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
4143 if (--extra->hideRefCount == 0)
4144 dirty(HideReference);
4148 void QQuickItemPrivate::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data)
4152 case QQuickItem::ItemChildAddedChange:
4153 q->itemChange(change, data);
4154 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4155 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4156 if (change.types & QQuickItemPrivate::Children) {
4157 change.listener->itemChildAdded(q, data.item);
4161 case QQuickItem::ItemChildRemovedChange:
4162 q->itemChange(change, data);
4163 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4164 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4165 if (change.types & QQuickItemPrivate::Children) {
4166 change.listener->itemChildRemoved(q, data.item);
4170 case QQuickItem::ItemSceneChange:
4171 q->itemChange(change, data);
4173 case QQuickItem::ItemVisibleHasChanged:
4174 q->itemChange(change, data);
4175 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4176 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4177 if (change.types & QQuickItemPrivate::Visibility) {
4178 change.listener->itemVisibilityChanged(q);
4182 case QQuickItem::ItemParentHasChanged:
4183 q->itemChange(change, data);
4184 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4185 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4186 if (change.types & QQuickItemPrivate::Parent) {
4187 change.listener->itemParentChanged(q, data.item);
4191 case QQuickItem::ItemOpacityHasChanged:
4192 q->itemChange(change, data);
4193 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4194 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4195 if (change.types & QQuickItemPrivate::Opacity) {
4196 change.listener->itemOpacityChanged(q);
4200 case QQuickItem::ItemActiveFocusHasChanged:
4201 q->itemChange(change, data);
4203 case QQuickItem::ItemRotationHasChanged:
4204 q->itemChange(change, data);
4205 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4206 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4207 if (change.types & QQuickItemPrivate::Rotation) {
4208 change.listener->itemRotationChanged(q);
4216 \property QQuickItem::smooth
4217 \brief whether the item is smoothly transformed.
4219 This property is provided purely for the purpose of optimization. Turning
4220 smooth transforms off is faster, but looks worse; turning smooth
4221 transformations on is slower, but looks better.
4223 By default smooth transformations are off.
4227 Returns true if the item should be drawn with antialiasing and
4228 smooth pixmap filtering, false otherwise.
4230 The default is false.
4234 bool QQuickItem::smooth() const
4236 Q_D(const QQuickItem);
4241 Sets whether the item should be drawn with antialiasing and
4242 smooth pixmap filtering to \a smooth.
4246 void QQuickItem::setSmooth(bool smooth)
4249 if (d->smooth == smooth)
4253 d->dirty(QQuickItemPrivate::Smooth);
4255 emit smoothChanged(smooth);
4258 QQuickItem::Flags QQuickItem::flags() const
4260 Q_D(const QQuickItem);
4261 return (QQuickItem::Flags)d->flags;
4264 void QQuickItem::setFlag(Flag flag, bool enabled)
4268 setFlags((Flags)(d->flags | (quint32)flag));
4270 setFlags((Flags)(d->flags & ~(quint32)flag));
4273 void QQuickItem::setFlags(Flags flags)
4277 if ((flags & ItemIsFocusScope) != (d->flags & ItemIsFocusScope)) {
4278 if (flags & ItemIsFocusScope && !d->childItems.isEmpty() && d->canvas) {
4279 qWarning("QQuickItem: Cannot set FocusScope once item has children and is in a canvas.");
4280 flags &= ~ItemIsFocusScope;
4281 } else if (d->flags & ItemIsFocusScope) {
4282 qWarning("QQuickItem: Cannot unset FocusScope flag.");
4283 flags |= ItemIsFocusScope;
4287 if ((flags & ItemClipsChildrenToShape ) != (d->flags & ItemClipsChildrenToShape))
4288 d->dirty(QQuickItemPrivate::Clip);
4293 qreal QQuickItem::x() const
4295 Q_D(const QQuickItem);
4299 qreal QQuickItem::y() const
4301 Q_D(const QQuickItem);
4305 QPointF QQuickItem::pos() const
4307 Q_D(const QQuickItem);
4308 return QPointF(d->x, d->y);
4311 void QQuickItem::setX(qreal v)
4320 d->dirty(QQuickItemPrivate::Position);
4322 geometryChanged(QRectF(x(), y(), width(), height()),
4323 QRectF(oldx, y(), width(), height()));
4326 void QQuickItem::setY(qreal v)
4335 d->dirty(QQuickItemPrivate::Position);
4337 geometryChanged(QRectF(x(), y(), width(), height()),
4338 QRectF(x(), oldy, width(), height()));
4341 void QQuickItem::setPos(const QPointF &pos)
4344 if (QPointF(d->x, d->y) == pos)
4353 d->dirty(QQuickItemPrivate::Position);
4355 geometryChanged(QRectF(x(), y(), width(), height()),
4356 QRectF(oldx, oldy, width(), height()));
4359 qreal QQuickItem::width() const
4361 Q_D(const QQuickItem);
4365 void QQuickItem::setWidth(qreal w)
4371 d->widthValid = true;
4375 qreal oldWidth = d->width;
4378 d->dirty(QQuickItemPrivate::Size);
4380 geometryChanged(QRectF(x(), y(), width(), height()),
4381 QRectF(x(), y(), oldWidth, height()));
4384 void QQuickItem::resetWidth()
4387 d->widthValid = false;
4388 setImplicitWidth(implicitWidth());
4391 void QQuickItemPrivate::implicitWidthChanged()
4394 emit q->implicitWidthChanged();
4397 qreal QQuickItemPrivate::getImplicitWidth() const
4399 return implicitWidth;
4402 Returns the width of the item that is implied by other properties that determine the content.
4404 qreal QQuickItem::implicitWidth() const
4406 Q_D(const QQuickItem);
4407 return d->getImplicitWidth();
4411 \qmlproperty real QtQuick2::Item::implicitWidth
4412 \qmlproperty real QtQuick2::Item::implicitHeight
4414 Defines the natural width or height of the Item if no \l width or \l height is specified.
4416 The default implicit size for most items is 0x0, however some elements have an inherent
4417 implicit size which cannot be overridden, e.g. Image, Text.
4419 Setting the implicit size is useful for defining components that have a preferred size
4420 based on their content, for example:
4427 property alias icon: image.source
4428 property alias label: text.text
4429 implicitWidth: text.implicitWidth + image.implicitWidth
4430 implicitHeight: Math.max(text.implicitHeight, image.implicitHeight)
4435 anchors.left: image.right; anchors.right: parent.right
4436 anchors.verticalCenter: parent.verticalCenter
4441 \bold Note: using implicitWidth of Text or TextEdit and setting the width explicitly
4442 incurs a performance penalty as the text must be laid out twice.
4446 Sets the implied width of the item to \a w.
4447 This is the width implied by other properties that determine the content.
4449 void QQuickItem::setImplicitWidth(qreal w)
4452 bool changed = w != d->implicitWidth;
4453 d->implicitWidth = w;
4454 if (d->width == w || widthValid()) {
4456 d->implicitWidthChanged();
4460 qreal oldWidth = d->width;
4463 d->dirty(QQuickItemPrivate::Size);
4465 geometryChanged(QRectF(x(), y(), width(), height()),
4466 QRectF(x(), y(), oldWidth, height()));
4469 d->implicitWidthChanged();
4473 Returns whether the width property has been set explicitly.
4475 bool QQuickItem::widthValid() const
4477 Q_D(const QQuickItem);
4478 return d->widthValid;
4481 qreal QQuickItem::height() const
4483 Q_D(const QQuickItem);
4487 void QQuickItem::setHeight(qreal h)
4493 d->heightValid = true;
4497 qreal oldHeight = d->height;
4500 d->dirty(QQuickItemPrivate::Size);
4502 geometryChanged(QRectF(x(), y(), width(), height()),
4503 QRectF(x(), y(), width(), oldHeight));
4506 void QQuickItem::resetHeight()
4509 d->heightValid = false;
4510 setImplicitHeight(implicitHeight());
4513 void QQuickItemPrivate::implicitHeightChanged()
4516 emit q->implicitHeightChanged();
4519 qreal QQuickItemPrivate::getImplicitHeight() const
4521 return implicitHeight;
4525 Returns the height of the item that is implied by other properties that determine the content.
4527 qreal QQuickItem::implicitHeight() const
4529 Q_D(const QQuickItem);
4530 return d->getImplicitHeight();
4535 Sets the implied height of the item to \a h.
4536 This is the height implied by other properties that determine the content.
4538 void QQuickItem::setImplicitHeight(qreal h)
4541 bool changed = h != d->implicitHeight;
4542 d->implicitHeight = h;
4543 if (d->height == h || heightValid()) {
4545 d->implicitHeightChanged();
4549 qreal oldHeight = d->height;
4552 d->dirty(QQuickItemPrivate::Size);
4554 geometryChanged(QRectF(x(), y(), width(), height()),
4555 QRectF(x(), y(), width(), oldHeight));
4558 d->implicitHeightChanged();
4561 void QQuickItem::setImplicitSize(qreal w, qreal h)
4564 bool wChanged = w != d->implicitWidth;
4565 bool hChanged = h != d->implicitHeight;
4567 d->implicitWidth = w;
4568 d->implicitHeight = h;
4572 if (d->width == w || widthValid()) {
4574 d->implicitWidthChanged();
4577 if (d->height == h || heightValid()) {
4579 d->implicitHeightChanged();
4585 qreal oldWidth = d->width;
4586 qreal oldHeight = d->height;
4592 d->dirty(QQuickItemPrivate::Size);
4594 geometryChanged(QRectF(x(), y(), width(), height()),
4595 QRectF(x(), y(), oldWidth, oldHeight));
4597 if (!wDone && wChanged)
4598 d->implicitWidthChanged();
4599 if (!hDone && hChanged)
4600 d->implicitHeightChanged();
4604 Returns whether the height property has been set explicitly.
4606 bool QQuickItem::heightValid() const
4608 Q_D(const QQuickItem);
4609 return d->heightValid;
4612 void QQuickItem::setSize(const QSizeF &size)
4615 d->heightValid = true;
4616 d->widthValid = true;
4618 if (QSizeF(d->width, d->height) == size)
4621 qreal oldHeight = d->height;
4622 qreal oldWidth = d->width;
4623 d->height = size.height();
4624 d->width = size.width();
4626 d->dirty(QQuickItemPrivate::Size);
4628 geometryChanged(QRectF(x(), y(), width(), height()),
4629 QRectF(x(), y(), oldWidth, oldHeight));
4632 bool QQuickItem::hasActiveFocus() const
4634 Q_D(const QQuickItem);
4635 return d->activeFocus;
4638 bool QQuickItem::hasFocus() const
4640 Q_D(const QQuickItem);
4644 void QQuickItem::setFocus(bool focus)
4647 if (d->focus == focus)
4651 // Need to find our nearest focus scope
4652 QQuickItem *scope = parentItem();
4653 while (scope && !scope->isFocusScope())
4654 scope = scope->parentItem();
4656 QQuickCanvasPrivate::get(d->canvas)->setFocusInScope(scope, this);
4658 QQuickCanvasPrivate::get(d->canvas)->clearFocusInScope(scope, this);
4661 emit focusChanged(focus);
4665 bool QQuickItem::isFocusScope() const
4667 return flags() & ItemIsFocusScope;
4670 QQuickItem *QQuickItem::scopedFocusItem() const
4672 Q_D(const QQuickItem);
4673 if (!isFocusScope())
4676 return d->subFocusItem;
4680 Qt::MouseButtons QQuickItem::acceptedMouseButtons() const
4682 Q_D(const QQuickItem);
4683 return d->acceptedMouseButtons();
4686 void QQuickItem::setAcceptedMouseButtons(Qt::MouseButtons buttons)
4689 if (buttons & Qt::LeftButton)
4692 d->extra.clearFlag();
4694 buttons &= ~Qt::LeftButton;
4695 if (buttons || d->extra.isAllocated())
4696 d->extra.value().acceptedMouseButtons = buttons;
4699 bool QQuickItem::filtersChildMouseEvents() const
4701 Q_D(const QQuickItem);
4702 return d->filtersChildMouseEvents;
4705 void QQuickItem::setFiltersChildMouseEvents(bool filter)
4708 d->filtersChildMouseEvents = filter;
4711 bool QQuickItem::isUnderMouse() const
4713 Q_D(const QQuickItem);
4717 QPoint cursorPos = QCursor::pos();
4718 if (QRectF(0, 0, width(), height()).contains(mapFromScene(cursorPos))) // ### refactor: d->canvas->mapFromGlobal(cursorPos))))
4723 bool QQuickItem::acceptHoverEvents() const
4725 Q_D(const QQuickItem);
4726 return d->hoverEnabled;
4729 void QQuickItem::setAcceptHoverEvents(bool enabled)
4732 d->hoverEnabled = enabled;
4735 void QQuickItem::grabMouse()
4740 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
4741 if (canvasPriv->mouseGrabberItem == this)
4744 QQuickItem *oldGrabber = canvasPriv->mouseGrabberItem;
4745 canvasPriv->mouseGrabberItem = this;
4747 oldGrabber->mouseUngrabEvent();
4750 void QQuickItem::ungrabMouse()
4755 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
4756 if (canvasPriv->mouseGrabberItem != this) {
4757 qWarning("QQuickItem::ungrabMouse(): Item is not the mouse grabber.");
4761 canvasPriv->mouseGrabberItem = 0;
4765 bool QQuickItem::keepMouseGrab() const
4767 Q_D(const QQuickItem);
4768 return d->keepMouse;
4772 The flag indicating whether the mouse should remain
4773 with this item is set to \a keep.
4775 This is useful for items that wish to grab and keep mouse
4776 interaction following a predefined gesture. For example,
4777 an item that is interested in horizontal mouse movement
4778 may set keepMouseGrab to true once a threshold has been
4779 exceeded. Once keepMouseGrab has been set to true, filtering
4780 items will not react to mouse events.
4782 If the item does not indicate that it wishes to retain mouse grab,
4783 a filtering item may steal the grab. For example, Flickable may attempt
4784 to steal a mouse grab if it detects that the user has begun to
4789 void QQuickItem::setKeepMouseGrab(bool keep)
4792 d->keepMouse = keep;
4796 Grabs the touch points specified by \a ids.
4798 These touch points will be owned by the item until
4799 they are released. Alternatively, the grab can be stolen
4800 by a filtering item like Flickable. Use setKeepTouchGrab()
4801 to prevent the grab from being stolen.
4803 \sa ungrabTouchPoints(), setKeepTouchGrab()
4805 void QQuickItem::grabTouchPoints(const QList<int> &ids)
4810 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
4812 QSet<QQuickItem*> ungrab;
4813 for (int i = 0; i < ids.count(); ++i) {
4814 QQuickItem *oldGrabber = canvasPriv->itemForTouchPointId.value(ids.at(i));
4815 if (oldGrabber == this)
4818 canvasPriv->itemForTouchPointId[ids.at(i)] = this;
4820 ungrab.insert(oldGrabber);
4822 foreach (QQuickItem *oldGrabber, ungrab)
4823 oldGrabber->touchUngrabEvent();
4827 Ungrabs the touch points owned by this item.
4829 \sa grabTouchPoints()
4831 void QQuickItem::ungrabTouchPoints()
4836 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
4838 QMutableHashIterator<int, QQuickItem*> i(canvasPriv->itemForTouchPointId);
4839 while (i.hasNext()) {
4841 if (i.value() == this)
4848 Returns a value indicating whether the touch points grabbed by this item
4849 should remain with this item exclusively.
4851 \sa setKeepTouchGrab(), keepMouseGrab()
4853 bool QQuickItem::keepTouchGrab() const
4855 Q_D(const QQuickItem);
4856 return d->keepTouch;
4860 The flag indicating whether the touch points grabbed
4861 by this item should remain with this item is set to \a keep.
4863 This is useful for items that wish to grab and keep specific touch
4864 points following a predefined gesture. For example,
4865 an item that is interested in horizontal touch point movement
4866 may set setKeepTouchGrab to true once a threshold has been
4867 exceeded. Once setKeepTouchGrab has been set to true, filtering
4868 items will not react to the relevant touch points.
4870 If the item does not indicate that it wishes to retain touch point grab,
4871 a filtering item may steal the grab. For example, Flickable may attempt
4872 to steal a touch point grab if it detects that the user has begun to
4875 \sa keepTouchGrab(), setKeepMouseGrab()
4877 void QQuickItem::setKeepTouchGrab(bool keep)
4880 d->keepTouch = keep;
4884 \qmlmethod object QtQuick2::Item::mapFromItem(Item item, real x, real y)
4886 Maps the point (\a x, \a y), which is in \a item's coordinate system, to
4887 this item's coordinate system, and returns an object with \c x and \c y
4888 properties matching the mapped coordinate.
4890 If \a item is a \c null value, this maps the point from the coordinate
4891 system of the root QML view.
4894 \qmlmethod object QtQuick2::Item::mapToItem(Item item, real x, real y)
4896 Maps the point (\a x, \a y), which is in this item's coordinate system, to
4897 \a item's coordinate system, and returns an object with \c x and \c y
4898 properties matching the mapped coordinate.
4900 If \a item is a \c null value, this maps \a x and \a y to the coordinate
4901 system of the root QML view.
4903 QPointF QQuickItem::mapToItem(const QQuickItem *item, const QPointF &point) const
4905 QPointF p = mapToScene(point);
4907 p = item->mapFromScene(p);
4911 QPointF QQuickItem::mapToScene(const QPointF &point) const
4913 Q_D(const QQuickItem);
4914 return d->itemToCanvasTransform().map(point);
4917 QRectF QQuickItem::mapRectToItem(const QQuickItem *item, const QRectF &rect) const
4919 Q_D(const QQuickItem);
4920 QTransform t = d->itemToCanvasTransform();
4922 t *= QQuickItemPrivate::get(item)->canvasToItemTransform();
4923 return t.mapRect(rect);
4926 QRectF QQuickItem::mapRectToScene(const QRectF &rect) const
4928 Q_D(const QQuickItem);
4929 return d->itemToCanvasTransform().mapRect(rect);
4932 QPointF QQuickItem::mapFromItem(const QQuickItem *item, const QPointF &point) const
4934 QPointF p = item?item->mapToScene(point):point;
4935 return mapFromScene(p);
4938 QPointF QQuickItem::mapFromScene(const QPointF &point) const
4940 Q_D(const QQuickItem);
4941 return d->canvasToItemTransform().map(point);
4944 QRectF QQuickItem::mapRectFromItem(const QQuickItem *item, const QRectF &rect) const
4946 Q_D(const QQuickItem);
4947 QTransform t = item?QQuickItemPrivate::get(item)->itemToCanvasTransform():QTransform();
4948 t *= d->canvasToItemTransform();
4949 return t.mapRect(rect);
4952 QRectF QQuickItem::mapRectFromScene(const QRectF &rect) const
4954 Q_D(const QQuickItem);
4955 return d->canvasToItemTransform().mapRect(rect);
4960 \qmlmethod QtQuick2::Item::forceActiveFocus()
4962 Forces active focus on the item.
4964 This method sets focus on the item and makes sure that all the focus scopes
4965 higher in the object hierarchy are also given the focus.
4969 Forces active focus on the item.
4971 This method sets focus on the item and makes sure that all the focus scopes
4972 higher in the object hierarchy are also given the focus.
4976 \qmlmethod QtQuick2::Item::childAt(real x, real y)
4978 Returns the visible child item at point (\a x, \a y), which is in this
4979 item's coordinate system, or \c null if there is no such item.
4983 Returns the visible child item at point (\a x, \a y), which is in this
4984 item's coordinate system, or 0 if there is no such item.
4988 \qmlproperty list<State> QtQuick2::Item::states
4989 This property holds a list of states defined by the item.
5005 \sa {qmlstate}{States}
5008 \qmlproperty list<Transition> QtQuick2::Item::transitions
5009 This property holds a list of transitions defined by the item.
5025 \sa {QML Animation and Transitions}{Transitions}
5028 \qmlproperty list<Filter> QtQuick2::Item::filter
5029 This property holds a list of graphical filters to be applied to the item.
5031 \l {Filter}{Filters} include things like \l {Blur}{blurring}
5032 the item, or giving it a \l Reflection. Some
5033 filters may not be available on all canvases; if a filter is not
5034 available on a certain canvas, it will simply not be applied for
5035 that canvas (but the QML will still be considered valid).
5053 \qmlproperty bool QtQuick2::Item::clip
5054 This property holds whether clipping is enabled. The default clip value is \c false.
5056 If clipping is enabled, an item will clip its own painting, as well
5057 as the painting of its children, to its bounding rectangle.
5059 Non-rectangular clipping regions are not supported for performance reasons.
5063 \property QQuickItem::clip
5064 This property holds whether clipping is enabled. The default clip value is \c false.
5066 If clipping is enabled, an item will clip its own painting, as well
5067 as the painting of its children, to its bounding rectangle. If you set
5068 clipping during an item's paint operation, remember to re-set it to
5069 prevent clipping the rest of your scene.
5071 Non-rectangular clipping regions are not supported for performance reasons.
5075 \qmlproperty string QtQuick2::Item::state
5077 This property holds the name of the current state of the item.
5079 This property is often used in scripts to change between states. For
5084 if (button.state == 'On')
5085 button.state = 'Off';
5087 button.state = 'On';
5091 If the item is in its base state (i.e. no explicit state has been
5092 set), \c state will be a blank string. Likewise, you can return an
5093 item to its base state by setting its current state to \c ''.
5095 \sa {qmlstates}{States}
5099 \qmlproperty list<Transform> QtQuick2::Item::transform
5100 This property holds the list of transformations to apply.
5102 For more information see \l Transform.
5106 \enum QQuickItem::TransformOrigin
5108 Controls the point about which simple transforms like scale apply.
5110 \value TopLeft The top-left corner of the item.
5111 \value Top The center point of the top of the item.
5112 \value TopRight The top-right corner of the item.
5113 \value Left The left most point of the vertical middle.
5114 \value Center The center of the item.
5115 \value Right The right most point of the vertical middle.
5116 \value BottomLeft The bottom-left corner of the item.
5117 \value Bottom The center point of the bottom of the item.
5118 \value BottomRight The bottom-right corner of the item.
5123 \qmlproperty bool QtQuick2::Item::activeFocus
5125 This property indicates whether the item has active focus.
5127 An item with active focus will receive keyboard input,
5128 or is a FocusScope ancestor of the item that will receive keyboard input.
5130 Usually, activeFocus is gained by setting focus on an item and its enclosing
5131 FocusScopes. In the following example \c input will have activeFocus.
5144 \sa focus, {qmlfocus}{Keyboard Focus}
5148 \qmlproperty bool QtQuick2::Item::focus
5149 This property indicates whether the item has focus within the enclosing focus scope. If true, this item
5150 will gain active focus when the enclosing focus scope gains active focus.
5151 In the following example, \c input will be given active focus when \c scope gains active focus.
5164 For the purposes of this property, the scene as a whole is assumed to act like a focus scope.
5165 On a practical level, that means the following QML will give active focus to \c input on startup.
5176 \sa activeFocus, {qmlfocus}{Keyboard Focus}
5181 \property QQuickItem::anchors
5186 \property QQuickItem::left
5191 \property QQuickItem::right
5196 \property QQuickItem::horizontalCenter
5201 \property QQuickItem::top
5206 \property QQuickItem::bottom
5211 \property QQuickItem::verticalCenter
5216 \property QQuickItem::focus
5221 \property QQuickItem::transform
5226 \property QQuickItem::transformOrigin
5231 \property QQuickItem::activeFocus
5236 \property QQuickItem::baseline
5241 \property QQuickItem::data
5246 \property QQuickItem::resources
5251 \property QQuickItem::state
5256 \property QQuickItem::states
5261 \property QQuickItem::transformOriginPoint
5266 \property QQuickItem::transitions
5270 bool QQuickItem::event(QEvent *ev)
5273 if (ev->type() == QEvent::PolishRequest) {
5275 d->polishScheduled = false;
5279 return QObject::event(ev);
5282 if (ev->type() == QEvent::InputMethodQuery) {
5283 QInputMethodQueryEvent *query = static_cast<QInputMethodQueryEvent *>(ev);
5284 Qt::InputMethodQueries queries = query->queries();
5285 for (uint i = 0; i < 32; ++i) {
5286 Qt::InputMethodQuery q = (Qt::InputMethodQuery)(int)(queries & (1<<i));
5288 QVariant v = inputMethodQuery(q);
5289 query->setValue(q, v);
5294 } else if (ev->type() == QEvent::InputMethod) {
5295 inputMethodEvent(static_cast<QInputMethodEvent *>(ev));
5298 return QObject::event(ev);
5301 #ifndef QT_NO_DEBUG_STREAM
5302 QDebug operator<<(QDebug debug, QQuickItem *item)
5305 debug << "QQuickItem(0)";
5309 debug << item->metaObject()->className() << "(this =" << ((void*)item)
5310 << ", name=" << item->objectName()
5311 << ", parent =" << ((void*)item->parentItem())
5312 << ", geometry =" << QRectF(item->pos(), QSizeF(item->width(), item->height()))
5313 << ", z =" << item->z() << ')';
5318 qint64 QQuickItemPrivate::consistentTime = -1;
5319 void QQuickItemPrivate::setConsistentTime(qint64 t)
5324 class QElapsedTimerConsistentTimeHack
5328 t1 = QQuickItemPrivate::consistentTime;
5332 return QQuickItemPrivate::consistentTime - t1;
5335 qint64 val = QQuickItemPrivate::consistentTime - t1;
5336 t1 = QQuickItemPrivate::consistentTime;
5346 void QQuickItemPrivate::start(QElapsedTimer &t)
5348 if (QQuickItemPrivate::consistentTime == -1)
5351 ((QElapsedTimerConsistentTimeHack*)&t)->start();
5354 qint64 QQuickItemPrivate::elapsed(QElapsedTimer &t)
5356 if (QQuickItemPrivate::consistentTime == -1)
5359 return ((QElapsedTimerConsistentTimeHack*)&t)->elapsed();
5362 qint64 QQuickItemPrivate::restart(QElapsedTimer &t)
5364 if (QQuickItemPrivate::consistentTime == -1)
5367 return ((QElapsedTimerConsistentTimeHack*)&t)->restart();
5371 \fn bool QQuickItem::isTextureProvider() const
5373 Returns true if this item is a texture provider. The default
5374 implementation returns false.
5376 This function can be called from any thread.
5379 bool QQuickItem::isTextureProvider() const
5381 Q_D(const QQuickItem);
5382 return d->extra.isAllocated() && d->extra->layer && d->extra->layer->effectSource() ?
5383 d->extra->layer->effectSource()->isTextureProvider() : false;
5387 \fn QSGTextureProvider *QQuickItem::textureProvider() const
5389 Returns the texture provider for an item. The default implementation
5392 This function may only be called on the rendering thread.
5395 QSGTextureProvider *QQuickItem::textureProvider() const
5397 Q_D(const QQuickItem);
5398 return d->extra.isAllocated() && d->extra->layer && d->extra->layer->effectSource() ?
5399 d->extra->layer->effectSource()->textureProvider() : 0;
5402 QQuickItemLayer *QQuickItemPrivate::layer() const
5404 if (!extra.isAllocated() || !extra->layer) {
5405 extra.value().layer = new QQuickItemLayer(const_cast<QQuickItem *>(q_func()));
5406 if (!componentComplete)
5407 extra->layer->classBegin();
5409 return extra->layer;
5412 QQuickItemLayer::QQuickItemLayer(QQuickItem *item)
5417 , m_componentComplete(true)
5418 , m_wrapMode(QQuickShaderEffectSource::ClampToEdge)
5419 , m_format(QQuickShaderEffectSource::RGBA)
5421 , m_effectComponent(0)
5427 QQuickItemLayer::~QQuickItemLayer()
5429 delete m_effectSource;
5436 \qmlproperty bool QtQuick2::Item::layer.enabled
5438 Holds wether the item is layered or not. Layering is disabled by default.
5440 A layered item is rendered into an offscreen surface and cached until
5441 it is changed. Enabling layering for complex QML item hierarchies can
5442 some times be an optimization.
5444 None of the other layer properties have any effect when the layer
5448 void QQuickItemLayer::setEnabled(bool e)
5453 if (m_componentComplete) {
5460 emit enabledChanged(e);
5463 void QQuickItemLayer::classBegin()
5465 Q_ASSERT(!m_effectSource);
5466 Q_ASSERT(!m_effect);
5467 m_componentComplete = false;
5470 void QQuickItemLayer::componentComplete()
5472 Q_ASSERT(!m_componentComplete);
5473 m_componentComplete = true;
5478 void QQuickItemLayer::activate()
5480 Q_ASSERT(!m_effectSource);
5481 m_effectSource = new QQuickShaderEffectSource();
5483 QQuickItem *parentItem = m_item->parentItem();
5485 m_effectSource->setParentItem(parentItem);
5486 m_effectSource->stackAfter(m_item);
5489 m_effectSource->setSourceItem(m_item);
5490 m_effectSource->setHideSource(true);
5491 m_effectSource->setSmooth(m_smooth);
5492 m_effectSource->setTextureSize(m_size);
5493 m_effectSource->setSourceRect(m_sourceRect);
5494 m_effectSource->setMipmap(m_mipmap);
5495 m_effectSource->setWrapMode(m_wrapMode);
5496 m_effectSource->setFormat(m_format);
5498 if (m_effectComponent)
5501 m_effectSource->setVisible(m_item->isVisible() && !m_effect);
5508 QQuickItemPrivate *id = QQuickItemPrivate::get(m_item);
5509 id->addItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Opacity | QQuickItemPrivate::Parent | QQuickItemPrivate::Visibility | QQuickItemPrivate::SiblingOrder);
5512 void QQuickItemLayer::deactivate()
5514 Q_ASSERT(m_effectSource);
5516 if (m_effectComponent)
5519 delete m_effectSource;
5522 QQuickItemPrivate *id = QQuickItemPrivate::get(m_item);
5523 id->removeItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Opacity | QQuickItemPrivate::Parent | QQuickItemPrivate::Visibility | QQuickItemPrivate::SiblingOrder);
5526 void QQuickItemLayer::activateEffect()
5528 Q_ASSERT(m_effectSource);
5529 Q_ASSERT(m_effectComponent);
5530 Q_ASSERT(!m_effect);
5532 QObject *created = m_effectComponent->create();
5533 m_effect = qobject_cast<QQuickItem *>(created);
5535 qWarning("Item: layer.effect is not a QML Item.");
5539 QQuickItem *parentItem = m_item->parentItem();
5541 m_effect->setParentItem(parentItem);
5542 m_effect->stackAfter(m_effectSource);
5544 m_effect->setVisible(m_item->isVisible());
5545 m_effect->setProperty(m_name, qVariantFromValue<QObject *>(m_effectSource));
5548 void QQuickItemLayer::deactivateEffect()
5550 Q_ASSERT(m_effectSource);
5551 Q_ASSERT(m_effectComponent);
5559 \qmlproperty Component QtQuick2::Item::layer.effect
5561 Holds the effect that is applied to this layer.
5563 The effect is typically a \l ShaderEffect component, although any \l Item component can be
5564 assigned. The effect should have a source texture property with a name matching \l samplerName.
5569 void QQuickItemLayer::setEffect(QDeclarativeComponent *component)
5571 if (component == m_effectComponent)
5574 bool updateNeeded = false;
5575 if (m_effectSource && m_effectComponent) {
5577 updateNeeded = true;
5580 m_effectComponent = component;
5582 if (m_effectSource && m_effectComponent) {
5584 updateNeeded = true;
5592 m_effectSource->setVisible(m_item->isVisible() && !m_effect);
5595 emit effectChanged(component);
5600 \qmlproperty bool QtQuick2::Item::layer.mipmap
5602 If this property is true, mipmaps are generated for the texture.
5604 \note Some OpenGL ES 2 implementations do not support mipmapping of
5605 non-power-of-two textures.
5608 void QQuickItemLayer::setMipmap(bool mipmap)
5610 if (mipmap == m_mipmap)
5615 m_effectSource->setMipmap(m_mipmap);
5617 emit mipmapChanged(mipmap);
5622 \qmlproperty enumeration QtQuick2::Item::layer.format
5624 This property defines the internal OpenGL format of the texture.
5625 Modifying this property makes most sense when the \a layer.effect is also
5626 specified. Depending on the OpenGL implementation, this property might
5627 allow you to save some texture memory.
5630 \o ShaderEffectSource.Alpha - GL_ALPHA
5631 \o ShaderEffectSource.RGB - GL_RGB
5632 \o ShaderEffectSource.RGBA - GL_RGBA
5635 \note Some OpenGL implementations do not support the GL_ALPHA format.
5638 void QQuickItemLayer::setFormat(QQuickShaderEffectSource::Format f)
5645 m_effectSource->setFormat(m_format);
5647 emit formatChanged(m_format);
5652 \qmlproperty enumeration QtQuick2::Item::layer.sourceRect
5654 This property defines which rectangular area of the \l sourceItem to
5655 render into the texture. The source rectangle can be larger than
5656 \l sourceItem itself. If the rectangle is null, which is the default,
5657 the whole \l sourceItem is rendered to texture.
5660 void QQuickItemLayer::setSourceRect(const QRectF &sourceRect)
5662 if (sourceRect == m_sourceRect)
5664 m_sourceRect = sourceRect;
5667 m_effectSource->setSourceRect(m_sourceRect);
5669 emit sourceRectChanged(sourceRect);
5675 \qmlproperty bool QtQuick2::Item::layer.smooth
5677 Holds whether the layer is smoothly transformed.
5680 void QQuickItemLayer::setSmooth(bool s)
5687 m_effectSource->setSmooth(m_smooth);
5689 emit smoothChanged(s);
5695 \qmlproperty size QtQuick2::Item::layer.textureSize
5697 This property holds the requested pixel size of the layers texture. If it is empty,
5698 which is the default, the size of the item is used.
5700 \note Some platforms have a limit on how small framebuffer objects can be,
5701 which means the actual texture size might be larger than the requested
5705 void QQuickItemLayer::setSize(const QSize &size)
5712 m_effectSource->setTextureSize(size);
5714 emit sizeChanged(size);
5720 \qmlproperty enumeration QtQuick2::Item::layer.wrapMode
5722 This property defines the OpenGL wrap modes associated with the texture.
5723 Modifying this property makes most sense when the \a layer.effect is
5727 \o ShaderEffectSource.ClampToEdge - GL_CLAMP_TO_EDGE both horizontally and vertically
5728 \o ShaderEffectSource.RepeatHorizontally - GL_REPEAT horizontally, GL_CLAMP_TO_EDGE vertically
5729 \o ShaderEffectSource.RepeatVertically - GL_CLAMP_TO_EDGE horizontally, GL_REPEAT vertically
5730 \o ShaderEffectSource.Repeat - GL_REPEAT both horizontally and vertically
5733 \note Some OpenGL ES 2 implementations do not support the GL_REPEAT
5734 wrap mode with non-power-of-two textures.
5737 void QQuickItemLayer::setWrapMode(QQuickShaderEffectSource::WrapMode mode)
5739 if (mode != m_wrapMode)
5744 m_effectSource->setWrapMode(m_wrapMode);
5746 emit wrapModeChanged(mode);
5750 \qmlproperty string QtQuick2::Item::layer.samplerName
5752 Holds the name of the effect's source texture property.
5754 samplerName needs to match the name of the effect's source texture property
5755 so that the Item can pass the layer's offscreen surface to the effect correctly.
5757 \sa effect, ShaderEffect
5760 void QQuickItemLayer::setName(const QByteArray &name) {
5764 m_effect->setProperty(m_name, QVariant());
5765 m_effect->setProperty(name, qVariantFromValue<QObject *>(m_effectSource));
5768 emit nameChanged(name);
5771 void QQuickItemLayer::itemOpacityChanged(QQuickItem *item)
5777 void QQuickItemLayer::itemGeometryChanged(QQuickItem *, const QRectF &, const QRectF &)
5782 void QQuickItemLayer::itemParentChanged(QQuickItem *item, QQuickItem *parent)
5785 Q_ASSERT(item == m_item);
5786 Q_ASSERT(parent != m_effectSource);
5787 Q_ASSERT(parent == 0 || parent != m_effect);
5789 m_effectSource->setParentItem(parent);
5791 m_effectSource->stackAfter(m_item);
5794 m_effect->setParentItem(parent);
5796 m_effect->stackAfter(m_effectSource);
5800 void QQuickItemLayer::itemSiblingOrderChanged(QQuickItem *)
5802 m_effectSource->stackAfter(m_item);
5804 m_effect->stackAfter(m_effectSource);
5807 void QQuickItemLayer::itemVisibilityChanged(QQuickItem *)
5809 QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
5811 l->setVisible(m_item->isVisible());
5814 void QQuickItemLayer::updateZ()
5816 if (!m_componentComplete || !m_enabled)
5818 QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
5820 l->setZ(m_item->z());
5823 void QQuickItemLayer::updateOpacity()
5825 QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
5827 l->setOpacity(m_item->opacity());
5830 void QQuickItemLayer::updateGeometry()
5832 QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
5834 QRectF bounds = m_item->boundingRect();
5835 l->setWidth(bounds.width());
5836 l->setHeight(bounds.height());
5837 l->setX(bounds.x() + m_item->x());
5838 l->setY(bounds.y() + m_item->y());
5841 void QQuickItemLayer::updateMatrix()
5843 // Called directly from transformChanged(), so needs some extra
5845 if (!m_componentComplete || !m_enabled)
5847 QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
5849 QQuickItemPrivate *ld = QQuickItemPrivate::get(l);
5850 l->setScale(m_item->scale());
5851 l->setRotation(m_item->rotation());
5852 ld->transforms = QQuickItemPrivate::get(m_item)->transforms;
5853 if (ld->origin() != QQuickItemPrivate::get(m_item)->origin())
5854 ld->extra.value().origin = QQuickItemPrivate::get(m_item)->origin();
5855 ld->dirty(QQuickItemPrivate::Transform);
5858 QQuickItemPrivate::ExtraData::ExtraData()
5859 : z(0), scale(1), rotation(0), opacity(1),
5860 contents(0), screenAttached(0), layoutDirectionAttached(0),
5861 keyHandler(0), layer(0), effectRefCount(0), hideRefCount(0),
5862 opacityNode(0), clipNode(0), rootNode(0), beforePaintNode(0),
5863 acceptedMouseButtons(0), origin(QQuickItem::Center)
5869 #include <moc_qquickitem.cpp>