Pārlūkot izejas kodu

Add support to show override icon in DPE based entity inspector (#14507)

* Initial prototype for prefabs-dpe integration

Idea is simple:
1. If non-opaque value, simply convert AZ::Dom::Value to PrefabDomValue
2. If opaque value, get its void* and serialize the value
3. In either of the above cases, modify dpe-dompath to prefab-dompath by
   reading in the 'SerializedPath' information stored in property editor
   nodes

Signed-off-by: srikappa-amzn <[email protected]>

* Remove merge conflict leftovers

Signed-off-by: srikappa-amzn <[email protected]>

* Add override icon to dpe rows and context menu to revert overrides

Signed-off-by: srikappa-amzn <[email protected]>

* Serialized values to json and injected into dpe dom instead of storing them as opaque values

Signed-off-by: srikappa-amzn <[email protected]>

* Make the label left aligned to override icon and make the icon smaller

Signed-off-by: srikappa-amzn <[email protected]>

* Fix enabling dpe flag after merge from development

Signed-off-by: srikappa-amzn <[email protected]>

* Remove pragma optimize lines

Signed-off-by: srikappa-amzn <[email protected]>

* Add a new setting registry key to put the inspector overrides work under

Signed-off-by: srikappa-amzn <[email protected]>

* Hide dpe integration code behind a flag

Signed-off-by: srikappa-amzn <[email protected]>

* Add a prefab adapter

Signed-off-by: srikappa-amzn <[email protected]>

* Remove unused code in DPEComponentAdapter

Signed-off-by: srikappa-amzn <[email protected]>

* Code cleanup for PR

Signed-off-by: srikappa-amzn <[email protected]>

* More code cleanup

Signed-off-by: srikappa-amzn <[email protected]>

* Move PrefabEditorPreferences to AzCore and wrap new logic in ReflectionAdapter in feature flag

Signed-off-by: srikappa-amzn <[email protected]>

* Move implementation of new virtual methods to cpp files

Signed-off-by: srikappa-amzn <[email protected]>

* Move prefab editor preferences back to AzToolsFramework

Signed-off-by: srikappa-amzn <[email protected]>

* Added function and class comments

Signed-off-by: srikappa-amzn <[email protected]>

* Remove unused variable and revert label and LegacyReflectionBridge behavior to previous one

Signed-off-by: srikappa-amzn <[email protected]>

* Change SetSerializedIdentifier to use an rvalue reference to avoid new copy for string literals

Signed-off-by: srikappa-amzn <[email protected]>

* Moved OverrideProperty registration to prefab adapter

Signed-off-by: srikappa-amzn <[email protected]>

* Removed explicit AzToolsFramework::Prefab namespacing when redundant

Signed-off-by: srikappa-amzn <[email protected]>

* Remove unused variables

Signed-off-by: srikappa-amzn <[email protected]>

* Remove nested namespace for forward declaration to fix clang error on linux

Signed-off-by: srikappa-amzn <[email protected]>

* Added a nullptr check

Signed-off-by: srikappa-amzn <[email protected]>

* Add comment about the existence of IsInspectorOverrideManagementEnabled check in ReflectionAdapter

Signed-off-by: srikappa-amzn <[email protected]>

* Changed variable from AZ::Dom::Path to AZStd::string_view in AreOverridesPresent method for automated tests support

Signed-off-by: srikappa-amzn <[email protected]>

---------

Signed-off-by: srikappa-amzn <[email protected]>
srikappa-amzn 2 gadi atpakaļ
vecāks
revīzija
4f15a55606
28 mainītis faili ar 486 papildinājumiem un 52 dzēšanām
  1. 1 1
      AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/editor_entity_utils.py
  2. 9 0
      Code/Framework/AzCore/AzCore/Component/Component.cpp
  3. 10 0
      Code/Framework/AzCore/AzCore/Component/Component.h
  4. 1 0
      Code/Framework/AzCore/AzCore/Component/EntitySerializer.cpp
  5. 4 1
      Code/Framework/AzFramework/AzFramework/DocumentPropertyEditor/Reflection/LegacyReflectionBridge.cpp
  6. 109 35
      Code/Framework/AzFramework/AzFramework/DocumentPropertyEditor/ReflectionAdapter.cpp
  7. 7 0
      Code/Framework/AzFramework/AzFramework/DocumentPropertyEditor/ReflectionAdapter.h
  8. 39 0
      Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/DocumentPropertyEditor/OverridePropertyHandler.cpp
  9. 43 0
      Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/DocumentPropertyEditor/OverridePropertyHandler.h
  10. 55 0
      Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/DocumentPropertyEditor/PrefabAdapter.cpp
  11. 32 0
      Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/DocumentPropertyEditor/PrefabAdapter.h
  12. 41 0
      Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/DocumentPropertyEditor/PrefabAdapterInterface.h
  13. 19 0
      Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/DocumentPropertyEditor/PrefabPropertyEditorNodes.h
  14. 5 1
      Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Overrides/PrefabOverridePublicHandler.cpp
  15. 3 1
      Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Overrides/PrefabOverridePublicHandler.h
  16. 4 1
      Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Overrides/PrefabOverridePublicInterface.h
  17. 14 1
      Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabEditorPreferences.cpp
  18. 1 0
      Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabEditorPreferences.h
  19. 0 1
      Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.cpp
  20. 10 0
      Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/EditorComponentBase.cpp
  21. 9 0
      Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/EditorComponentBase.h
  22. 24 6
      Code/Framework/AzToolsFramework/AzToolsFramework/UI/DocumentPropertyEditor/DPEComponentAdapter.cpp
  23. 12 0
      Code/Framework/AzToolsFramework/AzToolsFramework/UI/DocumentPropertyEditor/DPEComponentAdapter.h
  24. 6 0
      Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/EntityPropertyEditor.cpp
  25. 3 0
      Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/EntityPropertyEditor.hxx
  26. 16 1
      Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyEditorAPI_Internals.h
  27. 8 2
      Code/Framework/AzToolsFramework/AzToolsFramework/aztoolsframework_files.cmake
  28. 1 1
      Registry/o3de.editor.setreg

+ 1 - 1
AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/editor_entity_utils.py

@@ -757,7 +757,7 @@ class EditorEntity:
         as this will currently always return as True on a container entity.
         :return: True if overrides are present, False otherwise
         """
-        return prefab.PrefabOverridePublicRequestBus(bus.Broadcast, "AreOverridesPresent", self.id)
+        return prefab.PrefabOverridePublicRequestBus(bus.Broadcast, "AreOverridesPresent", self.id, "")
 
     def revert_overrides(self) -> bool:
         """

+ 9 - 0
Code/Framework/AzCore/AzCore/Component/Component.cpp

@@ -159,6 +159,15 @@ namespace AZ
         }
     }
 
