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
18#include "imgui/imgui.h"
22#include "zelda3/dungeon/room.h"
26
27#include "rom/rom.h"
28
29namespace yaze {
30namespace editor {
31
35enum class EntityType {
36 None,
37 Object, // Room tile objects
38 Door, // Door entities
39 Sprite, // Enemy/NPC sprites
40 Item // Pot items
41};
42
48 size_t index = 0; // Index into the respective container
49
50 bool operator==(const SelectedEntity& other) const {
51 return type == other.type && index == other.index;
52 }
53};
54
64 public:
65 explicit DungeonObjectInteraction(gui::Canvas* canvas) : canvas_(canvas) {
66 // Set up initial context
69 }
70
71 // ========================================================================
72 // Context and Configuration
73 // ========================================================================
74
86
96
97 // Legacy setter - kept for backwards compatibility
103
104 // Main interaction handling
107 void PlaceObjectAtPosition(int room_x, int room_y);
108
109 // Selection rectangle (like OverworldEditor)
111 void SelectObjectsInRect();
112 void DrawSelectionHighlights(); // Draw highlights for selected objects
113 void DrawHoverHighlight(const std::vector<zelda3::RoomObject>& objects); // Draw hover indicator
114
115 // Drag and select box functionality
116 void DrawSelectBox();
117 void DrawDragPreview();
118 void DrawGhostPreview(); // Draw ghost preview for object placement
120 bool IsObjectInSelectBox(const zelda3::RoomObject& object) const;
121
122 // Coordinate conversion
123 std::pair<int, int> RoomToCanvasCoordinates(int room_x, int room_y) const;
124 std::pair<int, int> CanvasToRoomCoordinates(int canvas_x, int canvas_y) const;
125 bool IsWithinCanvasBounds(int canvas_x, int canvas_y, int margin = 32) const;
126
127 // State management
128 void SetCurrentRoom(std::array<zelda3::Room, dungeon_coords::kRoomCount>* rooms,
129 int room_id);
130 void SetPreviewObject(const zelda3::RoomObject& object, bool loaded);
136
137 // Mode manager access
140
141 // Mode queries - delegate to mode manager
145
150
151 // Door placement mode
163 void DrawDoorGhostPreview(); // Draw door ghost preview with wall snapping
164 void PlaceDoorAtPosition(int canvas_x, int canvas_y); // Place door at snapped position
170
171 // Sprite placement mode
172 void SetSpritePlacementMode(bool enabled, uint8_t sprite_id = 0);
179 uint8_t GetPreviewSpriteId() const {
180 return mode_manager_.GetModeState().preview_sprite_id.value_or(0);
181 }
182 void DrawSpriteGhostPreview(); // Draw sprite ghost preview
183 void PlaceSpriteAtPosition(int canvas_x, int canvas_y);
189
190 // Item placement mode
191 void SetItemPlacementMode(bool enabled, uint8_t item_id = 0);
195 void SetPreviewItemId(uint8_t id) {
197 }
198 uint8_t GetPreviewItemId() const {
199 return mode_manager_.GetModeState().preview_item_id.value_or(0);
200 }
201 void DrawItemGhostPreview(); // Draw item ghost preview
202 void PlaceItemAtPosition(int canvas_x, int canvas_y);
208
209 // Selection state - delegates to ObjectSelection
210 std::vector<size_t> GetSelectedObjectIndices() const {
212 }
213 void SetSelectedObjects(const std::vector<size_t>& indices) {
215 for (size_t idx : indices) {
217 }
218 }
222 void ClearSelection();
223 bool IsObjectSelected(size_t index) const {
224 return selection_.IsObjectSelected(index);
225 }
226 size_t GetSelectionCount() const { return selection_.GetSelectionCount(); }
227
228 // Selection change notification
229 void SetSelectionChangeCallback(std::function<void()> callback) {
230 selection_.SetSelectionChangedCallback(std::move(callback));
231 }
232
233 // Helper for click selection with proper mode handling
235
236 // Object manipulation
237 void HandleScrollWheelResize(); // Resize selected objects with scroll wheel
238 size_t GetHoveredObjectIndex() const; // Get index of object under cursor
239
241 void HandleCopySelected();
242 void HandlePasteObjects();
243 bool HasClipboardData() const { return has_clipboard_data_; }
244
245 // Layer assignment for selected objects
246 void SendSelectedToLayer(int target_layer);
247
248 // Object ordering (changes draw order within the layer)
249 // SNES draws objects in list order - first objects appear behind, last on top
250 void SendSelectedToFront(); // Move to end of list (drawn last, appears on top)
251 void SendSelectedToBack(); // Move to start of list (drawn first, appears behind)
252 void BringSelectedForward(); // Move up one position in list
253 void SendSelectedBackward(); // Move down one position in list
254
255 // Layer filter access (delegates to ObjectSelection)
256 void SetLayerFilter(int layer) { selection_.SetLayerFilter(layer); }
257 int GetLayerFilter() const { return selection_.GetLayerFilter(); }
260 const char* GetLayerFilterName() const { return selection_.GetLayerFilterName(); }
261 void SetLayersMerged(bool merged) { selection_.SetLayersMerged(merged); }
262 bool AreLayersMerged() const { return selection_.AreLayersMerged(); }
263
264 // Check keyboard shortcuts for layer operations
266
267 // Callbacks - stored in interaction_context_ (single source of truth)
269 std::function<void(const zelda3::RoomObject&)> callback) {
270 object_placed_callback_ = std::move(callback);
271 }
272 void SetCacheInvalidationCallback(std::function<void()> callback) {
273 interaction_context_.on_invalidate_cache = std::move(callback);
275 }
276 void SetMutationCallback(std::function<void()> callback) {
277 interaction_context_.on_mutation = std::move(callback);
279 }
280 // Backward compatibility alias
281 [[deprecated("Use SetMutationCallback() instead")]]
282 void SetMutationHook(std::function<void()> callback) {
283 SetMutationCallback(std::move(callback));
284 }
285
287 editor_system_ = system;
288 }
289
290 // Entity selection (doors, sprites, items)
291 void SelectEntity(EntityType type, size_t index);
295
296 // Entity hit detection
297 std::optional<SelectedEntity> GetEntityAtPosition(int canvas_x, int canvas_y) const;
298
299 // Draw entity selection highlights
301 void DrawDoorSnapIndicators(); // Show valid snap positions during door drag
302
303 // Entity interaction
304 bool TrySelectEntityAtCursor(); // Try to select door/sprite/item at cursor
305 void HandleEntityDrag(); // Handle dragging selected entity
306
307 // Callbacks for entity changes
308 void SetEntityChangedCallback(std::function<void()> callback) {
309 interaction_context_.on_entity_changed = std::move(callback);
311 }
312
313 private:
316 std::array<zelda3::Room, dungeon_coords::kRoomCount>* rooms_ = nullptr;
318 Rom* rom_ = nullptr;
319 std::unique_ptr<zelda3::ObjectDrawer> object_drawer_;
320
321 // Unified interaction context and coordinator for entity handling
324
325 // Unified mode state machine - replaces scattered boolean flags
327
328 // Helper to calculate object bounds
329 std::pair<int, int> CalculateObjectBounds(const zelda3::RoomObject& object);
330
331 // Preview object state (used by ModeState but kept here for ghost bitmap)
333
334 // Ghost preview bitmap (persists across frames for placement preview)
335 std::unique_ptr<gfx::BackgroundBuffer> ghost_preview_buffer_;
338
339 // Unified selection system - replaces legacy selection state
341
342 // Hover detection for resize
343 size_t hovered_object_index_ = static_cast<size_t>(-1);
345
346 // Callbacks - stored only in interaction_context_ (no duplication)
347 std::function<void(const zelda3::RoomObject&)> object_placed_callback_;
348
349 // Clipboard for copy/paste
350 std::vector<zelda3::RoomObject> clipboard_;
352
353 // Entity selection state (doors, sprites, items)
355 bool is_entity_mode_ = false; // When true, suppress all object interactions
356};
357
358} // namespace editor
359} // namespace yaze
360
361#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:24
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)
void PlaceDoorAtPosition(int canvas_x, int canvas_y)
bool IsWithinCanvasBounds(int canvas_x, int canvas_y, int margin=32) const
void SetCacheInvalidationCallback(std::function< void()> callback)
std::unique_ptr< gfx::BackgroundBuffer > ghost_preview_buffer_
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)
bool IsObjectInSelectBox(const zelda3::RoomObject &object) const
void DrawHoverHighlight(const std::vector< zelda3::RoomObject > &objects)
void PlaceSpriteAtPosition(int canvas_x, int canvas_y)
std::function< void(const zelda3::RoomObject &) object_placed_callback_)
std::unique_ptr< zelda3::ObjectDrawer > object_drawer_
void SetSpritePlacementMode(bool enabled, uint8_t sprite_id=0)
void SetEditorSystem(zelda3::DungeonEditorSystem *system)
void SetObjectPlacedCallback(std::function< void(const zelda3::RoomObject &)> callback)
std::vector< size_t > GetSelectedObjectIndices() const
void SetSelectionChangeCallback(std::function< void()> callback)
InteractionCoordinator & entity_coordinator()
Get the interaction coordinator for entity handling.
std::array< zelda3::Room, dungeon_coords::kRoomCount > * rooms_
std::vector< zelda3::RoomObject > clipboard_
void SetMutationCallback(std::function< void()> callback)
void SetEntityChangedCallback(std::function< void()> callback)
std::optional< SelectedEntity > GetEntityAtPosition(int canvas_x, int canvas_y) const
void SetMutationHook(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 SetPreviewObject(const zelda3::RoomObject &object, bool loaded)
void PlaceItemAtPosition(int canvas_x, int canvas_y)
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.
Modern, robust canvas for drawing and manipulating graphics.
Definition canvas.h:150
Comprehensive dungeon editing system.
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.
bool operator==(const SelectedEntity &other) const
Represents a group of palettes.