// Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include "CoreMinimal.h" #include "SlateFwd.h" #include "Widgets/DeclarativeSyntaxSupport.h" #include "Input/Reply.h" #include "Widgets/SCompoundWidget.h" #include "Engine/SkeletalMesh.h" #include "Widgets/Views/STableViewBase.h" #include "Widgets/Views/STableRow.h" struct FAssetData; class IEditableSkeleton; template class SListView; ////////////////////////////////////////////////////////////////////////// // FDisplayedRetargetSourceInfo class FDisplayedRetargetSourceInfo { public: FName Name; TSoftObjectPtr ReferenceMesh; /** Static function for creating a new item, but ensures that you can only have a TSharedRef to one */ static TSharedRef Make(const FName& SourcePose, TSoftObjectPtr InReferenceMesh, bool bInDirtyFlag) { return MakeShareable(new FDisplayedRetargetSourceInfo(SourcePose, InReferenceMesh, bInDirtyFlag)); } FString GetDisplayName() { TArray Args; Args.Add(FStringFormatArg(Name.ToString())); Args.Add(FStringFormatArg(bDirtyFlag ? TEXT(" [out of date]") : TEXT(""))); return FString::Format(TEXT("{0}{1}"), Args); } FString GetReferenceMeshName() { TArray Args; Args.Add(FStringFormatArg((!ReferenceMesh.IsNull()) ? ReferenceMesh.ToString() : TEXT("None"))); return FString::Format(TEXT("{0}"), Args); } /** Requests a rename on the socket item */ void RequestRename() { OnEnterEditingMode.ExecuteIfBound(); } /** Delegate for when the context menu requests a rename */ DECLARE_DELEGATE(FOnEnterEditingMode); FOnEnterEditingMode OnEnterEditingMode; protected: /** Hidden constructor, always use Make above */ FDisplayedRetargetSourceInfo(const FName& InSource, TSoftObjectPtr InRefMesh, bool InDirtyFlag) : Name( InSource ) , ReferenceMesh( InRefMesh ) , bRenamePending( false ) , bDirtyFlag(InDirtyFlag) {} /** Hidden constructor, always use Make above */ FDisplayedRetargetSourceInfo() {} bool bRenamePending; bool bDirtyFlag; }; typedef SListView< TSharedPtr > SRetargetSourceListType; ////////////////////////////////////////////////////////////////////////// // SRetargetSourceWindow class SRetargetSourceWindow : public SCompoundWidget { public: SLATE_BEGIN_ARGS( SRetargetSourceWindow ) {} SLATE_END_ARGS() /** * Slate construction function * * @param InArgs - Arguments passed from Slate * */ void Construct( const FArguments& InArgs, const TSharedRef& InEditableSkeleton, FSimpleMulticastDelegate& InOnPostUndo); /** * Filters the SListView when the user changes the search text box (NameFilterBox) * * @param SearchText - The text the user has typed * */ void OnFilterTextChanged( const FText& SearchText ); /** * Filters the SListView when the user hits enter or clears the search box * Simply calls OnFilterTextChanged * * @param SearchText - The text the user has typed * @param CommitInfo - Not used * */ void OnFilterTextCommitted( const FText& SearchText, ETextCommit::Type CommitInfo ); /** * Create a widget for an entry in the tree from an info * * @param InInfo - Shared pointer to the morph target we're generating a row for * @param OwnerTable - The table that owns this row * * @return A new Slate widget, containing the UI for this row */ TSharedRef GenerateRetargetSourceRow(TSharedPtr InInfo, const TSharedRef& OwnerTable); /** * Handler for adding new retarget source. It displays the asset picker */ void OnAddRetargetSource(); /** * Callback for asset picker */ void OnAssetSelectedFromMeshPicker(const FAssetData& AssetData); /** * Adds a new retarget source with given name * * @param Name - Name of retarget source * @param ReferenceMesh - Reference Mesh this pose is based on * */ void AddRetargetSource( const FName Name, USkeletalMesh * ReferenceMesh ); /** * Return true if it can delete * */ bool CanPerformDelete() const; /** * Handler for the delete of retarget source */ void OnDeleteRetargetSource(); /** * Return true if it can perform rename * */ bool CanPerformRename() const; /** * Handler for the rename of retarget source */ void OnRenameRetargetSource(); /** * Return true if it can delete * */ bool CanPerformRefresh() const; /** * Handler for the delete of retarget source */ void OnRefreshRetargetSource(bool bAll = false); /** * Accessor so our rows can grab the filtertext for highlighting * */ FText& GetFilterText() { return FilterText; } // SWidget interface virtual int32 OnPaint( const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyCullingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled ) const override; // end of SWidget interface private: /** Handler for context menus */ TSharedPtr OnGetContextMenuContent() const; /** * Clears and rebuilds the table, according to an optional search string * * @param SearchText - Optional search string * */ void CreateRetargetSourceList( const FString& SearchText = FString(""), const FName NewName = NAME_None ); /** The editable skeleton */ TWeakPtr EditableSkeletonPtr; /** Box to filter to a specific morph target name */ TSharedPtr NameFilterBox; /** Widget used to display the list of retarget sources */ TSharedPtr RetargetSourceListView; /** A list of retarget sources. Used by the RetargetSourceListView. */ TArray< TSharedPtr > RetargetSourceList; /** Current text typed into NameFilterBox */ FText FilterText; /** Item to rename. Only valid for adding **/ mutable TSharedPtr ItemToRename; /** Rename committed. Called by Inline Widget **/ void OnRenameCommit(const FName& InOldName, const FString& InNewName); /** Verify Rename is legit or not **/ bool OnVerifyRenameCommit( const FName& OldName, const FString& NewName, FText& OutErrorMessage); /** Delegate for undo/redo transaction **/ void PostUndo(); /** Button handler **/ FReply OnAddRetargetSourceButtonClicked(); FReply OnUpdateAllRetargetSourceButtonClicked(); }; class SCompatibleSkeletons : public SCompoundWidget { public: SLATE_BEGIN_ARGS( SCompatibleSkeletons ){} SLATE_END_ARGS() void Construct(const FArguments& InArgs, const TSharedRef& InEditableSkeleton, FSimpleMulticastDelegate& InOnPostUndo); FReply OnAddSkeletonClicked(); FReply OnRemoveSkeletonClicked(); TSharedRef GenerateRowForItem(TSharedRef Item, const TSharedRef& OwnerTable) const; void OnAssetSelectedFromSkeletonPicker(const FAssetData& AssetData); private: void UpdateCompatibleSkeletonAssets(const USkeleton& Skeleton); TArray> CompatibleSkeletonAssets; TSharedPtr>> CompatibleSkeletonListView; TWeakPtr EditableSkeletonPtr; };