// 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 >& 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(TEXT("AssetRegistry")); TArray SelectedAssets; for ( auto ItemIt = SelectedItems.CreateConstIterator(); ItemIt; ++ItemIt) { const TSharedPtr& 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(Item)->FolderPath); // Add assets found in the asset registry AssetRegistryModule.Get().GetAssets(Filter, SelectedAssets); } else { SelectedAssets.Add(StaticCastSharedPtr(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>::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>::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>::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 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(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 Operation = DragDropEvent.GetOperation(); if (Operation.IsValid()) { Operation->SetCursorOverride(TOptional()); if (Operation->IsOfType()) { TSharedPtr DragDropOp = StaticCastSharedPtr(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 Operation = DragDropEvent.GetOperation(); if (!Operation.IsValid()) { return FReply::Unhandled(); } if (Operation->IsOfType()) { TSharedPtr DragDropOp = StaticCastSharedPtr(Operation); OnFilesDragDropped.ExecuteIfBound(DragDropOp->GetFiles(), StaticCastSharedPtr(AssetItem)->FolderPath); return FReply::Handled(); } else if (Operation->IsOfType()) { TSharedPtr DragDropOp = StaticCastSharedPtr(Operation); OnPathsDragDropped.ExecuteIfBound(DragDropOp->PathNames, StaticCastSharedPtr(AssetItem)->FolderPath); return FReply::Handled(); } else if (Operation->IsOfType()) { TSharedPtr DragDropOp = StaticCastSharedPtr(Operation); OnAssetsDragDropped.ExecuteIfBound(DragDropOp->AssetData, StaticCastSharedPtr(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(NULL, *CachedPackageName); UpdatePackageDirtyState(); AssetTypeActions.Reset(); if ( AssetItem->GetType() != EAssetItemType::Folder ) { UClass* AssetClass = FindObject(ANY_PACKAGE, *StaticCastSharedPtr(AssetItem)->Data.AssetClass.ToString()); if (AssetClass) { FAssetToolsModule& AssetToolsModule = FModuleManager::LoadModuleChecked(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(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 SAssetViewItem::CreateToolTipWidget() const { if ( AssetItem.IsValid() ) { if(OnGetCustomAssetToolTip.IsBound() && AssetItem->GetType() != EAssetItemType::Folder) { FAssetData& AssetData = StaticCastSharedPtr(AssetItem)->Data; return OnGetCustomAssetToolTip.Execute(AssetData); } else if(AssetItem->GetType() != EAssetItemType::Folder) { const FAssetData& AssetData = StaticCastSharedPtr(AssetItem)->Data; UClass* AssetClass = FindObject(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 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 MetadataMap; TSet ShownTags; if ( AssetClass != NULL && AssetClass->GetDefaultObject() != NULL ) { AssetClass->GetDefaultObject()->GetAssetRegistryTagMetadata(MetadataMap); TArray 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(AssetClass, TagIt.Key())) { DisplayName = Field->GetDisplayNameText(); // Strip off enum prefixes if they exist if (UByteProperty* ByteProperty = Cast(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 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(AssetItem)->FolderName; const FString& FolderPath = StaticCastSharedPtr(AssetItem)->FolderPath; // Create a box to hold every line of info in the body of the tooltip TSharedRef 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(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(AssetItem)->Data; return AssetTypeActions.Pin()->GetAssetDescription(AssetData); } } return FText::GetEmpty(); } void SAssetViewItem::AddToToolTipInfoBox(const TSharedRef& 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(AssetItem)->Data.PackageName.ToString(); CachedPackageFileName = SourceControlHelpers::PackageFilename(CachedPackageName); } else { CachedPackageName = StaticCastSharedPtr(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(AssetItem)->Data.AssetName); } else { return StaticCastSharedPtr(AssetItem)->FolderName; } } return FText(); } FSlateColor SAssetViewItem::GetAssetColor() const { if(AssetItem.IsValid()) { if(AssetItem->GetType() == EAssetItemType::Folder) { const TSharedPtr Color = ContentBrowserUtils::LoadColor( StaticCastSharedPtr(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(AssetItem)->Data; if(AssetData.IsValid() && AssetData.IsAssetLoaded()) { UObject* Asset = AssetData.GetAsset(); if(Asset != nullptr) { if(UTexture2D* Texture2D = Cast(Asset)) { Texture2D->bForceMiplevelsToBeResident = bForce; } else if(UMaterial* Material = Cast(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(AssetItem)->Data; if(AssetData.IsValid() && AssetData.IsAssetLoaded()) { if(InAsset == AssetData.GetAsset()) { SetForceMipLevelsToBeResident(true); } } } } } bool SAssetViewItem::OnVisualizeTooltip(const TSharedPtr& TooltipContent) { if(OnVisualizeAssetToolTip.IsBound() && TooltipContent.IsValid() && AssetItem->GetType() != EAssetItemType::Folder) { FAssetData& AssetData = StaticCastSharedPtr(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 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(AssetItem->GetType() == EAssetItemType::Normal ? StaticCastSharedPtr(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 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(AssetItem)->bDeveloperFolder; } } ChildSlot [ SNew(SBorder) .BorderImage(this, &SAssetViewItem::GetBorderImage) .Padding(0) .AddMetaData(FTagMetaData((AssetItem->GetType() == EAssetItemType::Normal) ? StaticCastSharedPtr(AssetItem)->Data.ObjectPath : ((AssetItem->GetType() == EAssetItemType::Folder) ? FName(*StaticCastSharedPtr(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& 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 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 SAssetColumnItem::GenerateWidgetForColumn( const FName& ColumnName, FIsSelected InIsSelected ) { TSharedPtr 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(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(AssetItem->GetType() == EAssetItemType::Normal ? StaticCastSharedPtr(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::Create( TAttribute::FGetter::CreateSP(this, &SAssetColumnItem::GetAssetTagText, ColumnName) ) ) .Text( TAttribute::Create( TAttribute::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(AssetItem)->FolderName.ToString(); Result += TEXT("\n"); Result += LOCTEXT("FolderName", "Folder").ToString(); return Result; } else { const FString AssetName = StaticCastSharedPtr(AssetItem)->Data.AssetName.ToString(); const FString AssetType = StaticCastSharedPtr(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(AssetItem)->Data.PackagePath); } else { return FText::FromString(StaticCastSharedPtr(AssetItem)->FolderPath); } } else { return FText(); } } FText SAssetColumnItem::GetAssetTagText(FName AssetRegistryTag) const { if ( AssetItem.IsValid() ) { if(AssetItem->GetType() != EAssetItemType::Folder) { const FString* TagValue = StaticCastSharedPtr(AssetItem)->Data.TagsAndValues.Find(AssetRegistryTag); if ( TagValue != NULL ) { return FText::FromString(*TagValue); } } } return FText(); } #undef LOCTEXT_NAMESPACE