[Qt][WK2] Do not apply new viewport properties until after the first visually non...
[WebKit.git] / Source / WebKit2 / UIProcess / qt / QtViewportInteractionEngine.h
1 /*
2  * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies)
3  * Copyright (C) 2011 Benjamin Poulain <benjamin@webkit.org>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public License
16  * along with this program; see the file COPYING.LIB.  If not, write to
17  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  *
20  */
21
22 #ifndef QtViewportInteractionEngine_h
23 #define QtViewportInteractionEngine_h
24
25 #include "OwnPtr.h"
26 #include <QScroller>
27 #include "qwebkitglobal.h"
28 #include <QtCore/QObject>
29 #include <QtCore/QRectF>
30 #include <QtCore/QVariant>
31 #include <QtCore/QVariantAnimation>
32
33 QT_BEGIN_NAMESPACE
34 class QPointF;
35 class QQuickItem;
36 QT_END_NAMESPACE
37
38 namespace WebKit {
39
40 class ViewportUpdateGuard;
41
42 class QtViewportInteractionEngine : public QObject {
43     Q_OBJECT
44
45 public:
46     QtViewportInteractionEngine(const QQuickItem*, QQuickItem*);
47     ~QtViewportInteractionEngine();
48
49     struct Constraints {
50         Constraints()
51             : initialScale(1.0)
52             , minimumScale(0.25)
53             , maximumScale(1.8)
54             , devicePixelRatio(1.0)
55             , isUserScalable(true)
56         { }
57
58         qreal initialScale;
59         qreal minimumScale;
60         qreal maximumScale;
61         qreal devicePixelRatio;
62         bool isUserScalable;
63     };
64
65     bool event(QEvent*);
66
67     void reset();
68     void applyConstraints(const Constraints&);
69
70     void setItemRectVisible(const QRectF&);
71     void animateItemRectVisible(const QRectF&);
72
73     void pagePositionRequest(const QPoint& pos);
74
75     bool scrollAnimationActive() const;
76     void interruptScrollAnimation();
77
78     bool panGestureActive() const;
79     void panGestureStarted(const QPointF& touchPoint, qint64 eventTimestampMillis);
80     void panGestureRequestUpdate(const QPointF& touchPoint, qint64 eventTimestampMillis);
81     void panGestureCancelled();
82     void panGestureEnded(const QPointF& touchPoint, qint64 eventTimestampMillis);
83
84     bool scaleAnimationActive() const;
85     void interruptScaleAnimation();
86
87     bool pinchGestureActive() const;
88     void pinchGestureStarted(const QPointF& pinchCenterInContentCoordinates);
89     void pinchGestureRequestUpdate(const QPointF& pinchCenterInContentCoordinates, qreal totalScaleFactor);
90     void pinchGestureEnded();
91
92     void zoomToAreaGestureEnded(const QPointF& touchPoint, const QRectF& endArea);
93
94 Q_SIGNALS:
95     void viewportUpdateRequested();
96     void viewportTrajectoryVectorChanged(const QPointF&);
97
98 private Q_SLOTS:
99     // Respond to changes of content that are not driven by us, like the page resizing itself.
100     void itemSizeChanged();
101
102     void scaleAnimationStateChanged(QAbstractAnimation::State, QAbstractAnimation::State);
103     void scaleAnimationValueChanged(QVariant value) { setItemRectVisible(value.toRectF()); }
104
105 private:
106     qreal cssScaleFromItem(qreal);
107     qreal itemScaleFromCSS(qreal);
108     qreal innerBoundedCSSScale(qreal);
109     qreal outerBoundedCSSScale(qreal);
110
111     QRectF computePosRangeForItemAtScale(qreal itemScale) const;
112     void ensureContentWithinViewportBoundary();
113
114     void scaleContent(const QPointF& centerInContentCoordinates, qreal scale);
115
116     // As long as the object exists this function will always return the same QScroller instance.
117     QScroller* scroller() { return QScroller::scroller(this); }
118
119     friend class ViewportUpdateGuard;
120
121     const QQuickItem* const m_viewport;
122     QQuickItem* const m_content;
123
124     Constraints m_constraints;
125     int m_pendingUpdates;
126     OwnPtr<ViewportUpdateGuard> m_pinchViewportUpdateDeferrer;
127     enum UserInteractionFlag {
128         UserHasNotInteractedWithContent = 0,
129         UserHasMovedContent = 1,
130         UserHasScaledContent = 2,
131     };
132     Q_DECLARE_FLAGS(UserInteractionFlags, UserInteractionFlag);
133     UserInteractionFlags m_userInteractionFlags;
134
135     class ScaleAnimation : public QVariantAnimation {
136     public:
137         ScaleAnimation(QObject* parent = 0)
138             : QVariantAnimation(parent)
139         { }
140
141         virtual void updateCurrentValue(const QVariant&) { }
142     };
143
144     ScaleAnimation* m_scaleAnimation;
145     QPointF m_lastPinchCenterInViewportCoordinates;
146     qreal m_pinchStartScale;
147 };
148
149 inline bool operator==(const QtViewportInteractionEngine::Constraints& a, const QtViewportInteractionEngine::Constraints& b)
150 {
151     return a.initialScale == b.initialScale
152             && a.minimumScale == b.minimumScale
153             && a.maximumScale == b.maximumScale
154             && a.isUserScalable == b.isUserScalable;
155 }
156
157 }
158
159 #endif // QtViewportInteractionEngine_h