yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
object_selection.h
Go to the documentation of this file.
1#ifndef YAZE_APP_EDITOR_DUNGEON_OBJECT_SELECTION_H
2#define YAZE_APP_EDITOR_DUNGEON_OBJECT_SELECTION_H
3
4#include <cstdint>
5#include <functional>
6#include <set>
7#include <tuple>
8#include <vector>
9
11#include "imgui/imgui.h"
13#include "zelda3/dungeon/room.h"
15
16namespace yaze {
17namespace editor {
18
36 public:
37 enum class SelectionMode {
38 Single, // Replace selection with single object
39 Add, // Add to existing selection (Shift)
40 Toggle, // Toggle object in selection (Ctrl)
41 Rectangle, // Rectangle drag selection
42 };
43
44 // Layer filter constants
45 static constexpr int kLayerAll = -1; // Select from all layers
46 static constexpr int kMaskLayer =
47 -2; // Mask mode: only BG2/Layer 1 objects (overlays)
48 static constexpr int kLayer1 = 0; // BG1 (Layer 0)
49 static constexpr int kLayer2 = 1; // BG2 (Layer 1) - overlay objects
50 static constexpr int kLayer3 = 2; // BG3 (Layer 2)
51
52 explicit ObjectSelection() = default;
53
54 // ============================================================================
55 // Selection Operations
56 // ============================================================================
57
63 void SelectObject(size_t index, SelectionMode mode = SelectionMode::Single);
64
74 void SelectObjectsInRect(int room_min_x, int room_min_y, int room_max_x,
75 int room_max_y,
76 const std::vector<zelda3::RoomObject>& objects,
78
85 void SelectAll(size_t object_count);
86
91 void SelectAll(const std::vector<zelda3::RoomObject>& objects);
92
96 void ClearSelection();
97
103 bool IsObjectSelected(size_t index) const;
104
109 std::vector<size_t> GetSelectedIndices() const;
110
114 size_t GetSelectionCount() const { return selected_indices_.size(); }
115
119 bool HasSelection() const { return !selected_indices_.empty(); }
120
125 std::optional<size_t> GetPrimarySelection() const;
126
127 // ============================================================================
128 // Rectangle Selection State
129 // ============================================================================
130
136 void BeginRectangleSelection(int canvas_x, int canvas_y);
137
143 void UpdateRectangleSelection(int canvas_x, int canvas_y);
144
150 void EndRectangleSelection(const std::vector<zelda3::RoomObject>& objects,
152
157
164
169 std::tuple<int, int, int, int> GetRectangleSelectionBounds() const;
170
175 bool IsRectangleLargeEnough(int min_pixels) const;
176
177 // ============================================================================
178 // Visual Rendering
179 // ============================================================================
180
188 gui::Canvas* canvas, const std::vector<zelda3::RoomObject>& objects,
189 std::function<std::tuple<int, int, int, int>(const zelda3::RoomObject&)>
190 bounds_calculator);
191
197
203 ImVec4 GetLayerTypeColor(const zelda3::RoomObject& object) const;
204
205 // ============================================================================
206 // Callbacks
207 // ============================================================================
208
212 void SetSelectionChangedCallback(std::function<void()> callback) {
213 selection_changed_callback_ = std::move(callback);
214 }
215
216 // ============================================================================
217 // Layer Filtering
218 // ============================================================================
219
227 void SetLayerFilter(int layer) { active_layer_filter_ = layer; }
228
233 int GetLayerFilter() const { return active_layer_filter_; }
234
240 bool IsLayerEnabled(int layer) const {
242 }
243
249
254 const char* GetLayerFilterName() const {
255 switch (active_layer_filter_) {
256 case kMaskLayer:
257 return "Mask Mode (BG2 Overlays)";
258 case kLayer1:
259 return "Layer 1 (BG1)";
260 case kLayer2:
261 return "Layer 2 (BG2)";
262 case kLayer3:
263 return "Layer 3 (BG3)";
264 default:
265 return "All Layers";
266 }
267 }
268
274
281 return PassesLayerFilter(object);
282 }
283
290 void SetLayersMerged(bool merged) { layers_merged_ = merged; }
291
295 bool AreLayersMerged() const { return layers_merged_; }
296
297 // ============================================================================
298 // Utility Functions
299 // ============================================================================
300
307 static std::pair<int, int> RoomToCanvasCoordinates(int room_x, int room_y);
308
315 static std::pair<int, int> CanvasToRoomCoordinates(int canvas_x,
316 int canvas_y);
317
323 static std::tuple<int, int, int, int> GetObjectBounds(
324 const zelda3::RoomObject& object);
325
326 private:
327 // Selection state
328 std::set<size_t>
329 selected_indices_; // Using set for fast lookup and auto-sort
330
331 // Rectangle selection state
335 int rect_end_x_ = 0;
336 int rect_end_y_ = 0;
337
338 // Layer filtering state
340 kLayerAll; // -1 = all layers, 0/1/2 = specific layer
341 bool layers_merged_ = false; // Whether room has merged layers
342
343 // Callbacks
344 std::function<void()> selection_changed_callback_;
345
346 // Helper functions
348 bool IsObjectInRectangle(const zelda3::RoomObject& object, int min_x,
349 int min_y, int max_x, int max_y) const;
350 bool PassesLayerFilter(const zelda3::RoomObject& object) const;
351};
352
353} // namespace editor
354} // namespace yaze
355
356#endif // YAZE_APP_EDITOR_DUNGEON_OBJECT_SELECTION_H
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 IsObjectInRectangle(const zelda3::RoomObject &object, int min_x, int min_y, int max_x, int max_y) const
std::tuple< int, int, int, int > GetRectangleSelectionBounds() const
Get rectangle selection bounds in canvas coordinates.
bool IsMaskModeActive() const
Check if mask selection mode is active.
bool IsRectangleSelectionActive() const
Check if a rectangle selection is in progress.
void UpdateRectangleSelection(int canvas_x, int canvas_y)
Update rectangle selection endpoint.
static std::pair< int, int > RoomToCanvasCoordinates(int room_x, int room_y)
Convert room tile coordinates to canvas pixel coordinates.
void DrawSelectionHighlights(gui::Canvas *canvas, const std::vector< zelda3::RoomObject > &objects, std::function< std::tuple< int, int, int, int >(const zelda3::RoomObject &)> bounds_calculator)
Draw selection highlights for all selected objects.
int GetLayerFilter() const
Get the current active layer filter.
std::function< void()> selection_changed_callback_
static constexpr int kMaskLayer
bool IsObjectSelected(size_t index) const
Check if an object is selected.
std::set< size_t > selected_indices_
std::vector< size_t > GetSelectedIndices() const
Get all selected object indices.
static std::tuple< int, int, int, int > GetObjectBounds(const zelda3::RoomObject &object)
Calculate the bounding box of an object.
bool PassesLayerFilterForObject(const zelda3::RoomObject &object) const
Check if an object passes the current layer filter.
bool AreLayersMerged() const
Check if layers are currently merged.
bool IsRectangleLargeEnough(int min_pixels) const
Check if rectangle selection exceeds a minimum pixel size.
void SelectAll(size_t object_count)
Select all objects in the current room.
static std::pair< int, int > CanvasToRoomCoordinates(int canvas_x, int canvas_y)
Convert canvas pixel coordinates to room tile coordinates.
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.
void EndRectangleSelection(const std::vector< zelda3::RoomObject > &objects, SelectionMode mode=SelectionMode::Single)
Complete rectangle selection operation.
void BeginRectangleSelection(int canvas_x, int canvas_y)
Begin a rectangle selection operation.
bool PassesLayerFilter(const zelda3::RoomObject &object) const
const char * GetLayerFilterName() const
Get the name of the current layer filter for display.
ImVec4 GetLayerTypeColor(const zelda3::RoomObject &object) const
Get selection highlight color based on object layer and type.
void SetLayersMerged(bool merged)
Set whether layers are currently merged in the room.
static constexpr int kLayerAll
void SetLayerFilter(int layer)
Set the active layer filter for selection.
bool IsLayerFilterActive() const
Check if layer filtering is active.
void CancelRectangleSelection()
Cancel rectangle selection without modifying selection.
std::optional< size_t > GetPrimarySelection() const
Get the primary selected object (first in selection)
void DrawRectangleSelectionBox(gui::Canvas *canvas)
Draw the active rectangle selection box.
bool IsLayerEnabled(int layer) const
Check if a specific layer is enabled for selection.
void SelectObjectsInRect(int room_min_x, int room_min_y, int room_max_x, int room_max_y, const std::vector< zelda3::RoomObject > &objects, SelectionMode mode=SelectionMode::Single)
Select multiple objects within a rectangle.
bool HasSelection() const
Check if any objects are selected.
Modern, robust canvas for drawing and manipulating graphics.
Definition canvas.h:150