Arma Reforger Explorer  1.1.0.42
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
SCR_ActionMenuInteractionDisplay.c
Go to the documentation of this file.
2 {
3  HIDDEN = 0,
4  DISABLED = 1,
5  ENABLED = 2,
6 };
7 
9 {
10  UNDEFINED = 0,
11  COLLAPSED = 1,
12  EXPANDED = 2,
13 };
14 
16 {
17  const ref Color ENABLED = Color.FromSRGBA(255, 255, 255, 255);
18  const ref Color DISABLED = Color.FromSRGBA(128, 128, 128, 255);
19  const ref Color ENABLED_CONTEXT = Color.FromSRGBA(255, 182, 95, 255);
20 };
21 
24 {
25  const static string DEFAULT = "#AR-UserActionUnavailable";
26 };
27 
29 {
30  // Global action menu atributes
31  static WorkspaceWidget s_wWorkspace;
32  static Widget s_wActionMenu;
33 
34  // Shared element atributes
35  static ResourceName s_sLayout;
36  static float s_fFadeInSpeed;
37  static int s_iSpacing = 2;
38 
39  // Selected element atributes
40  static float s_fHeight = 32;
41  static int s_iTextSize = 30;
42  static float s_fAlpha = 1;
43 
44  // Non-selected element atributes
45  static float s_fHeightNonSelected = 20;
46  static int s_iTextSizeNonSelected = 18;
47  static float s_fAlphaNonSelected = 0.8;
48 };
49 
51 {
52  protected Widget m_wElement;
53  protected TextWidget m_wActionText;
54  protected TextWidget m_wContextText;
55  protected ImageWidget m_wPerformType;
56  protected ImageWidget m_wPerformTypeHold;
57  protected ImageWidget m_wProgress;
58  protected bool m_bIsSelected = false;
59  protected int m_iIndex = 0;
60 
61  void SetEnabled(bool bEnabled)
62  {
63  if (m_wActionText)
64  {
65  if (bEnabled)
66  {
67  m_wActionText.SetColor(ActionMenuColor.ENABLED);
68  }
69  else
70  {
71  m_wActionText.SetColor(ActionMenuColor.DISABLED);
72  }
73  }
74 
75  if (m_wContextText)
76  {
77  if (bEnabled)
78  {
79  m_wContextText.SetColor(ActionMenuColor.ENABLED_CONTEXT);
80  }
81  else
82  {
83  m_wContextText.SetColor(ActionMenuColor.DISABLED);
84  }
85  }
86  }
87 
88  bool Set(BaseUserAction pAction, int iIndex, bool bIsSelected, bool bIsAvailable)
89  {
90  if (!m_wElement)
91  return false;
92 
93  if (!pAction)
94  return false;
95 
96  m_bIsSelected = bIsSelected;
97  m_iIndex = iIndex;
98 
99  string sActionName = pAction.GetActionName();
100 
101  // TODO: Make a special widget?
102  // Handle differently?
103  if (m_bIsSelected && !bIsAvailable)
104  {
105  string failReason = pAction.GetCannotPerformReason();
106  if (failReason == string.Empty)
107  failReason = ActionMenuFailReason.DEFAULT;
108 
109  // failReason.ToUpper() wouldn't cut it :\
110  sActionName = string.Format("%1 (%2)", sActionName, failReason);
111  }
112 
113  array<string> aActionStrings = new array<string>();
114  sActionName.Split("%CTX_HACK%", aActionStrings, true);
115 
116  int iActionStrings = aActionStrings.Count();
117 
118  if (iActionStrings == 0 || !aActionStrings[0])
119  return false;
120 
121  // Set string in widget and format it with provided ActionNameParams (if any)
122  m_wActionText.SetTextFormat(
123  aActionStrings[0],
124  pAction.ActionNameParams[0],
125  pAction.ActionNameParams[1],
126  pAction.ActionNameParams[2],
127  pAction.ActionNameParams[3],
128  pAction.ActionNameParams[4],
129  pAction.ActionNameParams[5],
130  pAction.ActionNameParams[6],
131  pAction.ActionNameParams[7],
132  pAction.ActionNameParams[8]
133  );
134 
135  if (iActionStrings > 1 && aActionStrings[1])
136  {
137  m_wContextText.SetText(aActionStrings[1]);
138  m_wContextText.SetVisible(true);
139  }
140  else
141  {
142  m_wContextText.SetText("");
143  m_wContextText.SetVisible(false);
144  }
145 
146  if (bIsSelected)
147  {
148  m_wActionText.SetExactFontSize(ActionMenuElementContext.s_iTextSize);
149  m_wActionText.SetDesiredFontSize(ActionMenuElementContext.s_iTextSize);
150 
151  m_wContextText.SetExactFontSize(ActionMenuElementContext.s_iTextSize);
152  m_wContextText.SetDesiredFontSize(ActionMenuElementContext.s_iTextSize);
153 
154  m_wPerformType.SetSize(2, ActionMenuElementContext.s_fHeight);
155  }
156  else
157  {
158  m_wActionText.SetExactFontSize(ActionMenuElementContext.s_iTextSizeNonSelected);
159  m_wActionText.SetDesiredFontSize(ActionMenuElementContext.s_iTextSizeNonSelected);
160 
161  m_wContextText.SetExactFontSize(ActionMenuElementContext.s_iTextSizeNonSelected);
162  m_wContextText.SetDesiredFontSize(ActionMenuElementContext.s_iTextSizeNonSelected);
163 
164  m_wPerformType.SetSize(2, ActionMenuElementContext.s_fHeightNonSelected);
165  }
166 
167  // Instant & hold actions indicator
168  float fDuration = pAction.GetActionDuration();
169 
170  if (fDuration != 0)
171  {
172  m_wPerformType.SetColor(ActionMenuColor.ENABLED);
173  m_wPerformTypeHold.SetOpacity(1);
174  }
175  else
176  {
177  m_wPerformType.SetColor(ActionMenuColor.DISABLED);
178  m_wPerformTypeHold.SetOpacity(0);
179  }
180 
181  return true;
182  }
183 
184  void Show(float fFadeSpeed, float fTimeSlice = 0)
185  {
186  if (!m_wElement)
187  return;
188 
189  float fAlpha;
190  float fTargetAlpha;
191 
192  if (m_bIsSelected)
193  fTargetAlpha = ActionMenuElementContext.s_fAlpha;
194  else
195  fTargetAlpha = ActionMenuElementContext.s_fAlphaNonSelected;
196 
197  if (fTimeSlice == 0)
198  {
199  fAlpha = fTargetAlpha;
200  }
201  else
202  {
203  fAlpha = m_wElement.GetOpacity();
204  fAlpha = Math.Lerp(fAlpha, fTargetAlpha, fFadeSpeed * fTimeSlice);
205  }
206 
207  m_wElement.SetOpacity(fAlpha);
208  m_wElement.SetVisible(true);
209  }
210 
211  void Hide()
212  {
213  if (!m_wElement)
214  return;
215 
216  m_wElement.SetOpacity(0);
217  m_wElement.SetVisible(false);
218  }
219 
220  void SetProgress(float p)
221  {
222  if (!m_wProgress)
223  return;
224 
225  m_wProgress.SetMaskProgress(p);
226  }
227 
228  void ActionMenuElement()
229  {
230  m_wElement = ActionMenuElementContext.s_wWorkspace.CreateWidgets(ActionMenuElementContext.s_sLayout, ActionMenuElementContext.s_wActionMenu);
231  LayoutSlot.SetHorizontalAlign(m_wElement, LayoutHorizontalAlign.Left);
232  LayoutSlot.SetPadding(m_wElement, 0, 0, 0, ActionMenuElementContext.s_iSpacing);
233 
234  m_wActionText = TextWidget.Cast(m_wElement.FindAnyWidget("ActionText"));
235  m_wContextText = TextWidget.Cast(m_wElement.FindAnyWidget("ActionContext"));
236  m_wPerformType = ImageWidget.Cast(m_wElement.FindAnyWidget("ActionType"));
237  m_wPerformTypeHold = ImageWidget.Cast(m_wElement.FindAnyWidget("ActionTypeHold"));
238  m_wProgress = ImageWidget.Cast(m_wElement.FindAnyWidget("ActionProgress"));
239  }
240 
241  void ~ActionMenuElement()
242  {
243  if (m_wElement)
244  m_wElement.RemoveFromHierarchy();
245 
246  m_wElement = null;
247  }
248 };
249 
250 //------------------------------------------------------------------------------------------------
252 {
253  [Attribute("{C80DEB58AA948E59}UI/layouts/HUD/InteractionSystem/ActionMenuElement.layout", UIWidgets.ResourceNamePicker, params: "layout")]
254  ResourceName m_sElementLayout;
255 
256  [Attribute("0", UIWidgets.CheckBox, "Fixed placement")]
257  protected bool m_bFixedPlacement;
258 
259  [Attribute("10.0", UIWidgets.Slider, params: "0 100 0.1")]
260  protected float m_fScrollAnimationSpeed;
261 
262  [Attribute("1.0", UIWidgets.Slider, params: "0 10 0.05")]
263  protected float m_fAutoExpandTime;
264 
265  [Attribute("10.0", UIWidgets.Slider, params: "0 100 0.1")]
266  protected float m_fFadeInSpeed;
267 
268  [Attribute("0.05", UIWidgets.Slider, "Action list element fade-in expand delay (in seconds).", params: "0 1 0.001")]
269  protected float m_fFadeInOffset;
270 
271  protected EActionMenu m_eState = EActionMenu.UNDEFINED;
272 
273  protected Widget m_wActionMenu;
274  protected Widget m_wActionButton;
275  protected Widget m_wArrowUp;
276  protected Widget m_wArrowDown;
277  protected Widget m_wHoldText;
278  protected ImageWidget m_wArrowIcon;
279 
280  protected ref map<BaseUserAction,ActionMenuElement> m_mActionWidget = new map<BaseUserAction,ActionMenuElement>;
281  protected ref array<ref ActionMenuElement> m_aActionMenuElements = new array<ref ActionMenuElement>;
282 
283  protected int m_iCurrentScroll = 0;
284  protected float m_fCurrentScrollAnimation = 0.0;
285 
286  protected float m_fExpandTimer = 0.0; // Timer for auto-expand feature
287  protected float m_fExpandedTimer = 0.0; // Time elapsed from menu expand, used for sequential fade in of elements
288 
289  protected UserActionContext m_pPrevContext = null;
290 
291  // Data containing info from interaction handler
292  protected ref ActionDisplayData m_pLastData;
293 
294  //~ In order for the continues action process not to instantly go from 100% to 0 it holds the 100% for x seconds. This const is how long it holds (In seconds)
295  protected const float CONTINUES_ACTION_RESET_HOLD = 0.25;
296 
297  //------------------------------------------------------------------------------------------------
299  protected void Create()
300  {
301  if (!m_wRoot)
302  {
303  Print("ActionsMenuDisplay is missing root layout!", LogLevel.ERROR);
304  return;
305  }
306 
307  if (!m_bFixedPlacement)
308  {
309  FrameSlot.SetAnchorMin(m_wRoot, 0, 0);
310  FrameSlot.SetAnchorMax(m_wRoot, 0, 0);
311  FrameSlot.SetAlignment(m_wRoot, 0, 0);
312  }
313  else
314  {
315  FrameSlot.SetAnchorMin(m_wRoot, 0.48, 0.94);
316  FrameSlot.SetAnchorMax(m_wRoot, 0.48, 0.94);
317  FrameSlot.SetAlignment(m_wRoot, 0, 0);
318  }
319 
320  m_wActionMenu = m_wRoot.FindAnyWidget("ActionMenu");
321  m_wActionButton = m_wRoot.FindAnyWidget("ActionButton");
322  m_wArrowUp = m_wRoot.FindAnyWidget("ArrowUp");
323  m_wArrowDown = m_wRoot.FindAnyWidget("ArrowDown");
324  m_wHoldText = m_wRoot.FindAnyWidget("HoldText");
325  m_wArrowIcon = ImageWidget.Cast(m_wRoot.FindAnyWidget("DirectionArrow"));
326 
327  if (!m_wActionMenu)
328  {
329  // TODO: Log error?
330  return;
331  }
332 
333  // Store constant data in structure for ActionMenuElement(s) to access
334  ActionMenuElementContext.s_wWorkspace = m_wRoot.GetWorkspace();
335  ActionMenuElementContext.s_wActionMenu = m_wActionMenu;
336  ActionMenuElementContext.s_sLayout = m_sElementLayout;
337  ActionMenuElementContext.s_fFadeInSpeed = m_fFadeInSpeed;
338 
339  // Initialize action menu state and data
340  Collapse();
341  }
342 
343  //------------------------------------------------------------------------------------------------
344  protected void Destroy()
345  {
346  if (m_aActionMenuElements)
347  m_aActionMenuElements.Clear();
348  }
349 
350  //------------------------------------------------------------------------------------------------
351  protected bool Update(ActionsTuple pActionsData, BaseUserAction pSelectedAction, UserActionContext pCurrentContext, float fTimeSlice)
352  {
353  if (!pCurrentContext)
354  return false;
355 
356  // Detect context change
357  if (pCurrentContext != m_pPrevContext)
358  {
359  m_pPrevContext = pCurrentContext;
360  Collapse();
361  }
362 
363  int iActionsCount = pActionsData.param1.Count();
364 
365  if (!pActionsData.param1 || iActionsCount == 0)
366  return false;
367 
368  if (iActionsCount > 1)
369  {
370  RunExpandTimer(fTimeSlice);
371  RunExpandedTimer(fTimeSlice);
372  }
373  else
374  Collapse();
375 
376  int iActiveWidgetsCount = m_aActionMenuElements.Count();
377  int iActionsDelta = iActiveWidgetsCount - iActionsCount;
378  int iAbsDelta = Math.AbsInt(iActionsDelta);
379 
380  // Add or remove widgets
381  if (iActionsDelta < 0)
382  {
383  // Elements missing
384  for (int i = 0; i < iAbsDelta; i++)
385  {
386  ref ActionMenuElement pActionMenuElement = new ActionMenuElement();
387  m_aActionMenuElements.Insert(pActionMenuElement);
388  }
389  }
390  else if (iActionsDelta > 0)
391  {
392  // Elements over
393  for (int i = iActiveWidgetsCount-1; i >= iActiveWidgetsCount-iAbsDelta; i--)
394  {
395  ActionMenuElement pActionMenuElement = m_aActionMenuElements[i];
396  pActionMenuElement.Hide();
397  }
398  }
399 
400  int iCurrentAction = -1;
401  for (int i = 0; i < pActionsData.param1.Count(); i++)
402  {
403  if (pActionsData.param1[i] == pSelectedAction)
404  {
405  iCurrentAction = i;
406  break;
407  }
408  }
409 
410  if (iCurrentAction == -1)
411  return false;
412 
413  // Expand menu upon interaction
414  if (iCurrentAction > 0)
415  Expand();
416 
417  // Clear action map before it is re-filled by actual data
418  m_mActionWidget.Clear();
419 
420  // Set widget data
421  for (int i = 0; i < iActionsCount; i++)
422  {
423  BaseUserAction pAction = pActionsData.param1[i];
424  ActionMenuElement pActionMenuElement = m_aActionMenuElements[i];
425 
426  // Setup menu element
427  bool succeeded = pActionMenuElement.Set(pAction, i, pAction == pSelectedAction, pActionsData.param2[i]);
428 
429  if (!succeeded)
430  {
431  pActionMenuElement.Hide();
432  continue;
433  }
434 
435  // Add new entry to action map
436  m_mActionWidget.Insert(pAction, pActionMenuElement);
437 
438  // Set element visibility based on menu state
439  if ((i == 0 || m_eState == EActionMenu.EXPANDED) && (m_fExpandedTimer >= i * m_fFadeInOffset))
440  pActionMenuElement.Show(m_fFadeInSpeed, fTimeSlice);
441  else
442  pActionMenuElement.Hide();
443 
444  // Set enabled/disabled based on whether action can be performed
445  pActionMenuElement.SetEnabled(pActionsData.param2[i]);
446  }
447 
448  // Update visibility of the HOLD button prefix
449  if (pSelectedAction.GetActionDuration() != 0)
450  m_wHoldText.SetVisible(true);
451  else
452  m_wHoldText.SetVisible(false);
453 
454  // Toggle selection / adjustment widgets
455  bool isInProgress = pSelectedAction && pSelectedAction.IsInProgress();
456  SCR_AdjustSignalAction adjustAction = SCR_AdjustSignalAction.Cast(pSelectedAction);
457  if (isInProgress && adjustAction && adjustAction.IsManuallyAdjusted())
458  {
459  UpdateArrow(m_wArrowUp, EActionMenuScroll.ENABLED);
460  UpdateArrow(m_wArrowDown, EActionMenuScroll.ENABLED);
461  }
462  else if (isInProgress || iActionsCount <= 1)
463  {
464  UpdateArrow(m_wArrowUp, EActionMenuScroll.HIDDEN);
465  UpdateArrow(m_wArrowDown, EActionMenuScroll.HIDDEN);
466  }
467  else
468  {
469  if (pSelectedAction == pActionsData.param1[0])
470  UpdateArrow(m_wArrowUp, EActionMenuScroll.DISABLED);
471  else
472  UpdateArrow(m_wArrowUp, EActionMenuScroll.ENABLED);
473 
474  if (pSelectedAction == pActionsData.param1[iActionsCount-1])
475  UpdateArrow(m_wArrowDown, EActionMenuScroll.DISABLED);
476  else
477  UpdateArrow(m_wArrowDown, EActionMenuScroll.ENABLED);
478  }
479 
480  // Set and animate scroll
481  SetScroll(iCurrentAction, fTimeSlice);
482 
483  return true;
484  }
485 
486  //------------------------------------------------------------------------------------------------
487  protected bool GetSafeZone(vector worldPosition, vector screenPosition, vector min01, vector max01, out vector clampedPosition)
488  {
489  WorkspaceWidget workspace = m_wActionMenu.GetWorkspace();
490  int screenw = workspace.DPIUnscale(workspace.GetWidth());
491  int screenh = workspace.DPIUnscale(workspace.GetHeight());
492 
493 
494  float padding = 15.0;
495 
496  vector min = Vector(
497  screenw * min01[0] + padding,
498  screenh * min01[1] + padding,
499  0.0);
500 
501  float menuw, menuh;
502  m_wActionMenu.GetScreenSize(menuw, menuh);
503  menuw = workspace.DPIUnscale(menuw);
504  menuh = workspace.DPIUnscale(menuh);
505 
506  // Maxs are offset by the menu width, so the menu never overflows
507  vector max = Vector(
508  screenw * max01[0] - menuw - padding,
509  screenh * max01[1] - menuh + padding,
510  0.0);
511 
512 
513  bool clamped = false;
514  clampedPosition = screenPosition;
515 
516  // Bold assumption that can be done is that if this display is shown,
517  // the main camera is used for collecting the actions
518  CameraManager cameraManager = GetGame().GetCameraManager();
519  if (cameraManager)
520  {
521  CameraBase currentCamera = cameraManager.CurrentCamera();
522  if (currentCamera)
523  {
524  vector camTM[4];
525  currentCamera.GetWorldCameraTransform(camTM);
526  vector toActionDir = (worldPosition - camTM[3]).Normalized();
527  float d = vector.Dot(toActionDir, camTM[2]);
528  const float threshold = 0.5;
529  const float invThreshold = 1.0 / 0.5;
530  // Action is "behind view"
531  if (d < threshold)
532  {
533  float stickiness = 1.0;
534  // Use this to blend towards "full backwards" smoothly
535  if (d > 0.0)
536  stickiness = Math.Clamp(1.0 - (d * invThreshold), 0.0, 1.0);
537 
538  clampedPosition[1] = Math.Lerp(clampedPosition[1], max[1], stickiness);
539  clamped = true;
540  }
541  }
542  }
543 
544 
545  for (int i = 0; i < 2; ++i)
546  {
547  if (clampedPosition[i] < min[i])
548  {
549  clampedPosition[i] = min[i];
550  clamped = true;
551  }
552  else if (clampedPosition[i] > max[i])
553  {
554  clampedPosition[i] = max[i];
555  clamped = true;
556  }
557  }
558 
559  return clamped;
560  }
561 
562  //------------------------------------------------------------------------------------------------
563  void SetPosition(vector vWorldPosition)
564  {
565  if (!m_wRoot)
566  return;
567 
568  if (!m_bFixedPlacement)
569  {
570  vector vScreenPosition = GetGame().GetWorkspace().ProjWorldToScreen(vWorldPosition, GetGame().GetWorld());
571  vector vClampedPosition;
572  if (GetSafeZone(vWorldPosition, vScreenPosition, "0.15 0.15 0", "0.85 0.85 0", vClampedPosition))
573  {
574 
575  vector dir = (vScreenPosition - vClampedPosition).Normalized();
576 
577  float rads = 0;
578  float d = vector.Dot(dir, vector.Right);
579  if (vector.Dot(dir, vector.Up) > 0.0)
580  rads = Math.Acos(d);
581  else
582  rads = -Math.Acos(d);
583 
584  const float size = 25.0;
585  vector point = size * dir;
586  FrameSlot.SetPos(m_wArrowIcon, 3.0 + point[0], point[1]);
587  m_wArrowIcon.SetRotation(rads * Math.RAD2DEG);
588  m_wArrowIcon.SetVisible(true);
589  }
590  else
591  {
592  m_wArrowIcon.SetVisible(false);
593  }
594 
595  FrameSlot.SetPos(m_wRoot, vClampedPosition[0], vClampedPosition[1]);
596 
597  // If action menu is drawn over picture in picture, fade out its opacity
598  // so it is not as intrusive and so it promotes the idea of it being "behind" the sights
599  SCR_2DPIPSightsComponent pipSights = ArmaReforgerScripted.GetCurrentPIPSights();
600  bool isPointInPIP = pipSights && pipSights.IsScreenPositionInSights(vClampedPosition);
601 
602  float alpha = 1.0;
603  if (isPointInPIP)
604  alpha = 0.75;
605 
606  m_wActionButton.SetOpacity(alpha);
607  m_wActionMenu.SetOpacity(alpha);
608  }
609  }
610 
611  protected void SetScreenPosition(vector screenPosition)
612  {
613  if (!m_wRoot)
614  return;
615 
616  FrameSlot.SetPos(m_wRoot, screenPosition[0], screenPosition[1]);
617  }
618 
619  //------------------------------------------------------------------------------------------------
620  void SetScroll(int iCurrentScroll, float fTimeSlice = 0)
621  {
622  if (!m_wActionMenu)
623  return;
624 
625  float fCurrentScroll = iCurrentScroll;
626 
627  // Reset action list to initial position
628  if (fTimeSlice == 0)
629  {
630  m_fCurrentScrollAnimation = 0.0;
631 
632  float fVerticalPos = - 0.5 * ActionMenuElementContext.s_fHeight;
633 
634  FrameSlot.SetPosY(m_wActionMenu, fVerticalPos);
635  }
636  // Scroll the action list towards the target position (iCurrentScroll)
637  else if (Math.AbsFloat(m_fCurrentScrollAnimation - fCurrentScroll) > 0.001)
638  {
639  m_fCurrentScrollAnimation = Math.Lerp(m_fCurrentScrollAnimation, fCurrentScroll, m_fScrollAnimationSpeed * fTimeSlice);
640 
641  float fVerticalPos = - 0.5 * ActionMenuElementContext.s_fHeight;
642  fVerticalPos -= m_fCurrentScrollAnimation * (ActionMenuElementContext.s_fHeightNonSelected + ActionMenuElementContext.s_iSpacing);
643 
644  FrameSlot.SetPosY(m_wActionMenu, fVerticalPos);
645  }
646  }
647 
648  //------------------------------------------------------------------------------------------------
649  void UpdateArrow(Widget w, EActionMenuScroll state)
650  {
651  if (!w)
652  return;
653 
654  if (state == EActionMenuScroll.HIDDEN)
655  {
656  w.SetVisible(false);
657  }
658  else
659  {
660  w.SetVisible(true);
661 
662  if (state == EActionMenuScroll.ENABLED)
663  w.SetColor(ActionMenuColor.ENABLED);
664  else
665  w.SetColor(ActionMenuColor.DISABLED);
666  }
667  }
668 
669  //------------------------------------------------------------------------------------------------
670  void RunExpandTimer(float fTimeSlice)
671  {
672  if (m_eState != EActionMenu.COLLAPSED)
673  {
674  m_fExpandTimer = 0.0;
675  return;
676  }
677 
678  // Expansion of additional actions
679  m_fExpandTimer += fTimeSlice;
680 
681  if (m_fExpandTimer > m_fAutoExpandTime)
682  Expand();
683  }
684 
685  //------------------------------------------------------------------------------------------------
686  void RunExpandedTimer(float fTimeSlice)
687  {
688  if (m_eState != EActionMenu.EXPANDED)
689  {
690  m_fExpandedTimer = 0.0;
691  return;
692  }
693 
694  // Expansion of additional actions
695  m_fExpandedTimer += fTimeSlice;
696  }
697 
698  //------------------------------------------------------------------------------------------------
699  void Expand()
700  {
701  if (m_eState == EActionMenu.EXPANDED)
702  return;
703 
704  m_eState = EActionMenu.EXPANDED;
705  }
706 
707  //------------------------------------------------------------------------------------------------
708  void Collapse()
709  {
710  m_eState = EActionMenu.COLLAPSED;
711 
712  SetScroll(0);
713  }
714 
715  #ifndef DISABLE_INTERACTIONS
716  //------------------------------------------------------------------------------------------------
718  override void OnActionStart(IEntity pUser, BaseUserAction pPerformedAction)
719  {
720  ActionMenuElement pActionMenuElement = m_mActionWidget.Get(pPerformedAction);
721 
722  if (!pActionMenuElement)
723  return;
724 
725  pActionMenuElement.SetProgress(0);
726  }
727 
728  //------------------------------------------------------------------------------------------------
730  override void OnActionProgress(IEntity pUser, BaseUserAction pPerformedAction, float fProgress, float fDuration)
731  {
732  ActionMenuElement pActionMenuElement = m_mActionWidget.Get(pPerformedAction);
733  if (!pActionMenuElement)
734  return;
735  if (fDuration == 0.0)
736  pActionMenuElement.SetProgress(0.0);
737  //~ Continues action
738  else
739  pActionMenuElement.SetProgress(fProgress / fDuration);
740  }
741 
742  //------------------------------------------------------------------------------------------------
744  override void OnActionFinish(IEntity pUser, BaseUserAction pFinishedAction, ActionFinishReason eFinishReason)
745  {
746  ActionMenuElement pActionMenuElement = m_mActionWidget.Get(pFinishedAction);
747 
748  if (!pActionMenuElement)
749  return;
750 
751  pActionMenuElement.SetProgress(0);
752  }
753 
754  //------------------------------------------------------------------------------------------------
755  override void DisplayUpdate(IEntity owner, float timeSlice)
756  {
757  // Need data to update
758  if (!m_pLastData || !m_pLastData.pSelectedAction)
759  {
760  if (m_bShown)
761  Show(false);
762 
763  return;
764  }
765 
766  // Update ui
767  bool succeeded = Update(m_pLastData.pActionsData, m_pLastData.pSelectedAction, m_pLastData.pCurrentContext, timeSlice);
768 
769  // Toggle visibility
770  if (!succeeded)
771  {
772  if (m_bShown)
773  Show(false);
774 
775  return;
776  }
777 
778  if (!m_bShown)
779  Show(true);
780 
781  // Update current widget context position
782  UserActionContext lastContext = m_pLastData.pCurrentContext;
783  if (lastContext)
784  {
785  vector worldPosition = lastContext.GetOrigin();
786  SetPosition(worldPosition);
787  }
788 
789  // Clear last data
790  m_pLastData = null;
791 
792  // Be careful: pUser can be passed in as NULL if player has no controlled entity!
793  // Can be used to progress animations
794  // Will be called every frame from the interaction handler as long as we have a valid player controller
795 
796 
797  // PlayerController pc = PlayerController.Cast(owner);
798  // if (pc)
799  // auto user = pc.GetControlledEntity();
800  }
801 
802  //------------------------------------------------------------------------------------------------
803  override void DisplayStartDraw(IEntity owner)
804  {
805  super.DisplayStartDraw(owner);
806  Create();
807 
808  Show(false);
809  }
810 
811  //------------------------------------------------------------------------------------------------
812  override void DisplayStopDraw(IEntity owner)
813  {
814  Destroy();
815  m_pLastData = null;
816  }
817 
818  //------------------------------------------------------------------------------------------------
820  override void ShowDisplay()
821  {
822  super.ShowDisplay();
823 
824  Show(true);
825  }
826 
827  //------------------------------------------------------------------------------------------------
829  override void HideDisplay()
830  {
831  m_pLastData = null;
832 
833  Show(false);
834 
835  super.HideDisplay();
836  }
837 
838  //------------------------------------------------------------------------------------------------
840  override void SetDisplayData(ActionDisplayData data)
841  {
842  m_pLastData = data;
843  }
844 
845  //------------------------------------------------------------------------------------------------
847  {
848  Destroy();
849  }
850  #endif
851 };
m_bShown
protected bool m_bShown
Definition: SCR_InfoDisplay.c:61
SCR_ActionMenuInteractionDisplay
Definition: SCR_ActionMenuInteractionDisplay.c:251
ActionMenuElementContext
Definition: SCR_ActionMenuInteractionDisplay.c:28
ENABLED
@ ENABLED
Definition: SCR_ActionMenuInteractionDisplay.c:5
m_wRoot
protected Widget m_wRoot
Definition: SCR_ScenarioFrameworkLayerTaskDefend.c:59
SCR_BaseInteractionDisplay
Base class for displaying interactions in the UI.
Definition: SCR_BaseInteractionDisplay.c:39
GetGame
ArmaReforgerScripted GetGame()
Definition: game.c:1424
DISABLED
@ DISABLED
Definition: SCR_ActionMenuInteractionDisplay.c:4
Show
override void Show(WorkspaceWidget pWorkspace, Widget pToolTipWidget, float desiredPosX, float desiredPosY)
Definition: SCR_ScriptedWidgetTooltip.c:55
ActionMenuFailReason
Temp class until localization is done.
Definition: SCR_ActionMenuInteractionDisplay.c:23
ActionMenuColor
Definition: SCR_ActionMenuInteractionDisplay.c:15
ActionFinishReason
ActionFinishReason
Reason for why an action ended. Used in SCR_BaseInteractionDisplay and derived classes.
Definition: SCR_BaseInteractionDisplay.c:3
m_eState
EAITargetClusterState m_eState
Definition: SCR_AITargetClusterState.c:24
ActionsTuple
Definition: SCR_BaseInteractionDisplay.c:13
Attribute
typedef Attribute
Post-process effect of scripted camera.
EActionMenu
EActionMenu
Definition: SCR_ActionMenuInteractionDisplay.c:8
ActionDisplayData
Data container.
Definition: SCR_BaseInteractionDisplay.c:29
SCR_AdjustSignalAction
Definition: SCR_AdjustSignalAction.c:1
m_iIndex
private int m_iIndex
Definition: SCR_StressTestGroupActivation.c:11
EXPANDED
@ EXPANDED
Definition: SCR_ActionMenuInteractionDisplay.c:12
BaseUserAction
Definition: BaseUserAction.c:12
COLLAPSED
@ COLLAPSED
Definition: SCR_ActionMenuInteractionDisplay.c:11
data
Get all prefabs that have the spawner data
Definition: SCR_EntityCatalogManagerComponent.c:305
params
Configs ServerBrowser KickDialogs params
Definition: SCR_NotificationSenderComponent.c:24
EActionMenuScroll
EActionMenuScroll
Definition: SCR_ActionMenuInteractionDisplay.c:1
m_fFadeInSpeed
protected float m_fFadeInSpeed
Definition: SCR_TooltipManagerEditorUIComponent.c:11
UNDEFINED
@ UNDEFINED
Definition: SCR_ActionMenuInteractionDisplay.c:10
HIDDEN
@ HIDDEN
Definition: SCR_ActionMenuInteractionDisplay.c:3
UserActionContext
Definition: UserActionContext.c:15
ActionMenuElement
Definition: SCR_ActionMenuInteractionDisplay.c:50