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