2014-12-07 19:09:38 -05:00
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
2014-03-14 14:13:41 -04:00
# include "AnimGraphPrivatePCH.h"
# include "GraphEditorActions.h"
# include "ScopedTransaction.h"
# include "Kismet2NameValidators.h"
2014-04-24 08:49:31 -04:00
# include "AnimGraphNode_SaveCachedPose.h"
2014-08-21 18:50:33 -04:00
# include "BlueprintNodeSpawner.h"
2014-08-23 20:16:29 -04:00
# include "BlueprintActionDatabaseRegistrar.h"
2014-03-14 14:13:41 -04:00
/////////////////////////////////////////////////////
// FCachedPoseNameValidator
class FCachedPoseNameValidator : public FStringSetNameValidator
{
public :
FCachedPoseNameValidator ( class UBlueprint * InBlueprint , const FString & InExistingName )
: FStringSetNameValidator ( InExistingName )
{
TArray < UAnimGraphNode_SaveCachedPose * > Nodes ;
FBlueprintEditorUtils : : GetAllNodesOfClass < UAnimGraphNode_SaveCachedPose > ( InBlueprint , Nodes ) ;
2014-04-24 08:49:31 -04:00
for ( auto Node : Nodes )
2014-03-14 14:13:41 -04:00
{
Names . Add ( Node - > CacheName ) ;
}
}
} ;
/////////////////////////////////////////////////////
// UAnimGraphNode_ComponentToLocalSpace
2014-04-23 18:30:37 -04:00
# define LOCTEXT_NAMESPACE "A3Nodes"
2014-10-14 10:29:11 -04:00
UAnimGraphNode_SaveCachedPose : : UAnimGraphNode_SaveCachedPose ( const FObjectInitializer & ObjectInitializer )
: Super ( ObjectInitializer )
2014-03-14 14:13:41 -04:00
{
bCanRenameNode = true ;
}
2014-09-03 18:14:09 -04:00
FText UAnimGraphNode_SaveCachedPose : : GetTooltipText ( ) const
2014-03-14 14:13:41 -04:00
{
2014-09-03 18:14:09 -04:00
return LOCTEXT ( " SaveCachedPose_Tooltip " , " Denotes an animation tree that can be referenced elsewhere in the blueprint, which will be evaluated at most once per frame and then cached. " ) ;
2014-03-14 14:13:41 -04:00
}
2014-04-23 18:30:37 -04:00
FText UAnimGraphNode_SaveCachedPose : : GetNodeTitle ( ENodeTitleType : : Type TitleType ) const
2014-03-14 14:13:41 -04:00
{
2014-04-23 18:30:37 -04:00
if ( TitleType = = ENodeTitleType : : EditableTitle )
{
return FText : : FromString ( CacheName ) ;
}
2014-09-16 15:01:38 -04:00
else if ( ( TitleType = = ENodeTitleType : : MenuTitle ) & & CacheName . IsEmpty ( ) )
2014-08-21 18:50:33 -04:00
{
return LOCTEXT ( " NewSaveCachedPose " , " New Save cached pose... " ) ;
}
2015-04-02 11:16:23 -04:00
else if ( CachedNodeTitle . IsOutOfDate ( this ) )
2014-04-23 18:30:37 -04:00
{
FFormatNamedArguments Args ;
Args . Add ( TEXT ( " NodeTitle " ) , FText : : FromString ( CacheName ) ) ;
2015-04-02 11:16:23 -04:00
CachedNodeTitle . SetCachedText ( FText : : Format ( LOCTEXT ( " AnimGraphNode_SaveCachedPose_Title " , " Save cached pose '{NodeTitle}' " ) , Args ) , this ) ;
2014-04-23 18:30:37 -04:00
}
2014-09-04 11:25:05 -04:00
return CachedNodeTitle ;
2014-04-23 18:30:37 -04:00
}
2014-03-14 14:13:41 -04:00
FString UAnimGraphNode_SaveCachedPose : : GetNodeCategory ( ) const
{
return TEXT ( " Cached Poses " ) ;
}
2014-08-23 20:16:29 -04:00
void UAnimGraphNode_SaveCachedPose : : GetMenuActions ( FBlueprintActionDatabaseRegistrar & ActionRegistrar ) const
2014-08-21 18:50:33 -04:00
{
auto PostSpawnSetupLambda = [ ] ( UEdGraphNode * NewNode , bool bIsTemplateNode )
{
UAnimGraphNode_SaveCachedPose * CachedPoseNode = CastChecked < UAnimGraphNode_SaveCachedPose > ( NewNode ) ;
// we use an empty CacheName in GetNodeTitle() to relay the proper menu title
if ( ! bIsTemplateNode )
{
// @TODO: is the idea that this name is unique? what if Rand() hit twice? why not MakeUniqueObjectName()?
CachedPoseNode - > CacheName = TEXT ( " SavedPose " ) + FString : : FromInt ( FMath : : Rand ( ) ) ;
}
} ;
2014-09-10 17:09:26 -04:00
// actions get registered under specific object-keys; the idea is that
// actions might have to be updated (or deleted) if their object-key is
// mutated (or removed)... here we use the node's class (so if the node
// type disappears, then the action should go with it)
UClass * ActionKey = GetClass ( ) ;
// to keep from needlessly instantiating a UBlueprintNodeSpawner, first
// check to make sure that the registrar is looking for actions of this type
// (could be regenerating actions for a specific asset, and therefore the
// registrar would only accept actions corresponding to that asset)
if ( ActionRegistrar . IsOpenForRegistration ( ActionKey ) )
{
UBlueprintNodeSpawner * NodeSpawner = UBlueprintNodeSpawner : : Create ( GetClass ( ) ) ;
NodeSpawner - > CustomizeNodeDelegate = UBlueprintNodeSpawner : : FCustomizeNodeDelegate : : CreateStatic ( PostSpawnSetupLambda ) ;
2014-08-21 18:50:33 -04:00
2014-09-10 17:09:26 -04:00
ActionRegistrar . AddBlueprintAction ( ActionKey , NodeSpawner ) ;
}
2014-08-21 18:50:33 -04:00
}
bool UAnimGraphNode_SaveCachedPose : : IsCompatibleWithGraph ( const UEdGraph * TargetGraph ) const
{
//EGraphType GraphType = TargetGraph->GetSchema()->GetGraphType(TargetGraph);
//bool const bIsNotStateMachine = (GraphType != GT_StateMachine);
bool const bIsNotStateMachine = TargetGraph - > GetOuter ( ) - > IsA ( UAnimBlueprint : : StaticClass ( ) ) ;
return bIsNotStateMachine & & Super : : IsCompatibleWithGraph ( TargetGraph ) ;
}
2014-03-14 14:13:41 -04:00
void UAnimGraphNode_SaveCachedPose : : OnRenameNode ( const FString & NewName )
{
CacheName = NewName ;
FBlueprintEditorUtils : : MarkBlueprintAsStructurallyModified ( GetBlueprint ( ) ) ;
}
TSharedPtr < class INameValidatorInterface > UAnimGraphNode_SaveCachedPose : : MakeNameValidator ( ) const
{
return MakeShareable ( new FCachedPoseNameValidator ( GetBlueprint ( ) , CacheName ) ) ;
2014-04-23 18:30:37 -04:00
}
# undef LOCTEXT_NAMESPACE