LYN-5288 | Clicking on a Prefab in the viewport should select the entire Prefab and not an individual Entity (#4462)
* Setup work for the ContainerEntity SystemComponent and Interface. Signed-off-by: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com> * Introduce Container Entity Notification Bus Signed-off-by: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com> * Introduce a proxy model to control open/closed state of entity containers. Register prefab containers as entity containers. Profit. Signed-off-by: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com> * Add open state to OnContainerEntityStatusChanged notification + improvements to comments. Signed-off-by: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com> * Fix to notification trigger to include new arguments. Signed-off-by: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com> * Fix issue where the Level container would not be expanded correctly. The Level container is now no longer a container entity (since we don't need to be able to close it). Signed-off-by: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com> * Revert the addition of an extra proxy layer (which was causing issues) and just move the container logic to the existing filter. Fix bug in the dataChanged signal. Signed-off-by: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com> * Fix column count in dataChanged signal to correctly update all column and fix visual glitches. Limit container registration to the prefab WIP flag so that the changes can be submitted with an opt-in mechanism. Signed-off-by: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com> * Add doubleclick behavior on Outliner items - enters focus mode when double clicking on prefab containers. Signed-off-by: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com> * override sourceModel() to store pointer to avoid dynamic casting at every filterAcceptsRow call. Signed-off-by: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com> * Minor comment fixes and nits Signed-off-by: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com> * Move container selection logic to a helper function in the ContainerEntityInterface to simplify reusing it in the near future. Signed-off-by: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com> * Support lazy initialization for tests (since we do not load a level, the lazy initialization in OnEntityStreamLoadSuccess does not trigger) Signed-off-by: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com>
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
|
||||
#include <AzToolsFramework/Prefab/PrefabFocusHandler.h>
|
||||
|
||||
#include <AzToolsFramework/ContainerEntity/ContainerEntityInterface.h>
|
||||
#include <AzToolsFramework/Entity/EditorEntityHelpers.h>
|
||||
#include <AzToolsFramework/Entity/PrefabEditorEntityOwnershipInterface.h>
|
||||
#include <AzToolsFramework/Prefab/Instance/Instance.h>
|
||||
@@ -35,6 +36,30 @@ namespace AzToolsFramework::Prefab
|
||||
EditorEntityContextNotificationBus::Handler::BusDisconnect();
|
||||
}
|
||||
|
||||
void PrefabFocusHandler::Initialize()
|
||||
{
|
||||
m_containerEntityInterface = AZ::Interface<ContainerEntityInterface>::Get();
|
||||
AZ_Assert(
|
||||
m_containerEntityInterface,
|
||||
"Prefab - PrefabFocusHandler - "
|
||||
"Container Entity Interface could not be found. "
|
||||
"Check that it is being correctly initialized.");
|
||||
|
||||
m_focusModeInterface = AZ::Interface<FocusModeInterface>::Get();
|
||||
AZ_Assert(
|
||||
m_focusModeInterface,
|
||||
"Prefab - PrefabFocusHandler - "
|
||||
"Focus Mode Interface could not be found. "
|
||||
"Check that it is being correctly initialized.");
|
||||
|
||||
m_instanceEntityMapperInterface = AZ::Interface<InstanceEntityMapperInterface>::Get();
|
||||
AZ_Assert(
|
||||
m_instanceEntityMapperInterface,
|
||||
"Prefab - PrefabFocusHandler - "
|
||||
"Instance Entity Mapper Interface could not be found. "
|
||||
"Check that it is being correctly initialized.");
|
||||
}
|
||||
|
||||
PrefabFocusOperationResult PrefabFocusHandler::FocusOnOwningPrefab(AZ::EntityId entityId)
|
||||
{
|
||||
InstanceOptionalReference focusedInstance;
|
||||
@@ -44,7 +69,7 @@ namespace AzToolsFramework::Prefab
|
||||
PrefabEditorEntityOwnershipInterface* prefabEditorEntityOwnershipInterface =
|
||||
AZ::Interface<PrefabEditorEntityOwnershipInterface>::Get();
|
||||
|
||||
if(!prefabEditorEntityOwnershipInterface)
|
||||
if (!prefabEditorEntityOwnershipInterface)
|
||||
{
|
||||
return AZ::Failure(AZStd::string("Could not focus on root prefab instance - internal error "
|
||||
"(PrefabEditorEntityOwnershipInterface unavailable)."));
|
||||
@@ -79,8 +104,16 @@ namespace AzToolsFramework::Prefab
|
||||
return AZ::Failure(AZStd::string("Prefab Focus Handler: invalid instance to focus on."));
|
||||
}
|
||||
|
||||
if (!m_isInitialized)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
if (!m_focusedInstance.has_value() || &m_focusedInstance->get() != &focusedInstance->get())
|
||||
{
|
||||
// Close all container entities in the old path
|
||||
CloseInstanceContainers(m_instanceFocusVector);
|
||||
|
||||
m_focusedInstance = focusedInstance;
|
||||
m_focusedTemplateId = focusedInstance->get().GetTemplateId();
|
||||
|
||||
@@ -103,12 +136,14 @@ namespace AzToolsFramework::Prefab
|
||||
}
|
||||
|
||||
// Focus on the descendants of the container entity
|
||||
if (FocusModeInterface* focusModeInterface = AZ::Interface<FocusModeInterface>::Get())
|
||||
{
|
||||
focusModeInterface->SetFocusRoot(containerEntityId);
|
||||
}
|
||||
m_focusModeInterface->SetFocusRoot(containerEntityId);
|
||||
|
||||
// Refresh path variables
|
||||
RefreshInstanceFocusList();
|
||||
|
||||
// Open all container entities in the new path
|
||||
OpenInstanceContainers(m_instanceFocusVector);
|
||||
|
||||
PrefabFocusNotificationBus::Broadcast(&PrefabFocusNotifications::OnPrefabFocusChanged);
|
||||
}
|
||||
|
||||
@@ -156,6 +191,11 @@ namespace AzToolsFramework::Prefab
|
||||
|
||||
void PrefabFocusHandler::OnEntityStreamLoadSuccess()
|
||||
{
|
||||
if (!m_isInitialized)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
// Focus on the root prefab (AZ::EntityId() will default to it)
|
||||
FocusOnOwningPrefab(AZ::EntityId());
|
||||
}
|
||||
@@ -184,4 +224,26 @@ namespace AzToolsFramework::Prefab
|
||||
}
|
||||
}
|
||||
|
||||
void PrefabFocusHandler::OpenInstanceContainers(const AZStd::vector<InstanceOptionalReference>& instances) const
|
||||
{
|
||||
for (const InstanceOptionalReference& instance : instances)
|
||||
{
|
||||
if (instance.has_value())
|
||||
{
|
||||
m_containerEntityInterface->SetContainerOpenState(instance->get().GetContainerEntityId(), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PrefabFocusHandler::CloseInstanceContainers(const AZStd::vector<InstanceOptionalReference>& instances) const
|
||||
{
|
||||
for (const InstanceOptionalReference& instance : instances)
|
||||
{
|
||||
if (instance.has_value())
|
||||
{
|
||||
m_containerEntityInterface->SetContainerOpenState(instance->get().GetContainerEntityId(), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace AzToolsFramework::Prefab
|
||||
|
||||
@@ -15,6 +15,12 @@
|
||||
#include <AzToolsFramework/Prefab/PrefabFocusInterface.h>
|
||||
#include <AzToolsFramework/Prefab/Template/Template.h>
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
class ContainerEntityInterface;
|
||||
class FocusModeInterface;
|
||||
}
|
||||
|
||||
namespace AzToolsFramework::Prefab
|
||||
{
|
||||
class InstanceEntityMapperInterface;
|
||||
@@ -30,6 +36,8 @@ namespace AzToolsFramework::Prefab
|
||||
PrefabFocusHandler();
|
||||
~PrefabFocusHandler();
|
||||
|
||||
void Initialize();
|
||||
|
||||
// PrefabFocusInterface overrides ...
|
||||
PrefabFocusOperationResult FocusOnOwningPrefab(AZ::EntityId entityId) override;
|
||||
PrefabFocusOperationResult FocusOnPathIndex(AzFramework::EntityContextId entityContextId, int index) override;
|
||||
@@ -46,12 +54,19 @@ namespace AzToolsFramework::Prefab
|
||||
PrefabFocusOperationResult FocusOnPrefabInstance(InstanceOptionalReference focusedInstance);
|
||||
void RefreshInstanceFocusList();
|
||||
|
||||
void OpenInstanceContainers(const AZStd::vector<InstanceOptionalReference>& instances) const;
|
||||
void CloseInstanceContainers(const AZStd::vector<InstanceOptionalReference>& instances) const;
|
||||
|
||||
InstanceOptionalReference m_focusedInstance;
|
||||
TemplateId m_focusedTemplateId;
|
||||
AZStd::vector<InstanceOptionalReference> m_instanceFocusVector;
|
||||
AZ::IO::Path m_instanceFocusPath;
|
||||
|
||||
InstanceEntityMapperInterface* m_instanceEntityMapperInterface;
|
||||
ContainerEntityInterface* m_containerEntityInterface = nullptr;
|
||||
FocusModeInterface* m_focusModeInterface = nullptr;
|
||||
InstanceEntityMapperInterface* m_instanceEntityMapperInterface = nullptr;
|
||||
|
||||
bool m_isInitialized = false;
|
||||
};
|
||||
|
||||
} // namespace AzToolsFramework::Prefab
|
||||
|
||||
Reference in New Issue
Block a user