Use swipe gesture to switch between slides on Android
authorliyuqian <liyuqian@google.com>
Thu, 12 May 2016 16:17:04 +0000 (09:17 -0700)
committerCommit bot <commit-bot@chromium.org>
Thu, 12 May 2016 16:17:04 +0000 (09:17 -0700)
BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1965013007

Review-Url: https://codereview.chromium.org/1965013007

platform_tools/android/apps/viewer/src/main/java/org/skia/viewer/ViewerActivity.java
tools/viewer/sk_app/Window.h
tools/viewer/sk_app/android/Window_android.cpp
tools/viewer/sk_app/android/Window_android.h
tools/viewer/sk_app/android/surface_glue_android.cpp
tools/viewer/sk_app/android/surface_glue_android.h

index 48cec39..e115de6 100644 (file)
@@ -9,17 +9,50 @@ package org.skia.viewer;
 
 import android.app.Activity;
 import android.os.Bundle;
+import android.util.Log;
+import android.view.GestureDetector;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
 import android.view.Surface;
 import android.view.SurfaceHolder;
 import android.view.SurfaceView;
+import android.view.View;
+
+public class ViewerActivity
+        extends Activity implements SurfaceHolder.Callback, View.OnTouchListener {
+    private static final float FLING_VELOCITY_THRESHOLD = 1000;
 
-public class ViewerActivity extends Activity implements SurfaceHolder.Callback {
     private SurfaceView mView;
     private ViewerApplication mApplication;
+    private GestureDetector mGestureDetector;
 
     private native void onSurfaceCreated(long handle, Surface surface);
     private native void onSurfaceChanged(long handle, Surface surface);
     private native void onSurfaceDestroyed(long handle);
+    private native void onKeyPressed(long handle, int keycode);
+
+    private class GestureListener extends GestureDetector.SimpleOnGestureListener {
+        @Override
+        public boolean onDown(MotionEvent e) {
+            return true;
+        }
+
+        @Override
+        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
+            if (Math.abs(velocityX) > Math.abs(velocityY)
+                && Math.abs(velocityX) > FLING_VELOCITY_THRESHOLD) {
+                if (velocityX > 0) {
+                    // Fling right
+                    onKeyPressed(mApplication.getNativeHandle(), KeyEvent.KEYCODE_SOFT_RIGHT);
+                } else {
+                    // Fling left
+                    onKeyPressed(mApplication.getNativeHandle(), KeyEvent.KEYCODE_SOFT_LEFT);
+                }
+                return true;
+            }
+            return false;
+        }
+    }
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
@@ -29,6 +62,9 @@ public class ViewerActivity extends Activity implements SurfaceHolder.Callback {
         mApplication = (ViewerApplication) getApplication();
         mView = (SurfaceView) findViewById(R.id.surfaceView);
         mView.getHolder().addCallback(this);
+
+        mGestureDetector = new GestureDetector(getApplicationContext(), new GestureListener());
+        mView.setOnTouchListener(this);
     }
 
     @Override
@@ -51,4 +87,9 @@ public class ViewerActivity extends Activity implements SurfaceHolder.Callback {
             onSurfaceDestroyed(mApplication.getNativeHandle());
         }
     }
+
+    @Override
+    public boolean onTouch(View v, MotionEvent event) {
+        return mGestureDetector.onTouchEvent(event);
+    }
 }
index 5a7c9b8..f233f13 100644 (file)
@@ -130,7 +130,7 @@ public:
     uint32_t width() { return fWidth; }
     uint32_t height() { return fHeight;  }
 
-    const DisplayParams& getDisplayParams();
+    virtual const DisplayParams& getDisplayParams();
     void setDisplayParams(const DisplayParams& params);
 
 protected:
index 09e7ef1..0156ea1 100644 (file)
@@ -27,6 +27,16 @@ bool Window_android::init(SkiaAndroidApp* skiaAndroidApp) {
     return true;
 }
 
