From 45926d0dbddc3bb8a294bb407cb07ade47bdd37b Mon Sep 17 00:00:00 2001 From: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com> Date: Fri, 22 Oct 2021 12:37:43 -0700 Subject: [PATCH] LYN-7539 + LYN-7541 | Focus Mode - Show prefab names and dirty markers instead of instance names in breadcrumbs (#4850) * Change Prefab Focus breadcrumb widget to display template filename instead of instance container entity name. Also display dirty state for the template (*) and refresh it in real time. Signed-off-by: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com> * Streamline path creation code; fix stem retrieval to ensure extension is cut correctly; delay refresh one frame when path is clicked to correctly refresh it. Signed-off-by: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com> * Remove test code. Signed-off-by: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com> * Simplify code to use Native directly. Signed-off-by: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com> * Minor variable renaming and comment adjustments to make them clearer. Signed-off-by: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com> --- .../Prefab/PrefabFocusHandler.cpp | 57 ++++++++++++++++--- .../Prefab/PrefabFocusHandler.h | 5 +- .../Prefab/PrefabPublicNotificationBus.h | 4 ++ .../Prefab/PrefabSystemComponent.cpp | 11 ++-- .../Prefab/PrefabViewportFocusPathHandler.cpp | 5 ++ 5 files changed, 68 insertions(+), 14 deletions(-) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabFocusHandler.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabFocusHandler.cpp index 8bc258fef9..5ba7382831 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabFocusHandler.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabFocusHandler.cpp @@ -16,6 +16,7 @@ #include #include #include +#include namespace AzToolsFramework::Prefab { @@ -79,7 +80,7 @@ namespace AzToolsFramework::Prefab auto editUndo = aznew PrefabFocusUndo("Edit Prefab"); editUndo->Capture(entityId); editUndo->SetParent(undoBatch.GetUndoBatch()); - ToolsApplicationRequestBus::Broadcast(&ToolsApplicationRequestBus::Events::RunRedoSeparately, editUndo); + FocusOnPrefabInstanceOwningEntityId(entityId); } return AZ::Success(); @@ -94,9 +95,7 @@ namespace AzToolsFramework::Prefab InstanceOptionalReference focusedInstance = m_instanceFocusHierarchy[index]; - FocusOnOwningPrefab(focusedInstance->get().GetContainerEntityId()); - - return AZ::Success(); + return FocusOnOwningPrefab(focusedInstance->get().GetContainerEntityId()); } PrefabFocusOperationResult PrefabFocusHandler::FocusOnPrefabInstanceOwningEntityId(AZ::EntityId entityId) @@ -255,7 +254,7 @@ namespace AzToolsFramework::Prefab void PrefabFocusHandler::OnEntityInfoUpdatedName(AZ::EntityId entityId, [[maybe_unused]]const AZStd::string& name) { - // Determine if the entityId is the container for any of the instances in the vector + // Determine if the entityId is the container for any of the instances in the vector. auto result = AZStd::find_if( m_instanceFocusHierarchy.begin(), m_instanceFocusHierarchy.end(), [entityId](const InstanceOptionalReference& instance) @@ -279,6 +278,25 @@ namespace AzToolsFramework::Prefab PrefabFocusNotificationBus::Broadcast(&PrefabFocusNotifications::OnPrefabFocusChanged); } + void PrefabFocusHandler::OnPrefabTemplateDirtyFlagUpdated(TemplateId templateId, [[maybe_unused]] bool status) + { + // Determine if the templateId matches any of the instances in the vector. + auto result = AZStd::find_if( + m_instanceFocusHierarchy.begin(), m_instanceFocusHierarchy.end(), + [templateId](const InstanceOptionalReference& instance) + { + return (instance->get().GetTemplateId() == templateId); + } + ); + + if (result != m_instanceFocusHierarchy.end()) + { + // Refresh the path and notify changes. + RefreshInstanceFocusPath(); + PrefabFocusNotificationBus::Broadcast(&PrefabFocusNotifications::OnPrefabFocusChanged); + } + } + void PrefabFocusHandler::RefreshInstanceFocusList() { m_instanceFocusHierarchy.clear(); @@ -293,17 +311,42 @@ namespace AzToolsFramework::Prefab currentInstance = currentInstance->get().GetParentInstance(); } - // Invert the vector, since we need the top instance to be at index 0 + // Invert the vector, since we need the top instance to be at index 0. AZStd::reverse(m_instanceFocusHierarchy.begin(), m_instanceFocusHierarchy.end()); } void PrefabFocusHandler::RefreshInstanceFocusPath() { + auto prefabSystemComponentInterface = AZ::Interface::Get(); + m_instanceFocusPath.clear(); + size_t index = 0; + size_t maxIndex = m_instanceFocusHierarchy.size() - 1; + for (const InstanceOptionalReference& instance : m_instanceFocusHierarchy) { - m_instanceFocusPath.Append(instance->get().GetContainerEntity()->get().GetName()); + AZStd::string prefabName; + + if (index < maxIndex) + { + // Get the filename without the extension (stem). + prefabName = instance->get().GetTemplateSourcePath().Stem().Native(); + } + else + { + // Get the full filename. + prefabName = instance->get().GetTemplateSourcePath().Filename().Native(); + } + + if (prefabSystemComponentInterface->IsTemplateDirty(instance->get().GetTemplateId())) + { + prefabName += "*"; + } + + m_instanceFocusPath.Append(prefabName); + + ++index; } } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabFocusHandler.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabFocusHandler.h index cb8165e7f0..9decaed1ec 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabFocusHandler.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabFocusHandler.h @@ -64,8 +64,9 @@ namespace AzToolsFramework::Prefab void OnEntityInfoUpdatedName(AZ::EntityId entityId, const AZStd::string& name) override; // PrefabPublicNotifications overrides ... - void OnPrefabInstancePropagationEnd(); - + void OnPrefabInstancePropagationEnd() override; + void OnPrefabTemplateDirtyFlagUpdated(TemplateId templateId, bool status) override; + private: PrefabFocusOperationResult FocusOnPrefabInstance(InstanceOptionalReference focusedInstance); void RefreshInstanceFocusList(); diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicNotificationBus.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicNotificationBus.h index 65725b04de..8b0d446f51 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicNotificationBus.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicNotificationBus.h @@ -9,6 +9,7 @@ #pragma once #include +#include namespace AzToolsFramework { @@ -22,6 +23,9 @@ namespace AzToolsFramework virtual void OnPrefabInstancePropagationBegin() {} virtual void OnPrefabInstancePropagationEnd() {} + + virtual void OnPrefabTemplateDirtyFlagUpdated( + [[maybe_unused]] TemplateId templateId, [[maybe_unused]] bool status) {} }; using PrefabPublicNotificationBus = AZ::EBus; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.cpp index b1fdf9784d..c930c66786 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.cpp @@ -185,7 +185,7 @@ namespace AzToolsFramework if (AZ::JsonSerialization::Compare(templateDomToUpdate, updatedDom) != AZ::JsonSerializerCompareResult::Equal) { templateDomToUpdate.CopyFrom(updatedDom, templateDomToUpdate.GetAllocator()); - templateToUpdate->get().MarkAsDirty(true); + SetTemplateDirtyFlag(templateId, true); PropagateTemplateChanges(templateId); } } @@ -813,11 +813,12 @@ namespace AzToolsFramework void PrefabSystemComponent::SetTemplateDirtyFlag(TemplateId templateId, bool dirty) { - auto templateRef = FindTemplate(templateId); - - if (templateRef.has_value()) + if (auto templateReference = FindTemplate(templateId); templateReference.has_value()) { - templateRef->get().MarkAsDirty(dirty); + templateReference->get().MarkAsDirty(dirty); + + PrefabPublicNotificationBus::Broadcast( + &PrefabPublicNotificationBus::Events::OnPrefabTemplateDirtyFlagUpdated, templateId, dirty); } } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Prefab/PrefabViewportFocusPathHandler.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Prefab/PrefabViewportFocusPathHandler.cpp index 21ada94184..52cf3279a4 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Prefab/PrefabViewportFocusPathHandler.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Prefab/PrefabViewportFocusPathHandler.cpp @@ -10,6 +10,8 @@ #include +#include + namespace AzToolsFramework::Prefab { PrefabViewportFocusPathHandler::PrefabViewportFocusPathHandler() @@ -47,6 +49,9 @@ namespace AzToolsFramework::Prefab [&](const QString&, int linkIndex) { m_prefabFocusPublicInterface->FocusOnPathIndex(m_editorEntityContextId, linkIndex); + + // Manually refresh path + QTimer::singleShot(0, [&]() { OnPrefabFocusChanged(); }); } );