ComboInput/Source/ComboInputEditor/Private/Ed/SEdComboActionGraphNode.cpp
2023-09-27 12:21:35 -04:00

1452 lines
43 KiB
C++

// ©2023 Batty Bovine Productions, LLC. All Rights Reserved.
#include "SEdComboActionGraphNode.h"
#include "ComboInputEditor.h"
#include "Nodes/ComboActionGraphNode.h"
#include "Helpers/ComboActionGraphColors.h"
#include "Ed/SEdComboActionGraphNodeIndex.h"
#include "Ed/EdComboActionGraphNode.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<UComboActionGraphEditorSettings>())
{
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<SWidget> GetDefaultValueWidget() override
{
return SNew(STextBlock);
}
const FSlateBrush *GetPinBorder() const
{
FComboInputEditorModule &ComboInputEditorModule = FComboInputEditorModule::Get();
if (const UComboActionGraphEditorSettings *GraphEditorSettings = GetMutableDefault<UComboActionGraphEditorSettings>())
{
switch (GraphEditorSettings->GetNodeType())
{
case EComboActionNodeType::SoftCorners:
return ComboInputEditorModule.ComboActionGraphEditorStyleSet->GetBrush("MDSStyleSet.Node.TextSoftEdges");
case EComboActionNodeType::HardCorners:
return ComboInputEditorModule.ComboActionGraphEditorStyleSet->GetBrush("MDSStyleSet.Node.TextHardEdges");
}
}
return ComboInputEditorModule.ComboActionGraphEditorStyleSet->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<UComboActionGraphEditorSettings>();
}
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
{
FComboInputEditorModule &ComboInputEditorModule = FComboInputEditorModule::Get();
return ComboInputEditorModule.ComboActionGraphEditorStyleSet->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<SErrorText> ErrorText;
TSharedPtr<SNodeTitle> NodeTitle = SNew(SNodeTitle, GraphNode);
TSharedPtr<SVerticalBox> StackBox;
TSharedPtr<SVerticalBox> UniformBox;
this->ContentScale.Bind(this, &SGraphNode::GetContentScale);
FComboInputEditorModule &ComboInputEditorModule = FComboInputEditorModule::Get();
const FSlateBrush *CircleBrush = ComboInputEditorModule.ComboActionGraphEditorStyleSet->GetBrush(TEXT("MDSStyleSet.Node.IndexCircle"));
this->GetOrAddSlot(ENodeZone::Left)
.SlotOffset(TAttribute<FVector2D>(this, &SEdComboActionGraphNode::GetIndexSlotOffset))
.SlotSize(TAttribute<FVector2D>(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(ComboInputEditorModule.ComboActionGraphEditorStyleSet.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<SCommentBubble> CommentBubble;
const FSlateColor CommentColor = GetDefault<UGraphEditorSettings>()->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<FVector2D>(CommentBubble.Get(), &SCommentBubble::GetOffset))
.SlotSize(TAttribute<FVector2D>(CommentBubble.Get(), &SCommentBubble::GetSize))
.AllowScaling(TAttribute<bool>(CommentBubble.Get(), &SCommentBubble::IsScalingAllowed))
.VAlign(VAlign_Top)
[
CommentBubble.ToSharedRef()
];
ErrorReporting = ErrorText;
ErrorReporting->SetError(ErrorMsg);
CreatePinWidgets();
}
void SEdComboActionGraphNode::CreatePinWidgets()
{
UEdComboActionGraphNode *StateNode = CastChecked<UEdComboActionGraphNode>(GraphNode);
for (int32 PinIdx = 0; PinIdx < StateNode->Pins.Num(); PinIdx++)
{
UEdGraphPin* MyPin = StateNode->Pins[PinIdx];
if (!MyPin->bHidden)
{
TSharedPtr<SGraphPin> NewPin = SNew(SComboActionGraphPin, MyPin);
AddPin(NewPin.ToSharedRef());
}
}
}
void SEdComboActionGraphNode::AddPin(const TSharedRef<SGraphPin>& PinToAdd)
{
PinToAdd->SetOwner(SharedThis(this));
const UEdGraphPin* PinObj = PinToAdd->GetPinObj();
const bool bAdvancedParameter = PinObj && PinObj->bAdvancedView;
if (bAdvancedParameter)
{
PinToAdd->SetVisibility( TAttribute<EVisibility>(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<UEdComboActionGraphNode>(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<UEdComboActionGraphNode>(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
{
FComboInputEditorModule &ComboInputEditorModule = FComboInputEditorModule::Get();
if (GraphEditorSettings)
{
switch (GraphEditorSettings->GetNodeType())
{
case EComboActionNodeType::SoftCorners:
return ComboInputEditorModule.ComboActionGraphEditorStyleSet->GetBrush("MDSStyleSet.Node.SoftEdges");
case EComboActionNodeType::HardCorners:
return ComboInputEditorModule.ComboActionGraphEditorStyleSet->GetBrush("MDSStyleSet.Node.HardEdges");
}
}
return ComboInputEditorModule.ComboActionGraphEditorStyleSet->GetBrush("MDSStyleSet.Node.SoftEdges");
}
const FSlateBrush *SEdComboActionGraphNode::GetTextNodeTypeBrush() const
{
FComboInputEditorModule &ComboInputEditorModule = FComboInputEditorModule::Get();
if (GraphEditorSettings)
{
switch (GraphEditorSettings->GetNodeType())
{
case EComboActionNodeType::SoftCorners:
return ComboInputEditorModule.ComboActionGraphEditorStyleSet->GetBrush("MDSStyleSet.Node.TextSoftEdges");
case EComboActionNodeType::HardCorners:
return ComboInputEditorModule.ComboActionGraphEditorStyleSet->GetBrush("MDSStyleSet.Node.TextHardEdges");
}
}
return ComboInputEditorModule.ComboActionGraphEditorStyleSet->GetBrush("MDSStyleSet.Node.TextSoftEdges");
}
FSlateColor SEdComboActionGraphNode::GetBorderBackgroundColor() const
{
UEdComboActionGraphNode *MyNode = CastChecked<UEdComboActionGraphNode>(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
{
FComboInputEditorModule &ComboInputEditorModule = FComboInputEditorModule::Get();
bool bHasDecorators = false;
if (const UEdComboActionGraphNode *EdParentNode = Cast<UEdComboActionGraphNode>(this->GraphNode))
{
if (EdParentNode->ComboActionGraphNode)
{
bHasDecorators = EdParentNode->ComboActionGraphNode->DoesInheritDecorators() ;
}
}
return ComboInputEditorModule.ComboActionGraphEditorStyleSet->GetBrush( bHasDecorators ? "MDSStyleSet.Icon.OK" : "MDSStyleSet.Icon.Error" );
}
FSlateColor SEdComboActionGraphNode::GetInheritsImageTint() const
{
bool bHasDecorators = false;
if (const UEdComboActionGraphNode *EdParentNode = Cast<UEdComboActionGraphNode>(GraphNode))
{
if (EdParentNode->ComboActionGraphNode)
{
bHasDecorators = EdParentNode->ComboActionGraphNode->DoesInheritDecorators() ;
}
}
return bHasDecorators ? FSlateColor(FLinearColor::Green) : FSlateColor(FLinearColor::Red);
}
const FSlateBrush*SEdComboActionGraphNode::GetBulletPointImageBrush() const
{
FComboInputEditorModule &ComboInputEditorModule = FComboInputEditorModule::Get();
return ComboInputEditorModule.ComboActionGraphEditorStyleSet->GetBrush( "MDSStyleSet.Icon.BulletPoint" );
}
FText SEdComboActionGraphNode::GetIndexOverlayTooltipText() const
{
return LOCTEXT("NodeIndexTooltip", "Node index");
}
FText SEdComboActionGraphNode::GetIndexText() const
{
if (const UEdComboActionGraphNode *EdParentNode = Cast<UEdComboActionGraphNode>(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<UEdComboActionGraphNode>(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<UEdComboActionGraphNode>(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<UEdComboActionGraphNode>(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<UEdComboActionGraphNode>(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<UEdComboActionGraphNode>(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<UEdComboActionGraphNode>(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<UEdComboActionGraphNode>(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<UComboActionGraphEditorSettings>())
{
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<UComboActionGraphEditorSettings>();
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<UEdComboActionGraphNode>(GraphNode))
{
return EdParentNode->GetTooltipText();
}
return LOCTEXT("SEdComboActionGraphNode_Tooltip", "invalid node selected");
}
#undef LOCTEXT_NAMESPACE