379 lines
12 KiB
C++
379 lines
12 KiB
C++
#include "DismembermentGraph/SDismembermentGraphNode.h"
|
|
#include "DismembermentGraph/DismembermentGraphNode.h"
|
|
#include "GraphEditorSettings.h"
|
|
#include "SGraphPin.h"
|
|
#include "SlateOptMacros.h"
|
|
#include "Widgets/SBoxPanel.h"
|
|
#include "Widgets/Text/SInlineEditableTextBlock.h"
|
|
#include "Widgets/Images/SImage.h"
|
|
#include "Styling/AppStyle.h"
|
|
|
|
BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION
|
|
|
|
void SDismembermentGraphNode::Construct(const FArguments& InArgs, UEdGraphNode* InNode)
|
|
{
|
|
GraphNode = InNode;
|
|
UpdateGraphNode();
|
|
bIsHovered = false;
|
|
}
|
|
|
|
void SDismembermentGraphNode::UpdateGraphNode()
|
|
{
|
|
// Clear the widget
|
|
ContentScale.Bind(this, &SGraphNode::GetContentScale);
|
|
LeftNodeBox.Reset();
|
|
RightNodeBox.Reset();
|
|
// OutputPinBox.Reset(); // Comment out this line because OutputPinBox is not defined
|
|
|
|
// Setup the node title
|
|
TSharedPtr<SNodeTitle> NodeTitle = SNew(SNodeTitle, GraphNode);
|
|
|
|
// Create the node body
|
|
this->ContentScale.Bind(this, &SGraphNode::GetContentScale);
|
|
this->GetOrAddSlot(ENodeZone::Center)
|
|
.HAlign(HAlign_Center)
|
|
.VAlign(VAlign_Center)
|
|
[
|
|
SNew(SBorder)
|
|
.BorderImage(FAppStyle::GetBrush("Graph.StateNode.Body"))
|
|
.BorderBackgroundColor(this, &SDismembermentGraphNode::GetNodeColor)
|
|
.HAlign(HAlign_Fill)
|
|
.VAlign(VAlign_Fill)
|
|
.Padding(0.0f)
|
|
[
|
|
SNew(SOverlay)
|
|
// Main node body
|
|
+ SOverlay::Slot()
|
|
.HAlign(HAlign_Fill)
|
|
.VAlign(VAlign_Fill)
|
|
[
|
|
SNew(SVerticalBox)
|
|
// Title bar
|
|
+ SVerticalBox::Slot()
|
|
.AutoHeight()
|
|
[
|
|
SNew(SBorder)
|
|
.BorderImage(FAppStyle::GetBrush("Graph.StateNode.ColorSpill"))
|
|
.BorderBackgroundColor(this, &SDismembermentGraphNode::GetNodeTitleColor)
|
|
.HAlign(HAlign_Fill)
|
|
.VAlign(VAlign_Center)
|
|
.Padding(FMargin(10.0f, 5.0f))
|
|
[
|
|
SNew(SHorizontalBox)
|
|
// Node title
|
|
+ SHorizontalBox::Slot()
|
|
.AutoWidth()
|
|
[
|
|
SNew(STextBlock)
|
|
.Text(this, &SDismembermentGraphNode::GetNodeTitle)
|
|
.TextStyle(FAppStyle::Get(), "Graph.StateNode.NodeTitle")
|
|
.Margin(FMargin(0.0f, 0.0f, 4.0f, 0.0f))
|
|
]
|
|
// Node category
|
|
+ SHorizontalBox::Slot()
|
|
.AutoWidth()
|
|
[
|
|
SNew(STextBlock)
|
|
.Text(this, &SDismembermentGraphNode::GetNodeCategory)
|
|
.TextStyle(FAppStyle::Get(), "Graph.StateNode.NodeTitle")
|
|
.ColorAndOpacity(FLinearColor(0.8f, 0.8f, 0.8f))
|
|
.Margin(FMargin(4.0f, 0.0f, 0.0f, 0.0f))
|
|
]
|
|
]
|
|
]
|
|
// Node content
|
|
+ SVerticalBox::Slot()
|
|
.Padding(0.0f)
|
|
.AutoHeight()
|
|
[
|
|
SNew(SBorder)
|
|
.BorderImage(FAppStyle::GetBrush("NoBorder"))
|
|
.HAlign(HAlign_Fill)
|
|
.VAlign(VAlign_Fill)
|
|
.Padding(FMargin(10.0f, 0.0f))
|
|
[
|
|
SNew(SVerticalBox)
|
|
// Node description
|
|
+ SVerticalBox::Slot()
|
|
.AutoHeight()
|
|
.Padding(FMargin(0.0f, 4.0f))
|
|
[
|
|
SNew(STextBlock)
|
|
.Text(this, &SDismembermentGraphNode::GetNodeDescription)
|
|
.TextStyle(FAppStyle::Get(), "Graph.StateNode.Description")
|
|
.WrapTextAt(200.0f)
|
|
]
|
|
// Node preview
|
|
+ SVerticalBox::Slot()
|
|
.AutoHeight()
|
|
.Padding(FMargin(0.0f, 4.0f))
|
|
[
|
|
GetNodePreviewWidget()
|
|
]
|
|
]
|
|
]
|
|
// Input pins
|
|
+ SVerticalBox::Slot()
|
|
.AutoHeight()
|
|
[
|
|
SAssignNew(LeftNodeBox, SVerticalBox)
|
|
]
|
|
// Output pins
|
|
+ SVerticalBox::Slot()
|
|
.AutoHeight()
|
|
[
|
|
SAssignNew(RightNodeBox, SVerticalBox)
|
|
]
|
|
]
|
|
]
|
|
];
|
|
|
|
// Create all the pins
|
|
CreatePinWidgets();
|
|
}
|
|
|
|
void SDismembermentGraphNode::CreatePinWidgets()
|
|
{
|
|
UDismembermentGraphNode* DismembermentNode = GetDismembermentGraphNode();
|
|
if (!DismembermentNode)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Create the input pins
|
|
for (int32 PinIndex = 0; PinIndex < DismembermentNode->Pins.Num(); PinIndex++)
|
|
{
|
|
UEdGraphPin* Pin = DismembermentNode->Pins[PinIndex];
|
|
if (!Pin->bHidden)
|
|
{
|
|
TSharedPtr<SGraphPin> NewPin = SNew(SGraphPin, Pin);
|
|
AddPin(NewPin.ToSharedRef());
|
|
}
|
|
}
|
|
}
|
|
|
|
void SDismembermentGraphNode::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() == EGPD_Input)
|
|
{
|
|
LeftNodeBox->AddSlot()
|
|
.AutoHeight()
|
|
.HAlign(HAlign_Left)
|
|
.VAlign(VAlign_Center)
|
|
.Padding(10.0f, 4.0f)
|
|
[
|
|
PinToAdd
|
|
];
|
|
InputPins.Add(PinToAdd);
|
|
}
|
|
else // EGPD_Output
|
|
{
|
|
RightNodeBox->AddSlot()
|
|
.AutoHeight()
|
|
.HAlign(HAlign_Right)
|
|
.VAlign(VAlign_Center)
|
|
.Padding(10.0f, 4.0f)
|
|
[
|
|
PinToAdd
|
|
];
|
|
OutputPins.Add(PinToAdd);
|
|
}
|
|
}
|
|
|
|
TSharedPtr<SToolTip> SDismembermentGraphNode::GetComplexTooltip()
|
|
{
|
|
UDismembermentGraphNode* DismembermentNode = GetDismembermentGraphNode();
|
|
if (!DismembermentNode)
|
|
{
|
|
return nullptr;
|
|
}
|
|
|
|
return SNew(SToolTip)
|
|
[
|
|
SNew(SVerticalBox)
|
|
+ SVerticalBox::Slot()
|
|
.AutoHeight()
|
|
.Padding(FMargin(0.0f, 2.0f))
|
|
[
|
|
SNew(STextBlock)
|
|
.Text(DismembermentNode->GetNodeTitle(ENodeTitleType::FullTitle))
|
|
.Font(FCoreStyle::GetDefaultFontStyle("Bold", 12))
|
|
]
|
|
+ SVerticalBox::Slot()
|
|
.AutoHeight()
|
|
.Padding(FMargin(0.0f, 2.0f))
|
|
[
|
|
SNew(STextBlock)
|
|
.Text(DismembermentNode->GetTooltipText())
|
|
.Font(FCoreStyle::GetDefaultFontStyle("Regular", 10))
|
|
]
|
|
];
|
|
}
|
|
|
|
FReply SDismembermentGraphNode::OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
|
|
{
|
|
return FReply::Handled().DetectDrag(SharedThis(this), EKeys::LeftMouseButton);
|
|
}
|
|
|
|
FReply SDismembermentGraphNode::OnMouseButtonUp(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
|
|
{
|
|
return FReply::Handled();
|
|
}
|
|
|
|
FReply SDismembermentGraphNode::OnMouseMove(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
|
|
{
|
|
return FReply::Unhandled();
|
|
}
|
|
|
|
void SDismembermentGraphNode::OnMouseEnter(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
|
|
{
|
|
bIsHovered = true;
|
|
SGraphNode::OnMouseEnter(MyGeometry, MouseEvent);
|
|
}
|
|
|
|
void SDismembermentGraphNode::OnMouseLeave(const FPointerEvent& MouseEvent)
|
|
{
|
|
bIsHovered = false;
|
|
SGraphNode::OnMouseLeave(MouseEvent);
|
|
}
|
|
|
|
UDismembermentGraphNode* SDismembermentGraphNode::GetDismembermentGraphNode() const
|
|
{
|
|
return Cast<UDismembermentGraphNode>(GraphNode);
|
|
}
|
|
|
|
TSharedRef<SWidget> SDismembermentGraphNode::GetNodeTitleWidget()
|
|
{
|
|
UDismembermentGraphNode* DismembermentNode = GetDismembermentGraphNode();
|
|
if (!DismembermentNode)
|
|
{
|
|
return SNew(STextBlock).Text(NSLOCTEXT("SDismembermentGraphNode", "InvalidNode", "Invalid Node"));
|
|
}
|
|
|
|
return SNew(STextBlock)
|
|
.Text(DismembermentNode->GetNodeTitle(ENodeTitleType::FullTitle))
|
|
.TextStyle(FAppStyle::Get(), "Graph.StateNode.NodeTitle");
|
|
}
|
|
|
|
TSharedRef<SWidget> SDismembermentGraphNode::GetNodeBodyWidget()
|
|
{
|
|
UDismembermentGraphNode* DismembermentNode = GetDismembermentGraphNode();
|
|
if (!DismembermentNode)
|
|
{
|
|
return SNew(STextBlock).Text(NSLOCTEXT("SDismembermentGraphNode", "InvalidNode", "Invalid Node"));
|
|
}
|
|
|
|
return SNew(STextBlock)
|
|
.Text(DismembermentNode->GetTooltipText())
|
|
.TextStyle(FAppStyle::Get(), "Graph.StateNode.Description")
|
|
.WrapTextAt(200.0f);
|
|
}
|
|
|
|
TSharedRef<SWidget> SDismembermentGraphNode::GetNodePreviewWidget()
|
|
{
|
|
// This can be customized for different node types to show a preview
|
|
return SNew(SBox)
|
|
.WidthOverride(100.0f)
|
|
.HeightOverride(100.0f)
|
|
.HAlign(HAlign_Center)
|
|
.VAlign(VAlign_Center)
|
|
[
|
|
SNew(SBorder)
|
|
.BorderImage(FAppStyle::GetBrush("Graph.StateNode.Body"))
|
|
.BorderBackgroundColor(FLinearColor(0.1f, 0.1f, 0.1f, 0.5f))
|
|
.HAlign(HAlign_Center)
|
|
.VAlign(VAlign_Center)
|
|
[
|
|
SNew(STextBlock)
|
|
.Text(NSLOCTEXT("SDismembermentGraphNode", "Preview", "Preview"))
|
|
.TextStyle(FAppStyle::Get(), "Graph.StateNode.Description")
|
|
]
|
|
];
|
|
}
|
|
|
|
FSlateColor SDismembermentGraphNode::GetNodeColor() const
|
|
{
|
|
UDismembermentGraphNode* DismembermentNode = GetDismembermentGraphNode();
|
|
if (!DismembermentNode)
|
|
{
|
|
return FLinearColor::Black;
|
|
}
|
|
|
|
FLinearColor NodeColor = DismembermentNode->NodeTitleColor;
|
|
if (IsNodeSelected())
|
|
{
|
|
NodeColor = FLinearColor(1.0f, 0.5f, 0.0f);
|
|
}
|
|
else if (IsNodeHovered())
|
|
{
|
|
NodeColor = NodeColor * 1.2f;
|
|
}
|
|
|
|
return NodeColor;
|
|
}
|
|
|
|
FSlateColor SDismembermentGraphNode::GetNodeTitleColor() const
|
|
{
|
|
UDismembermentGraphNode* DismembermentNode = GetDismembermentGraphNode();
|
|
if (!DismembermentNode)
|
|
{
|
|
return FLinearColor::Black;
|
|
}
|
|
|
|
return DismembermentNode->NodeTitleColor.LinearRGBToHSV();
|
|
}
|
|
|
|
FText SDismembermentGraphNode::GetNodeTitle() const
|
|
{
|
|
UDismembermentGraphNode* DismembermentNode = GetDismembermentGraphNode();
|
|
if (!DismembermentNode)
|
|
{
|
|
return NSLOCTEXT("SDismembermentGraphNode", "InvalidNode", "Invalid Node");
|
|
}
|
|
|
|
return DismembermentNode->GetNodeTitle(ENodeTitleType::FullTitle);
|
|
}
|
|
|
|
FText SDismembermentGraphNode::GetNodeCategory() const
|
|
{
|
|
UDismembermentGraphNode* DismembermentNode = GetDismembermentGraphNode();
|
|
if (!DismembermentNode)
|
|
{
|
|
return FText::GetEmpty();
|
|
}
|
|
|
|
return DismembermentNode->NodeCategory;
|
|
}
|
|
|
|
FText SDismembermentGraphNode::GetNodeDescription() const
|
|
{
|
|
UDismembermentGraphNode* DismembermentNode = GetDismembermentGraphNode();
|
|
if (!DismembermentNode)
|
|
{
|
|
return FText::GetEmpty();
|
|
}
|
|
|
|
return DismembermentNode->NodeDescription;
|
|
}
|
|
|
|
bool SDismembermentGraphNode::IsNodeSelected() const
|
|
{
|
|
return GraphNode && GraphNode->IsSelected();
|
|
}
|
|
|
|
bool SDismembermentGraphNode::IsNodeHovered() const
|
|
{
|
|
return bIsHovered;
|
|
}
|
|
|
|
END_SLATE_FUNCTION_BUILD_OPTIMIZATION
|