1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the QtQml module of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #include "qquickitem.h"
44 #include "qquickcanvas.h"
45 #include <QtQml/qjsengine.h>
46 #include "qquickcanvas_p.h"
48 #include "qquickevents_p_p.h"
49 #include "qquickscreen_p.h"
51 #include <QtQml/qqmlengine.h>
52 #include <QtQml/qqmlcomponent.h>
53 #include <QtQml/qqmlinfo.h>
54 #include <QtGui/qpen.h>
55 #include <QtGui/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/qqmlglobal_p.h>
63 #include <private/qqmlengine_p.h>
64 #include <QtQuick/private/qquickstategroup_p.h>
65 #include <private/qqmlopenmetaobject_p.h>
66 #include <QtQuick/private/qquickstate_p.h>
67 #include <private/qlistmodelinterface_p.h>
68 #include <private/qquickitem_p.h>
69 #include <private/qqmlaccessors_p.h>
70 #include <QtQuick/private/qquickaccessibleattached_p.h>
74 // XXX todo Check that elements that create items handle memory correctly after visual ownership change
78 static void QQuickItem_parentNotifier(QObject *o, intptr_t, QQmlNotifier **n)
80 QQuickItemPrivate *d = QQuickItemPrivate::get(static_cast<QQuickItem *>(o));
81 *n = &d->parentNotifier;
84 QML_PRIVATE_ACCESSOR(QQuickItem, QQuickItem *, parent, parentItem)
85 QML_PRIVATE_ACCESSOR(QQuickItem, qreal, x, x)
86 QML_PRIVATE_ACCESSOR(QQuickItem, qreal, y, y)
87 QML_PRIVATE_ACCESSOR(QQuickItem, qreal, width, width)
88 QML_PRIVATE_ACCESSOR(QQuickItem, qreal, height, height)
90 static QQmlAccessors QQuickItem_parent = { QQuickItem_parentRead, QQuickItem_parentNotifier };
91 static QQmlAccessors QQuickItem_x = { QQuickItem_xRead, 0 };
92 static QQmlAccessors QQuickItem_y = { QQuickItem_yRead, 0 };
93 static QQmlAccessors QQuickItem_width = { QQuickItem_widthRead, 0 };
94 static QQmlAccessors QQuickItem_height = { QQuickItem_heightRead, 0 };
96 QML_DECLARE_PROPERTIES(QQuickItem) {
97 { QML_PROPERTY_NAME(parent), 0, &QQuickItem_parent },
98 { QML_PROPERTY_NAME(x), 0, &QQuickItem_x },
99 { QML_PROPERTY_NAME(y), 0, &QQuickItem_y },
100 { QML_PROPERTY_NAME(width), 0, &QQuickItem_width },
101 { QML_PROPERTY_NAME(height), 0, &QQuickItem_height }
104 void QQuickItemPrivate::registerAccessorProperties()
106 QML_DEFINE_PROPERTIES(QQuickItem);
110 \qmlclass Transform QQuickTransform
111 \inqmlmodule QtQuick 2
112 \ingroup qml-transform-elements
113 \brief The Transform elements provide a way of building advanced transformations on Items.
115 The Transform element is a base type which cannot be instantiated directly.
116 The following concrete Transform types are available:
124 The Transform elements let you create and control advanced transformations that can be configured
125 independently using specialized properties.
127 You can assign any number of Transform elements to an \l Item. Each Transform is applied in order,
132 \qmlclass Translate QQuickTranslate
133 \inqmlmodule QtQuick 2
134 \ingroup qml-transform-elements
135 \brief The Translate object provides a way to move an Item without changing its x or y properties.
137 The Translate object provides independent control over position in addition to the Item's x and y properties.
139 The following example moves the Y axis of the \l Rectangle elements while still allowing the \l Row element
140 to lay the items out as if they had not been transformed:
146 width: 100; height: 100
148 transform: Translate { y: 20 }
151 width: 100; height: 100
153 transform: Translate { y: -20 }
162 \qmlproperty real QtQuick2::Translate::x
164 The translation along the X axis.
168 \qmlproperty real QtQuick2::Translate::y
170 The translation along the Y axis.
174 \qmlclass Scale QQuickScale
175 \inqmlmodule QtQuick 2
176 \ingroup qml-transform-elements
177 \brief The Scale element provides a way to scale an Item.
179 The Scale element gives more control over scaling than using \l Item's \l{Item::scale}{scale} property. Specifically,
180 it allows a different scale for the x and y axes, and allows the scale to be relative to an
183 The following example scales the X axis of the Rectangle, relative to its interior point 25, 25:
186 width: 100; height: 100
188 transform: Scale { origin.x: 25; origin.y: 25; xScale: 3}
192 \sa Rotation, Translate
196 \qmlproperty real QtQuick2::Scale::origin.x
197 \qmlproperty real QtQuick2::Scale::origin.y
199 The point that the item is scaled from (i.e., the point that stays fixed relative to the parent as
200 the rest of the item grows). By default the origin is 0, 0.
204 \qmlproperty real QtQuick2::Scale::xScale
206 The scaling factor for the X axis.
210 \qmlproperty real QtQuick2::Scale::yScale
212 The scaling factor for the Y axis.
216 \qmlclass Rotation QQuickRotation
217 \inqmlmodule QtQuick 2
218 \ingroup qml-transform-elements
219 \brief The Rotation object provides a way to rotate an Item.
221 The Rotation object gives more control over rotation than using \l Item's \l{Item::rotation}{rotation} property.
222 Specifically, it allows (z axis) rotation to be relative to an arbitrary point.
224 The following example rotates a Rectangle around its interior point 25, 25:
227 width: 100; height: 100
229 transform: Rotation { origin.x: 25; origin.y: 25; angle: 45}
233 Rotation also provides a way to specify 3D-like rotations for Items. For these types of
234 rotations you must specify the axis to rotate around in addition to the origin point.
236 The following example shows various 3D-like rotations applied to an \l Image.
237 \snippet doc/src/snippets/qml/rotation.qml 0
239 \image axisrotation.png
241 \sa {declarative/ui-components/dialcontrol}{Dial Control example}, {declarative/toys/clocks}{Clocks example}
245 \qmlproperty real QtQuick2::Rotation::origin.x
246 \qmlproperty real QtQuick2::Rotation::origin.y
248 The origin point of the rotation (i.e., the point that stays fixed relative to the parent as
249 the rest of the item rotates). By default the origin is 0, 0.
253 \qmlproperty real QtQuick2::Rotation::axis.x
254 \qmlproperty real QtQuick2::Rotation::axis.y
255 \qmlproperty real QtQuick2::Rotation::axis.z
257 The axis to rotate around. For simple (2D) rotation around a point, you do not need to specify an axis,
258 as the default axis is the z axis (\c{ axis { x: 0; y: 0; z: 1 } }).
260 For a typical 3D-like rotation you will usually specify both the origin and the axis.
262 \image 3d-rotation-axis.png
266 \qmlproperty real QtQuick2::Rotation::angle
268 The angle to rotate, in degrees clockwise.
271 QQuickTransformPrivate::QQuickTransformPrivate()
275 QQuickTransform::QQuickTransform(QObject *parent)
276 : QObject(*(new QQuickTransformPrivate), parent)
280 QQuickTransform::QQuickTransform(QQuickTransformPrivate &dd, QObject *parent)
281 : QObject(dd, parent)
285 QQuickTransform::~QQuickTransform()
287 Q_D(QQuickTransform);
288 for (int ii = 0; ii < d->items.count(); ++ii) {
289 QQuickItemPrivate *p = QQuickItemPrivate::get(d->items.at(ii));
290 p->transforms.removeOne(this);
291 p->dirty(QQuickItemPrivate::Transform);
295 void QQuickTransform::update()
297 Q_D(QQuickTransform);
298 for (int ii = 0; ii < d->items.count(); ++ii) {
299 QQuickItemPrivate *p = QQuickItemPrivate::get(d->items.at(ii));
300 p->dirty(QQuickItemPrivate::Transform);
304 QQuickContents::QQuickContents(QQuickItem *item)
305 : m_item(item), m_x(0), m_y(0), m_width(0), m_height(0)
309 QQuickContents::~QQuickContents()
311 QList<QQuickItem *> children = m_item->childItems();
312 for (int i = 0; i < children.count(); ++i) {
313 QQuickItem *child = children.at(i);
314 QQuickItemPrivate::get(child)->removeItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed);
318 bool QQuickContents::calcHeight(QQuickItem *changed)
321 qreal oldheight = m_height;
325 qreal bottom = oldy + oldheight;
326 qreal y = changed->y();
327 if (y + changed->height() > bottom)
328 bottom = y + changed->height();
332 m_height = bottom - top;
336 QList<QQuickItem *> children = m_item->childItems();
337 for (int i = 0; i < children.count(); ++i) {
338 QQuickItem *child = children.at(i);
339 qreal y = child->y();
340 if (y + child->height() > bottom)
341 bottom = y + child->height();
345 if (!children.isEmpty())
347 m_height = qMax(bottom - top, qreal(0.0));
350 return (m_height != oldheight || m_y != oldy);
353 bool QQuickContents::calcWidth(QQuickItem *changed)
356 qreal oldwidth = m_width;
360 qreal right = oldx + oldwidth;
361 qreal x = changed->x();
362 if (x + changed->width() > right)
363 right = x + changed->width();
367 m_width = right - left;
369 qreal left = FLT_MAX;
371 QList<QQuickItem *> children = m_item->childItems();
372 for (int i = 0; i < children.count(); ++i) {
373 QQuickItem *child = children.at(i);
374 qreal x = child->x();
375 if (x + child->width() > right)
376 right = x + child->width();
380 if (!children.isEmpty())
382 m_width = qMax(right - left, qreal(0.0));
385 return (m_width != oldwidth || m_x != oldx);
388 void QQuickContents::complete()
390 QQuickItemPrivate::get(m_item)->addItemChangeListener(this, QQuickItemPrivate::Children);
392 QList<QQuickItem *> children = m_item->childItems();
393 for (int i = 0; i < children.count(); ++i) {
394 QQuickItem *child = children.at(i);
395 QQuickItemPrivate::get(child)->addItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed);
396 //###what about changes to visibility?
401 void QQuickContents::updateRect()
403 QQuickItemPrivate::get(m_item)->emitChildrenRectChanged(rectF());
406 void QQuickContents::itemGeometryChanged(QQuickItem *changed, const QRectF &newGeometry, const QRectF &oldGeometry)
409 bool wChanged = false;
410 bool hChanged = false;
411 //### we can only pass changed if the left edge has moved left, or the right edge has moved right
412 if (newGeometry.width() != oldGeometry.width() || newGeometry.x() != oldGeometry.x())
413 wChanged = calcWidth(/*changed*/);
414 if (newGeometry.height() != oldGeometry.height() || newGeometry.y() != oldGeometry.y())
415 hChanged = calcHeight(/*changed*/);
416 if (wChanged || hChanged)
420 void QQuickContents::itemDestroyed(QQuickItem *item)
423 QQuickItemPrivate::get(item)->removeItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed);
427 void QQuickContents::itemChildRemoved(QQuickItem *, QQuickItem *item)
430 QQuickItemPrivate::get(item)->removeItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed);
434 void QQuickContents::itemChildAdded(QQuickItem *, QQuickItem *item)
437 QQuickItemPrivate::get(item)->addItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed);
441 QQuickItemKeyFilter::QQuickItemKeyFilter(QQuickItem *item)
442 : m_processPost(false), m_next(0)
444 QQuickItemPrivate *p = item?QQuickItemPrivate::get(item):0;
446 m_next = p->extra.value().keyHandler;
447 p->extra->keyHandler = this;
451 QQuickItemKeyFilter::~QQuickItemKeyFilter()
455 void QQuickItemKeyFilter::keyPressed(QKeyEvent *event, bool post)
457 if (m_next) m_next->keyPressed(event, post);
460 void QQuickItemKeyFilter::keyReleased(QKeyEvent *event, bool post)
462 if (m_next) m_next->keyReleased(event, post);
465 void QQuickItemKeyFilter::inputMethodEvent(QInputMethodEvent *event, bool post)
468 m_next->inputMethodEvent(event, post);
473 QVariant QQuickItemKeyFilter::inputMethodQuery(Qt::InputMethodQuery query) const
475 if (m_next) return m_next->inputMethodQuery(query);
479 void QQuickItemKeyFilter::componentComplete()
481 if (m_next) m_next->componentComplete();
484 \qmlclass KeyNavigation QQuickKeyNavigationAttached
485 \inqmlmodule QtQuick 2
486 \ingroup qml-basic-interaction-elements
487 \brief The KeyNavigation attached property supports key navigation by arrow keys.
489 Key-based user interfaces commonly allow the use of arrow keys to navigate between
490 focusable items. The KeyNavigation attached property enables this behavior by providing a
491 convenient way to specify the item that should gain focus when an arrow or tab key is pressed.
493 The following example provides key navigation for a 2x2 grid of items:
495 \snippet doc/src/snippets/qml/keynavigation.qml 0
497 The top-left item initially receives focus by setting \l {Item::}{focus} to
498 \c true. When an arrow key is pressed, the focus will move to the
499 appropriate item, as defined by the value that has been set for
500 the KeyNavigation \l left, \l right, \l up or \l down properties.
502 Note that if a KeyNavigation attached property receives the key press and release
503 events for a requested arrow or tab key, the event is accepted and does not
504 propagate any further.
506 By default, KeyNavigation receives key events after the item to which it is attached.
507 If the item accepts the key event, the KeyNavigation attached property will not
508 receive an event for that key. Setting the \l priority property to
509 \c KeyNavigation.BeforeItem allows the event to be used for key navigation
510 before the item, rather than after.
512 If item to which the focus is switching is not enabled or visible, an attempt will
513 be made to skip this item and focus on the next. This is possible if there are
514 a chain of items with the same KeyNavigation handler. If multiple items in a row are not enabled
515 or visible, they will also be skipped.
517 KeyNavigation will implicitly set the other direction to return focus to this item. So if you set
518 \l left to another item, \l right will be set on that item's KeyNavigation to set focus back to this
519 item. However, if that item's KeyNavigation has had right explicitly set then no change will occur.
520 This means that the above example could have been written, with the same behaviour, without specifing
521 KeyNavigation.right or KeyNavigation.down for any of the items.
523 \sa {Keys}{Keys attached property}
527 \qmlproperty Item QtQuick2::KeyNavigation::left
528 \qmlproperty Item QtQuick2::KeyNavigation::right
529 \qmlproperty Item QtQuick2::KeyNavigation::up
530 \qmlproperty Item QtQuick2::KeyNavigation::down
531 \qmlproperty Item QtQuick2::KeyNavigation::tab
532 \qmlproperty Item QtQuick2::KeyNavigation::backtab
534 These properties hold the item to assign focus to
535 when the left, right, up or down cursor keys, or the
540 \qmlproperty Item QtQuick2::KeyNavigation::tab
541 \qmlproperty Item QtQuick2::KeyNavigation::backtab
543 These properties hold the item to assign focus to
544 when the Tab key or Shift+Tab key combination (Backtab) are pressed.
547 QQuickKeyNavigationAttached::QQuickKeyNavigationAttached(QObject *parent)
548 : QObject(*(new QQuickKeyNavigationAttachedPrivate), parent),
549 QQuickItemKeyFilter(qobject_cast<QQuickItem*>(parent))
551 m_processPost = true;
554 QQuickKeyNavigationAttached *
555 QQuickKeyNavigationAttached::qmlAttachedProperties(QObject *obj)
557 return new QQuickKeyNavigationAttached(obj);
560 QQuickItem *QQuickKeyNavigationAttached::left() const
562 Q_D(const QQuickKeyNavigationAttached);
566 void QQuickKeyNavigationAttached::setLeft(QQuickItem *i)
568 Q_D(QQuickKeyNavigationAttached);
573 QQuickKeyNavigationAttached* other =
574 qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
575 if (other && !other->d_func()->rightSet){
576 other->d_func()->right = qobject_cast<QQuickItem*>(parent());
577 emit other->rightChanged();
582 QQuickItem *QQuickKeyNavigationAttached::right() const
584 Q_D(const QQuickKeyNavigationAttached);
588 void QQuickKeyNavigationAttached::setRight(QQuickItem *i)
590 Q_D(QQuickKeyNavigationAttached);
595 QQuickKeyNavigationAttached* other =
596 qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
597 if (other && !other->d_func()->leftSet){
598 other->d_func()->left = qobject_cast<QQuickItem*>(parent());
599 emit other->leftChanged();
604 QQuickItem *QQuickKeyNavigationAttached::up() const
606 Q_D(const QQuickKeyNavigationAttached);
610 void QQuickKeyNavigationAttached::setUp(QQuickItem *i)
612 Q_D(QQuickKeyNavigationAttached);
617 QQuickKeyNavigationAttached* other =
618 qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
619 if (other && !other->d_func()->downSet){
620 other->d_func()->down = qobject_cast<QQuickItem*>(parent());
621 emit other->downChanged();
626 QQuickItem *QQuickKeyNavigationAttached::down() const
628 Q_D(const QQuickKeyNavigationAttached);
632 void QQuickKeyNavigationAttached::setDown(QQuickItem *i)
634 Q_D(QQuickKeyNavigationAttached);
639 QQuickKeyNavigationAttached* other =
640 qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
641 if (other && !other->d_func()->upSet) {
642 other->d_func()->up = qobject_cast<QQuickItem*>(parent());
643 emit other->upChanged();
648 QQuickItem *QQuickKeyNavigationAttached::tab() const
650 Q_D(const QQuickKeyNavigationAttached);
654 void QQuickKeyNavigationAttached::setTab(QQuickItem *i)
656 Q_D(QQuickKeyNavigationAttached);
661 QQuickKeyNavigationAttached* other =
662 qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
663 if (other && !other->d_func()->backtabSet) {
664 other->d_func()->backtab = qobject_cast<QQuickItem*>(parent());
665 emit other->backtabChanged();
670 QQuickItem *QQuickKeyNavigationAttached::backtab() const
672 Q_D(const QQuickKeyNavigationAttached);
676 void QQuickKeyNavigationAttached::setBacktab(QQuickItem *i)
678 Q_D(QQuickKeyNavigationAttached);
682 d->backtabSet = true;
683 QQuickKeyNavigationAttached* other =
684 qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
685 if (other && !other->d_func()->tabSet) {
686 other->d_func()->tab = qobject_cast<QQuickItem*>(parent());
687 emit other->tabChanged();
689 emit backtabChanged();
693 \qmlproperty enumeration QtQuick2::KeyNavigation::priority
695 This property determines whether the keys are processed before
696 or after the attached item's own key handling.
699 \li KeyNavigation.BeforeItem - process the key events before normal
700 item key processing. If the event is used for key navigation, it will be accepted and will not
701 be passed on to the item.
702 \li KeyNavigation.AfterItem (default) - process the key events after normal item key
703 handling. If the item accepts the key event it will not be
704 handled by the KeyNavigation attached property handler.
707 QQuickKeyNavigationAttached::Priority QQuickKeyNavigationAttached::priority() const
709 return m_processPost ? AfterItem : BeforeItem;
712 void QQuickKeyNavigationAttached::setPriority(Priority order)
714 bool processPost = order == AfterItem;
715 if (processPost != m_processPost) {
716 m_processPost = processPost;
717 emit priorityChanged();
721 void QQuickKeyNavigationAttached::keyPressed(QKeyEvent *event, bool post)
723 Q_D(QQuickKeyNavigationAttached);
726 if (post != m_processPost) {
727 QQuickItemKeyFilter::keyPressed(event, post);
732 switch (event->key()) {
734 if (QQuickItem *parentItem = qobject_cast<QQuickItem*>(parent()))
735 mirror = QQuickItemPrivate::get(parentItem)->effectiveLayoutMirror;
736 QQuickItem* leftItem = mirror ? d->right : d->left;
738 setFocusNavigation(leftItem, mirror ? "right" : "left");
743 case Qt::Key_Right: {
744 if (QQuickItem *parentItem = qobject_cast<QQuickItem*>(parent()))
745 mirror = QQuickItemPrivate::get(parentItem)->effectiveLayoutMirror;
746 QQuickItem* rightItem = mirror ? d->left : d->right;
748 setFocusNavigation(rightItem, mirror ? "left" : "right");
755 setFocusNavigation(d->up, "up");
761 setFocusNavigation(d->down, "down");
767 setFocusNavigation(d->tab, "tab");
771 case Qt::Key_Backtab:
773 setFocusNavigation(d->backtab, "backtab");
781 if (!event->isAccepted()) QQuickItemKeyFilter::keyPressed(event, post);
784 void QQuickKeyNavigationAttached::keyReleased(QKeyEvent *event, bool post)
786 Q_D(QQuickKeyNavigationAttached);
789 if (post != m_processPost) {
790 QQuickItemKeyFilter::keyReleased(event, post);
795 switch (event->key()) {
797 if (QQuickItem *parentItem = qobject_cast<QQuickItem*>(parent()))
798 mirror = QQuickItemPrivate::get(parentItem)->effectiveLayoutMirror;
799 if (mirror ? d->right : d->left)
803 if (QQuickItem *parentItem = qobject_cast<QQuickItem*>(parent()))
804 mirror = QQuickItemPrivate::get(parentItem)->effectiveLayoutMirror;
805 if (mirror ? d->left : d->right)
823 case Qt::Key_Backtab:
832 if (!event->isAccepted()) QQuickItemKeyFilter::keyReleased(event, post);
835 void QQuickKeyNavigationAttached::setFocusNavigation(QQuickItem *currentItem, const char *dir)
837 QQuickItem *initialItem = currentItem;
838 bool isNextItem = false;
841 if (currentItem->isVisible() && currentItem->isEnabled()) {
842 currentItem->setFocus(true);
845 qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(currentItem, false);
847 QQuickItem *tempItem = qvariant_cast<QQuickItem*>(attached->property(dir));
849 currentItem = tempItem;
855 while (currentItem != initialItem && isNextItem);
858 const QQuickKeysAttached::SigMap QQuickKeysAttached::sigMap[] = {
859 { Qt::Key_Left, "leftPressed" },
860 { Qt::Key_Right, "rightPressed" },
861 { Qt::Key_Up, "upPressed" },
862 { Qt::Key_Down, "downPressed" },
863 { Qt::Key_Tab, "tabPressed" },
864 { Qt::Key_Backtab, "backtabPressed" },
865 { Qt::Key_Asterisk, "asteriskPressed" },
866 { Qt::Key_NumberSign, "numberSignPressed" },
867 { Qt::Key_Escape, "escapePressed" },
868 { Qt::Key_Return, "returnPressed" },
869 { Qt::Key_Enter, "enterPressed" },
870 { Qt::Key_Delete, "deletePressed" },
871 { Qt::Key_Space, "spacePressed" },
872 { Qt::Key_Back, "backPressed" },
873 { Qt::Key_Cancel, "cancelPressed" },
874 { Qt::Key_Select, "selectPressed" },
875 { Qt::Key_Yes, "yesPressed" },
876 { Qt::Key_No, "noPressed" },
877 { Qt::Key_Context1, "context1Pressed" },
878 { Qt::Key_Context2, "context2Pressed" },
879 { Qt::Key_Context3, "context3Pressed" },
880 { Qt::Key_Context4, "context4Pressed" },
881 { Qt::Key_Call, "callPressed" },
882 { Qt::Key_Hangup, "hangupPressed" },
883 { Qt::Key_Flip, "flipPressed" },
884 { Qt::Key_Menu, "menuPressed" },
885 { Qt::Key_VolumeUp, "volumeUpPressed" },
886 { Qt::Key_VolumeDown, "volumeDownPressed" },
890 bool QQuickKeysAttachedPrivate::isConnected(const char *signalName)
892 return isSignalConnected(signalIndex(signalName));
896 \qmlclass Keys QQuickKeysAttached
897 \inqmlmodule QtQuick 2
898 \ingroup qml-basic-interaction-elements
899 \brief The Keys attached property provides key handling to Items.
901 All visual primitives support key handling via the Keys
902 attached property. Keys can be handled via the onPressed
903 and onReleased signal properties.
905 The signal properties have a \l KeyEvent parameter, named
906 \e event which contains details of the event. If a key is
907 handled \e event.accepted should be set to true to prevent the
908 event from propagating up the item hierarchy.
910 \section1 Example Usage
912 The following example shows how the general onPressed handler can
913 be used to test for a certain key; in this case, the left cursor
916 \snippet doc/src/snippets/qml/keys/keys-pressed.qml key item
918 Some keys may alternatively be handled via specific signal properties,
919 for example \e onSelectPressed. These handlers automatically set
920 \e event.accepted to true.
922 \snippet doc/src/snippets/qml/keys/keys-handler.qml key item
924 See \l{Qt::Key}{Qt.Key} for the list of keyboard codes.
926 \section1 Key Handling Priorities
928 The Keys attached property can be configured to handle key events
929 before or after the item it is attached to. This makes it possible
930 to intercept events in order to override an item's default behavior,
931 or act as a fallback for keys not handled by the item.
933 If \l priority is Keys.BeforeItem (default) the order of key event processing is:
936 \li Items specified in \c forwardTo
937 \li specific key handlers, e.g. onReturnPressed
938 \li onKeyPress, onKeyRelease handlers
939 \li Item specific key handling, e.g. TextInput key handling
943 If priority is Keys.AfterItem the order of key event processing is:
946 \li Item specific key handling, e.g. TextInput key handling
947 \li Items specified in \c forwardTo
948 \li specific key handlers, e.g. onReturnPressed
949 \li onKeyPress, onKeyRelease handlers
953 If the event is accepted during any of the above steps, key
956 \sa KeyEvent, {KeyNavigation}{KeyNavigation attached property}
960 \qmlproperty bool QtQuick2::Keys::enabled
962 This flags enables key handling if true (default); otherwise
963 no key handlers will be called.
967 \qmlproperty enumeration QtQuick2::Keys::priority
969 This property determines whether the keys are processed before
970 or after the attached item's own key handling.
973 \li Keys.BeforeItem (default) - process the key events before normal
974 item key processing. If the event is accepted it will not
975 be passed on to the item.
976 \li Keys.AfterItem - process the key events after normal item key
977 handling. If the item accepts the key event it will not be
978 handled by the Keys attached property handler.
983 \qmlproperty list<Object> QtQuick2::Keys::forwardTo
985 This property provides a way to forward key presses, key releases, and keyboard input
986 coming from input methods to other items. This can be useful when you want
987 one item to handle some keys (e.g. the up and down arrow keys), and another item to
988 handle other keys (e.g. the left and right arrow keys). Once an item that has been
989 forwarded keys accepts the event it is no longer forwarded to items later in the
992 This example forwards key events to two lists:
1003 Keys.forwardTo: [list1, list2]
1010 \qmlsignal QtQuick2::Keys::onPressed(KeyEvent event)
1012 This handler is called when a key has been pressed. The \a event
1013 parameter provides information about the event.
1017 \qmlsignal QtQuick2::Keys::onReleased(KeyEvent event)
1019 This handler is called when a key has been released. The \a event
1020 parameter provides information about the event.
1024 \qmlsignal QtQuick2::Keys::onDigit0Pressed(KeyEvent event)
1026 This handler is called when the digit '0' has been pressed. The \a event
1027 parameter provides information about the event.
1031 \qmlsignal QtQuick2::Keys::onDigit1Pressed(KeyEvent event)
1033 This handler is called when the digit '1' has been pressed. The \a event
1034 parameter provides information about the event.
1038 \qmlsignal QtQuick2::Keys::onDigit2Pressed(KeyEvent event)
1040 This handler is called when the digit '2' has been pressed. The \a event
1041 parameter provides information about the event.
1045 \qmlsignal QtQuick2::Keys::onDigit3Pressed(KeyEvent event)
1047 This handler is called when the digit '3' has been pressed. The \a event
1048 parameter provides information about the event.
1052 \qmlsignal QtQuick2::Keys::onDigit4Pressed(KeyEvent event)
1054 This handler is called when the digit '4' has been pressed. The \a event
1055 parameter provides information about the event.
1059 \qmlsignal QtQuick2::Keys::onDigit5Pressed(KeyEvent event)
1061 This handler is called when the digit '5' has been pressed. The \a event
1062 parameter provides information about the event.
1066 \qmlsignal QtQuick2::Keys::onDigit6Pressed(KeyEvent event)
1068 This handler is called when the digit '6' has been pressed. The \a event
1069 parameter provides information about the event.
1073 \qmlsignal QtQuick2::Keys::onDigit7Pressed(KeyEvent event)
1075 This handler is called when the digit '7' has been pressed. The \a event
1076 parameter provides information about the event.
1080 \qmlsignal QtQuick2::Keys::onDigit8Pressed(KeyEvent event)
1082 This handler is called when the digit '8' has been pressed. The \a event
1083 parameter provides information about the event.
1087 \qmlsignal QtQuick2::Keys::onDigit9Pressed(KeyEvent event)
1089 This handler is called when the digit '9' has been pressed. The \a event
1090 parameter provides information about the event.
1094 \qmlsignal QtQuick2::Keys::onLeftPressed(KeyEvent event)
1096 This handler is called when the Left arrow has been pressed. The \a event
1097 parameter provides information about the event.
1101 \qmlsignal QtQuick2::Keys::onRightPressed(KeyEvent event)
1103 This handler is called when the Right arrow has been pressed. The \a event
1104 parameter provides information about the event.
1108 \qmlsignal QtQuick2::Keys::onUpPressed(KeyEvent event)
1110 This handler is called when the Up arrow has been pressed. The \a event
1111 parameter provides information about the event.
1115 \qmlsignal QtQuick2::Keys::onDownPressed(KeyEvent event)
1117 This handler is called when the Down arrow has been pressed. The \a event
1118 parameter provides information about the event.
1122 \qmlsignal QtQuick2::Keys::onTabPressed(KeyEvent event)
1124 This handler is called when the Tab key has been pressed. The \a event
1125 parameter provides information about the event.
1129 \qmlsignal QtQuick2::Keys::onBacktabPressed(KeyEvent event)
1131 This handler is called when the Shift+Tab key combination (Backtab) has
1132 been pressed. The \a event parameter provides information about the event.
1136 \qmlsignal QtQuick2::Keys::onAsteriskPressed(KeyEvent event)
1138 This handler is called when the Asterisk '*' has been pressed. The \a event
1139 parameter provides information about the event.
1143 \qmlsignal QtQuick2::Keys::onEscapePressed(KeyEvent event)
1145 This handler is called when the Escape key has been pressed. The \a event
1146 parameter provides information about the event.
1150 \qmlsignal QtQuick2::Keys::onReturnPressed(KeyEvent event)
1152 This handler is called when the Return key has been pressed. The \a event
1153 parameter provides information about the event.
1157 \qmlsignal QtQuick2::Keys::onEnterPressed(KeyEvent event)
1159 This handler is called when the Enter key has been pressed. The \a event
1160 parameter provides information about the event.
1164 \qmlsignal QtQuick2::Keys::onDeletePressed(KeyEvent event)
1166 This handler is called when the Delete key has been pressed. The \a event
1167 parameter provides information about the event.
1171 \qmlsignal QtQuick2::Keys::onSpacePressed(KeyEvent event)
1173 This handler is called when the Space key has been pressed. The \a event
1174 parameter provides information about the event.
1178 \qmlsignal QtQuick2::Keys::onBackPressed(KeyEvent event)
1180 This handler is called when the Back key has been pressed. The \a event
1181 parameter provides information about the event.
1185 \qmlsignal QtQuick2::Keys::onCancelPressed(KeyEvent event)
1187 This handler is called when the Cancel key has been pressed. The \a event
1188 parameter provides information about the event.
1192 \qmlsignal QtQuick2::Keys::onSelectPressed(KeyEvent event)
1194 This handler is called when the Select key has been pressed. The \a event
1195 parameter provides information about the event.
1199 \qmlsignal QtQuick2::Keys::onYesPressed(KeyEvent event)
1201 This handler is called when the Yes key has been pressed. The \a event
1202 parameter provides information about the event.
1206 \qmlsignal QtQuick2::Keys::onNoPressed(KeyEvent event)
1208 This handler is called when the No key has been pressed. The \a event
1209 parameter provides information about the event.
1213 \qmlsignal QtQuick2::Keys::onContext1Pressed(KeyEvent event)
1215 This handler is called when the Context1 key has been pressed. The \a event
1216 parameter provides information about the event.
1220 \qmlsignal QtQuick2::Keys::onContext2Pressed(KeyEvent event)
1222 This handler is called when the Context2 key has been pressed. The \a event
1223 parameter provides information about the event.
1227 \qmlsignal QtQuick2::Keys::onContext3Pressed(KeyEvent event)
1229 This handler is called when the Context3 key has been pressed. The \a event
1230 parameter provides information about the event.
1234 \qmlsignal QtQuick2::Keys::onContext4Pressed(KeyEvent event)
1236 This handler is called when the Context4 key has been pressed. The \a event
1237 parameter provides information about the event.
1241 \qmlsignal QtQuick2::Keys::onCallPressed(KeyEvent event)
1243 This handler is called when the Call key has been pressed. The \a event
1244 parameter provides information about the event.
1248 \qmlsignal QtQuick2::Keys::onHangupPressed(KeyEvent event)
1250 This handler is called when the Hangup key has been pressed. The \a event
1251 parameter provides information about the event.
1255 \qmlsignal QtQuick2::Keys::onFlipPressed(KeyEvent event)
1257 This handler is called when the Flip key has been pressed. The \a event
1258 parameter provides information about the event.
1262 \qmlsignal QtQuick2::Keys::onMenuPressed(KeyEvent event)
1264 This handler is called when the Menu key has been pressed. The \a event
1265 parameter provides information about the event.
1269 \qmlsignal QtQuick2::Keys::onVolumeUpPressed(KeyEvent event)
1271 This handler is called when the VolumeUp key has been pressed. The \a event
1272 parameter provides information about the event.
1276 \qmlsignal QtQuick2::Keys::onVolumeDownPressed(KeyEvent event)
1278 This handler is called when the VolumeDown key has been pressed. The \a event
1279 parameter provides information about the event.
1282 QQuickKeysAttached::QQuickKeysAttached(QObject *parent)
1283 : QObject(*(new QQuickKeysAttachedPrivate), parent),
1284 QQuickItemKeyFilter(qobject_cast<QQuickItem*>(parent))
1286 Q_D(QQuickKeysAttached);
1287 m_processPost = false;
1288 d->item = qobject_cast<QQuickItem*>(parent);
1291 QQuickKeysAttached::~QQuickKeysAttached()
1295 QQuickKeysAttached::Priority QQuickKeysAttached::priority() const
1297 return m_processPost ? AfterItem : BeforeItem;
1300 void QQuickKeysAttached::setPriority(Priority order)
1302 bool processPost = order == AfterItem;
1303 if (processPost != m_processPost) {
1304 m_processPost = processPost;
1305 emit priorityChanged();
1309 void QQuickKeysAttached::componentComplete()
1311 Q_D(QQuickKeysAttached);
1313 for (int ii = 0; ii < d->targets.count(); ++ii) {
1314 QQuickItem *targetItem = d->targets.at(ii);
1315 if (targetItem && (targetItem->flags() & QQuickItem::ItemAcceptsInputMethod)) {
1316 d->item->setFlag(QQuickItem::ItemAcceptsInputMethod);
1323 void QQuickKeysAttached::keyPressed(QKeyEvent *event, bool post)
1325 Q_D(QQuickKeysAttached);
1326 if (post != m_processPost || !d->enabled || d->inPress) {
1328 QQuickItemKeyFilter::keyPressed(event, post);
1332 // first process forwards
1333 if (d->item && d->item->canvas()) {
1335 for (int ii = 0; ii < d->targets.count(); ++ii) {
1336 QQuickItem *i = d->targets.at(ii);
1337 if (i && i->isVisible()) {
1338 d->item->canvas()->sendEvent(i, event);
1339 if (event->isAccepted()) {
1348 QQuickKeyEvent ke(*event);
1349 QByteArray keySignal = keyToSignal(event->key());
1350 if (!keySignal.isEmpty()) {
1351 keySignal += "(QQuickKeyEvent*)";
1352 if (d->isConnected(keySignal)) {
1353 // If we specifically handle a key then default to accepted
1354 ke.setAccepted(true);
1355 int idx = QQuickKeysAttached::staticMetaObject.indexOfSignal(keySignal);
1356 metaObject()->method(idx).invoke(this, Qt::DirectConnection, Q_ARG(QQuickKeyEvent*, &ke));
1359 if (!ke.isAccepted())
1361 event->setAccepted(ke.isAccepted());
1363 if (!event->isAccepted()) QQuickItemKeyFilter::keyPressed(event, post);
1366 void QQuickKeysAttached::keyReleased(QKeyEvent *event, bool post)
1368 Q_D(QQuickKeysAttached);
1369 if (post != m_processPost || !d->enabled || d->inRelease) {
1371 QQuickItemKeyFilter::keyReleased(event, post);
1375 if (d->item && d->item->canvas()) {
1376 d->inRelease = true;
1377 for (int ii = 0; ii < d->targets.count(); ++ii) {
1378 QQuickItem *i = d->targets.at(ii);
1379 if (i && i->isVisible()) {
1380 d->item->canvas()->sendEvent(i, event);
1381 if (event->isAccepted()) {
1382 d->inRelease = false;
1387 d->inRelease = false;
1390 QQuickKeyEvent ke(*event);
1392 event->setAccepted(ke.isAccepted());
1394 if (!event->isAccepted()) QQuickItemKeyFilter::keyReleased(event, post);
1397 void QQuickKeysAttached::inputMethodEvent(QInputMethodEvent *event, bool post)
1399 Q_D(QQuickKeysAttached);
1400 if (post == m_processPost && d->item && !d->inIM && d->item->canvas()) {
1402 for (int ii = 0; ii < d->targets.count(); ++ii) {
1403 QQuickItem *i = d->targets.at(ii);
1404 if (i && i->isVisible() && (i->flags() & QQuickItem::ItemAcceptsInputMethod)) {
1405 d->item->canvas()->sendEvent(i, event);
1406 if (event->isAccepted()) {
1415 QQuickItemKeyFilter::inputMethodEvent(event, post);
1418 QVariant QQuickKeysAttached::inputMethodQuery(Qt::InputMethodQuery query) const
1420 Q_D(const QQuickKeysAttached);
1422 for (int ii = 0; ii < d->targets.count(); ++ii) {
1423 QQuickItem *i = d->targets.at(ii);
1424 if (i && i->isVisible() && (i->flags() & QQuickItem::ItemAcceptsInputMethod) && i == d->imeItem) {
1425 //### how robust is i == d->imeItem check?
1426 QVariant v = i->inputMethodQuery(query);
1427 if (v.userType() == QVariant::RectF)
1428 v = d->item->mapRectFromItem(i, v.toRectF()); //### cost?
1433 return QQuickItemKeyFilter::inputMethodQuery(query);
1436 QQuickKeysAttached *QQuickKeysAttached::qmlAttachedProperties(QObject *obj)
1438 return new QQuickKeysAttached(obj);
1442 \qmlclass LayoutMirroring QQuickLayoutMirroringAttached
1443 \inqmlmodule QtQuick 2
1444 \ingroup qml-utility-elements
1445 \brief The LayoutMirroring attached property is used to mirror layout behavior.
1447 The LayoutMirroring attached property is used to horizontally mirror \l {anchor-layout}{Item anchors},
1448 \l{Using QML Positioner and Repeater Items}{positioner} elements (such as \l Row and \l Grid)
1449 and views (such as \l GridView and horizontal \l ListView). Mirroring is a visual change: left
1450 anchors become right anchors, and positioner elements like \l Grid and \l Row reverse the
1451 horizontal layout of child items.
1453 Mirroring is enabled for an item by setting the \l enabled property to true. By default, this
1454 only affects the item itself; setting the \l childrenInherit property to true propagates the mirroring
1455 behavior to all child elements as well. If the \c LayoutMirroring attached property has not been defined
1456 for an item, mirroring is not enabled.
1458 The following example shows mirroring in action. The \l Row below is specified as being anchored
1459 to the left of its parent. However, since mirroring has been enabled, the anchor is horizontally
1460 reversed and it is now anchored to the right. Also, since items in a \l Row are positioned
1461 from left to right by default, they are now positioned from right to left instead, as demonstrated
1462 by the numbering and opacity of the items:
1464 \snippet doc/src/snippets/qml/layoutmirroring.qml 0
1466 \image layoutmirroring.png
1468 Layout mirroring is useful when it is necessary to support both left-to-right and right-to-left
1469 layout versions of an application to target different language areas. The \l childrenInherit
1470 property allows layout mirroring to be applied without manually setting layout configurations
1471 for every item in an application. Keep in mind, however, that mirroring does not affect any
1472 positioning that is defined by the \l Item \l {Item::}{x} coordinate value, so even with
1473 mirroring enabled, it will often be necessary to apply some layout fixes to support the
1474 desired layout direction. Also, it may be necessary to disable the mirroring of individual
1475 child items (by setting \l {enabled}{LayoutMirroring.enabled} to false for such items) if
1476 mirroring is not the desired behavior, or if the child item already implements mirroring in
1479 See \l {QML Right-to-left User Interfaces} for further details on using \c LayoutMirroring and
1480 other related features to implement right-to-left support for an application.
1484 \qmlproperty bool QtQuick2::LayoutMirroring::enabled
1486 This property holds whether the item's layout is mirrored horizontally. Setting this to true
1487 horizontally reverses \l {anchor-layout}{anchor} settings such that left anchors become right,
1488 and right anchors become left. For \l{Using QML Positioner and Repeater Items}{positioner} elements
1489 (such as \l Row and \l Grid) and view elements (such as \l {GridView}{GridView} and \l {ListView}{ListView})
1490 this also mirrors the horizontal layout direction of the item.
1492 The default value is false.
1496 \qmlproperty bool QtQuick2::LayoutMirroring::childrenInherit
1498 This property holds whether the \l {enabled}{LayoutMirroring.enabled} value for this item
1499 is inherited by its children.
1501 The default value is false.
1505 QQuickLayoutMirroringAttached::QQuickLayoutMirroringAttached(QObject *parent) : QObject(parent), itemPrivate(0)
1507 if (QQuickItem *item = qobject_cast<QQuickItem*>(parent)) {
1508 itemPrivate = QQuickItemPrivate::get(item);
1509 itemPrivate->extra.value().layoutDirectionAttached = this;
1511 qmlInfo(parent) << tr("LayoutDirection attached property only works with Items");
1514 QQuickLayoutMirroringAttached * QQuickLayoutMirroringAttached::qmlAttachedProperties(QObject *object)
1516 return new QQuickLayoutMirroringAttached(object);
1519 bool QQuickLayoutMirroringAttached::enabled() const
1521 return itemPrivate ? itemPrivate->effectiveLayoutMirror : false;
1524 void QQuickLayoutMirroringAttached::setEnabled(bool enabled)
1529 itemPrivate->isMirrorImplicit = false;
1530 if (enabled != itemPrivate->effectiveLayoutMirror) {
1531 itemPrivate->setLayoutMirror(enabled);
1532 if (itemPrivate->inheritMirrorFromItem)
1533 itemPrivate->resolveLayoutMirror();
1537 void QQuickLayoutMirroringAttached::resetEnabled()
1539 if (itemPrivate && !itemPrivate->isMirrorImplicit) {
1540 itemPrivate->isMirrorImplicit = true;
1541 itemPrivate->resolveLayoutMirror();
1545 bool QQuickLayoutMirroringAttached::childrenInherit() const
1547 return itemPrivate ? itemPrivate->inheritMirrorFromItem : false;
1550 void QQuickLayoutMirroringAttached::setChildrenInherit(bool childrenInherit) {
1551 if (itemPrivate && childrenInherit != itemPrivate->inheritMirrorFromItem) {
1552 itemPrivate->inheritMirrorFromItem = childrenInherit;
1553 itemPrivate->resolveLayoutMirror();
1554 childrenInheritChanged();
1558 void QQuickItemPrivate::resolveLayoutMirror()
1561 if (QQuickItem *parentItem = q->parentItem()) {
1562 QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(parentItem);
1563 setImplicitLayoutMirror(parentPrivate->inheritedLayoutMirror, parentPrivate->inheritMirrorFromParent);
1565 setImplicitLayoutMirror(isMirrorImplicit ? false : effectiveLayoutMirror, inheritMirrorFromItem);
1569 void QQuickItemPrivate::setImplicitLayoutMirror(bool mirror, bool inherit)
1571 inherit = inherit || inheritMirrorFromItem;
1572 if (!isMirrorImplicit && inheritMirrorFromItem)
1573 mirror = effectiveLayoutMirror;
1574 if (mirror == inheritedLayoutMirror && inherit == inheritMirrorFromParent)
1577 inheritMirrorFromParent = inherit;
1578 inheritedLayoutMirror = inheritMirrorFromParent ? mirror : false;
1580 if (isMirrorImplicit)
1581 setLayoutMirror(inherit ? inheritedLayoutMirror : false);
1582 for (int i = 0; i < childItems.count(); ++i) {
1583 if (QQuickItem *child = qobject_cast<QQuickItem *>(childItems.at(i))) {
1584 QQuickItemPrivate *childPrivate = QQuickItemPrivate::get(child);
1585 childPrivate->setImplicitLayoutMirror(inheritedLayoutMirror, inheritMirrorFromParent);
1590 void QQuickItemPrivate::setLayoutMirror(bool mirror)
1592 if (mirror != effectiveLayoutMirror) {
1593 effectiveLayoutMirror = mirror;
1595 QQuickAnchorsPrivate *anchor_d = QQuickAnchorsPrivate::get(_anchors);
1596 anchor_d->fillChanged();
1597 anchor_d->centerInChanged();
1598 anchor_d->updateHorizontalAnchors();
1599 emit _anchors->mirroredChanged();
1602 if (extra.isAllocated() && extra->layoutDirectionAttached) {
1603 emit extra->layoutDirectionAttached->enabledChanged();
1608 void QQuickItemPrivate::setAccessibleFlagAndListener()
1611 QQuickItem *item = q;
1613 if (item->d_func()->isAccessible)
1614 break; // already set - grandparents should have the flag set as well.
1616 if (item->canvas() && item->canvas()->rootItem() == item)
1617 break; // don't add a listener to the canvas root item
1619 item->d_func()->isAccessible = true;
1620 item = item->d_func()->parentItem;
1624 void QQuickItemPrivate::updateSubFocusItem(QQuickItem *scope, bool focus)
1629 QQuickItemPrivate *scopePrivate = QQuickItemPrivate::get(scope);
1631 QQuickItem *oldSubFocusItem = scopePrivate->subFocusItem;
1632 // Correct focus chain in scope
1633 if (oldSubFocusItem) {
1634 QQuickItem *sfi = scopePrivate->subFocusItem->parentItem();
1635 while (sfi != scope) {
1636 QQuickItemPrivate::get(sfi)->subFocusItem = 0;
1637 sfi = sfi->parentItem();
1642 scopePrivate->subFocusItem = q;
1643 QQuickItem *sfi = scopePrivate->subFocusItem->parentItem();
1644 while (sfi != scope) {
1645 QQuickItemPrivate::get(sfi)->subFocusItem = q;
1646 sfi = sfi->parentItem();
1649 scopePrivate->subFocusItem = 0;
1656 \brief The QQuickItem class provides the most basic of all visual items in QML.
1660 All visual items in Qt Quick inherit from QQuickItem. Although QQuickItem
1661 has no visual appearance, it defines all the properties that are
1662 common across visual items - such as the x and y position, the
1663 width and height, \l {anchor-layout}{anchoring} and key handling.
1665 You can subclass QQuickItem to provide your own custom visual item that inherits
1666 these features. Note that, because it does not draw anything, QQuickItem sets the
1667 QGraphicsItem::ItemHasNoContents flag. If you subclass QQuickItem to create a visual
1668 item, you will need to unset this flag.
1673 \qmlclass Item QQuickItem
1675 \inqmlmodule QtQuick 2
1676 \ingroup qml-basic-visual-elements
1677 \brief The Item is the most basic of all visual items in QML.
1679 All visual items in Qt Quick inherit from Item. Although Item
1680 has no visual appearance, it defines all the properties that are
1681 common across visual items - such as the x and y position, the
1682 width and height, \l {anchor-layout}{anchoring} and key handling.
1684 Item is also useful for grouping items together.
1701 fillMode: Image.Tile
1708 \section1 Key Handling
1710 Key handling is available to all Item-based visual elements via the \l {Keys}{Keys}
1711 attached property. The \e Keys attached property provides basic handlers such
1712 as \l {Keys::onPressed}{onPressed} and \l {Keys::onReleased}{onReleased},
1713 as well as handlers for specific keys, such as
1714 \l {Keys::onCancelPressed}{onCancelPressed}. The example below
1715 assigns \l {qmlfocus}{focus} to the item and handles
1716 the Left key via the general \e onPressed handler and the Select key via the
1717 onSelectPressed handler:
1723 if (event.key == Qt.Key_Left) {
1724 console.log("move left");
1725 event.accepted = true;
1728 Keys.onSelectPressed: console.log("Selected");
1732 See the \l {Keys}{Keys} attached property for detailed documentation.
1734 \section1 Layout Mirroring
1736 Item layouts can be mirrored using the \l {LayoutMirroring}{LayoutMirroring} attached property.
1741 \fn void QQuickItem::childrenRectChanged(const QRectF &)
1746 \fn void QQuickItem::baselineOffsetChanged(qreal)
1751 \fn void QQuickItem::stateChanged(const QString &state)
1756 \fn void QQuickItem::parentChanged(QQuickItem *)
1761 \fn void QQuickItem::smoothChanged(bool)
1766 \fn void QQuickItem::clipChanged(bool)
1770 /*! \fn void QQuickItem::transformOriginChanged(TransformOrigin)
1775 \fn void QQuickItem::focusChanged(bool)
1780 \fn void QQuickItem::activeFocusChanged(bool)
1784 \fn QQuickItem::QQuickItem(QQuickItem *parent)
1786 Constructs a QQuickItem with the given \a parent.
1788 QQuickItem::QQuickItem(QQuickItem* parent)
1789 : QObject(*(new QQuickItemPrivate), parent)
1797 QQuickItem::QQuickItem(QQuickItemPrivate &dd, QQuickItem *parent)
1798 : QObject(dd, parent)
1805 static int qt_item_count = 0;
1807 static void qt_print_item_count()
1809 qDebug("Number of leaked items: %i", qt_item_count);
1815 Destroys the QQuickItem.
1817 QQuickItem::~QQuickItem()
1821 if (qt_item_count < 0)
1822 qDebug("Item destroyed after qt_print_item_count() was called.");
1829 else if (d->canvas && d->itemNodeInstance)
1830 QQuickCanvasPrivate::get(d->canvas)->cleanup(d->itemNodeInstance); // cleanup root
1831 // XXX todo - optimize
1832 while (!d->childItems.isEmpty())
1833 d->childItems.first()->setParentItem(0);
1835 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
1836 QQuickAnchorsPrivate *anchor = d->changeListeners.at(ii).listener->anchorPrivate();
1838 anchor->clearItem(this);
1842 update item anchors that depended on us unless they are our child (and will also be destroyed),
1843 or our sibling, and our parent is also being destroyed.
1845 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
1846 QQuickAnchorsPrivate *anchor = d->changeListeners.at(ii).listener->anchorPrivate();
1847 if (anchor && anchor->item && anchor->item->parentItem() && anchor->item->parentItem() != this)
1851 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
1852 const QQuickItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
1853 if (change.types & QQuickItemPrivate::Destroyed)
1854 change.listener->itemDestroyed(this);
1857 d->changeListeners.clear();
1859 if (d->extra.isAllocated()) {
1860 delete d->extra->contents; d->extra->contents = 0;
1861 delete d->extra->layer; d->extra->layer = 0;
1864 delete d->_anchors; d->_anchors = 0;
1865 delete d->_stateGroup; d->_stateGroup = 0;
1869 \qmlproperty enumeration QtQuick2::Item::transformOrigin
1870 This property holds the origin point around which scale and rotation transform.
1872 Nine transform origins are available, as shown in the image below.
1874 \image declarative-transformorigin.png
1876 This example rotates an image around its bottom-right corner.
1879 source: "myimage.png"
1880 transformOrigin: Item.BottomRight
1885 The default transform origin is \c Item.Center.
1887 To set an arbitrary transform origin point use the \l Scale or \l Rotation
1892 \qmlproperty Item QtQuick2::Item::parent
1893 This property holds the parent of the item.
1897 \property QQuickItem::parent
1898 This property holds the parent of the item.
1900 void QQuickItem::setParentItem(QQuickItem *parentItem)
1903 if (parentItem == d->parentItem)
1907 QQuickItem *itemAncestor = parentItem->parentItem();
1908 while (itemAncestor != 0) {
1909 if (itemAncestor == this) {
1910 qWarning("QQuickItem::setParentItem: Parent is already part of this items subtree.");
1913 itemAncestor = itemAncestor->parentItem();
1917 d->removeFromDirtyList();
1919 QQuickItem *oldParentItem = d->parentItem;
1920 QQuickItem *scopeFocusedItem = 0;
1922 if (oldParentItem) {
1923 QQuickItemPrivate *op = QQuickItemPrivate::get(oldParentItem);
1925 QQuickItem *scopeItem = 0;
1927 if (d->canvas && hasFocus()) {
1928 scopeFocusedItem = this;
1929 } else if (d->canvas && !isFocusScope() && d->subFocusItem) {
1930 scopeFocusedItem = d->subFocusItem;
1933 if (scopeFocusedItem) {
1934 scopeItem = oldParentItem;
1935 while (!scopeItem->isFocusScope()) scopeItem = scopeItem->parentItem();
1936 QQuickCanvasPrivate::get(d->canvas)->clearFocusInScope(scopeItem, scopeFocusedItem,
1937 QQuickCanvasPrivate::DontChangeFocusProperty);
1940 const bool wasVisible = isVisible();
1941 op->removeChild(this);
1943 emit oldParentItem->visibleChildrenChanged();
1945 } else if (d->canvas) {
1946 QQuickCanvasPrivate::get(d->canvas)->parentlessItems.remove(this);
1949 d->parentItem = parentItem;
1951 QQuickCanvas *parentCanvas = parentItem?QQuickItemPrivate::get(parentItem)->canvas:0;
1952 if (d->canvas != parentCanvas) {
1953 QQuickItemPrivate::InitializationState initState;
1955 d->initCanvas(&initState, parentCanvas);
1958 d->dirty(QQuickItemPrivate::ParentChanged);
1961 QQuickItemPrivate::get(d->parentItem)->addChild(this);
1963 d->setEffectiveVisibleRecur(d->calcEffectiveVisible());
1964 d->setEffectiveEnableRecur(0, d->calcEffectiveEnable());
1966 if (scopeFocusedItem && d->parentItem && d->canvas) {
1967 // We need to test whether this item becomes scope focused
1968 QQuickItem *scopeItem = 0;
1969 scopeItem = d->parentItem;
1970 while (!scopeItem->isFocusScope()) scopeItem = scopeItem->parentItem();
1972 if (scopeItem->scopedFocusItem()) {
1973 QQuickItemPrivate::get(scopeFocusedItem)->focus = false;
1974 emit scopeFocusedItem->focusChanged(false);
1976 QQuickCanvasPrivate::get(d->canvas)->setFocusInScope(scopeItem, scopeFocusedItem,
1977 QQuickCanvasPrivate::DontChangeFocusProperty);
1981 d->resolveLayoutMirror();
1983 d->itemChange(ItemParentHasChanged, d->parentItem);
1985 d->parentNotifier.notify();
1986 if (d->isAccessible && d->parentItem) {
1987 d->parentItem->d_func()->setAccessibleFlagAndListener();
1990 emit parentChanged(d->parentItem);
1991 if (isVisible() && d->parentItem)
1992 emit d->parentItem->visibleChildrenChanged();
1995 void QQuickItem::stackBefore(const QQuickItem *sibling)
1998 if (!sibling || sibling == this || !d->parentItem || d->parentItem != QQuickItemPrivate::get(sibling)->parentItem) {
1999 qWarning("QQuickItem::stackBefore: Cannot stack before %p, which must be a sibling", sibling);
2003 QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(d->parentItem);
2005 int myIndex = parentPrivate->childItems.indexOf(this);
2006 int siblingIndex = parentPrivate->childItems.indexOf(const_cast<QQuickItem *>(sibling));
2008 Q_ASSERT(myIndex != -1 && siblingIndex != -1);
2010 if (myIndex == siblingIndex - 1)
2013 parentPrivate->childItems.removeAt(myIndex);
2015 if (myIndex < siblingIndex) --siblingIndex;
2017 parentPrivate->childItems.insert(siblingIndex, this);
2019 parentPrivate->dirty(QQuickItemPrivate::ChildrenStackingChanged);
2020 parentPrivate->markSortedChildrenDirty(this);
2022 for (int ii = qMin(siblingIndex, myIndex); ii < parentPrivate->childItems.count(); ++ii)
2023 QQuickItemPrivate::get(parentPrivate->childItems.at(ii))->siblingOrderChanged();
2026 void QQuickItem::stackAfter(const QQuickItem *sibling)
2029 if (!sibling || sibling == this || !d->parentItem || d->parentItem != QQuickItemPrivate::get(sibling)->parentItem) {
2030 qWarning("QQuickItem::stackAfter: Cannot stack after %p, which must be a sibling", sibling);
2034 QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(d->parentItem);
2036 int myIndex = parentPrivate->childItems.indexOf(this);
2037 int siblingIndex = parentPrivate->childItems.indexOf(const_cast<QQuickItem *>(sibling));
2039 Q_ASSERT(myIndex != -1 && siblingIndex != -1);
2041 if (myIndex == siblingIndex + 1)
2044 parentPrivate->childItems.removeAt(myIndex);
2046 if (myIndex < siblingIndex) --siblingIndex;
2048 parentPrivate->childItems.insert(siblingIndex + 1, this);
2050 parentPrivate->dirty(QQuickItemPrivate::ChildrenStackingChanged);
2051 parentPrivate->markSortedChildrenDirty(this);
2053 for (int ii = qMin(myIndex, siblingIndex + 1); ii < parentPrivate->childItems.count(); ++ii)
2054 QQuickItemPrivate::get(parentPrivate->childItems.at(ii))->siblingOrderChanged();
2058 Returns the QQuickItem parent of this item.
2060 QQuickItem *QQuickItem::parentItem() const
2062 Q_D(const QQuickItem);
2063 return d->parentItem;
2066 QSGEngine *QQuickItem::sceneGraphEngine() const
2068 return canvas()->sceneGraphEngine();
2071 QQuickCanvas *QQuickItem::canvas() const
2073 Q_D(const QQuickItem);
2077 static bool itemZOrder_sort(QQuickItem *lhs, QQuickItem *rhs)
2079 return lhs->z() < rhs->z();
2082 QList<QQuickItem *> QQuickItemPrivate::paintOrderChildItems() const
2084 if (sortedChildItems)
2085 return *sortedChildItems;
2087 // If none of the items have set Z then the paint order list is the same as
2088 // the childItems list. This is by far the most common case.
2090 for (int i = 0; i < childItems.count(); ++i) {
2091 if (QQuickItemPrivate::get(childItems.at(i))->z() != 0.) {
2097 sortedChildItems = new QList<QQuickItem*>(childItems);
2098 qStableSort(sortedChildItems->begin(), sortedChildItems->end(), itemZOrder_sort);
2099 return *sortedChildItems;
2102 sortedChildItems = const_cast<QList<QQuickItem*>*>(&childItems);
2107 void QQuickItemPrivate::addChild(QQuickItem *child)
2111 Q_ASSERT(!childItems.contains(child));
2113 childItems.append(child);
2115 markSortedChildrenDirty(child);
2116 dirty(QQuickItemPrivate::ChildrenChanged);
2118 itemChange(QQuickItem::ItemChildAddedChange, child);
2120 emit q->childrenChanged();
2123 void QQuickItemPrivate::removeChild(QQuickItem *child)
2128 Q_ASSERT(childItems.contains(child));
2129 childItems.removeOne(child);
2130 Q_ASSERT(!childItems.contains(child));
2132 markSortedChildrenDirty(child);
2133 dirty(QQuickItemPrivate::ChildrenChanged);
2135 itemChange(QQuickItem::ItemChildRemovedChange, child);
2137 emit q->childrenChanged();
2140 void QQuickItemPrivate::InitializationState::clear()
2145 void QQuickItemPrivate::InitializationState::clear(QQuickItem *fs)
2150 QQuickItem *QQuickItemPrivate::InitializationState::getFocusScope(QQuickItem *item)
2153 QQuickItem *fs = item->parentItem();
2154 while (fs->parentItem() && !fs->isFocusScope())
2155 fs = fs->parentItem();
2161 void QQuickItemPrivate::initCanvas(InitializationState *state, QQuickCanvas *c)
2166 removeFromDirtyList();
2167 QQuickCanvasPrivate *c = QQuickCanvasPrivate::get(canvas);
2168 if (polishScheduled)
2169 c->itemsToPolish.remove(q);
2170 if (c->mouseGrabberItem == q)
2171 c->mouseGrabberItem = 0;
2173 c->hoverItems.removeAll(q);
2174 if (itemNodeInstance)
2175 c->cleanup(itemNodeInstance);
2177 c->parentlessItems.remove(q);
2182 if (canvas && polishScheduled)
2183 QQuickCanvasPrivate::get(canvas)->itemsToPolish.insert(q);
2185 itemNodeInstance = 0;
2187 if (extra.isAllocated()) {
2188 extra->opacityNode = 0;
2189 extra->clipNode = 0;
2190 extra->rootNode = 0;
2191 extra->beforePaintNode = 0;
2197 InitializationState _dummy;
2198 InitializationState *childState = state;
2200 if (c && q->isFocusScope()) {
2202 childState = &_dummy;
2205 if (!parentItem && canvas)
2206 QQuickCanvasPrivate::get(canvas)->parentlessItems.insert(q);
2208 for (int ii = 0; ii < childItems.count(); ++ii) {
2209 QQuickItem *child = childItems.at(ii);
2210 QQuickItemPrivate::get(child)->initCanvas(childState, c);
2215 if (state->getFocusScope(q)->scopedFocusItem()) {
2217 emit q->focusChanged(false);
2219 QQuickCanvasPrivate::get(canvas)->setFocusInScope(state->getFocusScope(q), q);
2225 if (extra.isAllocated() && extra->screenAttached)
2226 extra->screenAttached->canvasChanged(c);
2227 itemChange(QQuickItem::ItemSceneChange, c);
2231 Returns a transform that maps points from canvas space into item space.
2233 QTransform QQuickItemPrivate::canvasToItemTransform() const
2235 // XXX todo - optimize
2236 return itemToCanvasTransform().inverted();
2240 Returns a transform that maps points from item space into canvas space.
2242 QTransform QQuickItemPrivate::itemToCanvasTransform() const
2245 QTransform rv = parentItem?QQuickItemPrivate::get(parentItem)->itemToCanvasTransform():QTransform();
2246 itemToParentTransform(rv);
2251 Motifies \a t with this items local transform relative to its parent.
2253 void QQuickItemPrivate::itemToParentTransform(QTransform &t) const
2258 if (!transforms.isEmpty()) {
2260 for (int ii = transforms.count() - 1; ii >= 0; --ii)
2261 transforms.at(ii)->applyTo(&m);
2262 t = m.toTransform();
2265 if (scale() != 1. || rotation() != 0.) {
2266 QPointF tp = computeTransformOrigin();
2267 t.translate(tp.x(), tp.y());
2268 t.scale(scale(), scale());
2269 t.rotate(rotation());
2270 t.translate(-tp.x(), -tp.y());
2276 \qmlproperty real QtQuick2::Item::childrenRect.x
2277 \qmlproperty real QtQuick2::Item::childrenRect.y
2278 \qmlproperty real QtQuick2::Item::childrenRect.width
2279 \qmlproperty real QtQuick2::Item::childrenRect.height
2281 The childrenRect properties allow an item access to the geometry of its
2282 children. This property is useful if you have an item that needs to be
2283 sized to fit its children.
2288 \qmlproperty list<Item> QtQuick2::Item::children
2289 \qmlproperty list<Object> QtQuick2::Item::resources
2291 The children property contains the list of visual children of this item.
2292 The resources property contains non-visual resources that you want to
2295 Generally you can rely on Item's default property to handle all this for
2296 you, but it can come in handy in some cases.
2315 Returns true if construction of the QML component is complete; otherwise
2318 It is often desirable to delay some processing until the component is
2321 \sa componentComplete()
2323 bool QQuickItem::isComponentComplete() const
2325 Q_D(const QQuickItem);
2326 return d->componentComplete;
2329 QQuickItemPrivate::QQuickItemPrivate()
2330 : _anchors(0), _stateGroup(0),
2331 flags(0), widthValid(false), heightValid(false), baselineOffsetValid(false), componentComplete(true),
2332 keepMouse(false), keepTouch(false), hoverEnabled(false), smooth(false), focus(false), activeFocus(false), notifiedFocus(false),
2333 notifiedActiveFocus(false), filtersChildMouseEvents(false), explicitVisible(true),
2334 effectiveVisible(true), explicitEnable(true), effectiveEnable(true), polishScheduled(false),
2335 inheritedLayoutMirror(false), effectiveLayoutMirror(false), isMirrorImplicit(true),
2336 inheritMirrorFromParent(false), inheritMirrorFromItem(false), childrenDoNotOverlap(false),
2337 staticSubtreeGeometry(false),
2338 isAccessible(false),
2340 dirtyAttributes(0), nextDirtyItem(0), prevDirtyItem(0),
2342 canvas(0), parentItem(0), sortedChildItems(&childItems),
2346 x(0), y(0), width(0), height(0), implicitWidth(0), implicitHeight(0),
2350 itemNodeInstance(0), groupNode(0), paintNode(0)
2354 QQuickItemPrivate::~QQuickItemPrivate()
2356 if (sortedChildItems != &childItems)
2357 delete sortedChildItems;
2360 void QQuickItemPrivate::init(QQuickItem *parent)
2364 static bool atexit_registered = false;
2365 if (!atexit_registered) {
2366 atexit(qt_print_item_count);
2367 atexit_registered = true;
2373 registerAccessorProperties();
2375 baselineOffsetValid = false;
2378 q->setParentItem(parent);
2379 QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(parent);
2380 setImplicitLayoutMirror(parentPrivate->inheritedLayoutMirror, parentPrivate->inheritMirrorFromParent);
2384 void QQuickItemPrivate::data_append(QQmlListProperty<QObject> *prop, QObject *o)
2389 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2391 // This test is measurably (albeit only slightly) faster than qobject_cast<>()
2392 const QMetaObject *mo = o->metaObject();
2393 while (mo && mo != &QQuickItem::staticMetaObject) {
2394 mo = mo->d.superdata;
2398 QQuickItem *item = static_cast<QQuickItem *>(o);
2399 item->setParentItem(that);
2401 if (o->inherits("QGraphicsItem"))
2402 qWarning("Cannot add a QtQuick 1.0 item (%s) into a QtQuick 2.0 scene!", o->metaObject()->className());
2404 // XXX todo - do we really want this behavior?
2410 \qmlproperty list<Object> QtQuick2::Item::data
2413 The data property allows you to freely mix visual children and resources
2414 in an item. If you assign a visual item to the data list it becomes
2415 a child and if you assign any other object type, it is added as a resource.
2439 data is a behind-the-scenes property: you should never need to explicitly
2443 int QQuickItemPrivate::data_count(QQmlListProperty<QObject> *prop)
2450 QObject *QQuickItemPrivate::data_at(QQmlListProperty<QObject> *prop, int i)
2458 void QQuickItemPrivate::data_clear(QQmlListProperty<QObject> *prop)
2464 QObject *QQuickItemPrivate::resources_at(QQmlListProperty<QObject> *prop, int index)
2466 const QObjectList children = prop->object->children();
2467 if (index < children.count())
2468 return children.at(index);
2473 void QQuickItemPrivate::resources_append(QQmlListProperty<QObject> *prop, QObject *o)
2475 // XXX todo - do we really want this behavior?
2476 o->setParent(prop->object);
2479 int QQuickItemPrivate::resources_count(QQmlListProperty<QObject> *prop)
2481 return prop->object->children().count();
2484 void QQuickItemPrivate::resources_clear(QQmlListProperty<QObject> *prop)
2486 // XXX todo - do we really want this behavior?
2487 const QObjectList children = prop->object->children();
2488 for (int index = 0; index < children.count(); index++)
2489 children.at(index)->setParent(0);
2492 QQuickItem *QQuickItemPrivate::children_at(QQmlListProperty<QQuickItem> *prop, int index)
2494 QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2495 if (index >= p->childItems.count() || index < 0)
2498 return p->childItems.at(index);
2501 void QQuickItemPrivate::children_append(QQmlListProperty<QQuickItem> *prop, QQuickItem *o)
2506 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2507 if (o->parentItem() == that)
2508 o->setParentItem(0);
2510 o->setParentItem(that);
2513 int QQuickItemPrivate::children_count(QQmlListProperty<QQuickItem> *prop)
2515 QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2516 return p->childItems.count();
2519 void QQuickItemPrivate::children_clear(QQmlListProperty<QQuickItem> *prop)
2521 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2522 QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2523 while (!p->childItems.isEmpty())
2524 p->childItems.at(0)->setParentItem(0);
2527 void QQuickItemPrivate::visibleChildren_append(QQmlListProperty<QQuickItem>*, QQuickItem *self)
2530 qmlInfo(self) << "QQuickItem: visibleChildren property is readonly and cannot be assigned to.";
2533 int QQuickItemPrivate::visibleChildren_count(QQmlListProperty<QQuickItem> *prop)
2535 QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2536 int visibleCount = 0;
2537 int c = p->childItems.count();
2539 if (p->childItems.at(c)->isVisible()) visibleCount++;
2542 return visibleCount;
2545 QQuickItem *QQuickItemPrivate::visibleChildren_at(QQmlListProperty<QQuickItem> *prop, int index)
2547 QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2548 const int childCount = p->childItems.count();
2549 if (index >= childCount || index < 0)
2552 int visibleCount = -1;
2553 for (int i = 0; i < childCount; i++) {
2554 if (p->childItems.at(i)->isVisible()) visibleCount++;
2555 if (visibleCount == index) return p->childItems.at(i);
2560 int QQuickItemPrivate::transform_count(QQmlListProperty<QQuickTransform> *prop)
2562 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2563 QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2565 return p->transforms.count();
2568 void QQuickTransform::appendToItem(QQuickItem *item)
2570 Q_D(QQuickTransform);
2574 QQuickItemPrivate *p = QQuickItemPrivate::get(item);
2576 if (!d->items.isEmpty() && !p->transforms.isEmpty() && p->transforms.contains(this)) {
2577 p->transforms.removeOne(this);
2578 p->transforms.append(this);
2580 p->transforms.append(this);
2581 d->items.append(item);
2584 p->dirty(QQuickItemPrivate::Transform);
2587 void QQuickTransform::prependToItem(QQuickItem *item)
2589 Q_D(QQuickTransform);
2593 QQuickItemPrivate *p = QQuickItemPrivate::get(item);
2595 if (!d->items.isEmpty() && !p->transforms.isEmpty() && p->transforms.contains(this)) {
2596 p->transforms.removeOne(this);
2597 p->transforms.prepend(this);
2599 p->transforms.prepend(this);
2600 d->items.append(item);
2603 p->dirty(QQuickItemPrivate::Transform);
2606 void QQuickItemPrivate::transform_append(QQmlListProperty<QQuickTransform> *prop, QQuickTransform *transform)
2611 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2612 transform->appendToItem(that);
2615 QQuickTransform *QQuickItemPrivate::transform_at(QQmlListProperty<QQuickTransform> *prop, int idx)
2617 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2618 QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2620 if (idx < 0 || idx >= p->transforms.count())
2623 return p->transforms.at(idx);
2626 void QQuickItemPrivate::transform_clear(QQmlListProperty<QQuickTransform> *prop)
2628 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2629 QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2631 for (int ii = 0; ii < p->transforms.count(); ++ii) {
2632 QQuickTransform *t = p->transforms.at(ii);
2633 QQuickTransformPrivate *tp = QQuickTransformPrivate::get(t);
2634 tp->items.removeOne(that);
2637 p->transforms.clear();
2639 p->dirty(QQuickItemPrivate::Transform);
2643 \property QQuickItem::childrenRect
2644 \brief The geometry of an item's children.
2646 This property holds the (collective) position and size of the item's children.
2650 \qmlproperty real QtQuick2::Item::x
2651 \qmlproperty real QtQuick2::Item::y
2652 \qmlproperty real QtQuick2::Item::width
2653 \qmlproperty real QtQuick2::Item::height
2655 Defines the item's position and size relative to its parent.
2658 Item { x: 100; y: 100; width: 100; height: 100 }
2663 \qmlproperty real QtQuick2::Item::z
2665 Sets the stacking order of sibling items. By default the stacking order is 0.
2667 Items with a higher stacking value are drawn on top of siblings with a
2668 lower stacking order. Items with the same stacking value are drawn
2669 bottom up in the order they appear. Items with a negative stacking
2670 value are drawn under their parent's content.
2672 The following example shows the various effects of stacking order.
2676 \li \image declarative-item_stacking1.png
2677 \li Same \c z - later children above earlier children:
2682 width: 100; height: 100
2686 x: 50; y: 50; width: 100; height: 100
2691 \li \image declarative-item_stacking2.png
2692 \li Higher \c z on top:
2698 width: 100; height: 100
2702 x: 50; y: 50; width: 100; height: 100
2707 \li \image declarative-item_stacking3.png
2708 \li Same \c z - children above parents:
2713 width: 100; height: 100
2716 x: 50; y: 50; width: 100; height: 100
2722 \li \image declarative-item_stacking4.png
2723 \li Lower \c z below:
2728 width: 100; height: 100
2732 x: 50; y: 50; width: 100; height: 100
2741 \qmlproperty bool QtQuick2::Item::visible
2743 This property holds whether the item is visible. By default this is true.
2745 Setting this property directly affects the \c visible value of child
2746 items. When set to \c false, the \c visible values of all child items also
2747 become \c false. When set to \c true, the \c visible values of child items
2748 are returned to \c true, unless they have explicitly been set to \c false.
2750 (Because of this flow-on behavior, using the \c visible property may not
2751 have the intended effect if a property binding should only respond to
2752 explicit property changes. In such cases it may be better to use the
2753 \l opacity property instead.)
2755 Setting this property to \c false automatically causes \l focus to be set
2756 to \c false, and this item will longer receive mouse and keyboard events.
2757 (In contrast, setting the \l opacity to 0 does not affect the \l focus
2758 property and the receiving of key events.)
2760 \note This property's value is only affected by changes to this property or
2761 the parent's \c visible property. It does not change, for example, if this
2762 item moves off-screen, or if the \l opacity changes to 0.
2767 \qmlproperty AnchorLine QtQuick2::Item::anchors.top
2768 \qmlproperty AnchorLine QtQuick2::Item::anchors.bottom
2769 \qmlproperty AnchorLine QtQuick2::Item::anchors.left
2770 \qmlproperty AnchorLine QtQuick2::Item::anchors.right
2771 \qmlproperty AnchorLine QtQuick2::Item::anchors.horizontalCenter
2772 \qmlproperty AnchorLine QtQuick2::Item::anchors.verticalCenter
2773 \qmlproperty AnchorLine QtQuick2::Item::anchors.baseline
2775 \qmlproperty Item QtQuick2::Item::anchors.fill
2776 \qmlproperty Item QtQuick2::Item::anchors.centerIn
2778 \qmlproperty real QtQuick2::Item::anchors.margins
2779 \qmlproperty real QtQuick2::Item::anchors.topMargin
2780 \qmlproperty real QtQuick2::Item::anchors.bottomMargin
2781 \qmlproperty real QtQuick2::Item::anchors.leftMargin
2782 \qmlproperty real QtQuick2::Item::anchors.rightMargin
2783 \qmlproperty real QtQuick2::Item::anchors.horizontalCenterOffset
2784 \qmlproperty real QtQuick2::Item::anchors.verticalCenterOffset
2785 \qmlproperty real QtQuick2::Item::anchors.baselineOffset
2787 \qmlproperty bool QtQuick2::Item::anchors.mirrored
2789 Anchors provide a way to position an item by specifying its
2790 relationship with other items.
2792 Margins apply to top, bottom, left, right, and fill anchors.
2793 The \c anchors.margins property can be used to set all of the various margins at once, to the same value.
2794 Note that margins are anchor-specific and are not applied if an item does not
2797 Offsets apply for horizontal center, vertical center, and baseline anchors.
2801 \li \image declarative-anchors_example.png
2802 \li Text anchored to Image, horizontally centered and vertically below, with a margin.
2811 anchors.horizontalCenter: pic.horizontalCenter
2812 anchors.top: pic.bottom
2813 anchors.topMargin: 5
2819 \li \image declarative-anchors_example2.png
2821 Left of Text anchored to right of Image, with a margin. The y
2822 property of both defaults to 0.
2832 anchors.left: pic.right
2833 anchors.leftMargin: 5
2840 \c anchors.fill provides a convenient way for one item to have the
2841 same geometry as another item, and is equivalent to connecting all
2842 four directional anchors.
2844 To clear an anchor value, set it to \c undefined.
2846 \c anchors.mirrored returns true it the layout has been \l {LayoutMirroring}{mirrored}.
2848 \note You can only anchor an item to siblings or a parent.
2850 For more information see \l {anchor-layout}{Anchor Layouts}.
2854 \property QQuickItem::baselineOffset
2855 \brief The position of the item's baseline in local coordinates.
2857 The baseline of a \l Text item is the imaginary line on which the text
2858 sits. Controls containing text usually set their baseline to the
2859 baseline of their text.
2861 For non-text items, a default baseline offset of 0 is used.
2863 QQuickAnchors *QQuickItemPrivate::anchors() const
2866 Q_Q(const QQuickItem);
2867 _anchors = new QQuickAnchors(const_cast<QQuickItem *>(q));
2868 if (!componentComplete)
2869 _anchors->classBegin();
2874 void QQuickItemPrivate::siblingOrderChanged()
2877 for (int ii = 0; ii < changeListeners.count(); ++ii) {
2878 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
2879 if (change.types & QQuickItemPrivate::SiblingOrder) {
2880 change.listener->itemSiblingOrderChanged(q);
2885 QQmlListProperty<QObject> QQuickItemPrivate::data()
2887 return QQmlListProperty<QObject>(q_func(), 0, QQuickItemPrivate::data_append,
2888 QQuickItemPrivate::data_count,
2889 QQuickItemPrivate::data_at,
2890 QQuickItemPrivate::data_clear);
2893 QRectF QQuickItem::childrenRect()
2896 if (!d->extra.isAllocated() || !d->extra->contents) {
2897 d->extra.value().contents = new QQuickContents(this);
2898 if (d->componentComplete)
2899 d->extra->contents->complete();
2901 return d->extra->contents->rectF();
2904 QList<QQuickItem *> QQuickItem::childItems() const
2906 Q_D(const QQuickItem);
2907 return d->childItems;
2910 bool QQuickItem::clip() const
2912 return flags() & ItemClipsChildrenToShape;
2915 void QQuickItem::setClip(bool c)
2920 setFlag(ItemClipsChildrenToShape, c);
2922 emit clipChanged(c);
2927 This function is called to handle this item's changes in
2928 geometry from \a oldGeometry to \a newGeometry. If the two
2929 geometries are the same, it doesn't do anything.
2931 void QQuickItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
2936 QQuickAnchorsPrivate::get(d->_anchors)->updateMe();
2938 bool xChange = (newGeometry.x() != oldGeometry.x());
2939 bool yChange = (newGeometry.y() != oldGeometry.y());
2940 bool widthChange = (newGeometry.width() != oldGeometry.width());
2941 bool heightChange = (newGeometry.height() != oldGeometry.height());
2943 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
2944 const QQuickItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
2945 if (change.types & QQuickItemPrivate::Geometry) {
2946 if (change.gTypes == QQuickItemPrivate::GeometryChange) {
2947 change.listener->itemGeometryChanged(this, newGeometry, oldGeometry);
2948 } else if ((xChange && (change.gTypes & QQuickItemPrivate::XChange)) ||
2949 (yChange && (change.gTypes & QQuickItemPrivate::YChange)) ||
2950 (widthChange && (change.gTypes & QQuickItemPrivate::WidthChange)) ||
2951 (heightChange && (change.gTypes & QQuickItemPrivate::HeightChange))) {
2952 change.listener->itemGeometryChanged(this, newGeometry, oldGeometry);
2962 emit widthChanged();
2964 emit heightChanged();
2968 Called by the rendering thread when it is time to sync the state of the QML objects with the
2969 scene graph objects. The function should return the root of the scene graph subtree for
2970 this item. \a oldNode is the node that was returned the last time the function was called.
2972 The main thread is blocked while this function is executed so it is safe to read
2973 values from the QQuickItem instance and other objects in the main thread.
2975 \warning This is the only function in which it is allowed to make use of scene graph
2976 objects from the main thread. Use of scene graph objects outside this function will
2977 result in race conditions and potential crashes.
2980 QSGNode *QQuickItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
2986 QSGTransformNode *QQuickItemPrivate::createTransformNode()
2988 return new QSGTransformNode;
2991 void QQuickItem::updatePolish()
2995 void QQuickItem::sendAccessibilityUpdate()
2999 void QQuickItemPrivate::addItemChangeListener(QQuickItemChangeListener *listener, ChangeTypes types)
3001 changeListeners.append(ChangeListener(listener, types));
3004 void QQuickItemPrivate::removeItemChangeListener(QQuickItemChangeListener *listener, ChangeTypes types)
3006 ChangeListener change(listener, types);
3007 changeListeners.removeOne(change);
3010 void QQuickItemPrivate::updateOrAddGeometryChangeListener(QQuickItemChangeListener *listener, GeometryChangeTypes types)
3012 ChangeListener change(listener, types);
3013 int index = changeListeners.find(change);
3015 changeListeners[index].gTypes = change.gTypes; //we may have different GeometryChangeTypes
3017 changeListeners.append(change);
3020 void QQuickItemPrivate::updateOrRemoveGeometryChangeListener(QQuickItemChangeListener *listener,
3021 GeometryChangeTypes types)
3023 ChangeListener change(listener, types);
3024 if (types == NoChange) {
3025 changeListeners.removeOne(change);
3027 int index = changeListeners.find(change);
3029 changeListeners[index].gTypes = change.gTypes; //we may have different GeometryChangeTypes
3033 void QQuickItem::keyPressEvent(QKeyEvent *event)
3038 void QQuickItem::keyReleaseEvent(QKeyEvent *event)
3043 void QQuickItem::inputMethodEvent(QInputMethodEvent *event)
3048 void QQuickItem::focusInEvent(QFocusEvent *)
3052 void QQuickItem::focusOutEvent(QFocusEvent *)
3056 void QQuickItem::mousePressEvent(QMouseEvent *event)
3061 void QQuickItem::mouseMoveEvent(QMouseEvent *event)
3066 void QQuickItem::mouseReleaseEvent(QMouseEvent *event)
3071 void QQuickItem::mouseDoubleClickEvent(QMouseEvent *)
3075 void QQuickItem::mouseUngrabEvent()
3080 void QQuickItem::touchUngrabEvent()
3085 void QQuickItem::wheelEvent(QWheelEvent *event)
3090 void QQuickItem::touchEvent(QTouchEvent *event)
3095 void QQuickItem::hoverEnterEvent(QHoverEvent *event)
3100 void QQuickItem::hoverMoveEvent(QHoverEvent *event)
3105 void QQuickItem::hoverLeaveEvent(QHoverEvent *event)
3110 void QQuickItem::dragEnterEvent(QDragEnterEvent *event)
3115 void QQuickItem::dragMoveEvent(QDragMoveEvent *event)
3121 void QQuickItem::dragLeaveEvent(QDragLeaveEvent *event)
3127 void QQuickItem::dropEvent(QDropEvent *event)
3132 bool QQuickItem::childMouseEventFilter(QQuickItem *, QEvent *)
3137 void QQuickItem::windowDeactivateEvent()
3139 foreach (QQuickItem* item, childItems()) {
3140 item->windowDeactivateEvent();
3144 QVariant QQuickItem::inputMethodQuery(Qt::InputMethodQuery query) const
3146 Q_D(const QQuickItem);
3151 v = (bool)(flags() & ItemAcceptsInputMethod);
3154 case Qt::ImCursorRectangle:
3156 case Qt::ImCursorPosition:
3157 case Qt::ImSurroundingText:
3158 case Qt::ImCurrentSelection:
3159 case Qt::ImMaximumTextLength:
3160 case Qt::ImAnchorPosition:
3161 case Qt::ImPreferredLanguage:
3162 if (d->extra.isAllocated() && d->extra->keyHandler)
3163 v = d->extra->keyHandler->inputMethodQuery(query);
3171 QQuickAnchorLine QQuickItemPrivate::left() const
3173 Q_Q(const QQuickItem);
3174 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Left);
3177 QQuickAnchorLine QQuickItemPrivate::right() const
3179 Q_Q(const QQuickItem);
3180 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Right);
3183 QQuickAnchorLine QQuickItemPrivate::horizontalCenter() const
3185 Q_Q(const QQuickItem);
3186 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::HCenter);
3189 QQuickAnchorLine QQuickItemPrivate::top() const
3191 Q_Q(const QQuickItem);
3192 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Top);
3195 QQuickAnchorLine QQuickItemPrivate::bottom() const
3197 Q_Q(const QQuickItem);
3198 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Bottom);
3201 QQuickAnchorLine QQuickItemPrivate::verticalCenter() const
3203 Q_Q(const QQuickItem);
3204 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::VCenter);
3207 QQuickAnchorLine QQuickItemPrivate::baseline() const
3209 Q_Q(const QQuickItem);
3210 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Baseline);
3213 qreal QQuickItem::baselineOffset() const
3215 Q_D(const QQuickItem);
3216 if (d->baselineOffsetValid) {
3217 return d->baselineOffset;
3223 void QQuickItem::setBaselineOffset(qreal offset)
3226 if (offset == d->baselineOffset)
3229 d->baselineOffset = offset;
3230 d->baselineOffsetValid = true;
3232 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
3233 const QQuickItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
3234 if (change.types & QQuickItemPrivate::Geometry) {
3235 QQuickAnchorsPrivate *anchor = change.listener->anchorPrivate();
3237 anchor->updateVerticalAnchors();
3240 emit baselineOffsetChanged(offset);
3243 void QQuickItem::update()
3246 Q_ASSERT(flags() & ItemHasContents);
3247 d->dirty(QQuickItemPrivate::Content);
3250 void QQuickItem::polish()
3253 if (!d->polishScheduled) {
3254 d->polishScheduled = true;
3256 QQuickCanvasPrivate *p = QQuickCanvasPrivate::get(d->canvas);
3257 bool maybeupdate = p->itemsToPolish.isEmpty();
3258 p->itemsToPolish.insert(this);
3259 if (maybeupdate) d->canvas->maybeUpdate();
3264 void QQuickItem::mapFromItem(QQmlV8Function *args) const
3266 if (args->Length() != 0) {
3267 v8::Local<v8::Value> item = (*args)[0];
3268 QV8Engine *engine = args->engine();
3270 QQuickItem *itemObj = 0;
3271 if (!item->IsNull())
3272 itemObj = qobject_cast<QQuickItem*>(engine->toQObject(item));
3274 if (!itemObj && !item->IsNull()) {
3275 qmlInfo(this) << "mapFromItem() given argument \"" << engine->toString(item->ToString())
3276 << "\" which is neither null nor an Item";
3280 v8::Local<v8::Object> rv = v8::Object::New();
3281 args->returnValue(rv);
3283 qreal x = (args->Length() > 1)?(*args)[1]->NumberValue():0;
3284 qreal y = (args->Length() > 2)?(*args)[2]->NumberValue():0;
3286 QPointF p = mapFromItem(itemObj, QPointF(x, y));
3288 rv->Set(v8::String::New("x"), v8::Number::New(p.x()));
3289 rv->Set(v8::String::New("y"), v8::Number::New(p.y()));
3293 QTransform QQuickItem::itemTransform(QQuickItem *other, bool *ok) const
3295 Q_D(const QQuickItem);
3297 // XXX todo - we need to be able to handle common parents better and detect
3301 QTransform t = d->itemToCanvasTransform();
3302 if (other) t *= QQuickItemPrivate::get(other)->canvasToItemTransform();
3307 void QQuickItem::mapToItem(QQmlV8Function *args) const
3309 if (args->Length() != 0) {
3310 v8::Local<v8::Value> item = (*args)[0];
3311 QV8Engine *engine = args->engine();
3313 QQuickItem *itemObj = 0;
3314 if (!item->IsNull())
3315 itemObj = qobject_cast<QQuickItem*>(engine->toQObject(item));
3317 if (!itemObj && !item->IsNull()) {
3318 qmlInfo(this) << "mapToItem() given argument \"" << engine->toString(item->ToString())
3319 << "\" which is neither null nor an Item";
3323 v8::Local<v8::Object> rv = v8::Object::New();
3324 args->returnValue(rv);
3326 qreal x = (args->Length() > 1)?(*args)[1]->NumberValue():0;
3327 qreal y = (args->Length() > 2)?(*args)[2]->NumberValue():0;
3329 QPointF p = mapToItem(itemObj, QPointF(x, y));
3331 rv->Set(v8::String::New("x"), v8::Number::New(p.x()));
3332 rv->Set(v8::String::New("y"), v8::Number::New(p.y()));
3336 void QQuickItem::forceActiveFocus()
3339 QQuickItem *parent = parentItem();
3341 if (parent->flags() & QQuickItem::ItemIsFocusScope) {
3342 parent->setFocus(true);
3344 parent = parent->parentItem();
3348 QQuickItem *QQuickItem::childAt(qreal x, qreal y) const
3350 // XXX todo - should this include transform etc.?
3351 const QList<QQuickItem *> children = childItems();
3352 for (int i = children.count()-1; i >= 0; --i) {
3353 QQuickItem *child = children.at(i);
3354 if (child->isVisible() && child->x() <= x
3355 && child->x() + child->width() >= x
3357 && child->y() + child->height() >= y)
3363 QQmlListProperty<QObject> QQuickItemPrivate::resources()
3365 return QQmlListProperty<QObject>(q_func(), 0, QQuickItemPrivate::resources_append,
3366 QQuickItemPrivate::resources_count,
3367 QQuickItemPrivate::resources_at,
3368 QQuickItemPrivate::resources_clear);
3371 QQmlListProperty<QQuickItem> QQuickItemPrivate::children()
3373 return QQmlListProperty<QQuickItem>(q_func(), 0, QQuickItemPrivate::children_append,
3374 QQuickItemPrivate::children_count,
3375 QQuickItemPrivate::children_at,
3376 QQuickItemPrivate::children_clear);
3381 \qmlproperty real QtQuick2::Item::visibleChildren
3382 This read-only property lists all of the item's children that are currently visible.
3383 Note that a child's visibility may have changed explicitly, or because the visibility
3384 of this (it's parent) item or another grandparent changed.
3386 QQmlListProperty<QQuickItem> QQuickItemPrivate::visibleChildren()
3388 return QQmlListProperty<QQuickItem>(q_func(), 0, QQuickItemPrivate::visibleChildren_append,
3389 QQuickItemPrivate::visibleChildren_count,
3390 QQuickItemPrivate::visibleChildren_at);
3394 QQmlListProperty<QQuickState> QQuickItemPrivate::states()
3396 return _states()->statesProperty();
3399 QQmlListProperty<QQuickTransition> QQuickItemPrivate::transitions()
3401 return _states()->transitionsProperty();
3404 QString QQuickItemPrivate::state() const
3409 return _stateGroup->state();
3412 void QQuickItemPrivate::setState(const QString &state)
3414 _states()->setState(state);
3417 QString QQuickItem::state() const
3419 Q_D(const QQuickItem);
3423 void QQuickItem::setState(const QString &state)
3429 QQmlListProperty<QQuickTransform> QQuickItem::transform()
3431 return QQmlListProperty<QQuickTransform>(this, 0, QQuickItemPrivate::transform_append,
3432 QQuickItemPrivate::transform_count,
3433 QQuickItemPrivate::transform_at,
3434 QQuickItemPrivate::transform_clear);
3437 void QQuickItem::classBegin()
3440 d->componentComplete = false;
3442 d->_stateGroup->classBegin();
3444 d->_anchors->classBegin();
3445 if (d->extra.isAllocated() && d->extra->layer)
3446 d->extra->layer->classBegin();
3449 void QQuickItem::componentComplete()
3452 d->componentComplete = true;
3454 d->_stateGroup->componentComplete();
3456 d->_anchors->componentComplete();
3457 QQuickAnchorsPrivate::get(d->_anchors)->updateOnComplete();
3460 if (d->extra.isAllocated() && d->extra->layer)
3461 d->extra->layer->componentComplete();
3463 if (d->extra.isAllocated() && d->extra->keyHandler)
3464 d->extra->keyHandler->componentComplete();
3466 if (d->extra.isAllocated() && d->extra->contents)
3467 d->extra->contents->complete();
3470 QQuickStateGroup *QQuickItemPrivate::_states()
3474 _stateGroup = new QQuickStateGroup;
3475 if (!componentComplete)
3476 _stateGroup->classBegin();
3477 FAST_CONNECT(_stateGroup, SIGNAL(stateChanged(QString)),
3478 q, SIGNAL(stateChanged(QString)))
3484 QPointF QQuickItemPrivate::computeTransformOrigin() const
3488 case QQuickItem::TopLeft:
3489 return QPointF(0, 0);
3490 case QQuickItem::Top:
3491 return QPointF(width / 2., 0);
3492 case QQuickItem::TopRight:
3493 return QPointF(width, 0);
3494 case QQuickItem::Left:
3495 return QPointF(0, height / 2.);
3496 case QQuickItem::Center:
3497 return QPointF(width / 2., height / 2.);
3498 case QQuickItem::Right:
3499 return QPointF(width, height / 2.);
3500 case QQuickItem::BottomLeft:
3501 return QPointF(0, height);
3502 case QQuickItem::Bottom:
3503 return QPointF(width / 2., height);
3504 case QQuickItem::BottomRight:
3505 return QPointF(width, height);
3509 void QQuickItemPrivate::transformChanged()
3511 if (extra.isAllocated() && extra->layer)
3512 extra->layer->updateMatrix();
3515 void QQuickItemPrivate::deliverKeyEvent(QKeyEvent *e)
3519 Q_ASSERT(e->isAccepted());
3520 if (extra.isAllocated() && extra->keyHandler) {
3521 if (e->type() == QEvent::KeyPress)
3522 extra->keyHandler->keyPressed(e, false);
3524 extra->keyHandler->keyReleased(e, false);
3526 if (e->isAccepted())
3532 if (e->type() == QEvent::KeyPress)
3533 q->keyPressEvent(e);
3535 q->keyReleaseEvent(e);
3537 if (e->isAccepted())
3540 if (extra.isAllocated() && extra->keyHandler) {
3543 if (e->type() == QEvent::KeyPress)
3544 extra->keyHandler->keyPressed(e, true);
3546 extra->keyHandler->keyReleased(e, true);
3550 void QQuickItemPrivate::deliverInputMethodEvent(QInputMethodEvent *e)
3554 Q_ASSERT(e->isAccepted());
3555 if (extra.isAllocated() && extra->keyHandler) {
3556 extra->keyHandler->inputMethodEvent(e, false);
3558 if (e->isAccepted())
3564 q->inputMethodEvent(e);
3566 if (e->isAccepted())
3569 if (extra.isAllocated() && extra->keyHandler) {
3572 extra->keyHandler->inputMethodEvent(e, true);
3576 void QQuickItemPrivate::deliverFocusEvent(QFocusEvent *e)
3580 if (e->type() == QEvent::FocusIn) {
3583 q->focusOutEvent(e);
3587 void QQuickItemPrivate::deliverMouseEvent(QMouseEvent *e)
3591 Q_ASSERT(e->isAccepted());
3593 switch (e->type()) {
3595 Q_ASSERT(!"Unknown event type");
3596 case QEvent::MouseMove:
3597 q->mouseMoveEvent(e);
3599 case QEvent::MouseButtonPress:
3600 q->mousePressEvent(e);
3602 case QEvent::MouseButtonRelease:
3603 q->mouseReleaseEvent(e);
3605 case QEvent::MouseButtonDblClick:
3606 q->mouseDoubleClickEvent(e);
3611 void QQuickItemPrivate::deliverWheelEvent(QWheelEvent *e)
3617 void QQuickItemPrivate::deliverTouchEvent(QTouchEvent *e)
3623 void QQuickItemPrivate::deliverHoverEvent(QHoverEvent *e)
3626 switch (e->type()) {
3628 Q_ASSERT(!"Unknown event type");
3629 case QEvent::HoverEnter:
3630 q->hoverEnterEvent(e);
3632 case QEvent::HoverLeave:
3633 q->hoverLeaveEvent(e);
3635 case QEvent::HoverMove:
3636 q->hoverMoveEvent(e);
3641 void QQuickItemPrivate::deliverDragEvent(QEvent *e)
3644 switch (e->type()) {
3646 Q_ASSERT(!"Unknown event type");
3647 case QEvent::DragEnter:
3648 q->dragEnterEvent(static_cast<QDragEnterEvent *>(e));
3650 case QEvent::DragLeave:
3651 q->dragLeaveEvent(static_cast<QDragLeaveEvent *>(e));
3653 case QEvent::DragMove:
3654 q->dragMoveEvent(static_cast<QDragMoveEvent *>(e));
3657 q->dropEvent(static_cast<QDropEvent *>(e));
3662 void QQuickItem::itemChange(ItemChange change, const ItemChangeData &value)
3669 Notify input method on updated query values if needed. \a indicates changed attributes.
3671 void QQuickItem::updateInputMethod(Qt::InputMethodQueries queries)
3673 if (hasActiveFocus())
3674 qApp->inputMethod()->update(queries);
3678 // XXX todo - do we want/need this anymore?
3679 // Note that it's now used for varying clip rect
3680 QRectF QQuickItem::boundingRect() const
3682 Q_D(const QQuickItem);
3683 return QRectF(0, 0, d->width, d->height);
3686 QQuickItem::TransformOrigin QQuickItem::transformOrigin() const
3688 Q_D(const QQuickItem);
3692 void QQuickItem::setTransformOrigin(TransformOrigin origin)
3695 if (origin == d->origin())
3698 d->extra.value().origin = origin;
3699 d->dirty(QQuickItemPrivate::TransformOrigin);
3701 emit transformOriginChanged(d->origin());
3704 QPointF QQuickItem::transformOriginPoint() const
3706 Q_D(const QQuickItem);
3707 if (d->extra.isAllocated() && !d->extra->userTransformOriginPoint.isNull())
3708 return d->extra->userTransformOriginPoint;
3709 return d->computeTransformOrigin();
3712 void QQuickItem::setTransformOriginPoint(const QPointF &point)
3715 if (d->extra.value().userTransformOriginPoint == point)
3718 d->extra->userTransformOriginPoint = point;
3719 d->dirty(QQuickItemPrivate::TransformOrigin);
3722 qreal QQuickItem::z() const
3724 Q_D(const QQuickItem);
3728 void QQuickItem::setZ(qreal v)
3734 d->extra.value().z = v;
3736 d->dirty(QQuickItemPrivate::ZValue);
3737 if (d->parentItem) {
3738 QQuickItemPrivate::get(d->parentItem)->dirty(QQuickItemPrivate::ChildrenStackingChanged);
3739 QQuickItemPrivate::get(d->parentItem)->markSortedChildrenDirty(this);
3744 if (d->extra.isAllocated() && d->extra->layer)
3745 d->extra->layer->updateZ();
3750 \qmlproperty real QtQuick2::Item::rotation
3751 This property holds the rotation of the item in degrees clockwise.
3753 This specifies how many degrees to rotate the item around its transformOrigin.
3754 The default rotation is 0 degrees (i.e. not rotated at all).
3758 \li \image declarative-rotation.png
3763 width: 100; height: 100
3766 x: 25; y: 25; width: 50; height: 50
3773 \sa transform, Rotation
3777 \qmlproperty real QtQuick2::Item::scale
3778 This property holds the scale of the item.
3780 A scale of less than 1 means the item will be displayed smaller than
3781 normal, and a scale of greater than 1 means the item will be
3782 displayed larger than normal. A negative scale means the item will
3785 By default, items are displayed at a scale of 1 (i.e. at their
3788 Scaling is from the item's transformOrigin.
3792 \li \image declarative-scale.png
3797 width: 100; height: 100
3800 width: 25; height: 25
3804 x: 25; y: 25; width: 50; height: 50
3811 \sa transform, Scale
3815 \qmlproperty real QtQuick2::Item::opacity
3817 This property holds the opacity of the item. Opacity is specified as a
3818 number between 0 (fully transparent) and 1 (fully opaque). The default is 1.
3820 When this property is set, the specified opacity is also applied
3821 individually to child items. In almost all cases this is what you want,
3822 but in some cases it may produce undesired results. For example in the
3823 second set of rectangles below, the red rectangle has specified an opacity
3824 of 0.5, which affects the opacity of its blue child rectangle even though
3825 the child has not specified an opacity.
3829 \li \image declarative-item_opacity1.png
3835 width: 100; height: 100
3838 x: 50; y: 50; width: 100; height: 100
3844 \li \image declarative-item_opacity2.png
3851 width: 100; height: 100
3854 x: 50; y: 50; width: 100; height: 100
3861 If an item's opacity is set to 0, the item will no longer receive mouse
3862 events, but will continue to receive key events and will retain the keyboard
3863 \l focus if it has been set. (In contrast, setting the \l visible property
3864 to \c false stops both mouse and keyboard events, and also removes focus
3869 Returns a value indicating whether mouse input should
3870 remain with this item exclusively.
3872 \sa setKeepMouseGrab()
3875 qreal QQuickItem::rotation() const
3877 Q_D(const QQuickItem);
3878 return d->rotation();
3881 void QQuickItem::setRotation(qreal r)
3884 if (d->rotation() == r)
3887 d->extra.value().rotation = r;
3889 d->dirty(QQuickItemPrivate::BasicTransform);
3891 d->itemChange(ItemRotationHasChanged, r);
3893 emit rotationChanged();
3896 qreal QQuickItem::scale() const
3898 Q_D(const QQuickItem);
3902 void QQuickItem::setScale(qreal s)
3905 if (d->scale() == s)
3908 d->extra.value().scale = s;
3910 d->dirty(QQuickItemPrivate::BasicTransform);
3912 emit scaleChanged();
3915 qreal QQuickItem::opacity() const
3917 Q_D(const QQuickItem);
3918 return d->opacity();
3921 void QQuickItem::setOpacity(qreal o)
3924 if (d->opacity() == o)
3927 d->extra.value().opacity = o;
3929 d->dirty(QQuickItemPrivate::OpacityValue);
3931 d->itemChange(ItemOpacityHasChanged, o);
3933 emit opacityChanged();
3936 bool QQuickItem::isVisible() const
3938 Q_D(const QQuickItem);
3939 return d->effectiveVisible;
3942 void QQuickItem::setVisible(bool v)
3945 if (v == d->explicitVisible)
3948 d->explicitVisible = v;
3950 const bool childVisibilityChanged = d->setEffectiveVisibleRecur(d->calcEffectiveVisible());
3951 if (childVisibilityChanged && d->parentItem)
3952 emit d->parentItem->visibleChildrenChanged(); // signal the parent, not this!
3955 bool QQuickItem::isEnabled() const
3957 Q_D(const QQuickItem);
3958 return d->effectiveEnable;
3961 void QQuickItem::setEnabled(bool e)
3964 if (e == d->explicitEnable)
3967 d->explicitEnable = e;
3969 QQuickItem *scope = parentItem();
3970 while (scope && !scope->isFocusScope())
3971 scope = scope->parentItem();
3973 d->setEffectiveEnableRecur(scope, d->calcEffectiveEnable());
3976 bool QQuickItemPrivate::calcEffectiveVisible() const
3978 // XXX todo - Should the effective visible of an element with no parent just be the current
3979 // effective visible? This would prevent pointless re-processing in the case of an element
3980 // moving to/from a no-parent situation, but it is different from what graphics view does.
3981 return explicitVisible && (!parentItem || QQuickItemPrivate::get(parentItem)->effectiveVisible);
3984 bool QQuickItemPrivate::setEffectiveVisibleRecur(bool newEffectiveVisible)
3988 if (newEffectiveVisible && !explicitVisible) {
3989 // This item locally overrides visibility
3990 return false; // effective visibility didn't change
3993 if (newEffectiveVisible == effectiveVisible) {
3994 // No change necessary
3995 return false; // effective visibility didn't change
3998 effectiveVisible = newEffectiveVisible;
4000 if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
4003 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(canvas);
4004 if (canvasPriv->mouseGrabberItem == q)
4008 bool childVisibilityChanged = false;
4009 for (int ii = 0; ii < childItems.count(); ++ii)
4010 childVisibilityChanged |= QQuickItemPrivate::get(childItems.at(ii))->setEffectiveVisibleRecur(newEffectiveVisible);
4012 itemChange(QQuickItem::ItemVisibleHasChanged, effectiveVisible);
4014 emit q->visibleChanged();
4015 if (childVisibilityChanged)
4016 emit q->visibleChildrenChanged();
4018 return true; // effective visibility DID change
4021 bool QQuickItemPrivate::calcEffectiveEnable() const
4023 // XXX todo - Should the effective enable of an element with no parent just be the current
4024 // effective enable? This would prevent pointless re-processing in the case of an element
4025 // moving to/from a no-parent situation, but it is different from what graphics view does.
4026 return explicitEnable && (!parentItem || QQuickItemPrivate::get(parentItem)->effectiveEnable);
4029 void QQuickItemPrivate::setEffectiveEnableRecur(QQuickItem *scope, bool newEffectiveEnable)
4033 if (newEffectiveEnable && !explicitEnable) {
4034 // This item locally overrides enable
4038 if (newEffectiveEnable == effectiveEnable) {
4039 // No change necessary
4043 effectiveEnable = newEffectiveEnable;
4046 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(canvas);
4047 if (canvasPriv->mouseGrabberItem == q)
4049 if (scope && !effectiveEnable && activeFocus) {
4050 canvasPriv->clearFocusInScope(
4051 scope, q, QQuickCanvasPrivate::DontChangeFocusProperty | QQuickCanvasPrivate::DontChangeSubFocusItem);
4055 for (int ii = 0; ii < childItems.count(); ++ii) {
4056 QQuickItemPrivate::get(childItems.at(ii))->setEffectiveEnableRecur(
4057 flags & QQuickItem::ItemIsFocusScope ? q : scope, newEffectiveEnable);
4060 if (canvas && scope && effectiveEnable && focus) {
4061 QQuickCanvasPrivate::get(canvas)->setFocusInScope(
4062 scope, q, QQuickCanvasPrivate::DontChangeFocusProperty | QQuickCanvasPrivate::DontChangeSubFocusItem);
4065 emit q->enabledChanged();
4068 QString QQuickItemPrivate::dirtyToString() const
4070 #define DIRTY_TO_STRING(value) if (dirtyAttributes & value) { \
4071 if (!rv.isEmpty()) \
4072 rv.append(QLatin1String("|")); \
4073 rv.append(QLatin1String(#value)); \
4076 // QString rv = QLatin1String("0x") + QString::number(dirtyAttributes, 16);
4079 DIRTY_TO_STRING(TransformOrigin);
4080 DIRTY_TO_STRING(Transform);
4081 DIRTY_TO_STRING(BasicTransform);
4082 DIRTY_TO_STRING(Position);
4083 DIRTY_TO_STRING(Size);
4084 DIRTY_TO_STRING(ZValue);
4085 DIRTY_TO_STRING(Content);
4086 DIRTY_TO_STRING(Smooth);
4087 DIRTY_TO_STRING(OpacityValue);
4088 DIRTY_TO_STRING(ChildrenChanged);
4089 DIRTY_TO_STRING(ChildrenStackingChanged);
4090 DIRTY_TO_STRING(ParentChanged);
4091 DIRTY_TO_STRING(Clip);
4092 DIRTY_TO_STRING(Canvas);
4093 DIRTY_TO_STRING(EffectReference);
4094 DIRTY_TO_STRING(Visible);
4095 DIRTY_TO_STRING(HideReference);
4096 DIRTY_TO_STRING(PerformanceHints);
4101 void QQuickItemPrivate::dirty(DirtyType type)
4104 if (type & (TransformOrigin | Transform | BasicTransform | Position | Size))
4107 if (!(dirtyAttributes & type) || (canvas && !prevDirtyItem)) {
4108 dirtyAttributes |= type;
4111 QQuickCanvasPrivate::get(canvas)->dirtyItem(q);
4116 void QQuickItemPrivate::addToDirtyList()
4121 if (!prevDirtyItem) {
4122 Q_ASSERT(!nextDirtyItem);
4124 QQuickCanvasPrivate *p = QQuickCanvasPrivate::get(canvas);
4125 nextDirtyItem = p->dirtyItemList;
4126 if (nextDirtyItem) QQuickItemPrivate::get(nextDirtyItem)->prevDirtyItem = &nextDirtyItem;
4127 prevDirtyItem = &p->dirtyItemList;
4128 p->dirtyItemList = q;
4131 Q_ASSERT(prevDirtyItem);
4134 void QQuickItemPrivate::removeFromDirtyList()
4136 if (prevDirtyItem) {
4137 if (nextDirtyItem) QQuickItemPrivate::get(nextDirtyItem)->prevDirtyItem = prevDirtyItem;
4138 *prevDirtyItem = nextDirtyItem;
4142 Q_ASSERT(!prevDirtyItem);
4143 Q_ASSERT(!nextDirtyItem);
4146 void QQuickItemPrivate::refFromEffectItem(bool hide)
4148 ++extra.value().effectRefCount;
4149 if (1 == extra->effectRefCount) {
4150 dirty(EffectReference);
4151 if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
4154 if (++extra->hideRefCount == 1)
4155 dirty(HideReference);
4159 void QQuickItemPrivate::derefFromEffectItem(bool unhide)
4161 Q_ASSERT(extra->effectRefCount);
4162 --extra->effectRefCount;
4163 if (0 == extra->effectRefCount) {
4164 dirty(EffectReference);
4165 if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
4168 if (--extra->hideRefCount == 0)
4169 dirty(HideReference);
4173 void QQuickItemPrivate::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data)
4177 case QQuickItem::ItemChildAddedChange:
4178 q->itemChange(change, data);
4179 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4180 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4181 if (change.types & QQuickItemPrivate::Children) {
4182 change.listener->itemChildAdded(q, data.item);
4186 case QQuickItem::ItemChildRemovedChange:
4187 q->itemChange(change, data);
4188 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4189 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4190 if (change.types & QQuickItemPrivate::Children) {
4191 change.listener->itemChildRemoved(q, data.item);
4195 case QQuickItem::ItemSceneChange:
4196 q->itemChange(change, data);
4198 case QQuickItem::ItemVisibleHasChanged:
4199 q->itemChange(change, data);
4200 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4201 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4202 if (change.types & QQuickItemPrivate::Visibility) {
4203 change.listener->itemVisibilityChanged(q);
4207 case QQuickItem::ItemParentHasChanged:
4208 q->itemChange(change, data);
4209 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4210 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4211 if (change.types & QQuickItemPrivate::Parent) {
4212 change.listener->itemParentChanged(q, data.item);
4216 case QQuickItem::ItemOpacityHasChanged:
4217 q->itemChange(change, data);
4218 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4219 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4220 if (change.types & QQuickItemPrivate::Opacity) {
4221 change.listener->itemOpacityChanged(q);
4225 case QQuickItem::ItemActiveFocusHasChanged:
4226 q->itemChange(change, data);
4228 case QQuickItem::ItemRotationHasChanged:
4229 q->itemChange(change, data);
4230 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4231 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4232 if (change.types & QQuickItemPrivate::Rotation) {
4233 change.listener->itemRotationChanged(q);
4241 \property QQuickItem::smooth
4242 \brief whether the item is smoothly transformed.
4244 This property is provided purely for the purpose of optimization. Turning
4245 smooth transforms off is faster, but looks worse; turning smooth
4246 transformations on is slower, but looks better.
4248 By default smooth transformations are off.
4252 Returns true if the item should be drawn with antialiasing and
4253 smooth pixmap filtering, false otherwise.
4255 The default is false.
4259 bool QQuickItem::smooth() const
4261 Q_D(const QQuickItem);
4266 Sets whether the item should be drawn with antialiasing and
4267 smooth pixmap filtering to \a smooth.
4271 void QQuickItem::setSmooth(bool smooth)
4274 if (d->smooth == smooth)
4278 d->dirty(QQuickItemPrivate::Smooth);
4280 emit smoothChanged(smooth);
4283 QQuickItem::Flags QQuickItem::flags() const
4285 Q_D(const QQuickItem);
4286 return (QQuickItem::Flags)d->flags;
4289 void QQuickItem::setFlag(Flag flag, bool enabled)
4293 setFlags((Flags)(d->flags | (quint32)flag));
4295 setFlags((Flags)(d->flags & ~(quint32)flag));
4298 void QQuickItem::setFlags(Flags flags)
4302 if ((flags & ItemIsFocusScope) != (d->flags & ItemIsFocusScope)) {
4303 if (flags & ItemIsFocusScope && !d->childItems.isEmpty() && d->canvas) {
4304 qWarning("QQuickItem: Cannot set FocusScope once item has children and is in a canvas.");
4305 flags &= ~ItemIsFocusScope;
4306 } else if (d->flags & ItemIsFocusScope) {
4307 qWarning("QQuickItem: Cannot unset FocusScope flag.");
4308 flags |= ItemIsFocusScope;
4312 if ((flags & ItemClipsChildrenToShape ) != (d->flags & ItemClipsChildrenToShape))
4313 d->dirty(QQuickItemPrivate::Clip);
4318 qreal QQuickItem::x() const
4320 Q_D(const QQuickItem);
4324 qreal QQuickItem::y() const
4326 Q_D(const QQuickItem);
4330 QPointF QQuickItem::pos() const
4332 Q_D(const QQuickItem);
4333 return QPointF(d->x, d->y);
4336 void QQuickItem::setX(qreal v)
4345 d->dirty(QQuickItemPrivate::Position);
4347 geometryChanged(QRectF(x(), y(), width(), height()),
4348 QRectF(oldx, y(), width(), height()));
4351 void QQuickItem::setY(qreal v)
4360 d->dirty(QQuickItemPrivate::Position);
4362 geometryChanged(QRectF(x(), y(), width(), height()),
4363 QRectF(x(), oldy, width(), height()));
4366 void QQuickItem::setPos(const QPointF &pos)
4369 if (QPointF(d->x, d->y) == pos)
4378 d->dirty(QQuickItemPrivate::Position);
4380 geometryChanged(QRectF(x(), y(), width(), height()),
4381 QRectF(oldx, oldy, width(), height()));
4384 qreal QQuickItem::width() const
4386 Q_D(const QQuickItem);
4390 void QQuickItem::setWidth(qreal w)
4396 d->widthValid = true;
4400 qreal oldWidth = d->width;
4403 d->dirty(QQuickItemPrivate::Size);
4405 geometryChanged(QRectF(x(), y(), width(), height()),
4406 QRectF(x(), y(), oldWidth, height()));
4409 void QQuickItem::resetWidth()
4412 d->widthValid = false;
4413 setImplicitWidth(implicitWidth());
4416 void QQuickItemPrivate::implicitWidthChanged()
4419 emit q->implicitWidthChanged();
4422 qreal QQuickItemPrivate::getImplicitWidth() const
4424 return implicitWidth;
4427 Returns the width of the item that is implied by other properties that determine the content.
4429 qreal QQuickItem::implicitWidth() const
4431 Q_D(const QQuickItem);
4432 return d->getImplicitWidth();
4436 \qmlproperty real QtQuick2::Item::implicitWidth
4437 \qmlproperty real QtQuick2::Item::implicitHeight
4439 Defines the natural width or height of the Item if no \l width or \l height is specified.
4441 The default implicit size for most items is 0x0, however some elements have an inherent
4442 implicit size which cannot be overridden, e.g. Image, Text.
4444 Setting the implicit size is useful for defining components that have a preferred size
4445 based on their content, for example:
4452 property alias icon: image.source
4453 property alias label: text.text
4454 implicitWidth: text.implicitWidth + image.implicitWidth
4455 implicitHeight: Math.max(text.implicitHeight, image.implicitHeight)
4460 anchors.left: image.right; anchors.right: parent.right
4461 anchors.verticalCenter: parent.verticalCenter
4466 \b Note: using implicitWidth of Text or TextEdit and setting the width explicitly
4467 incurs a performance penalty as the text must be laid out twice.
4471 Sets the implied width of the item to \a w.
4472 This is the width implied by other properties that determine the content.
4474 void QQuickItem::setImplicitWidth(qreal w)
4477 bool changed = w != d->implicitWidth;
4478 d->implicitWidth = w;
4479 if (d->width == w || widthValid()) {
4481 d->implicitWidthChanged();
4485 qreal oldWidth = d->width;
4488 d->dirty(QQuickItemPrivate::Size);
4490 geometryChanged(QRectF(x(), y(), width(), height()),
4491 QRectF(x(), y(), oldWidth, height()));
4494 d->implicitWidthChanged();
4498 Returns whether the width property has been set explicitly.
4500 bool QQuickItem::widthValid() const
4502 Q_D(const QQuickItem);
4503 return d->widthValid;
4506 qreal QQuickItem::height() const
4508 Q_D(const QQuickItem);
4512 void QQuickItem::setHeight(qreal h)
4518 d->heightValid = true;
4522 qreal oldHeight = d->height;
4525 d->dirty(QQuickItemPrivate::Size);
4527 geometryChanged(QRectF(x(), y(), width(), height()),
4528 QRectF(x(), y(), width(), oldHeight));
4531 void QQuickItem::resetHeight()
4534 d->heightValid = false;
4535 setImplicitHeight(implicitHeight());
4538 void QQuickItemPrivate::implicitHeightChanged()
4541 emit q->implicitHeightChanged();
4544 qreal QQuickItemPrivate::getImplicitHeight() const
4546 return implicitHeight;
4550 Returns the height of the item that is implied by other properties that determine the content.
4552 qreal QQuickItem::implicitHeight() const
4554 Q_D(const QQuickItem);
4555 return d->getImplicitHeight();
4560 Sets the implied height of the item to \a h.
4561 This is the height implied by other properties that determine the content.
4563 void QQuickItem::setImplicitHeight(qreal h)
4566 bool changed = h != d->implicitHeight;
4567 d->implicitHeight = h;
4568 if (d->height == h || heightValid()) {
4570 d->implicitHeightChanged();
4574 qreal oldHeight = d->height;
4577 d->dirty(QQuickItemPrivate::Size);
4579 geometryChanged(QRectF(x(), y(), width(), height()),
4580 QRectF(x(), y(), width(), oldHeight));
4583 d->implicitHeightChanged();
4586 void QQuickItem::setImplicitSize(qreal w, qreal h)
4589 bool wChanged = w != d->implicitWidth;
4590 bool hChanged = h != d->implicitHeight;
4592 d->implicitWidth = w;
4593 d->implicitHeight = h;
4597 if (d->width == w || widthValid()) {
4599 d->implicitWidthChanged();
4602 if (d->height == h || heightValid()) {
4604 d->implicitHeightChanged();
4610 qreal oldWidth = d->width;
4611 qreal oldHeight = d->height;
4617 d->dirty(QQuickItemPrivate::Size);
4619 geometryChanged(QRectF(x(), y(), width(), height()),
4620 QRectF(x(), y(), oldWidth, oldHeight));
4622 if (!wDone && wChanged)
4623 d->implicitWidthChanged();
4624 if (!hDone && hChanged)
4625 d->implicitHeightChanged();
4629 Returns whether the height property has been set explicitly.
4631 bool QQuickItem::heightValid() const
4633 Q_D(const QQuickItem);
4634 return d->heightValid;
4637 void QQuickItem::setSize(const QSizeF &size)
4640 d->heightValid = true;
4641 d->widthValid = true;
4643 if (QSizeF(d->width, d->height) == size)
4646 qreal oldHeight = d->height;
4647 qreal oldWidth = d->width;
4648 d->height = size.height();
4649 d->width = size.width();
4651 d->dirty(QQuickItemPrivate::Size);
4653 geometryChanged(QRectF(x(), y(), width(), height()),
4654 QRectF(x(), y(), oldWidth, oldHeight));
4657 bool QQuickItem::hasActiveFocus() const
4659 Q_D(const QQuickItem);
4660 return d->activeFocus;
4663 bool QQuickItem::hasFocus() const
4665 Q_D(const QQuickItem);
4669 void QQuickItem::setFocus(bool focus)
4672 if (d->focus == focus)
4676 // Need to find our nearest focus scope
4677 QQuickItem *scope = parentItem();
4678 while (scope && !scope->isFocusScope())
4679 scope = scope->parentItem();
4681 QQuickCanvasPrivate::get(d->canvas)->setFocusInScope(scope, this);
4683 QQuickCanvasPrivate::get(d->canvas)->clearFocusInScope(scope, this);
4686 emit focusChanged(focus);
4690 bool QQuickItem::isFocusScope() const
4692 return flags() & ItemIsFocusScope;
4695 QQuickItem *QQuickItem::scopedFocusItem() const
4697 Q_D(const QQuickItem);
4698 if (!isFocusScope())
4701 return d->subFocusItem;
4705 Qt::MouseButtons QQuickItem::acceptedMouseButtons() const
4707 Q_D(const QQuickItem);
4708 return d->acceptedMouseButtons();
4711 void QQuickItem::setAcceptedMouseButtons(Qt::MouseButtons buttons)
4714 if (buttons & Qt::LeftButton)
4717 d->extra.clearFlag();
4719 buttons &= ~Qt::LeftButton;
4720 if (buttons || d->extra.isAllocated())
4721 d->extra.value().acceptedMouseButtons = buttons;
4724 bool QQuickItem::filtersChildMouseEvents() const
4726 Q_D(const QQuickItem);
4727 return d->filtersChildMouseEvents;
4730 void QQuickItem::setFiltersChildMouseEvents(bool filter)
4733 d->filtersChildMouseEvents = filter;
4736 bool QQuickItem::isUnderMouse() const
4738 Q_D(const QQuickItem);
4742 QPoint cursorPos = QCursor::pos();
4743 if (QRectF(0, 0, width(), height()).contains(mapFromScene(cursorPos))) // ### refactor: d->canvas->mapFromGlobal(cursorPos))))
4748 bool QQuickItem::acceptHoverEvents() const
4750 Q_D(const QQuickItem);
4751 return d->hoverEnabled;
4754 void QQuickItem::setAcceptHoverEvents(bool enabled)
4757 d->hoverEnabled = enabled;
4760 void QQuickItem::grabMouse()
4765 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
4766 if (canvasPriv->mouseGrabberItem == this)
4769 QQuickItem *oldGrabber = canvasPriv->mouseGrabberItem;
4770 canvasPriv->mouseGrabberItem = this;
4772 QEvent ev(QEvent::UngrabMouse);
4773 d->canvas->sendEvent(oldGrabber, &ev);
4777 void QQuickItem::ungrabMouse()
4782 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
4783 if (canvasPriv->mouseGrabberItem != this) {
4784 qWarning("QQuickItem::ungrabMouse(): Item is not the mouse grabber.");
4788 canvasPriv->mouseGrabberItem = 0;
4790 QEvent ev(QEvent::UngrabMouse);
4791 d->canvas->sendEvent(this, &ev);
4794 bool QQuickItem::keepMouseGrab() const
4796 Q_D(const QQuickItem);
4797 return d->keepMouse;
4801 The flag indicating whether the mouse should remain
4802 with this item is set to \a keep.
4804 This is useful for items that wish to grab and keep mouse
4805 interaction following a predefined gesture. For example,
4806 an item that is interested in horizontal mouse movement
4807 may set keepMouseGrab to true once a threshold has been
4808 exceeded. Once keepMouseGrab has been set to true, filtering
4809 items will not react to mouse events.
4811 If the item does not indicate that it wishes to retain mouse grab,
4812 a filtering item may steal the grab. For example, Flickable may attempt
4813 to steal a mouse grab if it detects that the user has begun to
4818 void QQuickItem::setKeepMouseGrab(bool keep)
4821 d->keepMouse = keep;
4825 Grabs the touch points specified by \a ids.
4827 These touch points will be owned by the item until
4828 they are released. Alternatively, the grab can be stolen
4829 by a filtering item like Flickable. Use setKeepTouchGrab()
4830 to prevent the grab from being stolen.
4832 \sa ungrabTouchPoints(), setKeepTouchGrab()
4834 void QQuickItem::grabTouchPoints(const QList<int> &ids)
4839 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
4841 QSet<QQuickItem*> ungrab;
4842 for (int i = 0; i < ids.count(); ++i) {
4843 QQuickItem *oldGrabber = canvasPriv->itemForTouchPointId.value(ids.at(i));
4844 if (oldGrabber == this)
4847 canvasPriv->itemForTouchPointId[ids.at(i)] = this;
4849 ungrab.insert(oldGrabber);
4851 foreach (QQuickItem *oldGrabber, ungrab)
4852 oldGrabber->touchUngrabEvent();
4856 Ungrabs the touch points owned by this item.
4858 \sa grabTouchPoints()
4860 void QQuickItem::ungrabTouchPoints()
4865 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
4867 QMutableHashIterator<int, QQuickItem*> i(canvasPriv->itemForTouchPointId);
4868 while (i.hasNext()) {
4870 if (i.value() == this)
4877 Returns a value indicating whether the touch points grabbed by this item
4878 should remain with this item exclusively.
4880 \sa setKeepTouchGrab(), keepMouseGrab()
4882 bool QQuickItem::keepTouchGrab() const
4884 Q_D(const QQuickItem);
4885 return d->keepTouch;
4889 The flag indicating whether the touch points grabbed
4890 by this item should remain with this item is set to \a keep.
4892 This is useful for items that wish to grab and keep specific touch
4893 points following a predefined gesture. For example,
4894 an item that is interested in horizontal touch point movement
4895 may set setKeepTouchGrab to true once a threshold has been
4896 exceeded. Once setKeepTouchGrab has been set to true, filtering
4897 items will not react to the relevant touch points.
4899 If the item does not indicate that it wishes to retain touch point grab,
4900 a filtering item may steal the grab. For example, Flickable may attempt
4901 to steal a touch point grab if it detects that the user has begun to
4904 \sa keepTouchGrab(), setKeepMouseGrab()
4906 void QQuickItem::setKeepTouchGrab(bool keep)
4909 d->keepTouch = keep;
4913 \qmlmethod object QtQuick2::Item::mapFromItem(Item item, real x, real y)
4915 Maps the point (\a x, \a y), which is in \a item's coordinate system, to
4916 this item's coordinate system, and returns an object with \c x and \c y
4917 properties matching the mapped coordinate.
4919 If \a item is a \c null value, this maps the point from the coordinate
4920 system of the root QML view.
4923 \qmlmethod object QtQuick2::Item::mapToItem(Item item, real x, real y)
4925 Maps the point (\a x, \a y), which is in this item's coordinate system, to
4926 \a item's coordinate system, and returns an object with \c x and \c y
4927 properties matching the mapped coordinate.
4929 If \a item is a \c null value, this maps \a x and \a y to the coordinate
4930 system of the root QML view.
4932 QPointF QQuickItem::mapToItem(const QQuickItem *item, const QPointF &point) const
4934 QPointF p = mapToScene(point);
4936 p = item->mapFromScene(p);
4940 QPointF QQuickItem::mapToScene(const QPointF &point) const
4942 Q_D(const QQuickItem);
4943 return d->itemToCanvasTransform().map(point);
4946 QRectF QQuickItem::mapRectToItem(const QQuickItem *item, const QRectF &rect) const
4948 Q_D(const QQuickItem);
4949 QTransform t = d->itemToCanvasTransform();
4951 t *= QQuickItemPrivate::get(item)->canvasToItemTransform();
4952 return t.mapRect(rect);
4955 QRectF QQuickItem::mapRectToScene(const QRectF &rect) const
4957 Q_D(const QQuickItem);
4958 return d->itemToCanvasTransform().mapRect(rect);
4961 QPointF QQuickItem::mapFromItem(const QQuickItem *item, const QPointF &point) const
4963 QPointF p = item?item->mapToScene(point):point;
4964 return mapFromScene(p);
4967 QPointF QQuickItem::mapFromScene(const QPointF &point) const
4969 Q_D(const QQuickItem);
4970 return d->canvasToItemTransform().map(point);
4973 QRectF QQuickItem::mapRectFromItem(const QQuickItem *item, const QRectF &rect) const
4975 Q_D(const QQuickItem);
4976 QTransform t = item?QQuickItemPrivate::get(item)->itemToCanvasTransform():QTransform();
4977 t *= d->canvasToItemTransform();
4978 return t.mapRect(rect);
4981 QRectF QQuickItem::mapRectFromScene(const QRectF &rect) const
4983 Q_D(const QQuickItem);
4984 return d->canvasToItemTransform().mapRect(rect);
4989 \qmlmethod QtQuick2::Item::forceActiveFocus()
4991 Forces active focus on the item.
4993 This method sets focus on the item and makes sure that all the focus scopes
4994 higher in the object hierarchy are also given the focus.
4998 Forces active focus on the item.
5000 This method sets focus on the item and makes sure that all the focus scopes
5001 higher in the object hierarchy are also given the focus.
5005 \qmlmethod QtQuick2::Item::childAt(real x, real y)
5007 Returns the visible child item at point (\a x, \a y), which is in this
5008 item's coordinate system, or \c null if there is no such item.
5012 Returns the visible child item at point (\a x, \a y), which is in this
5013 item's coordinate system, or 0 if there is no such item.
5017 \qmlproperty list<State> QtQuick2::Item::states
5018 This property holds a list of states defined by the item.
5034 \sa {qmlstate}{States}
5037 \qmlproperty list<Transition> QtQuick2::Item::transitions
5038 This property holds a list of transitions defined by the item.
5054 \sa {QML Animation and Transitions}{Transitions}
5057 \qmlproperty list<Filter> QtQuick2::Item::filter
5058 This property holds a list of graphical filters to be applied to the item.
5060 \l {Filter}{Filters} include things like \l {Blur}{blurring}
5061 the item, or giving it a \l Reflection. Some
5062 filters may not be available on all canvases; if a filter is not
5063 available on a certain canvas, it will simply not be applied for
5064 that canvas (but the QML will still be considered valid).
5082 \qmlproperty bool QtQuick2::Item::clip
5083 This property holds whether clipping is enabled. The default clip value is \c false.
5085 If clipping is enabled, an item will clip its own painting, as well
5086 as the painting of its children, to its bounding rectangle.
5088 Non-rectangular clipping regions are not supported for performance reasons.
5092 \property QQuickItem::clip
5093 This property holds whether clipping is enabled. The default clip value is \c false.
5095 If clipping is enabled, an item will clip its own painting, as well
5096 as the painting of its children, to its bounding rectangle. If you set
5097 clipping during an item's paint operation, remember to re-set it to
5098 prevent clipping the rest of your scene.
5100 Non-rectangular clipping regions are not supported for performance reasons.
5104 \qmlproperty string QtQuick2::Item::state
5106 This property holds the name of the current state of the item.
5108 This property is often used in scripts to change between states. For
5113 if (button.state == 'On')
5114 button.state = 'Off';
5116 button.state = 'On';
5120 If the item is in its base state (i.e. no explicit state has been
5121 set), \c state will be a blank string. Likewise, you can return an
5122 item to its base state by setting its current state to \c ''.
5124 \sa {qmlstates}{States}
5128 \qmlproperty list<Transform> QtQuick2::Item::transform
5129 This property holds the list of transformations to apply.
5131 For more information see \l Transform.
5135 \enum QQuickItem::TransformOrigin
5137 Controls the point about which simple transforms like scale apply.
5139 \value TopLeft The top-left corner of the item.
5140 \value Top The center point of the top of the item.
5141 \value TopRight The top-right corner of the item.
5142 \value Left The left most point of the vertical middle.
5143 \value Center The center of the item.
5144 \value Right The right most point of the vertical middle.
5145 \value BottomLeft The bottom-left corner of the item.
5146 \value Bottom The center point of the bottom of the item.
5147 \value BottomRight The bottom-right corner of the item.
5152 \qmlproperty bool QtQuick2::Item::activeFocus
5154 This property indicates whether the item has active focus.
5156 An item with active focus will receive keyboard input,
5157 or is a FocusScope ancestor of the item that will receive keyboard input.
5159 Usually, activeFocus is gained by setting focus on an item and its enclosing
5160 FocusScopes. In the following example \c input will have activeFocus.
5173 \sa focus, {qmlfocus}{Keyboard Focus}
5177 \qmlproperty bool QtQuick2::Item::focus
5178 This property indicates whether the item has focus within the enclosing focus scope. If true, this item
5179 will gain active focus when the enclosing focus scope gains active focus.
5180 In the following example, \c input will be given active focus when \c scope gains active focus.
5193 For the purposes of this property, the scene as a whole is assumed to act like a focus scope.
5194 On a practical level, that means the following QML will give active focus to \c input on startup.
5205 \sa activeFocus, {qmlfocus}{Keyboard Focus}
5210 \property QQuickItem::anchors
5215 \property QQuickItem::left
5220 \property QQuickItem::right
5225 \property QQuickItem::horizontalCenter
5230 \property QQuickItem::top
5235 \property QQuickItem::bottom
5240 \property QQuickItem::verticalCenter
5245 \property QQuickItem::focus
5250 \property QQuickItem::transform
5255 \property QQuickItem::transformOrigin
5260 \property QQuickItem::activeFocus
5265 \property QQuickItem::baseline
5270 \property QQuickItem::data
5275 \property QQuickItem::resources
5280 \property QQuickItem::state
5285 \property QQuickItem::states
5290 \property QQuickItem::transformOriginPoint
5295 \property QQuickItem::transitions
5299 bool QQuickItem::event(QEvent *ev)
5302 if (ev->type() == QEvent::PolishRequest) {
5304 d->polishScheduled = false;
5308 return QObject::event(ev);
5311 if (ev->type() == QEvent::InputMethodQuery) {
5312 QInputMethodQueryEvent *query = static_cast<QInputMethodQueryEvent *>(ev);
5313 Qt::InputMethodQueries queries = query->queries();
5314 for (uint i = 0; i < 32; ++i) {
5315 Qt::InputMethodQuery q = (Qt::InputMethodQuery)(int)(queries & (1<<i));
5317 QVariant v = inputMethodQuery(q);
5318 query->setValue(q, v);
5323 } else if (ev->type() == QEvent::InputMethod) {
5324 inputMethodEvent(static_cast<QInputMethodEvent *>(ev));
5327 return QObject::event(ev);
5330 #ifndef QT_NO_DEBUG_STREAM
5331 QDebug operator<<(QDebug debug, QQuickItem *item)
5334 debug << "QQuickItem(0)";
5338 debug << item->metaObject()->className() << "(this =" << ((void*)item)
5339 << ", name=" << item->objectName()
5340 << ", parent =" << ((void*)item->parentItem())
5341 << ", geometry =" << QRectF(item->pos(), QSizeF(item->width(), item->height()))
5342 << ", z =" << item->z() << ')';
5347 qint64 QQuickItemPrivate::consistentTime = -1;
5348 void QQuickItemPrivate::setConsistentTime(qint64 t)
5353 class QElapsedTimerConsistentTimeHack
5357 t1 = QQuickItemPrivate::consistentTime;
5361 return QQuickItemPrivate::consistentTime - t1;
5364 qint64 val = QQuickItemPrivate::consistentTime - t1;
5365 t1 = QQuickItemPrivate::consistentTime;
5375 void QQuickItemPrivate::start(QElapsedTimer &t)
5377 if (QQuickItemPrivate::consistentTime == -1)
5380 ((QElapsedTimerConsistentTimeHack*)&t)->start();
5383 qint64 QQuickItemPrivate::elapsed(QElapsedTimer &t)
5385 if (QQuickItemPrivate::consistentTime == -1)
5388 return ((QElapsedTimerConsistentTimeHack*)&t)->elapsed();
5391 qint64 QQuickItemPrivate::restart(QElapsedTimer &t)
5393 if (QQuickItemPrivate::consistentTime == -1)
5396 return ((QElapsedTimerConsistentTimeHack*)&t)->restart();
5400 \fn bool QQuickItem::isTextureProvider() const
5402 Returns true if this item is a texture provider. The default
5403 implementation returns false.
5405 This function can be called from any thread.
5408 bool QQuickItem::isTextureProvider() const
5410 Q_D(const QQuickItem);
5411 return d->extra.isAllocated() && d->extra->layer && d->extra->layer->effectSource() ?
5412 d->extra->layer->effectSource()->isTextureProvider() : false;
5416 \fn QSGTextureProvider *QQuickItem::textureProvider() const
5418 Returns the texture provider for an item. The default implementation
5421 This function may only be called on the rendering thread.
5424 QSGTextureProvider *QQuickItem::textureProvider() const
5426 Q_D(const QQuickItem);
5427 return d->extra.isAllocated() && d->extra->layer && d->extra->layer->effectSource() ?
5428 d->extra->layer->effectSource()->textureProvider() : 0;
5431 QQuickItemLayer *QQuickItemPrivate::layer() const
5433 if (!extra.isAllocated() || !extra->layer) {
5434 extra.value().layer = new QQuickItemLayer(const_cast<QQuickItem *>(q_func()));
5435 if (!componentComplete)
5436 extra->layer->classBegin();
5438 return extra->layer;
5441 QQuickItemLayer::QQuickItemLayer(QQuickItem *item)
5446 , m_componentComplete(true)
5447 , m_wrapMode(QQuickShaderEffectSource::ClampToEdge)
5448 , m_format(QQuickShaderEffectSource::RGBA)
5450 , m_effectComponent(0)
5456 QQuickItemLayer::~QQuickItemLayer()
5458 delete m_effectSource;
5465 \qmlproperty bool QtQuick2::Item::layer.enabled
5467 Holds wether the item is layered or not. Layering is disabled by default.
5469 A layered item is rendered into an offscreen surface and cached until
5470 it is changed. Enabling layering for complex QML item hierarchies can
5471 some times be an optimization.
5473 None of the other layer properties have any effect when the layer
5477 void QQuickItemLayer::setEnabled(bool e)
5482 if (m_componentComplete) {
5489 emit enabledChanged(e);
5492 void QQuickItemLayer::classBegin()
5494 Q_ASSERT(!m_effectSource);
5495 Q_ASSERT(!m_effect);
5496 m_componentComplete = false;
5499 void QQuickItemLayer::componentComplete()
5501 Q_ASSERT(!m_componentComplete);
5502 m_componentComplete = true;
5507 void QQuickItemLayer::activate()
5509 Q_ASSERT(!m_effectSource);
5510 m_effectSource = new QQuickShaderEffectSource();
5512 QQuickItem *parentItem = m_item->parentItem();
5514 m_effectSource->setParentItem(parentItem);
5515 m_effectSource->stackAfter(m_item);
5518 m_effectSource->setSourceItem(m_item);
5519 m_effectSource->setHideSource(true);
5520 m_effectSource->setSmooth(m_smooth);
5521 m_effectSource->setTextureSize(m_size);
5522 m_effectSource->setSourceRect(m_sourceRect);
5523 m_effectSource->setMipmap(m_mipmap);
5524 m_effectSource->setWrapMode(m_wrapMode);
5525 m_effectSource->setFormat(m_format);
5527 if (m_effectComponent)
5530 m_effectSource->setVisible(m_item->isVisible() && !m_effect);
5537 QQuickItemPrivate *id = QQuickItemPrivate::get(m_item);
5538 id->addItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Opacity | QQuickItemPrivate::Parent | QQuickItemPrivate::Visibility | QQuickItemPrivate::SiblingOrder);
5541 void QQuickItemLayer::deactivate()
5543 Q_ASSERT(m_effectSource);
5545 if (m_effectComponent)
5548 delete m_effectSource;
5551 QQuickItemPrivate *id = QQuickItemPrivate::get(m_item);
5552 id->removeItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Opacity | QQuickItemPrivate::Parent | QQuickItemPrivate::Visibility | QQuickItemPrivate::SiblingOrder);
5555 void QQuickItemLayer::activateEffect()
5557 Q_ASSERT(m_effectSource);
5558 Q_ASSERT(m_effectComponent);
5559 Q_ASSERT(!m_effect);
5561 QObject *created = m_effectComponent->create();
5562 m_effect = qobject_cast<QQuickItem *>(created);
5564 qWarning("Item: layer.effect is not a QML Item.");
5568 QQuickItem *parentItem = m_item->parentItem();
5570 m_effect->setParentItem(parentItem);
5571 m_effect->stackAfter(m_effectSource);
5573 m_effect->setVisible(m_item->isVisible());
5574 m_effect->setProperty(m_name, qVariantFromValue<QObject *>(m_effectSource));
5577 void QQuickItemLayer::deactivateEffect()
5579 Q_ASSERT(m_effectSource);
5580 Q_ASSERT(m_effectComponent);
5588 \qmlproperty Component QtQuick2::Item::layer.effect
5590 Holds the effect that is applied to this layer.
5592 The effect is typically a \l ShaderEffect component, although any \l Item component can be
5593 assigned. The effect should have a source texture property with a name matching \l samplerName.
5598 void QQuickItemLayer::setEffect(QQmlComponent *component)
5600 if (component == m_effectComponent)
5603 bool updateNeeded = false;
5604 if (m_effectSource && m_effectComponent) {
5606 updateNeeded = true;
5609 m_effectComponent = component;
5611 if (m_effectSource && m_effectComponent) {
5613 updateNeeded = true;
5621 m_effectSource->setVisible(m_item->isVisible() && !m_effect);
5624 emit effectChanged(component);
5629 \qmlproperty bool QtQuick2::Item::layer.mipmap
5631 If this property is true, mipmaps are generated for the texture.
5633 \note Some OpenGL ES 2 implementations do not support mipmapping of
5634 non-power-of-two textures.
5637 void QQuickItemLayer::setMipmap(bool mipmap)
5639 if (mipmap == m_mipmap)
5644 m_effectSource->setMipmap(m_mipmap);
5646 emit mipmapChanged(mipmap);
5651 \qmlproperty enumeration QtQuick2::Item::layer.format
5653 This property defines the internal OpenGL format of the texture.
5654 Modifying this property makes most sense when the \a layer.effect is also
5655 specified. Depending on the OpenGL implementation, this property might
5656 allow you to save some texture memory.
5659 \li ShaderEffectSource.Alpha - GL_ALPHA
5660 \li ShaderEffectSource.RGB - GL_RGB
5661 \li ShaderEffectSource.RGBA - GL_RGBA
5664 \note Some OpenGL implementations do not support the GL_ALPHA format.
5667 void QQuickItemLayer::setFormat(QQuickShaderEffectSource::Format f)
5674 m_effectSource->setFormat(m_format);
5676 emit formatChanged(m_format);
5681 \qmlproperty enumeration QtQuick2::Item::layer.sourceRect
5683 This property defines which rectangular area of the \l sourceItem to
5684 render into the texture. The source rectangle can be larger than
5685 \l sourceItem itself. If the rectangle is null, which is the default,
5686 the whole \l sourceItem is rendered to texture.
5689 void QQuickItemLayer::setSourceRect(const QRectF &sourceRect)
5691 if (sourceRect == m_sourceRect)
5693 m_sourceRect = sourceRect;
5696 m_effectSource->setSourceRect(m_sourceRect);
5698 emit sourceRectChanged(sourceRect);
5704 \qmlproperty bool QtQuick2::Item::layer.smooth
5706 Holds whether the layer is smoothly transformed.
5709 void QQuickItemLayer::setSmooth(bool s)
5716 m_effectSource->setSmooth(m_smooth);
5718 emit smoothChanged(s);
5724 \qmlproperty size QtQuick2::Item::layer.textureSize
5726 This property holds the requested pixel size of the layers texture. If it is empty,
5727 which is the default, the size of the item is used.
5729 \note Some platforms have a limit on how small framebuffer objects can be,
5730 which means the actual texture size might be larger than the requested
5734 void QQuickItemLayer::setSize(const QSize &size)
5741 m_effectSource->setTextureSize(size);
5743 emit sizeChanged(size);
5749 \qmlproperty enumeration QtQuick2::Item::layer.wrapMode
5751 This property defines the OpenGL wrap modes associated with the texture.
5752 Modifying this property makes most sense when the \a layer.effect is
5756 \li ShaderEffectSource.ClampToEdge - GL_CLAMP_TO_EDGE both horizontally and vertically
5757 \li ShaderEffectSource.RepeatHorizontally - GL_REPEAT horizontally, GL_CLAMP_TO_EDGE vertically
5758 \li ShaderEffectSource.RepeatVertically - GL_CLAMP_TO_EDGE horizontally, GL_REPEAT vertically
5759 \li ShaderEffectSource.Repeat - GL_REPEAT both horizontally and vertically
5762 \note Some OpenGL ES 2 implementations do not support the GL_REPEAT
5763 wrap mode with non-power-of-two textures.
5766 void QQuickItemLayer::setWrapMode(QQuickShaderEffectSource::WrapMode mode)
5768 if (mode == m_wrapMode)
5773 m_effectSource->setWrapMode(m_wrapMode);
5775 emit wrapModeChanged(mode);
5779 \qmlproperty string QtQuick2::Item::layer.samplerName
5781 Holds the name of the effect's source texture property.
5783 samplerName needs to match the name of the effect's source texture property
5784 so that the Item can pass the layer's offscreen surface to the effect correctly.
5786 \sa effect, ShaderEffect
5789 void QQuickItemLayer::setName(const QByteArray &name) {
5793 m_effect->setProperty(m_name, QVariant());
5794 m_effect->setProperty(name, qVariantFromValue<QObject *>(m_effectSource));
5797 emit nameChanged(name);
5800 void QQuickItemLayer::itemOpacityChanged(QQuickItem *item)
5806 void QQuickItemLayer::itemGeometryChanged(QQuickItem *, const QRectF &, const QRectF &)
5811 void QQuickItemLayer::itemParentChanged(QQuickItem *item, QQuickItem *parent)
5814 Q_ASSERT(item == m_item);
5815 Q_ASSERT(parent != m_effectSource);
5816 Q_ASSERT(parent == 0 || parent != m_effect);
5818 m_effectSource->setParentItem(parent);
5820 m_effectSource->stackAfter(m_item);
5823 m_effect->setParentItem(parent);
5825 m_effect->stackAfter(m_effectSource);
5829 void QQuickItemLayer::itemSiblingOrderChanged(QQuickItem *)
5831 m_effectSource->stackAfter(m_item);
5833 m_effect->stackAfter(m_effectSource);
5836 void QQuickItemLayer::itemVisibilityChanged(QQuickItem *)
5838 QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
5840 l->setVisible(m_item->isVisible());
5843 void QQuickItemLayer::updateZ()
5845 if (!m_componentComplete || !m_enabled)
5847 QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
5849 l->setZ(m_item->z());
5852 void QQuickItemLayer::updateOpacity()
5854 QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
5856 l->setOpacity(m_item->opacity());
5859 void QQuickItemLayer::updateGeometry()
5861 QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
5863 QRectF bounds = m_item->boundingRect();
5864 l->setWidth(bounds.width());
5865 l->setHeight(bounds.height());
5866 l->setX(bounds.x() + m_item->x());
5867 l->setY(bounds.y() + m_item->y());
5870 void QQuickItemLayer::updateMatrix()
5872 // Called directly from transformChanged(), so needs some extra
5874 if (!m_componentComplete || !m_enabled)
5876 QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
5878 QQuickItemPrivate *ld = QQuickItemPrivate::get(l);
5879 l->setScale(m_item->scale());
5880 l->setRotation(m_item->rotation());
5881 ld->transforms = QQuickItemPrivate::get(m_item)->transforms;
5882 if (ld->origin() != QQuickItemPrivate::get(m_item)->origin())
5883 ld->extra.value().origin = QQuickItemPrivate::get(m_item)->origin();
5884 ld->dirty(QQuickItemPrivate::Transform);
5887 QQuickItemPrivate::ExtraData::ExtraData()
5888 : z(0), scale(1), rotation(0), opacity(1),
5889 contents(0), screenAttached(0), layoutDirectionAttached(0),
5890 keyHandler(0), layer(0), effectRefCount(0), hideRefCount(0),
5891 opacityNode(0), clipNode(0), rootNode(0), beforePaintNode(0),
5892 acceptedMouseButtons(0), origin(QQuickItem::Center)
5898 #include <moc_qquickitem.cpp>