Bug 716673 - Misc cleanups in PanZoomController. r=pcwalton
authorKartikaya Gupta <kgupta@mozilla.com>
Tue, 10 Jan 2012 10:05:46 -0500
changeset 85436 9b10d778278b8e36ae1d81513d228f6bb0680e4e
parent 85435 dcf520615ac25f1c1a1e429c4b0457510e82047b
child 85437 4f670580388f0b585d1062d6248269562c97f15c
push id805
push userakeybl@mozilla.com
push dateWed, 01 Feb 2012 18:17:35 +0000
treeherdermozilla-aurora@6fb3bf232436 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspcwalton
bugs716673
milestone12.0a1
Bug 716673 - Misc cleanups in PanZoomController. r=pcwalton - Remove unused imports. - Move all class variables together, and make some final. - Fix up some comments. - Remove unused methods. - Remove some dead code - Move some functions around so they are grouped based on behaviour.
mobile/android/base/ui/PanZoomController.java
--- a/mobile/android/base/ui/PanZoomController.java
+++ b/mobile/android/base/ui/PanZoomController.java
@@ -49,35 +49,31 @@ import org.mozilla.gecko.GeckoAppShell;
 import org.mozilla.gecko.GeckoEvent;
 import org.mozilla.gecko.GeckoEventListener;
 import android.graphics.PointF;
 import android.graphics.RectF;
 import android.util.Log;
 import android.view.GestureDetector;
 import android.view.MotionEvent;
 import android.view.ScaleGestureDetector;
-import java.lang.Math;
-import java.util.Date;
 import java.util.Timer;
 import java.util.TimerTask;
 
 /*
  * Handles the kinetic scrolling and zooming physics for a layer controller.
  *
  * Many ideas are from Joe Hewitt's Scrollability:
  *   https://github.com/joehewitt/scrollability/
  */
 public class PanZoomController
     extends GestureDetector.SimpleOnGestureListener
     implements ScaleGestureDetector.OnScaleGestureListener, GeckoEventListener
 {
     private static final String LOGTAG = "GeckoPanZoomController";
 
-    private LayerController mController;
-
     // This fraction of velocity remains after every animation frame when the velocity is low.
     private static final float FRICTION_SLOW = 0.85f;
     // This fraction of velocity remains after every animation frame when the velocity is high.
     private static final float FRICTION_FAST = 0.97f;
     // Below this velocity (in pixels per frame), the friction starts increasing from FRICTION_FAST
     // to FRICTION_SLOW.
     private static final float VELOCITY_THRESHOLD = 10.0f;
     // Animation stops if the velocity is below this value when overscrolled or panning.
@@ -117,51 +113,52 @@ public class PanZoomController
         0.80794f,   /* 10 */
         0.86069f,   /* 11 */
         0.90651f,   /* 12 */
         0.94471f,   /* 13 */
         0.97401f,   /* 14 */
         0.99309f,   /* 15 */
     };
 
-    /* The timer that handles flings or bounces. */
-    private Timer mAnimationTimer;
-    /* The runnable being scheduled by the animation timer. */
-    private AnimationRunnable mAnimationRunnable;
-    /* Information about the X axis. */
-    private AxisX mX;
-    /* Information about the Y axis. */
-    private AxisY mY;
-    /* The zoom focus at the first zoom event (in page coordinates). */
-    private PointF mLastZoomFocus;
-    /* The time the last motion event took place. */
-    private long mLastEventTime;
-
     private enum PanZoomState {
         NOTHING,        /* no touch-start events received */
         FLING,          /* all touches removed, but we're still scrolling page */
         TOUCHING,       /* one touch-start event received */
         PANNING_LOCKED, /* touch-start followed by move (i.e. panning with axis lock) */
         PANNING,        /* panning without axis lock */
         PANNING_HOLD,   /* in panning, but not moving.
                          * similar to TOUCHING but after starting a pan */
         PANNING_HOLD_LOCKED, /* like PANNING_HOLD, but axis lock still in effect */
         PINCHING,       /* nth touch-start, where n > 1. this mode allows pan and zoom */
         ANIMATED_ZOOM   /* animated zoom to a new rect */
     }
 
