| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436 | // Copyright 2017-2021 marynate. All Rights Reserved.#pragma once#include "IExtContentBrowserSingleton.h"#include "ExtAssetViewTypes.h"#include "ExtAssetData.h"#include "CoreMinimal.h"#include "SlateFwd.h"#include "Widgets/DeclarativeSyntaxSupport.h"#include "Input/Reply.h"#include "Widgets/SCompoundWidget.h"#include "AssetRegistry/AssetData.h"#include "Widgets/Views/STableViewBase.h"#include "Widgets/Views/STableRow.h"#include "Widgets/Views/STreeView.h"#include "Misc/TextFilter.h"#include "Delegates/DelegateCombinations.h"struct FHistoryData;struct FTreeItem;typedef TTextFilter< const FString& > FolderTextFilter;DECLARE_DELEGATE_OneParam(FOnAssetTreeSearchBoxChanged, const FText& /*SearchText*/);DECLARE_DELEGATE_TwoParams(FOnAssetTreeSearchBoxCommitted, const FText& /*InSearchText*/, ETextCommit::Type /*InCommitType*/);/** * The tree view of folders which contain content. */class SExtPathView : public SCompoundWidget{public:	SLATE_BEGIN_ARGS( SExtPathView )		: _FocusSearchBoxWhenOpened(true)		, _ShowTreeTitle(false)		, _SearchBarVisibility(EVisibility::Visible)		, _ShowSeparator(true)		, _AllowContextMenu(true)		, _AllowClassesFolder(false)		, _SelectionMode( ESelectionMode::Multi )		{}		/** Content displayed to the left of the search bar */		SLATE_NAMED_SLOT( FArguments, SearchContent )		/** Called when a tree paths was selected */		SLATE_EVENT( FOnPathSelected, OnPathSelected )		/** Called when a context menu is opening on a folder */		SLATE_EVENT( FOnGetFolderContextMenu, OnGetFolderContextMenu )		/** Called a context menu is opening on a path */		SLATE_EVENT( FContentBrowserMenuExtender_SelectedPaths, OnGetPathContextMenuExtender )		/** If true, the search box will be focus the frame after construction */		SLATE_ARGUMENT( bool, FocusSearchBoxWhenOpened )		/** If true, The tree title will be displayed */		SLATE_ARGUMENT( bool, ShowTreeTitle )		/** If EVisibility::Visible, The tree search bar will be displayed */		SLATE_ATTRIBUTE( EVisibility, SearchBarVisibility )		/** If true, The tree search bar separator be displayed */		SLATE_ARGUMENT( bool, ShowSeparator )		/** If false, the context menu will be suppressed */		SLATE_ARGUMENT( bool, AllowContextMenu )		/** If false, the classes folder will be suppressed */		SLATE_ARGUMENT( bool, AllowClassesFolder )		/** The selection mode for the tree view */		SLATE_ARGUMENT( ESelectionMode::Type, SelectionMode )	SLATE_END_ARGS()	/** Destructor */	~SExtPathView();	/** Constructs this widget with InArgs */	virtual void Construct( const FArguments& InArgs );	/** Tick path view */	virtual void Tick(const FGeometry& AllottedGeometry, const double InCurrentTime, const float InDeltaTime) override;	/** Selects the closest matches to the supplied paths in the tree. "/" delimited */	virtual void SetSelectedPaths(const TArray<FString>& Paths);	/** Clears selection of all paths */	void ClearSelection();	/** Returns the number of selected paths */	int32 GetNumPathsSelected() const;	/** Returns the first selected path in the tree view */	FString GetSelectedPath() const;	/** Returns all selected paths in the tree view */	TArray<FString> GetSelectedPaths() const;	/** Adds nodes to the tree in order to construct the specified path. If bUserNamed is true, the user will name the folder and Path includes the default name. */	virtual TSharedPtr<FTreeItem> AddPath(const FString& Path, const FString* RootPathPtr = nullptr, bool bUserNamed = false);	/** Attempts to removed the folder at the end of the specified path from the tree. Returns true when successful. */	bool RemovePath(const FString& Path);	/** Sets up an inline rename for the specified folder */	void RenameFolder(const FString& FolderToRename);	/**	 * Selects the paths containing the specified assets.	 *	 *	@param AssetDataList		- A list of assets to sync the view to	 * 	 *	@param bAllowImplicitSync	- true to allow the view to sync to parent folders if they are already selected,	 *								  false to force the view to select the explicit Parent folders of each asset 	 */	void SyncToAssets( const TArray<FExtAssetData>& AssetDataList, const bool bAllowImplicitSync = false );	/**	 * Selects the given paths.	 *	 *	@param FolderList			- A list of folders to sync the view to	 * 	 *	@param bAllowImplicitSync	- true to allow the view to sync to parent folders if they are already selected,	 *								  false to force the view to select the explicit Parent folders of each asset 	 */	void SyncToFolders( const TArray<FString>& FolderList, const bool bAllowImplicitSync = false );	/**	 * Selects the given items.	 *	 *	@param ItemSelection		- A list of assets and folders to sync the view to	 * 	 *	@param bAllowImplicitSync	- true to allow the view to sync to parent folders if they are already selected,	 *								  false to force the view to select the explicit Parent folders of each asset 	 */	void SyncTo( const FExtContentBrowserSelection& ItemSelection, const bool bAllowImplicitSync = false );	/** Finds the item that represents the specified path, if it exists. */	TSharedPtr<FTreeItem> FindItemRecursive(const FString& Path) const;	/** Sets the state of the path view to the one described by the history data */	void ApplyHistoryData( const FHistoryData& History );	/** Saves any settings to config that should be persistent between editor sessions */	virtual void SaveSettings(const FString& IniFilename, const FString& IniSection, const FString& SettingsString) const;	/** Loads any settings to config that should be persistent between editor sessions */	virtual void LoadSettings(const FString& IniFilename, const FString& IniSection, const FString& SettingsString);	/** Populates the tree with all folders that are not filtered out */	virtual void Populate();	/** Sets an alternate tree title*/	void SetTreeTitle(FText InTitle)	{		TreeTitle = InTitle;	};	FText GetTreeTitle() const;	EVisibility GetTreeTitleVisibility() const;	FText GetPluginVersionText() const	{		return PluginVersionText;	}	/** Handler for when search terms change in the asset tree search box */	virtual void OnAssetTreeSearchBoxChanged(const FText& InSearchText);	/** Handler for when search term is committed in the asset tree search box */	virtual void OnAssetTreeSearchBoxCommitted(const FText& InSearchText, ETextCommit::Type InCommitType);#if ECB_LEGACYpublic:	/** Delegate that handles if any folder paths changed as a result of a move, rename, etc. in the path view*/	FOnFolderPathChanged OnFolderPathChanged;#endifprotected:	/** Expands all parents of the specified item */	void RecursiveExpandParents(const TSharedPtr<FTreeItem>& Item);	/** Sort the root items into the correct order */	void SortRootItems();	/** Handles updating the content browser when an asset path is added to the asset registry */	virtual void OnAssetRegistryPathAdded(const FString& Path);	/** Handles updating the content browser when an asset path is removed from the asset registry */	virtual void OnAssetRegistryPathRemoved(const FString& Path);	/** Handles updating the content browser when a root content path is added to the asset registry */	virtual void OnAssetRegistryRootPathAdded(const FString& Path);	/** Handles updating the content browser when a root content path is removed from the asset registry */	virtual void OnAssetRegistryRootPathRemoved(const FString& Path);	/** Handles updating the content browser when root content path list been updated in the asset registry */	virtual void OnAssetRegistryRootPathUpdated();	/** Handles updating the content browser when folders is start rescanning from the asset registry */	virtual void OnAssetRegistryFolderStartGathering(const TArray<FString>& Paths);	/** Handles updating the content browser when folders is finishing rescanning from the asset registry */	virtual void OnAssetRegistryFolderFinishGathering(const FString& InPath, const FString& InRootPath);	/** Creates a list item for the tree view */	virtual TSharedRef<ITableRow> GenerateTreeRow(TSharedPtr<FTreeItem> TreeItem, const TSharedRef<STableViewBase>& OwnerTable);	/** Handles focusing a folder widget after it has been created with the intent to rename */	void TreeItemScrolledIntoView(TSharedPtr<FTreeItem> TreeItem, const TSharedPtr<ITableRow>& Widget);	/** Handler for tree view selection changes */	void TreeSelectionChanged(TSharedPtr< FTreeItem > TreeItem, ESelectInfo::Type SelectInfo);	/** Gets the content for a context menu */	TSharedPtr<SWidget> MakePathViewContextMenu();	/** Handler for returning a list of children associated with a particular tree node */	void GetChildrenForTree(TSharedPtr< FTreeItem > TreeItem, TArray< TSharedPtr<FTreeItem> >& OutChildren);	/** Gets the string to highlight in tree items (used in folder searching) */	FText GetHighlightText() const;	/** True if the specified item is selected in the asset tree */	bool IsTreeItemSelected(TSharedPtr<FTreeItem> TreeItem) const;	/** Handler for tree view folders are dragged */	FReply OnFolderDragDetected(const FGeometry& Geometry, const FPointerEvent& MouseEvent);	/** Handler for when assets or asset paths are dropped on a tree item */	virtual void TreeAssetsOrPathsDropped(const TArray<FAssetData>& AssetList, const TArray<FString>& AssetPaths, const TSharedPtr<FTreeItem>& TreeItem);	/** Handler for when asset paths are dropped on a tree item */	void TreeFilesDropped(const TArray<FString>& FileNames, const TSharedPtr<FTreeItem>& TreeItem);	/** Handler for the user selecting to move assets or asset paths to the specified folder */	virtual void ExecuteTreeDropMove(TArray<FAssetData> AssetList, TArray<FString> AssetPaths, FString DestinationPath);	/** Get relative path to one of the root paths, assume root paths are sorted */	void GetPathItemList(const FString& InPath, const TArray<FString>& InRootPaths, TArray<FString>& OutPathItemList, bool bIncludeRootPath) const;private:	/** Internal sync implementation, syncs to the tree to the given array of items */	void SyncToInternal( const TArray<FExtAssetData>& AssetDataList, const TArray<FString>& FolderPaths, const bool bAllowImplicitSync );	/** Called when "new folder" is selected in the context menu */	void OnCreateNewFolder(const FString& FolderName, const FString& FolderPath);	/** Selects the given path only if it exists. Returns true if selected. */	bool ExplicitlyAddPathToSelection(const FString& Path);	/** Returns true if the selection changed delegate should be allowed */	bool ShouldAllowTreeItemChangedDelegate() const;	/** Adds a new root folder */	TSharedPtr<FTreeItem> AddRootItem( const FString& InFolderName );	/** Handler for recursively expanding/collapsing items in the tree view */	void SetTreeItemExpansionRecursive( TSharedPtr< FTreeItem > TreeItem, bool bInExpansionState );	/** Handler for tree view expansion changes */	void TreeExpansionChanged( TSharedPtr< FTreeItem > TreeItem, bool bIsExpanded );	/** Handler for when the search box filter has changed */	void FilterUpdated();	/** Populates OutSearchStrings with the strings that should be used in searching */	void PopulateFolderSearchStrings( const FString& FolderName, OUT TArray< FString >& OutSearchStrings ) const;	/** Returns true if the supplied folder item already exists in the tree. If so, ExistingItem will be set to the found item. */	bool FolderAlreadyExists(const TSharedPtr< FTreeItem >& TreeItem, TSharedPtr< FTreeItem >& ExistingItem);	/** Removes the supplied folder from the tree. */	void RemoveFolderItem(const TSharedPtr< FTreeItem >& TreeItem);	/** True if the specified item is expanded in the asset tree */	bool IsTreeItemExpanded(TSharedPtr<FTreeItem> TreeItem) const;	/** Gets all the UObjects represented by assets in the AssetList */	void GetDroppedObjects(const TArray<FAssetData>& AssetList, TArray<UObject*>& OutDroppedObjects);	/** Handler for the user selecting to copy assets or asset paths to the specified folder */	void ExecuteTreeDropCopy(TArray<FAssetData> AssetList, TArray<FString> AssetPaths, FString DestinationPath);	/** Handler for the user selecting to copy assets or asset paths - and dependencies - to the specified folder */	void ExecuteTreeDropAdvancedCopy(TArray<FAssetData> AssetList, TArray<FString> AssetPaths, FString DestinationPath);	/** Notification for when the Asset Registry has completed it's initial search */	void OnAssetRegistrySearchCompleted();	/** Handles updating the content browser when a path is populated with an asset for the first time */	void OnFolderPopulated(const FString& Path);	/** Called from an engine core event when a new content path has been added or removed, so that we can refresh our root set of paths */	void OnContentPathMountedOrDismounted( const FString& AssetPath, const FString& FileSystemPath );	/** Called when the class hierarchy is updated due to the available modules changing */	void OnClassHierarchyUpdated();	/** Delegate called when an editor setting is changed */	void HandleSettingChanged(FName PropertyName);	/** One-off active timer to focus the widget post-construct */	EActiveTimerReturnType SetFocusPostConstruct(double InCurrentTime, float InDeltaTime);	/** One-off active timer to repopulate the path view */	EActiveTimerReturnType TriggerRepopulate(double InCurrentTime, float InDeltaTime);protected:	/** A helper class to manage PreventTreeItemChangedDelegateCount by incrementing it when constructed (on the stack) and decrementing when destroyed */	class FScopedPreventTreeItemChangedDelegate	{	public:		FScopedPreventTreeItemChangedDelegate(const TSharedRef<SExtPathView>& InPathView)			: PathView(InPathView)		{			PathView->PreventTreeItemChangedDelegateCount++;		}		~FScopedPreventTreeItemChangedDelegate()		{			check(PathView->PreventTreeItemChangedDelegateCount > 0);			PathView->PreventTreeItemChangedDelegateCount--;		}	private:		TSharedRef<SExtPathView> PathView;	};	/** The tree view widget */	TSharedPtr< STreeView< TSharedPtr<FTreeItem>> > TreeViewPtr;	/** The asset tree search box */	TSharedPtr< SSearchBox > SearchBoxPtr;	/** The list of folders in the tree */	TArray< TSharedPtr<FTreeItem> > TreeRootItems;	/** The The TextFilter attached to the SearchBox widget */	TSharedPtr< FolderTextFilter > SearchBoxFolderFilter;	/** The paths that were last reported by OnPathSelected event. Used in preserving selection when filtering folders */	TSet< FString > LastSelectedPaths;	/** If not empty, this is the path of the folders to sync once they are available while assets are still being discovered */	TArray<FString> PendingInitialPaths;	TSharedPtr<SWidget> PathViewWidget;private:	/** The paths that were last reported by OnPathExpanded event. Used in preserving expansion when filtering folders */	TSet< FString > LastExpandedPaths;	/** Delegate to invoke when selection changes. */	FOnPathSelected OnPathSelected;	/** Delegate to invoke when generating the context menu for a folder */	FOnGetFolderContextMenu OnGetFolderContextMenu;	/** Delegate to invoke when a context menu for a folder is opening. */	FContentBrowserMenuExtender_SelectedPaths OnGetPathContextMenuExtender;	/** If > 0, the selection or expansion changed delegate will not be called. Used to update the tree from an external source or in certain bulk operations. */	int32 PreventTreeItemChangedDelegateCount;	/** If false, the context menu will not open when right clicking an item in the tree */	bool bAllowContextMenu;	/** If false, the classes folder will not be added to the tree automatically */	bool bAllowClassesFolder;	/** The title of this path view */	FText TreeTitle;	/** The plugin version text */	FText PluginVersionText;};/*** The tree view of folders which contain favorited folders.*/class SFavoritePathView : public SExtPathView{public:	/** Constructs this widget with InArgs */	virtual void Construct(const FArguments& InArgs) override;	virtual void Populate() override;	/** Saves any settings to config that should be persistent between editor sessions */	virtual void SaveSettings(const FString& IniFilename, const FString& IniSection, const FString& SettingsString) const override;	/** Loads any settings to config that should be persistent between editor sessions */	virtual void LoadSettings(const FString& IniFilename, const FString& IniSection, const FString& SettingsString) override;	/** Handler for when search terms change in the asset tree search box */	virtual void OnAssetTreeSearchBoxChanged(const FText& InSearchText) override;	/** Handler for when search term is committed in the asset tree search box */	virtual void OnAssetTreeSearchBoxCommitted(const FText& InSearchText, ETextCommit::Type InCommitType) override;	/** Selects the closest matches to the supplied paths in the tree. "/" delimited */	virtual void SetSelectedPaths(const TArray<FString>& Paths) override;	FOnAssetTreeSearchBoxChanged OnFavoriteSearchChanged;	FOnAssetTreeSearchBoxCommitted OnFavoriteSearchCommitted;	/** Adds nodes to the tree in order to construct the specified path. If bUserNamed is true, the user will name the folder and Path includes the default name. */	virtual TSharedPtr<FTreeItem> AddPath(const FString& Path, const FString* RootPathPtr = nullptr, bool bUserNamed = false) override;private:	virtual TSharedRef<ITableRow> GenerateTreeRow(TSharedPtr<FTreeItem> TreeItem, const TSharedRef<STableViewBase>& OwnerTable) override;	/** Handles updating the content browser when an asset path is added to the asset registry */	virtual void OnAssetRegistryPathAdded(const FString& Path) override;	/** Handles updating the content browser when an asset path is removed from the asset registry */	virtual void OnAssetRegistryPathRemoved(const FString& Path) override;	virtual void ExecuteTreeDropMove(TArray<FAssetData> AssetList, TArray<FString> AssetPaths, FString DestinationPath) override;private:	TArray<FString> RemovedByFolderMove;};
 |