yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
dungeon_workbench_content.h
Go to the documentation of this file.
1#ifndef YAZE_APP_EDITOR_DUNGEON_WORKSPACE_DUNGEON_WORKBENCH_CONTENT_H
2#define YAZE_APP_EDITOR_DUNGEON_WORKSPACE_DUNGEON_WORKBENCH_CONTENT_H
3
4#include <cstdint>
5#include <deque>
6#include <functional>
7#include <memory>
8#include <optional>
9#include <string>
10#include <unordered_map>
11#include <utility>
12#include <vector>
13
17
18namespace yaze {
19class Rom;
20} // namespace yaze
21
22namespace yaze::zelda3 {
23class PitDamageTable;
24} // namespace yaze::zelda3
25
26namespace yaze::editor {
27
28class DungeonCanvasViewer;
29class DungeonMapPanel;
30class DungeonEntrancesPanel;
31class DungeonRoomSelector;
32class RoomMatrixContent;
33class CustomCollisionPanel;
34class MinecartTrackEditorPanel;
35class RoomTagEditorPanel;
36class WaterFillPanel;
37enum class RoomSelectionIntent;
38
40 bool show_left = false;
41 bool show_right = false;
42 bool compact_left = false;
43 bool compact_right = false;
44};
45
54
56 bool visible = false;
57 float min_x = 0.0f;
58 float min_y = 0.0f;
59 float max_x = 0.0f;
60 float max_y = 0.0f;
61};
62
67
72
73DungeonWorkbenchResponsiveLayout ResolveDungeonWorkbenchResponsiveLayout(
74 float total_width, float min_canvas_width, float min_sidebar_width,
75 float splitter_width, bool want_left, bool want_right);
76
77DungeonWorkbenchPaneLayout ResolveDungeonWorkbenchPaneLayout(
78 float total_width, float min_canvas_width, float min_sidebar_width,
79 float splitter_width, float stored_left_width, float stored_right_width,
80 bool want_left, bool want_right);
81
82// An already-open standalone tool owns its WindowContent for that frame. Route
83// repeated Workbench requests back to that window instead of drawing the same
84// instance in both presentations.
86 bool standalone_window_open);
87
88// Single stable window for dungeon editing. This is step 2 in the Workbench plan.
90 public:
92 DungeonRoomSelector* room_selector, int* current_room_id,
93 std::function<void(int)> on_room_selected,
94 std::function<void(int, RoomSelectionIntent)>
95 on_room_selected_with_intent,
96 std::function<void(int)> on_save_room,
97 std::function<void()> on_save_all_rooms,
98 std::function<DungeonCanvasViewer*()> get_viewer,
99 std::function<DungeonCanvasViewer*(int)> get_compare_viewer,
100 std::function<const std::deque<int>&()> get_recent_rooms,
101 std::function<void(int)> forget_recent_room,
102 std::function<void(bool)> set_workflow_mode, Rom* rom = nullptr);
104
105 std::string GetId() const override;
106 std::string GetDisplayName() const override;
107 std::string GetIcon() const override;
108 std::string GetEditorCategory() const override;
109 int GetPriority() const override;
110 std::string GetWorkflowGroup() const override { return "Core"; }
111
112 void SetRom(Rom* rom);
114 CustomCollisionPanel* custom_collision,
115 WaterFillPanel* water_fill,
116 MinecartTrackEditorPanel* minecart_tracks);
118 object_coverage_content_ = object_coverage;
119 }
120 void SetEmbeddedEditorPanels(WindowContent* object_selector,
121 WindowContent* door_editor,
122 WindowContent* sprite_editor,
123 WindowContent* item_editor,
124 WindowContent* room_graphics,
125 WindowContent* palette_editor);
127 DungeonEntrancesPanel* entrances) {
128 room_matrix_content_ = room_matrix;
129 entrance_navigator_content_ = entrances;
130 }
131 void SetRoomRenderContextCallback(std::function<void(int)> callback) {
132 prepare_room_render_context_ = std::move(callback);
133 }
135 std::function<bool(const std::string&)> is_window_open,
136 std::function<bool(const std::string&)> open_and_focus_window) {
137 is_standalone_tool_open_ = std::move(is_window_open);
138 open_and_focus_standalone_tool_ = std::move(open_and_focus_window);
139 }
140 void SetOpenKeyboardShortcutsCallback(std::function<void()> callback) {
141 open_keyboard_shortcuts_ = std::move(callback);
142 }
144 std::function<zelda3::PitDamageTable*()> provider) {
145 get_pit_damage_table_ = std::move(provider);
146 }
147 void FocusRoomInspector();
149 void FocusRoomMatrix();
151 void ShowConnectedGraph();
153 // Opens the read-only Proposal Preview window (room renders + overlay).
155 // Loads an overlay file; returns false and records the error on failure.
156 bool LoadProposalOverlay(const std::string& path);
157 const std::optional<DungeonProposalOverlay>& proposal_overlay() const {
158 return proposal_overlay_;
159 }
160 const std::string& proposal_error() const { return proposal_error_; }
162 void OpenDoorTool();
163 void OpenSpriteTool();
164 void OpenItemTool();
166 void OpenPaletteTool();
167 void OpenRoomTagsTool();
169 void OpenWaterFillTool();
170 void OpenMinecartTool();
172 bool PopOutActiveTool();
173
174 // Mirror toggle: when true, the inspector renders on the LEFT and the
175 // sidebar renders on the RIGHT (ZScream-style). Width semantics are
176 // preserved (layout_state_.right_width is still the inspector's width),
177 // so splitter drags still affect the correct pane regardless of side.
178 void SetInspectorOnLeft(bool on_left) { inspector_on_left_ = on_left; }
179 bool IsInspectorOnLeft() const { return inspector_on_left_; }
180 // Wired by the editor to persist the user's mirror choice in UserSettings.
181 // Called when the in-inspector swap-side button is clicked.
182 void SetOnInspectorSideChanged(std::function<void(bool)> cb) {
183 on_inspector_side_changed_ = std::move(cb);
184 }
186 std::function<void(DungeonCanvasViewer&)> cb) {
187 on_primary_canvas_drawn_ = std::move(cb);
188 }
189
190 // Lightweight state probes for unit tests; production rendering remains
191 // driven by the Workbench inspector.
193 const char* GetInspectorModeIdForTesting() const;
194 const char* GetActiveToolIdForTesting() const;
195 const char* GetSidebarModeIdForTesting() const;
197 DrawPitDamageControls(room_id);
198 }
203 void SetAllSaveFlagsForTesting(bool value) { SetAllSaveFlags(value); }
204
206 void NotifyRoomChanged(int previous_room_id) {
207 previous_room_id_ = previous_room_id;
208 }
209
210 // Wire undo/redo state from the editor's UndoManager.
211 void SetUndoRedoProvider(std::function<bool()> can_undo,
212 std::function<bool()> can_redo,
213 std::function<void()> on_undo,
214 std::function<void()> on_redo,
215 std::function<std::string()> undo_desc,
216 std::function<std::string()> redo_desc,
217 std::function<int()> undo_depth) {
218 can_undo_ = std::move(can_undo);
219 can_redo_ = std::move(can_redo);
220 on_undo_ = std::move(on_undo);
221 on_redo_ = std::move(on_redo);
222 undo_desc_ = std::move(undo_desc);
223 redo_desc_ = std::move(redo_desc);
224 undo_depth_ = std::move(undo_depth);
225 }
226
227 void Draw(bool* p_open) override;
228
229 private:
231 enum class WorkbenchTool : uint8_t {
232 None,
233 RoomTags,
235 WaterFill,
243 Palette,
244 };
245
246 void DrawSidebarPane(float width, float height, float button_size,
247 bool compact);
248 void DrawSidebarHeader(float button_size, bool compact);
249 void DrawSidebarModeTabs();
250 void DrawSidebarContent();
251 void DrawCanvasPane(float width, float height,
252 DungeonCanvasViewer* primary_viewer);
253 void DrawSplitView(DungeonCanvasViewer& primary_viewer);
254 void DrawInspectorPane(float width, float height, float button_size,
255 bool compact, DungeonCanvasViewer* viewer);
256 void DrawInspectorHeader(float button_size, bool compact);
257 void DrawInspector(DungeonCanvasViewer& viewer, bool compact);
258 void DrawInspectorShelf(DungeonCanvasViewer& viewer, bool compact);
262 void DrawSelectedObjectActions(DungeonCanvasViewer& viewer, size_t index);
266 void OpenTool(WorkbenchTool tool);
267 void CloseToolInspector();
269 bool IsStandaloneToolOpen(WorkbenchTool tool) const;
271 const char* GetWorkbenchToolId(WorkbenchTool tool) const;
272 const char* GetWorkbenchToolShortLabel(WorkbenchTool tool) const;
274 void DrawApplyScopeControls(int room_id);
275 void DrawPitDamageControls(int room_id);
279 void SetAllSaveFlags(bool value);
280
281 // Lazily build a room_id → dungeon_name cache from ROM entrance tables so the
282 // room badge can show accurate group context for custom Oracle dungeons.
284
286 int* current_room_id_ = nullptr;
287
288 // Workbench-owned UI state (was in DungeonEditorV2, moved here Phase 6.2).
294 std::function<void(int)> on_room_selected_;
296 std::function<void(int)> on_save_room_;
297 std::function<void()> on_save_all_rooms_;
300 std::function<const std::deque<int>&()> get_recent_rooms_;
301 std::function<void(int)> forget_recent_room_;
302 std::function<void(bool)> set_workflow_mode_;
303 std::function<bool(const std::string&)> is_standalone_tool_open_;
304 std::function<bool(const std::string&)> open_and_focus_standalone_tool_;
305 std::function<void()> open_keyboard_shortcuts_;
306 std::function<void(bool)> on_inspector_side_changed_;
308 std::function<void(int)> prepare_room_render_context_;
310 Rom* rom_ = nullptr;
311
312 enum class SidebarMode : uint8_t { Objects, Sprites, Doors, Items };
315 enum class InspectorMode : uint8_t { Inspect, Tools };
318
319 char compare_search_buf_[64] = {};
320
321 // ROM-based room→dungeon group label cache (lazy-built on first room render).
322 std::unordered_map<int, std::string> room_dungeon_cache_;
324
325 // Undo/redo providers (set via SetUndoRedoProvider).
326 std::function<bool()> can_undo_;
327 std::function<bool()> can_redo_;
328 std::function<void()> on_undo_;
329 std::function<void()> on_redo_;
330 std::function<std::string()> undo_desc_;
331 std::function<std::string()> redo_desc_;
332 std::function<int()> undo_depth_;
333
335
336 // Proposal Preview window state (read-only review of layout proposals).
338 char proposal_path_[1024] = {};
339 std::optional<DungeonProposalOverlay> proposal_overlay_;
340 std::string proposal_error_;
341 std::vector<char> proposal_layer_visible_;
343 float proposal_scale_ = 1.0f;
350 std::unique_ptr<DungeonMapPanel> embedded_dungeon_map_;
364};
365
366} // namespace yaze::editor
367
368#endif // YAZE_APP_EDITOR_DUNGEON_WORKSPACE_DUNGEON_WORKBENCH_CONTENT_H
The Rom class is used to load, save, and modify Rom data. This is a generic SNES ROM container and do...
Definition rom.h:49
WindowContent for displaying and editing dungeon entrances.
WindowContent for displaying multiple rooms in a spatial dungeon layout.
Handles room and entrance selection UI.
void DrawInspector(DungeonCanvasViewer &viewer, bool compact)
void DrawInspectorShelfSelection(DungeonCanvasViewer &viewer)
bool IsStandaloneToolOpen(WorkbenchTool tool) const
void SetOpenKeyboardShortcutsCallback(std::function< void()> callback)
DungeonWorkbenchContent(DungeonRoomSelector *room_selector, int *current_room_id, std::function< void(int)> on_room_selected, std::function< void(int, RoomSelectionIntent)> on_room_selected_with_intent, std::function< void(int)> on_save_room, std::function< void()> on_save_all_rooms, std::function< DungeonCanvasViewer *()> get_viewer, std::function< DungeonCanvasViewer *(int)> get_compare_viewer, std::function< const std::deque< int > &()> get_recent_rooms, std::function< void(int)> forget_recent_room, std::function< void(bool)> set_workflow_mode, Rom *rom=nullptr)
void DrawProposalPreviewWindow(DungeonCanvasViewer &viewer)
std::function< bool(const std::string &) is_standalone_tool_open_)
int GetPriority() const override
Get display priority for menu ordering.
DungeonWorkbenchPitDamageControlRects pit_damage_control_rects_
void DrawSelectedObjectActions(DungeonCanvasViewer &viewer, size_t index)
bool IsWorkbenchToolAvailable(WorkbenchTool tool) const
void DrawInspectorHeader(float button_size, bool compact)
void SetUndoRedoProvider(std::function< bool()> can_undo, std::function< bool()> can_redo, std::function< void()> on_undo, std::function< void()> on_redo, std::function< std::string()> undo_desc, std::function< std::string()> redo_desc, std::function< int()> undo_depth)
void SetPrimaryCanvasDrawnCallback(std::function< void(DungeonCanvasViewer &)> cb)
void DrawSidebarPane(float width, float height, float button_size, bool compact)
DungeonMapPanel * GetEmbeddedDungeonMap(DungeonCanvasViewer &viewer)
void SetRoomRenderContextCallback(std::function< void(int)> callback)
void DrawInspectorPane(float width, float height, float button_size, bool compact, DungeonCanvasViewer *viewer)
void SetObjectCoverageContent(WindowContent *object_coverage)
void DrawInspectorShelfRoom(DungeonCanvasViewer &viewer)
void SetOnInspectorSideChanged(std::function< void(bool)> cb)
WindowContent * GetWorkbenchToolContent(WorkbenchTool tool) const
std::string GetEditorCategory() const override
Editor category this panel belongs to.
const DungeonWorkbenchPitDamageControlRects & GetPitDamageControlRectsForTesting() const
std::optional< DungeonProposalOverlay > proposal_overlay_
void DrawWorkbenchTool(DungeonCanvasViewer &viewer, WorkbenchTool tool)
void DrawSidebarHeader(float button_size, bool compact)
const char * GetWorkbenchToolShortLabel(WorkbenchTool tool) const
void DrawDungeonMapPopup(DungeonCanvasViewer &viewer)
std::unique_ptr< DungeonMapPanel > embedded_dungeon_map_
void SetStandaloneToolCallbacks(std::function< bool(const std::string &)> is_window_open, std::function< bool(const std::string &)> open_and_focus_window)
void DrawInspectorToolPanel(DungeonCanvasViewer &viewer)
std::function< void(int, RoomSelectionIntent)> on_room_selected_with_intent_
void SetEmbeddedEditorPanels(WindowContent *object_selector, WindowContent *door_editor, WindowContent *sprite_editor, WindowContent *item_editor, WindowContent *room_graphics, WindowContent *palette_editor)
void SetEmbeddedToolPanels(RoomTagEditorPanel *room_tags, CustomCollisionPanel *custom_collision, WaterFillPanel *water_fill, MinecartTrackEditorPanel *minecart_tracks)
void DrawCanvasPane(float width, float height, DungeonCanvasViewer *primary_viewer)
std::function< void(DungeonCanvasViewer &) on_primary_canvas_drawn_)
const char * GetWorkbenchToolId(WorkbenchTool tool) const
const char * GetWorkbenchToolUnavailableMessage(WorkbenchTool tool) const
void NotifyRoomChanged(int previous_room_id)
Called by the editor when the current room changes.
std::string GetWorkflowGroup() const override
Optional workflow group for hack-centric actions.
bool DrawObjectPlacementInspector(DungeonCanvasViewer &viewer)
std::string GetId() const override
Unique identifier for this panel.
bool LoadProposalOverlay(const std::string &path)
void DrawSplitView(DungeonCanvasViewer &primary_viewer)
std::function< zelda3::PitDamageTable *()> get_pit_damage_table_
std::string GetIcon() const override
Material Design icon for this panel.
std::function< DungeonCanvasViewer *(int)> get_compare_viewer_
std::unordered_map< int, std::string > room_dungeon_cache_
std::string GetDisplayName() const override
Human-readable name shown in menus and title bars.
std::function< void(bool)> on_inspector_side_changed_
void Draw(bool *p_open) override
Draw the panel content.
void SetPitDamageTableProvider(std::function< zelda3::PitDamageTable *()> provider)
std::function< bool(const std::string &) open_and_focus_standalone_tool_)
std::function< const std::deque< int > &()> get_recent_rooms_
const std::optional< DungeonProposalOverlay > & proposal_overlay() const
void SetNavigationPanels(RoomMatrixContent *room_matrix, DungeonEntrancesPanel *entrances)
void DrawInspectorShelf(DungeonCanvasViewer &viewer, bool compact)
std::function< DungeonCanvasViewer *()> get_viewer_
WindowContent for displaying a visual 16x19 grid of all dungeon rooms.
WindowContent showing all room tag slots and their usage across rooms.
Base interface for all logical window content components.
Editors are the view controllers for the application.
DungeonWorkbenchPaneLayout ResolveDungeonWorkbenchPaneLayout(float total_width, float min_canvas_width, float min_sidebar_width, float splitter_width, float stored_left_width, float stored_right_width, bool want_left, bool want_right)
RoomSelectionIntent
Intent for room selection in the dungeon editor.
DungeonWorkbenchResponsiveLayout ResolveDungeonWorkbenchResponsiveLayout(float total_width, float min_canvas_width, float min_sidebar_width, float splitter_width, bool want_left, bool want_right)
DungeonWorkbenchToolRequestTarget ResolveDungeonWorkbenchToolRequestTarget(bool standalone_window_open)
Zelda 3 specific classes and functions.