292 lines
11 KiB
C++
292 lines
11 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,
|
|
UIEditorShortcutManager shortcutManager,
|
|
EditorHostCommandBridge::RuntimeCommandOwner& runtimeCommandOwner,
|
|
std::function<void()> requestExit)
|
|
: m_iconService(std::move(iconService))
|
|
, m_viewportRuntimeServices(std::move(viewportRuntimeServices))
|
|
, m_workspacePanels(std::move(workspacePanels))
|
|
, m_shortcutManager(std::move(shortcutManager)) {
|
|
m_hostCommandBridge.BindRuntimeCommandOwner(&runtimeCommandOwner);
|
|
m_hostCommandBridge.SetExitRequestHandler(std::move(requestExit));
|
|
m_shortcutManager.SetHostCommandHandler(&m_hostCommandBridge);
|
|
m_shellServices.commandDispatcher = &m_shortcutManager.GetCommandDispatcher();
|
|
m_shellServices.shortcutManager = &m_shortcutManager;
|
|
}
|
|
|
|
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_shellServices.textMeasurer = &textMeasurer;
|
|
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 = {};
|
|
m_shellServices.textMeasurer = nullptr;
|
|
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,
|
|
UIEditorShortcutManager shortcutManager,
|
|
EditorHostCommandBridge::RuntimeCommandOwner& runtimeCommandOwner,
|
|
std::function<void()> requestExit) {
|
|
return std::make_unique<EditorShellRuntime>(
|
|
std::move(workspacePanels),
|
|
std::move(iconService),
|
|
std::move(viewportRuntimeServices),
|
|
std::move(shortcutManager),
|
|
runtimeCommandOwner,
|
|
std::move(requestExit));
|
|
}
|
|
|
|
} // namespace XCEngine::UI::Editor::App
|
|
|
|
namespace XCEngine::UI::Editor::App {
|
|
|
|
void EditorShellRuntime::RenderRequestedViewports(
|
|
EditorFrameServices& frameServices,
|
|
const ::XCEngine::Rendering::RenderContext& renderContext) {
|
|
if (m_viewportRuntimeServices != nullptr) {
|
|
frameServices.SyncSceneViewportRenderRequest(
|
|
m_viewportRuntimeServices->GetSceneViewportRuntime());
|
|
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;
|
|
}
|
|
|
|
m_hostCommandBridge.BindCommandFocusService(
|
|
m_workspacePanels.GetCommandFocusService());
|
|
m_hostCommandBridge.BindEditCommandRoutes(
|
|
m_workspacePanels.FindCommandRoute(EditorActionRoute::Hierarchy),
|
|
m_workspacePanels.FindCommandRoute(EditorActionRoute::Project),
|
|
m_workspacePanels.FindCommandRoute(EditorActionRoute::Scene),
|
|
m_workspacePanels.FindCommandRoute(EditorActionRoute::Inspector));
|
|
|
|
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 = m_shellServices,
|
|
.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());
|
|
}
|
|
|
|
} // namespace XCEngine::UI::Editor::App
|
|
|
|
|