Merge remote-tracking branch 'upstream/stabilization/2110' into nvsickle/FixEntityOrdering

This commit is contained in:
nvsickle
2021-11-04 12:07:53 -07:00
140 changed files with 2907 additions and 1620 deletions
@@ -58,6 +58,10 @@ namespace AzToolsFramework
//! @return The highest closed entity container id if any, or entityId otherwise.
virtual AZ::EntityId FindHighestSelectableEntity(AZ::EntityId entityId) const = 0;
//! Triggers the OnContainerEntityStatusChanged notifications for all registered containers,
//! allowing listeners to update correctly.
virtual void RefreshAllContainerEntities(AzFramework::EntityContextId entityContextId) const = 0;
//! Clears all open state information for Container Entities for the EntityContextId provided.
//! Used when context is switched, for example in the case of a new root prefab being loaded
//! in place of an old one.
@@ -142,6 +142,15 @@ namespace AzToolsFramework
Clear(editorEntityContextId);
}
void ContainerEntitySystemComponent::RefreshAllContainerEntities([[maybe_unused]] AzFramework::EntityContextId entityContextId) const
{
for (AZ::EntityId containerEntityId : m_containers)
{
ContainerEntityNotificationBus::Broadcast(
&ContainerEntityNotificationBus::Events::OnContainerEntityStatusChanged, containerEntityId, m_openContainers.contains(containerEntityId));
}
}
ContainerEntityOperationResult ContainerEntitySystemComponent::Clear(AzFramework::EntityContextId entityContextId)
{
// We don't yet support multiple entity contexts, so only clear the default.
@@ -47,6 +47,7 @@ namespace AzToolsFramework
ContainerEntityOperationResult SetContainerOpen(AZ::EntityId entityId, bool open) override;
bool IsContainerOpen(AZ::EntityId entityId) const override;
AZ::EntityId FindHighestSelectableEntity(AZ::EntityId entityId) const override;
void RefreshAllContainerEntities(AzFramework::EntityContextId entityContextId) const override;
ContainerEntityOperationResult Clear(AzFramework::EntityContextId entityContextId) override;
bool IsUnderClosedContainerEntity(AZ::EntityId entityId) const override;
@@ -86,6 +86,45 @@ namespace AzToolsFramework::Prefab
return AZ::Success();
}
PrefabFocusOperationResult PrefabFocusHandler::FocusOnParentOfFocusedPrefab(
[[maybe_unused]] AzFramework::EntityContextId entityContextId)
{
// If only one instance is in the hierarchy, this operation is invalid
size_t hierarchySize = m_instanceFocusHierarchy.size();
if (hierarchySize <= 1)
{
return AZ::Failure(
AZStd::string("Prefab Focus Handler: Could not complete FocusOnParentOfFocusedPrefab operation while focusing on the root."));
}
// Retrieve parent of currently focused prefab.
InstanceOptionalReference parentInstance = m_instanceFocusHierarchy[hierarchySize - 2];
// Use container entity of parent Instance for focus operations.
AZ::EntityId entityId = parentInstance->get().GetContainerEntityId();
// Initialize Undo Batch object
ScopedUndoBatch undoBatch("Edit Prefab");
// Clear selection
{
const EntityIdList selectedEntities = EntityIdList{};
auto selectionUndo = aznew SelectionCommand(selectedEntities, "Clear Selection");
selectionUndo->SetParent(undoBatch.GetUndoBatch());
ToolsApplicationRequestBus::Broadcast(&ToolsApplicationRequestBus::Events::SetSelectedEntities, selectedEntities);
}
// Edit Prefab
{
auto editUndo = aznew PrefabFocusUndo("Edit Prefab");
editUndo->Capture(entityId);
editUndo->SetParent(undoBatch.GetUndoBatch());
FocusOnPrefabInstanceOwningEntityId(entityId);
}
return AZ::Success();
}
PrefabFocusOperationResult PrefabFocusHandler::FocusOnPathIndex([[maybe_unused]] AzFramework::EntityContextId entityContextId, int index)
{
if (index < 0 || index >= m_instanceFocusHierarchy.size())
@@ -50,6 +50,7 @@ namespace AzToolsFramework::Prefab
// PrefabFocusPublicInterface overrides ...
PrefabFocusOperationResult FocusOnOwningPrefab(AZ::EntityId entityId) override;
PrefabFocusOperationResult FocusOnParentOfFocusedPrefab(AzFramework::EntityContextId entityContextId) override;
PrefabFocusOperationResult FocusOnPathIndex(AzFramework::EntityContextId entityContextId, int index) override;
AZ::EntityId GetFocusedPrefabContainerEntityId(AzFramework::EntityContextId entityContextId) const override;
bool IsOwningPrefabBeingFocused(AZ::EntityId entityId) const override;
@@ -30,6 +30,9 @@ namespace AzToolsFramework::Prefab
//! @param entityId The entityId of the entity whose owning instance we want the prefab system to focus on.
virtual PrefabFocusOperationResult FocusOnOwningPrefab(AZ::EntityId entityId) = 0;
//! Set the focused prefab instance to the parent of the currently focused prefab instance. Supports undo/redo.
virtual PrefabFocusOperationResult FocusOnParentOfFocusedPrefab(AzFramework::EntityContextId entityContextId) = 0;
//! Set the focused prefab instance to the instance at position index of the current path. Supports undo/redo.
//! @param index The index of the instance in the current path that we want the prefab system to focus on.
virtual PrefabFocusOperationResult FocusOnPathIndex(AzFramework::EntityContextId entityContextId, int index) = 0;
@@ -12,11 +12,12 @@
#include <AzCore/Utils/TypeHash.h>
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
#include <AzToolsFramework/ContainerEntity/ContainerEntityInterface.h>
#include <AzToolsFramework/Entity/EditorEntityContextBus.h>
#include <AzToolsFramework/Entity/EditorEntityHelpers.h>
#include <AzToolsFramework/Entity/EditorEntityInfoBus.h>
#include <AzToolsFramework/Prefab/EditorPrefabComponent.h>
#include <AzToolsFramework/Entity/PrefabEditorEntityOwnershipInterface.h>
#include <AzToolsFramework/Prefab/EditorPrefabComponent.h>
#include <AzToolsFramework/Prefab/Instance/Instance.h>
#include <AzToolsFramework/Prefab/Instance/InstanceEntityIdMapper.h>
#include <AzToolsFramework/Prefab/Instance/InstanceEntityMapperInterface.h>
@@ -565,6 +566,7 @@ namespace AzToolsFramework
parentId = m_prefabFocusPublicInterface->GetFocusedPrefabContainerEntityId(editorEntityContextId);
}
// If the parent entity isn't owned by a prefab instance, bail.
InstanceOptionalReference owningInstanceOfParentEntity = GetOwnerInstanceByEntityId(parentId);
if (!owningInstanceOfParentEntity)
{
@@ -572,6 +574,14 @@ namespace AzToolsFramework
"Cannot add entity because the owning instance of parent entity with id '%llu' could not be found.",
static_cast<AZ::u64>(parentId)));
}
// If the parent entity is a closed container, bail.
if (auto containerEntityInterface = AZ::Interface<ContainerEntityInterface>::Get(); !containerEntityInterface->IsContainerOpen(parentId))
{
return AZ::Failure(AZStd::string::format(
"Cannot add entity because the parent entity (id '%llu') is a closed container entity.",
static_cast<AZ::u64>(parentId)));
}
EntityAlias entityAlias = Instance::GenerateEntityAlias();
@@ -43,6 +43,7 @@
#include <AzToolsFramework/API/ComponentEntityObjectBus.h>
#include <AzToolsFramework/AssetBrowser/AssetBrowserEntry.h>
#include <AzToolsFramework/AssetBrowser/AssetBrowserSourceDropBus.h>
#include <AzToolsFramework/ContainerEntity/ContainerEntityInterface.h>
#include <AzToolsFramework/Entity/EditorEntityContextBus.h>
#include <AzToolsFramework/Entity/EditorEntityHelpers.h>
#include <AzToolsFramework/Entity/EditorEntityInfoBus.h>
@@ -764,10 +765,21 @@ namespace AzToolsFramework
return canHandleData;
}
bool EntityOutlinerListModel::CanDropMimeDataAssets(const QMimeData* data, Qt::DropAction /*action*/, int /*row*/, int /*column*/, const QModelIndex& /*parent*/) const
bool EntityOutlinerListModel::CanDropMimeDataAssets(
const QMimeData* data,
[[maybe_unused]] Qt::DropAction action,
[[maybe_unused]] int row,
[[maybe_unused]] int column,
const QModelIndex& parent) const
{
using namespace AzToolsFramework;
// Disable dropping assets on closed container entities.
AZ::EntityId parentId = GetEntityFromIndex(parent);
if (auto containerEntityInterface = AZ::Interface<ContainerEntityInterface>::Get();
!containerEntityInterface->IsContainerOpen(parentId))
{
return false;
}
if (data->hasFormat(AssetBrowser::AssetBrowserEntry::GetMimeType()))
{
return DecodeAssetMimeData(data);
@@ -788,8 +800,15 @@ namespace AzToolsFramework
return false;
}
// If the parent entity is a closed container, bail.
if (auto containerEntityInterface = AZ::Interface<ContainerEntityInterface>::Get();
!containerEntityInterface->IsContainerOpen(assignParentId))
{
return false;
}
// Source Files
if (sourceFiles.size() > 0)
if (!sourceFiles.empty())
{
// Get position (center of viewport). If no viewport is available, (0,0,0) will be used.
AZ::Vector3 viewportCenterPosition = AZ::Vector3::CreateZero();
@@ -973,6 +992,12 @@ namespace AzToolsFramework
return false;
}
// If the new parent is a closed container, bail.
if (auto containerEntityInterface = AZ::Interface<ContainerEntityInterface>::Get(); !containerEntityInterface->IsContainerOpen(newParentId))
{
return false;
}
// Ignore entities not owned by the editor context. It is assumed that all entities belong
// to the same context since multiple selection doesn't span across views.
for (const AZ::EntityId& entityId : selectedEntityIds)
@@ -2155,20 +2180,9 @@ namespace AzToolsFramework
void EntityOutlinerItemDelegate::PaintAncestorForegrounds(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
{
// Go through ancestors and add them to the stack
AZStd::stack<QModelIndex> handlerStack;
// Ancestor foregrounds are painted on top of the childrens'.
for (QModelIndex ancestorIndex = index.parent(); ancestorIndex.isValid(); ancestorIndex = ancestorIndex.parent())
{
handlerStack.push(ancestorIndex);
}
// Apply the ancestor overrides from top to bottom
while (!handlerStack.empty())
{
QModelIndex ancestorIndex = handlerStack.top();
handlerStack.pop();
AZ::EntityId ancestorEntityId(ancestorIndex.data(EntityOutlinerListModel::EntityIdRole).value<AZ::u64>());
auto ancestorUiHandler = m_editorEntityFrameworkInterface->GetHandler(ancestorEntityId);
@@ -8,6 +8,7 @@
#include <AzToolsFramework/UI/Prefab/LevelRootUiHandler.h>
#include <AzToolsFramework/Prefab/PrefabFocusPublicInterface.h>
#include <AzToolsFramework/Prefab/PrefabPublicInterface.h>
#include <AzToolsFramework/UI/Outliner/EntityOutlinerListModel.hxx>
@@ -92,4 +93,16 @@ namespace AzToolsFramework
painter->drawLine(rect.bottomLeft(), rect.bottomRight());
painter->restore();
}
bool LevelRootUiHandler::OnEntityDoubleClick(AZ::EntityId entityId) const
{
if (auto prefabFocusPublicInterface = AZ::Interface<Prefab::PrefabFocusPublicInterface>::Get();
!prefabFocusPublicInterface->IsOwningPrefabBeingFocused(entityId))
{
prefabFocusPublicInterface->FocusOnOwningPrefab(entityId);
}
// Don't propagate event.
return true;
}
}
@@ -33,6 +33,7 @@ namespace AzToolsFramework
bool CanToggleLockVisibility(AZ::EntityId entityId) const override;
bool CanRename(AZ::EntityId entityId) const override;
void PaintItemBackground(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const override;
bool OnEntityDoubleClick(AZ::EntityId entityId) const override;
private:
Prefab::PrefabPublicInterface* m_prefabPublicInterface = nullptr;
@@ -35,6 +35,7 @@
#include <AzToolsFramework/UI/EditorEntityUi/EditorEntityUiInterface.h>
#include <AzToolsFramework/UI/Prefab/PrefabIntegrationInterface.h>
#include <AzToolsFramework/UI/UICore/WidgetHelpers.h>
#include <AzToolsFramework/Viewport/ActionBus.h>
#include <AzQtComponents/Components/Widgets/CheckBox.h>
#include <AzQtComponents/Components/FlowLayout.h>
@@ -54,6 +55,7 @@
#include <QMenu>
#include <QMessageBox>
#include <QScrollArea>
#include <QTimer>
#include <QVBoxLayout>
#include <QWidget>
@@ -61,6 +63,8 @@ namespace AzToolsFramework
{
namespace Prefab
{
AzFramework::EntityContextId PrefabIntegrationManager::s_editorEntityContextId = AzFramework::EntityContextId::CreateNull();
ContainerEntityInterface* PrefabIntegrationManager::s_containerEntityInterface = nullptr;
EditorEntityUiInterface* PrefabIntegrationManager::s_editorEntityUiInterface = nullptr;
PrefabFocusPublicInterface* PrefabIntegrationManager::s_prefabFocusPublicInterface = nullptr;
@@ -136,6 +140,9 @@ namespace AzToolsFramework
return;
}
// Get EditorEntityContextId
EditorEntityContextRequestBus::BroadcastResult(s_editorEntityContextId, &EditorEntityContextRequests::GetEditorEntityContextId);
// Initialize Editor functionality for the Prefab Focus Handler
auto prefabFocusInterface = AZ::Interface<PrefabFocusInterface>::Get();
prefabFocusInterface->InitializeEditorInterfaces();
@@ -145,10 +152,16 @@ namespace AzToolsFramework
PrefabInstanceContainerNotificationBus::Handler::BusConnect();
AZ::Interface<PrefabIntegrationInterface>::Register(this);
AssetBrowser::AssetBrowserSourceDropBus::Handler::BusConnect(s_prefabFileExtension);
EditorEntityContextNotificationBus::Handler::BusConnect();
InitializeShortcuts();
}
PrefabIntegrationManager::~PrefabIntegrationManager()
{
UninitializeShortcuts();
EditorEntityContextNotificationBus::Handler::BusDisconnect();
AssetBrowser::AssetBrowserSourceDropBus::Handler::BusDisconnect();
AZ::Interface<PrefabIntegrationInterface>::Unregister(this);
PrefabInstanceContainerNotificationBus::Handler::BusDisconnect();
@@ -161,6 +174,74 @@ namespace AzToolsFramework
PrefabUserSettings::Reflect(context);
}
void PrefabIntegrationManager::InitializeShortcuts()
{
// Open/Edit Prefab (+)
// We also support = to enable easier editing on compact US keyboards.
{
m_actions.emplace_back(AZStd::make_unique<QAction>(nullptr));
m_actions.back()->setShortcuts({ QKeySequence(Qt::Key_Plus), QKeySequence(Qt::Key_Equal) });
m_actions.back()->setText("Open/Edit Prefab");
m_actions.back()->setStatusTip("Edit the prefab in focus mode.");
QObject::connect(
m_actions.back().get(), &QAction::triggered, m_actions.back().get(),
[]
{
AzToolsFramework::EntityIdList selectedEntities;
AzToolsFramework::ToolsApplicationRequestBus::BroadcastResult(
selectedEntities, &AzToolsFramework::ToolsApplicationRequests::GetSelectedEntities);
if (selectedEntities.size() != 1)
{
return;
}
AZ::EntityId selectedEntity = selectedEntities[0];
if (!s_prefabPublicInterface->IsInstanceContainerEntity(selectedEntity))
{
return;
}
if (!s_prefabFocusPublicInterface->IsOwningPrefabBeingFocused(selectedEntity))
{
ContextMenu_EditPrefab(selectedEntity);
}
});
EditorActionRequestBus::Broadcast(
&EditorActionRequests::AddActionViaBusCrc, AZ_CRC_CE("com.o3de.action.editortransform.prefabopen"),
m_actions.back().get());
}
// Close Prefab (-)
{
m_actions.emplace_back(AZStd::make_unique<QAction>(nullptr));
m_actions.back()->setShortcuts({ QKeySequence(Qt::Key_Minus) });
m_actions.back()->setText("Close Prefab");
m_actions.back()->setStatusTip("Close focus mode for this prefab and move one level up.");
QObject::connect(
m_actions.back().get(), &QAction::triggered, m_actions.back().get(),
[]
{
ContextMenu_ClosePrefab();
});
EditorActionRequestBus::Broadcast(
&EditorActionRequests::AddActionViaBusCrc, AZ_CRC_CE("com.o3de.action.editortransform.prefabclose"),
m_actions.back().get());
}
}
void PrefabIntegrationManager::UninitializeShortcuts()
{
m_actions.clear();
}
int PrefabIntegrationManager::GetMenuPosition() const
{
return aznumeric_cast<int>(EditorContextMenuOrdering::MIDDLE);
@@ -181,16 +262,13 @@ namespace AzToolsFramework
AzFramework::ApplicationRequests::Bus::BroadcastResult(
prefabWipFeaturesEnabled, &AzFramework::ApplicationRequests::ArePrefabWipFeaturesEnabled);
auto editorEntityContextId = AzFramework::EntityContextId::CreateNull();
EditorEntityContextRequestBus::BroadcastResult(editorEntityContextId, &EditorEntityContextRequests::GetEditorEntityContextId);
// Create Prefab
{
if (!selectedEntities.empty())
{
// Hide if the only selected entity is the Focused Instance Container
if (selectedEntities.size() > 1 ||
selectedEntities[0] != s_prefabFocusPublicInterface->GetFocusedPrefabContainerEntityId(editorEntityContextId))
selectedEntities[0] != s_prefabFocusPublicInterface->GetFocusedPrefabContainerEntityId(s_editorEntityContextId))
{
bool layerInSelection = false;
@@ -254,17 +332,30 @@ namespace AzToolsFramework
if (s_prefabPublicInterface->IsInstanceContainerEntity(selectedEntity))
{
// Edit Prefab
if (!s_prefabFocusPublicInterface->IsOwningPrefabBeingFocused(selectedEntity))
{
QAction* editAction = menu->addAction(QObject::tr("Edit Prefab"));
// Edit Prefab
QAction* editAction = menu->addAction(QObject::tr("Open/Edit Prefab"));
editAction->setShortcut(QKeySequence(Qt::Key_Plus));
editAction->setToolTip(QObject::tr("Edit the prefab in focus mode."));
QObject::connect(editAction, &QAction::triggered, editAction, [selectedEntity] {
ContextMenu_EditPrefab(selectedEntity);
});
}
else
{
// Close Prefab
QAction* closeAction = menu->addAction(QObject::tr("Close Prefab"));
closeAction->setShortcut(QKeySequence(Qt::Key_Minus));
closeAction->setToolTip(QObject::tr("Close focus mode for this prefab and move one level up."));
itemWasShown = true;
QObject::connect(
closeAction, &QAction::triggered, closeAction,
[]
{
ContextMenu_ClosePrefab();
});
}
// Save Prefab
@@ -279,9 +370,9 @@ namespace AzToolsFramework
QObject::connect(saveAction, &QAction::triggered, saveAction, [selectedEntity] {
ContextMenu_SavePrefab(selectedEntity);
});
itemWasShown = true;
}
itemWasShown = true;
}
}
}
@@ -295,7 +386,8 @@ namespace AzToolsFramework
QObject::connect(deleteAction, &QAction::triggered, deleteAction, [] { ContextMenu_DeleteSelected(); });
if (selectedEntities.empty() ||
(selectedEntities.size() == 1 && selectedEntities[0] == s_prefabFocusPublicInterface->GetFocusedPrefabContainerEntityId(editorEntityContextId)))
(selectedEntities.size() == 1 &&
selectedEntities[0] == s_prefabFocusPublicInterface->GetFocusedPrefabContainerEntityId(s_editorEntityContextId)))
{
deleteAction->setDisabled(true);
}
@@ -306,7 +398,7 @@ namespace AzToolsFramework
AZ::EntityId selectedEntityId = selectedEntities[0];
if (s_prefabPublicInterface->IsInstanceContainerEntity(selectedEntityId) &&
selectedEntityId != s_prefabFocusPublicInterface->GetFocusedPrefabContainerEntityId(editorEntityContextId))
selectedEntityId != s_prefabFocusPublicInterface->GetFocusedPrefabContainerEntityId(s_editorEntityContextId))
{
QAction* detachPrefabAction = menu->addAction(QObject::tr("Detach Prefab..."));
QObject::connect(
@@ -334,6 +426,24 @@ namespace AzToolsFramework
}
}
void PrefabIntegrationManager::OnStartPlayInEditorBegin()
{
// Focus on the root prefab (AZ::EntityId() will default to it)
s_prefabFocusPublicInterface->FocusOnOwningPrefab(AZ::EntityId());
}
void PrefabIntegrationManager::OnStopPlayInEditor()
{
// Refresh all containers when leaving Game Mode to ensure everything is synced.
QTimer::singleShot(
0,
[&]()
{
s_containerEntityInterface->RefreshAllContainerEntities(s_editorEntityContextId);
}
);
}
void PrefabIntegrationManager::ContextMenu_CreatePrefab(AzToolsFramework::EntityIdList selectedEntities)
{
// Save a reference to our currently active window since it will be
@@ -343,12 +453,9 @@ namespace AzToolsFramework
const AZStd::string prefabFilesPath = "@projectroot@/Prefabs";
// Remove focused instance container entity if it's part of the list
auto editorEntityContextId = AzFramework::EntityContextId::CreateNull();
EditorEntityContextRequestBus::BroadcastResult(editorEntityContextId, &EditorEntityContextRequests::GetEditorEntityContextId);
auto focusedContainerIter = AZStd::find(
selectedEntities.begin(), selectedEntities.end(),
s_prefabFocusPublicInterface->GetFocusedPrefabContainerEntityId(editorEntityContextId));
s_prefabFocusPublicInterface->GetFocusedPrefabContainerEntityId(s_editorEntityContextId));
if (focusedContainerIter != selectedEntities.end())
{
selectedEntities.erase(focusedContainerIter);
@@ -500,6 +607,11 @@ namespace AzToolsFramework
}
}
void PrefabIntegrationManager::ContextMenu_ClosePrefab()
{
s_prefabFocusPublicInterface->FocusOnParentOfFocusedPrefab(s_editorEntityContextId);
}
void PrefabIntegrationManager::ContextMenu_EditPrefab(AZ::EntityId containerEntity)
{
s_prefabFocusPublicInterface->FocusOnOwningPrefab(containerEntity);
@@ -14,6 +14,7 @@
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
#include <AzToolsFramework/AssetBrowser/AssetBrowserSourceDropBus.h>
#include <AzToolsFramework/Editor/EditorContextMenuBus.h>
#include <AzToolsFramework/Entity/EditorEntityContextBus.h>
#include <AzToolsFramework/Prefab/PrefabPublicInterface.h>
#include <AzToolsFramework/Prefab/PrefabSystemComponentInterface.h>
#include <AzToolsFramework/UI/Prefab/LevelRootUiHandler.h>
@@ -56,6 +57,7 @@ namespace AzToolsFramework
, public PrefabInstanceContainerNotificationBus::Handler
, public PrefabIntegrationInterface
, public QObject
, private EditorEntityContextNotificationBus::Handler
{
public:
AZ_CLASS_ALLOCATOR(PrefabIntegrationManager, AZ::SystemAllocator, 0);
@@ -76,6 +78,10 @@ namespace AzToolsFramework
// EntityOutlinerSourceDropHandlingBus overrides ...
void HandleSourceFileType(AZStd::string_view sourceFilePath, AZ::EntityId parentId, AZ::Vector3 position) const override;
// EditorEntityContextNotificationBus overrides ...
void OnStartPlayInEditorBegin() override;
void OnStopPlayInEditor() override;
// PrefabInstanceContainerNotificationBus overrides ...
void OnPrefabComponentActivate(AZ::EntityId entityId) override;
void OnPrefabComponentDeactivate(AZ::EntityId entityId) override;
@@ -96,11 +102,16 @@ namespace AzToolsFramework
static void ContextMenu_CreatePrefab(AzToolsFramework::EntityIdList selectedEntities);
static void ContextMenu_InstantiatePrefab();
static void ContextMenu_InstantiateProceduralPrefab();
static void ContextMenu_ClosePrefab();
static void ContextMenu_EditPrefab(AZ::EntityId containerEntity);
static void ContextMenu_SavePrefab(AZ::EntityId containerEntity);
static void ContextMenu_DeleteSelected();
static void ContextMenu_DetachPrefab(AZ::EntityId containerEntity);
// Shortcut setup handlers
void InitializeShortcuts();
void UninitializeShortcuts();
// Prompt and resolve dialogs
static bool QueryUserForPrefabSaveLocation(
const AZStd::string& suggestedName, const char* initialTargetDirectory, AZ::u32 prefabUserSettingsId, QWidget* activeWindow,
@@ -140,7 +151,10 @@ namespace AzToolsFramework
AZStd::unique_ptr<QDialog> ConstructSavePrefabDialog(TemplateId templateId, bool useSaveAllPrefabsPreference);
void SavePrefabsInDialog(QDialog* unsavedPrefabsDialog);
AZStd::vector<AZStd::unique_ptr<QAction>> m_actions;
static const AZStd::string s_prefabFileExtension;
static AzFramework::EntityContextId s_editorEntityContextId;
static ContainerEntityInterface* s_containerEntityInterface;
static EditorEntityUiInterface* s_editorEntityUiInterface;
@@ -21,6 +21,8 @@
namespace AzToolsFramework
{
AzFramework::EntityContextId PrefabUiHandler::s_editorEntityContextId = AzFramework::EntityContextId::CreateNull();
const QColor PrefabUiHandler::m_backgroundColor = QColor("#444444");
const QColor PrefabUiHandler::m_backgroundHoverColor = QColor("#5A5A5A");
const QColor PrefabUiHandler::m_backgroundSelectedColor = QColor("#656565");
@@ -47,6 +49,9 @@ namespace AzToolsFramework
AZ_Assert(false, "PrefabUiHandler - could not get PrefabFocusPublicInterface on PrefabUiHandler construction.");
return;
}
// Get EditorEntityContextId
EditorEntityContextRequestBus::BroadcastResult(s_editorEntityContextId, &EditorEntityContextRequests::GetEditorEntityContextId);
}
QString PrefabUiHandler::GenerateItemInfoString(AZ::EntityId entityId) const
@@ -180,7 +185,7 @@ namespace AzToolsFramework
painter->restore();
}
void PrefabUiHandler::PaintDescendantBackground(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index,
void PrefabUiHandler::PaintDescendantForeground(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index,
const QModelIndex& descendantIndex) const
{
if (!painter)
@@ -425,19 +430,23 @@ namespace AzToolsFramework
if (m_prefabFocusPublicInterface->IsOwningPrefabBeingFocused(entityId))
{
auto editorEntityContextId = AzFramework::EntityContextId::CreateNull();
EditorEntityContextRequestBus::BroadcastResult(editorEntityContextId, &EditorEntityContextRequests::GetEditorEntityContextId);
// Go one level up.
int length = m_prefabFocusPublicInterface->GetPrefabFocusPathLength(editorEntityContextId);
m_prefabFocusPublicInterface->FocusOnPathIndex(editorEntityContextId, length - 2);
// Close this prefab and focus on the parent
m_prefabFocusPublicInterface->FocusOnParentOfFocusedPrefab(s_editorEntityContextId);
}
}
bool PrefabUiHandler::OnEntityDoubleClick(AZ::EntityId entityId) const
{
// Focus on this prefab
m_prefabFocusPublicInterface->FocusOnOwningPrefab(entityId);
if (!m_prefabFocusPublicInterface->IsOwningPrefabBeingFocused(entityId))
{
// Focus on this prefab
m_prefabFocusPublicInterface->FocusOnOwningPrefab(entityId);
}
else
{
// Close this prefab and focus on the parent
m_prefabFocusPublicInterface->FocusOnParentOfFocusedPrefab(s_editorEntityContextId);
}
// Don't propagate event.
return true;
@@ -10,6 +10,8 @@
#include <AzToolsFramework/UI/EditorEntityUi/EditorEntityUiHandlerBase.h>
#include <AzFramework/Entity/EntityContextBus.h>
namespace AzToolsFramework
{
@@ -34,9 +36,12 @@ namespace AzToolsFramework
QString GenerateItemTooltip(AZ::EntityId entityId) const override;
QIcon GenerateItemIcon(AZ::EntityId entityId) const override;
void PaintItemBackground(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const override;
void PaintDescendantBackground(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index,
const QModelIndex& descendantIndex) const override;
void PaintItemForeground(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const override;
void PaintDescendantForeground(
QPainter* painter,
const QStyleOptionViewItem& option,
const QModelIndex& index,
const QModelIndex& descendantIndex) const override;
bool OnOutlinerItemClick(const QPoint& position, const QStyleOptionViewItem& option, const QModelIndex& index) const override;
void OnOutlinerItemCollapse(const QModelIndex& index) const override;
bool OnEntityDoubleClick(AZ::EntityId entityId) const override;
@@ -49,6 +54,8 @@ namespace AzToolsFramework
static QModelIndex GetLastVisibleChild(const QModelIndex& parent);
static QModelIndex Internal_GetLastVisibleChild(const QAbstractItemModel* model, const QModelIndex& index);
static AzFramework::EntityContextId s_editorEntityContextId;
static constexpr int m_prefabCapsuleRadius = 6;
static constexpr int m_prefabBorderThickness = 2;
static const QColor m_backgroundColor;
@@ -59,12 +59,11 @@ namespace AzToolsFramework::Prefab
connect(m_backButton, &QToolButton::clicked, this,
[&]()
{
if (int length = m_prefabFocusPublicInterface->GetPrefabFocusPathLength(m_editorEntityContextId); length > 1)
{
m_prefabFocusPublicInterface->FocusOnPathIndex(m_editorEntityContextId, length - 2);
}
m_prefabFocusPublicInterface->FocusOnParentOfFocusedPrefab(m_editorEntityContextId);
}
);
m_backButton->setToolTip("Up one level (-)");
}
void PrefabViewportFocusPathHandler::OnPrefabFocusChanged()
@@ -12,6 +12,7 @@
#include <AzToolsFramework/ViewportSelection/EditorSelectionUtil.h>
#include <AzToolsFramework/ViewportUi/ViewportUiCluster.h>
#include <AzToolsFramework/ViewportUi/ViewportUiDisplay.h>
#include <AzToolsFramework/ViewportUi/ViewportUiDisplayLayout.h>
#include <AzToolsFramework/ViewportUi/ViewportUiSwitcher.h>
#include <AzToolsFramework/ViewportUi/ViewportUiTextField.h>
#include <QWidget>
@@ -19,7 +20,6 @@
namespace AzToolsFramework::ViewportUi::Internal
{
const static int HighlightBorderSize = 5;
const static int TopHighlightBorderSize = 25;
const static char* HighlightBorderColor = "#4A90E2";
static void UnparentWidgets(ViewportUiElementIdInfoLookup& viewportUiElementIdInfoLookup)
@@ -61,7 +61,7 @@ namespace AzToolsFramework::ViewportUi::Internal
, m_uiOverlay(parent)
, m_fullScreenLayout(&m_uiOverlay)
, m_uiOverlayLayout()
, m_componentModeBorderText(&m_uiOverlay)
, m_viewportBorderText(&m_uiOverlay)
{
}
@@ -221,11 +221,11 @@ namespace AzToolsFramework::ViewportUi::Internal
AZStd::shared_ptr<QWidget> ViewportUiDisplay::GetViewportUiElement(ViewportUiElementId elementId)
{
auto element = m_viewportUiElements.find(elementId);
if (element != m_viewportUiElements.end())
if (auto element = m_viewportUiElements.find(elementId); element != m_viewportUiElements.end())
{
return element->second.m_widget;
}
return nullptr;
}
@@ -287,27 +287,30 @@ namespace AzToolsFramework::ViewportUi::Internal
{
return element.IsValid() && element.m_widget->isVisible();
}
return false;
}
void ViewportUiDisplay::CreateViewportBorder(const AZStd::string& borderTitle)
{
const AZStd::string styleSheet = AZStd::string::format(
"border: %dpx solid %s; border-top: %dpx solid %s;", HighlightBorderSize, HighlightBorderColor, TopHighlightBorderSize,
"border: %dpx solid %s; border-top: %dpx solid %s;", HighlightBorderSize, HighlightBorderColor, ViewportUiTopBorderSize,
HighlightBorderColor);
m_uiOverlay.setStyleSheet(styleSheet.c_str());
m_uiOverlayLayout.setContentsMargins(
HighlightBorderSize + ViewportUiOverlayMargin, TopHighlightBorderSize + ViewportUiOverlayMargin,
HighlightBorderSize + ViewportUiOverlayMargin, ViewportUiTopBorderSize + ViewportUiOverlayMargin,
HighlightBorderSize + ViewportUiOverlayMargin, HighlightBorderSize + ViewportUiOverlayMargin);
m_componentModeBorderText.setVisible(true);
m_componentModeBorderText.setText(borderTitle.c_str());
m_viewportBorderText.setVisible(true);
m_viewportBorderText.setText(borderTitle.c_str());
}
void ViewportUiDisplay::RemoveViewportBorder()
{
m_componentModeBorderText.setVisible(false);
m_viewportBorderText.setVisible(false);
m_uiOverlay.setStyleSheet("border: none;");
m_uiOverlayLayout.setMargin(ViewportUiOverlayMargin);
m_uiOverlayLayout.setContentsMargins(
ViewportUiOverlayMargin, ViewportUiOverlayMargin + ViewportUiOverlayTopMarginPadding, ViewportUiOverlayMargin,
ViewportUiOverlayMargin);
}
void ViewportUiDisplay::PositionViewportUiElementFromWorldSpace(ViewportUiElementId elementId, const AZ::Vector3& pos)
@@ -359,10 +362,10 @@ namespace AzToolsFramework::ViewportUi::Internal
// format the label which will appear on top of the highlight border
AZStd::string styleSheet = AZStd::string::format("background-color: %s; border: none;", HighlightBorderColor);
m_componentModeBorderText.setStyleSheet(styleSheet.c_str());
m_componentModeBorderText.setFixedHeight(TopHighlightBorderSize);
m_componentModeBorderText.setVisible(false);
m_fullScreenLayout.addWidget(&m_componentModeBorderText, 0, 0, Qt::AlignTop | Qt::AlignHCenter);
m_viewportBorderText.setStyleSheet(styleSheet.c_str());
m_viewportBorderText.setFixedHeight(ViewportUiTopBorderSize);
m_viewportBorderText.setVisible(false);
m_fullScreenLayout.addWidget(&m_viewportBorderText, 0, 0, Qt::AlignTop | Qt::AlignHCenter);
}
void ViewportUiDisplay::PrepareWidgetForViewportUi(QPointer<QWidget> widget)
@@ -395,14 +398,14 @@ namespace AzToolsFramework::ViewportUi::Internal
void ViewportUiDisplay::UpdateUiOverlayGeometry()
{
// add the component mode border region if visible
// add the viewport border region if visible
QRegion region;
if (m_componentModeBorderText.isVisible())
if (m_viewportBorderText.isVisible())
{
// get the border region by taking the entire region and subtracting the non-border area
region += m_uiOverlay.rect();
region -= QRect(
QPoint(m_uiOverlay.rect().left() + HighlightBorderSize, m_uiOverlay.rect().top() + TopHighlightBorderSize),
QPoint(m_uiOverlay.rect().left() + HighlightBorderSize, m_uiOverlay.rect().top() + ViewportUiTopBorderSize),
QPoint(m_uiOverlay.rect().right() - HighlightBorderSize, m_uiOverlay.rect().bottom() - HighlightBorderSize));
}
@@ -113,7 +113,7 @@ namespace AzToolsFramework::ViewportUi::Internal
QWidget m_uiOverlay; //!< The UI Overlay which displays Viewport UI Elements.
QGridLayout m_fullScreenLayout; //!< The layout which extends across the full screen.
ViewportUiDisplayLayout m_uiOverlayLayout; //!< The layout used for optionally anchoring Viewport UI Elements.
QLabel m_componentModeBorderText; //!< The text used for the Component Mode border.
QLabel m_viewportBorderText; //!< The text used for the viewport border.
QWidget* m_renderOverlay;
QPointer<QWidget> m_fullScreenWidget; //!< Reference to the widget attached to m_fullScreenLayout if any.
@@ -14,13 +14,20 @@
#include <QGridLayout>
#include <QPointer>
namespace AzToolsFramework::ViewportUi
{
//! Margin for the Viewport UI Overlay (in pixels)
constexpr int ViewportUiOverlayMargin = 5;
//! Padding to make space for ImGui (in pixels)
constexpr int ViewportUiOverlayTopMarginPadding = 20;
//! Size of the top viewport border (in pixels)
constexpr int ViewportUiTopBorderSize = 25;
//! Size of the left, right and bottom viewport border (in pixels)
constexpr int ViewportUiLeftRightBottomBorderSize = 5;
} // namespace AzToolsFramework::ViewportUi
namespace AzToolsFramework::ViewportUi::Internal
{
// margin for the Viewport UI Overlay in pixels
constexpr int ViewportUiOverlayMargin = 5;
// padding to make space for ImGui
constexpr int ViewportUiOverlayTopMarginPadding = 20;
//! QGridLayout implementation that uses a grid of QVBox/QHBoxLayouts internally to stack widgets.
class ViewportUiDisplayLayout : public QGridLayout
{
@@ -57,9 +57,7 @@ namespace UnitTest
ArgumentContainer argContainer{ {} };
// Append Command Line override for the Project Cache Path
auto projectCachePathOverride = FixedValueString::format(R"(--project-cache-path="%s")", m_tempDir.GetDirectory());
auto projectPathOverride = FixedValueString{ R"(--project-path=AutomatedTesting)" };
argContainer.push_back(projectCachePathOverride.data());
auto projectPathOverride = FixedValueString::format(R"(--project-path="%s")", m_tempDir.GetDirectory());
argContainer.push_back(projectPathOverride.data());
m_application = new ToolsTestApplication("AssetFileInfoListComparisonTest", aznumeric_caster(argContainer.size()), argContainer.data());
AzToolsFramework::AssetSeedManager assetSeedManager;
@@ -100,7 +98,7 @@ namespace UnitTest
m_application->Start(AzFramework::Application::Descriptor());
// Without this, the user settings component would attempt to save on finalize/shutdown. Since the file is
// shared across the whole engine, if multiple tests are run in parallel, the saving could cause a crash
// shared across the whole engine, if multiple tests are run in parallel, the saving could cause a crash
// in the unit tests.
AZ::UserSettingsComponentRequestBus::Broadcast(&AZ::UserSettingsComponentRequests::DisableSaveOnFinalize);
@@ -223,7 +221,7 @@ namespace UnitTest
// AssetFileInfo should contain {2*, 4*, 5}
AzToolsFramework::AssetFileInfoList assetFileInfoList;
ASSERT_TRUE(AZ::Utils::LoadObjectFromFileInPlace(TempFiles[FileIndex::ResultAssetFileInfoList], assetFileInfoList)) << "Unable to read the asset file info list.\n";
EXPECT_EQ(assetFileInfoList.m_fileInfoList.size(), 3);
@@ -256,7 +254,7 @@ namespace UnitTest
}
}
// Verifying that correct assetId are present in the assetFileInfo list
// Verifying that correct assetId are present in the assetFileInfo list
AZStd::unordered_set<AZ::Data::AssetId> expectedAssetIds{ m_assets[2], m_assets[4], m_assets[5] };
for (const AzToolsFramework::AssetFileInfo& assetFileInfo : assetFileInfoList.m_fileInfoList)
@@ -298,7 +296,7 @@ namespace UnitTest
{
firstAssetIdToAssetFileInfoMap[assetFileInfo.m_assetId] = AZStd::move(assetFileInfo);
}
AzToolsFramework::AssetFileInfoList secondAssetFileInfoList;
ASSERT_TRUE(AZ::Utils::LoadObjectFromFileInPlace(TempFiles[FileIndex::SecondAssetFileInfoList], secondAssetFileInfoList)) << "Unable to read the asset file info list.\n";
@@ -315,7 +313,7 @@ namespace UnitTest
auto foundSecond = secondAssetIdToAssetFileInfoMap.find(assetFileInfo.m_assetId);
if (foundSecond != secondAssetIdToAssetFileInfoMap.end())
{
// Even if the asset Id is present in both the AssetFileInfo List, it should match the file hash from the second AssetFileInfo list
// Even if the asset Id is present in both the AssetFileInfo List, it should match the file hash from the second AssetFileInfo list
for (int idx = 0; idx < AzToolsFramework::AssetFileInfo::s_arraySize; idx++)
{
if (foundSecond->second.m_hash[idx] != assetFileInfo.m_hash[idx])
@@ -343,7 +341,7 @@ namespace UnitTest
}
}
// Verifying that correct assetId are present in the assetFileInfo list
// Verifying that correct assetId are present in the assetFileInfo list
AZStd::unordered_set<AZ::Data::AssetId> expectedAssetIds{ m_assets[0], m_assets[1], m_assets[2], m_assets[3], m_assets[4], m_assets[5] };
for (const AzToolsFramework::AssetFileInfo& assetFileInfo : assetFileInfoList.m_fileInfoList)
@@ -403,7 +401,7 @@ namespace UnitTest
}
}
// Verifying that correct assetId are present in the assetFileInfo list
// Verifying that correct assetId are present in the assetFileInfo list
AZStd::unordered_set<AZ::Data::AssetId> expectedAssetIds{ m_assets[1], m_assets[2], m_assets[3], m_assets[4] };
for (const AzToolsFramework::AssetFileInfo& assetFileInfo : assetFileInfoList.m_fileInfoList)
@@ -462,7 +460,7 @@ namespace UnitTest
}
}
// Verifying that correct assetId are present in the assetFileInfo list
// Verifying that correct assetId are present in the assetFileInfo list
AZStd::unordered_set<AZ::Data::AssetId> expectedAssetIds{ m_assets[5] };
for (const AzToolsFramework::AssetFileInfo& assetFileInfo : assetFileInfoList.m_fileInfoList)
@@ -493,7 +491,7 @@ namespace UnitTest
EXPECT_EQ(assetFileInfoList.m_fileInfoList.size(), 5);
// Verifying that correct assetId are present in the assetFileInfo list
// Verifying that correct assetId are present in the assetFileInfo list
AZStd::unordered_set<AZ::Data::AssetId> expectedAssetIds{ m_assets[0], m_assets[1], m_assets[2], m_assets[3], m_assets[4] };
for (const AzToolsFramework::AssetFileInfo& assetFileInfo : assetFileInfoList.m_fileInfoList)
@@ -601,7 +599,7 @@ namespace UnitTest
}
}
// Verifying that correct assetId are present in the assetFileInfo list
// Verifying that correct assetId are present in the assetFileInfo list
AZStd::unordered_set<AZ::Data::AssetId> expectedAssetIds{ m_assets[2] };
for (const AzToolsFramework::AssetFileInfo& assetFileInfo : assetFileInfoList.m_fileInfoList)
@@ -625,12 +623,12 @@ namespace UnitTest
AssetFileInfoListComparison::ComparisonData filePatternComparisonData(AssetFileInfoListComparison::ComparisonType::FilePattern,"$1", "Asset[0-3].txt", AssetFileInfoListComparison::FilePatternType::Regex);
filePatternComparisonData.m_firstInput = TempFiles[FileIndex::FirstAssetFileInfoList];
assetFileInfoListComparison.AddComparisonStep(filePatternComparisonData);
AzToolsFramework::AssetFileInfoListComparison::ComparisonData deltaComparisonData(AzToolsFramework::AssetFileInfoListComparison::ComparisonType::Delta, TempFiles[FileIndex::ResultAssetFileInfoList]);
deltaComparisonData.m_firstInput = "$1";
deltaComparisonData.m_secondInput = TempFiles[FileIndex::SecondAssetFileInfoList];
assetFileInfoListComparison.AddComparisonStep(deltaComparisonData);
ASSERT_TRUE(assetFileInfoListComparison.CompareAndSaveResults().IsSuccess()) << "Multiple Comparison Operation( FilePattern + Delta ) failed.\n";
// Output of the FilePattern Operation should be {0,1,2,3}
// Output of the Delta Operation should be {2*,4*,5}
@@ -666,7 +664,7 @@ namespace UnitTest
}
}
// Verifying that correct assetId are present in the assetFileInfo list
// Verifying that correct assetId are present in the assetFileInfo list
AZStd::unordered_set<AZ::Data::AssetId> expectedAssetIds{ m_assets[2], m_assets[4], m_assets[5] };
for (const AzToolsFramework::AssetFileInfo& assetFileInfo : assetFileInfoList.m_fileInfoList)
@@ -738,7 +736,7 @@ namespace UnitTest
}
}
// Verifying that correct assetId are present in the assetFileInfo list
// Verifying that correct assetId are present in the assetFileInfo list
AZStd::unordered_set<AZ::Data::AssetId> expectedAssetIds{ m_assets[4], m_assets[5] };
for (const AzToolsFramework::AssetFileInfo& assetFileInfo : assetFileInfoList.m_fileInfoList)
@@ -63,10 +63,8 @@ namespace UnitTest
ArgumentContainer argContainer{ {} };
// Append Command Line override for the Project Cache Path
AZ::IO::Path cacheProjectRootFolder{ m_tempDir.GetDirectory() };
auto projectCachePathOverride = FixedValueString::format(R"(--project-cache-path="%s")", cacheProjectRootFolder.c_str());
auto projectPathOverride = FixedValueString{ R"(--project-path=AutomatedTesting)" };
argContainer.push_back(projectCachePathOverride.data());
auto cacheProjectRootFolder = AZ::IO::Path{ m_tempDir.GetDirectory() } / "Cache";
auto projectPathOverride = FixedValueString::format(R"(--project-path="%s")", m_tempDir.GetDirectory());
argContainer.push_back(projectPathOverride.data());
m_application = new ToolsTestApplication("AssetSeedManagerTest", aznumeric_caster(argContainer.size()), argContainer.data());
m_assetSeedManager = new AzToolsFramework::AssetSeedManager();
@@ -572,7 +572,9 @@ namespace UnitTest
AZ::SettingsRegistryInterface* registry = AZ::SettingsRegistry::Get();
auto projectPathKey =
AZ::SettingsRegistryInterface::FixedValueString(AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey) + "/project_path";
registry->Set(projectPathKey, "AutomatedTesting");
AZ::IO::FixedMaxPath enginePath;
registry->Get(enginePath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_EngineRootFolder);
registry->Set(projectPathKey, (enginePath / "AutomatedTesting").Native());
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddRuntimeFilePaths(*registry);
AzFramework::Application::Descriptor descriptor;
@@ -59,7 +59,9 @@ protected:
AZ::SettingsRegistryInterface* registry = AZ::SettingsRegistry::Get();
auto projectPathKey =
AZ::SettingsRegistryInterface::FixedValueString(AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey) + "/project_path";
registry->Set(projectPathKey, "AutomatedTesting");
AZ::IO::FixedMaxPath enginePath;
registry->Get(enginePath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_EngineRootFolder);
registry->Set(projectPathKey, (enginePath / "AutomatedTesting").Native());
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddRuntimeFilePaths(*registry);
m_app.Start(AZ::ComponentApplication::Descriptor());
@@ -184,7 +186,9 @@ public:
AZ::SettingsRegistryInterface* registry = AZ::SettingsRegistry::Get();
auto projectPathKey =
AZ::SettingsRegistryInterface::FixedValueString(AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey) + "/project_path";
registry->Set(projectPathKey, "AutomatedTesting");
AZ::IO::FixedMaxPath enginePath;
registry->Get(enginePath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_EngineRootFolder);
registry->Set(projectPathKey, (enginePath / "AutomatedTesting").Native());
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddRuntimeFilePaths(*registry);
m_app.Start(AzFramework::Application::Descriptor());
@@ -44,10 +44,8 @@ namespace UnitTest
ArgumentContainer argContainer{ {} };
// Append Command Line override for the Project Cache Path
AZ::IO::Path cacheProjectRootFolder{ m_tempDir.GetDirectory() };
auto projectCachePathOverride = FixedValueString::format(R"(--project-cache-path="%s")", cacheProjectRootFolder.c_str());
auto projectPathOverride = FixedValueString{ R"(--project-path=AutomatedTesting)" };
argContainer.push_back(projectCachePathOverride.data());
auto cacheProjectRootFolder = AZ::IO::Path{ m_tempDir.GetDirectory() } / "Cache";
auto projectPathOverride = FixedValueString::format(R"(--project-path="%s")", m_tempDir.GetDirectory());
argContainer.push_back(projectPathOverride.data());
m_application = new ToolsTestApplication("AddressedAssetCatalogManager", aznumeric_caster(argContainer.size()), argContainer.data());
@@ -195,10 +193,7 @@ namespace UnitTest
ArgumentContainer argContainer{ {} };
// Append Command Line override for the Project Cache Path
AZ::IO::Path cacheProjectRootFolder{ m_tempDir.GetDirectory() };
auto projectCachePathOverride = FixedValueString::format(R"(--project-cache-path="%s")", cacheProjectRootFolder.c_str());
auto projectPathOverride = FixedValueString{ R"(--project-path=AutomatedTesting)" };
argContainer.push_back(projectCachePathOverride.data());
auto projectPathOverride = FixedValueString::format(R"(--project-path="%s")", m_tempDir.GetDirectory());
argContainer.push_back(projectPathOverride.data());
m_application = new ToolsTestApplication("MessageTest", aznumeric_caster(argContainer.size()), argContainer.data());
@@ -1059,7 +1059,9 @@ namespace UnitTest
AZ::SettingsRegistryInterface* registry = AZ::SettingsRegistry::Get();
auto projectPathKey =
AZ::SettingsRegistryInterface::FixedValueString(AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey) + "/project_path";
registry->Set(projectPathKey, "AutomatedTesting");
AZ::IO::FixedMaxPath enginePath;
registry->Get(enginePath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_EngineRootFolder);
registry->Set(projectPathKey, (enginePath / "AutomatedTesting").Native());
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddRuntimeFilePaths(*registry);
m_app.Start(AzFramework::Application::Descriptor());