yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
canvas_pipelines.cc
Go to the documentation of this file.
2
3#include <algorithm>
4
9#include "imgui/imgui.h"
10
11namespace yaze::gui {
12
13void BeginCanvas(Canvas& canvas, ImVec2 child_size) {
14 BeginPadding(1);
15
16 ImVec2 effective_size = child_size;
17 if (child_size.x == 0 && child_size.y == 0) {
18 if (canvas.IsAutoResize()) {
19 effective_size = canvas.GetPreferredSize();
20 } else {
21 effective_size = canvas.GetCurrentSize();
22 }
23 }
24
25 ImGui::BeginChild(canvas.canvas_id().c_str(), effective_size, true,
26 ImGuiWindowFlags_NoScrollbar);
27 canvas.DrawBackground();
28 EndPadding();
29 canvas.DrawContextMenu();
30}
31
32void EndCanvas(Canvas& canvas) {
33 canvas.DrawGrid();
34 canvas.DrawOverlay();
35 ImGui::EndChild();
36}
37
39 canvas.Begin(options);
40
41 CanvasRuntime runtime;
42 runtime.draw_list = canvas.draw_list();
43 runtime.canvas_p0 = canvas.zero_point();
44 runtime.canvas_sz = options.viewport_size.value_or(canvas.canvas_size());
45 runtime.scrolling = canvas.scrolling();
46 runtime.hovered = canvas.IsMouseHovering();
47 runtime.grid_step = options.grid_step.value_or(canvas.GetGridStep());
48 runtime.scale = canvas.GetGlobalScale();
49 runtime.content_size = canvas.GetCurrentSize();
50
51 return runtime;
52}
53
54void EndCanvas(Canvas& canvas, CanvasRuntime& /*runtime*/,
55 const CanvasFrameOptions& options) {
56 canvas.End(options);
57}
58
59ZoomToFitResult ComputeZoomToFit(ImVec2 content_px, ImVec2 canvas_px,
60 float padding_px) {
61 ZoomToFitResult result;
62 result.scale = 1.0f;
63 result.scroll = ImVec2(0, 0);
64
65 if (content_px.x <= 0 || content_px.y <= 0) {
66 return result;
67 }
68
69 float available_x = canvas_px.x - padding_px * 2;
70 float available_y = canvas_px.y - padding_px * 2;
71
72 if (available_x <= 0 || available_y <= 0) {
73 return result;
74 }
75
76 float scale_x = available_x / content_px.x;
77 float scale_y = available_y / content_px.y;
78 result.scale = std::min(scale_x, scale_y);
79
80 float scaled_w = content_px.x * result.scale;
81 float scaled_h = content_px.y * result.scale;
82 result.scroll.x = (canvas_px.x - scaled_w) / 2.0f;
83 result.scroll.y = (canvas_px.y - scaled_h) / 2.0f;
84
85 return result;
86}
87
88ImVec2 ClampScroll(ImVec2 scroll, ImVec2 content_px, ImVec2 canvas_px) {
89 float max_scroll_x = std::max(0.0f, content_px.x - canvas_px.x);
90 float max_scroll_y = std::max(0.0f, content_px.y - canvas_px.y);
91
92 return ImVec2(std::clamp(scroll.x, -max_scroll_x, 0.0f),
93 std::clamp(scroll.y, -max_scroll_y, 0.0f));
94}
95
96void GraphicsBinCanvasPipeline(int width, int height, int tile_size,
97 int num_sheets_to_load, int canvas_id,
98 bool is_loaded, gfx::BitmapTable& graphics_bin) {
99 Canvas canvas;
100 if (ImGuiID child_id =
101 ImGui::GetID((ImTextureID)(intptr_t)(intptr_t)canvas_id);
102 ImGui::BeginChild(child_id, ImGui::GetContentRegionAvail(), true,
103 ImGuiWindowFlags_AlwaysVerticalScrollbar)) {
104 canvas.DrawBackground(ImVec2(width + 1, num_sheets_to_load * height + 1));
105 canvas.DrawContextMenu();
106 if (is_loaded) {
107 ScopedNearestSampling nearest_sampling(canvas.draw_list());
108 for (const auto& [key, value] : graphics_bin) {
109 if (!value || !value->texture()) {
110 continue;
111 }
112 int offset = height * (key + 1);
113 int top_left_y = canvas.zero_point().y + 2;
114 if (key >= 1) {
115 top_left_y = canvas.zero_point().y + height * key;
116 }
117 canvas.draw_list()->AddImage(
118 (ImTextureID)(intptr_t)value->texture(),
119 ImVec2(canvas.zero_point().x + 2, top_left_y),
120 ImVec2(canvas.zero_point().x + 0x100,
121 canvas.zero_point().y + offset),
122 ImVec2(0, 0), ImVec2(1, 1), ImGui::GetColorU32(ImVec4(1, 1, 1, 1)));
123 }
124 }
125 canvas.DrawTileSelector(tile_size);
126 canvas.DrawGrid(tile_size);
127 canvas.DrawOverlay();
128 canvas.RenderPersistentPopups();
129 }
130 ImGui::EndChild();
131}
132
133void BitmapCanvasPipeline(Canvas& canvas, gfx::Bitmap& bitmap, int width,
134 int height, int tile_size, bool is_loaded,
135 bool scrollbar, int canvas_id) {
136 auto draw_canvas = [&](Canvas& c, gfx::Bitmap& bmp, int w, int h, int ts,
137 bool loaded) {
138 c.DrawBackground(ImVec2(w + 1, h + 1));
139 c.DrawContextMenu();
140 c.DrawBitmap(bmp, 2, loaded);
141 c.DrawTileSelector(ts);
142 c.DrawGrid(ts);
143 c.DrawOverlay();
145 };
146
147 if (scrollbar) {
148 if (ImGuiID child_id =
149 ImGui::GetID((ImTextureID)(intptr_t)(intptr_t)canvas_id);
150 ImGui::BeginChild(child_id, ImGui::GetContentRegionAvail(), true,
151 ImGuiWindowFlags_AlwaysVerticalScrollbar)) {
152 draw_canvas(canvas, bitmap, width, height, tile_size, is_loaded);
153 }
154 ImGui::EndChild();
155 } else {
156 draw_canvas(canvas, bitmap, width, height, tile_size, is_loaded);
157 }
158}
159
161 const std::string& label, bool auto_resize) {
162 canvas.SetAutoResize(auto_resize);
163
164 if (auto_resize && bitmap.is_active()) {
165 ImVec2 content_size = ImVec2(bitmap.width(), bitmap.height());
166 ImVec2 preferred_size = CanvasUtils::CalculatePreferredCanvasSize(
167 content_size, canvas.GetGlobalScale());
168 canvas.SetCanvasSize(preferred_size);
169 }
170
171 if (canvas.BeginTableCanvas(label)) {
172 canvas.DrawBackground();
173 canvas.DrawContextMenu();
174
175 if (bitmap.is_active()) {
176 canvas.DrawBitmap(bitmap, 2, 2, canvas.GetGlobalScale());
177 }
178
179 canvas.DrawGrid();
180 canvas.DrawOverlay();
181 canvas.RenderPersistentPopups();
182 }
183 canvas.EndTableCanvas();
184}
185
186} // namespace yaze::gui
Represents a bitmap image optimized for SNES ROM hacking.
Definition bitmap.h:70
bool is_active() const
Definition bitmap.h:414
int height() const
Definition bitmap.h:399
int width() const
Definition bitmap.h:398
Modern, robust canvas for drawing and manipulating graphics.
Definition canvas.h:64
void DrawBitmap(Bitmap &bitmap, int border_offset, float scale)
Definition canvas.cc:1295
bool BeginTableCanvas(const std::string &label="")
Definition canvas.cc:501
void DrawContextMenu()
Definition canvas.cc:824
auto draw_list() const
Definition canvas.h:363
bool DrawTileSelector(int size, int size_y=0)
Definition canvas.cc:1231
ImVec2 GetCurrentSize() const
Definition canvas.h:290
void SetCanvasSize(ImVec2 canvas_size)
Definition canvas.h:388
ImVec2 GetPreferredSize() const
Definition canvas.cc:491
float GetGridStep() const
Definition canvas.h:396
void Begin(ImVec2 canvas_size=ImVec2(0, 0))
Begin canvas rendering (ImGui-style)
Definition canvas.cc:608
auto canvas_size() const
Definition canvas.h:373
auto canvas_id() const
Definition canvas.h:420
void RenderPersistentPopups()
Definition canvas.cc:1010
bool IsAutoResize() const
Definition canvas.h:292
void End()
End canvas rendering (ImGui-style)
Definition canvas.cc:614
float GetGlobalScale() const
Definition canvas.h:392
auto zero_point() const
Definition canvas.h:364
bool IsMouseHovering() const
Definition canvas.h:354
void DrawBackground(ImVec2 canvas_size=ImVec2(0, 0), std::optional< ImVec2 > viewport_size=std::nullopt)
Definition canvas.cc:703
auto scrolling() const
Definition canvas.h:366
void EndTableCanvas()
Definition canvas.cc:524
void SetAutoResize(bool auto_resize)
Definition canvas.h:291
void DrawGrid(float grid_step=64.0f, int tile_id_offset=8)
Definition canvas.cc:1627
RAII scope that samples the images drawn inside it with nearest-neighbor filtering.
std::unordered_map< int, std::unique_ptr< gfx::Bitmap > > BitmapTable
Definition bitmap.h:549
ImVec2 CalculatePreferredCanvasSize(ImVec2 content_size, float global_scale, float min_scale)
Graphical User Interface (GUI) components for the application.
void EndCanvas(Canvas &canvas)
void BeginPadding(int i)
Definition style.cc:299
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)
void EndPadding()
Definition style.cc:303
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< ImVec2 > viewport_size
std::optional< float > grid_step