Merge pull request #4725 from aws-lumberyard-dev/hultonha_LYN-7394_focus_cursor
Updates to support 'lock'/'forbidden' cursor when in Focus Mode
This commit is contained in:
@@ -38,6 +38,8 @@ namespace UnitTest
|
||||
void BeginCursorCapture() override;
|
||||
void EndCursorCapture() override;
|
||||
bool IsMouseOver() const override;
|
||||
void SetOverrideCursor(AzToolsFramework::ViewportInteraction::CursorStyleOverride cursorStyleOverride) override;
|
||||
void ClearOverrideCursor() override;
|
||||
|
||||
private:
|
||||
AzToolsFramework::QtEventToAzInputMapper* m_inputChannelMapper = nullptr;
|
||||
@@ -58,6 +60,17 @@ namespace UnitTest
|
||||
return true;
|
||||
}
|
||||
|
||||
void ViewportMouseCursorRequestImpl::SetOverrideCursor(
|
||||
[[maybe_unused]] AzToolsFramework::ViewportInteraction::CursorStyleOverride cursorStyleOverride)
|
||||
{
|
||||
// noop
|
||||
}
|
||||
|
||||
void ViewportMouseCursorRequestImpl::ClearOverrideCursor()
|
||||
{
|
||||
// noop
|
||||
}
|
||||
|
||||
class ModularViewportCameraControllerFixture : public AllocatorsTestFixture
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -244,6 +244,17 @@ namespace AzToolsFramework
|
||||
|
||||
const auto eventType = event->type();
|
||||
|
||||
if (eventType == QEvent::Type::MouseMove)
|
||||
{
|
||||
// clear override cursor when moving outside of the viewport
|
||||
const auto* mouseEvent = static_cast<const QMouseEvent*>(event);
|
||||
if (m_overrideCursor && !m_sourceWidget->geometry().contains(m_sourceWidget->mapFromGlobal(mouseEvent->globalPos())))
|
||||
{
|
||||
qApp->restoreOverrideCursor();
|
||||
m_overrideCursor = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Only accept mouse & key release events that originate from an object that is not our target widget,
|
||||
// as we don't want to erroneously intercept user input meant for another component.
|
||||
if (object != m_sourceWidget && eventType != QEvent::Type::KeyRelease && eventType != QEvent::Type::MouseButtonRelease)
|
||||
@@ -262,7 +273,7 @@ namespace AzToolsFramework
|
||||
if (eventType == QEvent::FocusIn)
|
||||
{
|
||||
const auto globalCursorPosition = QCursor::pos();
|
||||
if (m_sourceWidget->geometry().contains(globalCursorPosition))
|
||||
if (m_sourceWidget->geometry().contains(m_sourceWidget->mapFromGlobal(globalCursorPosition)))
|
||||
{
|
||||
HandleMouseMoveEvent(globalCursorPosition);
|
||||
}
|
||||
@@ -452,4 +463,32 @@ namespace AzToolsFramework
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static Qt::CursorShape QtCursorFromAzCursor(const ViewportInteraction::CursorStyleOverride cursorStyleOverride)
|
||||
{
|
||||
switch (cursorStyleOverride)
|
||||
{
|
||||
case ViewportInteraction::CursorStyleOverride::Forbidden:
|
||||
return Qt::ForbiddenCursor;
|
||||
default:
|
||||
return Qt::ArrowCursor;
|
||||
}
|
||||
}
|
||||
|
||||
void QtEventToAzInputMapper::SetOverrideCursor(ViewportInteraction::CursorStyleOverride cursorStyleOverride)
|
||||
{
|
||||
ClearOverrideCursor();
|
||||
|
||||
qApp->setOverrideCursor(QtCursorFromAzCursor(cursorStyleOverride));
|
||||
m_overrideCursor = true;
|
||||
}
|
||||
|
||||
void QtEventToAzInputMapper::ClearOverrideCursor()
|
||||
{
|
||||
if (m_overrideCursor)
|
||||
{
|
||||
qApp->restoreOverrideCursor();
|
||||
m_overrideCursor = false;
|
||||
}
|
||||
}
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
@@ -15,10 +15,11 @@
|
||||
#include <AzFramework/Input/Channels/InputChannelDeltaWithSharedPosition2D.h>
|
||||
#include <AzFramework/Input/Channels/InputChannelDigitalWithSharedModifierKeyStates.h>
|
||||
#include <AzFramework/Input/Channels/InputChannelDigitalWithSharedPosition2D.h>
|
||||
|
||||
#include <AzFramework/Input/Devices/Keyboard/InputDeviceKeyboard.h>
|
||||
#include <AzFramework/Input/Devices/Mouse/InputDeviceMouse.h>
|
||||
|
||||
#include <AzToolsFramework/Viewport/ViewportMessages.h>
|
||||
|
||||
#include <QEvent>
|
||||
#include <QObject>
|
||||
#include <QPoint>
|
||||
@@ -55,6 +56,9 @@ namespace AzToolsFramework
|
||||
//! like a dolly or rotation, where mouse movement is important but cursor location is not.
|
||||
void SetCursorCaptureEnabled(bool enabled);
|
||||
|
||||
void SetOverrideCursor(ViewportInteraction::CursorStyleOverride cursorStyleOverride);
|
||||
void ClearOverrideCursor();
|
||||
|
||||
// QObject overrides...
|
||||
bool eventFilter(QObject* object, QEvent* event) override;
|
||||
|
||||
@@ -164,6 +168,8 @@ namespace AzToolsFramework
|
||||
bool m_enabled = true;
|
||||
// Flags whether or not the cursor is being constrained to the source widget (for invisible mouse movement).
|
||||
bool m_capturingCursor = false;
|
||||
// Flags whether the cursor has been overridden.
|
||||
bool m_overrideCursor = false;
|
||||
|
||||
// Our viewport-specific AZ devices. We control their internal input channel states.
|
||||
AZStd::unique_ptr<EditorQtMouseDevice> m_mouseDevice;
|
||||
|
||||
@@ -302,6 +302,12 @@ namespace AzToolsFramework
|
||||
|
||||
using EditorViewportInputTimeNowRequestBus = AZ::EBus<EditorViewportInputTimeNowRequests>;
|
||||
|
||||
//! The style of cursor override.
|
||||
enum class CursorStyleOverride
|
||||
{
|
||||
Forbidden
|
||||
};
|
||||
|
||||
//! Viewport requests for managing the viewport cursor state.
|
||||
class ViewportMouseCursorRequests
|
||||
{
|
||||
@@ -312,6 +318,10 @@ namespace AzToolsFramework
|
||||
virtual void EndCursorCapture() = 0;
|
||||
//! Is the mouse over the viewport.
|
||||
virtual bool IsMouseOver() const = 0;
|
||||
//! Set the cursor style override.
|
||||
virtual void SetOverrideCursor(CursorStyleOverride cursorStyleOverride) = 0;
|
||||
//! Clear the cursor style override.
|
||||
virtual void ClearOverrideCursor() = 0;
|
||||
|
||||
protected:
|
||||
~ViewportMouseCursorRequests() = default;
|
||||
|
||||
@@ -44,6 +44,13 @@ AZ_CVAR(
|
||||
nullptr,
|
||||
AZ::ConsoleFunctorFlags::Null,
|
||||
"Display the aggregate world bounds for a given entity (the union of all world component Aabbs)");
|
||||
AZ_CVAR(
|
||||
bool,
|
||||
ed_useCursorLockIconInFocusMode,
|
||||
false,
|
||||
nullptr,
|
||||
AZ::ConsoleFunctorFlags::Null,
|
||||
"Use a lock icon when the cursor is over entities that cannot be interacted with");
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
@@ -222,6 +229,13 @@ namespace AzToolsFramework
|
||||
// verify if the entity Id corresponds to an entity that is focused; if not, halt selection.
|
||||
if (entityIdUnderCursor.IsValid() && !IsSelectableAccordingToFocusMode(entityIdUnderCursor))
|
||||
{
|
||||
if (ed_useCursorLockIconInFocusMode)
|
||||
{
|
||||
ViewportInteraction::ViewportMouseCursorRequestBus::Event(
|
||||
viewportId, &ViewportInteraction::ViewportMouseCursorRequestBus::Events::SetOverrideCursor,
|
||||
ViewportInteraction::CursorStyleOverride::Forbidden);
|
||||
}
|
||||
|
||||
if (mouseInteraction.m_mouseInteraction.m_mouseButtons.Left() &&
|
||||
mouseInteraction.m_mouseEvent == ViewportInteraction::MouseEvent::Down ||
|
||||
mouseInteraction.m_mouseEvent == ViewportInteraction::MouseEvent::DoubleClick)
|
||||
@@ -232,6 +246,9 @@ namespace AzToolsFramework
|
||||
return CursorEntityIdQuery(AZ::EntityId(), AZ::EntityId());
|
||||
}
|
||||
|
||||
ViewportInteraction::ViewportMouseCursorRequestBus::Event(
|
||||
viewportId, &ViewportInteraction::ViewportMouseCursorRequestBus::Events::ClearOverrideCursor);
|
||||
|
||||
// container entity support - if the entity that is being selected is part of a closed container,
|
||||
// change the selection to the container instead.
|
||||
if (ContainerEntityInterface* containerEntityInterface = AZ::Interface<ContainerEntityInterface>::Get())
|
||||
|
||||
+2
@@ -102,6 +102,8 @@ namespace AtomToolsFramework
|
||||
void BeginCursorCapture() override;
|
||||
void EndCursorCapture() override;
|
||||
bool IsMouseOver() const override;
|
||||
void SetOverrideCursor(AzToolsFramework::ViewportInteraction::CursorStyleOverride cursorStyleOverride) override;
|
||||
void ClearOverrideCursor() override;
|
||||
|
||||
// AzFramework::WindowRequestBus::Handler overrides ...
|
||||
void SetWindowTitle(const AZStd::string& title) override;
|
||||
|
||||
@@ -375,6 +375,16 @@ namespace AtomToolsFramework
|
||||
m_inputChannelMapper->SetCursorCaptureEnabled(false);
|
||||
}
|
||||
|
||||
void RenderViewportWidget::SetOverrideCursor(AzToolsFramework::ViewportInteraction::CursorStyleOverride cursorStyleOverride)
|
||||
{
|
||||
m_inputChannelMapper->SetOverrideCursor(cursorStyleOverride);
|
||||
}
|
||||
|
||||
void RenderViewportWidget::ClearOverrideCursor()
|
||||
{
|
||||
m_inputChannelMapper->ClearOverrideCursor();
|
||||
}
|
||||
|
||||
void RenderViewportWidget::SetWindowTitle(const AZStd::string& title)
|
||||
{
|
||||
setWindowTitle(QString::fromUtf8(title.c_str()));
|
||||
|
||||
Reference in New Issue
Block a user