Files
UE_SpaceStudio/SpaceStudioClient/Plugins/MultiWindow/Source/MultiWindow/Private/MultiWindowBPLibrary.cpp
T

172 lines
6.1 KiB
C++

/************************************************************************/
/* Author: YWT20 */
/* Expected release year : 2024 */
/************************************************************************/
#include "MultiWindowBPLibrary.h"
#include "Engine.h"
#include "Blueprint/UserWidget.h"
#include "SMWindow.h"
#include "Components/Widget.h"
#include "Widgets/SWidget.h"
#include "Widgets/Layout/SConstraintCanvas.h"
#include "Framework/Application/SlateApplication.h"
#include "Engine/GameViewportClient.h"
#include "GenericPlatform/GenericApplication.h"
#include "GameFramework/GameUserSettings.h"
#include "MultiWindow.h"
UMultiWindowBPLibrary::UMultiWindowBPLibrary(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
}
bool UMultiWindowBPLibrary::CreateMultiWindow(
UObject* WorldContextObject,
UUserWidget* ContentWidget,
AMultiWindowActor*& MultiWindowActor,
FVector2D WindowPositon,
FVector2D WindowSize,
bool bIsAutoCenter,
bool bIsCreateTitle,
FString WindowTitle,
float WindowBorderMarginLeft,
float WindowBorderMarginTop,
float WindowBorderMarginRight,
float WindowBorderMarginBottom,
EWindowSizingRule WindowSizingRule,
bool bIsAutoContentDPIScale,
bool IsTopmostWindow,
bool ForceFocusToGameViewport
)
{
TSharedPtr<SMWindow> window = SNew(SMWindow)
.Title(FText::FromString(WindowTitle))
.ScreenPosition(WindowPositon)
.ClientSize(WindowSize)
.FocusWhenFirstShown(true)
.HasCloseButton(true)
.IsTopmostWindow(IsTopmostWindow)
.SupportsMaximize(true)
.LayoutBorder(FMargin(WindowBorderMarginLeft, WindowBorderMarginTop, WindowBorderMarginRight, WindowBorderMarginBottom))
.SupportsMinimize(true)
.CreateTitleBar(bIsCreateTitle)
.AutoCenter(bIsAutoCenter ? (EAutoCenter::PrimaryWorkArea) : (EAutoCenter::None))
.SizingRule((ESizingRule)WindowSizingRule);
if (!window.IsValid()) { return false; }
window->SetViewportSizeDrivenByWindow(true);
FSlateApplication& slateApp = FSlateApplication::Get();
TArray<TSharedRef <SWindow>> OutWindows;
slateApp.GetAllVisibleWindowsOrdered(OutWindows);
if (TSharedPtr <SWindow> MainMenu = OutWindows[0])
{
slateApp.AddWindowAsNativeChild(window.ToSharedRef(), MainMenu.ToSharedRef());
}
else
{
slateApp.AddWindow(window.ToSharedRef(), true);
}
if (ContentWidget)
{
window->SetContent(ContentWidget->TakeWidget());
}
window->SetWindowMode(EWindowMode::Windowed);
if (UWorld* World = GEngine->GetWorldFromContextObjectChecked(WorldContextObject)) {
MultiWindowActor = World->SpawnActor<AMultiWindowActor>(FVector::ZeroVector, FRotator::ZeroRotator);
MultiWindowActor->InitWindow(window, ContentWidget);
MultiWindowActor->WindowOriginSize = WindowSize;
MultiWindowActor->bIsAutoContentDPIScale = bIsAutoContentDPIScale;
MultiWindowActor->ForceFocusToGameViewport = ForceFocusToGameViewport;
window->MultiWindowActor = MultiWindowActor;
}
return true;
}
bool UMultiWindowBPLibrary::CreateRelativeMultiWindow(UObject* WorldContextObject, UUserWidget* ContentWidget, AMultiWindowActor*& MultiWindowActor, int32 MonitorIndex, FVector2D WindowPositon, FVector2D WindowSize, bool bIsAutoCenter, bool bIsCreateTitle, FString WindowTitle, float WindowBorderMarginLeft, float WindowBorderMarginTop, float WindowBorderMarginRight, float WindowBorderMarginBottom, EWindowSizingRule WindowSizingRule, bool bIsAutoContentDPIScale, bool IsTopmostWindow, bool ForceFocusToGameViewport)
{
CreateMultiWindow(WorldContextObject, ContentWidget, MultiWindowActor, WindowPositon, WindowSize, bIsAutoCenter, bIsCreateTitle, WindowTitle, WindowBorderMarginLeft, WindowBorderMarginTop, WindowBorderMarginRight, WindowBorderMarginBottom, WindowSizingRule, bIsAutoContentDPIScale, IsTopmostWindow);
if (MonitorIndex < 0) return false;
FDisplayMetrics displayMetrics;
displayMetrics.RebuildDisplayMetrics(displayMetrics);
if (!displayMetrics.MonitorInfo.IsValidIndex(MonitorIndex)) return false;
FMonitorInfo monitorInfo = displayMetrics.MonitorInfo[MonitorIndex];
if (!GEngine) return false;
if (bIsAutoCenter)
{
WindowPositon = FVector2D(monitorInfo.WorkArea.Left, monitorInfo.WorkArea.Top);
WindowPositon += FVector2D(monitorInfo.NativeWidth * 0.5f, monitorInfo.NativeHeight * 0.5f);
WindowPositon -= WindowSize / 2;
}
else
{
WindowPositon += FVector2D(monitorInfo.WorkArea.Left, monitorInfo.WorkArea.Top);
}
MultiWindowActor->ForceFocusToGameViewport = ForceFocusToGameViewport;
MultiWindowActor->SetWindowPosition(WindowPositon);
return true;
}
bool UMultiWindowBPLibrary::CreateMultiWindowByMonitor(UObject* WorldContextObject, UUserWidget* ContentWidget, AMultiWindowActor*& MultiWindowActor, int32 MonitorIndex, bool bIsCreateTitle, FString WindowTitle, bool ForceFocusToGameViewport)
{
CreateMultiWindow(WorldContextObject, ContentWidget, MultiWindowActor, FVector2D(), FVector2D(800.0f, 640.0f), false, bIsCreateTitle, WindowTitle, 0, 0, 0, 0, EWindowSizingRule::FixedSize, false, true);
if (MonitorIndex < 0) return false;
FDisplayMetrics displayMetrics;
displayMetrics.RebuildDisplayMetrics(displayMetrics);
if (!displayMetrics.MonitorInfo.IsValidIndex(MonitorIndex)) return false;
FMonitorInfo monitorInfo = displayMetrics.MonitorInfo[MonitorIndex];
if (!GEngine) return false;
MultiWindowActor->SetWindowPosition(FVector2D(monitorInfo.WorkArea.Left, monitorInfo.WorkArea.Top));
MultiWindowActor->ForceFocusToGameViewport = ForceFocusToGameViewport;
MultiWindowActor->SetWindowMaximize();
return true;
}
int32 UMultiWindowBPLibrary::GetMonitorCount()
{
FDisplayMetrics displayMetrics;
displayMetrics.RebuildDisplayMetrics(displayMetrics);
return displayMetrics.MonitorInfo.Num();
}
int32 UMultiWindowBPLibrary::GetPrimaryMonitorIndex()
{
FDisplayMetrics displayMetrics;
displayMetrics.RebuildDisplayMetrics(displayMetrics);
for (int32 i = 0; i < displayMetrics.MonitorInfo.Num(); i++)
{
if (displayMetrics.MonitorInfo[i].bIsPrimary) return i;
}
return -1;
}
void UMultiWindowBPLibrary::MW_PrintToLog()
{
FDisplayMetrics displayMetrics;
displayMetrics.RebuildDisplayMetrics(displayMetrics);
displayMetrics.PrintToLog();
}