2014-08-21 20:30:51 -04:00
// Copyright 1998-2014 Epic Games, Inc. All Rights Reserved.
# include "ContentBrowserPCH.h"
# include "SAssetDialog.h"
# define LOCTEXT_NAMESPACE "ContentBrowser"
2014-09-01 13:25:23 -04:00
SAssetDialog : : SAssetDialog ( )
: DialogType ( EAssetDialogType : : Open )
, ExistingAssetPolicy ( ESaveAssetDialogExistingAssetPolicy : : Disallow )
, bLastInputValidityCheckSuccessful ( false )
2014-09-15 21:28:40 -04:00
, bPendingFocusNextFrame ( true )
2014-09-01 13:25:23 -04:00
{
}
2014-08-21 20:30:51 -04:00
BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION
void SAssetDialog : : Construct ( const FArguments & InArgs , const FSharedAssetDialogConfig & InConfig )
{
DialogType = InConfig . GetDialogType ( ) ;
AssetClassNames = InConfig . AssetClassNames ;
const FString DefaultPath = InConfig . DefaultPath ;
FPathPickerConfig PathPickerConfig ;
PathPickerConfig . DefaultPath = DefaultPath ;
PathPickerConfig . bFocusSearchBoxWhenOpened = false ;
PathPickerConfig . OnPathSelected = FOnPathSelected : : CreateSP ( this , & SAssetDialog : : HandlePathSelected ) ;
2014-09-15 20:43:33 -04:00
PathPickerConfig . SetPathsDelegates . Add ( & SetPathsDelegate ) ;
2014-08-21 20:30:51 -04:00
FAssetPickerConfig AssetPickerConfig ;
AssetPickerConfig . Filter . ClassNames . Append ( AssetClassNames ) ;
AssetPickerConfig . Filter . PackagePaths . Add ( FName ( * DefaultPath ) ) ;
AssetPickerConfig . bAllowDragging = false ;
AssetPickerConfig . InitialAssetViewType = EAssetViewType : : Tile ;
AssetPickerConfig . ThumbnailScale = 0.125 ;
AssetPickerConfig . OnAssetSelected = FOnAssetSelected : : CreateSP ( this , & SAssetDialog : : OnAssetSelected ) ;
AssetPickerConfig . OnAssetsActivated = FOnAssetsActivated : : CreateSP ( this , & SAssetDialog : : OnAssetsActivated ) ;
AssetPickerConfig . SetFilterDelegates . Add ( & SetFilterDelegate ) ;
AssetPickerConfig . GetCurrentSelectionDelegates . Add ( & GetCurrentSelectionDelegate ) ;
2014-08-22 19:06:27 -04:00
AssetPickerConfig . SaveSettingsName = TEXT ( " AssetDialog " ) ;
2014-09-15 20:43:33 -04:00
AssetPickerConfig . bCanShowFolders = true ;
AssetPickerConfig . OnFolderEntered = FOnPathSelected : : CreateSP ( this , & SAssetDialog : : HandleAssetViewFolderEntered ) ;
2014-08-21 20:30:51 -04:00
SetCurrentlySelectedPath ( DefaultPath ) ;
// Open and save specific configuration
FText ConfirmButtonText ;
bool bIncludeNameBox = false ;
if ( DialogType = = EAssetDialogType : : Open )
{
const FOpenAssetDialogConfig & OpenAssetConfig = static_cast < const FOpenAssetDialogConfig & > ( InConfig ) ;
PathPickerConfig . bAllowContextMenu = false ;
ConfirmButtonText = LOCTEXT ( " AssetDialogOpenButton " , " Open " ) ;
AssetPickerConfig . SelectionMode = OpenAssetConfig . bAllowMultipleSelection ? ESelectionMode : : Multi : ESelectionMode : : Single ;
2014-09-15 21:28:40 -04:00
AssetPickerConfig . bFocusSearchBoxWhenOpened = true ;
2014-08-21 20:30:51 -04:00
bIncludeNameBox = false ;
}
else if ( DialogType = = EAssetDialogType : : Save )
{
const FSaveAssetDialogConfig & SaveAssetConfig = static_cast < const FSaveAssetDialogConfig & > ( InConfig ) ;
PathPickerConfig . bAllowContextMenu = true ;
ConfirmButtonText = LOCTEXT ( " AssetDialogSaveButton " , " Save " ) ;
AssetPickerConfig . SelectionMode = ESelectionMode : : Single ;
2014-09-15 21:28:40 -04:00
AssetPickerConfig . bFocusSearchBoxWhenOpened = false ;
2014-08-21 20:30:51 -04:00
bIncludeNameBox = true ;
2014-09-01 13:25:23 -04:00
ExistingAssetPolicy = SaveAssetConfig . ExistingAssetPolicy ;
2014-08-21 20:30:51 -04:00
SetCurrentlyEnteredAssetName ( SaveAssetConfig . DefaultAssetName ) ;
}
else
{
ensureMsgf ( 0 , TEXT ( " AssetDialog type %d is not supported. " ) , DialogType ) ;
}
2014-09-15 20:43:33 -04:00
TSharedPtr < SWidget > PathPicker = FContentBrowserSingleton : : Get ( ) . CreatePathPicker ( PathPickerConfig ) ;
TSharedPtr < SWidget > AssetPicker = FContentBrowserSingleton : : Get ( ) . CreateAssetPicker ( AssetPickerConfig ) ;
2014-08-21 20:30:51 -04:00
// The root widget in this dialog.
TSharedRef < SVerticalBox > MainVerticalBox = SNew ( SVerticalBox ) ;
// Path/Asset view
MainVerticalBox - > AddSlot ( )
. FillHeight ( 1 )
. Padding ( 0 , 0 , 0 , 4 )
[
SNew ( SSplitter )
+ SSplitter : : Slot ( )
. Value ( 0.25f )
[
SNew ( SBorder )
. BorderImage ( FEditorStyle : : GetBrush ( " ToolPanel.GroupBorder " ) )
[
PathPicker . ToSharedRef ( )
]
]
+ SSplitter : : Slot ( )
. Value ( 0.75f )
[
SNew ( SBorder )
. BorderImage ( FEditorStyle : : GetBrush ( " ToolPanel.GroupBorder " ) )
[
AssetPicker . ToSharedRef ( )
]
]
] ;
// Input error strip, if we are using a name box
if ( bIncludeNameBox )
{
// Name Error label
MainVerticalBox - > AddSlot ( )
. AutoHeight ( )
[
// Constant height, whether the label is visible or not
SNew ( SBox ) . HeightOverride ( 18 )
[
SNew ( SBorder )
. Visibility ( this , & SAssetDialog : : GetNameErrorLabelVisibility )
. BorderImage ( FEditorStyle : : GetBrush ( " AssetDialog.ErrorLabelBorder " ) )
. Content ( )
[
SNew ( STextBlock )
. Text ( this , & SAssetDialog : : GetNameErrorLabelText )
. TextStyle ( FEditorStyle : : Get ( ) , " AssetDialog.ErrorLabelFont " )
]
]
] ;
}
// Buttons and asset name
TSharedRef < SHorizontalBox > ButtonsAndNameBox = SNew ( SHorizontalBox ) ;
if ( bIncludeNameBox )
{
ButtonsAndNameBox - > AddSlot ( )
. AutoWidth ( )
. HAlign ( HAlign_Right )
. VAlign ( VAlign_Center )
. Padding ( 80 , 3 , 4 , 3 )
[
SNew ( STextBlock ) . Text ( LOCTEXT ( " NameBoxLabel " , " Name: " ) )
] ;
ButtonsAndNameBox - > AddSlot ( )
. FillWidth ( 1 )
. VAlign ( VAlign_Center )
. Padding ( 4 , 3 )
[
2014-09-15 21:28:40 -04:00
SAssignNew ( NameEditableText , SEditableTextBox )
2014-08-21 20:30:51 -04:00
. Text ( this , & SAssetDialog : : GetAssetNameText )
. OnTextCommitted ( this , & SAssetDialog : : OnAssetNameTextCommited )
. OnTextChanged ( this , & SAssetDialog : : OnAssetNameTextCommited , ETextCommit : : Default )
2014-09-15 21:28:40 -04:00
. SelectAllTextWhenFocused ( true )
2014-08-21 20:30:51 -04:00
] ;
}
ButtonsAndNameBox - > AddSlot ( )
. AutoWidth ( )
. VAlign ( VAlign_Center )
. Padding ( 4 , 3 )
[
SNew ( SButton )
. Text ( ConfirmButtonText )
. IsEnabled ( this , & SAssetDialog : : IsConfirmButtonEnabled )
. OnClicked ( this , & SAssetDialog : : OnConfirmClicked )
] ;
ButtonsAndNameBox - > AddSlot ( )
. AutoWidth ( )
. VAlign ( VAlign_Center )
. Padding ( 4 , 3 )
[
SNew ( SButton )
. Text ( LOCTEXT ( " AssetDialogCancelButton " , " Cancel " ) )
. OnClicked ( this , & SAssetDialog : : OnCancelClicked )
] ;
MainVerticalBox - > AddSlot ( )
. AutoHeight ( )
. HAlign ( bIncludeNameBox ? HAlign_Fill : HAlign_Right )
. Padding ( 8 , 2 , 8 , 4 )
[
SNew ( SBorder )
. BorderImage ( FEditorStyle : : GetBrush ( " ToolPanel.GroupBorder " ) )
[
ButtonsAndNameBox
]
] ;
ChildSlot
[
MainVerticalBox
] ;
}
END_SLATE_FUNCTION_BUILD_OPTIMIZATION
FReply SAssetDialog : : OnKeyDown ( const FGeometry & MyGeometry , const FKeyboardEvent & InKeyboardEvent )
{
if ( InKeyboardEvent . GetKey ( ) = = EKeys : : Escape )
{
CloseDialog ( ) ;
return FReply : : Handled ( ) ;
}
return SCompoundWidget : : OnKeyDown ( MyGeometry , InKeyboardEvent ) ;
}
2014-09-15 21:28:40 -04:00
void SAssetDialog : : Tick ( const FGeometry & AllottedGeometry , const double InCurrentTime , const float InDeltaTime )
{
if ( bPendingFocusNextFrame )
{
FocusNameBox ( ) ;
bPendingFocusNextFrame = false ;
}
SCompoundWidget : : Tick ( AllottedGeometry , InCurrentTime , InDeltaTime ) ;
}
2014-08-21 20:30:51 -04:00
void SAssetDialog : : SetOnAssetsChosenForOpen ( const FOnAssetsChosenForOpen & InOnAssetsChosenForOpen )
{
OnAssetsChosenForOpen = InOnAssetsChosenForOpen ;
}
void SAssetDialog : : SetOnObjectPathChosenForSave ( const FOnObjectPathChosenForSave & InOnObjectPathChosenForSave )
{
OnObjectPathChosenForSave = InOnObjectPathChosenForSave ;
}
2014-09-15 21:28:40 -04:00
void SAssetDialog : : FocusNameBox ( )
{
if ( NameEditableText . IsValid ( ) )
{
FSlateApplication : : Get ( ) . SetKeyboardFocus ( NameEditableText . ToSharedRef ( ) , EKeyboardFocusCause : : SetDirectly ) ;
}
}
2014-08-21 20:30:51 -04:00
FText SAssetDialog : : GetAssetNameText ( ) const
{
return FText : : FromString ( CurrentlyEnteredAssetName ) ;
}
void SAssetDialog : : OnAssetNameTextCommited ( const FText & InText , ETextCommit : : Type InCommitType )
{
SetCurrentlyEnteredAssetName ( InText . ToString ( ) ) ;
if ( InCommitType = = ETextCommit : : OnEnter )
{
CommitObjectPathForSave ( ) ;
}
}
EVisibility SAssetDialog : : GetNameErrorLabelVisibility ( ) const
{
return GetNameErrorLabelText ( ) . IsEmpty ( ) ? EVisibility : : Hidden : EVisibility : : Visible ;
}
FString SAssetDialog : : GetNameErrorLabelText ( ) const
{
if ( ! bLastInputValidityCheckSuccessful )
{
return LastInputValidityErrorText . ToString ( ) ;
}
return TEXT ( " " ) ;
}
void SAssetDialog : : HandlePathSelected ( const FString & NewPath )
{
FARFilter NewFilter ;
NewFilter . ClassNames . Append ( AssetClassNames ) ;
NewFilter . PackagePaths . Add ( FName ( * NewPath ) ) ;
SetCurrentlySelectedPath ( NewPath ) ;
SetFilterDelegate . ExecuteIfBound ( NewFilter ) ;
}
2014-09-15 20:43:33 -04:00
void SAssetDialog : : HandleAssetViewFolderEntered ( const FString & NewPath )
{
SetCurrentlySelectedPath ( NewPath ) ;
TArray < FString > NewPaths ;
NewPaths . Add ( NewPath ) ;
SetPathsDelegate . Execute ( NewPaths ) ;
}
2014-08-21 20:30:51 -04:00
bool SAssetDialog : : IsConfirmButtonEnabled ( ) const
{
if ( DialogType = = EAssetDialogType : : Open )
{
return CurrentlySelectedAssets . Num ( ) > 0 ;
}
else if ( DialogType = = EAssetDialogType : : Save )
{
return bLastInputValidityCheckSuccessful ;
}
else
{
ensureMsgf ( 0 , TEXT ( " AssetDialog type %d is not supported. " ) , DialogType ) ;
}
return false ;
}
FReply SAssetDialog : : OnConfirmClicked ( )
{
if ( DialogType = = EAssetDialogType : : Open )
{
TArray < FAssetData > SelectedAssets = GetCurrentSelectionDelegate . Execute ( ) ;
if ( SelectedAssets . Num ( ) > 0 )
{
ChooseAssetsForOpen ( SelectedAssets ) ;
}
}
else if ( DialogType = = EAssetDialogType : : Save )
{
// @todo save asset validation (e.g. "asset already exists" check)
CommitObjectPathForSave ( ) ;
}
else
{
ensureMsgf ( 0 , TEXT ( " AssetDialog type %d is not supported. " ) , DialogType ) ;
}
return FReply : : Handled ( ) ;
}
FReply SAssetDialog : : OnCancelClicked ( )
{
CloseDialog ( ) ;
return FReply : : Handled ( ) ;
}
void SAssetDialog : : OnAssetSelected ( const FAssetData & AssetData )
{
CurrentlySelectedAssets = GetCurrentSelectionDelegate . Execute ( ) ;
if ( AssetData . IsValid ( ) )
{
SetCurrentlySelectedPath ( AssetData . PackagePath . ToString ( ) ) ;
SetCurrentlyEnteredAssetName ( AssetData . AssetName . ToString ( ) ) ;
}
}
void SAssetDialog : : OnAssetsActivated ( const TArray < FAssetData > & SelectedAssets , EAssetTypeActivationMethod : : Type ActivationType )
{
const bool bCorrectActivationMethod = ( ActivationType = = EAssetTypeActivationMethod : : DoubleClicked | | ActivationType = = EAssetTypeActivationMethod : : Opened ) ;
if ( SelectedAssets . Num ( ) > 0 & & bCorrectActivationMethod )
{
if ( DialogType = = EAssetDialogType : : Open )
{
ChooseAssetsForOpen ( SelectedAssets ) ;
}
else if ( DialogType = = EAssetDialogType : : Save )
{
const FAssetData & AssetData = SelectedAssets [ 0 ] ;
SetCurrentlySelectedPath ( AssetData . PackagePath . ToString ( ) ) ;
SetCurrentlyEnteredAssetName ( AssetData . AssetName . ToString ( ) ) ;
CommitObjectPathForSave ( ) ;
}
else
{
ensureMsgf ( 0 , TEXT ( " AssetDialog type %d is not supported. " ) , DialogType ) ;
}
}
}
void SAssetDialog : : CloseDialog ( )
{
FWidgetPath WidgetPath ;
TSharedPtr < SWindow > ContainingWindow = FSlateApplication : : Get ( ) . FindWidgetWindow ( AsShared ( ) , WidgetPath ) ;
if ( ContainingWindow . IsValid ( ) )
{
ContainingWindow - > RequestDestroyWindow ( ) ;
}
}
void SAssetDialog : : SetCurrentlySelectedPath ( const FString & NewPath )
{
CurrentlySelectedPath = NewPath ;
UpdateInputValidity ( ) ;
}
void SAssetDialog : : SetCurrentlyEnteredAssetName ( const FString & NewName )
{
CurrentlyEnteredAssetName = NewName ;
UpdateInputValidity ( ) ;
}
void SAssetDialog : : UpdateInputValidity ( )
{
bLastInputValidityCheckSuccessful = true ;
if ( CurrentlyEnteredAssetName . IsEmpty ( ) )
{
// No error text for an empty name. Just fail validity.
LastInputValidityErrorText = FText : : GetEmpty ( ) ;
bLastInputValidityCheckSuccessful = false ;
}
if ( bLastInputValidityCheckSuccessful )
{
if ( CurrentlySelectedPath . IsEmpty ( ) )
{
LastInputValidityErrorText = LOCTEXT ( " AssetDialog_NoPathSelected " , " You must select a path. " ) ;
bLastInputValidityCheckSuccessful = false ;
}
}
if ( DialogType = = EAssetDialogType : : Save )
{
if ( bLastInputValidityCheckSuccessful )
{
const FString ObjectPath = GetObjectPathForSave ( ) ;
FText ErrorMessage ;
2014-09-01 13:25:23 -04:00
const bool bAllowExistingAsset = ( ExistingAssetPolicy = = ESaveAssetDialogExistingAssetPolicy : : AllowButWarn ) ;
if ( ! ContentBrowserUtils : : IsValidObjectPathForCreate ( ObjectPath , ErrorMessage , bAllowExistingAsset ) )
2014-08-21 20:30:51 -04:00
{
LastInputValidityErrorText = ErrorMessage ;
bLastInputValidityCheckSuccessful = false ;
}
}
}
}
void SAssetDialog : : ChooseAssetsForOpen ( const TArray < FAssetData > & SelectedAssets )
{
if ( ensure ( DialogType = = EAssetDialogType : : Open ) )
{
if ( SelectedAssets . Num ( ) > 0 )
{
OnAssetsChosenForOpen . ExecuteIfBound ( SelectedAssets ) ;
CloseDialog ( ) ;
}
}
}
FString SAssetDialog : : GetObjectPathForSave ( ) const
{
return CurrentlySelectedPath / CurrentlyEnteredAssetName + TEXT ( " . " ) + CurrentlyEnteredAssetName ;
}
void SAssetDialog : : CommitObjectPathForSave ( )
{
if ( ensure ( DialogType = = EAssetDialogType : : Save ) )
{
if ( bLastInputValidityCheckSuccessful )
{
const FString ObjectPath = GetObjectPathForSave ( ) ;
2014-09-01 13:25:23 -04:00
bool bProceedWithSave = true ;
// If we were asked to warn on existing assets, do it now
if ( ExistingAssetPolicy = = ESaveAssetDialogExistingAssetPolicy : : AllowButWarn )
{
FAssetRegistryModule & AssetRegistryModule = FModuleManager : : LoadModuleChecked < FAssetRegistryModule > ( " AssetRegistry " ) ;
FAssetData ExistingAsset = AssetRegistryModule . Get ( ) . GetAssetByObjectPath ( FName ( * ObjectPath ) ) ;
if ( ExistingAsset . IsValid ( ) & & AssetClassNames . Contains ( ExistingAsset . AssetClass ) )
{
EAppReturnType : : Type ShouldReplace = FMessageDialog : : Open ( EAppMsgType : : YesNo , FText : : Format ( LOCTEXT ( " ReplaceAssetMessage " , " {ExistingAsset} already exists. Do you want to replace it? " ) , FText : : FromString ( CurrentlyEnteredAssetName ) ) ) ;
bProceedWithSave = ( ShouldReplace = = EAppReturnType : : Yes ) ;
}
}
if ( bProceedWithSave )
{
OnObjectPathChosenForSave . ExecuteIfBound ( ObjectPath ) ;
CloseDialog ( ) ;
}
2014-08-21 20:30:51 -04:00
}
}
}
# undef LOCTEXT_NAMESPACE