增加多屏显示,视频播放
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
/************************************************************************/
|
||||
/* Author: YWT20 */
|
||||
/* Expected release year : 2024 */
|
||||
/************************************************************************/
|
||||
|
||||
using UnrealBuildTool;
|
||||
|
||||
public class MultiWindow : ModuleRules
|
||||
{
|
||||
public MultiWindow(ReadOnlyTargetRules Target) : base(Target)
|
||||
{
|
||||
PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs;
|
||||
|
||||
PublicIncludePaths.AddRange(
|
||||
new string[] {
|
||||
// ... add public include paths required here ...
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
PrivateIncludePaths.AddRange(
|
||||
new string[] {
|
||||
// ... add other private include paths required here ...
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
PublicDependencyModuleNames.AddRange(
|
||||
new string[]
|
||||
{
|
||||
"Core",
|
||||
// ... add other public dependencies that you statically link with here ...
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
PrivateDependencyModuleNames.AddRange(
|
||||
new string[]
|
||||
{
|
||||
"CoreUObject",
|
||||
"Engine",
|
||||
"Slate",
|
||||
"SlateCore",
|
||||
"UMG",
|
||||
"InputCore",
|
||||
"ApplicationCore",
|
||||
// ... add private dependencies that you statically link with here ...
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
DynamicallyLoadedModuleNames.AddRange(
|
||||
new string[]
|
||||
{
|
||||
// ... add any modules that your module loads dynamically here ...
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/************************************************************************/
|
||||
/* Author: YWT20 */
|
||||
/* Expected release year : 2024 */
|
||||
/************************************************************************/
|
||||
|
||||
#include "MultiWindow.h"
|
||||
|
||||
#define LOCTEXT_NAMESPACE "FMultiWindowModule"
|
||||
|
||||
void FMultiWindowModule::StartupModule()
|
||||
{
|
||||
// This code will execute after your module is loaded into memory; the exact timing is specified in the .uplugin file per-module
|
||||
|
||||
}
|
||||
|
||||
void FMultiWindowModule::ShutdownModule()
|
||||
{
|
||||
// This function may be called during shutdown to clean up your module. For modules that support dynamic reloading,
|
||||
// we call this function before unloading the module.
|
||||
|
||||
}
|
||||
|
||||
#undef LOCTEXT_NAMESPACE
|
||||
|
||||
IMPLEMENT_MODULE(FMultiWindowModule, MultiWindow)
|
||||
+242
@@ -0,0 +1,242 @@
|
||||
/************************************************************************/
|
||||
/* Author: YWT20 */
|
||||
/* Expected release year : 2024 */
|
||||
/************************************************************************/
|
||||
|
||||
|
||||
#include "MultiWindowActor.h"
|
||||
#include "Components/Widget.h"
|
||||
#include "Widgets/SWindow.h"
|
||||
#include "Widgets/Layout/SConstraintCanvas.h"
|
||||
#include "Engine.h"
|
||||
#include <SMWindow.h>
|
||||
|
||||
|
||||
AMultiWindowActor::AMultiWindowActor()
|
||||
{
|
||||
PrimaryActorTick.bCanEverTick = true;
|
||||
}
|
||||
|
||||
void AMultiWindowActor::BeginPlay()
|
||||
{
|
||||
Super::BeginPlay();
|
||||
viewPort = GEngine->GameViewport->Viewport;
|
||||
}
|
||||
|
||||
void AMultiWindowActor::EndPlay(const EEndPlayReason::Type EndPlayReason)
|
||||
{
|
||||
Super::EndPlay(EndPlayReason);
|
||||
SetWindowClose();
|
||||
}
|
||||
|
||||
void AMultiWindowActor::Tick(float DeltaTime)
|
||||
{
|
||||
Super::Tick(DeltaTime);
|
||||
UpdateContentDPI();
|
||||
|
||||
if (WindowPos != GetWindowPositoin())
|
||||
{
|
||||
WindowPos = GetWindowPositoin();
|
||||
OnWindowMoved.Broadcast(WindowPos);
|
||||
}
|
||||
|
||||
if (ForceFocusToGameViewport && !viewPort->HasFocus())
|
||||
{
|
||||
if (!timerHandle.IsValid())
|
||||
{
|
||||
GetWorldTimerManager().SetTimer(timerHandle, this, &AMultiWindowActor::CheckFocus, focusTime, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AMultiWindowActor::InitWindow(TSharedPtr<SWindow> InWindow, UUserWidget* InContentWidget)
|
||||
{
|
||||
if (IsPendingKillPending()) return;
|
||||
|
||||
window = InWindow;
|
||||
contentWidget = InContentWidget;
|
||||
window->GetOnWindowClosedEvent().AddUObject(this, &AMultiWindowActor::EventOnWindowClose);
|
||||
WindowPos = GetWindowPositoin();
|
||||
|
||||
window->GetOnWindowActivatedEvent().AddLambda([&]() {
|
||||
OnWindowActivated.Broadcast();
|
||||
});
|
||||
window->GetOnWindowDeactivatedEvent().AddLambda([&]() {
|
||||
OnWindowDeactivated.Broadcast();
|
||||
});
|
||||
}
|
||||
|
||||
void AMultiWindowActor::UpdateContentDPI()
|
||||
{
|
||||
if (bIsAutoContentDPIScale && WindowOriginSize != GetWindowSize())
|
||||
{
|
||||
FVector2D TempWindowDPI = GetWindowSize() / WindowOriginSize;
|
||||
if (TempWindowDPI != WindowDPI)
|
||||
{
|
||||
WindowDPI = TempWindowDPI;
|
||||
contentWidget->SetRenderScale(WindowDPI);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AMultiWindowActor::CheckFocus()
|
||||
{
|
||||
if (!viewPort->HasFocus())
|
||||
{
|
||||
FSlateApplication::Get().SetAllUserFocusToGameViewport();
|
||||
}
|
||||
GetWorldTimerManager().ClearTimer(timerHandle);
|
||||
}
|
||||
|
||||
void AMultiWindowActor::SetWindowShow(bool bIsShow)
|
||||
{
|
||||
if (window.IsValid())
|
||||
{
|
||||
if (bIsShow)
|
||||
{
|
||||
window->ShowWindow();
|
||||
}
|
||||
else
|
||||
{
|
||||
window->HideWindow();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AMultiWindowActor::SetWindowContentWidget(UUserWidget* ContentWidget)
|
||||
{
|
||||
if (ContentWidget && window.IsValid())
|
||||
{
|
||||
window->SetContent(ContentWidget->TakeWidget());
|
||||
contentWidget = ContentWidget;
|
||||
}
|
||||
}
|
||||
|
||||
UUserWidget* AMultiWindowActor::GetWindowContentWidget()
|
||||
{
|
||||
return contentWidget;
|
||||
}
|
||||
|
||||
void AMultiWindowActor::SetWindowSize(FVector2D WindowSize)
|
||||
{
|
||||
if (window)
|
||||
{
|
||||
window->Resize(WindowSize);
|
||||
WindowOriginSize = WindowSize;
|
||||
}
|
||||
}
|
||||
|
||||
void AMultiWindowActor::SetWindowPosition(FVector2D WindowPosition)
|
||||
{
|
||||
if (window)
|
||||
{
|
||||
window->MoveWindowTo(WindowPosition);
|
||||
}
|
||||
}
|
||||
|
||||
FVector2D AMultiWindowActor::GetWindowSize()
|
||||
{
|
||||
if (window)
|
||||
{
|
||||
FVector2D tempSize = window->GetSizeInScreen();
|
||||
FMargin tempBorderSize = window->GetWindowBorderSize(false);
|
||||
tempSize.X -= tempBorderSize.GetDesiredSize().X;
|
||||
tempSize.Y -= tempBorderSize.GetDesiredSize().Y + window->GetTitleBarSize().Get();
|
||||
return tempSize;
|
||||
}
|
||||
return FVector2D();
|
||||
}
|
||||
|
||||
FVector2D AMultiWindowActor::GetWindowPositoin()
|
||||
{
|
||||
if (window)
|
||||
{
|
||||
FVector2D tempSize = window->GetPositionInScreen();
|
||||
return tempSize;
|
||||
}
|
||||
return FVector2D();
|
||||
}
|
||||
|
||||
//FVector2D AMultiWindowActor::GetWindowDPI()
|
||||
//{
|
||||
// return WindowDPI;
|
||||
//}
|
||||
|
||||
void AMultiWindowActor::SetWindowTitle(const FString& WindowTitle)
|
||||
{
|
||||
if (window)
|
||||
{
|
||||
window->SetTitle(FText::FromString(WindowTitle));
|
||||
}
|
||||
}
|
||||
|
||||
void AMultiWindowActor::SetWindowMaximize()
|
||||
{
|
||||
if (window)
|
||||
{
|
||||
window->Maximize();
|
||||
}
|
||||
}
|
||||
|
||||
void AMultiWindowActor::SetWindowRestore()
|
||||
{
|
||||
if (window)
|
||||
{
|
||||
window->Restore();
|
||||
}
|
||||
}
|
||||
|
||||
void AMultiWindowActor::SetWindowMinimize()
|
||||
{
|
||||
if (window)
|
||||
{
|
||||
window->Minimize();
|
||||
}
|
||||
}
|
||||
|
||||
void AMultiWindowActor::SetWindowClose()
|
||||
{
|
||||
if (window)
|
||||
{
|
||||
if (OnWindowClose.IsBound())
|
||||
{
|
||||
OnWindowClose.Broadcast();
|
||||
}
|
||||
OnWindowClose.Clear();
|
||||
|
||||
window->GetOnWindowClosedEvent().RemoveAll(this);
|
||||
window->GetOnWindowActivatedEvent().RemoveAll(this);
|
||||
window->GetOnWindowDeactivatedEvent().RemoveAll(this);
|
||||
|
||||
//window->DestroyWindowImmediately();
|
||||
window->RequestDestroyWindow();
|
||||
window.Reset();
|
||||
Destroy();
|
||||
}
|
||||
}
|
||||
|
||||
FText AMultiWindowActor::GetWindowTitle()
|
||||
{
|
||||
if (window)
|
||||
{
|
||||
return window->GetTitle();
|
||||
}
|
||||
return FText();
|
||||
}
|
||||
|
||||
void AMultiWindowActor::SetDPIScaleFactor(const float Factor)
|
||||
{
|
||||
if (window)
|
||||
{
|
||||
window->SetDPIScaleFactor(Factor);
|
||||
}
|
||||
}
|
||||
|
||||
float AMultiWindowActor::GetDPIScaleFactor() const
|
||||
{
|
||||
if (window)
|
||||
{
|
||||
return window->GetDPIScaleFactor();
|
||||
}
|
||||
return 0.0f;
|
||||
}
|
||||
+171
@@ -0,0 +1,171 @@
|
||||
/************************************************************************/
|
||||
/* 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();
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/************************************************************************/
|
||||
/* Author: YWT20 */
|
||||
/* Expected release year : 2024 */
|
||||
/************************************************************************/
|
||||
|
||||
|
||||
#include "SMWindow.h"
|
||||
#include "MultiWindowActor.h"
|
||||
|
||||
FReply SMWindow::OnKeyChar(const FGeometry& MyGeometry, const FCharacterEvent& InCharacterEvent)
|
||||
{
|
||||
if (MultiWindowActor)
|
||||
{
|
||||
return MultiWindowActor->contentWidget->OnKeyChar(MyGeometry, InCharacterEvent).NativeReply;
|
||||
}
|
||||
return FReply::Unhandled();
|
||||
}
|
||||
|
||||
FReply SMWindow::OnPreviewKeyDown(const FGeometry& MyGeometry, const FKeyEvent& InKeyEvent)
|
||||
{
|
||||
if (MultiWindowActor)
|
||||
{
|
||||
return MultiWindowActor->contentWidget->OnPreviewKeyDown(MyGeometry, InKeyEvent).NativeReply;
|
||||
}
|
||||
return FReply::Unhandled();
|
||||
}
|
||||
|
||||
FReply SMWindow::OnKeyDown(const FGeometry& MyGeometry, const FKeyEvent& InKeyEvent)
|
||||
{
|
||||
if (MultiWindowActor)
|
||||
{
|
||||
return MultiWindowActor->contentWidget->OnKeyDown(MyGeometry, InKeyEvent).NativeReply;
|
||||
}
|
||||
return FReply::Unhandled();
|
||||
}
|
||||
|
||||
FReply SMWindow::OnKeyUp(const FGeometry& MyGeometry, const FKeyEvent& InKeyEvent)
|
||||
{
|
||||
if (MultiWindowActor)
|
||||
{
|
||||
return MultiWindowActor->contentWidget->OnKeyUp(MyGeometry, InKeyEvent).NativeReply;
|
||||
}
|
||||
return FReply::Unhandled();
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
/************************************************************************/
|
||||
/* Author: YWT20 */
|
||||
/* Expected release year : 2024 */
|
||||
/************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Modules/ModuleManager.h"
|
||||
|
||||
class FMultiWindowModule : public IModuleInterface
|
||||
{
|
||||
public:
|
||||
|
||||
/** IModuleInterface implementation */
|
||||
virtual void StartupModule() override;
|
||||
virtual void ShutdownModule() override;
|
||||
};
|
||||
@@ -0,0 +1,147 @@
|
||||
/************************************************************************/
|
||||
/* Author: YWT20 */
|
||||
/* Expected release year : 2024 */
|
||||
/************************************************************************/
|
||||
|
||||
#pragma once
|
||||
#include "CoreMinimal.h"
|
||||
#include "Blueprint/UserWidget.h"
|
||||
#include "GameFramework/Actor.h"
|
||||
#include "Framework/Application/SlateApplication.h"
|
||||
#include "TimerManager.h"
|
||||
#include "MultiWindowActor.generated.h"
|
||||
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnWindowEvent);
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnWindowMovedEvent, FVector2D, pos);
|
||||
|
||||
UCLASS()
|
||||
class MULTIWINDOW_API AMultiWindowActor : public AActor
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
AMultiWindowActor();
|
||||
|
||||
protected:
|
||||
virtual void BeginPlay() override;
|
||||
|
||||
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
|
||||
public:
|
||||
virtual void Tick(float DeltaTime) override;
|
||||
|
||||
TSharedPtr<SWindow> window = nullptr;
|
||||
|
||||
UUserWidget* contentWidget;
|
||||
|
||||
FViewport* viewPort;
|
||||
|
||||
FTimerHandle timerHandle;
|
||||
public:
|
||||
FVector2D WindowOriginSize;
|
||||
|
||||
FVector2D WindowPos;
|
||||
|
||||
FVector2D WindowDPI;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "MultiWindow")
|
||||
float focusTime = 0.25f;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "MultiWindow")
|
||||
bool ForceFocusToGameViewport;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "MultiWindow")
|
||||
bool bIsAutoContentDPIScale;
|
||||
|
||||
// Invoked when the window is about to be closed.
|
||||
UPROPERTY(BlueprintAssignable, Category = "MultiWindow|Event")
|
||||
FOnWindowEvent OnWindowClose;
|
||||
|
||||
// Invoked when the window has been activated.
|
||||
UPROPERTY(BlueprintAssignable, Category = "MultiWindow|Event")
|
||||
FOnWindowEvent OnWindowActivated;
|
||||
|
||||
// Invoked when the window has been deactivated.
|
||||
UPROPERTY(BlueprintAssignable, Category = "MultiWindow|Event")
|
||||
FOnWindowEvent OnWindowDeactivated;
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category = "MultiWindow|Event")
|
||||
FOnWindowMovedEvent OnWindowMoved;
|
||||
|
||||
public:
|
||||
void EventOnWindowClose(const TSharedRef<SWindow>& InSWindow)
|
||||
{
|
||||
if (IsPendingKillPending()) return;
|
||||
if (OnWindowClose.IsBound())
|
||||
{
|
||||
OnWindowClose.Broadcast();
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
// Initialize multi-window data
|
||||
void InitWindow(TSharedPtr<SWindow> InWindow, UUserWidget* InContentWidget);
|
||||
|
||||
void UpdateContentDPI();
|
||||
|
||||
void CheckFocus();
|
||||
|
||||
// Set the window visible
|
||||
UFUNCTION(BlueprintCallable, Category = "MultiWindow")
|
||||
void SetWindowShow(bool bIsShow);
|
||||
|
||||
// Set the widget content for this window
|
||||
UFUNCTION(BlueprintCallable, Category = "MultiWindow")
|
||||
void SetWindowContentWidget(UUserWidget* ContentWidget);
|
||||
|
||||
// Set the widget content for this window
|
||||
UFUNCTION(BlueprintPure, Category = "MultiWindow")
|
||||
UUserWidget* GetWindowContentWidget();
|
||||
|
||||
// Resize the window to be dpi scaled NewClientSize immediately
|
||||
UFUNCTION(BlueprintCallable, Category = "MultiWindow")
|
||||
void SetWindowSize(FVector2D WindowSize);
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "MultiWindow")
|
||||
FVector2D GetWindowSize();
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "MultiWindow")
|
||||
void SetWindowPosition(FVector2D WindowPosition);
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "MultiWindow")
|
||||
FVector2D GetWindowPositoin();
|
||||
|
||||
//UFUNCTION(BlueprintPure, Category = "MultiWindow")
|
||||
// FVector2D GetWindowDPI();
|
||||
|
||||
// Sets the current window title
|
||||
UFUNCTION(BlueprintCallable, Category = "MultiWindow")
|
||||
void SetWindowTitle(const FString& WindowTitle);
|
||||
|
||||
// Maximize window size
|
||||
UFUNCTION(BlueprintCallable, Category = "MultiWindow")
|
||||
void SetWindowMaximize();
|
||||
|
||||
// Restore window size
|
||||
UFUNCTION(BlueprintCallable, Category = "MultiWindow")
|
||||
void SetWindowRestore();
|
||||
|
||||
// Minimize window size
|
||||
UFUNCTION(BlueprintCallable, Category = "MultiWindow")
|
||||
void SetWindowMinimize();
|
||||
|
||||
// Close the window
|
||||
UFUNCTION(BlueprintCallable, Category = "MultiWindow")
|
||||
void SetWindowClose();
|
||||
|
||||
// Grabs the current window title
|
||||
UFUNCTION(BlueprintPure, Category = "MultiWindow | V2")
|
||||
FText GetWindowTitle();
|
||||
|
||||
// Overrides the DPI scale factor of the native window
|
||||
UFUNCTION(BlueprintCallable, Category = "MultiWindow | V2")
|
||||
void SetDPIScaleFactor(const float Factor);
|
||||
|
||||
// Returns the DPI scale factor of the native window
|
||||
UFUNCTION(BlueprintPure, Category = "MultiWindow | V2")
|
||||
float GetDPIScaleFactor() const;
|
||||
};
|
||||
+96
@@ -0,0 +1,96 @@
|
||||
/************************************************************************/
|
||||
/* Author: YWT20 */
|
||||
/* Expected release year : 2024 */
|
||||
/************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Kismet/BlueprintFunctionLibrary.h"
|
||||
#include "MultiWindowActor.h"
|
||||
#include "MultiWindowBPLibrary.generated.h"
|
||||
|
||||
UENUM(BlueprintType)
|
||||
enum class EWindowSizingRule : uint8
|
||||
{
|
||||
/* The windows size fixed and cannot be resized **/
|
||||
FixedSize,
|
||||
|
||||
/** The window size is computed from its content and cannot be resized by users */
|
||||
Autosized,
|
||||
|
||||
/** The window can be resized by users */
|
||||
UserSized,
|
||||
};
|
||||
|
||||
UCLASS()
|
||||
class UMultiWindowBPLibrary : public UBlueprintFunctionLibrary
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
public:
|
||||
// Create new window
|
||||
UFUNCTION(BlueprintCallable, Category = "MultiWindow | V1", meta = (WorldContext = "WorldContextObject", AdvancedDisplay = "5"))
|
||||
static bool CreateMultiWindow(
|
||||
UObject* WorldContextObject,
|
||||
UUserWidget* ContentWidget,
|
||||
AMultiWindowActor*& MultiWindowActor,
|
||||
FVector2D WindowPositon = FVector2D(0, 0),
|
||||
FVector2D WindowSize = FVector2D(500, 500),
|
||||
bool bIsAutoCenter = false,
|
||||
bool bIsCreateTitle = true,
|
||||
FString WindowTitle = FString(TEXT("MultiWindow")),
|
||||
float WindowBorderMarginLeft = 5.0f,
|
||||
float WindowBorderMarginTop = 5.0f,
|
||||
float WindowBorderMarginRight = 5.0f,
|
||||
float WindowBorderMarginBottom = 5.0f,
|
||||
EWindowSizingRule WindowSizingRule = EWindowSizingRule::UserSized,
|
||||
bool bIsAutoContentDPIScale = false,
|
||||
bool IsTopmostWindow = false,
|
||||
bool ForceFocusToGameViewport = false
|
||||
);
|
||||
|
||||
// Create new relative window
|
||||
UFUNCTION(BlueprintCallable, Category = "MultiWindow | V2", meta = (WorldContext = "WorldContextObject", AdvancedDisplay = "5"))
|
||||
static bool CreateRelativeMultiWindow(
|
||||
UObject* WorldContextObject,
|
||||
UUserWidget* ContentWidget,
|
||||
AMultiWindowActor*& MultiWindowActor,
|
||||
int32 MonitorIndex,
|
||||
FVector2D WindowPositon = FVector2D(0, 0),
|
||||
FVector2D WindowSize = FVector2D(500, 500),
|
||||
bool bIsAutoCenter = false,
|
||||
bool bIsCreateTitle = true,
|
||||
FString WindowTitle = FString(TEXT("MultiWindow")),
|
||||
float WindowBorderMarginLeft = 5.0f,
|
||||
float WindowBorderMarginTop = 5.0f,
|
||||
float WindowBorderMarginRight = 5.0f,
|
||||
float WindowBorderMarginBottom = 5.0f,
|
||||
EWindowSizingRule WindowSizingRule = EWindowSizingRule::UserSized,
|
||||
bool bIsAutoContentDPIScale = false,
|
||||
bool IsTopmostWindow = false,
|
||||
bool ForceFocusToGameViewport = false
|
||||
);
|
||||
|
||||
// Create new window by Monitor
|
||||
UFUNCTION(BlueprintCallable, Category = "MultiWindow | V2", meta = (WorldContext = "WorldContextObject"))
|
||||
static bool CreateMultiWindowByMonitor(
|
||||
UObject* WorldContextObject,
|
||||
UUserWidget* ContentWidget,
|
||||
AMultiWindowActor*& MultiWindowActor,
|
||||
int32 MonitorIndex,
|
||||
bool bIsCreateTitle = false,
|
||||
FString WindowTitle = FString(TEXT("MultiWindow")),
|
||||
bool ForceFocusToGameViewport = false
|
||||
);
|
||||
|
||||
// Get monitor count
|
||||
UFUNCTION(BlueprintPure, Category = "MultiWindow | V2")
|
||||
static int32 GetMonitorCount();
|
||||
|
||||
// Get primary monitor index
|
||||
UFUNCTION(BlueprintPure, Category = "MultiWindow | V2")
|
||||
static int32 GetPrimaryMonitorIndex();
|
||||
|
||||
// Logs out display metrics
|
||||
UFUNCTION(BlueprintCallable, Category = "MultiWindow | V2")
|
||||
static void MW_PrintToLog();
|
||||
};
|
||||
@@ -0,0 +1,27 @@
|
||||
/************************************************************************/
|
||||
/* Author: YWT20 */
|
||||
/* Expected release year : 2024 */
|
||||
/************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Framework/Application/SlateApplication.h"
|
||||
#include "Widgets/SWindow.h"
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class MULTIWINDOW_API SMWindow : public SWindow
|
||||
{
|
||||
public:
|
||||
class AMultiWindowActor* MultiWindowActor;
|
||||
public:
|
||||
virtual FReply OnKeyChar(const FGeometry& MyGeometry, const FCharacterEvent& InCharacterEvent) override;
|
||||
|
||||
virtual FReply OnPreviewKeyDown(const FGeometry& MyGeometry, const FKeyEvent& InKeyEvent) override;
|
||||
|
||||
virtual FReply OnKeyDown(const FGeometry& MyGeometry, const FKeyEvent& InKeyEvent) override;
|
||||
|
||||
virtual FReply OnKeyUp(const FGeometry& MyGeometry, const FKeyEvent& InKeyEvent) override;
|
||||
};
|
||||
Reference in New Issue
Block a user