// Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include "Styling/AppStyle.h" #include "KismetPins/SGraphPinBool.h" #include "KismetPins/SGraphPinNum.h" #include "KismetPins/SGraphPinInteger.h" #include "KismetPins/SGraphPinObject.h" #include "KismetPins/SGraphPinString.h" #include "MetasoundEditorGraph.h" #include "MetasoundEditorGraphBuilder.h" #include "MetasoundEditorGraphMemberDefaults.h" #include "MetasoundEditorGraphNode.h" #include "MetasoundFrontendController.h" #include "SGraphPin.h" #include "Styling/SlateStyleRegistry.h" #include "Widgets/Input/SButton.h" #include "Widgets/SBoxPanel.h" #include "Widgets/SNullWidget.h" #include "Widgets/SWidget.h" #define LOCTEXT_NAMESPACE "MetasoundEditor" namespace Metasound { namespace Editor { template class METASOUNDEDITOR_API TMetasoundGraphPin : public ParentPinType { public: SLATE_BEGIN_ARGS(TMetasoundGraphPin) { } SLATE_END_ARGS() Frontend::FConstInputHandle GetConstInputHandle() const { using namespace Frontend; const bool bIsInput = (ParentPinType::GetDirection() == EGPD_Input); if (bIsInput) { if (const UEdGraphPin* Pin = ParentPinType::GetPinObj()) { if (const UMetasoundEditorGraphNode* MetasoundEditorNode = Cast(Pin->GetOwningNode())) { FConstNodeHandle NodeHandle = MetasoundEditorNode->GetConstNodeHandle(); return NodeHandle->GetConstInputWithVertexName(Pin->GetFName()); } } } return IInputController::GetInvalidHandle(); } Frontend::FInputHandle GetInputHandle() { using namespace Frontend; const bool bIsInput = (ParentPinType::GetDirection() == EGPD_Input); if (bIsInput) { if (UEdGraphPin* Pin = ParentPinType::GetPinObj()) { if (UMetasoundEditorGraphNode* MetasoundEditorNode = Cast(Pin->GetOwningNode())) { FNodeHandle NodeHandle = MetasoundEditorNode->GetNodeHandle(); return NodeHandle->GetInputWithVertexName(Pin->GetFName()); } } } return IInputController::GetInvalidHandle(); } bool ShowDefaultValueWidget() const { UEdGraphPin* Pin = ParentPinType::GetPinObj(); if (!Pin) { return true; } UMetasoundEditorGraphMemberNode* Node = Cast(Pin->GetOwningNode()); if (!Node) { return true; } UMetasoundEditorGraphMember* Member = Node->GetMember(); if (!Member) { return true; } UMetasoundEditorGraphMemberDefaultFloat* DefaultFloat = Cast(Member->GetLiteral()); if (!DefaultFloat) { return true; } return DefaultFloat->WidgetType == EMetasoundMemberDefaultWidget::None; } virtual TSharedRef GetDefaultValueWidget() override { using namespace Frontend; TSharedRef DefaultWidget = ParentPinType::GetDefaultValueWidget(); if (!ShowDefaultValueWidget()) { return SNullWidget::NullWidget; } // For now, arrays do not support literals. // TODO: Support array literals by displaying // default literals (non-array too) in inspector window. FConstInputHandle InputHandle = GetConstInputHandle(); if (!InputHandle->IsValid() || ParentPinType::IsArray()) { return DefaultWidget; } return SNew(SHorizontalBox) + SHorizontalBox::Slot() .VAlign(VAlign_Center) [ DefaultWidget ] + SHorizontalBox::Slot() .AutoWidth() .VAlign(VAlign_Center) [ SNew(SButton) .ToolTipText(LOCTEXT("ResetToClassDefaultToolTip", "Reset to class default")) .ButtonStyle(FAppStyle::Get(), TEXT("NoBorder")) .ContentPadding(0.0f) .Visibility(TAttribute::Create([this] { using namespace Frontend; if (!ParentPinType::IsConnected()) { FConstInputHandle InputHandle = GetConstInputHandle(); if (const FMetasoundFrontendLiteral* Literal = InputHandle->GetLiteral()) { const bool bIsDefaultConstructed = Literal->GetType() == EMetasoundFrontendLiteralType::None; const bool bIsTriggerDataType = InputHandle->GetDataType() == GetMetasoundDataTypeName(); if (!bIsDefaultConstructed && !bIsTriggerDataType) { return EVisibility::Visible; } } } return EVisibility::Collapsed; })) .OnClicked(FOnClicked::CreateLambda([this]() { using namespace Frontend; if (UEdGraphPin* Pin = ParentPinType::GetPinObj()) { if (UMetasoundEditorGraphNode* Node = Cast(Pin->GetOwningNode())) { if (UMetasoundEditorGraph* MetaSoundGraph = CastChecked(Node->GetGraph())) { UObject& MetaSound = MetaSoundGraph->GetMetasoundChecked(); { const FScopedTransaction Transaction(LOCTEXT("MetaSoundEditorResetToClassDefault", "Reset to Class Default")); MetaSound.Modify(); MetaSoundGraph->Modify(); if (UMetasoundEditorGraphMemberNode* MemberNode = Cast(Node)) { UMetasoundEditorGraphMember* Member = MemberNode->GetMember(); if (ensure(Member)) { Member->ResetToClassDefault(); } } else { FInputHandle InputHandle = GetInputHandle(); InputHandle->ClearLiteral(); } } // Full node synchronization required as custom // node-level widgets may need to be refreshed MetaSoundGraph->SetSynchronizationRequired(); } } } return FReply::Handled(); })) .Content() [ SNew(SImage) .Image(FAppStyle::GetBrush("PropertyWindow.DiffersFromDefault")) ] ]; } virtual const FSlateBrush* GetPinIcon() const { const bool bIsConnected = ParentPinType::IsConnected(); bool bIsConstructorPin = false; if (const UEdGraphPin* Pin = ParentPinType::GetPinObj()) { if (const UMetasoundEditorGraphNode* Node = Cast(Pin->GetOwningNode())) { if (const UMetasoundEditorGraphMemberNode* MemberNode = Cast(Node)) { if (const UMetasoundEditorGraphInput* Input = Cast(MemberNode->GetMember())) { bIsConstructorPin = Input->ConstructorPin; } } } } if (bIsConstructorPin) { if (const ISlateStyle* MetasoundStyle = FSlateStyleRegistry::FindSlateStyle("MetaSoundStyle")) { if (ParentPinType::IsArray()) { return bIsConnected ? MetasoundStyle->GetBrush(TEXT("MetasoundEditor.Graph.ConstructorPinArray")) : MetasoundStyle->GetBrush(TEXT("MetasoundEditor.Graph.ConstructorPinArrayDisconnected")); } else { return bIsConnected ? MetasoundStyle->GetBrush(TEXT("MetasoundEditor.Graph.ConstructorPin")) : MetasoundStyle->GetBrush(TEXT("MetasoundEditor.Graph.ConstructorPinDisconnected")); } } } return SGraphPin::GetPinIcon(); } }; class SMetasoundGraphPin : public TMetasoundGraphPin { public: void Construct(const FArguments& InArgs, UEdGraphPin* InGraphPinObj) { SGraphPin::Construct(SGraphPin::FArguments(), InGraphPinObj); } }; class SMetasoundGraphPinBool : public TMetasoundGraphPin { public: void Construct(const FArguments& InArgs, UEdGraphPin* InGraphPinObj) { SGraphPinBool::Construct(SGraphPinBool::FArguments(), InGraphPinObj); } }; class SMetasoundGraphPinFloat : public TMetasoundGraphPin> { public: void Construct(const FArguments& InArgs, UEdGraphPin* InGraphPinObj) { SGraphPinNum::Construct(SGraphPinNum::FArguments(), InGraphPinObj); } }; class SMetasoundGraphPinInteger : public TMetasoundGraphPin { public: void Construct(const FArguments& InArgs, UEdGraphPin* InGraphPinObj) { SGraphPinInteger::Construct(SGraphPinInteger::FArguments(), InGraphPinObj); } }; class SMetasoundGraphPinObject : public TMetasoundGraphPin { public: void Construct(const FArguments& InArgs, UEdGraphPin* InGraphPinObj) { SGraphPinObject::Construct(SGraphPinObject::FArguments(), InGraphPinObj); } }; class SMetasoundGraphPinString : public TMetasoundGraphPin { public: void Construct(const FArguments& InArgs, UEdGraphPin* InGraphPinObj) { SGraphPinString::Construct(SGraphPinString::FArguments(), InGraphPinObj); } }; } // namespace Editor } // namespace Metasound #undef LOCTEXT_NAMESPACE