refactor(new_editor): introduce win32 window session state
This commit is contained in:
@@ -242,6 +242,7 @@ if(XCENGINE_BUILD_XCUI_EDITOR_APP)
|
||||
set(XCUI_EDITOR_APP_PLATFORM_SOURCES
|
||||
app/Platform/Win32/Windowing/EditorWindow.cpp
|
||||
app/Platform/Win32/Windowing/EditorFloatingWindowPlacement.cpp
|
||||
app/Platform/Win32/Windowing/EditorWindowSession.cpp
|
||||
app/Platform/Win32/Content/EditorUtilityWindowContentController.cpp
|
||||
app/Platform/Win32/Chrome/EditorWindowChromeController.cpp
|
||||
app/Platform/Win32/Runtime/EditorWindowFrameDriver.cpp
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
#include "Platform/Win32/Windowing/EditorWindow.h"
|
||||
#include "Platform/Win32/Runtime/EditorWindowFrameDriver.h"
|
||||
#include "Platform/Win32/Runtime/EditorWindowRuntimeController.h"
|
||||
#include "Platform/Win32/Windowing/EditorWindowState.h"
|
||||
#include "Platform/Win32/Windowing/EditorWindowSupport.h"
|
||||
|
||||
#include <XCEditor/Foundation/UIEditorTheme.h>
|
||||
@@ -233,12 +232,13 @@ bool EditorWindowChromeController::HandleSystemCommand(
|
||||
EditorContext& editorContext,
|
||||
bool globalTabDragActive,
|
||||
WPARAM wParam) {
|
||||
const HWND hwnd = window.GetHwnd();
|
||||
switch (wParam & 0xFFF0u) {
|
||||
case SC_MAXIMIZE:
|
||||
ToggleMaximizeRestore(window, editorContext, globalTabDragActive);
|
||||
return true;
|
||||
case SC_RESTORE:
|
||||
if (!IsIconic(window.m_state->window.hwnd)) {
|
||||
if (hwnd != nullptr && !IsIconic(hwnd)) {
|
||||
ToggleMaximizeRestore(window, editorContext, globalTabDragActive);
|
||||
return true;
|
||||
}
|
||||
@@ -253,7 +253,7 @@ bool EditorWindowChromeController::HandleGetMinMaxInfo(
|
||||
LPARAM lParam) const {
|
||||
const ::XCEngine::UI::UISize minimumOuterSize = window.m_runtime->ResolveMinimumOuterSize();
|
||||
return Host::HandleBorderlessWindowGetMinMaxInfo(
|
||||
window.m_state->window.hwnd,
|
||||
window.GetHwnd(),
|
||||
lParam,
|
||||
static_cast<int>(minimumOuterSize.width),
|
||||
static_cast<int>(minimumOuterSize.height));
|
||||
@@ -264,7 +264,7 @@ LRESULT EditorWindowChromeController::HandleNcCalcSize(
|
||||
WPARAM wParam,
|
||||
LPARAM lParam) const {
|
||||
return Host::HandleBorderlessWindowNcCalcSize(
|
||||
window.m_state->window.hwnd,
|
||||
window.GetHwnd(),
|
||||
wParam,
|
||||
lParam,
|
||||
GetWindowDpi());
|
||||
@@ -283,8 +283,8 @@ bool EditorWindowChromeController::UpdateResizeHover(EditorWindow& window, LPARA
|
||||
|
||||
bool EditorWindowChromeController::HandleResizeButtonDown(EditorWindow& window, LPARAM lParam) {
|
||||
const Host::BorderlessWindowResizeEdge edge = HitTestResizeEdge(window, lParam);
|
||||
if (edge == Host::BorderlessWindowResizeEdge::None ||
|
||||
window.m_state->window.hwnd == nullptr) {
|
||||
const HWND hwnd = window.GetHwnd();
|
||||
if (edge == Host::BorderlessWindowResizeEdge::None || hwnd == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -294,7 +294,7 @@ bool EditorWindowChromeController::HandleResizeButtonDown(EditorWindow& window,
|
||||
}
|
||||
|
||||
RECT windowRect = {};
|
||||
if (!GetWindowRect(window.m_state->window.hwnd, &windowRect)) {
|
||||
if (!GetWindowRect(hwnd, &windowRect)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -319,8 +319,8 @@ bool EditorWindowChromeController::HandleResizePointerMove(
|
||||
EditorWindow& window,
|
||||
EditorContext& editorContext,
|
||||
bool globalTabDragActive) {
|
||||
if (!IsBorderlessResizeActive() ||
|
||||
window.m_state->window.hwnd == nullptr) {
|
||||
const HWND hwnd = window.GetHwnd();
|
||||
if (!IsBorderlessResizeActive() || hwnd == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -380,14 +380,14 @@ bool EditorWindowChromeController::HandleResizePointerMove(
|
||||
|
||||
const auto setWindowPosBegin = std::chrono::steady_clock::now();
|
||||
SetWindowPos(
|
||||
window.m_state->window.hwnd,
|
||||
hwnd,
|
||||
nullptr,
|
||||
targetRect.left,
|
||||
targetRect.top,
|
||||
width,
|
||||
height,
|
||||
SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOCOPYBITS | SWP_NOREDRAW);
|
||||
ValidateRect(window.m_state->window.hwnd, nullptr);
|
||||
ValidateRect(hwnd, nullptr);
|
||||
if (IsVerboseResizeTraceEnabled()) {
|
||||
const auto totalEnd = std::chrono::steady_clock::now();
|
||||
const auto setWindowPosMs =
|
||||
@@ -434,12 +434,13 @@ void EditorWindowChromeController::ForceClearResizeState(EditorWindow& window) {
|
||||
Host::BorderlessWindowResizeEdge EditorWindowChromeController::HitTestResizeEdge(
|
||||
const EditorWindow& window,
|
||||
LPARAM lParam) const {
|
||||
if (window.m_state->window.hwnd == nullptr || IsBorderlessWindowMaximized()) {
|
||||
const HWND hwnd = window.GetHwnd();
|
||||
if (hwnd == nullptr || IsBorderlessWindowMaximized()) {
|
||||
return Host::BorderlessWindowResizeEdge::None;
|
||||
}
|
||||
|
||||
RECT clientRect = {};
|
||||
if (!GetClientRect(window.m_state->window.hwnd, &clientRect)) {
|
||||
if (!GetClientRect(hwnd, &clientRect)) {
|
||||
return Host::BorderlessWindowResizeEdge::None;
|
||||
}
|
||||
|
||||
@@ -482,6 +483,7 @@ bool EditorWindowChromeController::HandleChromeButtonDown(EditorWindow& window,
|
||||
return false;
|
||||
}
|
||||
|
||||
const HWND hwnd = window.GetHwnd();
|
||||
const Host::BorderlessWindowChromeHitTarget hitTarget = HitTestChrome(window, lParam);
|
||||
switch (hitTarget) {
|
||||
case Host::BorderlessWindowChromeHitTarget::MinimizeButton:
|
||||
@@ -492,7 +494,7 @@ bool EditorWindowChromeController::HandleChromeButtonDown(EditorWindow& window,
|
||||
window.InvalidateHostWindow();
|
||||
return true;
|
||||
case Host::BorderlessWindowChromeHitTarget::DragRegion:
|
||||
if (window.m_state->window.hwnd != nullptr) {
|
||||
if (hwnd != nullptr) {
|
||||
if (IsBorderlessWindowMaximized()) {
|
||||
POINT screenPoint = {};
|
||||
if (GetCursorPos(&screenPoint)) {
|
||||
@@ -503,7 +505,7 @@ bool EditorWindowChromeController::HandleChromeButtonDown(EditorWindow& window,
|
||||
}
|
||||
|
||||
window.ForceReleasePointerCapture();
|
||||
SendMessageW(window.m_state->window.hwnd, WM_NCLBUTTONDOWN, HTCAPTION, 0);
|
||||
SendMessageW(hwnd, WM_NCLBUTTONDOWN, HTCAPTION, 0);
|
||||
}
|
||||
return true;
|
||||
case Host::BorderlessWindowChromeHitTarget::None:
|
||||
@@ -565,8 +567,8 @@ bool EditorWindowChromeController::HandleChromeDragRestorePointerMove(
|
||||
EditorWindow& window,
|
||||
EditorContext& editorContext,
|
||||
bool globalTabDragActive) {
|
||||
if (!IsBorderlessWindowDragRestoreArmed() ||
|
||||
window.m_state->window.hwnd == nullptr) {
|
||||
const HWND hwnd = window.GetHwnd();
|
||||
if (!IsBorderlessWindowDragRestoreArmed() || hwnd == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -630,7 +632,7 @@ bool EditorWindowChromeController::HandleChromeDragRestorePointerMove(
|
||||
SetBorderlessWindowMaximized(false);
|
||||
ApplyPredictedWindowRectTransition(window, editorContext, globalTabDragActive, targetRect);
|
||||
ClearChromeDragRestoreState(window);
|
||||
SendMessageW(window.m_state->window.hwnd, WM_NCLBUTTONDOWN, HTCAPTION, 0);
|
||||
SendMessageW(hwnd, WM_NCLBUTTONDOWN, HTCAPTION, 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -655,12 +657,13 @@ void EditorWindowChromeController::ClearChromeState(EditorWindow& window) {
|
||||
Host::BorderlessWindowChromeHitTarget EditorWindowChromeController::HitTestChrome(
|
||||
const EditorWindow& window,
|
||||
LPARAM lParam) const {
|
||||
if (window.m_state->window.hwnd == nullptr) {
|
||||
const HWND hwnd = window.GetHwnd();
|
||||
if (hwnd == nullptr) {
|
||||
return Host::BorderlessWindowChromeHitTarget::None;
|
||||
}
|
||||
|
||||
RECT clientRect = {};
|
||||
if (!GetClientRect(window.m_state->window.hwnd, &clientRect)) {
|
||||
if (!GetClientRect(hwnd, &clientRect)) {
|
||||
return Host::BorderlessWindowChromeHitTarget::None;
|
||||
}
|
||||
|
||||
@@ -695,7 +698,7 @@ Host::BorderlessWindowChromeLayout EditorWindowChromeController::ResolveChromeLa
|
||||
bool EditorWindowChromeController::ShouldUseDetachedTitleBarTabStrip(
|
||||
const EditorWindow& window) const {
|
||||
const EditorWindowTitleBarBinding* titleBarBinding = window.m_runtime->TryGetTitleBarBinding();
|
||||
return !window.m_state->window.primary &&
|
||||
return !window.IsPrimary() &&
|
||||
titleBarBinding != nullptr &&
|
||||
titleBarBinding->ShouldUseDetachedTitleBarTabStrip();
|
||||
}
|
||||
@@ -718,7 +721,7 @@ void EditorWindowChromeController::AppendChrome(
|
||||
1.0f);
|
||||
}
|
||||
|
||||
if (!window.m_state->window.primary) {
|
||||
if (!window.IsPrimary()) {
|
||||
if (useDetachedTitleBarTabStrip) {
|
||||
if (window.m_runtime->GetTitleBarLogoIcon().IsValid()) {
|
||||
drawList.AddImage(
|
||||
@@ -750,10 +753,11 @@ void EditorWindowChromeController::AppendChrome(
|
||||
(layout.titleBarRect.height - kBorderlessTitleBarFontSize) * 0.5f -
|
||||
1.0f)),
|
||||
[&window]() {
|
||||
const std::string_view cachedTitleText = window.GetCachedTitleText();
|
||||
const std::string_view fallbackWindowTitle =
|
||||
window.m_state->window.titleText.empty()
|
||||
cachedTitleText.empty()
|
||||
? std::string_view("XCEngine Editor")
|
||||
: std::string_view(window.m_state->window.titleText);
|
||||
: cachedTitleText;
|
||||
const EditorWindowTitleBarBinding* titleBarBinding =
|
||||
window.m_runtime->TryGetTitleBarBinding();
|
||||
return titleBarBinding != nullptr
|
||||
@@ -775,10 +779,10 @@ void EditorWindowChromeController::AppendChrome(
|
||||
UIColor(1.0f, 1.0f, 1.0f, 1.0f));
|
||||
}
|
||||
|
||||
const std::string titleText =
|
||||
window.m_state->window.titleText.empty()
|
||||
const std::string_view cachedTitleText = window.GetCachedTitleText();
|
||||
const std::string titleText = cachedTitleText.empty()
|
||||
? std::string("XCEngine Editor")
|
||||
: window.m_state->window.titleText;
|
||||
: std::string(cachedTitleText);
|
||||
const std::string frameRateText = window.m_runtime->BuildFrameRateText();
|
||||
drawList.AddText(
|
||||
UIPoint(
|
||||
@@ -834,20 +838,20 @@ bool EditorWindowChromeController::QueryCurrentWindowRect(
|
||||
const EditorWindow& window,
|
||||
RECT& outRect) const {
|
||||
outRect = {};
|
||||
return window.m_state->window.hwnd != nullptr &&
|
||||
GetWindowRect(window.m_state->window.hwnd, &outRect) != FALSE;
|
||||
const HWND hwnd = window.GetHwnd();
|
||||
return hwnd != nullptr && GetWindowRect(hwnd, &outRect) != FALSE;
|
||||
}
|
||||
|
||||
bool EditorWindowChromeController::QueryBorderlessWindowWorkAreaRect(
|
||||
const EditorWindow& window,
|
||||
RECT& outRect) const {
|
||||
outRect = {};
|
||||
if (window.m_state->window.hwnd == nullptr) {
|
||||
const HWND hwnd = window.GetHwnd();
|
||||
if (hwnd == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const HMONITOR monitor =
|
||||
MonitorFromWindow(window.m_state->window.hwnd, MONITOR_DEFAULTTONEAREST);
|
||||
const HMONITOR monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
|
||||
if (monitor == nullptr) {
|
||||
return false;
|
||||
}
|
||||
@@ -867,7 +871,8 @@ bool EditorWindowChromeController::ApplyPredictedWindowRectTransition(
|
||||
EditorContext& editorContext,
|
||||
bool globalTabDragActive,
|
||||
const RECT& targetRect) {
|
||||
if (window.m_state->window.hwnd == nullptr) {
|
||||
const HWND hwnd = window.GetHwnd();
|
||||
if (hwnd == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -887,7 +892,7 @@ bool EditorWindowChromeController::ApplyPredictedWindowRectTransition(
|
||||
MarkPredictedClientPixelSizePresented();
|
||||
}
|
||||
SetWindowPos(
|
||||
window.m_state->window.hwnd,
|
||||
hwnd,
|
||||
nullptr,
|
||||
targetRect.left,
|
||||
targetRect.top,
|
||||
@@ -902,7 +907,7 @@ void EditorWindowChromeController::ToggleMaximizeRestore(
|
||||
EditorWindow& window,
|
||||
EditorContext& editorContext,
|
||||
bool globalTabDragActive) {
|
||||
if (window.m_state->window.hwnd == nullptr) {
|
||||
if (window.GetHwnd() == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -934,19 +939,20 @@ void EditorWindowChromeController::ExecuteChromeAction(
|
||||
EditorContext& editorContext,
|
||||
bool globalTabDragActive,
|
||||
Host::BorderlessWindowChromeHitTarget target) {
|
||||
if (window.m_state->window.hwnd == nullptr) {
|
||||
const HWND hwnd = window.GetHwnd();
|
||||
if (hwnd == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (target) {
|
||||
case Host::BorderlessWindowChromeHitTarget::MinimizeButton:
|
||||
ShowWindow(window.m_state->window.hwnd, SW_MINIMIZE);
|
||||
ShowWindow(hwnd, SW_MINIMIZE);
|
||||
break;
|
||||
case Host::BorderlessWindowChromeHitTarget::MaximizeRestoreButton:
|
||||
ToggleMaximizeRestore(window, editorContext, globalTabDragActive);
|
||||
break;
|
||||
case Host::BorderlessWindowChromeHitTarget::CloseButton:
|
||||
PostMessageW(window.m_state->window.hwnd, WM_CLOSE, 0, 0);
|
||||
PostMessageW(hwnd, WM_CLOSE, 0, 0);
|
||||
break;
|
||||
case Host::BorderlessWindowChromeHitTarget::DragRegion:
|
||||
case Host::BorderlessWindowChromeHitTarget::None:
|
||||
|
||||
@@ -23,7 +23,7 @@ EditorWindowFrameTransferRequests EditorWindowFrameDriver::DriveFrameInternal(
|
||||
ValidateRect(hwnd, nullptr);
|
||||
}
|
||||
if (requestSkipNextSteadyStateFrame) {
|
||||
window.m_chromeController->RequestSkipNextSteadyStateFrame();
|
||||
window.RequestSkipNextSteadyStateFrame();
|
||||
}
|
||||
|
||||
return transferRequests;
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
#include "Platform/Win32/Chrome/EditorWindowChromeController.h"
|
||||
#include "Platform/Win32/Content/EditorWindowContentController.h"
|
||||
#include "Platform/Win32/Runtime/EditorWindowFrameDriver.h"
|
||||
#include "Platform/Win32/Windowing/EditorWindowSession.h"
|
||||
#include "Platform/Win32/Windowing/EditorWindowSupport.h"
|
||||
#include "Platform/Win32/Runtime/EditorWindowFrameOrchestrator.h"
|
||||
#include "Platform/Win32/Runtime/EditorWindowInputController.h"
|
||||
#include "Platform/Win32/Windowing/EditorWindowState.h"
|
||||
#include "Platform/Win32/Runtime/EditorWindowRuntimeController.h"
|
||||
#include "Composition/EditorContext.h"
|
||||
#include <XCEditor/Docking/UIEditorDockHostTransfer.h>
|
||||
@@ -79,46 +79,44 @@ EditorWindow::EditorWindow(
|
||||
std::wstring title,
|
||||
bool primary,
|
||||
std::unique_ptr<EditorWindowContentController> contentController)
|
||||
: m_state(std::make_unique<EditorWindowState>())
|
||||
: m_session(std::make_unique<EditorWindowSession>(
|
||||
std::move(windowId),
|
||||
std::move(title),
|
||||
primary))
|
||||
, m_chromeController(std::make_unique<EditorWindowChromeController>())
|
||||
, m_frameOrchestrator(std::make_unique<EditorWindowFrameOrchestrator>())
|
||||
, m_inputController(std::make_unique<EditorWindowInputController>())
|
||||
, m_runtime(std::make_unique<EditorWindowRuntimeController>(
|
||||
std::move(contentController))) {
|
||||
m_state->window.windowId = std::move(windowId);
|
||||
m_state->window.title = std::move(title);
|
||||
m_state->window.primary = primary;
|
||||
UpdateCachedTitleText();
|
||||
}
|
||||
std::move(contentController))) {}
|
||||
|
||||
EditorWindow::~EditorWindow() = default;
|
||||
|
||||
std::string_view EditorWindow::GetWindowId() const {
|
||||
return m_state->window.windowId;
|
||||
return m_session->GetWindowId();
|
||||
}
|
||||
|
||||
HWND EditorWindow::GetHwnd() const {
|
||||
return m_state->window.hwnd;
|
||||
return m_session->GetHwnd();
|
||||
}
|
||||
|
||||
bool EditorWindow::HasHwnd() const {
|
||||
return m_state->window.hwnd != nullptr;
|
||||
return m_session->HasHwnd();
|
||||
}
|
||||
|
||||
EditorWindowLifecycleState EditorWindow::GetLifecycleState() const {
|
||||
return m_state->window.lifecycle;
|
||||
return m_session->GetLifecycleState();
|
||||
}
|
||||
|
||||
bool EditorWindow::IsPrimary() const {
|
||||
return m_state->window.primary;
|
||||
return m_session->IsPrimary();
|
||||
}
|
||||
|
||||
bool EditorWindow::IsClosing() const {
|
||||
return m_state->window.lifecycle == EditorWindowLifecycleState::Closing;
|
||||
return m_session->IsClosing();
|
||||
}
|
||||
|
||||
bool EditorWindow::IsDestroyed() const {
|
||||
return m_state->window.lifecycle == EditorWindowLifecycleState::Destroyed;
|
||||
return m_session->IsDestroyed();
|
||||
}
|
||||
|
||||
bool EditorWindow::IsRenderReady() const {
|
||||
@@ -126,7 +124,11 @@ bool EditorWindow::IsRenderReady() const {
|
||||
}
|
||||
|
||||
const std::wstring& EditorWindow::GetTitle() const {
|
||||
return m_state->window.title;
|
||||
return m_session->GetTitle();
|
||||
}
|
||||
|
||||
std::string_view EditorWindow::GetCachedTitleText() const {
|
||||
return m_session->GetCachedTitleText();
|
||||
}
|
||||
|
||||
const UIEditorWorkspaceController* EditorWindow::TryGetWorkspaceController() const {
|
||||
@@ -143,35 +145,32 @@ const UIEditorWorkspaceController& EditorWindow::GetWorkspaceController() const
|
||||
}
|
||||
|
||||
void EditorWindow::AttachHwnd(HWND hwnd) {
|
||||
m_state->window.hwnd = hwnd;
|
||||
m_state->window.lifecycle = EditorWindowLifecycleState::NativeAttached;
|
||||
m_session->AttachHwnd(hwnd);
|
||||
}
|
||||
|
||||
void EditorWindow::MarkInitializing() {
|
||||
m_state->window.lifecycle = EditorWindowLifecycleState::Initializing;
|
||||
m_session->MarkInitializing();
|
||||
}
|
||||
|
||||
void EditorWindow::MarkRunning() {
|
||||
m_state->window.lifecycle = EditorWindowLifecycleState::Running;
|
||||
m_session->MarkRunning();
|
||||
}
|
||||
|
||||
void EditorWindow::MarkDestroyed() {
|
||||
m_state->window.hwnd = nullptr;
|
||||
m_state->window.lifecycle = EditorWindowLifecycleState::Destroyed;
|
||||
m_session->MarkDestroyed();
|
||||
m_inputController->ResetWindowState();
|
||||
}
|
||||
|
||||
void EditorWindow::MarkClosing() {
|
||||
m_state->window.lifecycle = EditorWindowLifecycleState::Closing;
|
||||
m_session->MarkClosing();
|
||||
}
|
||||
|
||||
void EditorWindow::SetPrimary(bool primary) {
|
||||
m_state->window.primary = primary;
|
||||
m_session->SetPrimary(primary);
|
||||
}
|
||||
|
||||
void EditorWindow::SetTitle(std::wstring title) {
|
||||
m_state->window.title = std::move(title);
|
||||
UpdateCachedTitleText();
|
||||
m_session->SetTitle(std::move(title));
|
||||
}
|
||||
|
||||
void EditorWindow::ReplaceWorkspaceController(UIEditorWorkspaceController workspaceController) {
|
||||
@@ -181,8 +180,9 @@ void EditorWindow::ReplaceWorkspaceController(UIEditorWorkspaceController worksp
|
||||
}
|
||||
|
||||
void EditorWindow::InvalidateHostWindow() const {
|
||||
if (m_state->window.hwnd != nullptr && IsWindow(m_state->window.hwnd)) {
|
||||
InvalidateRect(m_state->window.hwnd, nullptr, FALSE);
|
||||
if (const HWND hwnd = m_session->GetHwnd();
|
||||
hwnd != nullptr && IsWindow(hwnd)) {
|
||||
InvalidateRect(hwnd, nullptr, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -191,14 +191,14 @@ bool EditorWindow::Initialize(
|
||||
EditorContext& editorContext,
|
||||
const std::filesystem::path& captureRoot,
|
||||
bool autoCaptureOnStartup) {
|
||||
if (m_state->window.hwnd == nullptr) {
|
||||
if (m_session->GetHwnd() == nullptr) {
|
||||
LogRuntimeTrace("app", "window initialize skipped: hwnd is null");
|
||||
return false;
|
||||
}
|
||||
|
||||
Host::RefreshBorderlessWindowDwmDecorations(m_state->window.hwnd);
|
||||
Host::RefreshBorderlessWindowDwmDecorations(m_session->GetHwnd());
|
||||
m_chromeController->Reset();
|
||||
m_chromeController->SetWindowDpi(QueryWindowDpi(m_state->window.hwnd));
|
||||
m_chromeController->SetWindowDpi(QueryWindowDpi(m_session->GetHwnd()));
|
||||
m_runtime->SetDpiScale(GetDpiScale());
|
||||
|
||||
std::ostringstream dpiTrace = {};
|
||||
@@ -208,7 +208,7 @@ bool EditorWindow::Initialize(
|
||||
|
||||
MarkInitializing();
|
||||
const bool initialized = m_runtime->Initialize(
|
||||
m_state->window.hwnd,
|
||||
m_session->GetHwnd(),
|
||||
repoRoot,
|
||||
editorContext,
|
||||
captureRoot,
|
||||
@@ -216,7 +216,7 @@ bool EditorWindow::Initialize(
|
||||
if (initialized) {
|
||||
MarkRunning();
|
||||
} else {
|
||||
m_state->window.lifecycle = EditorWindowLifecycleState::NativeAttached;
|
||||
m_session->MarkNativeAttached();
|
||||
}
|
||||
return initialized;
|
||||
}
|
||||
@@ -267,12 +267,13 @@ bool EditorWindow::ApplyWindowResize(UINT width, UINT height) {
|
||||
bool EditorWindow::QueryCurrentClientPixelSize(UINT& outWidth, UINT& outHeight) const {
|
||||
outWidth = 0u;
|
||||
outHeight = 0u;
|
||||
if (m_state->window.hwnd == nullptr || !IsWindow(m_state->window.hwnd)) {
|
||||
const HWND hwnd = m_session->GetHwnd();
|
||||
if (hwnd == nullptr || !IsWindow(hwnd)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
RECT clientRect = {};
|
||||
if (!GetClientRect(m_state->window.hwnd, &clientRect)) {
|
||||
if (!GetClientRect(hwnd, &clientRect)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -312,8 +313,9 @@ UIPoint EditorWindow::ConvertClientPixelsToDips(LONG x, LONG y) const {
|
||||
|
||||
UIPoint EditorWindow::ConvertScreenPixelsToClientDips(const POINT& screenPoint) const {
|
||||
POINT clientPoint = screenPoint;
|
||||
if (m_state->window.hwnd != nullptr) {
|
||||
ScreenToClient(m_state->window.hwnd, &clientPoint);
|
||||
if (const HWND hwnd = m_session->GetHwnd();
|
||||
hwnd != nullptr) {
|
||||
ScreenToClient(hwnd, &clientPoint);
|
||||
}
|
||||
|
||||
const float dpiScale = m_chromeController->GetDpiScale(kBaseDpiScale);
|
||||
@@ -374,8 +376,9 @@ bool EditorWindow::OnResize(UINT width, UINT height) {
|
||||
if (!matchedPresentedPrediction) {
|
||||
m_chromeController->ClearPredictedClientPixelSize();
|
||||
}
|
||||
if (m_state->window.hwnd != nullptr) {
|
||||
Host::RefreshBorderlessWindowDwmDecorations(m_state->window.hwnd);
|
||||
if (const HWND hwnd = m_session->GetHwnd();
|
||||
hwnd != nullptr) {
|
||||
Host::RefreshBorderlessWindowDwmDecorations(hwnd);
|
||||
}
|
||||
|
||||
if (matchedPresentedPrediction) {
|
||||
@@ -405,11 +408,12 @@ bool EditorWindow::OnExitSizeMove() {
|
||||
void EditorWindow::OnDpiChanged(UINT dpi, const RECT& suggestedRect) {
|
||||
m_chromeController->SetWindowDpi(dpi == 0u ? kDefaultDpi : dpi);
|
||||
m_runtime->SetDpiScale(GetDpiScale());
|
||||
if (m_state->window.hwnd != nullptr) {
|
||||
if (const HWND hwnd = m_session->GetHwnd();
|
||||
hwnd != nullptr) {
|
||||
const LONG windowWidth = suggestedRect.right - suggestedRect.left;
|
||||
const LONG windowHeight = suggestedRect.bottom - suggestedRect.top;
|
||||
SetWindowPos(
|
||||
m_state->window.hwnd,
|
||||
hwnd,
|
||||
nullptr,
|
||||
suggestedRect.left,
|
||||
suggestedRect.top,
|
||||
@@ -421,7 +425,7 @@ void EditorWindow::OnDpiChanged(UINT dpi, const RECT& suggestedRect) {
|
||||
if (QueryCurrentClientPixelSize(clientWidth, clientHeight)) {
|
||||
ApplyWindowResize(clientWidth, clientHeight);
|
||||
}
|
||||
Host::RefreshBorderlessWindowDwmDecorations(m_state->window.hwnd);
|
||||
Host::RefreshBorderlessWindowDwmDecorations(hwnd);
|
||||
}
|
||||
|
||||
std::ostringstream trace = {};
|
||||
@@ -435,10 +439,6 @@ bool EditorWindow::IsVerboseRuntimeTraceEnabled() {
|
||||
return s_enabled;
|
||||
}
|
||||
|
||||
void EditorWindow::UpdateCachedTitleText() {
|
||||
m_state->window.titleText = WideToUtf8(m_state->window.title);
|
||||
}
|
||||
|
||||
} // namespace XCEngine::UI::Editor::App
|
||||
|
||||
namespace XCEngine::UI::Editor::App {
|
||||
@@ -512,7 +512,7 @@ std::uint8_t ResolveExpectedShellCaptureButtons(
|
||||
EditorWindowFrameTransferRequests EditorWindow::RenderFrame(
|
||||
EditorContext& editorContext,
|
||||
bool globalTabDragActive) {
|
||||
if (!m_runtime->IsReady() || m_state->window.hwnd == nullptr) {
|
||||
if (!m_runtime->IsReady() || m_session->GetHwnd() == nullptr) {
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -554,49 +554,41 @@ EditorWindowFrameTransferRequests EditorWindow::RenderFrame(
|
||||
EditorWindowFrameTransferRequests EditorWindow::OnPaintMessage(
|
||||
EditorContext& editorContext,
|
||||
bool globalTabDragActive) {
|
||||
if (!m_runtime->IsReady() || m_state->window.hwnd == nullptr) {
|
||||
if (!m_runtime->IsReady() || m_session->GetHwnd() == nullptr) {
|
||||
return {};
|
||||
}
|
||||
|
||||
PAINTSTRUCT paintStruct = {};
|
||||
BeginPaint(m_state->window.hwnd, &paintStruct);
|
||||
BeginPaint(m_session->GetHwnd(), &paintStruct);
|
||||
const EditorWindowFrameTransferRequests transferRequests =
|
||||
EditorWindowFrameDriver::DriveImmediateFrame(
|
||||
*this,
|
||||
editorContext,
|
||||
globalTabDragActive);
|
||||
EndPaint(m_state->window.hwnd, &paintStruct);
|
||||
EndPaint(m_session->GetHwnd(), &paintStruct);
|
||||
return transferRequests;
|
||||
}
|
||||
|
||||
void EditorWindow::QueueCompletedImmediateFrame(
|
||||
EditorWindowFrameTransferRequests transferRequests) {
|
||||
m_hasQueuedCompletedImmediateFrame = true;
|
||||
if (transferRequests.beginGlobalTabDrag.has_value()) {
|
||||
m_queuedImmediateFrameTransferRequests.beginGlobalTabDrag =
|
||||
std::move(transferRequests.beginGlobalTabDrag);
|
||||
}
|
||||
if (transferRequests.detachPanel.has_value()) {
|
||||
m_queuedImmediateFrameTransferRequests.detachPanel =
|
||||
std::move(transferRequests.detachPanel);
|
||||
}
|
||||
if (transferRequests.openUtilityWindow.has_value()) {
|
||||
m_queuedImmediateFrameTransferRequests.openUtilityWindow =
|
||||
std::move(transferRequests.openUtilityWindow);
|
||||
}
|
||||
m_session->QueueCompletedImmediateFrame(std::move(transferRequests));
|
||||
}
|
||||
|
||||
bool EditorWindow::HasQueuedCompletedImmediateFrame() const {
|
||||
return m_hasQueuedCompletedImmediateFrame;
|
||||
return m_session->HasQueuedCompletedImmediateFrame();
|
||||
}
|
||||
|
||||
EditorWindowFrameTransferRequests
|
||||
EditorWindow::ConsumeQueuedCompletedImmediateFrameTransferRequests() {
|
||||
m_hasQueuedCompletedImmediateFrame = false;
|
||||
EditorWindowFrameTransferRequests transferRequests =
|
||||
std::move(m_queuedImmediateFrameTransferRequests);
|
||||
m_queuedImmediateFrameTransferRequests = {};
|
||||
return transferRequests;
|
||||
return m_session->ConsumeQueuedCompletedImmediateFrameTransferRequests();
|
||||
}
|
||||
|
||||
void EditorWindow::RequestSkipNextSteadyStateFrame() {
|
||||
m_chromeController->RequestSkipNextSteadyStateFrame();
|
||||
}
|
||||
|
||||
bool EditorWindow::ConsumeSkipNextSteadyStateFrame() {
|
||||
return m_chromeController->ConsumeSkipNextSteadyStateFrame();
|
||||
}
|
||||
|
||||
UIRect EditorWindow::ResolveWorkspaceBounds(float clientWidthDips, float clientHeightDips) const {
|
||||
@@ -634,7 +626,7 @@ EditorWindowFrameTransferRequests EditorWindow::RenderRuntimeFrame(
|
||||
.bounds = workspaceBounds,
|
||||
.inputEvents = frameEvents,
|
||||
.captureStatusText = m_runtime->BuildCaptureStatusText(),
|
||||
.primary = m_state->window.primary,
|
||||
.primary = m_session->IsPrimary(),
|
||||
.globalTabDragActive = globalTabDragActive,
|
||||
.useDetachedTitleBarTabStrip = useDetachedTitleBarTabStrip,
|
||||
},
|
||||
@@ -748,21 +740,22 @@ bool EditorWindow::OwnsPointerCapture(EditorWindowPointerCaptureOwner owner) con
|
||||
}
|
||||
|
||||
void EditorWindow::AcquirePointerCapture(EditorWindowPointerCaptureOwner owner) {
|
||||
m_inputController->AcquirePointerCapture(m_state->window.hwnd, owner);
|
||||
m_inputController->AcquirePointerCapture(m_session->GetHwnd(), owner);
|
||||
}
|
||||
|
||||
void EditorWindow::ReleasePointerCapture(EditorWindowPointerCaptureOwner owner) {
|
||||
m_inputController->ReleasePointerCapture(m_state->window.hwnd, owner);
|
||||
m_inputController->ReleasePointerCapture(m_session->GetHwnd(), owner);
|
||||
}
|
||||
|
||||
void EditorWindow::ForceReleasePointerCapture() {
|
||||
m_inputController->ForceReleasePointerCapture(m_state->window.hwnd);
|
||||
m_inputController->ForceReleasePointerCapture(m_session->GetHwnd());
|
||||
}
|
||||
|
||||
void EditorWindow::TryStartImmediateShellPointerCapture(LPARAM lParam) {
|
||||
if (m_state->window.hwnd == nullptr ||
|
||||
!IsWindow(m_state->window.hwnd) ||
|
||||
GetCapture() == m_state->window.hwnd) {
|
||||
const HWND hwnd = m_session->GetHwnd();
|
||||
if (hwnd == nullptr ||
|
||||
!IsWindow(hwnd) ||
|
||||
GetCapture() == hwnd) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -794,7 +787,8 @@ void EditorWindow::QueuePointerEvent(
|
||||
|
||||
void EditorWindow::QueueSyntheticPointerStateSyncEvent(
|
||||
const ::XCEngine::UI::UIInputModifiers& modifiers) {
|
||||
if (m_state->window.hwnd == nullptr || !IsWindow(m_state->window.hwnd)) {
|
||||
const HWND hwnd = m_session->GetHwnd();
|
||||
if (hwnd == nullptr || !IsWindow(hwnd)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -802,7 +796,7 @@ void EditorWindow::QueueSyntheticPointerStateSyncEvent(
|
||||
if (!GetCursorPos(&screenPoint)) {
|
||||
return;
|
||||
}
|
||||
if (!ScreenToClient(m_state->window.hwnd, &screenPoint)) {
|
||||
if (!ScreenToClient(hwnd, &screenPoint)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -813,17 +807,18 @@ void EditorWindow::QueueSyntheticPointerStateSyncEvent(
|
||||
|
||||
void EditorWindow::QueuePointerLeaveEvent() {
|
||||
::XCEngine::UI::UIPoint position = {};
|
||||
if (m_state->window.hwnd != nullptr) {
|
||||
if (const HWND hwnd = m_session->GetHwnd();
|
||||
hwnd != nullptr) {
|
||||
POINT clientPoint = {};
|
||||
GetCursorPos(&clientPoint);
|
||||
ScreenToClient(m_state->window.hwnd, &clientPoint);
|
||||
ScreenToClient(hwnd, &clientPoint);
|
||||
position = ConvertClientPixelsToDips(clientPoint.x, clientPoint.y);
|
||||
}
|
||||
m_inputController->QueuePointerLeaveEvent(position);
|
||||
}
|
||||
|
||||
void EditorWindow::QueuePointerWheelEvent(short wheelDelta, WPARAM wParam, LPARAM lParam) {
|
||||
if (m_state->window.hwnd == nullptr) {
|
||||
if (m_session->GetHwnd() == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -831,7 +826,7 @@ void EditorWindow::QueuePointerWheelEvent(short wheelDelta, WPARAM wParam, LPARA
|
||||
GET_X_LPARAM(lParam),
|
||||
GET_Y_LPARAM(lParam)
|
||||
};
|
||||
ScreenToClient(m_state->window.hwnd, &screenPoint);
|
||||
ScreenToClient(m_session->GetHwnd(), &screenPoint);
|
||||
|
||||
m_inputController->QueuePointerWheelEvent(
|
||||
ConvertClientPixelsToDips(screenPoint.x, screenPoint.y),
|
||||
@@ -840,7 +835,8 @@ void EditorWindow::QueuePointerWheelEvent(short wheelDelta, WPARAM wParam, LPARA
|
||||
}
|
||||
|
||||
bool EditorWindow::IsPointerInsideClientArea() const {
|
||||
if (m_state->window.hwnd == nullptr || !IsWindow(m_state->window.hwnd)) {
|
||||
const HWND hwnd = m_session->GetHwnd();
|
||||
if (hwnd == nullptr || !IsWindow(hwnd)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -849,14 +845,14 @@ bool EditorWindow::IsPointerInsideClientArea() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!IsScreenPointOverWindow(m_state->window.hwnd, screenPoint)) {
|
||||
if (!IsScreenPointOverWindow(hwnd, screenPoint)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const LPARAM pointParam = MAKELPARAM(
|
||||
static_cast<SHORT>(screenPoint.x),
|
||||
static_cast<SHORT>(screenPoint.y));
|
||||
return SendMessageW(m_state->window.hwnd, WM_NCHITTEST, 0, pointParam) == HTCLIENT;
|
||||
return SendMessageW(hwnd, WM_NCHITTEST, 0, pointParam) == HTCLIENT;
|
||||
}
|
||||
|
||||
LPCWSTR EditorWindow::ResolveCurrentCursorResource() const {
|
||||
|
||||
@@ -5,8 +5,7 @@
|
||||
#endif
|
||||
|
||||
#include "Platform/Win32/Windowing/EditorWindowPointerCapture.h"
|
||||
#include "Platform/Win32/Windowing/EditorWindowState.h"
|
||||
#include "Platform/Win32/Windowing/EditorWindowTransferRequests.h"
|
||||
#include "Platform/Win32/Windowing/EditorWindowSession.h"
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
@@ -61,7 +60,7 @@ class EditorWindowLifecycleCoordinator;
|
||||
class EditorWindowMessageDispatcher;
|
||||
class EditorWindowRuntimeController;
|
||||
class EditorWindowWorkspaceCoordinator;
|
||||
struct EditorWindowState;
|
||||
class EditorWindowSession;
|
||||
|
||||
class EditorWindow {
|
||||
public:
|
||||
@@ -85,6 +84,7 @@ public:
|
||||
bool IsClosing() const;
|
||||
bool IsDestroyed() const;
|
||||
const std::wstring& GetTitle() const;
|
||||
std::string_view GetCachedTitleText() const;
|
||||
const UIEditorWorkspaceController* TryGetWorkspaceController() const;
|
||||
const UIEditorWorkspaceController& GetWorkspaceController() const;
|
||||
::XCEngine::UI::UIPoint ConvertScreenPixelsToClientDips(const POINT& screenPoint) const;
|
||||
@@ -135,6 +135,8 @@ private:
|
||||
EditorWindowFrameTransferRequests transferRequests);
|
||||
bool HasQueuedCompletedImmediateFrame() const;
|
||||
EditorWindowFrameTransferRequests ConsumeQueuedCompletedImmediateFrameTransferRequests();
|
||||
void RequestSkipNextSteadyStateFrame();
|
||||
bool ConsumeSkipNextSteadyStateFrame();
|
||||
bool OnResize(UINT width, UINT height);
|
||||
void OnEnterSizeMove();
|
||||
bool OnExitSizeMove();
|
||||
@@ -177,16 +179,13 @@ private:
|
||||
float PixelsToDips(float pixels) const;
|
||||
::XCEngine::UI::UIPoint ConvertClientPixelsToDips(LONG x, LONG y) const;
|
||||
void ApplyShellRuntimePointerCapture();
|
||||
void UpdateCachedTitleText();
|
||||
static bool IsVerboseRuntimeTraceEnabled();
|
||||
|
||||
std::unique_ptr<EditorWindowState> m_state = {};
|
||||
std::unique_ptr<EditorWindowSession> m_session = {};
|
||||
std::unique_ptr<EditorWindowChromeController> m_chromeController = {};
|
||||
std::unique_ptr<EditorWindowFrameOrchestrator> m_frameOrchestrator = {};
|
||||
std::unique_ptr<EditorWindowInputController> m_inputController = {};
|
||||
std::unique_ptr<EditorWindowRuntimeController> m_runtime = {};
|
||||
EditorWindowFrameTransferRequests m_queuedImmediateFrameTransferRequests = {};
|
||||
bool m_hasQueuedCompletedImmediateFrame = false;
|
||||
};
|
||||
|
||||
} // namespace XCEngine::UI::Editor::App
|
||||
|
||||
@@ -190,7 +190,7 @@ void EditorWindowHostRuntime::RenderAllWindows(
|
||||
continue;
|
||||
}
|
||||
|
||||
if (window->m_chromeController->ConsumeSkipNextSteadyStateFrame()) {
|
||||
if (window->ConsumeSkipNextSteadyStateFrame()) {
|
||||
workspaceCoordinator.RefreshWindowPresentation(*window);
|
||||
continue;
|
||||
}
|
||||
|
||||
126
new_editor/app/Platform/Win32/Windowing/EditorWindowSession.cpp
Normal file
126
new_editor/app/Platform/Win32/Windowing/EditorWindowSession.cpp
Normal file
@@ -0,0 +1,126 @@
|
||||
#include "Platform/Win32/Windowing/EditorWindowSession.h"
|
||||
|
||||
#include "Platform/Win32/Windowing/EditorWindowSupport.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
namespace XCEngine::UI::Editor::App {
|
||||
|
||||
using namespace EditorWindowSupport;
|
||||
|
||||
EditorWindowSession::EditorWindowSession(
|
||||
std::string windowId,
|
||||
std::wstring title,
|
||||
bool primary) {
|
||||
m_state.window.windowId = std::move(windowId);
|
||||
m_state.window.title = std::move(title);
|
||||
m_state.window.primary = primary;
|
||||
UpdateCachedTitleText();
|
||||
}
|
||||
|
||||
std::string_view EditorWindowSession::GetWindowId() const {
|
||||
return m_state.window.windowId;
|
||||
}
|
||||
|
||||
HWND EditorWindowSession::GetHwnd() const {
|
||||
return m_state.window.hwnd;
|
||||
}
|
||||
|
||||
bool EditorWindowSession::HasHwnd() const {
|
||||
return m_state.window.hwnd != nullptr;
|
||||
}
|
||||
|
||||
EditorWindowLifecycleState EditorWindowSession::GetLifecycleState() const {
|
||||
return m_state.window.lifecycle;
|
||||
}
|
||||
|
||||
bool EditorWindowSession::IsPrimary() const {
|
||||
return m_state.window.primary;
|
||||
}
|
||||
|
||||
bool EditorWindowSession::IsClosing() const {
|
||||
return m_state.window.lifecycle == EditorWindowLifecycleState::Closing;
|
||||
}
|
||||
|
||||
bool EditorWindowSession::IsDestroyed() const {
|
||||
return m_state.window.lifecycle == EditorWindowLifecycleState::Destroyed;
|
||||
}
|
||||
|
||||
const std::wstring& EditorWindowSession::GetTitle() const {
|
||||
return m_state.window.title;
|
||||
}
|
||||
|
||||
std::string_view EditorWindowSession::GetCachedTitleText() const {
|
||||
return m_state.window.titleText;
|
||||
}
|
||||
|
||||
void EditorWindowSession::AttachHwnd(HWND hwnd) {
|
||||
m_state.window.hwnd = hwnd;
|
||||
m_state.window.lifecycle = EditorWindowLifecycleState::NativeAttached;
|
||||
}
|
||||
|
||||
void EditorWindowSession::MarkNativeAttached() {
|
||||
m_state.window.lifecycle = EditorWindowLifecycleState::NativeAttached;
|
||||
}
|
||||
|
||||
void EditorWindowSession::MarkInitializing() {
|
||||
m_state.window.lifecycle = EditorWindowLifecycleState::Initializing;
|
||||
}
|
||||
|
||||
void EditorWindowSession::MarkRunning() {
|
||||
m_state.window.lifecycle = EditorWindowLifecycleState::Running;
|
||||
}
|
||||
|
||||
void EditorWindowSession::MarkDestroyed() {
|
||||
m_state.window.hwnd = nullptr;
|
||||
m_state.window.lifecycle = EditorWindowLifecycleState::Destroyed;
|
||||
}
|
||||
|
||||
void EditorWindowSession::MarkClosing() {
|
||||
m_state.window.lifecycle = EditorWindowLifecycleState::Closing;
|
||||
}
|
||||
|
||||
void EditorWindowSession::SetPrimary(bool primary) {
|
||||
m_state.window.primary = primary;
|
||||
}
|
||||
|
||||
void EditorWindowSession::SetTitle(std::wstring title) {
|
||||
m_state.window.title = std::move(title);
|
||||
UpdateCachedTitleText();
|
||||
}
|
||||
|
||||
void EditorWindowSession::QueueCompletedImmediateFrame(
|
||||
EditorWindowFrameTransferRequests transferRequests) {
|
||||
m_hasQueuedCompletedImmediateFrame = true;
|
||||
if (transferRequests.beginGlobalTabDrag.has_value()) {
|
||||
m_queuedImmediateFrameTransferRequests.beginGlobalTabDrag =
|
||||
std::move(transferRequests.beginGlobalTabDrag);
|
||||
}
|
||||
if (transferRequests.detachPanel.has_value()) {
|
||||
m_queuedImmediateFrameTransferRequests.detachPanel =
|
||||
std::move(transferRequests.detachPanel);
|
||||
}
|
||||
if (transferRequests.openUtilityWindow.has_value()) {
|
||||
m_queuedImmediateFrameTransferRequests.openUtilityWindow =
|
||||
std::move(transferRequests.openUtilityWindow);
|
||||
}
|
||||
}
|
||||
|
||||
bool EditorWindowSession::HasQueuedCompletedImmediateFrame() const {
|
||||
return m_hasQueuedCompletedImmediateFrame;
|
||||
}
|
||||
|
||||
EditorWindowFrameTransferRequests
|
||||
EditorWindowSession::ConsumeQueuedCompletedImmediateFrameTransferRequests() {
|
||||
m_hasQueuedCompletedImmediateFrame = false;
|
||||
EditorWindowFrameTransferRequests transferRequests =
|
||||
std::move(m_queuedImmediateFrameTransferRequests);
|
||||
m_queuedImmediateFrameTransferRequests = {};
|
||||
return transferRequests;
|
||||
}
|
||||
|
||||
void EditorWindowSession::UpdateCachedTitleText() {
|
||||
m_state.window.titleText = WideToUtf8(m_state.window.title);
|
||||
}
|
||||
|
||||
} // namespace XCEngine::UI::Editor::App
|
||||
@@ -0,0 +1,47 @@
|
||||
#pragma once
|
||||
|
||||
#include "Platform/Win32/Windowing/EditorWindowState.h"
|
||||
#include "Platform/Win32/Windowing/EditorWindowTransferRequests.h"
|
||||
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
namespace XCEngine::UI::Editor::App {
|
||||
|
||||
class EditorWindowSession final {
|
||||
public:
|
||||
EditorWindowSession(std::string windowId, std::wstring title, bool primary);
|
||||
|
||||
std::string_view GetWindowId() const;
|
||||
HWND GetHwnd() const;
|
||||
bool HasHwnd() const;
|
||||
EditorWindowLifecycleState GetLifecycleState() const;
|
||||
bool IsPrimary() const;
|
||||
bool IsClosing() const;
|
||||
bool IsDestroyed() const;
|
||||
const std::wstring& GetTitle() const;
|
||||
std::string_view GetCachedTitleText() const;
|
||||
|
||||
void AttachHwnd(HWND hwnd);
|
||||
void MarkNativeAttached();
|
||||
void MarkInitializing();
|
||||
void MarkRunning();
|
||||
void MarkDestroyed();
|
||||
void MarkClosing();
|
||||
void SetPrimary(bool primary);
|
||||
void SetTitle(std::wstring title);
|
||||
|
||||
void QueueCompletedImmediateFrame(
|
||||
EditorWindowFrameTransferRequests transferRequests);
|
||||
bool HasQueuedCompletedImmediateFrame() const;
|
||||
EditorWindowFrameTransferRequests ConsumeQueuedCompletedImmediateFrameTransferRequests();
|
||||
|
||||
private:
|
||||
void UpdateCachedTitleText();
|
||||
|
||||
EditorWindowState m_state = {};
|
||||
EditorWindowFrameTransferRequests m_queuedImmediateFrameTransferRequests = {};
|
||||
bool m_hasQueuedCompletedImmediateFrame = false;
|
||||
};
|
||||
|
||||
} // namespace XCEngine::UI::Editor::App
|
||||
Reference in New Issue
Block a user