feat: Enhance editor card management and shortcut functionality

- Introduced new shortcut categories for graphics, screen, and sprite editors, improving accessibility and organization.
- Updated DungeonEditorV2 and other editor classes to register cards with the EditorCardManager, allowing for better control and visibility management.
- Refactored shortcut registration for dungeon, graphics, screen, and sprite editors, ensuring consistent user experience across the application.
- Improved initialization processes to handle dynamic card visibility and shortcuts effectively.
This commit is contained in:
scawful
2025-10-09 09:46:29 -04:00
parent 9465195956
commit 219406901d
15 changed files with 315 additions and 86 deletions

View File

@@ -176,7 +176,18 @@ void AssemblyEditor::Initialize() {
text_editor_.SetLanguageDefinition(GetAssemblyLanguageDef());
}
absl::Status AssemblyEditor::Load() { return absl::OkStatus(); }
absl::Status AssemblyEditor::Load() {
// Register cards with EditorCardManager
// Note: Assembly editor uses dynamic file tabs, so we register the main editor window
auto& card_manager = gui::EditorCardManager::Get();
// The assembly editor itself acts as a card when shown
// Individual files are tabs within it, not separate cards
printf("[AssemblyEditor] Assembly editor uses dynamic file tabs\n");
return absl::OkStatus();
}
void AssemblyEditor::OpenFolder(const std::string& folder_path) {
current_folder_ = LoadFolder(folder_path);

View File

@@ -6,6 +6,7 @@
#include "app/editor/editor.h"
#include "app/gui/modules/text_editor.h"
#include "app/gui/editor_layout.h"
#include "app/gui/editor_card_manager.h"
#include "app/gui/style.h"
#include "app/rom.h"

View File

@@ -157,7 +157,9 @@ void DungeonCanvasViewer::DrawDungeonCanvas(int room_id) {
// Process queued texture commands
if (rom_ && rom_->is_loaded()) {
gfx::Arena::Get().ProcessTextureQueue(nullptr); // Will use default renderer
// Process texture queue using Arena's stored renderer
// The renderer was initialized in EditorManager::LoadAssets()
gfx::Arena::Get().ProcessTextureQueue(nullptr);
}
// Draw layer information overlay

View File

@@ -881,8 +881,11 @@ absl::Status DungeonEditor::UpdateRoomBackgroundLayers(int /*room_id*/) {
void DungeonEditor::ProcessDeferredTextures() {
// Process queued texture commands via Arena's deferred system
// Note: Arena will use its stored renderer reference
// Note: Arena uses its stored renderer reference (initialized in EditorManager)
// The parameter is ignored, but we pass nullptr to indicate we're using the stored renderer
gfx::Arena::Get().ProcessTextureQueue(nullptr);
// NOTE: This is deprecated - use DungeonEditorV2 instead
}
} // namespace yaze::editor

View File

@@ -24,55 +24,8 @@ void DungeonEditorV2::Initialize(gfx::IRenderer* renderer, Rom* rom) {
// Setup docking class for room windows
room_window_class_.ClassId = ImGui::GetID("DungeonRoomClass");
room_window_class_.DockingAllowUnclassed = false; // Room windows dock together
}
void DungeonEditorV2::Initialize() {}
absl::Status DungeonEditorV2::Load() {
if (!rom_ || !rom_->is_loaded()) {
return absl::FailedPreconditionError("ROM not loaded");
}
// Load all rooms using the loader component - DEFERRED for lazy loading
// RETURN_IF_ERROR(room_loader_.LoadAllRooms(rooms_));
RETURN_IF_ERROR(room_loader_.LoadRoomEntrances(entrances_));
// Load palette group
auto dungeon_main_pal_group = rom_->palette_group().dungeon_main;
current_palette_ = dungeon_main_pal_group[current_palette_group_id_];
ASSIGN_OR_RETURN(current_palette_group_,
gfx::CreatePaletteGroupFromLargePalette(current_palette_));
// Initialize components with loaded data
room_selector_.set_rooms(&rooms_);
room_selector_.set_entrances(&entrances_);
room_selector_.set_active_rooms(active_rooms_);
room_selector_.set_room_selected_callback(
[this](int room_id) { OnRoomSelected(room_id); });
canvas_viewer_.SetRooms(&rooms_);
canvas_viewer_.SetCurrentPaletteGroup(current_palette_group_);
canvas_viewer_.SetCurrentPaletteId(current_palette_id_);
object_selector_.SetCurrentPaletteGroup(current_palette_group_);
object_selector_.SetCurrentPaletteId(current_palette_id_);
object_selector_.set_rooms(&rooms_);
// NOW initialize emulator preview with loaded ROM
object_emulator_preview_.Initialize(renderer_, rom_);
// Initialize palette editor with loaded ROM
palette_editor_.Initialize(rom_);
// Initialize unified object editor card
object_editor_card_ = std::make_unique<ObjectEditorCard>(renderer_, rom_, &canvas_viewer_);
// Initialize manual renderer for debugging (uses canvas from canvas_viewer_)
manual_renderer_ = std::make_unique<ManualObjectRenderer>(
&canvas_viewer_.canvas(), rom_);
printf("[DungeonEditorV2] Manual renderer initialized for debugging\n");
// Register all cards with the card manager for unified control
// Register all cards with the card manager (done once during initialization)
auto& card_manager = gui::EditorCardManager::Get();
card_manager.RegisterCard({
@@ -146,6 +99,53 @@ absl::Status DungeonEditorV2::Load() {
});
printf("[DungeonEditorV2] Registered 7 cards with EditorCardManager\n");
}
void DungeonEditorV2::Initialize() {}
absl::Status DungeonEditorV2::Load() {
if (!rom_ || !rom_->is_loaded()) {
return absl::FailedPreconditionError("ROM not loaded");
}
// Load all rooms using the loader component - DEFERRED for lazy loading
// RETURN_IF_ERROR(room_loader_.LoadAllRooms(rooms_));
RETURN_IF_ERROR(room_loader_.LoadRoomEntrances(entrances_));
// Load palette group
auto dungeon_main_pal_group = rom_->palette_group().dungeon_main;
current_palette_ = dungeon_main_pal_group[current_palette_group_id_];
ASSIGN_OR_RETURN(current_palette_group_,
gfx::CreatePaletteGroupFromLargePalette(current_palette_));
// Initialize components with loaded data
room_selector_.set_rooms(&rooms_);
room_selector_.set_entrances(&entrances_);
room_selector_.set_active_rooms(active_rooms_);
room_selector_.set_room_selected_callback(
[this](int room_id) { OnRoomSelected(room_id); });
canvas_viewer_.SetRooms(&rooms_);
canvas_viewer_.SetCurrentPaletteGroup(current_palette_group_);
canvas_viewer_.SetCurrentPaletteId(current_palette_id_);
object_selector_.SetCurrentPaletteGroup(current_palette_group_);
object_selector_.SetCurrentPaletteId(current_palette_id_);
object_selector_.set_rooms(&rooms_);
// NOW initialize emulator preview with loaded ROM
object_emulator_preview_.Initialize(renderer_, rom_);
// Initialize palette editor with loaded ROM
palette_editor_.Initialize(rom_);
// Initialize unified object editor card
object_editor_card_ = std::make_unique<ObjectEditorCard>(renderer_, rom_, &canvas_viewer_);
// Initialize manual renderer for debugging (uses canvas from canvas_viewer_)
manual_renderer_ = std::make_unique<ManualObjectRenderer>(
&canvas_viewer_.canvas(), rom_);
printf("[DungeonEditorV2] Manual renderer initialized for debugging\n");
// Wire palette changes to trigger room re-renders
palette_editor_.SetOnPaletteChanged([this](int /*palette_id*/) {
@@ -267,12 +267,16 @@ void DungeonEditorV2::DrawToolset() {
void DungeonEditorV2::DrawControlPanel() {
// Small, collapsible control panel for dungeon editor
ImGui::SetNextWindowSize(ImVec2(250, 200), ImGuiCond_FirstUseEver);
ImGui::SetNextWindowSize(ImVec2(280, 280), ImGuiCond_FirstUseEver);
ImGui::SetNextWindowPos(ImVec2(10, 100), ImGuiCond_FirstUseEver);
ImGuiWindowFlags flags = ImGuiWindowFlags_None;
if (ImGui::Begin(ICON_MD_CASTLE " Dungeon Controls", &show_control_panel_, flags)) {
ImGui::TextWrapped("Welcome to Dungeon Editor V2!");
ImGui::TextDisabled("Use checkboxes below to open cards");
ImGui::Separator();
DrawToolset();
ImGui::Separator();

View File

@@ -120,14 +120,16 @@ class DungeonEditorV2 : public Editor {
std::unordered_map<int, std::shared_ptr<gui::EditorCard>> room_cards_;
int current_room_id_ = 0;
// Card visibility flags
bool show_room_selector_ = true;
// Card visibility flags - Start with only control panel visible
// Other cards hidden by default to prevent crash on ROM load
// User can open them via View menu or shortcuts
bool show_room_selector_ = false;
bool show_room_matrix_ = false;
bool show_entrances_list_ = false;
bool show_room_graphics_ = false; // Room graphics card
bool show_object_editor_ = true; // Unified object editor card
bool show_palette_editor_ = true;
bool show_control_panel_ = true; // Optional control panel
bool show_room_graphics_ = false;
bool show_object_editor_ = false;
bool show_palette_editor_ = false;
bool show_control_panel_ = true; // Only control panel visible on start
bool control_panel_minimized_ = false;
// Palette management

View File

@@ -616,7 +616,7 @@ void EditorManager::Initialize(gfx::IRenderer* renderer, const std::string& file
"Card Browser", {ImGuiKey_B, ImGuiMod_Ctrl, ImGuiMod_Shift},
[this]() { show_card_browser_ = true; });
// Dungeon Card shortcuts
// === DUNGEON CARD SHORTCUTS (Ctrl+Shift+Key) ===
context_.shortcut_manager.RegisterShortcut(
"Toggle Dungeon Controls", {ImGuiKey_D, ImGuiMod_Ctrl, ImGuiMod_Shift},
[]() { gui::EditorCardManager::Get().ToggleCard("dungeon.control_panel"); });
@@ -638,6 +638,45 @@ void EditorManager::Initialize(gfx::IRenderer* renderer, const std::string& file
context_.shortcut_manager.RegisterShortcut(
"Toggle Dungeon Palette", {ImGuiKey_P, ImGuiMod_Ctrl, ImGuiMod_Shift},
[]() { gui::EditorCardManager::Get().ToggleCard("dungeon.palette_editor"); });
// === GRAPHICS CARD SHORTCUTS (Ctrl+Shift+Number) ===
context_.shortcut_manager.RegisterShortcut(
"Toggle Sheet Editor", {ImGuiKey_1, ImGuiMod_Ctrl, ImGuiMod_Shift},
[]() { gui::EditorCardManager::Get().ToggleCard("graphics.sheet_editor"); });
context_.shortcut_manager.RegisterShortcut(
"Toggle Sheet Browser", {ImGuiKey_2, ImGuiMod_Ctrl, ImGuiMod_Shift},
[]() { gui::EditorCardManager::Get().ToggleCard("graphics.sheet_browser"); });
context_.shortcut_manager.RegisterShortcut(
"Toggle Player Animations", {ImGuiKey_3, ImGuiMod_Ctrl, ImGuiMod_Shift},
[]() { gui::EditorCardManager::Get().ToggleCard("graphics.player_animations"); });
context_.shortcut_manager.RegisterShortcut(
"Toggle Prototype Viewer", {ImGuiKey_4, ImGuiMod_Ctrl, ImGuiMod_Shift},
[]() { gui::EditorCardManager::Get().ToggleCard("graphics.prototype_viewer"); });
// === SCREEN EDITOR SHORTCUTS (Alt+Number) ===
context_.shortcut_manager.RegisterShortcut(
"Toggle Dungeon Maps", {ImGuiKey_1, ImGuiMod_Alt},
[]() { gui::EditorCardManager::Get().ToggleCard("screen.dungeon_maps"); });
context_.shortcut_manager.RegisterShortcut(
"Toggle Inventory Menu", {ImGuiKey_2, ImGuiMod_Alt},
[]() { gui::EditorCardManager::Get().ToggleCard("screen.inventory_menu"); });
context_.shortcut_manager.RegisterShortcut(
"Toggle Overworld Map Screen", {ImGuiKey_3, ImGuiMod_Alt},
[]() { gui::EditorCardManager::Get().ToggleCard("screen.overworld_map"); });
context_.shortcut_manager.RegisterShortcut(
"Toggle Title Screen", {ImGuiKey_4, ImGuiMod_Alt},
[]() { gui::EditorCardManager::Get().ToggleCard("screen.title_screen"); });
context_.shortcut_manager.RegisterShortcut(
"Toggle Naming Screen", {ImGuiKey_5, ImGuiMod_Alt},
[]() { gui::EditorCardManager::Get().ToggleCard("screen.naming_screen"); });
// === SPRITE EDITOR SHORTCUTS (Alt+Shift+Number) ===
context_.shortcut_manager.RegisterShortcut(
"Toggle Vanilla Sprites", {ImGuiKey_1, ImGuiMod_Alt, ImGuiMod_Shift},
[]() { gui::EditorCardManager::Get().ToggleCard("sprite.vanilla_editor"); });
context_.shortcut_manager.RegisterShortcut(
"Toggle Custom Sprites", {ImGuiKey_2, ImGuiMod_Alt, ImGuiMod_Shift},
[]() { gui::EditorCardManager::Get().ToggleCard("sprite.custom_editor"); });
#ifdef YAZE_WITH_GRPC
// Agent Editor shortcut

View File

@@ -41,7 +41,52 @@ constexpr ImGuiTableFlags kGfxEditTableFlags =
ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable |
ImGuiTableFlags_SizingFixedFit;
void GraphicsEditor::Initialize() {}
void GraphicsEditor::Initialize() {
// Register cards with EditorCardManager during initialization (once)
auto& card_manager = gui::EditorCardManager::Get();
card_manager.RegisterCard({
.card_id = "graphics.sheet_editor",
.display_name = "Sheet Editor",
.icon = ICON_MD_EDIT,
.category = "Graphics",
.shortcut_hint = "Ctrl+Shift+1",
.visibility_flag = &show_sheet_editor_,
.priority = 10
});
card_manager.RegisterCard({
.card_id = "graphics.sheet_browser",
.display_name = "Sheet Browser",
.icon = ICON_MD_VIEW_LIST,
.category = "Graphics",
.shortcut_hint = "Ctrl+Shift+2",
.visibility_flag = &show_sheet_browser_,
.priority = 20
});
card_manager.RegisterCard({
.card_id = "graphics.player_animations",
.display_name = "Player Animations",
.icon = ICON_MD_PERSON,
.category = "Graphics",
.shortcut_hint = "Ctrl+Shift+3",
.visibility_flag = &show_player_animations_,
.priority = 30
});
card_manager.RegisterCard({
.card_id = "graphics.prototype_viewer",
.display_name = "Prototype Viewer",
.icon = ICON_MD_CONSTRUCTION,
.category = "Graphics",
.shortcut_hint = "Ctrl+Shift+4",
.visibility_flag = &show_prototype_viewer_,
.priority = 40
});
printf("[GraphicsEditor] Registered 4 cards with EditorCardManager\n");
}
absl::Status GraphicsEditor::Load() {
gfx::ScopedTimer timer("GraphicsEditor::Load");

View File

@@ -7,6 +7,7 @@
#include "app/editor/editor.h"
#include "app/editor/graphics/palette_editor.h"
#include "app/gfx/bitmap.h"
#include "app/gui/editor_card_manager.h"
#include "app/gfx/snes_tile.h"
#include "app/gui/canvas.h"
#include "app/gui/editor_layout.h"
@@ -116,8 +117,9 @@ class GraphicsEditor : public Editor {
absl::Status DecompressSuperDonkey();
// Member Variables
// Card visibility
bool show_sheet_editor_ = true;
// Card visibility - ALL FALSE by default to prevent crash on ROM load
// Cards only shown when user explicitly opens them via View menu or shortcuts
bool show_sheet_editor_ = false;
bool show_sheet_browser_ = false;
bool show_player_animations_ = false;
bool show_prototype_viewer_ = false;

View File

@@ -29,7 +29,62 @@ namespace editor {
constexpr uint32_t kRedPen = 0xFF0000FF;
void ScreenEditor::Initialize() {}
void ScreenEditor::Initialize() {
// Register cards with EditorCardManager during initialization (once)
auto& card_manager = gui::EditorCardManager::Get();
card_manager.RegisterCard({
.card_id = "screen.dungeon_maps",
.display_name = "Dungeon Maps",
.icon = ICON_MD_MAP,
.category = "Screen",
.shortcut_hint = "Alt+1",
.visibility_flag = &show_dungeon_maps_,
.priority = 10
});
card_manager.RegisterCard({
.card_id = "screen.inventory_menu",
.display_name = "Inventory Menu",
.icon = ICON_MD_INVENTORY,
.category = "Screen",
.shortcut_hint = "Alt+2",
.visibility_flag = &show_inventory_menu_,
.priority = 20
});
card_manager.RegisterCard({
.card_id = "screen.overworld_map",
.display_name = "Overworld Map",
.icon = ICON_MD_PUBLIC,
.category = "Screen",
.shortcut_hint = "Alt+3",
.visibility_flag = &show_overworld_map_,
.priority = 30
});
card_manager.RegisterCard({
.card_id = "screen.title_screen",
.display_name = "Title Screen",
.icon = ICON_MD_TITLE,
.category = "Screen",
.shortcut_hint = "Alt+4",
.visibility_flag = &show_title_screen_,
.priority = 40
});
card_manager.RegisterCard({
.card_id = "screen.naming_screen",
.display_name = "Naming Screen",
.icon = ICON_MD_EDIT,
.category = "Screen",
.shortcut_hint = "Alt+5",
.visibility_flag = &show_naming_screen_,
.priority = 50
});
printf("[ScreenEditor] Registered 5 cards with EditorCardManager\n");
}
absl::Status ScreenEditor::Load() {
gfx::ScopedTimer timer("ScreenEditor::Load");

View File

@@ -7,6 +7,7 @@
#include "app/editor/editor.h"
#include "app/gfx/bitmap.h"
#include "app/gfx/snes_palette.h"
#include "app/gui/editor_card_manager.h"
#include "app/gfx/tilemap.h"
#include "app/gui/canvas.h"
#include "app/rom.h"
@@ -77,8 +78,9 @@ class ScreenEditor : public Editor {
EditingMode current_mode_ = EditingMode::DRAW;
// Card visibility
bool show_dungeon_maps_ = true;
// Card visibility - ALL FALSE by default to prevent crash on ROM load
// Cards only shown when user explicitly opens them via View menu or shortcuts
bool show_dungeon_maps_ = false;
bool show_inventory_menu_ = false;
bool show_overworld_map_ = false;
bool show_title_screen_ = false;

View File

@@ -24,7 +24,32 @@ using ImGui::TableNextRow;
using ImGui::TableSetupColumn;
using ImGui::Text;
void SpriteEditor::Initialize() {}
void SpriteEditor::Initialize() {
// Register cards with EditorCardManager during initialization (once)
auto& card_manager = gui::EditorCardManager::Get();
card_manager.RegisterCard({
.card_id = "sprite.vanilla_editor",
.display_name = "Vanilla Sprites",
.icon = ICON_MD_SMART_TOY,
.category = "Sprite",
.shortcut_hint = "Alt+Shift+1",
.visibility_flag = &show_vanilla_editor_,
.priority = 10
});
card_manager.RegisterCard({
.card_id = "sprite.custom_editor",
.display_name = "Custom Sprites",
.icon = ICON_MD_ADD_CIRCLE,
.category = "Sprite",
.shortcut_hint = "Alt+Shift+2",
.visibility_flag = &show_custom_editor_,
.priority = 20
});
printf("[SpriteEditor] Registered 2 cards with EditorCardManager\n");
}
absl::Status SpriteEditor::Load() {
gfx::ScopedTimer timer("SpriteEditor::Load");

View File

@@ -8,6 +8,7 @@
#include "app/editor/editor.h"
#include "app/editor/sprite/zsprite.h"
#include "app/gui/canvas.h"
#include "app/gui/editor_card_manager.h"
#include "app/gui/editor_layout.h"
#include "app/rom.h"
@@ -83,8 +84,9 @@ class SpriteEditor : public Editor {
void DrawAnimationFrames();
void DrawToolset();
// Card visibility
bool show_vanilla_editor_ = true;
// Card visibility - ALL FALSE by default to prevent crash on ROM load
// Cards only shown when user explicitly opens them via View menu or shortcuts
bool show_vanilla_editor_ = false;
bool show_custom_editor_ = false;
ImVector<int> active_sprites_; /**< Active sprites. */