yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
tile_selector_widget.cc
Go to the documentation of this file.
2
3#include <algorithm>
4
5namespace yaze::gui {
6
8 : config_(),
9 total_tiles_(config_.total_tiles),
10 widget_id_(std::move(widget_id)) {}
11
12TileSelectorWidget::TileSelectorWidget(std::string widget_id, Config config)
13 : config_(config),
14 total_tiles_(config.total_tiles),
15 widget_id_(std::move(widget_id)) {}
16
18 canvas_ = canvas;
19}
20
21void TileSelectorWidget::SetTileCount(int total_tiles) {
22 total_tiles_ = std::max(total_tiles, 0);
25 }
26}
27
29 if (IsValidTileId(tile_id)) {
30 selected_tile_id_ = tile_id;
31 }
32}
33
35 bool atlas_ready) {
36 RenderResult result;
37
38 if (!canvas_) {
39 return result;
40 }
41
42 const int tile_display_size =
43 static_cast<int>(config_.tile_size * config_.display_scale);
44
45 // Calculate total content size for ImGui child window scrolling
46 const int num_rows =
48 const ImVec2 content_size(
49 config_.tiles_per_row * tile_display_size + config_.draw_offset.x * 2,
50 num_rows * tile_display_size + config_.draw_offset.y * 2);
51
52 // Set content size for ImGui child window (must be called before
53 // DrawBackground)
54 ImGui::SetCursorPos(ImVec2(0, 0));
55 ImGui::Dummy(content_size);
56 ImGui::SetCursorPos(ImVec2(0, 0));
57
58 // Handle pending scroll (deferred from ScrollToTile call outside render
59 // context)
60 if (pending_scroll_tile_id_ >= 0) {
62 const ImVec2 target = TileOrigin(pending_scroll_tile_id_);
64 const ImVec2 window_size = ImGui::GetWindowSize();
65 float scroll_x =
66 target.x - (window_size.x / 2.0f) + (tile_display_size / 2.0f);
67 float scroll_y =
68 target.y - (window_size.y / 2.0f) + (tile_display_size / 2.0f);
69 scroll_x = std::max(0.0f, scroll_x);
70 scroll_y = std::max(0.0f, scroll_y);
71 ImGui::SetScrollX(scroll_x);
72 ImGui::SetScrollY(scroll_y);
73 }
74 }
75 pending_scroll_tile_id_ = -1; // Clear pending scroll
76 }
77
80
81 if (atlas_ready && atlas.is_active()) {
82 canvas_->DrawBitmap(atlas, static_cast<int>(config_.draw_offset.x),
83 static_cast<int>(config_.draw_offset.y),
85
86 result = HandleInteraction(tile_display_size);
87
89 DrawTileIdLabels(tile_display_size);
90 }
91
92 DrawHighlight(tile_display_size);
93 }
94
97
98 return result;
99}
100
102 int tile_display_size) {
103 RenderResult result;
104
105 if (!ImGui::IsItemHovered()) {
106 return result;
107 }
108
109 const bool clicked = ImGui::IsMouseClicked(ImGuiMouseButton_Left);
110 const bool double_clicked =
111 ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left);
112
113 if (clicked || double_clicked) {
114 const int hovered_tile = ResolveTileAtCursor(tile_display_size);
115 if (IsValidTileId(hovered_tile)) {
116 result.tile_clicked = clicked;
117 result.tile_double_clicked = double_clicked;
118 if (hovered_tile != selected_tile_id_) {
119 selected_tile_id_ = hovered_tile;
120 result.selection_changed = true;
121 }
123 }
124 }
125
126 return result;
127}
128
129int TileSelectorWidget::ResolveTileAtCursor(int tile_display_size) const {
130 if (!canvas_) {
131 return -1;
132 }
133
134 const ImVec2 screen_pos = ImGui::GetIO().MousePos;
135 const ImVec2 origin = canvas_->zero_point();
136 const ImVec2 scroll = canvas_->scrolling();
137
138 // Convert screen position to canvas content position (accounting for scroll)
139 ImVec2 local =
140 ImVec2(screen_pos.x - origin.x - config_.draw_offset.x - scroll.x,
141 screen_pos.y - origin.y - config_.draw_offset.y - scroll.y);
142
143 if (local.x < 0.0f || local.y < 0.0f) {
144 return -1;
145 }
146
147 const int column = static_cast<int>(local.x / tile_display_size);
148 const int row = static_cast<int>(local.y / tile_display_size);
149
150 return row * config_.tiles_per_row + column;
151}
152
153void TileSelectorWidget::DrawHighlight(int tile_display_size) const {
155 return;
156 }
157
158 const int column = selected_tile_id_ % config_.tiles_per_row;
159 const int row = selected_tile_id_ / config_.tiles_per_row;
160
161 const float x = config_.draw_offset.x + column * tile_display_size;
162 const float y = config_.draw_offset.y + row * tile_display_size;
163
164 canvas_->DrawOutlineWithColor(static_cast<int>(x), static_cast<int>(y),
165 tile_display_size, tile_display_size,
167}
168
170 // Future enhancement: draw ImGui text overlay with tile indices.
171}
172
173void TileSelectorWidget::ScrollToTile(int tile_id, bool use_imgui_scroll) {
174 if (!canvas_ || !IsValidTileId(tile_id)) {
175 return;
176 }
177
178 // Defer scroll until next render (when we're in the correct ImGui window
179 // context)
180 pending_scroll_tile_id_ = tile_id;
181 pending_scroll_use_imgui_ = use_imgui_scroll;
182}
183
184ImVec2 TileSelectorWidget::TileOrigin(int tile_id) const {
185 if (!IsValidTileId(tile_id)) {
186 return ImVec2(-1, -1);
187 }
188 const int tile_display_size =
189 static_cast<int>(config_.tile_size * config_.display_scale);
190 const int column = tile_id % config_.tiles_per_row;
191 const int row = tile_id / config_.tiles_per_row;
192 return ImVec2(config_.draw_offset.x + column * tile_display_size,
193 config_.draw_offset.y + row * tile_display_size);
194}
195
196bool TileSelectorWidget::IsValidTileId(int tile_id) const {
197 return tile_id >= 0 && tile_id < total_tiles_;
198}
199
200} // namespace yaze::gui
Represents a bitmap image optimized for SNES ROM hacking.
Definition bitmap.h:67
bool is_active() const
Definition bitmap.h:384
Modern, robust canvas for drawing and manipulating graphics.
Definition canvas.h:150
void DrawBitmap(Bitmap &bitmap, int border_offset, float scale)
Definition canvas.cc:1075
void DrawOutlineWithColor(int x, int y, int w, int h, ImVec4 color)
Definition canvas.cc:1144
void DrawContextMenu()
Definition canvas.cc:602
auto zero_point() const
Definition canvas.h:443
auto scrolling() const
Definition canvas.h:445
void DrawBackground(ImVec2 canvas_size=ImVec2(0, 0))
Definition canvas.cc:547
void DrawGrid(float grid_step=64.0f, int tile_id_offset=8)
Definition canvas.cc:1398
int ResolveTileAtCursor(int tile_display_size) const
RenderResult Render(gfx::Bitmap &atlas, bool atlas_ready)
bool IsValidTileId(int tile_id) const
ImVec2 TileOrigin(int tile_id) const
RenderResult HandleInteraction(int tile_display_size)
void ScrollToTile(int tile_id, bool use_imgui_scroll=true)
void DrawTileIdLabels(int tile_display_size) const
void DrawHighlight(int tile_display_size) const
TileSelectorWidget(std::string widget_id)
Graphical User Interface (GUI) components for the application.