summaryrefslogtreecommitdiffhomepage
path: root/editor/app.hpp
blob: e0168d68f7db196593f97a06d645d0749ae1f482 (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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
#pragma once
#include "compat/defs.hpp"
#include "compat/enum-bitset.hpp"
#include "editor.hpp"
#include "draw/wireframe.hpp"
#include "draw/quad-floor.hpp"
#include "draw/quad-wall-n.hpp"
#include "draw/quad-wall-w.hpp"
#include "draw/quad.hpp"
#include "draw/box.hpp"
#include "floormat/app.hpp"
#include "keys.hpp"
#include "object-id.hpp"
#include <memory>
#include <Corrade/Containers/Pointer.h>
#include <Corrade/Containers/Optional.h>
#include <Magnum/ImGuiIntegration/Context.h>

namespace floormat {

struct chunk;
struct floormat_main;
struct tile_atlas;
struct tile_editor;
struct fm_settings;
struct anim_atlas;
struct character;

struct cursor_state final {
    Optional<Vector2i> pixel;
    Optional<global_coords> tile;
    bool in_imgui = false;
};

struct clickable;

enum class Cursor: uint32_t {
    Arrow, TextInput, Wait, Crosshair, WaitArrow,
    ResizeNWSE, ResizeNESW, ResizeWE, ResizeNS, ResizeAll,
    No, Hand, Hidden, HiddenLocked,
};

enum class popup_target_type : unsigned char {
    none, scenery,
};

struct popup_target final {
    object_id id; // todo switch to weak_ptr<entity>
    popup_target_type target = popup_target_type::none;
    bool operator==(const popup_target&) const;
};

struct app final : floormat_app
{
    static int run_from_argv(int argc, const char* const* argv);
    static fm_settings parse_cmdline(int argc, const char* const* argv);
    ~app() override;
#ifdef _WIN32
    static void set_dpi_aware();
#endif
    object_id object_at_cursor();

private:
    using key_set = enum_bitset<key, key_COUNT>;

    app(fm_settings&& opts);

    fm_DECLARE_DELETED_COPY_ASSIGNMENT(app);
    fm_DECLARE_DEPRECATED_MOVE_ASSIGNMENT(app);

    int exec();

    void update(float dt) override;
    void update_world(float dt);
    void update_cursor_tile(const Optional<Vector2i>& pixel);
    z_bounds get_z_bounds() override;
    void set_cursor();
    void maybe_initialize_chunk(const chunk_coords_& pos, chunk& c) override;
    void maybe_initialize_chunk_(const chunk_coords_& pos, chunk& c);
    void update_character(float dt);
    void reset_world();
    void reset_world(struct world&& w);
    void ensure_player_character(world& w);

    void draw() override;

    void on_mouse_move(const mouse_move_event& event) noexcept override;
    void on_mouse_up_down(const mouse_button_event& event, bool is_down) noexcept override;
    void on_mouse_scroll(const mouse_scroll_event& event) noexcept override;
    void on_key_up_down(const key_event& event, bool is_down) noexcept override;
    std::tuple<key, int> resolve_keybinding(int k, int mods);
    void on_text_input_event(const text_input_event& event) noexcept override;
    //bool on_text_editing_event(const text_editing_event& event) noexcept override;
    void on_viewport_event(const Magnum::Math::Vector2<int>& size) noexcept override;
    void on_any_event(const any_event& event) noexcept override;
    void on_focus_in() noexcept override;
    void on_focus_out() noexcept override;
    void on_mouse_leave() noexcept override;
    void on_mouse_enter() noexcept override;

    void do_mouse_move(int modifiers);
    void do_mouse_up_down(uint8_t button, bool is_down, int modifiers);
    void do_mouse_scroll(int offset);

    void do_camera(float dt, const key_set& cmds, int mods);
    void reset_camera_offset();
    clickable* find_clickable_scenery(const Optional<Vector2i>& pixel);

    void do_quicksave();
    void do_quickload();
    void do_new_file();
    void do_escape();

    void draw_collision_boxes();
    void draw_clickables();
    void draw_light_info();
    void draw_lightmap_test();

    void draw_editor_pane(float main_menu_height);
    void draw_inspector();
    bool check_inspector_exists(const popup_target& p);
    void draw_editor_tile_pane_atlas(tile_editor& ed, StringView name, const std::shared_ptr<tile_atlas>& atlas);
    void draw_editor_scenery_pane(scenery_editor& ed);
    void draw_editor_vobj_pane(vobj_editor& ed);
    void set_cursor_from_imgui();
    void draw_cursor();
    void init_imgui(Vector2i size);
    void draw_ui();
    float draw_main_menu();
    void draw_fps();
    void draw_tile_under_cursor();
    void draw_z_level();
    void do_popup_menu();
    void kill_popups(bool hard);
    void render_menu();

    void do_key(key k, int mods);
    void do_key(key k);
    void do_set_mode(editor_mode mode);
    void do_rotate(bool backward);
    void apply_commands(const key_set& k);
    int get_key_modifiers();
    void clear_keys(key min_inclusive, key max_exclusive);
    void clear_keys();
    void clear_non_global_keys();
    void clear_non_repeated_keys();

    Containers::Pointer<floormat_main> M;
    ImGuiIntegration::Context _imgui{NoCreate};
    GL::Texture2D _wireframe_texture = wireframe::make_constant_texture();
    wireframe_mesh<wireframe::quad_floor>  _wireframe_quad   {_wireframe_texture};
    wireframe_mesh<wireframe::quad_wall_n> _wireframe_wall_n {_wireframe_texture};
    wireframe_mesh<wireframe::quad_wall_w> _wireframe_wall_w {_wireframe_texture};
    wireframe_mesh<wireframe::box>         _wireframe_box    {_wireframe_texture};
    wireframe_mesh<wireframe::quad>        _wireframe_rect   {_wireframe_texture};
    editor _editor{this};
    key_set keys;
    std::array<int, key_set::COUNT> key_modifiers = {};
    std::vector<popup_target> inspectors;
    object_id _character_id = 0;
    cursor_state cursor;
    popup_target _popup_target;

    object_id _tested_light = 0;

    int8_t _z_level = 0;

    bool _pending_popup         : 1 = false;
    bool _render_bboxes         : 1 = false;
    bool _render_clickables     : 1 = false;
    bool _render_vobjs          : 1 = true;
    bool _render_all_z_levels   : 1 = true;
    bool _testing_light         : 1 = false;
};

} // namespace floormat