summaryrefslogtreecommitdiff
path: root/android
diff options
context:
space:
mode:
authorTomaž Vajngerl <tomaz.vajngerl@collabora.com>2014-11-30 17:18:56 +0100
committerTomaž Vajngerl <tomaz.vajngerl@collabora.com>2014-12-04 23:04:29 +0100
commit86aadc8276a69079ee45a128a713f91ae544e02e (patch)
tree967c8537bf0dac1fb846d3015d5181563ca56fef /android
parenta9c434a284ee9a6a2dda17d0644e6f8972f568b7 (diff)
android: Fennec PanZoomControler updates..
Change-Id: I277fbf522b16d9b479260df8372a5ee160adcc37
Diffstat (limited to 'android')
-rw-r--r--android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java2
-rw-r--r--android/experimental/LOAndroid3/src/java/org/mozilla/gecko/OnInterceptTouchListener.java14
-rw-r--r--android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/GeckoLayerClient.java2
-rw-r--r--android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/TouchEventHandler.java33
-rw-r--r--android/experimental/LOAndroid3/src/java/org/mozilla/gecko/ui/PanZoomController.java38
-rw-r--r--android/experimental/LOAndroid3/src/java/org/mozilla/gecko/ui/PanZoomTarget.java3
-rw-r--r--android/experimental/LOAndroid3/src/java/org/mozilla/gecko/ui/SimpleScaleGestureDetector.java28
7 files changed, 98 insertions, 22 deletions
diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java
index c6af5e724833..30a8bc965979 100644
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java
@@ -55,7 +55,7 @@ public class LOKitThread extends Thread {
mLayerClient.setPageRect(0, 0, mTileProvider.getPageWidth(), mTileProvider.getPageHeight());
mLayerClient.setViewportMetrics(mLayerClient.getViewportMetrics());
- mLayerClient.setForceRedraw();
+ mLayerClient.forceRedraw();
}
/** Invalidate everything + handle the geometry change + draw. */
diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/OnInterceptTouchListener.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/OnInterceptTouchListener.java
new file mode 100644
index 000000000000..d0cd3d48a943
--- /dev/null
+++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/OnInterceptTouchListener.java
@@ -0,0 +1,14 @@
+/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package org.mozilla.gecko;
+
+import android.view.MotionEvent;
+import android.view.View;
+
+public interface OnInterceptTouchListener extends View.OnTouchListener {
+ /** Override this method for a chance to consume events before the view or its children */
+ public boolean onInterceptTouchEvent(View view, MotionEvent event);
+}
diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/GeckoLayerClient.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/GeckoLayerClient.java
index 7efed043e3b0..aa47aaac93fa 100644
--- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/GeckoLayerClient.java
+++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/GeckoLayerClient.java
@@ -400,7 +400,7 @@ public class GeckoLayerClient implements PanZoomTarget, LayerView.Listener {
}
/** Implementation of PanZoomTarget */
- public void setForceRedraw() {
+ public void forceRedraw() {
mForceRedraw = true;
if (mGeckoIsReady) {
geometryChanged();
diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/TouchEventHandler.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/TouchEventHandler.java
index f0fe21baf0c4..a17e63c93478 100644
--- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/TouchEventHandler.java
+++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/TouchEventHandler.java
@@ -6,12 +6,13 @@
package org.mozilla.gecko.gfx;
import android.content.Context;
+import android.os.Build;
import android.os.SystemClock;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
-import android.view.View.OnTouchListener;
+import org.mozilla.gecko.OnInterceptTouchListener;
import org.mozilla.gecko.ui.PanZoomController;
import org.mozilla.gecko.ui.SimpleScaleGestureDetector;
@@ -66,7 +67,7 @@ public final class TouchEventHandler {
private final ListenerTimeoutProcessor mListenerTimeoutProcessor;
// the listener we use to notify gecko of touch events
- private OnTouchListener mOnTouchListener;
+ private OnInterceptTouchListener mOnTouchListener;
// whether or not we should wait for touch listeners to respond (this state is
// per-tab and is updated when we switch tabs).
@@ -127,13 +128,16 @@ public final class TouchEventHandler {
mView = view;
mEventQueue = new LinkedList<MotionEvent>();
- mGestureDetector = new GestureDetector(context, layerClient.getGestureListener());
- mScaleGestureDetector = new SimpleScaleGestureDetector(layerClient.getScaleGestureListener());
mPanZoomController = layerClient.getPanZoomController();
+ mGestureDetector = new GestureDetector(context, mPanZoomController);
+ mScaleGestureDetector = new SimpleScaleGestureDetector(mPanZoomController);
mListenerTimeoutProcessor = new ListenerTimeoutProcessor();
mDispatchEvents = true;
- mGestureDetector.setOnDoubleTapListener(layerClient.getDoubleTapListener());
+ mGestureDetector.setOnDoubleTapListener(mPanZoomController);
+ }
+
+ void destroy() {
}
/* This function MUST be called on the UI thread */
@@ -145,12 +149,21 @@ public final class TouchEventHandler {
return true;
}
+ if (mOnTouchListener.onInterceptTouchEvent(mView, event)) {
+ return true;
+ }
+
// if this is a hover event just notify gecko, we don't have any interest in the java layer.
if (isHoverEvent(event)) {
mOnTouchListener.onTouch(mView, event);
return true;
}
+ if (isScrollEvent(event)) {
+ dispatchEvent(event);
+ return true;
+ }
+
if (isDownEvent(event)) {
// this is the start of a new block of events! whee!
mHoldInQueue = mWaitForTouchListeners;
@@ -225,7 +238,7 @@ public final class TouchEventHandler {
}
/* This function MUST be called on the UI thread. */
- public void setOnTouchListener(OnTouchListener onTouchListener) {
+ public void setOnTouchListener(OnInterceptTouchListener onTouchListener) {
mOnTouchListener = onTouchListener;
}
@@ -244,6 +257,14 @@ public final class TouchEventHandler {
return (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL);
}
+ private boolean isScrollEvent(MotionEvent event) {
+ if (Build.VERSION.SDK_INT <= 11) {
+ return false;
+ }
+ int action = (event.getAction() & MotionEvent.ACTION_MASK);
+ return (action == MotionEvent.ACTION_SCROLL);
+ }
+
/**
* Dispatch the event to the gesture detectors and the pan/zoom controller.
*/
diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/ui/PanZoomController.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/ui/PanZoomController.java
index 555c7ebe60fa..65daf76a484f 100644
--- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/ui/PanZoomController.java
+++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/ui/PanZoomController.java
@@ -50,6 +50,9 @@ public class PanZoomController
// The maximum amount we allow you to zoom into a page
private static final float MAX_ZOOM = 4.0f;
+ // The maximum amount we would like to scroll with the mouse
+ private static final float MAX_SCROLL = 0.075f * LOKitShell.getDpi();
+
private enum PanZoomState {
NOTHING, /* no touch-start events received */
FLING, /* all touches removed, but we're still scrolling page */
@@ -110,7 +113,9 @@ public class PanZoomController
}
private void setState(PanZoomState state) {
- mState = state;
+ if (state != mState) {
+ mState = state;
+ }
}
private ImmutableViewportMetrics getMetrics() {
@@ -131,6 +136,7 @@ public class PanZoomController
case MotionEvent.ACTION_MOVE: return onTouchMove(event);
case MotionEvent.ACTION_UP: return onTouchEnd(event);
case MotionEvent.ACTION_CANCEL: return onTouchCancel(event);
+ case MotionEvent.ACTION_SCROLL: return onScroll(event);
default: return false;
}
}
@@ -158,6 +164,7 @@ public class PanZoomController
// transitions.
synchronized (mTarget.getLock()) {
mTarget.setViewportMetrics(getValidViewportMetrics());
+ mTarget.forceRedraw();
}
break;
}
@@ -214,7 +221,7 @@ public class PanZoomController
// We just interrupted a double-tap animation, so force a redraw in
// case this touchstart is just a tap that doesn't end up triggering
// a redraw
- mTarget.setForceRedraw();
+ mTarget.forceRedraw();
// fall through
case FLING:
case BOUNCE:
@@ -337,6 +344,18 @@ public class PanZoomController
return false;
}
+ private boolean onScroll(MotionEvent event) {
+ if (mState == PanZoomState.NOTHING || mState == PanZoomState.FLING) {
+ float scrollX = event.getAxisValue(MotionEvent.AXIS_HSCROLL);
+ float scrollY = event.getAxisValue(MotionEvent.AXIS_VSCROLL);
+
+ scrollBy(scrollX * MAX_SCROLL, scrollY * MAX_SCROLL);
+ bounce();
+ return true;
+ }
+ return false;
+ }
+
private void startTouch(float x, float y, long time) {
mX.startTouch(x);
mY.startTouch(y);
@@ -434,7 +453,7 @@ public class PanZoomController
}
/* Performs a bounce-back animation to the given viewport metrics. */
- private void bounce(ImmutableViewportMetrics metrics) {
+ private void bounce(ImmutableViewportMetrics metrics, PanZoomState state) {
stopAnimationTimer();
ImmutableViewportMetrics bounceStartMetrics = getMetrics();
@@ -443,6 +462,8 @@ public class PanZoomController
return;
}
+ setState(state);
+
// At this point we have already set mState to BOUNCE or ANIMATED_ZOOM, so
// getRedrawHint() is returning false. This means we can safely call
// setAnimationTarget to set the new final display port and not have it get
@@ -453,8 +474,7 @@ public class PanZoomController
/* Performs a bounce-back animation to the nearest valid viewport metrics. */
private void bounce() {
- setState(PanZoomState.BOUNCE);
- bounce(getValidViewportMetrics());
+ bounce(getValidViewportMetrics(), PanZoomState.BOUNCE);
}
/* Starts the fling or bounce animation. */
@@ -654,7 +674,7 @@ public class PanZoomController
stopAnimationTimer();
// Force a viewport synchronisation
- mTarget.setForceRedraw();
+ mTarget.forceRedraw();
}
/* Returns the nearest viewport metrics with no overscroll visible. */
@@ -837,7 +857,8 @@ public class PanZoomController
startTouch(detector.getFocusX(), detector.getFocusY(), detector.getEventTime());
// Force a viewport synchronisation
- mTarget.setForceRedraw();
+ mTarget.forceRedraw();
+
}
/**
@@ -896,7 +917,6 @@ public class PanZoomController
* pixels.
*/
private boolean animatedZoomTo(RectF zoomToRect) {
- setState(PanZoomState.ANIMATED_ZOOM);
final float startZoom = getMetrics().zoomFactor;
RectF viewport = getMetrics().getViewport();
@@ -932,7 +952,7 @@ public class PanZoomController
// clamped down to prevent overscroll, over-zoom, and other bad conditions.
finalMetrics = getValidViewportMetrics(finalMetrics);
- bounce(finalMetrics);
+ bounce(finalMetrics, PanZoomState.ANIMATED_ZOOM);
return true;
}
diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/ui/PanZoomTarget.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/ui/PanZoomTarget.java
index fdac874ee6f9..b4eeb52a7dd7 100644
--- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/ui/PanZoomTarget.java
+++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/ui/PanZoomTarget.java
@@ -16,7 +16,8 @@ public interface PanZoomTarget {
public void setAnimationTarget(ImmutableViewportMetrics viewport);
public void setViewportMetrics(ImmutableViewportMetrics viewport);
- public void setForceRedraw();
+ /** This triggers an (asynchronous) viewport update/redraw. */
+ public void forceRedraw();
public boolean post(Runnable action);
public Object getLock();
diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/ui/SimpleScaleGestureDetector.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/ui/SimpleScaleGestureDetector.java
index 6f920cafb218..faafad04bfb9 100644
--- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/ui/SimpleScaleGestureDetector.java
+++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/ui/SimpleScaleGestureDetector.java
@@ -39,6 +39,7 @@ public class SimpleScaleGestureDetector {
private SimpleScaleGestureListener mListener;
private long mLastEventTime;
+ private boolean mScaleResult;
/* Information about all pointers that are down. */
private LinkedList<PointerInfo> mPointerInfo;
@@ -53,6 +54,12 @@ public class SimpleScaleGestureDetector {
public void onTouchEvent(MotionEvent event) {
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
+ // If we get ACTION_DOWN while still tracking any pointers,
+ // something is wrong. Cancel the current gesture and start over.
+ if (getPointersDown() > 0)
+ onTouchEnd(event);
+ onTouchStart(event);
+ break;
case MotionEvent.ACTION_POINTER_DOWN:
onTouchStart(event);
break;
@@ -101,7 +108,10 @@ public class SimpleScaleGestureDetector {
private void onTouchEnd(MotionEvent event) {
mLastEventTime = event.getEventTime();
- boolean isCancel = (event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_CANCEL;
+ int action = event.getAction() & MotionEvent.ACTION_MASK;
+ boolean isCancel = (action == MotionEvent.ACTION_CANCEL ||
+ action == MotionEvent.ACTION_DOWN);
+
int id = event.getPointerId(getActionIndex(event));
ListIterator<PointerInfo> iterator = mPointerInfo.listIterator();
while (iterator.hasNext()) {
@@ -196,9 +206,19 @@ public class SimpleScaleGestureDetector {
/* Sends the requested scale gesture notification to the listener. */
private void sendScaleGesture(EventType eventType) {
switch (eventType) {
- case BEGIN: mListener.onScaleBegin(this); break;
- case CONTINUE: mListener.onScale(this); break;
- case END: mListener.onScaleEnd(this); break;
+ case BEGIN:
+ mScaleResult = mListener.onScaleBegin(this);
+ break;
+ case CONTINUE:
+ if (mScaleResult) {
+ mListener.onScale(this);
+ }
+ break;
+ case END:
+ if (mScaleResult) {
+ mListener.onScaleEnd(this);
+ }
+ break;
}
}