rhodes 5.5.0.3 → 5.5.0.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +10 -0
- data/lib/commonAPI/coreapi/ext/platform/android/src/com/rho/notification/NotificationSingleton.java +20 -8
- data/lib/commonAPI/coreapi/ext/platform/iphone/cpp_based_impl/SystemImpl.mm +1 -2
- data/lib/commonAPI/coreapi/ext/system.xml +1 -1
- data/platform/android/build/android.rake +1 -0
- data/platform/iphone/Classes/AppManager/AppManager.m +44 -3
- data/platform/iphone/Classes/NativeView/RhoNativeViewManager.mm +4 -3
- data/platform/iphone/Classes/NativeView/RhoNativeViewManagerOC.h +1 -1
- data/platform/iphone/Classes/RhoMainView.h +8 -2
- data/platform/iphone/Classes/RhoUIWebView.h +75 -0
- data/platform/iphone/Classes/RhoUIWebView.m +142 -0
- data/platform/iphone/Classes/RhoWKWebView.h +87 -0
- data/platform/iphone/Classes/RhoWKWebView.m +187 -0
- data/platform/iphone/Classes/RhoWebView.h +72 -0
- data/platform/iphone/Classes/RhoWebViewFabrique.h +35 -0
- data/platform/iphone/Classes/RhoWebViewFabrique.m +87 -0
- data/platform/iphone/Classes/Rhodes.m +17 -6
- data/platform/iphone/Classes/Signature.old/SignatureDelegate.m +11 -4
- data/platform/iphone/Classes/Signature/SignatureDelegate.m +3 -4
- data/platform/iphone/Classes/SimpleMainView.h +7 -5
- data/platform/iphone/Classes/SimpleMainView.m +174 -179
- data/platform/iphone/Classes/SplitView/RightViewController.h +2 -2
- data/platform/iphone/Classes/SplitView/RightViewController.m +9 -10
- data/platform/iphone/Classes/SplitView/SplittedMainView.h +2 -3
- data/platform/iphone/Classes/SplitView/SplittedMainView.m +10 -7
- data/platform/iphone/Classes/TabbedMainView.h +2 -1
- data/platform/iphone/Classes/TabbedMainView.m +13 -10
- data/platform/iphone/Classes/URLProtocol/CRhoURLProtocol.m +21 -5
- data/platform/iphone/Classes/WebView.m +1 -1
- data/platform/iphone/RhoAppBaseLib/RhoAppBaseLib.xcodeproj/project.pbxproj +40 -3
- data/platform/iphone/RhoLib/RhoLib.xcodeproj/project.pbxproj +4 -0
- data/platform/iphone/rbuild/iphone.rake +51 -0
- data/platform/shared/common/RhoNativeViewManager.h +9 -9
- data/platform/shared/common/RhodesApp.cpp +13 -1
- data/platform/shared/net/HttpServer.cpp +12 -2
- data/platform/shared/qt/rhodes/ExternalWebView.ui +11 -2
- data/platform/shared/qt/rhodes/QtMainWindow.cpp +9 -7
- data/platform/shared/qt/rhodes/QtMainWindow.ui +13 -4
- data/platform/shared/qt/rhodes/qkineticscroller.cpp +1245 -0
- data/platform/shared/qt/rhodes/qkineticscroller.h +165 -0
- data/platform/shared/qt/rhodes/qkineticscroller_p.h +168 -0
- data/platform/shared/qt/rhodes/qtflickgesture.cpp +696 -0
- data/platform/shared/qt/rhodes/qtflickgesture_p.h +107 -0
- data/platform/shared/qt/rhodes/qtscroller.cpp +2080 -0
- data/platform/shared/qt/rhodes/qtscroller.h +138 -0
- data/platform/shared/qt/rhodes/qtscroller_p.h +205 -0
- data/platform/shared/qt/rhodes/qtscrollerfilter.cpp +350 -0
- data/platform/shared/qt/rhodes/qtscrollerfilter_p.h +110 -0
- data/platform/shared/qt/rhodes/qtscrollerproperties.cpp +412 -0
- data/platform/shared/qt/rhodes/qtscrollerproperties.h +135 -0
- data/platform/shared/qt/rhodes/qtscrollerproperties_p.h +90 -0
- data/platform/shared/qt/rhodes/qtscrollevent.cpp +190 -0
- data/platform/shared/qt/rhodes/qtscrollevent.h +100 -0
- data/platform/shared/qt/rhodes/qtscrollevent_p.h +33 -0
- data/platform/shared/qt/rhodes/qwebviewkineticscroller.cpp +347 -0
- data/platform/shared/qt/rhodes/qwebviewkineticscroller.h +90 -0
- data/platform/shared/qt/rhodes/qwebviewselectionsuppressor.h +113 -0
- data/platform/shared/qt/rhodes/rhodes.pro +19 -0
- data/res/generators/rhogen.rb +307 -15
- data/res/generators/templates/application/app/Settings/err_sync.erb +12 -6
- data/res/generators/templates/application/app/Settings/home.erb +32 -17
- data/res/generators/templates/application/app/Settings/index.erb +55 -26
- data/res/generators/templates/application/app/Settings/javascript_index.html +111 -0
- data/res/generators/templates/application/app/Settings/javascript_login.html +65 -0
- data/res/generators/templates/application/app/Settings/login.erb +25 -19
- data/res/generators/templates/application/app/Settings/reset.erb +18 -9
- data/res/generators/templates/application/app/Settings/wait.erb +10 -7
- data/res/generators/templates/application/app/index.erb +32 -20
- data/res/generators/templates/application/app/javascript_index.html +66 -0
- data/res/generators/templates/application/app/javascript_index.js +250 -0
- data/res/generators/templates/application/app/layout.erb +12 -67
- data/res/generators/templates/application/javascript_build.yml +41 -0
- data/res/generators/templates/application/javascript_rhoconfig.txt +123 -0
- data/res/generators/templates/application/public/bootstrap-3.3.7/css/bootstrap-theme.css +587 -0
- data/res/generators/templates/application/public/bootstrap-3.3.7/css/bootstrap-theme.css.map +1 -0
- data/res/generators/templates/application/public/bootstrap-3.3.7/css/bootstrap-theme.min.css +6 -0
- data/res/generators/templates/application/public/bootstrap-3.3.7/css/bootstrap-theme.min.css.map +1 -0
- data/res/generators/templates/application/public/bootstrap-3.3.7/css/bootstrap.css +6757 -0
- data/res/generators/templates/application/public/bootstrap-3.3.7/css/bootstrap.css.map +1 -0
- data/res/generators/templates/application/public/bootstrap-3.3.7/css/bootstrap.min.css +6 -0
- data/res/generators/templates/application/public/bootstrap-3.3.7/css/bootstrap.min.css.map +1 -0
- data/res/generators/templates/application/public/bootstrap-3.3.7/fonts/glyphicons-halflings-regular.eot +0 -0
- data/res/generators/templates/application/public/bootstrap-3.3.7/fonts/glyphicons-halflings-regular.svg +288 -0
- data/res/generators/templates/application/public/bootstrap-3.3.7/fonts/glyphicons-halflings-regular.ttf +0 -0
- data/res/generators/templates/application/public/bootstrap-3.3.7/fonts/glyphicons-halflings-regular.woff +0 -0
- data/res/generators/templates/application/public/bootstrap-3.3.7/fonts/glyphicons-halflings-regular.woff2 +0 -0
- data/res/generators/templates/application/public/bootstrap-3.3.7/js/bootstrap.js +2377 -0
- data/res/generators/templates/application/public/bootstrap-3.3.7/js/bootstrap.min.js +7 -0
- data/res/generators/templates/application/public/bootstrap-3.3.7/js/npm.js +13 -0
- data/res/generators/templates/application/public/css/style.css +3 -0
- data/res/generators/templates/application/public/jquery/jquery-3.1.1.min.js +4 -0
- data/res/generators/templates/application/public/jquery/jquery-3.1.1.min.map +1 -0
- data/res/generators/templates/application/rhoconfig.txt +16 -0
- data/res/generators/templates/iphone_project/Bremen7.xcodeproj/project.pbxproj +4 -0
- data/res/generators/templates/model/edit.erb +22 -21
- data/res/generators/templates/model/index.erb +24 -22
- data/res/generators/templates/model/javascript_edit.html +65 -0
- data/res/generators/templates/model/javascript_index.html +56 -0
- data/res/generators/templates/model/javascript_index.js +83 -0
- data/res/generators/templates/model/javascript_model.js +16 -0
- data/res/generators/templates/model/javascript_new.html +64 -0
- data/res/generators/templates/model/javascript_show.html +66 -0
- data/res/generators/templates/model/new.erb +22 -19
- data/res/generators/templates/model/show.erb +22 -14
- data/res/prebuild_base_app/app/index.erb +31 -18
- data/res/prebuild_base_app/app/layout.erb +11 -56
- data/version +1 -1
- metadata +59 -24
- data/res/generators/templates/application/public/css/android.css +0 -418
- data/res/generators/templates/application/public/css/iphone.css +0 -378
- data/res/generators/templates/application/public/css/jqmobile-patch.css +0 -62
- data/res/generators/templates/application/public/css/re_webkit.css +0 -736
- data/res/generators/templates/application/public/css/re_webkit_flat.css +0 -753
- data/res/generators/templates/application/public/css/windows_mobile.css +0 -327
- data/res/generators/templates/application/public/jqmobile/images/ajax-loader.gif +0 -0
- data/res/generators/templates/application/public/jqmobile/images/icon-search-black.png +0 -0
- data/res/generators/templates/application/public/jqmobile/images/icons-18-black.png +0 -0
- data/res/generators/templates/application/public/jqmobile/images/icons-18-white.png +0 -0
- data/res/generators/templates/application/public/jqmobile/images/icons-36-black.png +0 -0
- data/res/generators/templates/application/public/jqmobile/images/icons-36-white.png +0 -0
- data/res/generators/templates/application/public/jqmobile/jquery.mobile-1.4.5.min.css +0 -3
- data/res/generators/templates/application/public/jqmobile/jquery.mobile-1.4.5.min.js +0 -10
- data/res/generators/templates/application/public/jqmobile/jquery.mobile-1.4.5.min.map +0 -1
- data/res/generators/templates/application/public/jqmobile/jquery.mobile.structure-1.4.5.min.css +0 -3
- data/res/generators/templates/application/public/jqmobile/jquery.mobile.theme-1.4.5.min.css +0 -3
- data/res/generators/templates/application/public/jquery/jquery-1.9.1.min.js +0 -5
- data/res/generators/templates/application/public/jquery/jquery-1.9.1.min.map +0 -1
- data/res/generators/templates/application/public/js/application.js +0 -1
- data/res/generators/templates/application/public/js/jqmobile-patch.js +0 -466
- data/res/generators/templates/application/public/js/syncengine.js +0 -504
@@ -0,0 +1,165 @@
|
|
1
|
+
/****************************************************************************
|
2
|
+
**
|
3
|
+
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
4
|
+
** All rights reserved.
|
5
|
+
** Contact: Nokia Corporation (qt-info@nokia.com)
|
6
|
+
**
|
7
|
+
** This file is part of the QtGui module of the Qt Toolkit.
|
8
|
+
**
|
9
|
+
** $QT_BEGIN_LICENSE:LGPL$
|
10
|
+
** No Commercial Usage
|
11
|
+
** This file contains pre-release code and may not be distributed.
|
12
|
+
** You may use this file in accordance with the terms and conditions
|
13
|
+
** contained in the Technology Preview License Agreement accompanying
|
14
|
+
** this package.
|
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
|
+
** If you have questions regarding the use of this file, please contact
|
29
|
+
** Nokia at qt-info@nokia.com.
|
30
|
+
**
|
31
|
+
**
|
32
|
+
**
|
33
|
+
**
|
34
|
+
**
|
35
|
+
**
|
36
|
+
**
|
37
|
+
**
|
38
|
+
** $QT_END_LICENSE$
|
39
|
+
**
|
40
|
+
****************************************************************************/
|
41
|
+
|
42
|
+
#ifndef QKINETICSCROLLER_H
|
43
|
+
#define QKINETICSCROLLER_H
|
44
|
+
|
45
|
+
#include <QtCore/qmetatype.h>
|
46
|
+
#include <QtCore/qpoint.h>
|
47
|
+
#include <QtCore/qrect.h>
|
48
|
+
#include <QtCore/qvariant.h>
|
49
|
+
|
50
|
+
QT_BEGIN_HEADER
|
51
|
+
|
52
|
+
QT_BEGIN_NAMESPACE
|
53
|
+
|
54
|
+
QT_MODULE(Gui)
|
55
|
+
|
56
|
+
class QKineticScrollerPrivate;
|
57
|
+
|
58
|
+
class QKineticScroller
|
59
|
+
{
|
60
|
+
public:
|
61
|
+
virtual ~QKineticScroller();
|
62
|
+
|
63
|
+
bool isEnabled() const;
|
64
|
+
void setEnabled(bool b);
|
65
|
+
|
66
|
+
enum State
|
67
|
+
{
|
68
|
+
StateInactive,
|
69
|
+
StatePressed,
|
70
|
+
StateDragging,
|
71
|
+
StateScrolling,
|
72
|
+
};
|
73
|
+
|
74
|
+
State state() const;
|
75
|
+
void reset();
|
76
|
+
|
77
|
+
enum OvershootPolicy
|
78
|
+
{
|
79
|
+
OvershootWhenScrollable,
|
80
|
+
OvershootAlwaysOff,
|
81
|
+
OvershootAlwaysOn,
|
82
|
+
};
|
83
|
+
|
84
|
+
OvershootPolicy horizontalOvershootPolicy() const;
|
85
|
+
void setHorizontalOvershootPolicy(OvershootPolicy policy);
|
86
|
+
OvershootPolicy verticalOvershootPolicy() const;
|
87
|
+
void setVerticalOvershootPolicy(OvershootPolicy policy);
|
88
|
+
|
89
|
+
enum ScrollMetric
|
90
|
+
{
|
91
|
+
DragVelocitySmoothingFactor, // qreal [0..1/s] (complex calculation involving time) v = v_new* DASF + v_old * (1-DASF)
|
92
|
+
|
93
|
+
LinearDecelerationFactor, // qreal [m/s^2]
|
94
|
+
ExponentialDecelerationBase, // qreal
|
95
|
+
OvershootSpringConstant, // qreal [kg/s^2]
|
96
|
+
OvershootDragResistanceFactor, // qreal [0..1]
|
97
|
+
OvershootMaximumDistance, // QPointF([m], [m])
|
98
|
+
|
99
|
+
DragStartDistance, // qreal [m]
|
100
|
+
DragStartDirectionErrorMargin, // qreal [m]
|
101
|
+
|
102
|
+
MinimumVelocity, // qreal [m/s]
|
103
|
+
MaximumVelocity, // qreal [m/s]
|
104
|
+
MaximumNonAcceleratedVelocity, // qreal [m/s]
|
105
|
+
|
106
|
+
MaximumClickThroughVelocity, // qreal [m/s]
|
107
|
+
AxisLockThreshold, // qreal [0..1] atan(|min(dx,dy)|/|max(dx,dy)|)
|
108
|
+
|
109
|
+
FramesPerSecond, // int [frames/s]
|
110
|
+
|
111
|
+
FastSwipeMaximumTime, // qreal [s]
|
112
|
+
FastSwipeMinimumVelocity, // qreal [m/s]
|
113
|
+
FastSwipeBaseVelocity, // qreal [m/s]
|
114
|
+
|
115
|
+
ScrollMetricCount
|
116
|
+
};
|
117
|
+
|
118
|
+
QVariant scrollMetric(ScrollMetric metric) const;
|
119
|
+
void setScrollMetric(ScrollMetric metric, const QVariant &value);
|
120
|
+
void resetScrollMetrics();
|
121
|
+
|
122
|
+
void scrollTo(const QPointF &pos, int scrollTime = 1000);
|
123
|
+
void ensureVisible(const QPointF &pos, int xmargin, int ymargin, int scrollTime = 1000);
|
124
|
+
|
125
|
+
qreal dpi() const;
|
126
|
+
void setDpi(qreal dpi);
|
127
|
+
void setDpiFromWidget(QWidget *widget);
|
128
|
+
|
129
|
+
void registerDebugHook(void (*callback)(void *user, const QPointF &releaseVelocity, const QPointF &position, const QPointF &overshootPosition), void *user);
|
130
|
+
|
131
|
+
protected:
|
132
|
+
explicit QKineticScroller();
|
133
|
+
|
134
|
+
virtual QSizeF viewportSize() const = 0;
|
135
|
+
virtual QPointF maximumContentPosition() const = 0;
|
136
|
+
virtual QPointF contentPosition() const = 0;
|
137
|
+
virtual void setContentPosition(const QPointF &pos, const QPointF &overshootDelta) = 0;
|
138
|
+
|
139
|
+
virtual void stateChanged(State oldState);
|
140
|
+
virtual bool canStartScrollingAt(const QPointF &pos) const;
|
141
|
+
virtual void cancelPress(const QPointF &pressPos);
|
142
|
+
|
143
|
+
enum Input {
|
144
|
+
InputPress,
|
145
|
+
InputMove,
|
146
|
+
InputRelease
|
147
|
+
};
|
148
|
+
|
149
|
+
bool handleInput(Input input, const QPointF &position, qint64 timestamp);
|
150
|
+
|
151
|
+
QKineticScroller(QKineticScrollerPrivate &dd);
|
152
|
+
QScopedPointer<QKineticScrollerPrivate> d_ptr;
|
153
|
+
|
154
|
+
private:
|
155
|
+
Q_DISABLE_COPY(QKineticScroller)
|
156
|
+
Q_DECLARE_PRIVATE(QKineticScroller)
|
157
|
+
};
|
158
|
+
|
159
|
+
QT_END_NAMESPACE
|
160
|
+
|
161
|
+
Q_DECLARE_METATYPE(QKineticScroller *)
|
162
|
+
|
163
|
+
QT_END_HEADER
|
164
|
+
|
165
|
+
#endif // QKINETICSCROLLER_H
|
@@ -0,0 +1,168 @@
|
|
1
|
+
/****************************************************************************
|
2
|
+
**
|
3
|
+
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
4
|
+
** All rights reserved.
|
5
|
+
** Contact: Nokia Corporation (qt-info@nokia.com)
|
6
|
+
**
|
7
|
+
** This file is part of the QtGui module of the Qt Toolkit.
|
8
|
+
**
|
9
|
+
** $QT_BEGIN_LICENSE:LGPL$
|
10
|
+
** No Commercial Usage
|
11
|
+
** This file contains pre-release code and may not be distributed.
|
12
|
+
** You may use this file in accordance with the terms and conditions
|
13
|
+
** contained in the Technology Preview License Agreement accompanying
|
14
|
+
** this package.
|
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
|
+
** If you have questions regarding the use of this file, please contact
|
29
|
+
** Nokia at qt-info@nokia.com.
|
30
|
+
**
|
31
|
+
**
|
32
|
+
**
|
33
|
+
**
|
34
|
+
**
|
35
|
+
**
|
36
|
+
**
|
37
|
+
**
|
38
|
+
** $QT_END_LICENSE$
|
39
|
+
**
|
40
|
+
****************************************************************************/
|
41
|
+
|
42
|
+
//
|
43
|
+
// W A R N I N G
|
44
|
+
// -------------
|
45
|
+
//
|
46
|
+
// This file is not part of the Qt API. It exists purely as an
|
47
|
+
// implementation detail. This header file may change from version to
|
48
|
+
// version without notice, or even be removed.
|
49
|
+
//
|
50
|
+
// We mean it.
|
51
|
+
//
|
52
|
+
|
53
|
+
#include <QTime>
|
54
|
+
#include <QPointer>
|
55
|
+
#include <QObject>
|
56
|
+
#include <qkineticscroller.h>
|
57
|
+
#include <QEvent>
|
58
|
+
#if QT_VERSION < 0x040700
|
59
|
+
# include <QTime>
|
60
|
+
#else
|
61
|
+
# include <QElapsedTimer>
|
62
|
+
#endif
|
63
|
+
|
64
|
+
QT_BEGIN_NAMESPACE
|
65
|
+
|
66
|
+
class QKineticScrollerPrivate : public QObject
|
67
|
+
{
|
68
|
+
Q_OBJECT
|
69
|
+
Q_DECLARE_PUBLIC(QKineticScroller)
|
70
|
+
|
71
|
+
public:
|
72
|
+
QKineticScrollerPrivate();
|
73
|
+
virtual ~QKineticScrollerPrivate();
|
74
|
+
void init();
|
75
|
+
|
76
|
+
void setState(QKineticScroller::State s);
|
77
|
+
|
78
|
+
bool pressWhileInactive(QKineticScroller::Input input, const QPointF &position, qint64 timestamp);
|
79
|
+
bool moveWhilePressed(QKineticScroller::Input input, const QPointF &position, qint64 timestamp);
|
80
|
+
bool releaseWhilePressed(QKineticScroller::Input input, const QPointF &position, qint64 timestamp);
|
81
|
+
bool moveWhileDragging(QKineticScroller::Input input, const QPointF &position, qint64 timestamp);
|
82
|
+
bool releaseWhileDragging(QKineticScroller::Input input, const QPointF &position, qint64 timestamp);
|
83
|
+
bool pressWhileScrolling(QKineticScroller::Input input, const QPointF &position, qint64 timestamp);
|
84
|
+
|
85
|
+
void timerEvent(QTimerEvent *);
|
86
|
+
void timerEventWhileDragging();
|
87
|
+
void timerEventWhileScrolling();
|
88
|
+
|
89
|
+
void handleDrag(const QPointF &position, qint64 timestamp);
|
90
|
+
void updateVelocity(const QPointF &deltaPixel, qint64 deltaTime);
|
91
|
+
|
92
|
+
qreal decelerate(qreal v, qreal t);
|
93
|
+
QPointF calculateVelocity(qreal time);
|
94
|
+
void setContentPositionHelper(const QPointF &deltaPos);
|
95
|
+
|
96
|
+
QPointF realDpi(int screen);
|
97
|
+
|
98
|
+
|
99
|
+
static const char *stateName(QKineticScroller::State state);
|
100
|
+
static const char *inputName(QKineticScroller::Input input);
|
101
|
+
|
102
|
+
// metrics
|
103
|
+
|
104
|
+
qreal dragVelocitySmoothingFactor;
|
105
|
+
qreal linearDecelerationFactor;
|
106
|
+
qreal exponentialDecelerationBase;
|
107
|
+
qreal overshootSpringConstantRoot;
|
108
|
+
QPointF overshootMaximumDistance;
|
109
|
+
qreal overshootDragResistanceFactor;
|
110
|
+
qreal dragStartDistance;
|
111
|
+
qreal dragStartDirectionErrorMargin;
|
112
|
+
qreal maximumVelocity;
|
113
|
+
qreal minimumVelocity;
|
114
|
+
qreal maximumNonAcceleratedVelocity;
|
115
|
+
qreal maximumClickThroughVelocity;
|
116
|
+
qreal axisLockThreshold;
|
117
|
+
qreal fastSwipeBaseVelocity;
|
118
|
+
qreal fastSwipeMinimumVelocity;
|
119
|
+
qreal fastSwipeMaximumTime;
|
120
|
+
int framesPerSecond;
|
121
|
+
|
122
|
+
// state
|
123
|
+
|
124
|
+
bool enabled;
|
125
|
+
QKineticScroller::State state;
|
126
|
+
QKineticScroller::OvershootPolicy hOvershootPolicy;
|
127
|
+
QKineticScroller::OvershootPolicy vOvershootPolicy;
|
128
|
+
QPointF oldVelocity;
|
129
|
+
|
130
|
+
QPointF pressPosition;
|
131
|
+
QPointF lastPosition;
|
132
|
+
qint64 pressTimestamp;
|
133
|
+
qint64 lastTimestamp;
|
134
|
+
|
135
|
+
QPointF dragDistance; // the distance we should move during the next drag timer event
|
136
|
+
|
137
|
+
QPointF scrollToPosition;
|
138
|
+
bool scrollToX;
|
139
|
+
bool scrollToY;
|
140
|
+
|
141
|
+
QPointF overshootPosition; // the number of pixels we are overshooting (before overshootDragResistanceFactor)
|
142
|
+
bool overshootX;
|
143
|
+
bool overshootY;
|
144
|
+
|
145
|
+
qreal pixelPerMeter;
|
146
|
+
|
147
|
+
#if QT_VERSION < 0x040700
|
148
|
+
QTime scrollRelativeTimer;
|
149
|
+
QTime scrollAbsoluteTimer;
|
150
|
+
#else
|
151
|
+
QElapsedTimer scrollRelativeTimer;
|
152
|
+
QElapsedTimer scrollAbsoluteTimer;
|
153
|
+
#endif
|
154
|
+
QPointF releaseVelocity; // the starting velocity of the scrolling state
|
155
|
+
QPointF overshootVelocity; // the starting velocity when going into overshoot
|
156
|
+
qreal overshootStartTimeX;
|
157
|
+
qreal overshootStartTimeY;
|
158
|
+
int timerId;
|
159
|
+
|
160
|
+
bool cancelPress;
|
161
|
+
|
162
|
+
void (*debugHook)(void *user, const QPointF &releaseVelocity, const QPointF &position, const QPointF &overshootPosition);
|
163
|
+
void *debugHookUser;
|
164
|
+
|
165
|
+
QKineticScroller *q_ptr;
|
166
|
+
};
|
167
|
+
|
168
|
+
QT_END_NAMESPACE
|
@@ -0,0 +1,696 @@
|
|
1
|
+
/****************************************************************************
|
2
|
+
**
|
3
|
+
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
4
|
+
** All rights reserved.
|
5
|
+
** Contact: Nokia Corporation (qt-info@nokia.com)
|
6
|
+
**
|
7
|
+
** This file is part of the QtGui module of the Qt Toolkit.
|
8
|
+
**
|
9
|
+
** $QT_BEGIN_LICENSE:LGPL$
|
10
|
+
** No Commercial Usage
|
11
|
+
** This file contains pre-release code and may not be distributed.
|
12
|
+
** You may use this file in accordance with the terms and conditions
|
13
|
+
** contained in the Technology Preview License Agreement accompanying
|
14
|
+
** this package.
|
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
|
+
** If you have questions regarding the use of this file, please contact
|
29
|
+
** Nokia at qt-info@nokia.com.
|
30
|
+
**
|
31
|
+
**
|
32
|
+
**
|
33
|
+
**
|
34
|
+
**
|
35
|
+
**
|
36
|
+
**
|
37
|
+
**
|
38
|
+
** $QT_END_LICENSE$
|
39
|
+
**
|
40
|
+
****************************************************************************/
|
41
|
+
|
42
|
+
#include "qgesture.h"
|
43
|
+
#include "qapplication.h"
|
44
|
+
#include "qevent.h"
|
45
|
+
#include "qwidget.h"
|
46
|
+
#include "qgraphicsitem.h"
|
47
|
+
#include "qgraphicsscene.h"
|
48
|
+
#include "qgraphicssceneevent.h"
|
49
|
+
#include "qgraphicsview.h"
|
50
|
+
#if (QT_VERSION < QT_VERSION_CHECK(4, 7, 0))
|
51
|
+
# include <QTime>
|
52
|
+
typedef QTime QElapsedTimer;
|
53
|
+
#else
|
54
|
+
# include <QElapsedTimer>
|
55
|
+
#endif
|
56
|
+
#include "qtscroller.h"
|
57
|
+
#include "qtflickgesture_p.h"
|
58
|
+
#include "qdebug.h"
|
59
|
+
|
60
|
+
#ifndef QT_NO_GESTURES
|
61
|
+
|
62
|
+
//#define QFLICKGESTURE_DEBUG
|
63
|
+
|
64
|
+
#ifdef QFLICKGESTURE_DEBUG
|
65
|
+
# define qFGDebug qDebug
|
66
|
+
#else
|
67
|
+
# define qFGDebug while (false) qDebug
|
68
|
+
#endif
|
69
|
+
|
70
|
+
extern bool qt_sendSpontaneousEvent(QObject *receiver, QEvent *event);
|
71
|
+
|
72
|
+
static QMouseEvent *copyMouseEvent(QEvent *e)
|
73
|
+
{
|
74
|
+
switch (e->type()) {
|
75
|
+
case QEvent::MouseButtonPress:
|
76
|
+
case QEvent::MouseButtonRelease:
|
77
|
+
case QEvent::MouseMove: {
|
78
|
+
QMouseEvent *me = static_cast<QMouseEvent *>(e);
|
79
|
+
return new QMouseEvent(me->type(), QPoint(0, 0), me->globalPos(), me->button(), me->buttons(), me->modifiers());
|
80
|
+
}
|
81
|
+
case QEvent::GraphicsSceneMousePress:
|
82
|
+
case QEvent::GraphicsSceneMouseRelease:
|
83
|
+
case QEvent::GraphicsSceneMouseMove: {
|
84
|
+
QGraphicsSceneMouseEvent *me = static_cast<QGraphicsSceneMouseEvent *>(e);
|
85
|
+
#if 1
|
86
|
+
QEvent::Type met = me->type() == QEvent::GraphicsSceneMousePress ? QEvent::MouseButtonPress :
|
87
|
+
(me->type() == QEvent::GraphicsSceneMouseRelease ? QEvent::MouseButtonRelease : QEvent::MouseMove);
|
88
|
+
return new QMouseEvent(met, QPoint(0, 0), me->screenPos(), me->button(), me->buttons(), me->modifiers());
|
89
|
+
#else
|
90
|
+
QGraphicsSceneMouseEvent *copy = new QGraphicsSceneMouseEvent(me->type());
|
91
|
+
copy->setPos(me->pos());
|
92
|
+
copy->setScenePos(me->scenePos());
|
93
|
+
copy->setScreenPos(me->screenPos());
|
94
|
+
for (int i = 0x1; i <= 0x10; i <<= 1) {
|
95
|
+
Qt::MouseButton button = Qt::MouseButton(i);
|
96
|
+
copy->setButtonDownPos(button, me->buttonDownPos(button));
|
97
|
+
copy->setButtonDownScenePos(button, me->buttonDownScenePos(button));
|
98
|
+
copy->setButtonDownScreenPos(button, me->buttonDownScreenPos(button));
|
99
|
+
}
|
100
|
+
copy->setLastPos(me->lastPos());
|
101
|
+
copy->setLastScenePos(me->lastScenePos());
|
102
|
+
copy->setLastScreenPos(me->lastScreenPos());
|
103
|
+
copy->setButtons(me->buttons());
|
104
|
+
copy->setButton(me->button());
|
105
|
+
copy->setModifiers(me->modifiers());
|
106
|
+
return copy;
|
107
|
+
#endif
|
108
|
+
}
|
109
|
+
default:
|
110
|
+
return 0;
|
111
|
+
}
|
112
|
+
}
|
113
|
+
|
114
|
+
class PressDelayHandler : public QObject
|
115
|
+
{
|
116
|
+
private:
|
117
|
+
PressDelayHandler(QObject *parent = 0)
|
118
|
+
: QObject(parent)
|
119
|
+
, pressDelayTimer(0)
|
120
|
+
, sendingEvent(false)
|
121
|
+
, mouseButton(Qt::NoButton)
|
122
|
+
, mouseTarget(0)
|
123
|
+
{ }
|
124
|
+
|
125
|
+
static PressDelayHandler *inst;
|
126
|
+
|
127
|
+
public:
|
128
|
+
enum {
|
129
|
+
UngrabMouseBefore = 1,
|
130
|
+
RegrabMouseAfterwards = 2
|
131
|
+
};
|
132
|
+
|
133
|
+
static PressDelayHandler *instance()
|
134
|
+
{
|
135
|
+
static PressDelayHandler *inst = 0;
|
136
|
+
if (!inst)
|
137
|
+
inst = new PressDelayHandler(QCoreApplication::instance());
|
138
|
+
return inst;
|
139
|
+
}
|
140
|
+
|
141
|
+
bool shouldEventBeIgnored(QEvent *) const
|
142
|
+
{
|
143
|
+
return sendingEvent;
|
144
|
+
}
|
145
|
+
|
146
|
+
bool isDelaying() const
|
147
|
+
{
|
148
|
+
return !pressDelayEvent.isNull();
|
149
|
+
}
|
150
|
+
|
151
|
+
void pressed(QEvent *e, int delay)
|
152
|
+
{
|
153
|
+
if (!pressDelayEvent) {
|
154
|
+
pressDelayEvent.reset(copyMouseEvent(e));
|
155
|
+
pressDelayTimer = startTimer(delay);
|
156
|
+
mouseTarget = QApplication::widgetAt(pressDelayEvent->globalPos());
|
157
|
+
mouseButton = pressDelayEvent->button();
|
158
|
+
qFGDebug() << "QFG: consuming/delaying mouse press";
|
159
|
+
} else {
|
160
|
+
qFGDebug() << "QFG: NOT consuming/delaying mouse press";
|
161
|
+
}
|
162
|
+
e->setAccepted(true);
|
163
|
+
}
|
164
|
+
|
165
|
+
bool released(QEvent *e, bool scrollerWasActive, bool scrollerIsActive)
|
166
|
+
{
|
167
|
+
// consume this event if the scroller was or is active
|
168
|
+
bool result = scrollerWasActive || scrollerIsActive;
|
169
|
+
|
170
|
+
// stop the timer
|
171
|
+
if (pressDelayTimer) {
|
172
|
+
killTimer(pressDelayTimer);
|
173
|
+
pressDelayTimer = 0;
|
174
|
+
}
|
175
|
+
// we still haven't even sent the press, so do it now
|
176
|
+
if (pressDelayEvent && mouseTarget && !scrollerIsActive) {
|
177
|
+
QScopedPointer<QMouseEvent> releaseEvent(copyMouseEvent(e));
|
178
|
+
|
179
|
+
qFGDebug() << "QFG: re-sending mouse press (due to release) for " << mouseTarget;
|
180
|
+
sendMouseEvent(pressDelayEvent.data(), UngrabMouseBefore);
|
181
|
+
|
182
|
+
qFGDebug() << "QFG: faking mouse release (due to release) for " << mouseTarget;
|
183
|
+
sendMouseEvent(releaseEvent.data());
|
184
|
+
result = true; // consume this event
|
185
|
+
} else if (mouseTarget && scrollerIsActive) {
|
186
|
+
// we grabbed the mouse expicitly when the scroller became active, so undo that now
|
187
|
+
sendMouseEvent(0, UngrabMouseBefore);
|
188
|
+
}
|
189
|
+
pressDelayEvent.reset(0);
|
190
|
+
mouseTarget = 0;
|
191
|
+
return result;
|
192
|
+
}
|
193
|
+
|
194
|
+
void scrollerWasIntercepted()
|
195
|
+
{
|
196
|
+
qFGDebug() << "QFG: deleting delayed mouse press, since scroller was only intercepted";
|
197
|
+
if (pressDelayEvent) {
|
198
|
+
// we still haven't even sent the press, so just throw it away now
|
199
|
+
if (pressDelayTimer) {
|
200
|
+
killTimer(pressDelayTimer);
|
201
|
+
pressDelayTimer = 0;
|
202
|
+
}
|
203
|
+
pressDelayEvent.reset(0);
|
204
|
+
}
|
205
|
+
mouseTarget = 0;
|
206
|
+
}
|
207
|
+
|
208
|
+
void scrollerBecameActive()
|
209
|
+
{
|
210
|
+
if (pressDelayEvent) {
|
211
|
+
// we still haven't even sent the press, so just throw it away now
|
212
|
+
qFGDebug() << "QFG: deleting delayed mouse press, since scroller is active now";
|
213
|
+
if (pressDelayTimer) {
|
214
|
+
killTimer(pressDelayTimer);
|
215
|
+
pressDelayTimer = 0;
|
216
|
+
}
|
217
|
+
pressDelayEvent.reset(0);
|
218
|
+
mouseTarget = 0;
|
219
|
+
} else if (mouseTarget) {
|
220
|
+
// we did send a press, so we need to fake a release now
|
221
|
+
Qt::MouseButtons mouseButtons = QApplication::mouseButtons();
|
222
|
+
|
223
|
+
// release all pressed mouse buttons
|
224
|
+
/*for (int i = 0; i < 32; ++i) {
|
225
|
+
if (mouseButtons & (1 << i)) {
|
226
|
+
Qt::MouseButton b = static_cast<Qt::MouseButton>(1 << i);
|
227
|
+
mouseButtons &= ~b;
|
228
|
+
QPoint farFarAway(-QWIDGETSIZE_MAX, -QWIDGETSIZE_MAX);
|
229
|
+
|
230
|
+
qFGDebug() << "QFG: sending a fake mouse release at far-far-away to " << mouseTarget;
|
231
|
+
QMouseEvent re(QEvent::MouseButtonRelease, QPoint(), farFarAway,
|
232
|
+
b, mouseButtons, QApplication::keyboardModifiers());
|
233
|
+
sendMouseEvent(&re);
|
234
|
+
}
|
235
|
+
}*/
|
236
|
+
|
237
|
+
QPoint farFarAway(-QWIDGETSIZE_MAX, -QWIDGETSIZE_MAX);
|
238
|
+
|
239
|
+
qFGDebug() << "QFG: sending a fake mouse release at far-far-away to " << mouseTarget;
|
240
|
+
QMouseEvent re(QEvent::MouseButtonRelease, QPoint(), farFarAway,
|
241
|
+
mouseButton, QApplication::mouseButtons() & ~mouseButton,
|
242
|
+
QApplication::keyboardModifiers());
|
243
|
+
sendMouseEvent(&re, RegrabMouseAfterwards);
|
244
|
+
// don't clear the mouseTarget just yet, since we need to explicitly ungrab the mouse on release!
|
245
|
+
}
|
246
|
+
}
|
247
|
+
|
248
|
+
protected:
|
249
|
+
void timerEvent(QTimerEvent *e)
|
250
|
+
{
|
251
|
+
if (e->timerId() == pressDelayTimer) {
|
252
|
+
if (pressDelayEvent && mouseTarget) {
|
253
|
+
qFGDebug() << "QFG: timer event: re-sending mouse press to " << mouseTarget;
|
254
|
+
sendMouseEvent(pressDelayEvent.data(), UngrabMouseBefore);
|
255
|
+
}
|
256
|
+
pressDelayEvent.reset(0);
|
257
|
+
|
258
|
+
if (pressDelayTimer) {
|
259
|
+
killTimer(pressDelayTimer);
|
260
|
+
pressDelayTimer = 0;
|
261
|
+
}
|
262
|
+
}
|
263
|
+
}
|
264
|
+
|
265
|
+
void sendMouseEvent(QMouseEvent *me, int flags = 0)
|
266
|
+
{
|
267
|
+
if (mouseTarget) {
|
268
|
+
sendingEvent = true;
|
269
|
+
|
270
|
+
QGraphicsItem *grabber = 0;
|
271
|
+
if (mouseTarget->parentWidget()) {
|
272
|
+
if (QGraphicsView *gv = qobject_cast<QGraphicsView *>(mouseTarget->parentWidget())) {
|
273
|
+
if (gv->scene())
|
274
|
+
grabber = gv->scene()->mouseGrabberItem();
|
275
|
+
}
|
276
|
+
}
|
277
|
+
|
278
|
+
if (grabber && (flags & UngrabMouseBefore)) {
|
279
|
+
// GraphicsView Mouse Handling Workaround #1:
|
280
|
+
// we need to ungrab the mouse before re-sending the press,
|
281
|
+
// since the scene had already set the mouse grabber to the
|
282
|
+
// original (and consumed) event's receiver
|
283
|
+
qFGDebug() << "QFG: ungrabbing" << grabber;
|
284
|
+
grabber->ungrabMouse();
|
285
|
+
}
|
286
|
+
|
287
|
+
if (me) {
|
288
|
+
QMouseEvent copy(me->type(), mouseTarget->mapFromGlobal(me->globalPos()), me->globalPos(), me->button(), me->buttons(), me->modifiers());
|
289
|
+
qt_sendSpontaneousEvent(mouseTarget, ©);
|
290
|
+
}
|
291
|
+
|
292
|
+
if (grabber && (flags & RegrabMouseAfterwards)) {
|
293
|
+
// GraphicsView Mouse Handling Workaround #2:
|
294
|
+
// we need to re-grab the mouse after sending a faked mouse
|
295
|
+
// release, since we still need the mouse moves for the gesture
|
296
|
+
// (the scene will clear the item's mouse grabber status on
|
297
|
+
// release).
|
298
|
+
qFGDebug() << "QFG: re-grabbing" << grabber;
|
299
|
+
grabber->grabMouse();
|
300
|
+
}
|
301
|
+
sendingEvent = false;
|
302
|
+
}
|
303
|
+
}
|
304
|
+
|
305
|
+
|
306
|
+
private:
|
307
|
+
int pressDelayTimer;
|
308
|
+
QScopedPointer<QMouseEvent> pressDelayEvent;
|
309
|
+
bool sendingEvent;
|
310
|
+
Qt::MouseButton mouseButton;
|
311
|
+
QPointer<QWidget> mouseTarget;
|
312
|
+
};
|
313
|
+
|
314
|
+
|
315
|
+
/*!
|
316
|
+
\internal
|
317
|
+
\class QFlickGesture
|
318
|
+
\since 4.8
|
319
|
+
\brief The QFlickGesture class describes a flicking gesture made by the user.
|
320
|
+
\ingroup gestures
|
321
|
+
The QFlickGesture is more complex than the QPanGesture that uses QScroller and QScrollerProperties
|
322
|
+
to decide if it is triggered.
|
323
|
+
This gesture is reacting on touch event as compared to the QMouseFlickGesture.
|
324
|
+
|
325
|
+
\sa {Gestures Programming}, QScroller, QScrollerProperties, QMouseFlickGesture
|
326
|
+
*/
|
327
|
+
|
328
|
+
/*!
|
329
|
+
\internal
|
330
|
+
*/
|
331
|
+
QtFlickGesture::QtFlickGesture(QObject *receiver_, Qt::MouseButton button, QObject *parent)
|
332
|
+
: QGesture(parent), receiver(receiver_), receiverScroller(0), button(button),
|
333
|
+
macIgnoreWheel(false)
|
334
|
+
{
|
335
|
+
receiverScroller = (receiver && QtScroller::hasScroller(receiver)) ? QtScroller::scroller(receiver) : 0;
|
336
|
+
}
|
337
|
+
|
338
|
+
QtFlickGesture::~QtFlickGesture()
|
339
|
+
{ }
|
340
|
+
|
341
|
+
bool QtFlickGesture::eventFilter(QObject *o, QEvent *e)
|
342
|
+
{
|
343
|
+
if ((e->type() == QEvent::Move) && o && o == receiverWindow) {
|
344
|
+
receiverWindowPos = receiverWindow->geometry().topLeft();
|
345
|
+
}
|
346
|
+
return QGesture::eventFilter(o, e);
|
347
|
+
}
|
348
|
+
|
349
|
+
//
|
350
|
+
// QFlickGestureRecognizer
|
351
|
+
//
|
352
|
+
|
353
|
+
|
354
|
+
QtFlickGestureRecognizer::QtFlickGestureRecognizer(Qt::MouseButton button)
|
355
|
+
{
|
356
|
+
this->button = button;
|
357
|
+
}
|
358
|
+
|
359
|
+
/*! \reimp
|
360
|
+
*/
|
361
|
+
QGesture *QtFlickGestureRecognizer::create(QObject *target)
|
362
|
+
{
|
363
|
+
QGraphicsObject *go = qobject_cast<QGraphicsObject*>(target);
|
364
|
+
if (go && button == Qt::NoButton) {
|
365
|
+
go->setAcceptTouchEvents(true);
|
366
|
+
}
|
367
|
+
return new QtFlickGesture(target, button);
|
368
|
+
}
|
369
|
+
|
370
|
+
/*! \internal
|
371
|
+
The recognize function detects a touch event suitable to start the attached QScroller.
|
372
|
+
The QFlickGesture will be triggered as soon as the scroller is no longer in the state
|
373
|
+
QScroller::Inactive or QScroller::Pressed. It will be finished or canceled
|
374
|
+
at the next QEvent::TouchEnd.
|
375
|
+
Note that the QScroller might continue scrolling (kinetically) at this point.
|
376
|
+
*/
|
377
|
+
QGestureRecognizer::Result QtFlickGestureRecognizer::recognize(QGesture *state,
|
378
|
+
QObject *watched,
|
379
|
+
QEvent *event)
|
380
|
+
{
|
381
|
+
Q_UNUSED(watched);
|
382
|
+
|
383
|
+
static QElapsedTimer monotonicTimer;
|
384
|
+
if (!monotonicTimer.isValid())
|
385
|
+
monotonicTimer.start();
|
386
|
+
|
387
|
+
QtFlickGesture *q = static_cast<QtFlickGesture *>(state);
|
388
|
+
QtFlickGesture *d = q; // for source compatiblitly with the 4.8 QScroller
|
389
|
+
|
390
|
+
QtScroller *scroller = d->receiverScroller;
|
391
|
+
if (!scroller)
|
392
|
+
return Ignore; // nothing to do without a scroller?
|
393
|
+
|
394
|
+
QWidget *receiverWidget = qobject_cast<QWidget *>(d->receiver);
|
395
|
+
QGraphicsObject *receiverGraphicsObject = qobject_cast<QGraphicsObject *>(d->receiver);
|
396
|
+
|
397
|
+
// this is only set for events that we inject into the event loop via sendEvent()
|
398
|
+
if (PressDelayHandler::instance()->shouldEventBeIgnored(event)) {
|
399
|
+
//qFGDebug() << state << "QFG: ignored event: " << event->type();
|
400
|
+
return Ignore;
|
401
|
+
}
|
402
|
+
|
403
|
+
const QMouseEvent *me = 0;
|
404
|
+
const QGraphicsSceneMouseEvent *gsme = 0;
|
405
|
+
const QTouchEvent *te = 0;
|
406
|
+
QPoint globalPos;
|
407
|
+
|
408
|
+
// qFGDebug() << "FlickGesture "<<state<<"watched:"<<watched<<"receiver"<<d->receiver<<"event"<<event->type()<<"button"<<button;
|
409
|
+
|
410
|
+
switch (event->type()) {
|
411
|
+
case QEvent::MouseButtonPress:
|
412
|
+
case QEvent::MouseButtonRelease:
|
413
|
+
case QEvent::MouseMove:
|
414
|
+
if (!receiverWidget)
|
415
|
+
return Ignore;
|
416
|
+
if (button != Qt::NoButton) {
|
417
|
+
me = static_cast<const QMouseEvent *>(event);
|
418
|
+
globalPos = me->globalPos();
|
419
|
+
}
|
420
|
+
break;
|
421
|
+
case QEvent::GraphicsSceneMousePress:
|
422
|
+
case QEvent::GraphicsSceneMouseRelease:
|
423
|
+
case QEvent::GraphicsSceneMouseMove:
|
424
|
+
if (!receiverGraphicsObject)
|
425
|
+
return Ignore;
|
426
|
+
if (button != Qt::NoButton) {
|
427
|
+
gsme = static_cast<const QGraphicsSceneMouseEvent *>(event);
|
428
|
+
globalPos = gsme->screenPos();
|
429
|
+
}
|
430
|
+
break;
|
431
|
+
case QEvent::TouchBegin:
|
432
|
+
case QEvent::TouchEnd:
|
433
|
+
case QEvent::TouchUpdate:
|
434
|
+
if (button == Qt::NoButton) {
|
435
|
+
te = static_cast<const QTouchEvent *>(event);
|
436
|
+
if (!te->touchPoints().isEmpty())
|
437
|
+
globalPos = te->touchPoints().at(0).screenPos().toPoint();
|
438
|
+
}
|
439
|
+
break;
|
440
|
+
|
441
|
+
#if defined(Q_WS_MAC)
|
442
|
+
// the only way to distinguish between real mouse wheels and wheel
|
443
|
+
// events generated by the native 2 finger swipe gesture is to listen
|
444
|
+
// for these events (according to Apple's Cocoa Event-Handling Guide)
|
445
|
+
|
446
|
+
case QEvent::NativeGesture: {
|
447
|
+
#if 0 // QNativeGestureEvent is in qevent_p.h, which is of no use for this solution
|
448
|
+
QNativeGestureEvent *nge = static_cast<QNativeGestureEvent *>(event);
|
449
|
+
if (nge->gestureType == QNativeGestureEvent::GestureBegin)
|
450
|
+
d->macIgnoreWheel = true;
|
451
|
+
else if (nge->gestureType == QNativeGestureEvent::GestureEnd)
|
452
|
+
d->macIgnoreWheel = false;
|
453
|
+
#else // This is a very evil hack, but it only has to work for Qt 4.6/4.7 anyway
|
454
|
+
int type = *reinterpret_cast<int *>(event + 1);
|
455
|
+
if (type == 1)
|
456
|
+
d->macIgnoreWheel = true;
|
457
|
+
else if (type == 2)
|
458
|
+
d->macIgnoreWheel = false;
|
459
|
+
#endif
|
460
|
+
break;
|
461
|
+
}
|
462
|
+
#endif
|
463
|
+
|
464
|
+
// consume all wheel events if the scroller is active
|
465
|
+
case QEvent::Wheel:
|
466
|
+
if (d->macIgnoreWheel || (scroller->state() != QtScroller::Inactive))
|
467
|
+
return Ignore | ConsumeEventHint;
|
468
|
+
break;
|
469
|
+
|
470
|
+
// consume all dbl click events if the scroller is active
|
471
|
+
case QEvent::MouseButtonDblClick:
|
472
|
+
if (scroller->state() != QtScroller::Inactive)
|
473
|
+
return Ignore | ConsumeEventHint;
|
474
|
+
break;
|
475
|
+
|
476
|
+
default:
|
477
|
+
break;
|
478
|
+
}
|
479
|
+
|
480
|
+
if (!me && !gsme && !te) // Neither mouse nor touch
|
481
|
+
return Ignore;
|
482
|
+
// get the current pointer position in local coordinates.
|
483
|
+
QPointF point;
|
484
|
+
QtScroller::Input inputType = (QtScroller::Input) 0;
|
485
|
+
|
486
|
+
switch (event->type()) {
|
487
|
+
case QEvent::MouseButtonPress:
|
488
|
+
if (me && me->button() == button && me->buttons() == button) {
|
489
|
+
point = me->globalPos();
|
490
|
+
inputType = QtScroller::InputPress;
|
491
|
+
} else if (me) {
|
492
|
+
scroller->stop();
|
493
|
+
return CancelGesture;
|
494
|
+
}
|
495
|
+
break;
|
496
|
+
case QEvent::MouseButtonRelease:
|
497
|
+
if (me && me->button() == button) {
|
498
|
+
point = me->globalPos();
|
499
|
+
inputType = QtScroller::InputRelease;
|
500
|
+
}
|
501
|
+
break;
|
502
|
+
case QEvent::MouseMove:
|
503
|
+
#ifdef Q_OS_SYMBIAN
|
504
|
+
// Qt on Symbian tracks the button state internally, while Qt on Win/Mac/Unix
|
505
|
+
// relies on the windowing system to report the current buttons state.
|
506
|
+
if (me && (me->buttons() == button || !me->buttons())) {
|
507
|
+
#else
|
508
|
+
if (me && me->buttons() == button) {
|
509
|
+
#endif
|
510
|
+
point = me->globalPos();
|
511
|
+
inputType = QtScroller::InputMove;
|
512
|
+
}
|
513
|
+
break;
|
514
|
+
|
515
|
+
case QEvent::GraphicsSceneMousePress:
|
516
|
+
if (gsme && gsme->button() == button && gsme->buttons() == button) {
|
517
|
+
point = gsme->scenePos();
|
518
|
+
inputType = QtScroller::InputPress;
|
519
|
+
} else if (gsme) {
|
520
|
+
scroller->stop();
|
521
|
+
return CancelGesture;
|
522
|
+
}
|
523
|
+
break;
|
524
|
+
case QEvent::GraphicsSceneMouseRelease:
|
525
|
+
if (gsme && gsme->button() == button) {
|
526
|
+
point = gsme->scenePos();
|
527
|
+
inputType = QtScroller::InputRelease;
|
528
|
+
}
|
529
|
+
break;
|
530
|
+
case QEvent::GraphicsSceneMouseMove:
|
531
|
+
#ifdef Q_OS_SYMBIAN
|
532
|
+
// Qt on Symbian tracks the button state internally, while Qt on Win/Mac/Unix
|
533
|
+
// relies on the windowing system to report the current buttons state.
|
534
|
+
if (gsme && (gsme->buttons() == button || !gsme->buttons())) {
|
535
|
+
#else
|
536
|
+
if (gsme && gsme->buttons() == button) {
|
537
|
+
#endif
|
538
|
+
point = gsme->scenePos();
|
539
|
+
inputType = QtScroller::InputMove;
|
540
|
+
}
|
541
|
+
break;
|
542
|
+
|
543
|
+
case QEvent::TouchBegin:
|
544
|
+
inputType = QtScroller::InputPress;
|
545
|
+
// fall through
|
546
|
+
case QEvent::TouchEnd:
|
547
|
+
if (!inputType)
|
548
|
+
inputType = QtScroller::InputRelease;
|
549
|
+
// fallthrough
|
550
|
+
case QEvent::TouchUpdate:
|
551
|
+
if (!inputType)
|
552
|
+
inputType = QtScroller::InputMove;
|
553
|
+
|
554
|
+
if (te->device()->type() == QTouchDevice::TouchPad) {
|
555
|
+
if (te->touchPoints().count() != 2) // 2 fingers on pad
|
556
|
+
return Ignore;
|
557
|
+
|
558
|
+
point = te->touchPoints().at(0).startScenePos() +
|
559
|
+
((te->touchPoints().at(0).scenePos() - te->touchPoints().at(0).startScenePos()) +
|
560
|
+
(te->touchPoints().at(1).scenePos() - te->touchPoints().at(1).startScenePos())) / 2;
|
561
|
+
} else { // TouchScreen
|
562
|
+
if (te->touchPoints().count() != 1) // 1 finger on screen
|
563
|
+
return Ignore;
|
564
|
+
|
565
|
+
point = te->touchPoints().at(0).scenePos();
|
566
|
+
}
|
567
|
+
break;
|
568
|
+
|
569
|
+
default:
|
570
|
+
break;
|
571
|
+
}
|
572
|
+
|
573
|
+
// Check for an active scroller at globalPos
|
574
|
+
if (inputType == QtScroller::InputPress) {
|
575
|
+
foreach (QtScroller *as, QtScroller::activeScrollers()) {
|
576
|
+
if (as != scroller) {
|
577
|
+
QRegion scrollerRegion;
|
578
|
+
|
579
|
+
if (QWidget *w = qobject_cast<QWidget *>(as->target())) {
|
580
|
+
scrollerRegion = QRect(w->mapToGlobal(QPoint(0, 0)), w->size());
|
581
|
+
} else if (QGraphicsObject *go = qobject_cast<QGraphicsObject *>(as->target())) {
|
582
|
+
if (go->scene() && !go->scene()->views().isEmpty()) {
|
583
|
+
foreach (QGraphicsView *gv, go->scene()->views())
|
584
|
+
scrollerRegion |= gv->mapFromScene(go->mapToScene(go->boundingRect()))
|
585
|
+
.translated(gv->mapToGlobal(QPoint(0, 0)));
|
586
|
+
}
|
587
|
+
}
|
588
|
+
// active scrollers always have priority
|
589
|
+
if (scrollerRegion.contains(globalPos)) {
|
590
|
+
qFGDebug() << "QFG: ignoring press event at" << globalPos << "since another scroller is active there";
|
591
|
+
return Ignore;
|
592
|
+
}
|
593
|
+
}
|
594
|
+
}
|
595
|
+
}
|
596
|
+
|
597
|
+
bool scrollerWasDragging = (scroller->state() == QtScroller::Dragging);
|
598
|
+
bool scrollerWasScrolling = (scroller->state() == QtScroller::Scrolling);
|
599
|
+
|
600
|
+
if (inputType) {
|
601
|
+
// QWidget::mapFromGlobal is very expensive on X11, so we cache the global position of the widget
|
602
|
+
if (receiverWidget) {
|
603
|
+
if (receiverWidget->window() != d->receiverWindow) {
|
604
|
+
if (d->receiverWindow)
|
605
|
+
d->receiverWindow->removeEventFilter(q);
|
606
|
+
d->receiverWindow = receiverWidget->window();
|
607
|
+
d->receiverWindowPos = d->receiverWindow->geometry().topLeft();
|
608
|
+
d->receiverWindow->installEventFilter(q);
|
609
|
+
}
|
610
|
+
point = receiverWidget->mapFrom(d->receiverWindow, point.toPoint() - d->receiverWindowPos);
|
611
|
+
} else if (receiverGraphicsObject) {
|
612
|
+
point = receiverGraphicsObject->mapFromScene(point);
|
613
|
+
}
|
614
|
+
// inform the scroller about the new event
|
615
|
+
scroller->handleInput(inputType, point, monotonicTimer.elapsed());
|
616
|
+
}
|
617
|
+
|
618
|
+
// depending on the scroller state return the gesture state
|
619
|
+
Result result(0);
|
620
|
+
bool scrollerIsActive = (scroller->state() == QtScroller::Dragging ||
|
621
|
+
scroller->state() == QtScroller::Scrolling);
|
622
|
+
|
623
|
+
// Consume all mouse events while dragging or scrolling to avoid nasty
|
624
|
+
// side effects with Qt's standard widgets.
|
625
|
+
if ((me || gsme) && scrollerIsActive)
|
626
|
+
result |= ConsumeEventHint;
|
627
|
+
|
628
|
+
// The only problem with this approach is that we consume the
|
629
|
+
// MouseRelease when we start the scrolling with a flick gesture, so we
|
630
|
+
// have to fake a MouseRelease "somewhere" to not mess with the internal
|
631
|
+
// states of Qt's widgets (a QPushButton would stay in 'pressed' state
|
632
|
+
// forever, if it doesn't receive a MouseRelease).
|
633
|
+
if (me || gsme) {
|
634
|
+
if (!scrollerWasDragging && !scrollerWasScrolling && scrollerIsActive)
|
635
|
+
PressDelayHandler::instance()->scrollerBecameActive();
|
636
|
+
else if (scrollerWasScrolling && (scroller->state() == QtScroller::Dragging || scroller->state() == QtScroller::Inactive))
|
637
|
+
PressDelayHandler::instance()->scrollerWasIntercepted();
|
638
|
+
}
|
639
|
+
|
640
|
+
if (!inputType) {
|
641
|
+
result |= Ignore;
|
642
|
+
} else {
|
643
|
+
switch (event->type()) {
|
644
|
+
case QEvent::MouseButtonPress:
|
645
|
+
case QEvent::GraphicsSceneMousePress:
|
646
|
+
if (scroller->state() == QtScroller::Pressed) {
|
647
|
+
int pressDelay = int(1000 * scroller->scrollerProperties().scrollMetric(QtScrollerProperties::MousePressEventDelay).toReal());
|
648
|
+
if (pressDelay > 0) {
|
649
|
+
result |= ConsumeEventHint;
|
650
|
+
|
651
|
+
PressDelayHandler::instance()->pressed(event, pressDelay);
|
652
|
+
event->accept();
|
653
|
+
}
|
654
|
+
}
|
655
|
+
// fall through
|
656
|
+
case QEvent::TouchBegin:
|
657
|
+
q->setHotSpot(globalPos);
|
658
|
+
result |= scrollerIsActive ? TriggerGesture : MayBeGesture;
|
659
|
+
break;
|
660
|
+
|
661
|
+
|
662
|
+
case QEvent::MouseMove:
|
663
|
+
case QEvent::GraphicsSceneMouseMove:
|
664
|
+
if (PressDelayHandler::instance()->isDelaying())
|
665
|
+
result |= ConsumeEventHint;
|
666
|
+
// fall through
|
667
|
+
case QEvent::TouchUpdate:
|
668
|
+
result |= scrollerIsActive ? TriggerGesture : Ignore;
|
669
|
+
break;
|
670
|
+
|
671
|
+
case QEvent::GraphicsSceneMouseRelease:
|
672
|
+
case QEvent::MouseButtonRelease:
|
673
|
+
if (PressDelayHandler::instance()->released(event, scrollerWasDragging || scrollerWasScrolling, scrollerIsActive))
|
674
|
+
result |= ConsumeEventHint;
|
675
|
+
// fall through
|
676
|
+
case QEvent::TouchEnd:
|
677
|
+
result |= scrollerIsActive ? FinishGesture : CancelGesture;
|
678
|
+
break;
|
679
|
+
|
680
|
+
default:
|
681
|
+
result |= Ignore;
|
682
|
+
break;
|
683
|
+
}
|
684
|
+
}
|
685
|
+
return result;
|
686
|
+
}
|
687
|
+
|
688
|
+
|
689
|
+
/*! \reimp
|
690
|
+
*/
|
691
|
+
void QtFlickGestureRecognizer::reset(QGesture *state)
|
692
|
+
{
|
693
|
+
QGestureRecognizer::reset(state);
|
694
|
+
}
|
695
|
+
|
696
|
+
#endif // QT_NO_GESTURES
|