+    AZStd::string Component::GetSerializedIdentifier() const
+    {
+        return AZStd::string();
+    }
+
+    void Component::SetSerializedIdentifier(AZStd::string)
+    {
+    }
+
     //=========================================================================
     // ReflectInternal
     //=========================================================================

+ 10 - 0
Code/Framework/AzCore/AzCore/Component/Component.h

@@ -118,6 +118,16 @@ namespace AZ
          */
         void SetId(const ComponentId& id)   { m_id = id; }
 
+        //! Sets the provided string as the serialized identifier for the component. This should be done only for editor components
+        //! since those are the only ones that'll be written to disk.
+        //! @param serializedIdentifer The unique identifier for this component within the entity it lives in.
+        virtual void SetSerializedIdentifier(AZStd::string serializedIdentifer);
+
+        //! Gets the serialzied identifier of this component within an entity. This will be a non-empty string for components that
+        //! inherit from EditorComponentBase. For all others, it'll be empty.
+        //! @return The serialized identifier of this component.
+        virtual AZStd::string GetSerializedIdentifier() const;
+
         /**
         * Override to conduct per-component or per-slice validation logic during slice asset processing.
         * @param sliceEntities All entities that belong to the slice that the entity with this component is on.

+ 1 - 0
Code/Framework/AzCore/AzCore/Component/EntitySerializer.cpp

@@ -89,6 +89,7 @@ namespace AZ
                 if (component && (component->GetUnderlyingComponentType() != genericComponentWrapperTypeId))
                 {
                     entityInstance->m_components.emplace_back(component);
+                    component->SetSerializedIdentifier(componentKey);
                 }
             }
 

+ 4 - 1
Code/Framework/AzFramework/AzFramework/DocumentPropertyEditor/Reflection/LegacyReflectionBridge.cpp

@@ -254,7 +254,10 @@ namespace AZ::Reflection
                 else if (classElement)
                 {
                     AZStd::string_view elementName = classElement->m_name;
-                    if (!elementName.empty())
+
+                    // Construct the serialized path for only those elements that have valid edit data. Otherwise, you can end up with
+                    // serialized paths looking like "token1////token2/token3"
+                    if (!elementName.empty() && classElement->m_editData)
                     {
                         path.append("/");
                         path.append(elementName);

+ 109 - 35
Code/Framework/AzFramework/AzFramework/DocumentPropertyEditor/ReflectionAdapter.cpp

@@ -7,10 +7,11 @@
  */
 
 #include <AzCore/Component/ComponentApplicationBus.h>
+#include <AzCore/DOM/Backends/JSON/JsonSerializationUtils.h>
 #include <AzCore/DOM/DomPrefixTree.h>
 #include <AzCore/DOM/DomUtils.h>
+#include <AzCore/Settings/SettingsRegistry.h>
 #include <AzCore/std/ranges/ranges_algorithm.h>
-#include <AzFramework/DocumentPropertyEditor/AdapterBuilder.h>
 #include <AzFramework/DocumentPropertyEditor/PropertyEditorNodes.h>
 #include <AzFramework/DocumentPropertyEditor/Reflection/LegacyReflectionBridge.h>
 #include <AzFramework/DocumentPropertyEditor/ReflectionAdapter.h>
@@ -25,6 +26,8 @@ namespace AZ::DocumentPropertyEditor
         // Look-up table of onChanged callbacks for handling property changes
         AZ::Dom::DomPrefixTree<AZStd::function<Dom::Value(const Dom::Value&)>> m_onChangedCallbacks;
 
+        static constexpr AZStd::string_view InspectorOverrideManagementKey = "/O3DE/Preferences/Prefabs/EnableInspectorOverrideManagement";
+
         struct BoundContainer
         {
             AZ::SerializeContext::IDataContainer* m_container;
@@ -246,6 +249,54 @@ namespace AZ::DocumentPropertyEditor
             }
         }
 
