1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the QtQml module of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #include "qquickitem.h"
44 #include "qquickcanvas.h"
45 #include <QtQml/qjsengine.h>
46 #include "qquickcanvas_p.h"
48 #include "qquickevents_p_p.h"
49 #include "qquickscreen_p.h"
51 #include <QtQml/qqmlengine.h>
52 #include <QtQml/qqmlcomponent.h>
53 #include <QtQml/qqmlinfo.h>
54 #include <QtGui/qpen.h>
55 #include <QtGui/qguiapplication.h>
56 #include <QtGui/private/qguiapplication_p.h>
57 #include <QtGui/qinputmethod.h>
58 #include <QtCore/qdebug.h>
59 #include <QtCore/qcoreevent.h>
60 #include <QtCore/qnumeric.h>
62 #include <private/qqmlglobal_p.h>
63 #include <private/qqmlengine_p.h>
64 #include <QtQuick/private/qquickstategroup_p.h>
65 #include <private/qqmlopenmetaobject_p.h>
66 #include <QtQuick/private/qquickstate_p.h>
67 #include <private/qlistmodelinterface_p.h>
68 #include <private/qquickitem_p.h>
69 #include <private/qqmlaccessors_p.h>
70 #include <QtQuick/private/qquickaccessibleattached_p.h>
74 // XXX todo Check that elements that create items handle memory correctly after visual ownership change
79 void printFocusTree(QQuickItem *item, QQuickItem *scope = 0, int depth = 1);
80 void printFocusTree(QQuickItem *item, QQuickItem *scope, int depth)
83 << QByteArray(depth, '\t').constData()
84 << (scope && QQuickItemPrivate::get(scope)->subFocusItem == item ? '*' : ' ')
86 << item->hasActiveFocus()
87 << item->isFocusScope()
89 foreach (QQuickItem *child, item->childItems()) {
92 item->isFocusScope() || !scope ? item : scope,
93 item->isFocusScope() || !scope ? depth + 1 : depth);
98 static void QQuickItem_parentNotifier(QObject *o, intptr_t, QQmlNotifier **n)
100 QQuickItemPrivate *d = QQuickItemPrivate::get(static_cast<QQuickItem *>(o));
101 *n = &d->parentNotifier;
104 QML_PRIVATE_ACCESSOR(QQuickItem, QQuickItem *, parent, parentItem)
105 QML_PRIVATE_ACCESSOR(QQuickItem, qreal, x, x)
106 QML_PRIVATE_ACCESSOR(QQuickItem, qreal, y, y)
107 QML_PRIVATE_ACCESSOR(QQuickItem, qreal, width, width)
108 QML_PRIVATE_ACCESSOR(QQuickItem, qreal, height, height)
110 static QQmlAccessors QQuickItem_parent = { QQuickItem_parentRead, QQuickItem_parentNotifier };
111 static QQmlAccessors QQuickItem_x = { QQuickItem_xRead, 0 };
112 static QQmlAccessors QQuickItem_y = { QQuickItem_yRead, 0 };
113 static QQmlAccessors QQuickItem_width = { QQuickItem_widthRead, 0 };
114 static QQmlAccessors QQuickItem_height = { QQuickItem_heightRead, 0 };
116 QML_DECLARE_PROPERTIES(QQuickItem) {
117 { QML_PROPERTY_NAME(parent), 0, &QQuickItem_parent },
118 { QML_PROPERTY_NAME(x), 0, &QQuickItem_x },
119 { QML_PROPERTY_NAME(y), 0, &QQuickItem_y },
120 { QML_PROPERTY_NAME(width), 0, &QQuickItem_width },
121 { QML_PROPERTY_NAME(height), 0, &QQuickItem_height }
124 void QQuickItemPrivate::registerAccessorProperties()
126 QML_DEFINE_PROPERTIES(QQuickItem);
130 \qmlclass Transform QQuickTransform
131 \inqmlmodule QtQuick 2
132 \ingroup qml-transform-elements
133 \brief The Transform elements provide a way of building advanced transformations on Items.
135 The Transform element is a base type which cannot be instantiated directly.
136 The following concrete Transform types are available:
144 The Transform elements let you create and control advanced transformations that can be configured
145 independently using specialized properties.
147 You can assign any number of Transform elements to an \l Item. Each Transform is applied in order,
152 \qmlclass Translate QQuickTranslate
153 \inqmlmodule QtQuick 2
154 \ingroup qml-transform-elements
155 \brief The Translate object provides a way to move an Item without changing its x or y properties.
157 The Translate object provides independent control over position in addition to the Item's x and y properties.
159 The following example moves the Y axis of the \l Rectangle elements while still allowing the \l Row element
160 to lay the items out as if they had not been transformed:
166 width: 100; height: 100
168 transform: Translate { y: 20 }
171 width: 100; height: 100
173 transform: Translate { y: -20 }
182 \qmlproperty real QtQuick2::Translate::x
184 The translation along the X axis.
188 \qmlproperty real QtQuick2::Translate::y
190 The translation along the Y axis.
194 \qmlclass Scale QQuickScale
195 \inqmlmodule QtQuick 2
196 \ingroup qml-transform-elements
197 \brief The Scale element provides a way to scale an Item.
199 The Scale element gives more control over scaling than using \l Item's \l{Item::scale}{scale} property. Specifically,
200 it allows a different scale for the x and y axes, and allows the scale to be relative to an
203 The following example scales the X axis of the Rectangle, relative to its interior point 25, 25:
206 width: 100; height: 100
208 transform: Scale { origin.x: 25; origin.y: 25; xScale: 3}
212 \sa Rotation, Translate
216 \qmlproperty real QtQuick2::Scale::origin.x
217 \qmlproperty real QtQuick2::Scale::origin.y
219 The point that the item is scaled from (i.e., the point that stays fixed relative to the parent as
220 the rest of the item grows). By default the origin is 0, 0.
224 \qmlproperty real QtQuick2::Scale::xScale
226 The scaling factor for the X axis.
230 \qmlproperty real QtQuick2::Scale::yScale
232 The scaling factor for the Y axis.
236 \qmlclass Rotation QQuickRotation
237 \inqmlmodule QtQuick 2
238 \ingroup qml-transform-elements
239 \brief The Rotation object provides a way to rotate an Item.
241 The Rotation object gives more control over rotation than using \l Item's \l{Item::rotation}{rotation} property.
242 Specifically, it allows (z axis) rotation to be relative to an arbitrary point.
244 The following example rotates a Rectangle around its interior point 25, 25:
247 width: 100; height: 100
249 transform: Rotation { origin.x: 25; origin.y: 25; angle: 45}
253 Rotation also provides a way to specify 3D-like rotations for Items. For these types of
254 rotations you must specify the axis to rotate around in addition to the origin point.
256 The following example shows various 3D-like rotations applied to an \l Image.
257 \snippet doc/src/snippets/qml/rotation.qml 0
259 \image axisrotation.png
261 \sa {declarative/ui-components/dialcontrol}{Dial Control example}, {declarative/toys/clocks}{Clocks example}
265 \qmlproperty real QtQuick2::Rotation::origin.x
266 \qmlproperty real QtQuick2::Rotation::origin.y
268 The origin point of the rotation (i.e., the point that stays fixed relative to the parent as
269 the rest of the item rotates). By default the origin is 0, 0.
273 \qmlproperty real QtQuick2::Rotation::axis.x
274 \qmlproperty real QtQuick2::Rotation::axis.y
275 \qmlproperty real QtQuick2::Rotation::axis.z
277 The axis to rotate around. For simple (2D) rotation around a point, you do not need to specify an axis,
278 as the default axis is the z axis (\c{ axis { x: 0; y: 0; z: 1 } }).
280 For a typical 3D-like rotation you will usually specify both the origin and the axis.
282 \image 3d-rotation-axis.png
286 \qmlproperty real QtQuick2::Rotation::angle
288 The angle to rotate, in degrees clockwise.
291 QQuickTransformPrivate::QQuickTransformPrivate()
295 QQuickTransform::QQuickTransform(QObject *parent)
296 : QObject(*(new QQuickTransformPrivate), parent)
300 QQuickTransform::QQuickTransform(QQuickTransformPrivate &dd, QObject *parent)
301 : QObject(dd, parent)
305 QQuickTransform::~QQuickTransform()
307 Q_D(QQuickTransform);
308 for (int ii = 0; ii < d->items.count(); ++ii) {
309 QQuickItemPrivate *p = QQuickItemPrivate::get(d->items.at(ii));
310 p->transforms.removeOne(this);
311 p->dirty(QQuickItemPrivate::Transform);
315 void QQuickTransform::update()
317 Q_D(QQuickTransform);
318 for (int ii = 0; ii < d->items.count(); ++ii) {
319 QQuickItemPrivate *p = QQuickItemPrivate::get(d->items.at(ii));
320 p->dirty(QQuickItemPrivate::Transform);
324 QQuickContents::QQuickContents(QQuickItem *item)
325 : m_item(item), m_x(0), m_y(0), m_width(0), m_height(0)
329 QQuickContents::~QQuickContents()
331 QList<QQuickItem *> children = m_item->childItems();
332 for (int i = 0; i < children.count(); ++i) {
333 QQuickItem *child = children.at(i);
334 QQuickItemPrivate::get(child)->removeItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed);
338 bool QQuickContents::calcHeight(QQuickItem *changed)
341 qreal oldheight = m_height;
345 qreal bottom = oldy + oldheight;
346 qreal y = changed->y();
347 if (y + changed->height() > bottom)
348 bottom = y + changed->height();
352 m_height = bottom - top;
356 QList<QQuickItem *> children = m_item->childItems();
357 for (int i = 0; i < children.count(); ++i) {
358 QQuickItem *child = children.at(i);
359 qreal y = child->y();
360 if (y + child->height() > bottom)
361 bottom = y + child->height();
365 if (!children.isEmpty())
367 m_height = qMax(bottom - top, qreal(0.0));
370 return (m_height != oldheight || m_y != oldy);
373 bool QQuickContents::calcWidth(QQuickItem *changed)
376 qreal oldwidth = m_width;
380 qreal right = oldx + oldwidth;
381 qreal x = changed->x();
382 if (x + changed->width() > right)
383 right = x + changed->width();
387 m_width = right - left;
389 qreal left = FLT_MAX;
391 QList<QQuickItem *> children = m_item->childItems();
392 for (int i = 0; i < children.count(); ++i) {
393 QQuickItem *child = children.at(i);
394 qreal x = child->x();
395 if (x + child->width() > right)
396 right = x + child->width();
400 if (!children.isEmpty())
402 m_width = qMax(right - left, qreal(0.0));
405 return (m_width != oldwidth || m_x != oldx);
408 void QQuickContents::complete()
410 QQuickItemPrivate::get(m_item)->addItemChangeListener(this, QQuickItemPrivate::Children);
412 QList<QQuickItem *> children = m_item->childItems();
413 for (int i = 0; i < children.count(); ++i) {
414 QQuickItem *child = children.at(i);
415 QQuickItemPrivate::get(child)->addItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed);
416 //###what about changes to visibility?
421 void QQuickContents::updateRect()
423 QQuickItemPrivate::get(m_item)->emitChildrenRectChanged(rectF());
426 void QQuickContents::itemGeometryChanged(QQuickItem *changed, const QRectF &newGeometry, const QRectF &oldGeometry)
429 bool wChanged = false;
430 bool hChanged = false;
431 //### we can only pass changed if the left edge has moved left, or the right edge has moved right
432 if (newGeometry.width() != oldGeometry.width() || newGeometry.x() != oldGeometry.x())
433 wChanged = calcWidth(/*changed*/);
434 if (newGeometry.height() != oldGeometry.height() || newGeometry.y() != oldGeometry.y())
435 hChanged = calcHeight(/*changed*/);
436 if (wChanged || hChanged)
440 void QQuickContents::itemDestroyed(QQuickItem *item)
443 QQuickItemPrivate::get(item)->removeItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed);
447 void QQuickContents::itemChildRemoved(QQuickItem *, QQuickItem *item)
450 QQuickItemPrivate::get(item)->removeItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed);
454 void QQuickContents::itemChildAdded(QQuickItem *, QQuickItem *item)
457 QQuickItemPrivate::get(item)->addItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed);
461 QQuickItemKeyFilter::QQuickItemKeyFilter(QQuickItem *item)
462 : m_processPost(false), m_next(0)
464 QQuickItemPrivate *p = item?QQuickItemPrivate::get(item):0;
466 m_next = p->extra.value().keyHandler;
467 p->extra->keyHandler = this;
471 QQuickItemKeyFilter::~QQuickItemKeyFilter()
475 void QQuickItemKeyFilter::keyPressed(QKeyEvent *event, bool post)
477 if (m_next) m_next->keyPressed(event, post);
480 void QQuickItemKeyFilter::keyReleased(QKeyEvent *event, bool post)
482 if (m_next) m_next->keyReleased(event, post);
485 void QQuickItemKeyFilter::inputMethodEvent(QInputMethodEvent *event, bool post)
488 m_next->inputMethodEvent(event, post);
493 QVariant QQuickItemKeyFilter::inputMethodQuery(Qt::InputMethodQuery query) const
495 if (m_next) return m_next->inputMethodQuery(query);
499 void QQuickItemKeyFilter::componentComplete()
501 if (m_next) m_next->componentComplete();
504 \qmlclass KeyNavigation QQuickKeyNavigationAttached
505 \inqmlmodule QtQuick 2
506 \ingroup qml-basic-interaction-elements
507 \brief The KeyNavigation attached property supports key navigation by arrow keys.
509 Key-based user interfaces commonly allow the use of arrow keys to navigate between
510 focusable items. The KeyNavigation attached property enables this behavior by providing a
511 convenient way to specify the item that should gain focus when an arrow or tab key is pressed.
513 The following example provides key navigation for a 2x2 grid of items:
515 \snippet doc/src/snippets/qml/keynavigation.qml 0
517 The top-left item initially receives focus by setting \l {Item::}{focus} to
518 \c true. When an arrow key is pressed, the focus will move to the
519 appropriate item, as defined by the value that has been set for
520 the KeyNavigation \l left, \l right, \l up or \l down properties.
522 Note that if a KeyNavigation attached property receives the key press and release
523 events for a requested arrow or tab key, the event is accepted and does not
524 propagate any further.
526 By default, KeyNavigation receives key events after the item to which it is attached.
527 If the item accepts the key event, the KeyNavigation attached property will not
528 receive an event for that key. Setting the \l priority property to
529 \c KeyNavigation.BeforeItem allows the event to be used for key navigation
530 before the item, rather than after.
532 If item to which the focus is switching is not enabled or visible, an attempt will
533 be made to skip this item and focus on the next. This is possible if there are
534 a chain of items with the same KeyNavigation handler. If multiple items in a row are not enabled
535 or visible, they will also be skipped.
537 KeyNavigation will implicitly set the other direction to return focus to this item. So if you set
538 \l left to another item, \l right will be set on that item's KeyNavigation to set focus back to this
539 item. However, if that item's KeyNavigation has had right explicitly set then no change will occur.
540 This means that the above example could have been written, with the same behaviour, without specifing
541 KeyNavigation.right or KeyNavigation.down for any of the items.
543 \sa {Keys}{Keys attached property}
547 \qmlproperty Item QtQuick2::KeyNavigation::left
548 \qmlproperty Item QtQuick2::KeyNavigation::right
549 \qmlproperty Item QtQuick2::KeyNavigation::up
550 \qmlproperty Item QtQuick2::KeyNavigation::down
551 \qmlproperty Item QtQuick2::KeyNavigation::tab
552 \qmlproperty Item QtQuick2::KeyNavigation::backtab
554 These properties hold the item to assign focus to
555 when the left, right, up or down cursor keys, or the
560 \qmlproperty Item QtQuick2::KeyNavigation::tab
561 \qmlproperty Item QtQuick2::KeyNavigation::backtab
563 These properties hold the item to assign focus to
564 when the Tab key or Shift+Tab key combination (Backtab) are pressed.
567 QQuickKeyNavigationAttached::QQuickKeyNavigationAttached(QObject *parent)
568 : QObject(*(new QQuickKeyNavigationAttachedPrivate), parent),
569 QQuickItemKeyFilter(qobject_cast<QQuickItem*>(parent))
571 m_processPost = true;
574 QQuickKeyNavigationAttached *
575 QQuickKeyNavigationAttached::qmlAttachedProperties(QObject *obj)
577 return new QQuickKeyNavigationAttached(obj);
580 QQuickItem *QQuickKeyNavigationAttached::left() const
582 Q_D(const QQuickKeyNavigationAttached);
586 void QQuickKeyNavigationAttached::setLeft(QQuickItem *i)
588 Q_D(QQuickKeyNavigationAttached);
593 QQuickKeyNavigationAttached* other =
594 qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
595 if (other && !other->d_func()->rightSet){
596 other->d_func()->right = qobject_cast<QQuickItem*>(parent());
597 emit other->rightChanged();
602 QQuickItem *QQuickKeyNavigationAttached::right() const
604 Q_D(const QQuickKeyNavigationAttached);
608 void QQuickKeyNavigationAttached::setRight(QQuickItem *i)
610 Q_D(QQuickKeyNavigationAttached);
615 QQuickKeyNavigationAttached* other =
616 qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
617 if (other && !other->d_func()->leftSet){
618 other->d_func()->left = qobject_cast<QQuickItem*>(parent());
619 emit other->leftChanged();
624 QQuickItem *QQuickKeyNavigationAttached::up() const
626 Q_D(const QQuickKeyNavigationAttached);
630 void QQuickKeyNavigationAttached::setUp(QQuickItem *i)
632 Q_D(QQuickKeyNavigationAttached);
637 QQuickKeyNavigationAttached* other =
638 qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
639 if (other && !other->d_func()->downSet){
640 other->d_func()->down = qobject_cast<QQuickItem*>(parent());
641 emit other->downChanged();
646 QQuickItem *QQuickKeyNavigationAttached::down() const
648 Q_D(const QQuickKeyNavigationAttached);
652 void QQuickKeyNavigationAttached::setDown(QQuickItem *i)
654 Q_D(QQuickKeyNavigationAttached);
659 QQuickKeyNavigationAttached* other =
660 qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
661 if (other && !other->d_func()->upSet) {
662 other->d_func()->up = qobject_cast<QQuickItem*>(parent());
663 emit other->upChanged();
668 QQuickItem *QQuickKeyNavigationAttached::tab() const
670 Q_D(const QQuickKeyNavigationAttached);
674 void QQuickKeyNavigationAttached::setTab(QQuickItem *i)
676 Q_D(QQuickKeyNavigationAttached);
681 QQuickKeyNavigationAttached* other =
682 qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
683 if (other && !other->d_func()->backtabSet) {
684 other->d_func()->backtab = qobject_cast<QQuickItem*>(parent());
685 emit other->backtabChanged();
690 QQuickItem *QQuickKeyNavigationAttached::backtab() const
692 Q_D(const QQuickKeyNavigationAttached);
696 void QQuickKeyNavigationAttached::setBacktab(QQuickItem *i)
698 Q_D(QQuickKeyNavigationAttached);
702 d->backtabSet = true;
703 QQuickKeyNavigationAttached* other =
704 qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
705 if (other && !other->d_func()->tabSet) {
706 other->d_func()->tab = qobject_cast<QQuickItem*>(parent());
707 emit other->tabChanged();
709 emit backtabChanged();
713 \qmlproperty enumeration QtQuick2::KeyNavigation::priority
715 This property determines whether the keys are processed before
716 or after the attached item's own key handling.
719 \li KeyNavigation.BeforeItem - process the key events before normal
720 item key processing. If the event is used for key navigation, it will be accepted and will not
721 be passed on to the item.
722 \li KeyNavigation.AfterItem (default) - process the key events after normal item key
723 handling. If the item accepts the key event it will not be
724 handled by the KeyNavigation attached property handler.
727 QQuickKeyNavigationAttached::Priority QQuickKeyNavigationAttached::priority() const
729 return m_processPost ? AfterItem : BeforeItem;
732 void QQuickKeyNavigationAttached::setPriority(Priority order)
734 bool processPost = order == AfterItem;
735 if (processPost != m_processPost) {
736 m_processPost = processPost;
737 emit priorityChanged();
741 void QQuickKeyNavigationAttached::keyPressed(QKeyEvent *event, bool post)
743 Q_D(QQuickKeyNavigationAttached);
746 if (post != m_processPost) {
747 QQuickItemKeyFilter::keyPressed(event, post);
752 switch (event->key()) {
754 if (QQuickItem *parentItem = qobject_cast<QQuickItem*>(parent()))
755 mirror = QQuickItemPrivate::get(parentItem)->effectiveLayoutMirror;
756 QQuickItem* leftItem = mirror ? d->right : d->left;
758 setFocusNavigation(leftItem, mirror ? "right" : "left");
763 case Qt::Key_Right: {
764 if (QQuickItem *parentItem = qobject_cast<QQuickItem*>(parent()))
765 mirror = QQuickItemPrivate::get(parentItem)->effectiveLayoutMirror;
766 QQuickItem* rightItem = mirror ? d->left : d->right;
768 setFocusNavigation(rightItem, mirror ? "left" : "right");
775 setFocusNavigation(d->up, "up");
781 setFocusNavigation(d->down, "down");
787 setFocusNavigation(d->tab, "tab");
791 case Qt::Key_Backtab:
793 setFocusNavigation(d->backtab, "backtab");
801 if (!event->isAccepted()) QQuickItemKeyFilter::keyPressed(event, post);
804 void QQuickKeyNavigationAttached::keyReleased(QKeyEvent *event, bool post)
806 Q_D(QQuickKeyNavigationAttached);
809 if (post != m_processPost) {
810 QQuickItemKeyFilter::keyReleased(event, post);
815 switch (event->key()) {
817 if (QQuickItem *parentItem = qobject_cast<QQuickItem*>(parent()))
818 mirror = QQuickItemPrivate::get(parentItem)->effectiveLayoutMirror;
819 if (mirror ? d->right : d->left)
823 if (QQuickItem *parentItem = qobject_cast<QQuickItem*>(parent()))
824 mirror = QQuickItemPrivate::get(parentItem)->effectiveLayoutMirror;
825 if (mirror ? d->left : d->right)
843 case Qt::Key_Backtab:
852 if (!event->isAccepted()) QQuickItemKeyFilter::keyReleased(event, post);
855 void QQuickKeyNavigationAttached::setFocusNavigation(QQuickItem *currentItem, const char *dir)
857 QQuickItem *initialItem = currentItem;
858 bool isNextItem = false;
861 if (currentItem->isVisible() && currentItem->isEnabled()) {
862 currentItem->setFocus(true);
865 qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(currentItem, false);
867 QQuickItem *tempItem = qvariant_cast<QQuickItem*>(attached->property(dir));
869 currentItem = tempItem;
875 while (currentItem != initialItem && isNextItem);
878 const QQuickKeysAttached::SigMap QQuickKeysAttached::sigMap[] = {
879 { Qt::Key_Left, "leftPressed" },
880 { Qt::Key_Right, "rightPressed" },
881 { Qt::Key_Up, "upPressed" },
882 { Qt::Key_Down, "downPressed" },
883 { Qt::Key_Tab, "tabPressed" },
884 { Qt::Key_Backtab, "backtabPressed" },
885 { Qt::Key_Asterisk, "asteriskPressed" },
886 { Qt::Key_NumberSign, "numberSignPressed" },
887 { Qt::Key_Escape, "escapePressed" },
888 { Qt::Key_Return, "returnPressed" },
889 { Qt::Key_Enter, "enterPressed" },
890 { Qt::Key_Delete, "deletePressed" },
891 { Qt::Key_Space, "spacePressed" },
892 { Qt::Key_Back, "backPressed" },
893 { Qt::Key_Cancel, "cancelPressed" },
894 { Qt::Key_Select, "selectPressed" },
895 { Qt::Key_Yes, "yesPressed" },
896 { Qt::Key_No, "noPressed" },
897 { Qt::Key_Context1, "context1Pressed" },
898 { Qt::Key_Context2, "context2Pressed" },
899 { Qt::Key_Context3, "context3Pressed" },
900 { Qt::Key_Context4, "context4Pressed" },
901 { Qt::Key_Call, "callPressed" },
902 { Qt::Key_Hangup, "hangupPressed" },
903 { Qt::Key_Flip, "flipPressed" },
904 { Qt::Key_Menu, "menuPressed" },
905 { Qt::Key_VolumeUp, "volumeUpPressed" },
906 { Qt::Key_VolumeDown, "volumeDownPressed" },
910 bool QQuickKeysAttachedPrivate::isConnected(const char *signalName)
912 return isSignalConnected(signalIndex(signalName));
916 \qmlclass Keys QQuickKeysAttached
917 \inqmlmodule QtQuick 2
918 \ingroup qml-basic-interaction-elements
919 \brief The Keys attached property provides key handling to Items.
921 All visual primitives support key handling via the Keys
922 attached property. Keys can be handled via the onPressed
923 and onReleased signal properties.
925 The signal properties have a \l KeyEvent parameter, named
926 \e event which contains details of the event. If a key is
927 handled \e event.accepted should be set to true to prevent the
928 event from propagating up the item hierarchy.
930 \section1 Example Usage
932 The following example shows how the general onPressed handler can
933 be used to test for a certain key; in this case, the left cursor
936 \snippet doc/src/snippets/qml/keys/keys-pressed.qml key item
938 Some keys may alternatively be handled via specific signal properties,
939 for example \e onSelectPressed. These handlers automatically set
940 \e event.accepted to true.
942 \snippet doc/src/snippets/qml/keys/keys-handler.qml key item
944 See \l{Qt::Key}{Qt.Key} for the list of keyboard codes.
946 \section1 Key Handling Priorities
948 The Keys attached property can be configured to handle key events
949 before or after the item it is attached to. This makes it possible
950 to intercept events in order to override an item's default behavior,
951 or act as a fallback for keys not handled by the item.
953 If \l priority is Keys.BeforeItem (default) the order of key event processing is:
956 \li Items specified in \c forwardTo
957 \li specific key handlers, e.g. onReturnPressed
958 \li onKeyPress, onKeyRelease handlers
959 \li Item specific key handling, e.g. TextInput key handling
963 If priority is Keys.AfterItem the order of key event processing is:
966 \li Item specific key handling, e.g. TextInput key handling
967 \li Items specified in \c forwardTo
968 \li specific key handlers, e.g. onReturnPressed
969 \li onKeyPress, onKeyRelease handlers
973 If the event is accepted during any of the above steps, key
976 \sa KeyEvent, {KeyNavigation}{KeyNavigation attached property}
980 \qmlproperty bool QtQuick2::Keys::enabled
982 This flags enables key handling if true (default); otherwise
983 no key handlers will be called.
987 \qmlproperty enumeration QtQuick2::Keys::priority
989 This property determines whether the keys are processed before
990 or after the attached item's own key handling.
993 \li Keys.BeforeItem (default) - process the key events before normal
994 item key processing. If the event is accepted it will not
995 be passed on to the item.
996 \li Keys.AfterItem - process the key events after normal item key
997 handling. If the item accepts the key event it will not be
998 handled by the Keys attached property handler.
1003 \qmlproperty list<Object> QtQuick2::Keys::forwardTo
1005 This property provides a way to forward key presses, key releases, and keyboard input
1006 coming from input methods to other items. This can be useful when you want
1007 one item to handle some keys (e.g. the up and down arrow keys), and another item to
1008 handle other keys (e.g. the left and right arrow keys). Once an item that has been
1009 forwarded keys accepts the event it is no longer forwarded to items later in the
1012 This example forwards key events to two lists:
1023 Keys.forwardTo: [list1, list2]
1030 \qmlsignal QtQuick2::Keys::onPressed(KeyEvent event)
1032 This handler is called when a key has been pressed. The \a event
1033 parameter provides information about the event.
1037 \qmlsignal QtQuick2::Keys::onReleased(KeyEvent event)
1039 This handler is called when a key has been released. The \a event
1040 parameter provides information about the event.
1044 \qmlsignal QtQuick2::Keys::onDigit0Pressed(KeyEvent event)
1046 This handler is called when the digit '0' has been pressed. The \a event
1047 parameter provides information about the event.
1051 \qmlsignal QtQuick2::Keys::onDigit1Pressed(KeyEvent event)
1053 This handler is called when the digit '1' has been pressed. The \a event
1054 parameter provides information about the event.
1058 \qmlsignal QtQuick2::Keys::onDigit2Pressed(KeyEvent event)
1060 This handler is called when the digit '2' has been pressed. The \a event
1061 parameter provides information about the event.
1065 \qmlsignal QtQuick2::Keys::onDigit3Pressed(KeyEvent event)
1067 This handler is called when the digit '3' has been pressed. The \a event
1068 parameter provides information about the event.
1072 \qmlsignal QtQuick2::Keys::onDigit4Pressed(KeyEvent event)
1074 This handler is called when the digit '4' has been pressed. The \a event
1075 parameter provides information about the event.
1079 \qmlsignal QtQuick2::Keys::onDigit5Pressed(KeyEvent event)
1081 This handler is called when the digit '5' has been pressed. The \a event
1082 parameter provides information about the event.
1086 \qmlsignal QtQuick2::Keys::onDigit6Pressed(KeyEvent event)
1088 This handler is called when the digit '6' has been pressed. The \a event
1089 parameter provides information about the event.
1093 \qmlsignal QtQuick2::Keys::onDigit7Pressed(KeyEvent event)
1095 This handler is called when the digit '7' has been pressed. The \a event
1096 parameter provides information about the event.
1100 \qmlsignal QtQuick2::Keys::onDigit8Pressed(KeyEvent event)
1102 This handler is called when the digit '8' has been pressed. The \a event
1103 parameter provides information about the event.
1107 \qmlsignal QtQuick2::Keys::onDigit9Pressed(KeyEvent event)
1109 This handler is called when the digit '9' has been pressed. The \a event
1110 parameter provides information about the event.
1114 \qmlsignal QtQuick2::Keys::onLeftPressed(KeyEvent event)
1116 This handler is called when the Left arrow has been pressed. The \a event
1117 parameter provides information about the event.
1121 \qmlsignal QtQuick2::Keys::onRightPressed(KeyEvent event)
1123 This handler is called when the Right arrow has been pressed. The \a event
1124 parameter provides information about the event.
1128 \qmlsignal QtQuick2::Keys::onUpPressed(KeyEvent event)
1130 This handler is called when the Up arrow has been pressed. The \a event
1131 parameter provides information about the event.
1135 \qmlsignal QtQuick2::Keys::onDownPressed(KeyEvent event)
1137 This handler is called when the Down arrow has been pressed. The \a event
1138 parameter provides information about the event.
1142 \qmlsignal QtQuick2::Keys::onTabPressed(KeyEvent event)
1144 This handler is called when the Tab key has been pressed. The \a event
1145 parameter provides information about the event.
1149 \qmlsignal QtQuick2::Keys::onBacktabPressed(KeyEvent event)
1151 This handler is called when the Shift+Tab key combination (Backtab) has
1152 been pressed. The \a event parameter provides information about the event.
1156 \qmlsignal QtQuick2::Keys::onAsteriskPressed(KeyEvent event)
1158 This handler is called when the Asterisk '*' has been pressed. The \a event
1159 parameter provides information about the event.
1163 \qmlsignal QtQuick2::Keys::onEscapePressed(KeyEvent event)
1165 This handler is called when the Escape key has been pressed. The \a event
1166 parameter provides information about the event.
1170 \qmlsignal QtQuick2::Keys::onReturnPressed(KeyEvent event)
1172 This handler is called when the Return key has been pressed. The \a event
1173 parameter provides information about the event.
1177 \qmlsignal QtQuick2::Keys::onEnterPressed(KeyEvent event)
1179 This handler is called when the Enter key has been pressed. The \a event
1180 parameter provides information about the event.
1184 \qmlsignal QtQuick2::Keys::onDeletePressed(KeyEvent event)
1186 This handler is called when the Delete key has been pressed. The \a event
1187 parameter provides information about the event.
1191 \qmlsignal QtQuick2::Keys::onSpacePressed(KeyEvent event)
1193 This handler is called when the Space key has been pressed. The \a event
1194 parameter provides information about the event.
1198 \qmlsignal QtQuick2::Keys::onBackPressed(KeyEvent event)
1200 This handler is called when the Back key has been pressed. The \a event
1201 parameter provides information about the event.
1205 \qmlsignal QtQuick2::Keys::onCancelPressed(KeyEvent event)
1207 This handler is called when the Cancel key has been pressed. The \a event
1208 parameter provides information about the event.
1212 \qmlsignal QtQuick2::Keys::onSelectPressed(KeyEvent event)
1214 This handler is called when the Select key has been pressed. The \a event
1215 parameter provides information about the event.
1219 \qmlsignal QtQuick2::Keys::onYesPressed(KeyEvent event)
1221 This handler is called when the Yes key has been pressed. The \a event
1222 parameter provides information about the event.
1226 \qmlsignal QtQuick2::Keys::onNoPressed(KeyEvent event)
1228 This handler is called when the No key has been pressed. The \a event
1229 parameter provides information about the event.
1233 \qmlsignal QtQuick2::Keys::onContext1Pressed(KeyEvent event)
1235 This handler is called when the Context1 key has been pressed. The \a event
1236 parameter provides information about the event.
1240 \qmlsignal QtQuick2::Keys::onContext2Pressed(KeyEvent event)
1242 This handler is called when the Context2 key has been pressed. The \a event
1243 parameter provides information about the event.
1247 \qmlsignal QtQuick2::Keys::onContext3Pressed(KeyEvent event)
1249 This handler is called when the Context3 key has been pressed. The \a event
1250 parameter provides information about the event.
1254 \qmlsignal QtQuick2::Keys::onContext4Pressed(KeyEvent event)
1256 This handler is called when the Context4 key has been pressed. The \a event
1257 parameter provides information about the event.
1261 \qmlsignal QtQuick2::Keys::onCallPressed(KeyEvent event)
1263 This handler is called when the Call key has been pressed. The \a event
1264 parameter provides information about the event.
1268 \qmlsignal QtQuick2::Keys::onHangupPressed(KeyEvent event)
1270 This handler is called when the Hangup key has been pressed. The \a event
1271 parameter provides information about the event.
1275 \qmlsignal QtQuick2::Keys::onFlipPressed(KeyEvent event)
1277 This handler is called when the Flip key has been pressed. The \a event
1278 parameter provides information about the event.
1282 \qmlsignal QtQuick2::Keys::onMenuPressed(KeyEvent event)
1284 This handler is called when the Menu key has been pressed. The \a event
1285 parameter provides information about the event.
1289 \qmlsignal QtQuick2::Keys::onVolumeUpPressed(KeyEvent event)
1291 This handler is called when the VolumeUp key has been pressed. The \a event
1292 parameter provides information about the event.
1296 \qmlsignal QtQuick2::Keys::onVolumeDownPressed(KeyEvent event)
1298 This handler is called when the VolumeDown key has been pressed. The \a event
1299 parameter provides information about the event.
1302 QQuickKeysAttached::QQuickKeysAttached(QObject *parent)
1303 : QObject(*(new QQuickKeysAttachedPrivate), parent),
1304 QQuickItemKeyFilter(qobject_cast<QQuickItem*>(parent))
1306 Q_D(QQuickKeysAttached);
1307 m_processPost = false;
1308 d->item = qobject_cast<QQuickItem*>(parent);
1311 QQuickKeysAttached::~QQuickKeysAttached()
1315 QQuickKeysAttached::Priority QQuickKeysAttached::priority() const
1317 return m_processPost ? AfterItem : BeforeItem;
1320 void QQuickKeysAttached::setPriority(Priority order)
1322 bool processPost = order == AfterItem;
1323 if (processPost != m_processPost) {
1324 m_processPost = processPost;
1325 emit priorityChanged();
1329 void QQuickKeysAttached::componentComplete()
1331 Q_D(QQuickKeysAttached);
1333 for (int ii = 0; ii < d->targets.count(); ++ii) {
1334 QQuickItem *targetItem = d->targets.at(ii);
1335 if (targetItem && (targetItem->flags() & QQuickItem::ItemAcceptsInputMethod)) {
1336 d->item->setFlag(QQuickItem::ItemAcceptsInputMethod);
1343 void QQuickKeysAttached::keyPressed(QKeyEvent *event, bool post)
1345 Q_D(QQuickKeysAttached);
1346 if (post != m_processPost || !d->enabled || d->inPress) {
1348 QQuickItemKeyFilter::keyPressed(event, post);
1352 // first process forwards
1353 if (d->item && d->item->canvas()) {
1355 for (int ii = 0; ii < d->targets.count(); ++ii) {
1356 QQuickItem *i = d->targets.at(ii);
1357 if (i && i->isVisible()) {
1358 d->item->canvas()->sendEvent(i, event);
1359 if (event->isAccepted()) {
1368 QQuickKeyEvent ke(*event);
1369 QByteArray keySignal = keyToSignal(event->key());
1370 if (!keySignal.isEmpty()) {
1371 keySignal += "(QQuickKeyEvent*)";
1372 if (d->isConnected(keySignal)) {
1373 // If we specifically handle a key then default to accepted
1374 ke.setAccepted(true);
1375 int idx = QQuickKeysAttached::staticMetaObject.indexOfSignal(keySignal);
1376 metaObject()->method(idx).invoke(this, Qt::DirectConnection, Q_ARG(QQuickKeyEvent*, &ke));
1379 if (!ke.isAccepted())
1381 event->setAccepted(ke.isAccepted());
1383 if (!event->isAccepted()) QQuickItemKeyFilter::keyPressed(event, post);
1386 void QQuickKeysAttached::keyReleased(QKeyEvent *event, bool post)
1388 Q_D(QQuickKeysAttached);
1389 if (post != m_processPost || !d->enabled || d->inRelease) {
1391 QQuickItemKeyFilter::keyReleased(event, post);
1395 if (d->item && d->item->canvas()) {
1396 d->inRelease = true;
1397 for (int ii = 0; ii < d->targets.count(); ++ii) {
1398 QQuickItem *i = d->targets.at(ii);
1399 if (i && i->isVisible()) {
1400 d->item->canvas()->sendEvent(i, event);
1401 if (event->isAccepted()) {
1402 d->inRelease = false;
1407 d->inRelease = false;
1410 QQuickKeyEvent ke(*event);
1412 event->setAccepted(ke.isAccepted());
1414 if (!event->isAccepted()) QQuickItemKeyFilter::keyReleased(event, post);
1417 void QQuickKeysAttached::inputMethodEvent(QInputMethodEvent *event, bool post)
1419 Q_D(QQuickKeysAttached);
1420 if (post == m_processPost && d->item && !d->inIM && d->item->canvas()) {
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)) {
1425 d->item->canvas()->sendEvent(i, event);
1426 if (event->isAccepted()) {
1435 QQuickItemKeyFilter::inputMethodEvent(event, post);
1438 QVariant QQuickKeysAttached::inputMethodQuery(Qt::InputMethodQuery query) const
1440 Q_D(const QQuickKeysAttached);
1442 for (int ii = 0; ii < d->targets.count(); ++ii) {
1443 QQuickItem *i = d->targets.at(ii);
1444 if (i && i->isVisible() && (i->flags() & QQuickItem::ItemAcceptsInputMethod) && i == d->imeItem) {
1445 //### how robust is i == d->imeItem check?
1446 QVariant v = i->inputMethodQuery(query);
1447 if (v.userType() == QVariant::RectF)
1448 v = d->item->mapRectFromItem(i, v.toRectF()); //### cost?
1453 return QQuickItemKeyFilter::inputMethodQuery(query);
1456 QQuickKeysAttached *QQuickKeysAttached::qmlAttachedProperties(QObject *obj)
1458 return new QQuickKeysAttached(obj);
1462 \qmlclass LayoutMirroring QQuickLayoutMirroringAttached
1463 \inqmlmodule QtQuick 2
1464 \ingroup qml-utility-elements
1465 \brief The LayoutMirroring attached property is used to mirror layout behavior.
1467 The LayoutMirroring attached property is used to horizontally mirror \l {anchor-layout}{Item anchors},
1468 \l{Using QML Positioner and Repeater Items}{positioner} elements (such as \l Row and \l Grid)
1469 and views (such as \l GridView and horizontal \l ListView). Mirroring is a visual change: left
1470 anchors become right anchors, and positioner elements like \l Grid and \l Row reverse the
1471 horizontal layout of child items.
1473 Mirroring is enabled for an item by setting the \l enabled property to true. By default, this
1474 only affects the item itself; setting the \l childrenInherit property to true propagates the mirroring
1475 behavior to all child elements as well. If the \c LayoutMirroring attached property has not been defined
1476 for an item, mirroring is not enabled.
1478 The following example shows mirroring in action. The \l Row below is specified as being anchored
1479 to the left of its parent. However, since mirroring has been enabled, the anchor is horizontally
1480 reversed and it is now anchored to the right. Also, since items in a \l Row are positioned
1481 from left to right by default, they are now positioned from right to left instead, as demonstrated
1482 by the numbering and opacity of the items:
1484 \snippet doc/src/snippets/qml/layoutmirroring.qml 0
1486 \image layoutmirroring.png
1488 Layout mirroring is useful when it is necessary to support both left-to-right and right-to-left
1489 layout versions of an application to target different language areas. The \l childrenInherit
1490 property allows layout mirroring to be applied without manually setting layout configurations
1491 for every item in an application. Keep in mind, however, that mirroring does not affect any
1492 positioning that is defined by the \l Item \l {Item::}{x} coordinate value, so even with
1493 mirroring enabled, it will often be necessary to apply some layout fixes to support the
1494 desired layout direction. Also, it may be necessary to disable the mirroring of individual
1495 child items (by setting \l {enabled}{LayoutMirroring.enabled} to false for such items) if
1496 mirroring is not the desired behavior, or if the child item already implements mirroring in
1499 See \l {QML Right-to-left User Interfaces} for further details on using \c LayoutMirroring and
1500 other related features to implement right-to-left support for an application.
1504 \qmlproperty bool QtQuick2::LayoutMirroring::enabled
1506 This property holds whether the item's layout is mirrored horizontally. Setting this to true
1507 horizontally reverses \l {anchor-layout}{anchor} settings such that left anchors become right,
1508 and right anchors become left. For \l{Using QML Positioner and Repeater Items}{positioner} elements
1509 (such as \l Row and \l Grid) and view elements (such as \l {GridView}{GridView} and \l {ListView}{ListView})
1510 this also mirrors the horizontal layout direction of the item.
1512 The default value is false.
1516 \qmlproperty bool QtQuick2::LayoutMirroring::childrenInherit
1518 This property holds whether the \l {enabled}{LayoutMirroring.enabled} value for this item
1519 is inherited by its children.
1521 The default value is false.
1525 QQuickLayoutMirroringAttached::QQuickLayoutMirroringAttached(QObject *parent) : QObject(parent), itemPrivate(0)
1527 if (QQuickItem *item = qobject_cast<QQuickItem*>(parent)) {
1528 itemPrivate = QQuickItemPrivate::get(item);
1529 itemPrivate->extra.value().layoutDirectionAttached = this;
1531 qmlInfo(parent) << tr("LayoutDirection attached property only works with Items");
1534 QQuickLayoutMirroringAttached * QQuickLayoutMirroringAttached::qmlAttachedProperties(QObject *object)
1536 return new QQuickLayoutMirroringAttached(object);
1539 bool QQuickLayoutMirroringAttached::enabled() const
1541 return itemPrivate ? itemPrivate->effectiveLayoutMirror : false;
1544 void QQuickLayoutMirroringAttached::setEnabled(bool enabled)
1549 itemPrivate->isMirrorImplicit = false;
1550 if (enabled != itemPrivate->effectiveLayoutMirror) {
1551 itemPrivate->setLayoutMirror(enabled);
1552 if (itemPrivate->inheritMirrorFromItem)
1553 itemPrivate->resolveLayoutMirror();
1557 void QQuickLayoutMirroringAttached::resetEnabled()
1559 if (itemPrivate && !itemPrivate->isMirrorImplicit) {
1560 itemPrivate->isMirrorImplicit = true;
1561 itemPrivate->resolveLayoutMirror();
1565 bool QQuickLayoutMirroringAttached::childrenInherit() const
1567 return itemPrivate ? itemPrivate->inheritMirrorFromItem : false;
1570 void QQuickLayoutMirroringAttached::setChildrenInherit(bool childrenInherit) {
1571 if (itemPrivate && childrenInherit != itemPrivate->inheritMirrorFromItem) {
1572 itemPrivate->inheritMirrorFromItem = childrenInherit;
1573 itemPrivate->resolveLayoutMirror();
1574 childrenInheritChanged();
1578 void QQuickItemPrivate::resolveLayoutMirror()
1581 if (QQuickItem *parentItem = q->parentItem()) {
1582 QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(parentItem);
1583 setImplicitLayoutMirror(parentPrivate->inheritedLayoutMirror, parentPrivate->inheritMirrorFromParent);
1585 setImplicitLayoutMirror(isMirrorImplicit ? false : effectiveLayoutMirror, inheritMirrorFromItem);
1589 void QQuickItemPrivate::setImplicitLayoutMirror(bool mirror, bool inherit)
1591 inherit = inherit || inheritMirrorFromItem;
1592 if (!isMirrorImplicit && inheritMirrorFromItem)
1593 mirror = effectiveLayoutMirror;
1594 if (mirror == inheritedLayoutMirror && inherit == inheritMirrorFromParent)
1597 inheritMirrorFromParent = inherit;
1598 inheritedLayoutMirror = inheritMirrorFromParent ? mirror : false;
1600 if (isMirrorImplicit)
1601 setLayoutMirror(inherit ? inheritedLayoutMirror : false);
1602 for (int i = 0; i < childItems.count(); ++i) {
1603 if (QQuickItem *child = qobject_cast<QQuickItem *>(childItems.at(i))) {
1604 QQuickItemPrivate *childPrivate = QQuickItemPrivate::get(child);
1605 childPrivate->setImplicitLayoutMirror(inheritedLayoutMirror, inheritMirrorFromParent);
1610 void QQuickItemPrivate::setLayoutMirror(bool mirror)
1612 if (mirror != effectiveLayoutMirror) {
1613 effectiveLayoutMirror = mirror;
1615 QQuickAnchorsPrivate *anchor_d = QQuickAnchorsPrivate::get(_anchors);
1616 anchor_d->fillChanged();
1617 anchor_d->centerInChanged();
1618 anchor_d->updateHorizontalAnchors();
1619 emit _anchors->mirroredChanged();
1622 if (extra.isAllocated() && extra->layoutDirectionAttached) {
1623 emit extra->layoutDirectionAttached->enabledChanged();
1628 void QQuickItemPrivate::setAccessibleFlagAndListener()
1631 QQuickItem *item = q;
1633 if (item->d_func()->isAccessible)
1634 break; // already set - grandparents should have the flag set as well.
1636 item->d_func()->isAccessible = true;
1637 item = item->d_func()->parentItem;
1641 void QQuickItemPrivate::updateSubFocusItem(QQuickItem *scope, bool focus)
1646 QQuickItemPrivate *scopePrivate = QQuickItemPrivate::get(scope);
1648 QQuickItem *oldSubFocusItem = scopePrivate->subFocusItem;
1649 // Correct focus chain in scope
1650 if (oldSubFocusItem) {
1651 QQuickItem *sfi = scopePrivate->subFocusItem->parentItem();
1652 while (sfi && sfi != scope) {
1653 QQuickItemPrivate::get(sfi)->subFocusItem = 0;
1654 sfi = sfi->parentItem();
1659 scopePrivate->subFocusItem = q;
1660 QQuickItem *sfi = scopePrivate->subFocusItem->parentItem();
1661 while (sfi && sfi != scope) {
1662 QQuickItemPrivate::get(sfi)->subFocusItem = q;
1663 sfi = sfi->parentItem();
1666 scopePrivate->subFocusItem = 0;
1673 \brief The QQuickItem class provides the most basic of all visual items in QML.
1677 All visual items in Qt Quick inherit from QQuickItem. Although QQuickItem
1678 has no visual appearance, it defines all the properties that are
1679 common across visual items - such as the x and y position, the
1680 width and height, \l {anchor-layout}{anchoring} and key handling.
1682 You can subclass QQuickItem to provide your own custom visual item that inherits
1683 these features. Note that, because it does not draw anything, QQuickItem sets the
1684 QGraphicsItem::ItemHasNoContents flag. If you subclass QQuickItem to create a visual
1685 item, you will need to unset this flag.
1690 \qmlclass Item QQuickItem
1692 \inqmlmodule QtQuick 2
1693 \ingroup qml-basic-visual-elements
1694 \brief The Item is the most basic of all visual items in QML.
1696 All visual items in Qt Quick inherit from Item. Although Item
1697 has no visual appearance, it defines all the properties that are
1698 common across visual items - such as the x and y position, the
1699 width and height, \l {anchor-layout}{anchoring} and key handling.
1701 Item is also useful for grouping items together.
1718 fillMode: Image.Tile
1725 \section1 Key Handling
1727 Key handling is available to all Item-based visual elements via the \l {Keys}{Keys}
1728 attached property. The \e Keys attached property provides basic handlers such
1729 as \l {Keys::onPressed}{onPressed} and \l {Keys::onReleased}{onReleased},
1730 as well as handlers for specific keys, such as
1731 \l {Keys::onCancelPressed}{onCancelPressed}. The example below
1732 assigns \l {qmlfocus}{focus} to the item and handles
1733 the Left key via the general \e onPressed handler and the Select key via the
1734 onSelectPressed handler:
1740 if (event.key == Qt.Key_Left) {
1741 console.log("move left");
1742 event.accepted = true;
1745 Keys.onSelectPressed: console.log("Selected");
1749 See the \l {Keys}{Keys} attached property for detailed documentation.
1751 \section1 Layout Mirroring
1753 Item layouts can be mirrored using the \l {LayoutMirroring}{LayoutMirroring} attached property.
1758 \fn void QQuickItem::childrenRectChanged(const QRectF &)
1763 \fn void QQuickItem::baselineOffsetChanged(qreal)
1768 \fn void QQuickItem::stateChanged(const QString &state)
1773 \fn void QQuickItem::parentChanged(QQuickItem *)
1778 \fn void QQuickItem::smoothChanged(bool)
1783 \fn void QQuickItem::clipChanged(bool)
1787 /*! \fn void QQuickItem::transformOriginChanged(TransformOrigin)
1792 \fn void QQuickItem::focusChanged(bool)
1797 \fn void QQuickItem::activeFocusChanged(bool)
1801 \fn QQuickItem::QQuickItem(QQuickItem *parent)
1803 Constructs a QQuickItem with the given \a parent.
1805 QQuickItem::QQuickItem(QQuickItem* parent)
1806 : QObject(*(new QQuickItemPrivate), parent)
1814 QQuickItem::QQuickItem(QQuickItemPrivate &dd, QQuickItem *parent)
1815 : QObject(dd, parent)
1822 static int qt_item_count = 0;
1824 static void qt_print_item_count()
1826 qDebug("Number of leaked items: %i", qt_item_count);
1832 Destroys the QQuickItem.
1834 QQuickItem::~QQuickItem()
1838 if (qt_item_count < 0)
1839 qDebug("Item destroyed after qt_print_item_count() was called.");
1844 if (d->canvasRefCount > 1)
1845 d->canvasRefCount = 1; // Make sure canvas is set to null in next call to derefCanvas().
1851 // XXX todo - optimize
1852 while (!d->childItems.isEmpty())
1853 d->childItems.first()->setParentItem(0);
1855 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
1856 QQuickAnchorsPrivate *anchor = d->changeListeners.at(ii).listener->anchorPrivate();
1858 anchor->clearItem(this);
1862 update item anchors that depended on us unless they are our child (and will also be destroyed),
1863 or our sibling, and our parent is also being destroyed.
1865 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
1866 QQuickAnchorsPrivate *anchor = d->changeListeners.at(ii).listener->anchorPrivate();
1867 if (anchor && anchor->item && anchor->item->parentItem() && anchor->item->parentItem() != this)
1871 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
1872 const QQuickItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
1873 if (change.types & QQuickItemPrivate::Destroyed)
1874 change.listener->itemDestroyed(this);
1877 d->changeListeners.clear();
1879 if (d->extra.isAllocated()) {
1880 delete d->extra->contents; d->extra->contents = 0;
1881 delete d->extra->layer; d->extra->layer = 0;
1884 delete d->_anchors; d->_anchors = 0;
1885 delete d->_stateGroup; d->_stateGroup = 0;
1889 \qmlproperty enumeration QtQuick2::Item::transformOrigin
1890 This property holds the origin point around which scale and rotation transform.
1892 Nine transform origins are available, as shown in the image below.
1894 \image declarative-transformorigin.png
1896 This example rotates an image around its bottom-right corner.
1899 source: "myimage.png"
1900 transformOrigin: Item.BottomRight
1905 The default transform origin is \c Item.Center.
1907 To set an arbitrary transform origin point use the \l Scale or \l Rotation
1912 \qmlproperty Item QtQuick2::Item::parent
1913 This property holds the parent of the item.
1917 \property QQuickItem::parent
1918 This property holds the parent of the item.
1920 void QQuickItem::setParentItem(QQuickItem *parentItem)
1923 if (parentItem == d->parentItem)
1927 QQuickItem *itemAncestor = parentItem->parentItem();
1928 while (itemAncestor != 0) {
1929 if (itemAncestor == this) {
1930 qWarning("QQuickItem::setParentItem: Parent is already part of this items subtree.");
1933 itemAncestor = itemAncestor->parentItem();
1937 d->removeFromDirtyList();
1939 QQuickItem *oldParentItem = d->parentItem;
1940 QQuickItem *scopeFocusedItem = 0;
1942 if (oldParentItem) {
1943 QQuickItemPrivate *op = QQuickItemPrivate::get(oldParentItem);
1945 QQuickItem *scopeItem = 0;
1948 scopeFocusedItem = this;
1949 else if (!isFocusScope() && d->subFocusItem)
1950 scopeFocusedItem = d->subFocusItem;
1952 if (scopeFocusedItem) {
1953 scopeItem = oldParentItem;
1954 while (!scopeItem->isFocusScope() && scopeItem->parentItem())
1955 scopeItem = scopeItem->parentItem();
1957 QQuickCanvasPrivate::get(d->canvas)->clearFocusInScope(scopeItem, scopeFocusedItem,
1958 QQuickCanvasPrivate::DontChangeFocusProperty);
1959 if (scopeFocusedItem != this)
1960 QQuickItemPrivate::get(scopeFocusedItem)->updateSubFocusItem(this, true);
1962 QQuickItemPrivate::get(scopeFocusedItem)->updateSubFocusItem(scopeItem, false);
1966 const bool wasVisible = isVisible();
1967 op->removeChild(this);
1969 emit oldParentItem->visibleChildrenChanged();
1971 } else if (d->canvas) {
1972 QQuickCanvasPrivate::get(d->canvas)->parentlessItems.remove(this);
1975 QQuickCanvas *oldParentCanvas = oldParentItem ? QQuickItemPrivate::get(oldParentItem)->canvas : 0;
1976 QQuickCanvas *parentCanvas = parentItem ? QQuickItemPrivate::get(parentItem)->canvas : 0;
1977 if (oldParentCanvas == parentCanvas) {
1978 // Avoid freeing and reallocating resources if the canvas stays the same.
1979 d->parentItem = parentItem;
1981 if (oldParentCanvas)
1983 d->parentItem = parentItem;
1985 d->refCanvas(parentCanvas);
1988 d->dirty(QQuickItemPrivate::ParentChanged);
1991 QQuickItemPrivate::get(d->parentItem)->addChild(this);
1993 QQuickCanvasPrivate::get(d->canvas)->parentlessItems.insert(this);
1995 d->setEffectiveVisibleRecur(d->calcEffectiveVisible());
1996 d->setEffectiveEnableRecur(0, d->calcEffectiveEnable());
1998 if (d->parentItem) {
1999 if (!scopeFocusedItem) {
2001 scopeFocusedItem = this;
2002 else if (!isFocusScope() && d->subFocusItem)
2003 scopeFocusedItem = d->subFocusItem;
2006 if (scopeFocusedItem) {
2007 // We need to test whether this item becomes scope focused
2008 QQuickItem *scopeItem = d->parentItem;
2009 while (!scopeItem->isFocusScope() && scopeItem->parentItem())
2010 scopeItem = scopeItem->parentItem();
2012 if (QQuickItemPrivate::get(scopeItem)->subFocusItem
2013 || (!scopeItem->isFocusScope() && scopeItem->hasFocus())) {
2014 if (scopeFocusedItem != this)
2015 QQuickItemPrivate::get(scopeFocusedItem)->updateSubFocusItem(this, false);
2016 QQuickItemPrivate::get(scopeFocusedItem)->focus = false;
2017 emit scopeFocusedItem->focusChanged(false);
2020 QQuickCanvasPrivate::get(d->canvas)->setFocusInScope(scopeItem, scopeFocusedItem,
2021 QQuickCanvasPrivate::DontChangeFocusProperty);
2023 QQuickItemPrivate::get(scopeFocusedItem)->updateSubFocusItem(scopeItem, true);
2029 d->resolveLayoutMirror();
2031 d->itemChange(ItemParentHasChanged, d->parentItem);
2033 d->parentNotifier.notify();
2034 if (d->isAccessible && d->parentItem) {
2035 d->parentItem->d_func()->setAccessibleFlagAndListener();
2038 emit parentChanged(d->parentItem);
2039 if (isVisible() && d->parentItem)
2040 emit d->parentItem->visibleChildrenChanged();
2043 void QQuickItem::stackBefore(const QQuickItem *sibling)
2046 if (!sibling || sibling == this || !d->parentItem || d->parentItem != QQuickItemPrivate::get(sibling)->parentItem) {
2047 qWarning("QQuickItem::stackBefore: Cannot stack before %p, which must be a sibling", sibling);
2051 QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(d->parentItem);
2053 int myIndex = parentPrivate->childItems.indexOf(this);
2054 int siblingIndex = parentPrivate->childItems.indexOf(const_cast<QQuickItem *>(sibling));
2056 Q_ASSERT(myIndex != -1 && siblingIndex != -1);
2058 if (myIndex == siblingIndex - 1)
2061 parentPrivate->childItems.removeAt(myIndex);
2063 if (myIndex < siblingIndex) --siblingIndex;
2065 parentPrivate->childItems.insert(siblingIndex, this);
2067 parentPrivate->dirty(QQuickItemPrivate::ChildrenStackingChanged);
2068 parentPrivate->markSortedChildrenDirty(this);
2070 for (int ii = qMin(siblingIndex, myIndex); ii < parentPrivate->childItems.count(); ++ii)
2071 QQuickItemPrivate::get(parentPrivate->childItems.at(ii))->siblingOrderChanged();
2074 void QQuickItem::stackAfter(const QQuickItem *sibling)
2077 if (!sibling || sibling == this || !d->parentItem || d->parentItem != QQuickItemPrivate::get(sibling)->parentItem) {
2078 qWarning("QQuickItem::stackAfter: Cannot stack after %p, which must be a sibling", sibling);
2082 QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(d->parentItem);
2084 int myIndex = parentPrivate->childItems.indexOf(this);
2085 int siblingIndex = parentPrivate->childItems.indexOf(const_cast<QQuickItem *>(sibling));
2087 Q_ASSERT(myIndex != -1 && siblingIndex != -1);
2089 if (myIndex == siblingIndex + 1)
2092 parentPrivate->childItems.removeAt(myIndex);
2094 if (myIndex < siblingIndex) --siblingIndex;
2096 parentPrivate->childItems.insert(siblingIndex + 1, this);
2098 parentPrivate->dirty(QQuickItemPrivate::ChildrenStackingChanged);
2099 parentPrivate->markSortedChildrenDirty(this);
2101 for (int ii = qMin(myIndex, siblingIndex + 1); ii < parentPrivate->childItems.count(); ++ii)
2102 QQuickItemPrivate::get(parentPrivate->childItems.at(ii))->siblingOrderChanged();
2106 Returns the QQuickItem parent of this item.
2108 QQuickItem *QQuickItem::parentItem() const
2110 Q_D(const QQuickItem);
2111 return d->parentItem;
2114 QSGEngine *QQuickItem::sceneGraphEngine() const
2116 return canvas()->sceneGraphEngine();
2119 QQuickCanvas *QQuickItem::canvas() const
2121 Q_D(const QQuickItem);
2125 static bool itemZOrder_sort(QQuickItem *lhs, QQuickItem *rhs)
2127 return lhs->z() < rhs->z();
2130 QList<QQuickItem *> QQuickItemPrivate::paintOrderChildItems() const
2132 if (sortedChildItems)
2133 return *sortedChildItems;
2135 // If none of the items have set Z then the paint order list is the same as
2136 // the childItems list. This is by far the most common case.
2138 for (int i = 0; i < childItems.count(); ++i) {
2139 if (QQuickItemPrivate::get(childItems.at(i))->z() != 0.) {
2145 sortedChildItems = new QList<QQuickItem*>(childItems);
2146 qStableSort(sortedChildItems->begin(), sortedChildItems->end(), itemZOrder_sort);
2147 return *sortedChildItems;
2150 sortedChildItems = const_cast<QList<QQuickItem*>*>(&childItems);
2155 void QQuickItemPrivate::addChild(QQuickItem *child)
2159 Q_ASSERT(!childItems.contains(child));
2161 childItems.append(child);
2163 markSortedChildrenDirty(child);
2164 dirty(QQuickItemPrivate::ChildrenChanged);
2166 itemChange(QQuickItem::ItemChildAddedChange, child);
2168 emit q->childrenChanged();
2171 void QQuickItemPrivate::removeChild(QQuickItem *child)
2176 Q_ASSERT(childItems.contains(child));
2177 childItems.removeOne(child);
2178 Q_ASSERT(!childItems.contains(child));
2180 markSortedChildrenDirty(child);
2181 dirty(QQuickItemPrivate::ChildrenChanged);
2183 itemChange(QQuickItem::ItemChildRemovedChange, child);
2185 emit q->childrenChanged();
2188 void QQuickItemPrivate::InitializationState::clear()
2193 void QQuickItemPrivate::InitializationState::clear(QQuickItem *fs)
2198 QQuickItem *QQuickItemPrivate::InitializationState::getFocusScope(QQuickItem *item)
2201 QQuickItem *fs = item->parentItem();
2202 while (fs->parentItem() && !fs->isFocusScope())
2203 fs = fs->parentItem();
2209 void QQuickItemPrivate::refCanvas(InitializationState *state, QQuickCanvas *c)
2211 // An item needs a canvas if it is referenced by another item which has a canvas.
2212 // Typically the item is referenced by a parent, but can also be referenced by a
2213 // ShaderEffect or ShaderEffectSource. 'canvasRefCount' counts how many items with
2214 // a canvas is referencing this item. When the reference count goes from zero to one,
2215 // or one to zero, the canvas of this item is updated and propagated to the children.
2216 // As long as the reference count stays above zero, the canvas is unchanged.
2217 // refCanvas() increments the reference count.
2218 // derefCanvas() decrements the reference count.
2221 Q_ASSERT((canvas != 0) == (canvasRefCount > 0));
2223 if (++canvasRefCount > 1) {
2225 qWarning("QQuickItem: Cannot use same item on different canvases at the same time.");
2226 return; // Canvas already set.
2229 Q_ASSERT(canvas == 0);
2232 if (polishScheduled)
2233 QQuickCanvasPrivate::get(canvas)->itemsToPolish.insert(q);
2235 InitializationState _dummy;
2236 InitializationState *childState = state;
2238 if (q->isFocusScope()) {
2240 childState = &_dummy;
2244 QQuickCanvasPrivate::get(canvas)->parentlessItems.insert(q);
2246 for (int ii = 0; ii < childItems.count(); ++ii) {
2247 QQuickItem *child = childItems.at(ii);
2248 QQuickItemPrivate::get(child)->refCanvas(childState, c);
2253 if (extra.isAllocated() && extra->screenAttached)
2254 extra->screenAttached->canvasChanged(c);
2255 itemChange(QQuickItem::ItemSceneChange, c);
2258 void QQuickItemPrivate::derefCanvas()
2261 Q_ASSERT((canvas != 0) == (canvasRefCount > 0));
2264 return; // This can happen when destroying recursive shader effect sources.
2266 if (--canvasRefCount > 0)
2267 return; // There are still other references, so don't set canvas to null yet.
2269 q->releaseResources();
2270 removeFromDirtyList();
2271 QQuickCanvasPrivate *c = QQuickCanvasPrivate::get(canvas);
2272 if (polishScheduled)
2273 c->itemsToPolish.remove(q);
2274 if (c->mouseGrabberItem == q)
2275 c->mouseGrabberItem = 0;
2277 c->hoverItems.removeAll(q);
2278 if (itemNodeInstance)
2279 c->cleanup(itemNodeInstance);
2281 c->parentlessItems.remove(q);
2285 itemNodeInstance = 0;
2287 if (extra.isAllocated()) {
2288 extra->opacityNode = 0;
2289 extra->clipNode = 0;
2290 extra->rootNode = 0;
2291 extra->beforePaintNode = 0;
2297 for (int ii = 0; ii < childItems.count(); ++ii) {
2298 QQuickItem *child = childItems.at(ii);
2299 QQuickItemPrivate::get(child)->derefCanvas();
2304 if (extra.isAllocated() && extra->screenAttached)
2305 extra->screenAttached->canvasChanged(0);
2306 itemChange(QQuickItem::ItemSceneChange, (QQuickCanvas *)0);
2311 Returns a transform that maps points from canvas space into item space.
2313 QTransform QQuickItemPrivate::canvasToItemTransform() const
2315 // XXX todo - optimize
2316 return itemToCanvasTransform().inverted();
2320 Returns a transform that maps points from item space into canvas space.
2322 QTransform QQuickItemPrivate::itemToCanvasTransform() const
2325 QTransform rv = parentItem?QQuickItemPrivate::get(parentItem)->itemToCanvasTransform():QTransform();
2326 itemToParentTransform(rv);
2331 Motifies \a t with this items local transform relative to its parent.
2333 void QQuickItemPrivate::itemToParentTransform(QTransform &t) const
2338 if (!transforms.isEmpty()) {
2340 for (int ii = transforms.count() - 1; ii >= 0; --ii)
2341 transforms.at(ii)->applyTo(&m);
2342 t = m.toTransform();
2345 if (scale() != 1. || rotation() != 0.) {
2346 QPointF tp = computeTransformOrigin();
2347 t.translate(tp.x(), tp.y());
2348 t.scale(scale(), scale());
2349 t.rotate(rotation());
2350 t.translate(-tp.x(), -tp.y());
2356 \qmlproperty real QtQuick2::Item::childrenRect.x
2357 \qmlproperty real QtQuick2::Item::childrenRect.y
2358 \qmlproperty real QtQuick2::Item::childrenRect.width
2359 \qmlproperty real QtQuick2::Item::childrenRect.height
2361 The childrenRect properties allow an item access to the geometry of its
2362 children. This property is useful if you have an item that needs to be
2363 sized to fit its children.
2368 \qmlproperty list<Item> QtQuick2::Item::children
2369 \qmlproperty list<Object> QtQuick2::Item::resources
2371 The children property contains the list of visual children of this item.
2372 The resources property contains non-visual resources that you want to
2375 Generally you can rely on Item's default property to handle all this for
2376 you, but it can come in handy in some cases.
2395 Returns true if construction of the QML component is complete; otherwise
2398 It is often desirable to delay some processing until the component is
2401 \sa componentComplete()
2403 bool QQuickItem::isComponentComplete() const
2405 Q_D(const QQuickItem);
2406 return d->componentComplete;
2409 QQuickItemPrivate::QQuickItemPrivate()
2410 : _anchors(0), _stateGroup(0),
2411 flags(0), widthValid(false), heightValid(false), baselineOffsetValid(false), componentComplete(true),
2412 keepMouse(false), keepTouch(false), hoverEnabled(false), smooth(true), focus(false), activeFocus(false), notifiedFocus(false),
2413 notifiedActiveFocus(false), filtersChildMouseEvents(false), explicitVisible(true),
2414 effectiveVisible(true), explicitEnable(true), effectiveEnable(true), polishScheduled(false),
2415 inheritedLayoutMirror(false), effectiveLayoutMirror(false), isMirrorImplicit(true),
2416 inheritMirrorFromParent(false), inheritMirrorFromItem(false), childrenDoNotOverlap(false),
2417 staticSubtreeGeometry(false),
2418 isAccessible(false),
2420 dirtyAttributes(0), nextDirtyItem(0), prevDirtyItem(0),
2422 canvas(0), canvasRefCount(0), parentItem(0), sortedChildItems(&childItems),
2426 x(0), y(0), width(0), height(0), implicitWidth(0), implicitHeight(0),
2430 itemNodeInstance(0), groupNode(0), paintNode(0)
2434 QQuickItemPrivate::~QQuickItemPrivate()
2436 if (sortedChildItems != &childItems)
2437 delete sortedChildItems;
2440 void QQuickItemPrivate::init(QQuickItem *parent)
2444 static bool atexit_registered = false;
2445 if (!atexit_registered) {
2446 atexit(qt_print_item_count);
2447 atexit_registered = true;
2453 registerAccessorProperties();
2455 baselineOffsetValid = false;
2458 q->setParentItem(parent);
2459 QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(parent);
2460 setImplicitLayoutMirror(parentPrivate->inheritedLayoutMirror, parentPrivate->inheritMirrorFromParent);
2464 void QQuickItemPrivate::data_append(QQmlListProperty<QObject> *prop, QObject *o)
2469 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2471 // This test is measurably (albeit only slightly) faster than qobject_cast<>()
2472 const QMetaObject *mo = o->metaObject();
2473 while (mo && mo != &QQuickItem::staticMetaObject) {
2474 mo = mo->d.superdata;
2478 QQuickItem *item = static_cast<QQuickItem *>(o);
2479 item->setParentItem(that);
2481 if (o->inherits("QGraphicsItem"))
2482 qWarning("Cannot add a QtQuick 1.0 item (%s) into a QtQuick 2.0 scene!", o->metaObject()->className());
2484 // XXX todo - do we really want this behavior?
2490 \qmlproperty list<Object> QtQuick2::Item::data
2493 The data property allows you to freely mix visual children and resources
2494 in an item. If you assign a visual item to the data list it becomes
2495 a child and if you assign any other object type, it is added as a resource.
2519 data is a behind-the-scenes property: you should never need to explicitly
2523 int QQuickItemPrivate::data_count(QQmlListProperty<QObject> *prop)
2530 QObject *QQuickItemPrivate::data_at(QQmlListProperty<QObject> *prop, int i)
2538 void QQuickItemPrivate::data_clear(QQmlListProperty<QObject> *prop)
2544 QObject *QQuickItemPrivate::resources_at(QQmlListProperty<QObject> *prop, int index)
2546 const QObjectList children = prop->object->children();
2547 if (index < children.count())
2548 return children.at(index);
2553 void QQuickItemPrivate::resources_append(QQmlListProperty<QObject> *prop, QObject *o)
2555 // XXX todo - do we really want this behavior?
2556 o->setParent(prop->object);
2559 int QQuickItemPrivate::resources_count(QQmlListProperty<QObject> *prop)
2561 return prop->object->children().count();
2564 void QQuickItemPrivate::resources_clear(QQmlListProperty<QObject> *prop)
2566 // XXX todo - do we really want this behavior?
2567 const QObjectList children = prop->object->children();
2568 for (int index = 0; index < children.count(); index++)
2569 children.at(index)->setParent(0);
2572 QQuickItem *QQuickItemPrivate::children_at(QQmlListProperty<QQuickItem> *prop, int index)
2574 QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2575 if (index >= p->childItems.count() || index < 0)
2578 return p->childItems.at(index);
2581 void QQuickItemPrivate::children_append(QQmlListProperty<QQuickItem> *prop, QQuickItem *o)
2586 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2587 if (o->parentItem() == that)
2588 o->setParentItem(0);
2590 o->setParentItem(that);
2593 int QQuickItemPrivate::children_count(QQmlListProperty<QQuickItem> *prop)
2595 QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2596 return p->childItems.count();
2599 void QQuickItemPrivate::children_clear(QQmlListProperty<QQuickItem> *prop)
2601 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2602 QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2603 while (!p->childItems.isEmpty())
2604 p->childItems.at(0)->setParentItem(0);
2607 void QQuickItemPrivate::visibleChildren_append(QQmlListProperty<QQuickItem>*, QQuickItem *self)
2610 qmlInfo(self) << "QQuickItem: visibleChildren property is readonly and cannot be assigned to.";
2613 int QQuickItemPrivate::visibleChildren_count(QQmlListProperty<QQuickItem> *prop)
2615 QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2616 int visibleCount = 0;
2617 int c = p->childItems.count();
2619 if (p->childItems.at(c)->isVisible()) visibleCount++;
2622 return visibleCount;
2625 QQuickItem *QQuickItemPrivate::visibleChildren_at(QQmlListProperty<QQuickItem> *prop, int index)
2627 QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2628 const int childCount = p->childItems.count();
2629 if (index >= childCount || index < 0)
2632 int visibleCount = -1;
2633 for (int i = 0; i < childCount; i++) {
2634 if (p->childItems.at(i)->isVisible()) visibleCount++;
2635 if (visibleCount == index) return p->childItems.at(i);
2640 int QQuickItemPrivate::transform_count(QQmlListProperty<QQuickTransform> *prop)
2642 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2643 QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2645 return p->transforms.count();
2648 void QQuickTransform::appendToItem(QQuickItem *item)
2650 Q_D(QQuickTransform);
2654 QQuickItemPrivate *p = QQuickItemPrivate::get(item);
2656 if (!d->items.isEmpty() && !p->transforms.isEmpty() && p->transforms.contains(this)) {
2657 p->transforms.removeOne(this);
2658 p->transforms.append(this);
2660 p->transforms.append(this);
2661 d->items.append(item);
2664 p->dirty(QQuickItemPrivate::Transform);
2667 void QQuickTransform::prependToItem(QQuickItem *item)
2669 Q_D(QQuickTransform);
2673 QQuickItemPrivate *p = QQuickItemPrivate::get(item);
2675 if (!d->items.isEmpty() && !p->transforms.isEmpty() && p->transforms.contains(this)) {
2676 p->transforms.removeOne(this);
2677 p->transforms.prepend(this);
2679 p->transforms.prepend(this);
2680 d->items.append(item);
2683 p->dirty(QQuickItemPrivate::Transform);
2686 void QQuickItemPrivate::transform_append(QQmlListProperty<QQuickTransform> *prop, QQuickTransform *transform)
2691 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2692 transform->appendToItem(that);
2695 QQuickTransform *QQuickItemPrivate::transform_at(QQmlListProperty<QQuickTransform> *prop, int idx)
2697 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2698 QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2700 if (idx < 0 || idx >= p->transforms.count())
2703 return p->transforms.at(idx);
2706 void QQuickItemPrivate::transform_clear(QQmlListProperty<QQuickTransform> *prop)
2708 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2709 QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2711 for (int ii = 0; ii < p->transforms.count(); ++ii) {
2712 QQuickTransform *t = p->transforms.at(ii);
2713 QQuickTransformPrivate *tp = QQuickTransformPrivate::get(t);
2714 tp->items.removeOne(that);
2717 p->transforms.clear();
2719 p->dirty(QQuickItemPrivate::Transform);
2723 \property QQuickItem::childrenRect
2724 \brief The geometry of an item's children.
2726 This property holds the (collective) position and size of the item's children.
2730 \qmlproperty real QtQuick2::Item::x
2731 \qmlproperty real QtQuick2::Item::y
2732 \qmlproperty real QtQuick2::Item::width
2733 \qmlproperty real QtQuick2::Item::height
2735 Defines the item's position and size relative to its parent.
2738 Item { x: 100; y: 100; width: 100; height: 100 }
2743 \qmlproperty real QtQuick2::Item::z
2745 Sets the stacking order of sibling items. By default the stacking order is 0.
2747 Items with a higher stacking value are drawn on top of siblings with a
2748 lower stacking order. Items with the same stacking value are drawn
2749 bottom up in the order they appear. Items with a negative stacking
2750 value are drawn under their parent's content.
2752 The following example shows the various effects of stacking order.
2756 \li \image declarative-item_stacking1.png
2757 \li Same \c z - later children above earlier children:
2762 width: 100; height: 100
2766 x: 50; y: 50; width: 100; height: 100
2771 \li \image declarative-item_stacking2.png
2772 \li Higher \c z on top:
2778 width: 100; height: 100
2782 x: 50; y: 50; width: 100; height: 100
2787 \li \image declarative-item_stacking3.png
2788 \li Same \c z - children above parents:
2793 width: 100; height: 100
2796 x: 50; y: 50; width: 100; height: 100
2802 \li \image declarative-item_stacking4.png
2803 \li Lower \c z below:
2808 width: 100; height: 100
2812 x: 50; y: 50; width: 100; height: 100
2821 \qmlproperty bool QtQuick2::Item::visible
2823 This property holds whether the item is visible. By default this is true.
2825 Setting this property directly affects the \c visible value of child
2826 items. When set to \c false, the \c visible values of all child items also
2827 become \c false. When set to \c true, the \c visible values of child items
2828 are returned to \c true, unless they have explicitly been set to \c false.
2830 (Because of this flow-on behavior, using the \c visible property may not
2831 have the intended effect if a property binding should only respond to
2832 explicit property changes. In such cases it may be better to use the
2833 \l opacity property instead.)
2835 Setting this property to \c false automatically causes \l focus to be set
2836 to \c false, and this item will longer receive mouse and keyboard events.
2837 (In contrast, setting the \l opacity to 0 does not affect the \l focus
2838 property and the receiving of key events.)
2840 \note This property's value is only affected by changes to this property or
2841 the parent's \c visible property. It does not change, for example, if this
2842 item moves off-screen, or if the \l opacity changes to 0.
2847 \qmlproperty AnchorLine QtQuick2::Item::anchors.top
2848 \qmlproperty AnchorLine QtQuick2::Item::anchors.bottom
2849 \qmlproperty AnchorLine QtQuick2::Item::anchors.left
2850 \qmlproperty AnchorLine QtQuick2::Item::anchors.right
2851 \qmlproperty AnchorLine QtQuick2::Item::anchors.horizontalCenter
2852 \qmlproperty AnchorLine QtQuick2::Item::anchors.verticalCenter
2853 \qmlproperty AnchorLine QtQuick2::Item::anchors.baseline
2855 \qmlproperty Item QtQuick2::Item::anchors.fill
2856 \qmlproperty Item QtQuick2::Item::anchors.centerIn
2858 \qmlproperty real QtQuick2::Item::anchors.margins
2859 \qmlproperty real QtQuick2::Item::anchors.topMargin
2860 \qmlproperty real QtQuick2::Item::anchors.bottomMargin
2861 \qmlproperty real QtQuick2::Item::anchors.leftMargin
2862 \qmlproperty real QtQuick2::Item::anchors.rightMargin
2863 \qmlproperty real QtQuick2::Item::anchors.horizontalCenterOffset
2864 \qmlproperty real QtQuick2::Item::anchors.verticalCenterOffset
2865 \qmlproperty real QtQuick2::Item::anchors.baselineOffset
2867 \qmlproperty bool QtQuick2::Item::anchors.mirrored
2869 Anchors provide a way to position an item by specifying its
2870 relationship with other items.
2872 Margins apply to top, bottom, left, right, and fill anchors.
2873 The \c anchors.margins property can be used to set all of the various margins at once, to the same value.
2874 Note that margins are anchor-specific and are not applied if an item does not
2877 Offsets apply for horizontal center, vertical center, and baseline anchors.
2881 \li \image declarative-anchors_example.png
2882 \li Text anchored to Image, horizontally centered and vertically below, with a margin.
2891 anchors.horizontalCenter: pic.horizontalCenter
2892 anchors.top: pic.bottom
2893 anchors.topMargin: 5
2899 \li \image declarative-anchors_example2.png
2901 Left of Text anchored to right of Image, with a margin. The y
2902 property of both defaults to 0.
2912 anchors.left: pic.right
2913 anchors.leftMargin: 5
2920 \c anchors.fill provides a convenient way for one item to have the
2921 same geometry as another item, and is equivalent to connecting all
2922 four directional anchors.
2924 To clear an anchor value, set it to \c undefined.
2926 \c anchors.mirrored returns true it the layout has been \l {LayoutMirroring}{mirrored}.
2928 \note You can only anchor an item to siblings or a parent.
2930 For more information see \l {anchor-layout}{Anchor Layouts}.
2934 \property QQuickItem::baselineOffset
2935 \brief The position of the item's baseline in local coordinates.
2937 The baseline of a \l Text item is the imaginary line on which the text
2938 sits. Controls containing text usually set their baseline to the
2939 baseline of their text.
2941 For non-text items, a default baseline offset of 0 is used.
2943 QQuickAnchors *QQuickItemPrivate::anchors() const
2946 Q_Q(const QQuickItem);
2947 _anchors = new QQuickAnchors(const_cast<QQuickItem *>(q));
2948 if (!componentComplete)
2949 _anchors->classBegin();
2954 void QQuickItemPrivate::siblingOrderChanged()
2957 for (int ii = 0; ii < changeListeners.count(); ++ii) {
2958 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
2959 if (change.types & QQuickItemPrivate::SiblingOrder) {
2960 change.listener->itemSiblingOrderChanged(q);
2965 QQmlListProperty<QObject> QQuickItemPrivate::data()
2967 return QQmlListProperty<QObject>(q_func(), 0, QQuickItemPrivate::data_append,
2968 QQuickItemPrivate::data_count,
2969 QQuickItemPrivate::data_at,
2970 QQuickItemPrivate::data_clear);
2973 QRectF QQuickItem::childrenRect()
2976 if (!d->extra.isAllocated() || !d->extra->contents) {
2977 d->extra.value().contents = new QQuickContents(this);
2978 if (d->componentComplete)
2979 d->extra->contents->complete();
2981 return d->extra->contents->rectF();
2984 QList<QQuickItem *> QQuickItem::childItems() const
2986 Q_D(const QQuickItem);
2987 return d->childItems;
2990 bool QQuickItem::clip() const
2992 return flags() & ItemClipsChildrenToShape;
2995 void QQuickItem::setClip(bool c)
3000 setFlag(ItemClipsChildrenToShape, c);
3002 emit clipChanged(c);
3007 This function is called to handle this item's changes in
3008 geometry from \a oldGeometry to \a newGeometry. If the two
3009 geometries are the same, it doesn't do anything.
3011 void QQuickItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
3016 QQuickAnchorsPrivate::get(d->_anchors)->updateMe();
3018 bool xChange = (newGeometry.x() != oldGeometry.x());
3019 bool yChange = (newGeometry.y() != oldGeometry.y());
3020 bool widthChange = (newGeometry.width() != oldGeometry.width());
3021 bool heightChange = (newGeometry.height() != oldGeometry.height());
3023 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
3024 const QQuickItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
3025 if (change.types & QQuickItemPrivate::Geometry) {
3026 if (change.gTypes == QQuickItemPrivate::GeometryChange) {
3027 change.listener->itemGeometryChanged(this, newGeometry, oldGeometry);
3028 } else if ((xChange && (change.gTypes & QQuickItemPrivate::XChange)) ||
3029 (yChange && (change.gTypes & QQuickItemPrivate::YChange)) ||
3030 (widthChange && (change.gTypes & QQuickItemPrivate::WidthChange)) ||
3031 (heightChange && (change.gTypes & QQuickItemPrivate::HeightChange))) {
3032 change.listener->itemGeometryChanged(this, newGeometry, oldGeometry);
3042 emit widthChanged();
3044 emit heightChanged();
3048 Called by the rendering thread when it is time to sync the state of the QML objects with the
3049 scene graph objects. The function should return the root of the scene graph subtree for
3050 this item. \a oldNode is the node that was returned the last time the function was called.
3052 The main thread is blocked while this function is executed so it is safe to read
3053 values from the QQuickItem instance and other objects in the main thread.
3055 \warning This is the only function in which it is allowed to make use of scene graph
3056 objects from the main thread. Use of scene graph objects outside this function will
3057 result in race conditions and potential crashes.
3060 QSGNode *QQuickItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
3067 This function is called when the item's scene graph resources are no longer needed.
3068 It allows items to free its resources, for instance textures, that are not owned by scene graph
3069 nodes. Note that scene graph nodes are managed by QQuickCanvas and should not be deleted by
3070 this function. Scene graph resources are no longer needed when the parent is set to null and
3071 the item is not used by any \l ShaderEffect or \l ShaderEffectSource.
3073 This function is called from the main thread. Therefore, resources used by the scene graph
3074 should not be deleted directly, but by calling \l QObject::deleteLater().
3076 \note The item destructor still needs to free its scene graph resources if not already done.
3079 void QQuickItem::releaseResources()
3083 QSGTransformNode *QQuickItemPrivate::createTransformNode()
3085 return new QSGTransformNode;
3088 void QQuickItem::updatePolish()
3092 void QQuickItemPrivate::addItemChangeListener(QQuickItemChangeListener *listener, ChangeTypes types)
3094 changeListeners.append(ChangeListener(listener, types));
3097 void QQuickItemPrivate::removeItemChangeListener(QQuickItemChangeListener *listener, ChangeTypes types)
3099 ChangeListener change(listener, types);
3100 changeListeners.removeOne(change);
3103 void QQuickItemPrivate::updateOrAddGeometryChangeListener(QQuickItemChangeListener *listener, GeometryChangeTypes types)
3105 ChangeListener change(listener, types);
3106 int index = changeListeners.find(change);
3108 changeListeners[index].gTypes = change.gTypes; //we may have different GeometryChangeTypes
3110 changeListeners.append(change);
3113 void QQuickItemPrivate::updateOrRemoveGeometryChangeListener(QQuickItemChangeListener *listener,
3114 GeometryChangeTypes types)
3116 ChangeListener change(listener, types);
3117 if (types == NoChange) {
3118 changeListeners.removeOne(change);
3120 int index = changeListeners.find(change);
3122 changeListeners[index].gTypes = change.gTypes; //we may have different GeometryChangeTypes
3126 void QQuickItem::keyPressEvent(QKeyEvent *event)
3131 void QQuickItem::keyReleaseEvent(QKeyEvent *event)
3136 void QQuickItem::inputMethodEvent(QInputMethodEvent *event)
3141 void QQuickItem::focusInEvent(QFocusEvent *)
3143 #ifndef QT_NO_ACCESSIBILITY
3144 QAccessibleEvent ev(this, QAccessible::Focus);
3145 QAccessible::updateAccessibility(&ev);
3149 void QQuickItem::focusOutEvent(QFocusEvent *)
3153 void QQuickItem::mousePressEvent(QMouseEvent *event)
3158 void QQuickItem::mouseMoveEvent(QMouseEvent *event)
3163 void QQuickItem::mouseReleaseEvent(QMouseEvent *event)
3168 void QQuickItem::mouseDoubleClickEvent(QMouseEvent *)
3172 void QQuickItem::mouseUngrabEvent()
3177 void QQuickItem::touchUngrabEvent()
3182 void QQuickItem::wheelEvent(QWheelEvent *event)
3187 void QQuickItem::touchEvent(QTouchEvent *event)
3192 void QQuickItem::hoverEnterEvent(QHoverEvent *event)
3197 void QQuickItem::hoverMoveEvent(QHoverEvent *event)
3202 void QQuickItem::hoverLeaveEvent(QHoverEvent *event)
3207 void QQuickItem::dragEnterEvent(QDragEnterEvent *event)
3212 void QQuickItem::dragMoveEvent(QDragMoveEvent *event)
3218 void QQuickItem::dragLeaveEvent(QDragLeaveEvent *event)
3224 void QQuickItem::dropEvent(QDropEvent *event)
3229 bool QQuickItem::childMouseEventFilter(QQuickItem *, QEvent *)
3234 void QQuickItem::windowDeactivateEvent()
3236 foreach (QQuickItem* item, childItems()) {
3237 item->windowDeactivateEvent();
3241 QVariant QQuickItem::inputMethodQuery(Qt::InputMethodQuery query) const
3243 Q_D(const QQuickItem);
3248 v = (bool)(flags() & ItemAcceptsInputMethod);
3251 case Qt::ImCursorRectangle:
3253 case Qt::ImCursorPosition:
3254 case Qt::ImSurroundingText:
3255 case Qt::ImCurrentSelection:
3256 case Qt::ImMaximumTextLength:
3257 case Qt::ImAnchorPosition:
3258 case Qt::ImPreferredLanguage:
3259 if (d->extra.isAllocated() && d->extra->keyHandler)
3260 v = d->extra->keyHandler->inputMethodQuery(query);
3268 QQuickAnchorLine QQuickItemPrivate::left() const
3270 Q_Q(const QQuickItem);
3271 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Left);
3274 QQuickAnchorLine QQuickItemPrivate::right() const
3276 Q_Q(const QQuickItem);
3277 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Right);
3280 QQuickAnchorLine QQuickItemPrivate::horizontalCenter() const
3282 Q_Q(const QQuickItem);
3283 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::HCenter);
3286 QQuickAnchorLine QQuickItemPrivate::top() const
3288 Q_Q(const QQuickItem);
3289 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Top);
3292 QQuickAnchorLine QQuickItemPrivate::bottom() const
3294 Q_Q(const QQuickItem);
3295 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Bottom);
3298 QQuickAnchorLine QQuickItemPrivate::verticalCenter() const
3300 Q_Q(const QQuickItem);
3301 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::VCenter);
3304 QQuickAnchorLine QQuickItemPrivate::baseline() const
3306 Q_Q(const QQuickItem);
3307 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Baseline);
3310 qreal QQuickItem::baselineOffset() const
3312 Q_D(const QQuickItem);
3313 if (d->baselineOffsetValid) {
3314 return d->baselineOffset;
3320 void QQuickItem::setBaselineOffset(qreal offset)
3323 if (offset == d->baselineOffset)
3326 d->baselineOffset = offset;
3327 d->baselineOffsetValid = true;
3329 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
3330 const QQuickItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
3331 if (change.types & QQuickItemPrivate::Geometry) {
3332 QQuickAnchorsPrivate *anchor = change.listener->anchorPrivate();
3334 anchor->updateVerticalAnchors();
3338 if (d->_anchors && (d->_anchors->usedAnchors() & QQuickAnchors::BaselineAnchor))
3339 QQuickAnchorsPrivate::get(d->_anchors)->updateVerticalAnchors();
3341 emit baselineOffsetChanged(offset);
3344 void QQuickItem::update()
3347 Q_ASSERT(flags() & ItemHasContents);
3348 d->dirty(QQuickItemPrivate::Content);
3351 void QQuickItem::polish()
3354 if (!d->polishScheduled) {
3355 d->polishScheduled = true;
3357 QQuickCanvasPrivate *p = QQuickCanvasPrivate::get(d->canvas);
3358 bool maybeupdate = p->itemsToPolish.isEmpty();
3359 p->itemsToPolish.insert(this);
3360 if (maybeupdate) d->canvas->maybeUpdate();
3365 void QQuickItem::mapFromItem(QQmlV8Function *args) const
3367 if (args->Length() != 0) {
3368 v8::Local<v8::Value> item = (*args)[0];
3369 QV8Engine *engine = args->engine();
3371 QQuickItem *itemObj = 0;
3372 if (!item->IsNull())
3373 itemObj = qobject_cast<QQuickItem*>(engine->toQObject(item));
3375 if (!itemObj && !item->IsNull()) {
3376 qmlInfo(this) << "mapFromItem() given argument \"" << engine->toString(item->ToString())
3377 << "\" which is neither null nor an Item";
3381 v8::Local<v8::Object> rv = v8::Object::New();
3382 args->returnValue(rv);
3384 qreal x = (args->Length() > 1)?(*args)[1]->NumberValue():0;
3385 qreal y = (args->Length() > 2)?(*args)[2]->NumberValue():0;
3387 QPointF p = mapFromItem(itemObj, QPointF(x, y));
3389 rv->Set(v8::String::New("x"), v8::Number::New(p.x()));
3390 rv->Set(v8::String::New("y"), v8::Number::New(p.y()));
3394 QTransform QQuickItem::itemTransform(QQuickItem *other, bool *ok) const
3396 Q_D(const QQuickItem);
3398 // XXX todo - we need to be able to handle common parents better and detect
3402 QTransform t = d->itemToCanvasTransform();
3403 if (other) t *= QQuickItemPrivate::get(other)->canvasToItemTransform();
3408 void QQuickItem::mapToItem(QQmlV8Function *args) const
3410 if (args->Length() != 0) {
3411 v8::Local<v8::Value> item = (*args)[0];
3412 QV8Engine *engine = args->engine();
3414 QQuickItem *itemObj = 0;
3415 if (!item->IsNull())
3416 itemObj = qobject_cast<QQuickItem*>(engine->toQObject(item));
3418 if (!itemObj && !item->IsNull()) {
3419 qmlInfo(this) << "mapToItem() given argument \"" << engine->toString(item->ToString())
3420 << "\" which is neither null nor an Item";
3424 v8::Local<v8::Object> rv = v8::Object::New();
3425 args->returnValue(rv);
3427 qreal x = (args->Length() > 1)?(*args)[1]->NumberValue():0;
3428 qreal y = (args->Length() > 2)?(*args)[2]->NumberValue():0;
3430 QPointF p = mapToItem(itemObj, QPointF(x, y));
3432 rv->Set(v8::String::New("x"), v8::Number::New(p.x()));
3433 rv->Set(v8::String::New("y"), v8::Number::New(p.y()));
3437 void QQuickItem::forceActiveFocus()
3440 QQuickItem *parent = parentItem();
3442 if (parent->flags() & QQuickItem::ItemIsFocusScope) {
3443 parent->setFocus(true);
3445 parent = parent->parentItem();
3449 QQuickItem *QQuickItem::childAt(qreal x, qreal y) const
3451 // XXX todo - should this include transform etc.?
3452 const QList<QQuickItem *> children = childItems();
3453 for (int i = children.count()-1; i >= 0; --i) {
3454 QQuickItem *child = children.at(i);
3455 if (child->isVisible() && child->x() <= x
3456 && child->x() + child->width() >= x
3458 && child->y() + child->height() >= y)
3464 QQmlListProperty<QObject> QQuickItemPrivate::resources()
3466 return QQmlListProperty<QObject>(q_func(), 0, QQuickItemPrivate::resources_append,
3467 QQuickItemPrivate::resources_count,
3468 QQuickItemPrivate::resources_at,
3469 QQuickItemPrivate::resources_clear);
3472 QQmlListProperty<QQuickItem> QQuickItemPrivate::children()
3474 return QQmlListProperty<QQuickItem>(q_func(), 0, QQuickItemPrivate::children_append,
3475 QQuickItemPrivate::children_count,
3476 QQuickItemPrivate::children_at,
3477 QQuickItemPrivate::children_clear);
3482 \qmlproperty real QtQuick2::Item::visibleChildren
3483 This read-only property lists all of the item's children that are currently visible.
3484 Note that a child's visibility may have changed explicitly, or because the visibility
3485 of this (it's parent) item or another grandparent changed.
3487 QQmlListProperty<QQuickItem> QQuickItemPrivate::visibleChildren()
3489 return QQmlListProperty<QQuickItem>(q_func(), 0, QQuickItemPrivate::visibleChildren_append,
3490 QQuickItemPrivate::visibleChildren_count,
3491 QQuickItemPrivate::visibleChildren_at);
3495 QQmlListProperty<QQuickState> QQuickItemPrivate::states()
3497 return _states()->statesProperty();
3500 QQmlListProperty<QQuickTransition> QQuickItemPrivate::transitions()
3502 return _states()->transitionsProperty();
3505 QString QQuickItemPrivate::state() const
3510 return _stateGroup->state();
3513 void QQuickItemPrivate::setState(const QString &state)
3515 _states()->setState(state);
3518 QString QQuickItem::state() const
3520 Q_D(const QQuickItem);
3524 void QQuickItem::setState(const QString &state)
3530 QQmlListProperty<QQuickTransform> QQuickItem::transform()
3532 return QQmlListProperty<QQuickTransform>(this, 0, QQuickItemPrivate::transform_append,
3533 QQuickItemPrivate::transform_count,
3534 QQuickItemPrivate::transform_at,
3535 QQuickItemPrivate::transform_clear);
3538 void QQuickItem::classBegin()
3541 d->componentComplete = false;
3543 d->_stateGroup->classBegin();
3545 d->_anchors->classBegin();
3546 if (d->extra.isAllocated() && d->extra->layer)
3547 d->extra->layer->classBegin();
3550 void QQuickItem::componentComplete()
3553 d->componentComplete = true;
3555 d->_stateGroup->componentComplete();
3557 d->_anchors->componentComplete();
3558 QQuickAnchorsPrivate::get(d->_anchors)->updateOnComplete();
3561 if (d->extra.isAllocated() && d->extra->layer)
3562 d->extra->layer->componentComplete();
3564 if (d->extra.isAllocated() && d->extra->keyHandler)
3565 d->extra->keyHandler->componentComplete();
3567 if (d->extra.isAllocated() && d->extra->contents)
3568 d->extra->contents->complete();
3571 QQuickStateGroup *QQuickItemPrivate::_states()
3575 _stateGroup = new QQuickStateGroup;
3576 if (!componentComplete)
3577 _stateGroup->classBegin();
3578 FAST_CONNECT(_stateGroup, SIGNAL(stateChanged(QString)),
3579 q, SIGNAL(stateChanged(QString)))
3585 QPointF QQuickItemPrivate::computeTransformOrigin() const
3589 case QQuickItem::TopLeft:
3590 return QPointF(0, 0);
3591 case QQuickItem::Top:
3592 return QPointF(width / 2., 0);
3593 case QQuickItem::TopRight:
3594 return QPointF(width, 0);
3595 case QQuickItem::Left:
3596 return QPointF(0, height / 2.);
3597 case QQuickItem::Center:
3598 return QPointF(width / 2., height / 2.);
3599 case QQuickItem::Right:
3600 return QPointF(width, height / 2.);
3601 case QQuickItem::BottomLeft:
3602 return QPointF(0, height);
3603 case QQuickItem::Bottom:
3604 return QPointF(width / 2., height);
3605 case QQuickItem::BottomRight:
3606 return QPointF(width, height);
3610 void QQuickItemPrivate::transformChanged()
3612 if (extra.isAllocated() && extra->layer)
3613 extra->layer->updateMatrix();
3616 void QQuickItemPrivate::deliverKeyEvent(QKeyEvent *e)
3620 Q_ASSERT(e->isAccepted());
3621 if (extra.isAllocated() && extra->keyHandler) {
3622 if (e->type() == QEvent::KeyPress)
3623 extra->keyHandler->keyPressed(e, false);
3625 extra->keyHandler->keyReleased(e, false);
3627 if (e->isAccepted())
3633 if (e->type() == QEvent::KeyPress)
3634 q->keyPressEvent(e);
3636 q->keyReleaseEvent(e);
3638 if (e->isAccepted())
3641 if (extra.isAllocated() && extra->keyHandler) {
3644 if (e->type() == QEvent::KeyPress)
3645 extra->keyHandler->keyPressed(e, true);
3647 extra->keyHandler->keyReleased(e, true);
3651 void QQuickItemPrivate::deliverInputMethodEvent(QInputMethodEvent *e)
3655 Q_ASSERT(e->isAccepted());
3656 if (extra.isAllocated() && extra->keyHandler) {
3657 extra->keyHandler->inputMethodEvent(e, false);
3659 if (e->isAccepted())
3665 q->inputMethodEvent(e);
3667 if (e->isAccepted())
3670 if (extra.isAllocated() && extra->keyHandler) {
3673 extra->keyHandler->inputMethodEvent(e, true);
3677 void QQuickItemPrivate::deliverFocusEvent(QFocusEvent *e)
3681 if (e->type() == QEvent::FocusIn) {
3684 q->focusOutEvent(e);
3688 void QQuickItemPrivate::deliverMouseEvent(QMouseEvent *e)
3692 Q_ASSERT(e->isAccepted());
3694 switch (e->type()) {
3696 Q_ASSERT(!"Unknown event type");
3697 case QEvent::MouseMove:
3698 q->mouseMoveEvent(e);
3700 case QEvent::MouseButtonPress:
3701 q->mousePressEvent(e);
3703 case QEvent::MouseButtonRelease:
3704 q->mouseReleaseEvent(e);
3706 case QEvent::MouseButtonDblClick:
3707 q->mouseDoubleClickEvent(e);
3712 void QQuickItemPrivate::deliverWheelEvent(QWheelEvent *e)
3718 void QQuickItemPrivate::deliverTouchEvent(QTouchEvent *e)
3724 void QQuickItemPrivate::deliverHoverEvent(QHoverEvent *e)
3727 switch (e->type()) {
3729 Q_ASSERT(!"Unknown event type");
3730 case QEvent::HoverEnter:
3731 q->hoverEnterEvent(e);
3733 case QEvent::HoverLeave:
3734 q->hoverLeaveEvent(e);
3736 case QEvent::HoverMove:
3737 q->hoverMoveEvent(e);
3742 void QQuickItemPrivate::deliverDragEvent(QEvent *e)
3745 switch (e->type()) {
3747 Q_ASSERT(!"Unknown event type");
3748 case QEvent::DragEnter:
3749 q->dragEnterEvent(static_cast<QDragEnterEvent *>(e));
3751 case QEvent::DragLeave:
3752 q->dragLeaveEvent(static_cast<QDragLeaveEvent *>(e));
3754 case QEvent::DragMove:
3755 q->dragMoveEvent(static_cast<QDragMoveEvent *>(e));
3758 q->dropEvent(static_cast<QDropEvent *>(e));
3763 void QQuickItem::itemChange(ItemChange change, const ItemChangeData &value)
3770 Notify input method on updated query values if needed. \a indicates changed attributes.
3772 void QQuickItem::updateInputMethod(Qt::InputMethodQueries queries)
3774 if (hasActiveFocus())
3775 qApp->inputMethod()->update(queries);
3779 // XXX todo - do we want/need this anymore?
3780 QRectF QQuickItem::boundingRect() const
3782 Q_D(const QQuickItem);
3783 return QRectF(0, 0, d->width, d->height);
3787 QRectF QQuickItem::clipRect() const
3789 Q_D(const QQuickItem);
3790 return QRectF(0, 0, d->width, d->height);
3794 QQuickItem::TransformOrigin QQuickItem::transformOrigin() const
3796 Q_D(const QQuickItem);
3800 void QQuickItem::setTransformOrigin(TransformOrigin origin)
3803 if (origin == d->origin())
3806 d->extra.value().origin = origin;
3807 d->dirty(QQuickItemPrivate::TransformOrigin);
3809 emit transformOriginChanged(d->origin());
3812 QPointF QQuickItem::transformOriginPoint() const
3814 Q_D(const QQuickItem);
3815 if (d->extra.isAllocated() && !d->extra->userTransformOriginPoint.isNull())
3816 return d->extra->userTransformOriginPoint;
3817 return d->computeTransformOrigin();
3820 void QQuickItem::setTransformOriginPoint(const QPointF &point)
3823 if (d->extra.value().userTransformOriginPoint == point)
3826 d->extra->userTransformOriginPoint = point;
3827 d->dirty(QQuickItemPrivate::TransformOrigin);
3830 qreal QQuickItem::z() const
3832 Q_D(const QQuickItem);
3836 void QQuickItem::setZ(qreal v)
3842 d->extra.value().z = v;
3844 d->dirty(QQuickItemPrivate::ZValue);
3845 if (d->parentItem) {
3846 QQuickItemPrivate::get(d->parentItem)->dirty(QQuickItemPrivate::ChildrenStackingChanged);
3847 QQuickItemPrivate::get(d->parentItem)->markSortedChildrenDirty(this);
3852 if (d->extra.isAllocated() && d->extra->layer)
3853 d->extra->layer->updateZ();
3858 \qmlproperty real QtQuick2::Item::rotation
3859 This property holds the rotation of the item in degrees clockwise.
3861 This specifies how many degrees to rotate the item around its transformOrigin.
3862 The default rotation is 0 degrees (i.e. not rotated at all).
3866 \li \image declarative-rotation.png
3871 width: 100; height: 100
3874 x: 25; y: 25; width: 50; height: 50
3881 \sa transform, Rotation
3885 \qmlproperty real QtQuick2::Item::scale
3886 This property holds the scale of the item.
3888 A scale of less than 1 means the item will be displayed smaller than
3889 normal, and a scale of greater than 1 means the item will be
3890 displayed larger than normal. A negative scale means the item will
3893 By default, items are displayed at a scale of 1 (i.e. at their
3896 Scaling is from the item's transformOrigin.
3900 \li \image declarative-scale.png
3905 width: 100; height: 100
3908 width: 25; height: 25
3912 x: 25; y: 25; width: 50; height: 50
3919 \sa transform, Scale
3923 \qmlproperty real QtQuick2::Item::opacity
3925 This property holds the opacity of the item. Opacity is specified as a
3926 number between 0 (fully transparent) and 1 (fully opaque). The default is 1.
3928 When this property is set, the specified opacity is also applied
3929 individually to child items. In almost all cases this is what you want,
3930 but in some cases it may produce undesired results. For example in the
3931 second set of rectangles below, the red rectangle has specified an opacity
3932 of 0.5, which affects the opacity of its blue child rectangle even though
3933 the child has not specified an opacity.
3937 \li \image declarative-item_opacity1.png
3943 width: 100; height: 100
3946 x: 50; y: 50; width: 100; height: 100
3952 \li \image declarative-item_opacity2.png
3959 width: 100; height: 100
3962 x: 50; y: 50; width: 100; height: 100
3969 If an item's opacity is set to 0, the item will no longer receive mouse
3970 events, but will continue to receive key events and will retain the keyboard
3971 \l focus if it has been set. (In contrast, setting the \l visible property
3972 to \c false stops both mouse and keyboard events, and also removes focus
3977 Returns a value indicating whether mouse input should
3978 remain with this item exclusively.
3980 \sa setKeepMouseGrab()
3983 qreal QQuickItem::rotation() const
3985 Q_D(const QQuickItem);
3986 return d->rotation();
3989 void QQuickItem::setRotation(qreal r)
3992 if (d->rotation() == r)
3995 d->extra.value().rotation = r;
3997 d->dirty(QQuickItemPrivate::BasicTransform);
3999 d->itemChange(ItemRotationHasChanged, r);
4001 emit rotationChanged();
4004 qreal QQuickItem::scale() const
4006 Q_D(const QQuickItem);
4010 void QQuickItem::setScale(qreal s)
4013 if (d->scale() == s)
4016 d->extra.value().scale = s;
4018 d->dirty(QQuickItemPrivate::BasicTransform);
4020 emit scaleChanged();
4023 qreal QQuickItem::opacity() const
4025 Q_D(const QQuickItem);
4026 return d->opacity();
4029 void QQuickItem::setOpacity(qreal o)
4032 if (d->opacity() == o)
4035 d->extra.value().opacity = o;
4037 d->dirty(QQuickItemPrivate::OpacityValue);
4039 d->itemChange(ItemOpacityHasChanged, o);
4041 emit opacityChanged();
4044 bool QQuickItem::isVisible() const
4046 Q_D(const QQuickItem);
4047 return d->effectiveVisible;
4050 void QQuickItem::setVisible(bool v)
4053 if (v == d->explicitVisible)
4056 d->explicitVisible = v;
4058 const bool childVisibilityChanged = d->setEffectiveVisibleRecur(d->calcEffectiveVisible());
4059 if (childVisibilityChanged && d->parentItem)
4060 emit d->parentItem->visibleChildrenChanged(); // signal the parent, not this!
4063 bool QQuickItem::isEnabled() const
4065 Q_D(const QQuickItem);
4066 return d->effectiveEnable;
4069 void QQuickItem::setEnabled(bool e)
4072 if (e == d->explicitEnable)
4075 d->explicitEnable = e;
4077 QQuickItem *scope = parentItem();
4078 while (scope && !scope->isFocusScope())
4079 scope = scope->parentItem();
4081 d->setEffectiveEnableRecur(scope, d->calcEffectiveEnable());
4084 bool QQuickItemPrivate::calcEffectiveVisible() const
4086 // XXX todo - Should the effective visible of an element with no parent just be the current
4087 // effective visible? This would prevent pointless re-processing in the case of an element
4088 // moving to/from a no-parent situation, but it is different from what graphics view does.
4089 return explicitVisible && (!parentItem || QQuickItemPrivate::get(parentItem)->effectiveVisible);
4092 bool QQuickItemPrivate::setEffectiveVisibleRecur(bool newEffectiveVisible)
4096 if (newEffectiveVisible && !explicitVisible) {
4097 // This item locally overrides visibility
4098 return false; // effective visibility didn't change
4101 if (newEffectiveVisible == effectiveVisible) {
4102 // No change necessary
4103 return false; // effective visibility didn't change
4106 effectiveVisible = newEffectiveVisible;
4108 if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
4111 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(canvas);
4112 if (canvasPriv->mouseGrabberItem == q)
4116 bool childVisibilityChanged = false;
4117 for (int ii = 0; ii < childItems.count(); ++ii)
4118 childVisibilityChanged |= QQuickItemPrivate::get(childItems.at(ii))->setEffectiveVisibleRecur(newEffectiveVisible);
4120 itemChange(QQuickItem::ItemVisibleHasChanged, effectiveVisible);
4121 #ifndef QT_NO_ACCESSIBILITY
4123 QAccessibleEvent ev(q, effectiveVisible ? QAccessible::ObjectShow : QAccessible::ObjectHide);
4124 QAccessible::updateAccessibility(&ev);
4127 emit q->visibleChanged();
4128 if (childVisibilityChanged)
4129 emit q->visibleChildrenChanged();
4131 return true; // effective visibility DID change
4134 bool QQuickItemPrivate::calcEffectiveEnable() const
4136 // XXX todo - Should the effective enable of an element with no parent just be the current
4137 // effective enable? This would prevent pointless re-processing in the case of an element
4138 // moving to/from a no-parent situation, but it is different from what graphics view does.
4139 return explicitEnable && (!parentItem || QQuickItemPrivate::get(parentItem)->effectiveEnable);
4142 void QQuickItemPrivate::setEffectiveEnableRecur(QQuickItem *scope, bool newEffectiveEnable)
4146 if (newEffectiveEnable && !explicitEnable) {
4147 // This item locally overrides enable
4151 if (newEffectiveEnable == effectiveEnable) {
4152 // No change necessary
4156 effectiveEnable = newEffectiveEnable;
4159 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(canvas);
4160 if (canvasPriv->mouseGrabberItem == q)
4162 if (scope && !effectiveEnable && activeFocus) {
4163 canvasPriv->clearFocusInScope(
4164 scope, q, QQuickCanvasPrivate::DontChangeFocusProperty | QQuickCanvasPrivate::DontChangeSubFocusItem);
4168 for (int ii = 0; ii < childItems.count(); ++ii) {
4169 QQuickItemPrivate::get(childItems.at(ii))->setEffectiveEnableRecur(
4170 (flags & QQuickItem::ItemIsFocusScope) && scope ? q : scope, newEffectiveEnable);
4173 if (canvas && scope && effectiveEnable && focus) {
4174 QQuickCanvasPrivate::get(canvas)->setFocusInScope(
4175 scope, q, QQuickCanvasPrivate::DontChangeFocusProperty | QQuickCanvasPrivate::DontChangeSubFocusItem);
4178 emit q->enabledChanged();
4181 QString QQuickItemPrivate::dirtyToString() const
4183 #define DIRTY_TO_STRING(value) if (dirtyAttributes & value) { \
4184 if (!rv.isEmpty()) \
4185 rv.append(QLatin1String("|")); \
4186 rv.append(QLatin1String(#value)); \
4189 // QString rv = QLatin1String("0x") + QString::number(dirtyAttributes, 16);
4192 DIRTY_TO_STRING(TransformOrigin);
4193 DIRTY_TO_STRING(Transform);
4194 DIRTY_TO_STRING(BasicTransform);
4195 DIRTY_TO_STRING(Position);
4196 DIRTY_TO_STRING(Size);
4197 DIRTY_TO_STRING(ZValue);
4198 DIRTY_TO_STRING(Content);
4199 DIRTY_TO_STRING(Smooth);
4200 DIRTY_TO_STRING(OpacityValue);
4201 DIRTY_TO_STRING(ChildrenChanged);
4202 DIRTY_TO_STRING(ChildrenStackingChanged);
4203 DIRTY_TO_STRING(ParentChanged);
4204 DIRTY_TO_STRING(Clip);
4205 DIRTY_TO_STRING(Canvas);
4206 DIRTY_TO_STRING(EffectReference);
4207 DIRTY_TO_STRING(Visible);
4208 DIRTY_TO_STRING(HideReference);
4209 DIRTY_TO_STRING(PerformanceHints);
4214 void QQuickItemPrivate::dirty(DirtyType type)
4217 if (type & (TransformOrigin | Transform | BasicTransform | Position | Size))
4220 if (!(dirtyAttributes & type) || (canvas && !prevDirtyItem)) {
4221 dirtyAttributes |= type;
4224 QQuickCanvasPrivate::get(canvas)->dirtyItem(q);
4229 void QQuickItemPrivate::addToDirtyList()
4234 if (!prevDirtyItem) {
4235 Q_ASSERT(!nextDirtyItem);
4237 QQuickCanvasPrivate *p = QQuickCanvasPrivate::get(canvas);
4238 nextDirtyItem = p->dirtyItemList;
4239 if (nextDirtyItem) QQuickItemPrivate::get(nextDirtyItem)->prevDirtyItem = &nextDirtyItem;
4240 prevDirtyItem = &p->dirtyItemList;
4241 p->dirtyItemList = q;
4244 Q_ASSERT(prevDirtyItem);
4247 void QQuickItemPrivate::removeFromDirtyList()
4249 if (prevDirtyItem) {
4250 if (nextDirtyItem) QQuickItemPrivate::get(nextDirtyItem)->prevDirtyItem = prevDirtyItem;
4251 *prevDirtyItem = nextDirtyItem;
4255 Q_ASSERT(!prevDirtyItem);
4256 Q_ASSERT(!nextDirtyItem);
4259 void QQuickItemPrivate::refFromEffectItem(bool hide)
4261 ++extra.value().effectRefCount;
4262 if (1 == extra->effectRefCount) {
4263 dirty(EffectReference);
4264 if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
4267 if (++extra->hideRefCount == 1)
4268 dirty(HideReference);
4272 void QQuickItemPrivate::derefFromEffectItem(bool unhide)
4274 Q_ASSERT(extra->effectRefCount);
4275 --extra->effectRefCount;
4276 if (0 == extra->effectRefCount) {
4277 dirty(EffectReference);
4278 if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
4281 if (--extra->hideRefCount == 0)
4282 dirty(HideReference);
4286 void QQuickItemPrivate::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data)
4290 case QQuickItem::ItemChildAddedChange:
4291 q->itemChange(change, data);
4292 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4293 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4294 if (change.types & QQuickItemPrivate::Children) {
4295 change.listener->itemChildAdded(q, data.item);
4299 case QQuickItem::ItemChildRemovedChange:
4300 q->itemChange(change, data);
4301 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4302 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4303 if (change.types & QQuickItemPrivate::Children) {
4304 change.listener->itemChildRemoved(q, data.item);
4308 case QQuickItem::ItemSceneChange:
4309 q->itemChange(change, data);
4311 case QQuickItem::ItemVisibleHasChanged:
4312 q->itemChange(change, data);
4313 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4314 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4315 if (change.types & QQuickItemPrivate::Visibility) {
4316 change.listener->itemVisibilityChanged(q);
4320 case QQuickItem::ItemParentHasChanged:
4321 q->itemChange(change, data);
4322 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4323 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4324 if (change.types & QQuickItemPrivate::Parent) {
4325 change.listener->itemParentChanged(q, data.item);
4329 case QQuickItem::ItemOpacityHasChanged:
4330 q->itemChange(change, data);
4331 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4332 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4333 if (change.types & QQuickItemPrivate::Opacity) {
4334 change.listener->itemOpacityChanged(q);
4338 case QQuickItem::ItemActiveFocusHasChanged:
4339 q->itemChange(change, data);
4341 case QQuickItem::ItemRotationHasChanged:
4342 q->itemChange(change, data);
4343 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4344 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4345 if (change.types & QQuickItemPrivate::Rotation) {
4346 change.listener->itemRotationChanged(q);
4354 \property QQuickItem::smooth
4355 \brief whether the item is smoothed or not.
4357 Primarily used in image based elements to decide if the item should use smooth
4358 sampling or not. Smooth sampling is performed using linear interpolation, while
4359 non-smooth is performed using nearest neighbor.
4361 In Qt Quick 2.0, this property has minimal impact on performance.
4367 Returns true if the item should be drawn with antialiasing and
4368 smooth pixmap filtering, false otherwise.
4370 The default is false.
4374 bool QQuickItem::smooth() const
4376 Q_D(const QQuickItem);
4381 Sets whether the item should be drawn with antialiasing and
4382 smooth pixmap filtering to \a smooth.
4386 void QQuickItem::setSmooth(bool smooth)
4389 if (d->smooth == smooth)
4393 d->dirty(QQuickItemPrivate::Smooth);
4395 emit smoothChanged(smooth);
4398 QQuickItem::Flags QQuickItem::flags() const
4400 Q_D(const QQuickItem);
4401 return (QQuickItem::Flags)d->flags;
4404 void QQuickItem::setFlag(Flag flag, bool enabled)
4408 setFlags((Flags)(d->flags | (quint32)flag));
4410 setFlags((Flags)(d->flags & ~(quint32)flag));
4413 void QQuickItem::setFlags(Flags flags)
4417 if ((flags & ItemIsFocusScope) != (d->flags & ItemIsFocusScope)) {
4418 if (flags & ItemIsFocusScope && !d->childItems.isEmpty() && d->canvas) {
4419 qWarning("QQuickItem: Cannot set FocusScope once item has children and is in a canvas.");
4420 flags &= ~ItemIsFocusScope;
4421 } else if (d->flags & ItemIsFocusScope) {
4422 qWarning("QQuickItem: Cannot unset FocusScope flag.");
4423 flags |= ItemIsFocusScope;
4427 if ((flags & ItemClipsChildrenToShape ) != (d->flags & ItemClipsChildrenToShape))
4428 d->dirty(QQuickItemPrivate::Clip);
4433 qreal QQuickItem::x() const
4435 Q_D(const QQuickItem);
4439 qreal QQuickItem::y() const
4441 Q_D(const QQuickItem);
4445 QPointF QQuickItem::pos() const
4447 Q_D(const QQuickItem);
4448 return QPointF(d->x, d->y);
4451 void QQuickItem::setX(qreal v)
4460 d->dirty(QQuickItemPrivate::Position);
4462 geometryChanged(QRectF(x(), y(), width(), height()),
4463 QRectF(oldx, y(), width(), height()));
4466 void QQuickItem::setY(qreal v)
4475 d->dirty(QQuickItemPrivate::Position);
4477 geometryChanged(QRectF(x(), y(), width(), height()),
4478 QRectF(x(), oldy, width(), height()));
4481 void QQuickItem::setPos(const QPointF &pos)
4484 if (QPointF(d->x, d->y) == pos)
4493 d->dirty(QQuickItemPrivate::Position);
4495 geometryChanged(QRectF(x(), y(), width(), height()),
4496 QRectF(oldx, oldy, width(), height()));
4499 qreal QQuickItem::width() const
4501 Q_D(const QQuickItem);
4505 void QQuickItem::setWidth(qreal w)
4511 d->widthValid = true;
4515 qreal oldWidth = d->width;
4518 d->dirty(QQuickItemPrivate::Size);
4520 geometryChanged(QRectF(x(), y(), width(), height()),
4521 QRectF(x(), y(), oldWidth, height()));
4524 void QQuickItem::resetWidth()
4527 d->widthValid = false;
4528 setImplicitWidth(implicitWidth());
4531 void QQuickItemPrivate::implicitWidthChanged()
4534 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4535 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4536 if (change.types & QQuickItemPrivate::ImplicitWidth) {
4537 change.listener->itemImplicitWidthChanged(q);
4540 emit q->implicitWidthChanged();
4543 qreal QQuickItemPrivate::getImplicitWidth() const
4545 return implicitWidth;
4548 Returns the width of the item that is implied by other properties that determine the content.
4550 qreal QQuickItem::implicitWidth() const
4552 Q_D(const QQuickItem);
4553 return d->getImplicitWidth();
4557 \qmlproperty real QtQuick2::Item::implicitWidth
4558 \qmlproperty real QtQuick2::Item::implicitHeight
4560 Defines the natural width or height of the Item if no \l width or \l height is specified.
4562 The default implicit size for most items is 0x0, however some elements have an inherent
4563 implicit size which cannot be overridden, e.g. Image, Text.
4565 Setting the implicit size is useful for defining components that have a preferred size
4566 based on their content, for example:
4573 property alias icon: image.source
4574 property alias label: text.text
4575 implicitWidth: text.implicitWidth + image.implicitWidth
4576 implicitHeight: Math.max(text.implicitHeight, image.implicitHeight)
4581 anchors.left: image.right; anchors.right: parent.right
4582 anchors.verticalCenter: parent.verticalCenter
4587 \b Note: using implicitWidth of Text or TextEdit and setting the width explicitly
4588 incurs a performance penalty as the text must be laid out twice.
4592 Sets the implied width of the item to \a w.
4593 This is the width implied by other properties that determine the content.
4595 void QQuickItem::setImplicitWidth(qreal w)
4598 bool changed = w != d->implicitWidth;
4599 d->implicitWidth = w;
4600 if (d->width == w || widthValid()) {
4602 d->implicitWidthChanged();
4606 qreal oldWidth = d->width;
4609 d->dirty(QQuickItemPrivate::Size);
4611 geometryChanged(QRectF(x(), y(), width(), height()),
4612 QRectF(x(), y(), oldWidth, height()));
4615 d->implicitWidthChanged();
4619 Returns whether the width property has been set explicitly.
4621 bool QQuickItem::widthValid() const
4623 Q_D(const QQuickItem);
4624 return d->widthValid;
4627 qreal QQuickItem::height() const
4629 Q_D(const QQuickItem);
4633 void QQuickItem::setHeight(qreal h)
4639 d->heightValid = true;
4643 qreal oldHeight = d->height;
4646 d->dirty(QQuickItemPrivate::Size);
4648 geometryChanged(QRectF(x(), y(), width(), height()),
4649 QRectF(x(), y(), width(), oldHeight));
4652 void QQuickItem::resetHeight()
4655 d->heightValid = false;
4656 setImplicitHeight(implicitHeight());
4659 void QQuickItemPrivate::implicitHeightChanged()
4662 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4663 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4664 if (change.types & QQuickItemPrivate::ImplicitHeight) {
4665 change.listener->itemImplicitHeightChanged(q);
4668 emit q->implicitHeightChanged();
4671 qreal QQuickItemPrivate::getImplicitHeight() const
4673 return implicitHeight;
4677 Returns the height of the item that is implied by other properties that determine the content.
4679 qreal QQuickItem::implicitHeight() const
4681 Q_D(const QQuickItem);
4682 return d->getImplicitHeight();
4687 Sets the implied height of the item to \a h.
4688 This is the height implied by other properties that determine the content.
4690 void QQuickItem::setImplicitHeight(qreal h)
4693 bool changed = h != d->implicitHeight;
4694 d->implicitHeight = h;
4695 if (d->height == h || heightValid()) {
4697 d->implicitHeightChanged();
4701 qreal oldHeight = d->height;
4704 d->dirty(QQuickItemPrivate::Size);
4706 geometryChanged(QRectF(x(), y(), width(), height()),
4707 QRectF(x(), y(), width(), oldHeight));
4710 d->implicitHeightChanged();
4713 void QQuickItem::setImplicitSize(qreal w, qreal h)
4716 bool wChanged = w != d->implicitWidth;
4717 bool hChanged = h != d->implicitHeight;
4719 d->implicitWidth = w;
4720 d->implicitHeight = h;
4724 if (d->width == w || widthValid()) {
4726 d->implicitWidthChanged();
4729 if (d->height == h || heightValid()) {
4731 d->implicitHeightChanged();
4737 qreal oldWidth = d->width;
4738 qreal oldHeight = d->height;
4744 d->dirty(QQuickItemPrivate::Size);
4746 geometryChanged(QRectF(x(), y(), width(), height()),
4747 QRectF(x(), y(), oldWidth, oldHeight));
4749 if (!wDone && wChanged)
4750 d->implicitWidthChanged();
4751 if (!hDone && hChanged)
4752 d->implicitHeightChanged();
4756 Returns whether the height property has been set explicitly.
4758 bool QQuickItem::heightValid() const
4760 Q_D(const QQuickItem);
4761 return d->heightValid;
4764 void QQuickItem::setSize(const QSizeF &size)
4767 d->heightValid = true;
4768 d->widthValid = true;
4770 if (QSizeF(d->width, d->height) == size)
4773 qreal oldHeight = d->height;
4774 qreal oldWidth = d->width;
4775 d->height = size.height();
4776 d->width = size.width();
4778 d->dirty(QQuickItemPrivate::Size);
4780 geometryChanged(QRectF(x(), y(), width(), height()),
4781 QRectF(x(), y(), oldWidth, oldHeight));
4784 bool QQuickItem::hasActiveFocus() const
4786 Q_D(const QQuickItem);
4787 return d->activeFocus;
4790 bool QQuickItem::hasFocus() const
4792 Q_D(const QQuickItem);
4796 void QQuickItem::setFocus(bool focus)
4799 if (d->focus == focus)
4802 if (d->canvas || d->parentItem) {
4803 // Need to find our nearest focus scope
4804 QQuickItem *scope = parentItem();
4805 while (scope && !scope->isFocusScope() && scope->parentItem())
4806 scope = scope->parentItem();
4809 QQuickCanvasPrivate::get(d->canvas)->setFocusInScope(scope, this);
4811 QQuickCanvasPrivate::get(d->canvas)->clearFocusInScope(scope, this);
4813 // do the focus changes from setFocusInScope/clearFocusInScope that are
4814 // unrelated to a canvas
4815 QVarLengthArray<QQuickItem *, 20> changed;
4816 QQuickItem *oldSubFocusItem = QQuickItemPrivate::get(scope)->subFocusItem;
4817 if (oldSubFocusItem) {
4818 QQuickItemPrivate::get(oldSubFocusItem)->updateSubFocusItem(scope, false);
4819 QQuickItemPrivate::get(oldSubFocusItem)->focus = false;
4820 changed << oldSubFocusItem;
4822 d->updateSubFocusItem(scope, focus);
4826 emit focusChanged(focus);
4828 QQuickCanvasPrivate::notifyFocusChangesRecur(changed.data(), changed.count() - 1);
4832 emit focusChanged(focus);
4836 bool QQuickItem::isFocusScope() const
4838 return flags() & ItemIsFocusScope;
4841 QQuickItem *QQuickItem::scopedFocusItem() const
4843 Q_D(const QQuickItem);
4844 if (!isFocusScope())
4847 return d->subFocusItem;
4851 Qt::MouseButtons QQuickItem::acceptedMouseButtons() const
4853 Q_D(const QQuickItem);
4854 return d->acceptedMouseButtons();
4857 void QQuickItem::setAcceptedMouseButtons(Qt::MouseButtons buttons)
4860 if (buttons & Qt::LeftButton)
4863 d->extra.clearFlag();
4865 buttons &= ~Qt::LeftButton;
4866 if (buttons || d->extra.isAllocated())
4867 d->extra.value().acceptedMouseButtons = buttons;
4870 bool QQuickItem::filtersChildMouseEvents() const
4872 Q_D(const QQuickItem);
4873 return d->filtersChildMouseEvents;
4876 void QQuickItem::setFiltersChildMouseEvents(bool filter)
4879 d->filtersChildMouseEvents = filter;
4882 bool QQuickItem::isUnderMouse() const
4884 Q_D(const QQuickItem);
4888 QPointF cursorPos = QGuiApplicationPrivate::lastCursorPosition;
4889 return contains(mapFromScene(cursorPos)); // ### refactor: d->canvas->mapFromGlobal(cursorPos))))
4892 bool QQuickItem::acceptHoverEvents() const
4894 Q_D(const QQuickItem);
4895 return d->hoverEnabled;
4898 void QQuickItem::setAcceptHoverEvents(bool enabled)
4901 d->hoverEnabled = enabled;
4904 void QQuickItem::grabMouse()
4909 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
4910 if (canvasPriv->mouseGrabberItem == this)
4913 QQuickItem *oldGrabber = canvasPriv->mouseGrabberItem;
4914 canvasPriv->mouseGrabberItem = this;
4916 QEvent ev(QEvent::UngrabMouse);
4917 d->canvas->sendEvent(oldGrabber, &ev);
4921 void QQuickItem::ungrabMouse()
4926 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
4927 if (canvasPriv->mouseGrabberItem != this) {
4928 qWarning("QQuickItem::ungrabMouse(): Item is not the mouse grabber.");
4932 canvasPriv->mouseGrabberItem = 0;
4934 QEvent ev(QEvent::UngrabMouse);
4935 d->canvas->sendEvent(this, &ev);
4938 bool QQuickItem::keepMouseGrab() const
4940 Q_D(const QQuickItem);
4941 return d->keepMouse;
4945 The flag indicating whether the mouse should remain
4946 with this item is set to \a keep.
4948 This is useful for items that wish to grab and keep mouse
4949 interaction following a predefined gesture. For example,
4950 an item that is interested in horizontal mouse movement
4951 may set keepMouseGrab to true once a threshold has been
4952 exceeded. Once keepMouseGrab has been set to true, filtering
4953 items will not react to mouse events.
4955 If the item does not indicate that it wishes to retain mouse grab,
4956 a filtering item may steal the grab. For example, Flickable may attempt
4957 to steal a mouse grab if it detects that the user has begun to
4962 void QQuickItem::setKeepMouseGrab(bool keep)
4965 d->keepMouse = keep;
4969 Grabs the touch points specified by \a ids.
4971 These touch points will be owned by the item until
4972 they are released. Alternatively, the grab can be stolen
4973 by a filtering item like Flickable. Use setKeepTouchGrab()
4974 to prevent the grab from being stolen.
4976 \sa ungrabTouchPoints(), setKeepTouchGrab()
4978 void QQuickItem::grabTouchPoints(const QList<int> &ids)
4983 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
4985 QSet<QQuickItem*> ungrab;
4986 for (int i = 0; i < ids.count(); ++i) {
4987 QQuickItem *oldGrabber = canvasPriv->itemForTouchPointId.value(ids.at(i));
4988 if (oldGrabber == this)
4991 canvasPriv->itemForTouchPointId[ids.at(i)] = this;
4993 ungrab.insert(oldGrabber);
4995 foreach (QQuickItem *oldGrabber, ungrab)
4996 oldGrabber->touchUngrabEvent();
5000 Ungrabs the touch points owned by this item.
5002 \sa grabTouchPoints()
5004 void QQuickItem::ungrabTouchPoints()
5009 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
5011 QMutableHashIterator<int, QQuickItem*> i(canvasPriv->itemForTouchPointId);
5012 while (i.hasNext()) {
5014 if (i.value() == this)
5021 Returns a value indicating whether the touch points grabbed by this item
5022 should remain with this item exclusively.
5024 \sa setKeepTouchGrab(), keepMouseGrab()
5026 bool QQuickItem::keepTouchGrab() const
5028 Q_D(const QQuickItem);
5029 return d->keepTouch;
5033 The flag indicating whether the touch points grabbed
5034 by this item should remain with this item is set to \a keep.
5036 This is useful for items that wish to grab and keep specific touch
5037 points following a predefined gesture. For example,
5038 an item that is interested in horizontal touch point movement
5039 may set setKeepTouchGrab to true once a threshold has been
5040 exceeded. Once setKeepTouchGrab has been set to true, filtering
5041 items will not react to the relevant touch points.
5043 If the item does not indicate that it wishes to retain touch point grab,
5044 a filtering item may steal the grab. For example, Flickable may attempt
5045 to steal a touch point grab if it detects that the user has begun to
5048 \sa keepTouchGrab(), setKeepMouseGrab()
5050 void QQuickItem::setKeepTouchGrab(bool keep)
5053 d->keepTouch = keep;
5057 Returns true if this item contains \a point, which is in local coordinates;
5058 returns false otherwise.
5060 This function can be overwritten in order to handle point collisions in items
5061 with custom shapes. The default implementation checks if the point is inside
5062 the item's bounding rect.
5064 Note that it's normally used to check if the item is under the mouse cursor,
5065 and for that reason, the implementation of this function should be as light-weight
5068 bool QQuickItem::contains(const QPointF &point) const
5070 Q_D(const QQuickItem);
5071 return QRectF(0, 0, d->width, d->height).contains(point);
5075 \qmlmethod object QtQuick2::Item::mapFromItem(Item item, real x, real y)
5077 Maps the point (\a x, \a y), which is in \a item's coordinate system, to
5078 this item's coordinate system, and returns an object with \c x and \c y
5079 properties matching the mapped coordinate.
5081 If \a item is a \c null value, this maps the point from the coordinate
5082 system of the root QML view.
5085 \qmlmethod object QtQuick2::Item::mapToItem(Item item, real x, real y)
5087 Maps the point (\a x, \a y), which is in this item's coordinate system, to
5088 \a item's coordinate system, and returns an object with \c x and \c y
5089 properties matching the mapped coordinate.
5091 If \a item is a \c null value, this maps \a x and \a y to the coordinate
5092 system of the root QML view.
5094 QPointF QQuickItem::mapToItem(const QQuickItem *item, const QPointF &point) const
5096 QPointF p = mapToScene(point);
5098 p = item->mapFromScene(p);
5102 QPointF QQuickItem::mapToScene(const QPointF &point) const
5104 Q_D(const QQuickItem);
5105 return d->itemToCanvasTransform().map(point);
5108 QRectF QQuickItem::mapRectToItem(const QQuickItem *item, const QRectF &rect) const
5110 Q_D(const QQuickItem);
5111 QTransform t = d->itemToCanvasTransform();
5113 t *= QQuickItemPrivate::get(item)->canvasToItemTransform();
5114 return t.mapRect(rect);
5117 QRectF QQuickItem::mapRectToScene(const QRectF &rect) const
5119 Q_D(const QQuickItem);
5120 return d->itemToCanvasTransform().mapRect(rect);
5123 QPointF QQuickItem::mapFromItem(const QQuickItem *item, const QPointF &point) const
5125 QPointF p = item?item->mapToScene(point):point;
5126 return mapFromScene(p);
5129 QPointF QQuickItem::mapFromScene(const QPointF &point) const
5131 Q_D(const QQuickItem);
5132 return d->canvasToItemTransform().map(point);
5135 QRectF QQuickItem::mapRectFromItem(const QQuickItem *item, const QRectF &rect) const
5137 Q_D(const QQuickItem);
5138 QTransform t = item?QQuickItemPrivate::get(item)->itemToCanvasTransform():QTransform();
5139 t *= d->canvasToItemTransform();
5140 return t.mapRect(rect);
5143 QRectF QQuickItem::mapRectFromScene(const QRectF &rect) const
5145 Q_D(const QQuickItem);
5146 return d->canvasToItemTransform().mapRect(rect);
5151 \qmlmethod QtQuick2::Item::forceActiveFocus()
5153 Forces active focus on the item.
5155 This method sets focus on the item and makes sure that all the focus scopes
5156 higher in the object hierarchy are also given the focus.
5160 Forces active focus on the item.
5162 This method sets focus on the item and makes sure that all the focus scopes
5163 higher in the object hierarchy are also given the focus.
5167 \qmlmethod QtQuick2::Item::childAt(real x, real y)
5169 Returns the visible child item at point (\a x, \a y), which is in this
5170 item's coordinate system, or \c null if there is no such item.
5174 Returns the visible child item at point (\a x, \a y), which is in this
5175 item's coordinate system, or 0 if there is no such item.
5179 \qmlproperty list<State> QtQuick2::Item::states
5180 This property holds a list of states defined by the item.
5196 \sa {qmlstate}{States}
5199 \qmlproperty list<Transition> QtQuick2::Item::transitions
5200 This property holds a list of transitions defined by the item.
5216 \sa {QML Animation and Transitions}{Transitions}
5219 \qmlproperty list<Filter> QtQuick2::Item::filter
5220 This property holds a list of graphical filters to be applied to the item.
5222 \l {Filter}{Filters} include things like \l {Blur}{blurring}
5223 the item, or giving it a \l Reflection. Some
5224 filters may not be available on all canvases; if a filter is not
5225 available on a certain canvas, it will simply not be applied for
5226 that canvas (but the QML will still be considered valid).
5244 \qmlproperty bool QtQuick2::Item::clip
5245 This property holds whether clipping is enabled. The default clip value is \c false.
5247 If clipping is enabled, an item will clip its own painting, as well
5248 as the painting of its children, to its bounding rectangle.
5250 Non-rectangular clipping regions are not supported for performance reasons.
5254 \property QQuickItem::clip
5255 This property holds whether clipping is enabled. The default clip value is \c false.
5257 If clipping is enabled, an item will clip its own painting, as well
5258 as the painting of its children, to its bounding rectangle. If you set
5259 clipping during an item's paint operation, remember to re-set it to
5260 prevent clipping the rest of your scene.
5262 Non-rectangular clipping regions are not supported for performance reasons.
5266 \qmlproperty string QtQuick2::Item::state
5268 This property holds the name of the current state of the item.
5270 This property is often used in scripts to change between states. For
5275 if (button.state == 'On')
5276 button.state = 'Off';
5278 button.state = 'On';
5282 If the item is in its base state (i.e. no explicit state has been
5283 set), \c state will be a blank string. Likewise, you can return an
5284 item to its base state by setting its current state to \c ''.
5286 \sa {qmlstates}{States}
5290 \qmlproperty list<Transform> QtQuick2::Item::transform
5291 This property holds the list of transformations to apply.
5293 For more information see \l Transform.
5297 \enum QQuickItem::TransformOrigin
5299 Controls the point about which simple transforms like scale apply.
5301 \value TopLeft The top-left corner of the item.
5302 \value Top The center point of the top of the item.
5303 \value TopRight The top-right corner of the item.
5304 \value Left The left most point of the vertical middle.
5305 \value Center The center of the item.
5306 \value Right The right most point of the vertical middle.
5307 \value BottomLeft The bottom-left corner of the item.
5308 \value Bottom The center point of the bottom of the item.
5309 \value BottomRight The bottom-right corner of the item.
5314 \qmlproperty bool QtQuick2::Item::activeFocus
5316 This property indicates whether the item has active focus.
5318 An item with active focus will receive keyboard input,
5319 or is a FocusScope ancestor of the item that will receive keyboard input.
5321 Usually, activeFocus is gained by setting focus on an item and its enclosing
5322 FocusScopes. In the following example \c input will have activeFocus.
5335 \sa focus, {qmlfocus}{Keyboard Focus}
5339 \qmlproperty bool QtQuick2::Item::focus
5340 This property indicates whether the item has focus within the enclosing focus scope. If true, this item
5341 will gain active focus when the enclosing focus scope gains active focus.
5342 In the following example, \c input will be given active focus when \c scope gains active focus.
5355 For the purposes of this property, the scene as a whole is assumed to act like a focus scope.
5356 On a practical level, that means the following QML will give active focus to \c input on startup.
5367 \sa activeFocus, {qmlfocus}{Keyboard Focus}
5372 \property QQuickItem::anchors
5377 \property QQuickItem::left
5382 \property QQuickItem::right
5387 \property QQuickItem::horizontalCenter
5392 \property QQuickItem::top
5397 \property QQuickItem::bottom
5402 \property QQuickItem::verticalCenter
5407 \property QQuickItem::focus
5412 \property QQuickItem::transform
5417 \property QQuickItem::transformOrigin
5422 \property QQuickItem::activeFocus
5427 \property QQuickItem::baseline
5432 \property QQuickItem::data
5437 \property QQuickItem::resources
5442 \property QQuickItem::state
5447 \property QQuickItem::states
5452 \property QQuickItem::transformOriginPoint
5457 \property QQuickItem::transitions
5461 bool QQuickItem::event(QEvent *ev)
5464 if (ev->type() == QEvent::PolishRequest) {
5466 d->polishScheduled = false;
5470 return QObject::event(ev);
5473 if (ev->type() == QEvent::InputMethodQuery) {
5474 QInputMethodQueryEvent *query = static_cast<QInputMethodQueryEvent *>(ev);
5475 Qt::InputMethodQueries queries = query->queries();
5476 for (uint i = 0; i < 32; ++i) {
5477 Qt::InputMethodQuery q = (Qt::InputMethodQuery)(int)(queries & (1<<i));
5479 QVariant v = inputMethodQuery(q);
5480 query->setValue(q, v);
5485 } else if (ev->type() == QEvent::InputMethod) {
5486 inputMethodEvent(static_cast<QInputMethodEvent *>(ev));
5489 return QObject::event(ev);
5492 #ifndef QT_NO_DEBUG_STREAM
5493 QDebug operator<<(QDebug debug, QQuickItem *item)
5496 debug << "QQuickItem(0)";
5500 debug << item->metaObject()->className() << "(this =" << ((void*)item)
5501 << ", name=" << item->objectName()
5502 << ", parent =" << ((void*)item->parentItem())
5503 << ", geometry =" << QRectF(item->pos(), QSizeF(item->width(), item->height()))
5504 << ", z =" << item->z() << ')';
5509 qint64 QQuickItemPrivate::consistentTime = -1;
5510 void QQuickItemPrivate::setConsistentTime(qint64 t)
5515 class QElapsedTimerConsistentTimeHack
5519 t1 = QQuickItemPrivate::consistentTime;
5523 return QQuickItemPrivate::consistentTime - t1;
5526 qint64 val = QQuickItemPrivate::consistentTime - t1;
5527 t1 = QQuickItemPrivate::consistentTime;
5537 void QQuickItemPrivate::start(QElapsedTimer &t)
5539 if (QQuickItemPrivate::consistentTime == -1)
5542 ((QElapsedTimerConsistentTimeHack*)&t)->start();
5545 qint64 QQuickItemPrivate::elapsed(QElapsedTimer &t)
5547 if (QQuickItemPrivate::consistentTime == -1)
5550 return ((QElapsedTimerConsistentTimeHack*)&t)->elapsed();
5553 qint64 QQuickItemPrivate::restart(QElapsedTimer &t)
5555 if (QQuickItemPrivate::consistentTime == -1)
5558 return ((QElapsedTimerConsistentTimeHack*)&t)->restart();
5562 \fn bool QQuickItem::isTextureProvider() const
5564 Returns true if this item is a texture provider. The default
5565 implementation returns false.
5567 This function can be called from any thread.
5570 bool QQuickItem::isTextureProvider() const
5572 Q_D(const QQuickItem);
5573 return d->extra.isAllocated() && d->extra->layer && d->extra->layer->effectSource() ?
5574 d->extra->layer->effectSource()->isTextureProvider() : false;
5578 \fn QSGTextureProvider *QQuickItem::textureProvider() const
5580 Returns the texture provider for an item. The default implementation
5583 This function may only be called on the rendering thread.
5586 QSGTextureProvider *QQuickItem::textureProvider() const
5588 Q_D(const QQuickItem);
5589 return d->extra.isAllocated() && d->extra->layer && d->extra->layer->effectSource() ?
5590 d->extra->layer->effectSource()->textureProvider() : 0;
5593 QQuickItemLayer *QQuickItemPrivate::layer() const
5595 if (!extra.isAllocated() || !extra->layer) {
5596 extra.value().layer = new QQuickItemLayer(const_cast<QQuickItem *>(q_func()));
5597 if (!componentComplete)
5598 extra->layer->classBegin();
5600 return extra->layer;
5603 QQuickItemLayer::QQuickItemLayer(QQuickItem *item)
5608 , m_componentComplete(true)
5609 , m_wrapMode(QQuickShaderEffectSource::ClampToEdge)
5610 , m_format(QQuickShaderEffectSource::RGBA)
5612 , m_effectComponent(0)
5618 QQuickItemLayer::~QQuickItemLayer()
5620 delete m_effectSource;
5627 \qmlproperty bool QtQuick2::Item::layer.enabled
5629 Holds wether the item is layered or not. Layering is disabled by default.
5631 A layered item is rendered into an offscreen surface and cached until
5632 it is changed. Enabling layering for complex QML item hierarchies can
5633 some times be an optimization.
5635 None of the other layer properties have any effect when the layer
5639 void QQuickItemLayer::setEnabled(bool e)
5644 if (m_componentComplete) {
5651 emit enabledChanged(e);
5654 void QQuickItemLayer::classBegin()
5656 Q_ASSERT(!m_effectSource);
5657 Q_ASSERT(!m_effect);
5658 m_componentComplete = false;
5661 void QQuickItemLayer::componentComplete()
5663 Q_ASSERT(!m_componentComplete);
5664 m_componentComplete = true;
5669 void QQuickItemLayer::activate()
5671 Q_ASSERT(!m_effectSource);
5672 m_effectSource = new QQuickShaderEffectSource();
5674 QQuickItem *parentItem = m_item->parentItem();
5676 m_effectSource->setParentItem(parentItem);
5677 m_effectSource->stackAfter(m_item);
5680 m_effectSource->setSourceItem(m_item);
5681 m_effectSource->setHideSource(true);
5682 m_effectSource->setSmooth(m_smooth);
5683 m_effectSource->setTextureSize(m_size);
5684 m_effectSource->setSourceRect(m_sourceRect);
5685 m_effectSource->setMipmap(m_mipmap);
5686 m_effectSource->setWrapMode(m_wrapMode);
5687 m_effectSource->setFormat(m_format);
5689 if (m_effectComponent)
5692 m_effectSource->setVisible(m_item->isVisible() && !m_effect);
5699 QQuickItemPrivate *id = QQuickItemPrivate::get(m_item);
5700 id->addItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Opacity | QQuickItemPrivate::Parent | QQuickItemPrivate::Visibility | QQuickItemPrivate::SiblingOrder);
5703 void QQuickItemLayer::deactivate()
5705 Q_ASSERT(m_effectSource);
5707 if (m_effectComponent)
5710 delete m_effectSource;
5713 QQuickItemPrivate *id = QQuickItemPrivate::get(m_item);
5714 id->removeItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Opacity | QQuickItemPrivate::Parent | QQuickItemPrivate::Visibility | QQuickItemPrivate::SiblingOrder);
5717 void QQuickItemLayer::activateEffect()
5719 Q_ASSERT(m_effectSource);
5720 Q_ASSERT(m_effectComponent);
5721 Q_ASSERT(!m_effect);
5723 QObject *created = m_effectComponent->beginCreate(m_effectComponent->creationContext());
5724 m_effect = qobject_cast<QQuickItem *>(created);
5726 qWarning("Item: layer.effect is not a QML Item.");
5727 m_effectComponent->completeCreate();
5731 QQuickItem *parentItem = m_item->parentItem();
5733 m_effect->setParentItem(parentItem);
5734 m_effect->stackAfter(m_effectSource);
5736 m_effect->setVisible(m_item->isVisible());
5737 m_effect->setProperty(m_name, qVariantFromValue<QObject *>(m_effectSource));
5738 m_effectComponent->completeCreate();
5741 void QQuickItemLayer::deactivateEffect()
5743 Q_ASSERT(m_effectSource);
5744 Q_ASSERT(m_effectComponent);
5752 \qmlproperty Component QtQuick2::Item::layer.effect
5754 Holds the effect that is applied to this layer.
5756 The effect is typically a \l ShaderEffect component, although any \l Item component can be
5757 assigned. The effect should have a source texture property with a name matching \l samplerName.
5762 void QQuickItemLayer::setEffect(QQmlComponent *component)
5764 if (component == m_effectComponent)
5767 bool updateNeeded = false;
5768 if (m_effectSource && m_effectComponent) {
5770 updateNeeded = true;
5773 m_effectComponent = component;
5775 if (m_effectSource && m_effectComponent) {
5777 updateNeeded = true;
5785 m_effectSource->setVisible(m_item->isVisible() && !m_effect);
5788 emit effectChanged(component);
5793 \qmlproperty bool QtQuick2::Item::layer.mipmap
5795 If this property is true, mipmaps are generated for the texture.
5797 \note Some OpenGL ES 2 implementations do not support mipmapping of
5798 non-power-of-two textures.
5801 void QQuickItemLayer::setMipmap(bool mipmap)
5803 if (mipmap == m_mipmap)
5808 m_effectSource->setMipmap(m_mipmap);
5810 emit mipmapChanged(mipmap);
5815 \qmlproperty enumeration QtQuick2::Item::layer.format
5817 This property defines the internal OpenGL format of the texture.
5818 Modifying this property makes most sense when the \a layer.effect is also
5819 specified. Depending on the OpenGL implementation, this property might
5820 allow you to save some texture memory.
5823 \li ShaderEffectSource.Alpha - GL_ALPHA
5824 \li ShaderEffectSource.RGB - GL_RGB
5825 \li ShaderEffectSource.RGBA - GL_RGBA
5828 \note Some OpenGL implementations do not support the GL_ALPHA format.
5831 void QQuickItemLayer::setFormat(QQuickShaderEffectSource::Format f)
5838 m_effectSource->setFormat(m_format);
5840 emit formatChanged(m_format);
5845 \qmlproperty enumeration QtQuick2::Item::layer.sourceRect
5847 This property defines which rectangular area of the \l sourceItem to
5848 render into the texture. The source rectangle can be larger than
5849 \l sourceItem itself. If the rectangle is null, which is the default,
5850 the whole \l sourceItem is rendered to texture.
5853 void QQuickItemLayer::setSourceRect(const QRectF &sourceRect)
5855 if (sourceRect == m_sourceRect)
5857 m_sourceRect = sourceRect;
5860 m_effectSource->setSourceRect(m_sourceRect);
5862 emit sourceRectChanged(sourceRect);
5868 \qmlproperty bool QtQuick2::Item::layer.smooth
5870 Holds whether the layer is smoothly transformed.
5873 void QQuickItemLayer::setSmooth(bool s)
5880 m_effectSource->setSmooth(m_smooth);
5882 emit smoothChanged(s);
5888 \qmlproperty size QtQuick2::Item::layer.textureSize
5890 This property holds the requested pixel size of the layers texture. If it is empty,
5891 which is the default, the size of the item is used.
5893 \note Some platforms have a limit on how small framebuffer objects can be,
5894 which means the actual texture size might be larger than the requested
5898 void QQuickItemLayer::setSize(const QSize &size)
5905 m_effectSource->setTextureSize(size);
5907 emit sizeChanged(size);
5913 \qmlproperty enumeration QtQuick2::Item::layer.wrapMode
5915 This property defines the OpenGL wrap modes associated with the texture.
5916 Modifying this property makes most sense when the \a layer.effect is
5920 \li ShaderEffectSource.ClampToEdge - GL_CLAMP_TO_EDGE both horizontally and vertically
5921 \li ShaderEffectSource.RepeatHorizontally - GL_REPEAT horizontally, GL_CLAMP_TO_EDGE vertically
5922 \li ShaderEffectSource.RepeatVertically - GL_CLAMP_TO_EDGE horizontally, GL_REPEAT vertically
5923 \li ShaderEffectSource.Repeat - GL_REPEAT both horizontally and vertically
5926 \note Some OpenGL ES 2 implementations do not support the GL_REPEAT
5927 wrap mode with non-power-of-two textures.
5930 void QQuickItemLayer::setWrapMode(QQuickShaderEffectSource::WrapMode mode)
5932 if (mode == m_wrapMode)
5937 m_effectSource->setWrapMode(m_wrapMode);
5939 emit wrapModeChanged(mode);
5943 \qmlproperty string QtQuick2::Item::layer.samplerName
5945 Holds the name of the effect's source texture property.
5947 samplerName needs to match the name of the effect's source texture property
5948 so that the Item can pass the layer's offscreen surface to the effect correctly.
5950 \sa effect, ShaderEffect
5953 void QQuickItemLayer::setName(const QByteArray &name) {
5957 m_effect->setProperty(m_name, QVariant());
5958 m_effect->setProperty(name, qVariantFromValue<QObject *>(m_effectSource));
5961 emit nameChanged(name);
5964 void QQuickItemLayer::itemOpacityChanged(QQuickItem *item)
5970 void QQuickItemLayer::itemGeometryChanged(QQuickItem *, const QRectF &, const QRectF &)
5975 void QQuickItemLayer::itemParentChanged(QQuickItem *item, QQuickItem *parent)
5978 Q_ASSERT(item == m_item);
5979 Q_ASSERT(parent != m_effectSource);
5980 Q_ASSERT(parent == 0 || parent != m_effect);
5982 m_effectSource->setParentItem(parent);
5984 m_effectSource->stackAfter(m_item);
5987 m_effect->setParentItem(parent);
5989 m_effect->stackAfter(m_effectSource);
5993 void QQuickItemLayer::itemSiblingOrderChanged(QQuickItem *)
5995 m_effectSource->stackAfter(m_item);
5997 m_effect->stackAfter(m_effectSource);
6000 void QQuickItemLayer::itemVisibilityChanged(QQuickItem *)
6002 QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
6004 l->setVisible(m_item->isVisible());
6007 void QQuickItemLayer::updateZ()
6009 if (!m_componentComplete || !m_enabled)
6011 QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
6013 l->setZ(m_item->z());
6016 void QQuickItemLayer::updateOpacity()
6018 QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
6020 l->setOpacity(m_item->opacity());
6023 void QQuickItemLayer::updateGeometry()
6025 QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
6027 QRectF bounds = m_item->clipRect();
6028 l->setWidth(bounds.width());
6029 l->setHeight(bounds.height());
6030 l->setX(bounds.x() + m_item->x());
6031 l->setY(bounds.y() + m_item->y());
6034 void QQuickItemLayer::updateMatrix()
6036 // Called directly from transformChanged(), so needs some extra
6038 if (!m_componentComplete || !m_enabled)
6040 QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
6042 QQuickItemPrivate *ld = QQuickItemPrivate::get(l);
6043 l->setScale(m_item->scale());
6044 l->setRotation(m_item->rotation());
6045 ld->transforms = QQuickItemPrivate::get(m_item)->transforms;
6046 if (ld->origin() != QQuickItemPrivate::get(m_item)->origin())
6047 ld->extra.value().origin = QQuickItemPrivate::get(m_item)->origin();
6048 ld->dirty(QQuickItemPrivate::Transform);
6051 QQuickItemPrivate::ExtraData::ExtraData()
6052 : z(0), scale(1), rotation(0), opacity(1),
6053 contents(0), screenAttached(0), layoutDirectionAttached(0),
6054 keyHandler(0), layer(0), effectRefCount(0), hideRefCount(0),
6055 opacityNode(0), clipNode(0), rootNode(0), beforePaintNode(0),
6056 acceptedMouseButtons(0), origin(QQuickItem::Center)
6062 #include <moc_qquickitem.cpp>