Merge pull request #5170 from aws-lumberyard-dev/daimini/cherrypick/outlinerEntityOrderingFix

Cherry-pick: resolve entity ordering for EntityOutliner
monroegm-disable-blank-issue-2
Danilo Aimini 4 years ago committed by GitHub
commit d948d78b2e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -943,13 +943,15 @@ namespace AzToolsFramework
{ {
return false; return false;
} }
const int count = rowCount(parent);
AZ::EntityId newParentId = GetEntityFromIndex(parent); AZ::EntityId newParentId = GetEntityFromIndex(parent);
AZ::EntityId beforeEntityId = GetEntityFromIndex(index(row, 0, parent)); AZ::EntityId beforeEntityId = (row >= 0 && row < count) ? GetEntityFromIndex(index(row, 0, parent)) : AZ::EntityId();
EntityIdList topLevelEntityIds; EntityIdList topLevelEntityIds;
topLevelEntityIds.reserve(entityIdListContainer.m_entityIds.size()); topLevelEntityIds.reserve(entityIdListContainer.m_entityIds.size());
ToolsApplicationRequestBus::Broadcast(&ToolsApplicationRequestBus::Events::FindTopLevelEntityIdsInactive, entityIdListContainer.m_entityIds, topLevelEntityIds); ToolsApplicationRequestBus::Broadcast(&ToolsApplicationRequestBus::Events::FindTopLevelEntityIdsInactive, entityIdListContainer.m_entityIds, topLevelEntityIds);
if (!ReparentEntities(newParentId, topLevelEntityIds, beforeEntityId)) const auto appendActionForInvalid = newParentId.IsValid() && (row >= count) ? AppendEnd : AppendBeginning;
if (!ReparentEntities(newParentId, topLevelEntityIds, beforeEntityId, appendActionForInvalid))
{ {
return false; return false;
} }
@ -1046,7 +1048,7 @@ namespace AzToolsFramework
return true; return true;
} }
bool EntityOutlinerListModel::ReparentEntities(const AZ::EntityId& newParentId, const EntityIdList &selectedEntityIds, const AZ::EntityId& beforeEntityId) bool EntityOutlinerListModel::ReparentEntities(const AZ::EntityId& newParentId, const EntityIdList &selectedEntityIds, const AZ::EntityId& beforeEntityId, ReparentForInvalid forInvalid)
{ {
AZ_PROFILE_FUNCTION(AzToolsFramework); AZ_PROFILE_FUNCTION(AzToolsFramework);
if (!CanReparentEntities(newParentId, selectedEntityIds)) if (!CanReparentEntities(newParentId, selectedEntityIds))
@ -1056,10 +1058,18 @@ namespace AzToolsFramework
m_isFilterDirty = true; m_isFilterDirty = true;
ScopedUndoBatch undo("Reparent Entities");
//capture child entity order before re-parent operation, which will automatically add order info if not present //capture child entity order before re-parent operation, which will automatically add order info if not present
EntityOrderArray entityOrderArray = GetEntityChildOrder(newParentId); EntityOrderArray entityOrderArray = GetEntityChildOrder(newParentId);
//search for the insertion entity in the order array
const auto beforeEntityItr = AZStd::find(entityOrderArray.begin(), entityOrderArray.end(), beforeEntityId);
const bool hasInvalidIndex = beforeEntityItr == entityOrderArray.end();
if (hasInvalidIndex && forInvalid == None)
{
return false;
}
ScopedUndoBatch undo("Reparent Entities");
// The new parent is dirty due to sort change(s) // The new parent is dirty due to sort change(s)
undo.MarkEntityDirty(GetEntityIdForSortInfo(newParentId)); undo.MarkEntityDirty(GetEntityIdForSortInfo(newParentId));
@ -1088,9 +1098,7 @@ namespace AzToolsFramework
} }
} }
//search for the insertion entity in the order array
auto beforeEntityItr = AZStd::find(entityOrderArray.begin(), entityOrderArray.end(), beforeEntityId);
//replace order info matching selection with bad values rather than remove to preserve layout //replace order info matching selection with bad values rather than remove to preserve layout
for (auto& id : entityOrderArray) for (auto& id : entityOrderArray)
{ {
@ -1100,17 +1108,25 @@ namespace AzToolsFramework
} }
} }
if (newParentId.IsValid()) //if adding to a valid parent entity, insert at the found entity location or at the head/tail depending on placeAtTail flag
if (hasInvalidIndex)
{ {
//if adding to a valid parent entity, insert at the found entity location or at the head of the container switch(forInvalid)
auto insertItr = beforeEntityItr != entityOrderArray.end() ? beforeEntityItr : entityOrderArray.begin(); {
entityOrderArray.insert(insertItr, processedEntityIds.begin(), processedEntityIds.end()); case AppendEnd:
} entityOrderArray.insert(entityOrderArray.end(), processedEntityIds.begin(), processedEntityIds.end());
else break;
case AppendBeginning:
entityOrderArray.insert(entityOrderArray.begin(), processedEntityIds.begin(), processedEntityIds.end());
break;
default:
AZ_Assert(false, "Unexpected type for ReparentForInvalid");
break;
}
}
else
{ {
//if adding to an invalid parent entity (the root), insert at the found entity location or at the tail of the container entityOrderArray.insert(beforeEntityItr, processedEntityIds.begin(), processedEntityIds.end());
auto insertItr = beforeEntityItr != entityOrderArray.end() ? beforeEntityItr : entityOrderArray.end();
entityOrderArray.insert(insertItr, processedEntityIds.begin(), processedEntityIds.end());
} }
//remove placeholder entity ids //remove placeholder entity ids

@ -72,6 +72,13 @@ namespace AzToolsFramework
ColumnCount //!< Total number of columns ColumnCount //!< Total number of columns
}; };
enum ReparentForInvalid
{
None, //!< For an invalid location the entity does not change location
AppendEnd, //!< Append Item to end of target parent list
AppendBeginning, //!< Append Item to the beginning of target parent list
};
// Note: the ColumnSortIndex column isn't shown, hence the -1 and the need for a separate counter. // Note: the ColumnSortIndex column isn't shown, hence the -1 and the need for a separate counter.
// A wrong column count number causes refresh issues and hover mismatch on model update. // A wrong column count number causes refresh issues and hover mismatch on model update.
static const int VisibleColumnCount = ColumnCount - 1; static const int VisibleColumnCount = ColumnCount - 1;
@ -162,7 +169,7 @@ namespace AzToolsFramework
// Buffer Processing Slots - These are called using single-shot events when the buffers begin to fill. // Buffer Processing Slots - These are called using single-shot events when the buffers begin to fill.
bool CanReparentEntities(const AZ::EntityId& newParentId, const EntityIdList& selectedEntityIds) const; bool CanReparentEntities(const AZ::EntityId& newParentId, const EntityIdList& selectedEntityIds) const;
bool ReparentEntities(const AZ::EntityId& newParentId, const EntityIdList& selectedEntityIds, const AZ::EntityId& beforeEntityId = AZ::EntityId()); bool ReparentEntities(const AZ::EntityId& newParentId, const EntityIdList& selectedEntityIds, const AZ::EntityId& beforeEntityId = AZ::EntityId(), ReparentForInvalid forInvalid = None);
//! Use the current filter setting and re-evaluate the filter. //! Use the current filter setting and re-evaluate the filter.
void InvalidateFilter(); void InvalidateFilter();

Loading…
Cancel
Save