+    private final LayerController mController;
+    private final Axis mX;
+    private final Axis mY;
+
+    /* The timer that handles flings or bounces. */
+    private Timer mAnimationTimer;
+    /* The runnable being scheduled by the animation timer. */
+    private AnimationRunnable mAnimationRunnable;
+    /* The zoom focus at the first zoom event (in page coordinates). */
+    private PointF mLastZoomFocus;
+    /* The time the last motion event took place. */
+    private long mLastEventTime;
+    /* Current state the pan/zoom UI is in. */
     private PanZoomState mState;
 
     private boolean mOverridePanning;
     private boolean mOverrideScrollAck;
     private boolean mOverrideScrollPending;
 
     public PanZoomController(LayerController controller) {
         mController = controller;
-        mX = new AxisX(); mY = new AxisY();
+        mX = new AxisX();
+        mY = new AxisY();
         mState = PanZoomState.NOTHING;
 
         GeckoAppShell.registerGeckoEventListener("Browser:ZoomToRect", this);
         GeckoAppShell.registerGeckoEventListener("Browser:ZoomToPageWidth", this);
         GeckoAppShell.registerGeckoEventListener("Panning:Override", this);
         GeckoAppShell.registerGeckoEventListener("Panning:CancelOverride", this);
         GeckoAppShell.registerGeckoEventListener("Gesture:ScrollAck", this);
     }
