179 lines
6.6 KiB
C++
179 lines
6.6 KiB
C++
#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 <XCEngine/UI/DrawData.h>
|
|
|
|
#include <algorithm>
|
|
#include <sstream>
|
|
|
|
namespace XCEngine::UI::Editor::App {
|
|
|
|
using namespace EditorWindowSupport;
|
|
using ::XCEngine::UI::UIDrawData;
|
|
using ::XCEngine::UI::UIDrawList;
|
|
using ::XCEngine::UI::UIInputEvent;
|
|
using ::XCEngine::UI::UIPoint;
|
|
using ::XCEngine::UI::UIRect;
|
|
|
|
void EditorWindow::RenderFrame(
|
|
EditorContext& editorContext,
|
|
bool globalTabDragActive) {
|
|
if (!m_render.ready || m_window.hwnd == nullptr) {
|
|
return;
|
|
}
|
|
|
|
UINT pixelWidth = 0u;
|
|
UINT pixelHeight = 0u;
|
|
if (!ResolveRenderClientPixelSize(pixelWidth, pixelHeight)) {
|
|
return;
|
|
}
|
|
|
|
const float width = PixelsToDips(static_cast<float>(pixelWidth));
|
|
const float height = PixelsToDips(static_cast<float>(pixelHeight));
|
|
const UIRect workspaceBounds = ResolveWorkspaceBounds(width, height);
|
|
|
|
UIDrawData drawData = {};
|
|
UIDrawList& drawList = drawData.EmplaceDrawList("XCEditorShell");
|
|
drawList.AddFilledRect(
|
|
UIRect(0.0f, 0.0f, width, height),
|
|
kShellSurfaceColor);
|
|
|
|
if (editorContext.IsValid()) {
|
|
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);
|
|
m_composition.shellRuntime.Update(
|
|
editorContext,
|
|
m_composition.workspaceController,
|
|
workspaceBounds,
|
|
frameEvents,
|
|
BuildCaptureStatusText(),
|
|
m_window.primary
|
|
? EditorShellVariant::Primary
|
|
: EditorShellVariant::DetachedWindow);
|
|
const UIEditorShellInteractionFrame& shellFrame =
|
|
m_composition.shellRuntime.GetShellFrame();
|
|
const UIEditorDockHostInteractionState& dockHostInteractionState =
|
|
m_composition.shellRuntime
|
|
.GetShellInteractionState()
|
|
.workspaceInteractionState
|
|
.dockHostInteractionState;
|
|
if (IsVerboseRuntimeTraceEnabled() &&
|
|
(!frameEvents.empty() ||
|
|
shellFrame.result.workspaceResult.dockHostResult.layoutChanged ||
|
|
shellFrame.result.workspaceResult.dockHostResult.commandExecuted)) {
|
|
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());
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
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);
|
|
}
|
|
} else {
|
|
drawList.AddText(
|
|
UIPoint(28.0f, 28.0f),
|
|
"Editor shell asset invalid.",
|
|
kShellTextColor,
|
|
16.0f);
|
|
drawList.AddText(
|
|
UIPoint(28.0f, 54.0f),
|
|
editorContext.GetValidationMessage().empty()
|
|
? std::string("Unknown validation error.")
|
|
: editorContext.GetValidationMessage(),
|
|
kShellMutedTextColor,
|
|
12.0f);
|
|
}
|
|
|
|
AppendBorderlessWindowChrome(drawList, width);
|
|
|
|
const Host::D3D12WindowRenderLoopPresentResult presentResult =
|
|
m_render.windowRenderLoop.Present(drawData);
|
|
if (!presentResult.warning.empty()) {
|
|
LogRuntimeTrace("present", presentResult.warning);
|
|
}
|
|
|
|
m_render.autoScreenshot.CaptureIfRequested(
|
|
m_render.renderer,
|
|
drawData,
|
|
pixelWidth,
|
|
pixelHeight,
|
|
presentResult.framePresented);
|
|
}
|
|
|
|
void EditorWindow::OnPaintMessage(
|
|
EditorContext& editorContext,
|
|
bool globalTabDragActive) {
|
|
if (!m_render.ready || m_window.hwnd == nullptr) {
|
|
return;
|
|
}
|
|
|
|
PAINTSTRUCT paintStruct = {};
|
|
BeginPaint(m_window.hwnd, &paintStruct);
|
|
RenderFrame(editorContext, globalTabDragActive);
|
|
EndPaint(m_window.hwnd, &paintStruct);
|
|
}
|
|
|
|
UIRect EditorWindow::ResolveWorkspaceBounds(float clientWidthDips, float clientHeightDips) const {
|
|
if (!IsBorderlessWindowEnabled()) {
|
|
return UIRect(0.0f, 0.0f, clientWidthDips, clientHeightDips);
|
|
}
|
|
|
|
const float titleBarHeight = (std::min)(kBorderlessTitleBarHeightDips, clientHeightDips);
|
|
return UIRect(
|
|
0.0f,
|
|
titleBarHeight,
|
|
clientWidthDips,
|
|
(std::max)(0.0f, clientHeightDips - titleBarHeight));
|
|
}
|
|
|
|
} // namespace XCEngine::UI::Editor::App
|