void UK2Node_Select::PostPasteNode() { Super::PostPasteNode(); UEdGraphPin* IndexPin = GetIndexPin(); // This information will be cleared and we want to restore it FString OldDefaultValue = IndexPin->DefaultValue; // Corrects data in the index pin that is not valid after pasting PinTypeChanged(GetIndexPin()); // Restore the default value of the index pin IndexPin->DefaultValue = OldDefaultValue; }
bool UK2Node_Select::CanChangePinType(UEdGraphPin* Pin) const { // If this is the index pin, only allow type switching if nothing is linked to the pin if (Pin == GetIndexPin()) { if (Pin->LinkedTo.Num() > 0) { return false; } } // Else it's one of the wildcard pins that share their type, so make sure none of them have a link else { if (GetReturnValuePin()->LinkedTo.Num() > 0) { return false; } else { TArray<UEdGraphPin*> OptionPins; GetOptionPins(OptionPins); for (auto It = OptionPins.CreateConstIterator(); It; It++) { UEdGraphPin* OptionPin = (*It); if (OptionPin && OptionPin->LinkedTo.Num() > 0) { return false; } } } } return true; }
void UK2Node_GetArrayItem::NotifyPinConnectionListChanged(UEdGraphPin* Pin) { Super::NotifyPinConnectionListChanged(Pin); if (Pin != GetIndexPin() && Pin->ParentPin == nullptr) { UEdGraphPin* ArrayPin = Pins[0]; UEdGraphPin* ResultPin = Pins[2]; auto ClearWildcardType = [ArrayPin, ResultPin]() { ArrayPin->PinType.PinCategory = UEdGraphSchema_K2::PC_Wildcard; ArrayPin->PinType.PinSubCategory = TEXT(""); ArrayPin->PinType.PinSubCategoryObject = NULL; ResultPin->PinType.PinCategory = UEdGraphSchema_K2::PC_Wildcard; ResultPin->PinType.PinSubCategory = TEXT(""); ResultPin->PinType.PinSubCategoryObject = NULL; ResultPin->PinType.bIsReference = true; ArrayPin->BreakAllPinLinks(); ResultPin->BreakAllPinLinks(); }; const int32 NewLinkCount = Pin->LinkedTo.Num(); const bool bPinsHasLinks = (NewLinkCount > 0); if (ArrayPin == Pin) { if (bPinsHasLinks) { // if we had more than one input, we'd have to find the common base type ensure(NewLinkCount == 1); // the input array has authority, change output types, even if they are connected PropagatePinType(Pin->LinkedTo[0]->PinType); } // if the array pin was disconnected from everything, and... else if (ResultPin->LinkedTo.Num() == 0) { ClearWildcardType(); } } else if (ArrayPin->LinkedTo.Num() == 0) { // if we cleared the result pin's connections if (!bPinsHasLinks) { ClearWildcardType(); } // if this is the first connection to the result pin... else if (NewLinkCount == 1) { PropagatePinType(Pin->LinkedTo[0]->PinType); } // else, the result pin already had a connection and a type, leave // it alone, as it is what facilitated this connection as well } // else, leave this node alone, the array input is still connected and // it has authority over the wildcard types (the type set should already be good) } }
void UK2Node_Select::AddOptionPinToNode() { const UEdGraphSchema_K2* K2Schema = GetDefault<UEdGraphSchema_K2>(); // Increment the pin count NumOptionPins++; // We guarantee at least 2 options by default and since we just increased the count // to more than 2, we need to make sure we're now dealing with an index for selection // instead of the default boolean check if (IndexPinType.PinCategory == K2Schema->PC_Boolean) { IndexPinType.PinCategory = K2Schema->PC_Int; GetIndexPin()->BreakAllPinLinks(); } // We will let the AllocateDefaultPins call handle the actual addition via ReconstructNode ReconstructNode(); }
void UK2Node_Select::AutowireNewNode(UEdGraphPin* FromPin) { if (FromPin) { // Attempt to autowire to the index pin as users generally drag off of something intending to use // it as an index in a select statement rather than an arbitrary entry: const UEdGraphSchema_K2* K2Schema = CastChecked<UEdGraphSchema_K2>(GetSchema()); UEdGraphPin* IndexPin = GetIndexPin(); ECanCreateConnectionResponse ConnectResponse = K2Schema->CanCreateConnection(FromPin, IndexPin).Response; if (ConnectResponse == ECanCreateConnectionResponse::CONNECT_RESPONSE_MAKE) { if (K2Schema->TryCreateConnection(FromPin, IndexPin)) { FromPin->GetOwningNode()->NodeConnectionListChanged(); this->NodeConnectionListChanged(); return; } } } // No connection made, just use default autowire logic: Super::AutowireNewNode(FromPin); }
void UK2Node_Select::PinTypeChanged(UEdGraphPin* Pin) { const UEdGraphSchema_K2* Schema = GetDefault<UEdGraphSchema_K2>(); if (Pin == GetIndexPin()) { if (IndexPinType != Pin->PinType) { IndexPinType = Pin->PinType; if (IndexPinType.PinSubCategoryObject.IsValid()) { SetEnum(Cast<UEnum>(IndexPinType.PinSubCategoryObject.Get())); } else if (Enum) { SetEnum(NULL); } // Remove all but two options if we switched to a bool index if (IndexPinType.PinCategory == Schema->PC_Boolean) { if (NumOptionPins > 2) { NumOptionPins = 2; bReconstructNode = true; } } // Reset the default value Schema->SetPinDefaultValueBasedOnType(Pin); } } else { // Set the return value UEdGraphPin* ReturnPin = GetReturnValuePin(); if (ReturnPin->PinType != Pin->PinType) { ReturnPin->PinType = Pin->PinType; Schema->SetPinDefaultValueBasedOnType(ReturnPin); } // Set the options TArray<UEdGraphPin*> OptionPins; GetOptionPins(OptionPins); for (auto It = OptionPins.CreateConstIterator(); It; It++) { UEdGraphPin* OptionPin = (*It); if (OptionPin->PinType != Pin->PinType || OptionPin == Pin) { OptionPin->PinType = Pin->PinType; Schema->SetPinDefaultValueBasedOnType(OptionPin); } } } // Reconstruct the node since the options could change if (bReconstructNode) { ReconstructNode(); } // Let the graph know to refresh GetGraph()->NotifyGraphChanged(); UBlueprint* Blueprint = GetBlueprint(); if(!Blueprint->bBeingCompiled) { FBlueprintEditorUtils::MarkBlueprintAsModified(Blueprint); Blueprint->BroadcastChanged(); } }
/** Determine if any pins are connected, if so make all the other pins the same type, if not, make sure pins are switched back to wildcards */ void UK2Node_Select::NotifyPinConnectionListChanged(UEdGraphPin* Pin) { Super::NotifyPinConnectionListChanged(Pin); const UEdGraphSchema_K2* Schema = GetDefault<UEdGraphSchema_K2>(); // If this is the Enum pin we need to set the enum and reconstruct the node if (Pin == GetIndexPin()) { // If the index pin was just linked to another pin if (Pin->LinkedTo.Num() > 0) { UEdGraphPin* LinkPin = Pin->LinkedTo[0]; IndexPinType = LinkPin->PinType; Pin->PinType = IndexPinType; // See if it was an enum pin if (LinkPin->PinType.PinCategory == Schema->PC_Byte && LinkPin->PinType.PinSubCategoryObject != NULL && LinkPin->PinType.PinSubCategoryObject->IsA(UEnum::StaticClass())) { UEnum* EnumPtr = Cast<UEnum>(LinkPin->PinType.PinSubCategoryObject.Get()); SetEnum(EnumPtr); } else { SetEnum(NULL); } Schema->SetPinDefaultValueBasedOnType(Pin); GetGraph()->NotifyGraphChanged(); UBlueprint* Blueprint = GetBlueprint(); if(!Blueprint->bBeingCompiled) { FBlueprintEditorUtils::MarkBlueprintAsModified(Blueprint); Blueprint->BroadcastChanged(); } // If the index pin is a boolean, we need to remove all but 2 options if (IndexPinType.PinCategory == Schema->PC_Boolean && NumOptionPins != 2) { NumOptionPins = 2; bReconstructNode = true; } } } else { // Grab references to all option pins and the return pin TArray<UEdGraphPin*> OptionPins; GetOptionPins(OptionPins); UEdGraphPin* ReturnPin = FindPin(Schema->PN_ReturnValue); // See if this pin is one of the wildcard pins bool bIsWildcardPin = (Pin == ReturnPin || OptionPins.Find(Pin) != INDEX_NONE) && Pin->PinType.PinCategory == Schema->PC_Wildcard; // If the pin was one of the wildcards we have to handle it specially if (bIsWildcardPin) { // If the pin is linked, make sure the other wildcard pins match if (Pin->LinkedTo.Num() > 0) { // Set pin type on the pin Pin->PinType = Pin->LinkedTo[0]->PinType; // Make sure the return pin is the same pin type if (ReturnPin != Pin) { ReturnPin->Modify(); ReturnPin->PinType = Pin->PinType; UEdGraphSchema_K2::ValidateExistingConnections(ReturnPin); } // Make sure all options are of the same pin type for (auto It = OptionPins.CreateConstIterator(); It; It++) { UEdGraphPin* OptionPin = (*It); if (*It && *It != Pin) { (*It)->Modify(); (*It)->PinType = Pin->PinType; UEdGraphSchema_K2::ValidateExistingConnections(*It); } } bReconstructNode = true; } } } }
void UK2Node_Select::ReallocatePinsDuringReconstruction(TArray<UEdGraphPin*>& OldPins) { Super::ReallocatePinsDuringReconstruction(OldPins); const UEdGraphSchema_K2* Schema = GetDefault<UEdGraphSchema_K2>(); // See if this node was saved in the old version with a boolean as the condition UEdGraphPin* OldConditionPin = NULL; UEdGraphPin* OldIndexPin = NULL; for (auto It = OldPins.CreateConstIterator(); It; It++) { if ((*It)->PinName == TEXT("bPickOption0")) { OldConditionPin = (*It); } else if ((*It)->PinName == TEXT("Index")) { OldIndexPin = (*It); } } UEdGraphPin* IndexPin = GetIndexPin(); // If we are fixing up an old bool node (swap the options and copy the condition links) if (OldConditionPin) { // Set the index pin type IndexPinType.PinCategory = Schema->PC_Boolean; IndexPinType.PinSubCategory = TEXT(""); IndexPinType.PinSubCategoryObject = NULL; // Set the pin type and Copy the pin IndexPin->PinType = IndexPinType; Schema->CopyPinLinks(*OldConditionPin, *IndexPin); // If we copy links, we need to send a notification if (IndexPin->LinkedTo.Num() > 0) { PinConnectionListChanged(IndexPin); } UEdGraphPin* OptionPin0 = FindPin("Option 0"); UEdGraphPin* OptionPin1 = FindPin("Option 1"); for (auto It = OldPins.CreateConstIterator(); It; It++) { UEdGraphPin* OldPin = (*It); if (OldPin->PinName == OptionPin0->PinName) { Schema->MovePinLinks(*OldPin, *OptionPin1); } else if (OldPin->PinName == OptionPin1->PinName) { Schema->MovePinLinks(*OldPin, *OptionPin0); } } } // If the index pin has links or a default value but is a wildcard, this is an old int pin so convert it if (OldIndexPin && IndexPinType.PinCategory == Schema->PC_Wildcard && (OldIndexPin->LinkedTo.Num() > 0 || OldIndexPin->DefaultValue != TEXT(""))) { IndexPinType.PinCategory = Schema->PC_Int; IndexPinType.PinSubCategory = TEXT(""); IndexPinType.PinSubCategoryObject = NULL; IndexPin->PinType = IndexPinType; } }