refactor(new_editor/app): reorganize host structure and add smoke test

This commit is contained in:
2026-04-15 08:24:06 +08:00
parent 3617b4840b
commit 9e5954cf0a
235 changed files with 11157 additions and 10028 deletions

View File

@@ -0,0 +1,332 @@
#include <XCEditor/Workspace/UIEditorWorkspaceCompose.h>
#include <algorithm>
#include <utility>
namespace XCEngine::UI::Editor {
namespace {
using Widgets::AppendUIEditorDockHostBackground;
using Widgets::AppendUIEditorDockHostForeground;
using Widgets::AppendUIEditorViewportSlotBackground;
using Widgets::AppendUIEditorViewportSlotForeground;
using Widgets::BuildUIEditorDockHostLayout;
using Widgets::UIEditorDockHostForegroundOptions;
const UIEditorWorkspacePanelPresentationState* FindPanelStateImpl(
const UIEditorWorkspaceComposeState& state,
std::string_view panelId) {
for (const UIEditorWorkspacePanelPresentationState& panelState : state.panelStates) {
if (panelState.panelId == panelId) {
return &panelState;
}
}
return nullptr;
}
UIEditorWorkspacePanelPresentationState* FindMutablePanelStateImpl(
UIEditorWorkspaceComposeState& state,
std::string_view panelId) {
for (UIEditorWorkspacePanelPresentationState& panelState : state.panelStates) {
if (panelState.panelId == panelId) {
return &panelState;
}
}
return nullptr;
}
bool SupportsExternalViewportPresentation(
const UIEditorPanelRegistry& panelRegistry,
const UIEditorWorkspacePanelPresentationModel& presentation) {
if (presentation.kind != UIEditorPanelPresentationKind::ViewportShell) {
return false;
}
const UIEditorPanelDescriptor* descriptor =
FindUIEditorPanelDescriptor(panelRegistry, presentation.panelId);
return descriptor != nullptr &&
descriptor->presentationKind == UIEditorPanelPresentationKind::ViewportShell;
}
std::vector<UIEditorPanelContentHostBinding> BuildContentHostBindings(
const UIEditorPanelRegistry& panelRegistry,
const std::vector<UIEditorWorkspacePanelPresentationModel>& presentations) {
std::vector<UIEditorPanelContentHostBinding> bindings = {};
bindings.reserve(presentations.size());
for (const UIEditorWorkspacePanelPresentationModel& presentation : presentations) {
const UIEditorPanelDescriptor* descriptor =
FindUIEditorPanelDescriptor(panelRegistry, presentation.panelId);
if (descriptor == nullptr ||
descriptor->presentationKind != presentation.kind ||
!IsUIEditorPanelPresentationExternallyHosted(presentation.kind)) {
continue;
}
UIEditorPanelContentHostBinding binding = {};
binding.panelId = presentation.panelId;
binding.kind = presentation.kind;
bindings.push_back(std::move(binding));
}
return bindings;
}
UIEditorWorkspacePanelPresentationState& EnsurePanelState(
UIEditorWorkspaceComposeState& state,
std::string_view panelId) {
for (UIEditorWorkspacePanelPresentationState& panelState : state.panelStates) {
if (panelState.panelId == panelId) {
return panelState;
}
}
UIEditorWorkspacePanelPresentationState panelState = {};
panelState.panelId = std::string(panelId);
state.panelStates.push_back(std::move(panelState));
return state.panelStates.back();
}
void ResetHiddenViewportPresentationState(
UIEditorWorkspaceComposeState& state,
std::string_view panelId) {
UIEditorWorkspacePanelPresentationState* panelState =
FindMutablePanelStateImpl(state, panelId);
if (panelState == nullptr) {
return;
}
panelState->viewportShellState = {};
}
void TrimObsoleteViewportPresentationStates(
UIEditorWorkspaceComposeState& state,
const UIEditorPanelRegistry& panelRegistry,
const std::vector<UIEditorWorkspacePanelPresentationModel>& presentations) {
state.panelStates.erase(
std::remove_if(
state.panelStates.begin(),
state.panelStates.end(),
[&](const UIEditorWorkspacePanelPresentationState& panelState) {
for (const UIEditorWorkspacePanelPresentationModel& presentation : presentations) {
if (presentation.panelId == panelState.panelId &&
SupportsExternalViewportPresentation(panelRegistry, presentation)) {
return false;
}
}
return true;
}),
state.panelStates.end());
}
} // namespace
const UIEditorWorkspacePanelPresentationModel* FindUIEditorWorkspacePanelPresentationModel(
const std::vector<UIEditorWorkspacePanelPresentationModel>& presentations,
std::string_view panelId) {
for (const UIEditorWorkspacePanelPresentationModel& presentation : presentations) {
if (presentation.panelId == panelId) {
return &presentation;
}
}
return nullptr;
}
const UIEditorWorkspacePanelPresentationState* FindUIEditorWorkspacePanelPresentationState(
const UIEditorWorkspaceComposeState& state,
std::string_view panelId) {
return FindPanelStateImpl(state, panelId);
}
const UIEditorWorkspaceViewportComposeRequest* FindUIEditorWorkspaceViewportPresentationRequest(
const UIEditorWorkspaceComposeRequest& request,
std::string_view panelId) {
for (const UIEditorWorkspaceViewportComposeRequest& viewportRequest : request.viewportRequests) {
if (viewportRequest.panelId == panelId) {
return &viewportRequest;
}
}
return nullptr;
}
const UIEditorWorkspaceViewportComposeFrame* FindUIEditorWorkspaceViewportPresentationFrame(
const UIEditorWorkspaceComposeFrame& frame,
std::string_view panelId) {
for (const UIEditorWorkspaceViewportComposeFrame& viewportFrame : frame.viewportFrames) {
if (viewportFrame.panelId == panelId) {
return &viewportFrame;
}
}
return nullptr;
}
UIEditorWorkspaceComposeRequest ResolveUIEditorWorkspaceComposeRequest(
const ::XCEngine::UI::UIRect& bounds,
const UIEditorPanelRegistry& panelRegistry,
const UIEditorWorkspaceModel& workspace,
const UIEditorWorkspaceSession& session,
const std::vector<UIEditorWorkspacePanelPresentationModel>& presentations,
const Widgets::UIEditorDockHostState& dockHostState,
const Widgets::UIEditorDockHostMetrics& dockHostMetrics,
const Widgets::UIEditorViewportSlotMetrics& viewportMetrics) {
UIEditorWorkspaceComposeRequest request = {};
request.dockHostLayout = BuildUIEditorDockHostLayout(
bounds,
panelRegistry,
workspace,
session,
dockHostState,
dockHostMetrics);
const std::vector<UIEditorPanelContentHostBinding> contentHostBindings =
BuildContentHostBindings(panelRegistry, presentations);
request.contentHostRequest = ResolveUIEditorPanelContentHostRequest(
request.dockHostLayout,
panelRegistry,
contentHostBindings);
for (const UIEditorPanelContentHostMountRequest& mountRequest :
request.contentHostRequest.mountRequests) {
if (mountRequest.kind != UIEditorPanelPresentationKind::ViewportShell) {
continue;
}
const UIEditorWorkspacePanelPresentationModel* presentation =
FindUIEditorWorkspacePanelPresentationModel(presentations, mountRequest.panelId);
if (presentation == nullptr ||
!SupportsExternalViewportPresentation(panelRegistry, *presentation)) {
continue;
}
UIEditorWorkspaceViewportComposeRequest viewportRequest = {};
viewportRequest.panelId = mountRequest.panelId;
viewportRequest.bounds = mountRequest.bounds;
viewportRequest.viewportShellRequest = ResolveUIEditorViewportShellRequest(
mountRequest.bounds,
presentation->viewportShellModel.spec,
viewportMetrics);
request.viewportRequests.push_back(std::move(viewportRequest));
}
return request;
}
UIEditorWorkspaceComposeFrame UpdateUIEditorWorkspaceCompose(
UIEditorWorkspaceComposeState& state,
const ::XCEngine::UI::UIRect& bounds,
const UIEditorPanelRegistry& panelRegistry,
const UIEditorWorkspaceModel& workspace,
const UIEditorWorkspaceSession& session,
const std::vector<UIEditorWorkspacePanelPresentationModel>& presentations,
const std::vector<::XCEngine::UI::UIInputEvent>& inputEvents,
const Widgets::UIEditorDockHostState& dockHostState,
const Widgets::UIEditorDockHostMetrics& dockHostMetrics,
const Widgets::UIEditorViewportSlotMetrics& viewportMetrics) {
UIEditorWorkspaceComposeFrame frame = {};
frame.dockHostLayout = BuildUIEditorDockHostLayout(
bounds,
panelRegistry,
workspace,
session,
dockHostState,
dockHostMetrics);
const std::vector<UIEditorPanelContentHostBinding> contentHostBindings =
BuildContentHostBindings(panelRegistry, presentations);
const UIEditorPanelContentHostRequest contentHostRequest =
ResolveUIEditorPanelContentHostRequest(
frame.dockHostLayout,
panelRegistry,
contentHostBindings);
frame.contentHostFrame = UpdateUIEditorPanelContentHost(
state.contentHostState,
contentHostRequest,
panelRegistry,
contentHostBindings);
TrimObsoleteViewportPresentationStates(state, panelRegistry, presentations);
for (const UIEditorWorkspacePanelPresentationModel& presentation : presentations) {
if (!SupportsExternalViewportPresentation(panelRegistry, presentation)) {
continue;
}
const UIEditorPanelContentHostPanelState* contentHostPanelState =
FindUIEditorPanelContentHostPanelState(frame.contentHostFrame, presentation.panelId);
if (contentHostPanelState == nullptr || !contentHostPanelState->mounted) {
ResetHiddenViewportPresentationState(state, presentation.panelId);
continue;
}
UIEditorWorkspacePanelPresentationState& panelState =
EnsurePanelState(state, presentation.panelId);
UIEditorWorkspaceViewportComposeFrame viewportFrame = {};
viewportFrame.panelId = presentation.panelId;
viewportFrame.bounds = contentHostPanelState->bounds;
viewportFrame.viewportShellModel = presentation.viewportShellModel;
viewportFrame.viewportShellFrame = UpdateUIEditorViewportShell(
panelState.viewportShellState,
contentHostPanelState->bounds,
presentation.viewportShellModel,
inputEvents,
viewportMetrics);
frame.viewportFrames.push_back(std::move(viewportFrame));
}
return frame;
}
std::vector<std::string> CollectUIEditorWorkspaceComposeExternalBodyPanelIds(
const UIEditorWorkspaceComposeFrame& frame) {
return CollectMountedUIEditorPanelContentHostPanelIds(frame.contentHostFrame);
}
void AppendUIEditorWorkspaceCompose(
::XCEngine::UI::UIDrawList& drawList,
const UIEditorWorkspaceComposeFrame& frame,
const Widgets::UIEditorDockHostPalette& dockHostPalette,
const Widgets::UIEditorDockHostMetrics& dockHostMetrics,
const Widgets::UIEditorViewportSlotPalette& viewportPalette,
const Widgets::UIEditorViewportSlotMetrics& viewportMetrics) {
AppendUIEditorDockHostBackground(
drawList,
frame.dockHostLayout,
dockHostPalette,
dockHostMetrics);
for (const UIEditorWorkspaceViewportComposeFrame& viewportFrame : frame.viewportFrames) {
AppendUIEditorViewportSlotBackground(
drawList,
viewportFrame.viewportShellFrame.slotLayout,
viewportFrame.viewportShellModel.spec.toolItems,
viewportFrame.viewportShellModel.spec.statusSegments,
viewportFrame.viewportShellFrame.slotState,
viewportPalette,
viewportMetrics);
AppendUIEditorViewportSlotForeground(
drawList,
viewportFrame.viewportShellFrame.slotLayout,
viewportFrame.viewportShellModel.spec.chrome,
viewportFrame.viewportShellModel.frame,
viewportFrame.viewportShellModel.spec.toolItems,
viewportFrame.viewportShellModel.spec.statusSegments,
viewportFrame.viewportShellFrame.slotState,
viewportPalette,
viewportMetrics);
}
UIEditorDockHostForegroundOptions foregroundOptions = {};
foregroundOptions.externalBodyPanelIds =
CollectUIEditorWorkspaceComposeExternalBodyPanelIds(frame);
AppendUIEditorDockHostForeground(
drawList,
frame.dockHostLayout,
foregroundOptions,
dockHostPalette,
dockHostMetrics);
}
} // namespace XCEngine::UI::Editor