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 // Stored placement filter constants
45 static constexpr int kLayerAll = -1; // Select from all placements
46 static constexpr int kMaskLayer =
47 -2; // Mask mode: only stored value 1 objects (BG2 overlays)
48 static constexpr int kLayer1 = 0; // Primary / upper layer (BG1)
49 static constexpr int kLayer2 = 1; // BG2 overlay / lower layer (BG2)
50 static constexpr int kLayer3 = 2; // BG1 overlay room stream
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
153 const std::vector<zelda3::RoomObject>& objects,
155 std::function<bool(const zelda3::RoomObject&)> is_object_visible = {});
156
161
168
173 std::tuple<int, int, int, int> GetRectangleSelectionBounds() const;
174
179 bool IsRectangleLargeEnough(int min_pixels) const;
180
181 // ============================================================================
182 // Visual Rendering
183 // ============================================================================
184
192 gui::Canvas* canvas, const std::vector<zelda3::RoomObject>& objects,
193 std::function<std::tuple<int, int, int, int>(const zelda3::RoomObject&)>
194 bounds_calculator);
195
201
207 ImVec4 GetLayerTypeColor(const zelda3::RoomObject& object) const;
208
209 // ============================================================================
210 // Callbacks
211 // ============================================================================
212
216 void SetSelectionChangedCallback(std::function<void()> callback) {
217 selection_changed_callback_ = std::move(callback);
218 }
219
220 // ============================================================================
221 // Layer Filtering
222 // ============================================================================
223
231 void SetLayerFilter(int layer) { active_layer_filter_ = layer; }
232
237 int GetLayerFilter() const { return active_layer_filter_; }
238
244 bool IsLayerEnabled(int layer) const {
246 }
247
253
258 const char* GetLayerFilterName() const {
259 switch (active_layer_filter_) {
260 case kMaskLayer:
261 return "Mask Mode (BG2 Overlays)";
262 case kLayer1:
263 return "Primary / Upper layer (BG1)";
264 case kLayer2:
265 return "BG2 overlay / Lower layer (BG2)";
266 case kLayer3:
267 return "BG1 overlay (room stream only)";
268 default:
269 return "All Stored Placements";
270 }
271 }
272
278
285 return PassesLayerFilter(object);
286 }
287
294 void SetLayersMerged(bool merged) { layers_merged_ = merged; }
295
299 bool AreLayersMerged() const { return layers_merged_; }
300
301 // ============================================================================
302 // Utility Functions
303 // ============================================================================
304
311 static std::pair<int, int> RoomToCanvasCoordinates(int room_x, int room_y);
312
319 static std::pair<int, int> CanvasToRoomCoordinates(int canvas_x,
320 int canvas_y);
321
327 static std::tuple<int, int, int, int> GetObjectBounds(
328 const zelda3::RoomObject& object);
329
330 private:
331 // Selection state
332 std::set<size_t>
333 selected_indices_; // Using set for fast lookup and auto-sort
334
335 // Rectangle selection state
339 int rect_end_x_ = 0;
340 int rect_end_y_ = 0;
341
342 // Layer filtering state
344 kLayerAll; // -1 = all layers, 0/1/2 = specific layer
345 bool layers_merged_ = false; // Whether room has merged layers
346
347 // Callbacks
348 std::function<void()> selection_changed_callback_;
349
350 // Helper functions
352 bool IsObjectInRectangle(const zelda3::RoomObject& object, int min_x,
353 int min_y, int max_x, int max_y) const;
354 bool PassesLayerFilter(const zelda3::RoomObject& object) const;
355};
356
357} // namespace editor
358} // namespace yaze
359
360#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_
void EndRectangleSelection(const std::vector< zelda3::RoomObject > &objects, SelectionMode mode=SelectionMode::Single, std::function< bool(const zelda3::RoomObject &)> is_object_visible={})
Complete rectangle selection operation.
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 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:64