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:
@@ -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);
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -33,7 +33,17 @@ void Arena::QueueTextureCommand(TextureCommandType type, Bitmap* bitmap) {
|
||||
}
|
||||
|
||||
void Arena::ProcessTextureQueue(IRenderer* renderer) {
|
||||
if (!renderer_ || texture_command_queue_.empty()) return;
|
||||
// Use provided renderer if available, otherwise use stored renderer
|
||||
IRenderer* active_renderer = renderer ? renderer : renderer_;
|
||||
|
||||
if (!active_renderer) {
|
||||
// Arena not initialized yet - defer processing
|
||||
return;
|
||||
}
|
||||
|
||||
if (texture_command_queue_.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Performance optimization: Batch process textures with limits
|
||||
// Process up to 8 texture operations per frame to avoid frame drops
|
||||
@@ -45,40 +55,59 @@ void Arena::ProcessTextureQueue(IRenderer* renderer) {
|
||||
const auto& command = *it;
|
||||
bool should_remove = true;
|
||||
|
||||
// CRITICAL: Replicate the exact short-circuit evaluation from working code
|
||||
// We MUST check command.bitmap AND command.bitmap->surface() in one expression
|
||||
// to avoid dereferencing invalid pointers
|
||||
|
||||
switch (command.type) {
|
||||
case TextureCommandType::CREATE: {
|
||||
// Create a new texture and update it with bitmap data
|
||||
if (command.bitmap && command.bitmap->surface() &&
|
||||
command.bitmap->surface()->format &&
|
||||
// Use short-circuit evaluation - if bitmap is invalid, never call ->surface()
|
||||
if (command.bitmap && command.bitmap->surface() &&
|
||||
command.bitmap->surface()->format &&
|
||||
command.bitmap->is_active() &&
|
||||
command.bitmap->width() > 0 && command.bitmap->height() > 0) {
|
||||
auto texture = renderer_->CreateTexture(command.bitmap->width(),
|
||||
command.bitmap->height());
|
||||
if (texture) {
|
||||
command.bitmap->set_texture(texture);
|
||||
renderer_->UpdateTexture(texture, *command.bitmap);
|
||||
processed++;
|
||||
} else {
|
||||
should_remove = false; // Retry next frame
|
||||
|
||||
try {
|
||||
auto texture = active_renderer->CreateTexture(command.bitmap->width(),
|
||||
command.bitmap->height());
|
||||
if (texture) {
|
||||
command.bitmap->set_texture(texture);
|
||||
active_renderer->UpdateTexture(texture, *command.bitmap);
|
||||
processed++;
|
||||
} else {
|
||||
should_remove = false; // Retry next frame
|
||||
}
|
||||
} catch (...) {
|
||||
printf("[Arena] ERROR: Exception during texture creation\n");
|
||||
should_remove = true; // Remove bad command
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TextureCommandType::UPDATE: {
|
||||
// Update existing texture with current bitmap data
|
||||
if (command.bitmap && command.bitmap->texture() &&
|
||||
if (command.bitmap->texture() &&
|
||||
command.bitmap->surface() && command.bitmap->surface()->format &&
|
||||
command.bitmap->is_active()) {
|
||||
renderer_->UpdateTexture(command.bitmap->texture(), *command.bitmap);
|
||||
processed++;
|
||||
try {
|
||||
active_renderer->UpdateTexture(command.bitmap->texture(), *command.bitmap);
|
||||
processed++;
|
||||
} catch (...) {
|
||||
printf("[Arena] ERROR: Exception during texture update\n");
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TextureCommandType::DESTROY: {
|
||||
if (command.bitmap && command.bitmap->texture()) {
|
||||
renderer_->DestroyTexture(command.bitmap->texture());
|
||||
command.bitmap->set_texture(nullptr);
|
||||
processed++;
|
||||
if (command.bitmap->texture()) {
|
||||
try {
|
||||
active_renderer->DestroyTexture(command.bitmap->texture());
|
||||
command.bitmap->set_texture(nullptr);
|
||||
processed++;
|
||||
} catch (...) {
|
||||
printf("[Arena] ERROR: Exception during texture destruction\n");
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -22,6 +22,13 @@ void EditorCardManager::RegisterCard(const CardInfo& info) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if already registered to avoid duplicates
|
||||
if (cards_.find(info.card_id) != cards_.end()) {
|
||||
printf("[EditorCardManager] WARNING: Card '%s' already registered, skipping duplicate\n",
|
||||
info.card_id.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
cards_[info.card_id] = info;
|
||||
printf("[EditorCardManager] Registered card: %s (%s)\n",
|
||||
info.card_id.c_str(), info.display_name.c_str());
|
||||
|
||||
Reference in New Issue
Block a user