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_LEGACY
- public:
- /** Delegate that handles if any folder paths changed as a result of a move, rename, etc. in the path view*/
- FOnFolderPathChanged OnFolderPathChanged;
- #endif
- protected:
- /** 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;
- };
|