diff options
author | Brian Osman <brianosman@google.com> | 2017-06-07 10:00:30 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-06-07 14:27:09 +0000 |
commit | b53f48cfec64830fa506267487a1037d27acb474 (patch) | |
tree | c7f108034ba97437371fce51c52d90970cf98156 /tools | |
parent | 2e425ebd95dd97f788f7f8a3b8529d77d69b4f61 (diff) |
Touch input support for Windows
Had to add some logic to avoid touch and mouse cross-talk, because
(at least on my laptop), the touch screen generates both kinds of
events.
This seems really useful [1] for the many [2] Skia developers with
touch-enabled Windows devices.
----------
1: No, not really.
2: N = 1?
Bug: skia:
Change-Id: Ib888bf4198f2cc0a29a31581ec4b64d3d9008c33
Reviewed-on: https://skia-review.googlesource.com/18920
Reviewed-by: Yuqian Li <liyuqian@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/viewer/Viewer.cpp | 9 | ||||
-rw-r--r-- | tools/viewer/Viewer.h | 7 | ||||
-rw-r--r-- | tools/viewer/sk_app/win/Window_win.cpp | 30 |
3 files changed, 46 insertions, 0 deletions
diff --git a/tools/viewer/Viewer.cpp b/tools/viewer/Viewer.cpp index 3503e6481f..e8e37346d8 100644 --- a/tools/viewer/Viewer.cpp +++ b/tools/viewer/Viewer.cpp @@ -251,6 +251,7 @@ Viewer::Viewer(int argc, char** argv, void* platformData) , fColorMode(ColorMode::kLegacy) , fColorSpacePrimaries(gSrgbPrimaries) , fZoomLevel(0.0f) + , fGestureDevice(GestureDevice::kNone) { static SkTaskGroup::Enabler kTaskGroupEnabler; SkGraphics::Init(); @@ -819,6 +820,9 @@ void Viewer::onPaint(SkCanvas* canvas) { } bool Viewer::onTouch(intptr_t owner, Window::InputState state, float x, float y) { + if (GestureDevice::kMouse == fGestureDevice) { + return false; + } void* castedOwner = reinterpret_cast<void*>(owner); switch (state) { case Window::kUp_InputState: { @@ -834,11 +838,15 @@ bool Viewer::onTouch(intptr_t owner, Window::InputState state, float x, float y) break; } } + fGestureDevice = fGesture.isBeingTouched() ? GestureDevice::kTouch : GestureDevice::kNone; fWindow->inval(); return true; } bool Viewer::onMouse(float x, float y, Window::InputState state, uint32_t modifiers) { + if (GestureDevice::kTouch == fGestureDevice) { + return false; + } switch (state) { case Window::kUp_InputState: { fGesture.touchEnd(nullptr); @@ -853,6 +861,7 @@ bool Viewer::onMouse(float x, float y, Window::InputState state, uint32_t modifi break; } } + fGestureDevice = fGesture.isBeingTouched() ? GestureDevice::kMouse : GestureDevice::kNone; fWindow->inval(); return true; } diff --git a/tools/viewer/Viewer.h b/tools/viewer/Viewer.h index fac280ff59..1b68007ede 100644 --- a/tools/viewer/Viewer.h +++ b/tools/viewer/Viewer.h @@ -91,7 +91,14 @@ private: sk_app::CommandSet fCommands; + enum class GestureDevice { + kNone, + kTouch, + kMouse, + }; + SkTouchGesture fGesture; + GestureDevice fGestureDevice; // identity unless the window initially scales the content to fit the screen. SkMatrix fDefaultMatrix; diff --git a/tools/viewer/sk_app/win/Window_win.cpp b/tools/viewer/sk_app/win/Window_win.cpp index 1bec410ad2..6760089f79 100644 --- a/tools/viewer/sk_app/win/Window_win.cpp +++ b/tools/viewer/sk_app/win/Window_win.cpp @@ -114,6 +114,7 @@ bool Window_win::init(HINSTANCE hInstance) { } SetWindowLongPtr(fHWnd, GWLP_USERDATA, (LONG_PTR)this); + RegisterTouchWindow(fHWnd, 0); return true; } @@ -196,6 +197,7 @@ static uint32_t get_modifiers(UINT message, WPARAM wParam, LPARAM lParam) { if (wParam & MK_SHIFT) { modifiers |= Window::kShift_ModifierKey; } + break; } return modifiers; @@ -296,6 +298,34 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) get_modifiers(message, wParam, lParam)); break; + case WM_TOUCH: { + uint16_t numInputs = LOWORD(wParam); + std::unique_ptr<TOUCHINPUT[]> inputs(new TOUCHINPUT[numInputs]); + if (GetTouchInputInfo((HTOUCHINPUT)lParam, numInputs, inputs.get(), + sizeof(TOUCHINPUT))) { + RECT rect; + GetClientRect(hWnd, &rect); + for (uint16_t i = 0; i < numInputs; ++i) { + TOUCHINPUT ti = inputs[i]; + Window::InputState state; + if (ti.dwFlags & TOUCHEVENTF_DOWN) { + state = Window::kDown_InputState; + } else if (ti.dwFlags & TOUCHEVENTF_MOVE) { + state = Window::kMove_InputState; + } else if (ti.dwFlags & TOUCHEVENTF_UP) { + state = Window::kUp_InputState; + } else { + continue; + } + // TOUCHINPUT coordinates are in 100ths of pixels + // Adjust for that, and make them window relative + LONG tx = (ti.x / 100) - rect.left; + LONG ty = (ti.y / 100) - rect.top; + eventHandled = window->onTouch(ti.dwID, state, tx, ty) || eventHandled; + } + } + } break; + default: return DefWindowProc(hWnd, message, wParam, lParam); } |