1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the QtDeclarative module of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
44 #include "qsgcanvas.h"
45 #include <QtDeclarative/qjsengine.h>
46 #include "qsgcanvas_p.h"
49 #include "qsgevents_p_p.h"
51 #include <QtDeclarative/qdeclarativeengine.h>
52 #include <QtDeclarative/qdeclarativecomponent.h>
53 #include <QtDeclarative/qdeclarativeinfo.h>
54 #include <QtGui/qpen.h>
55 #include <QtGui/qcursor.h>
56 #include <QtGui/qguiapplication.h>
57 #include <QtGui/qinputpanel.h>
58 #include <QtCore/qdebug.h>
59 #include <QtCore/qcoreevent.h>
60 #include <QtCore/qnumeric.h>
62 #include <private/qdeclarativeengine_p.h>
63 #include <private/qdeclarativestategroup_p.h>
64 #include <private/qdeclarativeopenmetaobject_p.h>
65 #include <private/qdeclarativestate_p.h>
66 #include <private/qlistmodelinterface_p.h>
67 #include <private/qsgitem_p.h>
71 // XXX todo Readd parentNotifier for faster parent bindings
72 // XXX todo Check that elements that create items handle memory correctly after visual ownership change
77 \qmlclass Transform QSGTransform
78 \inqmlmodule QtQuick 2
79 \ingroup qml-transform-elements
80 \brief The Transform elements provide a way of building advanced transformations on Items.
82 The Transform element is a base type which cannot be instantiated directly.
83 The following concrete Transform types are available:
91 The Transform elements let you create and control advanced transformations that can be configured
92 independently using specialized properties.
94 You can assign any number of Transform elements to an \l Item. Each Transform is applied in order,
99 \qmlclass Translate QSGTranslate
100 \inqmlmodule QtQuick 2
101 \ingroup qml-transform-elements
102 \brief The Translate object provides a way to move an Item without changing its x or y properties.
104 The Translate object provides independent control over position in addition to the Item's x and y properties.
106 The following example moves the Y axis of the \l Rectangle elements while still allowing the \l Row element
107 to lay the items out as if they had not been transformed:
113 width: 100; height: 100
115 transform: Translate { y: 20 }
118 width: 100; height: 100
120 transform: Translate { y: -20 }
129 \qmlproperty real QtQuick2::Translate::x
131 The translation along the X axis.
135 \qmlproperty real QtQuick2::Translate::y
137 The translation along the Y axis.
141 \qmlclass Scale QSGScale
142 \inqmlmodule QtQuick 2
143 \ingroup qml-transform-elements
144 \brief The Scale element provides a way to scale an Item.
146 The Scale element gives more control over scaling than using \l Item's \l{Item::scale}{scale} property. Specifically,
147 it allows a different scale for the x and y axes, and allows the scale to be relative to an
150 The following example scales the X axis of the Rectangle, relative to its interior point 25, 25:
153 width: 100; height: 100
155 transform: Scale { origin.x: 25; origin.y: 25; xScale: 3}
159 \sa Rotation, Translate
163 \qmlproperty real QtQuick2::Scale::origin.x
164 \qmlproperty real QtQuick2::Scale::origin.y
166 The point that the item is scaled from (i.e., the point that stays fixed relative to the parent as
167 the rest of the item grows). By default the origin is 0, 0.
171 \qmlproperty real QtQuick2::Scale::xScale
173 The scaling factor for the X axis.
177 \qmlproperty real QtQuick2::Scale::yScale
179 The scaling factor for the Y axis.
183 \qmlclass Rotation QSGRotation
184 \inqmlmodule QtQuick 2
185 \ingroup qml-transform-elements
186 \brief The Rotation object provides a way to rotate an Item.
188 The Rotation object gives more control over rotation than using \l Item's \l{Item::rotation}{rotation} property.
189 Specifically, it allows (z axis) rotation to be relative to an arbitrary point.
191 The following example rotates a Rectangle around its interior point 25, 25:
194 width: 100; height: 100
196 transform: Rotation { origin.x: 25; origin.y: 25; angle: 45}
200 Rotation also provides a way to specify 3D-like rotations for Items. For these types of
201 rotations you must specify the axis to rotate around in addition to the origin point.
203 The following example shows various 3D-like rotations applied to an \l Image.
204 \snippet doc/src/snippets/declarative/rotation.qml 0
206 \image axisrotation.png
208 \sa {declarative/ui-components/dialcontrol}{Dial Control example}, {declarative/toys/clocks}{Clocks example}
212 \qmlproperty real QtQuick2::Rotation::origin.x
213 \qmlproperty real QtQuick2::Rotation::origin.y
215 The origin point of the rotation (i.e., the point that stays fixed relative to the parent as
216 the rest of the item rotates). By default the origin is 0, 0.
220 \qmlproperty real QtQuick2::Rotation::axis.x
221 \qmlproperty real QtQuick2::Rotation::axis.y
222 \qmlproperty real QtQuick2::Rotation::axis.z
224 The axis to rotate around. For simple (2D) rotation around a point, you do not need to specify an axis,
225 as the default axis is the z axis (\c{ axis { x: 0; y: 0; z: 1 } }).
227 For a typical 3D-like rotation you will usually specify both the origin and the axis.
229 \image 3d-rotation-axis.png
233 \qmlproperty real QtQuick2::Rotation::angle
235 The angle to rotate, in degrees clockwise.
238 QSGTransformPrivate::QSGTransformPrivate()
242 QSGTransform::QSGTransform(QObject *parent)
243 : QObject(*(new QSGTransformPrivate), parent)
247 QSGTransform::QSGTransform(QSGTransformPrivate &dd, QObject *parent)
248 : QObject(dd, parent)
252 QSGTransform::~QSGTransform()
255 for (int ii = 0; ii < d->items.count(); ++ii) {
256 QSGItemPrivate *p = QSGItemPrivate::get(d->items.at(ii));
257 p->transforms.removeOne(this);
258 p->dirty(QSGItemPrivate::Transform);
262 void QSGTransform::update()
265 for (int ii = 0; ii < d->items.count(); ++ii) {
266 QSGItemPrivate *p = QSGItemPrivate::get(d->items.at(ii));
267 p->dirty(QSGItemPrivate::Transform);
271 QSGContents::QSGContents(QSGItem *item)
272 : m_item(item), m_x(0), m_y(0), m_width(0), m_height(0)
275 connect(this, SIGNAL(rectChanged(QRectF)), m_item, SIGNAL(childrenRectChanged(QRectF)));
278 QSGContents::~QSGContents()
280 QList<QSGItem *> children = m_item->childItems();
281 for (int i = 0; i < children.count(); ++i) {
282 QSGItem *child = children.at(i);
283 QSGItemPrivate::get(child)->removeItemChangeListener(this, QSGItemPrivate::Geometry | QSGItemPrivate::Destroyed);
287 QRectF QSGContents::rectF() const
289 return QRectF(m_x, m_y, m_width, m_height);
292 void QSGContents::calcHeight(QSGItem *changed)
295 qreal oldheight = m_height;
299 qreal bottom = oldy + oldheight;
300 qreal y = changed->y();
301 if (y + changed->height() > bottom)
302 bottom = y + changed->height();
306 m_height = bottom - top;
310 QList<QSGItem *> children = m_item->childItems();
311 for (int i = 0; i < children.count(); ++i) {
312 QSGItem *child = children.at(i);
313 qreal y = child->y();
314 if (y + child->height() > bottom)
315 bottom = y + child->height();
319 if (!children.isEmpty())
321 m_height = qMax(bottom - top, qreal(0.0));
324 if (m_height != oldheight || m_y != oldy)
325 emit rectChanged(rectF());
328 void QSGContents::calcWidth(QSGItem *changed)
331 qreal oldwidth = m_width;
335 qreal right = oldx + oldwidth;
336 qreal x = changed->x();
337 if (x + changed->width() > right)
338 right = x + changed->width();
342 m_width = right - left;
344 qreal left = FLT_MAX;
346 QList<QSGItem *> children = m_item->childItems();
347 for (int i = 0; i < children.count(); ++i) {
348 QSGItem *child = children.at(i);
349 qreal x = child->x();
350 if (x + child->width() > right)
351 right = x + child->width();
355 if (!children.isEmpty())
357 m_width = qMax(right - left, qreal(0.0));
360 if (m_width != oldwidth || m_x != oldx)
361 emit rectChanged(rectF());
364 void QSGContents::complete()
366 QList<QSGItem *> children = m_item->childItems();
367 for (int i = 0; i < children.count(); ++i) {
368 QSGItem *child = children.at(i);
369 QSGItemPrivate::get(child)->addItemChangeListener(this, QSGItemPrivate::Geometry | QSGItemPrivate::Destroyed);
370 //###what about changes to visibility?
376 void QSGContents::itemGeometryChanged(QSGItem *changed, const QRectF &newGeometry, const QRectF &oldGeometry)
379 //### we can only pass changed if the left edge has moved left, or the right edge has moved right
380 if (newGeometry.width() != oldGeometry.width() || newGeometry.x() != oldGeometry.x())
381 calcWidth(/*changed*/);
382 if (newGeometry.height() != oldGeometry.height() || newGeometry.y() != oldGeometry.y())
383 calcHeight(/*changed*/);
386 void QSGContents::itemDestroyed(QSGItem *item)
389 QSGItemPrivate::get(item)->removeItemChangeListener(this, QSGItemPrivate::Geometry | QSGItemPrivate::Destroyed);
393 void QSGContents::childRemoved(QSGItem *item)
396 QSGItemPrivate::get(item)->removeItemChangeListener(this, QSGItemPrivate::Geometry | QSGItemPrivate::Destroyed);
400 void QSGContents::childAdded(QSGItem *item)
403 QSGItemPrivate::get(item)->addItemChangeListener(this, QSGItemPrivate::Geometry | QSGItemPrivate::Destroyed);
408 QSGItemKeyFilter::QSGItemKeyFilter(QSGItem *item)
409 : m_processPost(false), m_next(0)
411 QSGItemPrivate *p = item?QSGItemPrivate::get(item):0;
413 m_next = p->keyHandler;
414 p->keyHandler = this;
418 QSGItemKeyFilter::~QSGItemKeyFilter()
422 void QSGItemKeyFilter::keyPressed(QKeyEvent *event, bool post)
424 if (m_next) m_next->keyPressed(event, post);
427 void QSGItemKeyFilter::keyReleased(QKeyEvent *event, bool post)
429 if (m_next) m_next->keyReleased(event, post);
432 void QSGItemKeyFilter::inputMethodEvent(QInputMethodEvent *event, bool post)
435 m_next->inputMethodEvent(event, post);
440 QVariant QSGItemKeyFilter::inputMethodQuery(Qt::InputMethodQuery query) const
442 if (m_next) return m_next->inputMethodQuery(query);
446 void QSGItemKeyFilter::componentComplete()
448 if (m_next) m_next->componentComplete();
451 \qmlclass KeyNavigation QSGKeyNavigationAttached
452 \inqmlmodule QtQuick 2
453 \ingroup qml-basic-interaction-elements
454 \brief The KeyNavigation attached property supports key navigation by arrow keys.
456 Key-based user interfaces commonly allow the use of arrow keys to navigate between
457 focusable items. The KeyNavigation attached property enables this behavior by providing a
458 convenient way to specify the item that should gain focus when an arrow or tab key is pressed.
460 The following example provides key navigation for a 2x2 grid of items:
462 \snippet doc/src/snippets/declarative/keynavigation.qml 0
464 The top-left item initially receives focus by setting \l {Item::}{focus} to
465 \c true. When an arrow key is pressed, the focus will move to the
466 appropriate item, as defined by the value that has been set for
467 the KeyNavigation \l left, \l right, \l up or \l down properties.
469 Note that if a KeyNavigation attached property receives the key press and release
470 events for a requested arrow or tab key, the event is accepted and does not
471 propagate any further.
473 By default, KeyNavigation receives key events after the item to which it is attached.
474 If the item accepts the key event, the KeyNavigation attached property will not
475 receive an event for that key. Setting the \l priority property to
476 \c KeyNavigation.BeforeItem allows the event to be used for key navigation
477 before the item, rather than after.
479 If item to which the focus is switching is not enabled or visible, an attempt will
480 be made to skip this item and focus on the next. This is possible if there are
481 a chain of items with the same KeyNavigation handler. If multiple items in a row are not enabled
482 or visible, they will also be skipped.
484 KeyNavigation will implicitly set the other direction to return focus to this item. So if you set
485 \l left to another item, \l right will be set on that item's KeyNavigation to set focus back to this
486 item. However, if that item's KeyNavigation has had right explicitly set then no change will occur.
487 This means that the above example could have been written, with the same behaviour, without specifing
488 KeyNavigation.right or KeyNavigation.down for any of the items.
490 \sa {Keys}{Keys attached property}
494 \qmlproperty Item QtQuick2::KeyNavigation::left
495 \qmlproperty Item QtQuick2::KeyNavigation::right
496 \qmlproperty Item QtQuick2::KeyNavigation::up
497 \qmlproperty Item QtQuick2::KeyNavigation::down
498 \qmlproperty Item QtQuick2::KeyNavigation::tab
499 \qmlproperty Item QtQuick2::KeyNavigation::backtab
501 These properties hold the item to assign focus to
502 when the left, right, up or down cursor keys, or the
507 \qmlproperty Item QtQuick2::KeyNavigation::tab
508 \qmlproperty Item QtQuick2::KeyNavigation::backtab
510 These properties hold the item to assign focus to
511 when the Tab key or Shift+Tab key combination (Backtab) are pressed.
514 QSGKeyNavigationAttached::QSGKeyNavigationAttached(QObject *parent)
515 : QObject(*(new QSGKeyNavigationAttachedPrivate), parent),
516 QSGItemKeyFilter(qobject_cast<QSGItem*>(parent))
518 m_processPost = true;
521 QSGKeyNavigationAttached *
522 QSGKeyNavigationAttached::qmlAttachedProperties(QObject *obj)
524 return new QSGKeyNavigationAttached(obj);
527 QSGItem *QSGKeyNavigationAttached::left() const
529 Q_D(const QSGKeyNavigationAttached);
533 void QSGKeyNavigationAttached::setLeft(QSGItem *i)
535 Q_D(QSGKeyNavigationAttached);
540 QSGKeyNavigationAttached* other =
541 qobject_cast<QSGKeyNavigationAttached*>(qmlAttachedPropertiesObject<QSGKeyNavigationAttached>(i));
542 if (other && !other->d_func()->rightSet){
543 other->d_func()->right = qobject_cast<QSGItem*>(parent());
544 emit other->rightChanged();
549 QSGItem *QSGKeyNavigationAttached::right() const
551 Q_D(const QSGKeyNavigationAttached);
555 void QSGKeyNavigationAttached::setRight(QSGItem *i)
557 Q_D(QSGKeyNavigationAttached);
562 QSGKeyNavigationAttached* other =
563 qobject_cast<QSGKeyNavigationAttached*>(qmlAttachedPropertiesObject<QSGKeyNavigationAttached>(i));
564 if (other && !other->d_func()->leftSet){
565 other->d_func()->left = qobject_cast<QSGItem*>(parent());
566 emit other->leftChanged();
571 QSGItem *QSGKeyNavigationAttached::up() const
573 Q_D(const QSGKeyNavigationAttached);
577 void QSGKeyNavigationAttached::setUp(QSGItem *i)
579 Q_D(QSGKeyNavigationAttached);
584 QSGKeyNavigationAttached* other =
585 qobject_cast<QSGKeyNavigationAttached*>(qmlAttachedPropertiesObject<QSGKeyNavigationAttached>(i));
586 if (other && !other->d_func()->downSet){
587 other->d_func()->down = qobject_cast<QSGItem*>(parent());
588 emit other->downChanged();
593 QSGItem *QSGKeyNavigationAttached::down() const
595 Q_D(const QSGKeyNavigationAttached);
599 void QSGKeyNavigationAttached::setDown(QSGItem *i)
601 Q_D(QSGKeyNavigationAttached);
606 QSGKeyNavigationAttached* other =
607 qobject_cast<QSGKeyNavigationAttached*>(qmlAttachedPropertiesObject<QSGKeyNavigationAttached>(i));
608 if(other && !other->d_func()->upSet){
609 other->d_func()->up = qobject_cast<QSGItem*>(parent());
610 emit other->upChanged();
615 QSGItem *QSGKeyNavigationAttached::tab() const
617 Q_D(const QSGKeyNavigationAttached);
621 void QSGKeyNavigationAttached::setTab(QSGItem *i)
623 Q_D(QSGKeyNavigationAttached);
628 QSGKeyNavigationAttached* other =
629 qobject_cast<QSGKeyNavigationAttached*>(qmlAttachedPropertiesObject<QSGKeyNavigationAttached>(i));
630 if(other && !other->d_func()->backtabSet){
631 other->d_func()->backtab = qobject_cast<QSGItem*>(parent());
632 emit other->backtabChanged();
637 QSGItem *QSGKeyNavigationAttached::backtab() const
639 Q_D(const QSGKeyNavigationAttached);
643 void QSGKeyNavigationAttached::setBacktab(QSGItem *i)
645 Q_D(QSGKeyNavigationAttached);
649 d->backtabSet = true;
650 QSGKeyNavigationAttached* other =
651 qobject_cast<QSGKeyNavigationAttached*>(qmlAttachedPropertiesObject<QSGKeyNavigationAttached>(i));
652 if(other && !other->d_func()->tabSet){
653 other->d_func()->tab = qobject_cast<QSGItem*>(parent());
654 emit other->tabChanged();
656 emit backtabChanged();
660 \qmlproperty enumeration QtQuick2::KeyNavigation::priority
662 This property determines whether the keys are processed before
663 or after the attached item's own key handling.
666 \o KeyNavigation.BeforeItem - process the key events before normal
667 item key processing. If the event is used for key navigation, it will be accepted and will not
668 be passed on to the item.
669 \o KeyNavigation.AfterItem (default) - process the key events after normal item key
670 handling. If the item accepts the key event it will not be
671 handled by the KeyNavigation attached property handler.
674 QSGKeyNavigationAttached::Priority QSGKeyNavigationAttached::priority() const
676 return m_processPost ? AfterItem : BeforeItem;
679 void QSGKeyNavigationAttached::setPriority(Priority order)
681 bool processPost = order == AfterItem;
682 if (processPost != m_processPost) {
683 m_processPost = processPost;
684 emit priorityChanged();
688 void QSGKeyNavigationAttached::keyPressed(QKeyEvent *event, bool post)
690 Q_D(QSGKeyNavigationAttached);
693 if (post != m_processPost) {
694 QSGItemKeyFilter::keyPressed(event, post);
699 switch(event->key()) {
701 if (QSGItem *parentItem = qobject_cast<QSGItem*>(parent()))
702 mirror = QSGItemPrivate::get(parentItem)->effectiveLayoutMirror;
703 QSGItem* leftItem = mirror ? d->right : d->left;
705 setFocusNavigation(leftItem, mirror ? "right" : "left");
710 case Qt::Key_Right: {
711 if (QSGItem *parentItem = qobject_cast<QSGItem*>(parent()))
712 mirror = QSGItemPrivate::get(parentItem)->effectiveLayoutMirror;
713 QSGItem* rightItem = mirror ? d->left : d->right;
715 setFocusNavigation(rightItem, mirror ? "left" : "right");
722 setFocusNavigation(d->up, "up");
728 setFocusNavigation(d->down, "down");
734 setFocusNavigation(d->tab, "tab");
738 case Qt::Key_Backtab:
740 setFocusNavigation(d->backtab, "backtab");
748 if (!event->isAccepted()) QSGItemKeyFilter::keyPressed(event, post);
751 void QSGKeyNavigationAttached::keyReleased(QKeyEvent *event, bool post)
753 Q_D(QSGKeyNavigationAttached);
756 if (post != m_processPost) {
757 QSGItemKeyFilter::keyReleased(event, post);
762 switch(event->key()) {
764 if (QSGItem *parentItem = qobject_cast<QSGItem*>(parent()))
765 mirror = QSGItemPrivate::get(parentItem)->effectiveLayoutMirror;
766 if (mirror ? d->right : d->left)
770 if (QSGItem *parentItem = qobject_cast<QSGItem*>(parent()))
771 mirror = QSGItemPrivate::get(parentItem)->effectiveLayoutMirror;
772 if (mirror ? d->left : d->right)
790 case Qt::Key_Backtab:
799 if (!event->isAccepted()) QSGItemKeyFilter::keyReleased(event, post);
802 void QSGKeyNavigationAttached::setFocusNavigation(QSGItem *currentItem, const char *dir)
804 QSGItem *initialItem = currentItem;
805 bool isNextItem = false;
808 if (currentItem->isVisible() && currentItem->isEnabled()) {
809 currentItem->setFocus(true);
812 qmlAttachedPropertiesObject<QSGKeyNavigationAttached>(currentItem, false);
814 QSGItem *tempItem = qvariant_cast<QSGItem*>(attached->property(dir));
816 currentItem = tempItem;
822 while (currentItem != initialItem && isNextItem);
825 const QSGKeysAttached::SigMap QSGKeysAttached::sigMap[] = {
826 { Qt::Key_Left, "leftPressed" },
827 { Qt::Key_Right, "rightPressed" },
828 { Qt::Key_Up, "upPressed" },
829 { Qt::Key_Down, "downPressed" },
830 { Qt::Key_Tab, "tabPressed" },
831 { Qt::Key_Backtab, "backtabPressed" },
832 { Qt::Key_Asterisk, "asteriskPressed" },
833 { Qt::Key_NumberSign, "numberSignPressed" },
834 { Qt::Key_Escape, "escapePressed" },
835 { Qt::Key_Return, "returnPressed" },
836 { Qt::Key_Enter, "enterPressed" },
837 { Qt::Key_Delete, "deletePressed" },
838 { Qt::Key_Space, "spacePressed" },
839 { Qt::Key_Back, "backPressed" },
840 { Qt::Key_Cancel, "cancelPressed" },
841 { Qt::Key_Select, "selectPressed" },
842 { Qt::Key_Yes, "yesPressed" },
843 { Qt::Key_No, "noPressed" },
844 { Qt::Key_Context1, "context1Pressed" },
845 { Qt::Key_Context2, "context2Pressed" },
846 { Qt::Key_Context3, "context3Pressed" },
847 { Qt::Key_Context4, "context4Pressed" },
848 { Qt::Key_Call, "callPressed" },
849 { Qt::Key_Hangup, "hangupPressed" },
850 { Qt::Key_Flip, "flipPressed" },
851 { Qt::Key_Menu, "menuPressed" },
852 { Qt::Key_VolumeUp, "volumeUpPressed" },
853 { Qt::Key_VolumeDown, "volumeDownPressed" },
857 bool QSGKeysAttachedPrivate::isConnected(const char *signalName)
859 return isSignalConnected(signalIndex(signalName));
863 \qmlclass Keys QSGKeysAttached
864 \inqmlmodule QtQuick 2
865 \ingroup qml-basic-interaction-elements
866 \brief The Keys attached property provides key handling to Items.
868 All visual primitives support key handling via the Keys
869 attached property. Keys can be handled via the onPressed
870 and onReleased signal properties.
872 The signal properties have a \l KeyEvent parameter, named
873 \e event which contains details of the event. If a key is
874 handled \e event.accepted should be set to true to prevent the
875 event from propagating up the item hierarchy.
877 \section1 Example Usage
879 The following example shows how the general onPressed handler can
880 be used to test for a certain key; in this case, the left cursor
883 \snippet doc/src/snippets/declarative/keys/keys-pressed.qml key item
885 Some keys may alternatively be handled via specific signal properties,
886 for example \e onSelectPressed. These handlers automatically set
887 \e event.accepted to true.
889 \snippet doc/src/snippets/declarative/keys/keys-handler.qml key item
891 See \l{Qt::Key}{Qt.Key} for the list of keyboard codes.
893 \section1 Key Handling Priorities
895 The Keys attached property can be configured to handle key events
896 before or after the item it is attached to. This makes it possible
897 to intercept events in order to override an item's default behavior,
898 or act as a fallback for keys not handled by the item.
900 If \l priority is Keys.BeforeItem (default) the order of key event processing is:
903 \o Items specified in \c forwardTo
904 \o specific key handlers, e.g. onReturnPressed
905 \o onKeyPress, onKeyRelease handlers
906 \o Item specific key handling, e.g. TextInput key handling
910 If priority is Keys.AfterItem the order of key event processing is:
913 \o Item specific key handling, e.g. TextInput key handling
914 \o Items specified in \c forwardTo
915 \o specific key handlers, e.g. onReturnPressed
916 \o onKeyPress, onKeyRelease handlers
920 If the event is accepted during any of the above steps, key
923 \sa KeyEvent, {KeyNavigation}{KeyNavigation attached property}
927 \qmlproperty bool QtQuick2::Keys::enabled
929 This flags enables key handling if true (default); otherwise
930 no key handlers will be called.
934 \qmlproperty enumeration QtQuick2::Keys::priority
936 This property determines whether the keys are processed before
937 or after the attached item's own key handling.
940 \o Keys.BeforeItem (default) - process the key events before normal
941 item key processing. If the event is accepted it will not
942 be passed on to the item.
943 \o Keys.AfterItem - process the key events after normal item key
944 handling. If the item accepts the key event it will not be
945 handled by the Keys attached property handler.
950 \qmlproperty list<Object> QtQuick2::Keys::forwardTo
952 This property provides a way to forward key presses, key releases, and keyboard input
953 coming from input methods to other items. This can be useful when you want
954 one item to handle some keys (e.g. the up and down arrow keys), and another item to
955 handle other keys (e.g. the left and right arrow keys). Once an item that has been
956 forwarded keys accepts the event it is no longer forwarded to items later in the
959 This example forwards key events to two lists:
970 Keys.forwardTo: [list1, list2]
977 \qmlsignal QtQuick2::Keys::onPressed(KeyEvent event)
979 This handler is called when a key has been pressed. The \a event
980 parameter provides information about the event.
984 \qmlsignal QtQuick2::Keys::onReleased(KeyEvent event)
986 This handler is called when a key has been released. The \a event
987 parameter provides information about the event.
991 \qmlsignal QtQuick2::Keys::onDigit0Pressed(KeyEvent event)
993 This handler is called when the digit '0' has been pressed. The \a event
994 parameter provides information about the event.
998 \qmlsignal QtQuick2::Keys::onDigit1Pressed(KeyEvent event)
1000 This handler is called when the digit '1' has been pressed. The \a event
1001 parameter provides information about the event.
1005 \qmlsignal QtQuick2::Keys::onDigit2Pressed(KeyEvent event)
1007 This handler is called when the digit '2' has been pressed. The \a event
1008 parameter provides information about the event.
1012 \qmlsignal QtQuick2::Keys::onDigit3Pressed(KeyEvent event)
1014 This handler is called when the digit '3' has been pressed. The \a event
1015 parameter provides information about the event.
1019 \qmlsignal QtQuick2::Keys::onDigit4Pressed(KeyEvent event)
1021 This handler is called when the digit '4' has been pressed. The \a event
1022 parameter provides information about the event.
1026 \qmlsignal QtQuick2::Keys::onDigit5Pressed(KeyEvent event)
1028 This handler is called when the digit '5' has been pressed. The \a event
1029 parameter provides information about the event.
1033 \qmlsignal QtQuick2::Keys::onDigit6Pressed(KeyEvent event)
1035 This handler is called when the digit '6' has been pressed. The \a event
1036 parameter provides information about the event.
1040 \qmlsignal QtQuick2::Keys::onDigit7Pressed(KeyEvent event)
1042 This handler is called when the digit '7' has been pressed. The \a event
1043 parameter provides information about the event.
1047 \qmlsignal QtQuick2::Keys::onDigit8Pressed(KeyEvent event)
1049 This handler is called when the digit '8' has been pressed. The \a event
1050 parameter provides information about the event.
1054 \qmlsignal QtQuick2::Keys::onDigit9Pressed(KeyEvent event)
1056 This handler is called when the digit '9' has been pressed. The \a event
1057 parameter provides information about the event.
1061 \qmlsignal QtQuick2::Keys::onLeftPressed(KeyEvent event)
1063 This handler is called when the Left arrow has been pressed. The \a event
1064 parameter provides information about the event.
1068 \qmlsignal QtQuick2::Keys::onRightPressed(KeyEvent event)
1070 This handler is called when the Right arrow has been pressed. The \a event
1071 parameter provides information about the event.
1075 \qmlsignal QtQuick2::Keys::onUpPressed(KeyEvent event)
1077 This handler is called when the Up arrow has been pressed. The \a event
1078 parameter provides information about the event.
1082 \qmlsignal QtQuick2::Keys::onDownPressed(KeyEvent event)
1084 This handler is called when the Down arrow has been pressed. The \a event
1085 parameter provides information about the event.
1089 \qmlsignal QtQuick2::Keys::onTabPressed(KeyEvent event)
1091 This handler is called when the Tab key has been pressed. The \a event
1092 parameter provides information about the event.
1096 \qmlsignal QtQuick2::Keys::onBacktabPressed(KeyEvent event)
1098 This handler is called when the Shift+Tab key combination (Backtab) has
1099 been pressed. The \a event parameter provides information about the event.
1103 \qmlsignal QtQuick2::Keys::onAsteriskPressed(KeyEvent event)
1105 This handler is called when the Asterisk '*' has been pressed. The \a event
1106 parameter provides information about the event.
1110 \qmlsignal QtQuick2::Keys::onEscapePressed(KeyEvent event)
1112 This handler is called when the Escape key has been pressed. The \a event
1113 parameter provides information about the event.
1117 \qmlsignal QtQuick2::Keys::onReturnPressed(KeyEvent event)
1119 This handler is called when the Return key has been pressed. The \a event
1120 parameter provides information about the event.
1124 \qmlsignal QtQuick2::Keys::onEnterPressed(KeyEvent event)
1126 This handler is called when the Enter key has been pressed. The \a event
1127 parameter provides information about the event.
1131 \qmlsignal QtQuick2::Keys::onDeletePressed(KeyEvent event)
1133 This handler is called when the Delete key has been pressed. The \a event
1134 parameter provides information about the event.
1138 \qmlsignal QtQuick2::Keys::onSpacePressed(KeyEvent event)
1140 This handler is called when the Space key has been pressed. The \a event
1141 parameter provides information about the event.
1145 \qmlsignal QtQuick2::Keys::onBackPressed(KeyEvent event)
1147 This handler is called when the Back key has been pressed. The \a event
1148 parameter provides information about the event.
1152 \qmlsignal QtQuick2::Keys::onCancelPressed(KeyEvent event)
1154 This handler is called when the Cancel key has been pressed. The \a event
1155 parameter provides information about the event.
1159 \qmlsignal QtQuick2::Keys::onSelectPressed(KeyEvent event)
1161 This handler is called when the Select key has been pressed. The \a event
1162 parameter provides information about the event.
1166 \qmlsignal QtQuick2::Keys::onYesPressed(KeyEvent event)
1168 This handler is called when the Yes key has been pressed. The \a event
1169 parameter provides information about the event.
1173 \qmlsignal QtQuick2::Keys::onNoPressed(KeyEvent event)
1175 This handler is called when the No key has been pressed. The \a event
1176 parameter provides information about the event.
1180 \qmlsignal QtQuick2::Keys::onContext1Pressed(KeyEvent event)
1182 This handler is called when the Context1 key has been pressed. The \a event
1183 parameter provides information about the event.
1187 \qmlsignal QtQuick2::Keys::onContext2Pressed(KeyEvent event)
1189 This handler is called when the Context2 key has been pressed. The \a event
1190 parameter provides information about the event.
1194 \qmlsignal QtQuick2::Keys::onContext3Pressed(KeyEvent event)
1196 This handler is called when the Context3 key has been pressed. The \a event
1197 parameter provides information about the event.
1201 \qmlsignal QtQuick2::Keys::onContext4Pressed(KeyEvent event)
1203 This handler is called when the Context4 key has been pressed. The \a event
1204 parameter provides information about the event.
1208 \qmlsignal QtQuick2::Keys::onCallPressed(KeyEvent event)
1210 This handler is called when the Call key has been pressed. The \a event
1211 parameter provides information about the event.
1215 \qmlsignal QtQuick2::Keys::onHangupPressed(KeyEvent event)
1217 This handler is called when the Hangup key has been pressed. The \a event
1218 parameter provides information about the event.
1222 \qmlsignal QtQuick2::Keys::onFlipPressed(KeyEvent event)
1224 This handler is called when the Flip key has been pressed. The \a event
1225 parameter provides information about the event.
1229 \qmlsignal QtQuick2::Keys::onMenuPressed(KeyEvent event)
1231 This handler is called when the Menu key has been pressed. The \a event
1232 parameter provides information about the event.
1236 \qmlsignal QtQuick2::Keys::onVolumeUpPressed(KeyEvent event)
1238 This handler is called when the VolumeUp key has been pressed. The \a event
1239 parameter provides information about the event.
1243 \qmlsignal QtQuick2::Keys::onVolumeDownPressed(KeyEvent event)
1245 This handler is called when the VolumeDown key has been pressed. The \a event
1246 parameter provides information about the event.
1249 QSGKeysAttached::QSGKeysAttached(QObject *parent)
1250 : QObject(*(new QSGKeysAttachedPrivate), parent),
1251 QSGItemKeyFilter(qobject_cast<QSGItem*>(parent))
1253 Q_D(QSGKeysAttached);
1254 m_processPost = false;
1255 d->item = qobject_cast<QSGItem*>(parent);
1258 QSGKeysAttached::~QSGKeysAttached()
1262 QSGKeysAttached::Priority QSGKeysAttached::priority() const
1264 return m_processPost ? AfterItem : BeforeItem;
1267 void QSGKeysAttached::setPriority(Priority order)
1269 bool processPost = order == AfterItem;
1270 if (processPost != m_processPost) {
1271 m_processPost = processPost;
1272 emit priorityChanged();
1276 void QSGKeysAttached::componentComplete()
1278 Q_D(QSGKeysAttached);
1280 for (int ii = 0; ii < d->targets.count(); ++ii) {
1281 QSGItem *targetItem = d->targets.at(ii);
1282 if (targetItem && (targetItem->flags() & QSGItem::ItemAcceptsInputMethod)) {
1283 d->item->setFlag(QSGItem::ItemAcceptsInputMethod);
1290 void QSGKeysAttached::keyPressed(QKeyEvent *event, bool post)
1292 Q_D(QSGKeysAttached);
1293 if (post != m_processPost || !d->enabled || d->inPress) {
1295 QSGItemKeyFilter::keyPressed(event, post);
1299 // first process forwards
1300 if (d->item && d->item->canvas()) {
1302 for (int ii = 0; ii < d->targets.count(); ++ii) {
1303 QSGItem *i = d->targets.at(ii);
1304 if (i && i->isVisible()) {
1305 d->item->canvas()->sendEvent(i, event);
1306 if (event->isAccepted()) {
1315 QSGKeyEvent ke(*event);
1316 QByteArray keySignal = keyToSignal(event->key());
1317 if (!keySignal.isEmpty()) {
1318 keySignal += "(QSGKeyEvent*)";
1319 if (d->isConnected(keySignal)) {
1320 // If we specifically handle a key then default to accepted
1321 ke.setAccepted(true);
1322 int idx = QSGKeysAttached::staticMetaObject.indexOfSignal(keySignal);
1323 metaObject()->method(idx).invoke(this, Qt::DirectConnection, Q_ARG(QSGKeyEvent*, &ke));
1326 if (!ke.isAccepted())
1328 event->setAccepted(ke.isAccepted());
1330 if (!event->isAccepted()) QSGItemKeyFilter::keyPressed(event, post);
1333 void QSGKeysAttached::keyReleased(QKeyEvent *event, bool post)
1335 Q_D(QSGKeysAttached);
1336 if (post != m_processPost || !d->enabled || d->inRelease) {
1338 QSGItemKeyFilter::keyReleased(event, post);
1342 if (d->item && d->item->canvas()) {
1343 d->inRelease = true;
1344 for (int ii = 0; ii < d->targets.count(); ++ii) {
1345 QSGItem *i = d->targets.at(ii);
1346 if (i && i->isVisible()) {
1347 d->item->canvas()->sendEvent(i, event);
1348 if (event->isAccepted()) {
1349 d->inRelease = false;
1354 d->inRelease = false;
1357 QSGKeyEvent ke(*event);
1359 event->setAccepted(ke.isAccepted());
1361 if (!event->isAccepted()) QSGItemKeyFilter::keyReleased(event, post);
1364 void QSGKeysAttached::inputMethodEvent(QInputMethodEvent *event, bool post)
1366 Q_D(QSGKeysAttached);
1367 if (post == m_processPost && d->item && !d->inIM && d->item->canvas()) {
1369 for (int ii = 0; ii < d->targets.count(); ++ii) {
1370 QSGItem *i = d->targets.at(ii);
1371 if (i && i->isVisible() && (i->flags() & QSGItem::ItemAcceptsInputMethod)) {
1372 d->item->canvas()->sendEvent(i, event);
1373 if (event->isAccepted()) {
1382 QSGItemKeyFilter::inputMethodEvent(event, post);
1385 QVariant QSGKeysAttached::inputMethodQuery(Qt::InputMethodQuery query) const
1387 Q_D(const QSGKeysAttached);
1389 for (int ii = 0; ii < d->targets.count(); ++ii) {
1390 QSGItem *i = d->targets.at(ii);
1391 if (i && i->isVisible() && (i->flags() & QSGItem::ItemAcceptsInputMethod) && i == d->imeItem) {
1392 //### how robust is i == d->imeItem check?
1393 QVariant v = i->inputMethodQuery(query);
1394 if (v.userType() == QVariant::RectF)
1395 v = d->item->mapRectFromItem(i, v.toRectF()); //### cost?
1400 return QSGItemKeyFilter::inputMethodQuery(query);
1403 QSGKeysAttached *QSGKeysAttached::qmlAttachedProperties(QObject *obj)
1405 return new QSGKeysAttached(obj);
1409 \qmlclass LayoutMirroring QSGLayoutMirroringAttached
1410 \inqmlmodule QtQuick 2
1411 \ingroup qml-utility-elements
1412 \brief The LayoutMirroring attached property is used to mirror layout behavior.
1414 The LayoutMirroring attached property is used to horizontally mirror \l {anchor-layout}{Item anchors},
1415 \l{Using QML Positioner and Repeater Items}{positioner} elements (such as \l Row and \l Grid)
1416 and views (such as \l GridView and horizontal \l ListView). Mirroring is a visual change: left
1417 anchors become right anchors, and positioner elements like \l Grid and \l Row reverse the
1418 horizontal layout of child items.
1420 Mirroring is enabled for an item by setting the \l enabled property to true. By default, this
1421 only affects the item itself; setting the \l childrenInherit property to true propagates the mirroring
1422 behavior to all child elements as well. If the \c LayoutMirroring attached property has not been defined
1423 for an item, mirroring is not enabled.
1425 The following example shows mirroring in action. The \l Row below is specified as being anchored
1426 to the left of its parent. However, since mirroring has been enabled, the anchor is horizontally
1427 reversed and it is now anchored to the right. Also, since items in a \l Row are positioned
1428 from left to right by default, they are now positioned from right to left instead, as demonstrated
1429 by the numbering and opacity of the items:
1431 \snippet doc/src/snippets/declarative/layoutmirroring.qml 0
1433 \image layoutmirroring.png
1435 Layout mirroring is useful when it is necessary to support both left-to-right and right-to-left
1436 layout versions of an application to target different language areas. The \l childrenInherit
1437 property allows layout mirroring to be applied without manually setting layout configurations
1438 for every item in an application. Keep in mind, however, that mirroring does not affect any
1439 positioning that is defined by the \l Item \l {Item::}{x} coordinate value, so even with
1440 mirroring enabled, it will often be necessary to apply some layout fixes to support the
1441 desired layout direction. Also, it may be necessary to disable the mirroring of individual
1442 child items (by setting \l {enabled}{LayoutMirroring.enabled} to false for such items) if
1443 mirroring is not the desired behavior, or if the child item already implements mirroring in
1446 See \l {QML Right-to-left User Interfaces} for further details on using \c LayoutMirroring and
1447 other related features to implement right-to-left support for an application.
1451 \qmlproperty bool QtQuick2::LayoutMirroring::enabled
1453 This property holds whether the item's layout is mirrored horizontally. Setting this to true
1454 horizontally reverses \l {anchor-layout}{anchor} settings such that left anchors become right,
1455 and right anchors become left. For \l{Using QML Positioner and Repeater Items}{positioner} elements
1456 (such as \l Row and \l Grid) and view elements (such as \l {GridView}{GridView} and \l {ListView}{ListView})
1457 this also mirrors the horizontal layout direction of the item.
1459 The default value is false.
1463 \qmlproperty bool QtQuick2::LayoutMirroring::childrenInherit
1465 This property holds whether the \l {enabled}{LayoutMirroring.enabled} value for this item
1466 is inherited by its children.
1468 The default value is false.
1472 QSGLayoutMirroringAttached::QSGLayoutMirroringAttached(QObject *parent) : QObject(parent), itemPrivate(0)
1474 if (QSGItem *item = qobject_cast<QSGItem*>(parent)) {
1475 itemPrivate = QSGItemPrivate::get(item);
1476 itemPrivate->attachedLayoutDirection = this;
1478 qmlInfo(parent) << tr("LayoutDirection attached property only works with Items");
1481 QSGLayoutMirroringAttached * QSGLayoutMirroringAttached::qmlAttachedProperties(QObject *object)
1483 return new QSGLayoutMirroringAttached(object);
1486 bool QSGLayoutMirroringAttached::enabled() const
1488 return itemPrivate ? itemPrivate->effectiveLayoutMirror : false;
1491 void QSGLayoutMirroringAttached::setEnabled(bool enabled)
1496 itemPrivate->isMirrorImplicit = false;
1497 if (enabled != itemPrivate->effectiveLayoutMirror) {
1498 itemPrivate->setLayoutMirror(enabled);
1499 if (itemPrivate->inheritMirrorFromItem)
1500 itemPrivate->resolveLayoutMirror();
1504 void QSGLayoutMirroringAttached::resetEnabled()
1506 if (itemPrivate && !itemPrivate->isMirrorImplicit) {
1507 itemPrivate->isMirrorImplicit = true;
1508 itemPrivate->resolveLayoutMirror();
1512 bool QSGLayoutMirroringAttached::childrenInherit() const
1514 return itemPrivate ? itemPrivate->inheritMirrorFromItem : false;
1517 void QSGLayoutMirroringAttached::setChildrenInherit(bool childrenInherit) {
1518 if (itemPrivate && childrenInherit != itemPrivate->inheritMirrorFromItem) {
1519 itemPrivate->inheritMirrorFromItem = childrenInherit;
1520 itemPrivate->resolveLayoutMirror();
1521 childrenInheritChanged();
1525 void QSGItemPrivate::resolveLayoutMirror()
1528 if (QSGItem *parentItem = q->parentItem()) {
1529 QSGItemPrivate *parentPrivate = QSGItemPrivate::get(parentItem);
1530 setImplicitLayoutMirror(parentPrivate->inheritedLayoutMirror, parentPrivate->inheritMirrorFromParent);
1532 setImplicitLayoutMirror(isMirrorImplicit ? false : effectiveLayoutMirror, inheritMirrorFromItem);
1536 void QSGItemPrivate::setImplicitLayoutMirror(bool mirror, bool inherit)
1538 inherit = inherit || inheritMirrorFromItem;
1539 if (!isMirrorImplicit && inheritMirrorFromItem)
1540 mirror = effectiveLayoutMirror;
1541 if (mirror == inheritedLayoutMirror && inherit == inheritMirrorFromParent)
1544 inheritMirrorFromParent = inherit;
1545 inheritedLayoutMirror = inheritMirrorFromParent ? mirror : false;
1547 if (isMirrorImplicit)
1548 setLayoutMirror(inherit ? inheritedLayoutMirror : false);
1549 for (int i = 0; i < childItems.count(); ++i) {
1550 if (QSGItem *child = qobject_cast<QSGItem *>(childItems.at(i))) {
1551 QSGItemPrivate *childPrivate = QSGItemPrivate::get(child);
1552 childPrivate->setImplicitLayoutMirror(inheritedLayoutMirror, inheritMirrorFromParent);
1557 void QSGItemPrivate::setLayoutMirror(bool mirror)
1559 if (mirror != effectiveLayoutMirror) {
1560 effectiveLayoutMirror = mirror;
1562 QSGAnchorsPrivate *anchor_d = QSGAnchorsPrivate::get(_anchors);
1563 anchor_d->fillChanged();
1564 anchor_d->centerInChanged();
1565 anchor_d->updateHorizontalAnchors();
1566 emit _anchors->mirroredChanged();
1569 if (attachedLayoutDirection) {
1570 emit attachedLayoutDirection->enabledChanged();
1577 \brief The QSGItem class provides the most basic of all visual items in QML.
1579 All visual items in Qt Declarative inherit from QSGItem. Although QSGItem
1580 has no visual appearance, it defines all the properties that are
1581 common across visual items - such as the x and y position, the
1582 width and height, \l {anchor-layout}{anchoring} and key handling.
1584 You can subclass QSGItem to provide your own custom visual item that inherits
1585 these features. Note that, because it does not draw anything, QSGItem sets the
1586 QGraphicsItem::ItemHasNoContents flag. If you subclass QSGItem to create a visual
1587 item, you will need to unset this flag.
1592 \qmlclass Item QSGItem
1593 \inqmlmodule QtQuick 2
1594 \ingroup qml-basic-visual-elements
1595 \brief The Item is the most basic of all visual items in QML.
1597 All visual items in Qt Declarative inherit from Item. Although Item
1598 has no visual appearance, it defines all the properties that are
1599 common across visual items - such as the x and y position, the
1600 width and height, \l {anchor-layout}{anchoring} and key handling.
1602 Item is also useful for grouping items together.
1619 fillMode: Image.Tile
1626 \section1 Key Handling
1628 Key handling is available to all Item-based visual elements via the \l {Keys}{Keys}
1629 attached property. The \e Keys attached property provides basic handlers such
1630 as \l {Keys::onPressed}{onPressed} and \l {Keys::onReleased}{onReleased},
1631 as well as handlers for specific keys, such as
1632 \l {Keys::onCancelPressed}{onCancelPressed}. The example below
1633 assigns \l {qmlfocus}{focus} to the item and handles
1634 the Left key via the general \e onPressed handler and the Select key via the
1635 onSelectPressed handler:
1641 if (event.key == Qt.Key_Left) {
1642 console.log("move left");
1643 event.accepted = true;
1646 Keys.onSelectPressed: console.log("Selected");
1650 See the \l {Keys}{Keys} attached property for detailed documentation.
1652 \section1 Layout Mirroring
1654 Item layouts can be mirrored using the \l {LayoutMirroring}{LayoutMirroring} attached property.
1659 \fn void QSGItem::childrenRectChanged(const QRectF &)
1664 \fn void QSGItem::baselineOffsetChanged(qreal)
1669 \fn void QSGItem::stateChanged(const QString &state)
1674 \fn void QSGItem::parentChanged(QSGItem *)
1679 \fn void QSGItem::smoothChanged(bool)
1684 \fn void QSGItem::clipChanged(bool)
1688 /*! \fn void QSGItem::transformOriginChanged(TransformOrigin)
1693 \fn void QSGItem::focusChanged(bool)
1698 \fn void QSGItem::activeFocusChanged(bool)
1702 \fn QSGItem::QSGItem(QSGItem *parent)
1704 Constructs a QSGItem with the given \a parent.
1706 QSGItem::QSGItem(QSGItem* parent)
1707 : QObject(*(new QSGItemPrivate), parent)
1715 QSGItem::QSGItem(QSGItemPrivate &dd, QSGItem *parent)
1716 : QObject(dd, parent)
1723 static int qt_item_count = 0;
1725 static void qt_print_item_count()
1727 qDebug("Number of leaked items: %i", qt_item_count);
1733 Destroys the QSGItem.
1739 if (qt_item_count < 0)
1740 qDebug("Item destroyed after qt_print_item_count() was called.");
1747 else if (d->canvas && d->itemNodeInstance)
1748 QSGCanvasPrivate::get(d->canvas)->cleanup(d->itemNodeInstance); // cleanup root
1749 // XXX todo - optimize
1750 while (!d->childItems.isEmpty())
1751 d->childItems.first()->setParentItem(0);
1753 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
1754 QSGAnchorsPrivate *anchor = d->changeListeners.at(ii).listener->anchorPrivate();
1756 anchor->clearItem(this);
1759 // XXX todo - the original checks if the parent is being destroyed
1760 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
1761 QSGAnchorsPrivate *anchor = d->changeListeners.at(ii).listener->anchorPrivate();
1762 if (anchor && anchor->item && anchor->item->parent() != this) //child will be deleted anyway
1763 anchor->updateOnComplete();
1766 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
1767 const QSGItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
1768 if (change.types & QSGItemPrivate::Destroyed)
1769 change.listener->itemDestroyed(this);
1771 d->changeListeners.clear();
1772 delete d->_anchorLines; d->_anchorLines = 0;
1773 delete d->_anchors; d->_anchors = 0;
1774 delete d->_stateGroup; d->_stateGroup = 0;
1775 delete d->_contents; d->_contents = 0;
1779 \qmlproperty enumeration QtQuick2::Item::transformOrigin
1780 This property holds the origin point around which scale and rotation transform.
1782 Nine transform origins are available, as shown in the image below.
1784 \image declarative-transformorigin.png
1786 This example rotates an image around its bottom-right corner.
1789 source: "myimage.png"
1790 transformOrigin: Item.BottomRight
1795 The default transform origin is \c Item.Center.
1797 To set an arbitrary transform origin point use the \l Scale or \l Rotation
1802 \qmlproperty Item QtQuick2::Item::parent
1803 This property holds the parent of the item.
1807 \property QSGItem::parent
1808 This property holds the parent of the item.
1810 void QSGItem::setParentItem(QSGItem *parentItem)
1813 if (parentItem == d->parentItem)
1816 d->removeFromDirtyList();
1818 QSGItem *oldParentItem = d->parentItem;
1819 QSGItem *scopeFocusedItem = 0;
1821 if (oldParentItem) {
1822 QSGItemPrivate *op = QSGItemPrivate::get(oldParentItem);
1824 QSGItem *scopeItem = 0;
1826 if (d->canvas && hasFocus()) {
1827 scopeItem = oldParentItem;
1828 while (!scopeItem->isFocusScope()) scopeItem = scopeItem->parentItem();
1829 scopeFocusedItem = this;
1830 } else if (d->canvas && !isFocusScope() && d->subFocusItem) {
1831 scopeItem = oldParentItem;
1832 while (!scopeItem->isFocusScope()) scopeItem = scopeItem->parentItem();
1833 scopeFocusedItem = d->subFocusItem;
1836 if (scopeFocusedItem)
1837 QSGCanvasPrivate::get(d->canvas)->clearFocusInScope(scopeItem, scopeFocusedItem,
1838 QSGCanvasPrivate::DontChangeFocusProperty);
1840 op->removeChild(this);
1843 d->parentItem = parentItem;
1845 QSGCanvas *parentCanvas = parentItem?QSGItemPrivate::get(parentItem)->canvas:0;
1846 if (d->canvas != parentCanvas) {
1847 QSGItemPrivate::InitializationState initState;
1849 d->initCanvas(&initState, parentCanvas);
1852 d->dirty(QSGItemPrivate::ParentChanged);
1855 QSGItemPrivate::get(d->parentItem)->addChild(this);
1857 d->setEffectiveVisibleRecur(d->calcEffectiveVisible());
1858 d->setEffectiveEnableRecur(d->calcEffectiveEnable());
1860 if (scopeFocusedItem && d->parentItem && d->canvas) {
1861 // We need to test whether this item becomes scope focused
1862 QSGItem *scopeItem = 0;
1863 scopeItem = d->parentItem;
1864 while (!scopeItem->isFocusScope()) scopeItem = scopeItem->parentItem();
1866 if (scopeItem->scopedFocusItem()) {
1867 QSGItemPrivate::get(scopeFocusedItem)->focus = false;
1868 emit scopeFocusedItem->focusChanged(false);
1870 QSGCanvasPrivate::get(d->canvas)->setFocusInScope(scopeItem, scopeFocusedItem,
1871 QSGCanvasPrivate::DontChangeFocusProperty);
1875 d->resolveLayoutMirror();
1877 d->itemChange(ItemParentHasChanged, d->parentItem);
1879 emit parentChanged(d->parentItem);
1882 void QSGItem::stackBefore(const QSGItem *sibling)
1885 if (!sibling || sibling == this || !d->parentItem || d->parentItem != QSGItemPrivate::get(sibling)->parentItem) {
1886 qWarning("QSGItem::stackBefore: Cannot stack before %p, which must be a sibling", sibling);
1890 QSGItemPrivate *parentPrivate = QSGItemPrivate::get(d->parentItem);
1892 int myIndex = parentPrivate->childItems.indexOf(this);
1893 int siblingIndex = parentPrivate->childItems.indexOf(const_cast<QSGItem *>(sibling));
1895 Q_ASSERT(myIndex != -1 && siblingIndex != -1);
1897 if (myIndex == siblingIndex - 1)
1900 parentPrivate->childItems.removeAt(myIndex);
1902 if (myIndex < siblingIndex) --siblingIndex;
1904 parentPrivate->childItems.insert(siblingIndex, this);
1906 parentPrivate->dirty(QSGItemPrivate::ChildrenStackingChanged);
1908 for (int ii = qMin(siblingIndex, myIndex); ii < parentPrivate->childItems.count(); ++ii)
1909 QSGItemPrivate::get(parentPrivate->childItems.at(ii))->siblingOrderChanged();
1912 void QSGItem::stackAfter(const QSGItem *sibling)
1915 if (!sibling || sibling == this || !d->parentItem || d->parentItem != QSGItemPrivate::get(sibling)->parentItem) {
1916 qWarning("QSGItem::stackAfter: Cannot stack after %p, which must be a sibling", sibling);
1920 QSGItemPrivate *parentPrivate = QSGItemPrivate::get(d->parentItem);
1922 int myIndex = parentPrivate->childItems.indexOf(this);
1923 int siblingIndex = parentPrivate->childItems.indexOf(const_cast<QSGItem *>(sibling));
1925 Q_ASSERT(myIndex != -1 && siblingIndex != -1);
1927 if (myIndex == siblingIndex + 1)
1930 parentPrivate->childItems.removeAt(myIndex);
1932 if (myIndex < siblingIndex) --siblingIndex;
1934 parentPrivate->childItems.insert(siblingIndex + 1, this);
1936 parentPrivate->dirty(QSGItemPrivate::ChildrenStackingChanged);
1938 for (int ii = qMin(myIndex, siblingIndex + 1); ii < parentPrivate->childItems.count(); ++ii)
1939 QSGItemPrivate::get(parentPrivate->childItems.at(ii))->siblingOrderChanged();
1943 Returns the QSGItem parent of this item.
1945 QSGItem *QSGItem::parentItem() const
1948 return d->parentItem;
1951 QSGEngine *QSGItem::sceneGraphEngine() const
1953 return canvas()->sceneGraphEngine();
1956 QSGCanvas *QSGItem::canvas() const
1962 static bool itemZOrder_sort(QSGItem *lhs, QSGItem *rhs)
1964 return lhs->z() < rhs->z();
1967 QList<QSGItem *> QSGItemPrivate::paintOrderChildItems() const
1969 // XXX todo - optimize, don't sort and return items that are
1970 // ignored anyway, like invisible or disabled items.
1971 QList<QSGItem *> items = childItems;
1972 qStableSort(items.begin(), items.end(), itemZOrder_sort);
1976 void QSGItemPrivate::addChild(QSGItem *child)
1980 Q_ASSERT(!childItems.contains(child));
1982 childItems.append(child);
1984 dirty(QSGItemPrivate::ChildrenChanged);
1986 itemChange(QSGItem::ItemChildAddedChange, child);
1988 emit q->childrenChanged();
1991 void QSGItemPrivate::removeChild(QSGItem *child)
1996 Q_ASSERT(childItems.contains(child));
1997 childItems.removeOne(child);
1998 Q_ASSERT(!childItems.contains(child));
2000 dirty(QSGItemPrivate::ChildrenChanged);
2002 itemChange(QSGItem::ItemChildRemovedChange, child);
2004 emit q->childrenChanged();
2007 void QSGItemPrivate::InitializationState::clear()
2012 void QSGItemPrivate::InitializationState::clear(QSGItem *fs)
2017 QSGItem *QSGItemPrivate::InitializationState::getFocusScope(QSGItem *item)
2020 QSGItem *fs = item->parentItem();
2021 while (!fs->isFocusScope())
2022 fs = fs->parentItem();
2028 void QSGItemPrivate::initCanvas(InitializationState *state, QSGCanvas *c)
2033 removeFromDirtyList();
2034 QSGCanvasPrivate *c = QSGCanvasPrivate::get(canvas);
2035 if (polishScheduled)
2036 c->itemsToPolish.remove(q);
2037 if (c->mouseGrabberItem == q)
2038 c->mouseGrabberItem = 0;
2040 c->hoverItems.removeAll(q);
2041 if (itemNodeInstance)
2042 c->cleanup(itemNodeInstance);
2047 if (canvas && polishScheduled)
2048 QSGCanvasPrivate::get(canvas)->itemsToPolish.insert(q);
2050 itemNodeInstance = 0;
2056 beforePaintNode = 0;
2058 InitializationState _dummy;
2059 InitializationState *childState = state;
2061 if (c && q->isFocusScope()) {
2063 childState = &_dummy;
2066 for (int ii = 0; ii < childItems.count(); ++ii) {
2067 QSGItem *child = childItems.at(ii);
2068 QSGItemPrivate::get(child)->initCanvas(childState, c);
2073 if (state->getFocusScope(q)->scopedFocusItem()) {
2075 emit q->focusChanged(false);
2077 QSGCanvasPrivate::get(canvas)->setFocusInScope(state->getFocusScope(q), q);
2083 itemChange(QSGItem::ItemSceneChange, c);
2087 Returns a transform that maps points from canvas space into item space.
2089 QTransform QSGItemPrivate::canvasToItemTransform() const
2091 // XXX todo - optimize
2092 return itemToCanvasTransform().inverted();
2096 Returns a transform that maps points from item space into canvas space.
2098 QTransform QSGItemPrivate::itemToCanvasTransform() const
2101 QTransform rv = parentItem?QSGItemPrivate::get(parentItem)->itemToCanvasTransform():QTransform();
2102 itemToParentTransform(rv);
2107 Motifies \a t with this items local transform relative to its parent.
2109 void QSGItemPrivate::itemToParentTransform(QTransform &t) const
2114 if (!transforms.isEmpty()) {
2116 for (int ii = transforms.count() - 1; ii >= 0; --ii)
2117 transforms.at(ii)->applyTo(&m);
2118 t = m.toTransform();
2121 if (scale != 1. || rotation != 0.) {
2122 QPointF tp = computeTransformOrigin();
2123 t.translate(tp.x(), tp.y());
2124 t.scale(scale, scale);
2126 t.translate(-tp.x(), -tp.y());
2132 \qmlproperty real QtQuick2::Item::childrenRect.x
2133 \qmlproperty real QtQuick2::Item::childrenRect.y
2134 \qmlproperty real QtQuick2::Item::childrenRect.width
2135 \qmlproperty real QtQuick2::Item::childrenRect.height
2137 The childrenRect properties allow an item access to the geometry of its
2138 children. This property is useful if you have an item that needs to be
2139 sized to fit its children.
2144 \qmlproperty list<Item> QtQuick2::Item::children
2145 \qmlproperty list<Object> QtQuick2::Item::resources
2147 The children property contains the list of visual children of this item.
2148 The resources property contains non-visual resources that you want to
2151 Generally you can rely on Item's default property to handle all this for
2152 you, but it can come in handy in some cases.
2171 Returns true if construction of the QML component is complete; otherwise
2174 It is often desirable to delay some processing until the component is
2177 \sa componentComplete()
2179 bool QSGItem::isComponentComplete() const
2182 return d->componentComplete;
2185 QSGItemPrivate::QSGItemPrivate()
2186 : _anchors(0), _contents(0), baselineOffset(0), _anchorLines(0), _stateGroup(0), origin(QSGItem::Center),
2188 flags(0), widthValid(false), heightValid(false), componentComplete(true),
2189 keepMouse(false), hoverEnabled(false), smooth(false), focus(false), activeFocus(false), notifiedFocus(false),
2190 notifiedActiveFocus(false), filtersChildMouseEvents(false), explicitVisible(true),
2191 effectiveVisible(true), explicitEnable(true), effectiveEnable(true), polishScheduled(false),
2192 inheritedLayoutMirror(false), effectiveLayoutMirror(false), isMirrorImplicit(true),
2193 inheritMirrorFromParent(false), inheritMirrorFromItem(false), childrenDoNotOverlap(false),
2195 canvas(0), parentItem(0),
2199 x(0), y(0), width(0), height(0), implicitWidth(0), implicitHeight(0),
2200 z(0), scale(1), rotation(0), opacity(1),
2202 attachedLayoutDirection(0), acceptedMouseButtons(0),
2203 imHints(Qt::ImhMultiLine),
2207 dirtyAttributes(0), nextDirtyItem(0), prevDirtyItem(0),
2209 itemNodeInstance(0), opacityNode(0), clipNode(0), rootNode(0), groupNode(0), paintNode(0)
2210 , beforePaintNode(0), effectRefCount(0), hideRefCount(0)
2214 void QSGItemPrivate::init(QSGItem *parent)
2218 static bool atexit_registered = false;
2219 if (!atexit_registered) {
2220 atexit(qt_print_item_count);
2221 atexit_registered = true;
2226 baselineOffset.invalidate();
2229 q->setParentItem(parent);
2230 QSGItemPrivate *parentPrivate = QSGItemPrivate::get(parent);
2231 setImplicitLayoutMirror(parentPrivate->inheritedLayoutMirror, parentPrivate->inheritMirrorFromParent);
2235 void QSGItemPrivate::data_append(QDeclarativeListProperty<QObject> *prop, QObject *o)
2240 QSGItem *that = static_cast<QSGItem *>(prop->object);
2242 // This test is measurably (albeit only slightly) faster than qobject_cast<>()
2243 const QMetaObject *mo = o->metaObject();
2244 while (mo && mo != &QSGItem::staticMetaObject) {
2245 mo = mo->d.superdata;
2249 QSGItem *item = static_cast<QSGItem *>(o);
2250 item->setParentItem(that);
2252 if (o->inherits("QGraphicsItem"))
2253 qWarning("Cannot add a QtQuick 1.0 item (%s) into a QtQuick 2.0 scene!", o->metaObject()->className());
2255 // XXX todo - do we really want this behavior?
2261 \qmlproperty list<Object> QtQuick2::Item::data
2264 The data property allows you to freely mix visual children and resources
2265 in an item. If you assign a visual item to the data list it becomes
2266 a child and if you assign any other object type, it is added as a resource.
2290 data is a behind-the-scenes property: you should never need to explicitly
2294 int QSGItemPrivate::data_count(QDeclarativeListProperty<QObject> *prop)
2301 QObject *QSGItemPrivate::data_at(QDeclarativeListProperty<QObject> *prop, int i)
2309 void QSGItemPrivate::data_clear(QDeclarativeListProperty<QObject> *prop)
2315 QObject *QSGItemPrivate::resources_at(QDeclarativeListProperty<QObject> *prop, int index)
2317 const QObjectList children = prop->object->children();
2318 if (index < children.count())
2319 return children.at(index);
2324 void QSGItemPrivate::resources_append(QDeclarativeListProperty<QObject> *prop, QObject *o)
2326 // XXX todo - do we really want this behavior?
2327 o->setParent(prop->object);
2330 int QSGItemPrivate::resources_count(QDeclarativeListProperty<QObject> *prop)
2332 return prop->object->children().count();
2335 void QSGItemPrivate::resources_clear(QDeclarativeListProperty<QObject> *prop)
2337 // XXX todo - do we really want this behavior?
2338 const QObjectList children = prop->object->children();
2339 for (int index = 0; index < children.count(); index++)
2340 children.at(index)->setParent(0);
2343 QSGItem *QSGItemPrivate::children_at(QDeclarativeListProperty<QSGItem> *prop, int index)
2345 QSGItemPrivate *p = QSGItemPrivate::get(static_cast<QSGItem *>(prop->object));
2346 if (index >= p->childItems.count() || index < 0)
2349 return p->childItems.at(index);
2352 void QSGItemPrivate::children_append(QDeclarativeListProperty<QSGItem> *prop, QSGItem *o)
2357 QSGItem *that = static_cast<QSGItem *>(prop->object);
2358 if (o->parentItem() == that)
2359 o->setParentItem(0);
2361 o->setParentItem(that);
2364 int QSGItemPrivate::children_count(QDeclarativeListProperty<QSGItem> *prop)
2366 QSGItemPrivate *p = QSGItemPrivate::get(static_cast<QSGItem *>(prop->object));
2367 return p->childItems.count();
2370 void QSGItemPrivate::children_clear(QDeclarativeListProperty<QSGItem> *prop)
2372 QSGItem *that = static_cast<QSGItem *>(prop->object);
2373 QSGItemPrivate *p = QSGItemPrivate::get(that);
2374 while (!p->childItems.isEmpty())
2375 p->childItems.at(0)->setParentItem(0);
2378 int QSGItemPrivate::transform_count(QDeclarativeListProperty<QSGTransform> *prop)
2380 QSGItem *that = static_cast<QSGItem *>(prop->object);
2381 return QSGItemPrivate::get(that)->transforms.count();
2384 void QSGTransform::appendToItem(QSGItem *item)
2390 QSGItemPrivate *p = QSGItemPrivate::get(item);
2392 if (!d->items.isEmpty() && !p->transforms.isEmpty() && p->transforms.contains(this)) {
2393 p->transforms.removeOne(this);
2394 p->transforms.append(this);
2396 p->transforms.append(this);
2397 d->items.append(item);
2400 p->dirty(QSGItemPrivate::Transform);
2403 void QSGTransform::prependToItem(QSGItem *item)
2409 QSGItemPrivate *p = QSGItemPrivate::get(item);
2411 if (!d->items.isEmpty() && !p->transforms.isEmpty() && p->transforms.contains(this)) {
2412 p->transforms.removeOne(this);
2413 p->transforms.prepend(this);
2415 p->transforms.prepend(this);
2416 d->items.append(item);
2419 p->dirty(QSGItemPrivate::Transform);
2422 void QSGItemPrivate::transform_append(QDeclarativeListProperty<QSGTransform> *prop, QSGTransform *transform)
2427 QSGItem *that = static_cast<QSGItem *>(prop->object);
2428 transform->appendToItem(that);
2431 QSGTransform *QSGItemPrivate::transform_at(QDeclarativeListProperty<QSGTransform> *prop, int idx)
2433 QSGItem *that = static_cast<QSGItem *>(prop->object);
2434 QSGItemPrivate *p = QSGItemPrivate::get(that);
2436 if (idx < 0 || idx >= p->transforms.count())
2439 return p->transforms.at(idx);
2442 void QSGItemPrivate::transform_clear(QDeclarativeListProperty<QSGTransform> *prop)
2444 QSGItem *that = static_cast<QSGItem *>(prop->object);
2445 QSGItemPrivate *p = QSGItemPrivate::get(that);
2447 for (int ii = 0; ii < p->transforms.count(); ++ii) {
2448 QSGTransform *t = p->transforms.at(ii);
2449 QSGTransformPrivate *tp = QSGTransformPrivate::get(t);
2450 tp->items.removeOne(that);
2453 p->transforms.clear();
2455 p->dirty(QSGItemPrivate::Transform);
2459 \property QSGItem::childrenRect
2460 \brief The geometry of an item's children.
2462 This property holds the (collective) position and size of the item's children.
2466 \qmlproperty real QtQuick2::Item::x
2467 \qmlproperty real QtQuick2::Item::y
2468 \qmlproperty real QtQuick2::Item::width
2469 \qmlproperty real QtQuick2::Item::height
2471 Defines the item's position and size relative to its parent.
2474 Item { x: 100; y: 100; width: 100; height: 100 }
2479 \qmlproperty real QtQuick2::Item::z
2481 Sets the stacking order of sibling items. By default the stacking order is 0.
2483 Items with a higher stacking value are drawn on top of siblings with a
2484 lower stacking order. Items with the same stacking value are drawn
2485 bottom up in the order they appear. Items with a negative stacking
2486 value are drawn under their parent's content.
2488 The following example shows the various effects of stacking order.
2492 \o \image declarative-item_stacking1.png
2493 \o Same \c z - later children above earlier children:
2498 width: 100; height: 100
2502 x: 50; y: 50; width: 100; height: 100
2507 \o \image declarative-item_stacking2.png
2508 \o Higher \c z on top:
2514 width: 100; height: 100
2518 x: 50; y: 50; width: 100; height: 100
2523 \o \image declarative-item_stacking3.png
2524 \o Same \c z - children above parents:
2529 width: 100; height: 100
2532 x: 50; y: 50; width: 100; height: 100
2538 \o \image declarative-item_stacking4.png
2539 \o Lower \c z below:
2544 width: 100; height: 100
2548 x: 50; y: 50; width: 100; height: 100
2557 \qmlproperty bool QtQuick2::Item::visible
2559 This property holds whether the item is visible. By default this is true.
2561 Setting this property directly affects the \c visible value of child
2562 items. When set to \c false, the \c visible values of all child items also
2563 become \c false. When set to \c true, the \c visible values of child items
2564 are returned to \c true, unless they have explicitly been set to \c false.
2566 (Because of this flow-on behavior, using the \c visible property may not
2567 have the intended effect if a property binding should only respond to
2568 explicit property changes. In such cases it may be better to use the
2569 \l opacity property instead.)
2571 Setting this property to \c false automatically causes \l focus to be set
2572 to \c false, and this item will longer receive mouse and keyboard events.
2573 (In contrast, setting the \l opacity to 0 does not affect the \l focus
2574 property and the receiving of key events.)
2576 \note This property's value is only affected by changes to this property or
2577 the parent's \c visible property. It does not change, for example, if this
2578 item moves off-screen, or if the \l opacity changes to 0.
2583 \qmlproperty AnchorLine QtQuick2::Item::anchors.top
2584 \qmlproperty AnchorLine QtQuick2::Item::anchors.bottom
2585 \qmlproperty AnchorLine QtQuick2::Item::anchors.left
2586 \qmlproperty AnchorLine QtQuick2::Item::anchors.right
2587 \qmlproperty AnchorLine QtQuick2::Item::anchors.horizontalCenter
2588 \qmlproperty AnchorLine QtQuick2::Item::anchors.verticalCenter
2589 \qmlproperty AnchorLine QtQuick2::Item::anchors.baseline
2591 \qmlproperty Item QtQuick2::Item::anchors.fill
2592 \qmlproperty Item QtQuick2::Item::anchors.centerIn
2594 \qmlproperty real QtQuick2::Item::anchors.margins
2595 \qmlproperty real QtQuick2::Item::anchors.topMargin
2596 \qmlproperty real QtQuick2::Item::anchors.bottomMargin
2597 \qmlproperty real QtQuick2::Item::anchors.leftMargin
2598 \qmlproperty real QtQuick2::Item::anchors.rightMargin
2599 \qmlproperty real QtQuick2::Item::anchors.horizontalCenterOffset
2600 \qmlproperty real QtQuick2::Item::anchors.verticalCenterOffset
2601 \qmlproperty real QtQuick2::Item::anchors.baselineOffset
2603 \qmlproperty bool QtQuick2::Item::anchors.mirrored
2605 Anchors provide a way to position an item by specifying its
2606 relationship with other items.
2608 Margins apply to top, bottom, left, right, and fill anchors.
2609 The \c anchors.margins property can be used to set all of the various margins at once, to the same value.
2610 Note that margins are anchor-specific and are not applied if an item does not
2613 Offsets apply for horizontal center, vertical center, and baseline anchors.
2617 \o \image declarative-anchors_example.png
2618 \o Text anchored to Image, horizontally centered and vertically below, with a margin.
2627 anchors.horizontalCenter: pic.horizontalCenter
2628 anchors.top: pic.bottom
2629 anchors.topMargin: 5
2635 \o \image declarative-anchors_example2.png
2637 Left of Text anchored to right of Image, with a margin. The y
2638 property of both defaults to 0.
2648 anchors.left: pic.right
2649 anchors.leftMargin: 5
2656 \c anchors.fill provides a convenient way for one item to have the
2657 same geometry as another item, and is equivalent to connecting all
2658 four directional anchors.
2660 To clear an anchor value, set it to \c undefined.
2662 \c anchors.mirrored returns true it the layout has been \l {LayoutMirroring}{mirrored}.
2664 \note You can only anchor an item to siblings or a parent.
2666 For more information see \l {anchor-layout}{Anchor Layouts}.
2670 \property QSGItem::baselineOffset
2671 \brief The position of the item's baseline in local coordinates.
2673 The baseline of a \l Text item is the imaginary line on which the text
2674 sits. Controls containing text usually set their baseline to the
2675 baseline of their text.
2677 For non-text items, a default baseline offset of 0 is used.
2679 QSGAnchors *QSGItemPrivate::anchors() const
2683 _anchors = new QSGAnchors(const_cast<QSGItem *>(q));
2684 if (!componentComplete)
2685 _anchors->classBegin();
2690 QSGItemPrivate::AnchorLines *QSGItemPrivate::anchorLines() const
2693 if (!_anchorLines) _anchorLines =
2694 new AnchorLines(const_cast<QSGItem *>(q));
2695 return _anchorLines;
2698 void QSGItemPrivate::siblingOrderChanged()
2701 for(int ii = 0; ii < changeListeners.count(); ++ii) {
2702 const QSGItemPrivate::ChangeListener &change = changeListeners.at(ii);
2703 if (change.types & QSGItemPrivate::SiblingOrder) {
2704 change.listener->itemSiblingOrderChanged(q);
2709 QDeclarativeListProperty<QObject> QSGItemPrivate::data()
2711 return QDeclarativeListProperty<QObject>(q_func(), 0, QSGItemPrivate::data_append,
2712 QSGItemPrivate::data_count,
2713 QSGItemPrivate::data_at,
2714 QSGItemPrivate::data_clear);
2717 QRectF QSGItem::childrenRect()
2720 if (!d->_contents) {
2721 d->_contents = new QSGContents(this);
2722 if (d->componentComplete)
2723 d->_contents->complete();
2725 return d->_contents->rectF();
2728 QList<QSGItem *> QSGItem::childItems() const
2731 return d->childItems;
2734 bool QSGItem::clip() const
2736 return flags() & ItemClipsChildrenToShape;
2739 void QSGItem::setClip(bool c)
2744 setFlag(ItemClipsChildrenToShape, c);
2746 emit clipChanged(c);
2751 This function is called to handle this item's changes in
2752 geometry from \a oldGeometry to \a newGeometry. If the two
2753 geometries are the same, it doesn't do anything.
2755 void QSGItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
2760 QSGAnchorsPrivate::get(d->_anchors)->updateMe();
2762 for(int ii = 0; ii < d->changeListeners.count(); ++ii) {
2763 const QSGItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
2764 if (change.types & QSGItemPrivate::Geometry)
2765 change.listener->itemGeometryChanged(this, newGeometry, oldGeometry);
2768 if (newGeometry.x() != oldGeometry.x())
2770 if (newGeometry.y() != oldGeometry.y())
2772 if (newGeometry.width() != oldGeometry.width())
2773 emit widthChanged();
2774 if (newGeometry.height() != oldGeometry.height())
2775 emit heightChanged();
2779 Called by the rendering thread when it is time to sync the state of the QML objects with the
2780 scene graph objects. The function should return the root of the scene graph subtree for
2781 this item. \a oldNode is the node that was returned the last time the function was called.
2783 The main thread is blocked while this function is executed so it is safe to read
2784 values from the QSGItem instance and other objects in the main thread.
2786 \warning This is the only function in which it is allowed to make use of scene graph
2787 objects from the main thread. Use of scene graph objects outside this function will
2788 result in race conditions and potential crashes.
2791 QSGNode *QSGItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
2797 QSGTransformNode *QSGItemPrivate::createTransformNode()
2799 return new QSGTransformNode;
2802 void QSGItem::updatePolish()
2806 void QSGItemPrivate::removeItemChangeListener(QSGItemChangeListener *listener, ChangeTypes types)
2808 ChangeListener change(listener, types);
2809 changeListeners.removeOne(change);
2812 void QSGItem::keyPressEvent(QKeyEvent *event)
2817 void QSGItem::keyReleaseEvent(QKeyEvent *event)
2822 void QSGItem::inputMethodEvent(QInputMethodEvent *event)
2827 void QSGItem::focusInEvent(QFocusEvent *)
2831 void QSGItem::focusOutEvent(QFocusEvent *)
2835 void QSGItem::mousePressEvent(QMouseEvent *event)
2840 void QSGItem::mouseMoveEvent(QMouseEvent *event)
2845 void QSGItem::mouseReleaseEvent(QMouseEvent *event)
2850 void QSGItem::mouseDoubleClickEvent(QMouseEvent *event)
2852 mousePressEvent(event);
2855 void QSGItem::mouseUngrabEvent()
2860 void QSGItem::wheelEvent(QWheelEvent *event)
2865 void QSGItem::touchEvent(QTouchEvent *event)
2870 void QSGItem::hoverEnterEvent(QHoverEvent *event)
2875 void QSGItem::hoverMoveEvent(QHoverEvent *event)
2880 void QSGItem::hoverLeaveEvent(QHoverEvent *event)
2885 void QSGItem::dragMoveEvent(QSGDragEvent *event)
2887 event->setAccepted(false);
2890 void QSGItem::dragEnterEvent(QSGDragEvent *event)
2892 event->setAccepted(false);
2895 void QSGItem::dragExitEvent(QSGDragEvent *event)
2897 event->setAccepted(false);
2900 void QSGItem::dragDropEvent(QSGDragEvent *event)
2902 event->setAccepted(false);
2905 bool QSGItem::childMouseEventFilter(QSGItem *, QEvent *)
2910 void QSGItem::windowDeactivateEvent()
2912 foreach (QSGItem* item, childItems()) {
2913 item->windowDeactivateEvent();
2917 Qt::InputMethodHints QSGItem::inputMethodHints() const
2923 void QSGItem::setInputMethodHints(Qt::InputMethodHints hints)
2928 if (!d->canvas || d->canvas->activeFocusItem() != this)
2931 QInputPanel *p = qApp->inputPanel();
2932 if (p->inputItem() == this)
2933 qApp->inputPanel()->update(Qt::ImHints);
2936 void QSGItem::updateMicroFocus()
2938 QInputPanel *p = qApp->inputPanel();
2939 if (p->inputItem() == this)
2940 qApp->inputPanel()->update(Qt::ImQueryInput);
2943 QVariant QSGItem::inputMethodQuery(Qt::InputMethodQuery query) const
2950 v = (bool)(flags() & ItemAcceptsInputMethod);
2953 v = (int)inputMethodHints();
2955 case Qt::ImCursorRectangle:
2957 case Qt::ImCursorPosition:
2958 case Qt::ImSurroundingText:
2959 case Qt::ImCurrentSelection:
2960 case Qt::ImMaximumTextLength:
2961 case Qt::ImAnchorPosition:
2962 case Qt::ImPreferredLanguage:
2964 v = d->keyHandler->inputMethodQuery(query);
2972 QSGAnchorLine QSGItemPrivate::left() const
2974 return anchorLines()->left;
2977 QSGAnchorLine QSGItemPrivate::right() const
2979 return anchorLines()->right;
2982 QSGAnchorLine QSGItemPrivate::horizontalCenter() const
2984 return anchorLines()->hCenter;
2987 QSGAnchorLine QSGItemPrivate::top() const
2989 return anchorLines()->top;
2992 QSGAnchorLine QSGItemPrivate::bottom() const
2994 return anchorLines()->bottom;
2997 QSGAnchorLine QSGItemPrivate::verticalCenter() const
2999 return anchorLines()->vCenter;
3002 QSGAnchorLine QSGItemPrivate::baseline() const
3004 return anchorLines()->baseline;
3007 qreal QSGItem::baselineOffset() const
3010 if (!d->baselineOffset.isValid()) {
3013 return d->baselineOffset;
3016 void QSGItem::setBaselineOffset(qreal offset)
3019 if (offset == d->baselineOffset)
3022 d->baselineOffset = offset;
3024 for(int ii = 0; ii < d->changeListeners.count(); ++ii) {
3025 const QSGItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
3026 if (change.types & QSGItemPrivate::Geometry) {
3027 QSGAnchorsPrivate *anchor = change.listener->anchorPrivate();
3029 anchor->updateVerticalAnchors();
3032 emit baselineOffsetChanged(offset);
3035 void QSGItem::update()
3038 Q_ASSERT(flags() & ItemHasContents);
3039 d->dirty(QSGItemPrivate::Content);
3042 void QSGItem::polish()
3045 if (!d->polishScheduled) {
3046 d->polishScheduled = true;
3048 QSGCanvasPrivate *p = QSGCanvasPrivate::get(d->canvas);
3049 bool maybeupdate = p->itemsToPolish.isEmpty();
3050 p->itemsToPolish.insert(this);
3051 if (maybeupdate) d->canvas->maybeUpdate();
3056 void QSGItem::mapFromItem(QDeclarativeV8Function *args) const
3058 if (args->Length() != 0) {
3059 v8::Local<v8::Value> item = (*args)[0];
3060 QV8Engine *engine = args->engine();
3062 QSGItem *itemObj = 0;
3063 if (!item->IsNull())
3064 itemObj = qobject_cast<QSGItem*>(engine->toQObject(item));
3066 if (!itemObj && !item->IsNull()) {
3067 qmlInfo(this) << "mapFromItem() given argument \"" << engine->toString(item->ToString())
3068 << "\" which is neither null nor an Item";
3072 v8::Local<v8::Object> rv = v8::Object::New();
3073 args->returnValue(rv);
3075 qreal x = (args->Length() > 1)?(*args)[1]->NumberValue():0;
3076 qreal y = (args->Length() > 2)?(*args)[2]->NumberValue():0;
3078 QPointF p = mapFromItem(itemObj, QPointF(x, y));
3080 rv->Set(v8::String::New("x"), v8::Number::New(p.x()));
3081 rv->Set(v8::String::New("y"), v8::Number::New(p.y()));
3085 QTransform QSGItem::itemTransform(QSGItem *other, bool *ok) const
3089 // XXX todo - we need to be able to handle common parents better and detect
3093 QTransform t = d->itemToCanvasTransform();
3094 if (other) t *= QSGItemPrivate::get(other)->canvasToItemTransform();
3099 void QSGItem::mapToItem(QDeclarativeV8Function *args) const
3101 if (args->Length() != 0) {
3102 v8::Local<v8::Value> item = (*args)[0];
3103 QV8Engine *engine = args->engine();
3105 QSGItem *itemObj = 0;
3106 if (!item->IsNull())
3107 itemObj = qobject_cast<QSGItem*>(engine->toQObject(item));
3109 if (!itemObj && !item->IsNull()) {
3110 qmlInfo(this) << "mapToItem() given argument \"" << engine->toString(item->ToString())
3111 << "\" which is neither null nor an Item";
3115 v8::Local<v8::Object> rv = v8::Object::New();
3116 args->returnValue(rv);
3118 qreal x = (args->Length() > 1)?(*args)[1]->NumberValue():0;
3119 qreal y = (args->Length() > 2)?(*args)[2]->NumberValue():0;
3121 QPointF p = mapToItem(itemObj, QPointF(x, y));
3123 rv->Set(v8::String::New("x"), v8::Number::New(p.x()));
3124 rv->Set(v8::String::New("y"), v8::Number::New(p.y()));
3128 void QSGItem::forceActiveFocus()
3131 QSGItem *parent = parentItem();
3133 if (parent->flags() & QSGItem::ItemIsFocusScope) {
3134 parent->setFocus(true);
3136 parent = parent->parentItem();
3140 QSGItem *QSGItem::childAt(qreal x, qreal y) const
3142 // XXX todo - should this include transform etc.?
3143 const QList<QSGItem *> children = childItems();
3144 for (int i = children.count()-1; i >= 0; --i) {
3145 QSGItem *child = children.at(i);
3146 if (child->isVisible() && child->x() <= x
3147 && child->x() + child->width() >= x
3149 && child->y() + child->height() >= y)
3155 QDeclarativeListProperty<QObject> QSGItemPrivate::resources()
3157 return QDeclarativeListProperty<QObject>(q_func(), 0, QSGItemPrivate::resources_append,
3158 QSGItemPrivate::resources_count,
3159 QSGItemPrivate::resources_at,
3160 QSGItemPrivate::resources_clear);
3163 QDeclarativeListProperty<QSGItem> QSGItemPrivate::children()
3165 return QDeclarativeListProperty<QSGItem>(q_func(), 0, QSGItemPrivate::children_append,
3166 QSGItemPrivate::children_count,
3167 QSGItemPrivate::children_at,
3168 QSGItemPrivate::children_clear);
3172 QDeclarativeListProperty<QDeclarativeState> QSGItemPrivate::states()
3174 return _states()->statesProperty();
3177 QDeclarativeListProperty<QDeclarativeTransition> QSGItemPrivate::transitions()
3179 return _states()->transitionsProperty();
3182 QString QSGItemPrivate::state() const
3187 return _stateGroup->state();
3190 void QSGItemPrivate::setState(const QString &state)
3192 _states()->setState(state);
3195 QString QSGItem::state() const
3201 void QSGItem::setState(const QString &state)
3207 QDeclarativeListProperty<QSGTransform> QSGItem::transform()
3210 return QDeclarativeListProperty<QSGTransform>(this, 0, d->transform_append, d->transform_count,
3211 d->transform_at, d->transform_clear);
3214 void QSGItem::classBegin()
3217 d->componentComplete = false;
3219 d->_stateGroup->classBegin();
3221 d->_anchors->classBegin();
3224 void QSGItem::componentComplete()
3227 d->componentComplete = true;
3229 d->_stateGroup->componentComplete();
3231 d->_anchors->componentComplete();
3232 QSGAnchorsPrivate::get(d->_anchors)->updateOnComplete();
3235 d->keyHandler->componentComplete();
3237 d->_contents->complete();
3240 QDeclarativeStateGroup *QSGItemPrivate::_states()
3244 _stateGroup = new QDeclarativeStateGroup;
3245 if (!componentComplete)
3246 _stateGroup->classBegin();
3247 QObject::connect(_stateGroup, SIGNAL(stateChanged(QString)),
3248 q, SIGNAL(stateChanged(QString)));
3254 QSGItemPrivate::AnchorLines::AnchorLines(QSGItem *q)
3257 left.anchorLine = QSGAnchorLine::Left;
3259 right.anchorLine = QSGAnchorLine::Right;
3261 hCenter.anchorLine = QSGAnchorLine::HCenter;
3263 top.anchorLine = QSGAnchorLine::Top;
3265 bottom.anchorLine = QSGAnchorLine::Bottom;
3267 vCenter.anchorLine = QSGAnchorLine::VCenter;
3269 baseline.anchorLine = QSGAnchorLine::Baseline;
3272 QPointF QSGItemPrivate::computeTransformOrigin() const
3276 case QSGItem::TopLeft:
3277 return QPointF(0, 0);
3279 return QPointF(width / 2., 0);
3280 case QSGItem::TopRight:
3281 return QPointF(width, 0);
3283 return QPointF(0, height / 2.);
3284 case QSGItem::Center:
3285 return QPointF(width / 2., height / 2.);
3286 case QSGItem::Right:
3287 return QPointF(width, height / 2.);
3288 case QSGItem::BottomLeft:
3289 return QPointF(0, height);
3290 case QSGItem::Bottom:
3291 return QPointF(width / 2., height);
3292 case QSGItem::BottomRight:
3293 return QPointF(width, height);
3297 void QSGItemPrivate::transformChanged()
3301 void QSGItemPrivate::deliverKeyEvent(QKeyEvent *e)
3305 Q_ASSERT(e->isAccepted());
3307 if (e->type() == QEvent::KeyPress)
3308 keyHandler->keyPressed(e, false);
3310 keyHandler->keyReleased(e, false);
3312 if (e->isAccepted())
3318 if (e->type() == QEvent::KeyPress)
3319 q->keyPressEvent(e);
3321 q->keyReleaseEvent(e);
3323 if (e->isAccepted())
3329 if (e->type() == QEvent::KeyPress)
3330 keyHandler->keyPressed(e, true);
3332 keyHandler->keyReleased(e, true);
3336 void QSGItemPrivate::deliverInputMethodEvent(QInputMethodEvent *e)
3340 Q_ASSERT(e->isAccepted());
3342 keyHandler->inputMethodEvent(e, false);
3344 if (e->isAccepted())
3350 q->inputMethodEvent(e);
3352 if (e->isAccepted())
3358 keyHandler->inputMethodEvent(e, true);
3362 void QSGItemPrivate::deliverFocusEvent(QFocusEvent *e)
3366 if (e->type() == QEvent::FocusIn) {
3369 q->focusOutEvent(e);
3373 void QSGItemPrivate::deliverMouseEvent(QMouseEvent *e)
3377 Q_ASSERT(e->isAccepted());
3381 Q_ASSERT(!"Unknown event type");
3382 case QEvent::MouseMove:
3383 q->mouseMoveEvent(e);
3385 case QEvent::MouseButtonPress:
3386 q->mousePressEvent(e);
3388 case QEvent::MouseButtonRelease:
3389 q->mouseReleaseEvent(e);
3391 case QEvent::MouseButtonDblClick:
3392 q->mouseDoubleClickEvent(e);
3397 void QSGItemPrivate::deliverWheelEvent(QWheelEvent *e)
3403 void QSGItemPrivate::deliverTouchEvent(QTouchEvent *e)
3409 void QSGItemPrivate::deliverHoverEvent(QHoverEvent *e)
3414 Q_ASSERT(!"Unknown event type");
3415 case QEvent::HoverEnter:
3416 q->hoverEnterEvent(e);
3418 case QEvent::HoverLeave:
3419 q->hoverLeaveEvent(e);
3421 case QEvent::HoverMove:
3422 q->hoverMoveEvent(e);
3427 void QSGItemPrivate::deliverDragEvent(QSGDragEvent *e)
3430 switch (e->type()) {
3432 Q_ASSERT(!"Unknown event type");
3433 case QSGEvent::SGDragEnter:
3434 q->dragEnterEvent(e);
3436 case QSGEvent::SGDragExit:
3437 q->dragExitEvent(e);
3439 case QSGEvent::SGDragMove:
3440 q->dragMoveEvent(e);
3442 case QSGEvent::SGDragDrop:
3443 q->dragDropEvent(e);
3448 void QSGItem::itemChange(ItemChange change, const ItemChangeData &value)
3455 // XXX todo - do we want/need this anymore?
3456 // Note that it's now used for varying clip rect
3457 QRectF QSGItem::boundingRect() const
3460 return QRectF(0, 0, d->width, d->height);
3463 QSGItem::TransformOrigin QSGItem::transformOrigin() const
3469 void QSGItem::setTransformOrigin(TransformOrigin origin)
3472 if (origin == d->origin)
3476 d->dirty(QSGItemPrivate::TransformOrigin);
3478 emit transformOriginChanged(d->origin);
3481 QPointF QSGItem::transformOriginPoint() const
3484 if (!d->transformOriginPoint.isNull())
3485 return d->transformOriginPoint;
3486 return d->computeTransformOrigin();
3489 void QSGItem::setTransformOriginPoint(const QPointF &point)
3492 if (d->transformOriginPoint == point)
3495 d->transformOriginPoint = point;
3496 d->dirty(QSGItemPrivate::TransformOrigin);
3499 qreal QSGItem::z() const
3505 void QSGItem::setZ(qreal v)
3513 d->dirty(QSGItemPrivate::ZValue);
3515 QSGItemPrivate::get(d->parentItem)->dirty(QSGItemPrivate::ChildrenStackingChanged);
3522 \qmlproperty real QtQuick2::Item::rotation
3523 This property holds the rotation of the item in degrees clockwise.
3525 This specifies how many degrees to rotate the item around its transformOrigin.
3526 The default rotation is 0 degrees (i.e. not rotated at all).
3530 \o \image declarative-rotation.png
3535 width: 100; height: 100
3538 x: 25; y: 25; width: 50; height: 50
3545 \sa transform, Rotation
3549 \qmlproperty real QtQuick2::Item::scale
3550 This property holds the scale of the item.
3552 A scale of less than 1 means the item will be displayed smaller than
3553 normal, and a scale of greater than 1 means the item will be
3554 displayed larger than normal. A negative scale means the item will
3557 By default, items are displayed at a scale of 1 (i.e. at their
3560 Scaling is from the item's transformOrigin.
3564 \o \image declarative-scale.png
3569 width: 100; height: 100
3572 width: 25; height: 25
3576 x: 25; y: 25; width: 50; height: 50
3583 \sa transform, Scale
3587 \qmlproperty real QtQuick2::Item::opacity
3589 This property holds the opacity of the item. Opacity is specified as a
3590 number between 0 (fully transparent) and 1 (fully opaque). The default is 1.
3592 When this property is set, the specified opacity is also applied
3593 individually to child items. In almost all cases this is what you want,
3594 but in some cases it may produce undesired results. For example in the
3595 second set of rectangles below, the red rectangle has specified an opacity
3596 of 0.5, which affects the opacity of its blue child rectangle even though
3597 the child has not specified an opacity.
3601 \o \image declarative-item_opacity1.png
3607 width: 100; height: 100
3610 x: 50; y: 50; width: 100; height: 100
3616 \o \image declarative-item_opacity2.png
3623 width: 100; height: 100
3626 x: 50; y: 50; width: 100; height: 100
3633 If an item's opacity is set to 0, the item will no longer receive mouse
3634 events, but will continue to receive key events and will retain the keyboard
3635 \l focus if it has been set. (In contrast, setting the \l visible property
3636 to \c false stops both mouse and keyboard events, and also removes focus
3641 Returns a value indicating whether mouse input should
3642 remain with this item exclusively.
3644 \sa setKeepMouseGrab()
3647 qreal QSGItem::rotation() const
3653 void QSGItem::setRotation(qreal r)
3656 if (d->rotation == r)
3661 d->dirty(QSGItemPrivate::BasicTransform);
3663 d->itemChange(ItemRotationHasChanged, r);
3665 emit rotationChanged();
3668 qreal QSGItem::scale() const
3674 void QSGItem::setScale(qreal s)
3682 d->dirty(QSGItemPrivate::BasicTransform);
3684 emit scaleChanged();
3687 qreal QSGItem::opacity() const
3693 void QSGItem::setOpacity(qreal o)
3696 if (d->opacity == o)
3701 d->dirty(QSGItemPrivate::OpacityValue);
3703 d->itemChange(ItemOpacityHasChanged, o);
3705 emit opacityChanged();
3708 bool QSGItem::isVisible() const
3711 return d->effectiveVisible;
3714 void QSGItem::setVisible(bool v)
3717 if (v == d->explicitVisible)
3720 d->explicitVisible = v;
3722 d->setEffectiveVisibleRecur(d->calcEffectiveVisible());
3725 bool QSGItem::isEnabled() const
3728 return d->effectiveEnable;
3731 void QSGItem::setEnabled(bool e)
3734 if (e == d->explicitEnable)
3737 d->explicitEnable = e;
3739 d->setEffectiveEnableRecur(d->calcEffectiveEnable());
3742 bool QSGItemPrivate::calcEffectiveVisible() const
3744 // XXX todo - Should the effective visible of an element with no parent just be the current
3745 // effective visible? This would prevent pointless re-processing in the case of an element
3746 // moving to/from a no-parent situation, but it is different from what graphics view does.
3747 return explicitVisible && (!parentItem || QSGItemPrivate::get(parentItem)->effectiveVisible);
3750 void QSGItemPrivate::setEffectiveVisibleRecur(bool newEffectiveVisible)
3754 if (newEffectiveVisible && !explicitVisible) {
3755 // This item locally overrides visibility
3759 if (newEffectiveVisible == effectiveVisible) {
3760 // No change necessary
3764 effectiveVisible = newEffectiveVisible;
3766 if (parentItem) QSGItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
3769 QSGCanvasPrivate *canvasPriv = QSGCanvasPrivate::get(canvas);
3770 if (canvasPriv->mouseGrabberItem == q)
3774 for (int ii = 0; ii < childItems.count(); ++ii)
3775 QSGItemPrivate::get(childItems.at(ii))->setEffectiveVisibleRecur(newEffectiveVisible);
3777 for(int ii = 0; ii < changeListeners.count(); ++ii) {
3778 const QSGItemPrivate::ChangeListener &change = changeListeners.at(ii);
3779 if (change.types & QSGItemPrivate::Visibility)
3780 change.listener->itemVisibilityChanged(q);
3783 emit q->visibleChanged();
3786 bool QSGItemPrivate::calcEffectiveEnable() const
3788 // XXX todo - Should the effective enable of an element with no parent just be the current
3789 // effective enable? This would prevent pointless re-processing in the case of an element
3790 // moving to/from a no-parent situation, but it is different from what graphics view does.
3791 return explicitEnable && (!parentItem || QSGItemPrivate::get(parentItem)->effectiveEnable);
3794 void QSGItemPrivate::setEffectiveEnableRecur(bool newEffectiveEnable)
3798 // XXX todo - need to fixup focus
3800 if (newEffectiveEnable && !explicitEnable) {
3801 // This item locally overrides enable
3805 if (newEffectiveEnable == effectiveEnable) {
3806 // No change necessary
3810 effectiveEnable = newEffectiveEnable;
3813 QSGCanvasPrivate *canvasPriv = QSGCanvasPrivate::get(canvas);
3814 if (canvasPriv->mouseGrabberItem == q)
3818 for (int ii = 0; ii < childItems.count(); ++ii)
3819 QSGItemPrivate::get(childItems.at(ii))->setEffectiveEnableRecur(newEffectiveEnable);
3821 emit q->enabledChanged();
3824 QString QSGItemPrivate::dirtyToString() const
3826 #define DIRTY_TO_STRING(value) if (dirtyAttributes & value) { \
3827 if (!rv.isEmpty()) \
3828 rv.append(QLatin1String("|")); \
3829 rv.append(QLatin1String(#value)); \
3832 // QString rv = QLatin1String("0x") + QString::number(dirtyAttributes, 16);
3835 DIRTY_TO_STRING(TransformOrigin);
3836 DIRTY_TO_STRING(Transform);
3837 DIRTY_TO_STRING(BasicTransform);
3838 DIRTY_TO_STRING(Position);
3839 DIRTY_TO_STRING(Size);
3840 DIRTY_TO_STRING(ZValue);
3841 DIRTY_TO_STRING(Content);
3842 DIRTY_TO_STRING(Smooth);
3843 DIRTY_TO_STRING(OpacityValue);
3844 DIRTY_TO_STRING(ChildrenChanged);
3845 DIRTY_TO_STRING(ChildrenStackingChanged);
3846 DIRTY_TO_STRING(ParentChanged);
3847 DIRTY_TO_STRING(Clip);
3848 DIRTY_TO_STRING(Canvas);
3849 DIRTY_TO_STRING(EffectReference);
3850 DIRTY_TO_STRING(Visible);
3851 DIRTY_TO_STRING(HideReference);
3856 void QSGItemPrivate::dirty(DirtyType type)
3859 if (type & (TransformOrigin | Transform | BasicTransform | Position | Size))
3862 if (!(dirtyAttributes & type) || (canvas && !prevDirtyItem)) {
3863 dirtyAttributes |= type;
3866 QSGCanvasPrivate::get(canvas)->dirtyItem(q);
3871 void QSGItemPrivate::addToDirtyList()
3876 if (!prevDirtyItem) {
3877 Q_ASSERT(!nextDirtyItem);
3879 QSGCanvasPrivate *p = QSGCanvasPrivate::get(canvas);
3880 nextDirtyItem = p->dirtyItemList;
3881 if (nextDirtyItem) QSGItemPrivate::get(nextDirtyItem)->prevDirtyItem = &nextDirtyItem;
3882 prevDirtyItem = &p->dirtyItemList;
3883 p->dirtyItemList = q;
3886 Q_ASSERT(prevDirtyItem);
3889 void QSGItemPrivate::removeFromDirtyList()
3891 if (prevDirtyItem) {
3892 if (nextDirtyItem) QSGItemPrivate::get(nextDirtyItem)->prevDirtyItem = prevDirtyItem;
3893 *prevDirtyItem = nextDirtyItem;
3897 Q_ASSERT(!prevDirtyItem);
3898 Q_ASSERT(!nextDirtyItem);
3901 void QSGItemPrivate::refFromEffectItem(bool hide)
3904 if (1 == effectRefCount) {
3905 dirty(EffectReference);
3906 if (parentItem) QSGItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
3909 if (++hideRefCount == 1)
3910 dirty(HideReference);
3914 void QSGItemPrivate::derefFromEffectItem(bool unhide)
3916 Q_ASSERT(effectRefCount);
3918 if (0 == effectRefCount) {
3919 dirty(EffectReference);
3920 if (parentItem) QSGItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
3923 if (--hideRefCount == 0)
3924 dirty(HideReference);
3928 void QSGItemPrivate::itemChange(QSGItem::ItemChange change, const QSGItem::ItemChangeData &data)
3932 case QSGItem::ItemChildAddedChange:
3933 q->itemChange(change, data);
3934 if (_contents && componentComplete)
3935 _contents->childAdded(data.item);
3936 for(int ii = 0; ii < changeListeners.count(); ++ii) {
3937 const QSGItemPrivate::ChangeListener &change = changeListeners.at(ii);
3938 if (change.types & QSGItemPrivate::Children) {
3939 change.listener->itemChildAdded(q, data.item);
3943 case QSGItem::ItemChildRemovedChange:
3944 q->itemChange(change, data);
3945 if (_contents && componentComplete)
3946 _contents->childRemoved(data.item);
3947 for(int ii = 0; ii < changeListeners.count(); ++ii) {
3948 const QSGItemPrivate::ChangeListener &change = changeListeners.at(ii);
3949 if (change.types & QSGItemPrivate::Children) {
3950 change.listener->itemChildRemoved(q, data.item);
3954 case QSGItem::ItemSceneChange:
3955 q->itemChange(change, data);
3957 case QSGItem::ItemVisibleHasChanged:
3958 q->itemChange(change, data);
3959 for(int ii = 0; ii < changeListeners.count(); ++ii) {
3960 const QSGItemPrivate::ChangeListener &change = changeListeners.at(ii);
3961 if (change.types & QSGItemPrivate::Visibility) {
3962 change.listener->itemVisibilityChanged(q);
3966 case QSGItem::ItemParentHasChanged:
3967 q->itemChange(change, data);
3968 for(int ii = 0; ii < changeListeners.count(); ++ii) {
3969 const QSGItemPrivate::ChangeListener &change = changeListeners.at(ii);
3970 if (change.types & QSGItemPrivate::Parent) {
3971 change.listener->itemParentChanged(q, data.item);
3975 case QSGItem::ItemOpacityHasChanged:
3976 q->itemChange(change, data);
3977 for(int ii = 0; ii < changeListeners.count(); ++ii) {
3978 const QSGItemPrivate::ChangeListener &change = changeListeners.at(ii);
3979 if (change.types & QSGItemPrivate::Opacity) {
3980 change.listener->itemOpacityChanged(q);
3984 case QSGItem::ItemActiveFocusHasChanged:
3985 q->itemChange(change, data);
3987 case QSGItem::ItemRotationHasChanged:
3988 q->itemChange(change, data);
3989 for(int ii = 0; ii < changeListeners.count(); ++ii) {
3990 const QSGItemPrivate::ChangeListener &change = changeListeners.at(ii);
3991 if (change.types & QSGItemPrivate::Rotation) {
3992 change.listener->itemRotationChanged(q);
4000 \property QSGItem::smooth
4001 \brief whether the item is smoothly transformed.
4003 This property is provided purely for the purpose of optimization. Turning
4004 smooth transforms off is faster, but looks worse; turning smooth
4005 transformations on is slower, but looks better.
4007 By default smooth transformations are off.
4011 Returns true if the item should be drawn with antialiasing and
4012 smooth pixmap filtering, false otherwise.
4014 The default is false.
4018 bool QSGItem::smooth() const
4025 Sets whether the item should be drawn with antialiasing and
4026 smooth pixmap filtering to \a smooth.
4030 void QSGItem::setSmooth(bool smooth)
4033 if (d->smooth == smooth)
4037 d->dirty(QSGItemPrivate::Smooth);
4039 emit smoothChanged(smooth);
4042 QSGItem::Flags QSGItem::flags() const
4045 return (QSGItem::Flags)d->flags;
4048 void QSGItem::setFlag(Flag flag, bool enabled)
4052 setFlags((Flags)(d->flags | (quint32)flag));
4054 setFlags((Flags)(d->flags & ~(quint32)flag));
4057 void QSGItem::setFlags(Flags flags)
4061 if ((flags & ItemIsFocusScope) != (d->flags & ItemIsFocusScope)) {
4062 if (flags & ItemIsFocusScope && !d->childItems.isEmpty() && d->canvas) {
4063 qWarning("QSGItem: Cannot set FocusScope once item has children and is in a canvas.");
4064 flags &= ~ItemIsFocusScope;
4065 } else if (d->flags & ItemIsFocusScope) {
4066 qWarning("QSGItem: Cannot unset FocusScope flag.");
4067 flags |= ItemIsFocusScope;
4071 if ((flags & ItemClipsChildrenToShape ) != (d->flags & ItemClipsChildrenToShape))
4072 d->dirty(QSGItemPrivate::Clip);
4077 qreal QSGItem::x() const
4083 qreal QSGItem::y() const
4089 QPointF QSGItem::pos() const
4092 return QPointF(d->x, d->y);
4095 void QSGItem::setX(qreal v)
4104 d->dirty(QSGItemPrivate::Position);
4106 geometryChanged(QRectF(x(), y(), width(), height()),
4107 QRectF(oldx, y(), width(), height()));
4110 void QSGItem::setY(qreal v)
4119 d->dirty(QSGItemPrivate::Position);
4121 geometryChanged(QRectF(x(), y(), width(), height()),
4122 QRectF(x(), oldy, width(), height()));
4125 void QSGItem::setPos(const QPointF &pos)
4128 if (QPointF(d->x, d->y) == pos)
4137 d->dirty(QSGItemPrivate::Position);
4139 geometryChanged(QRectF(x(), y(), width(), height()),
4140 QRectF(oldx, oldy, width(), height()));
4143 qreal QSGItem::width() const
4149 void QSGItem::setWidth(qreal w)
4155 d->widthValid = true;
4159 qreal oldWidth = d->width;
4162 d->dirty(QSGItemPrivate::Size);
4164 geometryChanged(QRectF(x(), y(), width(), height()),
4165 QRectF(x(), y(), oldWidth, height()));
4168 void QSGItem::resetWidth()
4171 d->widthValid = false;
4172 setImplicitWidth(implicitWidth());
4175 void QSGItemPrivate::implicitWidthChanged()
4178 emit q->implicitWidthChanged();
4181 qreal QSGItemPrivate::getImplicitWidth() const
4183 return implicitWidth;
4186 Returns the width of the item that is implied by other properties that determine the content.
4188 qreal QSGItem::implicitWidth() const
4191 return d->getImplicitWidth();
4195 \qmlproperty real QtQuick2::Item::implicitWidth
4196 \qmlproperty real QtQuick2::Item::implicitHeight
4198 Defines the natural width or height of the Item if no \l width or \l height is specified.
4200 The default implicit size for most items is 0x0, however some elements have an inherent
4201 implicit size which cannot be overridden, e.g. Image, Text.
4203 Setting the implicit size is useful for defining components that have a preferred size
4204 based on their content, for example:
4211 property alias icon: image.source
4212 property alias label: text.text
4213 implicitWidth: text.implicitWidth + image.implicitWidth
4214 implicitHeight: Math.max(text.implicitHeight, image.implicitHeight)
4219 anchors.left: image.right; anchors.right: parent.right
4220 anchors.verticalCenter: parent.verticalCenter
4225 \bold Note: using implicitWidth of Text or TextEdit and setting the width explicitly
4226 incurs a performance penalty as the text must be laid out twice.
4230 Sets the implied width of the item to \a w.
4231 This is the width implied by other properties that determine the content.
4233 void QSGItem::setImplicitWidth(qreal w)
4236 bool changed = w != d->implicitWidth;
4237 d->implicitWidth = w;
4238 if (d->width == w || widthValid()) {
4240 d->implicitWidthChanged();
4244 qreal oldWidth = d->width;
4247 d->dirty(QSGItemPrivate::Size);
4249 geometryChanged(QRectF(x(), y(), width(), height()),
4250 QRectF(x(), y(), oldWidth, height()));
4253 d->implicitWidthChanged();
4257 Returns whether the width property has been set explicitly.
4259 bool QSGItem::widthValid() const
4262 return d->widthValid;
4265 qreal QSGItem::height() const
4271 void QSGItem::setHeight(qreal h)
4277 d->heightValid = true;
4281 qreal oldHeight = d->height;
4284 d->dirty(QSGItemPrivate::Size);
4286 geometryChanged(QRectF(x(), y(), width(), height()),
4287 QRectF(x(), y(), width(), oldHeight));
4290 void QSGItem::resetHeight()
4293 d->heightValid = false;
4294 setImplicitHeight(implicitHeight());
4297 void QSGItemPrivate::implicitHeightChanged()
4300 emit q->implicitHeightChanged();
4303 qreal QSGItemPrivate::getImplicitHeight() const
4305 return implicitHeight;
4309 Returns the height of the item that is implied by other properties that determine the content.
4311 qreal QSGItem::implicitHeight() const
4314 return d->getImplicitHeight();
4319 Sets the implied height of the item to \a h.
4320 This is the height implied by other properties that determine the content.
4322 void QSGItem::setImplicitHeight(qreal h)
4325 bool changed = h != d->implicitHeight;
4326 d->implicitHeight = h;
4327 if (d->height == h || heightValid()) {
4329 d->implicitHeightChanged();
4333 qreal oldHeight = d->height;
4336 d->dirty(QSGItemPrivate::Size);
4338 geometryChanged(QRectF(x(), y(), width(), height()),
4339 QRectF(x(), y(), width(), oldHeight));
4342 d->implicitHeightChanged();
4346 Returns whether the height property has been set explicitly.
4348 bool QSGItem::heightValid() const
4351 return d->heightValid;
4354 void QSGItem::setSize(const QSizeF &size)
4357 d->heightValid = true;
4358 d->widthValid = true;
4360 if (QSizeF(d->width, d->height) == size)
4363 qreal oldHeight = d->height;
4364 qreal oldWidth = d->width;
4365 d->height = size.height();
4366 d->width = size.width();
4368 d->dirty(QSGItemPrivate::Size);
4370 geometryChanged(QRectF(x(), y(), width(), height()),
4371 QRectF(x(), y(), oldWidth, oldHeight));
4374 bool QSGItem::hasActiveFocus() const
4377 return d->activeFocus;
4380 bool QSGItem::hasFocus() const
4386 void QSGItem::setFocus(bool focus)
4389 if (d->focus == focus)
4393 // Need to find our nearest focus scope
4394 QSGItem *scope = parentItem();
4395 while (scope && !scope->isFocusScope())
4396 scope = scope->parentItem();
4398 QSGCanvasPrivate::get(d->canvas)->setFocusInScope(scope, this);
4400 QSGCanvasPrivate::get(d->canvas)->clearFocusInScope(scope, this);
4403 emit focusChanged(focus);
4407 bool QSGItem::isFocusScope() const
4409 return flags() & ItemIsFocusScope;
4412 QSGItem *QSGItem::scopedFocusItem() const
4415 if (!isFocusScope())
4418 return d->subFocusItem;
4422 Qt::MouseButtons QSGItem::acceptedMouseButtons() const
4425 return d->acceptedMouseButtons;
4428 void QSGItem::setAcceptedMouseButtons(Qt::MouseButtons buttons)
4431 d->acceptedMouseButtons = buttons;
4434 bool QSGItem::filtersChildMouseEvents() const
4437 return d->filtersChildMouseEvents;
4440 void QSGItem::setFiltersChildMouseEvents(bool filter)
4443 d->filtersChildMouseEvents = filter;
4446 bool QSGItem::isUnderMouse() const
4452 QPoint cursorPos = QCursor::pos();
4453 if (QRectF(0, 0, width(), height()).contains(mapFromScene(cursorPos))) // ### refactor: d->canvas->mapFromGlobal(cursorPos))))
4458 bool QSGItem::acceptHoverEvents() const
4461 return d->hoverEnabled;
4464 void QSGItem::setAcceptHoverEvents(bool enabled)
4467 d->hoverEnabled = enabled;
4470 void QSGItem::grabMouse()
4475 QSGCanvasPrivate *canvasPriv = QSGCanvasPrivate::get(d->canvas);
4476 if (canvasPriv->mouseGrabberItem == this)
4479 QSGItem *oldGrabber = canvasPriv->mouseGrabberItem;
4480 canvasPriv->mouseGrabberItem = this;
4482 oldGrabber->mouseUngrabEvent();
4485 void QSGItem::ungrabMouse()
4490 QSGCanvasPrivate *canvasPriv = QSGCanvasPrivate::get(d->canvas);
4491 if (canvasPriv->mouseGrabberItem != this) {
4492 qWarning("QSGItem::ungrabMouse(): Item is not the mouse grabber.");
4496 canvasPriv->mouseGrabberItem = 0;
4500 bool QSGItem::keepMouseGrab() const
4503 return d->keepMouse;
4507 The flag indicating whether the mouse should remain
4508 with this item is set to \a keep.
4510 This is useful for items that wish to grab and keep mouse
4511 interaction following a predefined gesture. For example,
4512 an item that is interested in horizontal mouse movement
4513 may set keepMouseGrab to true once a threshold has been
4514 exceeded. Once keepMouseGrab has been set to true, filtering
4515 items will not react to mouse events.
4517 If the item does not indicate that it wishes to retain mouse grab,
4518 a filtering item may steal the grab. For example, Flickable may attempt
4519 to steal a mouse grab if it detects that the user has begun to
4524 void QSGItem::setKeepMouseGrab(bool keep)
4527 d->keepMouse = keep;
4531 \qmlmethod object QtQuick2::Item::mapFromItem(Item item, real x, real y)
4533 Maps the point (\a x, \a y), which is in \a item's coordinate system, to
4534 this item's coordinate system, and returns an object with \c x and \c y
4535 properties matching the mapped cooordinate.
4537 If \a item is a \c null value, this maps the point from the coordinate
4538 system of the root QML view.
4541 \qmlmethod object QtQuick2::Item::mapToItem(Item item, real x, real y)
4543 Maps the point (\a x, \a y), which is in this item's coordinate system, to
4544 \a item's coordinate system, and returns an object with \c x and \c y
4545 properties matching the mapped cooordinate.
4547 If \a item is a \c null value, this maps \a x and \a y to the coordinate
4548 system of the root QML view.
4550 QPointF QSGItem::mapToItem(const QSGItem *item, const QPointF &point) const
4552 QPointF p = mapToScene(point);
4554 p = item->mapFromScene(p);
4558 QPointF QSGItem::mapToScene(const QPointF &point) const
4561 return d->itemToCanvasTransform().map(point);
4564 QRectF QSGItem::mapRectToItem(const QSGItem *item, const QRectF &rect) const
4567 QTransform t = d->itemToCanvasTransform();
4569 t *= QSGItemPrivate::get(item)->canvasToItemTransform();
4570 return t.mapRect(rect);
4573 QRectF QSGItem::mapRectToScene(const QRectF &rect) const
4576 return d->itemToCanvasTransform().mapRect(rect);
4579 QPointF QSGItem::mapFromItem(const QSGItem *item, const QPointF &point) const
4581 QPointF p = item?item->mapToScene(point):point;
4582 return mapFromScene(p);
4585 QPointF QSGItem::mapFromScene(const QPointF &point) const
4588 return d->canvasToItemTransform().map(point);
4591 QRectF QSGItem::mapRectFromItem(const QSGItem *item, const QRectF &rect) const
4594 QTransform t = item?QSGItemPrivate::get(item)->itemToCanvasTransform():QTransform();
4595 t *= d->canvasToItemTransform();
4596 return t.mapRect(rect);
4599 QRectF QSGItem::mapRectFromScene(const QRectF &rect) const
4602 return d->canvasToItemTransform().mapRect(rect);
4607 \qmlmethod QtQuick2::Item::forceActiveFocus()
4609 Forces active focus on the item.
4611 This method sets focus on the item and makes sure that all the focus scopes
4612 higher in the object hierarchy are also given the focus.
4616 Forces active focus on the item.
4618 This method sets focus on the item and makes sure that all the focus scopes
4619 higher in the object hierarchy are also given the focus.
4623 \qmlmethod QtQuick2::Item::childAt(real x, real y)
4625 Returns the visible child item at point (\a x, \a y), which is in this
4626 item's coordinate system, or \c null if there is no such item.
4630 Returns the visible child item at point (\a x, \a y), which is in this
4631 item's coordinate system, or 0 if there is no such item.
4635 \qmlproperty list<State> QtQuick2::Item::states
4636 This property holds a list of states defined by the item.
4652 \sa {qmlstate}{States}
4655 \qmlproperty list<Transition> QtQuick2::Item::transitions
4656 This property holds a list of transitions defined by the item.
4672 \sa {QML Animation and Transitions}{Transitions}
4675 \qmlproperty list<Filter> QtQuick2::Item::filter
4676 This property holds a list of graphical filters to be applied to the item.
4678 \l {Filter}{Filters} include things like \l {Blur}{blurring}
4679 the item, or giving it a \l Reflection. Some
4680 filters may not be available on all canvases; if a filter is not
4681 available on a certain canvas, it will simply not be applied for
4682 that canvas (but the QML will still be considered valid).
4700 \qmlproperty bool QtQuick2::Item::clip
4701 This property holds whether clipping is enabled. The default clip value is \c false.
4703 If clipping is enabled, an item will clip its own painting, as well
4704 as the painting of its children, to its bounding rectangle.
4706 Non-rectangular clipping regions are not supported for performance reasons.
4710 \property QSGItem::clip
4711 This property holds whether clipping is enabled. The default clip value is \c false.
4713 If clipping is enabled, an item will clip its own painting, as well
4714 as the painting of its children, to its bounding rectangle. If you set
4715 clipping during an item's paint operation, remember to re-set it to
4716 prevent clipping the rest of your scene.
4718 Non-rectangular clipping regions are not supported for performance reasons.
4722 \qmlproperty string QtQuick2::Item::state
4724 This property holds the name of the current state of the item.
4726 This property is often used in scripts to change between states. For
4731 if (button.state == 'On')
4732 button.state = 'Off';
4734 button.state = 'On';
4738 If the item is in its base state (i.e. no explicit state has been
4739 set), \c state will be a blank string. Likewise, you can return an
4740 item to its base state by setting its current state to \c ''.
4742 \sa {qmlstates}{States}
4746 \qmlproperty list<Transform> QtQuick2::Item::transform
4747 This property holds the list of transformations to apply.
4749 For more information see \l Transform.
4753 \enum QSGItem::TransformOrigin
4755 Controls the point about which simple transforms like scale apply.
4757 \value TopLeft The top-left corner of the item.
4758 \value Top The center point of the top of the item.
4759 \value TopRight The top-right corner of the item.
4760 \value Left The left most point of the vertical middle.
4761 \value Center The center of the item.
4762 \value Right The right most point of the vertical middle.
4763 \value BottomLeft The bottom-left corner of the item.
4764 \value Bottom The center point of the bottom of the item.
4765 \value BottomRight The bottom-right corner of the item.
4770 \qmlproperty bool QtQuick2::Item::activeFocus
4772 This property indicates whether the item has active focus.
4774 An item with active focus will receive keyboard input,
4775 or is a FocusScope ancestor of the item that will receive keyboard input.
4777 Usually, activeFocus is gained by setting focus on an item and its enclosing
4778 FocusScopes. In the following example \c input will have activeFocus.
4791 \sa focus, {qmlfocus}{Keyboard Focus}
4795 \qmlproperty bool QtQuick2::Item::focus
4796 This property indicates whether the item has focus within the enclosing focus scope. If true, this item
4797 will gain active focus when the enclosing focus scope gains active focus.
4798 In the following example, \c input will be given active focus when \c scope gains active focus.
4811 For the purposes of this property, the scene as a whole is assumed to act like a focus scope.
4812 On a practical level, that means the following QML will give active focus to \c input on startup.
4823 \sa activeFocus, {qmlfocus}{Keyboard Focus}
4828 \property QSGItem::anchors
4833 \property QSGItem::left
4838 \property QSGItem::right
4843 \property QSGItem::horizontalCenter
4848 \property QSGItem::top
4853 \property QSGItem::bottom
4858 \property QSGItem::verticalCenter
4863 \property QSGItem::focus
4868 \property QSGItem::transform
4873 \property QSGItem::transformOrigin
4878 \property QSGItem::activeFocus
4883 \property QSGItem::baseline
4888 \property QSGItem::data
4893 \property QSGItem::resources
4898 \property QSGItem::state
4903 \property QSGItem::states
4908 \property QSGItem::transformOriginPoint
4913 \property QSGItem::transitions
4917 bool QSGItem::event(QEvent *ev)
4920 if (ev->type() == QEvent::PolishRequest) {
4922 d->polishScheduled = false;
4926 return QObject::event(ev);
4929 if (ev->type() == QEvent::InputMethodQuery) {
4930 QInputMethodQueryEvent *query = static_cast<QInputMethodQueryEvent *>(ev);
4931 Qt::InputMethodQueries queries = query->queries();
4932 for (uint i = 0; i < 32; ++i) {
4933 Qt::InputMethodQuery q = (Qt::InputMethodQuery)(int)(queries & (1<<i));
4935 QVariant v = inputMethodQuery(q);
4936 query->setValue(q, v);
4941 } else if (ev->type() == QEvent::InputMethod) {
4942 inputMethodEvent(static_cast<QInputMethodEvent *>(ev));
4945 return QObject::event(ev);
4948 #ifndef QT_NO_DEBUG_STREAM
4949 QDebug operator<<(QDebug debug, QSGItem *item)
4952 debug << "QSGItem(0)";
4956 debug << item->metaObject()->className() << "(this =" << ((void*)item)
4957 << ", name=" << item->objectName()
4958 << ", parent =" << ((void*)item->parentItem())
4959 << ", geometry =" << QRectF(item->pos(), QSizeF(item->width(), item->height()))
4960 << ", z =" << item->z() << ')';
4965 qint64 QSGItemPrivate::consistentTime = -1;
4966 void QSGItemPrivate::setConsistentTime(qint64 t)
4971 class QElapsedTimerConsistentTimeHack
4975 t1 = QSGItemPrivate::consistentTime;
4979 return QSGItemPrivate::consistentTime - t1;
4982 qint64 val = QSGItemPrivate::consistentTime - t1;
4983 t1 = QSGItemPrivate::consistentTime;
4993 void QSGItemPrivate::start(QElapsedTimer &t)
4995 if (QSGItemPrivate::consistentTime == -1)
4998 ((QElapsedTimerConsistentTimeHack*)&t)->start();
5001 qint64 QSGItemPrivate::elapsed(QElapsedTimer &t)
5003 if (QSGItemPrivate::consistentTime == -1)
5006 return ((QElapsedTimerConsistentTimeHack*)&t)->elapsed();
5009 qint64 QSGItemPrivate::restart(QElapsedTimer &t)
5011 if (QSGItemPrivate::consistentTime == -1)
5014 return ((QElapsedTimerConsistentTimeHack*)&t)->restart();
5018 \fn bool QSGItem::isTextureProvider() const
5020 Returns true if this item is a texture provider. The default
5021 implementation returns false.
5023 This function can be called from any thread.
5027 \fn QSGTextureProvider *QSGItem::textureProvider() const
5029 Returns the texture provider for an item. The default implementation
5032 This function may only be called on the rendering thread.
5037 #include <moc_qsgitem.cpp>