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.
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