// ©2023 Batty Bovine Productions, LLC. All Rights Reserved. #include "SEdComboActionGraphNode.h" #include "Nodes/ComboActionGraphNode.h" #include "Helpers/ComboActionGraphColors.h" #include "Ed/SEdComboActionGraphNodeIndex.h" #include "Ed/EdComboActionGraphNode.h" //#include "SLevelOfDetailBranchNode.h" #include "Widgets/Text/SInlineEditableTextBlock.h" #include "SCommentBubble.h" #include "SlateOptMacros.h" #include "SGraphPin.h" #include "GraphEditorSettings.h" #include "Blueprint/UserWidget.h" #include "ComboActionGraph.h" #include "Settings/ComboActionGraphEditorSettings.h" #include "Settings/FComboActionGraphEditorStyle.h" #include "Widgets/Layout/SGridPanel.h" #include "Widgets/Layout/SScaleBox.h" #define LOCTEXT_NAMESPACE "EdComboActionGraph" #pragma region Pin class SComboActionGraphPin : public SGraphPin { public: SLATE_BEGIN_ARGS(SComboActionGraphPin) {} SLATE_END_ARGS() void Construct(const FArguments &InArgs, UEdGraphPin *InPin) { this->SetCursor(EMouseCursor::Default); bShowLabel = true; GraphPinObj = InPin; check(GraphPinObj != nullptr); const UEdGraphSchema *Schema = GraphPinObj->GetSchema(); check(Schema); // Pins Out/In Border SBorder::Construct(SBorder::FArguments() .BorderImage(this, &SComboActionGraphPin::GetPinBorder) .BorderBackgroundColor(this, &SComboActionGraphPin::GetPinColor) .OnMouseButtonDown(this, &SComboActionGraphPin::OnPinMouseDown) .Cursor(this, &SComboActionGraphPin::GetPinCursor) .Padding(FMargin(5.0f)) ); } protected: virtual FSlateColor GetPinColor() const override { if (const UComboActionGraphEditorSettings *GraphEditorSettings = GetMutableDefault()) { switch (GraphEditorSettings->GetNodeTheme()) { case EComboActionNodeTheme::DarkTheme: return ComboActionGraphColors::PinsDock::LightTheme; case EComboActionNodeTheme::LightTheme: return ComboActionGraphColors::PinsDock::DarkTheme; default: return ComboActionGraphColors::PinsDock::LightTheme; } } return ComboActionGraphColors::Pin::Default; } virtual TSharedRef GetDefaultValueWidget() override { return SNew(STextBlock); } const FSlateBrush *GetPinBorder() const { if (const UComboActionGraphEditorSettings *GraphEditorSettings = GetMutableDefault()) { switch (GraphEditorSettings->GetNodeType()) { case EComboActionNodeType::SoftCorners: return FComboActionGraphEditorStyle::GetBrush("MDSStyleSet.Node.TextSoftEdges"); case EComboActionNodeType::HardCorners: return FComboActionGraphEditorStyle::GetBrush("MDSStyleSet.Node.TextHardEdges"); } } return FComboActionGraphEditorStyle::GetBrush(TEXT("MDSStyleSet.Graph.PinDocksOverlay")); } }; #pragma endregion void SEdComboActionGraphNode::Construct(const FArguments &InArgs, UEdComboActionGraphNode *InNode) { this->GraphNode = InNode; this->UpdateGraphNode(); InNode->SEdNode = this; //bIsHovered = false; this->GraphEditorSettings = GetMutableDefault(); } void SEdComboActionGraphNode::OnMouseEnter(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) { //bIsHovered = true; SetToolTipText(GetTooltipText()); OnVisualizeTooltip(GetToolTip()->AsWidget()); SGraphNode::OnMouseEnter(MyGeometry, MouseEvent); } void SEdComboActionGraphNode::OnMouseLeave(const FPointerEvent& MouseEvent) { //bIsHovered = false; SetToolTipText(FText::GetEmpty()); OnToolTipClosing(); SGraphNode::OnMouseLeave(MouseEvent); } const FSlateBrush *SEdComboActionGraphNode::GetIndexBrush() const { return FComboActionGraphEditorStyle::GetBrush("MDSStyleSet.Node.TextSoftEdges"); } BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION void SEdComboActionGraphNode::UpdateGraphNode() { const FMargin NodePadding = FMargin(2.0f); const FMargin UnifiedRowsPadding = FMargin(0.f, 1.15f, 0.f, 0.f); const FSlateColor DefaultFontColor = ComboActionGraphColors::TextColors::Normal; InputPins.Empty(); OutputPins.Empty(); // Reset variables that are going to be exposed, in case we are refreshing an already setup node. RightNodeBox.Reset(); LeftNodeBox.Reset(); OutputPinBox.Reset(); TSharedPtr ErrorText; TSharedPtr NodeTitle = SNew(SNodeTitle, GraphNode); TSharedPtr StackBox; TSharedPtr UniformBox; this->ContentScale.Bind(this, &SGraphNode::GetContentScale); const FSlateBrush* CircleBrush = FComboActionGraphEditorStyle::GetBrush(TEXT("MDSStyleSet.Node.IndexCircle")); this->GetOrAddSlot(ENodeZone::Left) .SlotOffset(TAttribute(this, &SEdComboActionGraphNode::GetIndexSlotOffset)) .SlotSize(TAttribute(this, &SEdComboActionGraphNode::GetIndexSlotSize)) [ SNew(SOverlay) +SOverlay::Slot() .HAlign(HAlign_Fill) .VAlign(VAlign_Fill) [ SNew(SBox) .WidthOverride(CircleBrush->ImageSize.X) .HeightOverride(CircleBrush->ImageSize.Y) ] +SOverlay::Slot() .HAlign(HAlign_Fill) .VAlign(VAlign_Fill) [ SNew(SBorder) .BorderImage(CircleBrush) .BorderBackgroundColor(FLinearColor::Gray) .Padding(FMargin(4.0f)) .VAlign(VAlign_Center) .HAlign(HAlign_Center) [ SNew(STextBlock) .Font(FCoreStyle::GetDefaultFontStyle("Regular", 8)) .Text(this, &SEdComboActionGraphNode::GetIndexText) .Visibility(this, &SEdComboActionGraphNode::GetIndexSlotVisibility) ] ] ]; this->GetOrAddSlot(ENodeZone::Center) .HAlign(HAlign_Fill) .VAlign(VAlign_Fill) [ SNew(SBox) [ // OUTER STYLE SNew(SBorder) .BorderImage(this, &SEdComboActionGraphNode::GetNodeTypeBrush) .Padding(3.0f) .BorderBackgroundColor(this, &SEdComboActionGraphNode::GetBorderBackgroundColor) [ SNew(SOverlay) // Adding some colours so its not so boring + SOverlay::Slot() .HAlign(HAlign_Fill) .VAlign(VAlign_Fill) [ // INNER STYLE SNew(SBorder) .BorderImage(this, &SEdComboActionGraphNode::GetNodeTypeBrush) .HAlign(HAlign_Fill) .VAlign(VAlign_Center) .Visibility(EVisibility::SelfHitTestInvisible) .BorderBackgroundColor(this, &SEdComboActionGraphNode::GetBorderFrontColor) ] // Pins and node details + SOverlay::Slot() .HAlign(HAlign_Fill) .VAlign(VAlign_Fill) [ SNew(SVerticalBox) // INPUT PIN AREA + SVerticalBox::Slot() .AutoHeight() [ SNew(SBox) .MinDesiredHeight(NodePadding.Top) [ SAssignNew(LeftNodeBox, SVerticalBox) ] ] + SVerticalBox::Slot() .AutoHeight() [ SNew(SSpacer) .Size(FVector2D(0.f, 10.f)) ] + SVerticalBox::Slot() .Padding(FMargin(NodePadding.Left, 0.0f, NodePadding.Right, 0.0f)) .VAlign(VAlign_Fill) [ SNew(SVerticalBox) #pragma region Stack + SVerticalBox::Slot() .HAlign(HAlign_Fill) .VAlign(VAlign_Fill) [ SNew(SBox) .MinDesiredWidth(FOptionalSize(145.f)) .Visibility(this, &SEdComboActionGraphNode::GetStackVisibility) [ SNew(SVerticalBox) #pragma region InheritanceOnly + SVerticalBox::Slot() .VAlign(VAlign_Fill) [ SNew(SBorder) .BorderImage(this, &SEdComboActionGraphNode::GetTextNodeTypeBrush) .BorderBackgroundColor(this, &SEdComboActionGraphNode::GetDecoratorsBackgroundColor) .HAlign(HAlign_Fill) .VAlign(VAlign_Fill) .Visibility(this, &SEdComboActionGraphNode::ShowInheritsDecoratorsSlot_Stack) [ SNew(SVerticalBox) + SVerticalBox::Slot() [ SNew(SHorizontalBox) + SHorizontalBox::Slot() .Padding(FMargin(4.0f, 0.f, 4.0f, 0.f)) .HAlign(HAlign_Fill) [ SNew(STextBlock) .Text(this, &SEdComboActionGraphNode::GetDecoratorsInheritanceText) .Justification(ETextJustify::Center) ] ] ] ] #pragma endregion #pragma region ImplementsOnly + SVerticalBox::Slot() .VAlign(VAlign_Fill) [ SNew(SBorder) .BorderImage(this, &SEdComboActionGraphNode::GetTextNodeTypeBrush) .BorderBackgroundColor(this, &SEdComboActionGraphNode::GetDecoratorsBackgroundColor) .HAlign(HAlign_Fill) .VAlign(VAlign_Fill) .Visibility(this, &SEdComboActionGraphNode::ShowImplementsOnlySlot_Stack) [ SNew(SVerticalBox) + SVerticalBox::Slot() [ SNew(SHorizontalBox) + SHorizontalBox::Slot() .HAlign(HAlign_Fill) .Padding(FMargin(4.0f, 0.f, 4.0f, 0.f)) [ SNew(STextBlock) .Text(this, &SEdComboActionGraphNode::GetDecoratorsText) .Justification(ETextJustify::Center) ] ] ] ] #pragma endregion ] ] #pragma endregion + SVerticalBox::Slot() .AutoHeight() [ SAssignNew(NodeBody, SBorder) .BorderImage(this, &SEdComboActionGraphNode::GetTextNodeTypeBrush) .BorderBackgroundColor(this, &SEdComboActionGraphNode::GetNodeTitleBackgroundColor) .HAlign(HAlign_Fill) .VAlign(VAlign_Center) .Visibility(EVisibility::SelfHitTestInvisible) [ SNew(SBox) .MinDesiredWidth(FOptionalSize(145.f)) [ SNew(SVerticalBox) + SVerticalBox::Slot() .AutoHeight() [ SNew(SOverlay) + SOverlay::Slot() .HAlign(HAlign_Center) .VAlign(VAlign_Fill) [ SNew(SVerticalBox) #pragma region NameSlot // NAME SLOT + SVerticalBox::Slot() .AutoHeight() .HAlign(HAlign_Center) [ SNew(SHorizontalBox) + SHorizontalBox::Slot() .AutoWidth() [ // POPUP ERROR MESSAGE SAssignNew(ErrorText, SErrorText) .BackgroundColor( this, &SEdComboActionGraphNode::GetErrorColor) .ToolTipText( this, &SEdComboActionGraphNode::GetErrorMsgToolTip) ] + SHorizontalBox::Slot() .AutoWidth() .HAlign(HAlign_Center) [ SNew(SHorizontalBox) + SHorizontalBox::Slot() .Padding(FMargin(4.0f, 0.0f, 4.0f, 0.0f)) [ SNew(SVerticalBox) + SVerticalBox::Slot() .HAlign(HAlign_Center) .AutoHeight() [ SAssignNew(InlineEditableText, SInlineEditableTextBlock) .Style(FComboActionGraphEditorStyle::Get(), "MDSStyleSet.NodeTitleInlineEditableText") .Text(NodeTitle.Get(), &SNodeTitle::GetHeadTitle) .OnVerifyTextChanged( this, &SEdComboActionGraphNode::OnVerifyNameTextChanged) .OnTextCommitted( this, &SEdComboActionGraphNode::OnNameTextCommitted) .IsReadOnly(this, &SEdComboActionGraphNode::IsNameReadOnly) .IsSelected(this, &SEdComboActionGraphNode::IsSelectedExclusively) .Justification(ETextJustify::Center) .Visibility(EVisibility::Visible) ] + SVerticalBox::Slot() .AutoHeight() [ NodeTitle.ToSharedRef() ] ] ] ] #pragma endregion ] ] #pragma region Unified + SVerticalBox::Slot() .VAlign(VAlign_Fill) [ SNew(SBox) .Visibility(this, &SEdComboActionGraphNode::GetUnifiedVisibility) .HAlign(HAlign_Fill) [ SNew(SVerticalBox) + SVerticalBox::Slot() [ SNew(SBox) .Visibility(this, &SEdComboActionGraphNode::ShowDecoratorsBottomPadding) [ SNew(SSpacer) .Size(FVector2D(0.f, 2.5f)) ] ] #pragma region InheritanceOnly // INHERITS ONLY + SVerticalBox::Slot() .AutoHeight() .HAlign(HAlign_Fill) .VAlign(VAlign_Fill) .Padding(FMargin(8.0f, 0.f, 8.0f, 0.f)) [ SNew(SBox) .Visibility(this, &SEdComboActionGraphNode::ShowInheritsDecoratorsSlot_Unified) .MaxDesiredWidth(FOptionalSize(130.f)) .HAlign(HAlign_Fill) [ SNew(SGridPanel) .Visibility(EVisibility::HitTestInvisible) .FillColumn(0, 2.f) .FillColumn(1, 1.f) #pragma region Title + SGridPanel::Slot(0,0) .HAlign(HAlign_Fill) [ SNew(STextBlock) .Text(LOCTEXT("A", "DECORATORS")) .Font(FCoreStyle::GetDefaultFontStyle("Bold", 8)) .ColorAndOpacity(DefaultFontColor) ] #pragma endregion #pragma region Inherits + SGridPanel::Slot(0,1) .HAlign(HAlign_Fill) .Padding(UnifiedRowsPadding) [ SNew(SBox) .Visibility(this, &SEdComboActionGraphNode::ShowInheritsDecoratorsSlot_Unified) .HAlign(HAlign_Left) [ SNew(SScaleBox) .Stretch(EStretch::ScaleToFit) [ SNew(SHorizontalBox) +SHorizontalBox::Slot() .HAlign(HAlign_Fill) .VAlign(VAlign_Center) [ SNew(SScaleBox) .HAlign(HAlign_Left) .VAlign(VAlign_Center) .Stretch(EStretch::ScaleToFit) [ SNew(SBox) .MaxAspectRatio(FOptionalSize(1)) .MaxDesiredHeight(FOptionalSize(6.f)) .MaxDesiredWidth(FOptionalSize(6.f)) [ SNew(SImage) .Image(this, &SEdComboActionGraphNode::GetBulletPointImageBrush) ] ] ] +SHorizontalBox::Slot() [ SNew(SSpacer) .Size(FVector2D(1.f, 0.f)) ] +SHorizontalBox::Slot() .HAlign(HAlign_Fill) .AutoWidth() [ SNew(STextBlock) .Text(LOCTEXT("B", "inherits")) .Font(FCoreStyle::GetDefaultFontStyle("Regular", 8)) .Justification(ETextJustify::Left) .ColorAndOpacity(DefaultFontColor) ] ] ] ] + SGridPanel::Slot(1,1) .HAlign(HAlign_Right) .VAlign(VAlign_Center) .Padding(UnifiedRowsPadding) [ SNew(SScaleBox) .Stretch(EStretch::ScaleToFit) .HAlign(HAlign_Center) [ SNew(SBox) .Visibility(this, &SEdComboActionGraphNode::ShowInheritsDecoratorsSlot_Unified) .MaxAspectRatio(FOptionalSize(1)) .MaxDesiredHeight(FOptionalSize(12.f)) .MaxDesiredWidth(FOptionalSize(12.f)) [ SNew(SImage) .Image(this, &SEdComboActionGraphNode::GetInheritsImageBrush) .ColorAndOpacity(this, &SEdComboActionGraphNode::GetInheritsImageTint) ] ] ] #pragma endregion ] ] #pragma endregion #pragma region ImplementsOnly // IMPLEMENTS ONLY + SVerticalBox::Slot() + SVerticalBox::Slot() .AutoHeight() .HAlign(HAlign_Fill) .VAlign(VAlign_Fill) .Padding(FMargin(8.0f, 0.f, 8.0f, 0.f)) [ SNew(SBox) .Visibility(this, &SEdComboActionGraphNode::ShowImplementsOnlySlot_Unified) .MaxDesiredWidth(FOptionalSize(130.f)) .HAlign(HAlign_Fill) [ SNew(SGridPanel) .Visibility(EVisibility::HitTestInvisible) .FillColumn(0, 2.f) .FillColumn(1, 1.f) #pragma region Title + SGridPanel::Slot(0,0) .HAlign(HAlign_Fill) [ SNew(STextBlock) .Text(LOCTEXT("A", "DECORATORS")) .Font(FCoreStyle::GetDefaultFontStyle("Bold", 8)) .ColorAndOpacity(DefaultFontColor) ] #pragma endregion #pragma region Implements + SGridPanel::Slot(0,1) .HAlign(HAlign_Fill) .Padding(UnifiedRowsPadding) [ SNew(SBox) .Visibility(this, &SEdComboActionGraphNode::ShowImplementsOnlySlot_Unified) .HAlign(HAlign_Left) [ SNew(SScaleBox) .Stretch(EStretch::ScaleToFit) [ SNew(SHorizontalBox) +SHorizontalBox::Slot() .HAlign(HAlign_Fill) .VAlign(VAlign_Center) [ SNew(SScaleBox) .HAlign(HAlign_Left) .VAlign(VAlign_Center) .Stretch(EStretch::ScaleToFit) [ SNew(SBox) .MaxAspectRatio(FOptionalSize(1)) .MaxDesiredHeight(FOptionalSize(6.f)) .MaxDesiredWidth(FOptionalSize(6.f)) [ SNew(SImage) .Image(this, &SEdComboActionGraphNode::GetBulletPointImageBrush) .ColorAndOpacity(this, &SEdComboActionGraphNode::GetBulletPointsImagePointColor) ] ] ] +SHorizontalBox::Slot() [ SNew(SSpacer) .Size(FVector2D(1.f, 0.f)) ] +SHorizontalBox::Slot() .HAlign(HAlign_Fill) .AutoWidth() [ SNew(STextBlock) .Text(LOCTEXT("C", "implements")) .Font(FCoreStyle::GetDefaultFontStyle("Regular", 8)) .Justification(ETextJustify::Left) .ColorAndOpacity(this, &SEdComboActionGraphNode::GetImplementsRowColor) ] ] ] ] + SGridPanel::Slot(1,1) .HAlign(HAlign_Right) .VAlign(VAlign_Center) .Padding(UnifiedRowsPadding) [ SNew(SOverlay) +SOverlay::Slot() [ SNew(SScaleBox) .Stretch(EStretch::ScaleToFit) .HAlign(HAlign_Center) [ SNew(SBox) .Visibility(this, &SEdComboActionGraphNode::ShowImplementsOnlySlot_Unified) .MaxAspectRatio(FOptionalSize(1)) .MaxDesiredHeight(FOptionalSize(12.f)) .MaxDesiredWidth(FOptionalSize(12.f)) .WidthOverride(12.f) ] ] +SOverlay::Slot() .HAlign(HAlign_Center) [ SNew(STextBlock) .Text(this, &SEdComboActionGraphNode::GetNumberOfDecorators) .Font(FCoreStyle::GetDefaultFontStyle("Regular", 8)) .ColorAndOpacity(this, &SEdComboActionGraphNode::GetImplementsRowColor) .Justification(ETextJustify::Center) ] ] #pragma endregion ] ] #pragma endregion #pragma region Both // BOTH + SVerticalBox::Slot() .AutoHeight() .HAlign(HAlign_Fill) .VAlign(VAlign_Fill) .Padding(FMargin(8.0f, 0.f, 8.0f, 0.f)) [ SNew(SBox) .Visibility(this, &SEdComboActionGraphNode::ShowAllDecorators) .MaxDesiredWidth(FOptionalSize(130.f)) .HAlign(HAlign_Fill) [ SNew(SGridPanel) .Visibility(EVisibility::HitTestInvisible) .FillColumn(0, 2.f) .FillColumn(1, 1.f) #pragma region Title + SGridPanel::Slot(0,0) .HAlign(HAlign_Fill) [ SNew(STextBlock) .Text(LOCTEXT("A", "DECORATORS")) .Font(FCoreStyle::GetDefaultFontStyle("Bold", 8)) .ColorAndOpacity(DefaultFontColor) ] #pragma endregion #pragma region Inherits + SGridPanel::Slot(0,1) .HAlign(HAlign_Fill) .Padding(UnifiedRowsPadding) [ SNew(SBox) .Visibility(this, &SEdComboActionGraphNode::ShowAllDecorators) .HAlign(HAlign_Left) [ SNew(SScaleBox) .Stretch(EStretch::ScaleToFit) [ SNew(SHorizontalBox) +SHorizontalBox::Slot() .HAlign(HAlign_Fill) .VAlign(VAlign_Center) [ SNew(SScaleBox) .HAlign(HAlign_Left) .VAlign(VAlign_Center) .Stretch(EStretch::ScaleToFit) [ SNew(SBox) .MaxAspectRatio(FOptionalSize(1)) .MaxDesiredHeight(FOptionalSize(6.f)) .MaxDesiredWidth(FOptionalSize(6.f)) [ SNew(SImage) .Image(this, &SEdComboActionGraphNode::GetBulletPointImageBrush) ] ] ] +SHorizontalBox::Slot() [ SNew(SSpacer) .Size(FVector2D(1.f, 0.f)) ] +SHorizontalBox::Slot() .HAlign(HAlign_Fill) .AutoWidth() [ SNew(STextBlock) .Text(LOCTEXT("B", "inherits")) .Font(FCoreStyle::GetDefaultFontStyle("Regular", 8)) .Justification(ETextJustify::Left) .ColorAndOpacity(DefaultFontColor) ] ] ] ] + SGridPanel::Slot(1,1) .HAlign(HAlign_Right) .VAlign(VAlign_Center) .Padding(UnifiedRowsPadding) [ SNew(SScaleBox) .Stretch(EStretch::ScaleToFit) .HAlign(HAlign_Center) [ SNew(SBox) .Visibility(this, &SEdComboActionGraphNode::ShowAllDecorators) .MaxAspectRatio(FOptionalSize(1)) .MaxDesiredHeight(FOptionalSize(12.f)) .MaxDesiredWidth(FOptionalSize(12.f)) [ SNew(SImage) .Image(this, &SEdComboActionGraphNode::GetInheritsImageBrush) .ColorAndOpacity(this, &SEdComboActionGraphNode::GetInheritsImageTint) ] ] ] #pragma endregion #pragma region Implements + SGridPanel::Slot(0,2) .HAlign(HAlign_Fill) .Padding(UnifiedRowsPadding) [ SNew(SBox) .Visibility(this, &SEdComboActionGraphNode::ShowAllDecorators) .HAlign(HAlign_Left) [ SNew(SScaleBox) .Stretch(EStretch::ScaleToFit) [ SNew(SHorizontalBox) +SHorizontalBox::Slot() .HAlign(HAlign_Fill) .VAlign(VAlign_Center) [ SNew(SScaleBox) .HAlign(HAlign_Left) .VAlign(VAlign_Center) .Stretch(EStretch::ScaleToFit) [ SNew(SBox) .MaxAspectRatio(FOptionalSize(1)) .MaxDesiredHeight(FOptionalSize(6.f)) .MaxDesiredWidth(FOptionalSize(6.f)) [ SNew(SImage) .Image(this, &SEdComboActionGraphNode::GetBulletPointImageBrush) .ColorAndOpacity(this, &SEdComboActionGraphNode::GetBulletPointsImagePointColor) ] ] ] +SHorizontalBox::Slot() [ SNew(SSpacer) .Size(FVector2D(1.f, 0.f)) ] +SHorizontalBox::Slot() .HAlign(HAlign_Fill) .AutoWidth() [ SNew(STextBlock) .Text(LOCTEXT("C", "implements")) .Font(FCoreStyle::GetDefaultFontStyle("Regular", 8)) .Justification(ETextJustify::Left) .ColorAndOpacity(this, &SEdComboActionGraphNode::GetImplementsRowColor) ] ] ] ] + SGridPanel::Slot(1,2) .HAlign(HAlign_Right) .VAlign(VAlign_Center) .Padding(UnifiedRowsPadding) [ SNew(SOverlay) +SOverlay::Slot() [ SNew(SScaleBox) .Stretch(EStretch::ScaleToFit) .HAlign(HAlign_Center) [ SNew(SBox) .Visibility(this, &SEdComboActionGraphNode::ShowAllDecorators) .MaxAspectRatio(FOptionalSize(1)) .MaxDesiredHeight(FOptionalSize(12.f)) .MaxDesiredWidth(FOptionalSize(12.f)) .WidthOverride(12.f) ] ] +SOverlay::Slot() .HAlign(HAlign_Center) [ SNew(STextBlock) .Text(this, &SEdComboActionGraphNode::GetNumberOfDecorators) .Font(FCoreStyle::GetDefaultFontStyle("Regular", 8)) .ColorAndOpacity(this, &SEdComboActionGraphNode::GetImplementsRowColor) .Justification(ETextJustify::Center) ] ] #pragma endregion ] ] #pragma endregion + SVerticalBox::Slot() .HAlign(HAlign_Center) .VAlign(VAlign_Fill) [ SNew(SSpacer) .Size(FVector2D(0.f, 2.5f)) ] ] ] #pragma endregion ] ] ] ] + SVerticalBox::Slot() .AutoHeight() [ SNew(SSpacer) .Size(FVector2D(0.f, 10.f)) ] // OUTPUT PIN AREA + SVerticalBox::Slot() .AutoHeight() [ SNew(SBox) .MinDesiredHeight(NodePadding.Bottom) [ SAssignNew(RightNodeBox, SVerticalBox) + SVerticalBox::Slot() .HAlign(HAlign_Fill) .VAlign(VAlign_Fill) .Padding(20.0f, 0.0f) .FillHeight(1.0f) [ SAssignNew(OutputPinBox, SHorizontalBox) ] ] ] ] ] ] ]; // Create comment bubble TSharedPtr CommentBubble; const FSlateColor CommentColor = GetDefault()->DefaultCommentNodeTitleColor; SAssignNew(CommentBubble, SCommentBubble) .GraphNode(GraphNode) .Text(this, &SGraphNode::GetNodeComment) .OnTextCommitted(this, &SGraphNode::OnCommentTextCommitted) .ColorAndOpacity(CommentColor) .AllowPinning(true) .EnableTitleBarBubble(true) .EnableBubbleCtrls(true) .GraphLOD(this, &SGraphNode::GetCurrentLOD) .IsGraphNodeHovered(this, &SGraphNode::IsHovered); GetOrAddSlot(ENodeZone::TopCenter) .SlotOffset(TAttribute(CommentBubble.Get(), &SCommentBubble::GetOffset)) .SlotSize(TAttribute(CommentBubble.Get(), &SCommentBubble::GetSize)) .AllowScaling(TAttribute(CommentBubble.Get(), &SCommentBubble::IsScalingAllowed)) .VAlign(VAlign_Top) [ CommentBubble.ToSharedRef() ]; ErrorReporting = ErrorText; ErrorReporting->SetError(ErrorMsg); CreatePinWidgets(); } void SEdComboActionGraphNode::CreatePinWidgets() { UEdComboActionGraphNode *StateNode = CastChecked(GraphNode); for (int32 PinIdx = 0; PinIdx < StateNode->Pins.Num(); PinIdx++) { UEdGraphPin* MyPin = StateNode->Pins[PinIdx]; if (!MyPin->bHidden) { TSharedPtr NewPin = SNew(SComboActionGraphPin, MyPin); AddPin(NewPin.ToSharedRef()); } } } void SEdComboActionGraphNode::AddPin(const TSharedRef& PinToAdd) { PinToAdd->SetOwner(SharedThis(this)); const UEdGraphPin* PinObj = PinToAdd->GetPinObj(); const bool bAdvancedParameter = PinObj && PinObj->bAdvancedView; if (bAdvancedParameter) { PinToAdd->SetVisibility( TAttribute(PinToAdd, &SGraphPin::IsPinVisibleAsAdvanced) ); } if (PinToAdd->GetDirection() == EEdGraphPinDirection::EGPD_Input) { LeftNodeBox->AddSlot() .HAlign(HAlign_Fill) .VAlign(VAlign_Fill) .FillHeight(1.0f) .Padding(20.0f,0.0f) [ PinToAdd ]; InputPins.Add(PinToAdd); } else // Direction == EEdGraphPinDirection::EGPD_Output { OutputPinBox->AddSlot() .HAlign(HAlign_Fill) .VAlign(VAlign_Fill) .FillWidth(1.0f) [ PinToAdd ]; OutputPins.Add(PinToAdd); } } bool SEdComboActionGraphNode::IsNameReadOnly() const { UEdComboActionGraphNode *EdNode_Node = Cast(this->GraphNode); check(EdNode_Node != nullptr); UComboActionGraph *ComboActionGraphNode = EdNode_Node->ComboActionGraphNode->Graph; check(this->GraphNode != nullptr); return !this->GraphNode->bCanRenameNode || SGraphNode::IsNameReadOnly(); } END_SLATE_FUNCTION_BUILD_OPTIMIZATION void SEdComboActionGraphNode::OnNameTextCommitted(const FText& InText, ETextCommit::Type CommitInfo) { if (InText.IsEmpty()) return; SGraphNode::OnNameTextCommited(InText, CommitInfo); UEdComboActionGraphNode *MyNode = CastChecked(GraphNode); if (MyNode != nullptr && MyNode->ComboActionGraphNode != nullptr) { const FScopedTransaction Transaction(LOCTEXT("ComboActionGraphEditorRenameNode", "Combo Action Editor: Rename Node")); MyNode->Modify(); MyNode->ComboActionGraphNode->Modify(); MyNode->ComboActionGraphNode->SetNodeTitle(InText); UpdateGraphNode(); } } const FSlateBrush *SEdComboActionGraphNode::GetNodeTypeBrush() const { if (GraphEditorSettings) { switch (GraphEditorSettings->GetNodeType()) { case EComboActionNodeType::SoftCorners: return FComboActionGraphEditorStyle::GetBrush("MDSStyleSet.Node.SoftEdges"); case EComboActionNodeType::HardCorners: return FComboActionGraphEditorStyle::GetBrush("MDSStyleSet.Node.HardEdges"); } } return FComboActionGraphEditorStyle::GetBrush("MDSStyleSet.Node.SoftEdges"); } const FSlateBrush *SEdComboActionGraphNode::GetTextNodeTypeBrush() const { if (GraphEditorSettings) { switch (GraphEditorSettings->GetNodeType()) { case EComboActionNodeType::SoftCorners: return FComboActionGraphEditorStyle::GetBrush("MDSStyleSet.Node.TextSoftEdges"); case EComboActionNodeType::HardCorners: return FComboActionGraphEditorStyle::GetBrush("MDSStyleSet.Node.TextHardEdges"); } } return FComboActionGraphEditorStyle::GetBrush("MDSStyleSet.Node.TextSoftEdges"); } FSlateColor SEdComboActionGraphNode::GetBorderBackgroundColor() const { UEdComboActionGraphNode *MyNode = CastChecked(this->GraphNode); return MyNode ? MyNode->GetBackgroundColor() : ComboActionGraphColors::NodeBorder::HighlightAbortRange0; } FSlateColor SEdComboActionGraphNode::GetBorderFrontColor() const { if (GraphEditorSettings) { switch (GraphEditorSettings->GetNodeTheme()) { case EComboActionNodeTheme::DarkTheme: return ComboActionGraphColors::Overlay::DarkTheme; case EComboActionNodeTheme::LightTheme: return ComboActionGraphColors::Overlay::LightTheme; } } return ComboActionGraphColors::Overlay::DarkTheme; } FSlateColor SEdComboActionGraphNode::GetNodeTitleBackgroundColor() const { return ComboActionGraphColors::NodeBody::Default; } FSlateColor SEdComboActionGraphNode::GetDecoratorsBackgroundColor() const { return ComboActionGraphColors::DecoratorsBody::Default; } FSlateColor SEdComboActionGraphNode::GetPinsDockColor() const { if (GraphEditorSettings) { switch (GraphEditorSettings->GetNodeTheme()) { case EComboActionNodeTheme::DarkTheme: return ComboActionGraphColors::PinsDock::DarkTheme; case EComboActionNodeTheme::LightTheme: return ComboActionGraphColors::PinsDock::LightTheme; } } return ComboActionGraphColors::Overlay::DarkTheme; } EVisibility SEdComboActionGraphNode::GetDragOverMarkerVisibility() const { return EVisibility::Visible; } const FSlateBrush*SEdComboActionGraphNode::GetNameIcon() const { return FAppStyle::GetBrush(TEXT("BTEditor.Graph.BTNode.Icon")); } const FSlateBrush*SEdComboActionGraphNode::GetInheritsImageBrush() const { bool bHasDecorators = false; if (const UEdComboActionGraphNode *EdParentNode = Cast(this->GraphNode)) { if (EdParentNode->ComboActionGraphNode) { bHasDecorators = EdParentNode->ComboActionGraphNode->DoesInheritDecorators() ; } } return FComboActionGraphEditorStyle::GetBrush( bHasDecorators ? "MDSStyleSet.Icon.OK" : "MDSStyleSet.Icon.Error" ); } FSlateColor SEdComboActionGraphNode::GetInheritsImageTint() const { bool bHasDecorators = false; if (const UEdComboActionGraphNode *EdParentNode = Cast(GraphNode)) { if (EdParentNode->ComboActionGraphNode) { bHasDecorators = EdParentNode->ComboActionGraphNode->DoesInheritDecorators() ; } } return bHasDecorators ? FSlateColor(FLinearColor::Green) : FSlateColor(FLinearColor::Red); } const FSlateBrush*SEdComboActionGraphNode::GetBulletPointImageBrush() const { return FComboActionGraphEditorStyle::GetBrush( "MDSStyleSet.Icon.BulletPoint" ); } FText SEdComboActionGraphNode::GetIndexOverlayTooltipText() const { return LOCTEXT("NodeIndexTooltip", "Node index"); } FText SEdComboActionGraphNode::GetIndexText() const { if (const UEdComboActionGraphNode *EdParentNode = Cast(GraphNode)) { if (const auto Node = EdParentNode->ComboActionGraphNode) { if (const auto Graph = Node->Graph) { const int32 Index = Graph->AllNodes.Find(Node); return FText::AsNumber(Index); } return FText::AsNumber(EdParentNode->ComboActionGraphNode->GetNodeIndex()); } } return FText::AsNumber(INDEX_NONE); } EVisibility SEdComboActionGraphNode::GetIndexSlotVisibility() const { if (IsHovered()) { return EVisibility::SelfHitTestInvisible; } return EVisibility::Collapsed; } FVector2D SEdComboActionGraphNode::GetIndexSlotOffset() const { if (IsHovered()) { return FVector2D(-20.f); } return FVector2D(-15.f); } FVector2D SEdComboActionGraphNode::GetIndexSlotSize() const { if (IsHovered()) { return FVector2D(24.f); } return FVector2D(12.f); } void SEdComboActionGraphNode::OnIndexHoverStateChanged(bool bArg) const { // TODO something } FSlateColor SEdComboActionGraphNode::GetOverlayWidgetBackgroundColor(bool bArg) const { return bArg ? ComboActionGraphColors::IndexBorder::HoveredState : ComboActionGraphColors::IndexBorder::NormalState; } bool SEdComboActionGraphNode::HasGraphDecorators() const { if (const UEdComboActionGraphNode *EdParentNode = Cast(GraphNode)) { if (EdParentNode->ComboActionGraphNode && EdParentNode->ComboActionGraphNode->Graph) { for (const auto& Itr : EdParentNode->ComboActionGraphNode->Graph->GetGraphDecorators()) { if (Itr.DecoratorType != nullptr) { return true; } } } } return false; } bool SEdComboActionGraphNode::HasNodeDecorators() const { if (const UEdComboActionGraphNode *EdParentNode = Cast(GraphNode)) { if (EdParentNode->ComboActionGraphNode) { if (EdParentNode->ComboActionGraphNode->GetNodeDecorators().Num() > 0) { bool bAllValid = true; for (const auto& Itr : EdParentNode->ComboActionGraphNode->GetNodeDecorators()) { if (Itr.DecoratorType == nullptr) { bAllValid = false; } } return bAllValid; } } } return false; } EVisibility SEdComboActionGraphNode::ShowImplementsOnlySlot_Unified() const { if (GraphEditorSettings) { if (GraphEditorSettings->ShowDetailedInfo_NumDecorators() && !GraphEditorSettings->ShowDetailedInfo_InheritsDecorators()) { return EVisibility::SelfHitTestInvisible; //return HasGraphDecorators() ? EVisibility::Visible : EVisibility::Collapsed; } } return EVisibility::Collapsed; } FText SEdComboActionGraphNode::GetDecoratorsText() const { if (const UEdComboActionGraphNode *EdParentNode = Cast(GraphNode)) { if (EdParentNode->ComboActionGraphNode) { FString Number = FString::FromInt(EdParentNode->ComboActionGraphNode->GetNodeDecorators().Num()); FString ReturnText = FString(TEXT("DECORATORS: ")); return FText::FromString( ReturnText.Append(Number) ); } } return FText::FromString("DECORATORS: none"); } FText SEdComboActionGraphNode::GetNumberOfDecorators() const { if (const UEdComboActionGraphNode *EdParentNode = Cast(GraphNode)) { if (EdParentNode->ComboActionGraphNode) { const int32 Number = EdParentNode->ComboActionGraphNode->GetNodeDecorators().Num(); if (Number <= 0) return FText::FromString(TEXT("-")); if (Number > 9) return FText::FromString(TEXT("9+")); return FText::FromString(FString::FromInt(Number)); } } return FText::FromString("-"); } EVisibility SEdComboActionGraphNode::ShowInheritsDecoratorsSlot_Unified() const { if (GraphEditorSettings) { if (GraphEditorSettings->GetDecoratorsStyle() == EComboActionDecoratorsInfoStyle::Unified) { if (GraphEditorSettings->ShowDetailedInfo_InheritsDecorators() && !GraphEditorSettings->ShowDetailedInfo_NumDecorators()) { return EVisibility::SelfHitTestInvisible; //return HasGraphDecorators() ? EVisibility::Visible : EVisibility::Collapsed; } } } return EVisibility::Collapsed; } EVisibility SEdComboActionGraphNode::ShowImplementsOnlySlot_Stack() const { if (GraphEditorSettings) { if (GraphEditorSettings->GetDecoratorsStyle() == EComboActionDecoratorsInfoStyle::Stack) { if (GraphEditorSettings->ShowDetailedInfo_NumDecorators()) { return EVisibility::SelfHitTestInvisible; //return HasGraphDecorators() ? EVisibility::Visible : EVisibility::Collapsed; } } } return EVisibility::Collapsed; } EVisibility SEdComboActionGraphNode::ShowInheritsDecoratorsSlot_Stack() const { if (GraphEditorSettings) { if (GraphEditorSettings->GetDecoratorsStyle() == EComboActionDecoratorsInfoStyle::Stack) { if (GraphEditorSettings->ShowDetailedInfo_InheritsDecorators()) { return EVisibility::SelfHitTestInvisible; //return HasGraphDecorators() ? EVisibility::Visible : EVisibility::Collapsed; } } } return EVisibility::Collapsed; } EVisibility SEdComboActionGraphNode::ShowAllDecorators() const { if (GraphEditorSettings) { if (GraphEditorSettings->GetDecoratorsStyle() == EComboActionDecoratorsInfoStyle::Unified) { if (GraphEditorSettings->ShowDetailedInfo_InheritsDecorators() && GraphEditorSettings->ShowDetailedInfo_NumDecorators()) { return EVisibility::SelfHitTestInvisible; //return HasGraphDecorators() ? EVisibility::Visible : EVisibility::Collapsed; } } } return EVisibility::Collapsed; } EVisibility SEdComboActionGraphNode::ShowDecoratorsBottomPadding() const { if (GraphEditorSettings) { if (GraphEditorSettings->ShowDetailedInfo_InheritsDecorators() || GraphEditorSettings->ShowDetailedInfo_NumDecorators()) { return EVisibility::SelfHitTestInvisible; } } return EVisibility::Collapsed; } FSlateColor SEdComboActionGraphNode::GetImplementsRowColor() const { if (const UEdComboActionGraphNode *EdParentNode = Cast(GraphNode)) { if (EdParentNode->ComboActionGraphNode) { if (EdParentNode->ComboActionGraphNode->GetNodeDecorators().Num() > 0) { return ComboActionGraphColors::TextColors::Normal; } return ComboActionGraphColors::TextColors::Disabled; } } return ComboActionGraphColors::TextColors::Normal; } FSlateColor SEdComboActionGraphNode::GetBulletPointsImagePointColor() const { if (const UEdComboActionGraphNode *EdParentNode = Cast(GraphNode)) { if (EdParentNode->ComboActionGraphNode) { if (EdParentNode->ComboActionGraphNode->GetNodeDecorators().Num() > 0) { return ComboActionGraphColors::BulletPointsColors::Normal; } return ComboActionGraphColors::BulletPointsColors::Disabled; } } return ComboActionGraphColors::BulletPointsColors::Normal; } FText SEdComboActionGraphNode::GetDecoratorsInheritanceText() const { if (const UEdComboActionGraphNode *EdParentNode = Cast(GraphNode)) { if (EdParentNode->ComboActionGraphNode) { FString Result = EdParentNode->ComboActionGraphNode->DoesInheritDecorators() ? TEXT("yes") : TEXT("no") ; return FText::FromString( FString(TEXT("INHERITS: ")).Append(Result) ); } } return FText::FromString("invalid"); } EComboActionDecoratorsInfoStyle SEdComboActionGraphNode::GetDecoratorsStyle() const { if (this->GraphEditorSettings) { return GraphEditorSettings->GetDecoratorsStyle(); } if (const auto TempSettings = GetMutableDefault()) { return TempSettings->GetDecoratorsStyle(); } return EComboActionDecoratorsInfoStyle::Stack; } EVisibility SEdComboActionGraphNode::GetStackVisibility() const { if (this->GetDecoratorsStyle() == EComboActionDecoratorsInfoStyle::Stack) { if (GraphEditorSettings) { if (GraphEditorSettings->ShowDetailedInfo_InheritsDecorators() || GraphEditorSettings->ShowDetailedInfo_NumDecorators()) { return EVisibility::SelfHitTestInvisible; } return EVisibility::Collapsed; } const auto TempSettings = GetMutableDefault(); if (TempSettings) return GetDecoratorsStyle() == EComboActionDecoratorsInfoStyle::Stack ? EVisibility::SelfHitTestInvisible : EVisibility::Collapsed; { if (TempSettings->ShowDetailedInfo_InheritsDecorators() || TempSettings->ShowDetailedInfo_NumDecorators()) { return EVisibility::SelfHitTestInvisible; } return EVisibility::Collapsed; } } return EVisibility::Collapsed; } EVisibility SEdComboActionGraphNode::GetUnifiedVisibility() const { return GetDecoratorsStyle() == EComboActionDecoratorsInfoStyle::Unified ? EVisibility::SelfHitTestInvisible : EVisibility::Collapsed; } FText SEdComboActionGraphNode::GetTooltipText() const { if (const UEdComboActionGraphNode *EdParentNode = Cast(GraphNode)) { return EdParentNode->GetTooltipText(); } return LOCTEXT("SEdComboActionGraphNode_Tooltip", "invalid node selected"); } #undef LOCTEXT_NAMESPACE