Start using pen input events

This commit is contained in:
Yousef Khadadeh 2026-03-03 14:59:18 +03:00
parent 451bf9b6b2
commit 5b6316bd15
5 changed files with 208 additions and 41 deletions

View file

@ -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<MouseButton>(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<MouseButton>(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;

View file

@ -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<KeyData, 256> 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<std::string, RichText::TextData>& 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;
};

View file

@ -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())

View file

@ -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:

View file

@ -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: {