2026-04-15 08:24:06 +08:00
|
|
|
#include "EditorContext.h"
|
2026-04-12 01:29:00 +08:00
|
|
|
|
2026-04-15 08:24:06 +08:00
|
|
|
#include "Composition/EditorShellAssetBuilder.h"
|
2026-04-12 01:29:00 +08:00
|
|
|
|
|
|
|
|
#include <sstream>
|
|
|
|
|
#include <utility>
|
|
|
|
|
|
|
|
|
|
namespace XCEngine::UI::Editor::App {
|
|
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
|
|
using ::XCEngine::UI::Editor::BuildEditorShellShortcutManager;
|
|
|
|
|
|
|
|
|
|
std::string ComposeStatusText(
|
|
|
|
|
std::string_view status,
|
|
|
|
|
std::string_view message) {
|
|
|
|
|
if (status.empty()) {
|
|
|
|
|
return std::string(message);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (message.empty()) {
|
|
|
|
|
return std::string(status);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return std::string(status) + ": " + std::string(message);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // namespace
|
|
|
|
|
|
2026-04-15 08:24:06 +08:00
|
|
|
bool EditorContext::Initialize(const std::filesystem::path& repoRoot) {
|
|
|
|
|
m_shellAsset = BuildEditorShellAsset(repoRoot);
|
2026-04-12 01:29:00 +08:00
|
|
|
m_shellValidation = ValidateEditorShellAsset(m_shellAsset);
|
|
|
|
|
if (!m_shellValidation.IsValid()) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-12 01:49:08 +08:00
|
|
|
m_session = {};
|
|
|
|
|
m_session.repoRoot = repoRoot;
|
|
|
|
|
m_session.projectRoot = (repoRoot / "project").lexically_normal();
|
|
|
|
|
m_hostCommandBridge.BindSession(m_session);
|
2026-04-12 01:29:00 +08:00
|
|
|
m_shortcutManager = BuildEditorShellShortcutManager(m_shellAsset);
|
2026-04-12 01:49:08 +08:00
|
|
|
m_shortcutManager.SetHostCommandHandler(&m_hostCommandBridge);
|
2026-04-12 01:29:00 +08:00
|
|
|
m_shellServices = {};
|
|
|
|
|
m_shellServices.commandDispatcher = &m_shortcutManager.GetCommandDispatcher();
|
|
|
|
|
m_shellServices.shortcutManager = &m_shortcutManager;
|
|
|
|
|
SetReadyStatus();
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-15 08:24:06 +08:00
|
|
|
void EditorContext::AttachTextMeasurer(
|
2026-04-12 01:29:00 +08:00
|
|
|
const UIEditorTextMeasurer& textMeasurer) {
|
|
|
|
|
m_shellServices.textMeasurer = &textMeasurer;
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-15 08:24:06 +08:00
|
|
|
void EditorContext::SetExitRequestHandler(std::function<void()> handler) {
|
2026-04-12 01:49:08 +08:00
|
|
|
m_hostCommandBridge.SetExitRequestHandler(std::move(handler));
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-15 08:24:06 +08:00
|
|
|
void EditorContext::SyncSessionFromWorkspace(
|
2026-04-14 15:07:52 +08:00
|
|
|
const UIEditorWorkspaceController& workspaceController) {
|
2026-04-15 08:24:06 +08:00
|
|
|
SyncEditorSessionFromWorkspace(m_session, workspaceController);
|
2026-04-12 01:49:08 +08:00
|
|
|
}
|
|
|
|
|
|
2026-04-15 08:24:06 +08:00
|
|
|
bool EditorContext::IsValid() const {
|
2026-04-12 01:29:00 +08:00
|
|
|
return m_shellValidation.IsValid();
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-15 08:24:06 +08:00
|
|
|
const std::string& EditorContext::GetValidationMessage() const {
|
2026-04-12 01:29:00 +08:00
|
|
|
return m_shellValidation.message;
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-15 08:24:06 +08:00
|
|
|
const EditorShellAsset& EditorContext::GetShellAsset() const {
|
2026-04-12 01:29:00 +08:00
|
|
|
return m_shellAsset;
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-15 08:24:06 +08:00
|
|
|
const EditorSession& EditorContext::GetSession() const {
|
2026-04-12 01:49:08 +08:00
|
|
|
return m_session;
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-15 08:24:06 +08:00
|
|
|
void EditorContext::SetSelection(EditorSelectionState selection) {
|
2026-04-12 11:12:27 +08:00
|
|
|
m_session.selection = std::move(selection);
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-15 08:24:06 +08:00
|
|
|
void EditorContext::ClearSelection() {
|
2026-04-12 11:12:27 +08:00
|
|
|
m_session.selection = {};
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-15 08:24:06 +08:00
|
|
|
UIEditorWorkspaceController EditorContext::BuildWorkspaceController() const {
|
2026-04-14 15:07:52 +08:00
|
|
|
return UIEditorWorkspaceController(
|
|
|
|
|
m_shellAsset.panelRegistry,
|
|
|
|
|
m_shellAsset.workspace,
|
|
|
|
|
m_shellAsset.workspaceSession);
|
2026-04-12 01:29:00 +08:00
|
|
|
}
|
|
|
|
|
|
2026-04-15 08:24:06 +08:00
|
|
|
const UIEditorShellInteractionServices& EditorContext::GetShellServices() const {
|
2026-04-12 01:29:00 +08:00
|
|
|
return m_shellServices;
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-15 08:24:06 +08:00
|
|
|
UIEditorShellInteractionDefinition EditorContext::BuildShellDefinition(
|
2026-04-14 15:07:52 +08:00
|
|
|
const UIEditorWorkspaceController& workspaceController,
|
2026-04-14 16:19:23 +08:00
|
|
|
std::string_view captureText,
|
2026-04-15 08:24:06 +08:00
|
|
|
EditorShellVariant variant) const {
|
|
|
|
|
return BuildEditorShellInteractionDefinition(
|
2026-04-12 01:29:00 +08:00
|
|
|
m_shellAsset,
|
2026-04-14 15:07:52 +08:00
|
|
|
workspaceController,
|
2026-04-12 01:29:00 +08:00
|
|
|
ComposeStatusText(m_lastStatus, m_lastMessage),
|
2026-04-14 16:19:23 +08:00
|
|
|
captureText,
|
|
|
|
|
variant);
|
2026-04-12 01:29:00 +08:00
|
|
|
}
|
|
|
|
|
|
2026-04-15 08:24:06 +08:00
|
|
|
std::string EditorContext::DescribeWorkspaceState(
|
2026-04-14 15:07:52 +08:00
|
|
|
const UIEditorWorkspaceController& workspaceController,
|
2026-04-12 01:29:00 +08:00
|
|
|
const UIEditorShellInteractionState& interactionState) const {
|
|
|
|
|
std::ostringstream stream = {};
|
2026-04-14 15:07:52 +08:00
|
|
|
stream << "active=" << workspaceController.GetWorkspace().activePanelId;
|
2026-04-12 01:29:00 +08:00
|
|
|
const auto visiblePanels =
|
|
|
|
|
CollectUIEditorWorkspaceVisiblePanels(
|
2026-04-14 15:07:52 +08:00
|
|
|
workspaceController.GetWorkspace(),
|
|
|
|
|
workspaceController.GetSession());
|
2026-04-12 01:29:00 +08:00
|
|
|
stream << " visible=[";
|
|
|
|
|
for (std::size_t index = 0; index < visiblePanels.size(); ++index) {
|
|
|
|
|
if (index > 0u) {
|
|
|
|
|
stream << ',';
|
|
|
|
|
}
|
|
|
|
|
stream << visiblePanels[index].panelId;
|
|
|
|
|
}
|
|
|
|
|
stream << ']';
|
|
|
|
|
|
|
|
|
|
const auto& dockState =
|
|
|
|
|
interactionState.workspaceInteractionState.dockHostInteractionState;
|
|
|
|
|
stream << " dragNode=" << dockState.activeTabDragNodeId;
|
|
|
|
|
stream << " dragPanel=" << dockState.activeTabDragPanelId;
|
|
|
|
|
if (dockState.dockHostState.dropPreview.visible) {
|
|
|
|
|
stream << " dropTarget=" << dockState.dockHostState.dropPreview.targetNodeId;
|
|
|
|
|
}
|
|
|
|
|
return stream.str();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // namespace XCEngine::UI::Editor::App
|
2026-04-15 08:24:06 +08:00
|
|
|
|