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