2014-03-14 14:13:41 -04:00
// Copyright 1998-2014 Epic Games, Inc. All Rights Reserved.
# include "BlueprintGraphPrivatePCH.h"
2014-05-29 17:11:10 -04:00
# include "Engine/LevelScriptBlueprint.h"
2014-03-14 14:13:41 -04:00
# include "K2ActionMenuBuilder.h"
# include "ComponentAssetBroker.h"
# include "KismetEditorUtilities.h"
# include "ObjectEditorUtils.h"
2014-05-22 06:52:28 -04:00
# include "Matinee/MatineeActor.h"
2014-03-14 14:13:41 -04:00
2014-05-29 16:42:22 -04:00
# include "K2Node_CastByteToEnum.h"
# include "K2Node_ClassDynamicCast.h"
# include "K2Node_EnumLiteral.h"
# include "K2Node_ForEachElementInEnum.h"
# include "K2Node_GetEnumeratorName.h"
# include "K2Node_GetEnumeratorNameAsString.h"
# include "K2Node_GetInputAxisValue.h"
# include "K2Node_GetInputVectorAxisValue.h"
# include "K2Node_GetNumEnumEntries.h"
# include "K2Node_InputAxisKeyEvent.h"
# include "K2Node_InputVectorAxisEvent.h"
# include "K2Node_Message.h"
# include "K2Node_MultiGate.h"
# include "K2Node_SwitchEnum.h"
# include "K2Node_SwitchString.h"
# include "K2Node_VariableSetRef.h"
# include "EdGraphSchema_K2_Actions.h"
2014-03-14 14:13:41 -04:00
# define LOCTEXT_NAMESPACE "KismetSchema"
/*******************************************************************************
* Static File Helpers
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
namespace K2ActionCategories
{
static FString const SubCategoryDelim ( " | " ) ;
static FString const AddEventCategory = LOCTEXT ( " AddEventCategory " , " Add Event " ) . ToString ( ) ;
static FString const AddEventForPrefix = LOCTEXT ( " AddEventForPrefix " , " Add Event for " ) . ToString ( ) ;
static FString const AddEventForActorsCategory = LOCTEXT ( " EventForActorsCategory " , " Add event for selected actors " ) . ToString ( ) ;
static FString const AnimNotifyCategory = LOCTEXT ( " AnimNotifyCategory " , " Add AnimNotify Event " ) . ToString ( ) ;
static FString const BranchPointCategory = LOCTEXT ( " BranchPointCategory " , " Add Montage Branching Point Event " ) . ToString ( ) ;
static FString const StateMachineCategory = LOCTEXT ( " StateMachineCategory " , " Add State Machine Event " ) . ToString ( ) ;
static FString const DefaultEventDispatcherCategory = LOCTEXT ( " DispatchersCategory " , " Event Dispatchers " ) . ToString ( ) ;
static FString const DelegateCategory = LOCTEXT ( " DelegateCategory " , " Event Dispatcher " ) . ToString ( ) ;
static FString const DelegateBindingCategory = LOCTEXT ( " DelegateBindingCategory " , " Assign Event Dispatcher " ) . ToString ( ) ;
static FString const InputCategory = LOCTEXT ( " InputCategory " , " Input " ) . ToString ( ) ;
static FString const ActionEventsSubCategory = LOCTEXT ( " ActionEventsCategory " , " Action Events " ) . ToString ( ) ;
static FString const AxisValuesSubCategory = LOCTEXT ( " ActionValuesCategory " , " Axis Values " ) . ToString ( ) ;
static FString const AxisEventsSubCategory = LOCTEXT ( " AxisEventsCategory " , " Axis Events " ) . ToString ( ) ;
static FString const KeyEventsSubCategory = LOCTEXT ( " KeyEventsCategory " , " Key Events " ) . ToString ( ) ;
2014-04-23 18:28:49 -04:00
static FString const KeyValuesSubCategory = LOCTEXT ( " KeyValuesCategory " , " Key Values " ) . ToString ( ) ;
2014-03-14 14:13:41 -04:00
static FString const GamepadEventsSubCategory = LOCTEXT ( " GamepadEventsCategory " , " Gamepad Events " ) . ToString ( ) ;
2014-04-23 18:28:49 -04:00
static FString const GamepadValuesSubCategory = LOCTEXT ( " GamepadValuesCategory " , " Gamepad Values " ) . ToString ( ) ;
2014-03-14 14:13:41 -04:00
static FString const MouseEventsSubCategory = LOCTEXT ( " MouseEventsCategory " , " Mouse Events " ) . ToString ( ) ;
2014-04-23 18:28:49 -04:00
static FString const MouseValuesSubCategory = LOCTEXT ( " MouseValuesCategory " , " Mouse Values " ) . ToString ( ) ;
2014-03-14 14:13:41 -04:00
static FString const ActionEventsCategory = InputCategory + SubCategoryDelim + ActionEventsSubCategory ;
static FString const AxisCategory = InputCategory + SubCategoryDelim + AxisValuesSubCategory ;
static FString const AxisEventCategory = InputCategory + SubCategoryDelim + AxisEventsSubCategory ;
static FString const KeyEventsCategory = InputCategory + SubCategoryDelim + KeyEventsSubCategory ;
2014-04-23 18:28:49 -04:00
static FString const KeyValuesCategory = InputCategory + SubCategoryDelim + KeyValuesSubCategory ;
2014-03-14 14:13:41 -04:00
static FString const GamepadEventsCategory = InputCategory + SubCategoryDelim + GamepadEventsSubCategory ;
2014-04-23 18:28:49 -04:00
static FString const GamepadValuesCategory = InputCategory + SubCategoryDelim + GamepadValuesSubCategory ;
2014-03-14 14:13:41 -04:00
static FString const MouseEventsCategory = InputCategory + SubCategoryDelim + MouseEventsSubCategory ;
2014-04-23 18:28:49 -04:00
static FString const MouseValuesCategory = InputCategory + SubCategoryDelim + MouseValuesSubCategory ;
2014-03-14 14:13:41 -04:00
static FString const TouchEventsCategory = InputCategory ;
static FString const UtilitiesCategory = LOCTEXT ( " UtilityCategory " , " Utilities " ) . ToString ( ) ;
static FString const ArraySubCategory = LOCTEXT ( " ArrayCategory " , " Array " ) . ToString ( ) ;
static FString const CastingSubCategory = LOCTEXT ( " CastingCategory " , " Casting " ) . ToString ( ) ;
static FString const EnumSubCategory = LOCTEXT ( " EnumCategory " , " Enum " ) . ToString ( ) ;
static FString const FlowSubCategory = LOCTEXT ( " FlowCategory " , " Flow Control " ) . ToString ( ) ;
static FString const SwitchSubCategory = LOCTEXT ( " SwitchCategory " , " Switch " ) . ToString ( ) ;
static FString const MacroToolsSubCategory = LOCTEXT ( " MacroCategory " , " Macro " ) . ToString ( ) ;
static FString const NameSubCategory = LOCTEXT ( " NameCategory " , " Name " ) . ToString ( ) ;
static FString const StringSubCategory = LOCTEXT ( " StringCategory " , " String " ) . ToString ( ) ;
static FString const StructSubCategory = LOCTEXT ( " StructCategory " , " Struct " ) . ToString ( ) ;
static FString const MakeStructSubCategory = LOCTEXT ( " MakeStruct " , " Make Struct " ) . ToString ( ) ;
static FString const BreakStructSubCategory = LOCTEXT ( " BreakStruct " , " Break Struct " ) . ToString ( ) ;
static FString const TextSubCategory = LOCTEXT ( " TextCategory " , " Text " ) . ToString ( ) ;
static FString const ArrayCategory = UtilitiesCategory + SubCategoryDelim + ArraySubCategory ;
static FString const CastingCategory = UtilitiesCategory + SubCategoryDelim + CastingSubCategory ;
static FString const EnumCategory = UtilitiesCategory + SubCategoryDelim + EnumSubCategory ;
static FString const FlowControlCategory = UtilitiesCategory + SubCategoryDelim + FlowSubCategory ;
static FString const MacroToolsCategory = UtilitiesCategory + SubCategoryDelim + MacroToolsSubCategory ;
static FString const NameCategory = UtilitiesCategory + SubCategoryDelim + NameSubCategory ;
static FString const MakeStructCategory = UtilitiesCategory + SubCategoryDelim + StructSubCategory + SubCategoryDelim + MakeStructSubCategory ;
static FString const BreakStructCategory = UtilitiesCategory + SubCategoryDelim + StructSubCategory + SubCategoryDelim + BreakStructSubCategory ;
static FString const StringCategory = UtilitiesCategory + SubCategoryDelim + StringSubCategory ;
static FString const TextCategory = UtilitiesCategory + SubCategoryDelim + TextSubCategory ;
static FString const FallbackMacroCategory = UtilitiesCategory ;
static FString const AddComponentCategory = LOCTEXT ( " AddComponentCategory " , " Add Component " ) . ToString ( ) ;
static FString const VariablesCategory = LOCTEXT ( " VariablesCategory " , " Variables " ) . ToString ( ) ;
static FString const GameCategory = LOCTEXT ( " GameCategory " , " Game " ) . ToString ( ) ;
static FString const GenericFunctionCategory = LOCTEXT ( " FunctionCategory " , " Call Function " ) . ToString ( ) ;
static FString const CallFuncForEachCategory = LOCTEXT ( " CallFuncForEachCategory " , " Call Function For Each " ) . ToString ( ) ;
static FString const CallFuncOnPrefix = LOCTEXT ( " CallFuncOnPrefix " , " Call Function on " ) . ToString ( ) ;
static FString const CallFuncOnActorsCategory = LOCTEXT ( " CallFuncOnSelectedActors " , " Call function on selected actors " ) . ToString ( ) ;
static FString const FallbackInterfaceCategory = LOCTEXT ( " InterfaceCategory " , " Interface Messages " ) . ToString ( ) ;
}
/** Helper function to add new action types to the actions array */
template < class ActionType >
static void GetRequestedAction ( FGraphActionListBuilderBase & ActionMenuBuilder , const FString & Category )
{
UK2Node * NodeTemplate = NewObject < ActionType > ( ActionMenuBuilder . OwnerOfTemporaries ) ;
TSharedPtr < FEdGraphSchemaAction_K2NewNode > Action = FK2ActionMenuBuilder : : AddNewNodeAction ( ActionMenuBuilder , Category , NodeTemplate - > GetNodeTitle ( ENodeTitleType : : ListView ) , NodeTemplate - > GetTooltip ( ) , 0 , NodeTemplate - > GetKeywords ( ) ) ;
Action - > NodeTemplate = NodeTemplate ;
2014-04-23 18:30:37 -04:00
Action - > SearchTitle = Action - > NodeTemplate - > GetNodeSearchTitle ( ) ;
2014-03-14 14:13:41 -04:00
}
/** Utility for creating spawn from archetype nodes */
static void AddSpawnActorNodeAction ( FGraphActionListBuilderBase & ContextMenuBuilder , const FString & FunctionCategory )
{
FString const SpawnActorCategory = FunctionCategory + K2ActionCategories : : SubCategoryDelim + K2ActionCategories : : GameCategory ;
// Add the new SpawnActorFromClass node
{
UK2Node * NodeTemplate = ContextMenuBuilder . CreateTemplateNode < UK2Node_SpawnActorFromClass > ( ) ;
2014-04-23 18:30:37 -04:00
TSharedPtr < FEdGraphSchemaAction_K2NewNode > Action = FK2ActionMenuBuilder : : AddNewNodeAction ( ContextMenuBuilder , SpawnActorCategory , LOCTEXT ( " SpawnActorFromClass " , " Spawn Actor from Class " ) , NodeTemplate - > GetTooltip ( ) , 0 , NodeTemplate - > GetKeywords ( ) ) ;
2014-03-14 14:13:41 -04:00
Action - > NodeTemplate = NodeTemplate ;
}
}
/** Gets all the input action and axis events and nodes */
static void GetInputNodes ( FGraphActionListBuilderBase & ActionMenuBuilder , const bool bIncludeEvents )
{
if ( bIncludeEvents )
{
TArray < FName > ActionNames ;
GetDefault < UInputSettings > ( ) - > GetActionNames ( ActionNames ) ;
for ( const FName InputActionName : ActionNames )
{
2014-04-23 18:30:37 -04:00
TSharedPtr < FEdGraphSchemaAction_K2NewNode > Action = FK2ActionMenuBuilder : : AddNewNodeAction ( ActionMenuBuilder , K2ActionCategories : : ActionEventsCategory , FText : : FromName ( InputActionName ) , InputActionName . ToString ( ) ) ;
2014-03-14 14:13:41 -04:00
UK2Node_InputAction * InputActionNode = ActionMenuBuilder . CreateTemplateNode < UK2Node_InputAction > ( ) ;
InputActionNode - > InputActionName = InputActionName ;
Action - > NodeTemplate = InputActionNode ;
2014-04-23 18:30:37 -04:00
Action - > SearchTitle = Action - > NodeTemplate - > GetNodeSearchTitle ( ) ;
2014-03-14 14:13:41 -04:00
Action - > Keywords = TEXT ( " InputAction " ) ;
}
TArray < FName > AxisNames ;
GetDefault < UInputSettings > ( ) - > GetAxisNames ( AxisNames ) ;
for ( const FName InputAxisName : AxisNames )
{
2014-04-23 18:30:37 -04:00
TSharedPtr < FEdGraphSchemaAction_K2NewNode > GetAction = FK2ActionMenuBuilder : : AddNewNodeAction ( ActionMenuBuilder , K2ActionCategories : : AxisCategory , FText : : FromName ( InputAxisName ) , InputAxisName . ToString ( ) ) ;
2014-03-14 14:13:41 -04:00
UK2Node_GetInputAxisValue * GetInputAxisValue = ActionMenuBuilder . CreateTemplateNode < UK2Node_GetInputAxisValue > ( ) ;
GetInputAxisValue - > Initialize ( InputAxisName ) ;
GetAction - > NodeTemplate = GetInputAxisValue ;
2014-04-23 18:30:37 -04:00
GetAction - > SearchTitle = GetAction - > NodeTemplate - > GetNodeSearchTitle ( ) ;
2014-03-14 14:13:41 -04:00
GetAction - > Keywords = TEXT ( " InputAxis " ) ;
2014-04-23 18:30:37 -04:00
TSharedPtr < FEdGraphSchemaAction_K2NewNode > Action = FK2ActionMenuBuilder : : AddNewNodeAction ( ActionMenuBuilder , K2ActionCategories : : AxisEventCategory , FText : : FromName ( InputAxisName ) , InputAxisName . ToString ( ) ) ;
2014-03-14 14:13:41 -04:00
UK2Node_InputAxisEvent * InputAxisEvent = ActionMenuBuilder . CreateTemplateNode < UK2Node_InputAxisEvent > ( ) ;
InputAxisEvent - > Initialize ( InputAxisName ) ;
Action - > NodeTemplate = InputAxisEvent ;
2014-04-23 18:30:37 -04:00
Action - > SearchTitle = Action - > NodeTemplate - > GetNodeSearchTitle ( ) ;
2014-03-14 14:13:41 -04:00
Action - > Keywords = TEXT ( " InputAxis " ) ;
}
TArray < FKey > AllKeys ;
EKeys : : GetAllKeys ( AllKeys ) ;
for ( FKey Key : AllKeys )
{
if ( Key . IsBindableInBlueprints ( ) )
{
const FText KeyName = Key . GetDisplayName ( ) ;
const bool bGamepad = Key . IsGamepadKey ( ) ;
const bool bMouse = Key . IsMouseButton ( ) ;
2014-04-23 18:28:49 -04:00
const FString & KeyEventCategory = ( bGamepad ? K2ActionCategories : : GamepadEventsCategory : ( bMouse ? K2ActionCategories : : MouseEventsCategory : K2ActionCategories : : KeyEventsCategory ) ) ;
2014-03-14 14:13:41 -04:00
2014-04-23 18:30:37 -04:00
TSharedPtr < FEdGraphSchemaAction_K2NewNode > Action = FK2ActionMenuBuilder : : AddNewNodeAction ( ActionMenuBuilder , KeyEventCategory , KeyName , KeyName . ToString ( ) ) ;
2014-04-23 18:28:49 -04:00
TSharedPtr < FEdGraphSchemaAction_K2NewNode > GetAction ;
2014-03-14 14:13:41 -04:00
if ( bGamepad )
{
Action - > Keywords = TEXT ( " Input Key InputKey Gamepad Joypad Joystick Stick " ) ;
}
else if ( bMouse )
{
Action - > Keywords = TEXT ( " Input Key InputKey Mouse " ) ;
}
else
{
Action - > Keywords = TEXT ( " Input Key InputKey Keyboard " ) ;
}
2014-04-23 18:28:49 -04:00
2014-04-28 11:24:25 -04:00
if ( Key . IsFloatAxis ( ) )
2014-04-23 18:28:49 -04:00
{
UK2Node_InputAxisKeyEvent * InputKeyAxisNode = ActionMenuBuilder . CreateTemplateNode < UK2Node_InputAxisKeyEvent > ( ) ;
InputKeyAxisNode - > Initialize ( Key ) ;
Action - > NodeTemplate = InputKeyAxisNode ;
2014-04-23 18:30:37 -04:00
Action - > SearchTitle = Action - > NodeTemplate - > GetNodeSearchTitle ( ) ;
2014-04-23 18:28:49 -04:00
const FString & KeyValuesCategory = ( bGamepad ? K2ActionCategories : : GamepadValuesCategory : ( bMouse ? K2ActionCategories : : MouseValuesCategory : K2ActionCategories : : KeyValuesCategory ) ) ;
2014-04-23 18:30:37 -04:00
GetAction = FK2ActionMenuBuilder : : AddNewNodeAction ( ActionMenuBuilder , KeyValuesCategory , KeyName , KeyName . ToString ( ) ) ;
2014-04-23 18:28:49 -04:00
UK2Node_GetInputAxisKeyValue * GetInputAxisKeyValue = ActionMenuBuilder . CreateTemplateNode < UK2Node_GetInputAxisKeyValue > ( ) ;
GetInputAxisKeyValue - > Initialize ( Key ) ;
GetAction - > NodeTemplate = GetInputAxisKeyValue ;
GetAction - > Keywords = Action - > Keywords ;
}
2014-04-28 11:24:25 -04:00
else if ( Key . IsVectorAxis ( ) )
{
UK2Node_InputVectorAxisEvent * InputVectorAxisNode = ActionMenuBuilder . CreateTemplateNode < UK2Node_InputVectorAxisEvent > ( ) ;
InputVectorAxisNode - > Initialize ( Key ) ;
Action - > NodeTemplate = InputVectorAxisNode ;
Action - > SearchTitle = Action - > NodeTemplate - > GetNodeSearchTitle ( ) ;
const FString & KeyValuesCategory = ( bGamepad ? K2ActionCategories : : GamepadValuesCategory : ( bMouse ? K2ActionCategories : : MouseValuesCategory : K2ActionCategories : : KeyValuesCategory ) ) ;
GetAction = FK2ActionMenuBuilder : : AddNewNodeAction ( ActionMenuBuilder , KeyValuesCategory , KeyName , KeyName . ToString ( ) ) ;
UK2Node_GetInputVectorAxisValue * GetInputVectorAxisValue = ActionMenuBuilder . CreateTemplateNode < UK2Node_GetInputVectorAxisValue > ( ) ;
GetInputVectorAxisValue - > Initialize ( Key ) ;
GetAction - > NodeTemplate = GetInputVectorAxisValue ;
GetAction - > Keywords = Action - > Keywords ;
}
2014-04-23 18:28:49 -04:00
else
{
UK2Node_InputKey * InputKeyNode = ActionMenuBuilder . CreateTemplateNode < UK2Node_InputKey > ( ) ;
InputKeyNode - > InputKey = Key ;
Action - > NodeTemplate = InputKeyNode ;
2014-04-23 18:30:37 -04:00
Action - > SearchTitle = Action - > NodeTemplate - > GetNodeSearchTitle ( ) ;
2014-04-23 18:28:49 -04:00
}
2014-03-14 14:13:41 -04:00
}
}
2014-04-23 18:30:37 -04:00
TSharedPtr < FEdGraphSchemaAction_K2NewNode > Action = FK2ActionMenuBuilder : : AddNewNodeAction ( ActionMenuBuilder , K2ActionCategories : : TouchEventsCategory , LOCTEXT ( " Touch " , " Touch " ) , LOCTEXT ( " Touch " , " Touch " ) . ToString ( ) ) ;
2014-03-14 14:13:41 -04:00
UK2Node_InputTouch * InputTouchNode = ActionMenuBuilder . CreateTemplateNode < UK2Node_InputTouch > ( ) ;
Action - > NodeTemplate = InputTouchNode ;
2014-04-23 18:30:37 -04:00
Action - > SearchTitle = Action - > NodeTemplate - > GetNodeSearchTitle ( ) ;
2014-03-14 14:13:41 -04:00
Action - > Keywords = TEXT ( " Input Touch " ) ;
}
}
/** Generate a set of 'AddComponent' actions from the selection set */
static void GetAddComponentActionsUsingSelectedAssets ( FBlueprintGraphActionListBuilder & ContextMenuBuilder )
{
FEditorDelegates : : LoadSelectedAssetsIfNeeded . Broadcast ( ) ;
USelection * SelectedAssets = GEditor - > GetSelectedObjects ( ) ;
for ( FSelectionIterator Iter ( * SelectedAssets ) ; Iter ; + + Iter )
{
UObject * Asset = * Iter ;
TArray < TSubclassOf < UActorComponent > > ComponentClasses = FComponentAssetBrokerage : : GetComponentsForAsset ( Asset ) ;
for ( int32 i = 0 ; i < ComponentClasses . Num ( ) ; i + + )
{
TSubclassOf < UActorComponent > DestinationComponentType = ComponentClasses [ i ] ;
TSharedPtr < FEdGraphSchemaAction_K2AddComponent > NewAction = FK2ActionMenuBuilder : : CreateAddComponentAction ( ContextMenuBuilder . OwnerOfTemporaries , ContextMenuBuilder . Blueprint , DestinationComponentType , Asset ) ;
ContextMenuBuilder . AddAction ( NewAction ) ;
}
}
}
/** Generate a set of 'AddComponent' actions, one for each allowed component class */
static void GetAddComponentClasses ( UBlueprint const * BlueprintIn , FGraphActionListBuilderBase & ActionMenuBuilder )
{
for ( TObjectIterator < UClass > It ; It ; + + It )
{
UClass * Class = * It ;
// If this is a subclass of ActorComponent, not abstract, and tagged as spawnable from Kismet
if ( Class - > IsChildOf ( UActorComponent : : StaticClass ( ) ) & & ! Class - > HasAnyClassFlags ( CLASS_Abstract ) & & Class - > HasMetaData ( FBlueprintMetadata : : MD_BlueprintSpawnableComponent ) )
{
TSharedPtr < FEdGraphSchemaAction_K2AddComponent > NewAction = FK2ActionMenuBuilder : : CreateAddComponentAction ( ActionMenuBuilder . OwnerOfTemporaries , BlueprintIn , Class , /*Asset=*/ NULL ) ;
ActionMenuBuilder . AddAction ( NewAction ) ;
}
}
}
/** Gets the add comment action */
static void GetCommentAction ( UBlueprint const * BlueprintIn , FGraphActionListBuilderBase & ActionMenuBuilder )
{
const bool bIsManyNodesSelected = ( FKismetEditorUtilities : : GetNumberOfSelectedNodes ( BlueprintIn ) > 0 ) ;
2014-04-23 18:30:37 -04:00
const FText MenuDescription = bIsManyNodesSelected ? LOCTEXT ( " AddCommentFromSelection " , " Create Comment from Selection " ) : LOCTEXT ( " AddComment " , " Add Comment... " ) ;
2014-03-14 14:13:41 -04:00
const FString ToolTip = LOCTEXT ( " CreateCommentToolTip " , " Create a resizable comment box. " ) . ToString ( ) ;
TSharedPtr < FEdGraphSchemaAction_K2AddComment > NewAction = TSharedPtr < FEdGraphSchemaAction_K2AddComment > ( new FEdGraphSchemaAction_K2AddComment ( MenuDescription , ToolTip ) ) ;
ActionMenuBuilder . AddAction ( NewAction ) ;
}
/** */
2014-04-23 17:34:21 -04:00
static void GetEnumUtilitiesNodes ( FBlueprintGraphActionListBuilder & ContextMenuBuilder , bool bNumEnum , bool bForEach , bool bCastFromByte , bool bLiteralByte , UEnum * OnlyEnum = NULL )
2014-03-14 14:13:41 -04:00
{
struct FGetEnumUtilitiesNodes
{
2014-05-29 17:14:20 -04:00
static void Get ( FBlueprintGraphActionListBuilder & InContextMenuBuilder , bool bInNumEnum , bool bInForEach , bool bInCastFromByte , bool bInLiteralByte , UEnum * Enum , const FString & Category )
2014-03-14 14:13:41 -04:00
{
const bool bIsBlueprintType = UEdGraphSchema_K2 : : IsAllowableBlueprintVariableType ( Enum ) ;
if ( bIsBlueprintType )
{
if ( bInNumEnum )
{
UK2Node_GetNumEnumEntries * EnumTemplate = InContextMenuBuilder . CreateTemplateNode < UK2Node_GetNumEnumEntries > ( ) ;
EnumTemplate - > Enum = Enum ;
UK2Node * NodeTemplate = EnumTemplate ;
TSharedPtr < FEdGraphSchemaAction_K2NewNode > Action = FK2ActionMenuBuilder : : AddNewNodeAction (
InContextMenuBuilder , Category , NodeTemplate - > GetNodeTitle ( ENodeTitleType : : ListView ) , NodeTemplate - > GetTooltip ( ) , 0 , NodeTemplate - > GetKeywords ( ) ) ;
Action - > NodeTemplate = NodeTemplate ;
2014-04-23 18:30:37 -04:00
Action - > SearchTitle = NodeTemplate - > GetNodeSearchTitle ( ) ;
2014-03-14 14:13:41 -04:00
}
if ( bInForEach )
{
UK2Node_ForEachElementInEnum * EnumTemplate = InContextMenuBuilder . CreateTemplateNode < UK2Node_ForEachElementInEnum > ( ) ;
EnumTemplate - > Enum = Enum ;
UK2Node * NodeTemplate = EnumTemplate ;
TSharedPtr < FEdGraphSchemaAction_K2NewNode > Action = FK2ActionMenuBuilder : : AddNewNodeAction (
InContextMenuBuilder , Category , NodeTemplate - > GetNodeTitle ( ENodeTitleType : : ListView ) , NodeTemplate - > GetTooltip ( ) , 0 , NodeTemplate - > GetKeywords ( ) ) ;
Action - > NodeTemplate = NodeTemplate ;
2014-04-23 18:30:37 -04:00
Action - > SearchTitle = NodeTemplate - > GetNodeSearchTitle ( ) ;
2014-03-14 14:13:41 -04:00
}
if ( bInCastFromByte )
{
UK2Node_CastByteToEnum * EnumTemplate = InContextMenuBuilder . CreateTemplateNode < UK2Node_CastByteToEnum > ( ) ;
EnumTemplate - > Enum = Enum ;
EnumTemplate - > bSafe = true ;
UK2Node * NodeTemplate = EnumTemplate ;
TSharedPtr < FEdGraphSchemaAction_K2NewNode > Action = FK2ActionMenuBuilder : : AddNewNodeAction (
InContextMenuBuilder , Category , NodeTemplate - > GetNodeTitle ( ENodeTitleType : : ListView ) , NodeTemplate - > GetTooltip ( ) , 0 , NodeTemplate - > GetKeywords ( ) ) ;
Action - > NodeTemplate = NodeTemplate ;
2014-04-23 18:30:37 -04:00
Action - > SearchTitle = NodeTemplate - > GetNodeSearchTitle ( ) ;
2014-03-14 14:13:41 -04:00
}
2014-04-23 17:34:21 -04:00
2014-05-29 17:14:20 -04:00
if ( bInLiteralByte )
2014-04-23 17:34:21 -04:00
{
UK2Node_EnumLiteral * EnumTemplate = InContextMenuBuilder . CreateTemplateNode < UK2Node_EnumLiteral > ( ) ;
EnumTemplate - > Enum = Enum ;
UK2Node * NodeTemplate = EnumTemplate ;
TSharedPtr < FEdGraphSchemaAction_K2NewNode > Action = FK2ActionMenuBuilder : : AddNewNodeAction (
InContextMenuBuilder , Category , NodeTemplate - > GetNodeTitle ( ENodeTitleType : : ListView ) , NodeTemplate - > GetTooltip ( ) , 0 , NodeTemplate - > GetKeywords ( ) ) ;
Action - > NodeTemplate = NodeTemplate ;
}
2014-03-14 14:13:41 -04:00
}
}
} ;
if ( OnlyEnum )
{
2014-04-23 17:34:21 -04:00
FGetEnumUtilitiesNodes : : Get ( ContextMenuBuilder , bNumEnum , bForEach , bCastFromByte , bLiteralByte , OnlyEnum , K2ActionCategories : : EnumCategory ) ;
2014-03-14 14:13:41 -04:00
}
else
{
for ( TObjectIterator < UEnum > EnumIt ; EnumIt ; + + EnumIt )
{
if ( UEnum * CurrentEnum = * EnumIt )
{
2014-04-23 17:34:21 -04:00
FGetEnumUtilitiesNodes : : Get ( ContextMenuBuilder , bNumEnum , bForEach , bCastFromByte , bLiteralByte , CurrentEnum , K2ActionCategories : : EnumCategory ) ;
2014-03-14 14:13:41 -04:00
}
}
}
}
/** Get functions you can call from the given interface */
static void GetInterfaceMessages ( UClass * CurrentInterface , const FString & MessagesCategory , FBlueprintGraphActionListBuilder & ContextMenuBuilder )
{
if ( CurrentInterface & & FKismetEditorUtilities : : IsClassABlueprintInterface ( CurrentInterface ) & & ! FKismetEditorUtilities : : IsClassABlueprintSkeleton ( CurrentInterface ) )
{
const FString MessageSubCategory = FString : : Printf ( TEXT ( " %s|%s " ) , * MessagesCategory , * CurrentInterface - > GetName ( ) ) ;
for ( TFieldIterator < UFunction > FunctionIt ( CurrentInterface , EFieldIteratorFlags : : ExcludeSuper ) ; FunctionIt ; + + FunctionIt )
{
UFunction * Function = * FunctionIt ;
if ( UEdGraphSchema_K2 : : CanUserKismetCallFunction ( Function ) )
{
UK2Node_Message * MessageTemplate = ContextMenuBuilder . CreateTemplateNode < UK2Node_Message > ( ) ;
MessageTemplate - > FunctionReference . SetExternalMember ( Function - > GetFName ( ) , CurrentInterface ) ;
2014-04-23 18:30:37 -04:00
TSharedPtr < FEdGraphSchemaAction_K2NewNode > Action = FK2ActionMenuBuilder : : AddNewNodeAction ( ContextMenuBuilder , MessageSubCategory , FText : : FromString ( Function - > GetName ( ) ) , MessageTemplate - > GetTooltip ( ) , 0 , MessageTemplate - > GetKeywords ( ) ) ;
2014-03-14 14:13:41 -04:00
Action - > NodeTemplate = MessageTemplate ;
2014-04-23 18:30:37 -04:00
Action - > SearchTitle = MessageTemplate - > GetNodeSearchTitle ( ) ;
2014-03-14 14:13:41 -04:00
}
}
}
}
/** Helper method to get a reference variable setter node */
static void GetReferenceSetterItems ( FBlueprintGraphActionListBuilder & ContextMenuBuilder )
{
const UEdGraphPin * AssociatedPin = ContextMenuBuilder . FromPin ;
UK2Node_VariableSetRef * SetRefTemplate = ContextMenuBuilder . CreateTemplateNode < UK2Node_VariableSetRef > ( ) ;
TSharedPtr < FEdGraphSchemaAction_K2NewNode > Action = FK2ActionMenuBuilder : : AddNewNodeAction ( ContextMenuBuilder , K2ActionCategories : : VariablesCategory , SetRefTemplate - > GetNodeTitle ( ENodeTitleType : : ListView ) , SetRefTemplate - > GetTooltip ( ) , 0 , SetRefTemplate - > GetKeywords ( ) ) ;
Action - > NodeTemplate = SetRefTemplate ;
2014-04-23 18:30:37 -04:00
Action - > SearchTitle = SetRefTemplate - > GetNodeSearchTitle ( ) ;
2014-03-14 14:13:41 -04:00
}
/**
* Check if function library can be used with specified scope
*
* @ param LibraryClass Function library to test
* @ param ScopeClass Blueprint class used for restriction test
*/
static bool CanUseLibraryFunctionsForScope ( UClass * LibraryClass , const UClass * ScopeClass )
{
static const FName NAME_RestristedToClasses ( TEXT ( " RestrictedToClasses " ) ) ;
if ( LibraryClass - > HasMetaData ( NAME_RestristedToClasses ) )
{
const FString & ClassRestrictions = LibraryClass - > GetMetaData ( NAME_RestristedToClasses ) ;
for ( UClass * TestOwnerClass = ( UClass * ) ScopeClass ; TestOwnerClass ; TestOwnerClass = TestOwnerClass - > GetSuperClass ( ) )
{
const bool bFound = ( ClassRestrictions = = TestOwnerClass - > GetName ( ) ) | | ! ! FCString : : StrfindDelim ( * ClassRestrictions , * ScopeClass - > GetName ( ) , TEXT ( " " ) ) ;
if ( bFound )
{
return true ;
}
}
return false ;
}
return true ;
}
/** */
static UClass * FindMostDerivedCommonActor ( TArray < AActor * > & InObjects )
{
check ( InObjects . Num ( ) > 0 ) ;
// Find the most derived common class for all passed in Objects
UClass * CommonClass = InObjects [ 0 ] - > GetClass ( ) ;
for ( int32 ObjIdx = 1 ; ObjIdx < InObjects . Num ( ) ; + + ObjIdx )
{
while ( ! InObjects [ ObjIdx ] - > IsA ( CommonClass ) )
{
CommonClass = CommonClass - > GetSuperClass ( ) ;
}
}
return CommonClass ;
}
/*******************************************************************************
* FBlueprintGraphActionListBuilder
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
//------------------------------------------------------------------------------
FBlueprintGraphActionListBuilder : : FBlueprintGraphActionListBuilder ( const UEdGraph * InGraph )
: FGraphContextMenuBuilder ( InGraph )
{
check ( CurrentGraph ! = NULL ) ;
Blueprint = FBlueprintEditorUtils : : FindBlueprintForGraph ( CurrentGraph ) ;
OwnerOfTemporaries = NewObject < UEdGraph > ( ( Blueprint ! = NULL ) ? ( UObject * ) Blueprint : ( UObject * ) GetTransientPackage ( ) ) ;
OwnerOfTemporaries - > Schema = CurrentGraph - > Schema ;
OwnerOfTemporaries - > SetFlags ( RF_Transient ) ;
}
/*******************************************************************************
* FBlueprintPaletteListBuilder
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
//------------------------------------------------------------------------------
FBlueprintPaletteListBuilder : : FBlueprintPaletteListBuilder ( UBlueprint const * BlueprintIn , FString const & CategoryIn /* = TEXT("")*/ )
: FCategorizedGraphActionListBuilder ( CategoryIn )
, Blueprint ( BlueprintIn )
{
if ( Blueprint ! = NULL )
{
OwnerOfTemporaries = NewObject < UEdGraph > ( ( UObject * ) Blueprint ) ;
OwnerOfTemporaries - > SetFlags ( RF_Transient ) ;
}
}
/*******************************************************************************
* Static FK2ActionMenuBuilder Interface
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/** */
int32 FK2ActionMenuBuilder : : bAllowUnsafeCommands = 0 ;
//------------------------------------------------------------------------------
TSharedPtr < FEdGraphSchemaAction_K2AddComponent > FK2ActionMenuBuilder : : CreateAddComponentAction ( UObject * TemporaryOuter , const UBlueprint * Blueprint , TSubclassOf < UActorComponent > DestinationComponentType , UObject * Asset )
{
// Make an add component node
UK2Node_CallFunction * CallFuncNode = NewObject < UK2Node_AddComponent > ( TemporaryOuter ) ;
UFunction * AddComponentFn = FindFieldChecked < UFunction > ( AActor : : StaticClass ( ) , UK2Node_AddComponent : : GetAddComponentFunctionName ( ) ) ;
CallFuncNode - > FunctionReference . SetFromField < UFunction > ( AddComponentFn , FBlueprintEditorUtils : : IsActorBased ( Blueprint ) ) ;
// Create an action to do it
FString Description ;
FString ToolTip ;
if ( Asset ! = NULL )
{
Description = FString : : Printf ( TEXT ( " Add %s (as %s) " ) , * Asset - > GetName ( ) , * DestinationComponentType - > GetName ( ) ) ;
ToolTip = FString : : Printf ( TEXT ( " Spawn a %s using %s " ) , * DestinationComponentType - > GetName ( ) , * Asset - > GetName ( ) ) ;
}
else
{
Description = FString : : Printf ( TEXT ( " Add %s " ) , * DestinationComponentType - > GetName ( ) ) ;
ToolTip = FString : : Printf ( TEXT ( " Spawn a %s " ) , * DestinationComponentType - > GetName ( ) ) ;
}
// Find class group name
FString ClassGroup ;
{
TArray < FString > ClassGroupNames ;
DestinationComponentType - > GetClassGroupNames ( ClassGroupNames ) ;
static const FString CommonClassGroup ( TEXT ( " Common " ) ) ;
if ( ClassGroupNames . Contains ( CommonClassGroup ) ) // 'Common' takes priority
{
ClassGroup = CommonClassGroup ;
}
else if ( ClassGroupNames . Num ( ) )
{
ClassGroup = ClassGroupNames [ 0 ] ;
}
}
// Create menu category
FString MenuCategory = K2ActionCategories : : AddComponentCategory + FString ( TEXT ( " | " ) ) + ClassGroup ;
2014-04-23 18:30:37 -04:00
TSharedPtr < FEdGraphSchemaAction_K2AddComponent > Action = TSharedPtr < FEdGraphSchemaAction_K2AddComponent > ( new FEdGraphSchemaAction_K2AddComponent ( MenuCategory , FText : : FromString ( Description ) , ToolTip , Asset ! = NULL ? 2 : 0 ) ) ;
2014-03-14 14:13:41 -04:00
Action - > NodeTemplate = CallFuncNode ;
2014-04-23 18:30:37 -04:00
Action - > SearchTitle = Action - > NodeTemplate - > GetNodeSearchTitle ( ) ;
2014-03-14 14:13:41 -04:00
Action - > ComponentClass = DestinationComponentType ;
Action - > ComponentAsset = Asset ;
return Action ;
}
//------------------------------------------------------------------------------
2014-04-23 18:30:37 -04:00
TSharedPtr < FEdGraphSchemaAction_K2NewNode > FK2ActionMenuBuilder : : AddNewNodeAction ( FGraphActionListBuilderBase & ContextMenuBuilder , const FString & Category , const FText & MenuDesc , const FString & Tooltip , const int32 Grouping , const FString & Keywords )
2014-03-14 14:13:41 -04:00
{
TSharedPtr < FEdGraphSchemaAction_K2NewNode > NewActionNode = TSharedPtr < FEdGraphSchemaAction_K2NewNode > ( new FEdGraphSchemaAction_K2NewNode ( Category , MenuDesc , Tooltip , Grouping ) ) ;
NewActionNode - > Keywords = Keywords ;
ContextMenuBuilder . AddAction ( NewActionNode ) ;
return NewActionNode ;
}
//------------------------------------------------------------------------------
void FK2ActionMenuBuilder : : AddEventForFunction ( FGraphActionListBuilderBase & ActionMenuBuilder , UFunction * Function )
{
if ( Function ! = NULL )
{
check ( ! Function - > HasAnyFunctionFlags ( FUNC_Delegate ) ) ;
const FString SigName = UEdGraphSchema_K2 : : GetFriendlySignitureName ( Function ) ;
2014-04-23 18:30:37 -04:00
const FString EventName = FText : : Format ( LOCTEXT ( " EventWithSignatureName " , " Event {0} " ) , FText : : FromString ( SigName ) ) . ToString ( ) ;
2014-03-14 14:13:41 -04:00
UK2Node_Event * EventNodeTemplate = ActionMenuBuilder . CreateTemplateNode < UK2Node_Event > ( ) ;
EventNodeTemplate - > EventSignatureName = Function - > GetFName ( ) ;
EventNodeTemplate - > EventSignatureClass = CastChecked < UClass > ( Function - > GetOuter ( ) ) ;
EventNodeTemplate - > bOverrideFunction = true ;
const FString Category = UK2Node_CallFunction : : GetDefaultCategoryForFunction ( Function , K2ActionCategories : : AddEventCategory ) ;
2014-04-23 18:30:37 -04:00
TSharedPtr < FEdGraphSchemaAction_K2AddEvent > Action ( new FEdGraphSchemaAction_K2AddEvent ( Category , FText : : FromString ( EventName ) , EventNodeTemplate - > GetTooltip ( ) , 0 ) ) ;
2014-03-14 14:13:41 -04:00
Action - > Keywords = EventNodeTemplate - > GetKeywords ( ) ;
Action - > NodeTemplate = EventNodeTemplate ;
2014-04-23 18:30:37 -04:00
Action - > SearchTitle = EventNodeTemplate - > GetNodeSearchTitle ( ) ;
2014-03-14 14:13:41 -04:00
ActionMenuBuilder . AddAction ( Action ) ;
}
}
//------------------------------------------------------------------------------
void FK2ActionMenuBuilder : : AttachMacroGraphAction ( FGraphActionListBuilderBase & ActionMenuBuilder , UEdGraph * MacroGraph )
{
FKismetUserDeclaredFunctionMetadata * MacroGraphMetadata = UK2Node_MacroInstance : : GetAssociatedGraphMetadata ( MacroGraph ) ;
if ( MacroGraphMetadata )
{
const FString CategoryName = ( ! MacroGraphMetadata - > Category . IsEmpty ( ) ) ? MacroGraphMetadata - > Category : K2ActionCategories : : FallbackMacroCategory ;
UK2Node_MacroInstance * MacroTemplate = ActionMenuBuilder . CreateTemplateNode < UK2Node_MacroInstance > ( ) ;
MacroTemplate - > SetMacroGraph ( MacroGraph ) ;
TSharedPtr < FEdGraphSchemaAction_K2NewNode > Action = FK2ActionMenuBuilder : : AddNewNodeAction ( ActionMenuBuilder , CategoryName , MacroTemplate - > GetNodeTitle ( ENodeTitleType : : ListView ) , MacroTemplate - > GetTooltip ( ) ) ;
Action - > NodeTemplate = MacroTemplate ;
2014-04-23 18:30:37 -04:00
Action - > SearchTitle = MacroTemplate - > GetNodeSearchTitle ( ) ;
2014-03-14 14:13:41 -04:00
}
}
//------------------------------------------------------------------------------
void FK2ActionMenuBuilder : : AddSpawnInfoForFunction ( const UFunction * Function , bool bIsParentContext , const FFunctionTargetInfo & TargetInfo , const FMemberReference & CallOnMember , const FString & BaseCategory , int32 const ActionGrouping , FGraphActionListBuilderBase & ListBuilder , bool bCalledForEach , bool bPlaceOnTop )
{
FString Tooltip = UK2Node_CallFunction : : GetDefaultTooltipForFunction ( Function ) ;
FString Description = UK2Node_CallFunction : : GetUserFacingFunctionName ( Function ) ;
FString Keywords = UK2Node_CallFunction : : GetKeywordsForFunction ( Function ) ;
if ( bIsParentContext )
{
const FString ParentContextName = Function - > GetOuter ( ) - > GetName ( ) ;
Tooltip = FString : : Printf ( TEXT ( " Call %s's version of %s. \n " ) , * ParentContextName , * Description ) + Tooltip ;
Description = ParentContextName + TEXT ( " 's " ) + Description ;
}
FString NodeCategory ;
if ( ! bIsParentContext & & ! bPlaceOnTop )
{
NodeCategory = UK2Node_CallFunction : : GetDefaultCategoryForFunction ( Function , BaseCategory ) ;
}
TSharedPtr < FEdGraphSchemaAction_K2NewNode > Action ;
// See if we want to create an actor ref node for the target
if ( TargetInfo . FunctionTarget = = FFunctionTargetInfo : : EFT_Actor )
{
2014-04-23 18:30:37 -04:00
TSharedPtr < FEdGraphSchemaAction_K2AddCallOnActor > ActorAction = TSharedPtr < FEdGraphSchemaAction_K2AddCallOnActor > ( new FEdGraphSchemaAction_K2AddCallOnActor ( NodeCategory , FText : : FromString ( Description ) , Tooltip , ActionGrouping ) ) ;
2014-03-14 14:13:41 -04:00
for ( int32 ActorIndex = 0 ; ActorIndex < TargetInfo . Actors . Num ( ) ; ActorIndex + + )
{
AActor * Actor = TargetInfo . Actors [ ActorIndex ] . Get ( ) ;
if ( Actor ! = NULL )
{
ActorAction - > LevelActors . Add ( Actor ) ;
}
}
Action = ActorAction ;
ListBuilder . AddAction ( ActorAction ) ;
}
// Or create a component property ref node for the target
else if ( TargetInfo . FunctionTarget = = FFunctionTargetInfo : : EFT_Component )
{
2014-04-23 18:30:37 -04:00
TSharedPtr < FEdGraphSchemaAction_K2AddCallOnVariable > VarAction = TSharedPtr < FEdGraphSchemaAction_K2AddCallOnVariable > ( new FEdGraphSchemaAction_K2AddCallOnVariable ( NodeCategory , FText : : FromString ( Description ) , Tooltip , ActionGrouping ) ) ;
2014-03-14 14:13:41 -04:00
VarAction - > VariableName = TargetInfo . ComponentPropertyName ;
Action = VarAction ;
ListBuilder . AddAction ( VarAction ) ;
}
// Default case (no additional nodes created for target)
else
{
2014-04-23 18:30:37 -04:00
Action = FK2ActionMenuBuilder : : AddNewNodeAction ( ListBuilder , NodeCategory , FText : : FromString ( Description ) , Tooltip , 0 , Keywords ) ;
2014-03-14 14:13:41 -04:00
}
Action - > Keywords = Keywords ;
const bool bHasArrayPointerParms = Function - > HasMetaData ( TEXT ( " ArrayParm " ) ) ;
const bool bIsPure = Function - > HasAllFunctionFlags ( FUNC_BlueprintPure ) ;
const bool bCommutativeAssociativeBinaryOperator = Function - > HasMetaData ( FBlueprintMetadata : : MD_CommutativeAssociativeBinaryOperator ) ;
const bool bMaterialParameterCollectionFunction = Function - > HasMetaData ( FBlueprintMetadata : : MD_MaterialParameterCollectionFunction ) ;
UK2Node_CallFunction * CallTemplate = NULL ;
if ( bCalledForEach )
{
CallTemplate = ListBuilder . CreateTemplateNode < UK2Node_CallFunction > ( ) ;
}
else if ( bCommutativeAssociativeBinaryOperator & & bIsPure )
{
CallTemplate = ListBuilder . CreateTemplateNode < UK2Node_CommutativeAssociativeBinaryOperator > ( ) ;
}
else if ( bMaterialParameterCollectionFunction )
{
CallTemplate = ListBuilder . CreateTemplateNode < UK2Node_CallMaterialParameterCollectionFunction > ( ) ;
}
else if ( CallOnMember . GetMemberName ( ) ! = NAME_None )
{
CallTemplate = ListBuilder . CreateTemplateNode < UK2Node_CallFunctionOnMember > ( ) ;
// Assign member to call on
UK2Node_CallFunctionOnMember * CallFuncOnMemberTemplate = CastChecked < UK2Node_CallFunctionOnMember > ( CallTemplate ) ;
CallFuncOnMemberTemplate - > MemberVariableToCallOn = CallOnMember ;
}
else if ( bIsParentContext )
{
CallTemplate = ListBuilder . CreateTemplateNode < UK2Node_CallParentFunction > ( ) ;
}
else if ( ! bHasArrayPointerParms )
{
CallTemplate = ListBuilder . CreateTemplateNode < UK2Node_CallFunction > ( ) ;
}
else
{
CallTemplate = ListBuilder . CreateTemplateNode < UK2Node_CallArrayFunction > ( ) ;
}
CallTemplate - > SetFromFunction ( Function ) ;
//@TODO: FUNCTIONREFACTOR: CallFuncNode->FunctionReference.SetExternalMember(Function->GetFName(), Function->GetOuterUClass());
Action - > NodeTemplate = CallTemplate ;
2014-04-23 18:30:37 -04:00
Action - > SearchTitle = Action - > NodeTemplate - > GetNodeSearchTitle ( ) ;
2014-03-14 14:13:41 -04:00
}
/*******************************************************************************
* Public FK2ActionMenuBuilder Interface
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
//------------------------------------------------------------------------------
FK2ActionMenuBuilder : : FK2ActionMenuBuilder ( UEdGraphSchema_K2 const * SchemaIn )
: K2Schema ( SchemaIn )
{
check ( K2Schema ! = NULL ) ;
}
//------------------------------------------------------------------------------
void FK2ActionMenuBuilder : : GetGraphContextActions ( FBlueprintGraphActionListBuilder & ContextMenuBuilder ) const
{
// Now do schema-specific stuff
if ( ContextMenuBuilder . FromPin ! = NULL )
{
GetPinAllowedNodeTypes ( ContextMenuBuilder ) ;
}
else
{
GetContextAllowedNodeTypes ( ContextMenuBuilder ) ;
}
}
//------------------------------------------------------------------------------
void FK2ActionMenuBuilder : : GetAllActions ( FBlueprintPaletteListBuilder & PaletteBuilder ) const
{
UClass const * ContextClass = PaletteBuilder . Blueprint ? PaletteBuilder . Blueprint - > SkeletonGeneratedClass : NULL ;
// Get the list of valid classes
for ( TObjectIterator < UClass > It ; It ; + + It )
{
UClass * Class = ( * It ) ;
if ( Class ! = ContextClass )
{
// Show protected members of parent classes
const bool bShowProtected = ContextClass - > IsChildOf ( Class ) ;
GetAllActionsForClass ( PaletteBuilder , Class , false , bShowProtected , false , true ) ;
}
}
}
//------------------------------------------------------------------------------
void FK2ActionMenuBuilder : : GetPaletteActions ( FBlueprintPaletteListBuilder & ActionMenuBuilder , TWeakObjectPtr < UClass > FilterClass /* = NULL*/ ) const
{
if ( FilterClass . IsValid ( ) )
{
UClass * SkelClass = ActionMenuBuilder . Blueprint ? ActionMenuBuilder . Blueprint - > SkeletonGeneratedClass : NULL ;
const bool bShowProtected = ( SkelClass ! = NULL ) & & SkelClass - > IsChildOf ( FilterClass . Get ( ) ) ; // show protected members of this class if our 'context' is a child of it
GetAllActionsForClass ( ActionMenuBuilder , FilterClass . Get ( ) , true , bShowProtected , true , true ) ;
}
else
{
GetAllActions ( ActionMenuBuilder ) ;
}
{
// Actions that are part of Flow Control
GetRequestedAction < UK2Node_IfThenElse > ( ActionMenuBuilder , K2ActionCategories : : FlowControlCategory ) ;
GetRequestedAction < UK2Node_ExecutionSequence > ( ActionMenuBuilder , K2ActionCategories : : FlowControlCategory ) ;
GetRequestedAction < UK2Node_MultiGate > ( ActionMenuBuilder , K2ActionCategories : : FlowControlCategory ) ;
GetSwitchMenuItems ( ActionMenuBuilder , K2ActionCategories : : FlowControlCategory ) ;
}
GetRequestedAction < UK2Node_MakeArray > ( ActionMenuBuilder , K2ActionCategories : : ArrayCategory ) ;
AddSpawnActorNodeAction ( ActionMenuBuilder , TEXT ( " " ) ) ;
GetAllEventActions ( ActionMenuBuilder ) ;
GetAllInterfaceMessageActions ( ActionMenuBuilder ) ;
GetInputNodes ( ActionMenuBuilder , true ) ;
// Components are only valid in actor based blueprints, but not in the level script blueprint
if ( ! FBlueprintEditorUtils : : IsLevelScriptBlueprint ( ActionMenuBuilder . Blueprint ) & & FBlueprintEditorUtils : : IsActorBased ( ActionMenuBuilder . Blueprint ) )
{
GetAddComponentClasses ( ActionMenuBuilder . Blueprint , ActionMenuBuilder ) ;
}
GetCommentAction ( ActionMenuBuilder . Blueprint , ActionMenuBuilder ) ;
GetMacroTools ( ActionMenuBuilder , true , NULL ) ;
GetRequestedAction < UK2Node_FormatText > ( ActionMenuBuilder , K2ActionCategories : : TextCategory ) ;
}
/*******************************************************************************
* Private FK2ActionMenuBuilder Methods
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
//------------------------------------------------------------------------------
void FK2ActionMenuBuilder : : GetContextAllowedNodeTypes ( FBlueprintGraphActionListBuilder & ContextMenuBuilder ) const
{
const UBlueprint * Blueprint = ContextMenuBuilder . Blueprint ;
UClass * Class = ( Blueprint ! = NULL ) ? Blueprint - > SkeletonGeneratedClass : NULL ;
if ( Class = = NULL )
{
UE_LOG ( LogBlueprint , Log , TEXT ( " GetContextAllowedNodeTypes: Failed to find class from Blueprint '%s' " ) , * Blueprint - > GetPathName ( ) ) ;
}
else
{
const EGraphType GraphType = K2Schema - > GetGraphType ( ContextMenuBuilder . CurrentGraph ) ;
const bool bSupportsEventGraphs = FBlueprintEditorUtils : : DoesSupportEventGraphs ( Blueprint ) ;
const bool bAllowEvents = ( ( GraphType = = GT_Ubergraph ) & & bSupportsEventGraphs ) | |
( ( bAllowUnsafeCommands ) & & ( Blueprint - > BlueprintType = = BPTYPE_MacroLibrary ) ) ;
const bool bIsConstructionScript = K2Schema - > IsConstructionScript ( ContextMenuBuilder . CurrentGraph ) ;
const bool bAllowImpureFuncs = K2Schema - > DoesGraphSupportImpureFunctions ( ContextMenuBuilder . CurrentGraph ) ;
// Flow control operations
if ( bAllowImpureFuncs )
{
GetRequestedAction < UK2Node_IfThenElse > ( ContextMenuBuilder , K2ActionCategories : : FlowControlCategory ) ;
GetRequestedAction < UK2Node_ExecutionSequence > ( ContextMenuBuilder , K2ActionCategories : : FlowControlCategory ) ;
GetRequestedAction < UK2Node_MultiGate > ( ContextMenuBuilder , K2ActionCategories : : FlowControlCategory ) ;
GetRequestedAction < UK2Node_MakeArray > ( ContextMenuBuilder , K2ActionCategories : : ArrayCategory ) ;
FBlueprintPaletteListBuilder PaletteBuilder ( ContextMenuBuilder . Blueprint ) ;
GetSwitchMenuItems ( PaletteBuilder , K2ActionCategories : : FlowControlCategory , ContextMenuBuilder . FromPin ) ;
ContextMenuBuilder . Append ( PaletteBuilder ) ;
}
GetRequestedAction < UK2Node_GetEnumeratorName > ( ContextMenuBuilder , K2ActionCategories : : NameCategory ) ;
GetRequestedAction < UK2Node_GetEnumeratorNameAsString > ( ContextMenuBuilder , K2ActionCategories : : StringCategory ) ;
GetRequestedAction < UK2Node_FormatText > ( ContextMenuBuilder , K2ActionCategories : : TextCategory ) ;
GetAnimNotifyMenuItems ( ContextMenuBuilder ) ;
GetVariableGettersSettersForClass ( ContextMenuBuilder , Class , true , bAllowEvents ) ;
uint32 FunctionTypes = UEdGraphSchema_K2 : : FT_Pure | UEdGraphSchema_K2 : : FT_Const | UEdGraphSchema_K2 : : FT_Protected ;
if ( bAllowImpureFuncs )
{
FunctionTypes | = UEdGraphSchema_K2 : : FT_Imperative ;
}
GetFuncNodesForClass ( ContextMenuBuilder , Class , Class , ContextMenuBuilder . CurrentGraph , FunctionTypes , K2ActionCategories : : GenericFunctionCategory ) ;
GetFuncNodesForClass ( ContextMenuBuilder , NULL , Class , ContextMenuBuilder . CurrentGraph , FunctionTypes , K2ActionCategories : : GenericFunctionCategory ) ;
// spawn actor from archetype node
if ( ! bIsConstructionScript )
{
AddSpawnActorNodeAction ( ContextMenuBuilder , K2ActionCategories : : GenericFunctionCategory ) ;
if ( Class - > IsChildOf ( AActor : : StaticClass ( ) ) )
{
GetInputNodes ( ContextMenuBuilder , true ) ;
}
}
// Add struct make/break nodes
GetStructActions ( ContextMenuBuilder ) ;
bool bCompositeOfUbberGraph = false ;
//If the composite has a ubergraph in its outer, it is allowed to have timelines/events added
if ( bSupportsEventGraphs & & K2Schema - > IsCompositeGraph ( ContextMenuBuilder . CurrentGraph ) )
{
const UEdGraph * TestGraph = ContextMenuBuilder . CurrentGraph ;
while ( TestGraph )
{
if ( UK2Node_Composite * Composite = Cast < UK2Node_Composite > ( TestGraph - > GetOuter ( ) ) )
{
TestGraph = Cast < UEdGraph > ( Composite - > GetOuter ( ) ) ;
}
else if ( K2Schema - > GetGraphType ( TestGraph ) = = GT_Ubergraph )
{
bCompositeOfUbberGraph = true ;
break ;
}
else
{
TestGraph = Cast < UEdGraph > ( TestGraph - > GetOuter ( ) ) ;
}
}
}
if ( bAllowEvents | | bCompositeOfUbberGraph )
{
FBlueprintPaletteListBuilder PaletteBuilder ( ContextMenuBuilder . Blueprint ) ;
GetAllEventActions ( PaletteBuilder ) ;
ContextMenuBuilder . Append ( PaletteBuilder ) ;
// PlayMovieScene
// @todo sequencer: Currently don't allow "PlayMovieScene" to be added to scripts unless Sequencer is enabled
// @todo sequencer: This block of logic causes MovieSceneTools to be circularly dependent with UnrealEd. Ideally we don't want UnrealEd to statically depend on MovieSceneTools!
/*
if ( FParse : : Param ( FCommandLine : : Get ( ) , TEXT ( " Sequencer " ) ) )
{
if ( FBlueprintEditorUtils : : IsLevelScriptBlueprint ( Blueprint ) & & FBlueprintEditorUtils : : DoesSupportEventGraphs ( Blueprint ) )
{
// @todo sequencer: Should probably use drag and drop to place a new MovieScene node instead of placing an empty node
TSharedPtr < FEdGraphSchemaAction_K2AddPlayMovieScene > Action ( new FEdGraphSchemaAction_K2AddPlayMovieScene ( TEXT ( " " ) , TEXT ( " Play MovieScene... " ) , TEXT ( " " ) , 0 ) ) ;
OutTypes . Add ( Action ) ;
UK2Node_PlayMovieScene * PlayMovieSceneNode = ContextMenuBuilder . CreateTemplateNode < UK2Node_PlayMovieScene > ( ) ;
Action - > NodeTemplate = PlayMovieSceneNode ;
}
} */
}
if ( FKismetEditorUtilities : : CanPasteNodes ( ContextMenuBuilder . CurrentGraph ) )
{
2014-04-23 18:30:37 -04:00
TSharedPtr < FEdGraphSchemaAction_K2PasteHere > NewAction ( new FEdGraphSchemaAction_K2PasteHere ( TEXT ( " " ) , LOCTEXT ( " PasteHere " , " Paste here " ) , TEXT ( " " ) , 0 ) ) ;
2014-03-14 14:13:41 -04:00
ContextMenuBuilder . AddAction ( NewAction ) ;
}
// Level script
if ( FBlueprintEditorUtils : : IsLevelScriptBlueprint ( Blueprint ) )
{
GetLiteralsFromActorSelection ( ContextMenuBuilder ) ;
GetBoundEventsFromActorSelection ( ContextMenuBuilder ) ;
GetMatineeControllers ( ContextMenuBuilder ) ;
GetFunctionCallsOnSelectedActors ( ContextMenuBuilder ) ;
}
// Non level script
else if ( FBlueprintEditorUtils : : IsActorBased ( Blueprint ) )
{
GetAddComponentActionsUsingSelectedAssets ( ContextMenuBuilder ) ;
GetAddComponentClasses ( ContextMenuBuilder . Blueprint , ContextMenuBuilder ) ;
GetFunctionCallsOnSelectedComponents ( ContextMenuBuilder ) ;
if ( bAllowEvents )
{
GetBoundEventsFromComponentSelection ( ContextMenuBuilder ) ;
}
}
// Show local variables and assignment nodes only if it's *not* an ubergraph
if ( ( GraphType ! = GT_Ubergraph ) & & ( GraphType ! = GT_Animation ) )
{
// Assignment statement
{
UK2Node * NodeTemplate = ContextMenuBuilder . CreateTemplateNode < UK2Node_AssignmentStatement > ( ) ;
TSharedPtr < FEdGraphSchemaAction_K2NewNode > Action = FK2ActionMenuBuilder : : AddNewNodeAction ( ContextMenuBuilder , K2ActionCategories : : MacroToolsCategory , NodeTemplate - > GetNodeTitle ( ENodeTitleType : : ListView ) , NodeTemplate - > GetTooltip ( ) , 0 , NodeTemplate - > GetKeywords ( ) ) ;
Action - > NodeTemplate = NodeTemplate ;
2014-04-23 18:30:37 -04:00
Action - > SearchTitle = NodeTemplate - > GetNodeSearchTitle ( ) ;
2014-03-14 14:13:41 -04:00
}
// Temporary variables
TArray < FEdGraphPinType > TemporaryTypes ;
// Standard Types
TemporaryTypes . Add ( FEdGraphPinType ( K2Schema - > PC_Int , TEXT ( " " ) , NULL , false , false ) ) ;
TemporaryTypes . Add ( FEdGraphPinType ( K2Schema - > PC_Float , TEXT ( " " ) , NULL , false , false ) ) ;
TemporaryTypes . Add ( FEdGraphPinType ( K2Schema - > PC_Boolean , TEXT ( " " ) , NULL , false , false ) ) ;
TemporaryTypes . Add ( FEdGraphPinType ( K2Schema - > PC_String , TEXT ( " " ) , NULL , false , false ) ) ;
TemporaryTypes . Add ( FEdGraphPinType ( K2Schema - > PC_Text , TEXT ( " " ) , NULL , false , false ) ) ;
// Array Variants
TemporaryTypes . Add ( FEdGraphPinType ( K2Schema - > PC_Int , TEXT ( " " ) , NULL , true , false ) ) ;
TemporaryTypes . Add ( FEdGraphPinType ( K2Schema - > PC_Float , TEXT ( " " ) , NULL , true , false ) ) ;
TemporaryTypes . Add ( FEdGraphPinType ( K2Schema - > PC_Boolean , TEXT ( " " ) , NULL , true , false ) ) ;
TemporaryTypes . Add ( FEdGraphPinType ( K2Schema - > PC_String , TEXT ( " " ) , NULL , true , false ) ) ;
TemporaryTypes . Add ( FEdGraphPinType ( K2Schema - > PC_Text , TEXT ( " " ) , NULL , true , false ) ) ;
FEdGraphPinType VectorPinType = FEdGraphPinType ( K2Schema - > PC_Struct , TEXT ( " Vector " ) , NULL , false , false ) ;
VectorPinType . PinSubCategoryObject = FindObjectChecked < UScriptStruct > ( UObject : : StaticClass ( ) , TEXT ( " Vector " ) ) ;
TemporaryTypes . Add ( VectorPinType ) ;
VectorPinType . bIsArray = true ;
TemporaryTypes . Add ( VectorPinType ) ;
FEdGraphPinType RotatorPinType = FEdGraphPinType ( K2Schema - > PC_Struct , TEXT ( " Rotator " ) , NULL , false , false ) ;
RotatorPinType . PinSubCategoryObject = FindObjectChecked < UScriptStruct > ( UObject : : StaticClass ( ) , TEXT ( " Rotator " ) ) ;
TemporaryTypes . Add ( RotatorPinType ) ;
RotatorPinType . bIsArray = true ;
TemporaryTypes . Add ( RotatorPinType ) ;
FEdGraphPinType TransformPinType = FEdGraphPinType ( K2Schema - > PC_Struct , TEXT ( " Transform " ) , NULL , false , false ) ;
TransformPinType . PinSubCategoryObject = FindObjectChecked < UScriptStruct > ( UObject : : StaticClass ( ) , TEXT ( " Transform " ) ) ;
TemporaryTypes . Add ( TransformPinType ) ;
TransformPinType . bIsArray = true ;
TemporaryTypes . Add ( TransformPinType ) ;
FEdGraphPinType BlendSampleDataPinType = FEdGraphPinType ( K2Schema - > PC_Struct , TEXT ( " BlendSampleData " ) , NULL , false , false ) ;
BlendSampleDataPinType . PinSubCategoryObject = FindObjectChecked < UScriptStruct > ( ANY_PACKAGE , TEXT ( " BlendSampleData " ) ) ;
BlendSampleDataPinType . bIsArray = true ;
TemporaryTypes . Add ( BlendSampleDataPinType ) ;
if ( bAllowUnsafeCommands )
{
for ( FObjectIterator Iter ( UScriptStruct : : StaticClass ( ) ) ; Iter ; + + Iter )
{
UScriptStruct * Struct = CastChecked < UScriptStruct > ( * Iter ) ;
TemporaryTypes . Add ( FEdGraphPinType ( K2Schema - > PC_Struct , TEXT ( " " ) , Struct , false , false ) ) ;
}
}
for ( TArray < FEdGraphPinType > : : TIterator TypeIt ( TemporaryTypes ) ; TypeIt ; + + TypeIt )
{
2014-05-09 17:43:40 -04:00
// Add a standard version of the local
2014-03-14 14:13:41 -04:00
{
2014-05-09 17:43:40 -04:00
UK2Node_TemporaryVariable * NodeTemplate = ContextMenuBuilder . CreateTemplateNode < UK2Node_TemporaryVariable > ( ) ;
NodeTemplate - > VariableType = * TypeIt ;
TSharedPtr < FEdGraphSchemaAction_K2NewNode > Action = FK2ActionMenuBuilder : : AddNewNodeAction ( ContextMenuBuilder , K2ActionCategories : : MacroToolsCategory , NodeTemplate - > GetNodeTitle ( ENodeTitleType : : ListView ) , NodeTemplate - > GetTooltip ( ) , 0 , NodeTemplate - > GetKeywords ( ) ) ;
Action - > NodeTemplate = NodeTemplate ;
Action - > SearchTitle = NodeTemplate - > GetNodeSearchTitle ( ) ;
2014-03-14 14:13:41 -04:00
}
}
// Add in bool and int persistent pin types
if ( GraphType = = GT_Macro )
{
// Persistent Integer
UK2Node_TemporaryVariable * PersistentIntNodeTemplate = ContextMenuBuilder . CreateTemplateNode < UK2Node_TemporaryVariable > ( ) ;
PersistentIntNodeTemplate - > VariableType = FEdGraphPinType ( K2Schema - > PC_Int , TEXT ( " " ) , NULL , false , false ) ;
PersistentIntNodeTemplate - > bIsPersistent = true ;
TSharedPtr < FEdGraphSchemaAction_K2NewNode > IntAction = FK2ActionMenuBuilder : : AddNewNodeAction ( ContextMenuBuilder , K2ActionCategories : : MacroToolsCategory , PersistentIntNodeTemplate - > GetNodeTitle ( ENodeTitleType : : ListView ) , PersistentIntNodeTemplate - > GetTooltip ( ) , 0 , PersistentIntNodeTemplate - > GetKeywords ( ) ) ;
IntAction - > NodeTemplate = PersistentIntNodeTemplate ;
2014-04-23 18:30:37 -04:00
IntAction - > SearchTitle = PersistentIntNodeTemplate - > GetNodeSearchTitle ( ) ;
2014-03-14 14:13:41 -04:00
// Persistent Bool
UK2Node_TemporaryVariable * PersistentBoolNodeTemplate = ContextMenuBuilder . CreateTemplateNode < UK2Node_TemporaryVariable > ( ) ;
PersistentBoolNodeTemplate - > VariableType = FEdGraphPinType ( K2Schema - > PC_Boolean , TEXT ( " " ) , NULL , false , false ) ;
PersistentBoolNodeTemplate - > bIsPersistent = true ;
TSharedPtr < FEdGraphSchemaAction_K2NewNode > BoolAction = FK2ActionMenuBuilder : : AddNewNodeAction ( ContextMenuBuilder , K2ActionCategories : : MacroToolsCategory , PersistentBoolNodeTemplate - > GetNodeTitle ( ENodeTitleType : : ListView ) , PersistentBoolNodeTemplate - > GetTooltip ( ) , 0 , PersistentBoolNodeTemplate - > GetKeywords ( ) ) ;
BoolAction - > NodeTemplate = PersistentBoolNodeTemplate ;
2014-04-23 18:30:37 -04:00
BoolAction - > SearchTitle = PersistentBoolNodeTemplate - > GetNodeSearchTitle ( ) ;
2014-03-14 14:13:41 -04:00
}
}
FBlueprintPaletteListBuilder PaletteBuilder ( ContextMenuBuilder . Blueprint ) ;
// Show viable macros to instance
GetMacroTools ( PaletteBuilder , bAllowImpureFuncs , ContextMenuBuilder . CurrentGraph ) ;
ContextMenuBuilder . Append ( PaletteBuilder ) ;
// Show messages that can potentially be called
if ( bAllowImpureFuncs ) // Note: Bad naming, but intentional; messages could have any number of arbitrary side effects
{
for ( TObjectIterator < UClass > It ; It ; + + It )
{
GetInterfaceMessages ( * It , TEXT ( " Interface Messages " ) , ContextMenuBuilder ) ;
}
}
GetCommentAction ( ContextMenuBuilder . Blueprint , ContextMenuBuilder ) ;
{
UK2Node * NodeTemplate = ContextMenuBuilder . CreateTemplateNode < UK2Node_Select > ( ) ;
TSharedPtr < FEdGraphSchemaAction_K2NewNode > SelectionAction = FK2ActionMenuBuilder : : AddNewNodeAction ( ContextMenuBuilder , K2ActionCategories : : UtilitiesCategory , NodeTemplate - > GetNodeTitle ( ENodeTitleType : : ListView ) , NodeTemplate - > GetTooltip ( ) , 0 , NodeTemplate - > GetKeywords ( ) ) ;
SelectionAction - > NodeTemplate = NodeTemplate ;
2014-04-23 18:30:37 -04:00
SelectionAction - > SearchTitle = NodeTemplate - > GetNodeSearchTitle ( ) ;
2014-03-14 14:13:41 -04:00
}
FEditorDelegates : : OnBlueprintContextMenuCreated . Broadcast ( ContextMenuBuilder ) ;
2014-04-23 17:34:21 -04:00
GetEnumUtilitiesNodes ( ContextMenuBuilder , true , true , true , true ) ;
2014-03-14 14:13:41 -04:00
}
}
//------------------------------------------------------------------------------
2014-04-02 18:09:23 -04:00
struct FClassDynamicCastHelper
{
static bool CanCastToClass ( const UClass * TestClass , const UEdGraphSchema_K2 * K2Schema )
{
check ( TestClass & & K2Schema ) ;
2014-05-05 01:38:12 -04:00
const bool bIsSkeletonClass = FKismetEditorUtilities : : IsClassABlueprintSkeleton ( TestClass ) ;
2014-04-02 18:09:23 -04:00
const bool bProperClass = TestClass - > HasAnyFlags ( RF_Public ) & & ! TestClass - > HasAnyClassFlags ( CLASS_Deprecated | CLASS_NewerVersionExists ) ;
const bool bAllowedByBPComms = K2Schema - > bAllowBlueprintComms | | ! TestClass - > ClassGeneratedBy ;
return ! bIsSkeletonClass & & bProperClass & & bAllowedByBPComms ;
}
static void SpawnNode ( UClass * TargetType , FBlueprintGraphActionListBuilder & ContextMenuBuilder )
{
static const FString CastCategory = K2ActionCategories : : GenericFunctionCategory + " | " + K2ActionCategories : : CastingCategory ;
UK2Node_DynamicCast * CastNode = ContextMenuBuilder . CreateTemplateNode < UK2Node_ClassDynamicCast > ( ) ;
CastNode - > TargetType = TargetType ;
TSharedPtr < FEdGraphSchemaAction_K2NewNode > Action = FK2ActionMenuBuilder : : AddNewNodeAction ( ContextMenuBuilder , CastCategory , CastNode - > GetNodeTitle ( ENodeTitleType : : ListView ) , TEXT ( " Dynamic cast to a specific type " ) , 0 , CastNode - > GetKeywords ( ) ) ;
Action - > NodeTemplate = CastNode ;
2014-04-23 18:30:37 -04:00
Action - > SearchTitle = CastNode - > GetNodeSearchTitle ( ) ;
2014-04-02 18:09:23 -04:00
}
static void GetClassDynamicCastNodes ( FBlueprintGraphActionListBuilder & ContextMenuBuilder , const UEdGraphSchema_K2 * K2Schema )
{
check ( ContextMenuBuilder . FromPin & & K2Schema ) ;
const UEdGraphPin & FromPin = * ContextMenuBuilder . FromPin ;
if ( ( FromPin . PinType . PinCategory = = K2Schema - > PC_Class ) )
{
UClass * PinClass = Cast < UClass > ( FromPin . PinType . PinSubCategoryObject . Get ( ) ) ;
if ( FromPin . Direction = = EGPD_Output )
{
for ( TObjectIterator < UClass > ClassIt ; ClassIt ; + + ClassIt )
{
UClass * TestClass = * ClassIt ;
const bool bCanCastFromPin = ! PinClass | | ( ( TestClass ! = PinClass ) & & TestClass - > IsChildOf ( PinClass ) ) ;
if ( bCanCastFromPin & & CanCastToClass ( TestClass , K2Schema ) )
{
SpawnNode ( TestClass , ContextMenuBuilder ) ;
}
}
}
else if ( PinClass
& & ( FromPin . Direction = = EGPD_Input )
& & ( UObject : : StaticClass ( ) ! = PinClass )
& & CanCastToClass ( PinClass , K2Schema ) )
{
SpawnNode ( PinClass , ContextMenuBuilder ) ;
}
}
}
} ;
2014-03-14 14:13:41 -04:00
void FK2ActionMenuBuilder : : GetPinAllowedNodeTypes ( FBlueprintGraphActionListBuilder & ContextMenuBuilder ) const
{
const UBlueprint * Blueprint = ContextMenuBuilder . Blueprint ;
UClass * Class = ( Blueprint ! = NULL ) ? Blueprint - > SkeletonGeneratedClass : NULL ;
if ( Class = = NULL )
{
UE_LOG ( LogBlueprint , Log , TEXT ( " GetPinAllowedNodeTypes: Failed to find class from Blueprint '%s' " ) , * Blueprint - > GetPathName ( ) ) ;
}
else
{
const UEdGraphPin & FromPin = * ContextMenuBuilder . FromPin ;
const EGraphType GraphType = K2Schema - > GetGraphType ( ContextMenuBuilder . CurrentGraph ) ;
const bool bAllowImpureFuncs = K2Schema - > DoesGraphSupportImpureFunctions ( ContextMenuBuilder . CurrentGraph ) ;
if ( ( FromPin . PinType . PinCategory = = K2Schema - > PC_Exec ) & & bAllowImpureFuncs )
{
GetRequestedAction < UK2Node_IfThenElse > ( ContextMenuBuilder , K2ActionCategories : : FlowControlCategory ) ;
GetRequestedAction < UK2Node_ExecutionSequence > ( ContextMenuBuilder , K2ActionCategories : : FlowControlCategory ) ;
GetRequestedAction < UK2Node_MultiGate > ( ContextMenuBuilder , K2ActionCategories : : FlowControlCategory ) ;
FBlueprintPaletteListBuilder PaletteBuilder ( ContextMenuBuilder . Blueprint ) ;
GetSwitchMenuItems ( PaletteBuilder , K2ActionCategories : : FlowControlCategory , ContextMenuBuilder . FromPin ) ;
ContextMenuBuilder . Append ( PaletteBuilder ) ;
// For Exec types, just show all imperative functions in current context
const bool bRequireDesiredPinType = true ;
const bool bWantBindableDelegates = ( GraphType = = GT_Ubergraph ) | | ( GraphType = = GT_Function ) | |
( ( bAllowUnsafeCommands ) & & ( Blueprint - > BlueprintType = = BPTYPE_MacroLibrary ) ) ;
GetFuncNodesForClass ( ContextMenuBuilder , Class , Class , ContextMenuBuilder . CurrentGraph , UEdGraphSchema_K2 : : FT_Imperative | UEdGraphSchema_K2 : : FT_Protected , K2ActionCategories : : GenericFunctionCategory ) ;
GetFuncNodesForClass ( ContextMenuBuilder , NULL , Class , ContextMenuBuilder . CurrentGraph , UEdGraphSchema_K2 : : FT_Imperative | UEdGraphSchema_K2 : : FT_Protected , K2ActionCategories : : GenericFunctionCategory ) ;
GetVariableGettersSettersForClass ( ContextMenuBuilder , Class , FromPin . PinType , true , false , true , bWantBindableDelegates , bRequireDesiredPinType ) ;
if ( FBlueprintEditorUtils : : IsLevelScriptBlueprint ( Blueprint ) )
{
GetFunctionCallsOnSelectedActors ( ContextMenuBuilder ) ;
}
else if ( FBlueprintEditorUtils : : IsActorBased ( Blueprint ) )
{
GetAddComponentActionsUsingSelectedAssets ( ContextMenuBuilder ) ;
GetAddComponentClasses ( ContextMenuBuilder . Blueprint , ContextMenuBuilder ) ;
}
if ( ! K2Schema - > IsConstructionScript ( ContextMenuBuilder . CurrentGraph ) )
{
AddSpawnActorNodeAction ( ContextMenuBuilder , K2ActionCategories : : GenericFunctionCategory ) ;
if ( Class - > IsChildOf ( AActor : : StaticClass ( ) ) )
{
const bool bIncludeEvents = FromPin . Direction = = EGPD_Input ;
GetInputNodes ( ContextMenuBuilder , bIncludeEvents ) ;
}
}
// for output pins, add macro flow control as a connection option
if ( FromPin . Direction = = EGPD_Output )
{
const bool bWantsOutputs = false ;
GetPinAllowedMacros ( ContextMenuBuilder , Class , FromPin . PinType , bWantsOutputs , bAllowImpureFuncs ) ;
}
// For input pins, add Events as a connection option
if ( FromPin . Direction = = EGPD_Input )
{
GetEventsForBlueprint ( PaletteBuilder ) ;
ContextMenuBuilder . Append ( PaletteBuilder ) ;
}
GetAllInterfaceMessageActions ( ContextMenuBuilder ) ;
}
2014-04-23 17:58:27 -04:00
else if ( ( FromPin . PinType . PinCategory = = K2Schema - > PC_Object ) | | ( FromPin . PinType . PinCategory = = K2Schema - > PC_Interface ) )
2014-03-14 14:13:41 -04:00
{
// For Object types, look for functions we can call on that object
UClass * PinClass = Cast < UClass > ( FromPin . PinType . PinSubCategoryObject . Get ( ) ) ;
if ( PinClass )
{
GetInterfaceMessages ( PinClass , TEXT ( " Interface Messages " ) , ContextMenuBuilder ) ;
if ( FromPin . Direction = = EGPD_Output )
{
// If this is a call to another generated class, find the first parent that is natively-defined, to prevent calls to improper function headers
if ( ! K2Schema - > bAllowBlueprintComms & & ( PinClass - > ClassGeneratedBy & & PinClass - > ClassGeneratedBy ! = Blueprint ) & & ! FBlueprintEditorUtils : : IsLevelScriptBlueprint ( Blueprint ) )
{
while ( PinClass - > ClassGeneratedBy ! = NULL )
{
PinClass = PinClass - > GetSuperClass ( ) ;
}
}
const bool bWantBindableDelegates = ( GraphType = = GT_Ubergraph ) | | ( GraphType = = GT_Function ) | |
( ( bAllowUnsafeCommands ) & & ( Blueprint - > BlueprintType = = BPTYPE_MacroLibrary ) ) ;
if ( ! FromPin . PinType . bIsArray )
{
FEdGraphPinType DontCareType ;
const bool bRequireDesiredPinType = false ;
GetVariableGettersSettersForClass ( ContextMenuBuilder , PinClass , DontCareType , false , true , bAllowImpureFuncs , bWantBindableDelegates , bRequireDesiredPinType ) ;
// Get functions you can call on this kind of pin
uint32 FunctionTypes = UEdGraphSchema_K2 : : FT_Const ;
if ( bAllowImpureFuncs )
{
FunctionTypes | = UEdGraphSchema_K2 : : FT_Imperative ;
}
GetFuncNodesForClass ( ContextMenuBuilder , PinClass , PinClass , ContextMenuBuilder . CurrentGraph , FunctionTypes , K2ActionCategories : : GenericFunctionCategory ) ;
if ( FromPin . PinType . bIsReference )
{
GetReferenceSetterItems ( ContextMenuBuilder ) ;
}
}
else if ( bAllowImpureFuncs & & PinClass )
{
GetFuncNodesForClass ( ContextMenuBuilder , PinClass , PinClass , ContextMenuBuilder . CurrentGraph , UEdGraphSchema_K2 : : FT_Imperative , K2ActionCategories : : CallFuncForEachCategory , FFunctionTargetInfo ( ) , false , true ) ;
if ( bWantBindableDelegates )
{
GetEventDispatcherNodesForClass ( ContextMenuBuilder , PinClass , false ) ;
}
}
GetFuncNodesWithPinType ( ContextMenuBuilder , NULL , Class , FromPin . PinType , false , ! bAllowImpureFuncs ) ;
GetPinAllowedMacros ( ContextMenuBuilder , Class , FromPin . PinType , false , bAllowImpureFuncs ) ;
}
if ( FromPin . Direction = = EGPD_Input )
{
const bool bRequireDesiredPinType = true ;
const bool bWantBindableDelegates = false ;
GetVariableGettersSettersForClass ( ContextMenuBuilder , Class , FromPin . PinType , true , true , false , bWantBindableDelegates , bRequireDesiredPinType ) ;
GetFuncNodesWithPinType ( ContextMenuBuilder , Class , Class , FromPin . PinType , true , ! bAllowImpureFuncs ) ;
GetFuncNodesWithPinType ( ContextMenuBuilder , NULL , Class , FromPin . PinType , true , ! bAllowImpureFuncs ) ;
GetPinAllowedMacros ( ContextMenuBuilder , Class , FromPin . PinType , true , bAllowImpureFuncs ) ;
}
// Dynamic casts
{
FString const CastCategory = K2ActionCategories : : GenericFunctionCategory + " | " + K2ActionCategories : : CastingCategory ;
for ( TObjectIterator < UClass > ClassIt ; ClassIt ; + + ClassIt )
{
UClass * TestClass = * ClassIt ;
2014-05-05 01:38:12 -04:00
bool bIsSkeletonClass = FKismetEditorUtilities : : IsClassABlueprintSkeleton ( TestClass ) ;
2014-03-14 14:13:41 -04:00
if ( TestClass - > HasAnyFlags ( RF_Public ) & & ! bIsSkeletonClass & & ! TestClass - > HasAnyClassFlags ( CLASS_Deprecated | CLASS_NewerVersionExists ) & & ( K2Schema - > bAllowBlueprintComms | | ! TestClass - > ClassGeneratedBy ) )
{
bool bIsCastable = false ;
if ( TestClass ! = PinClass )
{
// from Parent(pin) to Child(test) (output); offer cast
// from Parent(test) to Child(pin) (input); offer cast
if ( FromPin . Direction = = EGPD_Output )
{
bIsCastable = TestClass - > IsChildOf ( PinClass ) ;
}
else if ( FromPin . Direction = = EGPD_Input )
{
bIsCastable = PinClass - > IsChildOf ( TestClass ) ;
}
}
if ( bIsCastable )
{
UK2Node_DynamicCast * CastNode = ContextMenuBuilder . CreateTemplateNode < UK2Node_DynamicCast > ( ) ;
CastNode - > TargetType = TestClass ;
TSharedPtr < FEdGraphSchemaAction_K2NewNode > Action = FK2ActionMenuBuilder : : AddNewNodeAction ( ContextMenuBuilder , CastCategory , CastNode - > GetNodeTitle ( ENodeTitleType : : ListView ) , TEXT ( " Dynamic cast to a specific type " ) , 0 , CastNode - > GetKeywords ( ) ) ;
Action - > NodeTemplate = CastNode ;
2014-04-23 18:30:37 -04:00
Action - > SearchTitle = CastNode - > GetNodeSearchTitle ( ) ;
2014-03-14 14:13:41 -04:00
}
}
}
}
}
}
else if ( FromPin . PinType . PinCategory ! = K2Schema - > PC_Wildcard )
{
const bool bWantOutputs = FromPin . Direction = = EGPD_Input ;
// List variables that match the type
const bool bWantGetters = bWantOutputs ;
const bool bWantSetters = ( FromPin . Direction = = EGPD_Output ) & & bAllowImpureFuncs ;
const bool bRequirePinType = true ;
GetVariableGettersSettersForClass ( ContextMenuBuilder , Class , FromPin . PinType , true , bWantGetters , bWantSetters , false , bRequirePinType ) ;
// For POD types, look for a mix of callable and pure functions (in current context and in function libraries) that have an input/output of the correct type
GetFuncNodesWithPinType ( ContextMenuBuilder , Class , Class , FromPin . PinType , bWantOutputs , ! bAllowImpureFuncs ) ;
GetFuncNodesWithPinType ( ContextMenuBuilder , NULL , Class , FromPin . PinType , bWantOutputs , ! bAllowImpureFuncs ) ;
// Add if flow control block to pin for bool pin type
if ( ( FromPin . PinType . PinCategory = = K2Schema - > PC_Boolean ) & & ( bWantSetters ) )
{
GetRequestedAction < UK2Node_IfThenElse > ( ContextMenuBuilder , K2ActionCategories : : FlowControlCategory ) ;
}
// Add in any suitable macros for pin
GetPinAllowedMacros ( ContextMenuBuilder , Class , FromPin . PinType , bWantOutputs , bAllowImpureFuncs ) ;
if ( FromPin . Direction = = EGPD_Output )
{
// Try looking for switches that switch on this pin type
FBlueprintPaletteListBuilder PaletteBuilder ( ContextMenuBuilder . Blueprint ) ;
GetSwitchMenuItems ( PaletteBuilder , K2ActionCategories : : FlowControlCategory , ContextMenuBuilder . FromPin ) ;
ContextMenuBuilder . Append ( PaletteBuilder ) ;
// If this is a reference pin, grab a setter node as well
if ( FromPin . PinType . bIsReference & & ! FromPin . PinType . bIsArray )
{
GetReferenceSetterItems ( ContextMenuBuilder ) ;
}
}
else if ( FromPin . Direction = = EGPD_Input )
{
if ( FromPin . PinType . bIsArray )
{
GetRequestedAction < UK2Node_MakeArray > ( ContextMenuBuilder , K2ActionCategories : : ArrayCategory ) ;
}
}
if ( ( K2Schema - > PC_Struct = = FromPin . PinType . PinCategory ) & & ! FromPin . PinType . bIsArray )
{
UScriptStruct * PinStruct = Cast < UScriptStruct > ( FromPin . PinType . PinSubCategoryObject . Get ( ) ) ;
if ( ( FromPin . Direction = = EGPD_Output ) & & UK2Node_BreakStruct : : CanBeBroken ( PinStruct ) )
{
UK2Node_BreakStruct * NodeTemplate = ContextMenuBuilder . CreateTemplateNode < UK2Node_BreakStruct > ( ) ;
NodeTemplate - > StructType = PinStruct ;
TSharedPtr < FEdGraphSchemaAction_K2NewNode > Action = FK2ActionMenuBuilder : : AddNewNodeAction ( ContextMenuBuilder , FString ( ) , NodeTemplate - > GetNodeTitle ( ENodeTitleType : : ListView ) , NodeTemplate - > GetTooltip ( ) , 0 , NodeTemplate - > GetKeywords ( ) ) ;
Action - > NodeTemplate = NodeTemplate ;
2014-04-23 18:30:37 -04:00
Action - > SearchTitle = NodeTemplate - > GetNodeSearchTitle ( ) ;
2014-03-14 14:13:41 -04:00
}
else if ( ( FromPin . Direction = = EGPD_Input ) & & UK2Node_MakeStruct : : CanBeMade ( PinStruct ) )
{
UK2Node_MakeStruct * NodeTemplate = ContextMenuBuilder . CreateTemplateNode < UK2Node_MakeStruct > ( ) ;
NodeTemplate - > StructType = PinStruct ;
TSharedPtr < FEdGraphSchemaAction_K2NewNode > Action = FK2ActionMenuBuilder : : AddNewNodeAction ( ContextMenuBuilder , FString ( ) , NodeTemplate - > GetNodeTitle ( ENodeTitleType : : ListView ) , NodeTemplate - > GetTooltip ( ) , 0 , NodeTemplate - > GetKeywords ( ) ) ;
Action - > NodeTemplate = NodeTemplate ;
2014-04-23 18:30:37 -04:00
Action - > SearchTitle = NodeTemplate - > GetNodeSearchTitle ( ) ;
2014-03-14 14:13:41 -04:00
}
}
if ( ( FromPin . Direction = = EGPD_Input ) & & ( FromPin . PinType . PinCategory = = K2Schema - > PC_Delegate ) )
{
UK2Node_CreateDelegate * NodeTemplate = ContextMenuBuilder . CreateTemplateNode < UK2Node_CreateDelegate > ( ) ;
TSharedPtr < FEdGraphSchemaAction_K2NewNode > Action = FK2ActionMenuBuilder : : AddNewNodeAction ( ContextMenuBuilder , FString ( ) , NodeTemplate - > GetNodeTitle ( ENodeTitleType : : ListView ) , NodeTemplate - > GetTooltip ( ) , 0 , NodeTemplate - > GetKeywords ( ) ) ;
Action - > NodeTemplate = NodeTemplate ;
2014-04-23 18:30:37 -04:00
Action - > SearchTitle = NodeTemplate - > GetNodeSearchTitle ( ) ;
2014-03-14 14:13:41 -04:00
2014-04-23 20:18:55 -04:00
UFunction * Signature = FMemberReference : : ResolveSimpleMemberReference < UFunction > ( FromPin . PinType . PinSubCategoryMemberReference ) ;
2014-03-14 14:13:41 -04:00
const bool bSupportsEventGraphs = ( Blueprint & & FBlueprintEditorUtils : : DoesSupportEventGraphs ( Blueprint ) ) ;
const bool bAllowEvents = ( GraphType = = GT_Ubergraph ) ;
if ( Signature & & bSupportsEventGraphs & & bAllowEvents )
{
2014-04-23 18:30:37 -04:00
TSharedPtr < FEdGraphSchemaAction_EventFromFunction > DelegateEvent ( new FEdGraphSchemaAction_EventFromFunction ( FString ( ) , LOCTEXT ( " AddCustomEventForDispatcher " , " Add Custom Event for Dispatcher " ) , LOCTEXT ( " AddCustomEventForDispatcher_Tooltip " , " Add a new event for given Dispatcher " ) . ToString ( ) , 0 ) ) ;
2014-03-14 14:13:41 -04:00
ContextMenuBuilder . AddAction ( DelegateEvent ) ;
DelegateEvent - > SignatureFunction = Signature ;
}
}
}
2014-04-02 18:09:23 -04:00
FClassDynamicCastHelper : : GetClassDynamicCastNodes ( ContextMenuBuilder , K2Schema ) ;
2014-03-14 14:13:41 -04:00
if ( ( FromPin . Direction = = EGPD_Input ) & & ( FromPin . PinType . PinCategory = = K2Schema - > PC_Int ) )
{
2014-04-23 17:34:21 -04:00
GetEnumUtilitiesNodes ( ContextMenuBuilder , true , false , false , true ) ;
2014-03-14 14:13:41 -04:00
}
else if ( FromPin . PinType . PinCategory = = K2Schema - > PC_Text )
{
GetRequestedAction < UK2Node_FormatText > ( ContextMenuBuilder , K2ActionCategories : : ArrayCategory ) ;
}
UEnum * Enum = Cast < UEnum > ( FromPin . PinType . PinSubCategoryObject . Get ( ) ) ;
if ( ( FromPin . PinType . PinCategory = = K2Schema - > PC_Byte ) & & Enum )
{
if ( FromPin . Direction = = EGPD_Output )
{
FString ConversionsCategory = TEXT ( " Conversions " ) ;
GetRequestedAction < UK2Node_GetEnumeratorName > ( ContextMenuBuilder , K2ActionCategories : : NameCategory ) ;
GetRequestedAction < UK2Node_GetEnumeratorNameAsString > ( ContextMenuBuilder , K2ActionCategories : : StringCategory ) ;
}
if ( FromPin . Direction = = EGPD_Input )
{
2014-04-23 17:34:21 -04:00
GetEnumUtilitiesNodes ( ContextMenuBuilder , false , true , true , false , Enum ) ;
2014-03-14 14:13:41 -04:00
}
}
2014-04-23 17:34:21 -04:00
else if ( ( FromPin . PinType . PinCategory = = K2Schema - > PC_Byte ) & & ! Enum & & FromPin . Direction = = EGPD_Input )
{
GetEnumUtilitiesNodes ( ContextMenuBuilder , false , false , false , true ) ;
}
2014-03-14 14:13:41 -04:00
}
}
//------------------------------------------------------------------------------
void FK2ActionMenuBuilder : : GetFuncNodesForClass ( FGraphActionListBuilderBase & ListBuilder , const UClass * Class , const UClass * OwnerClass , const UEdGraph * DestGraph , uint32 FunctionTypes , const FString & BaseCategory , const FFunctionTargetInfo & TargetInfo , bool bShowInherited , bool bCalledForEach ) const
{
if ( Class ! = NULL )
{
bool bLatentFuncs = true ;
bool bIsConstructionScript = false ;
if ( DestGraph ! = NULL )
{
bLatentFuncs = ( K2Schema - > GetGraphType ( DestGraph ) = = GT_Ubergraph ) ;
bIsConstructionScript = K2Schema - > IsConstructionScript ( DestGraph ) ;
}
// Find all functions on the current class
EFieldIteratorFlags : : SuperClassFlags SuperClassFlag = bShowInherited ? EFieldIteratorFlags : : IncludeSuper : EFieldIteratorFlags : : ExcludeSuper ;
for ( TFieldIterator < UFunction > FunctionIt ( Class , SuperClassFlag ) ; FunctionIt ; + + FunctionIt )
{
UFunction * Function = * FunctionIt ;
if ( K2Schema - > CanFunctionBeUsedInClass ( Class , Function , DestGraph , FunctionTypes , bShowInherited , bCalledForEach , TargetInfo ) )
{
FK2ActionMenuBuilder : : AddSpawnInfoForFunction ( Function , false , TargetInfo , FMemberReference ( ) , BaseCategory , K2Schema - > AG_LevelReference , ListBuilder , bCalledForEach ) ;
}
}
// If looking for 'inherited functions', search for object properties we can call functions _on_
if ( bShowInherited )
{
for ( TFieldIterator < UObjectProperty > PropIt ( Class , EFieldIteratorFlags : : IncludeSuper ) ; PropIt ; + + PropIt )
{
UObjectProperty * ObjProp = * PropIt ;
// See if this object property is exposed to BP and has function categories we can call on it
FString ExposeFuncCatsString = ObjProp - > GetMetaData ( FBlueprintMetadata : : MD_ExposeFunctionCategories ) ;
if ( ObjProp - > HasAllPropertyFlags ( CPF_BlueprintVisible ) & & ExposeFuncCatsString . Len ( ) > 0 )
{
TArray < FString > ExposeFuncCats ;
ExposeFuncCatsString . ParseIntoArray ( & ExposeFuncCats , TEXT ( " , " ) , true ) ;
// Look for functions in those categories
UClass * ObjClass = ObjProp - > PropertyClass ;
for ( TFieldIterator < UFunction > FunctionIt ( ObjClass , EFieldIteratorFlags : : IncludeSuper ) ; FunctionIt ; + + FunctionIt )
{
UFunction * Function = * FunctionIt ;
// Get category of function and see if its in our list
FString FunctionCategory = Function - > GetMetaData ( FBlueprintMetadata : : MD_FunctionCategory ) ;
if ( ExposeFuncCats . Contains ( FunctionCategory ) )
{
// It is, create menu option for it
FMemberReference MemberVarRef ;
MemberVarRef . SetFromField < UProperty > ( ObjProp , false ) ;
FK2ActionMenuBuilder : : AddSpawnInfoForFunction ( Function , false , TargetInfo , MemberVarRef , BaseCategory , K2Schema - > AG_LevelReference , ListBuilder ) ;
}
}
}
}
}
}
else
{
// Find all functions in each function library
2014-04-30 13:33:50 -04:00
for ( TObjectIterator < UClass > ClassIt ; ClassIt ; + + ClassIt )
2014-03-14 14:13:41 -04:00
{
UClass * TestClass = * ClassIt ;
2014-04-30 07:59:51 -04:00
const bool bTransient = ( GetTransientPackage ( ) = = TestClass - > GetOutermost ( ) ) ;
const UClass * AuthoritativeOwnerClass = OwnerClass ? const_cast < UClass * > ( OwnerClass ) - > GetAuthoritativeClass ( ) : NULL ;
const bool bCanShowInOwnerClass = ! AuthoritativeOwnerClass | | ! TestClass - > IsChildOf ( AuthoritativeOwnerClass ) ;
const bool bIsProperFucntionLibrary = TestClass - > IsChildOf ( UBlueprintFunctionLibrary : : StaticClass ( ) ) & & CanUseLibraryFunctionsForScope ( TestClass , OwnerClass ) ;
2014-05-05 01:38:12 -04:00
const bool bIsSkeletonClass = FKismetEditorUtilities : : IsClassABlueprintSkeleton ( TestClass ) ;
2014-04-30 13:33:50 -04:00
if ( bCanShowInOwnerClass & & bIsProperFucntionLibrary & & ! bTransient & & ! bIsSkeletonClass )
2014-03-14 14:13:41 -04:00
{
GetFuncNodesForClass ( ListBuilder , TestClass , OwnerClass , DestGraph , FunctionTypes , BaseCategory , TargetInfo ) ;
}
}
}
}
//------------------------------------------------------------------------------
void FK2ActionMenuBuilder : : GetAllActionsForClass ( FBlueprintPaletteListBuilder & PaletteBuilder , const UClass * InClass , bool bShowInherited , bool bShowProtected , bool bShowVariables , bool bShowDelegates ) const
{
UBlueprint * ClassBlueprint = UBlueprint : : GetBlueprintFromClass ( InClass ) ;
// @TODO Don't show other blueprints yet...
if ( ! InClass - > HasAnyClassFlags ( CLASS_Deprecated | CLASS_NewerVersionExists ) & & ( ClassBlueprint = = NULL ) )
{
int32 FuncFlags = UEdGraphSchema_K2 : : FT_Const | UEdGraphSchema_K2 : : FT_Imperative | UEdGraphSchema_K2 : : FT_Pure ;
if ( bShowProtected )
{
FuncFlags | = UEdGraphSchema_K2 : : FT_Protected ;
}
GetFuncNodesForClass ( PaletteBuilder , InClass , InClass , NULL , FuncFlags , TEXT ( " " ) , FFunctionTargetInfo ( ) , bShowInherited ) ;
// Find vars
if ( bShowVariables )
{
EFieldIteratorFlags : : SuperClassFlags SuperClassFlag = bShowInherited ? EFieldIteratorFlags : : IncludeSuper : EFieldIteratorFlags : : ExcludeSuper ;
for ( TFieldIterator < UProperty > PropertyIt ( InClass , SuperClassFlag ) ; PropertyIt ; + + PropertyIt )
{
UProperty * Property = * PropertyIt ;
if ( K2Schema - > CanUserKismetAccessVariable ( Property , InClass , UEdGraphSchema_K2 : : CannotBeDelegate ) )
{
const FString PropertyTooltip = Property - > GetToolTipText ( ) . ToString ( ) ;
const FString PropertyDesc = GetDefault < UEditorStyleSettings > ( ) - > bShowFriendlyNames ? UEditorEngine : : GetFriendlyName ( Property ) : Property - > GetName ( ) ;
const FString PropertyCategory = FObjectEditorUtils : : GetCategory ( Property ) ;
2014-04-23 18:30:37 -04:00
TSharedPtr < FEdGraphSchemaAction_K2Var > NewVarAction = TSharedPtr < FEdGraphSchemaAction_K2Var > ( new FEdGraphSchemaAction_K2Var ( PropertyCategory , FText : : FromString ( PropertyDesc ) , PropertyTooltip , 0 ) ) ;
2014-03-14 14:13:41 -04:00
NewVarAction - > SetVariableInfo ( Property - > GetFName ( ) , InClass ) ;
PaletteBuilder . AddAction ( NewVarAction ) ;
}
}
}
if ( bShowDelegates )
{
const EFieldIteratorFlags : : SuperClassFlags SuperClassFlag = bShowInherited ? EFieldIteratorFlags : : IncludeSuper : EFieldIteratorFlags : : ExcludeSuper ;
for ( TFieldIterator < UMulticastDelegateProperty > PropertyIt ( InClass , SuperClassFlag ) ; PropertyIt ; + + PropertyIt )
{
UMulticastDelegateProperty * Property = * PropertyIt ;
const bool bHidden = FObjectEditorUtils : : IsVariableCategoryHiddenFromClass ( Property , InClass ) ;
const bool bShow = ! Property - > HasAnyPropertyFlags ( CPF_Parm ) & & Property - > HasAnyPropertyFlags ( CPF_BlueprintAssignable | CPF_BlueprintCallable ) & & ! bHidden ;
if ( bShow )
{
const FString PropertyTooltip = Property - > GetToolTipText ( ) . ToString ( ) ;
const FString PropertyDesc = GetDefault < UEditorStyleSettings > ( ) - > bShowFriendlyNames ? UEditorEngine : : GetFriendlyName ( Property ) : Property - > GetName ( ) ;
FString PropertyCategory = FObjectEditorUtils : : GetCategory ( Property ) ;
if ( PropertyCategory . IsEmpty ( ) )
{
PropertyCategory = K2ActionCategories : : DefaultEventDispatcherCategory ;
}
2014-04-23 17:36:48 -04:00
PropertyCategory = FName : : NameToDisplayString ( PropertyCategory , /*bIsBool =*/ false ) ;
2014-03-14 14:13:41 -04:00
2014-04-23 18:30:37 -04:00
TSharedPtr < FEdGraphSchemaAction_K2Delegate > NewFuncAction = MakeShareable ( new FEdGraphSchemaAction_K2Delegate ( PropertyCategory , FText : : FromString ( PropertyDesc ) , PropertyTooltip , 0 ) ) ;
2014-03-14 14:13:41 -04:00
NewFuncAction - > SetDelegateInfo ( Property - > GetFName ( ) , InClass ) ;
UClass * CurrentPropertyOwner = Cast < UClass > ( Property - > GetOuterUField ( ) ) ;
if ( CurrentPropertyOwner & & ClassBlueprint & & ClassBlueprint = = CurrentPropertyOwner - > ClassGeneratedBy )
{
NewFuncAction - > EdGraph = FBlueprintEditorUtils : : GetDelegateSignatureGraphByName ( ClassBlueprint , Property - > GetFName ( ) ) ;
}
else
{
NewFuncAction - > EdGraph = NULL ;
}
PaletteBuilder . AddAction ( NewFuncAction ) ;
}
}
}
}
}
//------------------------------------------------------------------------------
void FK2ActionMenuBuilder : : GetSwitchMenuItems ( FBlueprintPaletteListBuilder & ActionMenuBuilder , FString const & RootCategory , UEdGraphPin const * PinContext ) const
{
FString const SwitchControlCategory = RootCategory + K2ActionCategories : : SubCategoryDelim + K2ActionCategories : : SwitchSubCategory ;
// Determine if we have an enum restriction
UEnum * RequiredEnum = NULL ;
if ( PinContext ! = NULL )
{
RequiredEnum = Cast < UEnum > ( PinContext - > PinType . PinSubCategoryObject . Get ( ) ) ;
}
// Add integer switch
if ( ( PinContext = = NULL ) | | ( PinContext - > PinType . PinCategory = = K2Schema - > PC_Int ) ) //@TODO: Give byte->int casting a shot
{
GetRequestedAction < UK2Node_SwitchInteger > ( ActionMenuBuilder , SwitchControlCategory ) ;
}
// Add string switch
if ( ( PinContext = = NULL ) | | ( PinContext - > PinType . PinCategory = = K2Schema - > PC_String ) )
{
GetRequestedAction < UK2Node_SwitchString > ( ActionMenuBuilder , SwitchControlCategory ) ;
}
// Add Name switch
if ( ( PinContext = = NULL ) | | ( PinContext - > PinType . PinCategory = = K2Schema - > PC_Name ) )
{
GetRequestedAction < UK2Node_SwitchName > ( ActionMenuBuilder , SwitchControlCategory ) ;
}
// Add a switch entry for any enum types that pass the filter
if ( ( PinContext = = NULL ) | | ( RequiredEnum ! = NULL ) )
{
for ( TObjectIterator < UEnum > EnumIt ; EnumIt ; + + EnumIt )
{
UEnum * CurrentEnum = * EnumIt ;
const bool bIsBlueprintType = UEdGraphSchema_K2 : : IsAllowableBlueprintVariableType ( CurrentEnum ) ;
const bool bMatchesEnumFilter = ( RequiredEnum = = NULL ) | | ( CurrentEnum = = RequiredEnum ) ;
if ( bIsBlueprintType & & bMatchesEnumFilter )
{
UK2Node_SwitchEnum * EnumTemplate = ActionMenuBuilder . CreateTemplateNode < UK2Node_SwitchEnum > ( ) ;
EnumTemplate - > SetEnum ( CurrentEnum ) ;
UK2Node * NodeTemplate = EnumTemplate ;
TSharedPtr < FEdGraphSchemaAction_K2NewNode > Action = FK2ActionMenuBuilder : : AddNewNodeAction ( ActionMenuBuilder , SwitchControlCategory , NodeTemplate - > GetNodeTitle ( ENodeTitleType : : ListView ) , NodeTemplate - > GetTooltip ( ) , 0 , NodeTemplate - > GetKeywords ( ) ) ;
Action - > NodeTemplate = NodeTemplate ;
2014-04-23 18:30:37 -04:00
Action - > SearchTitle = NodeTemplate - > GetNodeSearchTitle ( ) ;
2014-03-14 14:13:41 -04:00
}
}
}
}
//------------------------------------------------------------------------------
void FK2ActionMenuBuilder : : GetAnimNotifyMenuItems ( FBlueprintGraphActionListBuilder & ContextMenuBuilder ) const
{
UAnimBlueprint * AnimBlueprint = Cast < UAnimBlueprint > ( FBlueprintEditorUtils : : FindBlueprintForGraph ( ContextMenuBuilder . CurrentGraph ) ) ;
if ( K2Schema - > DoesSupportAnimNotifyActions ( ) & & ( AnimBlueprint ! = NULL ) )
{
// find all animnotifies it can use
if ( AnimBlueprint - > TargetSkeleton )
{
for ( int32 I = 0 ; I < AnimBlueprint - > TargetSkeleton - > AnimationNotifies . Num ( ) ; + + I )
{
FName NotifyName = AnimBlueprint - > TargetSkeleton - > AnimationNotifies [ I ] ;
FString Label = NotifyName . ToString ( ) ;
2014-04-23 18:30:37 -04:00
TSharedPtr < FEdGraphSchemaAction_K2NewNode > Action = FK2ActionMenuBuilder : : AddNewNodeAction ( ContextMenuBuilder , K2ActionCategories : : AnimNotifyCategory , FText : : FromString ( Label ) , TEXT ( " " ) ) ;
2014-03-14 14:13:41 -04:00
UK2Node_Event * EventNode = ContextMenuBuilder . CreateTemplateNode < UK2Node_Event > ( ) ;
FString SignatureName = FString : : Printf ( TEXT ( " AnimNotify_%s " ) , * Label ) ;
EventNode - > EventSignatureName = FName ( * SignatureName ) ;
EventNode - > EventSignatureClass = UAnimInstance : : StaticClass ( ) ;
EventNode - > CustomFunctionName = EventNode - > EventSignatureName ;
Action - > NodeTemplate = EventNode ;
2014-04-23 18:30:37 -04:00
Action - > SearchTitle = Action - > NodeTemplate - > GetNodeSearchTitle ( ) ;
2014-03-14 14:13:41 -04:00
}
// @todo anim: fix this to be same as notifies, save same list in the
// add montage menus
// find all montages that uses current target skeleton
TArray < FName > BrancingPointHandlers ;
for ( FObjectIterator Iter ( UAnimMontage : : StaticClass ( ) ) ; Iter ; + + Iter )
{
UAnimMontage * Montage = CastChecked < UAnimMontage > ( * Iter ) ;
if ( Montage & & Montage - > GetSkeleton ( ) = = AnimBlueprint - > TargetSkeleton )
{
// now add event handler if exists
for ( int32 I = 0 ; I < Montage - > BranchingPoints . Num ( ) ; + + I )
{
BrancingPointHandlers . AddUnique ( Montage - > BranchingPoints [ I ] . EventName ) ;
}
}
}
for ( int32 I = 0 ; I < BrancingPointHandlers . Num ( ) ; + + I )
{
FName NotifyName = BrancingPointHandlers [ I ] ;
FString Label = NotifyName . ToString ( ) ;
2014-04-23 18:30:37 -04:00
TSharedPtr < FEdGraphSchemaAction_K2NewNode > Action = FK2ActionMenuBuilder : : AddNewNodeAction ( ContextMenuBuilder , K2ActionCategories : : BranchPointCategory , FText : : FromString ( Label ) , TEXT ( " " ) ) ;
2014-03-14 14:13:41 -04:00
UK2Node_Event * EventNode = ContextMenuBuilder . CreateTemplateNode < UK2Node_Event > ( ) ;
FString SignatureName = FString : : Printf ( TEXT ( " MontageBranchingPoint_%s " ) , * Label ) ;
EventNode - > EventSignatureName = FName ( * SignatureName ) ;
EventNode - > EventSignatureClass = UAnimInstance : : StaticClass ( ) ;
EventNode - > CustomFunctionName = EventNode - > EventSignatureName ;
Action - > NodeTemplate = EventNode ;
2014-04-23 18:30:37 -04:00
Action - > SearchTitle = Action - > NodeTemplate - > GetNodeSearchTitle ( ) ;
2014-03-14 14:13:41 -04:00
}
}
// State machine events
if ( UAnimBlueprintGeneratedClass * GeneratedClass = AnimBlueprint - > GetAnimBlueprintGeneratedClass ( ) )
{
for ( int32 NotifyIdx = 0 ; NotifyIdx < GeneratedClass - > AnimNotifies . Num ( ) ; NotifyIdx + + )
{
FName NotifyName = GeneratedClass - > AnimNotifies [ NotifyIdx ] . NotifyName ;
if ( NotifyName ! = NAME_None )
{
FString Label = NotifyName . ToString ( ) ;
2014-04-23 18:30:37 -04:00
TSharedPtr < FEdGraphSchemaAction_K2NewNode > Action = FK2ActionMenuBuilder : : AddNewNodeAction ( ContextMenuBuilder , K2ActionCategories : : StateMachineCategory , FText : : FromString ( Label ) , TEXT ( " " ) ) ;
2014-03-14 14:13:41 -04:00
UK2Node_Event * EventNode = ContextMenuBuilder . CreateTemplateNode < UK2Node_Event > ( ) ;
FString SignatureName = FString : : Printf ( TEXT ( " AnimNotify_%s " ) , * Label ) ;
EventNode - > EventSignatureName = FName ( * SignatureName ) ;
EventNode - > EventSignatureClass = UAnimInstance : : StaticClass ( ) ;
EventNode - > CustomFunctionName = EventNode - > EventSignatureName ;
Action - > NodeTemplate = EventNode ;
2014-04-23 18:30:37 -04:00
Action - > SearchTitle = Action - > NodeTemplate - > GetNodeSearchTitle ( ) ;
2014-03-14 14:13:41 -04:00
}
}
}
}
}
//------------------------------------------------------------------------------
void FK2ActionMenuBuilder : : GetVariableGettersSettersForClass ( FBlueprintGraphActionListBuilder & ContextMenuBuilder , const UClass * Class , bool bSelfContext , bool bIncludeDelegates ) const
{
FEdGraphPinType DontCareType ;
const bool bWantGetters = true ;
const bool bWantSetters = true ;
const bool bRequireDesiredPinType = false ;
GetVariableGettersSettersForClass ( ContextMenuBuilder , Class , DontCareType , bSelfContext , bWantGetters , bWantSetters , bIncludeDelegates , bRequireDesiredPinType ) ;
}
//------------------------------------------------------------------------------
void FK2ActionMenuBuilder : : GetVariableGettersSettersForClass ( FBlueprintGraphActionListBuilder & ContextMenuBuilder , const UClass * Class , const FEdGraphPinType & DesiredPinType , bool bSelfContext , bool bWantGetters , bool bWantSetters , bool bWantDelegates , bool bRequireDesiredPinType ) const
{
check ( Class ) ;
FString GetString ( TEXT ( " Get " ) ) ;
FString SetString ( TEXT ( " Set " ) ) ;
FString SelfString ( TEXT ( " Get a reference to self " ) ) ;
FString SelfTooltip ( TEXT ( " Get a reference to this object " ) ) ;
FString GetStructMemberString ( TEXT ( " Get members in " ) ) ;
FString SetStructMemberString ( TEXT ( " Set members in " ) ) ;
FString MakeStructString ( TEXT ( " Make " ) ) ;
if ( Class - > HasAnyClassFlags ( CLASS_Const ) )
{
bWantSetters = false ;
}
for ( TFieldIterator < UProperty > PropertyIt ( Class , EFieldIteratorFlags : : IncludeSuper ) ; PropertyIt ; + + PropertyIt )
{
UProperty * Property = * PropertyIt ;
UClass * PropertyClass = CastChecked < UClass > ( Property - > GetOuter ( ) ) ;
const bool bIsDelegate = Property - > IsA ( UMulticastDelegateProperty : : StaticClass ( ) ) ;
if ( UEdGraphSchema_K2 : : CanUserKismetAccessVariable ( Property , Class , UEdGraphSchema_K2 : : VariablesAndDelegates ) )
{
//@TODO: To properly filter protected and private variables, we need to know the calling context too
FString Category = FObjectEditorUtils : : GetCategory ( Property ) ;
FString PropertyTooltip = Property - > GetToolTipText ( ) . ToString ( ) ;
if ( PropertyTooltip . IsEmpty ( ) )
{
PropertyTooltip = FString : : Printf ( TEXT ( " Category %s " ) , * Category ) ;
}
const FString PropertyDescription = GetDefault < UEditorStyleSettings > ( ) - > bShowFriendlyNames ? UEditorEngine : : GetFriendlyName ( Property ) : Property - > GetName ( ) ;
FEdGraphPinType PropertyTypeAsPinType ;
bool bTypesMatchForRead = ! bRequireDesiredPinType ;
bool bTypesMatchForWrite = ! bRequireDesiredPinType ;
if ( bRequireDesiredPinType & & K2Schema - > ConvertPropertyToPinType ( Property , /*out*/ PropertyTypeAsPinType ) )
{
// reading (property out -> pin in)
bTypesMatchForRead = K2Schema - > ArePinTypesCompatible ( PropertyTypeAsPinType , DesiredPinType , Class ) ;
// writing (pin out -> property in)
// Always allow exec pins to write
bTypesMatchForWrite = DesiredPinType . PinCategory = = K2Schema - > PC_Exec | | K2Schema - > ArePinTypesCompatible ( DesiredPinType , PropertyTypeAsPinType , Class ) ;
}
FString FullCategoryName = K2ActionCategories : : VariablesCategory ;
if ( Category . IsEmpty ( ) = = false )
{
FullCategoryName + = K2ActionCategories : : SubCategoryDelim ;
FullCategoryName + = Category ;
}
const bool bIsReadOnly = FBlueprintEditorUtils : : IsPropertyReadOnlyInCurrentBlueprint ( ContextMenuBuilder . Blueprint , Property ) ;
const bool bCanRead = bWantGetters & & bTypesMatchForRead ;
const bool bCanWrite = bWantSetters & & bTypesMatchForWrite & & ! bIsReadOnly ;
const bool bCanModifyDelegate = ! bRequireDesiredPinType & & ! bIsReadOnly ;
if ( ! bIsDelegate )
{
// Variable getters and setters
if ( bCanRead )
{
2014-04-23 18:30:37 -04:00
TSharedPtr < FEdGraphSchemaAction_K2NewNode > ReadVar = FK2ActionMenuBuilder : : AddNewNodeAction ( ContextMenuBuilder , FullCategoryName , FText : : FromString ( GetString + PropertyDescription ) , PropertyTooltip ) ;
2014-03-14 14:13:41 -04:00
UK2Node_VariableGet * VarGetNode = ContextMenuBuilder . CreateTemplateNode < UK2Node_VariableGet > ( ) ;
VarGetNode - > SetFromProperty ( Property , bSelfContext ) ;
ReadVar - > NodeTemplate = VarGetNode ;
2014-04-23 18:30:37 -04:00
ReadVar - > SearchTitle = ReadVar - > NodeTemplate - > GetNodeSearchTitle ( ) ;
2014-03-14 14:13:41 -04:00
}
if ( bCanWrite )
{
2014-04-23 18:30:37 -04:00
TSharedPtr < FEdGraphSchemaAction_K2NewNode > WriteVar = FK2ActionMenuBuilder : : AddNewNodeAction ( ContextMenuBuilder , FullCategoryName , FText : : FromString ( SetString + PropertyDescription ) , PropertyTooltip ) ;
2014-03-14 14:13:41 -04:00
UK2Node_VariableSet * VarSetNode = ContextMenuBuilder . CreateTemplateNode < UK2Node_VariableSet > ( ) ;
VarSetNode - > SetFromProperty ( Property , bSelfContext ) ;
WriteVar - > NodeTemplate = VarSetNode ;
2014-04-23 18:30:37 -04:00
WriteVar - > SearchTitle = WriteVar - > NodeTemplate - > GetNodeSearchTitle ( ) ;
2014-03-14 14:13:41 -04:00
}
}
}
}
2014-05-09 17:43:40 -04:00
// Add any local variables to the list as well
UEdGraph * FunctionGraph = FBlueprintEditorUtils : : GetTopLevelGraph ( ContextMenuBuilder . CurrentGraph ) ;
TArray < UK2Node_FunctionEntry * > FunctionEntryNodes ;
FunctionGraph - > GetNodesOfClass < UK2Node_FunctionEntry > ( FunctionEntryNodes ) ;
if ( FunctionEntryNodes . Num ( ) = = 1 )
{
// Setting them without the property, cannot guarantee that properties in the UFunction are valid as local variables
for ( auto & LocalVariable : FunctionEntryNodes [ 0 ] - > LocalVariables )
{
bool bTypesMatchForRead = ! bRequireDesiredPinType ;
bool bTypesMatchForWrite = ! bRequireDesiredPinType ;
if ( bRequireDesiredPinType )
{
// reading (property out -> pin in)
bTypesMatchForRead = K2Schema - > ArePinTypesCompatible ( LocalVariable . VarType , DesiredPinType , Class ) ;
// writing (pin out -> property in)
// Always allow exec pins to write
bTypesMatchForWrite = DesiredPinType . PinCategory = = K2Schema - > PC_Exec | | K2Schema - > ArePinTypesCompatible ( DesiredPinType , LocalVariable . VarType , Class ) ;
}
FString Category = LocalVariable . Category . ToString ( ) ;
FString PropertyTooltip ;
if ( LocalVariable . HasMetaData ( TEXT ( " tooltip " ) ) )
{
PropertyTooltip = LocalVariable . GetMetaData ( TEXT ( " tooltip " ) ) ;
}
FString FullCategoryName = K2ActionCategories : : VariablesCategory ;
if ( Category . IsEmpty ( ) = = false )
{
FullCategoryName + = K2ActionCategories : : SubCategoryDelim ;
FullCategoryName + = Category ;
}
const FString PropertyDescription = GetDefault < UEditorStyleSettings > ( ) - > bShowFriendlyNames ? LocalVariable . FriendlyName : LocalVariable . VarName . ToString ( ) ;
const bool bCanRead = bWantGetters & & bTypesMatchForRead ;
const bool bCanWrite = bWantSetters & & bTypesMatchForWrite ;
{
// Variable getters and setters
if ( bCanRead )
{
TSharedPtr < FEdGraphSchemaAction_K2NewNode > ReadVar = FK2ActionMenuBuilder : : AddNewNodeAction ( ContextMenuBuilder , FullCategoryName , FText : : FromString ( GetString + PropertyDescription ) , PropertyTooltip ) ;
UK2Node_VariableGet * VarGetNode = ContextMenuBuilder . CreateTemplateNode < UK2Node_VariableGet > ( ) ;
VarGetNode - > VariableReference . SetLocalMember ( LocalVariable . VarName , FunctionGraph - > GetName ( ) , LocalVariable . VarGuid ) ;
ReadVar - > NodeTemplate = VarGetNode ;
ReadVar - > SearchTitle = ReadVar - > NodeTemplate - > GetNodeSearchTitle ( ) ;
}
if ( bCanWrite )
{
TSharedPtr < FEdGraphSchemaAction_K2NewNode > WriteVar = FK2ActionMenuBuilder : : AddNewNodeAction ( ContextMenuBuilder , FullCategoryName , FText : : FromString ( SetString + PropertyDescription ) , PropertyTooltip ) ;
UK2Node_VariableSet * VarSetNode = ContextMenuBuilder . CreateTemplateNode < UK2Node_VariableSet > ( ) ;
VarSetNode - > VariableReference . SetLocalMember ( LocalVariable . VarName , FunctionGraph - > GetName ( ) , LocalVariable . VarGuid ) ;
WriteVar - > NodeTemplate = VarSetNode ;
WriteVar - > SearchTitle = WriteVar - > NodeTemplate - > GetNodeSearchTitle ( ) ;
}
}
}
}
2014-03-14 14:13:41 -04:00
if ( bWantDelegates )
{
GetEventDispatcherNodesForClass ( ContextMenuBuilder , Class , bSelfContext ) ;
}
// Add in self-context variable getter, if needed
2014-04-30 07:59:51 -04:00
const bool bSelfIsAllowed = ! Class - > IsChildOf ( UBlueprintFunctionLibrary : : StaticClass ( ) ) ;
if ( bSelfContext & & bWantGetters & & bSelfIsAllowed )
2014-03-14 14:13:41 -04:00
{
2014-04-23 18:30:37 -04:00
TSharedPtr < FEdGraphSchemaAction_K2NewNode > SelfVar = FK2ActionMenuBuilder : : AddNewNodeAction ( ContextMenuBuilder , K2ActionCategories : : VariablesCategory , FText : : FromString ( SelfString ) , SelfTooltip ) ;
2014-03-14 14:13:41 -04:00
UK2Node_Self * SelfNode = ContextMenuBuilder . CreateTemplateNode < UK2Node_Self > ( ) ;
SelfNode - > SelfClass = ( UClass * ) Class ;
SelfVar - > NodeTemplate = SelfNode ;
2014-04-23 18:30:37 -04:00
SelfVar - > SearchTitle = SelfVar - > NodeTemplate - > GetNodeSearchTitle ( ) ;
2014-03-14 14:13:41 -04:00
SelfVar - > Keywords = SelfNode - > GetKeywords ( ) ;
}
}
//------------------------------------------------------------------------------
void FK2ActionMenuBuilder : : GetEventDispatcherNodesForClass ( FBlueprintGraphActionListBuilder & ContextMenuBuilder , const UClass * Class , bool bSelfContext ) const
{
check ( Class ) ;
static const FString BindString ( TEXT ( " Assign " ) ) ;
for ( TFieldIterator < UProperty > PropertyIt ( Class , EFieldIteratorFlags : : IncludeSuper ) ; PropertyIt ; + + PropertyIt )
{
UProperty * Property = * PropertyIt ;
UClass * PropertyClass = CastChecked < UClass > ( Property - > GetOuter ( ) ) ;
const bool bIsDelegate = Property - > IsA ( UMulticastDelegateProperty : : StaticClass ( ) ) ;
if ( UEdGraphSchema_K2 : : CanUserKismetAccessVariable ( Property , Class , UEdGraphSchema_K2 : : VariablesAndDelegates ) & & bIsDelegate )
{
const FString Category = FObjectEditorUtils : : GetCategory ( Property ) ;
FString PropertyTooltip = Property - > GetToolTipText ( ) . ToString ( ) ;
if ( PropertyTooltip . IsEmpty ( ) )
{
PropertyTooltip = FString : : Printf ( TEXT ( " Category %s " ) , * Category ) ;
}
const bool bCanHaveBlueprintImplementableEventInActorClass = bSelfContext & & ( PropertyClass = = AActor : : StaticClass ( ) ) ;
// e.g. Actor::OnActorBeginOverlap should not be assigned as a delegate, when one can implement Actor::ReceiveActorBeginOverlap
if ( Property - > HasAllPropertyFlags ( CPF_BlueprintAssignable ) & & ! bCanHaveBlueprintImplementableEventInActorClass )
{
{
UK2Node_AddDelegate * DelegateEventNode = ContextMenuBuilder . CreateTemplateNode < UK2Node_AddDelegate > ( ) ;
DelegateEventNode - > SetFromProperty ( Property , bSelfContext ) ;
const EGraphType GraphType = K2Schema - > GetGraphType ( ContextMenuBuilder . CurrentGraph ) ;
const bool bSupportsEventGraphs = ( ContextMenuBuilder . Blueprint & & FBlueprintEditorUtils : : DoesSupportEventGraphs ( ContextMenuBuilder . Blueprint ) ) ;
const bool bAllowEvents = ( ( GraphType = = GT_Ubergraph ) & & bSupportsEventGraphs ) ;
if ( bAllowEvents )
{
const FString PropertyDescription = GetDefault < UEditorStyleSettings > ( ) - > bShowFriendlyNames ? UEditorEngine : : GetFriendlyName ( Property ) : Property - > GetName ( ) ;
2014-04-23 18:30:37 -04:00
TSharedPtr < FEdGraphSchemaAction_K2AssignDelegate > AssignDelegateEvent ( new FEdGraphSchemaAction_K2AssignDelegate ( K2ActionCategories : : DelegateBindingCategory , FText : : FromString ( BindString + PropertyDescription ) , PropertyTooltip , 0 ) ) ;
2014-03-14 14:13:41 -04:00
AssignDelegateEvent - > NodeTemplate = DelegateEventNode ;
2014-04-23 18:30:37 -04:00
AssignDelegateEvent - > SearchTitle = AssignDelegateEvent - > NodeTemplate - > GetNodeSearchTitle ( ) ;
2014-03-14 14:13:41 -04:00
ContextMenuBuilder . AddAction ( AssignDelegateEvent ) ;
}
TSharedPtr < FEdGraphSchemaAction_K2NewNode > DelegateEvent = FK2ActionMenuBuilder : : AddNewNodeAction ( ContextMenuBuilder , K2ActionCategories : : DelegateCategory , DelegateEventNode - > GetNodeTitle ( ENodeTitleType : : FullTitle ) , PropertyTooltip ) ;
DelegateEvent - > NodeTemplate = DelegateEventNode ;
2014-04-23 18:30:37 -04:00
DelegateEvent - > SearchTitle = DelegateEvent - > NodeTemplate - > GetNodeSearchTitle ( ) ;
DelegateEvent - > SearchTitle = DelegateEventNode - > GetNodeSearchTitle ( ) ;
2014-03-14 14:13:41 -04:00
}
{
UK2Node_RemoveDelegate * DelegateEventNode = ContextMenuBuilder . CreateTemplateNode < UK2Node_RemoveDelegate > ( ) ;
DelegateEventNode - > SetFromProperty ( Property , bSelfContext ) ;
TSharedPtr < FEdGraphSchemaAction_K2NewNode > DelegateEvent = FK2ActionMenuBuilder : : AddNewNodeAction ( ContextMenuBuilder , K2ActionCategories : : DelegateCategory , DelegateEventNode - > GetNodeTitle ( ENodeTitleType : : FullTitle ) , PropertyTooltip ) ;
DelegateEvent - > NodeTemplate = DelegateEventNode ;
2014-04-23 18:30:37 -04:00
DelegateEvent - > SearchTitle = DelegateEvent - > NodeTemplate - > GetNodeSearchTitle ( ) ;
DelegateEvent - > SearchTitle = DelegateEventNode - > GetNodeSearchTitle ( ) ;
2014-03-14 14:13:41 -04:00
}
{
UK2Node_ClearDelegate * DelegateEventNode = ContextMenuBuilder . CreateTemplateNode < UK2Node_ClearDelegate > ( ) ;
DelegateEventNode - > SetFromProperty ( Property , bSelfContext ) ;
TSharedPtr < FEdGraphSchemaAction_K2NewNode > DelegateEvent = FK2ActionMenuBuilder : : AddNewNodeAction ( ContextMenuBuilder , K2ActionCategories : : DelegateCategory , DelegateEventNode - > GetNodeTitle ( ENodeTitleType : : FullTitle ) , PropertyTooltip ) ;
DelegateEvent - > NodeTemplate = DelegateEventNode ;
2014-04-23 18:30:37 -04:00
DelegateEvent - > SearchTitle = DelegateEvent - > NodeTemplate - > GetNodeSearchTitle ( ) ;
DelegateEvent - > SearchTitle = DelegateEventNode - > GetNodeSearchTitle ( ) ;
2014-03-14 14:13:41 -04:00
}
}
if ( Property - > HasAllPropertyFlags ( CPF_BlueprintCallable ) )
{
UK2Node_CallDelegate * DelegateEventNode = ContextMenuBuilder . CreateTemplateNode < UK2Node_CallDelegate > ( ) ;
DelegateEventNode - > SetFromProperty ( Property , bSelfContext ) ;
TSharedPtr < FEdGraphSchemaAction_K2NewNode > DelegateEvent = FK2ActionMenuBuilder : : AddNewNodeAction ( ContextMenuBuilder , K2ActionCategories : : DelegateCategory , DelegateEventNode - > GetNodeTitle ( ENodeTitleType : : FullTitle ) , PropertyTooltip ) ;
DelegateEvent - > NodeTemplate = DelegateEventNode ;
2014-04-23 18:30:37 -04:00
DelegateEvent - > SearchTitle = DelegateEvent - > NodeTemplate - > GetNodeSearchTitle ( ) ;
DelegateEvent - > SearchTitle = DelegateEventNode - > GetNodeSearchTitle ( ) ;
2014-03-14 14:13:41 -04:00
}
}
}
}
//------------------------------------------------------------------------------
void FK2ActionMenuBuilder : : GetStructActions ( FBlueprintGraphActionListBuilder & ContextMenuBuilder ) const
{
// Iterate through all script struct types
for ( TObjectIterator < UScriptStruct > It ; It ; + + It )
{
UScriptStruct * Struct = * It ;
// If this is a blueprintable variable add a make and break for it
if ( K2Schema - > IsAllowableBlueprintVariableType ( Struct ) )
{
if ( UK2Node_BreakStruct : : CanBeBroken ( Struct ) )
{
UK2Node_BreakStruct * BreakNodeTemplate = ContextMenuBuilder . CreateTemplateNode < UK2Node_BreakStruct > ( ) ;
if ( BreakNodeTemplate ! = NULL )
{
BreakNodeTemplate - > StructType = Struct ;
TSharedPtr < FEdGraphSchemaAction_K2NewNode > Action = FK2ActionMenuBuilder : : AddNewNodeAction ( ContextMenuBuilder , K2ActionCategories : : BreakStructCategory , BreakNodeTemplate - > GetNodeTitle ( ENodeTitleType : : ListView ) , BreakNodeTemplate - > GetTooltip ( ) , 0 , BreakNodeTemplate - > GetKeywords ( ) ) ;
Action - > NodeTemplate = BreakNodeTemplate ;
2014-04-23 18:30:37 -04:00
Action - > SearchTitle = Action - > NodeTemplate - > GetNodeSearchTitle ( ) ;
2014-03-14 14:13:41 -04:00
}
}
if ( UK2Node_MakeStruct : : CanBeMade ( Struct ) )
{
UK2Node_MakeStruct * MakeNodeTemplate = ContextMenuBuilder . CreateTemplateNode < UK2Node_MakeStruct > ( ) ;
if ( MakeNodeTemplate ! = NULL )
{
MakeNodeTemplate - > StructType = Struct ;
TSharedPtr < FEdGraphSchemaAction_K2NewNode > Action = FK2ActionMenuBuilder : : AddNewNodeAction ( ContextMenuBuilder , K2ActionCategories : : MakeStructCategory , MakeNodeTemplate - > GetNodeTitle ( ENodeTitleType : : ListView ) , MakeNodeTemplate - > GetTooltip ( ) , 0 , MakeNodeTemplate - > GetKeywords ( ) ) ;
Action - > NodeTemplate = MakeNodeTemplate ;
2014-04-23 18:30:37 -04:00
Action - > SearchTitle = Action - > NodeTemplate - > GetNodeSearchTitle ( ) ;
2014-03-14 14:13:41 -04:00
}
}
}
}
}
//------------------------------------------------------------------------------
void FK2ActionMenuBuilder : : GetAllEventActions ( FBlueprintPaletteListBuilder & ActionMenuBuilder ) const
{
// Events
GetEventsForBlueprint ( ActionMenuBuilder ) ;
// Timeline
if ( FBlueprintEditorUtils : : DoesSupportTimelines ( ActionMenuBuilder . Blueprint ) )
{
const FString ToolTip = LOCTEXT ( " Timeline_Tooltip " , " Add a Timeline node to modify values over time. " ) . ToString ( ) ;
2014-04-23 18:30:37 -04:00
TSharedPtr < FEdGraphSchemaAction_K2AddTimeline > Action = TSharedPtr < FEdGraphSchemaAction_K2AddTimeline > ( new FEdGraphSchemaAction_K2AddTimeline ( TEXT ( " " ) , LOCTEXT ( " AddTimeline " , " Add Timeline... " ) , ToolTip , 0 ) ) ;
2014-03-14 14:13:41 -04:00
ActionMenuBuilder . AddAction ( Action ) ;
UK2Node_Timeline * TimelineNodeTemplate = ActionMenuBuilder . CreateTemplateNode < UK2Node_Timeline > ( ) ;
TimelineNodeTemplate - > TimelineName = FBlueprintEditorUtils : : FindUniqueTimelineName ( ActionMenuBuilder . Blueprint ) ;
Action - > NodeTemplate = TimelineNodeTemplate ;
2014-04-23 18:30:37 -04:00
Action - > SearchTitle = Action - > NodeTemplate - > GetNodeSearchTitle ( ) ;
2014-03-14 14:13:41 -04:00
}
}
//------------------------------------------------------------------------------
void FK2ActionMenuBuilder : : GetEventsForBlueprint ( FBlueprintPaletteListBuilder & ActionMenuBuilder ) const
{
const UBlueprint * Blueprint = ActionMenuBuilder . Blueprint ;
check ( ActionMenuBuilder . Blueprint ) ;
// Keep track of the names of the functions being added for uniqueness
TArray < FName > ExistingFuncNames ;
// Keep track of the names of the functions that have already been added to the "show event" list
TArray < FName > ShowEventFuncNames ;
if ( Blueprint - > SkeletonGeneratedClass ! = NULL )
{
// Grab the list of events to be excluded from the override list
const FString ExclusionListKeyName = TEXT ( " KismetHideOverrides " ) ;
TArray < FString > ExcludedEventNames ;
if ( Blueprint - > ParentClass - > HasMetaData ( * ExclusionListKeyName ) )
{
const FString ExcludedEventNameString = Blueprint - > ParentClass - > GetMetaData ( * ExclusionListKeyName ) ;
ExcludedEventNameString . ParseIntoArray ( & ExcludedEventNames , TEXT ( " , " ) , true ) ;
}
// Start the name list by first adding all events already on the graph
TArray < UK2Node_Event * > AllEvents ;
FBlueprintEditorUtils : : GetAllNodesOfClass < UK2Node_Event > ( Blueprint , AllEvents ) ;
for ( auto It = AllEvents . CreateConstIterator ( ) ; It ; It + + )
{
ExistingFuncNames . Add ( ( * It ) - > EventSignatureName ) ;
}
for ( TFieldIterator < UFunction > FunctionIt ( Blueprint - > ParentClass , EFieldIteratorFlags : : IncludeSuper ) ; FunctionIt ; + + FunctionIt )
{
UFunction * Function = * FunctionIt ;
UClass * FuncClass = CastChecked < UClass > ( Function - > GetOuter ( ) ) ;
UK2Node_Event * ExistingOverride = FBlueprintEditorUtils : : FindOverrideForFunction ( Blueprint , FuncClass , Function - > GetFName ( ) ) ;
// See if it can be placed as an event
if ( K2Schema - > FunctionCanBePlacedAsEvent ( Function ) & & ! ExcludedEventNames . Contains ( Function - > GetName ( ) ) )
{
if ( ExistingOverride )
{
if ( ShowEventFuncNames . Find ( Function - > GetFName ( ) ) = = INDEX_NONE )
{
FK2ActionMenuBuilder : : AddEventForFunction ( ActionMenuBuilder , Function ) ;
ShowEventFuncNames . Add ( Function - > GetFName ( ) ) ;
}
}
else if ( ExistingFuncNames . Find ( Function - > GetFName ( ) ) = = INDEX_NONE )
{
FK2ActionMenuBuilder : : AddEventForFunction ( ActionMenuBuilder , Function ) ;
ExistingFuncNames . Add ( Function - > GetFName ( ) ) ;
}
}
}
}
// Build a list of all interface classes either implemented by this blueprint or through inheritance
TArray < UClass * > InterfaceClasses ;
FBlueprintEditorUtils : : FindImplementedInterfaces ( Blueprint , true , InterfaceClasses ) ;
// Add all potential interface events using the class list we build above
for ( auto It = InterfaceClasses . CreateConstIterator ( ) ; It ; It + + )
{
const UClass * Interface = ( * It ) ;
for ( TFieldIterator < UFunction > FunctionIt ( Interface , EFieldIteratorFlags : : IncludeSuper ) ; FunctionIt ; + + FunctionIt )
{
UFunction * Function = * FunctionIt ;
UK2Node_Event * ExistingOverride = FBlueprintEditorUtils : : FindOverrideForFunction ( Blueprint , Interface , Function - > GetFName ( ) ) ;
// See if it can be placed as an event
if ( K2Schema - > FunctionCanBePlacedAsEvent ( Function ) )
{
if ( ExistingOverride )
{
if ( ShowEventFuncNames . Find ( Function - > GetFName ( ) ) = = INDEX_NONE )
{
FK2ActionMenuBuilder : : AddEventForFunction ( ActionMenuBuilder , Function ) ;
}
}
else if ( ExistingFuncNames . Find ( Function - > GetFName ( ) ) = = INDEX_NONE )
{
FK2ActionMenuBuilder : : AddEventForFunction ( ActionMenuBuilder , Function ) ;
ExistingFuncNames . Add ( Function - > GetFName ( ) ) ;
}
}
}
}
// Add support for custom events, if applicable
2014-04-23 18:30:37 -04:00
TSharedPtr < FEdGraphSchemaAction_K2AddCustomEvent > Action = TSharedPtr < FEdGraphSchemaAction_K2AddCustomEvent > ( new FEdGraphSchemaAction_K2AddCustomEvent ( TEXT ( " " ) , LOCTEXT ( " AddCustomEvent " , " Custom Event... " ) , TEXT ( " " ) , 0 ) ) ;
2014-03-14 14:13:41 -04:00
ActionMenuBuilder . AddAction ( Action , K2ActionCategories : : AddEventCategory ) ;
UK2Node_CustomEvent * CustomEventNode = ActionMenuBuilder . CreateTemplateNode < UK2Node_CustomEvent > ( ) ;
CustomEventNode - > CustomFunctionName = FBlueprintEditorUtils : : FindUniqueCustomEventName ( Blueprint ) ;
CustomEventNode - > bIsEditable = true ;
Action - > NodeTemplate = CustomEventNode ;
2014-04-23 18:30:37 -04:00
Action - > SearchTitle = Action - > NodeTemplate - > GetNodeSearchTitle ( ) ;
2014-03-14 14:13:41 -04:00
}
//------------------------------------------------------------------------------
void FK2ActionMenuBuilder : : GetLiteralsFromActorSelection ( FBlueprintGraphActionListBuilder & ContextMenuBuilder ) const
{
const ULevelScriptBlueprint * LevelBlueprint = CastChecked < ULevelScriptBlueprint > ( ContextMenuBuilder . Blueprint ) ;
check ( LevelBlueprint ) ;
USelection * SelectedActors = GEditor - > GetSelectedActors ( ) ;
TArray < AActor * > ValidActors ;
for ( FSelectionIterator Iter ( * SelectedActors ) ; Iter ; + + Iter )
{
AActor * Actor = Cast < AActor > ( * Iter ) ;
if ( K2Schema - > IsActorValidForLevelScriptRefs ( Actor , LevelBlueprint ) )
{
ValidActors . Add ( Actor ) ;
}
}
if ( ValidActors . Num ( ) )
{
TArray < TSharedPtr < FEdGraphSchemaAction > > NewActions ;
for ( int32 ActorIndex = 0 ; ActorIndex < ValidActors . Num ( ) ; ActorIndex + + )
{
AActor * Actor = ValidActors [ ActorIndex ] ;
UK2Node_Literal * LiteralNodeTemplate = ContextMenuBuilder . CreateTemplateNode < UK2Node_Literal > ( ) ;
LiteralNodeTemplate - > SetObjectRef ( Actor ) ;
const FString Description = ( ValidActors . Num ( ) = = 1 ) ?
FString : : Printf ( * LOCTEXT ( " AddReferenceToActor " , " Add Reference to %s " ) . ToString ( ) , * Actor - > GetActorLabel ( ) ) :
LOCTEXT ( " AddReferencesToSelectedActors " , " Add references to selected actors " ) . ToString ( ) ;
const FString ToolTip = ( ValidActors . Num ( ) = = 1 ) ?
FString : : Printf ( * LOCTEXT ( " AddReferenceToActorToolTip " , " Add a reference to %s " ) . ToString ( ) , * Actor - > GetActorLabel ( ) ) :
LOCTEXT ( " AddReferencesToSelectedActorsToolTip " , " Add references to currently selected actors in the scene " ) . ToString ( ) ;
2014-04-23 18:30:37 -04:00
TSharedPtr < FEdGraphSchemaAction_K2NewNode > Action ( new FEdGraphSchemaAction_K2NewNode ( TEXT ( " " ) , FText : : FromString ( Description ) , ToolTip , K2Schema - > AG_LevelReference ) ) ;
2014-03-14 14:13:41 -04:00
Action - > Keywords = LiteralNodeTemplate - > GetKeywords ( ) ;
Action - > NodeTemplate = LiteralNodeTemplate ;
2014-04-23 18:30:37 -04:00
Action - > SearchTitle = Action - > NodeTemplate - > GetNodeSearchTitle ( ) ;
2014-03-14 14:13:41 -04:00
NewActions . Add ( Action ) ;
}
ContextMenuBuilder . AddActionList ( NewActions ) ;
}
}
//------------------------------------------------------------------------------
void FK2ActionMenuBuilder : : GetBoundEventsFromActorSelection ( FBlueprintGraphActionListBuilder & ContextMenuBuilder ) const
{
const ULevelScriptBlueprint * LevelBlueprint = CastChecked < ULevelScriptBlueprint > ( ContextMenuBuilder . Blueprint ) ;
check ( LevelBlueprint ! = NULL ) ;
USelection * SelectedActors = GEditor - > GetSelectedActors ( ) ;
TArray < AActor * > ValidActors ;
for ( FSelectionIterator Iter ( * SelectedActors ) ; Iter ; + + Iter )
{
// We only care about actors that are referenced in the world for bound events
AActor * Actor = Cast < AActor > ( * Iter ) ;
if ( K2Schema - > IsActorValidForLevelScriptRefs ( Actor , LevelBlueprint ) )
{
ValidActors . Add ( Actor ) ;
}
}
if ( ValidActors . Num ( ) > 0 )
{
UClass * CommonClass = FindMostDerivedCommonActor ( ValidActors ) ;
// If only one actor is selected then we build a different string using that actor's label else we show a generic string
const FString CurrentCategory = ( ValidActors . Num ( ) = = 1 ) ?
K2ActionCategories : : AddEventForPrefix + ValidActors [ 0 ] - > GetActorLabel ( ) :
K2ActionCategories : : AddEventForActorsCategory ;
AddBoundEventActionsForClass ( ContextMenuBuilder , CommonClass , CurrentCategory , ValidActors , NULL ) ;
}
}
//------------------------------------------------------------------------------
void FK2ActionMenuBuilder : : AddBoundEventActionsForClass ( FBlueprintGraphActionListBuilder & ContextMenuBuilder , UClass * BindClass , const FString & CurrentCategory , TArray < AActor * > & Actors , UObjectProperty * ComponentProperty ) const
{
const FString AddString = FString ( TEXT ( " Add " ) ) ;
const FString ViewString = FString ( TEXT ( " View " ) ) ;
check ( Actors . Num ( ) ! = 0 | | ComponentProperty ! = NULL ) ;
for ( TFieldIterator < UProperty > PropertyIt ( BindClass , EFieldIteratorFlags : : IncludeSuper ) ; PropertyIt ; + + PropertyIt )
{
UProperty * Property = * PropertyIt ;
// Check for multicast delegates that we can safely assign
if ( K2Schema - > CanUserKismetAccessVariable ( Property , BindClass , UEdGraphSchema_K2 : : MustBeDelegate ) )
{
if ( UMulticastDelegateProperty * DelegateProperty = Cast < UMulticastDelegateProperty > ( Property ) )
{
FString PropertyTooltip = DelegateProperty - > GetToolTipText ( ) . ToString ( ) ;
if ( PropertyTooltip . IsEmpty ( ) )
{
PropertyTooltip = Property - > GetName ( ) ;
}
// Add on category for delegate property
const FString EventCategory = CurrentCategory + TEXT ( " | " ) + FObjectEditorUtils : : GetCategory ( Property ) ;
if ( ComponentProperty ! = NULL )
{
const UK2Node * EventNode = FKismetEditorUtilities : : FindBoundEventForComponent ( ContextMenuBuilder . Blueprint , DelegateProperty - > GetFName ( ) , ComponentProperty - > GetFName ( ) ) ;
if ( EventNode )
{
2014-04-23 18:30:37 -04:00
TSharedPtr < FEdGraphSchemaAction_K2ViewNode > NewDelegateNode = TSharedPtr < FEdGraphSchemaAction_K2ViewNode > ( new FEdGraphSchemaAction_K2ViewNode ( EventCategory , FText : : FromString ( ViewString + DelegateProperty - > GetName ( ) ) , PropertyTooltip , K2Schema - > AG_LevelReference ) ) ;
2014-03-14 14:13:41 -04:00
NewDelegateNode - > NodePtr = EventNode ;
ContextMenuBuilder . AddAction ( NewDelegateNode ) ;
}
else
{
2014-04-23 18:30:37 -04:00
TSharedPtr < FEdGraphSchemaAction_K2NewNode > NewDelegateNode = TSharedPtr < FEdGraphSchemaAction_K2NewNode > ( new FEdGraphSchemaAction_K2NewNode ( EventCategory , FText : : FromString ( AddString + DelegateProperty - > GetName ( ) ) , PropertyTooltip , K2Schema - > AG_LevelReference ) ) ;
2014-03-14 14:13:41 -04:00
UK2Node_ComponentBoundEvent * NewComponentEvent = ContextMenuBuilder . CreateTemplateNode < UK2Node_ComponentBoundEvent > ( ) ;
NewComponentEvent - > InitializeComponentBoundEventParams ( ComponentProperty , DelegateProperty ) ;
NewDelegateNode - > NodeTemplate = NewComponentEvent ;
2014-04-23 18:30:37 -04:00
NewDelegateNode - > SearchTitle = NewDelegateNode - > NodeTemplate - > GetNodeSearchTitle ( ) ;
2014-03-14 14:13:41 -04:00
ContextMenuBuilder . AddAction ( NewDelegateNode ) ;
}
}
else if ( Actors . Num ( ) > 0 )
{
TArray < TSharedPtr < FEdGraphSchemaAction > > NewActions ;
for ( int32 ActorIndex = 0 ; ActorIndex < Actors . Num ( ) ; ActorIndex + + )
{
const UK2Node * ActorEventNode = FKismetEditorUtilities : : FindBoundEventForActor ( Actors [ ActorIndex ] , DelegateProperty - > GetFName ( ) ) ;
if ( ActorEventNode )
{
2014-04-23 18:30:37 -04:00
TSharedPtr < FEdGraphSchemaAction_K2ViewNode > NewDelegateNode = TSharedPtr < FEdGraphSchemaAction_K2ViewNode > ( new FEdGraphSchemaAction_K2ViewNode ( EventCategory , FText : : FromString ( ViewString + DelegateProperty - > GetName ( ) ) , PropertyTooltip , K2Schema - > AG_LevelReference ) ) ;
2014-03-14 14:13:41 -04:00
NewDelegateNode - > NodePtr = ActorEventNode ;
NewActions . Add ( NewDelegateNode ) ;
}
else
{
2014-04-23 18:30:37 -04:00
TSharedPtr < FEdGraphSchemaAction_K2NewNode > NewDelegateNode = TSharedPtr < FEdGraphSchemaAction_K2NewNode > ( new FEdGraphSchemaAction_K2NewNode ( EventCategory , FText : : FromString ( AddString + DelegateProperty - > GetName ( ) ) , PropertyTooltip , K2Schema - > AG_LevelReference ) ) ;
2014-03-14 14:13:41 -04:00
UK2Node_ActorBoundEvent * NewActorEvent = ContextMenuBuilder . CreateTemplateNode < UK2Node_ActorBoundEvent > ( ) ;
NewActorEvent - > InitializeActorBoundEventParams ( Actors [ ActorIndex ] , DelegateProperty ) ;
NewDelegateNode - > NodeTemplate = NewActorEvent ;
2014-04-23 18:30:37 -04:00
NewDelegateNode - > SearchTitle = NewDelegateNode - > NodeTemplate - > GetNodeSearchTitle ( ) ;
2014-03-14 14:13:41 -04:00
NewActions . Add ( NewDelegateNode ) ;
}
}
ContextMenuBuilder . AddActionList ( NewActions ) ;
}
}
}
}
}
//------------------------------------------------------------------------------
void FK2ActionMenuBuilder : : GetMatineeControllers ( FBlueprintGraphActionListBuilder & ContextMenuBuilder ) const
{
const ULevelScriptBlueprint * LevelBlueprint = CastChecked < ULevelScriptBlueprint > ( ContextMenuBuilder . Blueprint ) ;
ULevel * BlueprintLevel = LevelBlueprint - > GetLevel ( ) ;
check ( BlueprintLevel ! = NULL ) ;
bool bShowForSelected = true ;
TArray < AMatineeActor * > MatineeActors ;
if ( bShowForSelected )
{
// Find selected matinee actors in this level
USelection * SelectedActors = GEditor - > GetSelectedActors ( ) ;
for ( FSelectionIterator Iter ( * SelectedActors ) ; Iter ; + + Iter )
{
AMatineeActor * MatActor = Cast < AMatineeActor > ( * Iter ) ;
if ( MatActor ! = NULL & & ( MatActor - > GetLevel ( ) = = BlueprintLevel ) )
{
MatineeActors . Add ( MatActor ) ;
}
}
}
else
{
// Find all matinee actors in the level
for ( TArray < AActor * > : : TConstIterator LevelActorIterator ( BlueprintLevel - > Actors ) ; LevelActorIterator ; + + LevelActorIterator )
{
AMatineeActor * MatActor = Cast < AMatineeActor > ( * LevelActorIterator ) ;
if ( MatActor ! = NULL )
{
MatineeActors . Add ( MatActor ) ;
}
}
}
// Then remove any for which we already have a MatineeController node
TArray < UK2Node_MatineeController * > ExistingMatineeControllers ;
FBlueprintEditorUtils : : GetAllNodesOfClass ( ContextMenuBuilder . Blueprint , ExistingMatineeControllers ) ;
for ( int32 i = 0 ; i < ExistingMatineeControllers . Num ( ) ; i + + )
{
UK2Node_MatineeController * MatController = ExistingMatineeControllers [ i ] ;
if ( MatController - > MatineeActor ! = NULL )
{
MatineeActors . Remove ( MatController - > MatineeActor ) ;
}
}
// Then offer option for all that remain
for ( int32 i = 0 ; i < MatineeActors . Num ( ) ; i + + )
{
AMatineeActor * MatActor = MatineeActors [ i ] ;
2014-04-23 18:30:37 -04:00
FText Description = FText : : Format ( LOCTEXT ( " AddMatineeControllerForActor " , " Add MatineeController for {actorName} " ) , FText : : FromString ( MatActor - > GetName ( ) ) ) ;
FString ToolTip = FText : : Format ( LOCTEXT ( " AddMatineeControllerForActor_Tooltip " , " Add Matinee controller node for {actorName} " ) , FText : : FromString ( MatActor - > GetName ( ) ) ) . ToString ( ) ;
2014-03-14 14:13:41 -04:00
UK2Node_MatineeController * MatControlNode = ContextMenuBuilder . CreateTemplateNode < UK2Node_MatineeController > ( ) ;
MatControlNode - > MatineeActor = MatActor ;
TSharedPtr < FEdGraphSchemaAction_K2NewNode > Action = FK2ActionMenuBuilder : : AddNewNodeAction ( ContextMenuBuilder , TEXT ( " " ) , Description , ToolTip , K2Schema - > AG_LevelReference , MatControlNode - > GetKeywords ( ) ) ;
Action - > NodeTemplate = MatControlNode ;
2014-04-23 18:30:37 -04:00
Action - > SearchTitle = Action - > NodeTemplate - > GetNodeSearchTitle ( ) ;
2014-03-14 14:13:41 -04:00
}
}
//------------------------------------------------------------------------------
void FK2ActionMenuBuilder : : GetFunctionCallsOnSelectedActors ( FBlueprintGraphActionListBuilder & ContextMenuBuilder ) const
{
const ULevelScriptBlueprint * LevelBlueprint = CastChecked < ULevelScriptBlueprint > ( ContextMenuBuilder . Blueprint ) ;
ULevel * BlueprintLevel = LevelBlueprint - > GetLevel ( ) ;
check ( BlueprintLevel ! = NULL ) ;
USelection * SelectedActors = GEditor - > GetSelectedActors ( ) ;
TArray < AActor * > ValidActors ;
for ( FSelectionIterator Iter ( * SelectedActors ) ; Iter ; + + Iter )
{
AActor * Actor = Cast < AActor > ( * Iter ) ;
if ( Actor ! = NULL & & Actor - > GetLevel ( ) = = BlueprintLevel & & K2Schema - > IsActorValidForLevelScriptRefs ( Actor , LevelBlueprint ) )
{
ValidActors . Add ( Actor ) ;
}
}
if ( ValidActors . Num ( ) )
{
UClass * CommonClass = FindMostDerivedCommonActor ( ValidActors ) ;
// If only one actor is selected then we build a different string using that actor's label else we show a generic string
const FString BaseCategory = ( ValidActors . Num ( ) = = 1 ) ?
K2ActionCategories : : CallFuncOnPrefix + ValidActors [ 0 ] - > GetActorLabel ( ) :
K2ActionCategories : : CallFuncOnActorsCategory ;
GetFuncNodesForClass ( ContextMenuBuilder , CommonClass , NULL , ContextMenuBuilder . CurrentGraph , UEdGraphSchema_K2 : : FT_Imperative | UEdGraphSchema_K2 : : FT_Const , BaseCategory , FFunctionTargetInfo ( ValidActors ) ) ;
}
else
{
FText SelectActorsMsg = LOCTEXT ( " SelectActorForEvents " , " Select Actor(s) to see available Events & Functions " ) ;
FText SelectActorsToolTip = LOCTEXT ( " SelectActorForEventsTooltip " , " Select Actor(s) in the level to see available Events and Functions in this menu. " ) ;
2014-04-23 18:30:37 -04:00
TSharedPtr < FEdGraphSchemaAction_Dummy > MsgAction = TSharedPtr < FEdGraphSchemaAction_Dummy > ( new FEdGraphSchemaAction_Dummy ( TEXT ( " " ) , SelectActorsMsg , SelectActorsToolTip . ToString ( ) , K2Schema - > AG_LevelReference ) ) ;
2014-03-14 14:13:41 -04:00
ContextMenuBuilder . AddAction ( MsgAction ) ;
}
}
//------------------------------------------------------------------------------
void FK2ActionMenuBuilder : : GetBoundEventsFromComponentSelection ( FBlueprintGraphActionListBuilder & ContextMenuBuilder ) const
{
for ( int32 SelectIdx = 0 ; SelectIdx < ContextMenuBuilder . SelectedObjects . Num ( ) ; + + SelectIdx )
{
UObjectProperty * CompProperty = Cast < UObjectProperty > ( ContextMenuBuilder . SelectedObjects [ SelectIdx ] ) ;
if ( CompProperty ! = NULL & &
CompProperty - > PropertyClass ! = NULL & &
CompProperty - > PropertyClass - > IsChildOf ( UActorComponent : : StaticClass ( ) ) )
{
const FString PropertyName = GetDefault < UEditorStyleSettings > ( ) - > bShowFriendlyNames ? UEditorEngine : : GetFriendlyName ( CompProperty ) : CompProperty - > GetName ( ) ;
const FString CurrentCategory = K2ActionCategories : : AddEventForPrefix + PropertyName ;
TArray < AActor * > DummyActorList ;
AddBoundEventActionsForClass ( ContextMenuBuilder , CompProperty - > PropertyClass , CurrentCategory , DummyActorList , CompProperty ) ;
}
}
}
//------------------------------------------------------------------------------
void FK2ActionMenuBuilder : : GetFunctionCallsOnSelectedComponents ( FBlueprintGraphActionListBuilder & ContextMenuBuilder ) const
{
UObjectProperty * SelectedCompProperty = NULL ;
for ( int32 SelectIdx = 0 ; SelectIdx < ContextMenuBuilder . SelectedObjects . Num ( ) ; + + SelectIdx )
{
UObjectProperty * CompProperty = Cast < UObjectProperty > ( ContextMenuBuilder . SelectedObjects [ SelectIdx ] ) ;
if ( CompProperty ! = NULL & &
CompProperty - > PropertyClass ! = NULL & &
CompProperty - > PropertyClass - > IsChildOf ( UActorComponent : : StaticClass ( ) ) )
{
SelectedCompProperty = CompProperty ;
break ;
}
}
if ( SelectedCompProperty ! = NULL )
{
const FString PropertyName = GetDefault < UEditorStyleSettings > ( ) - > bShowFriendlyNames ? UEditorEngine : : GetFriendlyName ( SelectedCompProperty ) : SelectedCompProperty - > GetName ( ) ;
const FString BaseCategory = K2ActionCategories : : CallFuncOnPrefix + PropertyName ;
GetFuncNodesForClass ( ContextMenuBuilder , SelectedCompProperty - > PropertyClass , NULL , ContextMenuBuilder . CurrentGraph , UEdGraphSchema_K2 : : FT_Imperative | UEdGraphSchema_K2 : : FT_Const , BaseCategory , FFunctionTargetInfo ( SelectedCompProperty - > GetFName ( ) ) ) ;
}
else
{
FText SelectComponentMsg = LOCTEXT ( " SelectComponentForEvents " , " Select a Component to see available Events & Functions " ) ;
FText SelectComponentToolTip = LOCTEXT ( " SelectComponentForEventsTooltip " , " Select a Component in the MyBlueprint tab to see available Events and Functions in this menu. " ) ;
2014-04-23 18:30:37 -04:00
TSharedPtr < FEdGraphSchemaAction_Dummy > MsgAction = TSharedPtr < FEdGraphSchemaAction_Dummy > ( new FEdGraphSchemaAction_Dummy ( TEXT ( " " ) , SelectComponentMsg , SelectComponentToolTip . ToString ( ) , K2Schema - > AG_LevelReference ) ) ;
2014-03-14 14:13:41 -04:00
ContextMenuBuilder . AddAction ( MsgAction ) ;
}
}
//------------------------------------------------------------------------------
void FK2ActionMenuBuilder : : GetMacroTools ( FBlueprintPaletteListBuilder & ActionMenuBuilder , const bool bInAllowImpureFuncs , const UEdGraph * InCurrentGraph ) const
{
// Macro instances
for ( TObjectIterator < UBlueprint > BlueprintIt ; BlueprintIt ; + + BlueprintIt )
{
UBlueprint * MacroBP = * BlueprintIt ;
if ( ( ActionMenuBuilder . Blueprint = = MacroBP ) | | //add local Macros
( MacroBP - > BlueprintType = = BPTYPE_MacroLibrary ) & & ( ActionMenuBuilder . Blueprint - > ParentClass - > IsChildOf ( MacroBP - > ParentClass ) ) )
{
for ( TArray < UEdGraph * > : : TIterator GraphIt ( MacroBP - > MacroGraphs ) ; GraphIt ; + + GraphIt )
{
UEdGraph * MacroGraph = * GraphIt ;
//Check whether the current graph is same as the blueprint macro graph that we are trying to add instance of.
//If so, then don't allow adding action menu to instance the macro graph to its own definition.
if ( InCurrentGraph ! = MacroGraph )
{
UK2Node_Tunnel * FunctionEntryNode = NULL ;
UK2Node_Tunnel * FunctionResultNode = NULL ;
bool bIsMacroPure = false ;
FKismetEditorUtilities : : GetInformationOnMacro ( MacroGraph , /*out*/ FunctionEntryNode , /*out*/ FunctionResultNode , /*out*/ bIsMacroPure ) ;
if ( bIsMacroPure | | bInAllowImpureFuncs )
{
FK2ActionMenuBuilder : : AttachMacroGraphAction ( ActionMenuBuilder , MacroGraph ) ;
}
}
}
}
}
}
//------------------------------------------------------------------------------
void FK2ActionMenuBuilder : : GetPinAllowedMacros ( FBlueprintGraphActionListBuilder & ContextMenuBuilder , const UClass * Class , const FEdGraphPinType & DesiredPinType , bool bWantOutputs , bool bAllowImpureMacros ) const
{
// Macro instances
for ( TObjectIterator < UBlueprint > BlueprintIt ; BlueprintIt ; + + BlueprintIt )
{
UBlueprint * MacroBP = * BlueprintIt ;
if ( ( MacroBP = = ContextMenuBuilder . Blueprint ) | | //let local macros be added
( MacroBP - > BlueprintType = = BPTYPE_MacroLibrary ) & & ( ContextMenuBuilder . Blueprint - > ParentClass - > IsChildOf ( MacroBP - > ParentClass ) ) )
{
// getting 'top-level' of the macros
for ( TArray < UEdGraph * > : : TIterator GraphIt ( MacroBP - > MacroGraphs ) ; GraphIt ; + + GraphIt )
{
UEdGraph * MacroGraph = * GraphIt ;
//Check whether the current graph is same as the blueprint macro graph that we are trying to add instance of.
//If so, then don't allow adding action menu to instance the macro graph to its own definition.
if ( ContextMenuBuilder . CurrentGraph ! = MacroGraph )
{
UK2Node_Tunnel * FunctionEntryNode = NULL ;
UK2Node_Tunnel * FunctionResultNode = NULL ;
bool bIsMacroPure = false ;
FKismetEditorUtilities : : GetInformationOnMacro ( MacroGraph , /*out*/ FunctionEntryNode , /*out*/ FunctionResultNode , /*out*/ bIsMacroPure ) ;
bool bCompatible = false ;
UK2Node_Tunnel * FunctionNode = bWantOutputs ? FunctionResultNode : FunctionEntryNode ;
if ( ( FunctionNode ! = NULL ) & & ( bIsMacroPure | | bAllowImpureMacros ) )
{
// Search for matching pin between macro and desired pin
for ( TArray < UEdGraphPin * > : : TIterator PinIterator ( FunctionNode - > Pins ) ; PinIterator ; + + PinIterator )
{
UEdGraphPin * CurrentPin = * PinIterator ;
// Tunnels have all output pins on the entrance, and all input pins on the exit.
// Need to recheck direction for IsChildOf checks to occur correctly.
if ( ! bWantOutputs )
{
// Going from an output to an input pin.
if ( K2Schema - > ArePinTypesCompatible ( DesiredPinType , CurrentPin - > PinType , Class ) )
{
bCompatible = true ;
break ;
}
}
else
{
// Going from an input to an output pin.
if ( K2Schema - > ArePinTypesCompatible ( CurrentPin - > PinType , DesiredPinType , Class ) )
{
bCompatible = true ;
break ;
}
}
}
}
// Pull macro into action menu if its compatible
if ( bCompatible )
{
FK2ActionMenuBuilder : : AttachMacroGraphAction ( ContextMenuBuilder , MacroGraph ) ;
}
}
}
}
}
}
//------------------------------------------------------------------------------
void FK2ActionMenuBuilder : : GetFuncNodesWithPinType ( FBlueprintGraphActionListBuilder & ContextMenuBuilder , const UClass * Class , class UClass * OwnerClass , const FEdGraphPinType & DesiredPinType , bool bWantOutput , bool bPureOnly ) const
{
if ( Class ! = NULL )
{
UBlueprint * ClassBlueprint = UBlueprint : : GetBlueprintFromClass ( OwnerClass ) ;
static const FName NativeMakeFunc ( TEXT ( " NativeMakeFunc " ) ) ;
static const FName NativeBrakeFunc ( TEXT ( " NativeBreakFunc " ) ) ;
static const FName HasNativeMakeBreak ( TEXT ( " HasNativeMakeBreak " ) ) ;
const UScriptStruct * ScriptStruct = Cast < const UScriptStruct > ( DesiredPinType . PinSubCategoryObject . Get ( ) ) ;
const bool bStructWithNativeBrakeAndMake = ScriptStruct & & ScriptStruct - > GetBoolMetaData ( HasNativeMakeBreak ) ;
const bool bUseNativeMake = bStructWithNativeBrakeAndMake & & bWantOutput ;
const bool bUseNativeBrake = bStructWithNativeBrakeAndMake & & ! bWantOutput ;
for ( TFieldIterator < UFunction > FunctionIt ( Class , EFieldIteratorFlags : : IncludeSuper ) ; FunctionIt ; + + FunctionIt )
{
UFunction * Function = * FunctionIt ;
if ( K2Schema - > CanUserKismetCallFunction ( Function ) )
{
if ( ( false = = bPureOnly | | Function - > HasAnyFunctionFlags ( FUNC_BlueprintPure ) ) & &
K2Schema - > FunctionHasParamOfType ( Function , ClassBlueprint , DesiredPinType , bWantOutput ) )
{
const bool bShowMakeOnTop = bUseNativeMake & & Function - > HasMetaData ( NativeMakeFunc ) ;
const bool bShowBrakeOnTop = bUseNativeBrake & & Function - > HasMetaData ( NativeBrakeFunc ) ;
FK2ActionMenuBuilder : : AddSpawnInfoForFunction ( Function , false , FFunctionTargetInfo ( ) , FMemberReference ( ) , K2ActionCategories : : GenericFunctionCategory , K2Schema - > AG_LevelReference , ContextMenuBuilder , false , bShowMakeOnTop | | bShowBrakeOnTop ) ;
}
}
}
}
else
{
// Try each function library for functions matching the criteria
for ( TObjectIterator < UClass > ClassIt ; ClassIt ; + + ClassIt )
{
UClass * TestClass = * ClassIt ;
2014-05-05 01:38:12 -04:00
const bool bIsSkeletonClass = FKismetEditorUtilities : : IsClassABlueprintSkeleton ( TestClass ) ;
2014-03-14 14:13:41 -04:00
if ( TestClass - > IsChildOf ( UBlueprintFunctionLibrary : : StaticClass ( ) ) & &
2014-04-23 18:41:30 -04:00
CanUseLibraryFunctionsForScope ( OwnerClass , TestClass ) & & ! bIsSkeletonClass )
2014-03-14 14:13:41 -04:00
{
GetFuncNodesWithPinType ( ContextMenuBuilder , TestClass , OwnerClass , DesiredPinType , bWantOutput , bPureOnly ) ;
}
}
}
}
//------------------------------------------------------------------------------
void FK2ActionMenuBuilder : : GetAllInterfaceMessageActions ( FGraphActionListBuilderBase & ActionMenuBuilder ) const
{
// Add interface classes if relevant
for ( TObjectIterator < UClass > it ; it ; + + it )
{
UClass * CurrentInterface = * it ;
if ( FKismetEditorUtilities : : IsClassABlueprintInterface ( CurrentInterface ) & & ! FKismetEditorUtilities : : IsClassABlueprintSkeleton ( CurrentInterface ) )
{
for ( TFieldIterator < UFunction > FunctionIt ( CurrentInterface , EFieldIteratorFlags : : ExcludeSuper ) ; FunctionIt ; + + FunctionIt )
{
UFunction * Function = * FunctionIt ;
if ( K2Schema - > CanUserKismetCallFunction ( Function ) )
{
FString MessageCategory = UK2Node_CallFunction : : GetDefaultCategoryForFunction ( Function , TEXT ( " " ) ) ;
if ( MessageCategory . IsEmpty ( ) )
{
MessageCategory = K2ActionCategories : : FallbackInterfaceCategory ;
}
UK2Node_Message * MessageTemplate = ActionMenuBuilder . CreateTemplateNode < UK2Node_Message > ( ) ;
MessageTemplate - > FunctionReference . SetExternalMember ( Function - > GetFName ( ) , CurrentInterface ) ;
2014-04-23 18:30:37 -04:00
TSharedPtr < FEdGraphSchemaAction_K2NewNode > Action = FK2ActionMenuBuilder : : AddNewNodeAction ( ActionMenuBuilder , MessageCategory , FText : : FromString ( Function - > GetName ( ) ) , MessageTemplate - > GetTooltip ( ) , 0 , MessageTemplate - > GetKeywords ( ) ) ;
2014-03-14 14:13:41 -04:00
Action - > NodeTemplate = MessageTemplate ;
2014-04-23 18:30:37 -04:00
Action - > SearchTitle = Action - > NodeTemplate - > GetNodeSearchTitle ( ) ;
2014-03-14 14:13:41 -04:00
}
}
}
}
}
# undef LOCTEXT_NAMESPACE