# HG changeset patch # User Benjamin Golinvaux # Date 1561381075 -7200 # Node ID f0bf971a1e31f22e252a94d5e847986e8f77f225 # Parent 6845a05f95267aefb89779e7c64171746194f606 Keyboard event routing (handling done in app) diff -r 6845a05f9526 -r f0bf971a1e31 Applications/Generic/GuiAdapter.cpp --- a/Applications/Generic/GuiAdapter.cpp Mon Jun 24 10:31:57 2019 +0200 +++ b/Applications/Generic/GuiAdapter.cpp Mon Jun 24 14:57:55 2019 +0200 @@ -44,7 +44,7 @@ std::ostream& operator<<( std::ostream& os, const GuiAdapterKeyboardEvent& event) { - os << "ctrl: " << event.ctrlKey << ", " << + os << "sym: " << event.sym << " (" << (int)(event.sym[0]) << ") ctrl: " << event.ctrlKey << ", " << "shift: " << event.shiftKey << ", " << "alt: " << event.altKey; return os; @@ -112,10 +112,7 @@ //dest.padding = src.padding; } - void ConvertFromPlatform( - GuiAdapterWheelEvent& dest, - int eventType, - const EmscriptenWheelEvent& src) + void ConvertFromPlatform( GuiAdapterWheelEvent& dest, int eventType, const EmscriptenWheelEvent& src) { ConvertFromPlatform(dest.mouse, eventType, src.mouse); dest.deltaX = src.deltaX; @@ -138,15 +135,15 @@ dest.deltaMode = src.deltaMode; } - void ConvertFromPlatform( - GuiAdapterKeyboardEvent& dest, - const EmscriptenKeyboardEvent& src) + void ConvertFromPlatform(GuiAdapterKeyboardEvent& dest, const EmscriptenKeyboardEvent& src) { + dest.sym[0] = src.key[0]; + dest.sym[1] = 0; dest.ctrlKey = src.ctrlKey; dest.shiftKey = src.shiftKey; dest.altKey = src.altKey; } - + template struct FuncAdapterPayload { @@ -156,10 +153,10 @@ }; template - EM_BOOL OnEventAdapterFunc( - int eventType, const EmscriptenEvent* emEvent, void* userData) + typename GuiAdapterEvent, + typename EmscriptenEvent> + EM_BOOL OnEventAdapterFunc( + int eventType, const EmscriptenEvent* emEvent, void* userData) { // userData is OnMouseWheelFuncAdapterPayload @@ -170,7 +167,7 @@ // LOG(INFO) << "eventType: " << eventType << " wheelEvent: " << // (int)wheelEvent << " userData: " << userData << // " payload->userData: " << payload->userData; - + GuiAdapterEvent guiEvent; ConvertFromPlatform(guiEvent, eventType, *emEvent); bool ret = (*(payload->callback))(payload->canvasId, &guiEvent, payload->userData); @@ -186,7 +183,7 @@ // userData is OnMouseWheelFuncAdapterPayload FuncAdapterPayload* payload = reinterpret_cast*>(userData); - + GuiAdapterEvent guiEvent; ConvertFromPlatform(guiEvent, *wheelEvent); bool ret = (*(payload->callback))(payload->canvasId, &guiEvent, payload->userData); @@ -194,8 +191,8 @@ } template - EM_BOOL OnEventAdapterFunc3( - double time, void* userData) + EM_BOOL OnEventAdapterFunc3( + double time, void* userData) { // userData is OnMouseWheelFuncAdapterPayload FuncAdapterPayload* payload = @@ -207,17 +204,17 @@ // resize: (const char* target, void* userData, EM_BOOL useCapture, em_ui_callback_func callback) template< - typename GenericFunc, - typename GuiAdapterEvent, - typename EmscriptenEvent, + typename GenericFunc, + typename GuiAdapterEvent, + typename EmscriptenEvent, typename EmscriptenSetCallbackFunc> - static void SetCallback( - EmscriptenSetCallbackFunc emFunc, - std::string canvasId, void* userData, bool capture, GenericFunc func) + static void SetCallback( + EmscriptenSetCallbackFunc emFunc, + std::string canvasId, void* userData, bool capture, GenericFunc func) { // TODO: write RemoveCallback with an int id that gets returned from // here - FuncAdapterPayload* payload = + FuncAdapterPayload* payload = new FuncAdapterPayload(); std::auto_ptr > payloadP(payload); payload->canvasId = canvasId; @@ -397,76 +394,107 @@ #else -// SDL ONLY -void ConvertFromPlatform( - GuiAdapterMouseEvent& dest, - bool ctrlPressed, bool shiftPressed, bool altPressed, - const SDL_Event& source) -{ - memset(&dest, 0, sizeof(GuiAdapterMouseEvent)); - switch (source.type) + // SDL ONLY + void ConvertFromPlatform(GuiAdapterMouseEvent& dest, bool ctrlPressed, bool shiftPressed, bool altPressed, const SDL_Event& source) { - case SDL_MOUSEBUTTONDOWN: - dest.type = GUIADAPTER_EVENT_MOUSEDOWN; - break; - case SDL_MOUSEMOTION: - dest.type = GUIADAPTER_EVENT_MOUSEMOVE; - break; - case SDL_MOUSEBUTTONUP: - dest.type = GUIADAPTER_EVENT_MOUSEUP; - break; - case SDL_MOUSEWHEEL: - dest.type = GUIADAPTER_EVENT_WHEEL; - break; - default: - LOG(ERROR) << "SDL event: " << source.type << " is not supported"; - ORTHANC_ASSERT(false, "Not supported"); + memset(&dest, 0, sizeof(GuiAdapterMouseEvent)); + switch (source.type) + { + case SDL_MOUSEBUTTONDOWN: + dest.type = GUIADAPTER_EVENT_MOUSEDOWN; + break; + case SDL_MOUSEMOTION: + dest.type = GUIADAPTER_EVENT_MOUSEMOVE; + break; + case SDL_MOUSEBUTTONUP: + dest.type = GUIADAPTER_EVENT_MOUSEUP; + break; + case SDL_MOUSEWHEEL: + dest.type = GUIADAPTER_EVENT_WHEEL; + break; + default: + LOG(ERROR) << "SDL event: " << source.type << " is not supported"; + ORTHANC_ASSERT(false, "Not supported"); } - //dest.timestamp = src.timestamp; - //dest.screenX = src.screenX; - //dest.screenY = src.screenY; - //dest.clientX = src.clientX; - //dest.clientY = src.clientY; - dest.ctrlKey = ctrlPressed; - dest.shiftKey = shiftPressed; - dest.altKey = altPressed; - //dest.metaKey = src.metaKey; - switch (source.button.button) - { - case SDL_BUTTON_MIDDLE: - dest.button = 1; - break; + //dest.timestamp = src.timestamp; + //dest.screenX = src.screenX; + //dest.screenY = src.screenY; + //dest.clientX = src.clientX; + //dest.clientY = src.clientY; + dest.ctrlKey = ctrlPressed; + dest.shiftKey = shiftPressed; + dest.altKey = altPressed; + //dest.metaKey = src.metaKey; + switch (source.button.button) + { + case SDL_BUTTON_MIDDLE: + dest.button = 1; + break; - case SDL_BUTTON_RIGHT: - dest.button = 2; - break; + case SDL_BUTTON_RIGHT: + dest.button = 2; + break; - case SDL_BUTTON_LEFT: - dest.button = 0; - break; + case SDL_BUTTON_LEFT: + dest.button = 0; + break; - default: - break; - } - //dest.buttons = src.buttons; - //dest.movementX = src.movementX; - //dest.movementY = src.movementY; - dest.targetX = source.button.x; - dest.targetY = source.button.y; - //dest.canvasX = src.canvasX; - //dest.canvasY = src.canvasY; - //dest.padding = src.padding; + default: + break; + } + //dest.buttons = src.buttons; + //dest.movementX = src.movementX; + //dest.movementY = src.movementY; + dest.targetX = source.button.x; + dest.targetY = source.button.y; + //dest.canvasX = src.canvasX; + //dest.canvasY = src.canvasY; + //dest.padding = src.padding; } -void ConvertFromPlatform( - GuiAdapterWheelEvent& dest, - bool ctrlPressed, bool shiftPressed, bool altPressed, - const SDL_Event& source) -{ - ConvertFromPlatform(dest.mouse, ctrlPressed, shiftPressed, altPressed, source); - dest.deltaX = source.wheel.x; - dest.deltaY = source.wheel.y; -} + void ConvertFromPlatform( + GuiAdapterWheelEvent& dest, + bool ctrlPressed, bool shiftPressed, bool altPressed, + const SDL_Event& source) + { + ConvertFromPlatform(dest.mouse, ctrlPressed, shiftPressed, altPressed, source); + dest.deltaX = source.wheel.x; + dest.deltaY = source.wheel.y; + } + + void ConvertFromPlatform(GuiAdapterKeyboardEvent& dest, const SDL_Event& src) + { + memset(&dest, 0, sizeof(GuiAdapterMouseEvent)); + switch (src.type) + { + case SDL_KEYDOWN: + dest.type = GUIADAPTER_EVENT_KEYDOWN; + break; + case SDL_KEYUP: + dest.type = GUIADAPTER_EVENT_KEYUP; + break; + default: + LOG(ERROR) << "SDL event: " << src.type << " is not supported"; + ORTHANC_ASSERT(false, "Not supported"); + } + dest.sym[0] = src.key.keysym.sym; + dest.sym[1] = 0; + + if (src.key.keysym.mod & KMOD_CTRL) + dest.ctrlKey = true; + else + dest.ctrlKey = false; + + if (src.key.keysym.mod & KMOD_SHIFT) + dest.shiftKey = true; + else + dest.shiftKey = false; + + if (src.key.keysym.mod & KMOD_ALT) + dest.altKey = true; + else + dest.altKey = false; + } @@ -480,43 +508,44 @@ // SDL ONLY void GuiAdapter::SetMouseDownCallback( std::string canvasId, void* userData, bool capture, OnMouseEventFunc func) - { + { mouseDownHandlers_.push_back(EventHandlerData(canvasId, func, userData)); - } + } // SDL ONLY void GuiAdapter::SetMouseMoveCallback( std::string canvasId, void* userData, bool capture, OnMouseEventFunc func) - { + { mouseMoveHandlers_.push_back(EventHandlerData(canvasId, func, userData)); } // SDL ONLY void GuiAdapter::SetMouseUpCallback( std::string canvasId, void* userData, bool capture, OnMouseEventFunc func) - { + { mouseUpHandlers_.push_back(EventHandlerData(canvasId, func, userData)); } // SDL ONLY void GuiAdapter::SetWheelCallback( - std::string canvasId, void* userData, bool capture, OnMouseWheelFunc func) + std::string canvasId, void* userData, bool capture, OnMouseWheelFunc func) { mouseWheelHandlers_.push_back(EventHandlerData(canvasId, func, userData)); } // SDL ONLY void GuiAdapter::SetKeyDownCallback( - std::string canvasId, void* userData, bool capture, OnKeyDownFunc func) - { - } + std::string canvasId, void* userData, bool capture, OnKeyDownFunc func) + { + keyDownHandlers_.push_back(EventHandlerData(canvasId, func, userData)); + } // SDL ONLY void GuiAdapter::SetKeyUpCallback( - std::string canvasId, void* userData, bool capture, OnKeyUpFunc func) - { - } - + std::string canvasId, void* userData, bool capture, OnKeyUpFunc func) + { + keyUpHandlers_.push_back(EventHandlerData(canvasId, func, userData)); + } // SDL ONLY void GuiAdapter::OnAnimationFrame() @@ -558,7 +587,7 @@ case GUIADAPTER_EVENT_WHEEL: for (size_t i = 0; i < mouseWheelHandlers_.size(); i++) { - if(mouseWheelHandlers_[i].canvasName == windowTitle) + if (mouseWheelHandlers_[i].canvasName == windowTitle) (*(mouseWheelHandlers_[i].func))(windowTitle, &event, mouseWheelHandlers_[i].userData); } break; @@ -568,14 +597,16 @@ } } - // SDL ONLY - void GuiAdapter::OnMouseEvent(uint32_t windowID, const GuiAdapterMouseEvent& event) + + void GuiAdapter::OnKeyboardEvent(uint32_t windowID, const GuiAdapterKeyboardEvent& event) { - // the SDL window name IS the canvas name ("canvas" is used because this lib - // is designed for Wasm + // only one-letter (ascii) keyboard events supported for now + ORTHANC_ASSERT(event.sym[0] != 0); + ORTHANC_ASSERT(event.sym[1] == 0); + SDL_Window* sdlWindow = SDL_GetWindowFromID(windowID); ORTHANC_ASSERT(sdlWindow != NULL, "Window ID \"" << windowID << "\" is not a valid SDL window ID!"); - + const char* windowTitleSz = SDL_GetWindowTitle(sdlWindow); ORTHANC_ASSERT(windowTitleSz != NULL, "Window ID \"" << windowID << "\" has a NULL window title!"); @@ -584,42 +615,84 @@ switch (event.type) { - case GUIADAPTER_EVENT_MOUSEDOWN: - for (size_t i = 0; i < mouseDownHandlers_.size(); i++) + case GUIADAPTER_EVENT_KEYDOWN: + for (size_t i = 0; i < keyDownHandlers_.size(); i++) { - if (mouseDownHandlers_[i].canvasName == windowTitle) - (*(mouseDownHandlers_[i].func))(windowTitle, &event, mouseDownHandlers_[i].userData); + (*(keyDownHandlers_[i].func))(windowTitle, &event, keyDownHandlers_[i].userData); } break; - case GUIADAPTER_EVENT_MOUSEMOVE: - for (size_t i = 0; i < mouseMoveHandlers_.size(); i++) + case GUIADAPTER_EVENT_KEYUP: + for (size_t i = 0; i < keyUpHandlers_.size(); i++) { - if (mouseMoveHandlers_[i].canvasName == windowTitle) - (*(mouseMoveHandlers_[i].func))(windowTitle, &event, mouseMoveHandlers_[i].userData); - } - break; - case GUIADAPTER_EVENT_MOUSEUP: - for (size_t i = 0; i < mouseUpHandlers_.size(); i++) - { - if (mouseUpHandlers_[i].canvasName == windowTitle) - (*(mouseUpHandlers_[i].func))(windowTitle, &event, mouseUpHandlers_[i].userData); + (*(keyUpHandlers_[i].func))(windowTitle, &event, keyUpHandlers_[i].userData); } break; default: - ORTHANC_ASSERT(false, "Wrong event.type: " << event.type << " in GuiAdapter::OnMouseEvent(...)"); + ORTHANC_ASSERT(false, "Wrong event.type: " << event.type << " in GuiAdapter::OnKeyboardEvent(...)"); break; } + } - ////boost::shared_ptr GetWidgetFromWindowId(); - //boost::shared_ptr foundWidget; - //VisitWidgets([foundWidget, windowID](auto widget) - // { - // if (widget->GetSdlWindowID() == windowID) - // foundWidget = widget; - // }); - //ORTHANC_ASSERT(foundWidget, "WindowID " << windowID << " was not found in the registered widgets!"); - //if(foundWidget) - // foundWidget-> + // SDL ONLY + void GuiAdapter::OnMouseEvent(uint32_t windowID, const GuiAdapterMouseEvent& event) + { + if (windowID == 0) + { + LOG(WARN) << "GuiAdapter::OnMouseEvent -- windowID == 0 and event won't be routed!"; + } + else + { + // the SDL window name IS the canvas name ("canvas" is used because this lib + // is designed for Wasm + SDL_Window* sdlWindow = SDL_GetWindowFromID(windowID); + + ORTHANC_ASSERT(sdlWindow != NULL, "Window ID \"" << windowID << "\" is not a valid SDL window ID!"); + + const char* windowTitleSz = SDL_GetWindowTitle(sdlWindow); + ORTHANC_ASSERT(windowTitleSz != NULL, "Window ID \"" << windowID << "\" has a NULL window title!"); + + std::string windowTitle(windowTitleSz); + ORTHANC_ASSERT(windowTitle != "", "Window ID \"" << windowID << "\" has an empty window title!"); + + switch (event.type) + { + case GUIADAPTER_EVENT_MOUSEDOWN: + for (size_t i = 0; i < mouseDownHandlers_.size(); i++) + { + if (mouseDownHandlers_[i].canvasName == windowTitle) + (*(mouseDownHandlers_[i].func))(windowTitle, &event, mouseDownHandlers_[i].userData); + } + break; + case GUIADAPTER_EVENT_MOUSEMOVE: + for (size_t i = 0; i < mouseMoveHandlers_.size(); i++) + { + if (mouseMoveHandlers_[i].canvasName == windowTitle) + (*(mouseMoveHandlers_[i].func))(windowTitle, &event, mouseMoveHandlers_[i].userData); + } + break; + case GUIADAPTER_EVENT_MOUSEUP: + for (size_t i = 0; i < mouseUpHandlers_.size(); i++) + { + if (mouseUpHandlers_[i].canvasName == windowTitle) + (*(mouseUpHandlers_[i].func))(windowTitle, &event, mouseUpHandlers_[i].userData); + } + break; + default: + ORTHANC_ASSERT(false, "Wrong event.type: " << event.type << " in GuiAdapter::OnMouseEvent(...)"); + break; + } + + ////boost::shared_ptr GetWidgetFromWindowId(); + //boost::shared_ptr foundWidget; + //VisitWidgets([foundWidget, windowID](auto widget) + // { + // if (widget->GetSdlWindowID() == windowID) + // foundWidget = widget; + // }); + //ORTHANC_ASSERT(foundWidget, "WindowID " << windowID << " was not found in the registered widgets!"); + //if(foundWidget) + // foundWidget-> + } } // SDL ONLY @@ -637,7 +710,7 @@ GLuint id, GLenum severity, GLsizei length, - const GLchar* message, + const GLchar * message, const void* userParam) { if (severity != GL_DEBUG_SEVERITY_NOTIFICATION) @@ -646,7 +719,7 @@ (type == GL_DEBUG_TYPE_ERROR ? "** GL ERROR **" : ""), type, severity, message); } -} + } # endif // SDL ONLY @@ -680,16 +753,16 @@ stop = true; break; } - else if ( (event.type == SDL_MOUSEMOTION) || - (event.type == SDL_MOUSEBUTTONDOWN) || - (event.type == SDL_MOUSEBUTTONUP) ) + else if ((event.type == SDL_MOUSEMOTION) || + (event.type == SDL_MOUSEBUTTONDOWN) || + (event.type == SDL_MOUSEBUTTONUP)) { int scancodeCount = 0; const uint8_t* keyboardState = SDL_GetKeyboardState(&scancodeCount); bool ctrlPressed(false); bool shiftPressed(false); bool altPressed(false); - + if (SDL_SCANCODE_LCTRL < scancodeCount && keyboardState[SDL_SCANCODE_LCTRL]) ctrlPressed = true; if (SDL_SCANCODE_RCTRL < scancodeCount && keyboardState[SDL_SCANCODE_RCTRL]) @@ -700,7 +773,7 @@ shiftPressed = true; if (SDL_SCANCODE_LALT < scancodeCount && keyboardState[SDL_SCANCODE_LALT]) altPressed = true; - + GuiAdapterMouseEvent dest; ConvertFromPlatform(dest, ctrlPressed, shiftPressed, altPressed, event); OnMouseEvent(event.window.windowID, dest); @@ -768,23 +841,14 @@ // window.GetWindow().ToggleMaximize(); //TODO: move to particular handler break; - case SDLK_s: -#if 0 - // TODO: re-enable at application-level!!!! - VisitWidgets( - [](auto value) - { - auto widget = boost::dynamic_pointer_castFitContent(); - }); -#endif - break; - case SDLK_q: stop = true; break; default: + GuiAdapterKeyboardEvent dest; + ConvertFromPlatform(dest, event); + OnKeyboardEvent(event.window.windowID, dest); break; } } diff -r 6845a05f9526 -r f0bf971a1e31 Applications/Generic/GuiAdapter.h --- a/Applications/Generic/GuiAdapter.h Mon Jun 24 10:31:57 2019 +0200 +++ b/Applications/Generic/GuiAdapter.h Mon Jun 24 14:57:55 2019 +0200 @@ -67,12 +67,14 @@ }; - enum GuiAdapterMouseEventType + enum GuiAdapterHidEventType { GUIADAPTER_EVENT_MOUSEDOWN = 1973, GUIADAPTER_EVENT_MOUSEMOVE = 1974, GUIADAPTER_EVENT_MOUSEUP = 1975, - GUIADAPTER_EVENT_WHEEL = 1976 + GUIADAPTER_EVENT_WHEEL = 1976, + GUIADAPTER_EVENT_KEYDOWN = 1977, + GUIADAPTER_EVENT_KEYUP = 1978, }; const unsigned int GUIADAPTER_DELTA_PIXEL = 2973; @@ -116,8 +118,9 @@ #endif #endif - struct GuiAdapterMouseEvent { - GuiAdapterMouseEventType type; + struct GuiAdapterMouseEvent + { + GuiAdapterHidEventType type; //double timestamp; //long screenX; //long screenY; @@ -152,6 +155,8 @@ // EmscriptenKeyboardEvent struct GuiAdapterKeyboardEvent { + GuiAdapterHidEventType type; + char sym[32]; bool ctrlKey; bool shiftKey; bool altKey; @@ -177,37 +182,21 @@ FROM: https://codingrepo.com/javascript/2017/05/19/javascript-difference-mousedown-mouseup-click-events/ */ #if ORTHANC_ENABLE_WASM == 1 - void ConvertFromPlatform( - GuiAdapterUiEvent& dest, - int eventType, - const EmscriptenUiEvent& src); + void ConvertFromPlatform(GuiAdapterUiEvent& dest, int eventType, const EmscriptenUiEvent& src); - void ConvertFromPlatform( - GuiAdapterMouseEvent& dest, - int eventType, - const EmscriptenMouseEvent& src); + void ConvertFromPlatform(GuiAdapterMouseEvent& dest, int eventType, const EmscriptenMouseEvent& src); - void ConvertFromPlatform( - GuiAdapterWheelEvent& dest, - int eventType, - const EmscriptenWheelEvent& src); + void ConvertFromPlatform(GuiAdapterWheelEvent& dest, int eventType, const EmscriptenWheelEvent& src); - void ConvertFromPlatform( - GuiAdapterKeyboardEvent& dest, - const EmscriptenKeyboardEvent& src); - + void ConvertFromPlatform(GuiAdapterKeyboardEvent& dest, const EmscriptenKeyboardEvent& src); #else # if ORTHANC_ENABLE_SDL == 1 - void ConvertFromPlatform( - GuiAdapterMouseEvent& dest, - bool ctrlPressed, bool shiftPressed, bool altPressed, - const SDL_Event& source); + void ConvertFromPlatform(GuiAdapterMouseEvent& dest, bool ctrlPressed, bool shiftPressed, bool altPressed, const SDL_Event& source); - void ConvertFromPlatform( - GuiAdapterWheelEvent& dest, - bool ctrlPressed, bool shiftPressed, bool altPressed, - const SDL_Event& source); + void ConvertFromPlatform(GuiAdapterWheelEvent& dest, bool ctrlPressed, bool shiftPressed, bool altPressed, const SDL_Event& source); + + void ConvertFromPlatform(GuiAdapterKeyboardEvent& dest, const SDL_Event& source); # endif @@ -326,14 +315,17 @@ std::vector > mouseMoveHandlers_; std::vector > mouseUpHandlers_; std::vector > mouseWheelHandlers_; - + std::vector > keyDownHandlers_; + std::vector > keyUpHandlers_; /** This executes all the registered headers if needed (in wasm, the browser deals with this) */ void OnMouseEvent(uint32_t windowID, const GuiAdapterMouseEvent& event); - + + void OnKeyboardEvent(uint32_t windowID, const GuiAdapterKeyboardEvent& event); + /** Same remark as OnMouseEvent */