Arma Reforger Explorer 1.7.0.54
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
Loading...
Searching...
No Matches
SCR_HUDManagerComponent.c
Go to the documentation of this file.
1//#define DISABLE_HUD_MANAGER
2
3//------------------------------------------------------------------------------------------------
4// (i): The enum values needs to be power of 2
6{
7 BACKGROUND = 1, // Only background textures like Screen effects
8 LOW = 2, // Read-only information, like weapon info
9 MEDIUM = 4, //
10 HIGH = 8, // Dialogue-like elements like weapon switching
11 OVERLAY = 16, // Interactive elements that should always be on top
12 ALWAYS_TOP = 32
13}
14
16class SCR_HUDManagerComponentClass : HUDManagerComponentClass
20void OnScreenBrightnessChanged(float opacity, float sceneBrightness);
22
23class SCR_HUDManagerComponent : HUDManagerComponent
24{
25 [Attribute()]
26 protected ref array<ref SCR_HUDManagerHandler> m_aHandlers;
27 protected ref array<SCR_HUDManagerHandler> m_aUpdatableHandlers = {};
28
29 [Attribute()]
31 [Attribute()]
33
34 [Attribute("0 0 1 1", UIWidgets.CurveDialog, params: "0.1 0.6 0 0.4", desc: "Adaptive opacity (y) based on screen brightness (x).", category: "AdaptiveOpacity")]
35 private ref Curve m_AdaptiveOpacityCurve;
36
37 [Attribute("SCR_InterfaceSettings", desc: "Classname of the InterfaceSettings menu")]
39
40 private ref map<EHudLayers, Widget> m_aLayerWidgets = new map<EHudLayers, Widget>;
41 private Widget m_wRoot;
42 private Widget m_wRootTop;
43
44 protected BaseWorld m_World;
45
46 private bool m_MenuOpen;
47
48 protected ref ScriptInvokerBase<OnScreenBrightnessChanged> m_OnSceneBrightnessChanged = new ScriptInvokerBase<OnScreenBrightnessChanged>();
49
50 protected float m_fUpdateTime = -1;
51 const float UPDATE_DELAY = 500;
52
54 const float ADAPTIVE_OPACITY_THROTTLE = 0.01; // threshold opacity change to fire the AdaptiveOpacity invoker
55
56 protected float m_fSceneBrightness = -1;
57 protected float m_fOpacity = -1;
58
59 protected IEntity m_Owner;
60
61 protected ref array<SCR_HUDManagerHandler> m_aHandlersToRemoveFromUpdate = {};
62
63 #ifndef DISABLE_HUD_MANAGER
64
65 //------------------------------------------------------------------------------------------------
67 {
68 return m_aHUDElements.Count();
69 }
70
71 //------------------------------------------------------------------------------------------------
73 {
74 return m_Owner;
75 }
76
77 //------------------------------------------------------------------------------------------------
78 SCR_HUDManagerHandler FindHandler(typename handlerType)
79 {
80 foreach (SCR_HUDManagerHandler handler : m_aHandlers)
81 {
82 if (handler.Type() == handlerType)
83 return handler;
84 }
85
86 return null;
87 }
88
89 //------------------------------------------------------------------------------------------------
94
95 //------------------------------------------------------------------------------------------------
97 {
98 return m_wRoot;
99 }
100
101 //------------------------------------------------------------------------------------------------
102 protected override void OnInit(IEntity owner)
103 {
104 if (!GetGame().GetWorldEntity())
105 return;
106 m_Owner = owner;
107
108 foreach (SCR_HUDManagerHandler handler : m_aHandlers)
109 {
110 handler.OnInit(this);
111
112 if (handler.CanUpdate())
113 m_aUpdatableHandlers.Insert(handler);
114 }
115
116 foreach (SCR_HUDManagerHandler handler : m_aHandlers)
117 {
118 handler.OnStart(this);
119 }
120
121 ArmaReforgerScripted game = GetGame();
122 if (game && !game.GetHUDManager())
123 {
124 game.SetHUDManager(this);
126 }
127
128 m_World = GetGame().GetWorld();
129 }
130
131 //------------------------------------------------------------------------------------------------
132 protected override void OnUpdate(IEntity owner)
133 {
134 if (!m_World)
135 return;
136
137 if (!m_aHandlersToRemoveFromUpdate.IsEmpty())
138 {
140 {
141 m_aUpdatableHandlers.RemoveItem(handler);
142 handler.SetCanUpdate(false);
143 }
144
146 }
147
149 {
150 handler.OnUpdate(this);
151 }
152
153 float time = m_World.GetWorldTime();
154
155 if (time < m_fUpdateTime)
156 return;
157
159
160 //------------------------------------------------------------------------------------------------
161 // Adaptive opacity
162 //------------------------------------------------------------------------------------------------
163
164 // We want to enforce full opacity for brightness > 0.1 (midday, good weather)
165 float sceneBrightness = Math.Clamp(m_World.GetCameraSceneMiddleBrightness(0), 0, 0.1);
166
167 // Throttle the opacity update if brightness change is not bigger than n%
168 if (Math.AbsFloat(m_fSceneBrightness - sceneBrightness) < ADAPTIVE_OPACITY_BRIGHTNESS_THROTTLE)
169 return;
170
171 // Curve based opacity interpolation
172 float opacity = LegacyCurve.Curve(ECurveType.CurveProperty2D, sceneBrightness, m_AdaptiveOpacityCurve)[1];
173 opacity = Math.Clamp(Math.Round(opacity * 100) / 100, 0, 1);
174
175 // Invoke the opacity update only if change is greater than n%
176 if (Math.AbsFloat(m_fOpacity - opacity) >= ADAPTIVE_OPACITY_THROTTLE)
177 {
178 //PrintFormat("sceneBrightness: %1 -> opacity %2", sceneBrightness, opacity);
179
180 m_fSceneBrightness = sceneBrightness;
181 m_fOpacity = opacity;
182
184 m_OnSceneBrightnessChanged.Invoke(opacity, sceneBrightness);
185 }
186 }
187
188 //------------------------------------------------------------------------------------------------
190 {
191 return m_fOpacity;
192 }
193
194 //------------------------------------------------------------------------------------------------
196 {
197 return m_fSceneBrightness;
198 }
199
200 //------------------------------------------------------------------------------------------------
205
206 //------------------------------------------------------------------------------------------------
207 ScriptInvokerBase<OnScreenBrightnessChanged> GetSceneBrightnessChangedInvoker()
208 {
210 }
211
212 //------------------------------------------------------------------------------------------------
214 {
215 if (m_wRoot)
216 m_wRoot.RemoveFromHierarchy();
217 }
218
219 #endif
220
221 //------------------------------------------------------------------------------------------------
222 protected void CreateHUDLayers()
223 {
224 m_wRoot = GetGame().GetWorkspace().CreateWidget(WidgetType.FrameWidgetTypeID, WidgetFlags.VISIBLE, Color.FromInt(Color.WHITE), 0);
225 m_wRootTop = GetGame().GetWorkspace().CreateWidget(WidgetType.FrameWidgetTypeID, WidgetFlags.VISIBLE, Color.FromInt(Color.WHITE), 0);
226 m_wRootTop.SetZOrder(100); //set high to be always on top, even above MenuManager layouts
227
228 if (m_wRoot && m_wRootTop)
229 {
230 InitRootWidget(m_wRoot, "SCR_HUDManagerComponent.m_wRoot");
231 InitRootWidget(m_wRootTop, "SCR_HUDManagerComponent.m_wRootTop");
232
233 array<int> bitValues = new array<int>;
234 int bitCount = SCR_Enum.GetEnumValues(EHudLayers, bitValues);
235
236 for (int i = 0; i < bitCount; i++)
237 {
238 Widget frame;
239 Widget parent = m_wRoot;
240 if (bitValues[i] == EHudLayers.ALWAYS_TOP)
241 parent = m_wRootTop;
242
243 frame = GetGame().GetWorkspace().CreateWidget(WidgetType.FrameWidgetTypeID, WidgetFlags.VISIBLE, Color.FromInt(Color.WHITE), 0, parent);
244 FrameSlot.SetAnchorMin(frame, 0, 0);
245 FrameSlot.SetAnchorMax(frame, 1, 1);
246 FrameSlot.SetOffsets(frame, 0, 0, 0, 0);
247 frame.SetFlags(WidgetFlags.IGNORE_CURSOR);
248 frame.SetName(string.Format("SCR_HudManagerComponent: %1", typename.EnumToString(EHudLayers, bitValues[i])));
249
250 m_aLayerWidgets.Insert(bitValues[i], frame);
251 }
252 }
253 }
254
255 //------------------------------------------------------------------------------------------------
257 SCR_InfoDisplay FindInfoDisplay(typename type)
258 {
259 foreach (SCR_InfoDisplay display : m_aHUDElements)
260 {
261 if (display.Type() == type)
262 return display;
263 }
264
265 return null;
266 }
267
268 //------------------------------------------------------------------------------------------------
271 {
272 foreach (SCR_InfoDisplay display : m_aHUDElements)
273 {
274 if (display.m_LayoutPath == path)
275 return display;
276 }
277
278 return null;
279 }
280
281 //------------------------------------------------------------------------------------------------
284 {
285 foreach (SCR_InfoDisplay display : m_aHUDElements)
286 {
287 if (display.m_LayoutPath == path)
288 return display.GetRootWidget();
289 }
290
291 return null;
292 }
293
294 //------------------------------------------------------------------------------------------------
295 protected void InitRootWidget(Widget root, string name)
296 {
297 FrameSlot.SetAnchorMin(root, 0, 0);
298 FrameSlot.SetAnchorMax(root, 1, 1);
299 FrameSlot.SetOffsets(root, 0, 0, 0, 0);
300 root.SetFlags(WidgetFlags.IGNORE_CURSOR);
301 root.SetName(name);
302 }
303
304 //------------------------------------------------------------------------------------------------
306 {
307 #ifndef DISABLE_HUD_MANAGER
308
309 if (path == string.Empty)
310 return null;
311
312 Widget parent;
313 if (m_aLayerWidgets.Find(layer, parent) && parent)
314 {
315 Widget w = GetGame().GetWorkspace().CreateWidgets(path, parent);
316 if (w)
317 {
318 FrameSlot.SetAnchorMin(w, 0, 0);
319 FrameSlot.SetAnchorMax(w, 1, 1);
320 FrameSlot.SetOffsets(w, 0, 0, 0, 0);
321 w.SetFlags(WidgetFlags.IGNORE_CURSOR);
322 if (zOrder != 0)
323 w.SetZOrder(zOrder);
324
325 return w;
326 }
327 }
328
329 #endif
330
331 return null;
332 }
333
335 {
337 if (!layoutHandler)
338 return null;
339
340 SCR_HUDLayout owningLayout;
341 Widget parentWidget = layoutHandler.FindWidgetByNameFromAnyLayout(parentName, owningLayout);
342 if (!parentWidget)
343 return null;
344
345 if (parentWidget.FindHandler(SCR_HUDSlotUIComponent))
346 {
347 Print(parentName + " is a HUD Slot! Use InfoDisplay instead!", LogLevel.ERROR);
348 return null;
349 }
350
351 Widget elementWidget = GetGame().GetWorkspace().CreateWidgets(path, parentWidget);
352
353 SCR_HUDElement hudElement = new SCR_HUDElement();
354 hudElement.SetWidget(elementWidget);
355 hudElement.SetParentWidgetName(parentName);
356 hudElement.SetParentLayout(owningLayout);
357 owningLayout.AddHudElement(hudElement);
358
359 return hudElement;
360 }
361
366 void SetVisible(bool isVisible)
367 {
368 m_wRoot.SetVisible(isVisible);
369 m_wRootTop.SetVisible(isVisible);
370 }
371
376 {
377 return m_wRoot.IsVisible();
378 }
379
384 void SetVisibleLayers(EHudLayers layers = -1)
385 {
386 if (layers == -1)
387 {
388 //--- Show all
389 foreach (EHudLayers layer, Widget w : m_aLayerWidgets)
390 {
391 w.SetVisible(true);
392 }
393 }
394 else
395 {
396 //--- Show custom
397 foreach (EHudLayers layer, Widget w : m_aLayerWidgets)
398 {
399 w.SetVisible(layers & layer);
400 }
401 }
402 }
403
409 {
410 EHudLayers layers;
411 foreach (EHudLayers layer, Widget w : m_aLayerWidgets)
412 {
413 if (w.IsVisible()) layers = layers | layer;
414 }
415 return layers;
416 }
417
418 //------------------------------------------------------------------------------------------------
420 {
421 #ifndef DISABLE_HUD_MANAGER
422
423 ArmaReforgerScripted game = GetGame();
424
425 if (game)
426 return game.GetHUDManager();
427
428 #endif
429
430 return null;
431 }
432
433 #ifdef WORKBENCH
434 // The two methods below allow us to open a context menu over the SCR_HUDManagerComponent
435 // It adds a 'Add actions to AvailableActionsDisplay info' entry
436 // After selection a dialog with all actions is shown from which the user can select some
437 // AvailableActionsDisplay is then filled with entries of selected actions
438 // Entry is only added if we have a SCR_AvailableActionsDisplay object in the hud manager
439 // Multiple SCR_AvailableActionsDisplay are not supported
440
441 //------------------------------------------------------------------------------------------------
442 const int CONTEXT_GENERATE_AVAILABLE_INPUT_ACTION = 0;
443 //------------------------------------------------------------------------------------------------
444 override array<ref WB_UIMenuItem> _WB_GetContextMenuItems(IEntity owner)
445 {
446 // Prep array
447 array<ref WB_UIMenuItem> items = new array<ref WB_UIMenuItem>();
448
449 // Find available actions display
450 array<BaseInfoDisplay> elements = new array<BaseInfoDisplay>();
451 GetInfoDisplays(elements);
452 foreach (auto element : elements)
453 {
454 // Create item option
455 if (SCR_AvailableActionsDisplay.Cast(element))
456 {
457 ref WB_UIMenuItem actionsContextItem = new WB_UIMenuItem("Add actions to AvailableActionsDisplay info", CONTEXT_GENERATE_AVAILABLE_INPUT_ACTION);
458 items.Insert(actionsContextItem);
459 break;
460 }
461 }
462 // Return arr
463 return items;
464 }
465
466 //------------------------------------------------------------------------------------------------
467 override void _WB_OnContextMenu(IEntity owner, int id)
468 {
469 if (id == CONTEXT_GENERATE_AVAILABLE_INPUT_ACTION)
470 {
471 SCR_AvailableActionsDisplay target;
472
473 // Find available actions display
474 array<BaseInfoDisplay> elements = new array<BaseInfoDisplay>();
475 GetInfoDisplays(elements);
476 foreach (auto element : elements)
477 {
478 if (SCR_AvailableActionsDisplay.Cast(element))
479 {
480 target = SCR_AvailableActionsDisplay.Cast(element);
481 break;
482 }
483 }
484
485 if (!target)
486 return;
487
488 GenericEntity genericOwner = GenericEntity.Cast(owner);
489 if (!genericOwner)
490 return;
491
492 // Get all actions
493 InputManager mgr = GetGame().GetInputManager();
494 array<string> actions = {};
495 if (mgr)
496 {
497 int cnt = mgr.GetActionCount();
498 for (int i = 0; i < cnt; i++)
499 {
500 string act = mgr.GetActionName(i);
501 actions.Insert(act);
502 }
503 }
504
505 // Get wb we api
506 WorldEditorAPI api = genericOwner._WB_GetEditorAPI();
507 if (!api)
508 return;
509
510 // Pass them into a dialog
511 // TODO: Make this not use cpp and make it more reasonable in general
512 array<int> selection = new array<int>();
513 api.ShowItemListDialog("Actions Selection", "Select actions from the actions manager to create entry for.", 340, 480, actions, selection, 0);
514
515 // Parent entity source
516 IEntitySource entitySource = api.EntityToSource(owner);
517 if (!entitySource)
518 return;
519
520 // Hud manager source
521 BaseContainer componentContainer;
522 int cmpCount = entitySource.GetComponentCount();
523 for (int i = 0; i < cmpCount; i++)
524 {
525 IEntityComponentSource componentSource = entitySource.GetComponent(i);
526 if (componentSource.GetClassName() == "SCR_HUDManagerComponent")
527 {
528 componentContainer = componentSource.ToBaseContainer();
529 break;
530 }
531 }
532
533 if (!componentContainer)
534 return;
535
536 // InfoDisplays array of hud manager
537 BaseContainerList infoDisplays = componentContainer.GetObjectArray("InfoDisplays");
538 if (!infoDisplays)
539 return;
540
541 // SCR_AvailableActionsDisplay object
542 BaseContainer displaySource;
543 for (int i = 0; i < infoDisplays.Count(); i++)
544 {
545 BaseContainer container = infoDisplays.Get(i);
546 if (container.GetClassName() == "SCR_AvailableActionsDisplay")
547 {
548 displaySource = container;
549 break;
550 }
551 }
552
553 if (!displaySource)
554 return;
555
556 api.BeginEntityAction("Create action container");
557
558 const string list = "m_aActions";
559 // Create object for each action
560 foreach (auto sel : selection)
561 {
562 string selectedActionName = actions[sel];
563 if (selectedActionName == string.Empty)
564 continue;
565
566 const int objIndex = 0;
567 // Create object, push it into array
568 api.CreateObjectArrayVariableMember(displaySource, null, list, "SCR_AvailableActionContext", objIndex);
569 // Retrieve the source
570 BaseContainerList itemsList = displaySource.GetObjectArray(list);
571 BaseContainer thisContainer = itemsList.Get(objIndex);
572 thisContainer.Set("m_sAction", selectedActionName);
573 thisContainer.Set("m_sName", selectedActionName);
574 }
575
576 api.EndEntityAction();
577 return;
578 }
579 }
580 #endif
581}
string path
ref DSGameConfig game
Definition DSConfig.c:81
ArmaReforgerScripted GetGame()
Definition game.c:1398
LayerPresets layer
enum SCR_EAITalkRequestState MEDIUM
EDamageType type
func OnScreenBrightnessChanged
enum EHudLayers ComponentEditorProps(icon:HYBRID_COMPONENT_ICON)
UI Textures DeployMenu Briefing conflict_HintBanner_1_UI desc
enum EVehicleType IEntity
Definition Color.c:13
Definition Math.c:22
proto external WorldEditorAPI _WB_GetEditorAPI()
This returns world editor API, which is safe to use from editor events bellow.
Definition Math.c:13
void SetParentLayout(notnull SCR_HUDLayout parentLayout)
void SetWidget(notnull Widget widget)
void SetParentWidgetName(string parentWidgetName)
void AddHudElement(notnull SCR_HUDElement element, bool replaceParent=false)
SCR_InfoDisplay FindInfoDisplay(typename type)
Return hud component of given type.
ref ScriptInvokerBase< OnScreenBrightnessChanged > m_OnSceneBrightnessChanged
void SetVisibleLayers(EHudLayers layers=-1)
ref array< SCR_HUDManagerHandler > m_aHandlersToRemoveFromUpdate
SCR_InfoDisplay FindInfoDisplayByResourceName(ResourceName path)
Find layout by resorce name.
ScriptInvokerBase< OnScreenBrightnessChanged > GetSceneBrightnessChangedInvoker()
SCR_HUDElement CreateFreeElement(ResourceName path, string parentName)
SCR_HUDManagerHandler FindHandler(typename handlerType)
ref array< ref SCR_HUDManagerHandler > m_aHandlers
static SCR_HUDManagerComponent GetHUDManager()
void RemoveHandlerFromUpdatableHandlers(notnull SCR_HUDManagerHandler handler)
override void OnUpdate(IEntity owner)
void InitRootWidget(Widget root, string name)
override void OnInit(IEntity owner)
ref array< SCR_HUDManagerHandler > m_aUpdatableHandlers
Widget FindLayoutByResourceName(ResourceName path)
Find layout by resorce name.
Widget CreateLayout(ResourceName path, EHudLayers layer, int zOrder=0)
Widget FindWidgetByNameFromAnyLayout(string widgetName, out SCR_HUDLayout foundLayout=null)
Definition Types.c:486
HYBRID_COMPONENT_ICON
Default icon for all components written in script that don't inherit ScriptComponent.
proto void Print(void var, LogLevel level=LogLevel.NORMAL)
Prints content of variable to console/log.
LogLevel
Enum with severity of the logging message.
Definition LogLevel.c:14
SCR_FieldOfViewSettings Attribute
ECurveType
Definition ECurveType.c:13
BaseHUDComponentClass GameComponentClass GetInfoDisplays(out notnull array< BaseInfoDisplay > outInfoDisplays)
WidgetFlags
Widget flags. See enf::Widget::SetFlags().
Definition WidgetFlags.c:14