1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the QtQml module of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #include "qquickitem.h"
44 #include "qquickcanvas.h"
45 #include <QtQml/qjsengine.h>
46 #include "qquickcanvas_p.h"
48 #include "qquickevents_p_p.h"
49 #include "qquickscreen_p.h"
51 #include <QtQml/qqmlengine.h>
52 #include <QtQml/qqmlcomponent.h>
53 #include <QtQml/qqmlinfo.h>
54 #include <QtGui/qpen.h>
55 #include <QtGui/qguiapplication.h>
56 #include <QtGui/private/qguiapplication_p.h>
57 #include <QtGui/qinputmethod.h>
58 #include <QtCore/qdebug.h>
59 #include <QtCore/qcoreevent.h>
60 #include <QtCore/qnumeric.h>
62 #include <private/qqmlglobal_p.h>
63 #include <private/qqmlengine_p.h>
64 #include <QtQuick/private/qquickstategroup_p.h>
65 #include <private/qqmlopenmetaobject_p.h>
66 #include <QtQuick/private/qquickstate_p.h>
67 #include <private/qlistmodelinterface_p.h>
68 #include <private/qquickitem_p.h>
69 #include <private/qqmlaccessors_p.h>
70 #include <QtQuick/private/qquickaccessibleattached_p.h>
74 // XXX todo Check that elements that create items handle memory correctly after visual ownership change
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 && 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 && 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.");
1827 if (d->canvasRefCount > 1)
1828 d->canvasRefCount = 1; // Make sure canvas is set to null in next call to derefCanvas().
1834 // XXX todo - optimize
1835 while (!d->childItems.isEmpty())
1836 d->childItems.first()->setParentItem(0);
1838 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
1839 QQuickAnchorsPrivate *anchor = d->changeListeners.at(ii).listener->anchorPrivate();
1841 anchor->clearItem(this);
1845 update item anchors that depended on us unless they are our child (and will also be destroyed),
1846 or our sibling, and our parent is also being destroyed.
1848 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
1849 QQuickAnchorsPrivate *anchor = d->changeListeners.at(ii).listener->anchorPrivate();
1850 if (anchor && anchor->item && anchor->item->parentItem() && anchor->item->parentItem() != this)
1854 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
1855 const QQuickItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
1856 if (change.types & QQuickItemPrivate::Destroyed)
1857 change.listener->itemDestroyed(this);
1860 d->changeListeners.clear();
1862 if (d->extra.isAllocated()) {
1863 delete d->extra->contents; d->extra->contents = 0;
1864 delete d->extra->layer; d->extra->layer = 0;
1867 delete d->_anchors; d->_anchors = 0;
1868 delete d->_stateGroup; d->_stateGroup = 0;
1872 \qmlproperty enumeration QtQuick2::Item::transformOrigin
1873 This property holds the origin point around which scale and rotation transform.
1875 Nine transform origins are available, as shown in the image below.
1877 \image declarative-transformorigin.png
1879 This example rotates an image around its bottom-right corner.
1882 source: "myimage.png"
1883 transformOrigin: Item.BottomRight
1888 The default transform origin is \c Item.Center.
1890 To set an arbitrary transform origin point use the \l Scale or \l Rotation
1895 \qmlproperty Item QtQuick2::Item::parent
1896 This property holds the parent of the item.
1900 \property QQuickItem::parent
1901 This property holds the parent of the item.
1903 void QQuickItem::setParentItem(QQuickItem *parentItem)
1906 if (parentItem == d->parentItem)
1910 QQuickItem *itemAncestor = parentItem->parentItem();
1911 while (itemAncestor != 0) {
1912 if (itemAncestor == this) {
1913 qWarning("QQuickItem::setParentItem: Parent is already part of this items subtree.");
1916 itemAncestor = itemAncestor->parentItem();
1920 d->removeFromDirtyList();
1922 QQuickItem *oldParentItem = d->parentItem;
1923 QQuickItem *scopeFocusedItem = 0;
1925 if (oldParentItem) {
1926 QQuickItemPrivate *op = QQuickItemPrivate::get(oldParentItem);
1928 QQuickItem *scopeItem = 0;
1931 scopeFocusedItem = this;
1932 else if (!isFocusScope() && d->subFocusItem)
1933 scopeFocusedItem = d->subFocusItem;
1935 if (scopeFocusedItem) {
1936 scopeItem = oldParentItem;
1937 while (!scopeItem->isFocusScope() && scopeItem->parentItem())
1938 scopeItem = scopeItem->parentItem();
1940 QQuickCanvasPrivate::get(d->canvas)->clearFocusInScope(scopeItem, scopeFocusedItem,
1941 QQuickCanvasPrivate::DontChangeFocusProperty);
1943 QQuickItemPrivate::get(scopeFocusedItem)->updateSubFocusItem(scopeItem, false);
1947 const bool wasVisible = isVisible();
1948 op->removeChild(this);
1950 emit oldParentItem->visibleChildrenChanged();
1952 } else if (d->canvas) {
1953 QQuickCanvasPrivate::get(d->canvas)->parentlessItems.remove(this);
1956 QQuickCanvas *oldParentCanvas = oldParentItem ? QQuickItemPrivate::get(oldParentItem)->canvas : 0;
1957 QQuickCanvas *parentCanvas = parentItem ? QQuickItemPrivate::get(parentItem)->canvas : 0;
1958 if (oldParentCanvas == parentCanvas) {
1959 // Avoid freeing and reallocating resources if the canvas stays the same.
1960 d->parentItem = parentItem;
1962 if (oldParentCanvas)
1964 d->parentItem = parentItem;
1966 d->refCanvas(parentCanvas);
1969 d->dirty(QQuickItemPrivate::ParentChanged);
1972 QQuickItemPrivate::get(d->parentItem)->addChild(this);
1974 QQuickCanvasPrivate::get(d->canvas)->parentlessItems.insert(this);
1976 d->setEffectiveVisibleRecur(d->calcEffectiveVisible());
1977 d->setEffectiveEnableRecur(0, d->calcEffectiveEnable());
1979 if (d->parentItem) {
1980 if (!scopeFocusedItem) {
1982 scopeFocusedItem = this;
1983 else if (!isFocusScope() && d->subFocusItem)
1984 scopeFocusedItem = d->subFocusItem;
1987 if (scopeFocusedItem) {
1988 // We need to test whether this item becomes scope focused
1989 QQuickItem *scopeItem = d->parentItem;
1990 while (!scopeItem->isFocusScope() && scopeItem->parentItem())
1991 scopeItem = scopeItem->parentItem();
1993 if (scopeItem->scopedFocusItem()) {
1994 QQuickItemPrivate::get(scopeFocusedItem)->focus = false;
1995 emit scopeFocusedItem->focusChanged(false);
1998 QQuickCanvasPrivate::get(d->canvas)->setFocusInScope(scopeItem, scopeFocusedItem,
1999 QQuickCanvasPrivate::DontChangeFocusProperty);
2001 QQuickItemPrivate::get(scopeFocusedItem)->updateSubFocusItem(scopeItem, true);
2007 d->resolveLayoutMirror();
2009 d->itemChange(ItemParentHasChanged, d->parentItem);
2011 d->parentNotifier.notify();
2012 if (d->isAccessible && d->parentItem) {
2013 d->parentItem->d_func()->setAccessibleFlagAndListener();
2016 emit parentChanged(d->parentItem);
2017 if (isVisible() && d->parentItem)
2018 emit d->parentItem->visibleChildrenChanged();
2021 void QQuickItem::stackBefore(const QQuickItem *sibling)
2024 if (!sibling || sibling == this || !d->parentItem || d->parentItem != QQuickItemPrivate::get(sibling)->parentItem) {
2025 qWarning("QQuickItem::stackBefore: Cannot stack before %p, which must be a sibling", sibling);
2029 QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(d->parentItem);
2031 int myIndex = parentPrivate->childItems.indexOf(this);
2032 int siblingIndex = parentPrivate->childItems.indexOf(const_cast<QQuickItem *>(sibling));
2034 Q_ASSERT(myIndex != -1 && siblingIndex != -1);
2036 if (myIndex == siblingIndex - 1)
2039 parentPrivate->childItems.removeAt(myIndex);
2041 if (myIndex < siblingIndex) --siblingIndex;
2043 parentPrivate->childItems.insert(siblingIndex, this);
2045 parentPrivate->dirty(QQuickItemPrivate::ChildrenStackingChanged);
2046 parentPrivate->markSortedChildrenDirty(this);
2048 for (int ii = qMin(siblingIndex, myIndex); ii < parentPrivate->childItems.count(); ++ii)
2049 QQuickItemPrivate::get(parentPrivate->childItems.at(ii))->siblingOrderChanged();
2052 void QQuickItem::stackAfter(const QQuickItem *sibling)
2055 if (!sibling || sibling == this || !d->parentItem || d->parentItem != QQuickItemPrivate::get(sibling)->parentItem) {
2056 qWarning("QQuickItem::stackAfter: Cannot stack after %p, which must be a sibling", sibling);
2060 QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(d->parentItem);
2062 int myIndex = parentPrivate->childItems.indexOf(this);
2063 int siblingIndex = parentPrivate->childItems.indexOf(const_cast<QQuickItem *>(sibling));
2065 Q_ASSERT(myIndex != -1 && siblingIndex != -1);
2067 if (myIndex == siblingIndex + 1)
2070 parentPrivate->childItems.removeAt(myIndex);
2072 if (myIndex < siblingIndex) --siblingIndex;
2074 parentPrivate->childItems.insert(siblingIndex + 1, this);
2076 parentPrivate->dirty(QQuickItemPrivate::ChildrenStackingChanged);
2077 parentPrivate->markSortedChildrenDirty(this);
2079 for (int ii = qMin(myIndex, siblingIndex + 1); ii < parentPrivate->childItems.count(); ++ii)
2080 QQuickItemPrivate::get(parentPrivate->childItems.at(ii))->siblingOrderChanged();
2084 Returns the QQuickItem parent of this item.
2086 QQuickItem *QQuickItem::parentItem() const
2088 Q_D(const QQuickItem);
2089 return d->parentItem;
2092 QSGEngine *QQuickItem::sceneGraphEngine() const
2094 return canvas()->sceneGraphEngine();
2097 QQuickCanvas *QQuickItem::canvas() const
2099 Q_D(const QQuickItem);
2103 static bool itemZOrder_sort(QQuickItem *lhs, QQuickItem *rhs)
2105 return lhs->z() < rhs->z();
2108 QList<QQuickItem *> QQuickItemPrivate::paintOrderChildItems() const
2110 if (sortedChildItems)
2111 return *sortedChildItems;
2113 // If none of the items have set Z then the paint order list is the same as
2114 // the childItems list. This is by far the most common case.
2116 for (int i = 0; i < childItems.count(); ++i) {
2117 if (QQuickItemPrivate::get(childItems.at(i))->z() != 0.) {
2123 sortedChildItems = new QList<QQuickItem*>(childItems);
2124 qStableSort(sortedChildItems->begin(), sortedChildItems->end(), itemZOrder_sort);
2125 return *sortedChildItems;
2128 sortedChildItems = const_cast<QList<QQuickItem*>*>(&childItems);
2133 void QQuickItemPrivate::addChild(QQuickItem *child)
2137 Q_ASSERT(!childItems.contains(child));
2139 childItems.append(child);
2141 markSortedChildrenDirty(child);
2142 dirty(QQuickItemPrivate::ChildrenChanged);
2144 itemChange(QQuickItem::ItemChildAddedChange, child);
2146 emit q->childrenChanged();
2149 void QQuickItemPrivate::removeChild(QQuickItem *child)
2154 Q_ASSERT(childItems.contains(child));
2155 childItems.removeOne(child);
2156 Q_ASSERT(!childItems.contains(child));
2158 markSortedChildrenDirty(child);
2159 dirty(QQuickItemPrivate::ChildrenChanged);
2161 itemChange(QQuickItem::ItemChildRemovedChange, child);
2163 emit q->childrenChanged();
2166 void QQuickItemPrivate::InitializationState::clear()
2171 void QQuickItemPrivate::InitializationState::clear(QQuickItem *fs)
2176 QQuickItem *QQuickItemPrivate::InitializationState::getFocusScope(QQuickItem *item)
2179 QQuickItem *fs = item->parentItem();
2180 while (fs->parentItem() && !fs->isFocusScope())
2181 fs = fs->parentItem();
2187 void QQuickItemPrivate::refCanvas(InitializationState *state, QQuickCanvas *c)
2189 // An item needs a canvas if it is referenced by another item which has a canvas.
2190 // Typically the item is referenced by a parent, but can also be referenced by a
2191 // ShaderEffect or ShaderEffectSource. 'canvasRefCount' counts how many items with
2192 // a canvas is referencing this item. When the reference count goes from zero to one,
2193 // or one to zero, the canvas of this item is updated and propagated to the children.
2194 // As long as the reference count stays above zero, the canvas is unchanged.
2195 // refCanvas() increments the reference count.
2196 // derefCanvas() decrements the reference count.
2199 Q_ASSERT((canvas != 0) == (canvasRefCount > 0));
2201 if (++canvasRefCount > 1) {
2203 qWarning("QQuickItem: Cannot use same item on different canvases at the same time.");
2204 return; // Canvas already set.
2207 Q_ASSERT(canvas == 0);
2210 if (polishScheduled)
2211 QQuickCanvasPrivate::get(canvas)->itemsToPolish.insert(q);
2213 InitializationState _dummy;
2214 InitializationState *childState = state;
2216 if (q->isFocusScope()) {
2218 childState = &_dummy;
2222 QQuickCanvasPrivate::get(canvas)->parentlessItems.insert(q);
2224 for (int ii = 0; ii < childItems.count(); ++ii) {
2225 QQuickItem *child = childItems.at(ii);
2226 QQuickItemPrivate::get(child)->refCanvas(childState, c);
2231 if (extra.isAllocated() && extra->screenAttached)
2232 extra->screenAttached->canvasChanged(c);
2233 itemChange(QQuickItem::ItemSceneChange, c);
2236 void QQuickItemPrivate::derefCanvas()
2239 Q_ASSERT((canvas != 0) == (canvasRefCount > 0));
2242 return; // This can happen when destroying recursive shader effect sources.
2244 if (--canvasRefCount > 0)
2245 return; // There are still other references, so don't set canvas to null yet.
2247 q->releaseResources();
2248 removeFromDirtyList();
2249 QQuickCanvasPrivate *c = QQuickCanvasPrivate::get(canvas);
2250 if (polishScheduled)
2251 c->itemsToPolish.remove(q);
2252 if (c->mouseGrabberItem == q)
2253 c->mouseGrabberItem = 0;
2255 c->hoverItems.removeAll(q);
2256 if (itemNodeInstance)
2257 c->cleanup(itemNodeInstance);
2259 c->parentlessItems.remove(q);
2263 itemNodeInstance = 0;
2265 if (extra.isAllocated()) {
2266 extra->opacityNode = 0;
2267 extra->clipNode = 0;
2268 extra->rootNode = 0;
2269 extra->beforePaintNode = 0;
2275 for (int ii = 0; ii < childItems.count(); ++ii) {
2276 QQuickItem *child = childItems.at(ii);
2277 QQuickItemPrivate::get(child)->derefCanvas();
2282 if (extra.isAllocated() && extra->screenAttached)
2283 extra->screenAttached->canvasChanged(0);
2284 itemChange(QQuickItem::ItemSceneChange, (QQuickCanvas *)0);
2289 Returns a transform that maps points from canvas space into item space.
2291 QTransform QQuickItemPrivate::canvasToItemTransform() const
2293 // XXX todo - optimize
2294 return itemToCanvasTransform().inverted();
2298 Returns a transform that maps points from item space into canvas space.
2300 QTransform QQuickItemPrivate::itemToCanvasTransform() const
2303 QTransform rv = parentItem?QQuickItemPrivate::get(parentItem)->itemToCanvasTransform():QTransform();
2304 itemToParentTransform(rv);
2309 Motifies \a t with this items local transform relative to its parent.
2311 void QQuickItemPrivate::itemToParentTransform(QTransform &t) const
2316 if (!transforms.isEmpty()) {
2318 for (int ii = transforms.count() - 1; ii >= 0; --ii)
2319 transforms.at(ii)->applyTo(&m);
2320 t = m.toTransform();
2323 if (scale() != 1. || rotation() != 0.) {
2324 QPointF tp = computeTransformOrigin();
2325 t.translate(tp.x(), tp.y());
2326 t.scale(scale(), scale());
2327 t.rotate(rotation());
2328 t.translate(-tp.x(), -tp.y());
2334 \qmlproperty real QtQuick2::Item::childrenRect.x
2335 \qmlproperty real QtQuick2::Item::childrenRect.y
2336 \qmlproperty real QtQuick2::Item::childrenRect.width
2337 \qmlproperty real QtQuick2::Item::childrenRect.height
2339 The childrenRect properties allow an item access to the geometry of its
2340 children. This property is useful if you have an item that needs to be
2341 sized to fit its children.
2346 \qmlproperty list<Item> QtQuick2::Item::children
2347 \qmlproperty list<Object> QtQuick2::Item::resources
2349 The children property contains the list of visual children of this item.
2350 The resources property contains non-visual resources that you want to
2353 Generally you can rely on Item's default property to handle all this for
2354 you, but it can come in handy in some cases.
2373 Returns true if construction of the QML component is complete; otherwise
2376 It is often desirable to delay some processing until the component is
2379 \sa componentComplete()
2381 bool QQuickItem::isComponentComplete() const
2383 Q_D(const QQuickItem);
2384 return d->componentComplete;
2387 QQuickItemPrivate::QQuickItemPrivate()
2388 : _anchors(0), _stateGroup(0),
2389 flags(0), widthValid(false), heightValid(false), baselineOffsetValid(false), componentComplete(true),
2390 keepMouse(false), keepTouch(false), hoverEnabled(false), smooth(true), focus(false), activeFocus(false), notifiedFocus(false),
2391 notifiedActiveFocus(false), filtersChildMouseEvents(false), explicitVisible(true),
2392 effectiveVisible(true), explicitEnable(true), effectiveEnable(true), polishScheduled(false),
2393 inheritedLayoutMirror(false), effectiveLayoutMirror(false), isMirrorImplicit(true),
2394 inheritMirrorFromParent(false), inheritMirrorFromItem(false), childrenDoNotOverlap(false),
2395 staticSubtreeGeometry(false),
2396 isAccessible(false),
2398 dirtyAttributes(0), nextDirtyItem(0), prevDirtyItem(0),
2400 canvas(0), canvasRefCount(0), parentItem(0), sortedChildItems(&childItems),
2404 x(0), y(0), width(0), height(0), implicitWidth(0), implicitHeight(0),
2408 itemNodeInstance(0), groupNode(0), paintNode(0)
2412 QQuickItemPrivate::~QQuickItemPrivate()
2414 if (sortedChildItems != &childItems)
2415 delete sortedChildItems;
2418 void QQuickItemPrivate::init(QQuickItem *parent)
2422 static bool atexit_registered = false;
2423 if (!atexit_registered) {
2424 atexit(qt_print_item_count);
2425 atexit_registered = true;
2431 registerAccessorProperties();
2433 baselineOffsetValid = false;
2436 q->setParentItem(parent);
2437 QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(parent);
2438 setImplicitLayoutMirror(parentPrivate->inheritedLayoutMirror, parentPrivate->inheritMirrorFromParent);
2442 void QQuickItemPrivate::data_append(QQmlListProperty<QObject> *prop, QObject *o)
2447 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2449 // This test is measurably (albeit only slightly) faster than qobject_cast<>()
2450 const QMetaObject *mo = o->metaObject();
2451 while (mo && mo != &QQuickItem::staticMetaObject) {
2452 mo = mo->d.superdata;
2456 QQuickItem *item = static_cast<QQuickItem *>(o);
2457 item->setParentItem(that);
2459 if (o->inherits("QGraphicsItem"))
2460 qWarning("Cannot add a QtQuick 1.0 item (%s) into a QtQuick 2.0 scene!", o->metaObject()->className());
2462 // XXX todo - do we really want this behavior?
2468 \qmlproperty list<Object> QtQuick2::Item::data
2471 The data property allows you to freely mix visual children and resources
2472 in an item. If you assign a visual item to the data list it becomes
2473 a child and if you assign any other object type, it is added as a resource.
2497 data is a behind-the-scenes property: you should never need to explicitly
2501 int QQuickItemPrivate::data_count(QQmlListProperty<QObject> *prop)
2508 QObject *QQuickItemPrivate::data_at(QQmlListProperty<QObject> *prop, int i)
2516 void QQuickItemPrivate::data_clear(QQmlListProperty<QObject> *prop)
2522 QObject *QQuickItemPrivate::resources_at(QQmlListProperty<QObject> *prop, int index)
2524 const QObjectList children = prop->object->children();
2525 if (index < children.count())
2526 return children.at(index);
2531 void QQuickItemPrivate::resources_append(QQmlListProperty<QObject> *prop, QObject *o)
2533 // XXX todo - do we really want this behavior?
2534 o->setParent(prop->object);
2537 int QQuickItemPrivate::resources_count(QQmlListProperty<QObject> *prop)
2539 return prop->object->children().count();
2542 void QQuickItemPrivate::resources_clear(QQmlListProperty<QObject> *prop)
2544 // XXX todo - do we really want this behavior?
2545 const QObjectList children = prop->object->children();
2546 for (int index = 0; index < children.count(); index++)
2547 children.at(index)->setParent(0);
2550 QQuickItem *QQuickItemPrivate::children_at(QQmlListProperty<QQuickItem> *prop, int index)
2552 QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2553 if (index >= p->childItems.count() || index < 0)
2556 return p->childItems.at(index);
2559 void QQuickItemPrivate::children_append(QQmlListProperty<QQuickItem> *prop, QQuickItem *o)
2564 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2565 if (o->parentItem() == that)
2566 o->setParentItem(0);
2568 o->setParentItem(that);
2571 int QQuickItemPrivate::children_count(QQmlListProperty<QQuickItem> *prop)
2573 QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2574 return p->childItems.count();
2577 void QQuickItemPrivate::children_clear(QQmlListProperty<QQuickItem> *prop)
2579 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2580 QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2581 while (!p->childItems.isEmpty())
2582 p->childItems.at(0)->setParentItem(0);
2585 void QQuickItemPrivate::visibleChildren_append(QQmlListProperty<QQuickItem>*, QQuickItem *self)
2588 qmlInfo(self) << "QQuickItem: visibleChildren property is readonly and cannot be assigned to.";
2591 int QQuickItemPrivate::visibleChildren_count(QQmlListProperty<QQuickItem> *prop)
2593 QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2594 int visibleCount = 0;
2595 int c = p->childItems.count();
2597 if (p->childItems.at(c)->isVisible()) visibleCount++;
2600 return visibleCount;
2603 QQuickItem *QQuickItemPrivate::visibleChildren_at(QQmlListProperty<QQuickItem> *prop, int index)
2605 QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2606 const int childCount = p->childItems.count();
2607 if (index >= childCount || index < 0)
2610 int visibleCount = -1;
2611 for (int i = 0; i < childCount; i++) {
2612 if (p->childItems.at(i)->isVisible()) visibleCount++;
2613 if (visibleCount == index) return p->childItems.at(i);
2618 int QQuickItemPrivate::transform_count(QQmlListProperty<QQuickTransform> *prop)
2620 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2621 QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2623 return p->transforms.count();
2626 void QQuickTransform::appendToItem(QQuickItem *item)
2628 Q_D(QQuickTransform);
2632 QQuickItemPrivate *p = QQuickItemPrivate::get(item);
2634 if (!d->items.isEmpty() && !p->transforms.isEmpty() && p->transforms.contains(this)) {
2635 p->transforms.removeOne(this);
2636 p->transforms.append(this);
2638 p->transforms.append(this);
2639 d->items.append(item);
2642 p->dirty(QQuickItemPrivate::Transform);
2645 void QQuickTransform::prependToItem(QQuickItem *item)
2647 Q_D(QQuickTransform);
2651 QQuickItemPrivate *p = QQuickItemPrivate::get(item);
2653 if (!d->items.isEmpty() && !p->transforms.isEmpty() && p->transforms.contains(this)) {
2654 p->transforms.removeOne(this);
2655 p->transforms.prepend(this);
2657 p->transforms.prepend(this);
2658 d->items.append(item);
2661 p->dirty(QQuickItemPrivate::Transform);
2664 void QQuickItemPrivate::transform_append(QQmlListProperty<QQuickTransform> *prop, QQuickTransform *transform)
2669 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2670 transform->appendToItem(that);
2673 QQuickTransform *QQuickItemPrivate::transform_at(QQmlListProperty<QQuickTransform> *prop, int idx)
2675 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2676 QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2678 if (idx < 0 || idx >= p->transforms.count())
2681 return p->transforms.at(idx);
2684 void QQuickItemPrivate::transform_clear(QQmlListProperty<QQuickTransform> *prop)
2686 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2687 QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2689 for (int ii = 0; ii < p->transforms.count(); ++ii) {
2690 QQuickTransform *t = p->transforms.at(ii);
2691 QQuickTransformPrivate *tp = QQuickTransformPrivate::get(t);
2692 tp->items.removeOne(that);
2695 p->transforms.clear();
2697 p->dirty(QQuickItemPrivate::Transform);
2701 \property QQuickItem::childrenRect
2702 \brief The geometry of an item's children.
2704 This property holds the (collective) position and size of the item's children.
2708 \qmlproperty real QtQuick2::Item::x
2709 \qmlproperty real QtQuick2::Item::y
2710 \qmlproperty real QtQuick2::Item::width
2711 \qmlproperty real QtQuick2::Item::height
2713 Defines the item's position and size relative to its parent.
2716 Item { x: 100; y: 100; width: 100; height: 100 }
2721 \qmlproperty real QtQuick2::Item::z
2723 Sets the stacking order of sibling items. By default the stacking order is 0.
2725 Items with a higher stacking value are drawn on top of siblings with a
2726 lower stacking order. Items with the same stacking value are drawn
2727 bottom up in the order they appear. Items with a negative stacking
2728 value are drawn under their parent's content.
2730 The following example shows the various effects of stacking order.
2734 \li \image declarative-item_stacking1.png
2735 \li Same \c z - later children above earlier children:
2740 width: 100; height: 100
2744 x: 50; y: 50; width: 100; height: 100
2749 \li \image declarative-item_stacking2.png
2750 \li Higher \c z on top:
2756 width: 100; height: 100
2760 x: 50; y: 50; width: 100; height: 100
2765 \li \image declarative-item_stacking3.png
2766 \li Same \c z - children above parents:
2771 width: 100; height: 100
2774 x: 50; y: 50; width: 100; height: 100
2780 \li \image declarative-item_stacking4.png
2781 \li Lower \c z below:
2786 width: 100; height: 100
2790 x: 50; y: 50; width: 100; height: 100
2799 \qmlproperty bool QtQuick2::Item::visible
2801 This property holds whether the item is visible. By default this is true.
2803 Setting this property directly affects the \c visible value of child
2804 items. When set to \c false, the \c visible values of all child items also
2805 become \c false. When set to \c true, the \c visible values of child items
2806 are returned to \c true, unless they have explicitly been set to \c false.
2808 (Because of this flow-on behavior, using the \c visible property may not
2809 have the intended effect if a property binding should only respond to
2810 explicit property changes. In such cases it may be better to use the
2811 \l opacity property instead.)
2813 Setting this property to \c false automatically causes \l focus to be set
2814 to \c false, and this item will longer receive mouse and keyboard events.
2815 (In contrast, setting the \l opacity to 0 does not affect the \l focus
2816 property and the receiving of key events.)
2818 \note This property's value is only affected by changes to this property or
2819 the parent's \c visible property. It does not change, for example, if this
2820 item moves off-screen, or if the \l opacity changes to 0.
2825 \qmlproperty AnchorLine QtQuick2::Item::anchors.top
2826 \qmlproperty AnchorLine QtQuick2::Item::anchors.bottom
2827 \qmlproperty AnchorLine QtQuick2::Item::anchors.left
2828 \qmlproperty AnchorLine QtQuick2::Item::anchors.right
2829 \qmlproperty AnchorLine QtQuick2::Item::anchors.horizontalCenter
2830 \qmlproperty AnchorLine QtQuick2::Item::anchors.verticalCenter
2831 \qmlproperty AnchorLine QtQuick2::Item::anchors.baseline
2833 \qmlproperty Item QtQuick2::Item::anchors.fill
2834 \qmlproperty Item QtQuick2::Item::anchors.centerIn
2836 \qmlproperty real QtQuick2::Item::anchors.margins
2837 \qmlproperty real QtQuick2::Item::anchors.topMargin
2838 \qmlproperty real QtQuick2::Item::anchors.bottomMargin
2839 \qmlproperty real QtQuick2::Item::anchors.leftMargin
2840 \qmlproperty real QtQuick2::Item::anchors.rightMargin
2841 \qmlproperty real QtQuick2::Item::anchors.horizontalCenterOffset
2842 \qmlproperty real QtQuick2::Item::anchors.verticalCenterOffset
2843 \qmlproperty real QtQuick2::Item::anchors.baselineOffset
2845 \qmlproperty bool QtQuick2::Item::anchors.mirrored
2847 Anchors provide a way to position an item by specifying its
2848 relationship with other items.
2850 Margins apply to top, bottom, left, right, and fill anchors.
2851 The \c anchors.margins property can be used to set all of the various margins at once, to the same value.
2852 Note that margins are anchor-specific and are not applied if an item does not
2855 Offsets apply for horizontal center, vertical center, and baseline anchors.
2859 \li \image declarative-anchors_example.png
2860 \li Text anchored to Image, horizontally centered and vertically below, with a margin.
2869 anchors.horizontalCenter: pic.horizontalCenter
2870 anchors.top: pic.bottom
2871 anchors.topMargin: 5
2877 \li \image declarative-anchors_example2.png
2879 Left of Text anchored to right of Image, with a margin. The y
2880 property of both defaults to 0.
2890 anchors.left: pic.right
2891 anchors.leftMargin: 5
2898 \c anchors.fill provides a convenient way for one item to have the
2899 same geometry as another item, and is equivalent to connecting all
2900 four directional anchors.
2902 To clear an anchor value, set it to \c undefined.
2904 \c anchors.mirrored returns true it the layout has been \l {LayoutMirroring}{mirrored}.
2906 \note You can only anchor an item to siblings or a parent.
2908 For more information see \l {anchor-layout}{Anchor Layouts}.
2912 \property QQuickItem::baselineOffset
2913 \brief The position of the item's baseline in local coordinates.
2915 The baseline of a \l Text item is the imaginary line on which the text
2916 sits. Controls containing text usually set their baseline to the
2917 baseline of their text.
2919 For non-text items, a default baseline offset of 0 is used.
2921 QQuickAnchors *QQuickItemPrivate::anchors() const
2924 Q_Q(const QQuickItem);
2925 _anchors = new QQuickAnchors(const_cast<QQuickItem *>(q));
2926 if (!componentComplete)
2927 _anchors->classBegin();
2932 void QQuickItemPrivate::siblingOrderChanged()
2935 for (int ii = 0; ii < changeListeners.count(); ++ii) {
2936 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
2937 if (change.types & QQuickItemPrivate::SiblingOrder) {
2938 change.listener->itemSiblingOrderChanged(q);
2943 QQmlListProperty<QObject> QQuickItemPrivate::data()
2945 return QQmlListProperty<QObject>(q_func(), 0, QQuickItemPrivate::data_append,
2946 QQuickItemPrivate::data_count,
2947 QQuickItemPrivate::data_at,
2948 QQuickItemPrivate::data_clear);
2951 QRectF QQuickItem::childrenRect()
2954 if (!d->extra.isAllocated() || !d->extra->contents) {
2955 d->extra.value().contents = new QQuickContents(this);
2956 if (d->componentComplete)
2957 d->extra->contents->complete();
2959 return d->extra->contents->rectF();
2962 QList<QQuickItem *> QQuickItem::childItems() const
2964 Q_D(const QQuickItem);
2965 return d->childItems;
2968 bool QQuickItem::clip() const
2970 return flags() & ItemClipsChildrenToShape;
2973 void QQuickItem::setClip(bool c)
2978 setFlag(ItemClipsChildrenToShape, c);
2980 emit clipChanged(c);
2985 This function is called to handle this item's changes in
2986 geometry from \a oldGeometry to \a newGeometry. If the two
2987 geometries are the same, it doesn't do anything.
2989 void QQuickItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
2994 QQuickAnchorsPrivate::get(d->_anchors)->updateMe();
2996 bool xChange = (newGeometry.x() != oldGeometry.x());
2997 bool yChange = (newGeometry.y() != oldGeometry.y());
2998 bool widthChange = (newGeometry.width() != oldGeometry.width());
2999 bool heightChange = (newGeometry.height() != oldGeometry.height());
3001 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
3002 const QQuickItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
3003 if (change.types & QQuickItemPrivate::Geometry) {
3004 if (change.gTypes == QQuickItemPrivate::GeometryChange) {
3005 change.listener->itemGeometryChanged(this, newGeometry, oldGeometry);
3006 } else if ((xChange && (change.gTypes & QQuickItemPrivate::XChange)) ||
3007 (yChange && (change.gTypes & QQuickItemPrivate::YChange)) ||
3008 (widthChange && (change.gTypes & QQuickItemPrivate::WidthChange)) ||
3009 (heightChange && (change.gTypes & QQuickItemPrivate::HeightChange))) {
3010 change.listener->itemGeometryChanged(this, newGeometry, oldGeometry);
3020 emit widthChanged();
3022 emit heightChanged();
3026 Called by the rendering thread when it is time to sync the state of the QML objects with the
3027 scene graph objects. The function should return the root of the scene graph subtree for
3028 this item. \a oldNode is the node that was returned the last time the function was called.
3030 The main thread is blocked while this function is executed so it is safe to read
3031 values from the QQuickItem instance and other objects in the main thread.
3033 \warning This is the only function in which it is allowed to make use of scene graph
3034 objects from the main thread. Use of scene graph objects outside this function will
3035 result in race conditions and potential crashes.
3038 QSGNode *QQuickItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
3045 This function is called when the item's scene graph resources are no longer needed.
3046 It allows items to free its resources, for instance textures, that are not owned by scene graph
3047 nodes. Note that scene graph nodes are managed by QQuickCanvas and should not be deleted by
3048 this function. Scene graph resources are no longer needed when the parent is set to null and
3049 the item is not used by any \l ShaderEffect or \l ShaderEffectSource.
3051 This function is called from the main thread. Therefore, resources used by the scene graph
3052 should not be deleted directly, but by calling \l QObject::deleteLater().
3054 \note The item destructor still needs to free its scene graph resources if not already done.
3057 void QQuickItem::releaseResources()
3061 QSGTransformNode *QQuickItemPrivate::createTransformNode()
3063 return new QSGTransformNode;
3066 void QQuickItem::updatePolish()
3070 void QQuickItemPrivate::addItemChangeListener(QQuickItemChangeListener *listener, ChangeTypes types)
3072 changeListeners.append(ChangeListener(listener, types));
3075 void QQuickItemPrivate::removeItemChangeListener(QQuickItemChangeListener *listener, ChangeTypes types)
3077 ChangeListener change(listener, types);
3078 changeListeners.removeOne(change);
3081 void QQuickItemPrivate::updateOrAddGeometryChangeListener(QQuickItemChangeListener *listener, GeometryChangeTypes types)
3083 ChangeListener change(listener, types);
3084 int index = changeListeners.find(change);
3086 changeListeners[index].gTypes = change.gTypes; //we may have different GeometryChangeTypes
3088 changeListeners.append(change);
3091 void QQuickItemPrivate::updateOrRemoveGeometryChangeListener(QQuickItemChangeListener *listener,
3092 GeometryChangeTypes types)
3094 ChangeListener change(listener, types);
3095 if (types == NoChange) {
3096 changeListeners.removeOne(change);
3098 int index = changeListeners.find(change);
3100 changeListeners[index].gTypes = change.gTypes; //we may have different GeometryChangeTypes
3104 void QQuickItem::keyPressEvent(QKeyEvent *event)
3109 void QQuickItem::keyReleaseEvent(QKeyEvent *event)
3114 void QQuickItem::inputMethodEvent(QInputMethodEvent *event)
3119 void QQuickItem::focusInEvent(QFocusEvent *)
3121 #ifndef QT_NO_ACCESSIBILITY
3122 QAccessibleEvent ev(this, QAccessible::Focus);
3123 QAccessible::updateAccessibility(&ev);
3127 void QQuickItem::focusOutEvent(QFocusEvent *)
3131 void QQuickItem::mousePressEvent(QMouseEvent *event)
3136 void QQuickItem::mouseMoveEvent(QMouseEvent *event)
3141 void QQuickItem::mouseReleaseEvent(QMouseEvent *event)
3146 void QQuickItem::mouseDoubleClickEvent(QMouseEvent *)
3150 void QQuickItem::mouseUngrabEvent()
3155 void QQuickItem::touchUngrabEvent()
3160 void QQuickItem::wheelEvent(QWheelEvent *event)
3165 void QQuickItem::touchEvent(QTouchEvent *event)
3170 void QQuickItem::hoverEnterEvent(QHoverEvent *event)
3175 void QQuickItem::hoverMoveEvent(QHoverEvent *event)
3180 void QQuickItem::hoverLeaveEvent(QHoverEvent *event)
3185 void QQuickItem::dragEnterEvent(QDragEnterEvent *event)
3190 void QQuickItem::dragMoveEvent(QDragMoveEvent *event)
3196 void QQuickItem::dragLeaveEvent(QDragLeaveEvent *event)
3202 void QQuickItem::dropEvent(QDropEvent *event)
3207 bool QQuickItem::childMouseEventFilter(QQuickItem *, QEvent *)
3212 void QQuickItem::windowDeactivateEvent()
3214 foreach (QQuickItem* item, childItems()) {
3215 item->windowDeactivateEvent();
3219 QVariant QQuickItem::inputMethodQuery(Qt::InputMethodQuery query) const
3221 Q_D(const QQuickItem);
3226 v = (bool)(flags() & ItemAcceptsInputMethod);
3229 case Qt::ImCursorRectangle:
3231 case Qt::ImCursorPosition:
3232 case Qt::ImSurroundingText:
3233 case Qt::ImCurrentSelection:
3234 case Qt::ImMaximumTextLength:
3235 case Qt::ImAnchorPosition:
3236 case Qt::ImPreferredLanguage:
3237 if (d->extra.isAllocated() && d->extra->keyHandler)
3238 v = d->extra->keyHandler->inputMethodQuery(query);
3246 QQuickAnchorLine QQuickItemPrivate::left() const
3248 Q_Q(const QQuickItem);
3249 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Left);
3252 QQuickAnchorLine QQuickItemPrivate::right() const
3254 Q_Q(const QQuickItem);
3255 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Right);
3258 QQuickAnchorLine QQuickItemPrivate::horizontalCenter() const
3260 Q_Q(const QQuickItem);
3261 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::HCenter);
3264 QQuickAnchorLine QQuickItemPrivate::top() const
3266 Q_Q(const QQuickItem);
3267 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Top);
3270 QQuickAnchorLine QQuickItemPrivate::bottom() const
3272 Q_Q(const QQuickItem);
3273 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Bottom);
3276 QQuickAnchorLine QQuickItemPrivate::verticalCenter() const
3278 Q_Q(const QQuickItem);
3279 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::VCenter);
3282 QQuickAnchorLine QQuickItemPrivate::baseline() const
3284 Q_Q(const QQuickItem);
3285 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Baseline);
3288 qreal QQuickItem::baselineOffset() const
3290 Q_D(const QQuickItem);
3291 if (d->baselineOffsetValid) {
3292 return d->baselineOffset;
3298 void QQuickItem::setBaselineOffset(qreal offset)
3301 if (offset == d->baselineOffset)
3304 d->baselineOffset = offset;
3305 d->baselineOffsetValid = true;
3307 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
3308 const QQuickItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
3309 if (change.types & QQuickItemPrivate::Geometry) {
3310 QQuickAnchorsPrivate *anchor = change.listener->anchorPrivate();
3312 anchor->updateVerticalAnchors();
3316 if (d->_anchors && (d->_anchors->usedAnchors() & QQuickAnchors::BaselineAnchor))
3317 QQuickAnchorsPrivate::get(d->_anchors)->updateVerticalAnchors();
3319 emit baselineOffsetChanged(offset);
3322 void QQuickItem::update()
3325 Q_ASSERT(flags() & ItemHasContents);
3326 d->dirty(QQuickItemPrivate::Content);
3329 void QQuickItem::polish()
3332 if (!d->polishScheduled) {
3333 d->polishScheduled = true;
3335 QQuickCanvasPrivate *p = QQuickCanvasPrivate::get(d->canvas);
3336 bool maybeupdate = p->itemsToPolish.isEmpty();
3337 p->itemsToPolish.insert(this);
3338 if (maybeupdate) d->canvas->maybeUpdate();
3343 void QQuickItem::mapFromItem(QQmlV8Function *args) const
3345 if (args->Length() != 0) {
3346 v8::Local<v8::Value> item = (*args)[0];
3347 QV8Engine *engine = args->engine();
3349 QQuickItem *itemObj = 0;
3350 if (!item->IsNull())
3351 itemObj = qobject_cast<QQuickItem*>(engine->toQObject(item));
3353 if (!itemObj && !item->IsNull()) {
3354 qmlInfo(this) << "mapFromItem() given argument \"" << engine->toString(item->ToString())
3355 << "\" which is neither null nor an Item";
3359 v8::Local<v8::Object> rv = v8::Object::New();
3360 args->returnValue(rv);
3362 qreal x = (args->Length() > 1)?(*args)[1]->NumberValue():0;
3363 qreal y = (args->Length() > 2)?(*args)[2]->NumberValue():0;
3365 QPointF p = mapFromItem(itemObj, QPointF(x, y));
3367 rv->Set(v8::String::New("x"), v8::Number::New(p.x()));
3368 rv->Set(v8::String::New("y"), v8::Number::New(p.y()));
3372 QTransform QQuickItem::itemTransform(QQuickItem *other, bool *ok) const
3374 Q_D(const QQuickItem);
3376 // XXX todo - we need to be able to handle common parents better and detect
3380 QTransform t = d->itemToCanvasTransform();
3381 if (other) t *= QQuickItemPrivate::get(other)->canvasToItemTransform();
3386 void QQuickItem::mapToItem(QQmlV8Function *args) const
3388 if (args->Length() != 0) {
3389 v8::Local<v8::Value> item = (*args)[0];
3390 QV8Engine *engine = args->engine();
3392 QQuickItem *itemObj = 0;
3393 if (!item->IsNull())
3394 itemObj = qobject_cast<QQuickItem*>(engine->toQObject(item));
3396 if (!itemObj && !item->IsNull()) {
3397 qmlInfo(this) << "mapToItem() given argument \"" << engine->toString(item->ToString())
3398 << "\" which is neither null nor an Item";
3402 v8::Local<v8::Object> rv = v8::Object::New();
3403 args->returnValue(rv);
3405 qreal x = (args->Length() > 1)?(*args)[1]->NumberValue():0;
3406 qreal y = (args->Length() > 2)?(*args)[2]->NumberValue():0;
3408 QPointF p = mapToItem(itemObj, QPointF(x, y));
3410 rv->Set(v8::String::New("x"), v8::Number::New(p.x()));
3411 rv->Set(v8::String::New("y"), v8::Number::New(p.y()));
3415 void QQuickItem::forceActiveFocus()
3418 QQuickItem *parent = parentItem();
3420 if (parent->flags() & QQuickItem::ItemIsFocusScope) {
3421 parent->setFocus(true);
3423 parent = parent->parentItem();
3427 QQuickItem *QQuickItem::childAt(qreal x, qreal y) const
3429 // XXX todo - should this include transform etc.?
3430 const QList<QQuickItem *> children = childItems();
3431 for (int i = children.count()-1; i >= 0; --i) {
3432 QQuickItem *child = children.at(i);
3433 if (child->isVisible() && child->x() <= x
3434 && child->x() + child->width() >= x
3436 && child->y() + child->height() >= y)
3442 QQmlListProperty<QObject> QQuickItemPrivate::resources()
3444 return QQmlListProperty<QObject>(q_func(), 0, QQuickItemPrivate::resources_append,
3445 QQuickItemPrivate::resources_count,
3446 QQuickItemPrivate::resources_at,
3447 QQuickItemPrivate::resources_clear);
3450 QQmlListProperty<QQuickItem> QQuickItemPrivate::children()
3452 return QQmlListProperty<QQuickItem>(q_func(), 0, QQuickItemPrivate::children_append,
3453 QQuickItemPrivate::children_count,
3454 QQuickItemPrivate::children_at,
3455 QQuickItemPrivate::children_clear);
3460 \qmlproperty real QtQuick2::Item::visibleChildren
3461 This read-only property lists all of the item's children that are currently visible.
3462 Note that a child's visibility may have changed explicitly, or because the visibility
3463 of this (it's parent) item or another grandparent changed.
3465 QQmlListProperty<QQuickItem> QQuickItemPrivate::visibleChildren()
3467 return QQmlListProperty<QQuickItem>(q_func(), 0, QQuickItemPrivate::visibleChildren_append,
3468 QQuickItemPrivate::visibleChildren_count,
3469 QQuickItemPrivate::visibleChildren_at);
3473 QQmlListProperty<QQuickState> QQuickItemPrivate::states()
3475 return _states()->statesProperty();
3478 QQmlListProperty<QQuickTransition> QQuickItemPrivate::transitions()
3480 return _states()->transitionsProperty();
3483 QString QQuickItemPrivate::state() const
3488 return _stateGroup->state();
3491 void QQuickItemPrivate::setState(const QString &state)
3493 _states()->setState(state);
3496 QString QQuickItem::state() const
3498 Q_D(const QQuickItem);
3502 void QQuickItem::setState(const QString &state)
3508 QQmlListProperty<QQuickTransform> QQuickItem::transform()
3510 return QQmlListProperty<QQuickTransform>(this, 0, QQuickItemPrivate::transform_append,
3511 QQuickItemPrivate::transform_count,
3512 QQuickItemPrivate::transform_at,
3513 QQuickItemPrivate::transform_clear);
3516 void QQuickItem::classBegin()
3519 d->componentComplete = false;
3521 d->_stateGroup->classBegin();
3523 d->_anchors->classBegin();
3524 if (d->extra.isAllocated() && d->extra->layer)
3525 d->extra->layer->classBegin();
3528 void QQuickItem::componentComplete()
3531 d->componentComplete = true;
3533 d->_stateGroup->componentComplete();
3535 d->_anchors->componentComplete();
3536 QQuickAnchorsPrivate::get(d->_anchors)->updateOnComplete();
3539 if (d->extra.isAllocated() && d->extra->layer)
3540 d->extra->layer->componentComplete();
3542 if (d->extra.isAllocated() && d->extra->keyHandler)
3543 d->extra->keyHandler->componentComplete();
3545 if (d->extra.isAllocated() && d->extra->contents)
3546 d->extra->contents->complete();
3549 QQuickStateGroup *QQuickItemPrivate::_states()
3553 _stateGroup = new QQuickStateGroup;
3554 if (!componentComplete)
3555 _stateGroup->classBegin();
3556 FAST_CONNECT(_stateGroup, SIGNAL(stateChanged(QString)),
3557 q, SIGNAL(stateChanged(QString)))
3563 QPointF QQuickItemPrivate::computeTransformOrigin() const
3567 case QQuickItem::TopLeft:
3568 return QPointF(0, 0);
3569 case QQuickItem::Top:
3570 return QPointF(width / 2., 0);
3571 case QQuickItem::TopRight:
3572 return QPointF(width, 0);
3573 case QQuickItem::Left:
3574 return QPointF(0, height / 2.);
3575 case QQuickItem::Center:
3576 return QPointF(width / 2., height / 2.);
3577 case QQuickItem::Right:
3578 return QPointF(width, height / 2.);
3579 case QQuickItem::BottomLeft:
3580 return QPointF(0, height);
3581 case QQuickItem::Bottom:
3582 return QPointF(width / 2., height);
3583 case QQuickItem::BottomRight:
3584 return QPointF(width, height);
3588 void QQuickItemPrivate::transformChanged()
3590 if (extra.isAllocated() && extra->layer)
3591 extra->layer->updateMatrix();
3594 void QQuickItemPrivate::deliverKeyEvent(QKeyEvent *e)
3598 Q_ASSERT(e->isAccepted());
3599 if (extra.isAllocated() && extra->keyHandler) {
3600 if (e->type() == QEvent::KeyPress)
3601 extra->keyHandler->keyPressed(e, false);
3603 extra->keyHandler->keyReleased(e, false);
3605 if (e->isAccepted())
3611 if (e->type() == QEvent::KeyPress)
3612 q->keyPressEvent(e);
3614 q->keyReleaseEvent(e);
3616 if (e->isAccepted())
3619 if (extra.isAllocated() && extra->keyHandler) {
3622 if (e->type() == QEvent::KeyPress)
3623 extra->keyHandler->keyPressed(e, true);
3625 extra->keyHandler->keyReleased(e, true);
3629 void QQuickItemPrivate::deliverInputMethodEvent(QInputMethodEvent *e)
3633 Q_ASSERT(e->isAccepted());
3634 if (extra.isAllocated() && extra->keyHandler) {
3635 extra->keyHandler->inputMethodEvent(e, false);
3637 if (e->isAccepted())
3643 q->inputMethodEvent(e);
3645 if (e->isAccepted())
3648 if (extra.isAllocated() && extra->keyHandler) {
3651 extra->keyHandler->inputMethodEvent(e, true);
3655 void QQuickItemPrivate::deliverFocusEvent(QFocusEvent *e)
3659 if (e->type() == QEvent::FocusIn) {
3662 q->focusOutEvent(e);
3666 void QQuickItemPrivate::deliverMouseEvent(QMouseEvent *e)
3670 Q_ASSERT(e->isAccepted());
3672 switch (e->type()) {
3674 Q_ASSERT(!"Unknown event type");
3675 case QEvent::MouseMove:
3676 q->mouseMoveEvent(e);
3678 case QEvent::MouseButtonPress:
3679 q->mousePressEvent(e);
3681 case QEvent::MouseButtonRelease:
3682 q->mouseReleaseEvent(e);
3684 case QEvent::MouseButtonDblClick:
3685 q->mouseDoubleClickEvent(e);
3690 void QQuickItemPrivate::deliverWheelEvent(QWheelEvent *e)
3696 void QQuickItemPrivate::deliverTouchEvent(QTouchEvent *e)
3702 void QQuickItemPrivate::deliverHoverEvent(QHoverEvent *e)
3705 switch (e->type()) {
3707 Q_ASSERT(!"Unknown event type");
3708 case QEvent::HoverEnter:
3709 q->hoverEnterEvent(e);
3711 case QEvent::HoverLeave:
3712 q->hoverLeaveEvent(e);
3714 case QEvent::HoverMove:
3715 q->hoverMoveEvent(e);
3720 void QQuickItemPrivate::deliverDragEvent(QEvent *e)
3723 switch (e->type()) {
3725 Q_ASSERT(!"Unknown event type");
3726 case QEvent::DragEnter:
3727 q->dragEnterEvent(static_cast<QDragEnterEvent *>(e));
3729 case QEvent::DragLeave:
3730 q->dragLeaveEvent(static_cast<QDragLeaveEvent *>(e));
3732 case QEvent::DragMove:
3733 q->dragMoveEvent(static_cast<QDragMoveEvent *>(e));
3736 q->dropEvent(static_cast<QDropEvent *>(e));
3741 void QQuickItem::itemChange(ItemChange change, const ItemChangeData &value)
3748 Notify input method on updated query values if needed. \a indicates changed attributes.
3750 void QQuickItem::updateInputMethod(Qt::InputMethodQueries queries)
3752 if (hasActiveFocus())
3753 qApp->inputMethod()->update(queries);
3757 // XXX todo - do we want/need this anymore?
3758 // Note that it's now used for varying clip rect
3759 QRectF QQuickItem::boundingRect() const
3761 Q_D(const QQuickItem);
3762 return QRectF(0, 0, d->width, d->height);
3765 QQuickItem::TransformOrigin QQuickItem::transformOrigin() const
3767 Q_D(const QQuickItem);
3771 void QQuickItem::setTransformOrigin(TransformOrigin origin)
3774 if (origin == d->origin())
3777 d->extra.value().origin = origin;
3778 d->dirty(QQuickItemPrivate::TransformOrigin);
3780 emit transformOriginChanged(d->origin());
3783 QPointF QQuickItem::transformOriginPoint() const
3785 Q_D(const QQuickItem);
3786 if (d->extra.isAllocated() && !d->extra->userTransformOriginPoint.isNull())
3787 return d->extra->userTransformOriginPoint;
3788 return d->computeTransformOrigin();
3791 void QQuickItem::setTransformOriginPoint(const QPointF &point)
3794 if (d->extra.value().userTransformOriginPoint == point)
3797 d->extra->userTransformOriginPoint = point;
3798 d->dirty(QQuickItemPrivate::TransformOrigin);
3801 qreal QQuickItem::z() const
3803 Q_D(const QQuickItem);
3807 void QQuickItem::setZ(qreal v)
3813 d->extra.value().z = v;
3815 d->dirty(QQuickItemPrivate::ZValue);
3816 if (d->parentItem) {
3817 QQuickItemPrivate::get(d->parentItem)->dirty(QQuickItemPrivate::ChildrenStackingChanged);
3818 QQuickItemPrivate::get(d->parentItem)->markSortedChildrenDirty(this);
3823 if (d->extra.isAllocated() && d->extra->layer)
3824 d->extra->layer->updateZ();
3829 \qmlproperty real QtQuick2::Item::rotation
3830 This property holds the rotation of the item in degrees clockwise.
3832 This specifies how many degrees to rotate the item around its transformOrigin.
3833 The default rotation is 0 degrees (i.e. not rotated at all).
3837 \li \image declarative-rotation.png
3842 width: 100; height: 100
3845 x: 25; y: 25; width: 50; height: 50
3852 \sa transform, Rotation
3856 \qmlproperty real QtQuick2::Item::scale
3857 This property holds the scale of the item.
3859 A scale of less than 1 means the item will be displayed smaller than
3860 normal, and a scale of greater than 1 means the item will be
3861 displayed larger than normal. A negative scale means the item will
3864 By default, items are displayed at a scale of 1 (i.e. at their
3867 Scaling is from the item's transformOrigin.
3871 \li \image declarative-scale.png
3876 width: 100; height: 100
3879 width: 25; height: 25
3883 x: 25; y: 25; width: 50; height: 50
3890 \sa transform, Scale
3894 \qmlproperty real QtQuick2::Item::opacity
3896 This property holds the opacity of the item. Opacity is specified as a
3897 number between 0 (fully transparent) and 1 (fully opaque). The default is 1.
3899 When this property is set, the specified opacity is also applied
3900 individually to child items. In almost all cases this is what you want,
3901 but in some cases it may produce undesired results. For example in the
3902 second set of rectangles below, the red rectangle has specified an opacity
3903 of 0.5, which affects the opacity of its blue child rectangle even though
3904 the child has not specified an opacity.
3908 \li \image declarative-item_opacity1.png
3914 width: 100; height: 100
3917 x: 50; y: 50; width: 100; height: 100
3923 \li \image declarative-item_opacity2.png
3930 width: 100; height: 100
3933 x: 50; y: 50; width: 100; height: 100
3940 If an item's opacity is set to 0, the item will no longer receive mouse
3941 events, but will continue to receive key events and will retain the keyboard
3942 \l focus if it has been set. (In contrast, setting the \l visible property
3943 to \c false stops both mouse and keyboard events, and also removes focus
3948 Returns a value indicating whether mouse input should
3949 remain with this item exclusively.
3951 \sa setKeepMouseGrab()
3954 qreal QQuickItem::rotation() const
3956 Q_D(const QQuickItem);
3957 return d->rotation();
3960 void QQuickItem::setRotation(qreal r)
3963 if (d->rotation() == r)
3966 d->extra.value().rotation = r;
3968 d->dirty(QQuickItemPrivate::BasicTransform);
3970 d->itemChange(ItemRotationHasChanged, r);
3972 emit rotationChanged();
3975 qreal QQuickItem::scale() const
3977 Q_D(const QQuickItem);
3981 void QQuickItem::setScale(qreal s)
3984 if (d->scale() == s)
3987 d->extra.value().scale = s;
3989 d->dirty(QQuickItemPrivate::BasicTransform);
3991 emit scaleChanged();
3994 qreal QQuickItem::opacity() const
3996 Q_D(const QQuickItem);
3997 return d->opacity();
4000 void QQuickItem::setOpacity(qreal o)
4003 if (d->opacity() == o)
4006 d->extra.value().opacity = o;
4008 d->dirty(QQuickItemPrivate::OpacityValue);
4010 d->itemChange(ItemOpacityHasChanged, o);
4012 emit opacityChanged();
4015 bool QQuickItem::isVisible() const
4017 Q_D(const QQuickItem);
4018 return d->effectiveVisible;
4021 void QQuickItem::setVisible(bool v)
4024 if (v == d->explicitVisible)
4027 d->explicitVisible = v;
4029 const bool childVisibilityChanged = d->setEffectiveVisibleRecur(d->calcEffectiveVisible());
4030 if (childVisibilityChanged && d->parentItem)
4031 emit d->parentItem->visibleChildrenChanged(); // signal the parent, not this!
4034 bool QQuickItem::isEnabled() const
4036 Q_D(const QQuickItem);
4037 return d->effectiveEnable;
4040 void QQuickItem::setEnabled(bool e)
4043 if (e == d->explicitEnable)
4046 d->explicitEnable = e;
4048 QQuickItem *scope = parentItem();
4049 while (scope && !scope->isFocusScope())
4050 scope = scope->parentItem();
4052 d->setEffectiveEnableRecur(scope, d->calcEffectiveEnable());
4055 bool QQuickItemPrivate::calcEffectiveVisible() const
4057 // XXX todo - Should the effective visible of an element with no parent just be the current
4058 // effective visible? This would prevent pointless re-processing in the case of an element
4059 // moving to/from a no-parent situation, but it is different from what graphics view does.
4060 return explicitVisible && (!parentItem || QQuickItemPrivate::get(parentItem)->effectiveVisible);
4063 bool QQuickItemPrivate::setEffectiveVisibleRecur(bool newEffectiveVisible)
4067 if (newEffectiveVisible && !explicitVisible) {
4068 // This item locally overrides visibility
4069 return false; // effective visibility didn't change
4072 if (newEffectiveVisible == effectiveVisible) {
4073 // No change necessary
4074 return false; // effective visibility didn't change
4077 effectiveVisible = newEffectiveVisible;
4079 if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
4082 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(canvas);
4083 if (canvasPriv->mouseGrabberItem == q)
4087 bool childVisibilityChanged = false;
4088 for (int ii = 0; ii < childItems.count(); ++ii)
4089 childVisibilityChanged |= QQuickItemPrivate::get(childItems.at(ii))->setEffectiveVisibleRecur(newEffectiveVisible);
4091 itemChange(QQuickItem::ItemVisibleHasChanged, effectiveVisible);
4092 #ifndef QT_NO_ACCESSIBILITY
4094 QAccessibleEvent ev(q, effectiveVisible ? QAccessible::ObjectShow : QAccessible::ObjectHide);
4095 QAccessible::updateAccessibility(&ev);
4098 emit q->visibleChanged();
4099 if (childVisibilityChanged)
4100 emit q->visibleChildrenChanged();
4102 return true; // effective visibility DID change
4105 bool QQuickItemPrivate::calcEffectiveEnable() const
4107 // XXX todo - Should the effective enable of an element with no parent just be the current
4108 // effective enable? This would prevent pointless re-processing in the case of an element
4109 // moving to/from a no-parent situation, but it is different from what graphics view does.
4110 return explicitEnable && (!parentItem || QQuickItemPrivate::get(parentItem)->effectiveEnable);
4113 void QQuickItemPrivate::setEffectiveEnableRecur(QQuickItem *scope, bool newEffectiveEnable)
4117 if (newEffectiveEnable && !explicitEnable) {
4118 // This item locally overrides enable
4122 if (newEffectiveEnable == effectiveEnable) {
4123 // No change necessary
4127 effectiveEnable = newEffectiveEnable;
4130 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(canvas);
4131 if (canvasPriv->mouseGrabberItem == q)
4133 if (scope && !effectiveEnable && activeFocus) {
4134 canvasPriv->clearFocusInScope(
4135 scope, q, QQuickCanvasPrivate::DontChangeFocusProperty | QQuickCanvasPrivate::DontChangeSubFocusItem);
4139 for (int ii = 0; ii < childItems.count(); ++ii) {
4140 QQuickItemPrivate::get(childItems.at(ii))->setEffectiveEnableRecur(
4141 flags & QQuickItem::ItemIsFocusScope ? q : scope, newEffectiveEnable);
4144 if (canvas && scope && effectiveEnable && focus) {
4145 QQuickCanvasPrivate::get(canvas)->setFocusInScope(
4146 scope, q, QQuickCanvasPrivate::DontChangeFocusProperty | QQuickCanvasPrivate::DontChangeSubFocusItem);
4149 emit q->enabledChanged();
4152 QString QQuickItemPrivate::dirtyToString() const
4154 #define DIRTY_TO_STRING(value) if (dirtyAttributes & value) { \
4155 if (!rv.isEmpty()) \
4156 rv.append(QLatin1String("|")); \
4157 rv.append(QLatin1String(#value)); \
4160 // QString rv = QLatin1String("0x") + QString::number(dirtyAttributes, 16);
4163 DIRTY_TO_STRING(TransformOrigin);
4164 DIRTY_TO_STRING(Transform);
4165 DIRTY_TO_STRING(BasicTransform);
4166 DIRTY_TO_STRING(Position);
4167 DIRTY_TO_STRING(Size);
4168 DIRTY_TO_STRING(ZValue);
4169 DIRTY_TO_STRING(Content);
4170 DIRTY_TO_STRING(Smooth);
4171 DIRTY_TO_STRING(OpacityValue);
4172 DIRTY_TO_STRING(ChildrenChanged);
4173 DIRTY_TO_STRING(ChildrenStackingChanged);
4174 DIRTY_TO_STRING(ParentChanged);
4175 DIRTY_TO_STRING(Clip);
4176 DIRTY_TO_STRING(Canvas);
4177 DIRTY_TO_STRING(EffectReference);
4178 DIRTY_TO_STRING(Visible);
4179 DIRTY_TO_STRING(HideReference);
4180 DIRTY_TO_STRING(PerformanceHints);
4185 void QQuickItemPrivate::dirty(DirtyType type)
4188 if (type & (TransformOrigin | Transform | BasicTransform | Position | Size))
4191 if (!(dirtyAttributes & type) || (canvas && !prevDirtyItem)) {
4192 dirtyAttributes |= type;
4195 QQuickCanvasPrivate::get(canvas)->dirtyItem(q);
4200 void QQuickItemPrivate::addToDirtyList()
4205 if (!prevDirtyItem) {
4206 Q_ASSERT(!nextDirtyItem);
4208 QQuickCanvasPrivate *p = QQuickCanvasPrivate::get(canvas);
4209 nextDirtyItem = p->dirtyItemList;
4210 if (nextDirtyItem) QQuickItemPrivate::get(nextDirtyItem)->prevDirtyItem = &nextDirtyItem;
4211 prevDirtyItem = &p->dirtyItemList;
4212 p->dirtyItemList = q;
4215 Q_ASSERT(prevDirtyItem);
4218 void QQuickItemPrivate::removeFromDirtyList()
4220 if (prevDirtyItem) {
4221 if (nextDirtyItem) QQuickItemPrivate::get(nextDirtyItem)->prevDirtyItem = prevDirtyItem;
4222 *prevDirtyItem = nextDirtyItem;
4226 Q_ASSERT(!prevDirtyItem);
4227 Q_ASSERT(!nextDirtyItem);
4230 void QQuickItemPrivate::refFromEffectItem(bool hide)
4232 ++extra.value().effectRefCount;
4233 if (1 == extra->effectRefCount) {
4234 dirty(EffectReference);
4235 if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
4238 if (++extra->hideRefCount == 1)
4239 dirty(HideReference);
4243 void QQuickItemPrivate::derefFromEffectItem(bool unhide)
4245 Q_ASSERT(extra->effectRefCount);
4246 --extra->effectRefCount;
4247 if (0 == extra->effectRefCount) {
4248 dirty(EffectReference);
4249 if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
4252 if (--extra->hideRefCount == 0)
4253 dirty(HideReference);
4257 void QQuickItemPrivate::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data)
4261 case QQuickItem::ItemChildAddedChange:
4262 q->itemChange(change, data);
4263 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4264 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4265 if (change.types & QQuickItemPrivate::Children) {
4266 change.listener->itemChildAdded(q, data.item);
4270 case QQuickItem::ItemChildRemovedChange:
4271 q->itemChange(change, data);
4272 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4273 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4274 if (change.types & QQuickItemPrivate::Children) {
4275 change.listener->itemChildRemoved(q, data.item);
4279 case QQuickItem::ItemSceneChange:
4280 q->itemChange(change, data);
4282 case QQuickItem::ItemVisibleHasChanged:
4283 q->itemChange(change, data);
4284 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4285 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4286 if (change.types & QQuickItemPrivate::Visibility) {
4287 change.listener->itemVisibilityChanged(q);
4291 case QQuickItem::ItemParentHasChanged:
4292 q->itemChange(change, data);
4293 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4294 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4295 if (change.types & QQuickItemPrivate::Parent) {
4296 change.listener->itemParentChanged(q, data.item);
4300 case QQuickItem::ItemOpacityHasChanged:
4301 q->itemChange(change, data);
4302 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4303 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4304 if (change.types & QQuickItemPrivate::Opacity) {
4305 change.listener->itemOpacityChanged(q);
4309 case QQuickItem::ItemActiveFocusHasChanged:
4310 q->itemChange(change, data);
4312 case QQuickItem::ItemRotationHasChanged:
4313 q->itemChange(change, data);
4314 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4315 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4316 if (change.types & QQuickItemPrivate::Rotation) {
4317 change.listener->itemRotationChanged(q);
4325 \property QQuickItem::smooth
4326 \brief whether the item is smoothed or not.
4328 Primarily used in image based elements to decide if the item should use smooth
4329 sampling or not. Smooth sampling is performed using linear interpolation, while
4330 non-smooth is performed using nearest neighbor.
4332 In Qt Quick 2.0, this property has minimal impact on performance.
4338 Returns true if the item should be drawn with antialiasing and
4339 smooth pixmap filtering, false otherwise.
4341 The default is false.
4345 bool QQuickItem::smooth() const
4347 Q_D(const QQuickItem);
4352 Sets whether the item should be drawn with antialiasing and
4353 smooth pixmap filtering to \a smooth.
4357 void QQuickItem::setSmooth(bool smooth)
4360 if (d->smooth == smooth)
4364 d->dirty(QQuickItemPrivate::Smooth);
4366 emit smoothChanged(smooth);
4369 QQuickItem::Flags QQuickItem::flags() const
4371 Q_D(const QQuickItem);
4372 return (QQuickItem::Flags)d->flags;
4375 void QQuickItem::setFlag(Flag flag, bool enabled)
4379 setFlags((Flags)(d->flags | (quint32)flag));
4381 setFlags((Flags)(d->flags & ~(quint32)flag));
4384 void QQuickItem::setFlags(Flags flags)
4388 if ((flags & ItemIsFocusScope) != (d->flags & ItemIsFocusScope)) {
4389 if (flags & ItemIsFocusScope && !d->childItems.isEmpty() && d->canvas) {
4390 qWarning("QQuickItem: Cannot set FocusScope once item has children and is in a canvas.");
4391 flags &= ~ItemIsFocusScope;
4392 } else if (d->flags & ItemIsFocusScope) {
4393 qWarning("QQuickItem: Cannot unset FocusScope flag.");
4394 flags |= ItemIsFocusScope;
4398 if ((flags & ItemClipsChildrenToShape ) != (d->flags & ItemClipsChildrenToShape))
4399 d->dirty(QQuickItemPrivate::Clip);
4404 qreal QQuickItem::x() const
4406 Q_D(const QQuickItem);
4410 qreal QQuickItem::y() const
4412 Q_D(const QQuickItem);
4416 QPointF QQuickItem::pos() const
4418 Q_D(const QQuickItem);
4419 return QPointF(d->x, d->y);
4422 void QQuickItem::setX(qreal v)
4431 d->dirty(QQuickItemPrivate::Position);
4433 geometryChanged(QRectF(x(), y(), width(), height()),
4434 QRectF(oldx, y(), width(), height()));
4437 void QQuickItem::setY(qreal v)
4446 d->dirty(QQuickItemPrivate::Position);
4448 geometryChanged(QRectF(x(), y(), width(), height()),
4449 QRectF(x(), oldy, width(), height()));
4452 void QQuickItem::setPos(const QPointF &pos)
4455 if (QPointF(d->x, d->y) == pos)
4464 d->dirty(QQuickItemPrivate::Position);
4466 geometryChanged(QRectF(x(), y(), width(), height()),
4467 QRectF(oldx, oldy, width(), height()));
4470 qreal QQuickItem::width() const
4472 Q_D(const QQuickItem);
4476 void QQuickItem::setWidth(qreal w)
4482 d->widthValid = true;
4486 qreal oldWidth = d->width;
4489 d->dirty(QQuickItemPrivate::Size);
4491 geometryChanged(QRectF(x(), y(), width(), height()),
4492 QRectF(x(), y(), oldWidth, height()));
4495 void QQuickItem::resetWidth()
4498 d->widthValid = false;
4499 setImplicitWidth(implicitWidth());
4502 void QQuickItemPrivate::implicitWidthChanged()
4505 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4506 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4507 if (change.types & QQuickItemPrivate::ImplicitWidth) {
4508 change.listener->itemImplicitWidthChanged(q);
4511 emit q->implicitWidthChanged();
4514 qreal QQuickItemPrivate::getImplicitWidth() const
4516 return implicitWidth;
4519 Returns the width of the item that is implied by other properties that determine the content.
4521 qreal QQuickItem::implicitWidth() const
4523 Q_D(const QQuickItem);
4524 return d->getImplicitWidth();
4528 \qmlproperty real QtQuick2::Item::implicitWidth
4529 \qmlproperty real QtQuick2::Item::implicitHeight
4531 Defines the natural width or height of the Item if no \l width or \l height is specified.
4533 The default implicit size for most items is 0x0, however some elements have an inherent
4534 implicit size which cannot be overridden, e.g. Image, Text.
4536 Setting the implicit size is useful for defining components that have a preferred size
4537 based on their content, for example:
4544 property alias icon: image.source
4545 property alias label: text.text
4546 implicitWidth: text.implicitWidth + image.implicitWidth
4547 implicitHeight: Math.max(text.implicitHeight, image.implicitHeight)
4552 anchors.left: image.right; anchors.right: parent.right
4553 anchors.verticalCenter: parent.verticalCenter
4558 \b Note: using implicitWidth of Text or TextEdit and setting the width explicitly
4559 incurs a performance penalty as the text must be laid out twice.
4563 Sets the implied width of the item to \a w.
4564 This is the width implied by other properties that determine the content.
4566 void QQuickItem::setImplicitWidth(qreal w)
4569 bool changed = w != d->implicitWidth;
4570 d->implicitWidth = w;
4571 if (d->width == w || widthValid()) {
4573 d->implicitWidthChanged();
4577 qreal oldWidth = d->width;
4580 d->dirty(QQuickItemPrivate::Size);
4582 geometryChanged(QRectF(x(), y(), width(), height()),
4583 QRectF(x(), y(), oldWidth, height()));
4586 d->implicitWidthChanged();
4590 Returns whether the width property has been set explicitly.
4592 bool QQuickItem::widthValid() const
4594 Q_D(const QQuickItem);
4595 return d->widthValid;
4598 qreal QQuickItem::height() const
4600 Q_D(const QQuickItem);
4604 void QQuickItem::setHeight(qreal h)
4610 d->heightValid = true;
4614 qreal oldHeight = d->height;
4617 d->dirty(QQuickItemPrivate::Size);
4619 geometryChanged(QRectF(x(), y(), width(), height()),
4620 QRectF(x(), y(), width(), oldHeight));
4623 void QQuickItem::resetHeight()
4626 d->heightValid = false;
4627 setImplicitHeight(implicitHeight());
4630 void QQuickItemPrivate::implicitHeightChanged()
4633 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4634 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4635 if (change.types & QQuickItemPrivate::ImplicitHeight) {
4636 change.listener->itemImplicitHeightChanged(q);
4639 emit q->implicitHeightChanged();
4642 qreal QQuickItemPrivate::getImplicitHeight() const
4644 return implicitHeight;
4648 Returns the height of the item that is implied by other properties that determine the content.
4650 qreal QQuickItem::implicitHeight() const
4652 Q_D(const QQuickItem);
4653 return d->getImplicitHeight();
4658 Sets the implied height of the item to \a h.
4659 This is the height implied by other properties that determine the content.
4661 void QQuickItem::setImplicitHeight(qreal h)
4664 bool changed = h != d->implicitHeight;
4665 d->implicitHeight = h;
4666 if (d->height == h || heightValid()) {
4668 d->implicitHeightChanged();
4672 qreal oldHeight = d->height;
4675 d->dirty(QQuickItemPrivate::Size);
4677 geometryChanged(QRectF(x(), y(), width(), height()),
4678 QRectF(x(), y(), width(), oldHeight));
4681 d->implicitHeightChanged();
4684 void QQuickItem::setImplicitSize(qreal w, qreal h)
4687 bool wChanged = w != d->implicitWidth;
4688 bool hChanged = h != d->implicitHeight;
4690 d->implicitWidth = w;
4691 d->implicitHeight = h;
4695 if (d->width == w || widthValid()) {
4697 d->implicitWidthChanged();
4700 if (d->height == h || heightValid()) {
4702 d->implicitHeightChanged();
4708 qreal oldWidth = d->width;
4709 qreal oldHeight = d->height;
4715 d->dirty(QQuickItemPrivate::Size);
4717 geometryChanged(QRectF(x(), y(), width(), height()),
4718 QRectF(x(), y(), oldWidth, oldHeight));
4720 if (!wDone && wChanged)
4721 d->implicitWidthChanged();
4722 if (!hDone && hChanged)
4723 d->implicitHeightChanged();
4727 Returns whether the height property has been set explicitly.
4729 bool QQuickItem::heightValid() const
4731 Q_D(const QQuickItem);
4732 return d->heightValid;
4735 void QQuickItem::setSize(const QSizeF &size)
4738 d->heightValid = true;
4739 d->widthValid = true;
4741 if (QSizeF(d->width, d->height) == size)
4744 qreal oldHeight = d->height;
4745 qreal oldWidth = d->width;
4746 d->height = size.height();
4747 d->width = size.width();
4749 d->dirty(QQuickItemPrivate::Size);
4751 geometryChanged(QRectF(x(), y(), width(), height()),
4752 QRectF(x(), y(), oldWidth, oldHeight));
4755 bool QQuickItem::hasActiveFocus() const
4757 Q_D(const QQuickItem);
4758 return d->activeFocus;
4761 bool QQuickItem::hasFocus() const
4763 Q_D(const QQuickItem);
4767 void QQuickItem::setFocus(bool focus)
4770 if (d->focus == focus)
4773 if (d->canvas || d->parentItem) {
4774 // Need to find our nearest focus scope
4775 QQuickItem *scope = parentItem();
4776 while (scope && !scope->isFocusScope() && scope->parentItem())
4777 scope = scope->parentItem();
4780 QQuickCanvasPrivate::get(d->canvas)->setFocusInScope(scope, this);
4782 QQuickCanvasPrivate::get(d->canvas)->clearFocusInScope(scope, this);
4784 // do the focus changes from setFocusInScope/clearFocusInScope that are
4785 // unrelated to a canvas
4786 QVarLengthArray<QQuickItem *, 20> changed;
4787 QQuickItem *oldSubFocusItem = QQuickItemPrivate::get(scope)->subFocusItem;
4788 if (oldSubFocusItem) {
4789 QQuickItemPrivate::get(oldSubFocusItem)->focus = false;
4790 changed << oldSubFocusItem;
4792 d->updateSubFocusItem(scope, focus);
4796 emit focusChanged(focus);
4798 QQuickCanvasPrivate::notifyFocusChangesRecur(changed.data(), changed.count() - 1);
4802 emit focusChanged(focus);
4806 bool QQuickItem::isFocusScope() const
4808 return flags() & ItemIsFocusScope;
4811 QQuickItem *QQuickItem::scopedFocusItem() const
4813 Q_D(const QQuickItem);
4814 if (!isFocusScope())
4817 return d->subFocusItem;
4821 Qt::MouseButtons QQuickItem::acceptedMouseButtons() const
4823 Q_D(const QQuickItem);
4824 return d->acceptedMouseButtons();
4827 void QQuickItem::setAcceptedMouseButtons(Qt::MouseButtons buttons)
4830 if (buttons & Qt::LeftButton)
4833 d->extra.clearFlag();
4835 buttons &= ~Qt::LeftButton;
4836 if (buttons || d->extra.isAllocated())
4837 d->extra.value().acceptedMouseButtons = buttons;
4840 bool QQuickItem::filtersChildMouseEvents() const
4842 Q_D(const QQuickItem);
4843 return d->filtersChildMouseEvents;
4846 void QQuickItem::setFiltersChildMouseEvents(bool filter)
4849 d->filtersChildMouseEvents = filter;
4852 bool QQuickItem::isUnderMouse() const
4854 Q_D(const QQuickItem);
4858 QPointF cursorPos = QGuiApplicationPrivate::lastCursorPosition;
4859 if (QRectF(0, 0, width(), height()).contains(mapFromScene(cursorPos))) // ### refactor: d->canvas->mapFromGlobal(cursorPos))))
4864 bool QQuickItem::acceptHoverEvents() const
4866 Q_D(const QQuickItem);
4867 return d->hoverEnabled;
4870 void QQuickItem::setAcceptHoverEvents(bool enabled)
4873 d->hoverEnabled = enabled;
4876 void QQuickItem::grabMouse()
4881 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
4882 if (canvasPriv->mouseGrabberItem == this)
4885 QQuickItem *oldGrabber = canvasPriv->mouseGrabberItem;
4886 canvasPriv->mouseGrabberItem = this;
4888 QEvent ev(QEvent::UngrabMouse);
4889 d->canvas->sendEvent(oldGrabber, &ev);
4893 void QQuickItem::ungrabMouse()
4898 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
4899 if (canvasPriv->mouseGrabberItem != this) {
4900 qWarning("QQuickItem::ungrabMouse(): Item is not the mouse grabber.");
4904 canvasPriv->mouseGrabberItem = 0;
4906 QEvent ev(QEvent::UngrabMouse);
4907 d->canvas->sendEvent(this, &ev);
4910 bool QQuickItem::keepMouseGrab() const
4912 Q_D(const QQuickItem);
4913 return d->keepMouse;
4917 The flag indicating whether the mouse should remain
4918 with this item is set to \a keep.
4920 This is useful for items that wish to grab and keep mouse
4921 interaction following a predefined gesture. For example,
4922 an item that is interested in horizontal mouse movement
4923 may set keepMouseGrab to true once a threshold has been
4924 exceeded. Once keepMouseGrab has been set to true, filtering
4925 items will not react to mouse events.
4927 If the item does not indicate that it wishes to retain mouse grab,
4928 a filtering item may steal the grab. For example, Flickable may attempt
4929 to steal a mouse grab if it detects that the user has begun to
4934 void QQuickItem::setKeepMouseGrab(bool keep)
4937 d->keepMouse = keep;
4941 Grabs the touch points specified by \a ids.
4943 These touch points will be owned by the item until
4944 they are released. Alternatively, the grab can be stolen
4945 by a filtering item like Flickable. Use setKeepTouchGrab()
4946 to prevent the grab from being stolen.
4948 \sa ungrabTouchPoints(), setKeepTouchGrab()
4950 void QQuickItem::grabTouchPoints(const QList<int> &ids)
4955 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
4957 QSet<QQuickItem*> ungrab;
4958 for (int i = 0; i < ids.count(); ++i) {
4959 QQuickItem *oldGrabber = canvasPriv->itemForTouchPointId.value(ids.at(i));
4960 if (oldGrabber == this)
4963 canvasPriv->itemForTouchPointId[ids.at(i)] = this;
4965 ungrab.insert(oldGrabber);
4967 foreach (QQuickItem *oldGrabber, ungrab)
4968 oldGrabber->touchUngrabEvent();
4972 Ungrabs the touch points owned by this item.
4974 \sa grabTouchPoints()
4976 void QQuickItem::ungrabTouchPoints()
4981 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
4983 QMutableHashIterator<int, QQuickItem*> i(canvasPriv->itemForTouchPointId);
4984 while (i.hasNext()) {
4986 if (i.value() == this)
4993 Returns a value indicating whether the touch points grabbed by this item
4994 should remain with this item exclusively.
4996 \sa setKeepTouchGrab(), keepMouseGrab()
4998 bool QQuickItem::keepTouchGrab() const
5000 Q_D(const QQuickItem);
5001 return d->keepTouch;
5005 The flag indicating whether the touch points grabbed
5006 by this item should remain with this item is set to \a keep.
5008 This is useful for items that wish to grab and keep specific touch
5009 points following a predefined gesture. For example,
5010 an item that is interested in horizontal touch point movement
5011 may set setKeepTouchGrab to true once a threshold has been
5012 exceeded. Once setKeepTouchGrab has been set to true, filtering
5013 items will not react to the relevant touch points.
5015 If the item does not indicate that it wishes to retain touch point grab,
5016 a filtering item may steal the grab. For example, Flickable may attempt
5017 to steal a touch point grab if it detects that the user has begun to
5020 \sa keepTouchGrab(), setKeepMouseGrab()
5022 void QQuickItem::setKeepTouchGrab(bool keep)
5025 d->keepTouch = keep;
5029 \qmlmethod object QtQuick2::Item::mapFromItem(Item item, real x, real y)
5031 Maps the point (\a x, \a y), which is in \a item's coordinate system, to
5032 this item's coordinate system, and returns an object with \c x and \c y
5033 properties matching the mapped coordinate.
5035 If \a item is a \c null value, this maps the point from the coordinate
5036 system of the root QML view.
5039 \qmlmethod object QtQuick2::Item::mapToItem(Item item, real x, real y)
5041 Maps the point (\a x, \a y), which is in this item's coordinate system, to
5042 \a item's coordinate system, and returns an object with \c x and \c y
5043 properties matching the mapped coordinate.
5045 If \a item is a \c null value, this maps \a x and \a y to the coordinate
5046 system of the root QML view.
5048 QPointF QQuickItem::mapToItem(const QQuickItem *item, const QPointF &point) const
5050 QPointF p = mapToScene(point);
5052 p = item->mapFromScene(p);
5056 QPointF QQuickItem::mapToScene(const QPointF &point) const
5058 Q_D(const QQuickItem);
5059 return d->itemToCanvasTransform().map(point);
5062 QRectF QQuickItem::mapRectToItem(const QQuickItem *item, const QRectF &rect) const
5064 Q_D(const QQuickItem);
5065 QTransform t = d->itemToCanvasTransform();
5067 t *= QQuickItemPrivate::get(item)->canvasToItemTransform();
5068 return t.mapRect(rect);
5071 QRectF QQuickItem::mapRectToScene(const QRectF &rect) const
5073 Q_D(const QQuickItem);
5074 return d->itemToCanvasTransform().mapRect(rect);
5077 QPointF QQuickItem::mapFromItem(const QQuickItem *item, const QPointF &point) const
5079 QPointF p = item?item->mapToScene(point):point;
5080 return mapFromScene(p);
5083 QPointF QQuickItem::mapFromScene(const QPointF &point) const
5085 Q_D(const QQuickItem);
5086 return d->canvasToItemTransform().map(point);
5089 QRectF QQuickItem::mapRectFromItem(const QQuickItem *item, const QRectF &rect) const
5091 Q_D(const QQuickItem);
5092 QTransform t = item?QQuickItemPrivate::get(item)->itemToCanvasTransform():QTransform();
5093 t *= d->canvasToItemTransform();
5094 return t.mapRect(rect);
5097 QRectF QQuickItem::mapRectFromScene(const QRectF &rect) const
5099 Q_D(const QQuickItem);
5100 return d->canvasToItemTransform().mapRect(rect);
5105 \qmlmethod QtQuick2::Item::forceActiveFocus()
5107 Forces active focus on the item.
5109 This method sets focus on the item and makes sure that all the focus scopes
5110 higher in the object hierarchy are also given the focus.
5114 Forces active focus on the item.
5116 This method sets focus on the item and makes sure that all the focus scopes
5117 higher in the object hierarchy are also given the focus.
5121 \qmlmethod QtQuick2::Item::childAt(real x, real y)
5123 Returns the visible child item at point (\a x, \a y), which is in this
5124 item's coordinate system, or \c null if there is no such item.
5128 Returns the visible child item at point (\a x, \a y), which is in this
5129 item's coordinate system, or 0 if there is no such item.
5133 \qmlproperty list<State> QtQuick2::Item::states
5134 This property holds a list of states defined by the item.
5150 \sa {qmlstate}{States}
5153 \qmlproperty list<Transition> QtQuick2::Item::transitions
5154 This property holds a list of transitions defined by the item.
5170 \sa {QML Animation and Transitions}{Transitions}
5173 \qmlproperty list<Filter> QtQuick2::Item::filter
5174 This property holds a list of graphical filters to be applied to the item.
5176 \l {Filter}{Filters} include things like \l {Blur}{blurring}
5177 the item, or giving it a \l Reflection. Some
5178 filters may not be available on all canvases; if a filter is not
5179 available on a certain canvas, it will simply not be applied for
5180 that canvas (but the QML will still be considered valid).
5198 \qmlproperty bool QtQuick2::Item::clip
5199 This property holds whether clipping is enabled. The default clip value is \c false.
5201 If clipping is enabled, an item will clip its own painting, as well
5202 as the painting of its children, to its bounding rectangle.
5204 Non-rectangular clipping regions are not supported for performance reasons.
5208 \property QQuickItem::clip
5209 This property holds whether clipping is enabled. The default clip value is \c false.
5211 If clipping is enabled, an item will clip its own painting, as well
5212 as the painting of its children, to its bounding rectangle. If you set
5213 clipping during an item's paint operation, remember to re-set it to
5214 prevent clipping the rest of your scene.
5216 Non-rectangular clipping regions are not supported for performance reasons.
5220 \qmlproperty string QtQuick2::Item::state
5222 This property holds the name of the current state of the item.
5224 This property is often used in scripts to change between states. For
5229 if (button.state == 'On')
5230 button.state = 'Off';
5232 button.state = 'On';
5236 If the item is in its base state (i.e. no explicit state has been
5237 set), \c state will be a blank string. Likewise, you can return an
5238 item to its base state by setting its current state to \c ''.
5240 \sa {qmlstates}{States}
5244 \qmlproperty list<Transform> QtQuick2::Item::transform
5245 This property holds the list of transformations to apply.
5247 For more information see \l Transform.
5251 \enum QQuickItem::TransformOrigin
5253 Controls the point about which simple transforms like scale apply.
5255 \value TopLeft The top-left corner of the item.
5256 \value Top The center point of the top of the item.
5257 \value TopRight The top-right corner of the item.
5258 \value Left The left most point of the vertical middle.
5259 \value Center The center of the item.
5260 \value Right The right most point of the vertical middle.
5261 \value BottomLeft The bottom-left corner of the item.
5262 \value Bottom The center point of the bottom of the item.
5263 \value BottomRight The bottom-right corner of the item.
5268 \qmlproperty bool QtQuick2::Item::activeFocus
5270 This property indicates whether the item has active focus.
5272 An item with active focus will receive keyboard input,
5273 or is a FocusScope ancestor of the item that will receive keyboard input.
5275 Usually, activeFocus is gained by setting focus on an item and its enclosing
5276 FocusScopes. In the following example \c input will have activeFocus.
5289 \sa focus, {qmlfocus}{Keyboard Focus}
5293 \qmlproperty bool QtQuick2::Item::focus
5294 This property indicates whether the item has focus within the enclosing focus scope. If true, this item
5295 will gain active focus when the enclosing focus scope gains active focus.
5296 In the following example, \c input will be given active focus when \c scope gains active focus.
5309 For the purposes of this property, the scene as a whole is assumed to act like a focus scope.
5310 On a practical level, that means the following QML will give active focus to \c input on startup.
5321 \sa activeFocus, {qmlfocus}{Keyboard Focus}
5326 \property QQuickItem::anchors
5331 \property QQuickItem::left
5336 \property QQuickItem::right
5341 \property QQuickItem::horizontalCenter
5346 \property QQuickItem::top
5351 \property QQuickItem::bottom
5356 \property QQuickItem::verticalCenter
5361 \property QQuickItem::focus
5366 \property QQuickItem::transform
5371 \property QQuickItem::transformOrigin
5376 \property QQuickItem::activeFocus
5381 \property QQuickItem::baseline
5386 \property QQuickItem::data
5391 \property QQuickItem::resources
5396 \property QQuickItem::state
5401 \property QQuickItem::states
5406 \property QQuickItem::transformOriginPoint
5411 \property QQuickItem::transitions
5415 bool QQuickItem::event(QEvent *ev)
5418 if (ev->type() == QEvent::PolishRequest) {
5420 d->polishScheduled = false;
5424 return QObject::event(ev);
5427 if (ev->type() == QEvent::InputMethodQuery) {
5428 QInputMethodQueryEvent *query = static_cast<QInputMethodQueryEvent *>(ev);
5429 Qt::InputMethodQueries queries = query->queries();
5430 for (uint i = 0; i < 32; ++i) {
5431 Qt::InputMethodQuery q = (Qt::InputMethodQuery)(int)(queries & (1<<i));
5433 QVariant v = inputMethodQuery(q);
5434 query->setValue(q, v);
5439 } else if (ev->type() == QEvent::InputMethod) {
5440 inputMethodEvent(static_cast<QInputMethodEvent *>(ev));
5443 return QObject::event(ev);
5446 #ifndef QT_NO_DEBUG_STREAM
5447 QDebug operator<<(QDebug debug, QQuickItem *item)
5450 debug << "QQuickItem(0)";
5454 debug << item->metaObject()->className() << "(this =" << ((void*)item)
5455 << ", name=" << item->objectName()
5456 << ", parent =" << ((void*)item->parentItem())
5457 << ", geometry =" << QRectF(item->pos(), QSizeF(item->width(), item->height()))
5458 << ", z =" << item->z() << ')';
5463 qint64 QQuickItemPrivate::consistentTime = -1;
5464 void QQuickItemPrivate::setConsistentTime(qint64 t)
5469 class QElapsedTimerConsistentTimeHack
5473 t1 = QQuickItemPrivate::consistentTime;
5477 return QQuickItemPrivate::consistentTime - t1;
5480 qint64 val = QQuickItemPrivate::consistentTime - t1;
5481 t1 = QQuickItemPrivate::consistentTime;
5491 void QQuickItemPrivate::start(QElapsedTimer &t)
5493 if (QQuickItemPrivate::consistentTime == -1)
5496 ((QElapsedTimerConsistentTimeHack*)&t)->start();
5499 qint64 QQuickItemPrivate::elapsed(QElapsedTimer &t)
5501 if (QQuickItemPrivate::consistentTime == -1)
5504 return ((QElapsedTimerConsistentTimeHack*)&t)->elapsed();
5507 qint64 QQuickItemPrivate::restart(QElapsedTimer &t)
5509 if (QQuickItemPrivate::consistentTime == -1)
5512 return ((QElapsedTimerConsistentTimeHack*)&t)->restart();
5516 \fn bool QQuickItem::isTextureProvider() const
5518 Returns true if this item is a texture provider. The default
5519 implementation returns false.
5521 This function can be called from any thread.
5524 bool QQuickItem::isTextureProvider() const
5526 Q_D(const QQuickItem);
5527 return d->extra.isAllocated() && d->extra->layer && d->extra->layer->effectSource() ?
5528 d->extra->layer->effectSource()->isTextureProvider() : false;
5532 \fn QSGTextureProvider *QQuickItem::textureProvider() const
5534 Returns the texture provider for an item. The default implementation
5537 This function may only be called on the rendering thread.
5540 QSGTextureProvider *QQuickItem::textureProvider() const
5542 Q_D(const QQuickItem);
5543 return d->extra.isAllocated() && d->extra->layer && d->extra->layer->effectSource() ?
5544 d->extra->layer->effectSource()->textureProvider() : 0;
5547 QQuickItemLayer *QQuickItemPrivate::layer() const
5549 if (!extra.isAllocated() || !extra->layer) {
5550 extra.value().layer = new QQuickItemLayer(const_cast<QQuickItem *>(q_func()));
5551 if (!componentComplete)
5552 extra->layer->classBegin();
5554 return extra->layer;
5557 QQuickItemLayer::QQuickItemLayer(QQuickItem *item)
5562 , m_componentComplete(true)
5563 , m_wrapMode(QQuickShaderEffectSource::ClampToEdge)
5564 , m_format(QQuickShaderEffectSource::RGBA)
5566 , m_effectComponent(0)
5572 QQuickItemLayer::~QQuickItemLayer()
5574 delete m_effectSource;
5581 \qmlproperty bool QtQuick2::Item::layer.enabled
5583 Holds wether the item is layered or not. Layering is disabled by default.
5585 A layered item is rendered into an offscreen surface and cached until
5586 it is changed. Enabling layering for complex QML item hierarchies can
5587 some times be an optimization.
5589 None of the other layer properties have any effect when the layer
5593 void QQuickItemLayer::setEnabled(bool e)
5598 if (m_componentComplete) {
5605 emit enabledChanged(e);
5608 void QQuickItemLayer::classBegin()
5610 Q_ASSERT(!m_effectSource);
5611 Q_ASSERT(!m_effect);
5612 m_componentComplete = false;
5615 void QQuickItemLayer::componentComplete()
5617 Q_ASSERT(!m_componentComplete);
5618 m_componentComplete = true;
5623 void QQuickItemLayer::activate()
5625 Q_ASSERT(!m_effectSource);
5626 m_effectSource = new QQuickShaderEffectSource();
5628 QQuickItem *parentItem = m_item->parentItem();
5630 m_effectSource->setParentItem(parentItem);
5631 m_effectSource->stackAfter(m_item);
5634 m_effectSource->setSourceItem(m_item);
5635 m_effectSource->setHideSource(true);
5636 m_effectSource->setSmooth(m_smooth);
5637 m_effectSource->setTextureSize(m_size);
5638 m_effectSource->setSourceRect(m_sourceRect);
5639 m_effectSource->setMipmap(m_mipmap);
5640 m_effectSource->setWrapMode(m_wrapMode);
5641 m_effectSource->setFormat(m_format);
5643 if (m_effectComponent)
5646 m_effectSource->setVisible(m_item->isVisible() && !m_effect);
5653 QQuickItemPrivate *id = QQuickItemPrivate::get(m_item);
5654 id->addItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Opacity | QQuickItemPrivate::Parent | QQuickItemPrivate::Visibility | QQuickItemPrivate::SiblingOrder);
5657 void QQuickItemLayer::deactivate()
5659 Q_ASSERT(m_effectSource);
5661 if (m_effectComponent)
5664 delete m_effectSource;
5667 QQuickItemPrivate *id = QQuickItemPrivate::get(m_item);
5668 id->removeItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Opacity | QQuickItemPrivate::Parent | QQuickItemPrivate::Visibility | QQuickItemPrivate::SiblingOrder);
5671 void QQuickItemLayer::activateEffect()
5673 Q_ASSERT(m_effectSource);
5674 Q_ASSERT(m_effectComponent);
5675 Q_ASSERT(!m_effect);
5677 QObject *created = m_effectComponent->create();
5678 m_effect = qobject_cast<QQuickItem *>(created);
5680 qWarning("Item: layer.effect is not a QML Item.");
5684 QQuickItem *parentItem = m_item->parentItem();
5686 m_effect->setParentItem(parentItem);
5687 m_effect->stackAfter(m_effectSource);
5689 m_effect->setVisible(m_item->isVisible());
5690 m_effect->setProperty(m_name, qVariantFromValue<QObject *>(m_effectSource));
5693 void QQuickItemLayer::deactivateEffect()
5695 Q_ASSERT(m_effectSource);
5696 Q_ASSERT(m_effectComponent);
5704 \qmlproperty Component QtQuick2::Item::layer.effect
5706 Holds the effect that is applied to this layer.
5708 The effect is typically a \l ShaderEffect component, although any \l Item component can be
5709 assigned. The effect should have a source texture property with a name matching \l samplerName.
5714 void QQuickItemLayer::setEffect(QQmlComponent *component)
5716 if (component == m_effectComponent)
5719 bool updateNeeded = false;
5720 if (m_effectSource && m_effectComponent) {
5722 updateNeeded = true;
5725 m_effectComponent = component;
5727 if (m_effectSource && m_effectComponent) {
5729 updateNeeded = true;
5737 m_effectSource->setVisible(m_item->isVisible() && !m_effect);
5740 emit effectChanged(component);
5745 \qmlproperty bool QtQuick2::Item::layer.mipmap
5747 If this property is true, mipmaps are generated for the texture.
5749 \note Some OpenGL ES 2 implementations do not support mipmapping of
5750 non-power-of-two textures.
5753 void QQuickItemLayer::setMipmap(bool mipmap)
5755 if (mipmap == m_mipmap)
5760 m_effectSource->setMipmap(m_mipmap);
5762 emit mipmapChanged(mipmap);
5767 \qmlproperty enumeration QtQuick2::Item::layer.format
5769 This property defines the internal OpenGL format of the texture.
5770 Modifying this property makes most sense when the \a layer.effect is also
5771 specified. Depending on the OpenGL implementation, this property might
5772 allow you to save some texture memory.
5775 \li ShaderEffectSource.Alpha - GL_ALPHA
5776 \li ShaderEffectSource.RGB - GL_RGB
5777 \li ShaderEffectSource.RGBA - GL_RGBA
5780 \note Some OpenGL implementations do not support the GL_ALPHA format.
5783 void QQuickItemLayer::setFormat(QQuickShaderEffectSource::Format f)
5790 m_effectSource->setFormat(m_format);
5792 emit formatChanged(m_format);
5797 \qmlproperty enumeration QtQuick2::Item::layer.sourceRect
5799 This property defines which rectangular area of the \l sourceItem to
5800 render into the texture. The source rectangle can be larger than
5801 \l sourceItem itself. If the rectangle is null, which is the default,
5802 the whole \l sourceItem is rendered to texture.
5805 void QQuickItemLayer::setSourceRect(const QRectF &sourceRect)
5807 if (sourceRect == m_sourceRect)
5809 m_sourceRect = sourceRect;
5812 m_effectSource->setSourceRect(m_sourceRect);
5814 emit sourceRectChanged(sourceRect);
5820 \qmlproperty bool QtQuick2::Item::layer.smooth
5822 Holds whether the layer is smoothly transformed.
5825 void QQuickItemLayer::setSmooth(bool s)
5832 m_effectSource->setSmooth(m_smooth);
5834 emit smoothChanged(s);
5840 \qmlproperty size QtQuick2::Item::layer.textureSize
5842 This property holds the requested pixel size of the layers texture. If it is empty,
5843 which is the default, the size of the item is used.
5845 \note Some platforms have a limit on how small framebuffer objects can be,
5846 which means the actual texture size might be larger than the requested
5850 void QQuickItemLayer::setSize(const QSize &size)
5857 m_effectSource->setTextureSize(size);
5859 emit sizeChanged(size);
5865 \qmlproperty enumeration QtQuick2::Item::layer.wrapMode
5867 This property defines the OpenGL wrap modes associated with the texture.
5868 Modifying this property makes most sense when the \a layer.effect is
5872 \li ShaderEffectSource.ClampToEdge - GL_CLAMP_TO_EDGE both horizontally and vertically
5873 \li ShaderEffectSource.RepeatHorizontally - GL_REPEAT horizontally, GL_CLAMP_TO_EDGE vertically
5874 \li ShaderEffectSource.RepeatVertically - GL_CLAMP_TO_EDGE horizontally, GL_REPEAT vertically
5875 \li ShaderEffectSource.Repeat - GL_REPEAT both horizontally and vertically
5878 \note Some OpenGL ES 2 implementations do not support the GL_REPEAT
5879 wrap mode with non-power-of-two textures.
5882 void QQuickItemLayer::setWrapMode(QQuickShaderEffectSource::WrapMode mode)
5884 if (mode == m_wrapMode)
5889 m_effectSource->setWrapMode(m_wrapMode);
5891 emit wrapModeChanged(mode);
5895 \qmlproperty string QtQuick2::Item::layer.samplerName
5897 Holds the name of the effect's source texture property.
5899 samplerName needs to match the name of the effect's source texture property
5900 so that the Item can pass the layer's offscreen surface to the effect correctly.
5902 \sa effect, ShaderEffect
5905 void QQuickItemLayer::setName(const QByteArray &name) {
5909 m_effect->setProperty(m_name, QVariant());
5910 m_effect->setProperty(name, qVariantFromValue<QObject *>(m_effectSource));
5913 emit nameChanged(name);
5916 void QQuickItemLayer::itemOpacityChanged(QQuickItem *item)
5922 void QQuickItemLayer::itemGeometryChanged(QQuickItem *, const QRectF &, const QRectF &)
5927 void QQuickItemLayer::itemParentChanged(QQuickItem *item, QQuickItem *parent)
5930 Q_ASSERT(item == m_item);
5931 Q_ASSERT(parent != m_effectSource);
5932 Q_ASSERT(parent == 0 || parent != m_effect);
5934 m_effectSource->setParentItem(parent);
5936 m_effectSource->stackAfter(m_item);
5939 m_effect->setParentItem(parent);
5941 m_effect->stackAfter(m_effectSource);
5945 void QQuickItemLayer::itemSiblingOrderChanged(QQuickItem *)
5947 m_effectSource->stackAfter(m_item);
5949 m_effect->stackAfter(m_effectSource);
5952 void QQuickItemLayer::itemVisibilityChanged(QQuickItem *)
5954 QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
5956 l->setVisible(m_item->isVisible());
5959 void QQuickItemLayer::updateZ()
5961 if (!m_componentComplete || !m_enabled)
5963 QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
5965 l->setZ(m_item->z());
5968 void QQuickItemLayer::updateOpacity()
5970 QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
5972 l->setOpacity(m_item->opacity());
5975 void QQuickItemLayer::updateGeometry()
5977 QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
5979 QRectF bounds = m_item->boundingRect();
5980 l->setWidth(bounds.width());
5981 l->setHeight(bounds.height());
5982 l->setX(bounds.x() + m_item->x());
5983 l->setY(bounds.y() + m_item->y());
5986 void QQuickItemLayer::updateMatrix()
5988 // Called directly from transformChanged(), so needs some extra
5990 if (!m_componentComplete || !m_enabled)
5992 QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
5994 QQuickItemPrivate *ld = QQuickItemPrivate::get(l);
5995 l->setScale(m_item->scale());
5996 l->setRotation(m_item->rotation());
5997 ld->transforms = QQuickItemPrivate::get(m_item)->transforms;
5998 if (ld->origin() != QQuickItemPrivate::get(m_item)->origin())
5999 ld->extra.value().origin = QQuickItemPrivate::get(m_item)->origin();
6000 ld->dirty(QQuickItemPrivate::Transform);
6003 QQuickItemPrivate::ExtraData::ExtraData()
6004 : z(0), scale(1), rotation(0), opacity(1),
6005 contents(0), screenAttached(0), layoutDirectionAttached(0),
6006 keyHandler(0), layer(0), effectRefCount(0), hideRefCount(0),
6007 opacityNode(0), clipNode(0), rootNode(0), beforePaintNode(0),
6008 acceptedMouseButtons(0), origin(QQuickItem::Center)
6014 #include <moc_qquickitem.cpp>