+        void VisitValueWithSerializedPath(Reflection::IObjectAccess& access, const Reflection::IAttributes& attributes)
+        {
+            const AZ::TypeId valueType = access.GetType();
+            void* valuePointer = access.Get();
+
+            rapidjson::Document serializedValue;
+            JsonSerialization::Store(serializedValue, serializedValue.GetAllocator(), valuePointer, nullptr, valueType);
+
+            AZ::Dom::Value instancePointerValue;
+            auto outputWriter = instancePointerValue.GetWriteHandler();
+            auto convertToAzDomResult = AZ::Dom::Json::VisitRapidJsonValue(serializedValue, *outputWriter, AZ::Dom::Lifetime::Temporary);
+            VisitValue(
+                instancePointerValue,
+                access.Get(),
+                attributes,
+                [valuePointer, valueType, this](const Dom::Value& newValue)
+                {
+                    void* marshalledPointer = AZ::Dom::Utils::TryMarshalValueToPointer(newValue, valueType);
+                    rapidjson::Document serializedValue;
+                    JsonSerialization::Store(serializedValue, serializedValue.GetAllocator(), marshalledPointer, nullptr, valueType);
+
+                    JsonDeserializerSettings deserializeSettings;
+                    deserializeSettings.m_serializeContext = m_serializeContext;
+                    // now deserialize that value into the original location
+                    JsonSerialization::Load(valuePointer, valueType, serializedValue, deserializeSettings);
+
+                    AZ::Dom::Value newInstancePointerValue;
+                    auto outputWriter = newInstancePointerValue.GetWriteHandler();
+                    auto convertToAzDomResult =
+                        AZ::Dom::Json::VisitRapidJsonValue(serializedValue, *outputWriter, AZ::Dom::Lifetime::Temporary);
+                    return newInstancePointerValue;
+                },
+                false,
+                false);
+        }
+
+        bool IsInspectorOverrideManagementEnabled()
+        {
+            bool isInspectorOverrideManagementEnabled = false;
+
+            if (auto* registry = AZ::SettingsRegistry::Get())
+            {
+                registry->Get(isInspectorOverrideManagementEnabled, InspectorOverrideManagementKey);
+            }
+
+            return isInspectorOverrideManagementEnabled;
+        }
+
         template<class T>
         void VisitPrimitive(T& value, const Reflection::IAttributes& attributes)
         {
@@ -384,6 +435,10 @@ namespace AZ::DocumentPropertyEditor
 
             m_builder.BeginRow();
 
+            AZ::Reflection::AttributeDataType serializedPathAttribute =
+                attributes.Find(AZ::Reflection::DescriptorAttributes::SerializedPath);
+            m_adapter->OnBeginRow(&m_builder, serializedPathAttribute.GetString());
+
             for (const auto& attribute : Nodes::Row::RowAttributes)
             {
                 auto attributeValue = attributes.Find(attribute->GetName());
@@ -480,40 +535,55 @@ namespace AZ::DocumentPropertyEditor
                 {
                     hashValue = true;
                 }
-                VisitValue(
-                    instancePointerValue,
-                    access.Get(),
-                    attributes,
-                    // this needs to write the value back into the reflected object via Json serialization
-                    [valuePointer = access.Get(), valueType = access.GetType(), this](const Dom::Value& newValue)
-                    {
-                        // marshal this new value into a pointer for use by the Json serializer
-                        auto marshalledPointer = AZ::Dom::Utils::TryMarshalValueToPointer(newValue, valueType);
-
-                        rapidjson::Document buffer;
-                        JsonSerializerSettings serializeSettings;
-                        JsonDeserializerSettings deserializeSettings;
-                        serializeSettings.m_serializeContext = m_serializeContext;
-                        deserializeSettings.m_serializeContext = m_serializeContext;
-
-                        // serialize the new value to Json, using the original valuePointer as a reference object to generate a minimal diff
-                        JsonSerialization::Store(buffer, buffer.GetAllocator(), marshalledPointer, valuePointer, valueType, serializeSettings);
-
-                        // now deserialize that value into the original location
-                        JsonSerialization::Load(valuePointer, valueType, buffer, deserializeSettings);
-
-                        // NB: the returned value for serialized pointer values is instancePointerValue, but since this is passed by pointer,
-                        // it will not actually detect a changed dom value. Since we are already writing directly to the DOM before this step,
-                        // it won't affect the calling DPE, however, other DPEs pointed at the same adapter would be unaware of the change,
-                        // and wouldn't update their UI.
-                        // In future, to properly support multiple DPEs on one adapter, we will need to solve this. One way would be to store
-                        // the json serialized value (which is mostly human-readable text) as an attribute, so any change to the Json would
-                        // trigger an update. This would have the advantage of allowing opaque and pointer types to be searchable by the
-                        // string-based Filter adapter. Without this, things like Vector3 will not have searchable values by text. These
-                        // advantages would have to be measured against the size changes in the DOM and the time taken to populate and parse them.
-                        return newValue;
-                    },
-                    false, hashValue);
+
+                // The IsInspectorOverrideManagementEnabled() check is only temporary until the inspector override management feature set
+                // is fully developed. Since the original utils funtion is in AzToolsFramework and we can't access it from here, we are
+                // duplicating it in this class temporarily till we can do more testing and gain confidence about this new way of storing
+                // serialized values of opaque types directly in the DPE DOM.
+                if (IsInspectorOverrideManagementEnabled() && !serializedPathAttribute.GetString().empty())
+                {
+                    VisitValueWithSerializedPath(access, attributes);
+                }
+                else
+                {
+                    VisitValue(
+                        instancePointerValue,
+                        access.Get(),
+                        attributes,
+                        // this needs to write the value back into the reflected object via Json serialization
+                        [valuePointer = access.Get(), valueType = access.GetType(), this](const Dom::Value& newValue)
+                        {
+                            // marshal this new value into a pointer for use by the Json serializer
+                            auto marshalledPointer = AZ::Dom::Utils::TryMarshalValueToPointer(newValue, valueType);
+
+                            rapidjson::Document buffer;
+                            JsonSerializerSettings serializeSettings;
+                            JsonDeserializerSettings deserializeSettings;
+                            serializeSettings.m_serializeContext = m_serializeContext;
+                            deserializeSettings.m_serializeContext = m_serializeContext;
+
+                            // serialize the new value to Json, using the original valuePointer as a reference object to generate a minimal
+                            // diff
+                            JsonSerialization::Store(
+                                buffer, buffer.GetAllocator(), marshalledPointer, valuePointer, valueType, serializeSettings);
+
+                            // now deserialize that value into the original location
+                            JsonSerialization::Load(valuePointer, valueType, buffer, deserializeSettings);
+
+                            // NB: the returned value for serialized pointer values is instancePointerValue, but since this is passed by
+                            // pointer, it will not actually detect a changed dom value. Since we are already writing directly to the DOM
+                            // before this step, it won't affect the calling DPE, however, other DPEs pointed at the same adapter would be
+                            // unaware of the change, and wouldn't update their UI. In future, to properly support multiple DPEs on one
+                            // adapter, we will need to solve this. One way would be to store the json serialized value (which is mostly
+                            // human-readable text) as an attribute, so any change to the Json would trigger an update. This would have the
+                            // advantage of allowing opaque and pointer types to be searchable by the string-based Filter adapter. Without
+                            // this, things like Vector3 will not have searchable values by text. These advantages would have to be measured
+                            // against the size changes in the DOM and the time taken to populate and parse them.
+                            return newValue;
+                        },
+                        false,
+                        hashValue);
+                }
             }
         }
 
