LYN-8631 + LYN-8632 | Display appropriate read-only icons and procedural prefabs ui in the Outliner (#6160)
* First step of procedural prefab styling and read-only registration. Signed-off-by: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com> * WIP - Introduce read-only handler for procedural prefabs (not hooked up) Signed-off-by: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com> * Introduce read-only entity interface, handler and unit tests. Signed-off-by: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com> * Introduce temp read-only icon, use new icon hierarchy in Outliner. Signed-off-by: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com> * Switch from a push paradigm to a pull paradigm - handlers get to implement logic to determine if an entity should be read-only. This allows multiple systems to weigh into whether an entity is read-only. Signed-off-by: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com> * Fixed to missing call in test Signed-off-by: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com> * Post-rebase fixes to class name changes Signed-off-by: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com> * Display a lock icon on top of the entity icon in the Entity Outliner. This icon is added programmatically, which prevents having to alter all Outliner icons and future-proofs this functionality. Signed-off-by: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com> * Minor style changes to procedural prefabs in the Outliner (use white icon) Signed-off-by: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com> * Ensure cache is refreshed when the handler is created, and also whenever the focus changes. Signed-off-by: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com> * Remove Procedural Prefab setreg that was added in the wrong place Signed-off-by: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com> * Remove redundant function Signed-off-by: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com> * Fix spacing issue caused by rebase Signed-off-by: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com> * Change tooltip so that it accurately says "inspect" instead of "edit" for procedural prefabs. Signed-off-by: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com> * Address minor styling issues mentioned in PR. Signed-off-by: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com>
This commit is contained in:
+3
@@ -0,0 +1,3 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M9.58087 1.8457C8.88135 1.8457 7.99903 2.19115 6.93392 2.88204L6.92893 2.87676C6.30965 3.2791 5.82426 3.79917 5.22899 4.43697L5.22899 4.43697C4.86895 4.82273 4.46872 5.25156 3.97436 5.72345L4.40762 6.13135C6.90029 8.44469 8.28286 9.60136 9.56289 9.60136C10.2624 9.60136 11.1447 9.25592 12.2098 8.56503L12.2148 8.57031C12.9369 8.10117 13.5717 7.47196 14.368 6.68268L14.3681 6.68264C14.6677 6.38563 14.9902 6.06596 15.3489 5.72362L14.9156 5.31571C12.4229 3.00237 10.8609 1.8457 9.58087 1.8457ZM7.6529 3.64381L7.65238 3.64325C8.14738 3.13093 8.82452 2.81518 9.57127 2.81518C11.0878 2.81518 12.3171 4.11733 12.3171 5.72362C12.3171 6.53856 12.0007 7.27522 11.4909 7.80326L11.4914 7.80381C10.9964 8.31614 10.3192 8.63189 9.57249 8.63189C8.05599 8.63189 6.82663 7.32973 6.82663 5.72345C6.82663 4.90851 7.14307 4.17185 7.6529 3.64381ZM9.56659 3.78466C9.05074 3.78466 8.58461 4.0095 8.25119 4.37149L8.25649 4.3771C7.93789 4.72586 7.74192 5.20047 7.74192 5.72345C7.74192 6.79431 8.56359 7.66241 9.57717 7.66241C10.093 7.66241 10.5592 7.43756 10.8926 7.07558L10.8873 7.06997C11.2059 6.72121 11.4018 6.24659 11.4018 5.72362C11.4018 4.65276 10.5802 3.78466 9.56659 3.78466ZM2.97474 1.99964H6.70318C6.07867 2.40803 5.53108 2.87237 5.07056 3.38303H2.97474C2.38778 3.38303 1.896 3.86007 1.896 4.44841V13.035C1.896 13.6233 2.37192 14.1003 2.97474 14.1003H11.5094C12.0964 14.1003 12.5881 13.6392 12.5881 13.035H12.6199V9.26317C13.1109 8.93674 13.5803 8.5478 14 8.10987V13.035C14 14.4025 12.8895 15.4996 11.5253 15.4996H2.97474C1.61046 15.4996 0.5 14.4025 0.5 13.035V4.44841C0.5 3.09681 1.61046 1.99964 2.97474 1.99964Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.7 KiB |
@@ -0,0 +1,3 @@
|
||||
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M3 4.60547C3 2.94862 4.34315 1.60547 6 1.60547C7.65685 1.60547 9 2.94862 9 4.60547V5.84076H10V6.60547C10 7.53544 10 8.00043 9.89778 8.38193C9.62038 9.4172 8.81173 10.2258 7.77646 10.5032C7.39496 10.6055 6.92997 10.6055 6 10.6055C5.07003 10.6055 4.60504 10.6055 4.22354 10.5032C3.18827 10.2258 2.37962 9.4172 2.10222 8.38193C2 8.00043 2 7.53544 2 6.60547V5.84076H3V4.60547ZM5.25 6.89953V9.54659H6.75V6.89953H5.25ZM6 2.66429C4.89543 2.66429 4 3.55972 4 4.66429V5.84076L8 5.84076V4.66429C8 3.55972 7.10457 2.66429 6 2.66429Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 690 B |
@@ -7,7 +7,9 @@
|
||||
<file alias="prefab.svg">Entity/prefab.svg</file>
|
||||
<file alias="prefab_edit.svg">Entity/prefab_edit.svg</file>
|
||||
<file alias="prefab_edit_open.svg">Entity/prefab_edit_open.svg</file>
|
||||
<file alias="prefab_edit_open_readonly.svg">Entity/prefab_edit_open_readonly.svg</file>
|
||||
<file alias="prefab_edit_close.svg">Entity/prefab_edit_close.svg</file>
|
||||
<file alias="readonly.svg">Entity/readonly.svg</file>
|
||||
</qresource>
|
||||
<qresource prefix="/Level">
|
||||
<file alias="level.svg">Level/level.svg</file>
|
||||
|
||||
+2
-2
@@ -37,9 +37,9 @@ namespace AzToolsFramework
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided);
|
||||
|
||||
// ReadOnlyEntityPublicNotifications overrides ...
|
||||
// ReadOnlyEntityPublicInterface overrides ...
|
||||
bool IsReadOnly(const AZ::EntityId& entityId) override;
|
||||
|
||||
|
||||
// ReadOnlyEntityQueryInterface overrides ...
|
||||
void RefreshReadOnlyState(const EntityIdList& entityIds) override;
|
||||
void RefreshReadOnlyStateForAllEntities() override;
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <AzToolsFramework/ContainerEntity/ContainerEntityInterface.h>
|
||||
#include <AzToolsFramework/Entity/EditorEntityHelpers.h>
|
||||
#include <AzToolsFramework/Entity/PrefabEditorEntityOwnershipInterface.h>
|
||||
#include <AzToolsFramework/Entity/ReadOnly/ReadOnlyEntityInterface.h>
|
||||
#include <AzToolsFramework/Prefab/Instance/Instance.h>
|
||||
#include <AzToolsFramework/Prefab/Instance/InstanceEntityMapperInterface.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabFocusNotificationBus.h>
|
||||
@@ -74,6 +75,13 @@ namespace AzToolsFramework::Prefab
|
||||
"Prefab - PrefabFocusHandler - "
|
||||
"Focus Mode Interface could not be found. "
|
||||
"Check that it is being correctly initialized.");
|
||||
|
||||
m_readOnlyEntityQueryInterface = AZ::Interface<ReadOnlyEntityQueryInterface>::Get();
|
||||
AZ_Assert(
|
||||
m_readOnlyEntityQueryInterface,
|
||||
"Prefab - PrefabFocusHandler - "
|
||||
"ReadOnly Entity Query Interface could not be found. "
|
||||
"Check that it is being correctly initialized.");
|
||||
}
|
||||
|
||||
PrefabFocusOperationResult PrefabFocusHandler::FocusOnOwningPrefab(AZ::EntityId entityId)
|
||||
@@ -186,6 +194,8 @@ namespace AzToolsFramework::Prefab
|
||||
// Close all container entities in the old path.
|
||||
CloseInstanceContainers(m_instanceFocusHierarchy);
|
||||
|
||||
AZ::EntityId previousContainerEntityId = m_focusedInstanceContainerEntityId;
|
||||
|
||||
// Do not store the container for the root instance, use an invalid EntityId instead.
|
||||
m_focusedInstanceContainerEntityId = focusedInstance->get().GetParentInstance().has_value() ? focusedInstance->get().GetContainerEntityId() : AZ::EntityId();
|
||||
m_focusedTemplateId = focusedInstance->get().GetTemplateId();
|
||||
@@ -201,6 +211,12 @@ namespace AzToolsFramework::Prefab
|
||||
m_focusModeInterface->SetFocusRoot(containerEntityId);
|
||||
}
|
||||
|
||||
// Refresh the read-only cache, if the interface is initialized.
|
||||
if (m_readOnlyEntityQueryInterface)
|
||||
{
|
||||
m_readOnlyEntityQueryInterface->RefreshReadOnlyState({ previousContainerEntityId, m_focusedInstanceContainerEntityId });
|
||||
}
|
||||
|
||||
// Refresh path variables.
|
||||
RefreshInstanceFocusList();
|
||||
RefreshInstanceFocusPath();
|
||||
|
||||
@@ -22,6 +22,7 @@ namespace AzToolsFramework
|
||||
{
|
||||
class ContainerEntityInterface;
|
||||
class FocusModeInterface;
|
||||
class ReadOnlyEntityQueryInterface;
|
||||
}
|
||||
|
||||
namespace AzToolsFramework::Prefab
|
||||
@@ -93,6 +94,7 @@ namespace AzToolsFramework::Prefab
|
||||
ContainerEntityInterface* m_containerEntityInterface = nullptr;
|
||||
FocusModeInterface* m_focusModeInterface = nullptr;
|
||||
InstanceEntityMapperInterface* m_instanceEntityMapperInterface = nullptr;
|
||||
ReadOnlyEntityQueryInterface* m_readOnlyEntityQueryInterface = nullptr;
|
||||
};
|
||||
|
||||
} // namespace AzToolsFramework::Prefab
|
||||
|
||||
@@ -918,6 +918,18 @@ namespace AzToolsFramework
|
||||
}
|
||||
}
|
||||
|
||||
bool PrefabPublicHandler::IsOwnedByProceduralPrefabInstance(AZ::EntityId entityId) const
|
||||
{
|
||||
if (InstanceOptionalReference instanceReference = m_instanceEntityMapperInterface->FindOwningInstance(entityId);
|
||||
instanceReference.has_value())
|
||||
{
|
||||
TemplateReference templateReference = m_prefabSystemComponentInterface->FindTemplate(instanceReference->get().GetTemplateId());
|
||||
return (templateReference.has_value()) && (templateReference->get().IsProcedural());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PrefabPublicHandler::IsInstanceContainerEntity(AZ::EntityId entityId) const
|
||||
{
|
||||
InstanceOptionalReference owningInstance = m_instanceEntityMapperInterface->FindOwningInstance(entityId);
|
||||
|
||||
@@ -54,6 +54,7 @@ namespace AzToolsFramework
|
||||
|
||||
PrefabOperationResult GenerateUndoNodesForEntityChangeAndUpdateCache(AZ::EntityId entityId, UndoSystem::URSequencePoint* parentUndoBatch) override;
|
||||
|
||||
bool IsOwnedByProceduralPrefabInstance(AZ::EntityId entityId) const override;
|
||||
bool IsInstanceContainerEntity(AZ::EntityId entityId) const override;
|
||||
bool IsLevelInstanceContainerEntity(AZ::EntityId entityId) const override;
|
||||
AZ::EntityId GetInstanceContainerEntityId(AZ::EntityId entityId) const override;
|
||||
|
||||
@@ -101,6 +101,13 @@ namespace AzToolsFramework
|
||||
*/
|
||||
virtual PrefabOperationResult GenerateUndoNodesForEntityChangeAndUpdateCache(
|
||||
AZ::EntityId entityId, UndoSystem::URSequencePoint* parentUndoBatch) = 0;
|
||||
|
||||
/**
|
||||
* Detects if an entity is owned by a procedural prefab.
|
||||
* @param entityId The entity to query.
|
||||
* @return True if the entity is owned by a procedural prefab instance, false otherwise.
|
||||
*/
|
||||
virtual bool IsOwnedByProceduralPrefabInstance(AZ::EntityId entityId) const = 0;
|
||||
|
||||
/**
|
||||
* Detects if an entity is the container entity for its owning prefab instance.
|
||||
|
||||
+31
-6
@@ -47,6 +47,7 @@
|
||||
#include <AzToolsFramework/Entity/EditorEntityContextBus.h>
|
||||
#include <AzToolsFramework/Entity/EditorEntityHelpers.h>
|
||||
#include <AzToolsFramework/Entity/EditorEntityInfoBus.h>
|
||||
#include <AzToolsFramework/Entity/ReadOnly/ReadOnlyEntityInterface.h>
|
||||
#include <AzToolsFramework/FocusMode/FocusModeInterface.h>
|
||||
#include <AzToolsFramework/ToolsComponents/ComponentAssetMimeDataContainer.h>
|
||||
#include <AzToolsFramework/ToolsComponents/ComponentMimeData.h>
|
||||
@@ -313,7 +314,7 @@ namespace AzToolsFramework
|
||||
|
||||
if (isEditorOnly)
|
||||
{
|
||||
return QIcon(QString(":/Icons/Entity_Editor_Only.svg"));
|
||||
return QIcon(QString(":/Entity/entity_editoronly.svg"));
|
||||
}
|
||||
|
||||
AZ::Entity* entity = nullptr;
|
||||
@@ -322,10 +323,10 @@ namespace AzToolsFramework
|
||||
|
||||
if (!isInitiallyActive)
|
||||
{
|
||||
return QIcon(QString(":/Icons/Entity_Not_Active.svg"));
|
||||
return QIcon(QString(":/Entity/entity_notactive.svg"));
|
||||
}
|
||||
|
||||
return QIcon(QString(":/Icons/Entity.svg"));
|
||||
return QIcon(QString(":/Entity/entity.svg"));
|
||||
}
|
||||
|
||||
QVariant EntityOutlinerListModel::GetEntityTooltip(const AZ::EntityId& id) const
|
||||
@@ -1994,9 +1995,13 @@ namespace AzToolsFramework
|
||||
, m_lockCheckBoxes(parent, "Lock", EntityOutlinerListModel::PartiallyLockedRole, EntityOutlinerListModel::LockedAncestorRole)
|
||||
{
|
||||
m_editorEntityFrameworkInterface = AZ::Interface<AzToolsFramework::EditorEntityUiInterface>::Get();
|
||||
|
||||
AZ_Assert((m_editorEntityFrameworkInterface != nullptr),
|
||||
"EntityOutlinerItemDelegate requires a EditorEntityFrameworkInterface instance on Construction.");
|
||||
|
||||
m_readOnlyEntityPublicInterface = AZ::Interface<AzToolsFramework::ReadOnlyEntityPublicInterface>::Get();
|
||||
AZ_Assert(
|
||||
(m_readOnlyEntityPublicInterface != nullptr),
|
||||
"EntityOutlinerItemDelegate requires a ReadOnlyEntityPublicInterface instance on Construction.");
|
||||
}
|
||||
|
||||
EntityOutlinerItemDelegate::CheckboxGroup::CheckboxGroup(QWidget* parent, AZStd::string prefix,
|
||||
@@ -2108,6 +2113,12 @@ namespace AzToolsFramework
|
||||
}
|
||||
|
||||
PaintEntityNameAsRichText(painter, customOption, index);
|
||||
|
||||
// Paint Read-Only icon if necessary
|
||||
if (m_readOnlyEntityPublicInterface->IsReadOnly(entityId))
|
||||
{
|
||||
PaintReadOnlyIcon(painter, option, index);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -2166,10 +2177,10 @@ namespace AzToolsFramework
|
||||
|
||||
backgroundPath.addRect(backgroundRect);
|
||||
|
||||
QColor backgroundColor = m_hoverColor;
|
||||
QColor backgroundColor = s_hoverColor;
|
||||
if (isSelected)
|
||||
{
|
||||
backgroundColor = m_selectedColor;
|
||||
backgroundColor = s_selectedColor;
|
||||
}
|
||||
|
||||
painter->fillPath(backgroundPath, backgroundColor);
|
||||
@@ -2336,6 +2347,20 @@ namespace AzToolsFramework
|
||||
EntityOutlinerListModel::s_paintingName = false;
|
||||
}
|
||||
|
||||
void EntityOutlinerItemDelegate::PaintReadOnlyIcon(QPainter* painter, const QStyleOptionViewItem& option, [[maybe_unused]] const QModelIndex& index) const
|
||||
{
|
||||
// Build the rect that will be used to paint the icon
|
||||
QRect readOnlyRect = QRect(option.rect.topLeft() + s_readOnlyOffset, QSize(s_readOnlyRadius * 2, s_readOnlyRadius * 2));
|
||||
|
||||
painter->save();
|
||||
painter->setRenderHint(QPainter::Antialiasing, true);
|
||||
painter->setPen(Qt::NoPen);
|
||||
painter->setBrush(s_readOnlyBackgroundColor);
|
||||
painter->drawEllipse(readOnlyRect.center(), s_readOnlyRadius, s_readOnlyRadius);
|
||||
s_readOnlyIcon.paint(painter, readOnlyRect);
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
QSize EntityOutlinerItemDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& /*index*/) const
|
||||
{
|
||||
// Get the height of a tall character...
|
||||
|
||||
+13
-2
@@ -38,6 +38,7 @@ namespace AzToolsFramework
|
||||
{
|
||||
class EditorEntityUiInterface;
|
||||
class FocusModeInterface;
|
||||
class ReadOnlyEntityPublicInterface;
|
||||
|
||||
namespace EntityOutliner
|
||||
{
|
||||
@@ -344,6 +345,9 @@ namespace AzToolsFramework
|
||||
// Paint the entity name using rich text
|
||||
void PaintEntityNameAsRichText(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;
|
||||
|
||||
// Paint the read-only icon on the entity
|
||||
void PaintReadOnlyIcon(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;
|
||||
|
||||
struct CheckboxGroup
|
||||
{
|
||||
EntityOutlinerCheckBox m_default;
|
||||
@@ -372,10 +376,17 @@ namespace AzToolsFramework
|
||||
// this is a cache, and is hence mutable
|
||||
mutable QRect m_cachedBoundingRectOfTallCharacter;
|
||||
|
||||
const QColor m_selectedColor = QColor(255, 255, 255, 45);
|
||||
const QColor m_hoverColor = QColor(255, 255, 255, 30);
|
||||
inline static const QColor s_selectedColor = QColor(255, 255, 255, 45);
|
||||
inline static const QColor s_hoverColor = QColor(255, 255, 255, 30);
|
||||
|
||||
inline static const QColor s_readOnlyBackgroundColor = QColor("#444444");
|
||||
inline static const QPoint s_readOnlyOffset = QPoint(10, 10);
|
||||
inline static const int s_readOnlyRadius = 6;
|
||||
|
||||
QIcon s_readOnlyIcon = QIcon(QString(":/Entity/readonly.svg"));
|
||||
|
||||
EditorEntityUiInterface* m_editorEntityFrameworkInterface = nullptr;
|
||||
ReadOnlyEntityPublicInterface* m_readOnlyEntityPublicInterface = nullptr;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
+9
-1
@@ -27,6 +27,7 @@
|
||||
#include <AzToolsFramework/Entity/EditorEntityContextBus.h>
|
||||
#include <AzToolsFramework/Prefab/EditorPrefabComponent.h>
|
||||
#include <AzToolsFramework/Prefab/Instance/InstanceEntityMapperInterface.h>
|
||||
#include <AzToolsFramework/Prefab/Instance/InstanceToTemplateInterface.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabFocusInterface.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabFocusPublicInterface.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabLoaderInterface.h>
|
||||
@@ -1264,7 +1265,14 @@ namespace AzToolsFramework
|
||||
}
|
||||
else
|
||||
{
|
||||
s_editorEntityUiInterface->RegisterEntity(entityId, m_prefabUiHandler.GetHandlerId());
|
||||
if (s_prefabPublicInterface->IsOwnedByProceduralPrefabInstance(entityId))
|
||||
{
|
||||
s_editorEntityUiInterface->RegisterEntity(entityId, m_proceduralPrefabUiHandler.GetHandlerId());
|
||||
}
|
||||
else
|
||||
{
|
||||
s_editorEntityUiInterface->RegisterEntity(entityId, m_prefabUiHandler.GetHandlerId());
|
||||
}
|
||||
|
||||
// Register entity as a container
|
||||
s_containerEntityInterface->RegisterEntityAsContainer(entityId);
|
||||
|
||||
+10
-3
@@ -18,10 +18,11 @@
|
||||
#include <AzToolsFramework/Prefab/PrefabPublicInterface.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabSystemComponentInterface.h>
|
||||
#include <AzToolsFramework/UI/Prefab/LevelRootUiHandler.h>
|
||||
|
||||
#include <AzToolsFramework/UI/Prefab/PrefabIntegrationBus.h>
|
||||
#include <AzToolsFramework/UI/Prefab/PrefabIntegrationInterface.h>
|
||||
#include <AzToolsFramework/UI/Prefab/PrefabUiHandler.h>
|
||||
#include <AzToolsFramework/UI/Prefab/Procedural/ProceduralPrefabReadOnlyHandler.h>
|
||||
#include <AzToolsFramework/UI/Prefab/Procedural/ProceduralPrefabUiHandler.h>
|
||||
|
||||
#include <AzQtComponents/Components/Widgets/Card.h>
|
||||
|
||||
@@ -92,12 +93,18 @@ namespace AzToolsFramework
|
||||
void ExecuteSavePrefabDialog(TemplateId templateId, bool useSaveAllPrefabsPreference) override;
|
||||
|
||||
private:
|
||||
// Used to handle the UI for the level root
|
||||
// Used to handle the UI for the level root.
|
||||
LevelRootUiHandler m_levelRootUiHandler;
|
||||
|
||||
// Used to handle the UI for prefab entities
|
||||
// Used to handle the UI for prefab entities.
|
||||
PrefabUiHandler m_prefabUiHandler;
|
||||
|
||||
// Used to handle the UI for procedural prefab entities.
|
||||
ProceduralPrefabUiHandler m_proceduralPrefabUiHandler;
|
||||
|
||||
// Ensures entities owned by procedural prefab instances are marked as read-only correctly.
|
||||
ProceduralPrefabReadOnlyHandler m_proceduralPrefabReadOnlyHandler;
|
||||
|
||||
// Context menu item handlers
|
||||
static void ContextMenu_CreatePrefab(AzToolsFramework::EntityIdList selectedEntities);
|
||||
static void ContextMenu_InstantiatePrefab();
|
||||
|
||||
@@ -23,17 +23,6 @@ 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");
|
||||
const QColor PrefabUiHandler::m_prefabCapsuleColor = QColor("#1E252F");
|
||||
const QColor PrefabUiHandler::m_prefabCapsuleDisabledColor = QColor("#35383C");
|
||||
const QColor PrefabUiHandler::m_prefabCapsuleEditColor = QColor("#4A90E2");
|
||||
const QString PrefabUiHandler::m_prefabIconPath = QString(":/Entity/prefab.svg");
|
||||
const QString PrefabUiHandler::m_prefabEditIconPath = QString(":/Entity/prefab_edit.svg");
|
||||
const QString PrefabUiHandler::m_prefabEditOpenIconPath = QString(":/Entity/prefab_edit_open.svg");
|
||||
const QString PrefabUiHandler::m_prefabEditCloseIconPath = QString(":/Entity/prefab_edit_close.svg");
|
||||
|
||||
PrefabUiHandler::PrefabUiHandler()
|
||||
{
|
||||
m_prefabPublicInterface = AZ::Interface<Prefab::PrefabPublicInterface>::Get();
|
||||
|
||||
@@ -46,7 +46,7 @@ namespace AzToolsFramework
|
||||
void OnOutlinerItemCollapse(const QModelIndex& index) const override;
|
||||
bool OnEntityDoubleClick(AZ::EntityId entityId) const override;
|
||||
|
||||
private:
|
||||
protected:
|
||||
Prefab::PrefabFocusPublicInterface* m_prefabFocusPublicInterface = nullptr;
|
||||
Prefab::PrefabPublicInterface* m_prefabPublicInterface = nullptr;
|
||||
|
||||
@@ -56,17 +56,17 @@ namespace AzToolsFramework
|
||||
|
||||
static AzFramework::EntityContextId s_editorEntityContextId;
|
||||
|
||||
static constexpr int m_prefabCapsuleRadius = 6;
|
||||
static constexpr int m_prefabBorderThickness = 2;
|
||||
static const QColor m_backgroundColor;
|
||||
static const QColor m_backgroundHoverColor;
|
||||
static const QColor m_backgroundSelectedColor;
|
||||
static const QColor m_prefabCapsuleColor;
|
||||
static const QColor m_prefabCapsuleDisabledColor;
|
||||
static const QColor m_prefabCapsuleEditColor;
|
||||
static const QString m_prefabIconPath;
|
||||
static const QString m_prefabEditIconPath;
|
||||
static const QString m_prefabEditOpenIconPath;
|
||||
static const QString m_prefabEditCloseIconPath;
|
||||
int m_prefabCapsuleRadius = 6;
|
||||
int m_prefabBorderThickness = 2;
|
||||
QColor m_backgroundColor = QColor("#444444");
|
||||
QColor m_backgroundHoverColor = QColor("#5A5A5A");
|
||||
QColor m_backgroundSelectedColor = QColor("#656565");
|
||||
QColor m_prefabCapsuleColor = QColor("#1E252F");
|
||||
QColor m_prefabCapsuleDisabledColor = QColor("#35383C");
|
||||
QColor m_prefabCapsuleEditColor = QColor("#4A90E2");
|
||||
QString m_prefabIconPath = QString(":/Entity/prefab.svg");
|
||||
QString m_prefabEditIconPath = QString(":/Entity/prefab_edit.svg");
|
||||
QString m_prefabEditOpenIconPath = QString(":/Entity/prefab_edit_open.svg");
|
||||
QString m_prefabEditCloseIconPath = QString(":/Entity/prefab_edit_close.svg");
|
||||
};
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* 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/UI/Prefab/Procedural/ProceduralPrefabReadOnlyHandler.h>
|
||||
|
||||
#include <AzToolsFramework/Entity/EditorEntityContextBus.h>
|
||||
#include <AzToolsFramework/Entity/ReadOnly/ReadOnlyEntityInterface.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabPublicInterface.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabFocusPublicInterface.h>
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
namespace Prefab
|
||||
{
|
||||
ProceduralPrefabReadOnlyHandler::ProceduralPrefabReadOnlyHandler()
|
||||
{
|
||||
m_prefabPublicInterface = AZ::Interface<PrefabPublicInterface>::Get();
|
||||
AZ_Assert(
|
||||
m_prefabPublicInterface != nullptr,
|
||||
"ProceduralPrefabReadOnlyHandler requires a PrefabPublicInterface instance on Initialize.");
|
||||
|
||||
m_prefabFocusPublicInterface = AZ::Interface<PrefabFocusPublicInterface>::Get();
|
||||
AZ_Assert(
|
||||
m_prefabFocusPublicInterface != nullptr,
|
||||
"ProceduralPrefabReadOnlyHandler requires a PrefabFocusPublicInterface instance on Initialize.");
|
||||
|
||||
AzFramework::EntityContextId editorEntityContextId = AzFramework::EntityContextId::CreateNull();
|
||||
EditorEntityContextRequestBus::BroadcastResult(editorEntityContextId, &EditorEntityContextRequests::GetEditorEntityContextId);
|
||||
|
||||
ReadOnlyEntityQueryRequestBus::Handler::BusConnect(editorEntityContextId);
|
||||
|
||||
// Refresh the whole read-only cache
|
||||
if (auto readOnlyEntityQueryInterface = AZ::Interface<ReadOnlyEntityQueryInterface>::Get())
|
||||
{
|
||||
readOnlyEntityQueryInterface->RefreshReadOnlyStateForAllEntities();
|
||||
}
|
||||
}
|
||||
|
||||
ProceduralPrefabReadOnlyHandler ::~ProceduralPrefabReadOnlyHandler()
|
||||
{
|
||||
ReadOnlyEntityQueryRequestBus::Handler::BusDisconnect();
|
||||
}
|
||||
|
||||
void ProceduralPrefabReadOnlyHandler::IsReadOnly(const AZ::EntityId& entityId, bool& isReadOnly)
|
||||
{
|
||||
if(m_prefabPublicInterface->IsOwnedByProceduralPrefabInstance(entityId))
|
||||
{
|
||||
// All entities nested inside a procedural prefabs should always be marked as read-only.
|
||||
if (!m_prefabPublicInterface->IsInstanceContainerEntity(entityId))
|
||||
{
|
||||
isReadOnly = true;
|
||||
}
|
||||
|
||||
// The container entity of a procedural prefab should only be marked as read-only when the prefab is being edited.
|
||||
if (m_prefabFocusPublicInterface->IsOwningPrefabBeingFocused(entityId))
|
||||
{
|
||||
isReadOnly = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Prefab
|
||||
} // namespace AzToolsFramework
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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/Memory/SystemAllocator.h>
|
||||
#include <AzCore/RTTI/RTTI.h>
|
||||
|
||||
#include <AzToolsFramework/Entity/ReadOnly/ReadOnlyEntityBus.h>
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
namespace Prefab
|
||||
{
|
||||
class PrefabFocusPublicInterface;
|
||||
class PrefabPublicInterface;
|
||||
|
||||
//! Ensures entities in a procedural prefab are correctly reported as read-only.
|
||||
class ProceduralPrefabReadOnlyHandler
|
||||
: public ReadOnlyEntityQueryRequestBus::Handler
|
||||
{
|
||||
public:
|
||||
AZ_CLASS_ALLOCATOR(ProceduralPrefabReadOnlyHandler, AZ::SystemAllocator, 0);
|
||||
AZ_RTTI(AzToolsFramework::ProceduralPrefabReadOnlyHandler, "{A2D72461-8CA3-45EE-81D2-4976BC0B6AE9}");
|
||||
|
||||
ProceduralPrefabReadOnlyHandler();
|
||||
~ProceduralPrefabReadOnlyHandler() override;
|
||||
|
||||
// ReadOnlyEntityQueryRequestBus overrides ...
|
||||
void IsReadOnly(const AZ::EntityId& entityId, bool& isReadOnly) override;
|
||||
|
||||
private:
|
||||
PrefabPublicInterface* m_prefabPublicInterface = nullptr;
|
||||
PrefabFocusPublicInterface* m_prefabFocusPublicInterface = nullptr;
|
||||
};
|
||||
|
||||
} // namespace Prefab
|
||||
} // namespace AzToolsFramework
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* 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/UI/Prefab/Procedural/ProceduralPrefabUiHandler.h>
|
||||
|
||||
#include <AzToolsFramework/Prefab/PrefabPublicInterface.h>
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
ProceduralPrefabUiHandler::ProceduralPrefabUiHandler()
|
||||
{
|
||||
m_prefabCapsuleColor = QColor("#361561");
|
||||
m_prefabCapsuleDisabledColor = QColor("#4B3455");
|
||||
m_prefabCapsuleEditColor = QColor("#361561");
|
||||
m_prefabIconPath = QString(":/Entity/prefab_edit.svg");
|
||||
m_prefabEditOpenIconPath = QString(":/Entity/prefab_edit_open_readonly.svg");
|
||||
}
|
||||
|
||||
QString ProceduralPrefabUiHandler::GenerateItemTooltip(AZ::EntityId entityId) const
|
||||
{
|
||||
if (AZ::IO::Path path = m_prefabPublicInterface->GetOwningInstancePrefabPath(entityId); !path.empty())
|
||||
{
|
||||
return QObject::tr("Double click to inspect.\n%1").arg(path.Native().data());
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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 <AzToolsFramework/UI/Prefab/PrefabUiHandler.h>
|
||||
|
||||
#include <AzFramework/Entity/EntityContextBus.h>
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
namespace Prefab
|
||||
{
|
||||
class PrefabFocusPublicInterface;
|
||||
class PrefabPublicInterface;
|
||||
};
|
||||
|
||||
//! Implements the Editor UI for Procedural Prefabs.
|
||||
class ProceduralPrefabUiHandler
|
||||
: public PrefabUiHandler
|
||||
{
|
||||
public:
|
||||
AZ_CLASS_ALLOCATOR(ProceduralPrefabUiHandler, AZ::SystemAllocator, 0);
|
||||
AZ_RTTI(AzToolsFramework::ProceduralPrefabUiHandler, "{3A3DF9FF-9C2E-4439-B7B4-72173B5A3502}", PrefabUiHandler);
|
||||
|
||||
ProceduralPrefabUiHandler();
|
||||
~ProceduralPrefabUiHandler() override = default;
|
||||
|
||||
QString GenerateItemTooltip(AZ::EntityId entityId) const override;
|
||||
};
|
||||
} // namespace AzToolsFramework
|
||||
@@ -768,6 +768,10 @@ set(FILES
|
||||
UI/Prefab/PrefabUiHandler.cpp
|
||||
UI/Prefab/PrefabViewportFocusPathHandler.h
|
||||
UI/Prefab/PrefabViewportFocusPathHandler.cpp
|
||||
UI/Prefab/Procedural/ProceduralPrefabReadOnlyHandler.h
|
||||
UI/Prefab/Procedural/ProceduralPrefabReadOnlyHandler.cpp
|
||||
UI/Prefab/Procedural/ProceduralPrefabUiHandler.h
|
||||
UI/Prefab/Procedural/ProceduralPrefabUiHandler.cpp
|
||||
UI/Notifications/ToastNotificationsView.cpp
|
||||
UI/Notifications/ToastNotificationsView.h
|
||||
UI/Notifications/ToastBus.h
|
||||
|
||||
@@ -96,4 +96,22 @@ namespace AzToolsFramework
|
||||
// Verify the child entity is no longer marked as read-only
|
||||
EXPECT_FALSE(m_readOnlyEntityPublicInterface->IsReadOnly(m_entityMap[ChildEntityName]));
|
||||
}
|
||||
|
||||
TEST_F(ReadOnlyEntityFixture, EnsureCacheIsClearedCorrectlyEvenIfUnchanged)
|
||||
{
|
||||
// Create a handler that sets all entities to read-only.
|
||||
ReadOnlyHandlerAlwaysTrue alwaysTrueHandler;
|
||||
|
||||
{
|
||||
// Create a handler that sets the child entity to read-only.
|
||||
ReadOnlyHandlerEntityId entityIdHandler(m_entityMap[ChildEntityName]);
|
||||
|
||||
// Verify the child entity is marked as read-only
|
||||
EXPECT_TRUE(m_readOnlyEntityPublicInterface->IsReadOnly(m_entityMap[ChildEntityName]));
|
||||
}
|
||||
// When the handler goes out of scope, it calls RefreshReadOnlyStateForAllEntities and refreshes the cache.
|
||||
|
||||
// Verify the child entity is still marked as read-only
|
||||
EXPECT_TRUE(m_readOnlyEntityPublicInterface->IsReadOnly(m_entityMap[ChildEntityName]));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user