Files
yaze/src/app/editor/editor_manager.h
scawful 2f84879ca9 refactor(editor): introduce MenuOrchestrator for menu management
- Added MenuOrchestrator class to handle menu construction and coordination, improving separation of concerns within the editor.
- Refactored EditorManager to delegate menu-related tasks to MenuOrchestrator, enhancing maintainability and clarity.
- Updated CMake configuration to include new source files for the MenuOrchestrator component.

Benefits:
- Streamlines menu management, leading to a more organized and efficient user experience.
- Enhances the overall architecture by clearly defining roles for menu handling and editor operations.
2025-10-14 22:26:34 -04:00

385 lines
12 KiB
C++

#ifndef YAZE_APP_EDITOR_EDITOR_MANAGER_H
#define YAZE_APP_EDITOR_EDITOR_MANAGER_H
#define IMGUI_DEFINE_MATH_OPERATORS
#include "app/editor/system/user_settings.h"
#include "app/editor/ui/workspace_manager.h"
#include "imgui/imgui.h"
#include <deque>
#include <vector>
#include "absl/status/status.h"
#include "app/core/features.h"
#include "app/core/project.h"
#include "app/editor/code/assembly_editor.h"
#include "app/editor/code/memory_editor.h"
#include "app/editor/ui/menu_builder.h"
#include "app/editor/code/project_file_editor.h"
#include "app/editor/dungeon/dungeon_editor_v2.h"
#include "app/editor/graphics/graphics_editor.h"
#include "app/editor/palette/palette_editor.h"
#include "app/editor/graphics/screen_editor.h"
#include "app/editor/message/message_editor.h"
#include "app/editor/music/music_editor.h"
#include "app/editor/overworld/overworld_editor.h"
#include "app/editor/sprite/sprite_editor.h"
#include "app/editor/system/popup_manager.h"
#include "app/editor/system/proposal_drawer.h"
#include "app/editor/agent/agent_chat_history_popup.h"
#ifdef YAZE_WITH_GRPC
#include "app/editor/agent/agent_editor.h"
#include "app/editor/agent/automation_bridge.h"
#endif
#include "app/editor/system/settings_editor.h"
#include "app/editor/system/toast_manager.h"
#include "app/rom.h"
#include "app/editor/system/editor_registry.h"
#include "app/editor/system/menu_orchestrator.h"
#include "app/editor/system/project_manager.h"
#include "app/editor/system/rom_file_manager.h"
#include "app/editor/system/session_card_registry.h"
#include "app/editor/system/window_delegate.h"
#include "app/editor/ui/session_coordinator.h"
#include "app/editor/ui/editor_selection_dialog.h"
#include "app/editor/ui/welcome_screen.h"
#include "app/emu/emulator.h"
#include "app/gfx/debug/performance/performance_dashboard.h"
#include "yaze_config.h"
#ifdef YAZE_WITH_GRPC
// Forward declarations for gRPC-dependent types
namespace yaze::agent {
class AgentControlServer;
}
#endif
namespace yaze {
namespace editor {
/**
* @class EditorSet
* @brief Contains a complete set of editors for a single ROM instance
*/
class EditorSet {
public:
explicit EditorSet(Rom* rom = nullptr, UserSettings* user_settings = nullptr, size_t session_id = 0)
: session_id_(session_id),
assembly_editor_(rom),
dungeon_editor_(rom),
graphics_editor_(rom),
music_editor_(rom),
overworld_editor_(rom),
palette_editor_(rom),
screen_editor_(rom),
sprite_editor_(rom),
settings_editor_(rom, user_settings),
message_editor_(rom),
memory_editor_(rom) {
active_editors_ = {&overworld_editor_, &dungeon_editor_, &graphics_editor_,
&palette_editor_, &sprite_editor_, &message_editor_,
&music_editor_, &screen_editor_, &settings_editor_,
&assembly_editor_};
}
void set_user_settings(UserSettings* settings) {
settings_editor_.set_user_settings(settings);
}
size_t session_id() const { return session_id_; }
AssemblyEditor assembly_editor_;
DungeonEditorV2 dungeon_editor_;
GraphicsEditor graphics_editor_;
MusicEditor music_editor_;
OverworldEditor overworld_editor_;
PaletteEditor palette_editor_;
ScreenEditor screen_editor_;
SpriteEditor sprite_editor_;
SettingsEditor settings_editor_;
MessageEditor message_editor_;
MemoryEditorWithDiffChecker memory_editor_;
std::vector<Editor*> active_editors_;
private:
size_t session_id_ = 0;
};
/**
* @class EditorManager
* @brief The EditorManager controls the main editor window and manages the
* various editor classes.
*
* The EditorManager class contains instances of various editor classes such as
* AssemblyEditor, DungeonEditor, GraphicsEditor, MusicEditor, OverworldEditor,
* PaletteEditor, ScreenEditor, and SpriteEditor. The current_editor_ member
* variable points to the currently active editor in the tab view.
*
*/
class EditorManager {
public:
// Constructor and destructor must be defined in .cc file for std::unique_ptr with forward-declared types
EditorManager();
~EditorManager();
void Initialize(gfx::IRenderer* renderer, const std::string& filename = "");
// Processes startup flags to open a specific editor and cards.
void OpenEditorAndCardsFromFlags(const std::string& editor_name,
const std::string& cards_str);
absl::Status Update();
void DrawMenuBar();
auto emulator() -> emu::Emulator& { return emulator_; }
auto quit() const { return quit_; }
auto version() const { return version_; }
void DrawMenuBarExtras();
MenuBuilder& menu_builder() { return menu_builder_; }
void ShowSessionSwitcher();
void ShowEditorSelection();
void ShowDisplaySettings();
absl::Status SetCurrentRom(Rom* rom);
auto GetCurrentRom() -> Rom* { return current_rom_; }
auto GetCurrentEditorSet() -> EditorSet* { return current_editor_set_; }
auto overworld() -> yaze::zelda3::Overworld* { return &current_editor_set_->overworld_editor_.overworld(); }
// Session management helpers
size_t GetCurrentSessionIndex() const;
// Get current session's feature flags (falls back to global if no session)
core::FeatureFlags::Flags* GetCurrentFeatureFlags() {
size_t current_index = GetCurrentSessionIndex();
if (current_index < sessions_.size()) {
return &sessions_[current_index].feature_flags;
}
return &core::FeatureFlags::get(); // Fallback to global
}
void SetFontGlobalScale(float scale) {
user_settings_.prefs().font_global_scale = scale;
ImGui::GetIO().FontGlobalScale = scale;
SaveUserSettings();
}
void BuildModernMenu();
// User settings helpers
void LoadUserSettings();
void SaveUserSettings();
// Workspace management (delegates to WorkspaceManager)
void RefreshWorkspacePresets() { workspace_manager_.RefreshPresets(); }
void SaveWorkspacePreset(const std::string& name) { workspace_manager_.SaveWorkspacePreset(name); }
void LoadWorkspacePreset(const std::string& name) { workspace_manager_.LoadWorkspacePreset(name); }
// Jump-to functionality for cross-editor navigation
void JumpToDungeonRoom(int room_id);
void JumpToOverworldMap(int map_id);
void SwitchToEditor(EditorType editor_type);
// Card-based editor registry
static bool IsCardBasedEditor(EditorType type);
static std::string GetEditorCategory(EditorType type);
static EditorType GetEditorTypeFromCategory(const std::string& category);
bool IsSidebarVisible() const { return show_card_sidebar_; }
void SetSidebarVisible(bool visible) { show_card_sidebar_ = visible; }
// Clean up cards when switching editors
void HideCurrentEditorCards();
// Session management
void CreateNewSession();
void DuplicateCurrentSession();
void CloseCurrentSession();
void RemoveSession(size_t index);
void SwitchToSession(size_t index);
size_t GetActiveSessionCount() const;
// Workspace layout management
void SaveWorkspaceLayout();
void LoadWorkspaceLayout();
void ResetWorkspaceLayout();
void ShowAllWindows();
void HideAllWindows();
void MaximizeCurrentWindow();
void RestoreAllWindows();
void CloseAllFloatingWindows();
// Layout presets
void LoadDeveloperLayout();
void LoadDesignerLayout();
void LoadModderLayout();
// Helper methods
std::string GenerateUniqueEditorTitle(EditorType type, size_t session_index) const;
bool HasDuplicateSession(const std::string& filepath);
void RenameSession(size_t index, const std::string& new_name);
private:
void DrawWelcomeScreen();
absl::Status DrawRomSelector();
void DrawContextSensitiveCardControl(); // Card control for current editor
void DrawSessionSwitcher();
void DrawSessionManager();
void DrawLayoutPresets();
void DrawSessionRenameDialog();
absl::Status LoadRom();
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
void InitializeTestSuites();
bool quit_ = false;
bool new_project_menu = false;
bool show_emulator_ = false;
bool show_memory_editor_ = false;
bool show_asm_editor_ = false;
bool show_imgui_metrics_ = false;
bool show_imgui_demo_ = false;
bool show_palette_editor_ = false;
bool show_resource_label_manager = false;
bool show_workspace_layout = false;
bool show_save_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;
char session_rename_buffer_[256] = {};
// Testing interface
bool show_test_dashboard_ = false;
bool show_performance_dashboard_ = false;
// Agent proposal drawer
ProposalDrawer proposal_drawer_;
bool show_proposal_drawer_ = false;
#ifdef YAZE_WITH_GRPC
AutomationBridge harness_telemetry_bridge_;
#endif
// Agent chat history popup
AgentChatHistoryPopup agent_chat_history_popup_;
bool show_chat_history_popup_ = false;
// Project file editor
ProjectFileEditor project_file_editor_;
// Editor selection dialog
EditorSelectionDialog editor_selection_dialog_;
bool show_editor_selection_ = false;
// Welcome screen
WelcomeScreen welcome_screen_;
#ifdef YAZE_WITH_GRPC
// Agent editor - manages chat, collaboration, and network coordination
AgentEditor agent_editor_;
std::unique_ptr<yaze::agent::AgentControlServer> agent_control_server_;
#endif
std::string version_ = "";
absl::Status status_;
emu::Emulator emulator_;
public:
struct RomSession {
Rom rom;
EditorSet editors;
std::string custom_name; // User-defined session name
std::string filepath; // ROM filepath for duplicate detection
core::FeatureFlags::Flags feature_flags; // Per-session feature flags
RomSession() = default;
explicit RomSession(Rom&& r, UserSettings* user_settings = nullptr, size_t session_id = 0)
: rom(std::move(r)), editors(&rom, user_settings, session_id) {
filepath = rom.filename();
// Initialize with default feature flags
feature_flags = core::FeatureFlags::Flags{};
}
// Get display name (custom name or ROM title)
std::string GetDisplayName() const {
if (!custom_name.empty()) {
return custom_name;
}
return rom.title().empty() ? "Untitled Session" : rom.title();
}
};
private:
std::deque<RomSession> sessions_;
Rom* current_rom_ = nullptr;
EditorSet* current_editor_set_ = nullptr;
Editor* current_editor_ = nullptr;
EditorSet blank_editor_set_{};
gfx::IRenderer* renderer_ = nullptr;
core::YazeProject current_project_;
EditorContext context_;
std::unique_ptr<PopupManager> popup_manager_;
ToastManager toast_manager_;
MenuBuilder menu_builder_;
UserSettings user_settings_;
WorkspaceManager workspace_manager_{&toast_manager_};
// New delegated components
EditorRegistry editor_registry_;
std::unique_ptr<MenuOrchestrator> menu_orchestrator_;
ProjectManager project_manager_;
RomFileManager rom_file_manager_;
SessionCardRegistry card_registry_;
WindowDelegate window_delegate_;
std::unique_ptr<SessionCoordinator> session_coordinator_;
float autosave_timer_ = 0.0f;
// RAII helper for clean session context switching
class SessionScope {
public:
SessionScope(EditorManager* manager, size_t session_id);
~SessionScope();
private:
EditorManager* manager_;
Rom* prev_rom_;
EditorSet* prev_editor_set_;
size_t prev_session_id_;
};
};
} // namespace editor
} // namespace yaze
#endif // YAZE_APP_EDITOR_EDITOR_MANAGER_H