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