Refactor editor workspace panel bindings

This commit is contained in:
2026-04-29 13:29:17 +08:00
parent a8e1a2b097
commit da6f37dafe
14 changed files with 213 additions and 106 deletions

View File

@@ -9,13 +9,12 @@
#include "Scene/SceneEditCommandRoute.h"
#include "Scene/SceneViewportFeature.h"
#include "Product/EditorProductManifest.h"
#include "Windowing/EditorFrameServices.h"
#include <XCEditor/Panels/UIEditorHostedPanelDispatch.h>
#include <filesystem>
#include <memory>
#include <sstream>
#include <utility>
namespace XCEngine::UI::Editor::App {
@@ -28,22 +27,6 @@ constexpr int kProjectUpdatePriority = 20;
constexpr int kInspectorUpdatePriority = 30;
constexpr int kConsoleUpdatePriority = 40;
void RequestUtilityWindowFromFrameServices(
void* requester,
EditorUtilityWindowKind kind) {
auto* frameServices = static_cast<EditorFrameServices*>(requester);
if (frameServices != nullptr) {
frameServices->RequestOpenUtilityWindow(kind);
}
}
bool RequestSceneAssetFromFrameServices(
void* requester,
const std::filesystem::path& scenePath) {
auto* frameServices = static_cast<EditorFrameServices*>(requester);
return frameServices != nullptr && frameServices->RequestOpenSceneAsset(scenePath);
}
const UIEditorHostedPanelDispatchEntry& ResolveHostedPanelDispatchEntry(
const UIEditorHostedPanelDispatchFrame& dispatchFrame,
std::string_view panelId) {
@@ -183,6 +166,9 @@ std::string DescribeHierarchyPanelEvent(const HierarchyPanel::Event& event) {
class ConsoleWorkspacePanel final : public EditorWorkspacePanel {
public:
explicit ConsoleWorkspacePanel(const EditorSession& session)
: m_session(session) {}
std::string_view GetPanelId() const override {
return kConsolePanelId;
}
@@ -205,7 +191,7 @@ public:
void Update(const EditorWorkspacePanelUpdateContext& context) override {
m_panel.Update(
context.frameServices.GetSession(),
m_session,
ResolveHostedPanelDispatchEntry(
context.shellFrame.hostedPanelDispatchFrame,
GetPanelId()));
@@ -216,11 +202,18 @@ public:
}
private:
const EditorSession& m_session;
ConsolePanel m_panel = {};
};
class HierarchyWorkspacePanel final : public EditorWorkspacePanel {
public:
HierarchyWorkspacePanel(
EditorSceneRuntime& sceneRuntime,
EditorCommandFocusService& commandFocusService)
: m_sceneRuntime(sceneRuntime)
, m_commandFocusService(commandFocusService) {}
std::string_view GetPanelId() const override {
return kHierarchyPanelId;
}
@@ -247,11 +240,9 @@ public:
m_panel.ResetInteractionState();
}
void PrepareForShellDefinition(
EditorFrameServices& frameServices,
UIEditorWorkspaceController&) override {
m_panel.SetSceneRuntime(&frameServices.GetSceneRuntime());
m_panel.SetCommandFocusService(&frameServices.GetCommandFocusService());
void PrepareForShellDefinition(UIEditorWorkspaceController&) override {
m_panel.SetSceneRuntime(&m_sceneRuntime);
m_panel.SetCommandFocusService(&m_commandFocusService);
}
void Update(const EditorWorkspacePanelUpdateContext& context) override {
@@ -287,11 +278,27 @@ public:
}
private:
EditorSceneRuntime& m_sceneRuntime;
EditorCommandFocusService& m_commandFocusService;
HierarchyPanel m_panel = {};
};
class InspectorWorkspacePanel final : public EditorWorkspacePanel {
public:
InspectorWorkspacePanel(
const EditorSession& session,
EditorCommandFocusService& commandFocusService,
EditorProjectRuntime& projectRuntime,
EditorSceneRuntime& sceneRuntime,
EditorColorPickerToolState& colorPickerToolState,
RequestOpenUtilityWindowCallback requestOpenUtilityWindow)
: m_session(session)
, m_commandFocusService(commandFocusService)
, m_projectRuntime(projectRuntime)
, m_sceneRuntime(sceneRuntime)
, m_colorPickerToolState(colorPickerToolState)
, m_requestOpenUtilityWindow(std::move(requestOpenUtilityWindow)) {}
std::string_view GetPanelId() const override {
return kInspectorPanelId;
}
@@ -309,15 +316,14 @@ public:
}
void Update(const EditorWorkspacePanelUpdateContext& context) override {
m_panel.SetCommandFocusService(&context.frameServices.GetCommandFocusService());
m_panel.SetCommandFocusService(&m_commandFocusService);
InspectorPanelContext panelContext{
.session = context.frameServices.GetSession(),
.projectRuntime = context.frameServices.GetProjectRuntime(),
.sceneRuntime = context.frameServices.GetSceneRuntime(),
.colorPickerToolState = context.frameServices.GetColorPickerToolState(),
.textMeasurer = context.frameServices.GetTextMeasurer(),
.utilityWindowRequester = &context.frameServices,
.requestUtilityWindow = RequestUtilityWindowFromFrameServices,
.session = m_session,
.projectRuntime = m_projectRuntime,
.sceneRuntime = m_sceneRuntime,
.colorPickerToolState = m_colorPickerToolState,
.textMeasurer = m_textMeasurer,
.requestOpenUtilityWindow = m_requestOpenUtilityWindow,
};
m_panel.Update(
panelContext,
@@ -331,16 +337,37 @@ public:
m_panel.Append(drawList);
}
void Initialize(const EditorWorkspacePanelInitializationContext& context) override {
m_textMeasurer = &context.textMeasurer;
}
EditorEditCommandRoute* GetEditCommandRoute() override {
return &m_panel;
}
private:
const EditorSession& m_session;
EditorCommandFocusService& m_commandFocusService;
EditorProjectRuntime& m_projectRuntime;
EditorSceneRuntime& m_sceneRuntime;
EditorColorPickerToolState& m_colorPickerToolState;
RequestOpenUtilityWindowCallback m_requestOpenUtilityWindow = {};
const UIEditorTextMeasurer* m_textMeasurer = nullptr;
InspectorPanel m_panel = {};
};
class ProjectWorkspacePanel final : public EditorWorkspacePanel {
public:
ProjectWorkspacePanel(
EditorProjectRuntime& projectRuntime,
EditorCommandFocusService& commandFocusService,
::XCEngine::UI::Editor::System::SystemInteractionService* systemInteractionHost,
RequestOpenSceneAssetCallback requestOpenSceneAsset)
: m_projectRuntime(projectRuntime)
, m_commandFocusService(commandFocusService)
, m_systemInteractionHost(systemInteractionHost)
, m_requestOpenSceneAsset(std::move(requestOpenSceneAsset)) {}
std::string_view GetPanelId() const override {
return kProjectPanelId;
}
@@ -367,12 +394,10 @@ public:
}
void Update(const EditorWorkspacePanelUpdateContext& context) override {
m_panel.SetProjectRuntime(&context.frameServices.GetProjectRuntime());
m_panel.SetCommandFocusService(&context.frameServices.GetCommandFocusService());
m_panel.SetSystemInteractionHost(context.frameServices.GetSystemInteractionHost());
m_panel.SetSceneAssetOpenRequestHandler(
&context.frameServices,
RequestSceneAssetFromFrameServices);
m_panel.SetProjectRuntime(&m_projectRuntime);
m_panel.SetCommandFocusService(&m_commandFocusService);
m_panel.SetSystemInteractionHost(m_systemInteractionHost);
m_panel.SetSceneAssetOpenRequestHandler(m_requestOpenSceneAsset);
m_panel.Update(
ResolveHostedPanelDispatchEntry(
context.shellFrame.hostedPanelDispatchFrame,
@@ -415,11 +440,21 @@ public:
}
private:
EditorProjectRuntime& m_projectRuntime;
EditorCommandFocusService& m_commandFocusService;
::XCEngine::UI::Editor::System::SystemInteractionService* m_systemInteractionHost = nullptr;
RequestOpenSceneAssetCallback m_requestOpenSceneAsset = {};
ProjectPanel m_panel = {};
};
class SceneWorkspacePanel final : public EditorWorkspacePanel {
public:
SceneWorkspacePanel(
EditorSceneRuntime& sceneRuntime,
EditorCommandFocusService& commandFocusService)
: m_sceneRuntime(sceneRuntime)
, m_commandFocusService(commandFocusService) {}
std::string_view GetPanelId() const override {
return kScenePanelId;
}
@@ -454,17 +489,15 @@ public:
m_feature.ResetInteractionState();
}
void PrepareForShellDefinition(
EditorFrameServices& frameServices,
UIEditorWorkspaceController&) override {
m_commandRoute.BindSceneRuntime(&frameServices.GetSceneRuntime());
m_feature.SetCommandFocusService(&frameServices.GetCommandFocusService());
m_feature.SyncRenderRequest(frameServices.GetSceneRuntime());
void PrepareForShellDefinition(UIEditorWorkspaceController&) override {
m_commandRoute.BindSceneRuntime(&m_sceneRuntime);
m_feature.SetCommandFocusService(&m_commandFocusService);
m_feature.SyncRenderRequest(m_sceneRuntime);
}
void Update(const EditorWorkspacePanelUpdateContext& context) override {
m_feature.Update(
context.frameServices.GetSceneRuntime(),
m_sceneRuntime,
context.shellInteractionState.workspaceInteractionState.composeState,
context.shellFrame.workspaceInteractionFrame.composeFrame);
}
@@ -478,12 +511,17 @@ public:
}
private:
EditorSceneRuntime& m_sceneRuntime;
EditorCommandFocusService& m_commandFocusService;
SceneViewportFeature m_feature = {};
SceneEditCommandRoute m_commandRoute = {};
};
class GameWorkspacePanel final : public EditorWorkspacePanel {
public:
explicit GameWorkspacePanel(EditorCommandFocusService& commandFocusService)
: m_commandFocusService(commandFocusService) {}
std::string_view GetPanelId() const override {
return kGamePanelId;
}
@@ -509,10 +547,8 @@ public:
m_feature.ResetInteractionState();
}
void PrepareForShellDefinition(
EditorFrameServices& frameServices,
UIEditorWorkspaceController&) override {
m_feature.SetCommandFocusService(&frameServices.GetCommandFocusService());
void PrepareForShellDefinition(UIEditorWorkspaceController&) override {
m_feature.SetCommandFocusService(&m_commandFocusService);
}
void Update(const EditorWorkspacePanelUpdateContext& context) override {
@@ -526,24 +562,47 @@ public:
}
private:
EditorCommandFocusService& m_commandFocusService;
GameViewportFeature m_feature = {};
};
std::unique_ptr<EditorWorkspacePanel> CreateWorkspacePanelRuntime(
const EditorProductPanelDescriptor& panel) {
const EditorProductPanelDescriptor& panel,
const EditorSession& session,
EditorCommandFocusService& commandFocusService,
EditorProjectRuntime& projectRuntime,
EditorSceneRuntime& sceneRuntime,
EditorColorPickerToolState& colorPickerToolState,
::XCEngine::UI::Editor::System::SystemInteractionService* systemInteractionHost,
const RequestOpenUtilityWindowCallback& requestOpenUtilityWindow,
const RequestOpenSceneAssetCallback& requestOpenSceneAsset) {
switch (panel.runtimeKind) {
case EditorProductPanelRuntimeKind::Console:
return std::make_unique<ConsoleWorkspacePanel>();
return std::make_unique<ConsoleWorkspacePanel>(session);
case EditorProductPanelRuntimeKind::Game:
return std::make_unique<GameWorkspacePanel>();
return std::make_unique<GameWorkspacePanel>(commandFocusService);
case EditorProductPanelRuntimeKind::Hierarchy:
return std::make_unique<HierarchyWorkspacePanel>();
return std::make_unique<HierarchyWorkspacePanel>(
sceneRuntime,
commandFocusService);
case EditorProductPanelRuntimeKind::Inspector:
return std::make_unique<InspectorWorkspacePanel>();
return std::make_unique<InspectorWorkspacePanel>(
session,
commandFocusService,
projectRuntime,
sceneRuntime,
colorPickerToolState,
requestOpenUtilityWindow);
case EditorProductPanelRuntimeKind::Project:
return std::make_unique<ProjectWorkspacePanel>();
return std::make_unique<ProjectWorkspacePanel>(
projectRuntime,
commandFocusService,
systemInteractionHost,
requestOpenSceneAsset);
case EditorProductPanelRuntimeKind::Scene:
return std::make_unique<SceneWorkspacePanel>();
return std::make_unique<SceneWorkspacePanel>(
sceneRuntime,
commandFocusService);
case EditorProductPanelRuntimeKind::None:
default:
return nullptr;
@@ -552,11 +611,28 @@ std::unique_ptr<EditorWorkspacePanel> CreateWorkspacePanelRuntime(
} // namespace
EditorWorkspacePanelRuntimeSet CreateEditorWorkspacePanelRuntimeSet() {
EditorWorkspacePanelRuntimeSet CreateEditorWorkspacePanelRuntimeSet(
const EditorSession& session,
EditorCommandFocusService& commandFocusService,
EditorProjectRuntime& projectRuntime,
EditorSceneRuntime& sceneRuntime,
EditorColorPickerToolState& colorPickerToolState,
::XCEngine::UI::Editor::System::SystemInteractionService* systemInteractionHost,
RequestOpenUtilityWindowCallback requestOpenUtilityWindow,
RequestOpenSceneAssetCallback requestOpenSceneAsset) {
EditorWorkspacePanelRuntimeSet panels = {};
for (const EditorProductPanelDescriptor& panel : GetEditorProductPanels()) {
if (std::unique_ptr<EditorWorkspacePanel> runtime =
CreateWorkspacePanelRuntime(panel);
CreateWorkspacePanelRuntime(
panel,
session,
commandFocusService,
projectRuntime,
sceneRuntime,
colorPickerToolState,
systemInteractionHost,
requestOpenUtilityWindow,
requestOpenSceneAsset);
runtime != nullptr) {
panels.AddPanel(std::move(runtime));
}