Introduce a new Focus Mode API function to retrieve full list of EntityIds that are in focus. (#7159)
Signed-off-by: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com>
This commit is contained in:
@@ -17,6 +17,8 @@
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
using EntityIdList = AZStd::vector<AZ::EntityId>;
|
||||
|
||||
//! FocusModeInterface
|
||||
//! Interface to handle the Editor Focus Mode.
|
||||
class FocusModeInterface
|
||||
@@ -36,6 +38,9 @@ namespace AzToolsFramework
|
||||
//! @return The entity id of the root of the Editor focus, or an invalid entity id if no focus is set.
|
||||
virtual AZ::EntityId GetFocusRoot(AzFramework::EntityContextId entityContextId) = 0;
|
||||
|
||||
//! Returns a list of the ids of all the entities that are descendants of the focus root.
|
||||
virtual EntityIdList GetFocusedEntities(AzFramework::EntityContextId entityContextId) = 0;
|
||||
|
||||
//! Returns whether the entity id provided is part of the focused sub-tree.
|
||||
virtual bool IsInFocusSubTree(AZ::EntityId entityId) const = 0;
|
||||
};
|
||||
|
||||
+62
@@ -40,10 +40,14 @@ namespace AzToolsFramework
|
||||
void FocusModeSystemComponent::Activate()
|
||||
{
|
||||
AZ::Interface<FocusModeInterface>::Register(this);
|
||||
EditorEntityInfoNotificationBus::Handler::BusConnect();
|
||||
Prefab::PrefabPublicNotificationBus::Handler::BusConnect();
|
||||
}
|
||||
|
||||
void FocusModeSystemComponent::Deactivate()
|
||||
{
|
||||
Prefab::PrefabPublicNotificationBus::Handler::BusDisconnect();
|
||||
EditorEntityInfoNotificationBus::Handler::BusDisconnect();
|
||||
AZ::Interface<FocusModeInterface>::Unregister(this);
|
||||
}
|
||||
|
||||
@@ -89,6 +93,9 @@ namespace AzToolsFramework
|
||||
|
||||
AZ::EntityId previousFocusEntityId = m_focusRoot;
|
||||
m_focusRoot = entityId;
|
||||
|
||||
RefreshFocusedEntityIdList();
|
||||
|
||||
FocusModeNotificationBus::Broadcast(&FocusModeNotifications::OnEditorFocusChanged, previousFocusEntityId, m_focusRoot);
|
||||
}
|
||||
|
||||
@@ -102,6 +109,11 @@ namespace AzToolsFramework
|
||||
return m_focusRoot;
|
||||
}
|
||||
|
||||
EntityIdList FocusModeSystemComponent::GetFocusedEntities([[maybe_unused]] AzFramework::EntityContextId entityContextId)
|
||||
{
|
||||
return m_focusedEntityIdList;
|
||||
}
|
||||
|
||||
bool FocusModeSystemComponent::IsInFocusSubTree(AZ::EntityId entityId) const
|
||||
{
|
||||
if (m_focusRoot == AZ::EntityId())
|
||||
@@ -112,4 +124,54 @@ namespace AzToolsFramework
|
||||
return AzToolsFramework::IsInFocusSubTree(entityId, m_focusRoot);
|
||||
}
|
||||
|
||||
void FocusModeSystemComponent::OnEntityInfoUpdatedAddChildEnd(AZ::EntityId parentId, AZ::EntityId childId)
|
||||
{
|
||||
// If the parent's entityId is in the list, add the child.
|
||||
if (auto iter = AZStd::find(m_focusedEntityIdList.begin(), m_focusedEntityIdList.end(), parentId);
|
||||
iter != m_focusedEntityIdList.end())
|
||||
{
|
||||
m_focusedEntityIdList.push_back(childId);
|
||||
}
|
||||
}
|
||||
|
||||
void FocusModeSystemComponent::OnEntityInfoUpdatedRemoveChildEnd([[maybe_unused]] AZ::EntityId parentId, AZ::EntityId childId)
|
||||
{
|
||||
// If the removed entityId is in the list, remove it.
|
||||
if (auto iter = AZStd::find(m_focusedEntityIdList.begin(), m_focusedEntityIdList.end(), childId);
|
||||
iter != m_focusedEntityIdList.end())
|
||||
{
|
||||
m_focusedEntityIdList.erase(iter);
|
||||
}
|
||||
}
|
||||
|
||||
void FocusModeSystemComponent::OnPrefabInstancePropagationEnd()
|
||||
{
|
||||
// Can't rely on any of the entities in the list to still exist, refresh the whole thing.
|
||||
RefreshFocusedEntityIdList();
|
||||
}
|
||||
|
||||
void FocusModeSystemComponent::RefreshFocusedEntityIdList()
|
||||
{
|
||||
m_focusedEntityIdList.clear();
|
||||
|
||||
AZStd::queue<AZ::EntityId> entityIdQueue;
|
||||
entityIdQueue.push(m_focusRoot);
|
||||
|
||||
while (!entityIdQueue.empty())
|
||||
{
|
||||
AZ::EntityId entityId = entityIdQueue.front();
|
||||
entityIdQueue.pop();
|
||||
|
||||
m_focusedEntityIdList.push_back(entityId);
|
||||
|
||||
EntityIdList children;
|
||||
EditorEntityInfoRequestBus::EventResult(children, entityId, &EditorEntityInfoRequestBus::Events::GetChildren);
|
||||
|
||||
for (AZ::EntityId childEntityId : children)
|
||||
{
|
||||
entityIdQueue.push(childEntityId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
@@ -11,7 +11,9 @@
|
||||
#include <AzCore/Component/Component.h>
|
||||
#include <AzCore/Memory/SystemAllocator.h>
|
||||
|
||||
#include <AzToolsFramework/Entity/EditorEntityInfoBus.h>
|
||||
#include <AzToolsFramework/FocusMode/FocusModeInterface.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabPublicNotificationBus.h>
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
@@ -21,6 +23,8 @@ namespace AzToolsFramework
|
||||
class FocusModeSystemComponent final
|
||||
: public AZ::Component
|
||||
, private FocusModeInterface
|
||||
, private EditorEntityInfoNotificationBus::Handler
|
||||
, private Prefab::PrefabPublicNotificationBus::Handler
|
||||
{
|
||||
public:
|
||||
AZ_COMPONENT(FocusModeSystemComponent, "{6CE522FE-2057-4794-BD05-61E04BD8EA30}");
|
||||
@@ -42,10 +46,21 @@ namespace AzToolsFramework
|
||||
void SetFocusRoot(AZ::EntityId entityId) override;
|
||||
void ClearFocusRoot(AzFramework::EntityContextId entityContextId) override;
|
||||
AZ::EntityId GetFocusRoot(AzFramework::EntityContextId entityContextId) override;
|
||||
EntityIdList GetFocusedEntities(AzFramework::EntityContextId entityContextId) override;
|
||||
bool IsInFocusSubTree(AZ::EntityId entityId) const override;
|
||||
|
||||
// EditorEntityInfoNotificationBus overrides ...
|
||||
void OnEntityInfoUpdatedAddChildEnd(AZ::EntityId parentId, AZ::EntityId childId) override;
|
||||
void OnEntityInfoUpdatedRemoveChildEnd(AZ::EntityId parentId, AZ::EntityId childId) override;
|
||||
|
||||
// PrefabPublicNotificationBus overrides ...
|
||||
void OnPrefabInstancePropagationEnd() override;
|
||||
|
||||
private:
|
||||
void RefreshFocusedEntityIdList();
|
||||
|
||||
AZ::EntityId m_focusRoot;
|
||||
EntityIdList m_focusedEntityIdList;
|
||||
};
|
||||
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
*/
|
||||
|
||||
#include <Tests/FocusMode/EditorFocusModeFixture.h>
|
||||
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
|
||||
|
||||
namespace UnitTest
|
||||
{
|
||||
@@ -30,6 +31,58 @@ namespace UnitTest
|
||||
EXPECT_EQ(m_focusModeInterface->GetFocusRoot(m_editorEntityContextId), AZ::EntityId());
|
||||
}
|
||||
|
||||
TEST_F(EditorFocusModeFixture, GetFocusedEntitiesBase)
|
||||
{
|
||||
m_focusModeInterface->SetFocusRoot(m_entityMap[StreetEntityName]);
|
||||
|
||||
AzToolsFramework::EntityIdList entities = m_focusModeInterface->GetFocusedEntities(m_editorEntityContextId);
|
||||
|
||||
EXPECT_EQ(entities.size(), 5);
|
||||
EXPECT_TRUE(AZStd::find(entities.begin(), entities.end(), m_entityMap[StreetEntityName]) != entities.end());
|
||||
EXPECT_TRUE(AZStd::find(entities.begin(), entities.end(), m_entityMap[CarEntityName]) != entities.end());
|
||||
EXPECT_TRUE(AZStd::find(entities.begin(), entities.end(), m_entityMap[Passenger1EntityName]) != entities.end());
|
||||
EXPECT_TRUE(AZStd::find(entities.begin(), entities.end(), m_entityMap[SportsCarEntityName]) != entities.end());
|
||||
EXPECT_TRUE(AZStd::find(entities.begin(), entities.end(), m_entityMap[Passenger2EntityName]) != entities.end());
|
||||
}
|
||||
|
||||
TEST_F(EditorFocusModeFixture, GetFocusedEntitiesSiblings)
|
||||
{
|
||||
m_focusModeInterface->SetFocusRoot(m_entityMap[SportsCarEntityName]);
|
||||
|
||||
AzToolsFramework::EntityIdList entities = m_focusModeInterface->GetFocusedEntities(m_editorEntityContextId);
|
||||
|
||||
EXPECT_EQ(entities.size(), 2);
|
||||
EXPECT_TRUE(AZStd::find(entities.begin(), entities.end(), m_entityMap[SportsCarEntityName]) != entities.end());
|
||||
EXPECT_TRUE(AZStd::find(entities.begin(), entities.end(), m_entityMap[Passenger2EntityName]) != entities.end());
|
||||
}
|
||||
|
||||
TEST_F(EditorFocusModeFixture, GetFocusedEntitiesAddEntity)
|
||||
{
|
||||
m_focusModeInterface->SetFocusRoot(m_entityMap[SportsCarEntityName]);
|
||||
|
||||
AZ::EntityId testEntityId = CreateEditorEntity("Test", m_entityMap[Passenger2EntityName]);
|
||||
|
||||
AzToolsFramework::EntityIdList entities = m_focusModeInterface->GetFocusedEntities(m_editorEntityContextId);
|
||||
|
||||
EXPECT_EQ(entities.size(), 3);
|
||||
EXPECT_TRUE(AZStd::find(entities.begin(), entities.end(), m_entityMap[SportsCarEntityName]) != entities.end());
|
||||
EXPECT_TRUE(AZStd::find(entities.begin(), entities.end(), m_entityMap[Passenger2EntityName]) != entities.end());
|
||||
EXPECT_TRUE(AZStd::find(entities.begin(), entities.end(), testEntityId) != entities.end());
|
||||
}
|
||||
|
||||
TEST_F(EditorFocusModeFixture, GetFocusedEntitiesRemoveEntity)
|
||||
{
|
||||
m_focusModeInterface->SetFocusRoot(m_entityMap[SportsCarEntityName]);
|
||||
|
||||
AzToolsFramework::ToolsApplicationRequestBus::Broadcast(
|
||||
&AzToolsFramework::ToolsApplicationRequests::DeleteEntityAndAllDescendants, m_entityMap[Passenger2EntityName]);
|
||||
|
||||
AzToolsFramework::EntityIdList entities = m_focusModeInterface->GetFocusedEntities(m_editorEntityContextId);
|
||||
|
||||
EXPECT_EQ(entities.size(), 1);
|
||||
EXPECT_TRUE(AZStd::find(entities.begin(), entities.end(), m_entityMap[SportsCarEntityName]) != entities.end());
|
||||
}
|
||||
|
||||
TEST_F(EditorFocusModeFixture, IsInFocusSubTreeAncestorsDescendants)
|
||||
{
|
||||
// When the focus is set to an entity, all its descendants are in the focus subtree while the ancestors aren't.
|
||||
|
||||
Reference in New Issue
Block a user