diff options
Diffstat (limited to 'tools/viewer')
-rw-r--r-- | tools/viewer/Viewer.cpp | 42 | ||||
-rw-r--r-- | tools/viewer/Viewer.h | 6 | ||||
-rw-r--r-- | tools/viewer/sk_app/Window.cpp | 10 | ||||
-rw-r--r-- | tools/viewer/sk_app/Window.h | 14 | ||||
-rw-r--r-- | tools/viewer/sk_app/android/Window_android.cpp | 4 | ||||
-rw-r--r-- | tools/viewer/sk_app/android/surface_glue_android.cpp | 42 | ||||
-rw-r--r-- | tools/viewer/sk_app/android/surface_glue_android.h | 15 |
7 files changed, 115 insertions, 18 deletions
diff --git a/tools/viewer/Viewer.cpp b/tools/viewer/Viewer.cpp index 644dd22e5e..7f18652c2c 100644 --- a/tools/viewer/Viewer.cpp +++ b/tools/viewer/Viewer.cpp @@ -28,6 +28,13 @@ static void on_paint_handler(SkCanvas* canvas, void* userData) { return vv->onPaint(canvas); } +static bool on_touch_handler(int owner, Window::InputState state, float x, float y, void* userData) +{ + Viewer* viewer = reinterpret_cast<Viewer*>(userData); + + return viewer->onTouch(owner, state, x, y); +} + DEFINE_bool2(fullscreen, f, true, "Run fullscreen."); DEFINE_string(key, "", "Space-separated key/value pairs to add to JSON identifying this builder."); DEFINE_string2(match, m, nullptr, @@ -71,6 +78,7 @@ Viewer::Viewer(int argc, char** argv, void* platformData) // register callbacks fCommands.attach(fWindow); fWindow->registerPaintFunc(on_paint_handler, this); + fWindow->registerTouchFunc(on_touch_handler, this); // add key-bindings fCommands.addCommand('s', "Overlays", "Toggle stats display", [this]() { @@ -134,7 +142,6 @@ Viewer::Viewer(int argc, char** argv, void* platformData) // set up first frame fCurrentSlide = 0; setupCurrentSlide(-1); - updateMatrix(); fWindow->show(); } @@ -228,10 +235,9 @@ void Viewer::changeZoomLevel(float delta) { } else { fZoomScale = SK_Scalar1; } - this->updateMatrix(); } -void Viewer::updateMatrix(){ +SkMatrix Viewer::computeMatrix() { SkMatrix m; m.reset(); @@ -247,12 +253,10 @@ void Viewer::updateMatrix(){ m.postTranslate(cx, cy); } - // TODO: add gesture support - // Apply any gesture matrix - //m.preConcat(fGesture.localM()); - //m.preConcat(fGesture.globalM()); + m.preConcat(fGesture.localM()); + m.preConcat(fGesture.globalM()); - fLocalMatrix = m; + return m; } void Viewer::onPaint(SkCanvas* canvas) { @@ -273,7 +277,7 @@ void Viewer::onPaint(SkCanvas* canvas) { matrix.setRectToRect(slideBounds, contentRect, SkMatrix::kCenter_ScaleToFit); canvas->concat(matrix); } - canvas->concat(fLocalMatrix); + canvas->concat(computeMatrix()); fSlides[fCurrentSlide]->draw(canvas); canvas->restoreToCount(count); @@ -284,6 +288,26 @@ void Viewer::onPaint(SkCanvas* canvas) { fCommands.drawHelp(canvas); } +bool Viewer::onTouch(int owner, Window::InputState state, float x, float y) { + void* castedOwner = reinterpret_cast<void*>(owner); + switch (state) { + case Window::kUp_InputState: { + fGesture.touchEnd(castedOwner); + break; + } + case Window::kDown_InputState: { + fGesture.touchBegin(castedOwner, x, y); + break; + } + case Window::kMove_InputState: { + fGesture.touchMoved(castedOwner, x, y); + break; + } + } + fWindow->inval(); + return true; +} + void Viewer::drawStats(SkCanvas* canvas) { static const float kPixelPerMS = 2.0f; static const int kDisplayWidth = 130; diff --git a/tools/viewer/Viewer.h b/tools/viewer/Viewer.h index 3579e4d296..c785cff78e 100644 --- a/tools/viewer/Viewer.h +++ b/tools/viewer/Viewer.h @@ -24,6 +24,7 @@ public: void onPaint(SkCanvas* canvas); void onIdle(double ms) override; + bool onTouch(int owner, sk_app::Window::InputState state, float x, float y); private: void initSlides(); @@ -33,7 +34,7 @@ private: void drawStats(SkCanvas* canvas); void changeZoomLevel(float delta); - void updateMatrix(); + SkMatrix computeMatrix(); sk_app::Window* fWindow; @@ -50,13 +51,14 @@ private: sk_app::Window::BackendType fBackendType; // transform data - SkMatrix fLocalMatrix; SkScalar fZoomCenterX; SkScalar fZoomCenterY; SkScalar fZoomLevel; SkScalar fZoomScale; sk_app::CommandSet fCommands; + + SkTouchGesture fGesture; }; diff --git a/tools/viewer/sk_app/Window.cpp b/tools/viewer/sk_app/Window.cpp index dc0bf995d0..0a7bcf8a70 100644 --- a/tools/viewer/sk_app/Window.cpp +++ b/tools/viewer/sk_app/Window.cpp @@ -27,11 +27,17 @@ static bool default_mouse_func(int x, int y, Window::InputState state, uint32_t return false; } +static bool default_touch_func(int owner, Window::InputState state, float x, float y, + void* userData) { + return false; +} + static void default_paint_func(SkCanvas*, void* userData) {} Window::Window() : fCharFunc(default_char_func) , fKeyFunc(default_key_func) , fMouseFunc(default_mouse_func) + , fTouchFunc(default_touch_func) , fPaintFunc(default_paint_func) { } @@ -52,6 +58,10 @@ bool Window::onMouse(int x, int y, InputState state, uint32_t modifiers) { return fMouseFunc(x, y, state, modifiers, fMouseUserData); } +bool Window::onTouch(int owner, InputState state, float x, float y) { + return fTouchFunc(owner, state, x, y, fTouchUserData); +} + void Window::onPaint() { sk_sp<SkSurface> backbuffer = fWindowContext->getBackbufferSurface(); if (backbuffer) { diff --git a/tools/viewer/sk_app/Window.h b/tools/viewer/sk_app/Window.h index 5b41f87f07..63d5e19e55 100644 --- a/tools/viewer/sk_app/Window.h +++ b/tools/viewer/sk_app/Window.h @@ -9,8 +9,9 @@ #define Window_DEFINED #include "DisplayParams.h" -#include "SkTypes.h" #include "SkRect.h" +#include "SkTouchGesture.h" +#include "SkTypes.h" class SkCanvas; @@ -104,6 +105,7 @@ public: typedef bool(*OnCharFunc)(SkUnichar c, uint32_t modifiers, void* userData); typedef bool(*OnKeyFunc)(Key key, InputState state, uint32_t modifiers, void* userData); typedef bool(*OnMouseFunc)(int x, int y, InputState state, uint32_t modifiers, void* userData); + typedef bool(*OnTouchFunc)(int owner, InputState state, float x, float y, void* userData); typedef void(*OnPaintFunc)(SkCanvas*, void* userData); void registerCharFunc(OnCharFunc func, void* userData) { @@ -126,9 +128,15 @@ public: fPaintUserData = userData; } + void registerTouchFunc(OnTouchFunc func, void* userData) { + fTouchFunc = func; + fTouchUserData = userData; + } + bool onChar(SkUnichar c, uint32_t modifiers); bool onKey(Key key, InputState state, uint32_t modifiers); bool onMouse(int x, int y, InputState state, uint32_t modifiers); + bool onTouch(int owner, InputState state, float x, float y); // multi-owner = multi-touch void onPaint(); void onResize(uint32_t width, uint32_t height); @@ -150,10 +158,12 @@ protected: void* fKeyUserData; OnMouseFunc fMouseFunc; void* fMouseUserData; + OnTouchFunc fTouchFunc; + void* fTouchUserData; OnPaintFunc fPaintFunc; void* fPaintUserData; - WindowContext* fWindowContext; + WindowContext* fWindowContext = nullptr; }; } // namespace sk_app diff --git a/tools/viewer/sk_app/android/Window_android.cpp b/tools/viewer/sk_app/android/Window_android.cpp index 21998d5b41..106c40b7b0 100644 --- a/tools/viewer/sk_app/android/Window_android.cpp +++ b/tools/viewer/sk_app/android/Window_android.cpp @@ -64,6 +64,8 @@ void Window_android::onDisplayDestroyed() { detach(); } -void Window_android::inval() { fSkiaAndroidApp->postMessage(Message(kContentInvalidated)); } +void Window_android::inval() { + fSkiaAndroidApp->inval(); +} } // namespace sk_app diff --git a/tools/viewer/sk_app/android/surface_glue_android.cpp b/tools/viewer/sk_app/android/surface_glue_android.cpp index 3d8617f0aa..e8715582c0 100644 --- a/tools/viewer/sk_app/android/surface_glue_android.cpp +++ b/tools/viewer/sk_app/android/surface_glue_android.cpp @@ -13,6 +13,7 @@ #include <unistd.h> #include <unordered_map> +#include <android/input.h> #include <android/keycodes.h> #include <android/looper.h> #include <android/native_window_jni.h> @@ -31,6 +32,15 @@ static const std::unordered_map<int, Window::Key> ANDROID_TO_WINDOW_KEYMAP({ {AKEYCODE_SOFT_RIGHT, Window::Key::kRight} }); +static const std::unordered_map<int, Window::InputState> ANDROID_TO_WINDOW_STATEMAP({ + {AMOTION_EVENT_ACTION_DOWN, Window::kDown_InputState}, + {AMOTION_EVENT_ACTION_POINTER_DOWN, Window::kDown_InputState}, + {AMOTION_EVENT_ACTION_UP, Window::kUp_InputState}, + {AMOTION_EVENT_ACTION_POINTER_UP, Window::kUp_InputState}, + {AMOTION_EVENT_ACTION_MOVE, Window::kMove_InputState}, + {AMOTION_EVENT_ACTION_CANCEL, Window::kUp_InputState}, +}); + SkiaAndroidApp::SkiaAndroidApp(JNIEnv* env, jobject androidApp) { env->GetJavaVM(&fJavaVM); fAndroidApp = env->NewGlobalRef(androidApp); @@ -76,6 +86,14 @@ void SkiaAndroidApp::readMessage(Message* message) const { SkASSERT(readSize == sizeof(Message)); } +void SkiaAndroidApp::inval() { + SkAutoMutexAcquire ama(fMutex); + if (!fIsContentInvalidated) { + postMessage(Message(kContentInvalidated)); + fIsContentInvalidated = true; + } +} + int SkiaAndroidApp::message_callback(int fd, int events, void* data) { auto skiaAndroidApp = (SkiaAndroidApp*)data; Message message; @@ -90,6 +108,8 @@ int SkiaAndroidApp::message_callback(int fd, int events, void* data) { return 0; } case kContentInvalidated: { + SkAutoMutexAcquire ama(skiaAndroidApp->fMutex); + skiaAndroidApp->fIsContentInvalidated = false; skiaAndroidApp->paintIfNeeded(); break; } @@ -121,13 +141,20 @@ int SkiaAndroidApp::message_callback(int fd, int events, void* data) { break; } case kKeyPressed: { - auto it = ANDROID_TO_WINDOW_KEYMAP.find(message.keycode); + auto it = ANDROID_TO_WINDOW_KEYMAP.find(message.fKeycode); 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; } + case kTouched: { + auto it = ANDROID_TO_WINDOW_STATEMAP.find(message.fTouchState); + SkASSERT(it != ANDROID_TO_WINDOW_STATEMAP.end()); + skiaAndroidApp->fWindow->onTouch(message.fTouchOwner, it->second, message.fTouchX, + message.fTouchY); + break; + } default: { // do nothing } @@ -203,7 +230,18 @@ extern "C" JNIEXPORT void JNICALL Java_org_skia_viewer_ViewerActivity_onKeyPress jint keycode) { auto skiaAndroidApp = (SkiaAndroidApp*)handle; Message message(kKeyPressed); - message.keycode = keycode; + message.fKeycode = keycode; + skiaAndroidApp->postMessage(message); +} + +extern "C" JNIEXPORT void JNICALL Java_org_skia_viewer_ViewerActivity_onTouched( + JNIEnv* env, jobject activity, jlong handle, jint owner, jfloat x, jfloat y, jint state) { + auto skiaAndroidApp = (SkiaAndroidApp*)handle; + Message message(kTouched); + message.fTouchOwner = owner; + message.fTouchState = state; + message.fTouchX = x; + message.fTouchY = y; skiaAndroidApp->postMessage(message); } diff --git a/tools/viewer/sk_app/android/surface_glue_android.h b/tools/viewer/sk_app/android/surface_glue_android.h index 1ce06674b9..7ffba3080a 100644 --- a/tools/viewer/sk_app/android/surface_glue_android.h +++ b/tools/viewer/sk_app/android/surface_glue_android.h @@ -12,6 +12,7 @@ #include <android/native_window_jni.h> +#include "../private/SkMutex.h" #include "../Application.h" #include "../Window.h" @@ -24,13 +25,16 @@ enum MessageType { kSurfaceDestroyed, kDestroyApp, kContentInvalidated, - kKeyPressed + kKeyPressed, + kTouched }; struct Message { MessageType fType = kUndefined; ANativeWindow* fNativeWindow = nullptr; - int keycode = 0; + int fKeycode = 0; + int fTouchOwner, fTouchState; + float fTouchX, fTouchY; Message() {} Message(MessageType t) : fType(t) {} @@ -49,6 +53,10 @@ struct SkiaAndroidApp { // This must be called in SkiaAndroidApp's own pthread because the JNIEnv is thread sensitive void setTitle(const char* title) const; + + // This posts a kContentInvalidated message if there's no such message currently in the queue + void inval(); + private: pthread_t fThread; ANativeWindow* fNativeWindow; @@ -57,6 +65,9 @@ private: JNIEnv* fPThreadEnv; jmethodID fSetTitleMethodID; + bool fIsContentInvalidated = false; // use this to avoid duplicate invalidate events + SkMutex fMutex; + // This must be called in SkiaAndroidApp's own pthread because the JNIEnv is thread sensitive ~SkiaAndroidApp(); |