refactor: Improve Editor Management and UI Consistency

- Removed PushID and PopID calls in EditorManager to prevent ID stack corruption, relying on window titles for uniqueness.
- Updated ImGui window size and position settings to use FirstUseEver for maximizing on first open, enhancing user experience.
- Replaced AgentUI::PopPanelStyle with ImGui::PopStyleColor in multiple locations for consistency in style management.
- Ensured all EditorCard instances consistently call End after Begin, improving code clarity and preventing potential rendering issues.
This commit is contained in:
scawful
2025-10-06 00:33:10 -04:00
parent 5dca8ecc79
commit dd56addd5e
9 changed files with 287 additions and 118 deletions

View File

@@ -555,7 +555,7 @@ void AgentChatWidget::RenderHistory() {
} }
} }
ImGui::EndChild(); ImGui::EndChild();
AgentUI::PopPanelStyle(); ImGui::PopStyleColor(); // Pop the color we pushed at line 531
last_history_size_ = history.size(); last_history_size_ = history.size();
} }
@@ -1342,8 +1342,8 @@ void AgentChatWidget::RenderCollaborationPanel() {
} }
ImGui::EndChild(); ImGui::EndChild();
AgentUI::PopPanelStyle(); ImGui::PopStyleColor(); // Pop the ChildBg color from line 1091
ImGui::PopStyleVar(2); ImGui::PopStyleVar(2); // Pop the 2 StyleVars from lines 1082-1083
ImGui::PopID(); // CollabPanel ImGui::PopID(); // CollabPanel
} }
@@ -1666,7 +1666,7 @@ void AgentChatWidget::RenderAgentConfigPanel() {
} }
ImGui::EndChild(); ImGui::EndChild();
AgentUI::PopPanelStyle(); ImGui::PopStyleColor(); // Pop the ChildBg color from line 1609
} }
void AgentChatWidget::RenderZ3EDCommandPanel() { void AgentChatWidget::RenderZ3EDCommandPanel() {
@@ -1749,9 +1749,9 @@ void AgentChatWidget::RenderZ3EDCommandPanel() {
} }
ImGui::EndChild(); ImGui::EndChild();
AgentUI::PopPanelStyle(); ImGui::PopStyleColor(); // Pop the ChildBg color from line 1677
ImGui::PopID(); // FIX: Pop the Z3EDCmdPanel ID ImGui::PopID(); // Pop the Z3EDCmdPanel ID
} }
void AgentChatWidget::RenderRomSyncPanel() { void AgentChatWidget::RenderRomSyncPanel() {
@@ -1848,7 +1848,7 @@ void AgentChatWidget::RenderRomSyncPanel() {
} }
ImGui::EndChild(); ImGui::EndChild();
AgentUI::PopPanelStyle(); ImGui::PopStyleColor(); // Pop the ChildBg color from line 1758
} }
void AgentChatWidget::RenderSnapshotPreviewPanel() { void AgentChatWidget::RenderSnapshotPreviewPanel() {
@@ -1898,7 +1898,7 @@ void AgentChatWidget::RenderSnapshotPreviewPanel() {
} }
ImGui::EndChild(); ImGui::EndChild();
AgentUI::PopPanelStyle(); ImGui::PopStyleColor(); // Pop the ChildBg color from line 1860
} }
void AgentChatWidget::RenderProposalManagerPanel() { void AgentChatWidget::RenderProposalManagerPanel() {
@@ -2094,7 +2094,7 @@ void AgentChatWidget::RenderHarnessPanel() {
} }
ImGui::EndChild(); ImGui::EndChild();
AgentUI::PopPanelStyle(); ImGui::PopStyleColor(); // Pop the ChildBg color from line 1982
ImGui::PopID(); ImGui::PopID();
} }

View File

