yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
canvas_automation_api.cc
Go to the documentation of this file.
2
3#include <algorithm>
4#include <cmath>
5
6#include "app/gui/canvas.h"
7
8namespace yaze {
9namespace gui {
10
12
13// ============================================================================
14// Tile Operations
15// ============================================================================
16
17bool CanvasAutomationAPI::SetTileAt(int x, int y, int tile_id) {
18 if (!IsInBounds(x, y)) {
19 return false;
20 }
21
23 return tile_paint_callback_(x, y, tile_id);
24 }
25
26 // Default behavior: add to canvas points for drawing
27 // Note: Actual tile painting depends on the editor's canvas integration
28 ImVec2 canvas_pos = TileToCanvas(x, y);
29 canvas_->mutable_points()->push_back(canvas_pos);
30 return true;
31}
32
33int CanvasAutomationAPI::GetTileAt(int x, int y) const {
34 if (!IsInBounds(x, y)) {
35 return -1;
36 }
37
39 return tile_query_callback_(x, y);
40 }
41
42 // Default: return -1 (requires callback for actual implementation)
43 return -1;
44}
45
47 const std::vector<std::tuple<int, int, int>>& tiles) {
48 bool all_success = true;
49 for (const auto& [x, y, tile_id] : tiles) {
50 if (!SetTileAt(x, y, tile_id)) {
51 all_success = false;
52 }
53 }
54 return all_success;
55}
56
57// ============================================================================
58// Selection Operations
59// ============================================================================
60
62 if (!IsInBounds(x, y)) {
63 return;
64 }
65
66 ImVec2 canvas_pos = TileToCanvas(x, y);
68 canvas_->mutable_selected_points()->push_back(canvas_pos);
69 canvas_->mutable_selected_points()->push_back(canvas_pos);
70}
71
72void CanvasAutomationAPI::SelectTileRect(int x1, int y1, int x2, int y2) {
73 // Ensure x1 <= x2 and y1 <= y2
74 if (x1 > x2) std::swap(x1, x2);
75 if (y1 > y2) std::swap(y1, y2);
76
77 if (!IsInBounds(x1, y1) || !IsInBounds(x2, y2)) {
78 return;
79 }
80
81 ImVec2 start = TileToCanvas(x1, y1);
82 ImVec2 end = TileToCanvas(x2, y2);
83
85 canvas_->mutable_selected_points()->push_back(start);
86 canvas_->mutable_selected_points()->push_back(end);
87}
88
90 SelectionState state;
91
92 const auto& selected_points = canvas_->selected_points();
93 if (selected_points.size() >= 2) {
94 state.has_selection = true;
95 state.selection_start = selected_points[0];
96 state.selection_end = selected_points[1];
97
98 // Convert canvas positions back to tile coordinates
99 ImVec2 tile_start = CanvasToTile(state.selection_start);
100 ImVec2 tile_end = CanvasToTile(state.selection_end);
101
102 // Ensure proper ordering
103 int min_x = std::min(static_cast<int>(tile_start.x),
104 static_cast<int>(tile_end.x));
105 int max_x = std::max(static_cast<int>(tile_start.x),
106 static_cast<int>(tile_end.x));
107 int min_y = std::min(static_cast<int>(tile_start.y),
108 static_cast<int>(tile_end.y));
109 int max_y = std::max(static_cast<int>(tile_start.y),
110 static_cast<int>(tile_end.y));
111
112 // Generate all tiles in selection rectangle
113 for (int y = min_y; y <= max_y; ++y) {
114 for (int x = min_x; x <= max_x; ++x) {
115 state.selected_tiles.push_back(ImVec2(static_cast<float>(x),
116 static_cast<float>(y)));
117 }
118 }
119 }
120
121 return state;
122}
123
127
128// ============================================================================
129// View Operations
130// ============================================================================
131
132void CanvasAutomationAPI::ScrollToTile(int x, int y, bool center) {
133 if (!IsInBounds(x, y)) {
134 return;
135 }
136
137 if (center) {
138 CenterOn(x, y);
139 return;
140 }
141
142 // Check if tile is already visible
143 if (IsTileVisible(x, y)) {
144 return;
145 }
146
147 // Scroll to make tile visible
148 ImVec2 tile_canvas_pos = TileToCanvas(x, y);
149
150 // Get current scroll and canvas size
151 ImVec2 current_scroll = canvas_->scrolling();
152 ImVec2 canvas_size = canvas_->canvas_size();
153
154 // Calculate new scroll to make tile visible at top-left
155 float new_scroll_x = -tile_canvas_pos.x;
156 float new_scroll_y = -tile_canvas_pos.y;
157
158 canvas_->set_scrolling(ImVec2(new_scroll_x, new_scroll_y));
159}
160
162 if (!IsInBounds(x, y)) {
163 return;
164 }
165
166 ImVec2 tile_canvas_pos = TileToCanvas(x, y);
167 ImVec2 canvas_size = canvas_->canvas_size();
168
169 // Center the tile in the canvas view
170 float new_scroll_x = -(tile_canvas_pos.x - canvas_size.x / 2.0f);
171 float new_scroll_y = -(tile_canvas_pos.y - canvas_size.y / 2.0f);
172
173 canvas_->set_scrolling(ImVec2(new_scroll_x, new_scroll_y));
174}
175
177 // Clamp zoom to reasonable range
178 zoom = std::max(0.25f, std::min(zoom, 4.0f));
180}
181
183 return canvas_->global_scale();
184}
185
186// ============================================================================
187// Query Operations
188// ============================================================================
189
191 Dimensions dims;
192
193 // Get canvas size in pixels
194 ImVec2 canvas_size = canvas_->canvas_size();
195 float scale = canvas_->global_scale();
196
197 // Determine tile size from canvas grid size
198 int tile_size = 16; // Default
199 switch (canvas_->grid_size()) {
201 tile_size = 8;
202 break;
204 tile_size = 16;
205 break;
207 tile_size = 32;
208 break;
210 tile_size = 64;
211 break;
212 }
213
214 dims.tile_size = tile_size;
215 dims.width_tiles = static_cast<int>(canvas_size.x / (tile_size * scale));
216 dims.height_tiles = static_cast<int>(canvas_size.y / (tile_size * scale));
217
218 return dims;
219}
220
222 VisibleRegion region;
223
224 ImVec2 scroll = canvas_->scrolling();
225 ImVec2 canvas_size = canvas_->canvas_size();
226 float scale = canvas_->global_scale();
227 int tile_size = GetDimensions().tile_size;
228
229 // Top-left corner of visible region
230 ImVec2 top_left = CanvasToTile(ImVec2(-scroll.x, -scroll.y));
231
232 // Bottom-right corner of visible region
233 ImVec2 bottom_right = CanvasToTile(ImVec2(-scroll.x + canvas_size.x,
234 -scroll.y + canvas_size.y));
235
236 region.min_x = std::max(0, static_cast<int>(top_left.x));
237 region.min_y = std::max(0, static_cast<int>(top_left.y));
238
239 Dimensions dims = GetDimensions();
240 region.max_x = std::min(dims.width_tiles - 1, static_cast<int>(bottom_right.x));
241 region.max_y = std::min(dims.height_tiles - 1, static_cast<int>(bottom_right.y));
242
243 return region;
244}
245
246bool CanvasAutomationAPI::IsTileVisible(int x, int y) const {
247 if (!IsInBounds(x, y)) {
248 return false;
249 }
250
252 return x >= region.min_x && x <= region.max_x &&
253 y >= region.min_y && y <= region.max_y;
254}
255
256bool CanvasAutomationAPI::IsInBounds(int x, int y) const {
257 if (x < 0 || y < 0) {
258 return false;
259 }
260
261 Dimensions dims = GetDimensions();
262 return x < dims.width_tiles && y < dims.height_tiles;
263}
264
265// ============================================================================
266// Coordinate Conversion
267// ============================================================================
268
269ImVec2 CanvasAutomationAPI::TileToCanvas(int x, int y) const {
270 int tile_size = GetDimensions().tile_size;
271 float scale = canvas_->global_scale();
272
273 float canvas_x = x * tile_size * scale;
274 float canvas_y = y * tile_size * scale;
275
276 return ImVec2(canvas_x, canvas_y);
277}
278
279ImVec2 CanvasAutomationAPI::CanvasToTile(ImVec2 canvas_pos) const {
280 int tile_size = GetDimensions().tile_size;
281 float scale = canvas_->global_scale();
282
283 float tile_x = canvas_pos.x / (tile_size * scale);
284 float tile_y = canvas_pos.y / (tile_size * scale);
285
286 return ImVec2(std::floor(tile_x), std::floor(tile_y));
287}
288
289// ============================================================================
290// Callback Registration
291// ============================================================================
292
296
300
301} // namespace gui
302} // namespace yaze
303
bool IsTileVisible(int x, int y) const
Check if a tile is currently visible.
void SetTileQueryCallback(TileQueryCallback callback)
void SetTilePaintCallback(TilePaintCallback callback)
bool IsInBounds(int x, int y) const
Check if coordinates are within canvas bounds.
bool SetTileAt(int x, int y, int tile_id)
Paint a single tile at logical coordinates.
std::function< bool(int x, int y, int tile_id)> TilePaintCallback
Set callback for tile painting operations. Allows external systems (CLI, AI agents) to implement cust...
void ClearSelection()
Clear current selection.
void SetZoom(float zoom)
Set canvas zoom level.
void SelectTileRect(int x1, int y1, int x2, int y2)
Select a rectangular region of tiles.
VisibleRegion GetVisibleRegion() const
Get currently visible tile region.
Dimensions GetDimensions() const
Get canvas dimensions in logical tile units.
SelectionState GetSelection() const
Query current selection state.
void CenterOn(int x, int y)
Center canvas view on a specific tile.
ImVec2 CanvasToTile(ImVec2 canvas_pos) const
Convert canvas pixel coordinates to logical tile coordinates.
float GetZoom() const
Get current zoom level.
bool SetTiles(const std::vector< std::tuple< int, int, int > > &tiles)
Paint multiple tiles in a batch operation.
ImVec2 TileToCanvas(int x, int y) const
Convert logical tile coordinates to canvas pixel coordinates.
std::function< int(int x, int y)> TileQueryCallback
Set callback for tile querying operations. Allows external systems to provide tile data.
void SelectTile(int x, int y)
Select a single tile.
int GetTileAt(int x, int y) const
Query tile ID at logical coordinates.
void ScrollToTile(int x, int y, bool center=false)
Scroll canvas to make tile visible.
Modern, robust canvas for drawing and manipulating graphics.
Definition canvas.h:54
void set_scrolling(ImVec2 scroll)
Definition canvas.h:312
auto global_scale() const
Definition canvas.h:345
ImVector< ImVec2 > * mutable_points()
Definition canvas.h:307
auto mutable_selected_points()
Definition canvas.h:399
CanvasGridSize grid_size() const
Definition canvas.h:97
auto canvas_size() const
Definition canvas.h:314
void set_global_scale(float scale)
Definition canvas.h:315
auto scrolling() const
Definition canvas.h:311
auto selected_points() const
Definition canvas.h:400
Main namespace for the application.
Canvas dimensions in logical tile units.
Selection state returned by GetSelection().
Visible region in logical tile coordinates.