refactor(editor): integrate EditorCardRegistry for card management
- Introduced EditorCardRegistry class to centralize card registration and management, enhancing session awareness and visibility control. - Refactored EditorManager to delegate card-related operations to EditorCardRegistry, improving separation of concerns and maintainability. - Updated CMake configuration to include new source files for the EditorCardRegistry component. Benefits: - Streamlines card management within the editor, leading to a more organized and efficient user experience. - Enhances the overall architecture by clearly defining roles for card handling and editor operations.
This commit is contained in:
@@ -2,6 +2,7 @@
|
|||||||
#define YAZE_APP_CORE_EDITOR_H
|
#define YAZE_APP_CORE_EDITOR_H
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <cstddef>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
@@ -16,12 +17,67 @@
|
|||||||
|
|
||||||
namespace yaze {
|
namespace yaze {
|
||||||
|
|
||||||
|
// Forward declarations
|
||||||
|
class Rom;
|
||||||
|
namespace gfx {
|
||||||
|
class Renderer;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @namespace yaze::editor
|
* @namespace yaze::editor
|
||||||
* @brief Editors are the view controllers for the application.
|
* @brief Editors are the view controllers for the application.
|
||||||
*/
|
*/
|
||||||
namespace editor {
|
namespace editor {
|
||||||
|
|
||||||
|
// Forward declarations
|
||||||
|
class EditorCardRegistry;
|
||||||
|
class ToastManager;
|
||||||
|
class UserSettings;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @struct EditorDependencies
|
||||||
|
* @brief Unified dependency container for all editor types
|
||||||
|
*
|
||||||
|
* This struct encapsulates all dependencies that editors might need,
|
||||||
|
* providing a clean interface for dependency injection. It supports
|
||||||
|
* both standard editors and specialized ones (emulator, dungeon) that
|
||||||
|
* need additional dependencies like renderers.
|
||||||
|
*
|
||||||
|
* Design Philosophy:
|
||||||
|
* - Single point of dependency management
|
||||||
|
* - Type-safe for common dependencies
|
||||||
|
* - Extensible via custom_data for editor-specific needs
|
||||||
|
* - Session-aware for multi-session support
|
||||||
|
*
|
||||||
|
* Usage:
|
||||||
|
* ```cpp
|
||||||
|
* EditorDependencies deps;
|
||||||
|
* deps.rom = current_rom;
|
||||||
|
* deps.card_registry = &card_registry_;
|
||||||
|
* deps.session_id = session_index;
|
||||||
|
*
|
||||||
|
* // Standard editor
|
||||||
|
* OverworldEditor editor(deps);
|
||||||
|
*
|
||||||
|
* // Specialized editor with renderer
|
||||||
|
* deps.renderer = renderer_;
|
||||||
|
* DungeonEditor dungeon_editor(deps);
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
struct EditorDependencies {
|
||||||
|
Rom* rom = nullptr;
|
||||||
|
EditorCardRegistry* card_registry = nullptr;
|
||||||
|
ToastManager* toast_manager = nullptr;
|
||||||
|
PopupManager* popup_manager = nullptr;
|
||||||
|
ShortcutManager* shortcut_manager = nullptr;
|
||||||
|
UserSettings* user_settings = nullptr;
|
||||||
|
size_t session_id = 0;
|
||||||
|
|
||||||
|
// Optional dependencies for specialized editors
|
||||||
|
gfx::Renderer* renderer = nullptr; // For emulator, dungeon editor
|
||||||
|
void* custom_data = nullptr; // Type-erased for editor-specific needs
|
||||||
|
};
|
||||||
|
|
||||||
struct EditorContext {
|
struct EditorContext {
|
||||||
CommandManager command_manager;
|
CommandManager command_manager;
|
||||||
ExtensionManager extension_manager;
|
ExtensionManager extension_manager;
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ set(
|
|||||||
app/editor/sprite/sprite_editor.cc
|
app/editor/sprite/sprite_editor.cc
|
||||||
app/editor/system/command_manager.cc
|
app/editor/system/command_manager.cc
|
||||||
app/editor/system/command_palette.cc
|
app/editor/system/command_palette.cc
|
||||||
|
app/editor/system/editor_card_registry.cc
|
||||||
app/editor/system/editor_registry.cc
|
app/editor/system/editor_registry.cc
|
||||||
app/editor/system/extension_manager.cc
|
app/editor/system/extension_manager.cc
|
||||||
app/editor/system/menu_orchestrator.cc
|
app/editor/system/menu_orchestrator.cc
|
||||||
|
|||||||
@@ -137,7 +137,7 @@ EditorManager::EditorManager()
|
|||||||
|
|
||||||
// Initialize MenuOrchestrator after SessionCoordinator is created
|
// Initialize MenuOrchestrator after SessionCoordinator is created
|
||||||
menu_orchestrator_ = std::make_unique<MenuOrchestrator>(
|
menu_orchestrator_ = std::make_unique<MenuOrchestrator>(
|
||||||
menu_builder_, rom_file_manager_, project_manager_, editor_registry_,
|
this, menu_builder_, rom_file_manager_, project_manager_, editor_registry_,
|
||||||
*session_coordinator_, toast_manager_);
|
*session_coordinator_, toast_manager_);
|
||||||
|
|
||||||
// Initialize UICoordinator after all other components are created
|
// Initialize UICoordinator after all other components are created
|
||||||
@@ -215,7 +215,11 @@ void EditorManager::Initialize(gfx::IRenderer* renderer,
|
|||||||
// Register global sidebar toggle shortcut (Ctrl+B)
|
// Register global sidebar toggle shortcut (Ctrl+B)
|
||||||
context_.shortcut_manager.RegisterShortcut(
|
context_.shortcut_manager.RegisterShortcut(
|
||||||
"global.toggle_sidebar", {ImGuiKey_LeftCtrl, ImGuiKey_B},
|
"global.toggle_sidebar", {ImGuiKey_LeftCtrl, ImGuiKey_B},
|
||||||
[this]() { show_card_sidebar_ = !show_card_sidebar_; });
|
[this]() {
|
||||||
|
if (ui_coordinator_) {
|
||||||
|
ui_coordinator_->ToggleCardSidebar();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Register emulator cards early (emulator Initialize might not be called)
|
// Register emulator cards early (emulator Initialize might not be called)
|
||||||
auto& card_manager = gui::EditorCardManager::Get();
|
auto& card_manager = gui::EditorCardManager::Get();
|
||||||
@@ -463,17 +467,17 @@ void EditorManager::Initialize(gfx::IRenderer* renderer,
|
|||||||
|
|
||||||
welcome_screen_.SetNewProjectCallback([this]() {
|
welcome_screen_.SetNewProjectCallback([this]() {
|
||||||
status_ = CreateNewProject();
|
status_ = CreateNewProject();
|
||||||
if (status_.ok()) {
|
if (status_.ok() && ui_coordinator_) {
|
||||||
show_welcome_screen_ = false;
|
ui_coordinator_->SetWelcomeScreenVisible(false);
|
||||||
welcome_screen_manually_closed_ = true;
|
ui_coordinator_->SetWelcomeScreenManuallyClosed(true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
welcome_screen_.SetOpenProjectCallback([this](const std::string& filepath) {
|
welcome_screen_.SetOpenProjectCallback([this](const std::string& filepath) {
|
||||||
status_ = OpenRomOrProject(filepath);
|
status_ = OpenRomOrProject(filepath);
|
||||||
if (status_.ok()) {
|
if (status_.ok() && ui_coordinator_) {
|
||||||
show_welcome_screen_ = false;
|
ui_coordinator_->SetWelcomeScreenVisible(false);
|
||||||
welcome_screen_manually_closed_ = true;
|
ui_coordinator_->SetWelcomeScreenManuallyClosed(true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -542,10 +546,18 @@ void EditorManager::Initialize(gfx::IRenderer* renderer,
|
|||||||
// Command Palette and Global Search
|
// Command Palette and Global Search
|
||||||
context_.shortcut_manager.RegisterShortcut(
|
context_.shortcut_manager.RegisterShortcut(
|
||||||
"Command Palette", {ImGuiKey_P, ImGuiMod_Ctrl, ImGuiMod_Shift},
|
"Command Palette", {ImGuiKey_P, ImGuiMod_Ctrl, ImGuiMod_Shift},
|
||||||
[this]() { show_command_palette_ = true; });
|
[this]() {
|
||||||
|
if (ui_coordinator_) {
|
||||||
|
ui_coordinator_->ShowCommandPalette();
|
||||||
|
}
|
||||||
|
});
|
||||||
context_.shortcut_manager.RegisterShortcut(
|
context_.shortcut_manager.RegisterShortcut(
|
||||||
"Global Search", {ImGuiKey_K, ImGuiMod_Ctrl, ImGuiMod_Shift},
|
"Global Search", {ImGuiKey_K, ImGuiMod_Ctrl, ImGuiMod_Shift},
|
||||||
[this]() { show_global_search_ = true; });
|
[this]() {
|
||||||
|
if (ui_coordinator_) {
|
||||||
|
ui_coordinator_->ShowGlobalSearch();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
context_.shortcut_manager.RegisterShortcut(
|
context_.shortcut_manager.RegisterShortcut(
|
||||||
"Load Last ROM", {ImGuiKey_R, ImGuiMod_Ctrl}, [this]() {
|
"Load Last ROM", {ImGuiKey_R, ImGuiMod_Ctrl}, [this]() {
|
||||||
@@ -594,12 +606,20 @@ void EditorManager::Initialize(gfx::IRenderer* renderer,
|
|||||||
// Editor Selection Dialog shortcut
|
// Editor Selection Dialog shortcut
|
||||||
context_.shortcut_manager.RegisterShortcut(
|
context_.shortcut_manager.RegisterShortcut(
|
||||||
"Editor Selection", {ImGuiKey_E, ImGuiMod_Ctrl},
|
"Editor Selection", {ImGuiKey_E, ImGuiMod_Ctrl},
|
||||||
[this]() { show_editor_selection_ = true; });
|
[this]() {
|
||||||
|
if (ui_coordinator_) {
|
||||||
|
ui_coordinator_->ShowEditorSelection();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Card Browser shortcut
|
// Card Browser shortcut
|
||||||
context_.shortcut_manager.RegisterShortcut(
|
context_.shortcut_manager.RegisterShortcut(
|
||||||
"Card Browser", {ImGuiKey_B, ImGuiMod_Ctrl, ImGuiMod_Shift},
|
"Card Browser", {ImGuiKey_B, ImGuiMod_Ctrl, ImGuiMod_Shift},
|
||||||
[this]() { show_card_browser_ = true; });
|
[this]() {
|
||||||
|
if (ui_coordinator_) {
|
||||||
|
ui_coordinator_->ShowCardBrowser();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// === SIMPLIFIED CARD SHORTCUTS - Use Card Browser instead of individual shortcuts ===
|
// === SIMPLIFIED CARD SHORTCUTS - Use Card Browser instead of individual shortcuts ===
|
||||||
// Individual card shortcuts removed to prevent hash table overflow
|
// Individual card shortcuts removed to prevent hash table overflow
|
||||||
@@ -664,7 +684,11 @@ void EditorManager::Initialize(gfx::IRenderer* renderer,
|
|||||||
[this]() { CloseCurrentSession(); });
|
[this]() { CloseCurrentSession(); });
|
||||||
context_.shortcut_manager.RegisterShortcut(
|
context_.shortcut_manager.RegisterShortcut(
|
||||||
"Session Switcher", std::vector<ImGuiKey>{ImGuiKey_Tab, ImGuiMod_Ctrl},
|
"Session Switcher", std::vector<ImGuiKey>{ImGuiKey_Tab, ImGuiMod_Ctrl},
|
||||||
[this]() { show_session_switcher_ = true; });
|
[this]() {
|
||||||
|
if (ui_coordinator_) {
|
||||||
|
ui_coordinator_->ShowSessionSwitcher();
|
||||||
|
}
|
||||||
|
});
|
||||||
context_.shortcut_manager.RegisterShortcut(
|
context_.shortcut_manager.RegisterShortcut(
|
||||||
"Save Layout",
|
"Save Layout",
|
||||||
std::vector<ImGuiKey>{ImGuiKey_S, ImGuiMod_Ctrl, ImGuiMod_Shift},
|
std::vector<ImGuiKey>{ImGuiKey_S, ImGuiMod_Ctrl, ImGuiMod_Shift},
|
||||||
@@ -759,14 +783,22 @@ absl::Status EditorManager::Update() {
|
|||||||
ExecuteShortcuts(context_.shortcut_manager);
|
ExecuteShortcuts(context_.shortcut_manager);
|
||||||
toast_manager_.Draw();
|
toast_manager_.Draw();
|
||||||
|
|
||||||
// Draw editor selection dialog
|
// Draw editor selection dialog (managed by UICoordinator)
|
||||||
if (show_editor_selection_) {
|
if (ui_coordinator_ && ui_coordinator_->IsEditorSelectionVisible()) {
|
||||||
editor_selection_dialog_.Show(&show_editor_selection_);
|
bool show = true;
|
||||||
|
editor_selection_dialog_.Show(&show);
|
||||||
|
if (!show) {
|
||||||
|
ui_coordinator_->SetEditorSelectionVisible(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw card browser
|
// Draw card browser (managed by UICoordinator)
|
||||||
if (show_card_browser_) {
|
if (ui_coordinator_ && ui_coordinator_->IsCardBrowserVisible()) {
|
||||||
gui::EditorCardManager::Get().DrawCardBrowser(&show_card_browser_);
|
bool show = true;
|
||||||
|
gui::EditorCardManager::Get().DrawCardBrowser(&show);
|
||||||
|
if (!show) {
|
||||||
|
ui_coordinator_->SetCardBrowserVisible(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef YAZE_WITH_GRPC
|
#ifdef YAZE_WITH_GRPC
|
||||||
@@ -830,20 +862,13 @@ absl::Status EditorManager::Update() {
|
|||||||
|
|
||||||
// Check if ROM is loaded before allowing editor updates
|
// Check if ROM is loaded before allowing editor updates
|
||||||
if (!current_editor_set_) {
|
if (!current_editor_set_) {
|
||||||
// Show welcome screen when no session is active, but only if not manually closed
|
// Note: Welcome screen auto-show is now handled by UICoordinator
|
||||||
if (sessions_.empty() && !welcome_screen_manually_closed_) {
|
|
||||||
show_welcome_screen_ = true;
|
|
||||||
}
|
|
||||||
// Don't auto-show here, let the manual control handle it
|
|
||||||
return absl::OkStatus();
|
return absl::OkStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if current ROM is valid
|
// Check if current ROM is valid
|
||||||
if (!current_rom_) {
|
if (!current_rom_) {
|
||||||
// Only show welcome screen for truly empty state, not when ROM is loaded but current_rom_ is null
|
// Note: Welcome screen auto-show is now handled by UICoordinator
|
||||||
if (sessions_.empty() && !welcome_screen_manually_closed_) {
|
|
||||||
show_welcome_screen_ = true;
|
|
||||||
}
|
|
||||||
return absl::OkStatus();
|
return absl::OkStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -934,7 +959,7 @@ absl::Status EditorManager::Update() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (show_performance_dashboard_) {
|
if (ui_coordinator_ && ui_coordinator_->IsPerformanceDashboardVisible()) {
|
||||||
gfx::PerformanceDashboard::Get().Render();
|
gfx::PerformanceDashboard::Get().Render();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -949,7 +974,7 @@ absl::Status EditorManager::Update() {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Draw unified sidebar LAST so it appears on top of all other windows
|
// Draw unified sidebar LAST so it appears on top of all other windows
|
||||||
if (show_card_sidebar_ && current_editor_set_) {
|
if (ui_coordinator_ && ui_coordinator_->IsCardSidebarVisible() && current_editor_set_) {
|
||||||
auto& card_manager = gui::EditorCardManager::Get();
|
auto& card_manager = gui::EditorCardManager::Get();
|
||||||
|
|
||||||
// Collect all active card-based editors
|
// Collect all active card-based editors
|
||||||
@@ -998,7 +1023,9 @@ absl::Status EditorManager::Update() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
auto collapse_callback = [this]() {
|
auto collapse_callback = [this]() {
|
||||||
show_card_sidebar_ = false;
|
if (ui_coordinator_) {
|
||||||
|
ui_coordinator_->SetCardSidebarVisible(false);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
card_manager.DrawSidebar(sidebar_category, active_categories,
|
card_manager.DrawSidebar(sidebar_category, active_categories,
|
||||||
@@ -1143,12 +1170,12 @@ void EditorManager::DrawMenuBar() {
|
|||||||
|
|
||||||
// Project file editor
|
// Project file editor
|
||||||
project_file_editor_.Draw();
|
project_file_editor_.Draw();
|
||||||
if (show_performance_dashboard_) {
|
if (ui_coordinator_ && ui_coordinator_->IsPerformanceDashboardVisible()) {
|
||||||
gfx::PerformanceDashboard::Get().SetVisible(true);
|
gfx::PerformanceDashboard::Get().SetVisible(true);
|
||||||
gfx::PerformanceDashboard::Get().Update();
|
gfx::PerformanceDashboard::Get().Update();
|
||||||
gfx::PerformanceDashboard::Get().Render();
|
gfx::PerformanceDashboard::Get().Render();
|
||||||
if (!gfx::PerformanceDashboard::Get().IsVisible()) {
|
if (!gfx::PerformanceDashboard::Get().IsVisible()) {
|
||||||
show_performance_dashboard_ = false;
|
ui_coordinator_->SetPerformanceDashboardVisible(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1168,9 +1195,9 @@ void EditorManager::DrawMenuBar() {
|
|||||||
// Agent chat history popup (left side)
|
// Agent chat history popup (left side)
|
||||||
agent_chat_history_popup_.Draw();
|
agent_chat_history_popup_.Draw();
|
||||||
|
|
||||||
// Welcome screen (accessible from View menu)
|
// Welcome screen (managed by UICoordinator)
|
||||||
if (show_welcome_screen_) {
|
if (ui_coordinator_) {
|
||||||
DrawWelcomeScreen();
|
ui_coordinator_->DrawWelcomeScreen();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Emulator is now card-based - it creates its own windows
|
// Emulator is now card-based - it creates its own windows
|
||||||
@@ -1178,14 +1205,15 @@ void EditorManager::DrawMenuBar() {
|
|||||||
emulator_.Run(current_rom_);
|
emulator_.Run(current_rom_);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enhanced Command Palette UI with Fuzzy Search
|
// Enhanced Command Palette UI with Fuzzy Search (managed by UICoordinator)
|
||||||
if (show_command_palette_) {
|
if (ui_coordinator_ && ui_coordinator_->IsCommandPaletteVisible()) {
|
||||||
ImGui::SetNextWindowPos(ImGui::GetMainViewport()->GetCenter(),
|
ImGui::SetNextWindowPos(ImGui::GetMainViewport()->GetCenter(),
|
||||||
ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
|
ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
|
||||||
ImGui::SetNextWindowSize(ImVec2(800, 600), ImGuiCond_FirstUseEver);
|
ImGui::SetNextWindowSize(ImVec2(800, 600), ImGuiCond_FirstUseEver);
|
||||||
|
|
||||||
|
bool show_palette = true;
|
||||||
if (Begin(absl::StrFormat("%s Command Palette", ICON_MD_SEARCH).c_str(),
|
if (Begin(absl::StrFormat("%s Command Palette", ICON_MD_SEARCH).c_str(),
|
||||||
&show_command_palette_, ImGuiWindowFlags_NoCollapse)) {
|
&show_palette, ImGuiWindowFlags_NoCollapse)) {
|
||||||
|
|
||||||
// Search input with focus management
|
// Search input with focus management
|
||||||
static char query[256] = {};
|
static char query[256] = {};
|
||||||
@@ -1296,7 +1324,9 @@ void EditorManager::DrawMenuBar() {
|
|||||||
auto it = shortcuts.find(command_name);
|
auto it = shortcuts.find(command_name);
|
||||||
if (it != shortcuts.end() && it->second.callback) {
|
if (it != shortcuts.end() && it->second.callback) {
|
||||||
it->second.callback();
|
it->second.callback();
|
||||||
show_command_palette_ = false;
|
if (ui_coordinator_) {
|
||||||
|
ui_coordinator_->SetCommandPaletteVisible(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ImGui::PopID();
|
ImGui::PopID();
|
||||||
@@ -1335,17 +1365,23 @@ void EditorManager::DrawMenuBar() {
|
|||||||
ImGui::TextDisabled("| ↑↓=Navigate | Enter=Execute | Esc=Close");
|
ImGui::TextDisabled("| ↑↓=Navigate | Enter=Execute | Esc=Close");
|
||||||
}
|
}
|
||||||
End();
|
End();
|
||||||
|
|
||||||
|
// Update visibility state
|
||||||
|
if (!show_palette && ui_coordinator_) {
|
||||||
|
ui_coordinator_->SetCommandPaletteVisible(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enhanced Global Search UI
|
// Enhanced Global Search UI (managed by UICoordinator)
|
||||||
if (show_global_search_) {
|
if (ui_coordinator_ && ui_coordinator_->IsGlobalSearchVisible()) {
|
||||||
ImGui::SetNextWindowPos(ImGui::GetMainViewport()->GetCenter(),
|
ImGui::SetNextWindowPos(ImGui::GetMainViewport()->GetCenter(),
|
||||||
ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
|
ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
|
||||||
ImGui::SetNextWindowSize(ImVec2(800, 600), ImGuiCond_FirstUseEver);
|
ImGui::SetNextWindowSize(ImVec2(800, 600), ImGuiCond_FirstUseEver);
|
||||||
|
|
||||||
|
bool show_search = true;
|
||||||
if (Begin(
|
if (Begin(
|
||||||
absl::StrFormat("%s Global Search", ICON_MD_MANAGE_SEARCH).c_str(),
|
absl::StrFormat("%s Global Search", ICON_MD_MANAGE_SEARCH).c_str(),
|
||||||
&show_global_search_, ImGuiWindowFlags_NoCollapse)) {
|
&show_search, ImGuiWindowFlags_NoCollapse)) {
|
||||||
|
|
||||||
// Enhanced search input with focus management
|
// Enhanced search input with focus management
|
||||||
static char query[256] = {};
|
static char query[256] = {};
|
||||||
@@ -1413,7 +1449,9 @@ void EditorManager::DrawMenuBar() {
|
|||||||
ImGui::PushID(file.c_str());
|
ImGui::PushID(file.c_str());
|
||||||
if (ImGui::Button("Open")) {
|
if (ImGui::Button("Open")) {
|
||||||
status_ = OpenRomOrProject(file);
|
status_ = OpenRomOrProject(file);
|
||||||
show_global_search_ = false;
|
if (ui_coordinator_) {
|
||||||
|
ui_coordinator_->SetGlobalSearchVisible(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ImGui::PopID();
|
ImGui::PopID();
|
||||||
}
|
}
|
||||||
@@ -1498,7 +1536,9 @@ void EditorManager::DrawMenuBar() {
|
|||||||
.c_str())) {
|
.c_str())) {
|
||||||
if (!is_current) {
|
if (!is_current) {
|
||||||
SwitchToSession(i);
|
SwitchToSession(i);
|
||||||
show_global_search_ = false;
|
if (ui_coordinator_) {
|
||||||
|
ui_coordinator_->SetGlobalSearchVisible(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1518,6 +1558,11 @@ void EditorManager::DrawMenuBar() {
|
|||||||
ImGui::Text("%s Global search across all YAZE data", ICON_MD_INFO);
|
ImGui::Text("%s Global search across all YAZE data", ICON_MD_INFO);
|
||||||
}
|
}
|
||||||
End();
|
End();
|
||||||
|
|
||||||
|
// Update visibility state
|
||||||
|
if (!show_search && ui_coordinator_) {
|
||||||
|
ui_coordinator_->SetGlobalSearchVisible(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (show_palette_editor_ && current_editor_set_) {
|
if (show_palette_editor_ && current_editor_set_) {
|
||||||
@@ -1793,11 +1838,11 @@ absl::Status EditorManager::LoadRom() {
|
|||||||
RETURN_IF_ERROR(LoadAssets());
|
RETURN_IF_ERROR(LoadAssets());
|
||||||
|
|
||||||
// Hide welcome screen when ROM is successfully loaded - don't reset manual close state
|
// Hide welcome screen when ROM is successfully loaded - don't reset manual close state
|
||||||
show_welcome_screen_ = false;
|
ui_coordinator_->SetWelcomeScreenVisible(false);
|
||||||
|
|
||||||
// Clear recent editors for fresh start with new ROM and show editor selection dialog
|
// Clear recent editors for fresh start with new ROM and show editor selection dialog
|
||||||
editor_selection_dialog_.ClearRecentEditors();
|
editor_selection_dialog_.ClearRecentEditors();
|
||||||
show_editor_selection_ = true;
|
ui_coordinator_->SetEditorSelectionVisible(true);
|
||||||
|
|
||||||
return absl::OkStatus();
|
return absl::OkStatus();
|
||||||
}
|
}
|
||||||
@@ -1933,9 +1978,9 @@ absl::Status EditorManager::OpenRomOrProject(const std::string& filename) {
|
|||||||
RETURN_IF_ERROR(LoadAssets());
|
RETURN_IF_ERROR(LoadAssets());
|
||||||
|
|
||||||
// Hide welcome screen and show editor selection when ROM is loaded
|
// Hide welcome screen and show editor selection when ROM is loaded
|
||||||
show_welcome_screen_ = false;
|
ui_coordinator_->SetWelcomeScreenVisible(false);
|
||||||
editor_selection_dialog_.ClearRecentEditors();
|
editor_selection_dialog_.ClearRecentEditors();
|
||||||
show_editor_selection_ = true;
|
ui_coordinator_->SetEditorSelectionVisible(true);
|
||||||
}
|
}
|
||||||
return absl::OkStatus();
|
return absl::OkStatus();
|
||||||
}
|
}
|
||||||
@@ -2013,9 +2058,9 @@ absl::Status EditorManager::OpenProject() {
|
|||||||
RETURN_IF_ERROR(LoadAssets());
|
RETURN_IF_ERROR(LoadAssets());
|
||||||
|
|
||||||
// Hide welcome screen and show editor selection when project ROM is loaded
|
// Hide welcome screen and show editor selection when project ROM is loaded
|
||||||
show_welcome_screen_ = false;
|
ui_coordinator_->SetWelcomeScreenVisible(false);
|
||||||
editor_selection_dialog_.ClearRecentEditors();
|
editor_selection_dialog_.ClearRecentEditors();
|
||||||
show_editor_selection_ = true;
|
ui_coordinator_->SetEditorSelectionVisible(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply workspace settings
|
// Apply workspace settings
|
||||||
@@ -2515,9 +2560,9 @@ void EditorManager::LoadUserSettings() {
|
|||||||
ImGui::GetIO().FontGlobalScale = user_settings_.prefs().font_global_scale;
|
ImGui::GetIO().FontGlobalScale = user_settings_.prefs().font_global_scale;
|
||||||
|
|
||||||
// Apply welcome screen preference
|
// Apply welcome screen preference
|
||||||
if (!user_settings_.prefs().show_welcome_on_startup) {
|
if (ui_coordinator_ && !user_settings_.prefs().show_welcome_on_startup) {
|
||||||
show_welcome_screen_ = false;
|
ui_coordinator_->SetWelcomeScreenVisible(false);
|
||||||
welcome_screen_manually_closed_ = true;
|
ui_coordinator_->SetWelcomeScreenManuallyClosed(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -186,8 +186,14 @@ class EditorManager {
|
|||||||
static bool IsCardBasedEditor(EditorType type);
|
static bool IsCardBasedEditor(EditorType type);
|
||||||
static std::string GetEditorCategory(EditorType type);
|
static std::string GetEditorCategory(EditorType type);
|
||||||
static EditorType GetEditorTypeFromCategory(const std::string& category);
|
static EditorType GetEditorTypeFromCategory(const std::string& category);
|
||||||
bool IsSidebarVisible() const { return show_card_sidebar_; }
|
bool IsSidebarVisible() const {
|
||||||
void SetSidebarVisible(bool visible) { show_card_sidebar_ = visible; }
|
return ui_coordinator_ ? ui_coordinator_->IsCardSidebarVisible() : false;
|
||||||
|
}
|
||||||
|
void SetSidebarVisible(bool visible) {
|
||||||
|
if (ui_coordinator_) {
|
||||||
|
ui_coordinator_->SetCardSidebarVisible(visible);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Clean up cards when switching editors
|
// Clean up cards when switching editors
|
||||||
void HideCurrentEditorCards();
|
void HideCurrentEditorCards();
|
||||||
@@ -220,6 +226,19 @@ class EditorManager {
|
|||||||
bool HasDuplicateSession(const std::string& filepath);
|
bool HasDuplicateSession(const std::string& filepath);
|
||||||
void RenameSession(size_t index, const std::string& new_name);
|
void RenameSession(size_t index, const std::string& new_name);
|
||||||
|
|
||||||
|
// ROM and Project operations (public for MenuOrchestrator)
|
||||||
|
absl::Status LoadRom();
|
||||||
|
absl::Status SaveRom();
|
||||||
|
absl::Status SaveRomAs(const std::string& filename);
|
||||||
|
absl::Status OpenRomOrProject(const std::string& filename);
|
||||||
|
absl::Status CreateNewProject(const std::string& template_name = "Basic ROM Hack");
|
||||||
|
absl::Status OpenProject();
|
||||||
|
absl::Status SaveProject();
|
||||||
|
absl::Status SaveProjectAs();
|
||||||
|
absl::Status ImportProject(const std::string& project_path);
|
||||||
|
absl::Status RepairCurrentProject();
|
||||||
|
void ShowProjectHelp();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void DrawWelcomeScreen();
|
void DrawWelcomeScreen();
|
||||||
absl::Status DrawRomSelector();
|
absl::Status DrawRomSelector();
|
||||||
@@ -229,21 +248,7 @@ class EditorManager {
|
|||||||
void DrawLayoutPresets();
|
void DrawLayoutPresets();
|
||||||
void DrawSessionRenameDialog();
|
void DrawSessionRenameDialog();
|
||||||
|
|
||||||
absl::Status LoadRom();
|
|
||||||
absl::Status LoadAssets();
|
absl::Status LoadAssets();
|
||||||
absl::Status SaveRom();
|
|
||||||
absl::Status SaveRomAs(const std::string& filename);
|
|
||||||
absl::Status OpenRomOrProject(const std::string& filename);
|
|
||||||
|
|
||||||
// Project and session management
|
|
||||||
absl::Status CreateNewProject(
|
|
||||||
const std::string& template_name = "Basic ROM Hack");
|
|
||||||
absl::Status OpenProject();
|
|
||||||
absl::Status SaveProject();
|
|
||||||
absl::Status SaveProjectAs();
|
|
||||||
absl::Status ImportProject(const std::string& project_path);
|
|
||||||
absl::Status RepairCurrentProject();
|
|
||||||
void ShowProjectHelp();
|
|
||||||
|
|
||||||
// Testing system
|
// Testing system
|
||||||
void InitializeTestSuites();
|
void InitializeTestSuites();
|
||||||
@@ -258,26 +263,15 @@ class EditorManager {
|
|||||||
bool show_imgui_demo_ = false;
|
bool show_imgui_demo_ = false;
|
||||||
bool show_palette_editor_ = false;
|
bool show_palette_editor_ = false;
|
||||||
bool show_resource_label_manager = false;
|
bool show_resource_label_manager = false;
|
||||||
|
// Workspace dialog flags (managed by EditorManager, not UI)
|
||||||
bool show_workspace_layout = false;
|
bool show_workspace_layout = false;
|
||||||
bool show_save_workspace_preset_ = false;
|
bool show_save_workspace_preset_ = false;
|
||||||
bool show_load_workspace_preset_ = false;
|
bool show_load_workspace_preset_ = false;
|
||||||
bool show_session_switcher_ = false;
|
|
||||||
bool show_session_manager_ = false;
|
|
||||||
bool show_layout_presets_ = false;
|
|
||||||
bool show_homepage_ = true;
|
|
||||||
bool show_command_palette_ = false;
|
|
||||||
bool show_global_search_ = false;
|
|
||||||
bool show_session_rename_dialog_ = false;
|
|
||||||
bool show_welcome_screen_ = false;
|
|
||||||
bool welcome_screen_manually_closed_ = false;
|
|
||||||
bool show_card_browser_ = false;
|
|
||||||
bool show_card_sidebar_ = true; // VSCode-style sidebar for editor cards (toggle with Ctrl+B)
|
|
||||||
size_t session_to_rename_ = 0;
|
size_t session_to_rename_ = 0;
|
||||||
char session_rename_buffer_[256] = {};
|
char session_rename_buffer_[256] = {};
|
||||||
|
|
||||||
// Testing interface
|
// Note: Most UI visibility flags have been moved to UICoordinator
|
||||||
bool show_test_dashboard_ = false;
|
// Access via ui_coordinator_->IsXxxVisible() or SetXxxVisible()
|
||||||
bool show_performance_dashboard_ = false;
|
|
||||||
|
|
||||||
// Agent proposal drawer
|
// Agent proposal drawer
|
||||||
ProposalDrawer proposal_drawer_;
|
ProposalDrawer proposal_drawer_;
|
||||||
@@ -294,11 +288,9 @@ class EditorManager {
|
|||||||
// Project file editor
|
// Project file editor
|
||||||
ProjectFileEditor project_file_editor_;
|
ProjectFileEditor project_file_editor_;
|
||||||
|
|
||||||
// Editor selection dialog
|
// Note: Editor selection dialog and welcome screen are now managed by UICoordinator
|
||||||
|
// Kept here for backward compatibility during transition
|
||||||
EditorSelectionDialog editor_selection_dialog_;
|
EditorSelectionDialog editor_selection_dialog_;
|
||||||
bool show_editor_selection_ = false;
|
|
||||||
|
|
||||||
// Welcome screen
|
|
||||||
WelcomeScreen welcome_screen_;
|
WelcomeScreen welcome_screen_;
|
||||||
|
|
||||||
#ifdef YAZE_WITH_GRPC
|
#ifdef YAZE_WITH_GRPC
|
||||||
|
|||||||
888
src/app/editor/system/editor_card_registry.cc
Normal file
888
src/app/editor/system/editor_card_registry.cc
Normal file
@@ -0,0 +1,888 @@
|
|||||||
|
#include "app/editor/system/editor_card_registry.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <cstdio>
|
||||||
|
|
||||||
|
#include "absl/strings/str_format.h"
|
||||||
|
#include "app/gui/core/icons.h"
|
||||||
|
#include "app/gui/core/theme_manager.h"
|
||||||
|
#include "imgui/imgui.h"
|
||||||
|
|
||||||
|
namespace yaze {
|
||||||
|
namespace editor {
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// Session Lifecycle Management
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
void EditorCardRegistry::RegisterSession(size_t session_id) {
|
||||||
|
if (session_cards_.find(session_id) == session_cards_.end()) {
|
||||||
|
session_cards_[session_id] = std::vector<std::string>();
|
||||||
|
session_card_mapping_[session_id] = std::unordered_map<std::string, std::string>();
|
||||||
|
UpdateSessionCount();
|
||||||
|
printf("[EditorCardRegistry] Registered session %zu (total: %zu)\n",
|
||||||
|
session_id, session_count_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorCardRegistry::UnregisterSession(size_t session_id) {
|
||||||
|
auto it = session_cards_.find(session_id);
|
||||||
|
if (it != session_cards_.end()) {
|
||||||
|
UnregisterSessionCards(session_id);
|
||||||
|
session_cards_.erase(it);
|
||||||
|
session_card_mapping_.erase(session_id);
|
||||||
|
UpdateSessionCount();
|
||||||
|
|
||||||
|
// Reset active session if it was the one being removed
|
||||||
|
if (active_session_ == session_id) {
|
||||||
|
active_session_ = 0;
|
||||||
|
if (!session_cards_.empty()) {
|
||||||
|
active_session_ = session_cards_.begin()->first;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("[EditorCardRegistry] Unregistered session %zu (total: %zu)\n",
|
||||||
|
session_id, session_count_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorCardRegistry::SetActiveSession(size_t session_id) {
|
||||||
|
if (session_cards_.find(session_id) != session_cards_.end()) {
|
||||||
|
active_session_ = session_id;
|
||||||
|
printf("[EditorCardRegistry] Set active session to %zu\n", session_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// Card Registration
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
void EditorCardRegistry::RegisterCard(size_t session_id, const CardInfo& base_info) {
|
||||||
|
RegisterSession(session_id); // Ensure session exists
|
||||||
|
|
||||||
|
std::string prefixed_id = MakeCardId(session_id, base_info.card_id);
|
||||||
|
|
||||||
|
// Check if already registered to avoid duplicates
|
||||||
|
if (cards_.find(prefixed_id) != cards_.end()) {
|
||||||
|
printf("[EditorCardRegistry] WARNING: Card '%s' already registered, skipping duplicate\n",
|
||||||
|
prefixed_id.c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create new CardInfo with prefixed ID
|
||||||
|
CardInfo prefixed_info = base_info;
|
||||||
|
prefixed_info.card_id = prefixed_id;
|
||||||
|
|
||||||
|
// If no visibility_flag provided, create centralized one
|
||||||
|
if (!prefixed_info.visibility_flag) {
|
||||||
|
centralized_visibility_[prefixed_id] = false; // Hidden by default
|
||||||
|
prefixed_info.visibility_flag = ¢ralized_visibility_[prefixed_id];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Register the card
|
||||||
|
cards_[prefixed_id] = prefixed_info;
|
||||||
|
|
||||||
|
// Track in our session mapping
|
||||||
|
session_cards_[session_id].push_back(prefixed_id);
|
||||||
|
session_card_mapping_[session_id][base_info.card_id] = prefixed_id;
|
||||||
|
|
||||||
|
printf("[EditorCardRegistry] Registered card %s -> %s for session %zu\n",
|
||||||
|
base_info.card_id.c_str(), prefixed_id.c_str(), session_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorCardRegistry::RegisterCard(size_t session_id,
|
||||||
|
const std::string& card_id,
|
||||||
|
const std::string& display_name,
|
||||||
|
const std::string& icon,
|
||||||
|
const std::string& category,
|
||||||
|
const std::string& shortcut_hint,
|
||||||
|
int priority,
|
||||||
|
std::function<void()> on_show,
|
||||||
|
std::function<void()> on_hide,
|
||||||
|
bool visible_by_default) {
|
||||||
|
CardInfo info;
|
||||||
|
info.card_id = card_id;
|
||||||
|
info.display_name = display_name;
|
||||||
|
info.icon = icon;
|
||||||
|
info.category = category;
|
||||||
|
info.shortcut_hint = shortcut_hint;
|
||||||
|
info.priority = priority;
|
||||||
|
info.visibility_flag = nullptr; // Will be created in RegisterCard
|
||||||
|
info.on_show = on_show;
|
||||||
|
info.on_hide = on_hide;
|
||||||
|
|
||||||
|
RegisterCard(session_id, info);
|
||||||
|
|
||||||
|
// Set initial visibility if requested
|
||||||
|
if (visible_by_default) {
|
||||||
|
ShowCard(session_id, card_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorCardRegistry::UnregisterCard(size_t session_id, const std::string& base_card_id) {
|
||||||
|
std::string prefixed_id = GetPrefixedCardId(session_id, base_card_id);
|
||||||
|
if (prefixed_id.empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto it = cards_.find(prefixed_id);
|
||||||
|
if (it != cards_.end()) {
|
||||||
|
printf("[EditorCardRegistry] Unregistered card: %s\n", prefixed_id.c_str());
|
||||||
|
cards_.erase(it);
|
||||||
|
centralized_visibility_.erase(prefixed_id);
|
||||||
|
|
||||||
|
// Remove from session tracking
|
||||||
|
auto& session_card_list = session_cards_[session_id];
|
||||||
|
session_card_list.erase(
|
||||||
|
std::remove(session_card_list.begin(), session_card_list.end(), prefixed_id),
|
||||||
|
session_card_list.end());
|
||||||
|
|
||||||
|
session_card_mapping_[session_id].erase(base_card_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorCardRegistry::UnregisterCardsWithPrefix(const std::string& prefix) {
|
||||||
|
std::vector<std::string> to_remove;
|
||||||
|
|
||||||
|
// Find all cards with the given prefix
|
||||||
|
for (const auto& [card_id, card_info] : cards_) {
|
||||||
|
if (card_id.find(prefix) == 0) { // Starts with prefix
|
||||||
|
to_remove.push_back(card_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove them
|
||||||
|
for (const auto& card_id : to_remove) {
|
||||||
|
cards_.erase(card_id);
|
||||||
|
centralized_visibility_.erase(card_id);
|
||||||
|
printf("[EditorCardRegistry] Unregistered card with prefix '%s': %s\n",
|
||||||
|
prefix.c_str(), card_id.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Also clean up session tracking
|
||||||
|
for (auto& [session_id, card_list] : session_cards_) {
|
||||||
|
card_list.erase(
|
||||||
|
std::remove_if(card_list.begin(), card_list.end(),
|
||||||
|
[&prefix](const std::string& id) {
|
||||||
|
return id.find(prefix) == 0;
|
||||||
|
}),
|
||||||
|
card_list.end());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorCardRegistry::ClearAllCards() {
|
||||||
|
cards_.clear();
|
||||||
|
centralized_visibility_.clear();
|
||||||
|
session_cards_.clear();
|
||||||
|
session_card_mapping_.clear();
|
||||||
|
session_count_ = 0;
|
||||||
|
printf("[EditorCardRegistry] Cleared all cards\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// Card Control (Programmatic, No GUI)
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
bool EditorCardRegistry::ShowCard(size_t session_id, const std::string& base_card_id) {
|
||||||
|
std::string prefixed_id = GetPrefixedCardId(session_id, base_card_id);
|
||||||
|
if (prefixed_id.empty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto it = cards_.find(prefixed_id);
|
||||||
|
if (it != cards_.end()) {
|
||||||
|
if (it->second.visibility_flag) {
|
||||||
|
*it->second.visibility_flag = true;
|
||||||
|
}
|
||||||
|
if (it->second.on_show) {
|
||||||
|
it->second.on_show();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EditorCardRegistry::HideCard(size_t session_id, const std::string& base_card_id) {
|
||||||
|
std::string prefixed_id = GetPrefixedCardId(session_id, base_card_id);
|
||||||
|
if (prefixed_id.empty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto it = cards_.find(prefixed_id);
|
||||||
|
if (it != cards_.end()) {
|
||||||
|
if (it->second.visibility_flag) {
|
||||||
|
*it->second.visibility_flag = false;
|
||||||
|
}
|
||||||
|
if (it->second.on_hide) {
|
||||||
|
it->second.on_hide();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EditorCardRegistry::ToggleCard(size_t session_id, const std::string& base_card_id) {
|
||||||
|
std::string prefixed_id = GetPrefixedCardId(session_id, base_card_id);
|
||||||
|
if (prefixed_id.empty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto it = cards_.find(prefixed_id);
|
||||||
|
if (it != cards_.end() && it->second.visibility_flag) {
|
||||||
|
bool new_state = !(*it->second.visibility_flag);
|
||||||
|
*it->second.visibility_flag = new_state;
|
||||||
|
|
||||||
|
if (new_state && it->second.on_show) {
|
||||||
|
it->second.on_show();
|
||||||
|
} else if (!new_state && it->second.on_hide) {
|
||||||
|
it->second.on_hide();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EditorCardRegistry::IsCardVisible(size_t session_id, const std::string& base_card_id) const {
|
||||||
|
std::string prefixed_id = GetPrefixedCardId(session_id, base_card_id);
|
||||||
|
if (prefixed_id.empty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto it = cards_.find(prefixed_id);
|
||||||
|
if (it != cards_.end() && it->second.visibility_flag) {
|
||||||
|
return *it->second.visibility_flag;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool* EditorCardRegistry::GetVisibilityFlag(size_t session_id, const std::string& base_card_id) {
|
||||||
|
std::string prefixed_id = GetPrefixedCardId(session_id, base_card_id);
|
||||||
|
if (prefixed_id.empty()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto it = cards_.find(prefixed_id);
|
||||||
|
if (it != cards_.end()) {
|
||||||
|
return it->second.visibility_flag;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// Batch Operations
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
void EditorCardRegistry::ShowAllCardsInSession(size_t session_id) {
|
||||||
|
auto it = session_cards_.find(session_id);
|
||||||
|
if (it != session_cards_.end()) {
|
||||||
|
for (const auto& prefixed_card_id : it->second) {
|
||||||
|
auto card_it = cards_.find(prefixed_card_id);
|
||||||
|
if (card_it != cards_.end() && card_it->second.visibility_flag) {
|
||||||
|
*card_it->second.visibility_flag = true;
|
||||||
|
if (card_it->second.on_show) {
|
||||||
|
card_it->second.on_show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorCardRegistry::HideAllCardsInSession(size_t session_id) {
|
||||||
|
auto it = session_cards_.find(session_id);
|
||||||
|
if (it != session_cards_.end()) {
|
||||||
|
for (const auto& prefixed_card_id : it->second) {
|
||||||
|
auto card_it = cards_.find(prefixed_card_id);
|
||||||
|
if (card_it != cards_.end() && card_it->second.visibility_flag) {
|
||||||
|
*card_it->second.visibility_flag = false;
|
||||||
|
if (card_it->second.on_hide) {
|
||||||
|
card_it->second.on_hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorCardRegistry::ShowAllCardsInCategory(size_t session_id, const std::string& category) {
|
||||||
|
auto it = session_cards_.find(session_id);
|
||||||
|
if (it != session_cards_.end()) {
|
||||||
|
for (const auto& prefixed_card_id : it->second) {
|
||||||
|
auto card_it = cards_.find(prefixed_card_id);
|
||||||
|
if (card_it != cards_.end() && card_it->second.category == category) {
|
||||||
|
if (card_it->second.visibility_flag) {
|
||||||
|
*card_it->second.visibility_flag = true;
|
||||||
|
}
|
||||||
|
if (card_it->second.on_show) {
|
||||||
|
card_it->second.on_show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorCardRegistry::HideAllCardsInCategory(size_t session_id, const std::string& category) {
|
||||||
|
auto it = session_cards_.find(session_id);
|
||||||
|
if (it != session_cards_.end()) {
|
||||||
|
for (const auto& prefixed_card_id : it->second) {
|
||||||
|
auto card_it = cards_.find(prefixed_card_id);
|
||||||
|
if (card_it != cards_.end() && card_it->second.category == category) {
|
||||||
|
if (card_it->second.visibility_flag) {
|
||||||
|
*card_it->second.visibility_flag = false;
|
||||||
|
}
|
||||||
|
if (card_it->second.on_hide) {
|
||||||
|
card_it->second.on_hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorCardRegistry::ShowOnlyCard(size_t session_id, const std::string& base_card_id) {
|
||||||
|
// First get the category of the target card
|
||||||
|
std::string prefixed_id = GetPrefixedCardId(session_id, base_card_id);
|
||||||
|
if (prefixed_id.empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto target_it = cards_.find(prefixed_id);
|
||||||
|
if (target_it == cards_.end()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string category = target_it->second.category;
|
||||||
|
|
||||||
|
// Hide all cards in the same category
|
||||||
|
HideAllCardsInCategory(session_id, category);
|
||||||
|
|
||||||
|
// Show the target card
|
||||||
|
ShowCard(session_id, base_card_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// Query Methods
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
std::vector<std::string> EditorCardRegistry::GetCardsInSession(size_t session_id) const {
|
||||||
|
auto it = session_cards_.find(session_id);
|
||||||
|
if (it != session_cards_.end()) {
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<CardInfo> EditorCardRegistry::GetCardsInCategory(size_t session_id,
|
||||||
|
const std::string& category) const {
|
||||||
|
std::vector<CardInfo> result;
|
||||||
|
|
||||||
|
auto it = session_cards_.find(session_id);
|
||||||
|
if (it != session_cards_.end()) {
|
||||||
|
for (const auto& prefixed_card_id : it->second) {
|
||||||
|
auto card_it = cards_.find(prefixed_card_id);
|
||||||
|
if (card_it != cards_.end() && card_it->second.category == category) {
|
||||||
|
result.push_back(card_it->second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort by priority
|
||||||
|
std::sort(result.begin(), result.end(),
|
||||||
|
[](const CardInfo& a, const CardInfo& b) {
|
||||||
|
return a.priority < b.priority;
|
||||||
|
});
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> EditorCardRegistry::GetAllCategories(size_t session_id) const {
|
||||||
|
std::vector<std::string> categories;
|
||||||
|
|
||||||
|
auto it = session_cards_.find(session_id);
|
||||||
|
if (it != session_cards_.end()) {
|
||||||
|
for (const auto& prefixed_card_id : it->second) {
|
||||||
|
auto card_it = cards_.find(prefixed_card_id);
|
||||||
|
if (card_it != cards_.end()) {
|
||||||
|
if (std::find(categories.begin(), categories.end(),
|
||||||
|
card_it->second.category) == categories.end()) {
|
||||||
|
categories.push_back(card_it->second.category);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return categories;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CardInfo* EditorCardRegistry::GetCardInfo(size_t session_id,
|
||||||
|
const std::string& base_card_id) const {
|
||||||
|
std::string prefixed_id = GetPrefixedCardId(session_id, base_card_id);
|
||||||
|
if (prefixed_id.empty()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto it = cards_.find(prefixed_id);
|
||||||
|
if (it != cards_.end()) {
|
||||||
|
return &it->second;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> EditorCardRegistry::GetAllCategories() const {
|
||||||
|
std::vector<std::string> categories;
|
||||||
|
for (const auto& [card_id, card_info] : cards_) {
|
||||||
|
if (std::find(categories.begin(), categories.end(),
|
||||||
|
card_info.category) == categories.end()) {
|
||||||
|
categories.push_back(card_info.category);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return categories;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// View Menu Integration
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
void EditorCardRegistry::DrawViewMenuSection(size_t session_id, const std::string& category) {
|
||||||
|
auto cards = GetCardsInCategory(session_id, category);
|
||||||
|
|
||||||
|
if (cards.empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImGui::BeginMenu(category.c_str())) {
|
||||||
|
for (const auto& card : cards) {
|
||||||
|
DrawCardMenuItem(card);
|
||||||
|
}
|
||||||
|
ImGui::EndMenu();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorCardRegistry::DrawViewMenuAll(size_t session_id) {
|
||||||
|
auto categories = GetAllCategories(session_id);
|
||||||
|
|
||||||
|
for (const auto& category : categories) {
|
||||||
|
DrawViewMenuSection(session_id, category);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// VSCode-Style Sidebar
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
void EditorCardRegistry::DrawSidebar(size_t session_id,
|
||||||
|
const std::string& category,
|
||||||
|
const std::vector<std::string>& active_categories,
|
||||||
|
std::function<void(const std::string&)> on_category_switch,
|
||||||
|
std::function<void()> on_collapse) {
|
||||||
|
// Get cards for this session and category
|
||||||
|
auto cards = GetCardsInCategory(session_id, category);
|
||||||
|
|
||||||
|
if (cards.empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sidebar window
|
||||||
|
ImGui::SetNextWindowSize(ImVec2(GetSidebarWidth() + 220, 0), ImGuiCond_Always);
|
||||||
|
ImGui::SetNextWindowPos(ImVec2(0, ImGui::GetFrameHeightWithSpacing()), ImGuiCond_Always);
|
||||||
|
|
||||||
|
ImGui::Begin("##CardSidebar", nullptr,
|
||||||
|
ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize |
|
||||||
|
ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoCollapse);
|
||||||
|
|
||||||
|
// Draw category tabs on the left
|
||||||
|
ImGui::BeginChild("CategoryTabs", ImVec2(GetSidebarWidth(), 0), true);
|
||||||
|
|
||||||
|
for (const auto& cat : active_categories) {
|
||||||
|
bool is_active = (cat == category);
|
||||||
|
if (is_active) {
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_Button, gui::GetPrimaryVec4());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImGui::Button(cat.substr(0, 1).c_str(), ImVec2(GetSidebarWidth() - 8, 40))) {
|
||||||
|
if (on_category_switch) {
|
||||||
|
on_category_switch(cat);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_active) {
|
||||||
|
ImGui::PopStyleColor();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImGui::IsItemHovered()) {
|
||||||
|
ImGui::SetTooltip("%s", cat.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::EndChild();
|
||||||
|
|
||||||
|
ImGui::SameLine();
|
||||||
|
|
||||||
|
// Draw cards on the right
|
||||||
|
ImGui::BeginChild("Cards", ImVec2(0, 0), true);
|
||||||
|
|
||||||
|
ImGui::Text("%s %s", ICON_MD_DASHBOARD, category.c_str());
|
||||||
|
ImGui::Separator();
|
||||||
|
|
||||||
|
for (const auto& card : cards) {
|
||||||
|
DrawCardInSidebar(card, IsCardVisible(session_id, card.card_id));
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::EndChild();
|
||||||
|
|
||||||
|
ImGui::End();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// Compact Controls for Menu Bar
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
void EditorCardRegistry::DrawCompactCardControl(size_t session_id, const std::string& category) {
|
||||||
|
auto cards = GetCardsInCategory(session_id, category);
|
||||||
|
|
||||||
|
if (cards.empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compact dropdown
|
||||||
|
if (ImGui::BeginCombo("##CardControl", absl::StrFormat("%s Cards", ICON_MD_DASHBOARD).c_str())) {
|
||||||
|
for (const auto& card : cards) {
|
||||||
|
bool visible = card.visibility_flag ? *card.visibility_flag : false;
|
||||||
|
if (ImGui::MenuItem(absl::StrFormat("%s %s", card.icon.c_str(),
|
||||||
|
card.display_name.c_str()).c_str(),
|
||||||
|
nullptr, visible)) {
|
||||||
|
ToggleCard(session_id, card.card_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::EndCombo();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorCardRegistry::DrawInlineCardToggles(size_t session_id, const std::string& category) {
|
||||||
|
auto cards = GetCardsInCategory(session_id, category);
|
||||||
|
|
||||||
|
size_t visible_count = 0;
|
||||||
|
for (const auto& card : cards) {
|
||||||
|
if (card.visibility_flag && *card.visibility_flag) {
|
||||||
|
visible_count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::Text("(%zu/%zu)", visible_count, cards.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// Card Browser UI
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
void EditorCardRegistry::DrawCardBrowser(size_t session_id, bool* p_open) {
|
||||||
|
ImGui::SetNextWindowSize(ImVec2(800, 600), ImGuiCond_FirstUseEver);
|
||||||
|
|
||||||
|
if (ImGui::Begin(absl::StrFormat("%s Card Browser", ICON_MD_DASHBOARD).c_str(),
|
||||||
|
p_open)) {
|
||||||
|
|
||||||
|
static char search_filter[256] = "";
|
||||||
|
static std::string category_filter = "All";
|
||||||
|
|
||||||
|
// Search bar
|
||||||
|
ImGui::SetNextItemWidth(300);
|
||||||
|
ImGui::InputTextWithHint("##Search", absl::StrFormat("%s Search cards...",
|
||||||
|
ICON_MD_SEARCH).c_str(),
|
||||||
|
search_filter, sizeof(search_filter));
|
||||||
|
|
||||||
|
ImGui::SameLine();
|
||||||
|
|
||||||
|
// Category filter
|
||||||
|
if (ImGui::BeginCombo("##CategoryFilter", category_filter.c_str())) {
|
||||||
|
if (ImGui::Selectable("All", category_filter == "All")) {
|
||||||
|
category_filter = "All";
|
||||||
|
}
|
||||||
|
|
||||||
|
auto categories = GetAllCategories(session_id);
|
||||||
|
for (const auto& cat : categories) {
|
||||||
|
if (ImGui::Selectable(cat.c_str(), category_filter == cat)) {
|
||||||
|
category_filter = cat;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::EndCombo();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::Separator();
|
||||||
|
|
||||||
|
// Card table
|
||||||
|
if (ImGui::BeginTable("##CardTable", 4,
|
||||||
|
ImGuiTableFlags_ScrollY | ImGuiTableFlags_RowBg |
|
||||||
|
ImGuiTableFlags_Borders)) {
|
||||||
|
|
||||||
|
ImGui::TableSetupColumn("Visible", ImGuiTableColumnFlags_WidthFixed, 60);
|
||||||
|
ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_WidthStretch);
|
||||||
|
ImGui::TableSetupColumn("Category", ImGuiTableColumnFlags_WidthFixed, 120);
|
||||||
|
ImGui::TableSetupColumn("Shortcut", ImGuiTableColumnFlags_WidthFixed, 100);
|
||||||
|
ImGui::TableHeadersRow();
|
||||||
|
|
||||||
|
auto cards = (category_filter == "All")
|
||||||
|
? GetCardsInSession(session_id)
|
||||||
|
: std::vector<std::string>{};
|
||||||
|
|
||||||
|
if (category_filter != "All") {
|
||||||
|
auto cat_cards = GetCardsInCategory(session_id, category_filter);
|
||||||
|
for (const auto& card : cat_cards) {
|
||||||
|
cards.push_back(card.card_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& card_id : cards) {
|
||||||
|
auto card_it = cards_.find(card_id);
|
||||||
|
if (card_it == cards_.end()) continue;
|
||||||
|
|
||||||
|
const auto& card = card_it->second;
|
||||||
|
|
||||||
|
// Apply search filter
|
||||||
|
std::string search_str = search_filter;
|
||||||
|
if (!search_str.empty()) {
|
||||||
|
std::string card_lower = card.display_name;
|
||||||
|
std::transform(card_lower.begin(), card_lower.end(), card_lower.begin(), ::tolower);
|
||||||
|
std::transform(search_str.begin(), search_str.end(), search_str.begin(), ::tolower);
|
||||||
|
if (card_lower.find(search_str) == std::string::npos) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::TableNextRow();
|
||||||
|
|
||||||
|
// Visibility toggle
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
if (card.visibility_flag) {
|
||||||
|
bool visible = *card.visibility_flag;
|
||||||
|
if (ImGui::Checkbox(absl::StrFormat("##vis_%s", card.card_id.c_str()).c_str(),
|
||||||
|
&visible)) {
|
||||||
|
*card.visibility_flag = visible;
|
||||||
|
if (visible && card.on_show) {
|
||||||
|
card.on_show();
|
||||||
|
} else if (!visible && card.on_hide) {
|
||||||
|
card.on_hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Name with icon
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Text("%s %s", card.icon.c_str(), card.display_name.c_str());
|
||||||
|
|
||||||
|
// Category
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Text("%s", card.category.c_str());
|
||||||
|
|
||||||
|
// Shortcut
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::TextDisabled("%s", card.shortcut_hint.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::EndTable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::End();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// Workspace Presets
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
void EditorCardRegistry::SavePreset(const std::string& name, const std::string& description) {
|
||||||
|
WorkspacePreset preset;
|
||||||
|
preset.name = name;
|
||||||
|
preset.description = description;
|
||||||
|
|
||||||
|
// Collect all visible cards across all sessions
|
||||||
|
for (const auto& [card_id, card_info] : cards_) {
|
||||||
|
if (card_info.visibility_flag && *card_info.visibility_flag) {
|
||||||
|
preset.visible_cards.push_back(card_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
presets_[name] = preset;
|
||||||
|
SavePresetsToFile();
|
||||||
|
printf("[EditorCardRegistry] Saved preset: %s (%zu cards)\n",
|
||||||
|
name.c_str(), preset.visible_cards.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EditorCardRegistry::LoadPreset(const std::string& name) {
|
||||||
|
auto it = presets_.find(name);
|
||||||
|
if (it == presets_.end()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// First hide all cards
|
||||||
|
for (auto& [card_id, card_info] : cards_) {
|
||||||
|
if (card_info.visibility_flag) {
|
||||||
|
*card_info.visibility_flag = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Then show preset cards
|
||||||
|
for (const auto& card_id : it->second.visible_cards) {
|
||||||
|
auto card_it = cards_.find(card_id);
|
||||||
|
if (card_it != cards_.end() && card_it->second.visibility_flag) {
|
||||||
|
*card_it->second.visibility_flag = true;
|
||||||
|
if (card_it->second.on_show) {
|
||||||
|
card_it->second.on_show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("[EditorCardRegistry] Loaded preset: %s\n", name.c_str());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorCardRegistry::DeletePreset(const std::string& name) {
|
||||||
|
presets_.erase(name);
|
||||||
|
SavePresetsToFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<EditorCardRegistry::WorkspacePreset> EditorCardRegistry::GetPresets() const {
|
||||||
|
std::vector<WorkspacePreset> result;
|
||||||
|
for (const auto& [name, preset] : presets_) {
|
||||||
|
result.push_back(preset);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// Quick Actions
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
void EditorCardRegistry::ShowAll(size_t session_id) {
|
||||||
|
ShowAllCardsInSession(session_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorCardRegistry::HideAll(size_t session_id) {
|
||||||
|
HideAllCardsInSession(session_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorCardRegistry::ResetToDefaults(size_t session_id) {
|
||||||
|
// Hide all cards first
|
||||||
|
HideAllCardsInSession(session_id);
|
||||||
|
|
||||||
|
// TODO: Load default visibility from config file or hardcoded defaults
|
||||||
|
printf("[EditorCardRegistry] Reset to defaults for session %zu\n", session_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// Statistics
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
size_t EditorCardRegistry::GetVisibleCardCount(size_t session_id) const {
|
||||||
|
size_t count = 0;
|
||||||
|
auto it = session_cards_.find(session_id);
|
||||||
|
if (it != session_cards_.end()) {
|
||||||
|
for (const auto& prefixed_card_id : it->second) {
|
||||||
|
auto card_it = cards_.find(prefixed_card_id);
|
||||||
|
if (card_it != cards_.end() && card_it->second.visibility_flag) {
|
||||||
|
if (*card_it->second.visibility_flag) {
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// Session Prefixing Utilities
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
std::string EditorCardRegistry::MakeCardId(size_t session_id, const std::string& base_id) const {
|
||||||
|
if (ShouldPrefixCards()) {
|
||||||
|
return absl::StrFormat("s%zu.%s", session_id, base_id);
|
||||||
|
}
|
||||||
|
return base_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// Helper Methods (Private)
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
void EditorCardRegistry::UpdateSessionCount() {
|
||||||
|
session_count_ = session_cards_.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string EditorCardRegistry::GetPrefixedCardId(size_t session_id,
|
||||||
|
const std::string& base_id) const {
|
||||||
|
auto session_it = session_card_mapping_.find(session_id);
|
||||||
|
if (session_it != session_card_mapping_.end()) {
|
||||||
|
auto card_it = session_it->second.find(base_id);
|
||||||
|
if (card_it != session_it->second.end()) {
|
||||||
|
return card_it->second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback: try unprefixed ID (for single session or direct access)
|
||||||
|
if (cards_.find(base_id) != cards_.end()) {
|
||||||
|
return base_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ""; // Card not found
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorCardRegistry::UnregisterSessionCards(size_t session_id) {
|
||||||
|
auto it = session_cards_.find(session_id);
|
||||||
|
if (it != session_cards_.end()) {
|
||||||
|
for (const auto& prefixed_card_id : it->second) {
|
||||||
|
cards_.erase(prefixed_card_id);
|
||||||
|
centralized_visibility_.erase(prefixed_card_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorCardRegistry::SavePresetsToFile() {
|
||||||
|
// TODO: Implement file I/O for presets
|
||||||
|
printf("[EditorCardRegistry] SavePresetsToFile() - not yet implemented\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorCardRegistry::LoadPresetsFromFile() {
|
||||||
|
// TODO: Implement file I/O for presets
|
||||||
|
printf("[EditorCardRegistry] LoadPresetsFromFile() - not yet implemented\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorCardRegistry::DrawCardMenuItem(const CardInfo& info) {
|
||||||
|
bool visible = info.visibility_flag ? *info.visibility_flag : false;
|
||||||
|
|
||||||
|
std::string label = absl::StrFormat("%s %s", info.icon.c_str(),
|
||||||
|
info.display_name.c_str());
|
||||||
|
|
||||||
|
const char* shortcut = info.shortcut_hint.empty() ? nullptr : info.shortcut_hint.c_str();
|
||||||
|
|
||||||
|
if (ImGui::MenuItem(label.c_str(), shortcut, visible)) {
|
||||||
|
if (info.visibility_flag) {
|
||||||
|
*info.visibility_flag = !visible;
|
||||||
|
if (*info.visibility_flag && info.on_show) {
|
||||||
|
info.on_show();
|
||||||
|
} else if (!*info.visibility_flag && info.on_hide) {
|
||||||
|
info.on_hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorCardRegistry::DrawCardInSidebar(const CardInfo& info, bool is_active) {
|
||||||
|
if (is_active) {
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_Button, gui::GetPrimaryVec4());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImGui::Button(absl::StrFormat("%s %s", info.icon.c_str(),
|
||||||
|
info.display_name.c_str()).c_str(),
|
||||||
|
ImVec2(-1, 0))) {
|
||||||
|
if (info.visibility_flag) {
|
||||||
|
*info.visibility_flag = !*info.visibility_flag;
|
||||||
|
if (*info.visibility_flag && info.on_show) {
|
||||||
|
info.on_show();
|
||||||
|
} else if (!*info.visibility_flag && info.on_hide) {
|
||||||
|
info.on_hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_active) {
|
||||||
|
ImGui::PopStyleColor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace editor
|
||||||
|
} // namespace yaze
|
||||||
|
|
||||||
406
src/app/editor/system/editor_card_registry.h
Normal file
406
src/app/editor/system/editor_card_registry.h
Normal file
@@ -0,0 +1,406 @@
|
|||||||
|
#ifndef YAZE_APP_EDITOR_SYSTEM_EDITOR_CARD_REGISTRY_H_
|
||||||
|
#define YAZE_APP_EDITOR_SYSTEM_EDITOR_CARD_REGISTRY_H_
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "imgui/imgui.h"
|
||||||
|
|
||||||
|
namespace yaze {
|
||||||
|
namespace editor {
|
||||||
|
|
||||||
|
// Forward declaration
|
||||||
|
class EditorCard;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @struct CardInfo
|
||||||
|
* @brief Metadata for an editor card
|
||||||
|
*
|
||||||
|
* Describes a registerable UI card that can be shown/hidden,
|
||||||
|
* organized by category, and controlled programmatically.
|
||||||
|
*/
|
||||||
|
struct CardInfo {
|
||||||
|
std::string card_id; // Unique identifier (e.g., "dungeon.room_selector")
|
||||||
|
std::string display_name; // Human-readable name (e.g., "Room Selector")
|
||||||
|
std::string icon; // Material icon
|
||||||
|
std::string category; // Category (e.g., "Dungeon", "Graphics", "Palette")
|
||||||
|
std::string shortcut_hint; // Display hint (e.g., "Ctrl+Shift+R")
|
||||||
|
bool* visibility_flag; // Pointer to bool controlling visibility
|
||||||
|
EditorCard* card_instance; // Pointer to actual card (optional)
|
||||||
|
std::function<void()> on_show; // Callback when card is shown
|
||||||
|
std::function<void()> on_hide; // Callback when card is hidden
|
||||||
|
int priority; // Display priority for menus (lower = higher)
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class EditorCardRegistry
|
||||||
|
* @brief Central registry for all editor cards with session awareness and dependency injection
|
||||||
|
*
|
||||||
|
* This class combines the functionality of EditorCardManager (global card management)
|
||||||
|
* and SessionCardRegistry (session-aware prefixing) into a single, dependency-injected
|
||||||
|
* component that can be passed to editors.
|
||||||
|
*
|
||||||
|
* Design Philosophy:
|
||||||
|
* - Dependency injection (no singleton pattern)
|
||||||
|
* - Session-aware card ID prefixing for multi-session support
|
||||||
|
* - Centralized visibility management
|
||||||
|
* - View menu integration
|
||||||
|
* - Workspace preset system
|
||||||
|
* - No direct GUI dependency in registration logic
|
||||||
|
*
|
||||||
|
* Session-Aware Card IDs:
|
||||||
|
* - Single session: "dungeon.room_selector"
|
||||||
|
* - Multiple sessions: "s0.dungeon.room_selector", "s1.dungeon.room_selector"
|
||||||
|
*
|
||||||
|
* Usage:
|
||||||
|
* ```cpp
|
||||||
|
* // In EditorManager:
|
||||||
|
* EditorCardRegistry card_registry;
|
||||||
|
* EditorDependencies deps;
|
||||||
|
* deps.card_registry = &card_registry;
|
||||||
|
*
|
||||||
|
* // In Editor:
|
||||||
|
* deps.card_registry->RegisterCard(deps.session_id, {
|
||||||
|
* .card_id = "dungeon.room_selector",
|
||||||
|
* .display_name = "Room Selector",
|
||||||
|
* .icon = ICON_MD_LIST,
|
||||||
|
* .category = "Dungeon",
|
||||||
|
* .on_show = []() { }
|
||||||
|
* });
|
||||||
|
*
|
||||||
|
* // Programmatic control:
|
||||||
|
* deps.card_registry->ShowCard(deps.session_id, "dungeon.room_selector");
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
class EditorCardRegistry {
|
||||||
|
public:
|
||||||
|
EditorCardRegistry() = default;
|
||||||
|
~EditorCardRegistry() = default;
|
||||||
|
|
||||||
|
// Non-copyable, non-movable (manages pointers and callbacks)
|
||||||
|
EditorCardRegistry(const EditorCardRegistry&) = delete;
|
||||||
|
EditorCardRegistry& operator=(const EditorCardRegistry&) = delete;
|
||||||
|
EditorCardRegistry(EditorCardRegistry&&) = delete;
|
||||||
|
EditorCardRegistry& operator=(EditorCardRegistry&&) = delete;
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// Session Lifecycle Management
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Register a new session in the registry
|
||||||
|
* @param session_id Unique session identifier
|
||||||
|
*
|
||||||
|
* Creates internal tracking structures for the session.
|
||||||
|
* Must be called before registering cards for a session.
|
||||||
|
*/
|
||||||
|
void RegisterSession(size_t session_id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Unregister a session and all its cards
|
||||||
|
* @param session_id Session identifier to remove
|
||||||
|
*
|
||||||
|
* Automatically unregisters all cards associated with the session.
|
||||||
|
*/
|
||||||
|
void UnregisterSession(size_t session_id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the currently active session
|
||||||
|
* @param session_id Session to make active
|
||||||
|
*
|
||||||
|
* Used for determining whether to apply card ID prefixing.
|
||||||
|
*/
|
||||||
|
void SetActiveSession(size_t session_id);
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// Card Registration
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Register a card for a specific session
|
||||||
|
* @param session_id Session this card belongs to
|
||||||
|
* @param base_info Card metadata (ID will be automatically prefixed if needed)
|
||||||
|
*
|
||||||
|
* The card_id in base_info should be the unprefixed ID. This method
|
||||||
|
* automatically applies session prefixing when multiple sessions exist.
|
||||||
|
*/
|
||||||
|
void RegisterCard(size_t session_id, const CardInfo& base_info);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Register a card with inline parameters (convenience method)
|
||||||
|
*/
|
||||||
|
void RegisterCard(size_t session_id,
|
||||||
|
const std::string& card_id,
|
||||||
|
const std::string& display_name,
|
||||||
|
const std::string& icon,
|
||||||
|
const std::string& category,
|
||||||
|
const std::string& shortcut_hint = "",
|
||||||
|
int priority = 50,
|
||||||
|
std::function<void()> on_show = nullptr,
|
||||||
|
std::function<void()> on_hide = nullptr,
|
||||||
|
bool visible_by_default = false);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Unregister a specific card
|
||||||
|
* @param session_id Session the card belongs to
|
||||||
|
* @param base_card_id Unprefixed card ID
|
||||||
|
*/
|
||||||
|
void UnregisterCard(size_t session_id, const std::string& base_card_id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Unregister all cards with a given prefix
|
||||||
|
* @param prefix Prefix to match (e.g., "s0" or "s1.dungeon")
|
||||||
|
*
|
||||||
|
* Useful for cleaning up session cards or category cards.
|
||||||
|
*/
|
||||||
|
void UnregisterCardsWithPrefix(const std::string& prefix);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Remove all registered cards (use with caution)
|
||||||
|
*/
|
||||||
|
void ClearAllCards();
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// Card Control (Programmatic, No GUI)
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Show a card programmatically
|
||||||
|
* @param session_id Session the card belongs to
|
||||||
|
* @param base_card_id Unprefixed card ID
|
||||||
|
* @return true if card was found and shown
|
||||||
|
*/
|
||||||
|
bool ShowCard(size_t session_id, const std::string& base_card_id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Hide a card programmatically
|
||||||
|
*/
|
||||||
|
bool HideCard(size_t session_id, const std::string& base_card_id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Toggle a card's visibility
|
||||||
|
*/
|
||||||
|
bool ToggleCard(size_t session_id, const std::string& base_card_id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check if a card is currently visible
|
||||||
|
*/
|
||||||
|
bool IsCardVisible(size_t session_id, const std::string& base_card_id) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get visibility flag pointer for a card
|
||||||
|
* @return Pointer to bool controlling card visibility (for passing to EditorCard::Begin)
|
||||||
|
*/
|
||||||
|
bool* GetVisibilityFlag(size_t session_id, const std::string& base_card_id);
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// Batch Operations
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Show all cards in a specific session
|
||||||
|
*/
|
||||||
|
void ShowAllCardsInSession(size_t session_id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Hide all cards in a specific session
|
||||||
|
*/
|
||||||
|
void HideAllCardsInSession(size_t session_id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Show all cards in a category for a session
|
||||||
|
*/
|
||||||
|
void ShowAllCardsInCategory(size_t session_id, const std::string& category);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Hide all cards in a category for a session
|
||||||
|
*/
|
||||||
|
void HideAllCardsInCategory(size_t session_id, const std::string& category);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Show only one card, hiding all others in its category
|
||||||
|
*/
|
||||||
|
void ShowOnlyCard(size_t session_id, const std::string& base_card_id);
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// Query Methods
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get all cards registered for a session
|
||||||
|
* @return Vector of prefixed card IDs
|
||||||
|
*/
|
||||||
|
std::vector<std::string> GetCardsInSession(size_t session_id) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get cards in a specific category for a session
|
||||||
|
*/
|
||||||
|
std::vector<CardInfo> GetCardsInCategory(size_t session_id, const std::string& category) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get all categories for a session
|
||||||
|
*/
|
||||||
|
std::vector<std::string> GetAllCategories(size_t session_id) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get card metadata
|
||||||
|
* @param session_id Session the card belongs to
|
||||||
|
* @param base_card_id Unprefixed card ID
|
||||||
|
*/
|
||||||
|
const CardInfo* GetCardInfo(size_t session_id, const std::string& base_card_id) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get all registered categories across all sessions
|
||||||
|
*/
|
||||||
|
std::vector<std::string> GetAllCategories() const;
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// View Menu Integration
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Draw view menu section for a category
|
||||||
|
*/
|
||||||
|
void DrawViewMenuSection(size_t session_id, const std::string& category);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Draw all categories as view menu submenus
|
||||||
|
*/
|
||||||
|
void DrawViewMenuAll(size_t session_id);
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// VSCode-Style Sidebar
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Draw sidebar for a category with session filtering
|
||||||
|
*/
|
||||||
|
void DrawSidebar(size_t session_id,
|
||||||
|
const std::string& category,
|
||||||
|
const std::vector<std::string>& active_categories = {},
|
||||||
|
std::function<void(const std::string&)> on_category_switch = nullptr,
|
||||||
|
std::function<void()> on_collapse = nullptr);
|
||||||
|
|
||||||
|
static constexpr float GetSidebarWidth() { return 48.0f; }
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// Compact Controls for Menu Bar
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Draw compact card control for active editor's cards
|
||||||
|
*/
|
||||||
|
void DrawCompactCardControl(size_t session_id, const std::string& category);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Draw minimal inline card toggles
|
||||||
|
*/
|
||||||
|
void DrawInlineCardToggles(size_t session_id, const std::string& category);
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// Card Browser UI
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Draw visual card browser/toggler
|
||||||
|
*/
|
||||||
|
void DrawCardBrowser(size_t session_id, bool* p_open);
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// Workspace Presets
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
struct WorkspacePreset {
|
||||||
|
std::string name;
|
||||||
|
std::vector<std::string> visible_cards; // Card IDs
|
||||||
|
std::string description;
|
||||||
|
};
|
||||||
|
|
||||||
|
void SavePreset(const std::string& name, const std::string& description = "");
|
||||||
|
bool LoadPreset(const std::string& name);
|
||||||
|
void DeletePreset(const std::string& name);
|
||||||
|
std::vector<WorkspacePreset> GetPresets() const;
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// Quick Actions
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
void ShowAll(size_t session_id);
|
||||||
|
void HideAll(size_t session_id);
|
||||||
|
void ResetToDefaults(size_t session_id);
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// Statistics
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
size_t GetCardCount() const { return cards_.size(); }
|
||||||
|
size_t GetVisibleCardCount(size_t session_id) const;
|
||||||
|
size_t GetSessionCount() const { return session_count_; }
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// Session Prefixing Utilities
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Generate session-aware card ID
|
||||||
|
* @param session_id Session identifier
|
||||||
|
* @param base_id Unprefixed card ID
|
||||||
|
* @return Prefixed ID if multiple sessions, otherwise base ID
|
||||||
|
*
|
||||||
|
* Examples:
|
||||||
|
* - Single session: "dungeon.room_selector" → "dungeon.room_selector"
|
||||||
|
* - Multi-session: "dungeon.room_selector" → "s0.dungeon.room_selector"
|
||||||
|
*/
|
||||||
|
std::string MakeCardId(size_t session_id, const std::string& base_id) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check if card IDs should be prefixed
|
||||||
|
* @return true if session_count > 1
|
||||||
|
*/
|
||||||
|
bool ShouldPrefixCards() const { return session_count_ > 1; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Core card storage (prefixed IDs → CardInfo)
|
||||||
|
std::unordered_map<std::string, CardInfo> cards_;
|
||||||
|
|
||||||
|
// Centralized visibility flags for cards without external flags
|
||||||
|
std::unordered_map<std::string, bool> centralized_visibility_;
|
||||||
|
|
||||||
|
// Session tracking
|
||||||
|
size_t session_count_ = 0;
|
||||||
|
size_t active_session_ = 0;
|
||||||
|
|
||||||
|
// Maps session_id → vector of prefixed card IDs registered for that session
|
||||||
|
std::unordered_map<size_t, std::vector<std::string>> session_cards_;
|
||||||
|
|
||||||
|
// Maps session_id → (base_card_id → prefixed_card_id)
|
||||||
|
std::unordered_map<size_t, std::unordered_map<std::string, std::string>> session_card_mapping_;
|
||||||
|
|
||||||
|
// Workspace presets
|
||||||
|
std::unordered_map<std::string, WorkspacePreset> presets_;
|
||||||
|
|
||||||
|
// Active category tracking
|
||||||
|
std::string active_category_;
|
||||||
|
std::vector<std::string> recent_categories_;
|
||||||
|
static constexpr size_t kMaxRecentCategories = 5;
|
||||||
|
|
||||||
|
// Helper methods
|
||||||
|
void UpdateSessionCount();
|
||||||
|
std::string GetPrefixedCardId(size_t session_id, const std::string& base_id) const;
|
||||||
|
void UnregisterSessionCards(size_t session_id);
|
||||||
|
void SavePresetsToFile();
|
||||||
|
void LoadPresetsFromFile();
|
||||||
|
|
||||||
|
// UI drawing helpers (internal)
|
||||||
|
void DrawCardMenuItem(const CardInfo& info);
|
||||||
|
void DrawCardInSidebar(const CardInfo& info, bool is_active);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace editor
|
||||||
|
} // namespace yaze
|
||||||
|
|
||||||
|
#endif // YAZE_APP_EDITOR_SYSTEM_EDITOR_CARD_REGISTRY_H_
|
||||||
|
|
||||||
@@ -2,25 +2,28 @@
|
|||||||
|
|
||||||
#include "absl/strings/str_format.h"
|
#include "absl/strings/str_format.h"
|
||||||
#include "app/editor/editor.h"
|
#include "app/editor/editor.h"
|
||||||
|
#include "app/editor/editor_manager.h"
|
||||||
#include "app/editor/system/editor_registry.h"
|
#include "app/editor/system/editor_registry.h"
|
||||||
#include "app/editor/system/project_manager.h"
|
#include "app/editor/system/project_manager.h"
|
||||||
#include "app/editor/system/rom_file_manager.h"
|
#include "app/editor/system/rom_file_manager.h"
|
||||||
|
#include "app/editor/system/session_coordinator.h"
|
||||||
#include "app/editor/system/toast_manager.h"
|
#include "app/editor/system/toast_manager.h"
|
||||||
#include "app/editor/ui/menu_builder.h"
|
#include "app/editor/ui/menu_builder.h"
|
||||||
#include "app/editor/system/session_coordinator.h"
|
|
||||||
#include "app/gui/core/icons.h"
|
#include "app/gui/core/icons.h"
|
||||||
|
|
||||||
namespace yaze {
|
namespace yaze {
|
||||||
namespace editor {
|
namespace editor {
|
||||||
|
|
||||||
MenuOrchestrator::MenuOrchestrator(
|
MenuOrchestrator::MenuOrchestrator(
|
||||||
|
EditorManager* editor_manager,
|
||||||
MenuBuilder& menu_builder,
|
MenuBuilder& menu_builder,
|
||||||
RomFileManager& rom_manager,
|
RomFileManager& rom_manager,
|
||||||
ProjectManager& project_manager,
|
ProjectManager& project_manager,
|
||||||
EditorRegistry& editor_registry,
|
EditorRegistry& editor_registry,
|
||||||
SessionCoordinator& session_coordinator,
|
SessionCoordinator& session_coordinator,
|
||||||
ToastManager& toast_manager)
|
ToastManager& toast_manager)
|
||||||
: menu_builder_(menu_builder),
|
: editor_manager_(editor_manager),
|
||||||
|
menu_builder_(menu_builder),
|
||||||
rom_manager_(rom_manager),
|
rom_manager_(rom_manager),
|
||||||
project_manager_(project_manager),
|
project_manager_(project_manager),
|
||||||
editor_registry_(editor_registry),
|
editor_registry_(editor_registry),
|
||||||
@@ -39,6 +42,9 @@ void MenuOrchestrator::BuildMainMenu() {
|
|||||||
BuildWindowMenu();
|
BuildWindowMenu();
|
||||||
BuildHelpMenu();
|
BuildHelpMenu();
|
||||||
|
|
||||||
|
// Draw the constructed menu
|
||||||
|
menu_builder_.Draw();
|
||||||
|
|
||||||
menu_needs_refresh_ = false;
|
menu_needs_refresh_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -312,20 +318,28 @@ void MenuOrchestrator::RefreshMenu() {
|
|||||||
|
|
||||||
// Menu item callbacks - delegate to appropriate managers
|
// Menu item callbacks - delegate to appropriate managers
|
||||||
void MenuOrchestrator::OnOpenRom() {
|
void MenuOrchestrator::OnOpenRom() {
|
||||||
auto status = rom_manager_.LoadRom();
|
// Delegate to EditorManager's LoadRom which handles session management
|
||||||
|
if (editor_manager_) {
|
||||||
|
auto status = editor_manager_->LoadRom();
|
||||||
if (!status.ok()) {
|
if (!status.ok()) {
|
||||||
toast_manager_.Show(
|
toast_manager_.Show(
|
||||||
absl::StrFormat("Failed to load ROM: %s", status.message()),
|
absl::StrFormat("Failed to load ROM: %s", status.message()),
|
||||||
ToastType::kError);
|
ToastType::kError);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MenuOrchestrator::OnSaveRom() {
|
void MenuOrchestrator::OnSaveRom() {
|
||||||
auto status = rom_manager_.SaveRom();
|
// Delegate to EditorManager's SaveRom which handles editor data saving
|
||||||
|
if (editor_manager_) {
|
||||||
|
auto status = editor_manager_->SaveRom();
|
||||||
if (!status.ok()) {
|
if (!status.ok()) {
|
||||||
toast_manager_.Show(
|
toast_manager_.Show(
|
||||||
absl::StrFormat("Failed to save ROM: %s", status.message()),
|
absl::StrFormat("Failed to save ROM: %s", status.message()),
|
||||||
ToastType::kError);
|
ToastType::kError);
|
||||||
|
} else {
|
||||||
|
toast_manager_.Show("ROM saved successfully", ToastType::kSuccess);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -335,58 +349,75 @@ void MenuOrchestrator::OnSaveRomAs() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MenuOrchestrator::OnCreateProject() {
|
void MenuOrchestrator::OnCreateProject() {
|
||||||
auto status = project_manager_.CreateNewProject();
|
// Delegate to EditorManager which handles the full project creation flow
|
||||||
|
if (editor_manager_) {
|
||||||
|
auto status = editor_manager_->CreateNewProject();
|
||||||
if (!status.ok()) {
|
if (!status.ok()) {
|
||||||
toast_manager_.Show(
|
toast_manager_.Show(
|
||||||
absl::StrFormat("Failed to create project: %s", status.message()),
|
absl::StrFormat("Failed to create project: %s", status.message()),
|
||||||
ToastType::kError);
|
ToastType::kError);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MenuOrchestrator::OnOpenProject() {
|
void MenuOrchestrator::OnOpenProject() {
|
||||||
auto status = project_manager_.OpenProject();
|
// Delegate to EditorManager which handles ROM loading and session creation
|
||||||
|
if (editor_manager_) {
|
||||||
|
auto status = editor_manager_->OpenProject();
|
||||||
if (!status.ok()) {
|
if (!status.ok()) {
|
||||||
toast_manager_.Show(
|
toast_manager_.Show(
|
||||||
absl::StrFormat("Failed to open project: %s", status.message()),
|
absl::StrFormat("Failed to open project: %s", status.message()),
|
||||||
ToastType::kError);
|
ToastType::kError);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MenuOrchestrator::OnSaveProject() {
|
void MenuOrchestrator::OnSaveProject() {
|
||||||
auto status = project_manager_.SaveProject();
|
// Delegate to EditorManager which updates project with current state
|
||||||
|
if (editor_manager_) {
|
||||||
|
auto status = editor_manager_->SaveProject();
|
||||||
if (!status.ok()) {
|
if (!status.ok()) {
|
||||||
toast_manager_.Show(
|
toast_manager_.Show(
|
||||||
absl::StrFormat("Failed to save project: %s", status.message()),
|
absl::StrFormat("Failed to save project: %s", status.message()),
|
||||||
ToastType::kError);
|
ToastType::kError);
|
||||||
|
} else {
|
||||||
|
toast_manager_.Show("Project saved successfully", ToastType::kSuccess);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MenuOrchestrator::OnSaveProjectAs() {
|
void MenuOrchestrator::OnSaveProjectAs() {
|
||||||
auto status = project_manager_.SaveProjectAs();
|
// Delegate to EditorManager
|
||||||
|
if (editor_manager_) {
|
||||||
|
auto status = editor_manager_->SaveProjectAs();
|
||||||
if (!status.ok()) {
|
if (!status.ok()) {
|
||||||
toast_manager_.Show(
|
toast_manager_.Show(
|
||||||
absl::StrFormat("Failed to save project as: %s", status.message()),
|
absl::StrFormat("Failed to save project as: %s", status.message()),
|
||||||
ToastType::kError);
|
ToastType::kError);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Editor-specific menu actions
|
// Editor-specific menu actions
|
||||||
void MenuOrchestrator::OnSwitchToEditor(EditorType editor_type) {
|
void MenuOrchestrator::OnSwitchToEditor(EditorType editor_type) {
|
||||||
editor_registry_.SwitchToEditor(editor_type);
|
// Delegate to EditorManager which manages editor switching
|
||||||
toast_manager_.Show(
|
if (editor_manager_) {
|
||||||
absl::StrFormat("Switched to %s",
|
editor_manager_->SwitchToEditor(editor_type);
|
||||||
editor_registry_.GetEditorDisplayName(editor_type)),
|
}
|
||||||
ToastType::kInfo);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MenuOrchestrator::OnShowEditorSelection() {
|
void MenuOrchestrator::OnShowEditorSelection() {
|
||||||
// TODO: Show editor selection dialog
|
// Delegate to EditorManager
|
||||||
toast_manager_.Show("Editor Selection", ToastType::kInfo);
|
if (editor_manager_) {
|
||||||
|
editor_manager_->ShowEditorSelection();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MenuOrchestrator::OnShowDisplaySettings() {
|
void MenuOrchestrator::OnShowDisplaySettings() {
|
||||||
// TODO: Show display settings dialog
|
// Delegate to EditorManager
|
||||||
toast_manager_.Show("Display Settings", ToastType::kInfo);
|
if (editor_manager_) {
|
||||||
|
editor_manager_->ShowDisplaySettings();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Session management menu actions
|
// Session management menu actions
|
||||||
@@ -408,28 +439,38 @@ void MenuOrchestrator::OnSwitchToSession(size_t session_index) {
|
|||||||
|
|
||||||
// Window management menu actions
|
// Window management menu actions
|
||||||
void MenuOrchestrator::OnShowAllWindows() {
|
void MenuOrchestrator::OnShowAllWindows() {
|
||||||
// TODO: Delegate to WindowDelegate
|
// Delegate to EditorManager
|
||||||
toast_manager_.Show("Show All Windows", ToastType::kInfo);
|
if (editor_manager_) {
|
||||||
|
editor_manager_->ShowAllWindows();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MenuOrchestrator::OnHideAllWindows() {
|
void MenuOrchestrator::OnHideAllWindows() {
|
||||||
// TODO: Delegate to WindowDelegate
|
// Delegate to EditorManager
|
||||||
toast_manager_.Show("Hide All Windows", ToastType::kInfo);
|
if (editor_manager_) {
|
||||||
|
editor_manager_->HideAllWindows();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MenuOrchestrator::OnResetWorkspaceLayout() {
|
void MenuOrchestrator::OnResetWorkspaceLayout() {
|
||||||
// TODO: Delegate to WindowDelegate
|
// Delegate to EditorManager
|
||||||
toast_manager_.Show("Reset Workspace Layout", ToastType::kInfo);
|
if (editor_manager_) {
|
||||||
|
editor_manager_->ResetWorkspaceLayout();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MenuOrchestrator::OnSaveWorkspaceLayout() {
|
void MenuOrchestrator::OnSaveWorkspaceLayout() {
|
||||||
// TODO: Delegate to WindowDelegate
|
// Delegate to EditorManager
|
||||||
toast_manager_.Show("Save Workspace Layout", ToastType::kInfo);
|
if (editor_manager_) {
|
||||||
|
editor_manager_->SaveWorkspaceLayout();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MenuOrchestrator::OnLoadWorkspaceLayout() {
|
void MenuOrchestrator::OnLoadWorkspaceLayout() {
|
||||||
// TODO: Delegate to WindowDelegate
|
// Delegate to EditorManager
|
||||||
toast_manager_.Show("Load Workspace Layout", ToastType::kInfo);
|
if (editor_manager_) {
|
||||||
|
editor_manager_->LoadWorkspaceLayout();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tool menu actions
|
// Tool menu actions
|
||||||
|
|||||||
@@ -38,7 +38,8 @@ class ToastManager;
|
|||||||
class MenuOrchestrator {
|
class MenuOrchestrator {
|
||||||
public:
|
public:
|
||||||
// Constructor takes references to the managers it coordinates with
|
// Constructor takes references to the managers it coordinates with
|
||||||
MenuOrchestrator(MenuBuilder& menu_builder,
|
MenuOrchestrator(EditorManager* editor_manager,
|
||||||
|
MenuBuilder& menu_builder,
|
||||||
RomFileManager& rom_manager,
|
RomFileManager& rom_manager,
|
||||||
ProjectManager& project_manager,
|
ProjectManager& project_manager,
|
||||||
EditorRegistry& editor_registry,
|
EditorRegistry& editor_registry,
|
||||||
@@ -103,6 +104,7 @@ class MenuOrchestrator {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
// References to coordinated managers
|
// References to coordinated managers
|
||||||
|
EditorManager* editor_manager_;
|
||||||
MenuBuilder& menu_builder_;
|
MenuBuilder& menu_builder_;
|
||||||
RomFileManager& rom_manager_;
|
RomFileManager& rom_manager_;
|
||||||
ProjectManager& project_manager_;
|
ProjectManager& project_manager_;
|
||||||
|
|||||||
@@ -41,8 +41,54 @@ UICoordinator::UICoordinator(
|
|||||||
toast_manager_(toast_manager),
|
toast_manager_(toast_manager),
|
||||||
popup_manager_(popup_manager) {
|
popup_manager_(popup_manager) {
|
||||||
|
|
||||||
// Initialize welcome screen
|
// Initialize welcome screen with proper callbacks
|
||||||
welcome_screen_ = std::make_unique<WelcomeScreen>();
|
welcome_screen_ = std::make_unique<WelcomeScreen>();
|
||||||
|
|
||||||
|
// Wire welcome screen callbacks to EditorManager
|
||||||
|
welcome_screen_->SetOpenRomCallback([this]() {
|
||||||
|
if (editor_manager_) {
|
||||||
|
auto status = editor_manager_->LoadRom();
|
||||||
|
if (!status.ok()) {
|
||||||
|
toast_manager_.Show(
|
||||||
|
absl::StrFormat("Failed to load ROM: %s", status.message()),
|
||||||
|
ToastType::kError);
|
||||||
|
} else {
|
||||||
|
// Hide welcome screen on successful ROM load
|
||||||
|
show_welcome_screen_ = false;
|
||||||
|
welcome_screen_manually_closed_ = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
welcome_screen_->SetNewProjectCallback([this]() {
|
||||||
|
if (editor_manager_) {
|
||||||
|
auto status = editor_manager_->CreateNewProject();
|
||||||
|
if (!status.ok()) {
|
||||||
|
toast_manager_.Show(
|
||||||
|
absl::StrFormat("Failed to create project: %s", status.message()),
|
||||||
|
ToastType::kError);
|
||||||
|
} else {
|
||||||
|
// Hide welcome screen on successful project creation
|
||||||
|
show_welcome_screen_ = false;
|
||||||
|
welcome_screen_manually_closed_ = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
welcome_screen_->SetOpenProjectCallback([this](const std::string& filepath) {
|
||||||
|
if (editor_manager_) {
|
||||||
|
auto status = editor_manager_->OpenRomOrProject(filepath);
|
||||||
|
if (!status.ok()) {
|
||||||
|
toast_manager_.Show(
|
||||||
|
absl::StrFormat("Failed to open project: %s", status.message()),
|
||||||
|
ToastType::kError);
|
||||||
|
} else {
|
||||||
|
// Hide welcome screen on successful project open
|
||||||
|
show_welcome_screen_ = false;
|
||||||
|
welcome_screen_manually_closed_ = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void UICoordinator::DrawAllUI() {
|
void UICoordinator::DrawAllUI() {
|
||||||
@@ -217,10 +263,28 @@ void UICoordinator::DrawLayoutPresets() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void UICoordinator::DrawWelcomeScreen() {
|
void UICoordinator::DrawWelcomeScreen() {
|
||||||
|
// Auto-show welcome screen when no ROM is loaded (unless manually closed)
|
||||||
|
if (!show_welcome_screen_ && !welcome_screen_manually_closed_) {
|
||||||
|
// Check with EditorManager if we should show welcome screen
|
||||||
|
if (editor_manager_ && editor_manager_->GetActiveSessionCount() == 0) {
|
||||||
|
show_welcome_screen_ = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!show_welcome_screen_) return;
|
if (!show_welcome_screen_) return;
|
||||||
|
|
||||||
if (welcome_screen_) {
|
if (welcome_screen_) {
|
||||||
|
// Update recent projects before showing
|
||||||
|
welcome_screen_->RefreshRecentProjects();
|
||||||
|
|
||||||
|
bool was_open = show_welcome_screen_;
|
||||||
welcome_screen_->Show(&show_welcome_screen_);
|
welcome_screen_->Show(&show_welcome_screen_);
|
||||||
|
|
||||||
|
// Check if the welcome screen was manually closed via the close button
|
||||||
|
if (was_open && !show_welcome_screen_) {
|
||||||
|
welcome_screen_manually_closed_ = true;
|
||||||
|
welcome_screen_->MarkManuallyClosed();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -247,19 +311,11 @@ void UICoordinator::HidePopup(const std::string& popup_name) {
|
|||||||
popup_manager_.Hide(popup_name.c_str());
|
popup_manager_.Hide(popup_name.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void UICoordinator::ShowEditorSelection() {
|
|
||||||
show_editor_selection_ = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void UICoordinator::ShowDisplaySettings() {
|
void UICoordinator::ShowDisplaySettings() {
|
||||||
show_display_settings_ = true;
|
show_display_settings_ = true;
|
||||||
ShowPopup("Display Settings");
|
ShowPopup("Display Settings");
|
||||||
}
|
}
|
||||||
|
|
||||||
void UICoordinator::ShowSessionSwitcher() {
|
|
||||||
show_session_switcher_ = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void UICoordinator::HideCurrentEditorCards() {
|
void UICoordinator::HideCurrentEditorCards() {
|
||||||
// TODO: Implement card hiding logic
|
// TODO: Implement card hiding logic
|
||||||
// This would hide cards for the current editor
|
// This would hide cards for the current editor
|
||||||
|
|||||||
@@ -78,26 +78,44 @@ class UICoordinator {
|
|||||||
void HidePopup(const std::string& popup_name);
|
void HidePopup(const std::string& popup_name);
|
||||||
|
|
||||||
// UI state management
|
// UI state management
|
||||||
void ShowEditorSelection();
|
void ShowEditorSelection() { show_editor_selection_ = true; }
|
||||||
void ShowDisplaySettings();
|
void ShowDisplaySettings();
|
||||||
void ShowSessionSwitcher();
|
void ShowSessionSwitcher() { show_session_switcher_ = true; }
|
||||||
void HideCurrentEditorCards();
|
void HideCurrentEditorCards();
|
||||||
|
void ToggleCardSidebar() { show_card_sidebar_ = !show_card_sidebar_; }
|
||||||
|
void ShowGlobalSearch() { show_global_search_ = true; }
|
||||||
|
void ShowCommandPalette() { show_command_palette_ = true; }
|
||||||
|
void ShowCardBrowser() { show_card_browser_ = true; }
|
||||||
|
|
||||||
// Window visibility management
|
// Window visibility management
|
||||||
void ShowAllWindows();
|
void ShowAllWindows();
|
||||||
void HideAllWindows();
|
void HideAllWindows();
|
||||||
|
|
||||||
// UI state queries
|
// UI state queries (EditorManager can check these)
|
||||||
bool IsEditorSelectionVisible() const { return show_editor_selection_; }
|
bool IsEditorSelectionVisible() const { return show_editor_selection_; }
|
||||||
bool IsDisplaySettingsVisible() const { return show_display_settings_; }
|
bool IsDisplaySettingsVisible() const { return show_display_settings_; }
|
||||||
bool IsSessionSwitcherVisible() const { return show_session_switcher_; }
|
bool IsSessionSwitcherVisible() const { return show_session_switcher_; }
|
||||||
bool IsWelcomeScreenVisible() const { return show_welcome_screen_; }
|
bool IsWelcomeScreenVisible() const { return show_welcome_screen_; }
|
||||||
|
bool IsWelcomeScreenManuallyClosed() const { return welcome_screen_manually_closed_; }
|
||||||
|
bool IsGlobalSearchVisible() const { return show_global_search_; }
|
||||||
|
bool IsPerformanceDashboardVisible() const { return show_performance_dashboard_; }
|
||||||
|
bool IsCardBrowserVisible() const { return show_card_browser_; }
|
||||||
|
bool IsCommandPaletteVisible() const { return show_command_palette_; }
|
||||||
|
bool IsCardSidebarVisible() const { return show_card_sidebar_; }
|
||||||
|
|
||||||
// UI state setters
|
// UI state setters (for programmatic control)
|
||||||
void SetEditorSelectionVisible(bool visible) { show_editor_selection_ = visible; }
|
void SetEditorSelectionVisible(bool visible) { show_editor_selection_ = visible; }
|
||||||
void SetDisplaySettingsVisible(bool visible) { show_display_settings_ = visible; }
|
void SetDisplaySettingsVisible(bool visible) { show_display_settings_ = visible; }
|
||||||
void SetSessionSwitcherVisible(bool visible) { show_session_switcher_ = visible; }
|
void SetSessionSwitcherVisible(bool visible) { show_session_switcher_ = visible; }
|
||||||
void SetWelcomeScreenVisible(bool visible) { show_welcome_screen_ = visible; }
|
void SetWelcomeScreenVisible(bool visible) { show_welcome_screen_ = visible; }
|
||||||
|
void SetWelcomeScreenManuallyClosed(bool closed) { welcome_screen_manually_closed_ = closed; }
|
||||||
|
void SetGlobalSearchVisible(bool visible) { show_global_search_ = visible; }
|
||||||
|
void SetPerformanceDashboardVisible(bool visible) { show_performance_dashboard_ = visible; }
|
||||||
|
void SetCardBrowserVisible(bool visible) { show_card_browser_ = visible; }
|
||||||
|
void SetCommandPaletteVisible(bool visible) { show_command_palette_ = visible; }
|
||||||
|
void SetCardSidebarVisible(bool visible) { show_card_sidebar_ = visible; }
|
||||||
|
void SetImGuiDemoVisible(bool visible) { show_imgui_demo_ = visible; }
|
||||||
|
void SetImGuiMetricsVisible(bool visible) { show_imgui_metrics_ = visible; }
|
||||||
|
|
||||||
// Theme and styling helpers
|
// Theme and styling helpers
|
||||||
void ApplyMaterialDesignStyling();
|
void ApplyMaterialDesignStyling();
|
||||||
@@ -115,16 +133,25 @@ class UICoordinator {
|
|||||||
ToastManager& toast_manager_;
|
ToastManager& toast_manager_;
|
||||||
PopupManager& popup_manager_;
|
PopupManager& popup_manager_;
|
||||||
|
|
||||||
// UI state flags
|
// UI state flags (UICoordinator owns all UI visibility state)
|
||||||
bool show_editor_selection_ = false;
|
bool show_editor_selection_ = false;
|
||||||
bool show_display_settings_ = false;
|
bool show_display_settings_ = false;
|
||||||
bool show_session_switcher_ = false;
|
bool show_session_switcher_ = false;
|
||||||
bool show_welcome_screen_ = true;
|
bool show_welcome_screen_ = true;
|
||||||
|
bool welcome_screen_manually_closed_ = false;
|
||||||
bool show_global_search_ = false;
|
bool show_global_search_ = false;
|
||||||
bool show_performance_dashboard_ = false;
|
bool show_performance_dashboard_ = false;
|
||||||
bool show_imgui_demo_ = false;
|
bool show_imgui_demo_ = false;
|
||||||
bool show_imgui_metrics_ = false;
|
bool show_imgui_metrics_ = false;
|
||||||
bool show_test_dashboard_ = false;
|
bool show_test_dashboard_ = false;
|
||||||
|
bool show_card_browser_ = false;
|
||||||
|
bool show_command_palette_ = false;
|
||||||
|
bool show_emulator_ = false;
|
||||||
|
bool show_memory_editor_ = false;
|
||||||
|
bool show_asm_editor_ = false;
|
||||||
|
bool show_palette_editor_ = false;
|
||||||
|
bool show_resource_label_manager_ = false;
|
||||||
|
bool show_card_sidebar_ = false;
|
||||||
|
|
||||||
// Welcome screen component
|
// Welcome screen component
|
||||||
std::unique_ptr<WelcomeScreen> welcome_screen_;
|
std::unique_ptr<WelcomeScreen> welcome_screen_;
|
||||||
|
|||||||
Reference in New Issue
Block a user