123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503 |
- /*
- * 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 <Components/Slots/Data/DataSlotComponent.h>
- #include <Components/Connections/ConnectionComponent.h>
- #include <Components/Connections/DataConnections/DataConnectionComponent.h>
- #include <Components/Slots/Data/DataSlotConnectionPin.h>
- #include <Components/Slots/Data/DataSlotLayoutComponent.h>
- #include <Components/Slots/SlotConnectionFilterComponent.h>
- #include <Components/StylingComponent.h>
- #include <GraphCanvas/Components/Connections/ConnectionFilters/ConnectionFilters.h>
- #include <GraphCanvas/Components/Connections/ConnectionFilters/DataConnectionFilters.h>
- #include <GraphCanvas/Components/StyleBus.h>
- namespace GraphCanvas
- {
- //////////////////////
- // DataSlotComponent
- //////////////////////
- void DataSlotComponent::Reflect(AZ::ReflectContext* reflectContext)
- {
- AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(reflectContext);
- if (serializeContext)
- {
- serializeContext->Class<DataSlotComponent, SlotComponent>()
- ->Version(6)
- ->Field("TypeId", &DataSlotComponent::m_dataTypeId)
- ->Field("DataSlotType", &DataSlotComponent::m_dataSlotType)
- ->Field("CanConvertSlotTypes", &DataSlotComponent::m_canConvertSlotTypes)
- ->Field("ContainedTypeIds", &DataSlotComponent::m_containedTypeIds)
- ->Field("DataValueType", &DataSlotComponent::m_valueType)
- ->Field("IsUserSlot", &DataSlotComponent::m_isUserSlot)
- ;
- }
- }
- AZ::Entity* DataSlotComponent::CreateDataSlot(const AZ::EntityId& nodeId, const DataSlotConfiguration& dataSlotConfiguration)
- {
- AZ::Entity* entity = SlotComponent::CreateCoreSlotEntity();
- DataSlotComponent* dataSlot = aznew DataSlotComponent(dataSlotConfiguration);
- if (!entity->AddComponent(dataSlot))
- {
- delete dataSlot;
- delete entity;
- return nullptr;
- }
- entity->CreateComponent<DataSlotLayoutComponent>();
- AZStd::string styleClass;
- StyledEntityRequestBus::EventResult(styleClass, nodeId, &StyledEntityRequests::GetClass);
- entity->CreateComponent<StylingComponent>(Styling::Elements::DataSlot, nodeId, styleClass);
- SlotConnectionFilterComponent* connectionFilter = entity->CreateComponent<SlotConnectionFilterComponent>();
- SlotTypeFilter* slotTypeFilter = aznew SlotTypeFilter(ConnectionFilterType::Include);
- slotTypeFilter->AddSlotType(SlotTypes::DataSlot);
- connectionFilter->AddFilter(slotTypeFilter);
- ConnectionTypeFilter* connectionTypeFilter = aznew ConnectionTypeFilter(ConnectionFilterType::Include);
- switch (dataSlot->GetConnectionType())
- {
- case ConnectionType::CT_Input:
- connectionTypeFilter->AddConnectionType(CT_Output);
- break;
- case ConnectionType::CT_Output:
- connectionTypeFilter->AddConnectionType(CT_Input);
- break;
- default:
- break;
- };
- connectionFilter->AddFilter(connectionTypeFilter);
- connectionFilter->AddFilter(aznew DataSlotTypeFilter());
- return entity;
- }
-
- DataSlotComponent::DataSlotComponent()
- : SlotComponent(SlotTypes::DataSlot)
- , m_canConvertSlotTypes(false)
- , m_dataSlotType(DataSlotType::Value)
- , m_valueType(DataValueType::Primitive)
- , m_dataTypeId(AZ::Uuid::CreateNull())
- , m_previousDataSlotType(DataSlotType::Unknown)
- , m_isUserSlot(false)
- {
- if (m_slotConfiguration.m_slotGroup == SlotGroups::Invalid)
- {
- m_slotConfiguration.m_slotGroup = SlotGroups::DataGroup;
- }
- }
- DataSlotComponent::DataSlotComponent(const DataSlotConfiguration& dataSlotConfiguration)
- : SlotComponent(SlotTypes::DataSlot, dataSlotConfiguration)
- , m_canConvertSlotTypes(dataSlotConfiguration.m_canConvertTypes)
- , m_dataSlotType(dataSlotConfiguration.m_dataSlotType)
- , m_valueType(dataSlotConfiguration.m_dataValueType)
- , m_dataTypeId(dataSlotConfiguration.m_typeId)
- , m_containedTypeIds(dataSlotConfiguration.m_containerTypeIds)
- , m_previousDataSlotType(DataSlotType::Unknown)
- , m_isUserSlot(dataSlotConfiguration.m_isUserAdded)
- {
- if (m_slotConfiguration.m_slotGroup == SlotGroups::Invalid)
- {
- m_slotConfiguration.m_slotGroup = SlotGroups::DataGroup;
- }
- }
- DataSlotComponent::~DataSlotComponent()
- {
- }
-
- void DataSlotComponent::Init()
- {
- SlotComponent::Init();
- }
-
- void DataSlotComponent::Activate()
- {
- SlotComponent::Activate();
-
- DataSlotRequestBus::Handler::BusConnect(GetEntityId());
- // Will usually happen in a copy/paste scenario
- if (m_valueType == DataValueType::Container)
- {
- SetDataAndContainedTypeIds(m_dataTypeId, m_containedTypeIds, m_valueType);
- }
- }
-
- void DataSlotComponent::Deactivate()
- {
- SlotComponent::Deactivate();
-
- DataSlotRequestBus::Handler::BusDisconnect();
- }
- void DataSlotComponent::DisplayProposedConnection(const AZ::EntityId& connectionId, const Endpoint& endpoint)
- {
- const bool updateDisplay = false;
- RestoreDisplay(updateDisplay);
- DataSlotType slotType = DataSlotType::Unknown;
- DataSlotRequestBus::EventResult(slotType, endpoint.GetSlotId(), &DataSlotRequests::GetDataSlotType);
- m_displayedConnection = connectionId;
- m_connections.emplace_back(m_displayedConnection);
- m_previousDataSlotType = m_dataSlotType;
- bool isDisabled = false;
- if (slotType == DataSlotType::Value)
- {
- m_dataSlotType = DataSlotType::Value;
- isDisabled = HasConnections();
- }
- else if (slotType == DataSlotType::Reference)
- {
- if (DataSlotUtils::IsValueDataReferenceType(m_dataSlotType) || CanConvertToReference())
- {
- m_dataSlotType = DataSlotType::Reference;
- }
- }
- if (m_previousDataSlotType != m_dataSlotType)
- {
- DataSlotNotificationBus::Event(GetEntityId(), &DataSlotNotifications::OnDataSlotTypeChanged, m_dataSlotType);
- }
- NodePropertyRequestBus::Event(GetEntityId(), &NodePropertyRequests::SetDisabled, isDisabled);
- UpdateDisplay();
- }
- void DataSlotComponent::RemoveProposedConnection(const AZ::EntityId& /*connectionId*/, const Endpoint& /*endpoint*/)
- {
- RestoreDisplay(true);
- }
- void DataSlotComponent::AddConnectionId(const AZ::EntityId& connectionId, const Endpoint& endpoint)
- {
- SlotComponent::AddConnectionId(connectionId, endpoint);
- if (m_dataSlotType == DataSlotType::Value)
- {
- NodePropertyRequestBus::Event(GetEntityId(), &NodePropertyRequests::SetDisabled, true);
- }
- else if (m_dataSlotType == DataSlotType::Reference)
- {
- NodePropertyRequestBus::Event(GetEntityId(), &NodePropertyRequests::SetDisabled, false);
- }
- else
- {
- NodePropertyRequestBus::Event(GetEntityId(), &NodePropertyRequests::SetDisabled, HasConnections());
- }
- }
- void DataSlotComponent::RemoveConnectionId(const AZ::EntityId& connectionId, const Endpoint& endpoint)
- {
- SlotComponent::RemoveConnectionId(connectionId, endpoint);
- NodePropertyRequestBus::Event(GetEntityId(), &NodePropertyRequests::SetDisabled, HasConnections());
- }
- void DataSlotComponent::SetNode(const AZ::EntityId& nodeId)
- {
- SlotComponent::SetNode(nodeId);
- }
- SlotConfiguration* DataSlotComponent::CloneSlotConfiguration() const
- {
- DataSlotConfiguration* slotConfiguration = aznew DataSlotConfiguration();
- slotConfiguration->m_dataSlotType = GetDataSlotType();
- slotConfiguration->m_typeId = GetDataTypeId();
- slotConfiguration->m_containerTypeIds = m_containedTypeIds;
- slotConfiguration->m_isUserAdded = m_isUserSlot;
- PopulateSlotConfiguration((*slotConfiguration));
- return slotConfiguration;
- }
- void DataSlotComponent::UpdateDisplay()
- {
- DataSlotLayoutRequestBus::Event(GetEntityId(), &DataSlotLayoutRequests::UpdateDisplay);
- }
- void DataSlotComponent::RestoreDisplay(bool updateDisplay)
- {
- if (m_previousDataSlotType != DataSlotType::Unknown)
- {
- bool typeChanged = m_dataSlotType != m_previousDataSlotType;
- m_dataSlotType = m_previousDataSlotType;
- if (m_displayedConnection.IsValid())
- {
- for (auto connectionIter = m_connections.begin(); connectionIter != m_connections.end(); ++connectionIter)
- {
- if (*connectionIter == m_displayedConnection)
- {
- m_connections.erase(connectionIter);
- break;
- }
- }
- }
- if (updateDisplay)
- {
- UpdatePropertyDisplayState();
- if (typeChanged)
- {
- DataSlotNotificationBus::Event(GetEntityId(), &DataSlotNotifications::OnDataSlotTypeChanged, m_dataSlotType);
- }
- UpdateDisplay();
- }
- m_previousDataSlotType = DataSlotType::Unknown;
- m_displayedConnection.SetInvalid();
- }
- }
- void DataSlotComponent::OnFinalizeDisplay()
- {
- UpdatePropertyDisplayState();
- }
- void DataSlotComponent::UpdatePropertyDisplayState()
- {
- if (m_dataSlotType == DataSlotType::Reference)
- {
- NodePropertyRequestBus::Event(GetEntityId(), &NodePropertyRequests::SetDisabled, false);
- }
- else if (DataSlotUtils::IsValueDataSlotType(m_dataSlotType))
- {
- NodePropertyRequestBus::Event(GetEntityId(), &NodePropertyRequests::SetDisabled, HasConnections());
- }
- }
- bool DataSlotComponent::ConvertToReference(bool isNewSlot)
- {
- if (CanConvertToReference(isNewSlot))
- {
- AZ::EntityId nodeId = GetNode();
- GraphId graphId;
- SceneMemberRequestBus::EventResult(graphId, nodeId, &SceneMemberRequests::GetScene);
- {
- ScopedGraphUndoBlocker undoBlocker(graphId);
- bool convertedToReference = false;
- GraphModelRequestBus::EventResult(convertedToReference, graphId, &GraphModelRequests::ConvertSlotToReference, Endpoint(nodeId, GetEntityId()), isNewSlot);
- if (convertedToReference)
- {
- m_dataSlotType = DataSlotType::Reference;
- DataSlotNotificationBus::Event(GetEntityId(), &DataSlotNotifications::OnDataSlotTypeChanged, m_dataSlotType);
- NodePropertyRequestBus::Event(GetEntityId(), &NodePropertyRequests::SetDisabled, false);
- }
- }
- if (m_dataSlotType == DataSlotType::Reference)
- {
- GraphModelRequestBus::Event(graphId, &GraphModelRequests::RequestUndoPoint);
- }
- }
- return m_dataSlotType == DataSlotType::Reference;
- }
- bool DataSlotComponent::CanConvertToReference([[maybe_unused]] bool isNewSlot) const
- {
- bool canToggleReference = false;
- if (m_canConvertSlotTypes && DataSlotUtils::IsValueDataSlotType(m_dataSlotType) && !HasConnections())
- {
- AZ::EntityId nodeId = GetNode();
- GraphId graphId;
- SceneMemberRequestBus::EventResult(graphId, nodeId, &SceneMemberRequests::GetScene);
- GraphModelRequestBus::EventResult(canToggleReference, graphId, &GraphModelRequests::CanConvertSlotToReference, Endpoint(nodeId, GetEntityId()), isNewSlot);
- }
- return canToggleReference;
- }
- bool DataSlotComponent::ConvertToValue()
- {
- if (CanConvertToValue())
- {
- AZ::EntityId nodeId = GetNode();
- GraphId graphId;
- SceneMemberRequestBus::EventResult(graphId, nodeId, &SceneMemberRequests::GetScene);
- {
- ScopedGraphUndoBlocker undoBlocker(graphId);
-
- bool converted = false;
- GraphModelRequestBus::EventResult(converted, graphId, &GraphModelRequests::ConvertSlotToValue, Endpoint(nodeId, GetEntityId()));
- if (converted)
- {
- m_dataSlotType = DataSlotType::Value;
- DataSlotNotificationBus::Event(GetEntityId(), &DataSlotNotifications::OnDataSlotTypeChanged, m_dataSlotType);
- NodePropertyRequestBus::Event(GetEntityId(), &NodePropertyRequests::SetDisabled, HasConnections());
- }
- }
- if (DataSlotUtils::IsValueDataSlotType(m_dataSlotType))
- {
- GraphModelRequestBus::Event(graphId, &GraphModelRequests::RequestUndoPoint);
- }
- }
- return DataSlotUtils::IsValueDataSlotType(m_dataSlotType);
- }
- bool DataSlotComponent::CanConvertToValue() const
- {
- bool canConvertToValue = false;
- if (m_canConvertSlotTypes && m_dataSlotType == DataSlotType::Reference)
- {
- AZ::EntityId nodeId = GetNode();
- GraphId graphId;
- SceneMemberRequestBus::EventResult(graphId, nodeId, &SceneMemberRequests::GetScene);
- GraphModelRequestBus::EventResult(canConvertToValue, graphId, &GraphModelRequests::CanConvertSlotToValue, Endpoint(nodeId, GetEntityId()));
- }
- return canConvertToValue;
- }
- DataSlotType DataSlotComponent::GetDataSlotType() const
- {
- return m_dataSlotType;
- }
- DataValueType DataSlotComponent::GetDataValueType() const
- {
- return m_valueType;
- }
- AZ::Uuid DataSlotComponent::GetDataTypeId() const
- {
- return m_dataTypeId;
- }
- void DataSlotComponent::SetDataTypeId(AZ::Uuid typeId)
- {
- if (m_dataTypeId != typeId)
- {
- m_dataTypeId = typeId;
- UpdateDisplay();
- }
- }
- bool DataSlotComponent::IsUserSlot() const
- {
- return m_isUserSlot;
- }
- const Styling::StyleHelper* DataSlotComponent::GetDataColorPalette() const
- {
- AZ::EntityId sceneId;
- SceneMemberRequestBus::EventResult(sceneId, GetEntityId(), &SceneMemberRequests::GetScene);
- EditorId editorId;
- SceneRequestBus::EventResult(editorId, sceneId, &SceneRequests::GetEditorId);
- const Styling::StyleHelper* stylingHelper = nullptr;
- StyleManagerRequestBus::EventResult(stylingHelper, editorId, &StyleManagerRequests::FindDataColorPalette, m_dataTypeId);
- return stylingHelper;
- }
- size_t DataSlotComponent::GetContainedTypesCount() const
- {
- return m_containedTypeIds.size();
- }
- AZ::Uuid DataSlotComponent::GetContainedTypeId(size_t index) const
- {
- return m_containedTypeIds[index];
- }
- const GraphCanvas::Styling::StyleHelper* DataSlotComponent::GetContainedTypeColorPalette(size_t index) const
- {
- AZ::Uuid dataTypeId = m_containedTypeIds[index];
- AZ::EntityId sceneId;
- SceneMemberRequestBus::EventResult(sceneId, GetEntityId(), &SceneMemberRequests::GetScene);
- EditorId editorId;
- SceneRequestBus::EventResult(editorId, sceneId, &SceneRequests::GetEditorId);
- const Styling::StyleHelper* stylingHelper = nullptr;
- StyleManagerRequestBus::EventResult(stylingHelper, editorId, &StyleManagerRequests::FindDataColorPalette, dataTypeId);
- return stylingHelper;
- }
- void DataSlotComponent::SetDataAndContainedTypeIds(AZ::Uuid typeId, const AZStd::vector<AZ::Uuid>& typeIds, DataValueType valueType)
- {
- if (m_dataTypeId != typeId)
- {
- m_dataTypeId = typeId;
- // Handles a weird case with string.
- // Since it's a primitive, but is a container of chars.
- if (valueType == DataValueType::Primitive)
- {
- m_containedTypeIds.clear();
- }
- else
- {
- m_containedTypeIds = typeIds;
- }
- m_valueType = valueType;
- DataSlotNotificationBus::Event(GetEntityId(), &DataSlotNotifications::OnDisplayTypeChanged, m_dataTypeId, m_containedTypeIds);
-
- UpdatePropertyDisplayState();
- }
- }
- AZ::Entity* DataSlotComponent::ConstructConnectionEntity(const Endpoint& sourceEndpoint, const Endpoint& targetEndpoint, bool createModelConnection)
- {
- const AZStd::string k_valueConnectionSubStyle = ".varFlow";
- const AZStd::string k_referenceConnectionSubStyle = ".referenceFlow";
- bool isReference = GetDataSlotType() == DataSlotType::Reference;
- // Create this Connection's entity.
- return DataConnectionComponent::CreateDataConnection(sourceEndpoint, targetEndpoint, createModelConnection, isReference ? k_referenceConnectionSubStyle : k_valueConnectionSubStyle);
- }
- }
|