adding non-uniform scale component via button on transform component and forcing it to be adjacent in the component sort order and visible

main
greerdv 5 years ago
parent c8e8c1de66
commit d9b3b7ccfa

@ -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.

@ -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"));

@ -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<EntityPropertyEditorRequests>;

@ -39,9 +39,8 @@ namespace AzToolsFramework
editContext->Class<EditorNonUniformScaleComponent>("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"));

@ -26,12 +26,14 @@
#include <AzFramework/API/ApplicationAPI.h>
#include <AzFramework/Components/TransformComponent.h>
#include <AzToolsFramework/API/EntityCompositionRequestBus.h>
#include <AzToolsFramework/API/EntityPropertyEditorRequestsBus.h>
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
#include <AzToolsFramework/Entity/EditorEntityContextBus.h>
#include <AzToolsFramework/Prefab/PrefabPublicInterface.h>
#include <AzToolsFramework/ToolsComponents/TransformComponentBus.h>
#include <AzToolsFramework/ToolsComponents/TransformScalePropertyHandler.h>
#include <AzToolsFramework/ToolsComponents/EditorInspectorComponentBus.h>
#include <AzToolsFramework/ToolsComponents/EditorPendingCompositionBus.h>
#include <AzToolsFramework/ViewportSelection/EditorSelectionUtil.h>
#include <AzToolsFramework/Viewport/ViewportMessages.h>
@ -39,8 +41,6 @@
#include <QMenu>
#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<EditorNonUniformScaleComponent>();
AZStd::vector<AZ::Component*> 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;
}

@ -63,6 +63,7 @@ AZ_POP_DISABLE_WARNING
#include <AzToolsFramework/ToolsComponents/EditorOnlyEntityComponentBus.h>
#include <AzToolsFramework/ToolsComponents/EditorOnlyEntityComponent.h>
#include <AzToolsFramework/ToolsComponents/EditorLayerComponent.h>
#include <AzToolsFramework/ToolsComponents/EditorNonUniformScaleComponent.h>
#include <AzToolsFramework/ToolsMessaging/EntityHighlightBus.h>
#include <AzToolsFramework/UI/ComponentPalette/ComponentPaletteUtil.hxx>
#include <AzToolsFramework/UI/ComponentPalette/ComponentPaletteWidget.hxx>
@ -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<AZ::Edit::AttributeData<bool>*>(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<AZ::Edit::AttributeData<bool>*>(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()

@ -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<AZ::ComponentId> m_newComponentId;
private slots:
void OnPropertyRefreshRequired(); // refresh is needed for a property.
void UpdateContents();

Loading…
Cancel
Save