@@ -178,48 +175,44 @@ public class PanZoomController
                 mController.post(new Runnable() {
                     public void run() {
                         mOverrideScrollAck = true;
                         if (mOverridePanning && mOverrideScrollPending)
                             updatePosition();
                     }
                 });
             } else if (event.equals("Browser:ZoomToRect")) {
-                if (mController != null) {
-                    float scale = mController.getZoomFactor();
-                    float x = (float)message.getDouble("x");
-                    float y = (float)message.getDouble("y");
-                    final RectF zoomRect = new RectF(x, y,
-                                         x + (float)message.getDouble("w"),
-                                         y + (float)message.getDouble("h"));
-                    mController.post(new Runnable() {
-                        public void run() {
-                            animatedZoomTo(zoomRect);
-                        }
-                    });
-                }
+                float scale = mController.getZoomFactor();
+                float x = (float)message.getDouble("x");
+                float y = (float)message.getDouble("y");
+                final RectF zoomRect = new RectF(x, y,
+                                     x + (float)message.getDouble("w"),
+                                     y + (float)message.getDouble("h"));
+                mController.post(new Runnable() {
+                    public void run() {
+                        animatedZoomTo(zoomRect);
+                    }
+                });
             } else if (event.equals("Browser:ZoomToPageWidth")) {
-                if (mController != null) {
-                    float scale = mController.getZoomFactor();
-                    FloatSize pageSize = mController.getPageSize();
+                float scale = mController.getZoomFactor();
+                FloatSize pageSize = mController.getPageSize();
 
-                    RectF viewableRect = mController.getViewport();
-                    float y = viewableRect.top;
-                    // attempt to keep zoom keep focused on the center of the viewport
-                    float dh = viewableRect.height()*(1 - pageSize.width/viewableRect.width()); // increase in the height
-                    final RectF r = new RectF(0.0f,
-                                        y + dh/2,
-                                        pageSize.width,
-                                        (y + pageSize.width * viewableRect.height()/viewableRect.width()));
-                    mController.post(new Runnable() {
-                        public void run() {
-                            animatedZoomTo(r);
-                        }
-                    });
-                }
+                RectF viewableRect = mController.getViewport();
+                float y = viewableRect.top;
+                // attempt to keep zoom keep focused on the center of the viewport
+                float dh = viewableRect.height()*(1 - pageSize.width/viewableRect.width()); // increase in the height
+                final RectF r = new RectF(0.0f,
+                                    y + dh/2,
+                                    pageSize.width,
+                                    (y + pageSize.width * viewableRect.height()/viewableRect.width()));
+                mController.post(new Runnable() {
+                    public void run() {
+                        animatedZoomTo(r);
+                    }
+                });
             }
         } catch (Exception e) {
             Log.e(LOGTAG, "Exception handling message \"" + event + "\":", e);
         }
     }
 
     public boolean onTouchEvent(MotionEvent event) {
         switch (event.getAction() & event.ACTION_MASK) {
@@ -240,18 +233,18 @@ public class PanZoomController
         // anything special.
         switch (mState) {
         case FLING:
             mX.velocity = mY.velocity = 0.0f;
             mState = PanZoomState.NOTHING;
             // fall through
         case ANIMATED_ZOOM:
             // the zoom that's in progress likely makes no sense any more (such as if
-            // the screen orientation changed) so abort it and start a new one to
-            // ensure the viewport doesn't contain out-of-bounds areas
+            // the screen orientation changed) so abort it
+            // fall through
         case NOTHING:
             // Don't do animations here; they're distracting and can cause flashes on page
             // transitions.
             mController.setViewportMetrics(getValidViewportMetrics());
             mController.notifyLayerClientOfGeometryChange();
             break;
         }
     }
@@ -469,19 +462,16 @@ public class PanZoomController
         }
 
         mX.setFlingState(Axis.FlingStates.PANNING); mY.setFlingState(Axis.FlingStates.PANNING);
         mX.displace(mOverridePanning); mY.displace(mOverridePanning);
         updatePosition();
     }
 
     private void fling() {
-        if (mState != PanZoomState.FLING)
-            mX.velocity = mY.velocity = 0.0f;
-
         mX.disableSnap = mY.disableSnap = mOverridePanning;
 
         mX.displace(mOverridePanning); mY.displace(mOverridePanning);
         updatePosition();
 
         stopAnimationTimer();
 
         boolean stopped = stopped();
@@ -716,20 +706,16 @@ public class PanZoomController
         Log.d(LOGTAG, "Finishing animation at " + mController.getViewportMetrics());
         stopAnimationTimer();
 
         // Force a viewport synchronisation
         mController.setForceRedraw();
         mController.notifyLayerClientOfGeometryChange();
     }
 
