172 lines
6.1 KiB
C++
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();
|
|
}
|