new_editor: close editor-layer app boundary

This commit is contained in:
2026-04-22 16:24:59 +08:00
parent a805803858
commit 2c2a8b8669
25 changed files with 1036 additions and 439 deletions

View File

@@ -6,7 +6,7 @@
#include "Platform/Win32/EditorWindowSupport.h"
#include <XCEditor/Foundation/UIEditorTheme.h>
#include <XCEditor/Panels/UIEditorPanelRegistry.h>
#include <XCEditor/Workspace/UIEditorDetachedWindowPolicy.h>
#include <XCEngine/UI/DrawData.h>
#include <XCEngine/UI/Layout/UITabStripLayout.h>
@@ -32,86 +32,6 @@ constexpr float kTitleBarLogoInsetLeft = 8.0f;
constexpr float kTitleBarLogoTextGap = 8.0f;
constexpr float kTitleBarFrameStatsInsetRight = 12.0f;
bool IsRootPanelVisible(
const UIEditorWorkspaceController& controller,
std::string_view panelId) {
const UIEditorPanelSessionState* panelState =
FindUIEditorPanelSessionState(controller.GetSession(), panelId);
return panelState != nullptr && panelState->open && panelState->visible;
}
std::string ResolveDetachedTitleTabText(const EditorWindow& window) {
const auto& workspaceController = window.GetWorkspaceController();
const std::string_view activePanelId = workspaceController.GetWorkspace().activePanelId;
if (!activePanelId.empty()) {
if (const UIEditorPanelDescriptor* descriptor =
FindUIEditorPanelDescriptor(
workspaceController.GetPanelRegistry(),
activePanelId);
descriptor != nullptr &&
!descriptor->defaultTitle.empty()) {
return descriptor->defaultTitle;
}
}
return std::string("Panel");
}
const UIEditorPanelDescriptor* ResolveSingleVisibleRootPanelDescriptor(
const EditorWindow& window) {
const UIEditorWorkspaceController& workspaceController = window.GetWorkspaceController();
const UIEditorWorkspaceNode& root = workspaceController.GetWorkspace().root;
if (root.kind != UIEditorWorkspaceNodeKind::TabStack) {
return nullptr;
}
const UIEditorPanelRegistry& panelRegistry = workspaceController.GetPanelRegistry();
const UIEditorPanelDescriptor* visibleDescriptor = nullptr;
std::size_t visibleCount = 0u;
for (const UIEditorWorkspaceNode& child : root.children) {
if (child.kind != UIEditorWorkspaceNodeKind::Panel ||
!IsRootPanelVisible(workspaceController, child.panel.panelId)) {
continue;
}
const UIEditorPanelDescriptor* descriptor =
FindUIEditorPanelDescriptor(panelRegistry, child.panel.panelId);
if (descriptor == nullptr) {
return nullptr;
}
++visibleCount;
visibleDescriptor = descriptor;
if (visibleCount > 1u) {
return nullptr;
}
}
return visibleCount == 1u ? visibleDescriptor : nullptr;
}
bool IsToolWindow(const EditorWindow& window) {
if (window.IsPrimary()) {
return false;
}
const UIEditorPanelDescriptor* descriptor =
ResolveSingleVisibleRootPanelDescriptor(window);
return descriptor != nullptr && descriptor->toolWindow;
}
::XCEngine::UI::UISize ResolveMinimumOuterSize(const EditorWindow& window) {
if (const UIEditorPanelDescriptor* descriptor =
ResolveSingleVisibleRootPanelDescriptor(window);
descriptor != nullptr &&
descriptor->minimumDetachedWindowSize.width > 0.0f &&
descriptor->minimumDetachedWindowSize.height > 0.0f) {
return descriptor->minimumDetachedWindowSize;
}
return ::XCEngine::UI::UISize(640.0f, 360.0f);
}
float ResolveDetachedTabWidth(
std::string_view text,
const UIEditorTextMeasurer* textMeasurer) {
@@ -126,28 +46,6 @@ float ResolveDetachedTabWidth(
return MeasureUITabStripHeaderWidth(measuredLabelWidth, metrics.layoutMetrics);
}
bool HasSingleVisibleRootTab(const UIEditorWorkspaceController& controller) {
const UIEditorWorkspaceNode& root = controller.GetWorkspace().root;
if (root.kind != UIEditorWorkspaceNodeKind::TabStack) {
return false;
}
std::size_t visiblePanelCount = 0u;
for (const UIEditorWorkspaceNode& child : root.children) {
if (child.kind != UIEditorWorkspaceNodeKind::Panel ||
!IsRootPanelVisible(controller, child.panel.panelId)) {
continue;
}
++visiblePanelCount;
if (visiblePanelCount > 1u) {
return false;
}
}
return visiblePanelCount == 1u;
}
UIRect BuildDetachedTitleLogoRect(const Host::BorderlessWindowChromeLayout& layout) {
const float availableLeft = layout.titleBarRect.x;
const float availableRight = layout.minimizeButtonRect.x;
@@ -332,7 +230,8 @@ bool EditorWindowChromeController::HandleSystemCommand(
bool EditorWindowChromeController::HandleGetMinMaxInfo(
const EditorWindow& window,
LPARAM lParam) const {
const ::XCEngine::UI::UISize minimumOuterSize = ResolveMinimumOuterSize(window);
const ::XCEngine::UI::UISize minimumOuterSize =
ResolveUIEditorDetachedWorkspaceMinimumOuterSize(window.GetWorkspaceController());
return Host::HandleBorderlessWindowGetMinMaxInfo(
window.m_state->window.hwnd,
lParam,
@@ -412,7 +311,8 @@ bool EditorWindowChromeController::HandleResizePointerMove(
return false;
}
const ::XCEngine::UI::UISize minimumOuterSize = ResolveMinimumOuterSize(window);
const ::XCEngine::UI::UISize minimumOuterSize =
ResolveUIEditorDetachedWorkspaceMinimumOuterSize(window.GetWorkspaceController());
RECT targetRect = Host::ComputeBorderlessWindowResizeRect(
GetBorderlessResizeInitialWindowRect(),
GetBorderlessResizeInitialScreenPoint(),
@@ -718,7 +618,9 @@ Host::BorderlessWindowChromeLayout EditorWindowChromeController::ResolveChromeLa
float leadingOccupiedRight = 0.0f;
if (ShouldUseDetachedTitleBarTabStrip(window)) {
leadingOccupiedRight = ResolveDetachedTabWidth(
ResolveDetachedTitleTabText(window),
ResolveUIEditorDetachedWorkspaceTitle(
window.GetWorkspaceController(),
"Panel"),
&window.m_runtime->GetTextMeasurer());
}
@@ -730,8 +632,8 @@ Host::BorderlessWindowChromeLayout EditorWindowChromeController::ResolveChromeLa
bool EditorWindowChromeController::ShouldUseDetachedTitleBarTabStrip(
const EditorWindow& window) const {
return !window.m_state->window.primary &&
!IsToolWindow(window) &&
HasSingleVisibleRootTab(window.m_runtime->GetWorkspaceController());
!IsUIEditorDetachedWorkspaceToolWindow(window.m_runtime->GetWorkspaceController()) &&
HasUIEditorSingleVisibleRootTab(window.m_runtime->GetWorkspaceController());
}
void EditorWindowChromeController::AppendChrome(
@@ -787,8 +689,10 @@ void EditorWindowChromeController::AppendChrome(
0.0f,
(layout.titleBarRect.height - kBorderlessTitleBarFontSize) * 0.5f -
1.0f)),
IsToolWindow(window)
? ResolveDetachedTitleTabText(window)
IsUIEditorDetachedWorkspaceToolWindow(window.GetWorkspaceController())
? ResolveUIEditorDetachedWorkspaceTitle(
window.GetWorkspaceController(),
"Panel")
: (window.m_state->window.titleText.empty()
? std::string("XCEngine Editor")
: window.m_state->window.titleText),