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
19#include "imgui/imgui.h"
23#include "zelda3/dungeon/room.h"
27
28#include "rom/rom.h"
29
30namespace yaze {
31namespace editor {
32
33
34
44 public:
51
52 // ========================================================================
53 // Context and Configuration
54 // ========================================================================
55
68
78
79 // Last mutation/invalidation domain (best-effort). Used by editors to route
80 // undo capture and avoid expensive rerenders for overlay-only edits.
87
88 // Legacy setter - kept for backwards compatibility
93
94 // Main interaction handling
97 void PlaceObjectAtPosition(int room_x, int room_y);
98
99 void DrawSelectionHighlights(); // Draw highlights for selected objects
100 void DrawHoverHighlight(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(std::array<zelda3::Room, dungeon_coords::kRoomCount>* rooms,
112 int room_id);
113 void SetPreviewObject(const zelda3::RoomObject& object, bool loaded);
119
120 // Mode manager access
123
124 // Mode queries - delegate to mode manager
128
129 void CancelPlacement();
130
131 // 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 SendSelectedToFront(); // Move to end of list (drawn last, appears on top)
233 void SendSelectedToBack(); // Move to start of list (drawn first, appears behind)
234 void BringSelectedForward(); // Move up one position in list
235 void SendSelectedBackward(); // Move down one position in list
236
237 // Layer filter access (delegates to ObjectSelection)
238 void SetLayerFilter(int layer) { selection_.SetLayerFilter(layer); }
239 int GetLayerFilter() const { return selection_.GetLayerFilter(); }
242 const char* GetLayerFilterName() const { return selection_.GetLayerFilterName(); }
243 void SetLayersMerged(bool merged) { selection_.SetLayersMerged(merged); }
244 bool AreLayersMerged() const { return selection_.AreLayersMerged(); }
245
246 // Check keyboard shortcuts for layer operations
248
249 // Callbacks - stored in interaction_context_ (single source of truth)
251 std::function<void(const zelda3::RoomObject&)> callback) {
252 object_placed_callback_ = std::move(callback);
253 }
254 void SetCacheInvalidationCallback(std::function<void()> callback) {
255 interaction_context_.on_invalidate_cache = std::move(callback);
257 }
258 void SetMutationCallback(std::function<void()> callback) {
259 interaction_context_.on_mutation = std::move(callback);
261 }
263 editor_system_ = system;
264 }
265
266 // Entity selection (doors, sprites, items)
267 void SelectEntity(EntityType type, size_t index);
275
276
277 // Draw entity selection highlights
279 void DrawDoorSnapIndicators(); // Show valid snap positions during door drag
280
281 // Callbacks for entity changes
282 void SetEntityChangedCallback(std::function<void()> callback) {
283 interaction_context_.on_entity_changed = std::move(callback);
285 }
286
287 private:
290 std::array<zelda3::Room, dungeon_coords::kRoomCount>* rooms_ = nullptr;
292
293 // Unified interaction context and coordinator for entity handling
296
297 // Unified mode state machine - replaces scattered boolean flags
299
300 // Helper to calculate object bounds
301 std::pair<int, int> CalculateObjectBounds(const zelda3::RoomObject& object);
302
303 // Refactored input handlers
304 void HandleLeftClick(const ImVec2& canvas_mouse_pos);
305 void UpdateCollisionPainting(const ImVec2& canvas_mouse_pos);
306 void UpdateWaterFillPainting(const ImVec2& canvas_mouse_pos);
307 void HandleObjectSelectionStart(const ImVec2& canvas_mouse_pos);
308 void HandleEmptySpaceClick(const ImVec2& canvas_mouse_pos);
309 void HandleMouseRelease();
310
311 // Preview object state (used by ModeState but kept here for ghost bitmap)
313
314 // Ghost preview bitmap (persists across frames for placement preview)
316
317 // Unified selection system - replaces legacy selection state
319
320 // Callbacks - stored only in interaction_context_ (no duplication)
321 std::function<void(const zelda3::RoomObject&)> object_placed_callback_;
322
323 // Entity selection state (doors, sprites, items)
324 // Note: entity selection is owned by InteractionCoordinator/handlers.
325};
326
327} // namespace editor
328} // namespace yaze
329
330#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)
void SetCurrentRoom(std::array< zelda3::Room, dungeon_coords::kRoomCount > *rooms, int room_id)
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)
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.
std::array< zelda3::Room, dungeon_coords::kRoomCount > * rooms_
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.