8#include "imgui/imgui.h"
15 ImVec2 effective_size = child_size;
16 if (child_size.x == 0 && child_size.y == 0) {
24 ImGui::BeginChild(canvas.
canvas_id().c_str(), effective_size,
true,
25 ImGuiWindowFlags_NoScrollbar);
38 canvas.
Begin(options);
62 result.
scroll = ImVec2(0, 0);
64 if (content_px.x <= 0 || content_px.y <= 0) {
68 float available_x = canvas_px.x - padding_px * 2;
69 float available_y = canvas_px.y - padding_px * 2;
71 if (available_x <= 0 || available_y <= 0) {
75 float scale_x = available_x / content_px.x;
76 float scale_y = available_y / content_px.y;
77 result.
scale = std::min(scale_x, scale_y);
79 float scaled_w = content_px.x * result.
scale;
80 float scaled_h = content_px.y * result.
scale;
81 result.
scroll.x = (canvas_px.x - scaled_w) / 2.0f;
82 result.
scroll.y = (canvas_px.y - scaled_h) / 2.0f;
87ImVec2
ClampScroll(ImVec2 scroll, ImVec2 content_px, ImVec2 canvas_px) {
88 float max_scroll_x = std::max(0.0f, content_px.x - canvas_px.x);
89 float max_scroll_y = std::max(0.0f, content_px.y - canvas_px.y);
91 return ImVec2(std::clamp(scroll.x, -max_scroll_x, 0.0f),
92 std::clamp(scroll.y, -max_scroll_y, 0.0f));
96 int num_sheets_to_load,
int canvas_id,
99 if (ImGuiID child_id =
100 ImGui::GetID((ImTextureID)(intptr_t)(intptr_t)canvas_id);
101 ImGui::BeginChild(child_id, ImGui::GetContentRegionAvail(),
true,
102 ImGuiWindowFlags_AlwaysVerticalScrollbar)) {
103 canvas.
DrawBackground(ImVec2(width + 1, num_sheets_to_load * height + 1));
106 for (
const auto& [key, value] : graphics_bin) {
107 if (!value || !value->texture()) {
110 int offset = height * (key + 1);
113 top_left_y = canvas.
zero_point().y + height * key;
116 (ImTextureID)(intptr_t)value->texture(),
117 ImVec2(canvas.
zero_point().x + 2, top_left_y),
131 int height,
int tile_size,
bool is_loaded,
132 bool scrollbar,
int canvas_id) {
145 if (ImGuiID child_id =
146 ImGui::GetID((ImTextureID)(intptr_t)(intptr_t)canvas_id);
147 ImGui::BeginChild(child_id, ImGui::GetContentRegionAvail(),
true,
148 ImGuiWindowFlags_AlwaysVerticalScrollbar)) {
149 draw_canvas(canvas, bitmap, width, height, tile_size, is_loaded);
153 draw_canvas(canvas, bitmap, width, height, tile_size, is_loaded);
158 const std::string& label,
bool auto_resize) {
162 ImVec2 content_size = ImVec2(bitmap.
width(), bitmap.
height());
Represents a bitmap image optimized for SNES ROM hacking.
Modern, robust canvas for drawing and manipulating graphics.
void DrawBitmap(Bitmap &bitmap, int border_offset, float scale)
bool BeginTableCanvas(const std::string &label="")
bool DrawTileSelector(int size, int size_y=0)
ImVec2 GetCurrentSize() const
void SetCanvasSize(ImVec2 canvas_size)
ImVec2 GetPreferredSize() const
float GetGridStep() const
void Begin(ImVec2 canvas_size=ImVec2(0, 0))
Begin canvas rendering (ImGui-style)
void RenderPersistentPopups()
bool IsAutoResize() const
void End()
End canvas rendering (ImGui-style)
float GetGlobalScale() const
bool IsMouseHovering() const
void DrawBackground(ImVec2 canvas_size=ImVec2(0, 0))
void SetAutoResize(bool auto_resize)
void DrawGrid(float grid_step=64.0f, int tile_id_offset=8)
std::unordered_map< int, std::unique_ptr< gfx::Bitmap > > BitmapTable
ImVec2 CalculatePreferredCanvasSize(ImVec2 content_size, float global_scale, float min_scale)
Graphical User Interface (GUI) components for the application.
void EndCanvas(Canvas &canvas)
void BeginCanvas(Canvas &canvas, ImVec2 child_size)
void GraphicsBinCanvasPipeline(int width, int height, int tile_size, int num_sheets_to_load, int canvas_id, bool is_loaded, gfx::BitmapTable &graphics_bin)
ImVec2 ClampScroll(ImVec2 scroll, ImVec2 content_px, ImVec2 canvas_px)
void TableCanvasPipeline(Canvas &canvas, gfx::Bitmap &bitmap, const std::string &label, bool auto_resize)
ZoomToFitResult ComputeZoomToFit(ImVec2 content_px, ImVec2 canvas_px, float padding_px)
void BitmapCanvasPipeline(Canvas &canvas, gfx::Bitmap &bitmap, int width, int height, int tile_size, bool is_loaded, bool scrollbar, int canvas_id)
std::optional< float > grid_step