refactor(new_editor): centralize win32 frame execution
This commit is contained in:
@@ -269,6 +269,7 @@ if(XCENGINE_BUILD_XCUI_EDITOR_APP)
|
||||
set(XCUI_EDITOR_APP_PLATFORM_SOURCES
|
||||
app/Platform/Win32/EditorWindow.cpp
|
||||
app/Platform/Win32/EditorWindowChromeController.cpp
|
||||
app/Platform/Win32/EditorWindowFrameDriver.cpp
|
||||
app/Platform/Win32/EditorWindowFrameOrchestrator.cpp
|
||||
app/Platform/Win32/EditorWindowInputController.cpp
|
||||
app/Platform/Win32/EditorWindowRuntimeController.cpp
|
||||
|
||||
@@ -222,12 +222,16 @@ bool EditorWindow::Initialize(
|
||||
<< " scale=" << GetDpiScale();
|
||||
LogRuntimeTrace("window", dpiTrace.str());
|
||||
|
||||
return m_runtime->Initialize(
|
||||
const bool initialized = m_runtime->Initialize(
|
||||
m_state->window.hwnd,
|
||||
repoRoot,
|
||||
editorContext,
|
||||
captureRoot,
|
||||
autoCaptureOnStartup);
|
||||
if (initialized) {
|
||||
RequestFrame(EditorWindowFrameRequestReason::Initial);
|
||||
}
|
||||
return initialized;
|
||||
}
|
||||
|
||||
void EditorWindow::Shutdown() {
|
||||
@@ -385,6 +389,7 @@ void EditorWindow::OnResize(UINT width, UINT height) {
|
||||
if (!matchesPredictedClientSize) {
|
||||
ApplyWindowResize(width, height);
|
||||
}
|
||||
RequestFrame(EditorWindowFrameRequestReason::Resize);
|
||||
}
|
||||
|
||||
void EditorWindow::OnEnterSizeMove() {
|
||||
@@ -399,6 +404,7 @@ void EditorWindow::OnExitSizeMove() {
|
||||
if (QueryCurrentClientPixelSize(width, height)) {
|
||||
ApplyWindowResize(width, height);
|
||||
}
|
||||
RequestFrame(EditorWindowFrameRequestReason::ExitSizeMove);
|
||||
}
|
||||
|
||||
void EditorWindow::OnDpiChanged(UINT dpi, const RECT& suggestedRect) {
|
||||
@@ -427,6 +433,7 @@ void EditorWindow::OnDpiChanged(UINT dpi, const RECT& suggestedRect) {
|
||||
trace << "dpi changed to " << m_chromeController->GetWindowDpi()
|
||||
<< " scale=" << GetDpiScale();
|
||||
LogRuntimeTrace("window", trace.str());
|
||||
RequestFrame(EditorWindowFrameRequestReason::DpiChanged);
|
||||
}
|
||||
|
||||
bool EditorWindow::IsVerboseRuntimeTraceEnabled() {
|
||||
@@ -651,19 +658,15 @@ EditorWindowFrameTransferRequests EditorWindow::RenderFrame(
|
||||
return transferRequests;
|
||||
}
|
||||
|
||||
EditorWindowFrameTransferRequests EditorWindow::OnPaintMessage(
|
||||
EditorContext& editorContext,
|
||||
bool globalTabDragActive) {
|
||||
void EditorWindow::OnPaintMessage() {
|
||||
if (!m_runtime->IsReady() || m_state->window.hwnd == nullptr) {
|
||||
return {};
|
||||
return;
|
||||
}
|
||||
|
||||
PAINTSTRUCT paintStruct = {};
|
||||
BeginPaint(m_state->window.hwnd, &paintStruct);
|
||||
const EditorWindowFrameTransferRequests transferRequests =
|
||||
RenderFrame(editorContext, globalTabDragActive);
|
||||
EndPaint(m_state->window.hwnd, &paintStruct);
|
||||
return transferRequests;
|
||||
RequestFrame(EditorWindowFrameRequestReason::PaintMessage);
|
||||
}
|
||||
|
||||
UIRect EditorWindow::ResolveWorkspaceBounds(float clientWidthDips, float clientHeightDips) const {
|
||||
@@ -926,6 +929,17 @@ void EditorWindow::ResetInputModifiers() {
|
||||
|
||||
void EditorWindow::RequestManualScreenshot() {
|
||||
m_runtime->RequestManualScreenshot("manual_f12");
|
||||
RequestFrame(EditorWindowFrameRequestReason::ManualScreenshot);
|
||||
}
|
||||
|
||||
void EditorWindow::RequestFrame(EditorWindowFrameRequestReason reason) {
|
||||
m_pendingFrameRequestReasons |= ToFrameRequestMask(reason);
|
||||
}
|
||||
|
||||
std::uint32_t EditorWindow::ConsumePendingFrameRequestReasons() {
|
||||
const std::uint32_t pendingFrameRequestReasons = m_pendingFrameRequestReasons;
|
||||
m_pendingFrameRequestReasons = 0u;
|
||||
return pendingFrameRequestReasons;
|
||||
}
|
||||
|
||||
bool EditorWindow::IsPointerInsideClientArea() const {
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#endif
|
||||
|
||||
#include "Platform/Win32/EditorWindowPointerCapture.h"
|
||||
#include "Platform/Win32/EditorWindowFrameRequest.h"
|
||||
#include "Platform/Win32/EditorWindowTransferRequests.h"
|
||||
|
||||
#include <windows.h>
|
||||
@@ -61,6 +62,7 @@ namespace XCEngine::UI::Editor::App {
|
||||
class EditorContext;
|
||||
class EditorShellRuntime;
|
||||
class EditorWindowChromeController;
|
||||
class EditorWindowFrameDriver;
|
||||
class EditorWindowFrameOrchestrator;
|
||||
class EditorWindowHostRuntime;
|
||||
class EditorWindowInputController;
|
||||
@@ -95,6 +97,7 @@ public:
|
||||
|
||||
private:
|
||||
friend class EditorWindowChromeController;
|
||||
friend class EditorWindowFrameDriver;
|
||||
friend class EditorWindowHostRuntime;
|
||||
friend class EditorWindowMessageDispatcher;
|
||||
friend class EditorWindowWorkspaceCoordinator;
|
||||
@@ -135,13 +138,13 @@ private:
|
||||
bool autoCaptureOnStartup);
|
||||
void Shutdown();
|
||||
void ResetInteractionState();
|
||||
void RequestFrame(EditorWindowFrameRequestReason reason);
|
||||
std::uint32_t ConsumePendingFrameRequestReasons();
|
||||
|
||||
EditorWindowFrameTransferRequests RenderFrame(
|
||||
EditorContext& editorContext,
|
||||
bool globalTabDragActive);
|
||||
EditorWindowFrameTransferRequests OnPaintMessage(
|
||||
EditorContext& editorContext,
|
||||
bool globalTabDragActive);
|
||||
void OnPaintMessage();
|
||||
void OnResize(UINT width, UINT height);
|
||||
void OnEnterSizeMove();
|
||||
void OnExitSizeMove();
|
||||
@@ -253,6 +256,7 @@ private:
|
||||
std::unique_ptr<EditorWindowFrameOrchestrator> m_frameOrchestrator = {};
|
||||
std::unique_ptr<EditorWindowInputController> m_inputController = {};
|
||||
std::unique_ptr<EditorWindowRuntimeController> m_runtime = {};
|
||||
std::uint32_t m_pendingFrameRequestReasons = 0u;
|
||||
};
|
||||
|
||||
} // namespace XCEngine::UI::Editor::App
|
||||
|
||||
@@ -400,6 +400,8 @@ bool EditorWindowChromeController::HandleResizePointerMove(
|
||||
EditorWindow& window,
|
||||
EditorContext& editorContext,
|
||||
bool globalTabDragActive) {
|
||||
(void)editorContext;
|
||||
(void)globalTabDragActive;
|
||||
if (!IsBorderlessResizeActive() ||
|
||||
window.m_state->window.hwnd == nullptr) {
|
||||
return false;
|
||||
@@ -428,7 +430,7 @@ bool EditorWindowChromeController::HandleResizePointerMove(
|
||||
static_cast<UINT>(width),
|
||||
static_cast<UINT>(height));
|
||||
window.ApplyWindowResize(static_cast<UINT>(width), static_cast<UINT>(height));
|
||||
(void)window.RenderFrame(editorContext, globalTabDragActive);
|
||||
window.RequestFrame(EditorWindowFrameRequestReason::BorderlessTransition);
|
||||
|
||||
SetWindowPos(
|
||||
window.m_state->window.hwnd,
|
||||
@@ -897,6 +899,8 @@ bool EditorWindowChromeController::ApplyPredictedWindowRectTransition(
|
||||
EditorContext& editorContext,
|
||||
bool globalTabDragActive,
|
||||
const RECT& targetRect) {
|
||||
(void)editorContext;
|
||||
(void)globalTabDragActive;
|
||||
if (window.m_state->window.hwnd == nullptr) {
|
||||
return false;
|
||||
}
|
||||
@@ -909,7 +913,6 @@ bool EditorWindowChromeController::ApplyPredictedWindowRectTransition(
|
||||
|
||||
SetPredictedClientPixelSize(static_cast<UINT>(width), static_cast<UINT>(height));
|
||||
window.ApplyWindowResize(static_cast<UINT>(width), static_cast<UINT>(height));
|
||||
(void)window.RenderFrame(editorContext, globalTabDragActive);
|
||||
SetWindowPos(
|
||||
window.m_state->window.hwnd,
|
||||
nullptr,
|
||||
@@ -918,6 +921,7 @@ bool EditorWindowChromeController::ApplyPredictedWindowRectTransition(
|
||||
width,
|
||||
height,
|
||||
SWP_NOZORDER | SWP_NOACTIVATE);
|
||||
window.RequestFrame(EditorWindowFrameRequestReason::BorderlessTransition);
|
||||
window.InvalidateHostWindow();
|
||||
return true;
|
||||
}
|
||||
|
||||
29
new_editor/app/Platform/Win32/EditorWindowFrameDriver.cpp
Normal file
29
new_editor/app/Platform/Win32/EditorWindowFrameDriver.cpp
Normal file
@@ -0,0 +1,29 @@
|
||||
#include "Platform/Win32/EditorWindowFrameDriver.h"
|
||||
|
||||
#include "Platform/Win32/EditorWindow.h"
|
||||
|
||||
namespace XCEngine::UI::Editor::App {
|
||||
|
||||
EditorWindowFrameTransferRequests EditorWindowFrameDriver::DriveFrame(
|
||||
EditorWindow& window,
|
||||
EditorContext& editorContext,
|
||||
bool globalTabDragActive) {
|
||||
if (!window.IsRenderReady() ||
|
||||
window.GetHwnd() == nullptr ||
|
||||
window.IsClosing()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
(void)window.ConsumePendingFrameRequestReasons();
|
||||
|
||||
EditorWindowFrameTransferRequests transferRequests =
|
||||
window.RenderFrame(editorContext, globalTabDragActive);
|
||||
if (const HWND hwnd = window.GetHwnd();
|
||||
hwnd != nullptr && IsWindow(hwnd)) {
|
||||
ValidateRect(hwnd, nullptr);
|
||||
}
|
||||
|
||||
return transferRequests;
|
||||
}
|
||||
|
||||
} // namespace XCEngine::UI::Editor::App
|
||||
18
new_editor/app/Platform/Win32/EditorWindowFrameDriver.h
Normal file
18
new_editor/app/Platform/Win32/EditorWindowFrameDriver.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include "Platform/Win32/EditorWindowTransferRequests.h"
|
||||
|
||||
namespace XCEngine::UI::Editor::App {
|
||||
|
||||
class EditorContext;
|
||||
class EditorWindow;
|
||||
|
||||
class EditorWindowFrameDriver final {
|
||||
public:
|
||||
static EditorWindowFrameTransferRequests DriveFrame(
|
||||
EditorWindow& window,
|
||||
EditorContext& editorContext,
|
||||
bool globalTabDragActive);
|
||||
};
|
||||
|
||||
} // namespace XCEngine::UI::Editor::App
|
||||
22
new_editor/app/Platform/Win32/EditorWindowFrameRequest.h
Normal file
22
new_editor/app/Platform/Win32/EditorWindowFrameRequest.h
Normal file
@@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace XCEngine::UI::Editor::App {
|
||||
|
||||
enum class EditorWindowFrameRequestReason : std::uint32_t {
|
||||
None = 0u,
|
||||
Initial = 1u << 0u,
|
||||
PaintMessage = 1u << 1u,
|
||||
Resize = 1u << 2u,
|
||||
DpiChanged = 1u << 3u,
|
||||
ExitSizeMove = 1u << 4u,
|
||||
BorderlessTransition = 1u << 5u,
|
||||
ManualScreenshot = 1u << 6u
|
||||
};
|
||||
|
||||
constexpr std::uint32_t ToFrameRequestMask(EditorWindowFrameRequestReason reason) {
|
||||
return static_cast<std::uint32_t>(reason);
|
||||
}
|
||||
|
||||
} // namespace XCEngine::UI::Editor::App
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "Bootstrap/EditorResources.h"
|
||||
#include "Composition/EditorContext.h"
|
||||
#include "Platform/Win32/EditorWindow.h"
|
||||
#include "Platform/Win32/EditorWindowFrameDriver.h"
|
||||
#include "Platform/Win32/WindowManager/EditorWindowWorkspaceCoordinator.h"
|
||||
|
||||
#include <XCEditor/Foundation/UIEditorRuntimeTrace.h>
|
||||
@@ -234,7 +235,10 @@ void EditorWindowHostRuntime::RenderAllWindows(
|
||||
}
|
||||
|
||||
EditorWindowFrameTransferRequests transferRequests =
|
||||
window->RenderFrame(m_editorContext, globalTabDragActive);
|
||||
EditorWindowFrameDriver::DriveFrame(
|
||||
*window,
|
||||
m_editorContext,
|
||||
globalTabDragActive);
|
||||
workspaceCoordinator.CommitWindowProjection(*window);
|
||||
if (!transferRequests.HasPendingRequests()) {
|
||||
continue;
|
||||
|
||||
@@ -59,24 +59,6 @@ struct EditorWindowMessageDispatcher::DispatchContext {
|
||||
EditorWindow& window;
|
||||
};
|
||||
|
||||
void EditorWindowMessageDispatcher::RenderAndValidateWindow(const DispatchContext& context) {
|
||||
if (!context.window.IsRenderReady()) {
|
||||
return;
|
||||
}
|
||||
|
||||
EditorWindowFrameTransferRequests transferRequests = context.window.RenderFrame(
|
||||
context.hostRuntime.GetEditorContext(),
|
||||
context.workspaceCoordinator.IsGlobalTabDragActive());
|
||||
if (transferRequests.HasPendingRequests()) {
|
||||
context.workspaceCoordinator.HandleWindowFrameTransferRequests(
|
||||
context.window,
|
||||
std::move(transferRequests));
|
||||
}
|
||||
if (context.hwnd != nullptr && IsWindow(context.hwnd)) {
|
||||
ValidateRect(context.hwnd, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
bool EditorWindowMessageDispatcher::EnsureTrackingMouseLeave(const DispatchContext& context) {
|
||||
if (context.window.IsTrackingMouseLeave()) {
|
||||
return true;
|
||||
@@ -399,7 +381,7 @@ bool EditorWindowMessageDispatcher::TryDispatchWindowLifecycleMessage(
|
||||
context.window.OnDpiChanged(
|
||||
static_cast<UINT>(LOWORD(wParam)),
|
||||
*reinterpret_cast<const RECT*>(lParam));
|
||||
RenderAndValidateWindow(context);
|
||||
context.window.InvalidateHostWindow();
|
||||
outResult = 0;
|
||||
return true;
|
||||
case WM_ENTERSIZEMOVE:
|
||||
@@ -408,7 +390,7 @@ bool EditorWindowMessageDispatcher::TryDispatchWindowLifecycleMessage(
|
||||
return true;
|
||||
case WM_EXITSIZEMOVE:
|
||||
context.window.OnExitSizeMove();
|
||||
RenderAndValidateWindow(context);
|
||||
context.window.InvalidateHostWindow();
|
||||
outResult = 0;
|
||||
return true;
|
||||
case WM_SIZE:
|
||||
@@ -416,7 +398,7 @@ bool EditorWindowMessageDispatcher::TryDispatchWindowLifecycleMessage(
|
||||
context.window.OnResize(
|
||||
static_cast<UINT>(LOWORD(lParam)),
|
||||
static_cast<UINT>(HIWORD(lParam)));
|
||||
RenderAndValidateWindow(context);
|
||||
context.window.InvalidateHostWindow();
|
||||
}
|
||||
outResult = 0;
|
||||
return true;
|
||||
@@ -436,14 +418,7 @@ bool EditorWindowMessageDispatcher::TryDispatchWindowLifecycleMessage(
|
||||
outResult = 0;
|
||||
return true;
|
||||
case WM_PAINT:
|
||||
if (EditorWindowFrameTransferRequests transferRequests = context.window.OnPaintMessage(
|
||||
context.hostRuntime.GetEditorContext(),
|
||||
context.workspaceCoordinator.IsGlobalTabDragActive());
|
||||
transferRequests.HasPendingRequests()) {
|
||||
context.workspaceCoordinator.HandleWindowFrameTransferRequests(
|
||||
context.window,
|
||||
std::move(transferRequests));
|
||||
}
|
||||
context.window.OnPaintMessage();
|
||||
outResult = 0;
|
||||
return true;
|
||||
case WM_ERASEBKGND:
|
||||
|
||||
@@ -30,7 +30,6 @@ public:
|
||||
private:
|
||||
struct DispatchContext;
|
||||
|
||||
static void RenderAndValidateWindow(const DispatchContext& context);
|
||||
static bool EnsureTrackingMouseLeave(const DispatchContext& context);
|
||||
static bool TryHandleChromeHoverConsumption(
|
||||
const DispatchContext& context,
|
||||
|
||||
Reference in New Issue
Block a user