Kaydet (Commit) 2c15cb70 authored tarafından Tomaž Vajngerl's avatar Tomaž Vajngerl

android: extract touch handling into TouchEventHandler

Change-Id: I138f746940bf89349d4662c95427113bff221231
üst b0a1d430
......@@ -35,11 +35,11 @@ public final class DisplayPortMetrics {
public String toJSON() {
StringBuffer sb = new StringBuffer(256);
sb.append("{ \"left\": ").append(mPosition.left)
.append(", \"top\": ").append(mPosition.top)
.append(", \"right\": ").append(mPosition.right)
.append(", \"bottom\": ").append(mPosition.bottom)
.append(", \"resolution\": ").append(mResolution)
.append('}');
.append(", \"top\": ").append(mPosition.top)
.append(", \"right\": ").append(mPosition.right)
.append(", \"bottom\": ").append(mPosition.bottom)
.append(", \"resolution\": ").append(mResolution)
.append('}');
return sb.toString();
}
......
......@@ -212,7 +212,7 @@ public class GeckoLayerClient {
mLayerController.getView().postDelayed(new AdjustRunnable(), MIN_VIEWPORT_CHANGE_DELAY - timeDelta);
mPendingViewportAdjust = true;
} else {
adjustViewport();
adjustViewport(null);
}
}
......@@ -220,15 +220,21 @@ public class GeckoLayerClient {
mViewportSizeChanged = true;
}
private void adjustViewport() {
ViewportMetrics viewportMetrics =
new ViewportMetrics(mLayerController.getViewportMetrics());
void adjustViewport(DisplayPortMetrics displayPort) {
ImmutableViewportMetrics metrics = mLayerController.getViewportMetrics();
viewportMetrics.setViewport(viewportMetrics.getClampedViewport());
ViewportMetrics clampedMetrics = new ViewportMetrics(metrics);
clampedMetrics.setViewport(clampedMetrics.getClampedViewport());
mDisplayPort = DisplayPortCalculator.calculate(mLayerController.getViewportMetrics());
if (displayPort == null) {
displayPort = DisplayPortCalculator.calculate(metrics,
mLayerController.getPanZoomController().getVelocityVector());
}
mDisplayPort = displayPort;
mGeckoViewport = clampedMetrics;
LOKitShell.sendEvent(LOEvent.viewport(viewportMetrics));
LOKitShell.sendEvent(LOEvent.viewport(clampedMetrics));
if (mViewportSizeChanged) {
mViewportSizeChanged = false;
LOKitShell.viewSizeChanged();
......@@ -240,7 +246,7 @@ public class GeckoLayerClient {
public void geometryChanged() {
sendResizeEventIfNecessary(false);
if (mLayerController.getRedrawHint())
adjustViewport();
adjustViewport(null);
}
public ViewportMetrics getGeckoViewportMetrics() {
......@@ -267,7 +273,7 @@ public class GeckoLayerClient {
private class AdjustRunnable implements Runnable {
public void run() {
mPendingViewportAdjust = false;
adjustViewport();
adjustViewport(null);
}
}
}
\ No newline at end of file
......@@ -44,7 +44,6 @@ import android.graphics.Bitmap;
import android.graphics.PixelFormat;
import android.opengl.GLSurfaceView;
import android.util.Log;
import android.view.GestureDetector;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
......@@ -53,10 +52,8 @@ import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import org.libreoffice.LibreOfficeMainActivity;
import org.mozilla.gecko.ui.SimpleScaleGestureDetector;
import java.nio.IntBuffer;
import java.util.LinkedList;
/**
* A view rendered by the layer compositor.
......@@ -67,18 +64,16 @@ import java.util.LinkedList;
* Note that LayerView is accessed by Robocop via reflection.
*/
public class LayerView extends SurfaceView implements SurfaceHolder.Callback {
private static String LOGTAG = "GeckoLayerView";
private Context mContext;
private LayerController mController;
private TouchEventHandler mTouchEventHandler;
private GLController mGLController;
private InputConnectionHandler mInputConnectionHandler;
private LayerRenderer mRenderer;
private GestureDetector mGestureDetector;
private SimpleScaleGestureDetector mScaleGestureDetector;
private long mRenderTime;
private boolean mRenderTimeReset;
private static String LOGTAG = "GeckoLayerView";
/* List of events to be processed if the page does not prevent them. Should only be touched on the main thread */
private LinkedList<MotionEvent> mEventQueue = new LinkedList<MotionEvent>();
/* Must be a PAINT_xxx constant */
private int mPaintState = PAINT_NONE;
......@@ -101,11 +96,8 @@ public class LayerView extends SurfaceView implements SurfaceHolder.Callback {
mGLController = new GLController(this);
mContext = context;
mController = controller;
mTouchEventHandler = new TouchEventHandler(context, this, mController);
mRenderer = new LayerRenderer(this);
mGestureDetector = new GestureDetector(context, controller.getGestureListener());
mScaleGestureDetector =
new SimpleScaleGestureDetector(controller.getScaleGestureListener());
mGestureDetector.setOnDoubleTapListener(controller.getDoubleTapListener());
mInputConnectionHandler = null;
setFocusable(true);
......@@ -114,43 +106,13 @@ public class LayerView extends SurfaceView implements SurfaceHolder.Callback {
createGLThread();
}
private void addToEventQueue(MotionEvent event) {
MotionEvent copy = MotionEvent.obtain(event);
mEventQueue.add(copy);
}
public void processEventQueue() {
MotionEvent event = mEventQueue.poll();
while(event != null) {
processEvent(event);
event = mEventQueue.poll();
}
}
public void clearEventQueue() {
mEventQueue.clear();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (mController.onTouchEvent(event)) {
addToEventQueue(event);
return true;
}
return processEvent(event);
}
private boolean processEvent(MotionEvent event) {
if (mGestureDetector.onTouchEvent(event))
return true;
mScaleGestureDetector.onTouchEvent(event);
if (mScaleGestureDetector.isInProgress())
return true;
mController.getPanZoomController().onTouchEvent(event);
return true;
return mTouchEventHandler.handleEvent(event);
}
public LayerController getController() { return mController; }
public TouchEventHandler getTouchEventHandler() { return mTouchEventHandler; }
/** The LayerRenderer calls this to indicate that the window has changed size. */
public void setViewportSize(IntSize size) {
......@@ -215,11 +177,6 @@ public class LayerView extends SurfaceView implements SurfaceHolder.Callback {
}
}
public void changeCheckerboardBitmap(Bitmap bitmap) {
mRenderer.resetCheckerboard();
mRenderer.setCheckerboardBitmap(bitmap);
}
public void addLayer(Layer layer) {
mRenderer.addLayer(layer);
}
......@@ -390,4 +347,9 @@ public class LayerView extends SurfaceView implements SurfaceHolder.Callback {
super(e);
}
}
public void changeCheckerboardBitmap(Bitmap bitmap) {
mRenderer.resetCheckerboard();
mRenderer.setCheckerboardBitmap(bitmap);
}
}
......@@ -114,7 +114,8 @@ public class PanZoomController
* 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 */
ANIMATED_ZOOM, /* animated zoom to a new rect */
BOUNCE /* in a bounce animation */
}
private final LayerController mController;
......@@ -172,22 +173,39 @@ public class PanZoomController
// if that's the case, abort any animation in progress and re-zoom so that the page
// snaps to edges. for other cases (where the user's finger(s) are down) don't do
// anything special.
if (mState == PanZoomState.FLING) {
switch (mState) {
case FLING:
mX.stopFling();
mY.stopFling();
// fall through
case BOUNCE:
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
mState = PanZoomState.NOTHING;
// fall through
case NOTHING:
// Don't do animations here; they're distracting and can cause flashes on page
// transitions.
synchronized (mController) {
mController.setViewportMetrics(getValidViewportMetrics());
mController.notifyLayerClientOfGeometryChange();
}
break;
}
}
/** This must be called on the UI thread. */
public void pageSizeUpdated() {
if (mState == PanZoomState.NOTHING) {
ViewportMetrics validated = getValidViewportMetrics();
if (! (new ViewportMetrics(mController.getViewportMetrics())).fuzzyEquals(validated)) {
// page size changed such that we are now in overscroll. snap to the
// the nearest valid viewport
mController.setViewportMetrics(validated);
mController.notifyLayerClientOfGeometryChange();
synchronized (mController) {
ViewportMetrics validated = getValidViewportMetrics();
if (! (new ViewportMetrics(mController.getViewportMetrics())).fuzzyEquals(validated)) {
// page size changed such that we are now in overscroll. snap to the
// the nearest valid viewport
mController.setViewportMetrics(validated);
mController.notifyLayerClientOfGeometryChange();
}
}
}
}
......@@ -206,6 +224,7 @@ public class PanZoomController
case ANIMATED_ZOOM:
return false;
case FLING:
case BOUNCE:
case NOTHING:
startTouch(event.getX(0), event.getY(0), event.getEventTime());
return false;
......@@ -227,6 +246,7 @@ public class PanZoomController
switch (mState) {
case NOTHING:
case FLING:
case BOUNCE:
// should never happen
Log.e(LOGTAG, "Received impossible touch move while in " + mState);
return false;
......@@ -268,6 +288,7 @@ public class PanZoomController
switch (mState) {
case NOTHING:
case FLING:
case BOUNCE:
// should never happen
Log.e(LOGTAG, "Received impossible touch end while in " + mState);
return false;
......@@ -297,6 +318,7 @@ public class PanZoomController
private boolean onTouchCancel(MotionEvent event) {
mState = PanZoomState.NOTHING;
cancelTouch();
// ensure we snap back if we're overscrolled
bounce();
return false;
......@@ -401,8 +423,11 @@ public class PanZoomController
return;
}
mState = PanZoomState.FLING;
mState = PanZoomState.BOUNCE;
// set the animation target *after* setting state BOUNCE, so that
// the getRedrawHint() is returning false and we don't clobber the display
// port we set as a result of this animation target call.
mController.setAnimationTarget(metrics);
startAnimationTimer(new BounceRunnable(bounceStartMetrics, metrics));
}
......@@ -444,6 +469,10 @@ public class PanZoomController
return FloatMath.sqrt(xvel * xvel + yvel * yvel);
}
public PointF getVelocityVector() {
return new PointF(mX.getRealVelocity(), mY.getRealVelocity());
}
private boolean stopped() {
return getVelocity() < STOPPED_THRESHOLD;
}
......@@ -456,6 +485,9 @@ public class PanZoomController
mX.displace();
mY.displace();
PointF displacement = getDisplacement();
if (FloatUtils.fuzzyEquals(displacement.x, 0.0f) && FloatUtils.fuzzyEquals(displacement.y, 0.0f)) {
return;
}
if (! mSubscroller.scrollBy(displacement)) {
synchronized (mController) {
mController.scrollBy(displacement);
......@@ -510,7 +542,7 @@ public class PanZoomController
* animation by setting the state to PanZoomState.NOTHING. Handle this case and bail
* out.
*/
if (mState != PanZoomState.FLING) {
if (mState != PanZoomState.BOUNCE) {
finishAnimation();
return;
}
......@@ -756,7 +788,18 @@ public class PanZoomController
}
public boolean getRedrawHint() {
return (mState != PanZoomState.PINCHING && mState != PanZoomState.ANIMATED_ZOOM);
switch (mState) {
case PINCHING:
case ANIMATED_ZOOM:
case BOUNCE:
// don't redraw during these because the zoom is (or might be, in the case
// of BOUNCE) be changing rapidly and gecko will have to redraw the entire
// display port area. we trigger a force-redraw upon exiting these states.
return false;
default:
// allow redrawing in other states
return true;
}
}
@Override
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment