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 <QtWidgets/qgraphicstransform.h>
55 #include <QtGui/qpen.h>
56 #include <QtCore/qdebug.h>
57 #include <QtCore/qcoreevent.h>
58 #include <QtCore/qnumeric.h>
60 #include <private/qdeclarativeengine_p.h>
61 #include <private/qdeclarativestategroup_p.h>
62 #include <private/qdeclarativeopenmetaobject_p.h>
63 #include <private/qdeclarativestate_p.h>
64 #include <private/qlistmodelinterface_p.h>
65 #include <private/qsgitem_p.h>
69 // XXX todo Readd parentNotifier for faster parent bindings
70 // XXX todo Check that elements that create items handle memory correctly after visual ownership change
75 \qmlclass Transform QSGTransform
76 \inqmlmodule QtQuick 2
77 \ingroup qml-transform-elements
78 \brief The Transform elements provide a way of building advanced transformations on Items.
80 The Transform element is a base type which cannot be instantiated directly.
81 The following concrete Transform types are available:
89 The Transform elements let you create and control advanced transformations that can be configured
90 independently using specialized properties.
92 You can assign any number of Transform elements to an \l Item. Each Transform is applied in order,
97 \qmlclass Translate QSGTranslate
98 \inqmlmodule QtQuick 2
99 \ingroup qml-transform-elements
100 \brief The Translate object provides a way to move an Item without changing its x or y properties.
102 The Translate object provides independent control over position in addition to the Item's x and y properties.
104 The following example moves the Y axis of the \l Rectangle elements while still allowing the \l Row element
105 to lay the items out as if they had not been transformed:
111 width: 100; height: 100
113 transform: Translate { y: 20 }
116 width: 100; height: 100
118 transform: Translate { y: -20 }
127 \qmlproperty real QtQuick2::Translate::x
129 The translation along the X axis.
133 \qmlproperty real QtQuick2::Translate::y
135 The translation along the Y axis.
139 \qmlclass Scale QSGScale
140 \inqmlmodule QtQuick 2
141 \ingroup qml-transform-elements
142 \brief The Scale element provides a way to scale an Item.
144 The Scale element gives more control over scaling than using \l Item's \l{Item::scale}{scale} property. Specifically,
145 it allows a different scale for the x and y axes, and allows the scale to be relative to an
148 The following example scales the X axis of the Rectangle, relative to its interior point 25, 25:
151 width: 100; height: 100
153 transform: Scale { origin.x: 25; origin.y: 25; xScale: 3}
157 \sa Rotation, Translate
161 \qmlproperty real QtQuick2::Scale::origin.x
162 \qmlproperty real QtQuick2::Scale::origin.y
164 The point that the item is scaled from (i.e., the point that stays fixed relative to the parent as
165 the rest of the item grows). By default the origin is 0, 0.
169 \qmlproperty real QtQuick2::Scale::xScale
171 The scaling factor for the X axis.
175 \qmlproperty real QtQuick2::Scale::yScale
177 The scaling factor for the Y axis.
181 \qmlclass Rotation QSGRotation
182 \inqmlmodule QtQuick 2
183 \ingroup qml-transform-elements
184 \brief The Rotation object provides a way to rotate an Item.
186 The Rotation object gives more control over rotation than using \l Item's \l{Item::rotation}{rotation} property.
187 Specifically, it allows (z axis) rotation to be relative to an arbitrary point.
189 The following example rotates a Rectangle around its interior point 25, 25:
192 width: 100; height: 100
194 transform: Rotation { origin.x: 25; origin.y: 25; angle: 45}
198 Rotation also provides a way to specify 3D-like rotations for Items. For these types of
199 rotations you must specify the axis to rotate around in addition to the origin point.
201 The following example shows various 3D-like rotations applied to an \l Image.
202 \snippet doc/src/snippets/declarative/rotation.qml 0
204 \image axisrotation.png
206 \sa {declarative/ui-components/dialcontrol}{Dial Control example}, {declarative/toys/clocks}{Clocks example}
210 \qmlproperty real QtQuick2::Rotation::origin.x
211 \qmlproperty real QtQuick2::Rotation::origin.y
213 The origin point of the rotation (i.e., the point that stays fixed relative to the parent as
214 the rest of the item rotates). By default the origin is 0, 0.
218 \qmlproperty real QtQuick2::Rotation::axis.x
219 \qmlproperty real QtQuick2::Rotation::axis.y
220 \qmlproperty real QtQuick2::Rotation::axis.z
222 The axis to rotate around. For simple (2D) rotation around a point, you do not need to specify an axis,
223 as the default axis is the z axis (\c{ axis { x: 0; y: 0; z: 1 } }).
225 For a typical 3D-like rotation you will usually specify both the origin and the axis.
227 \image 3d-rotation-axis.png
231 \qmlproperty real QtQuick2::Rotation::angle
233 The angle to rotate, in degrees clockwise.
236 QSGTransformPrivate::QSGTransformPrivate()
240 QSGTransform::QSGTransform(QObject *parent)
241 : QObject(*(new QSGTransformPrivate), parent)
245 QSGTransform::QSGTransform(QSGTransformPrivate &dd, QObject *parent)
246 : QObject(dd, parent)
250 QSGTransform::~QSGTransform()
253 for (int ii = 0; ii < d->items.count(); ++ii) {
254 QSGItemPrivate *p = QSGItemPrivate::get(d->items.at(ii));
255 p->transforms.removeOne(this);
256 p->dirty(QSGItemPrivate::Transform);
260 void QSGTransform::update()
263 for (int ii = 0; ii < d->items.count(); ++ii) {
264 QSGItemPrivate *p = QSGItemPrivate::get(d->items.at(ii));
265 p->dirty(QSGItemPrivate::Transform);
269 QSGContents::QSGContents(QSGItem *item)
270 : m_item(item), m_x(0), m_y(0), m_width(0), m_height(0)
273 connect(this, SIGNAL(rectChanged(QRectF)), m_item, SIGNAL(childrenRectChanged(QRectF)));
276 QSGContents::~QSGContents()
278 QList<QSGItem *> children = m_item->childItems();
279 for (int i = 0; i < children.count(); ++i) {
280 QSGItem *child = children.at(i);
281 QSGItemPrivate::get(child)->removeItemChangeListener(this, QSGItemPrivate::Geometry | QSGItemPrivate::Destroyed);
285 QRectF QSGContents::rectF() const
287 return QRectF(m_x, m_y, m_width, m_height);
290 void QSGContents::calcHeight(QSGItem *changed)
293 qreal oldheight = m_height;
297 qreal bottom = oldy + oldheight;
298 qreal y = changed->y();
299 if (y + changed->height() > bottom)
300 bottom = y + changed->height();
304 m_height = bottom - top;
308 QList<QSGItem *> children = m_item->childItems();
309 for (int i = 0; i < children.count(); ++i) {
310 QSGItem *child = children.at(i);
311 qreal y = child->y();
312 if (y + child->height() > bottom)
313 bottom = y + child->height();
317 if (!children.isEmpty())
319 m_height = qMax(bottom - top, qreal(0.0));
322 if (m_height != oldheight || m_y != oldy)
323 emit rectChanged(rectF());
326 void QSGContents::calcWidth(QSGItem *changed)
329 qreal oldwidth = m_width;
333 qreal right = oldx + oldwidth;
334 qreal x = changed->x();
335 if (x + changed->width() > right)
336 right = x + changed->width();
340 m_width = right - left;
342 qreal left = FLT_MAX;
344 QList<QSGItem *> children = m_item->childItems();
345 for (int i = 0; i < children.count(); ++i) {
346 QSGItem *child = children.at(i);
347 qreal x = child->x();
348 if (x + child->width() > right)
349 right = x + child->width();
353 if (!children.isEmpty())
355 m_width = qMax(right - left, qreal(0.0));
358 if (m_width != oldwidth || m_x != oldx)
359 emit rectChanged(rectF());
362 void QSGContents::complete()
364 QList<QSGItem *> children = m_item->childItems();
365 for (int i = 0; i < children.count(); ++i) {
366 QSGItem *child = children.at(i);
367 QSGItemPrivate::get(child)->addItemChangeListener(this, QSGItemPrivate::Geometry | QSGItemPrivate::Destroyed);
368 //###what about changes to visibility?
374 void QSGContents::itemGeometryChanged(QSGItem *changed, const QRectF &newGeometry, const QRectF &oldGeometry)
377 //### we can only pass changed if the left edge has moved left, or the right edge has moved right
378 if (newGeometry.width() != oldGeometry.width() || newGeometry.x() != oldGeometry.x())
379 calcWidth(/*changed*/);
380 if (newGeometry.height() != oldGeometry.height() || newGeometry.y() != oldGeometry.y())
381 calcHeight(/*changed*/);
384 void QSGContents::itemDestroyed(QSGItem *item)
387 QSGItemPrivate::get(item)->removeItemChangeListener(this, QSGItemPrivate::Geometry | QSGItemPrivate::Destroyed);
391 void QSGContents::childRemoved(QSGItem *item)
394 QSGItemPrivate::get(item)->removeItemChangeListener(this, QSGItemPrivate::Geometry | QSGItemPrivate::Destroyed);
398 void QSGContents::childAdded(QSGItem *item)
401 QSGItemPrivate::get(item)->addItemChangeListener(this, QSGItemPrivate::Geometry | QSGItemPrivate::Destroyed);
406 QSGItemKeyFilter::QSGItemKeyFilter(QSGItem *item)
407 : m_processPost(false), m_next(0)
409 QSGItemPrivate *p = item?QSGItemPrivate::get(item):0;
411 m_next = p->keyHandler;
412 p->keyHandler = this;
416 QSGItemKeyFilter::~QSGItemKeyFilter()
420 void QSGItemKeyFilter::keyPressed(QKeyEvent *event, bool post)
422 if (m_next) m_next->keyPressed(event, post);
425 void QSGItemKeyFilter::keyReleased(QKeyEvent *event, bool post)
427 if (m_next) m_next->keyReleased(event, post);
430 void QSGItemKeyFilter::inputMethodEvent(QInputMethodEvent *event, bool post)
433 m_next->inputMethodEvent(event, post);
438 QVariant QSGItemKeyFilter::inputMethodQuery(Qt::InputMethodQuery query) const
440 if (m_next) return m_next->inputMethodQuery(query);
444 void QSGItemKeyFilter::componentComplete()
446 if (m_next) m_next->componentComplete();
449 \qmlclass KeyNavigation QSGKeyNavigationAttached
450 \inqmlmodule QtQuick 2
451 \ingroup qml-basic-interaction-elements
452 \brief The KeyNavigation attached property supports key navigation by arrow keys.
454 Key-based user interfaces commonly allow the use of arrow keys to navigate between
455 focusable items. The KeyNavigation attached property enables this behavior by providing a
456 convenient way to specify the item that should gain focus when an arrow or tab key is pressed.
458 The following example provides key navigation for a 2x2 grid of items:
460 \snippet doc/src/snippets/declarative/keynavigation.qml 0
462 The top-left item initially receives focus by setting \l {Item::}{focus} to
463 \c true. When an arrow key is pressed, the focus will move to the
464 appropriate item, as defined by the value that has been set for
465 the KeyNavigation \l left, \l right, \l up or \l down properties.
467 Note that if a KeyNavigation attached property receives the key press and release
468 events for a requested arrow or tab key, the event is accepted and does not
469 propagate any further.
471 By default, KeyNavigation receives key events after the item to which it is attached.
472 If the item accepts the key event, the KeyNavigation attached property will not
473 receive an event for that key. Setting the \l priority property to
474 \c KeyNavigation.BeforeItem allows the event to be used for key navigation
475 before the item, rather than after.
477 If item to which the focus is switching is not enabled or visible, an attempt will
478 be made to skip this item and focus on the next. This is possible if there are
479 a chain of items with the same KeyNavigation handler. If multiple items in a row are not enabled
480 or visible, they will also be skipped.
482 KeyNavigation will implicitly set the other direction to return focus to this item. So if you set
483 \l left to another item, \l right will be set on that item's KeyNavigation to set focus back to this
484 item. However, if that item's KeyNavigation has had right explicitly set then no change will occur.
485 This means that the above example could have been written, with the same behaviour, without specifing
486 KeyNavigation.right or KeyNavigation.down for any of the items.
488 \sa {Keys}{Keys attached property}
492 \qmlproperty Item QtQuick2::KeyNavigation::left
493 \qmlproperty Item QtQuick2::KeyNavigation::right
494 \qmlproperty Item QtQuick2::KeyNavigation::up
495 \qmlproperty Item QtQuick2::KeyNavigation::down
496 \qmlproperty Item QtQuick2::KeyNavigation::tab
497 \qmlproperty Item QtQuick2::KeyNavigation::backtab
499 These properties hold the item to assign focus to
500 when the left, right, up or down cursor keys, or the
505 \qmlproperty Item QtQuick2::KeyNavigation::tab
506 \qmlproperty Item QtQuick2::KeyNavigation::backtab
508 These properties hold the item to assign focus to
509 when the Tab key or Shift+Tab key combination (Backtab) are pressed.
512 QSGKeyNavigationAttached::QSGKeyNavigationAttached(QObject *parent)
513 : QObject(*(new QSGKeyNavigationAttachedPrivate), parent),
514 QSGItemKeyFilter(qobject_cast<QSGItem*>(parent))
516 m_processPost = true;
519 QSGKeyNavigationAttached *
520 QSGKeyNavigationAttached::qmlAttachedProperties(QObject *obj)
522 return new QSGKeyNavigationAttached(obj);
525 QSGItem *QSGKeyNavigationAttached::left() const
527 Q_D(const QSGKeyNavigationAttached);
531 void QSGKeyNavigationAttached::setLeft(QSGItem *i)
533 Q_D(QSGKeyNavigationAttached);
538 QSGKeyNavigationAttached* other =
539 qobject_cast<QSGKeyNavigationAttached*>(qmlAttachedPropertiesObject<QSGKeyNavigationAttached>(i));
540 if (other && !other->d_func()->rightSet){
541 other->d_func()->right = qobject_cast<QSGItem*>(parent());
542 emit other->rightChanged();
547 QSGItem *QSGKeyNavigationAttached::right() const
549 Q_D(const QSGKeyNavigationAttached);
553 void QSGKeyNavigationAttached::setRight(QSGItem *i)
555 Q_D(QSGKeyNavigationAttached);
560 QSGKeyNavigationAttached* other =
561 qobject_cast<QSGKeyNavigationAttached*>(qmlAttachedPropertiesObject<QSGKeyNavigationAttached>(i));
562 if (other && !other->d_func()->leftSet){
563 other->d_func()->left = qobject_cast<QSGItem*>(parent());
564 emit other->leftChanged();
569 QSGItem *QSGKeyNavigationAttached::up() const
571 Q_D(const QSGKeyNavigationAttached);
575 void QSGKeyNavigationAttached::setUp(QSGItem *i)
577 Q_D(QSGKeyNavigationAttached);
582 QSGKeyNavigationAttached* other =
583 qobject_cast<QSGKeyNavigationAttached*>(qmlAttachedPropertiesObject<QSGKeyNavigationAttached>(i));
584 if (other && !other->d_func()->downSet){
585 other->d_func()->down = qobject_cast<QSGItem*>(parent());
586 emit other->downChanged();
591 QSGItem *QSGKeyNavigationAttached::down() const
593 Q_D(const QSGKeyNavigationAttached);
597 void QSGKeyNavigationAttached::setDown(QSGItem *i)
599 Q_D(QSGKeyNavigationAttached);
604 QSGKeyNavigationAttached* other =
605 qobject_cast<QSGKeyNavigationAttached*>(qmlAttachedPropertiesObject<QSGKeyNavigationAttached>(i));
606 if(other && !other->d_func()->upSet){
607 other->d_func()->up = qobject_cast<QSGItem*>(parent());
608 emit other->upChanged();
613 QSGItem *QSGKeyNavigationAttached::tab() const
615 Q_D(const QSGKeyNavigationAttached);
619 void QSGKeyNavigationAttached::setTab(QSGItem *i)
621 Q_D(QSGKeyNavigationAttached);
626 QSGKeyNavigationAttached* other =
627 qobject_cast<QSGKeyNavigationAttached*>(qmlAttachedPropertiesObject<QSGKeyNavigationAttached>(i));
628 if(other && !other->d_func()->backtabSet){
629 other->d_func()->backtab = qobject_cast<QSGItem*>(parent());
630 emit other->backtabChanged();
635 QSGItem *QSGKeyNavigationAttached::backtab() const
637 Q_D(const QSGKeyNavigationAttached);
641 void QSGKeyNavigationAttached::setBacktab(QSGItem *i)
643 Q_D(QSGKeyNavigationAttached);
647 d->backtabSet = true;
648 QSGKeyNavigationAttached* other =
649 qobject_cast<QSGKeyNavigationAttached*>(qmlAttachedPropertiesObject<QSGKeyNavigationAttached>(i));
650 if(other && !other->d_func()->tabSet){
651 other->d_func()->tab = qobject_cast<QSGItem*>(parent());
652 emit other->tabChanged();
654 emit backtabChanged();
658 \qmlproperty enumeration QtQuick2::KeyNavigation::priority
660 This property determines whether the keys are processed before
661 or after the attached item's own key handling.
664 \o KeyNavigation.BeforeItem - process the key events before normal
665 item key processing. If the event is used for key navigation, it will be accepted and will not
666 be passed on to the item.
667 \o KeyNavigation.AfterItem (default) - process the key events after normal item key
668 handling. If the item accepts the key event it will not be
669 handled by the KeyNavigation attached property handler.
672 QSGKeyNavigationAttached::Priority QSGKeyNavigationAttached::priority() const
674 return m_processPost ? AfterItem : BeforeItem;
677 void QSGKeyNavigationAttached::setPriority(Priority order)
679 bool processPost = order == AfterItem;
680 if (processPost != m_processPost) {
681 m_processPost = processPost;
682 emit priorityChanged();
686 void QSGKeyNavigationAttached::keyPressed(QKeyEvent *event, bool post)
688 Q_D(QSGKeyNavigationAttached);
691 if (post != m_processPost) {
692 QSGItemKeyFilter::keyPressed(event, post);
697 switch(event->key()) {
699 if (QSGItem *parentItem = qobject_cast<QSGItem*>(parent()))
700 mirror = QSGItemPrivate::get(parentItem)->effectiveLayoutMirror;
701 QSGItem* leftItem = mirror ? d->right : d->left;
703 setFocusNavigation(leftItem, mirror ? "right" : "left");
708 case Qt::Key_Right: {
709 if (QSGItem *parentItem = qobject_cast<QSGItem*>(parent()))
710 mirror = QSGItemPrivate::get(parentItem)->effectiveLayoutMirror;
711 QSGItem* rightItem = mirror ? d->left : d->right;
713 setFocusNavigation(rightItem, mirror ? "left" : "right");
720 setFocusNavigation(d->up, "up");
726 setFocusNavigation(d->down, "down");
732 setFocusNavigation(d->tab, "tab");
736 case Qt::Key_Backtab:
738 setFocusNavigation(d->backtab, "backtab");
746 if (!event->isAccepted()) QSGItemKeyFilter::keyPressed(event, post);
749 void QSGKeyNavigationAttached::keyReleased(QKeyEvent *event, bool post)
751 Q_D(QSGKeyNavigationAttached);
754 if (post != m_processPost) {
755 QSGItemKeyFilter::keyReleased(event, post);
760 switch(event->key()) {
762 if (QSGItem *parentItem = qobject_cast<QSGItem*>(parent()))
763 mirror = QSGItemPrivate::get(parentItem)->effectiveLayoutMirror;
764 if (mirror ? d->right : d->left)
768 if (QSGItem *parentItem = qobject_cast<QSGItem*>(parent()))
769 mirror = QSGItemPrivate::get(parentItem)->effectiveLayoutMirror;
770 if (mirror ? d->left : d->right)
788 case Qt::Key_Backtab:
797 if (!event->isAccepted()) QSGItemKeyFilter::keyReleased(event, post);
800 void QSGKeyNavigationAttached::setFocusNavigation(QSGItem *currentItem, const char *dir)
802 QSGItem *initialItem = currentItem;
803 bool isNextItem = false;
806 if (currentItem->isVisible() && currentItem->isEnabled()) {
807 currentItem->setFocus(true);
810 qmlAttachedPropertiesObject<QSGKeyNavigationAttached>(currentItem, false);
812 QSGItem *tempItem = qvariant_cast<QSGItem*>(attached->property(dir));
814 currentItem = tempItem;
820 while (currentItem != initialItem && isNextItem);
823 const QSGKeysAttached::SigMap QSGKeysAttached::sigMap[] = {
824 { Qt::Key_Left, "leftPressed" },
825 { Qt::Key_Right, "rightPressed" },
826 { Qt::Key_Up, "upPressed" },
827 { Qt::Key_Down, "downPressed" },
828 { Qt::Key_Tab, "tabPressed" },
829 { Qt::Key_Backtab, "backtabPressed" },
830 { Qt::Key_Asterisk, "asteriskPressed" },
831 { Qt::Key_NumberSign, "numberSignPressed" },
832 { Qt::Key_Escape, "escapePressed" },
833 { Qt::Key_Return, "returnPressed" },
834 { Qt::Key_Enter, "enterPressed" },
835 { Qt::Key_Delete, "deletePressed" },
836 { Qt::Key_Space, "spacePressed" },
837 { Qt::Key_Back, "backPressed" },
838 { Qt::Key_Cancel, "cancelPressed" },
839 { Qt::Key_Select, "selectPressed" },
840 { Qt::Key_Yes, "yesPressed" },
841 { Qt::Key_No, "noPressed" },
842 { Qt::Key_Context1, "context1Pressed" },
843 { Qt::Key_Context2, "context2Pressed" },
844 { Qt::Key_Context3, "context3Pressed" },
845 { Qt::Key_Context4, "context4Pressed" },
846 { Qt::Key_Call, "callPressed" },
847 { Qt::Key_Hangup, "hangupPressed" },
848 { Qt::Key_Flip, "flipPressed" },
849 { Qt::Key_Menu, "menuPressed" },
850 { Qt::Key_VolumeUp, "volumeUpPressed" },
851 { Qt::Key_VolumeDown, "volumeDownPressed" },
855 bool QSGKeysAttachedPrivate::isConnected(const char *signalName)
857 return isSignalConnected(signalIndex(signalName));
861 \qmlclass Keys QSGKeysAttached
862 \inqmlmodule QtQuick 2
863 \ingroup qml-basic-interaction-elements
864 \brief The Keys attached property provides key handling to Items.
866 All visual primitives support key handling via the Keys
867 attached property. Keys can be handled via the onPressed
868 and onReleased signal properties.
870 The signal properties have a \l KeyEvent parameter, named
871 \e event which contains details of the event. If a key is
872 handled \e event.accepted should be set to true to prevent the
873 event from propagating up the item hierarchy.
875 \section1 Example Usage
877 The following example shows how the general onPressed handler can
878 be used to test for a certain key; in this case, the left cursor
881 \snippet doc/src/snippets/declarative/keys/keys-pressed.qml key item
883 Some keys may alternatively be handled via specific signal properties,
884 for example \e onSelectPressed. These handlers automatically set
885 \e event.accepted to true.
887 \snippet doc/src/snippets/declarative/keys/keys-handler.qml key item
889 See \l{Qt::Key}{Qt.Key} for the list of keyboard codes.
891 \section1 Key Handling Priorities
893 The Keys attached property can be configured to handle key events
894 before or after the item it is attached to. This makes it possible
895 to intercept events in order to override an item's default behavior,
896 or act as a fallback for keys not handled by the item.
898 If \l priority is Keys.BeforeItem (default) the order of key event processing is:
901 \o Items specified in \c forwardTo
902 \o specific key handlers, e.g. onReturnPressed
903 \o onKeyPress, onKeyRelease handlers
904 \o Item specific key handling, e.g. TextInput key handling
908 If priority is Keys.AfterItem the order of key event processing is:
911 \o Item specific key handling, e.g. TextInput key handling
912 \o Items specified in \c forwardTo
913 \o specific key handlers, e.g. onReturnPressed
914 \o onKeyPress, onKeyRelease handlers
918 If the event is accepted during any of the above steps, key
921 \sa KeyEvent, {KeyNavigation}{KeyNavigation attached property}
925 \qmlproperty bool QtQuick2::Keys::enabled
927 This flags enables key handling if true (default); otherwise
928 no key handlers will be called.
932 \qmlproperty enumeration QtQuick2::Keys::priority
934 This property determines whether the keys are processed before
935 or after the attached item's own key handling.
938 \o Keys.BeforeItem (default) - process the key events before normal
939 item key processing. If the event is accepted it will not
940 be passed on to the item.
941 \o Keys.AfterItem - process the key events after normal item key
942 handling. If the item accepts the key event it will not be
943 handled by the Keys attached property handler.
948 \qmlproperty list<Object> QtQuick2::Keys::forwardTo
950 This property provides a way to forward key presses, key releases, and keyboard input
951 coming from input methods to other items. This can be useful when you want
952 one item to handle some keys (e.g. the up and down arrow keys), and another item to
953 handle other keys (e.g. the left and right arrow keys). Once an item that has been
954 forwarded keys accepts the event it is no longer forwarded to items later in the
957 This example forwards key events to two lists:
968 Keys.forwardTo: [list1, list2]
975 \qmlsignal QtQuick2::Keys::onPressed(KeyEvent event)
977 This handler is called when a key has been pressed. The \a event
978 parameter provides information about the event.
982 \qmlsignal QtQuick2::Keys::onReleased(KeyEvent event)
984 This handler is called when a key has been released. The \a event
985 parameter provides information about the event.
989 \qmlsignal QtQuick2::Keys::onDigit0Pressed(KeyEvent event)
991 This handler is called when the digit '0' has been pressed. The \a event
992 parameter provides information about the event.
996 \qmlsignal QtQuick2::Keys::onDigit1Pressed(KeyEvent event)
998 This handler is called when the digit '1' has been pressed. The \a event
999 parameter provides information about the event.
1003 \qmlsignal QtQuick2::Keys::onDigit2Pressed(KeyEvent event)
1005 This handler is called when the digit '2' has been pressed. The \a event
1006 parameter provides information about the event.
1010 \qmlsignal QtQuick2::Keys::onDigit3Pressed(KeyEvent event)
1012 This handler is called when the digit '3' has been pressed. The \a event
1013 parameter provides information about the event.
1017 \qmlsignal QtQuick2::Keys::onDigit4Pressed(KeyEvent event)
1019 This handler is called when the digit '4' has been pressed. The \a event
1020 parameter provides information about the event.
1024 \qmlsignal QtQuick2::Keys::onDigit5Pressed(KeyEvent event)
1026 This handler is called when the digit '5' has been pressed. The \a event
1027 parameter provides information about the event.
1031 \qmlsignal QtQuick2::Keys::onDigit6Pressed(KeyEvent event)
1033 This handler is called when the digit '6' has been pressed. The \a event
1034 parameter provides information about the event.
1038 \qmlsignal QtQuick2::Keys::onDigit7Pressed(KeyEvent event)
1040 This handler is called when the digit '7' has been pressed. The \a event
1041 parameter provides information about the event.
1045 \qmlsignal QtQuick2::Keys::onDigit8Pressed(KeyEvent event)
1047 This handler is called when the digit '8' has been pressed. The \a event
1048 parameter provides information about the event.
1052 \qmlsignal QtQuick2::Keys::onDigit9Pressed(KeyEvent event)
1054 This handler is called when the digit '9' has been pressed. The \a event
1055 parameter provides information about the event.
1059 \qmlsignal QtQuick2::Keys::onLeftPressed(KeyEvent event)
1061 This handler is called when the Left arrow has been pressed. The \a event
1062 parameter provides information about the event.
1066 \qmlsignal QtQuick2::Keys::onRightPressed(KeyEvent event)
1068 This handler is called when the Right arrow has been pressed. The \a event
1069 parameter provides information about the event.
1073 \qmlsignal QtQuick2::Keys::onUpPressed(KeyEvent event)
1075 This handler is called when the Up arrow has been pressed. The \a event
1076 parameter provides information about the event.
1080 \qmlsignal QtQuick2::Keys::onDownPressed(KeyEvent event)
1082 This handler is called when the Down arrow has been pressed. The \a event
1083 parameter provides information about the event.
1087 \qmlsignal QtQuick2::Keys::onTabPressed(KeyEvent event)
1089 This handler is called when the Tab key has been pressed. The \a event
1090 parameter provides information about the event.
1094 \qmlsignal QtQuick2::Keys::onBacktabPressed(KeyEvent event)
1096 This handler is called when the Shift+Tab key combination (Backtab) has
1097 been pressed. The \a event parameter provides information about the event.
1101 \qmlsignal QtQuick2::Keys::onAsteriskPressed(KeyEvent event)
1103 This handler is called when the Asterisk '*' has been pressed. The \a event
1104 parameter provides information about the event.
1108 \qmlsignal QtQuick2::Keys::onEscapePressed(KeyEvent event)
1110 This handler is called when the Escape key has been pressed. The \a event
1111 parameter provides information about the event.
1115 \qmlsignal QtQuick2::Keys::onReturnPressed(KeyEvent event)
1117 This handler is called when the Return key has been pressed. The \a event
1118 parameter provides information about the event.
1122 \qmlsignal QtQuick2::Keys::onEnterPressed(KeyEvent event)
1124 This handler is called when the Enter key has been pressed. The \a event
1125 parameter provides information about the event.
1129 \qmlsignal QtQuick2::Keys::onDeletePressed(KeyEvent event)
1131 This handler is called when the Delete key has been pressed. The \a event
1132 parameter provides information about the event.
1136 \qmlsignal QtQuick2::Keys::onSpacePressed(KeyEvent event)
1138 This handler is called when the Space key has been pressed. The \a event
1139 parameter provides information about the event.
1143 \qmlsignal QtQuick2::Keys::onBackPressed(KeyEvent event)
1145 This handler is called when the Back key has been pressed. The \a event
1146 parameter provides information about the event.
1150 \qmlsignal QtQuick2::Keys::onCancelPressed(KeyEvent event)
1152 This handler is called when the Cancel key has been pressed. The \a event
1153 parameter provides information about the event.
1157 \qmlsignal QtQuick2::Keys::onSelectPressed(KeyEvent event)
1159 This handler is called when the Select key has been pressed. The \a event
1160 parameter provides information about the event.
1164 \qmlsignal QtQuick2::Keys::onYesPressed(KeyEvent event)
1166 This handler is called when the Yes key has been pressed. The \a event
1167 parameter provides information about the event.
1171 \qmlsignal QtQuick2::Keys::onNoPressed(KeyEvent event)
1173 This handler is called when the No key has been pressed. The \a event
1174 parameter provides information about the event.
1178 \qmlsignal QtQuick2::Keys::onContext1Pressed(KeyEvent event)
1180 This handler is called when the Context1 key has been pressed. The \a event
1181 parameter provides information about the event.
1185 \qmlsignal QtQuick2::Keys::onContext2Pressed(KeyEvent event)
1187 This handler is called when the Context2 key has been pressed. The \a event
1188 parameter provides information about the event.
1192 \qmlsignal QtQuick2::Keys::onContext3Pressed(KeyEvent event)
1194 This handler is called when the Context3 key has been pressed. The \a event
1195 parameter provides information about the event.
1199 \qmlsignal QtQuick2::Keys::onContext4Pressed(KeyEvent event)
1201 This handler is called when the Context4 key has been pressed. The \a event
1202 parameter provides information about the event.
1206 \qmlsignal QtQuick2::Keys::onCallPressed(KeyEvent event)
1208 This handler is called when the Call key has been pressed. The \a event
1209 parameter provides information about the event.
1213 \qmlsignal QtQuick2::Keys::onHangupPressed(KeyEvent event)
1215 This handler is called when the Hangup key has been pressed. The \a event
1216 parameter provides information about the event.
1220 \qmlsignal QtQuick2::Keys::onFlipPressed(KeyEvent event)
1222 This handler is called when the Flip key has been pressed. The \a event
1223 parameter provides information about the event.
1227 \qmlsignal QtQuick2::Keys::onMenuPressed(KeyEvent event)
1229 This handler is called when the Menu key has been pressed. The \a event
1230 parameter provides information about the event.
1234 \qmlsignal QtQuick2::Keys::onVolumeUpPressed(KeyEvent event)
1236 This handler is called when the VolumeUp key has been pressed. The \a event
1237 parameter provides information about the event.
1241 \qmlsignal QtQuick2::Keys::onVolumeDownPressed(KeyEvent event)
1243 This handler is called when the VolumeDown key has been pressed. The \a event
1244 parameter provides information about the event.
1247 QSGKeysAttached::QSGKeysAttached(QObject *parent)
1248 : QObject(*(new QSGKeysAttachedPrivate), parent),
1249 QSGItemKeyFilter(qobject_cast<QSGItem*>(parent))
1251 Q_D(QSGKeysAttached);
1252 m_processPost = false;
1253 d->item = qobject_cast<QSGItem*>(parent);
1256 QSGKeysAttached::~QSGKeysAttached()
1260 QSGKeysAttached::Priority QSGKeysAttached::priority() const
1262 return m_processPost ? AfterItem : BeforeItem;
1265 void QSGKeysAttached::setPriority(Priority order)
1267 bool processPost = order == AfterItem;
1268 if (processPost != m_processPost) {
1269 m_processPost = processPost;
1270 emit priorityChanged();
1274 void QSGKeysAttached::componentComplete()
1276 Q_D(QSGKeysAttached);
1278 for (int ii = 0; ii < d->targets.count(); ++ii) {
1279 QSGItem *targetItem = d->targets.at(ii);
1280 if (targetItem && (targetItem->flags() & QSGItem::ItemAcceptsInputMethod)) {
1281 d->item->setFlag(QSGItem::ItemAcceptsInputMethod);
1288 void QSGKeysAttached::keyPressed(QKeyEvent *event, bool post)
1290 Q_D(QSGKeysAttached);
1291 if (post != m_processPost || !d->enabled || d->inPress) {
1293 QSGItemKeyFilter::keyPressed(event, post);
1297 // first process forwards
1298 if (d->item && d->item->canvas()) {
1300 for (int ii = 0; ii < d->targets.count(); ++ii) {
1301 QSGItem *i = d->targets.at(ii);
1302 if (i && i->isVisible()) {
1303 d->item->canvas()->sendEvent(i, event);
1304 if (event->isAccepted()) {
1313 QSGKeyEvent ke(*event);
1314 QByteArray keySignal = keyToSignal(event->key());
1315 if (!keySignal.isEmpty()) {
1316 keySignal += "(QSGKeyEvent*)";
1317 if (d->isConnected(keySignal)) {
1318 // If we specifically handle a key then default to accepted
1319 ke.setAccepted(true);
1320 int idx = QSGKeysAttached::staticMetaObject.indexOfSignal(keySignal);
1321 metaObject()->method(idx).invoke(this, Qt::DirectConnection, Q_ARG(QSGKeyEvent*, &ke));
1324 if (!ke.isAccepted())
1326 event->setAccepted(ke.isAccepted());
1328 if (!event->isAccepted()) QSGItemKeyFilter::keyPressed(event, post);
1331 void QSGKeysAttached::keyReleased(QKeyEvent *event, bool post)
1333 Q_D(QSGKeysAttached);
1334 if (post != m_processPost || !d->enabled || d->inRelease) {
1336 QSGItemKeyFilter::keyReleased(event, post);
1340 if (d->item && d->item->canvas()) {
1341 d->inRelease = true;
1342 for (int ii = 0; ii < d->targets.count(); ++ii) {
1343 QSGItem *i = d->targets.at(ii);
1344 if (i && i->isVisible()) {
1345 d->item->canvas()->sendEvent(i, event);
1346 if (event->isAccepted()) {
1347 d->inRelease = false;
1352 d->inRelease = false;
1355 QSGKeyEvent ke(*event);
1357 event->setAccepted(ke.isAccepted());
1359 if (!event->isAccepted()) QSGItemKeyFilter::keyReleased(event, post);
1362 void QSGKeysAttached::inputMethodEvent(QInputMethodEvent *event, bool post)
1364 Q_D(QSGKeysAttached);
1365 if (post == m_processPost && d->item && !d->inIM && d->item->canvas()) {
1367 for (int ii = 0; ii < d->targets.count(); ++ii) {
1368 QSGItem *i = d->targets.at(ii);
1369 if (i && i->isVisible() && (i->flags() & QSGItem::ItemAcceptsInputMethod)) {
1370 d->item->canvas()->sendEvent(i, event);
1371 if (event->isAccepted()) {
1380 QSGItemKeyFilter::inputMethodEvent(event, post);
1383 QVariant QSGKeysAttached::inputMethodQuery(Qt::InputMethodQuery query) const
1385 Q_D(const QSGKeysAttached);
1387 for (int ii = 0; ii < d->targets.count(); ++ii) {
1388 QSGItem *i = d->targets.at(ii);
1389 if (i && i->isVisible() && (i->flags() & QSGItem::ItemAcceptsInputMethod) && i == d->imeItem) {
1390 //### how robust is i == d->imeItem check?
1391 QVariant v = i->inputMethodQuery(query);
1392 if (v.userType() == QVariant::RectF)
1393 v = d->item->mapRectFromItem(i, v.toRectF()); //### cost?
1398 return QSGItemKeyFilter::inputMethodQuery(query);
1401 QSGKeysAttached *QSGKeysAttached::qmlAttachedProperties(QObject *obj)
1403 return new QSGKeysAttached(obj);
1407 \qmlclass LayoutMirroring QSGLayoutMirroringAttached
1408 \inqmlmodule QtQuick 2
1409 \ingroup qml-utility-elements
1410 \brief The LayoutMirroring attached property is used to mirror layout behavior.
1412 The LayoutMirroring attached property is used to horizontally mirror \l {anchor-layout}{Item anchors},
1413 \l{Using QML Positioner and Repeater Items}{positioner} elements (such as \l Row and \l Grid)
1414 and views (such as \l GridView and horizontal \l ListView). Mirroring is a visual change: left
1415 anchors become right anchors, and positioner elements like \l Grid and \l Row reverse the
1416 horizontal layout of child items.
1418 Mirroring is enabled for an item by setting the \l enabled property to true. By default, this
1419 only affects the item itself; setting the \l childrenInherit property to true propagates the mirroring
1420 behavior to all child elements as well. If the \c LayoutMirroring attached property has not been defined
1421 for an item, mirroring is not enabled.
1423 The following example shows mirroring in action. The \l Row below is specified as being anchored
1424 to the left of its parent. However, since mirroring has been enabled, the anchor is horizontally
1425 reversed and it is now anchored to the right. Also, since items in a \l Row are positioned
1426 from left to right by default, they are now positioned from right to left instead, as demonstrated
1427 by the numbering and opacity of the items:
1429 \snippet doc/src/snippets/declarative/layoutmirroring.qml 0
1431 \image layoutmirroring.png
1433 Layout mirroring is useful when it is necessary to support both left-to-right and right-to-left
1434 layout versions of an application to target different language areas. The \l childrenInherit
1435 property allows layout mirroring to be applied without manually setting layout configurations
1436 for every item in an application. Keep in mind, however, that mirroring does not affect any
1437 positioning that is defined by the \l Item \l {Item::}{x} coordinate value, so even with
1438 mirroring enabled, it will often be necessary to apply some layout fixes to support the
1439 desired layout direction. Also, it may be necessary to disable the mirroring of individual
1440 child items (by setting \l {enabled}{LayoutMirroring.enabled} to false for such items) if
1441 mirroring is not the desired behavior, or if the child item already implements mirroring in
1444 See \l {QML Right-to-left User Interfaces} for further details on using \c LayoutMirroring and
1445 other related features to implement right-to-left support for an application.
1449 \qmlproperty bool QtQuick2::LayoutMirroring::enabled
1451 This property holds whether the item's layout is mirrored horizontally. Setting this to true
1452 horizontally reverses \l {anchor-layout}{anchor} settings such that left anchors become right,
1453 and right anchors become left. For \l{Using QML Positioner and Repeater Items}{positioner} elements
1454 (such as \l Row and \l Grid) and view elements (such as \l {GridView}{GridView} and \l {ListView}{ListView})
1455 this also mirrors the horizontal layout direction of the item.
1457 The default value is false.
1461 \qmlproperty bool QtQuick2::LayoutMirroring::childrenInherit
1463 This property holds whether the \l {enabled}{LayoutMirroring.enabled} value for this item
1464 is inherited by its children.
1466 The default value is false.
1470 QSGLayoutMirroringAttached::QSGLayoutMirroringAttached(QObject *parent) : QObject(parent), itemPrivate(0)
1472 if (QSGItem *item = qobject_cast<QSGItem*>(parent)) {
1473 itemPrivate = QSGItemPrivate::get(item);
1474 itemPrivate->attachedLayoutDirection = this;
1476 qmlInfo(parent) << tr("LayoutDirection attached property only works with Items");
1479 QSGLayoutMirroringAttached * QSGLayoutMirroringAttached::qmlAttachedProperties(QObject *object)
1481 return new QSGLayoutMirroringAttached(object);
1484 bool QSGLayoutMirroringAttached::enabled() const
1486 return itemPrivate ? itemPrivate->effectiveLayoutMirror : false;
1489 void QSGLayoutMirroringAttached::setEnabled(bool enabled)
1494 itemPrivate->isMirrorImplicit = false;
1495 if (enabled != itemPrivate->effectiveLayoutMirror) {
1496 itemPrivate->setLayoutMirror(enabled);
1497 if (itemPrivate->inheritMirrorFromItem)
1498 itemPrivate->resolveLayoutMirror();
1502 void QSGLayoutMirroringAttached::resetEnabled()
1504 if (itemPrivate && !itemPrivate->isMirrorImplicit) {
1505 itemPrivate->isMirrorImplicit = true;
1506 itemPrivate->resolveLayoutMirror();
1510 bool QSGLayoutMirroringAttached::childrenInherit() const
1512 return itemPrivate ? itemPrivate->inheritMirrorFromItem : false;
1515 void QSGLayoutMirroringAttached::setChildrenInherit(bool childrenInherit) {
1516 if (itemPrivate && childrenInherit != itemPrivate->inheritMirrorFromItem) {
1517 itemPrivate->inheritMirrorFromItem = childrenInherit;
1518 itemPrivate->resolveLayoutMirror();
1519 childrenInheritChanged();
1523 void QSGItemPrivate::resolveLayoutMirror()
1526 if (QSGItem *parentItem = q->parentItem()) {
1527 QSGItemPrivate *parentPrivate = QSGItemPrivate::get(parentItem);
1528 setImplicitLayoutMirror(parentPrivate->inheritedLayoutMirror, parentPrivate->inheritMirrorFromParent);
1530 setImplicitLayoutMirror(isMirrorImplicit ? false : effectiveLayoutMirror, inheritMirrorFromItem);
1534 void QSGItemPrivate::setImplicitLayoutMirror(bool mirror, bool inherit)
1536 inherit = inherit || inheritMirrorFromItem;
1537 if (!isMirrorImplicit && inheritMirrorFromItem)
1538 mirror = effectiveLayoutMirror;
1539 if (mirror == inheritedLayoutMirror && inherit == inheritMirrorFromParent)
1542 inheritMirrorFromParent = inherit;
1543 inheritedLayoutMirror = inheritMirrorFromParent ? mirror : false;
1545 if (isMirrorImplicit)
1546 setLayoutMirror(inherit ? inheritedLayoutMirror : false);
1547 for (int i = 0; i < childItems.count(); ++i) {
1548 if (QSGItem *child = qobject_cast<QSGItem *>(childItems.at(i))) {
1549 QSGItemPrivate *childPrivate = QSGItemPrivate::get(child);
1550 childPrivate->setImplicitLayoutMirror(inheritedLayoutMirror, inheritMirrorFromParent);
1555 void QSGItemPrivate::setLayoutMirror(bool mirror)
1557 if (mirror != effectiveLayoutMirror) {
1558 effectiveLayoutMirror = mirror;
1560 QSGAnchorsPrivate *anchor_d = QSGAnchorsPrivate::get(_anchors);
1561 anchor_d->fillChanged();
1562 anchor_d->centerInChanged();
1563 anchor_d->updateHorizontalAnchors();
1564 emit _anchors->mirroredChanged();
1567 if (attachedLayoutDirection) {
1568 emit attachedLayoutDirection->enabledChanged();
1575 \brief The QSGItem class provides the most basic of all visual items in QML.
1577 All visual items in Qt Declarative inherit from QSGItem. Although QSGItem
1578 has no visual appearance, it defines all the properties that are
1579 common across visual items - such as the x and y position, the
1580 width and height, \l {anchor-layout}{anchoring} and key handling.
1582 You can subclass QSGItem to provide your own custom visual item that inherits
1583 these features. Note that, because it does not draw anything, QSGItem sets the
1584 QGraphicsItem::ItemHasNoContents flag. If you subclass QSGItem to create a visual
1585 item, you will need to unset this flag.
1590 \qmlclass Item QSGItem
1591 \inqmlmodule QtQuick 2
1592 \ingroup qml-basic-visual-elements
1593 \brief The Item is the most basic of all visual items in QML.
1595 All visual items in Qt Declarative inherit from Item. Although Item
1596 has no visual appearance, it defines all the properties that are
1597 common across visual items - such as the x and y position, the
1598 width and height, \l {anchor-layout}{anchoring} and key handling.
1600 Item is also useful for grouping items together.
1617 fillMode: Image.Tile
1624 \section1 Key Handling
1626 Key handling is available to all Item-based visual elements via the \l {Keys}{Keys}
1627 attached property. The \e Keys attached property provides basic handlers such
1628 as \l {Keys::onPressed}{onPressed} and \l {Keys::onReleased}{onReleased},
1629 as well as handlers for specific keys, such as
1630 \l {Keys::onCancelPressed}{onCancelPressed}. The example below
1631 assigns \l {qmlfocus}{focus} to the item and handles
1632 the Left key via the general \e onPressed handler and the Select key via the
1633 onSelectPressed handler:
1639 if (event.key == Qt.Key_Left) {
1640 console.log("move left");
1641 event.accepted = true;
1644 Keys.onSelectPressed: console.log("Selected");
1648 See the \l {Keys}{Keys} attached property for detailed documentation.
1650 \section1 Layout Mirroring
1652 Item layouts can be mirrored using the \l {LayoutMirroring}{LayoutMirroring} attached property.
1657 \fn void QSGItem::childrenRectChanged(const QRectF &)
1662 \fn void QSGItem::baselineOffsetChanged(qreal)
1667 \fn void QSGItem::stateChanged(const QString &state)
1672 \fn void QSGItem::parentChanged(QSGItem *)
1677 \fn void QSGItem::smoothChanged(bool)
1682 \fn void QSGItem::clipChanged(bool)
1686 /*! \fn void QSGItem::transformOriginChanged(TransformOrigin)
1691 \fn void QSGItem::focusChanged(bool)
1696 \fn void QSGItem::activeFocusChanged(bool)
1700 \fn QSGItem::QSGItem(QSGItem *parent)
1702 Constructs a QSGItem with the given \a parent.
1704 QSGItem::QSGItem(QSGItem* parent)
1705 : QObject(*(new QSGItemPrivate), parent)
1713 QSGItem::QSGItem(QSGItemPrivate &dd, QSGItem *parent)
1714 : QObject(dd, parent)
1721 static int qt_item_count = 0;
1723 static void qt_print_item_count()
1725 qDebug("Number of leaked items: %i", qt_item_count);
1731 Destroys the QSGItem.
1737 if (qt_item_count < 0)
1738 qDebug("Item destroyed after qt_print_item_count() was called.");
1745 else if (d->canvas && d->itemNodeInstance)
1746 QSGCanvasPrivate::get(d->canvas)->cleanup(d->itemNodeInstance); // cleanup root
1747 // XXX todo - optimize
1748 while (!d->childItems.isEmpty())
1749 d->childItems.first()->setParentItem(0);
1751 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
1752 QSGAnchorsPrivate *anchor = d->changeListeners.at(ii).listener->anchorPrivate();
1754 anchor->clearItem(this);
1757 // XXX todo - the original checks if the parent is being destroyed
1758 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
1759 QSGAnchorsPrivate *anchor = d->changeListeners.at(ii).listener->anchorPrivate();
1760 if (anchor && anchor->item && anchor->item->parent() != this) //child will be deleted anyway
1761 anchor->updateOnComplete();
1764 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
1765 const QSGItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
1766 if (change.types & QSGItemPrivate::Destroyed)
1767 change.listener->itemDestroyed(this);
1769 d->changeListeners.clear();
1770 delete d->_anchorLines; d->_anchorLines = 0;
1771 delete d->_anchors; d->_anchors = 0;
1772 delete d->_stateGroup; d->_stateGroup = 0;
1773 delete d->_contents; d->_contents = 0;
1777 \qmlproperty enumeration QtQuick2::Item::transformOrigin
1778 This property holds the origin point around which scale and rotation transform.
1780 Nine transform origins are available, as shown in the image below.
1782 \image declarative-transformorigin.png
1784 This example rotates an image around its bottom-right corner.
1787 source: "myimage.png"
1788 transformOrigin: Item.BottomRight
1793 The default transform origin is \c Item.Center.
1795 To set an arbitrary transform origin point use the \l Scale or \l Rotation
1800 \qmlproperty Item QtQuick2::Item::parent
1801 This property holds the parent of the item.
1805 \property QSGItem::parent
1806 This property holds the parent of the item.
1808 void QSGItem::setParentItem(QSGItem *parentItem)
1811 if (parentItem == d->parentItem)
1814 d->removeFromDirtyList();
1816 QSGItem *oldParentItem = d->parentItem;
1817 QSGItem *scopeFocusedItem = 0;
1819 if (oldParentItem) {
1820 QSGItemPrivate *op = QSGItemPrivate::get(oldParentItem);
1822 QSGItem *scopeItem = 0;
1824 if (d->canvas && hasFocus()) {
1825 scopeItem = oldParentItem;
1826 while (!scopeItem->isFocusScope()) scopeItem = scopeItem->parentItem();
1827 scopeFocusedItem = this;
1828 } else if (d->canvas && !isFocusScope() && d->subFocusItem) {
1829 scopeItem = oldParentItem;
1830 while (!scopeItem->isFocusScope()) scopeItem = scopeItem->parentItem();
1831 scopeFocusedItem = d->subFocusItem;
1834 if (scopeFocusedItem)
1835 QSGCanvasPrivate::get(d->canvas)->clearFocusInScope(scopeItem, scopeFocusedItem,
1836 QSGCanvasPrivate::DontChangeFocusProperty);
1838 op->removeChild(this);
1841 d->parentItem = parentItem;
1843 QSGCanvas *parentCanvas = parentItem?QSGItemPrivate::get(parentItem)->canvas:0;
1844 if (d->canvas != parentCanvas) {
1845 QSGItemPrivate::InitializationState initState;
1847 d->initCanvas(&initState, parentCanvas);
1850 d->dirty(QSGItemPrivate::ParentChanged);
1853 QSGItemPrivate::get(d->parentItem)->addChild(this);
1855 d->setEffectiveVisibleRecur(d->calcEffectiveVisible());
1856 d->setEffectiveEnableRecur(d->calcEffectiveEnable());
1858 if (scopeFocusedItem && d->parentItem && d->canvas) {
1859 // We need to test whether this item becomes scope focused
1860 QSGItem *scopeItem = 0;
1861 scopeItem = d->parentItem;
1862 while (!scopeItem->isFocusScope()) scopeItem = scopeItem->parentItem();
1864 if (scopeItem->scopedFocusItem()) {
1865 QSGItemPrivate::get(scopeFocusedItem)->focus = false;
1866 emit scopeFocusedItem->focusChanged(false);
1868 QSGCanvasPrivate::get(d->canvas)->setFocusInScope(scopeItem, scopeFocusedItem,
1869 QSGCanvasPrivate::DontChangeFocusProperty);
1873 d->resolveLayoutMirror();
1875 d->itemChange(ItemParentHasChanged, d->parentItem);
1877 emit parentChanged(d->parentItem);
1880 void QSGItem::stackBefore(const QSGItem *sibling)
1883 if (!sibling || sibling == this || !d->parentItem || d->parentItem != QSGItemPrivate::get(sibling)->parentItem) {
1884 qWarning("QSGItem::stackBefore: Cannot stack before %p, which must be a sibling", sibling);
1888 QSGItemPrivate *parentPrivate = QSGItemPrivate::get(d->parentItem);
1890 int myIndex = parentPrivate->childItems.indexOf(this);
1891 int siblingIndex = parentPrivate->childItems.indexOf(const_cast<QSGItem *>(sibling));
1893 Q_ASSERT(myIndex != -1 && siblingIndex != -1);
1895 if (myIndex == siblingIndex - 1)
1898 parentPrivate->childItems.removeAt(myIndex);
1900 if (myIndex < siblingIndex) --siblingIndex;
1902 parentPrivate->childItems.insert(siblingIndex, this);
1904 parentPrivate->dirty(QSGItemPrivate::ChildrenStackingChanged);
1906 for (int ii = qMin(siblingIndex, myIndex); ii < parentPrivate->childItems.count(); ++ii)
1907 QSGItemPrivate::get(parentPrivate->childItems.at(ii))->siblingOrderChanged();
1910 void QSGItem::stackAfter(const QSGItem *sibling)
1913 if (!sibling || sibling == this || !d->parentItem || d->parentItem != QSGItemPrivate::get(sibling)->parentItem) {
1914 qWarning("QSGItem::stackAfter: Cannot stack after %p, which must be a sibling", sibling);
1918 QSGItemPrivate *parentPrivate = QSGItemPrivate::get(d->parentItem);
1920 int myIndex = parentPrivate->childItems.indexOf(this);
1921 int siblingIndex = parentPrivate->childItems.indexOf(const_cast<QSGItem *>(sibling));
1923 Q_ASSERT(myIndex != -1 && siblingIndex != -1);
1925 if (myIndex == siblingIndex + 1)
1928 parentPrivate->childItems.removeAt(myIndex);
1930 if (myIndex < siblingIndex) --siblingIndex;
1932 parentPrivate->childItems.insert(siblingIndex + 1, this);
1934 parentPrivate->dirty(QSGItemPrivate::ChildrenStackingChanged);
1936 for (int ii = qMin(myIndex, siblingIndex + 1); ii < parentPrivate->childItems.count(); ++ii)
1937 QSGItemPrivate::get(parentPrivate->childItems.at(ii))->siblingOrderChanged();
1941 Returns the QSGItem parent of this item.
1943 QSGItem *QSGItem::parentItem() const
1946 return d->parentItem;
1949 QSGEngine *QSGItem::sceneGraphEngine() const
1951 return canvas()->sceneGraphEngine();
1954 QSGCanvas *QSGItem::canvas() const
1960 static bool itemZOrder_sort(QSGItem *lhs, QSGItem *rhs)
1962 return lhs->z() < rhs->z();
1965 QList<QSGItem *> QSGItemPrivate::paintOrderChildItems() const
1967 // XXX todo - optimize, don't sort and return items that are
1968 // ignored anyway, like invisible or disabled items.
1969 QList<QSGItem *> items = childItems;
1970 qStableSort(items.begin(), items.end(), itemZOrder_sort);
1974 void QSGItemPrivate::addChild(QSGItem *child)
1978 Q_ASSERT(!childItems.contains(child));
1980 childItems.append(child);
1982 dirty(QSGItemPrivate::ChildrenChanged);
1984 itemChange(QSGItem::ItemChildAddedChange, child);
1986 emit q->childrenChanged();
1989 void QSGItemPrivate::removeChild(QSGItem *child)
1994 Q_ASSERT(childItems.contains(child));
1995 childItems.removeOne(child);
1996 Q_ASSERT(!childItems.contains(child));
1998 dirty(QSGItemPrivate::ChildrenChanged);
2000 itemChange(QSGItem::ItemChildRemovedChange, child);
2002 emit q->childrenChanged();
2005 void QSGItemPrivate::InitializationState::clear()
2010 void QSGItemPrivate::InitializationState::clear(QSGItem *fs)
2015 QSGItem *QSGItemPrivate::InitializationState::getFocusScope(QSGItem *item)
2018 QSGItem *fs = item->parentItem();
2019 while (!fs->isFocusScope())
2020 fs = fs->parentItem();
2026 void QSGItemPrivate::initCanvas(InitializationState *state, QSGCanvas *c)
2031 removeFromDirtyList();
2032 QSGCanvasPrivate *c = QSGCanvasPrivate::get(canvas);
2033 if (polishScheduled)
2034 c->itemsToPolish.remove(q);
2035 if (c->mouseGrabberItem == q)
2036 c->mouseGrabberItem = 0;
2038 c->hoverItems.removeAll(q);
2039 if (itemNodeInstance)
2040 c->cleanup(itemNodeInstance);
2045 if (canvas && polishScheduled)
2046 QSGCanvasPrivate::get(canvas)->itemsToPolish.insert(q);
2048 itemNodeInstance = 0;
2054 beforePaintNode = 0;
2056 InitializationState _dummy;
2057 InitializationState *childState = state;
2059 if (c && q->isFocusScope()) {
2061 childState = &_dummy;
2064 for (int ii = 0; ii < childItems.count(); ++ii) {
2065 QSGItem *child = childItems.at(ii);
2066 QSGItemPrivate::get(child)->initCanvas(childState, c);
2071 if (state->getFocusScope(q)->scopedFocusItem()) {
2073 emit q->focusChanged(false);
2075 QSGCanvasPrivate::get(canvas)->setFocusInScope(state->getFocusScope(q), q);
2081 itemChange(QSGItem::ItemSceneChange, c);
2085 Returns a transform that maps points from canvas space into item space.
2087 QTransform QSGItemPrivate::canvasToItemTransform() const
2089 // XXX todo - optimize
2090 return itemToCanvasTransform().inverted();
2094 Returns a transform that maps points from item space into canvas space.
2096 QTransform QSGItemPrivate::itemToCanvasTransform() const
2099 QTransform rv = parentItem?QSGItemPrivate::get(parentItem)->itemToCanvasTransform():QTransform();
2100 itemToParentTransform(rv);
2105 Motifies \a t with this items local transform relative to its parent.
2107 void QSGItemPrivate::itemToParentTransform(QTransform &t) const
2112 if (!transforms.isEmpty()) {
2114 for (int ii = transforms.count() - 1; ii >= 0; --ii)
2115 transforms.at(ii)->applyTo(&m);
2116 t = m.toTransform();
2119 if (scale != 1. || rotation != 0.) {
2120 QPointF tp = computeTransformOrigin();
2121 t.translate(tp.x(), tp.y());
2122 t.scale(scale, scale);
2124 t.translate(-tp.x(), -tp.y());
2130 \qmlproperty real QtQuick2::Item::childrenRect.x
2131 \qmlproperty real QtQuick2::Item::childrenRect.y
2132 \qmlproperty real QtQuick2::Item::childrenRect.width
2133 \qmlproperty real QtQuick2::Item::childrenRect.height
2135 The childrenRect properties allow an item access to the geometry of its
2136 children. This property is useful if you have an item that needs to be
2137 sized to fit its children.
2142 \qmlproperty list<Item> QtQuick2::Item::children
2143 \qmlproperty list<Object> QtQuick2::Item::resources
2145 The children property contains the list of visual children of this item.
2146 The resources property contains non-visual resources that you want to
2149 Generally you can rely on Item's default property to handle all this for
2150 you, but it can come in handy in some cases.
2169 Returns true if construction of the QML component is complete; otherwise
2172 It is often desirable to delay some processing until the component is
2175 \sa componentComplete()
2177 bool QSGItem::isComponentComplete() const
2180 return d->componentComplete;
2183 QSGItemPrivate::QSGItemPrivate()
2184 : _anchors(0), _contents(0), baselineOffset(0), _anchorLines(0), _stateGroup(0), origin(QSGItem::Center),
2186 flags(0), widthValid(false), heightValid(false), componentComplete(true),
2187 keepMouse(false), hoverEnabled(false), smooth(false), focus(false), activeFocus(false), notifiedFocus(false),
2188 notifiedActiveFocus(false), filtersChildMouseEvents(false), explicitVisible(true),
2189 effectiveVisible(true), explicitEnable(true), effectiveEnable(true), polishScheduled(false),
2190 inheritedLayoutMirror(false), effectiveLayoutMirror(false), isMirrorImplicit(true),
2191 inheritMirrorFromParent(false), inheritMirrorFromItem(false), childrenDoNotOverlap(false),
2193 canvas(0), parentItem(0),
2197 x(0), y(0), width(0), height(0), implicitWidth(0), implicitHeight(0),
2198 z(0), scale(1), rotation(0), opacity(1),
2200 attachedLayoutDirection(0), acceptedMouseButtons(0),
2201 imHints(Qt::ImhNone),
2205 dirtyAttributes(0), nextDirtyItem(0), prevDirtyItem(0),
2207 itemNodeInstance(0), opacityNode(0), clipNode(0), rootNode(0), groupNode(0), paintNode(0)
2208 , beforePaintNode(0), effectRefCount(0), hideRefCount(0)
2212 void QSGItemPrivate::init(QSGItem *parent)
2216 static bool atexit_registered = false;
2217 if (!atexit_registered) {
2218 atexit(qt_print_item_count);
2219 atexit_registered = true;
2224 baselineOffset.invalidate();
2227 q->setParentItem(parent);
2228 QSGItemPrivate *parentPrivate = QSGItemPrivate::get(parent);
2229 setImplicitLayoutMirror(parentPrivate->inheritedLayoutMirror, parentPrivate->inheritMirrorFromParent);
2233 void QSGItemPrivate::data_append(QDeclarativeListProperty<QObject> *prop, QObject *o)
2238 QSGItem *that = static_cast<QSGItem *>(prop->object);
2240 // This test is measurably (albeit only slightly) faster than qobject_cast<>()
2241 const QMetaObject *mo = o->metaObject();
2242 while (mo && mo != &QSGItem::staticMetaObject) {
2243 if (mo == &QGraphicsObject::staticMetaObject)
2244 qWarning("Cannot add a QtQuick 1.0 item (%s) into a QtQuick 2.0 scene!", o->metaObject()->className());
2245 mo = mo->d.superdata;
2249 QSGItem *item = static_cast<QSGItem *>(o);
2250 item->setParentItem(that);
2252 // XXX todo - do we really want this behavior?
2258 \qmlproperty list<Object> QtQuick2::Item::data
2261 The data property allows you to freely mix visual children and resources
2262 in an item. If you assign a visual item to the data list it becomes
2263 a child and if you assign any other object type, it is added as a resource.
2287 data is a behind-the-scenes property: you should never need to explicitly
2291 int QSGItemPrivate::data_count(QDeclarativeListProperty<QObject> *prop)
2298 QObject *QSGItemPrivate::data_at(QDeclarativeListProperty<QObject> *prop, int i)
2306 void QSGItemPrivate::data_clear(QDeclarativeListProperty<QObject> *prop)
2312 QObject *QSGItemPrivate::resources_at(QDeclarativeListProperty<QObject> *prop, int index)
2314 const QObjectList children = prop->object->children();
2315 if (index < children.count())
2316 return children.at(index);
2321 void QSGItemPrivate::resources_append(QDeclarativeListProperty<QObject> *prop, QObject *o)
2323 // XXX todo - do we really want this behavior?
2324 o->setParent(prop->object);
2327 int QSGItemPrivate::resources_count(QDeclarativeListProperty<QObject> *prop)
2329 return prop->object->children().count();
2332 void QSGItemPrivate::resources_clear(QDeclarativeListProperty<QObject> *prop)
2334 // XXX todo - do we really want this behavior?
2335 const QObjectList children = prop->object->children();
2336 for (int index = 0; index < children.count(); index++)
2337 children.at(index)->setParent(0);
2340 QSGItem *QSGItemPrivate::children_at(QDeclarativeListProperty<QSGItem> *prop, int index)
2342 QSGItemPrivate *p = QSGItemPrivate::get(static_cast<QSGItem *>(prop->object));
2343 if (index >= p->childItems.count() || index < 0)
2346 return p->childItems.at(index);
2349 void QSGItemPrivate::children_append(QDeclarativeListProperty<QSGItem> *prop, QSGItem *o)
2354 QSGItem *that = static_cast<QSGItem *>(prop->object);
2355 if (o->parentItem() == that)
2356 o->setParentItem(0);
2358 o->setParentItem(that);
2361 int QSGItemPrivate::children_count(QDeclarativeListProperty<QSGItem> *prop)
2363 QSGItemPrivate *p = QSGItemPrivate::get(static_cast<QSGItem *>(prop->object));
2364 return p->childItems.count();
2367 void QSGItemPrivate::children_clear(QDeclarativeListProperty<QSGItem> *prop)
2369 QSGItem *that = static_cast<QSGItem *>(prop->object);
2370 QSGItemPrivate *p = QSGItemPrivate::get(that);
2371 while (!p->childItems.isEmpty())
2372 p->childItems.at(0)->setParentItem(0);
2375 int QSGItemPrivate::transform_count(QDeclarativeListProperty<QSGTransform> *prop)
2377 QSGItem *that = static_cast<QSGItem *>(prop->object);
2378 return QSGItemPrivate::get(that)->transforms.count();
2381 void QSGTransform::appendToItem(QSGItem *item)
2387 QSGItemPrivate *p = QSGItemPrivate::get(item);
2389 if (!d->items.isEmpty() && !p->transforms.isEmpty() && p->transforms.contains(this)) {
2390 p->transforms.removeOne(this);
2391 p->transforms.append(this);
2393 p->transforms.append(this);
2394 d->items.append(item);
2397 p->dirty(QSGItemPrivate::Transform);
2400 void QSGTransform::prependToItem(QSGItem *item)
2406 QSGItemPrivate *p = QSGItemPrivate::get(item);
2408 if (!d->items.isEmpty() && !p->transforms.isEmpty() && p->transforms.contains(this)) {
2409 p->transforms.removeOne(this);
2410 p->transforms.prepend(this);
2412 p->transforms.prepend(this);
2413 d->items.append(item);
2416 p->dirty(QSGItemPrivate::Transform);
2419 void QSGItemPrivate::transform_append(QDeclarativeListProperty<QSGTransform> *prop, QSGTransform *transform)
2424 QSGItem *that = static_cast<QSGItem *>(prop->object);
2425 transform->appendToItem(that);
2428 QSGTransform *QSGItemPrivate::transform_at(QDeclarativeListProperty<QSGTransform> *prop, int idx)
2430 QSGItem *that = static_cast<QSGItem *>(prop->object);
2431 QSGItemPrivate *p = QSGItemPrivate::get(that);
2433 if (idx < 0 || idx >= p->transforms.count())
2436 return p->transforms.at(idx);
2439 void QSGItemPrivate::transform_clear(QDeclarativeListProperty<QSGTransform> *prop)
2441 QSGItem *that = static_cast<QSGItem *>(prop->object);
2442 QSGItemPrivate *p = QSGItemPrivate::get(that);
2444 for (int ii = 0; ii < p->transforms.count(); ++ii) {
2445 QSGTransform *t = p->transforms.at(ii);
2446 QSGTransformPrivate *tp = QSGTransformPrivate::get(t);
2447 tp->items.removeOne(that);
2450 p->transforms.clear();
2452 p->dirty(QSGItemPrivate::Transform);
2456 \property QSGItem::childrenRect
2457 \brief The geometry of an item's children.
2459 This property holds the (collective) position and size of the item's children.
2463 \qmlproperty real QtQuick2::Item::x
2464 \qmlproperty real QtQuick2::Item::y
2465 \qmlproperty real QtQuick2::Item::width
2466 \qmlproperty real QtQuick2::Item::height
2468 Defines the item's position and size relative to its parent.
2471 Item { x: 100; y: 100; width: 100; height: 100 }
2476 \qmlproperty real QtQuick2::Item::z
2478 Sets the stacking order of sibling items. By default the stacking order is 0.
2480 Items with a higher stacking value are drawn on top of siblings with a
2481 lower stacking order. Items with the same stacking value are drawn
2482 bottom up in the order they appear. Items with a negative stacking
2483 value are drawn under their parent's content.
2485 The following example shows the various effects of stacking order.
2489 \o \image declarative-item_stacking1.png
2490 \o Same \c z - later children above earlier children:
2495 width: 100; height: 100
2499 x: 50; y: 50; width: 100; height: 100
2504 \o \image declarative-item_stacking2.png
2505 \o Higher \c z on top:
2511 width: 100; height: 100
2515 x: 50; y: 50; width: 100; height: 100
2520 \o \image declarative-item_stacking3.png
2521 \o Same \c z - children above parents:
2526 width: 100; height: 100
2529 x: 50; y: 50; width: 100; height: 100
2535 \o \image declarative-item_stacking4.png
2536 \o Lower \c z below:
2541 width: 100; height: 100
2545 x: 50; y: 50; width: 100; height: 100
2554 \qmlproperty bool QtQuick2::Item::visible
2556 This property holds whether the item is visible. By default this is true.
2558 Setting this property directly affects the \c visible value of child
2559 items. When set to \c false, the \c visible values of all child items also
2560 become \c false. When set to \c true, the \c visible values of child items
2561 are returned to \c true, unless they have explicitly been set to \c false.
2563 (Because of this flow-on behavior, using the \c visible property may not
2564 have the intended effect if a property binding should only respond to
2565 explicit property changes. In such cases it may be better to use the
2566 \l opacity property instead.)
2568 Setting this property to \c false automatically causes \l focus to be set
2569 to \c false, and this item will longer receive mouse and keyboard events.
2570 (In contrast, setting the \l opacity to 0 does not affect the \l focus
2571 property and the receiving of key events.)
2573 \note This property's value is only affected by changes to this property or
2574 the parent's \c visible property. It does not change, for example, if this
2575 item moves off-screen, or if the \l opacity changes to 0.
2580 \qmlproperty AnchorLine QtQuick2::Item::anchors.top
2581 \qmlproperty AnchorLine QtQuick2::Item::anchors.bottom
2582 \qmlproperty AnchorLine QtQuick2::Item::anchors.left
2583 \qmlproperty AnchorLine QtQuick2::Item::anchors.right
2584 \qmlproperty AnchorLine QtQuick2::Item::anchors.horizontalCenter
2585 \qmlproperty AnchorLine QtQuick2::Item::anchors.verticalCenter
2586 \qmlproperty AnchorLine QtQuick2::Item::anchors.baseline
2588 \qmlproperty Item QtQuick2::Item::anchors.fill
2589 \qmlproperty Item QtQuick2::Item::anchors.centerIn
2591 \qmlproperty real QtQuick2::Item::anchors.margins
2592 \qmlproperty real QtQuick2::Item::anchors.topMargin
2593 \qmlproperty real QtQuick2::Item::anchors.bottomMargin
2594 \qmlproperty real QtQuick2::Item::anchors.leftMargin
2595 \qmlproperty real QtQuick2::Item::anchors.rightMargin
2596 \qmlproperty real QtQuick2::Item::anchors.horizontalCenterOffset
2597 \qmlproperty real QtQuick2::Item::anchors.verticalCenterOffset
2598 \qmlproperty real QtQuick2::Item::anchors.baselineOffset
2600 \qmlproperty bool QtQuick2::Item::anchors.mirrored
2602 Anchors provide a way to position an item by specifying its
2603 relationship with other items.
2605 Margins apply to top, bottom, left, right, and fill anchors.
2606 The \c anchors.margins property can be used to set all of the various margins at once, to the same value.
2607 Note that margins are anchor-specific and are not applied if an item does not
2610 Offsets apply for horizontal center, vertical center, and baseline anchors.
2614 \o \image declarative-anchors_example.png
2615 \o Text anchored to Image, horizontally centered and vertically below, with a margin.
2624 anchors.horizontalCenter: pic.horizontalCenter
2625 anchors.top: pic.bottom
2626 anchors.topMargin: 5
2632 \o \image declarative-anchors_example2.png
2634 Left of Text anchored to right of Image, with a margin. The y
2635 property of both defaults to 0.
2645 anchors.left: pic.right
2646 anchors.leftMargin: 5
2653 \c anchors.fill provides a convenient way for one item to have the
2654 same geometry as another item, and is equivalent to connecting all
2655 four directional anchors.
2657 To clear an anchor value, set it to \c undefined.
2659 \c anchors.mirrored returns true it the layout has been \l {LayoutMirroring}{mirrored}.
2661 \note You can only anchor an item to siblings or a parent.
2663 For more information see \l {anchor-layout}{Anchor Layouts}.
2667 \property QSGItem::baselineOffset
2668 \brief The position of the item's baseline in local coordinates.
2670 The baseline of a \l Text item is the imaginary line on which the text
2671 sits. Controls containing text usually set their baseline to the
2672 baseline of their text.
2674 For non-text items, a default baseline offset of 0 is used.
2676 QSGAnchors *QSGItemPrivate::anchors() const
2680 _anchors = new QSGAnchors(const_cast<QSGItem *>(q));
2681 if (!componentComplete)
2682 _anchors->classBegin();
2687 QSGItemPrivate::AnchorLines *QSGItemPrivate::anchorLines() const
2690 if (!_anchorLines) _anchorLines =
2691 new AnchorLines(const_cast<QSGItem *>(q));
2692 return _anchorLines;
2695 void QSGItemPrivate::siblingOrderChanged()
2698 for(int ii = 0; ii < changeListeners.count(); ++ii) {
2699 const QSGItemPrivate::ChangeListener &change = changeListeners.at(ii);
2700 if (change.types & QSGItemPrivate::SiblingOrder) {
2701 change.listener->itemSiblingOrderChanged(q);
2706 QDeclarativeListProperty<QObject> QSGItemPrivate::data()
2708 return QDeclarativeListProperty<QObject>(q_func(), 0, QSGItemPrivate::data_append,
2709 QSGItemPrivate::data_count,
2710 QSGItemPrivate::data_at,
2711 QSGItemPrivate::data_clear);
2714 QRectF QSGItem::childrenRect()
2717 if (!d->_contents) {
2718 d->_contents = new QSGContents(this);
2719 if (d->componentComplete)
2720 d->_contents->complete();
2722 return d->_contents->rectF();
2725 QList<QSGItem *> QSGItem::childItems() const
2728 return d->childItems;
2731 bool QSGItem::clip() const
2733 return flags() & ItemClipsChildrenToShape;
2736 void QSGItem::setClip(bool c)
2741 setFlag(ItemClipsChildrenToShape, c);
2743 emit clipChanged(c);
2748 This function is called to handle this item's changes in
2749 geometry from \a oldGeometry to \a newGeometry. If the two
2750 geometries are the same, it doesn't do anything.
2752 void QSGItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
2757 QSGAnchorsPrivate::get(d->_anchors)->updateMe();
2759 for(int ii = 0; ii < d->changeListeners.count(); ++ii) {
2760 const QSGItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
2761 if (change.types & QSGItemPrivate::Geometry)
2762 change.listener->itemGeometryChanged(this, newGeometry, oldGeometry);
2765 if (newGeometry.x() != oldGeometry.x())
2767 if (newGeometry.y() != oldGeometry.y())
2769 if (newGeometry.width() != oldGeometry.width())
2770 emit widthChanged();
2771 if (newGeometry.height() != oldGeometry.height())
2772 emit heightChanged();
2776 Called by the rendering thread when it is time to sync the state of the QML objects with the
2777 scene graph objects. The function should return the root of the scene graph subtree for
2778 this item. \a oldNode is the node that was returned the last time the function was called.
2780 The main thread is blocked while this function is executed so it is safe to read
2781 values from the QSGItem instance and other objects in the main thread.
2783 \warning This is the only function in which it is allowed to make use of scene graph
2784 objects from the main thread. Use of scene graph objects outside this function will
2785 result in race conditions and potential crashes.
2788 QSGNode *QSGItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
2794 QSGTransformNode *QSGItemPrivate::createTransformNode()
2796 return new QSGTransformNode;
2799 void QSGItem::updatePolish()
2803 void QSGItemPrivate::removeItemChangeListener(QSGItemChangeListener *listener, ChangeTypes types)
2805 ChangeListener change(listener, types);
2806 changeListeners.removeOne(change);
2809 void QSGItem::keyPressEvent(QKeyEvent *event)
2814 void QSGItem::keyReleaseEvent(QKeyEvent *event)
2819 void QSGItem::inputMethodEvent(QInputMethodEvent *event)
2824 void QSGItem::focusInEvent(QFocusEvent *)
2828 void QSGItem::focusOutEvent(QFocusEvent *)
2832 void QSGItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
2837 void QSGItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
2842 void QSGItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
2847 void QSGItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
2849 mousePressEvent(event);
2852 void QSGItem::mouseUngrabEvent()
2857 void QSGItem::wheelEvent(QWheelEvent *event)
2862 void QSGItem::touchEvent(QTouchEvent *event)
2867 void QSGItem::hoverEnterEvent(QHoverEvent *event)
2872 void QSGItem::hoverMoveEvent(QHoverEvent *event)
2877 void QSGItem::hoverLeaveEvent(QHoverEvent *event)
2882 void QSGItem::dragMoveEvent(QSGDragEvent *event)
2884 event->setAccepted(false);
2887 void QSGItem::dragEnterEvent(QSGDragEvent *event)
2889 event->setAccepted(false);
2892 void QSGItem::dragExitEvent(QSGDragEvent *event)
2894 event->setAccepted(false);
2897 void QSGItem::dragDropEvent(QSGDragEvent *event)
2899 event->setAccepted(false);
2902 bool QSGItem::childMouseEventFilter(QSGItem *, QEvent *)
2907 void QSGItem::windowDeactivateEvent()
2909 foreach (QSGItem* item, childItems()) {
2910 item->windowDeactivateEvent();
2914 Qt::InputMethodHints QSGItem::inputMethodHints() const
2920 void QSGItem::setInputMethodHints(Qt::InputMethodHints hints)
2925 if (!d->canvas || d->canvas->activeFocusItem() != this)
2928 QSGCanvasPrivate *cd = QSGCanvasPrivate::get(d->canvas);
2929 cd->updateInputMethodData();
2931 cd->updateInputContext();
2935 void QSGItem::updateMicroFocus()
2940 QSGCanvasPrivate::get(d->canvas)->updateInputContext();
2944 QVariant QSGItem::inputMethodQuery(Qt::InputMethodQuery query) const
2950 v = d->keyHandler->inputMethodQuery(query);
2955 QSGAnchorLine QSGItemPrivate::left() const
2957 return anchorLines()->left;
2960 QSGAnchorLine QSGItemPrivate::right() const
2962 return anchorLines()->right;
2965 QSGAnchorLine QSGItemPrivate::horizontalCenter() const
2967 return anchorLines()->hCenter;
2970 QSGAnchorLine QSGItemPrivate::top() const
2972 return anchorLines()->top;
2975 QSGAnchorLine QSGItemPrivate::bottom() const
2977 return anchorLines()->bottom;
2980 QSGAnchorLine QSGItemPrivate::verticalCenter() const
2982 return anchorLines()->vCenter;
2985 QSGAnchorLine QSGItemPrivate::baseline() const
2987 return anchorLines()->baseline;
2990 qreal QSGItem::baselineOffset() const
2993 if (!d->baselineOffset.isValid()) {
2996 return d->baselineOffset;
2999 void QSGItem::setBaselineOffset(qreal offset)
3002 if (offset == d->baselineOffset)
3005 d->baselineOffset = offset;
3007 for(int ii = 0; ii < d->changeListeners.count(); ++ii) {
3008 const QSGItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
3009 if (change.types & QSGItemPrivate::Geometry) {
3010 QSGAnchorsPrivate *anchor = change.listener->anchorPrivate();
3012 anchor->updateVerticalAnchors();
3015 emit baselineOffsetChanged(offset);
3018 void QSGItem::update()
3021 Q_ASSERT(flags() & ItemHasContents);
3022 d->dirty(QSGItemPrivate::Content);
3025 void QSGItem::polish()
3028 if (!d->polishScheduled) {
3029 d->polishScheduled = true;
3031 QSGCanvasPrivate *p = QSGCanvasPrivate::get(d->canvas);
3032 bool maybeupdate = p->itemsToPolish.isEmpty();
3033 p->itemsToPolish.insert(this);
3034 if (maybeupdate) d->canvas->maybeUpdate();
3039 void QSGItem::mapFromItem(QDeclarativeV8Function *args) const
3041 if (args->Length() != 0) {
3042 v8::Local<v8::Value> item = (*args)[0];
3043 QV8Engine *engine = args->engine();
3045 QSGItem *itemObj = 0;
3046 if (!item->IsNull())
3047 itemObj = qobject_cast<QSGItem*>(engine->toQObject(item));
3049 if (!itemObj && !item->IsNull()) {
3050 qmlInfo(this) << "mapFromItem() given argument \"" << engine->toString(item->ToString())
3051 << "\" which is neither null nor an Item";
3055 v8::Local<v8::Object> rv = v8::Object::New();
3056 args->returnValue(rv);
3058 qreal x = (args->Length() > 1)?(*args)[1]->NumberValue():0;
3059 qreal y = (args->Length() > 2)?(*args)[2]->NumberValue():0;
3061 QPointF p = mapFromItem(itemObj, QPointF(x, y));
3063 rv->Set(v8::String::New("x"), v8::Number::New(p.x()));
3064 rv->Set(v8::String::New("y"), v8::Number::New(p.y()));
3068 QTransform QSGItem::itemTransform(QSGItem *other, bool *ok) const
3072 // XXX todo - we need to be able to handle common parents better and detect
3076 QTransform t = d->itemToCanvasTransform();
3077 if (other) t *= QSGItemPrivate::get(other)->canvasToItemTransform();
3082 void QSGItem::mapToItem(QDeclarativeV8Function *args) const
3084 if (args->Length() != 0) {
3085 v8::Local<v8::Value> item = (*args)[0];
3086 QV8Engine *engine = args->engine();
3088 QSGItem *itemObj = 0;
3089 if (!item->IsNull())
3090 itemObj = qobject_cast<QSGItem*>(engine->toQObject(item));
3092 if (!itemObj && !item->IsNull()) {
3093 qmlInfo(this) << "mapToItem() given argument \"" << engine->toString(item->ToString())
3094 << "\" which is neither null nor an Item";
3098 v8::Local<v8::Object> rv = v8::Object::New();
3099 args->returnValue(rv);
3101 qreal x = (args->Length() > 1)?(*args)[1]->NumberValue():0;
3102 qreal y = (args->Length() > 2)?(*args)[2]->NumberValue():0;
3104 QPointF p = mapToItem(itemObj, QPointF(x, y));
3106 rv->Set(v8::String::New("x"), v8::Number::New(p.x()));
3107 rv->Set(v8::String::New("y"), v8::Number::New(p.y()));
3111 void QSGItem::forceActiveFocus()
3114 QSGItem *parent = parentItem();
3116 if (parent->flags() & QSGItem::ItemIsFocusScope) {
3117 parent->setFocus(true);
3119 parent = parent->parentItem();
3123 QSGItem *QSGItem::childAt(qreal x, qreal y) const
3125 // XXX todo - should this include transform etc.?
3126 const QList<QSGItem *> children = childItems();
3127 for (int i = children.count()-1; i >= 0; --i) {
3128 QSGItem *child = children.at(i);
3129 if (child->isVisible() && child->x() <= x
3130 && child->x() + child->width() >= x
3132 && child->y() + child->height() >= y)
3138 QDeclarativeListProperty<QObject> QSGItemPrivate::resources()
3140 return QDeclarativeListProperty<QObject>(q_func(), 0, QSGItemPrivate::resources_append,
3141 QSGItemPrivate::resources_count,
3142 QSGItemPrivate::resources_at,
3143 QSGItemPrivate::resources_clear);
3146 QDeclarativeListProperty<QSGItem> QSGItemPrivate::children()
3148 return QDeclarativeListProperty<QSGItem>(q_func(), 0, QSGItemPrivate::children_append,
3149 QSGItemPrivate::children_count,
3150 QSGItemPrivate::children_at,
3151 QSGItemPrivate::children_clear);
3155 QDeclarativeListProperty<QDeclarativeState> QSGItemPrivate::states()
3157 return _states()->statesProperty();
3160 QDeclarativeListProperty<QDeclarativeTransition> QSGItemPrivate::transitions()
3162 return _states()->transitionsProperty();
3165 QString QSGItemPrivate::state() const
3170 return _stateGroup->state();
3173 void QSGItemPrivate::setState(const QString &state)
3175 _states()->setState(state);
3178 QDeclarativeListProperty<QSGTransform> QSGItem::transform()
3181 return QDeclarativeListProperty<QSGTransform>(this, 0, d->transform_append, d->transform_count,
3182 d->transform_at, d->transform_clear);
3185 void QSGItem::classBegin()
3188 d->componentComplete = false;
3190 d->_stateGroup->classBegin();
3192 d->_anchors->classBegin();
3195 void QSGItem::componentComplete()
3198 d->componentComplete = true;
3200 d->_stateGroup->componentComplete();
3202 d->_anchors->componentComplete();
3203 QSGAnchorsPrivate::get(d->_anchors)->updateOnComplete();
3206 d->keyHandler->componentComplete();
3208 d->_contents->complete();
3211 QDeclarativeStateGroup *QSGItemPrivate::_states()
3215 _stateGroup = new QDeclarativeStateGroup;
3216 if (!componentComplete)
3217 _stateGroup->classBegin();
3218 QObject::connect(_stateGroup, SIGNAL(stateChanged(QString)),
3219 q, SIGNAL(stateChanged(QString)));
3225 QSGItemPrivate::AnchorLines::AnchorLines(QSGItem *q)
3228 left.anchorLine = QSGAnchorLine::Left;
3230 right.anchorLine = QSGAnchorLine::Right;
3232 hCenter.anchorLine = QSGAnchorLine::HCenter;
3234 top.anchorLine = QSGAnchorLine::Top;
3236 bottom.anchorLine = QSGAnchorLine::Bottom;
3238 vCenter.anchorLine = QSGAnchorLine::VCenter;
3240 baseline.anchorLine = QSGAnchorLine::Baseline;
3243 QPointF QSGItemPrivate::computeTransformOrigin() const
3247 case QSGItem::TopLeft:
3248 return QPointF(0, 0);
3250 return QPointF(width / 2., 0);
3251 case QSGItem::TopRight:
3252 return QPointF(width, 0);
3254 return QPointF(0, height / 2.);
3255 case QSGItem::Center:
3256 return QPointF(width / 2., height / 2.);
3257 case QSGItem::Right:
3258 return QPointF(width, height / 2.);
3259 case QSGItem::BottomLeft:
3260 return QPointF(0, height);
3261 case QSGItem::Bottom:
3262 return QPointF(width / 2., height);
3263 case QSGItem::BottomRight:
3264 return QPointF(width, height);
3268 void QSGItemPrivate::transformChanged()
3272 void QSGItemPrivate::deliverKeyEvent(QKeyEvent *e)
3276 Q_ASSERT(e->isAccepted());
3278 if (e->type() == QEvent::KeyPress)
3279 keyHandler->keyPressed(e, false);
3281 keyHandler->keyReleased(e, false);
3283 if (e->isAccepted())
3289 if (e->type() == QEvent::KeyPress)
3290 q->keyPressEvent(e);
3292 q->keyReleaseEvent(e);
3294 if (e->isAccepted())
3300 if (e->type() == QEvent::KeyPress)
3301 keyHandler->keyPressed(e, true);
3303 keyHandler->keyReleased(e, true);
3307 void QSGItemPrivate::deliverInputMethodEvent(QInputMethodEvent *e)
3311 Q_ASSERT(e->isAccepted());
3313 keyHandler->inputMethodEvent(e, false);
3315 if (e->isAccepted())
3321 q->inputMethodEvent(e);
3323 if (e->isAccepted())
3329 keyHandler->inputMethodEvent(e, true);
3333 void QSGItemPrivate::deliverFocusEvent(QFocusEvent *e)
3337 if (e->type() == QEvent::FocusIn) {
3340 q->focusOutEvent(e);
3344 void QSGItemPrivate::deliverMouseEvent(QGraphicsSceneMouseEvent *e)
3348 Q_ASSERT(e->isAccepted());
3352 Q_ASSERT(!"Unknown event type");
3353 case QEvent::GraphicsSceneMouseMove:
3354 q->mouseMoveEvent(e);
3356 case QEvent::GraphicsSceneMousePress:
3357 q->mousePressEvent(e);
3359 case QEvent::GraphicsSceneMouseRelease:
3360 q->mouseReleaseEvent(e);
3362 case QEvent::GraphicsSceneMouseDoubleClick:
3363 q->mouseDoubleClickEvent(e);
3368 void QSGItemPrivate::deliverWheelEvent(QWheelEvent *e)
3374 void QSGItemPrivate::deliverTouchEvent(QTouchEvent *e)
3380 void QSGItemPrivate::deliverHoverEvent(QHoverEvent *e)
3385 Q_ASSERT(!"Unknown event type");
3386 case QEvent::HoverEnter:
3387 q->hoverEnterEvent(e);
3389 case QEvent::HoverLeave:
3390 q->hoverLeaveEvent(e);
3392 case QEvent::HoverMove:
3393 q->hoverMoveEvent(e);
3398 void QSGItemPrivate::deliverDragEvent(QSGDragEvent *e)
3401 switch (e->type()) {
3403 Q_ASSERT(!"Unknown event type");
3404 case QSGEvent::SGDragEnter:
3405 q->dragEnterEvent(e);
3407 case QSGEvent::SGDragExit:
3408 q->dragExitEvent(e);
3410 case QSGEvent::SGDragMove:
3411 q->dragMoveEvent(e);
3413 case QSGEvent::SGDragDrop:
3414 q->dragDropEvent(e);
3419 void QSGItem::itemChange(ItemChange change, const ItemChangeData &value)
3426 // XXX todo - do we want/need this anymore?
3427 // Note that it's now used for varying clip rect
3428 QRectF QSGItem::boundingRect() const
3431 return QRectF(0, 0, d->width, d->height);
3434 QSGItem::TransformOrigin QSGItem::transformOrigin() const
3440 void QSGItem::setTransformOrigin(TransformOrigin origin)
3443 if (origin == d->origin)
3447 d->dirty(QSGItemPrivate::TransformOrigin);
3449 emit transformOriginChanged(d->origin);
3452 QPointF QSGItem::transformOriginPoint() const
3455 return d->computeTransformOrigin();
3458 qreal QSGItem::z() const
3464 void QSGItem::setZ(qreal v)
3472 d->dirty(QSGItemPrivate::ZValue);
3474 QSGItemPrivate::get(d->parentItem)->dirty(QSGItemPrivate::ChildrenStackingChanged);
3481 \qmlproperty real QtQuick2::Item::rotation
3482 This property holds the rotation of the item in degrees clockwise.
3484 This specifies how many degrees to rotate the item around its transformOrigin.
3485 The default rotation is 0 degrees (i.e. not rotated at all).
3489 \o \image declarative-rotation.png
3494 width: 100; height: 100
3497 x: 25; y: 25; width: 50; height: 50
3504 \sa transform, Rotation
3508 \qmlproperty real QtQuick2::Item::scale
3509 This property holds the scale of the item.
3511 A scale of less than 1 means the item will be displayed smaller than
3512 normal, and a scale of greater than 1 means the item will be
3513 displayed larger than normal. A negative scale means the item will
3516 By default, items are displayed at a scale of 1 (i.e. at their
3519 Scaling is from the item's transformOrigin.
3523 \o \image declarative-scale.png
3528 width: 100; height: 100
3531 width: 25; height: 25
3535 x: 25; y: 25; width: 50; height: 50
3542 \sa transform, Scale
3546 \qmlproperty real QtQuick2::Item::opacity
3548 This property holds the opacity of the item. Opacity is specified as a
3549 number between 0 (fully transparent) and 1 (fully opaque). The default is 1.
3551 When this property is set, the specified opacity is also applied
3552 individually to child items. In almost all cases this is what you want,
3553 but in some cases it may produce undesired results. For example in the
3554 second set of rectangles below, the red rectangle has specified an opacity
3555 of 0.5, which affects the opacity of its blue child rectangle even though
3556 the child has not specified an opacity.
3560 \o \image declarative-item_opacity1.png
3566 width: 100; height: 100
3569 x: 50; y: 50; width: 100; height: 100
3575 \o \image declarative-item_opacity2.png
3582 width: 100; height: 100
3585 x: 50; y: 50; width: 100; height: 100
3592 If an item's opacity is set to 0, the item will no longer receive mouse
3593 events, but will continue to receive key events and will retain the keyboard
3594 \l focus if it has been set. (In contrast, setting the \l visible property
3595 to \c false stops both mouse and keyboard events, and also removes focus
3600 Returns a value indicating whether mouse input should
3601 remain with this item exclusively.
3603 \sa setKeepMouseGrab()
3606 qreal QSGItem::rotation() const
3612 void QSGItem::setRotation(qreal r)
3615 if (d->rotation == r)
3620 d->dirty(QSGItemPrivate::BasicTransform);
3622 d->itemChange(ItemRotationHasChanged, r);
3624 emit rotationChanged();
3627 qreal QSGItem::scale() const
3633 void QSGItem::setScale(qreal s)
3641 d->dirty(QSGItemPrivate::BasicTransform);
3643 emit scaleChanged();
3646 qreal QSGItem::opacity() const
3652 void QSGItem::setOpacity(qreal o)
3655 if (d->opacity == o)
3660 d->dirty(QSGItemPrivate::OpacityValue);
3662 d->itemChange(ItemOpacityHasChanged, o);
3664 emit opacityChanged();
3667 bool QSGItem::isVisible() const
3670 return d->effectiveVisible;
3673 void QSGItem::setVisible(bool v)
3676 if (v == d->explicitVisible)
3679 d->explicitVisible = v;
3681 d->setEffectiveVisibleRecur(d->calcEffectiveVisible());
3684 bool QSGItem::isEnabled() const
3687 return d->effectiveEnable;
3690 void QSGItem::setEnabled(bool e)
3693 if (e == d->explicitEnable)
3696 d->explicitEnable = e;
3698 d->setEffectiveEnableRecur(d->calcEffectiveEnable());
3701 bool QSGItemPrivate::calcEffectiveVisible() const
3703 // XXX todo - Should the effective visible of an element with no parent just be the current
3704 // effective visible? This would prevent pointless re-processing in the case of an element
3705 // moving to/from a no-parent situation, but it is different from what graphics view does.
3706 return explicitVisible && (!parentItem || QSGItemPrivate::get(parentItem)->effectiveVisible);
3709 void QSGItemPrivate::setEffectiveVisibleRecur(bool newEffectiveVisible)
3713 if (newEffectiveVisible && !explicitVisible) {
3714 // This item locally overrides visibility
3718 if (newEffectiveVisible == effectiveVisible) {
3719 // No change necessary
3723 effectiveVisible = newEffectiveVisible;
3725 if (parentItem) QSGItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
3728 QSGCanvasPrivate *canvasPriv = QSGCanvasPrivate::get(canvas);
3729 if (canvasPriv->mouseGrabberItem == q)
3733 for (int ii = 0; ii < childItems.count(); ++ii)
3734 QSGItemPrivate::get(childItems.at(ii))->setEffectiveVisibleRecur(newEffectiveVisible);
3736 for(int ii = 0; ii < changeListeners.count(); ++ii) {
3737 const QSGItemPrivate::ChangeListener &change = changeListeners.at(ii);
3738 if (change.types & QSGItemPrivate::Visibility)
3739 change.listener->itemVisibilityChanged(q);
3742 emit q->visibleChanged();
3745 bool QSGItemPrivate::calcEffectiveEnable() const
3747 // XXX todo - Should the effective enable of an element with no parent just be the current
3748 // effective enable? This would prevent pointless re-processing in the case of an element
3749 // moving to/from a no-parent situation, but it is different from what graphics view does.
3750 return explicitEnable && (!parentItem || QSGItemPrivate::get(parentItem)->effectiveEnable);
3753 void QSGItemPrivate::setEffectiveEnableRecur(bool newEffectiveEnable)
3757 // XXX todo - need to fixup focus
3759 if (newEffectiveEnable && !explicitEnable) {
3760 // This item locally overrides enable
3764 if (newEffectiveEnable == effectiveEnable) {
3765 // No change necessary
3769 effectiveEnable = newEffectiveEnable;
3772 QSGCanvasPrivate *canvasPriv = QSGCanvasPrivate::get(canvas);
3773 if (canvasPriv->mouseGrabberItem == q)
3777 for (int ii = 0; ii < childItems.count(); ++ii)
3778 QSGItemPrivate::get(childItems.at(ii))->setEffectiveEnableRecur(newEffectiveEnable);
3780 emit q->enabledChanged();
3783 QString QSGItemPrivate::dirtyToString() const
3785 #define DIRTY_TO_STRING(value) if (dirtyAttributes & value) { \
3786 if (!rv.isEmpty()) \
3787 rv.append(QLatin1String("|")); \
3788 rv.append(QLatin1String(#value)); \
3791 // QString rv = QLatin1String("0x") + QString::number(dirtyAttributes, 16);
3794 DIRTY_TO_STRING(TransformOrigin);
3795 DIRTY_TO_STRING(Transform);
3796 DIRTY_TO_STRING(BasicTransform);
3797 DIRTY_TO_STRING(Position);
3798 DIRTY_TO_STRING(Size);
3799 DIRTY_TO_STRING(ZValue);
3800 DIRTY_TO_STRING(Content);
3801 DIRTY_TO_STRING(Smooth);
3802 DIRTY_TO_STRING(OpacityValue);
3803 DIRTY_TO_STRING(ChildrenChanged);
3804 DIRTY_TO_STRING(ChildrenStackingChanged);
3805 DIRTY_TO_STRING(ParentChanged);
3806 DIRTY_TO_STRING(Clip);
3807 DIRTY_TO_STRING(Canvas);
3808 DIRTY_TO_STRING(EffectReference);
3809 DIRTY_TO_STRING(Visible);
3810 DIRTY_TO_STRING(HideReference);
3815 void QSGItemPrivate::dirty(DirtyType type)
3818 if (type & (TransformOrigin | Transform | BasicTransform | Position | Size))
3821 if (!(dirtyAttributes & type) || (canvas && !prevDirtyItem)) {
3822 dirtyAttributes |= type;
3825 QSGCanvasPrivate::get(canvas)->dirtyItem(q);
3830 void QSGItemPrivate::addToDirtyList()
3835 if (!prevDirtyItem) {
3836 Q_ASSERT(!nextDirtyItem);
3838 QSGCanvasPrivate *p = QSGCanvasPrivate::get(canvas);
3839 nextDirtyItem = p->dirtyItemList;
3840 if (nextDirtyItem) QSGItemPrivate::get(nextDirtyItem)->prevDirtyItem = &nextDirtyItem;
3841 prevDirtyItem = &p->dirtyItemList;
3842 p->dirtyItemList = q;
3845 Q_ASSERT(prevDirtyItem);
3848 void QSGItemPrivate::removeFromDirtyList()
3850 if (prevDirtyItem) {
3851 if (nextDirtyItem) QSGItemPrivate::get(nextDirtyItem)->prevDirtyItem = prevDirtyItem;
3852 *prevDirtyItem = nextDirtyItem;
3856 Q_ASSERT(!prevDirtyItem);
3857 Q_ASSERT(!nextDirtyItem);
3860 void QSGItemPrivate::refFromEffectItem(bool hide)
3863 if (1 == effectRefCount) {
3864 dirty(EffectReference);
3865 if (parentItem) QSGItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
3868 if (++hideRefCount == 1)
3869 dirty(HideReference);
3873 void QSGItemPrivate::derefFromEffectItem(bool unhide)
3875 Q_ASSERT(effectRefCount);
3877 if (0 == effectRefCount) {
3878 dirty(EffectReference);
3879 if (parentItem) QSGItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
3882 if (--hideRefCount == 0)
3883 dirty(HideReference);
3887 void QSGItemPrivate::itemChange(QSGItem::ItemChange change, const QSGItem::ItemChangeData &data)
3891 case QSGItem::ItemChildAddedChange:
3892 q->itemChange(change, data);
3893 if (_contents && componentComplete)
3894 _contents->childAdded(data.item);
3895 for(int ii = 0; ii < changeListeners.count(); ++ii) {
3896 const QSGItemPrivate::ChangeListener &change = changeListeners.at(ii);
3897 if (change.types & QSGItemPrivate::Children) {
3898 change.listener->itemChildAdded(q, data.item);
3902 case QSGItem::ItemChildRemovedChange:
3903 q->itemChange(change, data);
3904 if (_contents && componentComplete)
3905 _contents->childRemoved(data.item);
3906 for(int ii = 0; ii < changeListeners.count(); ++ii) {
3907 const QSGItemPrivate::ChangeListener &change = changeListeners.at(ii);
3908 if (change.types & QSGItemPrivate::Children) {
3909 change.listener->itemChildRemoved(q, data.item);
3913 case QSGItem::ItemSceneChange:
3914 q->itemChange(change, data);
3916 case QSGItem::ItemVisibleHasChanged:
3917 q->itemChange(change, data);
3918 for(int ii = 0; ii < changeListeners.count(); ++ii) {
3919 const QSGItemPrivate::ChangeListener &change = changeListeners.at(ii);
3920 if (change.types & QSGItemPrivate::Visibility) {
3921 change.listener->itemVisibilityChanged(q);
3925 case QSGItem::ItemParentHasChanged:
3926 q->itemChange(change, data);
3927 for(int ii = 0; ii < changeListeners.count(); ++ii) {
3928 const QSGItemPrivate::ChangeListener &change = changeListeners.at(ii);
3929 if (change.types & QSGItemPrivate::Parent) {
3930 change.listener->itemParentChanged(q, data.item);
3934 case QSGItem::ItemOpacityHasChanged:
3935 q->itemChange(change, data);
3936 for(int ii = 0; ii < changeListeners.count(); ++ii) {
3937 const QSGItemPrivate::ChangeListener &change = changeListeners.at(ii);
3938 if (change.types & QSGItemPrivate::Opacity) {
3939 change.listener->itemOpacityChanged(q);
3943 case QSGItem::ItemActiveFocusHasChanged:
3944 q->itemChange(change, data);
3946 case QSGItem::ItemRotationHasChanged:
3947 q->itemChange(change, data);
3948 for(int ii = 0; ii < changeListeners.count(); ++ii) {
3949 const QSGItemPrivate::ChangeListener &change = changeListeners.at(ii);
3950 if (change.types & QSGItemPrivate::Rotation) {
3951 change.listener->itemRotationChanged(q);
3959 \property QSGItem::smooth
3960 \brief whether the item is smoothly transformed.
3962 This property is provided purely for the purpose of optimization. Turning
3963 smooth transforms off is faster, but looks worse; turning smooth
3964 transformations on is slower, but looks better.
3966 By default smooth transformations are off.
3970 Returns true if the item should be drawn with antialiasing and
3971 smooth pixmap filtering, false otherwise.
3973 The default is false.
3977 bool QSGItem::smooth() const
3984 Sets whether the item should be drawn with antialiasing and
3985 smooth pixmap filtering to \a smooth.
3989 void QSGItem::setSmooth(bool smooth)
3992 if (d->smooth == smooth)
3996 d->dirty(QSGItemPrivate::Smooth);
3998 emit smoothChanged(smooth);
4001 QSGItem::Flags QSGItem::flags() const
4004 return (QSGItem::Flags)d->flags;
4007 void QSGItem::setFlag(Flag flag, bool enabled)
4011 setFlags((Flags)(d->flags | (quint32)flag));
4013 setFlags((Flags)(d->flags & ~(quint32)flag));
4016 void QSGItem::setFlags(Flags flags)
4020 if ((flags & ItemIsFocusScope) != (d->flags & ItemIsFocusScope)) {
4021 if (flags & ItemIsFocusScope && !d->childItems.isEmpty() && d->canvas) {
4022 qWarning("QSGItem: Cannot set FocusScope once item has children and is in a canvas.");
4023 flags &= ~ItemIsFocusScope;
4024 } else if (d->flags & ItemIsFocusScope) {
4025 qWarning("QSGItem: Cannot unset FocusScope flag.");
4026 flags |= ItemIsFocusScope;
4030 if ((flags & ItemClipsChildrenToShape ) != (d->flags & ItemClipsChildrenToShape))
4031 d->dirty(QSGItemPrivate::Clip);
4036 qreal QSGItem::x() const
4042 qreal QSGItem::y() const
4048 QPointF QSGItem::pos() const
4051 return QPointF(d->x, d->y);
4054 void QSGItem::setX(qreal v)
4063 d->dirty(QSGItemPrivate::Position);
4065 geometryChanged(QRectF(x(), y(), width(), height()),
4066 QRectF(oldx, y(), width(), height()));
4069 void QSGItem::setY(qreal v)
4078 d->dirty(QSGItemPrivate::Position);
4080 geometryChanged(QRectF(x(), y(), width(), height()),
4081 QRectF(x(), oldy, width(), height()));
4084 void QSGItem::setPos(const QPointF &pos)
4087 if (QPointF(d->x, d->y) == pos)
4096 d->dirty(QSGItemPrivate::Position);
4098 geometryChanged(QRectF(x(), y(), width(), height()),
4099 QRectF(oldx, oldy, width(), height()));
4102 qreal QSGItem::width() const
4108 void QSGItem::setWidth(qreal w)
4114 d->widthValid = true;
4118 qreal oldWidth = d->width;
4121 d->dirty(QSGItemPrivate::Size);
4123 geometryChanged(QRectF(x(), y(), width(), height()),
4124 QRectF(x(), y(), oldWidth, height()));
4127 void QSGItem::resetWidth()
4130 d->widthValid = false;
4131 setImplicitWidth(implicitWidth());
4134 void QSGItemPrivate::implicitWidthChanged()
4137 emit q->implicitWidthChanged();
4140 qreal QSGItemPrivate::getImplicitWidth() const
4142 return implicitWidth;
4145 Returns the width of the item that is implied by other properties that determine the content.
4147 qreal QSGItem::implicitWidth() const
4150 return d->getImplicitWidth();
4154 \qmlproperty real QtQuick2::Item::implicitWidth
4155 \qmlproperty real QtQuick2::Item::implicitHeight
4157 Defines the natural width or height of the Item if no \l width or \l height is specified.
4159 The default implicit size for most items is 0x0, however some elements have an inherent
4160 implicit size which cannot be overridden, e.g. Image, Text.
4162 Setting the implicit size is useful for defining components that have a preferred size
4163 based on their content, for example:
4170 property alias icon: image.source
4171 property alias label: text.text
4172 implicitWidth: text.implicitWidth + image.implicitWidth
4173 implicitHeight: Math.max(text.implicitHeight, image.implicitHeight)
4178 anchors.left: image.right; anchors.right: parent.right
4179 anchors.verticalCenter: parent.verticalCenter
4184 \bold Note: using implicitWidth of Text or TextEdit and setting the width explicitly
4185 incurs a performance penalty as the text must be laid out twice.
4189 Sets the implied width of the item to \a w.
4190 This is the width implied by other properties that determine the content.
4192 void QSGItem::setImplicitWidth(qreal w)
4195 bool changed = w != d->implicitWidth;
4196 d->implicitWidth = w;
4197 if (d->width == w || widthValid()) {
4199 d->implicitWidthChanged();
4203 qreal oldWidth = d->width;
4206 d->dirty(QSGItemPrivate::Size);
4208 geometryChanged(QRectF(x(), y(), width(), height()),
4209 QRectF(x(), y(), oldWidth, height()));
4212 d->implicitWidthChanged();
4216 Returns whether the width property has been set explicitly.
4218 bool QSGItem::widthValid() const
4221 return d->widthValid;
4224 qreal QSGItem::height() const
4230 void QSGItem::setHeight(qreal h)
4236 d->heightValid = true;
4240 qreal oldHeight = d->height;
4243 d->dirty(QSGItemPrivate::Size);
4245 geometryChanged(QRectF(x(), y(), width(), height()),
4246 QRectF(x(), y(), width(), oldHeight));
4249 void QSGItem::resetHeight()
4252 d->heightValid = false;
4253 setImplicitHeight(implicitHeight());
4256 void QSGItemPrivate::implicitHeightChanged()
4259 emit q->implicitHeightChanged();
4262 qreal QSGItemPrivate::getImplicitHeight() const
4264 return implicitHeight;
4268 Returns the height of the item that is implied by other properties that determine the content.
4270 qreal QSGItem::implicitHeight() const
4273 return d->getImplicitHeight();
4278 Sets the implied height of the item to \a h.
4279 This is the height implied by other properties that determine the content.
4281 void QSGItem::setImplicitHeight(qreal h)
4284 bool changed = h != d->implicitHeight;
4285 d->implicitHeight = h;
4286 if (d->height == h || heightValid()) {
4288 d->implicitHeightChanged();
4292 qreal oldHeight = d->height;
4295 d->dirty(QSGItemPrivate::Size);
4297 geometryChanged(QRectF(x(), y(), width(), height()),
4298 QRectF(x(), y(), width(), oldHeight));
4301 d->implicitHeightChanged();
4305 Returns whether the height property has been set explicitly.
4307 bool QSGItem::heightValid() const
4310 return d->heightValid;
4313 void QSGItem::setSize(const QSizeF &size)
4316 d->heightValid = true;
4317 d->widthValid = true;
4319 if (QSizeF(d->width, d->height) == size)
4322 qreal oldHeight = d->height;
4323 qreal oldWidth = d->width;
4324 d->height = size.height();
4325 d->width = size.width();
4327 d->dirty(QSGItemPrivate::Size);
4329 geometryChanged(QRectF(x(), y(), width(), height()),
4330 QRectF(x(), y(), oldWidth, oldHeight));
4333 bool QSGItem::hasActiveFocus() const
4336 return d->activeFocus;
4339 bool QSGItem::hasFocus() const
4345 void QSGItem::setFocus(bool focus)
4348 if (d->focus == focus)
4352 // Need to find our nearest focus scope
4353 QSGItem *scope = parentItem();
4354 while (scope && !scope->isFocusScope())
4355 scope = scope->parentItem();
4357 QSGCanvasPrivate::get(d->canvas)->setFocusInScope(scope, this);
4359 QSGCanvasPrivate::get(d->canvas)->clearFocusInScope(scope, this);
4362 emit focusChanged(focus);
4366 bool QSGItem::isFocusScope() const
4368 return flags() & ItemIsFocusScope;
4371 QSGItem *QSGItem::scopedFocusItem() const
4374 if (!isFocusScope())
4377 return d->subFocusItem;
4381 Qt::MouseButtons QSGItem::acceptedMouseButtons() const
4384 return d->acceptedMouseButtons;
4387 void QSGItem::setAcceptedMouseButtons(Qt::MouseButtons buttons)
4390 d->acceptedMouseButtons = buttons;
4393 bool QSGItem::filtersChildMouseEvents() const
4396 return d->filtersChildMouseEvents;
4399 void QSGItem::setFiltersChildMouseEvents(bool filter)
4402 d->filtersChildMouseEvents = filter;
4405 bool QSGItem::isUnderMouse() const
4411 QPoint cursorPos = QCursor::pos();
4412 if (QRectF(0, 0, width(), height()).contains(mapFromScene(cursorPos))) // ### refactor: d->canvas->mapFromGlobal(cursorPos))))
4417 bool QSGItem::acceptHoverEvents() const
4420 return d->hoverEnabled;
4423 void QSGItem::setAcceptHoverEvents(bool enabled)
4426 d->hoverEnabled = enabled;
4429 void QSGItem::grabMouse()
4434 QSGCanvasPrivate *canvasPriv = QSGCanvasPrivate::get(d->canvas);
4435 if (canvasPriv->mouseGrabberItem == this)
4438 QSGItem *oldGrabber = canvasPriv->mouseGrabberItem;
4439 canvasPriv->mouseGrabberItem = this;
4441 oldGrabber->mouseUngrabEvent();
4444 void QSGItem::ungrabMouse()
4449 QSGCanvasPrivate *canvasPriv = QSGCanvasPrivate::get(d->canvas);
4450 if (canvasPriv->mouseGrabberItem != this) {
4451 qWarning("QSGItem::ungrabMouse(): Item is not the mouse grabber.");
4455 canvasPriv->mouseGrabberItem = 0;
4459 bool QSGItem::keepMouseGrab() const
4462 return d->keepMouse;
4466 The flag indicating whether the mouse should remain
4467 with this item is set to \a keep.
4469 This is useful for items that wish to grab and keep mouse
4470 interaction following a predefined gesture. For example,
4471 an item that is interested in horizontal mouse movement
4472 may set keepMouseGrab to true once a threshold has been
4473 exceeded. Once keepMouseGrab has been set to true, filtering
4474 items will not react to mouse events.
4476 If the item does not indicate that it wishes to retain mouse grab,
4477 a filtering item may steal the grab. For example, Flickable may attempt
4478 to steal a mouse grab if it detects that the user has begun to
4483 void QSGItem::setKeepMouseGrab(bool keep)
4486 d->keepMouse = keep;
4490 \qmlmethod object QtQuick2::Item::mapFromItem(Item item, real x, real y)
4492 Maps the point (\a x, \a y), which is in \a item's coordinate system, to
4493 this item's coordinate system, and returns an object with \c x and \c y
4494 properties matching the mapped cooordinate.
4496 If \a item is a \c null value, this maps the point from the coordinate
4497 system of the root QML view.
4500 \qmlmethod object QtQuick2::Item::mapToItem(Item item, real x, real y)
4502 Maps the point (\a x, \a y), which is in this item's coordinate system, to
4503 \a item's coordinate system, and returns an object with \c x and \c y
4504 properties matching the mapped cooordinate.
4506 If \a item is a \c null value, this maps \a x and \a y to the coordinate
4507 system of the root QML view.
4509 QPointF QSGItem::mapToItem(const QSGItem *item, const QPointF &point) const
4511 QPointF p = mapToScene(point);
4513 p = item->mapFromScene(p);
4517 QPointF QSGItem::mapToScene(const QPointF &point) const
4520 return d->itemToCanvasTransform().map(point);
4523 QRectF QSGItem::mapRectToItem(const QSGItem *item, const QRectF &rect) const
4526 QTransform t = d->itemToCanvasTransform();
4528 t *= QSGItemPrivate::get(item)->canvasToItemTransform();
4529 return t.mapRect(rect);
4532 QRectF QSGItem::mapRectToScene(const QRectF &rect) const
4535 return d->itemToCanvasTransform().mapRect(rect);
4538 QPointF QSGItem::mapFromItem(const QSGItem *item, const QPointF &point) const
4540 QPointF p = item?item->mapToScene(point):point;
4541 return mapFromScene(p);
4544 QPointF QSGItem::mapFromScene(const QPointF &point) const
4547 return d->canvasToItemTransform().map(point);
4550 QRectF QSGItem::mapRectFromItem(const QSGItem *item, const QRectF &rect) const
4553 QTransform t = item?QSGItemPrivate::get(item)->itemToCanvasTransform():QTransform();
4554 t *= d->canvasToItemTransform();
4555 return t.mapRect(rect);
4558 QRectF QSGItem::mapRectFromScene(const QRectF &rect) const
4561 return d->canvasToItemTransform().mapRect(rect);
4566 \qmlmethod QtQuick2::Item::forceActiveFocus()
4568 Forces active focus on the item.
4570 This method sets focus on the item and makes sure that all the focus scopes
4571 higher in the object hierarchy are also given the focus.
4575 Forces active focus on the item.
4577 This method sets focus on the item and makes sure that all the focus scopes
4578 higher in the object hierarchy are also given the focus.
4582 \qmlmethod QtQuick2::Item::childAt(real x, real y)
4584 Returns the visible child item at point (\a x, \a y), which is in this
4585 item's coordinate system, or \c null if there is no such item.
4589 Returns the visible child item at point (\a x, \a y), which is in this
4590 item's coordinate system, or 0 if there is no such item.
4594 \qmlproperty list<State> QtQuick2::Item::states
4595 This property holds a list of states defined by the item.
4611 \sa {qmlstate}{States}
4614 \qmlproperty list<Transition> QtQuick2::Item::transitions
4615 This property holds a list of transitions defined by the item.
4631 \sa {QML Animation and Transitions}{Transitions}
4634 \qmlproperty list<Filter> QtQuick2::Item::filter
4635 This property holds a list of graphical filters to be applied to the item.
4637 \l {Filter}{Filters} include things like \l {Blur}{blurring}
4638 the item, or giving it a \l Reflection. Some
4639 filters may not be available on all canvases; if a filter is not
4640 available on a certain canvas, it will simply not be applied for
4641 that canvas (but the QML will still be considered valid).
4659 \qmlproperty bool QtQuick2::Item::clip
4660 This property holds whether clipping is enabled. The default clip value is \c false.
4662 If clipping is enabled, an item will clip its own painting, as well
4663 as the painting of its children, to its bounding rectangle.
4665 Non-rectangular clipping regions are not supported for performance reasons.
4669 \property QSGItem::clip
4670 This property holds whether clipping is enabled. The default clip value is \c false.
4672 If clipping is enabled, an item will clip its own painting, as well
4673 as the painting of its children, to its bounding rectangle. If you set
4674 clipping during an item's paint operation, remember to re-set it to
4675 prevent clipping the rest of your scene.
4677 Non-rectangular clipping regions are not supported for performance reasons.
4681 \qmlproperty string QtQuick2::Item::state
4683 This property holds the name of the current state of the item.
4685 This property is often used in scripts to change between states. For
4690 if (button.state == 'On')
4691 button.state = 'Off';
4693 button.state = 'On';
4697 If the item is in its base state (i.e. no explicit state has been
4698 set), \c state will be a blank string. Likewise, you can return an
4699 item to its base state by setting its current state to \c ''.
4701 \sa {qmlstates}{States}
4705 \qmlproperty list<Transform> QtQuick2::Item::transform
4706 This property holds the list of transformations to apply.
4708 For more information see \l Transform.
4712 \enum QSGItem::TransformOrigin
4714 Controls the point about which simple transforms like scale apply.
4716 \value TopLeft The top-left corner of the item.
4717 \value Top The center point of the top of the item.
4718 \value TopRight The top-right corner of the item.
4719 \value Left The left most point of the vertical middle.
4720 \value Center The center of the item.
4721 \value Right The right most point of the vertical middle.
4722 \value BottomLeft The bottom-left corner of the item.
4723 \value Bottom The center point of the bottom of the item.
4724 \value BottomRight The bottom-right corner of the item.
4729 \qmlproperty bool QtQuick2::Item::activeFocus
4731 This property indicates whether the item has active focus.
4733 An item with active focus will receive keyboard input,
4734 or is a FocusScope ancestor of the item that will receive keyboard input.
4736 Usually, activeFocus is gained by setting focus on an item and its enclosing
4737 FocusScopes. In the following example \c input will have activeFocus.
4750 \sa focus, {qmlfocus}{Keyboard Focus}
4754 \qmlproperty bool QtQuick2::Item::focus
4755 This property indicates whether the item has focus within the enclosing focus scope. If true, this item
4756 will gain active focus when the enclosing focus scope gains active focus.
4757 In the following example, \c input will be given active focus when \c scope gains active focus.
4770 For the purposes of this property, the scene as a whole is assumed to act like a focus scope.
4771 On a practical level, that means the following QML will give active focus to \c input on startup.
4782 \sa activeFocus, {qmlfocus}{Keyboard Focus}
4787 \property QSGItem::anchors
4792 \property QSGItem::left
4797 \property QSGItem::right
4802 \property QSGItem::horizontalCenter
4807 \property QSGItem::top
4812 \property QSGItem::bottom
4817 \property QSGItem::verticalCenter
4822 \property QSGItem::focus
4827 \property QSGItem::transform
4832 \property QSGItem::transformOrigin
4837 \property QSGItem::activeFocus
4842 \property QSGItem::baseline
4847 \property QSGItem::data
4852 \property QSGItem::resources
4857 \property QSGItem::state
4862 \property QSGItem::states
4867 \property QSGItem::transformOriginPoint
4872 \property QSGItem::transitions
4876 bool QSGItem::event(QEvent *ev)
4878 return QObject::event(ev);
4881 if (ev->type() == QEvent::PolishRequest) {
4883 d->polishScheduled = false;
4887 return QObject::event(ev);
4892 #ifndef QT_NO_DEBUG_STREAM
4893 QDebug operator<<(QDebug debug, QSGItem *item)
4896 debug << "QSGItem(0)";
4900 debug << item->metaObject()->className() << "(this =" << ((void*)item)
4901 << ", name=" << item->objectName()
4902 << ", parent =" << ((void*)item->parentItem())
4903 << ", geometry =" << QRectF(item->pos(), QSizeF(item->width(), item->height()))
4904 << ", z =" << item->z() << ')';
4909 qint64 QSGItemPrivate::consistentTime = -1;
4910 void QSGItemPrivate::setConsistentTime(qint64 t)
4915 class QElapsedTimerConsistentTimeHack
4919 t1 = QSGItemPrivate::consistentTime;
4923 return QSGItemPrivate::consistentTime - t1;
4926 qint64 val = QSGItemPrivate::consistentTime - t1;
4927 t1 = QSGItemPrivate::consistentTime;
4937 void QSGItemPrivate::start(QElapsedTimer &t)
4939 if (QSGItemPrivate::consistentTime == -1)
4942 ((QElapsedTimerConsistentTimeHack*)&t)->start();
4945 qint64 QSGItemPrivate::elapsed(QElapsedTimer &t)
4947 if (QSGItemPrivate::consistentTime == -1)
4950 return ((QElapsedTimerConsistentTimeHack*)&t)->elapsed();
4953 qint64 QSGItemPrivate::restart(QElapsedTimer &t)
4955 if (QSGItemPrivate::consistentTime == -1)
4958 return ((QElapsedTimerConsistentTimeHack*)&t)->restart();
4962 \fn bool QSGItem::isTextureProvider() const
4964 Returns true if this item is a texture provider. The default
4965 implementation returns false.
4967 This function can be called from any thread.
4971 \fn QSGTextureProvider *QSGItem::textureProvider() const
4973 Returns the texture provider for an item. The default implementation
4976 This function may only be called on the rendering thread.
4981 #include <moc_qsgitem.cpp>