Merge branch 'development' into LYN-5265_state_tracker_impl
This commit is contained in:
@@ -47,14 +47,6 @@ namespace AzToolsFramework
|
||||
|
||||
//! Retrieve the absolute path for the Asset Database Location
|
||||
virtual bool GetAbsoluteAssetDatabaseLocation(AZStd::string& /*result*/) { return false; }
|
||||
|
||||
//! Retrieve the absolute folder path to the current game's source assets (the ones that go into source control)
|
||||
//! This may include the current mod path, if a mod is being edited by the editor
|
||||
virtual const char* GetAbsoluteDevGameFolderPath() = 0;
|
||||
|
||||
//! Retrieve the absolute folder path to the current developer root ('dev'), which contains source artifacts
|
||||
//! and is generally checked into source control.
|
||||
virtual const char* GetAbsoluteDevRootFolderPath() = 0;
|
||||
|
||||
/// Convert a full source path like "c:\\dev\\gamename\\blah\\test.tga" into a relative product path.
|
||||
/// asset paths never mention their alias and are relative to the asset cache root
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <AzToolsFramework/ToolsComponents/EditorAssetMimeDataContainer.h>
|
||||
#include <AzToolsFramework/ToolsComponents/ComponentAssetMimeDataContainer.h>
|
||||
#include <AzToolsFramework/ToolsComponents/TransformComponent.h>
|
||||
#include <AzToolsFramework/ContainerEntity/ContainerEntitySystemComponent.h>
|
||||
#include <AzToolsFramework/Entity/EditorEntityContextComponent.h>
|
||||
#include <AzToolsFramework/Entity/EditorEntityInfoBus.h>
|
||||
#include <AzToolsFramework/FocusMode/FocusModeSystemComponent.h>
|
||||
@@ -251,6 +252,7 @@ namespace AzToolsFramework
|
||||
azrtti_typeid<EditorEntityContextComponent>(),
|
||||
azrtti_typeid<Components::EditorEntityUiSystemComponent>(),
|
||||
azrtti_typeid<FocusModeSystemComponent>(),
|
||||
azrtti_typeid<ContainerEntitySystemComponent>(),
|
||||
azrtti_typeid<SliceMetadataEntityContextComponent>(),
|
||||
azrtti_typeid<Prefab::PrefabSystemComponent>(),
|
||||
azrtti_typeid<EditorEntityFixupComponent>(),
|
||||
|
||||
@@ -354,26 +354,6 @@ namespace AzToolsFramework
|
||||
}
|
||||
}
|
||||
|
||||
const char* AssetSystemComponent::GetAbsoluteDevGameFolderPath()
|
||||
{
|
||||
AZ::IO::FileIOBase* fileIO = AZ::IO::FileIOBase::GetInstance();
|
||||
if (fileIO)
|
||||
{
|
||||
return fileIO->GetAlias("@devassets@");
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
const char* AssetSystemComponent::GetAbsoluteDevRootFolderPath()
|
||||
{
|
||||
AZ::IO::FileIOBase* fileIO = AZ::IO::FileIOBase::GetInstance();
|
||||
if (fileIO)
|
||||
{
|
||||
return fileIO->GetAlias("@devroot@");
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
void AssetSystemComponent::OnSystemTick()
|
||||
{
|
||||
AssetSystemBus::ExecuteQueuedEvents();
|
||||
|
||||
@@ -56,8 +56,6 @@ namespace AzToolsFramework
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// AzToolsFramework::AssetSystemRequestBus::Handler overrides
|
||||
bool GetAbsoluteAssetDatabaseLocation(AZStd::string& result) override;
|
||||
const char* GetAbsoluteDevGameFolderPath() override;
|
||||
const char* GetAbsoluteDevRootFolderPath() override;
|
||||
bool GetRelativeProductPathFromFullSourceOrProductPath(const AZStd::string& fullPath, AZStd::string& outputPath) override;
|
||||
bool GenerateRelativeSourcePath(
|
||||
const AZStd::string& sourcePath, AZStd::string& outputPath, AZStd::string& watchFolder) override;
|
||||
|
||||
@@ -137,7 +137,7 @@ namespace AzToolsFramework
|
||||
AssetEditorWidgetUserSettings::AssetEditorWidgetUserSettings()
|
||||
{
|
||||
char assetRoot[AZ_MAX_PATH_LEN] = { 0 };
|
||||
AZ::IO::FileIOBase::GetInstance()->ResolvePath("@devassets@", assetRoot, AZ_MAX_PATH_LEN);
|
||||
AZ::IO::FileIOBase::GetInstance()->ResolvePath("@projectroot@", assetRoot, AZ_MAX_PATH_LEN);
|
||||
|
||||
m_lastSavePath = assetRoot;
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <AzToolsFramework/AssetBundle/AssetBundleComponent.h>
|
||||
#include <AzToolsFramework/Component/EditorComponentAPIComponent.h>
|
||||
#include <AzToolsFramework/Component/EditorLevelComponentAPIComponent.h>
|
||||
#include <AzToolsFramework/ContainerEntity/ContainerEntitySystemComponent.h>
|
||||
#include <AzToolsFramework/Entity/EditorEntityActionComponent.h>
|
||||
#include <AzToolsFramework/Entity/EditorEntityContextComponent.h>
|
||||
#include <AzToolsFramework/Entity/EditorEntityFixupComponent.h>
|
||||
@@ -70,6 +71,7 @@ namespace AzToolsFramework
|
||||
Components::EditorSelectionAccentSystemComponent::CreateDescriptor(),
|
||||
EditorEntityContextComponent::CreateDescriptor(),
|
||||
EditorEntityFixupComponent::CreateDescriptor(),
|
||||
ContainerEntitySystemComponent::CreateDescriptor(),
|
||||
FocusModeSystemComponent::CreateDescriptor(),
|
||||
SliceMetadataEntityContextComponent::CreateDescriptor(),
|
||||
SliceRequestComponent::CreateDescriptor(),
|
||||
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
//! Outcome object that returns an error message in case of failure to allow caller to handle internal errors.
|
||||
using ContainerEntityOperationResult = AZ::Outcome<void, AZStd::string>;
|
||||
|
||||
//! ContainerEntityInterface
|
||||
//! An entity registered as Container is just like a regular entity when open. If its state is changed
|
||||
//! to closed, all descendants of the entity will be treated as part of the entity itself. Selecting any
|
||||
//! descendant will result in the container being selected, and descendants will be hidden until the
|
||||
//! container is opened.
|
||||
class ContainerEntityInterface
|
||||
{
|
||||
public:
|
||||
AZ_RTTI(ContainerEntityInterface, "{0A877C3A-726C-4FD2-BAFE-A2B9F1DE78E4}");
|
||||
|
||||
//! Registers the entity as a container. The container will be closed by default.
|
||||
//! @param entityId The entityId that will be registered as a container.
|
||||
virtual ContainerEntityOperationResult RegisterEntityAsContainer(AZ::EntityId entityId) = 0;
|
||||
|
||||
//! Unregisters the entity as a container.
|
||||
//! The system will retain the closed state in case the entity is registered again later, but
|
||||
//! if queried the entity will no longer behave as a container.
|
||||
//! @param entityId The entityId that will be unregistered as a container.
|
||||
virtual ContainerEntityOperationResult UnregisterEntityAsContainer(AZ::EntityId entityId) = 0;
|
||||
|
||||
//! Returns whether the entity id provided is registered as a container.
|
||||
virtual bool IsContainer(AZ::EntityId entityId) const = 0;
|
||||
|
||||
//! Sets the open state of the container entity provided.
|
||||
//! @param entityId The entityId whose open state will be set.
|
||||
//! @param open True if the container should be opened, false if it should be closed.
|
||||
//! @return An error message if the operation was invalid, success otherwise.
|
||||
virtual ContainerEntityOperationResult SetContainerOpenState(AZ::EntityId entityId, bool open) = 0;
|
||||
|
||||
//! If the entity id provided is registered as a container, it returns whether it's open.
|
||||
//! @note the default value for non-containers is true, so this function can be called without
|
||||
//! verifying whether the entityId is registered as a container beforehand, since the container's
|
||||
//! open behavior is exactly the same as the one of a regular entity.
|
||||
//! @return False if the entityId is registered as a container, and its state is closed. True otherwise.
|
||||
virtual bool IsContainerOpen(AZ::EntityId entityId) const = 0;
|
||||
|
||||
//! Detects if one of the ancestors of entityId is a closed container entity.
|
||||
//! @return The highest closed entity container id if any, or entityId otherwise.
|
||||
virtual AZ::EntityId FindHighestSelectableEntity(AZ::EntityId entityId) const = 0;
|
||||
|
||||
};
|
||||
|
||||
} // namespace AzToolsFramework
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Component/EntityId.h>
|
||||
#include <AzCore/EBus/EBus.h>
|
||||
|
||||
#include <AzFramework/Entity/EntityContext.h>
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
//! Used to notify changes of state for Container Entities.
|
||||
class ContainerEntityNotifications
|
||||
: public AZ::EBusTraits
|
||||
{
|
||||
public:
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// EBusTraits overrides
|
||||
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple;
|
||||
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::ById;
|
||||
using BusIdType = AzFramework::EntityContextId;
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//! Triggered when a container entity status changes.
|
||||
//! @param entityId The entity whose status has changed.
|
||||
//! @param open The open state the container was changed to.
|
||||
virtual void OnContainerEntityStatusChanged([[maybe_unused]] AZ::EntityId entityId, [[maybe_unused]] bool open) {}
|
||||
|
||||
protected:
|
||||
~ContainerEntityNotifications() = default;
|
||||
};
|
||||
|
||||
using ContainerEntityNotificationBus = AZ::EBus<ContainerEntityNotifications>;
|
||||
|
||||
} // namespace AzToolsFramework
|
||||
+120
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzToolsFramework/ContainerEntity/ContainerEntitySystemComponent.h>
|
||||
|
||||
#include <AzCore/Component/TransformBus.h>
|
||||
#include <AzToolsFramework/ContainerEntity/ContainerEntityNotificationBus.h>
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
void ContainerEntitySystemComponent::Activate()
|
||||
{
|
||||
AZ::Interface<ContainerEntityInterface>::Register(this);
|
||||
}
|
||||
|
||||
void ContainerEntitySystemComponent::Deactivate()
|
||||
{
|
||||
AZ::Interface<ContainerEntityInterface>::Unregister(this);
|
||||
}
|
||||
|
||||
void ContainerEntitySystemComponent::Reflect([[maybe_unused]] AZ::ReflectContext* context)
|
||||
{
|
||||
}
|
||||
|
||||
void ContainerEntitySystemComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
|
||||
{
|
||||
provided.push_back(AZ_CRC_CE("ContainerEntityService"));
|
||||
}
|
||||
|
||||
ContainerEntityOperationResult ContainerEntitySystemComponent::RegisterEntityAsContainer(AZ::EntityId entityId)
|
||||
{
|
||||
if (IsContainer(entityId))
|
||||
{
|
||||
return AZ::Failure(AZStd::string(
|
||||
"ContainerEntitySystemComponent error - trying to register entity as container twice."));
|
||||
}
|
||||
|
||||
m_containers.insert(entityId);
|
||||
|
||||
return AZ::Success();
|
||||
}
|
||||
|
||||
ContainerEntityOperationResult ContainerEntitySystemComponent::UnregisterEntityAsContainer(AZ::EntityId entityId)
|
||||
{
|
||||
if (!IsContainer(entityId))
|
||||
{
|
||||
return AZ::Failure(AZStd::string(
|
||||
"ContainerEntitySystemComponent error - trying to unregister entity that is not a container."));
|
||||
}
|
||||
|
||||
m_containers.erase(entityId);
|
||||
|
||||
return AZ::Success();
|
||||
}
|
||||
|
||||
bool ContainerEntitySystemComponent::IsContainer(AZ::EntityId entityId) const
|
||||
{
|
||||
return m_containers.contains(entityId);
|
||||
}
|
||||
|
||||
ContainerEntityOperationResult ContainerEntitySystemComponent::SetContainerOpenState(AZ::EntityId entityId, bool open)
|
||||
{
|
||||
if (!IsContainer(entityId))
|
||||
{
|
||||
return AZ::Failure(AZStd::string(
|
||||
"ContainerEntitySystemComponent error - cannot set open state of entity that was not registered as container."));
|
||||
}
|
||||
|
||||
if(open)
|
||||
{
|
||||
m_openContainers.insert(entityId);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_openContainers.erase(entityId);
|
||||
}
|
||||
|
||||
ContainerEntityNotificationBus::Broadcast(&ContainerEntityNotificationBus::Events::OnContainerEntityStatusChanged, entityId, open);
|
||||
|
||||
return AZ::Success();
|
||||
}
|
||||
|
||||
bool ContainerEntitySystemComponent::IsContainerOpen(AZ::EntityId entityId) const
|
||||
{
|
||||
// If the entity is not a container, it should behave as open.
|
||||
if(!m_containers.contains(entityId))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// If the entity is a container, return its state.
|
||||
return m_openContainers.contains(entityId);
|
||||
}
|
||||
|
||||
AZ::EntityId ContainerEntitySystemComponent::FindHighestSelectableEntity(AZ::EntityId entityId) const
|
||||
{
|
||||
AZ::EntityId highestSelectableEntityId = entityId;
|
||||
|
||||
// Go up the hierarchy until you hit the root
|
||||
while (entityId.IsValid())
|
||||
{
|
||||
if (!IsContainerOpen(entityId))
|
||||
{
|
||||
// If one of the ancestors is a container and it's closed, keep track of its id.
|
||||
// We only return of the higher closed container in the hierarchy.
|
||||
highestSelectableEntityId = entityId;
|
||||
}
|
||||
|
||||
AZ::TransformBus::EventResult(entityId, entityId, &AZ::TransformBus::Events::GetParentId);
|
||||
}
|
||||
|
||||
return highestSelectableEntityId;
|
||||
}
|
||||
|
||||
} // namespace AzToolsFramework
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Component/Component.h>
|
||||
#include <AzCore/Memory/SystemAllocator.h>
|
||||
|
||||
#include <AzToolsFramework/ContainerEntity/ContainerEntityInterface.h>
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
//! System Component to track Container Entity registration and open state.
|
||||
//! An entity registered as Container is just like a regular entity when open. If its state is changed
|
||||
//! to closed, all descendants of the entity will be treated as part of the entity itself. Selecting any
|
||||
//! descendant will result in the container being selected, and descendants will be hidden until the
|
||||
//! container is opened.
|
||||
class ContainerEntitySystemComponent final
|
||||
: public AZ::Component
|
||||
, private ContainerEntityInterface
|
||||
{
|
||||
public:
|
||||
AZ_COMPONENT(ContainerEntitySystemComponent, "{74349759-B36B-44A6-B89F-F45D7111DD11}");
|
||||
|
||||
ContainerEntitySystemComponent() = default;
|
||||
virtual ~ContainerEntitySystemComponent() = default;
|
||||
|
||||
// AZ::Component overrides ...
|
||||
void Activate() override;
|
||||
void Deactivate() override;
|
||||
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided);
|
||||
|
||||
// ContainerEntityInterface overrides ...
|
||||
ContainerEntityOperationResult RegisterEntityAsContainer(AZ::EntityId entityId) override;
|
||||
ContainerEntityOperationResult UnregisterEntityAsContainer(AZ::EntityId entityId) override;
|
||||
bool IsContainer(AZ::EntityId entityId) const override;
|
||||
ContainerEntityOperationResult SetContainerOpenState(AZ::EntityId entityId, bool open) override;
|
||||
bool IsContainerOpen(AZ::EntityId entityId) const override;
|
||||
AZ::EntityId FindHighestSelectableEntity(AZ::EntityId entityId) const override;
|
||||
|
||||
private:
|
||||
AZStd::unordered_set<AZ::EntityId> m_containers; //!< All entities in this set are containers.
|
||||
AZStd::unordered_set<AZ::EntityId> m_openContainers; //!< All entities in this set are open containers.
|
||||
};
|
||||
|
||||
} // namespace AzToolsFramework
|
||||
@@ -39,7 +39,7 @@ namespace AzToolsFramework
|
||||
// the TraceContextLogFormatter.
|
||||
//
|
||||
// Usage example:
|
||||
// const char* gameFolder = m_context.pRC->GetSystemEnvironment()->pFileIO->GetAlias("@devassets@");
|
||||
// const char* gameFolder = m_context.pRC->GetSystemEnvironment()->pFileIO->GetAlias("@projectroot@");
|
||||
// AZ_TraceContext("Game folder", gameFolder);
|
||||
//
|
||||
// for (int i=0; i<subMeshCount; ++i)
|
||||
|
||||
@@ -66,7 +66,7 @@ namespace AzToolsFramework
|
||||
StringFunc::Path::Join(resolveBuffer, "log", logDirectory);
|
||||
fileIO->SetAlias("@log@", logDirectory.c_str());
|
||||
|
||||
fileIO->CreatePath("@root@");
|
||||
fileIO->CreatePath("@products@");
|
||||
fileIO->CreatePath("@user@");
|
||||
fileIO->CreatePath("@log@");
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include <AzToolsFramework/Prefab/PrefabFocusHandler.h>
|
||||
|
||||
#include <AzToolsFramework/ContainerEntity/ContainerEntityInterface.h>
|
||||
#include <AzToolsFramework/Entity/EditorEntityHelpers.h>
|
||||
#include <AzToolsFramework/Entity/PrefabEditorEntityOwnershipInterface.h>
|
||||
#include <AzToolsFramework/Prefab/Instance/Instance.h>
|
||||
@@ -35,6 +36,30 @@ namespace AzToolsFramework::Prefab
|
||||
EditorEntityContextNotificationBus::Handler::BusDisconnect();
|
||||
}
|
||||
|
||||
void PrefabFocusHandler::Initialize()
|
||||
{
|
||||
m_containerEntityInterface = AZ::Interface<ContainerEntityInterface>::Get();
|
||||
AZ_Assert(
|
||||
m_containerEntityInterface,
|
||||
"Prefab - PrefabFocusHandler - "
|
||||
"Container Entity Interface could not be found. "
|
||||
"Check that it is being correctly initialized.");
|
||||
|
||||
m_focusModeInterface = AZ::Interface<FocusModeInterface>::Get();
|
||||
AZ_Assert(
|
||||
m_focusModeInterface,
|
||||
"Prefab - PrefabFocusHandler - "
|
||||
"Focus Mode Interface could not be found. "
|
||||
"Check that it is being correctly initialized.");
|
||||
|
||||
m_instanceEntityMapperInterface = AZ::Interface<InstanceEntityMapperInterface>::Get();
|
||||
AZ_Assert(
|
||||
m_instanceEntityMapperInterface,
|
||||
"Prefab - PrefabFocusHandler - "
|
||||
"Instance Entity Mapper Interface could not be found. "
|
||||
"Check that it is being correctly initialized.");
|
||||
}
|
||||
|
||||
PrefabFocusOperationResult PrefabFocusHandler::FocusOnOwningPrefab(AZ::EntityId entityId)
|
||||
{
|
||||
InstanceOptionalReference focusedInstance;
|
||||
@@ -44,7 +69,7 @@ namespace AzToolsFramework::Prefab
|
||||
PrefabEditorEntityOwnershipInterface* prefabEditorEntityOwnershipInterface =
|
||||
AZ::Interface<PrefabEditorEntityOwnershipInterface>::Get();
|
||||
|
||||
if(!prefabEditorEntityOwnershipInterface)
|
||||
if (!prefabEditorEntityOwnershipInterface)
|
||||
{
|
||||
return AZ::Failure(AZStd::string("Could not focus on root prefab instance - internal error "
|
||||
"(PrefabEditorEntityOwnershipInterface unavailable)."));
|
||||
@@ -79,8 +104,16 @@ namespace AzToolsFramework::Prefab
|
||||
return AZ::Failure(AZStd::string("Prefab Focus Handler: invalid instance to focus on."));
|
||||
}
|
||||
|
||||
if (!m_isInitialized)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
if (!m_focusedInstance.has_value() || &m_focusedInstance->get() != &focusedInstance->get())
|
||||
{
|
||||
// Close all container entities in the old path
|
||||
CloseInstanceContainers(m_instanceFocusVector);
|
||||
|
||||
m_focusedInstance = focusedInstance;
|
||||
m_focusedTemplateId = focusedInstance->get().GetTemplateId();
|
||||
|
||||
@@ -103,12 +136,14 @@ namespace AzToolsFramework::Prefab
|
||||
}
|
||||
|
||||
// Focus on the descendants of the container entity
|
||||
if (FocusModeInterface* focusModeInterface = AZ::Interface<FocusModeInterface>::Get())
|
||||
{
|
||||
focusModeInterface->SetFocusRoot(containerEntityId);
|
||||
}
|
||||
m_focusModeInterface->SetFocusRoot(containerEntityId);
|
||||
|
||||
// Refresh path variables
|
||||
RefreshInstanceFocusList();
|
||||
|
||||
// Open all container entities in the new path
|
||||
OpenInstanceContainers(m_instanceFocusVector);
|
||||
|
||||
PrefabFocusNotificationBus::Broadcast(&PrefabFocusNotifications::OnPrefabFocusChanged);
|
||||
}
|
||||
|
||||
@@ -156,6 +191,11 @@ namespace AzToolsFramework::Prefab
|
||||
|
||||
void PrefabFocusHandler::OnEntityStreamLoadSuccess()
|
||||
{
|
||||
if (!m_isInitialized)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
// Focus on the root prefab (AZ::EntityId() will default to it)
|
||||
FocusOnOwningPrefab(AZ::EntityId());
|
||||
}
|
||||
@@ -184,4 +224,26 @@ namespace AzToolsFramework::Prefab
|
||||
}
|
||||
}
|
||||
|
||||
void PrefabFocusHandler::OpenInstanceContainers(const AZStd::vector<InstanceOptionalReference>& instances) const
|
||||
{
|
||||
for (const InstanceOptionalReference& instance : instances)
|
||||
{
|
||||
if (instance.has_value())
|
||||
{
|
||||
m_containerEntityInterface->SetContainerOpenState(instance->get().GetContainerEntityId(), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PrefabFocusHandler::CloseInstanceContainers(const AZStd::vector<InstanceOptionalReference>& instances) const
|
||||
{
|
||||
for (const InstanceOptionalReference& instance : instances)
|
||||
{
|
||||
if (instance.has_value())
|
||||
{
|
||||
m_containerEntityInterface->SetContainerOpenState(instance->get().GetContainerEntityId(), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace AzToolsFramework::Prefab
|
||||
|
||||
@@ -15,6 +15,12 @@
|
||||
#include <AzToolsFramework/Prefab/PrefabFocusInterface.h>
|
||||
#include <AzToolsFramework/Prefab/Template/Template.h>
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
class ContainerEntityInterface;
|
||||
class FocusModeInterface;
|
||||
}
|
||||
|
||||
namespace AzToolsFramework::Prefab
|
||||
{
|
||||
class InstanceEntityMapperInterface;
|
||||
@@ -30,6 +36,8 @@ namespace AzToolsFramework::Prefab
|
||||
PrefabFocusHandler();
|
||||
~PrefabFocusHandler();
|
||||
|
||||
void Initialize();
|
||||
|
||||
// PrefabFocusInterface overrides ...
|
||||
PrefabFocusOperationResult FocusOnOwningPrefab(AZ::EntityId entityId) override;
|
||||
PrefabFocusOperationResult FocusOnPathIndex(AzFramework::EntityContextId entityContextId, int index) override;
|
||||
@@ -46,12 +54,19 @@ namespace AzToolsFramework::Prefab
|
||||
PrefabFocusOperationResult FocusOnPrefabInstance(InstanceOptionalReference focusedInstance);
|
||||
void RefreshInstanceFocusList();
|
||||
|
||||
void OpenInstanceContainers(const AZStd::vector<InstanceOptionalReference>& instances) const;
|
||||
void CloseInstanceContainers(const AZStd::vector<InstanceOptionalReference>& instances) const;
|
||||
|
||||
InstanceOptionalReference m_focusedInstance;
|
||||
TemplateId m_focusedTemplateId;
|
||||
AZStd::vector<InstanceOptionalReference> m_instanceFocusVector;
|
||||
AZ::IO::Path m_instanceFocusPath;
|
||||
|
||||
InstanceEntityMapperInterface* m_instanceEntityMapperInterface;
|
||||
ContainerEntityInterface* m_containerEntityInterface = nullptr;
|
||||
FocusModeInterface* m_focusModeInterface = nullptr;
|
||||
InstanceEntityMapperInterface* m_instanceEntityMapperInterface = nullptr;
|
||||
|
||||
bool m_isInitialized = false;
|
||||
};
|
||||
|
||||
} // namespace AzToolsFramework::Prefab
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
#include <AzCore/Utils/Utils.h>
|
||||
#include <AzFramework/IO/FileOperations.h>
|
||||
#include <AzFramework/StringFunc/StringFunc.h>
|
||||
#include <AzToolsFramework/API/EditorAssetSystemAPI.h>
|
||||
@@ -78,13 +79,9 @@ namespace AzToolsFramework
|
||||
AzToolsFramework::ToolsApplicationRequestBus::BroadcastResult(entitiesAndDescendants,
|
||||
&AzToolsFramework::ToolsApplicationRequestBus::Events::GatherEntitiesAndAllDescendents, AzToolsFramework::EntityIdList{ entityId });
|
||||
|
||||
// Retrieve the game folder so we can use that as a root with the passed in relative path
|
||||
const char* gameFolder = nullptr;
|
||||
AzToolsFramework::AssetSystemRequestBus::BroadcastResult(gameFolder, &AzToolsFramework::AssetSystem::AssetSystemRequest::GetAbsoluteDevGameFolderPath);
|
||||
|
||||
// Join our relative path with the game folder to get a full path to the desired asset
|
||||
AZStd::string assetFullPath;
|
||||
AzFramework::StringFunc::Path::Join(gameFolder, assetPath, assetFullPath);
|
||||
AZ::IO::FixedMaxPath assetFullPath = AZ::Utils::GetProjectPath();
|
||||
assetFullPath /= assetPath;
|
||||
|
||||
// Call SliceUtilities::MakeNewSlice with all user input prompts disabled
|
||||
bool success = AzToolsFramework::SliceUtilities::MakeNewSlice(entitiesAndDescendants,
|
||||
|
||||
@@ -718,7 +718,7 @@ namespace AzToolsFramework
|
||||
|
||||
if (!fullPathFound)
|
||||
{
|
||||
assetFullPath = AZStd::string::format("@devassets@/%s", sliceAssetPath.c_str());
|
||||
assetFullPath = AZStd::string::format("@projectroot@/%s", sliceAssetPath.c_str());
|
||||
}
|
||||
|
||||
return Commit(assetFullPath.c_str(), preSaveCallback, postSaveCallback, sliceCommitFlags);
|
||||
@@ -1020,13 +1020,13 @@ namespace AzToolsFramework
|
||||
AZ::IO::FileIOBase* fileIO = AZ::IO::FileIOBase::GetInstance();
|
||||
AZ_Assert(fileIO, "File IO is not initialized.");
|
||||
|
||||
AZStd::string devAssetPath = fileIO->GetAlias("@devassets@");
|
||||
AZStd::string devAssetPath = fileIO->GetAlias("@projectroot@");
|
||||
AZStd::string userPath = fileIO->GetAlias("@user@");
|
||||
AZStd::string tempPath = fullPath;
|
||||
EBUS_EVENT(AzFramework::ApplicationRequests::Bus, NormalizePath, devAssetPath);
|
||||
EBUS_EVENT(AzFramework::ApplicationRequests::Bus, NormalizePath, userPath);
|
||||
EBUS_EVENT(AzFramework::ApplicationRequests::Bus, NormalizePath, tempPath);
|
||||
AzFramework::StringFunc::Replace(tempPath, "@devassets@", devAssetPath.c_str());
|
||||
AzFramework::StringFunc::Replace(tempPath, "@projectroot@", devAssetPath.c_str());
|
||||
AzFramework::StringFunc::Replace(tempPath, devAssetPath.c_str(), userPath.c_str());
|
||||
tempPath.append(".slicetemp");
|
||||
|
||||
|
||||
+2
-2
@@ -378,11 +378,11 @@ namespace AzToolsFramework
|
||||
// If this layer is being loaded, it won't have a level save dependency yet, so clear that flag.
|
||||
m_mustSaveLevelWhenLayerSaves = false;
|
||||
QString fullPathName = levelPakFile;
|
||||
if (fullPathName.contains("@devassets@"))
|
||||
if (fullPathName.contains("@projectroot@"))
|
||||
{
|
||||
AZ::IO::FileIOBase* fileIO = AZ::IO::FileIOBase::GetInstance();
|
||||
// Resolving the path through resolvepath would normalize and lowcase it, and in this case, we don't want that.
|
||||
fullPathName.replace("@devassets@", fileIO->GetAlias("@devassets@"));
|
||||
fullPathName.replace("@projectroot@", fileIO->GetAlias("@projectroot@"));
|
||||
}
|
||||
|
||||
QFileInfo fileNameInfo(fullPathName);
|
||||
|
||||
+33
-13
@@ -37,51 +37,71 @@ namespace AzToolsFramework
|
||||
return m_handlerId;
|
||||
}
|
||||
|
||||
QString EditorEntityUiHandlerBase::GenerateItemInfoString(AZ::EntityId /*entityId*/) const
|
||||
QString EditorEntityUiHandlerBase::GenerateItemInfoString([[maybe_unused]] AZ::EntityId entityId) const
|
||||
{
|
||||
return QString();
|
||||
}
|
||||
|
||||
QString EditorEntityUiHandlerBase::GenerateItemTooltip(AZ::EntityId /*entityId*/) const
|
||||
QString EditorEntityUiHandlerBase::GenerateItemTooltip([[maybe_unused]] AZ::EntityId entityId) const
|
||||
{
|
||||
return QString();
|
||||
}
|
||||
|
||||
QIcon EditorEntityUiHandlerBase::GenerateItemIcon(AZ::EntityId /*entityId*/) const
|
||||
QIcon EditorEntityUiHandlerBase::GenerateItemIcon([[maybe_unused]] AZ::EntityId entityId) const
|
||||
{
|
||||
return QIcon();
|
||||
}
|
||||
|
||||
bool EditorEntityUiHandlerBase::CanToggleLockVisibility(AZ::EntityId /*entityId*/) const
|
||||
bool EditorEntityUiHandlerBase::CanToggleLockVisibility([[maybe_unused]] AZ::EntityId entityId) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EditorEntityUiHandlerBase::CanRename(AZ::EntityId /*entityId*/) const
|
||||
bool EditorEntityUiHandlerBase::CanRename([[maybe_unused]] AZ::EntityId entityId) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void EditorEntityUiHandlerBase::PaintItemBackground(QPainter* /*painter*/, const QStyleOptionViewItem& /*option*/, const QModelIndex& /*index*/) const
|
||||
void EditorEntityUiHandlerBase::PaintItemBackground(
|
||||
[[maybe_unused]] QPainter* painter,
|
||||
[[maybe_unused]] const QStyleOptionViewItem& option,
|
||||
[[maybe_unused]] const QModelIndex& index) const
|
||||
{
|
||||
}
|
||||
|
||||
void EditorEntityUiHandlerBase::PaintDescendantBackground(QPainter* /*painter*/, const QStyleOptionViewItem& /*option*/, const QModelIndex& /*index*/,
|
||||
const QModelIndex& /*descendantIndex*/) const
|
||||
void EditorEntityUiHandlerBase::PaintDescendantBackground(
|
||||
[[maybe_unused]] QPainter* painter,
|
||||
[[maybe_unused]] const QStyleOptionViewItem& option,
|
||||
[[maybe_unused]] const QModelIndex& index,
|
||||
[[maybe_unused]] const QModelIndex& descendantIndex) const
|
||||
{
|
||||
}
|
||||
|
||||
void EditorEntityUiHandlerBase::PaintDescendantBranchBackground(QPainter* /*painter*/, const QTreeView* /*view*/, const QRect& /*rect*/,
|
||||
const QModelIndex& /*index*/, const QModelIndex& /*descendantIndex*/) const
|
||||
void EditorEntityUiHandlerBase::PaintDescendantBranchBackground(
|
||||
[[maybe_unused]] QPainter* painter,
|
||||
[[maybe_unused]] const QTreeView* view,
|
||||
[[maybe_unused]] const QRect& rect,
|
||||
[[maybe_unused]] const QModelIndex& index,
|
||||
[[maybe_unused]] const QModelIndex& descendantIndex) const
|
||||
{
|
||||
}
|
||||
|
||||
void EditorEntityUiHandlerBase::PaintItemForeground(QPainter* /*painter*/, const QStyleOptionViewItem& /*option*/, const QModelIndex& /*index*/) const
|
||||
void EditorEntityUiHandlerBase::PaintItemForeground(
|
||||
[[maybe_unused]] QPainter* painter,
|
||||
[[maybe_unused]] const QStyleOptionViewItem& option,
|
||||
[[maybe_unused]] const QModelIndex& index) const
|
||||
{
|
||||
}
|
||||
|
||||
void EditorEntityUiHandlerBase::PaintDescendantForeground(QPainter* /*painter*/, const QStyleOptionViewItem& /*option*/, const QModelIndex& /*index*/,
|
||||
const QModelIndex& /*descendantIndex*/) const
|
||||
void EditorEntityUiHandlerBase::PaintDescendantForeground(
|
||||
[[maybe_unused]] QPainter* painter,
|
||||
[[maybe_unused]] const QStyleOptionViewItem& option,
|
||||
[[maybe_unused]] const QModelIndex& index,
|
||||
[[maybe_unused]] const QModelIndex& descendantIndex) const
|
||||
{
|
||||
}
|
||||
|
||||
void EditorEntityUiHandlerBase::OnDoubleClick([[maybe_unused]] AZ::EntityId entityId) const
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
+3
@@ -61,6 +61,9 @@ namespace AzToolsFramework
|
||||
virtual void PaintDescendantForeground(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index,
|
||||
const QModelIndex& descendantIndex) const;
|
||||
|
||||
//! Triggered when the entity is double clicked in the Outliner.
|
||||
virtual void OnDoubleClick(AZ::EntityId entityId) const;
|
||||
|
||||
private:
|
||||
EditorEntityUiHandlerId m_handlerId = 0;
|
||||
};
|
||||
|
||||
+23
-2
@@ -88,6 +88,7 @@ namespace AzToolsFramework
|
||||
|
||||
EntityOutlinerListModel::~EntityOutlinerListModel()
|
||||
{
|
||||
ContainerEntityNotificationBus::Handler::BusDisconnect();
|
||||
EditorEntityInfoNotificationBus::Handler::BusDisconnect();
|
||||
EditorEntityContextNotificationBus::Handler::BusDisconnect();
|
||||
ToolsApplicationEvents::Bus::Handler::BusDisconnect();
|
||||
@@ -105,6 +106,12 @@ namespace AzToolsFramework
|
||||
EntityCompositionNotificationBus::Handler::BusConnect();
|
||||
AZ::EntitySystemBus::Handler::BusConnect();
|
||||
|
||||
AzFramework::EntityContextId editorEntityContextId = AzFramework::EntityContextId::CreateNull();
|
||||
AzToolsFramework::EditorEntityContextRequestBus::BroadcastResult(
|
||||
editorEntityContextId, &AzToolsFramework::EditorEntityContextRequestBus::Events::GetEditorEntityContextId);
|
||||
|
||||
ContainerEntityNotificationBus::Handler::BusConnect(editorEntityContextId);
|
||||
|
||||
m_editorEntityUiInterface = AZ::Interface<AzToolsFramework::EditorEntityUiInterface>::Get();
|
||||
AZ_Assert(m_editorEntityUiInterface != nullptr,
|
||||
"EntityOutlinerListModel requires a EditorEntityUiInterface instance on Initialize.");
|
||||
@@ -1333,12 +1340,26 @@ namespace AzToolsFramework
|
||||
emit EnableSelectionUpdates(true);
|
||||
}
|
||||
|
||||
void EntityOutlinerListModel::OnEntityRuntimeActivationChanged(AZ::EntityId entityId, bool activeOnStart)
|
||||
void EntityOutlinerListModel::OnEntityRuntimeActivationChanged(AZ::EntityId entityId, [[maybe_unused]] bool activeOnStart)
|
||||
{
|
||||
AZ_UNUSED(activeOnStart);
|
||||
QueueEntityUpdate(entityId);
|
||||
}
|
||||
|
||||
void EntityOutlinerListModel::OnContainerEntityStatusChanged(AZ::EntityId entityId, [[maybe_unused]] bool open)
|
||||
{
|
||||
QModelIndex changedIndex = GetIndexFromEntity(entityId);
|
||||
|
||||
// Trigger a refresh of all direct children so that they can be shown or hidden appropriately.
|
||||
int numChildren = rowCount(changedIndex);
|
||||
if (numChildren > 0)
|
||||
{
|
||||
emit dataChanged(index(0, 0, changedIndex), index(numChildren - 1, ColumnCount - 1, changedIndex));
|
||||
}
|
||||
|
||||
// Always expand containers
|
||||
QueueEntityToExpand(entityId, true);
|
||||
}
|
||||
|
||||
void EntityOutlinerListModel::OnEntityInfoUpdatedRemoveChildBegin([[maybe_unused]] AZ::EntityId parentId, [[maybe_unused]] AZ::EntityId childId)
|
||||
{
|
||||
//add/remove operations trigger selection change signals which assert and break undo/redo operations in progress in inspector etc.
|
||||
|
||||
+5
@@ -17,6 +17,7 @@
|
||||
|
||||
#include <AzToolsFramework/API/EntityCompositionNotificationBus.h>
|
||||
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
|
||||
#include <AzToolsFramework/ContainerEntity/ContainerEntityNotificationBus.h>
|
||||
#include <AzToolsFramework/Entity/EditorEntityContextBus.h>
|
||||
#include <AzToolsFramework/Entity/EditorEntityInfoBus.h>
|
||||
#include <AzToolsFramework/Entity/EditorEntityRuntimeActivationBus.h>
|
||||
@@ -54,6 +55,7 @@ namespace AzToolsFramework
|
||||
, private EntityCompositionNotificationBus::Handler
|
||||
, private EditorEntityRuntimeActivationChangeNotificationBus::Handler
|
||||
, private AZ::EntitySystemBus::Handler
|
||||
, private ContainerEntityNotificationBus::Handler
|
||||
{
|
||||
Q_OBJECT;
|
||||
|
||||
@@ -216,6 +218,9 @@ namespace AzToolsFramework
|
||||
// EditorEntityRuntimeActivationChangeNotificationBus::Handler
|
||||
void OnEntityRuntimeActivationChanged(AZ::EntityId entityId, bool activeOnStart) override;
|
||||
|
||||
// ContainerEntityNotificationBus overrides ...
|
||||
void OnContainerEntityStatusChanged(AZ::EntityId entityId, bool open) override;
|
||||
|
||||
// Drag/Drop of components from Component Palette.
|
||||
bool dropMimeDataComponentPalette(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent);
|
||||
|
||||
|
||||
+22
@@ -11,6 +11,8 @@
|
||||
#include <AzCore/Component/ComponentApplication.h>
|
||||
#include <AzCore/Component/Entity.h>
|
||||
|
||||
#include <AzToolsFramework/ContainerEntity/ContainerEntityInterface.h>
|
||||
|
||||
#include "EntityOutlinerListModel.hxx"
|
||||
|
||||
namespace AzToolsFramework
|
||||
@@ -19,6 +21,10 @@ namespace AzToolsFramework
|
||||
EntityOutlinerSortFilterProxyModel::EntityOutlinerSortFilterProxyModel(QObject* pParent)
|
||||
: QSortFilterProxyModel(pParent)
|
||||
{
|
||||
m_containerEntityInterface = AZ::Interface<ContainerEntityInterface>::Get();
|
||||
AZ_Assert(
|
||||
m_containerEntityInterface != nullptr,
|
||||
"EntityOutlinerContainerProxyModel requires a ContainerEntityInterface instance on construction.");
|
||||
}
|
||||
|
||||
void EntityOutlinerSortFilterProxyModel::UpdateFilter()
|
||||
@@ -26,8 +32,24 @@ namespace AzToolsFramework
|
||||
invalidateFilter();
|
||||
}
|
||||
|
||||
void EntityOutlinerSortFilterProxyModel::setSourceModel(QAbstractItemModel* sourceModel)
|
||||
{
|
||||
QSortFilterProxyModel::setSourceModel(sourceModel);
|
||||
|
||||
m_listModel = qobject_cast<EntityOutlinerListModel*>(sourceModel);
|
||||
AZ_Assert(m_listModel != nullptr, "EntityOutlinerContainerProxyModel requires an EntityOutlinerListModel as its source .");
|
||||
}
|
||||
|
||||
bool EntityOutlinerSortFilterProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex& sourceParent) const
|
||||
{
|
||||
// Retrieve the entityId of the parent entity
|
||||
AZ::EntityId parentEntityId = m_listModel->GetEntityFromIndex(sourceParent);
|
||||
|
||||
if(!m_containerEntityInterface->IsContainerOpen(parentEntityId))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
|
||||
QVariant visibilityData = sourceModel()->data(index, EntityOutlinerListModel::VisibilityRole);
|
||||
return visibilityData.isValid() ? visibilityData.toBool() : true;
|
||||
|
||||
+8
-4
@@ -19,11 +19,12 @@
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
class ContainerEntityInterface;
|
||||
class EntityOutlinerListModel;
|
||||
|
||||
/*!
|
||||
* Enables the Outliner to filter entries based on search string.
|
||||
* Enables the Outliner to do custom sorting on entries.
|
||||
*/
|
||||
//! Enables the Outliner to filter entries based on search string.
|
||||
//! Enables the Outliner to do custom sorting on entries.
|
||||
//! Enforces the correct rendering for container entities.
|
||||
class EntityOutlinerSortFilterProxyModel
|
||||
: public QSortFilterProxyModel
|
||||
{
|
||||
@@ -37,12 +38,15 @@ namespace AzToolsFramework
|
||||
void UpdateFilter();
|
||||
|
||||
// Qt overrides
|
||||
void setSourceModel(QAbstractItemModel* sourceModel) override;
|
||||
bool filterAcceptsRow(int sourceRow, const QModelIndex& sourceParent) const override;
|
||||
bool lessThan(const QModelIndex& left, const QModelIndex& right) const override;
|
||||
void sort(int column, Qt::SortOrder order) override;
|
||||
|
||||
private:
|
||||
QString m_filterName;
|
||||
EntityOutlinerListModel* m_listModel = nullptr;
|
||||
ContainerEntityInterface* m_containerEntityInterface = nullptr;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
+7
-2
@@ -199,6 +199,7 @@ namespace AzToolsFramework
|
||||
|
||||
m_proxyModel = aznew EntityOutlinerSortFilterProxyModel(this);
|
||||
m_proxyModel->setSourceModel(m_listModel);
|
||||
|
||||
m_gui->m_objectTree->setModel(m_proxyModel);
|
||||
|
||||
// Link up signals for informing the model of tree changes using the proxy as an intermediary
|
||||
@@ -905,8 +906,12 @@ namespace AzToolsFramework
|
||||
}
|
||||
}
|
||||
|
||||
void EntityOutlinerWidget::OnTreeItemDoubleClicked(const QModelIndex& /*index*/)
|
||||
void EntityOutlinerWidget::OnTreeItemDoubleClicked(const QModelIndex& index)
|
||||
{
|
||||
if (AZ::EntityId entityId = GetEntityIdFromIndex(index); auto entityUiHandler = m_editorEntityUiInterface->GetHandler(entityId))
|
||||
{
|
||||
entityUiHandler->OnDoubleClick(entityId);
|
||||
}
|
||||
}
|
||||
|
||||
void EntityOutlinerWidget::OnTreeItemExpanded(const QModelIndex& index)
|
||||
@@ -1150,7 +1155,7 @@ namespace AzToolsFramework
|
||||
{
|
||||
QTimer::singleShot(1, this, [this]() {
|
||||
m_gui->m_objectTree->setUpdatesEnabled(true);
|
||||
m_gui->m_objectTree->expand(m_proxyModel->index(0,0));
|
||||
m_gui->m_objectTree->expandToDepth(0);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -41,6 +41,7 @@ namespace AzToolsFramework
|
||||
{
|
||||
class EditorEntityUiInterface;
|
||||
class EntityOutlinerListModel;
|
||||
class EntityOutlinerContainerProxyModel;
|
||||
class EntityOutlinerSortFilterProxyModel;
|
||||
|
||||
namespace EntityOutliner
|
||||
@@ -119,6 +120,7 @@ namespace AzToolsFramework
|
||||
|
||||
Ui::EntityOutlinerWidgetUI* m_gui;
|
||||
EntityOutlinerListModel* m_listModel;
|
||||
EntityOutlinerContainerProxyModel* m_containerModel;
|
||||
EntityOutlinerSortFilterProxyModel* m_proxyModel;
|
||||
AZ::u64 m_selectionContextId;
|
||||
AZStd::vector<AZ::EntityId> m_selectedEntityIds;
|
||||
|
||||
+32
-2
@@ -22,6 +22,7 @@
|
||||
#include <AzToolsFramework/AssetBrowser/AssetBrowserBus.h>
|
||||
#include <AzToolsFramework/AssetBrowser/AssetSelectionModel.h>
|
||||
#include <AzToolsFramework/AssetBrowser/Entries/SourceAssetBrowserEntry.h>
|
||||
#include <AzToolsFramework/ContainerEntity/ContainerEntityInterface.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabFocusInterface.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabLoaderInterface.h>
|
||||
#include <AzToolsFramework/ToolsComponents/EditorLayerComponentBus.h>
|
||||
@@ -56,7 +57,7 @@ namespace AzToolsFramework
|
||||
{
|
||||
namespace Prefab
|
||||
{
|
||||
|
||||
ContainerEntityInterface* PrefabIntegrationManager::s_containerEntityInterface = nullptr;
|
||||
EditorEntityUiInterface* PrefabIntegrationManager::s_editorEntityUiInterface = nullptr;
|
||||
PrefabFocusInterface* PrefabIntegrationManager::s_prefabFocusInterface = nullptr;
|
||||
PrefabLoaderInterface* PrefabIntegrationManager::s_prefabLoaderInterface = nullptr;
|
||||
@@ -89,6 +90,13 @@ namespace AzToolsFramework
|
||||
|
||||
PrefabIntegrationManager::PrefabIntegrationManager()
|
||||
{
|
||||
s_containerEntityInterface = AZ::Interface<ContainerEntityInterface>::Get();
|
||||
if (s_containerEntityInterface == nullptr)
|
||||
{
|
||||
AZ_Assert(false, "Prefab - could not get ContainerEntityInterface on PrefabIntegrationManager construction.");
|
||||
return;
|
||||
}
|
||||
|
||||
s_editorEntityUiInterface = AZ::Interface<EditorEntityUiInterface>::Get();
|
||||
if (s_editorEntityUiInterface == nullptr)
|
||||
{
|
||||
@@ -307,7 +315,7 @@ namespace AzToolsFramework
|
||||
// temporarily null after QFileDialogs close, which we need in order to
|
||||
// be able to parent our message dialogs properly
|
||||
QWidget* activeWindow = QApplication::activeWindow();
|
||||
const AZStd::string prefabFilesPath = "@devassets@/Prefabs";
|
||||
const AZStd::string prefabFilesPath = "@projectroot@/Prefabs";
|
||||
|
||||
// Remove Level entity if it's part of the list
|
||||
|
||||
@@ -1057,6 +1065,7 @@ namespace AzToolsFramework
|
||||
|
||||
void PrefabIntegrationManager::OnPrefabComponentActivate(AZ::EntityId entityId)
|
||||
{
|
||||
// Register entity to appropriate UI Handler for UI overrides
|
||||
if (s_prefabPublicInterface->IsLevelInstanceContainerEntity(entityId))
|
||||
{
|
||||
s_editorEntityUiInterface->RegisterEntity(entityId, m_levelRootUiHandler.GetHandlerId());
|
||||
@@ -1064,11 +1073,32 @@ namespace AzToolsFramework
|
||||
else
|
||||
{
|
||||
s_editorEntityUiInterface->RegisterEntity(entityId, m_prefabUiHandler.GetHandlerId());
|
||||
|
||||
bool prefabWipFeaturesEnabled = false;
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(
|
||||
prefabWipFeaturesEnabled, &AzFramework::ApplicationRequests::ArePrefabWipFeaturesEnabled);
|
||||
|
||||
if (prefabWipFeaturesEnabled)
|
||||
{
|
||||
// Register entity as a container
|
||||
s_containerEntityInterface->RegisterEntityAsContainer(entityId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PrefabIntegrationManager::OnPrefabComponentDeactivate(AZ::EntityId entityId)
|
||||
{
|
||||
bool prefabWipFeaturesEnabled = false;
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(
|
||||
prefabWipFeaturesEnabled, &AzFramework::ApplicationRequests::ArePrefabWipFeaturesEnabled);
|
||||
|
||||
if (prefabWipFeaturesEnabled && !s_prefabPublicInterface->IsLevelInstanceContainerEntity(entityId))
|
||||
{
|
||||
// Unregister entity as a container
|
||||
s_containerEntityInterface->UnregisterEntityAsContainer(entityId);
|
||||
}
|
||||
|
||||
// Unregister entity from UI Handler
|
||||
s_editorEntityUiInterface->UnregisterEntity(entityId);
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
class ContainerEntityInterface;
|
||||
|
||||
namespace Prefab
|
||||
{
|
||||
class PrefabFocusInterface;
|
||||
@@ -134,6 +136,7 @@ namespace AzToolsFramework
|
||||
|
||||
static const AZStd::string s_prefabFileExtension;
|
||||
|
||||
static ContainerEntityInterface* s_containerEntityInterface;
|
||||
static EditorEntityUiInterface* s_editorEntityUiInterface;
|
||||
static PrefabFocusInterface* s_prefabFocusInterface;
|
||||
static PrefabLoaderInterface* s_prefabLoaderInterface;
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
|
||||
#include <AzToolsFramework/UI/Prefab/PrefabUiHandler.h>
|
||||
|
||||
#include <AzFramework/API/ApplicationAPI.h>
|
||||
|
||||
#include <AzToolsFramework/Prefab/PrefabFocusInterface.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabPublicInterface.h>
|
||||
#include <AzToolsFramework/UI/Outliner/EntityOutlinerListModel.hxx>
|
||||
@@ -317,4 +319,17 @@ namespace AzToolsFramework
|
||||
|
||||
return Internal_GetLastVisibleChild(model, lastChild);
|
||||
}
|
||||
|
||||
void PrefabUiHandler::OnDoubleClick(AZ::EntityId entityId) const
|
||||
{
|
||||
bool prefabWipFeaturesEnabled = false;
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(
|
||||
prefabWipFeaturesEnabled, &AzFramework::ApplicationRequests::ArePrefabWipFeaturesEnabled);
|
||||
|
||||
if (prefabWipFeaturesEnabled)
|
||||
{
|
||||
// Focus on this prefab
|
||||
m_prefabFocusInterface->FocusOnOwningPrefab(entityId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,13 +29,14 @@ namespace AzToolsFramework
|
||||
PrefabUiHandler();
|
||||
~PrefabUiHandler() override = default;
|
||||
|
||||
// EditorEntityUiHandler...
|
||||
// EditorEntityUiHandler overrides ...
|
||||
QString GenerateItemInfoString(AZ::EntityId entityId) const override;
|
||||
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 OnDoubleClick(AZ::EntityId entityId) const override;
|
||||
|
||||
private:
|
||||
Prefab::PrefabFocusInterface* m_prefabFocusInterface = nullptr;
|
||||
|
||||
+10
-1
@@ -13,8 +13,9 @@
|
||||
#include <AzFramework/Viewport/CameraState.h>
|
||||
#include <AzFramework/Viewport/ViewportScreen.h>
|
||||
#include <AzFramework/Visibility/BoundsBus.h>
|
||||
#include <AzToolsFramework/FocusMode/FocusModeInterface.h>
|
||||
#include <AzToolsFramework/API/EditorViewportIconDisplayInterface.h>
|
||||
#include <AzToolsFramework/ContainerEntity/ContainerEntityInterface.h>
|
||||
#include <AzToolsFramework/FocusMode/FocusModeInterface.h>
|
||||
#include <AzToolsFramework/ToolsComponents/EditorEntityIconComponentBus.h>
|
||||
#include <AzToolsFramework/Viewport/ViewportMessages.h>
|
||||
#include <AzToolsFramework/Viewport/ViewportTypes.h>
|
||||
@@ -191,6 +192,14 @@ namespace AzToolsFramework
|
||||
return AZ::EntityId();
|
||||
}
|
||||
|
||||
// Container Entity support - if the entity that is being selected is part of a closed container,
|
||||
// change the selection to the container instead.
|
||||
ContainerEntityInterface* containerEntityInterface = AZ::Interface<ContainerEntityInterface>::Get();
|
||||
if (containerEntityInterface)
|
||||
{
|
||||
return containerEntityInterface->FindHighestSelectableEntity(entityIdUnderCursor);
|
||||
}
|
||||
|
||||
return entityIdUnderCursor;
|
||||
}
|
||||
|
||||
|
||||
@@ -116,6 +116,10 @@ set(FILES
|
||||
Component/EditorLevelComponentAPIBus.h
|
||||
Component/EditorLevelComponentAPIComponent.cpp
|
||||
Component/EditorLevelComponentAPIComponent.h
|
||||
ContainerEntity/ContainerEntityInterface.h
|
||||
ContainerEntity/ContainerEntityNotificationBus.h
|
||||
ContainerEntity/ContainerEntitySystemComponent.cpp
|
||||
ContainerEntity/ContainerEntitySystemComponent.h
|
||||
Editor/EditorContextMenuBus.h
|
||||
Editor/EditorSettingsAPIBus.h
|
||||
Entity/EditorEntityStartStatus.h
|
||||
|
||||
Reference in New Issue
Block a user