Files
XCEngine/tests/editor/test_scene_viewport_navigation.cpp

184 lines
7.8 KiB
C++

#include <gtest/gtest.h>
#include "Viewport/SceneViewportNavigation.h"
using XCEngine::Editor::BuildSceneViewportCaptureFlags;
using XCEngine::Editor::BuildSceneViewportInput;
using XCEngine::Editor::BuildSceneViewportToolShortcutAction;
using XCEngine::Editor::CanResolveSceneViewportInteraction;
using XCEngine::Editor::SceneViewportCaptureRequest;
using XCEngine::Editor::SceneViewportInputBuildRequest;
using XCEngine::Editor::SceneViewportNavigationRequest;
using XCEngine::Editor::SceneViewportNavigationState;
using XCEngine::Editor::SceneViewportToolMode;
using XCEngine::Editor::SceneViewportToolShortcutRequest;
using XCEngine::Editor::UpdateSceneViewportNavigationState;
TEST(SceneViewportNavigationTest, ToolShortcutActionIgnoresShortcutsDuringTextInputOrDrag) {
SceneViewportToolShortcutRequest request = {};
request.pressedMove = true;
request.wantTextInput = true;
EXPECT_FALSE(BuildSceneViewportToolShortcutAction(request).HasAction());
request.wantTextInput = false;
request.lookDragging = true;
EXPECT_FALSE(BuildSceneViewportToolShortcutAction(request).HasAction());
request.lookDragging = false;
request.panDragging = true;
EXPECT_FALSE(BuildSceneViewportToolShortcutAction(request).HasAction());
}
TEST(SceneViewportNavigationTest, ToolShortcutActionMapsShortcutTargetsAndCancelFlags) {
SceneViewportToolShortcutRequest request = {};
request.pressedViewMove = true;
const auto viewMoveAction = BuildSceneViewportToolShortcutAction(request);
EXPECT_TRUE(viewMoveAction.HasAction());
EXPECT_EQ(viewMoveAction.targetTool, SceneViewportToolMode::ViewMove);
EXPECT_TRUE(viewMoveAction.cancelMoveGizmo);
EXPECT_TRUE(viewMoveAction.cancelRotateGizmo);
EXPECT_TRUE(viewMoveAction.cancelScaleGizmo);
request = {};
request.pressedRotate = true;
const auto rotateAction = BuildSceneViewportToolShortcutAction(request);
EXPECT_TRUE(rotateAction.HasAction());
EXPECT_EQ(rotateAction.targetTool, SceneViewportToolMode::Rotate);
EXPECT_TRUE(rotateAction.cancelMoveGizmo);
EXPECT_FALSE(rotateAction.cancelRotateGizmo);
EXPECT_TRUE(rotateAction.cancelScaleGizmo);
}
TEST(SceneViewportNavigationTest, NavigationUpdateBeginsLookAndPanDrags) {
SceneViewportNavigationRequest lookRequest = {};
lookRequest.hasInteractiveViewport = true;
lookRequest.viewportHovered = true;
lookRequest.clickedRight = true;
lookRequest.rightMouseDown = true;
const auto lookUpdate = UpdateSceneViewportNavigationState(lookRequest);
EXPECT_TRUE(lookUpdate.beginLookDrag);
EXPECT_FALSE(lookUpdate.beginPanDrag);
EXPECT_TRUE(lookUpdate.state.lookDragging);
EXPECT_FALSE(lookUpdate.state.panDragging);
SceneViewportNavigationRequest panRequest = {};
panRequest.hasInteractiveViewport = true;
panRequest.viewportHovered = true;
panRequest.usingViewMoveTool = true;
panRequest.clickedLeft = true;
panRequest.leftMouseDown = true;
const auto panUpdate = UpdateSceneViewportNavigationState(panRequest);
EXPECT_FALSE(panUpdate.beginLookDrag);
EXPECT_TRUE(panUpdate.beginPanDrag);
EXPECT_TRUE(panUpdate.beginLeftPanDrag);
EXPECT_TRUE(panUpdate.state.panDragging);
EXPECT_EQ(panUpdate.state.panDragButton, ImGuiMouseButton_Left);
SceneViewportNavigationRequest middlePanRequest = {};
middlePanRequest.hasInteractiveViewport = true;
middlePanRequest.viewportHovered = true;
middlePanRequest.clickedMiddle = true;
middlePanRequest.middleMouseDown = true;
const auto middlePanUpdate = UpdateSceneViewportNavigationState(middlePanRequest);
EXPECT_FALSE(middlePanUpdate.beginLookDrag);
EXPECT_TRUE(middlePanUpdate.beginPanDrag);
EXPECT_FALSE(middlePanUpdate.beginLeftPanDrag);
EXPECT_TRUE(middlePanUpdate.beginMiddlePanDrag);
EXPECT_TRUE(middlePanUpdate.state.panDragging);
EXPECT_EQ(middlePanUpdate.state.panDragButton, ImGuiMouseButton_Middle);
}
TEST(SceneViewportNavigationTest, NavigationUpdateBeginsMiddlePanWhenHeldButtonMissedClickEdge) {
SceneViewportNavigationRequest middlePanRequest = {};
middlePanRequest.hasInteractiveViewport = true;
middlePanRequest.viewportHovered = true;
middlePanRequest.middleMouseDown = true;
const auto middlePanUpdate = UpdateSceneViewportNavigationState(middlePanRequest);
EXPECT_FALSE(middlePanUpdate.beginLookDrag);
EXPECT_TRUE(middlePanUpdate.beginPanDrag);
EXPECT_FALSE(middlePanUpdate.beginLeftPanDrag);
EXPECT_TRUE(middlePanUpdate.beginMiddlePanDrag);
EXPECT_TRUE(middlePanUpdate.state.panDragging);
EXPECT_EQ(middlePanUpdate.state.panDragButton, ImGuiMouseButton_Middle);
}
TEST(SceneViewportNavigationTest, NavigationUpdateEndsDragsWhenButtonsRelease) {
SceneViewportNavigationRequest lookRequest = {};
lookRequest.state.lookDragging = true;
const auto lookUpdate = UpdateSceneViewportNavigationState(lookRequest);
EXPECT_FALSE(lookUpdate.state.lookDragging);
SceneViewportNavigationRequest panRequest = {};
panRequest.state.panDragging = true;
panRequest.state.panDragButton = ImGuiMouseButton_Left;
const auto panUpdate = UpdateSceneViewportNavigationState(panRequest);
EXPECT_FALSE(panUpdate.state.panDragging);
EXPECT_EQ(panUpdate.state.panDragButton, ImGuiMouseButton_Middle);
}
TEST(SceneViewportNavigationTest, CaptureFlagsTrackNavigationAndActiveGizmos) {
SceneViewportCaptureRequest request = {};
request.state.lookDragging = true;
const auto lookFlags = BuildSceneViewportCaptureFlags(request);
EXPECT_TRUE(lookFlags.captureMouse);
EXPECT_TRUE(lookFlags.captureKeyboard);
request = {};
request.rotateGizmoActive = true;
const auto gizmoFlags = BuildSceneViewportCaptureFlags(request);
EXPECT_TRUE(gizmoFlags.captureMouse);
EXPECT_FALSE(gizmoFlags.captureKeyboard);
}
TEST(SceneViewportNavigationTest, BuildInputRoutesWheelFocusMovementAndMouseDelta) {
SceneViewportInputBuildRequest request = {};
request.viewportSize = XCEngine::UI::UISize(640.0f, 360.0f);
request.viewportHovered = true;
request.viewportFocused = true;
request.mouseWheel = 2.0f;
const auto zoomInput = BuildSceneViewportInput(request);
EXPECT_FLOAT_EQ(zoomInput.mouseWheel, 2.0f);
EXPECT_FLOAT_EQ(zoomInput.flySpeedDelta, 0.0f);
EXPECT_FALSE(zoomInput.looking);
EXPECT_TRUE(zoomInput.focused);
request = {};
request.state.lookDragging = true;
request.viewportSize = XCEngine::UI::UISize(640.0f, 360.0f);
request.viewportHovered = true;
request.mouseWheel = 1.5f;
request.mouseDelta = XCEngine::UI::UIPoint(5.0f, -3.0f);
request.fastMove = true;
request.focusSelectionKeyPressed = true;
request.moveForwardKeyDown = true;
request.moveRightKeyDown = true;
request.moveUpKeyDown = true;
const auto flyInput = BuildSceneViewportInput(request);
EXPECT_FLOAT_EQ(flyInput.mouseWheel, 0.0f);
EXPECT_FLOAT_EQ(flyInput.flySpeedDelta, 1.5f);
EXPECT_TRUE(flyInput.looking);
EXPECT_TRUE(flyInput.fastMove);
EXPECT_TRUE(flyInput.focused);
EXPECT_TRUE(flyInput.focusSelectionRequested);
EXPECT_FLOAT_EQ(flyInput.moveForward, 1.0f);
EXPECT_FLOAT_EQ(flyInput.moveRight, 1.0f);
EXPECT_FLOAT_EQ(flyInput.moveUp, 1.0f);
EXPECT_FLOAT_EQ(flyInput.mouseDelta.x, 5.0f);
EXPECT_FLOAT_EQ(flyInput.mouseDelta.y, -3.0f);
}
TEST(SceneViewportNavigationTest, CanResolveInteractionRequiresHoverWithoutNavigationOrActiveGizmo) {
SceneViewportNavigationState state = {};
EXPECT_TRUE(CanResolveSceneViewportInteraction(true, true, false, state, false));
state.lookDragging = true;
EXPECT_FALSE(CanResolveSceneViewportInteraction(true, true, false, state, false));
state = {};
EXPECT_FALSE(CanResolveSceneViewportInteraction(true, true, true, state, false));
EXPECT_FALSE(CanResolveSceneViewportInteraction(true, true, false, state, true));
EXPECT_FALSE(CanResolveSceneViewportInteraction(false, true, false, state, false));
}