Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
pinch to zoom
  • Loading branch information
paulrouget committed Aug 16, 2018
1 parent 89ab110 commit 296b760
Show file tree
Hide file tree
Showing 6 changed files with 157 additions and 19 deletions.
18 changes: 18 additions & 0 deletions ports/libsimpleservo/src/api.rs
Expand Up @@ -286,6 +286,24 @@ impl ServoGlue {
self.process_event(event)
}

/// Start pinchzoom.
/// x/y are pinch origin coordinates.
pub fn pinchzoom_start(&mut self, factor: f32, _x: u32, _y: u32) -> Result<(), &'static str> {
self.process_event(WindowEvent::PinchZoom(factor))
}

/// Pinchzoom.
/// x/y are pinch origin coordinates.
pub fn pinchzoom(&mut self, factor: f32, _x: u32, _y: u32) -> Result<(), &'static str> {
self.process_event(WindowEvent::PinchZoom(factor))
}

/// End pinchzoom.
/// x/y are pinch origin coordinates.
pub fn pinchzoom_end(&mut self, factor: f32, _x: u32, _y: u32) -> Result<(), &'static str> {
self.process_event(WindowEvent::PinchZoom(factor))
}

/// Perform a click.
pub fn click(&mut self, x: u32, y: u32) -> Result<(), &'static str> {
let mouse_event =
Expand Down
18 changes: 18 additions & 0 deletions ports/libsimpleservo/src/capi.rs
Expand Up @@ -180,6 +180,24 @@ pub extern "C" fn scroll(dx: i32, dy: i32, x: i32, y: i32) {
call(|s| s.scroll(dx as i32, dy as i32, x as u32, y as u32));
}

#[no_mangle]
pub extern "C" fn pinchzoom_start(factor: f32, x: i32, y: i32) {
debug!("pinchzoom_start");
call(|s| s.pinchzoom_start(factor, x as u32, y as u32));
}

#[no_mangle]
pub extern "C" fn pinchzoom(factor: f32, x: i32, y: i32) {
debug!("pinchzoom");
call(|s| s.pinchzoom(factor, x as u32, y as u32));
}

#[no_mangle]
pub extern "C" fn pinchzoom_end(factor: f32, x: i32, y: i32) {
debug!("pinchzoom_end");
call(|s| s.pinchzoom_end(factor, x as u32, y as u32));
}

