2026-04-15 08:24:06 +08:00
|
|
|
#include "Composition/EditorShellRuntime.h"
|
|
|
|
|
|
2026-04-19 02:48:41 +08:00
|
|
|
#include "Host/TextureHost.h"
|
|
|
|
|
#include "Host/ViewportRenderHost.h"
|
2026-04-15 22:47:42 +08:00
|
|
|
#include "State/EditorContext.h"
|
|
|
|
|
|
2026-04-19 04:36:52 +08:00
|
|
|
#include "Composition/EditorPanelIds.h"
|
|
|
|
|
|
2026-04-15 22:47:42 +08:00
|
|
|
#include <XCEngine/Rendering/RenderContext.h>
|
|
|
|
|
|
2026-04-15 08:24:06 +08:00
|
|
|
namespace XCEngine::UI::Editor::App {
|
|
|
|
|
|
|
|
|
|
void EditorShellRuntime::Initialize(
|
|
|
|
|
const std::filesystem::path& repoRoot,
|
2026-04-19 02:48:41 +08:00
|
|
|
Host::TextureHost& textureHost,
|
|
|
|
|
UIEditorTextMeasurer& textMeasurer) {
|
|
|
|
|
m_textureHost = &textureHost;
|
|
|
|
|
m_builtInIcons.Initialize(textureHost);
|
|
|
|
|
m_sceneViewportController.Initialize(repoRoot, textureHost);
|
2026-04-15 08:24:06 +08:00
|
|
|
m_hierarchyPanel.SetBuiltInIcons(&m_builtInIcons);
|
|
|
|
|
m_projectPanel.SetBuiltInIcons(&m_builtInIcons);
|
2026-04-19 02:48:41 +08:00
|
|
|
m_projectPanel.SetTextMeasurer(&textMeasurer);
|
2026-04-15 08:24:06 +08:00
|
|
|
m_hierarchyPanel.Initialize();
|
|
|
|
|
m_projectPanel.Initialize(repoRoot);
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-19 02:48:41 +08:00
|
|
|
void EditorShellRuntime::AttachViewportWindowRenderer(Host::ViewportRenderHost& renderer) {
|
2026-04-15 08:24:06 +08:00
|
|
|
m_viewportHostService.AttachWindowRenderer(renderer);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void EditorShellRuntime::DetachViewportWindowRenderer() {
|
|
|
|
|
m_viewportHostService.DetachWindowRenderer();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void EditorShellRuntime::SetViewportSurfacePresentationEnabled(bool enabled) {
|
|
|
|
|
m_viewportHostService.SetSurfacePresentationEnabled(enabled);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void EditorShellRuntime::Shutdown() {
|
|
|
|
|
m_shellFrame = {};
|
|
|
|
|
m_shellInteractionState = {};
|
2026-04-15 19:30:58 +08:00
|
|
|
m_splitterDragCorrectionState = {};
|
2026-04-15 08:24:06 +08:00
|
|
|
m_traceEntries.clear();
|
2026-04-18 18:55:19 +08:00
|
|
|
m_sceneEditCommandRoute = {};
|
2026-04-19 02:48:41 +08:00
|
|
|
if (m_textureHost != nullptr) {
|
|
|
|
|
m_sceneViewportController.Shutdown(*m_textureHost);
|
2026-04-18 18:55:19 +08:00
|
|
|
m_builtInIcons.Shutdown();
|
2026-04-19 02:48:41 +08:00
|
|
|
m_textureHost = nullptr;
|
2026-04-18 18:55:19 +08:00
|
|
|
} else {
|
|
|
|
|
m_builtInIcons.Shutdown();
|
|
|
|
|
}
|
2026-04-15 08:24:06 +08:00
|
|
|
m_viewportHostService.Shutdown();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void EditorShellRuntime::ResetInteractionState() {
|
|
|
|
|
m_shellFrame = {};
|
|
|
|
|
m_shellInteractionState = {};
|
2026-04-15 19:30:58 +08:00
|
|
|
m_splitterDragCorrectionState = {};
|
2026-04-15 08:24:06 +08:00
|
|
|
m_traceEntries.clear();
|
2026-04-18 18:55:19 +08:00
|
|
|
m_sceneViewportController.ResetInteractionState();
|
2026-04-15 08:24:06 +08:00
|
|
|
m_hierarchyPanel.ResetInteractionState();
|
|
|
|
|
m_projectPanel.ResetInteractionState();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const UIEditorShellInteractionFrame& EditorShellRuntime::GetShellFrame() const {
|
|
|
|
|
return m_shellFrame;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const UIEditorShellInteractionState& EditorShellRuntime::GetShellInteractionState() const {
|
|
|
|
|
return m_shellInteractionState;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const std::vector<WorkspaceTraceEntry>& EditorShellRuntime::GetTraceEntries() const {
|
|
|
|
|
return m_traceEntries;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const std::vector<HierarchyPanel::Event>& EditorShellRuntime::GetHierarchyPanelEvents() const {
|
|
|
|
|
return m_hierarchyPanel.GetFrameEvents();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const std::vector<ProjectPanel::Event>& EditorShellRuntime::GetProjectPanelEvents() const {
|
|
|
|
|
return m_projectPanel.GetFrameEvents();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const std::string& EditorShellRuntime::GetBuiltInIconError() const {
|
|
|
|
|
return m_builtInIcons.GetLastError();
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-15 13:22:58 +08:00
|
|
|
void EditorShellRuntime::SetExternalDockHostDropPreview(
|
|
|
|
|
const Widgets::UIEditorDockHostDropPreviewState& preview) {
|
|
|
|
|
m_shellInteractionState.workspaceInteractionState.dockHostInteractionState
|
|
|
|
|
.dockHostState.dropPreview = preview;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void EditorShellRuntime::ClearExternalDockHostDropPreview() {
|
|
|
|
|
m_shellInteractionState.workspaceInteractionState.dockHostInteractionState
|
|
|
|
|
.dockHostState.dropPreview = {};
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-15 08:24:06 +08:00
|
|
|
ProjectPanel::CursorKind EditorShellRuntime::GetHostedContentCursorKind() const {
|
|
|
|
|
return m_projectPanel.GetCursorKind();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Widgets::UIEditorDockHostCursorKind EditorShellRuntime::GetDockCursorKind() const {
|
|
|
|
|
return Widgets::ResolveUIEditorDockHostCursorKind(
|
|
|
|
|
m_shellFrame.workspaceInteractionFrame.dockHostFrame.layout);
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-19 04:36:52 +08:00
|
|
|
EditorShellPointerOwner EditorShellRuntime::GetPointerOwner() const {
|
|
|
|
|
const auto& dockHostInteractionState =
|
|
|
|
|
m_shellInteractionState.workspaceInteractionState.dockHostInteractionState;
|
|
|
|
|
if (dockHostInteractionState.splitterDragState.active ||
|
|
|
|
|
!dockHostInteractionState.activeTabDragNodeId.empty()) {
|
|
|
|
|
return EditorShellPointerOwner::DockHost;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (const auto& panelState :
|
|
|
|
|
m_shellInteractionState.workspaceInteractionState.composeState.panelStates) {
|
|
|
|
|
if (!panelState.viewportShellState.inputBridgeState.captured) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (panelState.panelId == kGamePanelId) {
|
|
|
|
|
return EditorShellPointerOwner::GameViewport;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return EditorShellPointerOwner::SceneViewport;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (m_hierarchyPanel.HasActivePointerCapture()) {
|
|
|
|
|
return EditorShellPointerOwner::HierarchyPanel;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (m_projectPanel.HasActivePointerCapture()) {
|
|
|
|
|
return EditorShellPointerOwner::ProjectPanel;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return EditorShellPointerOwner::None;
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-15 08:24:06 +08:00
|
|
|
bool EditorShellRuntime::WantsHostPointerCapture() const {
|
2026-04-19 04:36:52 +08:00
|
|
|
return IsHostedContentPointerOwner(GetPointerOwner());
|
2026-04-15 08:24:06 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool EditorShellRuntime::WantsHostPointerRelease() const {
|
2026-04-19 04:36:52 +08:00
|
|
|
return !IsHostedContentPointerOwner(GetPointerOwner());
|
2026-04-15 08:24:06 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool EditorShellRuntime::HasHostedContentCapture() const {
|
2026-04-19 04:36:52 +08:00
|
|
|
return IsHostedContentPointerOwner(GetPointerOwner());
|
2026-04-15 08:24:06 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool EditorShellRuntime::HasShellInteractiveCapture() const {
|
2026-04-19 04:36:52 +08:00
|
|
|
return IsShellPointerOwner(GetPointerOwner());
|
2026-04-15 08:24:06 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool EditorShellRuntime::HasInteractiveCapture() const {
|
2026-04-19 04:36:52 +08:00
|
|
|
return GetPointerOwner() != EditorShellPointerOwner::None;
|
2026-04-15 08:24:06 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // namespace XCEngine::UI::Editor::App
|