diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorHelpers.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorHelpers.cpp index 6399a64635..94795c44a9 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorHelpers.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorHelpers.cpp @@ -115,6 +115,33 @@ namespace AzToolsFramework } } + CursorEntityIdQuery::CursorEntityIdQuery(AZ::EntityId entityId, AZ::EntityId rootEntityId) + : m_entityId(entityId) + , m_containerAncestorEntityId(rootEntityId) + { + } + + AZ::EntityId CursorEntityIdQuery::EntityIdUnderCursor() const + { + return m_entityId; + } + + AZ::EntityId CursorEntityIdQuery::ContainerAncestorEntityId() const + { + return m_containerAncestorEntityId; + } + + bool CursorEntityIdQuery::HasContainerAncestorEntityId() const + { + if (m_entityId.IsValid()) + { + return m_entityId != m_containerAncestorEntityId; + } + + return false; + } + + EditorHelpers::EditorHelpers(const EditorVisibleEntityDataCache* entityDataCache) : m_entityDataCache(entityDataCache) { @@ -131,7 +158,7 @@ namespace AzToolsFramework m_invalidClicks = AZStd::make_unique(AZStd::move(invalidClicks)); } - AZ::EntityId EditorHelpers::HandleMouseInteraction( + CursorEntityIdQuery EditorHelpers::FindEntityIdUnderCursor( const AzFramework::CameraState& cameraState, const ViewportInteraction::MouseInteractionEvent& mouseInteraction) { AZ_PROFILE_FUNCTION(AzToolsFramework); @@ -202,17 +229,18 @@ namespace AzToolsFramework m_invalidClicks->AddInvalidClick(mouseInteraction.m_mouseInteraction.m_mousePick.m_screenCoordinates); } - return AZ::EntityId(); + return CursorEntityIdQuery(AZ::EntityId(), AZ::EntityId()); } // 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::Get()) { - return containerEntityInterface->FindHighestSelectableEntity(entityIdUnderCursor); + const auto highestSelectableEntity = containerEntityInterface->FindHighestSelectableEntity(entityIdUnderCursor); + return CursorEntityIdQuery(entityIdUnderCursor, highestSelectableEntity); } - return entityIdUnderCursor; + return CursorEntityIdQuery(entityIdUnderCursor, AZ::EntityId()); } void EditorHelpers::Display2d( diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorHelpers.h b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorHelpers.h index 6623221bdc..458f15c1f2 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorHelpers.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorHelpers.h @@ -32,6 +32,28 @@ namespace AzToolsFramework struct MouseInteractionEvent; } + //!< Represents the result of a query to find the id of the entity under the cursor (if any). + class CursorEntityIdQuery + { + public: + CursorEntityIdQuery(AZ::EntityId entityId, AZ::EntityId rootEntityId); + + //! Returns the entity id under the cursor (if any). + //! @note In the case of no entity id under the cursor, an invalid entity id is returned. + AZ::EntityId EntityIdUnderCursor() const; + + //! Returns the topmost container entity id in the hierarchy if the entity id under the cursor is inside a container entity, otherwise returns the entity id. + //! @note In the case of no entity id under the cursor, an invalid entity id is returned. + AZ::EntityId ContainerAncestorEntityId() const; + + //! Returns true if the query has a container ancestor entity id, otherwise false. + bool HasContainerAncestorEntityId() const; + + private: + AZ::EntityId m_entityId; //HandleMouseInteraction(cameraState, mouseInteraction); + m_cachedEntityIdUnderCursor = m_editorHelpers->FindEntityIdUnderCursor(cameraState, mouseInteraction).ContainerAncestorEntityId(); // when left clicking, if we successfully clicked an entity, assign that // to the entity field selected in the entity inspector (RPE) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.cpp index c73742da4d..39c882b766 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -1799,7 +1800,8 @@ namespace AzToolsFramework const AzFramework::ViewportId viewportId = mouseInteraction.m_mouseInteraction.m_interactionId.m_viewportId; const AzFramework::CameraState cameraState = GetCameraState(viewportId); - m_cachedEntityIdUnderCursor = m_editorHelpers->HandleMouseInteraction(cameraState, mouseInteraction); + const auto cursorEntityIdQuery = m_editorHelpers->FindEntityIdUnderCursor(cameraState, mouseInteraction); + m_cachedEntityIdUnderCursor = cursorEntityIdQuery.ContainerAncestorEntityId(); const auto selectClickEvent = ClickDetectorEventFromViewportInteraction(mouseInteraction); m_cursorState.SetCurrentPosition(mouseInteraction.m_mouseInteraction.m_mousePick.m_screenCoordinates); @@ -1825,8 +1827,6 @@ namespace AzToolsFramework } } - const AZ::EntityId entityIdUnderCursor = m_cachedEntityIdUnderCursor; - EditorContextMenuUpdate(m_contextMenu, mouseInteraction); m_boxSelect.HandleMouseInteraction(mouseInteraction); @@ -1842,6 +1842,21 @@ namespace AzToolsFramework return true; } + const AZ::EntityId entityIdUnderCursor = m_cachedEntityIdUnderCursor; + + if (mouseInteraction.m_mouseEvent == ViewportInteraction::MouseEvent::DoubleClick && + mouseInteraction.m_mouseInteraction.m_mouseButtons.Left()) + { + if (cursorEntityIdQuery.HasContainerAncestorEntityId()) + { + if (auto prefabFocusInterface = AZ::Interface::Get()) + { + prefabFocusInterface->FocusOnPrefabInstanceOwningEntityId(cursorEntityIdQuery.ContainerAncestorEntityId()); + return false; + } + } + } + bool stickySelect = false; ViewportInteraction::ViewportSettingsRequestBus::EventResult( stickySelect, viewportId, &ViewportInteraction::ViewportSettingsRequestBus::Events::StickySelectEnabled);