Skip to content

Commit

Permalink
sml parent
Browse files Browse the repository at this point in the history
  • Loading branch information
yeshjho committed Nov 26, 2024
1 parent 7646bb8 commit 0245e2b
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -55,23 +55,27 @@ 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;
}
if (Widget->Slot == NULL) {
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;
}
Expand All @@ -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();
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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)) {
Expand Down Expand Up @@ -225,7 +239,24 @@ TArray<FString> UWidgetBlueprintHookData::GetParentWidgetNames() const {
return ResultWidgetNames;
}

UPanelWidget* UWidgetBlueprintHookData::ResolveParentWidget() const {
TArray<FString> UWidgetBlueprintHookData::GetIndirectParentWidgetNames() const
{
TArray<FString> 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<UWidgetBlueprintGeneratedClass>(WidgetClass.LoadSynchronous());
if (WidgetBlueprintClass == NULL) {
return NULL;
Expand All @@ -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;
Expand All @@ -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"),
Expand Down
22 changes: 18 additions & 4 deletions Mods/SML/Source/SML/Public/Patching/WidgetBlueprintHookManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down Expand Up @@ -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 */
Expand All @@ -100,6 +107,9 @@ class SML_API UWidgetBlueprintHookData : public UDataAsset {

UFUNCTION(BlueprintPure)
TArray<FString> GetParentWidgetNames() const;

UFUNCTION(BlueprintPure)
TArray<FString> GetIndirectParentWidgetNames() const;

/** Updates the blueprint widget class being hooked */
UFUNCTION(BlueprintSetter)
Expand All @@ -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()
Expand Down

0 comments on commit 0245e2b

Please sign in to comment.