new_editor: filter dead windows from live workspace sets
This commit is contained in:
@@ -1,10 +1,12 @@
|
||||
#include "Platform/Win32/WindowManager/Internal.h"
|
||||
|
||||
#include "Bootstrap/EditorResources.h"
|
||||
#include "State/EditorContext.h"
|
||||
#include "Platform/Win32/EditorWindow.h"
|
||||
|
||||
#include <XCEditor/Foundation/UIEditorRuntimeTrace.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <utility>
|
||||
|
||||
namespace XCEngine::UI::Editor::App {
|
||||
@@ -122,6 +124,102 @@ EditorWindowHostRuntime::EditorWindowHostRuntime(
|
||||
|
||||
EditorWindowHostRuntime::~EditorWindowHostRuntime() = default;
|
||||
|
||||
EditorWindow* EditorWindowHostRuntime::CreateEditorWindow(
|
||||
UIEditorWorkspaceController workspaceController,
|
||||
const CreateParams& params) {
|
||||
auto windowPtr = std::make_unique<EditorWindow>(
|
||||
params.windowId,
|
||||
params.title.empty() ? std::wstring(L"XCEngine Editor") : params.title,
|
||||
params.primary,
|
||||
std::move(workspaceController));
|
||||
EditorWindow* const rawWindow = windowPtr.get();
|
||||
m_windows.push_back(std::move(windowPtr));
|
||||
|
||||
const auto eraseRawWindow = [this, rawWindow]() {
|
||||
const auto it = std::find_if(
|
||||
m_windows.begin(),
|
||||
m_windows.end(),
|
||||
[rawWindow](const std::unique_ptr<EditorWindow>& candidate) {
|
||||
return candidate.get() == rawWindow;
|
||||
});
|
||||
if (it != m_windows.end()) {
|
||||
m_windows.erase(it);
|
||||
}
|
||||
};
|
||||
|
||||
m_pendingCreateWindow = rawWindow;
|
||||
const HWND hwnd = CreateWindowExW(
|
||||
WS_EX_APPWINDOW,
|
||||
m_hostConfig.windowClassName,
|
||||
rawWindow->GetTitle().c_str(),
|
||||
m_hostConfig.windowStyle,
|
||||
params.initialX,
|
||||
params.initialY,
|
||||
params.initialWidth,
|
||||
params.initialHeight,
|
||||
nullptr,
|
||||
nullptr,
|
||||
m_hostConfig.hInstance,
|
||||
m_hostConfig.windowUserData);
|
||||
m_pendingCreateWindow = nullptr;
|
||||
if (hwnd == nullptr) {
|
||||
eraseRawWindow();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!rawWindow->HasHwnd()) {
|
||||
rawWindow->AttachHwnd(hwnd);
|
||||
}
|
||||
|
||||
auto failWindowInitialization = [&](std::string_view message) {
|
||||
LogRuntimeTrace("window", std::string(message));
|
||||
DestroyEditorWindow(*rawWindow);
|
||||
eraseRawWindow();
|
||||
return static_cast<EditorWindow*>(nullptr);
|
||||
};
|
||||
|
||||
const HICON bigIcon = static_cast<HICON>(
|
||||
LoadImageW(
|
||||
m_hostConfig.hInstance,
|
||||
MAKEINTRESOURCEW(IDI_APP_ICON),
|
||||
IMAGE_ICON,
|
||||
0,
|
||||
0,
|
||||
LR_DEFAULTSIZE));
|
||||
const HICON smallIcon = static_cast<HICON>(
|
||||
LoadImageW(
|
||||
m_hostConfig.hInstance,
|
||||
MAKEINTRESOURCEW(IDI_APP_ICON_SMALL),
|
||||
IMAGE_ICON,
|
||||
GetSystemMetrics(SM_CXSMICON),
|
||||
GetSystemMetrics(SM_CYSMICON),
|
||||
LR_DEFAULTCOLOR));
|
||||
if (bigIcon != nullptr) {
|
||||
SendMessageW(hwnd, WM_SETICON, ICON_BIG, reinterpret_cast<LPARAM>(bigIcon));
|
||||
}
|
||||
if (smallIcon != nullptr) {
|
||||
SendMessageW(hwnd, WM_SETICON, ICON_SMALL, reinterpret_cast<LPARAM>(smallIcon));
|
||||
}
|
||||
|
||||
if (!rawWindow->Initialize(
|
||||
m_repoRoot,
|
||||
m_editorContext,
|
||||
m_editorContext.GetShellAsset().captureRootPath,
|
||||
params.autoCaptureOnStartup)) {
|
||||
return failWindowInitialization("managed window initialization failed");
|
||||
}
|
||||
|
||||
ShowWindow(hwnd, params.showCommand);
|
||||
UpdateWindow(hwnd);
|
||||
return rawWindow;
|
||||
}
|
||||
|
||||
void EditorWindowHostRuntime::HandlePendingNativeWindowCreated(HWND hwnd) {
|
||||
if (m_pendingCreateWindow != nullptr && !m_pendingCreateWindow->HasHwnd()) {
|
||||
m_pendingCreateWindow->AttachHwnd(hwnd);
|
||||
}
|
||||
}
|
||||
|
||||
void EditorWindowHostRuntime::Shutdown() {
|
||||
for (const std::unique_ptr<EditorWindow>& window : m_windows) {
|
||||
if (window != nullptr) {
|
||||
@@ -220,6 +318,56 @@ void EditorWindowHostRuntime::HandleDestroyedWindow(HWND hwnd) {
|
||||
}
|
||||
}
|
||||
|
||||
EditorWindow* EditorWindowHostRuntime::FindWindow(HWND hwnd) {
|
||||
if (hwnd == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
for (const std::unique_ptr<EditorWindow>& window : m_windows) {
|
||||
if (window != nullptr && window->GetHwnd() == hwnd) {
|
||||
return window.get();
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const EditorWindow* EditorWindowHostRuntime::FindWindow(HWND hwnd) const {
|
||||
return const_cast<EditorWindowHostRuntime*>(this)->FindWindow(hwnd);
|
||||
}
|
||||
|
||||
EditorWindow* EditorWindowHostRuntime::FindWindow(std::string_view windowId) {
|
||||
if (windowId.empty()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
for (const std::unique_ptr<EditorWindow>& window : m_windows) {
|
||||
if (window != nullptr && window->GetWindowId() == windowId) {
|
||||
return window.get();
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const EditorWindow* EditorWindowHostRuntime::FindWindow(std::string_view windowId) const {
|
||||
return const_cast<EditorWindowHostRuntime*>(this)->FindWindow(windowId);
|
||||
}
|
||||
|
||||
EditorWindow* EditorWindowHostRuntime::FindPrimaryWindow() {
|
||||
for (const std::unique_ptr<EditorWindow>& window : m_windows) {
|
||||
if (window != nullptr && window->IsPrimary()) {
|
||||
return window.get();
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const EditorWindow* EditorWindowHostRuntime::FindPrimaryWindow() const {
|
||||
return const_cast<EditorWindowHostRuntime*>(this)->FindPrimaryWindow();
|
||||
}
|
||||
|
||||
void EditorWindowHostRuntime::LogRuntimeTrace(
|
||||
std::string_view channel,
|
||||
std::string_view message) const {
|
||||
@@ -232,6 +380,55 @@ EditorWindowWorkspaceCoordinator::EditorWindowWorkspaceCoordinator(
|
||||
|
||||
EditorWindowWorkspaceCoordinator::~EditorWindowWorkspaceCoordinator() = default;
|
||||
|
||||
UIEditorWindowWorkspaceSet EditorWindowWorkspaceCoordinator::BuildWindowWorkspaceSet(
|
||||
std::string_view activeWindowId) const {
|
||||
UIEditorWindowWorkspaceSet windowSet = {};
|
||||
if (const EditorWindow* primaryWindow = m_hostRuntime.FindPrimaryWindow();
|
||||
primaryWindow != nullptr &&
|
||||
primaryWindow->GetHwnd() != nullptr) {
|
||||
windowSet.primaryWindowId = std::string(primaryWindow->GetWindowId());
|
||||
}
|
||||
|
||||
for (const std::unique_ptr<EditorWindow>& window : m_hostRuntime.GetWindows()) {
|
||||
if (window == nullptr || window->GetHwnd() == nullptr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
UIEditorWindowWorkspaceState entry = {};
|
||||
entry.windowId = std::string(window->GetWindowId());
|
||||
entry.workspace = window->GetWorkspaceController().GetWorkspace();
|
||||
entry.session = window->GetWorkspaceController().GetSession();
|
||||
windowSet.windows.push_back(std::move(entry));
|
||||
}
|
||||
|
||||
windowSet.activeWindowId =
|
||||
!activeWindowId.empty() &&
|
||||
([this, activeWindowId]() {
|
||||
const EditorWindow* activeWindow = m_hostRuntime.FindWindow(activeWindowId);
|
||||
return activeWindow != nullptr && activeWindow->GetHwnd() != nullptr;
|
||||
})()
|
||||
? std::string(activeWindowId)
|
||||
: windowSet.primaryWindowId;
|
||||
|
||||
return windowSet;
|
||||
}
|
||||
|
||||
UIEditorWindowWorkspaceController
|
||||
EditorWindowWorkspaceCoordinator::BuildLiveWindowWorkspaceController(
|
||||
std::string_view activeWindowId) const {
|
||||
return UIEditorWindowWorkspaceController(
|
||||
m_hostRuntime.GetEditorContext().GetShellAsset().panelRegistry,
|
||||
BuildWindowWorkspaceSet(activeWindowId));
|
||||
}
|
||||
|
||||
UIEditorWorkspaceController EditorWindowWorkspaceCoordinator::BuildWorkspaceControllerForWindow(
|
||||
const UIEditorWindowWorkspaceState& windowState) const {
|
||||
return UIEditorWorkspaceController(
|
||||
m_hostRuntime.GetEditorContext().GetShellAsset().panelRegistry,
|
||||
windowState.workspace,
|
||||
windowState.session);
|
||||
}
|
||||
|
||||
void EditorWindowWorkspaceCoordinator::HandleWindowFrameTransferRequests(
|
||||
EditorWindow& sourceWindow,
|
||||
EditorWindowFrameTransferRequests&& transferRequests) {
|
||||
|
||||
Reference in New Issue
Block a user