2021-09-01 04:50:52 -04:00
|
|
|
|
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
|
|
|
|
|
|
|
|
#include "ControlRigLocalVariableDetails.h"
|
|
|
|
|
|
|
|
|
|
|
|
#include "DetailWidgetRow.h"
|
|
|
|
|
|
#include "DetailLayoutBuilder.h"
|
|
|
|
|
|
#include "IDetailChildrenBuilder.h"
|
|
|
|
|
|
#include "SPinTypeSelector.h"
|
|
|
|
|
|
#include "Graph/ControlRigGraphSchema.h"
|
|
|
|
|
|
#include "Kismet2/BlueprintEditorUtils.h"
|
2021-09-27 19:54:25 -04:00
|
|
|
|
#include "Widgets/Input/SCheckBox.h"
|
2021-09-01 04:50:52 -04:00
|
|
|
|
#include "Widgets/Input/STextComboBox.h"
|
2021-09-06 04:39:25 -04:00
|
|
|
|
#include "ControlRigBlueprintGeneratedClass.h"
|
2021-09-10 10:04:27 -04:00
|
|
|
|
#include "ControlRigBlueprint.h"
|
2021-09-06 04:39:25 -04:00
|
|
|
|
#include "RigVMCore/RigVM.h"
|
2021-09-01 04:50:52 -04:00
|
|
|
|
|
|
|
|
|
|
#define LOCTEXT_NAMESPACE "LocalVariableDetails"
|
|
|
|
|
|
|
2021-11-11 11:47:13 -05:00
|
|
|
|
void FRigVMLocalVariableDetails::CustomizeDetails(IDetailLayoutBuilder& DetailBuilder)
|
2021-09-01 04:50:52 -04:00
|
|
|
|
{
|
|
|
|
|
|
ObjectsBeingCustomized.Reset();
|
2021-11-11 11:47:13 -05:00
|
|
|
|
|
|
|
|
|
|
TArray<TWeakObjectPtr<UObject>> DetailObjects;
|
|
|
|
|
|
DetailBuilder.GetObjectsBeingCustomized(DetailObjects);
|
|
|
|
|
|
for(TWeakObjectPtr<UObject> DetailObject : DetailObjects)
|
2021-09-01 04:50:52 -04:00
|
|
|
|
{
|
2021-11-11 11:47:13 -05:00
|
|
|
|
UDetailsViewWrapperObject* WrapperObject = CastChecked<UDetailsViewWrapperObject>(DetailObject.Get());
|
2021-09-01 04:50:52 -04:00
|
|
|
|
ObjectsBeingCustomized.Add(WrapperObject);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if(ObjectsBeingCustomized[0].IsValid())
|
|
|
|
|
|
{
|
2021-11-11 11:47:13 -05:00
|
|
|
|
VariableDescription = ObjectsBeingCustomized[0]->GetContent<FRigVMGraphVariableDescription>();
|
2021-09-01 04:50:52 -04:00
|
|
|
|
GraphBeingCustomized = ObjectsBeingCustomized[0]->GetTypedOuter<URigVMGraph>();
|
2021-09-06 04:39:25 -04:00
|
|
|
|
BlueprintBeingCustomized = GraphBeingCustomized->GetTypedOuter<UControlRigBlueprint>();
|
2021-09-14 10:59:08 -04:00
|
|
|
|
|
|
|
|
|
|
NameValidator = FControlRigLocalVariableNameValidator(BlueprintBeingCustomized, GraphBeingCustomized, VariableDescription.Name);
|
2021-09-01 04:50:52 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
2021-11-11 11:47:13 -05:00
|
|
|
|
DetailBuilder.HideCategory(TEXT("RigVMGraphVariableDescription"));
|
|
|
|
|
|
IDetailCategoryBuilder& Category = DetailBuilder.EditCategory(TEXT("Local Variable"));
|
2021-09-01 04:50:52 -04:00
|
|
|
|
|
2021-11-11 11:47:13 -05:00
|
|
|
|
NameHandle = DetailBuilder.GetProperty(TEXT("Name"));
|
|
|
|
|
|
TypeHandle = DetailBuilder.GetProperty(TEXT("CPPType"));
|
|
|
|
|
|
TypeObjectHandle = DetailBuilder.GetProperty(TEXT("CPPTypeObject"));
|
|
|
|
|
|
DefaultValueHandle = DetailBuilder.GetProperty(TEXT("DefaultValue"));
|
2021-09-01 04:50:52 -04:00
|
|
|
|
|
|
|
|
|
|
const UEdGraphSchema* Schema = GetDefault<UControlRigGraphSchema>();
|
|
|
|
|
|
|
|
|
|
|
|
const FSlateFontInfo DetailFontInfo = IDetailLayoutBuilder::GetDetailFont();
|
|
|
|
|
|
Category.AddCustomRow( LOCTEXT("LocalVariableName", "Variable Name") )
|
|
|
|
|
|
.NameContent()
|
|
|
|
|
|
[
|
|
|
|
|
|
SNew(STextBlock)
|
|
|
|
|
|
.Text(LOCTEXT("LocalVariableName", "Variable Name"))
|
|
|
|
|
|
.Font(IDetailLayoutBuilder::GetDetailFont())
|
|
|
|
|
|
]
|
|
|
|
|
|
.ValueContent()
|
|
|
|
|
|
.MaxDesiredWidth(250.0f)
|
|
|
|
|
|
[
|
2021-09-14 10:59:08 -04:00
|
|
|
|
SNew(SEditableTextBox)
|
|
|
|
|
|
.Font(IDetailLayoutBuilder::GetDetailFont())
|
|
|
|
|
|
.Text(this, &FRigVMLocalVariableDetails::GetName)
|
|
|
|
|
|
.OnTextCommitted(this, &FRigVMLocalVariableDetails::SetName)
|
|
|
|
|
|
.OnVerifyTextChanged(this, &FRigVMLocalVariableDetails::OnVerifyNameChanged)
|
2021-09-01 04:50:52 -04:00
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
|
|
TSharedPtr<IPinTypeSelectorFilter> CustomPinTypeFilter;
|
|
|
|
|
|
Category.AddCustomRow(LOCTEXT("VariableTypeLabel", "Variable Type"))
|
|
|
|
|
|
.NameContent()
|
|
|
|
|
|
[
|
|
|
|
|
|
SNew(STextBlock)
|
|
|
|
|
|
.Text(LOCTEXT("VariableTypeLabel", "Variable Type"))
|
|
|
|
|
|
.Font(DetailFontInfo)
|
|
|
|
|
|
]
|
|
|
|
|
|
.ValueContent()
|
|
|
|
|
|
.MaxDesiredWidth(980.f)
|
|
|
|
|
|
[
|
|
|
|
|
|
SNew(SPinTypeSelector, FGetPinTypeTree::CreateUObject(GetDefault<UEdGraphSchema_K2>(), &UEdGraphSchema_K2::GetVariableTypeTree))
|
|
|
|
|
|
.TargetPinType(this, &FRigVMLocalVariableDetails::OnGetPinInfo)
|
|
|
|
|
|
.OnPinTypeChanged(this, &FRigVMLocalVariableDetails::HandlePinInfoChanged)
|
|
|
|
|
|
.Schema(Schema)
|
|
|
|
|
|
.TypeTreeFilter(ETypeTreeFilter::None)
|
|
|
|
|
|
.Font(DetailFontInfo)
|
|
|
|
|
|
.CustomFilter(CustomPinTypeFilter)
|
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
|
|
|
2021-09-06 04:39:25 -04:00
|
|
|
|
if (BlueprintBeingCustomized)
|
2021-09-01 04:50:52 -04:00
|
|
|
|
{
|
2021-09-06 04:39:25 -04:00
|
|
|
|
UControlRigBlueprintGeneratedClass* RigClass = BlueprintBeingCustomized->GetControlRigBlueprintGeneratedClass();
|
|
|
|
|
|
UControlRig* CDO = Cast<UControlRig>(RigClass->GetDefaultObject(true /* create if needed */));
|
|
|
|
|
|
if (CDO->GetVM() != nullptr)
|
2021-09-01 04:50:52 -04:00
|
|
|
|
{
|
2021-09-06 04:39:25 -04:00
|
|
|
|
#if UE_RIGVM_UCLASS_BASED_STORAGE_DISABLED
|
|
|
|
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
FString SourcePath = FString::Printf(TEXT("LocalVariableDefault::%s|%s::Const"), *GraphBeingCustomized->GetGraphName(), *VariableDescription.Name.ToString());
|
|
|
|
|
|
URigVMMemoryStorage* LiteralMemory = CDO->GetVM()->GetLiteralMemory();
|
|
|
|
|
|
FProperty* Property = LiteralMemory->FindPropertyByName(*SourcePath);
|
|
|
|
|
|
if (Property)
|
2021-09-01 04:50:52 -04:00
|
|
|
|
{
|
2021-11-11 11:47:13 -05:00
|
|
|
|
IDetailCategoryBuilder& DefaultValueCategory = DetailBuilder.EditCategory(TEXT("DefaultValueCategory"), LOCTEXT("DefaultValueCategoryHeading", "Default Value"));
|
2021-09-06 04:39:25 -04:00
|
|
|
|
Property->ClearPropertyFlags(CPF_EditConst);
|
2021-09-01 04:50:52 -04:00
|
|
|
|
|
2021-09-06 04:39:25 -04:00
|
|
|
|
const FName SanitizedName = FRigVMPropertyDescription::SanitizeName(*SourcePath);
|
|
|
|
|
|
TArray<UObject*> Objects = {LiteralMemory};
|
|
|
|
|
|
IDetailPropertyRow* Row = DefaultValueCategory.AddExternalObjectProperty(Objects, SanitizedName);
|
|
|
|
|
|
Row->DisplayName(FText::FromName(VariableDescription.Name));
|
|
|
|
|
|
|
|
|
|
|
|
const FSimpleDelegate OnDefaultValueChanged = FSimpleDelegate::CreateLambda([this, Property, LiteralMemory]()
|
2021-09-01 04:50:52 -04:00
|
|
|
|
{
|
2021-09-06 04:39:25 -04:00
|
|
|
|
VariableDescription.DefaultValue = LiteralMemory->GetDataAsString(LiteralMemory->GetPropertyIndex(Property));
|
2021-09-01 04:50:52 -04:00
|
|
|
|
DefaultValueHandle->SetValue(VariableDescription.DefaultValue);
|
2021-09-06 04:39:25 -04:00
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
TSharedPtr<IPropertyHandle> Handle = Row->GetPropertyHandle();
|
|
|
|
|
|
Handle->SetOnPropertyValueChanged(OnDefaultValueChanged);
|
|
|
|
|
|
Handle->SetOnChildPropertyValueChanged(OnDefaultValueChanged);
|
|
|
|
|
|
}
|
|
|
|
|
|
#endif
|
2021-09-01 04:50:52 -04:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2021-09-14 10:59:08 -04:00
|
|
|
|
FText FRigVMLocalVariableDetails::GetName() const
|
|
|
|
|
|
{
|
|
|
|
|
|
return FText::FromName(VariableDescription.Name);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void FRigVMLocalVariableDetails::SetName(const FText& InNewText, ETextCommit::Type InCommitType)
|
|
|
|
|
|
{
|
|
|
|
|
|
if(InCommitType == ETextCommit::OnCleared)
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (InNewText.ToString() == VariableDescription.Name.ToString())
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
VariableDescription.Name = *InNewText.ToString();
|
|
|
|
|
|
NameHandle->SetValue(VariableDescription.Name);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool FRigVMLocalVariableDetails::OnVerifyNameChanged(const FText& InText, FText& OutErrorMessage)
|
|
|
|
|
|
{
|
|
|
|
|
|
EValidatorResult Result = NameValidator.IsValid(InText.ToString(), false);
|
|
|
|
|
|
OutErrorMessage = INameValidatorInterface::GetErrorText(InText.ToString(), Result);
|
|
|
|
|
|
|
|
|
|
|
|
return Result == EValidatorResult::Ok || Result == EValidatorResult::ExistingName;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2021-09-01 04:50:52 -04:00
|
|
|
|
FEdGraphPinType FRigVMLocalVariableDetails::OnGetPinInfo() const
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!VariableDescription.Name.IsNone())
|
|
|
|
|
|
{
|
|
|
|
|
|
return VariableDescription.ToPinType();
|
|
|
|
|
|
}
|
|
|
|
|
|
return FEdGraphPinType();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void FRigVMLocalVariableDetails::HandlePinInfoChanged(const FEdGraphPinType& PinType)
|
|
|
|
|
|
{
|
|
|
|
|
|
VariableDescription.ChangeType(PinType);
|
2021-09-10 10:04:27 -04:00
|
|
|
|
FControlRigBlueprintVMCompileScope CompileScope(BlueprintBeingCustomized);
|
2021-09-01 04:50:52 -04:00
|
|
|
|
TypeHandle->SetValue(VariableDescription.CPPType);
|
2021-09-06 04:39:25 -04:00
|
|
|
|
TypeObjectHandle->SetValue(VariableDescription.CPPTypeObject);
|
2021-09-01 04:50:52 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ECheckBoxState FRigVMLocalVariableDetails::HandleBoolDefaultValueIsChecked() const
|
|
|
|
|
|
{
|
|
|
|
|
|
return VariableDescription.DefaultValue == "1" ? ECheckBoxState::Checked : ECheckBoxState::Unchecked;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void FRigVMLocalVariableDetails::OnBoolDefaultValueChanged(ECheckBoxState InCheckBoxState)
|
|
|
|
|
|
{
|
|
|
|
|
|
VariableDescription.DefaultValue = InCheckBoxState == ECheckBoxState::Checked ? "1" : "0";
|
|
|
|
|
|
DefaultValueHandle->SetValue(VariableDescription.DefaultValue);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#undef LOCTEXT_NAMESPACE
|