Refine new_editor scene viewport flow
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
|
||||
#include <XCEditor/App/EditorPanelIds.h>
|
||||
#include <XCEditor/Viewport/UIEditorViewportInputBridge.h>
|
||||
#include <XCEditor/Viewport/UIEditorViewportSlot.h>
|
||||
|
||||
#include <XCEngine/Components/CameraComponent.h>
|
||||
#include <XCEngine/Components/GameObject.h>
|
||||
@@ -30,6 +31,7 @@ using ::XCEngine::Components::SceneManager;
|
||||
using ::XCEngine::Input::KeyCode;
|
||||
using ::XCEngine::UI::UIInputEvent;
|
||||
using ::XCEngine::UI::UIInputEventType;
|
||||
using ::XCEngine::UI::UIInputModifiers;
|
||||
using ::XCEngine::UI::UIPoint;
|
||||
using ::XCEngine::UI::UIPointerButton;
|
||||
using ::XCEngine::UI::UIRect;
|
||||
@@ -113,6 +115,45 @@ UIInputEvent MakePointerEvent(
|
||||
return event;
|
||||
}
|
||||
|
||||
UIInputEvent MakePointerEventWithModifiers(
|
||||
UIInputEventType type,
|
||||
float x,
|
||||
float y,
|
||||
const UIInputModifiers& modifiers,
|
||||
UIPointerButton button = UIPointerButton::None) {
|
||||
UIInputEvent event = {};
|
||||
event.type = type;
|
||||
event.position = UIPoint(x, y);
|
||||
event.pointerButton = button;
|
||||
event.modifiers = modifiers;
|
||||
return event;
|
||||
}
|
||||
|
||||
UIInputModifiers MakePointerModifiers(UIPointerButton button) {
|
||||
UIInputModifiers modifiers = {};
|
||||
switch (button) {
|
||||
case UIPointerButton::Left:
|
||||
modifiers.leftMouse = true;
|
||||
break;
|
||||
case UIPointerButton::Right:
|
||||
modifiers.rightMouse = true;
|
||||
break;
|
||||
case UIPointerButton::Middle:
|
||||
modifiers.middleMouse = true;
|
||||
break;
|
||||
case UIPointerButton::X1:
|
||||
modifiers.x1Mouse = true;
|
||||
break;
|
||||
case UIPointerButton::X2:
|
||||
modifiers.x2Mouse = true;
|
||||
break;
|
||||
case UIPointerButton::None:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return modifiers;
|
||||
}
|
||||
|
||||
UIInputEvent MakeWheelEvent(float x, float y, float wheelDelta) {
|
||||
UIInputEvent event = {};
|
||||
event.type = UIInputEventType::PointerWheel;
|
||||
@@ -436,10 +477,11 @@ TEST(SceneViewportRuntimeTests, RightMouseDragRotatesSceneCameraThroughViewportC
|
||||
inputRect,
|
||||
{
|
||||
MakePointerEvent(UIInputEventType::PointerMove, 220.0f, 180.0f),
|
||||
MakePointerEvent(
|
||||
MakePointerEventWithModifiers(
|
||||
UIInputEventType::PointerButtonDown,
|
||||
220.0f,
|
||||
180.0f,
|
||||
MakePointerModifiers(UIPointerButton::Right),
|
||||
UIPointerButton::Right)
|
||||
});
|
||||
controller.Update(
|
||||
@@ -452,7 +494,11 @@ TEST(SceneViewportRuntimeTests, RightMouseDragRotatesSceneCameraThroughViewportC
|
||||
inputBridgeState,
|
||||
inputRect,
|
||||
{
|
||||
MakePointerEvent(UIInputEventType::PointerMove, 280.0f, 220.0f)
|
||||
MakePointerEventWithModifiers(
|
||||
UIInputEventType::PointerMove,
|
||||
280.0f,
|
||||
220.0f,
|
||||
MakePointerModifiers(UIPointerButton::Right))
|
||||
});
|
||||
controller.Update(
|
||||
runtime,
|
||||
@@ -515,10 +561,11 @@ TEST(SceneViewportRuntimeTests, MiddleMouseDragPansSceneCameraWithGrabSemantics)
|
||||
inputRect,
|
||||
{
|
||||
MakePointerEvent(UIInputEventType::PointerMove, 220.0f, 180.0f),
|
||||
MakePointerEvent(
|
||||
MakePointerEventWithModifiers(
|
||||
UIInputEventType::PointerButtonDown,
|
||||
220.0f,
|
||||
180.0f,
|
||||
MakePointerModifiers(UIPointerButton::Middle),
|
||||
UIPointerButton::Middle)
|
||||
});
|
||||
controller.Update(
|
||||
@@ -531,7 +578,70 @@ TEST(SceneViewportRuntimeTests, MiddleMouseDragPansSceneCameraWithGrabSemantics)
|
||||
inputBridgeState,
|
||||
inputRect,
|
||||
{
|
||||
MakePointerEvent(UIInputEventType::PointerMove, 280.0f, 180.0f)
|
||||
MakePointerEventWithModifiers(
|
||||
UIInputEventType::PointerMove,
|
||||
280.0f,
|
||||
180.0f,
|
||||
MakePointerModifiers(UIPointerButton::Middle))
|
||||
});
|
||||
controller.Update(
|
||||
runtime,
|
||||
viewportHostService,
|
||||
BuildSceneComposeState(inputBridgeState),
|
||||
BuildSceneComposeFrame(dragFrame, inputRect, viewportSize));
|
||||
|
||||
const Math::Vector3 after = transform->GetPosition();
|
||||
EXPECT_LT(after.x, before.x);
|
||||
}
|
||||
|
||||
TEST(SceneViewportRuntimeTests, ViewToolLeftMouseDragPansSceneCameraWithGrabSemantics) {
|
||||
ScopedSceneManagerReset reset = {};
|
||||
TemporaryProjectRoot projectRoot = {};
|
||||
SaveMainScene(projectRoot, Math::Vector3(0.0f, 0.0f, 0.0f));
|
||||
|
||||
EditorSceneRuntime runtime = {};
|
||||
ASSERT_TRUE(runtime.Initialize(projectRoot.Root()));
|
||||
runtime.SetToolMode(SceneToolMode::View);
|
||||
|
||||
auto* camera = runtime.GetSceneViewCamera();
|
||||
ASSERT_NE(camera, nullptr);
|
||||
auto* transform = camera->GetGameObject()->GetTransform();
|
||||
ASSERT_NE(transform, nullptr);
|
||||
const Math::Vector3 before = transform->GetPosition();
|
||||
|
||||
SceneViewportController controller = {};
|
||||
ViewportHostService viewportHostService = {};
|
||||
UIEditorViewportInputBridgeState inputBridgeState = {};
|
||||
const UIRect inputRect(100.0f, 80.0f, 640.0f, 360.0f);
|
||||
const UISize viewportSize(640.0f, 360.0f);
|
||||
|
||||
const auto pressFrame = UpdateUIEditorViewportInputBridge(
|
||||
inputBridgeState,
|
||||
inputRect,
|
||||
{
|
||||
MakePointerEvent(UIInputEventType::PointerMove, 220.0f, 180.0f),
|
||||
MakePointerEventWithModifiers(
|
||||
UIInputEventType::PointerButtonDown,
|
||||
220.0f,
|
||||
180.0f,
|
||||
MakePointerModifiers(UIPointerButton::Left),
|
||||
UIPointerButton::Left)
|
||||
});
|
||||
controller.Update(
|
||||
runtime,
|
||||
viewportHostService,
|
||||
BuildSceneComposeState(inputBridgeState),
|
||||
BuildSceneComposeFrame(pressFrame, inputRect, viewportSize));
|
||||
|
||||
const auto dragFrame = UpdateUIEditorViewportInputBridge(
|
||||
inputBridgeState,
|
||||
inputRect,
|
||||
{
|
||||
MakePointerEventWithModifiers(
|
||||
UIInputEventType::PointerMove,
|
||||
280.0f,
|
||||
180.0f,
|
||||
MakePointerModifiers(UIPointerButton::Left))
|
||||
});
|
||||
controller.Update(
|
||||
runtime,
|
||||
@@ -610,10 +720,11 @@ TEST(SceneViewportRuntimeTests, ToolShortcutSwitchesFocusedSceneViewportIntoTran
|
||||
inputRect,
|
||||
{
|
||||
MakePointerEvent(UIInputEventType::PointerMove, 220.0f, 180.0f),
|
||||
MakePointerEvent(
|
||||
MakePointerEventWithModifiers(
|
||||
UIInputEventType::PointerButtonDown,
|
||||
220.0f,
|
||||
180.0f,
|
||||
MakePointerModifiers(UIPointerButton::Left),
|
||||
UIPointerButton::Left),
|
||||
MakePointerEvent(
|
||||
UIInputEventType::PointerButtonUp,
|
||||
@@ -646,5 +757,130 @@ TEST(SceneViewportRuntimeTests, ToolShortcutSwitchesFocusedSceneViewportIntoTran
|
||||
EXPECT_EQ(runtime.GetToolMode(), SceneToolMode::Translate);
|
||||
}
|
||||
|
||||
TEST(SceneViewportRuntimeTests, SceneToolOverlayClickSwitchesModeOnPointerDown) {
|
||||
ScopedSceneManagerReset reset = {};
|
||||
TemporaryProjectRoot projectRoot = {};
|
||||
SaveMainScene(projectRoot, Math::Vector3(0.0f, 0.0f, 0.0f));
|
||||
|
||||
EditorSceneRuntime runtime = {};
|
||||
ASSERT_TRUE(runtime.Initialize(projectRoot.Root()));
|
||||
runtime.SetToolMode(SceneToolMode::Translate);
|
||||
|
||||
SceneViewportController controller = {};
|
||||
ViewportHostService viewportHostService = {};
|
||||
UIEditorViewportInputBridgeState inputBridgeState = {};
|
||||
const UIRect inputRect(100.0f, 104.0f, 640.0f, 360.0f);
|
||||
const UISize viewportSize(640.0f, 360.0f);
|
||||
const UIPoint rotateButtonCenter(
|
||||
inputRect.x + 28.0f,
|
||||
inputRect.y + 82.0f);
|
||||
|
||||
const auto frame = UpdateUIEditorViewportInputBridge(
|
||||
inputBridgeState,
|
||||
inputRect,
|
||||
{
|
||||
MakePointerEvent(UIInputEventType::PointerMove, rotateButtonCenter.x, rotateButtonCenter.y),
|
||||
MakePointerEvent(
|
||||
UIInputEventType::PointerButtonDown,
|
||||
rotateButtonCenter.x,
|
||||
rotateButtonCenter.y,
|
||||
UIPointerButton::Left)
|
||||
});
|
||||
controller.Update(
|
||||
runtime,
|
||||
viewportHostService,
|
||||
BuildSceneComposeState(inputBridgeState),
|
||||
BuildSceneComposeFrame(frame, inputRect, viewportSize));
|
||||
|
||||
EXPECT_EQ(runtime.GetToolMode(), SceneToolMode::Rotate);
|
||||
}
|
||||
|
||||
TEST(SceneViewportRuntimeTests, SceneToolOverlayIncludesTransformButtonAndSwitchesModeOnPointerDown) {
|
||||
ScopedSceneManagerReset reset = {};
|
||||
TemporaryProjectRoot projectRoot = {};
|
||||
SaveMainScene(projectRoot, Math::Vector3(0.0f, 0.0f, 0.0f));
|
||||
|
||||
EditorSceneRuntime runtime = {};
|
||||
ASSERT_TRUE(runtime.Initialize(projectRoot.Root()));
|
||||
runtime.SetToolMode(SceneToolMode::Translate);
|
||||
|
||||
SceneViewportController controller = {};
|
||||
ViewportHostService viewportHostService = {};
|
||||
UIEditorViewportInputBridgeState inputBridgeState = {};
|
||||
const UIRect inputRect(100.0f, 104.0f, 640.0f, 360.0f);
|
||||
const UISize viewportSize(640.0f, 360.0f);
|
||||
const UIPoint transformButtonCenter(
|
||||
inputRect.x + 28.0f,
|
||||
inputRect.y + 148.0f);
|
||||
|
||||
const auto frame = UpdateUIEditorViewportInputBridge(
|
||||
inputBridgeState,
|
||||
inputRect,
|
||||
{
|
||||
MakePointerEvent(
|
||||
UIInputEventType::PointerMove,
|
||||
transformButtonCenter.x,
|
||||
transformButtonCenter.y),
|
||||
MakePointerEvent(
|
||||
UIInputEventType::PointerButtonDown,
|
||||
transformButtonCenter.x,
|
||||
transformButtonCenter.y,
|
||||
UIPointerButton::Left)
|
||||
});
|
||||
controller.Update(
|
||||
runtime,
|
||||
viewportHostService,
|
||||
BuildSceneComposeState(inputBridgeState),
|
||||
BuildSceneComposeFrame(frame, inputRect, viewportSize));
|
||||
|
||||
EXPECT_EQ(runtime.GetToolMode(), SceneToolMode::Transform);
|
||||
}
|
||||
|
||||
TEST(SceneViewportRuntimeTests, SceneToolOverlayHandlesCoalescedClickInSingleFrame) {
|
||||
ScopedSceneManagerReset reset = {};
|
||||
TemporaryProjectRoot projectRoot = {};
|
||||
SaveMainScene(projectRoot, Math::Vector3(0.0f, 0.0f, 0.0f));
|
||||
|
||||
EditorSceneRuntime runtime = {};
|
||||
ASSERT_TRUE(runtime.Initialize(projectRoot.Root()));
|
||||
runtime.SetToolMode(SceneToolMode::Translate);
|
||||
|
||||
SceneViewportController controller = {};
|
||||
ViewportHostService viewportHostService = {};
|
||||
UIEditorViewportInputBridgeState inputBridgeState = {};
|
||||
const UIRect inputRect(100.0f, 104.0f, 640.0f, 360.0f);
|
||||
const UISize viewportSize(640.0f, 360.0f);
|
||||
const UIPoint rotateButtonCenter(
|
||||
inputRect.x + 28.0f,
|
||||
inputRect.y + 82.0f);
|
||||
|
||||
const auto frame = UpdateUIEditorViewportInputBridge(
|
||||
inputBridgeState,
|
||||
inputRect,
|
||||
{
|
||||
MakePointerEvent(
|
||||
UIInputEventType::PointerMove,
|
||||
rotateButtonCenter.x,
|
||||
rotateButtonCenter.y),
|
||||
MakePointerEvent(
|
||||
UIInputEventType::PointerButtonDown,
|
||||
rotateButtonCenter.x,
|
||||
rotateButtonCenter.y,
|
||||
UIPointerButton::Left),
|
||||
MakePointerEvent(
|
||||
UIInputEventType::PointerButtonUp,
|
||||
rotateButtonCenter.x,
|
||||
rotateButtonCenter.y,
|
||||
UIPointerButton::Left)
|
||||
});
|
||||
controller.Update(
|
||||
runtime,
|
||||
viewportHostService,
|
||||
BuildSceneComposeState(inputBridgeState),
|
||||
BuildSceneComposeFrame(frame, inputRect, viewportSize));
|
||||
|
||||
EXPECT_EQ(runtime.GetToolMode(), SceneToolMode::Rotate);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace XCEngine::UI::Editor::App
|
||||
|
||||
Reference in New Issue
Block a user