#ifndef YAZE_APP_EDITOR_DUNGEON_DUNGEON_OBJECT_INTERACTION_H #define YAZE_APP_EDITOR_DUNGEON_DUNGEON_OBJECT_INTERACTION_H #include #include #include "app/gui/canvas/canvas.h" #include "imgui/imgui.h" #include "zelda3/dungeon/room.h" #include "zelda3/dungeon/room_object.h" namespace yaze { namespace editor { /** * @brief Handles object selection, placement, and interaction within the dungeon canvas * * This component manages mouse interactions for object selection (similar to OverworldEditor), * object placement, drag operations, and multi-object selection. */ class DungeonObjectInteraction { public: explicit DungeonObjectInteraction(gui::Canvas* canvas) : canvas_(canvas) {} // Main interaction handling void HandleCanvasMouseInput(); void CheckForObjectSelection(); void PlaceObjectAtPosition(int room_x, int room_y); // Selection rectangle (like OverworldEditor) void DrawObjectSelectRect(); void SelectObjectsInRect(); void DrawSelectionHighlights(); // Draw highlights for selected objects // Drag and select box functionality void DrawSelectBox(); void DrawDragPreview(); void UpdateSelectedObjects(); bool IsObjectInSelectBox(const zelda3::RoomObject& object) const; // Coordinate conversion std::pair RoomToCanvasCoordinates(int room_x, int room_y) const; std::pair CanvasToRoomCoordinates(int canvas_x, int canvas_y) const; bool IsWithinCanvasBounds(int canvas_x, int canvas_y, int margin = 32) const; // State management void SetCurrentRoom(std::array* rooms, int room_id); void SetPreviewObject(const zelda3::RoomObject& object, bool loaded); // Selection state const std::vector& GetSelectedObjectIndices() const { return selected_object_indices_; } bool IsObjectSelectActive() const { return object_select_active_; } void ClearSelection(); // Context menu void ShowContextMenu(); void HandleDeleteSelected(); void HandleCopySelected(); void HandlePasteObjects(); // Callbacks void SetObjectPlacedCallback( std::function callback) { object_placed_callback_ = callback; } void SetCacheInvalidationCallback(std::function callback) { cache_invalidation_callback_ = callback; } private: gui::Canvas* canvas_; std::array* rooms_ = nullptr; int current_room_id_ = 0; // Preview object state zelda3::RoomObject preview_object_{0, 0, 0, 0, 0}; bool object_loaded_ = false; // Drag and select infrastructure bool is_dragging_ = false; bool is_selecting_ = false; ImVec2 drag_start_pos_; ImVec2 drag_current_pos_; ImVec2 select_start_pos_; ImVec2 select_current_pos_; std::vector selected_objects_; // Object selection rectangle (like OverworldEditor) bool object_select_active_ = false; ImVec2 object_select_start_; ImVec2 object_select_end_; std::vector selected_object_indices_; // Callbacks std::function object_placed_callback_; std::function cache_invalidation_callback_; // Clipboard for copy/paste std::vector clipboard_; bool has_clipboard_data_ = false; }; } // namespace editor } // namespace yaze #endif // YAZE_APP_EDITOR_DUNGEON_DUNGEON_OBJECT_INTERACTION_H