3 [
Attribute(
"MenuTabLeft",
desc:
"Name of action from chimeraInputCommon")]
4 protected string m_sActionName;
7 protected string m_sLabel;
10 protected bool m_bIsMouseInput;
12 [
Attribute(defvalue:
"32",
desc:
"Define the Height in PX. Wight will be adjusted automatically")]
16 ref Color m_ActionDefault;
19 ref Color m_ActionHovered;
22 ref Color m_ActionDisabled;
25 ref Color m_LabelDefault;
27 [
Attribute(
"0.597421 0.061189 0.475868 1.000000", UIWidgets.ColorPicker)]
28 ref Color m_ActionToggled;
30 [
Attribute(
"0",
desc:
"If enabled there will be no sound played when the button is pressed")]
31 protected bool m_bDisableClickSound;
33 [
Attribute(
"0",
desc:
"Postion offset when button is not held")]
34 float m_fHoldIndicatorDefaultPosition;
37 float m_fHoldIndicatorHoldPosition;
39 [
Attribute(
"0.1",
desc:
"Time in sec who long the animation takes.")]
40 float m_fHoldIndicatorAnimationTime;
42 [
Attribute(
"1",
desc:
"If false the button will never change to its disabled visual state.")]
43 bool m_bCanBeDisabled;
45 [
Attribute(
"1",
desc:
"If false the Label does not change its color to disabled when button is disabled.")]
46 bool m_bChangeLabelColorOnDisabled;
49 protected string m_sButtonWidgetName;
52 protected string m_sHorizontalLayoutWidget;
55 protected string m_sTextHintWidget;
57 [
Attribute(
"{B7C8B633428B153D}UI/layouts/WidgetLibrary/Buttons/WLib_InputButtonDisplay.layout")]
58 protected ResourceName m_sInputButtonWidget;
60 [
Attribute(
"{983DFCCEB578C1C5}UI/layouts/InputButtons/InputButton_ComboIndicator.layout")]
61 protected ResourceName m_sComboIndicatorWidget;
63 [
Attribute(
"{3262679C50EF4F01}UI/Textures/Icons/icons_wrapperUI.imageset")]
64 protected ResourceName m_sComboIndicatorImageSet;
66 [
Attribute(
"{00FE3DBDFD15227B}UI/Textures/Icons/icons_wrapperUI-glow.imageset")]
67 protected ResourceName m_sComboIndicatorImageSetGlow;
69 [
Attribute(
desc:
"If enabled Text size is controlled by set size Inside the RichText widget")]
70 protected bool m_bOverrideTextSize;
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;
76 protected bool m_bDebugSimulateController;
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";
82 protected const float COMBO_INDICATOR_SIZE_MULTIPLIER = 0.5;
83 protected const float MIN_FONTSIZE_MULTIPLIER = 0.5;
86 protected Widget m_wHorizontalLayout;
87 protected ImageWidget m_wComboIndicatorImage;
88 protected ImageWidget m_wComboIndicatorShadow;
89 protected RichTextWidget m_wTextHint;
91 protected ref array<Widget> m_aComboWidgets = {};
92 protected ref array<BaseContainer> filterStack = {};
93 protected ref array<int> m_aFilterStackIndexRemover = {};
95 InputManager m_InputManager =
GetGame().GetInputManager();
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;
104 protected bool m_bForceDisabled;
105 protected bool m_bShouldBeEnabled;
106 protected bool m_bIsInteractionActive;
108 protected string m_sOldActionName;
110 protected bool m_bIsHoldingButton;
112 bool m_bIsDoubleTapStated;
114 protected float m_fDefaultHoldTime;
115 protected float m_fDefaultClickTime;
116 float m_fMaxHoldtime;
118 int m_iDoubleTapThreshold;
120 protected EInputDeviceType m_eCurrentInputDevice;
126 ref ScriptInvoker m_OnActivated =
new ScriptInvoker();
127 protected ref array<DialogUI> m_aDialogs;
130 override void HandlerAttached(Widget w)
132 super.HandlerAttached(w);
134 m_wHorizontalLayout = HorizontalLayoutWidget.Cast(w.FindAnyWidget(m_sHorizontalLayoutWidget));
135 m_wTextHint = RichTextWidget.Cast(w.FindAnyWidget(m_sTextHintWidget));
137 Widget buttonWidget = Widget.Cast(w.FindAnyWidget(m_sButtonWidgetName));
142 if (!m_ButtonDisplay)
146 GameProject.GetModuleConfig(
"InputManagerSettings").Get(
"HoldDuration", m_fDefaultHoldTime);
147 GameProject.GetModuleConfig(
"InputManagerSettings").Get(
"ClickDuration", m_fDefaultClickTime);
148 if (m_fDefaultClickTime)
150 m_fDefaultClickTime /= 1000;
151 m_fHoldTimeReduction += m_fDefaultClickTime;
157 m_wTextHint.SetVisible(
false);
159 m_wTextHint.SetText(m_sLabel);
160 m_wTextHint.SetColor(m_LabelDefault);
165 m_aDialogs =
new array<DialogUI>;
167 SCR_MenuHelper.GetOnActiveWidgetInteraction().Insert(OnActiveWidgetInteraction);
178 ChangeInputDevice(
m_InputManager.GetLastUsedInputDevice(),
false);
180 GetGame().OnInputDeviceIsGamepadInvoker().Insert(OnInputDeviceUserChanged);
182 if (m_bDebugSimulateController)
183 OnInputDeviceUserChanged(
true);
187 override void HandlerDeattached(Widget w)
193 GetGame().OnInputDeviceIsGamepadInvoker().Remove(OnInputDeviceUserChanged);
197 SCR_MenuHelper.GetOnActiveWidgetInteraction().Remove(OnActiveWidgetInteraction);
206 override bool OnClick(Widget w,
int x,
int y,
int button)
211 override void SetEnabled(
bool enabled,
bool animate =
true)
213 m_bShouldBeEnabled = enabled;
214 SetEnabled_Internal(enabled, animate);
218 protected void SetEnabled_Internal(
bool enabled,
bool animate =
true)
220 if (!m_bForceDisabled)
237 protected void OnInputDeviceUserChanged(
bool isGamepad)
240 ChangeInputDevice(EInputDeviceType.GAMEPAD,
false);
242 ChangeInputDevice(EInputDeviceType.KEYBOARD,
false);
247 protected void ChangeInputDevice(EInputDeviceType inputDevice,
bool hasFocus,
bool resetOverride =
false)
249 if (inputDevice == m_eCurrentInputDevice &&
m_sActionName == m_sOldActionName && !resetOverride)
252 if (inputDevice == EInputDeviceType.MOUSE && hasFocus && m_bIsMouseInput)
254 m_eCurrentInputDevice = inputDevice;
258 if (inputDevice == EInputDeviceType.GAMEPAD)
259 m_eCurrentInputDevice = inputDevice;
261 m_eCurrentInputDevice = EInputDeviceType.KEYBOARD;
266 if (inputDevice == EInputDeviceType.INVALID)
269 array<string> keyStack = {};
273 m_aFilterStackIndexRemover.Clear();
274 int index = keyStack.Count() - 1;
275 string keyCode = ProcessKeybindStack(
index, keyStack);
278 TStringArray m_aKeyCodeString =
new TStringArray;
279 if (keyCode.Contains(
" + "))
281 keyCode.Split(
" + ", m_aKeyCodeString,
true);
282 m_bIsComboInput =
true;
284 keyCode = m_aKeyCodeString[0];
286 else if (keyCode.Contains(
" | "))
288 keyCode.Split(
" | ", m_aKeyCodeString,
true);
290 if (m_aKeyCodeString[0].
Contains(
"keyboard:") && m_aKeyCodeString[1].
Contains(
"mouse:"))
291 m_bIsAlternativeInput =
false;
293 m_bIsAlternativeInput =
true;
295 keyCode = m_aKeyCodeString[0];
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);
309 GetInputFilterSettings(filterStack[0]);
312 ProcessFilterStack();
315 m_ButtonDisplay.SetAction(
data, filterStack[0]);
317 if (!m_bOverrideTextSize && m_wTextHint && m_ButtonDisplay)
319 int textSize = m_iHeightInPixel / m_ButtonDisplay.GetTextSizeModifier();
320 m_wTextHint.SetDesiredFontSize(textSize);
321 m_wTextHint.SetMinFontSize(textSize * MIN_FONTSIZE_MULTIPLIER);
325 if (m_bIsComboInput || m_bIsAlternativeInput)
326 CreateComboWidget(m_aKeyCodeString);
334 protected bool GetInputFilterSettings(BaseContainer filter)
336 m_bIsHoldAction =
false;
337 m_bIsDoubleTapAction =
false;
338 m_bPressedInput =
false;
340 m_bIsContinuous =
false;
345 switch (filter.GetClassName())
347 case "InputFilterHold":
349 filter.Get(
"HoldDuration", m_fMaxHoldtime);
350 if (m_fMaxHoldtime == -1 || m_fMaxHoldtime == 0)
351 m_fMaxHoldtime = m_fDefaultHoldTime;
353 m_fMaxHoldtime /= 1000;
354 m_fMaxHoldtime -= m_fHoldTimeReduction;
355 if (m_fMaxHoldtime <= 0)
356 m_fMaxHoldtime += m_fHoldTimeReduction;
358 m_bIsHoldAction =
true;
361 case "InputFilterHoldOnce":
363 filter.Get(
"HoldDuration", m_fMaxHoldtime);
364 if (m_fMaxHoldtime == -1 || m_fMaxHoldtime == 0)
365 m_fMaxHoldtime = m_fDefaultHoldTime;
367 m_fMaxHoldtime /= 1000;
368 m_fMaxHoldtime -= m_fHoldTimeReduction;
369 if (m_fMaxHoldtime <= 0)
370 m_fMaxHoldtime += m_fHoldTimeReduction;
372 m_bIsHoldAction =
true;
375 case "InputFilterDoubleClick":
377 m_bIsDoubleTapAction =
true;
378 filter.Get(
"Threshold", m_iDoubleTapThreshold);
379 if (m_iDoubleTapThreshold == -1)
380 GameProject.GetModuleConfig(
"InputManagerSettings").Get(
"DoubleClickDuration", m_iDoubleTapThreshold);
382 m_iDoubleTapThreshold /= 1000;
385 case "InputFilterPressed":
387 m_bPressedInput =
true;
390 case "InputFilterToggle":
395 case "InputFilterValue":
397 m_bIsContinuous =
true;
408 protected void CreateComboWidget(TStringArray keyCodes)
410 if (m_ButtonDisplay.GetIsOverwritten())
413 for (
int i = 1, count = keyCodes.Count(); i < count; i++)
418 BaseContainer keyData =
m_InputManager.GetKeyUIMapping(keyCodes[i]).GetObject(
"Data");
421 Print(
string.Format(
"No data found for %1 !! Check 'chimeraMapping.conf' and add data if necessary!", keyCodes[i]), LogLevel.ERROR);
426 Widget comboIndicator =
GetGame().GetWorkspace().CreateWidgets(m_sComboIndicatorWidget, m_wHorizontalLayout);
430 Print(
string.Format(
"Unable to create Widget! %1 or %2 are null!", m_sComboIndicatorWidget, m_wHorizontalLayout), LogLevel.ERROR);
434 m_wComboIndicatorImage = ImageWidget.Cast(comboIndicator.FindAnyWidget(COMBO_INDICATOR_IMAGE_NAME));
435 m_wComboIndicatorShadow = ImageWidget.Cast(comboIndicator.FindAnyWidget(COMBO_INDICATOR_SHADOW_NAME));
437 if (m_wComboIndicatorImage && m_wComboIndicatorShadow)
439 if (m_bIsAlternativeInput)
441 m_wComboIndicatorImage.LoadImageFromSet(0, m_sComboIndicatorImageSet, COMBO_INDICATOR_DIVIDER_NAME);
442 m_wComboIndicatorShadow.LoadImageFromSet(0, m_sComboIndicatorImageSetGlow, COMBO_INDICATOR_DIVIDER_NAME);
446 m_wComboIndicatorImage.LoadImageFromSet(0, m_sComboIndicatorImageSet,
"keybind_combo");
447 m_wComboIndicatorShadow.LoadImageFromSet(0, m_sComboIndicatorImageSetGlow,
"keybind_combo");
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);
455 Widget comboWidget =
GetGame().GetWorkspace().CreateWidgets(m_sInputButtonWidget, m_wHorizontalLayout);
459 Print(
string.Format(
"Unable to create Widget! %1 or %2 are null!", m_sInputButtonWidget, m_wHorizontalLayout), LogLevel.ERROR);
467 Print(
string.Format(
"%1 has no 'SCR_InputButtonDisplay' component attached!", component), LogLevel.ERROR);
472 component.SetAction(keyData, filterStack[i]);
474 m_aComboWidgets.Insert(comboIndicator);
475 m_aComboWidgets.Insert(comboWidget);
481 protected void DeleteComboWidget()
483 if (m_aComboWidgets.IsEmpty())
486 foreach (Widget widget : m_aComboWidgets)
491 widget.RemoveFromHierarchy();
494 m_aComboWidgets.Clear();
499 protected void SetInputAction()
501 if (!m_sOldActionName.IsEmpty())
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);
523 protected void OnButtonPressed(
float value, EActionTrigger reason)
530 override bool OnMouseButtonDown(Widget w,
int x,
int y,
int button)
535 if (m_bIsDoubleTapAction)
538 m_bIsHoldingButton =
true;
542 super.OnClick(w, x, y, button);
548 override bool OnDoubleClick(Widget w,
int x,
int y,
int button)
550 if (m_bIsDoubleTapAction)
551 super.OnDoubleClick(w, x, y, button);
557 override bool OnMouseEnter(Widget w,
int x,
int y)
559 super.OnMouseEnter(w, x, y);
562 if (m_OnAnimateHover)
563 m_OnAnimateHover.Invoke(
this);
569 override bool OnMouseLeave(Widget w, Widget enterW,
int x,
int y)
571 super.OnMouseLeave(w, enterW, x, y);
575 if (m_OnAnimateHover)
576 m_OnAnimateHover.Invoke(
this);
582 override void OnDisabled(
bool animate)
584 if (m_OnUpdateEnableColor)
585 m_OnUpdateEnableColor.Invoke(
this);
589 override void OnEnabled(
bool animate)
591 super.OnEnabled(animate);
593 if (m_OnUpdateEnableColor)
594 m_OnUpdateEnableColor.Invoke(
this);
600 void OnButtonHold(
float value)
605 if (!
m_wRoot.IsVisibleInHierarchy() || !
m_wRoot.IsEnabledInHierarchy() && m_bCanBeDisabled)
609 if (!IsParentMenuFocused())
614 if (m_bIsHoldingButton && m_ButtonDisplay)
616 m_bIsHoldingButton =
false;
623 if (value < m_fDefaultClickTime)
626 if (!m_bIsHoldingButton)
628 m_bIsHoldingButton =
true;
634 void PlaySoundClicked()
636 if (m_bDisableClickSound)
644 protected void OnInput()
649 if (!
m_wRoot.IsVisibleInHierarchy() || !
m_wRoot.IsEnabledInHierarchy() && m_bCanBeDisabled)
653 if (!IsParentMenuFocused())
657 Widget modal =
GetGame().GetWorkspace().GetModal();
669 protected void ActionPressed(
bool isHoldAction =
false)
672 m_ButtonDisplay.ActionPressed(isHoldAction);
674 foreach (Widget inputButton : m_aComboWidgets)
680 component.ActionPressed(isHoldAction);
685 protected void ActionReleased()
688 if (!m_bIsHoldAction && !m_bIsContinuous)
692 m_ButtonDisplay.ActionReleased();
694 foreach (Widget inputButton : m_aComboWidgets)
700 component.ActionReleased();
705 bool GetIsHoldingButton()
707 return m_bIsHoldingButton;
711 void SetIsHoldingButton(
bool isHolding)
713 m_bIsHoldingButton = isHolding;
717 float GetAnimationRate()
719 return m_fAnimationRate;
723 float GetAnimationTime()
725 return m_fAnimationTime;
729 bool GetIsInputCombo()
731 return m_bIsComboInput;
737 if (!m_OnAnimateHover)
740 return m_OnAnimateHover;
746 if (!m_OnUpdateEnableColor)
749 return m_OnUpdateEnableColor;
755 if (!m_OnHoldAnimComplete)
758 return m_OnHoldAnimComplete;
764 string ProcessKeybindStack(inout
int index, notnull array<string> keyStack)
766 if (!keyStack.IsIndexValid(
index))
770 string key = keyStack[
index];
777 m_aFilterStackIndexRemover.Insert(
index + 1);
778 return ProcessKeybindStack(
index, keyStack) +
" + " + ProcessKeybindStack(
index, keyStack);
782 m_aFilterStackIndexRemover.Insert(
index + 1);
783 return ProcessKeybindStack(
index, keyStack) +
" | " + ProcessKeybindStack(
index, keyStack);
797 void ProcessFilterStack()
799 if (filterStack.IsEmpty())
802 foreach (
int index : m_aFilterStackIndexRemover)
804 filterStack.RemoveOrdered(
index);
807 array<BaseContainer> filteredFilterStack = {};
808 int count = filterStack.Count() - 1;
809 for (
int i = count; i >= 0; i--)
811 BaseContainer filterStackIndex = filterStack[i];
812 filteredFilterStack.Insert(filterStackIndex);
814 if (!filterStackIndex)
817 if (filterStackIndex.GetClassName() ==
"InputFilterHold" || filterStackIndex.GetClassName() ==
"InputFilterHoldOnce")
819 filterStackIndex.Get(
"HoldDuration", m_fMaxHoldtime);
820 if (m_fMaxHoldtime == -1 || m_fMaxHoldtime == 0)
821 m_fMaxHoldtime = m_fDefaultHoldTime;
823 m_fMaxHoldtime /= 1000;
824 m_fMaxHoldtime -= m_fHoldTimeReduction;
825 if (m_fMaxHoldtime <= 0)
826 m_fMaxHoldtime += m_fHoldTimeReduction;
828 m_bIsHoldAction =
true;
832 filterStack = filteredFilterStack;
838 void SetLabel(
string label)
843 m_wTextHint.SetText(label);
844 m_wTextHint.SetVisible(
true);
849 void SetLabelColor(notnull Color color)
854 m_wTextHint.SetColor(color);
860 void SetAction(
string action)
866 ChangeInputDevice(
m_InputManager.GetLastUsedInputDevice(),
false);
872 return m_iHeightInPixel;
878 void SetSize(
int size)
880 m_iHeightInPixel = size;
882 if (!m_bOverrideTextSize && m_wTextHint && m_ButtonDisplay)
884 int textSize = m_iHeightInPixel / m_ButtonDisplay.GetTextSizeModifier();
885 m_wTextHint.SetDesiredFontSize(textSize);
886 m_wTextHint.SetMinFontSize(textSize * MIN_FONTSIZE_MULTIPLIER);
889 if (m_wComboIndicatorImage && m_wComboIndicatorShadow)
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);
895 m_ButtonDisplay.Resize();
899 bool IsClickSoundDisabled()
901 return m_bDisableClickSound;
906 void SetClickSoundDisabled(
bool isEnabled)
908 m_bDisableClickSound = isEnabled;
916 void SetTexture(
string imagePath,
string image =
string.Empty, Color color = Color.FromInt(Color.WHITE))
918 if (!m_ButtonDisplay)
922 m_ButtonDisplay.OverrideTexture(imagePath, image, color);
930 if (!m_ButtonDisplay)
933 m_ButtonDisplay.SetIsOverwritten(
false);
935 ChangeInputDevice(
m_InputManager.GetLastUsedInputDevice(),
false,
true);
939 void SetColorActionDisabled(Color newColor)
941 m_ActionDisabled = newColor;
957 protected void SetForceDisabled(
bool forceDisabled,
bool animate =
true)
959 GetGame().GetCallqueue().Remove(SetForceDisabled);
961 m_bForceDisabled = forceDisabled;
964 SetEnabled_Internal(
false);
966 SetEnabled_Internal(m_bShouldBeEnabled);
970 protected void SetForceDisabledWithDelay(
bool forceDisabled,
bool animate =
true,
int delay = 0)
972 m_bForceDisabled = forceDisabled;
976 SetForceDisabled(forceDisabled, animate);
980 GetGame().GetCallqueue().Remove(SetForceDisabled);
981 GetGame().GetCallqueue().CallLater(SetForceDisabled, delay,
false, forceDisabled, animate);
986 void OnActiveWidgetInteraction(
bool isInteractionActive,
int delay)
988 m_bIsInteractionActive = isInteractionActive;
991 SetForceDisabledWithDelay(isInteractionActive,
true, delay);
997 m_aDialogs.Insert(dialog);
999 SetForceDisabled(!IsInTopMenu() || m_bIsInteractionActive);
1003 void OnDialogClose(
DialogUI dialog)
1005 m_aDialogs.RemoveItem(dialog);
1007 SetForceDisabled(!IsInTopMenu() || m_bIsInteractionActive);
1014 SetForceDisabled(
false);
1021 SetForceDisabled(
true);
1028 return m_aDialogs.IsEmpty() || m_aDialogs[m_aDialogs.Count() - 1] ==
GetGame().GetMenuManager().GetOwnerMenu(
GetRootWidget());
1033 bool IsInTopDialog()
1035 return !m_aDialogs.IsEmpty() && m_aDialogs[m_aDialogs.Count() - 1] ==
GetGame().GetMenuManager().GetOwnerMenu(
GetRootWidget());
1039 bool GetForceDisabled()
1041 return m_bForceDisabled;
1047 static bool SetConnectionButtonEnabled(
SCR_InputButtonComponent button,
string serviceName,
bool forceDisabled =
false,
bool animate =
true)
1053 bool enabled = serviceActive && !forceDisabled;
1054 button.SetEnabled(enabled, animate);
1056 if (forceDisabled && serviceActive)
1058 button.ResetTexture();
1062 SetConnectionButtonTexture(button, enabled);
1074 button.SetEnabled(enabled, animate);
1075 SetConnectionButtonTexture(button, enabled);
1088 button.ResetTexture();
1093 Color color = Color.FromInt(
UIColors.WARNING_DISABLED.PackToInt());
1099 button.SetTexture(
UIConstants.ICONS_IMAGE_SET, icon, color);
1105 static SCR_InputButtonComponent GetInputButtonComponent(
string name, notnull Widget parent,
bool searchAllChildren =
true)