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
13
14FUnrealWindow::FUnrealWindow(int32 Width, int32 Height, FString WindowName)
15{
16 // Set window width and height
17 WindowWidth = Width;
18 WindowHeight = Height;
19
20 // Do not support Window minimize button,
21 // because this causes Camera sensors to stop rendering when window is minimized.
22 bool SupportMinimize = false;
23
24#ifdef EngineAllowRenderingMinimized
25 // Unless when we are using AGRARSENSE Unreal Engine fork,
26 // where SWindow has extra boolean which allows rendering when a window is minimized.
27 SupportMinimize = true;
28#endif
29
30 // Create SWindow
31 sWindow = SNew(SWindow)
32 .SupportsMinimize(SupportMinimize)
34 .Title(FText::FromString(WindowName))
35 .ScreenPosition(FVector2D(0, 0))
36 .ClientSize(FVector2D(WindowWidth, WindowHeight))
37 .AutoCenter(EAutoCenter::PreferredWorkArea)
38 .UseOSWindowBorder(true)
39 .SaneWindowPlacement(false)
40 .SizingRule(ESizingRule::UserSized);
41
42#ifdef EngineAllowRenderingMinimized
43 // Set SWindow AllowRenderingMinimized to true that allows SWindow to be rendered even when minimized.
44 // Defined and implemented in AGRARSENSE Unreal Engine fork
45 sWindow->AllowRenderingMinimized = true;
46#endif
47
48 // Add window to FSlateApplication
49 FSlateApplication::Get().AddWindow(sWindow.ToSharedRef());
50
51 // Assign window events delegates
53 sWindow->SetOnWindowClosed(onWindowClosedDelegate);
54
55 // Create and assign viewport to window
57 sWindow->SetContent(Viewport.ToSharedRef());
58
59 // Set references
60 ViewportClient = Viewport->ViewportClient;
61 SceneViewport = Viewport->SceneViewport;
62 sViewport = Viewport->Viewport;
63
64 // Resize window
66}
67
69{
71
72 FullScreenOverlay.Reset();
73 ViewportClient.Reset();
74 SceneViewport.Reset();
75 sViewport.Reset();
76 Viewport.Reset();
77 sWindow.Reset();
78
79 AddedWidgets.Empty();
80}
81
82void FUnrealWindow::SetupComponent(UTextureRenderTarget2D* TextureRenderTarget)
83{
84 if (ViewportClient.IsValid() && TextureRenderTarget)
85 {
86 ViewportClient->TextRenderTarget2D = TextureRenderTarget;
87 ViewportClient->texture = TextureRenderTarget->GetResource();
90 }
91}
92
93void FUnrealWindow::UpdateTexture(FTextureResource* Texture)
94{
95 if (ViewportClient.IsValid() && Texture)
96 {
97 ViewportClient->texture = Texture;
100 }
101}
102
104{
105 if (DrawToScreen)
106 {
107#if WITH_EDITOR
108 UE_LOG(LogTemp, Warning, TEXT("UnrealWindow.cpp: We are already drawing automatically, we should not draw manually!"));
109#endif
110 return;
111 }
112
113 if (SceneViewport.IsValid())
114 {
115 SceneViewport->Draw();
116 }
117}
118
119void FUnrealWindow::OnWindowClosed(const TSharedRef<SWindow>& SWindow)
120{
122}
123
125{
126 if (sWindow.IsValid())
127 {
128 sWindow->RequestDestroyWindow();
129 }
130}
131
132void FUnrealWindow::ResizeWindow(int32 width, int32 height)
133{
134 if (ViewportClient.IsValid() && SceneViewport.IsValid() && sWindow.IsValid())
135 {
136 WindowWidth = width;
137 WindowHeight = height;
138
141
142 SceneViewport->SetViewportSize(WindowWidth, WindowHeight);
143 sWindow->Resize(FVector2D(WindowWidth, WindowHeight));
144 }
145}
146
147void FUnrealWindow::AddUWidgetToWindow(UWidget* WidgetToAdd)
148{
149 if (!WidgetToAdd || !sWindow.IsValid())
150 {
151 return;
152 }
153
154 if (!FullScreenOverlay.IsValid())
155 {
156 // Create a full-screen SOverlay to contain the camera image and custom widget
157 FullScreenOverlay = SNew(SOverlay);
158
159 // Create a slot for current viewport widget
160 FullScreenOverlay->AddSlot(0)
161 .HAlign(HAlign_Fill)
162 .VAlign(VAlign_Fill)
163 [
164 Viewport.ToSharedRef()
165 ];
166 }
167
169
170 // Create a slot for the new widget
172 .HAlign(HAlign_Fill)
173 .VAlign(VAlign_Fill)
174 [
175 WidgetToAdd->TakeWidget()
176 ];
177
178 // Store information about the added widget
179 FAddedWidgetInfo WidgetInfo;
180 WidgetInfo.Widget = WidgetToAdd;
181 WidgetInfo.Index = AddedWidgetCount;
182 AddedWidgets.Add(WidgetInfo);
183
184 // Set the updated overlay as the window content
185 sWindow->SetContent(FullScreenOverlay.ToSharedRef());
186}
187
188void FUnrealWindow::RemoveUWidgetFromWindow(UWidget* WidgetToRemove)
189{
190 if (!WidgetToRemove || !sWindow.IsValid() || !FullScreenOverlay.IsValid())
191 {
192 return;
193 }
194
195 // Not the prettiest but works for this use case.
196 int32 WidgetIndexToRemove = -1;
197 for (int32 Index = 0; Index < AddedWidgets.Num(); ++Index)
198 {
199 if (AddedWidgets[Index].Widget == WidgetToRemove)
200 {
201 WidgetIndexToRemove = Index;
202 break;
203 }
204 }
205
206 if (WidgetIndexToRemove != -1)
207 {
208 // Remove Widget from slot (arrays start at 0 but slot 0 is the camera view)
209 FullScreenOverlay->RemoveSlot(WidgetIndexToRemove + 1);
210
211 // Set the updated overlay as the window content
212 sWindow->SetContent(FullScreenOverlay.ToSharedRef());
213
214 // Remove the widget info from the array
215 AddedWidgets.RemoveAt(WidgetIndexToRemove);
216 }
217}
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)
TArray< FAddedWidgetInfo > AddedWidgets
Definition: UnrealWindow.h:170
FUnrealWindow(int32 Width, int32 Height, FString WindowName="Camera")
void ResizeWindow(int32 Width, int32 Height)
TSharedPtr< SWindow > sWindow
Definition: UnrealWindow.h:165
void DestroyWindow()
TSharedPtr< FSceneViewport > SceneViewport
Definition: UnrealWindow.h:163
TSharedPtr< SViewport > sViewport
Definition: UnrealWindow.h:164
TSharedPtr< SOverlay > FullScreenOverlay
Definition: UnrealWindow.h:167
void RemoveUWidgetFromWindow(UWidget *WidgetToRemove)
static bool ShouldStartWindowMinimized()
UWidget * Widget
Definition: UnrealWindow.h:22