Refactor new editor state ownership model
This commit is contained in:
@@ -118,6 +118,7 @@ if(TARGET XCUIEditorAppLib)
|
||||
list(APPEND EDITOR_APP_FEATURE_TEST_SOURCES
|
||||
test_editor_host_command_bridge.cpp
|
||||
test_editor_shell_asset_validation.cpp
|
||||
test_editor_window_workspace_store.cpp
|
||||
test_structured_editor_shell.cpp
|
||||
test_editor_window_input_routing.cpp
|
||||
test_ui_editor_panel_registry.cpp
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "Composition/EditorPanelIds.h"
|
||||
#include "Commands/EditorEditCommandRoute.h"
|
||||
#include "Commands/EditorHostCommandBridge.h"
|
||||
#include "State/EditorCommandFocusService.h"
|
||||
#include "State/EditorSession.h"
|
||||
|
||||
namespace {
|
||||
|
||||
using XCEngine::UI::Editor::App::EditorActionRoute;
|
||||
using XCEngine::UI::Editor::App::EditorCommandFocusService;
|
||||
using XCEngine::UI::Editor::App::EditorEditCommandRoute;
|
||||
using XCEngine::UI::Editor::App::EditorHostCommandBridge;
|
||||
using XCEngine::UI::Editor::App::EditorSession;
|
||||
@@ -51,7 +54,8 @@ public:
|
||||
|
||||
TEST(EditorHostCommandBridgeTest, HierarchyEditCommandsDelegateToBoundRoute) {
|
||||
EditorSession session = {};
|
||||
session.activeRoute = EditorActionRoute::Hierarchy;
|
||||
EditorCommandFocusService commandFocus = {};
|
||||
commandFocus.ClaimFocus(EditorActionRoute::Hierarchy);
|
||||
|
||||
StubEditCommandRoute hierarchyRoute = {};
|
||||
hierarchyRoute.evaluationResult.executable = true;
|
||||
@@ -61,6 +65,7 @@ TEST(EditorHostCommandBridgeTest, HierarchyEditCommandsDelegateToBoundRoute) {
|
||||
|
||||
EditorHostCommandBridge bridge = {};
|
||||
bridge.BindSession(session);
|
||||
bridge.BindCommandFocusService(commandFocus);
|
||||
bridge.BindEditCommandRoutes(&hierarchyRoute, nullptr, nullptr);
|
||||
|
||||
const UIEditorHostCommandEvaluationResult evaluation =
|
||||
@@ -78,7 +83,6 @@ TEST(EditorHostCommandBridgeTest, HierarchyEditCommandsDelegateToBoundRoute) {
|
||||
|
||||
TEST(EditorHostCommandBridgeTest, UnsupportedHostCommandsUseHonestMessages) {
|
||||
EditorSession session = {};
|
||||
session.activeRoute = EditorActionRoute::None;
|
||||
|
||||
EditorHostCommandBridge bridge = {};
|
||||
bridge.BindSession(session);
|
||||
@@ -100,7 +104,6 @@ TEST(EditorHostCommandBridgeTest, UnsupportedHostCommandsUseHonestMessages) {
|
||||
|
||||
TEST(EditorHostCommandBridgeTest, AssetCommandsDelegateToProjectRoute) {
|
||||
EditorSession session = {};
|
||||
session.activeRoute = EditorActionRoute::Hierarchy;
|
||||
|
||||
StubEditCommandRoute projectRoute = {};
|
||||
projectRoute.assetEvaluationResult.executable = true;
|
||||
@@ -127,7 +130,8 @@ TEST(EditorHostCommandBridgeTest, AssetCommandsDelegateToProjectRoute) {
|
||||
|
||||
TEST(EditorHostCommandBridgeTest, SceneEditCommandsDelegateToBoundSceneRoute) {
|
||||
EditorSession session = {};
|
||||
session.activeRoute = EditorActionRoute::Scene;
|
||||
EditorCommandFocusService commandFocus = {};
|
||||
commandFocus.ClaimFocus(EditorActionRoute::Scene);
|
||||
|
||||
StubEditCommandRoute sceneRoute = {};
|
||||
sceneRoute.evaluationResult.executable = true;
|
||||
@@ -137,6 +141,7 @@ TEST(EditorHostCommandBridgeTest, SceneEditCommandsDelegateToBoundSceneRoute) {
|
||||
|
||||
EditorHostCommandBridge bridge = {};
|
||||
bridge.BindSession(session);
|
||||
bridge.BindCommandFocusService(commandFocus);
|
||||
bridge.BindEditCommandRoutes(nullptr, nullptr, &sceneRoute);
|
||||
|
||||
const UIEditorHostCommandEvaluationResult evaluation =
|
||||
@@ -154,7 +159,8 @@ TEST(EditorHostCommandBridgeTest, SceneEditCommandsDelegateToBoundSceneRoute) {
|
||||
|
||||
TEST(EditorHostCommandBridgeTest, InspectorEditCommandsDelegateToBoundInspectorRoute) {
|
||||
EditorSession session = {};
|
||||
session.activeRoute = EditorActionRoute::Inspector;
|
||||
EditorCommandFocusService commandFocus = {};
|
||||
commandFocus.ClaimFocus(EditorActionRoute::Inspector);
|
||||
|
||||
StubEditCommandRoute inspectorRoute = {};
|
||||
inspectorRoute.evaluationResult.executable = true;
|
||||
@@ -164,6 +170,7 @@ TEST(EditorHostCommandBridgeTest, InspectorEditCommandsDelegateToBoundInspectorR
|
||||
|
||||
EditorHostCommandBridge bridge = {};
|
||||
bridge.BindSession(session);
|
||||
bridge.BindCommandFocusService(commandFocus);
|
||||
bridge.BindEditCommandRoutes(nullptr, nullptr, nullptr, &inspectorRoute);
|
||||
|
||||
const UIEditorHostCommandEvaluationResult evaluation =
|
||||
@@ -179,4 +186,50 @@ TEST(EditorHostCommandBridgeTest, InspectorEditCommandsDelegateToBoundInspectorR
|
||||
EXPECT_EQ(inspectorRoute.lastDispatchedCommandId, "edit.delete");
|
||||
}
|
||||
|
||||
TEST(EditorHostCommandBridgeTest, ActivePanelRouteIsUsedAsFallbackWhenNoExplicitCommandFocusExists) {
|
||||
EditorSession session = {};
|
||||
session.activePanelId = XCEngine::UI::Editor::App::kHierarchyPanelId;
|
||||
|
||||
StubEditCommandRoute hierarchyRoute = {};
|
||||
hierarchyRoute.evaluationResult.executable = true;
|
||||
hierarchyRoute.evaluationResult.message = "Hierarchy route owns rename.";
|
||||
|
||||
EditorHostCommandBridge bridge = {};
|
||||
bridge.BindSession(session);
|
||||
bridge.BindEditCommandRoutes(&hierarchyRoute, nullptr, nullptr);
|
||||
|
||||
const UIEditorHostCommandEvaluationResult evaluation =
|
||||
bridge.EvaluateHostCommand("edit.rename");
|
||||
EXPECT_TRUE(evaluation.executable);
|
||||
EXPECT_EQ(evaluation.message, "Hierarchy route owns rename.");
|
||||
}
|
||||
|
||||
TEST(EditorHostCommandBridgeTest, ExplicitCommandFocusOverridesActivePanelFallback) {
|
||||
EditorSession session = {};
|
||||
session.activePanelId = XCEngine::UI::Editor::App::kProjectPanelId;
|
||||
|
||||
EditorCommandFocusService commandFocus = {};
|
||||
commandFocus.ClaimFocus(EditorActionRoute::Scene);
|
||||
|
||||
StubEditCommandRoute projectRoute = {};
|
||||
projectRoute.evaluationResult.executable = true;
|
||||
projectRoute.evaluationResult.message = "Project route.";
|
||||
|
||||
StubEditCommandRoute sceneRoute = {};
|
||||
sceneRoute.evaluationResult.executable = true;
|
||||
sceneRoute.evaluationResult.message = "Scene route.";
|
||||
|
||||
EditorHostCommandBridge bridge = {};
|
||||
bridge.BindSession(session);
|
||||
bridge.BindCommandFocusService(commandFocus);
|
||||
bridge.BindEditCommandRoutes(nullptr, &projectRoute, &sceneRoute);
|
||||
|
||||
const UIEditorHostCommandEvaluationResult evaluation =
|
||||
bridge.EvaluateHostCommand("edit.undo");
|
||||
EXPECT_TRUE(evaluation.executable);
|
||||
EXPECT_EQ(evaluation.message, "Scene route.");
|
||||
EXPECT_EQ(sceneRoute.lastEvaluatedCommandId, "edit.undo");
|
||||
EXPECT_TRUE(projectRoute.lastEvaluatedCommandId.empty());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "Project/EditorProjectRuntime.h"
|
||||
#include "State/EditorSelectionService.h"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
@@ -168,5 +169,26 @@ TEST(EditorProjectRuntimeTests, RenameSelectedItemRemapsSelectionAndDeleteClears
|
||||
EXPECT_EQ(runtime.GetSelection().kind, EditorSelectionKind::None);
|
||||
}
|
||||
|
||||
TEST(EditorProjectRuntimeTests, BoundSelectionServiceBecomesTheSingleProjectSelectionSource) {
|
||||
TemporaryRepo repo = {};
|
||||
ASSERT_TRUE(repo.CreateDirectory("project/Assets/Scripts"));
|
||||
ASSERT_TRUE(repo.WriteFile("project/Assets/Scripts/Player.cs"));
|
||||
|
||||
EditorSelectionService selectionService = {};
|
||||
EditorProjectRuntime runtime = {};
|
||||
ASSERT_TRUE(runtime.Initialize(repo.Root()));
|
||||
runtime.BindSelectionService(&selectionService);
|
||||
ASSERT_TRUE(runtime.NavigateToFolder("Assets/Scripts"));
|
||||
|
||||
ASSERT_TRUE(runtime.SetSelection("Assets/Scripts/Player.cs"));
|
||||
EXPECT_EQ(selectionService.GetSelection().kind, EditorSelectionKind::ProjectItem);
|
||||
EXPECT_EQ(selectionService.GetSelection().itemId, "Assets/Scripts/Player.cs");
|
||||
EXPECT_EQ(runtime.GetSelection().itemId, "Assets/Scripts/Player.cs");
|
||||
|
||||
runtime.ClearSelection();
|
||||
EXPECT_EQ(selectionService.GetSelection().kind, EditorSelectionKind::None);
|
||||
EXPECT_FALSE(runtime.HasSelection());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace XCEngine::UI::Editor::App
|
||||
|
||||
160
tests/UI/Editor/unit/test_editor_window_workspace_store.cpp
Normal file
160
tests/UI/Editor/unit/test_editor_window_workspace_store.cpp
Normal file
@@ -0,0 +1,160 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "Platform/Win32/WindowManager/EditorWindowWorkspaceStore.h"
|
||||
|
||||
#include <XCEditor/Workspace/UIEditorWorkspaceController.h>
|
||||
#include <XCEditor/Workspace/UIEditorWorkspaceModel.h>
|
||||
#include <XCEditor/Workspace/UIEditorWorkspaceQueries.h>
|
||||
|
||||
namespace {
|
||||
|
||||
using XCEngine::UI::Editor::App::Internal::EditorWindowWorkspaceStore;
|
||||
using XCEngine::UI::Editor::BuildDefaultUIEditorWorkspaceController;
|
||||
using XCEngine::UI::Editor::BuildUIEditorWorkspacePanel;
|
||||
using XCEngine::UI::Editor::BuildUIEditorWorkspaceSingleTabStack;
|
||||
using XCEngine::UI::Editor::BuildUIEditorWorkspaceSplit;
|
||||
using XCEngine::UI::Editor::BuildUIEditorWorkspaceTabStack;
|
||||
using XCEngine::UI::Editor::ContainsUIEditorWorkspacePanel;
|
||||
using XCEngine::UI::Editor::FindUIEditorWindowWorkspaceState;
|
||||
using XCEngine::UI::Editor::UIEditorPanelRegistry;
|
||||
using XCEngine::UI::Editor::UIEditorWindowWorkspaceOperationStatus;
|
||||
using XCEngine::UI::Editor::UIEditorWorkspaceCommand;
|
||||
using XCEngine::UI::Editor::UIEditorWorkspaceCommandKind;
|
||||
using XCEngine::UI::Editor::UIEditorWorkspaceCommandResult;
|
||||
using XCEngine::UI::Editor::UIEditorWorkspaceCommandStatus;
|
||||
using XCEngine::UI::Editor::UIEditorWorkspaceModel;
|
||||
using XCEngine::UI::Editor::UIEditorWorkspaceSplitAxis;
|
||||
|
||||
UIEditorPanelRegistry BuildPanelRegistry() {
|
||||
UIEditorPanelRegistry registry = {};
|
||||
registry.panels = {
|
||||
{ "doc-a", "Document A", {}, true, true, true },
|
||||
{ "doc-b", "Document B", {}, true, true, true },
|
||||
{ "inspector", "Inspector", {}, true, true, true },
|
||||
};
|
||||
return registry;
|
||||
}
|
||||
|
||||
UIEditorWorkspaceModel BuildWorkspace() {
|
||||
UIEditorWorkspaceModel workspace = {};
|
||||
workspace.root = BuildUIEditorWorkspaceSplit(
|
||||
"root-split",
|
||||
UIEditorWorkspaceSplitAxis::Horizontal,
|
||||
0.7f,
|
||||
BuildUIEditorWorkspaceTabStack(
|
||||
"document-tabs",
|
||||
{
|
||||
BuildUIEditorWorkspacePanel("doc-a-node", "doc-a", "Document A", true),
|
||||
BuildUIEditorWorkspacePanel("doc-b-node", "doc-b", "Document B", true),
|
||||
},
|
||||
0u),
|
||||
BuildUIEditorWorkspaceSingleTabStack(
|
||||
"inspector-panel",
|
||||
"inspector",
|
||||
"Inspector",
|
||||
true));
|
||||
workspace.activePanelId = "doc-a";
|
||||
return workspace;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST(EditorWindowWorkspaceStoreTest, RegistersPrimaryWindowProjectionAsAuthoritativeState) {
|
||||
EditorWindowWorkspaceStore store(BuildPanelRegistry());
|
||||
auto workspaceController =
|
||||
BuildDefaultUIEditorWorkspaceController(BuildPanelRegistry(), BuildWorkspace());
|
||||
std::string error = {};
|
||||
|
||||
ASSERT_TRUE(store.RegisterWindowProjection("main", true, workspaceController, error))
|
||||
<< error;
|
||||
ASSERT_TRUE(store.HasState());
|
||||
ASSERT_EQ(store.GetWindowSet().primaryWindowId, "main");
|
||||
ASSERT_EQ(store.GetWindowSet().activeWindowId, "main");
|
||||
ASSERT_EQ(store.GetWindowSet().windows.size(), 1u);
|
||||
|
||||
const auto* mainWindow = FindUIEditorWindowWorkspaceState(store.GetWindowSet(), "main");
|
||||
ASSERT_NE(mainWindow, nullptr);
|
||||
EXPECT_EQ(mainWindow->workspace.activePanelId, "doc-a");
|
||||
EXPECT_TRUE(ContainsUIEditorWorkspacePanel(mainWindow->workspace, "doc-b"));
|
||||
}
|
||||
|
||||
TEST(EditorWindowWorkspaceStoreTest, CommitsWindowLocalProjectionBackIntoCentralStore) {
|
||||
EditorWindowWorkspaceStore store(BuildPanelRegistry());
|
||||
auto workspaceController =
|
||||
BuildDefaultUIEditorWorkspaceController(BuildPanelRegistry(), BuildWorkspace());
|
||||
std::string error = {};
|
||||
ASSERT_TRUE(store.RegisterWindowProjection("main", true, workspaceController, error))
|
||||
<< error;
|
||||
|
||||
const UIEditorWorkspaceCommandResult activateResult = workspaceController.Dispatch(
|
||||
UIEditorWorkspaceCommand{
|
||||
UIEditorWorkspaceCommandKind::ActivatePanel,
|
||||
"doc-b",
|
||||
});
|
||||
ASSERT_EQ(activateResult.status, UIEditorWorkspaceCommandStatus::Changed);
|
||||
|
||||
ASSERT_TRUE(store.CommitWindowProjection("main", workspaceController, error))
|
||||
<< error;
|
||||
|
||||
const auto* mainWindow = FindUIEditorWindowWorkspaceState(store.GetWindowSet(), "main");
|
||||
ASSERT_NE(mainWindow, nullptr);
|
||||
EXPECT_EQ(mainWindow->workspace.activePanelId, "doc-b");
|
||||
}
|
||||
|
||||
TEST(EditorWindowWorkspaceStoreTest, AppliesCrossWindowMutationAgainstCentralStore) {
|
||||
EditorWindowWorkspaceStore store(BuildPanelRegistry());
|
||||
const auto workspaceController =
|
||||
BuildDefaultUIEditorWorkspaceController(BuildPanelRegistry(), BuildWorkspace());
|
||||
std::string error = {};
|
||||
ASSERT_TRUE(store.RegisterWindowProjection("main", true, workspaceController, error))
|
||||
<< error;
|
||||
|
||||
auto mutationController = store.BuildMutationController();
|
||||
const auto detachResult = mutationController.DetachPanelToNewWindow(
|
||||
"main",
|
||||
"document-tabs",
|
||||
"doc-b",
|
||||
"doc-b-window");
|
||||
ASSERT_EQ(detachResult.status, UIEditorWindowWorkspaceOperationStatus::Changed);
|
||||
ASSERT_TRUE(store.ValidateWindowSet(mutationController.GetWindowSet(), error))
|
||||
<< error;
|
||||
store.ReplaceWindowSet(mutationController.GetWindowSet());
|
||||
|
||||
ASSERT_EQ(store.GetWindowSet().windows.size(), 2u);
|
||||
EXPECT_EQ(store.GetWindowSet().activeWindowId, "doc-b-window");
|
||||
|
||||
const auto* detachedWindow =
|
||||
FindUIEditorWindowWorkspaceState(store.GetWindowSet(), "doc-b-window");
|
||||
ASSERT_NE(detachedWindow, nullptr);
|
||||
EXPECT_TRUE(ContainsUIEditorWorkspacePanel(detachedWindow->workspace, "doc-b"));
|
||||
}
|
||||
|
||||
TEST(EditorWindowWorkspaceStoreTest, RemovingDetachedWindowRepairsActiveWindowReference) {
|
||||
EditorWindowWorkspaceStore store(BuildPanelRegistry());
|
||||
const auto workspaceController =
|
||||
BuildDefaultUIEditorWorkspaceController(BuildPanelRegistry(), BuildWorkspace());
|
||||
std::string error = {};
|
||||
ASSERT_TRUE(store.RegisterWindowProjection("main", true, workspaceController, error))
|
||||
<< error;
|
||||
|
||||
auto mutationController = store.BuildMutationController();
|
||||
ASSERT_EQ(
|
||||
mutationController.DetachPanelToNewWindow(
|
||||
"main",
|
||||
"document-tabs",
|
||||
"doc-b",
|
||||
"doc-b-window").status,
|
||||
UIEditorWindowWorkspaceOperationStatus::Changed);
|
||||
ASSERT_TRUE(store.ValidateWindowSet(mutationController.GetWindowSet(), error))
|
||||
<< error;
|
||||
store.ReplaceWindowSet(mutationController.GetWindowSet());
|
||||
|
||||
store.RemoveWindow("doc-b-window", false);
|
||||
|
||||
EXPECT_EQ(store.GetWindowSet().windows.size(), 1u);
|
||||
EXPECT_EQ(store.GetWindowSet().primaryWindowId, "main");
|
||||
EXPECT_EQ(store.GetWindowSet().activeWindowId, "main");
|
||||
EXPECT_EQ(
|
||||
FindUIEditorWindowWorkspaceState(store.GetWindowSet(), "doc-b-window"),
|
||||
nullptr);
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
#include "Features/Scene/SceneViewportController.h"
|
||||
#include "Features/Inspector/InspectorSubject.h"
|
||||
#include "Rendering/Viewport/ViewportHostService.h"
|
||||
#include "State/EditorSelectionStamp.h"
|
||||
#include "State/EditorSelectionService.h"
|
||||
|
||||
#include "Composition/EditorPanelIds.h"
|
||||
#include <XCEditor/Viewport/UIEditorViewportInputBridge.h>
|
||||
@@ -399,30 +399,35 @@ TEST(SceneViewportRuntimeTests, SelectionStampAdvancesOnSceneSelectionChanges) {
|
||||
EXPECT_GT(runtime.GetSelectionStamp(), clearedStamp);
|
||||
}
|
||||
|
||||
TEST(SceneViewportRuntimeTests, InspectorSelectionResolverFollowsLatestSelectionDomain) {
|
||||
TEST(SceneViewportRuntimeTests, InspectorSelectionResolverFollowsUnifiedSelectionSnapshot) {
|
||||
ScopedSceneManagerReset reset = {};
|
||||
TemporaryProjectRoot projectRoot = {};
|
||||
SaveMainScene(projectRoot, Math::Vector3(4.0f, 5.0f, 6.0f));
|
||||
|
||||
EditorSelectionService selectionService = {};
|
||||
EditorSceneRuntime runtime = {};
|
||||
ASSERT_TRUE(runtime.Initialize(projectRoot.Root()));
|
||||
runtime.BindSelectionService(&selectionService);
|
||||
runtime.EnsureSceneSelection();
|
||||
ASSERT_TRUE(runtime.HasSceneSelection());
|
||||
|
||||
EditorSession session = {};
|
||||
session.selection = selectionService.GetSelection();
|
||||
EXPECT_EQ(
|
||||
ResolveInspectorSelectionSource(EditorSession{}, runtime),
|
||||
ResolveInspectorSelectionSource(session, runtime),
|
||||
InspectorSelectionSource::Scene);
|
||||
const InspectorSubject sceneSubject =
|
||||
BuildInspectorSubject(EditorSession{}, runtime);
|
||||
BuildInspectorSubject(session, runtime);
|
||||
EXPECT_EQ(sceneSubject.kind, InspectorSubjectKind::SceneObject);
|
||||
EXPECT_EQ(sceneSubject.source, InspectorSelectionSource::Scene);
|
||||
EXPECT_EQ(sceneSubject.sceneObject.displayName, "Target");
|
||||
|
||||
EditorSession session = {};
|
||||
session.selection.kind = EditorSelectionKind::ProjectItem;
|
||||
session.selection.itemId = "asset:scene";
|
||||
session.selection.displayName = "Main";
|
||||
session.selection.absolutePath = projectRoot.MainScenePath();
|
||||
session.selection.stamp = GenerateEditorSelectionStamp();
|
||||
selectionService.SetProjectSelection(
|
||||
"asset:scene",
|
||||
"Main",
|
||||
projectRoot.MainScenePath(),
|
||||
false);
|
||||
session.selection = selectionService.GetSelection();
|
||||
EXPECT_EQ(
|
||||
ResolveInspectorSelectionSource(session, runtime),
|
||||
InspectorSelectionSource::Project);
|
||||
@@ -432,24 +437,34 @@ TEST(SceneViewportRuntimeTests, InspectorSelectionResolverFollowsLatestSelection
|
||||
EXPECT_EQ(projectSubject.source, InspectorSelectionSource::Project);
|
||||
EXPECT_EQ(projectSubject.projectAsset.selection.itemId, "asset:scene");
|
||||
|
||||
runtime.EnsureSceneSelection();
|
||||
session.selection = selectionService.GetSelection();
|
||||
EXPECT_EQ(
|
||||
ResolveInspectorSelectionSource(session, runtime),
|
||||
InspectorSelectionSource::Project);
|
||||
EXPECT_EQ(
|
||||
BuildInspectorSubject(session, runtime).kind,
|
||||
InspectorSubjectKind::ProjectAsset);
|
||||
|
||||
runtime.ClearSelection();
|
||||
session.selection = selectionService.GetSelection();
|
||||
EXPECT_EQ(
|
||||
ResolveInspectorSelectionSource(session, runtime),
|
||||
InspectorSelectionSource::None);
|
||||
EXPECT_EQ(
|
||||
BuildInspectorSubject(session, runtime).kind,
|
||||
InspectorSubjectKind::None);
|
||||
|
||||
runtime.EnsureSceneSelection();
|
||||
session.selection = selectionService.GetSelection();
|
||||
EXPECT_EQ(
|
||||
ResolveInspectorSelectionSource(session, runtime),
|
||||
InspectorSelectionSource::Scene);
|
||||
|
||||
session.selection = {};
|
||||
session.selection.stamp = GenerateEditorSelectionStamp();
|
||||
EXPECT_EQ(
|
||||
ResolveInspectorSelectionSource(session, runtime),
|
||||
InspectorSelectionSource::None);
|
||||
selectionService.SetProjectSelection(
|
||||
"asset:scene",
|
||||
"Main",
|
||||
projectRoot.MainScenePath(),
|
||||
false);
|
||||
runtime.EnsureSceneSelection();
|
||||
EXPECT_EQ(selectionService.GetSelection().kind, EditorSelectionKind::ProjectItem);
|
||||
EXPECT_EQ(selectionService.GetSelection().itemId, "asset:scene");
|
||||
}
|
||||
|
||||
TEST(SceneViewportRuntimeTests, RightMouseDragRotatesSceneCameraThroughViewportController) {
|
||||
|
||||
Reference in New Issue
Block a user