123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318 |
- #include <AzCore/Settings/SettingsRegistryImpl.h>
- #include <AzFramework/Viewport/CameraInput.h>
- #include <AzFramework/Viewport/ViewportControllerList.h>
- #include <AzToolsFramework/Input/QtEventToAzInputMapper.h>
- #include <AzToolsFramework/UnitTest/AzToolsFrameworkTestHelpers.h>
- #include <AzToolsFramework/ViewportSelection/EditorInteractionSystemViewportSelectionRequestBus.h>
- #include <Editor/ViewportManipulatorController.h>
- #include <Mocks/MockWindowRequests.h>
- namespace UnitTest
- {
- using AzToolsFramework::ViewportInteraction::MouseInteractionEvent;
- class EditorInteractionViewportSelectionFake : public AzToolsFramework::EditorInteractionSystemViewportSelectionRequestBus::Handler
- {
- public:
- void Connect();
- void Disconnect();
-
- const AzToolsFramework::EditorVisibleEntityDataCacheInterface* GetEntityDataCache() const override;
- void SetHandler(const AzToolsFramework::ViewportSelectionRequestsBuilderFn& interactionRequestsBuilder) override;
- void SetDefaultHandler() override;
- bool InternalHandleMouseViewportInteraction(const MouseInteractionEvent& mouseInteraction) override;
- bool InternalHandleMouseManipulatorInteraction(const MouseInteractionEvent& mouseInteraction) override;
- AZStd::function<bool(const MouseInteractionEvent& mouseInteraction)> m_internalHandleMouseViewportInteraction;
- AZStd::function<bool(const MouseInteractionEvent& mouseInteraction)> m_internalHandleMouseManipulatorInteraction;
- };
- void EditorInteractionViewportSelectionFake::Connect()
- {
- AzToolsFramework::EditorInteractionSystemViewportSelectionRequestBus::Handler::BusConnect(AzToolsFramework::GetEntityContextId());
- }
- void EditorInteractionViewportSelectionFake::Disconnect()
- {
- AzToolsFramework::EditorInteractionSystemViewportSelectionRequestBus::Handler::BusDisconnect();
- }
- const AzToolsFramework::EditorVisibleEntityDataCacheInterface* EditorInteractionViewportSelectionFake::GetEntityDataCache() const
- {
- return nullptr;
- }
- void EditorInteractionViewportSelectionFake::SetHandler(
- [[maybe_unused]] const AzToolsFramework::ViewportSelectionRequestsBuilderFn& interactionRequestsBuilder)
- {
-
- }
- void EditorInteractionViewportSelectionFake::SetDefaultHandler()
- {
-
- }
- bool EditorInteractionViewportSelectionFake::InternalHandleMouseViewportInteraction(const MouseInteractionEvent& mouseInteraction)
- {
- if (m_internalHandleMouseViewportInteraction)
- {
- return m_internalHandleMouseViewportInteraction(mouseInteraction);
- }
- return false;
- }
- bool EditorInteractionViewportSelectionFake::InternalHandleMouseManipulatorInteraction(const MouseInteractionEvent& mouseInteraction)
- {
- if (m_internalHandleMouseManipulatorInteraction)
- {
- return m_internalHandleMouseManipulatorInteraction(mouseInteraction);
- }
- return false;
- }
- class ViewportManipulatorControllerFixture : public LeakDetectionFixture
- {
- public:
- static inline constexpr AzFramework::ViewportId TestViewportId = 1234;
- static inline const QSize WidgetSize = QSize(1920, 1080);
- void SetUp() override
- {
- LeakDetectionFixture::SetUp();
- m_rootWidget = AZStd::make_unique<QWidget>();
- m_rootWidget->setFixedSize(WidgetSize);
- QApplication::setActiveWindow(m_rootWidget.get());
- m_controllerList = AZStd::make_shared<AzFramework::ViewportControllerList>();
- m_controllerList->RegisterViewportContext(TestViewportId);
- m_inputChannelMapper = AZStd::make_unique<AzToolsFramework::QtEventToAzInputMapper>(m_rootWidget.get(), TestViewportId);
- m_settingsRegistry = AZStd::make_unique<AZ::SettingsRegistryImpl>();
- AZ::SettingsRegistry::Register(m_settingsRegistry.get());
- }
- void TearDown() override
- {
- AZ::SettingsRegistry::Unregister(m_settingsRegistry.get());
- m_settingsRegistry.reset();
- m_inputChannelMapper.reset();
- m_controllerList->UnregisterViewportContext(TestViewportId);
- m_controllerList.reset();
- m_rootWidget.reset();
- QApplication::setActiveWindow(nullptr);
- LeakDetectionFixture::TearDown();
- }
- AZStd::unique_ptr<QWidget> m_rootWidget;
- AzFramework::ViewportControllerListPtr m_controllerList;
- AZStd::unique_ptr<AzToolsFramework::QtEventToAzInputMapper> m_inputChannelMapper;
- AZStd::unique_ptr<AZ::SettingsRegistryInterface> m_settingsRegistry;
- };
- TEST_F(ViewportManipulatorControllerFixture, AnEventIsNotPropagatedToTheViewportWhenAManipulatorHandlesItFirst)
- {
-
- QObject::connect(
- m_inputChannelMapper.get(), &AzToolsFramework::QtEventToAzInputMapper::InputChannelUpdated, m_rootWidget.get(),
- [this](const AzFramework::InputChannel* inputChannel, [[maybe_unused]] QEvent* event)
- {
- m_controllerList->HandleInputChannelEvent(
- AzFramework::ViewportControllerInputEvent{ TestViewportId, nullptr, *inputChannel });
- });
- EditorInteractionViewportSelectionFake editorInteractionViewportFake;
- editorInteractionViewportFake.m_internalHandleMouseManipulatorInteraction = [](const MouseInteractionEvent&)
- {
-
- return true;
- };
- bool viewportInteractionCalled = false;
- editorInteractionViewportFake.m_internalHandleMouseViewportInteraction = [&viewportInteractionCalled](const MouseInteractionEvent&)
- {
-
- viewportInteractionCalled = true;
- return true;
- };
- editorInteractionViewportFake.Connect();
- m_controllerList->Add(AZStd::make_shared<SandboxEditor::ViewportManipulatorController>());
-
- MousePressAndMove(m_rootWidget.get(), QPoint(10, 10), QPoint(10, 10), Qt::MouseButton::LeftButton);
- MouseMove(m_rootWidget.get(), QPoint(20, 20), QPoint(10, 10), Qt::MouseButton::LeftButton);
- MouseMove(m_rootWidget.get(), QPoint(30, 30), QPoint(0, 0), Qt::MouseButton::LeftButton);
- QTest::mouseRelease(m_rootWidget.get(), Qt::MouseButton::LeftButton, Qt::KeyboardModifier::NoModifier, QPoint(30, 30));
-
- EXPECT_FALSE(viewportInteractionCalled);
- editorInteractionViewportFake.Disconnect();
- }
- TEST_F(ViewportManipulatorControllerFixture, ChangingFocusDoesNotClearInput)
- {
- bool endedEvent = false;
-
- QObject::connect(
- m_inputChannelMapper.get(), &AzToolsFramework::QtEventToAzInputMapper::InputChannelUpdated, m_rootWidget.get(),
- [&endedEvent](const AzFramework::InputChannel* inputChannel, [[maybe_unused]] QEvent* event)
- {
- if (inputChannel->GetInputChannelId() == AzFramework::InputDeviceKeyboard::Key::ModifierAltL &&
- inputChannel->IsStateEnded())
- {
- endedEvent = true;
- }
- });
-
- auto* secondaryWidget = new QWidget(m_rootWidget.get());
- m_rootWidget->show();
- secondaryWidget->show();
- m_rootWidget->setFocus();
-
- QTest::keyPress(m_rootWidget.get(), Qt::Key_Alt, Qt::KeyboardModifier::AltModifier);
-
-
- secondaryWidget->setFocus();
-
-
- EXPECT_FALSE(endedEvent);
- }
-
-
- TEST_F(ViewportManipulatorControllerFixture, ApplicationStateChangeDoesClearInput)
- {
- bool endedEvent = false;
-
- QObject::connect(
- m_inputChannelMapper.get(), &AzToolsFramework::QtEventToAzInputMapper::InputChannelUpdated, m_rootWidget.get(),
- [&endedEvent](const AzFramework::InputChannel* inputChannel, [[maybe_unused]] QEvent* event)
- {
- if (inputChannel->GetInputChannelId() == AzFramework::InputDeviceKeyboard::Key::AlphanumericW &&
- inputChannel->IsStateEnded())
- {
- endedEvent = true;
- }
- });
-
- auto* secondaryWidget = new QWidget(m_rootWidget.get());
- m_rootWidget->show();
- secondaryWidget->show();
- m_rootWidget->setFocus();
-
- QTest::keyPress(m_rootWidget.get(), Qt::Key_W);
-
-
- QApplicationStateChangeEvent applicationStateChangeEvent(Qt::ApplicationState::ApplicationInactive);
- QCoreApplication::sendEvent(m_rootWidget.get(), &applicationStateChangeEvent);
-
-
- EXPECT_TRUE(endedEvent);
- }
- TEST_F(ViewportManipulatorControllerFixture, DoubleClickIsNotRegisteredIfMouseDeltaHasMovedMoreThanDeadzoneInClickInterval)
- {
- AzFramework::NativeWindowHandle nativeWindowHandle = nullptr;
-
- QObject::connect(
- m_inputChannelMapper.get(), &AzToolsFramework::QtEventToAzInputMapper::InputChannelUpdated, m_rootWidget.get(),
- [this, nativeWindowHandle](const AzFramework::InputChannel* inputChannel, [[maybe_unused]] QEvent* event)
- {
- m_controllerList->HandleInputChannelEvent(
- AzFramework::ViewportControllerInputEvent{ TestViewportId, nativeWindowHandle, *inputChannel });
- });
- ::testing::NiceMock<MockWindowRequests> mockWindowRequests;
- mockWindowRequests.Connect(nativeWindowHandle);
- using ::testing::Return;
-
- ON_CALL(mockWindowRequests, GetClientAreaSize())
- .WillByDefault(Return(AzFramework::WindowSize(WidgetSize.width(), WidgetSize.height())));
- ON_CALL(mockWindowRequests, GetRenderResolution())
- .WillByDefault(Return(AzFramework::WindowSize(WidgetSize.width(), WidgetSize.height())));
- EditorInteractionViewportSelectionFake editorInteractionViewportFake;
- editorInteractionViewportFake.m_internalHandleMouseManipulatorInteraction = [](const MouseInteractionEvent&)
- {
-
- return false;
- };
- bool doubleClickDetected = false;
- editorInteractionViewportFake.m_internalHandleMouseViewportInteraction =
- [&doubleClickDetected](const MouseInteractionEvent& mouseInteractionEvent)
- {
-
- if (mouseInteractionEvent.m_mouseEvent == AzToolsFramework::ViewportInteraction::MouseEvent::DoubleClick)
- {
- doubleClickDetected = true;
- }
- return true;
- };
- editorInteractionViewportFake.Connect();
- m_controllerList->Add(AZStd::make_shared<SandboxEditor::ViewportManipulatorController>());
-
- MouseMove(m_rootWidget.get(), QPoint(0, 0), QPoint(10, 10));
- MousePressAndMove(m_rootWidget.get(), QPoint(10, 10), QPoint(0, 0), Qt::MouseButton::LeftButton);
- QTest::mouseRelease(m_rootWidget.get(), Qt::MouseButton::LeftButton, Qt::KeyboardModifier::NoModifier, QPoint(10, 10));
- MouseMove(m_rootWidget.get(), QPoint(10, 10), QPoint(20, 20));
- MousePressAndMove(m_rootWidget.get(), QPoint(20, 20), QPoint(0, 0), Qt::MouseButton::LeftButton);
- QTest::mouseRelease(m_rootWidget.get(), Qt::MouseButton::LeftButton, Qt::KeyboardModifier::NoModifier, QPoint(20, 20));
-
- EXPECT_FALSE(doubleClickDetected);
-
- MouseMove(m_rootWidget.get(), QPoint(0, 0), QPoint(10, 10));
- MousePressAndMove(m_rootWidget.get(), QPoint(10, 10), QPoint(0, 0), Qt::MouseButton::LeftButton);
- QTest::mouseRelease(m_rootWidget.get(), Qt::MouseButton::LeftButton, Qt::KeyboardModifier::NoModifier, QPoint(10, 10));
- MousePressAndMove(m_rootWidget.get(), QPoint(10, 10), QPoint(0, 0), Qt::MouseButton::LeftButton);
- QTest::mouseRelease(m_rootWidget.get(), Qt::MouseButton::LeftButton, Qt::KeyboardModifier::NoModifier, QPoint(10, 10));
-
- EXPECT_TRUE(doubleClickDetected);
- mockWindowRequests.Disconnect();
- editorInteractionViewportFake.Disconnect();
- }
- }
|