yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
interaction_coordinator.cc
Go to the documentation of this file.
3
4// Third-party library headers
5#include "imgui/imgui.h"
6
7namespace yaze::editor {
8
16
18 // Cancel current mode first
20
21 current_mode_ = mode;
22
23 // Activate the new mode
24 switch (mode) {
25 case Mode::PlaceDoor:
27 break;
30 break;
31 case Mode::PlaceItem:
33 break;
34 case Mode::Select:
35 // Nothing to activate
36 break;
37 }
38}
39
49
56
57bool InteractionCoordinator::HandleClick(int canvas_x, int canvas_y) {
58 // Check placement modes first
60 return door_handler_.HandleClick(canvas_x, canvas_y);
61 }
63 return sprite_handler_.HandleClick(canvas_x, canvas_y);
64 }
66 return item_handler_.HandleClick(canvas_x, canvas_y);
67 }
69 return tile_handler_.HandleClick(canvas_x, canvas_y);
70 }
71
72 // In select mode, only handle the click if the cursor is over an entity or object.
73 const auto entity = GetEntityAtPosition(canvas_x, canvas_y);
74 if (!entity.has_value()) {
75 return false;
76 }
77
78 const ImGuiIO& io = ImGui::GetIO();
79 const bool additive = io.KeyShift || io.KeyCtrl || io.KeySuper;
80
81 // Cross-selection rules:
82 // 1. Entities (Door, Sprite, Item) are exclusive to each other.
83 // 2. Entities are exclusive to Tile Objects.
84 // 3. Tile Objects support multi-selection.
85
86 if (entity->type == EntityType::Object) {
87 // If selecting an object, always clear entities.
89 // If not additive, also clear existing object selection.
90 if (!additive && ctx_ && ctx_->selection) {
92 }
93 return tile_handler_.HandleClick(canvas_x, canvas_y);
94 } else {
95 // If selecting an entity, always clear everything.
97 if (ctx_ && ctx_->selection) {
99 }
100
101 switch (entity->type) {
102 case EntityType::Door:
103 return door_handler_.HandleClick(canvas_x, canvas_y);
105 return sprite_handler_.HandleClick(canvas_x, canvas_y);
106 case EntityType::Item:
107 return item_handler_.HandleClick(canvas_x, canvas_y);
108 default:
109 return false;
110 }
111 }
112}
113
122
125
126 // Entity selection takes exclusive priority over tile object selection.
127 if (ctx_ && ctx_->selection) {
129 }
130
131 switch (type) {
132 case EntityType::Door:
134 break;
137 break;
138 case EntityType::Item:
140 break;
142 case EntityType::None:
143 default:
144 break;
145 }
146}
147
149 const bool had_selection = HasEntitySelection();
151 if (had_selection && ctx_) {
153 }
154}
155
162
164 int canvas_x, int canvas_y) const {
165 if (auto door = door_handler_.GetEntityAtPosition(canvas_x, canvas_y))
166 return SelectedEntity{EntityType::Door, *door};
167 if (auto sprite = sprite_handler_.GetEntityAtPosition(canvas_x, canvas_y))
168 return SelectedEntity{EntityType::Sprite, *sprite};
169 if (auto item = item_handler_.GetEntityAtPosition(canvas_x, canvas_y))
170 return SelectedEntity{EntityType::Item, *item};
171 if (auto object = tile_handler_.GetEntityAtPosition(canvas_x, canvas_y))
172 return SelectedEntity{EntityType::Object, *object};
173 return std::nullopt;
174}
175
177 if (auto idx = door_handler_.GetSelectedIndex()) {
178 return SelectedEntity{EntityType::Door, *idx};
179 }
180 if (auto idx = sprite_handler_.GetSelectedIndex()) {
182 }
183 if (auto idx = item_handler_.GetSelectedIndex()) {
184 return SelectedEntity{EntityType::Item, *idx};
185 }
187}
188
189void InteractionCoordinator::HandleDrag(ImVec2 current_pos, ImVec2 delta) {
190 // Forward drag to handlers that have active selections
192 door_handler_.HandleDrag(current_pos, delta);
193 }
195 sprite_handler_.HandleDrag(current_pos, delta);
196 }
198 item_handler_.HandleDrag(current_pos, delta);
199 }
200
201 // Tile objects (managed by ObjectSelection)
203 tile_handler_.HandleDrag(current_pos, delta);
204 }
205}
206
213
229
231 // Draw selection highlights for all entity types
235
236 // Draw snap indicators for door placement
239 }
240}
241
243 // Render placement success toasts for all handlers unconditionally so they
244 // remain visible even after the user exits placement mode immediately.
249}
250
252 int canvas_y) {
253 // Clear all selections first
255
256 // Try to select in priority order: doors, sprites, items
257 // (matches original DungeonObjectInteraction behavior)
258 if (door_handler_.HandleClick(canvas_x, canvas_y)) {
259 return true;
260 }
261 if (sprite_handler_.HandleClick(canvas_x, canvas_y)) {
262 return true;
263 }
264 if (item_handler_.HandleClick(canvas_x, canvas_y)) {
265 return true;
266 }
267
268 return false;
269}
270
275
281
291
305
307 switch (current_mode_) {
308 case Mode::PlaceDoor:
309 return &door_handler_;
311 return &sprite_handler_;
312 case Mode::PlaceItem:
313 return &item_handler_;
314 case Mode::Select:
315 default:
316 return nullptr;
317 }
318}
319
320} // namespace yaze::editor
Abstract base class for entity interaction handlers.
virtual bool HandleMouseWheel(float delta)
void SetContext(InteractionContext *ctx)
Set the interaction context.
void DrawSelectionHighlight() override
Draw selection highlight for selected entities.
void DrawSnapIndicators()
Draw snap position indicators during door drag.
void SelectDoor(size_t index)
Select door at index.
void DrawGhostPreview() override
Draw ghost preview during placement.
void HandleDrag(ImVec2 current_pos, ImVec2 delta) override
Handle mouse drag.
void CancelPlacement() override
Cancel current placement.
void BeginPlacement() override
Begin placement mode.
void HandleRelease() override
Handle mouse release.
bool HandleClick(int canvas_x, int canvas_y) override
Handle mouse click at canvas position.
std::optional< size_t > GetSelectedIndex() const
Get selected door index.
bool IsPlacementActive() const override
Check if placement mode is active.
std::optional< size_t > GetEntityAtPosition(int canvas_x, int canvas_y) const override
Get entity at canvas position.
bool HasSelection() const
Check if a door is selected.
bool TrySelectEntityAtCursor(int canvas_x, int canvas_y)
Try to select entity at cursor position.
Mode GetSelectedEntityType() const
Get the type of currently selected entity.
void CancelCurrentMode()
Cancel current mode and return to select mode.
void SetContext(InteractionContext *ctx)
Set the shared interaction context.
BaseEntityHandler * GetActiveHandler()
Get active handler based on current mode.
void DeleteSelectedEntity()
Delete currently selected entity.
bool IsPlacementActive() const
Check if any placement mode is active.
bool HandleClick(int canvas_x, int canvas_y)
Handle click at canvas position.
void SelectEntity(EntityType type, size_t index)
void DrawPostPlacementOverlays()
Draw post-placement success toasts for all handlers (unconditional)
void DrawSelectionHighlights()
Draw selection highlights for all entity types.
void SetMode(Mode mode)
Set interaction mode.
void ClearAllEntitySelections()
Clear all entity selections.
void DrawGhostPreviews()
Draw ghost previews for active placement mode.
std::optional< SelectedEntity > GetEntityAtPosition(int canvas_x, int canvas_y) const
void HandleDrag(ImVec2 current_pos, ImVec2 delta)
Handle drag operation.
void DrawSelectionHighlight() override
Draw selection highlight for selected entities.
bool HandleClick(int canvas_x, int canvas_y) override
Handle mouse click at canvas position.
bool IsPlacementActive() const override
Check if placement mode is active.
void DrawGhostPreview() override
Draw ghost preview during placement.
void BeginPlacement() override
Begin placement mode.
void HandleDrag(ImVec2 current_pos, ImVec2 delta) override
Handle mouse drag.
std::optional< size_t > GetEntityAtPosition(int canvas_x, int canvas_y) const override
Get entity at canvas position.
bool HasSelection() const
Check if an item is selected.
void HandleRelease() override
Handle mouse release.
std::optional< size_t > GetSelectedIndex() const
Get selected item index.
void SelectItem(size_t index)
Select item at index.
void CancelPlacement() override
Cancel current placement.
void ClearSelection()
Clear all selections.
bool HasSelection() const
Check if any objects are selected.
bool IsPlacementActive() const override
Check if placement mode is active.
void CancelPlacement() override
Cancel current placement.
void HandleRelease() override
Handle mouse release.
void SelectSprite(size_t index)
Select sprite at index.
bool HasSelection() const
Check if a sprite is selected.
std::optional< size_t > GetEntityAtPosition(int canvas_x, int canvas_y) const override
Get entity at canvas position.
void DrawGhostPreview() override
Draw ghost preview during placement.
void DrawSelectionHighlight() override
Draw selection highlight for selected entities.
void HandleDrag(ImVec2 current_pos, ImVec2 delta) override
Handle mouse drag.
bool HandleClick(int canvas_x, int canvas_y) override
Handle mouse click at canvas position.
std::optional< size_t > GetSelectedIndex() const
Get selected sprite index.
void BeginPlacement() override
Begin placement mode.
void DrawGhostPreview() override
Draw ghost preview during placement.
bool HandleMouseWheel(float delta) override
void HandleRelease() override
Handle mouse release.
void HandleDrag(ImVec2 current_pos, ImVec2 delta) override
Handle mouse drag.
bool IsPlacementActive() const override
Check if placement mode is active.
bool HandleClick(int canvas_x, int canvas_y) override
Handle mouse click at canvas position.
void CancelPlacement() override
Cancel current placement.
std::optional< size_t > GetEntityAtPosition(int canvas_x, int canvas_y) const override
Get entity at canvas position.
Editors are the view controllers for the application.
EntityType
Type of entity that can be selected in the dungeon editor.
Shared context for all interaction handlers.
void NotifyEntityChanged() const
Notify that entity has changed.
Represents a selected entity in the dungeon editor.