yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
dungeon_object_interaction.h
Go to the documentation of this file.
1#ifndef YAZE_APP_EDITOR_DUNGEON_DUNGEON_OBJECT_INTERACTION_H
2#define YAZE_APP_EDITOR_DUNGEON_DUNGEON_OBJECT_INTERACTION_H
3
4#include <functional>
5#include <memory>
6#include <optional>
7#include <utility>
8#include <vector>
9
20#include "imgui/imgui.h"
25#include "zelda3/dungeon/room.h"
28
29#include "rom/rom.h"
30
31namespace yaze {
32namespace editor {
33
43 public:
50
51 // ========================================================================
52 // Context and Configuration
53 // ========================================================================
54
67
77
78 // Last mutation/invalidation domain (best-effort). Used by editors to route
79 // undo capture and avoid expensive rerenders for overlay-only edits.
86
87 // Legacy setter - kept for backwards compatibility
92
93 // Main interaction handling
96 void PlaceObjectAtPosition(int room_x, int room_y);
97
98 void DrawSelectionHighlights(); // Draw highlights for selected objects
100 const std::vector<zelda3::RoomObject>& objects); // Draw hover indicator
101
102 // Drag and select box functionality
103 void DrawGhostPreview(); // Draw ghost preview for object placement
104
105 // Coordinate conversion
106 std::pair<int, int> RoomToCanvasCoordinates(int room_x, int room_y) const;
107 std::pair<int, int> CanvasToRoomCoordinates(int canvas_x, int canvas_y) const;
108 bool IsWithinCanvasBounds(int canvas_x, int canvas_y, int margin = 32) const;
109
110 // State management
111 void SetCurrentRoom(DungeonRoomStore* rooms, int room_id);
112 void SetPreviewObject(const zelda3::RoomObject& object, bool loaded);
118
119 // Mode manager access
122
123 // Mode queries - delegate to mode manager
127
128 void CancelPlacement();
129
130 // Door placement mode
148
149 // Sprite placement mode
150 void SetSpritePlacementMode(bool enabled, uint8_t sprite_id = 0);
157 uint8_t GetPreviewSpriteId() const {
158 return mode_manager_.GetModeState().preview_sprite_id.value_or(0);
159 }
165
166 // Item placement mode
167 void SetItemPlacementMode(bool enabled, uint8_t item_id = 0);
171 void SetPreviewItemId(uint8_t id) {
173 }
174 uint8_t GetPreviewItemId() const {
175 return mode_manager_.GetModeState().preview_item_id.value_or(0);
176 }
182
183 // Selection state - delegates to ObjectSelection
184 std::vector<size_t> GetSelectedObjectIndices() const {
186 }
187 void SetSelectedObjects(const std::vector<size_t>& indices) {
189 for (size_t idx : indices) {
191 }
192 }
196 void ClearSelection();
197 bool IsObjectSelected(size_t index) const {
198 return selection_.IsObjectSelected(index);
199 }
200 size_t GetSelectionCount() const { return selection_.GetSelectionCount(); }
201
202 // Selection change notification
203 void SetSelectionChangeCallback(std::function<void()> callback) {
204 selection_.SetSelectionChangedCallback(std::move(callback));
205 }
206
207 // Helper for click selection with proper mode handling
208
209 // Object manipulation
210 void HandleScrollWheelResize(); // Resize selected objects with scroll wheel
211
214 void HandleCopySelected();
215 void HandlePasteObjects();
219
220 // Inspector-friendly mutation helpers (with undo + rerender integration).
221 // These are intended for UI panels that want to edit a single object without
222 // duplicating mutation/invalidation boilerplate.
223 bool SetObjectId(size_t index, int16_t id);
224 bool SetObjectSize(size_t index, uint8_t size);
225 bool SetObjectLayer(size_t index, zelda3::RoomObject::LayerType layer);
226
227 // Layer assignment for selected objects
228 void SendSelectedToLayer(int target_layer);
229
230 // Object ordering (changes draw order within the layer)
231 // SNES draws objects in list order - first objects appear behind, last on top
232 void
233 SendSelectedToFront(); // Move to end of list (drawn last, appears on top)
234 void
235 SendSelectedToBack(); // Move to start of list (drawn first, appears behind)
236 void BringSelectedForward(); // Move up one position in list
237 void SendSelectedBackward(); // Move down one position in list
238
239 // Layer filter access (delegates to ObjectSelection)
240 void SetLayerFilter(int layer) { selection_.SetLayerFilter(layer); }
241 int GetLayerFilter() const { return selection_.GetLayerFilter(); }
244 const char* GetLayerFilterName() const {
246 }
247 void SetLayersMerged(bool merged) { selection_.SetLayersMerged(merged); }
248 bool AreLayersMerged() const { return selection_.AreLayersMerged(); }
249
250 // Check keyboard shortcuts for layer operations
252
253 // Callbacks - stored in interaction_context_ (single source of truth)
255 std::function<void(const zelda3::RoomObject&)> callback) {
256 object_placed_callback_ = std::move(callback);
257 }
258 void SetCacheInvalidationCallback(std::function<void()> callback) {
259 interaction_context_.on_invalidate_cache = std::move(callback);
261 }
262 void SetMutationCallback(std::function<void()> callback) {
263 interaction_context_.on_mutation = std::move(callback);
265 }
267 editor_system_ = system;
268 }
269
270 // Entity selection (doors, sprites, items)
271 void SelectEntity(EntityType type, size_t index);
279
280 // Draw entity selection highlights
282 void DrawDoorSnapIndicators(); // Show valid snap positions during door drag
283
284 // Callbacks for entity changes
285 void SetEntityChangedCallback(std::function<void()> callback) {
286 interaction_context_.on_entity_changed = std::move(callback);
288 }
289
290 private:
295
296 // Unified interaction context and coordinator for entity handling
299
300 // Unified mode state machine - replaces scattered boolean flags
302
303 // Helper to calculate object bounds
304 std::pair<int, int> CalculateObjectBounds(const zelda3::RoomObject& object);
305
306 // Refactored input handlers
307 void HandleLeftClick(const ImVec2& canvas_mouse_pos);
308 void UpdateCollisionPainting(const ImVec2& canvas_mouse_pos);
309 void UpdateWaterFillPainting(const ImVec2& canvas_mouse_pos);
310 void HandleObjectSelectionStart(const ImVec2& canvas_mouse_pos);
311 void HandleEmptySpaceClick(const ImVec2& canvas_mouse_pos);
312 void HandleMouseRelease();
313
314 // Preview object state (used by ModeState but kept here for ghost bitmap)
316
317 // Ghost preview bitmap (persists across frames for placement preview)
319
320 // Unified selection system - replaces legacy selection state
322
323 // Callbacks - stored only in interaction_context_ (no duplication)
324 std::function<void(const zelda3::RoomObject&)> object_placed_callback_;
325
326 // Entity selection state (doors, sprites, items)
327 // Note: entity selection is owned by InteractionCoordinator/handlers.
328};
329
330} // namespace editor
331} // namespace yaze
332
333#endif // YAZE_APP_EDITOR_DUNGEON_DUNGEON_OBJECT_INTERACTION_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:28
Handles object selection, placement, and interaction within the dungeon canvas.
void SetSelectedObjects(const std::vector< size_t > &indices)
std::pair< int, int > CalculateObjectBounds(const zelda3::RoomObject &object)
bool IsWithinCanvasBounds(int canvas_x, int canvas_y, int margin=32) const
void SetCacheInvalidationCallback(std::function< void()> callback)
void HandleObjectSelectionStart(const ImVec2 &canvas_mouse_pos)
std::pair< int, int > RoomToCanvasCoordinates(int room_x, int room_y) const
void SetCurrentPaletteGroup(const gfx::PaletteGroup &group)
void SetContext(const InteractionContext &ctx)
Set the unified interaction context.
void SetItemPlacementMode(bool enabled, uint8_t item_id=0)
void DrawHoverHighlight(const std::vector< zelda3::RoomObject > &objects)
std::function< void(const zelda3::RoomObject &) object_placed_callback_)
void SetSpritePlacementMode(bool enabled, uint8_t sprite_id=0)
void SetEditorSystem(zelda3::DungeonEditorSystem *system)
bool SetObjectLayer(size_t index, zelda3::RoomObject::LayerType layer)
void SetObjectPlacedCallback(std::function< void(const zelda3::RoomObject &)> callback)
void HandleLeftClick(const ImVec2 &canvas_mouse_pos)
void SetCurrentRoom(DungeonRoomStore *rooms, int room_id)
std::vector< size_t > GetSelectedObjectIndices() const
void SetSelectionChangeCallback(std::function< void()> callback)
void UpdateWaterFillPainting(const ImVec2 &canvas_mouse_pos)
InteractionCoordinator & entity_coordinator()
Get the interaction coordinator for entity handling.
void SetMutationCallback(std::function< void()> callback)
void SetEntityChangedCallback(std::function< void()> callback)
void SelectEntity(EntityType type, size_t index)
const InteractionCoordinator & entity_coordinator() const
void SetDoorPlacementMode(bool enabled, zelda3::DoorType type=zelda3::DoorType::NormalDoor)
std::pair< int, int > CanvasToRoomCoordinates(int canvas_x, int canvas_y) const
void HandleEmptySpaceClick(const ImVec2 &canvas_mouse_pos)
void SetPreviewObject(const zelda3::RoomObject &object, bool loaded)
void UpdateCollisionPainting(const ImVec2 &canvas_mouse_pos)
const InteractionModeManager & mode_manager() const
Coordinates interaction mode switching and dispatches to handlers.
void SetContext(InteractionContext *ctx)
Set the shared interaction context.
Manages interaction mode state and transitions.
void CancelCurrentMode()
Cancel current mode and return to Select.
InteractionMode GetMode() const
Get current interaction mode.
ModeState & GetModeState()
Get mutable reference to mode state.
Manages object selection state and operations for the dungeon editor.
void SetSelectionChangedCallback(std::function< void()> callback)
Set callback to be invoked when selection changes.
bool IsMaskModeActive() const
Check if mask selection mode is active.
bool IsRectangleSelectionActive() const
Check if a rectangle selection is in progress.
int GetLayerFilter() const
Get the current active layer filter.
bool IsObjectSelected(size_t index) const
Check if an object is selected.
std::vector< size_t > GetSelectedIndices() const
Get all selected object indices.
bool AreLayersMerged() const
Check if layers are currently merged.
size_t GetSelectionCount() const
Get the number of selected objects.
void SelectObject(size_t index, SelectionMode mode=SelectionMode::Single)
Select a single object by index.
void ClearSelection()
Clear all selections.
const char * GetLayerFilterName() const
Get the name of the current layer filter for display.
void SetLayersMerged(bool merged)
Set whether layers are currently merged in the room.
void SetLayerFilter(int layer)
Set the active layer filter for selection.
bool IsLayerFilterActive() const
Check if layer filtering is active.
bool HasSelection() const
Check if any objects are selected.
bool HasClipboardData() const
Check if clipboard has data.
Modern, robust canvas for drawing and manipulating graphics.
Definition canvas.h:150
MutationDomain
Domain/type of mutation for undo + invalidation routing.
EntityType
Type of entity that can be selected in the dungeon editor.
DoorType
Door types from ALTTP.
Definition door_types.h:33
@ NormalDoor
Normal door (upper layer)
Shared context for all interaction handlers.
std::function< void()> on_invalidate_cache
std::function< void()> on_entity_changed
std::optional< zelda3::DoorType > preview_door_type
std::optional< uint8_t > preview_item_id
std::optional< uint8_t > preview_sprite_id
Represents a selected entity in the dungeon editor.
Represents a group of palettes.