86 lines
2.5 KiB
C++
86 lines
2.5 KiB
C++
#pragma once
|
|
|
|
#include "CoreMinimal.h"
|
|
#include "WingServer.h"
|
|
#include "WingBasics.h"
|
|
#include "WingFetcher.h"
|
|
#include "WingUtils.h"
|
|
#include "WidgetBlueprint.h"
|
|
#include "Blueprint/WidgetTree.h"
|
|
#include "Components/PanelWidget.h"
|
|
#include "Kismet2/BlueprintEditorUtils.h"
|
|
#include "Widget_Remove.generated.h"
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// ---------------------------------------------------------------------------
|
|
// ---------------------------------------------------------------------------
|
|
|
|
UCLASS()
|
|
class UWing_Widget_Remove : public UWingHandler
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
public:
|
|
UPROPERTY(EditAnywhere, meta=(Description="Path to the widget, eg /Game/Widgets/WB_Test,widget:MyButton"))
|
|
FString Widget;
|
|
|
|
virtual void Register() override
|
|
{
|
|
UWingServer::AddHandler(this,
|
|
TEXT("Delete a widget from a Widget Blueprint's widget tree. "
|
|
"The widget must not have any children."));
|
|
}
|
|
virtual void Handle() override
|
|
{
|
|
// Walk to the widget.
|
|
WingFetcher F(WingOut::Stdout);
|
|
UWidget* TargetWidget = F.Walk(Widget).Cast<UWidget>();
|
|
if (!TargetWidget) return;
|
|
|
|
// Get the widget blueprint and tree from the widget's outer chain.
|
|
UWidgetBlueprint* BP = TargetWidget->GetTypedOuter<UWidgetBlueprint>();
|
|
if (!BP)
|
|
{
|
|
WingOut::Stdout.Printf(TEXT("ERROR: Could not find owning WidgetBlueprint\n"));
|
|
return;
|
|
}
|
|
UWidgetTree* Tree = BP->WidgetTree;
|
|
|
|
// If it's a panel, make sure it has no children.
|
|
if (UPanelWidget* Panel = Cast<UPanelWidget>(TargetWidget))
|
|
{
|
|
if (Panel->GetChildrenCount() > 0)
|
|
{
|
|
WingOut::Stdout.Printf(TEXT("ERROR: Widget '%s' has %d children. Remove them first.\n"),
|
|
*WingUtils::FormatName(TargetWidget), Panel->GetChildrenCount());
|
|
return;
|
|
}
|
|
}
|
|
|
|
FString WidgetName = WingUtils::FormatName(TargetWidget);
|
|
|
|
// Remove delegate bindings that reference this widget.
|
|
FString WidgetObjName = TargetWidget->GetName();
|
|
for (int32 i = BP->Bindings.Num() - 1; i >= 0; i--)
|
|
{
|
|
if (BP->Bindings[i].ObjectName == WidgetObjName)
|
|
BP->Bindings.RemoveAt(i);
|
|
}
|
|
|
|
// Remove the widget from the tree.
|
|
Tree->RemoveWidget(TargetWidget);
|
|
|
|
// Remove variable nodes from the blueprint graph if this was a variable.
|
|
if (TargetWidget->bIsVariable)
|
|
{
|
|
FBlueprintEditorUtils::RemoveVariableNodes(BP, TargetWidget->GetFName());
|
|
}
|
|
|
|
// Rename to transient package to avoid name conflicts with future widgets.
|
|
TargetWidget->Rename(nullptr, GetTransientPackage());
|
|
|
|
WingOut::Stdout.Printf(TEXT("Deleted widget '%s'\n"), *WidgetName);
|
|
}
|
|
};
|