rhodes 5.5.0.3 → 5.5.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +10 -0
  3. data/lib/commonAPI/coreapi/ext/platform/android/src/com/rho/notification/NotificationSingleton.java +20 -8
  4. data/lib/commonAPI/coreapi/ext/platform/iphone/cpp_based_impl/SystemImpl.mm +1 -2
  5. data/lib/commonAPI/coreapi/ext/system.xml +1 -1
  6. data/platform/android/build/android.rake +1 -0
  7. data/platform/iphone/Classes/AppManager/AppManager.m +44 -3
  8. data/platform/iphone/Classes/NativeView/RhoNativeViewManager.mm +4 -3
  9. data/platform/iphone/Classes/NativeView/RhoNativeViewManagerOC.h +1 -1
  10. data/platform/iphone/Classes/RhoMainView.h +8 -2
  11. data/platform/iphone/Classes/RhoUIWebView.h +75 -0
  12. data/platform/iphone/Classes/RhoUIWebView.m +142 -0
  13. data/platform/iphone/Classes/RhoWKWebView.h +87 -0
  14. data/platform/iphone/Classes/RhoWKWebView.m +187 -0
  15. data/platform/iphone/Classes/RhoWebView.h +72 -0
  16. data/platform/iphone/Classes/RhoWebViewFabrique.h +35 -0
  17. data/platform/iphone/Classes/RhoWebViewFabrique.m +87 -0
  18. data/platform/iphone/Classes/Rhodes.m +17 -6
  19. data/platform/iphone/Classes/Signature.old/SignatureDelegate.m +11 -4
  20. data/platform/iphone/Classes/Signature/SignatureDelegate.m +3 -4
  21. data/platform/iphone/Classes/SimpleMainView.h +7 -5
  22. data/platform/iphone/Classes/SimpleMainView.m +174 -179
  23. data/platform/iphone/Classes/SplitView/RightViewController.h +2 -2
  24. data/platform/iphone/Classes/SplitView/RightViewController.m +9 -10
  25. data/platform/iphone/Classes/SplitView/SplittedMainView.h +2 -3
  26. data/platform/iphone/Classes/SplitView/SplittedMainView.m +10 -7
  27. data/platform/iphone/Classes/TabbedMainView.h +2 -1
  28. data/platform/iphone/Classes/TabbedMainView.m +13 -10
  29. data/platform/iphone/Classes/URLProtocol/CRhoURLProtocol.m +21 -5
  30. data/platform/iphone/Classes/WebView.m +1 -1
  31. data/platform/iphone/RhoAppBaseLib/RhoAppBaseLib.xcodeproj/project.pbxproj +40 -3
  32. data/platform/iphone/RhoLib/RhoLib.xcodeproj/project.pbxproj +4 -0
  33. data/platform/iphone/rbuild/iphone.rake +51 -0
  34. data/platform/shared/common/RhoNativeViewManager.h +9 -9
  35. data/platform/shared/common/RhodesApp.cpp +13 -1
  36. data/platform/shared/net/HttpServer.cpp +12 -2
  37. data/platform/shared/qt/rhodes/ExternalWebView.ui +11 -2
  38. data/platform/shared/qt/rhodes/QtMainWindow.cpp +9 -7
  39. data/platform/shared/qt/rhodes/QtMainWindow.ui +13 -4
  40. data/platform/shared/qt/rhodes/qkineticscroller.cpp +1245 -0
  41. data/platform/shared/qt/rhodes/qkineticscroller.h +165 -0
  42. data/platform/shared/qt/rhodes/qkineticscroller_p.h +168 -0
  43. data/platform/shared/qt/rhodes/qtflickgesture.cpp +696 -0
  44. data/platform/shared/qt/rhodes/qtflickgesture_p.h +107 -0
  45. data/platform/shared/qt/rhodes/qtscroller.cpp +2080 -0
  46. data/platform/shared/qt/rhodes/qtscroller.h +138 -0
  47. data/platform/shared/qt/rhodes/qtscroller_p.h +205 -0
  48. data/platform/shared/qt/rhodes/qtscrollerfilter.cpp +350 -0
  49. data/platform/shared/qt/rhodes/qtscrollerfilter_p.h +110 -0
  50. data/platform/shared/qt/rhodes/qtscrollerproperties.cpp +412 -0
  51. data/platform/shared/qt/rhodes/qtscrollerproperties.h +135 -0
  52. data/platform/shared/qt/rhodes/qtscrollerproperties_p.h +90 -0
  53. data/platform/shared/qt/rhodes/qtscrollevent.cpp +190 -0
  54. data/platform/shared/qt/rhodes/qtscrollevent.h +100 -0
  55. data/platform/shared/qt/rhodes/qtscrollevent_p.h +33 -0
  56. data/platform/shared/qt/rhodes/qwebviewkineticscroller.cpp +347 -0
  57. data/platform/shared/qt/rhodes/qwebviewkineticscroller.h +90 -0
  58. data/platform/shared/qt/rhodes/qwebviewselectionsuppressor.h +113 -0
  59. data/platform/shared/qt/rhodes/rhodes.pro +19 -0
  60. data/res/generators/rhogen.rb +307 -15
  61. data/res/generators/templates/application/app/Settings/err_sync.erb +12 -6
  62. data/res/generators/templates/application/app/Settings/home.erb +32 -17
  63. data/res/generators/templates/application/app/Settings/index.erb +55 -26
  64. data/res/generators/templates/application/app/Settings/javascript_index.html +111 -0
  65. data/res/generators/templates/application/app/Settings/javascript_login.html +65 -0
  66. data/res/generators/templates/application/app/Settings/login.erb +25 -19
  67. data/res/generators/templates/application/app/Settings/reset.erb +18 -9
  68. data/res/generators/templates/application/app/Settings/wait.erb +10 -7
  69. data/res/generators/templates/application/app/index.erb +32 -20
  70. data/res/generators/templates/application/app/javascript_index.html +66 -0
  71. data/res/generators/templates/application/app/javascript_index.js +250 -0
  72. data/res/generators/templates/application/app/layout.erb +12 -67
  73. data/res/generators/templates/application/javascript_build.yml +41 -0
  74. data/res/generators/templates/application/javascript_rhoconfig.txt +123 -0
  75. data/res/generators/templates/application/public/bootstrap-3.3.7/css/bootstrap-theme.css +587 -0
  76. data/res/generators/templates/application/public/bootstrap-3.3.7/css/bootstrap-theme.css.map +1 -0
  77. data/res/generators/templates/application/public/bootstrap-3.3.7/css/bootstrap-theme.min.css +6 -0
  78. data/res/generators/templates/application/public/bootstrap-3.3.7/css/bootstrap-theme.min.css.map +1 -0
  79. data/res/generators/templates/application/public/bootstrap-3.3.7/css/bootstrap.css +6757 -0
  80. data/res/generators/templates/application/public/bootstrap-3.3.7/css/bootstrap.css.map +1 -0
  81. data/res/generators/templates/application/public/bootstrap-3.3.7/css/bootstrap.min.css +6 -0
  82. data/res/generators/templates/application/public/bootstrap-3.3.7/css/bootstrap.min.css.map +1 -0
  83. data/res/generators/templates/application/public/bootstrap-3.3.7/fonts/glyphicons-halflings-regular.eot +0 -0
  84. data/res/generators/templates/application/public/bootstrap-3.3.7/fonts/glyphicons-halflings-regular.svg +288 -0
  85. data/res/generators/templates/application/public/bootstrap-3.3.7/fonts/glyphicons-halflings-regular.ttf +0 -0
  86. data/res/generators/templates/application/public/bootstrap-3.3.7/fonts/glyphicons-halflings-regular.woff +0 -0
  87. data/res/generators/templates/application/public/bootstrap-3.3.7/fonts/glyphicons-halflings-regular.woff2 +0 -0
  88. data/res/generators/templates/application/public/bootstrap-3.3.7/js/bootstrap.js +2377 -0
  89. data/res/generators/templates/application/public/bootstrap-3.3.7/js/bootstrap.min.js +7 -0
  90. data/res/generators/templates/application/public/bootstrap-3.3.7/js/npm.js +13 -0
  91. data/res/generators/templates/application/public/css/style.css +3 -0
  92. data/res/generators/templates/application/public/jquery/jquery-3.1.1.min.js +4 -0
  93. data/res/generators/templates/application/public/jquery/jquery-3.1.1.min.map +1 -0
  94. data/res/generators/templates/application/rhoconfig.txt +16 -0
  95. data/res/generators/templates/iphone_project/Bremen7.xcodeproj/project.pbxproj +4 -0
  96. data/res/generators/templates/model/edit.erb +22 -21
  97. data/res/generators/templates/model/index.erb +24 -22
  98. data/res/generators/templates/model/javascript_edit.html +65 -0
  99. data/res/generators/templates/model/javascript_index.html +56 -0
  100. data/res/generators/templates/model/javascript_index.js +83 -0
  101. data/res/generators/templates/model/javascript_model.js +16 -0
  102. data/res/generators/templates/model/javascript_new.html +64 -0
  103. data/res/generators/templates/model/javascript_show.html +66 -0
  104. data/res/generators/templates/model/new.erb +22 -19
  105. data/res/generators/templates/model/show.erb +22 -14
  106. data/res/prebuild_base_app/app/index.erb +31 -18
  107. data/res/prebuild_base_app/app/layout.erb +11 -56
  108. data/version +1 -1
  109. metadata +59 -24
  110. data/res/generators/templates/application/public/css/android.css +0 -418
  111. data/res/generators/templates/application/public/css/iphone.css +0 -378
  112. data/res/generators/templates/application/public/css/jqmobile-patch.css +0 -62
  113. data/res/generators/templates/application/public/css/re_webkit.css +0 -736
  114. data/res/generators/templates/application/public/css/re_webkit_flat.css +0 -753
  115. data/res/generators/templates/application/public/css/windows_mobile.css +0 -327
  116. data/res/generators/templates/application/public/jqmobile/images/ajax-loader.gif +0 -0
  117. data/res/generators/templates/application/public/jqmobile/images/icon-search-black.png +0 -0
  118. data/res/generators/templates/application/public/jqmobile/images/icons-18-black.png +0 -0
  119. data/res/generators/templates/application/public/jqmobile/images/icons-18-white.png +0 -0
  120. data/res/generators/templates/application/public/jqmobile/images/icons-36-black.png +0 -0
  121. data/res/generators/templates/application/public/jqmobile/images/icons-36-white.png +0 -0
  122. data/res/generators/templates/application/public/jqmobile/jquery.mobile-1.4.5.min.css +0 -3
  123. data/res/generators/templates/application/public/jqmobile/jquery.mobile-1.4.5.min.js +0 -10
  124. data/res/generators/templates/application/public/jqmobile/jquery.mobile-1.4.5.min.map +0 -1
  125. data/res/generators/templates/application/public/jqmobile/jquery.mobile.structure-1.4.5.min.css +0 -3
  126. data/res/generators/templates/application/public/jqmobile/jquery.mobile.theme-1.4.5.min.css +0 -3
  127. data/res/generators/templates/application/public/jquery/jquery-1.9.1.min.js +0 -5
  128. data/res/generators/templates/application/public/jquery/jquery-1.9.1.min.map +0 -1
  129. data/res/generators/templates/application/public/js/application.js +0 -1
  130. data/res/generators/templates/application/public/js/jqmobile-patch.js +0 -466
  131. 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, &copy);
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