summaryrefslogtreecommitdiffhomepage
path: root/editor/events.cpp
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2022-10-31 21:41:46 +0100
committerStanislaw Halik <sthalik@misaki.pl>2022-10-31 21:41:46 +0100
commit4accaa62047f27bcf1ea28e1e68db33e50c335df (patch)
treea591529bce4fcb7b31164363a435fdca6dadb443 /editor/events.cpp
parent089f188a5b68c87f2be32b465624841fd3c2b44f (diff)
a
Diffstat (limited to 'editor/events.cpp')
-rw-r--r--editor/events.cpp107
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