@@ -625,6 +695,10 @@ namespace AZ::DocumentPropertyEditor
         m_propertyChangeEvent.Signal(changeInfo);
     }
 
+    void ReflectionAdapter::OnBeginRow(AdapterBuilder*, AZStd::string_view)
+    {
+    }
+
     Dom::Value ReflectionAdapter::GenerateContents()
     {
         m_impl->m_builder.BeginAdapter();

+ 7 - 0
Code/Framework/AzFramework/AzFramework/DocumentPropertyEditor/ReflectionAdapter.h

@@ -8,8 +8,10 @@
 
 #pragma once
 
+#include <AzFramework/DocumentPropertyEditor/AdapterBuilder.h>
 #include <AzFramework/DocumentPropertyEditor/RoutingAdapter.h>
 #include <AzCore/Serialization/SerializeContext.h>
+#include <AzCore/std/string/string_view.h>
 
 namespace AZ::DocumentPropertyEditor
 {
@@ -60,6 +62,11 @@ namespace AZ::DocumentPropertyEditor
         //! property editor instances has altered its value.
         void NotifyPropertyChanged(const PropertyChangeInfo& changeInfo);
 
+        //! Invoked when the adapter builder builds a new row.
+        //! @param adapterBuilder The adapter builder currently being used by this adapter.
+        //! @param serializedpath The serialized path fetched from AZ::Reflection::DescriptorAttributes.
+        virtual void OnBeginRow(AdapterBuilder* adapterBuilder, AZStd::string_view serializedPath);
+
         void* GetInstance() { return m_instance; }
         const void* GetInstance() const { return m_instance; }
         AZ::TypeId GetTypeId() const { return m_typeId; }

+ 39 - 0
Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/DocumentPropertyEditor/OverridePropertyHandler.cpp

@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#include <AzToolsFramework/Prefab/DocumentPropertyEditor/OverridePropertyHandler.h>
+
+namespace AzToolsFramework::Prefab
+{
+    OverridePropertyHandler::OverridePropertyHandler()
+    {
+        setContextMenuPolicy(Qt::CustomContextMenu);
+        connect(this, &OverridePropertyHandler::customContextMenuRequested, this, &OverridePropertyHandler::ShowContextMenu);
+    }
+
+    void OverridePropertyHandler::SetValueFromDom(const AZ::Dom::Value&)
+    {
+        static QIcon s_overrideIcon(QStringLiteral(":/Entity/entity_modified_as_override.svg"));
+
+        setIcon(s_overrideIcon);
+        setIconSize(QSize(8, 8));
+    }
+
+    void OverridePropertyHandler::ShowContextMenu(const QPoint& position)
+    {
+        QMenu contextMenu;
+        QAction* revertAction = contextMenu.addAction(tr("Revert Override"));
+
+        QAction* selectedItem = contextMenu.exec(mapToGlobal(position));
+
+        if (selectedItem == revertAction)
+        {
+            // This is the place where revert override code will be added later.
+        }
+    }
+} // namespace AzToolsFramework::Prefab

+ 43 - 0
Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/DocumentPropertyEditor/OverridePropertyHandler.h

@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#pragma once
+
+#include <AzToolsFramework/Prefab/DocumentPropertyEditor/PrefabPropertyEditorNodes.h>
+#include <AzToolsFramework/UI/DocumentPropertyEditor/PropertyHandlerWidget.h>
+
+#include <QIcon>
+#include <QMenu>
+#include <QObject>
+#include <QToolButton>
+
+
+namespace AzToolsFramework::Prefab
+{
+    //! Class to handle the override property when encountered in a DPE DOM.
+    //! Responsible for setting the ui/ux for overridden properties.
+    class OverridePropertyHandler
+        : public PropertyHandlerWidget<QToolButton>
+    {
+    public:
+        OverridePropertyHandler();
+        
+        //! Specifies the behavior when override property is encountered in the DPE DOM.
+        //! @param value The value holding the overridden property in the DPE DOM
+        void SetValueFromDom(const AZ::Dom::Value& value);
+
+        static constexpr const AZStd::string_view GetHandlerName()
+        {
+            return PrefabPropertyEditorNodes::PrefabOverrideProperty::Name;
+        }
+
+    private:
+        //! Shows a custom menu when the property is clicked. Can handle operations like 'Revert', etc.
+        void ShowContextMenu(const QPoint&);
+    };
+} // namespace AzToolsFramework::Prefab

+ 55 - 0
Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/DocumentPropertyEditor/PrefabAdapter.cpp

@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#include <AzFramework/DocumentPropertyEditor/AdapterBuilder.h>
+#include <AzToolsFramework/Prefab/DocumentPropertyEditor/PrefabAdapter.h>
+#include <AzToolsFramework/Prefab/DocumentPropertyEditor/PrefabPropertyEditorNodes.h>
+#include <AzToolsFramework/Prefab/DocumentPropertyEditor/OverridePropertyHandler.h>
+#include <AzToolsFramework/Prefab/Overrides/PrefabOverridePublicInterface.h>
+#include <AzToolsFramework/UI/DocumentPropertyEditor/PropertyEditorToolsSystemInterface.h>
+
+namespace AzToolsFramework::Prefab
+{
+    PrefabAdapter::PrefabAdapter()
+    {
+        m_prefabOverridePublicInterface = AZ::Interface<AzToolsFramework::Prefab::PrefabOverridePublicInterface>::Get();
+        if (m_prefabOverridePublicInterface == nullptr)
+        {
+            AZ_Assert(false, "Could not get PrefabOverridePublicInterface on PrefabAdapter construction.");
+            return;
+        }
+
+        auto* propertyEditorToolsSystemInterface = AZ::Interface<PropertyEditorToolsSystemInterface>::Get();
+        AZ_Assert(
+            propertyEditorToolsSystemInterface != nullptr,
+            "PrefabAdapter::PrefabAdapter() - PropertyEditorToolsSystemInterface is not available");
+        propertyEditorToolsSystemInterface->RegisterHandler<OverridePropertyHandler>();
+
+        AZ::Interface<PrefabAdapterInterface>::Register(this);
+    }
+
+    PrefabAdapter::~PrefabAdapter()
+    {
+        AZ::Interface<PrefabAdapterInterface>::Unregister(this);
+    }
+
+    void PrefabAdapter::AddPropertyHandlerIfOverridden(
+        AZ::DocumentPropertyEditor::AdapterBuilder* adapterBuilder, const AZ::Dom::Path& relativePathFromEntity, AZ::EntityId entityId) 
+    {
+        if (m_prefabOverridePublicInterface->AreOverridesPresent(entityId, relativePathFromEntity.ToString()))
+        {
+            adapterBuilder->BeginPropertyEditor<PrefabPropertyEditorNodes::PrefabOverrideProperty>();
+            adapterBuilder->Attribute(AZ::DocumentPropertyEditor::Nodes::PropertyEditor::SharePriorColumn, true);
+            adapterBuilder->Attribute(AZ::DocumentPropertyEditor::Nodes::PropertyEditor::UseMinimumWidth, true);
+            adapterBuilder->Attribute(
+                AZ::DocumentPropertyEditor::Nodes::PropertyEditor::Alignment,
+                AZ::DocumentPropertyEditor::Nodes::PropertyEditor::Align::AlignLeft);
+            adapterBuilder->EndPropertyEditor();
+        }
+    }
+} // namespace AzToolsFramework::Prefab

+ 32 - 0
Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/DocumentPropertyEditor/PrefabAdapter.h

@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#pragma once
+
+#include <AzToolsFramework/Prefab/DocumentPropertyEditor/PrefabAdapterInterface.h>
+#include <AzToolsFramework/UI/DocumentPropertyEditor/DPEComponentAdapter.h>
+
+namespace AzToolsFramework::Prefab
+{
+    class PrefabOverridePublicInterface;
+
+    class PrefabAdapter
+        : public AZ::DocumentPropertyEditor::ReflectionAdapter
+        , private PrefabAdapterInterface
+    {
+    public:
+        PrefabAdapter();
+        ~PrefabAdapter();
+    private:
+        void AddPropertyHandlerIfOverridden(
+            AZ::DocumentPropertyEditor::AdapterBuilder* adapterBuilder, const AZ::Dom::Path& componentPathInEntity, AZ::EntityId entityId) override;
+
+        PrefabOverridePublicInterface* m_prefabOverridePublicInterface = nullptr;
+    };
+
+} // namespace AzToolsFramework::Prefab

+ 41 - 0
Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/DocumentPropertyEditor/PrefabAdapterInterface.h

@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#pragma once
+
+#include <AzCore/Component/EntityId.h>
+#include <AzCore/RTTI/RTTI.h>
+
+namespace AZ
+{
+    namespace DocumentPropertyEditor
+    {
+        class AdapterBuilder;
+    }
+
+    namespace Dom
+    {
+        class Path;
+    }
+}
+
+namespace AzToolsFramework::Prefab
+{
+    class PrefabAdapterInterface
+    {
+    public:
+        AZ_RTTI(PrefabAdapterInterface, "{8272C235-1642-432F-8A51-63E9B4488D55}");
+
+        //! Adds a property handler to the DPE DOM if an override is present on the entity at the provided path.
+        //! @param adapterBuilder The builder to use to add the property handler. It could have already added other things to DOM.
+        //! @param relativePathFromEntity The path as seen by the entity a component or its properties.
+        //! @param entityId The entity id to use to query the prefab system about the presence of overrides.
+        virtual void AddPropertyHandlerIfOverridden(
+            AZ::DocumentPropertyEditor::AdapterBuilder* adapterBuilder, const AZ::Dom::Path& relativePathFromEntity, AZ::EntityId entityId) = 0;
+    };
+} // namespace AzToolsFramework::Prefab

+ 19 - 0
Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/DocumentPropertyEditor/PrefabPropertyEditorNodes.h

@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#pragma once
+
+#include <AzFramework/DocumentPropertyEditor/DocumentSchema.h>
+
+namespace AzToolsFramework::Prefab::PrefabPropertyEditorNodes
+{
+    struct PrefabOverrideProperty : AZ::DocumentPropertyEditor::NodeDefinition
+    {
+        static constexpr AZStd::string_view Name = "PrefabOverrideProperty";
+    };
+} // namespace AzToolsFramework::Prefab::PrefabPropertyEditorNodes

+ 5 - 1
Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Overrides/PrefabOverridePublicHandler.cpp

@@ -51,11 +51,15 @@ namespace AzToolsFramework
             }
         }
 
