yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
dungeon_canvas_room_frame.cc
Go to the documentation of this file.
2#include "util/i18n/tr.h"
3
4#include <algorithm>
5#include <cmath>
6
9#include "imgui/imgui.h"
10
11namespace yaze::editor {
12
13namespace {
14
15using namespace dungeon_ui; // NOLINT(google-build-using-namespace)
16
17} // namespace
18
20 if (room_id < 0 || room_id >= zelda3::kNumberOfRooms) {
21 ImGui::Text(tr("Invalid room ID: %d"), room_id);
22 return false;
23 }
24
25 if (!rom_ || !rom_->is_loaded()) {
26 ImGui::Text(tr("ROM not loaded"));
27 return false;
28 }
29
30 return true;
31}
32
34 const {
35 gui::CanvasFrameOptions frame_opts;
36 frame_opts.canvas_size = ImVec2(kDungeonRoomPixelSize, kDungeonRoomPixelSize);
37 const ImVec2 available = ImGui::GetContentRegionAvail();
38 frame_opts.viewport_size =
39 ImVec2(std::max(1.0f, available.x), std::max(1.0f, available.y));
40 frame_opts.draw_grid = show_grid_;
41 frame_opts.grid_step = static_cast<float>(custom_grid_size_);
42 frame_opts.draw_context_menu = true;
43 frame_opts.draw_overlay = true;
44 frame_opts.render_popups = true;
45 return frame_opts;
46}
47
49 const float fit_scale =
50 std::max(0.001f, std::min(viewport_size.x, viewport_size.y) /
51 kDungeonRoomPixelSize);
52 const float current_scale = canvas_.global_scale();
54 // The initial 1x Canvas value is its default. A supplied non-default zoom
55 // is intentional and remains centered until Fit is requested.
56 room_viewport_auto_fit_ = std::abs(current_scale - 1.0f) < 0.0001f;
57 } else if (std::abs(current_scale - room_viewport_last_scale_) > 0.0001f) {
59 }
60 // Selection/find requests should reveal their tile without reintroducing
61 // free pan. Retain explicit zoom when the tile is already visible; otherwise
62 // return to Fit before BeginCanvas creates drawing and input geometry.
64 const auto [tile_x, tile_y] = *pending_scroll_target_;
65 constexpr float kTileSize = 8.0f;
66 const float tile_size = kTileSize * current_scale;
67 const ImVec2 centered(
68 (viewport_size.x - kDungeonRoomPixelSize * current_scale) * 0.5f,
69 (viewport_size.y - kDungeonRoomPixelSize * current_scale) * 0.5f);
70 const ImVec2 target(centered.x + std::clamp(tile_x, 0, 63) * tile_size,
71 centered.y + std::clamp(tile_y, 0, 63) * tile_size);
72 if (target.x < 0 || target.y < 0 ||
73 target.x + tile_size > viewport_size.x ||
74 target.y + tile_size > viewport_size.y) {
76 }
77 }
79 canvas_.set_global_scale(fit_scale);
80 }
82 const float room_size = kDungeonRoomPixelSize * room_viewport_last_scale_;
83 canvas_.set_scrolling(ImVec2((viewport_size.x - room_size) * 0.5f,
84 (viewport_size.y - room_size) * 0.5f));
85}
86
88 gui::CanvasRuntime& canvas_rt) {
89 auto& io = ImGui::GetIO();
90 if (canvas_rt.hovered && (io.MouseWheel != 0 || io.MouseWheelH != 0)) {
91 const bool tool_active = crumble_floor_view_.rehearsing() ||
95 const bool resize_object =
96 object_interaction_enabled_ && !tool_active &&
99 if (resize_object) {
101 }
102 io.MouseWheel = 0;
103 io.MouseWheelH = 0;
104 }
105
106 // Normal room view stays centered, including explicit zoom and restored
107 // offsets. Free navigation belongs to the separate stitched-room overview.
109 canvas_rt.scrolling = canvas_.scrolling();
110 canvas_rt.scale = canvas_.global_scale();
111}
112
114 auto canvas_config = canvas_.GetConfig();
115 canvas_config.enable_grid = show_grid_;
116 canvas_config.grid_step = static_cast<float>(custom_grid_size_);
117 canvas_config.is_draggable = false;
118 // Main dungeon canvas is an editable scratchpad: users paint tiles into
119 // the room and manipulate object/sprite/door entities directly. Declaring
120 // the role lets future canvas surfaces default appropriately without each
121 // editor re-encoding the policy.
122 canvas_config.role = gui::CanvasRole::kEditableScratchpad;
123 canvas_.ApplyConfigSnapshot(canvas_config);
125}
126
128 const auto& config = canvas_.GetConfig();
129 show_grid_ = config.enable_grid;
130 set_custom_grid_size(static_cast<int>(config.grid_step));
131}
132
134 int room_id) {
135 if (prev_blockset_ != room.blockset() || prev_palette_ != room.palette() ||
136 prev_layout_ != room.layout_id() || prev_spriteset_ != room.spriteset()) {
137 if (room.rom() && room.rom()->is_loaded()) {
139 }
140
141 prev_blockset_ = room.blockset();
142 prev_palette_ = room.palette();
143 prev_layout_ = room.layout_id();
144 prev_spriteset_ = room.spriteset();
145 }
146
147 if (header_visible_) {
148 DrawRoomHeader(room, room_id);
149 }
150}
151
153 int room_id) {
154 if (!rooms_) {
155 return nullptr;
156 }
157
158 auto* room_ptr = rooms_->TryEnsureRoom(room_id);
159 if (!room_ptr) {
160 return nullptr;
161 }
162 auto& room = *room_ptr;
163 RefreshActiveRoomCanvasState(room, room_id);
164 return &room;
165}
166
167} // namespace yaze::editor
bool is_loaded() const
Definition rom.h:187
void RefreshActiveRoomCanvasState(zelda3::Room &room, int room_id)
std::optional< std::pair< int, int > > pending_scroll_target_
zelda3::Room * PrepareActiveRoomForCanvasFrame(int room_id)
DungeonObjectInteraction object_interaction_
void UpdateRoomCanvasViewport(ImVec2 viewport_size)
gui::CanvasFrameOptions BuildRoomCanvasFrameOptions() const
void DrawRoomHeader(zelda3::Room &room, int room_id)
MinecartTrackEditorPanel * minecart_track_panel_
void HandleRoomCanvasNavigation(gui::CanvasRuntime &canvas_rt)
std::vector< size_t > GetSelectedObjectIndices() const
InteractionCoordinator & entity_coordinator()
Get the interaction coordinator for entity handling.
zelda3::Room * TryEnsureRoom(int room_id)
bool IsPlacementActive() const
Check if any placement mode is active.
void set_scrolling(ImVec2 scroll)
Definition canvas.h:367
auto global_scale() const
Definition canvas.h:413
void ApplyConfigSnapshot(const CanvasConfig &snapshot)
Definition canvas.cc:1038
void set_global_scale(float scale)
Definition canvas.cc:323
void SetShowBuiltinContextMenu(bool show)
Definition canvas.h:220
CanvasConfig & GetConfig()
Definition canvas.h:243
auto scrolling() const
Definition canvas.h:366
uint8_t blockset() const
Definition room.h:1015
void ReloadGraphics(std::optional< uint8_t > entrance_blockset=std::nullopt)
Definition room.cc:1047
uint8_t palette() const
Definition room.h:1019
auto rom() const
Definition room.h:1082
uint8_t spriteset() const
Definition room.h:1018
uint8_t layout_id() const
Definition room.h:1026
Editors are the view controllers for the application.
constexpr int kNumberOfRooms
std::optional< ImVec2 > viewport_size
std::optional< float > grid_step