From 720f4e8fb2b3d0d8d98f51d1fef633afb622b43e Mon Sep 17 00:00:00 2001 From: scawful Date: Sun, 5 Oct 2025 18:14:51 -0400 Subject: [PATCH] refactor: Revamp Map Properties and Visual Effects UI - Updated the MapPropertiesSystem to enhance the user interface with icons and tooltips for better accessibility and clarity. - Renamed UI elements for consistency, changing "Map Properties" to "Area Configuration" and "Overlay Editor" to "Visual Effects Editor." - Improved the layout and organization of the properties panel, ensuring a more intuitive user experience. - Added detailed tooltips and help sections to guide users in configuring visual effects and overlays. - Removed legacy window code, consolidating all editor functionalities into a streamlined system for better performance and maintainability. --- src/app/editor/overworld/map_properties.cc | 342 ++++++++++++++----- src/app/editor/overworld/overworld_editor.cc | 109 ++---- 2 files changed, 280 insertions(+), 171 deletions(-) diff --git a/src/app/editor/overworld/map_properties.cc b/src/app/editor/overworld/map_properties.cc index 51264cca..1d931ee2 100644 --- a/src/app/editor/overworld/map_properties.cc +++ b/src/app/editor/overworld/map_properties.cc @@ -82,41 +82,83 @@ void MapPropertiesSystem::DrawSimplifiedMapSettings( HOVER_HINT(current_map_lock ? "Unlock Map" : "Lock Map"); TableNextColumn(); - if (ImGui::Button("Graphics", ImVec2(kTableButtonGraphics, 0))) { + if (ImGui::Button(ICON_MD_IMAGE " GFX", ImVec2(kTableButtonGraphics, 0))) { ImGui::OpenPopup("GraphicsPopup"); } - HOVER_HINT("Graphics Settings"); + if (ImGui::IsItemHovered()) { + ImGui::SetTooltip( + "Graphics Settings\n\n" + "Configure:\n" + " • Area graphics (tileset)\n" + " • Sprite graphics sheets\n" + " • Animated graphics (v3+)\n" + " • Custom tile16 sheets (8 slots)"); + } DrawGraphicsPopup(current_map, game_state); TableNextColumn(); - if (ImGui::Button("Palettes", ImVec2(kTableButtonPalettes, 0))) { + if (ImGui::Button(ICON_MD_PALETTE " Palettes", ImVec2(kTableButtonPalettes, 0))) { ImGui::OpenPopup("PalettesPopup"); } - HOVER_HINT("Palette Settings"); + if (ImGui::IsItemHovered()) { + ImGui::SetTooltip( + "Palette Settings\n\n" + "Configure:\n" + " • Area palette (background colors)\n" + " • Main palette (v2+)\n" + " • Sprite palettes\n" + " • Custom background colors"); + } DrawPalettesPopup(current_map, game_state, show_custom_bg_color_editor); TableNextColumn(); - if (ImGui::Button("Properties", ImVec2(kTableButtonProperties, 0))) { - ImGui::OpenPopup("PropertiesPopup"); + if (ImGui::Button(ICON_MD_TUNE " Config", ImVec2(kTableButtonProperties, 0))) { + ImGui::OpenPopup("ConfigPopup"); + } + if (ImGui::IsItemHovered()) { + ImGui::SetTooltip( + "Area Configuration\n\n" + "Quick access to:\n" + " • Message ID\n" + " • Game state settings\n" + " • Area size (v3+)\n" + " • Mosaic effects\n" + " • Visual effect overlays\n" + " • Map overlay info\n\n" + "Click 'Full Configuration Panel' for\n" + "comprehensive editing with all tabs."); } - HOVER_HINT("Map Properties & Overlays"); DrawPropertiesPopup(current_map, show_map_properties_panel, show_overlay_preview, game_state); TableNextColumn(); // View Controls - if (ImGui::Button("View", ImVec2(kTableButtonView, 0))) { + if (ImGui::Button(ICON_MD_VISIBILITY " View", ImVec2(kTableButtonView, 0))) { ImGui::OpenPopup("ViewPopup"); } - HOVER_HINT("View Controls"); + if (ImGui::IsItemHovered()) { + ImGui::SetTooltip( + "View Controls\n\n" + "Canvas controls:\n" + " • Zoom in/out\n" + " • Toggle fullscreen\n" + " • Reset view"); + } DrawViewPopup(); TableNextColumn(); // Quick Access Tools - if (ImGui::Button("Quick", ImVec2(kTableButtonQuick, 0))) { + if (ImGui::Button(ICON_MD_BOLT " Quick", ImVec2(kTableButtonQuick, 0))) { ImGui::OpenPopup("QuickPopup"); } - HOVER_HINT("Quick Access Tools"); + if (ImGui::IsItemHovered()) { + ImGui::SetTooltip( + "Quick Access Tools\n\n" + "Shortcuts to:\n" + " • Tile16 editor (Ctrl+T)\n" + " • Copy current map\n" + " • Lock/unlock map (Ctrl+L)"); + } DrawQuickAccessPopup(); ImGui::EndTable(); @@ -243,27 +285,60 @@ void MapPropertiesSystem::DrawOverlayEditor(int current_map, static uint8_t asm_version = (*rom_)[zelda3::OverworldCustomASMHasBeenApplied]; + + ImGui::TextColored(ImVec4(0.4f, 0.8f, 1.0f, 1.0f), + ICON_MD_LAYERS " Visual Effects Configuration"); + ImGui::Text("Map: 0x%02X", current_map); + Separator(); + if (asm_version < 1) { - Text("Subscreen overlays require ZSCustomOverworld v1+"); + ImGui::TextColored(ImVec4(1.0f, 0.6f, 0.4f, 1.0f), + ICON_MD_WARNING " Subscreen overlays require ZSCustomOverworld v1+"); + ImGui::Separator(); + ImGui::TextWrapped( + "To use visual effect overlays, you need to upgrade your ROM to " + "ZSCustomOverworld. This feature allows you to add atmospheric effects " + "like fog, rain, forest canopy, and sky backgrounds to your maps."); return; } - Text("Overlay Editor"); - Separator(); + // Help section + if (ImGui::CollapsingHeader(ICON_MD_HELP_OUTLINE " What are Visual Effects?", + ImGuiTreeNodeFlags_DefaultOpen)) { + ImGui::Indent(); + ImGui::TextWrapped( + "Visual effects (subscreen overlays) are semi-transparent layers drawn " + "on top of or behind your map. They reference special area maps (0x80-0x9F) " + "for their tile16 graphics data."); + ImGui::Spacing(); + ImGui::Text("Common uses:"); + ImGui::BulletText("Fog effects (Lost Woods, Skull Woods)"); + ImGui::BulletText("Rain (Misery Mire)"); + ImGui::BulletText("Forest canopy (Lost Woods)"); + ImGui::BulletText("Sky backgrounds (Death Mountain)"); + ImGui::BulletText("Under bridge views"); + ImGui::Unindent(); + ImGui::Separator(); + } // Enable/disable subscreen overlay static bool use_subscreen_overlay = false; - if (ImGui::Checkbox("Use Subscreen Overlay", &use_subscreen_overlay)) { + if (ImGui::Checkbox(ICON_MD_VISIBILITY " Enable Visual Effect for This Area", + &use_subscreen_overlay)) { // Update ROM data (*rom_)[zelda3::OverworldCustomSubscreenOverlayEnabled] = use_subscreen_overlay ? 1 : 0; } + if (ImGui::IsItemHovered()) { + ImGui::SetTooltip("Enable/disable visual effect overlay for this map area"); + } if (use_subscreen_overlay) { + ImGui::Spacing(); uint16_t current_overlay = overworld_->overworld_map(current_map)->subscreen_overlay(); - if (gui::InputHexWord("Overlay ID", ¤t_overlay, - kInputFieldSize + 20)) { + if (gui::InputHexWord(ICON_MD_PHOTO " Visual Effect Map ID", ¤t_overlay, + kInputFieldSize + 30)) { overworld_->mutable_overworld_map(current_map) ->set_subscreen_overlay(current_overlay); @@ -273,11 +348,37 @@ void MapPropertiesSystem::DrawOverlayEditor(int current_map, (*rom_)[rom_address] = current_overlay & 0xFF; (*rom_)[rom_address + 1] = (current_overlay >> 8) & 0xFF; } + if (ImGui::IsItemHovered()) { + ImGui::SetTooltip( + "ID of the special area map (0x80-0x9F) to use for\n" + "visual effects. That map's tile16 data will be drawn\n" + "as a semi-transparent layer on this area."); + } - Text("Common overlay IDs:"); - Text("0x0000 = None"); - Text("0x0001 = Map overlay"); - Text("0x0002 = Dungeon overlay"); + // Show description + std::string overlay_desc = GetOverlayDescription(current_overlay); + ImGui::TextColored(ImVec4(0.4f, 1.0f, 0.4f, 1.0f), + ICON_MD_INFO " %s", overlay_desc.c_str()); + + ImGui::Separator(); + if (ImGui::CollapsingHeader(ICON_MD_LIGHTBULB " Common Visual Effect IDs")) { + ImGui::Indent(); + ImGui::BulletText("0x0093 - Triforce Room Curtain"); + ImGui::BulletText("0x0094 - Under the Bridge"); + ImGui::BulletText("0x0095 - Sky Background (LW Death Mountain)"); + ImGui::BulletText("0x0096 - Pyramid Background"); + ImGui::BulletText("0x0097 - Fog Overlay (Master Sword Area)"); + ImGui::BulletText("0x009C - Lava Background (DW Death Mountain)"); + ImGui::BulletText("0x009D - Fog Overlay (Lost/Skull Woods)"); + ImGui::BulletText("0x009E - Tree Canopy (Forest)"); + ImGui::BulletText("0x009F - Rain Effect (Misery Mire)"); + ImGui::BulletText("0x00FF - No Overlay (Disabled)"); + ImGui::Unindent(); + } + } else { + ImGui::Spacing(); + ImGui::TextColored(ImVec4(0.6f, 0.6f, 0.6f, 1.0f), + ICON_MD_BLOCK " No visual effects enabled for this area"); } } @@ -297,9 +398,9 @@ void MapPropertiesSystem::SetupCanvasContextMenu( }; canvas.AddContextMenuItem(lock_item); - // Map Properties + // Area Configuration gui::Canvas::ContextMenuItem properties_item; - properties_item.label = "Map Properties"; + properties_item.label = ICON_MD_TUNE " Area Configuration"; properties_item.callback = [&show_map_properties_panel]() { show_map_properties_panel = true; }; @@ -311,15 +412,15 @@ void MapPropertiesSystem::SetupCanvasContextMenu( if (asm_version >= 3 && asm_version != 0xFF) { // Custom Background Color gui::Canvas::ContextMenuItem bg_color_item; - bg_color_item.label = "Custom Background Color"; + bg_color_item.label = ICON_MD_FORMAT_COLOR_FILL " Custom Background Color"; bg_color_item.callback = [&show_custom_bg_color_editor]() { show_custom_bg_color_editor = true; }; canvas.AddContextMenuItem(bg_color_item); - // Overlay Settings + // Visual Effects Editor gui::Canvas::ContextMenuItem overlay_item; - overlay_item.label = "Overlay Settings"; + overlay_item.label = ICON_MD_LAYERS " Visual Effects"; overlay_item.callback = [&show_overlay_editor]() { show_overlay_editor = true; }; @@ -355,7 +456,7 @@ void MapPropertiesSystem::DrawGraphicsPopup(int current_map, int game_state) { ImGui::Separator(); // Area Graphics - if (gui::InputHexByteCustom(ICON_MD_IMAGE " Area Graphics", + if (gui::InputHexByte(ICON_MD_IMAGE " Area Graphics", overworld_->mutable_overworld_map(current_map) ->mutable_area_graphics(), kHexByteInputWidth)) { @@ -365,7 +466,7 @@ void MapPropertiesSystem::DrawGraphicsPopup(int current_map, int game_state) { HOVER_HINT("Main tileset graphics for this map area"); // Sprite Graphics - if (gui::InputHexByteCustom( + if (gui::InputHexByte( absl::StrFormat(ICON_MD_PETS " Sprite GFX (%s)", kGameStateNames[game_state]) .c_str(), overworld_->mutable_overworld_map(current_map) @@ -379,7 +480,7 @@ void MapPropertiesSystem::DrawGraphicsPopup(int current_map, int game_state) { static uint8_t asm_version = (*rom_)[zelda3::OverworldCustomASMHasBeenApplied]; if (asm_version >= 3) { - if (gui::InputHexByteCustom(ICON_MD_ANIMATION " Animated GFX", + if (gui::InputHexByte(ICON_MD_ANIMATION " Animated GFX", overworld_->mutable_overworld_map(current_map) ->mutable_animated_gfx(), kHexByteInputWidth)) { @@ -399,7 +500,7 @@ void MapPropertiesSystem::DrawGraphicsPopup(int current_map, int game_state) { for (int i = 0; i < 8; i++) { TableNextColumn(); std::string label = absl::StrFormat(ICON_MD_LAYERS " Sheet %d", i); - if (gui::InputHexByteCustom(label.c_str(), + if (gui::InputHexByte(label.c_str(), overworld_->mutable_overworld_map(current_map) ->mutable_custom_tileset(i), 90.f)) { @@ -430,7 +531,7 @@ void MapPropertiesSystem::DrawPalettesPopup(int current_map, int game_state, ImGui::Separator(); // Area Palette - if (gui::InputHexByteCustom(ICON_MD_PALETTE " Area Palette", + if (gui::InputHexByte(ICON_MD_PALETTE " Area Palette", overworld_->mutable_overworld_map(current_map) ->mutable_area_palette(), kHexByteInputWidth)) { @@ -443,7 +544,7 @@ void MapPropertiesSystem::DrawPalettesPopup(int current_map, int game_state, static uint8_t asm_version = (*rom_)[zelda3::OverworldCustomASMHasBeenApplied]; if (asm_version >= 2) { - if (gui::InputHexByteCustom(ICON_MD_COLOR_LENS " Main Palette", + if (gui::InputHexByte(ICON_MD_COLOR_LENS " Main Palette", overworld_->mutable_overworld_map(current_map) ->mutable_main_palette(), kHexByteInputWidth)) { @@ -455,7 +556,7 @@ void MapPropertiesSystem::DrawPalettesPopup(int current_map, int game_state, } // Sprite Palette - if (gui::InputHexByteCustom( + if (gui::InputHexByte( absl::StrFormat(ICON_MD_COLORIZE " Sprite Pal (%s)", kGameStateNames[game_state]) .c_str(), overworld_->mutable_overworld_map(current_map) @@ -482,13 +583,13 @@ void MapPropertiesSystem::DrawPropertiesPopup(int current_map, bool& show_map_properties_panel, bool& show_overlay_preview, int& game_state) { - if (ImGui::BeginPopup("PropertiesPopup")) { + if (ImGui::BeginPopup("ConfigPopup")) { ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(kCompactItemSpacing, kCompactFramePadding)); ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(kCompactItemSpacing, kCompactFramePadding)); - ImGui::Text(ICON_MD_SETTINGS " Map Properties"); + ImGui::Text(ICON_MD_TUNE " Area Configuration"); ImGui::Separator(); // Basic Properties in 2-column layout for density @@ -567,12 +668,12 @@ void MapPropertiesSystem::DrawPropertiesPopup(int current_map, // Advanced Options Section ImGui::Separator(); - if (ImGui::Button(ICON_MD_OPEN_IN_NEW " Full Properties Panel", + if (ImGui::Button(ICON_MD_OPEN_IN_NEW " Full Configuration Panel", ImVec2(-1, 0))) { show_map_properties_panel = true; ImGui::CloseCurrentPopup(); } - HOVER_HINT("Open comprehensive properties editor with all tabs"); + HOVER_HINT("Open detailed area configuration with all settings tabs"); ImGui::PopStyleVar(2); // Pop the 2 style variables we pushed ImGui::EndPopup(); @@ -1026,91 +1127,170 @@ void MapPropertiesSystem::DrawOverlayControls(int current_map, bool is_special_overworld_map = (current_map >= 0x80 && current_map < 0xA0); if (is_special_overworld_map) { - // Special overworld maps (0x80-0x9F) do not support subscreen overlays - ImGui::Text("Special overworld maps (0x80-0x9F) do not support"); - ImGui::Text("subscreen overlays (visual effects)."); - ImGui::Text("Map 0x%02X is a special overworld map", current_map); + // Special overworld maps (0x80-0x9F) serve as visual effect sources + ImGui::TextColored(ImVec4(0.4f, 0.8f, 1.0f, 1.0f), + ICON_MD_INFO " Special Area Map (0x%02X)", current_map); + ImGui::Separator(); + ImGui::TextWrapped( + "This is a special area map (0x80-0x9F) used as a visual effect " + "source. These maps provide the graphics data for subscreen overlays " + "like fog, rain, forest canopy, and sky backgrounds that appear on " + "normal maps (0x00-0x7F)."); + ImGui::Spacing(); + ImGui::TextWrapped( + "You can edit the tile16 data here to customize how the visual effects " + "appear when referenced by other maps."); } else { - // Light World (0x00-0x3F) and Dark World (0x40-0x7F) maps support subscreen overlays for all versions + // Light World (0x00-0x3F) and Dark World (0x40-0x7F) maps support subscreen overlays - // Subscreen Overlay Section - ImGui::Text("Subscreen Overlay (Visual Effects)"); + // Comprehensive help section + ImGui::TextColored(ImVec4(0.4f, 0.8f, 1.0f, 1.0f), + ICON_MD_HELP_OUTLINE " Visual Effects Overview"); ImGui::SameLine(); - if (ImGui::Button("?")) { - ImGui::OpenPopup("SubscreenOverlayHelp"); + if (ImGui::Button(ICON_MD_INFO "##HelpButton")) { + ImGui::OpenPopup("OverlayTypesHelp"); } - if (ImGui::BeginPopup("SubscreenOverlayHelp")) { - ImGui::Text( - "Subscreen overlays are visual effects like fog, rain, canopy,"); - ImGui::Text("and backgrounds that are displayed using tile16 graphics."); - ImGui::Text( - "They reference special area maps (0x80-0x9F) for their tile data."); + + if (ImGui::BeginPopup("OverlayTypesHelp")) { + ImGui::Text(ICON_MD_HELP " Understanding Overlay Types"); + ImGui::Separator(); + + ImGui::TextColored(ImVec4(0.4f, 1.0f, 0.4f, 1.0f), + ICON_MD_LAYERS " 1. Subscreen Overlays (Visual Effects)"); + ImGui::Indent(); + ImGui::BulletText("Displayed as semi-transparent layers"); + ImGui::BulletText("Reference special area maps (0x80-0x9F)"); + ImGui::BulletText("Examples: fog, rain, forest canopy, sky"); + ImGui::BulletText("Purely visual - don't affect collision"); + ImGui::Unindent(); + + ImGui::Spacing(); + ImGui::TextColored(ImVec4(1.0f, 0.8f, 0.4f, 1.0f), + ICON_MD_EDIT_NOTE " 2. Map Overlays (Interactive)"); + ImGui::Indent(); + ImGui::BulletText("Dynamic tile16 changes on the map"); + ImGui::BulletText("Used for bridges appearing, holes opening"); + ImGui::BulletText("Stored as tile16 ID arrays"); + ImGui::BulletText("Affect collision and interaction"); + ImGui::BulletText("Triggered by game events/progression"); + ImGui::Unindent(); + + ImGui::Separator(); + ImGui::TextWrapped( + "Note: Subscreen overlays are what you configure here. " + "Map overlays are event-driven and edited separately."); + ImGui::EndPopup(); } + ImGui::Separator(); + + // Subscreen Overlay Section + ImGui::Text(ICON_MD_LAYERS " Subscreen Overlay (Visual Effects)"); uint16_t current_overlay = overworld_->mutable_overworld_map(current_map)->subscreen_overlay(); - if (gui::InputHexWord("Subscreen Overlay ID", ¤t_overlay, + if (gui::InputHexWord("Visual Effect Map ID", ¤t_overlay, kInputFieldSize + 20)) { overworld_->mutable_overworld_map(current_map) ->set_subscreen_overlay(current_overlay); RefreshMapProperties(); RefreshOverworldMap(); } - HOVER_HINT( - "Subscreen overlay ID - visual effects like fog, rain, backgrounds"); + if (ImGui::IsItemHovered()) { + ImGui::SetTooltip( + "References a special area map (0x80-0x9F) for visual effects.\n" + "The referenced map's tile16 data is drawn as a semi-transparent\n" + "layer on top of or behind this area for atmospheric effects."); + } - // Show subscreen overlay description + // Show subscreen overlay description with color coding std::string overlay_desc = GetOverlayDescription(current_overlay); - ImGui::Text("Description: %s", overlay_desc.c_str()); + if (current_overlay == 0x00FF) { + ImGui::TextColored(ImVec4(0.6f, 0.6f, 0.6f, 1.0f), + ICON_MD_CHECK " %s", overlay_desc.c_str()); + } else if (current_overlay >= 0x80 && current_overlay < 0xA0) { + ImGui::TextColored(ImVec4(0.4f, 1.0f, 0.4f, 1.0f), + ICON_MD_VISIBILITY " %s", overlay_desc.c_str()); + } else { + ImGui::TextColored(ImVec4(1.0f, 0.8f, 0.4f, 1.0f), + ICON_MD_HELP_OUTLINE " %s", overlay_desc.c_str()); + } - // Preview checkbox - if (ImGui::Checkbox("Preview Subscreen Overlay on Map", + // Preview checkbox with better labeling + ImGui::Spacing(); + if (ImGui::Checkbox(ICON_MD_PREVIEW " Preview Visual Effect on Map", &show_overlay_preview)) { // Toggle subscreen overlay preview } - HOVER_HINT("Show semi-transparent preview of subscreen overlay on the map"); + if (ImGui::IsItemHovered()) { + ImGui::SetTooltip( + "Shows a semi-transparent preview of the visual effect overlay\n" + "drawn on top of the current map in the editor canvas.\n\n" + "This preview shows how the subscreen overlay will appear in-game."); + } ImGui::Separator(); - // Interactive Overlay Section (for vanilla ROMs) + // Interactive/Dynamic Map Overlay Section (for vanilla ROMs) if (asm_version == 0xFF) { - ImGui::Text("Interactive Overlay (Holes/Changes)"); + ImGui::TextColored(ImVec4(1.0f, 0.8f, 0.4f, 1.0f), + ICON_MD_EDIT_NOTE " Map Overlay (Interactive)"); ImGui::SameLine(); - if (ImGui::Button("?")) { + if (ImGui::Button(ICON_MD_INFO "##MapOverlayHelp")) { ImGui::OpenPopup("InteractiveOverlayHelp"); } if (ImGui::BeginPopup("InteractiveOverlayHelp")) { - ImGui::Text( - "Interactive overlays reveal holes or change elements on top"); - ImGui::Text("of the map. They use tile16 graphics and are present in"); - ImGui::Text( - "vanilla ROMs. ZSCustomOverworld expands this functionality."); + ImGui::Text(ICON_MD_HELP " Map Overlays (Interactive Tile Changes)"); + ImGui::Separator(); + ImGui::TextWrapped( + "Map overlays are different from visual effect overlays. " + "They contain tile16 data that dynamically replaces tiles on " + "the map based on game events or progression."); + ImGui::Spacing(); + ImGui::Text("Common uses:"); + ImGui::BulletText("Bridges appearing over water"); + ImGui::BulletText("Holes revealing secret passages"); + ImGui::BulletText("Rocks/bushes being moved"); + ImGui::BulletText("Environmental changes from story events"); + ImGui::Spacing(); + ImGui::TextWrapped( + "These are triggered by game code and stored as separate " + "tile data arrays in the ROM. ZSCustomOverworld v3+ provides " + "extended control over these features."); ImGui::EndPopup(); } auto* current_map_ptr = overworld_->overworld_map(current_map); + ImGui::Spacing(); if (current_map_ptr->has_overlay()) { - ImGui::Text("Interactive Overlay ID: 0x%04X", - current_map_ptr->overlay_id()); - ImGui::Text("Overlay Data Size: %d bytes", + ImGui::TextColored(ImVec4(0.4f, 1.0f, 0.4f, 1.0f), + ICON_MD_CHECK " Overlay ID: 0x%04X", + current_map_ptr->overlay_id()); + ImGui::Text(ICON_MD_STORAGE " Data Size: %d bytes", static_cast(current_map_ptr->overlay_data().size())); + ImGui::TextColored(ImVec4(0.8f, 0.8f, 0.4f, 1.0f), + ICON_MD_INFO " Read-only in vanilla ROM"); } else { - ImGui::Text("No interactive overlay data for this map"); + ImGui::TextColored(ImVec4(0.6f, 0.6f, 0.6f, 1.0f), + ICON_MD_BLOCK " No map overlay data for this area"); } - HOVER_HINT( - "Interactive overlay for revealing holes/changing elements " - "(read-only in vanilla)"); } - // Show version info + // Show version and capability info + ImGui::Separator(); if (asm_version == 0xFF) { - ImGui::Text( - "Vanilla ROM - subscreen overlays reference special area maps"); - ImGui::Text( - "(0x80-0x9F) for visual effects like fog, rain, backgrounds."); + ImGui::TextColored(ImVec4(0.7f, 0.7f, 0.7f, 1.0f), + ICON_MD_INFO " Vanilla ROM"); + ImGui::BulletText("Visual effects use maps 0x80-0x9F"); + ImGui::BulletText("Map overlays are read-only"); } else { - ImGui::Text("ZSCustomOverworld v%d", asm_version); + ImGui::TextColored(ImVec4(0.4f, 1.0f, 0.4f, 1.0f), + ICON_MD_UPGRADE " ZSCustomOverworld v%d", asm_version); + ImGui::BulletText("Enhanced visual effect control"); + if (asm_version >= 3) { + ImGui::BulletText("Extended overlay system"); + ImGui::BulletText("Custom area sizes support"); + } } } } diff --git a/src/app/editor/overworld/overworld_editor.cc b/src/app/editor/overworld/overworld_editor.cc index 315640b3..77749540 100644 --- a/src/app/editor/overworld/overworld_editor.cc +++ b/src/app/editor/overworld/overworld_editor.cc @@ -225,10 +225,10 @@ absl::Status OverworldEditor::Update() { v3_settings_card.End(); } - // Map Properties Panel + // Area Configuration Panel (detailed editing) if (show_map_properties_panel_) { - ImGui::SetNextWindowSize(ImVec2(600, 700), ImGuiCond_FirstUseEver); - if (ImGui::Begin(ICON_MD_SETTINGS " Map Properties", &show_map_properties_panel_)) { + ImGui::SetNextWindowSize(ImVec2(650, 750), ImGuiCond_FirstUseEver); + if (ImGui::Begin(ICON_MD_TUNE " Area Configuration###AreaConfig", &show_map_properties_panel_)) { if (rom_->is_loaded() && overworld_.is_loaded() && map_properties_system_) { map_properties_system_->DrawMapPropertiesPanel(current_map_, show_map_properties_panel_); } @@ -247,10 +247,10 @@ absl::Status OverworldEditor::Update() { ImGui::End(); } - // Overlay Editor + // Visual Effects Editor (Subscreen Overlays) if (show_overlay_editor_) { - ImGui::SetNextWindowSize(ImVec2(450, 400), ImGuiCond_FirstUseEver); - if (ImGui::Begin(ICON_MD_LAYERS " Overlay Editor", &show_overlay_editor_)) { + ImGui::SetNextWindowSize(ImVec2(500, 450), ImGuiCond_FirstUseEver); + if (ImGui::Begin(ICON_MD_LAYERS " Visual Effects Editor###OverlayEditor", &show_overlay_editor_)) { if (rom_->is_loaded() && overworld_.is_loaded() && map_properties_system_) { map_properties_system_->DrawOverlayEditor(current_map_, show_overlay_editor_); } @@ -416,93 +416,22 @@ void OverworldEditor::DrawToolset() { show_usage_stats_ = !show_usage_stats_; } - if (toolbar.AddAction(ICON_MD_TUNE, "Open Map Properties")) { + if (toolbar.AddAction(ICON_MD_TUNE, "Open Area Configuration")) { show_map_properties_panel_ = !show_map_properties_panel_; } toolbar.End(); - // Legacy popup windows removed - all editors now use EditorCard system - // Tile16 Editor, Graphics Groups, Usage Stats, etc. are rendered in Update() as cards + // All editor windows are now rendered in Update() using either EditorCard system + // or MapPropertiesSystem for map-specific panels. This keeps the toolset clean + // and prevents ImGui ID stack issues. - if (show_gfx_group_editor_) { - std::string gfx_window_name = context_ - ? absl::StrFormat("%s Graphics Groups###GfxGroup_S%zu", ICON_MD_COLLECTIONS, context_->session_id) - : ICON_MD_COLLECTIONS " Graphics Groups"; - - // Responsive sizing - ImVec2 window_size = ImVec2( - gui::GetResponsiveWidth(500, 900, 0.6f), - ImGui::GetIO().DisplaySize.y * 0.7f - ); - ImGui::SetNextWindowSize(window_size, ImGuiCond_FirstUseEver); - - gui::BeginWindowWithDisplaySettings(gfx_window_name.c_str(), - &show_gfx_group_editor_); - status_ = gfx_group_editor_.Update(); - gui::EndWindowWithDisplaySettings(); - } - - if (show_properties_editor_) { - std::string props_window_name = context_ - ? absl::StrFormat("%s Map Properties###Props_S%zu", ICON_MD_SETTINGS, context_->session_id) - : ICON_MD_SETTINGS " Map Properties"; - - // Compact window for properties - ImVec2 window_size = ImVec2(450, 600); - ImGui::SetNextWindowSize(window_size, ImGuiCond_FirstUseEver); - - ImGui::Begin(props_window_name.c_str(), &show_properties_editor_); - DrawOverworldProperties(); - ImGui::End(); - } - - if (show_custom_bg_color_editor_) { - std::string bg_window_name = context_ - ? absl::StrFormat("%s Background Colors###BG_S%zu", ICON_MD_COLOR_LENS, context_->session_id) - : ICON_MD_COLOR_LENS " Background Colors"; - - ImVec2 window_size = ImVec2(400, 500); - ImGui::SetNextWindowSize(window_size, ImGuiCond_FirstUseEver); - - ImGui::Begin(bg_window_name.c_str(), &show_custom_bg_color_editor_); - DrawCustomBackgroundColorEditor(); - ImGui::End(); - } - - if (show_overlay_editor_) { - std::string overlay_window_name = context_ - ? absl::StrFormat("%s Overlay Editor###Overlay_S%zu", ICON_MD_LAYERS, context_->session_id) - : ICON_MD_LAYERS " Overlay Editor"; - - ImVec2 window_size = ImVec2(500, 600); - ImGui::SetNextWindowSize(window_size, ImGuiCond_FirstUseEver); - - ImGui::Begin(overlay_window_name.c_str(), &show_overlay_editor_); - DrawOverlayEditor(); - ImGui::End(); - } - - if (show_map_properties_panel_) { - // Create unique window name using session ID from context - std::string map_props_window_name = context_ - ? absl::StrFormat("%s Map Properties###MapProps_S%zu", ICON_MD_TUNE, context_->session_id) - : ICON_MD_TUNE " Map Properties"; - - ImVec2 window_size = ImVec2( - gui::GetResponsiveWidth(400, 700, 0.4f), - 600 - ); - ImGui::SetNextWindowSize(window_size, ImGuiCond_FirstUseEver); - - ImGui::Begin(map_props_window_name.c_str(), &show_map_properties_panel_); - - // Use WidgetIdScope for test automation - gui::WidgetIdScope map_props_scope("MapProperties"); - DrawMapPropertiesPanel(); - - ImGui::End(); - } + // Legacy window code removed - windows rendered in Update() include: + // - Graphics Groups (EditorCard) + // - Area Configuration (MapPropertiesSystem) + // - Background Color Editor (MapPropertiesSystem) + // - Visual Effects Editor (MapPropertiesSystem) + // - Tile16 Editor, Usage Stats, etc. (EditorCards) // Keyboard shortcuts for the Overworld Editor if (!ImGui::IsAnyItemActive()) { @@ -2609,9 +2538,9 @@ void OverworldEditor::DrawOverworldContextMenu() { Separator(); - // Quick access to map settings - if (MenuItem("Map Properties")) { - show_properties_editor_ = true; + // Quick access to area configuration + if (MenuItem(ICON_MD_TUNE " Area Configuration")) { + show_map_properties_panel_ = true; current_map_ = hovered_map; }