yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
canvas_modals.cc
Go to the documentation of this file.
1#include "canvas_modals.h"
2
3#include <algorithm>
4#include <iomanip>
5#include <sstream>
6
10#include "app/gui/core/icons.h"
12#include "imgui/imgui.h"
13
14namespace yaze {
15namespace gui {
16
17// Helper functions for dispatching config callbacks
18namespace {
19inline void DispatchConfig(
20 const std::function<void(const CanvasConfig&)>& callback,
21 const CanvasConfig& config) {
22 if (callback)
23 callback(config);
24}
25
26inline void DispatchScale(
27 const std::function<void(const CanvasConfig&)>& callback,
28 const CanvasConfig& config) {
29 if (callback)
30 callback(config);
31}
32} // namespace
33
34void CanvasModals::ShowAdvancedProperties(const std::string& canvas_id,
35 const CanvasConfig& config,
36 const gfx::Bitmap* bitmap) {
37 std::string modal_id = canvas_id + "_advanced_properties";
38
39 auto render_func = [=]() mutable {
40 CanvasConfig mutable_config = config; // Create mutable copy
41 mutable_config.on_config_changed = config.on_config_changed;
42 mutable_config.on_scale_changed = config.on_scale_changed;
43 RenderAdvancedPropertiesModal(modal_id, mutable_config, bitmap);
44 };
45
46 OpenModal(modal_id, render_func);
47}
48
49void CanvasModals::ShowScalingControls(const std::string& canvas_id,
50 const CanvasConfig& config,
51 const gfx::Bitmap* bitmap) {
52 std::string modal_id = canvas_id + "_scaling_controls";
53
54 auto render_func = [=]() mutable {
55 CanvasConfig mutable_config = config; // Create mutable copy
56 mutable_config.on_config_changed = config.on_config_changed;
57 mutable_config.on_scale_changed = config.on_scale_changed;
58 RenderScalingControlsModal(modal_id, mutable_config, bitmap);
59 };
60
61 OpenModal(modal_id, render_func);
62}
63
65 const std::string& canvas_id, const BppConversionOptions& options) {
66 std::string modal_id = canvas_id + "_bpp_conversion";
67
68 auto render_func = [=]() {
69 RenderBppConversionModal(modal_id, options);
70 };
71
72 OpenModal(modal_id, render_func);
73}
74
75void CanvasModals::ShowPaletteEditor(const std::string& canvas_id,
76 const PaletteEditorOptions& options) {
77 std::string modal_id = canvas_id + "_palette_editor";
78
79 auto render_func = [=]() {
80 RenderPaletteEditorModal(modal_id, options);
81 };
82
83 OpenModal(modal_id, render_func);
84}
85
86void CanvasModals::ShowColorAnalysis(const std::string& canvas_id,
87 const ColorAnalysisOptions& options) {
88 std::string modal_id = canvas_id + "_color_analysis";
89
90 auto render_func = [=]() {
91 RenderColorAnalysisModal(modal_id, options);
92 };
93
94 OpenModal(modal_id, render_func);
95}
96
98 const std::string& canvas_id, const PerformanceOptions& options) {
99 std::string modal_id = canvas_id + "_performance";
100
101 auto render_func = [=]() {
102 RenderPerformanceModal(modal_id, options);
103 };
104
105 OpenModal(modal_id, render_func);
106}
107
109 for (auto& modal : active_modals_) {
110 if (modal.is_open) {
111 modal.render_func();
112 }
113 }
114
115 // Remove closed modals
116 active_modals_.erase(
117 std::remove_if(active_modals_.begin(), active_modals_.end(),
118 [](const ModalState& modal) { return !modal.is_open; }),
119 active_modals_.end());
120}
121
123 return std::any_of(active_modals_.begin(), active_modals_.end(),
124 [](const ModalState& modal) { return modal.is_open; });
125}
126
127void CanvasModals::RenderAdvancedPropertiesModal(const std::string& canvas_id,
128 CanvasConfig& config,
129 const gfx::Bitmap* bitmap) {
130 std::string modal_title = "Advanced Canvas Properties";
131 ImGui::SetNextWindowSize(ImVec2(600, 500), ImGuiCond_FirstUseEver);
132
133 if (ImGui::BeginPopupModal(modal_title.c_str(), nullptr,
134 ImGuiWindowFlags_AlwaysAutoResize)) {
135 // Header with icon
136 ImGui::Text("%s %s", ICON_MD_SETTINGS, modal_title.c_str());
137 ImGui::Separator();
138
139 // Canvas Information Section
140 if (ImGui::CollapsingHeader(ICON_MD_ANALYTICS " Canvas Information",
141 ImGuiTreeNodeFlags_DefaultOpen)) {
142 ImGui::Columns(2, "CanvasInfo");
143
145 "Canvas Size",
146 std::to_string(static_cast<int>(config.canvas_size.x)) + " x " +
147 std::to_string(static_cast<int>(config.canvas_size.y)),
148 ICON_MD_STRAIGHTEN, ImVec4(0.2F, 0.8F, 1.0F, 1.0F));
149
151 "Content Size",
152 std::to_string(static_cast<int>(config.content_size.x)) + " x " +
153 std::to_string(static_cast<int>(config.content_size.y)),
154 ICON_MD_IMAGE, ImVec4(0.8F, 0.2F, 1.0F, 1.0F));
155
156 ImGui::NextColumn();
157
159 "Global Scale",
160 std::to_string(static_cast<int>(config.global_scale * 100)) + "%",
161 ICON_MD_ZOOM_IN, ImVec4(1.0F, 0.8F, 0.2F, 1.0F));
162
164 "Grid Step",
165 std::to_string(static_cast<int>(config.grid_step)) + "px",
166 ICON_MD_GRID_ON, ImVec4(0.2F, 1.0F, 0.2F, 1.0F));
167
168 ImGui::Columns(1);
169 }
170
171 // View Settings Section
172 if (ImGui::CollapsingHeader("👁️ View Settings",
173 ImGuiTreeNodeFlags_DefaultOpen)) {
174 ImGui::Checkbox("Show Grid", &config.enable_grid);
175 ImGui::SameLine();
176 RenderMaterialIcon("grid_on");
177
178 ImGui::Checkbox("Show Hex Labels", &config.enable_hex_labels);
179 ImGui::SameLine();
180 RenderMaterialIcon("label");
181
182 ImGui::Checkbox("Show Custom Labels", &config.enable_custom_labels);
183 ImGui::SameLine();
184 RenderMaterialIcon("edit");
185
186 ImGui::Checkbox("Enable Context Menu", &config.enable_context_menu);
187 ImGui::SameLine();
188 RenderMaterialIcon("menu");
189
190 ImGui::Checkbox("Draggable Canvas", &config.is_draggable);
191 ImGui::SameLine();
192 RenderMaterialIcon("drag_indicator");
193
194 ImGui::Checkbox("Auto Resize for Tables", &config.auto_resize);
195 ImGui::SameLine();
196 RenderMaterialIcon("fit_screen");
197 }
198
199 // Scale Controls Section
200 if (ImGui::CollapsingHeader(ICON_MD_BUILD " Scale Controls",
201 ImGuiTreeNodeFlags_DefaultOpen)) {
202 RenderSliderWithIcon("Global Scale", "zoom_in", &config.global_scale,
203 0.1f, 10.0f, "%.2f");
204 RenderSliderWithIcon("Grid Step", "grid_on", &config.grid_step, 1.0f,
205 128.0f, "%.1f");
206
207 // Preset scale buttons
208 ImGui::Text("Preset Scales:");
209 ImGui::SameLine();
210
211 const char* preset_labels[] = {"0.25x", "0.5x", "1x", "2x", "4x", "8x"};
212 const float preset_values[] = {0.25f, 0.5f, 1.0f, 2.0f, 4.0f, 8.0f};
213
214 for (int i = 0; i < 6; ++i) {
215 if (i > 0)
216 ImGui::SameLine();
217 if (ImGui::Button(preset_labels[i])) {
218 config.global_scale = preset_values[i];
219 DispatchConfig(config.on_config_changed, config);
220 }
221 }
222 }
223
224 // Scrolling Controls Section
225 if (ImGui::CollapsingHeader("📜 Scrolling Controls")) {
226 ImGui::Text("Current Scroll: %.1f, %.1f", config.scrolling.x,
227 config.scrolling.y);
228
229 if (ImGui::Button("Reset Scroll")) {
230 config.scrolling = ImVec2(0, 0);
231 DispatchConfig(config.on_config_changed, config);
232 }
233 ImGui::SameLine();
234
235 if (ImGui::Button("Center View") && bitmap) {
236 config.scrolling = ImVec2(
237 -(bitmap->width() * config.global_scale - config.canvas_size.x) /
238 2.0f,
239 -(bitmap->height() * config.global_scale - config.canvas_size.y) /
240 2.0f);
241 DispatchConfig(config.on_config_changed, config);
242 }
243 }
244
245 // Performance Integration Section
246 if (ImGui::CollapsingHeader(ICON_MD_TRENDING_UP " Performance")) {
247 auto& profiler = gfx::PerformanceProfiler::Get();
248
249 // Get stats for canvas operations
250 auto canvas_stats = profiler.GetStats("canvas_operations");
251 auto draw_stats = profiler.GetStats("canvas_draw");
252
253 RenderMetricPanel("Canvas Operations",
254 std::to_string(canvas_stats.sample_count) + " ops",
255 "speed", ImVec4(0.2F, 1.0F, 0.2F, 1.0F));
256
257 RenderMetricPanel("Average Time",
258 std::to_string(draw_stats.avg_time_us / 1000.0) + " ms",
259 "timer", ImVec4(1.0F, 0.8F, 0.2F, 1.0F));
260
261 if (ImGui::Button("Open Performance Dashboard")) {
263 }
264 }
265
266 // Action Buttons
267 ImGui::Separator();
268 ImGui::Spacing();
269
270 if (ImGui::Button("Apply Changes", ImVec2(120, 0))) {
271 DispatchConfig(config.on_config_changed, config);
272 ImGui::CloseCurrentPopup();
273 }
274 ImGui::SameLine();
275
276 if (ImGui::Button("Cancel", ImVec2(120, 0))) {
277 ImGui::CloseCurrentPopup();
278 }
279 ImGui::SameLine();
280
281 if (ImGui::Button("Reset to Defaults", ImVec2(150, 0))) {
282 config.global_scale = 1.0f;
283 config.grid_step = 32.0f;
284 config.enable_grid = true;
285 config.enable_hex_labels = false;
286 config.enable_custom_labels = false;
287 config.enable_context_menu = true;
288 config.is_draggable = false;
289 config.auto_resize = false;
290 config.scrolling = ImVec2(0, 0);
291 DispatchConfig(config.on_config_changed, config);
292 }
293
294 ImGui::EndPopup();
295 }
296}
297
298void CanvasModals::RenderScalingControlsModal(const std::string& canvas_id,
299 CanvasConfig& config,
300 const gfx::Bitmap* bitmap) {
301 std::string modal_title = "Canvas Scaling Controls";
302 ImGui::SetNextWindowSize(ImVec2(500, 400), ImGuiCond_FirstUseEver);
303
304 if (ImGui::BeginPopupModal(modal_title.c_str(), nullptr,
305 ImGuiWindowFlags_AlwaysAutoResize)) {
306 // Header with icon
307 ImGui::Text("%s %s", ICON_MD_ZOOM_IN, modal_title.c_str());
308 ImGui::Separator();
309
310 // Global Scale Section
311 ImGui::Text("Global Scale: %.3f", config.global_scale);
312 RenderSliderWithIcon("##GlobalScale", "zoom_in", &config.global_scale, 0.1f,
313 10.0f, "%.2f");
314
315 // Preset scale buttons
316 ImGui::Text("Preset Scales:");
317 const char* preset_labels[] = {"0.25x", "0.5x", "1x", "2x", "4x", "8x"};
318 const float preset_values[] = {0.25f, 0.5f, 1.0f, 2.0f, 4.0f, 8.0f};
319
320 for (int i = 0; i < 6; ++i) {
321 if (i > 0)
322 ImGui::SameLine();
323 if (ImGui::Button(preset_labels[i])) {
324 config.global_scale = preset_values[i];
325 DispatchScale(config.on_scale_changed, config);
326 }
327 }
328
329 ImGui::Separator();
330
331 // Grid Configuration Section
332 ImGui::Text("Grid Step: %.1f", config.grid_step);
333 RenderSliderWithIcon("##GridStep", "grid_on", &config.grid_step, 1.0f,
334 128.0f, "%.1f");
335
336 // Grid size presets
337 ImGui::Text("Grid Presets:");
338 const char* grid_labels[] = {"8x8", "16x16", "32x32", "64x64"};
339 const float grid_values[] = {8.0f, 16.0f, 32.0f, 64.0f};
340
341 for (int i = 0; i < 4; ++i) {
342 if (i > 0)
343 ImGui::SameLine();
344 if (ImGui::Button(grid_labels[i])) {
345 config.grid_step = grid_values[i];
346 DispatchScale(config.on_scale_changed, config);
347 }
348 }
349
350 ImGui::Separator();
351
352 // Canvas Information Section
353 ImGui::Text("Canvas Information");
354 ImGui::Text("Canvas Size: %.0f x %.0f", config.canvas_size.x,
355 config.canvas_size.y);
356 ImGui::Text("Scaled Size: %.0f x %.0f",
357 config.canvas_size.x * config.global_scale,
358 config.canvas_size.y * config.global_scale);
359
360 if (bitmap) {
361 ImGui::Text("Bitmap Size: %d x %d", bitmap->width(), bitmap->height());
362 ImGui::Text(
363 "Effective Scale: %.3f x %.3f",
364 (config.canvas_size.x * config.global_scale) / bitmap->width(),
365 (config.canvas_size.y * config.global_scale) / bitmap->height());
366 }
367
368 // Action Buttons
369 ImGui::Separator();
370 ImGui::Spacing();
371
372 if (ImGui::Button("Apply", ImVec2(120, 0))) {
373 DispatchScale(config.on_scale_changed, config);
374 ImGui::CloseCurrentPopup();
375 }
376 ImGui::SameLine();
377
378 if (ImGui::Button("Cancel", ImVec2(120, 0))) {
379 ImGui::CloseCurrentPopup();
380 }
381
382 ImGui::EndPopup();
383 }
384}
385
387 const std::string& canvas_id, const BppConversionOptions& options) {
388 std::string modal_title = "BPP Format Conversion";
389 ImGui::SetNextWindowSize(ImVec2(600, 500), ImGuiCond_FirstUseEver);
390
391 if (ImGui::BeginPopupModal(modal_title.c_str(), nullptr,
392 ImGuiWindowFlags_AlwaysAutoResize)) {
393 // Header with icon
394 ImGui::Text("%s %s", ICON_MD_SWAP_HORIZ, modal_title.c_str());
395 ImGui::Separator();
396
397 // Use the existing BppFormatUI for the conversion dialog
398 static std::unique_ptr<gui::BppFormatUI> bpp_ui =
399 std::make_unique<gui::BppFormatUI>(canvas_id + "_bpp_ui");
400
401 // Render the format selector
402 if (options.bitmap && options.palette) {
403 bpp_ui->RenderFormatSelector(const_cast<gfx::Bitmap*>(options.bitmap),
404 *options.palette, options.on_convert);
405 }
406
407 // Action Buttons
408 ImGui::Separator();
409 ImGui::Spacing();
410
411 if (ImGui::Button("Close", ImVec2(120, 0))) {
412 ImGui::CloseCurrentPopup();
413 }
414
415 ImGui::EndPopup();
416 }
417}
418
420 const std::string& canvas_id, const PaletteEditorOptions& options) {
421 std::string modal_title =
422 options.title.empty() ? "Palette Editor" : options.title;
423 ImGui::SetNextWindowSize(ImVec2(800, 600), ImGuiCond_FirstUseEver);
424
425 if (ImGui::BeginPopupModal(modal_title.c_str(), nullptr,
426 ImGuiWindowFlags_AlwaysAutoResize)) {
427 // Header with icon
428 ImGui::Text("%s %s", ICON_MD_PALETTE, modal_title.c_str());
429 ImGui::Separator();
430
431 // Use the existing PaletteWidget
432 static std::unique_ptr<gui::PaletteEditorWidget> palette_editor =
433 std::make_unique<gui::PaletteEditorWidget>();
434
435 if (options.palette) {
436 palette_editor->ShowPaletteEditor(*options.palette, modal_title);
437 }
438
439 // Action Buttons
440 ImGui::Separator();
441 ImGui::Spacing();
442
443 if (ImGui::Button("Close", ImVec2(120, 0))) {
444 ImGui::CloseCurrentPopup();
445 }
446
447 ImGui::EndPopup();
448 }
449}
450
452 const std::string& canvas_id, const ColorAnalysisOptions& options) {
453 std::string modal_title = "Color Analysis";
454 ImGui::SetNextWindowSize(ImVec2(700, 500), ImGuiCond_FirstUseEver);
455
456 if (ImGui::BeginPopupModal(modal_title.c_str(), nullptr,
457 ImGuiWindowFlags_AlwaysAutoResize)) {
458 // Header with icon
459 ImGui::Text("%s %s", ICON_MD_ZOOM_IN, modal_title.c_str());
460 ImGui::Separator();
461
462 // Use the existing PaletteWidget for color analysis
463 static std::unique_ptr<gui::PaletteEditorWidget> palette_editor =
464 std::make_unique<gui::PaletteEditorWidget>();
465
466 if (options.bitmap) {
467 palette_editor->ShowColorAnalysis(*options.bitmap, modal_title);
468 }
469
470 // Action Buttons
471 ImGui::Separator();
472 ImGui::Spacing();
473
474 if (ImGui::Button("Close", ImVec2(120, 0))) {
475 ImGui::CloseCurrentPopup();
476 }
477
478 ImGui::EndPopup();
479 }
480}
481
482void CanvasModals::RenderPerformanceModal(const std::string& canvas_id,
483 const PerformanceOptions& options) {
484 std::string modal_title = "Canvas Performance";
485 ImGui::SetNextWindowSize(ImVec2(500, 300), ImGuiCond_FirstUseEver);
486
487 if (ImGui::BeginPopupModal(modal_title.c_str(), nullptr,
488 ImGuiWindowFlags_AlwaysAutoResize)) {
489 // Header with icon
490 ImGui::Text("%s %s", ICON_MD_TRENDING_UP, modal_title.c_str());
491 ImGui::Separator();
492
493 // Performance metrics
494 RenderMetricPanel("Operation", options.operation_name, "speed",
495 ImVec4(0.2f, 1.0f, 0.2f, 1.0f));
496 RenderMetricPanel("Time", std::to_string(options.operation_time_ms) + " ms",
497 "timer", ImVec4(1.0f, 0.8f, 0.2f, 1.0f));
498
499 // Get overall performance stats
500 auto& profiler = gfx::PerformanceProfiler::Get();
501 auto canvas_stats = profiler.GetStats("canvas_operations");
502 auto draw_stats = profiler.GetStats("canvas_draw");
503
504 RenderMetricPanel("Total Operations",
505 std::to_string(canvas_stats.sample_count), "functions",
506 ImVec4(0.2F, 0.8F, 1.0F, 1.0F));
507 RenderMetricPanel("Average Time",
508 std::to_string(draw_stats.avg_time_us / 1000.0) + " ms",
509 "schedule", ImVec4(0.8F, 0.2F, 1.0F, 1.0F));
510
511 // Action Buttons
512 ImGui::Separator();
513 ImGui::Spacing();
514
515 if (ImGui::Button("Open Dashboard", ImVec2(150, 0))) {
517 }
518 ImGui::SameLine();
519
520 if (ImGui::Button("Close", ImVec2(120, 0))) {
521 ImGui::CloseCurrentPopup();
522 }
523
524 ImGui::EndPopup();
525 }
526}
527
528void CanvasModals::OpenModal(const std::string& id,
529 std::function<void()> render_func) {
530 // Check if modal already exists
531 auto it =
532 std::find_if(active_modals_.begin(), active_modals_.end(),
533 [&id](const ModalState& modal) { return modal.id == id; });
534
535 if (it != active_modals_.end()) {
536 it->is_open = true;
537 it->render_func = render_func;
538 } else {
539 active_modals_.push_back({true, id, render_func});
540 }
541
542 // Open the popup
543 ImGui::OpenPopup(id.c_str());
544}
545
546void CanvasModals::CloseModal(const std::string& id) {
547 auto it =
548 std::find_if(active_modals_.begin(), active_modals_.end(),
549 [&id](const ModalState& modal) { return modal.id == id; });
550
551 if (it != active_modals_.end()) {
552 it->is_open = false;
553 }
554}
555
556bool CanvasModals::IsModalOpen(const std::string& id) const {
557 auto it =
558 std::find_if(active_modals_.begin(), active_modals_.end(),
559 [&id](const ModalState& modal) { return modal.id == id; });
560
561 return it != active_modals_.end() && it->is_open;
562}
563
564void CanvasModals::RenderMaterialIcon(const std::string& icon_name,
565 const ImVec4& color) {
566 // Simple material icon rendering using Unicode symbols
567 // In a real implementation, you'd use a proper icon font
568 static std::unordered_map<std::string, const char*> icon_map = {
569 {"grid_on", ICON_MD_GRID_ON},
570 {"label", ICON_MD_LABEL},
571 {"edit", ICON_MD_EDIT},
572 {"menu", ICON_MD_MENU},
573 {"drag_indicator", ICON_MD_DRAG_INDICATOR},
574 {"fit_screen", ICON_MD_FIT_SCREEN},
575 {"zoom_in", ICON_MD_ZOOM_IN},
576 {"speed", ICON_MD_SPEED},
577 {"timer", ICON_MD_TIMER},
578 {"functions", ICON_MD_FUNCTIONS},
579 {"schedule", ICON_MD_SCHEDULE},
580 {"refresh", ICON_MD_REFRESH},
581 {"settings", ICON_MD_SETTINGS},
582 {"info", ICON_MD_INFO}};
583
584 auto it = icon_map.find(icon_name);
585 if (it != icon_map.end()) {
586 ImGui::TextColored(color, "%s", it->second);
587 }
588}
589
590void CanvasModals::RenderMetricPanel(const std::string& title,
591 const std::string& value,
592 const std::string& icon,
593 const ImVec4& color) {
594 ImGui::BeginGroup();
595
596 // Icon and title
597 ImGui::Text("%s %s", icon.c_str(), title.c_str());
598
599 // Value with color
600 ImGui::TextColored(color, "%s", value.c_str());
601
602 ImGui::EndGroup();
603}
604
605void CanvasModals::RenderSliderWithIcon(const std::string& label,
606 const std::string& icon, float* value,
607 float min_val, float max_val,
608 const char* format) {
609 ImGui::Text("%s %s", icon.c_str(), label.c_str());
610 ImGui::SameLine();
611 ImGui::SetNextItemWidth(200);
612 ImGui::SliderFloat(("##" + label).c_str(), value, min_val, max_val, format);
613}
614
615} // namespace gui
616} // namespace yaze
Represents a bitmap image optimized for SNES ROM hacking.
Definition bitmap.h:67
int height() const
Definition bitmap.h:374
int width() const
Definition bitmap.h:373
static PerformanceDashboard & Get()
void SetVisible(bool visible)
Show/hide the dashboard.
static PerformanceProfiler & Get()
void ShowAdvancedProperties(const std::string &canvas_id, const CanvasConfig &config, const gfx::Bitmap *bitmap=nullptr)
Show advanced canvas properties modal.
void ShowPaletteEditor(const std::string &canvas_id, const PaletteEditorOptions &options)
Show palette editor modal.
void RenderSliderWithIcon(const std::string &label, const std::string &icon, float *value, float min_val, float max_val, const char *format="%.2f")
void ShowPerformanceIntegration(const std::string &canvas_id, const PerformanceOptions &options)
Show performance dashboard integration.
std::vector< ModalState > active_modals_
void RenderMetricPanel(const std::string &title, const std::string &value, const std::string &icon, const ImVec4 &color=ImVec4(1, 1, 1, 1))
void RenderMaterialIcon(const std::string &icon_name, const ImVec4 &color=ImVec4(1, 1, 1, 1))
void RenderScalingControlsModal(const std::string &canvas_id, CanvasConfig &config, const gfx::Bitmap *bitmap)
void CloseModal(const std::string &id)
void Render()
Render all active modals.
void RenderPerformanceModal(const std::string &canvas_id, const PerformanceOptions &options)
void OpenModal(const std::string &id, std::function< void()> render_func)
void RenderAdvancedPropertiesModal(const std::string &canvas_id, CanvasConfig &config, const gfx::Bitmap *bitmap)
void RenderBppConversionModal(const std::string &canvas_id, const BppConversionOptions &options)
void RenderPaletteEditorModal(const std::string &canvas_id, const PaletteEditorOptions &options)
void ShowColorAnalysis(const std::string &canvas_id, const ColorAnalysisOptions &options)
Show color analysis modal.
void ShowBppConversionDialog(const std::string &canvas_id, const BppConversionOptions &options)
Show BPP format conversion dialog.
void RenderColorAnalysisModal(const std::string &canvas_id, const ColorAnalysisOptions &options)
void ShowScalingControls(const std::string &canvas_id, const CanvasConfig &config, const gfx::Bitmap *bitmap=nullptr)
Show scaling controls modal.
bool IsAnyModalOpen() const
Check if any modal is open.
bool IsModalOpen(const std::string &id) const
#define ICON_MD_FUNCTIONS
Definition icons.h:863
#define ICON_MD_SETTINGS
Definition icons.h:1699
#define ICON_MD_INFO
Definition icons.h:993
#define ICON_MD_FIT_SCREEN
Definition icons.h:781
#define ICON_MD_TRENDING_UP
Definition icons.h:2016
#define ICON_MD_SWAP_HORIZ
Definition icons.h:1896
#define ICON_MD_REFRESH
Definition icons.h:1572
#define ICON_MD_SCHEDULE
Definition icons.h:1652
#define ICON_MD_LABEL
Definition icons.h:1053
#define ICON_MD_DRAG_INDICATOR
Definition icons.h:624
#define ICON_MD_EDIT
Definition icons.h:645
#define ICON_MD_SPEED
Definition icons.h:1817
#define ICON_MD_GRID_ON
Definition icons.h:896
#define ICON_MD_TIMER
Definition icons.h:1982
#define ICON_MD_IMAGE
Definition icons.h:982
#define ICON_MD_BUILD
Definition icons.h:328
#define ICON_MD_STRAIGHTEN
Definition icons.h:1871
#define ICON_MD_ZOOM_IN
Definition icons.h:2194
#define ICON_MD_MENU
Definition icons.h:1196
#define ICON_MD_PALETTE
Definition icons.h:1370
#define ICON_MD_ANALYTICS
Definition icons.h:154
void DispatchConfig(const std::function< void(const CanvasConfig &)> &callback, const CanvasConfig &config)
void DispatchScale(const std::function< void(const CanvasConfig &)> &callback, const CanvasConfig &config)
BPP conversion options.
std::function< void(gfx::BppFormat)> on_convert
const gfx::SnesPalette * palette
Unified configuration for canvas display and interaction.
std::function< void(const CanvasConfig &) on_config_changed)
std::function< void(const CanvasConfig &) on_scale_changed)
Color analysis options.
Palette editor options.
Performance integration options.