26c92a94ac6ca9ef00a6d943ded624418deb7146
[profile/ivi/qtdeclarative.git] / src / qtquick1 / graphicsitems / qdeclarativepincharea.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: http://www.qt-project.org/
6 **
7 ** This file is part of the QtDeclarative module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 **
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 **
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
29 **
30 ** Other Usage
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "QtQuick1/private/qdeclarativepincharea_p.h"
43 #include "QtQuick1/private/qdeclarativepincharea_p_p.h"
44
45 #include <QApplication>
46 #include <QGraphicsScene>
47
48 #include <float.h>
49 #include <math.h>
50
51 QT_BEGIN_NAMESPACE
52
53
54
55
56 /*!
57     \qmlclass PinchEvent QDeclarative1PinchEvent
58     \inqmlmodule QtQuick 1
59     \ingroup qml-event-elements
60     \brief The PinchEvent object provides information about a pinch event.
61
62     \bold {The PinchEvent element was added in QtQuick 1.1}
63
64     The \c center, \c startCenter, \c previousCenter properties provide the center position between the two touch points.
65
66     The \c scale and \c previousScale properties provide the scale factor.
67
68     The \c angle, \c previousAngle and \c rotation properties provide the angle between the two points and the amount of rotation.
69
70     The \c point1, \c point2, \c startPoint1, \c startPoint2 properties provide the positions of the touch points.
71
72     The \c accepted property may be set to false in the \c onPinchStarted handler if the gesture should not
73     be handled.
74
75     \sa PinchArea
76 */
77
78 /*!
79     \qmlproperty QPointF QtQuick1::PinchEvent::center
80     \qmlproperty QPointF QtQuick1::PinchEvent::startCenter
81     \qmlproperty QPointF QtQuick1::PinchEvent::previousCenter
82
83     These properties hold the position of the center point between the two touch points.
84
85     \list
86     \o \c center is the current center point
87     \o \c previousCenter is the center point of the previous event.
88     \o \c startCenter is the center point when the gesture began
89     \endlist
90 */
91
92 /*!
93     \qmlproperty real QtQuick1::PinchEvent::scale
94     \qmlproperty real QtQuick1::PinchEvent::previousScale
95
96     These properties hold the scale factor determined by the change in distance between the two touch points.
97
98     \list
99     \o \c scale is the current scale factor.
100     \o \c previousScale is the scale factor of the previous event.
101     \endlist
102
103     When a pinch gesture is started, the scale is 1.0.
104 */
105
106 /*!
107     \qmlproperty real QtQuick1::PinchEvent::angle
108     \qmlproperty real QtQuick1::PinchEvent::previousAngle
109     \qmlproperty real QtQuick1::PinchEvent::rotation
110
111     These properties hold the angle between the two touch points.
112
113     \list
114     \o \c angle is the current angle between the two points in the range -180 to 180.
115     \o \c previousAngle is the angle of the previous event.
116     \o \c rotation is the total rotation since the pinch gesture started.
117     \endlist
118
119     When a pinch gesture is started, the rotation is 0.0.
120 */
121
122 /*!
123     \qmlproperty QPointF QtQuick1::PinchEvent::point1
124     \qmlproperty QPointF QtQuick1::PinchEvent::startPoint1
125     \qmlproperty QPointF QtQuick1::PinchEvent::point2
126     \qmlproperty QPointF QtQuick1::PinchEvent::startPoint2
127
128     These properties provide the actual touch points generating the pinch.
129
130     \list
131     \o \c point1 and \c point2 hold the current positions of the points.
132     \o \c startPoint1 and \c startPoint2 hold the positions of the points when the second point was touched.
133     \endlist
134 */
135
136 /*!
137     \qmlproperty bool QtQuick1::PinchEvent::accepted
138
139     Setting this property to false in the \c PinchArea::onPinchStarted handler
140     will result in no further pinch events being generated, and the gesture
141     ignored.
142 */
143
144 /*!
145     \qmlproperty int QtQuick1::PinchEvent::pointCount
146
147     Holds the number of points currently touched.  The PinchArea will not react
148     until two touch points have initited a gesture, but will remain active until
149     all touch points have been released.
150 */
151
152 QDeclarative1Pinch::QDeclarative1Pinch()
153     : m_target(0), m_minScale(1.0), m_maxScale(1.0)
154     , m_minRotation(0.0), m_maxRotation(0.0)
155     , m_axis(NoDrag), m_xmin(-FLT_MAX), m_xmax(FLT_MAX)
156     , m_ymin(-FLT_MAX), m_ymax(FLT_MAX), m_active(false)
157 {
158 }
159
160 QDeclarative1PinchAreaPrivate::~QDeclarative1PinchAreaPrivate()
161 {
162     delete pinch;
163 }
164
165 /*!
166     \qmlclass PinchArea QDeclarative1PinchArea
167     \inqmlmodule QtQuick 1
168     \brief The PinchArea item enables simple pinch gesture handling.
169     \inherits Item
170
171     \bold {The PinchArea element was added in QtQuick 1.1}
172
173     A PinchArea is an invisible item that is typically used in conjunction with
174     a visible item in order to provide pinch gesture handling for that item.
175
176     The \l enabled property is used to enable and disable pinch handling for
177     the proxied item. When disabled, the pinch area becomes transparent to
178     mouse/touch events.
179
180     PinchArea can be used in two ways:
181
182     \list
183     \o setting a \c pinch.target to provide automatic interaction with an element
184     \o using the onPinchStarted, onPinchUpdated and onPinchFinished handlers
185     \endlist
186
187     \sa PinchEvent
188 */
189
190 /*!
191     \qmlsignal QtQuick1::PinchArea::onPinchStarted()
192
193     This handler is called when the pinch area detects that a pinch gesture has started.
194
195     The \l {PinchEvent}{pinch} parameter provides information about the pinch gesture,
196     including the scale, center and angle of the pinch.
197
198     To ignore this gesture set the \c pinch.accepted property to false.  The gesture
199     will be cancelled and no further events will be sent.
200 */
201
202 /*!
203     \qmlsignal QtQuick1::PinchArea::onPinchUpdated()
204
205     This handler is called when the pinch area detects that a pinch gesture has changed.
206
207     The \l {PinchEvent}{pinch} parameter provides information about the pinch gesture,
208     including the scale, center and angle of the pinch.
209 */
210
211 /*!
212     \qmlsignal QtQuick1::PinchArea::onPinchFinished()
213
214     This handler is called when the pinch area detects that a pinch gesture has finished.
215
216     The \l {PinchEvent}{pinch} parameter provides information about the pinch gesture,
217     including the scale, center and angle of the pinch.
218 */
219
220
221 /*!
222     \qmlproperty Item QtQuick1::PinchArea::pinch.target
223     \qmlproperty bool QtQuick1::PinchArea::pinch.active
224     \qmlproperty real QtQuick1::PinchArea::pinch.minimumScale
225     \qmlproperty real QtQuick1::PinchArea::pinch.maximumScale
226     \qmlproperty real QtQuick1::PinchArea::pinch.minimumRotation
227     \qmlproperty real QtQuick1::PinchArea::pinch.maximumRotation
228     \qmlproperty enumeration QtQuick1::PinchArea::pinch.dragAxis
229     \qmlproperty real QtQuick1::PinchArea::pinch.minimumX
230     \qmlproperty real QtQuick1::PinchArea::pinch.maximumX
231     \qmlproperty real QtQuick1::PinchArea::pinch.minimumY
232     \qmlproperty real QtQuick1::PinchArea::pinch.maximumY
233
234     \c pinch provides a convenient way to make an item react to pinch gestures.
235
236     \list
237     \i \c pinch.target specifies the id of the item to drag.
238     \i \c pinch.active specifies if the target item is currently being dragged.
239     \i \c pinch.minimumScale and \c pinch.maximumScale limit the range of the Item::scale property.
240     \i \c pinch.minimumRotation and \c pinch.maximumRotation limit the range of the Item::rotation property.
241     \i \c pinch.dragAxis specifies whether dragging in not allowed (\c Pinch.NoDrag), can be done horizontally (\c Pinch.XAxis), vertically (\c Pinch.YAxis), or both (\c Pinch.XandYAxis)
242     \i \c pinch.minimum and \c pinch.maximum limit how far the target can be dragged along the corresponding axes.
243     \endlist
244 */
245
246 QDeclarative1PinchArea::QDeclarative1PinchArea(QDeclarativeItem *parent)
247   : QDeclarativeItem(*(new QDeclarative1PinchAreaPrivate), parent)
248 {
249     Q_D(QDeclarative1PinchArea);
250     d->init();
251 }
252
253 QDeclarative1PinchArea::~QDeclarative1PinchArea()
254 {
255 }
256
257 /*!
258     \qmlproperty bool QtQuick1::PinchArea::enabled
259     This property holds whether the item accepts pinch gestures.
260
261     This property defaults to true.
262 */
263 bool QDeclarative1PinchArea::isEnabled() const
264 {
265     Q_D(const QDeclarative1PinchArea);
266     return d->absorb;
267 }
268
269 void QDeclarative1PinchArea::setEnabled(bool a)
270 {
271     Q_D(QDeclarative1PinchArea);
272     if (a != d->absorb) {
273         d->absorb = a;
274         emit enabledChanged();
275     }
276 }
277
278 bool QDeclarative1PinchArea::event(QEvent *event)
279 {
280     Q_D(QDeclarative1PinchArea);
281     if (!d->absorb || !isVisible())
282         return QDeclarativeItem::event(event);
283     switch (event->type()) {
284     case QEvent::TouchBegin:
285     case QEvent::TouchUpdate: {
286             QTouchEvent *touch = static_cast<QTouchEvent*>(event);
287             d->touchPoints.clear();
288             for (int i = 0; i < touch->touchPoints().count(); ++i) {
289                 if (!(touch->touchPoints().at(i).state() & Qt::TouchPointReleased)) {
290                     d->touchPoints << touch->touchPoints().at(i);
291                 }
292             }
293             updatePinch();
294         }
295         return true;
296     case QEvent::TouchEnd:
297         d->touchPoints.clear();
298         updatePinch();
299         break;
300     default:
301         return QDeclarativeItem::event(event);
302     }
303
304     return QDeclarativeItem::event(event);
305 }
306
307 void QDeclarative1PinchArea::updatePinch()
308 {
309     Q_D(QDeclarative1PinchArea);
310     if (d->touchPoints.count() == 0) {
311         if (d->inPinch) {
312             d->stealMouse = false;
313             setKeepMouseGrab(false);
314             d->inPinch = false;
315             QPointF pinchCenter = mapFromScene(d->sceneLastCenter);
316             QDeclarative1PinchEvent pe(pinchCenter, d->pinchLastScale, d->pinchLastAngle, d->pinchRotation);
317             pe.setStartCenter(d->pinchStartCenter);
318             pe.setPreviousCenter(pinchCenter);
319             pe.setPreviousAngle(d->pinchLastAngle);
320             pe.setPreviousScale(d->pinchLastScale);
321             pe.setStartPoint1(mapFromScene(d->sceneStartPoint1));
322             pe.setStartPoint2(mapFromScene(d->sceneStartPoint2));
323             pe.setPoint1(mapFromScene(d->lastPoint1));
324             pe.setPoint2(mapFromScene(d->lastPoint2));
325             emit pinchFinished(&pe);
326             d->pinchStartDist = 0;
327             d->pinchActivated = false;
328             if (d->pinch && d->pinch->target())
329                 d->pinch->setActive(false);
330         }
331         return;
332     }
333     QTouchEvent::TouchPoint touchPoint1 = d->touchPoints.at(0);
334     QTouchEvent::TouchPoint touchPoint2 = d->touchPoints.at(d->touchPoints. count() >= 2 ? 1 : 0);
335     if (d->touchPoints.count() == 2
336         && (touchPoint1.state() & Qt::TouchPointPressed || touchPoint2.state() & Qt::TouchPointPressed)) {
337         d->id1 = touchPoint1.id();
338         d->sceneStartPoint1 = touchPoint1.scenePos();
339         d->sceneStartPoint2 = touchPoint2.scenePos();
340         d->inPinch = false;
341         d->pinchRejected = false;
342         d->pinchActivated = true;
343     } else if (d->pinchActivated && !d->pinchRejected) {
344         const int dragThreshold = QApplication::startDragDistance();
345         QPointF p1 = touchPoint1.scenePos();
346         QPointF p2 = touchPoint2.scenePos();
347         qreal dx = p1.x() - p2.x();
348         qreal dy = p1.y() - p2.y();
349         qreal dist = sqrt(dx*dx + dy*dy);
350         QPointF sceneCenter = (p1 + p2)/2;
351         qreal angle = QLineF(p1, p2).angle();
352         if (d->touchPoints.count() == 1) {
353             // If we only have one point then just move the center
354             if (d->id1 == touchPoint1.id())
355                 sceneCenter = d->sceneLastCenter + touchPoint1.scenePos() - d->lastPoint1;
356             else
357                 sceneCenter = d->sceneLastCenter + touchPoint2.scenePos() - d->lastPoint2;
358             angle = d->pinchLastAngle;
359         }
360         d->id1 = touchPoint1.id();
361         if (angle > 180)
362             angle -= 360;
363         if (!d->inPinch) {
364             if (d->touchPoints.count() >= 2
365                     && (qAbs(p1.x()-d->sceneStartPoint1.x()) > dragThreshold
366                     || qAbs(p1.y()-d->sceneStartPoint1.y()) > dragThreshold
367                     || qAbs(p2.x()-d->sceneStartPoint2.x()) > dragThreshold
368                     || qAbs(p2.y()-d->sceneStartPoint2.y()) > dragThreshold)) {
369                 d->sceneStartCenter = sceneCenter;
370                 d->sceneLastCenter = sceneCenter;
371                 d->pinchStartCenter = mapFromScene(sceneCenter);
372                 d->pinchStartDist = dist;
373                 d->pinchStartAngle = angle;
374                 d->pinchLastScale = 1.0;
375                 d->pinchLastAngle = angle;
376                 d->pinchRotation = 0.0;
377                 d->lastPoint1 = p1;
378                 d->lastPoint2 = p2;
379                 QDeclarative1PinchEvent pe(d->pinchStartCenter, 1.0, angle, 0.0);
380                 pe.setStartCenter(d->pinchStartCenter);
381                 pe.setPreviousCenter(d->pinchStartCenter);
382                 pe.setPreviousAngle(d->pinchLastAngle);
383                 pe.setPreviousScale(d->pinchLastScale);
384                 pe.setStartPoint1(mapFromScene(d->sceneStartPoint1));
385                 pe.setStartPoint2(mapFromScene(d->sceneStartPoint2));
386                 pe.setPoint1(mapFromScene(d->lastPoint1));
387                 pe.setPoint2(mapFromScene(d->lastPoint2));
388                 pe.setPointCount(d->touchPoints.count());
389                 emit pinchStarted(&pe);
390                 if (pe.accepted()) {
391                     d->inPinch = true;
392                     d->stealMouse = true;
393                     QGraphicsScene *s = scene();
394                     if (s && s->mouseGrabberItem() != this)
395                         grabMouse();
396                     setKeepMouseGrab(true);
397                     if (d->pinch && d->pinch->target()) {
398                         d->pinchStartPos = pinch()->target()->pos();
399                         d->pinchStartScale = d->pinch->target()->scale();
400                         d->pinchStartRotation = d->pinch->target()->rotation();
401                         d->pinch->setActive(true);
402                     }
403                 } else {
404                     d->pinchRejected = true;
405                 }
406             }
407         } else if (d->pinchStartDist > 0) {
408             qreal scale = dist ? dist / d->pinchStartDist : d->pinchLastScale;
409             qreal da = d->pinchLastAngle - angle;
410             if (da > 180)
411                 da -= 360;
412             else if (da < -180)
413                 da += 360;
414             d->pinchRotation += da;
415             QPointF pinchCenter = mapFromScene(sceneCenter);
416             QDeclarative1PinchEvent pe(pinchCenter, scale, angle, d->pinchRotation);
417             pe.setStartCenter(d->pinchStartCenter);
418             pe.setPreviousCenter(mapFromScene(d->sceneLastCenter));
419             pe.setPreviousAngle(d->pinchLastAngle);
420             pe.setPreviousScale(d->pinchLastScale);
421             pe.setStartPoint1(mapFromScene(d->sceneStartPoint1));
422             pe.setStartPoint2(mapFromScene(d->sceneStartPoint2));
423             pe.setPoint1(touchPoint1.pos());
424             pe.setPoint2(touchPoint2.pos());
425             pe.setPointCount(d->touchPoints.count());
426             d->pinchLastScale = scale;
427             d->sceneLastCenter = sceneCenter;
428             d->pinchLastAngle = angle;
429             d->lastPoint1 = touchPoint1.scenePos();
430             d->lastPoint2 = touchPoint2.scenePos();
431             emit pinchUpdated(&pe);
432             if (d->pinch && d->pinch->target()) {
433                 qreal s = d->pinchStartScale * scale;
434                 s = qMin(qMax(pinch()->minimumScale(),s), pinch()->maximumScale());
435                 pinch()->target()->setScale(s);
436                 QPointF pos = sceneCenter - d->sceneStartCenter + d->pinchStartPos;
437                 if (pinch()->axis() & QDeclarative1Pinch::XAxis) {
438                     qreal x = pos.x();
439                     if (x < pinch()->xmin())
440                         x = pinch()->xmin();
441                     else if (x > pinch()->xmax())
442                         x = pinch()->xmax();
443                     pinch()->target()->setX(x);
444                 }
445                 if (pinch()->axis() & QDeclarative1Pinch::YAxis) {
446                     qreal y = pos.y();
447                     if (y < pinch()->ymin())
448                         y = pinch()->ymin();
449                     else if (y > pinch()->ymax())
450                         y = pinch()->ymax();
451                     pinch()->target()->setY(y);
452                 }
453                 if (d->pinchStartRotation >= pinch()->minimumRotation()
454                         && d->pinchStartRotation <= pinch()->maximumRotation()) {
455                     qreal r = d->pinchRotation + d->pinchStartRotation;
456                     r = qMin(qMax(pinch()->minimumRotation(),r), pinch()->maximumRotation());
457                     pinch()->target()->setRotation(r);
458                 }
459             }
460         }
461     }
462 }
463
464 void QDeclarative1PinchArea::mousePressEvent(QGraphicsSceneMouseEvent *event)
465 {
466     Q_D(QDeclarative1PinchArea);
467     d->stealMouse = false;
468     if (!d->absorb)
469         QDeclarativeItem::mousePressEvent(event);
470     else {
471         setKeepMouseGrab(false);
472         event->setAccepted(true);
473     }
474 }
475
476 void QDeclarative1PinchArea::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
477 {
478     Q_D(QDeclarative1PinchArea);
479     if (!d->absorb) {
480         QDeclarativeItem::mouseMoveEvent(event);
481         return;
482     }
483 }
484
485 void QDeclarative1PinchArea::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
486 {
487     Q_D(QDeclarative1PinchArea);
488     d->stealMouse = false;
489     if (!d->absorb) {
490         QDeclarativeItem::mouseReleaseEvent(event);
491     } else {
492         QGraphicsScene *s = scene();
493         if (s && s->mouseGrabberItem() == this)
494             ungrabMouse();
495         setKeepMouseGrab(false);
496     }
497 }
498
499 bool QDeclarative1PinchArea::sceneEvent(QEvent *event)
500 {
501     bool rv = QDeclarativeItem::sceneEvent(event);
502     if (event->type() == QEvent::UngrabMouse) {
503         setKeepMouseGrab(false);
504     }
505     return rv;
506 }
507
508 bool QDeclarative1PinchArea::sendMouseEvent(QGraphicsSceneMouseEvent *event)
509 {
510     Q_D(QDeclarative1PinchArea);
511     QGraphicsSceneMouseEvent mouseEvent(event->type());
512     QRectF myRect = mapToScene(QRectF(0, 0, width(), height())).boundingRect();
513
514     QGraphicsScene *s = scene();
515     QDeclarativeItem *grabber = s ? qobject_cast<QDeclarativeItem*>(s->mouseGrabberItem()) : 0;
516     bool stealThisEvent = d->stealMouse;
517     if ((stealThisEvent || myRect.contains(event->scenePos().toPoint())) && (!grabber || !grabber->keepMouseGrab())) {
518         mouseEvent.setAccepted(false);
519         for (int i = 0x1; i <= 0x10; i <<= 1) {
520             if (event->buttons() & i) {
521                 Qt::MouseButton button = Qt::MouseButton(i);
522                 mouseEvent.setButtonDownPos(button, mapFromScene(event->buttonDownPos(button)));
523             }
524         }
525         mouseEvent.setScenePos(event->scenePos());
526         mouseEvent.setLastScenePos(event->lastScenePos());
527         mouseEvent.setPos(mapFromScene(event->scenePos()));
528         mouseEvent.setLastPos(mapFromScene(event->lastScenePos()));
529
530         switch(mouseEvent.type()) {
531         case QEvent::GraphicsSceneMouseMove:
532             mouseMoveEvent(&mouseEvent);
533             break;
534         case QEvent::GraphicsSceneMousePress:
535             mousePressEvent(&mouseEvent);
536             break;
537         case QEvent::GraphicsSceneMouseRelease:
538             mouseReleaseEvent(&mouseEvent);
539             break;
540         default:
541             break;
542         }
543         grabber = qobject_cast<QDeclarativeItem*>(s->mouseGrabberItem());
544         if (grabber && stealThisEvent && !grabber->keepMouseGrab() && grabber != this)
545             grabMouse();
546
547         return stealThisEvent;
548     }
549     if (mouseEvent.type() == QEvent::GraphicsSceneMouseRelease) {
550         d->stealMouse = false;
551         if (s && s->mouseGrabberItem() == this)
552             ungrabMouse();
553         setKeepMouseGrab(false);
554     }
555     return false;
556 }
557
558 bool QDeclarative1PinchArea::sceneEventFilter(QGraphicsItem *i, QEvent *e)
559 {
560     Q_D(QDeclarative1PinchArea);
561     if (!d->absorb || !isVisible())
562         return QDeclarativeItem::sceneEventFilter(i, e);
563     switch (e->type()) {
564     case QEvent::GraphicsSceneMousePress:
565     case QEvent::GraphicsSceneMouseMove:
566     case QEvent::GraphicsSceneMouseRelease:
567         return sendMouseEvent(static_cast<QGraphicsSceneMouseEvent *>(e));
568         break;
569     case QEvent::TouchBegin:
570     case QEvent::TouchUpdate: {
571             QTouchEvent *touch = static_cast<QTouchEvent*>(e);
572             d->touchPoints.clear();
573             for (int i = 0; i < touch->touchPoints().count(); ++i)
574                 if (!(touch->touchPoints().at(i).state() & Qt::TouchPointReleased))
575                     d->touchPoints << touch->touchPoints().at(i);
576             updatePinch();
577         }
578         return d->inPinch;
579     case QEvent::TouchEnd:
580         d->touchPoints.clear();
581         updatePinch();
582         break;
583     default:
584         break;
585     }
586
587     return QDeclarativeItem::sceneEventFilter(i, e);
588 }
589
590 void QDeclarative1PinchArea::geometryChanged(const QRectF &newGeometry,
591                                             const QRectF &oldGeometry)
592 {
593     QDeclarativeItem::geometryChanged(newGeometry, oldGeometry);
594 }
595
596 QVariant QDeclarative1PinchArea::itemChange(GraphicsItemChange change,
597                                        const QVariant &value)
598 {
599     return QDeclarativeItem::itemChange(change, value);
600 }
601
602 QDeclarative1Pinch *QDeclarative1PinchArea::pinch()
603 {
604     Q_D(QDeclarative1PinchArea);
605     if (!d->pinch)
606         d->pinch = new QDeclarative1Pinch;
607     return d->pinch;
608 }
609
610
611
612
613 QT_END_NAMESPACE