aboutsummaryrefslogtreecommitdiffhomepage
path: root/tools/viewer
diff options
context:
space:
mode:
Diffstat (limited to 'tools/viewer')
-rw-r--r--tools/viewer/Viewer.cpp42
-rw-r--r--tools/viewer/Viewer.h6
-rw-r--r--tools/viewer/sk_app/Window.cpp10
-rw-r--r--tools/viewer/sk_app/Window.h14
-rw-r--r--tools/viewer/sk_app/android/Window_android.cpp4
-rw-r--r--tools/viewer/sk_app/android/surface_glue_android.cpp42
-rw-r--r--tools/viewer/sk_app/android/surface_glue_android.h15
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();