Working on better handling of property setters
This commit is contained in:
BIN
Content/Testing/WB_Test.uasset
LFS
BIN
Content/Testing/WB_Test.uasset
LFS
Binary file not shown.
@@ -15,6 +15,9 @@
|
|||||||
#include "AnimationGraph.h"
|
#include "AnimationGraph.h"
|
||||||
#include "AnimationGraphSchema.h"
|
#include "AnimationGraphSchema.h"
|
||||||
#include "AnimationStateMachineSchema.h"
|
#include "AnimationStateMachineSchema.h"
|
||||||
|
#include "WingWidgets.h"
|
||||||
|
#include "WidgetBlueprint.h"
|
||||||
|
#include "Blueprint/WidgetTree.h"
|
||||||
#include "Blueprint_Dump.generated.h"
|
#include "Blueprint_Dump.generated.h"
|
||||||
|
|
||||||
|
|
||||||
@@ -96,6 +99,13 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Widget Tree
|
||||||
|
if (UWidgetBlueprint* WidgetBP = Cast<UWidgetBlueprint>(BP))
|
||||||
|
{
|
||||||
|
UWingServer::Print(TEXT("\nWidget Tree:\n"));
|
||||||
|
WingWidgets::PrintWidgetTree(WidgetBP->WidgetTree->RootWidget, 1);
|
||||||
|
}
|
||||||
|
|
||||||
// Event Dispatchers
|
// Event Dispatchers
|
||||||
if (!BP->DelegateSignatureGraphs.IsEmpty())
|
if (!BP->DelegateSignatureGraphs.IsEmpty())
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -14,6 +14,9 @@
|
|||||||
#include "MaterialGraph/MaterialGraphNode.h"
|
#include "MaterialGraph/MaterialGraphNode.h"
|
||||||
#include "IMaterialEditor.h"
|
#include "IMaterialEditor.h"
|
||||||
#include "Engine/LevelScriptBlueprint.h"
|
#include "Engine/LevelScriptBlueprint.h"
|
||||||
|
#include "WidgetBlueprint.h"
|
||||||
|
#include "Blueprint/WidgetTree.h"
|
||||||
|
#include "Components/Widget.h"
|
||||||
#include "Subsystems/AssetEditorSubsystem.h"
|
#include "Subsystems/AssetEditorSubsystem.h"
|
||||||
|
|
||||||
WingFetcher::WalkFunc WingFetcher::GetWalker(const FString& Step)
|
WingFetcher::WalkFunc WingFetcher::GetWalker(const FString& Step)
|
||||||
@@ -22,6 +25,7 @@ WingFetcher::WalkFunc WingFetcher::GetWalker(const FString& Step)
|
|||||||
if (Step.Equals(TEXT("node"), ESearchCase::IgnoreCase)) return &WingFetcher::Node;
|
if (Step.Equals(TEXT("node"), ESearchCase::IgnoreCase)) return &WingFetcher::Node;
|
||||||
if (Step.Equals(TEXT("pin"), ESearchCase::IgnoreCase)) return &WingFetcher::Pin;
|
if (Step.Equals(TEXT("pin"), ESearchCase::IgnoreCase)) return &WingFetcher::Pin;
|
||||||
if (Step.Equals(TEXT("component"), ESearchCase::IgnoreCase)) return &WingFetcher::Component;
|
if (Step.Equals(TEXT("component"), ESearchCase::IgnoreCase)) return &WingFetcher::Component;
|
||||||
|
if (Step.Equals(TEXT("widget"), ESearchCase::IgnoreCase)) return &WingFetcher::Widget;
|
||||||
if (Step.Equals(TEXT("levelblueprint"), ESearchCase::IgnoreCase)) return &WingFetcher::LevelBlueprint;
|
if (Step.Equals(TEXT("levelblueprint"), ESearchCase::IgnoreCase)) return &WingFetcher::LevelBlueprint;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@@ -312,6 +316,23 @@ WingFetcher& WingFetcher::Component(const FString& Value)
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WingFetcher& WingFetcher::Widget(const FString& Value)
|
||||||
|
{
|
||||||
|
if (bError) return *this;
|
||||||
|
|
||||||
|
UWidgetBlueprint* WidgetBP = ::Cast<UWidgetBlueprint>(Obj);
|
||||||
|
if (!WidgetBP)
|
||||||
|
return TypeMismatch(TEXT("widget"), TEXT("WidgetBlueprint"));
|
||||||
|
|
||||||
|
TArray<UWidget*> AllWidgets;
|
||||||
|
WidgetBP->WidgetTree->GetAllWidgets(AllWidgets);
|
||||||
|
UWidget* Found = WingUtils::FindExactlyOneNamed(Value, AllWidgets, TEXT("Widget"));
|
||||||
|
if (!Found) return SetError();
|
||||||
|
|
||||||
|
SetObj(Found);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
WingFetcher& WingFetcher::LevelBlueprint(const FString& Value)
|
WingFetcher& WingFetcher::LevelBlueprint(const FString& Value)
|
||||||
{
|
{
|
||||||
if (bError) return *this;
|
if (bError) return *this;
|
||||||
|
|||||||
@@ -29,11 +29,14 @@ FString FWingProperty::GetCategory()
|
|||||||
|
|
||||||
FString FWingProperty::GetText() const
|
FString FWingProperty::GetText() const
|
||||||
{
|
{
|
||||||
void* ValuePtr = Prop->ContainerPtrToValuePtr<void>(Container);
|
|
||||||
if (IsPinTypeProperty(Prop))
|
if (IsPinTypeProperty(Prop))
|
||||||
return UWingTypes::TypeToText(*static_cast<FEdGraphPinType*>(ValuePtr));
|
{
|
||||||
|
FEdGraphPinType PinType;
|
||||||
|
Prop->GetValue_InContainer(Container, &PinType);
|
||||||
|
return UWingTypes::TypeToText(PinType);
|
||||||
|
}
|
||||||
FString Result;
|
FString Result;
|
||||||
Prop->ExportTextItem_Direct(Result, ValuePtr, nullptr, nullptr, PPF_None);
|
Prop->ExportTextItem_InContainer(Result, Container, nullptr, nullptr, PPF_None);
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,15 +52,18 @@ FString FWingProperty::GetTruncatedText(int32 MaxLen) const
|
|||||||
|
|
||||||
bool FWingProperty::SetText(const FString &Value)
|
bool FWingProperty::SetText(const FString &Value)
|
||||||
{
|
{
|
||||||
void* ValuePtr = Prop->ContainerPtrToValuePtr<void>(Container);
|
|
||||||
|
|
||||||
// Notify that we're modifying the containing object.
|
// Notify that we're modifying the containing object.
|
||||||
if (Prop->GetOwnerClass())
|
if (Prop->GetOwnerClass())
|
||||||
UWingServer::AddTouchedObject(static_cast<UObject*>(Container));
|
UWingServer::AddTouchedObject(static_cast<UObject*>(Container));
|
||||||
|
|
||||||
// Pin types get parsed by UWingTypes.
|
// Pin types get parsed by UWingTypes.
|
||||||
if (IsPinTypeProperty(Prop))
|
if (IsPinTypeProperty(Prop))
|
||||||
return UWingTypes::TextToType(Value, *static_cast<FEdGraphPinType*>(ValuePtr));
|
{
|
||||||
|
FEdGraphPinType PinType;
|
||||||
|
if (!UWingTypes::TextToType(Value, PinType)) return false;
|
||||||
|
Prop->SetValue_InContainer(Container, &PinType);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// Byte Enum types.
|
// Byte Enum types.
|
||||||
if (FByteProperty* ByteProp = CastField<FByteProperty>(Prop))
|
if (FByteProperty* ByteProp = CastField<FByteProperty>(Prop))
|
||||||
@@ -66,22 +72,27 @@ bool FWingProperty::SetText(const FString &Value)
|
|||||||
{
|
{
|
||||||
int64 EnumValue;
|
int64 EnumValue;
|
||||||
if (!WingUtils::StringToEnum(Enum, Value, EnumValue)) return false;
|
if (!WingUtils::StringToEnum(Enum, Value, EnumValue)) return false;
|
||||||
ByteProp->SetPropertyValue(ValuePtr, (uint8)EnumValue);
|
uint8 ByteValue = (uint8)EnumValue;
|
||||||
|
Prop->SetValue_InContainer(Container, &ByteValue);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Regular Enum types.
|
// Regular Enum types.
|
||||||
|
// TODO: This doesn't use an incontainer setter, which means it
|
||||||
|
// doesn't call property setters.
|
||||||
if (FEnumProperty* EnumProp = CastField<FEnumProperty>(Prop))
|
if (FEnumProperty* EnumProp = CastField<FEnumProperty>(Prop))
|
||||||
{
|
{
|
||||||
int64 EnumValue;
|
int64 EnumValue;
|
||||||
if (!WingUtils::StringToEnum(EnumProp->GetEnum(), Value, EnumValue)) return false;
|
if (!WingUtils::StringToEnum(EnumProp->GetEnum(), Value, EnumValue)) return false;
|
||||||
EnumProp->GetUnderlyingProperty()->SetIntPropertyValue(ValuePtr, EnumValue);
|
FNumericProperty* Underlying = EnumProp->GetUnderlyingProperty();
|
||||||
|
void* ValuePtr = Underlying->ContainerPtrToValuePtr<void>(Container);
|
||||||
|
Underlying->SetIntPropertyValue(ValuePtr, EnumValue);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Non-enum properties use ImportText
|
// Non-enum properties use ImportText
|
||||||
const TCHAR* Result = Prop->ImportText_Direct(*Value, ValuePtr, nullptr, PPF_None);
|
const TCHAR* Result = Prop->ImportText_InContainer(*Value, Container, nullptr, PPF_None);
|
||||||
if (!Result)
|
if (!Result)
|
||||||
{
|
{
|
||||||
UWingServer::Printf(TEXT("ERROR: Failed to parse '%s' for property '%s' (type: %s)\n"),
|
UWingServer::Printf(TEXT("ERROR: Failed to parse '%s' for property '%s' (type: %s)\n"),
|
||||||
|
|||||||
@@ -271,7 +271,12 @@ FString WingUtils::FormatName(const FBPInterfaceDescription &IFace)
|
|||||||
|
|
||||||
FString WingUtils::FormatName(const FWingActorComponent &Comp)
|
FString WingUtils::FormatName(const FWingActorComponent &Comp)
|
||||||
{
|
{
|
||||||
return Comp.GetName();
|
return SanitizeName(Comp.GetName());
|
||||||
|
}
|
||||||
|
|
||||||
|
FString WingUtils::FormatName(const UWidget *Widget)
|
||||||
|
{
|
||||||
|
return SanitizeName(Widget->GetName());
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============================================================
|
// ============================================================
|
||||||
|
|||||||
26
Plugins/UEWingman/Source/UEWingman/Private/WingWidgets.cpp
Normal file
26
Plugins/UEWingman/Source/UEWingman/Private/WingWidgets.cpp
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
#include "WingWidgets.h"
|
||||||
|
#include "WingServer.h"
|
||||||
|
#include "WingUtils.h"
|
||||||
|
#include "Blueprint/WidgetTree.h"
|
||||||
|
#include "Components/Widget.h"
|
||||||
|
#include "Components/PanelWidget.h"
|
||||||
|
#include "Components/PanelSlot.h"
|
||||||
|
|
||||||
|
void WingWidgets::PrintWidgetTree(UWidget* Widget, int32 Depth)
|
||||||
|
{
|
||||||
|
FString Indent = FString::ChrN(Depth * 2, TEXT(' '));
|
||||||
|
if (Widget == nullptr)
|
||||||
|
{
|
||||||
|
UWingServer::Printf(TEXT("%s[null]\n"), *Indent);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
FString TypeName = WingUtils::FormatName(Widget->GetClass());
|
||||||
|
FString WidgetName = WingUtils::FormatName(Widget);
|
||||||
|
UWingServer::Printf(TEXT("%s%s %s\n"), *Indent, *TypeName, *WidgetName);
|
||||||
|
|
||||||
|
if (UPanelWidget* Panel = Cast<UPanelWidget>(Widget))
|
||||||
|
{
|
||||||
|
for (UPanelSlot* Slot : Panel->GetSlots())
|
||||||
|
PrintWidgetTree(Slot->Content, Depth + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -52,6 +52,7 @@ public:
|
|||||||
WingFetcher& Node(const FString& Value);
|
WingFetcher& Node(const FString& Value);
|
||||||
WingFetcher& Pin(const FString& Value);
|
WingFetcher& Pin(const FString& Value);
|
||||||
WingFetcher& Component(const FString& Value);
|
WingFetcher& Component(const FString& Value);
|
||||||
|
WingFetcher& Widget(const FString& Value);
|
||||||
WingFetcher& LevelBlueprint(const FString& Value);
|
WingFetcher& LevelBlueprint(const FString& Value);
|
||||||
|
|
||||||
// Return true if there haven't been any errors.
|
// Return true if there haven't been any errors.
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ class UTexture;
|
|||||||
class UScriptStruct;
|
class UScriptStruct;
|
||||||
class UEnum;
|
class UEnum;
|
||||||
class USCS_Node;
|
class USCS_Node;
|
||||||
|
class UWidget;
|
||||||
struct FMemberReference;
|
struct FMemberReference;
|
||||||
struct FBPVariableDescription;
|
struct FBPVariableDescription;
|
||||||
struct FUserPinInfo;
|
struct FUserPinInfo;
|
||||||
@@ -79,6 +80,7 @@ public:
|
|||||||
static FString FormatName(const FUserPinInfo &Pin);
|
static FString FormatName(const FUserPinInfo &Pin);
|
||||||
static FString FormatName(const FBPInterfaceDescription &IFace);
|
static FString FormatName(const FBPInterfaceDescription &IFace);
|
||||||
static FString FormatName(const FWingActorComponent &Comp);
|
static FString FormatName(const FWingActorComponent &Comp);
|
||||||
|
static FString FormatName(const UWidget *Widget);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////
|
||||||
// Identifies
|
// Identifies
|
||||||
@@ -112,7 +114,7 @@ public:
|
|||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T, typename = std::enable_if_t<!std::is_pointer_v<T>>>
|
||||||
static TArray<T*> FindAllNamed(const FString &Name, TArray<T> &Array)
|
static TArray<T*> FindAllNamed(const FString &Name, TArray<T> &Array)
|
||||||
{
|
{
|
||||||
TArray<T*> Result;
|
TArray<T*> Result;
|
||||||
@@ -130,7 +132,7 @@ public:
|
|||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T, typename = std::enable_if_t<!std::is_pointer_v<T>>>
|
||||||
static T* FindExactlyOneNamed(const FString &Name, TArray<T> &Array, const TCHAR *Kind)
|
static T* FindExactlyOneNamed(const FString &Name, TArray<T> &Array, const TCHAR *Kind)
|
||||||
{
|
{
|
||||||
int Count = 0;
|
int Count = 0;
|
||||||
@@ -140,16 +142,6 @@ public:
|
|||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
static bool FindExactlyNoneNamed(const FString &Name, const TArray<T*> &Array, const TCHAR *Kind)
|
|
||||||
{
|
|
||||||
for (T* Elt: Array) if (Identifies(Name, Elt))
|
|
||||||
{
|
|
||||||
return CheckExactlyNoneNamed(1, Kind, Name);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
static bool FindExactlyNoneNamed(const FString &Name, const TArray<T> &Array, const TCHAR *Kind)
|
static bool FindExactlyNoneNamed(const FString &Name, const TArray<T> &Array, const TCHAR *Kind)
|
||||||
{
|
{
|
||||||
|
|||||||
13
Plugins/UEWingman/Source/UEWingman/Public/WingWidgets.h
Normal file
13
Plugins/UEWingman/Source/UEWingman/Public/WingWidgets.h
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
|
||||||
|
class UWidgetTree;
|
||||||
|
class UWidget;
|
||||||
|
|
||||||
|
// Utility functions for widget blueprint manipulation.
|
||||||
|
class WingWidgets
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static void PrintWidgetTree(UWidget* Widget, int32 Depth);
|
||||||
|
};
|
||||||
@@ -33,7 +33,8 @@ public class UEWingman : ModuleRules
|
|||||||
"Slate",
|
"Slate",
|
||||||
"SlateCore",
|
"SlateCore",
|
||||||
"ToolMenus",
|
"ToolMenus",
|
||||||
"UMG"
|
"UMG",
|
||||||
|
"UMGEditor"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user