You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
Big conversion of FStrings and FNames to FText. Version bump to move some MaterialFunction UProperty from a TArray<FString> to TArray<FText> (some Engine assets are older than being allowed to auto-convert the UProperty) Auto conversion of FName to FText (and back) now supported (as well as TArrays of those types). Searching categories by both the localized string and the source string is now supported in Blueprints. #jira UE-14481 - We are missing ability to translate node categories #codereview Justin.Sargent [CL 2542875 by Michael Schoell in Main branch]
244 lines
8.5 KiB
C++
244 lines
8.5 KiB
C++
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
|
|
|
|
/*=============================================================================
|
|
SoundClassGraphSchema.cpp
|
|
=============================================================================*/
|
|
|
|
#include "UnrealEd.h"
|
|
#include "AssetData.h"
|
|
#include "ScopedTransaction.h"
|
|
#include "GraphEditorActions.h"
|
|
#include "SoundClassEditorUtilities.h"
|
|
#include "GenericCommands.h"
|
|
|
|
#define LOCTEXT_NAMESPACE "SoundClassSchema"
|
|
|
|
UEdGraphNode* FSoundClassGraphSchemaAction_NewNode::PerformAction(class UEdGraph* ParentGraph, UEdGraphPin* FromPin, const FVector2D Location, bool bSelectNewNode/* = true*/)
|
|
{
|
|
FSoundClassEditorUtilities::CreateSoundClass(ParentGraph, FromPin, Location, NewSoundClassName);
|
|
return NULL;
|
|
}
|
|
|
|
USoundClassGraphSchema::USoundClassGraphSchema(const FObjectInitializer& ObjectInitializer)
|
|
: Super(ObjectInitializer)
|
|
{
|
|
}
|
|
|
|
bool USoundClassGraphSchema::ConnectionCausesLoop(const UEdGraphPin* InputPin, const UEdGraphPin* OutputPin) const
|
|
{
|
|
USoundClassGraphNode* InputNode = CastChecked<USoundClassGraphNode>(InputPin->GetOwningNode());
|
|
USoundClassGraphNode* OutputNode = CastChecked<USoundClassGraphNode>(OutputPin->GetOwningNode());
|
|
|
|
return InputNode->SoundClass->RecurseCheckChild( OutputNode->SoundClass );
|
|
}
|
|
|
|
void USoundClassGraphSchema::GetBreakLinkToSubMenuActions( class FMenuBuilder& MenuBuilder, UEdGraphPin* InGraphPin )
|
|
{
|
|
// Make sure we have a unique name for every entry in the list
|
|
TMap< FString, uint32 > LinkTitleCount;
|
|
|
|
// Add all the links we could break from
|
|
for(TArray<class UEdGraphPin*>::TConstIterator Links(InGraphPin->LinkedTo); Links; ++Links)
|
|
{
|
|
UEdGraphPin* Pin = *Links;
|
|
FString TitleString = Pin->GetOwningNode()->GetNodeTitle(ENodeTitleType::ListView).ToString();
|
|
FText Title = FText::FromString( TitleString );
|
|
if ( Pin->PinName != TEXT("") )
|
|
{
|
|
TitleString = FString::Printf(TEXT("%s (%s)"), *TitleString, *Pin->PinName);
|
|
|
|
// Add name of connection if possible
|
|
FFormatNamedArguments Args;
|
|
Args.Add( TEXT("NodeTitle"), Title );
|
|
Args.Add( TEXT("PinName"), Pin->GetDisplayName() );
|
|
Title = FText::Format( LOCTEXT("BreakDescPin", "{NodeTitle} ({PinName})"), Args );
|
|
}
|
|
|
|
uint32 &Count = LinkTitleCount.FindOrAdd( TitleString );
|
|
|
|
FText Description;
|
|
FFormatNamedArguments Args;
|
|
Args.Add( TEXT("NodeTitle"), Title );
|
|
Args.Add( TEXT("NumberOfNodes"), Count );
|
|
|
|
if ( Count == 0 )
|
|
{
|
|
Description = FText::Format( LOCTEXT("BreakDesc", "Break link to {NodeTitle}"), Args );
|
|
}
|
|
else
|
|
{
|
|
Description = FText::Format( LOCTEXT("BreakDescMulti", "Break link to {NodeTitle} ({NumberOfNodes})"), Args );
|
|
}
|
|
++Count;
|
|
|
|
MenuBuilder.AddMenuEntry( Description, Description, FSlateIcon(), FUIAction(
|
|
FExecuteAction::CreateUObject((USoundClassGraphSchema*const)this, &USoundClassGraphSchema::BreakSinglePinLink, const_cast< UEdGraphPin* >(InGraphPin), *Links) ) );
|
|
}
|
|
}
|
|
|
|
void USoundClassGraphSchema::GetGraphContextActions(FGraphContextMenuBuilder& ContextMenuBuilder) const
|
|
{
|
|
const FText Name = LOCTEXT("NewSoundClass", "New Sound Class");
|
|
const FText ToolTip = LOCTEXT("NewSoundClassTooltip", "Create a new sound class");
|
|
|
|
TSharedPtr<FSoundClassGraphSchemaAction_NewNode> NewAction(new FSoundClassGraphSchemaAction_NewNode(FText::GetEmpty(), Name, ToolTip.ToString(), 0));
|
|
|
|
ContextMenuBuilder.AddAction( NewAction );
|
|
}
|
|
|
|
void USoundClassGraphSchema::GetContextMenuActions(const UEdGraph* CurrentGraph, const UEdGraphNode* InGraphNode, const UEdGraphPin* InGraphPin, class FMenuBuilder* MenuBuilder, bool bIsDebugging) const
|
|
{
|
|
if (InGraphPin)
|
|
{
|
|
MenuBuilder->BeginSection("SoundClassGraphSchemaPinActions", LOCTEXT("PinActionsMenuHeader", "Pin Actions"));
|
|
{
|
|
// Only display the 'Break Links' option if there is a link to break!
|
|
if (InGraphPin->LinkedTo.Num() > 0)
|
|
{
|
|
MenuBuilder->AddMenuEntry( FGraphEditorCommands::Get().BreakPinLinks );
|
|
|
|
// add sub menu for break link to
|
|
if(InGraphPin->LinkedTo.Num() > 1)
|
|
{
|
|
MenuBuilder->AddSubMenu(
|
|
LOCTEXT("BreakLinkTo", "Break Link To..." ),
|
|
LOCTEXT("BreakSpecificLinks", "Break a specific link..." ),
|
|
FNewMenuDelegate::CreateUObject( (USoundClassGraphSchema*const)this, &USoundClassGraphSchema::GetBreakLinkToSubMenuActions, const_cast<UEdGraphPin*>(InGraphPin)));
|
|
}
|
|
else
|
|
{
|
|
((USoundClassGraphSchema*const)this)->GetBreakLinkToSubMenuActions(*MenuBuilder, const_cast<UEdGraphPin*>(InGraphPin));
|
|
}
|
|
}
|
|
}
|
|
MenuBuilder->EndSection();
|
|
}
|
|
else if (InGraphNode)
|
|
{
|
|
const USoundClassGraphNode* SoundGraphNode = Cast<const USoundClassGraphNode>(InGraphNode);
|
|
|
|
MenuBuilder->BeginSection("SoundClassGraphSchemaNodeActions", LOCTEXT("ClassActionsMenuHeader", "SoundClass Actions"));
|
|
{
|
|
MenuBuilder->AddMenuEntry(FGraphEditorCommands::Get().BreakNodeLinks);
|
|
MenuBuilder->AddMenuEntry(FGenericCommands::Get().Delete);
|
|
}
|
|
MenuBuilder->EndSection();
|
|
}
|
|
|
|
// No Super call so Node comments option is not shown
|
|
}
|
|
|
|
const FPinConnectionResponse USoundClassGraphSchema::CanCreateConnection(const UEdGraphPin* PinA, const UEdGraphPin* PinB) const
|
|
{
|
|
// Make sure the pins are not on the same node
|
|
if (PinA->GetOwningNode() == PinB->GetOwningNode())
|
|
{
|
|
return FPinConnectionResponse(CONNECT_RESPONSE_DISALLOW, LOCTEXT("ConnectionSameNode", "Both are on the same node"));
|
|
}
|
|
|
|
// Compare the directions
|
|
const UEdGraphPin* InputPin = NULL;
|
|
const UEdGraphPin* OutputPin = NULL;
|
|
|
|
if (!CategorizePinsByDirection(PinA, PinB, /*out*/ InputPin, /*out*/ OutputPin))
|
|
{
|
|
return FPinConnectionResponse(CONNECT_RESPONSE_DISALLOW, LOCTEXT("ConnectionIncompatible", "Directions are not compatible"));
|
|
}
|
|
|
|
if (ConnectionCausesLoop(InputPin, OutputPin))
|
|
{
|
|
return FPinConnectionResponse(CONNECT_RESPONSE_DISALLOW, LOCTEXT("ConnectionLoop", "Connection would cause loop"));
|
|
}
|
|
|
|
// Break existing connections on inputs only - multiple output connections are acceptable
|
|
if (InputPin->LinkedTo.Num() > 0)
|
|
{
|
|
ECanCreateConnectionResponse ReplyBreakOutputs;
|
|
if (InputPin == PinA)
|
|
{
|
|
ReplyBreakOutputs = CONNECT_RESPONSE_BREAK_OTHERS_A;
|
|
}
|
|
else
|
|
{
|
|
ReplyBreakOutputs = CONNECT_RESPONSE_BREAK_OTHERS_B;
|
|
}
|
|
return FPinConnectionResponse(ReplyBreakOutputs, LOCTEXT("ConnectionReplace", "Replace existing connections"));
|
|
}
|
|
|
|
return FPinConnectionResponse(CONNECT_RESPONSE_MAKE, FText::GetEmpty());
|
|
}
|
|
|
|
bool USoundClassGraphSchema::TryCreateConnection(UEdGraphPin* PinA, UEdGraphPin* PinB) const
|
|
{
|
|
bool bModified = UEdGraphSchema::TryCreateConnection(PinA, PinB);
|
|
|
|
if (bModified)
|
|
{
|
|
CastChecked<USoundClassGraph>(PinA->GetOwningNode()->GetGraph())->LinkSoundClasses();
|
|
}
|
|
|
|
return bModified;
|
|
}
|
|
|
|
bool USoundClassGraphSchema::ShouldHidePinDefaultValue(UEdGraphPin* Pin) const
|
|
{
|
|
return true;
|
|
}
|
|
|
|
FLinearColor USoundClassGraphSchema::GetPinTypeColor(const FEdGraphPinType& PinType) const
|
|
{
|
|
return FLinearColor::White;
|
|
}
|
|
|
|
void USoundClassGraphSchema::BreakNodeLinks(UEdGraphNode& TargetNode) const
|
|
{
|
|
Super::BreakNodeLinks(TargetNode);
|
|
|
|
CastChecked<USoundClassGraph>(TargetNode.GetGraph())->LinkSoundClasses();
|
|
}
|
|
|
|
void USoundClassGraphSchema::BreakPinLinks(UEdGraphPin& TargetPin, bool bSendsNodeNotifcation) const
|
|
{
|
|
const FScopedTransaction Transaction( NSLOCTEXT("UnrealEd", "GraphEd_BreakPinLinks", "Break Pin Links") );
|
|
|
|
Super::BreakPinLinks(TargetPin, bSendsNodeNotifcation);
|
|
|
|
// if this would notify the node then we need to re-link sound classes
|
|
if (bSendsNodeNotifcation)
|
|
{
|
|
CastChecked<USoundClassGraph>(TargetPin.GetOwningNode()->GetGraph())->LinkSoundClasses();
|
|
}
|
|
}
|
|
|
|
void USoundClassGraphSchema::BreakSinglePinLink(UEdGraphPin* SourcePin, UEdGraphPin* TargetPin)
|
|
{
|
|
const FScopedTransaction Transaction( NSLOCTEXT("UnrealEd", "GraphEd_BreakSinglePinLink", "Break Pin Link") );
|
|
Super::BreakSinglePinLink(SourcePin, TargetPin);
|
|
|
|
CastChecked<USoundClassGraph>(SourcePin->GetOwningNode()->GetGraph())->LinkSoundClasses();
|
|
}
|
|
|
|
void USoundClassGraphSchema::DroppedAssetsOnGraph(const TArray<class FAssetData>& Assets, const FVector2D& GraphPosition, UEdGraph* Graph) const
|
|
{
|
|
USoundClassGraph* SoundClassGraph = CastChecked<USoundClassGraph>(Graph);
|
|
|
|
TArray<USoundClass*> UndisplayedClasses;
|
|
for (int32 AssetIdx = 0; AssetIdx < Assets.Num(); ++AssetIdx)
|
|
{
|
|
USoundClass* SoundClass = Cast<USoundClass>(Assets[AssetIdx].GetAsset());
|
|
if (SoundClass && !SoundClassGraph->IsClassDisplayed(SoundClass))
|
|
{
|
|
UndisplayedClasses.Add(SoundClass);
|
|
}
|
|
}
|
|
|
|
if (UndisplayedClasses.Num() > 0)
|
|
{
|
|
const FScopedTransaction Transaction( LOCTEXT("SoundClassEditorDropClasses", "Sound Class Editor: Drag and Drop Sound Class") );
|
|
|
|
SoundClassGraph->AddDroppedSoundClasses(UndisplayedClasses, GraphPosition.X, GraphPosition.Y);
|
|
}
|
|
}
|
|
|
|
#undef LOCTEXT_NAMESPACE
|