yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
canvas_context_menu.cc
Go to the documentation of this file.
2#include "util/i18n/tr.h"
3
12#include "imgui/imgui.h"
13
14namespace yaze {
15namespace gui {
16
17namespace {
18inline void Dispatch(const std::function<void(CanvasContextMenu::Command,
19 const CanvasConfig&)>& handler,
21 if (handler) {
22 handler(command, config);
23 }
24}
25} // namespace
26
27void CanvasContextMenu::Initialize(const std::string& canvas_id) {
28 canvas_id_ = canvas_id;
29 enabled_ = true;
31 palette_editor_ = std::make_unique<PaletteEditorWidget>();
32
33 // Initialize canvas state
34 canvas_size_ = ImVec2(0, 0);
35 content_size_ = ImVec2(0, 0);
36 global_scale_ = 1.0F;
37 grid_step_ = 32.0F;
38 enable_grid_ = true;
39 enable_hex_labels_ = false;
42 is_draggable_ = false;
43 auto_resize_ = false;
44 scrolling_ = ImVec2(0, 0);
46
47 // Create default menu items
49}
50
54
56 global_items_.push_back(item);
57}
58
60 CanvasUsage usage) {
61 usage_specific_items_[usage].push_back(item);
62}
63
68
70 const std::string& context_id, const ImVec2& /* mouse_pos */, Rom* rom,
71 const gfx::Bitmap* bitmap, const gfx::SnesPalette* /* palette */,
72 const std::function<void(Command, const CanvasConfig&)>& command_handler,
73 CanvasConfig current_config, Canvas* canvas) {
74 if (!enabled_)
75 return;
76
77 // Context menu (under default mouse threshold)
78 if (ImVec2 drag_delta = ImGui::GetMouseDragDelta(ImGuiMouseButton_Right);
79 enable_context_menu_ && drag_delta.x == 0.0F && drag_delta.y == 0.0F) {
80 if (ImGui::IsItemHovered() &&
81 ImGui::IsMouseReleased(ImGuiMouseButton_Right)) {
82 context_open_screen_position_ = ImGui::GetIO().MousePos;
83 }
84 ImGui::OpenPopupOnItemClick(context_id.c_str(),
85 ImGuiPopupFlags_MouseButtonRight);
86 }
87
88 // Phase 4: Popup callback for automatic popup management
89 auto popup_callback = [canvas](const std::string& id,
90 std::function<void()> callback) {
91 if (canvas) {
92 canvas->GetPopupRegistry().Open(id, callback);
93 }
94 };
95
96 // Contents of the Context Menu (Phase 4: Priority-based ordering)
97 if (ImGui::BeginPopup(context_id.c_str())) {
98 // PRIORITY 0: Editor-specific items (from Canvas::editor_menu_)
99 if (canvas && !canvas->editor_menu().sections.empty()) {
100 RenderCanvasMenu(canvas->editor_menu(), popup_callback);
101 }
102
103 // Only show built-in menu items if show_builtin_context_menu is true
104 if (current_config.show_builtin_context_menu) {
105 // Also render usage-specific items (legacy support)
107 RenderUsageSpecificMenu(popup_callback);
108 ImGui::Separator();
109 }
110
111 // Shared built-in canvas tools. Bitmap and palette mutation entries
112 // ("Pixel Format", "Edit Palette") would corrupt the underlying data
113 // for read-only roles (kPreviewOnly, kSelectionSource) whose bitmap
114 // is a shared view (gfx-group sheets, sprite atlas thumbnails). Gate
115 // them on the canvas role; view controls below stay unconditional so
116 // read-only canvases keep pan/zoom/reset.
117 if (bitmap && RoleAllowsBitmapMutation(current_config.role)) {
118 RenderBitmapOperationsMenu(const_cast<gfx::Bitmap*>(bitmap));
119 ImGui::Separator();
120
121 RenderPaletteOperationsMenu(rom, const_cast<gfx::Bitmap*>(bitmap));
122 ImGui::Separator();
123 }
124
125 RenderViewControlsMenu(command_handler, current_config);
126
127 // PRIORITY 30: Debug/Performance
128 if (ImGui::GetIO().KeyCtrl) { // Only show when Ctrl is held
129 ImGui::Separator();
131 }
132
133 // Render global menu items (if any)
134 if (!global_items_.empty()) {
135 ImGui::Separator();
136 RenderMenuSection("Custom Actions", global_items_, popup_callback);
137 }
138 }
139
140 ImGui::EndPopup();
141 }
142}
143
147
149 const ImVec2& canvas_size, const ImVec2& content_size, float global_scale,
150 float grid_step, bool enable_grid, bool enable_hex_labels,
151 bool enable_custom_labels, bool enable_context_menu, bool is_draggable,
152 bool auto_resize, const ImVec2& scrolling) {
153 canvas_size_ = canvas_size;
154 content_size_ = content_size;
155 global_scale_ = global_scale;
156 grid_step_ = grid_step;
157 enable_grid_ = enable_grid;
158 enable_hex_labels_ = enable_hex_labels;
159 enable_custom_labels_ = enable_custom_labels;
160 enable_context_menu_ = enable_context_menu;
161 is_draggable_ = is_draggable;
162 auto_resize_ = auto_resize;
163 scrolling_ = scrolling;
164}
165
167 const CanvasMenuItem& item,
168 std::function<void(const std::string&, std::function<void()>)>
169 popup_callback) {
170 // Phase 4: Delegate to canvas_menu.h implementation
171 gui::RenderMenuItem(item, popup_callback);
172}
173
175 const std::string& title, const std::vector<CanvasMenuItem>& items,
176 std::function<void(const std::string&, std::function<void()>)>
177 popup_callback) {
178 if (items.empty())
179 return;
180
181 ImGui::TextColored(ImVec4(0.7F, 0.7F, 0.7F, 1.0F), "%s", title.c_str());
182 for (const auto& item : items) {
183 RenderMenuItem(item, popup_callback);
184 }
185}
186
188 std::function<void(const std::string&, std::function<void()>)>
189 popup_callback) {
191 if (it == usage_specific_items_.end() || it->second.empty()) {
192 return;
193 }
194
195 std::string usage_name = GetUsageModeName(current_usage_);
196 ImVec4 usage_color = GetUsageModeColor(current_usage_);
197
198 ImGui::TextColored(usage_color, tr("%s %s Mode"), ICON_MD_COLOR_LENS,
199 usage_name.c_str());
200 ImGui::Separator();
201
202 for (const auto& item : it->second) {
203 RenderMenuItem(item, popup_callback);
204 }
205}
206
208 const std::function<void(Command, const CanvasConfig&)>& command_handler,
209 CanvasConfig current_config) {
210 if (ImGui::BeginMenu(ICON_MD_VISIBILITY " View Controls")) {
211 if (ImGui::MenuItem(tr("Reset View"), "Ctrl+R")) {
212 Dispatch(command_handler, Command::kResetView, current_config);
213 }
214 if (ImGui::MenuItem(tr("Zoom to Fit"), "Ctrl+F")) {
215 Dispatch(command_handler, Command::kZoomToFit, current_config);
216 }
217 if (ImGui::BeginMenu(ICON_MD_ZOOM_IN " Zoom")) {
218 if (ImGui::MenuItem(tr("Zoom In"), "Ctrl++")) {
219 CanvasConfig updated = current_config;
220 updated.global_scale *= 1.25F;
221 Dispatch(command_handler, Command::kSetScale, updated);
222 }
223 if (ImGui::MenuItem(tr("Zoom Out"), "Ctrl+-")) {
224 CanvasConfig updated = current_config;
225 updated.global_scale *= 0.8F;
226 Dispatch(command_handler, Command::kSetScale, updated);
227 }
228
229 const struct ScaleOption {
230 const char* label;
231 float value;
232 } scale_options[] = {{"0.25x", 0.25F}, {"0.5x", 0.5F}, {"1x", 1.0F},
233 {"2x", 2.0F}, {"4x", 4.0F}, {"8x", 8.0F}};
234
235 ImGui::Separator();
236 for (const auto& option : scale_options) {
237 const bool selected = current_config.global_scale == option.value;
238 if (ImGui::MenuItem(option.label, nullptr, selected)) {
239 CanvasConfig updated = current_config;
240 updated.global_scale = option.value;
241 Dispatch(command_handler, Command::kSetScale, updated);
242 }
243 }
244 ImGui::EndMenu();
245 }
246
247 ImGui::Separator();
248 if (ImGui::MenuItem(tr("Show Grid"), nullptr, enable_grid_)) {
249 CanvasConfig updated = current_config;
250 updated.enable_grid = !enable_grid_;
251 Dispatch(command_handler, Command::kToggleGrid, updated);
252 }
253 if (ImGui::MenuItem(tr("Show Hex Labels"), nullptr, enable_hex_labels_)) {
254 CanvasConfig updated = current_config;
256 Dispatch(command_handler, Command::kToggleHexLabels, updated);
257 }
258 if (ImGui::MenuItem(tr("Show Custom Labels"), nullptr,
260 CanvasConfig updated = current_config;
262 Dispatch(command_handler, Command::kToggleCustomLabels, updated);
263 }
264
265 if (ImGui::BeginMenu(ICON_MD_GRID_ON " Grid")) {
266 const struct GridOption {
267 const char* label;
268 float value;
269 } grid_options[] = {
270 {"8x8", 8.0F}, {"16x16", 16.0F}, {"32x32", 32.0F}, {"64x64", 64.0F}};
271
272 for (const auto& option : grid_options) {
273 const bool selected = grid_step_ == option.value;
274 if (ImGui::MenuItem(option.label, nullptr, selected)) {
275 CanvasConfig updated = current_config;
276 updated.grid_step = option.value;
277 Dispatch(command_handler, Command::kSetGridStep, updated);
278 }
279 }
280 ImGui::EndMenu();
281 }
282
283 ImGui::Separator();
284 ImGui::TextDisabled(tr("Canvas %.0f x %.0f"), canvas_size_.x,
285 canvas_size_.y);
286 ImGui::TextDisabled(tr("Content %.0f x %.0f"), content_size_.x,
287 content_size_.y);
288 ImGui::TextDisabled(tr("Scale %.2f"), global_scale_);
289 ImGui::TextDisabled(tr("Grid %.1f"), grid_step_);
290
291 ImGui::Separator();
292 if (ImGui::MenuItem(tr("Advanced Properties..."))) {
293 CanvasConfig updated = current_config;
294 updated.enable_grid = enable_grid_;
298 updated.is_draggable = is_draggable_;
299 updated.auto_resize = auto_resize_;
300 updated.grid_step = grid_step_;
301 updated.canvas_size = canvas_size_;
302 updated.content_size = content_size_;
303 updated.scrolling = scrolling_;
304 Dispatch(command_handler, Command::kOpenAdvancedProperties, updated);
305 }
306 ImGui::EndMenu();
307 }
308}
309
311 if (!bitmap)
312 return;
313
314 if (ImGui::BeginMenu(ICON_MD_IMAGE " Bitmap")) {
315 ImGui::TextDisabled(tr("Size %d x %d"), bitmap->width(), bitmap->height());
316 if (auto* surface = bitmap->surface()) {
317 ImGui::TextDisabled(tr("Pitch %d"), surface->pitch);
318 ImGui::TextDisabled(tr("BPP %d / %d bytes"),
321 }
322
323 if (ImGui::BeginMenu(tr("Pixel Format"))) {
324 if (ImGui::MenuItem(tr("Indexed"))) {
326 // Queue texture update via Arena's deferred system
329 }
330 if (ImGui::MenuItem(tr("4BPP"))) {
332 // Queue texture update via Arena's deferred system
335 }
336 if (ImGui::MenuItem(tr("8BPP"))) {
338 // Queue texture update via Arena's deferred system
341 }
342 ImGui::EndMenu();
343 }
344
345 if (ImGui::BeginMenu(tr("Format Tools"))) {
346 if (ImGui::MenuItem(tr("Format Analysis..."))) {
347 // Open BPP analysis
348 }
349 if (ImGui::MenuItem(tr("Convert Format..."))) {
350 // Open BPP conversion dialog
351 }
352 if (ImGui::MenuItem(tr("Format Comparison..."))) {
353 // Open format comparison tool
354 }
355 ImGui::EndMenu();
356 }
357
358 ImGui::EndMenu();
359 }
360}
361
363 gfx::Bitmap* bitmap) {
364 if (!bitmap)
365 return;
366
367 if (ImGui::BeginMenu(ICON_MD_PALETTE " Palette")) {
368 if (ImGui::MenuItem(tr("Edit Palette..."))) {
369 palette_editor_->ShowPaletteEditor(*bitmap->mutable_palette(),
370 "Palette Editor");
371 }
372 if (ImGui::MenuItem(tr("Color Analysis..."))) {
373 palette_editor_->ShowColorAnalysis(*bitmap, "Color Analysis");
374 }
375
376 if (rom && ImGui::BeginMenu(tr("ROM Palette Selection"))) {
377 palette_editor_->Initialize(rom);
378
379 // Render palette selector inline
380 ImGui::Text(tr("Group:"));
381 ImGui::SameLine();
382 ImGui::InputScalar("##group", ImGuiDataType_U64,
384 ImGui::Text(tr("Palette:"));
385 ImGui::SameLine();
386 ImGui::InputScalar("##palette", ImGuiDataType_U64, &edit_palette_index_);
387
388 if (ImGui::Button(tr("Apply to Canvas"))) {
389 palette_editor_->ApplyROMPalette(bitmap, edit_palette_group_name_index_,
391 }
392 ImGui::EndMenu();
393 }
394
395 if (ImGui::BeginMenu(tr("View Palette"))) {
396 DisplayEditablePalette(*bitmap->mutable_palette(), "Palette", true, 8);
397 ImGui::EndMenu();
398 }
399
400 ImGui::Separator();
401
402 // Palette Help submenu
403 if (ImGui::BeginMenu(ICON_MD_HELP " Palette Help")) {
404 ImGui::TextColored(ImVec4(0.7F, 0.9F, 1.0F, 1.0F), tr("Bitmap Metadata"));
405 ImGui::Separator();
406
407 const auto& meta = bitmap->metadata();
408 ImGui::Text(tr("Source BPP: %d"), meta.source_bpp);
409 ImGui::Text(tr("Palette Format: %s"),
410 meta.palette_format == 0 ? "Full" : "Sub-palette");
411 ImGui::Text(tr("Source Type: %s"), meta.source_type.c_str());
412 ImGui::Text(tr("Expected Colors: %d"), meta.palette_colors);
413 ImGui::Text(tr("Actual Palette Size: %zu"), bitmap->palette().size());
414
415 ImGui::Separator();
416 ImGui::TextColored(ImVec4(1.0F, 0.9F, 0.6F, 1.0F),
417 tr("Palette Application Method"));
418 if (meta.palette_format == 0) {
419 ImGui::TextWrapped(
420 tr("Full palette (SetPalette) - all colors applied directly"));
421 } else {
422 ImGui::TextWrapped(tr(
423 "Sub-palette (SetPaletteWithTransparent) - color 0 is transparent, "
424 "1-7 from palette"));
425 }
426
427 ImGui::Separator();
428 ImGui::TextColored(ImVec4(0.6F, 1.0F, 0.6F, 1.0F), tr("Documentation"));
429 if (ImGui::MenuItem(tr("Palette System Architecture"))) {
430 ImGui::SetClipboardText("yaze/docs/palette-system-architecture.md");
431 // TODO: Open file in system viewer
432 }
433 if (ImGui::MenuItem(tr("User Palette Guide"))) {
434 ImGui::SetClipboardText("yaze/docs/user-palette-guide.md");
435 // TODO: Open file in system viewer
436 }
437
438 ImGui::EndMenu();
439 }
440
441 ImGui::EndMenu();
442 }
443}
444
446 if (!palette_editor_)
447 return;
448
449 palette_editor_->DrawROMPaletteSelector();
450}
451
453 if (ImGui::BeginMenu(ICON_MD_TRENDING_UP " Performance")) {
454 auto& profiler = gfx::PerformanceProfiler::Get();
455 auto canvas_stats = profiler.GetStats("canvas_operations");
456 auto draw_stats = profiler.GetStats("canvas_draw");
457
458 ImGui::Text(tr("Canvas Operations: %zu"), canvas_stats.sample_count);
459 ImGui::Text(tr("Average Time: %.2f ms"), draw_stats.avg_time_us / 1000.0);
460
461 if (ImGui::MenuItem(tr("Performance Dashboard..."))) {
463 }
464 if (ImGui::MenuItem(tr("Usage Report..."))) {
465 // Open usage report
466 }
467
468 ImGui::EndMenu();
469 }
470}
471
472void CanvasContextMenu::RenderMaterialIcon(const std::string& icon_name,
473 const ImVec4& color) {
474 // Simple material icon rendering using Unicode symbols
475 static std::unordered_map<std::string, const char*> icon_map = {
476 {"grid_on", ICON_MD_GRID_ON},
477 {"label", ICON_MD_LABEL},
478 {"edit", ICON_MD_EDIT},
479 {"menu", ICON_MD_MENU},
480 {"drag_indicator", ICON_MD_DRAG_INDICATOR},
481 {"fit_screen", ICON_MD_FIT_SCREEN},
482 {"zoom_in", ICON_MD_ZOOM_IN},
483 {"speed", ICON_MD_SPEED},
484 {"timer", ICON_MD_TIMER},
485 {"functions", ICON_MD_FUNCTIONS},
486 {"schedule", ICON_MD_SCHEDULE},
487 {"refresh", ICON_MD_REFRESH},
488 {"settings", ICON_MD_SETTINGS},
489 {"info", ICON_MD_INFO},
490 {"view", ICON_MD_VISIBILITY},
491 {"properties", ICON_MD_SETTINGS},
492 {"bitmap", ICON_MD_IMAGE},
493 {"palette", ICON_MD_PALETTE},
494 {"bpp", ICON_MD_SWAP_HORIZ},
495 {"performance", ICON_MD_TRENDING_UP},
496 {"grid", ICON_MD_GRID_ON},
497 {"scaling", ICON_MD_ZOOM_IN}};
498
499 auto it = icon_map.find(icon_name);
500 if (it != icon_map.end()) {
501 ImGui::TextColored(color, "%s", it->second);
502 }
503}
504
506 switch (usage) {
508 return "Tile Painting";
510 return "Tile Selecting";
512 return "Rectangle Selection";
514 return "Color Painting";
516 return "Bitmap Editing";
518 return "Palette Editing";
520 return "BPP Conversion";
522 return "Performance Mode";
524 return "Entity Manipulation";
526 return "Unknown";
527 default:
528 return "Unknown";
529 }
530}
531
533 switch (usage) {
535 return ImVec4(0.2F, 1.0F, 0.2F, 1.0F); // Green
537 return ImVec4(0.2F, 0.8F, 1.0F, 1.0F); // Blue
539 return ImVec4(1.0F, 0.8F, 0.2F, 1.0F); // Yellow
541 return ImVec4(1.0F, 0.2F, 1.0F, 1.0F); // Magenta
543 return ImVec4(1.0F, 0.5F, 0.2F, 1.0F); // Orange
545 return ImVec4(0.8F, 0.2F, 1.0F, 1.0F); // Purple
547 return ImVec4(0.2F, 1.0F, 1.0F, 1.0F); // Cyan
549 return ImVec4(1.0F, 0.2F, 0.2F, 1.0F); // Red
551 return ImVec4(0.4F, 0.8F, 1.0F, 1.0F); // Light Blue
553 return ImVec4(0.7F, 0.7F, 0.7F, 1.0F); // Gray
554 default:
555 return ImVec4(0.7F, 0.7F, 0.7F, 1.0F); // Gray
556 }
557}
558
560 // The shared canvas should not invent placeholder actions like "Paint Tile"
561 // or "Select Tile". Callers can inject real usage-specific items when a
562 // given editor has concrete actions to expose.
563}
564
565} // namespace gui
566} // namespace yaze
The Rom class is used to load, save, and modify Rom data. This is a generic SNES ROM container and do...
Definition rom.h:28
void QueueTextureCommand(TextureCommandType type, Bitmap *bitmap)
Definition arena.cc:39
static Arena & Get()
Definition arena.cc:24
Represents a bitmap image optimized for SNES ROM hacking.
Definition bitmap.h:69
const SnesPalette & palette() const
Definition bitmap.h:391
void Reformat(int format)
Reformat the bitmap to use a different pixel format.
Definition bitmap.cc:286
BitmapMetadata & metadata()
Definition bitmap.h:393
SnesPalette * mutable_palette()
Definition bitmap.h:392
int height() const
Definition bitmap.h:397
int width() const
Definition bitmap.h:396
SDL_Surface * surface() const
Definition bitmap.h:402
static PerformanceDashboard & Get()
void SetVisible(bool visible)
Show/hide the dashboard.
static PerformanceProfiler & Get()
Represents a palette of colors for the Super Nintendo Entertainment System (SNES).
void Initialize(const std::string &canvas_id)
std::unique_ptr< PaletteEditorWidget > palette_editor_
void SetUsageMode(CanvasUsage usage)
std::unordered_map< CanvasUsage, std::vector< CanvasMenuItem > > usage_specific_items_
void RenderMenuItem(const CanvasMenuItem &item, std::function< void(const std::string &, std::function< void()>)> popup_callback)
void SetCanvasState(const ImVec2 &canvas_size, const ImVec2 &content_size, float global_scale, float grid_step, bool enable_grid, bool enable_hex_labels, bool enable_custom_labels, bool enable_context_menu, bool is_draggable, bool auto_resize, const ImVec2 &scrolling)
void RenderMaterialIcon(const std::string &icon_name, const ImVec4 &color=ImVec4(1, 1, 1, 1))
void RenderUsageSpecificMenu(std::function< void(const std::string &, std::function< void()>)> popup_callback)
void RenderViewControlsMenu(const std::function< void(Command, const CanvasConfig &)> &command_handler, CanvasConfig current_config)
std::string GetUsageModeName(CanvasUsage usage) const
ImVec4 GetUsageModeColor(CanvasUsage usage) const
void RenderMenuSection(const std::string &title, const std::vector< CanvasMenuItem > &items, std::function< void(const std::string &, std::function< void()>)> popup_callback)
std::vector< CanvasMenuItem > global_items_
void RenderPaletteOperationsMenu(Rom *rom, gfx::Bitmap *bitmap)
std::optional< ImVec2 > context_open_screen_position_
void AddMenuItem(const CanvasMenuItem &item)
void Render(const std::string &context_id, const ImVec2 &mouse_pos, Rom *rom, const gfx::Bitmap *bitmap, const gfx::SnesPalette *palette, const std::function< void(Command, const CanvasConfig &)> &command_handler, CanvasConfig current_config, Canvas *canvas)
void RenderBitmapOperationsMenu(gfx::Bitmap *bitmap)
Modern, robust canvas for drawing and manipulating graphics.
Definition canvas.h:64
PopupRegistry & GetPopupRegistry()
Definition canvas.h:221
CanvasMenuDefinition & editor_menu()
Definition canvas.h:207
void Open(const std::string &popup_id, std::function< void()> render_callback)
Open a persistent popup.
#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_VISIBILITY
Definition icons.h:2101
#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_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_COLOR_LENS
Definition icons.h:440
#define ICON_MD_HELP
Definition icons.h:933
@ kIndexed
Definition bitmap.h:38
@ k8bpp
Definition bitmap.h:40
@ k4bpp
Definition bitmap.h:39
void Dispatch(const std::function< void(CanvasContextMenu::Command, const CanvasConfig &)> &handler, CanvasContextMenu::Command command, CanvasConfig config)
CanvasUsage
Canvas usage patterns and tracking.
void RenderCanvasMenu(const CanvasMenuDefinition &menu, std::function< void(const std::string &, std::function< void()>)> popup_opened_callback)
Render a complete menu definition.
constexpr bool RoleAllowsBitmapMutation(CanvasRole role)
void RenderMenuItem(const CanvasMenuItem &item, std::function< void(const std::string &, std::function< void()>)> popup_opened_callback)
Render a single menu item.
Definition canvas_menu.cc:6
absl::Status DisplayEditablePalette(gfx::SnesPalette &palette, const std::string &title, bool show_color_picker, int colors_per_row, ImGuiColorEditFlags flags)
Definition color.cc:357
int GetSurfaceBitsPerPixel(SDL_Surface *surface)
Get bits per pixel from a surface.
Definition sdl_compat.h:455
int GetSurfaceBytesPerPixel(SDL_Surface *surface)
Get bytes per pixel from a surface.
Definition sdl_compat.h:530
SDL2/SDL3 compatibility layer.
Unified configuration for canvas display and interaction.
std::vector< CanvasMenuSection > sections
Declarative menu item definition.
Definition canvas_menu.h:64