From 5b6316bd15c950d425a2f66086dc1fa9e641aef4 Mon Sep 17 00:00:00 2001 From: Yousef Khadadeh Date: Tue, 3 Mar 2026 14:59:18 +0300 Subject: [PATCH] Start using pen input events --- src/InputManager.cpp | 163 +++++++++++++++++++++++++++++++++++++++---- src/InputManager.hpp | 29 ++++++-- src/MainProgram.cpp | 15 ++++ src/MainProgram.hpp | 5 ++ src/main.cpp | 37 ++++------ 5 files changed, 208 insertions(+), 41 deletions(-) diff --git a/src/InputManager.cpp b/src/InputManager.cpp index cdb1259..43f26d8 100644 --- a/src/InputManager.cpp +++ b/src/InputManager.cpp @@ -354,15 +354,6 @@ void InputManager::set_key_up(const SDL_KeyboardEvent& e, KeyCode kCode) { keys[kCode].held = false; } -void InputManager::set_pen_button_down(const SDL_PenButtonEvent& e) { - pen.buttons[e.button].held = true; - pen.buttons[e.button].pressed = true; -} - -void InputManager::set_pen_button_up(const SDL_PenButtonEvent& e) { - pen.buttons[e.button].held = false; -} - uint32_t InputManager::make_generic_key_mod(SDL_Keymod m) { uint32_t toRet = 0; if(m & SDL_KMOD_CTRL) @@ -378,22 +369,28 @@ uint32_t InputManager::make_generic_key_mod(SDL_Keymod m) { void InputManager::backend_mouse_button_up_update(const SDL_MouseButtonEvent& e) { Vector2f mousePos = {e.x * main.window.density, e.y * main.window.density}; + mouse.set_pos(mousePos); + if(e.button == 1) mouse.leftDown = false; else if(e.button == 2) mouse.middleDown = false; else if(e.button == 3) mouse.rightDown = false; - main.input_mouse_button_callback(MouseButtonCallbackArgs{ + MouseButtonCallbackArgs args{ .button = static_cast(e.button), .down = e.down, .clicks = e.clicks, .pos = mousePos - }); + }; + main.input_mouse_button_callback(args); + main.input_pure_mouse_button_callback(args); } void InputManager::backend_mouse_button_down_update(const SDL_MouseButtonEvent& e) { Vector2f mousePos = {e.x * main.window.density, e.y * main.window.density}; + mouse.set_pos(mousePos); + if(e.button == 1) { mouse.leftDown = true; mouse.leftClicks = e.clicks; @@ -406,18 +403,25 @@ void InputManager::backend_mouse_button_down_update(const SDL_MouseButtonEvent& mouse.rightDown = true; mouse.rightClicks = e.clicks; } - main.input_mouse_button_callback(MouseButtonCallbackArgs{ + MouseButtonCallbackArgs args{ .button = static_cast(e.button), .down = e.down, .clicks = e.clicks, .pos = mousePos - }); + }; + main.input_mouse_button_callback(args); + main.input_pure_mouse_button_callback(args); } void InputManager::backend_mouse_motion_update(const SDL_MouseMotionEvent& e) { Vector2f mouseNewPos = {e.x * main.window.density, e.y * main.window.density}; - Vector2f mouseRel = {e.xrel * main.window.density, e.yrel * main.window.density}; mouse.set_pos(mouseNewPos); + + Vector2f mouseRel = {e.xrel * main.window.density, e.yrel * main.window.density}; + main.input_pure_mouse_motion_callback({ + .pos = mouseNewPos, + .move = mouseRel + }); main.input_mouse_motion_callback({ .pos = mouseNewPos, .move = mouseRel @@ -427,6 +431,7 @@ void InputManager::backend_mouse_motion_update(const SDL_MouseMotionEvent& e) { void InputManager::backend_mouse_wheel_update(const SDL_MouseWheelEvent& e) { Vector2f mouseNewPos = {e.mouse_x * main.window.density, e.mouse_y * main.window.density}; mouse.set_pos(mouseNewPos); + mouse.scrollAmount.x() += e.x; mouse.scrollAmount.y() += e.y; main.input_mouse_wheel_callback({ @@ -436,6 +441,136 @@ void InputManager::backend_mouse_wheel_update(const SDL_MouseWheelEvent& e) { }); } +void InputManager::backend_pen_button_down_update(const SDL_PenButtonEvent& e) { + Vector2f mouseNewPos = {e.x * main.window.density, e.y * main.window.density}; + mouse.set_pos(mouseNewPos); + + pen.previousPos = mouseNewPos; + pen.buttons[e.button].held = true; + pen.buttons[e.button].pressed = true; + + if(e.button == main.toolbar.tabletOptions.middleClickButton) { + main.input_mouse_button_callback({ + .button = MouseButton::MIDDLE, + .down = e.down, + .clicks = 1, + .pos = mouseNewPos + }); + } + else if(e.button == main.toolbar.tabletOptions.rightClickButton) { + main.input_mouse_button_callback({ + .button = MouseButton::RIGHT, + .down = e.down, + .clicks = 1, + .pos = mouseNewPos + }); + } + + main.input_pen_button_callback({ + .button = e.button, + .down = e.down, + .pos = mouseNewPos + }); +} + +void InputManager::backend_pen_button_up_update(const SDL_PenButtonEvent& e) { + Vector2f mouseNewPos = {e.x * main.window.density, e.y * main.window.density}; + mouse.set_pos(mouseNewPos); + + pen.previousPos = mouseNewPos; + pen.buttons[e.button].held = false; + + if(e.button == main.toolbar.tabletOptions.middleClickButton) { + main.input_mouse_button_callback({ + .button = MouseButton::MIDDLE, + .down = e.down, + .clicks = 1, + .pos = mouseNewPos + }); + } + else if(e.button == main.toolbar.tabletOptions.rightClickButton) { + main.input_mouse_button_callback({ + .button = MouseButton::RIGHT, + .down = e.down, + .clicks = 1, + .pos = mouseNewPos + }); + } + + main.input_pen_button_callback({ + .button = e.button, + .down = e.down, + .pos = mouseNewPos + }); +} + +void InputManager::backend_pen_touch_down_update(const SDL_PenTouchEvent& e) { + Vector2f mouseNewPos = {e.x * main.window.density, e.y * main.window.density}; + mouse.set_pos(mouseNewPos); + + pen.previousPos = mouseNewPos; + pen.isDown = true; + mouse.leftDown = true; + if((std::chrono::steady_clock::now() - pen.lastPenLeftClickTime) > std::chrono::milliseconds(300)) + pen.leftClicksSaved = 0; + pen.leftClicksSaved++; + mouse.leftClicks = pen.leftClicksSaved; + pen.lastPenLeftClickTime = std::chrono::steady_clock::now(); + pen.isEraser = e.eraser; + + main.input_mouse_button_callback({ + .button = MouseButton::LEFT, + .down = e.down, + .clicks = mouse.leftClicks, + .pos = mouseNewPos + }); + main.input_pen_touch_callback({ + .down = e.down, + .eraser = e.eraser, + .pos = mouseNewPos + }); +} + +void InputManager::backend_pen_touch_up_update(const SDL_PenTouchEvent& e) { + Vector2f mouseNewPos = {e.x * main.window.density, e.y * main.window.density}; + mouse.set_pos(mouseNewPos); + + pen.previousPos = mouseNewPos; + pen.isDown = false; + mouse.leftDown = false; + pen.isEraser = e.eraser; + pen.pressure = 0.0; + + main.input_mouse_button_callback({ + .button = MouseButton::LEFT, + .down = e.down, + .clicks = 0, + .pos = mouseNewPos + }); + main.input_pen_touch_callback({ + .down = e.down, + .eraser = e.eraser, + .pos = mouseNewPos + }); +} + +void InputManager::backend_pen_motion_update(const SDL_PenMotionEvent& e) { + Vector2f mouseNewPos = {e.x * main.window.density, e.y * main.window.density}; + mouse.set_pos(mouseNewPos); + + Vector2f mouseRel = mouseNewPos - pen.previousPos; + pen.previousPos = mouseNewPos; + + main.input_mouse_motion_callback({ + .pos = mouseNewPos, + .move = mouseRel + }); + main.input_pen_motion_callback({ + .pos = mouseNewPos, + .move = mouseRel + }); +} + void InputManager::backend_key_down_update(const SDL_KeyboardEvent& e) { auto kPress = e.key; auto kMod = e.mod; diff --git a/src/InputManager.hpp b/src/InputManager.hpp index 6cd90a0..78895cf 100644 --- a/src/InputManager.hpp +++ b/src/InputManager.hpp @@ -71,7 +71,6 @@ struct InputManager { uint8_t rightClicks = 0; uint8_t middleClicks = 0; Vector2f lastPos = {0, 0}; - friend struct InputManager; } mouse; struct Touch { @@ -86,6 +85,8 @@ struct InputManager { bool isEraser = false; float pressure = 0.0f; int leftClicksSaved = 0; + Vector2f previousPos; + std::chrono::steady_clock::time_point lastPenLeftClickTime; std::array buttons; } pen; @@ -208,18 +209,21 @@ struct InputManager { bool ctrl_or_meta_held(); void stop_key_input(); - void set_pen_button_up(const SDL_PenButtonEvent& e); - void set_pen_button_down(const SDL_PenButtonEvent& e); uint32_t make_generic_key_mod(SDL_Keymod m); - void set_key_up(const SDL_KeyboardEvent& e, KeyCode kCode); void set_key_down(const SDL_KeyboardEvent& e, KeyCode kCode); + void backend_mouse_button_up_update(const SDL_MouseButtonEvent& e); void backend_mouse_button_down_update(const SDL_MouseButtonEvent& e); void backend_mouse_motion_update(const SDL_MouseMotionEvent& e); void backend_mouse_wheel_update(const SDL_MouseWheelEvent& e); void backend_key_up_update(const SDL_KeyboardEvent& e); void backend_key_down_update(const SDL_KeyboardEvent& e); + void backend_pen_button_down_update(const SDL_PenButtonEvent& e); + void backend_pen_button_up_update(const SDL_PenButtonEvent& e); + void backend_pen_touch_down_update(const SDL_PenTouchEvent& e); + void backend_pen_touch_up_update(const SDL_PenTouchEvent& e); + void backend_pen_motion_update(const SDL_PenMotionEvent& e); void set_clipboard_str(std::string_view s); void set_clipboard_plain_and_richtext_pair(const std::pair& plainAndRichtextPair); @@ -269,6 +273,23 @@ struct InputManager { Vector2i tickAmount; }; + struct PenButtonCallbackArgs { + uint8_t button; + bool down; + Vector2f pos; + }; + + struct PenTouchCallbackArgs { + bool down; + bool eraser; + Vector2f pos; + }; + + struct PenMotionCallbackArgs { + Vector2f pos; + Vector2f move; + }; + MainProgram& main; }; diff --git a/src/MainProgram.cpp b/src/MainProgram.cpp index 882f6ce..e00ef35 100755 --- a/src/MainProgram.cpp +++ b/src/MainProgram.cpp @@ -326,6 +326,12 @@ void MainProgram::input_key_callback(const InputManager::KeyCallbackArgs& key) { world->input_key_callback(key); } +void MainProgram::input_pure_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button) { +} + +void MainProgram::input_pure_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion) { +} + void MainProgram::input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button) { if(world) world->input_mouse_button_callback(button); @@ -341,6 +347,15 @@ void MainProgram::input_mouse_wheel_callback(const InputManager::MouseWheelCallb world->input_mouse_wheel_callback(wheel); } +void MainProgram::input_pen_button_callback(const InputManager::PenButtonCallbackArgs& button) { +} + +void MainProgram::input_pen_touch_callback(const InputManager::PenTouchCallbackArgs& touch) { +} + +void MainProgram::input_pen_motion_callback(const InputManager::PenMotionCallbackArgs& motion) { +} + bool MainProgram::network_being_used() { for(auto& w : worlds) { if(w->netObjMan.is_connected()) diff --git a/src/MainProgram.hpp b/src/MainProgram.hpp index 9d350e4..652864a 100644 --- a/src/MainProgram.hpp +++ b/src/MainProgram.hpp @@ -121,9 +121,14 @@ class MainProgram { std::string displayName; void input_key_callback(const InputManager::KeyCallbackArgs& key); + void input_pure_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button); + void input_pure_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion); void input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button); void input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion); void input_mouse_wheel_callback(const InputManager::MouseWheelCallbackArgs& wheel); + void input_pen_button_callback(const InputManager::PenButtonCallbackArgs& button); + void input_pen_touch_callback(const InputManager::PenTouchCallbackArgs& touch); + void input_pen_motion_callback(const InputManager::PenMotionCallbackArgs& motion); ~MainProgram(); private: diff --git a/src/main.cpp b/src/main.cpp index 84b2771..10a1eec 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -784,20 +784,9 @@ SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event) { } case SDL_EVENT_PEN_MOTION: { mS.m->update_scale_and_density(); - mS.m->input.pen.isEraser = event->pmotion.pen_state & SDL_PEN_INPUT_ERASER_TIP; - mS.m->input.mouse.set_pos({event->pmotion.x * mS.m->window.density, event->pmotion.y * mS.m->window.density}); - break; - } - case SDL_EVENT_PEN_DOWN: { - mS.m->input.pen.isDown = true; - mS.m->input.mouse.leftDown = true; - if((std::chrono::steady_clock::now() - mS.m->input.pen.lastPenLeftClickTime) > std::chrono::milliseconds(300)) - mS.m->input.pen.leftClicksSaved = 0; - mS.m->input.pen.leftClicksSaved++; - mS.m->input.mouse.leftClicks = mS.m->input.pen.leftClicksSaved; - mS.m->input.pen.lastPenLeftClickTime = std::chrono::steady_clock::now(); - mS.m->input.pen.isEraser = event->ptouch.eraser; - //mS.m->input.mouse.set_pos({event->ptouch.x, event->ptouch.y}); + mS.m->input.backend_pen_motion_update(event->pmotion); + //mS.m->input.pen.isEraser = event->pmotion.pen_state & SDL_PEN_INPUT_ERASER_TIP; + //mS.m->input.mouse.set_pos({event->pmotion.x * mS.m->window.density, event->pmotion.y * mS.m->window.density}); break; } case SDL_EVENT_PEN_AXIS: { @@ -806,22 +795,24 @@ SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event) { //mS.m->input.mouse.set_pos({event->paxis.x, event->paxis.y}); break; } + case SDL_EVENT_PEN_DOWN: { + mS.m->update_scale_and_density(); + mS.m->input.backend_pen_touch_down_update(event->ptouch); + break; + } case SDL_EVENT_PEN_UP: { - mS.m->input.pen.isDown = false; - mS.m->input.mouse.leftDown = false; - mS.m->input.pen.isEraser = event->ptouch.eraser; - mS.m->input.pen.pressure = 0.0; - //mS.m->input.mouse.set_pos({event->ptouch.x, event->ptouch.y}); + mS.m->update_scale_and_density(); + mS.m->input.backend_pen_touch_up_update(event->ptouch); break; } case SDL_EVENT_PEN_BUTTON_UP: { - mS.m->input.set_pen_button_up(event->pbutton); - //mS.m->input.mouse.set_pos({event->pbutton.x, event->pbutton.y}); + mS.m->update_scale_and_density(); + mS.m->input.backend_pen_button_up_update(event->pbutton); break; } case SDL_EVENT_PEN_BUTTON_DOWN: { - mS.m->input.set_pen_button_down(event->pbutton); - //mS.m->input.mouse.set_pos({event->pbutton.x, event->pbutton.y}); + mS.m->update_scale_and_density(); + mS.m->input.backend_pen_button_down_update(event->pbutton); break; } case SDL_EVENT_FINGER_DOWN: {