From f1c209dc77df73b3f34ef9385f8b86061a615e63 Mon Sep 17 00:00:00 2001 From: kgv Date: Wed, 6 Oct 2021 23:55:43 +0300 Subject: [PATCH] 0032609: Visualization, Wasm_Window - handle mouse movements outside canvas element Wasm_Window::ProcessMouseEvent() - removed redundant check on EMSCRIPTEN_EVENT_MOUSEUP event. ViewerTest and WebGL sample - mouse movements are now tracked on window element to allow tracking updates when mouse with clicked button is moved outside canvas element. --- samples/webgl/WasmOcctView.cpp | 36 ++++++++++++++++++++-- src/ViewerTest/ViewerTest_EventManager.cxx | 36 ++++++++++++++++++++-- src/Wasm/Wasm_Window.cxx | 9 ++++-- 3 files changed, 72 insertions(+), 9 deletions(-) diff --git a/samples/webgl/WasmOcctView.cpp b/samples/webgl/WasmOcctView.cpp index 65efdd3ab4..e47f395acb 100644 --- a/samples/webgl/WasmOcctView.cpp +++ b/samples/webgl/WasmOcctView.cpp @@ -185,12 +185,16 @@ void WasmOcctView::initWindow() emscripten_set_resize_callback (EMSCRIPTEN_EVENT_TARGET_WINDOW, this, toUseCapture, onResizeCallback); emscripten_set_mousedown_callback (aTargetId, this, toUseCapture, onMouseCallback); - emscripten_set_mouseup_callback (aTargetId, this, toUseCapture, onMouseCallback); - emscripten_set_mousemove_callback (aTargetId, this, toUseCapture, onMouseCallback); + // bind these events to window to track mouse movements outside of canvas + //emscripten_set_mouseup_callback (aTargetId, this, toUseCapture, onMouseCallback); + //emscripten_set_mousemove_callback (aTargetId, this, toUseCapture, onMouseCallback); + //emscripten_set_mouseleave_callback (aTargetId, this, toUseCapture, onMouseCallback); + emscripten_set_mouseup_callback (EMSCRIPTEN_EVENT_TARGET_WINDOW, this, toUseCapture, onMouseCallback); + emscripten_set_mousemove_callback (EMSCRIPTEN_EVENT_TARGET_WINDOW, this, toUseCapture, onMouseCallback); + emscripten_set_dblclick_callback (aTargetId, this, toUseCapture, onMouseCallback); emscripten_set_click_callback (aTargetId, this, toUseCapture, onMouseCallback); emscripten_set_mouseenter_callback (aTargetId, this, toUseCapture, onMouseCallback); - emscripten_set_mouseleave_callback (aTargetId, this, toUseCapture, onMouseCallback); emscripten_set_wheel_callback (aTargetId, this, toUseCapture, onWheelCallback); emscripten_set_touchstart_callback (aTargetId, this, toUseCapture, onTouchCallback); @@ -474,6 +478,21 @@ EM_BOOL WasmOcctView::onResizeEvent (int theEventType, const EmscriptenUiEvent* return EM_TRUE; } +//! Update canvas bounding rectangle. +EM_JS(void, jsUpdateBoundingClientRect, (), { + Module._myCanvasRect = Module.canvas.getBoundingClientRect(); +}); + +//! Get canvas bounding top. +EM_JS(int, jsGetBoundingClientTop, (), { + return Math.round(Module._myCanvasRect.top); +}); + +//! Get canvas bounding left. +EM_JS(int, jsGetBoundingClientLeft, (), { + return Math.round(Module._myCanvasRect.left); +}); + // ================================================================ // Function : onMouseEvent // Purpose : @@ -486,6 +505,17 @@ EM_BOOL WasmOcctView::onMouseEvent (int theEventType, const EmscriptenMouseEvent } Handle(Wasm_Window) aWindow = Handle(Wasm_Window)::DownCast (myView->Window()); + if (theEventType == EMSCRIPTEN_EVENT_MOUSEMOVE + || theEventType == EMSCRIPTEN_EVENT_MOUSEUP) + { + // these events are bound to EMSCRIPTEN_EVENT_TARGET_WINDOW, and coordinates should be converted + jsUpdateBoundingClientRect(); + EmscriptenMouseEvent anEvent = *theEvent; + anEvent.targetX -= jsGetBoundingClientLeft(); + anEvent.targetY -= jsGetBoundingClientTop(); + return aWindow->ProcessMouseEvent (*this, theEventType, &anEvent) ? EM_TRUE : EM_FALSE; + } + return aWindow->ProcessMouseEvent (*this, theEventType, theEvent) ? EM_TRUE : EM_FALSE; } diff --git a/src/ViewerTest/ViewerTest_EventManager.cxx b/src/ViewerTest/ViewerTest_EventManager.cxx index e22e72981b..7ae3a25c74 100644 --- a/src/ViewerTest/ViewerTest_EventManager.cxx +++ b/src/ViewerTest/ViewerTest_EventManager.cxx @@ -624,6 +624,21 @@ static EM_BOOL onResizeCallback (int theEventType, const EmscriptenUiEvent* theE return EM_FALSE; } +//! Update canvas bounding rectangle. +EM_JS(void, occJSUpdateBoundingClientRect, (), { + Module._myCanvasRect = Module.canvas.getBoundingClientRect(); +}); + +//! Get canvas bounding top. +EM_JS(int, occJSGetBoundingClientTop, (), { + return Math.round(Module._myCanvasRect.top); +}); + +//! Get canvas bounding left. +EM_JS(int, occJSGetBoundingClientLeft, (), { + return Math.round(Module._myCanvasRect.left); +}); + //! Handle mouse input event. static EM_BOOL onWasmMouseCallback (int theEventType, const EmscriptenMouseEvent* theEvent, void* ) { @@ -632,6 +647,17 @@ static EM_BOOL onWasmMouseCallback (int theEventType, const EmscriptenMouseEvent && !ViewerTest::CurrentView().IsNull()) { Handle(Wasm_Window) aWindow = Handle(Wasm_Window)::DownCast (ViewerTest::CurrentView()->Window()); + if (theEventType == EMSCRIPTEN_EVENT_MOUSEMOVE + || theEventType == EMSCRIPTEN_EVENT_MOUSEUP) + { + // these events are bound to EMSCRIPTEN_EVENT_TARGET_WINDOW, and coordinates should be converted + occJSUpdateBoundingClientRect(); + EmscriptenMouseEvent anEvent = *theEvent; + anEvent.targetX -= occJSGetBoundingClientLeft(); + anEvent.targetY -= occJSGetBoundingClientTop(); + return aWindow->ProcessMouseEvent (*aViewCtrl, theEventType, &anEvent) ? EM_TRUE : EM_FALSE; + } + return aWindow->ProcessMouseEvent (*aViewCtrl, theEventType, theEvent) ? EM_TRUE : EM_FALSE; } return EM_FALSE; @@ -730,13 +756,17 @@ void ViewerTest_EventManager::SetupWindowCallbacks (const Handle(Aspect_Window)& // so that if web application changes canvas size by other means it should use another way to tell OCCT about resize emscripten_set_resize_callback (EMSCRIPTEN_EVENT_TARGET_WINDOW, anOpaque, toUseCapture, onResizeCallback); + // bind these events to window to track mouse movements outside of canvas + //emscripten_set_mouseup_callback (aTargetId, anOpaque, toUseCapture, onWasmMouseCallback); + //emscripten_set_mousemove_callback (aTargetId, anOpaque, toUseCapture, onWasmMouseCallback); + //emscripten_set_mouseleave_callback (aTargetId, anOpaque, toUseCapture, onWasmMouseCallback); + emscripten_set_mouseup_callback (EMSCRIPTEN_EVENT_TARGET_WINDOW, anOpaque, toUseCapture, onWasmMouseCallback); + emscripten_set_mousemove_callback (EMSCRIPTEN_EVENT_TARGET_WINDOW, anOpaque, toUseCapture, onWasmMouseCallback); + emscripten_set_mousedown_callback (aTargetId, anOpaque, toUseCapture, onWasmMouseCallback); - emscripten_set_mouseup_callback (aTargetId, anOpaque, toUseCapture, onWasmMouseCallback); - emscripten_set_mousemove_callback (aTargetId, anOpaque, toUseCapture, onWasmMouseCallback); emscripten_set_dblclick_callback (aTargetId, anOpaque, toUseCapture, onWasmMouseCallback); emscripten_set_click_callback (aTargetId, anOpaque, toUseCapture, onWasmMouseCallback); emscripten_set_mouseenter_callback (aTargetId, anOpaque, toUseCapture, onWasmMouseCallback); - emscripten_set_mouseleave_callback (aTargetId, anOpaque, toUseCapture, onWasmMouseCallback); emscripten_set_wheel_callback (aTargetId, anOpaque, toUseCapture, onWasmWheelCallback); emscripten_set_touchstart_callback (aTargetId, anOpaque, toUseCapture, onWasmTouchCallback); diff --git a/src/Wasm/Wasm_Window.cxx b/src/Wasm/Wasm_Window.cxx index b2a81e3499..19100a4b7c 100644 --- a/src/Wasm/Wasm_Window.cxx +++ b/src/Wasm/Wasm_Window.cxx @@ -290,10 +290,13 @@ bool Wasm_Window::ProcessMouseEvent (Aspect_WindowInputListener& theListener, case EMSCRIPTEN_EVENT_MOUSEDOWN: case EMSCRIPTEN_EVENT_MOUSEUP: { - if (aNewPos2i.x() < 0 || aNewPos2i.x() > mySize.x() - || aNewPos2i.y() < 0 || aNewPos2i.y() > mySize.y()) + if (theEventType == EMSCRIPTEN_EVENT_MOUSEDOWN) { - return false; + if (aNewPos2i.x() < 0 || aNewPos2i.x() > mySize.x() + || aNewPos2i.y() < 0 || aNewPos2i.y() > mySize.y()) + { + return false; + } } if (theListener.UpdateMouseButtons (aNewPos2i, aButtons, aFlags, isEmulated)) { -- 2.20.1