-    private float computeElasticity(float excess, float viewportLength) {
-        return 1.0f - excess / (viewportLength * SNAP_LIMIT);
-    }
-
     // Physics information for one axis (X or Y).
     private abstract static class Axis {
         public enum FlingStates {
             STOPPED,
             PANNING,
             FLINGING,
             WAITING_TO_SNAP,
             SNAPPING,
@@ -924,16 +910,32 @@ public class PanZoomController
         @Override
         protected float getPageLength() { return mController.getPageSize().height; }
     }
 
     /*
      * Zooming
      */
     @Override
+    public boolean onScaleBegin(ScaleGestureDetector detector) {
+        Log.d(LOGTAG, "onScaleBegin in " + mState);
+
+        if (mState == PanZoomState.ANIMATED_ZOOM)
+            return false;
+
+        mState = PanZoomState.PINCHING;
+        mLastZoomFocus = new PointF(detector.getFocusX(), detector.getFocusY());
+        GeckoApp.mAppContext.hidePluginViews();
+        GeckoApp.mAppContext.mAutoCompletePopup.hide();
+        cancelTouch();
+
+        return true;
+    }
+
+    @Override
     public boolean onScale(ScaleGestureDetector detector) {
         Log.d(LOGTAG, "onScale in state " + mState);
 
         if (mState == PanZoomState.ANIMATED_ZOOM)
             return false;
 
         float prevSpan = detector.getPreviousSpan();
         if (FloatUtils.fuzzyEquals(prevSpan, 0.0f)) {
@@ -971,32 +973,16 @@ public class PanZoomController
         }
 
         mLastZoomFocus.set(detector.getFocusX(), detector.getFocusY());
 
         return true;
     }
 
     @Override
-    public boolean onScaleBegin(ScaleGestureDetector detector) {
-        Log.d(LOGTAG, "onScaleBegin in " + mState);
-
-        if (mState == PanZoomState.ANIMATED_ZOOM)
-            return false;
-
-        mState = PanZoomState.PINCHING;
-        mLastZoomFocus = new PointF(detector.getFocusX(), detector.getFocusY());
-        GeckoApp.mAppContext.hidePluginViews();
-        GeckoApp.mAppContext.mAutoCompletePopup.hide();
-        cancelTouch();
-
-        return true;
-    }
-
-    @Override
     public void onScaleEnd(ScaleGestureDetector detector) {
         Log.d(LOGTAG, "onScaleEnd in " + mState);
 
         if (mState == PanZoomState.ANIMATED_ZOOM)
             return;
 
         mState = PanZoomState.PANNING_HOLD_LOCKED;
         mX.firstTouchPos = mX.lastTouchPos = mX.touchPos = detector.getFocusX();
@@ -1008,16 +994,20 @@ public class PanZoomController
         GeckoApp.mAppContext.showPluginViews();
 
         mState = PanZoomState.TOUCHING;
         mX.velocity = mY.velocity = 0.0f;
         mX.locked = mY.locked = false;
         mLastEventTime = detector.getEventTime();
     }
 
+    public boolean getRedrawHint() {
+        return (mState == PanZoomState.NOTHING || mState == PanZoomState.FLING);
+    }
+
     private void sendPointToGecko(String event, MotionEvent motionEvent) {
         String json;
         try {
             PointF point = new PointF(motionEvent.getX(), motionEvent.getY());
             point = mController.convertViewPointToLayerPoint(point);
             if (point == null) {
                 return;
             }
@@ -1030,44 +1020,40 @@ public class PanZoomController
         GeckoAppShell.sendEventToGecko(new GeckoEvent(event, json));
     }
 
     @Override
     public void onLongPress(MotionEvent motionEvent) {
         sendPointToGecko("Gesture:LongPress", motionEvent);
     }
 
-    public boolean getRedrawHint() {
-        return (mState == PanZoomState.NOTHING || mState == PanZoomState.FLING);
-    }
-
     @Override
     public boolean onDown(MotionEvent motionEvent) {
         sendPointToGecko("Gesture:ShowPress", motionEvent);
         return false;
     }
 
     @Override
     public boolean onSingleTapConfirmed(MotionEvent motionEvent) {
         GeckoApp.mAppContext.mAutoCompletePopup.hide();
         sendPointToGecko("Gesture:SingleTap", motionEvent);
         return true;
     }
 
-    private void cancelTouch() {
-        GeckoEvent e = new GeckoEvent("Gesture:CancelTouch", "");
-        GeckoAppShell.sendEventToGecko(e);
-    }
-
     @Override
     public boolean onDoubleTap(MotionEvent motionEvent) {
         sendPointToGecko("Gesture:DoubleTap", motionEvent);
         return true;
     }
 
+    private void cancelTouch() {
+        GeckoEvent e = new GeckoEvent("Gesture:CancelTouch", "");
+        GeckoAppShell.sendEventToGecko(e);
+    }
+
     private boolean animatedZoomTo(RectF zoomToRect) {
         GeckoApp.mAppContext.hidePluginViews();
         GeckoApp.mAppContext.mAutoCompletePopup.hide();
 
         mState = PanZoomState.ANIMATED_ZOOM;
         final float startZoom = mController.getZoomFactor();
         final PointF startPoint = mController.getOrigin();