From 0245e2bcbfe01266b5a6b3aba9fd22ece2f2f499 Mon Sep 17 00:00:00 2001 From: yeshjho Date: Mon, 25 Nov 2024 22:18:35 -0800 Subject: [PATCH] sml parent --- .../Patching/WidgetBlueprintHookManager.cpp | 47 +++++++++++++++---- .../Patching/WidgetBlueprintHookManager.h | 22 +++++++-- 2 files changed, 57 insertions(+), 12 deletions(-) diff --git a/Mods/SML/Source/SML/Private/Patching/WidgetBlueprintHookManager.cpp b/Mods/SML/Source/SML/Private/Patching/WidgetBlueprintHookManager.cpp index 17d782a019..f3f4b16557 100644 --- a/Mods/SML/Source/SML/Private/Patching/WidgetBlueprintHookManager.cpp +++ b/Mods/SML/Source/SML/Private/Patching/WidgetBlueprintHookManager.cpp @@ -55,7 +55,7 @@ bool WidgetBlueprintHookParentValidator::ValidateDirectWidget(UWidget* Widget, U return true; } -bool WidgetBlueprintHookParentValidator::ValidateIndirectChildWidget(UWidget* Widget, UPanelWidget*& OutPanelWidget, bool bCheckVariableName) { +bool WidgetBlueprintHookParentValidator::ValidateIndirectChildWidget(UWidget* Widget, UPanelWidget*& OutPanelWidget, bool bCheckVariableName, FName ParentNameToCheck) { if (!ValidateWidgetBase(Widget, bCheckVariableName)) { return false; } @@ -63,15 +63,19 @@ bool WidgetBlueprintHookParentValidator::ValidateIndirectChildWidget(UWidget* Wi return false; } UPanelWidget* ParentPanelWidget = Widget->Slot->Parent; + while (ParentPanelWidget && (!ParentNameToCheck.IsNone() && ParentPanelWidget->GetFName() != ParentNameToCheck)) + { + ParentPanelWidget = ParentPanelWidget->GetParent(); + } return ValidateDirectWidget(ParentPanelWidget, OutPanelWidget, false); } -bool WidgetBlueprintHookParentValidator::ValidateParentWidget(UWidget* Widget, EWidgetBlueprintHookParentType ParentType, UPanelWidget*& OutParentWidget, bool bCheckVariableName) { +bool WidgetBlueprintHookParentValidator::ValidateParentWidget(UWidget* Widget, EWidgetBlueprintHookParentType ParentType, UPanelWidget*& OutParentWidget, bool bCheckVariableName, FName ParentNameToCheck) { if (ParentType == EWidgetBlueprintHookParentType::Direct) { return ValidateDirectWidget(Widget, OutParentWidget, bCheckVariableName); } if (ParentType == EWidgetBlueprintHookParentType::Indirect_Child) { - return ValidateIndirectChildWidget(Widget, OutParentWidget, bCheckVariableName); + return ValidateIndirectChildWidget(Widget, OutParentWidget, bCheckVariableName, ParentNameToCheck); } return false; } @@ -97,6 +101,15 @@ void UWidgetBlueprintHookData::SetParentWidgetName(FName InParentWidgetName) { ReinitializePanelSlotTemplate(); } +void UWidgetBlueprintHookData::SetIndirectParentWidgetNameToAttachTo(FName InIndirectParentWidgetNameToAttachTo) +{ + if (ParentWidgetType != EWidgetBlueprintHookParentType::Indirect_Child) { + return; + } + this->IndirectParentWidgetNameToAttachTo = InIndirectParentWidgetNameToAttachTo; + ReinitializePanelSlotTemplate(); +} + void UWidgetBlueprintHookData::SetNewWidgetName(FName InNewWidgetName) { this->NewWidgetName = InNewWidgetName; ReinitializeNewWidgetTemplate(); @@ -145,7 +158,7 @@ void UWidgetBlueprintHookData::ReinitializeNewWidgetTemplate() { } void UWidgetBlueprintHookData::ReinitializePanelSlotTemplate() { - if (const UPanelWidget* PanelWidget = ResolveParentWidget()) { + if (const UPanelWidget* PanelWidget = ResolveParentWidget(true)) { PanelSlotClass = UPanelWidgetAccessor::GetPanelSlotClass(PanelWidget); } else { PanelSlotClass = NULL; @@ -194,7 +207,8 @@ void UWidgetBlueprintHookData::PostEditChangeProperty(FPropertyChangedEvent& Pro const FName PropertyName = PropertyChangedEvent.MemberProperty->GetFName(); if (PropertyName == GET_MEMBER_NAME_CHECKED(ThisClass, WidgetClass) || PropertyName == GET_MEMBER_NAME_CHECKED(ThisClass, ParentWidgetType) || - PropertyName == GET_MEMBER_NAME_CHECKED(ThisClass, ParentWidgetName)) { + PropertyName == GET_MEMBER_NAME_CHECKED(ThisClass, ParentWidgetName) || + PropertyName == GET_MEMBER_NAME_CHECKED(ThisClass, IndirectParentWidgetNameToAttachTo)) { ReinitializePanelSlotTemplate(); } else if (PropertyName == GET_MEMBER_NAME_CHECKED(ThisClass, NewWidgetClass)) { @@ -225,7 +239,24 @@ TArray UWidgetBlueprintHookData::GetParentWidgetNames() const { return ResultWidgetNames; } -UPanelWidget* UWidgetBlueprintHookData::ResolveParentWidget() const { +TArray UWidgetBlueprintHookData::GetIndirectParentWidgetNames() const +{ + TArray ResultWidgetNames; + + UPanelWidget* ResultParentWidget; + + UPanelWidget* ParentPanelWidget = ResolveParentWidget(false); + while (ParentPanelWidget) { + if (WidgetBlueprintHookParentValidator::ValidateDirectWidget(ParentPanelWidget, ResultParentWidget, false)) { + ResultWidgetNames.Add(ParentPanelWidget->GetName()); + } + ParentPanelWidget = ParentPanelWidget->GetParent(); + } + + return ResultWidgetNames; +} + +UPanelWidget* UWidgetBlueprintHookData::ResolveParentWidget(bool bFollowIndirectParents) const { const UWidgetBlueprintGeneratedClass* WidgetBlueprintClass = Cast(WidgetClass.LoadSynchronous()); if (WidgetBlueprintClass == NULL) { return NULL; @@ -234,7 +265,7 @@ UPanelWidget* UWidgetBlueprintHookData::ResolveParentWidget() const { UWidget* ParentWidget = WidgetBlueprintClass->GetWidgetTreeArchetype()->FindWidget(ParentWidgetName); UPanelWidget* OutParentWidget; - if (WidgetBlueprintHookParentValidator::ValidateParentWidget(ParentWidget, ParentWidgetType, OutParentWidget, false)) { + if (WidgetBlueprintHookParentValidator::ValidateParentWidget(ParentWidget, ParentWidgetType, OutParentWidget, false, bFollowIndirectParents ? IndirectParentWidgetNameToAttachTo : FName{})) { return OutParentWidget; } return NULL; @@ -258,7 +289,7 @@ void UWidgetBlueprintHookManager::RegisterWidgetBlueprintHook(UWidgetBlueprintHo return; } - UPanelWidget* PanelWidget = HookData->ResolveParentWidget(); + UPanelWidget* PanelWidget = HookData->ResolveParentWidget(true); if (PanelWidget == NULL) { UE_LOG(LogWidgetBlueprintHookManager, Error, TEXT("Failed to hook widget blueprint %s, failed to resolve parent widget %s inside %s"), diff --git a/Mods/SML/Source/SML/Public/Patching/WidgetBlueprintHookManager.h b/Mods/SML/Source/SML/Public/Patching/WidgetBlueprintHookManager.h index 9095fe0893..5d4038e96b 100644 --- a/Mods/SML/Source/SML/Public/Patching/WidgetBlueprintHookManager.h +++ b/Mods/SML/Source/SML/Public/Patching/WidgetBlueprintHookManager.h @@ -30,10 +30,10 @@ enum class EWidgetBlueprintHookParentType : uint8 { }; namespace WidgetBlueprintHookParentValidator { - SML_API bool ValidateParentWidget(UWidget* Widget, EWidgetBlueprintHookParentType ParentType, UPanelWidget*& OutParentWidget, bool bCheckVariableName = true); + SML_API bool ValidateParentWidget(UWidget* Widget, EWidgetBlueprintHookParentType ParentType, UPanelWidget*& OutParentWidget, bool bCheckVariableName = true, FName ParentNameToCheck = FName{}); SML_API bool ValidateDirectWidget(UWidget* Widget, UPanelWidget*& OutPanelWidget, bool bCheckVariableName); - SML_API bool ValidateIndirectChildWidget(UWidget* Widget, UPanelWidget*& OutPanelWidget, bool bCheckVariableName); + SML_API bool ValidateIndirectChildWidget(UWidget* Widget, UPanelWidget*& OutPanelWidget, bool bCheckVariableName, FName ParentNameToCheck = FName{}); SML_API bool ValidateWidgetBase(UWidget* Widget, bool bCheckVariableName); } @@ -76,10 +76,17 @@ class SML_API UWidgetBlueprintHookData : public UDataAsset { UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Advanced") EWidgetBlueprintHookParentType ParentWidgetType; - /** Name of the parent widget variable to attach this widget to. Must a panel widget. */ + /** + * Name of the parent widget variable to attach this widget to. Must a panel widget. + * If ParentWidgetType is Indirect (Child), this is the name of the child widget variable to search for the parents. + */ UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Default", meta = (GetOptions = "GetParentWidgetNames")) FName ParentWidgetName; + /** Name of the parent widget to attach this widget to when ParentWidgetType is Indirect (Child) */ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Advanced", meta = (EditCondition = "ParentWidgetType == EWidgetBlueprintHookParentType::Indirect_Child", GetOptions = "GetIndirectParentWidgetNames")) + FName IndirectParentWidgetNameToAttachTo; + /** * When not -1, specifies the index in the parent widget Slots array at which the widget will be inserted * By default the widget will be appended to the array, but you can change the order if needed */ @@ -100,6 +107,9 @@ class SML_API UWidgetBlueprintHookData : public UDataAsset { UFUNCTION(BlueprintPure) TArray GetParentWidgetNames() const; + + UFUNCTION(BlueprintPure) + TArray GetIndirectParentWidgetNames() const; /** Updates the blueprint widget class being hooked */ UFUNCTION(BlueprintSetter) @@ -119,10 +129,14 @@ class SML_API UWidgetBlueprintHookData : public UDataAsset { /** Updates the name of the parent widget for this hook */ UFUNCTION(BlueprintSetter) void SetParentWidgetName(FName InParentWidgetName); + + /** Updates the name of the parent widget for this hook when ParentWidgetType is Indirect (Child) */ + UFUNCTION(BlueprintSetter) + void SetIndirectParentWidgetNameToAttachTo(FName InIndirectParentWidgetNameToAttachTo); void ReinitializeNewWidgetTemplate(); void ReinitializePanelSlotTemplate(); - UPanelWidget* ResolveParentWidget() const; + UPanelWidget* ResolveParentWidget(bool bFollowIndirectParents = false) const; }; UCLASS()