source: trunk/src/declarative/graphicsitems/qdeclarativeitem.cpp@ 846

Last change on this file since 846 was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

File size: 91.6 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the QtDeclarative module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "private/qdeclarativeitem_p.h"
43#include "qdeclarativeitem.h"
44
45#include "private/qdeclarativeevents_p_p.h"
46#include <private/qdeclarativeengine_p.h>
47#include <private/qgraphicsitem_p.h>
48
49#include <qdeclarativeengine.h>
50#include <qdeclarativeopenmetaobject_p.h>
51#include <qdeclarativestate_p.h>
52#include <qdeclarativeview.h>
53#include <qdeclarativestategroup_p.h>
54#include <qdeclarativecomponent.h>
55#include <qdeclarativeinfo.h>
56
57#include <QDebug>
58#include <QPen>
59#include <QEvent>
60#include <QGraphicsSceneMouseEvent>
61#include <QtCore/qnumeric.h>
62#include <QtScript/qscriptengine.h>
63#include <QtGui/qgraphicstransform.h>
64#include <qlistmodelinterface_p.h>
65
66#include <float.h>
67
68QT_BEGIN_NAMESPACE
69
70/*!
71 \qmlclass Transform QGraphicsTransform
72 \ingroup qml-transform-elements
73 \since 4.7
74 \brief The Transform elements provide a way of building advanced transformations on Items.
75
76 The Transform element is a base type which cannot be instantiated directly.
77 The following concrete Transform types are available:
78
79 \list
80 \o \l Rotation
81 \o \l Scale
82 \o \l Translate
83 \endlist
84
85 The Transform elements let you create and control advanced transformations that can be configured
86 independently using specialized properties.
87
88 You can assign any number of Transform elements to an \l Item. Each Transform is applied in order,
89 one at a time.
90*/
91
92/*!
93 \qmlclass Translate QDeclarativeTranslate
94 \ingroup qml-transform-elements
95 \since 4.7
96 \brief The Translate object provides a way to move an Item without changing its x or y properties.
97
98 The Translate object provides independent control over position in addition to the Item's x and y properties.
99
100 The following example moves the Y axis of the \l Rectangle elements while still allowing the \l Row element
101 to lay the items out as if they had not been transformed:
102 \qml
103 import QtQuick 1.0
104
105 Row {
106 Rectangle {
107 width: 100; height: 100
108 color: "blue"
109 transform: Translate { y: 20 }
110 }
111 Rectangle {
112 width: 100; height: 100
113 color: "red"
114 transform: Translate { y: -20 }
115 }
116 }
117 \endqml
118
119 \image translate.png
120*/
121
122/*!
123 \qmlproperty real Translate::x
124
125 The translation along the X axis.
126*/
127
128/*!
129 \qmlproperty real Translate::y
130
131 The translation along the Y axis.
132*/
133
134/*!
135 \qmlclass Scale QGraphicsScale
136 \ingroup qml-transform-elements
137 \since 4.7
138 \brief The Scale element provides a way to scale an Item.
139
140 The Scale element gives more control over scaling than using \l Item's \l{Item::scale}{scale} property. Specifically,
141 it allows a different scale for the x and y axes, and allows the scale to be relative to an
142 arbitrary point.
143
144 The following example scales the X axis of the Rectangle, relative to its interior point 25, 25:
145 \qml
146 Rectangle {
147 width: 100; height: 100
148 color: "blue"
149 transform: Scale { origin.x: 25; origin.y: 25; xScale: 3}
150 }
151 \endqml
152
153 \sa Rotation, Translate
154*/
155
156/*!
157 \qmlproperty real Scale::origin.x
158 \qmlproperty real Scale::origin.y
159
160 The point that the item is scaled from (i.e., the point that stays fixed relative to the parent as
161 the rest of the item grows). By default the origin is 0, 0.
162*/
163
164/*!
165 \qmlproperty real Scale::xScale
166
167 The scaling factor for the X axis.
168*/
169
170/*!
171 \qmlproperty real Scale::yScale
172
173 The scaling factor for the Y axis.
174*/
175
176/*!
177 \qmlclass Rotation QGraphicsRotation
178 \ingroup qml-transform-elements
179 \since 4.7
180 \brief The Rotation object provides a way to rotate an Item.
181
182 The Rotation object gives more control over rotation than using \l Item's \l{Item::rotation}{rotation} property.
183 Specifically, it allows (z axis) rotation to be relative to an arbitrary point.
184
185 The following example rotates a Rectangle around its interior point 25, 25:
186 \qml
187 Rectangle {
188 width: 100; height: 100
189 color: "blue"
190 transform: Rotation { origin.x: 25; origin.y: 25; angle: 45}
191 }
192 \endqml
193
194 Rotation also provides a way to specify 3D-like rotations for Items. For these types of
195 rotations you must specify the axis to rotate around in addition to the origin point.
196
197 The following example shows various 3D-like rotations applied to an \l Image.
198 \snippet doc/src/snippets/declarative/rotation.qml 0
199
200 \image axisrotation.png
201
202 \sa {declarative/ui-components/dialcontrol}{Dial Control example}, {declarative/toys/clocks}{Clocks example}
203*/
204
205/*!
206 \qmlproperty real Rotation::origin.x
207 \qmlproperty real Rotation::origin.y
208
209 The origin point of the rotation (i.e., the point that stays fixed relative to the parent as
210 the rest of the item rotates). By default the origin is 0, 0.
211*/
212
213/*!
214 \qmlproperty real Rotation::axis.x
215 \qmlproperty real Rotation::axis.y
216 \qmlproperty real Rotation::axis.z
217
218 The axis to rotate around. For simple (2D) rotation around a point, you do not need to specify an axis,
219 as the default axis is the z axis (\c{ axis { x: 0; y: 0; z: 1 } }).
220
221 For a typical 3D-like rotation you will usually specify both the origin and the axis.
222
223 \image 3d-rotation-axis.png
224*/
225
226/*!
227 \qmlproperty real Rotation::angle
228
229 The angle to rotate, in degrees clockwise.
230*/
231
232QDeclarativeContents::QDeclarativeContents(QDeclarativeItem *item) : m_item(item), m_x(0), m_y(0), m_width(0), m_height(0)
233{
234 //### optimize
235 connect(this, SIGNAL(rectChanged(QRectF)), m_item, SIGNAL(childrenRectChanged(QRectF)));
236}
237
238QDeclarativeContents::~QDeclarativeContents()
239{
240 QList<QGraphicsItem *> children = m_item->childItems();
241 for (int i = 0; i < children.count(); ++i) {
242 QDeclarativeItem *child = qobject_cast<QDeclarativeItem *>(children.at(i));
243 if(!child)//### Should this be ignoring non-QDeclarativeItem graphicsobjects?
244 continue;
245 QDeclarativeItemPrivate::get(child)->removeItemChangeListener(this, QDeclarativeItemPrivate::Geometry | QDeclarativeItemPrivate::Destroyed);
246 }
247}
248
249QRectF QDeclarativeContents::rectF() const
250{
251 return QRectF(m_x, m_y, m_width, m_height);
252}
253
254void QDeclarativeContents::calcHeight(QDeclarativeItem *changed)
255{
256 qreal oldy = m_y;
257 qreal oldheight = m_height;
258
259 if (changed) {
260 qreal top = oldy;
261 qreal bottom = oldy + oldheight;
262 qreal y = changed->y();
263 if (y + changed->height() > bottom)
264 bottom = y + changed->height();
265 if (y < top)
266 top = y;
267 m_y = top;
268 m_height = bottom - top;
269 } else {
270 qreal top = FLT_MAX;
271 qreal bottom = 0;
272 QList<QGraphicsItem *> children = m_item->childItems();
273 for (int i = 0; i < children.count(); ++i) {
274 QDeclarativeItem *child = qobject_cast<QDeclarativeItem *>(children.at(i));
275 if(!child)//### Should this be ignoring non-QDeclarativeItem graphicsobjects?
276 continue;
277 qreal y = child->y();
278 if (y + child->height() > bottom)
279 bottom = y + child->height();
280 if (y < top)
281 top = y;
282 }
283 if (!children.isEmpty())
284 m_y = top;
285 m_height = qMax(bottom - top, qreal(0.0));
286 }
287
288 if (m_height != oldheight || m_y != oldy)
289 emit rectChanged(rectF());
290}
291
292void QDeclarativeContents::calcWidth(QDeclarativeItem *changed)
293{
294 qreal oldx = m_x;
295 qreal oldwidth = m_width;
296
297 if (changed) {
298 qreal left = oldx;
299 qreal right = oldx + oldwidth;
300 qreal x = changed->x();
301 if (x + changed->width() > right)
302 right = x + changed->width();
303 if (x < left)
304 left = x;
305 m_x = left;
306 m_width = right - left;
307 } else {
308 qreal left = FLT_MAX;
309 qreal right = 0;
310 QList<QGraphicsItem *> children = m_item->childItems();
311 for (int i = 0; i < children.count(); ++i) {
312 QDeclarativeItem *child = qobject_cast<QDeclarativeItem *>(children.at(i));
313 if(!child)//### Should this be ignoring non-QDeclarativeItem graphicsobjects?
314 continue;
315 qreal x = child->x();
316 if (x + child->width() > right)
317 right = x + child->width();
318 if (x < left)
319 left = x;
320 }
321 if (!children.isEmpty())
322 m_x = left;
323 m_width = qMax(right - left, qreal(0.0));
324 }
325
326 if (m_width != oldwidth || m_x != oldx)
327 emit rectChanged(rectF());
328}
329
330void QDeclarativeContents::complete()
331{
332 QList<QGraphicsItem *> children = m_item->childItems();
333 for (int i = 0; i < children.count(); ++i) {
334 QDeclarativeItem *child = qobject_cast<QDeclarativeItem *>(children.at(i));
335 if(!child)//### Should this be ignoring non-QDeclarativeItem graphicsobjects?
336 continue;
337 QDeclarativeItemPrivate::get(child)->addItemChangeListener(this, QDeclarativeItemPrivate::Geometry | QDeclarativeItemPrivate::Destroyed);
338 //###what about changes to visibility?
339 }
340
341 calcGeometry();
342}
343
344void QDeclarativeContents::itemGeometryChanged(QDeclarativeItem *changed, const QRectF &newGeometry, const QRectF &oldGeometry)
345{
346 Q_UNUSED(changed)
347 //### we can only pass changed if the left edge has moved left, or the right edge has moved right
348 if (newGeometry.width() != oldGeometry.width() || newGeometry.x() != oldGeometry.x())
349 calcWidth(/*changed*/);
350 if (newGeometry.height() != oldGeometry.height() || newGeometry.y() != oldGeometry.y())
351 calcHeight(/*changed*/);
352}
353
354void QDeclarativeContents::itemDestroyed(QDeclarativeItem *item)
355{
356 if (item)
357 QDeclarativeItemPrivate::get(item)->removeItemChangeListener(this, QDeclarativeItemPrivate::Geometry | QDeclarativeItemPrivate::Destroyed);
358 calcGeometry();
359}
360
361void QDeclarativeContents::childRemoved(QDeclarativeItem *item)
362{
363 if (item)
364 QDeclarativeItemPrivate::get(item)->removeItemChangeListener(this, QDeclarativeItemPrivate::Geometry | QDeclarativeItemPrivate::Destroyed);
365 calcGeometry();
366}
367
368void QDeclarativeContents::childAdded(QDeclarativeItem *item)
369{
370 if (item)
371 QDeclarativeItemPrivate::get(item)->addItemChangeListener(this, QDeclarativeItemPrivate::Geometry | QDeclarativeItemPrivate::Destroyed);
372 calcWidth(item);
373 calcHeight(item);
374}
375
376QDeclarativeItemKeyFilter::QDeclarativeItemKeyFilter(QDeclarativeItem *item)
377: m_processPost(false), m_next(0)
378{
379 QDeclarativeItemPrivate *p =
380 item?static_cast<QDeclarativeItemPrivate *>(QGraphicsItemPrivate::get(item)):0;
381 if (p) {
382 m_next = p->keyHandler;
383 p->keyHandler = this;
384 }
385}
386
387QDeclarativeItemKeyFilter::~QDeclarativeItemKeyFilter()
388{
389}
390
391void QDeclarativeItemKeyFilter::keyPressed(QKeyEvent *event, bool post)
392{
393 if (m_next) m_next->keyPressed(event, post);
394}
395
396void QDeclarativeItemKeyFilter::keyReleased(QKeyEvent *event, bool post)
397{
398 if (m_next) m_next->keyReleased(event, post);
399}
400
401void QDeclarativeItemKeyFilter::inputMethodEvent(QInputMethodEvent *event, bool post)
402{
403 if (m_next) m_next->inputMethodEvent(event, post);
404}
405
406QVariant QDeclarativeItemKeyFilter::inputMethodQuery(Qt::InputMethodQuery query) const
407{
408 if (m_next) return m_next->inputMethodQuery(query);
409 return QVariant();
410}
411
412void QDeclarativeItemKeyFilter::componentComplete()
413{
414 if (m_next) m_next->componentComplete();
415}
416
417
418/*!
419 \qmlclass KeyNavigation QDeclarativeKeyNavigationAttached
420 \ingroup qml-basic-interaction-elements
421 \since 4.7
422 \brief The KeyNavigation attached property supports key navigation by arrow keys.
423
424 Key-based user interfaces commonly allow the use of arrow keys to navigate between
425 focusable items. The KeyNavigation attached property enables this behavior by providing a
426 convenient way to specify the item that should gain focus when an arrow or tab key is pressed.
427
428 The following example provides key navigation for a 2x2 grid of items:
429
430 \snippet doc/src/snippets/declarative/keynavigation.qml 0
431
432 The top-left item initially receives focus by setting \l {Item::}{focus} to
433 \c true. When an arrow key is pressed, the focus will move to the
434 appropriate item, as defined by the value that has been set for
435 the KeyNavigation \l left, \l right, \l up or \l down properties.
436
437 Note that if a KeyNavigation attached property receives the key press and release
438 events for a requested arrow or tab key, the event is accepted and does not
439 propagate any further.
440
441 By default, KeyNavigation receives key events after the item to which it is attached.
442 If the item accepts the key event, the KeyNavigation attached property will not
443 receive an event for that key. Setting the \l priority property to
444 \c KeyNavigation.BeforeItem allows the event to be used for key navigation
445 before the item, rather than after.
446
447 \sa {Keys}{Keys attached property}
448*/
449
450/*!
451 \qmlproperty Item KeyNavigation::left
452 \qmlproperty Item KeyNavigation::right
453 \qmlproperty Item KeyNavigation::up
454 \qmlproperty Item KeyNavigation::down
455
456 These properties hold the item to assign focus to
457 when the left, right, up or down cursor keys are
458 pressed.
459*/
460
461/*!
462 \qmlproperty Item KeyNavigation::tab
463 \qmlproperty Item KeyNavigation::backtab
464
465 These properties hold the item to assign focus to
466 when the Tab key or Shift+Tab key combination (Backtab) are pressed.
467*/
468
469QDeclarativeKeyNavigationAttached::QDeclarativeKeyNavigationAttached(QObject *parent)
470: QObject(*(new QDeclarativeKeyNavigationAttachedPrivate), parent),
471 QDeclarativeItemKeyFilter(qobject_cast<QDeclarativeItem*>(parent))
472{
473 m_processPost = true;
474}
475
476QDeclarativeKeyNavigationAttached *
477QDeclarativeKeyNavigationAttached::qmlAttachedProperties(QObject *obj)
478{
479 return new QDeclarativeKeyNavigationAttached(obj);
480}
481
482QDeclarativeItem *QDeclarativeKeyNavigationAttached::left() const
483{
484 Q_D(const QDeclarativeKeyNavigationAttached);
485 return d->left;
486}
487
488void QDeclarativeKeyNavigationAttached::setLeft(QDeclarativeItem *i)
489{
490 Q_D(QDeclarativeKeyNavigationAttached);
491 if (d->left == i)
492 return;
493 d->left = i;
494 emit leftChanged();
495}
496
497QDeclarativeItem *QDeclarativeKeyNavigationAttached::right() const
498{
499 Q_D(const QDeclarativeKeyNavigationAttached);
500 return d->right;
501}
502
503void QDeclarativeKeyNavigationAttached::setRight(QDeclarativeItem *i)
504{
505 Q_D(QDeclarativeKeyNavigationAttached);
506 if (d->right == i)
507 return;
508 d->right = i;
509 emit rightChanged();
510}
511
512QDeclarativeItem *QDeclarativeKeyNavigationAttached::up() const
513{
514 Q_D(const QDeclarativeKeyNavigationAttached);
515 return d->up;
516}
517
518void QDeclarativeKeyNavigationAttached::setUp(QDeclarativeItem *i)
519{
520 Q_D(QDeclarativeKeyNavigationAttached);
521 if (d->up == i)
522 return;
523 d->up = i;
524 emit upChanged();
525}
526
527QDeclarativeItem *QDeclarativeKeyNavigationAttached::down() const
528{
529 Q_D(const QDeclarativeKeyNavigationAttached);
530 return d->down;
531}
532
533void QDeclarativeKeyNavigationAttached::setDown(QDeclarativeItem *i)
534{
535 Q_D(QDeclarativeKeyNavigationAttached);
536 if (d->down == i)
537 return;
538 d->down = i;
539 emit downChanged();
540}
541
542QDeclarativeItem *QDeclarativeKeyNavigationAttached::tab() const
543{
544 Q_D(const QDeclarativeKeyNavigationAttached);
545 return d->tab;
546}
547
548void QDeclarativeKeyNavigationAttached::setTab(QDeclarativeItem *i)
549{
550 Q_D(QDeclarativeKeyNavigationAttached);
551 if (d->tab == i)
552 return;
553 d->tab = i;
554 emit tabChanged();
555}
556
557QDeclarativeItem *QDeclarativeKeyNavigationAttached::backtab() const
558{
559 Q_D(const QDeclarativeKeyNavigationAttached);
560 return d->backtab;
561}
562
563void QDeclarativeKeyNavigationAttached::setBacktab(QDeclarativeItem *i)
564{
565 Q_D(QDeclarativeKeyNavigationAttached);
566 if (d->backtab == i)
567 return;
568 d->backtab = i;
569 emit backtabChanged();
570}
571
572/*!
573 \qmlproperty enumeration KeyNavigation::priority
574
575 This property determines whether the keys are processed before
576 or after the attached item's own key handling.
577
578 \list
579 \o KeyNavigation.BeforeItem - process the key events before normal
580 item key processing. If the event is used for key navigation, it will be accepted and will not
581 be passed on to the item.
582 \o KeyNavigation.AfterItem (default) - process the key events after normal item key
583 handling. If the item accepts the key event it will not be
584 handled by the KeyNavigation attached property handler.
585 \endlist
586*/
587QDeclarativeKeyNavigationAttached::Priority QDeclarativeKeyNavigationAttached::priority() const
588{
589 return m_processPost ? AfterItem : BeforeItem;
590}
591
592void QDeclarativeKeyNavigationAttached::setPriority(Priority order)
593{
594 bool processPost = order == AfterItem;
595 if (processPost != m_processPost) {
596 m_processPost = processPost;
597 emit priorityChanged();
598 }
599}
600
601void QDeclarativeKeyNavigationAttached::keyPressed(QKeyEvent *event, bool post)
602{
603 Q_D(QDeclarativeKeyNavigationAttached);
604 event->ignore();
605
606 if (post != m_processPost) {
607 QDeclarativeItemKeyFilter::keyPressed(event, post);
608 return;
609 }
610
611 switch(event->key()) {
612 case Qt::Key_Left:
613 if (d->left) {
614 d->left->setFocus(true);
615 event->accept();
616 }
617 break;
618 case Qt::Key_Right:
619 if (d->right) {
620 d->right->setFocus(true);
621 event->accept();
622 }
623 break;
624 case Qt::Key_Up:
625 if (d->up) {
626 d->up->setFocus(true);
627 event->accept();
628 }
629 break;
630 case Qt::Key_Down:
631 if (d->down) {
632 d->down->setFocus(true);
633 event->accept();
634 }
635 break;
636 case Qt::Key_Tab:
637 if (d->tab) {
638 d->tab->setFocus(true);
639 event->accept();
640 }
641 break;
642 case Qt::Key_Backtab:
643 if (d->backtab) {
644 d->backtab->setFocus(true);
645 event->accept();
646 }
647 break;
648 default:
649 break;
650 }
651
652 if (!event->isAccepted()) QDeclarativeItemKeyFilter::keyPressed(event, post);
653}
654
655void QDeclarativeKeyNavigationAttached::keyReleased(QKeyEvent *event, bool post)
656{
657 Q_D(QDeclarativeKeyNavigationAttached);
658 event->ignore();
659
660 if (post != m_processPost) {
661 QDeclarativeItemKeyFilter::keyReleased(event, post);
662 return;
663 }
664
665 switch(event->key()) {
666 case Qt::Key_Left:
667 if (d->left) {
668 event->accept();
669 }
670 break;
671 case Qt::Key_Right:
672 if (d->right) {
673 event->accept();
674 }
675 break;
676 case Qt::Key_Up:
677 if (d->up) {
678 event->accept();
679 }
680 break;
681 case Qt::Key_Down:
682 if (d->down) {
683 event->accept();
684 }
685 break;
686 case Qt::Key_Tab:
687 if (d->tab) {
688 event->accept();
689 }
690 break;
691 case Qt::Key_Backtab:
692 if (d->backtab) {
693 event->accept();
694 }
695 break;
696 default:
697 break;
698 }
699
700 if (!event->isAccepted()) QDeclarativeItemKeyFilter::keyReleased(event, post);
701}
702
703/*!
704 \qmlclass Keys QDeclarativeKeysAttached
705 \ingroup qml-basic-interaction-elements
706 \since 4.7
707 \brief The Keys attached property provides key handling to Items.
708
709 All visual primitives support key handling via the Keys
710 attached property. Keys can be handled via the onPressed
711 and onReleased signal properties.
712
713 The signal properties have a \l KeyEvent parameter, named
714 \e event which contains details of the event. If a key is
715 handled \e event.accepted should be set to true to prevent the
716 event from propagating up the item hierarchy.
717
718 \section1 Example Usage
719
720 The following example shows how the general onPressed handler can
721 be used to test for a certain key; in this case, the left cursor
722 key:
723
724 \snippet doc/src/snippets/declarative/keys/keys-pressed.qml key item
725
726 Some keys may alternatively be handled via specific signal properties,
727 for example \e onSelectPressed. These handlers automatically set
728 \e event.accepted to true.
729
730 \snippet doc/src/snippets/declarative/keys/keys-handler.qml key item
731
732 See \l{Qt::Key}{Qt.Key} for the list of keyboard codes.
733
734 \section1 Key Handling Priorities
735
736 The Keys attached property can be configured to handle key events
737 before or after the item it is attached to. This makes it possible
738 to intercept events in order to override an item's default behavior,
739 or act as a fallback for keys not handled by the item.
740
741 If \l priority is Keys.BeforeItem (default) the order of key event processing is:
742
743 \list 1
744 \o Items specified in \c forwardTo
745 \o specific key handlers, e.g. onReturnPressed
746 \o onKeyPress, onKeyRelease handlers
747 \o Item specific key handling, e.g. TextInput key handling
748 \o parent item
749 \endlist
750
751 If priority is Keys.AfterItem the order of key event processing is:
752
753 \list 1
754 \o Item specific key handling, e.g. TextInput key handling
755 \o Items specified in \c forwardTo
756 \o specific key handlers, e.g. onReturnPressed
757 \o onKeyPress, onKeyRelease handlers
758 \o parent item
759 \endlist
760
761 If the event is accepted during any of the above steps, key
762 propagation stops.
763
764 \sa KeyEvent, {KeyNavigation}{KeyNavigation attached property}
765*/
766
767/*!
768 \qmlproperty bool Keys::enabled
769
770 This flags enables key handling if true (default); otherwise
771 no key handlers will be called.
772*/
773
774/*!
775 \qmlproperty enumeration Keys::priority
776
777 This property determines whether the keys are processed before
778 or after the attached item's own key handling.
779
780 \list
781 \o Keys.BeforeItem (default) - process the key events before normal
782 item key processing. If the event is accepted it will not
783 be passed on to the item.
784 \o Keys.AfterItem - process the key events after normal item key
785 handling. If the item accepts the key event it will not be
786 handled by the Keys attached property handler.
787 \endlist
788*/
789
790/*!
791 \qmlproperty list<Object> Keys::forwardTo
792
793 This property provides a way to forward key presses, key releases, and keyboard input
794 coming from input methods to other items. This can be useful when you want
795 one item to handle some keys (e.g. the up and down arrow keys), and another item to
796 handle other keys (e.g. the left and right arrow keys). Once an item that has been
797 forwarded keys accepts the event it is no longer forwarded to items later in the
798 list.
799
800 This example forwards key events to two lists:
801 \qml
802 ListView { id: list1 ... }
803 ListView { id: list2 ... }
804 Keys.forwardTo: [list1, list2]
805 focus: true
806 \endqml
807*/
808
809/*!
810 \qmlsignal Keys::onPressed(KeyEvent event)
811
812 This handler is called when a key has been pressed. The \a event
813 parameter provides information about the event.
814*/
815
816/*!
817 \qmlsignal Keys::onReleased(KeyEvent event)
818
819 This handler is called when a key has been released. The \a event
820 parameter provides information about the event.
821*/
822
823/*!
824 \qmlsignal Keys::onDigit0Pressed(KeyEvent event)
825
826 This handler is called when the digit '0' has been pressed. The \a event
827 parameter provides information about the event.
828*/
829
830/*!
831 \qmlsignal Keys::onDigit1Pressed(KeyEvent event)
832
833 This handler is called when the digit '1' has been pressed. The \a event
834 parameter provides information about the event.
835*/
836
837/*!
838 \qmlsignal Keys::onDigit2Pressed(KeyEvent event)
839
840 This handler is called when the digit '2' has been pressed. The \a event
841 parameter provides information about the event.
842*/
843
844/*!
845 \qmlsignal Keys::onDigit3Pressed(KeyEvent event)
846
847 This handler is called when the digit '3' has been pressed. The \a event
848 parameter provides information about the event.
849*/
850
851/*!
852 \qmlsignal Keys::onDigit4Pressed(KeyEvent event)
853
854 This handler is called when the digit '4' has been pressed. The \a event
855 parameter provides information about the event.
856*/
857
858/*!
859 \qmlsignal Keys::onDigit5Pressed(KeyEvent event)
860
861 This handler is called when the digit '5' has been pressed. The \a event
862 parameter provides information about the event.
863*/
864
865/*!
866 \qmlsignal Keys::onDigit6Pressed(KeyEvent event)
867
868 This handler is called when the digit '6' has been pressed. The \a event
869 parameter provides information about the event.
870*/
871
872/*!
873 \qmlsignal Keys::onDigit7Pressed(KeyEvent event)
874
875 This handler is called when the digit '7' has been pressed. The \a event
876 parameter provides information about the event.
877*/
878
879/*!
880 \qmlsignal Keys::onDigit8Pressed(KeyEvent event)
881
882 This handler is called when the digit '8' has been pressed. The \a event
883 parameter provides information about the event.
884*/
885
886/*!
887 \qmlsignal Keys::onDigit9Pressed(KeyEvent event)
888
889 This handler is called when the digit '9' has been pressed. The \a event
890 parameter provides information about the event.
891*/
892
893/*!
894 \qmlsignal Keys::onLeftPressed(KeyEvent event)
895
896 This handler is called when the Left arrow has been pressed. The \a event
897 parameter provides information about the event.
898*/
899
900/*!
901 \qmlsignal Keys::onRightPressed(KeyEvent event)
902
903 This handler is called when the Right arrow has been pressed. The \a event
904 parameter provides information about the event.
905*/
906
907/*!
908 \qmlsignal Keys::onUpPressed(KeyEvent event)
909
910 This handler is called when the Up arrow has been pressed. The \a event
911 parameter provides information about the event.
912*/
913
914/*!
915 \qmlsignal Keys::onDownPressed(KeyEvent event)
916
917 This handler is called when the Down arrow has been pressed. The \a event
918 parameter provides information about the event.
919*/
920
921/*!
922 \qmlsignal Keys::onTabPressed(KeyEvent event)
923
924 This handler is called when the Tab key has been pressed. The \a event
925 parameter provides information about the event.
926*/
927
928/*!
929 \qmlsignal Keys::onBacktabPressed(KeyEvent event)
930
931 This handler is called when the Shift+Tab key combination (Backtab) has
932 been pressed. The \a event parameter provides information about the event.
933*/
934
935/*!
936 \qmlsignal Keys::onAsteriskPressed(KeyEvent event)
937
938 This handler is called when the Asterisk '*' has been pressed. The \a event
939 parameter provides information about the event.
940*/
941
942/*!
943 \qmlsignal Keys::onEscapePressed(KeyEvent event)
944
945 This handler is called when the Escape key has been pressed. The \a event
946 parameter provides information about the event.
947*/
948
949/*!
950 \qmlsignal Keys::onReturnPressed(KeyEvent event)
951
952 This handler is called when the Return key has been pressed. The \a event
953 parameter provides information about the event.
954*/
955
956/*!
957 \qmlsignal Keys::onEnterPressed(KeyEvent event)
958
959 This handler is called when the Enter key has been pressed. The \a event
960 parameter provides information about the event.
961*/
962
963/*!
964 \qmlsignal Keys::onDeletePressed(KeyEvent event)
965
966 This handler is called when the Delete key has been pressed. The \a event
967 parameter provides information about the event.
968*/
969
970/*!
971 \qmlsignal Keys::onSpacePressed(KeyEvent event)
972
973 This handler is called when the Space key has been pressed. The \a event
974 parameter provides information about the event.
975*/
976
977/*!
978 \qmlsignal Keys::onBackPressed(KeyEvent event)
979
980 This handler is called when the Back key has been pressed. The \a event
981 parameter provides information about the event.
982*/
983
984/*!
985 \qmlsignal Keys::onCancelPressed(KeyEvent event)
986
987 This handler is called when the Cancel key has been pressed. The \a event
988 parameter provides information about the event.
989*/
990
991/*!
992 \qmlsignal Keys::onSelectPressed(KeyEvent event)
993
994 This handler is called when the Select key has been pressed. The \a event
995 parameter provides information about the event.
996*/
997
998/*!
999 \qmlsignal Keys::onYesPressed(KeyEvent event)
1000
1001 This handler is called when the Yes key has been pressed. The \a event
1002 parameter provides information about the event.
1003*/
1004
1005/*!
1006 \qmlsignal Keys::onNoPressed(KeyEvent event)
1007
1008 This handler is called when the No key has been pressed. The \a event
1009 parameter provides information about the event.
1010*/
1011
1012/*!
1013 \qmlsignal Keys::onContext1Pressed(KeyEvent event)
1014
1015 This handler is called when the Context1 key has been pressed. The \a event
1016 parameter provides information about the event.
1017*/
1018
1019/*!
1020 \qmlsignal Keys::onContext2Pressed(KeyEvent event)
1021
1022 This handler is called when the Context2 key has been pressed. The \a event
1023 parameter provides information about the event.
1024*/
1025
1026/*!
1027 \qmlsignal Keys::onContext3Pressed(KeyEvent event)
1028
1029 This handler is called when the Context3 key has been pressed. The \a event
1030 parameter provides information about the event.
1031*/
1032
1033/*!
1034 \qmlsignal Keys::onContext4Pressed(KeyEvent event)
1035
1036 This handler is called when the Context4 key has been pressed. The \a event
1037 parameter provides information about the event.
1038*/
1039
1040/*!
1041 \qmlsignal Keys::onCallPressed(KeyEvent event)
1042
1043 This handler is called when the Call key has been pressed. The \a event
1044 parameter provides information about the event.
1045*/
1046
1047/*!
1048 \qmlsignal Keys::onHangupPressed(KeyEvent event)
1049
1050 This handler is called when the Hangup key has been pressed. The \a event
1051 parameter provides information about the event.
1052*/
1053
1054/*!
1055 \qmlsignal Keys::onFlipPressed(KeyEvent event)
1056
1057 This handler is called when the Flip key has been pressed. The \a event
1058 parameter provides information about the event.
1059*/
1060
1061/*!
1062 \qmlsignal Keys::onMenuPressed(KeyEvent event)
1063
1064 This handler is called when the Menu key has been pressed. The \a event
1065 parameter provides information about the event.
1066*/
1067
1068/*!
1069 \qmlsignal Keys::onVolumeUpPressed(KeyEvent event)
1070
1071 This handler is called when the VolumeUp key has been pressed. The \a event
1072 parameter provides information about the event.
1073*/
1074
1075/*!
1076 \qmlsignal Keys::onVolumeDownPressed(KeyEvent event)
1077
1078 This handler is called when the VolumeDown key has been pressed. The \a event
1079 parameter provides information about the event.
1080*/
1081
1082const QDeclarativeKeysAttached::SigMap QDeclarativeKeysAttached::sigMap[] = {
1083 { Qt::Key_Left, "leftPressed" },
1084 { Qt::Key_Right, "rightPressed" },
1085 { Qt::Key_Up, "upPressed" },
1086 { Qt::Key_Down, "downPressed" },
1087 { Qt::Key_Tab, "tabPressed" },
1088 { Qt::Key_Backtab, "backtabPressed" },
1089 { Qt::Key_Asterisk, "asteriskPressed" },
1090 { Qt::Key_NumberSign, "numberSignPressed" },
1091 { Qt::Key_Escape, "escapePressed" },
1092 { Qt::Key_Return, "returnPressed" },
1093 { Qt::Key_Enter, "enterPressed" },
1094 { Qt::Key_Delete, "deletePressed" },
1095 { Qt::Key_Space, "spacePressed" },
1096 { Qt::Key_Back, "backPressed" },
1097 { Qt::Key_Cancel, "cancelPressed" },
1098 { Qt::Key_Select, "selectPressed" },
1099 { Qt::Key_Yes, "yesPressed" },
1100 { Qt::Key_No, "noPressed" },
1101 { Qt::Key_Context1, "context1Pressed" },
1102 { Qt::Key_Context2, "context2Pressed" },
1103 { Qt::Key_Context3, "context3Pressed" },
1104 { Qt::Key_Context4, "context4Pressed" },
1105 { Qt::Key_Call, "callPressed" },
1106 { Qt::Key_Hangup, "hangupPressed" },
1107 { Qt::Key_Flip, "flipPressed" },
1108 { Qt::Key_Menu, "menuPressed" },
1109 { Qt::Key_VolumeUp, "volumeUpPressed" },
1110 { Qt::Key_VolumeDown, "volumeDownPressed" },
1111 { 0, 0 }
1112};
1113
1114bool QDeclarativeKeysAttachedPrivate::isConnected(const char *signalName)
1115{
1116 return isSignalConnected(signalIndex(signalName));
1117}
1118
1119QDeclarativeKeysAttached::QDeclarativeKeysAttached(QObject *parent)
1120: QObject(*(new QDeclarativeKeysAttachedPrivate), parent),
1121 QDeclarativeItemKeyFilter(qobject_cast<QDeclarativeItem*>(parent))
1122{
1123 Q_D(QDeclarativeKeysAttached);
1124 m_processPost = false;
1125 d->item = qobject_cast<QDeclarativeItem*>(parent);
1126}
1127
1128QDeclarativeKeysAttached::~QDeclarativeKeysAttached()
1129{
1130}
1131
1132QDeclarativeKeysAttached::Priority QDeclarativeKeysAttached::priority() const
1133{
1134 return m_processPost ? AfterItem : BeforeItem;
1135}
1136
1137void QDeclarativeKeysAttached::setPriority(Priority order)
1138{
1139 bool processPost = order == AfterItem;
1140 if (processPost != m_processPost) {
1141 m_processPost = processPost;
1142 emit priorityChanged();
1143 }
1144}
1145
1146void QDeclarativeKeysAttached::componentComplete()
1147{
1148 Q_D(QDeclarativeKeysAttached);
1149 if (d->item) {
1150 for (int ii = 0; ii < d->targets.count(); ++ii) {
1151 QGraphicsItem *targetItem = d->finalFocusProxy(d->targets.at(ii));
1152 if (targetItem && (targetItem->flags() & QGraphicsItem::ItemAcceptsInputMethod)) {
1153 d->item->setFlag(QGraphicsItem::ItemAcceptsInputMethod);
1154 break;
1155 }
1156 }
1157 }
1158}
1159
1160void QDeclarativeKeysAttached::keyPressed(QKeyEvent *event, bool post)
1161{
1162 Q_D(QDeclarativeKeysAttached);
1163 if (post != m_processPost || !d->enabled || d->inPress) {
1164 event->ignore();
1165 QDeclarativeItemKeyFilter::keyPressed(event, post);
1166 return;
1167 }
1168
1169 // first process forwards
1170 if (d->item && d->item->scene()) {
1171 d->inPress = true;
1172 for (int ii = 0; ii < d->targets.count(); ++ii) {
1173 QGraphicsItem *i = d->finalFocusProxy(d->targets.at(ii));
1174 if (i && i->isVisible()) {
1175 d->item->scene()->sendEvent(i, event);
1176 if (event->isAccepted()) {
1177 d->inPress = false;
1178 return;
1179 }
1180 }
1181 }
1182 d->inPress = false;
1183 }
1184
1185 QDeclarativeKeyEvent ke(*event);
1186 QByteArray keySignal = keyToSignal(event->key());
1187 if (!keySignal.isEmpty()) {
1188 keySignal += "(QDeclarativeKeyEvent*)";
1189 if (d->isConnected(keySignal)) {
1190 // If we specifically handle a key then default to accepted
1191 ke.setAccepted(true);
1192 int idx = QDeclarativeKeysAttached::staticMetaObject.indexOfSignal(keySignal);
1193 metaObject()->method(idx).invoke(this, Qt::DirectConnection, Q_ARG(QDeclarativeKeyEvent*, &ke));
1194 }
1195 }
1196 if (!ke.isAccepted())
1197 emit pressed(&ke);
1198 event->setAccepted(ke.isAccepted());
1199
1200 if (!event->isAccepted()) QDeclarativeItemKeyFilter::keyPressed(event, post);
1201}
1202
1203void QDeclarativeKeysAttached::keyReleased(QKeyEvent *event, bool post)
1204{
1205 Q_D(QDeclarativeKeysAttached);
1206 if (post != m_processPost || !d->enabled || d->inRelease) {
1207 event->ignore();
1208 QDeclarativeItemKeyFilter::keyReleased(event, post);
1209 return;
1210 }
1211
1212 if (d->item && d->item->scene()) {
1213 d->inRelease = true;
1214 for (int ii = 0; ii < d->targets.count(); ++ii) {
1215 QGraphicsItem *i = d->finalFocusProxy(d->targets.at(ii));
1216 if (i && i->isVisible()) {
1217 d->item->scene()->sendEvent(i, event);
1218 if (event->isAccepted()) {
1219 d->inRelease = false;
1220 return;
1221 }
1222 }
1223 }
1224 d->inRelease = false;
1225 }
1226
1227 QDeclarativeKeyEvent ke(*event);
1228 emit released(&ke);
1229 event->setAccepted(ke.isAccepted());
1230
1231 if (!event->isAccepted()) QDeclarativeItemKeyFilter::keyReleased(event, post);
1232}
1233
1234void QDeclarativeKeysAttached::inputMethodEvent(QInputMethodEvent *event, bool post)
1235{
1236 Q_D(QDeclarativeKeysAttached);
1237 if (post == m_processPost && d->item && !d->inIM && d->item->scene()) {
1238 d->inIM = true;
1239 for (int ii = 0; ii < d->targets.count(); ++ii) {
1240 QGraphicsItem *i = d->finalFocusProxy(d->targets.at(ii));
1241 if (i && i->isVisible() && (i->flags() & QGraphicsItem::ItemAcceptsInputMethod)) {
1242 d->item->scene()->sendEvent(i, event);
1243 if (event->isAccepted()) {
1244 d->imeItem = i;
1245 d->inIM = false;
1246 return;
1247 }
1248 }
1249 }
1250 d->inIM = false;
1251 }
1252 if (!event->isAccepted()) QDeclarativeItemKeyFilter::inputMethodEvent(event, post);
1253}
1254
1255class QDeclarativeItemAccessor : public QGraphicsItem
1256{
1257public:
1258 QVariant doInputMethodQuery(Qt::InputMethodQuery query) const {
1259 return QGraphicsItem::inputMethodQuery(query);
1260 }
1261};
1262
1263QVariant QDeclarativeKeysAttached::inputMethodQuery(Qt::InputMethodQuery query) const
1264{
1265 Q_D(const QDeclarativeKeysAttached);
1266 if (d->item) {
1267 for (int ii = 0; ii < d->targets.count(); ++ii) {
1268 QGraphicsItem *i = d->finalFocusProxy(d->targets.at(ii));
1269 if (i && i->isVisible() && (i->flags() & QGraphicsItem::ItemAcceptsInputMethod) && i == d->imeItem) { //### how robust is i == d->imeItem check?
1270 QVariant v = static_cast<QDeclarativeItemAccessor *>(i)->doInputMethodQuery(query);
1271 if (v.userType() == QVariant::RectF)
1272 v = d->item->mapRectFromItem(i, v.toRectF()); //### cost?
1273 return v;
1274 }
1275 }
1276 }
1277 return QDeclarativeItemKeyFilter::inputMethodQuery(query);
1278}
1279
1280QDeclarativeKeysAttached *QDeclarativeKeysAttached::qmlAttachedProperties(QObject *obj)
1281{
1282 return new QDeclarativeKeysAttached(obj);
1283}
1284
1285/*!
1286 \class QDeclarativeItem
1287 \since 4.7
1288 \brief The QDeclarativeItem class provides the most basic of all visual items in QML.
1289
1290 All visual items in Qt Declarative inherit from QDeclarativeItem. Although QDeclarativeItem
1291 has no visual appearance, it defines all the properties that are
1292 common across visual items - such as the x and y position, the
1293 width and height, \l {anchor-layout}{anchoring} and key handling.
1294
1295 You can subclass QDeclarativeItem to provide your own custom visual item that inherits
1296 these features. Note that, because it does not draw anything, QDeclarativeItem sets the
1297 QGraphicsItem::ItemHasNoContents flag. If you subclass QDeclarativeItem to create a visual
1298 item, you will need to unset this flag.
1299
1300*/
1301
1302/*!
1303 \qmlclass Item QDeclarativeItem
1304 \ingroup qml-basic-visual-elements
1305 \since 4.7
1306 \brief The Item is the most basic of all visual items in QML.
1307
1308 All visual items in Qt Declarative inherit from Item. Although Item
1309 has no visual appearance, it defines all the properties that are
1310 common across visual items - such as the x and y position, the
1311 width and height, \l {anchor-layout}{anchoring} and key handling.
1312
1313 Item is also useful for grouping items together.
1314
1315 \qml
1316 Item {
1317 Image {
1318 source: "tile.png"
1319 }
1320 Image {
1321 x: 80
1322 width: 100
1323 height: 100
1324 source: "tile.png"
1325 }
1326 Image {
1327 x: 190
1328 width: 100
1329 height: 100
1330 fillMode: Image.Tile
1331 source: "tile.png"
1332 }
1333 }
1334 \endqml
1335
1336
1337 \section1 Key Handling
1338
1339 Key handling is available to all Item-based visual elements via the \l {Keys}{Keys}
1340 attached property. The \e Keys attached property provides basic handlers such
1341 as \l {Keys::onPressed}{onPressed} and \l {Keys::onReleased}{onReleased},
1342 as well as handlers for specific keys, such as
1343 \l {Keys::onCancelPressed}{onCancelPressed}. The example below
1344 assigns \l {qmlfocus}{focus} to the item and handles
1345 the Left key via the general \e onPressed handler and the Select key via the
1346 onSelectPressed handler:
1347
1348 \qml
1349 Item {
1350 focus: true
1351 Keys.onPressed: {
1352 if (event.key == Qt.Key_Left) {
1353 console.log("move left");
1354 event.accepted = true;
1355 }
1356 }
1357 Keys.onSelectPressed: console.log("Selected");
1358 }
1359 \endqml
1360
1361 See the \l {Keys}{Keys} attached property for detailed documentation.
1362*/
1363
1364/*!
1365 \fn void QDeclarativeItem::childrenRectChanged(const QRectF &)
1366 \internal
1367*/
1368
1369/*!
1370 \fn void QDeclarativeItem::baselineOffsetChanged(qreal)
1371 \internal
1372*/
1373
1374/*!
1375 \fn void QDeclarativeItem::stateChanged(const QString &state)
1376 \internal
1377*/
1378
1379/*!
1380 \fn void QDeclarativeItem::parentChanged(QDeclarativeItem *)
1381 \internal
1382*/
1383
1384/*!
1385 \fn void QDeclarativeItem::smoothChanged(bool)
1386 \internal
1387*/
1388
1389/*!
1390 \fn void QDeclarativeItem::clipChanged(bool)
1391 \internal
1392*/
1393
1394/*! \fn void QDeclarativeItem::transformOriginChanged(TransformOrigin)
1395 \internal
1396*/
1397
1398/*!
1399 \fn void QDeclarativeItem::focusChanged(bool)
1400 \internal
1401*/
1402
1403/*!
1404 \fn void QDeclarativeItem::activeFocusChanged(bool)
1405 \internal
1406*/
1407
1408// ### Must fix
1409struct RegisterAnchorLineAtStartup {
1410 RegisterAnchorLineAtStartup() {
1411 qRegisterMetaType<QDeclarativeAnchorLine>("QDeclarativeAnchorLine");
1412 }
1413};
1414static RegisterAnchorLineAtStartup registerAnchorLineAtStartup;
1415
1416
1417/*!
1418 \fn QDeclarativeItem::QDeclarativeItem(QDeclarativeItem *parent)
1419
1420 Constructs a QDeclarativeItem with the given \a parent.
1421*/
1422QDeclarativeItem::QDeclarativeItem(QDeclarativeItem* parent)
1423 : QGraphicsObject(*(new QDeclarativeItemPrivate), parent, 0)
1424{
1425 Q_D(QDeclarativeItem);
1426 d->init(parent);
1427}
1428
1429/*! \internal
1430*/
1431QDeclarativeItem::QDeclarativeItem(QDeclarativeItemPrivate &dd, QDeclarativeItem *parent)
1432 : QGraphicsObject(dd, parent, 0)
1433{
1434 Q_D(QDeclarativeItem);
1435 d->init(parent);
1436}
1437
1438/*!
1439 Destroys the QDeclarativeItem.
1440*/
1441QDeclarativeItem::~QDeclarativeItem()
1442{
1443 Q_D(QDeclarativeItem);
1444 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
1445 QDeclarativeAnchorsPrivate *anchor = d->changeListeners.at(ii).listener->anchorPrivate();
1446 if (anchor)
1447 anchor->clearItem(this);
1448 }
1449 if (!d->parent || (parentItem() && !parentItem()->QGraphicsItem::d_ptr->inDestructor)) {
1450 for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
1451 QDeclarativeAnchorsPrivate *anchor = d->changeListeners.at(ii).listener->anchorPrivate();
1452 if (anchor && anchor->item && anchor->item->parentItem() != this) //child will be deleted anyway
1453 anchor->updateOnComplete();
1454 }
1455 }
1456 for(int ii = 0; ii < d->changeListeners.count(); ++ii) {
1457 const QDeclarativeItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
1458 if (change.types & QDeclarativeItemPrivate::Destroyed)
1459 change.listener->itemDestroyed(this);
1460 }
1461 d->changeListeners.clear();
1462 delete d->_anchorLines; d->_anchorLines = 0;
1463 delete d->_anchors; d->_anchors = 0;
1464 delete d->_stateGroup; d->_stateGroup = 0;
1465 delete d->_contents; d->_contents = 0;
1466}
1467
1468/*!
1469 \qmlproperty enumeration Item::transformOrigin
1470 This property holds the origin point around which scale and rotation transform.
1471
1472 Nine transform origins are available, as shown in the image below.
1473
1474 \image declarative-transformorigin.png
1475
1476 This example rotates an image around its bottom-right corner.
1477 \qml
1478 Image {
1479 source: "myimage.png"
1480 transformOrigin: Item.BottomRight
1481 rotation: 45
1482 }
1483 \endqml
1484
1485 The default transform origin is \c Item.Center.
1486
1487 To set an arbitrary transform origin point use the \l Scale or \l Rotation
1488 transform elements.
1489*/
1490
1491/*!
1492 \qmlproperty Item Item::parent
1493 This property holds the parent of the item.
1494*/
1495
1496/*!
1497 \property QDeclarativeItem::parent
1498 This property holds the parent of the item.
1499*/
1500void QDeclarativeItem::setParentItem(QDeclarativeItem *parent)
1501{
1502 QGraphicsObject::setParentItem(parent);
1503}
1504
1505/*!
1506 Returns the QDeclarativeItem parent of this item.
1507*/
1508QDeclarativeItem *QDeclarativeItem::parentItem() const
1509{
1510 return qobject_cast<QDeclarativeItem *>(QGraphicsObject::parentItem());
1511}
1512
1513/*!
1514 \qmlproperty real Item::childrenRect.x
1515 \qmlproperty real Item::childrenRect.y
1516 \qmlproperty real Item::childrenRect.width
1517 \qmlproperty real Item::childrenRect.height
1518
1519 The childrenRect properties allow an item access to the geometry of its
1520 children. This property is useful if you have an item that needs to be
1521 sized to fit its children.
1522*/
1523
1524
1525/*!
1526 \qmlproperty list<Item> Item::children
1527 \qmlproperty list<Object> Item::resources
1528
1529 The children property contains the list of visual children of this item.
1530 The resources property contains non-visual resources that you want to
1531 reference by name.
1532
1533 Generally you can rely on Item's default property to handle all this for
1534 you, but it can come in handy in some cases.
1535
1536 \qml
1537 Item {
1538 children: [
1539 Text {},
1540 Rectangle {}
1541 ]
1542 resources: [
1543 Component {
1544 id: myComponent
1545 Text {}
1546 }
1547 ]
1548 }
1549 \endqml
1550*/
1551
1552/*!
1553 Returns true if construction of the QML component is complete; otherwise
1554 returns false.
1555
1556 It is often desirable to delay some processing until the component is
1557 completed.
1558
1559 \sa componentComplete()
1560*/
1561bool QDeclarativeItem::isComponentComplete() const
1562{
1563 Q_D(const QDeclarativeItem);
1564 return d->componentComplete;
1565}
1566
1567void QDeclarativeItemPrivate::data_append(QDeclarativeListProperty<QObject> *prop, QObject *o)
1568{
1569 if (!o)
1570 return;
1571
1572 QDeclarativeItem *that = static_cast<QDeclarativeItem *>(prop->object);
1573
1574 // This test is measurably (albeit only slightly) faster than qobject_cast<>()
1575 const QMetaObject *mo = o->metaObject();
1576 while (mo && mo != &QGraphicsObject::staticMetaObject) mo = mo->d.superdata;
1577
1578 if (mo) {
1579 QGraphicsObject *graphicsObject = static_cast<QGraphicsObject *>(o);
1580 QDeclarativeItemPrivate *contentItemPrivate = static_cast<QDeclarativeItemPrivate *>(QGraphicsItemPrivate::get(graphicsObject));
1581 if (contentItemPrivate->componentComplete) {
1582 graphicsObject->setParentItem(that);
1583 } else {
1584 contentItemPrivate->setParentItemHelper(that, /*newParentVariant=*/0, /*thisPointerVariant=*/0);
1585 }
1586 } else {
1587 o->setParent(that);
1588 }
1589}
1590
1591static inline int children_count_helper(QDeclarativeListProperty<QObject> *prop)
1592{
1593 QGraphicsItemPrivate *d = QGraphicsItemPrivate::get(static_cast<QGraphicsObject *>(prop->object));
1594 return d->children.count();
1595}
1596
1597static inline QObject *children_at_helper(QDeclarativeListProperty<QObject> *prop, int index)
1598{
1599 QGraphicsItemPrivate *d = QGraphicsItemPrivate::get(static_cast<QGraphicsObject *>(prop->object));
1600 if (index >= 0 && index < d->children.count())
1601 return d->children.at(index)->toGraphicsObject();
1602 else
1603 return 0;
1604}
1605
1606static inline void children_clear_helper(QDeclarativeListProperty<QObject> *prop)
1607{
1608 QDeclarativeItemPrivate *d = static_cast<QDeclarativeItemPrivate*>(QGraphicsItemPrivate::get(static_cast<QGraphicsObject *>(prop->object)));
1609 int childCount = d->children.count();
1610 if (d->componentComplete) {
1611 for (int index = 0 ;index < childCount; index++)
1612 d->children.at(0)->setParentItem(0);
1613 } else {
1614 for (int index = 0 ;index < childCount; index++)
1615 QGraphicsItemPrivate::get(d->children.at(0))->setParentItemHelper(0, /*newParentVariant=*/0, /*thisPointerVariant=*/0);
1616 }
1617}
1618
1619int QDeclarativeItemPrivate::data_count(QDeclarativeListProperty<QObject> *prop)
1620{
1621 return resources_count(prop) + children_count_helper(prop);
1622}
1623
1624QObject *QDeclarativeItemPrivate::data_at(QDeclarativeListProperty<QObject> *prop, int i)
1625{
1626 int resourcesCount = resources_count(prop);
1627 if (i < resourcesCount)
1628 return resources_at(prop, i);
1629 const int j = i - resourcesCount;
1630 if (j < children_count_helper(prop))
1631 return children_at_helper(prop, j);
1632 return 0;
1633}
1634
1635void QDeclarativeItemPrivate::data_clear(QDeclarativeListProperty<QObject> *prop)
1636{
1637 resources_clear(prop);
1638 children_clear_helper(prop);
1639}
1640
1641QObject *QDeclarativeItemPrivate::resources_at(QDeclarativeListProperty<QObject> *prop, int index)
1642{
1643 const QObjectList children = prop->object->children();
1644 if (index < children.count())
1645 return children.at(index);
1646 else
1647 return 0;
1648}
1649
1650void QDeclarativeItemPrivate::resources_append(QDeclarativeListProperty<QObject> *prop, QObject *o)
1651{
1652 o->setParent(prop->object);
1653}
1654
1655int QDeclarativeItemPrivate::resources_count(QDeclarativeListProperty<QObject> *prop)
1656{
1657 return prop->object->children().count();
1658}
1659
1660void QDeclarativeItemPrivate::resources_clear(QDeclarativeListProperty<QObject> *prop)
1661{
1662 const QObjectList children = prop->object->children();
1663 for (int index = 0; index < children.count(); index++)
1664 children.at(index)->setParent(0);
1665}
1666
1667int QDeclarativeItemPrivate::transform_count(QDeclarativeListProperty<QGraphicsTransform> *list)
1668{
1669 QGraphicsObject *object = qobject_cast<QGraphicsObject *>(list->object);
1670 if (object) {
1671 QGraphicsItemPrivate *d = QGraphicsItemPrivate::get(object);
1672 return d->transformData ? d->transformData->graphicsTransforms.size() : 0;
1673 } else {
1674 return 0;
1675 }
1676}
1677
1678void QDeclarativeItemPrivate::transform_append(QDeclarativeListProperty<QGraphicsTransform> *list, QGraphicsTransform *item)
1679{
1680 QGraphicsObject *object = qobject_cast<QGraphicsObject *>(list->object);
1681 if (object && item) // QGraphicsItem applies the list in the wrong order, so we prepend.
1682 QGraphicsItemPrivate::get(object)->prependGraphicsTransform(item);
1683}
1684
1685QGraphicsTransform *QDeclarativeItemPrivate::transform_at(QDeclarativeListProperty<QGraphicsTransform> *list, int idx)
1686{
1687 QGraphicsObject *object = qobject_cast<QGraphicsObject *>(list->object);
1688 if (object) {
1689 QGraphicsItemPrivate *d = QGraphicsItemPrivate::get(object);
1690 if (!d->transformData)
1691 return 0;
1692 return d->transformData->graphicsTransforms.at(idx);
1693 } else {
1694 return 0;
1695 }
1696}
1697
1698void QDeclarativeItemPrivate::transform_clear(QDeclarativeListProperty<QGraphicsTransform> *list)
1699{
1700 QGraphicsObject *object = qobject_cast<QGraphicsObject *>(list->object);
1701 if (object) {
1702 QGraphicsItemPrivate *d = QGraphicsItemPrivate::get(object);
1703 if (!d->transformData)
1704 return;
1705 object->setTransformations(QList<QGraphicsTransform *>());
1706 }
1707}
1708
1709void QDeclarativeItemPrivate::parentProperty(QObject *o, void *rv, QDeclarativeNotifierEndpoint *e)
1710{
1711 QDeclarativeItem *item = static_cast<QDeclarativeItem*>(o);
1712 if (e)
1713 e->connect(&item->d_func()->parentNotifier);
1714 *((QDeclarativeItem **)rv) = item->parentItem();
1715}
1716
1717/*!
1718 \qmlproperty list<Object> Item::data
1719 \default
1720
1721 The data property allows you to freely mix visual children and resources
1722 in an item. If you assign a visual item to the data list it becomes
1723 a child and if you assign any other object type, it is added as a resource.
1724
1725 So you can write:
1726 \qml
1727 Item {
1728 Text {}
1729 Rectangle {}
1730 Timer {}
1731 }
1732 \endqml
1733
1734 instead of:
1735 \qml
1736 Item {
1737 children: [
1738 Text {},
1739 Rectangle {}
1740 ]
1741 resources: [
1742 Timer {}
1743 ]
1744 }
1745 \endqml
1746
1747 data is a behind-the-scenes property: you should never need to explicitly
1748 specify it.
1749 */
1750
1751QDeclarativeListProperty<QObject> QDeclarativeItemPrivate::data()
1752{
1753 return QDeclarativeListProperty<QObject>(q_func(), 0, QDeclarativeItemPrivate::data_append,
1754 QDeclarativeItemPrivate::data_count,
1755 QDeclarativeItemPrivate::data_at,
1756 QDeclarativeItemPrivate::data_clear
1757 );
1758}
1759
1760/*!
1761 \property QDeclarativeItem::childrenRect
1762 \brief The geometry of an item's children.
1763
1764 This property holds the (collective) position and size of the item's children.
1765*/
1766QRectF QDeclarativeItem::childrenRect()
1767{
1768 Q_D(QDeclarativeItem);
1769 if (!d->_contents) {
1770 d->_contents = new QDeclarativeContents(this);
1771 if (d->componentComplete)
1772 d->_contents->complete();
1773 }
1774 return d->_contents->rectF();
1775}
1776
1777bool QDeclarativeItem::clip() const
1778{
1779 return flags() & ItemClipsChildrenToShape;
1780}
1781
1782void QDeclarativeItem::setClip(bool c)
1783{
1784 if (clip() == c)
1785 return;
1786 setFlag(ItemClipsChildrenToShape, c);
1787 emit clipChanged(c);
1788}
1789
1790/*!
1791 \qmlproperty real Item::x
1792 \qmlproperty real Item::y
1793 \qmlproperty real Item::width
1794 \qmlproperty real Item::height
1795
1796 Defines the item's position and size relative to its parent.
1797
1798 \qml
1799 Item { x: 100; y: 100; width: 100; height: 100 }
1800 \endqml
1801 */
1802
1803/*!
1804 \qmlproperty real Item::z
1805
1806 Sets the stacking order of sibling items. By default the stacking order is 0.
1807
1808 Items with a higher stacking value are drawn on top of siblings with a
1809 lower stacking order. Items with the same stacking value are drawn
1810 bottom up in the order they appear. Items with a negative stacking
1811 value are drawn under their parent's content.
1812
1813 The following example shows the various effects of stacking order.
1814
1815 \table
1816 \row
1817 \o \image declarative-item_stacking1.png
1818 \o Same \c z - later children above earlier children:
1819 \qml
1820 Item {
1821 Rectangle {
1822 color: "red"
1823 width: 100; height: 100
1824 }
1825 Rectangle {
1826 color: "blue"
1827 x: 50; y: 50; width: 100; height: 100
1828 }
1829 }
1830 \endqml
1831 \row
1832 \o \image declarative-item_stacking2.png
1833 \o Higher \c z on top:
1834 \qml
1835 Item {
1836 Rectangle {
1837 z: 1
1838 color: "red"
1839 width: 100; height: 100
1840 }
1841 Rectangle {
1842 color: "blue"
1843 x: 50; y: 50; width: 100; height: 100
1844 }
1845 }
1846 \endqml
1847 \row
1848 \o \image declarative-item_stacking3.png
1849 \o Same \c z - children above parents:
1850 \qml
1851 Item {
1852 Rectangle {
1853 color: "red"
1854 width: 100; height: 100
1855 Rectangle {
1856 color: "blue"
1857 x: 50; y: 50; width: 100; height: 100
1858 }
1859 }
1860 }
1861 \endqml
1862 \row
1863 \o \image declarative-item_stacking4.png
1864 \o Lower \c z below:
1865 \qml
1866 Item {
1867 Rectangle {
1868 color: "red"
1869 width: 100; height: 100
1870 Rectangle {
1871 z: -1
1872 color: "blue"
1873 x: 50; y: 50; width: 100; height: 100
1874 }
1875 }
1876 }
1877 \endqml
1878 \endtable
1879 */
1880
1881/*!
1882 \qmlproperty bool Item::visible
1883
1884 Whether the item is visible. By default this is true.
1885
1886 \note visible is not linked to actual visibility; if an item
1887 moves off screen, or the opacity changes to 0, this will
1888 not affect the visible property.
1889*/
1890
1891
1892/*!
1893 This function is called to handle this item's changes in
1894 geometry from \a oldGeometry to \a newGeometry. If the two
1895 geometries are the same, it doesn't do anything.
1896 */
1897void QDeclarativeItem::geometryChanged(const QRectF &newGeometry,
1898 const QRectF &oldGeometry)
1899{
1900 Q_D(QDeclarativeItem);
1901
1902 if (d->_anchors)
1903 d->_anchors->d_func()->updateMe();
1904
1905 if (transformOrigin() != QDeclarativeItem::TopLeft
1906 && (newGeometry.width() != oldGeometry.width() || newGeometry.height() != oldGeometry.height())) {
1907 if (d->transformData) {
1908 QPointF origin = d->computeTransformOrigin();
1909 if (transformOriginPoint() != origin)
1910 setTransformOriginPoint(origin);
1911 } else {
1912 d->transformOriginDirty = true;
1913 }
1914 }
1915
1916 for(int ii = 0; ii < d->changeListeners.count(); ++ii) {
1917 const QDeclarativeItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
1918 if (change.types & QDeclarativeItemPrivate::Geometry)
1919 change.listener->itemGeometryChanged(this, newGeometry, oldGeometry);
1920 }
1921
1922 if (newGeometry.width() != oldGeometry.width())
1923 emit widthChanged();
1924 if (newGeometry.height() != oldGeometry.height())
1925 emit heightChanged();
1926}
1927
1928void QDeclarativeItemPrivate::removeItemChangeListener(QDeclarativeItemChangeListener *listener, ChangeTypes types)
1929{
1930 ChangeListener change(listener, types);
1931 changeListeners.removeOne(change);
1932}
1933
1934/*! \internal */
1935void QDeclarativeItem::keyPressEvent(QKeyEvent *event)
1936{
1937 Q_D(QDeclarativeItem);
1938 keyPressPreHandler(event);
1939 if (event->isAccepted())
1940 return;
1941 if (d->keyHandler)
1942 d->keyHandler->keyPressed(event, true);
1943 else
1944 event->ignore();
1945}
1946
1947/*! \internal */
1948void QDeclarativeItem::keyReleaseEvent(QKeyEvent *event)
1949{
1950 Q_D(QDeclarativeItem);
1951 keyReleasePreHandler(event);
1952 if (event->isAccepted())
1953 return;
1954 if (d->keyHandler)
1955 d->keyHandler->keyReleased(event, true);
1956 else
1957 event->ignore();
1958}
1959
1960/*! \internal */
1961void QDeclarativeItem::inputMethodEvent(QInputMethodEvent *event)
1962{
1963 Q_D(QDeclarativeItem);
1964 inputMethodPreHandler(event);
1965 if (event->isAccepted())
1966 return;
1967 if (d->keyHandler)
1968 d->keyHandler->inputMethodEvent(event, true);
1969 else
1970 event->ignore();
1971}
1972
1973/*! \internal */
1974QVariant QDeclarativeItem::inputMethodQuery(Qt::InputMethodQuery query) const
1975{
1976 Q_D(const QDeclarativeItem);
1977 QVariant v;
1978 if (d->keyHandler)
1979 v = d->keyHandler->inputMethodQuery(query);
1980
1981 if (!v.isValid())
1982 v = QGraphicsObject::inputMethodQuery(query);
1983
1984 return v;
1985}
1986
1987/*!
1988 \internal
1989 */
1990void QDeclarativeItem::keyPressPreHandler(QKeyEvent *event)
1991{
1992 Q_D(QDeclarativeItem);
1993 if (d->keyHandler && !d->doneEventPreHandler)
1994 d->keyHandler->keyPressed(event, false);
1995 else
1996 event->ignore();
1997 d->doneEventPreHandler = true;
1998}
1999
2000/*!
2001 \internal
2002 */
2003void QDeclarativeItem::keyReleasePreHandler(QKeyEvent *event)
2004{
2005 Q_D(QDeclarativeItem);
2006 if (d->keyHandler && !d->doneEventPreHandler)
2007 d->keyHandler->keyReleased(event, false);
2008 else
2009 event->ignore();
2010 d->doneEventPreHandler = true;
2011}
2012
2013/*!
2014 \internal
2015 */
2016void QDeclarativeItem::inputMethodPreHandler(QInputMethodEvent *event)
2017{
2018 Q_D(QDeclarativeItem);
2019 if (d->keyHandler && !d->doneEventPreHandler)
2020 d->keyHandler->inputMethodEvent(event, false);
2021 else
2022 event->ignore();
2023 d->doneEventPreHandler = true;
2024}
2025
2026/*!
2027 \internal
2028*/
2029QDeclarativeAnchorLine QDeclarativeItemPrivate::left() const
2030{
2031 return anchorLines()->left;
2032}
2033
2034/*!
2035 \internal
2036*/
2037QDeclarativeAnchorLine QDeclarativeItemPrivate::right() const
2038{
2039 return anchorLines()->right;
2040}
2041
2042/*!
2043 \internal
2044*/
2045QDeclarativeAnchorLine QDeclarativeItemPrivate::horizontalCenter() const
2046{
2047 return anchorLines()->hCenter;
2048}
2049
2050/*!
2051 \internal
2052*/
2053QDeclarativeAnchorLine QDeclarativeItemPrivate::top() const
2054{
2055 return anchorLines()->top;
2056}
2057
2058/*!
2059 \internal
2060*/
2061QDeclarativeAnchorLine QDeclarativeItemPrivate::bottom() const
2062{
2063 return anchorLines()->bottom;
2064}
2065
2066/*!
2067 \internal
2068*/
2069QDeclarativeAnchorLine QDeclarativeItemPrivate::verticalCenter() const
2070{
2071 return anchorLines()->vCenter;
2072}
2073
2074
2075/*!
2076 \internal
2077*/
2078QDeclarativeAnchorLine QDeclarativeItemPrivate::baseline() const
2079{
2080 return anchorLines()->baseline;
2081}
2082
2083/*!
2084 \qmlproperty AnchorLine Item::anchors.top
2085 \qmlproperty AnchorLine Item::anchors.bottom
2086 \qmlproperty AnchorLine Item::anchors.left
2087 \qmlproperty AnchorLine Item::anchors.right
2088 \qmlproperty AnchorLine Item::anchors.horizontalCenter
2089 \qmlproperty AnchorLine Item::anchors.verticalCenter
2090 \qmlproperty AnchorLine Item::anchors.baseline
2091
2092 \qmlproperty Item Item::anchors.fill
2093 \qmlproperty Item Item::anchors.centerIn
2094
2095 \qmlproperty real Item::anchors.margins
2096 \qmlproperty real Item::anchors.topMargin
2097 \qmlproperty real Item::anchors.bottomMargin
2098 \qmlproperty real Item::anchors.leftMargin
2099 \qmlproperty real Item::anchors.rightMargin
2100 \qmlproperty real Item::anchors.horizontalCenterOffset
2101 \qmlproperty real Item::anchors.verticalCenterOffset
2102 \qmlproperty real Item::anchors.baselineOffset
2103
2104 Anchors provide a way to position an item by specifying its
2105 relationship with other items.
2106
2107 Margins apply to top, bottom, left, right, and fill anchors.
2108 The \c anchors.margins property can be used to set all of the various margins at once, to the same value.
2109 Note that margins are anchor-specific and are not applied if an item does not
2110 use anchors.
2111
2112 Offsets apply for horizontal center, vertical center, and baseline anchors.
2113
2114 \table
2115 \row
2116 \o \image declarative-anchors_example.png
2117 \o Text anchored to Image, horizontally centered and vertically below, with a margin.
2118 \qml
2119 Image { id: pic; ... }
2120 Text {
2121 id: label
2122 anchors.horizontalCenter: pic.horizontalCenter
2123 anchors.top: pic.bottom
2124 anchors.topMargin: 5
2125 ...
2126 }
2127 \endqml
2128 \row
2129 \o \image declarative-anchors_example2.png
2130 \o
2131 Left of Text anchored to right of Image, with a margin. The y
2132 property of both defaults to 0.
2133
2134 \qml
2135 Image { id: pic; ... }
2136 Text {
2137 id: label
2138 anchors.left: pic.right
2139 anchors.leftMargin: 5
2140 ...
2141 }
2142 \endqml
2143 \endtable
2144
2145 \c anchors.fill provides a convenient way for one item to have the
2146 same geometry as another item, and is equivalent to connecting all
2147 four directional anchors.
2148
2149 To clear an anchor value, set it to \c undefined.
2150
2151 \note You can only anchor an item to siblings or a parent.
2152
2153 For more information see \l {anchor-layout}{Anchor Layouts}.
2154*/
2155
2156/*!
2157 \property QDeclarativeItem::baselineOffset
2158 \brief The position of the item's baseline in local coordinates.
2159
2160 The baseline of a \l Text item is the imaginary line on which the text
2161 sits. Controls containing text usually set their baseline to the
2162 baseline of their text.
2163
2164 For non-text items, a default baseline offset of 0 is used.
2165*/
2166qreal QDeclarativeItem::baselineOffset() const
2167{
2168 Q_D(const QDeclarativeItem);
2169 if (!d->baselineOffset.isValid()) {
2170 return 0.0;
2171 } else
2172 return d->baselineOffset;
2173}
2174
2175void QDeclarativeItem::setBaselineOffset(qreal offset)
2176{
2177 Q_D(QDeclarativeItem);
2178 if (offset == d->baselineOffset)
2179 return;
2180
2181 d->baselineOffset = offset;
2182
2183 for(int ii = 0; ii < d->changeListeners.count(); ++ii) {
2184 const QDeclarativeItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
2185 if (change.types & QDeclarativeItemPrivate::Geometry) {
2186 QDeclarativeAnchorsPrivate *anchor = change.listener->anchorPrivate();
2187 if (anchor)
2188 anchor->updateVerticalAnchors();
2189 }
2190 }
2191 emit baselineOffsetChanged(offset);
2192}
2193
2194/*!
2195 \qmlproperty real Item::rotation
2196 This property holds the rotation of the item in degrees clockwise.
2197
2198 This specifies how many degrees to rotate the item around its transformOrigin.
2199 The default rotation is 0 degrees (i.e. not rotated at all).
2200
2201 \table
2202 \row
2203 \o \image declarative-rotation.png
2204 \o
2205 \qml
2206 Rectangle {
2207 color: "blue"
2208 width: 100; height: 100
2209 Rectangle {
2210 color: "red"
2211 x: 25; y: 25; width: 50; height: 50
2212 rotation: 30
2213 }
2214 }
2215 \endqml
2216 \endtable
2217
2218 \sa transform, Rotation
2219*/
2220
2221/*!
2222 \qmlproperty real Item::scale
2223 This property holds the scale of the item.
2224
2225 A scale of less than 1 means the item will be displayed smaller than
2226 normal, and a scale of greater than 1 means the item will be
2227 displayed larger than normal. A negative scale means the item will
2228 be mirrored.
2229
2230 By default, items are displayed at a scale of 1 (i.e. at their
2231 normal size).
2232
2233 Scaling is from the item's transformOrigin.
2234
2235 \table
2236 \row
2237 \o \image declarative-scale.png
2238 \o
2239 \qml
2240 Rectangle {
2241 color: "blue"
2242 width: 100; height: 100
2243 Rectangle {
2244 color: "green"
2245 width: 25; height: 25
2246 }
2247 Rectangle {
2248 color: "red"
2249 x: 25; y: 25; width: 50; height: 50
2250 scale: 1.4
2251 }
2252 }
2253 \endqml
2254 \endtable
2255
2256 \sa transform, Scale
2257*/
2258
2259/*!
2260 \qmlproperty real Item::opacity
2261
2262 The opacity of the item. Opacity is specified as a number between 0
2263 (fully transparent) and 1 (fully opaque). The default is 1.
2264
2265 Opacity is an \e inherited attribute. That is, the opacity is
2266 also applied individually to child items. In almost all cases this
2267 is what you want, but in some cases (like the following example)
2268 it may produce undesired results.
2269
2270 \table
2271 \row
2272 \o \image declarative-item_opacity1.png
2273 \o
2274 \qml
2275 Item {
2276 Rectangle {
2277 color: "red"
2278 width: 100; height: 100
2279 Rectangle {
2280 color: "blue"
2281 x: 50; y: 50; width: 100; height: 100
2282 }
2283 }
2284 }
2285 \endqml
2286 \row
2287 \o \image declarative-item_opacity2.png
2288 \o
2289 \qml
2290 Item {
2291 Rectangle {
2292 opacity: 0.5
2293 color: "red"
2294 width: 100; height: 100
2295 Rectangle {
2296 color: "blue"
2297 x: 50; y: 50; width: 100; height: 100
2298 }
2299 }
2300 }
2301 \endqml
2302 \endtable
2303*/
2304
2305/*!
2306 Returns a value indicating whether mouse input should
2307 remain with this item exclusively.
2308
2309 \sa setKeepMouseGrab()
2310 */
2311bool QDeclarativeItem::keepMouseGrab() const
2312{
2313 Q_D(const QDeclarativeItem);
2314 return d->keepMouse;
2315}
2316
2317/*!
2318 The flag indicating whether the mouse should remain
2319 with this item is set to \a keep.
2320
2321 This is useful for items that wish to grab and keep mouse
2322 interaction following a predefined gesture. For example,
2323 an item that is interested in horizontal mouse movement
2324 may set keepMouseGrab to true once a threshold has been
2325 exceeded. Once keepMouseGrab has been set to true, filtering
2326 items will not react to mouse events.
2327
2328 If the item does not indicate that it wishes to retain mouse grab,
2329 a filtering item may steal the grab. For example, Flickable may attempt
2330 to steal a mouse grab if it detects that the user has begun to
2331 move the viewport.
2332
2333 \sa keepMouseGrab()
2334 */
2335void QDeclarativeItem::setKeepMouseGrab(bool keep)
2336{
2337 Q_D(QDeclarativeItem);
2338 d->keepMouse = keep;
2339}
2340
2341/*!
2342 \qmlmethod object Item::mapFromItem(Item item, real x, real y)
2343
2344 Maps the point (\a x, \a y), which is in \a item's coordinate system, to
2345 this item's coordinate system, and returns an object with \c x and \c y
2346 properties matching the mapped cooordinate.
2347
2348 If \a item is a \c null value, this maps the point from the coordinate
2349 system of the root QML view.
2350*/
2351QScriptValue QDeclarativeItem::mapFromItem(const QScriptValue &item, qreal x, qreal y) const
2352{
2353 QScriptValue sv = QDeclarativeEnginePrivate::getScriptEngine(qmlEngine(this))->newObject();
2354 QDeclarativeItem *itemObj = qobject_cast<QDeclarativeItem*>(item.toQObject());
2355 if (!itemObj && !item.isNull()) {
2356 qmlInfo(this) << "mapFromItem() given argument \"" << item.toString() << "\" which is neither null nor an Item";
2357 return 0;
2358 }
2359
2360 // If QGraphicsItem::mapFromItem() is called with 0, behaves the same as mapFromScene()
2361 QPointF p = qobject_cast<QGraphicsItem*>(this)->mapFromItem(itemObj, x, y);
2362 sv.setProperty(QLatin1String("x"), p.x());
2363 sv.setProperty(QLatin1String("y"), p.y());
2364 return sv;
2365}
2366
2367/*!
2368 \qmlmethod object Item::mapToItem(Item item, real x, real y)
2369
2370 Maps the point (\a x, \a y), which is in this item's coordinate system, to
2371 \a item's coordinate system, and returns an object with \c x and \c y
2372 properties matching the mapped cooordinate.
2373
2374 If \a item is a \c null value, this maps \a x and \a y to the coordinate
2375 system of the root QML view.
2376*/
2377QScriptValue QDeclarativeItem::mapToItem(const QScriptValue &item, qreal x, qreal y) const
2378{
2379 QScriptValue sv = QDeclarativeEnginePrivate::getScriptEngine(qmlEngine(this))->newObject();
2380 QDeclarativeItem *itemObj = qobject_cast<QDeclarativeItem*>(item.toQObject());
2381 if (!itemObj && !item.isNull()) {
2382 qmlInfo(this) << "mapToItem() given argument \"" << item.toString() << "\" which is neither null nor an Item";
2383 return 0;
2384 }
2385
2386 // If QGraphicsItem::mapToItem() is called with 0, behaves the same as mapToScene()
2387 QPointF p = qobject_cast<QGraphicsItem*>(this)->mapToItem(itemObj, x, y);
2388 sv.setProperty(QLatin1String("x"), p.x());
2389 sv.setProperty(QLatin1String("y"), p.y());
2390 return sv;
2391}
2392
2393/*!
2394 \qmlmethod Item::forceActiveFocus()
2395
2396 Force active focus on the item.
2397 This method sets focus on the item and makes sure that all the focus scopes higher in the object hierarchy are also given focus.
2398*/
2399void QDeclarativeItem::forceActiveFocus()
2400{
2401 setFocus(true);
2402 QGraphicsItem *parent = parentItem();
2403 while (parent) {
2404 if (parent->flags() & QGraphicsItem::ItemIsFocusScope)
2405 parent->setFocus(Qt::OtherFocusReason);
2406 parent = parent->parentItem();
2407 }
2408}
2409
2410
2411/*!
2412 \qmlmethod Item::childAt(real x, real y)
2413
2414 Returns the visible child item at point (\a x, \a y), which is in this
2415 item's coordinate system, or \c null if there is no such item.
2416 */
2417QDeclarativeItem *QDeclarativeItem::childAt(qreal x, qreal y) const
2418{
2419 const QList<QGraphicsItem *> children = childItems();
2420 for (int i = children.count()-1; i >= 0; --i) {
2421 if (QDeclarativeItem *child = qobject_cast<QDeclarativeItem *>(children.at(i))) {
2422 if (child->isVisible() && child->x() <= x
2423 && child->x() + child->width() >= x
2424 && child->y() <= y
2425 && child->y() + child->height() >= y)
2426 return child;
2427 }
2428 }
2429 return 0;
2430}
2431
2432void QDeclarativeItemPrivate::focusChanged(bool flag)
2433{
2434 Q_Q(QDeclarativeItem);
2435 if (!(flags & QGraphicsItem::ItemIsFocusScope) && parent)
2436 emit q->activeFocusChanged(flag); //see also QDeclarativeItemPrivate::subFocusItemChange()
2437 emit q->focusChanged(flag);
2438}
2439
2440QDeclarativeListProperty<QObject> QDeclarativeItemPrivate::resources()
2441{
2442 return QDeclarativeListProperty<QObject>(q_func(), 0, QDeclarativeItemPrivate::resources_append,
2443 QDeclarativeItemPrivate::resources_count,
2444 QDeclarativeItemPrivate::resources_at,
2445 QDeclarativeItemPrivate::resources_clear
2446 );
2447}
2448
2449/*!
2450 \qmlproperty list<State> Item::states
2451 This property holds a list of states defined by the item.
2452
2453 \qml
2454 Item {
2455 states: [
2456 State { ... },
2457 State { ... }
2458 ...
2459 ]
2460 }
2461 \endqml
2462
2463 \sa {qmlstate}{States}
2464*/
2465
2466QDeclarativeListProperty<QDeclarativeState> QDeclarativeItemPrivate::states()
2467{
2468 return _states()->statesProperty();
2469}
2470
2471/*!
2472 \qmlproperty list<Transition> Item::transitions
2473 This property holds a list of transitions defined by the item.
2474
2475 \qml
2476 Item {
2477 transitions: [
2478 Transition { ... },
2479 Transition { ... }
2480 ...
2481 ]
2482 }
2483 \endqml
2484
2485 \sa {qdeclarativeanimation.html#transitions}{QML Transitions}
2486*/
2487
2488
2489QDeclarativeListProperty<QDeclarativeTransition> QDeclarativeItemPrivate::transitions()
2490{
2491 return _states()->transitionsProperty();
2492}
2493
2494/*
2495 \qmlproperty list<Filter> Item::filter
2496 This property holds a list of graphical filters to be applied to the item.
2497
2498 \l {Filter}{Filters} include things like \l {Blur}{blurring}
2499 the item, or giving it a \l Reflection. Some
2500 filters may not be available on all canvases; if a filter is not
2501 available on a certain canvas, it will simply not be applied for
2502 that canvas (but the QML will still be considered valid).
2503
2504 \qml
2505 Item {
2506 filter: [
2507 Blur { ... },
2508 Reflection { ... }
2509 ...
2510 ]
2511 }
2512 \endqml
2513*/
2514
2515/*!
2516 \qmlproperty bool Item::clip
2517 This property holds whether clipping is enabled. The default clip value is \c false.
2518
2519 If clipping is enabled, an item will clip its own painting, as well
2520 as the painting of its children, to its bounding rectangle.
2521
2522 Non-rectangular clipping regions are not supported for performance reasons.
2523*/
2524
2525/*!
2526 \property QDeclarativeItem::clip
2527 This property holds whether clipping is enabled. The default clip value is \c false.
2528
2529 If clipping is enabled, an item will clip its own painting, as well
2530 as the painting of its children, to its bounding rectangle. If you set
2531 clipping during an item's paint operation, remember to re-set it to
2532 prevent clipping the rest of your scene.
2533
2534 Non-rectangular clipping regions are not supported for performance reasons.
2535*/
2536
2537/*!
2538 \qmlproperty string Item::state
2539
2540 This property holds the name of the current state of the item.
2541
2542 This property is often used in scripts to change between states. For
2543 example:
2544
2545 \qml
2546 function toggle() {
2547 if (button.state == 'On')
2548 button.state = 'Off';
2549 else
2550 button.state = 'On';
2551 }
2552 \endqml
2553
2554 If the item is in its base state (i.e. no explicit state has been
2555 set), \c state will be a blank string. Likewise, you can return an
2556 item to its base state by setting its current state to \c ''.
2557
2558 \sa {qmlstates}{States}
2559*/
2560
2561QString QDeclarativeItemPrivate::state() const
2562{
2563 if (!_stateGroup)
2564 return QString();
2565 else
2566 return _stateGroup->state();
2567}
2568
2569void QDeclarativeItemPrivate::setState(const QString &state)
2570{
2571 _states()->setState(state);
2572}
2573
2574/*!
2575 \qmlproperty list<Transform> Item::transform
2576 This property holds the list of transformations to apply.
2577
2578 For more information see \l Transform.
2579*/
2580
2581/*! \internal */
2582QDeclarativeListProperty<QGraphicsTransform> QDeclarativeItem::transform()
2583{
2584 Q_D(QDeclarativeItem);
2585 return QDeclarativeListProperty<QGraphicsTransform>(this, 0, d->transform_append, d->transform_count,
2586 d->transform_at, d->transform_clear);
2587}
2588
2589/*!
2590 \internal
2591
2592 classBegin() is called when the item is constructed, but its
2593 properties have not yet been set.
2594
2595 \sa componentComplete(), isComponentComplete()
2596*/
2597void QDeclarativeItem::classBegin()
2598{
2599 Q_D(QDeclarativeItem);
2600 d->componentComplete = false;
2601 if (d->_stateGroup)
2602 d->_stateGroup->classBegin();
2603 if (d->_anchors)
2604 d->_anchors->classBegin();
2605}
2606
2607/*!
2608 \internal
2609
2610 componentComplete() is called when all items in the component
2611 have been constructed. It is often desirable to delay some
2612 processing until the component is complete an all bindings in the
2613 component have been resolved.
2614*/
2615void QDeclarativeItem::componentComplete()
2616{
2617 Q_D(QDeclarativeItem);
2618 d->componentComplete = true;
2619 if (d->_stateGroup)
2620 d->_stateGroup->componentComplete();
2621 if (d->_anchors) {
2622 d->_anchors->componentComplete();
2623 d->_anchors->d_func()->updateOnComplete();
2624 }
2625 if (d->keyHandler)
2626 d->keyHandler->componentComplete();
2627 if (d->_contents)
2628 d->_contents->complete();
2629}
2630
2631QDeclarativeStateGroup *QDeclarativeItemPrivate::_states()
2632{
2633 Q_Q(QDeclarativeItem);
2634 if (!_stateGroup) {
2635 _stateGroup = new QDeclarativeStateGroup;
2636 if (!componentComplete)
2637 _stateGroup->classBegin();
2638 QObject::connect(_stateGroup, SIGNAL(stateChanged(QString)),
2639 q, SIGNAL(stateChanged(QString)));
2640 }
2641
2642 return _stateGroup;
2643}
2644
2645QDeclarativeItemPrivate::AnchorLines::AnchorLines(QGraphicsObject *q)
2646{
2647 left.item = q;
2648 left.anchorLine = QDeclarativeAnchorLine::Left;
2649 right.item = q;
2650 right.anchorLine = QDeclarativeAnchorLine::Right;
2651 hCenter.item = q;
2652 hCenter.anchorLine = QDeclarativeAnchorLine::HCenter;
2653 top.item = q;
2654 top.anchorLine = QDeclarativeAnchorLine::Top;
2655 bottom.item = q;
2656 bottom.anchorLine = QDeclarativeAnchorLine::Bottom;
2657 vCenter.item = q;
2658 vCenter.anchorLine = QDeclarativeAnchorLine::VCenter;
2659 baseline.item = q;
2660 baseline.anchorLine = QDeclarativeAnchorLine::Baseline;
2661}
2662
2663QPointF QDeclarativeItemPrivate::computeTransformOrigin() const
2664{
2665 Q_Q(const QDeclarativeItem);
2666
2667 QRectF br = q->boundingRect();
2668
2669 switch(origin) {
2670 default:
2671 case QDeclarativeItem::TopLeft:
2672 return QPointF(0, 0);
2673 case QDeclarativeItem::Top:
2674 return QPointF(br.width() / 2., 0);
2675 case QDeclarativeItem::TopRight:
2676 return QPointF(br.width(), 0);
2677 case QDeclarativeItem::Left:
2678 return QPointF(0, br.height() / 2.);
2679 case QDeclarativeItem::Center:
2680 return QPointF(br.width() / 2., br.height() / 2.);
2681 case QDeclarativeItem::Right:
2682 return QPointF(br.width(), br.height() / 2.);
2683 case QDeclarativeItem::BottomLeft:
2684 return QPointF(0, br.height());
2685 case QDeclarativeItem::Bottom:
2686 return QPointF(br.width() / 2., br.height());
2687 case QDeclarativeItem::BottomRight:
2688 return QPointF(br.width(), br.height());
2689 }
2690}
2691
2692/*! \internal */
2693bool QDeclarativeItem::sceneEvent(QEvent *event)
2694{
2695 Q_D(QDeclarativeItem);
2696 if (event->type() == QEvent::KeyPress) {
2697 QKeyEvent *k = static_cast<QKeyEvent *>(event);
2698 if ((k->key() == Qt::Key_Tab || k->key() == Qt::Key_Backtab) &&
2699 !(k->modifiers() & (Qt::ControlModifier | Qt::AltModifier))) {
2700 keyPressEvent(static_cast<QKeyEvent *>(event));
2701 if (!event->isAccepted())
2702 return QGraphicsItem::sceneEvent(event);
2703 else
2704 return true;
2705 } else {
2706 return QGraphicsItem::sceneEvent(event);
2707 }
2708 } else {
2709 bool rv = QGraphicsItem::sceneEvent(event);
2710
2711 if (event->type() == QEvent::FocusIn ||
2712 event->type() == QEvent::FocusOut) {
2713 d->focusChanged(hasActiveFocus());
2714 }
2715 return rv;
2716 }
2717}
2718
2719/*!
2720 \internal
2721
2722 Note that unlike QGraphicsItems, QDeclarativeItem::itemChange() is \e not called
2723 during initial widget polishing. Items wishing to optimize start-up construction
2724 should instead consider using componentComplete().
2725*/
2726QVariant QDeclarativeItem::itemChange(GraphicsItemChange change,
2727 const QVariant &value)
2728{
2729 Q_D(QDeclarativeItem);
2730 switch (change) {
2731 case ItemParentHasChanged:
2732 emit parentChanged(parentItem());
2733 d->parentNotifier.notify();
2734 break;
2735 case ItemVisibleHasChanged: {
2736 for(int ii = 0; ii < d->changeListeners.count(); ++ii) {
2737 const QDeclarativeItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
2738 if (change.types & QDeclarativeItemPrivate::Visibility) {
2739 change.listener->itemVisibilityChanged(this);
2740 }
2741 }
2742 }
2743 break;
2744 case ItemOpacityHasChanged: {
2745 for(int ii = 0; ii < d->changeListeners.count(); ++ii) {
2746 const QDeclarativeItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
2747 if (change.types & QDeclarativeItemPrivate::Opacity) {
2748 change.listener->itemOpacityChanged(this);
2749 }
2750 }
2751 }
2752 break;
2753 case ItemChildAddedChange:
2754 if (d->_contents && d->componentComplete)
2755 d->_contents->childAdded(qobject_cast<QDeclarativeItem*>(
2756 value.value<QGraphicsItem*>()));
2757 break;
2758 case ItemChildRemovedChange:
2759 if (d->_contents && d->componentComplete)
2760 d->_contents->childRemoved(qobject_cast<QDeclarativeItem*>(
2761 value.value<QGraphicsItem*>()));
2762 break;
2763 default:
2764 break;
2765 }
2766
2767 return QGraphicsItem::itemChange(change, value);
2768}
2769
2770/*! \internal */
2771QRectF QDeclarativeItem::boundingRect() const
2772{
2773 Q_D(const QDeclarativeItem);
2774 return QRectF(0, 0, d->mWidth, d->mHeight);
2775}
2776
2777/*!
2778 \enum QDeclarativeItem::TransformOrigin
2779
2780 Controls the point about which simple transforms like scale apply.
2781
2782 \value TopLeft The top-left corner of the item.
2783 \value Top The center point of the top of the item.
2784 \value TopRight The top-right corner of the item.
2785 \value Left The left most point of the vertical middle.
2786 \value Center The center of the item.
2787 \value Right The right most point of the vertical middle.
2788 \value BottomLeft The bottom-left corner of the item.
2789 \value Bottom The center point of the bottom of the item.
2790 \value BottomRight The bottom-right corner of the item.
2791*/
2792
2793/*!
2794 Returns the current transform origin.
2795*/
2796QDeclarativeItem::TransformOrigin QDeclarativeItem::transformOrigin() const
2797{
2798 Q_D(const QDeclarativeItem);
2799 return d->origin;
2800}
2801
2802/*!
2803 Set the transform \a origin.
2804*/
2805void QDeclarativeItem::setTransformOrigin(TransformOrigin origin)
2806{
2807 Q_D(QDeclarativeItem);
2808 if (origin != d->origin) {
2809 d->origin = origin;
2810 if (d->transformData)
2811 QGraphicsItem::setTransformOriginPoint(d->computeTransformOrigin());
2812 else
2813 d->transformOriginDirty = true;
2814 emit transformOriginChanged(d->origin);
2815 }
2816}
2817
2818void QDeclarativeItemPrivate::transformChanged()
2819{
2820 Q_Q(QDeclarativeItem);
2821 if (transformOriginDirty) {
2822 q->QGraphicsItem::setTransformOriginPoint(computeTransformOrigin());
2823 transformOriginDirty = false;
2824 }
2825}
2826
2827/*!
2828 \property QDeclarativeItem::smooth
2829 \brief whether the item is smoothly transformed.
2830
2831 This property is provided purely for the purpose of optimization. Turning
2832 smooth transforms off is faster, but looks worse; turning smooth
2833 transformations on is slower, but looks better.
2834
2835 By default smooth transformations are off.
2836*/
2837
2838/*!
2839 Returns true if the item should be drawn with antialiasing and
2840 smooth pixmap filtering, false otherwise.
2841
2842 The default is false.
2843
2844 \sa setSmooth()
2845*/
2846bool QDeclarativeItem::smooth() const
2847{
2848 Q_D(const QDeclarativeItem);
2849 return d->smooth;
2850}
2851
2852/*!
2853 Sets whether the item should be drawn with antialiasing and
2854 smooth pixmap filtering to \a smooth.
2855
2856 \sa smooth()
2857*/
2858void QDeclarativeItem::setSmooth(bool smooth)
2859{
2860 Q_D(QDeclarativeItem);
2861 if (d->smooth == smooth)
2862 return;
2863 d->smooth = smooth;
2864 emit smoothChanged(smooth);
2865 update();
2866}
2867
2868/*!
2869 \property QDeclarativeItem::anchors
2870 \internal
2871*/
2872
2873/*!
2874 \property QDeclarativeItem::left
2875 \internal
2876*/
2877
2878/*!
2879 \property QDeclarativeItem::right
2880 \internal
2881*/
2882
2883/*!
2884 \property QDeclarativeItem::horizontalCenter
2885 \internal
2886*/
2887
2888/*!
2889 \property QDeclarativeItem::top
2890 \internal
2891*/
2892
2893/*!
2894 \property QDeclarativeItem::bottom
2895 \internal
2896*/
2897
2898/*!
2899 \property QDeclarativeItem::verticalCenter
2900 \internal
2901*/
2902
2903/*!
2904 \property QDeclarativeItem::focus
2905 \internal
2906*/
2907
2908/*!
2909 \property QDeclarativeItem::transform
2910 \internal
2911*/
2912
2913/*!
2914 \property QDeclarativeItem::transformOrigin
2915 \internal
2916*/
2917
2918/*!
2919 \property QDeclarativeItem::activeFocus
2920 \internal
2921*/
2922
2923/*!
2924 \property QDeclarativeItem::baseline
2925 \internal
2926*/
2927
2928/*!
2929 \property QDeclarativeItem::data
2930 \internal
2931*/
2932
2933/*!
2934 \property QDeclarativeItem::resources
2935 \internal
2936*/
2937
2938/*!
2939 \property QDeclarativeItem::state
2940 \internal
2941*/
2942
2943/*!
2944 \property QDeclarativeItem::states
2945 \internal
2946*/
2947
2948/*!
2949 \property QDeclarativeItem::transformOriginPoint
2950 \internal
2951*/
2952
2953/*!
2954 \property QDeclarativeItem::transitions
2955 \internal
2956*/
2957
2958/*!
2959 \internal
2960 Return the width of the item
2961*/
2962qreal QDeclarativeItem::width() const
2963{
2964 Q_D(const QDeclarativeItem);
2965 return d->width();
2966}
2967
2968/*!
2969 \internal
2970 Set the width of the item
2971*/
2972void QDeclarativeItem::setWidth(qreal w)
2973{
2974 Q_D(QDeclarativeItem);
2975 d->setWidth(w);
2976}
2977
2978/*!
2979 \internal
2980 Reset the width of the item
2981*/
2982void QDeclarativeItem::resetWidth()
2983{
2984 Q_D(QDeclarativeItem);
2985 d->resetWidth();
2986}
2987
2988/*!
2989 \internal
2990 Return the width of the item
2991*/
2992qreal QDeclarativeItemPrivate::width() const
2993{
2994 return mWidth;
2995}
2996
2997/*!
2998 \internal
2999*/
3000void QDeclarativeItemPrivate::setWidth(qreal w)
3001{
3002 Q_Q(QDeclarativeItem);
3003 if (qIsNaN(w))
3004 return;
3005
3006 widthValid = true;
3007 if (mWidth == w)
3008 return;
3009
3010 qreal oldWidth = mWidth;
3011
3012 q->prepareGeometryChange();
3013 mWidth = w;
3014
3015 q->geometryChanged(QRectF(q->x(), q->y(), width(), height()),
3016 QRectF(q->x(), q->y(), oldWidth, height()));
3017}
3018
3019/*!
3020 \internal
3021*/
3022void QDeclarativeItemPrivate::resetWidth()
3023{
3024 Q_Q(QDeclarativeItem);
3025 widthValid = false;
3026 q->setImplicitWidth(q->implicitWidth());
3027}
3028
3029/*!
3030 Returns the width of the item that is implied by other properties that determine the content.
3031*/
3032qreal QDeclarativeItem::implicitWidth() const
3033{
3034 Q_D(const QDeclarativeItem);
3035 return d->implicitWidth;
3036}
3037
3038/*!
3039 Sets the implied width of the item to \a w.
3040 This is the width implied by other properties that determine the content.
3041*/
3042void QDeclarativeItem::setImplicitWidth(qreal w)
3043{
3044 Q_D(QDeclarativeItem);
3045 d->implicitWidth = w;
3046 if (d->mWidth == w || widthValid())
3047 return;
3048
3049 qreal oldWidth = d->mWidth;
3050
3051 prepareGeometryChange();
3052 d->mWidth = w;
3053
3054 geometryChanged(QRectF(x(), y(), width(), height()),
3055 QRectF(x(), y(), oldWidth, height()));
3056}
3057
3058/*!
3059 Returns whether the width property has been set explicitly.
3060*/
3061bool QDeclarativeItem::widthValid() const
3062{
3063 Q_D(const QDeclarativeItem);
3064 return d->widthValid;
3065}
3066
3067/*!
3068 \internal
3069 Return the height of the item
3070*/
3071qreal QDeclarativeItem::height() const
3072{
3073 Q_D(const QDeclarativeItem);
3074 return d->height();
3075}
3076
3077/*!
3078 \internal
3079 Set the height of the item
3080*/
3081void QDeclarativeItem::setHeight(qreal h)
3082{
3083 Q_D(QDeclarativeItem);
3084 d->setHeight(h);
3085}
3086
3087/*!
3088 \internal
3089 Reset the height of the item
3090*/
3091void QDeclarativeItem::resetHeight()
3092{
3093 Q_D(QDeclarativeItem);
3094 d->resetHeight();
3095}
3096
3097/*!
3098 \internal
3099*/
3100qreal QDeclarativeItemPrivate::height() const
3101{
3102 return mHeight;
3103}
3104
3105/*!
3106 \internal
3107*/
3108void QDeclarativeItemPrivate::setHeight(qreal h)
3109{
3110 Q_Q(QDeclarativeItem);
3111 if (qIsNaN(h))
3112 return;
3113
3114 heightValid = true;
3115 if (mHeight == h)
3116 return;
3117
3118 qreal oldHeight = mHeight;
3119
3120 q->prepareGeometryChange();
3121 mHeight = h;
3122
3123 q->geometryChanged(QRectF(q->x(), q->y(), width(), height()),
3124 QRectF(q->x(), q->y(), width(), oldHeight));
3125}
3126
3127/*!
3128 \internal
3129*/
3130void QDeclarativeItemPrivate::resetHeight()
3131{
3132 Q_Q(QDeclarativeItem);
3133 heightValid = false;
3134 q->setImplicitHeight(q->implicitHeight());
3135}
3136
3137/*!
3138 Returns the height of the item that is implied by other properties that determine the content.
3139*/
3140qreal QDeclarativeItem::implicitHeight() const
3141{
3142 Q_D(const QDeclarativeItem);
3143 return d->implicitHeight;
3144}
3145
3146/*!
3147 Sets the implied height of the item to \a h.
3148 This is the height implied by other properties that determine the content.
3149*/
3150void QDeclarativeItem::setImplicitHeight(qreal h)
3151{
3152 Q_D(QDeclarativeItem);
3153 d->implicitHeight = h;
3154 if (d->mHeight == h || heightValid())
3155 return;
3156
3157 qreal oldHeight = d->mHeight;
3158
3159 prepareGeometryChange();
3160 d->mHeight = h;
3161
3162 geometryChanged(QRectF(x(), y(), width(), height()),
3163 QRectF(x(), y(), width(), oldHeight));
3164}
3165
3166/*!
3167 Returns whether the height property has been set explicitly.
3168*/
3169bool QDeclarativeItem::heightValid() const
3170{
3171 Q_D(const QDeclarativeItem);
3172 return d->heightValid;
3173}
3174
3175/*! \internal */
3176void QDeclarativeItem::setSize(const QSizeF &size)
3177{
3178 Q_D(QDeclarativeItem);
3179 d->heightValid = true;
3180 d->widthValid = true;
3181
3182 if (d->height() == size.height() && d->width() == size.width())
3183 return;
3184
3185 qreal oldHeight = d->height();
3186 qreal oldWidth = d->width();
3187
3188 prepareGeometryChange();
3189 d->setHeight(size.height());
3190 d->setWidth(size.width());
3191
3192 geometryChanged(QRectF(x(), y(), width(), height()),
3193 QRectF(x(), y(), oldWidth, oldHeight));
3194}
3195
3196/*!
3197 \qmlproperty bool Item::activeFocus
3198
3199 This property indicates whether the item has active focus.
3200
3201 An item with active focus will receive keyboard input,
3202 or is a FocusScope ancestor of the item that will receive keyboard input.
3203
3204 Usually, activeFocus is gained by setting focus on an item and its enclosing
3205 FocusScopes. In the following example \c input will have activeFocus.
3206 \qml
3207 Rectangle {
3208 FocusScope {
3209 focus: true
3210 TextInput {
3211 id: input
3212 focus: true
3213 }
3214 }
3215 }
3216 \endqml
3217
3218 \sa focus, {qmlfocus}{Keyboard Focus}
3219*/
3220
3221/*! \internal */
3222bool QDeclarativeItem::hasActiveFocus() const
3223{
3224 Q_D(const QDeclarativeItem);
3225 return focusItem() == this ||
3226 (d->flags & QGraphicsItem::ItemIsFocusScope && focusItem() != 0);
3227}
3228
3229/*!
3230 \qmlproperty bool Item::focus
3231 This property indicates whether the item has focus within the enclosing focus scope. If true, this item
3232 will gain active focus when the enclosing focus scope gains active focus.
3233 In the following example, \c input will be given active focus when \c scope gains active focus.
3234 \qml
3235 Rectangle {
3236 FocusScope {
3237 id: scope
3238 TextInput {
3239 id: input
3240 focus: true
3241 }
3242 }
3243 }
3244 \endqml
3245
3246 For the purposes of this property, the scene as a whole is assumed to act like a focus scope.
3247 On a practical level, that means the following QML will give active focus to \c input on startup.
3248
3249 \qml
3250 Rectangle {
3251 TextInput {
3252 id: input
3253 focus: true
3254 }
3255 }
3256 \endqml
3257
3258 \sa activeFocus, {qmlfocus}{Keyboard Focus}
3259*/
3260
3261/*! \internal */
3262bool QDeclarativeItem::hasFocus() const
3263{
3264 Q_D(const QDeclarativeItem);
3265 QGraphicsItem *p = d->parent;
3266 while (p) {
3267 if (p->flags() & QGraphicsItem::ItemIsFocusScope) {
3268 return p->focusScopeItem() == this;
3269 }
3270 p = p->parentItem();
3271 }
3272
3273 return hasActiveFocus();
3274}
3275
3276/*! \internal */
3277void QDeclarativeItem::setFocus(bool focus)
3278{
3279 if (focus)
3280 QGraphicsItem::setFocus(Qt::OtherFocusReason);
3281 else
3282 QGraphicsItem::clearFocus();
3283}
3284
3285/*!
3286 \internal
3287*/
3288void QDeclarativeItem::paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *)
3289{
3290}
3291
3292/*!
3293 \internal
3294*/
3295bool QDeclarativeItem::event(QEvent *ev)
3296{
3297 Q_D(QDeclarativeItem);
3298 switch (ev->type()) {
3299 case QEvent::KeyPress:
3300 case QEvent::KeyRelease:
3301 case QEvent::InputMethod:
3302 d->doneEventPreHandler = false;
3303 break;
3304 default:
3305 break;
3306 }
3307
3308 return QGraphicsObject::event(ev);
3309}
3310
3311#ifndef QT_NO_DEBUG_STREAM
3312QDebug operator<<(QDebug debug, QDeclarativeItem *item)
3313{
3314 if (!item) {
3315 debug << "QDeclarativeItem(0)";
3316 return debug;
3317 }
3318
3319 debug << item->metaObject()->className() << "(this =" << ((void*)item)
3320 << ", parent =" << ((void*)item->parentItem())
3321 << ", geometry =" << QRectF(item->pos(), QSizeF(item->width(), item->height()))
3322 << ", z =" << item->zValue() << ')';
3323 return debug;
3324}
3325#endif
3326
3327qint64 QDeclarativeItemPrivate::consistentTime = -1;
3328void QDeclarativeItemPrivate::setConsistentTime(qint64 t)
3329{
3330 consistentTime = t;
3331}
3332
3333class QElapsedTimerConsistentTimeHack
3334{
3335public:
3336 void start() {
3337 t1 = QDeclarativeItemPrivate::consistentTime;
3338 t2 = 0;
3339 }
3340 qint64 elapsed() {
3341 return QDeclarativeItemPrivate::consistentTime - t1;
3342 }
3343 qint64 restart() {
3344 qint64 val = QDeclarativeItemPrivate::consistentTime - t1;
3345 t1 = QDeclarativeItemPrivate::consistentTime;
3346 t2 = 0;
3347 return val;
3348 }
3349
3350private:
3351 qint64 t1;
3352 qint64 t2;
3353};
3354
3355void QDeclarativeItemPrivate::start(QElapsedTimer &t)
3356{
3357 if (QDeclarativeItemPrivate::consistentTime == -1)
3358 t.start();
3359 else
3360 ((QElapsedTimerConsistentTimeHack*)&t)->start();
3361}
3362
3363qint64 QDeclarativeItemPrivate::elapsed(QElapsedTimer &t)
3364{
3365 if (QDeclarativeItemPrivate::consistentTime == -1)
3366 return t.elapsed();
3367 else
3368 return ((QElapsedTimerConsistentTimeHack*)&t)->elapsed();
3369}
3370
3371qint64 QDeclarativeItemPrivate::restart(QElapsedTimer &t)
3372{
3373 if (QDeclarativeItemPrivate::consistentTime == -1)
3374 return t.restart();
3375 else
3376 return ((QElapsedTimerConsistentTimeHack*)&t)->restart();
3377}
3378
3379QT_END_NAMESPACE
3380
3381#include <moc_qdeclarativeitem.cpp>
Note: See TracBrowser for help on using the repository browser.