2014-12-07 19:09:38 -05:00
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
2014-03-14 14:13:41 -04:00
# include "ContentBrowserPCH.h"
2015-05-29 13:15:40 -04:00
# include "CollectionAssetManagement.h"
2014-03-14 14:13:41 -04:00
# include "CollectionViewTypes.h"
# include "CollectionContextMenu.h"
2015-06-19 07:33:02 -04:00
# include "DragAndDrop/AssetDragDropOp.h"
# include "DragAndDrop/CollectionDragDropOp.h"
2014-03-14 14:13:41 -04:00
# include "ObjectTools.h"
# include "SourcesViewWidgets.h"
# include "ContentBrowserModule.h"
2014-10-14 22:50:06 -04:00
# include "SExpandableArea.h"
2015-05-21 14:47:20 -04:00
# include "SSearchBox.h"
2014-03-14 14:13:41 -04:00
# define LOCTEXT_NAMESPACE "ContentBrowser"
2015-06-10 13:19:26 -04:00
namespace CollectionViewFilter
{
void GetBasicStrings ( const FCollectionItem & InCollection , TArray < FString > & OutBasicStrings )
{
OutBasicStrings . Add ( InCollection . CollectionName . ToString ( ) ) ;
}
2015-06-24 12:29:41 -04:00
bool TestComplexExpression ( const FCollectionItem & InCollection , const FName & InKey , const FTextFilterString & InValue , ETextFilterComparisonOperation InComparisonOperation , ETextFilterTextComparisonMode InTextComparisonMode )
2015-06-10 13:19:26 -04:00
{
static const FName NameKeyName = " Name " ;
static const FName TypeKeyName = " Type " ;
// Handle the collection name
if ( InKey = = NameKeyName )
{
// Names can only work with Equal or NotEqual type tests
if ( InComparisonOperation ! = ETextFilterComparisonOperation : : Equal & & InComparisonOperation ! = ETextFilterComparisonOperation : : NotEqual )
{
return false ;
}
const bool bIsMatch = TextFilterUtils : : TestBasicStringExpression ( InCollection . CollectionName . ToString ( ) , InValue , InTextComparisonMode ) ;
return ( InComparisonOperation = = ETextFilterComparisonOperation : : Equal ) ? bIsMatch : ! bIsMatch ;
}
// Handle the collection type
if ( InKey = = TypeKeyName )
{
// Types can only work with Equal or NotEqual type tests
if ( InComparisonOperation ! = ETextFilterComparisonOperation : : Equal & & InComparisonOperation ! = ETextFilterComparisonOperation : : NotEqual )
{
return false ;
}
const bool bIsMatch = TextFilterUtils : : TestBasicStringExpression ( ECollectionShareType : : ToString ( InCollection . CollectionType ) , InValue , InTextComparisonMode ) ;
return ( InComparisonOperation = = ETextFilterComparisonOperation : : Equal ) ? bIsMatch : ! bIsMatch ;
}
return false ;
}
} // namespace CollectionViewFilter
2014-03-14 14:13:41 -04:00
void SCollectionView : : Construct ( const FArguments & InArgs )
{
OnCollectionSelected = InArgs . _OnCollectionSelected ;
bAllowCollectionButtons = InArgs . _AllowCollectionButtons ;
bAllowRightClickMenu = InArgs . _AllowRightClickMenu ;
2015-06-19 07:33:02 -04:00
bAllowCollectionDrag = InArgs . _AllowCollectionDrag ;
bDraggedOver = false ;
2014-03-14 14:13:41 -04:00
2015-06-01 10:04:42 -04:00
FCollectionManagerModule & CollectionManagerModule = FCollectionManagerModule : : GetModule ( ) ;
2014-03-14 14:13:41 -04:00
CollectionManagerModule . Get ( ) . OnCollectionCreated ( ) . AddSP ( this , & SCollectionView : : HandleCollectionCreated ) ;
CollectionManagerModule . Get ( ) . OnCollectionRenamed ( ) . AddSP ( this , & SCollectionView : : HandleCollectionRenamed ) ;
2015-06-19 07:33:02 -04:00
CollectionManagerModule . Get ( ) . OnCollectionReparented ( ) . AddSP ( this , & SCollectionView : : HandleCollectionReparented ) ;
2014-03-14 14:13:41 -04:00
CollectionManagerModule . Get ( ) . OnCollectionDestroyed ( ) . AddSP ( this , & SCollectionView : : HandleCollectionDestroyed ) ;
Commands = TSharedPtr < FUICommandList > ( new FUICommandList ) ;
CollectionContextMenu = MakeShareable ( new FCollectionContextMenu ( SharedThis ( this ) ) ) ;
CollectionContextMenu - > BindCommands ( Commands ) ;
2015-06-10 13:19:26 -04:00
CollectionItemTextFilter = MakeShareable ( new FCollectionItemTextFilter (
FCollectionItemTextFilter : : FItemToStringArray : : CreateStatic ( & CollectionViewFilter : : GetBasicStrings ) ,
FCollectionItemTextFilter : : FItemTestComplexExpression : : CreateStatic ( & CollectionViewFilter : : TestComplexExpression )
) ) ;
CollectionItemTextFilter - > OnChanged ( ) . AddSP ( this , & SCollectionView : : UpdateFilteredCollectionItems ) ;
2015-05-29 13:15:40 -04:00
if ( InArgs . _AllowQuickAssetManagement )
{
QuickAssetManagement = MakeShareable ( new FCollectionAssetManagement ( ) ) ;
}
2014-03-14 14:13:41 -04:00
FOnContextMenuOpening CollectionListContextMenuOpening ;
if ( InArgs . _AllowContextMenu )
{
2015-06-19 07:33:02 -04:00
CollectionListContextMenuOpening = FOnContextMenuOpening : : CreateSP ( this , & SCollectionView : : MakeCollectionTreeContextMenu ) ;
2014-03-14 14:13:41 -04:00
}
PreventSelectionChangedDelegateCount = 0 ;
TSharedRef < SWidget > HeaderContent = SNew ( SHorizontalBox )
2015-05-21 14:47:20 -04:00
+ SHorizontalBox : : Slot ( )
. FillWidth ( 1.0f )
2015-05-26 10:11:32 -04:00
. Padding ( 0.0f )
2014-03-14 14:13:41 -04:00
[
2015-05-26 10:11:32 -04:00
SNew ( SHorizontalBox )
+ SHorizontalBox : : Slot ( )
[
SNew ( STextBlock )
. Font ( FEditorStyle : : GetFontStyle ( " ContentBrowser.SourceTitleFont " ) )
. Text ( LOCTEXT ( " CollectionsListTitle " , " Collections " ) )
. Visibility ( this , & SCollectionView : : GetCollectionsTitleTextVisibility )
]
+ SHorizontalBox : : Slot ( )
[
SAssignNew ( SearchBoxPtr , SSearchBox )
. HintText ( LOCTEXT ( " CollectionsViewSearchBoxHint " , " Search Collections " ) )
2015-06-10 13:19:26 -04:00
. OnTextChanged ( this , & SCollectionView : : SetCollectionsSearchFilterText )
2015-05-26 10:11:32 -04:00
. Visibility ( this , & SCollectionView : : GetCollectionsSearchBoxVisibility )
]
2014-03-14 14:13:41 -04:00
]
+ SHorizontalBox : : Slot ( )
. AutoWidth ( )
2015-05-21 14:47:20 -04:00
. VAlign ( VAlign_Center )
. Padding ( 2.0f , 0.0f , 0.0f , 0.0f )
2014-03-14 14:13:41 -04:00
[
SNew ( SButton )
2015-05-21 14:47:20 -04:00
. ButtonStyle ( FEditorStyle : : Get ( ) , " FlatButton " )
2014-03-14 14:13:41 -04:00
. ToolTipText ( LOCTEXT ( " AddCollectionButtonTooltip " , " Add a collection. " ) )
. OnClicked ( this , & SCollectionView : : MakeAddCollectionMenu )
2015-05-21 14:47:20 -04:00
. ContentPadding ( FMargin ( 2 , 2 ) )
2014-03-14 14:13:41 -04:00
. Visibility ( this , & SCollectionView : : GetAddCollectionButtonVisibility )
[
SNew ( SImage ) . Image ( FEditorStyle : : GetBrush ( " ContentBrowser.AddCollectionButtonIcon " ) )
]
] ;
TSharedRef < SWidget > BodyContent = SNew ( SVerticalBox )
// Separator
+ SVerticalBox : : Slot ( )
. AutoHeight ( )
[
SNew ( SSeparator )
]
2015-06-19 07:33:02 -04:00
// Collections tree
2014-03-14 14:13:41 -04:00
+ SVerticalBox : : Slot ( )
. FillHeight ( 1.f )
[
2015-06-19 07:33:02 -04:00
SAssignNew ( CollectionTreePtr , STreeView < TSharedPtr < FCollectionItem > > )
. TreeItemsSource ( & VisibleRootCollectionItems )
. OnGenerateRow ( this , & SCollectionView : : GenerateCollectionRow )
. OnGetChildren ( this , & SCollectionView : : GetCollectionItemChildren )
2014-03-14 14:13:41 -04:00
. ItemHeight ( 18 )
. SelectionMode ( ESelectionMode : : Multi )
. OnSelectionChanged ( this , & SCollectionView : : CollectionSelectionChanged )
2015-06-19 07:33:02 -04:00
. OnContextMenuOpening ( CollectionListContextMenuOpening )
2014-03-14 14:13:41 -04:00
. OnItemScrolledIntoView ( this , & SCollectionView : : CollectionItemScrolledIntoView )
. ClearSelectionOnClick ( false )
2015-06-19 07:33:02 -04:00
. Visibility ( this , & SCollectionView : : GetCollectionTreeVisibility )
2014-03-14 14:13:41 -04:00
] ;
TSharedPtr < SWidget > Content ;
if ( InArgs . _AllowCollapsing )
{
Content = SAssignNew ( CollectionsExpandableAreaPtr , SExpandableArea )
. MaxHeight ( 200 )
. BorderImage ( FEditorStyle : : GetBrush ( " NoBorder " ) )
2015-05-21 14:47:20 -04:00
. HeaderPadding ( FMargin ( 4.0f , 0.0f , 0.0f , 0.0f ) )
2014-03-14 14:13:41 -04:00
. HeaderContent ( )
[
2015-05-26 10:11:32 -04:00
SNew ( SBox )
. Padding ( FMargin ( 6.0f , 0.0f , 0.0f , 0.0f ) )
[
HeaderContent
]
2014-03-14 14:13:41 -04:00
]
. BodyContent ( )
[
BodyContent
] ;
}
else
{
Content = SNew ( SVerticalBox )
2015-05-21 14:47:20 -04:00
+ SVerticalBox : : Slot ( )
. AutoHeight ( )
[
HeaderContent
2014-03-14 14:13:41 -04:00
]
2015-05-21 14:47:20 -04:00
+ SVerticalBox : : Slot ( )
[
BodyContent
] ;
2014-03-14 14:13:41 -04:00
}
ChildSlot
[
2015-06-19 07:33:02 -04:00
SNew ( SOverlay )
// Main content
+ SOverlay : : Slot ( )
[
Content . ToSharedRef ( )
]
// Drop target overlay
+ SOverlay : : Slot ( )
[
SNew ( SBorder )
. Padding ( 0 )
. Visibility ( EVisibility : : HitTestInvisible )
. BorderImage ( this , & SCollectionView : : GetCollectionViewDropTargetBorder )
. BorderBackgroundColor ( FLinearColor : : Yellow )
[
SNullWidget : : NullWidget
]
]
2014-03-14 14:13:41 -04:00
] ;
UpdateCollectionItems ( ) ;
}
void SCollectionView : : HandleCollectionCreated ( const FCollectionNameType & Collection )
{
UpdateCollectionItems ( ) ;
}
void SCollectionView : : HandleCollectionRenamed ( const FCollectionNameType & OriginalCollection , const FCollectionNameType & NewCollection )
2015-06-19 07:33:02 -04:00
{
// If the original collection was expanded, we want to pass that expansion state onto its new entry
bool bWasExpanded = false ;
{
TSharedPtr < FCollectionItem > OriginalCollectionItem = AvailableCollections . FindRef ( OriginalCollection ) ;
if ( OriginalCollectionItem . IsValid ( ) )
{
bWasExpanded = CollectionTreePtr - > IsItemExpanded ( OriginalCollectionItem ) ;
}
}
UpdateCollectionItems ( ) ;
if ( bWasExpanded )
{
TSharedPtr < FCollectionItem > NewCollectionItem = AvailableCollections . FindRef ( NewCollection ) ;
if ( NewCollectionItem . IsValid ( ) )
{
CollectionTreePtr - > SetItemExpansion ( NewCollectionItem , true ) ;
}
}
}
void SCollectionView : : HandleCollectionReparented ( const FCollectionNameType & Collection , const TOptional < FCollectionNameType > & OldParent , const TOptional < FCollectionNameType > & NewParent )
2014-03-14 14:13:41 -04:00
{
UpdateCollectionItems ( ) ;
}
void SCollectionView : : HandleCollectionDestroyed ( const FCollectionNameType & Collection )
{
UpdateCollectionItems ( ) ;
}
void SCollectionView : : UpdateCollectionItems ( )
{
2015-06-19 07:33:02 -04:00
struct FGatherCollectionItems
2014-03-14 14:13:41 -04:00
{
2015-06-19 07:33:02 -04:00
FGatherCollectionItems ( )
: CollectionManagerModule ( FCollectionManagerModule : : GetModule ( ) )
2014-03-14 14:13:41 -04:00
{
}
2015-06-19 07:33:02 -04:00
void GatherCollectionItems ( FAvailableCollectionsMap & OutAvailableCollections )
2014-03-14 14:13:41 -04:00
{
2015-06-19 07:33:02 -04:00
OutAvailableCollections . Reset ( ) ;
TArray < FCollectionNameType > RootCollections ;
CollectionManagerModule . Get ( ) . GetRootCollections ( RootCollections ) ;
ProcessGatheredCollectionsAndRecurse ( RootCollections , nullptr , OutAvailableCollections ) ;
}
void GatherChildCollectionItems ( const TSharedPtr < FCollectionItem > & InParentCollectionItem , FAvailableCollectionsMap & OutAvailableCollections )
{
TArray < FCollectionNameType > ChildCollections ;
CollectionManagerModule . Get ( ) . GetChildCollections ( InParentCollectionItem - > CollectionName , InParentCollectionItem - > CollectionType , ChildCollections ) ;
ProcessGatheredCollectionsAndRecurse ( ChildCollections , InParentCollectionItem , OutAvailableCollections ) ;
}
void ProcessGatheredCollectionsAndRecurse ( const TArray < FCollectionNameType > & InCollections , const TSharedPtr < FCollectionItem > & InParentCollectionItem , FAvailableCollectionsMap & OutAvailableCollections )
{
for ( const FCollectionNameType & Collection : InCollections )
{
// Never display system collections
if ( Collection . Type = = ECollectionShareType : : CST_System )
{
continue ;
}
TSharedPtr < FCollectionItem > CollectionItem = MakeShareable ( new FCollectionItem ( Collection . Name , Collection . Type ) ) ;
OutAvailableCollections . Add ( Collection , CollectionItem ) ;
if ( InParentCollectionItem . IsValid ( ) )
{
// Fixup the parent and child pointers
InParentCollectionItem - > ChildCollections . Add ( CollectionItem ) ;
CollectionItem - > ParentCollection = InParentCollectionItem ;
}
// Recurse
GatherChildCollectionItems ( CollectionItem , OutAvailableCollections ) ;
}
}
FCollectionManagerModule & CollectionManagerModule ;
} ;
// Backup the current selection and expansion state of our collections
// We're about to re-create the tree, so we'll need to re-apply this again afterwards
TArray < FCollectionNameType > SelectedCollections ;
TArray < FCollectionNameType > ExpandedCollections ;
{
const auto SelectedCollectionItems = CollectionTreePtr - > GetSelectedItems ( ) ;
SelectedCollections . Reserve ( SelectedCollectionItems . Num ( ) ) ;
for ( const TSharedPtr < FCollectionItem > & SelectedCollectionItem : SelectedCollectionItems )
{
SelectedCollections . Add ( FCollectionNameType ( SelectedCollectionItem - > CollectionName , SelectedCollectionItem - > CollectionType ) ) ;
}
}
{
TSet < TSharedPtr < FCollectionItem > > ExpandedCollectionItems ;
CollectionTreePtr - > GetExpandedItems ( ExpandedCollectionItems ) ;
ExpandedCollections . Reserve ( ExpandedCollectionItems . Num ( ) ) ;
for ( const TSharedPtr < FCollectionItem > & ExpandedCollectionItem : ExpandedCollectionItems )
{
ExpandedCollections . Add ( FCollectionNameType ( ExpandedCollectionItem - > CollectionName , ExpandedCollectionItem - > CollectionType ) ) ;
2014-03-14 14:13:41 -04:00
}
}
2015-06-19 07:33:02 -04:00
FGatherCollectionItems GatherCollectionItems ;
GatherCollectionItems . GatherCollectionItems ( AvailableCollections ) ;
2015-05-21 14:47:20 -04:00
2015-06-10 13:19:26 -04:00
UpdateFilteredCollectionItems ( ) ;
2015-06-19 07:33:02 -04:00
// Restore selection and expansion
SetSelectedCollections ( SelectedCollections , false ) ;
SetExpandedCollections ( ExpandedCollections ) ;
2015-05-21 14:47:20 -04:00
}
2015-06-10 13:19:26 -04:00
void SCollectionView : : UpdateFilteredCollectionItems ( )
2015-05-21 14:47:20 -04:00
{
2015-06-19 07:33:02 -04:00
VisibleCollections . Reset ( ) ;
VisibleRootCollectionItems . Reset ( ) ;
auto AddVisibleCollection = [ & ] ( const TSharedPtr < FCollectionItem > & InCollectionItem )
2015-05-21 14:47:20 -04:00
{
2015-06-19 07:33:02 -04:00
VisibleCollections . Add ( FCollectionNameType ( InCollectionItem - > CollectionName , InCollectionItem - > CollectionType ) ) ;
if ( ! InCollectionItem - > ParentCollection . IsValid ( ) )
2015-05-21 14:47:20 -04:00
{
2015-06-19 07:33:02 -04:00
VisibleRootCollectionItems . AddUnique ( InCollectionItem ) ;
}
} ;
auto AddVisibleCollectionRecursive = [ & ] ( const TSharedPtr < FCollectionItem > & InCollectionItem )
{
TSharedPtr < FCollectionItem > CollectionItemToAdd = InCollectionItem ;
do
{
AddVisibleCollection ( CollectionItemToAdd ) ;
CollectionItemToAdd = CollectionItemToAdd - > ParentCollection . Pin ( ) ;
}
while ( CollectionItemToAdd . IsValid ( ) ) ;
} ;
// Do we have an active filter to test against?
if ( CollectionItemTextFilter - > GetRawFilterText ( ) . IsEmpty ( ) )
{
// No filter, just mark everything as visible
for ( const auto & AvailableCollectionInfo : AvailableCollections )
{
AddVisibleCollection ( AvailableCollectionInfo . Value ) ;
}
}
else
{
TArray < TSharedRef < FCollectionItem > > CollectionsToExpandTo ;
// Test everything against the filter - a visible child needs to make sure its parents are also marked as visible
for ( const auto & AvailableCollectionInfo : AvailableCollections )
{
const TSharedPtr < FCollectionItem > & CollectionItem = AvailableCollectionInfo . Value ;
if ( CollectionItemTextFilter - > PassesFilter ( * CollectionItem ) )
{
AddVisibleCollectionRecursive ( CollectionItem ) ;
CollectionsToExpandTo . Add ( CollectionItem . ToSharedRef ( ) ) ;
}
}
// Make sure all matching items have their parents expanded so they can be seen
for ( const TSharedRef < FCollectionItem > & CollectionItem : CollectionsToExpandTo )
{
ExpandParentItems ( CollectionItem ) ;
2015-05-21 14:47:20 -04:00
}
}
2015-06-19 07:33:02 -04:00
VisibleRootCollectionItems . Sort ( FCollectionItem : : FCompareFCollectionItemByName ( ) ) ;
CollectionTreePtr - > RequestTreeRefresh ( ) ;
2015-05-21 14:47:20 -04:00
}
2015-06-10 13:19:26 -04:00
void SCollectionView : : SetCollectionsSearchFilterText ( const FText & InSearchText )
2015-05-21 14:47:20 -04:00
{
2015-06-10 13:19:26 -04:00
CollectionItemTextFilter - > SetRawFilterText ( InSearchText ) ;
SearchBoxPtr - > SetError ( CollectionItemTextFilter - > GetFilterErrorText ( ) ) ;
}
FText SCollectionView : : GetCollectionsSearchFilterText ( ) const
{
return CollectionItemTextFilter - > GetRawFilterText ( ) ;
2014-03-14 14:13:41 -04:00
}
2015-06-19 07:33:02 -04:00
void SCollectionView : : SetSelectedCollections ( const TArray < FCollectionNameType > & CollectionsToSelect , const bool bEnsureVisible )
2014-03-14 14:13:41 -04:00
{
// Prevent the selection changed delegate since the invoking code requested it
FScopedPreventSelectionChangedDelegate DelegatePrevention ( SharedThis ( this ) ) ;
// Expand the collections area if we are indeed selecting at least one collection
2015-06-19 07:33:02 -04:00
if ( bEnsureVisible & & CollectionsToSelect . Num ( ) > 0 & & CollectionsExpandableAreaPtr . IsValid ( ) )
2014-03-14 14:13:41 -04:00
{
CollectionsExpandableAreaPtr - > SetExpanded ( true ) ;
}
2015-06-19 07:33:02 -04:00
// Clear the selection to start, then add the selected items as they are found
CollectionTreePtr - > ClearSelection ( ) ;
2014-03-14 14:13:41 -04:00
2015-06-19 07:33:02 -04:00
for ( const FCollectionNameType & CollectionToSelect : CollectionsToSelect )
2014-03-14 14:13:41 -04:00
{
2015-06-19 07:33:02 -04:00
TSharedPtr < FCollectionItem > CollectionItemToSelect = AvailableCollections . FindRef ( CollectionToSelect ) ;
if ( CollectionItemToSelect . IsValid ( ) )
2014-03-14 14:13:41 -04:00
{
2015-06-19 07:33:02 -04:00
if ( bEnsureVisible )
2014-03-14 14:13:41 -04:00
{
2015-06-19 07:33:02 -04:00
ExpandParentItems ( CollectionItemToSelect . ToSharedRef ( ) ) ;
CollectionTreePtr - > RequestScrollIntoView ( CollectionItemToSelect ) ;
2014-03-14 14:13:41 -04:00
}
2015-06-19 07:33:02 -04:00
CollectionTreePtr - > SetItemSelection ( CollectionItemToSelect , true ) ;
// If the selected collection doesn't pass our current filter, we need to clear it
if ( bEnsureVisible & & ! CollectionItemTextFilter - > PassesFilter ( FCollectionItem ( CollectionItemToSelect - > CollectionName , CollectionItemToSelect - > CollectionType ) ) )
{
SearchBoxPtr - > SetText ( FText : : GetEmpty ( ) ) ;
}
}
}
}
void SCollectionView : : SetExpandedCollections ( const TArray < FCollectionNameType > & CollectionsToExpand )
{
// Clear the expansion to start, then add the expanded items as they are found
CollectionTreePtr - > ClearExpandedItems ( ) ;
for ( const FCollectionNameType & CollectionToExpand : CollectionsToExpand )
{
TSharedPtr < FCollectionItem > CollectionItemToExpand = AvailableCollections . FindRef ( CollectionToExpand ) ;
if ( CollectionItemToExpand . IsValid ( ) )
{
CollectionTreePtr - > SetItemExpansion ( CollectionItemToExpand , true ) ;
2014-03-14 14:13:41 -04:00
}
}
}
void SCollectionView : : ClearSelection ( )
{
// Prevent the selection changed delegate since the invoking code requested it
FScopedPreventSelectionChangedDelegate DelegatePrevention ( SharedThis ( this ) ) ;
// Clear the selection to start, then add the selected paths as they are found
2015-06-19 07:33:02 -04:00
CollectionTreePtr - > ClearSelection ( ) ;
2014-03-14 14:13:41 -04:00
}
TArray < FCollectionNameType > SCollectionView : : GetSelectedCollections ( ) const
{
TArray < FCollectionNameType > RetArray ;
2015-06-19 07:33:02 -04:00
TArray < TSharedPtr < FCollectionItem > > Items = CollectionTreePtr - > GetSelectedItems ( ) ;
2014-03-14 14:13:41 -04:00
for ( int32 ItemIdx = 0 ; ItemIdx < Items . Num ( ) ; + + ItemIdx )
{
const TSharedPtr < FCollectionItem > & Item = Items [ ItemIdx ] ;
2015-06-01 09:29:31 -04:00
RetArray . Add ( FCollectionNameType ( Item - > CollectionName , Item - > CollectionType ) ) ;
2014-03-14 14:13:41 -04:00
}
return RetArray ;
}
2015-05-29 13:15:40 -04:00
void SCollectionView : : SetSelectedAssets ( const TArray < FAssetData > & SelectedAssets )
{
if ( QuickAssetManagement . IsValid ( ) )
{
QuickAssetManagement - > SetCurrentAssets ( SelectedAssets ) ;
}
}
2015-06-10 13:19:26 -04:00
void SCollectionView : : ApplyHistoryData ( const FHistoryData & History )
2014-03-14 14:13:41 -04:00
{
// Prevent the selection changed delegate because it would add more history when we are just setting a state
FScopedPreventSelectionChangedDelegate DelegatePrevention ( SharedThis ( this ) ) ;
2015-06-19 07:33:02 -04:00
CollectionTreePtr - > ClearSelection ( ) ;
2014-03-14 14:13:41 -04:00
for ( auto HistoryIt = History . SourcesData . Collections . CreateConstIterator ( ) ; HistoryIt ; + + HistoryIt )
{
2015-06-19 07:33:02 -04:00
TSharedPtr < FCollectionItem > CollectionHistoryItem = AvailableCollections . FindRef ( FCollectionNameType ( ( * HistoryIt ) . Name , ( * HistoryIt ) . Type ) ) ;
if ( CollectionHistoryItem . IsValid ( ) )
2014-03-14 14:13:41 -04:00
{
2015-06-19 07:33:02 -04:00
ExpandParentItems ( CollectionHistoryItem . ToSharedRef ( ) ) ;
CollectionTreePtr - > RequestScrollIntoView ( CollectionHistoryItem ) ;
CollectionTreePtr - > SetItemSelection ( CollectionHistoryItem , true ) ;
2014-03-14 14:13:41 -04:00
}
}
}
void SCollectionView : : SaveSettings ( const FString & IniFilename , const FString & IniSection , const FString & SettingsString ) const
{
2015-06-19 07:33:02 -04:00
auto SaveCollectionsArrayToIni = [ & ] ( const FString & InSubKey , const TArray < TSharedPtr < FCollectionItem > > & InCollectionItems )
2014-03-14 14:13:41 -04:00
{
2015-06-19 07:33:02 -04:00
FString CollectionsString ;
for ( const TSharedPtr < FCollectionItem > & CollectionItem : InCollectionItems )
2014-03-14 14:13:41 -04:00
{
2015-06-19 07:33:02 -04:00
if ( CollectionsString . Len ( ) > 0 )
{
CollectionsString + = TEXT ( " , " ) ;
}
CollectionsString + = CollectionItem - > CollectionName . ToString ( ) ;
CollectionsString + = TEXT ( " ? " ) ;
CollectionsString + = FString : : FromInt ( CollectionItem - > CollectionType ) ;
2014-03-14 14:13:41 -04:00
}
2015-06-19 07:33:02 -04:00
GConfig - > SetString ( * IniSection , * ( SettingsString + InSubKey ) , * CollectionsString , IniFilename ) ;
} ;
2014-03-14 14:13:41 -04:00
const bool IsCollectionsExpanded = CollectionsExpandableAreaPtr . IsValid ( ) ? CollectionsExpandableAreaPtr - > IsExpanded ( ) : true ;
GConfig - > SetBool ( * IniSection , * ( SettingsString + TEXT ( " .CollectionsExpanded " ) ) , IsCollectionsExpanded , IniFilename ) ;
2015-06-19 07:33:02 -04:00
SaveCollectionsArrayToIni ( TEXT ( " .SelectedCollections " ) , CollectionTreePtr - > GetSelectedItems ( ) ) ;
{
TSet < TSharedPtr < FCollectionItem > > ExpandedCollectionItems ;
CollectionTreePtr - > GetExpandedItems ( ExpandedCollectionItems ) ;
SaveCollectionsArrayToIni ( TEXT ( " .ExpandedCollections " ) , ExpandedCollectionItems . Array ( ) ) ;
}
2014-03-14 14:13:41 -04:00
}
void SCollectionView : : LoadSettings ( const FString & IniFilename , const FString & IniSection , const FString & SettingsString )
{
2015-06-19 07:33:02 -04:00
auto LoadCollectionsArrayFromIni = [ & ] ( const FString & InSubKey ) - > TArray < FCollectionNameType >
{
TArray < FCollectionNameType > RetCollectionsArray ;
FString CollectionsArrayString ;
if ( GConfig - > GetString ( * IniSection , * ( SettingsString + InSubKey ) , CollectionsArrayString , IniFilename ) )
{
TArray < FString > CollectionStrings ;
CollectionsArrayString . ParseIntoArray ( CollectionStrings , TEXT ( " , " ) , /*bCullEmpty*/ true ) ;
for ( const FString & CollectionString : CollectionStrings )
{
FString CollectionName ;
FString CollectionTypeString ;
if ( CollectionString . Split ( TEXT ( " ? " ) , & CollectionName , & CollectionTypeString ) )
{
const int32 CollectionType = FCString : : Atoi ( * CollectionTypeString ) ;
if ( CollectionType > = 0 & & CollectionType < ECollectionShareType : : CST_All )
{
RetCollectionsArray . Add ( FCollectionNameType ( FName ( * CollectionName ) , ECollectionShareType : : Type ( CollectionType ) ) ) ;
}
}
}
}
return RetCollectionsArray ;
} ;
2014-03-14 14:13:41 -04:00
// Collection expansion state
bool bCollectionsExpanded = false ;
2015-06-19 07:33:02 -04:00
if ( CollectionsExpandableAreaPtr . IsValid ( ) & & GConfig - > GetBool ( * IniSection , * ( SettingsString + TEXT ( " .CollectionsExpanded " ) ) , bCollectionsExpanded , IniFilename ) )
2014-03-14 14:13:41 -04:00
{
CollectionsExpandableAreaPtr - > SetExpanded ( bCollectionsExpanded ) ;
}
// Selected Collections
2015-06-19 07:33:02 -04:00
TArray < FCollectionNameType > NewSelectedCollections = LoadCollectionsArrayFromIni ( TEXT ( " .SelectedCollections " ) ) ;
if ( NewSelectedCollections . Num ( ) > 0 )
2014-03-14 14:13:41 -04:00
{
2015-06-19 07:33:02 -04:00
SetSelectedCollections ( NewSelectedCollections ) ;
2014-03-14 14:13:41 -04:00
2015-06-19 07:33:02 -04:00
const TArray < TSharedPtr < FCollectionItem > > SelectedCollectionItems = CollectionTreePtr - > GetSelectedItems ( ) ;
if ( SelectedCollectionItems . Num ( ) > 0 )
2014-03-14 14:13:41 -04:00
{
2015-06-19 07:33:02 -04:00
CollectionSelectionChanged ( SelectedCollectionItems [ 0 ] , ESelectInfo : : Direct ) ;
2014-03-14 14:13:41 -04:00
}
}
2015-06-19 07:33:02 -04:00
// Expanded Collections
TArray < FCollectionNameType > NewExpandedCollections = LoadCollectionsArrayFromIni ( TEXT ( " .ExpandedCollections " ) ) ;
if ( NewExpandedCollections . Num ( ) > 0 )
2014-03-14 14:13:41 -04:00
{
2015-06-19 07:33:02 -04:00
SetExpandedCollections ( NewExpandedCollections ) ;
2014-03-14 14:13:41 -04:00
}
}
2014-10-30 12:29:36 -04:00
FReply SCollectionView : : OnKeyDown ( const FGeometry & MyGeometry , const FKeyEvent & InKeyEvent )
2014-03-14 14:13:41 -04:00
{
2014-10-30 12:29:36 -04:00
if ( Commands - > ProcessCommandBindings ( InKeyEvent ) )
2014-03-14 14:13:41 -04:00
{
return FReply : : Handled ( ) ;
}
return FReply : : Unhandled ( ) ;
}
2015-06-19 07:33:02 -04:00
void SCollectionView : : OnDragEnter ( const FGeometry & MyGeometry , const FDragDropEvent & DragDropEvent )
{
ValidateDragDropOnCollectionTree ( MyGeometry , DragDropEvent , bDraggedOver ) ; // updates bDraggedOver
}
void SCollectionView : : OnDragLeave ( const FDragDropEvent & DragDropEvent )
{
bDraggedOver = false ;
}
FReply SCollectionView : : OnDragOver ( const FGeometry & MyGeometry , const FDragDropEvent & DragDropEvent )
{
ValidateDragDropOnCollectionTree ( MyGeometry , DragDropEvent , bDraggedOver ) ; // updates bDraggedOver
return ( bDraggedOver ) ? FReply : : Handled ( ) : FReply : : Unhandled ( ) ;
}
FReply SCollectionView : : OnDrop ( const FGeometry & MyGeometry , const FDragDropEvent & DragDropEvent )
{
if ( ValidateDragDropOnCollectionTree ( MyGeometry , DragDropEvent , bDraggedOver ) ) // updates bDraggedOver
{
bDraggedOver = false ;
return HandleDragDropOnCollectionTree ( MyGeometry , DragDropEvent ) ;
}
if ( bDraggedOver )
{
// We were able to handle this operation, but could not due to another error - still report this drop as handled so it doesn't fall through to other widgets
bDraggedOver = false ;
return FReply : : Handled ( ) ;
}
return FReply : : Unhandled ( ) ;
}
2014-03-14 14:13:41 -04:00
bool SCollectionView : : ShouldAllowSelectionChangedDelegate ( ) const
{
return PreventSelectionChangedDelegateCount = = 0 ;
}
FReply SCollectionView : : MakeAddCollectionMenu ( )
{
// Get all menu extenders for this context menu from the content browser module
FContentBrowserModule & ContentBrowserModule = FModuleManager : : GetModuleChecked < FContentBrowserModule > ( TEXT ( " ContentBrowser " ) ) ;
TArray < FContentBrowserMenuExtender > MenuExtenderDelegates = ContentBrowserModule . GetAllCollectionViewContextMenuExtenders ( ) ;
TArray < TSharedPtr < FExtender > > Extenders ;
for ( int32 i = 0 ; i < MenuExtenderDelegates . Num ( ) ; + + i )
{
if ( MenuExtenderDelegates [ i ] . IsBound ( ) )
{
Extenders . Add ( MenuExtenderDelegates [ i ] . Execute ( ) ) ;
}
}
TSharedPtr < FExtender > MenuExtender = FExtender : : Combine ( Extenders ) ;
FMenuBuilder MenuBuilder ( /*bInShouldCloseWindowAfterMenuSelection=*/ true , NULL , MenuExtender , true ) ;
CollectionContextMenu - > UpdateProjectSourceControl ( ) ;
CollectionContextMenu - > MakeNewCollectionSubMenu ( MenuBuilder ) ;
FSlateApplication : : Get ( ) . PushMenu (
AsShared ( ) ,
2015-06-05 20:19:33 -04:00
FWidgetPath ( ) ,
2014-03-14 14:13:41 -04:00
MenuBuilder . MakeWidget ( ) ,
FSlateApplication : : Get ( ) . GetCursorPos ( ) ,
FPopupTransitionEffect ( FPopupTransitionEffect : : TopMenu )
) ;
return FReply : : Handled ( ) ;
}
2015-05-26 10:11:32 -04:00
EVisibility SCollectionView : : GetCollectionsTitleTextVisibility ( ) const
{
// Only show the title text if we have an expansion area, but are collapsed
return ( CollectionsExpandableAreaPtr . IsValid ( ) & & ! CollectionsExpandableAreaPtr - > IsExpanded ( ) ) ? EVisibility : : Visible : EVisibility : : Collapsed ;
}
EVisibility SCollectionView : : GetCollectionsSearchBoxVisibility ( ) const
{
// Only show the search box if we have an expanded expansion area, or aren't currently using an expansion area
return ( ! CollectionsExpandableAreaPtr . IsValid ( ) | | CollectionsExpandableAreaPtr - > IsExpanded ( ) ) ? EVisibility : : Visible : EVisibility : : Collapsed ;
}
2014-03-14 14:13:41 -04:00
EVisibility SCollectionView : : GetAddCollectionButtonVisibility ( ) const
{
return ( bAllowCollectionButtons & & ( ! CollectionsExpandableAreaPtr . IsValid ( ) | | CollectionsExpandableAreaPtr - > IsExpanded ( ) ) ) ? EVisibility : : Visible : EVisibility : : Collapsed ;
}
void SCollectionView : : CreateCollectionItem ( ECollectionShareType : : Type CollectionType )
{
if ( ensure ( CollectionType ! = ECollectionShareType : : CST_All ) )
{
2015-06-01 10:04:42 -04:00
FCollectionManagerModule & CollectionManagerModule = FCollectionManagerModule : : GetModule ( ) ;
2014-03-14 14:13:41 -04:00
const FName BaseCollectionName = * LOCTEXT ( " NewCollectionName " , " NewCollection " ) . ToString ( ) ;
FName CollectionName ;
CollectionManagerModule . Get ( ) . CreateUniqueCollectionName ( BaseCollectionName , CollectionType , CollectionName ) ;
2015-06-01 09:29:31 -04:00
TSharedPtr < FCollectionItem > NewItem = MakeShareable ( new FCollectionItem ( CollectionName , CollectionType ) ) ;
2014-03-14 14:13:41 -04:00
2015-05-21 14:47:20 -04:00
// Adding a new collection now, so clear any filter we may have applied
SearchBoxPtr - > SetText ( FText : : GetEmpty ( ) ) ;
2014-03-14 14:13:41 -04:00
// Mark the new collection for rename and that it is new so it will be created upon successful rename
NewItem - > bRenaming = true ;
NewItem - > bNewCollection = true ;
2015-06-19 07:33:02 -04:00
AvailableCollections . Add ( FCollectionNameType ( NewItem - > CollectionName , NewItem - > CollectionType ) , NewItem ) ;
2015-06-10 13:19:26 -04:00
UpdateFilteredCollectionItems ( ) ;
2015-06-19 07:33:02 -04:00
CollectionTreePtr - > RequestScrollIntoView ( NewItem ) ;
CollectionTreePtr - > SetSelection ( NewItem ) ;
2014-03-14 14:13:41 -04:00
}
}
void SCollectionView : : RenameCollectionItem ( const TSharedPtr < FCollectionItem > & ItemToRename )
{
if ( ensure ( ItemToRename . IsValid ( ) ) )
{
ItemToRename - > bRenaming = true ;
2015-06-19 07:33:02 -04:00
CollectionTreePtr - > RequestScrollIntoView ( ItemToRename ) ;
2014-03-14 14:13:41 -04:00
}
}
2015-06-19 07:33:02 -04:00
void SCollectionView : : DeleteCollectionItems ( const TArray < TSharedPtr < FCollectionItem > > & ItemsToDelete )
2014-03-14 14:13:41 -04:00
{
2015-06-19 07:33:02 -04:00
if ( ItemsToDelete . Num ( ) = = 0 )
2014-03-14 14:13:41 -04:00
{
2015-06-19 07:33:02 -04:00
return ;
}
2014-03-14 14:13:41 -04:00
2015-06-19 07:33:02 -04:00
// Before we delete anything (as this will trigger a tree update) we need to work out what our new selection should be in the case that
// all of the selected items are removed
const TArray < TSharedPtr < FCollectionItem > > PreviouslySelectedItems = CollectionTreePtr - > GetSelectedItems ( ) ;
// Get the first selected item that will be deleted so we can find a suitable new selection
TSharedPtr < FCollectionItem > FirstSelectedItemDeleted ;
for ( const auto & ItemToDelete : ItemsToDelete )
{
if ( PreviouslySelectedItems . Contains ( ItemToDelete ) )
2014-03-14 14:13:41 -04:00
{
2015-06-19 07:33:02 -04:00
FirstSelectedItemDeleted = ItemToDelete ;
break ;
2014-03-14 14:13:41 -04:00
}
}
2015-06-19 07:33:02 -04:00
// Build up an array of potential new selections (in the case that we're deleting everything that's selected)
// Earlier items should be considered first, we base this list on the first selected item that will be deleted, and include previous siblings, and then all parents and roots
TArray < FCollectionNameType > PotentialNewSelections ;
if ( FirstSelectedItemDeleted . IsValid ( ) )
2014-03-14 14:13:41 -04:00
{
2015-06-19 07:33:02 -04:00
TSharedPtr < FCollectionItem > RootSelectedItemDeleted = FirstSelectedItemDeleted ;
TSharedPtr < FCollectionItem > ParentCollectionItem = FirstSelectedItemDeleted - > ParentCollection . Pin ( ) ;
if ( ParentCollectionItem . IsValid ( ) )
{
// Add all the siblings until we find the item that will be deleted
for ( const auto & ChildItemWeakPtr : ParentCollectionItem - > ChildCollections )
{
TSharedPtr < FCollectionItem > ChildItem = ChildItemWeakPtr . Pin ( ) ;
if ( ChildItem . IsValid ( ) )
{
if ( ChildItem = = FirstSelectedItemDeleted )
{
break ;
}
// We add siblings as the start, as the closest sibling should be the first match
PotentialNewSelections . Insert ( FCollectionNameType ( ChildItem - > CollectionName , ChildItem - > CollectionType ) , 0 ) ;
}
}
// Now add this parent, and all other parents too
do
{
PotentialNewSelections . Add ( FCollectionNameType ( ParentCollectionItem - > CollectionName , ParentCollectionItem - > CollectionType ) ) ;
RootSelectedItemDeleted = ParentCollectionItem ;
ParentCollectionItem = ParentCollectionItem - > ParentCollection . Pin ( ) ;
}
while ( ParentCollectionItem . IsValid ( ) ) ;
}
if ( RootSelectedItemDeleted . IsValid ( ) )
{
// Add all the root level items before this one
const int32 InsertionPoint = PotentialNewSelections . Num ( ) ;
for ( const auto & RootItem : VisibleRootCollectionItems )
{
if ( RootItem = = RootSelectedItemDeleted )
{
break ;
}
// Add each root item at the insertion point, as the closest item should be a better match
PotentialNewSelections . Insert ( FCollectionNameType ( RootItem - > CollectionName , RootItem - > CollectionType ) , InsertionPoint ) ;
}
}
2014-03-14 14:13:41 -04:00
}
2015-06-19 07:33:02 -04:00
// Delete all given collections
int32 NumSelectedItemsDeleted = 0 ;
FCollectionManagerModule & CollectionManagerModule = FCollectionManagerModule : : GetModule ( ) ;
for ( const TSharedPtr < FCollectionItem > & ItemToDelete : ItemsToDelete )
{
if ( CollectionManagerModule . Get ( ) . DestroyCollection ( ItemToDelete - > CollectionName , ItemToDelete - > CollectionType ) )
{
if ( PreviouslySelectedItems . Contains ( ItemToDelete ) )
{
+ + NumSelectedItemsDeleted ;
}
}
else
{
// Display a warning
const FVector2D & CursorPos = FSlateApplication : : Get ( ) . GetCursorPos ( ) ;
FSlateRect MessageAnchor ( CursorPos . X , CursorPos . Y , CursorPos . X , CursorPos . Y ) ;
ContentBrowserUtils : : DisplayMessage (
FText : : Format ( LOCTEXT ( " CollectionDestroyFailed " , " Failed to destroy collection. {0} " ) , CollectionManagerModule . Get ( ) . GetLastError ( ) ) ,
MessageAnchor ,
CollectionTreePtr . ToSharedRef ( )
) ;
}
}
// DestroyCollection will have triggered a notification that will have updated the tree, we now need to apply a suitable selection...
// Did this delete change the list of selected items?
if ( NumSelectedItemsDeleted > 0 | | PreviouslySelectedItems . Num ( ) = = 0 )
{
// If we removed everything that was selected, we need to try and find a suitable replacement...
if ( NumSelectedItemsDeleted > = PreviouslySelectedItems . Num ( ) & & VisibleCollections . Num ( ) > 1 )
{
// Include the first visible item as an absolute last resort should everything else suitable have been removed from the tree
PotentialNewSelections . Add ( * VisibleCollections . CreateConstIterator ( ) ) ;
// Check the potential new selections array and try and select the first one that's still visible in the tree
TArray < FCollectionNameType > NewItemSelection ;
for ( const FCollectionNameType & PotentialNewSelection : PotentialNewSelections )
{
if ( VisibleCollections . Contains ( PotentialNewSelection ) )
{
NewItemSelection . Add ( PotentialNewSelection ) ;
break ;
}
}
SetSelectedCollections ( NewItemSelection , true ) ;
}
// Broadcast the new selection
const TArray < TSharedPtr < FCollectionItem > > UpdatedSelectedItems = CollectionTreePtr - > GetSelectedItems ( ) ;
CollectionSelectionChanged ( ( UpdatedSelectedItems . Num ( ) > 0 ) ? UpdatedSelectedItems [ 0 ] : nullptr , ESelectInfo : : Direct ) ;
}
2014-03-14 14:13:41 -04:00
}
2015-06-19 07:33:02 -04:00
EVisibility SCollectionView : : GetCollectionTreeVisibility ( ) const
2014-03-14 14:13:41 -04:00
{
2015-06-19 07:33:02 -04:00
return AvailableCollections . Num ( ) > 0 ? EVisibility : : Visible : EVisibility : : Collapsed ;
}
const FSlateBrush * SCollectionView : : GetCollectionViewDropTargetBorder ( ) const
{
return bDraggedOver ? FEditorStyle : : GetBrush ( " ContentBrowser.CollectionTreeDragDropBorder " ) : FEditorStyle : : GetBrush ( " NoBorder " ) ;
2014-03-14 14:13:41 -04:00
}
TSharedRef < ITableRow > SCollectionView : : GenerateCollectionRow ( TSharedPtr < FCollectionItem > CollectionItem , const TSharedRef < STableViewBase > & OwnerTable )
{
check ( CollectionItem . IsValid ( ) ) ;
2015-05-29 13:15:40 -04:00
// Only bind the check box callbacks if we're allowed to show check boxes
TAttribute < bool > IsCollectionCheckBoxEnabledAttribute ;
TAttribute < ECheckBoxState > IsCollectionCheckedAttribute ;
FOnCheckStateChanged OnCollectionCheckStateChangedDelegate ;
if ( QuickAssetManagement . IsValid ( ) )
{
IsCollectionCheckBoxEnabledAttribute . Bind ( TAttribute < bool > : : FGetter : : CreateSP ( this , & SCollectionView : : IsCollectionCheckBoxEnabled , CollectionItem ) ) ;
IsCollectionCheckedAttribute . Bind ( TAttribute < ECheckBoxState > : : FGetter : : CreateSP ( this , & SCollectionView : : IsCollectionChecked , CollectionItem ) ) ;
OnCollectionCheckStateChangedDelegate . BindSP ( this , & SCollectionView : : OnCollectionCheckStateChanged , CollectionItem ) ;
}
2015-06-19 07:33:02 -04:00
TSharedPtr < STableRow < TSharedPtr < FCollectionItem > > > TableRow = SNew ( STableRow < TSharedPtr < FCollectionItem > > , OwnerTable )
. OnDragDetected ( this , & SCollectionView : : OnCollectionDragDetected ) ;
2014-03-14 14:13:41 -04:00
TableRow - > SetContent
(
2015-06-19 07:33:02 -04:00
SNew ( SCollectionTreeItem )
2014-03-14 14:13:41 -04:00
. ParentWidget ( SharedThis ( this ) )
. CollectionItem ( CollectionItem )
. OnNameChangeCommit ( this , & SCollectionView : : CollectionNameChangeCommit )
. OnVerifyRenameCommit ( this , & SCollectionView : : CollectionVerifyRenameCommit )
2015-06-19 07:33:02 -04:00
. OnValidateDragDrop ( this , & SCollectionView : : ValidateDragDropOnCollectionItem )
. OnHandleDragDrop ( this , & SCollectionView : : HandleDragDropOnCollectionItem )
. IsSelected ( TableRow . Get ( ) , & STableRow < TSharedPtr < FCollectionItem > > : : IsSelectedExclusively )
. IsReadOnly ( this , & SCollectionView : : IsCollectionNameReadOnly )
. HighlightText ( this , & SCollectionView : : GetCollectionsSearchFilterText )
. IsCheckBoxEnabled ( IsCollectionCheckBoxEnabledAttribute )
. IsCollectionChecked ( IsCollectionCheckedAttribute )
. OnCollectionCheckStateChanged ( OnCollectionCheckStateChangedDelegate )
2014-03-14 14:13:41 -04:00
) ;
return TableRow . ToSharedRef ( ) ;
}
2015-06-19 07:33:02 -04:00
void SCollectionView : : GetCollectionItemChildren ( TSharedPtr < FCollectionItem > InParentItem , TArray < TSharedPtr < FCollectionItem > > & OutChildItems ) const
{
for ( const auto & ChildItemWeakPtr : InParentItem - > ChildCollections )
{
TSharedPtr < FCollectionItem > ChildItem = ChildItemWeakPtr . Pin ( ) ;
if ( ChildItem . IsValid ( ) & & VisibleCollections . Contains ( FCollectionNameType ( ChildItem - > CollectionName , ChildItem - > CollectionType ) ) )
{
OutChildItems . Add ( ChildItem ) ;
}
}
OutChildItems . Sort ( FCollectionItem : : FCompareFCollectionItemByName ( ) ) ;
}
FReply SCollectionView : : OnCollectionDragDetected ( const FGeometry & Geometry , const FPointerEvent & MouseEvent )
{
if ( bAllowCollectionDrag & & MouseEvent . IsMouseButtonDown ( EKeys : : LeftMouseButton ) )
{
const TArray < FCollectionNameType > SelectedCollections = GetSelectedCollections ( ) ;
if ( SelectedCollections . Num ( ) > 0 )
{
TSharedRef < FCollectionDragDropOp > DragDropOp = FCollectionDragDropOp : : New ( SelectedCollections ) ;
CurrentCollectionDragDropOp = DragDropOp ;
return FReply : : Handled ( ) . BeginDragDrop ( DragDropOp ) ;
}
}
return FReply : : Unhandled ( ) ;
}
bool SCollectionView : : ValidateDragDropOnCollectionTree ( const FGeometry & Geometry , const FDragDropEvent & DragDropEvent , bool & OutIsKnownDragOperation )
{
OutIsKnownDragOperation = false ;
TSharedPtr < FDragDropOperation > Operation = DragDropEvent . GetOperation ( ) ;
if ( ! Operation . IsValid ( ) )
{
return false ;
}
if ( Operation - > IsOfType < FCollectionDragDropOp > ( ) )
{
OutIsKnownDragOperation = true ;
return true ;
}
return false ;
}
FReply SCollectionView : : HandleDragDropOnCollectionTree ( const FGeometry & Geometry , const FDragDropEvent & DragDropEvent )
{
// Should have already called ValidateDragDropOnCollectionTree prior to calling this...
TSharedPtr < FDragDropOperation > Operation = DragDropEvent . GetOperation ( ) ;
check ( Operation . IsValid ( ) ) ;
FCollectionManagerModule & CollectionManagerModule = FCollectionManagerModule : : GetModule ( ) ;
if ( Operation - > IsOfType < FCollectionDragDropOp > ( ) )
{
TSharedPtr < FCollectionDragDropOp > DragDropOp = StaticCastSharedPtr < FCollectionDragDropOp > ( Operation ) ;
// Reparent all of the collections in the drag drop so that they are root level items
for ( const FCollectionNameType & NewChildCollection : DragDropOp - > Collections )
{
if ( ! CollectionManagerModule . Get ( ) . ReparentCollection (
NewChildCollection . Name , NewChildCollection . Type ,
NAME_None , ECollectionShareType : : CST_All
) )
{
ContentBrowserUtils : : DisplayMessage ( CollectionManagerModule . Get ( ) . GetLastError ( ) , Geometry . GetClippingRect ( ) , SharedThis ( this ) ) ;
}
}
return FReply : : Handled ( ) ;
}
return FReply : : Unhandled ( ) ;
}
bool SCollectionView : : ValidateDragDropOnCollectionItem ( TSharedRef < FCollectionItem > CollectionItem , const FGeometry & Geometry , const FDragDropEvent & DragDropEvent , bool & OutIsKnownDragOperation )
{
OutIsKnownDragOperation = false ;
TSharedPtr < FDragDropOperation > Operation = DragDropEvent . GetOperation ( ) ;
if ( ! Operation . IsValid ( ) )
{
return false ;
}
bool bIsValidDrag = false ;
TOptional < EMouseCursor : : Type > NewDragCursor ;
if ( Operation - > IsOfType < FCollectionDragDropOp > ( ) )
{
TSharedPtr < FCollectionDragDropOp > DragDropOp = StaticCastSharedPtr < FCollectionDragDropOp > ( Operation ) ;
OutIsKnownDragOperation = true ;
FCollectionManagerModule & CollectionManagerModule = FCollectionManagerModule : : GetModule ( ) ;
bIsValidDrag = true ;
for ( const FCollectionNameType & PotentialChildCollection : DragDropOp - > Collections )
{
bIsValidDrag = CollectionManagerModule . Get ( ) . IsValidParentCollection (
PotentialChildCollection . Name , PotentialChildCollection . Type ,
CollectionItem - > CollectionName , CollectionItem - > CollectionType
) ;
if ( ! bIsValidDrag )
{
DragDropOp - > SetToolTip ( CollectionManagerModule . Get ( ) . GetLastError ( ) , FEditorStyle : : GetBrush ( TEXT ( " Graph.ConnectorFeedback.Error " ) ) ) ;
break ;
}
}
// If we are dragging over a child collection item, then this view as a whole should not be marked as dragged over
bDraggedOver = false ;
}
else if ( Operation - > IsOfType < FAssetDragDropOp > ( ) )
{
TSharedPtr < FAssetDragDropOp > DragDropOp = StaticCastSharedPtr < FAssetDragDropOp > ( Operation ) ;
OutIsKnownDragOperation = true ;
bIsValidDrag = DragDropOp - > AssetData . Num ( ) > 0 ;
}
// Set the default slashed circle if this drag is invalid and a drag operation hasn't set NewDragCursor to something custom
if ( ! bIsValidDrag & & ! NewDragCursor . IsSet ( ) )
{
NewDragCursor = EMouseCursor : : SlashedCircle ;
}
Operation - > SetCursorOverride ( NewDragCursor ) ;
return bIsValidDrag ;
}
FReply SCollectionView : : HandleDragDropOnCollectionItem ( TSharedRef < FCollectionItem > CollectionItem , const FGeometry & Geometry , const FDragDropEvent & DragDropEvent )
{
// Should have already called ValidateDragDropOnCollectionItem prior to calling this...
TSharedPtr < FDragDropOperation > Operation = DragDropEvent . GetOperation ( ) ;
check ( Operation . IsValid ( ) ) ;
FCollectionManagerModule & CollectionManagerModule = FCollectionManagerModule : : GetModule ( ) ;
if ( Operation - > IsOfType < FCollectionDragDropOp > ( ) )
{
TSharedPtr < FCollectionDragDropOp > DragDropOp = StaticCastSharedPtr < FCollectionDragDropOp > ( Operation ) ;
// Make sure our drop item is marked as expanded so that we'll be able to see the newly added children
CollectionTreePtr - > SetItemExpansion ( CollectionItem , true ) ;
// Reparent all of the collections in the drag drop so that they are our immediate children
for ( const FCollectionNameType & NewChildCollection : DragDropOp - > Collections )
{
if ( ! CollectionManagerModule . Get ( ) . ReparentCollection (
NewChildCollection . Name , NewChildCollection . Type ,
CollectionItem - > CollectionName , CollectionItem - > CollectionType
) )
{
ContentBrowserUtils : : DisplayMessage ( CollectionManagerModule . Get ( ) . GetLastError ( ) , Geometry . GetClippingRect ( ) , SharedThis ( this ) ) ;
}
}
return FReply : : Handled ( ) ;
}
else if ( Operation - > IsOfType < FAssetDragDropOp > ( ) )
{
TSharedPtr < FAssetDragDropOp > DragDropOp = StaticCastSharedPtr < FAssetDragDropOp > ( Operation ) ;
TArray < FName > ObjectPaths ;
ObjectPaths . Reserve ( DragDropOp - > AssetData . Num ( ) ) ;
for ( const FAssetData & AssetData : DragDropOp - > AssetData )
{
ObjectPaths . Add ( AssetData . ObjectPath ) ;
}
int32 NumAdded = 0 ;
FText Message ;
if ( CollectionManagerModule . Get ( ) . AddToCollection ( CollectionItem - > CollectionName , CollectionItem - > CollectionType , ObjectPaths , & NumAdded ) )
{
if ( DragDropOp - > AssetData . Num ( ) = = 1 )
{
FFormatNamedArguments Args ;
Args . Add ( TEXT ( " AssetName " ) , FText : : FromName ( DragDropOp - > AssetData [ 0 ] . AssetName ) ) ;
Args . Add ( TEXT ( " CollectionName " ) , FText : : FromName ( CollectionItem - > CollectionName ) ) ;
Message = FText : : Format ( LOCTEXT ( " CollectionAssetsAdded " , " Added {AssetName} to {CollectionName} " ) , Args ) ;
}
else
{
FFormatNamedArguments Args ;
Args . Add ( TEXT ( " Number " ) , NumAdded ) ;
Args . Add ( TEXT ( " CollectionName " ) , FText : : FromName ( CollectionItem - > CollectionName ) ) ;
Message = FText : : Format ( LOCTEXT ( " CollectionAssetsAdded " , " Added {Number} asset(s) to {CollectionName} " ) , Args ) ;
}
}
else
{
Message = CollectionManagerModule . Get ( ) . GetLastError ( ) ;
}
// Added items to the collection or failed. Either way, display the message.
ContentBrowserUtils : : DisplayMessage ( Message , Geometry . GetClippingRect ( ) , SharedThis ( this ) ) ;
return FReply : : Handled ( ) ;
}
return FReply : : Unhandled ( ) ;
}
void SCollectionView : : ExpandParentItems ( const TSharedRef < FCollectionItem > & InCollectionItem )
{
for ( TSharedPtr < FCollectionItem > CollectionItemToExpand = InCollectionItem - > ParentCollection . Pin ( ) ;
CollectionItemToExpand . IsValid ( ) ;
CollectionItemToExpand = CollectionItemToExpand - > ParentCollection . Pin ( )
)
{
CollectionTreePtr - > SetItemExpansion ( CollectionItemToExpand , true ) ;
}
}
TSharedPtr < SWidget > SCollectionView : : MakeCollectionTreeContextMenu ( )
2014-03-14 14:13:41 -04:00
{
if ( ! bAllowRightClickMenu )
{
return NULL ;
}
2015-06-19 07:33:02 -04:00
return CollectionContextMenu - > MakeCollectionTreeContextMenu ( Commands ) ;
2014-03-14 14:13:41 -04:00
}
2015-05-29 13:15:40 -04:00
bool SCollectionView : : IsCollectionCheckBoxEnabled ( TSharedPtr < FCollectionItem > CollectionItem ) const
{
2015-06-01 09:29:31 -04:00
return QuickAssetManagement . IsValid ( ) & & QuickAssetManagement - > IsCollectionEnabled ( FCollectionNameType ( CollectionItem - > CollectionName , CollectionItem - > CollectionType ) ) ;
2015-05-29 13:15:40 -04:00
}
ECheckBoxState SCollectionView : : IsCollectionChecked ( TSharedPtr < FCollectionItem > CollectionItem ) const
{
if ( QuickAssetManagement . IsValid ( ) )
{
2015-06-01 09:29:31 -04:00
return QuickAssetManagement - > GetCollectionCheckState ( FCollectionNameType ( CollectionItem - > CollectionName , CollectionItem - > CollectionType ) ) ;
2015-05-29 13:15:40 -04:00
}
return ECheckBoxState : : Unchecked ;
}
void SCollectionView : : OnCollectionCheckStateChanged ( ECheckBoxState NewState , TSharedPtr < FCollectionItem > CollectionItem )
{
if ( QuickAssetManagement . IsValid ( ) )
{
switch ( NewState )
{
case ECheckBoxState : : Checked :
2015-06-01 09:29:31 -04:00
QuickAssetManagement - > AddCurrentAssetsToCollection ( FCollectionNameType ( CollectionItem - > CollectionName , CollectionItem - > CollectionType ) ) ;
2015-05-29 13:15:40 -04:00
break ;
case ECheckBoxState : : Unchecked :
2015-06-01 09:29:31 -04:00
QuickAssetManagement - > RemoveCurrentAssetsFromCollection ( FCollectionNameType ( CollectionItem - > CollectionName , CollectionItem - > CollectionType ) ) ;
2015-05-29 13:15:40 -04:00
break ;
default :
break ;
}
}
}
2014-03-14 14:13:41 -04:00
void SCollectionView : : CollectionSelectionChanged ( TSharedPtr < FCollectionItem > CollectionItem , ESelectInfo : : Type /*SelectInfo*/ )
{
if ( ShouldAllowSelectionChangedDelegate ( ) & & OnCollectionSelected . IsBound ( ) )
{
if ( CollectionItem . IsValid ( ) )
{
2015-06-01 09:29:31 -04:00
OnCollectionSelected . Execute ( FCollectionNameType ( CollectionItem - > CollectionName , CollectionItem - > CollectionType ) ) ;
2014-03-14 14:13:41 -04:00
}
else
{
OnCollectionSelected . Execute ( FCollectionNameType ( NAME_None , ECollectionShareType : : CST_All ) ) ;
}
}
}
void SCollectionView : : CollectionItemScrolledIntoView ( TSharedPtr < FCollectionItem > CollectionItem , const TSharedPtr < ITableRow > & Widget )
{
if ( CollectionItem - > bRenaming & & Widget . IsValid ( ) & & Widget - > GetContent ( ) . IsValid ( ) )
{
CollectionItem - > OnRenamedRequestEvent . Broadcast ( ) ;
}
}
2015-06-19 07:33:02 -04:00
bool SCollectionView : : IsCollectionNameReadOnly ( ) const
2014-03-14 14:13:41 -04:00
{
2015-06-19 07:33:02 -04:00
// We can't rename collections while they're being dragged
TSharedPtr < FCollectionDragDropOp > DragDropOp = CurrentCollectionDragDropOp . Pin ( ) ;
if ( DragDropOp . IsValid ( ) )
{
TArray < TSharedPtr < FCollectionItem > > SelectedCollectionItems = CollectionTreePtr - > GetSelectedItems ( ) ;
for ( const auto & SelectedCollectionItem : SelectedCollectionItems )
{
if ( DragDropOp - > Collections . Contains ( FCollectionNameType ( SelectedCollectionItem - > CollectionName , SelectedCollectionItem - > CollectionType ) ) )
{
return true ;
}
}
}
2014-03-14 14:13:41 -04:00
CollectionContextMenu - > UpdateProjectSourceControl ( ) ;
2014-04-23 18:13:40 -04:00
return ! CollectionContextMenu - > CanRenameSelectedCollections ( ) ;
2014-03-14 14:13:41 -04:00
}
bool SCollectionView : : CollectionNameChangeCommit ( const TSharedPtr < FCollectionItem > & CollectionItem , const FString & NewName , bool bChangeConfirmed , FText & OutWarningMessage )
{
// There should only ever be one item selected when renaming
2015-06-19 07:33:02 -04:00
check ( CollectionTreePtr - > GetNumItemsSelected ( ) = = 1 ) ;
2014-03-14 14:13:41 -04:00
2015-06-01 10:04:42 -04:00
FCollectionManagerModule & CollectionManagerModule = FCollectionManagerModule : : GetModule ( ) ;
2014-03-14 14:13:41 -04:00
ECollectionShareType : : Type CollectionType = CollectionItem - > CollectionType ;
// If new name is empty, set it back to the original name
2015-06-01 09:29:31 -04:00
const FName NewNameFinal ( NewName . IsEmpty ( ) ? CollectionItem - > CollectionName : FName ( * NewName ) ) ;
2014-03-14 14:13:41 -04:00
if ( CollectionItem - > bNewCollection )
{
CollectionItem - > bNewCollection = false ;
// If we can canceled the name change when creating a new asset, we want to silently remove it
if ( ! bChangeConfirmed )
{
2015-06-19 07:33:02 -04:00
AvailableCollections . Remove ( FCollectionNameType ( CollectionItem - > CollectionName , CollectionItem - > CollectionType ) ) ;
2015-06-10 13:19:26 -04:00
UpdateFilteredCollectionItems ( ) ;
2014-03-14 14:13:41 -04:00
return false ;
}
2015-06-01 09:29:31 -04:00
if ( ! CollectionManagerModule . Get ( ) . CreateCollection ( NewNameFinal , CollectionType ) )
2014-03-14 14:13:41 -04:00
{
// Failed to add the collection, remove it from the list
2015-06-19 07:33:02 -04:00
AvailableCollections . Remove ( FCollectionNameType ( CollectionItem - > CollectionName , CollectionItem - > CollectionType ) ) ;
2015-06-10 13:19:26 -04:00
UpdateFilteredCollectionItems ( ) ;
2014-03-14 14:13:41 -04:00
OutWarningMessage = FText : : Format ( LOCTEXT ( " CreateCollectionFailed " , " Failed to create the collection. {0} " ) , CollectionManagerModule . Get ( ) . GetLastError ( ) ) ;
return false ;
}
}
else
{
// If the old name is the same as the new name, just early exit here.
if ( CollectionItem - > CollectionName = = NewNameFinal )
{
return true ;
}
2015-05-21 14:47:20 -04:00
// If the new name doesn't pass our current filter, we need to clear it
2015-06-10 13:19:26 -04:00
if ( ! CollectionItemTextFilter - > PassesFilter ( FCollectionItem ( NewNameFinal , CollectionType ) ) )
2015-05-21 14:47:20 -04:00
{
SearchBoxPtr - > SetText ( FText : : GetEmpty ( ) ) ;
}
2014-03-14 14:13:41 -04:00
// Otherwise perform the rename
2015-06-01 09:29:31 -04:00
if ( ! CollectionManagerModule . Get ( ) . RenameCollection ( CollectionItem - > CollectionName , CollectionType , NewNameFinal , CollectionType ) )
2014-03-14 14:13:41 -04:00
{
// Failed to rename the collection
OutWarningMessage = FText : : Format ( LOCTEXT ( " RenameCollectionFailed " , " Failed to rename the collection. {0} " ) , CollectionManagerModule . Get ( ) . GetLastError ( ) ) ;
return false ;
}
}
// At this point CollectionItem is no longer a member of the CollectionItems list (as the list is repopulated by
// UpdateCollectionItems, which is called by a broadcast from CollectionManagerModule::RenameCollection, above).
// So search again for the item by name and type.
2015-06-19 07:33:02 -04:00
auto NewCollectionItemPtr = AvailableCollections . Find ( FCollectionNameType ( NewNameFinal , CollectionType ) ) ;
2014-03-14 14:13:41 -04:00
// Reselect the path to notify that the selection has changed
{
FScopedPreventSelectionChangedDelegate DelegatePrevention ( SharedThis ( this ) ) ;
2015-06-19 07:33:02 -04:00
CollectionTreePtr - > ClearSelection ( ) ;
2014-03-14 14:13:41 -04:00
}
// Set the selection
if ( NewCollectionItemPtr )
{
const auto & NewCollectionItem = * NewCollectionItemPtr ;
2015-06-19 07:33:02 -04:00
CollectionTreePtr - > RequestScrollIntoView ( NewCollectionItem ) ;
CollectionTreePtr - > SetItemSelection ( NewCollectionItem , true ) ;
2014-03-14 14:13:41 -04:00
}
return true ;
}
bool SCollectionView : : CollectionVerifyRenameCommit ( const TSharedPtr < FCollectionItem > & CollectionItem , const FString & NewName , const FSlateRect & MessageAnchor , FText & OutErrorMessage )
{
2015-06-01 09:29:31 -04:00
const FName NewNameFinal = * NewName ;
2014-03-14 14:13:41 -04:00
// If the new name is the same as the old name, consider this to be unchanged, and accept it.
2015-06-01 09:29:31 -04:00
if ( CollectionItem - > CollectionName = = NewNameFinal )
2014-03-14 14:13:41 -04:00
{
return true ;
}
2015-06-01 10:04:42 -04:00
FCollectionManagerModule & CollectionManagerModule = FCollectionManagerModule : : GetModule ( ) ;
2014-03-14 14:13:41 -04:00
2015-06-01 09:29:31 -04:00
if ( CollectionManagerModule . Get ( ) . CollectionExists ( NewNameFinal , ECollectionShareType : : CST_All ) )
2014-03-14 14:13:41 -04:00
{
// This collection already exists, inform the user and continue
2015-06-01 09:29:31 -04:00
OutErrorMessage = FText : : Format ( LOCTEXT ( " RenameCollectionAlreadyExists " , " A collection already exists with the name '{0}'. " ) , FText : : FromName ( NewNameFinal ) ) ;
2014-03-14 14:13:41 -04:00
// Return false to indicate that the user should enter a new name
return false ;
}
return true ;
}
# undef LOCTEXT_NAMESPACE