-        bool PrefabOverridePublicHandler::AreOverridesPresent(AZ::EntityId entityId)
+        bool PrefabOverridePublicHandler::AreOverridesPresent(AZ::EntityId entityId, AZStd::string_view relativePathFromEntity)
         {
             AZStd::pair<AZ::Dom::Path, LinkId> pathAndLinkIdPair = GetPathAndLinkIdFromFocusedPrefab(entityId);
             if (!pathAndLinkIdPair.first.IsEmpty() && pathAndLinkIdPair.second != InvalidLinkId)
             {
+                if (!relativePathFromEntity.empty())
+                {
+                    pathAndLinkIdPair.first /= relativePathFromEntity;
+                }
                 return m_prefabOverrideHandler.AreOverridesPresent(pathAndLinkIdPair.first, pathAndLinkIdPair.second);
             }
 

+ 3 - 1
Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Overrides/PrefabOverridePublicHandler.h

@@ -31,8 +31,10 @@ namespace AzToolsFramework
             //! Checks whether overrides are present on the given entity id. Overrides can come from any ancestor prefab but
             //! this function specifically checks for overrides from the focused prefab.
             //! @param entityId The id of the entity to check for overrides.
+            //! @param relativePathFromEntity The relative path from the entity. This can be used to query about overrides on components
+            //!        and their properties
             //! @return true if overrides are present on the given entity id from the focused prefab.
-            bool AreOverridesPresent(AZ::EntityId entityId) override;
+            bool AreOverridesPresent(AZ::EntityId entityId, AZStd::string_view relativePathFromEntity = {}) override;
 
             //! Gets the override type on the given entity id. Overrides can come from any ancestor prefab but
             //! this function specifically checks for overrides from the focused prefab.

+ 4 - 1
Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Overrides/PrefabOverridePublicInterface.h

@@ -9,6 +9,7 @@
 #pragma once
 
 #include <AzCore/Component/EntityId.h>
+#include <AzCore/DOM/DomPath.h>
 #include <AzCore/RTTI/RTTI.h>
 #include <AzToolsFramework/Prefab/Overrides/PrefabOverrideTypes.h>
 
@@ -24,8 +25,10 @@ namespace AzToolsFramework
             //! Checks whether overrides are present on the given entity id. The prefab that creates the overrides is identified
             //! by the class implmenting this interface based on certain selections in the editor. eg: the prefab currently being edited.
             //! @param entityId The id of the entity to check for overrides.
+            //! @param relativePathFromEntity The relative path from the entity. This can be used to query about overrides on components
+            //!        and their properties
             //! @return true if overrides are present on the given entity id.
-            virtual bool AreOverridesPresent(AZ::EntityId entityId) = 0;
+            virtual bool AreOverridesPresent(AZ::EntityId entityId, AZStd::string_view relativePathFromEntity = {}) = 0;
 
             //! Gets the override type on the given entity id. The prefab that creates the overrides is identified
             //! by the class implmenting this interface based on certain selections in the editor. eg: the prefab currently being edited.

+ 14 - 1
Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabEditorPreferences.cpp

@@ -6,12 +6,13 @@
  *
  */
 
-#include <AzToolsFramework/Prefab/PrefabEditorPreferences.h>
 #include <AzCore/Settings/SettingsRegistry.h>
+#include <AzToolsFramework/Prefab/PrefabEditorPreferences.h>
 
 namespace AzToolsFramework::Prefab
 {
     static constexpr AZStd::string_view EnablePrefabOverridesUxKey = "/O3DE/Preferences/Prefabs/EnableOverridesUx";
+    static constexpr AZStd::string_view InspectorOverrideManagementKey = "/O3DE/Preferences/Prefabs/EnableInspectorOverrideManagement";
     static constexpr AZStd::string_view HotReloadToggleKey = "/O3DE/Preferences/Prefabs/EnableHotReloading";
 
     bool IsHotReloadingEnabled()
@@ -37,4 +38,16 @@ namespace AzToolsFramework::Prefab
         return prefabOverridesUxEnabled;
     }
 
+    bool IsInspectorOverrideManagementEnabled()
+    {
+        bool isInspectorOverrideManagementEnabled = false;
+
+        if (auto* registry = AZ::SettingsRegistry::Get())
+        {
+            registry->Get(isInspectorOverrideManagementEnabled, InspectorOverrideManagementKey);
+        }
+
+        return isInspectorOverrideManagementEnabled;
+    }
+
 } // namespace AzToolsFramework::Prefab

