Files
UnrealEngineUWP/Engine/Source/Editor/ContentBrowser/Private/AssetViewWidgets.cpp
2015-04-16 17:03:14 -04:00

1603 lines
46 KiB
C++

// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
#include "ContentBrowserPCH.h"
#include "ISourceControlModule.h"
#include "AssetThumbnail.h"
#include "AssetViewTypes.h"
#include "AssetViewWidgets.h"
#include "SThumbnailEditModeTools.h"
#include "DragAndDrop/AssetDragDropOp.h"
#include "DragAndDrop/AssetPathDragDropOp.h"
#include "DragDropHandler.h"
#include "BreakIterator.h"
#include "SInlineEditableTextBlock.h"
#define LOCTEXT_NAMESPACE "ContentBrowser"
///////////////////////////////
// FAssetViewModeUtils
///////////////////////////////
FReply FAssetViewModeUtils::OnViewModeKeyDown( const TSet< TSharedPtr<FAssetViewItem> >& SelectedItems, const FKeyEvent& InKeyEvent )
{
// All asset views use Ctrl-C to copy references to assets
if ( InKeyEvent.IsControlDown() && InKeyEvent.GetCharacter() == 'C' )
{
FAssetRegistryModule& AssetRegistryModule = FModuleManager::LoadModuleChecked<FAssetRegistryModule>(TEXT("AssetRegistry"));
TArray<FAssetData> SelectedAssets;
for ( auto ItemIt = SelectedItems.CreateConstIterator(); ItemIt; ++ItemIt)
{
const TSharedPtr<FAssetViewItem>& Item = *ItemIt;
if(Item.IsValid())
{
if(Item->GetType() == EAssetItemType::Folder)
{
// we need to recurse & copy references to all folder contents
FARFilter Filter;
Filter.PackagePaths.Add(*StaticCastSharedPtr<FAssetViewFolder>(Item)->FolderPath);
// Add assets found in the asset registry
AssetRegistryModule.Get().GetAssets(Filter, SelectedAssets);
}
else
{
SelectedAssets.Add(StaticCastSharedPtr<FAssetViewAsset>(Item)->Data);
}
}
}
ContentBrowserUtils::CopyAssetReferencesToClipboard(SelectedAssets);
return FReply::Handled();
}
return FReply::Unhandled();
}
///////////////////////////////
// Asset view modes
///////////////////////////////
FReply SAssetTileView::OnKeyDown( const FGeometry& InGeometry, const FKeyEvent& InKeyEvent )
{
FReply Reply = FAssetViewModeUtils::OnViewModeKeyDown(SelectedItems, InKeyEvent);
if ( Reply.IsEventHandled() )
{
return Reply;
}
else
{
return STileView<TSharedPtr<FAssetViewItem>>::OnKeyDown(InGeometry, InKeyEvent);
}
}
FReply SAssetListView::OnKeyDown( const FGeometry& InGeometry, const FKeyEvent& InKeyEvent )
{
FReply Reply = FAssetViewModeUtils::OnViewModeKeyDown(SelectedItems, InKeyEvent);
if ( Reply.IsEventHandled() )
{
return Reply;
}
else
{
return SListView<TSharedPtr<FAssetViewItem>>::OnKeyDown(InGeometry, InKeyEvent);
}
}
FReply SAssetColumnView::OnKeyDown( const FGeometry& InGeometry, const FKeyEvent& InKeyEvent )
{
FReply Reply = FAssetViewModeUtils::OnViewModeKeyDown(SelectedItems, InKeyEvent);
if ( Reply.IsEventHandled() )
{
return Reply;
}
else
{
return SListView<TSharedPtr<FAssetViewItem>>::OnKeyDown(InGeometry, InKeyEvent);
}
}
///////////////////////////////
// SAssetViewItem
///////////////////////////////
SAssetViewItem::~SAssetViewItem()
{
if ( AssetItem.IsValid() )
{
AssetItem->OnAssetDataChanged.RemoveAll( this );
}
OnItemDestroyed.ExecuteIfBound( AssetItem );
SetForceMipLevelsToBeResident(false);
}
void SAssetViewItem::Construct( const FArguments& InArgs )
{
AssetItem = InArgs._AssetItem;
OnRenameBegin = InArgs._OnRenameBegin;
OnRenameCommit = InArgs._OnRenameCommit;
OnVerifyRenameCommit = InArgs._OnVerifyRenameCommit;
OnItemDestroyed = InArgs._OnItemDestroyed;
ShouldAllowToolTip = InArgs._ShouldAllowToolTip;
ThumbnailEditMode = InArgs._ThumbnailEditMode;
HighlightText = InArgs._HighlightText;
OnAssetsDragDropped = InArgs._OnAssetsDragDropped;
OnPathsDragDropped = InArgs._OnPathsDragDropped;
OnFilesDragDropped = InArgs._OnFilesDragDropped;
OnGetCustomAssetToolTip = InArgs._OnGetCustomAssetToolTip;
OnVisualizeAssetToolTip = InArgs._OnVisualizeAssetToolTip;
OnAssetToolTipClosing = InArgs._OnAssetToolTipClosing;
bDraggedOver = false;
bPackageDirty = false;
OnAssetDataChanged();
AssetItem->OnAssetDataChanged.AddSP(this, &SAssetViewItem::OnAssetDataChanged);
AssetDirtyBrush = FEditorStyle::GetBrush("ContentBrowser.ContentDirty");
SCCStateBrush = nullptr;
// refresh SCC state icon
HandleSourceControlStateChanged();
SourceControlStateDelay = 0.0f;
bSourceControlStateRequested = false;
ISourceControlModule::Get().GetProvider().RegisterSourceControlStateChanged_Handle(FSourceControlStateChanged::FDelegate::CreateSP(this, &SAssetViewItem::HandleSourceControlStateChanged));
// Source control state may have already been cached, make sure the control is in sync with
// cached state as the delegate is not going to be invoked again until source control state
// changes. This will be necessary any time the widget is destroyed and recreated after source
// control state has been cached; for instance when the widget is killed via FWidgetGenerator::OnEndGenerationPass
// or a view is refreshed due to user filtering/navigating):
HandleSourceControlStateChanged();
}
void SAssetViewItem::Tick( const FGeometry& AllottedGeometry, const double InCurrentTime, const float InDeltaTime )
{
const float PrevSizeX = LastGeometry.Size.X;
LastGeometry = AllottedGeometry;
// Set cached wrap text width based on new "LastGeometry" value.
// We set this only when changed because binding a delegate to text wrapping attributes is expensive
if( PrevSizeX != AllottedGeometry.Size.X && InlineRenameWidget.IsValid() )
{
InlineRenameWidget->SetWrapTextAt( GetNameTextWrapWidth() );
}
UpdatePackageDirtyState();
UpdateSourceControlState((float)InDeltaTime);
}
TSharedPtr<IToolTip> SAssetViewItem::GetToolTip()
{
return ShouldAllowToolTip.Get() ? SCompoundWidget::GetToolTip() : NULL;
}
bool SAssetViewItem::ValidateDragDrop( const FGeometry& MyGeometry, const FDragDropEvent& DragDropEvent ) const
{
return IsFolder() && DragDropHandler::ValidateDragDropOnAssetFolder(MyGeometry, DragDropEvent, StaticCastSharedPtr<FAssetViewFolder>(AssetItem)->FolderPath);
}
void SAssetViewItem::OnDragEnter( const FGeometry& MyGeometry, const FDragDropEvent& DragDropEvent )
{
bDraggedOver = false;
if (ValidateDragDrop(MyGeometry, DragDropEvent))
{
bDraggedOver = true;
}
}
void SAssetViewItem::OnDragLeave( const FDragDropEvent& DragDropEvent )
{
if(IsFolder())
{
TSharedPtr<FDragDropOperation> Operation = DragDropEvent.GetOperation();
if (Operation.IsValid())
{
Operation->SetCursorOverride(TOptional<EMouseCursor::Type>());
if (Operation->IsOfType<FAssetDragDropOp>())
{
TSharedPtr<FAssetDragDropOp> DragDropOp = StaticCastSharedPtr<FAssetDragDropOp>(Operation);
DragDropOp->ResetToDefaultToolTip();
}
}
bDraggedOver = false;
}
bDraggedOver = false;
}
FReply SAssetViewItem::OnDragOver( const FGeometry& MyGeometry, const FDragDropEvent& DragDropEvent )
{
bDraggedOver = false;
if (ValidateDragDrop(MyGeometry, DragDropEvent))
{
bDraggedOver = true;
return FReply::Handled();
}
return FReply::Unhandled();
}
FReply SAssetViewItem::OnDrop( const FGeometry& MyGeometry, const FDragDropEvent& DragDropEvent )
{
bDraggedOver = false;
if (ValidateDragDrop(MyGeometry, DragDropEvent))
{
check(AssetItem->GetType() == EAssetItemType::Folder);
TSharedPtr<FDragDropOperation> Operation = DragDropEvent.GetOperation();
if (!Operation.IsValid())
{
return FReply::Unhandled();
}
if (Operation->IsOfType<FExternalDragOperation>())
{
TSharedPtr<FExternalDragOperation> DragDropOp = StaticCastSharedPtr<FExternalDragOperation>(Operation);
OnFilesDragDropped.ExecuteIfBound(DragDropOp->GetFiles(), StaticCastSharedPtr<FAssetViewFolder>(AssetItem)->FolderPath);
return FReply::Handled();
}
else if (Operation->IsOfType<FAssetPathDragDropOp>())
{
TSharedPtr<FAssetPathDragDropOp> DragDropOp = StaticCastSharedPtr<FAssetPathDragDropOp>(Operation);
OnPathsDragDropped.ExecuteIfBound(DragDropOp->PathNames, StaticCastSharedPtr<FAssetViewFolder>(AssetItem)->FolderPath);
return FReply::Handled();
}
else if (Operation->IsOfType<FAssetDragDropOp>())
{
TSharedPtr<FAssetDragDropOp> DragDropOp = StaticCastSharedPtr<FAssetDragDropOp>(Operation);
OnAssetsDragDropped.ExecuteIfBound(DragDropOp->AssetData, StaticCastSharedPtr<FAssetViewFolder>(AssetItem)->FolderPath);
return FReply::Handled();
}
}
return FReply::Unhandled();
}
void SAssetViewItem::HandleBeginNameChange( const FText& OriginalText )
{
OnRenameBegin.ExecuteIfBound(AssetItem, OriginalText.ToString(), LastGeometry.GetClippingRect());
}
void SAssetViewItem::HandleNameCommitted( const FText& NewText, ETextCommit::Type CommitInfo )
{
OnRenameCommit.ExecuteIfBound(AssetItem, NewText.ToString(), LastGeometry.GetClippingRect(), CommitInfo);
}
bool SAssetViewItem::HandleVerifyNameChanged( const FText& NewText, FText& OutErrorMessage )
{
return !OnVerifyRenameCommit.IsBound() || OnVerifyRenameCommit.Execute(AssetItem, NewText, LastGeometry.GetClippingRect(), OutErrorMessage);
}
void SAssetViewItem::OnAssetDataChanged()
{
CachePackageName();
AssetPackage = FindObjectSafe<UPackage>(NULL, *CachedPackageName);
UpdatePackageDirtyState();
AssetTypeActions.Reset();
if ( AssetItem->GetType() != EAssetItemType::Folder )
{
UClass* AssetClass = FindObject<UClass>(ANY_PACKAGE, *StaticCastSharedPtr<FAssetViewAsset>(AssetItem)->Data.AssetClass.ToString());
if (AssetClass)
{
FAssetToolsModule& AssetToolsModule = FModuleManager::LoadModuleChecked<FAssetToolsModule>(TEXT("AssetTools"));
AssetTypeActions = AssetToolsModule.Get().GetAssetTypeActionsForClass(AssetClass).Pin();
}
}
if ( InlineRenameWidget.IsValid() )
{
InlineRenameWidget->SetText( GetNameText() );
}
}
void SAssetViewItem::DirtyStateChanged()
{
}
FText SAssetViewItem::GetAssetClassText() const
{
if (AssetItem.IsValid())
{
if (AssetItem->GetType() != EAssetItemType::Folder)
{
if (AssetTypeActions.IsValid())
{
return AssetTypeActions.Pin()->GetName();
}
else
{
return FText::FromName(StaticCastSharedPtr<FAssetViewAsset>(AssetItem)->Data.AssetClass);
}
}
else
{
return LOCTEXT("FolderName", "Folder");
}
}
return FText();
}
const FSlateBrush* SAssetViewItem::GetSCCStateImage() const
{
return SCCStateBrush;
}
void SAssetViewItem::HandleSourceControlStateChanged()
{
if ( ISourceControlModule::Get().IsEnabled() && AssetItem.IsValid() && (AssetItem->GetType() == EAssetItemType::Normal) && !AssetItem->IsTemporaryItem() && !FPackageName::IsScriptPackage(CachedPackageName) )
{
FSourceControlStatePtr SourceControlState = ISourceControlModule::Get().GetProvider().GetState(CachedPackageFileName, EStateCacheUsage::Use);
if(SourceControlState.IsValid())
{
SCCStateBrush = FEditorStyle::GetBrush(SourceControlState->GetIconName());
}
}
}
const FSlateBrush* SAssetViewItem::GetDirtyImage() const
{
return IsDirty() ? AssetDirtyBrush : NULL;
}
EVisibility SAssetViewItem::GetThumbnailEditModeUIVisibility() const
{
return !IsFolder() && ThumbnailEditMode.Get() == true ? EVisibility::Visible : EVisibility::Collapsed;
}
BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION
TSharedRef<SToolTip> SAssetViewItem::CreateToolTipWidget() const
{
if ( AssetItem.IsValid() )
{
if(OnGetCustomAssetToolTip.IsBound() && AssetItem->GetType() != EAssetItemType::Folder)
{
FAssetData& AssetData = StaticCastSharedPtr<FAssetViewAsset>(AssetItem)->Data;
return OnGetCustomAssetToolTip.Execute(AssetData);
}
else if(AssetItem->GetType() != EAssetItemType::Folder)
{
const FAssetData& AssetData = StaticCastSharedPtr<FAssetViewAsset>(AssetItem)->Data;
UClass* AssetClass = FindObject<UClass>(ANY_PACKAGE, *AssetData.AssetClass.ToString());
// The tooltip contains the name, class, path, and asset registry tags
const FText NameText = FText::FromName( AssetData.AssetName );
const FText ClassText = FText::Format( LOCTEXT("ClassName", "({0})"), GetAssetClassText() );
// Create a box to hold every line of info in the body of the tooltip
TSharedRef<SVerticalBox> InfoBox = SNew(SVerticalBox);
// Add Path
AddToToolTipInfoBox( InfoBox, LOCTEXT("TileViewTooltipPath", "Path"), FText::FromName(AssetData.PackagePath), false );
// If we are using a loaded class, find all the hidden tags so we don't display them
TMap<FName, UObject::FAssetRegistryTagMetadata> MetadataMap;
TSet<FName> ShownTags;
if ( AssetClass != NULL && AssetClass->GetDefaultObject() != NULL )
{
AssetClass->GetDefaultObject()->GetAssetRegistryTagMetadata(MetadataMap);
TArray<UObject::FAssetRegistryTag> Tags;
AssetClass->GetDefaultObject()->GetAssetRegistryTags(Tags);
for ( auto TagIt = Tags.CreateConstIterator(); TagIt; ++TagIt )
{
if (TagIt->Type != UObject::FAssetRegistryTag::TT_Hidden )
{
ShownTags.Add(TagIt->Name);
}
}
}
// If an asset class could not be loaded we cannot determine hidden tags so display no tags.
if( AssetClass != NULL )
{
// Add all asset registry tags and values
for ( auto TagIt = AssetData.TagsAndValues.CreateConstIterator(); TagIt; ++TagIt )
{
// Skip tags that are set to be hidden
if ( ShownTags.Contains(TagIt.Key()) )
{
const UObject::FAssetRegistryTagMetadata* Metadata = MetadataMap.Find(TagIt.Key());
const bool bImportant = (Metadata != nullptr && !Metadata->ImportantValue.IsEmpty() && Metadata->ImportantValue == TagIt.Value());
// Since all we have at this point is a string, we can't be very smart here.
// We need to strip some noise off class paths in some cases, but can't load the asset to inspect its UPROPERTYs manually due to performance concerns.
FString ValueString = TagIt.Value();
const TCHAR StringToRemove[] = TEXT("Class'/Script/");
if (ValueString.StartsWith(StringToRemove) && ValueString.EndsWith(TEXT("'")))
{
// Remove the class path for native classes, and also remove Engine. for engine classes
const int32 SizeOfPrefix = ARRAY_COUNT(StringToRemove);
ValueString = ValueString.Mid(SizeOfPrefix - 1, ValueString.Len() - SizeOfPrefix).Replace(TEXT("Engine."), TEXT(""));
}
// Check for DisplayName metadata
FText DisplayName;
if (UProperty* Field = FindField<UProperty>(AssetClass, TagIt.Key()))
{
DisplayName = Field->GetDisplayNameText();
// Strip off enum prefixes if they exist
if (UByteProperty* ByteProperty = Cast<UByteProperty>(Field))
{
if (ByteProperty->Enum)
{
const FString EnumPrefix = ByteProperty->Enum->GenerateEnumPrefix();
if (EnumPrefix.Len() && ValueString.StartsWith(EnumPrefix))
{
ValueString = ValueString.RightChop(EnumPrefix.Len() + 1); // +1 to skip over the underscore
}
}
ValueString = FName::NameToDisplayString(ValueString, false);
}
}
else
{
// We have no type information by this point, so no idea if it's a bool :(
const bool bIsBool = false;
DisplayName = FText::FromString(FName::NameToDisplayString(TagIt.Key().ToString(), bIsBool));
}
// Add suffix to the value string, if one is defined for this tag
if (Metadata != nullptr && !Metadata->Suffix.IsEmpty())
{
ValueString += TEXT(" ");
ValueString += Metadata->Suffix.ToString();
}
AddToToolTipInfoBox(InfoBox, DisplayName, FText::FromString(ValueString), bImportant);
}
}
}
TSharedRef<SVerticalBox> OverallTooltipVBox = SNew(SVerticalBox);
// Top section (asset name, type, is checked out)
OverallTooltipVBox->AddSlot()
.AutoHeight()
.Padding(0, 0, 0, 4)
[
SNew(SBorder)
.Padding(6)
.BorderImage(FEditorStyle::GetBrush("ContentBrowser.TileViewTooltip.ContentBorder"))
[
SNew(SVerticalBox)
+ SVerticalBox::Slot()
.AutoHeight()
[
SNew(SHorizontalBox)
+ SHorizontalBox::Slot()
.AutoWidth()
.VAlign(VAlign_Center)
.Padding(0, 0, 4, 0)
[
SNew(STextBlock)
.Text(NameText)
.Font(FEditorStyle::GetFontStyle("ContentBrowser.TileViewTooltip.NameFont"))
]
+ SHorizontalBox::Slot()
.AutoWidth()
.VAlign(VAlign_Center)
[
SNew(STextBlock).Text(ClassText)
.HighlightText(HighlightText)
]
]
+ SVerticalBox::Slot()
.AutoHeight()
[
SNew(STextBlock)
.Visibility(this, &SAssetViewItem::GetCheckedOutByOtherTextVisibility)
.Text(this, &SAssetViewItem::GetCheckedOutByOtherText)
.ColorAndOpacity(FLinearColor(0.1f, 0.5f, 1.f, 1.f))
]
]
];
// Middle section (user description, if present)
FText UserDescription = GetAssetUserDescription();
if (!UserDescription.IsEmpty())
{
OverallTooltipVBox->AddSlot()
.AutoHeight()
.Padding(0, 0, 0, 4)
[
SNew(SBorder)
.Padding(6)
.BorderImage(FEditorStyle::GetBrush("ContentBrowser.TileViewTooltip.ContentBorder"))
[
SNew(STextBlock)
.WrapTextAt(300.0f)
.Font(FEditorStyle::GetFontStyle("ContentBrowser.TileViewTooltip.AssetUserDescriptionFont"))
.Text(UserDescription)
]
];
}
// Bottom section (asset registry tags)
OverallTooltipVBox->AddSlot()
.AutoHeight()
[
SNew(SBorder)
.Padding(6)
.BorderImage(FEditorStyle::GetBrush("ContentBrowser.TileViewTooltip.ContentBorder"))
[
InfoBox
]
];
return SNew(SToolTip)
.TextMargin(1)
.BorderImage( FEditorStyle::GetBrush("ContentBrowser.TileViewTooltip.ToolTipBorder") )
[
SNew(SBorder)
.Padding(6)
.BorderImage( FEditorStyle::GetBrush("ContentBrowser.TileViewTooltip.NonContentBorder") )
[
OverallTooltipVBox
]
];
}
else
{
const FText& FolderName = StaticCastSharedPtr<FAssetViewFolder>(AssetItem)->FolderName;
const FString& FolderPath = StaticCastSharedPtr<FAssetViewFolder>(AssetItem)->FolderPath;
// Create a box to hold every line of info in the body of the tooltip
TSharedRef<SVerticalBox> InfoBox = SNew(SVerticalBox);
AddToToolTipInfoBox( InfoBox, LOCTEXT("TileViewTooltipPath", "Path"), FText::FromString(FolderPath), false );
return SNew(SToolTip)
.TextMargin(1)
.BorderImage( FEditorStyle::GetBrush("ContentBrowser.TileViewTooltip.ToolTipBorder") )
[
SNew(SBorder)
.Padding(6)
.BorderImage( FEditorStyle::GetBrush("ContentBrowser.TileViewTooltip.NonContentBorder") )
[
SNew(SVerticalBox)
+SVerticalBox::Slot()
.AutoHeight()
.Padding(0, 0, 0, 4)
[
SNew(SBorder)
.Padding(6)
.BorderImage( FEditorStyle::GetBrush("ContentBrowser.TileViewTooltip.ContentBorder") )
[
SNew(SVerticalBox)
+SVerticalBox::Slot()
.AutoHeight()
[
SNew(SHorizontalBox)
+SHorizontalBox::Slot()
.AutoWidth()
.VAlign(VAlign_Center)
.Padding(0, 0, 4, 0)
[
SNew(STextBlock)
.Text( FolderName )
.Font( FEditorStyle::GetFontStyle("ContentBrowser.TileViewTooltip.NameFont") )
]
+SHorizontalBox::Slot()
.AutoWidth()
.VAlign(VAlign_Center)
[
SNew(STextBlock)
.Text( LOCTEXT("FolderNameBracketed", "(Folder)") )
]
]
]
]
+SVerticalBox::Slot()
.AutoHeight()
[
SNew(SBorder)
.Padding(6)
.BorderImage( FEditorStyle::GetBrush("ContentBrowser.TileViewTooltip.ContentBorder") )
[
InfoBox
]
]
]
];
}
}
else
{
// Return an empty tooltip since the asset item wasn't valid
return SNew(SToolTip);
}
}
END_SLATE_FUNCTION_BUILD_OPTIMIZATION
EVisibility SAssetViewItem::GetCheckedOutByOtherTextVisibility() const
{
return GetCheckedOutByOtherText().IsEmpty() ? EVisibility::Collapsed : EVisibility::Visible;
}
FText SAssetViewItem::GetCheckedOutByOtherText() const
{
if ( AssetItem.IsValid() && AssetItem->GetType() != EAssetItemType::Folder && !GIsSavingPackage && !IsGarbageCollecting() )
{
const FAssetData& AssetData = StaticCastSharedPtr<FAssetViewAsset>(AssetItem)->Data;
ISourceControlProvider& SourceControlProvider = ISourceControlModule::Get().GetProvider();
FSourceControlStatePtr SourceControlState = SourceControlProvider.GetState(SourceControlHelpers::PackageFilename(AssetData.PackageName.ToString()), EStateCacheUsage::Use);
FString UserWhichHasPackageCheckedOut;
if (SourceControlState.IsValid() && SourceControlState->IsCheckedOutOther(&UserWhichHasPackageCheckedOut) )
{
if ( !UserWhichHasPackageCheckedOut.IsEmpty() )
{
return SourceControlState->GetDisplayTooltip();
}
}
}
return FText::GetEmpty();
}
FText SAssetViewItem::GetAssetUserDescription() const
{
if (AssetItem.IsValid() && AssetTypeActions.IsValid())
{
if (AssetItem->GetType() != EAssetItemType::Folder)
{
const FAssetData& AssetData = StaticCastSharedPtr<FAssetViewAsset>(AssetItem)->Data;
return AssetTypeActions.Pin()->GetAssetDescription(AssetData);
}
}
return FText::GetEmpty();
}
void SAssetViewItem::AddToToolTipInfoBox(const TSharedRef<SVerticalBox>& InfoBox, const FText& Key, const FText& Value, bool bImportant) const
{
FWidgetStyle ImportantStyle;
ImportantStyle.SetForegroundColor(FLinearColor(1, 0.5, 0, 1));
InfoBox->AddSlot()
.AutoHeight()
.Padding(0, 1)
[
SNew(SHorizontalBox)
+SHorizontalBox::Slot()
.AutoWidth()
.Padding(0, 0, 4, 0)
[
SNew(STextBlock) .Text( FText::Format(LOCTEXT("AssetViewTooltipFormat", "{0}:"), Key ) )
.ColorAndOpacity(bImportant ? ImportantStyle.GetSubduedForegroundColor() : FSlateColor::UseSubduedForeground())
]
+SHorizontalBox::Slot()
.AutoWidth()
[
SNew(STextBlock) .Text( Value )
.ColorAndOpacity(bImportant ? ImportantStyle.GetForegroundColor() : FSlateColor::UseForeground())
.HighlightText((Key.ToString() == TEXT("Path")) ? HighlightText : FText())
]
];
}
void SAssetViewItem::UpdatePackageDirtyState()
{
bool bNewIsDirty = false;
// Only update the dirty state for non-temporary asset items that aren't a built in script
if ( AssetItem.IsValid() && !AssetItem->IsTemporaryItem() && AssetItem->GetType() != EAssetItemType::Folder && !FPackageName::IsScriptPackage(CachedPackageName) )
{
if ( AssetPackage.IsValid() )
{
bNewIsDirty = AssetPackage->IsDirty();
}
}
if ( bNewIsDirty != bPackageDirty )
{
bPackageDirty = bNewIsDirty;
DirtyStateChanged();
}
}
bool SAssetViewItem::IsDirty() const
{
return bPackageDirty;
}
void SAssetViewItem::UpdateSourceControlState(float InDeltaTime)
{
SourceControlStateDelay += InDeltaTime;
if ( !bSourceControlStateRequested && SourceControlStateDelay > 1.0f && AssetItem.IsValid() )
{
// Only update the SCC state for non-temporary asset items that aren't a built in script
if ( AssetItem.IsValid() && !AssetItem->IsTemporaryItem() && AssetItem->GetType() != EAssetItemType::Folder && !FPackageName::IsScriptPackage(CachedPackageName) )
{
// Request the most recent SCC state for this asset
ISourceControlModule::Get().QueueStatusUpdate(CachedPackageFileName);
}
bSourceControlStateRequested = true;
}
}
void SAssetViewItem::CachePackageName()
{
if(AssetItem.IsValid())
{
if(AssetItem->GetType() != EAssetItemType::Folder)
{
CachedPackageName = StaticCastSharedPtr<FAssetViewAsset>(AssetItem)->Data.PackageName.ToString();
CachedPackageFileName = SourceControlHelpers::PackageFilename(CachedPackageName);
}
else
{
CachedPackageName = StaticCastSharedPtr<FAssetViewFolder>(AssetItem)->FolderName.ToString();
}
}
}
const FSlateBrush* SAssetViewItem::GetBorderImage() const
{
return bDraggedOver ? FEditorStyle::GetBrush("Menu.Background") : FEditorStyle::GetBrush("NoBorder");
}
bool SAssetViewItem::IsFolder() const
{
return AssetItem.IsValid() && AssetItem->GetType() == EAssetItemType::Folder;
}
FText SAssetViewItem::GetNameText() const
{
if(AssetItem.IsValid())
{
if(AssetItem->GetType() != EAssetItemType::Folder)
{
return FText::FromName(StaticCastSharedPtr<FAssetViewAsset>(AssetItem)->Data.AssetName);
}
else
{
return StaticCastSharedPtr<FAssetViewFolder>(AssetItem)->FolderName;
}
}
return FText();
}
FSlateColor SAssetViewItem::GetAssetColor() const
{
if(AssetItem.IsValid())
{
if(AssetItem->GetType() == EAssetItemType::Folder)
{
const TSharedPtr<FLinearColor> Color = ContentBrowserUtils::LoadColor( StaticCastSharedPtr<FAssetViewFolder>(AssetItem)->FolderPath );
if ( Color.IsValid() )
{
return *Color.Get();
}
}
else if(AssetTypeActions.IsValid())
{
return AssetTypeActions.Pin()->GetTypeColor().ReinterpretAsLinear();
}
}
return ContentBrowserUtils::GetDefaultColor();
}
void SAssetViewItem::SetForceMipLevelsToBeResident(bool bForce) const
{
if(AssetItem.IsValid() && AssetItem->GetType() == EAssetItemType::Normal)
{
const FAssetData& AssetData = StaticCastSharedPtr<FAssetViewAsset>(AssetItem)->Data;
if(AssetData.IsValid() && AssetData.IsAssetLoaded())
{
UObject* Asset = AssetData.GetAsset();
if(Asset != nullptr)
{
if(UTexture2D* Texture2D = Cast<UTexture2D>(Asset))
{
Texture2D->bForceMiplevelsToBeResident = bForce;
}
else if(UMaterial* Material = Cast<UMaterial>(Asset))
{
Material->SetForceMipLevelsToBeResident(bForce, bForce, -1.0f);
}
}
}
}
}
void SAssetViewItem::HandleAssetLoaded(UObject* InAsset) const
{
if(InAsset != nullptr)
{
if(AssetItem.IsValid() && AssetItem->GetType() == EAssetItemType::Normal)
{
const FAssetData& AssetData = StaticCastSharedPtr<FAssetViewAsset>(AssetItem)->Data;
if(AssetData.IsValid() && AssetData.IsAssetLoaded())
{
if(InAsset == AssetData.GetAsset())
{
SetForceMipLevelsToBeResident(true);
}
}
}
}
}
bool SAssetViewItem::OnVisualizeTooltip(const TSharedPtr<SWidget>& TooltipContent)
{
if(OnVisualizeAssetToolTip.IsBound() && TooltipContent.IsValid() && AssetItem->GetType() != EAssetItemType::Folder)
{
FAssetData& AssetData = StaticCastSharedPtr<FAssetViewAsset>(AssetItem)->Data;
return OnVisualizeAssetToolTip.Execute(TooltipContent, AssetData);
}
// No custom behaviour, return false to allow slate to visualize the widget
return false;
}
void SAssetViewItem::OnToolTipClosing()
{
OnAssetToolTipClosing.ExecuteIfBound();
}
///////////////////////////////
// SAssetListItem
///////////////////////////////
SAssetListItem::~SAssetListItem()
{
FCoreUObjectDelegates::OnAssetLoaded.RemoveAll(this);
}
BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION
void SAssetListItem::Construct( const FArguments& InArgs )
{
SAssetViewItem::Construct( SAssetViewItem::FArguments()
.AssetItem(InArgs._AssetItem)
.OnRenameBegin(InArgs._OnRenameBegin)
.OnRenameCommit(InArgs._OnRenameCommit)
.OnVerifyRenameCommit(InArgs._OnVerifyRenameCommit)
.OnItemDestroyed(InArgs._OnItemDestroyed)
.ShouldAllowToolTip(InArgs._ShouldAllowToolTip)
.ThumbnailEditMode(InArgs._ThumbnailEditMode)
.HighlightText(InArgs._HighlightText)
.OnAssetsDragDropped(InArgs._OnAssetsDragDropped)
.OnPathsDragDropped(InArgs._OnPathsDragDropped)
.OnFilesDragDropped(InArgs._OnFilesDragDropped)
.OnGetCustomAssetToolTip(InArgs._OnGetCustomAssetToolTip)
.OnVisualizeAssetToolTip(InArgs._OnVisualizeAssetToolTip)
.OnAssetToolTipClosing( InArgs._OnAssetToolTipClosing )
);
AssetThumbnail = InArgs._AssetThumbnail;
ItemHeight = InArgs._ItemHeight;
const float ThumbnailPadding = InArgs._ThumbnailPadding;
bool bIsDeveloperFolder = false;
TSharedPtr<SWidget> Thumbnail;
if ( AssetItem.IsValid() && AssetThumbnail.IsValid() )
{
FAssetThumbnailConfig ThumbnailConfig;
ThumbnailConfig.bAllowFadeIn = true;
ThumbnailConfig.bAllowHintText = InArgs._AllowThumbnailHintLabel;
ThumbnailConfig.bForceGenericThumbnail = (AssetItem->GetType() == EAssetItemType::Creation);
ThumbnailConfig.bAllowAssetSpecificThumbnailOverlay = (AssetItem->GetType() != EAssetItemType::Creation);
ThumbnailConfig.ThumbnailLabel = InArgs._ThumbnailLabel;
ThumbnailConfig.HighlightedText = InArgs._HighlightText;
ThumbnailConfig.HintColorAndOpacity = InArgs._ThumbnailHintColorAndOpacity;
Thumbnail = AssetThumbnail->MakeThumbnailWidget(ThumbnailConfig);
}
else
{
Thumbnail = SNew(SImage) .Image( FEditorStyle::GetDefaultBrush() );
}
ChildSlot
[
SNew(SBorder)
.BorderImage(this, &SAssetViewItem::GetBorderImage)
.Padding(0)
.AddMetaData<FTagMetaData>(FTagMetaData(AssetItem->GetType() == EAssetItemType::Normal ? StaticCastSharedPtr<FAssetViewAsset>(AssetItem)->Data.ObjectPath : NAME_None))
[
SNew(SHorizontalBox)
// Viewport
+SHorizontalBox::Slot()
.AutoWidth()
.VAlign(VAlign_Center)
[
SNew( SBox )
.Padding(ThumbnailPadding - 4.f)
.WidthOverride( this, &SAssetListItem::GetThumbnailBoxSize )
.HeightOverride( this, &SAssetListItem::GetThumbnailBoxSize )
[
// Drop shadow border
SNew(SBorder)
.Padding(4.f)
.BorderImage( IsFolder() ? FEditorStyle::GetBrush("NoBorder") : FEditorStyle::GetBrush("ContentBrowser.ThumbnailShadow") )
[
SNew(SOverlay)
// Folder base
+SOverlay::Slot()
[
SNew(SImage)
.Visibility(IsFolder() ? EVisibility::Visible : EVisibility::Collapsed)
.Image( bIsDeveloperFolder ? FEditorStyle::GetBrush("ContentBrowser.ListViewDeveloperFolderIcon.Base") : FEditorStyle::GetBrush("ContentBrowser.ListViewFolderIcon.Base") )
.ColorAndOpacity(this, &SAssetViewItem::GetAssetColor)
]
// Folder tint
+SOverlay::Slot()
[
SNew(SImage)
.Visibility(IsFolder() ? EVisibility::Visible : EVisibility::Collapsed)
.Image( bIsDeveloperFolder ? FEditorStyle::GetBrush("ContentBrowser.ListViewDeveloperFolderIcon.Mask") : FEditorStyle::GetBrush("ContentBrowser.ListViewFolderIcon.Mask") )
]
// The actual thumbnail
+SOverlay::Slot()
[
SNew(SHorizontalBox)
.Visibility(IsFolder() ? EVisibility::Collapsed : EVisibility::Visible)
+SHorizontalBox::Slot()
[
Thumbnail.ToSharedRef()
]
]
+SOverlay::Slot()
[
SNew(SThumbnailEditModeTools, AssetThumbnail)
.SmallView(true)
.Visibility(this, &SAssetListItem::GetThumbnailEditModeUIVisibility)
]
// Source control state
+SOverlay::Slot()
.HAlign(HAlign_Right)
.VAlign(VAlign_Top)
[
SNew( SBox )
.WidthOverride( this, &SAssetListItem::GetSCCImageSize )
.HeightOverride( this, &SAssetListItem::GetSCCImageSize )
[
SNew(SImage).Image( this, &SAssetListItem::GetSCCStateImage )
]
]
// Dirty state
+SOverlay::Slot()
.HAlign(HAlign_Left)
.VAlign(VAlign_Bottom)
[
SNew(SImage)
.Image( this, &SAssetListItem::GetDirtyImage )
]
]
]
]
+SHorizontalBox::Slot()
.AutoWidth()
.Padding(6, 0, 0, 0)
.VAlign(VAlign_Center)
[
SNew(SVerticalBox)
+SVerticalBox::Slot()
.AutoHeight()
.Padding(0, 1)
[
SAssignNew(InlineRenameWidget, SInlineEditableTextBlock)
.Font(FEditorStyle::GetFontStyle("ContentBrowser.AssetTileViewNameFont"))
.Text( GetNameText() )
.OnBeginTextEdit(this, &SAssetListItem::HandleBeginNameChange)
.OnTextCommitted(this, &SAssetListItem::HandleNameCommitted)
.OnVerifyTextChanged(this, &SAssetListItem::HandleVerifyNameChanged)
.HighlightText(InArgs._HighlightText)
.IsSelected(InArgs._IsSelected)
.IsReadOnly(ThumbnailEditMode)
]
+SVerticalBox::Slot()
.AutoHeight()
.Padding(0, 1)
[
// Class
SAssignNew(ClassText, STextBlock)
.Font(FEditorStyle::GetFontStyle("ContentBrowser.AssetListViewClassFont"))
.Text(GetAssetClassText())
.HighlightText(InArgs._HighlightText)
]
]
]
];
SetToolTip( CreateToolTipWidget() );
if(AssetItem.IsValid())
{
AssetItem->RenamedRequestEvent.BindSP( InlineRenameWidget.Get(), &SInlineEditableTextBlock::EnterEditingMode );
}
SetForceMipLevelsToBeResident(true);
// listen for asset loads so we can force mips to stream in if required
FCoreUObjectDelegates::OnAssetLoaded.AddSP(this, &SAssetViewItem::HandleAssetLoaded);
}
END_SLATE_FUNCTION_BUILD_OPTIMIZATION
void SAssetListItem::OnAssetDataChanged()
{
SAssetViewItem::OnAssetDataChanged();
if (ClassText.IsValid())
{
ClassText->SetText(GetAssetClassText());
}
SetToolTip( CreateToolTipWidget() );
}
FOptionalSize SAssetListItem::GetThumbnailBoxSize() const
{
return FOptionalSize( ItemHeight.Get() );
}
FOptionalSize SAssetListItem::GetSCCImageSize() const
{
return GetThumbnailBoxSize().Get() * 0.3;
}
///////////////////////////////
// SAssetTileItem
///////////////////////////////
SAssetTileItem::~SAssetTileItem()
{
FCoreUObjectDelegates::OnAssetLoaded.RemoveAll(this);
}
BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION
void SAssetTileItem::Construct( const FArguments& InArgs )
{
SAssetViewItem::Construct( SAssetViewItem::FArguments()
.AssetItem(InArgs._AssetItem)
.OnRenameBegin(InArgs._OnRenameBegin)
.OnRenameCommit(InArgs._OnRenameCommit)
.OnVerifyRenameCommit(InArgs._OnVerifyRenameCommit)
.OnItemDestroyed(InArgs._OnItemDestroyed)
.ShouldAllowToolTip(InArgs._ShouldAllowToolTip)
.ThumbnailEditMode(InArgs._ThumbnailEditMode)
.HighlightText(InArgs._HighlightText)
.OnAssetsDragDropped(InArgs._OnAssetsDragDropped)
.OnPathsDragDropped(InArgs._OnPathsDragDropped)
.OnFilesDragDropped(InArgs._OnFilesDragDropped)
.OnGetCustomAssetToolTip(InArgs._OnGetCustomAssetToolTip)
.OnVisualizeAssetToolTip(InArgs._OnVisualizeAssetToolTip)
.OnAssetToolTipClosing( InArgs._OnAssetToolTipClosing )
);
AssetThumbnail = InArgs._AssetThumbnail;
ItemWidth = InArgs._ItemWidth;
ThumbnailPadding = IsFolder() ? InArgs._ThumbnailPadding + 5.0f : InArgs._ThumbnailPadding;
TSharedPtr<SWidget> Thumbnail;
if ( AssetItem.IsValid() && AssetThumbnail.IsValid() )
{
FAssetThumbnailConfig ThumbnailConfig;
ThumbnailConfig.bAllowFadeIn = true;
ThumbnailConfig.bAllowHintText = InArgs._AllowThumbnailHintLabel;
ThumbnailConfig.bForceGenericThumbnail = (AssetItem->GetType() == EAssetItemType::Creation);
ThumbnailConfig.bAllowAssetSpecificThumbnailOverlay = (AssetItem->GetType() != EAssetItemType::Creation);
ThumbnailConfig.ThumbnailLabel = InArgs._ThumbnailLabel;
ThumbnailConfig.HighlightedText = InArgs._HighlightText;
ThumbnailConfig.HintColorAndOpacity = InArgs._ThumbnailHintColorAndOpacity;
Thumbnail = AssetThumbnail->MakeThumbnailWidget(ThumbnailConfig);
}
else
{
Thumbnail = SNew(SImage) .Image( FEditorStyle::GetDefaultBrush() );
}
bool bIsDeveloperFolder = false;
if(AssetItem.IsValid())
{
if(AssetItem->GetType() == EAssetItemType::Folder)
{
bIsDeveloperFolder = StaticCastSharedPtr<FAssetViewFolder>(AssetItem)->bDeveloperFolder;
}
}
ChildSlot
[
SNew(SBorder)
.BorderImage(this, &SAssetViewItem::GetBorderImage)
.Padding(0)
.AddMetaData<FTagMetaData>(FTagMetaData((AssetItem->GetType() == EAssetItemType::Normal) ? StaticCastSharedPtr<FAssetViewAsset>(AssetItem)->Data.ObjectPath : ((AssetItem->GetType() == EAssetItemType::Folder) ? FName(*StaticCastSharedPtr<FAssetViewFolder>(AssetItem)->FolderPath) : NAME_None)))
[
SNew(SVerticalBox)
// Thumbnail
+SVerticalBox::Slot()
.AutoHeight()
.HAlign(HAlign_Center)
[
// The remainder of the space is reserved for the name.
SNew(SBox)
.Padding(ThumbnailPadding - 4.f)
.WidthOverride(this, &SAssetTileItem::GetThumbnailBoxSize)
.HeightOverride( this, &SAssetTileItem::GetThumbnailBoxSize )
[
// Drop shadow border
SNew(SBorder)
.Padding(4.f)
.BorderImage(IsFolder() ? FEditorStyle::GetBrush("NoBorder") : FEditorStyle::GetBrush("ContentBrowser.ThumbnailShadow"))
[
SNew(SOverlay)
// Folder base
+SOverlay::Slot()
[
SNew(SImage)
.Visibility(IsFolder() ? EVisibility::Visible : EVisibility::Collapsed)
.Image( bIsDeveloperFolder ? FEditorStyle::GetBrush("ContentBrowser.TileViewDeveloperFolderIcon.Base") : FEditorStyle::GetBrush("ContentBrowser.TileViewFolderIcon.Base") )
.ColorAndOpacity(this, &SAssetViewItem::GetAssetColor)
]
// Folder tint
+SOverlay::Slot()
[
SNew(SImage)
.Visibility(IsFolder() ? EVisibility::Visible : EVisibility::Collapsed)
.Image( bIsDeveloperFolder ? FEditorStyle::GetBrush("ContentBrowser.TileViewDeveloperFolderIcon.Mask") : FEditorStyle::GetBrush("ContentBrowser.TileViewFolderIcon.Mask") )
]
// The actual thumbnail
+SOverlay::Slot()
[
SNew(SHorizontalBox)
.Visibility(IsFolder() ? EVisibility::Collapsed : EVisibility::Visible)
+SHorizontalBox::Slot()
[
Thumbnail.ToSharedRef()
]
]
// Tools for thumbnail edit mode
+SOverlay::Slot()
[
SNew(SThumbnailEditModeTools, AssetThumbnail)
.Visibility(this, &SAssetTileItem::GetThumbnailEditModeUIVisibility)
]
// Source control state
+SOverlay::Slot()
.HAlign(HAlign_Right)
.VAlign(VAlign_Top)
.Padding(FMargin(0, 2, 2, 0))
[
SNew( SBox )
.WidthOverride( this, &SAssetTileItem::GetSCCImageSize )
.HeightOverride( this, &SAssetTileItem::GetSCCImageSize )
[
SNew(SImage)
.Image( this, &SAssetTileItem::GetSCCStateImage )
]
]
// Dirty state
+SOverlay::Slot()
.HAlign(HAlign_Left)
.VAlign(VAlign_Bottom)
.Padding(FMargin(2, 0, 0, 2))
[
SNew(SImage)
.Image( this, &SAssetTileItem::GetDirtyImage )
]
]
]
]
+SVerticalBox::Slot()
.Padding(FMargin(1.f, 0))
.HAlign(HAlign_Center)
.VAlign(VAlign_Center)
.FillHeight(1.f)
[
SAssignNew(InlineRenameWidget, SInlineEditableTextBlock)
.Font( this, &SAssetTileItem::GetThumbnailFont )
.Text( GetNameText() )
.OnBeginTextEdit(this, &SAssetTileItem::HandleBeginNameChange)
.OnTextCommitted(this, &SAssetTileItem::HandleNameCommitted)
.OnVerifyTextChanged(this, &SAssetTileItem::HandleVerifyNameChanged)
.HighlightText(InArgs._HighlightText)
.IsSelected(InArgs._IsSelected)
.IsReadOnly(ThumbnailEditMode)
.Justification(ETextJustify::Center)
.LineBreakPolicy(FBreakIterator::CreateCamelCaseBreakIterator())
]
]
];
SetToolTip( CreateToolTipWidget() );
if(AssetItem.IsValid())
{
AssetItem->RenamedRequestEvent.BindSP( InlineRenameWidget.Get(), &SInlineEditableTextBlock::EnterEditingMode );
}
SetForceMipLevelsToBeResident(true);
// listen for asset loads so we can force mips to stream in if required
FCoreUObjectDelegates::OnAssetLoaded.AddSP(this, &SAssetViewItem::HandleAssetLoaded);
}
END_SLATE_FUNCTION_BUILD_OPTIMIZATION
void SAssetTileItem::OnAssetDataChanged()
{
SAssetViewItem::OnAssetDataChanged();
SetToolTip( CreateToolTipWidget() );
}
FOptionalSize SAssetTileItem::GetThumbnailBoxSize() const
{
return FOptionalSize( ItemWidth.Get() );
}
FOptionalSize SAssetTileItem::GetSCCImageSize() const
{
return GetThumbnailBoxSize().Get() * 0.2;
}
FSlateFontInfo SAssetTileItem::GetThumbnailFont() const
{
FOptionalSize ThumbSize = GetThumbnailBoxSize();
if ( ThumbSize.IsSet() )
{
float Size = ThumbSize.Get();
if ( Size < 50 )
{
const static FName SmallFontName("ContentBrowser.AssetTileViewNameFontVerySmall");
return FEditorStyle::GetFontStyle(SmallFontName);
}
else if ( Size < 85 )
{
const static FName SmallFontName("ContentBrowser.AssetTileViewNameFontSmall");
return FEditorStyle::GetFontStyle(SmallFontName);
}
}
const static FName RegularFont("ContentBrowser.AssetTileViewNameFont");
return FEditorStyle::GetFontStyle(RegularFont);
}
///////////////////////////////
// SAssetColumnItem
///////////////////////////////
/** Custom box for the Name column of an asset */
class SAssetColumnItemNameBox : public SCompoundWidget
{
public:
SLATE_BEGIN_ARGS( SAssetColumnItemNameBox ) {}
/** The color of the asset */
SLATE_ATTRIBUTE( FMargin, Padding )
/** The widget content presented in the box */
SLATE_DEFAULT_SLOT(FArguments, Content)
SLATE_END_ARGS()
~SAssetColumnItemNameBox() {}
void Construct( const FArguments& InArgs, const TSharedRef<SAssetColumnItem>& InOwnerAssetColumnItem )
{
OwnerAssetColumnItem = InOwnerAssetColumnItem;
ChildSlot
[
SNew(SBox)
.Padding(InArgs._Padding)
[
InArgs._Content.Widget
]
];
}
/** Forward the event to the view item that this name box belongs to */
virtual void OnToolTipClosing() override
{
if ( OwnerAssetColumnItem.IsValid() )
{
OwnerAssetColumnItem.Pin()->OnToolTipClosing();
}
}
private:
TWeakPtr<SAssetViewItem> OwnerAssetColumnItem;
};
void SAssetColumnItem::Construct( const FArguments& InArgs )
{
SAssetViewItem::Construct( SAssetViewItem::FArguments()
.AssetItem(InArgs._AssetItem)
.OnRenameBegin(InArgs._OnRenameBegin)
.OnRenameCommit(InArgs._OnRenameCommit)
.OnVerifyRenameCommit(InArgs._OnVerifyRenameCommit)
.OnItemDestroyed(InArgs._OnItemDestroyed)
.HighlightText(InArgs._HighlightText)
.OnAssetsDragDropped(InArgs._OnAssetsDragDropped)
.OnPathsDragDropped(InArgs._OnPathsDragDropped)
.OnFilesDragDropped(InArgs._OnFilesDragDropped)
.OnGetCustomAssetToolTip(InArgs._OnGetCustomAssetToolTip)
.OnVisualizeAssetToolTip(InArgs._OnVisualizeAssetToolTip)
.OnAssetToolTipClosing(InArgs._OnAssetToolTipClosing)
);
HighlightText = InArgs._HighlightText;
}
BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION
TSharedRef<SWidget> SAssetColumnItem::GenerateWidgetForColumn( const FName& ColumnName, FIsSelected InIsSelected )
{
TSharedPtr<SWidget> Content;
// A little right padding so text from this column does not run directly into text from the next.
static const FMargin ColumnItemPadding( 0, 0, 6, 0 );
if ( ColumnName == "Name" )
{
const FSlateBrush* IconBrush;
if(IsFolder())
{
if(AssetItem.IsValid() && StaticCastSharedPtr<FAssetViewFolder>(AssetItem)->bDeveloperFolder)
{
IconBrush = FEditorStyle::GetBrush("ContentBrowser.ColumnViewDeveloperFolderIcon");
}
else
{
IconBrush = FEditorStyle::GetBrush("ContentBrowser.ColumnViewFolderIcon");
}
}
else
{
IconBrush = FEditorStyle::GetBrush("ContentBrowser.ColumnViewAssetIcon");;
}
// Make icon overlays (eg, SCC and dirty status) a reasonable size in relation to the icon size (note: it is assumed this icon is square)
const float IconOverlaySize = IconBrush->ImageSize.X * 0.6f;
Content = SNew(SHorizontalBox)
.AddMetaData<FTagMetaData>(FTagMetaData(AssetItem->GetType() == EAssetItemType::Normal ? StaticCastSharedPtr<FAssetViewAsset>(AssetItem)->Data.ObjectPath : NAME_None))
// Icon
+SHorizontalBox::Slot()
.AutoWidth()
.Padding(0, 0, 4, 0)
[
SNew(SOverlay)
// The actual icon
+SOverlay::Slot()
[
SNew(SImage)
.Image( IconBrush )
.ColorAndOpacity(this, &SAssetColumnItem::GetAssetColor)
]
// Source control state
+SOverlay::Slot()
.HAlign(HAlign_Right)
.VAlign(VAlign_Top)
[
SNew(SBox)
.WidthOverride(IconOverlaySize)
.HeightOverride(IconOverlaySize)
[
SNew(SImage)
.Image(this, &SAssetColumnItem::GetSCCStateImage)
]
]
// Dirty state
+SOverlay::Slot()
.HAlign(HAlign_Left)
.VAlign(VAlign_Bottom)
[
SNew(SBox)
.WidthOverride(IconOverlaySize)
.HeightOverride(IconOverlaySize)
[
SNew(SImage)
.Image(this, &SAssetColumnItem::GetDirtyImage)
]
]
]
// Editable Name
+SHorizontalBox::Slot()
.AutoWidth()
[
SAssignNew(InlineRenameWidget, SInlineEditableTextBlock)
.Text( GetNameText() )
.OnBeginTextEdit(this, &SAssetColumnItem::HandleBeginNameChange)
.OnTextCommitted(this, &SAssetColumnItem::HandleNameCommitted)
.OnVerifyTextChanged(this, &SAssetColumnItem::HandleVerifyNameChanged)
.HighlightText(HighlightText)
.IsSelected(InIsSelected)
.IsReadOnly(ThumbnailEditMode)
];
if(AssetItem.IsValid())
{
AssetItem->RenamedRequestEvent.BindSP( InlineRenameWidget.Get(), &SInlineEditableTextBlock::EnterEditingMode );
}
return SNew( SAssetColumnItemNameBox, SharedThis(this) )
.Padding( ColumnItemPadding )
.ToolTip( CreateToolTipWidget() )
[
Content.ToSharedRef()
];
}
else if ( ColumnName == "Class" )
{
Content = SAssignNew(ClassText, STextBlock)
.ToolTipText( this, &SAssetColumnItem::GetAssetClassText )
.Text( GetAssetClassText() )
.HighlightText( HighlightText );
}
else if ( ColumnName == "Path" )
{
Content = SAssignNew(PathText, STextBlock)
.ToolTipText( this, &SAssetColumnItem::GetAssetPathText )
.Text( GetAssetPathText() )
.HighlightText( HighlightText );
}
else
{
Content = SNew(STextBlock)
.ToolTipText( TAttribute<FText>::Create( TAttribute<FText>::FGetter::CreateSP(this, &SAssetColumnItem::GetAssetTagText, ColumnName) ) )
.Text( TAttribute<FText>::Create( TAttribute<FText>::FGetter::CreateSP(this, &SAssetColumnItem::GetAssetTagText, ColumnName) ) );
}
return SNew(SBox)
.Padding( ColumnItemPadding )
[
Content.ToSharedRef()
];
}
END_SLATE_FUNCTION_BUILD_OPTIMIZATION
void SAssetColumnItem::OnAssetDataChanged()
{
SAssetViewItem::OnAssetDataChanged();
if ( ClassText.IsValid() )
{
ClassText->SetText( GetAssetClassText() );
}
if ( PathText.IsValid() )
{
PathText->SetText( GetAssetPathText() );
}
}
FString SAssetColumnItem::GetAssetNameToolTipText() const
{
if ( AssetItem.IsValid() )
{
if(AssetItem->GetType() == EAssetItemType::Folder)
{
FString Result = StaticCastSharedPtr<FAssetViewFolder>(AssetItem)->FolderName.ToString();
Result += TEXT("\n");
Result += LOCTEXT("FolderName", "Folder").ToString();
return Result;
}
else
{
const FString AssetName = StaticCastSharedPtr<FAssetViewAsset>(AssetItem)->Data.AssetName.ToString();
const FString AssetType = StaticCastSharedPtr<FAssetViewAsset>(AssetItem)->Data.AssetClass.ToString();
FString Result = AssetName;
Result += TEXT("\n");
Result += AssetType;
return Result;
}
}
else
{
return FString();
}
}
FText SAssetColumnItem::GetAssetPathText() const
{
if ( AssetItem.IsValid() )
{
if(AssetItem->GetType() != EAssetItemType::Folder)
{
return FText::FromName(StaticCastSharedPtr<FAssetViewAsset>(AssetItem)->Data.PackagePath);
}
else
{
return FText::FromString(StaticCastSharedPtr<FAssetViewFolder>(AssetItem)->FolderPath);
}
}
else
{
return FText();
}
}
FText SAssetColumnItem::GetAssetTagText(FName AssetRegistryTag) const
{
if ( AssetItem.IsValid() )
{
if(AssetItem->GetType() != EAssetItemType::Folder)
{
const FString* TagValue = StaticCastSharedPtr<FAssetViewAsset>(AssetItem)->Data.TagsAndValues.Find(AssetRegistryTag);
if ( TagValue != NULL )
{
return FText::FromString(*TagValue);
}
}
}
return FText();
}
#undef LOCTEXT_NAMESPACE