diff --git a/libopenage/input/input_manager.cpp b/libopenage/input/input_manager.cpp index 58bca7fb9e..4857863eb1 100644 --- a/libopenage/input/input_manager.cpp +++ b/libopenage/input/input_manager.cpp @@ -1,4 +1,4 @@ -// Copyright 2015-2023 the openage authors. See copying.md for legal info. +// Copyright 2015-2024 the openage authors. See copying.md for legal info. #include "input_manager.h" @@ -9,6 +9,7 @@ #include "input/input_context.h" #include "renderer/gui/guisys/public/gui_input.h" + namespace openage::input { InputManager::InputManager() : @@ -131,7 +132,8 @@ bool InputManager::process(const QEvent &ev) { input::Event input_ev{ev}; // Check context list on top of the stack (most recent bound first) - for (auto const &ctx : this->active_contexts) { + for (size_t i = this->active_contexts.size(); i > 0; --i) { + auto &ctx = this->active_contexts.at(i - 1); if (ctx->is_bound(input_ev)) { auto &actions = ctx->lookup(input_ev); for (auto const &action : actions) { diff --git a/libopenage/input/tests.cpp b/libopenage/input/tests.cpp index b97efb9219..11860e6449 100644 --- a/libopenage/input/tests.cpp +++ b/libopenage/input/tests.cpp @@ -87,16 +87,40 @@ void action_demo() { input_action catch_all{input_action_t::CUSTOM, nop}; // events that map to specific keys/buttons - Event ev_up{event_class::KEYBOARD, Qt::Key_Up, Qt::NoModifier, QEvent::KeyRelease}; - Event ev_down{event_class::KEYBOARD, Qt::Key_Down, Qt::NoModifier, QEvent::KeyRelease}; - - Event ev_w{event_class::KEYBOARD, Qt::Key_W, Qt::NoModifier, QEvent::KeyRelease}; - Event ev_a{event_class::KEYBOARD, Qt::Key_A, Qt::NoModifier, QEvent::KeyRelease}; - Event ev_s{event_class::KEYBOARD, Qt::Key_S, Qt::NoModifier, QEvent::KeyRelease}; - Event ev_d{event_class::KEYBOARD, Qt::Key_D, Qt::NoModifier, QEvent::KeyRelease}; - - Event ev_lmb{event_class::MOUSE, Qt::LeftButton, Qt::NoModifier, QEvent::MouseButtonRelease}; - Event ev_rmb{event_class::MOUSE, Qt::RightButton, Qt::NoModifier, QEvent::MouseButtonRelease}; + Event ev_up{event_class::KEYBOARD, + Qt::Key::Key_Up, + Qt::KeyboardModifier::NoModifier, + QEvent::KeyRelease}; + Event ev_down{event_class::KEYBOARD, + Qt::Key::Key_Down, + Qt::KeyboardModifier::NoModifier, + QEvent::KeyRelease}; + + Event ev_w{event_class::KEYBOARD, + Qt::Key::Key_W, + Qt::KeyboardModifier::NoModifier, + QEvent::KeyRelease}; + Event ev_a{event_class::KEYBOARD, + Qt::Key::Key_A, + Qt::KeyboardModifier::NoModifier, + QEvent::KeyRelease}; + Event ev_s{event_class::KEYBOARD, + Qt::Key::Key_S, + Qt::KeyboardModifier::NoModifier, + QEvent::KeyRelease}; + Event ev_d{event_class::KEYBOARD, + Qt::Key::Key_D, + Qt::KeyboardModifier::NoModifier, + QEvent::KeyRelease}; + + Event ev_lmb{event_class::MOUSE_BUTTON, + Qt::MouseButton::LeftButton, + Qt::KeyboardModifier::NoModifier, + QEvent::MouseButtonRelease}; + Event ev_rmb{event_class::MOUSE_BUTTON, + Qt::MouseButton::RightButton, + Qt::KeyboardModifier::NoModifier, + QEvent::MouseButtonRelease}; // bind events to actions in the contexts mgr.get_global_context()->bind(ev_up, push_a); diff --git a/libopenage/presenter/presenter.cpp b/libopenage/presenter/presenter.cpp index 38c741f8fd..64df9bc05a 100644 --- a/libopenage/presenter/presenter.cpp +++ b/libopenage/presenter/presenter.cpp @@ -217,6 +217,9 @@ void Presenter::init_input() { this->input_manager->process(ev); }); this->window->add_mouse_button_callback([&](const QMouseEvent &ev) { + this->input_manager->process(ev); + }); + this->window->add_mouse_move_callback([&](const QMouseEvent &ev) { this->input_manager->set_mouse(ev.position().x(), ev.position().y()); this->input_manager->process(ev); }); diff --git a/libopenage/renderer/opengl/window.cpp b/libopenage/renderer/opengl/window.cpp index 8389c6e241..5f75717540 100644 --- a/libopenage/renderer/opengl/window.cpp +++ b/libopenage/renderer/opengl/window.cpp @@ -122,13 +122,18 @@ void GlWindow::update() { } break; case QEvent::MouseButtonPress: case QEvent::MouseButtonRelease: - case QEvent::MouseMove: case QEvent::MouseButtonDblClick: { auto const ev = std::dynamic_pointer_cast(event); for (auto &cb : this->on_mouse_button) { cb(*ev); } } break; + case QEvent::MouseMove: { + auto const ev = std::dynamic_pointer_cast(event); + for (auto &cb : this->on_mouse_move) { + cb(*ev); + } + } break; case QEvent::Wheel: { auto const ev = std::dynamic_pointer_cast(event); for (auto &cb : this->on_mouse_wheel) { diff --git a/libopenage/renderer/window.cpp b/libopenage/renderer/window.cpp index 497f36c535..88dbefb92e 100644 --- a/libopenage/renderer/window.cpp +++ b/libopenage/renderer/window.cpp @@ -39,6 +39,10 @@ void Window::add_mouse_button_callback(const mouse_button_cb_t &cb) { this->on_mouse_button.push_back(cb); } +void Window::add_mouse_move_callback(const mouse_move_cb_t &cb) { + this->on_mouse_move.push_back(cb); +} + void Window::add_mouse_wheel_callback(const mouse_wheel_cb_t &cb) { this->on_mouse_wheel.push_back(cb); } diff --git a/libopenage/renderer/window.h b/libopenage/renderer/window.h index 2ac9c13430..71960e2d17 100644 --- a/libopenage/renderer/window.h +++ b/libopenage/renderer/window.h @@ -79,6 +79,7 @@ class Window { using key_cb_t = std::function; using mouse_button_cb_t = std::function; + using mouse_move_cb_t = std::function; using mouse_wheel_cb_t = std::function; using resize_cb_t = std::function; @@ -96,6 +97,13 @@ class Window { */ void add_mouse_button_callback(const mouse_button_cb_t &cb); + /** + * Register a function that executes when the mouse is moved. + * + * @param cb Callback function. + */ + void add_mouse_move_callback(const mouse_move_cb_t &cb); + /** * Register a function that executes when a mouse wheel action is used. * @@ -173,6 +181,11 @@ class Window { */ std::vector on_mouse_button; + /** + * Callbacks for mouse move actions. + */ + std::vector on_mouse_move; + /** * Callbacks for mouse wheel actions. */