1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the QtDeclarative module of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
44 #include "qsgcanvas.h"
45 #include <QtDeclarative/qjsengine.h>
46 #include "qsgcanvas_p.h"
49 #include "qsgevents_p_p.h"
51 #include <QtDeclarative/qdeclarativeengine.h>
52 #include <QtDeclarative/qdeclarativecomponent.h>
53 #include <QtDeclarative/qdeclarativeinfo.h>
54 #include <QtGui/qgraphicstransform.h>
55 #include <QtGui/qpen.h>
56 #include <QtGui/qinputcontext.h>
57 #include <QtCore/qdebug.h>
58 #include <QtCore/qcoreevent.h>
59 #include <QtCore/qnumeric.h>
61 #include <private/qdeclarativeengine_p.h>
62 #include <private/qdeclarativestategroup_p.h>
63 #include <private/qdeclarativeopenmetaobject_p.h>
64 #include <private/qdeclarativestate_p.h>
65 #include <private/qlistmodelinterface_p.h>
66 #include <private/qsgitem_p.h>
70 // XXX todo Readd parentNotifier for faster parent bindings
71 // XXX todo Check that elements that create items handle memory correctly after visual ownership change
76 \qmlclass Transform QSGTransform
77 \inqmlmodule QtQuick 2
78 \ingroup qml-transform-elements
79 \brief The Transform elements provide a way of building advanced transformations on Items.
81 The Transform element is a base type which cannot be instantiated directly.
82 The following concrete Transform types are available:
90 The Transform elements let you create and control advanced transformations that can be configured
91 independently using specialized properties.
93 You can assign any number of Transform elements to an \l Item. Each Transform is applied in order,
98 \qmlclass Translate QSGTranslate
99 \inqmlmodule QtQuick 2
100 \ingroup qml-transform-elements
101 \brief The Translate object provides a way to move an Item without changing its x or y properties.
103 The Translate object provides independent control over position in addition to the Item's x and y properties.
105 The following example moves the Y axis of the \l Rectangle elements while still allowing the \l Row element
106 to lay the items out as if they had not been transformed:
112 width: 100; height: 100
114 transform: Translate { y: 20 }
117 width: 100; height: 100
119 transform: Translate { y: -20 }
128 \qmlproperty real QtQuick2::Translate::x
130 The translation along the X axis.
134 \qmlproperty real QtQuick2::Translate::y
136 The translation along the Y axis.
140 \qmlclass Scale QSGScale
141 \inqmlmodule QtQuick 2
142 \ingroup qml-transform-elements
143 \brief The Scale element provides a way to scale an Item.
145 The Scale element gives more control over scaling than using \l Item's \l{Item::scale}{scale} property. Specifically,
146 it allows a different scale for the x and y axes, and allows the scale to be relative to an
149 The following example scales the X axis of the Rectangle, relative to its interior point 25, 25:
152 width: 100; height: 100
154 transform: Scale { origin.x: 25; origin.y: 25; xScale: 3}
158 \sa Rotation, Translate
162 \qmlproperty real QtQuick2::Scale::origin.x
163 \qmlproperty real QtQuick2::Scale::origin.y
165 The point that the item is scaled from (i.e., the point that stays fixed relative to the parent as
166 the rest of the item grows). By default the origin is 0, 0.
170 \qmlproperty real QtQuick2::Scale::xScale
172 The scaling factor for the X axis.
176 \qmlproperty real QtQuick2::Scale::yScale
178 The scaling factor for the Y axis.
182 \qmlclass Rotation QSGRotation
183 \inqmlmodule QtQuick 2
184 \ingroup qml-transform-elements
185 \brief The Rotation object provides a way to rotate an Item.
187 The Rotation object gives more control over rotation than using \l Item's \l{Item::rotation}{rotation} property.
188 Specifically, it allows (z axis) rotation to be relative to an arbitrary point.
190 The following example rotates a Rectangle around its interior point 25, 25:
193 width: 100; height: 100
195 transform: Rotation { origin.x: 25; origin.y: 25; angle: 45}
199 Rotation also provides a way to specify 3D-like rotations for Items. For these types of
200 rotations you must specify the axis to rotate around in addition to the origin point.
202 The following example shows various 3D-like rotations applied to an \l Image.
203 \snippet doc/src/snippets/declarative/rotation.qml 0
205 \image axisrotation.png
207 \sa {declarative/ui-components/dialcontrol}{Dial Control example}, {declarative/toys/clocks}{Clocks example}
211 \qmlproperty real QtQuick2::Rotation::origin.x
212 \qmlproperty real QtQuick2::Rotation::origin.y
214 The origin point of the rotation (i.e., the point that stays fixed relative to the parent as
215 the rest of the item rotates). By default the origin is 0, 0.
219 \qmlproperty real QtQuick2::Rotation::axis.x
220 \qmlproperty real QtQuick2::Rotation::axis.y
221 \qmlproperty real QtQuick2::Rotation::axis.z
223 The axis to rotate around. For simple (2D) rotation around a point, you do not need to specify an axis,
224 as the default axis is the z axis (\c{ axis { x: 0; y: 0; z: 1 } }).
226 For a typical 3D-like rotation you will usually specify both the origin and the axis.
228 \image 3d-rotation-axis.png
232 \qmlproperty real QtQuick2::Rotation::angle
234 The angle to rotate, in degrees clockwise.
237 QSGTransformPrivate::QSGTransformPrivate()
241 QSGTransform::QSGTransform(QObject *parent)
242 : QObject(*(new QSGTransformPrivate), parent)
246 QSGTransform::QSGTransform(QSGTransformPrivate &dd, QObject *parent)
247 : QObject(dd, parent)
251 QSGTransform::~QSGTransform()
254 for (int ii = 0; ii < d->items.count(); ++ii) {
255 QSGItemPrivate *p = QSGItemPrivate::get(d->items.at(ii));
256 p->transforms.removeOne(this);
257 p->dirty(QSGItemPrivate::Transform);
261 void QSGTransform::update()
264 for (int ii = 0; ii < d->items.count(); ++ii) {
265 QSGItemPrivate *p = QSGItemPrivate::get(d->items.at(ii));
266 p->dirty(QSGItemPrivate::Transform);
270 QSGContents::QSGContents(QSGItem *item)
271 : m_item(item), m_x(0), m_y(0), m_width(0), m_height(0)
274 connect(this, SIGNAL(rectChanged(QRectF)), m_item, SIGNAL(childrenRectChanged(QRectF)));
277 QSGContents::~QSGContents()
279 QList<QSGItem *> children = m_item->childItems();
280 for (int i = 0; i < children.count(); ++i) {
281 QSGItem *child = children.at(i);
282 QSGItemPrivate::get(child)->removeItemChangeListener(this, QSGItemPrivate::Geometry | QSGItemPrivate::Destroyed);
286 QRectF QSGContents::rectF() const
288 return QRectF(m_x, m_y, m_width, m_height);
291 void QSGContents::calcHeight(QSGItem *changed)
294 qreal oldheight = m_height;
298 qreal bottom = oldy + oldheight;
299 qreal y = changed->y();
300 if (y + changed->height() > bottom)
301 bottom = y + changed->height();
305 m_height = bottom - top;
309 QList<QSGItem *> children = m_item->childItems();
310 for (int i = 0; i < children.count(); ++i) {
311 QSGItem *child = children.at(i);
312 qreal y = child->y();
313 if (y + child->height() > bottom)
314 bottom = y + child->height();
318 if (!children.isEmpty())
320 m_height = qMax(bottom - top, qreal(0.0));
323 if (m_height != oldheight || m_y != oldy)
324 emit rectChanged(rectF());
327 void QSGContents::calcWidth(QSGItem *changed)
330 qreal oldwidth = m_width;
334 qreal right = oldx + oldwidth;
335 qreal x = changed->x();
336 if (x + changed->width() > right)
337 right = x + changed->width();
341 m_width = right - left;
343 qreal left = FLT_MAX;
345 QList<QSGItem *> children = m_item->childItems();
346 for (int i = 0; i < children.count(); ++i) {
347 QSGItem *child = children.at(i);
348 qreal x = child->x();
349 if (x + child->width() > right)
350 right = x + child->width();
354 if (!children.isEmpty())
356 m_width = qMax(right - left, qreal(0.0));
359 if (m_width != oldwidth || m_x != oldx)
360 emit rectChanged(rectF());
363 void QSGContents::complete()
365 QList<QSGItem *> children = m_item->childItems();
366 for (int i = 0; i < children.count(); ++i) {
367 QSGItem *child = children.at(i);
368 QSGItemPrivate::get(child)->addItemChangeListener(this, QSGItemPrivate::Geometry | QSGItemPrivate::Destroyed);
369 //###what about changes to visibility?
375 void QSGContents::itemGeometryChanged(QSGItem *changed, const QRectF &newGeometry, const QRectF &oldGeometry)
378 //### we can only pass changed if the left edge has moved left, or the right edge has moved right
379 if (newGeometry.width() != oldGeometry.width() || newGeometry.x() != oldGeometry.x())
380 calcWidth(/*changed*/);
381 if (newGeometry.height() != oldGeometry.height() || newGeometry.y() != oldGeometry.y())
382 calcHeight(/*changed*/);
385 void QSGContents::itemDestroyed(QSGItem *item)
388 QSGItemPrivate::get(item)->removeItemChangeListener(this, QSGItemPrivate::Geometry | QSGItemPrivate::Destroyed);
392 void QSGContents::childRemoved(QSGItem *item)
395 QSGItemPrivate::get(item)->removeItemChangeListener(this, QSGItemPrivate::Geometry | QSGItemPrivate::Destroyed);
399 void QSGContents::childAdded(QSGItem *item)
402 QSGItemPrivate::get(item)->addItemChangeListener(this, QSGItemPrivate::Geometry | QSGItemPrivate::Destroyed);
407 QSGItemKeyFilter::QSGItemKeyFilter(QSGItem *item)
408 : m_processPost(false), m_next(0)
410 QSGItemPrivate *p = item?QSGItemPrivate::get(item):0;
412 m_next = p->keyHandler;
413 p->keyHandler = this;
417 QSGItemKeyFilter::~QSGItemKeyFilter()
421 void QSGItemKeyFilter::keyPressed(QKeyEvent *event, bool post)
423 if (m_next) m_next->keyPressed(event, post);
426 void QSGItemKeyFilter::keyReleased(QKeyEvent *event, bool post)
428 if (m_next) m_next->keyReleased(event, post);
431 void QSGItemKeyFilter::inputMethodEvent(QInputMethodEvent *event, bool post)
434 m_next->inputMethodEvent(event, post);
439 QVariant QSGItemKeyFilter::inputMethodQuery(Qt::InputMethodQuery query) const
441 if (m_next) return m_next->inputMethodQuery(query);
445 void QSGItemKeyFilter::componentComplete()
447 if (m_next) m_next->componentComplete();
450 \qmlclass KeyNavigation QSGKeyNavigationAttached
451 \inqmlmodule QtQuick 2
452 \ingroup qml-basic-interaction-elements
453 \brief The KeyNavigation attached property supports key navigation by arrow keys.
455 Key-based user interfaces commonly allow the use of arrow keys to navigate between
456 focusable items. The KeyNavigation attached property enables this behavior by providing a
457 convenient way to specify the item that should gain focus when an arrow or tab key is pressed.
459 The following example provides key navigation for a 2x2 grid of items:
461 \snippet doc/src/snippets/declarative/keynavigation.qml 0
463 The top-left item initially receives focus by setting \l {Item::}{focus} to
464 \c true. When an arrow key is pressed, the focus will move to the
465 appropriate item, as defined by the value that has been set for
466 the KeyNavigation \l left, \l right, \l up or \l down properties.
468 Note that if a KeyNavigation attached property receives the key press and release
469 events for a requested arrow or tab key, the event is accepted and does not
470 propagate any further.
472 By default, KeyNavigation receives key events after the item to which it is attached.
473 If the item accepts the key event, the KeyNavigation attached property will not
474 receive an event for that key. Setting the \l priority property to
475 \c KeyNavigation.BeforeItem allows the event to be used for key navigation
476 before the item, rather than after.
478 If item to which the focus is switching is not enabled or visible, an attempt will
479 be made to skip this item and focus on the next. This is possible if there are
480 a chain of items with the same KeyNavigation handler. If multiple items in a row are not enabled
481 or visible, they will also be skipped.
483 KeyNavigation will implicitly set the other direction to return focus to this item. So if you set
484 \l left to another item, \l right will be set on that item's KeyNavigation to set focus back to this
485 item. However, if that item's KeyNavigation has had right explicitly set then no change will occur.
486 This means that the above example could have been written, with the same behaviour, without specifing
487 KeyNavigation.right or KeyNavigation.down for any of the items.
489 \sa {Keys}{Keys attached property}
493 \qmlproperty Item QtQuick2::KeyNavigation::left
494 \qmlproperty Item QtQuick2::KeyNavigation::right
495 \qmlproperty Item QtQuick2::KeyNavigation::up
496 \qmlproperty Item QtQuick2::KeyNavigation::down
497 \qmlproperty Item QtQuick2::KeyNavigation::tab
498 \qmlproperty Item QtQuick2::KeyNavigation::backtab
500 These properties hold the item to assign focus to
501 when the left, right, up or down cursor keys, or the
506 \qmlproperty Item QtQuick2::KeyNavigation::tab
507 \qmlproperty Item QtQuick2::KeyNavigation::backtab
509 These properties hold the item to assign focus to
510 when the Tab key or Shift+Tab key combination (Backtab) are pressed.
513 QSGKeyNavigationAttached::QSGKeyNavigationAttached(QObject *parent)
514 : QObject(*(new QSGKeyNavigationAttachedPrivate), parent),
515 QSGItemKeyFilter(qobject_cast<QSGItem*>(parent))
517 m_processPost = true;
520 QSGKeyNavigationAttached *
521 QSGKeyNavigationAttached::qmlAttachedProperties(QObject *obj)
523 return new QSGKeyNavigationAttached(obj);
526 QSGItem *QSGKeyNavigationAttached::left() const
528 Q_D(const QSGKeyNavigationAttached);
532 void QSGKeyNavigationAttached::setLeft(QSGItem *i)
534 Q_D(QSGKeyNavigationAttached);
539 QSGKeyNavigationAttached* other =
540 qobject_cast<QSGKeyNavigationAttached*>(qmlAttachedPropertiesObject<QSGKeyNavigationAttached>(i));
541 if (other && !other->d_func()->rightSet){
542 other->d_func()->right = qobject_cast<QSGItem*>(parent());
543 emit other->rightChanged();
548 QSGItem *QSGKeyNavigationAttached::right() const
550 Q_D(const QSGKeyNavigationAttached);
554 void QSGKeyNavigationAttached::setRight(QSGItem *i)
556 Q_D(QSGKeyNavigationAttached);
561 QSGKeyNavigationAttached* other =
562 qobject_cast<QSGKeyNavigationAttached*>(qmlAttachedPropertiesObject<QSGKeyNavigationAttached>(i));
563 if (other && !other->d_func()->leftSet){
564 other->d_func()->left = qobject_cast<QSGItem*>(parent());
565 emit other->leftChanged();
570 QSGItem *QSGKeyNavigationAttached::up() const
572 Q_D(const QSGKeyNavigationAttached);
576 void QSGKeyNavigationAttached::setUp(QSGItem *i)
578 Q_D(QSGKeyNavigationAttached);
583 QSGKeyNavigationAttached* other =
584 qobject_cast<QSGKeyNavigationAttached*>(qmlAttachedPropertiesObject<QSGKeyNavigationAttached>(i));
585 if (other && !other->d_func()->downSet){
586 other->d_func()->down = qobject_cast<QSGItem*>(parent());
587 emit other->downChanged();
592 QSGItem *QSGKeyNavigationAttached::down() const
594 Q_D(const QSGKeyNavigationAttached);
598 void QSGKeyNavigationAttached::setDown(QSGItem *i)
600 Q_D(QSGKeyNavigationAttached);
605 QSGKeyNavigationAttached* other =
606 qobject_cast<QSGKeyNavigationAttached*>(qmlAttachedPropertiesObject<QSGKeyNavigationAttached>(i));
607 if(other && !other->d_func()->upSet){
608 other->d_func()->up = qobject_cast<QSGItem*>(parent());
609 emit other->upChanged();
614 QSGItem *QSGKeyNavigationAttached::tab() const
616 Q_D(const QSGKeyNavigationAttached);
620 void QSGKeyNavigationAttached::setTab(QSGItem *i)
622 Q_D(QSGKeyNavigationAttached);
627 QSGKeyNavigationAttached* other =
628 qobject_cast<QSGKeyNavigationAttached*>(qmlAttachedPropertiesObject<QSGKeyNavigationAttached>(i));
629 if(other && !other->d_func()->backtabSet){
630 other->d_func()->backtab = qobject_cast<QSGItem*>(parent());
631 emit other->backtabChanged();
636 QSGItem *QSGKeyNavigationAttached::backtab() const
638 Q_D(const QSGKeyNavigationAttached);
642 void QSGKeyNavigationAttached::setBacktab(QSGItem *i)
644 Q_D(QSGKeyNavigationAttached);
648 d->backtabSet = true;
649 QSGKeyNavigationAttached* other =
650 qobject_cast<QSGKeyNavigationAttached*>(qmlAttachedPropertiesObject<QSGKeyNavigationAttached>(i));
651 if(other && !other->d_func()->tabSet){
652 other->d_func()->tab = qobject_cast<QSGItem*>(parent());
653 emit other->tabChanged();
655 emit backtabChanged();
659 \qmlproperty enumeration QtQuick2::KeyNavigation::priority
661 This property determines whether the keys are processed before
662 or after the attached item's own key handling.
665 \o KeyNavigation.BeforeItem - process the key events before normal
666 item key processing. If the event is used for key navigation, it will be accepted and will not
667 be passed on to the item.
668 \o KeyNavigation.AfterItem (default) - process the key events after normal item key
669 handling. If the item accepts the key event it will not be
670 handled by the KeyNavigation attached property handler.
673 QSGKeyNavigationAttached::Priority QSGKeyNavigationAttached::priority() const
675 return m_processPost ? AfterItem : BeforeItem;
678 void QSGKeyNavigationAttached::setPriority(Priority order)
680 bool processPost = order == AfterItem;
681 if (processPost != m_processPost) {
682 m_processPost = processPost;
683 emit priorityChanged();
687 void QSGKeyNavigationAttached::keyPressed(QKeyEvent *event, bool post)
689 Q_D(QSGKeyNavigationAttached);
692 if (post != m_processPost) {
693 QSGItemKeyFilter::keyPressed(event, post);
698 switch(event->key()) {
700 if (QSGItem *parentItem = qobject_cast<QSGItem*>(parent()))
701 mirror = QSGItemPrivate::get(parentItem)->effectiveLayoutMirror;
702 QSGItem* leftItem = mirror ? d->right : d->left;
704 setFocusNavigation(leftItem, mirror ? "right" : "left");
709 case Qt::Key_Right: {
710 if (QSGItem *parentItem = qobject_cast<QSGItem*>(parent()))
711 mirror = QSGItemPrivate::get(parentItem)->effectiveLayoutMirror;
712 QSGItem* rightItem = mirror ? d->left : d->right;
714 setFocusNavigation(rightItem, mirror ? "left" : "right");
721 setFocusNavigation(d->up, "up");
727 setFocusNavigation(d->down, "down");
733 setFocusNavigation(d->tab, "tab");
737 case Qt::Key_Backtab:
739 setFocusNavigation(d->backtab, "backtab");
747 if (!event->isAccepted()) QSGItemKeyFilter::keyPressed(event, post);
750 void QSGKeyNavigationAttached::keyReleased(QKeyEvent *event, bool post)
752 Q_D(QSGKeyNavigationAttached);
755 if (post != m_processPost) {
756 QSGItemKeyFilter::keyReleased(event, post);
761 switch(event->key()) {
763 if (QSGItem *parentItem = qobject_cast<QSGItem*>(parent()))
764 mirror = QSGItemPrivate::get(parentItem)->effectiveLayoutMirror;
765 if (mirror ? d->right : d->left)
769 if (QSGItem *parentItem = qobject_cast<QSGItem*>(parent()))
770 mirror = QSGItemPrivate::get(parentItem)->effectiveLayoutMirror;
771 if (mirror ? d->left : d->right)
789 case Qt::Key_Backtab:
798 if (!event->isAccepted()) QSGItemKeyFilter::keyReleased(event, post);
801 void QSGKeyNavigationAttached::setFocusNavigation(QSGItem *currentItem, const char *dir)
803 QSGItem *initialItem = currentItem;
804 bool isNextItem = false;
807 if (currentItem->isVisible() && currentItem->isEnabled()) {
808 currentItem->setFocus(true);
811 qmlAttachedPropertiesObject<QSGKeyNavigationAttached>(currentItem, false);
813 QSGItem *tempItem = qvariant_cast<QSGItem*>(attached->property(dir));
815 currentItem = tempItem;
821 while (currentItem != initialItem && isNextItem);
824 const QSGKeysAttached::SigMap QSGKeysAttached::sigMap[] = {
825 { Qt::Key_Left, "leftPressed" },
826 { Qt::Key_Right, "rightPressed" },
827 { Qt::Key_Up, "upPressed" },
828 { Qt::Key_Down, "downPressed" },
829 { Qt::Key_Tab, "tabPressed" },
830 { Qt::Key_Backtab, "backtabPressed" },
831 { Qt::Key_Asterisk, "asteriskPressed" },
832 { Qt::Key_NumberSign, "numberSignPressed" },
833 { Qt::Key_Escape, "escapePressed" },
834 { Qt::Key_Return, "returnPressed" },
835 { Qt::Key_Enter, "enterPressed" },
836 { Qt::Key_Delete, "deletePressed" },
837 { Qt::Key_Space, "spacePressed" },
838 { Qt::Key_Back, "backPressed" },
839 { Qt::Key_Cancel, "cancelPressed" },
840 { Qt::Key_Select, "selectPressed" },
841 { Qt::Key_Yes, "yesPressed" },
842 { Qt::Key_No, "noPressed" },
843 { Qt::Key_Context1, "context1Pressed" },
844 { Qt::Key_Context2, "context2Pressed" },
845 { Qt::Key_Context3, "context3Pressed" },
846 { Qt::Key_Context4, "context4Pressed" },
847 { Qt::Key_Call, "callPressed" },
848 { Qt::Key_Hangup, "hangupPressed" },
849 { Qt::Key_Flip, "flipPressed" },
850 { Qt::Key_Menu, "menuPressed" },
851 { Qt::Key_VolumeUp, "volumeUpPressed" },
852 { Qt::Key_VolumeDown, "volumeDownPressed" },
856 bool QSGKeysAttachedPrivate::isConnected(const char *signalName)
858 return isSignalConnected(signalIndex(signalName));
862 \qmlclass Keys QSGKeysAttached
863 \inqmlmodule QtQuick 2
864 \ingroup qml-basic-interaction-elements
865 \brief The Keys attached property provides key handling to Items.
867 All visual primitives support key handling via the Keys
868 attached property. Keys can be handled via the onPressed
869 and onReleased signal properties.
871 The signal properties have a \l KeyEvent parameter, named
872 \e event which contains details of the event. If a key is
873 handled \e event.accepted should be set to true to prevent the
874 event from propagating up the item hierarchy.
876 \section1 Example Usage
878 The following example shows how the general onPressed handler can
879 be used to test for a certain key; in this case, the left cursor
882 \snippet doc/src/snippets/declarative/keys/keys-pressed.qml key item
884 Some keys may alternatively be handled via specific signal properties,
885 for example \e onSelectPressed. These handlers automatically set
886 \e event.accepted to true.
888 \snippet doc/src/snippets/declarative/keys/keys-handler.qml key item
890 See \l{Qt::Key}{Qt.Key} for the list of keyboard codes.
892 \section1 Key Handling Priorities
894 The Keys attached property can be configured to handle key events
895 before or after the item it is attached to. This makes it possible
896 to intercept events in order to override an item's default behavior,
897 or act as a fallback for keys not handled by the item.
899 If \l priority is Keys.BeforeItem (default) the order of key event processing is:
902 \o Items specified in \c forwardTo
903 \o specific key handlers, e.g. onReturnPressed
904 \o onKeyPress, onKeyRelease handlers
905 \o Item specific key handling, e.g. TextInput key handling
909 If priority is Keys.AfterItem the order of key event processing is:
912 \o Item specific key handling, e.g. TextInput key handling
913 \o Items specified in \c forwardTo
914 \o specific key handlers, e.g. onReturnPressed
915 \o onKeyPress, onKeyRelease handlers
919 If the event is accepted during any of the above steps, key
922 \sa KeyEvent, {KeyNavigation}{KeyNavigation attached property}
926 \qmlproperty bool QtQuick2::Keys::enabled
928 This flags enables key handling if true (default); otherwise
929 no key handlers will be called.
933 \qmlproperty enumeration QtQuick2::Keys::priority
935 This property determines whether the keys are processed before
936 or after the attached item's own key handling.
939 \o Keys.BeforeItem (default) - process the key events before normal
940 item key processing. If the event is accepted it will not
941 be passed on to the item.
942 \o Keys.AfterItem - process the key events after normal item key
943 handling. If the item accepts the key event it will not be
944 handled by the Keys attached property handler.
949 \qmlproperty list<Object> QtQuick2::Keys::forwardTo
951 This property provides a way to forward key presses, key releases, and keyboard input
952 coming from input methods to other items. This can be useful when you want
953 one item to handle some keys (e.g. the up and down arrow keys), and another item to
954 handle other keys (e.g. the left and right arrow keys). Once an item that has been
955 forwarded keys accepts the event it is no longer forwarded to items later in the
958 This example forwards key events to two lists:
969 Keys.forwardTo: [list1, list2]
976 \qmlsignal QtQuick2::Keys::onPressed(KeyEvent event)
978 This handler is called when a key has been pressed. The \a event
979 parameter provides information about the event.
983 \qmlsignal QtQuick2::Keys::onReleased(KeyEvent event)
985 This handler is called when a key has been released. The \a event
986 parameter provides information about the event.
990 \qmlsignal QtQuick2::Keys::onDigit0Pressed(KeyEvent event)
992 This handler is called when the digit '0' has been pressed. The \a event
993 parameter provides information about the event.
997 \qmlsignal QtQuick2::Keys::onDigit1Pressed(KeyEvent event)
999 This handler is called when the digit '1' has been pressed. The \a event
1000 parameter provides information about the event.
1004 \qmlsignal QtQuick2::Keys::onDigit2Pressed(KeyEvent event)
1006 This handler is called when the digit '2' has been pressed. The \a event
1007 parameter provides information about the event.
1011 \qmlsignal QtQuick2::Keys::onDigit3Pressed(KeyEvent event)
1013 This handler is called when the digit '3' has been pressed. The \a event
1014 parameter provides information about the event.
1018 \qmlsignal QtQuick2::Keys::onDigit4Pressed(KeyEvent event)
1020 This handler is called when the digit '4' has been pressed. The \a event
1021 parameter provides information about the event.
1025 \qmlsignal QtQuick2::Keys::onDigit5Pressed(KeyEvent event)
1027 This handler is called when the digit '5' has been pressed. The \a event
1028 parameter provides information about the event.
1032 \qmlsignal QtQuick2::Keys::onDigit6Pressed(KeyEvent event)
1034 This handler is called when the digit '6' has been pressed. The \a event
1035 parameter provides information about the event.
1039 \qmlsignal QtQuick2::Keys::onDigit7Pressed(KeyEvent event)
1041 This handler is called when the digit '7' has been pressed. The \a event
1042 parameter provides information about the event.
1046 \qmlsignal QtQuick2::Keys::onDigit8Pressed(KeyEvent event)
1048 This handler is called when the digit '8' has been pressed. The \a event
1049 parameter provides information about the event.
1053 \qmlsignal QtQuick2::Keys::onDigit9Pressed(KeyEvent event)
1055 This handler is called when the digit '9' has been pressed. The \a event
1056 parameter provides information about the event.
1060 \qmlsignal QtQuick2::Keys::onLeftPressed(KeyEvent event)
1062 This handler is called when the Left arrow has been pressed. The \a event
1063 parameter provides information about the event.
1067 \qmlsignal QtQuick2::Keys::onRightPressed(KeyEvent event)
1069 This handler is called when the Right arrow has been pressed. The \a event
1070 parameter provides information about the event.
1074 \qmlsignal QtQuick2::Keys::onUpPressed(KeyEvent event)
1076 This handler is called when the Up arrow has been pressed. The \a event
1077 parameter provides information about the event.
1081 \qmlsignal QtQuick2::Keys::onDownPressed(KeyEvent event)
1083 This handler is called when the Down arrow has been pressed. The \a event
1084 parameter provides information about the event.
1088 \qmlsignal QtQuick2::Keys::onTabPressed(KeyEvent event)
1090 This handler is called when the Tab key has been pressed. The \a event
1091 parameter provides information about the event.
1095 \qmlsignal QtQuick2::Keys::onBacktabPressed(KeyEvent event)
1097 This handler is called when the Shift+Tab key combination (Backtab) has
1098 been pressed. The \a event parameter provides information about the event.
1102 \qmlsignal QtQuick2::Keys::onAsteriskPressed(KeyEvent event)
1104 This handler is called when the Asterisk '*' has been pressed. The \a event
1105 parameter provides information about the event.
1109 \qmlsignal QtQuick2::Keys::onEscapePressed(KeyEvent event)
1111 This handler is called when the Escape key has been pressed. The \a event
1112 parameter provides information about the event.
1116 \qmlsignal QtQuick2::Keys::onReturnPressed(KeyEvent event)
1118 This handler is called when the Return key has been pressed. The \a event
1119 parameter provides information about the event.
1123 \qmlsignal QtQuick2::Keys::onEnterPressed(KeyEvent event)
1125 This handler is called when the Enter key has been pressed. The \a event
1126 parameter provides information about the event.
1130 \qmlsignal QtQuick2::Keys::onDeletePressed(KeyEvent event)
1132 This handler is called when the Delete key has been pressed. The \a event
1133 parameter provides information about the event.
1137 \qmlsignal QtQuick2::Keys::onSpacePressed(KeyEvent event)
1139 This handler is called when the Space key has been pressed. The \a event
1140 parameter provides information about the event.
1144 \qmlsignal QtQuick2::Keys::onBackPressed(KeyEvent event)
1146 This handler is called when the Back key has been pressed. The \a event
1147 parameter provides information about the event.
1151 \qmlsignal QtQuick2::Keys::onCancelPressed(KeyEvent event)
1153 This handler is called when the Cancel key has been pressed. The \a event
1154 parameter provides information about the event.
1158 \qmlsignal QtQuick2::Keys::onSelectPressed(KeyEvent event)
1160 This handler is called when the Select key has been pressed. The \a event
1161 parameter provides information about the event.
1165 \qmlsignal QtQuick2::Keys::onYesPressed(KeyEvent event)
1167 This handler is called when the Yes key has been pressed. The \a event
1168 parameter provides information about the event.
1172 \qmlsignal QtQuick2::Keys::onNoPressed(KeyEvent event)
1174 This handler is called when the No key has been pressed. The \a event
1175 parameter provides information about the event.
1179 \qmlsignal QtQuick2::Keys::onContext1Pressed(KeyEvent event)
1181 This handler is called when the Context1 key has been pressed. The \a event
1182 parameter provides information about the event.
1186 \qmlsignal QtQuick2::Keys::onContext2Pressed(KeyEvent event)
1188 This handler is called when the Context2 key has been pressed. The \a event
1189 parameter provides information about the event.
1193 \qmlsignal QtQuick2::Keys::onContext3Pressed(KeyEvent event)
1195 This handler is called when the Context3 key has been pressed. The \a event
1196 parameter provides information about the event.
1200 \qmlsignal QtQuick2::Keys::onContext4Pressed(KeyEvent event)
1202 This handler is called when the Context4 key has been pressed. The \a event
1203 parameter provides information about the event.
1207 \qmlsignal QtQuick2::Keys::onCallPressed(KeyEvent event)
1209 This handler is called when the Call key has been pressed. The \a event
1210 parameter provides information about the event.
1214 \qmlsignal QtQuick2::Keys::onHangupPressed(KeyEvent event)
1216 This handler is called when the Hangup key has been pressed. The \a event
1217 parameter provides information about the event.
1221 \qmlsignal QtQuick2::Keys::onFlipPressed(KeyEvent event)
1223 This handler is called when the Flip key has been pressed. The \a event
1224 parameter provides information about the event.
1228 \qmlsignal QtQuick2::Keys::onMenuPressed(KeyEvent event)
1230 This handler is called when the Menu key has been pressed. The \a event
1231 parameter provides information about the event.
1235 \qmlsignal QtQuick2::Keys::onVolumeUpPressed(KeyEvent event)
1237 This handler is called when the VolumeUp key has been pressed. The \a event
1238 parameter provides information about the event.
1242 \qmlsignal QtQuick2::Keys::onVolumeDownPressed(KeyEvent event)
1244 This handler is called when the VolumeDown key has been pressed. The \a event
1245 parameter provides information about the event.
1248 QSGKeysAttached::QSGKeysAttached(QObject *parent)
1249 : QObject(*(new QSGKeysAttachedPrivate), parent),
1250 QSGItemKeyFilter(qobject_cast<QSGItem*>(parent))
1252 Q_D(QSGKeysAttached);
1253 m_processPost = false;
1254 d->item = qobject_cast<QSGItem*>(parent);
1257 QSGKeysAttached::~QSGKeysAttached()
1261 QSGKeysAttached::Priority QSGKeysAttached::priority() const
1263 return m_processPost ? AfterItem : BeforeItem;
1266 void QSGKeysAttached::setPriority(Priority order)
1268 bool processPost = order == AfterItem;
1269 if (processPost != m_processPost) {
1270 m_processPost = processPost;
1271 emit priorityChanged();
1275 void QSGKeysAttached::componentComplete()
1277 Q_D(QSGKeysAttached);
1279 for (int ii = 0; ii < d->targets.count(); ++ii) {
1280 QSGItem *targetItem = d->targets.at(ii);
1281 if (targetItem && (targetItem->flags() & QSGItem::ItemAcceptsInputMethod)) {
1282 d->item->setFlag(QSGItem::ItemAcceptsInputMethod);
1289 void QSGKeysAttached::keyPressed(QKeyEvent *event, bool post)
1291 Q_D(QSGKeysAttached);
1292 if (post != m_processPost || !d->enabled || d->inPress) {
1294 QSGItemKeyFilter::keyPressed(event, post);
1298 // first process forwards
1299 if (d->item && d->item->canvas()) {
1301 for (int ii = 0; ii < d->targets.count(); ++ii) {
1302 QSGItem *i = d->targets.at(ii);
1303 if (i && i->isVisible()) {
1304 d->item->canvas()->sendEvent(i, event);
1305 if (event->isAccepted()) {
1314 QSGKeyEvent ke(*event);
1315 QByteArray keySignal = keyToSignal(event->key());
1316 if (!keySignal.isEmpty()) {
1317 keySignal += "(QSGKeyEvent*)";
1318 if (d->isConnected(keySignal)) {
1319 // If we specifically handle a key then default to accepted
1320 ke.setAccepted(true);
1321 int idx = QSGKeysAttached::staticMetaObject.indexOfSignal(keySignal);
1322 metaObject()->method(idx).invoke(this, Qt::DirectConnection, Q_ARG(QSGKeyEvent*, &ke));
1325 if (!ke.isAccepted())
1327 event->setAccepted(ke.isAccepted());
1329 if (!event->isAccepted()) QSGItemKeyFilter::keyPressed(event, post);
1332 void QSGKeysAttached::keyReleased(QKeyEvent *event, bool post)
1334 Q_D(QSGKeysAttached);
1335 if (post != m_processPost || !d->enabled || d->inRelease) {
1337 QSGItemKeyFilter::keyReleased(event, post);
1341 if (d->item && d->item->canvas()) {
1342 d->inRelease = true;
1343 for (int ii = 0; ii < d->targets.count(); ++ii) {
1344 QSGItem *i = d->targets.at(ii);
1345 if (i && i->isVisible()) {
1346 d->item->canvas()->sendEvent(i, event);
1347 if (event->isAccepted()) {
1348 d->inRelease = false;
1353 d->inRelease = false;
1356 QSGKeyEvent ke(*event);
1358 event->setAccepted(ke.isAccepted());
1360 if (!event->isAccepted()) QSGItemKeyFilter::keyReleased(event, post);
1363 void QSGKeysAttached::inputMethodEvent(QInputMethodEvent *event, bool post)
1365 Q_D(QSGKeysAttached);
1366 if (post == m_processPost && d->item && !d->inIM && d->item->canvas()) {
1368 for (int ii = 0; ii < d->targets.count(); ++ii) {
1369 QSGItem *i = d->targets.at(ii);
1370 if (i && i->isVisible() && (i->flags() & QSGItem::ItemAcceptsInputMethod)) {
1371 d->item->canvas()->sendEvent(i, event);
1372 if (event->isAccepted()) {
1381 QSGItemKeyFilter::inputMethodEvent(event, post);
1384 QVariant QSGKeysAttached::inputMethodQuery(Qt::InputMethodQuery query) const
1386 Q_D(const QSGKeysAttached);
1388 for (int ii = 0; ii < d->targets.count(); ++ii) {
1389 QSGItem *i = d->targets.at(ii);
1390 if (i && i->isVisible() && (i->flags() & QSGItem::ItemAcceptsInputMethod) && i == d->imeItem) {
1391 //### how robust is i == d->imeItem check?
1392 QVariant v = i->inputMethodQuery(query);
1393 if (v.userType() == QVariant::RectF)
1394 v = d->item->mapRectFromItem(i, v.toRectF()); //### cost?
1399 return QSGItemKeyFilter::inputMethodQuery(query);
1402 QSGKeysAttached *QSGKeysAttached::qmlAttachedProperties(QObject *obj)
1404 return new QSGKeysAttached(obj);
1408 \qmlclass LayoutMirroring QSGLayoutMirroringAttached
1409 \inqmlmodule QtQuick 2
1410 \ingroup qml-utility-elements
1411 \brief The LayoutMirroring attached property is used to mirror layout behavior.
1413 The LayoutMirroring attached property is used to horizontally mirror \l {anchor-layout}{Item anchors},
1414 \l{Using QML Positioner and Repeater Items}{positioner} elements (such as \l Row and \l Grid)
1415 and views (such as \l GridView and horizontal \l ListView). Mirroring is a visual change: left
1416 anchors become right anchors, and positioner elements like \l Grid and \l Row reverse the
1417 horizontal layout of child items.
1419 Mirroring is enabled for an item by setting the \l enabled property to true. By default, this
1420 only affects the item itself; setting the \l childrenInherit property to true propagates the mirroring
1421 behavior to all child elements as well. If the \c LayoutMirroring attached property has not been defined
1422 for an item, mirroring is not enabled.
1424 The following example shows mirroring in action. The \l Row below is specified as being anchored
1425 to the left of its parent. However, since mirroring has been enabled, the anchor is horizontally
1426 reversed and it is now anchored to the right. Also, since items in a \l Row are positioned
1427 from left to right by default, they are now positioned from right to left instead, as demonstrated
1428 by the numbering and opacity of the items:
1430 \snippet doc/src/snippets/declarative/layoutmirroring.qml 0
1432 \image layoutmirroring.png
1434 Layout mirroring is useful when it is necessary to support both left-to-right and right-to-left
1435 layout versions of an application to target different language areas. The \l childrenInherit
1436 property allows layout mirroring to be applied without manually setting layout configurations
1437 for every item in an application. Keep in mind, however, that mirroring does not affect any
1438 positioning that is defined by the \l Item \l {Item::}{x} coordinate value, so even with
1439 mirroring enabled, it will often be necessary to apply some layout fixes to support the
1440 desired layout direction. Also, it may be necessary to disable the mirroring of individual
1441 child items (by setting \l {enabled}{LayoutMirroring.enabled} to false for such items) if
1442 mirroring is not the desired behavior, or if the child item already implements mirroring in
1445 See \l {QML Right-to-left User Interfaces} for further details on using \c LayoutMirroring and
1446 other related features to implement right-to-left support for an application.
1450 \qmlproperty bool QtQuick2::LayoutMirroring::enabled
1452 This property holds whether the item's layout is mirrored horizontally. Setting this to true
1453 horizontally reverses \l {anchor-layout}{anchor} settings such that left anchors become right,
1454 and right anchors become left. For \l{Using QML Positioner and Repeater Items}{positioner} elements
1455 (such as \l Row and \l Grid) and view elements (such as \l {GridView}{GridView} and \l {ListView}{ListView})
1456 this also mirrors the horizontal layout direction of the item.
1458 The default value is false.
1462 \qmlproperty bool QtQuick2::LayoutMirroring::childrenInherit
1464 This property holds whether the \l {enabled}{LayoutMirroring.enabled} value for this item
1465 is inherited by its children.
1467 The default value is false.
1471 QSGLayoutMirroringAttached::QSGLayoutMirroringAttached(QObject *parent) : QObject(parent), itemPrivate(0)
1473 if (QSGItem *item = qobject_cast<QSGItem*>(parent)) {
1474 itemPrivate = QSGItemPrivate::get(item);
1475 itemPrivate->attachedLayoutDirection = this;
1477 qmlInfo(parent) << tr("LayoutDirection attached property only works with Items");
1480 QSGLayoutMirroringAttached * QSGLayoutMirroringAttached::qmlAttachedProperties(QObject *object)
1482 return new QSGLayoutMirroringAttached(object);
1485 bool QSGLayoutMirroringAttached::enabled() const
1487 return itemPrivate ? itemPrivate->effectiveLayoutMirror : false;
1490 void QSGLayoutMirroringAttached::setEnabled(bool enabled)
1495 itemPrivate->isMirrorImplicit = false;
1496 if (enabled != itemPrivate->effectiveLayoutMirror) {
1497 itemPrivate->setLayoutMirror(enabled);
1498 if (itemPrivate->inheritMirrorFromItem)
1499 itemPrivate->resolveLayoutMirror();
1503 void QSGLayoutMirroringAttached::resetEnabled()
1505 if (itemPrivate && !itemPrivate->isMirrorImplicit) {
1506 itemPrivate->isMirrorImplicit = true;
1507 itemPrivate->resolveLayoutMirror();
1511 bool QSGLayoutMirroringAttached::childrenInherit() const
1513 return itemPrivate ? itemPrivate->inheritMirrorFromItem : false;
1516 void QSGLayoutMirroringAttached::setChildrenInherit(bool childrenInherit) {
1517 if (itemPrivate && childrenInherit != itemPrivate->inheritMirrorFromItem) {
1518 itemPrivate->inheritMirrorFromItem = childrenInherit;
1519 itemPrivate->resolveLayoutMirror();
1520 childrenInheritChanged();
1524 void QSGItemPrivate::resolveLayoutMirror()
1527 if (QSGItem *parentItem = q->parentItem()) {
1528 QSGItemPrivate *parentPrivate = QSGItemPrivate::get(parentItem);
1529 setImplicitLayoutMirror(parentPrivate->inheritedLayoutMirror, parentPrivate->inheritMirrorFromParent);
1531 setImplicitLayoutMirror(isMirrorImplicit ? false : effectiveLayoutMirror, inheritMirrorFromItem);
1535 void QSGItemPrivate::setImplicitLayoutMirror(bool mirror, bool inherit)
1537 inherit = inherit || inheritMirrorFromItem;
1538 if (!isMirrorImplicit && inheritMirrorFromItem)
1539 mirror = effectiveLayoutMirror;
1540 if (mirror == inheritedLayoutMirror && inherit == inheritMirrorFromParent)
1543 inheritMirrorFromParent = inherit;
1544 inheritedLayoutMirror = inheritMirrorFromParent ? mirror : false;
1546 if (isMirrorImplicit)
1547 setLayoutMirror(inherit ? inheritedLayoutMirror : false);
1548 for (int i = 0; i < childItems.count(); ++i) {
1549 if (QSGItem *child = qobject_cast<QSGItem *>(childItems.at(i))) {
1550 QSGItemPrivate *childPrivate = QSGItemPrivate::get(child);
1551 childPrivate->setImplicitLayoutMirror(inheritedLayoutMirror, inheritMirrorFromParent);
1556 void QSGItemPrivate::setLayoutMirror(bool mirror)
1558 if (mirror != effectiveLayoutMirror) {
1559 effectiveLayoutMirror = mirror;
1561 QSGAnchorsPrivate *anchor_d = QSGAnchorsPrivate::get(_anchors);
1562 anchor_d->fillChanged();
1563 anchor_d->centerInChanged();
1564 anchor_d->updateHorizontalAnchors();
1565 emit _anchors->mirroredChanged();
1568 if (attachedLayoutDirection) {
1569 emit attachedLayoutDirection->enabledChanged();
1576 \brief The QSGItem class provides the most basic of all visual items in QML.
1578 All visual items in Qt Declarative inherit from QSGItem. Although QSGItem
1579 has no visual appearance, it defines all the properties that are
1580 common across visual items - such as the x and y position, the
1581 width and height, \l {anchor-layout}{anchoring} and key handling.
1583 You can subclass QSGItem to provide your own custom visual item that inherits
1584 these features. Note that, because it does not draw anything, QSGItem sets the
1585 QGraphicsItem::ItemHasNoContents flag. If you subclass QSGItem to create a visual
1586 item, you will need to unset this flag.
1591 \qmlclass Item QSGItem
1592 \inqmlmodule QtQuick 2
1593 \ingroup qml-basic-visual-elements
1594 \brief The Item is the most basic of all visual items in QML.
1596 All visual items in Qt Declarative inherit from Item. Although Item
1597 has no visual appearance, it defines all the properties that are
1598 common across visual items - such as the x and y position, the
1599 width and height, \l {anchor-layout}{anchoring} and key handling.
1601 Item is also useful for grouping items together.
1618 fillMode: Image.Tile
1625 \section1 Key Handling
1627 Key handling is available to all Item-based visual elements via the \l {Keys}{Keys}
1628 attached property. The \e Keys attached property provides basic handlers such
1629 as \l {Keys::onPressed}{onPressed} and \l {Keys::onReleased}{onReleased},
1630 as well as handlers for specific keys, such as
1631 \l {Keys::onCancelPressed}{onCancelPressed}. The example below
1632 assigns \l {qmlfocus}{focus} to the item and handles
1633 the Left key via the general \e onPressed handler and the Select key via the
1634 onSelectPressed handler:
1640 if (event.key == Qt.Key_Left) {
1641 console.log("move left");
1642 event.accepted = true;
1645 Keys.onSelectPressed: console.log("Selected");
1649 See the \l {Keys}{Keys} attached property for detailed documentation.
1651 \section1 Layout Mirroring
1653 Item layouts can be mirrored using the \l {LayoutMirroring}{LayoutMirroring} attached property.
1658 \fn void QSGItem::childrenRectChanged(const QRectF &)
1663 \fn void QSGItem::baselineOffsetChanged(qreal)
1668 \fn void QSGItem::stateChanged(const QString &state)
1673 \fn void QSGItem::parentChanged(QSGItem *)
1678 \fn void QSGItem::smoothChanged(bool)
1683 \fn void QSGItem::clipChanged(bool)
1687 /*! \fn void QSGItem::transformOriginChanged(TransformOrigin)
1692 \fn void QSGItem::focusChanged(bool)
1697 \fn void QSGItem::activeFocusChanged(bool)
1701 \fn QSGItem::QSGItem(QSGItem *parent)
1703 Constructs a QSGItem with the given \a parent.
1705 QSGItem::QSGItem(QSGItem* parent)
1706 : QObject(*(new QSGItemPrivate), parent)
1714 QSGItem::QSGItem(QSGItemPrivate &dd, QSGItem *parent)
1715 : QObject(dd, parent)
1722 static int qt_item_count = 0;
1724 static void qt_print_item_count()
1726 qDebug("Number of leaked items: %i", qt_item_count);
1732 Destroys the QSGItem.
1738 if (qt_item_count < 0)
1739 qDebug("Item destroyed after qt_print_item_count() was called.");
1746 else if (d->canvas && d->itemNodeInstance)
1747 QSGCanvasPrivate::get(d->canvas)->cleanup(d->itemNodeInstance); // cleanup root
1748 // XXX todo - optimize
1749 while (!d->childItems.isEmpty())
1750 d->childItems.first()->setParentItem(0);
1752 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
1753 QSGAnchorsPrivate *anchor = d->changeListeners.at(ii).listener->anchorPrivate();
1755 anchor->clearItem(this);
1758 // XXX todo - the original checks if the parent is being destroyed
1759 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
1760 QSGAnchorsPrivate *anchor = d->changeListeners.at(ii).listener->anchorPrivate();
1761 if (anchor && anchor->item && anchor->item->parent() != this) //child will be deleted anyway
1762 anchor->updateOnComplete();
1765 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
1766 const QSGItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
1767 if (change.types & QSGItemPrivate::Destroyed)
1768 change.listener->itemDestroyed(this);
1770 d->changeListeners.clear();
1771 delete d->_anchorLines; d->_anchorLines = 0;
1772 delete d->_anchors; d->_anchors = 0;
1773 delete d->_stateGroup; d->_stateGroup = 0;
1774 delete d->_contents; d->_contents = 0;
1778 \qmlproperty enumeration QtQuick2::Item::transformOrigin
1779 This property holds the origin point around which scale and rotation transform.
1781 Nine transform origins are available, as shown in the image below.
1783 \image declarative-transformorigin.png
1785 This example rotates an image around its bottom-right corner.
1788 source: "myimage.png"
1789 transformOrigin: Item.BottomRight
1794 The default transform origin is \c Item.Center.
1796 To set an arbitrary transform origin point use the \l Scale or \l Rotation
1801 \qmlproperty Item QtQuick2::Item::parent
1802 This property holds the parent of the item.
1806 \property QSGItem::parent
1807 This property holds the parent of the item.
1809 void QSGItem::setParentItem(QSGItem *parentItem)
1812 if (parentItem == d->parentItem)
1815 d->removeFromDirtyList();
1817 QSGItem *oldParentItem = d->parentItem;
1818 QSGItem *scopeFocusedItem = 0;
1820 if (oldParentItem) {
1821 QSGItemPrivate *op = QSGItemPrivate::get(oldParentItem);
1823 QSGItem *scopeItem = 0;
1825 if (d->canvas && hasFocus()) {
1826 scopeItem = oldParentItem;
1827 while (!scopeItem->isFocusScope()) scopeItem = scopeItem->parentItem();
1828 scopeFocusedItem = this;
1829 } else if (d->canvas && !isFocusScope() && d->subFocusItem) {
1830 scopeItem = oldParentItem;
1831 while (!scopeItem->isFocusScope()) scopeItem = scopeItem->parentItem();
1832 scopeFocusedItem = d->subFocusItem;
1835 if (scopeFocusedItem)
1836 QSGCanvasPrivate::get(d->canvas)->clearFocusInScope(scopeItem, scopeFocusedItem,
1837 QSGCanvasPrivate::DontChangeFocusProperty);
1839 op->removeChild(this);
1842 d->parentItem = parentItem;
1844 QSGCanvas *parentCanvas = parentItem?QSGItemPrivate::get(parentItem)->canvas:0;
1845 if (d->canvas != parentCanvas) {
1846 QSGItemPrivate::InitializationState initState;
1848 d->initCanvas(&initState, parentCanvas);
1851 d->dirty(QSGItemPrivate::ParentChanged);
1854 QSGItemPrivate::get(d->parentItem)->addChild(this);
1856 d->setEffectiveVisibleRecur(d->calcEffectiveVisible());
1857 d->setEffectiveEnableRecur(d->calcEffectiveEnable());
1859 if (scopeFocusedItem && d->parentItem && d->canvas) {
1860 // We need to test whether this item becomes scope focused
1861 QSGItem *scopeItem = 0;
1862 scopeItem = d->parentItem;
1863 while (!scopeItem->isFocusScope()) scopeItem = scopeItem->parentItem();
1865 if (scopeItem->scopedFocusItem()) {
1866 QSGItemPrivate::get(scopeFocusedItem)->focus = false;
1867 emit scopeFocusedItem->focusChanged(false);
1869 QSGCanvasPrivate::get(d->canvas)->setFocusInScope(scopeItem, scopeFocusedItem,
1870 QSGCanvasPrivate::DontChangeFocusProperty);
1874 d->resolveLayoutMirror();
1876 d->itemChange(ItemParentHasChanged, d->parentItem);
1878 emit parentChanged(d->parentItem);
1881 void QSGItem::stackBefore(const QSGItem *sibling)
1884 if (!sibling || sibling == this || !d->parentItem || d->parentItem != QSGItemPrivate::get(sibling)->parentItem) {
1885 qWarning("QSGItem::stackBefore: Cannot stack before %p, which must be a sibling", sibling);
1889 QSGItemPrivate *parentPrivate = QSGItemPrivate::get(d->parentItem);
1891 int myIndex = parentPrivate->childItems.indexOf(this);
1892 int siblingIndex = parentPrivate->childItems.indexOf(const_cast<QSGItem *>(sibling));
1894 Q_ASSERT(myIndex != -1 && siblingIndex != -1);
1896 if (myIndex == siblingIndex - 1)
1899 parentPrivate->childItems.removeAt(myIndex);
1901 if (myIndex < siblingIndex) --siblingIndex;
1903 parentPrivate->childItems.insert(siblingIndex, this);
1905 parentPrivate->dirty(QSGItemPrivate::ChildrenStackingChanged);
1907 for (int ii = qMin(siblingIndex, myIndex); ii < parentPrivate->childItems.count(); ++ii)
1908 QSGItemPrivate::get(parentPrivate->childItems.at(ii))->siblingOrderChanged();
1911 void QSGItem::stackAfter(const QSGItem *sibling)
1914 if (!sibling || sibling == this || !d->parentItem || d->parentItem != QSGItemPrivate::get(sibling)->parentItem) {
1915 qWarning("QSGItem::stackAfter: Cannot stack after %p, which must be a sibling", sibling);
1919 QSGItemPrivate *parentPrivate = QSGItemPrivate::get(d->parentItem);
1921 int myIndex = parentPrivate->childItems.indexOf(this);
1922 int siblingIndex = parentPrivate->childItems.indexOf(const_cast<QSGItem *>(sibling));
1924 Q_ASSERT(myIndex != -1 && siblingIndex != -1);
1926 if (myIndex == siblingIndex + 1)
1929 parentPrivate->childItems.removeAt(myIndex);
1931 if (myIndex < siblingIndex) --siblingIndex;
1933 parentPrivate->childItems.insert(siblingIndex + 1, this);
1935 parentPrivate->dirty(QSGItemPrivate::ChildrenStackingChanged);
1937 for (int ii = qMin(myIndex, siblingIndex + 1); ii < parentPrivate->childItems.count(); ++ii)
1938 QSGItemPrivate::get(parentPrivate->childItems.at(ii))->siblingOrderChanged();
1942 Returns the QSGItem parent of this item.
1944 QSGItem *QSGItem::parentItem() const
1947 return d->parentItem;
1950 QSGEngine *QSGItem::sceneGraphEngine() const
1952 return canvas()->sceneGraphEngine();
1955 QSGCanvas *QSGItem::canvas() const
1961 static bool itemZOrder_sort(QSGItem *lhs, QSGItem *rhs)
1963 return lhs->z() < rhs->z();
1966 QList<QSGItem *> QSGItemPrivate::paintOrderChildItems() const
1968 // XXX todo - optimize, don't sort and return items that are
1969 // ignored anyway, like invisible or disabled items.
1970 QList<QSGItem *> items = childItems;
1971 qStableSort(items.begin(), items.end(), itemZOrder_sort);
1975 void QSGItemPrivate::addChild(QSGItem *child)
1979 Q_ASSERT(!childItems.contains(child));
1981 childItems.append(child);
1983 dirty(QSGItemPrivate::ChildrenChanged);
1985 itemChange(QSGItem::ItemChildAddedChange, child);
1987 emit q->childrenChanged();
1990 void QSGItemPrivate::removeChild(QSGItem *child)
1995 Q_ASSERT(childItems.contains(child));
1996 childItems.removeOne(child);
1997 Q_ASSERT(!childItems.contains(child));
1999 dirty(QSGItemPrivate::ChildrenChanged);
2001 itemChange(QSGItem::ItemChildRemovedChange, child);
2003 emit q->childrenChanged();
2006 void QSGItemPrivate::InitializationState::clear()
2011 void QSGItemPrivate::InitializationState::clear(QSGItem *fs)
2016 QSGItem *QSGItemPrivate::InitializationState::getFocusScope(QSGItem *item)
2019 QSGItem *fs = item->parentItem();
2020 while (!fs->isFocusScope())
2021 fs = fs->parentItem();
2027 void QSGItemPrivate::initCanvas(InitializationState *state, QSGCanvas *c)
2032 removeFromDirtyList();
2033 QSGCanvasPrivate *c = QSGCanvasPrivate::get(canvas);
2034 if (polishScheduled)
2035 c->itemsToPolish.remove(q);
2036 if (c->mouseGrabberItem == q)
2037 c->mouseGrabberItem = 0;
2039 c->hoverItems.removeAll(q);
2040 if (itemNodeInstance)
2041 c->cleanup(itemNodeInstance);
2046 if (canvas && polishScheduled)
2047 QSGCanvasPrivate::get(canvas)->itemsToPolish.insert(q);
2049 if (canvas && hoverEnabled && !canvas->hasMouseTracking())
2050 canvas->setMouseTracking(true);
2052 itemNodeInstance = 0;
2058 beforePaintNode = 0;
2060 InitializationState _dummy;
2061 InitializationState *childState = state;
2063 if (c && q->isFocusScope()) {
2065 childState = &_dummy;
2068 for (int ii = 0; ii < childItems.count(); ++ii) {
2069 QSGItem *child = childItems.at(ii);
2070 QSGItemPrivate::get(child)->initCanvas(childState, c);
2075 if (state->getFocusScope(q)->scopedFocusItem()) {
2077 emit q->focusChanged(false);
2079 QSGCanvasPrivate::get(canvas)->setFocusInScope(state->getFocusScope(q), q);
2085 itemChange(QSGItem::ItemSceneChange, c);
2089 Returns a transform that maps points from canvas space into item space.
2091 QTransform QSGItemPrivate::canvasToItemTransform() const
2093 // XXX todo - optimize
2094 return itemToCanvasTransform().inverted();
2098 Returns a transform that maps points from item space into canvas space.
2100 QTransform QSGItemPrivate::itemToCanvasTransform() const
2103 QTransform rv = parentItem?QSGItemPrivate::get(parentItem)->itemToCanvasTransform():QTransform();
2104 itemToParentTransform(rv);
2109 Motifies \a t with this items local transform relative to its parent.
2111 void QSGItemPrivate::itemToParentTransform(QTransform &t) const
2116 if (!transforms.isEmpty()) {
2118 for (int ii = transforms.count() - 1; ii >= 0; --ii)
2119 transforms.at(ii)->applyTo(&m);
2120 t = m.toTransform();
2123 if (scale != 1. || rotation != 0.) {
2124 QPointF tp = computeTransformOrigin();
2125 t.translate(tp.x(), tp.y());
2126 t.scale(scale, scale);
2128 t.translate(-tp.x(), -tp.y());
2134 \qmlproperty real QtQuick2::Item::childrenRect.x
2135 \qmlproperty real QtQuick2::Item::childrenRect.y
2136 \qmlproperty real QtQuick2::Item::childrenRect.width
2137 \qmlproperty real QtQuick2::Item::childrenRect.height
2139 The childrenRect properties allow an item access to the geometry of its
2140 children. This property is useful if you have an item that needs to be
2141 sized to fit its children.
2146 \qmlproperty list<Item> QtQuick2::Item::children
2147 \qmlproperty list<Object> QtQuick2::Item::resources
2149 The children property contains the list of visual children of this item.
2150 The resources property contains non-visual resources that you want to
2153 Generally you can rely on Item's default property to handle all this for
2154 you, but it can come in handy in some cases.
2173 Returns true if construction of the QML component is complete; otherwise
2176 It is often desirable to delay some processing until the component is
2179 \sa componentComplete()
2181 bool QSGItem::isComponentComplete() const
2184 return d->componentComplete;
2187 QSGItemPrivate::QSGItemPrivate()
2188 : _anchors(0), _contents(0), baselineOffset(0), _anchorLines(0), _stateGroup(0), origin(QSGItem::Center),
2190 flags(0), widthValid(false), heightValid(false), componentComplete(true),
2191 keepMouse(false), hoverEnabled(false), smooth(false), focus(false), activeFocus(false), notifiedFocus(false),
2192 notifiedActiveFocus(false), filtersChildMouseEvents(false), explicitVisible(true),
2193 effectiveVisible(true), explicitEnable(true), effectiveEnable(true), polishScheduled(false),
2194 inheritedLayoutMirror(false), effectiveLayoutMirror(false), isMirrorImplicit(true),
2195 inheritMirrorFromParent(false), inheritMirrorFromItem(false), childrenDoNotOverlap(false),
2197 canvas(0), parentItem(0),
2201 x(0), y(0), width(0), height(0), implicitWidth(0), implicitHeight(0),
2202 z(0), scale(1), rotation(0), opacity(1),
2204 attachedLayoutDirection(0), acceptedMouseButtons(0),
2205 imHints(Qt::ImhNone),
2209 dirtyAttributes(0), nextDirtyItem(0), prevDirtyItem(0),
2211 itemNodeInstance(0), opacityNode(0), clipNode(0), rootNode(0), groupNode(0), paintNode(0)
2212 , beforePaintNode(0), effectRefCount(0), hideRefCount(0)
2216 void QSGItemPrivate::init(QSGItem *parent)
2220 static bool atexit_registered = false;
2221 if (!atexit_registered) {
2222 atexit(qt_print_item_count);
2223 atexit_registered = true;
2228 baselineOffset.invalidate();
2231 q->setParentItem(parent);
2232 QSGItemPrivate *parentPrivate = QSGItemPrivate::get(parent);
2233 setImplicitLayoutMirror(parentPrivate->inheritedLayoutMirror, parentPrivate->inheritMirrorFromParent);
2237 void QSGItemPrivate::data_append(QDeclarativeListProperty<QObject> *prop, QObject *o)
2242 QSGItem *that = static_cast<QSGItem *>(prop->object);
2244 // This test is measurably (albeit only slightly) faster than qobject_cast<>()
2245 const QMetaObject *mo = o->metaObject();
2246 while (mo && mo != &QSGItem::staticMetaObject) {
2247 if (mo == &QGraphicsObject::staticMetaObject)
2248 qWarning("Cannot add a QtQuick 1.0 item (%s) into a QtQuick 2.0 scene!", o->metaObject()->className());
2249 mo = mo->d.superdata;
2253 QSGItem *item = static_cast<QSGItem *>(o);
2254 item->setParentItem(that);
2256 // XXX todo - do we really want this behavior?
2262 \qmlproperty list<Object> QtQuick2::Item::data
2265 The data property allows you to freely mix visual children and resources
2266 in an item. If you assign a visual item to the data list it becomes
2267 a child and if you assign any other object type, it is added as a resource.
2291 data is a behind-the-scenes property: you should never need to explicitly
2295 int QSGItemPrivate::data_count(QDeclarativeListProperty<QObject> *prop)
2302 QObject *QSGItemPrivate::data_at(QDeclarativeListProperty<QObject> *prop, int i)
2310 void QSGItemPrivate::data_clear(QDeclarativeListProperty<QObject> *prop)
2316 QObject *QSGItemPrivate::resources_at(QDeclarativeListProperty<QObject> *prop, int index)
2318 const QObjectList children = prop->object->children();
2319 if (index < children.count())
2320 return children.at(index);
2325 void QSGItemPrivate::resources_append(QDeclarativeListProperty<QObject> *prop, QObject *o)
2327 // XXX todo - do we really want this behavior?
2328 o->setParent(prop->object);
2331 int QSGItemPrivate::resources_count(QDeclarativeListProperty<QObject> *prop)
2333 return prop->object->children().count();
2336 void QSGItemPrivate::resources_clear(QDeclarativeListProperty<QObject> *prop)
2338 // XXX todo - do we really want this behavior?
2339 const QObjectList children = prop->object->children();
2340 for (int index = 0; index < children.count(); index++)
2341 children.at(index)->setParent(0);
2344 QSGItem *QSGItemPrivate::children_at(QDeclarativeListProperty<QSGItem> *prop, int index)
2346 QSGItemPrivate *p = QSGItemPrivate::get(static_cast<QSGItem *>(prop->object));
2347 if (index >= p->childItems.count() || index < 0)
2350 return p->childItems.at(index);
2353 void QSGItemPrivate::children_append(QDeclarativeListProperty<QSGItem> *prop, QSGItem *o)
2358 QSGItem *that = static_cast<QSGItem *>(prop->object);
2359 if (o->parentItem() == that)
2360 o->setParentItem(0);
2362 o->setParentItem(that);
2365 int QSGItemPrivate::children_count(QDeclarativeListProperty<QSGItem> *prop)
2367 QSGItemPrivate *p = QSGItemPrivate::get(static_cast<QSGItem *>(prop->object));
2368 return p->childItems.count();
2371 void QSGItemPrivate::children_clear(QDeclarativeListProperty<QSGItem> *prop)
2373 QSGItem *that = static_cast<QSGItem *>(prop->object);
2374 QSGItemPrivate *p = QSGItemPrivate::get(that);
2375 while (!p->childItems.isEmpty())
2376 p->childItems.at(0)->setParentItem(0);
2379 int QSGItemPrivate::transform_count(QDeclarativeListProperty<QSGTransform> *prop)
2381 QSGItem *that = static_cast<QSGItem *>(prop->object);
2382 return QSGItemPrivate::get(that)->transforms.count();
2385 void QSGTransform::appendToItem(QSGItem *item)
2391 QSGItemPrivate *p = QSGItemPrivate::get(item);
2393 if (!d->items.isEmpty() && !p->transforms.isEmpty() && p->transforms.contains(this)) {
2394 p->transforms.removeOne(this);
2395 p->transforms.append(this);
2397 p->transforms.append(this);
2398 d->items.append(item);
2401 p->dirty(QSGItemPrivate::Transform);
2404 void QSGTransform::prependToItem(QSGItem *item)
2410 QSGItemPrivate *p = QSGItemPrivate::get(item);
2412 if (!d->items.isEmpty() && !p->transforms.isEmpty() && p->transforms.contains(this)) {
2413 p->transforms.removeOne(this);
2414 p->transforms.prepend(this);
2416 p->transforms.prepend(this);
2417 d->items.append(item);
2420 p->dirty(QSGItemPrivate::Transform);
2423 void QSGItemPrivate::transform_append(QDeclarativeListProperty<QSGTransform> *prop, QSGTransform *transform)
2428 QSGItem *that = static_cast<QSGItem *>(prop->object);
2429 transform->appendToItem(that);
2432 QSGTransform *QSGItemPrivate::transform_at(QDeclarativeListProperty<QSGTransform> *prop, int idx)
2434 QSGItem *that = static_cast<QSGItem *>(prop->object);
2435 QSGItemPrivate *p = QSGItemPrivate::get(that);
2437 if (idx < 0 || idx >= p->transforms.count())
2440 return p->transforms.at(idx);
2443 void QSGItemPrivate::transform_clear(QDeclarativeListProperty<QSGTransform> *prop)
2445 QSGItem *that = static_cast<QSGItem *>(prop->object);
2446 QSGItemPrivate *p = QSGItemPrivate::get(that);
2448 for (int ii = 0; ii < p->transforms.count(); ++ii) {
2449 QSGTransform *t = p->transforms.at(ii);
2450 QSGTransformPrivate *tp = QSGTransformPrivate::get(t);
2451 tp->items.removeOne(that);
2454 p->transforms.clear();
2456 p->dirty(QSGItemPrivate::Transform);
2460 \property QSGItem::childrenRect
2461 \brief The geometry of an item's children.
2463 This property holds the (collective) position and size of the item's children.
2467 \qmlproperty real QtQuick2::Item::x
2468 \qmlproperty real QtQuick2::Item::y
2469 \qmlproperty real QtQuick2::Item::width
2470 \qmlproperty real QtQuick2::Item::height
2472 Defines the item's position and size relative to its parent.
2475 Item { x: 100; y: 100; width: 100; height: 100 }
2480 \qmlproperty real QtQuick2::Item::z
2482 Sets the stacking order of sibling items. By default the stacking order is 0.
2484 Items with a higher stacking value are drawn on top of siblings with a
2485 lower stacking order. Items with the same stacking value are drawn
2486 bottom up in the order they appear. Items with a negative stacking
2487 value are drawn under their parent's content.
2489 The following example shows the various effects of stacking order.
2493 \o \image declarative-item_stacking1.png
2494 \o Same \c z - later children above earlier children:
2499 width: 100; height: 100
2503 x: 50; y: 50; width: 100; height: 100
2508 \o \image declarative-item_stacking2.png
2509 \o Higher \c z on top:
2515 width: 100; height: 100
2519 x: 50; y: 50; width: 100; height: 100
2524 \o \image declarative-item_stacking3.png
2525 \o Same \c z - children above parents:
2530 width: 100; height: 100
2533 x: 50; y: 50; width: 100; height: 100
2539 \o \image declarative-item_stacking4.png
2540 \o Lower \c z below:
2545 width: 100; height: 100
2549 x: 50; y: 50; width: 100; height: 100
2558 \qmlproperty bool QtQuick2::Item::visible
2560 This property holds whether the item is visible. By default this is true.
2562 Setting this property directly affects the \c visible value of child
2563 items. When set to \c false, the \c visible values of all child items also
2564 become \c false. When set to \c true, the \c visible values of child items
2565 are returned to \c true, unless they have explicitly been set to \c false.
2567 (Because of this flow-on behavior, using the \c visible property may not
2568 have the intended effect if a property binding should only respond to
2569 explicit property changes. In such cases it may be better to use the
2570 \l opacity property instead.)
2572 Setting this property to \c false automatically causes \l focus to be set
2573 to \c false, and this item will longer receive mouse and keyboard events.
2574 (In contrast, setting the \l opacity to 0 does not affect the \l focus
2575 property and the receiving of key events.)
2577 \note This property's value is only affected by changes to this property or
2578 the parent's \c visible property. It does not change, for example, if this
2579 item moves off-screen, or if the \l opacity changes to 0.
2584 \qmlproperty AnchorLine QtQuick2::Item::anchors.top
2585 \qmlproperty AnchorLine QtQuick2::Item::anchors.bottom
2586 \qmlproperty AnchorLine QtQuick2::Item::anchors.left
2587 \qmlproperty AnchorLine QtQuick2::Item::anchors.right
2588 \qmlproperty AnchorLine QtQuick2::Item::anchors.horizontalCenter
2589 \qmlproperty AnchorLine QtQuick2::Item::anchors.verticalCenter
2590 \qmlproperty AnchorLine QtQuick2::Item::anchors.baseline
2592 \qmlproperty Item QtQuick2::Item::anchors.fill
2593 \qmlproperty Item QtQuick2::Item::anchors.centerIn
2595 \qmlproperty real QtQuick2::Item::anchors.margins
2596 \qmlproperty real QtQuick2::Item::anchors.topMargin
2597 \qmlproperty real QtQuick2::Item::anchors.bottomMargin
2598 \qmlproperty real QtQuick2::Item::anchors.leftMargin
2599 \qmlproperty real QtQuick2::Item::anchors.rightMargin
2600 \qmlproperty real QtQuick2::Item::anchors.horizontalCenterOffset
2601 \qmlproperty real QtQuick2::Item::anchors.verticalCenterOffset
2602 \qmlproperty real QtQuick2::Item::anchors.baselineOffset
2604 \qmlproperty bool QtQuick2::Item::anchors.mirrored
2606 Anchors provide a way to position an item by specifying its
2607 relationship with other items.
2609 Margins apply to top, bottom, left, right, and fill anchors.
2610 The \c anchors.margins property can be used to set all of the various margins at once, to the same value.
2611 Note that margins are anchor-specific and are not applied if an item does not
2614 Offsets apply for horizontal center, vertical center, and baseline anchors.
2618 \o \image declarative-anchors_example.png
2619 \o Text anchored to Image, horizontally centered and vertically below, with a margin.
2628 anchors.horizontalCenter: pic.horizontalCenter
2629 anchors.top: pic.bottom
2630 anchors.topMargin: 5
2636 \o \image declarative-anchors_example2.png
2638 Left of Text anchored to right of Image, with a margin. The y
2639 property of both defaults to 0.
2649 anchors.left: pic.right
2650 anchors.leftMargin: 5
2657 \c anchors.fill provides a convenient way for one item to have the
2658 same geometry as another item, and is equivalent to connecting all
2659 four directional anchors.
2661 To clear an anchor value, set it to \c undefined.
2663 \c anchors.mirrored returns true it the layout has been \l {LayoutMirroring}{mirrored}.
2665 \note You can only anchor an item to siblings or a parent.
2667 For more information see \l {anchor-layout}{Anchor Layouts}.
2671 \property QSGItem::baselineOffset
2672 \brief The position of the item's baseline in local coordinates.
2674 The baseline of a \l Text item is the imaginary line on which the text
2675 sits. Controls containing text usually set their baseline to the
2676 baseline of their text.
2678 For non-text items, a default baseline offset of 0 is used.
2680 QSGAnchors *QSGItemPrivate::anchors() const
2684 _anchors = new QSGAnchors(const_cast<QSGItem *>(q));
2685 if (!componentComplete)
2686 _anchors->classBegin();
2691 QSGItemPrivate::AnchorLines *QSGItemPrivate::anchorLines() const
2694 if (!_anchorLines) _anchorLines =
2695 new AnchorLines(const_cast<QSGItem *>(q));
2696 return _anchorLines;
2699 void QSGItemPrivate::siblingOrderChanged()
2702 for(int ii = 0; ii < changeListeners.count(); ++ii) {
2703 const QSGItemPrivate::ChangeListener &change = changeListeners.at(ii);
2704 if (change.types & QSGItemPrivate::SiblingOrder) {
2705 change.listener->itemSiblingOrderChanged(q);
2710 QDeclarativeListProperty<QObject> QSGItemPrivate::data()
2712 return QDeclarativeListProperty<QObject>(q_func(), 0, QSGItemPrivate::data_append,
2713 QSGItemPrivate::data_count,
2714 QSGItemPrivate::data_at,
2715 QSGItemPrivate::data_clear);
2718 QRectF QSGItem::childrenRect()
2721 if (!d->_contents) {
2722 d->_contents = new QSGContents(this);
2723 if (d->componentComplete)
2724 d->_contents->complete();
2726 return d->_contents->rectF();
2729 QList<QSGItem *> QSGItem::childItems() const
2732 return d->childItems;
2735 bool QSGItem::clip() const
2737 return flags() & ItemClipsChildrenToShape;
2740 void QSGItem::setClip(bool c)
2745 setFlag(ItemClipsChildrenToShape, c);
2747 emit clipChanged(c);
2752 This function is called to handle this item's changes in
2753 geometry from \a oldGeometry to \a newGeometry. If the two
2754 geometries are the same, it doesn't do anything.
2756 void QSGItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
2761 QSGAnchorsPrivate::get(d->_anchors)->updateMe();
2763 for(int ii = 0; ii < d->changeListeners.count(); ++ii) {
2764 const QSGItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
2765 if (change.types & QSGItemPrivate::Geometry)
2766 change.listener->itemGeometryChanged(this, newGeometry, oldGeometry);
2769 if (newGeometry.x() != oldGeometry.x())
2771 if (newGeometry.y() != oldGeometry.y())
2773 if (newGeometry.width() != oldGeometry.width())
2774 emit widthChanged();
2775 if (newGeometry.height() != oldGeometry.height())
2776 emit heightChanged();
2780 Called by the rendering thread when it is time to sync the state of the QML objects with the
2781 scene graph objects. The function should return the root of the scene graph subtree for
2782 this item. \a oldNode is the node that was returned the last time the function was called.
2784 The main thread is blocked while this function is executed so it is safe to read
2785 values from the QSGItem instance and other objects in the main thread.
2787 \warning This is the only function in which it is allowed to make use of scene graph
2788 objects from the main thread. Use of scene graph objects outside this function will
2789 result in race conditions and potential crashes.
2792 QSGNode *QSGItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
2798 QSGTransformNode *QSGItemPrivate::createTransformNode()
2800 return new QSGTransformNode;
2803 void QSGItem::updatePolish()
2807 void QSGItemPrivate::removeItemChangeListener(QSGItemChangeListener *listener, ChangeTypes types)
2809 ChangeListener change(listener, types);
2810 changeListeners.removeOne(change);
2813 void QSGItem::keyPressEvent(QKeyEvent *event)
2818 void QSGItem::keyReleaseEvent(QKeyEvent *event)
2823 void QSGItem::inputMethodEvent(QInputMethodEvent *event)
2828 void QSGItem::focusInEvent(QFocusEvent *)
2832 void QSGItem::focusOutEvent(QFocusEvent *)
2836 void QSGItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
2841 void QSGItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
2846 void QSGItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
2851 void QSGItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
2853 mousePressEvent(event);
2856 void QSGItem::mouseUngrabEvent()
2861 void QSGItem::wheelEvent(QWheelEvent *event)
2866 void QSGItem::touchEvent(QTouchEvent *event)
2871 void QSGItem::hoverEnterEvent(QHoverEvent *event)
2876 void QSGItem::hoverMoveEvent(QHoverEvent *event)
2881 void QSGItem::hoverLeaveEvent(QHoverEvent *event)
2886 void QSGItem::dragMoveEvent(QSGDragEvent *event)
2888 event->setAccepted(false);
2891 void QSGItem::dragEnterEvent(QSGDragEvent *event)
2893 event->setAccepted(false);
2896 void QSGItem::dragExitEvent(QSGDragEvent *event)
2898 event->setAccepted(false);
2901 void QSGItem::dragDropEvent(QSGDragEvent *event)
2903 event->setAccepted(false);
2906 bool QSGItem::childMouseEventFilter(QSGItem *, QEvent *)
2911 void QSGItem::windowDeactivateEvent()
2913 foreach (QSGItem* item, childItems()) {
2914 item->windowDeactivateEvent();
2918 Qt::InputMethodHints QSGItem::inputMethodHints() const
2924 void QSGItem::setInputMethodHints(Qt::InputMethodHints hints)
2929 if (!d->canvas || d->canvas->activeFocusItem() != this)
2932 QSGCanvasPrivate::get(d->canvas)->updateInputMethodData();
2934 if (d->canvas->hasFocus())
2935 if (QInputContext *inputContext = d->canvas->inputContext())
2936 inputContext->update();
2940 void QSGItem::updateMicroFocus()
2944 if (d->canvas && d->canvas->hasFocus())
2945 if (QInputContext *inputContext = d->canvas->inputContext())
2946 inputContext->update();
2950 QVariant QSGItem::inputMethodQuery(Qt::InputMethodQuery query) const
2956 v = d->keyHandler->inputMethodQuery(query);
2961 QSGAnchorLine QSGItemPrivate::left() const
2963 return anchorLines()->left;
2966 QSGAnchorLine QSGItemPrivate::right() const
2968 return anchorLines()->right;
2971 QSGAnchorLine QSGItemPrivate::horizontalCenter() const
2973 return anchorLines()->hCenter;
2976 QSGAnchorLine QSGItemPrivate::top() const
2978 return anchorLines()->top;
2981 QSGAnchorLine QSGItemPrivate::bottom() const
2983 return anchorLines()->bottom;
2986 QSGAnchorLine QSGItemPrivate::verticalCenter() const
2988 return anchorLines()->vCenter;
2991 QSGAnchorLine QSGItemPrivate::baseline() const
2993 return anchorLines()->baseline;
2996 qreal QSGItem::baselineOffset() const
2999 if (!d->baselineOffset.isValid()) {
3002 return d->baselineOffset;
3005 void QSGItem::setBaselineOffset(qreal offset)
3008 if (offset == d->baselineOffset)
3011 d->baselineOffset = offset;
3013 for(int ii = 0; ii < d->changeListeners.count(); ++ii) {
3014 const QSGItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
3015 if (change.types & QSGItemPrivate::Geometry) {
3016 QSGAnchorsPrivate *anchor = change.listener->anchorPrivate();
3018 anchor->updateVerticalAnchors();
3021 emit baselineOffsetChanged(offset);
3024 void QSGItem::update()
3027 Q_ASSERT(flags() & ItemHasContents);
3028 d->dirty(QSGItemPrivate::Content);
3031 void QSGItem::polish()
3034 if (!d->polishScheduled) {
3035 d->polishScheduled = true;
3037 QSGCanvasPrivate *p = QSGCanvasPrivate::get(d->canvas);
3038 bool maybeupdate = p->itemsToPolish.isEmpty();
3039 p->itemsToPolish.insert(this);
3040 if (maybeupdate) d->canvas->maybeUpdate();
3045 void QSGItem::mapFromItem(QDeclarativeV8Function *args) const
3047 if (args->Length() != 0) {
3048 v8::Local<v8::Value> item = (*args)[0];
3049 QV8Engine *engine = args->engine();
3051 QSGItem *itemObj = 0;
3052 if (!item->IsNull())
3053 itemObj = qobject_cast<QSGItem*>(engine->toQObject(item));
3055 if (!itemObj && !item->IsNull()) {
3056 qmlInfo(this) << "mapFromItem() given argument \"" << engine->toString(item->ToString())
3057 << "\" which is neither null nor an Item";
3061 v8::Local<v8::Object> rv = v8::Object::New();
3062 args->returnValue(rv);
3064 qreal x = (args->Length() > 1)?(*args)[1]->NumberValue():0;
3065 qreal y = (args->Length() > 2)?(*args)[2]->NumberValue():0;
3067 QPointF p = mapFromItem(itemObj, QPointF(x, y));
3069 rv->Set(v8::String::New("x"), v8::Number::New(p.x()));
3070 rv->Set(v8::String::New("y"), v8::Number::New(p.y()));
3074 QTransform QSGItem::itemTransform(QSGItem *other, bool *ok) const
3078 // XXX todo - we need to be able to handle common parents better and detect
3082 QTransform t = d->itemToCanvasTransform();
3083 if (other) t *= QSGItemPrivate::get(other)->canvasToItemTransform();
3088 void QSGItem::mapToItem(QDeclarativeV8Function *args) const
3090 if (args->Length() != 0) {
3091 v8::Local<v8::Value> item = (*args)[0];
3092 QV8Engine *engine = args->engine();
3094 QSGItem *itemObj = 0;
3095 if (!item->IsNull())
3096 itemObj = qobject_cast<QSGItem*>(engine->toQObject(item));
3098 if (!itemObj && !item->IsNull()) {
3099 qmlInfo(this) << "mapToItem() given argument \"" << engine->toString(item->ToString())
3100 << "\" which is neither null nor an Item";
3104 v8::Local<v8::Object> rv = v8::Object::New();
3105 args->returnValue(rv);
3107 qreal x = (args->Length() > 1)?(*args)[1]->NumberValue():0;
3108 qreal y = (args->Length() > 2)?(*args)[2]->NumberValue():0;
3110 QPointF p = mapToItem(itemObj, QPointF(x, y));
3112 rv->Set(v8::String::New("x"), v8::Number::New(p.x()));
3113 rv->Set(v8::String::New("y"), v8::Number::New(p.y()));
3117 void QSGItem::forceActiveFocus()
3120 QSGItem *parent = parentItem();
3122 if (parent->flags() & QSGItem::ItemIsFocusScope) {
3123 parent->setFocus(true);
3125 parent = parent->parentItem();
3129 QSGItem *QSGItem::childAt(qreal x, qreal y) const
3131 // XXX todo - should this include transform etc.?
3132 const QList<QSGItem *> children = childItems();
3133 for (int i = children.count()-1; i >= 0; --i) {
3134 QSGItem *child = children.at(i);
3135 if (child->isVisible() && child->x() <= x
3136 && child->x() + child->width() >= x
3138 && child->y() + child->height() >= y)
3144 QDeclarativeListProperty<QObject> QSGItemPrivate::resources()
3146 return QDeclarativeListProperty<QObject>(q_func(), 0, QSGItemPrivate::resources_append,
3147 QSGItemPrivate::resources_count,
3148 QSGItemPrivate::resources_at,
3149 QSGItemPrivate::resources_clear);
3152 QDeclarativeListProperty<QSGItem> QSGItemPrivate::children()
3154 return QDeclarativeListProperty<QSGItem>(q_func(), 0, QSGItemPrivate::children_append,
3155 QSGItemPrivate::children_count,
3156 QSGItemPrivate::children_at,
3157 QSGItemPrivate::children_clear);
3161 QDeclarativeListProperty<QDeclarativeState> QSGItemPrivate::states()
3163 return _states()->statesProperty();
3166 QDeclarativeListProperty<QDeclarativeTransition> QSGItemPrivate::transitions()
3168 return _states()->transitionsProperty();
3171 QString QSGItemPrivate::state() const
3176 return _stateGroup->state();
3179 void QSGItemPrivate::setState(const QString &state)
3181 _states()->setState(state);
3184 QDeclarativeListProperty<QSGTransform> QSGItem::transform()
3187 return QDeclarativeListProperty<QSGTransform>(this, 0, d->transform_append, d->transform_count,
3188 d->transform_at, d->transform_clear);
3191 void QSGItem::classBegin()
3194 d->componentComplete = false;
3196 d->_stateGroup->classBegin();
3198 d->_anchors->classBegin();
3201 void QSGItem::componentComplete()
3204 d->componentComplete = true;
3206 d->_stateGroup->componentComplete();
3208 d->_anchors->componentComplete();
3209 QSGAnchorsPrivate::get(d->_anchors)->updateOnComplete();
3212 d->keyHandler->componentComplete();
3214 d->_contents->complete();
3217 QDeclarativeStateGroup *QSGItemPrivate::_states()
3221 _stateGroup = new QDeclarativeStateGroup;
3222 if (!componentComplete)
3223 _stateGroup->classBegin();
3224 QObject::connect(_stateGroup, SIGNAL(stateChanged(QString)),
3225 q, SIGNAL(stateChanged(QString)));
3231 QSGItemPrivate::AnchorLines::AnchorLines(QSGItem *q)
3234 left.anchorLine = QSGAnchorLine::Left;
3236 right.anchorLine = QSGAnchorLine::Right;
3238 hCenter.anchorLine = QSGAnchorLine::HCenter;
3240 top.anchorLine = QSGAnchorLine::Top;
3242 bottom.anchorLine = QSGAnchorLine::Bottom;
3244 vCenter.anchorLine = QSGAnchorLine::VCenter;
3246 baseline.anchorLine = QSGAnchorLine::Baseline;
3249 QPointF QSGItemPrivate::computeTransformOrigin() const
3253 case QSGItem::TopLeft:
3254 return QPointF(0, 0);
3256 return QPointF(width / 2., 0);
3257 case QSGItem::TopRight:
3258 return QPointF(width, 0);
3260 return QPointF(0, height / 2.);
3261 case QSGItem::Center:
3262 return QPointF(width / 2., height / 2.);
3263 case QSGItem::Right:
3264 return QPointF(width, height / 2.);
3265 case QSGItem::BottomLeft:
3266 return QPointF(0, height);
3267 case QSGItem::Bottom:
3268 return QPointF(width / 2., height);
3269 case QSGItem::BottomRight:
3270 return QPointF(width, height);
3274 void QSGItemPrivate::transformChanged()
3278 void QSGItemPrivate::deliverKeyEvent(QKeyEvent *e)
3282 Q_ASSERT(e->isAccepted());
3284 if (e->type() == QEvent::KeyPress)
3285 keyHandler->keyPressed(e, false);
3287 keyHandler->keyReleased(e, false);
3289 if (e->isAccepted())
3295 if (e->type() == QEvent::KeyPress)
3296 q->keyPressEvent(e);
3298 q->keyReleaseEvent(e);
3300 if (e->isAccepted())
3306 if (e->type() == QEvent::KeyPress)
3307 keyHandler->keyPressed(e, true);
3309 keyHandler->keyReleased(e, true);
3313 void QSGItemPrivate::deliverInputMethodEvent(QInputMethodEvent *e)
3317 Q_ASSERT(e->isAccepted());
3319 keyHandler->inputMethodEvent(e, false);
3321 if (e->isAccepted())
3327 q->inputMethodEvent(e);
3329 if (e->isAccepted())
3335 keyHandler->inputMethodEvent(e, true);
3339 void QSGItemPrivate::deliverFocusEvent(QFocusEvent *e)
3343 if (e->type() == QEvent::FocusIn) {
3346 q->focusOutEvent(e);
3350 void QSGItemPrivate::deliverMouseEvent(QGraphicsSceneMouseEvent *e)
3354 Q_ASSERT(e->isAccepted());
3358 Q_ASSERT(!"Unknown event type");
3359 case QEvent::GraphicsSceneMouseMove:
3360 q->mouseMoveEvent(e);
3362 case QEvent::GraphicsSceneMousePress:
3363 q->mousePressEvent(e);
3365 case QEvent::GraphicsSceneMouseRelease:
3366 q->mouseReleaseEvent(e);
3368 case QEvent::GraphicsSceneMouseDoubleClick:
3369 q->mouseDoubleClickEvent(e);
3374 void QSGItemPrivate::deliverWheelEvent(QWheelEvent *e)
3380 void QSGItemPrivate::deliverTouchEvent(QTouchEvent *e)
3386 void QSGItemPrivate::deliverHoverEvent(QHoverEvent *e)
3391 Q_ASSERT(!"Unknown event type");
3392 case QEvent::HoverEnter:
3393 q->hoverEnterEvent(e);
3395 case QEvent::HoverLeave:
3396 q->hoverLeaveEvent(e);
3398 case QEvent::HoverMove:
3399 q->hoverMoveEvent(e);
3404 void QSGItemPrivate::deliverDragEvent(QSGDragEvent *e)
3407 switch (e->type()) {
3409 Q_ASSERT(!"Unknown event type");
3410 case QSGEvent::SGDragEnter:
3411 q->dragEnterEvent(e);
3413 case QSGEvent::SGDragExit:
3414 q->dragExitEvent(e);
3416 case QSGEvent::SGDragMove:
3417 q->dragMoveEvent(e);
3419 case QSGEvent::SGDragDrop:
3420 q->dragDropEvent(e);
3425 void QSGItem::itemChange(ItemChange change, const ItemChangeData &value)
3432 // XXX todo - do we want/need this anymore?
3433 // Note that it's now used for varying clip rect
3434 QRectF QSGItem::boundingRect() const
3437 return QRectF(0, 0, d->width, d->height);
3440 QSGItem::TransformOrigin QSGItem::transformOrigin() const
3446 void QSGItem::setTransformOrigin(TransformOrigin origin)
3449 if (origin == d->origin)
3453 d->dirty(QSGItemPrivate::TransformOrigin);
3455 emit transformOriginChanged(d->origin);
3458 QPointF QSGItem::transformOriginPoint() const
3461 return d->computeTransformOrigin();
3464 qreal QSGItem::z() const
3470 void QSGItem::setZ(qreal v)
3478 d->dirty(QSGItemPrivate::ZValue);
3480 QSGItemPrivate::get(d->parentItem)->dirty(QSGItemPrivate::ChildrenStackingChanged);
3487 \qmlproperty real QtQuick2::Item::rotation
3488 This property holds the rotation of the item in degrees clockwise.
3490 This specifies how many degrees to rotate the item around its transformOrigin.
3491 The default rotation is 0 degrees (i.e. not rotated at all).
3495 \o \image declarative-rotation.png
3500 width: 100; height: 100
3503 x: 25; y: 25; width: 50; height: 50
3510 \sa transform, Rotation
3514 \qmlproperty real QtQuick2::Item::scale
3515 This property holds the scale of the item.
3517 A scale of less than 1 means the item will be displayed smaller than
3518 normal, and a scale of greater than 1 means the item will be
3519 displayed larger than normal. A negative scale means the item will
3522 By default, items are displayed at a scale of 1 (i.e. at their
3525 Scaling is from the item's transformOrigin.
3529 \o \image declarative-scale.png
3534 width: 100; height: 100
3537 width: 25; height: 25
3541 x: 25; y: 25; width: 50; height: 50
3548 \sa transform, Scale
3552 \qmlproperty real QtQuick2::Item::opacity
3554 This property holds the opacity of the item. Opacity is specified as a
3555 number between 0 (fully transparent) and 1 (fully opaque). The default is 1.
3557 When this property is set, the specified opacity is also applied
3558 individually to child items. In almost all cases this is what you want,
3559 but in some cases it may produce undesired results. For example in the
3560 second set of rectangles below, the red rectangle has specified an opacity
3561 of 0.5, which affects the opacity of its blue child rectangle even though
3562 the child has not specified an opacity.
3566 \o \image declarative-item_opacity1.png
3572 width: 100; height: 100
3575 x: 50; y: 50; width: 100; height: 100
3581 \o \image declarative-item_opacity2.png
3588 width: 100; height: 100
3591 x: 50; y: 50; width: 100; height: 100
3598 If an item's opacity is set to 0, the item will no longer receive mouse
3599 events, but will continue to receive key events and will retain the keyboard
3600 \l focus if it has been set. (In contrast, setting the \l visible property
3601 to \c false stops both mouse and keyboard events, and also removes focus
3606 Returns a value indicating whether mouse input should
3607 remain with this item exclusively.
3609 \sa setKeepMouseGrab()
3612 qreal QSGItem::rotation() const
3618 void QSGItem::setRotation(qreal r)
3621 if (d->rotation == r)
3626 d->dirty(QSGItemPrivate::BasicTransform);
3628 d->itemChange(ItemRotationHasChanged, r);
3630 emit rotationChanged();
3633 qreal QSGItem::scale() const
3639 void QSGItem::setScale(qreal s)
3647 d->dirty(QSGItemPrivate::BasicTransform);
3649 emit scaleChanged();
3652 qreal QSGItem::opacity() const
3658 void QSGItem::setOpacity(qreal o)
3661 if (d->opacity == o)
3666 d->dirty(QSGItemPrivate::OpacityValue);
3668 d->itemChange(ItemOpacityHasChanged, o);
3670 emit opacityChanged();
3673 bool QSGItem::isVisible() const
3676 return d->effectiveVisible;
3679 void QSGItem::setVisible(bool v)
3682 if (v == d->explicitVisible)
3685 d->explicitVisible = v;
3687 d->setEffectiveVisibleRecur(d->calcEffectiveVisible());
3690 bool QSGItem::isEnabled() const
3693 return d->effectiveEnable;
3696 void QSGItem::setEnabled(bool e)
3699 if (e == d->explicitEnable)
3702 d->explicitEnable = e;
3704 d->setEffectiveEnableRecur(d->calcEffectiveEnable());
3707 bool QSGItemPrivate::calcEffectiveVisible() const
3709 // XXX todo - Should the effective visible of an element with no parent just be the current
3710 // effective visible? This would prevent pointless re-processing in the case of an element
3711 // moving to/from a no-parent situation, but it is different from what graphics view does.
3712 return explicitVisible && (!parentItem || QSGItemPrivate::get(parentItem)->effectiveVisible);
3715 void QSGItemPrivate::setEffectiveVisibleRecur(bool newEffectiveVisible)
3719 if (newEffectiveVisible && !explicitVisible) {
3720 // This item locally overrides visibility
3724 if (newEffectiveVisible == effectiveVisible) {
3725 // No change necessary
3729 effectiveVisible = newEffectiveVisible;
3731 if (parentItem) QSGItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
3734 QSGCanvasPrivate *canvasPriv = QSGCanvasPrivate::get(canvas);
3735 if (canvasPriv->mouseGrabberItem == q)
3739 for (int ii = 0; ii < childItems.count(); ++ii)
3740 QSGItemPrivate::get(childItems.at(ii))->setEffectiveVisibleRecur(newEffectiveVisible);
3742 for(int ii = 0; ii < changeListeners.count(); ++ii) {
3743 const QSGItemPrivate::ChangeListener &change = changeListeners.at(ii);
3744 if (change.types & QSGItemPrivate::Visibility)
3745 change.listener->itemVisibilityChanged(q);
3748 emit q->visibleChanged();
3751 bool QSGItemPrivate::calcEffectiveEnable() const
3753 // XXX todo - Should the effective enable of an element with no parent just be the current
3754 // effective enable? This would prevent pointless re-processing in the case of an element
3755 // moving to/from a no-parent situation, but it is different from what graphics view does.
3756 return explicitEnable && (!parentItem || QSGItemPrivate::get(parentItem)->effectiveEnable);
3759 void QSGItemPrivate::setEffectiveEnableRecur(bool newEffectiveEnable)
3763 // XXX todo - need to fixup focus
3765 if (newEffectiveEnable && !explicitEnable) {
3766 // This item locally overrides enable
3770 if (newEffectiveEnable == effectiveEnable) {
3771 // No change necessary
3775 effectiveEnable = newEffectiveEnable;
3778 QSGCanvasPrivate *canvasPriv = QSGCanvasPrivate::get(canvas);
3779 if (canvasPriv->mouseGrabberItem == q)
3783 for (int ii = 0; ii < childItems.count(); ++ii)
3784 QSGItemPrivate::get(childItems.at(ii))->setEffectiveEnableRecur(newEffectiveEnable);
3786 emit q->enabledChanged();
3789 QString QSGItemPrivate::dirtyToString() const
3791 #define DIRTY_TO_STRING(value) if (dirtyAttributes & value) { \
3792 if (!rv.isEmpty()) \
3793 rv.append(QLatin1String("|")); \
3794 rv.append(QLatin1String(#value)); \
3797 // QString rv = QLatin1String("0x") + QString::number(dirtyAttributes, 16);
3800 DIRTY_TO_STRING(TransformOrigin);
3801 DIRTY_TO_STRING(Transform);
3802 DIRTY_TO_STRING(BasicTransform);
3803 DIRTY_TO_STRING(Position);
3804 DIRTY_TO_STRING(Size);
3805 DIRTY_TO_STRING(ZValue);
3806 DIRTY_TO_STRING(Content);
3807 DIRTY_TO_STRING(Smooth);
3808 DIRTY_TO_STRING(OpacityValue);
3809 DIRTY_TO_STRING(ChildrenChanged);
3810 DIRTY_TO_STRING(ChildrenStackingChanged);
3811 DIRTY_TO_STRING(ParentChanged);
3812 DIRTY_TO_STRING(Clip);
3813 DIRTY_TO_STRING(Canvas);
3814 DIRTY_TO_STRING(EffectReference);
3815 DIRTY_TO_STRING(Visible);
3816 DIRTY_TO_STRING(HideReference);
3821 void QSGItemPrivate::dirty(DirtyType type)
3824 if (type & (TransformOrigin | Transform | BasicTransform | Position | Size))
3827 if (!(dirtyAttributes & type) || (canvas && !prevDirtyItem)) {
3828 dirtyAttributes |= type;
3831 QSGCanvasPrivate::get(canvas)->dirtyItem(q);
3836 void QSGItemPrivate::addToDirtyList()
3841 if (!prevDirtyItem) {
3842 Q_ASSERT(!nextDirtyItem);
3844 QSGCanvasPrivate *p = QSGCanvasPrivate::get(canvas);
3845 nextDirtyItem = p->dirtyItemList;
3846 if (nextDirtyItem) QSGItemPrivate::get(nextDirtyItem)->prevDirtyItem = &nextDirtyItem;
3847 prevDirtyItem = &p->dirtyItemList;
3848 p->dirtyItemList = q;
3851 Q_ASSERT(prevDirtyItem);
3854 void QSGItemPrivate::removeFromDirtyList()
3856 if (prevDirtyItem) {
3857 if (nextDirtyItem) QSGItemPrivate::get(nextDirtyItem)->prevDirtyItem = prevDirtyItem;
3858 *prevDirtyItem = nextDirtyItem;
3862 Q_ASSERT(!prevDirtyItem);
3863 Q_ASSERT(!nextDirtyItem);
3866 void QSGItemPrivate::refFromEffectItem(bool hide)
3869 if (1 == effectRefCount) {
3870 dirty(EffectReference);
3871 if (parentItem) QSGItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
3874 if (++hideRefCount == 1)
3875 dirty(HideReference);
3879 void QSGItemPrivate::derefFromEffectItem(bool unhide)
3881 Q_ASSERT(effectRefCount);
3883 if (0 == effectRefCount) {
3884 dirty(EffectReference);
3885 if (parentItem) QSGItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
3888 if (--hideRefCount == 0)
3889 dirty(HideReference);
3893 void QSGItemPrivate::itemChange(QSGItem::ItemChange change, const QSGItem::ItemChangeData &data)
3897 case QSGItem::ItemChildAddedChange:
3898 q->itemChange(change, data);
3899 if (_contents && componentComplete)
3900 _contents->childAdded(data.item);
3901 for(int ii = 0; ii < changeListeners.count(); ++ii) {
3902 const QSGItemPrivate::ChangeListener &change = changeListeners.at(ii);
3903 if (change.types & QSGItemPrivate::Children) {
3904 change.listener->itemChildAdded(q, data.item);
3908 case QSGItem::ItemChildRemovedChange:
3909 q->itemChange(change, data);
3910 if (_contents && componentComplete)
3911 _contents->childRemoved(data.item);
3912 for(int ii = 0; ii < changeListeners.count(); ++ii) {
3913 const QSGItemPrivate::ChangeListener &change = changeListeners.at(ii);
3914 if (change.types & QSGItemPrivate::Children) {
3915 change.listener->itemChildRemoved(q, data.item);
3919 case QSGItem::ItemSceneChange:
3920 q->itemChange(change, data);
3922 case QSGItem::ItemVisibleHasChanged:
3923 q->itemChange(change, data);
3924 for(int ii = 0; ii < changeListeners.count(); ++ii) {
3925 const QSGItemPrivate::ChangeListener &change = changeListeners.at(ii);
3926 if (change.types & QSGItemPrivate::Visibility) {
3927 change.listener->itemVisibilityChanged(q);
3931 case QSGItem::ItemParentHasChanged:
3932 q->itemChange(change, data);
3933 for(int ii = 0; ii < changeListeners.count(); ++ii) {
3934 const QSGItemPrivate::ChangeListener &change = changeListeners.at(ii);
3935 if (change.types & QSGItemPrivate::Parent) {
3936 change.listener->itemParentChanged(q, data.item);
3940 case QSGItem::ItemOpacityHasChanged:
3941 q->itemChange(change, data);
3942 for(int ii = 0; ii < changeListeners.count(); ++ii) {
3943 const QSGItemPrivate::ChangeListener &change = changeListeners.at(ii);
3944 if (change.types & QSGItemPrivate::Opacity) {
3945 change.listener->itemOpacityChanged(q);
3949 case QSGItem::ItemActiveFocusHasChanged:
3950 q->itemChange(change, data);
3952 case QSGItem::ItemRotationHasChanged:
3953 q->itemChange(change, data);
3954 for(int ii = 0; ii < changeListeners.count(); ++ii) {
3955 const QSGItemPrivate::ChangeListener &change = changeListeners.at(ii);
3956 if (change.types & QSGItemPrivate::Rotation) {
3957 change.listener->itemRotationChanged(q);
3965 \property QSGItem::smooth
3966 \brief whether the item is smoothly transformed.
3968 This property is provided purely for the purpose of optimization. Turning
3969 smooth transforms off is faster, but looks worse; turning smooth
3970 transformations on is slower, but looks better.
3972 By default smooth transformations are off.
3976 Returns true if the item should be drawn with antialiasing and
3977 smooth pixmap filtering, false otherwise.
3979 The default is false.
3983 bool QSGItem::smooth() const
3990 Sets whether the item should be drawn with antialiasing and
3991 smooth pixmap filtering to \a smooth.
3995 void QSGItem::setSmooth(bool smooth)
3998 if (d->smooth == smooth)
4002 d->dirty(QSGItemPrivate::Smooth);
4004 emit smoothChanged(smooth);
4007 QSGItem::Flags QSGItem::flags() const
4010 return (QSGItem::Flags)d->flags;
4013 void QSGItem::setFlag(Flag flag, bool enabled)
4017 setFlags((Flags)(d->flags | (quint32)flag));
4019 setFlags((Flags)(d->flags & ~(quint32)flag));
4022 void QSGItem::setFlags(Flags flags)
4026 if ((flags & ItemIsFocusScope) != (d->flags & ItemIsFocusScope)) {
4027 if (flags & ItemIsFocusScope && !d->childItems.isEmpty() && d->canvas) {
4028 qWarning("QSGItem: Cannot set FocusScope once item has children and is in a canvas.");
4029 flags &= ~ItemIsFocusScope;
4030 } else if (d->flags & ItemIsFocusScope) {
4031 qWarning("QSGItem: Cannot unset FocusScope flag.");
4032 flags |= ItemIsFocusScope;
4036 if ((flags & ItemClipsChildrenToShape ) != (d->flags & ItemClipsChildrenToShape))
4037 d->dirty(QSGItemPrivate::Clip);
4042 qreal QSGItem::x() const
4048 qreal QSGItem::y() const
4054 QPointF QSGItem::pos() const
4057 return QPointF(d->x, d->y);
4060 void QSGItem::setX(qreal v)
4069 d->dirty(QSGItemPrivate::Position);
4071 geometryChanged(QRectF(x(), y(), width(), height()),
4072 QRectF(oldx, y(), width(), height()));
4075 void QSGItem::setY(qreal v)
4084 d->dirty(QSGItemPrivate::Position);
4086 geometryChanged(QRectF(x(), y(), width(), height()),
4087 QRectF(x(), oldy, width(), height()));
4090 void QSGItem::setPos(const QPointF &pos)
4093 if (QPointF(d->x, d->y) == pos)
4102 d->dirty(QSGItemPrivate::Position);
4104 geometryChanged(QRectF(x(), y(), width(), height()),
4105 QRectF(oldx, oldy, width(), height()));
4108 qreal QSGItem::width() const
4114 void QSGItem::setWidth(qreal w)
4120 d->widthValid = true;
4124 qreal oldWidth = d->width;
4127 d->dirty(QSGItemPrivate::Size);
4129 geometryChanged(QRectF(x(), y(), width(), height()),
4130 QRectF(x(), y(), oldWidth, height()));
4133 void QSGItem::resetWidth()
4136 d->widthValid = false;
4137 setImplicitWidth(implicitWidth());
4140 void QSGItemPrivate::implicitWidthChanged()
4143 emit q->implicitWidthChanged();
4146 qreal QSGItemPrivate::getImplicitWidth() const
4148 return implicitWidth;
4151 Returns the width of the item that is implied by other properties that determine the content.
4153 qreal QSGItem::implicitWidth() const
4156 return d->getImplicitWidth();
4160 \qmlproperty real QtQuick2::Item::implicitWidth
4161 \qmlproperty real QtQuick2::Item::implicitHeight
4163 Defines the natural width or height of the Item if no \l width or \l height is specified.
4165 The default implicit size for most items is 0x0, however some elements have an inherent
4166 implicit size which cannot be overridden, e.g. Image, Text.
4168 Setting the implicit size is useful for defining components that have a preferred size
4169 based on their content, for example:
4176 property alias icon: image.source
4177 property alias label: text.text
4178 implicitWidth: text.implicitWidth + image.implicitWidth
4179 implicitHeight: Math.max(text.implicitHeight, image.implicitHeight)
4184 anchors.left: image.right; anchors.right: parent.right
4185 anchors.verticalCenter: parent.verticalCenter
4190 \bold Note: using implicitWidth of Text or TextEdit and setting the width explicitly
4191 incurs a performance penalty as the text must be laid out twice.
4195 Sets the implied width of the item to \a w.
4196 This is the width implied by other properties that determine the content.
4198 void QSGItem::setImplicitWidth(qreal w)
4201 bool changed = w != d->implicitWidth;
4202 d->implicitWidth = w;
4203 if (d->width == w || widthValid()) {
4205 d->implicitWidthChanged();
4209 qreal oldWidth = d->width;
4212 d->dirty(QSGItemPrivate::Size);
4214 geometryChanged(QRectF(x(), y(), width(), height()),
4215 QRectF(x(), y(), oldWidth, height()));
4218 d->implicitWidthChanged();
4222 Returns whether the width property has been set explicitly.
4224 bool QSGItem::widthValid() const
4227 return d->widthValid;
4230 qreal QSGItem::height() const
4236 void QSGItem::setHeight(qreal h)
4242 d->heightValid = true;
4246 qreal oldHeight = d->height;
4249 d->dirty(QSGItemPrivate::Size);
4251 geometryChanged(QRectF(x(), y(), width(), height()),
4252 QRectF(x(), y(), width(), oldHeight));
4255 void QSGItem::resetHeight()
4258 d->heightValid = false;
4259 setImplicitHeight(implicitHeight());
4262 void QSGItemPrivate::implicitHeightChanged()
4265 emit q->implicitHeightChanged();
4268 qreal QSGItemPrivate::getImplicitHeight() const
4270 return implicitHeight;
4274 Returns the height of the item that is implied by other properties that determine the content.
4276 qreal QSGItem::implicitHeight() const
4279 return d->getImplicitHeight();
4284 Sets the implied height of the item to \a h.
4285 This is the height implied by other properties that determine the content.
4287 void QSGItem::setImplicitHeight(qreal h)
4290 bool changed = h != d->implicitHeight;
4291 d->implicitHeight = h;
4292 if (d->height == h || heightValid()) {
4294 d->implicitHeightChanged();
4298 qreal oldHeight = d->height;
4301 d->dirty(QSGItemPrivate::Size);
4303 geometryChanged(QRectF(x(), y(), width(), height()),
4304 QRectF(x(), y(), width(), oldHeight));
4307 d->implicitHeightChanged();
4311 Returns whether the height property has been set explicitly.
4313 bool QSGItem::heightValid() const
4316 return d->heightValid;
4319 void QSGItem::setSize(const QSizeF &size)
4322 d->heightValid = true;
4323 d->widthValid = true;
4325 if (QSizeF(d->width, d->height) == size)
4328 qreal oldHeight = d->height;
4329 qreal oldWidth = d->width;
4330 d->height = size.height();
4331 d->width = size.width();
4333 d->dirty(QSGItemPrivate::Size);
4335 geometryChanged(QRectF(x(), y(), width(), height()),
4336 QRectF(x(), y(), oldWidth, oldHeight));
4339 bool QSGItem::hasActiveFocus() const
4342 return d->activeFocus;
4345 bool QSGItem::hasFocus() const
4351 void QSGItem::setFocus(bool focus)
4354 if (d->focus == focus)
4358 // Need to find our nearest focus scope
4359 QSGItem *scope = parentItem();
4360 while (scope && !scope->isFocusScope())
4361 scope = scope->parentItem();
4363 QSGCanvasPrivate::get(d->canvas)->setFocusInScope(scope, this);
4365 QSGCanvasPrivate::get(d->canvas)->clearFocusInScope(scope, this);
4368 emit focusChanged(focus);
4372 bool QSGItem::isFocusScope() const
4374 return flags() & ItemIsFocusScope;
4377 QSGItem *QSGItem::scopedFocusItem() const
4380 if (!isFocusScope())
4383 return d->subFocusItem;
4387 Qt::MouseButtons QSGItem::acceptedMouseButtons() const
4390 return d->acceptedMouseButtons;
4393 void QSGItem::setAcceptedMouseButtons(Qt::MouseButtons buttons)
4396 d->acceptedMouseButtons = buttons;
4399 bool QSGItem::filtersChildMouseEvents() const
4402 return d->filtersChildMouseEvents;
4405 void QSGItem::setFiltersChildMouseEvents(bool filter)
4408 d->filtersChildMouseEvents = filter;
4411 bool QSGItem::isUnderMouse() const
4417 QPoint cursorPos = QCursor::pos();
4418 if (QRectF(0, 0, width(), height()).contains(mapFromScene(d->canvas->mapFromGlobal(cursorPos))))
4423 bool QSGItem::acceptHoverEvents() const
4426 return d->hoverEnabled;
4429 void QSGItem::setAcceptHoverEvents(bool enabled)
4432 d->hoverEnabled = enabled;
4435 QSGCanvasPrivate *c = QSGCanvasPrivate::get(d->canvas);
4436 if (d->hoverEnabled){
4437 if (!d->canvas->hasMouseTracking())
4438 d->canvas->setMouseTracking(true);
4440 c->hoverItems.prepend(this);
4441 c->sendHoverEvent(QEvent::HoverEnter, this, c->lastMousePosition, c->lastMousePosition,
4442 QApplication::keyboardModifiers(), true);
4444 c->hoverItems.removeAll(this);
4445 c->sendHoverEvent(QEvent::HoverLeave, this, c->lastMousePosition, c->lastMousePosition,
4446 QApplication::keyboardModifiers(), true);
4451 void QSGItem::grabMouse()
4456 QSGCanvasPrivate *canvasPriv = QSGCanvasPrivate::get(d->canvas);
4457 if (canvasPriv->mouseGrabberItem == this)
4460 QSGItem *oldGrabber = canvasPriv->mouseGrabberItem;
4461 canvasPriv->mouseGrabberItem = this;
4463 oldGrabber->mouseUngrabEvent();
4466 void QSGItem::ungrabMouse()
4471 QSGCanvasPrivate *canvasPriv = QSGCanvasPrivate::get(d->canvas);
4472 if (canvasPriv->mouseGrabberItem != this) {
4473 qWarning("QSGItem::ungrabMouse(): Item is not the mouse grabber.");
4477 canvasPriv->mouseGrabberItem = 0;
4481 bool QSGItem::keepMouseGrab() const
4484 return d->keepMouse;
4488 The flag indicating whether the mouse should remain
4489 with this item is set to \a keep.
4491 This is useful for items that wish to grab and keep mouse
4492 interaction following a predefined gesture. For example,
4493 an item that is interested in horizontal mouse movement
4494 may set keepMouseGrab to true once a threshold has been
4495 exceeded. Once keepMouseGrab has been set to true, filtering
4496 items will not react to mouse events.
4498 If the item does not indicate that it wishes to retain mouse grab,
4499 a filtering item may steal the grab. For example, Flickable may attempt
4500 to steal a mouse grab if it detects that the user has begun to
4505 void QSGItem::setKeepMouseGrab(bool keep)
4508 d->keepMouse = keep;
4512 \qmlmethod object QtQuick2::Item::mapFromItem(Item item, real x, real y)
4514 Maps the point (\a x, \a y), which is in \a item's coordinate system, to
4515 this item's coordinate system, and returns an object with \c x and \c y
4516 properties matching the mapped cooordinate.
4518 If \a item is a \c null value, this maps the point from the coordinate
4519 system of the root QML view.
4522 \qmlmethod object QtQuick2::Item::mapToItem(Item item, real x, real y)
4524 Maps the point (\a x, \a y), which is in this item's coordinate system, to
4525 \a item's coordinate system, and returns an object with \c x and \c y
4526 properties matching the mapped cooordinate.
4528 If \a item is a \c null value, this maps \a x and \a y to the coordinate
4529 system of the root QML view.
4531 QPointF QSGItem::mapToItem(const QSGItem *item, const QPointF &point) const
4533 QPointF p = mapToScene(point);
4535 p = item->mapFromScene(p);
4539 QPointF QSGItem::mapToScene(const QPointF &point) const
4542 return d->itemToCanvasTransform().map(point);
4545 QRectF QSGItem::mapRectToItem(const QSGItem *item, const QRectF &rect) const
4548 QTransform t = d->itemToCanvasTransform();
4550 t *= QSGItemPrivate::get(item)->canvasToItemTransform();
4551 return t.mapRect(rect);
4554 QRectF QSGItem::mapRectToScene(const QRectF &rect) const
4557 return d->itemToCanvasTransform().mapRect(rect);
4560 QPointF QSGItem::mapFromItem(const QSGItem *item, const QPointF &point) const
4562 QPointF p = item?item->mapToScene(point):point;
4563 return mapFromScene(p);
4566 QPointF QSGItem::mapFromScene(const QPointF &point) const
4569 return d->canvasToItemTransform().map(point);
4572 QRectF QSGItem::mapRectFromItem(const QSGItem *item, const QRectF &rect) const
4575 QTransform t = item?QSGItemPrivate::get(item)->itemToCanvasTransform():QTransform();
4576 t *= d->canvasToItemTransform();
4577 return t.mapRect(rect);
4580 QRectF QSGItem::mapRectFromScene(const QRectF &rect) const
4583 return d->canvasToItemTransform().mapRect(rect);
4588 \qmlmethod QtQuick2::Item::forceActiveFocus()
4590 Forces active focus on the item.
4592 This method sets focus on the item and makes sure that all the focus scopes
4593 higher in the object hierarchy are also given the focus.
4597 Forces active focus on the item.
4599 This method sets focus on the item and makes sure that all the focus scopes
4600 higher in the object hierarchy are also given the focus.
4604 \qmlmethod QtQuick2::Item::childAt(real x, real y)
4606 Returns the visible child item at point (\a x, \a y), which is in this
4607 item's coordinate system, or \c null if there is no such item.
4611 Returns the visible child item at point (\a x, \a y), which is in this
4612 item's coordinate system, or 0 if there is no such item.
4616 \qmlproperty list<State> QtQuick2::Item::states
4617 This property holds a list of states defined by the item.
4633 \sa {qmlstate}{States}
4636 \qmlproperty list<Transition> QtQuick2::Item::transitions
4637 This property holds a list of transitions defined by the item.
4653 \sa {QML Animation and Transitions}{Transitions}
4656 \qmlproperty list<Filter> QtQuick2::Item::filter
4657 This property holds a list of graphical filters to be applied to the item.
4659 \l {Filter}{Filters} include things like \l {Blur}{blurring}
4660 the item, or giving it a \l Reflection. Some
4661 filters may not be available on all canvases; if a filter is not
4662 available on a certain canvas, it will simply not be applied for
4663 that canvas (but the QML will still be considered valid).
4681 \qmlproperty bool QtQuick2::Item::clip
4682 This property holds whether clipping is enabled. The default clip value is \c false.
4684 If clipping is enabled, an item will clip its own painting, as well
4685 as the painting of its children, to its bounding rectangle.
4687 Non-rectangular clipping regions are not supported for performance reasons.
4691 \property QSGItem::clip
4692 This property holds whether clipping is enabled. The default clip value is \c false.
4694 If clipping is enabled, an item will clip its own painting, as well
4695 as the painting of its children, to its bounding rectangle. If you set
4696 clipping during an item's paint operation, remember to re-set it to
4697 prevent clipping the rest of your scene.
4699 Non-rectangular clipping regions are not supported for performance reasons.
4703 \qmlproperty string QtQuick2::Item::state
4705 This property holds the name of the current state of the item.
4707 This property is often used in scripts to change between states. For
4712 if (button.state == 'On')
4713 button.state = 'Off';
4715 button.state = 'On';
4719 If the item is in its base state (i.e. no explicit state has been
4720 set), \c state will be a blank string. Likewise, you can return an
4721 item to its base state by setting its current state to \c ''.
4723 \sa {qmlstates}{States}
4727 \qmlproperty list<Transform> QtQuick2::Item::transform
4728 This property holds the list of transformations to apply.
4730 For more information see \l Transform.
4734 \enum QSGItem::TransformOrigin
4736 Controls the point about which simple transforms like scale apply.
4738 \value TopLeft The top-left corner of the item.
4739 \value Top The center point of the top of the item.
4740 \value TopRight The top-right corner of the item.
4741 \value Left The left most point of the vertical middle.
4742 \value Center The center of the item.
4743 \value Right The right most point of the vertical middle.
4744 \value BottomLeft The bottom-left corner of the item.
4745 \value Bottom The center point of the bottom of the item.
4746 \value BottomRight The bottom-right corner of the item.
4751 \qmlproperty bool QtQuick2::Item::activeFocus
4753 This property indicates whether the item has active focus.
4755 An item with active focus will receive keyboard input,
4756 or is a FocusScope ancestor of the item that will receive keyboard input.
4758 Usually, activeFocus is gained by setting focus on an item and its enclosing
4759 FocusScopes. In the following example \c input will have activeFocus.
4772 \sa focus, {qmlfocus}{Keyboard Focus}
4776 \qmlproperty bool QtQuick2::Item::focus
4777 This property indicates whether the item has focus within the enclosing focus scope. If true, this item
4778 will gain active focus when the enclosing focus scope gains active focus.
4779 In the following example, \c input will be given active focus when \c scope gains active focus.
4792 For the purposes of this property, the scene as a whole is assumed to act like a focus scope.
4793 On a practical level, that means the following QML will give active focus to \c input on startup.
4804 \sa activeFocus, {qmlfocus}{Keyboard Focus}
4809 \property QSGItem::anchors
4814 \property QSGItem::left
4819 \property QSGItem::right
4824 \property QSGItem::horizontalCenter
4829 \property QSGItem::top
4834 \property QSGItem::bottom
4839 \property QSGItem::verticalCenter
4844 \property QSGItem::focus
4849 \property QSGItem::transform
4854 \property QSGItem::transformOrigin
4859 \property QSGItem::activeFocus
4864 \property QSGItem::baseline
4869 \property QSGItem::data
4874 \property QSGItem::resources
4879 \property QSGItem::state
4884 \property QSGItem::states
4889 \property QSGItem::transformOriginPoint
4894 \property QSGItem::transitions
4898 bool QSGItem::event(QEvent *ev)
4900 return QObject::event(ev);
4903 if (ev->type() == QEvent::PolishRequest) {
4905 d->polishScheduled = false;
4909 return QObject::event(ev);
4914 #ifndef QT_NO_DEBUG_STREAM
4915 QDebug operator<<(QDebug debug, QSGItem *item)
4918 debug << "QSGItem(0)";
4922 debug << item->metaObject()->className() << "(this =" << ((void*)item)
4923 << ", name=" << item->objectName()
4924 << ", parent =" << ((void*)item->parentItem())
4925 << ", geometry =" << QRectF(item->pos(), QSizeF(item->width(), item->height()))
4926 << ", z =" << item->z() << ')';
4931 qint64 QSGItemPrivate::consistentTime = -1;
4932 void QSGItemPrivate::setConsistentTime(qint64 t)
4937 class QElapsedTimerConsistentTimeHack
4941 t1 = QSGItemPrivate::consistentTime;
4945 return QSGItemPrivate::consistentTime - t1;
4948 qint64 val = QSGItemPrivate::consistentTime - t1;
4949 t1 = QSGItemPrivate::consistentTime;
4959 void QSGItemPrivate::start(QElapsedTimer &t)
4961 if (QSGItemPrivate::consistentTime == -1)
4964 ((QElapsedTimerConsistentTimeHack*)&t)->start();
4967 qint64 QSGItemPrivate::elapsed(QElapsedTimer &t)
4969 if (QSGItemPrivate::consistentTime == -1)
4972 return ((QElapsedTimerConsistentTimeHack*)&t)->elapsed();
4975 qint64 QSGItemPrivate::restart(QElapsedTimer &t)
4977 if (QSGItemPrivate::consistentTime == -1)
4980 return ((QElapsedTimerConsistentTimeHack*)&t)->restart();
4985 #include <moc_qsgitem.cpp>