+ 1 - 0
Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabEditorPreferences.h

@@ -12,5 +12,6 @@ namespace AzToolsFramework::Prefab
 {
     bool IsHotReloadingEnabled();
     bool IsPrefabOverridesUxEnabled();
+    bool IsInspectorOverrideManagementEnabled();
 
 } // namespace AzToolsFramework::Prefab

+ 0 - 1
Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.cpp

@@ -18,7 +18,6 @@
 #include <AzToolsFramework/Prefab/Instance/InstanceEntityIdMapper.h>
 #include <AzToolsFramework/Prefab/Instance/InstanceSerializer.h>
 #include <AzToolsFramework/Prefab/PrefabDomUtils.h>
-#include <AzToolsFramework/Prefab/PrefabEditorPreferences.h>
 #include <AzToolsFramework/Prefab/Spawnable/EditorInfoRemover.h>
 #include <AzToolsFramework/Prefab/Spawnable/PrefabCatchmentProcessor.h>
 #include <AzToolsFramework/Prefab/Spawnable/PrefabConversionPipeline.h>

+ 10 - 0
Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/EditorComponentBase.cpp

@@ -96,5 +96,15 @@ namespace AzToolsFramework
         {
             return AzToolsFramework::IsSelected(GetEntityId());
         }
+
+        void EditorComponentBase::SetSerializedIdentifier(AZStd::string alias)
+        {
+            m_alias = alias;
+        }
+
+        AZStd::string EditorComponentBase::GetSerializedIdentifier() const
+        {
+            return m_alias;
+        }
     }
 } // namespace AzToolsFramework

+ 9 - 0
Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/EditorComponentBase.h

@@ -116,6 +116,14 @@ namespace AzToolsFramework
             virtual void Deactivate() override;
             //////////////////////////////////////////////////////////////////////////
 
+            //! Sets the provided string as the serialized identifier for the component.
+            //! @param serializedIdentifer The unique identifier for this component within the entity it lives in.
+            void SetSerializedIdentifier(AZStd::string serializedIdentifier) override;
+
+            //! Gets the serialzied identifier of this component within an entity.
+            //! @return The serialized identifier of this component.
+            AZStd::string GetSerializedIdentifier() const override;
+
             /**
              * Gets the transform interface of the entity that the component
              * belongs to, if the entity has a transform component.
@@ -190,6 +198,7 @@ namespace AzToolsFramework
             static void Reflect(AZ::ReflectContext* context);
 
         private:
+            AZStd::string m_alias;
             AZ::TransformInterface* m_transform;
         };
 

+ 24 - 6
Code/Framework/AzToolsFramework/AzToolsFramework/UI/DocumentPropertyEditor/DPEComponentAdapter.cpp

@@ -6,10 +6,13 @@
  *
  */
 
