diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2022-10-31 21:41:46 +0100 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2022-10-31 21:41:46 +0100 |
commit | 4accaa62047f27bcf1ea28e1e68db33e50c335df (patch) | |
tree | a591529bce4fcb7b31164363a435fdca6dadb443 /editor/events.cpp | |
parent | 089f188a5b68c87f2be32b465624841fd3c2b44f (diff) |
a
Diffstat (limited to 'editor/events.cpp')
-rw-r--r-- | editor/events.cpp | 107 |
1 files changed, 77 insertions, 30 deletions
diff --git a/editor/events.cpp b/editor/events.cpp index 8a665c64..fc8693af 100644 --- a/editor/events.cpp +++ b/editor/events.cpp @@ -3,12 +3,16 @@ #include "floormat/main.hpp" #include "floormat/events.hpp" #include "src/world.hpp" +#include "keys.hpp" #include <utility> #include <Magnum/Platform/Sdl2Application.h> #include <Magnum/ImGuiIntegration/Context.hpp> +#include <SDL_keycode.h> +#include <SDL_events.h> + namespace floormat { void app::on_focus_in() noexcept {} @@ -18,11 +22,21 @@ void app::on_any_event(const any_event&) noexcept {} #define accessor(type, name) \ type m_##name = {}; auto name() const noexcept { return m_##name; } -void app::clear_non_global_keys() +void app::clear_keys(key min_inclusive, key max_exclusive) { using key_type = decltype(keys)::value_type; - for (key i = key::MIN; i < key::GLOBAL; i = key{key_type(i) + 1}) - keys[i] = false; + for (key_type i = key_type(min_inclusive); i < key_type(max_exclusive); i++) + { + const auto idx = key(i); + keys[idx] = false; + key_modifiers[i] = kmod_none; + } +} + +void app::clear_keys() +{ + keys.reset(); + key_modifiers = {}; } void app::on_mouse_move(const mouse_move_event& event) noexcept @@ -33,7 +47,7 @@ void app::on_mouse_move(const mouse_move_event& event) noexcept cursor.in_imgui = _imgui.handleMouseMoveEvent(e); update_cursor_tile(event.position); - do_mouse_move(); + do_mouse_move(event.mods); } void app::on_mouse_up_down(const mouse_button_event& event, bool is_down) noexcept @@ -50,9 +64,7 @@ void app::on_mouse_up_down(const mouse_button_event& event, bool is_down) noexce } e = {event.position, Button(event.button)}; if (!(cursor.in_imgui = is_down ? _imgui.handleMousePressEvent(e) : _imgui.handleMouseReleaseEvent(e))) - do_mouse_up_down(event.button, is_down); - else - clear_non_global_keys(); + do_mouse_up_down(event.button, is_down, event.mods); } void app::on_mouse_scroll(const mouse_scroll_event& event) noexcept @@ -64,6 +76,21 @@ void app::on_mouse_scroll(const mouse_scroll_event& event) noexcept _imgui.handleMouseScrollEvent(e); } +static constexpr int fixup_mods_(int mods, int value, int mask) +{ + return !!(mods & mask) * value; +} + +static constexpr int fixup_mods(int mods) +{ + int ret = 0; + ret |= fixup_mods_(mods, kmod_ctrl, KMOD_CTRL); + ret |= fixup_mods_(mods, kmod_shift, KMOD_SHIFT); + ret |= fixup_mods_(mods, kmod_alt, KMOD_ALT); + ret |= fixup_mods_(mods, kmod_super, KMOD_GUI); + return ret; +} + void app::on_key_up_down(const key_event& event, bool is_down) noexcept { using KeyEvent = Platform::Sdl2Application::KeyEvent; @@ -75,29 +102,39 @@ void app::on_key_up_down(const key_event& event, bool is_down) noexcept accessor(Modifiers, modifiers) } e = {Ev::Key(event.key), Ev::Modifier(event.mods)}; - if (!(is_down ? _imgui.handleKeyPressEvent(e) : _imgui.handleKeyReleaseEvent(e))) - { - // todo put it into a separate function - const key x = fm_begin(switch (event.key) { - default: return key::COUNT; - case SDLK_w: return key::camera_up; - case SDLK_a: return key::camera_left; - case SDLK_s: return key::camera_down; - case SDLK_d: return key::camera_right; - case SDLK_HOME: return key::camera_reset; - case SDLK_r: return key::rotate_tile; - case SDLK_1: return key::mode_none; - case SDLK_2: return key::mode_floor; - case SDLK_3: return key::mode_walls; - case SDLK_F5: return key::quicksave; - case SDLK_F9: return key::quickload; - case SDLK_ESCAPE: return key::quit; - }); - if (x != key::COUNT && (!event.is_repeated || (key)x < key::NO_REPEAT)) - keys[x] = is_down; - } - else + [[maybe_unused]] constexpr int CTRL = kmod_ctrl; + [[maybe_unused]] constexpr int SHIFT = kmod_shift; + [[maybe_unused]] constexpr int ALT = kmod_alt; + [[maybe_unused]] constexpr int SUPER = kmod_super; + + const auto mods = fixup_mods(event.mods); + + const key x = fm_begin(switch (auto k = event.key | mods) { + default: return key_COUNT; + case SDLK_w: return key_camera_up; + case SDLK_a: return key_camera_left; + case SDLK_s: return key_camera_down; + case SDLK_d: return key_camera_right; + case SDLK_HOME: return key_camera_reset; + case SDLK_r: return key_rotate_tile; + case SDLK_1: return key_mode_none; + case SDLK_2: return key_mode_floor; + case SDLK_3: return key_mode_walls; + case SDLK_F5: return key_quicksave; + case SDLK_F9: return key_quickload; + case SDLK_q | CTRL: return key_quit; + }); + + if (x == key_COUNT) + void(); + else if (x >= key_NO_REPEAT) + !event.is_repeated ? do_key(x, mods) : void(); + else if (is_down ? _imgui.handleKeyPressEvent(e) : _imgui.handleKeyReleaseEvent(e)) clear_non_global_keys(); + else { + keys[x] = is_down; + key_modifiers[std::size_t(x)] = event.mods; + } } void app::on_text_input_event(const text_input_event& event) noexcept @@ -117,7 +154,7 @@ void app::on_viewport_event(const Math::Vector2<int>& size) noexcept void app::on_focus_out() noexcept { update_cursor_tile(std::nullopt); - keys = {}; + clear_keys(); } void app::on_mouse_leave() noexcept @@ -125,4 +162,14 @@ void app::on_mouse_leave() noexcept update_cursor_tile(std::nullopt); } +void app::do_key(floormat::key k) +{ + do_key(k, SDL_GetModState()); +} + +int app::get_key_modifiers() +{ + return fixup_mods(SDL_GetModState()); +} + } // namespace floormat |