2019-12-27 09:26:59 -05:00
// Copyright Epic Games, Inc. All Rights Reserved.
2018-04-12 16:57:51 -04:00
2019-01-08 11:38:48 -05:00
# include "Graph/ControlRigGraphSchema.h"
# include "Graph/ControlRigGraph.h"
# include "Graph/ControlRigGraphNode.h"
# include "IControlRigEditorModule.h"
2018-04-12 16:57:51 -04:00
# include "UObject/UObjectIterator.h"
# include "Units/RigUnit.h"
# include "Kismet2/BlueprintEditorUtils.h"
2020-09-24 00:43:27 -04:00
# include "EdGraphNode_Comment.h"
2021-01-14 15:00:40 -04:00
# include "EdGraphSchema_K2_Actions.h"
2018-04-12 16:57:51 -04:00
# include "ScopedTransaction.h"
# include "Framework/MultiBox/MultiBoxBuilder.h"
# include "GraphEditorActions.h"
2019-04-02 11:26:55 -04:00
# include "ControlRig.h"
# include "ControlRigBlueprint.h"
# include "ControlRigBlueprintGeneratedClass.h"
2021-04-06 18:39:05 -04:00
# include "ControlRigDeveloper.h"
2019-04-02 11:26:55 -04:00
# include "Widgets/Notifications/SNotificationList.h"
# include "Framework/Notifications/NotificationManager.h"
2019-05-21 19:25:23 -04:00
# include "EulerTransform.h"
2020-01-22 17:58:55 -05:00
# include "Curves/CurveFloat.h"
2021-01-05 09:12:57 -04:00
# include "RigVMModel/Nodes/RigVMLibraryNode.h"
# include "RigVMModel/Nodes/RigVMCollapseNode.h"
# include "RigVMModel/Nodes/RigVMFunctionEntryNode.h"
# include "RigVMModel/Nodes/RigVMFunctionReturnNode.h"
2021-06-07 06:49:07 -04:00
# include "RigVMModel/RigVMVariableDescription.h"
2021-09-08 07:57:30 -04:00
# include "RigVMCore/RigVMUnknownType.h"
2021-06-07 06:49:07 -04:00
# include "Kismet2/Kismet2NameValidators.h"
2018-04-12 16:57:51 -04:00
2021-03-10 05:52:25 -04:00
# if WITH_EDITOR
# include "ControlRigEditor/Private/Editor/SControlRigFunctionLocalizationWidget.h"
2021-03-19 06:43:49 -04:00
# include "Misc/MessageDialog.h"
2021-03-10 05:52:25 -04:00
# endif
2018-04-12 16:57:51 -04:00
# define LOCTEXT_NAMESPACE "ControlRigGraphSchema"
const FName UControlRigGraphSchema : : GraphName_ControlRig ( TEXT ( " Rig Graph " ) ) ;
2021-09-14 10:59:08 -04:00
FControlRigLocalVariableNameValidator : : FControlRigLocalVariableNameValidator ( const UBlueprint * Blueprint , const URigVMGraph * Graph , FName InExistingName )
: FStringSetNameValidator ( InExistingName . ToString ( ) )
{
if ( Blueprint )
{
TSet < FName > NamesTemp ;
// We allow local variables with same name as blueprint variable
FBlueprintEditorUtils : : GetFunctionNameList ( Blueprint , NamesTemp ) ;
FBlueprintEditorUtils : : GetAllGraphNames ( Blueprint , NamesTemp ) ;
FBlueprintEditorUtils : : GetSCSVariableNameList ( Blueprint , NamesTemp ) ;
FBlueprintEditorUtils : : GetImplementingBlueprintsFunctionNameList ( Blueprint , NamesTemp ) ;
for ( FName & Name : NamesTemp )
{
Names . Add ( Name . ToString ( ) ) ;
}
}
if ( Graph )
{
for ( const FRigVMGraphVariableDescription & LocalVariable : Graph - > GetLocalVariables ( ) )
{
Names . Add ( LocalVariable . Name . ToString ( ) ) ;
}
2021-09-27 11:50:32 -04:00
for ( const FRigVMGraphVariableDescription & InputArgument : Graph - > GetInputArguments ( ) )
{
Names . Add ( InputArgument . Name . ToString ( ) ) ;
}
2021-09-14 10:59:08 -04:00
}
}
2021-10-22 05:17:33 -04:00
EValidatorResult FControlRigLocalVariableNameValidator : : IsValid ( const FString & Name , bool bOriginal )
{
EValidatorResult Result = FStringSetNameValidator : : IsValid ( Name , bOriginal ) ;
if ( Result = = EValidatorResult : : Ok )
{
if ( URigVMController : : GetSanitizedName ( Name , false , true ) = = Name )
{
return Result ;
}
return EValidatorResult : : ContainsInvalidCharacters ;
}
return Result ;
}
EValidatorResult FControlRigLocalVariableNameValidator : : IsValid ( const FName & Name , bool bOriginal )
{
return IsValid ( Name . ToString ( ) , bOriginal ) ;
}
2021-11-24 05:33:15 -05:00
FControlRigNameValidator : : FControlRigNameValidator ( const UBlueprint * Blueprint , const UStruct * ValidationScope , FName InExistingName )
: FStringSetNameValidator ( InExistingName . ToString ( ) )
{
if ( Blueprint )
{
TSet < FName > NamesTemp ;
FBlueprintEditorUtils : : GetClassVariableList ( Blueprint , NamesTemp , true ) ;
FBlueprintEditorUtils : : GetFunctionNameList ( Blueprint , NamesTemp ) ;
FBlueprintEditorUtils : : GetAllGraphNames ( Blueprint , NamesTemp ) ;
FBlueprintEditorUtils : : GetSCSVariableNameList ( Blueprint , NamesTemp ) ;
FBlueprintEditorUtils : : GetImplementingBlueprintsFunctionNameList ( Blueprint , NamesTemp ) ;
for ( FName & Name : NamesTemp )
{
Names . Add ( Name . ToString ( ) ) ;
}
}
}
EValidatorResult FControlRigNameValidator : : IsValid ( const FString & Name , bool bOriginal )
{
EValidatorResult Result = FStringSetNameValidator : : IsValid ( Name , bOriginal ) ;
if ( Result = = EValidatorResult : : Ok )
{
if ( URigVMController : : GetSanitizedName ( Name , false , true ) = = Name )
{
return Result ;
}
return EValidatorResult : : ContainsInvalidCharacters ;
}
return Result ;
}
EValidatorResult FControlRigNameValidator : : IsValid ( const FName & Name , bool bOriginal )
{
return IsValid ( Name . ToString ( ) , bOriginal ) ;
}
2021-06-07 06:49:07 -04:00
FEdGraphPinType FControlRigGraphSchemaAction_LocalVar : : GetPinType ( ) const
{
if ( UControlRigGraph * Graph = Cast < UControlRigGraph > ( GetVariableScope ( ) ) )
{
for ( FRigVMGraphVariableDescription Variable : Graph - > GetModel ( ) - > GetLocalVariables ( ) )
{
if ( Variable . Name = = GetVariableName ( ) )
{
return Variable . ToPinType ( ) ;
}
}
2021-09-27 11:50:32 -04:00
for ( FRigVMGraphVariableDescription Variable : Graph - > GetModel ( ) - > GetInputArguments ( ) )
{
if ( Variable . Name = = GetVariableName ( ) )
{
return Variable . ToPinType ( ) ;
}
}
2021-06-07 06:49:07 -04:00
}
return FEdGraphPinType ( ) ;
}
void FControlRigGraphSchemaAction_LocalVar : : ChangeVariableType ( const FEdGraphPinType & NewPinType )
{
if ( UControlRigGraph * Graph = Cast < UControlRigGraph > ( GetVariableScope ( ) ) )
{
FString NewCPPType ;
UObject * NewCPPTypeObject = nullptr ;
2021-11-18 08:00:07 -05:00
RigVMTypeUtils : : CPPTypeFromPinType ( NewPinType , NewCPPType , & NewCPPTypeObject ) ;
2021-07-19 06:35:29 -04:00
Graph - > GetController ( ) - > SetLocalVariableType ( GetVariableName ( ) , NewCPPType , NewCPPTypeObject , true , true ) ;
2021-06-07 06:49:07 -04:00
}
}
void FControlRigGraphSchemaAction_LocalVar : : RenameVariable ( const FName & NewName )
{
const FName OldName = GetVariableName ( ) ;
2021-09-14 10:59:08 -04:00
if ( OldName = = NewName )
{
return ;
}
2021-06-07 06:49:07 -04:00
if ( UControlRigGraph * Graph = Cast < UControlRigGraph > ( GetVariableScope ( ) ) )
{
2021-07-19 06:35:29 -04:00
if ( Graph - > GetController ( ) - > RenameLocalVariable ( OldName , NewName , true , true ) )
2021-06-07 06:49:07 -04:00
{
SetVariableInfo ( NewName , GetVariableScope ( ) , GetPinType ( ) . PinCategory = = TEXT ( " bool " ) ) ;
}
}
}
bool FControlRigGraphSchemaAction_LocalVar : : IsValidName ( const FName & NewName , FText & OutErrorMessage ) const
{
if ( UControlRigGraph * ControlRigGraph = Cast < UControlRigGraph > ( GetVariableScope ( ) ) )
{
2021-09-14 10:59:08 -04:00
FControlRigLocalVariableNameValidator NameValidator ( ControlRigGraph - > GetBlueprint ( ) , ControlRigGraph - > GetModel ( ) , GetVariableName ( ) ) ;
EValidatorResult Result = NameValidator . IsValid ( NewName . ToString ( ) , false ) ;
if ( Result ! = EValidatorResult : : Ok & & Result ! = EValidatorResult : : ExistingName )
2021-06-07 06:49:07 -04:00
{
OutErrorMessage = FText : : FromString ( TEXT ( " Name with invalid format " ) ) ;
return false ;
}
}
return true ;
}
void FControlRigGraphSchemaAction_LocalVar : : DeleteVariable ( )
{
if ( UControlRigGraph * Graph = Cast < UControlRigGraph > ( GetVariableScope ( ) ) )
{
2021-07-19 06:35:29 -04:00
Graph - > GetController ( ) - > RemoveLocalVariable ( GetVariableName ( ) , true , true ) ;
2021-06-07 06:49:07 -04:00
}
}
bool FControlRigGraphSchemaAction_LocalVar : : IsVariableUsed ( )
{
if ( UControlRigGraph * ControlRigGraph = Cast < UControlRigGraph > ( GetVariableScope ( ) ) )
{
const FString VarNameStr = GetVariableName ( ) . ToString ( ) ;
for ( URigVMNode * Node : ControlRigGraph - > GetModel ( ) - > GetNodes ( ) )
{
if ( URigVMVariableNode * VarNode = Cast < URigVMVariableNode > ( Node ) )
{
if ( VarNode - > FindPin ( TEXT ( " Variable " ) ) - > GetDefaultValue ( ) = = VarNameStr )
{
return true ;
}
}
}
}
return false ;
}
2021-08-31 14:14:38 -04:00
FControlRigGraphSchemaAction_PromoteToVariable : : FControlRigGraphSchemaAction_PromoteToVariable ( UEdGraphPin * InEdGraphPin , bool InLocalVariable )
: FEdGraphSchemaAction ( FText ( ) ,
InLocalVariable ? LOCTEXT ( " PromoteToLocalVariable " , " Promote to local variable " ) : LOCTEXT ( " PromoteToVariable " , " Promote to variable " ) ,
InLocalVariable ? LOCTEXT ( " PromoteToLocalVariable " , " Promote to local variable " ) : LOCTEXT ( " PromoteToVariable " , " Promote to variable " ) ,
1 )
, EdGraphPin ( InEdGraphPin )
, bLocalVariable ( InLocalVariable )
{
}
UEdGraphNode * FControlRigGraphSchemaAction_PromoteToVariable : : PerformAction ( UEdGraph * ParentGraph , UEdGraphPin * FromPin ,
const FVector2D Location , bool bSelectNewNode )
{
UControlRigGraph * RigGraph = Cast < UControlRigGraph > ( ParentGraph ) ;
if ( RigGraph = = nullptr )
{
return nullptr ;
}
UControlRigBlueprint * Blueprint = RigGraph - > GetBlueprint ( ) ;
URigVMGraph * Model = RigGraph - > GetModel ( ) ;
URigVMController * Controller = RigGraph - > GetController ( ) ;
if ( ( Blueprint = = nullptr ) | |
( Model = = nullptr ) | |
( Controller = = nullptr ) )
{
return nullptr ;
}
2021-09-14 22:19:52 -04:00
URigVMPin * ModelPin = Model - > FindPin ( FromPin - > GetName ( ) ) ;
2021-08-31 14:14:38 -04:00
FName VariableName ( NAME_None ) ;
const FScopedTransaction Transaction (
bLocalVariable ?
LOCTEXT ( " GraphEd_PromoteToLocalVariable " , " Promote Pin To Local Variable " ) :
LOCTEXT ( " GraphEd_PromoteToVariable " , " Promote Pin To Variable " ) ) ;
if ( bLocalVariable )
{
const FRigVMGraphVariableDescription VariableDescription = Controller - > AddLocalVariable (
* ModelPin - > GetPinPath ( ) ,
ModelPin - > GetCPPType ( ) ,
ModelPin - > GetCPPTypeObject ( ) ,
ModelPin - > GetDefaultValue ( ) ,
true ,
true
) ;
VariableName = VariableDescription . Name ;
}
else
{
Blueprint - > Modify ( ) ;
FString DefaultValue = ModelPin - > GetDefaultValue ( ) ;
if ( ! DefaultValue . IsEmpty ( ) )
{
if ( UScriptStruct * ScriptStruct = Cast < UScriptStruct > ( ModelPin - > GetCPPTypeObject ( ) ) )
{
if ( ScriptStruct = = TBaseStructure < FVector2D > : : Get ( ) )
{
FVector2D Value = FVector2D : : ZeroVector ;
ScriptStruct - > ImportText ( * DefaultValue , & Value , nullptr , PPF_None , nullptr , FString ( ) ) ;
DefaultValue = Value . ToString ( ) ;
}
if ( ScriptStruct = = TBaseStructure < FVector > : : Get ( ) )
{
FVector Value = FVector : : ZeroVector ;
ScriptStruct - > ImportText ( * DefaultValue , & Value , nullptr , PPF_None , nullptr , FString ( ) ) ;
DefaultValue = Value . ToString ( ) ;
}
if ( ScriptStruct = = TBaseStructure < FQuat > : : Get ( ) )
{
FQuat Value = FQuat : : Identity ;
ScriptStruct - > ImportText ( * DefaultValue , & Value , nullptr , PPF_None , nullptr , FString ( ) ) ;
DefaultValue = Value . ToString ( ) ;
}
if ( ScriptStruct = = TBaseStructure < FRotator > : : Get ( ) )
{
FRotator Value = FRotator : : ZeroRotator ;
ScriptStruct - > ImportText ( * DefaultValue , & Value , nullptr , PPF_None , nullptr , FString ( ) ) ;
DefaultValue = Value . ToString ( ) ;
}
if ( ScriptStruct = = TBaseStructure < FTransform > : : Get ( ) )
{
FTransform Value = FTransform : : Identity ;
ScriptStruct - > ImportText ( * DefaultValue , & Value , nullptr , PPF_None , nullptr , FString ( ) ) ;
DefaultValue = Value . ToString ( ) ;
}
}
}
FRigVMExternalVariable ExternalVariable ;
ExternalVariable . Name = FromPin - > GetFName ( ) ;
ExternalVariable . bIsArray = ModelPin - > IsArray ( ) ;
ExternalVariable . TypeName = ModelPin - > IsArray ( ) ? * ModelPin - > GetArrayElementCppType ( ) : * ModelPin - > GetCPPType ( ) ;
ExternalVariable . TypeObject = ModelPin - > GetCPPTypeObject ( ) ;
VariableName = Blueprint - > AddCRMemberVariableFromExternal (
ExternalVariable ,
DefaultValue
) ;
}
if ( ! VariableName . IsNone ( ) )
{
URigVMNode * ModelNode = Controller - > AddVariableNode (
VariableName ,
ModelPin - > GetCPPType ( ) ,
ModelPin - > GetCPPTypeObject ( ) ,
FromPin - > Direction = = EGPD_Input ,
ModelPin - > GetDefaultValue ( ) ,
Location ,
FString ( ) ,
true ,
true
) ;
if ( ModelNode )
{
if ( FromPin - > Direction = = EGPD_Input )
{
Controller - > AddLink ( ModelNode - > FindPin ( TEXT ( " Value " ) ) , ModelPin , true ) ;
}
else
{
Controller - > AddLink ( ModelPin , ModelNode - > FindPin ( TEXT ( " Value " ) ) , true ) ;
}
return RigGraph - > FindNodeForModelNodeName ( ModelNode - > GetFName ( ) ) ;
}
}
return nullptr ;
}
2021-01-14 15:00:40 -04:00
FReply FControlRigFunctionDragDropAction : : DroppedOnPanel ( const TSharedRef < class SWidget > & Panel , FVector2D ScreenPosition , FVector2D GraphPosition , UEdGraph & Graph )
{
2021-06-07 06:49:07 -04:00
// For local variables
if ( SourceAction - > GetTypeId ( ) = = FControlRigGraphSchemaAction_LocalVar : : StaticGetTypeId ( ) )
{
if ( UControlRigGraph * TargetRigGraph = Cast < UControlRigGraph > ( & Graph ) )
{
if ( TargetRigGraph = = SourceRigGraph )
{
FControlRigGraphSchemaAction_LocalVar * VarAction = ( FControlRigGraphSchemaAction_LocalVar * ) SourceAction . Get ( ) ;
for ( FRigVMGraphVariableDescription LocalVariable : TargetRigGraph - > GetModel ( ) - > GetLocalVariables ( ) )
{
if ( LocalVariable . Name = = VarAction - > GetVariableName ( ) )
{
URigVMController * Controller = TargetRigGraph - > GetController ( ) ;
FMenuBuilder MenuBuilder ( true , NULL ) ;
const FText VariableNameText = FText : : FromName ( LocalVariable . Name ) ;
MenuBuilder . BeginSection ( " BPVariableDroppedOn " , VariableNameText ) ;
MenuBuilder . AddMenuEntry (
FText : : Format ( LOCTEXT ( " CreateGetVariable " , " Get {0} " ) , VariableNameText ) ,
FText : : Format ( LOCTEXT ( " CreateVariableGetterToolTip " , " Create Getter for variable '{0}' \n (Ctrl-drag to automatically create a getter) " ) , VariableNameText ) ,
FSlateIcon ( ) ,
FUIAction (
FExecuteAction : : CreateLambda ( [ Controller , LocalVariable , GraphPosition ] ( )
{
2021-07-19 06:35:29 -04:00
Controller - > AddVariableNode ( LocalVariable . Name , LocalVariable . CPPType , LocalVariable . CPPTypeObject , true , LocalVariable . DefaultValue , GraphPosition , FString ( ) , true , true ) ;
2021-06-07 06:49:07 -04:00
} ) ,
FCanExecuteAction ( ) ) ) ;
MenuBuilder . AddMenuEntry (
FText : : Format ( LOCTEXT ( " CreateSetVariable " , " Set {0} " ) , VariableNameText ) ,
FText : : Format ( LOCTEXT ( " CreateVariableSetterToolTip " , " Create Setter for variable '{0}' \n (Alt-drag to automatically create a setter) " ) , VariableNameText ) ,
FSlateIcon ( ) ,
FUIAction (
FExecuteAction : : CreateLambda ( [ Controller , LocalVariable , GraphPosition ] ( )
{
2021-07-19 06:35:29 -04:00
Controller - > AddVariableNode ( LocalVariable . Name , LocalVariable . CPPType , LocalVariable . CPPTypeObject , false , LocalVariable . DefaultValue , GraphPosition , FString ( ) , true , true ) ;
2021-06-07 06:49:07 -04:00
} ) ,
FCanExecuteAction ( ) ) ) ;
TSharedRef < SWidget > PanelWidget = Panel ;
// Show dialog to choose getter vs setter
FSlateApplication : : Get ( ) . PushMenu (
PanelWidget ,
FWidgetPath ( ) ,
MenuBuilder . MakeWidget ( ) ,
ScreenPosition ,
FPopupTransitionEffect ( FPopupTransitionEffect : : ContextMenu )
) ;
MenuBuilder . EndSection ( ) ;
}
}
}
}
}
// For functions
else if ( UControlRigGraph * TargetRigGraph = Cast < UControlRigGraph > ( & Graph ) )
2021-01-14 15:00:40 -04:00
{
if ( UControlRigBlueprint * TargetRigBlueprint = Cast < UControlRigBlueprint > ( FBlueprintEditorUtils : : FindBlueprintForGraph ( TargetRigGraph ) ) )
{
if ( URigVMGraph * FunctionDefinitionGraph = SourceRigBlueprint - > GetModel ( SourceRigGraph ) )
{
if ( URigVMLibraryNode * FunctionDefinitionNode = Cast < URigVMLibraryNode > ( FunctionDefinitionGraph - > GetOuter ( ) ) )
{
if ( URigVMController * TargetController = TargetRigBlueprint - > GetController ( TargetRigGraph ) )
{
2021-03-10 05:52:25 -04:00
if ( URigVMFunctionLibrary * FunctionLibrary = Cast < URigVMFunctionLibrary > ( FunctionDefinitionNode - > GetOuter ( ) ) )
{
if ( UControlRigBlueprint * FunctionRigBlueprint = Cast < UControlRigBlueprint > ( FunctionLibrary - > GetOuter ( ) ) )
{
# if WITH_EDITOR
if ( FunctionRigBlueprint ! = TargetRigBlueprint )
{
if ( ! FunctionRigBlueprint - > IsFunctionPublic ( FunctionDefinitionNode - > GetFName ( ) ) )
{
TargetRigBlueprint - > BroadcastRequestLocalizeFunctionDialog ( FunctionDefinitionNode ) ;
FunctionDefinitionNode = TargetRigBlueprint - > GetLocalFunctionLibrary ( ) - > FindPreviouslyLocalizedFunction ( FunctionDefinitionNode ) ;
}
}
# endif
2021-07-19 06:35:29 -04:00
TargetController - > AddFunctionReferenceNode ( FunctionDefinitionNode , GraphPosition , FString ( ) , true , true ) ;
2021-03-10 05:52:25 -04:00
}
}
2021-01-14 15:00:40 -04:00
}
}
}
}
}
2021-06-07 06:49:07 -04:00
2021-01-14 15:00:40 -04:00
return FReply : : Unhandled ( ) ;
}
FReply FControlRigFunctionDragDropAction : : DroppedOnPin ( FVector2D ScreenPosition , FVector2D GraphPosition )
{
return FReply : : Unhandled ( ) ;
}
FReply FControlRigFunctionDragDropAction : : DroppedOnAction ( TSharedRef < FEdGraphSchemaAction > Action )
{
return FReply : : Unhandled ( ) ;
}
FReply FControlRigFunctionDragDropAction : : DroppedOnCategory ( FText Category )
{
// todo
/*
if ( SourceAction . IsValid ( ) )
{
SourceAction - > MovePersistentItemToCategory ( Category ) ;
}
*/
return FReply : : Unhandled ( ) ;
}
void FControlRigFunctionDragDropAction : : HoverTargetChanged ( )
{
// todo - see FMyBlueprintItemDragDropAction
FGraphSchemaActionDragDropAction : : HoverTargetChanged ( ) ;
// check for category + graph, everything else we won't allow for now.
bDropTargetValid = true ;
}
FControlRigFunctionDragDropAction : : FControlRigFunctionDragDropAction ( )
: FGraphSchemaActionDragDropAction ( )
, SourceRigBlueprint ( nullptr )
, SourceRigGraph ( nullptr )
, bControlDrag ( false )
, bAltDrag ( false )
{
}
TSharedRef < FControlRigFunctionDragDropAction > FControlRigFunctionDragDropAction : : New ( TSharedPtr < FEdGraphSchemaAction > InAction , UControlRigBlueprint * InRigBlueprint , UControlRigGraph * InRigGraph )
{
TSharedRef < FControlRigFunctionDragDropAction > Action = MakeShareable ( new FControlRigFunctionDragDropAction ) ;
Action - > SourceAction = InAction ;
Action - > SourceRigBlueprint = InRigBlueprint ;
Action - > SourceRigGraph = InRigGraph ;
Action - > Construct ( ) ;
return Action ;
}
2018-04-12 16:57:51 -04:00
UControlRigGraphSchema : : UControlRigGraphSchema ( )
{
}
void UControlRigGraphSchema : : GetGraphContextActions ( FGraphContextMenuBuilder & ContextMenuBuilder ) const
{
}
2019-09-10 11:35:20 -04:00
void UControlRigGraphSchema : : GetContextMenuActions ( class UToolMenu * Menu , class UGraphNodeContextMenuContext * Context ) const
2018-04-12 16:57:51 -04:00
{
2020-01-22 17:58:55 -05:00
/*
// this seems to be taken care of by ControlRigGraphNode
2019-01-08 11:38:48 -05:00
# if WITH_EDITOR
2019-09-10 11:35:20 -04:00
return IControlRigEditorModule : : Get ( ) . GetContextMenuActions ( this , Menu , Context ) ;
2019-01-08 11:38:48 -05:00
# else
check ( 0 ) ;
# endif
2020-01-22 17:58:55 -05:00
*/
2018-04-12 16:57:51 -04:00
}
bool UControlRigGraphSchema : : TryCreateConnection ( UEdGraphPin * PinA , UEdGraphPin * PinB ) const
{
2019-05-21 19:25:23 -04:00
# if WITH_EDITOR
2021-03-19 06:43:49 -04:00
2019-05-21 19:25:23 -04:00
if ( GEditor )
2018-04-12 16:57:51 -04:00
{
2019-05-21 19:25:23 -04:00
GEditor - > CancelTransaction ( 0 ) ;
2018-04-12 16:57:51 -04:00
}
2021-03-19 06:43:49 -04:00
2019-05-21 19:25:23 -04:00
# endif
2018-04-12 16:57:51 -04:00
2020-02-04 11:06:23 -05:00
if ( PinA = = PinB )
{
return false ;
}
if ( PinA - > GetOwningNode ( ) = = PinB - > GetOwningNode ( ) )
{
return false ;
}
2020-01-22 17:58:55 -05:00
UControlRigGraphSchema * MutableThis = ( UControlRigGraphSchema * ) this ;
2019-05-21 19:25:23 -04:00
UBlueprint * Blueprint = FBlueprintEditorUtils : : FindBlueprintForNodeChecked ( PinA - > GetOwningNode ( ) ) ;
UControlRigBlueprint * RigBlueprint = Cast < UControlRigBlueprint > ( Blueprint ) ;
if ( RigBlueprint ! = nullptr )
{
2020-12-07 07:55:48 -04:00
if ( URigVMController * Controller = RigBlueprint - > GetOrCreateController ( PinA - > GetOwningNode ( ) - > GetGraph ( ) ) )
2019-05-21 19:25:23 -04:00
{
2020-12-07 07:55:48 -04:00
if ( PinA - > Direction = = EGPD_Input )
{
UEdGraphPin * Temp = PinA ;
PinA = PinB ;
PinB = Temp ;
}
2021-03-19 06:43:49 -04:00
# if WITH_EDITOR
// check if we are trying to connect a loop iteration pin to a return
if ( URigVMGraph * Graph = Controller - > GetGraph ( ) )
{
if ( URigVMPin * TargetPin = Graph - > FindPin ( PinB - > GetName ( ) ) )
{
if ( TargetPin - > IsExecuteContext ( ) & & TargetPin - > GetNode ( ) - > IsA < URigVMFunctionReturnNode > ( ) )
{
bool bIsInLoopIteration = false ;
if ( URigVMPin * SourcePin = Graph - > FindPin ( PinA - > GetName ( ) ) )
{
while ( SourcePin )
{
if ( ! SourcePin - > IsExecuteContext ( ) )
{
break ;
}
URigVMPin * CurrentSourcePin = SourcePin ;
SourcePin = nullptr ;
if ( URigVMUnitNode * UnitNode = Cast < URigVMUnitNode > ( CurrentSourcePin - > GetNode ( ) ) )
{
TSharedPtr < FStructOnScope > UnitScope = UnitNode - > ConstructStructInstance ( ) ;
if ( UnitScope . IsValid ( ) )
{
FRigVMStruct * Unit = ( FRigVMStruct * ) UnitScope - > GetStructMemory ( ) ;
if ( Unit - > IsForLoop ( ) )
{
if ( CurrentSourcePin - > GetFName ( ) ! = FRigVMStruct : : ForLoopCompletedPinName )
{
bIsInLoopIteration = true ;
break ;
}
}
}
}
for ( URigVMPin * PinOnSourceNode : CurrentSourcePin - > GetNode ( ) - > GetPins ( ) )
{
if ( ! PinOnSourceNode - > IsExecuteContext ( ) )
{
continue ;
}
if ( PinOnSourceNode - > GetDirection ( ) ! = ERigVMPinDirection : : Input & &
PinOnSourceNode - > GetDirection ( ) ! = ERigVMPinDirection : : IO )
{
continue ;
}
TArray < URigVMPin * > NextSourcePins = PinOnSourceNode - > GetLinkedSourcePins ( ) ;
if ( NextSourcePins . Num ( ) > 0 )
{
SourcePin = NextSourcePins [ 0 ] ;
break ;
}
}
}
}
if ( bIsInLoopIteration )
{
2021-03-19 15:05:09 -04:00
const EAppReturnType : : Type Answer = FMessageDialog : : Open ( EAppMsgType : : YesNo , FText : : FromString ( TEXT ( " Linking a function return within a loop is not recommended. \n Are you sure? " ) ) ) ;
2021-03-19 06:43:49 -04:00
if ( Answer = = EAppReturnType : : No )
{
return false ;
}
}
}
}
}
# endif
2021-07-19 06:35:29 -04:00
return Controller - > AddLink ( PinA - > GetName ( ) , PinB - > GetName ( ) , true , true ) ;
2019-05-21 19:25:23 -04:00
}
}
return false ;
2018-04-12 16:57:51 -04:00
}
static bool HasParentConnection_Recursive ( const UEdGraphPin * InPin )
{
if ( InPin - > ParentPin )
{
return InPin - > ParentPin - > LinkedTo . Num ( ) > 0 | | HasParentConnection_Recursive ( InPin - > ParentPin ) ;
}
return false ;
}
static bool HasChildConnection_Recursive ( const UEdGraphPin * InPin )
{
for ( const UEdGraphPin * SubPin : InPin - > SubPins )
{
if ( SubPin - > LinkedTo . Num ( ) > 0 | | HasChildConnection_Recursive ( SubPin ) )
{
return true ;
}
}
return false ;
}
const FPinConnectionResponse UControlRigGraphSchema : : CanCreateConnection ( const UEdGraphPin * A , const UEdGraphPin * B ) const
{
2019-05-21 19:25:23 -04:00
UBlueprint * Blueprint = FBlueprintEditorUtils : : FindBlueprintForNodeChecked ( A - > GetOwningNode ( ) ) ;
UControlRigBlueprint * RigBlueprint = Cast < UControlRigBlueprint > ( Blueprint ) ;
if ( RigBlueprint ! = nullptr )
{
2020-01-22 17:58:55 -05:00
UControlRigGraphNode * RigNodeA = Cast < UControlRigGraphNode > ( A - > GetOwningNode ( ) ) ;
UControlRigGraphNode * RigNodeB = Cast < UControlRigGraphNode > ( B - > GetOwningNode ( ) ) ;
2019-05-21 19:25:23 -04:00
2020-12-14 08:58:12 -04:00
if ( RigNodeA & & RigNodeB & & RigNodeA ! = RigNodeB )
2019-05-29 12:29:10 -04:00
{
2020-01-22 17:58:55 -05:00
URigVMPin * PinA = RigNodeA - > GetModelPinFromPinPath ( A - > GetName ( ) ) ;
if ( PinA )
{
PinA = PinA - > GetPinForLink ( ) ;
2020-12-07 07:55:48 -04:00
RigNodeA - > GetModel ( ) - > PrepareCycleChecking ( PinA , A - > Direction = = EGPD_Input ) ;
2020-01-22 17:58:55 -05:00
}
2019-05-29 12:29:10 -04:00
2020-01-22 17:58:55 -05:00
URigVMPin * PinB = RigNodeB - > GetModelPinFromPinPath ( B - > GetName ( ) ) ;
if ( PinB )
{
PinB = PinB - > GetPinForLink ( ) ;
}
2019-05-29 12:29:10 -04:00
2020-01-22 17:58:55 -05:00
if ( A - > Direction = = EGPD_Input )
{
URigVMPin * Temp = PinA ;
PinA = PinB ;
PinB = Temp ;
}
2021-01-26 04:06:19 -04:00
const FRigVMByteCode * ByteCode = RigNodeA - > GetController ( ) - > GetCurrentByteCode ( ) ;
2020-01-22 17:58:55 -05:00
FString FailureReason ;
2021-01-26 04:06:19 -04:00
bool bResult = RigNodeA - > GetModel ( ) - > CanLink ( PinA , PinB , & FailureReason , ByteCode ) ;
2020-01-22 17:58:55 -05:00
if ( ! bResult )
{
return FPinConnectionResponse ( CONNECT_RESPONSE_DISALLOW , FText : : FromString ( FailureReason ) ) ;
}
return FPinConnectionResponse ( CONNECT_RESPONSE_MAKE , LOCTEXT ( " ConnectResponse_Allowed " , " Connect " ) ) ;
2019-05-21 19:25:23 -04:00
}
}
return FPinConnectionResponse ( CONNECT_RESPONSE_DISALLOW , LOCTEXT ( " ConnectResponse_Disallowed_Unexpected " , " Unexpected error " ) ) ;
2018-04-12 16:57:51 -04:00
}
FLinearColor UControlRigGraphSchema : : GetPinTypeColor ( const FEdGraphPinType & PinType ) const
{
2019-04-02 11:26:55 -04:00
const FName & TypeName = PinType . PinCategory ;
if ( TypeName = = UEdGraphSchema_K2 : : PC_Struct )
{
2020-01-22 17:58:55 -05:00
if ( UStruct * Struct = Cast < UStruct > ( PinType . PinSubCategoryObject ) )
2019-04-02 11:26:55 -04:00
{
2020-01-22 17:58:55 -05:00
if ( Struct - > IsChildOf ( FRigVMExecuteContext : : StaticStruct ( ) ) )
{
return FLinearColor : : White ;
}
2021-09-08 07:57:30 -04:00
if ( Struct - > IsChildOf ( FRigVMUnknownType : : StaticStruct ( ) ) )
{
return FLinearColor ( FVector3f : : OneVector * 0.25f ) ;
}
2021-04-06 18:39:05 -04:00
if ( Struct = = FRigElementKey : : StaticStruct ( ) | | Struct = = FRigElementKeyCollection : : StaticStruct ( ) )
{
return FLinearColor ( 0.0 , 0.6588 , 0.9490 ) ;
}
2021-05-27 16:53:52 -04:00
if ( Struct = = FRigElementKey : : StaticStruct ( ) | | Struct = = FRigPose : : StaticStruct ( ) )
{
return FLinearColor ( 0.0 , 0.3588 , 0.5490 ) ;
}
2021-04-06 18:39:05 -04:00
// external types can register their own colors, check if there are any
if ( IControlRigDeveloperModule * Module = FModuleManager : : GetModulePtr < IControlRigDeveloperModule > ( " ControlRigDeveloper " ) )
{
if ( const FLinearColor * Color = Module - > FindPinTypeColor ( Struct ) )
{
return * Color ;
}
}
2019-04-02 11:26:55 -04:00
}
}
2021-06-22 14:11:52 -04:00
if ( TypeName = = UEdGraphSchema_K2 : : PC_Double )
{
FEdGraphPinType LocalPinType = PinType ;
LocalPinType . PinCategory = UEdGraphSchema_K2 : : PC_Float ;
return GetPinTypeColor ( LocalPinType ) ;
}
2018-04-12 16:57:51 -04:00
return GetDefault < UEdGraphSchema_K2 > ( ) - > GetPinTypeColor ( PinType ) ;
}
2021-08-31 14:14:38 -04:00
void UControlRigGraphSchema : : InsertAdditionalActions ( TArray < UBlueprint * > InBlueprints , TArray < UEdGraph * > EdGraphs ,
TArray < UEdGraphPin * > EdGraphPins , FGraphActionListBuilderBase & OutAllActions ) const
{
Super : : InsertAdditionalActions ( InBlueprints , EdGraphs , EdGraphPins , OutAllActions ) ;
if ( EdGraphPins . Num ( ) > 0 )
{
if ( UControlRigGraphNode * RigNode = Cast < UControlRigGraphNode > ( EdGraphPins [ 0 ] - > GetOwningNode ( ) ) )
{
if ( URigVMPin * ModelPin = RigNode - > GetModelPinFromPinPath ( EdGraphPins [ 0 ] - > GetName ( ) ) )
{
2021-09-08 07:57:30 -04:00
if ( ! ModelPin - > IsExecuteContext ( ) & & ! ModelPin - > IsUnknownType ( ) )
2021-08-31 14:14:38 -04:00
{
if ( ! ModelPin - > GetNode ( ) - > IsA < URigVMVariableNode > ( ) )
{
OutAllActions . AddAction ( TSharedPtr < FControlRigGraphSchemaAction_PromoteToVariable > (
new FControlRigGraphSchemaAction_PromoteToVariable ( EdGraphPins [ 0 ] , false )
) ) ;
if ( ! ModelPin - > GetGraph ( ) - > IsRootGraph ( ) )
{
OutAllActions . AddAction ( TSharedPtr < FControlRigGraphSchemaAction_PromoteToVariable > (
new FControlRigGraphSchemaAction_PromoteToVariable ( EdGraphPins [ 0 ] , true )
) ) ;
}
}
}
}
}
}
}
2021-11-24 05:33:15 -05:00
TSharedPtr < INameValidatorInterface > UControlRigGraphSchema : : GetNameValidator ( const UBlueprint * BlueprintObj , const FName & OriginalName , const UStruct * ValidationScope , const FName & ActionTypeId ) const
{
if ( ActionTypeId = = FControlRigGraphSchemaAction_LocalVar : : StaticGetTypeId ( ) )
{
if ( const UControlRigGraph * ControlRigGraph = Cast < UControlRigGraph > ( ValidationScope ) )
{
if ( const URigVMGraph * Graph = ControlRigGraph - > GetModel ( ) )
{
return MakeShareable ( new FControlRigLocalVariableNameValidator ( BlueprintObj , Graph , OriginalName ) ) ;
}
}
}
return MakeShareable ( new FControlRigNameValidator ( BlueprintObj , ValidationScope , OriginalName ) ) ;
}
2021-06-09 04:45:19 -04:00
bool UControlRigGraphSchema : : SupportsPinType ( UScriptStruct * ScriptStruct ) const
{
if ( ! ScriptStruct )
{
return false ;
}
for ( TFieldIterator < FProperty > It ( ScriptStruct ) ; It ; + + It )
{
FName PropertyName = It - > GetFName ( ) ;
FProperty * Property = * It ;
if ( FArrayProperty * ArrayProperty = CastField < FArrayProperty > ( Property ) )
{
Property = ArrayProperty - > Inner ;
}
FString CPPType = Property - > GetCPPType ( ) ;
if ( CPPType = = TEXT ( " bool " ) | |
CPPType = = TEXT ( " float " ) | |
2021-06-22 14:11:52 -04:00
CPPType = = TEXT ( " double " ) | |
2021-06-09 04:45:19 -04:00
CPPType = = TEXT ( " int32 " ) | |
CPPType = = TEXT ( " FString " ) | |
CPPType = = TEXT ( " FName " ) | |
CPPType = = TEXT ( " uint16 " ) )
{
continue ;
}
if ( FStructProperty * StructProperty = CastField < FStructProperty > ( Property ) )
{
if ( SupportsPinType ( StructProperty - > Struct ) )
{
continue ;
}
}
else if ( FEnumProperty * EnumProperty = CastField < FEnumProperty > ( Property ) )
{
continue ;
}
else if ( FByteProperty * ByteProperty = CastField < FByteProperty > ( Property ) )
{
if ( ByteProperty - > Enum )
{
continue ;
}
}
2021-10-19 06:24:52 -04:00
else if ( CastField < FObjectProperty > ( Property ) )
{
continue ;
}
2021-06-09 04:45:19 -04:00
return false ;
}
return true ;
}
bool UControlRigGraphSchema : : SupportsPinType ( TWeakPtr < const FEdGraphSchemaAction > SchemaAction , const FEdGraphPinType & PinType ) const
{
if ( PinType . IsContainer ( ) )
{
return false ;
}
const FName TypeName = PinType . PinCategory ;
if ( TypeName = = UEdGraphSchema_K2 : : PC_Boolean | |
TypeName = = UEdGraphSchema_K2 : : PC_Int | |
TypeName = = UEdGraphSchema_K2 : : PC_Float | |
2021-06-22 14:11:52 -04:00
TypeName = = UEdGraphSchema_K2 : : PC_Double | |
2021-06-09 04:45:19 -04:00
TypeName = = UEdGraphSchema_K2 : : PC_Name | |
TypeName = = UEdGraphSchema_K2 : : PC_String | |
TypeName = = UEdGraphSchema_K2 : : PC_Enum )
{
return true ;
}
2021-10-19 06:24:52 -04:00
if ( PinType . PinCategory = = UEdGraphSchema_K2 : : PC_Object | |
PinType . PinCategory = = UEdGraphSchema_K2 : : PC_SoftObject | |
PinType . PinCategory = = UEdGraphSchema_K2 : : AllObjectTypes )
{
if ( PinType . PinSubCategoryObject . IsValid ( ) )
{
return PinType . PinSubCategoryObject - > IsA < UClass > ( ) ;
}
}
2021-06-09 04:45:19 -04:00
if ( PinType . PinCategory = = UEdGraphSchema_K2 : : PC_Struct )
{
if ( UScriptStruct * ScriptStruct = Cast < UScriptStruct > ( PinType . PinSubCategoryObject ) )
{
2021-12-02 11:44:22 -05:00
if ( SchemaAction . IsValid ( ) & & SchemaAction . Pin ( ) - > IsAVariable ( ) )
2021-10-12 21:21:22 -04:00
{
2021-12-02 11:44:22 -05:00
if ( ScriptStruct - > IsChildOf ( FRigVMExecuteContext : : StaticStruct ( ) ) )
{
return false ;
}
2021-10-12 21:21:22 -04:00
}
2021-06-09 04:45:19 -04:00
return SupportsPinType ( ScriptStruct ) ;
}
}
if ( PinType . PinCategory = = UEdGraphSchema_K2 : : PC_Byte )
{
if ( PinType . PinSubCategoryObject . IsValid ( ) )
{
return PinType . PinSubCategoryObject - > IsA < UEnum > ( ) ;
}
}
return false ;
}
bool UControlRigGraphSchema : : SupportsPinTypeContainer ( TWeakPtr < const FEdGraphSchemaAction > SchemaAction ,
const FEdGraphPinType & PinType , const EPinContainerType & ContainerType ) const
{
2021-08-18 06:18:21 -04:00
return ContainerType = = EPinContainerType : : None | | ContainerType = = EPinContainerType : : Array ;
2021-06-09 04:45:19 -04:00
}
2018-04-12 16:57:51 -04:00
void UControlRigGraphSchema : : BreakPinLinks ( UEdGraphPin & TargetPin , bool bSendsNodeNotifcation ) const
{
2019-05-21 19:25:23 -04:00
//const FScopedTransaction Transaction( LOCTEXT("GraphEd_BreakPinLinks", "Break Pin Links") );
2018-04-12 16:57:51 -04:00
// cache this here, as BreakPinLinks can trigger a node reconstruction invalidating the TargetPin referenceS
2020-12-07 07:55:48 -04:00
if ( UControlRigGraphNode * Node = Cast < UControlRigGraphNode > ( TargetPin . GetOwningNode ( ) ) )
2019-04-12 10:01:39 -04:00
{
2021-07-19 06:35:29 -04:00
Node - > GetController ( ) - > BreakAllLinks ( TargetPin . GetName ( ) , TargetPin . Direction = = EGPD_Input , true , true ) ;
2019-04-12 10:01:39 -04:00
}
2018-04-12 16:57:51 -04:00
}
void UControlRigGraphSchema : : BreakSinglePinLink ( UEdGraphPin * SourcePin , UEdGraphPin * TargetPin ) const
{
2019-05-21 19:25:23 -04:00
//const FScopedTransaction Transaction(LOCTEXT("GraphEd_BreakSinglePinLink", "Break Pin Link") );
2018-04-12 16:57:51 -04:00
2020-12-07 07:55:48 -04:00
if ( UControlRigGraphNode * Node = Cast < UControlRigGraphNode > ( TargetPin - > GetOwningNode ( ) ) )
2019-04-12 10:01:39 -04:00
{
2019-05-21 19:25:23 -04:00
if ( SourcePin - > Direction = = EGPD_Input )
{
UEdGraphPin * Temp = TargetPin ;
TargetPin = SourcePin ;
SourcePin = Temp ;
}
2021-07-19 06:35:29 -04:00
Node - > GetController ( ) - > BreakLink ( SourcePin - > GetName ( ) , TargetPin - > GetName ( ) , true , true ) ;
2019-04-12 10:01:39 -04:00
}
2018-04-12 16:57:51 -04:00
}
2021-01-14 15:00:40 -04:00
bool UControlRigGraphSchema : : CanGraphBeDropped ( TSharedPtr < FEdGraphSchemaAction > InAction ) const
{
if ( ! InAction . IsValid ( ) )
{
return false ;
}
if ( InAction - > GetTypeId ( ) = = FEdGraphSchemaAction_K2Graph : : StaticGetTypeId ( ) )
{
FEdGraphSchemaAction_K2Graph * FuncAction = ( FEdGraphSchemaAction_K2Graph * ) InAction . Get ( ) ;
if ( UControlRigGraph * RigGraph = Cast < UControlRigGraph > ( ( UEdGraph * ) FuncAction - > EdGraph ) )
{
return true ;
}
}
2021-06-07 06:49:07 -04:00
else if ( InAction - > GetTypeId ( ) = = FControlRigGraphSchemaAction_LocalVar : : StaticGetTypeId ( ) )
{
FControlRigGraphSchemaAction_LocalVar * VarAction = ( FControlRigGraphSchemaAction_LocalVar * ) InAction . Get ( ) ;
if ( UControlRigGraph * RigGraph = Cast < UControlRigGraph > ( ( UEdGraph * ) VarAction - > GetVariableScope ( ) ) )
{
return true ;
}
}
2021-01-14 15:00:40 -04:00
return false ;
}
2021-06-07 06:49:07 -04:00
FReply UControlRigGraphSchema : : BeginGraphDragAction ( TSharedPtr < FEdGraphSchemaAction > InAction , const FPointerEvent & MouseEvent ) const
2021-01-14 15:00:40 -04:00
{
if ( ! InAction . IsValid ( ) )
{
return FReply : : Unhandled ( ) ;
}
if ( InAction - > GetTypeId ( ) = = FEdGraphSchemaAction_K2Graph : : StaticGetTypeId ( ) )
{
FEdGraphSchemaAction_K2Graph * FuncAction = ( FEdGraphSchemaAction_K2Graph * ) InAction . Get ( ) ;
2021-06-07 06:49:07 -04:00
if ( UControlRigGraph * RigGraph = Cast < UControlRigGraph > ( FuncAction - > EdGraph ) )
{
if ( UControlRigBlueprint * RigBlueprint = Cast < UControlRigBlueprint > ( FBlueprintEditorUtils : : FindBlueprintForGraph ( RigGraph ) ) )
{
TSharedRef < FControlRigFunctionDragDropAction > Action = FControlRigFunctionDragDropAction : : New ( InAction , RigBlueprint , RigGraph ) ;
Action - > SetAltDrag ( MouseEvent . IsAltDown ( ) ) ;
Action - > SetCtrlDrag ( MouseEvent . IsControlDown ( ) ) ;
return FReply : : Handled ( ) . BeginDragDrop ( Action ) ;
}
}
2021-01-27 05:06:20 -04:00
}
2021-06-07 06:49:07 -04:00
else if ( InAction - > GetTypeId ( ) = = FControlRigGraphSchemaAction_LocalVar : : StaticGetTypeId ( ) )
{
FControlRigGraphSchemaAction_LocalVar * VarAction = ( FControlRigGraphSchemaAction_LocalVar * ) InAction . Get ( ) ;
if ( UControlRigGraph * RigGraph = Cast < UControlRigGraph > ( VarAction - > GetVariableScope ( ) ) )
{
if ( UControlRigBlueprint * RigBlueprint = Cast < UControlRigBlueprint > ( FBlueprintEditorUtils : : FindBlueprintForGraph ( RigGraph ) ) )
{
TSharedRef < FControlRigFunctionDragDropAction > Action = FControlRigFunctionDragDropAction : : New ( InAction , RigBlueprint , RigGraph ) ;
Action - > SetAltDrag ( MouseEvent . IsAltDown ( ) ) ;
Action - > SetCtrlDrag ( MouseEvent . IsControlDown ( ) ) ;
return FReply : : Handled ( ) . BeginDragDrop ( Action ) ;
}
}
2021-01-14 15:00:40 -04:00
}
return FReply : : Unhandled ( ) ;
}
2018-04-12 16:57:51 -04:00
FConnectionDrawingPolicy * UControlRigGraphSchema : : CreateConnectionDrawingPolicy ( int32 InBackLayerID , int32 InFrontLayerID , float InZoomFactor , const FSlateRect & InClippingRect , class FSlateWindowElementList & InDrawElements , class UEdGraph * InGraphObj ) const
{
2019-01-08 11:38:48 -05:00
# if WITH_EDITOR
return IControlRigEditorModule : : Get ( ) . CreateConnectionDrawingPolicy ( InBackLayerID , InFrontLayerID , InZoomFactor , InClippingRect , InDrawElements , InGraphObj ) ;
# else
check ( 0 ) ;
return nullptr ;
# endif
2018-04-12 16:57:51 -04:00
}
bool UControlRigGraphSchema : : ShouldHidePinDefaultValue ( UEdGraphPin * Pin ) const
{
// we should hide default values if any of our parents are connected
return HasParentConnection_Recursive ( Pin ) ;
}
2020-01-22 17:58:55 -05:00
bool UControlRigGraphSchema : : IsPinBeingWatched ( UEdGraphPin const * Pin ) const
{
2020-12-07 07:55:48 -04:00
if ( UControlRigGraphNode * Node = Cast < UControlRigGraphNode > ( Pin - > GetOwningNode ( ) ) )
2020-01-22 17:58:55 -05:00
{
2020-12-07 07:55:48 -04:00
if ( URigVMPin * ModelPin = Node - > GetModel ( ) - > FindPin ( Pin - > GetName ( ) ) )
2020-01-22 17:58:55 -05:00
{
return ModelPin - > RequiresWatch ( ) ;
}
}
return false ;
}
void UControlRigGraphSchema : : ClearPinWatch ( UEdGraphPin const * Pin ) const
{
2020-12-07 07:55:48 -04:00
if ( UControlRigGraphNode * Node = Cast < UControlRigGraphNode > ( Pin - > GetOwningNode ( ) ) )
2020-01-22 17:58:55 -05:00
{
2020-12-07 07:55:48 -04:00
Node - > GetController ( ) - > SetPinIsWatched ( Pin - > GetName ( ) , false ) ;
2020-01-22 17:58:55 -05:00
}
}
void UControlRigGraphSchema : : OnPinConnectionDoubleCicked ( UEdGraphPin * PinA , UEdGraphPin * PinB , const FVector2D & GraphPosition ) const
{
2020-12-07 07:55:48 -04:00
if ( UControlRigGraphNode * Node = Cast < UControlRigGraphNode > ( PinA - > GetOwningNode ( ) ) )
2020-01-22 17:58:55 -05:00
{
2020-12-07 07:55:48 -04:00
if ( URigVMLink * Link = Node - > GetModel ( ) - > FindLink ( FString : : Printf ( TEXT ( " %s -> %s " ) , * PinA - > GetName ( ) , * PinB - > GetName ( ) ) ) )
2020-01-22 17:58:55 -05:00
{
2021-07-19 06:35:29 -04:00
Node - > GetController ( ) - > AddRerouteNodeOnLink ( Link , false , GraphPosition , FString ( ) , true , true ) ;
2020-01-22 17:58:55 -05:00
}
}
}
bool UControlRigGraphSchema : : MarkBlueprintDirtyFromNewNode ( UBlueprint * InBlueprint , UEdGraphNode * InEdGraphNode ) const
{
if ( InBlueprint = = nullptr | | InEdGraphNode = = nullptr )
{
return false ;
}
return true ;
}
bool UControlRigGraphSchema : : IsStructEditable ( UStruct * InStruct ) const
{
if ( InStruct = = FRuntimeFloatCurve : : StaticStruct ( ) )
{
return true ;
}
return false ;
}
2020-10-26 11:32:22 -04:00
void UControlRigGraphSchema : : SetNodePosition ( UEdGraphNode * Node , const FVector2D & Position ) const
{
2021-06-11 05:36:36 -04:00
return SetNodePosition ( Node , Position , true ) ;
}
void UControlRigGraphSchema : : SetNodePosition ( UEdGraphNode * Node , const FVector2D & Position , bool bSetupUndo ) const
{
StartGraphNodeInteraction ( Node ) ;
2020-10-26 11:32:22 -04:00
if ( UControlRigGraphNode * RigNode = Cast < UControlRigGraphNode > ( Node ) )
{
2021-07-19 06:35:29 -04:00
RigNode - > GetController ( ) - > SetNodePosition ( RigNode - > GetModelNode ( ) , Position , bSetupUndo , false , false ) ;
2020-10-26 11:32:22 -04:00
}
2021-06-11 06:33:25 -04:00
if ( UEdGraphNode_Comment * CommentNode = Cast < UEdGraphNode_Comment > ( Node ) )
{
if ( UControlRigGraph * Graph = CommentNode - > GetTypedOuter < UControlRigGraph > ( ) )
{
2021-07-19 06:35:29 -04:00
Graph - > GetController ( ) - > SetNodePositionByName ( CommentNode - > GetFName ( ) , Position , bSetupUndo , false , false ) ;
2021-06-11 06:33:25 -04:00
}
}
2020-10-26 11:32:22 -04:00
}
2020-12-14 08:58:12 -04:00
void UControlRigGraphSchema : : GetGraphDisplayInformation ( const UEdGraph & Graph , /*out*/ FGraphDisplayInfo & DisplayInfo ) const
{
Super : : GetGraphDisplayInformation ( Graph , DisplayInfo ) ;
if ( UControlRigGraph * RigGraph = Cast < UControlRigGraph > ( ( UEdGraph * ) & Graph ) )
{
TArray < FString > NodePathParts ;
2021-01-27 05:06:20 -04:00
if ( URigVMNode : : SplitNodePath ( RigGraph - > ModelNodePath , NodePathParts ) )
2020-12-14 08:58:12 -04:00
{
DisplayInfo . DisplayName = FText : : FromString ( NodePathParts . Last ( ) ) ;
DisplayInfo . PlainName = DisplayInfo . DisplayName ;
2021-06-08 16:32:53 -04:00
static const FText LocalFunctionText = FText : : FromString ( TEXT ( " A local function. " ) ) ;
DisplayInfo . Tooltip = LocalFunctionText ;
// if this is a riggraph within a collapse node - let's use that for the tooltip
if ( URigVMGraph * Model = RigGraph - > GetModel ( ) )
{
if ( URigVMCollapseNode * CollapseNode = Model - > GetTypedOuter < URigVMCollapseNode > ( ) )
{
DisplayInfo . Tooltip = CollapseNode - > GetToolTipText ( ) ;
}
}
}
else
{
static const FText MainGraphText = FText : : FromString ( TEXT ( " The main graph for the Control Rig. " ) ) ;
DisplayInfo . Tooltip = MainGraphText ;
2020-12-14 08:58:12 -04:00
}
}
}
2021-06-07 06:49:07 -04:00
bool UControlRigGraphSchema : : GetLocalVariables ( const UEdGraph * InGraph , TArray < FBPVariableDescription > & OutLocalVariables ) const
{
OutLocalVariables . Reset ( ) ;
if ( UControlRigGraph * RigGraph = Cast < UControlRigGraph > ( ( UEdGraph * ) InGraph ) )
{
if ( URigVMGraph * Model = RigGraph - > GetModel ( ) )
{
TArray < FRigVMGraphVariableDescription > LocalVariables = Model - > GetLocalVariables ( ) ;
for ( FRigVMGraphVariableDescription LocalVariable : LocalVariables )
{
FBPVariableDescription VariableDescription ;
VariableDescription . VarName = LocalVariable . Name ;
VariableDescription . FriendlyName = LocalVariable . Name . ToString ( ) ;
VariableDescription . DefaultValue = LocalVariable . DefaultValue ;
VariableDescription . VarType = LocalVariable . ToPinType ( ) ;
VariableDescription . PropertyFlags | = CPF_BlueprintVisible ;
OutLocalVariables . Add ( VariableDescription ) ;
}
}
}
return true ;
}
TSharedPtr < FEdGraphSchemaAction > UControlRigGraphSchema : : MakeActionFromVariableDescription ( const UEdGraph * InEdGraph ,
const FBPVariableDescription & Variable ) const
{
if ( UControlRigGraph * RigGraph = Cast < UControlRigGraph > ( ( UEdGraph * ) InEdGraph ) )
{
FText Category = Variable . Category ;
if ( Variable . Category . EqualTo ( UEdGraphSchema_K2 : : VR_DefaultCategory ) )
{
Category = FText : : GetEmpty ( ) ;
}
TSharedPtr < FControlRigGraphSchemaAction_LocalVar > Action = MakeShareable ( new FControlRigGraphSchemaAction_LocalVar ( Category , FText : : FromName ( Variable . VarName ) , FText : : GetEmpty ( ) , 0 , NodeSectionID : : LOCAL_VARIABLE ) ) ;
Action - > SetVariableInfo ( Variable . VarName , RigGraph , Variable . VarType . PinCategory = = UEdGraphSchema_K2 : : PC_Boolean ) ;
return Action ;
}
return nullptr ;
}
2021-01-27 05:06:20 -04:00
FText UControlRigGraphSchema : : GetGraphCategory ( const UEdGraph * InGraph ) const
{
if ( UControlRigGraph * RigGraph = Cast < UControlRigGraph > ( ( UEdGraph * ) InGraph ) )
{
if ( URigVMGraph * Model = RigGraph - > GetModel ( ) )
{
if ( URigVMCollapseNode * CollapseNode = Cast < URigVMCollapseNode > ( Model - > GetOuter ( ) ) )
{
return FText : : FromString ( CollapseNode - > GetNodeCategory ( ) ) ;
}
}
}
return FText ( ) ;
}
FReply UControlRigGraphSchema : : TrySetGraphCategory ( const UEdGraph * InGraph , const FText & InCategory )
{
if ( UControlRigGraph * RigGraph = Cast < UControlRigGraph > ( ( UEdGraph * ) InGraph ) )
{
if ( UControlRigBlueprint * RigBlueprint = Cast < UControlRigBlueprint > ( FBlueprintEditorUtils : : FindBlueprintForGraph ( RigGraph ) ) )
{
if ( URigVMGraph * Model = RigGraph - > GetModel ( ) )
{
if ( URigVMCollapseNode * CollapseNode = Cast < URigVMCollapseNode > ( Model - > GetOuter ( ) ) )
{
if ( URigVMController * Controller = RigBlueprint - > GetOrCreateController ( CollapseNode - > GetGraph ( ) ) )
{
2021-07-19 06:35:29 -04:00
if ( Controller - > SetNodeCategory ( CollapseNode , InCategory . ToString ( ) , true , false , true ) )
2021-01-27 05:06:20 -04:00
{
return FReply : : Handled ( ) ;
}
}
}
}
}
}
return FReply : : Unhandled ( ) ;
}
2020-12-14 08:58:12 -04:00
bool UControlRigGraphSchema : : TryDeleteGraph ( UEdGraph * GraphToDelete ) const
{
if ( UControlRigGraph * RigGraph = Cast < UControlRigGraph > ( GraphToDelete ) )
{
if ( UControlRigBlueprint * RigBlueprint = Cast < UControlRigBlueprint > ( FBlueprintEditorUtils : : FindBlueprintForGraph ( RigGraph ) ) )
{
2021-01-27 05:06:20 -04:00
if ( URigVMGraph * Model = RigBlueprint - > GetModel ( GraphToDelete ) )
2020-12-14 08:58:12 -04:00
{
2021-01-27 05:06:20 -04:00
if ( URigVMCollapseNode * LibraryNode = Cast < URigVMCollapseNode > ( Model - > GetOuter ( ) ) )
2021-01-14 15:00:40 -04:00
{
if ( URigVMController * Controller = RigBlueprint - > GetOrCreateController ( LibraryNode - > GetGraph ( ) ) )
2020-12-14 08:58:12 -04:00
{
2021-01-27 05:06:20 -04:00
// check if there is a "bulk remove function" transaction going on.
// which implies that a category is being deleted
if ( GEditor - > CanTransact ( ) )
{
if ( GEditor - > Trans - > GetQueueLength ( ) > 0 )
{
const FTransaction * LastTransaction = GEditor - > Trans - > GetTransaction ( GEditor - > Trans - > GetQueueLength ( ) - 1 ) ;
if ( LastTransaction )
{
if ( LastTransaction - > GetTitle ( ) . ToString ( ) = = TEXT ( " Bulk Remove Functions " ) )
{
// instead of deleting the graph, let's set its category to none
// and thus moving it to the top of the tree
return Controller - > SetNodeCategory ( LibraryNode , FString ( ) ) ;
}
}
}
}
2021-08-05 11:41:14 -04:00
bool bSetupUndoRedo = true ;
// if the element to remove is a function, check if it is public and referenced. If so,
// warn the user about a bulk remove
if ( URigVMFunctionLibrary * Library = Cast < URigVMFunctionLibrary > ( LibraryNode - > GetGraph ( ) ) )
{
const FName & FunctionName = LibraryNode - > GetFName ( ) ;
if ( RigBlueprint - > IsFunctionPublic ( FunctionName ) )
{
for ( auto Reference : Library - > GetReferencesForFunction ( FunctionName ) )
{
if ( Reference . IsValid ( ) )
{
UControlRigBlueprint * OtherBlueprint = Reference - > GetTypedOuter < UControlRigBlueprint > ( ) ;
if ( OtherBlueprint ! = RigBlueprint )
{
if ( RigBlueprint - > OnRequestBulkEditDialog ( ) . IsBound ( ) )
{
URigVMController * FunctionController = RigBlueprint - > GetController ( LibraryNode - > GetContainedGraph ( ) ) ;
FRigVMController_BulkEditResult Result = RigBlueprint - > OnRequestBulkEditDialog ( ) . Execute ( RigBlueprint , FunctionController , LibraryNode , ERigVMControllerBulkEditType : : RemoveFunction ) ;
if ( Result . bCanceled )
{
return false ;
}
bSetupUndoRedo = Result . bSetupUndoRedo ;
}
break ;
}
}
}
}
}
2021-01-27 05:06:20 -04:00
2021-08-05 11:41:14 -04:00
return Controller - > RemoveNode ( LibraryNode , bSetupUndoRedo , false , true ) ;
2020-12-14 08:58:12 -04:00
}
}
}
}
}
return false ;
}
bool UControlRigGraphSchema : : TryRenameGraph ( UEdGraph * GraphToRename , const FName & InNewName ) const
{
if ( UControlRigGraph * RigGraph = Cast < UControlRigGraph > ( GraphToRename ) )
{
if ( UControlRigBlueprint * RigBlueprint = Cast < UControlRigBlueprint > ( FBlueprintEditorUtils : : FindBlueprintForGraph ( RigGraph ) ) )
{
2021-11-09 11:31:17 -05:00
if ( URigVMGraph * Model = RigGraph - > GetModel ( ) )
2020-12-14 08:58:12 -04:00
{
2021-11-09 11:31:17 -05:00
if ( URigVMGraph * RootModel = Model - > GetRootGraph ( ) )
2020-12-14 08:58:12 -04:00
{
2021-11-09 11:31:17 -05:00
URigVMLibraryNode * LibraryNode = Cast < URigVMLibraryNode > ( RootModel - > FindNode ( RigGraph - > ModelNodePath ) ) ;
if ( LibraryNode )
2020-12-14 08:58:12 -04:00
{
2021-11-09 11:31:17 -05:00
if ( URigVMController * Controller = RigBlueprint - > GetOrCreateController ( LibraryNode - > GetGraph ( ) ) )
{
Controller - > RenameNode ( LibraryNode , InNewName , true , true ) ;
return true ;
}
2020-12-14 08:58:12 -04:00
}
}
}
}
}
return false ;
}
2021-01-05 09:12:57 -04:00
UEdGraphPin * UControlRigGraphSchema : : DropPinOnNode ( UEdGraphNode * InTargetNode , const FName & InSourcePinName , const FEdGraphPinType & InSourcePinType , EEdGraphPinDirection InSourcePinDirection ) const
{
FString NewPinName ;
if ( UControlRigBlueprint * RigBlueprint = Cast < UControlRigBlueprint > ( FBlueprintEditorUtils : : FindBlueprintForNode ( InTargetNode ) ) )
{
if ( UControlRigGraphNode * RigNode = Cast < UControlRigGraphNode > ( InTargetNode ) )
{
if ( URigVMNode * ModelNode = RigNode - > GetModelNode ( ) )
{
URigVMGraph * Model = nullptr ;
ERigVMPinDirection PinDirection = InSourcePinDirection = = EGPD_Input ? ERigVMPinDirection : : Input : ERigVMPinDirection : : Output ;
if ( URigVMCollapseNode * CollapseNode = Cast < URigVMCollapseNode > ( ModelNode ) )
{
Model = CollapseNode - > GetContainedGraph ( ) ;
PinDirection = PinDirection = = ERigVMPinDirection : : Output ? ERigVMPinDirection : : Input : ERigVMPinDirection : : Output ;
}
else if ( ModelNode - > IsA < URigVMFunctionEntryNode > ( ) | |
ModelNode - > IsA < URigVMFunctionReturnNode > ( ) )
{
Model = ModelNode - > GetGraph ( ) ;
}
if ( Model )
{
ensure ( ! Model - > IsTopLevelGraph ( ) ) ;
2021-11-18 08:00:07 -05:00
FRigVMExternalVariable ExternalVar = RigVMTypeUtils : : ExternalVariableFromPinType ( InSourcePinName , InSourcePinType ) ;
2021-01-05 09:12:57 -04:00
if ( ExternalVar . IsValid ( true /* allow null memory */ ) )
{
if ( URigVMController * Controller = RigBlueprint - > GetController ( Model ) )
{
FString TypeName = ExternalVar . TypeName . ToString ( ) ;
2021-10-20 11:50:24 -04:00
if ( ExternalVar . bIsArray )
{
TypeName = FString : : Printf ( URigVMController : : TArrayTemplate , * TypeName ) ;
}
2021-01-05 09:12:57 -04:00
FName TypeObjectPathName = NAME_None ;
if ( ExternalVar . TypeObject )
{
TypeObjectPathName = * ExternalVar . TypeObject - > GetPathName ( ) ;
}
2021-01-14 15:00:40 -04:00
FString DefaultValue ;
if ( PinBeingDropped )
{
if ( UControlRigGraphNode * SourceNode = Cast < UControlRigGraphNode > ( PinBeingDropped - > GetOwningNode ( ) ) )
{
if ( URigVMPin * SourcePin = SourceNode - > GetModelPinFromPinPath ( PinBeingDropped - > GetName ( ) ) )
{
DefaultValue = SourcePin - > GetDefaultValue ( ) ;
}
}
}
2021-01-05 09:12:57 -04:00
FName ExposedPinName = Controller - > AddExposedPin (
InSourcePinName ,
PinDirection ,
TypeName ,
TypeObjectPathName ,
2021-07-19 06:35:29 -04:00
DefaultValue ,
true ,
true
2021-01-05 09:12:57 -04:00
) ;
if ( ! ExposedPinName . IsNone ( ) )
{
NewPinName = ExposedPinName . ToString ( ) ;
}
}
}
}
if ( ! NewPinName . IsEmpty ( ) )
{
if ( URigVMPin * NewModelPin = ModelNode - > FindPin ( NewPinName ) )
{
return RigNode - > FindPin ( * NewModelPin - > GetPinPath ( ) ) ;
}
}
}
}
}
return nullptr ;
}
bool UControlRigGraphSchema : : SupportsDropPinOnNode ( UEdGraphNode * InTargetNode , const FEdGraphPinType & InSourcePinType , EEdGraphPinDirection InSourcePinDirection , FText & OutErrorMessage ) const
{
if ( UControlRigGraphNode * RigNode = Cast < UControlRigGraphNode > ( InTargetNode ) )
{
if ( URigVMNode * ModelNode = RigNode - > GetModelNode ( ) )
{
if ( ModelNode - > IsA < URigVMFunctionEntryNode > ( ) )
{
if ( InSourcePinDirection = = EGPD_Output )
{
OutErrorMessage = LOCTEXT ( " AddPinToReturnNode " , " Add Pin to Return Node " ) ;
return false ;
}
return true ;
}
else if ( ModelNode - > IsA < URigVMFunctionReturnNode > ( ) )
{
if ( InSourcePinDirection = = EGPD_Input )
{
OutErrorMessage = LOCTEXT ( " AddPinToEntryNode " , " Add Pin to Entry Node " ) ;
return false ;
}
return true ;
}
else if ( ModelNode - > IsA < URigVMCollapseNode > ( ) )
{
return true ;
}
}
}
return false ;
}
2018-04-12 16:57:51 -04:00
UControlRigGraphNode * UControlRigGraphSchema : : CreateGraphNode ( UControlRigGraph * InGraph , const FName & InPropertyName ) const
{
const bool bSelectNewNode = true ;
FGraphNodeCreator < UControlRigGraphNode > GraphNodeCreator ( * InGraph ) ;
UControlRigGraphNode * ControlRigGraphNode = GraphNodeCreator . CreateNode ( bSelectNewNode ) ;
2020-01-22 17:58:55 -05:00
ControlRigGraphNode - > ModelNodePath = InPropertyName . ToString ( ) ;
2018-04-12 16:57:51 -04:00
GraphNodeCreator . Finalize ( ) ;
return ControlRigGraphNode ;
}
2019-07-16 11:49:59 -04:00
void UControlRigGraphSchema : : TrySetDefaultValue ( UEdGraphPin & InPin , const FString & InNewDefaultValue , bool bMarkAsModified ) const
2018-04-12 16:57:51 -04:00
{
2019-05-21 19:25:23 -04:00
# if WITH_EDITOR
if ( GEditor )
{
GEditor - > CancelTransaction ( 0 ) ;
}
# endif
2019-07-16 11:49:59 -04:00
GetDefault < UEdGraphSchema_K2 > ( ) - > TrySetDefaultValue ( InPin , InNewDefaultValue , false ) ;
2018-04-12 16:57:51 -04:00
}
2019-07-16 11:49:59 -04:00
void UControlRigGraphSchema : : TrySetDefaultObject ( UEdGraphPin & InPin , UObject * InNewDefaultObject , bool bMarkAsModified ) const
2018-04-12 16:57:51 -04:00
{
2019-05-21 19:25:23 -04:00
# if WITH_EDITOR
if ( GEditor )
{
GEditor - > CancelTransaction ( 0 ) ;
}
# endif
2019-07-16 11:49:59 -04:00
GetDefault < UEdGraphSchema_K2 > ( ) - > TrySetDefaultObject ( InPin , InNewDefaultObject , false ) ;
2018-04-12 16:57:51 -04:00
}
2019-07-16 11:49:59 -04:00
void UControlRigGraphSchema : : TrySetDefaultText ( UEdGraphPin & InPin , const FText & InNewDefaultText , bool bMarkAsModified ) const
2018-04-12 16:57:51 -04:00
{
2019-05-21 19:25:23 -04:00
# if WITH_EDITOR
if ( GEditor )
{
GEditor - > CancelTransaction ( 0 ) ;
}
# endif
2019-07-16 11:49:59 -04:00
GetDefault < UEdGraphSchema_K2 > ( ) - > TrySetDefaultText ( InPin , InNewDefaultText , false ) ;
2018-04-12 16:57:51 -04:00
}
bool UControlRigGraphSchema : : ArePinsCompatible ( const UEdGraphPin * PinA , const UEdGraphPin * PinB , const UClass * CallingContext , bool bIgnoreArray /*= false*/ ) const
{
2019-04-24 18:34:05 -04:00
// filter out pins which have a parent
if ( PinB - > ParentPin ! = nullptr )
{
return false ;
}
2020-01-22 17:58:55 -05:00
2020-12-14 08:58:12 -04:00
if ( UControlRigGraphNode * GraphNode = Cast < UControlRigGraphNode > ( PinB - > GetOwningNode ( ) ) )
{
}
2020-01-22 17:58:55 -05:00
// for reroute nodes - always allow it
2021-09-08 07:57:30 -04:00
if ( PinA - > PinType . PinCategory = = TEXT ( " ANY_TYPE " ) )
2020-01-22 17:58:55 -05:00
{
UControlRigGraphSchema * MutableThis = ( UControlRigGraphSchema * ) this ;
MutableThis - > LastPinForCompatibleCheck = PinB ;
2020-02-04 11:06:23 -05:00
MutableThis - > bLastPinWasInput = PinB - > Direction = = EGPD_Input ;
2020-01-22 17:58:55 -05:00
return true ;
}
2021-09-08 07:57:30 -04:00
if ( PinB - > PinType . PinCategory = = TEXT ( " ANY_TYPE " ) )
2020-01-22 17:58:55 -05:00
{
UControlRigGraphSchema * MutableThis = ( UControlRigGraphSchema * ) this ;
MutableThis - > LastPinForCompatibleCheck = PinA ;
2020-02-04 11:06:23 -05:00
MutableThis - > bLastPinWasInput = PinA - > Direction = = EGPD_Input ;
2020-01-22 17:58:55 -05:00
return true ;
}
2021-09-08 07:57:30 -04:00
// if we are looking at a polymorphic node
if ( ( PinA - > PinType . ContainerType = = PinB - > PinType . ContainerType ) | |
( PinA - > PinType . PinSubCategoryObject ! = PinB - > PinType . PinSubCategoryObject ) )
{
if ( PinA - > PinType . PinCategory = = UEdGraphSchema_K2 : : PC_Struct & & PinA - > PinType . PinSubCategoryObject = = FRigVMUnknownType : : StaticStruct ( ) )
{
bool bIsExecuteContext = false ;
if ( const UScriptStruct * ExecuteContextScriptStruct = Cast < UScriptStruct > ( PinB - > PinType . PinSubCategoryObject ) )
{
bIsExecuteContext = ExecuteContextScriptStruct - > IsChildOf ( FRigVMExecuteContext : : StaticStruct ( ) ) ;
}
if ( ! bIsExecuteContext )
{
UControlRigGraphSchema * MutableThis = ( UControlRigGraphSchema * ) this ;
MutableThis - > LastPinForCompatibleCheck = PinB ;
MutableThis - > bLastPinWasInput = PinB - > Direction = = EGPD_Input ;
return true ;
}
}
else if ( PinB - > PinType . PinCategory = = UEdGraphSchema_K2 : : PC_Struct & & PinB - > PinType . PinSubCategoryObject = = FRigVMUnknownType : : StaticStruct ( ) )
{
bool bIsExecuteContext = false ;
if ( const UScriptStruct * ExecuteContextScriptStruct = Cast < UScriptStruct > ( PinA - > PinType . PinSubCategoryObject ) )
{
bIsExecuteContext = ExecuteContextScriptStruct - > IsChildOf ( FRigVMExecuteContext : : StaticStruct ( ) ) ;
}
if ( ! bIsExecuteContext )
{
UControlRigGraphSchema * MutableThis = ( UControlRigGraphSchema * ) this ;
MutableThis - > LastPinForCompatibleCheck = PinA ;
MutableThis - > bLastPinWasInput = PinA - > Direction = = EGPD_Input ;
return true ;
}
}
}
2021-08-23 09:02:38 -04:00
// if large world coordinate support is enabled we should allow connections
// between float and double
# if !UE_LARGE_WORLD_COORDINATES_DISABLED
if ( PinA - > PinType . ContainerType = = EPinContainerType : : None & &
PinB - > PinType . ContainerType = = EPinContainerType : : None )
{
if ( ( PinA - > PinType . PinCategory = = UEdGraphSchema_K2 : : PC_Float & &
PinB - > PinType . PinCategory = = UEdGraphSchema_K2 : : PC_Double ) | |
( PinA - > PinType . PinCategory = = UEdGraphSchema_K2 : : PC_Double & &
PinB - > PinType . PinCategory = = UEdGraphSchema_K2 : : PC_Float ) )
{
return true ;
}
}
# endif
2020-09-24 00:43:27 -04:00
struct Local
{
static FString GetCPPTypeFromPinType ( const FEdGraphPinType & InPinType )
{
return FString ( ) ;
}
} ;
if ( PinA - > PinType . PinCategory . IsNone ( ) & & PinB - > PinType . PinCategory . IsNone ( ) )
{
return true ;
}
else if ( PinA - > PinType . PinCategory . IsNone ( ) & & ! PinB - > PinType . PinCategory . IsNone ( ) )
{
if ( UControlRigGraphNode * RigNode = Cast < UControlRigGraphNode > ( PinA - > GetOwningNode ( ) ) )
{
if ( URigVMPrototypeNode * PrototypeNode = Cast < URigVMPrototypeNode > ( RigNode - > GetModelNode ( ) ) )
{
FString CPPType = Local : : GetCPPTypeFromPinType ( PinB - > PinType ) ;
FString Left , Right ;
URigVMPin : : SplitPinPathAtStart ( PinA - > GetName ( ) , Left , Right ) ;
if ( URigVMPin * ModelPin = PrototypeNode - > FindPin ( Right ) )
{
return PrototypeNode - > SupportsType ( ModelPin , CPPType ) ;
}
}
}
}
else if ( ! PinA - > PinType . PinCategory . IsNone ( ) & & PinB - > PinType . PinCategory . IsNone ( ) )
{
if ( UControlRigGraphNode * RigNode = Cast < UControlRigGraphNode > ( PinB - > GetOwningNode ( ) ) )
{
if ( URigVMPrototypeNode * PrototypeNode = Cast < URigVMPrototypeNode > ( RigNode - > GetModelNode ( ) ) )
{
FString CPPType = Local : : GetCPPTypeFromPinType ( PinA - > PinType ) ;
FString Left , Right ;
URigVMPin : : SplitPinPathAtStart ( PinB - > GetName ( ) , Left , Right ) ;
if ( URigVMPin * ModelPin = PrototypeNode - > FindPin ( Right ) )
{
return PrototypeNode - > SupportsType ( ModelPin , CPPType ) ;
}
}
}
}
2018-04-12 16:57:51 -04:00
return GetDefault < UEdGraphSchema_K2 > ( ) - > ArePinsCompatible ( PinA , PinB , CallingContext , bIgnoreArray ) ;
}
2019-04-02 11:26:55 -04:00
void UControlRigGraphSchema : : RenameNode ( UControlRigGraphNode * Node , const FName & InNewNodeName ) const
{
2020-01-22 17:58:55 -05:00
Node - > NodeTitle = FText : : FromName ( InNewNodeName ) ;
2019-04-02 11:26:55 -04:00
Node - > Modify ( ) ;
}
2019-04-12 10:01:39 -04:00
void UControlRigGraphSchema : : ResetPinDefaultsRecursive ( UEdGraphPin * InPin ) const
{
UControlRigGraphNode * RigNode = Cast < UControlRigGraphNode > ( InPin - > GetOwningNode ( ) ) ;
if ( RigNode = = nullptr )
{
return ;
}
2019-05-21 19:25:23 -04:00
RigNode - > CopyPinDefaultsToModel ( InPin ) ;
2019-04-12 10:01:39 -04:00
for ( UEdGraphPin * SubPin : InPin - > SubPins )
{
ResetPinDefaultsRecursive ( SubPin ) ;
}
}
2019-04-24 18:34:05 -04:00
void UControlRigGraphSchema : : GetVariablePinTypes ( TArray < FEdGraphPinType > & PinTypes ) const
{
PinTypes . Add ( FEdGraphPinType ( UEdGraphSchema_K2 : : PC_Boolean , FName ( NAME_None ) , nullptr , EPinContainerType : : None , false , FEdGraphTerminalType ( ) ) ) ;
PinTypes . Add ( FEdGraphPinType ( UEdGraphSchema_K2 : : PC_Float , FName ( NAME_None ) , nullptr , EPinContainerType : : None , false , FEdGraphTerminalType ( ) ) ) ;
2021-06-22 14:11:52 -04:00
PinTypes . Add ( FEdGraphPinType ( UEdGraphSchema_K2 : : PC_Double , FName ( NAME_None ) , nullptr , EPinContainerType : : None , false , FEdGraphTerminalType ( ) ) ) ;
2019-04-24 18:34:05 -04:00
PinTypes . Add ( FEdGraphPinType ( UEdGraphSchema_K2 : : PC_Int , FName ( NAME_None ) , nullptr , EPinContainerType : : None , false , FEdGraphTerminalType ( ) ) ) ;
PinTypes . Add ( FEdGraphPinType ( UEdGraphSchema_K2 : : PC_Struct , FName ( NAME_None ) , TBaseStructure < FVector > : : Get ( ) , EPinContainerType : : None , false , FEdGraphTerminalType ( ) ) ) ;
PinTypes . Add ( FEdGraphPinType ( UEdGraphSchema_K2 : : PC_Struct , FName ( NAME_None ) , TBaseStructure < FVector2D > : : Get ( ) , EPinContainerType : : None , false , FEdGraphTerminalType ( ) ) ) ;
PinTypes . Add ( FEdGraphPinType ( UEdGraphSchema_K2 : : PC_Struct , FName ( NAME_None ) , TBaseStructure < FRotator > : : Get ( ) , EPinContainerType : : None , false , FEdGraphTerminalType ( ) ) ) ;
PinTypes . Add ( FEdGraphPinType ( UEdGraphSchema_K2 : : PC_Struct , FName ( NAME_None ) , TBaseStructure < FTransform > : : Get ( ) , EPinContainerType : : None , false , FEdGraphTerminalType ( ) ) ) ;
2019-05-21 19:25:23 -04:00
PinTypes . Add ( FEdGraphPinType ( UEdGraphSchema_K2 : : PC_Struct , FName ( NAME_None ) , TBaseStructure < FEulerTransform > : : Get ( ) , EPinContainerType : : None , false , FEdGraphTerminalType ( ) ) ) ;
2019-04-24 18:34:05 -04:00
PinTypes . Add ( FEdGraphPinType ( UEdGraphSchema_K2 : : PC_Struct , FName ( NAME_None ) , TBaseStructure < FLinearColor > : : Get ( ) , EPinContainerType : : None , false , FEdGraphTerminalType ( ) ) ) ;
}
2019-04-12 10:01:39 -04:00
2020-02-04 11:06:23 -05:00
bool UControlRigGraphSchema : : SafeDeleteNodeFromGraph ( UEdGraph * Graph , UEdGraphNode * Node ) const
{
if ( UControlRigGraphNode * RigNode = Cast < UControlRigGraphNode > ( Node ) )
{
2021-07-19 06:35:29 -04:00
return RigNode - > GetController ( ) - > RemoveNode ( RigNode - > GetModelNode ( ) , true , false , true ) ;
2020-02-04 11:06:23 -05:00
}
return false ;
}
2020-09-24 00:43:27 -04:00
bool UControlRigGraphSchema : : CanVariableBeDropped ( UEdGraph * InGraph , FProperty * InVariableToDrop ) const
{
FRigVMExternalVariable ExternalVariable = FRigVMExternalVariable : : Make ( InVariableToDrop , nullptr ) ;
return ExternalVariable . IsValid ( true /* allow nullptr */ ) ;
}
bool UControlRigGraphSchema : : RequestVariableDropOnPanel ( UEdGraph * InGraph , FProperty * InVariableToDrop , const FVector2D & InDropPosition , const FVector2D & InScreenPosition )
{
# if WITH_EDITOR
if ( CanVariableBeDropped ( InGraph , InVariableToDrop ) )
{
FRigVMExternalVariable ExternalVariable = FRigVMExternalVariable : : Make ( InVariableToDrop , nullptr ) ;
UBlueprint * Blueprint = FBlueprintEditorUtils : : FindBlueprintForGraph ( InGraph ) ;
UControlRigBlueprint * RigBlueprint = Cast < UControlRigBlueprint > ( Blueprint ) ;
if ( RigBlueprint ! = nullptr )
{
RigBlueprint - > OnVariableDropped ( ) . Broadcast ( InGraph , InVariableToDrop , InDropPosition , InScreenPosition ) ;
return true ;
}
}
# endif
return false ;
}
2020-10-26 06:51:31 -04:00
bool UControlRigGraphSchema : : RequestVariableDropOnPin ( UEdGraph * InGraph , FProperty * InVariableToDrop , UEdGraphPin * InPin , const FVector2D & InDropPosition , const FVector2D & InScreenPosition )
{
# if WITH_EDITOR
if ( CanVariableBeDropped ( InGraph , InVariableToDrop ) )
{
2020-12-07 07:55:48 -04:00
if ( UControlRigGraph * Graph = Cast < UControlRigGraph > ( InGraph ) )
2020-10-26 06:51:31 -04:00
{
2020-12-07 07:55:48 -04:00
if ( URigVMPin * ModelPin = Graph - > GetModel ( ) - > FindPin ( InPin - > GetName ( ) ) )
2020-10-26 06:51:31 -04:00
{
FRigVMExternalVariable ExternalVariable = FRigVMExternalVariable : : Make ( InVariableToDrop , nullptr ) ;
if ( ModelPin - > CanBeBoundToVariable ( ExternalVariable ) )
{
FModifierKeysState KeyState = FSlateApplication : : Get ( ) . GetModifierKeys ( ) ;
if ( KeyState . IsAltDown ( ) )
{
2021-07-19 06:35:29 -04:00
return Graph - > GetController ( ) - > BindPinToVariable ( ModelPin - > GetPinPath ( ) , InVariableToDrop - > GetName ( ) , true , true ) ;
2020-10-26 06:51:31 -04:00
}
else
{
2020-12-07 07:55:48 -04:00
Graph - > GetController ( ) - > OpenUndoBracket ( TEXT ( " Bind Variable to Pin " ) ) ;
if ( URigVMVariableNode * VariableNode = Graph - > GetController ( ) - > AddVariableNode ( ExternalVariable . Name , ExternalVariable . TypeName . ToString ( ) , ExternalVariable . TypeObject , true , FString ( ) , InDropPosition + FVector2D ( 0.f , - 34.f ) ) )
2020-10-26 06:51:31 -04:00
{
2020-12-07 07:55:48 -04:00
Graph - > GetController ( ) - > AddLink ( VariableNode - > FindPin ( TEXT ( " Value " ) ) - > GetPinPath ( ) , ModelPin - > GetPinPath ( ) , true ) ;
2020-10-26 06:51:31 -04:00
}
2020-12-07 07:55:48 -04:00
Graph - > GetController ( ) - > CloseUndoBracket ( ) ;
2020-10-26 06:51:31 -04:00
return true ;
}
}
}
}
}
# endif
return false ;
}
2021-06-11 05:36:36 -04:00
void UControlRigGraphSchema : : StartGraphNodeInteraction ( UEdGraphNode * InNode ) const
{
# if WITH_EDITOR
check ( InNode ) ;
if ( NodesBeingInteracted . Contains ( InNode ) )
{
return ;
}
NodePositionsDuringStart . Reset ( ) ;
NodesBeingInteracted . Reset ( ) ;
UControlRigGraph * Graph = Cast < UControlRigGraph > ( InNode - > GetOuter ( ) ) ;
if ( Graph = = nullptr )
{
return ;
}
check ( Graph - > GetController ( ) ) ;
check ( Graph - > GetModel ( ) ) ;
NodesBeingInteracted = GetNodesToMoveForNode ( InNode ) ;
for ( UEdGraphNode * NodeToMove : NodesBeingInteracted )
{
FName NodeName = NodeToMove - > GetFName ( ) ;
if ( URigVMNode * ModelNode = Graph - > GetModel ( ) - > FindNodeByName ( NodeName ) )
{
NodePositionsDuringStart . FindOrAdd ( NodeName , ModelNode - > GetPosition ( ) ) ;
}
}
# endif
}
2020-09-24 00:43:27 -04:00
void UControlRigGraphSchema : : EndGraphNodeInteraction ( UEdGraphNode * InNode ) const
{
# if WITH_EDITOR
UControlRigGraph * Graph = Cast < UControlRigGraph > ( InNode - > GetOuter ( ) ) ;
if ( Graph = = nullptr )
{
return ;
}
2020-12-07 07:55:48 -04:00
check ( Graph - > GetController ( ) ) ;
check ( Graph - > GetModel ( ) ) ;
2020-09-24 00:43:27 -04:00
2021-06-11 05:36:36 -04:00
TArray < UEdGraphNode * > NodesToMove = GetNodesToMoveForNode ( InNode ) ;
bool bMovedSomething = false ;
Graph - > GetController ( ) - > OpenUndoBracket ( TEXT ( " Move Nodes " ) ) ;
for ( UEdGraphNode * NodeToMove : NodesToMove )
{
FName NodeName = NodeToMove - > GetFName ( ) ;
if ( URigVMNode * ModelNode = Graph - > GetModel ( ) - > FindNodeByName ( NodeName ) )
{
2021-06-11 06:33:25 -04:00
FVector2D NewPosition ( NodeToMove - > NodePosX , NodeToMove - > NodePosY ) ;
2021-06-11 05:36:36 -04:00
if ( FVector2D * OldPosition = NodePositionsDuringStart . Find ( NodeName ) )
{
2021-06-11 06:33:25 -04:00
TGuardValue < bool > SuspendNotification ( Graph - > bSuspendModelNotifications , true ) ;
2021-06-11 05:36:36 -04:00
Graph - > GetController ( ) - > SetNodePositionByName ( NodeName , * OldPosition , false , false ) ;
}
2021-07-19 06:35:29 -04:00
if ( Graph - > GetController ( ) - > SetNodePositionByName ( NodeName , NewPosition , true , false , true ) )
2021-06-11 05:36:36 -04:00
{
bMovedSomething = true ;
}
}
}
if ( bMovedSomething )
{
2021-06-11 06:33:25 -04:00
if ( GEditor )
{
GEditor - > CancelTransaction ( 0 ) ;
}
2021-06-11 05:36:36 -04:00
Graph - > GetController ( ) - > CloseUndoBracket ( ) ;
}
else
{
Graph - > GetController ( ) - > CancelUndoBracket ( ) ;
}
NodesBeingInteracted . Reset ( ) ;
NodePositionsDuringStart . Reset ( ) ;
# endif
}
TArray < UEdGraphNode * > UControlRigGraphSchema : : GetNodesToMoveForNode ( UEdGraphNode * InNode )
{
2020-09-24 00:43:27 -04:00
TArray < UEdGraphNode * > NodesToMove ;
2021-06-11 05:36:36 -04:00
# if WITH_EDITOR
UControlRigGraph * Graph = Cast < UControlRigGraph > ( InNode - > GetOuter ( ) ) ;
if ( Graph = = nullptr )
{
return NodesToMove ;
}
2020-09-24 00:43:27 -04:00
NodesToMove . Add ( InNode ) ;
for ( UEdGraphNode * SelectedGraphNode : Graph - > Nodes )
{
if ( SelectedGraphNode - > IsSelected ( ) )
{
NodesToMove . AddUnique ( SelectedGraphNode ) ;
}
}
for ( int32 NodeIndex = 0 ; NodeIndex < NodesToMove . Num ( ) ; NodeIndex + + )
{
if ( UEdGraphNode_Comment * CommentNode = Cast < UEdGraphNode_Comment > ( NodesToMove [ NodeIndex ] ) )
{
if ( CommentNode - > MoveMode = = ECommentBoxMode : : GroupMovement )
{
for ( FCommentNodeSet : : TConstIterator NodeIt ( CommentNode - > GetNodesUnderComment ( ) ) ; NodeIt ; + + NodeIt )
{
if ( UEdGraphNode * NodeUnderComment = Cast < UEdGraphNode > ( * NodeIt ) )
{
NodesToMove . AddUnique ( NodeUnderComment ) ;
}
}
}
}
}
# endif
2021-06-11 05:36:36 -04:00
return NodesToMove ;
2020-09-24 00:43:27 -04:00
}
2019-04-12 10:01:39 -04:00
2021-06-11 06:33:25 -04:00
FVector2D UControlRigGraphSchema : : GetNodePositionAtStartOfInteraction ( UEdGraphNode * InNode ) const
{
# if WITH_EDITOR
if ( InNode )
{
if ( const FVector2D * Position = NodePositionsDuringStart . Find ( InNode - > GetFName ( ) ) )
{
return * Position ;
}
return FVector2D ( InNode - > NodePosX , InNode - > NodePosY ) ;
}
# endif
return FVector2D : : ZeroVector ;
}
2021-09-08 10:41:30 -04:00
void UControlRigGraphSchema : : HandleModifiedEvent ( ERigVMGraphNotifType InNotifType , URigVMGraph * InGraph ,
UObject * InSubject )
{
switch ( InNotifType )
{
case ERigVMGraphNotifType : : NodeAdded :
case ERigVMGraphNotifType : : NodeRemoved :
case ERigVMGraphNotifType : : PinAdded :
case ERigVMGraphNotifType : : PinRemoved :
case ERigVMGraphNotifType : : PinRenamed :
case ERigVMGraphNotifType : : PinArraySizeChanged :
case ERigVMGraphNotifType : : PinTypeChanged :
case ERigVMGraphNotifType : : LinkAdded :
case ERigVMGraphNotifType : : LinkRemoved :
{
LastPinForCompatibleCheck = nullptr ;
break ;
}
default :
{
break ;
}
}
}
2021-06-11 05:36:36 -04:00
2021-04-06 18:39:05 -04:00
# undef LOCTEXT_NAMESPACE