1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the QtQml module of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #include "qquickitem.h"
44 #include "qquickcanvas.h"
45 #include <QtQml/qjsengine.h>
46 #include "qquickcanvas_p.h"
48 #include "qquickevents_p_p.h"
49 #include "qquickscreen_p.h"
51 #include <QtQml/qqmlengine.h>
52 #include <QtQml/qqmlcomponent.h>
53 #include <QtQml/qqmlinfo.h>
54 #include <QtGui/qpen.h>
55 #include <QtGui/qcursor.h>
56 #include <QtGui/qguiapplication.h>
57 #include <QtGui/qinputmethod.h>
58 #include <QtCore/qdebug.h>
59 #include <QtCore/qcoreevent.h>
60 #include <QtCore/qnumeric.h>
62 #include <private/qqmlglobal_p.h>
63 #include <private/qqmlengine_p.h>
64 #include <QtQuick/private/qquickstategroup_p.h>
65 #include <private/qqmlopenmetaobject_p.h>
66 #include <QtQuick/private/qquickstate_p.h>
67 #include <private/qlistmodelinterface_p.h>
68 #include <private/qquickitem_p.h>
69 #include <private/qqmlaccessors_p.h>
70 #include <QtQuick/private/qquickaccessibleattached_p.h>
74 // XXX todo Check that elements that create items handle memory correctly after visual ownership change
78 static void QQuickItem_parentNotifier(QObject *o, intptr_t, QQmlNotifier **n)
80 QQuickItemPrivate *d = QQuickItemPrivate::get(static_cast<QQuickItem *>(o));
81 *n = &d->parentNotifier;
84 QML_PRIVATE_ACCESSOR(QQuickItem, QQuickItem *, parent, parentItem)
85 QML_PRIVATE_ACCESSOR(QQuickItem, qreal, x, x)
86 QML_PRIVATE_ACCESSOR(QQuickItem, qreal, y, y)
87 QML_PRIVATE_ACCESSOR(QQuickItem, qreal, width, width)
88 QML_PRIVATE_ACCESSOR(QQuickItem, qreal, height, height)
90 static QQmlAccessors QQuickItem_parent = { QQuickItem_parentRead, QQuickItem_parentNotifier };
91 static QQmlAccessors QQuickItem_x = { QQuickItem_xRead, 0 };
92 static QQmlAccessors QQuickItem_y = { QQuickItem_yRead, 0 };
93 static QQmlAccessors QQuickItem_width = { QQuickItem_widthRead, 0 };
94 static QQmlAccessors QQuickItem_height = { QQuickItem_heightRead, 0 };
96 QML_DECLARE_PROPERTIES(QQuickItem) {
97 { QML_PROPERTY_NAME(parent), 0, &QQuickItem_parent },
98 { QML_PROPERTY_NAME(x), 0, &QQuickItem_x },
99 { QML_PROPERTY_NAME(y), 0, &QQuickItem_y },
100 { QML_PROPERTY_NAME(width), 0, &QQuickItem_width },
101 { QML_PROPERTY_NAME(height), 0, &QQuickItem_height }
104 void QQuickItemPrivate::registerAccessorProperties()
106 QML_DEFINE_PROPERTIES(QQuickItem);
110 \qmlclass Transform QQuickTransform
111 \inqmlmodule QtQuick 2
112 \ingroup qml-transform-elements
113 \brief The Transform elements provide a way of building advanced transformations on Items.
115 The Transform element is a base type which cannot be instantiated directly.
116 The following concrete Transform types are available:
124 The Transform elements let you create and control advanced transformations that can be configured
125 independently using specialized properties.
127 You can assign any number of Transform elements to an \l Item. Each Transform is applied in order,
132 \qmlclass Translate QQuickTranslate
133 \inqmlmodule QtQuick 2
134 \ingroup qml-transform-elements
135 \brief The Translate object provides a way to move an Item without changing its x or y properties.
137 The Translate object provides independent control over position in addition to the Item's x and y properties.
139 The following example moves the Y axis of the \l Rectangle elements while still allowing the \l Row element
140 to lay the items out as if they had not been transformed:
146 width: 100; height: 100
148 transform: Translate { y: 20 }
151 width: 100; height: 100
153 transform: Translate { y: -20 }
162 \qmlproperty real QtQuick2::Translate::x
164 The translation along the X axis.
168 \qmlproperty real QtQuick2::Translate::y
170 The translation along the Y axis.
174 \qmlclass Scale QQuickScale
175 \inqmlmodule QtQuick 2
176 \ingroup qml-transform-elements
177 \brief The Scale element provides a way to scale an Item.
179 The Scale element gives more control over scaling than using \l Item's \l{Item::scale}{scale} property. Specifically,
180 it allows a different scale for the x and y axes, and allows the scale to be relative to an
183 The following example scales the X axis of the Rectangle, relative to its interior point 25, 25:
186 width: 100; height: 100
188 transform: Scale { origin.x: 25; origin.y: 25; xScale: 3}
192 \sa Rotation, Translate
196 \qmlproperty real QtQuick2::Scale::origin.x
197 \qmlproperty real QtQuick2::Scale::origin.y
199 The point that the item is scaled from (i.e., the point that stays fixed relative to the parent as
200 the rest of the item grows). By default the origin is 0, 0.
204 \qmlproperty real QtQuick2::Scale::xScale
206 The scaling factor for the X axis.
210 \qmlproperty real QtQuick2::Scale::yScale
212 The scaling factor for the Y axis.
216 \qmlclass Rotation QQuickRotation
217 \inqmlmodule QtQuick 2
218 \ingroup qml-transform-elements
219 \brief The Rotation object provides a way to rotate an Item.
221 The Rotation object gives more control over rotation than using \l Item's \l{Item::rotation}{rotation} property.
222 Specifically, it allows (z axis) rotation to be relative to an arbitrary point.
224 The following example rotates a Rectangle around its interior point 25, 25:
227 width: 100; height: 100
229 transform: Rotation { origin.x: 25; origin.y: 25; angle: 45}
233 Rotation also provides a way to specify 3D-like rotations for Items. For these types of
234 rotations you must specify the axis to rotate around in addition to the origin point.
236 The following example shows various 3D-like rotations applied to an \l Image.
237 \snippet doc/src/snippets/qml/rotation.qml 0
239 \image axisrotation.png
241 \sa {declarative/ui-components/dialcontrol}{Dial Control example}, {declarative/toys/clocks}{Clocks example}
245 \qmlproperty real QtQuick2::Rotation::origin.x
246 \qmlproperty real QtQuick2::Rotation::origin.y
248 The origin point of the rotation (i.e., the point that stays fixed relative to the parent as
249 the rest of the item rotates). By default the origin is 0, 0.
253 \qmlproperty real QtQuick2::Rotation::axis.x
254 \qmlproperty real QtQuick2::Rotation::axis.y
255 \qmlproperty real QtQuick2::Rotation::axis.z
257 The axis to rotate around. For simple (2D) rotation around a point, you do not need to specify an axis,
258 as the default axis is the z axis (\c{ axis { x: 0; y: 0; z: 1 } }).
260 For a typical 3D-like rotation you will usually specify both the origin and the axis.
262 \image 3d-rotation-axis.png
266 \qmlproperty real QtQuick2::Rotation::angle
268 The angle to rotate, in degrees clockwise.
271 QQuickTransformPrivate::QQuickTransformPrivate()
275 QQuickTransform::QQuickTransform(QObject *parent)
276 : QObject(*(new QQuickTransformPrivate), parent)
280 QQuickTransform::QQuickTransform(QQuickTransformPrivate &dd, QObject *parent)
281 : QObject(dd, parent)
285 QQuickTransform::~QQuickTransform()
287 Q_D(QQuickTransform);
288 for (int ii = 0; ii < d->items.count(); ++ii) {
289 QQuickItemPrivate *p = QQuickItemPrivate::get(d->items.at(ii));
290 p->transforms.removeOne(this);
291 p->dirty(QQuickItemPrivate::Transform);
295 void QQuickTransform::update()
297 Q_D(QQuickTransform);
298 for (int ii = 0; ii < d->items.count(); ++ii) {
299 QQuickItemPrivate *p = QQuickItemPrivate::get(d->items.at(ii));
300 p->dirty(QQuickItemPrivate::Transform);
304 QQuickContents::QQuickContents(QQuickItem *item)
305 : m_item(item), m_x(0), m_y(0), m_width(0), m_height(0)
309 QQuickContents::~QQuickContents()
311 QList<QQuickItem *> children = m_item->childItems();
312 for (int i = 0; i < children.count(); ++i) {
313 QQuickItem *child = children.at(i);
314 QQuickItemPrivate::get(child)->removeItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed);
318 bool QQuickContents::calcHeight(QQuickItem *changed)
321 qreal oldheight = m_height;
325 qreal bottom = oldy + oldheight;
326 qreal y = changed->y();
327 if (y + changed->height() > bottom)
328 bottom = y + changed->height();
332 m_height = bottom - top;
336 QList<QQuickItem *> children = m_item->childItems();
337 for (int i = 0; i < children.count(); ++i) {
338 QQuickItem *child = children.at(i);
339 qreal y = child->y();
340 if (y + child->height() > bottom)
341 bottom = y + child->height();
345 if (!children.isEmpty())
347 m_height = qMax(bottom - top, qreal(0.0));
350 return (m_height != oldheight || m_y != oldy);
353 bool QQuickContents::calcWidth(QQuickItem *changed)
356 qreal oldwidth = m_width;
360 qreal right = oldx + oldwidth;
361 qreal x = changed->x();
362 if (x + changed->width() > right)
363 right = x + changed->width();
367 m_width = right - left;
369 qreal left = FLT_MAX;
371 QList<QQuickItem *> children = m_item->childItems();
372 for (int i = 0; i < children.count(); ++i) {
373 QQuickItem *child = children.at(i);
374 qreal x = child->x();
375 if (x + child->width() > right)
376 right = x + child->width();
380 if (!children.isEmpty())
382 m_width = qMax(right - left, qreal(0.0));
385 return (m_width != oldwidth || m_x != oldx);
388 void QQuickContents::complete()
390 QQuickItemPrivate::get(m_item)->addItemChangeListener(this, QQuickItemPrivate::Children);
392 QList<QQuickItem *> children = m_item->childItems();
393 for (int i = 0; i < children.count(); ++i) {
394 QQuickItem *child = children.at(i);
395 QQuickItemPrivate::get(child)->addItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed);
396 //###what about changes to visibility?
401 void QQuickContents::updateRect()
403 QQuickItemPrivate::get(m_item)->emitChildrenRectChanged(rectF());
406 void QQuickContents::itemGeometryChanged(QQuickItem *changed, const QRectF &newGeometry, const QRectF &oldGeometry)
409 bool wChanged = false;
410 bool hChanged = false;
411 //### we can only pass changed if the left edge has moved left, or the right edge has moved right
412 if (newGeometry.width() != oldGeometry.width() || newGeometry.x() != oldGeometry.x())
413 wChanged = calcWidth(/*changed*/);
414 if (newGeometry.height() != oldGeometry.height() || newGeometry.y() != oldGeometry.y())
415 hChanged = calcHeight(/*changed*/);
416 if (wChanged || hChanged)
420 void QQuickContents::itemDestroyed(QQuickItem *item)
423 QQuickItemPrivate::get(item)->removeItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed);
427 void QQuickContents::itemChildRemoved(QQuickItem *, QQuickItem *item)
430 QQuickItemPrivate::get(item)->removeItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed);
434 void QQuickContents::itemChildAdded(QQuickItem *, QQuickItem *item)
437 QQuickItemPrivate::get(item)->addItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed);
441 QQuickItemKeyFilter::QQuickItemKeyFilter(QQuickItem *item)
442 : m_processPost(false), m_next(0)
444 QQuickItemPrivate *p = item?QQuickItemPrivate::get(item):0;
446 m_next = p->extra.value().keyHandler;
447 p->extra->keyHandler = this;
451 QQuickItemKeyFilter::~QQuickItemKeyFilter()
455 void QQuickItemKeyFilter::keyPressed(QKeyEvent *event, bool post)
457 if (m_next) m_next->keyPressed(event, post);
460 void QQuickItemKeyFilter::keyReleased(QKeyEvent *event, bool post)
462 if (m_next) m_next->keyReleased(event, post);
465 void QQuickItemKeyFilter::inputMethodEvent(QInputMethodEvent *event, bool post)
468 m_next->inputMethodEvent(event, post);
473 QVariant QQuickItemKeyFilter::inputMethodQuery(Qt::InputMethodQuery query) const
475 if (m_next) return m_next->inputMethodQuery(query);
479 void QQuickItemKeyFilter::componentComplete()
481 if (m_next) m_next->componentComplete();
484 \qmlclass KeyNavigation QQuickKeyNavigationAttached
485 \inqmlmodule QtQuick 2
486 \ingroup qml-basic-interaction-elements
487 \brief The KeyNavigation attached property supports key navigation by arrow keys.
489 Key-based user interfaces commonly allow the use of arrow keys to navigate between
490 focusable items. The KeyNavigation attached property enables this behavior by providing a
491 convenient way to specify the item that should gain focus when an arrow or tab key is pressed.
493 The following example provides key navigation for a 2x2 grid of items:
495 \snippet doc/src/snippets/qml/keynavigation.qml 0
497 The top-left item initially receives focus by setting \l {Item::}{focus} to
498 \c true. When an arrow key is pressed, the focus will move to the
499 appropriate item, as defined by the value that has been set for
500 the KeyNavigation \l left, \l right, \l up or \l down properties.
502 Note that if a KeyNavigation attached property receives the key press and release
503 events for a requested arrow or tab key, the event is accepted and does not
504 propagate any further.
506 By default, KeyNavigation receives key events after the item to which it is attached.
507 If the item accepts the key event, the KeyNavigation attached property will not
508 receive an event for that key. Setting the \l priority property to
509 \c KeyNavigation.BeforeItem allows the event to be used for key navigation
510 before the item, rather than after.
512 If item to which the focus is switching is not enabled or visible, an attempt will
513 be made to skip this item and focus on the next. This is possible if there are
514 a chain of items with the same KeyNavigation handler. If multiple items in a row are not enabled
515 or visible, they will also be skipped.
517 KeyNavigation will implicitly set the other direction to return focus to this item. So if you set
518 \l left to another item, \l right will be set on that item's KeyNavigation to set focus back to this
519 item. However, if that item's KeyNavigation has had right explicitly set then no change will occur.
520 This means that the above example could have been written, with the same behaviour, without specifing
521 KeyNavigation.right or KeyNavigation.down for any of the items.
523 \sa {Keys}{Keys attached property}
527 \qmlproperty Item QtQuick2::KeyNavigation::left
528 \qmlproperty Item QtQuick2::KeyNavigation::right
529 \qmlproperty Item QtQuick2::KeyNavigation::up
530 \qmlproperty Item QtQuick2::KeyNavigation::down
531 \qmlproperty Item QtQuick2::KeyNavigation::tab
532 \qmlproperty Item QtQuick2::KeyNavigation::backtab
534 These properties hold the item to assign focus to
535 when the left, right, up or down cursor keys, or the
540 \qmlproperty Item QtQuick2::KeyNavigation::tab
541 \qmlproperty Item QtQuick2::KeyNavigation::backtab
543 These properties hold the item to assign focus to
544 when the Tab key or Shift+Tab key combination (Backtab) are pressed.
547 QQuickKeyNavigationAttached::QQuickKeyNavigationAttached(QObject *parent)
548 : QObject(*(new QQuickKeyNavigationAttachedPrivate), parent),
549 QQuickItemKeyFilter(qobject_cast<QQuickItem*>(parent))
551 m_processPost = true;
554 QQuickKeyNavigationAttached *
555 QQuickKeyNavigationAttached::qmlAttachedProperties(QObject *obj)
557 return new QQuickKeyNavigationAttached(obj);
560 QQuickItem *QQuickKeyNavigationAttached::left() const
562 Q_D(const QQuickKeyNavigationAttached);
566 void QQuickKeyNavigationAttached::setLeft(QQuickItem *i)
568 Q_D(QQuickKeyNavigationAttached);
573 QQuickKeyNavigationAttached* other =
574 qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
575 if (other && !other->d_func()->rightSet){
576 other->d_func()->right = qobject_cast<QQuickItem*>(parent());
577 emit other->rightChanged();
582 QQuickItem *QQuickKeyNavigationAttached::right() const
584 Q_D(const QQuickKeyNavigationAttached);
588 void QQuickKeyNavigationAttached::setRight(QQuickItem *i)
590 Q_D(QQuickKeyNavigationAttached);
595 QQuickKeyNavigationAttached* other =
596 qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
597 if (other && !other->d_func()->leftSet){
598 other->d_func()->left = qobject_cast<QQuickItem*>(parent());
599 emit other->leftChanged();
604 QQuickItem *QQuickKeyNavigationAttached::up() const
606 Q_D(const QQuickKeyNavigationAttached);
610 void QQuickKeyNavigationAttached::setUp(QQuickItem *i)
612 Q_D(QQuickKeyNavigationAttached);
617 QQuickKeyNavigationAttached* other =
618 qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
619 if (other && !other->d_func()->downSet){
620 other->d_func()->down = qobject_cast<QQuickItem*>(parent());
621 emit other->downChanged();
626 QQuickItem *QQuickKeyNavigationAttached::down() const
628 Q_D(const QQuickKeyNavigationAttached);
632 void QQuickKeyNavigationAttached::setDown(QQuickItem *i)
634 Q_D(QQuickKeyNavigationAttached);
639 QQuickKeyNavigationAttached* other =
640 qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
641 if (other && !other->d_func()->upSet) {
642 other->d_func()->up = qobject_cast<QQuickItem*>(parent());
643 emit other->upChanged();
648 QQuickItem *QQuickKeyNavigationAttached::tab() const
650 Q_D(const QQuickKeyNavigationAttached);
654 void QQuickKeyNavigationAttached::setTab(QQuickItem *i)
656 Q_D(QQuickKeyNavigationAttached);
661 QQuickKeyNavigationAttached* other =
662 qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
663 if (other && !other->d_func()->backtabSet) {
664 other->d_func()->backtab = qobject_cast<QQuickItem*>(parent());
665 emit other->backtabChanged();
670 QQuickItem *QQuickKeyNavigationAttached::backtab() const
672 Q_D(const QQuickKeyNavigationAttached);
676 void QQuickKeyNavigationAttached::setBacktab(QQuickItem *i)
678 Q_D(QQuickKeyNavigationAttached);
682 d->backtabSet = true;
683 QQuickKeyNavigationAttached* other =
684 qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
685 if (other && !other->d_func()->tabSet) {
686 other->d_func()->tab = qobject_cast<QQuickItem*>(parent());
687 emit other->tabChanged();
689 emit backtabChanged();
693 \qmlproperty enumeration QtQuick2::KeyNavigation::priority
695 This property determines whether the keys are processed before
696 or after the attached item's own key handling.
699 \o 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 \o 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 \o Items specified in \c forwardTo
937 \o specific key handlers, e.g. onReturnPressed
938 \o onKeyPress, onKeyRelease handlers
939 \o Item specific key handling, e.g. TextInput key handling
943 If priority is Keys.AfterItem the order of key event processing is:
946 \o Item specific key handling, e.g. TextInput key handling
947 \o Items specified in \c forwardTo
948 \o specific key handlers, e.g. onReturnPressed
949 \o 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 \o 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 \o 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;
1626 \brief The QQuickItem class provides the most basic of all visual items in QML.
1630 All visual items in Qt Quick inherit from QQuickItem. Although QQuickItem
1631 has no visual appearance, it defines all the properties that are
1632 common across visual items - such as the x and y position, the
1633 width and height, \l {anchor-layout}{anchoring} and key handling.
1635 You can subclass QQuickItem to provide your own custom visual item that inherits
1636 these features. Note that, because it does not draw anything, QQuickItem sets the
1637 QGraphicsItem::ItemHasNoContents flag. If you subclass QQuickItem to create a visual
1638 item, you will need to unset this flag.
1643 \qmlclass Item QQuickItem
1645 \inqmlmodule QtQuick 2
1646 \ingroup qml-basic-visual-elements
1647 \brief The Item is the most basic of all visual items in QML.
1649 All visual items in Qt Quick inherit from Item. Although Item
1650 has no visual appearance, it defines all the properties that are
1651 common across visual items - such as the x and y position, the
1652 width and height, \l {anchor-layout}{anchoring} and key handling.
1654 Item is also useful for grouping items together.
1671 fillMode: Image.Tile
1678 \section1 Key Handling
1680 Key handling is available to all Item-based visual elements via the \l {Keys}{Keys}
1681 attached property. The \e Keys attached property provides basic handlers such
1682 as \l {Keys::onPressed}{onPressed} and \l {Keys::onReleased}{onReleased},
1683 as well as handlers for specific keys, such as
1684 \l {Keys::onCancelPressed}{onCancelPressed}. The example below
1685 assigns \l {qmlfocus}{focus} to the item and handles
1686 the Left key via the general \e onPressed handler and the Select key via the
1687 onSelectPressed handler:
1693 if (event.key == Qt.Key_Left) {
1694 console.log("move left");
1695 event.accepted = true;
1698 Keys.onSelectPressed: console.log("Selected");
1702 See the \l {Keys}{Keys} attached property for detailed documentation.
1704 \section1 Layout Mirroring
1706 Item layouts can be mirrored using the \l {LayoutMirroring}{LayoutMirroring} attached property.
1711 \fn void QQuickItem::childrenRectChanged(const QRectF &)
1716 \fn void QQuickItem::baselineOffsetChanged(qreal)
1721 \fn void QQuickItem::stateChanged(const QString &state)
1726 \fn void QQuickItem::parentChanged(QQuickItem *)
1731 \fn void QQuickItem::smoothChanged(bool)
1736 \fn void QQuickItem::clipChanged(bool)
1740 /*! \fn void QQuickItem::transformOriginChanged(TransformOrigin)
1745 \fn void QQuickItem::focusChanged(bool)
1750 \fn void QQuickItem::activeFocusChanged(bool)
1754 \fn QQuickItem::QQuickItem(QQuickItem *parent)
1756 Constructs a QQuickItem with the given \a parent.
1758 QQuickItem::QQuickItem(QQuickItem* parent)
1759 : QObject(*(new QQuickItemPrivate), parent)
1767 QQuickItem::QQuickItem(QQuickItemPrivate &dd, QQuickItem *parent)
1768 : QObject(dd, parent)
1775 static int qt_item_count = 0;
1777 static void qt_print_item_count()
1779 qDebug("Number of leaked items: %i", qt_item_count);
1785 Destroys the QQuickItem.
1787 QQuickItem::~QQuickItem()
1791 if (qt_item_count < 0)
1792 qDebug("Item destroyed after qt_print_item_count() was called.");
1799 else if (d->canvas && d->itemNodeInstance)
1800 QQuickCanvasPrivate::get(d->canvas)->cleanup(d->itemNodeInstance); // cleanup root
1801 // XXX todo - optimize
1802 while (!d->childItems.isEmpty())
1803 d->childItems.first()->setParentItem(0);
1805 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
1806 QQuickAnchorsPrivate *anchor = d->changeListeners.at(ii).listener->anchorPrivate();
1808 anchor->clearItem(this);
1812 update item anchors that depended on us unless they are our child (and will also be destroyed),
1813 or our sibling, and our parent is also being destroyed.
1815 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
1816 QQuickAnchorsPrivate *anchor = d->changeListeners.at(ii).listener->anchorPrivate();
1817 if (anchor && anchor->item && anchor->item->parentItem() && anchor->item->parentItem() != this)
1821 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
1822 const QQuickItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
1823 if (change.types & QQuickItemPrivate::Destroyed)
1824 change.listener->itemDestroyed(this);
1827 d->changeListeners.clear();
1829 if (d->extra.isAllocated()) {
1830 delete d->extra->contents; d->extra->contents = 0;
1831 delete d->extra->layer; d->extra->layer = 0;
1834 delete d->_anchors; d->_anchors = 0;
1835 delete d->_stateGroup; d->_stateGroup = 0;
1839 \qmlproperty enumeration QtQuick2::Item::transformOrigin
1840 This property holds the origin point around which scale and rotation transform.
1842 Nine transform origins are available, as shown in the image below.
1844 \image declarative-transformorigin.png
1846 This example rotates an image around its bottom-right corner.
1849 source: "myimage.png"
1850 transformOrigin: Item.BottomRight
1855 The default transform origin is \c Item.Center.
1857 To set an arbitrary transform origin point use the \l Scale or \l Rotation
1862 \qmlproperty Item QtQuick2::Item::parent
1863 This property holds the parent of the item.
1867 \property QQuickItem::parent
1868 This property holds the parent of the item.
1870 void QQuickItem::setParentItem(QQuickItem *parentItem)
1873 if (parentItem == d->parentItem)
1877 QQuickItem *itemAncestor = parentItem->parentItem();
1878 while (itemAncestor != 0) {
1879 if (itemAncestor == this) {
1880 qWarning("QQuickItem::setParentItem: Parent is already part of this items subtree.");
1883 itemAncestor = itemAncestor->parentItem();
1887 d->removeFromDirtyList();
1889 QQuickItem *oldParentItem = d->parentItem;
1890 QQuickItem *scopeFocusedItem = 0;
1892 if (oldParentItem) {
1893 QQuickItemPrivate *op = QQuickItemPrivate::get(oldParentItem);
1895 QQuickItem *scopeItem = 0;
1897 if (d->canvas && hasFocus()) {
1898 scopeItem = oldParentItem;
1899 while (!scopeItem->isFocusScope()) scopeItem = scopeItem->parentItem();
1900 scopeFocusedItem = this;
1901 } else if (d->canvas && !isFocusScope() && d->subFocusItem) {
1902 scopeItem = oldParentItem;
1903 while (!scopeItem->isFocusScope()) scopeItem = scopeItem->parentItem();
1904 scopeFocusedItem = d->subFocusItem;
1907 if (scopeFocusedItem)
1908 QQuickCanvasPrivate::get(d->canvas)->clearFocusInScope(scopeItem, scopeFocusedItem,
1909 QQuickCanvasPrivate::DontChangeFocusProperty);
1911 const bool wasVisible = isVisible();
1912 op->removeChild(this);
1914 emit oldParentItem->visibleChildrenChanged();
1916 } else if (d->canvas) {
1917 QQuickCanvasPrivate::get(d->canvas)->parentlessItems.remove(this);
1920 d->parentItem = parentItem;
1922 QQuickCanvas *parentCanvas = parentItem?QQuickItemPrivate::get(parentItem)->canvas:0;
1923 if (d->canvas != parentCanvas) {
1924 QQuickItemPrivate::InitializationState initState;
1926 d->initCanvas(&initState, parentCanvas);
1929 d->dirty(QQuickItemPrivate::ParentChanged);
1932 QQuickItemPrivate::get(d->parentItem)->addChild(this);
1934 d->setEffectiveVisibleRecur(d->calcEffectiveVisible());
1935 d->setEffectiveEnableRecur(0, d->calcEffectiveEnable());
1937 if (scopeFocusedItem && d->parentItem && d->canvas) {
1938 // We need to test whether this item becomes scope focused
1939 QQuickItem *scopeItem = 0;
1940 scopeItem = d->parentItem;
1941 while (!scopeItem->isFocusScope()) scopeItem = scopeItem->parentItem();
1943 if (scopeItem->scopedFocusItem()) {
1944 QQuickItemPrivate::get(scopeFocusedItem)->focus = false;
1945 emit scopeFocusedItem->focusChanged(false);
1947 QQuickCanvasPrivate::get(d->canvas)->setFocusInScope(scopeItem, scopeFocusedItem,
1948 QQuickCanvasPrivate::DontChangeFocusProperty);
1952 d->resolveLayoutMirror();
1954 d->itemChange(ItemParentHasChanged, d->parentItem);
1956 d->parentNotifier.notify();
1957 if (d->isAccessible && d->parentItem) {
1958 d->parentItem->d_func()->setAccessibleFlagAndListener();
1961 emit parentChanged(d->parentItem);
1962 if (isVisible() && d->parentItem)
1963 emit d->parentItem->visibleChildrenChanged();
1966 void QQuickItem::stackBefore(const QQuickItem *sibling)
1969 if (!sibling || sibling == this || !d->parentItem || d->parentItem != QQuickItemPrivate::get(sibling)->parentItem) {
1970 qWarning("QQuickItem::stackBefore: Cannot stack before %p, which must be a sibling", sibling);
1974 QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(d->parentItem);
1976 int myIndex = parentPrivate->childItems.indexOf(this);
1977 int siblingIndex = parentPrivate->childItems.indexOf(const_cast<QQuickItem *>(sibling));
1979 Q_ASSERT(myIndex != -1 && siblingIndex != -1);
1981 if (myIndex == siblingIndex - 1)
1984 parentPrivate->childItems.removeAt(myIndex);
1986 if (myIndex < siblingIndex) --siblingIndex;
1988 parentPrivate->childItems.insert(siblingIndex, this);
1990 parentPrivate->dirty(QQuickItemPrivate::ChildrenStackingChanged);
1991 parentPrivate->markSortedChildrenDirty(this);
1993 for (int ii = qMin(siblingIndex, myIndex); ii < parentPrivate->childItems.count(); ++ii)
1994 QQuickItemPrivate::get(parentPrivate->childItems.at(ii))->siblingOrderChanged();
1997 void QQuickItem::stackAfter(const QQuickItem *sibling)
2000 if (!sibling || sibling == this || !d->parentItem || d->parentItem != QQuickItemPrivate::get(sibling)->parentItem) {
2001 qWarning("QQuickItem::stackAfter: Cannot stack after %p, which must be a sibling", sibling);
2005 QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(d->parentItem);
2007 int myIndex = parentPrivate->childItems.indexOf(this);
2008 int siblingIndex = parentPrivate->childItems.indexOf(const_cast<QQuickItem *>(sibling));
2010 Q_ASSERT(myIndex != -1 && siblingIndex != -1);
2012 if (myIndex == siblingIndex + 1)
2015 parentPrivate->childItems.removeAt(myIndex);
2017 if (myIndex < siblingIndex) --siblingIndex;
2019 parentPrivate->childItems.insert(siblingIndex + 1, this);
2021 parentPrivate->dirty(QQuickItemPrivate::ChildrenStackingChanged);
2022 parentPrivate->markSortedChildrenDirty(this);
2024 for (int ii = qMin(myIndex, siblingIndex + 1); ii < parentPrivate->childItems.count(); ++ii)
2025 QQuickItemPrivate::get(parentPrivate->childItems.at(ii))->siblingOrderChanged();
2029 Returns the QQuickItem parent of this item.
2031 QQuickItem *QQuickItem::parentItem() const
2033 Q_D(const QQuickItem);
2034 return d->parentItem;
2037 QSGEngine *QQuickItem::sceneGraphEngine() const
2039 return canvas()->sceneGraphEngine();
2042 QQuickCanvas *QQuickItem::canvas() const
2044 Q_D(const QQuickItem);
2048 static bool itemZOrder_sort(QQuickItem *lhs, QQuickItem *rhs)
2050 return lhs->z() < rhs->z();
2053 QList<QQuickItem *> QQuickItemPrivate::paintOrderChildItems() const
2055 if (sortedChildItems)
2056 return *sortedChildItems;
2058 // If none of the items have set Z then the paint order list is the same as
2059 // the childItems list. This is by far the most common case.
2061 for (int i = 0; i < childItems.count(); ++i) {
2062 if (QQuickItemPrivate::get(childItems.at(i))->z() != 0.) {
2068 sortedChildItems = new QList<QQuickItem*>(childItems);
2069 qStableSort(sortedChildItems->begin(), sortedChildItems->end(), itemZOrder_sort);
2070 return *sortedChildItems;
2073 sortedChildItems = const_cast<QList<QQuickItem*>*>(&childItems);
2078 void QQuickItemPrivate::addChild(QQuickItem *child)
2082 Q_ASSERT(!childItems.contains(child));
2084 childItems.append(child);
2086 markSortedChildrenDirty(child);
2087 dirty(QQuickItemPrivate::ChildrenChanged);
2089 itemChange(QQuickItem::ItemChildAddedChange, child);
2091 emit q->childrenChanged();
2094 void QQuickItemPrivate::removeChild(QQuickItem *child)
2099 Q_ASSERT(childItems.contains(child));
2100 childItems.removeOne(child);
2101 Q_ASSERT(!childItems.contains(child));
2103 markSortedChildrenDirty(child);
2104 dirty(QQuickItemPrivate::ChildrenChanged);
2106 itemChange(QQuickItem::ItemChildRemovedChange, child);
2108 emit q->childrenChanged();
2111 void QQuickItemPrivate::InitializationState::clear()
2116 void QQuickItemPrivate::InitializationState::clear(QQuickItem *fs)
2121 QQuickItem *QQuickItemPrivate::InitializationState::getFocusScope(QQuickItem *item)
2124 QQuickItem *fs = item->parentItem();
2125 while (fs->parentItem() && !fs->isFocusScope())
2126 fs = fs->parentItem();
2132 void QQuickItemPrivate::initCanvas(InitializationState *state, QQuickCanvas *c)
2137 removeFromDirtyList();
2138 QQuickCanvasPrivate *c = QQuickCanvasPrivate::get(canvas);
2139 if (polishScheduled)
2140 c->itemsToPolish.remove(q);
2141 if (c->mouseGrabberItem == q)
2142 c->mouseGrabberItem = 0;
2144 c->hoverItems.removeAll(q);
2145 if (itemNodeInstance)
2146 c->cleanup(itemNodeInstance);
2148 c->parentlessItems.remove(q);
2153 if (canvas && polishScheduled)
2154 QQuickCanvasPrivate::get(canvas)->itemsToPolish.insert(q);
2156 itemNodeInstance = 0;
2158 if (extra.isAllocated()) {
2159 extra->opacityNode = 0;
2160 extra->clipNode = 0;
2161 extra->rootNode = 0;
2162 extra->beforePaintNode = 0;
2168 InitializationState _dummy;
2169 InitializationState *childState = state;
2171 if (c && q->isFocusScope()) {
2173 childState = &_dummy;
2176 if (!parentItem && canvas)
2177 QQuickCanvasPrivate::get(canvas)->parentlessItems.insert(q);
2179 for (int ii = 0; ii < childItems.count(); ++ii) {
2180 QQuickItem *child = childItems.at(ii);
2181 QQuickItemPrivate::get(child)->initCanvas(childState, c);
2186 if (state->getFocusScope(q)->scopedFocusItem()) {
2188 emit q->focusChanged(false);
2190 QQuickCanvasPrivate::get(canvas)->setFocusInScope(state->getFocusScope(q), q);
2196 if (extra.isAllocated() && extra->screenAttached)
2197 extra->screenAttached->canvasChanged(c);
2198 itemChange(QQuickItem::ItemSceneChange, c);
2202 Returns a transform that maps points from canvas space into item space.
2204 QTransform QQuickItemPrivate::canvasToItemTransform() const
2206 // XXX todo - optimize
2207 return itemToCanvasTransform().inverted();
2211 Returns a transform that maps points from item space into canvas space.
2213 QTransform QQuickItemPrivate::itemToCanvasTransform() const
2216 QTransform rv = parentItem?QQuickItemPrivate::get(parentItem)->itemToCanvasTransform():QTransform();
2217 itemToParentTransform(rv);
2222 Motifies \a t with this items local transform relative to its parent.
2224 void QQuickItemPrivate::itemToParentTransform(QTransform &t) const
2229 if (!transforms.isEmpty()) {
2231 for (int ii = transforms.count() - 1; ii >= 0; --ii)
2232 transforms.at(ii)->applyTo(&m);
2233 t = m.toTransform();
2236 if (scale() != 1. || rotation() != 0.) {
2237 QPointF tp = computeTransformOrigin();
2238 t.translate(tp.x(), tp.y());
2239 t.scale(scale(), scale());
2240 t.rotate(rotation());
2241 t.translate(-tp.x(), -tp.y());
2247 \qmlproperty real QtQuick2::Item::childrenRect.x
2248 \qmlproperty real QtQuick2::Item::childrenRect.y
2249 \qmlproperty real QtQuick2::Item::childrenRect.width
2250 \qmlproperty real QtQuick2::Item::childrenRect.height
2252 The childrenRect properties allow an item access to the geometry of its
2253 children. This property is useful if you have an item that needs to be
2254 sized to fit its children.
2259 \qmlproperty list<Item> QtQuick2::Item::children
2260 \qmlproperty list<Object> QtQuick2::Item::resources
2262 The children property contains the list of visual children of this item.
2263 The resources property contains non-visual resources that you want to
2266 Generally you can rely on Item's default property to handle all this for
2267 you, but it can come in handy in some cases.
2286 Returns true if construction of the QML component is complete; otherwise
2289 It is often desirable to delay some processing until the component is
2292 \sa componentComplete()
2294 bool QQuickItem::isComponentComplete() const
2296 Q_D(const QQuickItem);
2297 return d->componentComplete;
2300 QQuickItemPrivate::QQuickItemPrivate()
2301 : _anchors(0), _stateGroup(0),
2302 flags(0), widthValid(false), heightValid(false), baselineOffsetValid(false), componentComplete(true),
2303 keepMouse(false), keepTouch(false), hoverEnabled(false), smooth(false), focus(false), activeFocus(false), notifiedFocus(false),
2304 notifiedActiveFocus(false), filtersChildMouseEvents(false), explicitVisible(true),
2305 effectiveVisible(true), explicitEnable(true), effectiveEnable(true), polishScheduled(false),
2306 inheritedLayoutMirror(false), effectiveLayoutMirror(false), isMirrorImplicit(true),
2307 inheritMirrorFromParent(false), inheritMirrorFromItem(false), childrenDoNotOverlap(false),
2308 staticSubtreeGeometry(false),
2309 isAccessible(false),
2311 dirtyAttributes(0), nextDirtyItem(0), prevDirtyItem(0),
2313 canvas(0), parentItem(0), sortedChildItems(&childItems),
2317 x(0), y(0), width(0), height(0), implicitWidth(0), implicitHeight(0),
2321 itemNodeInstance(0), groupNode(0), paintNode(0)
2325 QQuickItemPrivate::~QQuickItemPrivate()
2327 if (sortedChildItems != &childItems)
2328 delete sortedChildItems;
2331 void QQuickItemPrivate::init(QQuickItem *parent)
2335 static bool atexit_registered = false;
2336 if (!atexit_registered) {
2337 atexit(qt_print_item_count);
2338 atexit_registered = true;
2344 registerAccessorProperties();
2346 baselineOffsetValid = false;
2349 q->setParentItem(parent);
2350 QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(parent);
2351 setImplicitLayoutMirror(parentPrivate->inheritedLayoutMirror, parentPrivate->inheritMirrorFromParent);
2355 void QQuickItemPrivate::data_append(QQmlListProperty<QObject> *prop, QObject *o)
2360 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2362 // This test is measurably (albeit only slightly) faster than qobject_cast<>()
2363 const QMetaObject *mo = o->metaObject();
2364 while (mo && mo != &QQuickItem::staticMetaObject) {
2365 mo = mo->d.superdata;
2369 QQuickItem *item = static_cast<QQuickItem *>(o);
2370 item->setParentItem(that);
2372 if (o->inherits("QGraphicsItem"))
2373 qWarning("Cannot add a QtQuick 1.0 item (%s) into a QtQuick 2.0 scene!", o->metaObject()->className());
2375 // XXX todo - do we really want this behavior?
2381 \qmlproperty list<Object> QtQuick2::Item::data
2384 The data property allows you to freely mix visual children and resources
2385 in an item. If you assign a visual item to the data list it becomes
2386 a child and if you assign any other object type, it is added as a resource.
2410 data is a behind-the-scenes property: you should never need to explicitly
2414 int QQuickItemPrivate::data_count(QQmlListProperty<QObject> *prop)
2421 QObject *QQuickItemPrivate::data_at(QQmlListProperty<QObject> *prop, int i)
2429 void QQuickItemPrivate::data_clear(QQmlListProperty<QObject> *prop)
2435 QObject *QQuickItemPrivate::resources_at(QQmlListProperty<QObject> *prop, int index)
2437 const QObjectList children = prop->object->children();
2438 if (index < children.count())
2439 return children.at(index);
2444 void QQuickItemPrivate::resources_append(QQmlListProperty<QObject> *prop, QObject *o)
2446 // XXX todo - do we really want this behavior?
2447 o->setParent(prop->object);
2450 int QQuickItemPrivate::resources_count(QQmlListProperty<QObject> *prop)
2452 return prop->object->children().count();
2455 void QQuickItemPrivate::resources_clear(QQmlListProperty<QObject> *prop)
2457 // XXX todo - do we really want this behavior?
2458 const QObjectList children = prop->object->children();
2459 for (int index = 0; index < children.count(); index++)
2460 children.at(index)->setParent(0);
2463 QQuickItem *QQuickItemPrivate::children_at(QQmlListProperty<QQuickItem> *prop, int index)
2465 QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2466 if (index >= p->childItems.count() || index < 0)
2469 return p->childItems.at(index);
2472 void QQuickItemPrivate::children_append(QQmlListProperty<QQuickItem> *prop, QQuickItem *o)
2477 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2478 if (o->parentItem() == that)
2479 o->setParentItem(0);
2481 o->setParentItem(that);
2484 int QQuickItemPrivate::children_count(QQmlListProperty<QQuickItem> *prop)
2486 QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2487 return p->childItems.count();
2490 void QQuickItemPrivate::children_clear(QQmlListProperty<QQuickItem> *prop)
2492 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2493 QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2494 while (!p->childItems.isEmpty())
2495 p->childItems.at(0)->setParentItem(0);
2498 void QQuickItemPrivate::visibleChildren_append(QQmlListProperty<QQuickItem>*, QQuickItem *self)
2501 qmlInfo(self) << "QQuickItem: visibleChildren property is readonly and cannot be assigned to.";
2504 int QQuickItemPrivate::visibleChildren_count(QQmlListProperty<QQuickItem> *prop)
2506 QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2507 int visibleCount = 0;
2508 int c = p->childItems.count();
2510 if (p->childItems.at(c)->isVisible()) visibleCount++;
2513 return visibleCount;
2516 QQuickItem *QQuickItemPrivate::visibleChildren_at(QQmlListProperty<QQuickItem> *prop, int index)
2518 QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2519 const int childCount = p->childItems.count();
2520 if (index >= childCount || index < 0)
2523 int visibleCount = -1;
2524 for (int i = 0; i < childCount; i++) {
2525 if (p->childItems.at(i)->isVisible()) visibleCount++;
2526 if (visibleCount == index) return p->childItems.at(i);
2531 int QQuickItemPrivate::transform_count(QQmlListProperty<QQuickTransform> *prop)
2533 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2534 QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2536 return p->transforms.count();
2539 void QQuickTransform::appendToItem(QQuickItem *item)
2541 Q_D(QQuickTransform);
2545 QQuickItemPrivate *p = QQuickItemPrivate::get(item);
2547 if (!d->items.isEmpty() && !p->transforms.isEmpty() && p->transforms.contains(this)) {
2548 p->transforms.removeOne(this);
2549 p->transforms.append(this);
2551 p->transforms.append(this);
2552 d->items.append(item);
2555 p->dirty(QQuickItemPrivate::Transform);
2558 void QQuickTransform::prependToItem(QQuickItem *item)
2560 Q_D(QQuickTransform);
2564 QQuickItemPrivate *p = QQuickItemPrivate::get(item);
2566 if (!d->items.isEmpty() && !p->transforms.isEmpty() && p->transforms.contains(this)) {
2567 p->transforms.removeOne(this);
2568 p->transforms.prepend(this);
2570 p->transforms.prepend(this);
2571 d->items.append(item);
2574 p->dirty(QQuickItemPrivate::Transform);
2577 void QQuickItemPrivate::transform_append(QQmlListProperty<QQuickTransform> *prop, QQuickTransform *transform)
2582 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2583 transform->appendToItem(that);
2586 QQuickTransform *QQuickItemPrivate::transform_at(QQmlListProperty<QQuickTransform> *prop, int idx)
2588 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2589 QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2591 if (idx < 0 || idx >= p->transforms.count())
2594 return p->transforms.at(idx);
2597 void QQuickItemPrivate::transform_clear(QQmlListProperty<QQuickTransform> *prop)
2599 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2600 QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2602 for (int ii = 0; ii < p->transforms.count(); ++ii) {
2603 QQuickTransform *t = p->transforms.at(ii);
2604 QQuickTransformPrivate *tp = QQuickTransformPrivate::get(t);
2605 tp->items.removeOne(that);
2608 p->transforms.clear();
2610 p->dirty(QQuickItemPrivate::Transform);
2614 \property QQuickItem::childrenRect
2615 \brief The geometry of an item's children.
2617 This property holds the (collective) position and size of the item's children.
2621 \qmlproperty real QtQuick2::Item::x
2622 \qmlproperty real QtQuick2::Item::y
2623 \qmlproperty real QtQuick2::Item::width
2624 \qmlproperty real QtQuick2::Item::height
2626 Defines the item's position and size relative to its parent.
2629 Item { x: 100; y: 100; width: 100; height: 100 }
2634 \qmlproperty real QtQuick2::Item::z
2636 Sets the stacking order of sibling items. By default the stacking order is 0.
2638 Items with a higher stacking value are drawn on top of siblings with a
2639 lower stacking order. Items with the same stacking value are drawn
2640 bottom up in the order they appear. Items with a negative stacking
2641 value are drawn under their parent's content.
2643 The following example shows the various effects of stacking order.
2647 \o \image declarative-item_stacking1.png
2648 \o Same \c z - later children above earlier children:
2653 width: 100; height: 100
2657 x: 50; y: 50; width: 100; height: 100
2662 \o \image declarative-item_stacking2.png
2663 \o Higher \c z on top:
2669 width: 100; height: 100
2673 x: 50; y: 50; width: 100; height: 100
2678 \o \image declarative-item_stacking3.png
2679 \o Same \c z - children above parents:
2684 width: 100; height: 100
2687 x: 50; y: 50; width: 100; height: 100
2693 \o \image declarative-item_stacking4.png
2694 \o Lower \c z below:
2699 width: 100; height: 100
2703 x: 50; y: 50; width: 100; height: 100
2712 \qmlproperty bool QtQuick2::Item::visible
2714 This property holds whether the item is visible. By default this is true.
2716 Setting this property directly affects the \c visible value of child
2717 items. When set to \c false, the \c visible values of all child items also
2718 become \c false. When set to \c true, the \c visible values of child items
2719 are returned to \c true, unless they have explicitly been set to \c false.
2721 (Because of this flow-on behavior, using the \c visible property may not
2722 have the intended effect if a property binding should only respond to
2723 explicit property changes. In such cases it may be better to use the
2724 \l opacity property instead.)
2726 Setting this property to \c false automatically causes \l focus to be set
2727 to \c false, and this item will longer receive mouse and keyboard events.
2728 (In contrast, setting the \l opacity to 0 does not affect the \l focus
2729 property and the receiving of key events.)
2731 \note This property's value is only affected by changes to this property or
2732 the parent's \c visible property. It does not change, for example, if this
2733 item moves off-screen, or if the \l opacity changes to 0.
2738 \qmlproperty AnchorLine QtQuick2::Item::anchors.top
2739 \qmlproperty AnchorLine QtQuick2::Item::anchors.bottom
2740 \qmlproperty AnchorLine QtQuick2::Item::anchors.left
2741 \qmlproperty AnchorLine QtQuick2::Item::anchors.right
2742 \qmlproperty AnchorLine QtQuick2::Item::anchors.horizontalCenter
2743 \qmlproperty AnchorLine QtQuick2::Item::anchors.verticalCenter
2744 \qmlproperty AnchorLine QtQuick2::Item::anchors.baseline
2746 \qmlproperty Item QtQuick2::Item::anchors.fill
2747 \qmlproperty Item QtQuick2::Item::anchors.centerIn
2749 \qmlproperty real QtQuick2::Item::anchors.margins
2750 \qmlproperty real QtQuick2::Item::anchors.topMargin
2751 \qmlproperty real QtQuick2::Item::anchors.bottomMargin
2752 \qmlproperty real QtQuick2::Item::anchors.leftMargin
2753 \qmlproperty real QtQuick2::Item::anchors.rightMargin
2754 \qmlproperty real QtQuick2::Item::anchors.horizontalCenterOffset
2755 \qmlproperty real QtQuick2::Item::anchors.verticalCenterOffset
2756 \qmlproperty real QtQuick2::Item::anchors.baselineOffset
2758 \qmlproperty bool QtQuick2::Item::anchors.mirrored
2760 Anchors provide a way to position an item by specifying its
2761 relationship with other items.
2763 Margins apply to top, bottom, left, right, and fill anchors.
2764 The \c anchors.margins property can be used to set all of the various margins at once, to the same value.
2765 Note that margins are anchor-specific and are not applied if an item does not
2768 Offsets apply for horizontal center, vertical center, and baseline anchors.
2772 \o \image declarative-anchors_example.png
2773 \o Text anchored to Image, horizontally centered and vertically below, with a margin.
2782 anchors.horizontalCenter: pic.horizontalCenter
2783 anchors.top: pic.bottom
2784 anchors.topMargin: 5
2790 \o \image declarative-anchors_example2.png
2792 Left of Text anchored to right of Image, with a margin. The y
2793 property of both defaults to 0.
2803 anchors.left: pic.right
2804 anchors.leftMargin: 5
2811 \c anchors.fill provides a convenient way for one item to have the
2812 same geometry as another item, and is equivalent to connecting all
2813 four directional anchors.
2815 To clear an anchor value, set it to \c undefined.
2817 \c anchors.mirrored returns true it the layout has been \l {LayoutMirroring}{mirrored}.
2819 \note You can only anchor an item to siblings or a parent.
2821 For more information see \l {anchor-layout}{Anchor Layouts}.
2825 \property QQuickItem::baselineOffset
2826 \brief The position of the item's baseline in local coordinates.
2828 The baseline of a \l Text item is the imaginary line on which the text
2829 sits. Controls containing text usually set their baseline to the
2830 baseline of their text.
2832 For non-text items, a default baseline offset of 0 is used.
2834 QQuickAnchors *QQuickItemPrivate::anchors() const
2837 Q_Q(const QQuickItem);
2838 _anchors = new QQuickAnchors(const_cast<QQuickItem *>(q));
2839 if (!componentComplete)
2840 _anchors->classBegin();
2845 void QQuickItemPrivate::siblingOrderChanged()
2848 for (int ii = 0; ii < changeListeners.count(); ++ii) {
2849 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
2850 if (change.types & QQuickItemPrivate::SiblingOrder) {
2851 change.listener->itemSiblingOrderChanged(q);
2856 QQmlListProperty<QObject> QQuickItemPrivate::data()
2858 return QQmlListProperty<QObject>(q_func(), 0, QQuickItemPrivate::data_append,
2859 QQuickItemPrivate::data_count,
2860 QQuickItemPrivate::data_at,
2861 QQuickItemPrivate::data_clear);
2864 QRectF QQuickItem::childrenRect()
2867 if (!d->extra.isAllocated() || !d->extra->contents) {
2868 d->extra.value().contents = new QQuickContents(this);
2869 if (d->componentComplete)
2870 d->extra->contents->complete();
2872 return d->extra->contents->rectF();
2875 QList<QQuickItem *> QQuickItem::childItems() const
2877 Q_D(const QQuickItem);
2878 return d->childItems;
2881 bool QQuickItem::clip() const
2883 return flags() & ItemClipsChildrenToShape;
2886 void QQuickItem::setClip(bool c)
2891 setFlag(ItemClipsChildrenToShape, c);
2893 emit clipChanged(c);
2898 This function is called to handle this item's changes in
2899 geometry from \a oldGeometry to \a newGeometry. If the two
2900 geometries are the same, it doesn't do anything.
2902 void QQuickItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
2907 QQuickAnchorsPrivate::get(d->_anchors)->updateMe();
2909 bool xChange = (newGeometry.x() != oldGeometry.x());
2910 bool yChange = (newGeometry.y() != oldGeometry.y());
2911 bool widthChange = (newGeometry.width() != oldGeometry.width());
2912 bool heightChange = (newGeometry.height() != oldGeometry.height());
2914 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
2915 const QQuickItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
2916 if (change.types & QQuickItemPrivate::Geometry) {
2917 if (change.gTypes == QQuickItemPrivate::GeometryChange) {
2918 change.listener->itemGeometryChanged(this, newGeometry, oldGeometry);
2919 } else if ((xChange && (change.gTypes & QQuickItemPrivate::XChange)) ||
2920 (yChange && (change.gTypes & QQuickItemPrivate::YChange)) ||
2921 (widthChange && (change.gTypes & QQuickItemPrivate::WidthChange)) ||
2922 (heightChange && (change.gTypes & QQuickItemPrivate::HeightChange))) {
2923 change.listener->itemGeometryChanged(this, newGeometry, oldGeometry);
2933 emit widthChanged();
2935 emit heightChanged();
2939 Called by the rendering thread when it is time to sync the state of the QML objects with the
2940 scene graph objects. The function should return the root of the scene graph subtree for
2941 this item. \a oldNode is the node that was returned the last time the function was called.
2943 The main thread is blocked while this function is executed so it is safe to read
2944 values from the QQuickItem instance and other objects in the main thread.
2946 \warning This is the only function in which it is allowed to make use of scene graph
2947 objects from the main thread. Use of scene graph objects outside this function will
2948 result in race conditions and potential crashes.
2951 QSGNode *QQuickItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
2957 QSGTransformNode *QQuickItemPrivate::createTransformNode()
2959 return new QSGTransformNode;
2962 void QQuickItem::updatePolish()
2966 void QQuickItem::sendAccessibilityUpdate()
2970 void QQuickItemPrivate::addItemChangeListener(QQuickItemChangeListener *listener, ChangeTypes types)
2972 changeListeners.append(ChangeListener(listener, types));
2975 void QQuickItemPrivate::removeItemChangeListener(QQuickItemChangeListener *listener, ChangeTypes types)
2977 ChangeListener change(listener, types);
2978 changeListeners.removeOne(change);
2981 void QQuickItemPrivate::updateOrAddGeometryChangeListener(QQuickItemChangeListener *listener, GeometryChangeTypes types)
2983 ChangeListener change(listener, types);
2984 int index = changeListeners.find(change);
2986 changeListeners[index].gTypes = change.gTypes; //we may have different GeometryChangeTypes
2988 changeListeners.append(change);
2991 void QQuickItemPrivate::updateOrRemoveGeometryChangeListener(QQuickItemChangeListener *listener,
2992 GeometryChangeTypes types)
2994 ChangeListener change(listener, types);
2995 if (types == NoChange) {
2996 changeListeners.removeOne(change);
2998 int index = changeListeners.find(change);
3000 changeListeners[index].gTypes = change.gTypes; //we may have different GeometryChangeTypes
3004 void QQuickItem::keyPressEvent(QKeyEvent *event)
3009 void QQuickItem::keyReleaseEvent(QKeyEvent *event)
3014 void QQuickItem::inputMethodEvent(QInputMethodEvent *event)
3019 void QQuickItem::focusInEvent(QFocusEvent *)
3021 QAccessible::updateAccessibility(QAccessibleEvent(QAccessible::Focus, this, 0));
3024 void QQuickItem::focusOutEvent(QFocusEvent *)
3028 void QQuickItem::mousePressEvent(QMouseEvent *event)
3033 void QQuickItem::mouseMoveEvent(QMouseEvent *event)
3038 void QQuickItem::mouseReleaseEvent(QMouseEvent *event)
3043 void QQuickItem::mouseDoubleClickEvent(QMouseEvent *)
3047 void QQuickItem::mouseUngrabEvent()
3052 void QQuickItem::touchUngrabEvent()
3057 void QQuickItem::wheelEvent(QWheelEvent *event)
3062 void QQuickItem::touchEvent(QTouchEvent *event)
3067 void QQuickItem::hoverEnterEvent(QHoverEvent *event)
3072 void QQuickItem::hoverMoveEvent(QHoverEvent *event)
3077 void QQuickItem::hoverLeaveEvent(QHoverEvent *event)
3082 void QQuickItem::dragEnterEvent(QDragEnterEvent *event)
3087 void QQuickItem::dragMoveEvent(QDragMoveEvent *event)
3093 void QQuickItem::dragLeaveEvent(QDragLeaveEvent *event)
3099 void QQuickItem::dropEvent(QDropEvent *event)
3104 bool QQuickItem::childMouseEventFilter(QQuickItem *, QEvent *)
3109 void QQuickItem::windowDeactivateEvent()
3111 foreach (QQuickItem* item, childItems()) {
3112 item->windowDeactivateEvent();
3116 QVariant QQuickItem::inputMethodQuery(Qt::InputMethodQuery query) const
3118 Q_D(const QQuickItem);
3123 v = (bool)(flags() & ItemAcceptsInputMethod);
3126 case Qt::ImCursorRectangle:
3128 case Qt::ImCursorPosition:
3129 case Qt::ImSurroundingText:
3130 case Qt::ImCurrentSelection:
3131 case Qt::ImMaximumTextLength:
3132 case Qt::ImAnchorPosition:
3133 case Qt::ImPreferredLanguage:
3134 if (d->extra.isAllocated() && d->extra->keyHandler)
3135 v = d->extra->keyHandler->inputMethodQuery(query);
3143 QQuickAnchorLine QQuickItemPrivate::left() const
3145 Q_Q(const QQuickItem);
3146 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Left);
3149 QQuickAnchorLine QQuickItemPrivate::right() const
3151 Q_Q(const QQuickItem);
3152 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Right);
3155 QQuickAnchorLine QQuickItemPrivate::horizontalCenter() const
3157 Q_Q(const QQuickItem);
3158 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::HCenter);
3161 QQuickAnchorLine QQuickItemPrivate::top() const
3163 Q_Q(const QQuickItem);
3164 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Top);
3167 QQuickAnchorLine QQuickItemPrivate::bottom() const
3169 Q_Q(const QQuickItem);
3170 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Bottom);
3173 QQuickAnchorLine QQuickItemPrivate::verticalCenter() const
3175 Q_Q(const QQuickItem);
3176 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::VCenter);
3179 QQuickAnchorLine QQuickItemPrivate::baseline() const
3181 Q_Q(const QQuickItem);
3182 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Baseline);
3185 qreal QQuickItem::baselineOffset() const
3187 Q_D(const QQuickItem);
3188 if (d->baselineOffsetValid) {
3189 return d->baselineOffset;
3195 void QQuickItem::setBaselineOffset(qreal offset)
3198 if (offset == d->baselineOffset)
3201 d->baselineOffset = offset;
3202 d->baselineOffsetValid = true;
3204 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
3205 const QQuickItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
3206 if (change.types & QQuickItemPrivate::Geometry) {
3207 QQuickAnchorsPrivate *anchor = change.listener->anchorPrivate();
3209 anchor->updateVerticalAnchors();
3212 emit baselineOffsetChanged(offset);
3215 void QQuickItem::update()
3218 Q_ASSERT(flags() & ItemHasContents);
3219 d->dirty(QQuickItemPrivate::Content);
3222 void QQuickItem::polish()
3225 if (!d->polishScheduled) {
3226 d->polishScheduled = true;
3228 QQuickCanvasPrivate *p = QQuickCanvasPrivate::get(d->canvas);
3229 bool maybeupdate = p->itemsToPolish.isEmpty();
3230 p->itemsToPolish.insert(this);
3231 if (maybeupdate) d->canvas->maybeUpdate();
3236 void QQuickItem::mapFromItem(QQmlV8Function *args) const
3238 if (args->Length() != 0) {
3239 v8::Local<v8::Value> item = (*args)[0];
3240 QV8Engine *engine = args->engine();
3242 QQuickItem *itemObj = 0;
3243 if (!item->IsNull())
3244 itemObj = qobject_cast<QQuickItem*>(engine->toQObject(item));
3246 if (!itemObj && !item->IsNull()) {
3247 qmlInfo(this) << "mapFromItem() given argument \"" << engine->toString(item->ToString())
3248 << "\" which is neither null nor an Item";
3252 v8::Local<v8::Object> rv = v8::Object::New();
3253 args->returnValue(rv);
3255 qreal x = (args->Length() > 1)?(*args)[1]->NumberValue():0;
3256 qreal y = (args->Length() > 2)?(*args)[2]->NumberValue():0;
3258 QPointF p = mapFromItem(itemObj, QPointF(x, y));
3260 rv->Set(v8::String::New("x"), v8::Number::New(p.x()));
3261 rv->Set(v8::String::New("y"), v8::Number::New(p.y()));
3265 QTransform QQuickItem::itemTransform(QQuickItem *other, bool *ok) const
3267 Q_D(const QQuickItem);
3269 // XXX todo - we need to be able to handle common parents better and detect
3273 QTransform t = d->itemToCanvasTransform();
3274 if (other) t *= QQuickItemPrivate::get(other)->canvasToItemTransform();
3279 void QQuickItem::mapToItem(QQmlV8Function *args) const
3281 if (args->Length() != 0) {
3282 v8::Local<v8::Value> item = (*args)[0];
3283 QV8Engine *engine = args->engine();
3285 QQuickItem *itemObj = 0;
3286 if (!item->IsNull())
3287 itemObj = qobject_cast<QQuickItem*>(engine->toQObject(item));
3289 if (!itemObj && !item->IsNull()) {
3290 qmlInfo(this) << "mapToItem() given argument \"" << engine->toString(item->ToString())
3291 << "\" which is neither null nor an Item";
3295 v8::Local<v8::Object> rv = v8::Object::New();
3296 args->returnValue(rv);
3298 qreal x = (args->Length() > 1)?(*args)[1]->NumberValue():0;
3299 qreal y = (args->Length() > 2)?(*args)[2]->NumberValue():0;
3301 QPointF p = mapToItem(itemObj, QPointF(x, y));
3303 rv->Set(v8::String::New("x"), v8::Number::New(p.x()));
3304 rv->Set(v8::String::New("y"), v8::Number::New(p.y()));
3308 void QQuickItem::forceActiveFocus()
3311 QQuickItem *parent = parentItem();
3313 if (parent->flags() & QQuickItem::ItemIsFocusScope) {
3314 parent->setFocus(true);
3316 parent = parent->parentItem();
3320 QQuickItem *QQuickItem::childAt(qreal x, qreal y) const
3322 // XXX todo - should this include transform etc.?
3323 const QList<QQuickItem *> children = childItems();
3324 for (int i = children.count()-1; i >= 0; --i) {
3325 QQuickItem *child = children.at(i);
3326 if (child->isVisible() && child->x() <= x
3327 && child->x() + child->width() >= x
3329 && child->y() + child->height() >= y)
3335 QQmlListProperty<QObject> QQuickItemPrivate::resources()
3337 return QQmlListProperty<QObject>(q_func(), 0, QQuickItemPrivate::resources_append,
3338 QQuickItemPrivate::resources_count,
3339 QQuickItemPrivate::resources_at,
3340 QQuickItemPrivate::resources_clear);
3343 QQmlListProperty<QQuickItem> QQuickItemPrivate::children()
3345 return QQmlListProperty<QQuickItem>(q_func(), 0, QQuickItemPrivate::children_append,
3346 QQuickItemPrivate::children_count,
3347 QQuickItemPrivate::children_at,
3348 QQuickItemPrivate::children_clear);
3353 \qmlproperty real QtQuick2::Item::visibleChildren
3354 This read-only property lists all of the item's children that are currently visible.
3355 Note that a child's visibility may have changed explicitly, or because the visibility
3356 of this (it's parent) item or another grandparent changed.
3358 QQmlListProperty<QQuickItem> QQuickItemPrivate::visibleChildren()
3360 return QQmlListProperty<QQuickItem>(q_func(), 0, QQuickItemPrivate::visibleChildren_append,
3361 QQuickItemPrivate::visibleChildren_count,
3362 QQuickItemPrivate::visibleChildren_at);
3366 QQmlListProperty<QQuickState> QQuickItemPrivate::states()
3368 return _states()->statesProperty();
3371 QQmlListProperty<QQuickTransition> QQuickItemPrivate::transitions()
3373 return _states()->transitionsProperty();
3376 QString QQuickItemPrivate::state() const
3381 return _stateGroup->state();
3384 void QQuickItemPrivate::setState(const QString &state)
3386 _states()->setState(state);
3389 QString QQuickItem::state() const
3391 Q_D(const QQuickItem);
3395 void QQuickItem::setState(const QString &state)
3401 QQmlListProperty<QQuickTransform> QQuickItem::transform()
3403 return QQmlListProperty<QQuickTransform>(this, 0, QQuickItemPrivate::transform_append,
3404 QQuickItemPrivate::transform_count,
3405 QQuickItemPrivate::transform_at,
3406 QQuickItemPrivate::transform_clear);
3409 void QQuickItem::classBegin()
3412 d->componentComplete = false;
3414 d->_stateGroup->classBegin();
3416 d->_anchors->classBegin();
3417 if (d->extra.isAllocated() && d->extra->layer)
3418 d->extra->layer->classBegin();
3421 void QQuickItem::componentComplete()
3424 d->componentComplete = true;
3426 d->_stateGroup->componentComplete();
3428 d->_anchors->componentComplete();
3429 QQuickAnchorsPrivate::get(d->_anchors)->updateOnComplete();
3432 if (d->extra.isAllocated() && d->extra->layer)
3433 d->extra->layer->componentComplete();
3435 if (d->extra.isAllocated() && d->extra->keyHandler)
3436 d->extra->keyHandler->componentComplete();
3438 if (d->extra.isAllocated() && d->extra->contents)
3439 d->extra->contents->complete();
3442 QQuickStateGroup *QQuickItemPrivate::_states()
3446 _stateGroup = new QQuickStateGroup;
3447 if (!componentComplete)
3448 _stateGroup->classBegin();
3449 FAST_CONNECT(_stateGroup, SIGNAL(stateChanged(QString)),
3450 q, SIGNAL(stateChanged(QString)))
3456 QPointF QQuickItemPrivate::computeTransformOrigin() const
3460 case QQuickItem::TopLeft:
3461 return QPointF(0, 0);
3462 case QQuickItem::Top:
3463 return QPointF(width / 2., 0);
3464 case QQuickItem::TopRight:
3465 return QPointF(width, 0);
3466 case QQuickItem::Left:
3467 return QPointF(0, height / 2.);
3468 case QQuickItem::Center:
3469 return QPointF(width / 2., height / 2.);
3470 case QQuickItem::Right:
3471 return QPointF(width, height / 2.);
3472 case QQuickItem::BottomLeft:
3473 return QPointF(0, height);
3474 case QQuickItem::Bottom:
3475 return QPointF(width / 2., height);
3476 case QQuickItem::BottomRight:
3477 return QPointF(width, height);
3481 void QQuickItemPrivate::transformChanged()
3483 if (extra.isAllocated() && extra->layer)
3484 extra->layer->updateMatrix();
3487 void QQuickItemPrivate::deliverKeyEvent(QKeyEvent *e)
3491 Q_ASSERT(e->isAccepted());
3492 if (extra.isAllocated() && extra->keyHandler) {
3493 if (e->type() == QEvent::KeyPress)
3494 extra->keyHandler->keyPressed(e, false);
3496 extra->keyHandler->keyReleased(e, false);
3498 if (e->isAccepted())
3504 if (e->type() == QEvent::KeyPress)
3505 q->keyPressEvent(e);
3507 q->keyReleaseEvent(e);
3509 if (e->isAccepted())
3512 if (extra.isAllocated() && extra->keyHandler) {
3515 if (e->type() == QEvent::KeyPress)
3516 extra->keyHandler->keyPressed(e, true);
3518 extra->keyHandler->keyReleased(e, true);
3522 void QQuickItemPrivate::deliverInputMethodEvent(QInputMethodEvent *e)
3526 Q_ASSERT(e->isAccepted());
3527 if (extra.isAllocated() && extra->keyHandler) {
3528 extra->keyHandler->inputMethodEvent(e, false);
3530 if (e->isAccepted())
3536 q->inputMethodEvent(e);
3538 if (e->isAccepted())
3541 if (extra.isAllocated() && extra->keyHandler) {
3544 extra->keyHandler->inputMethodEvent(e, true);
3548 void QQuickItemPrivate::deliverFocusEvent(QFocusEvent *e)
3552 if (e->type() == QEvent::FocusIn) {
3555 q->focusOutEvent(e);
3559 void QQuickItemPrivate::deliverMouseEvent(QMouseEvent *e)
3563 Q_ASSERT(e->isAccepted());
3565 switch (e->type()) {
3567 Q_ASSERT(!"Unknown event type");
3568 case QEvent::MouseMove:
3569 q->mouseMoveEvent(e);
3571 case QEvent::MouseButtonPress:
3572 q->mousePressEvent(e);
3574 case QEvent::MouseButtonRelease:
3575 q->mouseReleaseEvent(e);
3577 case QEvent::MouseButtonDblClick:
3578 q->mouseDoubleClickEvent(e);
3583 void QQuickItemPrivate::deliverWheelEvent(QWheelEvent *e)
3589 void QQuickItemPrivate::deliverTouchEvent(QTouchEvent *e)
3595 void QQuickItemPrivate::deliverHoverEvent(QHoverEvent *e)
3598 switch (e->type()) {
3600 Q_ASSERT(!"Unknown event type");
3601 case QEvent::HoverEnter:
3602 q->hoverEnterEvent(e);
3604 case QEvent::HoverLeave:
3605 q->hoverLeaveEvent(e);
3607 case QEvent::HoverMove:
3608 q->hoverMoveEvent(e);
3613 void QQuickItemPrivate::deliverDragEvent(QEvent *e)
3616 switch (e->type()) {
3618 Q_ASSERT(!"Unknown event type");
3619 case QEvent::DragEnter:
3620 q->dragEnterEvent(static_cast<QDragEnterEvent *>(e));
3622 case QEvent::DragLeave:
3623 q->dragLeaveEvent(static_cast<QDragLeaveEvent *>(e));
3625 case QEvent::DragMove:
3626 q->dragMoveEvent(static_cast<QDragMoveEvent *>(e));
3629 q->dropEvent(static_cast<QDropEvent *>(e));
3634 void QQuickItem::itemChange(ItemChange change, const ItemChangeData &value)
3641 Notify input method on updated query values if needed. \a indicates changed attributes.
3643 void QQuickItem::updateInputMethod(Qt::InputMethodQueries queries)
3645 if (hasActiveFocus())
3646 qApp->inputMethod()->update(queries);
3650 // XXX todo - do we want/need this anymore?
3651 QRectF QQuickItem::boundingRect() const
3653 Q_D(const QQuickItem);
3654 return QRectF(0, 0, d->width, d->height);
3658 QRectF QQuickItem::clipRect() const
3660 Q_D(const QQuickItem);
3661 return QRectF(0, 0, d->width, d->height);
3665 QQuickItem::TransformOrigin QQuickItem::transformOrigin() const
3667 Q_D(const QQuickItem);
3671 void QQuickItem::setTransformOrigin(TransformOrigin origin)
3674 if (origin == d->origin())
3677 d->extra.value().origin = origin;
3678 d->dirty(QQuickItemPrivate::TransformOrigin);
3680 emit transformOriginChanged(d->origin());
3683 QPointF QQuickItem::transformOriginPoint() const
3685 Q_D(const QQuickItem);
3686 if (d->extra.isAllocated() && !d->extra->userTransformOriginPoint.isNull())
3687 return d->extra->userTransformOriginPoint;
3688 return d->computeTransformOrigin();
3691 void QQuickItem::setTransformOriginPoint(const QPointF &point)
3694 if (d->extra.value().userTransformOriginPoint == point)
3697 d->extra->userTransformOriginPoint = point;
3698 d->dirty(QQuickItemPrivate::TransformOrigin);
3701 qreal QQuickItem::z() const
3703 Q_D(const QQuickItem);
3707 void QQuickItem::setZ(qreal v)
3713 d->extra.value().z = v;
3715 d->dirty(QQuickItemPrivate::ZValue);
3716 if (d->parentItem) {
3717 QQuickItemPrivate::get(d->parentItem)->dirty(QQuickItemPrivate::ChildrenStackingChanged);
3718 QQuickItemPrivate::get(d->parentItem)->markSortedChildrenDirty(this);
3723 if (d->extra.isAllocated() && d->extra->layer)
3724 d->extra->layer->updateZ();
3729 \qmlproperty real QtQuick2::Item::rotation
3730 This property holds the rotation of the item in degrees clockwise.
3732 This specifies how many degrees to rotate the item around its transformOrigin.
3733 The default rotation is 0 degrees (i.e. not rotated at all).
3737 \o \image declarative-rotation.png
3742 width: 100; height: 100
3745 x: 25; y: 25; width: 50; height: 50
3752 \sa transform, Rotation
3756 \qmlproperty real QtQuick2::Item::scale
3757 This property holds the scale of the item.
3759 A scale of less than 1 means the item will be displayed smaller than
3760 normal, and a scale of greater than 1 means the item will be
3761 displayed larger than normal. A negative scale means the item will
3764 By default, items are displayed at a scale of 1 (i.e. at their
3767 Scaling is from the item's transformOrigin.
3771 \o \image declarative-scale.png
3776 width: 100; height: 100
3779 width: 25; height: 25
3783 x: 25; y: 25; width: 50; height: 50
3790 \sa transform, Scale
3794 \qmlproperty real QtQuick2::Item::opacity
3796 This property holds the opacity of the item. Opacity is specified as a
3797 number between 0 (fully transparent) and 1 (fully opaque). The default is 1.
3799 When this property is set, the specified opacity is also applied
3800 individually to child items. In almost all cases this is what you want,
3801 but in some cases it may produce undesired results. For example in the
3802 second set of rectangles below, the red rectangle has specified an opacity
3803 of 0.5, which affects the opacity of its blue child rectangle even though
3804 the child has not specified an opacity.
3808 \o \image declarative-item_opacity1.png
3814 width: 100; height: 100
3817 x: 50; y: 50; width: 100; height: 100
3823 \o \image declarative-item_opacity2.png
3830 width: 100; height: 100
3833 x: 50; y: 50; width: 100; height: 100
3840 If an item's opacity is set to 0, the item will no longer receive mouse
3841 events, but will continue to receive key events and will retain the keyboard
3842 \l focus if it has been set. (In contrast, setting the \l visible property
3843 to \c false stops both mouse and keyboard events, and also removes focus
3848 Returns a value indicating whether mouse input should
3849 remain with this item exclusively.
3851 \sa setKeepMouseGrab()
3854 qreal QQuickItem::rotation() const
3856 Q_D(const QQuickItem);
3857 return d->rotation();
3860 void QQuickItem::setRotation(qreal r)
3863 if (d->rotation() == r)
3866 d->extra.value().rotation = r;
3868 d->dirty(QQuickItemPrivate::BasicTransform);
3870 d->itemChange(ItemRotationHasChanged, r);
3872 emit rotationChanged();
3875 qreal QQuickItem::scale() const
3877 Q_D(const QQuickItem);
3881 void QQuickItem::setScale(qreal s)
3884 if (d->scale() == s)
3887 d->extra.value().scale = s;
3889 d->dirty(QQuickItemPrivate::BasicTransform);
3891 emit scaleChanged();
3894 qreal QQuickItem::opacity() const
3896 Q_D(const QQuickItem);
3897 return d->opacity();
3900 void QQuickItem::setOpacity(qreal o)
3903 if (d->opacity() == o)
3906 d->extra.value().opacity = o;
3908 d->dirty(QQuickItemPrivate::OpacityValue);
3910 d->itemChange(ItemOpacityHasChanged, o);
3912 emit opacityChanged();
3915 bool QQuickItem::isVisible() const
3917 Q_D(const QQuickItem);
3918 return d->effectiveVisible;
3921 void QQuickItem::setVisible(bool v)
3924 if (v == d->explicitVisible)
3927 d->explicitVisible = v;
3929 const bool childVisibilityChanged = d->setEffectiveVisibleRecur(d->calcEffectiveVisible());
3930 if (childVisibilityChanged && d->parentItem)
3931 emit d->parentItem->visibleChildrenChanged(); // signal the parent, not this!
3934 bool QQuickItem::isEnabled() const
3936 Q_D(const QQuickItem);
3937 return d->effectiveEnable;
3940 void QQuickItem::setEnabled(bool e)
3943 if (e == d->explicitEnable)
3946 d->explicitEnable = e;
3948 QQuickItem *scope = parentItem();
3949 while (scope && !scope->isFocusScope())
3950 scope = scope->parentItem();
3952 d->setEffectiveEnableRecur(scope, d->calcEffectiveEnable());
3955 bool QQuickItemPrivate::calcEffectiveVisible() const
3957 // XXX todo - Should the effective visible of an element with no parent just be the current
3958 // effective visible? This would prevent pointless re-processing in the case of an element
3959 // moving to/from a no-parent situation, but it is different from what graphics view does.
3960 return explicitVisible && (!parentItem || QQuickItemPrivate::get(parentItem)->effectiveVisible);
3963 bool QQuickItemPrivate::setEffectiveVisibleRecur(bool newEffectiveVisible)
3967 if (newEffectiveVisible && !explicitVisible) {
3968 // This item locally overrides visibility
3969 return false; // effective visibility didn't change
3972 if (newEffectiveVisible == effectiveVisible) {
3973 // No change necessary
3974 return false; // effective visibility didn't change
3977 effectiveVisible = newEffectiveVisible;
3979 if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
3982 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(canvas);
3983 if (canvasPriv->mouseGrabberItem == q)
3987 bool childVisibilityChanged = false;
3988 for (int ii = 0; ii < childItems.count(); ++ii)
3989 childVisibilityChanged |= QQuickItemPrivate::get(childItems.at(ii))->setEffectiveVisibleRecur(newEffectiveVisible);
3991 itemChange(QQuickItem::ItemVisibleHasChanged, effectiveVisible);
3994 QAccessible::updateAccessibility(QAccessibleEvent(effectiveVisible ? QAccessible::ObjectShow : QAccessible::ObjectHide, q, 0));
3996 emit q->visibleChanged();
3997 if (childVisibilityChanged)
3998 emit q->visibleChildrenChanged();
4000 return true; // effective visibility DID change
4003 bool QQuickItemPrivate::calcEffectiveEnable() const
4005 // XXX todo - Should the effective enable of an element with no parent just be the current
4006 // effective enable? This would prevent pointless re-processing in the case of an element
4007 // moving to/from a no-parent situation, but it is different from what graphics view does.
4008 return explicitEnable && (!parentItem || QQuickItemPrivate::get(parentItem)->effectiveEnable);
4011 void QQuickItemPrivate::setEffectiveEnableRecur(QQuickItem *scope, bool newEffectiveEnable)
4015 if (newEffectiveEnable && !explicitEnable) {
4016 // This item locally overrides enable
4020 if (newEffectiveEnable == effectiveEnable) {
4021 // No change necessary
4025 effectiveEnable = newEffectiveEnable;
4028 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(canvas);
4029 if (canvasPriv->mouseGrabberItem == q)
4031 if (scope && !effectiveEnable && activeFocus) {
4032 canvasPriv->clearFocusInScope(
4033 scope, q, QQuickCanvasPrivate::DontChangeFocusProperty | QQuickCanvasPrivate::DontChangeSubFocusItem);
4037 for (int ii = 0; ii < childItems.count(); ++ii) {
4038 QQuickItemPrivate::get(childItems.at(ii))->setEffectiveEnableRecur(
4039 flags & QQuickItem::ItemIsFocusScope ? q : scope, newEffectiveEnable);
4042 if (canvas && scope && effectiveEnable && focus) {
4043 QQuickCanvasPrivate::get(canvas)->setFocusInScope(
4044 scope, q, QQuickCanvasPrivate::DontChangeFocusProperty | QQuickCanvasPrivate::DontChangeSubFocusItem);
4047 emit q->enabledChanged();
4050 QString QQuickItemPrivate::dirtyToString() const
4052 #define DIRTY_TO_STRING(value) if (dirtyAttributes & value) { \
4053 if (!rv.isEmpty()) \
4054 rv.append(QLatin1String("|")); \
4055 rv.append(QLatin1String(#value)); \
4058 // QString rv = QLatin1String("0x") + QString::number(dirtyAttributes, 16);
4061 DIRTY_TO_STRING(TransformOrigin);
4062 DIRTY_TO_STRING(Transform);
4063 DIRTY_TO_STRING(BasicTransform);
4064 DIRTY_TO_STRING(Position);
4065 DIRTY_TO_STRING(Size);
4066 DIRTY_TO_STRING(ZValue);
4067 DIRTY_TO_STRING(Content);
4068 DIRTY_TO_STRING(Smooth);
4069 DIRTY_TO_STRING(OpacityValue);
4070 DIRTY_TO_STRING(ChildrenChanged);
4071 DIRTY_TO_STRING(ChildrenStackingChanged);
4072 DIRTY_TO_STRING(ParentChanged);
4073 DIRTY_TO_STRING(Clip);
4074 DIRTY_TO_STRING(Canvas);
4075 DIRTY_TO_STRING(EffectReference);
4076 DIRTY_TO_STRING(Visible);
4077 DIRTY_TO_STRING(HideReference);
4078 DIRTY_TO_STRING(PerformanceHints);
4083 void QQuickItemPrivate::dirty(DirtyType type)
4086 if (type & (TransformOrigin | Transform | BasicTransform | Position | Size))
4089 if (!(dirtyAttributes & type) || (canvas && !prevDirtyItem)) {
4090 dirtyAttributes |= type;
4093 QQuickCanvasPrivate::get(canvas)->dirtyItem(q);
4098 void QQuickItemPrivate::addToDirtyList()
4103 if (!prevDirtyItem) {
4104 Q_ASSERT(!nextDirtyItem);
4106 QQuickCanvasPrivate *p = QQuickCanvasPrivate::get(canvas);
4107 nextDirtyItem = p->dirtyItemList;
4108 if (nextDirtyItem) QQuickItemPrivate::get(nextDirtyItem)->prevDirtyItem = &nextDirtyItem;
4109 prevDirtyItem = &p->dirtyItemList;
4110 p->dirtyItemList = q;
4113 Q_ASSERT(prevDirtyItem);
4116 void QQuickItemPrivate::removeFromDirtyList()
4118 if (prevDirtyItem) {
4119 if (nextDirtyItem) QQuickItemPrivate::get(nextDirtyItem)->prevDirtyItem = prevDirtyItem;
4120 *prevDirtyItem = nextDirtyItem;
4124 Q_ASSERT(!prevDirtyItem);
4125 Q_ASSERT(!nextDirtyItem);
4128 void QQuickItemPrivate::refFromEffectItem(bool hide)
4130 ++extra.value().effectRefCount;
4131 if (1 == extra->effectRefCount) {
4132 dirty(EffectReference);
4133 if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
4136 if (++extra->hideRefCount == 1)
4137 dirty(HideReference);
4141 void QQuickItemPrivate::derefFromEffectItem(bool unhide)
4143 Q_ASSERT(extra->effectRefCount);
4144 --extra->effectRefCount;
4145 if (0 == extra->effectRefCount) {
4146 dirty(EffectReference);
4147 if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
4150 if (--extra->hideRefCount == 0)
4151 dirty(HideReference);
4155 void QQuickItemPrivate::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data)
4159 case QQuickItem::ItemChildAddedChange:
4160 q->itemChange(change, data);
4161 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4162 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4163 if (change.types & QQuickItemPrivate::Children) {
4164 change.listener->itemChildAdded(q, data.item);
4168 case QQuickItem::ItemChildRemovedChange:
4169 q->itemChange(change, data);
4170 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4171 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4172 if (change.types & QQuickItemPrivate::Children) {
4173 change.listener->itemChildRemoved(q, data.item);
4177 case QQuickItem::ItemSceneChange:
4178 q->itemChange(change, data);
4180 case QQuickItem::ItemVisibleHasChanged:
4181 q->itemChange(change, data);
4182 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4183 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4184 if (change.types & QQuickItemPrivate::Visibility) {
4185 change.listener->itemVisibilityChanged(q);
4189 case QQuickItem::ItemParentHasChanged:
4190 q->itemChange(change, data);
4191 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4192 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4193 if (change.types & QQuickItemPrivate::Parent) {
4194 change.listener->itemParentChanged(q, data.item);
4198 case QQuickItem::ItemOpacityHasChanged:
4199 q->itemChange(change, data);
4200 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4201 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4202 if (change.types & QQuickItemPrivate::Opacity) {
4203 change.listener->itemOpacityChanged(q);
4207 case QQuickItem::ItemActiveFocusHasChanged:
4208 q->itemChange(change, data);
4210 case QQuickItem::ItemRotationHasChanged:
4211 q->itemChange(change, data);
4212 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4213 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4214 if (change.types & QQuickItemPrivate::Rotation) {
4215 change.listener->itemRotationChanged(q);
4223 \property QQuickItem::smooth
4224 \brief whether the item is smoothly transformed.
4226 This property is provided purely for the purpose of optimization. Turning
4227 smooth transforms off is faster, but looks worse; turning smooth
4228 transformations on is slower, but looks better.
4230 By default smooth transformations are off.
4234 Returns true if the item should be drawn with antialiasing and
4235 smooth pixmap filtering, false otherwise.
4237 The default is false.
4241 bool QQuickItem::smooth() const
4243 Q_D(const QQuickItem);
4248 Sets whether the item should be drawn with antialiasing and
4249 smooth pixmap filtering to \a smooth.
4253 void QQuickItem::setSmooth(bool smooth)
4256 if (d->smooth == smooth)
4260 d->dirty(QQuickItemPrivate::Smooth);
4262 emit smoothChanged(smooth);
4265 QQuickItem::Flags QQuickItem::flags() const
4267 Q_D(const QQuickItem);
4268 return (QQuickItem::Flags)d->flags;
4271 void QQuickItem::setFlag(Flag flag, bool enabled)
4275 setFlags((Flags)(d->flags | (quint32)flag));
4277 setFlags((Flags)(d->flags & ~(quint32)flag));
4280 void QQuickItem::setFlags(Flags flags)
4284 if ((flags & ItemIsFocusScope) != (d->flags & ItemIsFocusScope)) {
4285 if (flags & ItemIsFocusScope && !d->childItems.isEmpty() && d->canvas) {
4286 qWarning("QQuickItem: Cannot set FocusScope once item has children and is in a canvas.");
4287 flags &= ~ItemIsFocusScope;
4288 } else if (d->flags & ItemIsFocusScope) {
4289 qWarning("QQuickItem: Cannot unset FocusScope flag.");
4290 flags |= ItemIsFocusScope;
4294 if ((flags & ItemClipsChildrenToShape ) != (d->flags & ItemClipsChildrenToShape))
4295 d->dirty(QQuickItemPrivate::Clip);
4300 qreal QQuickItem::x() const
4302 Q_D(const QQuickItem);
4306 qreal QQuickItem::y() const
4308 Q_D(const QQuickItem);
4312 QPointF QQuickItem::pos() const
4314 Q_D(const QQuickItem);
4315 return QPointF(d->x, d->y);
4318 void QQuickItem::setX(qreal v)
4327 d->dirty(QQuickItemPrivate::Position);
4329 geometryChanged(QRectF(x(), y(), width(), height()),
4330 QRectF(oldx, y(), width(), height()));
4333 void QQuickItem::setY(qreal v)
4342 d->dirty(QQuickItemPrivate::Position);
4344 geometryChanged(QRectF(x(), y(), width(), height()),
4345 QRectF(x(), oldy, width(), height()));
4348 void QQuickItem::setPos(const QPointF &pos)
4351 if (QPointF(d->x, d->y) == pos)
4360 d->dirty(QQuickItemPrivate::Position);
4362 geometryChanged(QRectF(x(), y(), width(), height()),
4363 QRectF(oldx, oldy, width(), height()));
4366 qreal QQuickItem::width() const
4368 Q_D(const QQuickItem);
4372 void QQuickItem::setWidth(qreal w)
4378 d->widthValid = true;
4382 qreal oldWidth = d->width;
4385 d->dirty(QQuickItemPrivate::Size);
4387 geometryChanged(QRectF(x(), y(), width(), height()),
4388 QRectF(x(), y(), oldWidth, height()));
4391 void QQuickItem::resetWidth()
4394 d->widthValid = false;
4395 setImplicitWidth(implicitWidth());
4398 void QQuickItemPrivate::implicitWidthChanged()
4401 emit q->implicitWidthChanged();
4404 qreal QQuickItemPrivate::getImplicitWidth() const
4406 return implicitWidth;
4409 Returns the width of the item that is implied by other properties that determine the content.
4411 qreal QQuickItem::implicitWidth() const
4413 Q_D(const QQuickItem);
4414 return d->getImplicitWidth();
4418 \qmlproperty real QtQuick2::Item::implicitWidth
4419 \qmlproperty real QtQuick2::Item::implicitHeight
4421 Defines the natural width or height of the Item if no \l width or \l height is specified.
4423 The default implicit size for most items is 0x0, however some elements have an inherent
4424 implicit size which cannot be overridden, e.g. Image, Text.
4426 Setting the implicit size is useful for defining components that have a preferred size
4427 based on their content, for example:
4434 property alias icon: image.source
4435 property alias label: text.text
4436 implicitWidth: text.implicitWidth + image.implicitWidth
4437 implicitHeight: Math.max(text.implicitHeight, image.implicitHeight)
4442 anchors.left: image.right; anchors.right: parent.right
4443 anchors.verticalCenter: parent.verticalCenter
4448 \bold Note: using implicitWidth of Text or TextEdit and setting the width explicitly
4449 incurs a performance penalty as the text must be laid out twice.
4453 Sets the implied width of the item to \a w.
4454 This is the width implied by other properties that determine the content.
4456 void QQuickItem::setImplicitWidth(qreal w)
4459 bool changed = w != d->implicitWidth;
4460 d->implicitWidth = w;
4461 if (d->width == w || widthValid()) {
4463 d->implicitWidthChanged();
4467 qreal oldWidth = d->width;
4470 d->dirty(QQuickItemPrivate::Size);
4472 geometryChanged(QRectF(x(), y(), width(), height()),
4473 QRectF(x(), y(), oldWidth, height()));
4476 d->implicitWidthChanged();
4480 Returns whether the width property has been set explicitly.
4482 bool QQuickItem::widthValid() const
4484 Q_D(const QQuickItem);
4485 return d->widthValid;
4488 qreal QQuickItem::height() const
4490 Q_D(const QQuickItem);
4494 void QQuickItem::setHeight(qreal h)
4500 d->heightValid = true;
4504 qreal oldHeight = d->height;
4507 d->dirty(QQuickItemPrivate::Size);
4509 geometryChanged(QRectF(x(), y(), width(), height()),
4510 QRectF(x(), y(), width(), oldHeight));
4513 void QQuickItem::resetHeight()
4516 d->heightValid = false;
4517 setImplicitHeight(implicitHeight());
4520 void QQuickItemPrivate::implicitHeightChanged()
4523 emit q->implicitHeightChanged();
4526 qreal QQuickItemPrivate::getImplicitHeight() const
4528 return implicitHeight;
4532 Returns the height of the item that is implied by other properties that determine the content.
4534 qreal QQuickItem::implicitHeight() const
4536 Q_D(const QQuickItem);
4537 return d->getImplicitHeight();
4542 Sets the implied height of the item to \a h.
4543 This is the height implied by other properties that determine the content.
4545 void QQuickItem::setImplicitHeight(qreal h)
4548 bool changed = h != d->implicitHeight;
4549 d->implicitHeight = h;
4550 if (d->height == h || heightValid()) {
4552 d->implicitHeightChanged();
4556 qreal oldHeight = d->height;
4559 d->dirty(QQuickItemPrivate::Size);
4561 geometryChanged(QRectF(x(), y(), width(), height()),
4562 QRectF(x(), y(), width(), oldHeight));
4565 d->implicitHeightChanged();
4568 void QQuickItem::setImplicitSize(qreal w, qreal h)
4571 bool wChanged = w != d->implicitWidth;
4572 bool hChanged = h != d->implicitHeight;
4574 d->implicitWidth = w;
4575 d->implicitHeight = h;
4579 if (d->width == w || widthValid()) {
4581 d->implicitWidthChanged();
4584 if (d->height == h || heightValid()) {
4586 d->implicitHeightChanged();
4592 qreal oldWidth = d->width;
4593 qreal oldHeight = d->height;
4599 d->dirty(QQuickItemPrivate::Size);
4601 geometryChanged(QRectF(x(), y(), width(), height()),
4602 QRectF(x(), y(), oldWidth, oldHeight));
4604 if (!wDone && wChanged)
4605 d->implicitWidthChanged();
4606 if (!hDone && hChanged)
4607 d->implicitHeightChanged();
4611 Returns whether the height property has been set explicitly.
4613 bool QQuickItem::heightValid() const
4615 Q_D(const QQuickItem);
4616 return d->heightValid;
4619 void QQuickItem::setSize(const QSizeF &size)
4622 d->heightValid = true;
4623 d->widthValid = true;
4625 if (QSizeF(d->width, d->height) == size)
4628 qreal oldHeight = d->height;
4629 qreal oldWidth = d->width;
4630 d->height = size.height();
4631 d->width = size.width();
4633 d->dirty(QQuickItemPrivate::Size);
4635 geometryChanged(QRectF(x(), y(), width(), height()),
4636 QRectF(x(), y(), oldWidth, oldHeight));
4639 bool QQuickItem::hasActiveFocus() const
4641 Q_D(const QQuickItem);
4642 return d->activeFocus;
4645 bool QQuickItem::hasFocus() const
4647 Q_D(const QQuickItem);
4651 void QQuickItem::setFocus(bool focus)
4654 if (d->focus == focus)
4658 // Need to find our nearest focus scope
4659 QQuickItem *scope = parentItem();
4660 while (scope && !scope->isFocusScope())
4661 scope = scope->parentItem();
4663 QQuickCanvasPrivate::get(d->canvas)->setFocusInScope(scope, this);
4665 QQuickCanvasPrivate::get(d->canvas)->clearFocusInScope(scope, this);
4668 emit focusChanged(focus);
4672 bool QQuickItem::isFocusScope() const
4674 return flags() & ItemIsFocusScope;
4677 QQuickItem *QQuickItem::scopedFocusItem() const
4679 Q_D(const QQuickItem);
4680 if (!isFocusScope())
4683 return d->subFocusItem;
4687 Qt::MouseButtons QQuickItem::acceptedMouseButtons() const
4689 Q_D(const QQuickItem);
4690 return d->acceptedMouseButtons();
4693 void QQuickItem::setAcceptedMouseButtons(Qt::MouseButtons buttons)
4696 if (buttons & Qt::LeftButton)
4699 d->extra.clearFlag();
4701 buttons &= ~Qt::LeftButton;
4702 if (buttons || d->extra.isAllocated())
4703 d->extra.value().acceptedMouseButtons = buttons;
4706 bool QQuickItem::filtersChildMouseEvents() const
4708 Q_D(const QQuickItem);
4709 return d->filtersChildMouseEvents;
4712 void QQuickItem::setFiltersChildMouseEvents(bool filter)
4715 d->filtersChildMouseEvents = filter;
4718 bool QQuickItem::isUnderMouse() const
4720 Q_D(const QQuickItem);
4724 QPoint cursorPos = QCursor::pos();
4725 if (QRectF(0, 0, width(), height()).contains(mapFromScene(cursorPos))) // ### refactor: d->canvas->mapFromGlobal(cursorPos))))
4730 bool QQuickItem::acceptHoverEvents() const
4732 Q_D(const QQuickItem);
4733 return d->hoverEnabled;
4736 void QQuickItem::setAcceptHoverEvents(bool enabled)
4739 d->hoverEnabled = enabled;
4742 void QQuickItem::grabMouse()
4747 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
4748 if (canvasPriv->mouseGrabberItem == this)
4751 QQuickItem *oldGrabber = canvasPriv->mouseGrabberItem;
4752 canvasPriv->mouseGrabberItem = this;
4754 QEvent ev(QEvent::UngrabMouse);
4755 d->canvas->sendEvent(oldGrabber, &ev);
4759 void QQuickItem::ungrabMouse()
4764 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
4765 if (canvasPriv->mouseGrabberItem != this) {
4766 qWarning("QQuickItem::ungrabMouse(): Item is not the mouse grabber.");
4770 canvasPriv->mouseGrabberItem = 0;
4772 QEvent ev(QEvent::UngrabMouse);
4773 d->canvas->sendEvent(this, &ev);
4776 bool QQuickItem::keepMouseGrab() const
4778 Q_D(const QQuickItem);
4779 return d->keepMouse;
4783 The flag indicating whether the mouse should remain
4784 with this item is set to \a keep.
4786 This is useful for items that wish to grab and keep mouse
4787 interaction following a predefined gesture. For example,
4788 an item that is interested in horizontal mouse movement
4789 may set keepMouseGrab to true once a threshold has been
4790 exceeded. Once keepMouseGrab has been set to true, filtering
4791 items will not react to mouse events.
4793 If the item does not indicate that it wishes to retain mouse grab,
4794 a filtering item may steal the grab. For example, Flickable may attempt
4795 to steal a mouse grab if it detects that the user has begun to
4800 void QQuickItem::setKeepMouseGrab(bool keep)
4803 d->keepMouse = keep;
4807 Grabs the touch points specified by \a ids.
4809 These touch points will be owned by the item until
4810 they are released. Alternatively, the grab can be stolen
4811 by a filtering item like Flickable. Use setKeepTouchGrab()
4812 to prevent the grab from being stolen.
4814 \sa ungrabTouchPoints(), setKeepTouchGrab()
4816 void QQuickItem::grabTouchPoints(const QList<int> &ids)
4821 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
4823 QSet<QQuickItem*> ungrab;
4824 for (int i = 0; i < ids.count(); ++i) {
4825 QQuickItem *oldGrabber = canvasPriv->itemForTouchPointId.value(ids.at(i));
4826 if (oldGrabber == this)
4829 canvasPriv->itemForTouchPointId[ids.at(i)] = this;
4831 ungrab.insert(oldGrabber);
4833 foreach (QQuickItem *oldGrabber, ungrab)
4834 oldGrabber->touchUngrabEvent();
4838 Ungrabs the touch points owned by this item.
4840 \sa grabTouchPoints()
4842 void QQuickItem::ungrabTouchPoints()
4847 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
4849 QMutableHashIterator<int, QQuickItem*> i(canvasPriv->itemForTouchPointId);
4850 while (i.hasNext()) {
4852 if (i.value() == this)
4859 Returns a value indicating whether the touch points grabbed by this item
4860 should remain with this item exclusively.
4862 \sa setKeepTouchGrab(), keepMouseGrab()
4864 bool QQuickItem::keepTouchGrab() const
4866 Q_D(const QQuickItem);
4867 return d->keepTouch;
4871 The flag indicating whether the touch points grabbed
4872 by this item should remain with this item is set to \a keep.
4874 This is useful for items that wish to grab and keep specific touch
4875 points following a predefined gesture. For example,
4876 an item that is interested in horizontal touch point movement
4877 may set setKeepTouchGrab to true once a threshold has been
4878 exceeded. Once setKeepTouchGrab has been set to true, filtering
4879 items will not react to the relevant touch points.
4881 If the item does not indicate that it wishes to retain touch point grab,
4882 a filtering item may steal the grab. For example, Flickable may attempt
4883 to steal a touch point grab if it detects that the user has begun to
4886 \sa keepTouchGrab(), setKeepMouseGrab()
4888 void QQuickItem::setKeepTouchGrab(bool keep)
4891 d->keepTouch = keep;
4895 \qmlmethod object QtQuick2::Item::mapFromItem(Item item, real x, real y)
4897 Maps the point (\a x, \a y), which is in \a item's coordinate system, to
4898 this item's coordinate system, and returns an object with \c x and \c y
4899 properties matching the mapped coordinate.
4901 If \a item is a \c null value, this maps the point from the coordinate
4902 system of the root QML view.
4905 \qmlmethod object QtQuick2::Item::mapToItem(Item item, real x, real y)
4907 Maps the point (\a x, \a y), which is in this item's coordinate system, to
4908 \a item's coordinate system, and returns an object with \c x and \c y
4909 properties matching the mapped coordinate.
4911 If \a item is a \c null value, this maps \a x and \a y to the coordinate
4912 system of the root QML view.
4914 QPointF QQuickItem::mapToItem(const QQuickItem *item, const QPointF &point) const
4916 QPointF p = mapToScene(point);
4918 p = item->mapFromScene(p);
4922 QPointF QQuickItem::mapToScene(const QPointF &point) const
4924 Q_D(const QQuickItem);
4925 return d->itemToCanvasTransform().map(point);
4928 QRectF QQuickItem::mapRectToItem(const QQuickItem *item, const QRectF &rect) const
4930 Q_D(const QQuickItem);
4931 QTransform t = d->itemToCanvasTransform();
4933 t *= QQuickItemPrivate::get(item)->canvasToItemTransform();
4934 return t.mapRect(rect);
4937 QRectF QQuickItem::mapRectToScene(const QRectF &rect) const
4939 Q_D(const QQuickItem);
4940 return d->itemToCanvasTransform().mapRect(rect);
4943 QPointF QQuickItem::mapFromItem(const QQuickItem *item, const QPointF &point) const
4945 QPointF p = item?item->mapToScene(point):point;
4946 return mapFromScene(p);
4949 QPointF QQuickItem::mapFromScene(const QPointF &point) const
4951 Q_D(const QQuickItem);
4952 return d->canvasToItemTransform().map(point);
4955 QRectF QQuickItem::mapRectFromItem(const QQuickItem *item, const QRectF &rect) const
4957 Q_D(const QQuickItem);
4958 QTransform t = item?QQuickItemPrivate::get(item)->itemToCanvasTransform():QTransform();
4959 t *= d->canvasToItemTransform();
4960 return t.mapRect(rect);
4963 QRectF QQuickItem::mapRectFromScene(const QRectF &rect) const
4965 Q_D(const QQuickItem);
4966 return d->canvasToItemTransform().mapRect(rect);
4971 \qmlmethod QtQuick2::Item::forceActiveFocus()
4973 Forces active focus on the item.
4975 This method sets focus on the item and makes sure that all the focus scopes
4976 higher in the object hierarchy are also given the focus.
4980 Forces active focus on the item.
4982 This method sets focus on the item and makes sure that all the focus scopes
4983 higher in the object hierarchy are also given the focus.
4987 \qmlmethod QtQuick2::Item::childAt(real x, real y)
4989 Returns the visible child item at point (\a x, \a y), which is in this
4990 item's coordinate system, or \c null if there is no such item.
4994 Returns the visible child item at point (\a x, \a y), which is in this
4995 item's coordinate system, or 0 if there is no such item.
4999 \qmlproperty list<State> QtQuick2::Item::states
5000 This property holds a list of states defined by the item.
5016 \sa {qmlstate}{States}
5019 \qmlproperty list<Transition> QtQuick2::Item::transitions
5020 This property holds a list of transitions defined by the item.
5036 \sa {QML Animation and Transitions}{Transitions}
5039 \qmlproperty list<Filter> QtQuick2::Item::filter
5040 This property holds a list of graphical filters to be applied to the item.
5042 \l {Filter}{Filters} include things like \l {Blur}{blurring}
5043 the item, or giving it a \l Reflection. Some
5044 filters may not be available on all canvases; if a filter is not
5045 available on a certain canvas, it will simply not be applied for
5046 that canvas (but the QML will still be considered valid).
5064 \qmlproperty bool QtQuick2::Item::clip
5065 This property holds whether clipping is enabled. The default clip value is \c false.
5067 If clipping is enabled, an item will clip its own painting, as well
5068 as the painting of its children, to its bounding rectangle.
5070 Non-rectangular clipping regions are not supported for performance reasons.
5074 \property QQuickItem::clip
5075 This property holds whether clipping is enabled. The default clip value is \c false.
5077 If clipping is enabled, an item will clip its own painting, as well
5078 as the painting of its children, to its bounding rectangle. If you set
5079 clipping during an item's paint operation, remember to re-set it to
5080 prevent clipping the rest of your scene.
5082 Non-rectangular clipping regions are not supported for performance reasons.
5086 \qmlproperty string QtQuick2::Item::state
5088 This property holds the name of the current state of the item.
5090 This property is often used in scripts to change between states. For
5095 if (button.state == 'On')
5096 button.state = 'Off';
5098 button.state = 'On';
5102 If the item is in its base state (i.e. no explicit state has been
5103 set), \c state will be a blank string. Likewise, you can return an
5104 item to its base state by setting its current state to \c ''.
5106 \sa {qmlstates}{States}
5110 \qmlproperty list<Transform> QtQuick2::Item::transform
5111 This property holds the list of transformations to apply.
5113 For more information see \l Transform.
5117 \enum QQuickItem::TransformOrigin
5119 Controls the point about which simple transforms like scale apply.
5121 \value TopLeft The top-left corner of the item.
5122 \value Top The center point of the top of the item.
5123 \value TopRight The top-right corner of the item.
5124 \value Left The left most point of the vertical middle.
5125 \value Center The center of the item.
5126 \value Right The right most point of the vertical middle.
5127 \value BottomLeft The bottom-left corner of the item.
5128 \value Bottom The center point of the bottom of the item.
5129 \value BottomRight The bottom-right corner of the item.
5134 \qmlproperty bool QtQuick2::Item::activeFocus
5136 This property indicates whether the item has active focus.
5138 An item with active focus will receive keyboard input,
5139 or is a FocusScope ancestor of the item that will receive keyboard input.
5141 Usually, activeFocus is gained by setting focus on an item and its enclosing
5142 FocusScopes. In the following example \c input will have activeFocus.
5155 \sa focus, {qmlfocus}{Keyboard Focus}
5159 \qmlproperty bool QtQuick2::Item::focus
5160 This property indicates whether the item has focus within the enclosing focus scope. If true, this item
5161 will gain active focus when the enclosing focus scope gains active focus.
5162 In the following example, \c input will be given active focus when \c scope gains active focus.
5175 For the purposes of this property, the scene as a whole is assumed to act like a focus scope.
5176 On a practical level, that means the following QML will give active focus to \c input on startup.
5187 \sa activeFocus, {qmlfocus}{Keyboard Focus}
5192 \property QQuickItem::anchors
5197 \property QQuickItem::left
5202 \property QQuickItem::right
5207 \property QQuickItem::horizontalCenter
5212 \property QQuickItem::top
5217 \property QQuickItem::bottom
5222 \property QQuickItem::verticalCenter
5227 \property QQuickItem::focus
5232 \property QQuickItem::transform
5237 \property QQuickItem::transformOrigin
5242 \property QQuickItem::activeFocus
5247 \property QQuickItem::baseline
5252 \property QQuickItem::data
5257 \property QQuickItem::resources
5262 \property QQuickItem::state
5267 \property QQuickItem::states
5272 \property QQuickItem::transformOriginPoint
5277 \property QQuickItem::transitions
5281 bool QQuickItem::event(QEvent *ev)
5284 if (ev->type() == QEvent::PolishRequest) {
5286 d->polishScheduled = false;
5290 return QObject::event(ev);
5293 if (ev->type() == QEvent::InputMethodQuery) {
5294 QInputMethodQueryEvent *query = static_cast<QInputMethodQueryEvent *>(ev);
5295 Qt::InputMethodQueries queries = query->queries();
5296 for (uint i = 0; i < 32; ++i) {
5297 Qt::InputMethodQuery q = (Qt::InputMethodQuery)(int)(queries & (1<<i));
5299 QVariant v = inputMethodQuery(q);
5300 query->setValue(q, v);
5305 } else if (ev->type() == QEvent::InputMethod) {
5306 inputMethodEvent(static_cast<QInputMethodEvent *>(ev));
5309 return QObject::event(ev);
5312 #ifndef QT_NO_DEBUG_STREAM
5313 QDebug operator<<(QDebug debug, QQuickItem *item)
5316 debug << "QQuickItem(0)";
5320 debug << item->metaObject()->className() << "(this =" << ((void*)item)
5321 << ", name=" << item->objectName()
5322 << ", parent =" << ((void*)item->parentItem())
5323 << ", geometry =" << QRectF(item->pos(), QSizeF(item->width(), item->height()))
5324 << ", z =" << item->z() << ')';
5329 qint64 QQuickItemPrivate::consistentTime = -1;
5330 void QQuickItemPrivate::setConsistentTime(qint64 t)
5335 class QElapsedTimerConsistentTimeHack
5339 t1 = QQuickItemPrivate::consistentTime;
5343 return QQuickItemPrivate::consistentTime - t1;
5346 qint64 val = QQuickItemPrivate::consistentTime - t1;
5347 t1 = QQuickItemPrivate::consistentTime;
5357 void QQuickItemPrivate::start(QElapsedTimer &t)
5359 if (QQuickItemPrivate::consistentTime == -1)
5362 ((QElapsedTimerConsistentTimeHack*)&t)->start();
5365 qint64 QQuickItemPrivate::elapsed(QElapsedTimer &t)
5367 if (QQuickItemPrivate::consistentTime == -1)
5370 return ((QElapsedTimerConsistentTimeHack*)&t)->elapsed();
5373 qint64 QQuickItemPrivate::restart(QElapsedTimer &t)
5375 if (QQuickItemPrivate::consistentTime == -1)
5378 return ((QElapsedTimerConsistentTimeHack*)&t)->restart();
5382 \fn bool QQuickItem::isTextureProvider() const
5384 Returns true if this item is a texture provider. The default
5385 implementation returns false.
5387 This function can be called from any thread.
5390 bool QQuickItem::isTextureProvider() const
5392 Q_D(const QQuickItem);
5393 return d->extra.isAllocated() && d->extra->layer && d->extra->layer->effectSource() ?
5394 d->extra->layer->effectSource()->isTextureProvider() : false;
5398 \fn QSGTextureProvider *QQuickItem::textureProvider() const
5400 Returns the texture provider for an item. The default implementation
5403 This function may only be called on the rendering thread.
5406 QSGTextureProvider *QQuickItem::textureProvider() const
5408 Q_D(const QQuickItem);
5409 return d->extra.isAllocated() && d->extra->layer && d->extra->layer->effectSource() ?
5410 d->extra->layer->effectSource()->textureProvider() : 0;
5413 QQuickItemLayer *QQuickItemPrivate::layer() const
5415 if (!extra.isAllocated() || !extra->layer) {
5416 extra.value().layer = new QQuickItemLayer(const_cast<QQuickItem *>(q_func()));
5417 if (!componentComplete)
5418 extra->layer->classBegin();
5420 return extra->layer;
5423 QQuickItemLayer::QQuickItemLayer(QQuickItem *item)
5428 , m_componentComplete(true)
5429 , m_wrapMode(QQuickShaderEffectSource::ClampToEdge)
5430 , m_format(QQuickShaderEffectSource::RGBA)
5432 , m_effectComponent(0)
5438 QQuickItemLayer::~QQuickItemLayer()
5440 delete m_effectSource;
5447 \qmlproperty bool QtQuick2::Item::layer.enabled
5449 Holds wether the item is layered or not. Layering is disabled by default.
5451 A layered item is rendered into an offscreen surface and cached until
5452 it is changed. Enabling layering for complex QML item hierarchies can
5453 some times be an optimization.
5455 None of the other layer properties have any effect when the layer
5459 void QQuickItemLayer::setEnabled(bool e)
5464 if (m_componentComplete) {
5471 emit enabledChanged(e);
5474 void QQuickItemLayer::classBegin()
5476 Q_ASSERT(!m_effectSource);
5477 Q_ASSERT(!m_effect);
5478 m_componentComplete = false;
5481 void QQuickItemLayer::componentComplete()
5483 Q_ASSERT(!m_componentComplete);
5484 m_componentComplete = true;
5489 void QQuickItemLayer::activate()
5491 Q_ASSERT(!m_effectSource);
5492 m_effectSource = new QQuickShaderEffectSource();
5494 QQuickItem *parentItem = m_item->parentItem();
5496 m_effectSource->setParentItem(parentItem);
5497 m_effectSource->stackAfter(m_item);
5500 m_effectSource->setSourceItem(m_item);
5501 m_effectSource->setHideSource(true);
5502 m_effectSource->setSmooth(m_smooth);
5503 m_effectSource->setTextureSize(m_size);
5504 m_effectSource->setSourceRect(m_sourceRect);
5505 m_effectSource->setMipmap(m_mipmap);
5506 m_effectSource->setWrapMode(m_wrapMode);
5507 m_effectSource->setFormat(m_format);
5509 if (m_effectComponent)
5512 m_effectSource->setVisible(m_item->isVisible() && !m_effect);
5519 QQuickItemPrivate *id = QQuickItemPrivate::get(m_item);
5520 id->addItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Opacity | QQuickItemPrivate::Parent | QQuickItemPrivate::Visibility | QQuickItemPrivate::SiblingOrder);
5523 void QQuickItemLayer::deactivate()
5525 Q_ASSERT(m_effectSource);
5527 if (m_effectComponent)
5530 delete m_effectSource;
5533 QQuickItemPrivate *id = QQuickItemPrivate::get(m_item);
5534 id->removeItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Opacity | QQuickItemPrivate::Parent | QQuickItemPrivate::Visibility | QQuickItemPrivate::SiblingOrder);
5537 void QQuickItemLayer::activateEffect()
5539 Q_ASSERT(m_effectSource);
5540 Q_ASSERT(m_effectComponent);
5541 Q_ASSERT(!m_effect);
5543 QObject *created = m_effectComponent->create();
5544 m_effect = qobject_cast<QQuickItem *>(created);
5546 qWarning("Item: layer.effect is not a QML Item.");
5550 QQuickItem *parentItem = m_item->parentItem();
5552 m_effect->setParentItem(parentItem);
5553 m_effect->stackAfter(m_effectSource);
5555 m_effect->setVisible(m_item->isVisible());
5556 m_effect->setProperty(m_name, qVariantFromValue<QObject *>(m_effectSource));
5559 void QQuickItemLayer::deactivateEffect()
5561 Q_ASSERT(m_effectSource);
5562 Q_ASSERT(m_effectComponent);
5570 \qmlproperty Component QtQuick2::Item::layer.effect
5572 Holds the effect that is applied to this layer.
5574 The effect is typically a \l ShaderEffect component, although any \l Item component can be
5575 assigned. The effect should have a source texture property with a name matching \l samplerName.
5580 void QQuickItemLayer::setEffect(QQmlComponent *component)
5582 if (component == m_effectComponent)
5585 bool updateNeeded = false;
5586 if (m_effectSource && m_effectComponent) {
5588 updateNeeded = true;
5591 m_effectComponent = component;
5593 if (m_effectSource && m_effectComponent) {
5595 updateNeeded = true;
5603 m_effectSource->setVisible(m_item->isVisible() && !m_effect);
5606 emit effectChanged(component);
5611 \qmlproperty bool QtQuick2::Item::layer.mipmap
5613 If this property is true, mipmaps are generated for the texture.
5615 \note Some OpenGL ES 2 implementations do not support mipmapping of
5616 non-power-of-two textures.
5619 void QQuickItemLayer::setMipmap(bool mipmap)
5621 if (mipmap == m_mipmap)
5626 m_effectSource->setMipmap(m_mipmap);
5628 emit mipmapChanged(mipmap);
5633 \qmlproperty enumeration QtQuick2::Item::layer.format
5635 This property defines the internal OpenGL format of the texture.
5636 Modifying this property makes most sense when the \a layer.effect is also
5637 specified. Depending on the OpenGL implementation, this property might
5638 allow you to save some texture memory.
5641 \o ShaderEffectSource.Alpha - GL_ALPHA
5642 \o ShaderEffectSource.RGB - GL_RGB
5643 \o ShaderEffectSource.RGBA - GL_RGBA
5646 \note Some OpenGL implementations do not support the GL_ALPHA format.
5649 void QQuickItemLayer::setFormat(QQuickShaderEffectSource::Format f)
5656 m_effectSource->setFormat(m_format);
5658 emit formatChanged(m_format);
5663 \qmlproperty enumeration QtQuick2::Item::layer.sourceRect
5665 This property defines which rectangular area of the \l sourceItem to
5666 render into the texture. The source rectangle can be larger than
5667 \l sourceItem itself. If the rectangle is null, which is the default,
5668 the whole \l sourceItem is rendered to texture.
5671 void QQuickItemLayer::setSourceRect(const QRectF &sourceRect)
5673 if (sourceRect == m_sourceRect)
5675 m_sourceRect = sourceRect;
5678 m_effectSource->setSourceRect(m_sourceRect);
5680 emit sourceRectChanged(sourceRect);
5686 \qmlproperty bool QtQuick2::Item::layer.smooth
5688 Holds whether the layer is smoothly transformed.
5691 void QQuickItemLayer::setSmooth(bool s)
5698 m_effectSource->setSmooth(m_smooth);
5700 emit smoothChanged(s);
5706 \qmlproperty size QtQuick2::Item::layer.textureSize
5708 This property holds the requested pixel size of the layers texture. If it is empty,
5709 which is the default, the size of the item is used.
5711 \note Some platforms have a limit on how small framebuffer objects can be,
5712 which means the actual texture size might be larger than the requested
5716 void QQuickItemLayer::setSize(const QSize &size)
5723 m_effectSource->setTextureSize(size);
5725 emit sizeChanged(size);
5731 \qmlproperty enumeration QtQuick2::Item::layer.wrapMode
5733 This property defines the OpenGL wrap modes associated with the texture.
5734 Modifying this property makes most sense when the \a layer.effect is
5738 \o ShaderEffectSource.ClampToEdge - GL_CLAMP_TO_EDGE both horizontally and vertically
5739 \o ShaderEffectSource.RepeatHorizontally - GL_REPEAT horizontally, GL_CLAMP_TO_EDGE vertically
5740 \o ShaderEffectSource.RepeatVertically - GL_CLAMP_TO_EDGE horizontally, GL_REPEAT vertically
5741 \o ShaderEffectSource.Repeat - GL_REPEAT both horizontally and vertically
5744 \note Some OpenGL ES 2 implementations do not support the GL_REPEAT
5745 wrap mode with non-power-of-two textures.
5748 void QQuickItemLayer::setWrapMode(QQuickShaderEffectSource::WrapMode mode)
5750 if (mode != m_wrapMode)
5755 m_effectSource->setWrapMode(m_wrapMode);
5757 emit wrapModeChanged(mode);
5761 \qmlproperty string QtQuick2::Item::layer.samplerName
5763 Holds the name of the effect's source texture property.
5765 samplerName needs to match the name of the effect's source texture property
5766 so that the Item can pass the layer's offscreen surface to the effect correctly.
5768 \sa effect, ShaderEffect
5771 void QQuickItemLayer::setName(const QByteArray &name) {
5775 m_effect->setProperty(m_name, QVariant());
5776 m_effect->setProperty(name, qVariantFromValue<QObject *>(m_effectSource));
5779 emit nameChanged(name);
5782 void QQuickItemLayer::itemOpacityChanged(QQuickItem *item)
5788 void QQuickItemLayer::itemGeometryChanged(QQuickItem *, const QRectF &, const QRectF &)
5793 void QQuickItemLayer::itemParentChanged(QQuickItem *item, QQuickItem *parent)
5796 Q_ASSERT(item == m_item);
5797 Q_ASSERT(parent != m_effectSource);
5798 Q_ASSERT(parent == 0 || parent != m_effect);
5800 m_effectSource->setParentItem(parent);
5802 m_effectSource->stackAfter(m_item);
5805 m_effect->setParentItem(parent);
5807 m_effect->stackAfter(m_effectSource);
5811 void QQuickItemLayer::itemSiblingOrderChanged(QQuickItem *)
5813 m_effectSource->stackAfter(m_item);
5815 m_effect->stackAfter(m_effectSource);
5818 void QQuickItemLayer::itemVisibilityChanged(QQuickItem *)
5820 QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
5822 l->setVisible(m_item->isVisible());
5825 void QQuickItemLayer::updateZ()
5827 if (!m_componentComplete || !m_enabled)
5829 QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
5831 l->setZ(m_item->z());
5834 void QQuickItemLayer::updateOpacity()
5836 QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
5838 l->setOpacity(m_item->opacity());
5841 void QQuickItemLayer::updateGeometry()
5843 QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
5845 QRectF bounds = m_item->clipRect();
5846 l->setWidth(bounds.width());
5847 l->setHeight(bounds.height());
5848 l->setX(bounds.x() + m_item->x());
5849 l->setY(bounds.y() + m_item->y());
5852 void QQuickItemLayer::updateMatrix()
5854 // Called directly from transformChanged(), so needs some extra
5856 if (!m_componentComplete || !m_enabled)
5858 QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
5860 QQuickItemPrivate *ld = QQuickItemPrivate::get(l);
5861 l->setScale(m_item->scale());
5862 l->setRotation(m_item->rotation());
5863 ld->transforms = QQuickItemPrivate::get(m_item)->transforms;
5864 if (ld->origin() != QQuickItemPrivate::get(m_item)->origin())
5865 ld->extra.value().origin = QQuickItemPrivate::get(m_item)->origin();
5866 ld->dirty(QQuickItemPrivate::Transform);
5869 QQuickItemPrivate::ExtraData::ExtraData()
5870 : z(0), scale(1), rotation(0), opacity(1),
5871 contents(0), screenAttached(0), layoutDirectionAttached(0),
5872 keyHandler(0), layer(0), effectRefCount(0), hideRefCount(0),
5873 opacityNode(0), clipNode(0), rootNode(0), beforePaintNode(0),
5874 acceptedMouseButtons(0), origin(QQuickItem::Center)
5880 #include <moc_qquickitem.cpp>