~loic.molinari/+junk/qtdeclarative-shadereffectsource-changes

« back to all changes in this revision

Viewing changes to src/quick/items/qquickpincharea.cpp

  • Committer: Loïc Molinari
  • Date: 2012-04-21 17:59:51 UTC
  • Revision ID: loic.molinari@canonical.com-20120421175951-bqx68caaf5zrp76l
Initial import

Show diffs side-by-side

added added

removed removed

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