Arma Reforger Explorer  1.1.0.42
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
SCR_InputButtonComponent.c
Go to the documentation of this file.
2 {
3  [Attribute("MenuTabLeft", desc: "Name of action from chimeraInputCommon")]
4  protected string m_sActionName;
5 
6  [Attribute("Navigation Button")]
7  protected string m_sLabel;
8 
9  [Attribute("0")]
10  protected bool m_bIsMouseInput;
11 
12  [Attribute(defvalue: "32", desc: "Define the Height in PX. Wight will be adjusted automatically")]
13  int m_iHeightInPixel;
14 
15  [Attribute(UIColors.GetColorAttribute(UIColors.CONTRAST_COLOR), UIWidgets.ColorPicker)]
16  ref Color m_ActionDefault;
17 
18  [Attribute(UIColors.GetColorAttribute(UIColors.HIGHLIGHTED), UIWidgets.ColorPicker)]
19  ref Color m_ActionHovered;
20 
21  [Attribute(UIColors.GetColorAttribute(UIColors.IDLE_DISABLED), UIWidgets.ColorPicker)]
22  ref Color m_ActionDisabled;
23 
24  [Attribute(UIColors.GetColorAttribute(Color.White), UIWidgets.ColorPicker)]
25  ref Color m_LabelDefault;
26 
27  [Attribute("0.597421 0.061189 0.475868 1.000000", UIWidgets.ColorPicker)]
28  ref Color m_ActionToggled;
29 
30  [Attribute("0", desc: "If enabled there will be no sound played when the button is pressed")]
31  protected bool m_bDisableClickSound;
32 
33  [Attribute("0", desc: "Postion offset when button is not held")]
34  float m_fHoldIndicatorDefaultPosition;
35 
36  [Attribute("5", desc: "Position offset when button is held")]
37  float m_fHoldIndicatorHoldPosition;
38 
39  [Attribute("0.1", desc:"Time in sec who long the animation takes.")]
40  float m_fHoldIndicatorAnimationTime;
41 
42  [Attribute("1", desc: "If false the button will never change to its disabled visual state.")]
43  bool m_bCanBeDisabled;
44 
45  [Attribute("1", desc: "If false the Label does not change its color to disabled when button is disabled.")]
46  bool m_bChangeLabelColorOnDisabled;
47 
48  [Attribute("InputButtonDisplayRoot")]
49  protected string m_sButtonWidgetName;
50 
51  [Attribute("HorizontalLayout0")]
52  protected string m_sHorizontalLayoutWidget;
53 
54  [Attribute("TextHint")]
55  protected string m_sTextHintWidget;
56 
57  [Attribute("{B7C8B633428B153D}UI/layouts/WidgetLibrary/Buttons/WLib_InputButtonDisplay.layout")]
58  protected ResourceName m_sInputButtonWidget;
59 
60  [Attribute("{983DFCCEB578C1C5}UI/layouts/InputButtons/InputButton_ComboIndicator.layout")]
61  protected ResourceName m_sComboIndicatorWidget;
62 
63  [Attribute("{3262679C50EF4F01}UI/Textures/Icons/icons_wrapperUI.imageset")]
64  protected ResourceName m_sComboIndicatorImageSet;
65 
66  [Attribute("{00FE3DBDFD15227B}UI/Textures/Icons/icons_wrapperUI-glow.imageset")]
67  protected ResourceName m_sComboIndicatorImageSetGlow;
68 
69  [Attribute(desc: "If enabled Text size is controlled by set size Inside the RichText widget")]
70  protected bool m_bOverrideTextSize;
71 
72  [Attribute("-0.05", desc: "Time that will the HoldTime will be reduced by to make the Animation the right length. Time in seconds")]
73  protected float m_fHoldTimeReduction;
74 
75  [Attribute()]
76  protected bool m_bDebugSimulateController;
77 
78  protected const string COMBO_INDICATOR_IMAGE_NAME = "ComboIndicatorImg";
79  protected const string COMBO_INDICATOR_SHADOW_NAME = "ComboIndicatorShadow";
80  protected const string COMBO_INDICATOR_DIVIDER_NAME = "keybind_divider";
81 
82  protected const float COMBO_INDICATOR_SIZE_MULTIPLIER = 0.5;
83  protected const float MIN_FONTSIZE_MULTIPLIER = 0.5;
84 
85  protected ref SCR_InputButtonDisplay m_ButtonDisplay;
86  protected Widget m_wHorizontalLayout;
87  protected ImageWidget m_wComboIndicatorImage;
88  protected ImageWidget m_wComboIndicatorShadow;
89  protected RichTextWidget m_wTextHint;
90 
91  protected ref array<Widget> m_aComboWidgets = {};
92  protected ref array<BaseContainer> filterStack = {};
93  protected ref array<int> m_aFilterStackIndexRemover = {};
94 
95  InputManager m_InputManager = GetGame().GetInputManager();
96 
97  protected bool m_bIsComboInput;
98  protected bool m_bIsAlternativeInput;
99  protected bool m_bIsHoldAction;
100  protected bool m_bIsDoubleTapAction;
101  protected bool m_bPressedInput;
102  protected bool m_bIsContinuous;
103 
104  protected bool m_bForceDisabled;
105  protected bool m_bShouldBeEnabled;
106  protected bool m_bIsInteractionActive;
107 
108  protected string m_sOldActionName;
109 
110  protected bool m_bIsHoldingButton;
111  bool m_bIsHovered;
112  bool m_bIsDoubleTapStated;
113 
114  protected float m_fDefaultHoldTime;
115  protected float m_fDefaultClickTime;
116  float m_fMaxHoldtime;
117 
118  int m_iDoubleTapThreshold;
119 
120  protected EInputDeviceType m_eCurrentInputDevice;
121 
122  protected ref ScriptInvokerVoid m_OnAnimateHover;
123  protected ref ScriptInvokerVoid m_OnUpdateEnableColor;
124  protected ref ScriptInvokerVoid m_OnHoldAnimComplete;
125 
126  ref ScriptInvoker m_OnActivated = new ScriptInvoker();
127  protected ref array<DialogUI> m_aDialogs;
128 
129  //------------------------------------------------------------------------------------------------
130  override void HandlerAttached(Widget w)
131  {
132  super.HandlerAttached(w);
133 
134  m_wHorizontalLayout = HorizontalLayoutWidget.Cast(w.FindAnyWidget(m_sHorizontalLayoutWidget));
135  m_wTextHint = RichTextWidget.Cast(w.FindAnyWidget(m_sTextHintWidget));
136 
137  Widget buttonWidget = Widget.Cast(w.FindAnyWidget(m_sButtonWidgetName));
138  if (!buttonWidget)
139  return;
140 
141  m_ButtonDisplay = SCR_InputButtonDisplay.Cast(buttonWidget.FindHandler(SCR_InputButtonDisplay));
142  if (!m_ButtonDisplay)
143  return;
144 
146  GameProject.GetModuleConfig("InputManagerSettings").Get("HoldDuration", m_fDefaultHoldTime);
147  GameProject.GetModuleConfig("InputManagerSettings").Get("ClickDuration", m_fDefaultClickTime);
148  if (m_fDefaultClickTime)
149  {
150  m_fDefaultClickTime /= 1000;
151  m_fHoldTimeReduction += m_fDefaultClickTime;
152  }
153 
154  if (m_wTextHint)
155  {
156  if (!m_sLabel)
157  m_wTextHint.SetVisible(false);
158 
159  m_wTextHint.SetText(m_sLabel);
160  m_wTextHint.SetColor(m_LabelDefault);
161  }
162 
163  if (GetGame().InPlayMode())
164  {
165  m_aDialogs = new array<DialogUI>;
166 
167  SCR_MenuHelper.GetOnActiveWidgetInteraction().Insert(OnActiveWidgetInteraction);
168  SCR_MenuHelper.GetOnDialogOpen().Insert(OnDialogOpen);
169  SCR_MenuHelper.GetOnDialogClose().Insert(OnDialogClose);
170  SCR_MenuHelper.GetOnMenuFocusGained().Insert(OnMenuFocusGained);
171  SCR_MenuHelper.GetOnMenuFocusLost().Insert(OnMenuFocusLost);
172  }
173 
174  m_bShouldBeEnabled = IsEnabled();
175 
176  m_ButtonDisplay.Init(m_wRoot);
177 
178  ChangeInputDevice(m_InputManager.GetLastUsedInputDevice(), false);
179 
180  GetGame().OnInputDeviceIsGamepadInvoker().Insert(OnInputDeviceUserChanged);
181 
182  if (m_bDebugSimulateController)
183  OnInputDeviceUserChanged(true);
184  }
185 
186  //------------------------------------------------------------------------------------------------
187  override void HandlerDeattached(Widget w)
188  {
190  if (!m_InputManager)
191  return;
192 
193  GetGame().OnInputDeviceIsGamepadInvoker().Remove(OnInputDeviceUserChanged);
194 
195  if (GetGame().InPlayMode())
196  {
197  SCR_MenuHelper.GetOnActiveWidgetInteraction().Remove(OnActiveWidgetInteraction);
198  SCR_MenuHelper.GetOnDialogOpen().Remove(OnDialogOpen);
199  SCR_MenuHelper.GetOnDialogClose().Remove(OnDialogClose);
200  SCR_MenuHelper.GetOnMenuFocusGained().Remove(OnMenuFocusGained);
201  SCR_MenuHelper.GetOnMenuFocusLost().Remove(OnMenuFocusLost);
202  }
203  }
204 
205  //------------------------------------------------------------------------------------------------
206  override bool OnClick(Widget w, int x, int y, int button)
207  {
208  }
209 
210  //------------------------------------------------------------------------------------------------
211  override void SetEnabled(bool enabled, bool animate = true)
212  {
213  m_bShouldBeEnabled = enabled;
214  SetEnabled_Internal(enabled, animate);
215  }
216 
217  //------------------------------------------------------------------------------------------------
218  protected void SetEnabled_Internal(bool enabled, bool animate = true)
219  {
220  if (!m_bForceDisabled)
221  {
222  m_wRoot.SetEnabled(enabled);
223  if (enabled)
224  OnEnabled(animate);
225  else
226  OnDisabled(animate);
227  }
228  else
229  {
230  m_wRoot.SetEnabled(false);
231  OnDisabled(animate);
232  }
233  }
234 
235  //------------------------------------------------------------------------------------------------
237  protected void OnInputDeviceUserChanged(bool isGamepad)
238  {
239  if (isGamepad)
240  ChangeInputDevice(EInputDeviceType.GAMEPAD, false);
241  else
242  ChangeInputDevice(EInputDeviceType.KEYBOARD, false);
243  }
244 
245  //------------------------------------------------------------------------------------------------
247  protected void ChangeInputDevice(EInputDeviceType inputDevice, bool hasFocus, bool resetOverride = false)
248  {
249  if (inputDevice == m_eCurrentInputDevice && m_sActionName == m_sOldActionName && !resetOverride)
250  return;
251 
252  if (inputDevice == EInputDeviceType.MOUSE && hasFocus && m_bIsMouseInput)
253  {
254  m_eCurrentInputDevice = inputDevice;
255  }
256  else
257  {
258  if (inputDevice == EInputDeviceType.GAMEPAD)
259  m_eCurrentInputDevice = inputDevice;
260  else
261  m_eCurrentInputDevice = EInputDeviceType.KEYBOARD;
262  }
263 
264  DeleteComboWidget();
265 
266  if (inputDevice == EInputDeviceType.INVALID)
267  return;
268 
269  array<string> keyStack = {};
271  if (m_InputManager.GetActionKeybinding(m_sActionName, keyStack, filterStack, m_eCurrentInputDevice))
272  {
273  m_aFilterStackIndexRemover.Clear();
274  int index = keyStack.Count() - 1;
275  string keyCode = ProcessKeybindStack(index, keyStack);
276 
277  //Check if InputAction is a Combo or alternative.
278  TStringArray m_aKeyCodeString = new TStringArray;
279  if (keyCode.Contains(" + "))
280  {
281  keyCode.Split(" + ", m_aKeyCodeString, true);
282  m_bIsComboInput = true;
283 
284  keyCode = m_aKeyCodeString[0];
285  }
286  else if (keyCode.Contains(" | "))
287  {
288  keyCode.Split(" | ", m_aKeyCodeString, true);
289 
290  if (m_aKeyCodeString[0].Contains("keyboard:") && m_aKeyCodeString[1].Contains("mouse:"))
291  m_bIsAlternativeInput = false;
292  else
293  m_bIsAlternativeInput = true;
294 
295  keyCode = m_aKeyCodeString[0];
296  }
297 
298  if (!m_InputManager || !keyCode || !m_InputManager.GetKeyUIMapping(keyCode))
299  return;
300 
301  BaseContainer data = m_InputManager.GetKeyUIMapping(keyCode).GetObject("Data");
302  if (!data)
303  {
304  Print(string.Format("No data found for %1 !! Check 'chimeraMapping.conf' and add data if necessary! Provided Actioname: %2.", keyCode, m_sActionName), LogLevel.ERROR);
305  return;
306  }
307 
308  //Check is there is a valid filter applied
309  GetInputFilterSettings(filterStack[0]);
310 
311  //Process filter stack for visualisation
312  ProcessFilterStack();
313 
314  if (m_ButtonDisplay)
315  m_ButtonDisplay.SetAction(data, filterStack[0]);
316 
317  if (!m_bOverrideTextSize && m_wTextHint && m_ButtonDisplay)
318  {
319  int textSize = m_iHeightInPixel / m_ButtonDisplay.GetTextSizeModifier();
320  m_wTextHint.SetDesiredFontSize(textSize);
321  m_wTextHint.SetMinFontSize(textSize * MIN_FONTSIZE_MULTIPLIER);
322  }
323 
324 
325  if (m_bIsComboInput || m_bIsAlternativeInput)
326  CreateComboWidget(m_aKeyCodeString);
327 
328  SetInputAction();
329  }
330  }
331 
332  //------------------------------------------------------------------------------------------------
334  protected bool GetInputFilterSettings(BaseContainer filter)
335  {
336  m_bIsHoldAction = false;
337  m_bIsDoubleTapAction = false;
338  m_bPressedInput = false;
339  m_bCanBeToggled = false;
340  m_bIsContinuous = false;
341 
342  if (!filter)
343  return false;
344 
345  switch (filter.GetClassName())
346  {
347  case "InputFilterHold":
348  {
349  filter.Get("HoldDuration", m_fMaxHoldtime);
350  if (m_fMaxHoldtime == -1 || m_fMaxHoldtime == 0)
351  m_fMaxHoldtime = m_fDefaultHoldTime;
352 
353  m_fMaxHoldtime /= 1000;
354  m_fMaxHoldtime -= m_fHoldTimeReduction;
355  if (m_fMaxHoldtime <= 0)
356  m_fMaxHoldtime += m_fHoldTimeReduction;
357 
358  m_bIsHoldAction = true;
359  break;
360  }
361  case "InputFilterHoldOnce":
362  {
363  filter.Get("HoldDuration", m_fMaxHoldtime);
364  if (m_fMaxHoldtime == -1 || m_fMaxHoldtime == 0)
365  m_fMaxHoldtime = m_fDefaultHoldTime;
366 
367  m_fMaxHoldtime /= 1000;
368  m_fMaxHoldtime -= m_fHoldTimeReduction;
369  if (m_fMaxHoldtime <= 0)
370  m_fMaxHoldtime += m_fHoldTimeReduction;
371 
372  m_bIsHoldAction = true;
373  break;
374  }
375  case "InputFilterDoubleClick":
376  {
377  m_bIsDoubleTapAction = true;
378  filter.Get("Threshold", m_iDoubleTapThreshold);
379  if (m_iDoubleTapThreshold == -1)
380  GameProject.GetModuleConfig("InputManagerSettings").Get("DoubleClickDuration", m_iDoubleTapThreshold);
381 
382  m_iDoubleTapThreshold /= 1000;
383  break;
384  }
385  case "InputFilterPressed":
386  {
387  m_bPressedInput = true;
388  break;
389  }
390  case "InputFilterToggle":
391  {
392  m_bCanBeToggled = true;
393  break;
394  }
395  case "InputFilterValue":
396  {
397  m_bIsContinuous = true;
398  break;
399  }
400  }
401 
402  return false;
403  }
404 
405  //------------------------------------------------------------------------------------------------
408  protected void CreateComboWidget(TStringArray keyCodes)
409  {
410  if (m_ButtonDisplay.GetIsOverwritten())
411  return;
412 
413  for (int i = 1, count = keyCodes.Count(); i < count; i++)
414  {
415  if (!keyCodes[i])
416  return;
417 
418  BaseContainer keyData = m_InputManager.GetKeyUIMapping(keyCodes[i]).GetObject("Data");
419  if (!keyData)
420  {
421  Print(string.Format("No data found for %1 !! Check 'chimeraMapping.conf' and add data if necessary!", keyCodes[i]), LogLevel.ERROR);
422  return;
423  }
424 
426  Widget comboIndicator = GetGame().GetWorkspace().CreateWidgets(m_sComboIndicatorWidget, m_wHorizontalLayout);
427 
428  if (!comboIndicator)
429  {
430  Print(string.Format("Unable to create Widget! %1 or %2 are null!", m_sComboIndicatorWidget, m_wHorizontalLayout), LogLevel.ERROR);
431  return;
432  }
433 
434  m_wComboIndicatorImage = ImageWidget.Cast(comboIndicator.FindAnyWidget(COMBO_INDICATOR_IMAGE_NAME));
435  m_wComboIndicatorShadow = ImageWidget.Cast(comboIndicator.FindAnyWidget(COMBO_INDICATOR_SHADOW_NAME));
436 
437  if (m_wComboIndicatorImage && m_wComboIndicatorShadow)
438  {
439  if (m_bIsAlternativeInput)
440  {
441  m_wComboIndicatorImage.LoadImageFromSet(0, m_sComboIndicatorImageSet, COMBO_INDICATOR_DIVIDER_NAME);
442  m_wComboIndicatorShadow.LoadImageFromSet(0, m_sComboIndicatorImageSetGlow, COMBO_INDICATOR_DIVIDER_NAME);
443  }
444  else
445  {
446  m_wComboIndicatorImage.LoadImageFromSet(0, m_sComboIndicatorImageSet, "keybind_combo");
447  m_wComboIndicatorShadow.LoadImageFromSet(0, m_sComboIndicatorImageSetGlow, "keybind_combo");
448  }
449 
450  m_wComboIndicatorImage.SetSize(m_iHeightInPixel * COMBO_INDICATOR_SIZE_MULTIPLIER, m_iHeightInPixel * COMBO_INDICATOR_SIZE_MULTIPLIER);
451  m_wComboIndicatorShadow.SetSize(m_iHeightInPixel * COMBO_INDICATOR_SIZE_MULTIPLIER, m_iHeightInPixel * COMBO_INDICATOR_SIZE_MULTIPLIER);
452  }
453 
455  Widget comboWidget = GetGame().GetWorkspace().CreateWidgets(m_sInputButtonWidget, m_wHorizontalLayout);
456 
457  if (!comboWidget)
458  {
459  Print(string.Format("Unable to create Widget! %1 or %2 are null!", m_sInputButtonWidget, m_wHorizontalLayout), LogLevel.ERROR);
460  return;
461  }
462 
463  SCR_InputButtonDisplay component = SCR_InputButtonDisplay.Cast(comboWidget.FindHandler(SCR_InputButtonDisplay));
464 
465  if (!component)
466  {
467  Print(string.Format("%1 has no 'SCR_InputButtonDisplay' component attached!", component), LogLevel.ERROR);
468  return;
469  }
470 
471  component.Init(m_wRoot);
472  component.SetAction(keyData, filterStack[i]);
473 
474  m_aComboWidgets.Insert(comboIndicator);
475  m_aComboWidgets.Insert(comboWidget);
476  }
477  }
478 
479  //------------------------------------------------------------------------------------------------
481  protected void DeleteComboWidget()
482  {
483  if (m_aComboWidgets.IsEmpty())
484  return;
485 
486  foreach (Widget widget : m_aComboWidgets)
487  {
488  if (!widget)
489  continue;
490 
491  widget.RemoveFromHierarchy();
492  }
493 
494  m_aComboWidgets.Clear();
495  }
496 
497  //------------------------------------------------------------------------------------------------
499  protected void SetInputAction()
500  {
501  if (!m_sOldActionName.IsEmpty())
502  {
503  m_InputManager.RemoveActionListener(m_sOldActionName, EActionTrigger.DOWN, OnButtonPressed);
504  m_InputManager.RemoveActionListener(m_sOldActionName, EActionTrigger.VALUE, OnButtonHold);
505  m_InputManager.RemoveActionListener(m_sOldActionName, EActionTrigger.UP, ActionReleased);
506  }
507 
508  if (m_sActionName.IsEmpty())
509  return;
510 
511  if (m_bIsHoldAction)
512  m_InputManager.AddActionListener(m_sActionName, EActionTrigger.VALUE, OnButtonHold);
513 
514  if (m_bIsContinuous)
515  m_InputManager.AddActionListener(m_sActionName, EActionTrigger.UP, ActionReleased);
516 
517  m_InputManager.AddActionListener(m_sActionName, EActionTrigger.DOWN, OnButtonPressed);
518 
519  m_sOldActionName = m_sActionName;
520  }
521 
522  //------------------------------------------------------------------------------------------------
523  protected void OnButtonPressed(float value, EActionTrigger reason)
524  {
525  PlaySoundClicked();
526  OnInput();
527  }
528 
529  //------------------------------------------------------------------------------------------------
530  override bool OnMouseButtonDown(Widget w, int x, int y, int button)
531  {
532  if (button != 0 || !m_wRoot.IsVisible() || !m_wRoot.IsEnabled())
533  return false;
534 
535  if (m_bIsDoubleTapAction)
536  return false;
537 
538  m_bIsHoldingButton = true;
539 
540  OnInput();
541 
542  super.OnClick(w, x, y, button);
543 
544  return false;
545  }
546 
547  //------------------------------------------------------------------------------------------------
548  override bool OnDoubleClick(Widget w, int x, int y, int button)
549  {
550  if (m_bIsDoubleTapAction)
551  super.OnDoubleClick(w, x, y, button);
552 
553  return false;
554  }
555 
556  //------------------------------------------------------------------------------------------------
557  override bool OnMouseEnter(Widget w, int x, int y)
558  {
559  super.OnMouseEnter(w, x, y);
560 
561  m_bIsHovered = true;
562  if (m_OnAnimateHover)
563  m_OnAnimateHover.Invoke(this);
564 
565  return false;
566  }
567 
568  //------------------------------------------------------------------------------------------------
569  override bool OnMouseLeave(Widget w, Widget enterW, int x, int y)
570  {
571  super.OnMouseLeave(w, enterW, x, y);
572 
573  m_bIsHovered = false;
574 
575  if (m_OnAnimateHover)
576  m_OnAnimateHover.Invoke(this);
577 
578  return false;
579  }
580 
581  //------------------------------------------------------------------------------------------------
582  override void OnDisabled(bool animate)
583  {
584  if (m_OnUpdateEnableColor)
585  m_OnUpdateEnableColor.Invoke(this);
586  }
587 
588  //------------------------------------------------------------------------------------------------
589  override void OnEnabled(bool animate)
590  {
591  super.OnEnabled(animate);
592 
593  if (m_OnUpdateEnableColor)
594  m_OnUpdateEnableColor.Invoke(this);
595  }
596 
597  //------------------------------------------------------------------------------------------------
600  void OnButtonHold(float value)
601  {
602  if (!m_wRoot)
603  return;
604 
605  if (!m_wRoot.IsVisibleInHierarchy() || !m_wRoot.IsEnabledInHierarchy() && m_bCanBeDisabled)
606  return;
607 
608  // Bail if attached to menu but menu is not focused
609  if (!IsParentMenuFocused())
610  return;
611 
612  if (value == 0)
613  {
614  if (m_bIsHoldingButton && m_ButtonDisplay)
615  {
616  m_bIsHoldingButton = false;
617  ActionReleased();
618  }
619 
620  return;
621  }
622 
623  if (value < m_fDefaultClickTime)
624  return;
625 
626  if (!m_bIsHoldingButton)
627  {
628  m_bIsHoldingButton = true;
629  ActionPressed(true);
630  }
631  }
632 
633  //------------------------------------------------------------------------------------------------
634  void PlaySoundClicked()
635  {
636  if (m_bDisableClickSound)
637  return;
638 
639  PlaySound(m_sSoundClicked);
640  }
641 
642  //------------------------------------------------------------------------------------------------
644  protected void OnInput()
645  {
646  if (!m_wRoot)
647  return;
648 
649  if (!m_wRoot.IsVisibleInHierarchy() || !m_wRoot.IsEnabledInHierarchy() && m_bCanBeDisabled)
650  return;
651 
652  // Bail if attached to menu but menu is not focused
653  if (!IsParentMenuFocused())
654  return;
655 
656  //--- If a modal widget is active, check if the button is in its hierarchy
657  Widget modal = GetGame().GetWorkspace().GetModal();
658  if (modal && !SCR_WidgetTools.InHierarchy(m_wRoot, modal))
659  return;
660 
661  m_OnActivated.Invoke(this, m_sActionName);
662  if (m_bIsHoldAction)
663  return;
664 
665  ActionPressed();
666  }
667 
668  //------------------------------------------------------------------------------------------------
669  protected void ActionPressed(bool isHoldAction = false)
670  {
671  if (m_ButtonDisplay)
672  m_ButtonDisplay.ActionPressed(isHoldAction);
673 
674  foreach (Widget inputButton : m_aComboWidgets)
675  {
676  SCR_InputButtonDisplay component = SCR_InputButtonDisplay.Cast(inputButton.FindHandler(SCR_InputButtonDisplay));
677  if (!component)
678  continue;
679 
680  component.ActionPressed(isHoldAction);
681  }
682  }
683 
684  //------------------------------------------------------------------------------------------------
685  protected void ActionReleased()
686  {
687 
688  if (!m_bIsHoldAction && !m_bIsContinuous)
689  return;
690 
691  if (m_ButtonDisplay)
692  m_ButtonDisplay.ActionReleased();
693 
694  foreach (Widget inputButton : m_aComboWidgets)
695  {
696  SCR_InputButtonDisplay component = SCR_InputButtonDisplay.Cast(inputButton.FindHandler(SCR_InputButtonDisplay));
697  if (!component)
698  continue;
699 
700  component.ActionReleased();
701  }
702  }
703 
704  //------------------------------------------------------------------------------------------------
705  bool GetIsHoldingButton()
706  {
707  return m_bIsHoldingButton;
708  }
709 
710  //------------------------------------------------------------------------------------------------
711  void SetIsHoldingButton(bool isHolding)
712  {
713  m_bIsHoldingButton = isHolding;
714  }
715 
716  //------------------------------------------------------------------------------------------------
717  float GetAnimationRate()
718  {
719  return m_fAnimationRate;
720  }
721 
722  //------------------------------------------------------------------------------------------------
723  float GetAnimationTime()
724  {
725  return m_fAnimationTime;
726  }
727 
728  //------------------------------------------------------------------------------------------------
729  bool GetIsInputCombo()
730  {
731  return m_bIsComboInput;
732  }
733 
734  //------------------------------------------------------------------------------------------------
735  ScriptInvokerVoid GetOnAnimateHover()
736  {
737  if (!m_OnAnimateHover)
738  m_OnAnimateHover = new ScriptInvokerVoid();
739 
740  return m_OnAnimateHover;
741  }
742 
743  //------------------------------------------------------------------------------------------------
744  ScriptInvokerVoid GetOnUpdateEnableColor()
745  {
746  if (!m_OnUpdateEnableColor)
747  m_OnUpdateEnableColor = new ScriptInvokerVoid();
748 
749  return m_OnUpdateEnableColor;
750  }
751 
752  //------------------------------------------------------------------------------------------------
753  ScriptInvokerVoid GetOnHoldAnimComplete()
754  {
755  if (!m_OnHoldAnimComplete)
756  m_OnHoldAnimComplete = new ScriptInvokerVoid();
757 
758  return m_OnHoldAnimComplete;
759  }
760 
761  //------------------------------------------------------------------------------------------------
764  string ProcessKeybindStack(inout int index, notnull array<string> keyStack)
765  {
766  if (!keyStack.IsIndexValid(index))
767  return string.Empty;
768 
769  // pop back
770  string key = keyStack[index];
771  index--;
772 
773  switch (key)
774  {
775  case "+": // combo
776  {
777  m_aFilterStackIndexRemover.Insert(index + 1);
778  return ProcessKeybindStack(index, keyStack) + " + " + ProcessKeybindStack(index, keyStack);
779  }
780  case "|": // sum/alternative
781  {
782  m_aFilterStackIndexRemover.Insert(index + 1);
783  return ProcessKeybindStack(index, keyStack) + " | " + ProcessKeybindStack(index, keyStack);
784  }
785 
786  default: // key value
787  return key;
788  }
789 
790  return string.Empty;
791  }
792 
793  //------------------------------------------------------------------------------------------------
797  void ProcessFilterStack()
798  {
799  if (filterStack.IsEmpty())
800  return;
801 
802  foreach (int index : m_aFilterStackIndexRemover)
803  {
804  filterStack.RemoveOrdered(index);
805  }
806 
807  array<BaseContainer> filteredFilterStack = {};
808  int count = filterStack.Count() - 1;
809  for (int i = count; i >= 0; i--)
810  {
811  BaseContainer filterStackIndex = filterStack[i];
812  filteredFilterStack.Insert(filterStackIndex);
813 
814  if (!filterStackIndex)
815  continue;
816 
817  if (filterStackIndex.GetClassName() == "InputFilterHold" || filterStackIndex.GetClassName() == "InputFilterHoldOnce")
818  {
819  filterStackIndex.Get("HoldDuration", m_fMaxHoldtime);
820  if (m_fMaxHoldtime == -1 || m_fMaxHoldtime == 0)
821  m_fMaxHoldtime = m_fDefaultHoldTime;
822 
823  m_fMaxHoldtime /= 1000;
824  m_fMaxHoldtime -= m_fHoldTimeReduction;
825  if (m_fMaxHoldtime <= 0)
826  m_fMaxHoldtime += m_fHoldTimeReduction;
827 
828  m_bIsHoldAction = true;
829  }
830  }
831  filterStack.Clear();
832  filterStack = filteredFilterStack;
833  }
834 
836  //------------------------------------------------------------------------------------------------
838  void SetLabel(string label)
839  {
840  if (!m_wTextHint)
841  return;
842 
843  m_wTextHint.SetText(label);
844  m_wTextHint.SetVisible(true);
845  }
846 
847  //------------------------------------------------------------------------------------------------
849  void SetLabelColor(notnull Color color)
850  {
851  if (!m_wTextHint)
852  return;
853 
854  m_wTextHint.SetColor(color);
855  }
856 
857  //------------------------------------------------------------------------------------------------
860  void SetAction(string action)
861  {
862  if (m_sActionName == action)
863  return;
864 
865  m_sActionName = action;
866  ChangeInputDevice(m_InputManager.GetLastUsedInputDevice(), false);
867  }
868 
869  //------------------------------------------------------------------------------------------------
870  int GetSize()
871  {
872  return m_iHeightInPixel;
873  }
874 
875  //------------------------------------------------------------------------------------------------
878  void SetSize(int size)
879  {
880  m_iHeightInPixel = size;
881 
882  if (!m_bOverrideTextSize && m_wTextHint && m_ButtonDisplay)
883  {
884  int textSize = m_iHeightInPixel / m_ButtonDisplay.GetTextSizeModifier();
885  m_wTextHint.SetDesiredFontSize(textSize);
886  m_wTextHint.SetMinFontSize(textSize * MIN_FONTSIZE_MULTIPLIER);
887  }
888 
889  if (m_wComboIndicatorImage && m_wComboIndicatorShadow)
890  {
891  m_wComboIndicatorImage.SetSize(m_iHeightInPixel * COMBO_INDICATOR_SIZE_MULTIPLIER, m_iHeightInPixel * COMBO_INDICATOR_SIZE_MULTIPLIER);
892  m_wComboIndicatorShadow.SetSize(m_iHeightInPixel * COMBO_INDICATOR_SIZE_MULTIPLIER, m_iHeightInPixel * COMBO_INDICATOR_SIZE_MULTIPLIER);
893  }
894 
895  m_ButtonDisplay.Resize();
896  }
897 
898  //------------------------------------------------------------------------------------------------
899  bool IsClickSoundDisabled()
900  {
901  return m_bDisableClickSound;
902  }
903 
904  //------------------------------------------------------------------------------------------------
906  void SetClickSoundDisabled(bool isEnabled)
907  {
908  m_bDisableClickSound = isEnabled;
909  }
910 
911  //------------------------------------------------------------------------------------------------
916  void SetTexture(string imagePath, string image = string.Empty, Color color = Color.FromInt(Color.WHITE))
917  {
918  if (!m_ButtonDisplay)
919  return;
920 
921  DeleteComboWidget();
922  m_ButtonDisplay.OverrideTexture(imagePath, image, color);
923  }
924 
925  //------------------------------------------------------------------------------------------------
928  void ResetTexture()
929  {
930  if (!m_ButtonDisplay)
931  return;
932 
933  m_ButtonDisplay.SetIsOverwritten(false);
934 
935  ChangeInputDevice(m_InputManager.GetLastUsedInputDevice(), false, true);
936  }
937 
938  //------------------------------------------------------------------------------------------------
939  void SetColorActionDisabled(Color newColor)
940  {
941  m_ActionDisabled = newColor;
942  }
943 
944  //------------------------------------------------------------------------------------------------
945  static SCR_InputButtonComponent FindComponent(notnull Widget w)
946  {
947  return SCR_InputButtonComponent.Cast(w.FindHandler(SCR_InputButtonComponent));
948  }
949 
950  //------------------------------------------------------------------------------------------------
951  bool IsHovering()
952  {
953  return m_bIsHovered;
954  }
955 
956  //------------------------------------------------------------------------------------------------
957  protected void SetForceDisabled(bool forceDisabled, bool animate = true)
958  {
959  GetGame().GetCallqueue().Remove(SetForceDisabled); //Stop SetForceDisabledWithDelay
960 
961  m_bForceDisabled = forceDisabled;
962 
963  if (forceDisabled)
964  SetEnabled_Internal(false);
965  else
966  SetEnabled_Internal(m_bShouldBeEnabled);
967  }
968 
969  //------------------------------------------------------------------------------------------------
970  protected void SetForceDisabledWithDelay(bool forceDisabled, bool animate = true, int delay = 0)
971  {
972  m_bForceDisabled = forceDisabled;
973 
974  if (delay == 0)
975  {
976  SetForceDisabled(forceDisabled, animate);
977  return;
978  }
979 
980  GetGame().GetCallqueue().Remove(SetForceDisabled);
981  GetGame().GetCallqueue().CallLater(SetForceDisabled, delay, false, forceDisabled, animate);
982  }
983 
984  //Handling Input through SCR_MenuHelper, ei: edit and combo boxes call this to disable buttons during interaction
985  //------------------------------------------------------------------------------------------------
986  void OnActiveWidgetInteraction(bool isInteractionActive, int delay)
987  {
988  m_bIsInteractionActive = isInteractionActive;
989 
990  if (IsInTopMenu())
991  SetForceDisabledWithDelay(isInteractionActive, true, delay);
992  }
993 
994  //------------------------------------------------------------------------------------------------
995  void OnDialogOpen(DialogUI dialog)
996  {
997  m_aDialogs.Insert(dialog);
998 
999  SetForceDisabled(!IsInTopMenu() || m_bIsInteractionActive);
1000  }
1001 
1002  //------------------------------------------------------------------------------------------------
1003  void OnDialogClose(DialogUI dialog)
1004  {
1005  m_aDialogs.RemoveItem(dialog);
1006 
1007  SetForceDisabled(!IsInTopMenu() || m_bIsInteractionActive);
1008  }
1009 
1010  //------------------------------------------------------------------------------------------------
1011  protected void OnMenuFocusGained(ChimeraMenuBase menu)
1012  {
1013  if (menu == ChimeraMenuBase.GetOwnerMenu(m_wRoot))
1014  SetForceDisabled(false);
1015  }
1016 
1017  //------------------------------------------------------------------------------------------------
1018  protected void OnMenuFocusLost(ChimeraMenuBase menu)
1019  {
1020  if (menu == ChimeraMenuBase.GetOwnerMenu(m_wRoot))
1021  SetForceDisabled(true);
1022  }
1023 
1024  //------------------------------------------------------------------------------------------------
1026  bool IsInTopMenu()
1027  {
1028  return m_aDialogs.IsEmpty() || m_aDialogs[m_aDialogs.Count() - 1] == GetGame().GetMenuManager().GetOwnerMenu(GetRootWidget());
1029  }
1030 
1031  //------------------------------------------------------------------------------------------------
1033  bool IsInTopDialog()
1034  {
1035  return !m_aDialogs.IsEmpty() && m_aDialogs[m_aDialogs.Count() - 1] == GetGame().GetMenuManager().GetOwnerMenu(GetRootWidget());
1036  }
1037 
1038  //------------------------------------------------------------------------------------------------
1039  bool GetForceDisabled()
1040  {
1041  return m_bForceDisabled;
1042  }
1043 
1044  // Connection state related methods
1045  //------------------------------------------------------------------------------------------------
1046  // Updates the button based on the state of services
1047  static bool SetConnectionButtonEnabled(SCR_InputButtonComponent button, string serviceName, bool forceDisabled = false, bool animate = true)
1048  {
1049  if (!button)
1050  return false;
1051 
1052  bool serviceActive = SCR_ServicesStatusHelper.IsServiceActive(serviceName);
1053  bool enabled = serviceActive && !forceDisabled;
1054  button.SetEnabled(enabled, animate);
1055 
1056  if (forceDisabled && serviceActive)
1057  {
1058  button.ResetTexture();
1059  return true;
1060  }
1061 
1062  SetConnectionButtonTexture(button, enabled);
1063 
1064  return true;
1065  }
1066 
1067  //------------------------------------------------------------------------------------------------
1068  // Forces the button into the desired state irrelevant of services
1069  static bool ForceConnectionButtonEnabled(SCR_InputButtonComponent button, bool enabled, bool animate = true)
1070  {
1071  if (!button)
1072  return false;
1073 
1074  button.SetEnabled(enabled, animate);
1075  SetConnectionButtonTexture(button, enabled);
1076 
1077  return true;
1078  }
1079 
1080  //------------------------------------------------------------------------------------------------
1081  static void SetConnectionButtonTexture(SCR_InputButtonComponent button, bool enabled)
1082  {
1083  if (!button)
1084  return;
1085 
1086  if (enabled)
1087  {
1088  button.ResetTexture();
1089  return;
1090  }
1091 
1092  string icon = UIConstants.ICON_SERVICES_ISSUES;
1093  Color color = Color.FromInt(UIColors.WARNING_DISABLED.PackToInt());
1094 
1095  // No connection
1096  if (SCR_ServicesStatusHelper.GetLastReceivedCommStatus() == SCR_ECommStatus.FAILED)
1097  icon = UIConstants.ICON_DISCONNECTION;
1098 
1099  button.SetTexture(UIConstants.ICONS_IMAGE_SET, icon, color);
1100  }
1101 
1102  //------------------------------------------------------------------------------------------------
1105  static SCR_InputButtonComponent GetInputButtonComponent(string name, notnull Widget parent, bool searchAllChildren = true)
1106  {
1108  SCR_WLibComponentBase.GetComponent(SCR_InputButtonComponent, name, parent, searchAllChildren)
1109  );
1110  return comp;
1111  }
1112 }
ChimeraMenuBase
Constant variables used in various menus.
Definition: ChimeraMenuBase.c:70
SCR_ECommStatus
SCR_ECommStatus
This class may become obsolete on BackendAPI update.
Definition: SCR_ServicesStatusHelper.c:2
SCR_WidgetTools
Definition: SCR_WidgetTools.c:1
m_InputManager
protected InputManager m_InputManager
Definition: SCR_BaseManualCameraComponent.c:15
PlaySound
SCR_ParticleContactComponentClass ScriptComponentClass PlaySound(IEntity owner, SCR_ParticleContactComponentClass prefabData, Contact contact)
Definition: SCR_ParticleContactComponent.c:38
m_wRoot
protected Widget m_wRoot
Definition: SCR_ScenarioFrameworkLayerTaskDefend.c:59
SCR_WLibComponentBase
Base class for all final Reforger interactive elements.
Definition: SCR_WLibComponentBase.c:4
SCR_InputButtonDisplay
Definition: SCR_InputButtonDisplay.c:1
UIConstants
Definition: Constants.c:130
GetGame
ArmaReforgerScripted GetGame()
Definition: game.c:1424
m_bCanBeToggled
protected bool m_bCanBeToggled
Definition: SCR_ModularButtonComponent.c:41
m_sActionName
protected string m_sActionName
Definition: SCR_ActionsRadialMenuEditorComponent.c:24
desc
UI Textures DeployMenu Briefing conflict_HintBanner_1_UI desc
Definition: SCR_RespawnBriefingComponent.c:17
GetRootWidget
Widget GetRootWidget()
Definition: SCR_UITaskManagerComponent.c:160
Attribute
typedef Attribute
Post-process effect of scripted camera.
UIColors
Definition: Constants.c:16
IsEnabled
int IsEnabled()
Definition: SCR_BaseManualCameraComponent.c:99
DialogUI
Definition: DialogUI.c:1
SCR_ButtonBaseComponent
Base class for any button, regardless its own content.
Definition: SCR_ButtonBaseComponent.c:3
Contains
proto external sealed bool Contains(IEntity item)
m_bIsHovered
protected bool m_bIsHovered
Definition: SCR_CampaignMobileAssemblyStandaloneComponent.c:23
SCR_MenuHelper
Definition: SCR_MenuHelper.c:15
SCR_ServicesStatusHelper
Definition: SCR_ServicesStatusHelper.c:15
index
SCR_DestructionSynchronizationComponentClass ScriptComponentClass int index
Definition: SCR_DestructionSynchronizationComponent.c:17
ScriptInvokerVoid
ScriptInvokerBase< ScriptInvokerVoidMethod > ScriptInvokerVoid
Definition: SCR_ScriptInvokerHelper.c:9
data
Get all prefabs that have the spawner data
Definition: SCR_EntityCatalogManagerComponent.c:305
SCR_InputButtonComponent
Definition: SCR_InputButtonComponent.c:1