You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
TTP# 335070 - Add GUI based way to specify additional non-asset files or paths to package CookCommandlet now uses the project settings to work out which additional directories it should cook (this removes the need for the editor to pass this information to that UAT via the command line). I've left the COOKDIR option in the UAT/CookCommandlet as, while non of our projects seem to be using it, I'm not comfortable removing it in case any scripts are using it. CopyBuildToStagingDirectory also uses these project settings to work out which additional directories it should stage when producing the staging manifest (these are split into UFS and non-UFS directories). This allows users to define additional directories in the editor (or directly in the settings file) which will always be staged regardless of how UAT is invoked. All of these paths are specified in the settings file as relative to the project Content directory, and the editor will enforce this fact when using the directory picker. Also mirrored the meta-data interface from UField on IPropertyHandle. This takes care of accessing the meta-data from the correct property, even when you're accessing an element inside an array (MattK approved!). ReviewedBy Thomas.Sarkanen, Robert.Manuszewski, Max.Preussner [CL 2088172 by Jamie Dale in Main branch]
93 lines
3.1 KiB
C++
93 lines
3.1 KiB
C++
// Copyright 1998-2014 Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "DetailCustomizationsPrivatePCH.h"
|
|
#include "StringAssetReferenceCustomization.h"
|
|
#include "AssetData.h"
|
|
|
|
void FStringAssetReferenceCustomization::CustomizeStructHeader( TSharedRef<IPropertyHandle> InStructPropertyHandle, FDetailWidgetRow& HeaderRow, IStructCustomizationUtils& StructCustomizationUtils )
|
|
{
|
|
StructPropertyHandle = InStructPropertyHandle;
|
|
|
|
FString ClassFilterString = StructPropertyHandle->GetMetaData("AllowedClasses");
|
|
if( !ClassFilterString.IsEmpty() )
|
|
{
|
|
TArray<FString> CustomClassFilterNames;
|
|
ClassFilterString.ParseIntoArray(&CustomClassFilterNames, TEXT(","), true);
|
|
|
|
for(auto It = CustomClassFilterNames.CreateConstIterator(); It; ++It)
|
|
{
|
|
const FString& ClassName = *It;
|
|
|
|
UClass* Class = FindObject<UClass>(ANY_PACKAGE, *ClassName);
|
|
if(!Class)
|
|
{
|
|
Class = LoadObject<UClass>(nullptr, *ClassName);
|
|
}
|
|
if(Class)
|
|
{
|
|
CustomClassFilters.Add(Class);
|
|
}
|
|
}
|
|
}
|
|
|
|
bExactClass = StructPropertyHandle->GetBoolMetaData("ExactClass");
|
|
|
|
FOnShouldFilterAsset AssetFilter;
|
|
UClass* ClassFilter = UObject::StaticClass();
|
|
if(CustomClassFilters.Num() == 1 && !bExactClass)
|
|
{
|
|
// If we only have one class to filter on, set it as the class type filter rather than use a filter callback
|
|
// We can only do this if we don't need an exact match, as the class filter also allows derived types
|
|
// The class filter is much faster than the callback as we're not performing two different sets of type tests
|
|
// (one against UObject, one against the actual type)
|
|
ClassFilter = CustomClassFilters[0];
|
|
}
|
|
else if(CustomClassFilters.Num() > 0)
|
|
{
|
|
// Only bind the filter if we have classes that need filtering
|
|
AssetFilter.BindSP(this, &FStringAssetReferenceCustomization::OnShouldFilterAsset);
|
|
}
|
|
|
|
// Can the field be cleared
|
|
const bool bAllowClear = !(StructPropertyHandle->GetMetaDataProperty()->PropertyFlags & CPF_NoClear);
|
|
|
|
HeaderRow
|
|
.NameContent()
|
|
[
|
|
InStructPropertyHandle->CreatePropertyNameWidget()
|
|
]
|
|
.ValueContent()
|
|
.MinDesiredWidth(250.0f)
|
|
.MaxDesiredWidth(0.0f)
|
|
[
|
|
// Add an object entry box. Even though this isn't an object entry, we will simulate one
|
|
SNew( SObjectPropertyEntryBox )
|
|
.PropertyHandle( InStructPropertyHandle )
|
|
.ThumbnailPool( StructCustomizationUtils.GetThumbnailPool() )
|
|
.AllowedClass( ClassFilter )
|
|
.OnShouldFilterAsset( AssetFilter )
|
|
.AllowClear( bAllowClear )
|
|
];
|
|
}
|
|
|
|
void FStringAssetReferenceCustomization::CustomizeStructChildren(TSharedRef<IPropertyHandle> InStructPropertyHandle, IDetailChildrenBuilder& StructBuilder, IStructCustomizationUtils& StructCustomizationUtils)
|
|
{
|
|
}
|
|
|
|
bool FStringAssetReferenceCustomization::OnShouldFilterAsset( const FAssetData& InAssetData ) const
|
|
{
|
|
// Only bound if we have classes to filter on, so we don't need to test for an empty array here
|
|
UClass* const AssetClass = InAssetData.GetClass();
|
|
for(auto It = CustomClassFilters.CreateConstIterator(); It; ++It)
|
|
{
|
|
UClass* const FilterClass = *It;
|
|
const bool bMatchesFilter = (bExactClass) ? AssetClass == FilterClass : AssetClass->IsChildOf(FilterClass);
|
|
if(bMatchesFilter)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|