2021-03-19 15:10:57 -04:00
// Copyright Epic Games, Inc. All Rights Reserved.
# include "MetasoundNodeDetailCustomization.h"
2021-04-06 01:41:29 -04:00
# include "Components/AudioComponent.h"
2021-03-19 15:10:57 -04:00
# include "Containers/Set.h"
# include "CoreMinimal.h"
# include "Delegates/Delegate.h"
# include "DetailCategoryBuilder.h"
# include "DetailLayoutBuilder.h"
# include "DetailWidgetRow.h"
# include "Framework/Notifications/NotificationManager.h"
# include "IDetailChildrenBuilder.h"
# include "IDetailGroup.h"
# include "Internationalization/Text.h"
# include "MetasoundAssetBase.h"
2021-04-07 02:59:10 -04:00
# include "MetasoundDataReference.h"
2021-12-13 18:15:01 -05:00
# include "MetasoundDataReferenceMacro.h"
2021-03-19 15:10:57 -04:00
# include "MetasoundEditorGraphBuilder.h"
# include "MetasoundEditorGraphNode.h"
2021-12-13 18:15:01 -05:00
# include "MetasoundEditorGraphInputNode.h"
# include "MetasoundEditorGraphMemberDefaults.h"
2021-11-07 23:43:01 -05:00
# include "MetasoundEditorGraphSchema.h"
2021-03-25 23:46:38 -04:00
# include "MetasoundEditorModule.h"
2021-03-19 15:10:57 -04:00
# include "MetasoundFrontend.h"
# include "MetasoundFrontendController.h"
2021-12-13 18:15:01 -05:00
# include "MetasoundFrontendDataTypeRegistry.h"
2021-03-19 15:10:57 -04:00
# include "MetasoundFrontendRegistries.h"
# include "MetasoundUObjectRegistry.h"
# include "PropertyCustomizationHelpers.h"
# include "PropertyEditorDelegates.h"
# include "PropertyHandle.h"
# include "PropertyRestriction.h"
2022-01-04 15:17:54 -05:00
# include "SAssetDropTarget.h"
2021-03-19 15:10:57 -04:00
# include "SlateCore/Public/Styling/SlateColor.h"
2021-11-07 23:43:01 -05:00
# include "SMetasoundActionMenu.h"
2021-04-07 02:59:10 -04:00
# include "SMetasoundGraphNode.h"
2021-11-07 23:43:01 -05:00
# include "SSearchableComboBox.h"
2021-03-19 15:10:57 -04:00
# include "Templates/Casts.h"
# include "Templates/SharedPointer.h"
# include "UObject/WeakObjectPtr.h"
# include "UObject/WeakObjectPtrTemplates.h"
2021-03-25 23:46:38 -04:00
# include "Widgets/Images/SImage.h"
# include "Widgets/Input/SButton.h"
2021-03-19 15:10:57 -04:00
# include "Widgets/Input/SCheckBox.h"
# include "Widgets/Input/SMultiLineEditableTextBox.h"
# include "Widgets/Input/STextComboBox.h"
# include "Widgets/Notifications/SNotificationList.h"
# include "Widgets/SToolTip.h"
# include "Widgets/SWidget.h"
# include "Widgets/Text/STextBlock.h"
2021-04-02 03:03:27 -04:00
# define LOCTEXT_NAMESPACE "MetaSoundEditor"
2021-03-19 15:10:57 -04:00
namespace Metasound
{
namespace Editor
{
2021-10-25 20:05:28 -04:00
namespace MemberCustomizationPrivate
2021-03-19 15:10:57 -04:00
{
2021-04-06 21:02:21 -04:00
/** Set of input types which are valid registered types, but should
* not show up as an input type option in the MetaSound editor . */
static const TSet < FName > HiddenInputTypeNames =
{
" Audio:Mono " ,
2021-04-13 12:55:34 -04:00
" Audio:Stereo "
2021-04-06 21:02:21 -04:00
} ;
2022-01-04 15:17:54 -05:00
void GetDataTypeFromElementPropertyHandle ( TSharedPtr < IPropertyHandle > ElementPropertyHandle , Frontend : : FDataTypeRegistryInfo & OutDataTypeInfo )
{
using namespace Frontend ;
TArray < UObject * > OuterObjects ;
ElementPropertyHandle - > GetOuterObjects ( OuterObjects ) ;
if ( OuterObjects . Num ( ) = = 1 )
{
UObject * Outer = OuterObjects . Last ( ) ;
if ( const UMetasoundEditorGraphMemberDefaultLiteral * DefaultLiteral = Cast < UMetasoundEditorGraphMemberDefaultLiteral > ( Outer ) )
{
if ( const UMetasoundEditorGraphMember * Member = Cast < UMetasoundEditorGraphMember > ( DefaultLiteral - > GetOuter ( ) ) )
{
ensure ( IDataTypeRegistry : : Get ( ) . GetDataTypeInfo ( Member - > GetDataType ( ) , OutDataTypeInfo ) ) ;
}
}
}
}
// If DataType is an array type, creates & returns the array's
// element type. Otherwise, returns this type's DataTypeName.
FName GetPrimitiveTypeName ( const Frontend : : FDataTypeRegistryInfo & InDataTypeInfo )
{
return InDataTypeInfo . IsArrayType ( )
? CreateElementTypeNameFromArrayTypeName ( InDataTypeInfo . DataTypeName )
: InDataTypeInfo . DataTypeName ;
}
2021-10-25 20:05:28 -04:00
} // namespace MemberCustomizationPrivate
2021-10-12 21:21:22 -04:00
FMetasoundFloatLiteralCustomization : : ~ FMetasoundFloatLiteralCustomization ( )
{
if ( FloatLiteral . IsValid ( ) )
{
2021-12-13 18:15:01 -05:00
FloatLiteral - > OnClampChanged . Remove ( OnClampChangedDelegateHandle ) ;
FloatLiteral - > OnRangeChanged . Remove ( OnRangeChangedDelegateHandle ) ;
2021-10-12 21:21:22 -04:00
}
}
2022-01-04 15:17:54 -05:00
void FMetasoundFloatLiteralCustomization : : CustomizeLiteral ( UMetasoundEditorGraphMemberDefaultLiteral & InLiteral , IDetailLayoutBuilder & InDetailLayout )
2021-10-12 21:21:22 -04:00
{
2022-01-04 15:17:54 -05:00
check ( DefaultCategoryBuilder ) ;
2021-10-12 21:21:22 -04:00
2021-12-13 18:15:01 -05:00
UMetasoundEditorGraphMemberDefaultFloat * DefaultFloat = Cast < UMetasoundEditorGraphMemberDefaultFloat > ( & InLiteral ) ;
if ( ! ensure ( DefaultFloat ) )
2021-10-12 21:21:22 -04:00
{
return ;
}
2021-12-13 18:15:01 -05:00
FloatLiteral = DefaultFloat ;
2021-10-12 21:21:22 -04:00
2022-01-04 15:17:54 -05:00
TSharedPtr < IPropertyHandle > DefaultValueHandle ;
IDetailPropertyRow * Row = DefaultCategoryBuilder - > AddExternalObjectProperty ( TArray < UObject * > ( { DefaultFloat } ) , UMetasoundEditorGraphMemberDefaultFloat : : GetDefaultPropertyName ( ) ) ;
if ( ensure ( Row ) )
{
DefaultValueHandle = Row - > GetPropertyHandle ( ) ;
}
2022-01-14 14:01:09 -05:00
// Apply the clamp range to the default value if
// 1. not using a widget and ClampDefault is true or
// 2. using a widget but not using a volume widget where VolumeWidgetUseLinearOutput is true
const bool bVolumeWidgetWithLinearOutput = DefaultFloat - > WidgetValueType = = EMetasoundMemberDefaultWidgetValueType : : Volume & & DefaultFloat - > VolumeWidgetUseLinearOutput ;
const bool bUsingWidget = DefaultFloat - > WidgetType ! = EMetasoundMemberDefaultWidget : : None ;
const bool bShouldClampDefaultValue = ( ! bUsingWidget & & DefaultFloat - > ClampDefault ) | | ( bUsingWidget & & ! bVolumeWidgetWithLinearOutput ) ;
2022-01-04 15:17:54 -05:00
Row = DefaultCategoryBuilder - > AddExternalObjectProperty ( TArray < UObject * > ( { DefaultFloat } ) , GET_MEMBER_NAME_CHECKED ( UMetasoundEditorGraphMemberDefaultFloat , ClampDefault ) ) ;
if ( ensure ( Row ) )
2021-10-12 21:21:22 -04:00
{
2022-01-14 14:01:09 -05:00
if ( bVolumeWidgetWithLinearOutput )
{
DefaultFloat - > SetRange ( FVector2D ( 0.0f , 1.0f ) ) ;
}
if ( bShouldClampDefaultValue )
2021-10-12 21:21:22 -04:00
{
2021-12-13 18:15:01 -05:00
FVector2D Range = DefaultFloat - > GetRange ( ) ;
2022-01-04 15:17:54 -05:00
DefaultValueHandle - > SetInstanceMetaData ( " ClampMin " , FString : : Printf ( TEXT ( " %f " ) , Range . X ) ) ;
DefaultValueHandle - > SetInstanceMetaData ( " ClampMax " , FString : : Printf ( TEXT ( " %f " ) , Range . Y ) ) ;
2021-10-12 21:21:22 -04:00
}
else // Stop clamping
{
2022-01-04 15:17:54 -05:00
DefaultValueHandle - > SetInstanceMetaData ( " ClampMin " , " " ) ;
DefaultValueHandle - > SetInstanceMetaData ( " ClampMax " , " " ) ;
2021-10-12 21:21:22 -04:00
}
2021-12-13 18:15:01 -05:00
DefaultFloat - > OnClampChanged . Remove ( OnClampChangedDelegateHandle ) ;
OnClampChangedDelegateHandle = DefaultFloat - > OnClampChanged . AddLambda ( [ this ] ( bool ClampInput )
2021-10-12 21:21:22 -04:00
{
if ( FloatLiteral . IsValid ( ) )
{
2021-12-13 18:15:01 -05:00
FloatLiteral - > OnClampChanged . Remove ( OnClampChangedDelegateHandle ) ;
2021-11-22 15:55:50 -05:00
if ( FMetasoundAssetBase * MetasoundAsset = Metasound : : IMetasoundUObjectRegistry : : Get ( ) . GetObjectAsAssetBase ( FloatLiteral - > GetOutermostObject ( ) ) )
2021-10-12 21:21:22 -04:00
{
2021-11-22 15:55:50 -05:00
MetasoundAsset - > SetSynchronizationRequired ( ) ;
2021-10-12 21:21:22 -04:00
}
}
} ) ;
2022-01-14 14:01:09 -05:00
if ( bShouldClampDefaultValue )
{
DefaultCategoryBuilder - > AddExternalObjectProperty ( TArray < UObject * > ( { DefaultFloat } ) , GET_MEMBER_NAME_CHECKED ( UMetasoundEditorGraphMemberDefaultFloat , Range ) ) ;
}
}
bool bIsGraphEditable = false ;
if ( const UMetasoundEditorGraphMember * ParentMember = InLiteral . GetParentMember ( ) )
{
if ( const UMetasoundEditorGraph * OwningGraph = ParentMember - > GetOwningGraph ( ) )
{
bIsGraphEditable = OwningGraph - > IsEditable ( ) ;
}
2021-10-12 21:21:22 -04:00
}
2022-01-04 15:17:54 -05:00
// add input widget properties
2022-01-14 14:01:09 -05:00
if ( bIsGraphEditable )
{
IDetailCategoryBuilder & WidgetCategoryBuilder = InDetailLayout . EditCategory ( " EditorOptions " ) ;
WidgetCategoryBuilder . AddExternalObjectProperty ( TArray < UObject * > ( { DefaultFloat } ) , GET_MEMBER_NAME_CHECKED ( UMetasoundEditorGraphMemberDefaultFloat , WidgetType ) ) ;
WidgetCategoryBuilder . AddExternalObjectProperty ( TArray < UObject * > ( { DefaultFloat } ) , GET_MEMBER_NAME_CHECKED ( UMetasoundEditorGraphMemberDefaultFloat , WidgetOrientation ) ) ;
WidgetCategoryBuilder . AddExternalObjectProperty ( TArray < UObject * > ( { DefaultFloat } ) , GET_MEMBER_NAME_CHECKED ( UMetasoundEditorGraphMemberDefaultFloat , WidgetValueType ) ) ;
if ( DefaultFloat - > WidgetValueType = = EMetasoundMemberDefaultWidgetValueType : : Volume )
{
WidgetCategoryBuilder . AddExternalObjectProperty ( TArray < UObject * > ( { DefaultFloat } ) , GET_MEMBER_NAME_CHECKED ( UMetasoundEditorGraphMemberDefaultFloat , VolumeWidgetUseLinearOutput ) ) ;
}
}
2021-03-23 17:55:31 -04:00
}
2022-01-04 15:17:54 -05:00
void FMetasoundObjectArrayLiteralCustomization : : CustomizeLiteral ( UMetasoundEditorGraphMemberDefaultLiteral & InLiteral , IDetailLayoutBuilder & InDetailLayout )
2021-03-23 17:55:31 -04:00
{
2022-01-04 15:17:54 -05:00
check ( DefaultCategoryBuilder ) ;
2021-03-23 17:55:31 -04:00
2022-01-04 15:17:54 -05:00
TSharedPtr < IPropertyHandle > DefaultValueHandle ;
IDetailPropertyRow * Row = DefaultCategoryBuilder - > AddExternalObjectProperty ( TArray < UObject * > ( { & InLiteral } ) , GET_MEMBER_NAME_CHECKED ( UMetasoundEditorGraphMemberDefaultObjectArray , Default ) ) ;
if ( ensure ( Row ) )
2021-03-23 17:55:31 -04:00
{
2022-01-04 15:17:54 -05:00
DefaultValueHandle = Row - > GetPropertyHandle ( ) ;
2021-03-23 17:55:31 -04:00
}
2022-01-04 15:17:54 -05:00
constexpr bool bShowChildren = true ;
Row - > ShowPropertyButtons ( false )
. CustomWidget ( bShowChildren )
. NameContent ( )
[
DefaultValueHandle - > CreatePropertyNameWidget ( )
]
. ValueContent ( )
[
SNew ( SAssetDropTarget )
. bSupportsMultiDrop ( true )
. OnAreAssetsAcceptableForDropWithReason_Lambda ( [ this , DefaultValueHandle ] ( TArrayView < FAssetData > InAssets , FText & OutReason )
{
Frontend : : FDataTypeRegistryInfo DataTypeInfo ;
MemberCustomizationPrivate : : GetDataTypeFromElementPropertyHandle ( DefaultValueHandle , DataTypeInfo ) ;
const IMetasoundEditorModule & EditorModule = FModuleManager : : GetModuleChecked < IMetasoundEditorModule > ( " MetaSoundEditor " ) ;
bool bCanDrop = true ;
for ( const FAssetData & AssetData : InAssets )
{
if ( DataTypeInfo . ProxyGeneratorClass )
{
if ( UClass * Class = AssetData . GetClass ( ) )
{
if ( EditorModule . IsExplicitProxyClass ( * DataTypeInfo . ProxyGeneratorClass ) )
{
bCanDrop & = Class = = DataTypeInfo . ProxyGeneratorClass ;
}
else
{
bCanDrop & = Class - > IsChildOf ( DataTypeInfo . ProxyGeneratorClass ) ;
}
}
}
}
return true ;
} )
. OnAssetsDropped_Lambda ( [ this , DefaultValueHandle ] ( const FDragDropEvent & DragDropEvent , TArrayView < FAssetData > InAssets )
{
if ( DefaultValueHandle . IsValid ( ) )
{
TSharedPtr < IPropertyHandleArray > ArrayHandle = DefaultValueHandle - > AsArray ( ) ;
if ( ensure ( ArrayHandle . IsValid ( ) ) )
{
for ( const FAssetData & AssetData : InAssets )
{
uint32 AddIndex = INDEX_NONE ;
ArrayHandle - > GetNumElements ( AddIndex ) ;
ArrayHandle - > AddItem ( ) ;
TSharedPtr < IPropertyHandle > ElementHandle = ArrayHandle - > GetElement ( static_cast < int32 > ( AddIndex ) ) ;
TSharedPtr < IPropertyHandle > ObjectHandle = ElementHandle - > GetChildHandle ( GET_MEMBER_NAME_CHECKED ( FMetasoundEditorGraphMemberDefaultObjectRef , Object ) ) ;
ObjectHandle - > SetValue ( AssetData . GetAsset ( ) ) ;
}
}
}
} )
[
DefaultValueHandle - > CreatePropertyValueWidget ( )
]
] ;
2021-03-23 17:55:31 -04:00
}
2021-12-13 18:15:01 -05:00
FText FMetasoundMemberDefaultBoolDetailCustomization : : GetPropertyNameOverride ( ) const
2021-03-23 17:55:31 -04:00
{
2022-01-04 15:17:54 -05:00
using namespace MemberCustomizationPrivate ;
if ( GetPrimitiveTypeName ( DataTypeInfo ) = = Metasound : : GetMetasoundDataTypeName < Metasound : : FTrigger > ( ) )
2021-03-23 17:55:31 -04:00
{
return LOCTEXT ( " TriggerInput_SimulateTitle " , " Simulate " ) ;
}
return FText : : GetEmpty ( ) ;
}
2021-12-13 18:15:01 -05:00
TSharedRef < SWidget > FMetasoundMemberDefaultBoolDetailCustomization : : CreateStructureWidget ( TSharedPtr < IPropertyHandle > & StructPropertyHandle ) const
2021-03-23 17:55:31 -04:00
{
using namespace Frontend ;
2022-01-04 15:17:54 -05:00
using namespace MemberCustomizationPrivate ;
2021-03-23 17:55:31 -04:00
2021-12-13 18:15:01 -05:00
TSharedPtr < IPropertyHandle > ValueProperty = StructPropertyHandle - > GetChildHandle ( GET_MEMBER_NAME_CHECKED ( FMetasoundEditorGraphMemberDefaultBoolRef , Value ) ) ;
if ( ValueProperty . IsValid ( ) )
2021-03-23 17:55:31 -04:00
{
2021-12-13 18:15:01 -05:00
// Not a trigger, so just display as underlying literal type (bool)
2022-01-04 15:17:54 -05:00
if ( GetPrimitiveTypeName ( DataTypeInfo ) ! = Metasound : : GetMetasoundDataTypeName < Metasound : : FTrigger > ( ) )
2021-03-23 17:55:31 -04:00
{
2021-12-13 18:15:01 -05:00
return ValueProperty - > CreatePropertyValueWidget ( ) ;
}
2021-03-23 17:55:31 -04:00
2021-12-13 18:15:01 -05:00
TAttribute < bool > EnablementAttribute = false ;
TAttribute < EVisibility > VisibilityAttribute = EVisibility : : Visible ;
TArray < UObject * > OuterObjects ;
ValueProperty - > GetOuterObjects ( OuterObjects ) ;
if ( ! OuterObjects . IsEmpty ( ) )
{
if ( UMetasoundEditorGraphMemberDefaultLiteral * Literal = Cast < UMetasoundEditorGraphMemberDefaultLiteral > ( OuterObjects . Last ( ) ) )
2021-04-07 02:59:10 -04:00
{
2021-12-13 18:15:01 -05:00
if ( UMetasoundEditorGraphInput * Input = Cast < UMetasoundEditorGraphInput > ( Literal - > GetParentMember ( ) ) )
2021-04-07 02:59:10 -04:00
{
2021-12-13 18:15:01 -05:00
// Don't display trigger simulation widget if its a trigger
// provided by an interface that does not support transmission.
const FInterfaceRegistryKey Key = GetInterfaceRegistryKey ( Input - > GetInterfaceVersion ( ) ) ;
const IInterfaceRegistryEntry * Entry = IInterfaceRegistry : : Get ( ) . FindInterfaceRegistryEntry ( Key ) ;
if ( ! Entry | | Entry - > GetRouterName ( ) = = Audio : : IParameterTransmitter : : RouterName )
{
EnablementAttribute = true ;
return SMetaSoundGraphNode : : CreateTriggerSimulationWidget ( * Literal , MoveTemp ( VisibilityAttribute ) , MoveTemp ( EnablementAttribute ) ) ;
}
const FText DisabledToolTip = LOCTEXT ( " NonTransmittibleInputTriggerSimulationDisabledTooltip " , " Trigger simulation disabled: Parent interface does not support being updated by game thread parameters. " ) ;
return SMetaSoundGraphNode : : CreateTriggerSimulationWidget ( * Literal , MoveTemp ( VisibilityAttribute ) , MoveTemp ( EnablementAttribute ) , & DisabledToolTip ) ;
2021-04-07 02:59:10 -04:00
}
}
2021-03-23 17:55:31 -04:00
}
}
return SNullWidget : : NullWidget ;
2021-03-19 15:10:57 -04:00
}
2021-12-13 18:15:01 -05:00
TSharedRef < SWidget > FMetasoundMemberDefaultIntDetailCustomization : : CreateStructureWidget ( TSharedPtr < IPropertyHandle > & StructPropertyHandle ) const
2021-03-19 15:10:57 -04:00
{
using namespace Frontend ;
2022-01-04 15:17:54 -05:00
using namespace MemberCustomizationPrivate ;
2021-03-19 15:10:57 -04:00
if ( FMetasoundFrontendRegistryContainer * Registry = FMetasoundFrontendRegistryContainer : : Get ( ) )
{
2021-12-13 18:15:01 -05:00
TSharedPtr < IPropertyHandle > ValueProperty = StructPropertyHandle - > GetChildHandle ( GET_MEMBER_NAME_CHECKED ( FMetasoundEditorGraphMemberDefaultIntRef , Value ) ) ;
2021-03-19 15:10:57 -04:00
if ( ValueProperty . IsValid ( ) )
{
2022-01-04 15:17:54 -05:00
TSharedPtr < const IEnumDataTypeInterface > EnumInterface = IDataTypeRegistry : : Get ( ) . GetEnumInterfaceForDataType ( GetPrimitiveTypeName ( DataTypeInfo ) ) ;
2021-03-19 15:10:57 -04:00
// Not an enum, so just display as underlying type (int32)
if ( ! EnumInterface . IsValid ( ) )
{
return ValueProperty - > CreatePropertyValueWidget ( ) ;
}
auto GetAll = [ Interface = EnumInterface ] ( TArray < TSharedPtr < FString > > & OutStrings , TArray < TSharedPtr < SToolTip > > & OutTooltips , TArray < bool > & )
{
for ( const IEnumDataTypeInterface : : FGenericInt32Entry & i : Interface - > GetAllEntries ( ) )
{
OutTooltips . Emplace ( SNew ( SToolTip ) . Text ( i . Tooltip ) ) ;
OutStrings . Emplace ( MakeShared < FString > ( i . DisplayName . ToString ( ) ) ) ;
}
} ;
auto GetValue = [ Interface = EnumInterface , Prop = ValueProperty ] ( )
{
int32 IntValue ;
if ( Prop - > GetValue ( IntValue ) ! = FPropertyAccess : : Success )
{
IntValue = Interface - > GetDefaultValue ( ) ;
2021-03-31 00:23:34 -04:00
UE_LOG ( LogMetasoundEditor , Warning , TEXT ( " Failed to read int Property '%s', defaulting. " ) , * GetNameSafe ( Prop - > GetProperty ( ) ) ) ;
2021-03-19 15:10:57 -04:00
}
if ( TOptional < IEnumDataTypeInterface : : FGenericInt32Entry > Result = Interface - > FindByValue ( IntValue ) )
{
return Result - > DisplayName . ToString ( ) ;
}
2021-03-31 00:23:34 -04:00
UE_LOG ( LogMetasoundEditor , Warning , TEXT ( " Failed to resolve int value '%d' to a valid enum value for enum '%s' " ) ,
2021-03-19 15:10:57 -04:00
IntValue , * Interface - > GetNamespace ( ) . ToString ( ) ) ;
// Return default (should always succeed as we can't have empty Enums and we must have a default).
return Interface - > FindByValue ( Interface - > GetDefaultValue ( ) ) - > DisplayName . ToString ( ) ;
} ;
auto SelectedValue = [ Interface = EnumInterface , Prop = ValueProperty ] ( const FString & InSelected )
{
TOptional < IEnumDataTypeInterface : : FGenericInt32Entry > Found =
Interface - > FindEntryBy ( [ TextSelected = FText : : FromString ( InSelected ) ] ( const IEnumDataTypeInterface : : FGenericInt32Entry & i )
{
return i . DisplayName . EqualTo ( TextSelected ) ;
} ) ;
if ( Found )
{
// Only save the changes if its different and we can read the old value to check that.
int32 CurrentValue ;
bool bReadCurrentValue = Prop - > GetValue ( CurrentValue ) = = FPropertyAccess : : Success ;
if ( ( bReadCurrentValue & & CurrentValue ! = Found - > Value ) | | ! bReadCurrentValue )
{
ensure ( Prop - > SetValue ( Found - > Value ) = = FPropertyAccess : : Success ) ;
}
}
else
{
2021-03-31 00:23:34 -04:00
UE_LOG ( LogMetasoundEditor , Warning , TEXT ( " Failed to Set Valid Value for Property '%s' with Value of '%s', writing default. " ) ,
2021-03-19 15:10:57 -04:00
* GetNameSafe ( Prop - > GetProperty ( ) ) , * InSelected ) ;
ensure ( Prop - > SetValue ( Interface - > GetDefaultValue ( ) ) = = FPropertyAccess : : Success ) ;
}
} ;
return PropertyCustomizationHelpers : : MakePropertyComboBox (
nullptr ,
FOnGetPropertyComboBoxStrings : : CreateLambda ( GetAll ) ,
FOnGetPropertyComboBoxValue : : CreateLambda ( GetValue ) ,
FOnPropertyComboBoxValueSelected : : CreateLambda ( SelectedValue )
) ;
}
}
return SNullWidget : : NullWidget ;
}
2021-12-13 18:15:01 -05:00
TSharedRef < SWidget > FMetasoundMemberDefaultObjectDetailCustomization : : CreateStructureWidget ( TSharedPtr < IPropertyHandle > & StructPropertyHandle ) const
2021-03-19 15:10:57 -04:00
{
2021-12-13 18:15:01 -05:00
TSharedPtr < IPropertyHandle > PropertyHandle = StructPropertyHandle - > GetChildHandle ( GET_MEMBER_NAME_CHECKED ( FMetasoundEditorGraphMemberDefaultObjectRef , Object ) ) ;
2021-03-19 15:10:57 -04:00
2021-11-07 23:43:01 -05:00
const IMetasoundEditorModule & EditorModule = FModuleManager : : GetModuleChecked < IMetasoundEditorModule > ( " MetaSoundEditor " ) ;
2022-01-04 15:17:54 -05:00
auto FilterAsset = [ InEditorModule = & EditorModule , InProxyGenClass = DataTypeInfo . ProxyGeneratorClass ] ( const FAssetData & InAsset )
2021-03-19 15:10:57 -04:00
{
2022-01-04 15:17:54 -05:00
if ( InProxyGenClass )
2021-03-19 15:10:57 -04:00
{
2021-11-07 23:43:01 -05:00
if ( UClass * Class = InAsset . GetClass ( ) )
2021-03-19 15:10:57 -04:00
{
2022-01-04 15:17:54 -05:00
if ( InEditorModule - > IsExplicitProxyClass ( * InProxyGenClass ) )
2021-11-07 23:43:01 -05:00
{
2022-01-04 15:17:54 -05:00
return Class ! = InProxyGenClass ;
2021-11-07 23:43:01 -05:00
}
2022-01-04 15:17:54 -05:00
return ! Class - > IsChildOf ( InProxyGenClass ) ;
2021-03-19 15:10:57 -04:00
}
}
2021-11-07 23:43:01 -05:00
return true ;
} ;
auto ValidateAsset = [ FilterAsset ] ( const FAssetData & InAsset )
{
2022-01-04 15:17:54 -05:00
// A null asset reference is a valid default
return InAsset . IsValid ( ) ? ! FilterAsset ( InAsset ) : true ;
2021-03-19 15:10:57 -04:00
} ;
auto GetAssetPath = [ PropertyHandle = PropertyHandle ] ( )
{
UObject * Object = nullptr ;
if ( PropertyHandle - > GetValue ( Object ) = = FPropertyAccess : : Success )
{
return Object - > GetPathName ( ) ;
}
return FString ( ) ;
} ;
return SNew ( SObjectPropertyEntryBox )
2021-04-05 19:26:15 -04:00
. AllowClear ( true )
2022-01-04 15:17:54 -05:00
. AllowedClass ( DataTypeInfo . ProxyGeneratorClass )
2021-03-19 15:10:57 -04:00
. DisplayBrowse ( true )
. DisplayThumbnail ( true )
2021-08-18 15:16:57 -04:00
. DisplayUseSelected ( true )
2022-01-04 15:17:54 -05:00
. NewAssetFactories ( PropertyCustomizationHelpers : : GetNewAssetFactoriesForClasses ( { DataTypeInfo . ProxyGeneratorClass } ) )
2021-08-18 15:16:57 -04:00
. ObjectPath_Lambda ( GetAssetPath )
. OnShouldFilterAsset_Lambda ( FilterAsset )
. OnShouldSetAsset_Lambda ( ValidateAsset )
. PropertyHandle ( PropertyHandle ) ;
2021-03-19 15:10:57 -04:00
}
2022-01-04 15:17:54 -05:00
TSharedRef < SWidget > FMetasoundDefaultMemberElementDetailCustomizationBase : : CreateNameWidget ( TSharedPtr < IPropertyHandle > StructPropertyHandle ) const
2021-03-23 17:55:31 -04:00
{
const FText PropertyName = GetPropertyNameOverride ( ) ;
if ( ! PropertyName . IsEmpty ( ) )
{
return SNew ( STextBlock )
. Font ( IDetailLayoutBuilder : : GetDetailFont ( ) )
. Text ( PropertyName ) ;
}
return SNew ( STextBlock )
2021-12-13 18:15:01 -05:00
. Text ( MemberCustomizationStyle : : DefaultPropertyText )
2021-03-23 17:55:31 -04:00
. Font ( IDetailLayoutBuilder : : GetDetailFont ( ) ) ;
}
2022-01-04 15:17:54 -05:00
TSharedRef < SWidget > FMetasoundDefaultMemberElementDetailCustomizationBase : : CreateValueWidget ( TSharedPtr < IPropertyHandleArray > ParentPropertyHandleArray , TSharedPtr < IPropertyHandle > StructPropertyHandle ) const
2021-03-19 15:10:57 -04:00
{
2021-03-23 17:55:31 -04:00
TSharedRef < SWidget > ValueWidget = CreateStructureWidget ( StructPropertyHandle ) ;
2022-01-04 15:17:54 -05:00
if ( ! ParentPropertyHandleArray . IsValid ( ) )
2021-03-19 15:10:57 -04:00
{
2021-03-23 17:55:31 -04:00
return ValueWidget ;
2021-03-19 15:10:57 -04:00
}
TSharedPtr < IPropertyHandle > StructPropertyPtr = StructPropertyHandle ;
2022-01-04 15:17:54 -05:00
FExecuteAction InsertAction = FExecuteAction : : CreateLambda ( [ ParentPropertyHandleArray , StructPropertyPtr ]
2021-03-19 15:10:57 -04:00
{
const int32 ArrayIndex = StructPropertyPtr . IsValid ( ) ? StructPropertyPtr - > GetIndexInArray ( ) : INDEX_NONE ;
2022-01-04 15:17:54 -05:00
if ( ParentPropertyHandleArray . IsValid ( ) & & ArrayIndex > = 0 )
2021-03-19 15:10:57 -04:00
{
2022-01-04 15:17:54 -05:00
ParentPropertyHandleArray - > Insert ( ArrayIndex ) ;
2021-03-19 15:10:57 -04:00
}
} ) ;
2022-01-04 15:17:54 -05:00
FExecuteAction DeleteAction = FExecuteAction : : CreateLambda ( [ ParentPropertyHandleArray , StructPropertyPtr ]
2021-03-19 15:10:57 -04:00
{
const int32 ArrayIndex = StructPropertyPtr . IsValid ( ) ? StructPropertyPtr - > GetIndexInArray ( ) : INDEX_NONE ;
2022-01-04 15:17:54 -05:00
if ( ParentPropertyHandleArray . IsValid ( ) & & ArrayIndex > = 0 )
2021-03-19 15:10:57 -04:00
{
2022-01-04 15:17:54 -05:00
ParentPropertyHandleArray - > DeleteItem ( ArrayIndex ) ;
2021-03-19 15:10:57 -04:00
}
} ) ;
2022-01-04 15:17:54 -05:00
FExecuteAction DuplicateAction = FExecuteAction : : CreateLambda ( [ ParentPropertyHandleArray , StructPropertyPtr ]
2021-03-19 15:10:57 -04:00
{
const int32 ArrayIndex = StructPropertyPtr . IsValid ( ) ? StructPropertyPtr - > GetIndexInArray ( ) : INDEX_NONE ;
2022-01-04 15:17:54 -05:00
if ( ParentPropertyHandleArray . IsValid ( ) & & ArrayIndex > = 0 )
2021-03-19 15:10:57 -04:00
{
2022-01-04 15:17:54 -05:00
ParentPropertyHandleArray - > DuplicateItem ( ArrayIndex ) ;
2021-03-19 15:10:57 -04:00
}
} ) ;
return SNew ( SHorizontalBox )
+ SHorizontalBox : : Slot ( )
2021-10-25 20:05:28 -04:00
. FillWidth ( 1.0f )
2021-03-19 15:10:57 -04:00
. Padding ( 1.0f , 0.0f , 0.0f , 0.0f )
. VAlign ( VAlign_Center )
[
2021-03-23 17:55:31 -04:00
ValueWidget
2021-03-19 15:10:57 -04:00
]
+ SHorizontalBox : : Slot ( )
2021-10-25 20:05:28 -04:00
. AutoWidth ( )
. Padding ( - 6.0f , 0.0f , 0.0f , 0.0f ) // Negative padding intentional on the left to bring the dropdown closer to the other buttons
2021-03-19 15:10:57 -04:00
. VAlign ( VAlign_Center )
[
PropertyCustomizationHelpers : : MakeInsertDeleteDuplicateButton ( InsertAction , DeleteAction , DuplicateAction )
] ;
}
2022-01-04 15:17:54 -05:00
void FMetasoundDefaultMemberElementDetailCustomizationBase : : CustomizeChildren ( TSharedRef < IPropertyHandle > StructPropertyHandle , IDetailChildrenBuilder & ChildBuilder , IPropertyTypeCustomizationUtils & StructCustomizationUtils )
2021-03-19 15:10:57 -04:00
{
2022-01-04 15:17:54 -05:00
TSharedPtr < IPropertyHandleArray > ParentPropertyHandleArray ;
TSharedPtr < IPropertyHandle > ElementPropertyHandle = StructPropertyHandle ;
if ( ElementPropertyHandle . IsValid ( ) )
2021-03-19 15:10:57 -04:00
{
2022-01-04 15:17:54 -05:00
TSharedPtr < IPropertyHandle > ParentProperty = ElementPropertyHandle - > GetParentHandle ( ) ;
while ( ParentProperty . IsValid ( ) & & ParentProperty - > GetProperty ( ) ! = nullptr )
2021-03-19 15:10:57 -04:00
{
2022-01-04 15:17:54 -05:00
ParentPropertyHandleArray = ParentProperty - > AsArray ( ) ;
if ( ParentPropertyHandleArray . IsValid ( ) )
2021-03-19 15:10:57 -04:00
{
2022-01-04 15:17:54 -05:00
ElementPropertyHandle = ParentProperty ;
break ;
2021-03-19 15:10:57 -04:00
}
}
}
2022-01-04 15:17:54 -05:00
MemberCustomizationPrivate : : GetDataTypeFromElementPropertyHandle ( ElementPropertyHandle , DataTypeInfo ) ;
2021-03-19 15:10:57 -04:00
2022-01-04 15:17:54 -05:00
TSharedRef < SWidget > ValueWidget = CreateValueWidget ( ParentPropertyHandleArray , StructPropertyHandle ) ;
2021-12-13 18:15:01 -05:00
FDetailWidgetRow & ValueRow = ChildBuilder . AddCustomRow ( MemberCustomizationStyle : : DefaultPropertyText ) ;
2022-01-04 15:17:54 -05:00
if ( ParentPropertyHandleArray . IsValid ( ) )
2021-03-19 15:10:57 -04:00
{
ValueRow . NameContent ( )
[
StructPropertyHandle - > CreatePropertyNameWidget ( )
] ;
}
else
{
ValueRow . NameContent ( )
[
2021-03-23 17:55:31 -04:00
CreateNameWidget ( StructPropertyHandle )
2021-03-19 15:10:57 -04:00
] ;
}
TArray < UObject * > OuterObjects ;
StructPropertyHandle - > GetOuterObjects ( OuterObjects ) ;
TArray < TWeakObjectPtr < UMetasoundEditorGraphInput > > Inputs ;
for ( UObject * Object : OuterObjects )
{
if ( UMetasoundEditorGraphInput * Input = Cast < UMetasoundEditorGraphInput > ( Object ) )
{
Inputs . Add ( Input ) ;
}
}
2021-12-13 18:15:01 -05:00
FSimpleDelegate UpdateFrontendDefaultLiteral = FSimpleDelegate : : CreateLambda ( [ InInputs = Inputs ] ( )
2021-03-19 15:10:57 -04:00
{
for ( const TWeakObjectPtr < UMetasoundEditorGraphInput > & GraphInput : InInputs )
{
if ( GraphInput . IsValid ( ) )
{
2021-12-13 18:15:01 -05:00
constexpr bool bPostTransaction = true ;
GraphInput - > UpdateFrontendDefaultLiteral ( bPostTransaction ) ;
2021-03-19 15:10:57 -04:00
}
}
} ) ;
2021-12-13 18:15:01 -05:00
StructPropertyHandle - > SetOnChildPropertyValueChanged ( UpdateFrontendDefaultLiteral ) ;
2021-03-19 15:10:57 -04:00
ValueRow . ValueContent ( )
[
ValueWidget
] ;
}
2022-01-04 15:17:54 -05:00
void FMetasoundDefaultMemberElementDetailCustomizationBase : : CustomizeHeader ( TSharedRef < IPropertyHandle > StructPropertyHandle , FDetailWidgetRow & HeaderRow , IPropertyTypeCustomizationUtils & StructCustomizationUtils )
2021-03-19 15:10:57 -04:00
{
}
2021-11-07 23:43:01 -05:00
FName FMetasoundDataTypeSelector : : GetDataType ( ) const
{
if ( GraphMember . IsValid ( ) )
{
2021-12-13 18:15:01 -05:00
return GraphMember - > GetDataType ( ) ;
2021-11-07 23:43:01 -05:00
}
return FName ( ) ;
}
void FMetasoundDataTypeSelector : : OnDataTypeSelected ( FName InSelectedTypeName )
{
FName NewDataTypeName ;
2021-12-13 18:15:01 -05:00
FName ArrayDataTypeName = CreateArrayTypeNameFromElementTypeName ( InSelectedTypeName ) ;
2021-11-07 23:43:01 -05:00
// Update data type based on "Is Array" checkbox and support for arrays.
// If an array type is not supported, default to the base data type.
IMetasoundEditorModule & EditorModule = FModuleManager : : GetModuleChecked < IMetasoundEditorModule > ( " MetaSoundEditor " ) ;
if ( DataTypeArrayCheckbox - > GetCheckedState ( ) = = ECheckBoxState : : Checked )
{
if ( EditorModule . IsRegisteredDataType ( ArrayDataTypeName ) )
{
NewDataTypeName = ArrayDataTypeName ;
}
else
{
2021-12-13 18:15:01 -05:00
ensure ( EditorModule . IsRegisteredDataType ( InSelectedTypeName ) ) ;
2021-11-07 23:43:01 -05:00
NewDataTypeName = InSelectedTypeName ;
}
}
else
{
if ( EditorModule . IsRegisteredDataType ( InSelectedTypeName ) )
{
NewDataTypeName = InSelectedTypeName ;
}
else
{
2021-12-13 18:15:01 -05:00
ensure ( EditorModule . IsRegisteredDataType ( ArrayDataTypeName ) ) ;
2021-11-07 23:43:01 -05:00
NewDataTypeName = ArrayDataTypeName ;
}
}
2021-12-13 18:15:01 -05:00
if ( NewDataTypeName = = GraphMember - > GetDataType ( ) )
2021-11-07 23:43:01 -05:00
{
return ;
}
// Have to stop playback to avoid attempting to change live edit data on invalid input type.
check ( GEditor ) ;
GEditor - > ResetPreviewAudioComponent ( ) ;
if ( GraphMember . IsValid ( ) )
{
GraphMember - > SetDataType ( NewDataTypeName ) ;
2021-12-13 18:15:01 -05:00
if ( FMetasoundAssetBase * MetasoundAsset = Metasound : : IMetasoundUObjectRegistry : : Get ( ) . GetObjectAsAssetBase ( GraphMember - > GetOutermostObject ( ) ) )
{
MetasoundAsset - > SetUpdateDetailsOnSynchronization ( ) ;
}
}
2021-11-07 23:43:01 -05:00
}
2021-10-25 20:05:28 -04:00
void FMetasoundDataTypeSelector : : AddDataTypeSelector ( IDetailLayoutBuilder & InDetailLayout , const FText & InRowName , TWeakObjectPtr < UMetasoundEditorGraphMember > InGraphMember , bool bIsEnabled )
2021-03-19 15:10:57 -04:00
{
2021-12-13 18:15:01 -05:00
using namespace Frontend ;
2021-11-07 23:43:01 -05:00
if ( ! InGraphMember . IsValid ( ) )
{
return ;
}
GraphMember = InGraphMember ;
2021-03-19 15:10:57 -04:00
2021-12-13 18:15:01 -05:00
FDataTypeRegistryInfo DataTypeInfo ;
if ( ! ensure ( IDataTypeRegistry : : Get ( ) . GetDataTypeInfo ( InGraphMember - > GetDataType ( ) , DataTypeInfo ) ) )
2021-03-19 15:10:57 -04:00
{
2021-12-13 18:15:01 -05:00
return ;
}
const bool bIsArrayType = DataTypeInfo . IsArrayType ( ) ;
if ( bIsArrayType )
{
ArrayTypeName = GraphMember - > GetDataType ( ) ;
BaseTypeName = CreateElementTypeNameFromArrayTypeName ( InGraphMember - > GetDataType ( ) ) ;
}
else
{
ArrayTypeName = CreateArrayTypeNameFromElementTypeName ( InGraphMember - > GetDataType ( ) ) ;
BaseTypeName = GraphMember - > GetDataType ( ) ;
2021-03-19 15:10:57 -04:00
}
2021-04-02 03:03:27 -04:00
IMetasoundEditorModule & EditorModule = FModuleManager : : GetModuleChecked < IMetasoundEditorModule > ( " MetaSoundEditor " ) ;
2021-04-06 21:02:21 -04:00
// Not all types have an equivalent array type. Base types without array
2021-12-13 18:15:01 -05:00
// types should have the "Is Array" checkbox disabled.
const bool bIsArrayTypeRegistered = bIsArrayType | | IDataTypeRegistry : : Get ( ) . IsRegistered ( ArrayTypeName ) ;
const bool bIsArrayTypeRegisteredHidden = MemberCustomizationPrivate : : HiddenInputTypeNames . Contains ( ArrayTypeName ) ;
2021-04-06 21:02:21 -04:00
2021-12-02 14:23:45 -05:00
TArray < FName > BaseDataTypes ;
2021-12-13 18:15:01 -05:00
IDataTypeRegistry : : Get ( ) . IterateDataTypeInfo ( [ & BaseDataTypes ] ( const FDataTypeRegistryInfo & RegistryInfo )
2021-03-19 15:10:57 -04:00
{
2021-12-02 14:23:45 -05:00
// Hide the type from the combo selector if any of the following is true;
2021-12-13 18:15:01 -05:00
const bool bIsArrayType = RegistryInfo . IsArrayType ( ) ;
const bool bIsVariable = RegistryInfo . bIsVariable ;
const bool bIsHiddenType = MemberCustomizationPrivate : : HiddenInputTypeNames . Contains ( RegistryInfo . DataTypeName ) ;
2021-12-02 14:23:45 -05:00
const bool bHideBaseType = bIsArrayType | | bIsVariable | | bIsHiddenType ;
if ( ! bHideBaseType )
2021-03-19 15:10:57 -04:00
{
2021-12-13 18:15:01 -05:00
BaseDataTypes . Add ( RegistryInfo . DataTypeName ) ;
2021-04-07 22:22:52 -04:00
}
2021-03-19 15:10:57 -04:00
} ) ;
2021-12-02 14:23:45 -05:00
BaseDataTypes . Sort ( [ ] ( const FName & DataTypeNameL , const FName & DataTypeNameR )
2021-03-19 15:10:57 -04:00
{
2021-11-07 23:43:01 -05:00
return DataTypeNameL . LexicalLess ( DataTypeNameR ) ;
2021-03-19 15:10:57 -04:00
} ) ;
2021-12-02 14:23:45 -05:00
Algo : : Transform ( BaseDataTypes , ComboOptions , [ ] ( const FName & Name ) { return MakeShared < FString > ( Name . ToString ( ) ) ; } ) ;
2021-11-07 23:43:01 -05:00
2021-12-02 14:23:45 -05:00
InDetailLayout . EditCategory ( " General " ) . AddCustomRow ( InRowName )
2021-07-27 15:36:03 -04:00
. IsEnabled ( bIsEnabled )
2021-03-19 15:10:57 -04:00
. NameContent ( )
[
SNew ( STextBlock )
. Text ( InRowName )
. Font ( IDetailLayoutBuilder : : GetDetailFont ( ) )
]
. ValueContent ( )
[
SNew ( SHorizontalBox )
+ SHorizontalBox : : Slot ( )
2021-11-07 23:43:01 -05:00
. AutoWidth ( )
. HAlign ( HAlign_Left )
2021-03-19 15:10:57 -04:00
. VAlign ( VAlign_Center )
2021-11-07 23:43:01 -05:00
. Padding ( 1.0f , 0.0f , 0.0f , 0.0f )
2021-03-19 15:10:57 -04:00
[
2021-11-07 23:43:01 -05:00
SAssignNew ( DataTypeComboBox , SSearchableComboBox )
. OptionsSource ( & ComboOptions )
. OnGenerateWidget_Lambda ( [ ] ( TSharedPtr < FString > InItem )
2021-03-19 15:10:57 -04:00
{
2021-11-07 23:43:01 -05:00
return SNew ( STextBlock )
. Text ( FText : : FromString ( * InItem ) ) ;
2021-03-19 15:10:57 -04:00
} )
2021-11-07 23:43:01 -05:00
. OnSelectionChanged_Lambda ( [ this ] ( TSharedPtr < FString > InNewName , ESelectInfo : : Type InSelectInfo )
{
if ( InSelectInfo ! = ESelectInfo : : OnNavigation )
{
OnDataTypeSelected ( FName ( * InNewName ) ) ;
}
} )
. Content ( )
[
SNew ( STextBlock )
. Text_Lambda ( [ this ] ( )
{
2021-12-13 18:15:01 -05:00
return FText : : FromName ( BaseTypeName ) ;
2021-11-07 23:43:01 -05:00
} )
]
2021-03-19 15:10:57 -04:00
]
+ SHorizontalBox : : Slot ( )
2021-11-07 23:43:01 -05:00
. AutoWidth ( )
. HAlign ( HAlign_Right )
2021-03-19 15:10:57 -04:00
. VAlign ( VAlign_Center )
2021-11-07 23:43:01 -05:00
. Padding ( 2.0f , 0.0f , 0.0f , 0.0f )
2021-03-19 15:10:57 -04:00
[
SAssignNew ( DataTypeArrayCheckbox , SCheckBox )
2021-04-08 14:10:56 -04:00
. IsEnabled ( bIsArrayTypeRegistered & & ! bIsArrayTypeRegisteredHidden )
2021-10-25 20:05:28 -04:00
. IsChecked_Lambda ( [ this , InGraphMember ] ( )
2021-03-19 15:10:57 -04:00
{
2021-10-25 20:05:28 -04:00
return OnGetDataTypeArrayCheckState ( InGraphMember ) ;
2021-03-19 15:10:57 -04:00
} )
2021-10-25 20:05:28 -04:00
. OnCheckStateChanged_Lambda ( [ this , InGraphMember ] ( ECheckBoxState InNewState )
2021-03-19 15:10:57 -04:00
{
2021-10-25 20:05:28 -04:00
OnDataTypeArrayChanged ( InGraphMember , InNewState ) ;
2021-03-19 15:10:57 -04:00
} )
[
SNew ( STextBlock )
. Text ( LOCTEXT ( " Node_IsArray " , " Is Array " ) )
. Font ( IDetailLayoutBuilder : : GetDetailFont ( ) )
]
]
] ;
2021-11-07 23:43:01 -05:00
2021-12-13 18:15:01 -05:00
auto NameMatchesPredicate = [ TypeString = BaseTypeName . ToString ( ) ] ( const TSharedPtr < FString > & Item ) { return * Item = = TypeString ; } ;
2021-11-07 23:43:01 -05:00
const TSharedPtr < FString > * SelectedItem = ComboOptions . FindByPredicate ( NameMatchesPredicate ) ;
if ( ensure ( SelectedItem ) )
{
DataTypeComboBox - > SetSelectedItem ( * SelectedItem ) ;
}
2021-03-19 15:10:57 -04:00
}
2021-10-25 20:05:28 -04:00
ECheckBoxState FMetasoundDataTypeSelector : : OnGetDataTypeArrayCheckState ( TWeakObjectPtr < UMetasoundEditorGraphMember > InGraphMember ) const
2021-03-19 15:10:57 -04:00
{
2021-12-13 18:15:01 -05:00
using namespace Frontend ;
2021-10-25 20:05:28 -04:00
if ( InGraphMember . IsValid ( ) )
2021-03-19 15:10:57 -04:00
{
2021-12-13 18:15:01 -05:00
FDataTypeRegistryInfo DataTypeInfo ;
if ( ensure ( IDataTypeRegistry : : Get ( ) . GetDataTypeInfo ( InGraphMember - > GetDataType ( ) , DataTypeInfo ) ) )
{
return DataTypeInfo . IsArrayType ( ) ? ECheckBoxState : : Checked : ECheckBoxState : : Unchecked ;
}
2021-03-19 15:10:57 -04:00
}
return ECheckBoxState : : Undetermined ;
}
2021-10-25 20:05:28 -04:00
void FMetasoundDataTypeSelector : : OnDataTypeArrayChanged ( TWeakObjectPtr < UMetasoundEditorGraphMember > InGraphMember , ECheckBoxState InNewState )
2021-03-19 15:10:57 -04:00
{
2021-11-07 23:43:01 -05:00
if ( InGraphMember . IsValid ( ) & & DataTypeComboBox . IsValid ( ) )
2021-03-19 15:10:57 -04:00
{
TSharedPtr < FString > DataTypeRoot = DataTypeComboBox - > GetSelectedItem ( ) ;
if ( ensure ( DataTypeRoot . IsValid ( ) ) )
{
2021-03-24 16:42:25 -04:00
// Have to stop playback to avoid attempting to change live edit data on invalid input type.
check ( GEditor ) ;
GEditor - > ResetPreviewAudioComponent ( ) ;
2021-12-13 18:15:01 -05:00
const FName DataType = InNewState = = ECheckBoxState : : Checked ? ArrayTypeName : BaseTypeName ;
InGraphMember - > SetDataType ( DataType ) ;
2021-03-19 15:10:57 -04:00
2021-12-13 18:15:01 -05:00
if ( FMetasoundAssetBase * MetasoundAsset = Metasound : : IMetasoundUObjectRegistry : : Get ( ) . GetObjectAsAssetBase ( GraphMember - > GetOutermostObject ( ) ) )
{
MetasoundAsset - > SetUpdateDetailsOnSynchronization ( ) ;
}
2021-03-19 15:10:57 -04:00
}
}
}
2021-12-13 18:15:01 -05:00
const FText FMetasoundInputDetailCustomization : : MemberNameText = LOCTEXT ( " InputGraphMemberLabel " , " Input " ) ;
bool FMetasoundInputDetailCustomization : : IsInterfaceMember ( ) const
{
if ( GraphMember . IsValid ( ) )
{
return CastChecked < UMetasoundEditorGraphVertex > ( GraphMember ) - > IsInterfaceMember ( ) ;
}
return false ;
}
const FText FMetasoundOutputDetailCustomization : : MemberNameText = LOCTEXT ( " OutputGraphMemberLabel " , " Output " ) ;
bool FMetasoundOutputDetailCustomization : : IsInterfaceMember ( ) const
2021-03-19 15:10:57 -04:00
{
2021-12-13 18:15:01 -05:00
if ( GraphMember . IsValid ( ) )
{
return CastChecked < UMetasoundEditorGraphVertex > ( GraphMember ) - > IsInterfaceMember ( ) ;
}
return false ;
2021-03-19 15:10:57 -04:00
}
} // namespace Editor
} // namespace Metasound
# undef LOCTEXT_NAMESPACE