summaryrefslogtreecommitdiffhomepage
path: root/editor/events.cpp
blob: 109a3a39d71d4fdedd57fac32ec41d4195a1fec3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#include "app.hpp"
#include "main/floormat-main.hpp"
#include "main/floormat-events.hpp"
#include "src/world.hpp"
#include <utility>
#include <Magnum/ImGuiIntegration/Context.hpp>

namespace floormat {

#define accessor(type, name) \
    type m_##name = {}; auto name() const noexcept { return m_##name; }

bool app::on_mouse_move(const mouse_move_event& event) noexcept
{
    struct {
        accessor(Vector2i, position)
    } e = {event.position};

    cursor.in_imgui = _imgui.handleMouseMoveEvent(e);

    if (!cursor.in_imgui)
        cursor.pixel = event.position;
    else
        cursor.pixel = std::nullopt;
    recalc_cursor_tile();

    if (cursor.tile)
        _editor.on_mouse_move(M->world(), *cursor.tile);

    return true;
}

bool app::on_mouse_up_down(const mouse_button_event& event, bool is_down) noexcept
{
    enum class Button : std::underlying_type_t<mouse_button> {
        Left = mouse_button_left,
        Right = mouse_button_right,
        Middle = mouse_button_middle,
    };
    struct ev {
        using Button = Button;
        accessor(Vector2i, position)
        accessor(Button, button)
    } e = {event.position, Button(event.button)};

    if (!(cursor.in_imgui = is_down
                            ? _imgui.handleMousePressEvent(e)
                            : _imgui.handleMouseReleaseEvent(e)))
    {
        cursor.pixel = event.position;
        recalc_cursor_tile();
        if (cursor.tile)
        {
            if (event.button == mouse_button_left && is_down)
                _editor.on_click(M->world(), *cursor.tile);
            else
                _editor.on_release();
        }
    }

    return true;
}

bool app::on_mouse_scroll(const mouse_scroll_event& event) noexcept
{
    struct {
        accessor(Vector2, offset)
        accessor(Vector2i, position)
    } e = {event.offset, event.position};
    _imgui.handleMouseScrollEvent(e);
    return true;
}

bool app::on_key_up_down(const floormat::key_event& event, bool is_down) noexcept
{
    enum Modifier : std::underlying_type_t<SDL_Keymod> {
        None = KMOD_NONE,
        Ctrl = KMOD_CTRL,
        Shift = KMOD_SHIFT,
        Alt = KMOD_ALT,
        Super = KMOD_GUI,
    };
    struct {
        accessor(SDL_Keymod, modifiers)
    } e = {};
    if (!(is_down ? _imgui.handleKeyPressEvent(e) : _imgui.handleKeyReleaseEvent(e)))
    {
        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_F5:       return key::quicksave;
                               case SDLK_F9:       return key::quickload;
                               case SDLK_ESCAPE:   return key::quit;
        });
        if (x != key::COUNT)
            _keys[x] = is_down && !event.is_repeated;
    }
    return true;
}

bool app::on_text_input_event(const floormat::text_input_event& event) noexcept
{
    struct {
        accessor(Containers::StringView, text)
    } e = {event.text};
    if (_imgui.handleTextInputEvent(e))
        _keys = {};
    return true;
}

} // namespace floormat