Arma Reforger Explorer 1.7.0.54
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
Loading...
Searching...
No Matches
SCR_PopupNotification.c
Go to the documentation of this file.
1//------------------------------------------------------------------------------------------------
3{
4 string m_sText;
5 string m_sSubtitle;
6 float m_fDuration;
7 int m_iPriority;
8 string m_sSound;
9 string m_aTextParams[4] = {"", "", "", ""};
10 string m_aSubtitleParams[4] = {"", "", "", ""};
11 SCR_EPopupMsgFilter m_eFilter;
12 WorldTimestamp m_fProgressStart;
13 WorldTimestamp m_fProgressEnd;
14 WorldTimestamp m_fHideTimestamp;
15};
16
17//------------------------------------------------------------------------------------------------
18class SCR_PopUpNotificationClass : GenericEntityClass
19{
20};
21
22//------------------------------------------------------------------------------------------------
25{
26 protected static const int INVALID_ID = -1;
27 protected static const float FADE_DURATION = 1;
28 protected static const ResourceName LAYOUT_NAME = "{8EF935F196AADE33}UI/layouts/Common/PopupUI.layout";
29 protected static const int POPUP_OFFSET = 35;
30
31 protected static SCR_PopUpNotification s_Instance = null;
33
34 static const float DEFAULT_DURATION = 4;
35 static const string TASKS_KEY_IMAGE_FORMAT = "<color rgba='226, 168, 79, 200'><shadow mode='image' color='0, 0, 0' size='1' offset='1, 1' opacity = '0.5'><action name='TasksOpen'/></shadow></color>";
36
37 protected ref array<ref SCR_PopupMessage> m_aQueue = {};
38
39 protected Widget m_wRoot;
43
44 protected float m_fDefaultAlpha;
45 protected float m_fDefaultHorizontalOffset = -1;
46
47 protected bool m_bInventoryOpen;
48 protected bool m_bOffset;
49 protected bool m_bIsEnabledInSettings = true;
50
51 protected IEntity m_Player;
52
54 protected string m_sCachedLanguage;
55
56 protected static const string INTERFACE_SETTINGS_NAME = "m_bShowNotifications";
57
58 //------------------------------------------------------------------------------------------------
60 {
61 if (!s_Instance)
62 {
63 BaseWorld world = GetGame().GetWorld();
64
65 if (world)
67 }
68
69 return s_Instance;
70 }
71
72 //------------------------------------------------------------------------------------------------
73 static void SetFilter(SCR_EPopupMsgFilter filter)
74 {
75 s_eFilter = filter;
76 }
77
78 //------------------------------------------------------------------------------------------------
79 void Offset(bool down)
80 {
82 return;
83
84 if (down == m_bOffset)
85 return;
86
87 m_bOffset = down;
88
89 int offset = POPUP_OFFSET;
90
91 if (!down)
92 offset = offset * -1;
93
94 FrameSlot.SetPosY(m_wPopupMsg, FrameSlot.GetPosY(m_wPopupMsg) + offset);
95 FrameSlot.SetPosY(m_wPopupMsgSmall, FrameSlot.GetPosY(m_wPopupMsgSmall) + offset);
96 FrameSlot.SetPosY(m_wStatusProgress, FrameSlot.GetPosY(m_wStatusProgress) + offset);
97 }
98
99 //------------------------------------------------------------------------------------------------
100 protected void ProcessInit()
101 {
102 if (!GetGame().GetHUDManager())
103 return;
104
105 PlayerController pc = GetGame().GetPlayerController();
106
107 if (!pc || !pc.GetControlledEntity())
108 return;
109
110 Widget root = GetGame().GetHUDManager().FindLayoutByResourceName(LAYOUT_NAME);
111 if (!root)
112 root = GetGame().GetHUDManager().CreateLayout(LAYOUT_NAME, EHudLayers.ALWAYS_TOP, 0);
113
114 if (!root)
115 return;
116
117 // Init can be safely processed
118 GetGame().GetCallqueue().Remove(ProcessInit);
119
120 SCR_EditorManagerEntity.GetInstance().GetOnModeChange().Insert(OnEditorModeChanged);
121 SCR_EditorManagerEntity.GetInstance().GetOnOpened().Insert(OnEditorOpened);
122 SCR_EditorManagerEntity.GetInstance().GetOnClosed().Insert(OnEditorClosed);
123 m_wRoot = root;
124
125 // Initialize popups UI
126 m_wPopupMsg = RichTextWidget.Cast(root.FindAnyWidget("Popup"));
127 m_wPopupMsgSmall = RichTextWidget.Cast(root.FindAnyWidget("PopupSmall"));
128 m_wStatusProgress = ProgressBarWidget.Cast(root.FindAnyWidget("Progress"));
129 m_fDefaultAlpha = m_wPopupMsg.GetColor().A();
130 m_wPopupMsg.SetVisible(false);
131 m_wPopupMsgSmall.SetVisible(false);
132 m_wStatusProgress.SetVisible(false);
133
134 GetGame().GetCallqueue().CallLater(SetDefaultHorizontalPosition, 500);
135
137
138 if (playerController)
140
141 RefreshQueue();
142
143 // Popups should not be visible in map
145 if (mapEntity)
146 {
147 MapConfiguration config = mapEntity.GetMapConfig();
148 if (config)
149 {
150 Widget mapWidget = config.RootWidgetRef;
151 if (mapWidget)
152 root.SetZOrder(mapWidget.GetZOrder() - 1);
153 }
154 }
155 }
156
157 //------------------------------------------------------------------------------------------------
158 protected void OnSettingsChanged()
159 {
161 if (!hudManager)
162 return;
163
164 BaseContainer interfaceSettings = GetGame().GetGameUserSettings().GetModule(hudManager.GetInterfaceSettingsClass());
165 if (!interfaceSettings)
166 return;
167
168 bool state;
169 if (!interfaceSettings.Get(INTERFACE_SETTINGS_NAME, state))
170 return;
171
173
176
177 string newLanguage;
178 WidgetManager.GetLanguage(newLanguage);
179 if (newLanguage.IsEmpty() || newLanguage == m_sCachedLanguage) // check if language is really changed
180 return;
181
182 m_sCachedLanguage = newLanguage;
183
184 ClearMsg();
185 }
186
187 //------------------------------------------------------------------------------------------------
188 protected void RefreshInventoryInvoker(IEntity previousPlayer, IEntity currentPlayer)
189 {
190 SCR_InventoryStorageManagerComponent inventory;
191
192 if (previousPlayer)
193 {
194 inventory = SCR_InventoryStorageManagerComponent.Cast(previousPlayer.FindComponent(SCR_InventoryStorageManagerComponent));
195
196 if (inventory)
197 inventory.m_OnInventoryOpenInvoker.Remove(OnInventoryToggle);
198 }
199
200 if (!currentPlayer)
201 return;
202
203 inventory = SCR_InventoryStorageManagerComponent.Cast(currentPlayer.FindComponent(SCR_InventoryStorageManagerComponent));
204
205 if (!inventory)
206 return;
207
208 // Make absolutely sure invoker is not used multiple times in the same inventory
209 inventory.m_OnInventoryOpenInvoker.Remove(OnInventoryToggle);
210 inventory.m_OnInventoryOpenInvoker.Insert(OnInventoryToggle);
211 }
212
213 //------------------------------------------------------------------------------------------------
214 void OnInventoryToggle(bool open)
215 {
216 m_bInventoryOpen = open;
217 }
218
219 //------------------------------------------------------------------------------------------------
220 protected void OnEditorOpened()
221 {
222 if (!m_wRoot)
223 return;
224
225 if (SCR_Enum.HasFlag(SCR_EditorManagerEntity.GetInstance().GetCurrentMode(), EEditorMode.BUILDING))
226 m_wRoot.SetVisible(true);
227 else
228 m_wRoot.SetVisible(false);
229 }
230
231 //------------------------------------------------------------------------------------------------
232 protected void OnEditorClosed()
233 {
234 if (!m_wRoot)
235 return;
236
237 m_wRoot.SetVisible(true);
238 }
239
240 //------------------------------------------------------------------------------------------------
242 {
243 if (!m_wRoot || !SCR_EditorManagerEntity.GetInstance().IsOpened())
244 return;
245
246 if (SCR_Enum.HasFlag(currentMode.GetModeType(), EEditorMode.BUILDING))
247 m_wRoot.SetVisible(true);
248 else
249 m_wRoot.SetVisible(false);
250 }
251
252 //------------------------------------------------------------------------------------------------
254 {
255 for (int i = 0, cnt = m_aQueue.Count(); i < cnt; i++)
256 {
257 if (m_aQueue[i].m_iPriority > priority)
258 return true;
259 }
260
261 return false;
262 }
263
264 //------------------------------------------------------------------------------------------------
265 void SetTitleText(string text)
266 {
267 if (m_wPopupMsg)
268 m_wPopupMsg.SetTextFormat(text);
269 }
270
271 //------------------------------------------------------------------------------------------------
282 void PopupMsg(string text, float duration = DEFAULT_DURATION, string text2 = "", int prio = -1, string param1 = "", string param2 = "", string param3 = "", string param4 = "", string text2param1 = "", string text2param2 = "", string text2param3 = "", string text2param4 = "", string sound = "", SCR_EPopupMsgFilter category = SCR_EPopupMsgFilter.ALL,
283 WorldTimestamp progressStart = null,
284 WorldTimestamp progressEnd = null
285 )
286 {
287 // Don't show UI on headless
288 if (System.IsConsoleApp())
289 return;
290
292 return;
293
294 // Check filter settings, stop if the message is filtered out
296 return;
297
298 // Invalid params
299 if ((text.IsEmpty() && text2.IsEmpty()) || duration == 0)
300 return;
301
303
304 if (!msg)
305 return;
306
307 msg.m_sText = text;
308 msg.m_sSubtitle = text2;
309 msg.m_fDuration = duration;
310 msg.m_iPriority = prio;
311 msg.m_sSound = sound;
312 msg.m_aTextParams = {param1, param2, param3, param4};
313 msg.m_aSubtitleParams = {text2param1, text2param2, text2param3, text2param4};
314 msg.m_eFilter = category;
315 msg.m_fProgressStart = progressStart;
316 msg.m_fProgressEnd = progressEnd;
317
318 RefreshQueue(msg);
319 }
320
321 //------------------------------------------------------------------------------------------------
323 {
324 return m_ShownMsg;
325 }
326
327 //------------------------------------------------------------------------------------------------
329 {
330 if (!m_ShownMsg)
331 return;
332
333 ChimeraWorld world = GetWorld();
334 m_ShownMsg.m_fHideTimestamp = world.GetServerTimestamp();
335 }
336
337 //------------------------------------------------------------------------------------------------
339 {
340 if (!m_ShownMsg || m_ShownMsg.m_fProgressEnd == 0)
341 return;
342
343 ChimeraWorld world = GetWorld();
344 WorldTimestamp curTime = world.GetServerTimestamp();
345
346 // Save progress bar status so only its filling speed is changed
347 float totalTime = m_ShownMsg.m_fProgressEnd.DiffMilliseconds(m_ShownMsg.m_fProgressStart);
348 float elapsedTime = curTime.DiffMilliseconds(m_ShownMsg.m_fProgressStart);
349 float curProgress = elapsedTime / totalTime;
350
351 // Avoid possible division by 0 later
352 if (curProgress == 1)
353 return;
354
355 m_ShownMsg.m_fProgressEnd = progressEnd;
356
357 // Recalculate start value so the bar keeps its original progress
358 float newRemainingTime = progressEnd.DiffMilliseconds(curTime);
359 float newTotalTime = newRemainingTime / (1 - curProgress);
360 float newElapsedTime = newTotalTime * curProgress;
361 m_ShownMsg.m_fProgressStart = curTime.PlusMilliseconds(-newElapsedTime);
362
363 // Needed to reset the progress bar limits
364 m_wStatusProgress.SetVisible(false);
365 }
366
367 //------------------------------------------------------------------------------------------------
368 protected void FadeWidget(notnull Widget widget, bool fadeOut = false, bool instant = false)
369 {
370 float alpha, targetAlpha;
371
372 if (fadeOut)
373 {
374 alpha = m_fDefaultAlpha;
375 targetAlpha = 0;
376 }
377 else
378 {
379 alpha = 0;
380 targetAlpha = m_fDefaultAlpha;
381 }
382
383 if (instant)
384 {
385 widget.SetOpacity(targetAlpha);
386 }
387 else
388 {
389 widget.SetOpacity(alpha);
390 AnimateWidget.Opacity(widget, targetAlpha, FADE_DURATION, !fadeOut || widget.IsVisible());
391 }
392 }
393
394 //------------------------------------------------------------------------------------------------
395 protected void RefreshQueue(SCR_PopupMessage msg = null)
396 {
397 if (msg)
398 {
399 int index = m_aQueue.Find(msg);
400
401 if (index == -1)
402 {
403 // Find the correct array index for the new message (based on priority)
404 SCR_PopupMessage checkedMsg;
405
406 for (int i = 0, cnt = m_aQueue.Count(); i < cnt; i++)
407 {
408 checkedMsg = m_aQueue[i];
409
410 // Infinite duration is always considered higher prio
411 if (msg.m_fDuration == -1)
412 {
413 if (checkedMsg.m_fDuration != -1 || checkedMsg.m_iPriority <= msg.m_iPriority)
414 index = i;
415 }
416 else if (checkedMsg.m_fDuration != -1 && checkedMsg.m_iPriority < msg.m_iPriority)
417 {
418 index = i;
419 }
420
421 if (index != -1)
422 break;
423 }
424
425 if (index == -1)
426 m_aQueue.Insert(msg);
427 else
428 m_aQueue.InsertAt(msg, index);
429 }
430 else
431 {
432 m_aQueue.RemoveOrdered(index);
433 }
434 }
435
436 if (m_aQueue.IsEmpty())
437 {
439 }
440 else if (m_wPopupMsg)
441 {
442 if (m_aQueue[0] != m_ShownMsg)
443 ShowMsg(m_aQueue[0]);
444
446 }
447 }
448
449 //------------------------------------------------------------------------------------------------
450 protected void ShowMsg(notnull SCR_PopupMessage msg)
451 {
453 return;
454
455 if (msg == m_ShownMsg)
456 return;
457
458 if (m_ShownMsg)
460
461 if (msg.m_fDuration != -1)
462 {
463 ChimeraWorld world = GetWorld();
464 msg.m_fHideTimestamp = world.GetServerTimestamp().PlusSeconds(msg.m_fDuration);
465 }
466
467 m_wPopupMsg.SetTextFormat(msg.m_sText, msg.m_aTextParams[0], msg.m_aTextParams[1], msg.m_aTextParams[2], msg.m_aTextParams[3]);
469
470 if (!msg.m_sSubtitle.IsEmpty())
471 {
472 m_wPopupMsgSmall.SetTextFormat(msg.m_sSubtitle, msg.m_aSubtitleParams[0], msg.m_aSubtitleParams[1], msg.m_aSubtitleParams[2], msg.m_aSubtitleParams[3]);
474 }
475
476 if (msg.m_fProgressStart != 0 && msg.m_fProgressEnd != 0)
477 {
478 m_wStatusProgress.SetMin(0);
479 m_wStatusProgress.SetMax(msg.m_fProgressEnd.DiffMilliseconds(msg.m_fProgressStart));
480 m_wStatusProgress.SetVisible(false);
482 }
483
484 if (!msg.m_sSound.IsEmpty())
485 SCR_UISoundEntity.SoundEvent(msg.m_sSound);
486
487 m_ShownMsg = msg;
488 }
489
490 //------------------------------------------------------------------------------------------------
491 protected void HideMsg(notnull SCR_PopupMessage msg)
492 {
493 if (msg == m_ShownMsg)
494 {
495 m_ShownMsg = null;
496
497 FadeWidget(m_wPopupMsg, true);
500 }
501
502 RefreshQueue(msg);
503 }
504
505 //------------------------------------------------------------------------------------------------
507 void ClearMsg()
508 {
509 if (m_wPopupMsg)
510 FadeWidget(m_wPopupMsg, true, true);
511
513 FadeWidget(m_wPopupMsgSmall, true, true);
514
516 FadeWidget(m_wStatusProgress, true, true);
517
518 m_aQueue.Clear();
519 m_ShownMsg = null;
520 }
521
522 //------------------------------------------------------------------------------------------------
524 {
525 float x, y;
526 m_wPopupMsg.GetScreenPos(x, y);
528 }
529
530 //------------------------------------------------------------------------------------------------
531 override void EOnFrame(IEntity owner, float timeSlice)
532 {
533 if (!m_ShownMsg)
534 return;
535
537 {
538 m_wPopupMsg.SetVisible(false);
539 m_wPopupMsgSmall.SetVisible(false);
540 m_wStatusProgress.SetVisible(false);
541 return;
542 }
543
544 BaseWorld world = GetGame().GetWorld();
545
546 if (!world)
547 return;
548
549 ChimeraWorld chimWorld = world;
550 WorldTimestamp curTime = chimWorld.GetServerTimestamp();
551 if (m_ShownMsg.m_fHideTimestamp != 0 && curTime.GreaterEqual(m_ShownMsg.m_fHideTimestamp))
552 {
554 return;
555 }
556
557 if (m_ShownMsg.m_sText && !m_wPopupMsg.IsVisible())
558 m_wPopupMsg.SetVisible(true);
559
560 if (m_ShownMsg.m_sSubtitle && !m_wPopupMsgSmall.IsVisible())
561 m_wPopupMsgSmall.SetVisible(true);
562
563 if (m_ShownMsg.m_fProgressEnd.Greater(curTime))
564 {
565 if (!m_wStatusProgress.IsVisible())
566 {
567 m_wStatusProgress.SetVisible(true);
568 m_wStatusProgress.SetMin(0);
569 m_wStatusProgress.SetMax(m_ShownMsg.m_fProgressEnd.DiffMilliseconds(m_ShownMsg.m_fProgressStart));
570 }
571
572 m_wStatusProgress.SetCurrent(curTime.DiffMilliseconds(m_ShownMsg.m_fProgressStart));
573 }
574 else if (m_wStatusProgress.IsVisible())
575 {
576 m_wStatusProgress.SetVisible(false);
577 }
578 }
579
580 //------------------------------------------------------------------------------------------------
582 {
583 SetFlags(EntityFlags.NO_TREE | EntityFlags.NO_LINK);
584
585 // Don't show UI on headless
586 if (System.IsConsoleApp())
587 return;
588
589 // Make sure init can be processed properly (when HUD Manager is ready, check in ProcessInit())
590 GetGame().GetCallqueue().Remove(ProcessInit);
591 GetGame().GetCallqueue().CallLater(ProcessInit, 1000, true);
592
593
594 // Initialize Interface settings
596 if (!hudManager)
597 return;
598
599 BaseContainer interfaceSettings = GetGame().GetGameUserSettings().GetModule(hudManager.GetInterfaceSettingsClass());
600 if (!interfaceSettings)
601 return;
602
603 if (interfaceSettings.Get(INTERFACE_SETTINGS_NAME, m_bIsEnabledInSettings))
604 {
605 GetGame().OnUserSettingsChangedInvoker().Insert(OnSettingsChanged);
606 WidgetManager.GetLanguage(m_sCachedLanguage);
607 }
608 }
609
610 //------------------------------------------------------------------------------------------------
612 {
613 GetGame().OnUserSettingsChangedInvoker().Remove(OnSettingsChanged);
614
615 if (m_wPopupMsg)
616 m_wPopupMsg.GetParent().RemoveFromHierarchy();
617
619
620 GetGame().GetCallqueue().Remove(ProcessInit);
621
622 if (!SCR_EditorManagerEntity.GetInstance())
623 return;
624
625 SCR_EditorManagerEntity.GetInstance().GetOnModeChange().Remove(OnEditorModeChanged);
626 SCR_EditorManagerEntity.GetInstance().GetOnOpened().Remove(OnEditorOpened);
627 SCR_EditorManagerEntity.GetInstance().GetOnClosed().Remove(OnEditorClosed);
628 }
629};
630
631//------------------------------------------------------------------------------------------------
ArmaReforgerScripted GetGame()
Definition game.c:1398
SCR_HUDManagerComponent GetHUDManager()
Definition game.c:1151
int m_iPriority
IEntity SpawnEntity(ResourceName entityResourceName, notnull IEntity slotOwner)
SCR_DestructionSynchronizationComponentClass ScriptComponentClass int index
void SCR_EditorManagerEntity(IEntitySource src, IEntity parent)
static WidgetAnimationOpacity Opacity(Widget widget, float targetValue, float speed, bool toggleVisibility=false)
void IEntity(IEntitySource src, IEntity parent)
protected script Constructor
proto external EntityEvent SetEventMask(EntityEvent e)
proto external Managed FindComponent(typename typeName)
proto external EntityEvent ClearEventMask(EntityEvent e)
proto external BaseWorld GetWorld()
proto external EntityFlags SetFlags(EntityFlags flags, bool recursively=false)
static SCR_HUDManagerComponent GetHUDManager()
MapConfiguration GetMapConfig()
Get map config.
static SCR_MapEntity GetMapInstance()
Get map entity instance.
ref OnControlledEntityChangedPlayerControllerInvoker m_OnControlledEntityChanged
bool IsPresentPopupWithHigherPriority(int priority)
ref array< ref SCR_PopupMessage > m_aQueue
void ClearMsg()
Clear and instant fade all popup messages.
void RefreshInventoryInvoker(IEntity previousPlayer, IEntity currentPlayer)
static const float FADE_DURATION
void ChangeProgressBarFinish(WorldTimestamp progressEnd)
static const ResourceName LAYOUT_NAME
void RefreshQueue(SCR_PopupMessage msg=null)
override void EOnFrame(IEntity owner, float timeSlice)
static SCR_EPopupMsgFilter s_eFilter
void FadeWidget(notnull Widget widget, bool fadeOut=false, bool instant=false)
void HideMsg(notnull SCR_PopupMessage msg)
void SCR_PopUpNotification(IEntitySource src, IEntity parent)
static void SetFilter(SCR_EPopupMsgFilter filter)
void PopupMsg(string text, float duration=DEFAULT_DURATION, string text2="", int prio=-1, string param1="", string param2="", string param3="", string param4="", string text2param1="", string text2param2="", string text2param3="", string text2param4="", string sound="", SCR_EPopupMsgFilter category=SCR_EPopupMsgFilter.ALL, WorldTimestamp progressStart=null, WorldTimestamp progressEnd=null)
static const float DEFAULT_DURATION
static const string INTERFACE_SETTINGS_NAME
ProgressBarWidget m_wStatusProgress
void OnEditorModeChanged(SCR_EditorModeEntity currentMode, SCR_EditorModeEntity prevMode)
void ShowMsg(notnull SCR_PopupMessage msg)
static SCR_PopUpNotification GetInstance()
SCR_PopupMessage GetCurrentMsg()
static const string TASKS_KEY_IMAGE_FORMAT
static SCR_PopUpNotification s_Instance
@ NONE
When Shape is created and not initialized yet.
Definition ShapeType.c:15
EEditorMode
Editor mode that defines overall functionality.
Definition EEditorMode.c:6
EntityEvent
Various entity events.
Definition EntityEvent.c:14
EntityFlags
Various entity flags.
Definition EntityFlags.c:14
@ ALL
Everything except general switch.
Definition EntityEvent.c:37
proto external PlayerController GetPlayerController()
T4 param4
Definition tuple.c:152
T3 param3
Definition tuple.c:93
T2 param2
Definition tuple.c:92
Tuple param1