diff --git a/Code/Editor/EditorViewportWidget.cpp b/Code/Editor/EditorViewportWidget.cpp index 1cfc3b6dd0..1b461e1356 100644 --- a/Code/Editor/EditorViewportWidget.cpp +++ b/Code/Editor/EditorViewportWidget.cpp @@ -714,7 +714,7 @@ void EditorViewportWidget::OnEditorNotifyEvent(EEditorNotifyEvent event) if (m_renderViewport) { - m_renderViewport->GetControllerList()->SetEnabled(false); + m_renderViewport->SetInputProcessingEnabled(false); } } break; @@ -738,7 +738,7 @@ void EditorViewportWidget::OnEditorNotifyEvent(EEditorNotifyEvent event) if (m_renderViewport) { - m_renderViewport->GetControllerList()->SetEnabled(true); + m_renderViewport->SetInputProcessingEnabled(true); } break; diff --git a/Code/Framework/AzFramework/AzFramework/Viewport/CameraInput.cpp b/Code/Framework/AzFramework/AzFramework/Viewport/CameraInput.cpp index a85d631160..0516cdd591 100644 --- a/Code/Framework/AzFramework/AzFramework/Viewport/CameraInput.cpp +++ b/Code/Framework/AzFramework/AzFramework/Viewport/CameraInput.cpp @@ -747,7 +747,7 @@ namespace AzFramework return button == inputChannelId; }); - // Accept active mouse channel updates, inactive movement channels will just have a 0 delta. + // accept active mouse channel updates, inactive movement channels will just have a 0 delta if (inputChannel.IsActive()) { if (inputChannelId == InputDeviceMouse::Movement::X) @@ -763,6 +763,7 @@ namespace AzFramework return ScrollEvent{ inputChannel.GetValue() }; } } + if (wasMouseButton || InputDeviceKeyboard::IsKeyboardDevice(inputDeviceId)) { return DiscreteInputEvent{ inputChannelId, inputChannel.GetState() }; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Input/QtEventToAzInputManager.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Input/QtEventToAzInputManager.cpp index a90908fd9d..039c1da8f2 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Input/QtEventToAzInputManager.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Input/QtEventToAzInputManager.cpp @@ -200,8 +200,24 @@ namespace AzToolsFramework deviceId.GetNameCrc32() == AzFramework::InputDeviceKeyboard::Id.GetNameCrc32(); } + void QtEventToAzInputMapper::SetEnabled(bool enabled) + { + m_enabled = enabled; + if (!enabled) + { + // Send an internal focus change event to reset our input state to fresh if we're disabled. + HandleFocusChange(nullptr); + } + } + bool QtEventToAzInputMapper::eventFilter(QObject* object, QEvent* event) { + // Abort if processing isn't enabled. + if (!m_enabled) + { + return false; + } + // Because there's no "end" to mouse movement and wheel events, we reset mouse movement channels that have been opened // during the next processed non-mouse event. if (m_mouseChannelsNeedUpdate && event->type() != QEvent::Type::MouseMove && event->type() != QEvent::Type::Wheel) @@ -268,14 +284,14 @@ namespace AzToolsFramework { auto systemCursorChannel = GetInputChannel(AzFramework::InputDeviceMouse::SystemCursorPosition); - auto cursorZChannel = + auto mouseWheelChannel = GetInputChannel(AzFramework::InputDeviceMouse::Movement::Z); systemCursorChannel->ProcessRawInputEvent(m_cursorPosition->m_normalizedPositionDelta.GetLength()); - cursorZChannel->ProcessRawInputEvent(0.f); + mouseWheelChannel->ProcessRawInputEvent(0.f); NotifyUpdateChannelIfNotIdle(systemCursorChannel, nullptr); - NotifyUpdateChannelIfNotIdle(cursorZChannel, nullptr); + NotifyUpdateChannelIfNotIdle(mouseWheelChannel, nullptr); } void QtEventToAzInputMapper::HandleMouseButtonEvent(QMouseEvent* mouseEvent) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Input/QtEventToAzInputManager.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Input/QtEventToAzInputManager.h index 515e0c3f8a..28ad949e7c 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Input/QtEventToAzInputManager.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Input/QtEventToAzInputManager.h @@ -44,6 +44,9 @@ namespace AzToolsFramework //! \returns true if the channel is handled by MapQtEventToAzInput. bool HandlesInputEvent(const AzFramework::InputChannel& channel) const; + //! Sets whether or not this input mapper should be updating its input channels from Qt events. + void SetEnabled(bool enabled); + // QObject overrides... bool eventFilter(QObject* object, QEvent* event) override; @@ -64,7 +67,7 @@ namespace AzToolsFramework { return static_cast(channelIt->second); } - return {}; + return nullptr; } // Adds channels from the specified channel container to our input channel ID -> input channel lookup table. @@ -139,6 +142,8 @@ namespace AzToolsFramework QWidget* m_sourceWidget; // Flags when mouse movement channels have been opened and may need to be closed (as there are no movement ended events). bool m_mouseChannelsNeedUpdate = false; + // Flags whether or not Qt events should currently be processed. + bool m_enabled = true; // Our viewport-specific AZ devices. We control their internal input channel states. AZStd::unique_ptr m_mouseDevice; diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Viewport/RenderViewportWidget.h b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Viewport/RenderViewportWidget.h index 316741cdc5..50378c15bd 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Viewport/RenderViewportWidget.h +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Viewport/RenderViewportWidget.h @@ -82,6 +82,12 @@ namespace AtomToolsFramework //! Gets the default camera that's been automatically registered to our ViewportContext. AZ::RPI::ViewPtr GetDefaultCamera(); AZ::RPI::ConstViewPtr GetDefaultCamera() const; + //! Sets whether or not input processing is enabled for this RenderViewportWidget. + //! While input processing is enabled, synthetic input events may appear in OnInputChannelEventFiltered + //! due to internal viewport input mapping via QtEventToAzInputMapper, so it may be desirable to disable + //! camera controller input processing wholesale to avoid competing input messages. + //! Input processing is enabled by default. + void SetInputProcessingEnabled(bool enabled); // AzToolsFramework::ViewportInteraction::ViewportInteractionRequestBus::Handler ... AzFramework::CameraState GetCameraState() override; diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/RenderViewportWidget.cpp b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/RenderViewportWidget.cpp index 86ee8a9c39..9fcd93f069 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/RenderViewportWidget.cpp +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/RenderViewportWidget.cpp @@ -299,6 +299,12 @@ namespace AtomToolsFramework } } + void RenderViewportWidget::SetInputProcessingEnabled(bool enabled) + { + m_inputChannelMapper->SetEnabled(enabled); + m_controllerList->SetEnabled(enabled); + } + AzFramework::CameraState RenderViewportWidget::GetCameraState() { AZ::RPI::ViewPtr currentView = m_viewportContext->GetDefaultView();