2026-04-15 10:47:57 +08:00
|
|
|
#include "Platform/Win32/EditorWindow.h"
|
|
|
|
|
#include "Platform/Win32/EditorWindowConstants.h"
|
|
|
|
|
#include "Platform/Win32/EditorWindowInputSupport.h"
|
|
|
|
|
#include "Platform/Win32/EditorWindowRuntimeSupport.h"
|
|
|
|
|
#include "Platform/Win32/EditorWindowStyle.h"
|
|
|
|
|
|
|
|
|
|
#include <sstream>
|
|
|
|
|
#include <utility>
|
|
|
|
|
|
|
|
|
|
namespace XCEngine::UI::Editor::App {
|
|
|
|
|
|
|
|
|
|
using namespace EditorWindowSupport;
|
|
|
|
|
using ::XCEngine::UI::UIDrawList;
|
|
|
|
|
using ::XCEngine::UI::UIInputEvent;
|
|
|
|
|
using ::XCEngine::UI::UIPoint;
|
|
|
|
|
using ::XCEngine::UI::UIRect;
|
|
|
|
|
|
|
|
|
|
void EditorWindow::RenderRuntimeFrame(
|
|
|
|
|
EditorContext& editorContext,
|
|
|
|
|
bool globalTabDragActive,
|
|
|
|
|
const UIRect& workspaceBounds,
|
|
|
|
|
UIDrawList& drawList) {
|
|
|
|
|
std::vector<UIInputEvent> frameEvents = std::move(m_input.pendingEvents);
|
|
|
|
|
m_input.pendingEvents.clear();
|
|
|
|
|
if (!frameEvents.empty() && IsVerboseRuntimeTraceEnabled()) {
|
|
|
|
|
LogRuntimeTrace(
|
|
|
|
|
"input",
|
|
|
|
|
DescribeInputEvents(frameEvents) + " | " +
|
|
|
|
|
editorContext.DescribeWorkspaceState(
|
|
|
|
|
m_composition.workspaceController,
|
|
|
|
|
m_composition.shellRuntime.GetShellInteractionState()));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const Host::D3D12WindowRenderLoopFrameContext frameContext =
|
|
|
|
|
m_render.windowRenderLoop.BeginFrame();
|
|
|
|
|
if (!frameContext.warning.empty()) {
|
|
|
|
|
LogRuntimeTrace("viewport", frameContext.warning);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
editorContext.AttachTextMeasurer(m_render.renderer);
|
2026-04-15 12:38:45 +08:00
|
|
|
const bool useDetachedTitleBarTabStrip = ShouldUseDetachedTitleBarTabStrip();
|
2026-04-15 10:47:57 +08:00
|
|
|
m_composition.shellRuntime.Update(
|
|
|
|
|
editorContext,
|
|
|
|
|
m_composition.workspaceController,
|
|
|
|
|
workspaceBounds,
|
|
|
|
|
frameEvents,
|
|
|
|
|
BuildCaptureStatusText(),
|
|
|
|
|
m_window.primary
|
|
|
|
|
? EditorShellVariant::Primary
|
2026-04-15 12:38:45 +08:00
|
|
|
: EditorShellVariant::DetachedWindow,
|
|
|
|
|
useDetachedTitleBarTabStrip,
|
|
|
|
|
useDetachedTitleBarTabStrip ? kBorderlessTitleBarHeightDips : 0.0f);
|
2026-04-15 10:47:57 +08:00
|
|
|
const UIEditorShellInteractionFrame& shellFrame =
|
|
|
|
|
m_composition.shellRuntime.GetShellFrame();
|
|
|
|
|
const UIEditorDockHostInteractionState& dockHostInteractionState =
|
|
|
|
|
m_composition.shellRuntime
|
|
|
|
|
.GetShellInteractionState()
|
|
|
|
|
.workspaceInteractionState
|
|
|
|
|
.dockHostInteractionState;
|
|
|
|
|
|
|
|
|
|
LogFrameInteractionTrace(editorContext, frameEvents, shellFrame);
|
|
|
|
|
QueueShellTransferRequests(globalTabDragActive, dockHostInteractionState, shellFrame);
|
|
|
|
|
|
|
|
|
|
ApplyHostCaptureRequests(shellFrame.result);
|
|
|
|
|
for (const WorkspaceTraceEntry& entry : m_composition.shellRuntime.GetTraceEntries()) {
|
|
|
|
|
LogRuntimeTrace(entry.channel, entry.message);
|
|
|
|
|
}
|
|
|
|
|
ApplyHostedContentCaptureRequests();
|
|
|
|
|
ApplyCurrentCursor();
|
|
|
|
|
m_composition.shellRuntime.Append(drawList);
|
|
|
|
|
if (frameContext.canRenderViewports) {
|
|
|
|
|
m_composition.shellRuntime.RenderRequestedViewports(frameContext.renderContext);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void EditorWindow::RenderInvalidFrame(
|
|
|
|
|
EditorContext& editorContext,
|
|
|
|
|
UIDrawList& drawList) const {
|
|
|
|
|
drawList.AddText(
|
|
|
|
|
UIPoint(28.0f, 28.0f),
|
|
|
|
|
"Editor shell asset invalid.",
|
|
|
|
|
EditorWindowSupport::kShellTextColor,
|
|
|
|
|
16.0f);
|
|
|
|
|
drawList.AddText(
|
|
|
|
|
UIPoint(28.0f, 54.0f),
|
|
|
|
|
editorContext.GetValidationMessage().empty()
|
|
|
|
|
? std::string("Unknown validation error.")
|
|
|
|
|
: editorContext.GetValidationMessage(),
|
|
|
|
|
EditorWindowSupport::kShellMutedTextColor,
|
|
|
|
|
12.0f);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void EditorWindow::LogFrameInteractionTrace(
|
|
|
|
|
EditorContext& editorContext,
|
|
|
|
|
const std::vector<UIInputEvent>& frameEvents,
|
|
|
|
|
const UIEditorShellInteractionFrame& shellFrame) const {
|
|
|
|
|
if (!IsVerboseRuntimeTraceEnabled() ||
|
|
|
|
|
(frameEvents.empty() &&
|
|
|
|
|
!shellFrame.result.workspaceResult.dockHostResult.layoutChanged &&
|
|
|
|
|
!shellFrame.result.workspaceResult.dockHostResult.commandExecuted)) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::ostringstream frameTrace = {};
|
|
|
|
|
frameTrace << "result consumed="
|
|
|
|
|
<< (shellFrame.result.consumed ? "true" : "false")
|
|
|
|
|
<< " layoutChanged="
|
|
|
|
|
<< (shellFrame.result.workspaceResult.dockHostResult.layoutChanged ? "true" : "false")
|
|
|
|
|
<< " commandExecuted="
|
|
|
|
|
<< (shellFrame.result.workspaceResult.dockHostResult.commandExecuted ? "true" : "false")
|
|
|
|
|
<< " active="
|
|
|
|
|
<< m_composition.workspaceController.GetWorkspace().activePanelId
|
|
|
|
|
<< " message="
|
|
|
|
|
<< shellFrame.result.workspaceResult.dockHostResult.layoutResult.message;
|
|
|
|
|
LogRuntimeTrace("frame", frameTrace.str());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void EditorWindow::QueueShellTransferRequests(
|
|
|
|
|
bool globalTabDragActive,
|
|
|
|
|
const UIEditorDockHostInteractionState& dockHostInteractionState,
|
|
|
|
|
const UIEditorShellInteractionFrame& shellFrame) {
|
|
|
|
|
if (!globalTabDragActive &&
|
|
|
|
|
!dockHostInteractionState.activeTabDragNodeId.empty() &&
|
|
|
|
|
!dockHostInteractionState.activeTabDragPanelId.empty()) {
|
|
|
|
|
QueuePendingTabDragStart(
|
|
|
|
|
dockHostInteractionState.activeTabDragNodeId,
|
|
|
|
|
dockHostInteractionState.activeTabDragPanelId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (shellFrame.result.workspaceResult.dockHostResult.detachRequested) {
|
|
|
|
|
QueuePendingDetachRequest(
|
|
|
|
|
shellFrame.result.workspaceResult.dockHostResult.detachedNodeId,
|
|
|
|
|
shellFrame.result.workspaceResult.dockHostResult.detachedPanelId);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // namespace XCEngine::UI::Editor::App
|