Files
XCEngine/editor/app/Composition/EditorShellRuntime.cpp

265 lines
9.3 KiB
C++

#include "EditorShellRuntime.h"
#include "UiTextureHost.h"
#include "ViewportRenderHost.h"
#include <XCEditor/Shell/UIEditorShellCapturePolicy.h>
#include <XCEngine/Rendering/RenderContext.h>
#include <cassert>
#include <utility>
namespace XCEngine::UI::Editor::App {
EditorShellRuntime::EditorShellRuntime(
EditorWorkspacePanelRuntimeSet workspacePanels,
std::unique_ptr<EditorIconService> iconService,
std::unique_ptr<EditorViewportRuntimeServices> viewportRuntimeServices)
: m_iconService(std::move(iconService))
, m_viewportRuntimeServices(std::move(viewportRuntimeServices))
, m_workspacePanels(std::move(workspacePanels)) {}
void EditorShellRuntime::Initialize(
const EditorRuntimePaths& runtimePaths,
Rendering::Host::UiTextureHost& textureHost,
Host::EditorHostResourceService& resourceService,
UIEditorTextMeasurer& textMeasurer,
SceneViewportEngineBridge& sceneViewportEngineBridge,
GameViewportEngineBridge& gameViewportEngineBridge,
EditorShaderProvider& shaderProvider) {
assert(m_iconService != nullptr);
assert(m_viewportRuntimeServices != nullptr);
if (m_iconService == nullptr || m_viewportRuntimeServices == nullptr) {
return;
}
m_iconService->Initialize(textureHost, resourceService);
m_viewportRuntimeServices->Initialize(
runtimePaths,
sceneViewportEngineBridge,
gameViewportEngineBridge,
shaderProvider);
m_workspacePanels.Initialize(
EditorWorkspacePanelInitializationContext{
.runtimePaths = runtimePaths,
.textMeasurer = textMeasurer,
.iconService = *m_iconService,
.sceneViewportRuntime = &m_viewportRuntimeServices->GetSceneViewportRuntime(),
});
}
void EditorShellRuntime::AttachViewportWindowRenderer(Rendering::Host::ViewportRenderHost& renderer) {
if (m_viewportRuntimeServices != nullptr) {
m_viewportRuntimeServices->AttachWindowRenderer(renderer);
}
}
void EditorShellRuntime::DetachViewportWindowRenderer() {
if (m_viewportRuntimeServices != nullptr) {
m_viewportRuntimeServices->DetachWindowRenderer();
}
}
void EditorShellRuntime::SetViewportSurfacePresentationEnabled(bool enabled) {
if (m_viewportRuntimeServices != nullptr) {
m_viewportRuntimeServices->SetSurfacePresentationEnabled(enabled);
}
}
void EditorShellRuntime::Shutdown() {
m_shellFrame = {};
m_shellInteractionState = {};
m_splitterDragCorrectionState = {};
m_traceEntries.clear();
m_workspacePanels.Shutdown(EditorWorkspacePanelShutdownContext{});
m_workspacePanels = {};
if (m_iconService != nullptr) {
m_iconService->Shutdown();
}
if (m_viewportRuntimeServices != nullptr) {
m_viewportRuntimeServices->Shutdown();
}
}
void EditorShellRuntime::ResetInteractionState() {
m_shellFrame = {};
m_shellInteractionState = {};
m_splitterDragCorrectionState = {};
m_traceEntries.clear();
m_workspacePanels.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::string& EditorShellRuntime::GetBuiltInIconError() const {
static const std::string kEmptyError = {};
return m_iconService != nullptr ? m_iconService->GetLastError() : kEmptyError;
}
void EditorShellRuntime::SetExternalDockHostDropPreview(
const Widgets::UIEditorDockHostDropPreviewState& preview) {
m_shellInteractionState.workspaceInteractionState.dockHostInteractionState
.dockHostState.dropPreview = preview;
}
void EditorShellRuntime::ClearExternalDockHostDropPreview() {
m_shellInteractionState.workspaceInteractionState.dockHostInteractionState
.dockHostState.dropPreview = {};
}
EditorWorkspaceShellCursorKind EditorShellRuntime::GetHostedContentCursorKind() const {
switch (m_workspacePanels.GetHostedContentCursorKind()) {
case EditorWorkspacePanelCursorKind::ResizeEW:
return EditorWorkspaceShellCursorKind::ResizeEW;
case EditorWorkspacePanelCursorKind::Arrow:
default:
return EditorWorkspaceShellCursorKind::Arrow;
}
}
Widgets::UIEditorDockHostCursorKind EditorShellRuntime::GetDockCursorKind() const {
return Widgets::ResolveUIEditorDockHostCursorKind(
m_shellFrame.workspaceInteractionFrame.dockHostFrame.layout);
}
bool EditorShellRuntime::TryResolveDockTabDragHotspot(
std::string_view nodeId,
std::string_view panelId,
const ::XCEngine::UI::UIPoint& point,
::XCEngine::UI::UIPoint& outHotspot) const {
return TryResolveUIEditorDockHostTabDragHotspot(
m_shellFrame.workspaceInteractionFrame.dockHostFrame.layout,
nodeId,
panelId,
point,
outHotspot);
}
UIEditorDockHostTabDropTarget EditorShellRuntime::ResolveDockTabDropTarget(
const ::XCEngine::UI::UIPoint& point) const {
return ResolveUIEditorDockHostTabDropTarget(
m_shellFrame.workspaceInteractionFrame.dockHostFrame.layout,
point);
}
bool EditorShellRuntime::HasHostedContentCapture() const {
return m_workspacePanels.HasActivePointerCapture();
}
bool EditorShellRuntime::HasShellInteractiveCapture() const {
return HasActiveUIEditorShellInteractiveCapture(m_shellInteractionState);
}
bool EditorShellRuntime::HasInteractiveCapture() const {
return HasHostedContentCapture() || HasShellInteractiveCapture();
}
std::unique_ptr<EditorWorkspaceShellRuntime> CreateEditorWorkspaceShellRuntime(
EditorWorkspacePanelRuntimeSet workspacePanels,
std::unique_ptr<EditorIconService> iconService,
std::unique_ptr<EditorViewportRuntimeServices> viewportRuntimeServices) {
return std::make_unique<EditorShellRuntime>(
std::move(workspacePanels),
std::move(iconService),
std::move(viewportRuntimeServices));
}
} // namespace XCEngine::UI::Editor::App
namespace XCEngine::UI::Editor::App {
void EditorShellRuntime::RenderRequestedViewports(
const ::XCEngine::Rendering::RenderContext& renderContext) {
if (m_viewportRuntimeServices != nullptr) {
m_viewportRuntimeServices->RenderRequestedViewports(renderContext);
}
}
void EditorShellRuntime::Append(::XCEngine::UI::UIDrawData& drawData) const {
if (m_iconService == nullptr) {
return;
}
m_drawComposer.Append(
EditorShellDrawComposerContext{
.shellFrame = m_shellFrame,
.shellInteractionState = m_shellInteractionState,
.iconService = *m_iconService,
.workspacePanels = m_workspacePanels,
},
drawData);
}
} // namespace XCEngine::UI::Editor::App
namespace XCEngine::UI::Editor::App {
void EditorShellRuntime::Update(
EditorFrameServices& frameServices,
UIEditorWorkspaceController& workspaceController,
const ::XCEngine::UI::UIRect& bounds,
const std::vector<::XCEngine::UI::UIInputEvent>& inputEvents,
std::string_view captureText,
EditorShellVariant shellVariant,
bool useDetachedTitleBarTabStrip,
float detachedTitleBarTabHeight,
float detachedWindowChromeHeight) {
if (m_viewportRuntimeServices == nullptr) {
return;
}
const auto buildDefinition = [&]() {
return m_sessionCoordinator.PrepareShellDefinition(
EditorShellSessionCoordinatorContext{
.frameServices = frameServices,
.workspaceController = workspaceController,
.captureText = captureText,
.shellVariant = shellVariant,
.workspacePanels = m_workspacePanels,
});
};
m_interactionEngine.Update(
EditorShellInteractionEngineContext{
.shellInteractionState = m_shellInteractionState,
.shellFrame = m_shellFrame,
.splitterDragCorrectionState = m_splitterDragCorrectionState,
.workspaceController = workspaceController,
.bounds = bounds,
.inputEvents = inputEvents,
.shellServices = frameServices.GetShellServices(),
.buildDefinition = buildDefinition,
.hostedContentCaptureActive = HasHostedContentCapture(),
.useDetachedTitleBarTabStrip = useDetachedTitleBarTabStrip,
.detachedTitleBarTabHeight = detachedTitleBarTabHeight,
.detachedWindowChromeHeight = detachedWindowChromeHeight,
.viewportRuntimeServices = *m_viewportRuntimeServices,
});
m_sessionCoordinator.FinalizeFrame(frameServices, workspaceController, m_shellFrame.result);
m_hostedPanelCoordinator.Update(
EditorShellHostedPanelCoordinatorContext{
.frameServices = frameServices,
.shellFrame = m_shellFrame,
.shellInteractionState = m_shellInteractionState,
.inputEvents = inputEvents,
.shellInteractiveCaptureActive = HasShellInteractiveCapture(),
.workspacePanels = m_workspacePanels,
});
m_traceEntries = frameServices.SyncWorkspacePanelFrameEvents(
m_workspacePanels.CollectFrameEvents());
frameServices.SyncSceneViewportRenderRequest(
m_viewportRuntimeServices->GetSceneViewportRuntime());
}
} // namespace XCEngine::UI::Editor::App