2015-06-25 20:02:03 -04:00
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
# include "DetailCustomizationsPrivatePCH.h"
# include "TextCustomization.h"
2015-07-30 20:39:29 -04:00
# include "IPropertyUtilities.h"
2015-06-25 20:02:03 -04:00
namespace
{
class STextPropertyWidget : public SCompoundWidget
{
2015-07-30 16:42:30 -04:00
SLATE_BEGIN_ARGS ( STextPropertyWidget )
: _Font ( FEditorStyle : : GetFontStyle ( TEXT ( " PropertyWindow.NormalFont " ) ) )
{ }
SLATE_ATTRIBUTE ( FSlateFontInfo , Font )
2015-06-25 20:02:03 -04:00
SLATE_END_ARGS ( )
public :
2015-07-30 16:42:30 -04:00
void Construct ( const FArguments & Arguments , const TSharedRef < IPropertyHandle > & InPropertyHandle , const TSharedPtr < IPropertyUtilities > & InPropertyUtilities ) ;
void GetDesiredWidth ( float & OutMinDesiredWidth , float & OutMaxDesiredWidth ) ;
bool SupportsKeyboardFocus ( ) const ;
FReply OnFocusReceived ( const FGeometry & MyGeometry , const FFocusEvent & InFocusEvent ) ;
void Tick ( const FGeometry & AllottedGeometry , const double InCurrentTime , const float InDeltaTime ) ;
bool CanEdit ( ) const ;
bool IsReadOnly ( ) const ;
2015-06-25 20:02:03 -04:00
private :
TSharedPtr < IPropertyHandle > PropertyHandle ;
2015-07-30 16:42:30 -04:00
TSharedPtr < IPropertyUtilities > PropertyUtilities ;
TSharedPtr < class SWidget > PrimaryWidget ;
TSharedPtr < SMultiLineEditableTextBox > MultiLineWidget ;
TSharedPtr < SEditableTextBox > SingleLineWidget ;
TOptional < float > PreviousHeight ;
bool bIsMultiLine ;
2015-06-25 20:02:03 -04:00
} ;
2015-07-30 16:42:30 -04:00
void STextPropertyWidget : : Construct ( const FArguments & InArgs , const TSharedRef < IPropertyHandle > & InPropertyHandle , const TSharedPtr < IPropertyUtilities > & InPropertyUtilities )
2015-06-25 20:02:03 -04:00
{
PropertyHandle = InPropertyHandle ;
2015-07-30 16:42:30 -04:00
PropertyUtilities = InPropertyUtilities ;
2015-06-25 20:02:03 -04:00
const auto & GetTextValue = [ this ] ( ) - > FText
{
FText TextValue ;
TArray < const void * > RawData ;
PropertyHandle - > AccessRawData ( RawData ) ;
if ( RawData . Num ( ) = = 1 )
{
const FText * RawDatum = reinterpret_cast < const FText * > ( RawData . Top ( ) ) ;
if ( RawDatum )
{
TextValue = * RawDatum ;
}
}
else if ( RawData . Num ( ) > 1 )
{
TextValue = NSLOCTEXT ( " PropertyEditor " , " MultipleValues " , " Multiple Values " ) ;
}
else
{
TextValue = FText : : GetEmpty ( ) ;
}
return TextValue ;
} ;
const auto & OnTextCommitted = [ this ] ( const FText & NewText , ETextCommit : : Type CommitInfo )
{
TArray < void * > RawData ;
PropertyHandle - > AccessRawData ( RawData ) ;
2015-07-30 15:45:22 -04:00
if ( RawData . Num ( ) > 0 )
{
PropertyHandle - > NotifyPreChange ( ) ;
for ( void * const RawDatum : RawData )
{
FText & PropertyValue = * ( reinterpret_cast < FText * const > ( RawDatum ) ) ;
// FText::FromString on the result of FText::ToString is intentional. For now, we want to nuke any namespace/key info and let it get regenerated from scratch,
// rather than risk adopting whatever came through some chain of calls. This will be replaced when preserving of identity is implemented.
PropertyValue = FText : : FromString ( NewText . ToString ( ) ) ;
}
PropertyHandle - > NotifyPostChange ( ) ;
PropertyHandle - > NotifyFinishedChangingProperties ( ) ;
2015-06-25 20:02:03 -04:00
}
} ;
2015-07-30 16:42:30 -04:00
TSharedPtr < SHorizontalBox > HorizontalBox ;
bIsMultiLine = PropertyHandle - > GetBoolMetaData ( " MultiLine " ) ;
if ( bIsMultiLine )
{
ChildSlot
[
SAssignNew ( HorizontalBox , SHorizontalBox )
+ SHorizontalBox : : Slot ( )
. FillWidth ( 1.0f )
[
SAssignNew ( MultiLineWidget , SMultiLineEditableTextBox )
. Text_Lambda ( GetTextValue )
. Font ( InArgs . _Font )
. SelectAllTextWhenFocused ( false )
. ClearKeyboardFocusOnCommit ( false )
. OnTextCommitted_Lambda ( OnTextCommitted )
. SelectAllTextOnCommit ( false )
. IsReadOnly ( this , & STextPropertyWidget : : IsReadOnly )
. AutoWrapText ( true )
. ModiferKeyForNewLine ( EModifierKey : : Shift )
]
] ;
PrimaryWidget = MultiLineWidget ;
}
else
{
ChildSlot
[
SAssignNew ( HorizontalBox , SHorizontalBox )
+ SHorizontalBox : : Slot ( )
. FillWidth ( 1.0f )
[
SAssignNew ( SingleLineWidget , SEditableTextBox )
. Text_Lambda ( GetTextValue )
. Font ( InArgs . _Font )
. SelectAllTextWhenFocused ( true )
. ClearKeyboardFocusOnCommit ( false )
. OnTextCommitted_Lambda ( OnTextCommitted )
. SelectAllTextOnCommit ( true )
. IsReadOnly ( this , & STextPropertyWidget : : IsReadOnly )
]
] ;
PrimaryWidget = SingleLineWidget ;
}
SetEnabled ( TAttribute < bool > ( this , & STextPropertyWidget : : CanEdit ) ) ;
}
void STextPropertyWidget : : GetDesiredWidth ( float & OutMinDesiredWidth , float & OutMaxDesiredWidth )
{
if ( bIsMultiLine )
{
OutMinDesiredWidth = 250.0f ;
}
else
{
OutMinDesiredWidth = 125.0f ;
}
OutMaxDesiredWidth = 600.0f ;
}
bool STextPropertyWidget : : SupportsKeyboardFocus ( ) const
{
return PrimaryWidget . IsValid ( ) & & PrimaryWidget - > SupportsKeyboardFocus ( ) ;
}
FReply STextPropertyWidget : : OnFocusReceived ( const FGeometry & MyGeometry , const FFocusEvent & InFocusEvent )
{
// Forward keyboard focus to our editable text widget
return FReply : : Handled ( ) . SetUserFocus ( PrimaryWidget . ToSharedRef ( ) , InFocusEvent . GetCause ( ) ) ;
}
void STextPropertyWidget : : Tick ( const FGeometry & AllottedGeometry , const double InCurrentTime , const float InDeltaTime )
{
const float CurrentHeight = AllottedGeometry . GetLocalSize ( ) . Y ;
if ( bIsMultiLine & & PreviousHeight . IsSet ( ) & & PreviousHeight . GetValue ( ) ! = CurrentHeight & & PropertyUtilities . IsValid ( ) )
{
PropertyUtilities - > RequestRefresh ( ) ;
}
PreviousHeight = CurrentHeight ;
}
bool STextPropertyWidget : : CanEdit ( ) const
{
return PropertyHandle . IsValid ( ) ? ! PropertyHandle - > IsEditConst ( ) : true ;
}
bool STextPropertyWidget : : IsReadOnly ( ) const
{
return ! CanEdit ( ) ;
2015-06-25 20:02:03 -04:00
}
}
void FTextCustomization : : CustomizeHeader ( TSharedRef < class IPropertyHandle > InPropertyHandle , class FDetailWidgetRow & HeaderRow , IPropertyTypeCustomizationUtils & PropertyTypeCustomizationUtils )
{
HeaderRow . FilterString ( InPropertyHandle - > GetPropertyDisplayName ( ) )
. NameContent ( )
[
InPropertyHandle - > CreatePropertyNameWidget ( )
]
. ValueContent ( )
[
2015-07-30 16:42:30 -04:00
SNew ( STextPropertyWidget , InPropertyHandle , PropertyTypeCustomizationUtils . GetPropertyUtilities ( ) )
2015-06-25 20:02:03 -04:00
] ;
}
void FTextCustomization : : CustomizeChildren ( TSharedRef < class IPropertyHandle > InPropertyHandle , class IDetailChildrenBuilder & StructBuilder , IPropertyTypeCustomizationUtils & PropertyTypeCustomizationUtils )
{
}