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 qtquick-visual-transforms
133 \brief For specifying 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 qtquick-visual-transforms
155 \brief 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 qtquick-visual-transforms
197 \brief 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 qtquick-visual-transforms
239 \brief 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 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 qtquick-input
507 \brief 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 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(qmlobject_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 QQuickKeysAttached::isConnected(const char *signalName)
912 Q_D(QQuickKeysAttached);
913 int signal_index = d->signalIndex(signalName);
914 return d->isSignalConnected(signal_index);
918 \qmlclass Keys QQuickKeysAttached
919 \inqmlmodule QtQuick 2
920 \ingroup qtquick-input
921 \brief Provides key handling to Items
923 All visual primitives support key handling via the Keys
924 attached property. Keys can be handled via the onPressed
925 and onReleased signal properties.
927 The signal properties have a \l KeyEvent parameter, named
928 \e event which contains details of the event. If a key is
929 handled \e event.accepted should be set to true to prevent the
930 event from propagating up the item hierarchy.
932 \section1 Example Usage
934 The following example shows how the general onPressed handler can
935 be used to test for a certain key; in this case, the left cursor
938 \snippet qml/keys/keys-pressed.qml key item
940 Some keys may alternatively be handled via specific signal properties,
941 for example \e onSelectPressed. These handlers automatically set
942 \e event.accepted to true.
944 \snippet qml/keys/keys-handler.qml key item
946 See \l{Qt::Key}{Qt.Key} for the list of keyboard codes.
948 \section1 Key Handling Priorities
950 The Keys attached property can be configured to handle key events
951 before or after the item it is attached to. This makes it possible
952 to intercept events in order to override an item's default behavior,
953 or act as a fallback for keys not handled by the item.
955 If \l priority is Keys.BeforeItem (default) the order of key event processing is:
958 \li Items specified in \c forwardTo
959 \li specific key handlers, e.g. onReturnPressed
960 \li onKeyPress, onKeyRelease handlers
961 \li Item specific key handling, e.g. TextInput key handling
965 If priority is Keys.AfterItem the order of key event processing is:
968 \li Item specific key handling, e.g. TextInput key handling
969 \li Items specified in \c forwardTo
970 \li specific key handlers, e.g. onReturnPressed
971 \li onKeyPress, onKeyRelease handlers
975 If the event is accepted during any of the above steps, key
978 \sa KeyEvent, {KeyNavigation}{KeyNavigation attached property}
982 \qmlproperty bool QtQuick2::Keys::enabled
984 This flags enables key handling if true (default); otherwise
985 no key handlers will be called.
989 \qmlproperty enumeration QtQuick2::Keys::priority
991 This property determines whether the keys are processed before
992 or after the attached item's own key handling.
995 \li Keys.BeforeItem (default) - process the key events before normal
996 item key processing. If the event is accepted it will not
997 be passed on to the item.
998 \li Keys.AfterItem - process the key events after normal item key
999 handling. If the item accepts the key event it will not be
1000 handled by the Keys attached property handler.
1005 \qmlproperty list<Object> QtQuick2::Keys::forwardTo
1007 This property provides a way to forward key presses, key releases, and keyboard input
1008 coming from input methods to other items. This can be useful when you want
1009 one item to handle some keys (e.g. the up and down arrow keys), and another item to
1010 handle other keys (e.g. the left and right arrow keys). Once an item that has been
1011 forwarded keys accepts the event it is no longer forwarded to items later in the
1014 This example forwards key events to two lists:
1025 Keys.forwardTo: [list1, list2]
1032 \qmlsignal QtQuick2::Keys::onPressed(KeyEvent event)
1034 This handler is called when a key has been pressed. The \a event
1035 parameter provides information about the event.
1039 \qmlsignal QtQuick2::Keys::onReleased(KeyEvent event)
1041 This handler is called when a key has been released. The \a event
1042 parameter provides information about the event.
1046 \qmlsignal QtQuick2::Keys::onDigit0Pressed(KeyEvent event)
1048 This handler is called when the digit '0' has been pressed. The \a event
1049 parameter provides information about the event.
1053 \qmlsignal QtQuick2::Keys::onDigit1Pressed(KeyEvent event)
1055 This handler is called when the digit '1' has been pressed. The \a event
1056 parameter provides information about the event.
1060 \qmlsignal QtQuick2::Keys::onDigit2Pressed(KeyEvent event)
1062 This handler is called when the digit '2' has been pressed. The \a event
1063 parameter provides information about the event.
1067 \qmlsignal QtQuick2::Keys::onDigit3Pressed(KeyEvent event)
1069 This handler is called when the digit '3' has been pressed. The \a event
1070 parameter provides information about the event.
1074 \qmlsignal QtQuick2::Keys::onDigit4Pressed(KeyEvent event)
1076 This handler is called when the digit '4' has been pressed. The \a event
1077 parameter provides information about the event.
1081 \qmlsignal QtQuick2::Keys::onDigit5Pressed(KeyEvent event)
1083 This handler is called when the digit '5' has been pressed. The \a event
1084 parameter provides information about the event.
1088 \qmlsignal QtQuick2::Keys::onDigit6Pressed(KeyEvent event)
1090 This handler is called when the digit '6' has been pressed. The \a event
1091 parameter provides information about the event.
1095 \qmlsignal QtQuick2::Keys::onDigit7Pressed(KeyEvent event)
1097 This handler is called when the digit '7' has been pressed. The \a event
1098 parameter provides information about the event.
1102 \qmlsignal QtQuick2::Keys::onDigit8Pressed(KeyEvent event)
1104 This handler is called when the digit '8' has been pressed. The \a event
1105 parameter provides information about the event.
1109 \qmlsignal QtQuick2::Keys::onDigit9Pressed(KeyEvent event)
1111 This handler is called when the digit '9' has been pressed. The \a event
1112 parameter provides information about the event.
1116 \qmlsignal QtQuick2::Keys::onLeftPressed(KeyEvent event)
1118 This handler is called when the Left arrow has been pressed. The \a event
1119 parameter provides information about the event.
1123 \qmlsignal QtQuick2::Keys::onRightPressed(KeyEvent event)
1125 This handler is called when the Right arrow has been pressed. The \a event
1126 parameter provides information about the event.
1130 \qmlsignal QtQuick2::Keys::onUpPressed(KeyEvent event)
1132 This handler is called when the Up arrow has been pressed. The \a event
1133 parameter provides information about the event.
1137 \qmlsignal QtQuick2::Keys::onDownPressed(KeyEvent event)
1139 This handler is called when the Down arrow has been pressed. The \a event
1140 parameter provides information about the event.
1144 \qmlsignal QtQuick2::Keys::onTabPressed(KeyEvent event)
1146 This handler is called when the Tab key has been pressed. The \a event
1147 parameter provides information about the event.
1151 \qmlsignal QtQuick2::Keys::onBacktabPressed(KeyEvent event)
1153 This handler is called when the Shift+Tab key combination (Backtab) has
1154 been pressed. The \a event parameter provides information about the event.
1158 \qmlsignal QtQuick2::Keys::onAsteriskPressed(KeyEvent event)
1160 This handler is called when the Asterisk '*' has been pressed. The \a event
1161 parameter provides information about the event.
1165 \qmlsignal QtQuick2::Keys::onEscapePressed(KeyEvent event)
1167 This handler is called when the Escape key has been pressed. The \a event
1168 parameter provides information about the event.
1172 \qmlsignal QtQuick2::Keys::onReturnPressed(KeyEvent event)
1174 This handler is called when the Return key has been pressed. The \a event
1175 parameter provides information about the event.
1179 \qmlsignal QtQuick2::Keys::onEnterPressed(KeyEvent event)
1181 This handler is called when the Enter key has been pressed. The \a event
1182 parameter provides information about the event.
1186 \qmlsignal QtQuick2::Keys::onDeletePressed(KeyEvent event)
1188 This handler is called when the Delete key has been pressed. The \a event
1189 parameter provides information about the event.
1193 \qmlsignal QtQuick2::Keys::onSpacePressed(KeyEvent event)
1195 This handler is called when the Space key has been pressed. The \a event
1196 parameter provides information about the event.
1200 \qmlsignal QtQuick2::Keys::onBackPressed(KeyEvent event)
1202 This handler is called when the Back key has been pressed. The \a event
1203 parameter provides information about the event.
1207 \qmlsignal QtQuick2::Keys::onCancelPressed(KeyEvent event)
1209 This handler is called when the Cancel key has been pressed. The \a event
1210 parameter provides information about the event.
1214 \qmlsignal QtQuick2::Keys::onSelectPressed(KeyEvent event)
1216 This handler is called when the Select key has been pressed. The \a event
1217 parameter provides information about the event.
1221 \qmlsignal QtQuick2::Keys::onYesPressed(KeyEvent event)
1223 This handler is called when the Yes key has been pressed. The \a event
1224 parameter provides information about the event.
1228 \qmlsignal QtQuick2::Keys::onNoPressed(KeyEvent event)
1230 This handler is called when the No key has been pressed. The \a event
1231 parameter provides information about the event.
1235 \qmlsignal QtQuick2::Keys::onContext1Pressed(KeyEvent event)
1237 This handler is called when the Context1 key has been pressed. The \a event
1238 parameter provides information about the event.
1242 \qmlsignal QtQuick2::Keys::onContext2Pressed(KeyEvent event)
1244 This handler is called when the Context2 key has been pressed. The \a event
1245 parameter provides information about the event.
1249 \qmlsignal QtQuick2::Keys::onContext3Pressed(KeyEvent event)
1251 This handler is called when the Context3 key has been pressed. The \a event
1252 parameter provides information about the event.
1256 \qmlsignal QtQuick2::Keys::onContext4Pressed(KeyEvent event)
1258 This handler is called when the Context4 key has been pressed. The \a event
1259 parameter provides information about the event.
1263 \qmlsignal QtQuick2::Keys::onCallPressed(KeyEvent event)
1265 This handler is called when the Call key has been pressed. The \a event
1266 parameter provides information about the event.
1270 \qmlsignal QtQuick2::Keys::onHangupPressed(KeyEvent event)
1272 This handler is called when the Hangup key has been pressed. The \a event
1273 parameter provides information about the event.
1277 \qmlsignal QtQuick2::Keys::onFlipPressed(KeyEvent event)
1279 This handler is called when the Flip key has been pressed. The \a event
1280 parameter provides information about the event.
1284 \qmlsignal QtQuick2::Keys::onMenuPressed(KeyEvent event)
1286 This handler is called when the Menu key has been pressed. The \a event
1287 parameter provides information about the event.
1291 \qmlsignal QtQuick2::Keys::onVolumeUpPressed(KeyEvent event)
1293 This handler is called when the VolumeUp key has been pressed. The \a event
1294 parameter provides information about the event.
1298 \qmlsignal QtQuick2::Keys::onVolumeDownPressed(KeyEvent event)
1300 This handler is called when the VolumeDown key has been pressed. The \a event
1301 parameter provides information about the event.
1304 QQuickKeysAttached::QQuickKeysAttached(QObject *parent)
1305 : QObject(*(new QQuickKeysAttachedPrivate), parent),
1306 QQuickItemKeyFilter(qmlobject_cast<QQuickItem*>(parent))
1308 Q_D(QQuickKeysAttached);
1309 m_processPost = false;
1310 d->item = qmlobject_cast<QQuickItem*>(parent);
1313 QQuickKeysAttached::~QQuickKeysAttached()
1317 QQuickKeysAttached::Priority QQuickKeysAttached::priority() const
1319 return m_processPost ? AfterItem : BeforeItem;
1322 void QQuickKeysAttached::setPriority(Priority order)
1324 bool processPost = order == AfterItem;
1325 if (processPost != m_processPost) {
1326 m_processPost = processPost;
1327 emit priorityChanged();
1331 void QQuickKeysAttached::componentComplete()
1333 Q_D(QQuickKeysAttached);
1335 for (int ii = 0; ii < d->targets.count(); ++ii) {
1336 QQuickItem *targetItem = d->targets.at(ii);
1337 if (targetItem && (targetItem->flags() & QQuickItem::ItemAcceptsInputMethod)) {
1338 d->item->setFlag(QQuickItem::ItemAcceptsInputMethod);
1345 void QQuickKeysAttached::keyPressed(QKeyEvent *event, bool post)
1347 Q_D(QQuickKeysAttached);
1348 if (post != m_processPost || !d->enabled || d->inPress) {
1350 QQuickItemKeyFilter::keyPressed(event, post);
1354 // first process forwards
1355 if (d->item && d->item->canvas()) {
1357 for (int ii = 0; ii < d->targets.count(); ++ii) {
1358 QQuickItem *i = d->targets.at(ii);
1359 if (i && i->isVisible()) {
1360 d->item->canvas()->sendEvent(i, event);
1361 if (event->isAccepted()) {
1370 QQuickKeyEvent ke(*event);
1371 QByteArray keySignal = keyToSignal(event->key());
1372 if (!keySignal.isEmpty()) {
1373 keySignal += "(QQuickKeyEvent*)";
1374 if (isConnected(keySignal)) {
1375 // If we specifically handle a key then default to accepted
1376 ke.setAccepted(true);
1377 int idx = QQuickKeysAttached::staticMetaObject.indexOfSignal(keySignal);
1378 metaObject()->method(idx).invoke(this, Qt::DirectConnection, Q_ARG(QQuickKeyEvent*, &ke));
1381 if (!ke.isAccepted())
1383 event->setAccepted(ke.isAccepted());
1385 if (!event->isAccepted()) QQuickItemKeyFilter::keyPressed(event, post);
1388 void QQuickKeysAttached::keyReleased(QKeyEvent *event, bool post)
1390 Q_D(QQuickKeysAttached);
1391 if (post != m_processPost || !d->enabled || d->inRelease) {
1393 QQuickItemKeyFilter::keyReleased(event, post);
1397 if (d->item && d->item->canvas()) {
1398 d->inRelease = true;
1399 for (int ii = 0; ii < d->targets.count(); ++ii) {
1400 QQuickItem *i = d->targets.at(ii);
1401 if (i && i->isVisible()) {
1402 d->item->canvas()->sendEvent(i, event);
1403 if (event->isAccepted()) {
1404 d->inRelease = false;
1409 d->inRelease = false;
1412 QQuickKeyEvent ke(*event);
1414 event->setAccepted(ke.isAccepted());
1416 if (!event->isAccepted()) QQuickItemKeyFilter::keyReleased(event, post);
1419 void QQuickKeysAttached::inputMethodEvent(QInputMethodEvent *event, bool post)
1421 Q_D(QQuickKeysAttached);
1422 if (post == m_processPost && d->item && !d->inIM && d->item->canvas()) {
1424 for (int ii = 0; ii < d->targets.count(); ++ii) {
1425 QQuickItem *i = d->targets.at(ii);
1426 if (i && i->isVisible() && (i->flags() & QQuickItem::ItemAcceptsInputMethod)) {
1427 d->item->canvas()->sendEvent(i, event);
1428 if (event->isAccepted()) {
1437 QQuickItemKeyFilter::inputMethodEvent(event, post);
1440 QVariant QQuickKeysAttached::inputMethodQuery(Qt::InputMethodQuery query) const
1442 Q_D(const QQuickKeysAttached);
1444 for (int ii = 0; ii < d->targets.count(); ++ii) {
1445 QQuickItem *i = d->targets.at(ii);
1446 if (i && i->isVisible() && (i->flags() & QQuickItem::ItemAcceptsInputMethod) && i == d->imeItem) {
1447 //### how robust is i == d->imeItem check?
1448 QVariant v = i->inputMethodQuery(query);
1449 if (v.userType() == QVariant::RectF)
1450 v = d->item->mapRectFromItem(i, v.toRectF()); //### cost?
1455 return QQuickItemKeyFilter::inputMethodQuery(query);
1458 QQuickKeysAttached *QQuickKeysAttached::qmlAttachedProperties(QObject *obj)
1460 return new QQuickKeysAttached(obj);
1464 \qmlclass LayoutMirroring QQuickLayoutMirroringAttached
1465 \inqmlmodule QtQuick 2
1466 \ingroup qtquick-positioners
1467 \ingroup qml-utility-elements
1468 \brief Property used to mirror layout behavior
1470 The LayoutMirroring attached property is used to horizontally mirror \l {anchor-layout}{Item anchors},
1471 \l{Using QML Positioner and Repeater Items}{positioner} elements (such as \l Row and \l Grid)
1472 and views (such as \l GridView and horizontal \l ListView). Mirroring is a visual change: left
1473 anchors become right anchors, and positioner elements like \l Grid and \l Row reverse the
1474 horizontal layout of child items.
1476 Mirroring is enabled for an item by setting the \l enabled property to true. By default, this
1477 only affects the item itself; setting the \l childrenInherit property to true propagates the mirroring
1478 behavior to all child elements as well. If the \c LayoutMirroring attached property has not been defined
1479 for an item, mirroring is not enabled.
1481 The following example shows mirroring in action. The \l Row below is specified as being anchored
1482 to the left of its parent. However, since mirroring has been enabled, the anchor is horizontally
1483 reversed and it is now anchored to the right. Also, since items in a \l Row are positioned
1484 from left to right by default, they are now positioned from right to left instead, as demonstrated
1485 by the numbering and opacity of the items:
1487 \snippet qml/layoutmirroring.qml 0
1489 \image layoutmirroring.png
1491 Layout mirroring is useful when it is necessary to support both left-to-right and right-to-left
1492 layout versions of an application to target different language areas. The \l childrenInherit
1493 property allows layout mirroring to be applied without manually setting layout configurations
1494 for every item in an application. Keep in mind, however, that mirroring does not affect any
1495 positioning that is defined by the \l Item \l {Item::}{x} coordinate value, so even with
1496 mirroring enabled, it will often be necessary to apply some layout fixes to support the
1497 desired layout direction. Also, it may be necessary to disable the mirroring of individual
1498 child items (by setting \l {enabled}{LayoutMirroring.enabled} to false for such items) if
1499 mirroring is not the desired behavior, or if the child item already implements mirroring in
1502 See \l {QML Right-to-left User Interfaces} for further details on using \c LayoutMirroring and
1503 other related features to implement right-to-left support for an application.
1507 \qmlproperty bool QtQuick2::LayoutMirroring::enabled
1509 This property holds whether the item's layout is mirrored horizontally. Setting this to true
1510 horizontally reverses \l {anchor-layout}{anchor} settings such that left anchors become right,
1511 and right anchors become left. For \l{Using QML Positioner and Repeater Items}{positioner} elements
1512 (such as \l Row and \l Grid) and view elements (such as \l {GridView}{GridView} and \l {ListView}{ListView})
1513 this also mirrors the horizontal layout direction of the item.
1515 The default value is false.
1519 \qmlproperty bool QtQuick2::LayoutMirroring::childrenInherit
1521 This property holds whether the \l {enabled}{LayoutMirroring.enabled} value for this item
1522 is inherited by its children.
1524 The default value is false.
1528 QQuickLayoutMirroringAttached::QQuickLayoutMirroringAttached(QObject *parent) : QObject(parent), itemPrivate(0)
1530 if (QQuickItem *item = qobject_cast<QQuickItem*>(parent)) {
1531 itemPrivate = QQuickItemPrivate::get(item);
1532 itemPrivate->extra.value().layoutDirectionAttached = this;
1534 qmlInfo(parent) << tr("LayoutDirection attached property only works with Items");
1537 QQuickLayoutMirroringAttached * QQuickLayoutMirroringAttached::qmlAttachedProperties(QObject *object)
1539 return new QQuickLayoutMirroringAttached(object);
1542 bool QQuickLayoutMirroringAttached::enabled() const
1544 return itemPrivate ? itemPrivate->effectiveLayoutMirror : false;
1547 void QQuickLayoutMirroringAttached::setEnabled(bool enabled)
1552 itemPrivate->isMirrorImplicit = false;
1553 if (enabled != itemPrivate->effectiveLayoutMirror) {
1554 itemPrivate->setLayoutMirror(enabled);
1555 if (itemPrivate->inheritMirrorFromItem)
1556 itemPrivate->resolveLayoutMirror();
1560 void QQuickLayoutMirroringAttached::resetEnabled()
1562 if (itemPrivate && !itemPrivate->isMirrorImplicit) {
1563 itemPrivate->isMirrorImplicit = true;
1564 itemPrivate->resolveLayoutMirror();
1568 bool QQuickLayoutMirroringAttached::childrenInherit() const
1570 return itemPrivate ? itemPrivate->inheritMirrorFromItem : false;
1573 void QQuickLayoutMirroringAttached::setChildrenInherit(bool childrenInherit) {
1574 if (itemPrivate && childrenInherit != itemPrivate->inheritMirrorFromItem) {
1575 itemPrivate->inheritMirrorFromItem = childrenInherit;
1576 itemPrivate->resolveLayoutMirror();
1577 childrenInheritChanged();
1581 void QQuickItemPrivate::resolveLayoutMirror()
1584 if (QQuickItem *parentItem = q->parentItem()) {
1585 QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(parentItem);
1586 setImplicitLayoutMirror(parentPrivate->inheritedLayoutMirror, parentPrivate->inheritMirrorFromParent);
1588 setImplicitLayoutMirror(isMirrorImplicit ? false : effectiveLayoutMirror, inheritMirrorFromItem);
1592 void QQuickItemPrivate::setImplicitLayoutMirror(bool mirror, bool inherit)
1594 inherit = inherit || inheritMirrorFromItem;
1595 if (!isMirrorImplicit && inheritMirrorFromItem)
1596 mirror = effectiveLayoutMirror;
1597 if (mirror == inheritedLayoutMirror && inherit == inheritMirrorFromParent)
1600 inheritMirrorFromParent = inherit;
1601 inheritedLayoutMirror = inheritMirrorFromParent ? mirror : false;
1603 if (isMirrorImplicit)
1604 setLayoutMirror(inherit ? inheritedLayoutMirror : false);
1605 for (int i = 0; i < childItems.count(); ++i) {
1606 if (QQuickItem *child = qmlobject_cast<QQuickItem *>(childItems.at(i))) {
1607 QQuickItemPrivate *childPrivate = QQuickItemPrivate::get(child);
1608 childPrivate->setImplicitLayoutMirror(inheritedLayoutMirror, inheritMirrorFromParent);
1613 void QQuickItemPrivate::setLayoutMirror(bool mirror)
1615 if (mirror != effectiveLayoutMirror) {
1616 effectiveLayoutMirror = mirror;
1618 QQuickAnchorsPrivate *anchor_d = QQuickAnchorsPrivate::get(_anchors);
1619 anchor_d->fillChanged();
1620 anchor_d->centerInChanged();
1621 anchor_d->updateHorizontalAnchors();
1624 if (extra.isAllocated() && extra->layoutDirectionAttached) {
1625 emit extra->layoutDirectionAttached->enabledChanged();
1630 void QQuickItemPrivate::setAccessibleFlagAndListener()
1633 QQuickItem *item = q;
1635 if (item->d_func()->isAccessible)
1636 break; // already set - grandparents should have the flag set as well.
1638 item->d_func()->isAccessible = true;
1639 item = item->d_func()->parentItem;
1643 void QQuickItemPrivate::updateSubFocusItem(QQuickItem *scope, bool focus)
1648 QQuickItemPrivate *scopePrivate = QQuickItemPrivate::get(scope);
1650 QQuickItem *oldSubFocusItem = scopePrivate->subFocusItem;
1651 // Correct focus chain in scope
1652 if (oldSubFocusItem) {
1653 QQuickItem *sfi = scopePrivate->subFocusItem->parentItem();
1654 while (sfi && sfi != scope) {
1655 QQuickItemPrivate::get(sfi)->subFocusItem = 0;
1656 sfi = sfi->parentItem();
1661 scopePrivate->subFocusItem = q;
1662 QQuickItem *sfi = scopePrivate->subFocusItem->parentItem();
1663 while (sfi && sfi != scope) {
1664 QQuickItemPrivate::get(sfi)->subFocusItem = q;
1665 sfi = sfi->parentItem();
1668 scopePrivate->subFocusItem = 0;
1675 \brief The QQuickItem class provides the most basic of all visual items in QML
1679 All visual items in Qt Quick inherit from QQuickItem. Although QQuickItem
1680 has no visual appearance, it defines all the properties that are
1681 common across visual items - such as the x and y position, the
1682 width and height, \l {anchor-layout}{anchoring} and key handling.
1684 You can subclass QQuickItem to provide your own custom visual item
1685 that inherits these features.
1687 \section1 Custom Items using Scene Graph
1689 All visual QML items are rendered using the scene graph, a
1690 low-level, high-performance rendering stack, closely tied to
1691 OpenGL. It is possible for subclasses of QQuickItem to add their
1692 own custom content into the scene graph by setting the
1693 QQuickItem::ItemHasContents flag and reimplementing the
1694 QQuickItem::updatePaintNode() function.
1696 \warning It is crucial that OpenGL operations and interaction with
1697 the scene graph happens exclusively on the rendering thread,
1698 primarily during the updatePaintNode() call. The best rule of
1699 thumb is to only use classes with the "QSG" prefix inside the
1700 QQuickItem::updatePaintNode() function.
1702 To read more about how the scene graph rendering works, see
1703 \l{Scene Graph and Rendering}
1705 \section1 Custom Items using QPainter
1707 The QQuickItem provides a subclass, QQuickPaintedItem, which
1708 allows the users to render content using QPainter.
1710 \warning Using QQuickPaintedItem uses an indirect 2D surface to
1711 render its content, either using software rasterization or using
1712 an OpenGL framebuffer object (FBO), so the rendering is a two-step
1713 operation. First rasterize the surface, then draw the
1714 surface. Using scene graph API directly is always significantly
1717 \sa QQuickCanvas, QQuickPaintedItem
1721 \qmlclass Item QQuickItem
1723 \inqmlmodule QtQuick 2
1724 \ingroup qtquick-visual
1725 \brief A basic visual QML type
1727 All visual items in Qt Quick inherit from Item. Although Item
1728 has no visual appearance, it defines all the properties that are
1729 common across visual items - such as the x and y position, the
1730 width and height, \l {anchor-layout}{anchoring} and key handling.
1732 Item is also useful for grouping items together.
1749 fillMode: Image.Tile
1756 \section1 Key Handling
1758 Key handling is available to all Item-based visual elements via the \l {Keys}{Keys}
1759 attached property. The \e Keys attached property provides basic handlers such
1760 as \l {Keys::onPressed}{onPressed} and \l {Keys::onReleased}{onReleased},
1761 as well as handlers for specific keys, such as
1762 \l {Keys::onCancelPressed}{onCancelPressed}. The example below
1763 assigns \l {qmlfocus}{focus} to the item and handles
1764 the Left key via the general \e onPressed handler and the Select key via the
1765 onSelectPressed handler:
1771 if (event.key == Qt.Key_Left) {
1772 console.log("move left");
1773 event.accepted = true;
1776 Keys.onSelectPressed: console.log("Selected");
1780 See the \l {Keys}{Keys} attached property for detailed documentation.
1782 \section1 Layout Mirroring
1784 Item layouts can be mirrored using the \l {LayoutMirroring}{LayoutMirroring} attached property.
1789 \fn void QQuickItem::childrenRectChanged(const QRectF &)
1794 \fn void QQuickItem::baselineOffsetChanged(qreal)
1799 \fn void QQuickItem::stateChanged(const QString &state)
1804 \fn void QQuickItem::parentChanged(QQuickItem *)
1809 \fn void QQuickItem::smoothChanged(bool)
1814 \fn void QQuickItem::clipChanged(bool)
1818 /*! \fn void QQuickItem::transformOriginChanged(TransformOrigin)
1823 \fn void QQuickItem::focusChanged(bool)
1828 \fn void QQuickItem::activeFocusChanged(bool)
1832 \fn QQuickItem::QQuickItem(QQuickItem *parent)
1834 Constructs a QQuickItem with the given \a parent.
1836 QQuickItem::QQuickItem(QQuickItem* parent)
1837 : QObject(*(new QQuickItemPrivate), parent)
1845 QQuickItem::QQuickItem(QQuickItemPrivate &dd, QQuickItem *parent)
1846 : QObject(dd, parent)
1853 static int qt_item_count = 0;
1855 static void qt_print_item_count()
1857 qDebug("Number of leaked items: %i", qt_item_count);
1863 Destroys the QQuickItem.
1865 QQuickItem::~QQuickItem()
1869 if (qt_item_count < 0)
1870 qDebug("Item destroyed after qt_print_item_count() was called.");
1875 if (d->canvasRefCount > 1)
1876 d->canvasRefCount = 1; // Make sure canvas is set to null in next call to derefCanvas().
1882 // XXX todo - optimize
1883 while (!d->childItems.isEmpty())
1884 d->childItems.first()->setParentItem(0);
1886 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
1887 QQuickAnchorsPrivate *anchor = d->changeListeners.at(ii).listener->anchorPrivate();
1889 anchor->clearItem(this);
1893 update item anchors that depended on us unless they are our child (and will also be destroyed),
1894 or our sibling, and our parent is also being destroyed.
1896 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
1897 QQuickAnchorsPrivate *anchor = d->changeListeners.at(ii).listener->anchorPrivate();
1898 if (anchor && anchor->item && anchor->item->parentItem() && anchor->item->parentItem() != this)
1902 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
1903 const QQuickItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
1904 if (change.types & QQuickItemPrivate::Destroyed)
1905 change.listener->itemDestroyed(this);
1908 d->changeListeners.clear();
1910 if (d->extra.isAllocated()) {
1911 delete d->extra->contents; d->extra->contents = 0;
1912 delete d->extra->layer; d->extra->layer = 0;
1915 delete d->_anchors; d->_anchors = 0;
1916 delete d->_stateGroup; d->_stateGroup = 0;
1920 \qmlproperty enumeration QtQuick2::Item::transformOrigin
1921 This property holds the origin point around which scale and rotation transform.
1923 Nine transform origins are available, as shown in the image below.
1925 \image declarative-transformorigin.png
1927 This example rotates an image around its bottom-right corner.
1930 source: "myimage.png"
1931 transformOrigin: Item.BottomRight
1936 The default transform origin is \c Item.Center.
1938 To set an arbitrary transform origin point use the \l Scale or \l Rotation
1943 \qmlproperty Item QtQuick2::Item::parent
1944 This property holds the parent of the item.
1948 \property QQuickItem::parent
1949 This property holds the parent of the item.
1951 void QQuickItem::setParentItem(QQuickItem *parentItem)
1954 if (parentItem == d->parentItem)
1958 QQuickItem *itemAncestor = parentItem->parentItem();
1959 while (itemAncestor != 0) {
1960 if (itemAncestor == this) {
1961 qWarning("QQuickItem::setParentItem: Parent is already part of this items subtree.");
1964 itemAncestor = itemAncestor->parentItem();
1968 d->removeFromDirtyList();
1970 QQuickItem *oldParentItem = d->parentItem;
1971 QQuickItem *scopeFocusedItem = 0;
1973 if (oldParentItem) {
1974 QQuickItemPrivate *op = QQuickItemPrivate::get(oldParentItem);
1976 QQuickItem *scopeItem = 0;
1979 scopeFocusedItem = this;
1980 else if (!isFocusScope() && d->subFocusItem)
1981 scopeFocusedItem = d->subFocusItem;
1983 if (scopeFocusedItem) {
1984 scopeItem = oldParentItem;
1985 while (!scopeItem->isFocusScope() && scopeItem->parentItem())
1986 scopeItem = scopeItem->parentItem();
1988 QQuickCanvasPrivate::get(d->canvas)->clearFocusInScope(scopeItem, scopeFocusedItem,
1989 QQuickCanvasPrivate::DontChangeFocusProperty);
1990 if (scopeFocusedItem != this)
1991 QQuickItemPrivate::get(scopeFocusedItem)->updateSubFocusItem(this, true);
1993 QQuickItemPrivate::get(scopeFocusedItem)->updateSubFocusItem(scopeItem, false);
1997 const bool wasVisible = isVisible();
1998 op->removeChild(this);
2000 emit oldParentItem->visibleChildrenChanged();
2002 } else if (d->canvas) {
2003 QQuickCanvasPrivate::get(d->canvas)->parentlessItems.remove(this);
2006 QQuickCanvas *oldParentCanvas = oldParentItem ? QQuickItemPrivate::get(oldParentItem)->canvas : 0;
2007 QQuickCanvas *parentCanvas = parentItem ? QQuickItemPrivate::get(parentItem)->canvas : 0;
2008 if (oldParentCanvas == parentCanvas) {
2009 // Avoid freeing and reallocating resources if the canvas stays the same.
2010 d->parentItem = parentItem;
2012 if (oldParentCanvas)
2014 d->parentItem = parentItem;
2016 d->refCanvas(parentCanvas);
2019 d->dirty(QQuickItemPrivate::ParentChanged);
2022 QQuickItemPrivate::get(d->parentItem)->addChild(this);
2024 QQuickCanvasPrivate::get(d->canvas)->parentlessItems.insert(this);
2026 d->setEffectiveVisibleRecur(d->calcEffectiveVisible());
2027 d->setEffectiveEnableRecur(0, d->calcEffectiveEnable());
2029 if (d->parentItem) {
2030 if (!scopeFocusedItem) {
2032 scopeFocusedItem = this;
2033 else if (!isFocusScope() && d->subFocusItem)
2034 scopeFocusedItem = d->subFocusItem;
2037 if (scopeFocusedItem) {
2038 // We need to test whether this item becomes scope focused
2039 QQuickItem *scopeItem = d->parentItem;
2040 while (!scopeItem->isFocusScope() && scopeItem->parentItem())
2041 scopeItem = scopeItem->parentItem();
2043 if (QQuickItemPrivate::get(scopeItem)->subFocusItem
2044 || (!scopeItem->isFocusScope() && scopeItem->hasFocus())) {
2045 if (scopeFocusedItem != this)
2046 QQuickItemPrivate::get(scopeFocusedItem)->updateSubFocusItem(this, false);
2047 QQuickItemPrivate::get(scopeFocusedItem)->focus = false;
2048 emit scopeFocusedItem->focusChanged(false);
2051 QQuickCanvasPrivate::get(d->canvas)->setFocusInScope(scopeItem, scopeFocusedItem,
2052 QQuickCanvasPrivate::DontChangeFocusProperty);
2054 QQuickItemPrivate::get(scopeFocusedItem)->updateSubFocusItem(scopeItem, true);
2060 d->resolveLayoutMirror();
2062 d->itemChange(ItemParentHasChanged, d->parentItem);
2064 d->parentNotifier.notify();
2065 if (d->isAccessible && d->parentItem) {
2066 d->parentItem->d_func()->setAccessibleFlagAndListener();
2069 emit parentChanged(d->parentItem);
2070 if (isVisible() && d->parentItem)
2071 emit d->parentItem->visibleChildrenChanged();
2074 void QQuickItem::stackBefore(const QQuickItem *sibling)
2077 if (!sibling || sibling == this || !d->parentItem || d->parentItem != QQuickItemPrivate::get(sibling)->parentItem) {
2078 qWarning("QQuickItem::stackBefore: Cannot stack before %p, which must be a sibling", sibling);
2082 QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(d->parentItem);
2084 int myIndex = parentPrivate->childItems.lastIndexOf(this);
2085 int siblingIndex = parentPrivate->childItems.lastIndexOf(const_cast<QQuickItem *>(sibling));
2087 Q_ASSERT(myIndex != -1 && siblingIndex != -1);
2089 if (myIndex == siblingIndex - 1)
2092 parentPrivate->childItems.move(myIndex, myIndex < siblingIndex ? siblingIndex - 1 : siblingIndex);
2094 parentPrivate->dirty(QQuickItemPrivate::ChildrenStackingChanged);
2095 parentPrivate->markSortedChildrenDirty(this);
2097 for (int ii = qMin(siblingIndex, myIndex); ii < parentPrivate->childItems.count(); ++ii)
2098 QQuickItemPrivate::get(parentPrivate->childItems.at(ii))->siblingOrderChanged();
2101 void QQuickItem::stackAfter(const QQuickItem *sibling)
2104 if (!sibling || sibling == this || !d->parentItem || d->parentItem != QQuickItemPrivate::get(sibling)->parentItem) {
2105 qWarning("QQuickItem::stackAfter: Cannot stack after %p, which must be a sibling", sibling);
2109 QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(d->parentItem);
2111 int myIndex = parentPrivate->childItems.lastIndexOf(this);
2112 int siblingIndex = parentPrivate->childItems.lastIndexOf(const_cast<QQuickItem *>(sibling));
2114 Q_ASSERT(myIndex != -1 && siblingIndex != -1);
2116 if (myIndex == siblingIndex + 1)
2119 parentPrivate->childItems.move(myIndex, myIndex > siblingIndex ? siblingIndex + 1 : siblingIndex);
2121 parentPrivate->dirty(QQuickItemPrivate::ChildrenStackingChanged);
2122 parentPrivate->markSortedChildrenDirty(this);
2124 for (int ii = qMin(myIndex, siblingIndex + 1); ii < parentPrivate->childItems.count(); ++ii)
2125 QQuickItemPrivate::get(parentPrivate->childItems.at(ii))->siblingOrderChanged();
2129 Returns the QQuickItem parent of this item.
2131 QQuickItem *QQuickItem::parentItem() const
2133 Q_D(const QQuickItem);
2134 return d->parentItem;
2137 QQuickCanvas *QQuickItem::canvas() const
2139 Q_D(const QQuickItem);
2143 static bool itemZOrder_sort(QQuickItem *lhs, QQuickItem *rhs)
2145 return lhs->z() < rhs->z();
2148 QList<QQuickItem *> QQuickItemPrivate::paintOrderChildItems() const
2150 if (sortedChildItems)
2151 return *sortedChildItems;
2153 // If none of the items have set Z then the paint order list is the same as
2154 // the childItems list. This is by far the most common case.
2156 for (int i = 0; i < childItems.count(); ++i) {
2157 if (QQuickItemPrivate::get(childItems.at(i))->z() != 0.) {
2163 sortedChildItems = new QList<QQuickItem*>(childItems);
2164 qStableSort(sortedChildItems->begin(), sortedChildItems->end(), itemZOrder_sort);
2165 return *sortedChildItems;
2168 sortedChildItems = const_cast<QList<QQuickItem*>*>(&childItems);
2173 void QQuickItemPrivate::addChild(QQuickItem *child)
2177 Q_ASSERT(!childItems.contains(child));
2179 childItems.append(child);
2181 markSortedChildrenDirty(child);
2182 dirty(QQuickItemPrivate::ChildrenChanged);
2184 itemChange(QQuickItem::ItemChildAddedChange, child);
2186 emit q->childrenChanged();
2189 void QQuickItemPrivate::removeChild(QQuickItem *child)
2194 Q_ASSERT(childItems.contains(child));
2195 childItems.removeOne(child);
2196 Q_ASSERT(!childItems.contains(child));
2198 markSortedChildrenDirty(child);
2199 dirty(QQuickItemPrivate::ChildrenChanged);
2201 itemChange(QQuickItem::ItemChildRemovedChange, child);
2203 emit q->childrenChanged();
2206 void QQuickItemPrivate::refCanvas(QQuickCanvas *c)
2208 // An item needs a canvas if it is referenced by another item which has a canvas.
2209 // Typically the item is referenced by a parent, but can also be referenced by a
2210 // ShaderEffect or ShaderEffectSource. 'canvasRefCount' counts how many items with
2211 // a canvas is referencing this item. When the reference count goes from zero to one,
2212 // or one to zero, the canvas of this item is updated and propagated to the children.
2213 // As long as the reference count stays above zero, the canvas is unchanged.
2214 // refCanvas() increments the reference count.
2215 // derefCanvas() decrements the reference count.
2218 Q_ASSERT((canvas != 0) == (canvasRefCount > 0));
2220 if (++canvasRefCount > 1) {
2222 qWarning("QQuickItem: Cannot use same item on different canvases at the same time.");
2223 return; // Canvas already set.
2226 Q_ASSERT(canvas == 0);
2229 if (polishScheduled)
2230 QQuickCanvasPrivate::get(canvas)->itemsToPolish.insert(q);
2233 QQuickCanvasPrivate::get(canvas)->parentlessItems.insert(q);
2235 for (int ii = 0; ii < childItems.count(); ++ii) {
2236 QQuickItem *child = childItems.at(ii);
2237 QQuickItemPrivate::get(child)->refCanvas(c);
2242 if (extra.isAllocated() && extra->screenAttached)
2243 extra->screenAttached->canvasChanged(c);
2244 itemChange(QQuickItem::ItemSceneChange, c);
2247 void QQuickItemPrivate::derefCanvas()
2250 Q_ASSERT((canvas != 0) == (canvasRefCount > 0));
2253 return; // This can happen when destroying recursive shader effect sources.
2255 if (--canvasRefCount > 0)
2256 return; // There are still other references, so don't set canvas to null yet.
2258 q->releaseResources();
2259 removeFromDirtyList();
2260 QQuickCanvasPrivate *c = QQuickCanvasPrivate::get(canvas);
2261 if (polishScheduled)
2262 c->itemsToPolish.remove(q);
2263 QMutableHashIterator<int, QQuickItem *> itemTouchMapIt(c->itemForTouchPointId);
2264 while (itemTouchMapIt.hasNext()) {
2265 if (itemTouchMapIt.next().value() == q)
2266 itemTouchMapIt.remove();
2268 if (c->mouseGrabberItem == q)
2269 c->mouseGrabberItem = 0;
2271 c->hoverItems.removeAll(q);
2272 if (itemNodeInstance)
2273 c->cleanup(itemNodeInstance);
2275 c->parentlessItems.remove(q);
2279 itemNodeInstance = 0;
2281 if (extra.isAllocated()) {
2282 extra->opacityNode = 0;
2283 extra->clipNode = 0;
2284 extra->rootNode = 0;
2285 extra->beforePaintNode = 0;
2291 for (int ii = 0; ii < childItems.count(); ++ii) {
2292 QQuickItem *child = childItems.at(ii);
2293 QQuickItemPrivate::get(child)->derefCanvas();
2298 if (extra.isAllocated() && extra->screenAttached)
2299 extra->screenAttached->canvasChanged(0);
2300 itemChange(QQuickItem::ItemSceneChange, (QQuickCanvas *)0);
2305 Returns a transform that maps points from canvas space into item space.
2307 QTransform QQuickItemPrivate::canvasToItemTransform() const
2309 // XXX todo - optimize
2310 return itemToCanvasTransform().inverted();
2314 Returns a transform that maps points from item space into canvas space.
2316 QTransform QQuickItemPrivate::itemToCanvasTransform() const
2319 QTransform rv = parentItem?QQuickItemPrivate::get(parentItem)->itemToCanvasTransform():QTransform();
2320 itemToParentTransform(rv);
2325 Motifies \a t with this items local transform relative to its parent.
2327 void QQuickItemPrivate::itemToParentTransform(QTransform &t) const
2332 if (!transforms.isEmpty()) {
2334 for (int ii = transforms.count() - 1; ii >= 0; --ii)
2335 transforms.at(ii)->applyTo(&m);
2336 t = m.toTransform();
2339 if (scale() != 1. || rotation() != 0.) {
2340 QPointF tp = computeTransformOrigin();
2341 t.translate(tp.x(), tp.y());
2342 t.scale(scale(), scale());
2343 t.rotate(rotation());
2344 t.translate(-tp.x(), -tp.y());
2350 \qmlproperty real QtQuick2::Item::childrenRect.x
2351 \qmlproperty real QtQuick2::Item::childrenRect.y
2352 \qmlproperty real QtQuick2::Item::childrenRect.width
2353 \qmlproperty real QtQuick2::Item::childrenRect.height
2355 The childrenRect properties allow an item access to the geometry of its
2356 children. This property is useful if you have an item that needs to be
2357 sized to fit its children.
2362 \qmlproperty list<Item> QtQuick2::Item::children
2363 \qmlproperty list<Object> QtQuick2::Item::resources
2365 The children property contains the list of visual children of this item.
2366 The resources property contains non-visual resources that you want to
2369 Generally you can rely on Item's default property to handle all this for
2370 you, but it can come in handy in some cases.
2389 Returns true if construction of the QML component is complete; otherwise
2392 It is often desirable to delay some processing until the component is
2395 \sa componentComplete()
2397 bool QQuickItem::isComponentComplete() const
2399 Q_D(const QQuickItem);
2400 return d->componentComplete;
2403 QQuickItemPrivate::QQuickItemPrivate()
2404 : _anchors(0), _stateGroup(0),
2405 flags(0), widthValid(false), heightValid(false), baselineOffsetValid(false), componentComplete(true),
2406 keepMouse(false), keepTouch(false), hoverEnabled(false), smooth(true), focus(false), activeFocus(false), notifiedFocus(false),
2407 notifiedActiveFocus(false), filtersChildMouseEvents(false), explicitVisible(true),
2408 effectiveVisible(true), explicitEnable(true), effectiveEnable(true), polishScheduled(false),
2409 inheritedLayoutMirror(false), effectiveLayoutMirror(false), isMirrorImplicit(true),
2410 inheritMirrorFromParent(false), inheritMirrorFromItem(false),
2411 isAccessible(false), culled(false),
2413 dirtyAttributes(0), nextDirtyItem(0), prevDirtyItem(0),
2415 canvas(0), canvasRefCount(0), parentItem(0), sortedChildItems(&childItems),
2419 x(0), y(0), width(0), height(0), implicitWidth(0), implicitHeight(0),
2423 itemNodeInstance(0), groupNode(0), paintNode(0)
2427 QQuickItemPrivate::~QQuickItemPrivate()
2429 if (sortedChildItems != &childItems)
2430 delete sortedChildItems;
2433 void QQuickItemPrivate::init(QQuickItem *parent)
2437 static bool atexit_registered = false;
2438 if (!atexit_registered) {
2439 atexit(qt_print_item_count);
2440 atexit_registered = true;
2446 registerAccessorProperties();
2448 baselineOffsetValid = false;
2451 q->setParentItem(parent);
2452 QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(parent);
2453 setImplicitLayoutMirror(parentPrivate->inheritedLayoutMirror, parentPrivate->inheritMirrorFromParent);
2457 void QQuickItemPrivate::data_append(QQmlListProperty<QObject> *prop, QObject *o)
2462 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2464 if (QQuickItem *item = qmlobject_cast<QQuickItem *>(o)) {
2465 item->setParentItem(that);
2467 if (o->inherits("QGraphicsItem"))
2468 qWarning("Cannot add a QtQuick 1.0 item (%s) into a QtQuick 2.0 scene!", o->metaObject()->className());
2470 // XXX todo - do we really want this behavior?
2476 \qmlproperty list<Object> QtQuick2::Item::data
2479 The data property allows you to freely mix visual children and resources
2480 in an item. If you assign a visual item to the data list it becomes
2481 a child and if you assign any other object type, it is added as a resource.
2505 data is a behind-the-scenes property: you should never need to explicitly
2509 int QQuickItemPrivate::data_count(QQmlListProperty<QObject> *prop)
2516 QObject *QQuickItemPrivate::data_at(QQmlListProperty<QObject> *prop, int i)
2524 void QQuickItemPrivate::data_clear(QQmlListProperty<QObject> *prop)
2530 QObject *QQuickItemPrivate::resources_at(QQmlListProperty<QObject> *prop, int index)
2532 const QObjectList children = prop->object->children();
2533 if (index < children.count())
2534 return children.at(index);
2539 void QQuickItemPrivate::resources_append(QQmlListProperty<QObject> *prop, QObject *o)
2541 // XXX todo - do we really want this behavior?
2542 o->setParent(prop->object);
2545 int QQuickItemPrivate::resources_count(QQmlListProperty<QObject> *prop)
2547 return prop->object->children().count();
2550 void QQuickItemPrivate::resources_clear(QQmlListProperty<QObject> *prop)
2552 // XXX todo - do we really want this behavior?
2553 const QObjectList children = prop->object->children();
2554 for (int index = 0; index < children.count(); index++)
2555 children.at(index)->setParent(0);
2558 QQuickItem *QQuickItemPrivate::children_at(QQmlListProperty<QQuickItem> *prop, int index)
2560 QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2561 if (index >= p->childItems.count() || index < 0)
2564 return p->childItems.at(index);
2567 void QQuickItemPrivate::children_append(QQmlListProperty<QQuickItem> *prop, QQuickItem *o)
2572 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2573 if (o->parentItem() == that)
2574 o->setParentItem(0);
2576 o->setParentItem(that);
2579 int QQuickItemPrivate::children_count(QQmlListProperty<QQuickItem> *prop)
2581 QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2582 return p->childItems.count();
2585 void QQuickItemPrivate::children_clear(QQmlListProperty<QQuickItem> *prop)
2587 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2588 QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2589 while (!p->childItems.isEmpty())
2590 p->childItems.at(0)->setParentItem(0);
2593 void QQuickItemPrivate::visibleChildren_append(QQmlListProperty<QQuickItem>*, QQuickItem *self)
2596 qmlInfo(self) << "QQuickItem: visibleChildren property is readonly and cannot be assigned to.";
2599 int QQuickItemPrivate::visibleChildren_count(QQmlListProperty<QQuickItem> *prop)
2601 QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2602 int visibleCount = 0;
2603 int c = p->childItems.count();
2605 if (p->childItems.at(c)->isVisible()) visibleCount++;
2608 return visibleCount;
2611 QQuickItem *QQuickItemPrivate::visibleChildren_at(QQmlListProperty<QQuickItem> *prop, int index)
2613 QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2614 const int childCount = p->childItems.count();
2615 if (index >= childCount || index < 0)
2618 int visibleCount = -1;
2619 for (int i = 0; i < childCount; i++) {
2620 if (p->childItems.at(i)->isVisible()) visibleCount++;
2621 if (visibleCount == index) return p->childItems.at(i);
2626 int QQuickItemPrivate::transform_count(QQmlListProperty<QQuickTransform> *prop)
2628 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2629 QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2631 return p->transforms.count();
2634 void QQuickTransform::appendToItem(QQuickItem *item)
2636 Q_D(QQuickTransform);
2640 QQuickItemPrivate *p = QQuickItemPrivate::get(item);
2642 if (!d->items.isEmpty() && !p->transforms.isEmpty() && p->transforms.contains(this)) {
2643 p->transforms.removeOne(this);
2644 p->transforms.append(this);
2646 p->transforms.append(this);
2647 d->items.append(item);
2650 p->dirty(QQuickItemPrivate::Transform);
2653 void QQuickTransform::prependToItem(QQuickItem *item)
2655 Q_D(QQuickTransform);
2659 QQuickItemPrivate *p = QQuickItemPrivate::get(item);
2661 if (!d->items.isEmpty() && !p->transforms.isEmpty() && p->transforms.contains(this)) {
2662 p->transforms.removeOne(this);
2663 p->transforms.prepend(this);
2665 p->transforms.prepend(this);
2666 d->items.append(item);
2669 p->dirty(QQuickItemPrivate::Transform);
2672 void QQuickItemPrivate::transform_append(QQmlListProperty<QQuickTransform> *prop, QQuickTransform *transform)
2677 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2678 transform->appendToItem(that);
2681 QQuickTransform *QQuickItemPrivate::transform_at(QQmlListProperty<QQuickTransform> *prop, int idx)
2683 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2684 QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2686 if (idx < 0 || idx >= p->transforms.count())
2689 return p->transforms.at(idx);
2692 void QQuickItemPrivate::transform_clear(QQmlListProperty<QQuickTransform> *prop)
2694 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2695 QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2697 for (int ii = 0; ii < p->transforms.count(); ++ii) {
2698 QQuickTransform *t = p->transforms.at(ii);
2699 QQuickTransformPrivate *tp = QQuickTransformPrivate::get(t);
2700 tp->items.removeOne(that);
2703 p->transforms.clear();
2705 p->dirty(QQuickItemPrivate::Transform);
2709 \property QQuickItem::childrenRect
2710 \brief Specifies the geometry of an item's children
2712 This property holds the (collective) position and size of the item's children.
2716 \qmlproperty real QtQuick2::Item::x
2717 \qmlproperty real QtQuick2::Item::y
2718 \qmlproperty real QtQuick2::Item::width
2719 \qmlproperty real QtQuick2::Item::height
2721 Defines the item's position and size relative to its parent.
2724 Item { x: 100; y: 100; width: 100; height: 100 }
2729 \qmlproperty real QtQuick2::Item::z
2731 Sets the stacking order of sibling items. By default the stacking order is 0.
2733 Items with a higher stacking value are drawn on top of siblings with a
2734 lower stacking order. Items with the same stacking value are drawn
2735 bottom up in the order they appear. Items with a negative stacking
2736 value are drawn under their parent's content.
2738 The following example shows the various effects of stacking order.
2742 \li \image declarative-item_stacking1.png
2743 \li Same \c z - later children above earlier children:
2748 width: 100; height: 100
2752 x: 50; y: 50; width: 100; height: 100
2757 \li \image declarative-item_stacking2.png
2758 \li Higher \c z on top:
2764 width: 100; height: 100
2768 x: 50; y: 50; width: 100; height: 100
2773 \li \image declarative-item_stacking3.png
2774 \li Same \c z - children above parents:
2779 width: 100; height: 100
2782 x: 50; y: 50; width: 100; height: 100
2788 \li \image declarative-item_stacking4.png
2789 \li Lower \c z below:
2794 width: 100; height: 100
2798 x: 50; y: 50; width: 100; height: 100
2807 \qmlproperty bool QtQuick2::Item::visible
2809 This property holds whether the item is visible. By default this is true.
2811 Setting this property directly affects the \c visible value of child
2812 items. When set to \c false, the \c visible values of all child items also
2813 become \c false. When set to \c true, the \c visible values of child items
2814 are returned to \c true, unless they have explicitly been set to \c false.
2816 (Because of this flow-on behavior, using the \c visible property may not
2817 have the intended effect if a property binding should only respond to
2818 explicit property changes. In such cases it may be better to use the
2819 \l opacity property instead.)
2821 If this property is set to \c false, the item will no longer receive mouse
2822 events, but will continue to receive key events and will retain the keyboard
2823 \l focus if it has been set. (In contrast, setting the \l enabled property
2824 to \c false stops both mouse and keyboard events, and also removes focus
2827 \note This property's value is only affected by changes to this property or
2828 the parent's \c visible property. It does not change, for example, if this
2829 item moves off-screen, or if the \l opacity changes to 0.
2833 \qmlproperty bool QtQuick2::Item::enabled
2835 This property holds whether the item receives mouse and keyboard events.
2836 By default this is true.
2838 Setting this property directly affects the \c enabled value of child
2839 items. When set to \c false, the \c enabled values of all child items also
2840 become \c false. When set to \c true, the \c enabled values of child items
2841 are returned to \c true, unless they have explicitly been set to \c false.
2843 Setting this property to \c false automatically causes \l activeFocus to be
2844 set to \c false, and this item will longer receive keyboard events.
2848 \qmlproperty AnchorLine QtQuick2::Item::anchors.top
2849 \qmlproperty AnchorLine QtQuick2::Item::anchors.bottom
2850 \qmlproperty AnchorLine QtQuick2::Item::anchors.left
2851 \qmlproperty AnchorLine QtQuick2::Item::anchors.right
2852 \qmlproperty AnchorLine QtQuick2::Item::anchors.horizontalCenter
2853 \qmlproperty AnchorLine QtQuick2::Item::anchors.verticalCenter
2854 \qmlproperty AnchorLine QtQuick2::Item::anchors.baseline
2856 \qmlproperty Item QtQuick2::Item::anchors.fill
2857 \qmlproperty Item QtQuick2::Item::anchors.centerIn
2859 \qmlproperty real QtQuick2::Item::anchors.margins
2860 \qmlproperty real QtQuick2::Item::anchors.topMargin
2861 \qmlproperty real QtQuick2::Item::anchors.bottomMargin
2862 \qmlproperty real QtQuick2::Item::anchors.leftMargin
2863 \qmlproperty real QtQuick2::Item::anchors.rightMargin
2864 \qmlproperty real QtQuick2::Item::anchors.horizontalCenterOffset
2865 \qmlproperty real QtQuick2::Item::anchors.verticalCenterOffset
2866 \qmlproperty real QtQuick2::Item::anchors.baselineOffset
2868 \qmlproperty bool QtQuick2::Item::anchors.alignWhenCentered
2870 Anchors provide a way to position an item by specifying its
2871 relationship with other items.
2873 Margins apply to top, bottom, left, right, and fill anchors.
2874 The \c anchors.margins property can be used to set all of the various margins at once, to the same value.
2875 It will not override a specific margin that has been previously set; to clear an explicit margin
2876 set it's value to \c undefined.
2877 Note that margins are anchor-specific and are not applied if an item does not
2880 Offsets apply for horizontal center, vertical center, and baseline anchors.
2884 \li \image declarative-anchors_example.png
2885 \li Text anchored to Image, horizontally centered and vertically below, with a margin.
2894 anchors.horizontalCenter: pic.horizontalCenter
2895 anchors.top: pic.bottom
2896 anchors.topMargin: 5
2902 \li \image declarative-anchors_example2.png
2904 Left of Text anchored to right of Image, with a margin. The y
2905 property of both defaults to 0.
2915 anchors.left: pic.right
2916 anchors.leftMargin: 5
2923 \c anchors.fill provides a convenient way for one item to have the
2924 same geometry as another item, and is equivalent to connecting all
2925 four directional anchors.
2927 To clear an anchor value, set it to \c undefined.
2929 \c anchors.alignWhenCentered (default true) forces centered anchors to align to a
2930 whole pixel, i.e. if the item being centered has an odd width/height the item
2931 will be positioned on a whole pixel rather than being placed on a half-pixel.
2932 This ensures the item is painted crisply. There are cases where this is not
2933 desirable, for example when rotating the item jitters may be apparent as the
2936 \note You can only anchor an item to siblings or a parent.
2938 For more information see \l {anchor-layout}{Anchor Layouts}.
2942 \property QQuickItem::baselineOffset
2943 \brief Speciifies the position of the item's baseline in local coordinates
2945 The baseline of a \l Text item is the imaginary line on which the text
2946 sits. Controls containing text usually set their baseline to the
2947 baseline of their text.
2949 For non-text items, a default baseline offset of 0 is used.
2951 QQuickAnchors *QQuickItemPrivate::anchors() const
2954 Q_Q(const QQuickItem);
2955 _anchors = new QQuickAnchors(const_cast<QQuickItem *>(q));
2956 if (!componentComplete)
2957 _anchors->classBegin();
2962 void QQuickItemPrivate::siblingOrderChanged()
2965 for (int ii = 0; ii < changeListeners.count(); ++ii) {
2966 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
2967 if (change.types & QQuickItemPrivate::SiblingOrder) {
2968 change.listener->itemSiblingOrderChanged(q);
2973 QQmlListProperty<QObject> QQuickItemPrivate::data()
2975 return QQmlListProperty<QObject>(q_func(), 0, QQuickItemPrivate::data_append,
2976 QQuickItemPrivate::data_count,
2977 QQuickItemPrivate::data_at,
2978 QQuickItemPrivate::data_clear);
2981 QRectF QQuickItem::childrenRect()
2984 if (!d->extra.isAllocated() || !d->extra->contents) {
2985 d->extra.value().contents = new QQuickContents(this);
2986 if (d->componentComplete)
2987 d->extra->contents->complete();
2989 return d->extra->contents->rectF();
2992 QList<QQuickItem *> QQuickItem::childItems() const
2994 Q_D(const QQuickItem);
2995 return d->childItems;
2998 bool QQuickItem::clip() const
3000 return flags() & ItemClipsChildrenToShape;
3003 void QQuickItem::setClip(bool c)
3008 setFlag(ItemClipsChildrenToShape, c);
3010 emit clipChanged(c);
3015 This function is called to handle this item's changes in
3016 geometry from \a oldGeometry to \a newGeometry. If the two
3017 geometries are the same, it doesn't do anything.
3019 Derived classes must call the base class method within their implementation.
3021 void QQuickItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
3026 QQuickAnchorsPrivate::get(d->_anchors)->updateMe();
3028 bool xChange = (newGeometry.x() != oldGeometry.x());
3029 bool yChange = (newGeometry.y() != oldGeometry.y());
3030 bool widthChange = (newGeometry.width() != oldGeometry.width());
3031 bool heightChange = (newGeometry.height() != oldGeometry.height());
3033 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
3034 const QQuickItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
3035 if (change.types & QQuickItemPrivate::Geometry) {
3036 if (change.gTypes == QQuickItemPrivate::GeometryChange) {
3037 change.listener->itemGeometryChanged(this, newGeometry, oldGeometry);
3038 } else if ((xChange && (change.gTypes & QQuickItemPrivate::XChange)) ||
3039 (yChange && (change.gTypes & QQuickItemPrivate::YChange)) ||
3040 (widthChange && (change.gTypes & QQuickItemPrivate::WidthChange)) ||
3041 (heightChange && (change.gTypes & QQuickItemPrivate::HeightChange))) {
3042 change.listener->itemGeometryChanged(this, newGeometry, oldGeometry);
3052 emit widthChanged();
3054 emit heightChanged();
3058 Called by the rendering thread, as a result of
3059 QQuickItem::update(), when it is time to sync the state of the QML
3060 objects with the scene graph objects.
3062 The function should return the root of the scene graph subtree for
3063 this item. Most implementations will return a single
3064 QSGGeometryNode containing the visual representation of this item.
3065 \a oldNode is the node that was returned the last time the
3066 function was called.
3069 QSGNode *MyItem::updatePaintNode(QSGNode *node, UpdatePaintNodeData *)
3071 QSGSimpleRectNode *n = static_cast<QSGSimpleRectNode *>(node);
3073 n = new QSGSimpleRectNode();
3074 n->setColor(Qt::red);
3076 n->setRect(boundingRect());
3081 The main thread is blocked while this function is executed so it is safe to read
3082 values from the QQuickItem instance and other objects in the main thread.
3084 If no call to QQuickItem::updatePaintNode() result in actual scene graph
3085 changes, like QSGNode::markDirty() or adding and removing nodes, then
3086 the underlying implementation may decide to not render the scene again as
3087 the visual outcome is identical.
3089 \warning It is crucial that OpenGL operations and interaction with
3090 the scene graph happens exclusively on the rendering thread,
3091 primarily during the QQuickItem::updatePaintNode() call. The best
3092 rule of thumb is to only use classes with the "QSG" prefix inside
3093 the QQuickItem::updatePaintNode() function.
3095 \sa QSGMaterial, QSGSimpleMaterial, QSGGeometryNode, QSGGeometry,
3096 QSGFlatColorMaterial, QSGTextureMaterial, QSGNode::markDirty()
3099 QSGNode *QQuickItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
3106 This function is called when the item's scene graph resources are no longer needed.
3107 It allows items to free its resources, for instance textures, that are not owned by scene graph
3108 nodes. Note that scene graph nodes are managed by QQuickCanvas and should not be deleted by
3109 this function. Scene graph resources are no longer needed when the parent is set to null and
3110 the item is not used by any \l ShaderEffect or \l ShaderEffectSource.
3112 This function is called from the main thread. Therefore, resources used by the scene graph
3113 should not be deleted directly, but by calling \l QObject::deleteLater().
3115 \note The item destructor still needs to free its scene graph resources if not already done.
3118 void QQuickItem::releaseResources()
3122 QSGTransformNode *QQuickItemPrivate::createTransformNode()
3124 return new QSGTransformNode;
3127 void QQuickItem::updatePolish()
3131 void QQuickItemPrivate::addItemChangeListener(QQuickItemChangeListener *listener, ChangeTypes types)
3133 changeListeners.append(ChangeListener(listener, types));
3136 void QQuickItemPrivate::removeItemChangeListener(QQuickItemChangeListener *listener, ChangeTypes types)
3138 ChangeListener change(listener, types);
3139 changeListeners.removeOne(change);
3142 void QQuickItemPrivate::updateOrAddGeometryChangeListener(QQuickItemChangeListener *listener, GeometryChangeTypes types)
3144 ChangeListener change(listener, types);
3145 int index = changeListeners.find(change);
3147 changeListeners[index].gTypes = change.gTypes; //we may have different GeometryChangeTypes
3149 changeListeners.append(change);
3152 void QQuickItemPrivate::updateOrRemoveGeometryChangeListener(QQuickItemChangeListener *listener,
3153 GeometryChangeTypes types)
3155 ChangeListener change(listener, types);
3156 if (types == NoChange) {
3157 changeListeners.removeOne(change);
3159 int index = changeListeners.find(change);
3161 changeListeners[index].gTypes = change.gTypes; //we may have different GeometryChangeTypes
3165 void QQuickItem::keyPressEvent(QKeyEvent *event)
3170 void QQuickItem::keyReleaseEvent(QKeyEvent *event)
3175 void QQuickItem::inputMethodEvent(QInputMethodEvent *event)
3180 void QQuickItem::focusInEvent(QFocusEvent *)
3182 #ifndef QT_NO_ACCESSIBILITY
3183 QAccessibleEvent ev(this, QAccessible::Focus);
3184 QAccessible::updateAccessibility(&ev);
3188 void QQuickItem::focusOutEvent(QFocusEvent *)
3192 void QQuickItem::mousePressEvent(QMouseEvent *event)
3197 void QQuickItem::mouseMoveEvent(QMouseEvent *event)
3202 void QQuickItem::mouseReleaseEvent(QMouseEvent *event)
3207 void QQuickItem::mouseDoubleClickEvent(QMouseEvent *)
3211 void QQuickItem::mouseUngrabEvent()
3216 void QQuickItem::touchUngrabEvent()
3221 void QQuickItem::wheelEvent(QWheelEvent *event)
3226 void QQuickItem::touchEvent(QTouchEvent *event)
3231 void QQuickItem::hoverEnterEvent(QHoverEvent *event)
3236 void QQuickItem::hoverMoveEvent(QHoverEvent *event)
3241 void QQuickItem::hoverLeaveEvent(QHoverEvent *event)
3246 #ifndef QT_NO_DRAGANDDROP
3247 void QQuickItem::dragEnterEvent(QDragEnterEvent *event)
3252 void QQuickItem::dragMoveEvent(QDragMoveEvent *event)
3258 void QQuickItem::dragLeaveEvent(QDragLeaveEvent *event)
3264 void QQuickItem::dropEvent(QDropEvent *event)
3268 #endif // QT_NO_DRAGANDDROP
3270 bool QQuickItem::childMouseEventFilter(QQuickItem *, QEvent *)
3275 void QQuickItem::windowDeactivateEvent()
3277 foreach (QQuickItem* item, childItems()) {
3278 item->windowDeactivateEvent();
3282 QVariant QQuickItem::inputMethodQuery(Qt::InputMethodQuery query) const
3284 Q_D(const QQuickItem);
3289 v = (bool)(flags() & ItemAcceptsInputMethod);
3292 case Qt::ImCursorRectangle:
3294 case Qt::ImCursorPosition:
3295 case Qt::ImSurroundingText:
3296 case Qt::ImCurrentSelection:
3297 case Qt::ImMaximumTextLength:
3298 case Qt::ImAnchorPosition:
3299 case Qt::ImPreferredLanguage:
3300 if (d->extra.isAllocated() && d->extra->keyHandler)
3301 v = d->extra->keyHandler->inputMethodQuery(query);
3309 QQuickAnchorLine QQuickItemPrivate::left() const
3311 Q_Q(const QQuickItem);
3312 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Left);
3315 QQuickAnchorLine QQuickItemPrivate::right() const
3317 Q_Q(const QQuickItem);
3318 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Right);
3321 QQuickAnchorLine QQuickItemPrivate::horizontalCenter() const
3323 Q_Q(const QQuickItem);
3324 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::HCenter);
3327 QQuickAnchorLine QQuickItemPrivate::top() const
3329 Q_Q(const QQuickItem);
3330 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Top);
3333 QQuickAnchorLine QQuickItemPrivate::bottom() const
3335 Q_Q(const QQuickItem);
3336 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Bottom);
3339 QQuickAnchorLine QQuickItemPrivate::verticalCenter() const
3341 Q_Q(const QQuickItem);
3342 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::VCenter);
3345 QQuickAnchorLine QQuickItemPrivate::baseline() const
3347 Q_Q(const QQuickItem);
3348 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Baseline);
3351 qreal QQuickItem::baselineOffset() const
3353 Q_D(const QQuickItem);
3354 if (d->baselineOffsetValid) {
3355 return d->baselineOffset;
3361 void QQuickItem::setBaselineOffset(qreal offset)
3364 if (offset == d->baselineOffset)
3367 d->baselineOffset = offset;
3368 d->baselineOffsetValid = true;
3370 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
3371 const QQuickItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
3372 if (change.types & QQuickItemPrivate::Geometry) {
3373 QQuickAnchorsPrivate *anchor = change.listener->anchorPrivate();
3375 anchor->updateVerticalAnchors();
3379 if (d->_anchors && (d->_anchors->usedAnchors() & QQuickAnchors::BaselineAnchor))
3380 QQuickAnchorsPrivate::get(d->_anchors)->updateVerticalAnchors();
3382 emit baselineOffsetChanged(offset);
3387 * Schedules a call to updatePaintNode() for this item.
3389 * The call to QQuickItem::updatePaintNode() will always happen if the
3390 * item is showing in a QQuickCanvas.
3392 * Only items which specifies QQuickItem::ItemHasContents are allowed
3393 * to call QQuickItem::update().
3395 void QQuickItem::update()
3398 Q_ASSERT(flags() & ItemHasContents);
3399 d->dirty(QQuickItemPrivate::Content);
3402 void QQuickItem::polish()
3405 if (!d->polishScheduled) {
3406 d->polishScheduled = true;
3408 QQuickCanvasPrivate *p = QQuickCanvasPrivate::get(d->canvas);
3409 bool maybeupdate = p->itemsToPolish.isEmpty();
3410 p->itemsToPolish.insert(this);
3411 if (maybeupdate) d->canvas->maybeUpdate();
3417 \qmlmethod object QtQuick2::Item::mapFromItem(Item item, real x, real y)
3418 \qmlmethod object QtQuick2::Item::mapFromItem(Item item, real x, real y, real width, real height)
3420 Maps the point (\a x, \a y) or rect (\a x, \a y, \a width, \a height), which is in \a
3421 item's coordinate system, to this item's coordinate system, and returns an object with \c x and
3422 \c y (and optionally \c width and \c height) properties matching the mapped coordinate.
3424 If \a item is a \c null value, this maps the point or rect from the coordinate system of
3427 void QQuickItem::mapFromItem(QQmlV8Function *args) const
3429 if (args->Length() != 0) {
3430 v8::Local<v8::Value> item = (*args)[0];
3431 QV8Engine *engine = args->engine();
3433 QQuickItem *itemObj = 0;
3434 if (!item->IsNull())
3435 itemObj = qobject_cast<QQuickItem*>(engine->toQObject(item));
3437 if (!itemObj && !item->IsNull()) {
3438 qmlInfo(this) << "mapFromItem() given argument \"" << engine->toString(item->ToString())
3439 << "\" which is neither null nor an Item";
3443 v8::Local<v8::Object> rv = v8::Object::New();
3444 args->returnValue(rv);
3446 qreal x = (args->Length() > 1)?(*args)[1]->NumberValue():0;
3447 qreal y = (args->Length() > 2)?(*args)[2]->NumberValue():0;
3449 if (args->Length() > 3) {
3450 qreal w = (*args)[3]->NumberValue();
3451 qreal h = (args->Length() > 4)?(*args)[4]->NumberValue():0;
3453 QRectF r = mapRectFromItem(itemObj, QRectF(x, y, w, h));
3455 rv->Set(v8::String::New("x"), v8::Number::New(r.x()));
3456 rv->Set(v8::String::New("y"), v8::Number::New(r.y()));
3457 rv->Set(v8::String::New("width"), v8::Number::New(r.width()));
3458 rv->Set(v8::String::New("height"), v8::Number::New(r.height()));
3460 QPointF p = mapFromItem(itemObj, QPointF(x, y));
3462 rv->Set(v8::String::New("x"), v8::Number::New(p.x()));
3463 rv->Set(v8::String::New("y"), v8::Number::New(p.y()));
3468 QTransform QQuickItem::itemTransform(QQuickItem *other, bool *ok) const
3470 Q_D(const QQuickItem);
3472 // XXX todo - we need to be able to handle common parents better and detect
3476 QTransform t = d->itemToCanvasTransform();
3477 if (other) t *= QQuickItemPrivate::get(other)->canvasToItemTransform();
3483 \qmlmethod object QtQuick2::Item::mapToItem(Item item, real x, real y)
3484 \qmlmethod object QtQuick2::Item::mapToItem(Item item, real x, real y, real width, real height)
3486 Maps the point (\a x, \a y) or rect (\a x, \a y, \a width, \a height), which is in this
3487 item's coordinate system, to \a item's coordinate system, and returns an object with \c x and
3488 \c y (and optionally \c width and \c height) properties matching the mapped coordinate.
3490 If \a item is a \c null value, this maps the point or rect to the coordinate system of the
3493 void QQuickItem::mapToItem(QQmlV8Function *args) const
3495 if (args->Length() != 0) {
3496 v8::Local<v8::Value> item = (*args)[0];
3497 QV8Engine *engine = args->engine();
3499 QQuickItem *itemObj = 0;
3500 if (!item->IsNull())
3501 itemObj = qobject_cast<QQuickItem*>(engine->toQObject(item));
3503 if (!itemObj && !item->IsNull()) {
3504 qmlInfo(this) << "mapToItem() given argument \"" << engine->toString(item->ToString())
3505 << "\" which is neither null nor an Item";
3509 v8::Local<v8::Object> rv = v8::Object::New();
3510 args->returnValue(rv);
3512 qreal x = (args->Length() > 1)?(*args)[1]->NumberValue():0;
3513 qreal y = (args->Length() > 2)?(*args)[2]->NumberValue():0;
3515 if (args->Length() > 3) {
3516 qreal w = (*args)[3]->NumberValue();
3517 qreal h = (args->Length() > 4)?(*args)[4]->NumberValue():0;
3519 QRectF r = mapRectToItem(itemObj, QRectF(x, y, w, h));
3521 rv->Set(v8::String::New("x"), v8::Number::New(r.x()));
3522 rv->Set(v8::String::New("y"), v8::Number::New(r.y()));
3523 rv->Set(v8::String::New("width"), v8::Number::New(r.width()));
3524 rv->Set(v8::String::New("height"), v8::Number::New(r.height()));
3526 QPointF p = mapToItem(itemObj, QPointF(x, y));
3528 rv->Set(v8::String::New("x"), v8::Number::New(p.x()));
3529 rv->Set(v8::String::New("y"), v8::Number::New(p.y()));
3534 void QQuickItem::forceActiveFocus()
3537 QQuickItem *parent = parentItem();
3539 if (parent->flags() & QQuickItem::ItemIsFocusScope) {
3540 parent->setFocus(true);
3542 parent = parent->parentItem();
3546 QQuickItem *QQuickItem::childAt(qreal x, qreal y) const
3548 // XXX todo - should this include transform etc.?
3549 const QList<QQuickItem *> children = childItems();
3550 for (int i = children.count()-1; i >= 0; --i) {
3551 QQuickItem *child = children.at(i);
3552 if (child->isVisible() && child->x() <= x
3553 && child->x() + child->width() >= x
3555 && child->y() + child->height() >= y)
3561 QQmlListProperty<QObject> QQuickItemPrivate::resources()
3563 return QQmlListProperty<QObject>(q_func(), 0, QQuickItemPrivate::resources_append,
3564 QQuickItemPrivate::resources_count,
3565 QQuickItemPrivate::resources_at,
3566 QQuickItemPrivate::resources_clear);
3569 QQmlListProperty<QQuickItem> QQuickItemPrivate::children()
3571 return QQmlListProperty<QQuickItem>(q_func(), 0, QQuickItemPrivate::children_append,
3572 QQuickItemPrivate::children_count,
3573 QQuickItemPrivate::children_at,
3574 QQuickItemPrivate::children_clear);
3579 \qmlproperty real QtQuick2::Item::visibleChildren
3580 This read-only property lists all of the item's children that are currently visible.
3581 Note that a child's visibility may have changed explicitly, or because the visibility
3582 of this (it's parent) item or another grandparent changed.
3584 QQmlListProperty<QQuickItem> QQuickItemPrivate::visibleChildren()
3586 return QQmlListProperty<QQuickItem>(q_func(), 0, QQuickItemPrivate::visibleChildren_append,
3587 QQuickItemPrivate::visibleChildren_count,
3588 QQuickItemPrivate::visibleChildren_at);
3592 QQmlListProperty<QQuickState> QQuickItemPrivate::states()
3594 return _states()->statesProperty();
3597 QQmlListProperty<QQuickTransition> QQuickItemPrivate::transitions()
3599 return _states()->transitionsProperty();
3602 QString QQuickItemPrivate::state() const
3607 return _stateGroup->state();
3610 void QQuickItemPrivate::setState(const QString &state)
3612 _states()->setState(state);
3615 QString QQuickItem::state() const
3617 Q_D(const QQuickItem);
3621 void QQuickItem::setState(const QString &state)
3627 QQmlListProperty<QQuickTransform> QQuickItem::transform()
3629 return QQmlListProperty<QQuickTransform>(this, 0, QQuickItemPrivate::transform_append,
3630 QQuickItemPrivate::transform_count,
3631 QQuickItemPrivate::transform_at,
3632 QQuickItemPrivate::transform_clear);
3637 Derived classes should call the base class method before adding their own action to
3638 perform at classBegin.
3640 void QQuickItem::classBegin()
3643 d->componentComplete = false;
3645 d->_stateGroup->classBegin();
3647 d->_anchors->classBegin();
3648 if (d->extra.isAllocated() && d->extra->layer)
3649 d->extra->layer->classBegin();
3654 Derived classes should call the base class method before adding their own actions to
3655 perform at componentComplete.
3657 void QQuickItem::componentComplete()
3660 d->componentComplete = true;
3662 d->_stateGroup->componentComplete();
3664 d->_anchors->componentComplete();
3665 QQuickAnchorsPrivate::get(d->_anchors)->updateOnComplete();
3668 if (d->extra.isAllocated() && d->extra->layer)
3669 d->extra->layer->componentComplete();
3671 if (d->extra.isAllocated() && d->extra->keyHandler)
3672 d->extra->keyHandler->componentComplete();
3674 if (d->extra.isAllocated() && d->extra->contents)
3675 d->extra->contents->complete();
3677 if (d->canvas && d->dirtyAttributes) {
3678 d->addToDirtyList();
3679 QQuickCanvasPrivate::get(d->canvas)->dirtyItem(this);
3683 QQuickStateGroup *QQuickItemPrivate::_states()
3687 _stateGroup = new QQuickStateGroup;
3688 if (!componentComplete)
3689 _stateGroup->classBegin();
3690 qmlobject_connect(_stateGroup, QQuickStateGroup, SIGNAL(stateChanged(QString)),
3691 q, QQuickItem, SIGNAL(stateChanged(QString)))
3697 QPointF QQuickItemPrivate::computeTransformOrigin() const
3701 case QQuickItem::TopLeft:
3702 return QPointF(0, 0);
3703 case QQuickItem::Top:
3704 return QPointF(width / 2., 0);
3705 case QQuickItem::TopRight:
3706 return QPointF(width, 0);
3707 case QQuickItem::Left:
3708 return QPointF(0, height / 2.);
3709 case QQuickItem::Center:
3710 return QPointF(width / 2., height / 2.);
3711 case QQuickItem::Right:
3712 return QPointF(width, height / 2.);
3713 case QQuickItem::BottomLeft:
3714 return QPointF(0, height);
3715 case QQuickItem::Bottom:
3716 return QPointF(width / 2., height);
3717 case QQuickItem::BottomRight:
3718 return QPointF(width, height);
3722 void QQuickItemPrivate::transformChanged()
3724 if (extra.isAllocated() && extra->layer)
3725 extra->layer->updateMatrix();
3728 void QQuickItemPrivate::deliverKeyEvent(QKeyEvent *e)
3732 Q_ASSERT(e->isAccepted());
3733 if (extra.isAllocated() && extra->keyHandler) {
3734 if (e->type() == QEvent::KeyPress)
3735 extra->keyHandler->keyPressed(e, false);
3737 extra->keyHandler->keyReleased(e, false);
3739 if (e->isAccepted())
3745 if (e->type() == QEvent::KeyPress)
3746 q->keyPressEvent(e);
3748 q->keyReleaseEvent(e);
3750 if (e->isAccepted())
3753 if (extra.isAllocated() && extra->keyHandler) {
3756 if (e->type() == QEvent::KeyPress)
3757 extra->keyHandler->keyPressed(e, true);
3759 extra->keyHandler->keyReleased(e, true);
3763 void QQuickItemPrivate::deliverInputMethodEvent(QInputMethodEvent *e)
3767 Q_ASSERT(e->isAccepted());
3768 if (extra.isAllocated() && extra->keyHandler) {
3769 extra->keyHandler->inputMethodEvent(e, false);
3771 if (e->isAccepted())
3777 q->inputMethodEvent(e);
3779 if (e->isAccepted())
3782 if (extra.isAllocated() && extra->keyHandler) {
3785 extra->keyHandler->inputMethodEvent(e, true);
3789 void QQuickItemPrivate::deliverFocusEvent(QFocusEvent *e)
3793 if (e->type() == QEvent::FocusIn) {
3796 q->focusOutEvent(e);
3800 void QQuickItemPrivate::deliverMouseEvent(QMouseEvent *e)
3804 Q_ASSERT(e->isAccepted());
3806 switch (e->type()) {
3808 Q_ASSERT(!"Unknown event type");
3809 case QEvent::MouseMove:
3810 q->mouseMoveEvent(e);
3812 case QEvent::MouseButtonPress:
3813 q->mousePressEvent(e);
3815 case QEvent::MouseButtonRelease:
3816 q->mouseReleaseEvent(e);
3818 case QEvent::MouseButtonDblClick:
3819 q->mouseDoubleClickEvent(e);
3824 void QQuickItemPrivate::deliverWheelEvent(QWheelEvent *e)
3830 void QQuickItemPrivate::deliverTouchEvent(QTouchEvent *e)
3836 void QQuickItemPrivate::deliverHoverEvent(QHoverEvent *e)
3839 switch (e->type()) {
3841 Q_ASSERT(!"Unknown event type");
3842 case QEvent::HoverEnter:
3843 q->hoverEnterEvent(e);
3845 case QEvent::HoverLeave:
3846 q->hoverLeaveEvent(e);
3848 case QEvent::HoverMove:
3849 q->hoverMoveEvent(e);
3854 #ifndef QT_NO_DRAGANDDROP
3855 void QQuickItemPrivate::deliverDragEvent(QEvent *e)
3858 switch (e->type()) {
3860 Q_ASSERT(!"Unknown event type");
3861 case QEvent::DragEnter:
3862 q->dragEnterEvent(static_cast<QDragEnterEvent *>(e));
3864 case QEvent::DragLeave:
3865 q->dragLeaveEvent(static_cast<QDragLeaveEvent *>(e));
3867 case QEvent::DragMove:
3868 q->dragMoveEvent(static_cast<QDragMoveEvent *>(e));
3871 q->dropEvent(static_cast<QDropEvent *>(e));
3875 #endif // QT_NO_DRAGANDDROP
3877 void QQuickItem::itemChange(ItemChange change, const ItemChangeData &value)
3884 Notify input method on updated query values if needed. \a indicates changed attributes.
3886 void QQuickItem::updateInputMethod(Qt::InputMethodQueries queries)
3888 if (hasActiveFocus())
3889 qApp->inputMethod()->update(queries);
3893 // XXX todo - do we want/need this anymore?
3894 QRectF QQuickItem::boundingRect() const
3896 Q_D(const QQuickItem);
3897 return QRectF(0, 0, d->width, d->height);
3901 QRectF QQuickItem::clipRect() const
3903 Q_D(const QQuickItem);
3904 return QRectF(0, 0, d->width, d->height);
3908 QQuickItem::TransformOrigin QQuickItem::transformOrigin() const
3910 Q_D(const QQuickItem);
3914 void QQuickItem::setTransformOrigin(TransformOrigin origin)
3917 if (origin == d->origin())
3920 d->extra.value().origin = origin;
3921 d->dirty(QQuickItemPrivate::TransformOrigin);
3923 emit transformOriginChanged(d->origin());
3926 QPointF QQuickItem::transformOriginPoint() const
3928 Q_D(const QQuickItem);
3929 if (d->extra.isAllocated() && !d->extra->userTransformOriginPoint.isNull())
3930 return d->extra->userTransformOriginPoint;
3931 return d->computeTransformOrigin();
3934 void QQuickItem::setTransformOriginPoint(const QPointF &point)
3937 if (d->extra.value().userTransformOriginPoint == point)
3940 d->extra->userTransformOriginPoint = point;
3941 d->dirty(QQuickItemPrivate::TransformOrigin);
3944 qreal QQuickItem::z() const
3946 Q_D(const QQuickItem);
3950 void QQuickItem::setZ(qreal v)
3956 d->extra.value().z = v;
3958 d->dirty(QQuickItemPrivate::ZValue);
3959 if (d->parentItem) {
3960 QQuickItemPrivate::get(d->parentItem)->dirty(QQuickItemPrivate::ChildrenStackingChanged);
3961 QQuickItemPrivate::get(d->parentItem)->markSortedChildrenDirty(this);
3966 if (d->extra.isAllocated() && d->extra->layer)
3967 d->extra->layer->updateZ();
3972 \qmlproperty real QtQuick2::Item::rotation
3973 This property holds the rotation of the item in degrees clockwise.
3975 This specifies how many degrees to rotate the item around its transformOrigin.
3976 The default rotation is 0 degrees (i.e. not rotated at all).
3980 \li \image declarative-rotation.png
3985 width: 100; height: 100
3988 x: 25; y: 25; width: 50; height: 50
3995 \sa transform, Rotation
3999 \qmlproperty real QtQuick2::Item::scale
4000 This property holds the scale of the item.
4002 A scale of less than 1 means the item will be displayed smaller than
4003 normal, and a scale of greater than 1 means the item will be
4004 displayed larger than normal. A negative scale means the item will
4007 By default, items are displayed at a scale of 1 (i.e. at their
4010 Scaling is from the item's transformOrigin.
4014 \li \image declarative-scale.png
4019 width: 100; height: 100
4022 width: 25; height: 25
4026 x: 25; y: 25; width: 50; height: 50
4033 \sa transform, Scale
4037 \qmlproperty real QtQuick2::Item::opacity
4039 This property holds the opacity of the item. Opacity is specified as a
4040 number between 0 (fully transparent) and 1 (fully opaque). The default is 1.
4042 When this property is set, the specified opacity is also applied
4043 individually to child items. In almost all cases this is what you want,
4044 but in some cases it may produce undesired results. For example in the
4045 second set of rectangles below, the red rectangle has specified an opacity
4046 of 0.5, which affects the opacity of its blue child rectangle even though
4047 the child has not specified an opacity.
4051 \li \image declarative-item_opacity1.png
4057 width: 100; height: 100
4060 x: 50; y: 50; width: 100; height: 100
4066 \li \image declarative-item_opacity2.png
4073 width: 100; height: 100
4076 x: 50; y: 50; width: 100; height: 100
4083 Changing an items opacity will not affect delivery of input events. (In contrast
4084 setting \l visible property to \c false stops mouse events, and setting the
4085 \l enabled property to \c false stops mouse and keyboard events, and also removes
4086 active focus from the item.)
4090 Returns a value indicating whether mouse input should
4091 remain with this item exclusively.
4093 \sa setKeepMouseGrab()
4096 qreal QQuickItem::rotation() const
4098 Q_D(const QQuickItem);
4099 return d->rotation();
4102 void QQuickItem::setRotation(qreal r)
4105 if (d->rotation() == r)
4108 d->extra.value().rotation = r;
4110 d->dirty(QQuickItemPrivate::BasicTransform);
4112 d->itemChange(ItemRotationHasChanged, r);
4114 emit rotationChanged();
4117 qreal QQuickItem::scale() const
4119 Q_D(const QQuickItem);
4123 void QQuickItem::setScale(qreal s)
4126 if (d->scale() == s)
4129 d->extra.value().scale = s;
4131 d->dirty(QQuickItemPrivate::BasicTransform);
4133 emit scaleChanged();
4136 qreal QQuickItem::opacity() const
4138 Q_D(const QQuickItem);
4139 return d->opacity();
4142 void QQuickItem::setOpacity(qreal o)
4145 if (d->opacity() == o)
4148 d->extra.value().opacity = o;
4150 d->dirty(QQuickItemPrivate::OpacityValue);
4152 d->itemChange(ItemOpacityHasChanged, o);
4154 emit opacityChanged();
4157 bool QQuickItem::isVisible() const
4159 Q_D(const QQuickItem);
4160 return d->effectiveVisible;
4163 void QQuickItem::setVisible(bool v)
4166 if (v == d->explicitVisible)
4169 d->explicitVisible = v;
4171 d->dirty(QQuickItemPrivate::Visible);
4173 const bool childVisibilityChanged = d->setEffectiveVisibleRecur(d->calcEffectiveVisible());
4174 if (childVisibilityChanged && d->parentItem)
4175 emit d->parentItem->visibleChildrenChanged(); // signal the parent, not this!
4178 bool QQuickItem::isEnabled() const
4180 Q_D(const QQuickItem);
4181 return d->effectiveEnable;
4184 void QQuickItem::setEnabled(bool e)
4187 if (e == d->explicitEnable)
4190 d->explicitEnable = e;
4192 QQuickItem *scope = parentItem();
4193 while (scope && !scope->isFocusScope())
4194 scope = scope->parentItem();
4196 d->setEffectiveEnableRecur(scope, d->calcEffectiveEnable());
4199 bool QQuickItemPrivate::calcEffectiveVisible() const
4201 // XXX todo - Should the effective visible of an element with no parent just be the current
4202 // effective visible? This would prevent pointless re-processing in the case of an element
4203 // moving to/from a no-parent situation, but it is different from what graphics view does.
4204 return explicitVisible && (!parentItem || QQuickItemPrivate::get(parentItem)->effectiveVisible);
4207 bool QQuickItemPrivate::setEffectiveVisibleRecur(bool newEffectiveVisible)
4211 if (newEffectiveVisible && !explicitVisible) {
4212 // This item locally overrides visibility
4213 return false; // effective visibility didn't change
4216 if (newEffectiveVisible == effectiveVisible) {
4217 // No change necessary
4218 return false; // effective visibility didn't change
4221 effectiveVisible = newEffectiveVisible;
4223 if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
4226 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(canvas);
4227 if (canvasPriv->mouseGrabberItem == q)
4231 bool childVisibilityChanged = false;
4232 for (int ii = 0; ii < childItems.count(); ++ii)
4233 childVisibilityChanged |= QQuickItemPrivate::get(childItems.at(ii))->setEffectiveVisibleRecur(newEffectiveVisible);
4235 itemChange(QQuickItem::ItemVisibleHasChanged, effectiveVisible);
4236 #ifndef QT_NO_ACCESSIBILITY
4238 QAccessibleEvent ev(q, effectiveVisible ? QAccessible::ObjectShow : QAccessible::ObjectHide);
4239 QAccessible::updateAccessibility(&ev);
4242 emit q->visibleChanged();
4243 if (childVisibilityChanged)
4244 emit q->visibleChildrenChanged();
4246 return true; // effective visibility DID change
4249 bool QQuickItemPrivate::calcEffectiveEnable() const
4251 // XXX todo - Should the effective enable of an element with no parent just be the current
4252 // effective enable? This would prevent pointless re-processing in the case of an element
4253 // moving to/from a no-parent situation, but it is different from what graphics view does.
4254 return explicitEnable && (!parentItem || QQuickItemPrivate::get(parentItem)->effectiveEnable);
4257 void QQuickItemPrivate::setEffectiveEnableRecur(QQuickItem *scope, bool newEffectiveEnable)
4261 if (newEffectiveEnable && !explicitEnable) {
4262 // This item locally overrides enable
4266 if (newEffectiveEnable == effectiveEnable) {
4267 // No change necessary
4271 effectiveEnable = newEffectiveEnable;
4274 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(canvas);
4275 if (canvasPriv->mouseGrabberItem == q)
4277 if (scope && !effectiveEnable && activeFocus) {
4278 canvasPriv->clearFocusInScope(
4279 scope, q, QQuickCanvasPrivate::DontChangeFocusProperty | QQuickCanvasPrivate::DontChangeSubFocusItem);
4283 for (int ii = 0; ii < childItems.count(); ++ii) {
4284 QQuickItemPrivate::get(childItems.at(ii))->setEffectiveEnableRecur(
4285 (flags & QQuickItem::ItemIsFocusScope) && scope ? q : scope, newEffectiveEnable);
4288 if (canvas && scope && effectiveEnable && focus) {
4289 QQuickCanvasPrivate::get(canvas)->setFocusInScope(
4290 scope, q, QQuickCanvasPrivate::DontChangeFocusProperty | QQuickCanvasPrivate::DontChangeSubFocusItem);
4293 emit q->enabledChanged();
4296 QString QQuickItemPrivate::dirtyToString() const
4298 #define DIRTY_TO_STRING(value) if (dirtyAttributes & value) { \
4299 if (!rv.isEmpty()) \
4300 rv.append(QLatin1String("|")); \
4301 rv.append(QLatin1String(#value)); \
4304 // QString rv = QLatin1String("0x") + QString::number(dirtyAttributes, 16);
4307 DIRTY_TO_STRING(TransformOrigin);
4308 DIRTY_TO_STRING(Transform);
4309 DIRTY_TO_STRING(BasicTransform);
4310 DIRTY_TO_STRING(Position);
4311 DIRTY_TO_STRING(Size);
4312 DIRTY_TO_STRING(ZValue);
4313 DIRTY_TO_STRING(Content);
4314 DIRTY_TO_STRING(Smooth);
4315 DIRTY_TO_STRING(OpacityValue);
4316 DIRTY_TO_STRING(ChildrenChanged);
4317 DIRTY_TO_STRING(ChildrenStackingChanged);
4318 DIRTY_TO_STRING(ParentChanged);
4319 DIRTY_TO_STRING(Clip);
4320 DIRTY_TO_STRING(Canvas);
4321 DIRTY_TO_STRING(EffectReference);
4322 DIRTY_TO_STRING(Visible);
4323 DIRTY_TO_STRING(HideReference);
4328 void QQuickItemPrivate::dirty(DirtyType type)
4331 if (type & (TransformOrigin | Transform | BasicTransform | Position | Size))
4334 if (!(dirtyAttributes & type) || (canvas && !prevDirtyItem)) {
4335 dirtyAttributes |= type;
4336 if (canvas && componentComplete) {
4338 QQuickCanvasPrivate::get(canvas)->dirtyItem(q);
4343 void QQuickItemPrivate::addToDirtyList()
4348 if (!prevDirtyItem) {
4349 Q_ASSERT(!nextDirtyItem);
4351 QQuickCanvasPrivate *p = QQuickCanvasPrivate::get(canvas);
4352 nextDirtyItem = p->dirtyItemList;
4353 if (nextDirtyItem) QQuickItemPrivate::get(nextDirtyItem)->prevDirtyItem = &nextDirtyItem;
4354 prevDirtyItem = &p->dirtyItemList;
4355 p->dirtyItemList = q;
4358 Q_ASSERT(prevDirtyItem);
4361 void QQuickItemPrivate::removeFromDirtyList()
4363 if (prevDirtyItem) {
4364 if (nextDirtyItem) QQuickItemPrivate::get(nextDirtyItem)->prevDirtyItem = prevDirtyItem;
4365 *prevDirtyItem = nextDirtyItem;
4369 Q_ASSERT(!prevDirtyItem);
4370 Q_ASSERT(!nextDirtyItem);
4373 void QQuickItemPrivate::refFromEffectItem(bool hide)
4375 ++extra.value().effectRefCount;
4376 if (1 == extra->effectRefCount) {
4377 dirty(EffectReference);
4378 if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
4381 if (++extra->hideRefCount == 1)
4382 dirty(HideReference);
4386 void QQuickItemPrivate::derefFromEffectItem(bool unhide)
4388 Q_ASSERT(extra->effectRefCount);
4389 --extra->effectRefCount;
4390 if (0 == extra->effectRefCount) {
4391 dirty(EffectReference);
4392 if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
4395 if (--extra->hideRefCount == 0)
4396 dirty(HideReference);
4400 void QQuickItemPrivate::setCulled(bool cull)
4406 if ((cull && ++extra->hideRefCount == 1) || (!cull && --extra->hideRefCount == 0))
4407 dirty(HideReference);
4410 void QQuickItemPrivate::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data)
4414 case QQuickItem::ItemChildAddedChange:
4415 q->itemChange(change, data);
4416 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4417 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4418 if (change.types & QQuickItemPrivate::Children) {
4419 change.listener->itemChildAdded(q, data.item);
4423 case QQuickItem::ItemChildRemovedChange:
4424 q->itemChange(change, data);
4425 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4426 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4427 if (change.types & QQuickItemPrivate::Children) {
4428 change.listener->itemChildRemoved(q, data.item);
4432 case QQuickItem::ItemSceneChange:
4433 q->itemChange(change, data);
4435 case QQuickItem::ItemVisibleHasChanged:
4436 q->itemChange(change, data);
4437 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4438 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4439 if (change.types & QQuickItemPrivate::Visibility) {
4440 change.listener->itemVisibilityChanged(q);
4444 case QQuickItem::ItemParentHasChanged:
4445 q->itemChange(change, data);
4446 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4447 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4448 if (change.types & QQuickItemPrivate::Parent) {
4449 change.listener->itemParentChanged(q, data.item);
4453 case QQuickItem::ItemOpacityHasChanged:
4454 q->itemChange(change, data);
4455 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4456 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4457 if (change.types & QQuickItemPrivate::Opacity) {
4458 change.listener->itemOpacityChanged(q);
4462 case QQuickItem::ItemActiveFocusHasChanged:
4463 q->itemChange(change, data);
4465 case QQuickItem::ItemRotationHasChanged:
4466 q->itemChange(change, data);
4467 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4468 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4469 if (change.types & QQuickItemPrivate::Rotation) {
4470 change.listener->itemRotationChanged(q);
4478 \property QQuickItem::smooth
4479 \brief Specifies whether the item is smoothed or not
4481 Primarily used in image based elements to decide if the item should use smooth
4482 sampling or not. Smooth sampling is performed using linear interpolation, while
4483 non-smooth is performed using nearest neighbor.
4485 In Qt Quick 2.0, this property has minimal impact on performance.
4491 Returns true if the item should be drawn with antialiasing and
4492 smooth pixmap filtering, false otherwise.
4494 The default is false.
4498 bool QQuickItem::smooth() const
4500 Q_D(const QQuickItem);
4505 Sets whether the item should be drawn with antialiasing and
4506 smooth pixmap filtering to \a smooth.
4510 void QQuickItem::setSmooth(bool smooth)
4513 if (d->smooth == smooth)
4517 d->dirty(QQuickItemPrivate::Smooth);
4519 emit smoothChanged(smooth);
4522 QQuickItem::Flags QQuickItem::flags() const
4524 Q_D(const QQuickItem);
4525 return (QQuickItem::Flags)d->flags;
4528 void QQuickItem::setFlag(Flag flag, bool enabled)
4532 setFlags((Flags)(d->flags | (quint32)flag));
4534 setFlags((Flags)(d->flags & ~(quint32)flag));
4537 void QQuickItem::setFlags(Flags flags)
4541 if ((flags & ItemIsFocusScope) != (d->flags & ItemIsFocusScope)) {
4542 if (flags & ItemIsFocusScope && !d->childItems.isEmpty() && d->canvas) {
4543 qWarning("QQuickItem: Cannot set FocusScope once item has children and is in a canvas.");
4544 flags &= ~ItemIsFocusScope;
4545 } else if (d->flags & ItemIsFocusScope) {
4546 qWarning("QQuickItem: Cannot unset FocusScope flag.");
4547 flags |= ItemIsFocusScope;
4551 if ((flags & ItemClipsChildrenToShape ) != (d->flags & ItemClipsChildrenToShape))
4552 d->dirty(QQuickItemPrivate::Clip);
4557 qreal QQuickItem::x() const
4559 Q_D(const QQuickItem);
4563 qreal QQuickItem::y() const
4565 Q_D(const QQuickItem);
4569 QPointF QQuickItem::pos() const
4571 Q_D(const QQuickItem);
4572 return QPointF(d->x, d->y);
4575 void QQuickItem::setX(qreal v)
4584 d->dirty(QQuickItemPrivate::Position);
4586 geometryChanged(QRectF(x(), y(), width(), height()),
4587 QRectF(oldx, y(), width(), height()));
4590 void QQuickItem::setY(qreal v)
4599 d->dirty(QQuickItemPrivate::Position);
4601 geometryChanged(QRectF(x(), y(), width(), height()),
4602 QRectF(x(), oldy, width(), height()));
4605 void QQuickItem::setPos(const QPointF &pos)
4608 if (QPointF(d->x, d->y) == pos)
4617 d->dirty(QQuickItemPrivate::Position);
4619 geometryChanged(QRectF(x(), y(), width(), height()),
4620 QRectF(oldx, oldy, width(), height()));
4623 qreal QQuickItem::width() const
4625 Q_D(const QQuickItem);
4629 void QQuickItem::setWidth(qreal w)
4635 d->widthValid = true;
4639 qreal oldWidth = d->width;
4642 d->dirty(QQuickItemPrivate::Size);
4644 geometryChanged(QRectF(x(), y(), width(), height()),
4645 QRectF(x(), y(), oldWidth, height()));
4648 void QQuickItem::resetWidth()
4651 d->widthValid = false;
4652 setImplicitWidth(implicitWidth());
4655 void QQuickItemPrivate::implicitWidthChanged()
4658 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4659 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4660 if (change.types & QQuickItemPrivate::ImplicitWidth) {
4661 change.listener->itemImplicitWidthChanged(q);
4664 emit q->implicitWidthChanged();
4667 qreal QQuickItemPrivate::getImplicitWidth() const
4669 return implicitWidth;
4672 Returns the width of the item that is implied by other properties that determine the content.
4674 qreal QQuickItem::implicitWidth() const
4676 Q_D(const QQuickItem);
4677 return d->getImplicitWidth();
4681 \qmlproperty real QtQuick2::Item::implicitWidth
4682 \qmlproperty real QtQuick2::Item::implicitHeight
4684 Defines the natural width or height of the Item if no \l width or \l height is specified.
4686 The default implicit size for most items is 0x0, however some elements have an inherent
4687 implicit size which cannot be overridden, e.g. Image, Text.
4689 Setting the implicit size is useful for defining components that have a preferred size
4690 based on their content, for example:
4697 property alias icon: image.source
4698 property alias label: text.text
4699 implicitWidth: text.implicitWidth + image.implicitWidth
4700 implicitHeight: Math.max(text.implicitHeight, image.implicitHeight)
4705 anchors.left: image.right; anchors.right: parent.right
4706 anchors.verticalCenter: parent.verticalCenter
4711 \b Note: using implicitWidth of Text or TextEdit and setting the width explicitly
4712 incurs a performance penalty as the text must be laid out twice.
4716 Sets the implied width of the item to \a w.
4717 This is the width implied by other properties that determine the content.
4719 void QQuickItem::setImplicitWidth(qreal w)
4722 bool changed = w != d->implicitWidth;
4723 d->implicitWidth = w;
4724 if (d->width == w || widthValid()) {
4726 d->implicitWidthChanged();
4727 if (d->width == w || widthValid())
4732 qreal oldWidth = d->width;
4735 d->dirty(QQuickItemPrivate::Size);
4737 geometryChanged(QRectF(x(), y(), width(), height()),
4738 QRectF(x(), y(), oldWidth, height()));
4741 d->implicitWidthChanged();
4745 Returns whether the width property has been set explicitly.
4747 bool QQuickItem::widthValid() const
4749 Q_D(const QQuickItem);
4750 return d->widthValid;
4753 qreal QQuickItem::height() const
4755 Q_D(const QQuickItem);
4759 void QQuickItem::setHeight(qreal h)
4765 d->heightValid = true;
4769 qreal oldHeight = d->height;
4772 d->dirty(QQuickItemPrivate::Size);
4774 geometryChanged(QRectF(x(), y(), width(), height()),
4775 QRectF(x(), y(), width(), oldHeight));
4778 void QQuickItem::resetHeight()
4781 d->heightValid = false;
4782 setImplicitHeight(implicitHeight());
4785 void QQuickItemPrivate::implicitHeightChanged()
4788 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4789 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4790 if (change.types & QQuickItemPrivate::ImplicitHeight) {
4791 change.listener->itemImplicitHeightChanged(q);
4794 emit q->implicitHeightChanged();
4797 qreal QQuickItemPrivate::getImplicitHeight() const
4799 return implicitHeight;
4803 Returns the height of the item that is implied by other properties that determine the content.
4805 qreal QQuickItem::implicitHeight() const
4807 Q_D(const QQuickItem);
4808 return d->getImplicitHeight();
4813 Sets the implied height of the item to \a h.
4814 This is the height implied by other properties that determine the content.
4816 void QQuickItem::setImplicitHeight(qreal h)
4819 bool changed = h != d->implicitHeight;
4820 d->implicitHeight = h;
4821 if (d->height == h || heightValid()) {
4823 d->implicitHeightChanged();
4824 if (d->height == h || heightValid())
4829 qreal oldHeight = d->height;
4832 d->dirty(QQuickItemPrivate::Size);
4834 geometryChanged(QRectF(x(), y(), width(), height()),
4835 QRectF(x(), y(), width(), oldHeight));
4838 d->implicitHeightChanged();
4841 void QQuickItem::setImplicitSize(qreal w, qreal h)
4844 bool wChanged = w != d->implicitWidth;
4845 bool hChanged = h != d->implicitHeight;
4847 d->implicitWidth = w;
4848 d->implicitHeight = h;
4852 if (d->width == w || widthValid()) {
4854 d->implicitWidthChanged();
4855 wDone = d->width == w || widthValid();
4858 if (d->height == h || heightValid()) {
4860 d->implicitHeightChanged();
4861 hDone = d->height == h || heightValid();
4867 qreal oldWidth = d->width;
4868 qreal oldHeight = d->height;
4874 d->dirty(QQuickItemPrivate::Size);
4876 geometryChanged(QRectF(x(), y(), width(), height()),
4877 QRectF(x(), y(), oldWidth, oldHeight));
4879 if (!wDone && wChanged)
4880 d->implicitWidthChanged();
4881 if (!hDone && hChanged)
4882 d->implicitHeightChanged();
4886 Returns whether the height property has been set explicitly.
4888 bool QQuickItem::heightValid() const
4890 Q_D(const QQuickItem);
4891 return d->heightValid;
4894 void QQuickItem::setSize(const QSizeF &size)
4897 d->heightValid = true;
4898 d->widthValid = true;
4900 if (QSizeF(d->width, d->height) == size)
4903 qreal oldHeight = d->height;
4904 qreal oldWidth = d->width;
4905 d->height = size.height();
4906 d->width = size.width();
4908 d->dirty(QQuickItemPrivate::Size);
4910 geometryChanged(QRectF(x(), y(), width(), height()),
4911 QRectF(x(), y(), oldWidth, oldHeight));
4914 bool QQuickItem::hasActiveFocus() const
4916 Q_D(const QQuickItem);
4917 return d->activeFocus;
4920 bool QQuickItem::hasFocus() const
4922 Q_D(const QQuickItem);
4926 void QQuickItem::setFocus(bool focus)
4929 if (d->focus == focus)
4932 if (d->canvas || d->parentItem) {
4933 // Need to find our nearest focus scope
4934 QQuickItem *scope = parentItem();
4935 while (scope && !scope->isFocusScope() && scope->parentItem())
4936 scope = scope->parentItem();
4939 QQuickCanvasPrivate::get(d->canvas)->setFocusInScope(scope, this);
4941 QQuickCanvasPrivate::get(d->canvas)->clearFocusInScope(scope, this);
4943 // do the focus changes from setFocusInScope/clearFocusInScope that are
4944 // unrelated to a canvas
4945 QVarLengthArray<QQuickItem *, 20> changed;
4946 QQuickItem *oldSubFocusItem = QQuickItemPrivate::get(scope)->subFocusItem;
4947 if (oldSubFocusItem) {
4948 QQuickItemPrivate::get(oldSubFocusItem)->updateSubFocusItem(scope, false);
4949 QQuickItemPrivate::get(oldSubFocusItem)->focus = false;
4950 changed << oldSubFocusItem;
4951 } else if (!scope->isFocusScope() && scope->hasFocus()) {
4952 QQuickItemPrivate::get(scope)->focus = false;
4955 d->updateSubFocusItem(scope, focus);
4959 emit focusChanged(focus);
4961 QQuickCanvasPrivate::notifyFocusChangesRecur(changed.data(), changed.count() - 1);
4964 QVarLengthArray<QQuickItem *, 20> changed;
4965 QQuickItem *oldSubFocusItem = d->subFocusItem;
4966 if (!isFocusScope() && oldSubFocusItem) {
4967 QQuickItemPrivate::get(oldSubFocusItem)->updateSubFocusItem(this, false);
4968 QQuickItemPrivate::get(oldSubFocusItem)->focus = false;
4969 changed << oldSubFocusItem;
4974 emit focusChanged(focus);
4976 QQuickCanvasPrivate::notifyFocusChangesRecur(changed.data(), changed.count() - 1);
4980 bool QQuickItem::isFocusScope() const
4982 return flags() & ItemIsFocusScope;
4985 QQuickItem *QQuickItem::scopedFocusItem() const
4987 Q_D(const QQuickItem);
4988 if (!isFocusScope())
4991 return d->subFocusItem;
4995 Qt::MouseButtons QQuickItem::acceptedMouseButtons() const
4997 Q_D(const QQuickItem);
4998 return d->acceptedMouseButtons();
5001 void QQuickItem::setAcceptedMouseButtons(Qt::MouseButtons buttons)
5004 if (buttons & Qt::LeftButton)
5007 d->extra.clearFlag();
5009 buttons &= ~Qt::LeftButton;
5010 if (buttons || d->extra.isAllocated())
5011 d->extra.value().acceptedMouseButtons = buttons;
5014 bool QQuickItem::filtersChildMouseEvents() const
5016 Q_D(const QQuickItem);
5017 return d->filtersChildMouseEvents;
5020 void QQuickItem::setFiltersChildMouseEvents(bool filter)
5023 d->filtersChildMouseEvents = filter;
5026 bool QQuickItem::isUnderMouse() const
5028 Q_D(const QQuickItem);
5032 QPointF cursorPos = QGuiApplicationPrivate::lastCursorPosition;
5033 return contains(mapFromScene(d->canvas->mapFromGlobal(cursorPos.toPoint())));
5036 bool QQuickItem::acceptHoverEvents() const
5038 Q_D(const QQuickItem);
5039 return d->hoverEnabled;
5042 void QQuickItem::setAcceptHoverEvents(bool enabled)
5045 d->hoverEnabled = enabled;
5048 void QQuickItem::grabMouse()
5053 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
5054 if (canvasPriv->mouseGrabberItem == this)
5057 QQuickItem *oldGrabber = canvasPriv->mouseGrabberItem;
5058 canvasPriv->mouseGrabberItem = this;
5060 QEvent ev(QEvent::UngrabMouse);
5061 d->canvas->sendEvent(oldGrabber, &ev);
5065 void QQuickItem::ungrabMouse()
5070 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
5071 if (canvasPriv->mouseGrabberItem != this) {
5072 qWarning("QQuickItem::ungrabMouse(): Item is not the mouse grabber.");
5076 canvasPriv->mouseGrabberItem = 0;
5078 QEvent ev(QEvent::UngrabMouse);
5079 d->canvas->sendEvent(this, &ev);
5082 bool QQuickItem::keepMouseGrab() const
5084 Q_D(const QQuickItem);
5085 return d->keepMouse;
5089 The flag indicating whether the mouse should remain
5090 with this item is set to \a keep.
5092 This is useful for items that wish to grab and keep mouse
5093 interaction following a predefined gesture. For example,
5094 an item that is interested in horizontal mouse movement
5095 may set keepMouseGrab to true once a threshold has been
5096 exceeded. Once keepMouseGrab has been set to true, filtering
5097 items will not react to mouse events.
5099 If the item does not indicate that it wishes to retain mouse grab,
5100 a filtering item may steal the grab. For example, Flickable may attempt
5101 to steal a mouse grab if it detects that the user has begun to
5106 void QQuickItem::setKeepMouseGrab(bool keep)
5109 d->keepMouse = keep;
5113 Grabs the touch points specified by \a ids.
5115 These touch points will be owned by the item until
5116 they are released. Alternatively, the grab can be stolen
5117 by a filtering item like Flickable. Use setKeepTouchGrab()
5118 to prevent the grab from being stolen.
5120 \sa ungrabTouchPoints(), setKeepTouchGrab()
5122 void QQuickItem::grabTouchPoints(const QVector<int> &ids)
5127 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
5129 QSet<QQuickItem*> ungrab;
5130 for (int i = 0; i < ids.count(); ++i) {
5131 QQuickItem *oldGrabber = canvasPriv->itemForTouchPointId.value(ids.at(i));
5132 if (oldGrabber == this)
5135 canvasPriv->itemForTouchPointId[ids.at(i)] = this;
5137 ungrab.insert(oldGrabber);
5139 foreach (QQuickItem *oldGrabber, ungrab)
5140 oldGrabber->touchUngrabEvent();
5144 Ungrabs the touch points owned by this item.
5146 \sa grabTouchPoints()
5148 void QQuickItem::ungrabTouchPoints()
5153 QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
5155 QMutableHashIterator<int, QQuickItem*> i(canvasPriv->itemForTouchPointId);
5156 while (i.hasNext()) {
5158 if (i.value() == this)
5165 Returns a value indicating whether the touch points grabbed by this item
5166 should remain with this item exclusively.
5168 \sa setKeepTouchGrab(), keepMouseGrab()
5170 bool QQuickItem::keepTouchGrab() const
5172 Q_D(const QQuickItem);
5173 return d->keepTouch;
5177 The flag indicating whether the touch points grabbed
5178 by this item should remain with this item is set to \a keep.
5180 This is useful for items that wish to grab and keep specific touch
5181 points following a predefined gesture. For example,
5182 an item that is interested in horizontal touch point movement
5183 may set setKeepTouchGrab to true once a threshold has been
5184 exceeded. Once setKeepTouchGrab has been set to true, filtering
5185 items will not react to the relevant touch points.
5187 If the item does not indicate that it wishes to retain touch point grab,
5188 a filtering item may steal the grab. For example, Flickable may attempt
5189 to steal a touch point grab if it detects that the user has begun to
5192 \sa keepTouchGrab(), setKeepMouseGrab()
5194 void QQuickItem::setKeepTouchGrab(bool keep)
5197 d->keepTouch = keep;
5201 Returns true if this item contains \a point, which is in local coordinates;
5202 returns false otherwise.
5204 This function can be overwritten in order to handle point collisions in items
5205 with custom shapes. The default implementation checks if the point is inside
5206 the item's bounding rect.
5208 Note that it's normally used to check if the item is under the mouse cursor,
5209 and for that reason, the implementation of this function should be as light-weight
5212 bool QQuickItem::contains(const QPointF &point) const
5214 Q_D(const QQuickItem);
5215 return QRectF(0, 0, d->width, d->height).contains(point);
5218 QPointF QQuickItem::mapToItem(const QQuickItem *item, const QPointF &point) const
5220 QPointF p = mapToScene(point);
5222 p = item->mapFromScene(p);
5226 QPointF QQuickItem::mapToScene(const QPointF &point) const
5228 Q_D(const QQuickItem);
5229 return d->itemToCanvasTransform().map(point);
5232 QRectF QQuickItem::mapRectToItem(const QQuickItem *item, const QRectF &rect) const
5234 Q_D(const QQuickItem);
5235 QTransform t = d->itemToCanvasTransform();
5237 t *= QQuickItemPrivate::get(item)->canvasToItemTransform();
5238 return t.mapRect(rect);
5241 QRectF QQuickItem::mapRectToScene(const QRectF &rect) const
5243 Q_D(const QQuickItem);
5244 return d->itemToCanvasTransform().mapRect(rect);
5247 QPointF QQuickItem::mapFromItem(const QQuickItem *item, const QPointF &point) const
5249 QPointF p = item?item->mapToScene(point):point;
5250 return mapFromScene(p);
5253 QPointF QQuickItem::mapFromScene(const QPointF &point) const
5255 Q_D(const QQuickItem);
5256 return d->canvasToItemTransform().map(point);
5259 QRectF QQuickItem::mapRectFromItem(const QQuickItem *item, const QRectF &rect) const
5261 Q_D(const QQuickItem);
5262 QTransform t = item?QQuickItemPrivate::get(item)->itemToCanvasTransform():QTransform();
5263 t *= d->canvasToItemTransform();
5264 return t.mapRect(rect);
5267 QRectF QQuickItem::mapRectFromScene(const QRectF &rect) const
5269 Q_D(const QQuickItem);
5270 return d->canvasToItemTransform().mapRect(rect);
5275 \qmlmethod QtQuick2::Item::forceActiveFocus()
5277 Forces active focus on the item.
5279 This method sets focus on the item and makes sure that all the focus scopes
5280 higher in the object hierarchy are also given the focus.
5284 Forces active focus on the item.
5286 This method sets focus on the item and makes sure that all the focus scopes
5287 higher in the object hierarchy are also given the focus.
5291 \qmlmethod QtQuick2::Item::childAt(real x, real y)
5293 Returns the visible child item at point (\a x, \a y), which is in this
5294 item's coordinate system, or \c null if there is no such item.
5298 Returns the visible child item at point (\a x, \a y), which is in this
5299 item's coordinate system, or 0 if there is no such item.
5303 \qmlproperty list<State> QtQuick2::Item::states
5304 This property holds a list of states defined by the item.
5320 \sa {qmlstate}{States}
5323 \qmlproperty list<Transition> QtQuick2::Item::transitions
5324 This property holds a list of transitions defined by the item.
5340 \sa {QML Animation and Transitions}{Transitions}
5343 \qmlproperty list<Filter> QtQuick2::Item::filter
5344 This property holds a list of graphical filters to be applied to the item.
5346 \l {Filter}{Filters} include things like \l {Blur}{blurring}
5347 the item, or giving it a \l Reflection. Some
5348 filters may not be available on all canvases; if a filter is not
5349 available on a certain canvas, it will simply not be applied for
5350 that canvas (but the QML will still be considered valid).
5368 \qmlproperty bool QtQuick2::Item::clip
5369 This property holds whether clipping is enabled. The default clip value is \c false.
5371 If clipping is enabled, an item will clip its own painting, as well
5372 as the painting of its children, to its bounding rectangle.
5374 Non-rectangular clipping regions are not supported for performance reasons.
5378 \property QQuickItem::clip
5379 This property holds whether clipping is enabled. The default clip value is \c false.
5381 If clipping is enabled, an item will clip its own painting, as well
5382 as the painting of its children, to its bounding rectangle. If you set
5383 clipping during an item's paint operation, remember to re-set it to
5384 prevent clipping the rest of your scene.
5386 Non-rectangular clipping regions are not supported for performance reasons.
5390 \qmlproperty string QtQuick2::Item::state
5392 This property holds the name of the current state of the item.
5394 This property is often used in scripts to change between states. For
5399 if (button.state == 'On')
5400 button.state = 'Off';
5402 button.state = 'On';
5406 If the item is in its base state (i.e. no explicit state has been
5407 set), \c state will be a blank string. Likewise, you can return an
5408 item to its base state by setting its current state to \c ''.
5410 \sa {qmlstates}{States}
5414 \qmlproperty list<Transform> QtQuick2::Item::transform
5415 This property holds the list of transformations to apply.
5417 For more information see \l Transform.
5421 \enum QQuickItem::TransformOrigin
5423 Controls the point about which simple transforms like scale apply.
5425 \value TopLeft The top-left corner of the item.
5426 \value Top The center point of the top of the item.
5427 \value TopRight The top-right corner of the item.
5428 \value Left The left most point of the vertical middle.
5429 \value Center The center of the item.
5430 \value Right The right most point of the vertical middle.
5431 \value BottomLeft The bottom-left corner of the item.
5432 \value Bottom The center point of the bottom of the item.
5433 \value BottomRight The bottom-right corner of the item.
5438 \qmlproperty bool QtQuick2::Item::activeFocus
5440 This property indicates whether the item has active focus.
5442 An item with active focus will receive keyboard input,
5443 or is a FocusScope ancestor of the item that will receive keyboard input.
5445 Usually, activeFocus is gained by setting focus on an item and its enclosing
5446 FocusScopes. In the following example \c input will have activeFocus.
5459 \sa focus, {qmlfocus}{Keyboard Focus}
5463 \qmlproperty bool QtQuick2::Item::focus
5464 This property indicates whether the item has focus within the enclosing focus scope. If true, this item
5465 will gain active focus when the enclosing focus scope gains active focus.
5466 In the following example, \c input will be given active focus when \c scope gains active focus.
5479 For the purposes of this property, the scene as a whole is assumed to act like a focus scope.
5480 On a practical level, that means the following QML will give active focus to \c input on startup.
5491 \sa activeFocus, {qmlfocus}{Keyboard Focus}
5496 \property QQuickItem::anchors
5501 \property QQuickItem::left
5506 \property QQuickItem::right
5511 \property QQuickItem::horizontalCenter
5516 \property QQuickItem::top
5521 \property QQuickItem::bottom
5526 \property QQuickItem::verticalCenter
5531 \property QQuickItem::focus
5536 \property QQuickItem::transform
5541 \property QQuickItem::transformOrigin
5546 \property QQuickItem::activeFocus
5551 \property QQuickItem::baseline
5556 \property QQuickItem::data
5561 \property QQuickItem::resources
5566 \property QQuickItem::state
5571 \property QQuickItem::states
5576 \property QQuickItem::transformOriginPoint
5581 \property QQuickItem::transitions
5585 bool QQuickItem::event(QEvent *ev)
5588 if (ev->type() == QEvent::PolishRequest) {
5590 d->polishScheduled = false;
5594 return QObject::event(ev);
5597 if (ev->type() == QEvent::InputMethodQuery) {
5598 QInputMethodQueryEvent *query = static_cast<QInputMethodQueryEvent *>(ev);
5599 Qt::InputMethodQueries queries = query->queries();
5600 for (uint i = 0; i < 32; ++i) {
5601 Qt::InputMethodQuery q = (Qt::InputMethodQuery)(int)(queries & (1<<i));
5603 QVariant v = inputMethodQuery(q);
5604 query->setValue(q, v);
5609 } else if (ev->type() == QEvent::InputMethod) {
5610 inputMethodEvent(static_cast<QInputMethodEvent *>(ev));
5613 return QObject::event(ev);
5616 #ifndef QT_NO_DEBUG_STREAM
5617 QDebug operator<<(QDebug debug, QQuickItem *item)
5620 debug << "QQuickItem(0)";
5624 debug << item->metaObject()->className() << "(this =" << ((void*)item)
5625 << ", name=" << item->objectName()
5626 << ", parent =" << ((void*)item->parentItem())
5627 << ", geometry =" << QRectF(item->pos(), QSizeF(item->width(), item->height()))
5628 << ", z =" << item->z() << ')';
5633 qint64 QQuickItemPrivate::consistentTime = -1;
5634 void QQuickItemPrivate::setConsistentTime(qint64 t)
5639 class QElapsedTimerConsistentTimeHack
5643 t1 = QQuickItemPrivate::consistentTime;
5647 return QQuickItemPrivate::consistentTime - t1;
5650 qint64 val = QQuickItemPrivate::consistentTime - t1;
5651 t1 = QQuickItemPrivate::consistentTime;
5661 void QQuickItemPrivate::start(QElapsedTimer &t)
5663 if (QQuickItemPrivate::consistentTime == -1)
5666 ((QElapsedTimerConsistentTimeHack*)&t)->start();
5669 qint64 QQuickItemPrivate::elapsed(QElapsedTimer &t)
5671 if (QQuickItemPrivate::consistentTime == -1)
5674 return ((QElapsedTimerConsistentTimeHack*)&t)->elapsed();
5677 qint64 QQuickItemPrivate::restart(QElapsedTimer &t)
5679 if (QQuickItemPrivate::consistentTime == -1)
5682 return ((QElapsedTimerConsistentTimeHack*)&t)->restart();
5686 \fn bool QQuickItem::isTextureProvider() const
5688 Returns true if this item is a texture provider. The default
5689 implementation returns false.
5691 This function can be called from any thread.
5694 bool QQuickItem::isTextureProvider() const
5696 Q_D(const QQuickItem);
5697 return d->extra.isAllocated() && d->extra->layer && d->extra->layer->effectSource() ?
5698 d->extra->layer->effectSource()->isTextureProvider() : false;
5702 \fn QSGTextureProvider *QQuickItem::textureProvider() const
5704 Returns the texture provider for an item. The default implementation
5707 This function may only be called on the rendering thread.
5710 QSGTextureProvider *QQuickItem::textureProvider() const
5712 Q_D(const QQuickItem);
5713 return d->extra.isAllocated() && d->extra->layer && d->extra->layer->effectSource() ?
5714 d->extra->layer->effectSource()->textureProvider() : 0;
5717 QQuickItemLayer *QQuickItemPrivate::layer() const
5719 if (!extra.isAllocated() || !extra->layer) {
5720 extra.value().layer = new QQuickItemLayer(const_cast<QQuickItem *>(q_func()));
5721 if (!componentComplete)
5722 extra->layer->classBegin();
5724 return extra->layer;
5727 QQuickItemLayer::QQuickItemLayer(QQuickItem *item)
5732 , m_componentComplete(true)
5733 , m_wrapMode(QQuickShaderEffectSource::ClampToEdge)
5734 , m_format(QQuickShaderEffectSource::RGBA)
5736 , m_effectComponent(0)
5742 QQuickItemLayer::~QQuickItemLayer()
5744 delete m_effectSource;
5751 \qmlproperty bool QtQuick2::Item::layer.enabled
5753 Holds wether the item is layered or not. Layering is disabled by default.
5755 A layered item is rendered into an offscreen surface and cached until
5756 it is changed. Enabling layering for complex QML item hierarchies can
5757 some times be an optimization.
5759 None of the other layer properties have any effect when the layer
5763 void QQuickItemLayer::setEnabled(bool e)
5768 if (m_componentComplete) {
5775 emit enabledChanged(e);
5778 void QQuickItemLayer::classBegin()
5780 Q_ASSERT(!m_effectSource);
5781 Q_ASSERT(!m_effect);
5782 m_componentComplete = false;
5785 void QQuickItemLayer::componentComplete()
5787 Q_ASSERT(!m_componentComplete);
5788 m_componentComplete = true;
5793 void QQuickItemLayer::activate()
5795 Q_ASSERT(!m_effectSource);
5796 m_effectSource = new QQuickShaderEffectSource();
5798 QQuickItem *parentItem = m_item->parentItem();
5800 m_effectSource->setParentItem(parentItem);
5801 m_effectSource->stackAfter(m_item);
5804 m_effectSource->setSourceItem(m_item);
5805 m_effectSource->setHideSource(true);
5806 m_effectSource->setSmooth(m_smooth);
5807 m_effectSource->setTextureSize(m_size);
5808 m_effectSource->setSourceRect(m_sourceRect);
5809 m_effectSource->setMipmap(m_mipmap);
5810 m_effectSource->setWrapMode(m_wrapMode);
5811 m_effectSource->setFormat(m_format);
5813 if (m_effectComponent)
5816 m_effectSource->setVisible(m_item->isVisible() && !m_effect);
5823 QQuickItemPrivate *id = QQuickItemPrivate::get(m_item);
5824 id->addItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Opacity | QQuickItemPrivate::Parent | QQuickItemPrivate::Visibility | QQuickItemPrivate::SiblingOrder);
5827 void QQuickItemLayer::deactivate()
5829 Q_ASSERT(m_effectSource);
5831 if (m_effectComponent)
5834 delete m_effectSource;
5837 QQuickItemPrivate *id = QQuickItemPrivate::get(m_item);
5838 id->removeItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Opacity | QQuickItemPrivate::Parent | QQuickItemPrivate::Visibility | QQuickItemPrivate::SiblingOrder);
5841 void QQuickItemLayer::activateEffect()
5843 Q_ASSERT(m_effectSource);
5844 Q_ASSERT(m_effectComponent);
5845 Q_ASSERT(!m_effect);
5847 QObject *created = m_effectComponent->beginCreate(m_effectComponent->creationContext());
5848 m_effect = qobject_cast<QQuickItem *>(created);
5850 qWarning("Item: layer.effect is not a QML Item.");
5851 m_effectComponent->completeCreate();
5855 QQuickItem *parentItem = m_item->parentItem();
5857 m_effect->setParentItem(parentItem);
5858 m_effect->stackAfter(m_effectSource);
5860 m_effect->setVisible(m_item->isVisible());
5861 m_effect->setProperty(m_name, qVariantFromValue<QObject *>(m_effectSource));
5862 m_effectComponent->completeCreate();
5865 void QQuickItemLayer::deactivateEffect()
5867 Q_ASSERT(m_effectSource);
5868 Q_ASSERT(m_effectComponent);
5876 \qmlproperty Component QtQuick2::Item::layer.effect
5878 Holds the effect that is applied to this layer.
5880 The effect is typically a \l ShaderEffect component, although any \l Item component can be
5881 assigned. The effect should have a source texture property with a name matching \l samplerName.
5886 void QQuickItemLayer::setEffect(QQmlComponent *component)
5888 if (component == m_effectComponent)
5891 bool updateNeeded = false;
5892 if (m_effectSource && m_effectComponent) {
5894 updateNeeded = true;
5897 m_effectComponent = component;
5899 if (m_effectSource && m_effectComponent) {
5901 updateNeeded = true;
5909 m_effectSource->setVisible(m_item->isVisible() && !m_effect);
5912 emit effectChanged(component);
5917 \qmlproperty bool QtQuick2::Item::layer.mipmap
5919 If this property is true, mipmaps are generated for the texture.
5921 \note Some OpenGL ES 2 implementations do not support mipmapping of
5922 non-power-of-two textures.
5925 void QQuickItemLayer::setMipmap(bool mipmap)
5927 if (mipmap == m_mipmap)
5932 m_effectSource->setMipmap(m_mipmap);
5934 emit mipmapChanged(mipmap);
5939 \qmlproperty enumeration QtQuick2::Item::layer.format
5941 This property defines the internal OpenGL format of the texture.
5942 Modifying this property makes most sense when the \a layer.effect is also
5943 specified. Depending on the OpenGL implementation, this property might
5944 allow you to save some texture memory.
5947 \li ShaderEffectSource.Alpha - GL_ALPHA
5948 \li ShaderEffectSource.RGB - GL_RGB
5949 \li ShaderEffectSource.RGBA - GL_RGBA
5952 \note Some OpenGL implementations do not support the GL_ALPHA format.
5955 void QQuickItemLayer::setFormat(QQuickShaderEffectSource::Format f)
5962 m_effectSource->setFormat(m_format);
5964 emit formatChanged(m_format);
5969 \qmlproperty enumeration QtQuick2::Item::layer.sourceRect
5971 This property defines which rectangular area of the \l sourceItem to
5972 render into the texture. The source rectangle can be larger than
5973 \l sourceItem itself. If the rectangle is null, which is the default,
5974 the whole \l sourceItem is rendered to texture.
5977 void QQuickItemLayer::setSourceRect(const QRectF &sourceRect)
5979 if (sourceRect == m_sourceRect)
5981 m_sourceRect = sourceRect;
5984 m_effectSource->setSourceRect(m_sourceRect);
5986 emit sourceRectChanged(sourceRect);
5992 \qmlproperty bool QtQuick2::Item::layer.smooth
5994 Holds whether the layer is smoothly transformed.
5997 void QQuickItemLayer::setSmooth(bool s)
6004 m_effectSource->setSmooth(m_smooth);
6006 emit smoothChanged(s);
6012 \qmlproperty size QtQuick2::Item::layer.textureSize
6014 This property holds the requested pixel size of the layers texture. If it is empty,
6015 which is the default, the size of the item is used.
6017 \note Some platforms have a limit on how small framebuffer objects can be,
6018 which means the actual texture size might be larger than the requested
6022 void QQuickItemLayer::setSize(const QSize &size)
6029 m_effectSource->setTextureSize(size);
6031 emit sizeChanged(size);
6037 \qmlproperty enumeration QtQuick2::Item::layer.wrapMode
6039 This property defines the OpenGL wrap modes associated with the texture.
6040 Modifying this property makes most sense when the \a layer.effect is
6044 \li ShaderEffectSource.ClampToEdge - GL_CLAMP_TO_EDGE both horizontally and vertically
6045 \li ShaderEffectSource.RepeatHorizontally - GL_REPEAT horizontally, GL_CLAMP_TO_EDGE vertically
6046 \li ShaderEffectSource.RepeatVertically - GL_CLAMP_TO_EDGE horizontally, GL_REPEAT vertically
6047 \li ShaderEffectSource.Repeat - GL_REPEAT both horizontally and vertically
6050 \note Some OpenGL ES 2 implementations do not support the GL_REPEAT
6051 wrap mode with non-power-of-two textures.
6054 void QQuickItemLayer::setWrapMode(QQuickShaderEffectSource::WrapMode mode)
6056 if (mode == m_wrapMode)
6061 m_effectSource->setWrapMode(m_wrapMode);
6063 emit wrapModeChanged(mode);
6067 \qmlproperty string QtQuick2::Item::layer.samplerName
6069 Holds the name of the effect's source texture property.
6071 samplerName needs to match the name of the effect's source texture property
6072 so that the Item can pass the layer's offscreen surface to the effect correctly.
6074 \sa effect, ShaderEffect
6077 void QQuickItemLayer::setName(const QByteArray &name) {
6081 m_effect->setProperty(m_name, QVariant());
6082 m_effect->setProperty(name, qVariantFromValue<QObject *>(m_effectSource));
6085 emit nameChanged(name);
6088 void QQuickItemLayer::itemOpacityChanged(QQuickItem *item)
6094 void QQuickItemLayer::itemGeometryChanged(QQuickItem *, const QRectF &, const QRectF &)
6099 void QQuickItemLayer::itemParentChanged(QQuickItem *item, QQuickItem *parent)
6102 Q_ASSERT(item == m_item);
6103 Q_ASSERT(parent != m_effectSource);
6104 Q_ASSERT(parent == 0 || parent != m_effect);
6106 m_effectSource->setParentItem(parent);
6108 m_effectSource->stackAfter(m_item);
6111 m_effect->setParentItem(parent);
6113 m_effect->stackAfter(m_effectSource);
6117 void QQuickItemLayer::itemSiblingOrderChanged(QQuickItem *)
6119 m_effectSource->stackAfter(m_item);
6121 m_effect->stackAfter(m_effectSource);
6124 void QQuickItemLayer::itemVisibilityChanged(QQuickItem *)
6126 QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
6128 l->setVisible(m_item->isVisible());
6131 void QQuickItemLayer::updateZ()
6133 if (!m_componentComplete || !m_enabled)
6135 QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
6137 l->setZ(m_item->z());
6140 void QQuickItemLayer::updateOpacity()
6142 QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
6144 l->setOpacity(m_item->opacity());
6147 void QQuickItemLayer::updateGeometry()
6149 QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
6151 QRectF bounds = m_item->clipRect();
6152 l->setWidth(bounds.width());
6153 l->setHeight(bounds.height());
6154 l->setX(bounds.x() + m_item->x());
6155 l->setY(bounds.y() + m_item->y());
6158 void QQuickItemLayer::updateMatrix()
6160 // Called directly from transformChanged(), so needs some extra
6162 if (!m_componentComplete || !m_enabled)
6164 QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
6166 QQuickItemPrivate *ld = QQuickItemPrivate::get(l);
6167 l->setScale(m_item->scale());
6168 l->setRotation(m_item->rotation());
6169 ld->transforms = QQuickItemPrivate::get(m_item)->transforms;
6170 if (ld->origin() != QQuickItemPrivate::get(m_item)->origin())
6171 ld->extra.value().origin = QQuickItemPrivate::get(m_item)->origin();
6172 ld->dirty(QQuickItemPrivate::Transform);
6175 QQuickItemPrivate::ExtraData::ExtraData()
6176 : z(0), scale(1), rotation(0), opacity(1),
6177 contents(0), screenAttached(0), layoutDirectionAttached(0),
6178 keyHandler(0), layer(0), effectRefCount(0), hideRefCount(0),
6179 opacityNode(0), clipNode(0), rootNode(0), beforePaintNode(0),
6180 acceptedMouseButtons(0), origin(QQuickItem::Center)
6186 #include <moc_qquickitem.cpp>