#[no_mangle]
pub extern "C" fn click(x: i32, y: i32) {
debug!("click");
Expand Down
39 changes: 38 additions & 1 deletion ports/libsimpleservo/src/jniapi.rs
Expand Up @@ -9,7 +9,7 @@ use api::{self, EventLoopWaker, ServoGlue, SERVO, HostTrait, ReadFileTrait};
use gl_glue;
use jni::{JNIEnv, JavaVM};
use jni::objects::{GlobalRef, JClass, JObject, JString, JValue};
use jni::sys::{jboolean, jint, jstring, JNI_TRUE};
use jni::sys::{jboolean, jfloat, jint, jstring, JNI_TRUE};
use log::Level;
use std;
use std::os::raw::c_void;
Expand Down Expand Up @@ -207,6 +207,43 @@ pub fn Java_com_mozilla_servoview_JNIServo_scroll(
call(env, |s| s.scroll(dx as i32, dy as i32, x as u32, y as u32));
}

#[no_mangle]
pub fn Java_com_mozilla_servoview_JNIServo_pinchZoomStart(
env: JNIEnv,
_: JClass,
factor: jfloat,
x: jint,
y: jint,
) {
debug!("pinchZoomStart");
call(env, |s| s.pinchzoom_start(factor as f32, x as u32, y as u32));
}

#[no_mangle]
pub fn Java_com_mozilla_servoview_JNIServo_pinchZoom(
env: JNIEnv,
_: JClass,
factor: jfloat,
x: jint,
y: jint,
) {
debug!("pinchZoom");
call(env, |s| s.pinchzoom(factor as f32, x as u32, y as u32));
}

#[no_mangle]
pub fn Java_com_mozilla_servoview_JNIServo_pinchZoomEnd(
env: JNIEnv,
_: JClass,
factor: jfloat,
x: jint,
y: jint,
) {
debug!("pinchZoomEnd");
call(env, |s| s.pinchzoom_end(factor as f32, x as u32, y as u32));
}


#[no_mangle]
pub fn Java_com_mozilla_servoview_JNIServo_click(env: JNIEnv, _: JClass, x: jint, y: jint) {
debug!("click");
Expand Down
Expand Up @@ -49,6 +49,12 @@ public native void init(Activity activity,

public native void scrollEnd(int dx, int dy, int x, int y);

public native void pinchZoomStart(float factor, int x, int y);

public native void pinchZoom(float factor, int x, int y);

public native void pinchZoomEnd(float factor, int x, int y);

public native void click(int x, int y);

public interface Callbacks {
Expand Down
Expand Up @@ -86,6 +86,18 @@ public void scrollEnd(int dx, int dy, int x, int y) {
mRunCallback.inGLThread(() -> mJNI.scrollEnd(dx, dy, x, y));
}

public void pinchZoomStart(float factor, int x, int y) {
mRunCallback.inGLThread(() -> mJNI.pinchZoomStart(factor, x, y));
}

public void pinchZoom(float factor, int x, int y) {
mRunCallback.inGLThread(() -> mJNI.pinchZoom(factor, x, y));
}

public void pinchZoomEnd(float factor, int x, int y) {
mRunCallback.inGLThread(() -> mJNI.pinchZoomEnd(factor, x, y));
}

public void click(int x, int y) {
mRunCallback.inGLThread(() -> mJNI.click(x, y));
}
Expand Down
Expand Up @@ -11,9 +11,11 @@
import android.opengl.GLES31;
import android.opengl.GLSurfaceView;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Choreographer;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.widget.OverScroller;

import com.mozilla.servoview.Servo.Client;
Expand All @@ -26,6 +28,7 @@
public class ServoView extends GLSurfaceView
implements
GestureDetector.OnGestureListener,
ScaleGestureDetector.OnScaleGestureListener,
Choreographer.FrameCallback,
GfxCallbacks,
RunCallback {
Expand All @@ -39,12 +42,18 @@ public class ServoView extends GLSurfaceView
private boolean mAnimating;
private String mServoArgs = "";
private GestureDetector mGestureDetector;
private ScaleGestureDetector mScaleGestureDetector;

private OverScroller mScroller;
private int mLastX = 0;
private int mCurX = 0;
private int mLastY = 0;
private int mCurY = 0;
private boolean mFlinging;
private boolean mScrolling;

private boolean mZooming;
private float mZoomFactor = 1;

public ServoView(Context context, AttributeSet attrs) {
super(context, attrs);
Expand Down Expand Up @@ -138,19 +147,18 @@ public void setClient(Client client) {

private void initGestures(Context context) {
mGestureDetector = new GestureDetector(context, this);
mScaleGestureDetector = new ScaleGestureDetector(context, this);
mScroller = new OverScroller(context);
}

public void doFrame(long frameTimeNanos) {

if (mScroller.isFinished() && mFlinging) {
// 3 reasons to be here: animating or scrolling/flinging or pinching

if (mFlinging && mScroller.isFinished()) {
mFlinging = false;
inGLThread(() -> mServo.scrollEnd(0, 0, mCurX, mCurY));
if (!mAnimating) {
// Not scrolling. Not animating. We don't need to schedule
// another frame.
return;
}
mScrolling = false;
mServo.scrollEnd(0, 0, mCurX, mCurY);
}

if (mFlinging) {
Expand All @@ -165,15 +173,25 @@ public void doFrame(long frameTimeNanos) {
mLastX = mCurX;
mLastY = mCurY;

if (dx != 0 || dy != 0) {
inGLThread(() -> mServo.scroll(dx, dy, mCurX, mCurY));
} else {
if (mAnimating) {
requestRender();
}
boolean scrollNecessary = mScrolling && (dx != 0 || dy != 0);
boolean zoomNecessary = mZooming && mZoomFactor != 1;

if (scrollNecessary) {
mServo.scroll(dx, dy, mCurX, mCurY);
}

if (zoomNecessary) {
mServo.pinchZoom(mZoomFactor, 0, 0);
mZoomFactor = 1;
}

if (!zoomNecessary && !scrollNecessary && mAnimating) {
requestRender();
}

Choreographer.getInstance().postFrameCallback(this);
if (mZooming || mScrolling || mAnimating) {
Choreographer.getInstance().postFrameCallback(this);
}
}

public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
Expand All @@ -198,6 +216,7 @@ public boolean onDown(MotionEvent e) {

public boolean onTouchEvent(final MotionEvent e) {
mGestureDetector.onTouchEvent(e);
mScaleGestureDetector.onTouchEvent(e);

int action = e.getActionMasked();
switch (action) {
Expand All @@ -207,7 +226,8 @@ public boolean onTouchEvent(final MotionEvent e) {
mCurY = (int) e.getY();
mLastY = mCurY;
mScroller.forceFinished(true);
inGLThread(() -> mServo.scrollStart(0, 0, mCurX, mCurY));
mServo.scrollStart(0, 0, mCurX, mCurY);
mScrolling = true;
Choreographer.getInstance().postFrameCallback(this);
return true;
case (MotionEvent.ACTION_MOVE):
Expand All @@ -217,8 +237,8 @@ public boolean onTouchEvent(final MotionEvent e) {
case (MotionEvent.ACTION_UP):
case (MotionEvent.ACTION_CANCEL):
if (!mFlinging) {
inGLThread(() -> mServo.scrollEnd(0, 0, mCurX, mCurY));
Choreographer.getInstance().removeFrameCallback(this);
mScrolling = false;
mServo.scrollEnd(0, 0, mCurX, mCurY);
}
return true;
default:
Expand All @@ -227,7 +247,7 @@ public boolean onTouchEvent(final MotionEvent e) {
}

public boolean onSingleTapUp(MotionEvent e) {
inGLThread(() -> mServo.click((int) e.getX(), (int) e.getY()));
mServo.click((int) e.getX(), (int) e.getY());
return false;
}

Expand All @@ -241,6 +261,33 @@ public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float d
public void onShowPress(MotionEvent e) {
}

@Override
public boolean onScaleBegin(ScaleGestureDetector detector) {
if (mScroller.isFinished()) {
mZoomFactor = detector.getScaleFactor();
mZooming = true;
mServo.pinchZoomStart(mZoomFactor, 0, 0);
Choreographer.getInstance().postFrameCallback(this);
return true;
} else {
return false;
}
}

@Override
public boolean onScale(ScaleGestureDetector detector) {
mZoomFactor *= detector.getScaleFactor();
return true;
}

@Override
public void onScaleEnd(ScaleGestureDetector detector) {
mZoomFactor = detector.getScaleFactor();
mZooming = false;
mServo.pinchZoomEnd(mZoomFactor, 0, 0);
}


@Override
public void onPause() {
super.onPause();
Expand Down

0 comments on commit 296b760

Please sign in to comment.