+const DisplayParams& Window_android::getDisplayParams() {
+    if (fWindowContext) {
+        return fWindowContext->getDisplayParams();
+    } else {
+        // fWindowContext doesn't exist because we haven't
+        // initDisplay yet.
+        return fDisplayParams;
+    }
+}
+
 void Window_android::setTitle(const char* title) {
     //todo
     SkDebugf("Title: %s", title);
@@ -49,11 +59,9 @@ void Window_android::initDisplay(ANativeWindow* window) {
     ContextPlatformData_android platformData;
     platformData.fNativeWindow = window;
     fWindowContext = VulkanWindowContext::Create((void*)&platformData, fDisplayParams);
-    fNativeWindowInitialized = true;
 }
 
 void Window_android::onDisplayDestroyed() {
-    fNativeWindowInitialized = false;
     detach();
 }
 
index 45e5bbe..2bf7bfe 100644 (file)
@@ -22,6 +22,7 @@ public:
     void initDisplay(ANativeWindow* window);
     void onDisplayDestroyed();
 
+    const DisplayParams& getDisplayParams() override;
     void setTitle(const char*) override;
     void show() override {}
 
@@ -37,7 +38,6 @@ private:
     SkiaAndroidApp* fSkiaAndroidApp = nullptr;
     SkRect fContentRect;
     DisplayParams fDisplayParams;
-    bool fNativeWindowInitialized = false;
 };
 
 }   // namespace sk_app
index b1d0029..acee839 100644 (file)
@@ -11,7 +11,9 @@
 #include <pthread.h>
 #include <stdio.h>
 #include <unistd.h>
+#include <unordered_map>
 
+#include <android/keycodes.h>
 #include <android/looper.h>
 #include <android/native_window_jni.h>
 
@@ -24,6 +26,11 @@ namespace sk_app {
 
 static const int LOOPER_ID_MESSAGEPIPE = 1;
 
+static const std::unordered_map<int, Window::Key> ANDROID_TO_WINDOW_KEYMAP({
+    {AKEYCODE_SOFT_LEFT, Window::Key::kLeft},
+    {AKEYCODE_SOFT_RIGHT, Window::Key::kRight}
+});
+
 void* pthread_main(void* arg);
 
 SkiaAndroidApp::SkiaAndroidApp() {
@@ -90,7 +97,6 @@ static int message_callback(int fd, int events, void* data) {
                      message.fNativeWindow);
             int width = ANativeWindow_getWidth(skiaAndroidApp->fNativeWindow);
             int height = ANativeWindow_getHeight(skiaAndroidApp->fNativeWindow);
-            skiaAndroidApp->fWindow->onResize(width, height);
             auto window_android = (Window_android*)skiaAndroidApp->fWindow;
             window_android->setContentRect(0, 0, width, height);
             skiaAndroidApp->paintIfNeeded();
@@ -105,6 +111,14 @@ static int message_callback(int fd, int events, void* data) {
             }
             break;
         }
+        case kKeyPressed: {
+            auto it = ANDROID_TO_WINDOW_KEYMAP.find(message.keycode);
+            SkASSERT(it != ANDROID_TO_WINDOW_KEYMAP.end());
+            // No modifier is supported so far
+            skiaAndroidApp->fWindow->onKey(it->second, Window::kDown_InputState, 0);
+            skiaAndroidApp->fWindow->onKey(it->second, Window::kUp_InputState, 0);
+            break;
+        }
         default: {
             // do nothing
         }
@@ -171,4 +185,14 @@ extern "C" JNIEXPORT void JNICALL Java_org_skia_viewer_ViewerActivity_onSurfaceD
     skiaAndroidApp->postMessage(Message(kSurfaceDestroyed));
 }
 
+extern "C" JNIEXPORT void JNICALL Java_org_skia_viewer_ViewerActivity_onKeyPressed(JNIEnv* env,
+                                                                                   jobject activity,
+                                                                                   jlong handle,
+                                                                                   jint keycode) {
+    auto skiaAndroidApp = (SkiaAndroidApp*)handle;
+    Message message(kKeyPressed);
+    message.keycode = keycode;
+    skiaAndroidApp->postMessage(message);
+}
+
 }  // namespace sk_app
index aefe462..2961122 100644 (file)
@@ -23,12 +23,14 @@ enum MessageType {
     kSurfaceChanged,
     kSurfaceDestroyed,
     kDestroyApp,
-    kContentInvalidated
+    kContentInvalidated,
+    kKeyPressed
 };
 
 struct Message {
     MessageType fType = kUndefined;
     ANativeWindow* fNativeWindow = nullptr;
+    int keycode = 0;
 
     Message() {}
     Message(MessageType t) : fType(t) {}