2019-12-26 15:33:43 -05:00
// Copyright Epic Games, Inc. All Rights Reserved.
2018-07-13 06:25:54 -04:00
# include "MovieSceneEventCustomization.h"
2023-02-02 18:47:18 -05:00
# include "MovieScene.h"
2023-03-20 12:05:06 -04:00
# include "MovieSceneDirectorBlueprintUtils.h"
# include "MovieSceneEventUtils.h"
2018-07-13 06:25:54 -04:00
# include "MovieSceneSequence.h"
2023-03-20 12:05:06 -04:00
# include "MovieSceneSequenceEditor.h"
2018-07-13 06:25:54 -04:00
2023-03-20 12:05:06 -04:00
# include "Channels/MovieSceneEvent.h"
2018-07-13 06:25:54 -04:00
# include "PropertyHandle.h"
2023-03-20 12:05:06 -04:00
# include "Sections/MovieSceneEventSectionBase.h"
# include "Tracks/MovieSceneEventTrack.h"
2018-07-13 06:25:54 -04:00
2019-10-01 20:41:42 -04:00
# include "K2Node_CustomEvent.h"
2018-07-13 06:25:54 -04:00
# include "Kismet2/BlueprintEditorUtils.h"
2022-05-09 13:12:28 -04:00
# include "Styling/AppStyle.h"
2018-07-13 06:25:54 -04:00
# include "EditorFontGlyphs.h"
# define LOCTEXT_NAMESPACE "MovieSceneEventCustomization"
TSharedRef < IPropertyTypeCustomization > FMovieSceneEventCustomization : : MakeInstance ( )
{
return MakeShared < FMovieSceneEventCustomization > ( ) ;
}
TSharedRef < IPropertyTypeCustomization > FMovieSceneEventCustomization : : MakeInstance ( UMovieSceneSection * InSection )
{
TSharedRef < FMovieSceneEventCustomization > Custo = MakeShared < FMovieSceneEventCustomization > ( ) ;
Custo - > WeakExternalSection = InSection ;
return Custo ;
}
void FMovieSceneEventCustomization : : GetEditObjects ( TArray < UObject * > & OutObjects ) const
{
UMovieSceneEventSectionBase * ExternalSection = Cast < UMovieSceneEventSectionBase > ( WeakExternalSection . Get ( ) ) ;
if ( ExternalSection )
{
OutObjects . Add ( ExternalSection ) ;
}
else
{
2023-03-20 12:05:06 -04:00
GetPropertyHandle ( ) - > GetOuterObjects ( OutObjects ) ;
2018-07-13 06:25:54 -04:00
}
}
2023-03-20 12:05:06 -04:00
void FMovieSceneEventCustomization : : GetPayloadVariables ( UObject * EditObject , void * RawData , FPayloadVariableMap & OutPayloadVariables ) const
2018-07-13 06:25:54 -04:00
{
2023-03-20 12:05:06 -04:00
const FMovieSceneEvent * EntryPoint = static_cast < FMovieSceneEvent * > ( RawData ) ;
for ( const TPair < FName , FMovieSceneEventPayloadVariable > & Pair : EntryPoint - > PayloadVariables )
2019-10-01 20:41:42 -04:00
{
2023-09-12 05:10:23 -04:00
OutPayloadVariables . Add ( Pair . Key , FMovieSceneDirectorBlueprintVariableValue { Pair . Value . ObjectValue , Pair . Value . Value } ) ;
2019-10-01 20:41:42 -04:00
}
2018-07-13 06:25:54 -04:00
}
2023-09-12 05:10:23 -04:00
bool FMovieSceneEventCustomization : : SetPayloadVariable ( UObject * EditObject , void * RawData , FName FieldName , const FMovieSceneDirectorBlueprintVariableValue & NewVariableValue )
2018-07-13 06:25:54 -04:00
{
2023-03-20 12:05:06 -04:00
UMovieSceneEventSectionBase * EventSection = Cast < UMovieSceneEventSectionBase > ( EditObject ) ;
FMovieSceneEvent * EntryPoint = static_cast < FMovieSceneEvent * > ( RawData ) ;
if ( ! EventSection | | ! EntryPoint )
2018-07-13 06:25:54 -04:00
{
2023-03-20 12:05:06 -04:00
return false ;
2018-07-13 06:25:54 -04:00
}
2023-03-20 12:05:06 -04:00
EventSection - > Modify ( ) ;
2019-10-01 20:41:42 -04:00
2023-03-20 12:05:06 -04:00
FMovieSceneEventPayloadVariable * PayloadVariable = EntryPoint - > PayloadVariables . Find ( FieldName ) ;
if ( ! PayloadVariable )
2019-10-01 20:41:42 -04:00
{
2023-03-20 12:05:06 -04:00
PayloadVariable = & EntryPoint - > PayloadVariables . Add ( FieldName ) ;
2019-10-01 20:41:42 -04:00
}
2023-09-12 05:10:23 -04:00
PayloadVariable - > Value = NewVariableValue . Value ;
PayloadVariable - > ObjectValue = NewVariableValue . ObjectValue ;
2023-03-20 12:05:06 -04:00
return true ;
2019-10-01 20:41:42 -04:00
}
2023-03-20 12:05:06 -04:00
UK2Node * FMovieSceneEventCustomization : : FindEndpoint ( UMovieSceneSequence * Sequence , UBlueprint * Blueprint , UObject * EditObject , void * RawData ) const
2019-10-01 20:41:42 -04:00
{
2023-03-20 12:05:06 -04:00
UMovieSceneEventSectionBase * EventSection = Cast < UMovieSceneEventSectionBase > ( EditObject ) ;
FMovieSceneEvent * EntryPoint = static_cast < FMovieSceneEvent * > ( RawData ) ;
if ( EventSection & & EntryPoint )
2019-10-01 20:41:42 -04:00
{
2023-03-20 12:05:06 -04:00
return FMovieSceneEventUtils : : FindEndpoint ( EntryPoint , EventSection , Blueprint ) ;
2019-10-01 20:41:42 -04:00
}
2023-03-20 12:05:06 -04:00
return nullptr ;
2019-10-01 20:41:42 -04:00
}
2023-03-20 12:05:06 -04:00
void FMovieSceneEventCustomization : : GetWellKnownParameterPinNames ( UObject * EditObject , void * RawData , TArray < FName > & OutWellKnownParameters ) const
2019-10-01 20:41:42 -04:00
{
2023-03-20 12:05:06 -04:00
// We only have one well-known parameter: the (optional) bound object parameter.
FMovieSceneEvent * EntryPoint = static_cast < FMovieSceneEvent * > ( RawData ) ;
OutWellKnownParameters . Add ( EntryPoint - > BoundObjectPinName ) ;
2019-10-01 20:41:42 -04:00
}
2023-03-20 12:05:06 -04:00
void FMovieSceneEventCustomization : : GetWellKnownParameterCandidates ( UK2Node * Endpoint , TArray < FWellKnownParameterCandidates > & OutCandidates ) const
2019-10-01 20:41:42 -04:00
{
2023-03-20 12:05:06 -04:00
FWellKnownParameterCandidates BoundObjectCandidates ;
BoundObjectCandidates . Metadata . PickerLabel = LOCTEXT ( " BoundObjectPin_Label " , " Pass Bound Object To " ) ;
BoundObjectCandidates . Metadata . PickerTooltip = LOCTEXT ( " BoundObjectPin_Tooltip " , " Specifies a pin to pass the bound object(s) through when the event is triggered. Interface and object pins are both supported. " ) ;
2018-07-13 06:25:54 -04:00
2023-03-20 12:05:06 -04:00
for ( UEdGraphPin * Pin : Endpoint - > Pins )
2018-07-13 06:25:54 -04:00
{
2023-03-20 12:05:06 -04:00
if ( Pin - > Direction = = EGPD_Output & &
( Pin - > PinType . PinCategory = = UEdGraphSchema_K2 : : PC_Object | |
Pin - > PinType . PinCategory = = UEdGraphSchema_K2 : : PC_Interface ) )
2018-07-13 06:25:54 -04:00
{
2023-03-20 12:05:06 -04:00
BoundObjectCandidates . CandidatePinNames . Add ( Pin - > GetFName ( ) ) ;
2018-07-13 06:25:54 -04:00
}
}
2023-03-20 12:05:06 -04:00
OutCandidates . Add ( BoundObjectCandidates ) ;
2019-10-01 20:41:42 -04:00
}
2023-03-20 12:05:06 -04:00
bool FMovieSceneEventCustomization : : SetWellKnownParameterPinName ( UObject * EditObject , void * RawData , int32 ParameterIndex , FName BoundPinName )
2019-10-01 20:41:42 -04:00
{
2023-03-20 12:05:06 -04:00
if ( ensure ( ParameterIndex = = 0 ) )
2018-07-13 06:25:54 -04:00
{
2023-03-20 12:05:06 -04:00
FMovieSceneEvent * EntryPoint = static_cast < FMovieSceneEvent * > ( RawData ) ;
EntryPoint - > BoundObjectPinName = BoundPinName ;
2019-10-01 20:41:42 -04:00
return true ;
2023-03-20 12:05:06 -04:00
}
return false ;
}
FMovieSceneDirectorBlueprintEndpointDefinition FMovieSceneEventCustomization : : GenerateEndpointDefinition ( UMovieSceneSequence * Sequence )
{
UMovieScene * MovieScene = Sequence - > GetMovieScene ( ) ;
TOptional < FGuid > CommonObjectBindingID ;
{
TArray < UObject * > EditObjects ;
GetEditObjects ( EditObjects ) ;
for ( UObject * Outer : EditObjects )
{
FGuid ThisBindingID ;
MovieScene - > FindTrackBinding ( * Outer - > GetTypedOuter < UMovieSceneTrack > ( ) , ThisBindingID ) ;
if ( CommonObjectBindingID . IsSet ( ) & & CommonObjectBindingID ! = ThisBindingID )
{
CommonObjectBindingID . Reset ( ) ;
break ;
}
CommonObjectBindingID = ThisBindingID ;
}
}
return FMovieSceneEventUtils : : GenerateEventDefinition ( MovieScene , CommonObjectBindingID . Get ( FGuid ( ) ) ) ;
}
void FMovieSceneEventCustomization : : OnCreateEndpoint ( UMovieSceneSequence * Sequence , UBlueprint * Blueprint , const TArray < UObject * > EditObjects , const TArray < void * > RawData , const FMovieSceneDirectorBlueprintEndpointDefinition & EndpointDefinition , UK2Node * NewEndpoint )
{
check ( RawData . Num ( ) = = EditObjects . Num ( ) ) ;
struct FSectionData
{
TArray < FMovieSceneEvent * > EntryPoints ;
2019-10-01 20:41:42 -04:00
} ;
2023-03-20 12:05:06 -04:00
TSortedMap < UMovieSceneEventSectionBase * , FSectionData > PerSectionData ;
2019-10-01 20:41:42 -04:00
2023-03-20 12:05:06 -04:00
for ( int32 Index = 0 ; Index < RawData . Num ( ) ; + + Index )
2019-10-01 20:41:42 -04:00
{
2023-03-20 12:05:06 -04:00
UMovieSceneEventSectionBase * EventSection = Cast < UMovieSceneEventSectionBase > ( EditObjects [ Index ] ) ;
FMovieSceneEvent * EntryPoint = static_cast < FMovieSceneEvent * > ( RawData [ Index ] ) ;
2019-10-01 20:41:42 -04:00
2023-03-20 12:05:06 -04:00
if ( EventSection )
2019-10-01 20:41:42 -04:00
{
2023-03-20 12:05:06 -04:00
FSectionData & SectionData = PerSectionData . FindOrAdd ( EventSection ) ;
SectionData . EntryPoints . Add ( EntryPoint ) ;
2019-10-01 20:41:42 -04:00
}
}
2023-03-20 12:05:06 -04:00
UEdGraphPin * BoundObjectPin = FMovieSceneDirectorBlueprintUtils : : FindCallTargetPin ( NewEndpoint , EndpointDefinition . PossibleCallTargetClass ) ;
2019-10-01 20:41:42 -04:00
2023-03-20 12:05:06 -04:00
for ( const TPair < UMovieSceneEventSectionBase * , FSectionData > & SectionPair : PerSectionData )
2019-10-01 20:41:42 -04:00
{
2023-03-20 12:05:06 -04:00
SectionPair . Key - > Modify ( ) ;
FMovieSceneEventUtils : : BindEventSectionToBlueprint ( SectionPair . Key , Blueprint ) ;
2019-10-01 20:41:42 -04:00
2023-03-20 12:05:06 -04:00
for ( FMovieSceneEvent * EntryPoint : SectionPair . Value . EntryPoints )
2019-10-01 20:41:42 -04:00
{
2023-03-20 12:05:06 -04:00
FMovieSceneEventUtils : : SetEndpoint ( EntryPoint , SectionPair . Key , NewEndpoint , BoundObjectPin ) ;
2019-10-01 20:41:42 -04:00
}
}
}
2023-03-20 12:05:06 -04:00
void FMovieSceneEventCustomization : : OnSetEndpoint ( UMovieSceneSequence * Sequence , UBlueprint * Blueprint , const TArray < UObject * > EditObjects , const TArray < void * > RawData , const FMovieSceneDirectorBlueprintEndpointDefinition & EndpointDefinition , UK2Node * NewEndpoint )
2019-10-01 20:41:42 -04:00
{
check ( EditObjects . Num ( ) = = RawData . Num ( ) ) ;
for ( int32 Index = 0 ; Index < RawData . Num ( ) ; + + Index )
2018-07-13 06:25:54 -04:00
{
2019-10-01 20:41:42 -04:00
UMovieSceneEventSectionBase * EventSection = Cast < UMovieSceneEventSectionBase > ( EditObjects [ Index ] ) ;
2023-03-20 12:05:06 -04:00
if ( EventSection )
{
EventSection - > Modify ( ) ;
if ( Blueprint )
{
FMovieSceneEventUtils : : BindEventSectionToBlueprint ( EventSection , Blueprint ) ;
}
}
2019-10-01 20:41:42 -04:00
2023-03-20 12:05:06 -04:00
FMovieSceneEvent * EntryPoint = static_cast < FMovieSceneEvent * > ( RawData [ Index ] ) ;
2019-10-01 20:41:42 -04:00
if ( EntryPoint )
2018-07-13 06:25:54 -04:00
{
2023-03-20 12:05:06 -04:00
UEdGraphPin * CallTargetPin = FMovieSceneDirectorBlueprintUtils : : FindCallTargetPin ( NewEndpoint , EndpointDefinition . PossibleCallTargetClass ) ;
FMovieSceneEventUtils : : SetEndpoint ( EntryPoint , EventSection , NewEndpoint , CallTargetPin ) ;
2018-07-13 06:25:54 -04:00
}
}
}
# undef LOCTEXT_NAMESPACE