Advertisement
MortaL

Untitled

Dec 19th, 2017
143
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include "SagaEditor.h"
  2. #include "UObject/UnrealType.h"
  3. #include "EdGraph/EdGraphPin.h"
  4. #include "Kismet/KismetSystemLibrary.h"
  5. #include "EdGraphSchema_K2.h"
  6. #include "K2Node_CallFunction.h"
  7. #include "K2Node_AssignmentStatement.h"
  8. #include "K2Node_CustomEvent.h"
  9. #include "K2Node_TemporaryVariable.h"
  10. #include "KismetCompiler.h"
  11. #include "BlueprintNodeSpawner.h"
  12. #include "BlueprintActionDatabaseRegistrar.h"
  13. #include "K2Node_Await.h"
  14. #include "Network/WarholdNetworkClasses.h"
  15. #include "K2Node_GetDataTableRow.h"
  16. #include "Network/UE4App.h"
  17. #include "BlueprintEditorUtils.h"
  18. #include "SGraphNode.h"
  19. #include "ContentBrowserModule.h"
  20. #include "Private/SAssetDialog.h"
  21. #include "GraphEditorSettings.h"
  22.  
  23. #define LOCTEXT_NAMESPACE "K2Node_WN"
  24.  
  25. void UK2Node_WN_Await::AllocateDefaultPins()
  26. {
  27.     const UEdGraphSchema_K2* K2Schema = Cast<UEdGraphSchema_K2>(GetSchema());
  28.  
  29.     CachedFunctionName = TEXT("...");
  30.  
  31.     if (K2Schema)
  32.     {
  33.         CreatePin(EGPD_Input, K2Schema->PC_Exec, TEXT(""), nullptr, false, false, K2Schema->PN_Execute);
  34.         UEdGraphPin* OutputExecPin = CreatePin(EGPD_Output, K2Schema->PC_Exec, TEXT(""), nullptr, false, false, K2Schema->PN_Then);
  35.         if (OutputExecPin)
  36.         {
  37.             OutputExecPin->PinFriendlyName = FText::FromString(K2Schema->PN_Completed);
  38.         }
  39.  
  40.         CreatePin(EGPD_Input, K2Schema->PC_Object, TEXT(""), UMailbox::StaticClass(), false, false, TEXT("Target"), false, INDEX_NONE, false, false);
  41.     }
  42. }
  43.  
  44. void UK2Node_WN_Await::ReallocatePinsDuringReconstruction(TArray<UEdGraphPin*>& OldPins)
  45. {
  46.     AllocateDefaultPins();
  47.  
  48.     ConstructMethodPinByMailbox(&OldPins);
  49.     MailboxPinChanged(&OldPins);
  50.  
  51.     RestoreSplitPins(OldPins);
  52. }
  53.  
  54. void UK2Node_WN_Await::PinConnectionListChanged(UEdGraphPin* Pin)
  55. {
  56.     Super::PinConnectionListChanged(Pin);
  57.  
  58.     if (Pin->PinName == TEXT("Target"))
  59.     {
  60.         MailboxPinChanged();
  61.  
  62.         // Refresh the UI for the graph so the pin changes show up
  63.         GetGraph()->NotifyGraphChanged();
  64.        
  65.         // Mark dirty
  66.         FBlueprintEditorUtils::MarkBlueprintAsModified(GetBlueprint());
  67.     }
  68. }
  69.  
  70.  
  71. UEdGraphPin* UK2Node_WN_Await::GetPinSpecified(FString PinName, TArray<UEdGraphPin*>* OldPins)
  72. {
  73.     if (OldPins != nullptr)
  74.         for (auto& pin : *OldPins)
  75.             if (pin->PinName == PinName)
  76.                 return pin;
  77.     return FindPin(PinName);
  78. }
  79.  
  80. UClass* UK2Node_WN_Await::GetMailboxClass(TArray<UEdGraphPin*>* OldPins)
  81. {
  82.     UEdGraphPin* target_pin = GetPinSpecified("Target", OldPins);
  83.  
  84.     UClass* MailboxClass = nullptr;
  85.  
  86.     if (target_pin && target_pin->DefaultObject && target_pin->LinkedTo.Num() == 0)
  87.     {
  88.         MailboxClass = Cast<UClass>(target_pin->DefaultObject);
  89.     }
  90.     else if (target_pin && target_pin->LinkedTo.Num())
  91.     {
  92.         UEdGraphPin* ClassSource = target_pin->LinkedTo[0];
  93.         MailboxClass = ClassSource ? Cast<UClass>(ClassSource->PinType.PinSubCategoryObject.Get()) : nullptr;
  94.     }
  95.  
  96.     return MailboxClass;
  97. }
  98.  
  99. UEdGraphPin* UK2Node_WN_Await::ConstructMethodPinByMailbox(TArray<UEdGraphPin*>* OldPins, bool bRemovePrevious)
  100. {
  101.     CachedMailboxName = TEXT("");
  102.  
  103.     const UEdGraphSchema_K2* K2Schema = Cast<UEdGraphSchema_K2>(GetSchema());
  104.  
  105.     UEdGraphPin* method_pin = nullptr;
  106.  
  107.     if (K2Schema)
  108.     {
  109.         UClass* MailboxClass = GetMailboxClass(OldPins);
  110.        
  111.         if (!MailboxClass)
  112.             CachedFunctionName = TEXT("...");
  113.  
  114.         MailboxFunctionNames.Empty();
  115.         if (MailboxClass)
  116.         {
  117.  
  118.             CachedMailboxName = MailboxClass->GetName();
  119.             for (auto func : TFieldRange<UFunction>(MailboxClass))
  120.             {
  121.                 if (func->FunctionFlags & FUNC_BlueprintCallable)
  122.                     if (auto ret_property = Cast<UObjectPropertyBase>(func->GetReturnProperty()))
  123.                     {
  124.                         if (ret_property->PropertyClass && ret_property->PropertyClass->IsChildOf<UFuture>())
  125.                         {
  126.                             MailboxFunctionNames.Add(*func->GetName());
  127.                         }
  128.                     }
  129.             }
  130.         }
  131.  
  132.         method_pin = GetPinSpecified(TEXT("Method"), OldPins);
  133.  
  134.         if (bRemovePrevious && method_pin && OldPins == nullptr)
  135.             RemovePin(method_pin);
  136.  
  137.         if (MailboxClass && MailboxClass != UMailbox::StaticClass() && method_pin == nullptr)
  138.             method_pin = CreatePin(EGPD_Input, K2Schema->PC_Name, TEXT(""), nullptr, false, false, TEXT("Method"), false, INDEX_NONE, false, false);
  139.  
  140.         if (method_pin)
  141.             method_pin->bHidden = false;
  142.     }
  143.  
  144.     return method_pin;
  145. }
  146.  
  147. void UK2Node_WN_Await::MailboxPinChanged(TArray<UEdGraphPin*>* OldPins)
  148. {
  149.  
  150.     const UEdGraphSchema_K2* K2Schema = Cast<UEdGraphSchema_K2>(GetSchema());
  151.  
  152.     if (K2Schema)
  153.     {
  154.         UClass* MailboxClass = GetMailboxClass(OldPins);
  155.  
  156.         UFunction* func = nullptr;
  157.  
  158.         UEdGraphPin* method_pin = ConstructMethodPinByMailbox(OldPins, MailboxClass != CurrentMailboxClass || MailboxClass == nullptr);
  159.  
  160.         if (MailboxClass)
  161.             func = GetMailboxFunction(MailboxClass, *method_pin->DefaultValue);
  162.  
  163.  
  164.         if (func != CurrentFunction || MailboxClass != CurrentMailboxClass || func == nullptr || MailboxClass == nullptr)
  165.         {
  166.             // Clears all previous pins
  167.             for (auto pin : CachedPins)
  168.                 RemovePin(pin);
  169.             CachedPins.Empty();
  170.  
  171.             CurrentFunction = func;
  172.             CurrentMailboxClass = MailboxClass;
  173.         } else
  174.         {
  175.             return;
  176.         }
  177.  
  178.         CachedMailboxName = TEXT("");
  179.  
  180.         if (MailboxClass)
  181.         {
  182.             CachedMailboxName = MailboxClass->GetName();
  183.  
  184.             method_pin->bHidden = false;
  185.  
  186.             if (func)
  187.             {
  188.                 CachedFunctionName = method_pin->DefaultValue;
  189.                 const UObject* const ClassDefaultObject = MailboxClass->GetDefaultObject(false);
  190.  
  191.                 UObjectPropertyBase* ReturnProperty = Cast<UObjectPropertyBase>(func->GetReturnProperty());
  192.  
  193.                 const TArray<UEdGraphPin*> in_pins = GeneratePinsForAsyncFunction(func, EGPD_Input);
  194.                 CachedPins.Append(in_pins);
  195.  
  196.                 if (ReturnProperty)
  197.                 {
  198.                     UFunction* exec_func_return = ReturnProperty->PropertyClass->FindFunctionByName(TEXT("Execute"));
  199.                     const TArray<UEdGraphPin*> out_pins = GeneratePinsForAsyncFunction(exec_func_return, EGPD_Output);
  200.                     CachedPins.Append(out_pins);
  201.                 }
  202.  
  203.             }
  204.             else
  205.             {
  206.  
  207.                 CachedFunctionName = TEXT("...");
  208.             }
  209.         }
  210.     }
  211. }
  212.  
  213. UFunction* UK2Node_WN_Await::GetMailboxFunction(UClass* MailboxClass, FName FunctionName)
  214. {
  215.     if (MailboxClass)
  216.         for (auto func : TFieldRange<UFunction>(MailboxClass))
  217.             if (func->FunctionFlags & FUNC_BlueprintCallable)
  218.                 if (auto ret_property = Cast<UObjectPropertyBase>(func->GetReturnProperty()))
  219.                     if (ret_property->PropertyClass && ret_property->PropertyClass->IsChildOf<UFuture>())
  220.                         if (func->GetName() == FunctionName.ToString())
  221.                             return func;
  222.     return nullptr;
  223. }
  224.  
  225. TArray<UEdGraphPin*> UK2Node_WN_Await::GeneratePinsForAsyncFunction(UFunction* func, EEdGraphPinDirection direction)
  226. {
  227.     TArray<UEdGraphPin*> OutPins;
  228.     const UEdGraphSchema_K2* K2Schema = Cast<UEdGraphSchema_K2>(GetSchema());
  229.     if (K2Schema && func)
  230.     {
  231.         UProperty* ReturnProperty = func->GetReturnProperty();
  232.         for (TFieldIterator<UProperty> PropertyIt(func, EFieldIteratorFlags::IncludeSuper); PropertyIt; ++PropertyIt)
  233.         {
  234.             UProperty* Property = *PropertyIt;
  235.             if (*PropertyIt != ReturnProperty)
  236.                 if (FBlueprintEditorUtils::PropertyStillExists(Property))
  237.                     if (UEdGraphPin* Pin = CreatePin(direction, FString(), FString(), nullptr, Property->GetName()))
  238.                     {
  239.                         K2Schema->ConvertPropertyToPinType(Property, /*out*/ Pin->PinType);
  240.                         OutPins.Add(Pin);
  241.                     }
  242.         }
  243.     }
  244.     return OutPins;
  245. }
  246.  
  247. void UK2Node_WN_Await::ExpandNode(class FKismetCompilerContext& CompilerContext, UEdGraph* SourceGraph)
  248. {
  249.     Super::ExpandNode(CompilerContext, SourceGraph);
  250.  
  251.     // TODO: Currently turned off due to reorganization of node from generated to customizable!
  252.  
  253.     //const UEdGraphSchema_K2* Schema = CompilerContext.GetSchema();
  254.     //check(Schema);
  255.     //bool bIsErrorFree = true;
  256.     //const UEdGraphSchema_K2* K2Schema = Cast<UEdGraphSchema_K2>(GetSchema());
  257.     //// Create intermediate function call
  258.     //auto CallIntermediateFunctionNode = CompilerContext.SpawnIntermediateNode<UK2Node_CallFunction>(this, SourceGraph);
  259.     //CallIntermediateFunctionNode->FunctionReference.SetExternalMember(NativeFunctionName(), GetTargetClass());
  260.     //CallIntermediateFunctionNode->AllocateDefaultPins();
  261.     //
  262.     //TArray<FString> retvals;
  263.     //TMap<FString, UObject*> retclasses;
  264.     //TMap<FString, bool> ret_bisarrays;
  265.     //
  266.     //
  267.     //retvals.Add(TEXT("RetVal1"));
  268.     //retclasses.Add(TEXT("RetVal1"), USessionBaseMailbox::StaticClass());
  269.     //ret_bisarrays.Add(TEXT("RetVal1"), false);
  270.     //
  271.     //retvals.Add(TEXT("RetVal2"));
  272.     //retclasses.Add(TEXT("RetVal2"), FindObject<UEnum>(ANY_PACKAGE, TEXT("ELoginResult"), true));
  273.     //ret_bisarrays.Add(TEXT("RetVal2"), false);
  274.     //
  275.     //retvals.Add(TEXT("RetVal3"));
  276.     //retclasses.Add(TEXT("RetVal3"), nullptr);
  277.     //ret_bisarrays.Add(TEXT("RetVal3"), false);
  278.     //
  279.     //
  280.     //
  281.     //TArray<FString> connectors;
  282.     //
  283.     //connectors.Add(TEXT("username"));
  284.     //connectors.Add(TEXT("password"));
  285.     //
  286.     //
  287.     //
  288.     //// connect to input exe
  289.     //{
  290.     //  auto InputExePin = GetExecPin();
  291.     //  auto CallFunctionInputExePin = CallIntermediateFunctionNode->GetExecPin();
  292.     //  bIsErrorFree &= InputExePin && CallFunctionInputExePin && CompilerContext.MovePinLinksToIntermediate(*InputExePin, *CallFunctionInputExePin).CanSafeConnect();
  293.     //}
  294.     //
  295.     //TMap<FString, UK2Node_AssignmentStatement*> assignment_nodes_by_name;
  296.     //TArray<UK2Node_AssignmentStatement*>  assignment_nodes;
  297.     ///// RetVals assignment section
  298.     //
  299.     //for (auto& retval_name : retvals)
  300.     //{
  301.     //  // Create Local Variable (for RetVal1)
  302.     //  auto PinCategory = FindPin(retval_name)->PinType.PinCategory;
  303.     //  // TODO: Old: // UK2Node_TemporaryVariable* TempVarOutput = CompilerContext.SpawnInternalVariable(this, PinCategory, FString(""), retclasses[retval_name], ret_bisarrays[retval_name]);
  304.     //    UK2Node_TemporaryVariable* TempVarOutput = CompilerContext.SpawnInternalVariable(this, PinCategory, FString(""), retclasses[retval_name], FEdGraphPinType::ToPinContainerType(ret_bisarrays[retval_name], false, false));
  305.     //
  306.     //  // Create assign node (for RetVal1)
  307.     //  UK2Node_AssignmentStatement* AssignNode = CompilerContext.SpawnIntermediateNode<UK2Node_AssignmentStatement>(this, SourceGraph);
  308.     //  assignment_nodes_by_name.Add(retval_name, AssignNode);
  309.     //  assignment_nodes.Add(AssignNode);
  310.     //
  311.     //  AssignNode->AllocateDefaultPins();
  312.     //
  313.     //
  314.     //  auto RetVal_VariablePin = TempVarOutput->GetVariablePin();
  315.     //
  316.     //  // connect local variable (for RetVal1) to assign node
  317.     //  auto AssignLHSPPin = AssignNode->GetVariablePin();
  318.     //  bIsErrorFree &= AssignLHSPPin && RetVal_VariablePin && Schema->TryCreateConnection(AssignLHSPPin, RetVal_VariablePin);
  319.     //
  320.     //  // connect local variable (for RetVal1) to output
  321.     //  auto OutputObjectPinPin = FindPin(retval_name);
  322.     //  bIsErrorFree &= RetVal_VariablePin && OutputObjectPinPin && CompilerContext.MovePinLinksToIntermediate(*OutputObjectPinPin, *RetVal_VariablePin).CanSafeConnect();
  323.     //}
  324.     //
  325.     //auto SchemaThen = FindPin(Schema->PN_Then);
  326.     //auto FirstPin = CallIntermediateFunctionNode->FindPin(Schema->PN_Then);
  327.     //auto LastPin = SchemaThen;
  328.     //
  329.     //for (int32 i = 0; i < assignment_nodes.Num(); i++)
  330.     //{
  331.     //  auto AssignNode = assignment_nodes[i];
  332.     //
  333.     //  UEdGraphPin* PrevPin = (i == 0)                             ? FirstPin : assignment_nodes[i - 1]->GetThenPin();
  334.     //  UEdGraphPin* NextPin = (i == assignment_nodes.Num() - 1)    ? LastPin  : assignment_nodes[i + 1]->GetThenPin();
  335.     //
  336.     //  // connect assign (for RetVal1) exec input to function output
  337.     //  auto AssignInputExePin = AssignNode->GetExecPin();
  338.     //  bIsErrorFree &= AssignInputExePin && PrevPin && Schema->TryCreateConnection(AssignInputExePin, PrevPin);
  339.     //
  340.     //  // auto AssignOutputExePin = AssignNode->GetThenPin();
  341.     //  // bIsErrorFree &= NextPin && AssignOutputExePin && Schema->TryCreateConnection(NextPin, AssignOutputExePin);
  342.     //  if (i == assignment_nodes.Num() - 1)
  343.     //  {
  344.     //      auto AssignInputThenPin = AssignNode->GetThenPin();
  345.     //      bIsErrorFree &= AssignInputThenPin && LastPin && CompilerContext.MovePinLinksToIntermediate(*LastPin, *AssignInputThenPin).CanSafeConnect();
  346.     //  }
  347.     //
  348.     //}
  349.     //
  350.     //
  351.     //
  352.     //
  353.     ///// END OF assignment sections
  354.     //
  355.     //
  356.     //// connect to Target
  357.     //auto CallIntermediateFunctionNodePin = CallIntermediateFunctionNode->FindPin(TEXT("Target"));
  358.     //{
  359.     //  auto TargetPin = FindPin(TEXT("Target"));
  360.     //  ensure(CallIntermediateFunctionNodePin);
  361.     //  bIsErrorFree &= TargetPin && CallIntermediateFunctionNodePin && CompilerContext.MovePinLinksToIntermediate(*TargetPin, *CallIntermediateFunctionNodePin).CanSafeConnect();
  362.     //}
  363.     //
  364.     //// Iterate over all named parameters
  365.     //for (auto& connector : connectors)
  366.     //{
  367.     //  auto IntermediatePin = CallIntermediateFunctionNode->FindPin(connector);
  368.     //  auto Pin = FindPin(connector);
  369.     //  ensure(IntermediatePin);
  370.     //  bIsErrorFree &= Pin && IntermediatePin && CompilerContext.MovePinLinksToIntermediate(*Pin, *IntermediatePin).CanSafeConnect();
  371.     //}
  372.     //
  373.     //// Create OnLoadEvent
  374.     //const FString DelegateOnLoadedParamName(TEXT("OnDone"));
  375.     //auto OnDoneEventNode = CompilerContext.SpawnIntermediateEventNode<UK2Node_CustomEvent>(this, CallIntermediateFunctionNodePin, SourceGraph);
  376.     //OnDoneEventNode->CustomFunctionName = *FString::Printf(TEXT("OnDone_%s"), *CompilerContext.GetGuid(this));
  377.     //OnDoneEventNode->AllocateDefaultPins();
  378.     //{
  379.     //  UFunction* LoadAssetFunction = CallIntermediateFunctionNode->GetTargetFunction();
  380.     //  UDelegateProperty* OnLoadDelegateProperty = LoadAssetFunction ? FindField<UDelegateProperty>(LoadAssetFunction, *DelegateOnLoadedParamName) : nullptr;
  381.     //  UFunction* OnLoadedSignature = OnLoadDelegateProperty ? OnLoadDelegateProperty->SignatureFunction : nullptr;
  382.     //  ensure(OnLoadedSignature);
  383.     //  for (TFieldIterator<UProperty> PropIt(OnLoadedSignature); PropIt && (PropIt->PropertyFlags & CPF_Parm); ++PropIt)
  384.     //  {
  385.     //      const UProperty* Param = *PropIt;
  386.     //      if (!Param->HasAnyPropertyFlags(CPF_OutParm) || Param->HasAnyPropertyFlags(CPF_ReferenceParm))
  387.     //      {
  388.     //          FEdGraphPinType PinType;
  389.     //          bIsErrorFree &= Schema->ConvertPropertyToPinType(Param, /*out*/ PinType);
  390.     //          bIsErrorFree &= (NULL != OnDoneEventNode->CreateUserDefinedPin(Param->GetName(), PinType, EGPD_Output));
  391.     //      }
  392.     //  }
  393.     //}
  394.     //
  395.     //// connect delegate
  396.     //{
  397.     //  auto CallFunctionDelegatePin = CallIntermediateFunctionNode->FindPin(DelegateOnLoadedParamName);
  398.     //  ensure(CallFunctionDelegatePin);
  399.     //  auto EventDelegatePin = OnDoneEventNode->FindPin(UK2Node_CustomEvent::DelegateOutputName);
  400.     //  bIsErrorFree &= CallFunctionDelegatePin && EventDelegatePin && Schema->TryCreateConnection(CallFunctionDelegatePin, EventDelegatePin);
  401.     //}
  402.     //
  403.     //// connect loaded object from event to assign
  404.     //for (auto& pair : assignment_nodes_by_name)
  405.     //{
  406.     //  auto RetValEventPin = OnDoneEventNode->FindPin(pair.Key);
  407.     //  ensure(RetValEventPin);
  408.     //  auto AssignRHSPPin = pair.Value->GetValuePin();
  409.     //  bIsErrorFree &= AssignRHSPPin && RetValEventPin && Schema->TryCreateConnection(RetValEventPin, AssignRHSPPin);
  410.     //}
  411.     //
  412.     //if (!bIsErrorFree)
  413.     //{
  414.     //  CompilerContext.MessageLog.Error(*LOCTEXT("InternalConnectionError", "K2Node_WN_K2Node_BaseApp_login_LatentFunction: Internal connection error. @@").ToString(), this);
  415.     //}
  416.     //
  417.     BreakAllNodeLinks();
  418. }
  419.  
  420. FText UK2Node_WN_Await::GetTooltipText() const
  421. {
  422.     return FText::Format(LOCTEXT("Await::GetTooltipText", "await {0}:{1}"), FText::FromString(CachedMailboxName), FText::FromString(CachedFunctionName));
  423. }
  424.  
  425. void UK2Node_WN_Await::PinDefaultValueChanged(UEdGraphPin* Pin)
  426. {
  427.     if (Pin->PinName == TEXT("Method"))
  428.     {
  429.         MailboxPinChanged();
  430.  
  431.         // Refresh the UI for the graph so the pin changes show up
  432.         GetGraph()->NotifyGraphChanged();
  433.  
  434.         // Mark dirty
  435.         FBlueprintEditorUtils::MarkBlueprintAsModified(GetBlueprint());
  436.     }
  437. }
  438.  
  439. FText UK2Node_WN_Await::GetNodeTitle(ENodeTitleType::Type TitleType) const
  440. {
  441.     return FText::Format(LOCTEXT("Await::GetNodeTitle", "await {0}"), FText::FromString(CachedFunctionName));
  442. }
  443.  
  444. bool UK2Node_WN_Await::IsCompatibleWithGraph(const UEdGraph* TargetGraph) const
  445. {
  446.     bool bIsCompatible = false;
  447.     // Can only place events in ubergraphs and macros (other code will help prevent macros with latents from ending up in functions), and basicasync task creates an event node:
  448.     EGraphType GraphType = TargetGraph->GetSchema()->GetGraphType(TargetGraph);
  449.     if (GraphType == EGraphType::GT_Ubergraph || GraphType == EGraphType::GT_Macro)
  450.     {
  451.         bIsCompatible = true;
  452.     }
  453.     return bIsCompatible && Super::IsCompatibleWithGraph(TargetGraph);
  454. }
  455.  
  456. FLinearColor UK2Node_WN_Await::GetNodeTitleColor() const
  457. {
  458.     return FLinearColor(1.f, 0.3, 0.3, 1.f);
  459. }
  460.  
  461. FName UK2Node_WN_Await::GetCornerIcon() const
  462. {
  463.     return TEXT("Graph.Latent.LatentIcon");
  464. }
  465.  
  466. void UK2Node_WN_Await::GetMenuActions(FBlueprintActionDatabaseRegistrar& ActionRegistrar) const
  467. {
  468.     // actions get registered under specific object-keys; the idea is that
  469.     // actions might have to be updated (or deleted) if their object-key is
  470.     // mutated (or removed)... here we use the node's class (so if the node
  471.     // type disappears, then the action should go with it)
  472.     UClass* ActionKey = GetClass();
  473.     // to keep from needlessly instantiating a UBlueprintNodeSpawner, first
  474.     // check to make sure that the registrar is looking for actions of this type
  475.     // (could be regenerating actions for a specific asset, and therefore the
  476.     // registrar would only accept actions corresponding to that asset)
  477.     if (ActionRegistrar.IsOpenForRegistration(ActionKey))
  478.     {
  479.         UBlueprintNodeSpawner* NodeSpawner = UBlueprintNodeSpawner::Create(GetClass());
  480.         check(NodeSpawner != nullptr);
  481.  
  482.         ActionRegistrar.AddBlueprintAction(ActionKey, NodeSpawner);
  483.     }
  484. }
  485.  
  486. FText UK2Node_WN_Await::GetMenuCategory() const
  487. {
  488.     return FText(LOCTEXT("Await", "Utilities"));
  489. }
  490.  
  491. TSharedPtr<SGraphNode> UK2Node_WN_Await::CreateVisualWidget()
  492. {
  493.  
  494.     return SNew(SK2Node_MethodsDropdown, this);
  495. }
  496.  
  497.  
  498.  
  499.  
  500. const UEdGraphSchema_K2* UK2Node_WN_Await::GetK2Schema()
  501. {
  502.     return CastChecked<UEdGraphSchema_K2>(GetSchema());
  503. }
  504.  
  505. /// SK2Node_MethodsDropdown
  506.  
  507. SK2Node_MethodsDropdown::FArguments::FArguments()
  508. {
  509.    
  510. }
  511.  
  512.  
  513. void SK2Node_MethodsDropdown::Construct(const FArguments& InArgs, UK2Node_WN_Await* InNode)
  514. {
  515.     GraphNode = InNode;
  516.     Names = InNode->MailboxFunctionNames;
  517.     CurrentIcon = FSlateIcon();
  518.     UpdateGraphNode();
  519. }
  520.  
  521. void SK2Node_MethodsDropdown::CreateStandardPinWidget(UEdGraphPin* Pin)
  522. {
  523.     if (Pin->PinName == "Method")
  524.     {
  525.         CreateDetailsPickers();
  526.     }
  527.     else
  528.     {
  529.         SGraphNode::CreateStandardPinWidget(Pin);
  530.     }
  531. }
  532.  
  533. TSharedRef<SWidget> SK2Node_MethodsDropdown::GetPickerMenu()
  534. {
  535.     // Close self only to enable use inside context menus
  536.     FMenuBuilder MenuBuilder(true, nullptr, nullptr, true);
  537.  
  538.  
  539.     FSlateIcon Icon;
  540.  
  541.     for (auto name : Names)
  542.     {
  543.         MenuBuilder.AddMenuEntry(
  544.             FText::FromName(name),
  545.             FText(),
  546.             Icon,
  547.             FUIAction(
  548.                 FExecuteAction::CreateRaw(this, &SK2Node_MethodsDropdown::SetMethodName, name)
  549.             )
  550.         );
  551.     }
  552.  
  553.  
  554.     return MenuBuilder.MakeWidget();
  555. }
  556.  
  557. void SK2Node_MethodsDropdown::OnAssetSelectedFromPicker(const FAssetData& AssetData)
  558. {
  559.     UpdateGraphNode();
  560. }
  561.  
  562. FText SK2Node_MethodsDropdown::GetAssetName() const
  563. {
  564.     return FText();
  565. }
  566.  
  567. void SK2Node_MethodsDropdown::CreateDetailsPickers()
  568. {
  569.     LeftNodeBox->AddSlot()
  570.                .AutoHeight()
  571.                .HAlign(HAlign_Left)
  572.                .VAlign(VAlign_Center)
  573.                .Padding(Settings->GetInputPinPadding())
  574.     [
  575.         SNew(SBox)
  576.         .MaxDesiredWidth(200.0f)
  577.         .Padding(FMargin(2, 0))
  578.         [
  579.             SNew(SComboButton)
  580.             .ButtonStyle(FEditorStyle::Get(), "PropertyEditor.AssetComboStyle")
  581.             // .ToolTipText(this, &SGraphNodeGetSequenceBinding::GetToolTipText)
  582.             .ForegroundColor(this, &SK2Node_MethodsDropdown::OnGetComboForeground)
  583.             .ButtonColorAndOpacity(this, &SK2Node_MethodsDropdown::OnGetWidgetBackground)
  584.             .ContentPadding(FMargin(2, 2, 2, 1))
  585.             .MenuPlacement(MenuPlacement_BelowAnchor)
  586.             .ButtonContent()
  587.             [
  588.                 ///
  589.                 GetCurrentItemWidget(
  590.                     SNew(STextBlock)
  591.                     .TextStyle(FEditorStyle::Get(), "PropertyEditor.AssetClass")
  592.                     .Font(FEditorStyle::GetFontStyle("PropertyWindow.NormalFont"))
  593.                 )
  594.                 ///
  595.             ]
  596.             .OnGetMenuContent(this, &SK2Node_MethodsDropdown::GetPickerMenu)
  597.         ]
  598.     ];
  599. }
  600.  
  601. TSharedRef<SWidget> SK2Node_MethodsDropdown::GetCurrentItemWidget(TSharedRef<STextBlock> TextContent)
  602. {
  603.     TextContent->SetText(TAttribute<FText>::Create(TAttribute<FText>::FGetter::CreateRaw(this, &SK2Node_MethodsDropdown::GetCurrentText)));
  604.  
  605.     return SNew(SHorizontalBox)
  606.         + SHorizontalBox::Slot()
  607.         .AutoWidth()
  608.         [
  609.             SNew(SOverlay)
  610.             + SOverlay::Slot()
  611.         [
  612.             SNew(SImage)
  613.             .Image_Raw(this, &SK2Node_MethodsDropdown::GetCurrentIconBrush)
  614.         ]
  615.  
  616.     + SOverlay::Slot()
  617.         .VAlign(VAlign_Top)
  618.         .HAlign(HAlign_Right)
  619.         [
  620.             SNew(SImage)
  621.             // .Visibility_Raw(this, &::GetSpawnableIconOverlayVisibility)
  622.         .Image(FEditorStyle::GetBrush("Sequencer.SpawnableIconOverlay"))
  623.         ]
  624.         ]
  625.  
  626.     + SHorizontalBox::Slot()
  627.         .Padding(4.f, 0, 0, 0)
  628.         .VAlign(VAlign_Center)
  629.         [
  630.             TextContent
  631.         ];
  632. }
  633.  
  634. FText SK2Node_MethodsDropdown::GetCurrentText()
  635. {
  636.     if (auto node = Cast<UK2Node_WN_Await>(GraphNode))
  637.         if (node->CurrentFunction)
  638.             return node->CurrentFunction->GetDisplayNameText();
  639.    
  640.     return LOCTEXT("SelectMethod", "Select method");
  641. }
  642.  
  643. const FSlateBrush* SK2Node_MethodsDropdown::GetCurrentIconBrush() const
  644. {
  645.     return CurrentIcon.GetOptionalIcon();
  646. }
  647.  
  648. void SK2Node_MethodsDropdown::SetMethodName(FName InName)
  649. {
  650.     if (UEdGraphPin* method_pin = GraphNode->FindPin("Method"))
  651.     {
  652.         const UEdGraphSchema_K2* K2Schema = GetDefault<UEdGraphSchema_K2>();
  653.  
  654.         K2Schema->TrySetDefaultValue(*method_pin, InName.ToString());
  655.     }
  656.  
  657. }
  658.  
  659. FSlateColor SK2Node_MethodsDropdown::OnGetComboForeground() const
  660. {
  661.     return FSlateColor(FLinearColor(1.f, 1.f, 1.f, IsHovered() ? 1.f : 0.6f));
  662. }
  663.  
  664. FSlateColor SK2Node_MethodsDropdown::OnGetWidgetForeground() const
  665. {
  666.     return FSlateColor(FLinearColor(1.f, 1.f, 1.f, IsHovered() ? 1.f : 0.15f));
  667. }
  668.  
  669. FSlateColor SK2Node_MethodsDropdown::OnGetWidgetBackground() const
  670. {
  671. {
  672.     return FSlateColor(FLinearColor(1.f, 1.f, 1.f, IsHovered() ? 0.8f : 0.4f));
  673. }
  674.  
  675.  
  676.  
  677.  
  678.  
  679. #undef LOCTEXT_NAMESPACE
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement