1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/layers/apz/src/Axis.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,219 @@ 1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* vim: set sw=2 ts=8 et tw=80 : */ 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +#ifndef mozilla_layers_Axis_h 1.11 +#define mozilla_layers_Axis_h 1.12 + 1.13 +#include <sys/types.h> // for int32_t 1.14 +#include "Units.h" // for CSSRect, CSSPoint 1.15 +#include "mozilla/TimeStamp.h" // for TimeDuration 1.16 +#include "nsTArray.h" // for nsTArray 1.17 + 1.18 +namespace mozilla { 1.19 +namespace layers { 1.20 + 1.21 +const float EPSILON = 0.0001f; 1.22 + 1.23 +class AsyncPanZoomController; 1.24 + 1.25 +/** 1.26 + * Helper class to maintain each axis of movement (X,Y) for panning and zooming. 1.27 + * Note that everything here is specific to one axis; that is, the X axis knows 1.28 + * nothing about the Y axis and vice versa. 1.29 + */ 1.30 +class Axis { 1.31 +public: 1.32 + Axis(AsyncPanZoomController* aAsyncPanZoomController); 1.33 + 1.34 + enum Overscroll { 1.35 + // Overscroll is not happening at all. 1.36 + OVERSCROLL_NONE = 0, 1.37 + // Overscroll is happening in the negative direction. This means either to 1.38 + // the left or to the top depending on the axis. 1.39 + OVERSCROLL_MINUS, 1.40 + // Overscroll is happening in the positive direction. This means either to 1.41 + // the right or to the bottom depending on the axis. 1.42 + OVERSCROLL_PLUS, 1.43 + // Overscroll is happening both ways. This only means something when the 1.44 + // page is scaled out to a smaller size than the viewport. 1.45 + OVERSCROLL_BOTH 1.46 + }; 1.47 + 1.48 + /** 1.49 + * Notify this Axis that a new touch has been received, including a time delta 1.50 + * indicating how long it has been since the previous one. This triggers a 1.51 + * recalculation of velocity. 1.52 + */ 1.53 + void UpdateWithTouchAtDevicePoint(int32_t aPos, const TimeDuration& aTimeDelta); 1.54 + 1.55 + /** 1.56 + * Notify this Axis that a touch has begun, i.e. the user has put their finger 1.57 + * on the screen but has not yet tried to pan. 1.58 + */ 1.59 + void StartTouch(int32_t aPos); 1.60 + 1.61 + /** 1.62 + * Notify this Axis that a touch has ended gracefully. This may perform 1.63 + * recalculations of the axis velocity. 1.64 + */ 1.65 + void EndTouch(); 1.66 + 1.67 + /** 1.68 + * Notify this Axis that a touch has ended forcefully. Useful for stopping 1.69 + * flings when a user puts their finger down in the middle of one (i.e. to 1.70 + * stop a previous touch including its fling so that a new one can take its 1.71 + * place). 1.72 + */ 1.73 + void CancelTouch(); 1.74 + 1.75 + /** 1.76 + * Takes a requested displacement to the position of this axis, and adjusts it 1.77 + * to account for overscroll (which might decrease the displacement; this is 1.78 + * to prevent the viewport from overscrolling the page rect), and axis locking 1.79 + * (which might prevent any displacement from happening). If overscroll 1.80 + * ocurred, its amount is written to |aOverscrollAmountOut|. 1.81 + * The adjusted displacement is returned. 1.82 + */ 1.83 + float AdjustDisplacement(float aDisplacement, float& aOverscrollAmountOut); 1.84 + 1.85 + /** 1.86 + * Gets the distance between the starting position of the touch supplied in 1.87 + * startTouch() and the current touch from the last 1.88 + * updateWithTouchAtDevicePoint(). 1.89 + */ 1.90 + float PanDistance(); 1.91 + 1.92 + /** 1.93 + * Gets the distance between the starting position of the touch supplied in 1.94 + * startTouch() and the supplied position. 1.95 + */ 1.96 + float PanDistance(float aPos); 1.97 + 1.98 + /** 1.99 + * Applies friction during a fling, or cancels the fling if the velocity is 1.100 + * too low. Returns true if the fling should continue to another frame, or 1.101 + * false if it should end. |aDelta| is the amount of time that has passed 1.102 + * since the last time friction was applied. 1.103 + */ 1.104 + bool FlingApplyFrictionOrCancel(const TimeDuration& aDelta); 1.105 + 1.106 + /* 1.107 + * Returns true if the page is zoomed in to some degree along this axis such that scrolling is 1.108 + * possible and this axis has not been scroll locked while panning. Otherwise, returns false. 1.109 + */ 1.110 + bool Scrollable(); 1.111 + 1.112 + void SetAxisLocked(bool aAxisLocked) { mAxisLocked = aAxisLocked; } 1.113 + 1.114 + /** 1.115 + * Gets the overscroll state of the axis in its current position. 1.116 + */ 1.117 + Overscroll GetOverscroll(); 1.118 + 1.119 + /** 1.120 + * If there is overscroll, returns the amount. Sign depends on in what 1.121 + * direction it is overscrolling. Positive excess means that it is 1.122 + * overscrolling in the positive direction, whereas negative excess means 1.123 + * that it is overscrolling in the negative direction. If there is overscroll 1.124 + * in both directions, this returns 0; it assumes that you check 1.125 + * GetOverscroll() first. 1.126 + */ 1.127 + float GetExcess(); 1.128 + 1.129 + /** 1.130 + * Gets the raw velocity of this axis at this moment. 1.131 + */ 1.132 + float GetVelocity(); 1.133 + 1.134 + /** 1.135 + * Sets the raw velocity of this axis at this moment. 1.136 + * Intended to be called only when the axis "takes over" a velocity from 1.137 + * another APZC, in which case there are no touch points available to call 1.138 + * UpdateWithTouchAtDevicePoint. In other circumstances, 1.139 + * UpdateWithTouchAtDevicePoint should be used and the velocity calculated 1.140 + * there. 1.141 + */ 1.142 + void SetVelocity(float aVelocity); 1.143 + 1.144 + /** 1.145 + * Gets the overscroll state of the axis given an additional displacement. 1.146 + * That is to say, if the given displacement is applied, this will tell you 1.147 + * whether or not it will overscroll, and in what direction. 1.148 + */ 1.149 + Overscroll DisplacementWillOverscroll(float aDisplacement); 1.150 + 1.151 + /** 1.152 + * If a displacement will overscroll the axis, this returns the amount and in 1.153 + * what direction. Similar to GetExcess() but takes a displacement to apply. 1.154 + */ 1.155 + float DisplacementWillOverscrollAmount(float aDisplacement); 1.156 + 1.157 + /** 1.158 + * If a scale will overscroll the axis, this returns the amount and in what 1.159 + * direction. Similar to GetExcess() but takes a displacement to apply. 1.160 + * 1.161 + * |aFocus| is the point at which the scale is focused at. We will offset the 1.162 + * scroll offset in such a way that it remains in the same place on the page 1.163 + * relative. 1.164 + */ 1.165 + float ScaleWillOverscrollAmount(float aScale, float aFocus); 1.166 + 1.167 + /** 1.168 + * Checks if an axis will overscroll in both directions by computing the 1.169 + * content rect and checking that its height/width (depending on the axis) 1.170 + * does not overextend past the viewport. 1.171 + * 1.172 + * This gets called by ScaleWillOverscroll(). 1.173 + */ 1.174 + bool ScaleWillOverscrollBothSides(float aScale); 1.175 + 1.176 + /** 1.177 + * Returns whether there is room to pan on this axis in either direction. 1.178 + */ 1.179 + bool HasRoomToPan() const; 1.180 + 1.181 + float GetOrigin() const; 1.182 + float GetCompositionLength() const; 1.183 + float GetPageStart() const; 1.184 + float GetPageLength() const; 1.185 + float GetCompositionEnd() const; 1.186 + float GetPageEnd() const; 1.187 + 1.188 + int32_t GetPos() const { return mPos; } 1.189 + 1.190 + virtual float GetPointOffset(const CSSPoint& aPoint) const = 0; 1.191 + virtual float GetRectLength(const CSSRect& aRect) const = 0; 1.192 + virtual float GetRectOffset(const CSSRect& aRect) const = 0; 1.193 + 1.194 +protected: 1.195 + int32_t mPos; 1.196 + int32_t mStartPos; 1.197 + float mVelocity; 1.198 + bool mAxisLocked; // Whether movement on this axis is locked. 1.199 + AsyncPanZoomController* mAsyncPanZoomController; 1.200 + nsTArray<float> mVelocityQueue; 1.201 +}; 1.202 + 1.203 +class AxisX : public Axis { 1.204 +public: 1.205 + AxisX(AsyncPanZoomController* mAsyncPanZoomController); 1.206 + virtual float GetPointOffset(const CSSPoint& aPoint) const; 1.207 + virtual float GetRectLength(const CSSRect& aRect) const; 1.208 + virtual float GetRectOffset(const CSSRect& aRect) const; 1.209 +}; 1.210 + 1.211 +class AxisY : public Axis { 1.212 +public: 1.213 + AxisY(AsyncPanZoomController* mAsyncPanZoomController); 1.214 + virtual float GetPointOffset(const CSSPoint& aPoint) const; 1.215 + virtual float GetRectLength(const CSSRect& aRect) const; 1.216 + virtual float GetRectOffset(const CSSRect& aRect) const; 1.217 +}; 1.218 + 1.219 +} 1.220 +} 1.221 + 1.222 +#endif