@@ -228,8 +228,8 @@ void AssemblyEditor::UpdateCodeView() {
current_folder_ = LoadFolder(FileDialogWrapper::ShowOpenFolderDialog()); current_folder_ = LoadFolder(FileDialogWrapper::ShowOpenFolderDialog());
} }
} }
file_browser_card.End();
} }
file_browser_card.End(); // ALWAYS call End after Begin
// Draw open files as individual, dockable EditorCards // Draw open files as individual, dockable EditorCards
for (int i = 0; i < active_files_.Size; i++) { for (int i = 0; i < active_files_.Size; i++) {
@@ -253,8 +253,8 @@ void AssemblyEditor::UpdateCodeView() {
active_file_id_ = file_id; active_file_id_ = file_id;
} }
open_files_[file_id].Render(absl::StrCat("##", card_name).c_str()); open_files_[file_id].Render(absl::StrCat("##", card_name).c_str());
file_card.End();
} }
file_card.End(); // ALWAYS call End after Begin
if (!open) { if (!open) {
active_files_.erase(active_files_.Data + i); active_files_.erase(active_files_.Data + i);

View File

@@ -1,23 +1,53 @@
#include "app/editor/code/memory_editor.h" #include "app/editor/code/memory_editor.h"
#include "absl/strings/str_format.h"
#include "app/gui/icons.h" #include "app/gui/icons.h"
#include "app/gui/style.h"
#include "imgui/imgui.h"
namespace yaze { namespace yaze {
namespace editor { namespace editor {
void MemoryEditorWithDiffChecker::DrawToolbar() { void MemoryEditorWithDiffChecker::DrawToolbar() {
// Modern compact toolbar with icon-only buttons
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(6, 4));
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(4, 4));
if (ImGui::Button(ICON_MD_LOCATION_SEARCHING " Jump")) { if (ImGui::Button(ICON_MD_LOCATION_SEARCHING " Jump")) {
ImGui::OpenPopup("JumpToAddress"); ImGui::OpenPopup("JumpToAddress");
} }
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("Jump to specific address");
}
ImGui::SameLine(); ImGui::SameLine();
if (ImGui::Button(ICON_MD_SEARCH " Search")) { if (ImGui::Button(ICON_MD_SEARCH " Search")) {
ImGui::OpenPopup("SearchPattern"); ImGui::OpenPopup("SearchPattern");
} }
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("Search for hex pattern");
}
ImGui::SameLine(); ImGui::SameLine();
if (ImGui::Button(ICON_MD_BOOKMARK " Bookmarks")) { if (ImGui::Button(ICON_MD_BOOKMARK " Bookmarks")) {
ImGui::OpenPopup("Bookmarks"); ImGui::OpenPopup("Bookmarks");
} }
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("Manage address bookmarks");
}
ImGui::SameLine();
ImGui::Text(ICON_MD_MORE_VERT);
ImGui::SameLine();
// Show current address
if (current_address_ != 0) {
ImGui::TextColored(ImVec4(0.4f, 0.8f, 1.0f, 1.0f),
ICON_MD_LOCATION_ON " 0x%06X", current_address_);
}
ImGui::PopStyleVar(2);
ImGui::Separator();
DrawJumpToAddressPopup(); DrawJumpToAddressPopup();
DrawSearchPopup(); DrawSearchPopup();
@@ -25,17 +55,37 @@ void MemoryEditorWithDiffChecker::DrawToolbar() {
} }
void MemoryEditorWithDiffChecker::DrawJumpToAddressPopup() { void MemoryEditorWithDiffChecker::DrawJumpToAddressPopup() {
if (ImGui::BeginPopup("JumpToAddress")) { if (ImGui::BeginPopupModal("JumpToAddress", nullptr, ImGuiWindowFlags_AlwaysAutoResize)) {
ImGui::Text(ICON_MD_LOCATION_SEARCHING " Jump to Address"); ImGui::TextColored(ImVec4(0.4f, 0.8f, 1.0f, 1.0f),
ICON_MD_LOCATION_SEARCHING " Jump to Address");
ImGui::Separator(); ImGui::Separator();
ImGui::InputText("Address (hex)", jump_address_, IM_ARRAYSIZE(jump_address_)); ImGui::Spacing();
ImGui::SetNextItemWidth(200);
if (ImGui::InputText("##jump_addr", jump_address_, IM_ARRAYSIZE(jump_address_),
ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_EnterReturnsTrue)) {
// Parse and jump on Enter key
unsigned int addr;
if (sscanf(jump_address_, "%X", &addr) == 1) {
current_address_ = addr;
ImGui::CloseCurrentPopup();
}
}
ImGui::TextDisabled("Format: 0x1C800 or 1C800"); ImGui::TextDisabled("Format: 0x1C800 or 1C800");
if (ImGui::Button("Go", ImVec2(120, 0))) {
// TODO: Parse address and scroll to it ImGui::Spacing();
ImGui::Separator();
ImGui::Spacing();
if (ImGui::Button(ICON_MD_CHECK " Go", ImVec2(120, 0))) {
unsigned int addr;
if (sscanf(jump_address_, "%X", &addr) == 1) {
current_address_ = addr;
}
ImGui::CloseCurrentPopup(); ImGui::CloseCurrentPopup();
} }
ImGui::SameLine(); ImGui::SameLine();
if (ImGui::Button("Cancel", ImVec2(120, 0))) { if (ImGui::Button(ICON_MD_CANCEL " Cancel", ImVec2(120, 0))) {
ImGui::CloseCurrentPopup(); ImGui::CloseCurrentPopup();
} }
ImGui::EndPopup(); ImGui::EndPopup();
@@ -43,17 +93,45 @@ void MemoryEditorWithDiffChecker::DrawJumpToAddressPopup() {
} }
void MemoryEditorWithDiffChecker::DrawSearchPopup() { void MemoryEditorWithDiffChecker::DrawSearchPopup() {
if (ImGui::BeginPopup("SearchPattern")) { if (ImGui::BeginPopupModal("SearchPattern", nullptr, ImGuiWindowFlags_AlwaysAutoResize)) {
ImGui::Text(ICON_MD_SEARCH " Search Hex Pattern"); ImGui::TextColored(ImVec4(0.4f, 0.8f, 0.4f, 1.0f),
ICON_MD_SEARCH " Search Hex Pattern");
ImGui::Separator(); ImGui::Separator();
ImGui::InputText("Pattern", search_pattern_, IM_ARRAYSIZE(search_pattern_)); ImGui::Spacing();
ImGui::SetNextItemWidth(300);
if (ImGui::InputText("##search_pattern", search_pattern_, IM_ARRAYSIZE(search_pattern_),
ImGuiInputTextFlags_EnterReturnsTrue)) {
// TODO: Implement search
ImGui::CloseCurrentPopup();
}
ImGui::TextDisabled("Use ?? for wildcard (e.g. FF 00 ?? 12)"); ImGui::TextDisabled("Use ?? for wildcard (e.g. FF 00 ?? 12)");
if (ImGui::Button("Search", ImVec2(120, 0))) { ImGui::Spacing();
// Quick preset patterns
ImGui::Text(ICON_MD_LIST " Quick Patterns:");
if (ImGui::SmallButton("LDA")) {
snprintf(search_pattern_, sizeof(search_pattern_), "A9 ??");
}
ImGui::SameLine();
if (ImGui::SmallButton("STA")) {
snprintf(search_pattern_, sizeof(search_pattern_), "8D ?? ??");
}
ImGui::SameLine();
if (ImGui::SmallButton("JSR")) {
snprintf(search_pattern_, sizeof(search_pattern_), "20 ?? ??");
}
ImGui::Spacing();
ImGui::Separator();
ImGui::Spacing();
if (ImGui::Button(ICON_MD_SEARCH " Search", ImVec2(120, 0))) {
// TODO: Implement search using hex-search handler // TODO: Implement search using hex-search handler
ImGui::CloseCurrentPopup(); ImGui::CloseCurrentPopup();
} }
ImGui::SameLine(); ImGui::SameLine();
if (ImGui::Button("Cancel", ImVec2(120, 0))) { if (ImGui::Button(ICON_MD_CANCEL " Cancel", ImVec2(120, 0))) {
ImGui::CloseCurrentPopup(); ImGui::CloseCurrentPopup();
} }
ImGui::EndPopup(); ImGui::EndPopup();
@@ -61,27 +139,79 @@ void MemoryEditorWithDiffChecker::DrawSearchPopup() {
} }
void MemoryEditorWithDiffChecker::DrawBookmarksPopup() { void MemoryEditorWithDiffChecker::DrawBookmarksPopup() {
if (ImGui::BeginPopup("Bookmarks")) { if (ImGui::BeginPopupModal("Bookmarks", nullptr, ImGuiWindowFlags_AlwaysAutoResize)) {
ImGui::Text(ICON_MD_BOOKMARK " Memory Bookmarks"); ImGui::TextColored(ImVec4(1.0f, 0.843f, 0.0f, 1.0f),
ICON_MD_BOOKMARK " Memory Bookmarks");
ImGui::Separator(); ImGui::Separator();
ImGui::Spacing();
if (bookmarks_.empty()) { if (bookmarks_.empty()) {
ImGui::TextDisabled("No bookmarks yet"); ImGui::TextDisabled(ICON_MD_INFO " No bookmarks yet");
ImGui::Spacing();
ImGui::Separator(); ImGui::Separator();
if (ImGui::Button("Add Current Address")) { ImGui::Spacing();
// TODO: Add bookmark at current address
if (ImGui::Button(ICON_MD_ADD " Add Current Address", ImVec2(250, 0))) {
Bookmark new_bookmark;
new_bookmark.address = current_address_;
new_bookmark.name = absl::StrFormat("Bookmark %zu", bookmarks_.size() + 1);
new_bookmark.description = "User-defined bookmark";
bookmarks_.push_back(new_bookmark);
} }
} else { } else {
for (size_t i = 0; i < bookmarks_.size(); ++i) { // Bookmarks table
const auto& bm = bookmarks_[i]; ImGui::BeginChild("##bookmarks_list", ImVec2(500, 300), true);
ImGui::PushID(static_cast<int>(i)); if (ImGui::BeginTable("##bookmarks_table", 3,
if (ImGui::Selectable(bm.name.c_str())) { ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg |
current_address_ = bm.address; ImGuiTableFlags_Resizable)) {
// TODO: Jump to this address ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_WidthFixed, 150);
ImGui::TableSetupColumn("Address", ImGuiTableColumnFlags_WidthFixed, 100);
ImGui::TableSetupColumn("Description", ImGuiTableColumnFlags_WidthStretch);
ImGui::TableHeadersRow();
for (size_t i = 0; i < bookmarks_.size(); ++i) {
const auto& bm = bookmarks_[i];
ImGui::PushID(static_cast<int>(i));
ImGui::TableNextRow();
ImGui::TableNextColumn();
if (ImGui::Selectable(bm.name.c_str(), false, ImGuiSelectableFlags_SpanAllColumns)) {
current_address_ = bm.address;
ImGui::CloseCurrentPopup();
}
ImGui::TableNextColumn();
ImGui::TextColored(ImVec4(0.4f, 0.8f, 1.0f, 1.0f), "0x%06X", bm.address);
ImGui::TableNextColumn();
ImGui::TextDisabled("%s", bm.description.c_str());
ImGui::PopID();
} }
ImGui::TextDisabled(" 0x%06X - %s", bm.address, bm.description.c_str()); ImGui::EndTable();
ImGui::PopID();
} }
ImGui::EndChild();
ImGui::Spacing();
if (ImGui::Button(ICON_MD_ADD " Add Bookmark", ImVec2(150, 0))) {
Bookmark new_bookmark;
new_bookmark.address = current_address_;
new_bookmark.name = absl::StrFormat("Bookmark %zu", bookmarks_.size() + 1);
new_bookmark.description = "User-defined bookmark";
bookmarks_.push_back(new_bookmark);
}
ImGui::SameLine();
if (ImGui::Button(ICON_MD_CLEAR_ALL " Clear All", ImVec2(150, 0))) {
bookmarks_.clear();
}
}
ImGui::Spacing();
ImGui::Separator();
ImGui::Spacing();
if (ImGui::Button(ICON_MD_CLOSE " Close", ImVec2(250, 0))) {
ImGui::CloseCurrentPopup();
} }
ImGui::EndPopup(); ImGui::EndPopup();

View File

@@ -140,8 +140,8 @@ void DungeonEditorV2::DrawLayout() {
gui::EditorCard room_card(card_name, ICON_MD_GRID_ON, &open); gui::EditorCard room_card(card_name, ICON_MD_GRID_ON, &open);
if (room_card.Begin()) { if (room_card.Begin()) {
DrawRoomTab(room_id); DrawRoomTab(room_id);
room_card.End();
} }
room_card.End(); // ALWAYS call End after Begin
if (!open) { if (!open) {
active_rooms_.erase(active_rooms_.Data + i); active_rooms_.erase(active_rooms_.Data + i);

View File

@@ -747,15 +747,12 @@ absl::Status EditorManager::Update() {
std::string window_title = std::string window_title =
GenerateUniqueEditorTitle(editor->type(), session_idx); GenerateUniqueEditorTitle(editor->type(), session_idx);
// Create truly unique ImGui ID combining session index and editor type // Note: PushID removed - window title provides sufficient uniqueness
// This ensures ImGui treats them as completely separate windows // and PushID was causing ID stack corruption issues
ImGui::PushID(static_cast<int>(session_idx * 100 + static_cast<int>(editor->type())));
// Set window to maximize on first open // Set window to maximize on first open (use FirstUseEver instead of IsWindowAppearing check)
if (ImGui::IsWindowAppearing()) { ImGui::SetNextWindowSize(ImGui::GetMainViewport()->WorkSize, ImGuiCond_FirstUseEver);
ImGui::SetNextWindowSize(ImGui::GetMainViewport()->WorkSize, ImGuiCond_Appearing); ImGui::SetNextWindowPos(ImGui::GetMainViewport()->WorkPos, ImGuiCond_FirstUseEver);
ImGui::SetNextWindowPos(ImGui::GetMainViewport()->WorkPos, ImGuiCond_Appearing);
}
if (ImGui::Begin(window_title.c_str(), editor->active(), if (ImGui::Begin(window_title.c_str(), editor->active(),
ImGuiWindowFlags_None)) { // Allow full docking ImGuiWindowFlags_None)) { // Allow full docking
@@ -801,7 +798,7 @@ absl::Status EditorManager::Update() {
context_.session_id = prev_session_id; // Restore previous session ID context_.session_id = prev_session_id; // Restore previous session ID
} }
ImGui::End(); ImGui::End();
ImGui::PopID(); // Pop the unique ID for this session+editor combination // PopID removed to match PushID removal above
} }
} }
} }

View File

@@ -56,27 +56,35 @@ absl::Status GraphicsEditor::Update() {
static gui::EditorCard player_anims_card("Player Animations", ICON_MD_PERSON); static gui::EditorCard player_anims_card("Player Animations", ICON_MD_PERSON);
static gui::EditorCard prototype_card("Prototype Viewer", ICON_MD_CONSTRUCTION); static gui::EditorCard prototype_card("Prototype Viewer", ICON_MD_CONSTRUCTION);
if (show_sheet_editor_ && sheet_editor_card.Begin(&show_sheet_editor_)) { if (show_sheet_editor_) {
status_ = UpdateGfxEdit(); if (sheet_editor_card.Begin(&show_sheet_editor_)) {
sheet_editor_card.End(); status_ = UpdateGfxEdit();
}
if (show_sheet_browser_ && sheet_browser_card.Begin(&show_sheet_browser_)) {
if (asset_browser_.Initialized == false) {
asset_browser_.Initialize(gfx::Arena::Get().gfx_sheets());
} }
asset_browser_.Draw(gfx::Arena::Get().gfx_sheets()); sheet_editor_card.End(); // ALWAYS call End after Begin
sheet_browser_card.End();
} }
if (show_player_animations_ && player_anims_card.Begin(&show_player_animations_)) { if (show_sheet_browser_) {
status_ = UpdateLinkGfxView(); if (sheet_browser_card.Begin(&show_sheet_browser_)) {
player_anims_card.End(); if (asset_browser_.Initialized == false) {
asset_browser_.Initialize(gfx::Arena::Get().gfx_sheets());
}
asset_browser_.Draw(gfx::Arena::Get().gfx_sheets());
}
sheet_browser_card.End(); // ALWAYS call End after Begin
} }
if (show_prototype_viewer_ && prototype_card.Begin(&show_prototype_viewer_)) { if (show_player_animations_) {
status_ = UpdateScadView(); if (player_anims_card.Begin(&show_player_animations_)) {
prototype_card.End(); status_ = UpdateLinkGfxView();
}
player_anims_card.End(); // ALWAYS call End after Begin
}
if (show_prototype_viewer_) {
if (prototype_card.Begin(&show_prototype_viewer_)) {
status_ = UpdateScadView();
}
prototype_card.End(); // ALWAYS call End after Begin
} }
CLEAR_AND_RETURN_STATUS(status_) CLEAR_AND_RETURN_STATUS(status_)

View File

@@ -74,25 +74,35 @@ absl::Status ScreenEditor::Update() {
static gui::EditorCard title_screen_card("Title Screen", ICON_MD_TITLE); static gui::EditorCard title_screen_card("Title Screen", ICON_MD_TITLE);
static gui::EditorCard naming_screen_card("Naming Screen", ICON_MD_EDIT_ATTRIBUTES); static gui::EditorCard naming_screen_card("Naming Screen", ICON_MD_EDIT_ATTRIBUTES);
if (show_dungeon_maps_ && dungeon_maps_card.Begin(&show_dungeon_maps_)) { if (show_dungeon_maps_) {
DrawDungeonMapsEditor(); if (dungeon_maps_card.Begin(&show_dungeon_maps_)) {
dungeon_maps_card.End(); DrawDungeonMapsEditor();
}
dungeon_maps_card.End(); // ALWAYS call End after Begin
} }
if (show_inventory_menu_ && inventory_menu_card.Begin(&show_inventory_menu_)) { if (show_inventory_menu_) {
DrawInventoryMenuEditor(); if (inventory_menu_card.Begin(&show_inventory_menu_)) {
inventory_menu_card.End(); DrawInventoryMenuEditor();
}
inventory_menu_card.End(); // ALWAYS call End after Begin
} }
if (show_overworld_map_ && overworld_map_card.Begin(&show_overworld_map_)) { if (show_overworld_map_) {
DrawOverworldMapEditor(); if (overworld_map_card.Begin(&show_overworld_map_)) {
overworld_map_card.End(); DrawOverworldMapEditor();
}
overworld_map_card.End(); // ALWAYS call End after Begin
} }
if (show_title_screen_ && title_screen_card.Begin(&show_title_screen_)) { if (show_title_screen_) {
DrawTitleScreenEditor(); if (title_screen_card.Begin(&show_title_screen_)) {
title_screen_card.End(); DrawTitleScreenEditor();
}
title_screen_card.End(); // ALWAYS call End after Begin
} }
if (show_naming_screen_ && naming_screen_card.Begin(&show_naming_screen_)) { if (show_naming_screen_) {
DrawNamingScreenEditor(); if (naming_screen_card.Begin(&show_naming_screen_)) {
naming_screen_card.End(); DrawNamingScreenEditor();
}
naming_screen_card.End(); // ALWAYS call End after Begin
} }
return status_; return status_;

View File

@@ -168,58 +168,72 @@ absl::Status OverworldEditor::Update() {
DrawOverworldCanvas(); DrawOverworldCanvas();
// Floating tile selector cards (4 tabs converted to separate cards) // Floating tile selector cards (4 tabs converted to separate cards)
if (show_tile16_selector_ && tile16_card.Begin(&show_tile16_selector_)) { if (show_tile16_selector_) {
status_ = DrawTile16Selector(); if (tile16_card.Begin(&show_tile16_selector_)) {
tile16_card.End(); status_ = DrawTile16Selector();
}
tile16_card.End(); // ALWAYS call End after Begin
} }
if (show_tile8_selector_ && tile8_card.Begin(&show_tile8_selector_)) { if (show_tile8_selector_) {
gui::BeginPadding(3); if (tile8_card.Begin(&show_tile8_selector_)) {
gui::BeginChildWithScrollbar("##Tile8SelectorScrollRegion"); gui::BeginPadding(3);
DrawTile8Selector(); gui::BeginChildWithScrollbar("##Tile8SelectorScrollRegion");
ImGui::EndChild(); DrawTile8Selector();
gui::EndNoPadding(); ImGui::EndChild();
tile8_card.End(); gui::EndNoPadding();
}
tile8_card.End(); // ALWAYS call End after Begin
} }
if (show_area_gfx_ && area_gfx_card.Begin(&show_area_gfx_)) { if (show_area_gfx_) {
status_ = DrawAreaGraphics(); if (area_gfx_card.Begin(&show_area_gfx_)) {
area_gfx_card.End(); status_ = DrawAreaGraphics();
}
area_gfx_card.End(); // ALWAYS call End after Begin
} }
if (show_scratch_ && scratch_card.Begin(&show_scratch_)) { if (show_scratch_) {
status_ = DrawScratchSpace(); if (scratch_card.Begin(&show_scratch_)) {
scratch_card.End(); status_ = DrawScratchSpace();
}
scratch_card.End(); // ALWAYS call End after Begin
} }
// Tile16 Editor popup-only (no tab) // Tile16 Editor popup-only (no tab)
if (show_tile16_editor_ && tile16_editor_card.Begin(&show_tile16_editor_)) { if (show_tile16_editor_) {
if (rom_->is_loaded()) { if (tile16_editor_card.Begin(&show_tile16_editor_)) {
status_ = tile16_editor_.Update(); if (rom_->is_loaded()) {
} else { status_ = tile16_editor_.Update();
gui::CenterText("No ROM loaded"); } else {
gui::CenterText("No ROM loaded");
}
} }
tile16_editor_card.End(); tile16_editor_card.End(); // ALWAYS call End after Begin
} }
// Graphics Groups popup // Graphics Groups popup
if (show_gfx_groups_ && gfx_groups_card.Begin(&show_gfx_groups_)) { if (show_gfx_groups_) {
if (rom_->is_loaded()) { if (gfx_groups_card.Begin(&show_gfx_groups_)) {
status_ = gfx_group_editor_.Update(); if (rom_->is_loaded()) {
} else { status_ = gfx_group_editor_.Update();
gui::CenterText("No ROM loaded"); } else {
gui::CenterText("No ROM loaded");
}
} }
gfx_groups_card.End(); gfx_groups_card.End(); // ALWAYS call End after Begin
} }
// Usage Statistics popup // Usage Statistics popup
if (show_usage_stats_ && usage_stats_card.Begin(&show_usage_stats_)) { if (show_usage_stats_) {
if (rom_->is_loaded()) { if (usage_stats_card.Begin(&show_usage_stats_)) {
status_ = UpdateUsageStats(); if (rom_->is_loaded()) {
} else { status_ = UpdateUsageStats();
gui::CenterText("No ROM loaded"); } else {
gui::CenterText("No ROM loaded");
}
} }
usage_stats_card.End(); usage_stats_card.End(); // ALWAYS call End after Begin
} }
// Area Configuration Panel (detailed editing) // Area Configuration Panel (detailed editing)
@@ -1254,7 +1268,6 @@ void OverworldEditor::DrawOverworldCanvas() {
gui::BeginNoPadding(); gui::BeginNoPadding();
gui::BeginChildBothScrollbars(7); gui::BeginChildBothScrollbars(7);
ow_map_canvas_.DrawBackground(); ow_map_canvas_.DrawBackground();
gui::EndNoPadding();
// Setup dynamic context menu based on current map state (Phase 3B) // Setup dynamic context menu based on current map state (Phase 3B)
if (rom_->is_loaded() && overworld_.is_loaded() && map_properties_system_) { if (rom_->is_loaded() && overworld_.is_loaded() && map_properties_system_) {
@@ -1314,6 +1327,7 @@ void OverworldEditor::DrawOverworldCanvas() {
ow_map_canvas_.DrawGrid(); ow_map_canvas_.DrawGrid();
ow_map_canvas_.DrawOverlay(); ow_map_canvas_.DrawOverlay();
EndChild(); EndChild();
gui::EndNoPadding(); // End the no-padding style that was started at line 1254
} }
absl::Status OverworldEditor::DrawTile16Selector() { absl::Status OverworldEditor::DrawTile16Selector() {
@@ -1344,7 +1358,13 @@ absl::Status OverworldEditor::DrawTile16Selector() {
if (result.selection_changed) { if (result.selection_changed) {
current_tile16_ = result.selected_tile; current_tile16_ = result.selected_tile;
RETURN_IF_ERROR(tile16_editor_.SetCurrentTile(current_tile16_)); auto status = tile16_editor_.SetCurrentTile(current_tile16_);
if (!status.ok()) {
// Store error but ensure we close the child before returning
EndChild();
ImGui::EndGroup();
return status;
}
// Note: We do NOT auto-scroll here because it breaks user interaction. // Note: We do NOT auto-scroll here because it breaks user interaction.
// The canvas should only scroll when explicitly requested (e.g., when // The canvas should only scroll when explicitly requested (e.g., when
// selecting a tile from the overworld canvas via ScrollBlocksetCanvasToCurrentTile). // selecting a tile from the overworld canvas via ScrollBlocksetCanvasToCurrentTile).

View File

@@ -43,14 +43,18 @@ absl::Status SpriteEditor::Update() {
static gui::EditorCard vanilla_card("Vanilla Sprites", ICON_MD_PEST_CONTROL_RODENT); static gui::EditorCard vanilla_card("Vanilla Sprites", ICON_MD_PEST_CONTROL_RODENT);
static gui::EditorCard custom_card("Custom Sprites", ICON_MD_ADD_MODERATOR); static gui::EditorCard custom_card("Custom Sprites", ICON_MD_ADD_MODERATOR);
if (show_vanilla_editor_ && vanilla_card.Begin(&show_vanilla_editor_)) { if (show_vanilla_editor_) {
DrawVanillaSpriteEditor(); if (vanilla_card.Begin(&show_vanilla_editor_)) {
vanilla_card.End(); DrawVanillaSpriteEditor();
}
vanilla_card.End(); // ALWAYS call End after Begin
} }
if (show_custom_editor_ && custom_card.Begin(&show_custom_editor_)) { if (show_custom_editor_) {
DrawCustomSprites(); if (custom_card.Begin(&show_custom_editor_)) {
custom_card.End(); DrawCustomSprites();
}
custom_card.End(); // ALWAYS call End after Begin
} }
return status_.ok() ? absl::OkStatus() : status_; return status_.ok() ? absl::OkStatus() : status_;