+#include <AzCore/DOM/Backends/JSON/JsonSerializationUtils.h>
+#include <AzFramework/DocumentPropertyEditor/AdapterBuilder.h>
 #include <AzToolsFramework/UI/DocumentPropertyEditor/DPEComponentAdapter.h>
-
+#include <AzToolsFramework/Prefab/DocumentPropertyEditor/PrefabAdapterInterface.h>
+#include <AzToolsFramework/Prefab/PrefabDomUtils.h>
+#include <AzToolsFramework/Prefab/PrefabFocusPublicInterface.h>
 #include <QtCore/QTimer>
-
 namespace AZ::DocumentPropertyEditor
 {
     ComponentAdapter::ComponentAdapter() = default;
@@ -71,11 +74,13 @@ namespace AZ::DocumentPropertyEditor
     void ComponentAdapter::SetComponent(AZ::Component* componentInstance)
     {
         m_componentInstance = componentInstance;
-        AzToolsFramework::PropertyEditorEntityChangeNotificationBus::MultiHandler::BusConnect(m_componentInstance->GetEntityId());
+        m_entityId = m_componentInstance->GetEntityId();
+        AzToolsFramework::PropertyEditorEntityChangeNotificationBus::MultiHandler::BusConnect(m_entityId);
         AzToolsFramework::ToolsApplicationEvents::Bus::Handler::BusConnect();
         AzToolsFramework::PropertyEditorGUIMessages::Bus::Handler::BusConnect();
         AZ::Uuid instanceTypeId = azrtti_typeid(m_componentInstance);
         SetValue(m_componentInstance, instanceTypeId);
+        m_componentAlias = componentInstance->GetSerializedIdentifier();
     }
 
     void ComponentAdapter::DoRefresh()
@@ -111,9 +116,7 @@ namespace AZ::DocumentPropertyEditor
                         else
                         {
                             AzToolsFramework::ToolsApplicationRequests::Bus::BroadcastResult(
-                                m_currentUndoNode,
-                                &AzToolsFramework::ToolsApplicationRequests::BeginUndoBatch,
-                                "Modify Entity Property");
+                                m_currentUndoNode, &AzToolsFramework::ToolsApplicationRequests::BeginUndoBatch, "Modify Entity Property");
                         }
 
                         AzToolsFramework::ToolsApplicationRequests::Bus::Broadcast(
@@ -138,4 +141,19 @@ namespace AZ::DocumentPropertyEditor
         return returnValue;
     }
 
+    void ComponentAdapter::OnBeginRow(AdapterBuilder* adapterBuilder, AZStd::string_view serializedPath)
+    {
+        if (!serializedPath.empty())
+        {
+            AZ::Dom::Path relativePathFromEntity(AzToolsFramework::Prefab::PrefabDomUtils::ComponentsName);
+            relativePathFromEntity /= m_componentAlias;
+            relativePathFromEntity /= AZ::Dom::Path(serializedPath);
+
+            auto* prefabAdapterInterface = AZ::Interface<AzToolsFramework::Prefab::PrefabAdapterInterface>::Get();
+            if (prefabAdapterInterface != nullptr)
+            {
+                prefabAdapterInterface->AddPropertyHandlerIfOverridden(adapterBuilder, relativePathFromEntity, m_entityId);
+            }
+        }
+    }
 } // namespace AZ::DocumentPropertyEditor

+ 12 - 0
Code/Framework/AzToolsFramework/AzToolsFramework/UI/DocumentPropertyEditor/DPEComponentAdapter.h

