More work on props
This commit is contained in:
@@ -1,6 +1,8 @@
|
|||||||
#include "WingPropHandle.h"
|
#include "WingPropHandle.h"
|
||||||
#include "WingServer.h"
|
#include "WingServer.h"
|
||||||
#include "WingActorComponent.h"
|
#include "WingActorComponent.h"
|
||||||
|
#include "WingUtils.h"
|
||||||
|
#include "WingTypes.h"
|
||||||
#include "PropertyEditorModule.h"
|
#include "PropertyEditorModule.h"
|
||||||
#include "IDetailTreeNode.h"
|
#include "IDetailTreeNode.h"
|
||||||
#include "Engine/Blueprint.h"
|
#include "Engine/Blueprint.h"
|
||||||
@@ -8,6 +10,8 @@
|
|||||||
#include "Components/PanelSlot.h"
|
#include "Components/PanelSlot.h"
|
||||||
#include "MaterialGraph/MaterialGraphNode.h"
|
#include "MaterialGraph/MaterialGraphNode.h"
|
||||||
#include "Materials/MaterialExpression.h"
|
#include "Materials/MaterialExpression.h"
|
||||||
|
#include "UObject/EnumProperty.h"
|
||||||
|
#include "EdGraph/EdGraphPin.h"
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
@@ -241,3 +245,84 @@ WingPropHandle::Handles WingPropHandle::GetDetails(UObject* Obj, bool Mutable, E
|
|||||||
|
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// GetText / SetText
|
||||||
|
//
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
bool WingPropHandle::IsPinTypeProperty(FProperty* Prop)
|
||||||
|
{
|
||||||
|
FStructProperty* StructProp = CastField<FStructProperty>(Prop);
|
||||||
|
return StructProp && StructProp->Struct == FEdGraphPinType::StaticStruct();
|
||||||
|
}
|
||||||
|
|
||||||
|
FString WingPropHandle::GetText(IPropertyHandle& Handle)
|
||||||
|
{
|
||||||
|
// Pin types: use our human-readable format.
|
||||||
|
if (IsPinTypeProperty(Handle.GetProperty()))
|
||||||
|
{
|
||||||
|
void* Data = nullptr;
|
||||||
|
if (Handle.GetValueData(Data) != FPropertyAccess::Success || !Data)
|
||||||
|
UE_LOG(LogTemp, Fatal, TEXT("GetValueData failed for pin type property '%s'"),
|
||||||
|
*Handle.GetProperty()->GetName());
|
||||||
|
return UWingTypes::TypeToText(*static_cast<FEdGraphPinType*>(Data));
|
||||||
|
}
|
||||||
|
|
||||||
|
FString Result;
|
||||||
|
if (Handle.GetValueAsFormattedString(Result) != FPropertyAccess::Success)
|
||||||
|
UE_LOG(LogTemp, Fatal, TEXT("GetValueAsFormattedString failed for property '%s'"),
|
||||||
|
*Handle.GetProperty()->GetName());
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WingPropHandle::SetText(IPropertyHandle& Handle, const FString& Text)
|
||||||
|
{
|
||||||
|
FProperty* Prop = Handle.GetProperty();
|
||||||
|
|
||||||
|
// Pin types: parse with our type parser.
|
||||||
|
if (IsPinTypeProperty(Prop))
|
||||||
|
{
|
||||||
|
FEdGraphPinType PinType;
|
||||||
|
UWingTypes::Requirements Req;
|
||||||
|
Req.BlueprintType = true;
|
||||||
|
Req.Blueprintable = false;
|
||||||
|
Req.AllowContainer = true;
|
||||||
|
if (!UWingTypes::TextToType(Text, PinType, Req)) return false;
|
||||||
|
void* Data = nullptr;
|
||||||
|
if (Handle.GetValueData(Data) != FPropertyAccess::Success || !Data)
|
||||||
|
{
|
||||||
|
UWingServer::Printf(TEXT("ERROR: Cannot access data for property '%s'\n"),
|
||||||
|
*WingUtils::FormatName(Prop));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Handle.NotifyPreChange();
|
||||||
|
*static_cast<FEdGraphPinType*>(Data) = PinType;
|
||||||
|
Handle.NotifyPostChange(EPropertyChangeType::ValueSet);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enums: canonicalize the string with our smarter prefix matching.
|
||||||
|
FString Value = Text;
|
||||||
|
UEnum* Enum = nullptr;
|
||||||
|
if (FByteProperty* ByteProp = CastField<FByteProperty>(Prop))
|
||||||
|
Enum = ByteProp->Enum;
|
||||||
|
if (FEnumProperty* EnumProp = CastField<FEnumProperty>(Prop))
|
||||||
|
Enum = EnumProp->GetEnum();
|
||||||
|
if (Enum != nullptr)
|
||||||
|
{
|
||||||
|
int64 EnumValue;
|
||||||
|
if (!WingUtils::StringToEnum(Enum, Value, EnumValue)) return false;
|
||||||
|
Value = Enum->GetNameStringByValue(EnumValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
FPropertyAccess::Result Result = Handle.SetValueFromFormattedString(Value);
|
||||||
|
if (Result != FPropertyAccess::Success)
|
||||||
|
{
|
||||||
|
UWingServer::Printf(TEXT("ERROR: Failed to parse '%s' for property '%s' (type: %s)\n"),
|
||||||
|
*Value, *WingUtils::FormatName(Prop), *Prop->GetCPPType());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|||||||
@@ -43,6 +43,12 @@ public:
|
|||||||
// Get a single named property from a struct.
|
// Get a single named property from a struct.
|
||||||
TSharedPtr<IPropertyHandle> NamedProperty(const UStruct* ScriptStruct, uint8* Data, FName Name);
|
TSharedPtr<IPropertyHandle> NamedProperty(const UStruct* ScriptStruct, uint8* Data, FName Name);
|
||||||
|
|
||||||
|
// Get/set text with special handling for enums (smarter prefix
|
||||||
|
// matching via WingUtils::StringToEnum) and FEdGraphPinType
|
||||||
|
// (human-readable format via UWingTypes).
|
||||||
|
static FString GetText(IPropertyHandle& Handle);
|
||||||
|
static bool SetText(IPropertyHandle& Handle, const FString& Text);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Root
|
struct Root
|
||||||
{
|
{
|
||||||
@@ -52,6 +58,7 @@ private:
|
|||||||
TSharedPtr<IPropertyRowGenerator> Generator;
|
TSharedPtr<IPropertyRowGenerator> Generator;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static bool IsPinTypeProperty(FProperty* Prop);
|
||||||
static bool IsInsideRootObject(const Root& Root, IPropertyHandle& Handle);
|
static bool IsInsideRootObject(const Root& Root, IPropertyHandle& Handle);
|
||||||
TArray<Root> Roots;
|
TArray<Root> Roots;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user