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 "qquickwindow.h"
45 #include <QtQml/qjsengine.h>
46 #include "qquickwindow_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 type is a base type which cannot be instantiated directly.
136 The following concrete Transform types are available:
144 The Transform types let you create and control advanced transformations that can be configured
145 independently using specialized properties.
147 You can assign any number of Transforms 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 items while still allowing the \l Row
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 type 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->window()) {
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->window()->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->window()) {
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->window()->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->window()) {
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->window()->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} types (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 types 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 items 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} types
1512 (such as \l Row and \l Grid) and view types (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 QQuickWindow, 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 types 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->windowRefCount > 1)
1876 d->windowRefCount = 1; // Make sure window is set to null in next call to derefWindow().
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 QQuickWindowPrivate::get(d->window)->clearFocusInScope(scopeItem, scopeFocusedItem,
1989 QQuickWindowPrivate::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->window) {
2003 QQuickWindowPrivate::get(d->window)->parentlessItems.remove(this);
2006 QQuickWindow *oldParentWindow = oldParentItem ? QQuickItemPrivate::get(oldParentItem)->window : 0;
2007 QQuickWindow *parentWindow = parentItem ? QQuickItemPrivate::get(parentItem)->window : 0;
2008 if (oldParentWindow == parentWindow) {
2009 // Avoid freeing and reallocating resources if the window stays the same.
2010 d->parentItem = parentItem;
2012 if (oldParentWindow)
2014 d->parentItem = parentItem;
2016 d->refWindow(parentWindow);
2019 d->dirty(QQuickItemPrivate::ParentChanged);
2022 QQuickItemPrivate::get(d->parentItem)->addChild(this);
2024 QQuickWindowPrivate::get(d->window)->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 QQuickWindowPrivate::get(d->window)->setFocusInScope(scopeItem, scopeFocusedItem,
2052 QQuickWindowPrivate::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 QQuickWindow *QQuickItem::window() 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::refWindow(QQuickWindow *c)
2208 // An item needs a window if it is referenced by another item which has a window.
2209 // Typically the item is referenced by a parent, but can also be referenced by a
2210 // ShaderEffect or ShaderEffectSource. 'windowRefCount' counts how many items with
2211 // a window is referencing this item. When the reference count goes from zero to one,
2212 // or one to zero, the window of this item is updated and propagated to the children.
2213 // As long as the reference count stays above zero, the window is unchanged.
2214 // refWindow() increments the reference count.
2215 // derefWindow() decrements the reference count.
2218 Q_ASSERT((window != 0) == (windowRefCount > 0));
2220 if (++windowRefCount > 1) {
2222 qWarning("QQuickItem: Cannot use same item on different windows at the same time.");
2223 return; // Window already set.
2226 Q_ASSERT(window == 0);
2229 if (polishScheduled)
2230 QQuickWindowPrivate::get(window)->itemsToPolish.insert(q);
2233 QQuickWindowPrivate::get(window)->parentlessItems.insert(q);
2235 for (int ii = 0; ii < childItems.count(); ++ii) {
2236 QQuickItem *child = childItems.at(ii);
2237 QQuickItemPrivate::get(child)->refWindow(c);
2242 if (extra.isAllocated() && extra->screenAttached)
2243 extra->screenAttached->windowChanged(c);
2244 itemChange(QQuickItem::ItemSceneChange, c);
2247 void QQuickItemPrivate::derefWindow()
2250 Q_ASSERT((window != 0) == (windowRefCount > 0));
2253 return; // This can happen when destroying recursive shader effect sources.
2255 if (--windowRefCount > 0)
2256 return; // There are still other references, so don't set window to null yet.
2258 q->releaseResources();
2259 removeFromDirtyList();
2260 QQuickWindowPrivate *c = QQuickWindowPrivate::get(window);
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)->derefWindow();
2298 if (extra.isAllocated() && extra->screenAttached)
2299 extra->screenAttached->windowChanged(0);
2300 itemChange(QQuickItem::ItemSceneChange, (QQuickWindow *)0);
2305 Returns a transform that maps points from window space into item space.
2307 QTransform QQuickItemPrivate::windowToItemTransform() const
2309 // XXX todo - optimize
2310 return itemToWindowTransform().inverted();
2314 Returns a transform that maps points from item space into window space.
2316 QTransform QQuickItemPrivate::itemToWindowTransform() const
2319 QTransform rv = parentItem?QQuickItemPrivate::get(parentItem)->itemToWindowTransform():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()
2408 , heightValid(false)
2409 , baselineOffsetValid(false)
2410 , componentComplete(true)
2413 , hoverEnabled(false)
2415 , antialiasing(false)
2417 , activeFocus(false)
2418 , notifiedFocus(false)
2419 , notifiedActiveFocus(false)
2420 , filtersChildMouseEvents(false)
2421 , explicitVisible(true)
2422 , effectiveVisible(true)
2423 , explicitEnable(true)
2424 , effectiveEnable(true)
2425 , polishScheduled(false)
2426 , inheritedLayoutMirror(false)
2427 , effectiveLayoutMirror(false)
2428 , isMirrorImplicit(true)
2429 , inheritMirrorFromParent(false)
2430 , inheritMirrorFromItem(false)
2431 , isAccessible(false)
2433 , dirtyAttributes(0)
2439 , sortedChildItems(&childItems)
2448 , itemNodeInstance(0)
2454 QQuickItemPrivate::~QQuickItemPrivate()
2456 if (sortedChildItems != &childItems)
2457 delete sortedChildItems;
2460 void QQuickItemPrivate::init(QQuickItem *parent)
2464 static bool atexit_registered = false;
2465 if (!atexit_registered) {
2466 atexit(qt_print_item_count);
2467 atexit_registered = true;
2473 registerAccessorProperties();
2475 baselineOffsetValid = false;
2478 q->setParentItem(parent);
2479 QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(parent);
2480 setImplicitLayoutMirror(parentPrivate->inheritedLayoutMirror, parentPrivate->inheritMirrorFromParent);
2484 void QQuickItemPrivate::data_append(QQmlListProperty<QObject> *prop, QObject *o)
2489 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2491 if (QQuickItem *item = qmlobject_cast<QQuickItem *>(o)) {
2492 item->setParentItem(that);
2494 if (o->inherits("QGraphicsItem"))
2495 qWarning("Cannot add a QtQuick 1.0 item (%s) into a QtQuick 2.0 scene!", o->metaObject()->className());
2497 // XXX todo - do we really want this behavior?
2503 \qmlproperty list<Object> QtQuick2::Item::data
2506 The data property allows you to freely mix visual children and resources
2507 in an item. If you assign a visual item to the data list it becomes
2508 a child and if you assign any other object type, it is added as a resource.
2532 data is a behind-the-scenes property: you should never need to explicitly
2536 int QQuickItemPrivate::data_count(QQmlListProperty<QObject> *prop)
2543 QObject *QQuickItemPrivate::data_at(QQmlListProperty<QObject> *prop, int i)
2551 void QQuickItemPrivate::data_clear(QQmlListProperty<QObject> *prop)
2557 QObject *QQuickItemPrivate::resources_at(QQmlListProperty<QObject> *prop, int index)
2559 const QObjectList children = prop->object->children();
2560 if (index < children.count())
2561 return children.at(index);
2566 void QQuickItemPrivate::resources_append(QQmlListProperty<QObject> *prop, QObject *o)
2568 // XXX todo - do we really want this behavior?
2569 o->setParent(prop->object);
2572 int QQuickItemPrivate::resources_count(QQmlListProperty<QObject> *prop)
2574 return prop->object->children().count();
2577 void QQuickItemPrivate::resources_clear(QQmlListProperty<QObject> *prop)
2579 // XXX todo - do we really want this behavior?
2580 const QObjectList children = prop->object->children();
2581 for (int index = 0; index < children.count(); index++)
2582 children.at(index)->setParent(0);
2585 QQuickItem *QQuickItemPrivate::children_at(QQmlListProperty<QQuickItem> *prop, int index)
2587 QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2588 if (index >= p->childItems.count() || index < 0)
2591 return p->childItems.at(index);
2594 void QQuickItemPrivate::children_append(QQmlListProperty<QQuickItem> *prop, QQuickItem *o)
2599 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2600 if (o->parentItem() == that)
2601 o->setParentItem(0);
2603 o->setParentItem(that);
2606 int QQuickItemPrivate::children_count(QQmlListProperty<QQuickItem> *prop)
2608 QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2609 return p->childItems.count();
2612 void QQuickItemPrivate::children_clear(QQmlListProperty<QQuickItem> *prop)
2614 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2615 QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2616 while (!p->childItems.isEmpty())
2617 p->childItems.at(0)->setParentItem(0);
2620 void QQuickItemPrivate::visibleChildren_append(QQmlListProperty<QQuickItem>*, QQuickItem *self)
2623 qmlInfo(self) << "QQuickItem: visibleChildren property is readonly and cannot be assigned to.";
2626 int QQuickItemPrivate::visibleChildren_count(QQmlListProperty<QQuickItem> *prop)
2628 QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2629 int visibleCount = 0;
2630 int c = p->childItems.count();
2632 if (p->childItems.at(c)->isVisible()) visibleCount++;
2635 return visibleCount;
2638 QQuickItem *QQuickItemPrivate::visibleChildren_at(QQmlListProperty<QQuickItem> *prop, int index)
2640 QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2641 const int childCount = p->childItems.count();
2642 if (index >= childCount || index < 0)
2645 int visibleCount = -1;
2646 for (int i = 0; i < childCount; i++) {
2647 if (p->childItems.at(i)->isVisible()) visibleCount++;
2648 if (visibleCount == index) return p->childItems.at(i);
2653 int QQuickItemPrivate::transform_count(QQmlListProperty<QQuickTransform> *prop)
2655 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2656 QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2658 return p->transforms.count();
2661 void QQuickTransform::appendToItem(QQuickItem *item)
2663 Q_D(QQuickTransform);
2667 QQuickItemPrivate *p = QQuickItemPrivate::get(item);
2669 if (!d->items.isEmpty() && !p->transforms.isEmpty() && p->transforms.contains(this)) {
2670 p->transforms.removeOne(this);
2671 p->transforms.append(this);
2673 p->transforms.append(this);
2674 d->items.append(item);
2677 p->dirty(QQuickItemPrivate::Transform);
2680 void QQuickTransform::prependToItem(QQuickItem *item)
2682 Q_D(QQuickTransform);
2686 QQuickItemPrivate *p = QQuickItemPrivate::get(item);
2688 if (!d->items.isEmpty() && !p->transforms.isEmpty() && p->transforms.contains(this)) {
2689 p->transforms.removeOne(this);
2690 p->transforms.prepend(this);
2692 p->transforms.prepend(this);
2693 d->items.append(item);
2696 p->dirty(QQuickItemPrivate::Transform);
2699 void QQuickItemPrivate::transform_append(QQmlListProperty<QQuickTransform> *prop, QQuickTransform *transform)
2704 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2705 transform->appendToItem(that);
2708 QQuickTransform *QQuickItemPrivate::transform_at(QQmlListProperty<QQuickTransform> *prop, int idx)
2710 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2711 QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2713 if (idx < 0 || idx >= p->transforms.count())
2716 return p->transforms.at(idx);
2719 void QQuickItemPrivate::transform_clear(QQmlListProperty<QQuickTransform> *prop)
2721 QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2722 QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2724 for (int ii = 0; ii < p->transforms.count(); ++ii) {
2725 QQuickTransform *t = p->transforms.at(ii);
2726 QQuickTransformPrivate *tp = QQuickTransformPrivate::get(t);
2727 tp->items.removeOne(that);
2730 p->transforms.clear();
2732 p->dirty(QQuickItemPrivate::Transform);
2736 \property QQuickItem::childrenRect
2737 \brief Specifies the geometry of an item's children
2739 This property holds the (collective) position and size of the item's children.
2743 \qmlproperty real QtQuick2::Item::x
2744 \qmlproperty real QtQuick2::Item::y
2745 \qmlproperty real QtQuick2::Item::width
2746 \qmlproperty real QtQuick2::Item::height
2748 Defines the item's position and size relative to its parent.
2751 Item { x: 100; y: 100; width: 100; height: 100 }
2756 \qmlproperty real QtQuick2::Item::z
2758 Sets the stacking order of sibling items. By default the stacking order is 0.
2760 Items with a higher stacking value are drawn on top of siblings with a
2761 lower stacking order. Items with the same stacking value are drawn
2762 bottom up in the order they appear. Items with a negative stacking
2763 value are drawn under their parent's content.
2765 The following example shows the various effects of stacking order.
2769 \li \image declarative-item_stacking1.png
2770 \li Same \c z - later children above earlier children:
2775 width: 100; height: 100
2779 x: 50; y: 50; width: 100; height: 100
2784 \li \image declarative-item_stacking2.png
2785 \li Higher \c z on top:
2791 width: 100; height: 100
2795 x: 50; y: 50; width: 100; height: 100
2800 \li \image declarative-item_stacking3.png
2801 \li Same \c z - children above parents:
2806 width: 100; height: 100
2809 x: 50; y: 50; width: 100; height: 100
2815 \li \image declarative-item_stacking4.png
2816 \li Lower \c z below:
2821 width: 100; height: 100
2825 x: 50; y: 50; width: 100; height: 100
2834 \qmlproperty bool QtQuick2::Item::visible
2836 This property holds whether the item is visible. By default this is true.
2838 Setting this property directly affects the \c visible value of child
2839 items. When set to \c false, the \c visible values of all child items also
2840 become \c false. When set to \c true, the \c visible values of child items
2841 are returned to \c true, unless they have explicitly been set to \c false.
2843 (Because of this flow-on behavior, using the \c visible property may not
2844 have the intended effect if a property binding should only respond to
2845 explicit property changes. In such cases it may be better to use the
2846 \l opacity property instead.)
2848 If this property is set to \c false, the item will no longer receive mouse
2849 events, but will continue to receive key events and will retain the keyboard
2850 \l focus if it has been set. (In contrast, setting the \l enabled property
2851 to \c false stops both mouse and keyboard events, and also removes focus
2854 \note This property's value is only affected by changes to this property or
2855 the parent's \c visible property. It does not change, for example, if this
2856 item moves off-screen, or if the \l opacity changes to 0.
2860 \qmlproperty bool QtQuick2::Item::enabled
2862 This property holds whether the item receives mouse and keyboard events.
2863 By default this is true.
2865 Setting this property directly affects the \c enabled value of child
2866 items. When set to \c false, the \c enabled values of all child items also
2867 become \c false. When set to \c true, the \c enabled values of child items
2868 are returned to \c true, unless they have explicitly been set to \c false.
2870 Setting this property to \c false automatically causes \l activeFocus to be
2871 set to \c false, and this item will longer receive keyboard events.
2875 \qmlproperty AnchorLine QtQuick2::Item::anchors.top
2876 \qmlproperty AnchorLine QtQuick2::Item::anchors.bottom
2877 \qmlproperty AnchorLine QtQuick2::Item::anchors.left
2878 \qmlproperty AnchorLine QtQuick2::Item::anchors.right
2879 \qmlproperty AnchorLine QtQuick2::Item::anchors.horizontalCenter
2880 \qmlproperty AnchorLine QtQuick2::Item::anchors.verticalCenter
2881 \qmlproperty AnchorLine QtQuick2::Item::anchors.baseline
2883 \qmlproperty Item QtQuick2::Item::anchors.fill
2884 \qmlproperty Item QtQuick2::Item::anchors.centerIn
2886 \qmlproperty real QtQuick2::Item::anchors.margins
2887 \qmlproperty real QtQuick2::Item::anchors.topMargin
2888 \qmlproperty real QtQuick2::Item::anchors.bottomMargin
2889 \qmlproperty real QtQuick2::Item::anchors.leftMargin
2890 \qmlproperty real QtQuick2::Item::anchors.rightMargin
2891 \qmlproperty real QtQuick2::Item::anchors.horizontalCenterOffset
2892 \qmlproperty real QtQuick2::Item::anchors.verticalCenterOffset
2893 \qmlproperty real QtQuick2::Item::anchors.baselineOffset
2895 \qmlproperty bool QtQuick2::Item::anchors.alignWhenCentered
2897 Anchors provide a way to position an item by specifying its
2898 relationship with other items.
2900 Margins apply to top, bottom, left, right, and fill anchors.
2901 The \c anchors.margins property can be used to set all of the various margins at once, to the same value.
2902 It will not override a specific margin that has been previously set; to clear an explicit margin
2903 set it's value to \c undefined.
2904 Note that margins are anchor-specific and are not applied if an item does not
2907 Offsets apply for horizontal center, vertical center, and baseline anchors.
2911 \li \image declarative-anchors_example.png
2912 \li Text anchored to Image, horizontally centered and vertically below, with a margin.
2921 anchors.horizontalCenter: pic.horizontalCenter
2922 anchors.top: pic.bottom
2923 anchors.topMargin: 5
2929 \li \image declarative-anchors_example2.png
2931 Left of Text anchored to right of Image, with a margin. The y
2932 property of both defaults to 0.
2942 anchors.left: pic.right
2943 anchors.leftMargin: 5
2950 \c anchors.fill provides a convenient way for one item to have the
2951 same geometry as another item, and is equivalent to connecting all
2952 four directional anchors.
2954 To clear an anchor value, set it to \c undefined.
2956 \c anchors.alignWhenCentered (default true) forces centered anchors to align to a
2957 whole pixel, i.e. if the item being centered has an odd width/height the item
2958 will be positioned on a whole pixel rather than being placed on a half-pixel.
2959 This ensures the item is painted crisply. There are cases where this is not
2960 desirable, for example when rotating the item jitters may be apparent as the
2963 \note You can only anchor an item to siblings or a parent.
2965 For more information see \l {anchor-layout}{Anchor Layouts}.
2969 \property QQuickItem::baselineOffset
2970 \brief Speciifies the position of the item's baseline in local coordinates
2972 The baseline of a \l Text item is the imaginary line on which the text
2973 sits. Controls containing text usually set their baseline to the
2974 baseline of their text.
2976 For non-text items, a default baseline offset of 0 is used.
2978 QQuickAnchors *QQuickItemPrivate::anchors() const
2981 Q_Q(const QQuickItem);
2982 _anchors = new QQuickAnchors(const_cast<QQuickItem *>(q));
2983 if (!componentComplete)
2984 _anchors->classBegin();
2989 void QQuickItemPrivate::siblingOrderChanged()
2992 for (int ii = 0; ii < changeListeners.count(); ++ii) {
2993 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
2994 if (change.types & QQuickItemPrivate::SiblingOrder) {
2995 change.listener->itemSiblingOrderChanged(q);
3000 QQmlListProperty<QObject> QQuickItemPrivate::data()
3002 return QQmlListProperty<QObject>(q_func(), 0, QQuickItemPrivate::data_append,
3003 QQuickItemPrivate::data_count,
3004 QQuickItemPrivate::data_at,
3005 QQuickItemPrivate::data_clear);
3008 QRectF QQuickItem::childrenRect()
3011 if (!d->extra.isAllocated() || !d->extra->contents) {
3012 d->extra.value().contents = new QQuickContents(this);
3013 if (d->componentComplete)
3014 d->extra->contents->complete();
3016 return d->extra->contents->rectF();
3019 QList<QQuickItem *> QQuickItem::childItems() const
3021 Q_D(const QQuickItem);
3022 return d->childItems;
3025 bool QQuickItem::clip() const
3027 return flags() & ItemClipsChildrenToShape;
3030 void QQuickItem::setClip(bool c)
3035 setFlag(ItemClipsChildrenToShape, c);
3037 emit clipChanged(c);
3042 This function is called to handle this item's changes in
3043 geometry from \a oldGeometry to \a newGeometry. If the two
3044 geometries are the same, it doesn't do anything.
3046 Derived classes must call the base class method within their implementation.
3048 void QQuickItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
3053 QQuickAnchorsPrivate::get(d->_anchors)->updateMe();
3055 bool xChange = (newGeometry.x() != oldGeometry.x());
3056 bool yChange = (newGeometry.y() != oldGeometry.y());
3057 bool widthChange = (newGeometry.width() != oldGeometry.width());
3058 bool heightChange = (newGeometry.height() != oldGeometry.height());
3060 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
3061 const QQuickItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
3062 if (change.types & QQuickItemPrivate::Geometry) {
3063 if (change.gTypes == QQuickItemPrivate::GeometryChange) {
3064 change.listener->itemGeometryChanged(this, newGeometry, oldGeometry);
3065 } else if ((xChange && (change.gTypes & QQuickItemPrivate::XChange)) ||
3066 (yChange && (change.gTypes & QQuickItemPrivate::YChange)) ||
3067 (widthChange && (change.gTypes & QQuickItemPrivate::WidthChange)) ||
3068 (heightChange && (change.gTypes & QQuickItemPrivate::HeightChange))) {
3069 change.listener->itemGeometryChanged(this, newGeometry, oldGeometry);
3079 emit widthChanged();
3081 emit heightChanged();
3085 Called by the rendering thread, as a result of
3086 QQuickItem::update(), when it is time to sync the state of the QML
3087 objects with the scene graph objects.
3089 The function should return the root of the scene graph subtree for
3090 this item. Most implementations will return a single
3091 QSGGeometryNode containing the visual representation of this item.
3092 \a oldNode is the node that was returned the last time the
3093 function was called.
3096 QSGNode *MyItem::updatePaintNode(QSGNode *node, UpdatePaintNodeData *)
3098 QSGSimpleRectNode *n = static_cast<QSGSimpleRectNode *>(node);
3100 n = new QSGSimpleRectNode();
3101 n->setColor(Qt::red);
3103 n->setRect(boundingRect());
3108 The main thread is blocked while this function is executed so it is safe to read
3109 values from the QQuickItem instance and other objects in the main thread.
3111 If no call to QQuickItem::updatePaintNode() result in actual scene graph
3112 changes, like QSGNode::markDirty() or adding and removing nodes, then
3113 the underlying implementation may decide to not render the scene again as
3114 the visual outcome is identical.
3116 \warning It is crucial that OpenGL operations and interaction with
3117 the scene graph happens exclusively on the rendering thread,
3118 primarily during the QQuickItem::updatePaintNode() call. The best
3119 rule of thumb is to only use classes with the "QSG" prefix inside
3120 the QQuickItem::updatePaintNode() function.
3122 \sa QSGMaterial, QSGSimpleMaterial, QSGGeometryNode, QSGGeometry,
3123 QSGFlatColorMaterial, QSGTextureMaterial, QSGNode::markDirty()
3126 QSGNode *QQuickItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
3133 This function is called when the item's scene graph resources are no longer needed.
3134 It allows items to free its resources, for instance textures, that are not owned by scene graph
3135 nodes. Note that scene graph nodes are managed by QQuickWindow and should not be deleted by
3136 this function. Scene graph resources are no longer needed when the parent is set to null and
3137 the item is not used by any \l ShaderEffect or \l ShaderEffectSource.
3139 This function is called from the main thread. Therefore, resources used by the scene graph
3140 should not be deleted directly, but by calling \l QObject::deleteLater().
3142 \note The item destructor still needs to free its scene graph resources if not already done.
3145 void QQuickItem::releaseResources()
3149 QSGTransformNode *QQuickItemPrivate::createTransformNode()
3151 return new QSGTransformNode;
3154 void QQuickItem::updatePolish()
3158 void QQuickItemPrivate::addItemChangeListener(QQuickItemChangeListener *listener, ChangeTypes types)
3160 changeListeners.append(ChangeListener(listener, types));
3163 void QQuickItemPrivate::removeItemChangeListener(QQuickItemChangeListener *listener, ChangeTypes types)
3165 ChangeListener change(listener, types);
3166 changeListeners.removeOne(change);
3169 void QQuickItemPrivate::updateOrAddGeometryChangeListener(QQuickItemChangeListener *listener, GeometryChangeTypes types)
3171 ChangeListener change(listener, types);
3172 int index = changeListeners.find(change);
3174 changeListeners[index].gTypes = change.gTypes; //we may have different GeometryChangeTypes
3176 changeListeners.append(change);
3179 void QQuickItemPrivate::updateOrRemoveGeometryChangeListener(QQuickItemChangeListener *listener,
3180 GeometryChangeTypes types)
3182 ChangeListener change(listener, types);
3183 if (types == NoChange) {
3184 changeListeners.removeOne(change);
3186 int index = changeListeners.find(change);
3188 changeListeners[index].gTypes = change.gTypes; //we may have different GeometryChangeTypes
3192 void QQuickItem::keyPressEvent(QKeyEvent *event)
3197 void QQuickItem::keyReleaseEvent(QKeyEvent *event)
3202 void QQuickItem::inputMethodEvent(QInputMethodEvent *event)
3207 void QQuickItem::focusInEvent(QFocusEvent *)
3209 #ifndef QT_NO_ACCESSIBILITY
3210 QAccessibleEvent ev(this, QAccessible::Focus);
3211 QAccessible::updateAccessibility(&ev);
3215 void QQuickItem::focusOutEvent(QFocusEvent *)
3219 void QQuickItem::mousePressEvent(QMouseEvent *event)
3224 void QQuickItem::mouseMoveEvent(QMouseEvent *event)
3229 void QQuickItem::mouseReleaseEvent(QMouseEvent *event)
3234 void QQuickItem::mouseDoubleClickEvent(QMouseEvent *)
3238 void QQuickItem::mouseUngrabEvent()
3243 void QQuickItem::touchUngrabEvent()
3248 void QQuickItem::wheelEvent(QWheelEvent *event)
3253 void QQuickItem::touchEvent(QTouchEvent *event)
3258 void QQuickItem::hoverEnterEvent(QHoverEvent *event)
3263 void QQuickItem::hoverMoveEvent(QHoverEvent *event)
3268 void QQuickItem::hoverLeaveEvent(QHoverEvent *event)
3273 #ifndef QT_NO_DRAGANDDROP
3274 void QQuickItem::dragEnterEvent(QDragEnterEvent *event)
3279 void QQuickItem::dragMoveEvent(QDragMoveEvent *event)
3285 void QQuickItem::dragLeaveEvent(QDragLeaveEvent *event)
3291 void QQuickItem::dropEvent(QDropEvent *event)
3295 #endif // QT_NO_DRAGANDDROP
3297 bool QQuickItem::childMouseEventFilter(QQuickItem *, QEvent *)
3302 void QQuickItem::windowDeactivateEvent()
3304 foreach (QQuickItem* item, childItems()) {
3305 item->windowDeactivateEvent();
3309 QVariant QQuickItem::inputMethodQuery(Qt::InputMethodQuery query) const
3311 Q_D(const QQuickItem);
3316 v = (bool)(flags() & ItemAcceptsInputMethod);
3319 case Qt::ImCursorRectangle:
3321 case Qt::ImCursorPosition:
3322 case Qt::ImSurroundingText:
3323 case Qt::ImCurrentSelection:
3324 case Qt::ImMaximumTextLength:
3325 case Qt::ImAnchorPosition:
3326 case Qt::ImPreferredLanguage:
3327 if (d->extra.isAllocated() && d->extra->keyHandler)
3328 v = d->extra->keyHandler->inputMethodQuery(query);
3336 QQuickAnchorLine QQuickItemPrivate::left() const
3338 Q_Q(const QQuickItem);
3339 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Left);
3342 QQuickAnchorLine QQuickItemPrivate::right() const
3344 Q_Q(const QQuickItem);
3345 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Right);
3348 QQuickAnchorLine QQuickItemPrivate::horizontalCenter() const
3350 Q_Q(const QQuickItem);
3351 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::HCenter);
3354 QQuickAnchorLine QQuickItemPrivate::top() const
3356 Q_Q(const QQuickItem);
3357 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Top);
3360 QQuickAnchorLine QQuickItemPrivate::bottom() const
3362 Q_Q(const QQuickItem);
3363 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Bottom);
3366 QQuickAnchorLine QQuickItemPrivate::verticalCenter() const
3368 Q_Q(const QQuickItem);
3369 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::VCenter);
3372 QQuickAnchorLine QQuickItemPrivate::baseline() const
3374 Q_Q(const QQuickItem);
3375 return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Baseline);
3378 qreal QQuickItem::baselineOffset() const
3380 Q_D(const QQuickItem);
3381 if (d->baselineOffsetValid) {
3382 return d->baselineOffset;
3388 void QQuickItem::setBaselineOffset(qreal offset)
3391 if (offset == d->baselineOffset)
3394 d->baselineOffset = offset;
3395 d->baselineOffsetValid = true;
3397 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
3398 const QQuickItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
3399 if (change.types & QQuickItemPrivate::Geometry) {
3400 QQuickAnchorsPrivate *anchor = change.listener->anchorPrivate();
3402 anchor->updateVerticalAnchors();
3406 if (d->_anchors && (d->_anchors->usedAnchors() & QQuickAnchors::BaselineAnchor))
3407 QQuickAnchorsPrivate::get(d->_anchors)->updateVerticalAnchors();
3409 emit baselineOffsetChanged(offset);
3414 * Schedules a call to updatePaintNode() for this item.
3416 * The call to QQuickItem::updatePaintNode() will always happen if the
3417 * item is showing in a QQuickWindow.
3419 * Only items which specifies QQuickItem::ItemHasContents are allowed
3420 * to call QQuickItem::update().
3422 void QQuickItem::update()
3425 Q_ASSERT(flags() & ItemHasContents);
3426 d->dirty(QQuickItemPrivate::Content);
3429 void QQuickItem::polish()
3432 if (!d->polishScheduled) {
3433 d->polishScheduled = true;
3435 QQuickWindowPrivate *p = QQuickWindowPrivate::get(d->window);
3436 bool maybeupdate = p->itemsToPolish.isEmpty();
3437 p->itemsToPolish.insert(this);
3438 if (maybeupdate) d->window->maybeUpdate();
3444 \qmlmethod object QtQuick2::Item::mapFromItem(Item item, real x, real y)
3445 \qmlmethod object QtQuick2::Item::mapFromItem(Item item, real x, real y, real width, real height)
3447 Maps the point (\a x, \a y) or rect (\a x, \a y, \a width, \a height), which is in \a
3448 item's coordinate system, to this item's coordinate system, and returns an object with \c x and
3449 \c y (and optionally \c width and \c height) properties matching the mapped coordinate.
3451 If \a item is a \c null value, this maps the point or rect from the coordinate system of
3454 void QQuickItem::mapFromItem(QQmlV8Function *args) const
3456 if (args->Length() != 0) {
3457 v8::Local<v8::Value> item = (*args)[0];
3458 QV8Engine *engine = args->engine();
3460 QQuickItem *itemObj = 0;
3461 if (!item->IsNull())
3462 itemObj = qobject_cast<QQuickItem*>(engine->toQObject(item));
3464 if (!itemObj && !item->IsNull()) {
3465 qmlInfo(this) << "mapFromItem() given argument \"" << engine->toString(item->ToString())
3466 << "\" which is neither null nor an Item";
3470 v8::Local<v8::Object> rv = v8::Object::New();
3471 args->returnValue(rv);
3473 qreal x = (args->Length() > 1)?(*args)[1]->NumberValue():0;
3474 qreal y = (args->Length() > 2)?(*args)[2]->NumberValue():0;
3476 if (args->Length() > 3) {
3477 qreal w = (*args)[3]->NumberValue();
3478 qreal h = (args->Length() > 4)?(*args)[4]->NumberValue():0;
3480 QRectF r = mapRectFromItem(itemObj, QRectF(x, y, w, h));
3482 rv->Set(v8::String::New("x"), v8::Number::New(r.x()));
3483 rv->Set(v8::String::New("y"), v8::Number::New(r.y()));
3484 rv->Set(v8::String::New("width"), v8::Number::New(r.width()));
3485 rv->Set(v8::String::New("height"), v8::Number::New(r.height()));
3487 QPointF p = mapFromItem(itemObj, QPointF(x, y));
3489 rv->Set(v8::String::New("x"), v8::Number::New(p.x()));
3490 rv->Set(v8::String::New("y"), v8::Number::New(p.y()));
3495 QTransform QQuickItem::itemTransform(QQuickItem *other, bool *ok) const
3497 Q_D(const QQuickItem);
3499 // XXX todo - we need to be able to handle common parents better and detect
3503 QTransform t = d->itemToWindowTransform();
3504 if (other) t *= QQuickItemPrivate::get(other)->windowToItemTransform();
3510 \qmlmethod object QtQuick2::Item::mapToItem(Item item, real x, real y)
3511 \qmlmethod object QtQuick2::Item::mapToItem(Item item, real x, real y, real width, real height)
3513 Maps the point (\a x, \a y) or rect (\a x, \a y, \a width, \a height), which is in this
3514 item's coordinate system, to \a item's coordinate system, and returns an object with \c x and
3515 \c y (and optionally \c width and \c height) properties matching the mapped coordinate.
3517 If \a item is a \c null value, this maps the point or rect to the coordinate system of the
3520 void QQuickItem::mapToItem(QQmlV8Function *args) const
3522 if (args->Length() != 0) {
3523 v8::Local<v8::Value> item = (*args)[0];
3524 QV8Engine *engine = args->engine();
3526 QQuickItem *itemObj = 0;
3527 if (!item->IsNull())
3528 itemObj = qobject_cast<QQuickItem*>(engine->toQObject(item));
3530 if (!itemObj && !item->IsNull()) {
3531 qmlInfo(this) << "mapToItem() given argument \"" << engine->toString(item->ToString())
3532 << "\" which is neither null nor an Item";
3536 v8::Local<v8::Object> rv = v8::Object::New();
3537 args->returnValue(rv);
3539 qreal x = (args->Length() > 1)?(*args)[1]->NumberValue():0;
3540 qreal y = (args->Length() > 2)?(*args)[2]->NumberValue():0;
3542 if (args->Length() > 3) {
3543 qreal w = (*args)[3]->NumberValue();
3544 qreal h = (args->Length() > 4)?(*args)[4]->NumberValue():0;
3546 QRectF r = mapRectToItem(itemObj, QRectF(x, y, w, h));
3548 rv->Set(v8::String::New("x"), v8::Number::New(r.x()));
3549 rv->Set(v8::String::New("y"), v8::Number::New(r.y()));
3550 rv->Set(v8::String::New("width"), v8::Number::New(r.width()));
3551 rv->Set(v8::String::New("height"), v8::Number::New(r.height()));
3553 QPointF p = mapToItem(itemObj, QPointF(x, y));
3555 rv->Set(v8::String::New("x"), v8::Number::New(p.x()));
3556 rv->Set(v8::String::New("y"), v8::Number::New(p.y()));
3561 void QQuickItem::forceActiveFocus()
3564 QQuickItem *parent = parentItem();
3566 if (parent->flags() & QQuickItem::ItemIsFocusScope) {
3567 parent->setFocus(true);
3569 parent = parent->parentItem();
3573 QQuickItem *QQuickItem::childAt(qreal x, qreal y) const
3575 // XXX todo - should this include transform etc.?
3576 const QList<QQuickItem *> children = childItems();
3577 for (int i = children.count()-1; i >= 0; --i) {
3578 QQuickItem *child = children.at(i);
3579 if (child->isVisible() && child->x() <= x
3580 && child->x() + child->width() >= x
3582 && child->y() + child->height() >= y)
3588 QQmlListProperty<QObject> QQuickItemPrivate::resources()
3590 return QQmlListProperty<QObject>(q_func(), 0, QQuickItemPrivate::resources_append,
3591 QQuickItemPrivate::resources_count,
3592 QQuickItemPrivate::resources_at,
3593 QQuickItemPrivate::resources_clear);
3596 QQmlListProperty<QQuickItem> QQuickItemPrivate::children()
3598 return QQmlListProperty<QQuickItem>(q_func(), 0, QQuickItemPrivate::children_append,
3599 QQuickItemPrivate::children_count,
3600 QQuickItemPrivate::children_at,
3601 QQuickItemPrivate::children_clear);
3606 \qmlproperty real QtQuick2::Item::visibleChildren
3607 This read-only property lists all of the item's children that are currently visible.
3608 Note that a child's visibility may have changed explicitly, or because the visibility
3609 of this (it's parent) item or another grandparent changed.
3611 QQmlListProperty<QQuickItem> QQuickItemPrivate::visibleChildren()
3613 return QQmlListProperty<QQuickItem>(q_func(), 0, QQuickItemPrivate::visibleChildren_append,
3614 QQuickItemPrivate::visibleChildren_count,
3615 QQuickItemPrivate::visibleChildren_at);
3619 QQmlListProperty<QQuickState> QQuickItemPrivate::states()
3621 return _states()->statesProperty();
3624 QQmlListProperty<QQuickTransition> QQuickItemPrivate::transitions()
3626 return _states()->transitionsProperty();
3629 QString QQuickItemPrivate::state() const
3634 return _stateGroup->state();
3637 void QQuickItemPrivate::setState(const QString &state)
3639 _states()->setState(state);
3642 QString QQuickItem::state() const
3644 Q_D(const QQuickItem);
3648 void QQuickItem::setState(const QString &state)
3654 QQmlListProperty<QQuickTransform> QQuickItem::transform()
3656 return QQmlListProperty<QQuickTransform>(this, 0, QQuickItemPrivate::transform_append,
3657 QQuickItemPrivate::transform_count,
3658 QQuickItemPrivate::transform_at,
3659 QQuickItemPrivate::transform_clear);
3664 Derived classes should call the base class method before adding their own action to
3665 perform at classBegin.
3667 void QQuickItem::classBegin()
3670 d->componentComplete = false;
3672 d->_stateGroup->classBegin();
3674 d->_anchors->classBegin();
3675 if (d->extra.isAllocated() && d->extra->layer)
3676 d->extra->layer->classBegin();
3681 Derived classes should call the base class method before adding their own actions to
3682 perform at componentComplete.
3684 void QQuickItem::componentComplete()
3687 d->componentComplete = true;
3689 d->_stateGroup->componentComplete();
3691 d->_anchors->componentComplete();
3692 QQuickAnchorsPrivate::get(d->_anchors)->updateOnComplete();
3695 if (d->extra.isAllocated() && d->extra->layer)
3696 d->extra->layer->componentComplete();
3698 if (d->extra.isAllocated() && d->extra->keyHandler)
3699 d->extra->keyHandler->componentComplete();
3701 if (d->extra.isAllocated() && d->extra->contents)
3702 d->extra->contents->complete();
3704 if (d->window && d->dirtyAttributes) {
3705 d->addToDirtyList();
3706 QQuickWindowPrivate::get(d->window)->dirtyItem(this);
3710 QQuickStateGroup *QQuickItemPrivate::_states()
3714 _stateGroup = new QQuickStateGroup;
3715 if (!componentComplete)
3716 _stateGroup->classBegin();
3717 qmlobject_connect(_stateGroup, QQuickStateGroup, SIGNAL(stateChanged(QString)),
3718 q, QQuickItem, SIGNAL(stateChanged(QString)))
3724 QPointF QQuickItemPrivate::computeTransformOrigin() const
3728 case QQuickItem::TopLeft:
3729 return QPointF(0, 0);
3730 case QQuickItem::Top:
3731 return QPointF(width / 2., 0);
3732 case QQuickItem::TopRight:
3733 return QPointF(width, 0);
3734 case QQuickItem::Left:
3735 return QPointF(0, height / 2.);
3736 case QQuickItem::Center:
3737 return QPointF(width / 2., height / 2.);
3738 case QQuickItem::Right:
3739 return QPointF(width, height / 2.);
3740 case QQuickItem::BottomLeft:
3741 return QPointF(0, height);
3742 case QQuickItem::Bottom:
3743 return QPointF(width / 2., height);
3744 case QQuickItem::BottomRight:
3745 return QPointF(width, height);
3749 void QQuickItemPrivate::transformChanged()
3751 if (extra.isAllocated() && extra->layer)
3752 extra->layer->updateMatrix();
3755 void QQuickItemPrivate::deliverKeyEvent(QKeyEvent *e)
3759 Q_ASSERT(e->isAccepted());
3760 if (extra.isAllocated() && extra->keyHandler) {
3761 if (e->type() == QEvent::KeyPress)
3762 extra->keyHandler->keyPressed(e, false);
3764 extra->keyHandler->keyReleased(e, false);
3766 if (e->isAccepted())
3772 if (e->type() == QEvent::KeyPress)
3773 q->keyPressEvent(e);
3775 q->keyReleaseEvent(e);
3777 if (e->isAccepted())
3780 if (extra.isAllocated() && extra->keyHandler) {
3783 if (e->type() == QEvent::KeyPress)
3784 extra->keyHandler->keyPressed(e, true);
3786 extra->keyHandler->keyReleased(e, true);
3790 void QQuickItemPrivate::deliverInputMethodEvent(QInputMethodEvent *e)
3794 Q_ASSERT(e->isAccepted());
3795 if (extra.isAllocated() && extra->keyHandler) {
3796 extra->keyHandler->inputMethodEvent(e, false);
3798 if (e->isAccepted())
3804 q->inputMethodEvent(e);
3806 if (e->isAccepted())
3809 if (extra.isAllocated() && extra->keyHandler) {
3812 extra->keyHandler->inputMethodEvent(e, true);
3816 void QQuickItemPrivate::deliverFocusEvent(QFocusEvent *e)
3820 if (e->type() == QEvent::FocusIn) {
3823 q->focusOutEvent(e);
3827 void QQuickItemPrivate::deliverMouseEvent(QMouseEvent *e)
3831 Q_ASSERT(e->isAccepted());
3833 switch (e->type()) {
3835 Q_ASSERT(!"Unknown event type");
3836 case QEvent::MouseMove:
3837 q->mouseMoveEvent(e);
3839 case QEvent::MouseButtonPress:
3840 q->mousePressEvent(e);
3842 case QEvent::MouseButtonRelease:
3843 q->mouseReleaseEvent(e);
3845 case QEvent::MouseButtonDblClick:
3846 q->mouseDoubleClickEvent(e);
3851 void QQuickItemPrivate::deliverWheelEvent(QWheelEvent *e)
3857 void QQuickItemPrivate::deliverTouchEvent(QTouchEvent *e)
3863 void QQuickItemPrivate::deliverHoverEvent(QHoverEvent *e)
3866 switch (e->type()) {
3868 Q_ASSERT(!"Unknown event type");
3869 case QEvent::HoverEnter:
3870 q->hoverEnterEvent(e);
3872 case QEvent::HoverLeave:
3873 q->hoverLeaveEvent(e);
3875 case QEvent::HoverMove:
3876 q->hoverMoveEvent(e);
3881 #ifndef QT_NO_DRAGANDDROP
3882 void QQuickItemPrivate::deliverDragEvent(QEvent *e)
3885 switch (e->type()) {
3887 Q_ASSERT(!"Unknown event type");
3888 case QEvent::DragEnter:
3889 q->dragEnterEvent(static_cast<QDragEnterEvent *>(e));
3891 case QEvent::DragLeave:
3892 q->dragLeaveEvent(static_cast<QDragLeaveEvent *>(e));
3894 case QEvent::DragMove:
3895 q->dragMoveEvent(static_cast<QDragMoveEvent *>(e));
3898 q->dropEvent(static_cast<QDropEvent *>(e));
3902 #endif // QT_NO_DRAGANDDROP
3904 void QQuickItem::itemChange(ItemChange change, const ItemChangeData &value)
3911 Notify input method on updated query values if needed. \a indicates changed attributes.
3913 void QQuickItem::updateInputMethod(Qt::InputMethodQueries queries)
3915 if (hasActiveFocus())
3916 qApp->inputMethod()->update(queries);
3920 // XXX todo - do we want/need this anymore?
3921 QRectF QQuickItem::boundingRect() const
3923 Q_D(const QQuickItem);
3924 return QRectF(0, 0, d->width, d->height);
3928 QRectF QQuickItem::clipRect() const
3930 Q_D(const QQuickItem);
3931 return QRectF(0, 0, d->width, d->height);
3935 QQuickItem::TransformOrigin QQuickItem::transformOrigin() const
3937 Q_D(const QQuickItem);
3941 void QQuickItem::setTransformOrigin(TransformOrigin origin)
3944 if (origin == d->origin())
3947 d->extra.value().origin = origin;
3948 d->dirty(QQuickItemPrivate::TransformOrigin);
3950 emit transformOriginChanged(d->origin());
3953 QPointF QQuickItem::transformOriginPoint() const
3955 Q_D(const QQuickItem);
3956 if (d->extra.isAllocated() && !d->extra->userTransformOriginPoint.isNull())
3957 return d->extra->userTransformOriginPoint;
3958 return d->computeTransformOrigin();
3961 void QQuickItem::setTransformOriginPoint(const QPointF &point)
3964 if (d->extra.value().userTransformOriginPoint == point)
3967 d->extra->userTransformOriginPoint = point;
3968 d->dirty(QQuickItemPrivate::TransformOrigin);
3971 qreal QQuickItem::z() const
3973 Q_D(const QQuickItem);
3977 void QQuickItem::setZ(qreal v)
3983 d->extra.value().z = v;
3985 d->dirty(QQuickItemPrivate::ZValue);
3986 if (d->parentItem) {
3987 QQuickItemPrivate::get(d->parentItem)->dirty(QQuickItemPrivate::ChildrenStackingChanged);
3988 QQuickItemPrivate::get(d->parentItem)->markSortedChildrenDirty(this);
3993 if (d->extra.isAllocated() && d->extra->layer)
3994 d->extra->layer->updateZ();
3999 \qmlproperty real QtQuick2::Item::rotation
4000 This property holds the rotation of the item in degrees clockwise.
4002 This specifies how many degrees to rotate the item around its transformOrigin.
4003 The default rotation is 0 degrees (i.e. not rotated at all).
4007 \li \image declarative-rotation.png
4012 width: 100; height: 100
4015 x: 25; y: 25; width: 50; height: 50
4022 \sa transform, Rotation
4026 \qmlproperty real QtQuick2::Item::scale
4027 This property holds the scale of the item.
4029 A scale of less than 1 means the item will be displayed smaller than
4030 normal, and a scale of greater than 1 means the item will be
4031 displayed larger than normal. A negative scale means the item will
4034 By default, items are displayed at a scale of 1 (i.e. at their
4037 Scaling is from the item's transformOrigin.
4041 \li \image declarative-scale.png
4046 width: 100; height: 100
4049 width: 25; height: 25
4053 x: 25; y: 25; width: 50; height: 50
4060 \sa transform, Scale
4064 \qmlproperty real QtQuick2::Item::opacity
4066 This property holds the opacity of the item. Opacity is specified as a
4067 number between 0 (fully transparent) and 1 (fully opaque). The default is 1.
4069 When this property is set, the specified opacity is also applied
4070 individually to child items. In almost all cases this is what you want,
4071 but in some cases it may produce undesired results. For example in the
4072 second set of rectangles below, the red rectangle has specified an opacity
4073 of 0.5, which affects the opacity of its blue child rectangle even though
4074 the child has not specified an opacity.
4078 \li \image declarative-item_opacity1.png
4084 width: 100; height: 100
4087 x: 50; y: 50; width: 100; height: 100
4093 \li \image declarative-item_opacity2.png
4100 width: 100; height: 100
4103 x: 50; y: 50; width: 100; height: 100
4110 Changing an items opacity will not affect delivery of input events. (In contrast
4111 setting \l visible property to \c false stops mouse events, and setting the
4112 \l enabled property to \c false stops mouse and keyboard events, and also removes
4113 active focus from the item.)
4117 Returns a value indicating whether mouse input should
4118 remain with this item exclusively.
4120 \sa setKeepMouseGrab()
4123 qreal QQuickItem::rotation() const
4125 Q_D(const QQuickItem);
4126 return d->rotation();
4129 void QQuickItem::setRotation(qreal r)
4132 if (d->rotation() == r)
4135 d->extra.value().rotation = r;
4137 d->dirty(QQuickItemPrivate::BasicTransform);
4139 d->itemChange(ItemRotationHasChanged, r);
4141 emit rotationChanged();
4144 qreal QQuickItem::scale() const
4146 Q_D(const QQuickItem);
4150 void QQuickItem::setScale(qreal s)
4153 if (d->scale() == s)
4156 d->extra.value().scale = s;
4158 d->dirty(QQuickItemPrivate::BasicTransform);
4160 emit scaleChanged();
4163 qreal QQuickItem::opacity() const
4165 Q_D(const QQuickItem);
4166 return d->opacity();
4169 void QQuickItem::setOpacity(qreal o)
4172 if (d->opacity() == o)
4175 d->extra.value().opacity = o;
4177 d->dirty(QQuickItemPrivate::OpacityValue);
4179 d->itemChange(ItemOpacityHasChanged, o);
4181 emit opacityChanged();
4184 bool QQuickItem::isVisible() const
4186 Q_D(const QQuickItem);
4187 return d->effectiveVisible;
4190 void QQuickItem::setVisible(bool v)
4193 if (v == d->explicitVisible)
4196 d->explicitVisible = v;
4198 d->dirty(QQuickItemPrivate::Visible);
4200 const bool childVisibilityChanged = d->setEffectiveVisibleRecur(d->calcEffectiveVisible());
4201 if (childVisibilityChanged && d->parentItem)
4202 emit d->parentItem->visibleChildrenChanged(); // signal the parent, not this!
4205 bool QQuickItem::isEnabled() const
4207 Q_D(const QQuickItem);
4208 return d->effectiveEnable;
4211 void QQuickItem::setEnabled(bool e)
4214 if (e == d->explicitEnable)
4217 d->explicitEnable = e;
4219 QQuickItem *scope = parentItem();
4220 while (scope && !scope->isFocusScope())
4221 scope = scope->parentItem();
4223 d->setEffectiveEnableRecur(scope, d->calcEffectiveEnable());
4226 bool QQuickItemPrivate::calcEffectiveVisible() const
4228 // XXX todo - Should the effective visible of an element with no parent just be the current
4229 // effective visible? This would prevent pointless re-processing in the case of an element
4230 // moving to/from a no-parent situation, but it is different from what graphics view does.
4231 return explicitVisible && (!parentItem || QQuickItemPrivate::get(parentItem)->effectiveVisible);
4234 bool QQuickItemPrivate::setEffectiveVisibleRecur(bool newEffectiveVisible)
4238 if (newEffectiveVisible && !explicitVisible) {
4239 // This item locally overrides visibility
4240 return false; // effective visibility didn't change
4243 if (newEffectiveVisible == effectiveVisible) {
4244 // No change necessary
4245 return false; // effective visibility didn't change
4248 effectiveVisible = newEffectiveVisible;
4250 if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
4253 QQuickWindowPrivate *windowPriv = QQuickWindowPrivate::get(window);
4254 if (windowPriv->mouseGrabberItem == q)
4258 bool childVisibilityChanged = false;
4259 for (int ii = 0; ii < childItems.count(); ++ii)
4260 childVisibilityChanged |= QQuickItemPrivate::get(childItems.at(ii))->setEffectiveVisibleRecur(newEffectiveVisible);
4262 itemChange(QQuickItem::ItemVisibleHasChanged, effectiveVisible);
4263 #ifndef QT_NO_ACCESSIBILITY
4265 QAccessibleEvent ev(q, effectiveVisible ? QAccessible::ObjectShow : QAccessible::ObjectHide);
4266 QAccessible::updateAccessibility(&ev);
4269 emit q->visibleChanged();
4270 if (childVisibilityChanged)
4271 emit q->visibleChildrenChanged();
4273 return true; // effective visibility DID change
4276 bool QQuickItemPrivate::calcEffectiveEnable() const
4278 // XXX todo - Should the effective enable of an element with no parent just be the current
4279 // effective enable? This would prevent pointless re-processing in the case of an element
4280 // moving to/from a no-parent situation, but it is different from what graphics view does.
4281 return explicitEnable && (!parentItem || QQuickItemPrivate::get(parentItem)->effectiveEnable);
4284 void QQuickItemPrivate::setEffectiveEnableRecur(QQuickItem *scope, bool newEffectiveEnable)
4288 if (newEffectiveEnable && !explicitEnable) {
4289 // This item locally overrides enable
4293 if (newEffectiveEnable == effectiveEnable) {
4294 // No change necessary
4298 effectiveEnable = newEffectiveEnable;
4301 QQuickWindowPrivate *windowPriv = QQuickWindowPrivate::get(window);
4302 if (windowPriv->mouseGrabberItem == q)
4304 if (scope && !effectiveEnable && activeFocus) {
4305 windowPriv->clearFocusInScope(
4306 scope, q, QQuickWindowPrivate::DontChangeFocusProperty | QQuickWindowPrivate::DontChangeSubFocusItem);
4310 for (int ii = 0; ii < childItems.count(); ++ii) {
4311 QQuickItemPrivate::get(childItems.at(ii))->setEffectiveEnableRecur(
4312 (flags & QQuickItem::ItemIsFocusScope) && scope ? q : scope, newEffectiveEnable);
4315 if (window && scope && effectiveEnable && focus) {
4316 QQuickWindowPrivate::get(window)->setFocusInScope(
4317 scope, q, QQuickWindowPrivate::DontChangeFocusProperty | QQuickWindowPrivate::DontChangeSubFocusItem);
4320 emit q->enabledChanged();
4323 QString QQuickItemPrivate::dirtyToString() const
4325 #define DIRTY_TO_STRING(value) if (dirtyAttributes & value) { \
4326 if (!rv.isEmpty()) \
4327 rv.append(QLatin1String("|")); \
4328 rv.append(QLatin1String(#value)); \
4331 // QString rv = QLatin1String("0x") + QString::number(dirtyAttributes, 16);
4334 DIRTY_TO_STRING(TransformOrigin);
4335 DIRTY_TO_STRING(Transform);
4336 DIRTY_TO_STRING(BasicTransform);
4337 DIRTY_TO_STRING(Position);
4338 DIRTY_TO_STRING(Size);
4339 DIRTY_TO_STRING(ZValue);
4340 DIRTY_TO_STRING(Content);
4341 DIRTY_TO_STRING(Smooth);
4342 DIRTY_TO_STRING(OpacityValue);
4343 DIRTY_TO_STRING(ChildrenChanged);
4344 DIRTY_TO_STRING(ChildrenStackingChanged);
4345 DIRTY_TO_STRING(ParentChanged);
4346 DIRTY_TO_STRING(Clip);
4347 DIRTY_TO_STRING(Window);
4348 DIRTY_TO_STRING(EffectReference);
4349 DIRTY_TO_STRING(Visible);
4350 DIRTY_TO_STRING(HideReference);
4351 DIRTY_TO_STRING(Antialiasing);
4356 void QQuickItemPrivate::dirty(DirtyType type)
4359 if (type & (TransformOrigin | Transform | BasicTransform | Position | Size))
4362 if (!(dirtyAttributes & type) || (window && !prevDirtyItem)) {
4363 dirtyAttributes |= type;
4364 if (window && componentComplete) {
4366 QQuickWindowPrivate::get(window)->dirtyItem(q);
4371 void QQuickItemPrivate::addToDirtyList()
4376 if (!prevDirtyItem) {
4377 Q_ASSERT(!nextDirtyItem);
4379 QQuickWindowPrivate *p = QQuickWindowPrivate::get(window);
4380 nextDirtyItem = p->dirtyItemList;
4381 if (nextDirtyItem) QQuickItemPrivate::get(nextDirtyItem)->prevDirtyItem = &nextDirtyItem;
4382 prevDirtyItem = &p->dirtyItemList;
4383 p->dirtyItemList = q;
4386 Q_ASSERT(prevDirtyItem);
4389 void QQuickItemPrivate::removeFromDirtyList()
4391 if (prevDirtyItem) {
4392 if (nextDirtyItem) QQuickItemPrivate::get(nextDirtyItem)->prevDirtyItem = prevDirtyItem;
4393 *prevDirtyItem = nextDirtyItem;
4397 Q_ASSERT(!prevDirtyItem);
4398 Q_ASSERT(!nextDirtyItem);
4401 void QQuickItemPrivate::refFromEffectItem(bool hide)
4403 ++extra.value().effectRefCount;
4404 if (1 == extra->effectRefCount) {
4405 dirty(EffectReference);
4406 if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
4409 if (++extra->hideRefCount == 1)
4410 dirty(HideReference);
4414 void QQuickItemPrivate::derefFromEffectItem(bool unhide)
4416 Q_ASSERT(extra->effectRefCount);
4417 --extra->effectRefCount;
4418 if (0 == extra->effectRefCount) {
4419 dirty(EffectReference);
4420 if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
4423 if (--extra->hideRefCount == 0)
4424 dirty(HideReference);
4428 void QQuickItemPrivate::setCulled(bool cull)
4434 if ((cull && ++extra->hideRefCount == 1) || (!cull && --extra->hideRefCount == 0))
4435 dirty(HideReference);
4438 void QQuickItemPrivate::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data)
4442 case QQuickItem::ItemChildAddedChange:
4443 q->itemChange(change, data);
4444 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4445 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4446 if (change.types & QQuickItemPrivate::Children) {
4447 change.listener->itemChildAdded(q, data.item);
4451 case QQuickItem::ItemChildRemovedChange:
4452 q->itemChange(change, data);
4453 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4454 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4455 if (change.types & QQuickItemPrivate::Children) {
4456 change.listener->itemChildRemoved(q, data.item);
4460 case QQuickItem::ItemSceneChange:
4461 q->itemChange(change, data);
4463 case QQuickItem::ItemVisibleHasChanged:
4464 q->itemChange(change, data);
4465 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4466 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4467 if (change.types & QQuickItemPrivate::Visibility) {
4468 change.listener->itemVisibilityChanged(q);
4472 case QQuickItem::ItemParentHasChanged:
4473 q->itemChange(change, data);
4474 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4475 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4476 if (change.types & QQuickItemPrivate::Parent) {
4477 change.listener->itemParentChanged(q, data.item);
4481 case QQuickItem::ItemOpacityHasChanged:
4482 q->itemChange(change, data);
4483 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4484 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4485 if (change.types & QQuickItemPrivate::Opacity) {
4486 change.listener->itemOpacityChanged(q);
4490 case QQuickItem::ItemActiveFocusHasChanged:
4491 q->itemChange(change, data);
4493 case QQuickItem::ItemRotationHasChanged:
4494 q->itemChange(change, data);
4495 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4496 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4497 if (change.types & QQuickItemPrivate::Rotation) {
4498 change.listener->itemRotationChanged(q);
4506 \property QQuickItem::smooth
4507 \brief Specifies whether the item is smoothed or not
4509 Primarily used in image based items to decide if the item should use smooth
4510 sampling or not. Smooth sampling is performed using linear interpolation, while
4511 non-smooth is performed using nearest neighbor.
4513 In Qt Quick 2.0, this property has minimal impact on performance.
4519 Returns true if the item should be drawn with
4520 smooth pixmap filtering, false otherwise.
4522 The default is true.
4526 bool QQuickItem::smooth() const
4528 Q_D(const QQuickItem);
4533 Sets whether the item should be drawn with antialiasing and
4534 smooth pixmap filtering to \a smooth.
4538 void QQuickItem::setSmooth(bool smooth)
4541 if (d->smooth == smooth)
4545 d->dirty(QQuickItemPrivate::Smooth);
4547 emit smoothChanged(smooth);
4551 \property QQuickItem::antialiasing
4552 \brief Specifies whether the item is antialiased or not
4554 Primarily used in Rectangle and image based elements to decide if the item should
4555 use antialiasing or not. Items with antialiasing enabled require more memory and
4556 are potentially slower to render.
4558 The default is false.
4562 Returns true if the item should be drawn with antialiasing, false otherwise.
4564 The default is false.
4566 \sa setAntialiasing()
4568 bool QQuickItem::antialiasing() const
4570 Q_D(const QQuickItem);
4571 return d->antialiasing;
4575 Sets whether the item should be drawn with antialiasing to \a antialiasing.
4579 void QQuickItem::setAntialiasing(bool antialiasing)
4582 if (d->antialiasing == antialiasing)
4585 d->antialiasing = antialiasing;
4586 d->dirty(QQuickItemPrivate::Antialiasing);
4588 emit antialiasingChanged(antialiasing);
4591 QQuickItem::Flags QQuickItem::flags() const
4593 Q_D(const QQuickItem);
4594 return (QQuickItem::Flags)d->flags;
4597 void QQuickItem::setFlag(Flag flag, bool enabled)
4601 setFlags((Flags)(d->flags | (quint32)flag));
4603 setFlags((Flags)(d->flags & ~(quint32)flag));
4606 void QQuickItem::setFlags(Flags flags)
4610 if ((flags & ItemIsFocusScope) != (d->flags & ItemIsFocusScope)) {
4611 if (flags & ItemIsFocusScope && !d->childItems.isEmpty() && d->window) {
4612 qWarning("QQuickItem: Cannot set FocusScope once item has children and is in a window.");
4613 flags &= ~ItemIsFocusScope;
4614 } else if (d->flags & ItemIsFocusScope) {
4615 qWarning("QQuickItem: Cannot unset FocusScope flag.");
4616 flags |= ItemIsFocusScope;
4620 if ((flags & ItemClipsChildrenToShape ) != (d->flags & ItemClipsChildrenToShape))
4621 d->dirty(QQuickItemPrivate::Clip);
4626 qreal QQuickItem::x() const
4628 Q_D(const QQuickItem);
4632 qreal QQuickItem::y() const
4634 Q_D(const QQuickItem);
4638 QPointF QQuickItem::pos() const
4640 Q_D(const QQuickItem);
4641 return QPointF(d->x, d->y);
4644 void QQuickItem::setX(qreal v)
4653 d->dirty(QQuickItemPrivate::Position);
4655 geometryChanged(QRectF(x(), y(), width(), height()),
4656 QRectF(oldx, y(), width(), height()));
4659 void QQuickItem::setY(qreal v)
4668 d->dirty(QQuickItemPrivate::Position);
4670 geometryChanged(QRectF(x(), y(), width(), height()),
4671 QRectF(x(), oldy, width(), height()));
4674 void QQuickItem::setPos(const QPointF &pos)
4677 if (QPointF(d->x, d->y) == pos)
4686 d->dirty(QQuickItemPrivate::Position);
4688 geometryChanged(QRectF(x(), y(), width(), height()),
4689 QRectF(oldx, oldy, width(), height()));
4692 qreal QQuickItem::width() const
4694 Q_D(const QQuickItem);
4698 void QQuickItem::setWidth(qreal w)
4704 d->widthValid = true;
4708 qreal oldWidth = d->width;
4711 d->dirty(QQuickItemPrivate::Size);
4713 geometryChanged(QRectF(x(), y(), width(), height()),
4714 QRectF(x(), y(), oldWidth, height()));
4717 void QQuickItem::resetWidth()
4720 d->widthValid = false;
4721 setImplicitWidth(implicitWidth());
4724 void QQuickItemPrivate::implicitWidthChanged()
4727 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4728 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4729 if (change.types & QQuickItemPrivate::ImplicitWidth) {
4730 change.listener->itemImplicitWidthChanged(q);
4733 emit q->implicitWidthChanged();
4736 qreal QQuickItemPrivate::getImplicitWidth() const
4738 return implicitWidth;
4741 Returns the width of the item that is implied by other properties that determine the content.
4743 qreal QQuickItem::implicitWidth() const
4745 Q_D(const QQuickItem);
4746 return d->getImplicitWidth();
4750 \qmlproperty real QtQuick2::Item::implicitWidth
4751 \qmlproperty real QtQuick2::Item::implicitHeight
4753 Defines the natural width or height of the Item if no \l width or \l height is specified.
4755 The default implicit size for most items is 0x0, however some items have an inherent
4756 implicit size which cannot be overridden, e.g. Image, Text.
4758 Setting the implicit size is useful for defining components that have a preferred size
4759 based on their content, for example:
4766 property alias icon: image.source
4767 property alias label: text.text
4768 implicitWidth: text.implicitWidth + image.implicitWidth
4769 implicitHeight: Math.max(text.implicitHeight, image.implicitHeight)
4774 anchors.left: image.right; anchors.right: parent.right
4775 anchors.verticalCenter: parent.verticalCenter
4780 \b Note: using implicitWidth of Text or TextEdit and setting the width explicitly
4781 incurs a performance penalty as the text must be laid out twice.
4785 Sets the implied width of the item to \a w.
4786 This is the width implied by other properties that determine the content.
4788 void QQuickItem::setImplicitWidth(qreal w)
4791 bool changed = w != d->implicitWidth;
4792 d->implicitWidth = w;
4793 if (d->width == w || widthValid()) {
4795 d->implicitWidthChanged();
4796 if (d->width == w || widthValid())
4801 qreal oldWidth = d->width;
4804 d->dirty(QQuickItemPrivate::Size);
4806 geometryChanged(QRectF(x(), y(), width(), height()),
4807 QRectF(x(), y(), oldWidth, height()));
4810 d->implicitWidthChanged();
4814 Returns whether the width property has been set explicitly.
4816 bool QQuickItem::widthValid() const
4818 Q_D(const QQuickItem);
4819 return d->widthValid;
4822 qreal QQuickItem::height() const
4824 Q_D(const QQuickItem);
4828 void QQuickItem::setHeight(qreal h)
4834 d->heightValid = true;
4838 qreal oldHeight = d->height;
4841 d->dirty(QQuickItemPrivate::Size);
4843 geometryChanged(QRectF(x(), y(), width(), height()),
4844 QRectF(x(), y(), width(), oldHeight));
4847 void QQuickItem::resetHeight()
4850 d->heightValid = false;
4851 setImplicitHeight(implicitHeight());
4854 void QQuickItemPrivate::implicitHeightChanged()
4857 for (int ii = 0; ii < changeListeners.count(); ++ii) {
4858 const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4859 if (change.types & QQuickItemPrivate::ImplicitHeight) {
4860 change.listener->itemImplicitHeightChanged(q);
4863 emit q->implicitHeightChanged();
4866 qreal QQuickItemPrivate::getImplicitHeight() const
4868 return implicitHeight;
4872 Returns the height of the item that is implied by other properties that determine the content.
4874 qreal QQuickItem::implicitHeight() const
4876 Q_D(const QQuickItem);
4877 return d->getImplicitHeight();
4882 Sets the implied height of the item to \a h.
4883 This is the height implied by other properties that determine the content.
4885 void QQuickItem::setImplicitHeight(qreal h)
4888 bool changed = h != d->implicitHeight;
4889 d->implicitHeight = h;
4890 if (d->height == h || heightValid()) {
4892 d->implicitHeightChanged();
4893 if (d->height == h || heightValid())
4898 qreal oldHeight = d->height;
4901 d->dirty(QQuickItemPrivate::Size);
4903 geometryChanged(QRectF(x(), y(), width(), height()),
4904 QRectF(x(), y(), width(), oldHeight));
4907 d->implicitHeightChanged();
4910 void QQuickItem::setImplicitSize(qreal w, qreal h)
4913 bool wChanged = w != d->implicitWidth;
4914 bool hChanged = h != d->implicitHeight;
4916 d->implicitWidth = w;
4917 d->implicitHeight = h;
4921 if (d->width == w || widthValid()) {
4923 d->implicitWidthChanged();
4924 wDone = d->width == w || widthValid();
4927 if (d->height == h || heightValid()) {
4929 d->implicitHeightChanged();
4930 hDone = d->height == h || heightValid();
4936 qreal oldWidth = d->width;
4937 qreal oldHeight = d->height;
4943 d->dirty(QQuickItemPrivate::Size);
4945 geometryChanged(QRectF(x(), y(), width(), height()),
4946 QRectF(x(), y(), oldWidth, oldHeight));
4948 if (!wDone && wChanged)
4949 d->implicitWidthChanged();
4950 if (!hDone && hChanged)
4951 d->implicitHeightChanged();
4955 Returns whether the height property has been set explicitly.
4957 bool QQuickItem::heightValid() const
4959 Q_D(const QQuickItem);
4960 return d->heightValid;
4963 void QQuickItem::setSize(const QSizeF &size)
4966 d->heightValid = true;
4967 d->widthValid = true;
4969 if (QSizeF(d->width, d->height) == size)
4972 qreal oldHeight = d->height;
4973 qreal oldWidth = d->width;
4974 d->height = size.height();
4975 d->width = size.width();
4977 d->dirty(QQuickItemPrivate::Size);
4979 geometryChanged(QRectF(x(), y(), width(), height()),
4980 QRectF(x(), y(), oldWidth, oldHeight));
4983 bool QQuickItem::hasActiveFocus() const
4985 Q_D(const QQuickItem);
4986 return d->activeFocus;
4989 bool QQuickItem::hasFocus() const
4991 Q_D(const QQuickItem);
4995 void QQuickItem::setFocus(bool focus)
4998 if (d->focus == focus)
5001 if (d->window || d->parentItem) {
5002 // Need to find our nearest focus scope
5003 QQuickItem *scope = parentItem();
5004 while (scope && !scope->isFocusScope() && scope->parentItem())
5005 scope = scope->parentItem();
5008 QQuickWindowPrivate::get(d->window)->setFocusInScope(scope, this);
5010 QQuickWindowPrivate::get(d->window)->clearFocusInScope(scope, this);
5012 // do the focus changes from setFocusInScope/clearFocusInScope that are
5013 // unrelated to a window
5014 QVarLengthArray<QQuickItem *, 20> changed;
5015 QQuickItem *oldSubFocusItem = QQuickItemPrivate::get(scope)->subFocusItem;
5016 if (oldSubFocusItem) {
5017 QQuickItemPrivate::get(oldSubFocusItem)->updateSubFocusItem(scope, false);
5018 QQuickItemPrivate::get(oldSubFocusItem)->focus = false;
5019 changed << oldSubFocusItem;
5020 } else if (!scope->isFocusScope() && scope->hasFocus()) {
5021 QQuickItemPrivate::get(scope)->focus = false;
5024 d->updateSubFocusItem(scope, focus);
5028 emit focusChanged(focus);
5030 QQuickWindowPrivate::notifyFocusChangesRecur(changed.data(), changed.count() - 1);
5033 QVarLengthArray<QQuickItem *, 20> changed;
5034 QQuickItem *oldSubFocusItem = d->subFocusItem;
5035 if (!isFocusScope() && oldSubFocusItem) {
5036 QQuickItemPrivate::get(oldSubFocusItem)->updateSubFocusItem(this, false);
5037 QQuickItemPrivate::get(oldSubFocusItem)->focus = false;
5038 changed << oldSubFocusItem;
5043 emit focusChanged(focus);
5045 QQuickWindowPrivate::notifyFocusChangesRecur(changed.data(), changed.count() - 1);
5049 bool QQuickItem::isFocusScope() const
5051 return flags() & ItemIsFocusScope;
5054 QQuickItem *QQuickItem::scopedFocusItem() const
5056 Q_D(const QQuickItem);
5057 if (!isFocusScope())
5060 return d->subFocusItem;
5064 Qt::MouseButtons QQuickItem::acceptedMouseButtons() const
5066 Q_D(const QQuickItem);
5067 return d->acceptedMouseButtons();
5070 void QQuickItem::setAcceptedMouseButtons(Qt::MouseButtons buttons)
5073 if (buttons & Qt::LeftButton)
5076 d->extra.clearFlag();
5078 buttons &= ~Qt::LeftButton;
5079 if (buttons || d->extra.isAllocated())
5080 d->extra.value().acceptedMouseButtons = buttons;
5083 bool QQuickItem::filtersChildMouseEvents() const
5085 Q_D(const QQuickItem);
5086 return d->filtersChildMouseEvents;
5089 void QQuickItem::setFiltersChildMouseEvents(bool filter)
5092 d->filtersChildMouseEvents = filter;
5095 bool QQuickItem::isUnderMouse() const
5097 Q_D(const QQuickItem);
5101 QPointF cursorPos = QGuiApplicationPrivate::lastCursorPosition;
5102 return contains(mapFromScene(d->window->mapFromGlobal(cursorPos.toPoint())));
5105 bool QQuickItem::acceptHoverEvents() const
5107 Q_D(const QQuickItem);
5108 return d->hoverEnabled;
5111 void QQuickItem::setAcceptHoverEvents(bool enabled)
5114 d->hoverEnabled = enabled;
5117 void QQuickItem::grabMouse()
5122 QQuickWindowPrivate *windowPriv = QQuickWindowPrivate::get(d->window);
5123 if (windowPriv->mouseGrabberItem == this)
5126 QQuickItem *oldGrabber = windowPriv->mouseGrabberItem;
5127 windowPriv->mouseGrabberItem = this;
5129 QEvent ev(QEvent::UngrabMouse);
5130 d->window->sendEvent(oldGrabber, &ev);
5134 void QQuickItem::ungrabMouse()
5139 QQuickWindowPrivate *windowPriv = QQuickWindowPrivate::get(d->window);
5140 if (windowPriv->mouseGrabberItem != this) {
5141 qWarning("QQuickItem::ungrabMouse(): Item is not the mouse grabber.");
5145 windowPriv->mouseGrabberItem = 0;
5147 QEvent ev(QEvent::UngrabMouse);
5148 d->window->sendEvent(this, &ev);
5151 bool QQuickItem::keepMouseGrab() const
5153 Q_D(const QQuickItem);
5154 return d->keepMouse;
5158 The flag indicating whether the mouse should remain
5159 with this item is set to \a keep.
5161 This is useful for items that wish to grab and keep mouse
5162 interaction following a predefined gesture. For example,
5163 an item that is interested in horizontal mouse movement
5164 may set keepMouseGrab to true once a threshold has been
5165 exceeded. Once keepMouseGrab has been set to true, filtering
5166 items will not react to mouse events.
5168 If the item does not indicate that it wishes to retain mouse grab,
5169 a filtering item may steal the grab. For example, Flickable may attempt
5170 to steal a mouse grab if it detects that the user has begun to
5175 void QQuickItem::setKeepMouseGrab(bool keep)
5178 d->keepMouse = keep;
5182 Grabs the touch points specified by \a ids.
5184 These touch points will be owned by the item until
5185 they are released. Alternatively, the grab can be stolen
5186 by a filtering item like Flickable. Use setKeepTouchGrab()
5187 to prevent the grab from being stolen.
5189 \sa ungrabTouchPoints(), setKeepTouchGrab()
5191 void QQuickItem::grabTouchPoints(const QVector<int> &ids)
5196 QQuickWindowPrivate *windowPriv = QQuickWindowPrivate::get(d->window);
5198 QSet<QQuickItem*> ungrab;
5199 for (int i = 0; i < ids.count(); ++i) {
5200 QQuickItem *oldGrabber = windowPriv->itemForTouchPointId.value(ids.at(i));
5201 if (oldGrabber == this)
5204 windowPriv->itemForTouchPointId[ids.at(i)] = this;
5206 ungrab.insert(oldGrabber);
5208 foreach (QQuickItem *oldGrabber, ungrab)
5209 oldGrabber->touchUngrabEvent();
5213 Ungrabs the touch points owned by this item.
5215 \sa grabTouchPoints()
5217 void QQuickItem::ungrabTouchPoints()
5222 QQuickWindowPrivate *windowPriv = QQuickWindowPrivate::get(d->window);
5224 QMutableHashIterator<int, QQuickItem*> i(windowPriv->itemForTouchPointId);
5225 while (i.hasNext()) {
5227 if (i.value() == this)
5234 Returns a value indicating whether the touch points grabbed by this item
5235 should remain with this item exclusively.
5237 \sa setKeepTouchGrab(), keepMouseGrab()
5239 bool QQuickItem::keepTouchGrab() const
5241 Q_D(const QQuickItem);
5242 return d->keepTouch;
5246 The flag indicating whether the touch points grabbed
5247 by this item should remain with this item is set to \a keep.
5249 This is useful for items that wish to grab and keep specific touch
5250 points following a predefined gesture. For example,
5251 an item that is interested in horizontal touch point movement
5252 may set setKeepTouchGrab to true once a threshold has been
5253 exceeded. Once setKeepTouchGrab has been set to true, filtering
5254 items will not react to the relevant touch points.
5256 If the item does not indicate that it wishes to retain touch point grab,
5257 a filtering item may steal the grab. For example, Flickable may attempt
5258 to steal a touch point grab if it detects that the user has begun to
5261 \sa keepTouchGrab(), setKeepMouseGrab()
5263 void QQuickItem::setKeepTouchGrab(bool keep)
5266 d->keepTouch = keep;
5270 Returns true if this item contains \a point, which is in local coordinates;
5271 returns false otherwise.
5273 This function can be overwritten in order to handle point collisions in items
5274 with custom shapes. The default implementation checks if the point is inside
5275 the item's bounding rect.
5277 Note that it's normally used to check if the item is under the mouse cursor,
5278 and for that reason, the implementation of this function should be as light-weight
5281 bool QQuickItem::contains(const QPointF &point) const
5283 Q_D(const QQuickItem);
5284 return QRectF(0, 0, d->width, d->height).contains(point);
5287 QPointF QQuickItem::mapToItem(const QQuickItem *item, const QPointF &point) const
5289 QPointF p = mapToScene(point);
5291 p = item->mapFromScene(p);
5295 QPointF QQuickItem::mapToScene(const QPointF &point) const
5297 Q_D(const QQuickItem);
5298 return d->itemToWindowTransform().map(point);
5301 QRectF QQuickItem::mapRectToItem(const QQuickItem *item, const QRectF &rect) const
5303 Q_D(const QQuickItem);
5304 QTransform t = d->itemToWindowTransform();
5306 t *= QQuickItemPrivate::get(item)->windowToItemTransform();
5307 return t.mapRect(rect);
5310 QRectF QQuickItem::mapRectToScene(const QRectF &rect) const
5312 Q_D(const QQuickItem);
5313 return d->itemToWindowTransform().mapRect(rect);
5316 QPointF QQuickItem::mapFromItem(const QQuickItem *item, const QPointF &point) const
5318 QPointF p = item?item->mapToScene(point):point;
5319 return mapFromScene(p);
5322 QPointF QQuickItem::mapFromScene(const QPointF &point) const
5324 Q_D(const QQuickItem);
5325 return d->windowToItemTransform().map(point);
5328 QRectF QQuickItem::mapRectFromItem(const QQuickItem *item, const QRectF &rect) const
5330 Q_D(const QQuickItem);
5331 QTransform t = item?QQuickItemPrivate::get(item)->itemToWindowTransform():QTransform();
5332 t *= d->windowToItemTransform();
5333 return t.mapRect(rect);
5336 QRectF QQuickItem::mapRectFromScene(const QRectF &rect) const
5338 Q_D(const QQuickItem);
5339 return d->windowToItemTransform().mapRect(rect);
5344 \qmlmethod QtQuick2::Item::forceActiveFocus()
5346 Forces active focus on the item.
5348 This method sets focus on the item and makes sure that all the focus scopes
5349 higher in the object hierarchy are also given the focus.
5353 Forces active focus on the item.
5355 This method sets focus on the item and makes sure that all the focus scopes
5356 higher in the object hierarchy are also given the focus.
5360 \qmlmethod QtQuick2::Item::childAt(real x, real y)
5362 Returns the visible child item at point (\a x, \a y), which is in this
5363 item's coordinate system, or \c null if there is no such item.
5367 Returns the visible child item at point (\a x, \a y), which is in this
5368 item's coordinate system, or 0 if there is no such item.
5372 \qmlproperty list<State> QtQuick2::Item::states
5373 This property holds a list of states defined by the item.
5389 \sa {qmlstate}{States}
5392 \qmlproperty list<Transition> QtQuick2::Item::transitions
5393 This property holds a list of transitions defined by the item.
5409 \sa {QML Animation and Transitions}{Transitions}
5412 \qmlproperty list<Filter> QtQuick2::Item::filter
5413 This property holds a list of graphical filters to be applied to the item.
5415 \l {Filter}{Filters} include things like \l {Blur}{blurring}
5416 the item, or giving it a \l Reflection. Some
5417 filters may not be available on all windows; if a filter is not
5418 available on a certain window, it will simply not be applied for
5419 that window (but the QML will still be considered valid).
5437 \qmlproperty bool QtQuick2::Item::clip
5438 This property holds whether clipping is enabled. The default clip value is \c false.
5440 If clipping is enabled, an item will clip its own painting, as well
5441 as the painting of its children, to its bounding rectangle.
5443 Non-rectangular clipping regions are not supported for performance reasons.
5447 \property QQuickItem::clip
5448 This property holds whether clipping is enabled. The default clip value is \c false.
5450 If clipping is enabled, an item will clip its own painting, as well
5451 as the painting of its children, to its bounding rectangle. If you set
5452 clipping during an item's paint operation, remember to re-set it to
5453 prevent clipping the rest of your scene.
5455 Non-rectangular clipping regions are not supported for performance reasons.
5459 \qmlproperty string QtQuick2::Item::state
5461 This property holds the name of the current state of the item.
5463 This property is often used in scripts to change between states. For
5468 if (button.state == 'On')
5469 button.state = 'Off';
5471 button.state = 'On';
5475 If the item is in its base state (i.e. no explicit state has been
5476 set), \c state will be a blank string. Likewise, you can return an
5477 item to its base state by setting its current state to \c ''.
5479 \sa {qmlstates}{States}
5483 \qmlproperty list<Transform> QtQuick2::Item::transform
5484 This property holds the list of transformations to apply.
5486 For more information see \l Transform.
5490 \enum QQuickItem::TransformOrigin
5492 Controls the point about which simple transforms like scale apply.
5494 \value TopLeft The top-left corner of the item.
5495 \value Top The center point of the top of the item.
5496 \value TopRight The top-right corner of the item.
5497 \value Left The left most point of the vertical middle.
5498 \value Center The center of the item.
5499 \value Right The right most point of the vertical middle.
5500 \value BottomLeft The bottom-left corner of the item.
5501 \value Bottom The center point of the bottom of the item.
5502 \value BottomRight The bottom-right corner of the item.
5507 \qmlproperty bool QtQuick2::Item::activeFocus
5509 This property indicates whether the item has active focus.
5511 An item with active focus will receive keyboard input,
5512 or is a FocusScope ancestor of the item that will receive keyboard input.
5514 Usually, activeFocus is gained by setting focus on an item and its enclosing
5515 FocusScopes. In the following example \c input will have activeFocus.
5528 \sa focus, {qmlfocus}{Keyboard Focus}
5532 \qmlproperty bool QtQuick2::Item::focus
5533 This property indicates whether the item has focus within the enclosing focus scope. If true, this item
5534 will gain active focus when the enclosing focus scope gains active focus.
5535 In the following example, \c input will be given active focus when \c scope gains active focus.
5548 For the purposes of this property, the scene as a whole is assumed to act like a focus scope.
5549 On a practical level, that means the following QML will give active focus to \c input on startup.
5560 \sa activeFocus, {qmlfocus}{Keyboard Focus}
5565 \property QQuickItem::anchors
5570 \property QQuickItem::left
5575 \property QQuickItem::right
5580 \property QQuickItem::horizontalCenter
5585 \property QQuickItem::top
5590 \property QQuickItem::bottom
5595 \property QQuickItem::verticalCenter
5600 \property QQuickItem::focus
5605 \property QQuickItem::transform
5610 \property QQuickItem::transformOrigin
5615 \property QQuickItem::activeFocus
5620 \property QQuickItem::baseline
5625 \property QQuickItem::data
5630 \property QQuickItem::resources
5635 \property QQuickItem::state
5640 \property QQuickItem::states
5645 \property QQuickItem::transformOriginPoint
5650 \property QQuickItem::transitions
5654 bool QQuickItem::event(QEvent *ev)
5657 if (ev->type() == QEvent::PolishRequest) {
5659 d->polishScheduled = false;
5663 return QObject::event(ev);
5666 if (ev->type() == QEvent::InputMethodQuery) {
5667 QInputMethodQueryEvent *query = static_cast<QInputMethodQueryEvent *>(ev);
5668 Qt::InputMethodQueries queries = query->queries();
5669 for (uint i = 0; i < 32; ++i) {
5670 Qt::InputMethodQuery q = (Qt::InputMethodQuery)(int)(queries & (1<<i));
5672 QVariant v = inputMethodQuery(q);
5673 query->setValue(q, v);
5678 } else if (ev->type() == QEvent::InputMethod) {
5679 inputMethodEvent(static_cast<QInputMethodEvent *>(ev));
5682 return QObject::event(ev);
5685 #ifndef QT_NO_DEBUG_STREAM
5686 QDebug operator<<(QDebug debug, QQuickItem *item)
5689 debug << "QQuickItem(0)";
5693 debug << item->metaObject()->className() << "(this =" << ((void*)item)
5694 << ", name=" << item->objectName()
5695 << ", parent =" << ((void*)item->parentItem())
5696 << ", geometry =" << QRectF(item->pos(), QSizeF(item->width(), item->height()))
5697 << ", z =" << item->z() << ')';
5702 qint64 QQuickItemPrivate::consistentTime = -1;
5703 void QQuickItemPrivate::setConsistentTime(qint64 t)
5708 class QElapsedTimerConsistentTimeHack
5712 t1 = QQuickItemPrivate::consistentTime;
5716 return QQuickItemPrivate::consistentTime - t1;
5719 qint64 val = QQuickItemPrivate::consistentTime - t1;
5720 t1 = QQuickItemPrivate::consistentTime;
5730 void QQuickItemPrivate::start(QElapsedTimer &t)
5732 if (QQuickItemPrivate::consistentTime == -1)
5735 ((QElapsedTimerConsistentTimeHack*)&t)->start();
5738 qint64 QQuickItemPrivate::elapsed(QElapsedTimer &t)
5740 if (QQuickItemPrivate::consistentTime == -1)
5743 return ((QElapsedTimerConsistentTimeHack*)&t)->elapsed();
5746 qint64 QQuickItemPrivate::restart(QElapsedTimer &t)
5748 if (QQuickItemPrivate::consistentTime == -1)
5751 return ((QElapsedTimerConsistentTimeHack*)&t)->restart();
5755 \fn bool QQuickItem::isTextureProvider() const
5757 Returns true if this item is a texture provider. The default
5758 implementation returns false.
5760 This function can be called from any thread.
5763 bool QQuickItem::isTextureProvider() const
5765 Q_D(const QQuickItem);
5766 return d->extra.isAllocated() && d->extra->layer && d->extra->layer->effectSource() ?
5767 d->extra->layer->effectSource()->isTextureProvider() : false;
5771 \fn QSGTextureProvider *QQuickItem::textureProvider() const
5773 Returns the texture provider for an item. The default implementation
5776 This function may only be called on the rendering thread.
5779 QSGTextureProvider *QQuickItem::textureProvider() const
5781 Q_D(const QQuickItem);
5782 return d->extra.isAllocated() && d->extra->layer && d->extra->layer->effectSource() ?
5783 d->extra->layer->effectSource()->textureProvider() : 0;
5786 QQuickItemLayer *QQuickItemPrivate::layer() const
5788 if (!extra.isAllocated() || !extra->layer) {
5789 extra.value().layer = new QQuickItemLayer(const_cast<QQuickItem *>(q_func()));
5790 if (!componentComplete)
5791 extra->layer->classBegin();
5793 return extra->layer;
5796 QQuickItemLayer::QQuickItemLayer(QQuickItem *item)
5801 , m_componentComplete(true)
5802 , m_wrapMode(QQuickShaderEffectSource::ClampToEdge)
5803 , m_format(QQuickShaderEffectSource::RGBA)
5805 , m_effectComponent(0)
5811 QQuickItemLayer::~QQuickItemLayer()
5813 delete m_effectSource;
5820 \qmlproperty bool QtQuick2::Item::layer.enabled
5822 Holds wether the item is layered or not. Layering is disabled by default.
5824 A layered item is rendered into an offscreen surface and cached until
5825 it is changed. Enabling layering for complex QML item hierarchies can
5826 some times be an optimization.
5828 None of the other layer properties have any effect when the layer
5832 void QQuickItemLayer::setEnabled(bool e)
5837 if (m_componentComplete) {
5844 emit enabledChanged(e);
5847 void QQuickItemLayer::classBegin()
5849 Q_ASSERT(!m_effectSource);
5850 Q_ASSERT(!m_effect);
5851 m_componentComplete = false;
5854 void QQuickItemLayer::componentComplete()
5856 Q_ASSERT(!m_componentComplete);
5857 m_componentComplete = true;
5862 void QQuickItemLayer::activate()
5864 Q_ASSERT(!m_effectSource);
5865 m_effectSource = new QQuickShaderEffectSource();
5867 QQuickItem *parentItem = m_item->parentItem();
5869 m_effectSource->setParentItem(parentItem);
5870 m_effectSource->stackAfter(m_item);
5873 m_effectSource->setSourceItem(m_item);
5874 m_effectSource->setHideSource(true);
5875 m_effectSource->setSmooth(m_smooth);
5876 m_effectSource->setTextureSize(m_size);
5877 m_effectSource->setSourceRect(m_sourceRect);
5878 m_effectSource->setMipmap(m_mipmap);
5879 m_effectSource->setWrapMode(m_wrapMode);
5880 m_effectSource->setFormat(m_format);
5882 if (m_effectComponent)
5885 m_effectSource->setVisible(m_item->isVisible() && !m_effect);
5892 QQuickItemPrivate *id = QQuickItemPrivate::get(m_item);
5893 id->addItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Opacity | QQuickItemPrivate::Parent | QQuickItemPrivate::Visibility | QQuickItemPrivate::SiblingOrder);
5896 void QQuickItemLayer::deactivate()
5898 Q_ASSERT(m_effectSource);
5900 if (m_effectComponent)
5903 delete m_effectSource;
5906 QQuickItemPrivate *id = QQuickItemPrivate::get(m_item);
5907 id->removeItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Opacity | QQuickItemPrivate::Parent | QQuickItemPrivate::Visibility | QQuickItemPrivate::SiblingOrder);
5910 void QQuickItemLayer::activateEffect()
5912 Q_ASSERT(m_effectSource);
5913 Q_ASSERT(m_effectComponent);
5914 Q_ASSERT(!m_effect);
5916 QObject *created = m_effectComponent->beginCreate(m_effectComponent->creationContext());
5917 m_effect = qobject_cast<QQuickItem *>(created);
5919 qWarning("Item: layer.effect is not a QML Item.");
5920 m_effectComponent->completeCreate();
5924 QQuickItem *parentItem = m_item->parentItem();
5926 m_effect->setParentItem(parentItem);
5927 m_effect->stackAfter(m_effectSource);
5929 m_effect->setVisible(m_item->isVisible());
5930 m_effect->setProperty(m_name, qVariantFromValue<QObject *>(m_effectSource));
5931 m_effectComponent->completeCreate();
5934 void QQuickItemLayer::deactivateEffect()
5936 Q_ASSERT(m_effectSource);
5937 Q_ASSERT(m_effectComponent);
5945 \qmlproperty Component QtQuick2::Item::layer.effect
5947 Holds the effect that is applied to this layer.
5949 The effect is typically a \l ShaderEffect component, although any \l Item component can be
5950 assigned. The effect should have a source texture property with a name matching \l samplerName.
5955 void QQuickItemLayer::setEffect(QQmlComponent *component)
5957 if (component == m_effectComponent)
5960 bool updateNeeded = false;
5961 if (m_effectSource && m_effectComponent) {
5963 updateNeeded = true;
5966 m_effectComponent = component;
5968 if (m_effectSource && m_effectComponent) {
5970 updateNeeded = true;
5978 m_effectSource->setVisible(m_item->isVisible() && !m_effect);
5981 emit effectChanged(component);
5986 \qmlproperty bool QtQuick2::Item::layer.mipmap
5988 If this property is true, mipmaps are generated for the texture.
5990 \note Some OpenGL ES 2 implementations do not support mipmapping of
5991 non-power-of-two textures.
5994 void QQuickItemLayer::setMipmap(bool mipmap)
5996 if (mipmap == m_mipmap)
6001 m_effectSource->setMipmap(m_mipmap);
6003 emit mipmapChanged(mipmap);
6008 \qmlproperty enumeration QtQuick2::Item::layer.format
6010 This property defines the internal OpenGL format of the texture.
6011 Modifying this property makes most sense when the \a layer.effect is also
6012 specified. Depending on the OpenGL implementation, this property might
6013 allow you to save some texture memory.
6016 \li ShaderEffectSource.Alpha - GL_ALPHA
6017 \li ShaderEffectSource.RGB - GL_RGB
6018 \li ShaderEffectSource.RGBA - GL_RGBA
6021 \note Some OpenGL implementations do not support the GL_ALPHA format.
6024 void QQuickItemLayer::setFormat(QQuickShaderEffectSource::Format f)
6031 m_effectSource->setFormat(m_format);
6033 emit formatChanged(m_format);
6038 \qmlproperty enumeration QtQuick2::Item::layer.sourceRect
6040 This property defines which rectangular area of the \l sourceItem to
6041 render into the texture. The source rectangle can be larger than
6042 \l sourceItem itself. If the rectangle is null, which is the default,
6043 the whole \l sourceItem is rendered to texture.
6046 void QQuickItemLayer::setSourceRect(const QRectF &sourceRect)
6048 if (sourceRect == m_sourceRect)
6050 m_sourceRect = sourceRect;
6053 m_effectSource->setSourceRect(m_sourceRect);
6055 emit sourceRectChanged(sourceRect);
6061 \qmlproperty bool QtQuick2::Item::layer.smooth
6063 Holds whether the layer is smoothly transformed.
6066 void QQuickItemLayer::setSmooth(bool s)
6073 m_effectSource->setSmooth(m_smooth);
6075 emit smoothChanged(s);
6081 \qmlproperty size QtQuick2::Item::layer.textureSize
6083 This property holds the requested pixel size of the layers texture. If it is empty,
6084 which is the default, the size of the item is used.
6086 \note Some platforms have a limit on how small framebuffer objects can be,
6087 which means the actual texture size might be larger than the requested
6091 void QQuickItemLayer::setSize(const QSize &size)
6098 m_effectSource->setTextureSize(size);
6100 emit sizeChanged(size);
6106 \qmlproperty enumeration QtQuick2::Item::layer.wrapMode
6108 This property defines the OpenGL wrap modes associated with the texture.
6109 Modifying this property makes most sense when the \a layer.effect is
6113 \li ShaderEffectSource.ClampToEdge - GL_CLAMP_TO_EDGE both horizontally and vertically
6114 \li ShaderEffectSource.RepeatHorizontally - GL_REPEAT horizontally, GL_CLAMP_TO_EDGE vertically
6115 \li ShaderEffectSource.RepeatVertically - GL_CLAMP_TO_EDGE horizontally, GL_REPEAT vertically
6116 \li ShaderEffectSource.Repeat - GL_REPEAT both horizontally and vertically
6119 \note Some OpenGL ES 2 implementations do not support the GL_REPEAT
6120 wrap mode with non-power-of-two textures.
6123 void QQuickItemLayer::setWrapMode(QQuickShaderEffectSource::WrapMode mode)
6125 if (mode == m_wrapMode)
6130 m_effectSource->setWrapMode(m_wrapMode);
6132 emit wrapModeChanged(mode);
6136 \qmlproperty string QtQuick2::Item::layer.samplerName
6138 Holds the name of the effect's source texture property.
6140 samplerName needs to match the name of the effect's source texture property
6141 so that the Item can pass the layer's offscreen surface to the effect correctly.
6143 \sa effect, ShaderEffect
6146 void QQuickItemLayer::setName(const QByteArray &name) {
6150 m_effect->setProperty(m_name, QVariant());
6151 m_effect->setProperty(name, qVariantFromValue<QObject *>(m_effectSource));
6154 emit nameChanged(name);
6157 void QQuickItemLayer::itemOpacityChanged(QQuickItem *item)
6163 void QQuickItemLayer::itemGeometryChanged(QQuickItem *, const QRectF &, const QRectF &)
6168 void QQuickItemLayer::itemParentChanged(QQuickItem *item, QQuickItem *parent)
6171 Q_ASSERT(item == m_item);
6172 Q_ASSERT(parent != m_effectSource);
6173 Q_ASSERT(parent == 0 || parent != m_effect);
6175 m_effectSource->setParentItem(parent);
6177 m_effectSource->stackAfter(m_item);
6180 m_effect->setParentItem(parent);
6182 m_effect->stackAfter(m_effectSource);
6186 void QQuickItemLayer::itemSiblingOrderChanged(QQuickItem *)
6188 m_effectSource->stackAfter(m_item);
6190 m_effect->stackAfter(m_effectSource);
6193 void QQuickItemLayer::itemVisibilityChanged(QQuickItem *)
6195 QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
6197 l->setVisible(m_item->isVisible());
6200 void QQuickItemLayer::updateZ()
6202 if (!m_componentComplete || !m_enabled)
6204 QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
6206 l->setZ(m_item->z());
6209 void QQuickItemLayer::updateOpacity()
6211 QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
6213 l->setOpacity(m_item->opacity());
6216 void QQuickItemLayer::updateGeometry()
6218 QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
6220 QRectF bounds = m_item->clipRect();
6221 l->setWidth(bounds.width());
6222 l->setHeight(bounds.height());
6223 l->setX(bounds.x() + m_item->x());
6224 l->setY(bounds.y() + m_item->y());
6227 void QQuickItemLayer::updateMatrix()
6229 // Called directly from transformChanged(), so needs some extra
6231 if (!m_componentComplete || !m_enabled)
6233 QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
6235 QQuickItemPrivate *ld = QQuickItemPrivate::get(l);
6236 l->setScale(m_item->scale());
6237 l->setRotation(m_item->rotation());
6238 ld->transforms = QQuickItemPrivate::get(m_item)->transforms;
6239 if (ld->origin() != QQuickItemPrivate::get(m_item)->origin())
6240 ld->extra.value().origin = QQuickItemPrivate::get(m_item)->origin();
6241 ld->dirty(QQuickItemPrivate::Transform);
6244 QQuickItemPrivate::ExtraData::ExtraData()
6245 : z(0), scale(1), rotation(0), opacity(1),
6246 contents(0), screenAttached(0), layoutDirectionAttached(0),
6247 keyHandler(0), layer(0), effectRefCount(0), hideRefCount(0),
6248 opacityNode(0), clipNode(0), rootNode(0), beforePaintNode(0),
6249 acceptedMouseButtons(0), origin(QQuickItem::Center)
6255 #include <moc_qquickitem.cpp>