2015-04-22 09:39:09 -04:00
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
# include "DetailCustomizationsPrivatePCH.h"
# include "PostProcessSettingsCustomization.h"
# include "ObjectEditorUtils.h"
2015-06-22 18:03:15 -04:00
# include "LightPropagationVolumeBlendable.h"
# include "SWidgetSwitcher.h"
# include "Classes/Engine/BlendableInterface.h"
2015-04-22 09:39:09 -04:00
# define LOCTEXT_NAMESPACE "PostProcessSettingsCustomization"
void FPostProcessSettingsCustomization : : CustomizeChildren ( TSharedRef < IPropertyHandle > StructPropertyHandle , class IDetailChildrenBuilder & StructBuilder , IPropertyTypeCustomizationUtils & StructCustomizationUtils )
{
2015-06-22 18:03:15 -04:00
TMap < FName , IDetailGroup * > CategoryNameToGroupMap ;
2015-04-22 09:39:09 -04:00
uint32 NumChildren = 0 ;
FPropertyAccess : : Result Result = StructPropertyHandle - > GetNumChildren ( NumChildren ) ;
2015-06-22 18:03:15 -04:00
UProperty * Prop = StructPropertyHandle - > GetProperty ( ) ;
UStructProperty * StructProp = Cast < UStructProperty > ( Prop ) ;
// a category with this name should be one level higher, should be "PostProcessSettings"
FName ClassName = StructProp - > Struct - > GetFName ( ) ;
2015-04-22 09:39:09 -04:00
if ( Result = = FPropertyAccess : : Success & & NumChildren > 0 )
{
for ( uint32 ChildIndex = 0 ; ChildIndex < NumChildren ; + + ChildIndex )
{
TSharedPtr < IPropertyHandle > ChildHandle = StructPropertyHandle - > GetChildHandle ( ChildIndex ) ;
if ( ChildHandle . IsValid ( ) & & ChildHandle - > GetProperty ( ) )
{
UProperty * Property = ChildHandle - > GetProperty ( ) ;
2015-06-22 18:03:15 -04:00
FName Category = FObjectEditorUtils : : GetCategoryFName ( Property ) ;
2015-04-22 09:39:09 -04:00
2015-06-22 18:03:15 -04:00
if ( Category = = ClassName )
2015-04-22 09:39:09 -04:00
{
2015-06-22 18:03:15 -04:00
// Some elements should be outside of the categories, they need to specify the struct nama as category
StructBuilder . AddChildProperty ( ChildHandle . ToSharedRef ( ) ) ;
2015-04-22 09:39:09 -04:00
}
2015-06-22 18:03:15 -04:00
else
{
IDetailGroup * Group = CategoryNameToGroupMap . FindRef ( Category ) ;
if ( ! Group )
{
Group = & StructBuilder . AddChildGroup ( Category , FText : : FromString ( FName : : NameToDisplayString ( Category . ToString ( ) , false ) ) ) ;
CategoryNameToGroupMap . Add ( Category , Group ) ;
}
2015-04-22 09:39:09 -04:00
2015-06-22 18:03:15 -04:00
Group - > AddPropertyRow ( ChildHandle . ToSharedRef ( ) ) ;
}
2015-04-22 09:39:09 -04:00
}
}
}
}
2015-06-22 18:03:15 -04:00
2015-04-22 09:39:09 -04:00
void FPostProcessSettingsCustomization : : CustomizeHeader ( TSharedRef < IPropertyHandle > StructPropertyHandle , class FDetailWidgetRow & HeaderRow , IPropertyTypeCustomizationUtils & StructCustomizationUtils )
{
HeaderRow . NameContent ( )
[
StructPropertyHandle - > CreatePropertyNameWidget ( )
] ;
HeaderRow . ValueContent ( )
[
StructPropertyHandle - > CreatePropertyValueWidget ( )
] ;
}
2015-06-22 18:03:15 -04:00
void FWeightedBlendableCustomization : : AddDirectAsset ( TSharedRef < IPropertyHandle > StructPropertyHandle , UPackage * Package , TSharedPtr < IPropertyHandle > Weight , TSharedPtr < IPropertyHandle > Value )
{
Weight - > SetValue ( 1.0f ) ;
{
TArray < UObject * > Objects ;
StructPropertyHandle - > GetOuterObjects ( Objects ) ;
TArray < FString > Values ;
for ( TArray < UObject * > : : TConstIterator It = Objects . CreateConstIterator ( ) ; It ; It + + )
{
UObject * Obj = * It ;
const UObject * NewObj = NewObject < ULightPropagationVolumeBlendable > ( Obj ) ;
FString Str = NewObj - > GetPathName ( ) ;
Values . Add ( Str ) ;
}
Value - > SetPerObjectValues ( Values ) ;
}
}
void FWeightedBlendableCustomization : : AddIndirectAsset ( TSharedPtr < IPropertyHandle > Weight )
{
Weight - > SetValue ( 1.0f ) ;
}
EVisibility FWeightedBlendableCustomization : : IsWeightVisible ( TSharedPtr < IPropertyHandle > Weight ) const
{
float WeightValue = 1.0f ;
Weight - > GetValue ( WeightValue ) ;
return ( WeightValue > = 0 ) ? EVisibility : : Visible : EVisibility : : Hidden ;
}
FText FWeightedBlendableCustomization : : GetDirectAssetName ( TSharedPtr < IPropertyHandle > Value ) const
{
UObject * RefObject = 0 ;
Value - > GetValue ( RefObject ) ;
check ( RefObject ) ;
return FText : : FromString ( RefObject - > GetFullName ( ) ) ;
}
FReply FWeightedBlendableCustomization : : JumpToDirectAsset ( TSharedPtr < IPropertyHandle > Value )
{
UObject * RefObject = 0 ;
Value - > GetValue ( RefObject ) ;
FAssetEditorManager : : Get ( ) . OpenEditorForAsset ( RefObject ) ;
return FReply : : Handled ( ) ;
}
TSharedRef < SWidget > FWeightedBlendableCustomization : : GenerateContentWidget ( TSharedRef < IPropertyHandle > StructPropertyHandle , UPackage * Package , TSharedPtr < IPropertyHandle > Weight , TSharedPtr < IPropertyHandle > Value )
{
FMenuBuilder MenuBuilder ( true , NULL ) ;
{
/*
for ( TObjectIterator < UClass > It ; It ; + + It )
{
if ( It - > IsChildOf ( UFactory : : StaticClass ( ) ) )
if ( It - > IsChildOf ( UBlendableInterface : : StaticClass ( ) ) )
*/
// todo: iterate through all UFactories that create UClasses with UBlendableInterface
{
FUIAction Direct2 ( FExecuteAction : : CreateSP ( this , & FWeightedBlendableCustomization : : AddDirectAsset , StructPropertyHandle , Package , Weight , Value ) ) ;
MenuBuilder . AddMenuEntry ( LOCTEXT ( " Blendable_DirectAsset2 " , " Light Propagation Volume Blendable " ) ,
LOCTEXT ( " Blendable_DirectAsset2h " , " references Light Propagation Volume Blendable (owned by the containing object) " ) , FSlateIcon ( ) , Direct2 ) ;
}
MenuBuilder . AddMenuSeparator ( ) ;
FUIAction Indirect ( FExecuteAction : : CreateSP ( this , & FWeightedBlendableCustomization : : AddIndirectAsset , Weight ) ) ;
MenuBuilder . AddMenuEntry ( LOCTEXT ( " Blendable_IndirectAsset " , " Asset reference " ) ,
LOCTEXT ( " Blendable_IndirectAsseth " , " reference a Blendable asset (owned by a content package), e.g. material with Post Process domain " ) , FSlateIcon ( ) , Indirect ) ;
}
TSharedRef < SWidgetSwitcher > Switcher = SNew ( SWidgetSwitcher )
. WidgetIndex ( this , & FWeightedBlendableCustomization : : ComputeSwitcherIndex , StructPropertyHandle , Package , Weight , Value ) ;
Switcher - > AddSlot ( )
[
SNew ( SComboButton )
. ButtonContent ( )
[
SNew ( STextBlock )
. Text ( LOCTEXT ( " Blendable_ChooseElement " , " Choose " ) )
]
. ContentPadding ( FMargin ( 6.0 , 2.0 ) )
. MenuContent ( )
[
MenuBuilder . MakeWidget ( )
]
] ;
Switcher - > AddSlot ( )
[
SNew ( SButton )
. ContentPadding ( FMargin ( 0 , 0 ) )
. Text ( this , & FWeightedBlendableCustomization : : GetDirectAssetName , Value )
. OnClicked ( this , & FWeightedBlendableCustomization : : JumpToDirectAsset , Value )
] ;
Switcher - > AddSlot ( )
[
SNew ( SObjectPropertyEntryBox )
. PropertyHandle ( Value )
] ;
return Switcher ;
}
int32 FWeightedBlendableCustomization : : ComputeSwitcherIndex ( TSharedRef < IPropertyHandle > StructPropertyHandle , UPackage * Package , TSharedPtr < IPropertyHandle > Weight , TSharedPtr < IPropertyHandle > Value ) const
{
float WeightValue = 1.0f ;
UObject * RefObject = 0 ;
Weight - > GetValue ( WeightValue ) ;
Value - > GetValue ( RefObject ) ;
if ( RefObject )
{
UPackage * PropPackage = RefObject - > GetOutermost ( ) ;
return ( PropPackage = = Package ) ? 1 : 2 ;
}
else
{
return ( WeightValue < 0.0f ) ? 0 : 2 ;
}
}
void FWeightedBlendableCustomization : : CustomizeChildren ( TSharedRef < class IPropertyHandle > StructPropertyHandle , class IDetailChildrenBuilder & StructBuilder , IPropertyTypeCustomizationUtils & StructCustomizationUtils )
{
// we don't have children but this is a pure virtual so we need to override
}
void FWeightedBlendableCustomization : : CustomizeHeader ( TSharedRef < IPropertyHandle > StructPropertyHandle , class FDetailWidgetRow & HeaderRow , IPropertyTypeCustomizationUtils & StructCustomizationUtils )
{
TSharedPtr < IPropertyHandle > SharedWeightProp ;
{
TSharedPtr < IPropertyHandle > ChildHandle = StructPropertyHandle - > GetChildHandle ( FName ( TEXT ( " Weight " ) ) ) ;
if ( ChildHandle . IsValid ( ) & & ChildHandle - > GetProperty ( ) )
{
SharedWeightProp = ChildHandle ;
}
}
TSharedPtr < IPropertyHandle > SharedValueProp ;
{
TSharedPtr < IPropertyHandle > ChildHandle = StructPropertyHandle - > GetChildHandle ( FName ( TEXT ( " Object " ) ) ) ;
if ( ChildHandle . IsValid ( ) & & ChildHandle - > GetProperty ( ) )
{
SharedValueProp = ChildHandle ;
}
}
float WeightValue = 1.0f ;
UObject * RefObject = 0 ;
SharedWeightProp - > GetValue ( WeightValue ) ;
SharedValueProp - > GetValue ( RefObject ) ;
UPackage * StructPackage = 0 ;
{
const TSharedPtr < IPropertyHandle > ParentHandle = StructPropertyHandle - > GetParentHandle ( ) ;
TArray < UObject * > Objects ;
StructPropertyHandle - > GetOuterObjects ( Objects ) ;
for ( TArray < UObject * > : : TConstIterator It = Objects . CreateConstIterator ( ) ; It ; It + + )
{
UObject * ref = * It ;
if ( StructPackage )
{
// does this mean we have to deal with multiple levels? The code here is not ready for that
check ( StructPackage = = ref - > GetOutermost ( ) ) ;
}
StructPackage = ref - > GetOutermost ( ) ;
}
}
HeaderRow . NameContent ( )
[
SNew ( SHorizontalBox )
. Visibility ( this , & FWeightedBlendableCustomization : : IsWeightVisible , SharedWeightProp )
+ SHorizontalBox : : Slot ( )
[
SNew ( SBox )
. MinDesiredWidth ( 44.0f )
. MaxDesiredWidth ( 44.0f )
[
SharedWeightProp - > CreatePropertyValueWidget ( )
]
]
] ;
HeaderRow . ValueContent ( )
[
SNew ( SHorizontalBox )
+ SHorizontalBox : : Slot ( )
[
GenerateContentWidget ( StructPropertyHandle , StructPackage , SharedWeightProp , SharedValueProp )
]
] ;
}
2015-04-22 09:39:09 -04:00
# undef LOCTEXT_NAMESPACE