1#define IMGUI_DEFINE_MATH_OPERATORS
15#include "imgui/imgui.h"
16#include "imgui/imgui_internal.h"
26 handler(command, config);
74 const std::string& context_id,
const ImVec2& ,
Rom* rom,
82 if (ImVec2 drag_delta = ImGui::GetMouseDragDelta(ImGuiMouseButton_Right);
84 if (ImGui::IsPopupOpenRequestForItem(ImGuiPopupFlags_MouseButtonRight,
85 ImGui::GetItemID())) {
86 const ImVec2 position = ImGui::GetIO().MousePos;
89 ImGui::OpenPopup(context_id.c_str());
95 auto popup_callback = [canvas](
const std::string& id,
96 std::function<void()> callback) {
104 std::optional<PopupStyleScope> popup_style;
105 if (ImGui::IsPopupOpen(context_id.c_str())) {
106 popup_style.emplace();
108 if (ImGui::BeginPopup(context_id.c_str())) {
139 if (ImGui::GetIO().KeyCtrl) {
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) {
179 std::function<
void(
const std::string&, std::function<
void()>)>
186 const std::string& title,
const std::vector<CanvasMenuItem>& items,
187 std::function<
void(
const std::string&, std::function<
void()>)>
192 ImGui::TextColored(ImVec4(0.7F, 0.7F, 0.7F, 1.0F),
"%s", title.c_str());
193 for (
const auto& item : items) {
199 std::function<
void(
const std::string&, std::function<
void()>)>
213 for (
const auto& item : it->second) {
222 if (ImGui::MenuItem(tr(
"Reset View"),
"Ctrl+R")) {
225 if (ImGui::MenuItem(tr(
"Zoom to Fit"),
"Ctrl+F")) {
229 if (ImGui::MenuItem(tr(
"Zoom In"),
"Ctrl++")) {
234 if (ImGui::MenuItem(tr(
"Zoom Out"),
"Ctrl+-")) {
240 const struct ScaleOption {
243 } scale_options[] = {{
"0.25x", 0.25F}, {
"0.5x", 0.5F}, {
"1x", 1.0F},
244 {
"2x", 2.0F}, {
"4x", 4.0F}, {
"8x", 8.0F}};
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)) {
259 if (ImGui::MenuItem(tr(
"Show Grid"),
nullptr,
enable_grid_)) {
269 if (ImGui::MenuItem(tr(
"Show Custom Labels"),
nullptr,
277 const struct GridOption {
281 {
"8x8", 8.0F}, {
"16x16", 16.0F}, {
"32x32", 32.0F}, {
"64x64", 64.0F}};
283 for (
const auto& option : grid_options) {
284 const bool selected =
grid_step_ == option.value;
285 if (ImGui::MenuItem(option.label,
nullptr, selected)) {
295 ImGui::TextDisabled(tr(
"Canvas %.0f x %.0f"),
canvas_size_.x,
297 ImGui::TextDisabled(tr(
"Content %.0f x %.0f"),
content_size_.x,
300 ImGui::TextDisabled(tr(
"Grid %.1f"),
grid_step_);
303 if (ImGui::MenuItem(tr(
"Advanced Properties..."))) {
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"),
334 if (ImGui::BeginMenu(tr(
"Pixel Format"))) {
335 if (ImGui::MenuItem(tr(
"Indexed"))) {
341 if (ImGui::MenuItem(tr(
"4BPP"))) {
347 if (ImGui::MenuItem(tr(
"8BPP"))) {
356 if (ImGui::BeginMenu(tr(
"Format Tools"))) {
357 if (ImGui::MenuItem(tr(
"Format Analysis..."))) {
360 if (ImGui::MenuItem(tr(
"Convert Format..."))) {
363 if (ImGui::MenuItem(tr(
"Format Comparison..."))) {
379 if (ImGui::MenuItem(tr(
"Edit Palette..."))) {
383 if (ImGui::MenuItem(tr(
"Color Analysis..."))) {
387 if (rom && ImGui::BeginMenu(tr(
"ROM Palette Selection"))) {
391 ImGui::Text(tr(
"Group:"));
393 ImGui::InputScalar(
"##group", ImGuiDataType_U64,
395 ImGui::Text(tr(
"Palette:"));
399 if (ImGui::Button(tr(
"Apply to Canvas"))) {
406 if (ImGui::BeginMenu(tr(
"View Palette"))) {
415 ImGui::TextColored(ImVec4(0.7F, 0.9F, 1.0F, 1.0F), tr(
"Bitmap Metadata"));
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());
427 ImGui::TextColored(ImVec4(1.0F, 0.9F, 0.6F, 1.0F),
428 tr(
"Palette Application Method"));
429 if (meta.palette_format == 0) {
431 tr(
"Full palette (SetPalette) - all colors applied directly"));
433 ImGui::TextWrapped(tr(
434 "Sub-palette (SetPaletteWithTransparent) - color 0 is transparent, "
435 "1-7 from palette"));
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");
444 if (ImGui::MenuItem(tr(
"User Palette Guide"))) {
445 ImGui::SetClipboardText(
"yaze/docs/user-palette-guide.md");
466 auto canvas_stats = profiler.GetStats(
"canvas_operations");
467 auto draw_stats = profiler.GetStats(
"canvas_draw");
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);
472 if (ImGui::MenuItem(tr(
"Performance Dashboard..."))) {
475 if (ImGui::MenuItem(tr(
"Usage Report..."))) {
484 const ImVec4& color) {
486 static std::unordered_map<std::string, const char*> icon_map = {
510 auto it = icon_map.find(icon_name);
511 if (it != icon_map.end()) {
512 ImGui::TextColored(color,
"%s", it->second);
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";
546 return ImVec4(0.2F, 1.0F, 0.2F, 1.0F);
548 return ImVec4(0.2F, 0.8F, 1.0F, 1.0F);
550 return ImVec4(1.0F, 0.8F, 0.2F, 1.0F);
552 return ImVec4(1.0F, 0.2F, 1.0F, 1.0F);
554 return ImVec4(1.0F, 0.5F, 0.2F, 1.0F);
556 return ImVec4(0.8F, 0.2F, 1.0F, 1.0F);
558 return ImVec4(0.2F, 1.0F, 1.0F, 1.0F);
560 return ImVec4(1.0F, 0.2F, 0.2F, 1.0F);
562 return ImVec4(0.4F, 0.8F, 1.0F, 1.0F);
564 return ImVec4(0.7F, 0.7F, 0.7F, 1.0F);
566 return ImVec4(0.7F, 0.7F, 0.7F, 1.0F);
The Rom class is used to load, save, and modify Rom data. This is a generic SNES ROM container and do...
void QueueTextureCommand(TextureCommandType type, Bitmap *bitmap)
Represents a bitmap image optimized for SNES ROM hacking.
const SnesPalette & palette() const
void Reformat(int format)
Reformat the bitmap to use a different pixel format.
BitmapMetadata & metadata()
SnesPalette * mutable_palette()
SDL_Surface * surface() const
Represents a palette of colors for the Super Nintendo Entertainment System (SNES).
Modern, robust canvas for drawing and manipulating graphics.
PopupRegistry & GetPopupRegistry()
bool PrepareContextMenu(const ImVec2 &screen_position)
CanvasMenuDefinition & editor_menu()
#define ICON_MD_FUNCTIONS
#define ICON_MD_FIT_SCREEN
#define ICON_MD_TRENDING_UP
#define ICON_MD_SWAP_HORIZ
#define ICON_MD_DRAG_INDICATOR
#define ICON_MD_VISIBILITY
#define ICON_MD_COLOR_LENS
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)
SDL2/SDL3 compatibility layer.
Unified configuration for canvas display and interaction.
bool enable_custom_labels
bool show_builtin_context_menu