void FGraphEditorDragDropAction::SetSimpleFeedbackMessage(const FSlateBrush* Icon, const FSlateColor& IconColor, const FText& Message) { // Let the user know the status of making this connection. // Use CreateRaw as we cannot using anything that will create a shared ptr from within an objects construction, this should be // safe though as we will destroy our window before we get destroyed. TAttribute<EVisibility> ErrorIconVisibility = TAttribute<EVisibility>::Create(TAttribute<EVisibility>::FGetter::CreateRaw(this, &FGraphEditorDragDropAction::GetErrorIconVisible)); TAttribute<EVisibility> IconVisibility = TAttribute<EVisibility>::Create(TAttribute<EVisibility>::FGetter::CreateRaw(this, &FGraphEditorDragDropAction::GetIconVisible)); SetFeedbackMessage( SNew(SHorizontalBox) +SHorizontalBox::Slot() .AutoWidth() .Padding(3.0f) [ SNew(SScaleBox) .Stretch(EStretch::ScaleToFit) [ SNew(SImage) .Visibility(ErrorIconVisibility) .Image( FEditorStyle::GetBrush( TEXT("Graph.ConnectorFeedback.Error") )) .ColorAndOpacity( FLinearColor::White ) ] ] +SHorizontalBox::Slot() .AutoWidth() .Padding(3.0f) [ SNew(SScaleBox) .Stretch(EStretch::ScaleToFit) [ SNew(SImage) .Visibility(IconVisibility) .Image( Icon ) .ColorAndOpacity( IconColor ) ] ] +SHorizontalBox::Slot() .AutoWidth() .MaxWidth(500) .VAlign(VAlign_Center) [ SNew(STextBlock) .WrapTextAt( 480 ) .Text( Message ) ] ); }
void FDragConnection::HoverTargetChanged() { TArray<FPinConnectionResponse> UniqueMessages; if (UEdGraphPin* TargetPinObj = GetHoveredPin()) { TArray<UEdGraphPin*> ValidSourcePins; ValidateGraphPinList(/*out*/ ValidSourcePins); // Check the schema for connection responses for (UEdGraphPin* StartingPinObj : ValidSourcePins) { if (TargetPinObj != StartingPinObj) { // The Graph object in which the pins reside. UEdGraph* GraphObj = StartingPinObj->GetOwningNode()->GetGraph(); // Determine what the schema thinks about the wiring action const FPinConnectionResponse Response = GraphObj->GetSchema()->CanCreateConnection( StartingPinObj, TargetPinObj ); if (Response.Response == ECanCreateConnectionResponse::CONNECT_RESPONSE_DISALLOW) { TSharedPtr<SGraphNode> NodeWidget = TargetPinObj->GetOwningNode()->NodeWidget.Pin(); if (NodeWidget.IsValid()) { NodeWidget->NotifyDisallowedPinConnection(StartingPinObj, TargetPinObj); } } UniqueMessages.AddUnique(Response); } } } else if(UEdGraphNode* TargetNodeObj = GetHoveredNode()) { TArray<UEdGraphPin*> ValidSourcePins; ValidateGraphPinList(/*out*/ ValidSourcePins); // Check the schema for connection responses for (UEdGraphPin* StartingPinObj : ValidSourcePins) { FPinConnectionResponse Response; FText ResponseText; if (StartingPinObj->GetOwningNode() != TargetNodeObj && StartingPinObj->GetSchema()->SupportsDropPinOnNode(TargetNodeObj, StartingPinObj->PinType, StartingPinObj->Direction, ResponseText)) { Response.Response = ECanCreateConnectionResponse::CONNECT_RESPONSE_MAKE; } else { Response.Response = ECanCreateConnectionResponse::CONNECT_RESPONSE_DISALLOW; } // Do not display an error if there is no message if (!ResponseText.IsEmpty()) { Response.Message = ResponseText; UniqueMessages.AddUnique(Response); } } } // Let the user know the status of dropping now if (UniqueMessages.Num() == 0) { // Display the place a new node icon, we're not over a valid pin SetSimpleFeedbackMessage( FEditorStyle::GetBrush(TEXT("Graph.ConnectorFeedback.NewNode")), FLinearColor::White, NSLOCTEXT("GraphEditor.Feedback", "PlaceNewNode", "Place a new node.")); } else { // Take the unique responses and create visual feedback for it TSharedRef<SVerticalBox> FeedbackBox = SNew(SVerticalBox); for (auto ResponseIt = UniqueMessages.CreateConstIterator(); ResponseIt; ++ResponseIt) { // Determine the icon const FSlateBrush* StatusSymbol = NULL; switch (ResponseIt->Response) { case CONNECT_RESPONSE_MAKE: case CONNECT_RESPONSE_BREAK_OTHERS_A: case CONNECT_RESPONSE_BREAK_OTHERS_B: case CONNECT_RESPONSE_BREAK_OTHERS_AB: StatusSymbol = FEditorStyle::GetBrush(TEXT("Graph.ConnectorFeedback.OK")); break; case CONNECT_RESPONSE_MAKE_WITH_CONVERSION_NODE: StatusSymbol = FEditorStyle::GetBrush(TEXT("Graph.ConnectorFeedback.ViaCast")); break; case CONNECT_RESPONSE_DISALLOW: default: StatusSymbol = FEditorStyle::GetBrush(TEXT("Graph.ConnectorFeedback.Error")); break; } // Add a new message row FeedbackBox->AddSlot() .AutoHeight() [ SNew(SHorizontalBox) +SHorizontalBox::Slot() .AutoWidth() .Padding(3.0f) [ SNew(SImage) .Image( StatusSymbol ) ] +SHorizontalBox::Slot() .AutoWidth() .VAlign(VAlign_Center) [ SNew(STextBlock) .Text( ResponseIt->Message ) ] ]; } SetFeedbackMessage(FeedbackBox); } }