Formalize scene viewport chrome and presentation helpers

This commit is contained in:
2026-04-04 13:50:34 +08:00
parent a3ba08bb99
commit bd35b8b4e8
9 changed files with 626 additions and 269 deletions

View File

@@ -28,16 +28,21 @@ using XCEngine::Editor::IProjectManager;
using XCEngine::Editor::ISceneManager;
using XCEngine::Editor::ISelectionManager;
using XCEngine::Editor::IViewportHostService;
using XCEngine::Editor::RefreshAndDrawSceneViewportPresentation;
using XCEngine::Editor::SceneSnapshot;
using XCEngine::Editor::SceneViewportInteractionActions;
using XCEngine::Editor::SceneViewportInput;
using XCEngine::Editor::SceneViewportInteractionFrameState;
using XCEngine::Editor::SceneViewportNavigationUpdate;
using XCEngine::Editor::SceneViewportOrientationAxis;
using XCEngine::Editor::SceneViewportOverlayData;
using XCEngine::Editor::SceneViewportOverlayFrameData;
using XCEngine::Editor::SceneViewportPivotMode;
using XCEngine::Editor::SceneViewportPresentationRequest;
using XCEngine::Editor::SceneViewportToolMode;
using XCEngine::Editor::SceneViewportTransformGizmoOverlayState;
using XCEngine::Editor::SceneViewportTransformSpaceMode;
using XCEngine::Editor::ShouldFocusSceneViewportAfterInteraction;
using XCEngine::Rendering::RenderContext;
class EmptySelectionManager : public ISelectionManager {
@@ -335,3 +340,82 @@ TEST(SceneViewportInteractionFrameTest, ResolveRequestCopiesFrameStateAndViewpor
EXPECT_FLOAT_EQ(request.absoluteMousePosition.x, 180.0f);
EXPECT_FLOAT_EQ(request.absoluteMousePosition.y, 260.0f);
}
TEST(SceneViewportInteractionFrameTest, FocusHelperTracksToolActionsAndNavigationBegins) {
const SceneViewportInteractionActions noActions = {};
const SceneViewportNavigationUpdate noNavigation = {};
EXPECT_FALSE(ShouldFocusSceneViewportAfterInteraction(false, noActions, noNavigation));
EXPECT_TRUE(ShouldFocusSceneViewportAfterInteraction(true, noActions, noNavigation));
SceneViewportInteractionActions clickActions = {};
clickActions.sceneIconClick = true;
EXPECT_TRUE(ShouldFocusSceneViewportAfterInteraction(false, clickActions, noNavigation));
SceneViewportNavigationUpdate navigationUpdate = {};
navigationUpdate.beginPanDrag = true;
EXPECT_TRUE(ShouldFocusSceneViewportAfterInteraction(false, noActions, navigationUpdate));
}
TEST(SceneViewportInteractionFrameTest, PresentationHelperSkipsNonInteractiveViewport) {
StubEditorContext context = {};
StubViewportHostService viewportHostService = {};
context.viewportHostService = &viewportHostService;
XCEngine::Editor::SceneViewportMoveGizmo moveGizmo = {};
XCEngine::Editor::SceneViewportRotateGizmo rotateGizmo = {};
XCEngine::Editor::SceneViewportScaleGizmo scaleGizmo = {};
SceneViewportPresentationRequest request = {};
request.context = &context;
request.viewportHostService = &viewportHostService;
request.hasInteractiveViewport = false;
request.geometry = BuildSceneViewportFrameGeometry(
ImVec2(640.0f, 360.0f),
ImVec2(10.0f, 20.0f),
ImVec2(40.0f, 60.0f));
request.gizmoFrameOptions = BuildSceneViewportToolState(
SceneViewportToolMode::Move,
SceneViewportPivotMode::Pivot,
SceneViewportTransformSpaceMode::Global)
.gizmoFrameOptions;
request.moveGizmo = &moveGizmo;
request.rotateGizmo = &rotateGizmo;
request.scaleGizmo = &scaleGizmo;
RefreshAndDrawSceneViewportPresentation(request);
EXPECT_EQ(viewportHostService.submissionCount, 0);
}
TEST(SceneViewportInteractionFrameTest, PresentationHelperRefreshesInteractiveViewportWithoutDrawList) {
StubEditorContext context = {};
StubViewportHostService viewportHostService = {};
context.viewportHostService = &viewportHostService;
viewportHostService.overlay.valid = true;
viewportHostService.overlay.verticalFovDegrees = 50.0f;
XCEngine::Editor::SceneViewportMoveGizmo moveGizmo = {};
XCEngine::Editor::SceneViewportRotateGizmo rotateGizmo = {};
XCEngine::Editor::SceneViewportScaleGizmo scaleGizmo = {};
SceneViewportPresentationRequest request = {};
request.context = &context;
request.viewportHostService = &viewportHostService;
request.hasInteractiveViewport = true;
request.geometry = BuildSceneViewportFrameGeometry(
ImVec2(640.0f, 360.0f),
ImVec2(10.0f, 20.0f),
ImVec2(40.0f, 60.0f));
request.gizmoFrameOptions = BuildSceneViewportToolState(
SceneViewportToolMode::Move,
SceneViewportPivotMode::Pivot,
SceneViewportTransformSpaceMode::Global)
.gizmoFrameOptions;
request.moveGizmo = &moveGizmo;
request.rotateGizmo = &rotateGizmo;
request.scaleGizmo = &scaleGizmo;
request.viewportMin = ImVec2(10.0f, 20.0f);
request.viewportMax = ImVec2(650.0f, 380.0f);
RefreshAndDrawSceneViewportPresentation(request);
EXPECT_EQ(viewportHostService.submissionCount, 1);
}