1#ifndef YAZE_APP_EDITOR_EDITOR_MANAGER_H
2#define YAZE_APP_EDITOR_EDITOR_MANAGER_H
4#define IMGUI_DEFINE_MATH_OPERATORS
14#include "absl/status/status.h"
15#include "absl/strings/string_view.h"
56#include "imgui/imgui.h"
59#include "yaze_config.h"
64class CanvasAutomationServiceImpl;
69class AgentUiController;
83class EditorManagerLayoutTestPeer;
125 const std::string& panels_str);
220 std::vector<editor::RomFileManager::BackupEntry>
GetRomBackups()
const;
261 current_index < session_coordinator_->GetTotalSessionCount()) {
273 ImGui::GetIO().FontGlobalScale = scale;
276 LOG_WARN(
"EditorManager",
"Failed to save user settings: %s",
277 status.ToString().c_str());
295 bool from_dialog =
false)
override;
373 bool remove_after_restore =
false);
383 size_t session_index)
const;
409 void SetCanvasAutomationService(CanvasAutomationServiceImpl* service) {
410 canvas_automation_service_ = service;
426#ifdef YAZE_ENABLE_TESTING
427 void ShowTestDashboard() { show_test_dashboard_ =
true; }
430#ifdef YAZE_BUILD_AGENT_UI
432 void ShowChatHistory();
439#ifdef YAZE_BUILD_AGENT_UI
449 absl::Status
SaveRomAs(
const std::string& filename);
457 const std::string& filename,
462 const std::string& template_name =
"Basic ROM Hack");
464 const std::string& template_name,
const std::string& rom_path,
465 const std::string& project_name,
466 const std::string& project_path = std::string());
468 const std::string& project_name,
469 const std::string& project_path = std::string());
502 const std::string& rom_path,
503 const std::optional<std::string>& expected_sha256 = std::nullopt);
539 absl::Status
LoadAssets(uint64_t loading_handle = 0);
563 const std::string& saved_category,
564 const std::vector<std::string>& available_categories)
const;
568 bool transient =
false);
588 void FinishRawRomOpen(
bool remembered_load_options,
bool ask_for_load_options,
589 bool is_first_time_rom_path);
719 std::unique_ptr<LayoutManager>
722 std::unique_ptr<RightDrawerManager>
737 bool publish_lyra =
true);
748 bool include_recent_files);
752 const std::string& contents);
754 const std::string& contents);
759 std::optional<size_t> previous_session_id);
761 size_t previous_session_count);
763 absl::StatusOr<const project::YazeProject*>
766 const std::string& detail,
768 const std::string& output_tail =
"",
769 bool can_cancel =
false)
const;
771 const std::string& detail,
777 const std::optional<std::string>& target_filename = std::nullopt);
780 const std::optional<std::string>& save_as_filename);
784 const std::string& saved_rom,
785 bool save_as,
bool rom_written =
true);
789 const std::string& state,
const std::string& editing_source_path =
"");
795 const std::optional<std::string>& save_as_filename);
799 const std::string& filename,
bool allow_dialogs =
true,
872 CanvasAutomationServiceImpl* canvas_automation_service_ =
nullptr;
The Rom class is used to load, save, and modify Rom data. This is a generic SNES ROM container and do...
Manages project versioning (Git) and ROM artifact snapshots.
Comprehensive AI Agent Platform & Bot Creator.
Central coordinator for all agent UI components.
Handles editor switching, layout initialization, and jump-to navigation.
SessionScope(EditorManager *manager, size_t session_index)
EditorSet * prev_editor_set_
size_t prev_session_index_
The EditorManager controls the main editor window and manages the various editor classes.
void ApplyProjectSaveSettings(project::YazeProject *project, bool include_recent_files)
std::optional< RomLoadOptionsOwner > rom_load_options_owner_
absl::Status SaveProjectAs()
std::unique_ptr< SessionCoordinator > session_coordinator_
RomLifecycleManager rom_lifecycle_
void SaveWorkspacePreset(const std::string &name)
StartupVisibility welcome_mode_override_
std::unique_ptr< AgentUiController > agent_ui_
void ConfirmPendingUnsavedSessionActionSaveAndContinue()
bool IsRomLoadOptionsOpen() const
void InitializeTestSuites()
std::optional< PendingRomSave > pending_rom_save_
void ApplyDefaultBackupPolicy()
float GetRightLayoutOffset() const
bool show_proposal_drawer_
std::vector< EditorType > CollectEditorsToPreload(EditorSet *editor_set) const
void SwitchToEditor(EditorType editor_type, bool force_visible=false, bool from_dialog=false) override
std::unique_ptr< GlobalEditorContext > editor_context_
void RestoreProjectEditingStateForSession(RomSession *session)
auto GetCurrentGameData() const -> zelda3::GameData *
bool RomLoadOptionsOwnerMatchesCurrentSession(const RomLoadOptionsOwner &owner) const
bool MaybeGuardPendingSessionAction(PendingUnsavedSessionAction action)
absl::Status SaveRomAs(const std::string &filename)
bool HasAnySessionPendingUnsavedWork() const
absl::Status OpenProjectInternal()
project::YazeProject current_project_
void HandleSessionSwitched(size_t new_index, RomSession *session, bool transient=false)
bool ProjectDescriptorMatchesDisk()
absl::Status CompletePendingProjectNativeSave()
absl::Status ValidateLyraTerrainProjectContext() const
void QueueBuildCurrentProject()
std::unique_ptr< RightDrawerManager > right_drawer_manager_
void CancelPendingUnsavedSessionAction()
void SetCurrentEditor(Editor *editor) override
bool SaveLayoutSnapshotAs(const std::string &name)
absl::Status PrepareRawProjectFileSave(const std::string &filepath, const std::string &contents)
absl::Status LoadAssetsForMode(uint64_t loading_handle=0)
MenuBuilder menu_builder_
bool IsCurrentProjectDirty() const
float settings_dirty_timestamp_
std::string GetPreferredStartupCategory(const std::string &saved_category, const std::vector< std::string > &available_categories) const
const WorkspaceWindowManager & window_manager() const
absl::StatusOr< std::string > RunProjectBuildCommand()
absl::Status CheckRomWritePolicy(const std::optional< std::string > &target_filename=std::nullopt)
Save the current ROM file.
void InitializeServices()
void ApplyLayoutDefaultsMigrationIfNeeded()
void SwitchToSession(size_t index)
bool active_project_build_reported_
absl::Status RestoreRomBackup(const std::string &backup_path)
absl::Status EnsureGameDataLoaded()
size_t GetActiveSessionCount() const
bool SessionHasPendingRomWork(size_t session_index) const
bool pending_project_open_transition_
absl::Status OpenProject()
ProjectManager project_manager_
void BindRomLoadOptionsToCurrentSession()
bool HasPendingPotItemSaveConfirmation() const
void CloseCurrentSession()
gfx::IRenderer * renderer_
Rom * GetCurrentRom() const override
bool IsRomWriteConfirmPending() const
bool CanRevertRom() const
void CancelPendingRomSave(bool hide_popups=false)
int PendingDungeonRoomCountForSession(size_t session_index) const
bool HasDuplicateSession(const std::string &filepath)
absl::Status RepairCurrentProject()
absl::Status SaveCurrentSession()
WorkspaceManager * workspace_manager()
std::unique_ptr< LayoutManager > layout_manager_
std::unique_ptr< DashboardPanel > dashboard_panel_
absl::Status RetireNativeSaveTransfer(const std::string &state, const std::string &editing_source_path="")
void HandleSessionClosed(size_t index)
bool HasPreviousEditorLayout() const
void ResetAssetState(RomSession *session)
void DrawSecondaryWindows()
void ProcessStartupActions(const AppConfig &config)
void LoadWorkspacePreset(const std::string &name)
std::string GenerateUniqueEditorTitle(EditorType type, size_t session_index) const
void RenameSession(size_t index, const std::string &new_name)
core::VersionManager * version_manager_
std::vector< editor::RomFileManager::BackupEntry > GetRomBackups() const
int ModifiedSessionCount() const
std::string CompactPendingUnsavedWorkLabel(size_t session_index) const
void LoadWorkspaceLayout()
const UserSettings & user_settings() const
std::vector< std::string > ListLayoutSnapshots() const
bool show_workspace_layout
SharedClipboard shared_clipboard_
MenuBuilder & menu_builder()
bool EditorInitRequiresGameData(EditorType type) const
void SyncEditorContextForCategory(const std::string &category)
const RightDrawerManager * right_drawer_manager() const
UICoordinator * ui_coordinator()
void ShowProjectManagement()
Injects dependencies into all editors within an EditorSet.
absl::Status RunCurrentProject()
Editor * ResolveEditorForCategory(const std::string &category)
void FinishRawRomOpen(bool remembered_load_options, bool ask_for_load_options, bool is_first_time_rom_path)
void DuplicateCurrentSession()
void Initialize(gfx::IRenderer *renderer, const std::string &filename="")
std::optional< size_t > runtime_feature_flags_session_id_
void MarkCurrentProjectDirty()
EditorRegistry editor_registry_
absl::Status FinalizeNewProject(const std::string &project_name, const std::string &project_path=std::string())
void SetupDialogCallbacks()
std::string DescribeAllPendingUnsavedWork() const
project::RomWritePolicy GetProjectRomWritePolicy() const
void MarkEditorLoaded(RomSession *session, EditorType type)
absl::Status StartPendingRomSave(const std::optional< std::string > &save_as_filename)
absl::Status CreateNewProjectFromRom(const std::string &template_name, const std::string &rom_path, const std::string &project_name, const std::string &project_path=std::string())
void ApplyStartupVisibilityOverrides()
void ResetWorkspaceLayout()
friend class EditorManagerLayoutTestPeer
absl::Status CreateNewProject(const std::string &template_name="Basic ROM Hack")
absl::Status RecordCompletedNativeSave(const project::YazeProject &project, const std::string &saved_rom, bool save_as, bool rom_written=true)
RightDrawerManager * right_drawer_manager()
void ConfirmPendingUnsavedSessionActionDiscardAndContinue()
absl::Status InitializeEditorForType(EditorType type, EditorSet *editor_set, Rom *rom)
ToastManager toast_manager_
LayoutCoordinator layout_coordinator_
absl::Status LoadAssets(uint64_t loading_handle=0)
std::string GetCurrentRomHash() const
FeatureHintManager feature_hint_manager_
bool HasPendingUnsavedSessionAction() const
void RefreshWorkspacePresets()
bool pending_layout_defaults_reset_
void RestoreActiveEditorLayoutAfterAssets(RomSession *session)
absl::Status SaveCurrentSessionAs()
std::string startup_editor_hint_
auto GetCurrentEditorSet() const -> EditorSet *
absl::Status OpenLyraTerrain()
uint64_t project_rom_selection_generation_
void CancelRomWriteConfirm()
bool IsRomBackupRestorePending() const
std::string DescribePendingUnsavedWork(size_t session_index) const
float GetBottomLayoutOffset() const
absl::Status PruneRomBackups()
void SetFontGlobalScale(float scale)
absl::Status LoadProjectWithRom(bool allow_dialogs=true)
EditorContextSnapshot GetEditorContextSnapshot(const std::string &category)
ProjectManagementPanel * project_management_panel()
void FinishPendingRomSaveAttempt(const absl::Status &status)
std::unique_ptr< MenuOrchestrator > menu_orchestrator_
void RequestSwitchToSession(size_t index) override
void HandleUIActionRequest(UIActionRequestEvent::Action action)
void ResolvePotItemSaveConfirmation(PotItemSaveDecision decision)
absl::Status CommitRawProjectFileSave(const std::string &filepath, const std::string &contents)
auto GetCurrentEditor() const -> Editor *override
absl::Status OpenRomOrProject(const std::string &filename, LoadOptionsPrompt prompt=LoadOptionsPrompt::kAsk)
bool HasPendingRomSaveConfirmation() const
void HandleSessionRomLoaded(size_t index, Rom *rom)
WorkspaceWindowManager & window_manager()
void RestoreCurrentRomIdentity()
ProjectFileEditor project_file_editor_
void SetSidebarVisible(bool visible)
void HandleHostVisibilityChanged(bool visible)
void ApplyLayoutPreset(const std::string &preset_name)
size_t session_to_rename_
void RestoreTemporaryLayoutSnapshot(bool clear_after_restore=false)
bool IsSidebarVisible() const
void ApplyStartupVisibility(const AppConfig &config)
ShortcutManager * shortcut_manager()
void ExecutePendingUnsavedSessionAction(const PendingUnsavedSessionAction &action)
bool WantsContinuousFrames() const
WorkspaceWindowManager window_manager_
absl::Status CreateLyraTerrain()
absl::Status SwapProjectRom(const std::string &rom_path, const std::optional< std::string > &expected_sha256=std::nullopt)
size_t PendingPaletteColorCountForSession(size_t session_index) const
void RestorePreviousEditorLayout()
absl::Status OpenLyraTerrainFromPath(const std::string &path)
bool show_rom_load_options_
std::string GetProjectExpectedRomHash() const
const WindowHost * window_host() const
void RestoreEditorLayoutAfterAssets(RomSession *session, EditorType type)
void PersistInputConfig(const emu::input::InputConfig &config)
UserSettings & user_settings()
absl::Status SaveProject()
absl::Status SaveRomInternal(const std::optional< std::string > &save_as_filename)
void SetStartupLoadHints(const AppConfig &config)
void MaybeEmitZScreamRomLoadHints()
void RebaseCleanProjectFileDraft(const std::string &filepath)
std::optional< size_t > pending_project_open_previous_session_id_
void CaptureActiveProjectContext()
absl::Status LoadAssetsLazy(uint64_t loading_handle=0)
bool PendingRomSaveMatchesActiveSession() const
void LoadDesignerLayout()
absl::Status DrawRomSelector()=delete
void SetAssetLoadMode(AssetLoadMode mode)
void DismissEditorSelection() override
absl::Status DiscardPendingRomBackupRestore()
void SaveWorkspaceLayout()
std::string NativeSaveEditingSourcePath() const
const std::vector< core::WriteConflict > & pending_write_conflicts() const
std::atomic< uint64_t > ui_sync_frame_id_
std::optional< size_t > active_project_context_session_id_
std::string GetPendingUnsavedSessionActionContinueLabel() const
std::string GetPendingUnsavedSessionActionPrompt() const
const project::YazeProject * GetCurrentProject() const
bool ApplyLayoutProfile(const std::string &profile_id)
absl::Status AutosaveActiveSession()
Editor * GetEditorByType(EditorType type, EditorSet *editor_set) const
absl::Status BuildCurrentProject()
StartupVisibility sidebar_mode_override_
RomLoadOptionsDialog rom_load_options_dialog_
absl::Status LoadRom()
Load a ROM file into a new or existing session.
void ShowRomLoadOptions()
std::vector< std::string > startup_panel_hints_
void SetupComponentCallbacks()
bool defer_project_native_completion_
std::vector< std::function< void()> > deferred_actions_
void RegisterEmulatorPanels()
bool RomLoadOptionsMatchCurrentSession() const
bool ActivateExistingSessionForOpen(const std::string &filename)
void OpenEditorAndPanelsFromFlags(const std::string &editor_name, const std::string &panels_str)
project::RomRole GetProjectRomRole() const
StartupVisibility dashboard_mode_override_
void BypassWriteConflictOnce()
void BindProjectContextToSession(RomSession *session, const project::YazeProject &project)
bool ApplyRememberedRomLoadChoice()
void InitializeSubsystems()
std::optional< size_t > ResolveSessionIndexById(size_t session_id) const
void ApplyCurrentProjectRuntimeContext()
void ShowProjectFileEditor()
void RefreshHackWorkflowBackend()
static bool IsPanelBasedEditor(EditorType type)
void ClearPendingWriteConflicts()
absl::Status Update()
Main update loop for the editor application.
void SetupSidebarCallbacks()
SessionCoordinator * session_coordinator()
size_t GetCurrentSessionIndex() const
absl::Status OpenRomOrProjectInternal(const std::string &filename, bool allow_dialogs=true, LoadOptionsPrompt prompt=LoadOptionsPrompt::kAsk)
absl::StatusOr< std::string > ResolveProjectRunTarget() const
void ShowPostLoadSurface()
absl::Status ImportProject(const std::string &project_path)
absl::Status ReloadProjectRom()
FeatureHintManager * feature_hint_manager()
AgentUiController * GetAgentUiController()
core::VersionManager * GetVersionManager()
WorkspaceWindowManager * GetWindowManager()
void RequestCloseSession(size_t index) override
size_t GetCurrentSessionId() const
Stable workspace identity; unlike the UI index, it does not compact.
std::string ExecuteEditorControl(const std::string &request)
bool ProjectFileDraftTargetsCurrentProject() const
absl::Status SaveProjectWorkBeforeRomSave(bool allow_dialogs)
void ClearTemporaryLayoutSnapshot()
AssetLoadMode asset_load_mode() const
ProjectWorkflowStatus MakeRunStatus(const std::string &summary, const std::string &detail, ProjectWorkflowState state) const
project::YazeProject * GetCurrentProject()
void LoadDeveloperLayout()
AgentEditor * GetAgentEditor()
void QueueDeferredAction(std::function< void()> action)
absl::Status ValidateProjectRomSelection(const std::string &rom_path)
SelectionPropertiesPanel selection_properties_panel_
WindowDelegate window_delegate_
bool DeleteLayoutSnapshot(const std::string &name)
absl::Status PrepareActiveProjectEditorDraftsForSave(bool publish_lyra=true)
const SessionCoordinator * session_coordinator() const
ProjectFileEditor * project_file_editor()
void ConfigureSession(RomSession *session) override
std::unique_ptr< ActivityBar > activity_bar_
ShortcutManager shortcut_manager_
bool IsRomHashMismatch() const
auto emulator() -> emu::Emulator &
const PanelHost * panel_host() const
emu::input::InputConfig BuildInputConfigFromSettings() const
bool RestoreLayoutSnapshot(const std::string &name, bool remove_after_restore=false)
void RefreshResourceLabelProvider()
bool HasPendingDungeonChangesForSession(size_t session_index) const
std::optional< PendingUnsavedSessionAction > pending_unsaved_session_action_
void MarkEditorInitialized(RomSession *session, EditorType type)
bool SessionHasPendingUnsavedWork(size_t session_index) const
absl::Status RevertRomToSavedInternal()
void SyncLayoutScopeFromCurrentProject()
WindowHost * window_host()
std::unique_ptr< BackgroundCommandTask > active_project_build_
bool IsCurrentProjectContextOwnedBySession(size_t session_id) const
bool IsPlanningOnlyProjectSave(const RomSession &session)
UserSettings user_settings_
core::FeatureFlags::Flags * GetCurrentFeatureFlags()
WorkspaceManager workspace_manager_
yaze::zelda3::Overworld * overworld() const
ProposalDrawer proposal_drawer_
void ConfigureEditorDependencies(EditorSet *editor_set, Rom *rom, size_t session_id)
absl::Status ResumePendingRomSave()
int pending_pot_item_unloaded_rooms() const
absl::StatusOr< const project::YazeProject * > PrepareActiveProjectContextForSave()
std::unique_ptr< ProjectManagementPanel > project_management_panel_
int pending_pot_item_total_rooms() const
bool HasOpenEditor() const
std::unique_ptr< workflow::HackWorkflowBackend > hack_workflow_backend_
PopupManager * popup_manager()
absl::StatusOr< std::string > ResolveProjectBuildCommand()
void RestoreProjectContextAfterFailedOpen(std::optional< size_t > previous_session_id)
void AnnounceRememberedRomLoadChoice()
void RemoveSession(size_t index)
absl::Status CheckOracleRomSafetyPreSave(Rom *rom)
void DetachActiveProjectContext()
UiSyncState GetUiSyncStateSnapshot() const
void PollProjectWorkflowTasks()
absl::Status LoadRomInternal()
ProjectWorkflowStatus MakeBuildStatus(const std::string &summary, const std::string &detail, ProjectWorkflowState state, const std::string &output_tail="", bool can_cancel=false) const
void CloseRomLoadOptions(const char *reason)
void CancelQueuedProjectBuild()
AssetLoadMode asset_load_mode_
absl::Status DiscardProvisionalSessionCreatedSince(size_t previous_session_count)
absl::Status EnsureEditorAssetsLoaded(EditorType type)
std::unique_ptr< PopupManager > popup_manager_
bool RestoreProjectContextForSession(RomSession *session)
void CaptureCurrentRomIdentity(bool preserve_editing_source=false)
std::atomic< int > pending_editor_deferred_actions_
std::unique_ptr< UICoordinator > ui_coordinator_
EditorActivator editor_activator_
absl::Status RevertRomToSaved()
absl::Status SetCurrentRom(Rom *rom)
std::string GetPendingUnsavedSessionActionSaveLabel() const
void InitializeShortcutSystem()
std::optional< PendingProjectRomSelection > pending_project_rom_selection_
void CaptureActiveProjectEditingState()
std::unique_ptr< WindowHost > window_host_
void CaptureTemporaryLayoutSnapshot()
float GetLeftLayoutOffset() const
void HandleSessionCreated(size_t index, RomSession *session)
absl::Status SaveActiveProjectEditingWork(bool allow_dialogs=true)
bool EditorRequiresGameData(EditorType type) const
ToastManager * toast_manager()
RomFileManager rom_file_manager_
void CaptureRuntimeFeatureFlags()
void ResetCurrentEditorLayout()
absl::Status ReplaceActiveSessionRom(Rom &&rom, const std::string &filepath)
char session_rename_buffer_[256]
Manages editor types, categories, and lifecycle.
Contains a complete set of editors for a single ROM instance.
Interface for editor classes.
Show-once feature tips backed by ToastManager + UserSettings.
Interface for editor selection and navigation.
Interface for session configuration.
Facade class that coordinates all layout-related operations.
float GetBottomLayoutOffset() const
Get the bottom margin needed for status bar.
float GetRightLayoutOffset() const
Get the right margin needed for drawers.
float GetLeftLayoutOffset() const
Get the left margin needed for sidebar (Activity Bar + Side Panel)
Editor for .yaze project files with syntax highlighting and validation.
Panel for managing project settings, ROM versions, and snapshots.
Handles all project file operations with ROM-first workflow.
ImGui drawer for displaying and managing agent proposals.
Manages right-side sliding drawers for agent chat, proposals, settings.
Handles all ROM file I/O operations.
Manages ROM and project persistence state.
void BypassWriteConflictOnce()
bool IsRomHashMismatch() const
Check whether the ROM hash mismatches the project's expected hash.
bool HasPendingPotItemSaveConfirmation() const
int pending_pot_item_unloaded_rooms() const
const std::string & current_rom_hash() const
Get the cached ROM hash string.
const std::vector< core::WriteConflict > & pending_write_conflicts() const
int pending_pot_item_total_rooms() const
bool IsRomWriteConfirmPending() const
Full-editing properties panel for selected entities.
High-level orchestrator for multi-session UI.
A session-aware status bar displayed at the bottom of the application.
Handles all UI drawing operations and state management.
Manages user preferences and settings persistence.
Low-level window operations with minimal dependencies.
void LoadDesignerLayout()
void LoadDeveloperLayout()
Thin host API over WorkspaceWindowManager for declarative window workflows.
Manages workspace layouts, sessions, and presets.
void SaveWorkspacePreset(const std::string &name)
void LoadWorkspacePreset(const std::string &name)
absl::Status SaveWorkspaceLayout(const std::string &name="")
absl::Status LoadWorkspaceLayout(const std::string &name="")
Central registry for all editor cards with session awareness and dependency injection.
A class for emulating and debugging SNES games.
Defines an abstract interface for all rendering operations.
#define LOG_WARN(category, format,...)
void SetCurrentEditor(Editor *editor)
Set the currently active editor.
Editors are the view controllers for the application.
std::optional< EditorType > ParseEditorTypeFromString(absl::string_view name)
StartupVisibility
Tri-state toggle used for startup UI visibility controls.
AssetLoadMode
Asset loading mode for editor resources.
Configuration options for the application startup.
std::string previous_path
std::string candidate_path
std::optional< std::string > save_as_filename
LoadOptionsPrompt load_options_prompt
bool layout_rebuild_pending
int pending_layout_actions
int pending_editor_actions
Represents a single session, containing a ROM and its associated editors.
core::FeatureFlags::Flags feature_flags
Modern project structure with comprehensive settings consolidation.