// Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include "CoreMinimal.h" #include "Layout/Visibility.h" #include "Widgets/DeclarativeSyntaxSupport.h" #include "Input/Reply.h" #include "Widgets/SWidget.h" #include "IPropertyTypeCustomization.h" #include "PropertyHandle.h" #include "IDetailCustomization.h" #include "Widgets/Views/SListView.h" #include "Widgets/Views/STableViewBase.h" #include "Widgets/Views/STableRow.h" #include "IDetailPropertyExtensionHandler.h" struct FAssetData; class FBlueprintEditor; class UAnimationAsset; class UAnimGraphNode_Base; class UBlendProfile; class UEditorParentPlayerListObj; class USkeleton; class IEditableSkeleton; struct FAnimParentNodeAssetOverride; class FAnimGraphNodeBindingExtension : public IDetailPropertyExtensionHandler { public: // IDetailPropertyExtensionHandler interface virtual bool IsPropertyExtendable(const UClass* InObjectClass, const IPropertyHandle& PropertyHandle) const override; virtual void ExtendWidgetRow(FDetailWidgetRow& InWidgetRow, const IDetailLayoutBuilder& InDetailBuilder, const UClass* InObjectClass, TSharedPtr PropertyHandle) override; private: // Helper function void GetOptionalPinData(const IPropertyHandle& PropertyHandle, int32& OutOptionalPinIndex, UAnimGraphNode_Base*& OutAnimGraphNode) const; }; ///////////////////////////////////////////////////// // FAnimGraphNodeDetails class FAnimGraphNodeDetails : public IDetailCustomization { public: static TSharedRef MakeInstance(); // IDetailCustomization interface virtual void CustomizeDetails(class IDetailLayoutBuilder& DetailBuilder) override; // End of IDetailCustomization interface protected: // Creates a widget for the supplied property TSharedRef CreatePropertyWidget(FProperty* TargetProperty, TSharedRef TargetPropertyHandle, UClass* NodeClass); // Creates the 'as pin' toggle widget for a property TSharedRef CreateAsPinWidget(TSharedRef InPropertyHandle); EVisibility GetVisibilityOfProperty(TSharedRef Handle) const; /** Delegate to handle filtering of asset pickers */ bool OnShouldFilterAnimAsset( const FAssetData& AssetData, UClass* NodeToFilterFor ) const; /** Called when a blend profile is selected */ void OnBlendProfileChanged(UBlendProfile* NewProfile, TSharedPtr PropertyHandle); /** Called when pin visibility changes */ void OnPinVisibilityChanged(bool bInIsVisible, int32 InOptionalPinIndex); /** The skeleton we're operating on */ USkeleton* TargetSkeleton = nullptr; /** Path to the current blueprints skeleton to allow us to filter asset pickers */ FString TargetSkeletonName; /** Builder that built this customization (used for refresh) */ IDetailLayoutBuilder* DetailLayoutBuilder = nullptr; /** Whether or not the anim blueprint is a template */ bool bIsAnimBPTemplate = false; }; ///////////////////////////////////////////////////// // FInputScaleBiasCustomization class FInputScaleBiasCustomization : public IPropertyTypeCustomization { public: static TSharedRef MakeInstance(); // IPropertyTypeCustomization interface virtual void CustomizeHeader(TSharedRef StructPropertyHandle, class FDetailWidgetRow& HeaderRow, IPropertyTypeCustomizationUtils& StructCustomizationUtils) override; virtual void CustomizeChildren(TSharedRef StructPropertyHandle, class IDetailChildrenBuilder& ChildBuilder, IPropertyTypeCustomizationUtils& StructCustomizationUtils) override; // End of IPropertyTypeCustomization interface FText GetMinValue(TSharedRef StructPropertyHandle) const; FText GetMaxValue(TSharedRef StructPropertyHandle) const; void OnMinValueCommitted(const FText& NewText, ETextCommit::Type CommitInfo, TSharedRef StructPropertyHandle); void OnMaxValueCommitted(const FText& NewText, ETextCommit::Type CommitInfo, TSharedRef StructPropertyHandle); }; ////////////////////////////////////////////////////////////////////////// // FBoneReferenceCustomization class FBoneReferenceCustomization : public IPropertyTypeCustomization { public: static TSharedRef MakeInstance(); // IPropertyTypeCustomization interface virtual void CustomizeHeader(TSharedRef StructPropertyHandle, class FDetailWidgetRow& HeaderRow, IPropertyTypeCustomizationUtils& StructCustomizationUtils) override; virtual void CustomizeChildren(TSharedRef StructPropertyHandle, class IDetailChildrenBuilder& ChildBuilder, IPropertyTypeCustomizationUtils& StructCustomizationUtils) override {} const struct FReferenceSkeleton& GetReferenceSkeleton() const; protected: USkeleton* GetSkeleton() const; static TSharedPtr FindStructMemberProperty(TSharedPtr PropertyHandle, const FName& PropertyName); TSharedPtr StructProperty; // Property to change after bone has been picked TSharedPtr BoneNameProperty; TArray> SelectedObjects; private: // Bone tree widget delegates virtual void OnBoneSelectionChanged(FName Name); virtual FName GetSelectedBone(bool& bMultipleValues) const; }; ////////////////////////////////////////////////////////////////////////// // FBoneSocketTargetCustomization class FBoneSocketTargetCustomization : public FBoneReferenceCustomization { public: static TSharedRef MakeInstance(); virtual void CustomizeHeader(TSharedRef StructPropertyHandle, class FDetailWidgetRow& HeaderRow, IPropertyTypeCustomizationUtils& StructCustomizationUtils) override; private: void ResolveChildProperties(); // Property to change after bone has been picked TSharedPtr SocketNameProperty; TSharedPtr UseSocketProperty; // Bone tree widget delegates virtual void OnBoneSelectionChanged(FName Name) override; virtual FName GetSelectedBone(bool& bMultipleValues) const override; const TArray& GetSocketList() const; TSharedPtr GetNameProperty() const; }; ////////////////////////////////////////////////////////////////////////// // // Type used to identify rows in a parent player tree list namespace EPlayerTreeViewEntryType { enum Type { Blueprint, Graph, Node }; } // Describes a single row entry in a player tree view struct FPlayerTreeViewEntry : public TSharedFromThis { FPlayerTreeViewEntry(FString Name, EPlayerTreeViewEntryType::Type InEntryType, FAnimParentNodeAssetOverride* InOverride = NULL) : EntryName(Name) , EntryType(InEntryType) , Override(InOverride) {} FORCENOINLINE bool operator==(const FPlayerTreeViewEntry& Other); void GenerateNameWidget(TSharedPtr Box); // Name for the row FString EntryName; // What the row represents EPlayerTreeViewEntryType::Type EntryType; // Node asset override for rows that represent nodes FAnimParentNodeAssetOverride* Override; // Children array for rows that represent blueprints and graphs. TArray> Children; }; class FAnimGraphParentPlayerDetails : public IDetailCustomization { public: static TSharedRef MakeInstance(TSharedRef InBlueprintEditor); virtual void CustomizeDetails(class IDetailLayoutBuilder& DetailBuilder); private: FAnimGraphParentPlayerDetails(const TSharedRef& InBlueprintEditor) : BlueprintEditorPtr(InBlueprintEditor) {} TSharedRef OnGenerateRow(TSharedPtr EventPtr, const TSharedRef< STableViewBase >& OwnerTable); void OnGetChildren(TSharedPtr InParent, TArray< TSharedPtr >& OutChildren); // Entries in the tree view TArray> ListEntries; // Hosting Blueprint Editor instance TWeakPtr BlueprintEditorPtr; // Editor meta-object containing override information UEditorParentPlayerListObj* EditorObject; }; class SParentPlayerTreeRow : public SMultiColumnTableRow> { public: SLATE_BEGIN_ARGS(SParentPlayerTreeRow){} SLATE_ARGUMENT(TSharedPtr, Item); SLATE_ARGUMENT(UEditorParentPlayerListObj*, OverrideObject); SLATE_ARGUMENT(TWeakPtr, BlueprintEditor); SLATE_END_ARGS(); void Construct(const FArguments& InArgs, const TSharedRef& InOwnerTableView); virtual TSharedRef GenerateWidgetForColumn(const FName& ColumnName); private: // Should an asset be filtered, ensures we only approve assets with matching skeletons bool OnShouldFilterAsset(const FAssetData& AssetData); // Sets the override asset when selected from the asset picker void OnAssetSelected(const FAssetData& AssetData); void OnCloseMenu(){} // Called when the user clicks the focus button, opens a graph panel if necessary in // read only mode and focusses on the node. FReply OnFocusNodeButtonClicked(); // Gets the current asset, either an override if one is selected or the original from the node. const UAnimationAsset* GetCurrentAssetToUse() const; // Whether or not we should show the reset to default button next to the asset picker EVisibility GetResetToDefaultVisibility() const; // Resets the selected asset override back to the original node's asset FReply OnResetButtonClicked(); // Gets the full path to the current asset FString GetCurrentAssetPath() const; // Editor object containing all possible overrides UEditorParentPlayerListObj* EditorObject; // Tree item we are representing TSharedPtr Item; // Graphnode this row represents, if any UAnimGraphNode_Base* GraphNode; // Blueprint editor pointer TWeakPtr BlueprintEditor; };