From cee4ca8067f6c69ceb993e4eeec1e5405e203285 Mon Sep 17 00:00:00 2001 From: greerdv Date: Fri, 30 Apr 2021 12:37:12 +0100 Subject: [PATCH 01/10] WIP adding button to transform component to add non-uniform scale component --- .../ToolsComponents/TransformComponent.cpp | 73 +++++++++++++++++++ .../ToolsComponents/TransformComponent.h | 13 ++++ 2 files changed, 86 insertions(+) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/TransformComponent.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/TransformComponent.cpp index dcced5b705..7d8b802622 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/TransformComponent.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/TransformComponent.cpp @@ -25,11 +25,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include @@ -37,10 +39,29 @@ #include +#pragma optimize("", off) + namespace AzToolsFramework { namespace Components { + void AddNonUniformScaleButton::Reflect(AZ::ReflectContext* context) + { + if (AZ::SerializeContext* serializeContext = azrtti_cast(context)) + { + serializeContext->Class()-> + Version(1); + + if (AZ::EditContext* ptrEdit = serializeContext->GetEditContext()) + { + ptrEdit->Class("AddNonUniformScaleButton", "")-> + UIElement(AZ::Edit::UIHandlers::Button, "", "Add non-uniform scale component")-> + Attribute(AZ::Edit::Attributes::ButtonText, "Add non-uniform scale") + ; + } + } + } + namespace Internal { const AZ::u32 ParentEntityCRC = AZ_CRC("Parent Entity", 0x5b1b276c); @@ -1196,8 +1217,55 @@ namespace AzToolsFramework destinationComponent->SetWorldTM(const_cast(sourceComponent)->GetWorldTM()); } + AZ::Crc32 TransformComponent::OnAddNonUniformScaleButtonPressed() + { + // if there is already a non-uniform scale component, do nothing + if (GetEntity()->FindComponent()) + { + return AZ::Edit::PropertyRefreshLevels::None; + } + + const AZStd::vector entityList = { GetEntityId() }; + const AZ::ComponentTypeList componentsToAdd = { EditorNonUniformScaleComponent::TYPEINFO_Uuid() }; + + AzToolsFramework::EntityCompositionRequests::AddComponentsOutcome outcome; + AzToolsFramework::EntityCompositionRequestBus::BroadcastResult(outcome, + &AzToolsFramework::EntityCompositionRequests::AddComponentsToEntities, entityList, componentsToAdd); + + auto nonUniformScaleComponent = GetEntity()->FindComponent(); + + if (!outcome.IsSuccess() || nonUniformScaleComponent == nullptr) + { + AZ_Warning("Transform component", false, "Failed to add non-uniform scale component."); + return AZ::Edit::PropertyRefreshLevels::None; + } + + AzToolsFramework::ToolsApplicationEvents::Bus::Broadcast( + &AzToolsFramework::ToolsApplicationEvents::Bus::Events::InvalidatePropertyDisplay, AzToolsFramework::Refresh_EntireTree); + + ComponentOrderArray componentOrderArray; + EditorInspectorComponentRequestBus::EventResult(componentOrderArray, GetEntityId(), + &EditorInspectorComponentRequests::GetComponentOrderArray); + + // find the id for the non-uniform scale component and move it immediately after the transform component in the sort order + auto nonUniformScaleComponentIter = AZStd::find(componentOrderArray.begin(), componentOrderArray.end(), nonUniformScaleComponent->GetId()); + auto transformComponentIter = AZStd::find(componentOrderArray.begin(), componentOrderArray.end(), GetId()); + if (nonUniformScaleComponentIter != componentOrderArray.end() && transformComponentIter != componentOrderArray.end()) + { + componentOrderArray.erase(nonUniformScaleComponentIter); + transformComponentIter = AZStd::find(componentOrderArray.begin(), componentOrderArray.end(), GetId()); + componentOrderArray.insert(++transformComponentIter, nonUniformScaleComponent->GetId()); + EditorInspectorComponentRequestBus::Event(GetEntityId(), + &EditorInspectorComponentRequests::SetComponentOrderArray, componentOrderArray); + } + + return AZ::Edit::PropertyRefreshLevels::EntireTree; + } + void TransformComponent::Reflect(AZ::ReflectContext* context) { + AddNonUniformScaleButton::Reflect(context); + // reflect data for script, serialization, editing.. if (AZ::SerializeContext* serializeContext = azrtti_cast(context)) { @@ -1211,6 +1279,7 @@ namespace AzToolsFramework serializeContext->Class()-> Field("Parent Entity", &TransformComponent::m_parentEntityId)-> Field("Transform Data", &TransformComponent::m_editorTransform)-> + Field("AddNonUniformScaleButton", &TransformComponent::m_addNonUniformScaleButton)-> Field("Cached World Transform", &TransformComponent::m_cachedWorldTransform)-> Field("Cached World Transform Parent", &TransformComponent::m_cachedWorldTransformParent)-> Field("Parent Activation Transform Mode", &TransformComponent::m_parentActivationTransformMode)-> @@ -1234,6 +1303,10 @@ namespace AzToolsFramework DataElement(AZ::Edit::UIHandlers::Default, &TransformComponent::m_editorTransform, "Values", "")-> Attribute(AZ::Edit::Attributes::ChangeNotify, &TransformComponent::TransformChanged)-> Attribute(AZ::Edit::Attributes::AutoExpand, true)-> + DataElement(AZ::Edit::UIHandlers::Default, &TransformComponent::m_addNonUniformScaleButton, "", "")-> + Attribute(AZ::Edit::Attributes::AutoExpand, true)-> + Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly)-> + Attribute(AZ::Edit::Attributes::ChangeNotify, &TransformComponent::OnAddNonUniformScaleButtonPressed)-> DataElement(AZ::Edit::UIHandlers::ComboBox, &TransformComponent::m_parentActivationTransformMode, "Parent activation", "Configures relative transform behavior when parent activates.")-> EnumAttribute(AZ::TransformConfig::ParentActivationTransformMode::MaintainOriginalRelativeTransform, "Original relative transform")-> diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/TransformComponent.h b/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/TransformComponent.h index 8327c5f128..dd8c7b8693 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/TransformComponent.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/TransformComponent.h @@ -23,6 +23,7 @@ #include #include #include +#include #include "EditorComponentBase.h" #include "TransformComponentBus.h" @@ -31,6 +32,15 @@ namespace AzToolsFramework { namespace Components { + class AddNonUniformScaleButton + { + public: + AZ_TYPE_INFO(AddNonUniformScaleButton, "{92ECB8B6-DD25-4FC0-A5EE-4CEBAF51A780}") + static void Reflect(AZ::ReflectContext* context); + private: + void OnAddNonUniformScaleButtonPressed() {}; + }; + /// Manages transform data as separate vector fields for editing purposes. /// The TransformComponent is referenced by other components in the same entity, it is not an asset. class TransformComponent @@ -228,6 +238,8 @@ namespace AzToolsFramework void CheckApplyCachedWorldTransform(const AZ::Transform& parentWorld); + AZ::Crc32 OnAddNonUniformScaleButtonPressed(); + // Drives transform behavior when parent activates. See AZ::TransformConfig::ParentActivationTransformMode for details. AZ::TransformConfig::ParentActivationTransformMode m_parentActivationTransformMode; @@ -259,6 +271,7 @@ namespace AzToolsFramework bool m_localTransformDirty = true; bool m_worldTransformDirty = true; bool m_isStatic = false; + AddNonUniformScaleButton m_addNonUniformScaleButton; // Deprecated AZ::InterpolationMode m_interpolatePosition; From d9b3b7ccfaae7bdb976f19cb786d09f81fa5170e Mon Sep 17 00:00:00 2001 From: greerdv Date: Tue, 4 May 2021 18:31:43 +0100 Subject: [PATCH 02/10] adding non-uniform scale component via button on transform component and forcing it to be adjacent in the component sort order and visible --- .../Serialization/EditContextConstants.inl | 3 + .../Components/NonUniformScaleComponent.cpp | 2 + .../API/EntityPropertyEditorRequestsBus.h | 4 + .../EditorNonUniformScaleComponent.cpp | 7 +- .../ToolsComponents/TransformComponent.cpp | 39 ++++----- .../PropertyEditor/EntityPropertyEditor.cpp | 84 +++++++++++++++++-- .../PropertyEditor/EntityPropertyEditor.hxx | 6 ++ 7 files changed, 113 insertions(+), 32 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/Serialization/EditContextConstants.inl b/Code/Framework/AzCore/AzCore/Serialization/EditContextConstants.inl index 90b9ba5afd..454d998321 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/EditContextConstants.inl +++ b/Code/Framework/AzCore/AzCore/Serialization/EditContextConstants.inl @@ -53,6 +53,9 @@ namespace AZ //! RemoveableByUser : A bool which determines if the component can be removed by the user. //! Setting this to false prevents the user from removing this component. Default behavior is removeable by user. const static AZ::Crc32 RemoveableByUser = AZ_CRC("RemoveableByUser", 0x32c7fd50); + //! A bool which determines if the component can be dragged to change where it appears in the entity sort order. + //! Setting this to false prevents the user from dragging the component. Default behaviour is draggable by user. + const static AZ::Crc32 DraggableByUser = AZ_CRC_CE("DraggableByUser"); const static AZ::Crc32 AppearsInAddComponentMenu = AZ_CRC("AppearsInAddComponentMenu", 0x53790e31); const static AZ::Crc32 ForceAutoExpand = AZ_CRC("ForceAutoExpand", 0x1a5c79d2); // Ignores expansion state set by user, enforces expansion. const static AZ::Crc32 AutoExpand = AZ_CRC("AutoExpand", 0x306ff5c0); // Expands automatically unless user changes expansion state. diff --git a/Code/Framework/AzFramework/AzFramework/Components/NonUniformScaleComponent.cpp b/Code/Framework/AzFramework/AzFramework/Components/NonUniformScaleComponent.cpp index 095d986fa1..57f14ddb38 100644 --- a/Code/Framework/AzFramework/AzFramework/Components/NonUniformScaleComponent.cpp +++ b/Code/Framework/AzFramework/AzFramework/Components/NonUniformScaleComponent.cpp @@ -36,6 +36,8 @@ namespace AzFramework void NonUniformScaleComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) { + incompatible.push_back(AZ_CRC_CE("NonUniformScaleService")); + incompatible.push_back(AZ_CRC_CE("DebugDrawObbService")); incompatible.push_back(AZ_CRC_CE("DebugDrawService")); incompatible.push_back(AZ_CRC_CE("EMotionFXActorService")); diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/API/EntityPropertyEditorRequestsBus.h b/Code/Framework/AzToolsFramework/AzToolsFramework/API/EntityPropertyEditorRequestsBus.h index 35b2e485b5..1959183fa0 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/API/EntityPropertyEditorRequestsBus.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/API/EntityPropertyEditorRequestsBus.h @@ -31,6 +31,10 @@ namespace AzToolsFramework //! Allows a component to get the list of selected entities //! \param selectedEntityIds the return vector holding the entities required virtual void GetSelectedEntities(EntityIdList& selectedEntityIds) = 0; + + //! Explicitly sets a component as having been the most recently added. + //! This means that the next time the UI refreshes, that component will be ensured to be visible. + virtual void SetNewComponentId(AZ::ComponentId componentId) = 0; }; using EntityPropertyEditorRequestBus = AZ::EBus; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/EditorNonUniformScaleComponent.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/EditorNonUniformScaleComponent.cpp index 5e928a382a..d28f23c847 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/EditorNonUniformScaleComponent.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/EditorNonUniformScaleComponent.cpp @@ -39,9 +39,8 @@ namespace AzToolsFramework editContext->Class("Non-uniform Scale", "Non-uniform scale for this entity only (does not propagate through hierarchy)") ->ClassElement(AZ::Edit::ClassElements::EditorData, "") - ->Attribute(AZ::Edit::Attributes::Category, "Non-uniform Scale") - ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC_CE("Game")) - ->Attribute(AZ::Edit::Attributes::AutoExpand, true) + ->Attribute(AZ::Edit::Attributes::RemoveableByUser, true) + ->Attribute(AZ::Edit::Attributes::DraggableByUser, false) ->DataElement( AZ::Edit::UIHandlers::Default, &EditorNonUniformScaleComponent::m_scale, "Non-uniform Scale", "Non-uniform scale for this entity only (does not propagate through hierarchy)") @@ -61,6 +60,8 @@ namespace AzToolsFramework void EditorNonUniformScaleComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) { + incompatible.push_back(AZ_CRC_CE("NonUniformScaleService")); + incompatible.push_back(AZ_CRC_CE("DebugDrawObbService")); incompatible.push_back(AZ_CRC_CE("DebugDrawService")); incompatible.push_back(AZ_CRC_CE("EMotionFXActorService")); diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/TransformComponent.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/TransformComponent.cpp index 7d8b802622..a025c02c32 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/TransformComponent.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/TransformComponent.cpp @@ -26,12 +26,14 @@ #include #include #include +#include #include #include #include #include #include #include +#include #include #include @@ -39,8 +41,6 @@ #include -#pragma optimize("", off) - namespace AzToolsFramework { namespace Components @@ -1232,33 +1232,28 @@ namespace AzToolsFramework AzToolsFramework::EntityCompositionRequestBus::BroadcastResult(outcome, &AzToolsFramework::EntityCompositionRequests::AddComponentsToEntities, entityList, componentsToAdd); - auto nonUniformScaleComponent = GetEntity()->FindComponent(); + AZStd::vector pendingComponents; + AzToolsFramework::EditorPendingCompositionRequestBus::Event(GetEntityId(), + &AzToolsFramework::EditorPendingCompositionRequests::GetPendingComponents, pendingComponents); - if (!outcome.IsSuccess() || nonUniformScaleComponent == nullptr) + AZ::ComponentId nonUniformScaleComponentId = AZ::InvalidComponentId; + for (const auto pendingComponent : pendingComponents) { - AZ_Warning("Transform component", false, "Failed to add non-uniform scale component."); - return AZ::Edit::PropertyRefreshLevels::None; + if (pendingComponent->RTTI_IsTypeOf(AzToolsFramework::Components::EditorNonUniformScaleComponent::RTTI_Type())) + { + nonUniformScaleComponentId = pendingComponent->GetId(); + } } - AzToolsFramework::ToolsApplicationEvents::Bus::Broadcast( - &AzToolsFramework::ToolsApplicationEvents::Bus::Events::InvalidatePropertyDisplay, AzToolsFramework::Refresh_EntireTree); - - ComponentOrderArray componentOrderArray; - EditorInspectorComponentRequestBus::EventResult(componentOrderArray, GetEntityId(), - &EditorInspectorComponentRequests::GetComponentOrderArray); - - // find the id for the non-uniform scale component and move it immediately after the transform component in the sort order - auto nonUniformScaleComponentIter = AZStd::find(componentOrderArray.begin(), componentOrderArray.end(), nonUniformScaleComponent->GetId()); - auto transformComponentIter = AZStd::find(componentOrderArray.begin(), componentOrderArray.end(), GetId()); - if (nonUniformScaleComponentIter != componentOrderArray.end() && transformComponentIter != componentOrderArray.end()) + if (!outcome.IsSuccess() || nonUniformScaleComponentId == AZ::InvalidComponentId) { - componentOrderArray.erase(nonUniformScaleComponentIter); - transformComponentIter = AZStd::find(componentOrderArray.begin(), componentOrderArray.end(), GetId()); - componentOrderArray.insert(++transformComponentIter, nonUniformScaleComponent->GetId()); - EditorInspectorComponentRequestBus::Event(GetEntityId(), - &EditorInspectorComponentRequests::SetComponentOrderArray, componentOrderArray); + AZ_Warning("Transform component", false, "Failed to add non-uniform scale component."); + return AZ::Edit::PropertyRefreshLevels::None; } + AzToolsFramework::EntityPropertyEditorRequestBus::Broadcast( + &AzToolsFramework::EntityPropertyEditorRequests::SetNewComponentId, nonUniformScaleComponentId); + return AZ::Edit::PropertyRefreshLevels::EntireTree; } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/EntityPropertyEditor.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/EntityPropertyEditor.cpp index 181f5b9a9d..0fdd55f24e 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/EntityPropertyEditor.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/EntityPropertyEditor.cpp @@ -63,6 +63,7 @@ AZ_POP_DISABLE_WARNING #include #include #include +#include #include #include #include @@ -494,6 +495,11 @@ namespace AzToolsFramework } } + void EntityPropertyEditor::SetNewComponentId(AZ::ComponentId componentId) + { + m_newComponentId = componentId; + } + void EntityPropertyEditor::SetOverrideEntityIds(const AzToolsFramework::EntityIdSet& entities) { m_overrideSelectedEntityIds = entities; @@ -1052,6 +1058,19 @@ namespace AzToolsFramework return false; } + // If component 1 is a non-uniform scale component, it is sorted earlier (it should appear immediately after transform) + if (component1.m_component->RTTI_IsTypeOf(AzToolsFramework::Components::EditorNonUniformScaleComponent::RTTI_Type())) + { + return true; + } + + // If component 2 is a non-uniform scale component, component 1 is never sorted earlier + // (transform will already dominate in the check above) + if (component2.m_component->RTTI_IsTypeOf(AzToolsFramework::Components::EditorNonUniformScaleComponent::RTTI_Type())) + { + return false; + } + if (!IsComponentRemovable(component1.m_component) && IsComponentRemovable(component2.m_component)) { return true; @@ -1128,10 +1147,7 @@ namespace AzToolsFramework { if (auto attributeData = azdynamic_cast*>(attribute)) { - if (!attributeData->Get(nullptr)) - { - return false; - } + return attributeData->Get(nullptr); } } } @@ -1166,6 +1182,34 @@ namespace AzToolsFramework return true; } + bool EntityPropertyEditor::IsComponentDraggable(const AZ::Component* component) + { + auto componentClassData = component ? GetComponentClassData(component) : nullptr; + if (componentClassData && componentClassData->m_editData) + { + if (auto editorDataElement = componentClassData->m_editData->FindElementData(AZ::Edit::ClassElements::EditorData)) + { + if (auto attribute = editorDataElement->FindAttribute(AZ::Edit::Attributes::DraggableByUser)) + { + if (auto attributeData = azdynamic_cast*>(attribute)) + { + if (!attributeData->Get(nullptr)) + { + return false; + } + } + } + } + } + + return true; + } + + bool EntityPropertyEditor::AreComponentsDraggable(const AZ::Entity::ComponentArrayType& components) const + { + return AZStd::all_of(components.begin(), components.end(), [](AZ::Component* component) {return IsComponentDraggable(component); }); + } + bool EntityPropertyEditor::AreComponentsCopyable(const AZ::Entity::ComponentArrayType& components) const { return AreComponentsCopyable(components, m_componentFilter); @@ -3367,7 +3411,9 @@ namespace AzToolsFramework sourceComponents.size() == m_selectedEntityIds.size() && targetComponents.size() == m_selectedEntityIds.size() && AreComponentsRemovable(sourceComponents) && - AreComponentsRemovable(targetComponents); + AreComponentsRemovable(targetComponents) && + AreComponentsDraggable(sourceComponents) && + AreComponentsDraggable(targetComponents); } bool EntityPropertyEditor::IsMoveComponentsUpAllowed() const @@ -3681,14 +3727,38 @@ namespace AzToolsFramework void EntityPropertyEditor::ScrollToNewComponent() { - //force new components to be visible, assuming they are added to the end of the list and layout - auto componentEditor = GetComponentEditorsFromIndex(m_componentEditorsUsed - 1); + // force new components to be visible + // if no component has been explicitly set at the most recently added, + // assume new components are added to the end of the list and layout + AZ::s32 newComponentIndex = m_componentEditorsUsed - 1; + + // if there is a component id explicitly set as the most recently added, try to find it and make sure it is visible + if (m_newComponentId.has_value()) + { + AZ::ComponentId newComponentId = m_newComponentId.value(); + for (AZ::s32 componentIndex = 0; componentIndex < m_componentEditorsUsed; ++componentIndex) + { + if (m_componentEditors[componentIndex]) + { + for (const auto component : m_componentEditors[componentIndex]->GetComponents()) + { + if (component->GetId() == newComponentId) + { + newComponentIndex = componentIndex; + } + } + } + } + } + + auto componentEditor = GetComponentEditorsFromIndex(newComponentIndex); if (componentEditor) { m_gui->m_componentList->ensureWidgetVisible(componentEditor); } m_shouldScrollToNewComponents = false; m_shouldScrollToNewComponentsQueued = false; + m_newComponentId.reset(); } void EntityPropertyEditor::QueueScrollToNewComponent() diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/EntityPropertyEditor.hxx b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/EntityPropertyEditor.hxx index 677dc98277..2fb1c7e03a 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/EntityPropertyEditor.hxx +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/EntityPropertyEditor.hxx @@ -211,6 +211,7 @@ namespace AzToolsFramework // EntityPropertEditorRequestBus void GetSelectedAndPinnedEntities(EntityIdList& selectedEntityIds) override; void GetSelectedEntities(EntityIdList& selectedEntityIds) override; + void SetNewComponentId(AZ::ComponentId componentId) override; bool IsEntitySelected(const AZ::EntityId& id) const; bool IsSingleEntitySelected(const AZ::EntityId& id) const; @@ -237,6 +238,8 @@ namespace AzToolsFramework static bool DoesComponentPassFilter(const AZ::Component* component, const ComponentFilter& filter); static bool IsComponentRemovable(const AZ::Component* component); bool AreComponentsRemovable(const AZ::Entity::ComponentArrayType& components) const; + static bool IsComponentDraggable(const AZ::Component* component); + bool AreComponentsDraggable(const AZ::Entity::ComponentArrayType& components) const; bool AreComponentsCopyable(const AZ::Entity::ComponentArrayType& components) const; void AddMenuOptionsForComponents(QMenu& menu, const QPoint& position); @@ -568,6 +571,9 @@ namespace AzToolsFramework void ConnectToEntityBuses(const AZ::EntityId& entityId); void DisconnectFromEntityBuses(const AZ::EntityId& entityId); + //! Stores a component id to be focused on next time the UI updates. + AZStd::optional m_newComponentId; + private slots: void OnPropertyRefreshRequired(); // refresh is needed for a property. void UpdateContents(); From 5e94c9c838a66b4b8bf59187f36bb2595174f4f7 Mon Sep 17 00:00:00 2001 From: greerdv Date: Tue, 4 May 2021 18:59:04 +0100 Subject: [PATCH 03/10] fixing highlighting behaviour when trying to drag components above non-uniform scale component --- .../UI/PropertyEditor/EntityPropertyEditor.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/EntityPropertyEditor.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/EntityPropertyEditor.cpp index 0fdd55f24e..51d4ed5026 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/EntityPropertyEditor.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/EntityPropertyEditor.cpp @@ -4143,7 +4143,8 @@ namespace AzToolsFramework { if (!componentEditor || !componentEditor->isVisible() || - !AreComponentsRemovable(componentEditor->GetComponents())) + !AreComponentsRemovable(componentEditor->GetComponents()) || + !AreComponentsDraggable(componentEditor->GetComponents())) { return false; } @@ -4293,6 +4294,7 @@ namespace AzToolsFramework while (targetComponentEditor && (targetComponentEditor->IsDragged() || !AreComponentsRemovable(targetComponentEditor->GetComponents()) + || !AreComponentsDraggable(targetComponentEditor->GetComponents()) || (globalRect.center().y() > GetWidgetGlobalRect(targetComponentEditor).center().y()))) { if (targetItr == m_componentEditors.end() || targetComponentEditor == m_componentEditors.back() || !targetComponentEditor->isVisible()) From cd93df4ca80ec35344d281c253e97528bc897f8a Mon Sep 17 00:00:00 2001 From: greerdv Date: Tue, 4 May 2021 23:15:51 +0100 Subject: [PATCH 04/10] hiding button to add non-uniform scale when there already is a NUS component on the entity --- .../ToolsComponents/TransformComponent.cpp | 53 +++++++++++++++---- .../ToolsComponents/TransformComponent.h | 4 +- 2 files changed, 44 insertions(+), 13 deletions(-) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/TransformComponent.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/TransformComponent.cpp index a025c02c32..e20c114b20 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/TransformComponent.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/TransformComponent.cpp @@ -1217,10 +1217,47 @@ namespace AzToolsFramework destinationComponent->SetWorldTM(const_cast(sourceComponent)->GetWorldTM()); } + AZ::Component* TransformComponent::FindPresentOrPendingComponent(AZ::Uuid componentUuid) + { + // first check if the component is present and valid + AZ::Component* foundComponent = GetEntity()->FindComponent(componentUuid); + if (foundComponent) + { + return foundComponent; + } + + // then check to see if there's a component pending because it's in an invalid state + AZStd::vector pendingComponents; + AzToolsFramework::EditorPendingCompositionRequestBus::Event(GetEntityId(), + &AzToolsFramework::EditorPendingCompositionRequests::GetPendingComponents, pendingComponents); + + for (const auto pendingComponent : pendingComponents) + { + if (pendingComponent->RTTI_IsTypeOf(componentUuid)) + { + return pendingComponent; + } + } + + return nullptr; + } + + AZ::Crc32 TransformComponent::AddNonUniformScaleButtonVisibility() + { + // if there is a non-uniform scale component already, hide altogether + if (FindPresentOrPendingComponent(EditorNonUniformScaleComponent::TYPEINFO_Uuid())) + { + return AZ::Edit::PropertyVisibility::Hide; + } + + // otherwise, just show children + return AZ::Edit::PropertyVisibility::ShowChildrenOnly; + } + AZ::Crc32 TransformComponent::OnAddNonUniformScaleButtonPressed() { // if there is already a non-uniform scale component, do nothing - if (GetEntity()->FindComponent()) + if (FindPresentOrPendingComponent(EditorNonUniformScaleComponent::TYPEINFO_Uuid())) { return AZ::Edit::PropertyRefreshLevels::None; } @@ -1232,17 +1269,11 @@ namespace AzToolsFramework AzToolsFramework::EntityCompositionRequestBus::BroadcastResult(outcome, &AzToolsFramework::EntityCompositionRequests::AddComponentsToEntities, entityList, componentsToAdd); - AZStd::vector pendingComponents; - AzToolsFramework::EditorPendingCompositionRequestBus::Event(GetEntityId(), - &AzToolsFramework::EditorPendingCompositionRequests::GetPendingComponents, pendingComponents); - AZ::ComponentId nonUniformScaleComponentId = AZ::InvalidComponentId; - for (const auto pendingComponent : pendingComponents) + auto nonUniformScaleComponent = FindPresentOrPendingComponent(EditorNonUniformScaleComponent::RTTI_Type()); + if (nonUniformScaleComponent) { - if (pendingComponent->RTTI_IsTypeOf(AzToolsFramework::Components::EditorNonUniformScaleComponent::RTTI_Type())) - { - nonUniformScaleComponentId = pendingComponent->GetId(); - } + nonUniformScaleComponentId = nonUniformScaleComponent->GetId(); } if (!outcome.IsSuccess() || nonUniformScaleComponentId == AZ::InvalidComponentId) @@ -1300,7 +1331,7 @@ namespace AzToolsFramework Attribute(AZ::Edit::Attributes::AutoExpand, true)-> DataElement(AZ::Edit::UIHandlers::Default, &TransformComponent::m_addNonUniformScaleButton, "", "")-> Attribute(AZ::Edit::Attributes::AutoExpand, true)-> - Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly)-> + Attribute(AZ::Edit::Attributes::Visibility, &TransformComponent::AddNonUniformScaleButtonVisibility)-> Attribute(AZ::Edit::Attributes::ChangeNotify, &TransformComponent::OnAddNonUniformScaleButtonPressed)-> DataElement(AZ::Edit::UIHandlers::ComboBox, &TransformComponent::m_parentActivationTransformMode, "Parent activation", "Configures relative transform behavior when parent activates.")-> diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/TransformComponent.h b/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/TransformComponent.h index dd8c7b8693..7a0675187a 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/TransformComponent.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/TransformComponent.h @@ -37,8 +37,6 @@ namespace AzToolsFramework public: AZ_TYPE_INFO(AddNonUniformScaleButton, "{92ECB8B6-DD25-4FC0-A5EE-4CEBAF51A780}") static void Reflect(AZ::ReflectContext* context); - private: - void OnAddNonUniformScaleButtonPressed() {}; }; /// Manages transform data as separate vector fields for editing purposes. @@ -238,6 +236,8 @@ namespace AzToolsFramework void CheckApplyCachedWorldTransform(const AZ::Transform& parentWorld); + AZ::Component* FindPresentOrPendingComponent(AZ::Uuid componentUuid); + AZ::Crc32 AddNonUniformScaleButtonVisibility(); AZ::Crc32 OnAddNonUniformScaleButtonPressed(); // Drives transform behavior when parent activates. See AZ::TransformConfig::ParentActivationTransformMode for details. From e1f7d04bc251c4e9e04853fa735c9549b4021876 Mon Sep 17 00:00:00 2001 From: greerdv Date: Wed, 5 May 2021 13:10:01 +0100 Subject: [PATCH 05/10] adding icon for non-uniform scale component --- .../Icons/Components/NonUniformScale.svg | 27 +++++++++++++++++++ .../EditorNonUniformScaleComponent.cpp | 2 ++ 2 files changed, 29 insertions(+) create mode 100644 Assets/Editor/Icons/Components/NonUniformScale.svg diff --git a/Assets/Editor/Icons/Components/NonUniformScale.svg b/Assets/Editor/Icons/Components/NonUniformScale.svg new file mode 100644 index 0000000000..f377232d62 --- /dev/null +++ b/Assets/Editor/Icons/Components/NonUniformScale.svg @@ -0,0 +1,27 @@ + + + Icons / Toolbar / Non Uniform Scaling + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/EditorNonUniformScaleComponent.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/EditorNonUniformScaleComponent.cpp index d28f23c847..67f8212f5e 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/EditorNonUniformScaleComponent.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/EditorNonUniformScaleComponent.cpp @@ -41,6 +41,8 @@ namespace AzToolsFramework ->ClassElement(AZ::Edit::ClassElements::EditorData, "") ->Attribute(AZ::Edit::Attributes::RemoveableByUser, true) ->Attribute(AZ::Edit::Attributes::DraggableByUser, false) + ->Attribute(AZ::Edit::Attributes::Icon, "Icons/Components/NonUniformScale.svg") + ->Attribute(AZ::Edit::Attributes::ViewportIcon, "Icons/Components/NonUniformScale.svg") ->DataElement( AZ::Edit::UIHandlers::Default, &EditorNonUniformScaleComponent::m_scale, "Non-uniform Scale", "Non-uniform scale for this entity only (does not propagate through hierarchy)") From 45cbe4767f18de76cb11b0cbce0f0316f21d6362 Mon Sep 17 00:00:00 2001 From: greerdv Date: Wed, 5 May 2021 15:14:50 +0100 Subject: [PATCH 06/10] adding comment to AddNonUniformScaleButton --- .../AzToolsFramework/ToolsComponents/TransformComponent.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/TransformComponent.h b/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/TransformComponent.h index 7a0675187a..783ecfc84f 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/TransformComponent.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/TransformComponent.h @@ -32,6 +32,8 @@ namespace AzToolsFramework { namespace Components { + // this is a workaround for a bug which causes the button to appear with incorrect placement if added directly + // to the transform component class AddNonUniformScaleButton { public: From ad6479967f5f9eff2e011f064687f0ca612988dd Mon Sep 17 00:00:00 2001 From: greerdv Date: Thu, 6 May 2021 22:15:00 +0100 Subject: [PATCH 07/10] changing add NUS button from invisible to read only when NUS component already present --- .../ToolsComponents/TransformComponent.cpp | 36 +++---------------- .../ToolsComponents/TransformComponent.h | 16 +++------ 2 files changed, 10 insertions(+), 42 deletions(-) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/TransformComponent.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/TransformComponent.cpp index e20c114b20..bca7dc08e2 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/TransformComponent.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/TransformComponent.cpp @@ -45,23 +45,6 @@ namespace AzToolsFramework { namespace Components { - void AddNonUniformScaleButton::Reflect(AZ::ReflectContext* context) - { - if (AZ::SerializeContext* serializeContext = azrtti_cast(context)) - { - serializeContext->Class()-> - Version(1); - - if (AZ::EditContext* ptrEdit = serializeContext->GetEditContext()) - { - ptrEdit->Class("AddNonUniformScaleButton", "")-> - UIElement(AZ::Edit::UIHandlers::Button, "", "Add non-uniform scale component")-> - Attribute(AZ::Edit::Attributes::ButtonText, "Add non-uniform scale") - ; - } - } - } - namespace Internal { const AZ::u32 ParentEntityCRC = AZ_CRC("Parent Entity", 0x5b1b276c); @@ -1242,16 +1225,9 @@ namespace AzToolsFramework return nullptr; } - AZ::Crc32 TransformComponent::AddNonUniformScaleButtonVisibility() + bool TransformComponent::IsAddNonUniformScaleButtonReadOnly() { - // if there is a non-uniform scale component already, hide altogether - if (FindPresentOrPendingComponent(EditorNonUniformScaleComponent::TYPEINFO_Uuid())) - { - return AZ::Edit::PropertyVisibility::Hide; - } - - // otherwise, just show children - return AZ::Edit::PropertyVisibility::ShowChildrenOnly; + return FindPresentOrPendingComponent(EditorNonUniformScaleComponent::TYPEINFO_Uuid()) != nullptr; } AZ::Crc32 TransformComponent::OnAddNonUniformScaleButtonPressed() @@ -1290,8 +1266,6 @@ namespace AzToolsFramework void TransformComponent::Reflect(AZ::ReflectContext* context) { - AddNonUniformScaleButton::Reflect(context); - // reflect data for script, serialization, editing.. if (AZ::SerializeContext* serializeContext = azrtti_cast(context)) { @@ -1329,9 +1303,9 @@ namespace AzToolsFramework DataElement(AZ::Edit::UIHandlers::Default, &TransformComponent::m_editorTransform, "Values", "")-> Attribute(AZ::Edit::Attributes::ChangeNotify, &TransformComponent::TransformChanged)-> Attribute(AZ::Edit::Attributes::AutoExpand, true)-> - DataElement(AZ::Edit::UIHandlers::Default, &TransformComponent::m_addNonUniformScaleButton, "", "")-> - Attribute(AZ::Edit::Attributes::AutoExpand, true)-> - Attribute(AZ::Edit::Attributes::Visibility, &TransformComponent::AddNonUniformScaleButtonVisibility)-> + DataElement(AZ::Edit::UIHandlers::Button, &TransformComponent::m_addNonUniformScaleButton, "", "")-> + Attribute(AZ::Edit::Attributes::ButtonText, "Add non-uniform scale")-> + Attribute(AZ::Edit::Attributes::ReadOnly, &TransformComponent::IsAddNonUniformScaleButtonReadOnly)-> Attribute(AZ::Edit::Attributes::ChangeNotify, &TransformComponent::OnAddNonUniformScaleButtonPressed)-> DataElement(AZ::Edit::UIHandlers::ComboBox, &TransformComponent::m_parentActivationTransformMode, "Parent activation", "Configures relative transform behavior when parent activates.")-> diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/TransformComponent.h b/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/TransformComponent.h index 783ecfc84f..3d1e1ed672 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/TransformComponent.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/TransformComponent.h @@ -32,15 +32,6 @@ namespace AzToolsFramework { namespace Components { - // this is a workaround for a bug which causes the button to appear with incorrect placement if added directly - // to the transform component - class AddNonUniformScaleButton - { - public: - AZ_TYPE_INFO(AddNonUniformScaleButton, "{92ECB8B6-DD25-4FC0-A5EE-4CEBAF51A780}") - static void Reflect(AZ::ReflectContext* context); - }; - /// Manages transform data as separate vector fields for editing purposes. /// The TransformComponent is referenced by other components in the same entity, it is not an asset. class TransformComponent @@ -239,7 +230,7 @@ namespace AzToolsFramework void CheckApplyCachedWorldTransform(const AZ::Transform& parentWorld); AZ::Component* FindPresentOrPendingComponent(AZ::Uuid componentUuid); - AZ::Crc32 AddNonUniformScaleButtonVisibility(); + bool IsAddNonUniformScaleButtonReadOnly(); AZ::Crc32 OnAddNonUniformScaleButtonPressed(); // Drives transform behavior when parent activates. See AZ::TransformConfig::ParentActivationTransformMode for details. @@ -273,7 +264,10 @@ namespace AzToolsFramework bool m_localTransformDirty = true; bool m_worldTransformDirty = true; bool m_isStatic = false; - AddNonUniformScaleButton m_addNonUniformScaleButton; + + // This is a workaround for a bug which causes the button to appear with incorrect placement if a UI + // element is used rather than a data element. + bool m_addNonUniformScaleButton = false; // Deprecated AZ::InterpolationMode m_interpolatePosition; From 2c6d04f6736721230086832007c77f561ecb3009 Mon Sep 17 00:00:00 2001 From: greerdv Date: Fri, 7 May 2021 15:03:57 +0100 Subject: [PATCH 08/10] feedback from PR --- .../Serialization/EditContextConstants.inl | 7 +-- .../EditorNonUniformScaleComponent.cpp | 2 +- .../ToolsComponents/TransformComponent.cpp | 19 ++++---- .../PropertyEditor/EntityPropertyEditor.cpp | 43 +++++++++---------- .../PropertyEditor/EntityPropertyEditor.hxx | 1 + 5 files changed, 34 insertions(+), 38 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/Serialization/EditContextConstants.inl b/Code/Framework/AzCore/AzCore/Serialization/EditContextConstants.inl index 454d998321..1016027966 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/EditContextConstants.inl +++ b/Code/Framework/AzCore/AzCore/Serialization/EditContextConstants.inl @@ -53,9 +53,10 @@ namespace AZ //! RemoveableByUser : A bool which determines if the component can be removed by the user. //! Setting this to false prevents the user from removing this component. Default behavior is removeable by user. const static AZ::Crc32 RemoveableByUser = AZ_CRC("RemoveableByUser", 0x32c7fd50); - //! A bool which determines if the component can be dragged to change where it appears in the entity sort order. - //! Setting this to false prevents the user from dragging the component. Default behaviour is draggable by user. - const static AZ::Crc32 DraggableByUser = AZ_CRC_CE("DraggableByUser"); + //! An int which, if specified, causes a component to be forced to a particular position in the sorted list of + //! components on an entity, and prevents dragging or moving operations which would affect that position. + const static AZ::Crc32 FixedComponentListIndex = AZ_CRC_CE("FixedComponentListIndex"); + const static AZ::Crc32 AppearsInAddComponentMenu = AZ_CRC("AppearsInAddComponentMenu", 0x53790e31); const static AZ::Crc32 ForceAutoExpand = AZ_CRC("ForceAutoExpand", 0x1a5c79d2); // Ignores expansion state set by user, enforces expansion. const static AZ::Crc32 AutoExpand = AZ_CRC("AutoExpand", 0x306ff5c0); // Expands automatically unless user changes expansion state. diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/EditorNonUniformScaleComponent.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/EditorNonUniformScaleComponent.cpp index 67f8212f5e..989398f196 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/EditorNonUniformScaleComponent.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/EditorNonUniformScaleComponent.cpp @@ -39,8 +39,8 @@ namespace AzToolsFramework editContext->Class("Non-uniform Scale", "Non-uniform scale for this entity only (does not propagate through hierarchy)") ->ClassElement(AZ::Edit::ClassElements::EditorData, "") + ->Attribute(AZ::Edit::Attributes::FixedComponentListIndex, 1) ->Attribute(AZ::Edit::Attributes::RemoveableByUser, true) - ->Attribute(AZ::Edit::Attributes::DraggableByUser, false) ->Attribute(AZ::Edit::Attributes::Icon, "Icons/Components/NonUniformScale.svg") ->Attribute(AZ::Edit::Attributes::ViewportIcon, "Icons/Components/NonUniformScale.svg") ->DataElement( diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/TransformComponent.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/TransformComponent.cpp index bca7dc08e2..f8d02b6581 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/TransformComponent.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/TransformComponent.cpp @@ -1203,8 +1203,7 @@ namespace AzToolsFramework AZ::Component* TransformComponent::FindPresentOrPendingComponent(AZ::Uuid componentUuid) { // first check if the component is present and valid - AZ::Component* foundComponent = GetEntity()->FindComponent(componentUuid); - if (foundComponent) + if (AZ::Component* foundComponent = GetEntity()->FindComponent(componentUuid)) { return foundComponent; } @@ -1241,18 +1240,15 @@ namespace AzToolsFramework const AZStd::vector entityList = { GetEntityId() }; const AZ::ComponentTypeList componentsToAdd = { EditorNonUniformScaleComponent::TYPEINFO_Uuid() }; - AzToolsFramework::EntityCompositionRequests::AddComponentsOutcome outcome; - AzToolsFramework::EntityCompositionRequestBus::BroadcastResult(outcome, + AzToolsFramework::EntityCompositionRequests::AddComponentsOutcome addComponentsOutcome; + AzToolsFramework::EntityCompositionRequestBus::BroadcastResult(addComponentsOutcome, &AzToolsFramework::EntityCompositionRequests::AddComponentsToEntities, entityList, componentsToAdd); - AZ::ComponentId nonUniformScaleComponentId = AZ::InvalidComponentId; - auto nonUniformScaleComponent = FindPresentOrPendingComponent(EditorNonUniformScaleComponent::RTTI_Type()); - if (nonUniformScaleComponent) - { - nonUniformScaleComponentId = nonUniformScaleComponent->GetId(); - } + const auto nonUniformScaleComponent = FindPresentOrPendingComponent(EditorNonUniformScaleComponent::RTTI_Type()); + AZ::ComponentId nonUniformScaleComponentId = + nonUniformScaleComponent ? nonUniformScaleComponent->GetId() : AZ::InvalidComponentId; - if (!outcome.IsSuccess() || nonUniformScaleComponentId == AZ::InvalidComponentId) + if (!addComponentsOutcome.IsSuccess() || !nonUniformScaleComponent) { AZ_Warning("Transform component", false, "Failed to add non-uniform scale component."); return AZ::Edit::PropertyRefreshLevels::None; @@ -1293,6 +1289,7 @@ namespace AzToolsFramework { ptrEdit->Class("Transform", "Controls the placement of the entity in the world in 3d")-> ClassElement(AZ::Edit::ClassElements::EditorData, "")-> + Attribute(AZ::Edit::Attributes::FixedComponentListIndex, 0)-> Attribute(AZ::Edit::Attributes::Icon, "Icons/Components/Transform.svg")-> Attribute(AZ::Edit::Attributes::ViewportIcon, "Icons/Components/Viewport/Transform.png")-> Attribute(AZ::Edit::Attributes::AutoExpand, true)-> diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/EntityPropertyEditor.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/EntityPropertyEditor.cpp index 51d4ed5026..c3639b872e 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/EntityPropertyEditor.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/EntityPropertyEditor.cpp @@ -1045,28 +1045,23 @@ namespace AzToolsFramework sortedComponents.end(), [=](const OrderedSortComponentEntry& component1, const OrderedSortComponentEntry& component2) { - // Transform component must be first, always - // If component 1 is a transform component, it is sorted earlier - if (component1.m_component->RTTI_IsTypeOf(AZ::EditorTransformComponentTypeId)) - { - return true; - } + AZStd::optional fixedComponentListIndex1 = GetFixedComponentListIndex(component1.m_component); + AZStd::optional fixedComponentListIndex2 = GetFixedComponentListIndex(component2.m_component); - // If component 2 is a transform component, component 1 is never sorted earlier - if (component2.m_component->RTTI_IsTypeOf(AZ::EditorTransformComponentTypeId)) + // If both components have fixed list indices, sort based on those indices + if (fixedComponentListIndex1.has_value() && fixedComponentListIndex2.has_value()) { - return false; + return fixedComponentListIndex1.value() < fixedComponentListIndex2.value(); } - // If component 1 is a non-uniform scale component, it is sorted earlier (it should appear immediately after transform) - if (component1.m_component->RTTI_IsTypeOf(AzToolsFramework::Components::EditorNonUniformScaleComponent::RTTI_Type())) + // If component 1 has a fixed list index, sort it first + if (fixedComponentListIndex1.has_value()) { return true; } - // If component 2 is a non-uniform scale component, component 1 is never sorted earlier - // (transform will already dominate in the check above) - if (component2.m_component->RTTI_IsTypeOf(AzToolsFramework::Components::EditorNonUniformScaleComponent::RTTI_Type())) + // If component 2 has a fixed list index, component 1 should not be sorted before it + if (fixedComponentListIndex2.has_value()) { return false; } @@ -1182,32 +1177,34 @@ namespace AzToolsFramework return true; } - bool EntityPropertyEditor::IsComponentDraggable(const AZ::Component* component) + AZStd::optional EntityPropertyEditor::GetFixedComponentListIndex(const AZ::Component* component) { auto componentClassData = component ? GetComponentClassData(component) : nullptr; if (componentClassData && componentClassData->m_editData) { if (auto editorDataElement = componentClassData->m_editData->FindElementData(AZ::Edit::ClassElements::EditorData)) { - if (auto attribute = editorDataElement->FindAttribute(AZ::Edit::Attributes::DraggableByUser)) + if (auto attribute = editorDataElement->FindAttribute(AZ::Edit::Attributes::FixedComponentListIndex)) { - if (auto attributeData = azdynamic_cast*>(attribute)) + if (auto attributeData = azdynamic_cast*>(attribute)) { - if (!attributeData->Get(nullptr)) - { - return false; - } + return { attributeData->Get(nullptr) }; } } } } + return {}; + } - return true; + bool EntityPropertyEditor::IsComponentDraggable(const AZ::Component* component) + { + return !GetFixedComponentListIndex(component).has_value(); } bool EntityPropertyEditor::AreComponentsDraggable(const AZ::Entity::ComponentArrayType& components) const { - return AZStd::all_of(components.begin(), components.end(), [](AZ::Component* component) {return IsComponentDraggable(component); }); + return AZStd::all_of( + components.begin(), components.end(), [](AZ::Component* component) { return IsComponentDraggable(component); }); } bool EntityPropertyEditor::AreComponentsCopyable(const AZ::Entity::ComponentArrayType& components) const diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/EntityPropertyEditor.hxx b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/EntityPropertyEditor.hxx index 2fb1c7e03a..9cd380ae06 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/EntityPropertyEditor.hxx +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/EntityPropertyEditor.hxx @@ -238,6 +238,7 @@ namespace AzToolsFramework static bool DoesComponentPassFilter(const AZ::Component* component, const ComponentFilter& filter); static bool IsComponentRemovable(const AZ::Component* component); bool AreComponentsRemovable(const AZ::Entity::ComponentArrayType& components) const; + static AZStd::optional GetFixedComponentListIndex(const AZ::Component* component); static bool IsComponentDraggable(const AZ::Component* component); bool AreComponentsDraggable(const AZ::Entity::ComponentArrayType& components) const; bool AreComponentsCopyable(const AZ::Entity::ComponentArrayType& components) const; From 9e222681070b459013b4d3582a8aa98c96fd5717 Mon Sep 17 00:00:00 2001 From: greerdv Date: Fri, 7 May 2021 15:18:51 +0100 Subject: [PATCH 09/10] feedback from PR --- .../AzToolsFramework/UI/PropertyEditor/EntityPropertyEditor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/EntityPropertyEditor.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/EntityPropertyEditor.cpp index c3639b872e..bfb2ff4256 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/EntityPropertyEditor.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/EntityPropertyEditor.cpp @@ -3730,7 +3730,7 @@ namespace AzToolsFramework AZ::s32 newComponentIndex = m_componentEditorsUsed - 1; // if there is a component id explicitly set as the most recently added, try to find it and make sure it is visible - if (m_newComponentId.has_value()) + if (m_newComponentId.has_value() && m_newComponentId.value() != AZ::InvalidComponentId) { AZ::ComponentId newComponentId = m_newComponentId.value(); for (AZ::s32 componentIndex = 0; componentIndex < m_componentEditorsUsed; ++componentIndex) From 3817c05d81a9fcdc43cb6ef9b8f4399e1a231f4d Mon Sep 17 00:00:00 2001 From: greerdv Date: Fri, 7 May 2021 19:54:59 +0100 Subject: [PATCH 10/10] fixing unit test --- .../Tests/UI/EntityPropertyEditorTests.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/Code/Framework/AzToolsFramework/Tests/UI/EntityPropertyEditorTests.cpp b/Code/Framework/AzToolsFramework/Tests/UI/EntityPropertyEditorTests.cpp index 3017df737d..d0f93bfdf8 100644 --- a/Code/Framework/AzToolsFramework/Tests/UI/EntityPropertyEditorTests.cpp +++ b/Code/Framework/AzToolsFramework/Tests/UI/EntityPropertyEditorTests.cpp @@ -17,13 +17,13 @@ #include #include #include +#include #include #include #include #include #include -#include #include #include @@ -55,7 +55,7 @@ namespace UnitTest TEST(EntityPropertyEditorTests, PrioritySort_NonTransformAsFirstItem_TransformMovesToTopRemainderUnchanged) { - ComponentApplication app; + ToolsApplication app; AZ::Entity::ComponentArrayType unorderedComponents; AZ::Entity::ComponentArrayType orderedComponents; @@ -68,12 +68,18 @@ namespace UnitTest Entity* systemEntity = app.Create(desc, startupParams); + // Need to reflect the components so that edit attribute used for sorting, such as FixedComponentListIndex, get set. + app.RegisterComponentDescriptor(AzToolsFramework::Components::TransformComponent::CreateDescriptor()); + app.RegisterComponentDescriptor(AzToolsFramework::Components::ScriptEditorComponent::CreateDescriptor()); + app.RegisterComponentDescriptor(AZ::AssetManagerComponent::CreateDescriptor()); + // Add more than 31 components, as we are testing the case where the sort fails when there are 32 or more items. const int numFillerItems = 32; for (int commentIndex = 0; commentIndex < numFillerItems; commentIndex++) { - unorderedComponents.insert(unorderedComponents.begin(), systemEntity->CreateComponent(AZ::StreamerComponent::RTTI_Type())); + unorderedComponents.insert(unorderedComponents.begin(), systemEntity->CreateComponent( + AzToolsFramework::Components::ScriptEditorComponent::RTTI_Type())); } // Add a TransformComponent at the end which should be sorted to the beginning by the priority sort.