@@ -15,6 +15,8 @@
 
 namespace AZ::DocumentPropertyEditor
 {
+    class AdapterBuilder;
+
     //! ComponentAdapter is responsible to listening for signals that affect each component in the Entity Inspector
     class ComponentAdapter
         : public ReflectionAdapter
@@ -23,6 +25,7 @@ namespace AZ::DocumentPropertyEditor
         , private AzToolsFramework::PropertyEditorGUIMessages::Bus::Handler
     {
     public:
+
         //! Creates an uninitialized (empty) ComponentAdapter.
         ComponentAdapter();
         //! Creates a ComponentAdapter with a specific component instance, see SetComponent
@@ -46,7 +49,16 @@ namespace AZ::DocumentPropertyEditor
 
         Dom::Value HandleMessage(const AdapterMessage& message) override;
 
+        //! Request the PrefabAdapterInterface to add a property handler if an override is present corresponding to the path provided.
+        //! @param adapterBuilder The adapter builder to use for adding property handler
+        //! @param serializedpath The serialized path to use to check whether an override is present corresponding to it
+        void OnBeginRow(AdapterBuilder* adapterBuilder, AZStd::string_view serializedPath) override;
+
     protected:
+
+        AZStd::string m_componentAlias;
+        AZ::EntityId m_entityId;
+
         AZ::Component* m_componentInstance = nullptr;
 
         AzToolsFramework::UndoSystem::URSequencePoint* m_currentUndoNode = nullptr;

+ 6 - 0
Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/EntityPropertyEditor.cpp

@@ -52,6 +52,7 @@ AZ_POP_DISABLE_WARNING
 #include <AzToolsFramework/Entity/EditorEntityHelpers.h>
 #include <AzToolsFramework/Entity/ReadOnly/ReadOnlyEntityInterface.h>
 #include <AzToolsFramework/Prefab/PrefabFocusPublicInterface.h>
+#include <AzToolsFramework/Prefab/PrefabEditorPreferences.h>
 #include <AzToolsFramework/Prefab/PrefabPublicInterface.h>
 #include <AzToolsFramework/Prefab/Instance/InstanceUpdateExecutorInterface.h>
 #include <AzToolsFramework/Slice/SliceDataFlagsCommand.h>
@@ -503,6 +504,11 @@ namespace AzToolsFramework
     {
         initEntityPropertyEditorResources();
 
+        if (Prefab::IsInspectorOverrideManagementEnabled())
+        {
+            m_prefabAdapter = AZStd::make_unique<Prefab::PrefabAdapter>();
+        }
+
         m_prefabPublicInterface = AZ::Interface<Prefab::PrefabPublicInterface>::Get();
         AZ_Assert(m_prefabPublicInterface != nullptr, "EntityPropertyEditor requires a PrefabPublicInterface instance on Initialize.");
 

+ 3 - 0
Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/EntityPropertyEditor.hxx

@@ -32,6 +32,7 @@
 #include <AzToolsFramework/Entity/EditorEntityContextBus.h>
 #include <AzToolsFramework/Entity/ReadOnly/ReadOnlyEntityBus.h>
 #include <AzToolsFramework/FocusMode/FocusModeNotificationBus.h>
+#include <AzToolsFramework/Prefab/DocumentPropertyEditor/PrefabAdapter.h>
 #include <AzToolsFramework/ToolsComponents/ComponentMimeData.h>
 #include <AzToolsFramework/ToolsComponents/EditorInspectorComponentBus.h>
 #include <AzQtComponents/Components/O3DEStylesheet.h>
@@ -640,6 +641,8 @@ namespace AzToolsFramework
         QStandardItem* m_comboItems[StatusItems];
         EntityIdSet m_overrideSelectedEntityIds;
 
+        // An adapter that works in conjuction with the DPE system as a manager for all prefab related operations in a DPE DOM.
+        AZStd::unique_ptr<Prefab::PrefabAdapter> m_prefabAdapter;
         Prefab::PrefabPublicInterface* m_prefabPublicInterface = nullptr;
         Prefab::InstanceUpdateExecutorInterface* m_instanceUpdateExecutorInterface = nullptr;
         bool m_prefabsAreEnabled = false;

+ 16 - 1
Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyEditorAPI_Internals.h

@@ -5,6 +5,7 @@
  * SPDX-License-Identifier: Apache-2.0 OR MIT
  *
  */
+
 #ifndef PROPERTYEDITORAPI_INTERNALS_H
 #define PROPERTYEDITORAPI_INTERNALS_H
 
@@ -16,10 +17,12 @@
 // and implement that interface, then register it with the property manager.
 
 #include <AzCore/Debug/Profiler.h>
+#include <AzCore/DOM/DomUtils.h>
 #include <AzCore/EBus/EBus.h>
 #include <AzCore/RTTI/AttributeReader.h>
 #include <AzCore/Serialization/EditContext.h>
 #include <AzFramework/DocumentPropertyEditor/ReflectionAdapter.h>
+#include <AzToolsFramework/Prefab/PrefabEditorPreferences.h>
 #include <AzToolsFramework/UI/DocumentPropertyEditor/PropertyEditorToolsSystemInterface.h>
 #include <AzToolsFramework/UI/PropertyEditor/InstanceDataHierarchy.h>
 #include <AzCore/Asset/AssetSerializer.h>
@@ -265,7 +268,19 @@ namespace AzToolsFramework
             auto value = AZ::DocumentPropertyEditor::Nodes::PropertyEditor::Value.ExtractFromDomNode(node);
             if (value.has_value())
             {
-                m_proxyValue = AZ::Dom::Utils::ValueToType<WrappedType>(value.value()).value_or(m_proxyValue);
+                if (!Prefab::IsInspectorOverrideManagementEnabled())
+                {
+                    m_proxyValue = AZ::Dom::Utils::ValueToType<WrappedType>(value.value()).value_or(m_proxyValue);
+                }
+                else
+                {
+                    AZ::JsonSerializationResult::ResultCode loadResult =
+                        AZ::Dom::Utils::LoadViaJsonSerialization(m_proxyValue, value.value());
+                    if (loadResult.GetProcessing() == AZ::JsonSerializationResult::Processing::Halted)
+                    {
+                        m_proxyValue = AZ::Dom::Utils::ValueToType<WrappedType>(value.value()).value_or(m_proxyValue);
+                    }
+                }
             }
 
             m_rpeHandler.ConsumeAttributes_Internal(GetWidget(), &m_proxyNode);

+ 8 - 2
Code/Framework/AzToolsFramework/AzToolsFramework/aztoolsframework_files.cmake

@@ -780,13 +780,19 @@ set(FILES
     UI/PropertyEditor/Model/AssetCompleterModel.cpp
     UI/PropertyEditor/View/AssetCompleterListView.h
     UI/PropertyEditor/View/AssetCompleterListView.cpp
+    Prefab/DocumentPropertyEditor/OverridePropertyHandler.h
+    Prefab/DocumentPropertyEditor/OverridePropertyHandler.cpp
+    Prefab/DocumentPropertyEditor/PrefabAdapter.h
+    Prefab/DocumentPropertyEditor/PrefabAdapter.cpp
+    Prefab/DocumentPropertyEditor/PrefabAdapterInterface.h
+    Prefab/DocumentPropertyEditor/PrefabPropertyEditorNodes.h
     Prefab/EditorPrefabComponent.h
     Prefab/EditorPrefabComponent.cpp
+    Prefab/PrefabEditorPreferences.h
+    Prefab/PrefabEditorPreferences.cpp
     Prefab/PrefabDomTypes.h
     Prefab/PrefabDomUtils.h
     Prefab/PrefabDomUtils.cpp
-    Prefab/PrefabEditorPreferences.h
-    Prefab/PrefabEditorPreferences.cpp
     Prefab/PrefabFocusHandler.h
     Prefab/PrefabFocusHandler.cpp
     Prefab/PrefabFocusInterface.h

+ 1 - 1
Registry/o3de.editor.setreg

@@ -1,4 +1,4 @@
- {
+{
     "O3DE": {
         "Autoexec": {
             "ConsoleCommands": {