Files
XCEngine/editor/app/Windowing/Content/EditorWorkspaceWindowContentController.cpp

284 lines
9.3 KiB
C++
Raw Normal View History

2026-04-27 19:16:08 +08:00
#include "Content/EditorWorkspaceWindowContentController.h"
2026-04-25 16:46:01 +08:00
#include <XCEditor/Foundation/UIEditorRuntimeTrace.h>
2026-04-26 16:27:13 +08:00
#include <XCEditor/Windowing/Presentation/EditorWindowPresentationPolicy.h>
#include <XCEditor/Windowing/System/EditorWindowSystem.h>
2026-04-25 16:46:01 +08:00
#include <XCEditor/Workspace/UIEditorDetachedWindowPolicy.h>
2026-04-27 13:40:26 +08:00
#include <utility>
2026-04-25 16:46:01 +08:00
namespace XCEngine::UI::Editor::App {
namespace {
EditorWindowContentCursorKind ToContentCursorKind(
EditorWorkspaceShellCursorKind cursorKind) {
2026-04-25 16:46:01 +08:00
switch (cursorKind) {
case EditorWorkspaceShellCursorKind::ResizeEW:
2026-04-25 16:46:01 +08:00
return EditorWindowContentCursorKind::ResizeEW;
case EditorWorkspaceShellCursorKind::Arrow:
2026-04-25 16:46:01 +08:00
default:
return EditorWindowContentCursorKind::Arrow;
}
}
EditorWindowContentCursorKind ToContentCursorKind(
Widgets::UIEditorDockHostCursorKind cursorKind) {
switch (cursorKind) {
case Widgets::UIEditorDockHostCursorKind::ResizeEW:
return EditorWindowContentCursorKind::ResizeEW;
case Widgets::UIEditorDockHostCursorKind::ResizeNS:
return EditorWindowContentCursorKind::ResizeNS;
case Widgets::UIEditorDockHostCursorKind::Arrow:
default:
return EditorWindowContentCursorKind::Arrow;
}
}
} // namespace
EditorWorkspaceWindowContentController::EditorWorkspaceWindowContentController(
2026-04-26 13:44:19 +08:00
const UIEditorWindowWorkspaceState& windowState,
2026-04-27 13:40:26 +08:00
EditorWindowSystem& windowSystem,
std::unique_ptr<EditorWorkspaceShellRuntime> shellRuntime)
2026-04-26 13:44:19 +08:00
: m_windowId(windowState.windowId)
, m_windowSystem(windowSystem)
, m_projection(BuildEditorWorkspaceWindowProjection(
std::wstring_view{},
windowSystem.GetPanelRegistry(),
windowState,
2026-04-27 13:40:26 +08:00
false))
, m_shellRuntime(std::move(shellRuntime)) {}
2026-04-25 16:46:01 +08:00
EditorWorkspaceWindowContentController::~EditorWorkspaceWindowContentController() = default;
2026-04-25 17:51:37 +08:00
EditorWindowContentCapabilities
EditorWorkspaceWindowContentController::GetCapabilities() const {
return EditorWindowContentCapabilities{
.workspace = true,
.dockHost = true,
.inputFeedback = true,
.titleBar = true,
.viewportRendering = true,
.utilityPanel = false,
};
}
2026-04-25 16:46:01 +08:00
EditorWindowWorkspaceBinding* EditorWorkspaceWindowContentController::TryGetWorkspaceBinding() {
return this;
}
const EditorWindowWorkspaceBinding*
EditorWorkspaceWindowContentController::TryGetWorkspaceBinding() const {
return this;
}
EditorWindowDockHostBinding* EditorWorkspaceWindowContentController::TryGetDockHostBinding() {
return this;
}
const EditorWindowDockHostBinding*
EditorWorkspaceWindowContentController::TryGetDockHostBinding() const {
return this;
}
const EditorWindowInputFeedbackBinding*
EditorWorkspaceWindowContentController::TryGetInputFeedbackBinding() const {
return this;
}
const EditorWindowTitleBarBinding*
EditorWorkspaceWindowContentController::TryGetTitleBarBinding() const {
return this;
}
const EditorWorkspaceWindowProjection*
EditorWorkspaceWindowContentController::TryGetWorkspaceProjection() const {
return &m_projection;
}
void EditorWorkspaceWindowContentController::RefreshWorkspaceProjection(
EditorWorkspaceWindowProjection projection) {
m_projection = std::move(projection);
2026-04-25 16:46:01 +08:00
}
bool EditorWorkspaceWindowContentController::TryBuildAuthoritativeWorkspaceController(
2026-04-26 16:01:07 +08:00
UIEditorWorkspaceController& outController) {
return m_windowSystem.TryBuildLiveWindowWorkspaceController(
m_windowId,
outController);
}
2026-04-25 16:46:01 +08:00
void EditorWorkspaceWindowContentController::Initialize(
const EditorWindowContentInitializationContext& context) {
if (m_shellRuntime == nullptr) {
return;
}
m_shellRuntime->Initialize(
2026-04-28 14:49:41 +08:00
context.runtimePaths,
2026-04-27 23:18:04 +08:00
context.textureHost,
context.resourceService,
context.textMeasurer,
context.sceneViewportEngineBridge,
context.gameViewportEngineBridge,
context.shaderProvider);
m_shellRuntime->AttachViewportWindowRenderer(context.viewportRenderer);
2026-04-25 16:46:01 +08:00
}
void EditorWorkspaceWindowContentController::Shutdown() {
if (m_shellRuntime != nullptr) {
m_shellRuntime->Shutdown();
}
2026-04-25 16:46:01 +08:00
}
void EditorWorkspaceWindowContentController::ResetInteractionState() {
if (m_shellRuntime != nullptr) {
m_shellRuntime->ResetInteractionState();
}
2026-04-25 16:46:01 +08:00
}
void EditorWorkspaceWindowContentController::SetViewportSurfacePresentationEnabled(bool enabled) {
if (m_shellRuntime != nullptr) {
m_shellRuntime->SetViewportSurfacePresentationEnabled(enabled);
}
2026-04-25 16:46:01 +08:00
}
EditorWindowFrameTransferRequests EditorWorkspaceWindowContentController::UpdateAndAppend(
const EditorWindowContentFrameContext& context,
::XCEngine::UI::UIDrawData& drawData) {
UIEditorWorkspaceController workspaceController = {};
if (!TryBuildAuthoritativeWorkspaceController(workspaceController)) {
AppendUIEditorRuntimeTrace(
"window",
"workspace frame skipped: authoritative state missing for window '" +
m_windowId + "'");
return {};
}
if (m_shellRuntime == nullptr) {
return {};
}
2026-04-26 16:01:07 +08:00
return m_frameOrchestrator.UpdateAndAppend(
context.frameServices,
workspaceController,
*m_shellRuntime,
2026-04-25 16:46:01 +08:00
context.bounds,
context.inputEvents,
2026-04-25 19:25:49 +08:00
context.cursorScreenPoint,
2026-04-25 16:46:01 +08:00
context.captureStatusText,
context.primary,
context.globalTabDragActive,
context.useDetachedTitleBarTabStrip,
drawData);
}
void EditorWorkspaceWindowContentController::RenderRequestedViewports(
const ::XCEngine::Rendering::RenderContext& renderContext) {
if (m_shellRuntime != nullptr) {
m_shellRuntime->RenderRequestedViewports(renderContext);
}
2026-04-25 16:46:01 +08:00
}
const UIEditorShellInteractionFrame&
EditorWorkspaceWindowContentController::GetShellFrame() const {
return m_shellRuntime->GetShellFrame();
2026-04-25 16:46:01 +08:00
}
const UIEditorShellInteractionState&
EditorWorkspaceWindowContentController::GetShellInteractionState() const {
return m_shellRuntime->GetShellInteractionState();
2026-04-25 16:46:01 +08:00
}
void EditorWorkspaceWindowContentController::SetExternalDockHostDropPreview(
const Widgets::UIEditorDockHostDropPreviewState& preview) {
if (m_shellRuntime != nullptr) {
m_shellRuntime->SetExternalDockHostDropPreview(preview);
}
2026-04-25 16:46:01 +08:00
}
void EditorWorkspaceWindowContentController::ClearExternalDockHostDropPreview() {
if (m_shellRuntime != nullptr) {
m_shellRuntime->ClearExternalDockHostDropPreview();
}
2026-04-25 16:46:01 +08:00
}
bool EditorWorkspaceWindowContentController::TryResolveDockTabDragHotspot(
std::string_view nodeId,
std::string_view panelId,
const ::XCEngine::UI::UIPoint& point,
::XCEngine::UI::UIPoint& outHotspot) const {
return m_shellRuntime != nullptr &&
m_shellRuntime->TryResolveDockTabDragHotspot(
2026-04-25 16:46:01 +08:00
nodeId,
panelId,
point,
outHotspot);
}
UIEditorDockHostTabDropTarget EditorWorkspaceWindowContentController::ResolveDockTabDropTarget(
const ::XCEngine::UI::UIPoint& point) const {
return m_shellRuntime != nullptr
? m_shellRuntime->ResolveDockTabDropTarget(point)
: UIEditorDockHostTabDropTarget{};
2026-04-25 16:46:01 +08:00
}
bool EditorWorkspaceWindowContentController::HasHostedContentCapture() const {
return m_shellRuntime != nullptr && m_shellRuntime->HasHostedContentCapture();
2026-04-25 16:46:01 +08:00
}
bool EditorWorkspaceWindowContentController::HasShellInteractiveCapture() const {
return m_shellRuntime != nullptr && m_shellRuntime->HasShellInteractiveCapture();
2026-04-25 16:46:01 +08:00
}
bool EditorWorkspaceWindowContentController::HasInteractiveCapture() const {
return m_shellRuntime != nullptr && m_shellRuntime->HasInteractiveCapture();
2026-04-25 16:46:01 +08:00
}
EditorWindowContentCursorKind
EditorWorkspaceWindowContentController::GetHostedContentCursorKind() const {
return m_shellRuntime != nullptr
? ToContentCursorKind(m_shellRuntime->GetHostedContentCursorKind())
: EditorWindowContentCursorKind::Arrow;
2026-04-25 16:46:01 +08:00
}
EditorWindowContentCursorKind EditorWorkspaceWindowContentController::GetDockCursorKind() const {
return m_shellRuntime != nullptr
? ToContentCursorKind(m_shellRuntime->GetDockCursorKind())
: EditorWindowContentCursorKind::Arrow;
2026-04-25 16:46:01 +08:00
}
::XCEngine::UI::UISize EditorWorkspaceWindowContentController::ResolveMinimumOuterSize() const {
return m_projection.minimumOuterSize;
2026-04-25 16:46:01 +08:00
}
bool EditorWorkspaceWindowContentController::ShouldUseDetachedTitleBarTabStrip() const {
return m_projection.useDetachedTitleBarTabStrip;
2026-04-25 16:46:01 +08:00
}
std::string EditorWorkspaceWindowContentController::ResolveTabStripTitleText(
std::string_view fallbackTitle) const {
return m_projection.tabStripTitleText.empty()
? std::string(fallbackTitle)
: m_projection.tabStripTitleText;
2026-04-25 16:46:01 +08:00
}
std::string EditorWorkspaceWindowContentController::ResolveDetachedWindowTitleText(
std::string_view fallbackWindowTitle) const {
return m_projection.detachedWindowTitleText.empty()
? std::string(fallbackWindowTitle)
: m_projection.detachedWindowTitleText;
2026-04-25 16:46:01 +08:00
}
std::unique_ptr<EditorWindowContentController> CreateEditorWorkspaceWindowContentController(
2026-04-26 13:44:19 +08:00
const UIEditorWindowWorkspaceState& windowState,
2026-04-27 13:40:26 +08:00
EditorWindowSystem& windowSystem,
std::unique_ptr<EditorWorkspaceShellRuntime> shellRuntime) {
2026-04-25 16:46:01 +08:00
return std::make_unique<EditorWorkspaceWindowContentController>(
2026-04-26 13:44:19 +08:00
windowState,
2026-04-27 13:40:26 +08:00
windowSystem,
std::move(shellRuntime));
2026-04-25 16:46:01 +08:00
}
} // namespace XCEngine::UI::Editor::App