Arma Reforger Explorer  1.1.0.42
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
SCR_KeybindActionDisplayRowComponent.c
Go to the documentation of this file.
1 /*
2 Component that handles displaying multiple binds on a row.
3 Allows to choose the number of displayed binds and how to show hidden ones, either by a clickable icon or by a number
4 Also handles repositioning and scrolling longer binds
5 */
6 
8 {
9  [Attribute("{A06BEA3AE2B878B9}UI/layouts/Menus/SettingsMenu/BindingMenu/KeybindActionDisplay.layout")]
10  ResourceName m_sLayout;
11 
12  [Attribute("1", desc: "maximum allowed number of displays")]
13  int m_iMaxDisplays;
14 
15  [Attribute("1", UIWidgets.ComboBox, "Horizontal layout container fill origin", "", ParamEnumArray.FromEnum(HorizontalFillOrigin))]
16  HorizontalFillOrigin m_eRowFillOrigin;
17 
18  [Attribute("0")]
19  bool m_bShowAdditionalKeybindsNumber;
20 
21  [Attribute("#AR-ValueUnit_Short_Plus")]
22  string m_sAdditionalKeybindsMessage;
23 
24  protected int m_iBindsLastIndex;
25 
26  protected Widget m_wHorizontalScrollFrame;
27  protected HorizontalLayoutWidget m_wContainerWidget;
28  protected ref array<SCR_KeybindActionDisplayComponent> m_aDisplays = {};
29 
30  protected RichTextWidget m_wAdditionalBindsText;
31  protected Widget m_wAdditionalBindsOverlay;
32 
33  protected SCR_ModularButtonComponent m_AdditionalBindsButton;
34  protected SCR_HorizontalScrollAnimationComponent m_HorizontalScrollComponent;
35 
36  protected const string ROOT_NAME = "KeybindActionDisplayRow";
37 
38  protected ref ScriptInvokerVoid m_OnAdditionalBindsClicked;
39 
40  //------------------------------------------------------------------------------------------------
41  override void HandlerAttached(Widget w)
42  {
43  super.HandlerAttached(w);
44 
45  m_wContainerWidget = HorizontalLayoutWidget.Cast(m_wRoot.FindAnyWidget("ActionDisplaysHorizontalLayout"));
46  if (m_wContainerWidget)
47  m_wContainerWidget.SetFillOrigin(m_eRowFillOrigin);
48 
49  m_wHorizontalScrollFrame = m_wRoot.FindAnyWidget("HorizontalScrollFrame");
50  if (m_wHorizontalScrollFrame)
51  m_HorizontalScrollComponent = SCR_HorizontalScrollAnimationComponent.FindComponent(m_wHorizontalScrollFrame);
52 
53  m_wAdditionalBindsText = RichTextWidget.Cast(m_wRoot.FindAnyWidget("AdditionalBinds"));
54  m_wAdditionalBindsOverlay = m_wRoot.FindAnyWidget("AdditionalBindsOverlay");
55 
56  Widget root = w.FindAnyWidget("AdditionalBindsButton");
57  if (root)
58  m_AdditionalBindsButton = SCR_ModularButtonComponent.FindComponent(root);
59 
60  if (m_AdditionalBindsButton)
61  m_AdditionalBindsButton.m_OnClicked.Insert(OnAdditionalBindsButtonClicked);
62 
63  ResetScrolling();
64 
65  // Init for editor work
66  if (!GetGame().InPlayMode())
67  CreateActionDisplays(null, null, EInputDeviceType.KEYBOARD);
68  }
69 
70  //------------------------------------------------------------------------------------------------
71  protected void ResetScrolling()
72  {
73  if (!m_wContainerWidget || !m_HorizontalScrollComponent)
74  return;
75 
76  m_HorizontalScrollComponent.AnimationStop();
77  m_HorizontalScrollComponent.ResetPosition();
78 
79  FrameSlot.SetAnchorMin(m_wContainerWidget, GetAlignment(), GetAlignment());
80  FrameSlot.SetAnchorMax(m_wContainerWidget, GetAlignment(), GetAlignment());
81  FrameSlot.SetAlignment(m_wContainerWidget, GetAlignment(), GetAlignment());
82 
83  LayoutSlot.SetPadding(m_wHorizontalScrollFrame, 0, 0, 0, 0);
84  }
85 
86  //------------------------------------------------------------------------------------------------
87  protected float GetAlignment()
88  {
89  switch (m_eRowFillOrigin)
90  {
91  case HorizontalFillOrigin.LEFT: return 0;
92  case HorizontalFillOrigin.CENTER: return 0.5;
93  case HorizontalFillOrigin.RIGHT: return 1;
94  }
95 
96  return 0;
97  }
98 
99  // TODO: there seems to be an execution order issue with widget resizing, so we need to wait two frames. Ask for fix
100  //------------------------------------------------------------------------------------------------
101  protected void UpdateScrollFrameSkip()
102  {
103  GetGame().GetCallqueue().Call(UpdateScrolling, true);
104  }
105 
106  //------------------------------------------------------------------------------------------------
107  protected void OnAdditionalBindsButtonClicked(SCR_ModularButtonComponent comp)
108  {
109  if (m_OnAdditionalBindsClicked)
110  m_OnAdditionalBindsClicked.Invoke();
111  }
112 
113  // --- Public ---
114  //------------------------------------------------------------------------------------------------
115  void UpdateScrolling(bool enable)
116  {
117  if (!m_wHorizontalScrollFrame || !m_wContainerWidget || !m_HorizontalScrollComponent || !m_wAdditionalBindsOverlay)
118  return;
119 
120  ResetScrolling();
121 
122  float frameX, frameY, textX, textY, additionalBindsX, additionalBindsY;
123  m_wHorizontalScrollFrame.GetScreenSize(frameX, frameY);
124  m_wContainerWidget.GetScreenSize(textX, textY);
125  m_wAdditionalBindsOverlay.GetScreenSize(additionalBindsX, additionalBindsY);
126 
127  vector alignment = FrameSlot.GetAlignment(m_wContainerWidget);
128 
129  bool move = enable && textX > frameX - additionalBindsX;
130 
131  // Adjust frame padding to avoid overlapping the Additional binds text
132  if ((move || m_eRowFillOrigin == HorizontalFillOrigin.RIGHT) && m_iBindsLastIndex + 1 > m_iMaxDisplays)
133  LayoutSlot.SetPadding(m_wHorizontalScrollFrame, 0, 0, additionalBindsX, 0);
134 
135  // Animation
136  if (move)
137  {
138  FrameSlot.SetAnchorMin(m_wContainerWidget, 0, GetAlignment());
139  FrameSlot.SetAnchorMax(m_wContainerWidget, 0, GetAlignment());
140  FrameSlot.SetAlignment(m_wContainerWidget, 0, GetAlignment());
141 
142  m_HorizontalScrollComponent.AnimationStart();
143  }
144  }
145 
146  //------------------------------------------------------------------------------------------------
147  void CreateActionDisplays(SCR_KeyBindingEntry entry, SCR_SettingsManagerKeybindModule settingsKeybindModule, EInputDeviceType device)
148  {
149  if (!m_wContainerWidget)
150  return;
151 
152  // Clear old displays
153  foreach (SCR_KeybindActionDisplayComponent display : m_aDisplays)
154  {
155  display.GetRootWidget().RemoveFromHierarchy();
156  }
157 
158  m_aDisplays.Clear();
159 
160  // Find number of available bindings
161  int lastIndex = m_iMaxDisplays - 1;
162  m_iBindsLastIndex = 0;
163 
164  if (entry && settingsKeybindModule)
165  {
166  string finalPreset;
167  string preset = entry.m_sPreset;;
168 
169  if (device == EInputDeviceType.GAMEPAD)
170  {
171  if (!entry.m_sPresetGamepadOptional.IsEmpty())
172  preset = entry.m_sPresetGamepadOptional;
173  else
174  preset = entry.m_sPreset;
175 
176  if (!preset.IsEmpty())
177  finalPreset = settingsKeybindModule.GetGamepadPresetPrefix() + preset;
178  }
179 
180  else if (device == EInputDeviceType.KEYBOARD && !preset.IsEmpty())
181  {
182  finalPreset = settingsKeybindModule.GetPrimaryPresetPrefix() + preset;
183  }
184 
185  m_iBindsLastIndex = settingsKeybindModule.GetActionBindCount(entry.m_sActionName, finalPreset, device) - 1;
186 
187  if (m_iBindsLastIndex < lastIndex)
188  lastIndex = m_iBindsLastIndex;
189  }
190 
191  // Make sure at least 1 display is created
192  lastIndex = Math.Clamp(lastIndex, 0, m_iMaxDisplays - 1);
193 
194  // Create displays
195  int index;
196  for (index = 0; index <= lastIndex; index++)
197  {
198  Widget w = GetGame().GetWorkspace().CreateWidgets(m_sLayout, m_wContainerWidget);
199  if (!w)
200  continue;
201 
203  if (!comp)
204  continue;
205 
206  m_aDisplays.Insert(comp);
207  }
208 
209  // Fill displays based on row alignment
210  index = 0;
212  foreach (SCR_KeybindActionDisplayComponent comp : m_aDisplays)
213  {
214  if (m_eRowFillOrigin != HorizontalFillOrigin.RIGHT)
215  data = new SCR_KeybindActionDisplayData(entry, settingsKeybindModule, device, SCR_EActionDisplayState.DEFAULT, index, lastIndex);
216  else
217  data = new SCR_KeybindActionDisplayData(entry, settingsKeybindModule, device, SCR_EActionDisplayState.DEFAULT, lastIndex - index, lastIndex);
218 
219  comp.UpdateActionDisplay(data);
220 
221  index ++;
222  }
223 
224  // Update Additional binds text
225  int remaining = m_iBindsLastIndex - lastIndex;
226  bool show = remaining > 0;
227 
228  if (m_wAdditionalBindsOverlay)
229  m_wAdditionalBindsOverlay.SetVisible(show);
230 
231  if (m_wAdditionalBindsText)
232  {
233  m_wAdditionalBindsText.SetVisible(show && m_bShowAdditionalKeybindsNumber);
234  m_wAdditionalBindsText.SetTextFormat(m_sAdditionalKeybindsMessage, remaining);
235  }
236 
237  if (m_AdditionalBindsButton)
238  m_AdditionalBindsButton.SetVisible(show && !m_bShowAdditionalKeybindsNumber);
239 
240  // Check for scrolling
241  GetGame().GetCallqueue().Call(UpdateScrollFrameSkip);
242  }
243 
244  //------------------------------------------------------------------------------------------------
245  void SetAllActionDisplayStates(SCR_EActionDisplayState state)
246  {
248  foreach (SCR_KeybindActionDisplayComponent comp : m_aDisplays)
249  {
250  data = comp.GetActionDisplayData();
251  if (!data)
252  continue;
253 
254  data.m_eState = state;
255 
256  comp.UpdateActionDisplay(data);
257  }
258  }
259 
260  //------------------------------------------------------------------------------------------------
261  ScriptInvokerVoid GetOnAdditionalBindsClicked()
262  {
263  if (!m_OnAdditionalBindsClicked)
264  m_OnAdditionalBindsClicked = new ScriptInvokerVoid();
265 
266  return m_OnAdditionalBindsClicked;
267  }
268 
269  //------------------------------------------------------------------------------------------------
270  static SCR_KeybindActionDisplayRowComponent FindComponent(notnull Widget w)
271  {
273  }
274 
275  //------------------------------------------------------------------------------------------------
276  static SCR_KeybindActionDisplayRowComponent FindComponentInHierarchy(notnull Widget w)
277  {
278  Widget actionRoot = w.FindAnyWidget(ROOT_NAME);
279  if (!actionRoot)
280  return null;
281 
282  return SCR_KeybindActionDisplayRowComponent.FindComponent(actionRoot);
283  }
284 }
SCR_HorizontalScrollAnimationComponent
Definition: SCR_HorizontalScrollAnimationComponent.c:14
m_wRoot
protected Widget m_wRoot
Definition: SCR_ScenarioFrameworkLayerTaskDefend.c:59
SCR_KeybindActionDisplayComponent
Definition: SCR_KeybindActionDisplayComponent.c:6
GetGame
ArmaReforgerScripted GetGame()
Definition: game.c:1424
SCR_SettingsManagerKeybindModule
Definition: SCR_SettingsManagerKeybindModule.c:2
desc
UI Textures DeployMenu Briefing conflict_HintBanner_1_UI desc
Definition: SCR_RespawnBriefingComponent.c:17
Attribute
typedef Attribute
Post-process effect of scripted camera.
m_sLayout
SCR_GMMenuEntry m_sLayout
SCR_KeybindActionDisplayRowComponent
Definition: SCR_KeybindActionDisplayRowComponent.c:7
index
SCR_DestructionSynchronizationComponentClass ScriptComponentClass int index
Definition: SCR_DestructionSynchronizationComponent.c:17
ScriptInvokerVoid
ScriptInvokerBase< ScriptInvokerVoidMethod > ScriptInvokerVoid
Definition: SCR_ScriptInvokerHelper.c:9
SCR_KeybindActionDisplayData
void SCR_KeybindActionDisplayData(SCR_KeyBindingEntry entry, SCR_SettingsManagerKeybindModule settingsKeybindModule, EInputDeviceType device, SCR_EActionDisplayState state, int index=0, int lastIndex=0)
Definition: SCR_KeybindActionDisplayComponent.c:113
data
Get all prefabs that have the spawner data
Definition: SCR_EntityCatalogManagerComponent.c:305
SCR_ScriptedWidgetComponent
Definition: SCR_ScriptedWidgetComponent.c:7