Agrarsense
UnrealWindow.cpp
Go to the documentation of this file.
1// Copyright (c) 2023 FrostBit Software Lab at the Lapland University of Applied Sciences
2//
3// This work is licensed under the terms of the MIT license.
4// For a copy, see <https://opensource.org/licenses/MIT>.
5
6#include "UnrealWindow.h"
7#include "Framework/Application/SlateApplication.h"
8#include "Widgets/SWidget.h"
9#include "Blueprint/UserWidget.h"
10#include "Widgets/SOverlay.h"
11
12FUnrealWindow::FUnrealWindow(int32 Width, int32 Height, FString WindowName, bool IsInitiallyMinized)
13{
14 // Set window width and height
15 WindowWidth = Width;
16 WindowHeight = Height;
17
18 // Do not support Window minimize button,
19 // because this causes Camera sensors to stop rendering when window is minimized.
20 // This is default behavior in Unreal Engine.
21 bool SupportMinimize = false;
22
23#ifdef EngineAllowRenderingMinimized
24 // Unless when we are using AGRARSENSE Unreal Engine fork,
25 // where SWindow has extra boolean which allows rendering when a window is minimized.
26 SupportMinimize = true;
27#endif
28
29 // Create SWindow
30 sWindow = SNew(SWindow)
31 .Title(FText::FromString(WindowName))
32 .ScreenPosition(FVector2D(0, 0))
33 .ClientSize(FVector2D(WindowWidth, WindowHeight))
34 .AutoCenter(EAutoCenter::PreferredWorkArea)
35 .UseOSWindowBorder(true)
36 .SaneWindowPlacement(false)
37 .SizingRule(ESizingRule::UserSized)
38 .SupportsMinimize(SupportMinimize)
39#if PLATFORM_LINUX
40 .FocusWhenFirstShown(IsInitiallyMinized) // only for Linux, on Windows this causes Window to be wrong size for some reason
41#endif
42 .IsInitiallyMinimized(IsInitiallyMinized);
43
44#ifdef EngineAllowRenderingMinimized
45 // Set SWindow AllowRenderingMinimized to true that allows SWindow to be rendered even when minimized.
46 // Defined and implemented in AGRARSENSE Unreal Engine fork
47 sWindow->AllowRenderingMinimized = true;
48#endif
49
50 // Add window to FSlateApplication
51 FSlateApplication::Get().AddWindow(sWindow.ToSharedRef());
52
53 // Assign window events delegates
55 sWindow->SetOnWindowClosed(onWindowClosedDelegate);
56
57 // Create and assign viewport to window
59 sWindow->SetContent(Viewport.ToSharedRef());
60
61 // Set references
62 ViewportClient = Viewport->ViewportClient;
63 SceneViewport = Viewport->SceneViewport;
64 sViewport = Viewport->Viewport;
65
66 // Resize window
68}
69
71{
73
74 FullScreenOverlay.Reset();
75 ViewportClient.Reset();
76 SceneViewport.Reset();
77 sViewport.Reset();
78 Viewport.Reset();
79 sWindow.Reset();
80
81 AddedWidgets.Empty();
82}
83
84void FUnrealWindow::SetupComponent(UTextureRenderTarget2D* TextureRenderTarget)
85{
86 if (ViewportClient.IsValid() && TextureRenderTarget)
87 {
88 ViewportClient->TextRenderTarget2D = TextureRenderTarget;
89 ViewportClient->texture = TextureRenderTarget->GetResource();
92 }
93}
94
95void FUnrealWindow::UpdateTexture(FTextureResource* Texture)
96{
97 if (ViewportClient.IsValid() && Texture)
98 {
99 ViewportClient->texture = Texture;
102 }
103}
104
106{
107 if (DrawToScreen)
108 {
109#if WITH_EDITOR
110 UE_LOG(LogTemp, Warning, TEXT("UnrealWindow.cpp: We are already drawing automatically, we should not draw manually!"));
111#endif
112 return;
113 }
114
115 if (SceneViewport.IsValid())
116 {
117 SceneViewport->Draw();
118 }
119}
120
121void FUnrealWindow::OnWindowClosed(const TSharedRef<SWindow>& SWindow)
122{
124}
125
127{
128 if (sWindow.IsValid())
129 {
130 sWindow->RequestDestroyWindow();
131 }
132}
133
134void FUnrealWindow::ResizeWindow(int32 width, int32 height)
135{
136 if (ViewportClient.IsValid() && SceneViewport.IsValid() && sWindow.IsValid())
137 {
138 WindowWidth = width;
139 WindowHeight = height;
140
143
144 SceneViewport->SetViewportSize(WindowWidth, WindowHeight);
145 sWindow->Resize(FVector2D(WindowWidth, WindowHeight));
146 }
147}
148
149void FUnrealWindow::AddUWidgetToWindow(UWidget* WidgetToAdd)
150{
151 if (!WidgetToAdd || !sWindow.IsValid())
152 {
153 return;
154 }
155
156 if (!FullScreenOverlay.IsValid())
157 {
158 // Create a full-screen SOverlay to contain the camera image and custom widget
159 FullScreenOverlay = SNew(SOverlay);
160
161 // Create a slot for current viewport widget
162 FullScreenOverlay->AddSlot(0)
163 .HAlign(HAlign_Fill)
164 .VAlign(VAlign_Fill)
165 [
166 Viewport.ToSharedRef()
167 ];
168 }
169
171
172 // Create a slot for the new widget
174 .HAlign(HAlign_Fill)
175 .VAlign(VAlign_Fill)
176 [
177 WidgetToAdd->TakeWidget()
178 ];
179
180 // Store information about the added widget
181 FAddedWidgetInfo WidgetInfo;
182 WidgetInfo.Widget = WidgetToAdd;
183 WidgetInfo.Index = AddedWidgetCount;
184 AddedWidgets.Add(WidgetInfo);
185
186 // Set the updated overlay as the window content
187 sWindow->SetContent(FullScreenOverlay.ToSharedRef());
188}
189
190void FUnrealWindow::RemoveUWidgetFromWindow(UWidget* WidgetToRemove)
191{
192 if (!WidgetToRemove || !sWindow.IsValid() || !FullScreenOverlay.IsValid())
193 {
194 return;
195 }
196
197 // Not the prettiest but works for this use case.
198 int32 WidgetIndexToRemove = -1;
199 for (int32 Index = 0; Index < AddedWidgets.Num(); ++Index)
200 {
201 if (AddedWidgets[Index].Widget == WidgetToRemove)
202 {
203 WidgetIndexToRemove = Index;
204 break;
205 }
206 }
207
208 if (WidgetIndexToRemove != -1)
209 {
210 // Remove Widget from slot (arrays start at 0 but slot 0 is the camera view)
211 FullScreenOverlay->RemoveSlot(WidgetIndexToRemove + 1);
212
213 // Set the updated overlay as the window content
214 sWindow->SetContent(FullScreenOverlay.ToSharedRef());
215
216 // Remove the widget info from the array
217 AddedWidgets.RemoveAt(WidgetIndexToRemove);
218 }
219}
TSharedPtr< FUnrealWindowViewportClient > ViewportClient
Definition: UnrealWindow.h:160
void UpdateTexture(FTextureResource *Texture)
FOnWindowClosed onWindowClosedDelegate
Definition: UnrealWindow.h:158
void SetupComponent(UTextureRenderTarget2D *TextureRenderTarget)
TSharedPtr< SUnrealWindowViewport > Viewport
Definition: UnrealWindow.h:161
void AddUWidgetToWindow(UWidget *WidgetToAdd)
void OnWindowClosed(const TSharedRef< SWindow > &Window)
int32 WindowHeight
Definition: UnrealWindow.h:152
TArray< FAddedWidgetInfo > AddedWidgets
Definition: UnrealWindow.h:170
void ResizeWindow(int32 Width, int32 Height)
TSharedPtr< SWindow > sWindow
Definition: UnrealWindow.h:165
FUnrealWindow(int32 Width, int32 Height, FString WindowName="Camera", bool IsInitiallyMinized=false)
void DestroyWindow()
TSharedPtr< FSceneViewport > SceneViewport
Definition: UnrealWindow.h:163
TSharedPtr< SViewport > sViewport
Definition: UnrealWindow.h:164
int32 AddedWidgetCount
Definition: UnrealWindow.h:154
TSharedPtr< SOverlay > FullScreenOverlay
Definition: UnrealWindow.h:167
void RemoveUWidgetFromWindow(UWidget *WidgetToRemove)
UWidget * Widget
Definition: UnrealWindow.h:22