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() ||
96 const bool resize_object =
97 object_interaction_enabled_ && !tool_active &&
100 if (resize_object) {
102 }
103 io.MouseWheel = 0;
104 io.MouseWheelH = 0;
105 }
106
107 // Normal room view stays centered, including explicit zoom and restored
108 // offsets. Free navigation belongs to the separate stitched-room overview.
110 canvas_rt.scrolling = canvas_.scrolling();
111 canvas_rt.scale = canvas_.global_scale();
112}
113
115 auto canvas_config = canvas_.GetConfig();
116 canvas_config.enable_grid = show_grid_;
117 canvas_config.grid_step = static_cast<float>(custom_grid_size_);
118 canvas_config.is_draggable = false;
119 // Main dungeon canvas is an editable scratchpad: users paint tiles into
120 // the room and manipulate object/sprite/door entities directly. Declaring
121 // the role lets future canvas surfaces default appropriately without each
122 // editor re-encoding the policy.
123 canvas_config.role = gui::CanvasRole::kEditableScratchpad;
124 canvas_.ApplyConfigSnapshot(canvas_config);
126}
127
129 const auto& config = canvas_.GetConfig();
130 show_grid_ = config.enable_grid;
131 set_custom_grid_size(static_cast<int>(config.grid_step));
132}
133
135 int room_id) {
136 if (prev_blockset_ != room.blockset() || prev_palette_ != room.palette() ||
137 prev_layout_ != room.layout_id() || prev_spriteset_ != room.spriteset()) {
138 if (room.rom() && room.rom()->is_loaded()) {
140 }
141
142 prev_blockset_ = room.blockset();
143 prev_palette_ = room.palette();
144 prev_layout_ = room.layout_id();
145 prev_spriteset_ = room.spriteset();
146 }
147
148 if (header_visible_) {
149 DrawRoomHeader(room, room_id);
150 }
151}
152
154 int room_id) {
155 if (!rooms_) {
156 return nullptr;
157 }
158
159 auto* room_ptr = rooms_->TryEnsureRoom(room_id);
160 if (!room_ptr) {
161 return nullptr;
162 }
163 auto& room = *room_ptr;
164 RefreshActiveRoomCanvasState(room, room_id);
165 return &room;
166}
167
168} // namespace yaze::editor
bool is_loaded() const
Definition rom.h:199
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.
const std::optional< MinecartToolPayload > & placement_brush() const
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:1039
void set_global_scale(float scale)
Definition canvas.cc:324
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