예제 #1
0
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;
}
예제 #2
0
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)
	}
}
예제 #4
0
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();
}
예제 #5
0
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);
}
예제 #6
0
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();
	}
}
예제 #7
0
/** 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;
			}
		}
	}
}
예제 #8
0
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;
	}
}