More refactoring
This commit is contained in:
128
Plugins/UEWingman/Source/UEWingman/Handlers/Widget_Add.h
Normal file
128
Plugins/UEWingman/Source/UEWingman/Handlers/Widget_Add.h
Normal file
@@ -0,0 +1,128 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "WingServer.h"
|
||||
#include "WingHandler.h"
|
||||
#include "WingFetcher.h"
|
||||
#include "WingWidgets.h"
|
||||
#include "WingUtils.h"
|
||||
#include "WidgetBlueprint.h"
|
||||
#include "Blueprint/WidgetTree.h"
|
||||
#include "Blueprint/UserWidget.h"
|
||||
#include "Kismet2/BlueprintEditorUtils.h"
|
||||
#include "Components/PanelWidget.h"
|
||||
#include "Widget_Add.generated.h"
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS()
|
||||
class UWing_Widget_Add : public UWingHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UPROPERTY(EditAnywhere, meta=(Description="Widget blueprint to add the widget to"))
|
||||
FString Blueprint;
|
||||
|
||||
UPROPERTY(EditAnywhere, meta=(Description="Widget type, from Widget_SearchTypes"))
|
||||
FString Type;
|
||||
|
||||
UPROPERTY(EditAnywhere, meta=(Description="Name for the new widget"))
|
||||
FString Name;
|
||||
|
||||
UPROPERTY(meta=(Optional, Description="Parent widget name. If omitted, sets as root."))
|
||||
FString Parent;
|
||||
|
||||
UPROPERTY(meta=(Optional, Description="Whether to expose the widget as a variable in the blueprint (default false)"))
|
||||
bool IsVariable = false;
|
||||
|
||||
virtual void Register() override
|
||||
{
|
||||
UWingServer::AddHandler(this,
|
||||
TEXT("Add a widget to a Widget Blueprint's widget tree. "
|
||||
"Use Widget_SearchTypes to find available widget types."));
|
||||
}
|
||||
virtual void Handle() override
|
||||
{
|
||||
// Fetch the widget blueprint.
|
||||
WingFetcher F(WingOut::Stdout);
|
||||
UWidgetBlueprint* BP = F.Walk(Blueprint).Cast<UWidgetBlueprint>();
|
||||
if (!BP) return;
|
||||
UWidgetTree* Tree = BP->WidgetTree;
|
||||
|
||||
// Resolve the widget type.
|
||||
WingWidgets WidgetMenu;
|
||||
TArray<WingWidgets::Type> TypeResults = WidgetMenu.Search(Type, 2, true);
|
||||
if (!WingUtils::CheckExactlyOneNamed(TypeResults.Num(), TEXT("Widget type"), Type, WingOut::Stdout)) return;
|
||||
|
||||
// Load the widget's class.
|
||||
UClass* WidgetClass = TypeResults[0].Class.LoadSynchronous();
|
||||
if (!WidgetClass)
|
||||
{
|
||||
WingOut::Stdout.Printf(TEXT("ERROR: Failed to load widget class for '%s'\n"), *Type);
|
||||
return;
|
||||
}
|
||||
|
||||
// Validate the proposed name.
|
||||
FName InternalID = WingUtils::CheckProposedName(Name, WingOut::Stdout);
|
||||
if (InternalID.IsNone()) return;
|
||||
|
||||
// Check that the name is unique among existing widgets.
|
||||
TArray<UWidget*> AllWidgets;
|
||||
Tree->GetAllWidgets(AllWidgets);
|
||||
TSet<FName> Names;
|
||||
FBlueprintEditorUtils::GetClassVariableList(BP, Names);
|
||||
if (!WingUtils::FindNoDuplicateNames(Names, AllWidgets, TEXT("widget or variable"), WingOut::Stdout)) return;
|
||||
if (!WingUtils::FindNoDuplicateName(Names, InternalID, TEXT("widget or variable"), WingOut::Stdout)) return;
|
||||
|
||||
// If a parent is specified, find it and verify it's a panel.
|
||||
UPanelWidget* ParentPanel = nullptr;
|
||||
if (!Parent.IsEmpty())
|
||||
{
|
||||
UWidget* ParentWidget = WingUtils::FindOneWithExternalID(Parent, AllWidgets, TEXT("Widget"), WingOut::Stdout);
|
||||
if (!ParentWidget) return;
|
||||
if (!WingWidgets::CheckCanBeParent(ParentWidget, WingOut::Stdout)) return;
|
||||
ParentPanel = Cast<UPanelWidget>(ParentWidget);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Tree->RootWidget != nullptr)
|
||||
{
|
||||
WingOut::Stdout.Printf(TEXT("ERROR: Widget tree already has a root widget. Specify a Parent.\n"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Create the widget.
|
||||
UWidget* NewWidget;
|
||||
if (WidgetClass->IsChildOf(UUserWidget::StaticClass()))
|
||||
NewWidget = CreateWidget<UUserWidget>(Tree, WidgetClass, InternalID);
|
||||
else
|
||||
NewWidget = NewObject<UWidget>(Tree, WidgetClass, InternalID, RF_Transactional);
|
||||
|
||||
if (!NewWidget)
|
||||
{
|
||||
WingOut::Stdout.Printf(TEXT("ERROR: Failed to create widget\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
// Initialize defaults and set variable flag.
|
||||
NewWidget->CreatedFromPalette();
|
||||
NewWidget->bIsVariable = IsVariable;
|
||||
|
||||
// Add to the tree.
|
||||
if (ParentPanel)
|
||||
{
|
||||
ParentPanel->AddChild(NewWidget);
|
||||
}
|
||||
else
|
||||
{
|
||||
Tree->RootWidget = NewWidget;
|
||||
}
|
||||
|
||||
WingOut::Stdout.Printf(TEXT("Created widget '%s' of type '%s'\n"), *Name, *Type);
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user