Files
UnrealEngine/Engine/Source/Runtime/UMG/Private/WidgetBlueprintLibrary.cpp
2025-05-18 13:04:45 +08:00

750 lines
21 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "Blueprint/WidgetBlueprintLibrary.h"
#include "Materials/MaterialInterface.h"
#include "Slate/SGameLayerManager.h"
#include "UObject/UObjectHash.h"
#include "UObject/UObjectIterator.h"
#include "UObject/Package.h"
#include "Engine/Texture2D.h"
#include "Materials/MaterialInstanceDynamic.h"
#include "Fonts/SlateFontInfo.h"
#include "Engine/Font.h"
#include "Engine/GameViewportClient.h"
#include "Brushes/SlateNoResource.h"
#include "Rendering/DrawElements.h"
#include "Styling/SlateTypes.h"
#include "Styling/CoreStyle.h"
#include "Styling/UMGCoreStyle.h"
#include "Framework/Application/SlateApplication.h"
#include "Slate/UMGDragDropOp.h"
#include "Slate/SlateBrushAsset.h"
#include "EngineGlobals.h"
#include "Blueprint/WidgetLayoutLibrary.h"
#include "Engine/Engine.h"
#include "Engine/GameEngine.h"
#include "Widgets/Layout/SWindowTitleBarArea.h"
#include UE_INLINE_GENERATED_CPP_BY_NAME(WidgetBlueprintLibrary)
//For PIE error messages
#define LOCTEXT_NAMESPACE "UMG"
/////////////////////////////////////////////////////
// UWidgetBlueprintLibrary
UWidgetBlueprintLibrary::UWidgetBlueprintLibrary(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
}
UUserWidget* UWidgetBlueprintLibrary::Create(UObject* WorldContextObject, TSubclassOf<UUserWidget> WidgetType, APlayerController* OwningPlayer)
{
if (WidgetType == nullptr)
{
return nullptr;
}
if (OwningPlayer)
{
return CreateWidget(OwningPlayer, WidgetType);
}
else if (APlayerController* ImpliedOwningPlayer = Cast<APlayerController>(WorldContextObject))
{
return CreateWidget(ImpliedOwningPlayer, WidgetType);
}
else if (UUserWidget* OwningWidget = Cast<UUserWidget>(WorldContextObject))
{
return CreateWidget(OwningWidget, WidgetType);
}
else if (UWorld* World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull))
{
return CreateWidget(World, WidgetType);
}
return nullptr;
}
UDragDropOperation* UWidgetBlueprintLibrary::CreateDragDropOperation(TSubclassOf<UDragDropOperation> Operation)
{
UDragDropOperation* DragDropOperation = nullptr;
if ( Operation )
{
DragDropOperation = NewObject<UDragDropOperation>(GetTransientPackage(), Operation);
}
else
{
DragDropOperation = NewObject<UDragDropOperation>();
}
return DragDropOperation;
}
void UWidgetBlueprintLibrary::SetInputMode_UIOnlyEx(APlayerController* PlayerController, UWidget* InWidgetToFocus, EMouseLockMode InMouseLockMode, const bool bFlushInput /* = false */)
{
if (PlayerController != nullptr)
{
FInputModeUIOnly InputMode;
InputMode.SetLockMouseToViewportBehavior(InMouseLockMode);
if (InWidgetToFocus != nullptr)
{
InputMode.SetWidgetToFocus(InWidgetToFocus->TakeWidget());
}
PlayerController->SetInputMode(InputMode);
if (bFlushInput)
{
PlayerController->FlushPressedKeys();
}
}
#if WITH_EDITOR
else
{
FMessageLog("PIE").Error(LOCTEXT("UMG WidgetBlueprint Library: SetInputMode_UIOnly", "SetInputMode_UIOnly expects a valid player controller as 'PlayerController' target"));
}
#endif // WITH_EDITOR
}
void UWidgetBlueprintLibrary::SetInputMode_GameAndUIEx(APlayerController* PlayerController, UWidget* InWidgetToFocus, EMouseLockMode InMouseLockMode, bool bHideCursorDuringCapture, const bool bFlushInput /* = false */)
{
if (PlayerController != nullptr)
{
FInputModeGameAndUI InputMode;
InputMode.SetLockMouseToViewportBehavior(InMouseLockMode);
InputMode.SetHideCursorDuringCapture(bHideCursorDuringCapture);
if (InWidgetToFocus != nullptr)
{
InputMode.SetWidgetToFocus(InWidgetToFocus->TakeWidget());
}
PlayerController->SetInputMode(InputMode);
if (bFlushInput)
{
PlayerController->FlushPressedKeys();
}
}
#if WITH_EDITOR
else
{
FMessageLog("PIE").Error(LOCTEXT("UMG WidgetBlueprint Library: SetInputMode_GameAndUI", "SetInputMode_GameAndUI expects a valid player controller as 'PlayerController' target"));
}
#endif // WITH_EDITOR
}
void UWidgetBlueprintLibrary::SetInputMode_GameOnly(APlayerController* PlayerController, const bool bFlushInput /* = false */)
{
if (PlayerController != nullptr)
{
FInputModeGameOnly InputMode;
PlayerController->SetInputMode(InputMode);
if (bFlushInput)
{
PlayerController->FlushPressedKeys();
}
}
#if WITH_EDITOR
else
{
FMessageLog("PIE").Error(LOCTEXT("UMG WidgetBlueprint Library: SetInputMode_GameOnly", "SetInputMode_GameOnly expects a valid player controller as 'PlayerController' target"));
}
#endif // WITH_EDITOR
}
void UWidgetBlueprintLibrary::SetFocusToGameViewport()
{
FSlateApplication::Get().SetAllUserFocusToGameViewport();
}
void UWidgetBlueprintLibrary::DrawBox(FPaintContext& Context, FVector2D Position, FVector2D Size, USlateBrushAsset* Brush, FLinearColor Tint)
{
Context.MaxLayer++;
if ( Brush )
{
FSlateDrawElement::MakeBox(
Context.OutDrawElements,
Context.MaxLayer,
Context.AllottedGeometry.ToPaintGeometry(Size, FSlateLayoutTransform(Position)),
&Brush->Brush,
ESlateDrawEffect::None,
Tint);
}
}
void UWidgetBlueprintLibrary::DrawSpline(FPaintContext& Context, FVector2D Start, FVector2D StartDir, FVector2D End, FVector2D EndDir, FLinearColor Tint, float Thickness)
{
Context.MaxLayer++;
FSlateDrawElement::MakeSpline(
Context.OutDrawElements,
Context.MaxLayer,
Context.AllottedGeometry.ToPaintGeometry(),
Start,
StartDir,
End,
EndDir,
Thickness,
ESlateDrawEffect::None,
Tint);
}
void UWidgetBlueprintLibrary::DrawLine(FPaintContext& Context, FVector2D PositionA, FVector2D PositionB, FLinearColor Tint, bool bAntiAlias, float Thickness)
{
Context.MaxLayer++;
TArray<FVector2f> Points;
Points.Add(UE::Slate::CastToVector2f(PositionA));
Points.Add(UE::Slate::CastToVector2f(PositionB));
if ((PositionA - PositionB).SquaredLength() > KINDA_SMALL_NUMBER)
{
FSlateDrawElement::MakeLines(
Context.OutDrawElements,
Context.MaxLayer,
Context.AllottedGeometry.ToPaintGeometry(),
Points,
ESlateDrawEffect::None,
Tint,
bAntiAlias,
Thickness);
}
}
void UWidgetBlueprintLibrary::DrawLines(FPaintContext& Context, const TArray<FVector2D>& Points, FLinearColor Tint, bool bAntiAlias, float Thickness)
{
if (Points.Num() < 2)
{
return;
}
// We need to trim points that might be overlapping. We convert to Float at the same time
TArray<FVector2f> ValidatedPoints;
ValidatedPoints.Reserve(Points.Num());
ValidatedPoints.Push(UE::Slate::CastToVector2f(Points[0]));
FVector2D LastPoint = Points[0];
for (int32 Index = 1; Index < Points.Num(); Index++)
{
FVector2D CurrentPoint = Points[Index];
// If a the distance between two point is very small, do not add it.
if ((CurrentPoint - LastPoint).SquaredLength() > KINDA_SMALL_NUMBER)
{
ValidatedPoints.Push(UE::Slate::CastToVector2f(Points[Index]));
LastPoint = CurrentPoint;
}
}
if (ValidatedPoints.Num() < 2)
{
return;
}
Context.MaxLayer++;
FSlateDrawElement::MakeLines(
Context.OutDrawElements,
Context.MaxLayer,
Context.AllottedGeometry.ToPaintGeometry(),
MoveTemp(ValidatedPoints),
ESlateDrawEffect::None,
Tint,
bAntiAlias,
Thickness);
}
void UWidgetBlueprintLibrary::DrawText(FPaintContext& Context, const FString& InString, FVector2D Position, FLinearColor Tint)
{
Context.MaxLayer++;
//TODO UMG Create a font asset usable as a UFont or as a slate font asset.
FSlateFontInfo FontInfo = FUMGCoreStyle::Get().GetWidgetStyle<FTextBlockStyle>("NormalText").Font;
FSlateDrawElement::MakeText(
Context.OutDrawElements,
Context.MaxLayer,
Context.AllottedGeometry.ToOffsetPaintGeometry(Position),
InString,
FontInfo,
ESlateDrawEffect::None,
Tint);
}
void UWidgetBlueprintLibrary::DrawTextFormatted(FPaintContext& Context, const FText& Text, FVector2D Position, UFont* Font, float FontSize, FName FontTypeFace, FLinearColor Tint)
{
if ( Font )
{
Context.MaxLayer++;
//TODO UMG Create a font asset usable as a UFont or as a slate font asset.
FSlateFontInfo FontInfo(Font, FontSize, FontTypeFace);
FSlateDrawElement::MakeText(
Context.OutDrawElements,
Context.MaxLayer,
Context.AllottedGeometry.ToOffsetPaintGeometry(Position),
Text,
FontInfo,
ESlateDrawEffect::None,
Tint);
}
}
FEventReply UWidgetBlueprintLibrary::Handled()
{
FEventReply Reply;
Reply.NativeReply = FReply::Handled();
return Reply;
}
FEventReply UWidgetBlueprintLibrary::Unhandled()
{
FEventReply Reply;
Reply.NativeReply = FReply::Unhandled();
return Reply;
}
FEventReply UWidgetBlueprintLibrary::CaptureMouse(FEventReply& Reply, UWidget* CapturingWidget)
{
if ( CapturingWidget )
{
TSharedPtr<SWidget> CapturingSlateWidget = CapturingWidget->GetCachedWidget();
if ( CapturingSlateWidget.IsValid() )
{
Reply.NativeReply = Reply.NativeReply.CaptureMouse(CapturingSlateWidget.ToSharedRef());
}
}
return Reply;
}
FEventReply UWidgetBlueprintLibrary::ReleaseMouseCapture(FEventReply& Reply)
{
Reply.NativeReply = Reply.NativeReply.ReleaseMouseCapture();
return Reply;
}
FEventReply UWidgetBlueprintLibrary::LockMouse( UPARAM( ref ) FEventReply& Reply, UWidget* CapturingWidget )
{
if ( CapturingWidget )
{
TSharedPtr< SWidget > SlateWidget = CapturingWidget->GetCachedWidget();
if ( SlateWidget.IsValid() )
{
Reply.NativeReply = Reply.NativeReply.LockMouseToWidget( SlateWidget.ToSharedRef() );
}
}
return Reply;
}
FEventReply UWidgetBlueprintLibrary::UnlockMouse( UPARAM( ref ) FEventReply& Reply )
{
Reply.NativeReply = Reply.NativeReply.ReleaseMouseLock();
return Reply;
}
FEventReply UWidgetBlueprintLibrary::SetUserFocus( UPARAM( ref ) FEventReply& Reply, UWidget* FocusWidget, bool bInAllUsers/* = false*/ )
{
if (FocusWidget)
{
TSharedPtr<SWidget> CapturingSlateWidget = FocusWidget->GetCachedWidget();
if (CapturingSlateWidget.IsValid())
{
Reply.NativeReply = Reply.NativeReply.SetUserFocus(CapturingSlateWidget.ToSharedRef(), EFocusCause::SetDirectly, bInAllUsers);
}
}
return Reply;
}
FEventReply UWidgetBlueprintLibrary::CaptureJoystick(FEventReply& Reply, UWidget* CapturingWidget, bool bInAllJoysticks/* = false*/)
{
return SetUserFocus(Reply, CapturingWidget, bInAllJoysticks);
}
FEventReply UWidgetBlueprintLibrary::ClearUserFocus(FEventReply& Reply, bool bInAllUsers /*= false*/)
{
Reply.NativeReply = Reply.NativeReply.ClearUserFocus(bInAllUsers);
return Reply;
}
FEventReply UWidgetBlueprintLibrary::ReleaseJoystickCapture(FEventReply& Reply, bool bInAllJoysticks /*= false*/)
{
return ClearUserFocus(Reply, bInAllJoysticks);
}
FEventReply UWidgetBlueprintLibrary::SetMousePosition(FEventReply& Reply, FVector2D NewMousePosition)
{
FIntPoint NewPoint((int32)NewMousePosition.X, (int32)NewMousePosition.Y);
Reply.NativeReply = Reply.NativeReply.SetMousePos(NewPoint);
return Reply;
}
FEventReply UWidgetBlueprintLibrary::DetectDrag(FEventReply& Reply, UWidget* WidgetDetectingDrag, FKey DragKey)
{
if ( WidgetDetectingDrag )
{
TSharedPtr<SWidget> SlateWidgetDetectingDrag = WidgetDetectingDrag->GetCachedWidget();
if ( SlateWidgetDetectingDrag.IsValid() )
{
Reply.NativeReply = Reply.NativeReply.DetectDrag(SlateWidgetDetectingDrag.ToSharedRef(), DragKey);
}
}
return Reply;
}
FEventReply UWidgetBlueprintLibrary::DetectDragIfPressed(const FPointerEvent& PointerEvent, UWidget* WidgetDetectingDrag, FKey DragKey)
{
if ( PointerEvent.GetEffectingButton() == DragKey || PointerEvent.IsTouchEvent() )
{
FEventReply Reply = UWidgetBlueprintLibrary::Handled();
return UWidgetBlueprintLibrary::DetectDrag(Reply, WidgetDetectingDrag, DragKey);
}
return UWidgetBlueprintLibrary::Unhandled();
}
FEventReply UWidgetBlueprintLibrary::EndDragDrop(FEventReply& Reply)
{
Reply.NativeReply = Reply.NativeReply.EndDragDrop();
return Reply;
}
bool UWidgetBlueprintLibrary::IsDragDropping()
{
if ( FSlateApplication::Get().IsDragDropping() )
{
TSharedPtr<FDragDropOperation> SlateDragOp = FSlateApplication::Get().GetDragDroppingContent();
if ( SlateDragOp.IsValid() && SlateDragOp->IsOfType<FUMGDragDropOp>() )
{
return true;
}
}
return false;
}
UDragDropOperation* UWidgetBlueprintLibrary::GetDragDroppingContent()
{
TSharedPtr<FDragDropOperation> SlateDragOp = FSlateApplication::Get().GetDragDroppingContent();
if ( SlateDragOp.IsValid() && SlateDragOp->IsOfType<FUMGDragDropOp>() )
{
TSharedPtr<FUMGDragDropOp> UMGDragDropOp = StaticCastSharedPtr<FUMGDragDropOp>(SlateDragOp);
return UMGDragDropOp->GetOperation();
}
return nullptr;
}
void UWidgetBlueprintLibrary::CancelDragDrop()
{
FSlateApplication::Get().CancelDragDrop();
}
FSlateBrush UWidgetBlueprintLibrary::MakeBrushFromAsset(USlateBrushAsset* BrushAsset)
{
if ( BrushAsset )
{
return BrushAsset->Brush;
}
return FSlateNoResource();
}
FSlateBrush UWidgetBlueprintLibrary::MakeBrushFromTexture(UTexture2D* Texture, int32 Width, int32 Height)
{
if ( Texture )
{
FSlateBrush Brush;
Brush.SetResourceObject(Texture);
Width = (Width > 0) ? Width : Texture->GetSizeX();
Height = (Height > 0) ? Height : Texture->GetSizeY();
Brush.ImageSize = FVector2D(Width, Height);
return Brush;
}
return FSlateNoResource();
}
FSlateBrush UWidgetBlueprintLibrary::MakeBrushFromMaterial(UMaterialInterface* Material, int32 Width, int32 Height)
{
if ( Material )
{
FSlateBrush Brush;
Brush.SetResourceObject(Material);
Brush.ImageSize = FVector2D(Width, Height);
return Brush;
}
return FSlateNoResource();
}
UObject* UWidgetBlueprintLibrary::GetBrushResource(const FSlateBrush& Brush)
{
return Brush.GetResourceObject();
}
UTexture2D* UWidgetBlueprintLibrary::GetBrushResourceAsTexture2D(const FSlateBrush& Brush)
{
return Cast<UTexture2D>(Brush.GetResourceObject());
}
UMaterialInterface* UWidgetBlueprintLibrary::GetBrushResourceAsMaterial(const FSlateBrush& Brush)
{
return Cast<UMaterialInterface>(Brush.GetResourceObject());
}
void UWidgetBlueprintLibrary::SetBrushResourceToTexture(FSlateBrush& Brush, UTexture2D* Texture)
{
Brush.SetResourceObject(Texture);
}
void UWidgetBlueprintLibrary::SetBrushResourceToMaterial(FSlateBrush& Brush, UMaterialInterface* Material)
{
Brush.SetResourceObject(Material);
}
FSlateBrush UWidgetBlueprintLibrary::NoResourceBrush()
{
return FSlateNoResource();
}
UMaterialInstanceDynamic* UWidgetBlueprintLibrary::GetDynamicMaterial(FSlateBrush& Brush)
{
UObject* Resource = Brush.GetResourceObject();
// If we already have a dynamic material, return it.
if ( UMaterialInstanceDynamic* DynamicMaterial = Cast<UMaterialInstanceDynamic>(Resource) )
{
return DynamicMaterial;
}
// If the resource has a material interface we'll just update the brush to have a dynamic material.
else if ( UMaterialInterface* Material = Cast<UMaterialInterface>(Resource) )
{
DynamicMaterial = UMaterialInstanceDynamic::Create(Material, nullptr);
Brush.SetResourceObject(DynamicMaterial);
return DynamicMaterial;
}
//TODO UMG can we do something for textures? General purpose dynamic material for them?
return nullptr;
}
void UWidgetBlueprintLibrary::DismissAllMenus()
{
FSlateApplication::Get().DismissAllMenus();
}
void UWidgetBlueprintLibrary::GetAllWidgetsOfClass(UObject* WorldContextObject, TArray<UUserWidget*>& FoundWidgets, TSubclassOf<UUserWidget> WidgetClass, bool TopLevelOnly)
{
//Prevent possibility of an ever-growing array if user uses this in a loop
FoundWidgets.Empty();
if ( !WidgetClass || !WorldContextObject )
{
return;
}
const UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull);
if ( !World )
{
return;
}
for ( TObjectIterator<UUserWidget> Itr; Itr; ++Itr )
{
UUserWidget* LiveWidget = *Itr;
// Skip any widget that's not in the current world context or that is not a child of the class specified.
if (LiveWidget->GetWorld() != World || !LiveWidget->GetClass()->IsChildOf(WidgetClass))
{
continue;
}
if ( TopLevelOnly )
{
if ( LiveWidget->IsInViewport() )
{
FoundWidgets.Add(LiveWidget);
}
}
else
{
FoundWidgets.Add(LiveWidget);
}
}
}
void UWidgetBlueprintLibrary::GetAllWidgetsWithInterface(UObject* WorldContextObject, TArray<UUserWidget*>& FoundWidgets, TSubclassOf<UInterface> Interface, bool TopLevelOnly)
{
//Prevent possibility of an ever-growing array if user uses this in a loop
FoundWidgets.Empty();
if (!Interface || !WorldContextObject)
{
return;
}
const UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull);
if (!World)
{
return;
}
for (TObjectIterator<UUserWidget> Itr; Itr; ++Itr)
{
UUserWidget* LiveWidget = *Itr;
// Skip any widget that's not in the current world context or that is not a child of the class specified.
if (LiveWidget->GetWorld() != World || !LiveWidget->GetClass()->ImplementsInterface(Interface))
{
continue;
}
if (TopLevelOnly)
{
if (LiveWidget->IsInViewport())
{
FoundWidgets.Add(LiveWidget);
}
}
else
{
FoundWidgets.Add(LiveWidget);
}
}
}
FInputEvent UWidgetBlueprintLibrary::GetInputEventFromKeyEvent(const FKeyEvent& Event)
{
return Event;
}
FKeyEvent UWidgetBlueprintLibrary::GetKeyEventFromAnalogInputEvent(const FAnalogInputEvent& Event)
{
return Event;
}
FInputEvent UWidgetBlueprintLibrary::GetInputEventFromCharacterEvent(const FCharacterEvent& Event)
{
return Event;
}
FInputEvent UWidgetBlueprintLibrary::GetInputEventFromPointerEvent(const FPointerEvent& Event)
{
return Event;
}
FInputEvent UWidgetBlueprintLibrary::GetInputEventFromNavigationEvent(const FNavigationEvent& Event)
{
return Event;
}
void UWidgetBlueprintLibrary::GetSafeZonePadding(UObject* WorldContextObject, FVector4& SafePadding, FVector2D& SafePaddingScale, FVector4& SpillOverPadding)
{
FVector2D ViewportSize = UWidgetLayoutLibrary::GetViewportSize(WorldContextObject);
FMargin PaddingSize;
FSlateApplication::Get().GetSafeZoneSize(PaddingSize, ViewportSize);
SafePadding.X = PaddingSize.Left;
SafePadding.Y = PaddingSize.Top;
SafePadding.Z = PaddingSize.Right;
SafePadding.W = PaddingSize.Bottom;
FVector2D padding(FMath::Max(SafePadding.Z, SafePadding.X), FMath::Max(SafePadding.W, SafePadding.Y));
SafePaddingScale = padding / ViewportSize;
SpillOverPadding = SafePadding;
}
void UWidgetBlueprintLibrary::SetColorVisionDeficiencyType(EColorVisionDeficiency Type, float Severity, bool CorrectDeficiency, bool ShowCorrectionWithDeficiency)
{
int32 AdjustedSeverity = FMath::TruncToInt32(FMath::Clamp(Severity, 0.f, 1.f) * 10);
FSlateApplicationBase::Get().GetRenderer()->SetColorVisionDeficiencyType(Type, AdjustedSeverity, CorrectDeficiency, ShowCorrectionWithDeficiency);
}
bool UWidgetBlueprintLibrary::SetHardwareCursor(UObject* WorldContextObject, EMouseCursor::Type CursorShape, FName CursorName, FVector2D HotSpot)
{
UWorld* World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull);
if ( World && World->IsGameWorld() )
{
if ( UGameViewportClient* ViewportClient = World->GetGameViewport() )
{
return ViewportClient->SetHardwareCursor(CursorShape, CursorName, HotSpot);
}
}
return false;
}
void UWidgetBlueprintLibrary::SetWindowTitleBarState(UWidget* TitleBarContent, EWindowTitleBarMode Mode, bool bTitleBarDragEnabled, bool bWindowButtonsVisible, bool bTitleBarVisible)
{
UGameEngine* GameEngine = Cast<UGameEngine>(GEngine);
if (GameEngine != nullptr && GameEngine->GameViewport)
{
TSharedPtr<IGameLayerManager> LayerManager = GameEngine->GameViewport->GetGameLayerManager();
if (LayerManager.IsValid())
{
LayerManager->SetWindowTitleBarState(TitleBarContent ? TitleBarContent->GetCachedWidget() : nullptr, Mode, bTitleBarDragEnabled, bWindowButtonsVisible, bTitleBarVisible);
}
}
}
void UWidgetBlueprintLibrary::RestorePreviousWindowTitleBarState()
{
UGameEngine* GameEngine = Cast<UGameEngine>(GEngine);
if (GameEngine != nullptr && GameEngine->GameViewport)
{
TSharedPtr<IGameLayerManager> LayerManager = GameEngine->GameViewport->GetGameLayerManager();
if (LayerManager.IsValid())
{
LayerManager->RestorePreviousWindowTitleBarState();
}
}
}
static UWidgetBlueprintLibrary::FOnGameWindowCloseButtonClickedDelegate OnGameWindowCloseButtonClicked;
static void OnGameWindowCloseButtonClickedSimpleDelegate()
{
if (OnGameWindowCloseButtonClicked.IsBound())
{
OnGameWindowCloseButtonClicked.Execute();
}
else
{
UGameEngine* GameEngine = Cast<UGameEngine>(GEngine);
TSharedPtr<SWindow> GameViewportWindow = GameEngine->GameViewportWindow.Pin();
if (GameViewportWindow.IsValid())
{
GameViewportWindow->RequestDestroyWindow();
}
}
}
void UWidgetBlueprintLibrary::SetWindowTitleBarOnCloseClickedDelegate(UWidgetBlueprintLibrary::FOnGameWindowCloseButtonClickedDelegate Delegate)
{
OnGameWindowCloseButtonClicked = Delegate;
SWindowTitleBarArea::SetOnCloseButtonClickedDelegate(FSimpleDelegate::CreateStatic(&OnGameWindowCloseButtonClickedSimpleDelegate));
}
void UWidgetBlueprintLibrary::SetWindowTitleBarCloseButtonActive(bool bActive)
{
SWindowTitleBarArea::SetIsCloseButtonActive(bActive);
}
#undef LOCTEXT_NAMESPACE