Arma Reforger Explorer  1.1.0.42
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
SCR_EditBoxComponent.c
Go to the documentation of this file.
1 // Component handling interaction with text input fields (edit boxes)
2 
3 // TODO:
4 // During interaction with edit boxes on pc, write mode does not disable itself if the dialog/menu is overlayed by another.
5 // This hasn't been a problem so far as there has never been an instance of a dialog/menu opening while an edit box interaction is allowed, but let's keep it in mind nonetheless
6 
7 //------------------------------------------------------------------------------------------------
9 {
10  [Attribute("0.1")]
11  protected float m_fColorsAnimationTime;
12 
13  [Attribute("0")]
14  protected bool m_bShowWriteIcon;
15 
16  [Attribute("1")]
17  protected bool m_bShowInvalidInputWarning;
18 
19  [Attribute(UIConstants.ICONS_IMAGE_SET, UIWidgets.ResourcePickerThumbnail, "Image resource for icons")]
20  protected ResourceName m_sIconImageSet;
21 
22  [Attribute("")]
23  protected string m_sIconImageName;
24 
25  [Attribute("WriteIconButton")]
26  protected string m_sWriteIconButtonName;
27 
28  [Attribute("0.1", "0 1")]
29  protected float m_fOpacityDefault;
30 
31  [Attribute("0.4", "0 1")]
32  protected float m_fOpacityFocused;
33 
34  [Attribute("0.022995 0.022995 0.022995 1.000000", UIWidgets.ColorPicker)]
35  protected ref Color m_BackgroundDefault;
36 
37  [Attribute("0.108995 0.108995 0.108995 1.000000", UIWidgets.ColorPicker)]
38  protected ref Color m_BackgroundInteracting;
39 
40  [Attribute("0.022995 0.022995 0.022995 1.000000", UIWidgets.ColorPicker)]
41  protected ref Color m_BackgroundFocused;
42 
43  [Attribute("", UIWidgets.EditBox, "Text that should appear next to error warning on invalid input")]
44  protected string m_sWarningText;
45 
46  Widget m_wEditBox;
47  Widget m_wColorOverlay;
48  Widget m_wEditBackground;
49  Widget m_wWarningIcon;
50  Widget m_wHorizontalLayout;
51 
52  Widget m_wWriteIconScale;
53  ImageWidget m_wImgWriteIcon;
54 
55  protected SCR_ModularButtonComponent m_WriteIconButton;
56 
57  protected SCR_WidgetHintComponent m_Hint;
58 
59  protected bool m_bValidInput = true;
60  protected bool m_bIsTyping;
61  protected ref Color COLOR_INVALID_INPUT = UIColors.WARNING;
62  protected ref Color COLOR_VALID_INPUT = Color.White;
63 
64  // Arguments passed: SCR_EditBoxComponent, string (text)
65  ref ScriptInvoker m_OnConfirm = new ScriptInvoker();
66  ref ScriptInvoker m_OnFocusChangedEditBox = new ScriptInvoker();
67 
68  protected MultilineEditBoxWidget m_wMultilineEditBoxWidget;
69  protected EditBoxWidget m_wEditBoxWidget;
70  protected SCR_EventHandlerComponent m_EVHComponent;
71 
72  protected const int INTERACTION_STATE_UPDATE_FREQUENCY = 50;
73  protected const int FOCUS_LOST_INTERACTION_STATE_UPDATE_DELAY = 1000 / UIConstants.FADE_RATE_DEFAULT;
74 
75  protected bool m_bIsFocused;
76  protected bool m_bIsInWriteMode;
77  protected bool m_bIsInWriteModePrevious;
78  protected ref Color m_BackgroundCurrent;
79 
80  // TODO: protect these
81  ref ScriptInvokerVoid m_OnWriteModeEnter = new ScriptInvokerVoid();
82  ref ScriptInvokerString m_OnWriteModeLeave = new ScriptInvokerString();
83  ref ScriptInvokerString m_OnTextChange = new ScriptInvokerString();
84 
85  protected string m_sTextPrevious;
86 
87  //------------------------------------------------------------------------------------------------
88  override void HandlerAttached(Widget w)
89  {
90  super.HandlerAttached(w);
91  m_wColorOverlay = w.FindAnyWidget("OverlayPanel");
92 
93  m_wEditBox = w.FindAnyWidget("EditBox");
94  m_wWarningIcon = w.FindAnyWidget("ErrorIcon");
95  m_wEditBackground = w.FindAnyWidget("EditBackground");
96  m_wHorizontalLayout = w.FindAnyWidget("HorizontalLayout");
97 
98  m_wWriteIconScale = w.FindAnyWidget("WriteIconScale");
99  m_wImgWriteIcon = ImageWidget.Cast(w.FindAnyWidget("WriteIcon"));
100 
101  m_Hint = SCR_WidgetHintComponent.Cast(SCR_WidgetTools.FindHandlerOnWidget(w, "Hint", SCR_WidgetHintComponent));
102 
103  // Setup warning
104  if (GetGame().InPlayMode() && m_wWarningIcon)
105  {
106  if (m_bUseLabel)
107  m_wWarningIcon.SetOpacity(0);
108  else
109  m_wWarningIcon.SetOpacity(0); // Without label, warning icon not shown at all
110  }
111 
112  if (m_Hint)
113  {
114  m_Hint.SetMessage(m_sWarningText);
115  m_Hint.SetVisible(0);
116  }
117 
118  // Setup for label-less edit boxes
119  m_wBackground.SetVisible(m_bUseLabel);
120 
121  // Convert to transition rate
122  if (m_fColorsAnimationTime <= 0)
123  m_fColorsAnimationTime = 1000;
124  else
125  m_fColorsAnimationTime = 1 / m_fColorsAnimationTime;
126 
127  if (!m_wEditBox)
128  return;
129 
130  EditBoxFilterComponent filter = EditBoxFilterComponent.Cast(m_wEditBox.FindHandler(EditBoxFilterComponent));
131  if (filter)
132  {
133  if (m_bShowInvalidInputWarning)
134  {
135  filter.m_OnInvalidInput.Insert(OnInvalidInput);
136  filter.m_OnTextTooLong.Insert(OnInvalidInput);
137  }
138 
139  filter.m_OnValidInput.Insert(OnValueChanged);
140  }
141 
142  m_EVHComponent = SCR_EventHandlerComponent.Cast(m_wEditBox.FindHandler(SCR_EventHandlerComponent));
143  if (m_EVHComponent)
144  {
145  m_EVHComponent.GetOnFocus().Insert(OnHandlerFocus);
146  m_EVHComponent.GetOnFocusLost().Insert(OnHandlerFocusLost);
147  m_EVHComponent.GetOnChangeFinal().Insert(OnConfirm);
148  }
149 
150  if (m_wEditBackground)
151  {
152  m_wEditBackground.SetOpacity(m_fOpacityDefault);
153  m_wEditBackground.SetColor(m_BackgroundDefault);
154  m_BackgroundCurrent = m_BackgroundDefault;
155  }
156 
157  // Image
158  if (m_wImgWriteIcon && m_wWriteIconScale)
159  {
160  bool hasResource = !m_sIconImageSet.IsEmpty() && !m_sIconImageName.IsEmpty();
161  m_wWriteIconScale.SetVisible(hasResource);
162 
163  if (hasResource)
164  m_wImgWriteIcon.LoadImageFromSet(0, m_sIconImageSet, m_sIconImageName);
165 
166  ShowWriteIcon(m_bShowWriteIcon && hasResource);
167  }
168 
169  // Write Icon button
170  Widget iconButton = m_wRoot.FindAnyWidget(m_sWriteIconButtonName);
171  if (iconButton)
172  m_WriteIconButton = SCR_ModularButtonComponent.FindComponent(iconButton);
173 
174  if (m_WriteIconButton)
175  m_WriteIconButton.m_OnClicked.Insert(OnInternalButtonClicked);
176 
177  //Type of edit box. Why aren't these derived from a common parent :(
178  m_wMultilineEditBoxWidget = MultilineEditBoxWidget.Cast(m_wEditBox);
179  m_wEditBoxWidget = EditBoxWidget.Cast(m_wEditBox);
180 
181  if (m_wMultilineEditBoxWidget)
182  m_bIsInWriteMode = m_wMultilineEditBoxWidget.IsInWriteMode();
183  else if (m_wEditBoxWidget)
184  m_bIsInWriteMode = m_wEditBoxWidget.IsInWriteMode();
185 
186  m_bIsInWriteModePrevious = m_bIsInWriteMode;
187 
188  m_sTextPrevious = GetEditBoxText();
189  }
190 
191  //------------------------------------------------------------------------------------------------
192  override void HandlerDeattached(Widget w)
193  {
194  super.HandlerDeattached(w);
195 
196  ClearInteractionState();
197  }
198 
199  //------------------------------------------------------------------------------------------------
200  override bool OnFocus(Widget w, int x, int y)
201  {
202  // Set focus to handler - super.OnFocus will be called only after the handler is focused!
203  GetGame().GetWorkspace().SetFocusedWidget(m_wEditBox);
204  m_bIsTyping = true;
205 
206  return true;
207  }
208 
209  //------------------------------------------------------------------------------------------------
210  void OnValueChanged()
211  {
212  if (m_Hint)
213  m_Hint.SetVisible(false);
214 
215  m_OnChanged.Invoke(this, GetEditBoxText());
216 
217  if (m_bValidInput)
218  return;
219 
220  AnimateWidget.Opacity(m_wWarningIcon, 0, m_fColorsAnimationTime, true);
221 
222  AnimateWidget.Color(m_wColorOverlay, COLOR_VALID_INPUT, m_fColorsAnimationTime);
223  m_bValidInput = true;
224 
225  }
226 
227  //------------------------------------------------------------------------------------------------
228  void OnHandlerFocus()
229  {
230  // Call focus event on parent class
231  super.OnFocus(m_wRoot, 0, 0);
232 
233  m_bIsTyping = true;
234  m_bIsFocused = true;
235 
236  // Make the widget unfocusable
237  m_wRoot.SetFlags(WidgetFlags.NOFOCUS);
238  m_OnFocusChangedEditBox.Invoke(this, m_wEditBox, true);
239 
240  UpdateBackgroundColor();
241 
242  //Update interaction state timer, because there are no delegates for write start and end :(
243  if(m_wMultilineEditBoxWidget || m_wEditBoxWidget)
244  GetGame().GetCallqueue().CallLater(UpdateInteractionState, INTERACTION_STATE_UPDATE_FREQUENCY, true, false);
245  }
246 
247  //------------------------------------------------------------------------------------------------
248  void OnHandlerFocusLost()
249  {
250  // Call focusLost event on parent class
251  super.OnFocusLost(m_wRoot, 0, 0);
252 
253  m_bIsTyping = false;
254  m_bIsFocused = false;
255 
256  // Make focusable again
257  if (m_wRoot)
258  m_wRoot.ClearFlags(WidgetFlags.NOFOCUS);
259 
260  m_OnFocusChangedEditBox.Invoke(this, m_wEditBox, false);
261 
262  ClearInteractionState();
263  }
264 
265  //------------------------------------------------------------------------------------------------
266  void OnInvalidInput()
267  {
268  // Show simple icon next to text when no message
269  if (!m_Hint || m_Hint && m_Hint.GetMessage().IsEmpty())
270  AnimateWidget.Opacity(m_wWarningIcon, 1, m_fColorsAnimationTime, true);
271  else if (m_Hint && !m_Hint.GetMessage().IsEmpty())
272  m_Hint.SetVisible(true);
273 
274  AnimateWidget.Color(m_wColorOverlay, COLOR_INVALID_INPUT, m_fColorsAnimationTime);
275  m_bValidInput = false;
276  }
277 
278  //------------------------------------------------------------------------------------------------
279  void ClearInvalidInput()
280  {
281  AnimateWidget.Opacity(m_wWarningIcon, 0, m_fColorsAnimationTime, true);
282  if (m_Hint)
283  m_Hint.SetVisible(false);
284 
285  AnimateWidget.Color(m_wColorOverlay, COLOR_VALID_INPUT, m_fColorsAnimationTime);
286  m_bValidInput = false;
287  }
288 
289  //------------------------------------------------------------------------------------------------
290  void ChangeOverlayColor(Color color)
291  {
292  m_wColorOverlay.SetColor(color);
293  }
294 
295  //------------------------------------------------------------------------------------------------
296  void ResetOverlayColor()
297  {
298  AnimateWidget.Color(m_wColorOverlay, COLOR_VALID_INPUT, m_fColorsAnimationTime);
299  }
300 
301  //------------------------------------------------------------------------------------------------
302  protected void OnConfirm(Widget w)
303  {
304  if (m_bIsTyping)
305  m_OnConfirm.Invoke(this, GetValue()); //TODO: this does not get called on gamepad!?
306  }
307 
308  //------------------------------------------------------------------------------------------------
309  protected void OnInternalButtonClicked()
310  {
311  ActivateWriteMode(true);
312  }
313 
314  //------------------------------------------------------------------------------------------------
315  protected string GetEditBoxText()
316  {
317  if (!m_wEditBox)
318  return string.Empty;
319 
320  EditBoxWidget editBox = EditBoxWidget.Cast(m_wEditBox);
321  if (editBox)
322  return editBox.GetText();
323 
324  MultilineEditBoxWidget editMulti = MultilineEditBoxWidget.Cast(m_wEditBox);
325  if (editMulti)
326  return editMulti.GetText();
327 
328  return string.Empty;
329  }
330 
331  //------------------------------------------------------------------------------------------------
332  protected void SetEditBoxText(string text)
333  {
334  if (!m_wEditBox)
335  return;
336 
337  EditBoxWidget editBox = EditBoxWidget.Cast(m_wEditBox);
338  if (editBox)
339  {
340  editBox.SetText(text);
341  return;
342  }
343 
344  MultilineEditBoxWidget editMulti = MultilineEditBoxWidget.Cast(m_wEditBox);
345  if (editMulti)
346  editMulti.SetText(text);
347  }
348 
349  //------------------------------------------------------------------------------------------------
350  protected string GetPlaceholderText()
351  {
352  EditBoxWidget editBox = EditBoxWidget.Cast(m_wEditBox);
353  if (editBox)
354  return editBox.GetPlaceholderText();
355  return string.Empty;
356  }
357 
358  //------------------------------------------------------------------------------------------------
359  void SetPlaceholderText(string str)
360  {
361  EditBoxWidget editBox = EditBoxWidget.Cast(m_wEditBox);
362  if (editBox)
363  editBox.SetPlaceholderText(str);
364  }
365 
366  //------------------------------------------------------------------------------------------------
369  static SCR_EditBoxComponent GetEditBoxComponent(string name, Widget parent, bool searchAllChildren = true)
370  {
371  if (!parent || name == string.Empty)
372  return null;
373 
374  Widget w;
375  if (searchAllChildren)
376  w = parent.FindAnyWidget(name);
377  else
378  w = parent.FindWidget(name);
379 
380  if (!w)
381  return null;
382 
384  return comp;
385  }
386 
387  //------------------------------------------------------------------------------------------------
389  void ActivateWriteMode(bool refocus = false)
390  {
391  if (refocus)
392  {
393  Widget target = m_wMultilineEditBoxWidget;
394  if (!m_wMultilineEditBoxWidget)
395  target = m_wEditBoxWidget;
396 
397  GetGame().GetWorkspace().SetFocusedWidget(target);
398  }
399 
400  if (m_wMultilineEditBoxWidget)
401  m_wMultilineEditBoxWidget.ActivateWriteMode();
402 
403 
404  if (m_wEditBoxWidget)
405  m_wEditBoxWidget.ActivateWriteMode();
406  }
407 
408  //------------------------------------------------------------------------------------------------
409  void ShowHint(bool show)
410  {
411  if (m_Hint)
412  m_Hint.SetVisible(show);
413  }
414 
415  //------------------------------------------------------------------------------------------------
416  void ShowWriteIcon(bool show)
417  {
418  if (m_wWriteIconScale)
419  m_wWriteIconScale.SetVisible(show);
420  }
421 
422  //------------------------------------------------------------------------------------------------
423  void UpdateInteractionState(bool forceDisabled)
424  {
425  int interactionStateUpdateDelay;
426  if (forceDisabled)
427  {
428  m_bIsInWriteMode = false;
429  interactionStateUpdateDelay = FOCUS_LOST_INTERACTION_STATE_UPDATE_DELAY;
430  }
431  else
432  {
433  //These don't come from a common parent :(
434  if (m_wMultilineEditBoxWidget)
435  m_bIsInWriteMode = m_wMultilineEditBoxWidget.IsInWriteMode();
436 
437  else if (m_wEditBoxWidget)
438  m_bIsInWriteMode = m_wEditBoxWidget.IsInWriteMode();
439  }
440 
441  if (m_bIsInWriteMode != m_bIsInWriteModePrevious || forceDisabled)
442  {
443  SCR_MenuHelper.SetActiveWidgetInteractionState(m_bIsInWriteMode, interactionStateUpdateDelay);
444 
445  UpdateBackgroundColor();
446 
447  if(m_bIsInWriteMode)
448  m_OnWriteModeEnter.Invoke();
449  else
450  m_OnWriteModeLeave.Invoke(GetEditBoxText());
451  }
452 
453  m_bIsInWriteModePrevious = m_bIsInWriteMode;
454 
455  if (GetEditBoxText() != m_sTextPrevious || forceDisabled)
456  {
457  m_sTextPrevious = GetEditBoxText();
458  m_OnTextChange.Invoke(m_sTextPrevious);
459  }
460  }
461 
462  //------------------------------------------------------------------------------------------------
463  void ClearInteractionState()
464  {
465  GetGame().GetCallqueue().Remove(UpdateInteractionState);
466  UpdateInteractionState(true);
467  }
468 
469  //------------------------------------------------------------------------------------------------
470  protected void UpdateBackgroundColor()
471  {
472  if (!m_wEditBackground)
473  return;
474 
475  Color idleColor = m_BackgroundDefault;
476  if (m_bIsFocused)
477  idleColor = m_BackgroundFocused;
478 
479  if(m_bIsInWriteMode)
480  m_BackgroundCurrent = m_BackgroundInteracting;
481  else
482  m_BackgroundCurrent = idleColor;
483 
484  AnimateWidget.Color(m_wEditBackground, m_BackgroundCurrent, m_fAnimationRate);
485  }
486 
487  //------------------------------------------------------------------------------------------------
489  void SetValue(string value) { SetEditBoxText(value); }
490  string GetValue() { return GetEditBoxText(); }
491  string GetPlaceHolderText() { return GetPlaceholderText(); }
492  Widget GetEditBoxWidget() { return m_wEditBox; }
493  bool IsValidInput() { return m_bValidInput; }
494  SCR_WidgetHintComponent GetHint() { return m_Hint; }
495  bool IsInWriteMode() { return m_bIsInWriteMode; }
496 
497  //------------------------------------------------------------------------------------------------
498  SCR_EventHandlerComponent GetEVHComponent()
499  {
500  return m_EVHComponent;
501  }
502 
503  //------------------------------------------------------------------------------------------------
505  void ConfirmValue(string value)
506  {
507  SetEditBoxText(value);
508  OnConfirm(m_wRoot);
509  }
510 
511 };
SCR_ChangeableComponentBase
Base class for all widgets that can change their internal state as editbox or spinbox.
Definition: SCR_ChangeableComponentBase.c:4
SCR_WidgetTools
Definition: SCR_WidgetTools.c:1
m_wRoot
protected Widget m_wRoot
Definition: SCR_ScenarioFrameworkLayerTaskDefend.c:59
UIConstants
Definition: Constants.c:130
GetGame
ArmaReforgerScripted GetGame()
Definition: game.c:1424
SCR_WidgetHintComponent
Definition: SCR_WidgetHintComponent.c:6
m_OnChanged
protected ref ScriptInvokerTabViewIndex m_OnChanged
Definition: SCR_TabViewComponent.c:64
Attribute
typedef Attribute
Post-process effect of scripted camera.
UIColors
Definition: Constants.c:16
SCR_EventHandlerComponent
Definition: SCR_EventHandlerComponent.c:5
ScriptInvokerString
ScriptInvokerBase< ScriptInvokerStringMethod > ScriptInvokerString
Definition: SCR_ScriptInvokerHelper.c:75
SCR_MenuHelper
Definition: SCR_MenuHelper.c:15
m_wBackground
protected ImageWidget m_wBackground
Definition: SCR_InventoryHitZonePointUI.c:382
ScriptInvokerVoid
ScriptInvokerBase< ScriptInvokerVoidMethod > ScriptInvokerVoid
Definition: SCR_ScriptInvokerHelper.c:9
SCR_EditBoxComponent
Definition: SCR_EditBoxComponent.c:8
EditBoxFilterComponent
Definition: EditBoxFilterComponent.c:5