5#include "imgui/imgui.h"
14 return ImVec2(std::floor(pos.x / grid_step) * grid_step,
15 std::floor(pos.y / grid_step) * grid_step);
36 ImVec2 canvas_p0, ImVec2 scrolling,
float ,
float ,
37 ImVec2 ,
bool is_hovered) {
46 const ImGuiIO& imgui_io = ImGui::GetIO();
47 const ImVec2 origin(canvas_p0.x + scrolling.x, canvas_p0.y + scrolling.y);
58 const gfx::Bitmap& bitmap, ImDrawList* draw_list, ImVec2 canvas_p0,
59 ImVec2 scrolling,
float global_scale,
float tile_size,
bool is_hovered) {
61 const ImGuiIO& imgui_io = ImGui::GetIO();
62 const ImVec2 origin(canvas_p0.x + scrolling.x, canvas_p0.y + scrolling.y);
63 const ImVec2 mouse_pos(imgui_io.MousePos.x - origin.x, imgui_io.MousePos.y - origin.y);
64 const auto scaled_size = tile_size * global_scale;
76 ImVec2 paint_pos = AlignToGridLocal(mouse_pos, scaled_size);
78 auto paint_pos_end = ImVec2(paint_pos.x + scaled_size, paint_pos.y + scaled_size);
86 reinterpret_cast<ImTextureID
>(bitmap.
texture()),
87 ImVec2(origin.x + paint_pos.x, origin.y + paint_pos.y),
88 ImVec2(origin.x + paint_pos.x + scaled_size, origin.y + paint_pos.y + scaled_size));
92 if (ImGui::IsMouseClicked(ImGuiMouseButton_Left) &&
93 ImGui::IsMouseDragging(ImGuiMouseButton_Left)) {
102 gfx::Tilemap& tilemap,
int current_tile, ImDrawList* draw_list,
103 ImVec2 canvas_p0, ImVec2 scrolling,
float global_scale,
bool is_hovered) {
105 const ImGuiIO& imgui_io = ImGui::GetIO();
106 const ImVec2 origin(canvas_p0.x + scrolling.x, canvas_p0.y + scrolling.y);
107 const ImVec2 mouse_pos(imgui_io.MousePos.x - origin.x, imgui_io.MousePos.y - origin.y);
114 const auto scaled_size = tilemap.
tile_size.
x * global_scale;
123 ImVec2 paint_pos =
AlignToGrid(mouse_pos, scaled_size);
127 hover_points_.push_back(ImVec2(paint_pos.x + scaled_size, paint_pos.y + scaled_size));
132 if (tiles_per_row > 0) {
133 int tile_x = (current_tile % tiles_per_row) * tilemap.
tile_size.
x;
134 int tile_y = (current_tile / tiles_per_row) * tilemap.
tile_size.
y;
136 if (tile_x >= 0 && tile_x < tilemap.
atlas.
width() &&
139 ImVec2 uv0 = ImVec2(
static_cast<float>(tile_x) / tilemap.
atlas.
width(),
140 static_cast<float>(tile_y) / tilemap.
atlas.
height());
146 ImVec2(origin.x + paint_pos.x, origin.y + paint_pos.y),
147 ImVec2(origin.x + paint_pos.x + scaled_size, origin.y + paint_pos.y + scaled_size),
153 if (ImGui::IsMouseClicked(ImGuiMouseButton_Left) ||
154 ImGui::IsMouseDragging(ImGuiMouseButton_Left)) {
163 const ImVec4& color, ImDrawList* draw_list, ImVec2 canvas_p0,
164 ImVec2 scrolling,
float global_scale,
float tile_size,
bool is_hovered) {
166 const ImGuiIO& imgui_io = ImGui::GetIO();
167 const ImVec2 origin(canvas_p0.x + scrolling.x, canvas_p0.y + scrolling.y);
168 const ImVec2 mouse_pos(imgui_io.MousePos.x - origin.x, imgui_io.MousePos.y - origin.y);
169 auto scaled_tile_size = tile_size * global_scale;
170 static bool is_dragging =
false;
171 static ImVec2 start_drag_pos;
180 ImVec2 paint_pos =
AlignToGrid(mouse_pos, scaled_tile_size);
187 hover_points_.push_back(ImVec2(paint_pos.x + scaled_tile_size, paint_pos.y + scaled_tile_size));
190 draw_list->AddRectFilled(
191 ImVec2(origin.x + paint_pos.x + 1, origin.y + paint_pos.y + 1),
192 ImVec2(origin.x + paint_pos.x + scaled_tile_size,
193 origin.y + paint_pos.y + scaled_tile_size),
194 IM_COL32(color.x * 255, color.y * 255, color.z * 255, 255));
197 if (ImGui::IsMouseClicked(ImGuiMouseButton_Left)) {
199 start_drag_pos = paint_pos;
202 if (is_dragging && ImGui::IsMouseReleased(ImGuiMouseButton_Left)) {
212 ImDrawList* , ImVec2 canvas_p0, ImVec2 scrolling,
float tile_size,
215 const ImGuiIO& imgui_io = ImGui::GetIO();
216 const ImVec2 origin(canvas_p0.x + scrolling.x, canvas_p0.y + scrolling.y);
217 const ImVec2 mouse_pos(imgui_io.MousePos.x - origin.x, imgui_io.MousePos.y - origin.y);
219 if (is_hovered && ImGui::IsMouseClicked(ImGuiMouseButton_Left)) {
221 ImVec2 painter_pos = AlignToGridLocal(mouse_pos, tile_size);
224 hover_points_.push_back(ImVec2(painter_pos.x + tile_size, painter_pos.y + tile_size));
228 if (is_hovered && ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left)) {
236 int current_map, ImDrawList* draw_list, ImVec2 canvas_p0, ImVec2 scrolling,
237 float global_scale,
float tile_size,
bool is_hovered) {
247 geometry.
scaled_size = ImVec2(tile_size * global_scale, tile_size * global_scale);
248 geometry.
canvas_sz = ImVec2(tile_size, tile_size);
252 geometry, current_map, tile_size, draw_list, ImGuiMouseButton_Right);
255 if (event.is_complete) {
264 if (!event.selected_tiles.empty() && !event.is_complete) {
279 return AlignToGridLocal(pos, grid_step);
283 const ImGuiIO& imgui_io = ImGui::GetIO();
284 const ImVec2 origin(canvas_p0.x + scrolling.x, canvas_p0.y + scrolling.y);
285 return ImVec2(imgui_io.MousePos.x - origin.x, imgui_io.MousePos.y - origin.y);
289 return ImGui::IsMouseClicked(button);
293 return ImGui::IsMouseDoubleClicked(button);
297 return ImGui::IsMouseDragging(button);
301 return ImGui::IsMouseReleased(button);
Free functions for canvas interaction handling.
Represents a bitmap image optimized for SNES ROM hacking.
TextureHandle texture() const
ImVector< ImVec2 > hover_points_
bool DrawSelectRect(int current_map, ImDrawList *draw_list, ImVec2 canvas_p0, ImVec2 scrolling, float global_scale, float tile_size, bool is_hovered)
Draw rectangle selector (multi-tile selection)
ImVector< ImVec2 > selected_points_
void ClearState()
Clear all interaction state.
bool DrawTilemapPainter(gfx::Tilemap &tilemap, int current_tile, ImDrawList *draw_list, ImVec2 canvas_p0, ImVec2 scrolling, float global_scale, bool is_hovered)
Draw tilemap painter (preview + interaction)
ImVec2 AlignPosToGrid(ImVec2 pos, float grid_step)
ImVec2 selected_tile_pos_
TileInteractionResult Update(ImVec2 canvas_p0, ImVec2 scrolling, float global_scale, float tile_size, ImVec2 canvas_size, bool is_hovered)
Update interaction state (call once per frame)
ImVec2 mouse_pos_in_canvas_
bool DrawTileSelector(ImDrawList *draw_list, ImVec2 canvas_p0, ImVec2 scrolling, float tile_size, bool is_hovered)
Draw tile selector (single tile selection)
bool DrawSolidTilePainter(const ImVec4 &color, ImDrawList *draw_list, ImVec2 canvas_p0, ImVec2 scrolling, float global_scale, float tile_size, bool is_hovered)
Draw solid color painter.
bool IsMouseClicked(ImGuiMouseButton button)
bool IsMouseDragging(ImGuiMouseButton button)
bool IsMouseReleased(ImGuiMouseButton button)
bool IsMouseDoubleClicked(ImGuiMouseButton button)
std::vector< ImVec2 > selected_tiles_
bool DrawTilePainter(const gfx::Bitmap &bitmap, ImDrawList *draw_list, ImVec2 canvas_p0, ImVec2 scrolling, float global_scale, float tile_size, bool is_hovered)
Draw tile painter (preview + interaction)
ImVec2 GetMousePosition(ImVec2 canvas_p0, ImVec2 scrolling)
void Initialize(const std::string &canvas_id)
Initialize the interaction handler.
TileInteractionMode current_mode_
ImVec2 AlignToGridLocal(ImVec2 pos, float grid_step)
ImVec2 AlignToGrid(ImVec2 pos, float grid_step)
Align position to grid.
RectSelectionEvent HandleRectangleSelection(const CanvasGeometry &geometry, int current_map, float tile_size, ImDrawList *draw_list, ImGuiMouseButton mouse_button)
Handle rectangle selection interaction.
Main namespace for the application.
int y
Y coordinate or height.
int x
X coordinate or width.
Tilemap structure for SNES tile-based graphics management.
Pair tile_size
Size of individual tiles (8x8 or 16x16)
Bitmap atlas
Master bitmap containing all tiles.
Canvas geometry calculated per-frame.
Event payload for rectangle selection operations.
Result of a tile interaction operation.