Arma Reforger Explorer 1.7.0.54
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
Loading...
Searching...
No Matches
SCR_ComboBoxComponent.c
Go to the documentation of this file.
2{
3 [Attribute("-1", UIWidgets.EditBox, "Maximum size of the list without using scrollbar. -1 for no limit")]
4 float m_fMaxListHeight;
5
6 [Attribute("true", UIWidgets.CheckBox, "Create the list below or above or below the root widget")]
7 bool m_bCreateListBelow;
8
9 [Attribute("{B8C4345E3A833B05}UI/layouts/WidgetLibrary/ComboBox/WLib_OpenedComboRoot.layout", UIWidgets.ResourceNamePicker, "Combo box element", "layout")]
10 ResourceName m_sListRootLayout;
11
12 [Attribute("{323CF37F81DF9B8A}UI/layouts/Common/Settings/ComboBox/ARComboBoxElement.layout", UIWidgets.ResourceNamePicker, "Combo box element", "layout")]
13 ResourceName m_sElementLayout;
14
15 [Attribute("0", UIWidgets.EditBox, "Gap between combo root and combo box items")]
16 float m_fItemsGap;
17
18 [Attribute("0", UIWidgets.EditBox, "Extra pixels to the left from the center of the widget")]
19 float m_fExtraPaddingLeft;
20
21 [Attribute("0", UIWidgets.EditBox, "Extra pixels to the right from the center of the widget")]
22 float m_fExtraPaddingRight;
23
24 [Attribute("0", UIWidgets.EditBox, "Starting angle of arrow icon to coordinate texture rotation")]
25 protected float m_fArrowDefaultAngle;
26
27 [Attribute("0", UIWidgets.CheckBox, "Allow manual drop down list width enforcing")]
28 protected bool m_bForceListWidth;
29
30 [Attribute("200", UIWidgets.EditBox, "How wide should drop down list be")]
31 protected float m_fListForcedWidth;
32
33 [Attribute("0", UIWidgets.EditBox, "How wide should drop down list be")]
34 protected float m_fListXOffset;
35
36 [Attribute(SCR_SoundEvent.FOCUS, UIWidgets.EditBox, "")]
37 protected string m_sSoundClosed;
38
39 [Attribute("OverlayArrow")]
40 protected string m_sButton;
41
42 [Attribute(UIColors.GetColorAttribute(UIColors.EDIT_WIDGET_BACKGROUND), UIWidgets.ColorPicker)]
44
45 [Attribute(UIColors.GetColorAttribute(UIColors.IDLE_DISABLED), UIWidgets.ColorPicker)]
47
48 [Attribute(UIColors.GetColorAttribute(UIColors.NEUTRAL_ACTIVE_STANDBY), UIWidgets.ColorPicker)]
49 protected ref Color m_ArrowDefault;
50
51 [Attribute(UIColors.GetColorAttribute(UIColors.CONTRAST_COLOR), UIWidgets.ColorPicker)]
53
54 [Attribute(UIColors.GetColorAttribute(UIColors.HIGHLIGHTED), UIWidgets.ColorPicker)]
55 protected ref Color m_ArrowFocused;
56
57 [Attribute("0", desc: "Should the arrow flip when the Combo box is opened")]
58 protected bool m_bRotateArrow;
59
61 protected ref array<Widget> m_aElementWidgets = new array<Widget>();
62 protected Widget m_wButton;
71 protected bool m_bOpened;
72
73 // Script invokers sends
76
77 protected float posX, posY;
78
80
81 protected const int INITIALIZATION_CHECK_FREQUENCY = 10;
82
83 //------------------------------------------------------------------------------------------------
84 override void HandlerAttached(Widget w)
85 {
86 super.HandlerAttached(w);
87 m_InputManager = GetGame().GetInputManager();
88 m_Workspace = GetGame().GetWorkspace();
89 m_wText = TextWidget.Cast(w.FindAnyWidget("Content"));
90 m_wContentRoot = w.FindAnyWidget("ComboButton");
92 {
94 if (comp)
95 {
96 comp.GetOnClick().Insert(OpenList);
97 comp.GetOnMouseEnter().Insert(OnHandlerHovered);
99 comp.GetOnFocus().Insert(OnHandlerFocus);
100 comp.GetOnFocusLost().Insert(OnHandlerFocusLost);
101 }
102 }
103
104 // Find arrow button
105 m_wButton = w.FindAnyWidget(m_sButton);
106
107 m_wArrowImage = ImageWidget.Cast(w.FindAnyWidget("ImageArrow"));
108 if (m_wArrowImage)
109 {
112 }
113
114 UpdateName();
115
116 Widget overlayText = w.FindAnyWidget("OverlayText");
117 if(overlayText)
118 m_wTextBackground = overlayText.FindAnyWidget("Background");
119
122
123 if (GetGame().InPlayMode())
125 }
126
127 //------------------------------------------------------------------------------------------------
128 override void HandlerDeattached(Widget w)
129 {
130 super.HandlerDeattached(w);
131 CloseList();
132
134 }
135
136 //------------------------------------------------------------------------------------------------
137 protected bool OnHandlerClicked()
138 {
139 OpenList();
140 if (GetGame().GetWorkspace().GetFocusedWidget() != m_wRoot)
141 GetGame().GetWorkspace().SetFocusedWidget(m_wRoot);
142
143 return true;
144 }
145
146 //------------------------------------------------------------------------------------------------
147 override bool OnFocus(Widget w, int x, int y)
148 {
149 // Prevent regular focus, handled by OnHandlerFocus
150 if (m_wContentRoot)
151 GetGame().GetWorkspace().SetFocusedWidget(m_wContentRoot);
152
153 return false;
154 }
155
156 //------------------------------------------------------------------------------------------------
157 override bool OnFocusLost(Widget w, int x, int y)
158 {
159 // Prevent regular focus, handled by OnHandlerFocusLost
160 return false;
161 }
162
163 //------------------------------------------------------------------------------------------------
164 protected void OnHandlerFocus()
165 {
166 // Call focus event on parent class
167 super.OnFocus(m_wRoot, 0, 0);
168
169 // Make the widget unfocusable
170 m_wRoot.SetFlags(WidgetFlags.NOFOCUS);
171 }
172
173 //------------------------------------------------------------------------------------------------
174 protected void OnHandlerFocusLost()
175 {
176 // Call focusLost event on parent class
177 super.OnFocusLost(m_wRoot, 0, 0);
178
179 // Make focusable again
180 m_wRoot.ClearFlags(WidgetFlags.NOFOCUS);
181 }
182
183 //------------------------------------------------------------------------------------------------
189
190 //------------------------------------------------------------------------------------------------
191 protected void OnHandlerUnhovered()
192 {
193 if (m_wArrowImage)
194 {
195 Color color = m_ArrowDefault;
196
197 if (m_bOpened)
198 color = m_ArrowInteracting;
199
201 }
202 }
203
204 //------------------------------------------------------------------------------------------------
205 protected void OnMenuFocusLost(ChimeraMenuBase menu)
206 {
208 CloseList();
209 }
210
211 //------------------------------------------------------------------------------------------------
212 override protected void OnEnabled(bool animate)
213 {
214 super.OnEnabled(animate);
215
216 if (m_wButton)
217 m_wButton.SetVisible(true);
218 }
219
220 //------------------------------------------------------------------------------------------------
221 override protected void OnDisabled(bool animate)
222 {
223 super.OnDisabled(animate);
224
225 if (m_wButton)
226 m_wButton.SetVisible(false);
227 }
228
229 //------------------------------------------------------------------------------------------------
230 protected void UpdateName()
231 {
232 if (!m_wText)
233 return;
234
235 if (m_aElementNames && m_iSelectedItem > -1 && m_iSelectedItem < m_aElementNames.Count())
236 m_wText.SetText(m_aElementNames[m_iSelectedItem]);
237 else
238 m_wText.SetText(string.Empty);
239 }
240
241 //------------------------------------------------------------------------------------------------
242 override bool SetCurrentItem(int i, bool playSound = false, bool animate = false)
243 {
244 bool result = super.SetCurrentItem(i, playSound, animate);
245 UpdateName();
246 if (m_bOpened)
248
249 return result;
250 }
251
252 //------------------------------------------------------------------------------------------------
254 {
256 return;
257
258 foreach (Widget w : m_aElementWidgets)
259 {
260 w.RemoveFromHierarchy();
261 }
262 m_aElementWidgets.Clear();
263
264 foreach (int i, string name : m_aElementNames)
265 {
266 Widget w = GetGame().GetWorkspace().CreateWidgets(m_sElementLayout, m_wContent);
267 if (!w)
268 continue;
269
270 if (!m_wElementsRoot.IsVisible())
271 m_wElementsRoot.SetVisible(true);
272
273 m_aElementWidgets.Insert(w);
274 OnCreateElement(w, i);
275
277 if (comp)
278 {
279 if (i == m_iSelectedItem)
280 {
281 GetGame().GetWorkspace().SetFocusedWidget(comp.GetRootWidget());
282 comp.SetToggled(true, false, false);
283 }
284
285 comp.SetText(m_aElementNames[i]);
286 comp.m_OnClicked.Insert(OnElementSelected);
287 }
288 }
289
290 // Set focus on the first one or current index
291 // TODO: fix "Given widget is already modal, not adding again" message
293 GetGame().GetWorkspace().AddModal(m_wElementsRoot, m_aElementWidgets[m_iSelectedItem]);
294 else if (m_aElementWidgets.Count() > 0 && m_aElementWidgets[0])
295 GetGame().GetWorkspace().AddModal(m_wElementsRoot, m_aElementWidgets[0]);
296
297 // Check until all elements have been initialized, to perform post init setups
298 GetGame().GetCallqueue().Remove(CheckElementsInitialized);
299 GetGame().GetCallqueue().CallLater(CheckElementsInitialized, INITIALIZATION_CHECK_FREQUENCY, true);
300 }
301
302 //------------------------------------------------------------------------------------------------
304 {
305 if (!m_bOpened || m_aElementWidgets.IsEmpty())
306 {
307 GetGame().GetCallqueue().Remove(CheckElementsInitialized);
308 return;
309 }
310
311 int initializedItems;
312 float totalItems = m_aElementWidgets.Count();
313
314 foreach (Widget element : m_aElementWidgets)
315 {
316 float x, y;
317 element.GetScreenSize(x, y);
318
319 if (x > 0 && y > 0)
320 initializedItems++;
321 }
322
323 if (initializedItems != totalItems)
324 return;
325
326 // Set slider position to selected element
327 if (m_wScrollLayout)
328 m_wScrollLayout.SetSliderPos(0, m_iSelectedItem / totalItems);
329
330 GetGame().GetCallqueue().Remove(CheckElementsInitialized);
331 }
332
333 //------------------------------------------------------------------------------------------------
334 void OpenList()
335 {
336 if (m_bOpened || !m_aElementNames || /*m_aElementNames.IsEmpty() ||*/ !m_wContentRoot)
337 return;
338
339 m_bOpened = true;
340
342
345
346 // Add escape handling
347 m_InputManager.ResetAction(UIConstants.MENU_ACTION_SELECT);
348 m_InputManager.AddActionListener(UIConstants.MENU_ACTION_BACK, EActionTrigger.DOWN, OnMenuBack);
349#ifdef WORKBENCH
350 m_InputManager.AddActionListener(UIConstants.MENU_ACTION_BACK_WB, EActionTrigger.DOWN, OnMenuBack);
351#endif
352
353 float x, y, w, h;
354 m_wContentRoot.GetScreenPos(x, y);
355 m_wContentRoot.GetScreenSize(w, h);
356
357 // Unscale all layout-based positions
358 x = m_Workspace.DPIUnscale(x);
359 y = m_Workspace.DPIUnscale(y);
360 w = m_Workspace.DPIUnscale(w);
361 h = m_Workspace.DPIUnscale(h);
362
363 // Modify width with the extra paddings on sides
364 x += m_fExtraPaddingLeft;
365 w -= m_fExtraPaddingLeft + m_fExtraPaddingRight;
366
367 m_wElementsRoot = GetGame().GetWorkspace().CreateWidgets(m_sListRootLayout, GetGame().GetWorkspace());
368 if (m_aElementData.IsEmpty())
369 m_wElementsRoot.SetVisible(false);
370
371 if (!m_wElementsRoot)
372 return;
373
374 // List Content setup
375 m_wContent = VerticalLayoutWidget.Cast(m_wElementsRoot.FindAnyWidget("Content"));
376 if (!m_wContent)
377 return;
378
379 if (m_bCreateListBelow)
380 {
381 y += h + m_fItemsGap;
382 }
383 else
384 {
385 y -= m_fItemsGap;
386 m_wContent.SetFillOrigin(VerticalFillOrigin.BOTTOM);
387 Widget separator = m_wContent.GetChildren();
388 if (separator)
389 separator.SetZOrder(-1);
390 }
391
392 // List Size setup
394 SizeLayoutWidget size = SizeLayoutWidget.Cast(m_wElementsRoot.FindAnyWidget("SizeLayout"));
395 if (size)
396 {
397 size.EnableWidthOverride(true);
398
400 size.SetWidthOverride(m_fListForcedWidth);
401 else
402 size.SetWidthOverride(w);
403
404 if (m_fMaxListHeight > 0)
405 {
406 size.SetMaxDesiredHeight(m_fMaxListHeight);
407 size.EnableMaxDesiredHeight(true);
408 }
409 }
410
411 // Cache content scroll layout if present
412 m_wScrollLayout = ScrollLayoutWidget.Cast(m_wElementsRoot.FindAnyWidget("ScrollLayout"));
413
414 // Create entries
416
417 // Modal handler
420 m_ModalHandler.m_OnModalClickOut.Insert(CloseList);
421
423 m_ModalHandler.SetupOwners(this, menu);
424
425 // Update arrow image
426 if (m_wArrowImage)
427 {
428 if (m_bRotateArrow)
429 m_wArrowImage.SetRotation(m_fArrowDefaultAngle + 180);
430
432 }
433
434 // Event
435 m_OnOpened.Invoke(this);
436 }
437
438 //------------------------------------------------------------------------------------------------
439 protected void OnCreateElement(Widget elementWidget, int index)
440 {
441 }
442
443 //------------------------------------------------------------------------------------------------
445 {
446 GetGame().GetCallqueue().Remove(CheckElementsInitialized);
447
448 if (!m_bOpened || !m_wElementsRoot || !m_aElementNames)
449 return;
450
454
455 // Remove escape handling
456 GetGame().GetInputManager().RemoveActionListener(UIConstants.MENU_ACTION_BACK, EActionTrigger.DOWN, OnMenuBack);
457#ifdef WORKBENCH
458 GetGame().GetInputManager().RemoveActionListener(UIConstants.MENU_ACTION_BACK_WB, EActionTrigger.DOWN, OnMenuBack);
459#endif
460
461 m_bOpened = false;
462 m_wElementsRoot.RemoveFromHierarchy();
463
464 foreach (Widget w : m_aElementWidgets)
465 {
466 if (!w)
467 continue;
468
469 SCR_ButtonTextComponent comp = SCR_ButtonTextComponent.Cast(w.GetHandler(0));
470 if (!comp)
471 continue;
472
473 comp.m_OnToggled.Remove(OnElementSelected);
474 }
475 m_aElementWidgets.Clear();
476
477 // Reset nagivation rules
478 m_wRoot.SetNavigation(WidgetNavigationDirection.UP, WidgetNavigationRuleType.ESCAPE);
479 m_wRoot.SetNavigation(WidgetNavigationDirection.DOWN, WidgetNavigationRuleType.ESCAPE);
480
481 GetGame().GetWorkspace().SetFocusedWidget(m_wContentRoot);
482
483 // Update arrow image
484 if (m_wArrowImage)
485 {
486 if (m_bRotateArrow)
488
490 }
491
493 m_OnClosed.Invoke(this);
494 }
495
496 //------------------------------------------------------------------------------------------------
497 protected void OnMenuBack()
498 {
499 if (m_bOpened)
500 CloseList();
501 }
502
503 //------------------------------------------------------------------------------------------------
504 override int AddItem(string item, bool last = false, Managed data = null)
505 {
506 int i = super.AddItem(item, last, data);
507 UpdateName();
508 if (m_bOpened)
510
511 return i;
512 }
513
514 //------------------------------------------------------------------------------------------------
515 override void ClearAll()
516 {
517 super.ClearAll();
518 UpdateName();
519 if (m_bOpened)
521 }
522
523 //------------------------------------------------------------------------------------------------
524 override void RemoveItem(int item, bool last = false)
525 {
526 super.RemoveItem(item, last);
527 UpdateName();
528 if (m_bOpened)
530 }
531
532 //------------------------------------------------------------------------------------------------
537 void SetElementWidgetEnabled(int index, bool enable, bool animate = true)
538 {
539 if (!m_aElementWidgets.IsIndexValid(index))
540 return;
541
542 Widget element = m_aElementWidgets[index];
543 if (!element)
544 return;
545
546 SCR_WLibComponentBase wLib = SCR_WLibComponentBase.Cast(element.FindHandler(SCR_WLibComponentBase));
547 if (wLib)
548 wLib.SetEnabled(enable, animate);
549 else
550 element.SetEnabled(enable);
551 }
552
553 //------------------------------------------------------------------------------------------------
554 private void OnElementSelected(SCR_ButtonTextComponent comp)
555 {
556 int i = m_aElementWidgets.Find(comp.m_wRoot);
557 if (i > -1)
558 {
559 SetCurrentItem(i, false, true);
560 if (m_wText)
561 m_wText.SetText(m_aElementNames[i]);
562 }
563
564 CloseList();
565 m_OnChanged.Invoke(this, i);
566 }
567
568 //------------------------------------------------------------------------------------------------
574 int GetElementWidgets(notnull array<Widget> elementWidgets)
575 {
576 foreach (Widget w: m_aElementWidgets)
577 elementWidgets.Insert(w);
578
579 return elementWidgets.Count();
580 }
581
582 //------------------------------------------------------------------------------------------------
583 bool IsOpened()
584 {
585 return m_bOpened;
586 }
587
588 //------------------------------------------------------------------------------------------------
591 static SCR_ComboBoxComponent GetComboBoxComponent(string name, Widget parent, bool searchAllChildren = true)
592 {
593 auto comp = SCR_ComboBoxComponent.Cast(
594 SCR_WLibComponentBase.GetComponent(SCR_ComboBoxComponent, name, parent, searchAllChildren)
595 );
596 return comp;
597 }
598};
599
600//------------------------------------------------------------------------------------------------
602{
605
607
608 //------------------------------------------------------------------------------------------------
609 override bool OnModalClickOut(Widget modalRoot, int x, int y, int button)
610 {
611 m_OnModalClickOut.Invoke();
612 return true;
613 }
614
615 //------------------------------------------------------------------------------------------------
616 override void HandlerDeattached(Widget w)
617 {
618 if (m_OwnerMenu)
619 m_OwnerMenu.m_OnUpdate.Remove(OnMenuUpdate);
620 }
621
622 //------------------------------------------------------------------------------------------------
624 {
625 m_Owner = owner;
626 m_OwnerMenu = menu;
627
628 if (m_OwnerMenu)
629 m_OwnerMenu.m_OnUpdate.Insert(OnMenuUpdate);
630 }
631
632 //------------------------------------------------------------------------------------------------
633 protected void OnMenuUpdate(float tDelta)
634 {
635 // Scroll input
636 if (GetGame().GetInputManager().GetActionValue("MenuScrollVertical") != 0)
637 {
638 m_Owner.CloseList();
639 return;
640 }
641
642 // Visible in hierarchy
643 if (!m_Owner.GetRootWidget().IsVisibleInHierarchy())
644 {
645 m_Owner.CloseList();
646 return;
647 }
648 }
649};
ArmaReforgerScripted GetGame()
Definition game.c:1398
int size
InputManager GetInputManager()
SCR_DestructionSynchronizationComponentClass ScriptComponentClass int index
Get all prefabs that have the spawner data
Widget m_wRoot
TextWidget m_wText
UI Textures DeployMenu Briefing conflict_HintBanner_1_UI desc
static WidgetAnimationColor Color(Widget widget, Color color, float speed)
Constant variables used in various menus.
static ChimeraMenuBase GetOwnerMenu(Widget w)
Returns parent menu of a widget.
Definition Color.c:13
Input management system for user interactions.
override void SetToggled(bool toggled, bool animate=true, bool invokeChange=true, bool instant=false)
void SetElementWidgetEnabled(int index, bool enable, bool animate=true)
void OnMenuFocusLost(ChimeraMenuBase menu)
void OnDisabled(bool animate)
ScrollLayoutWidget m_wScrollLayout
ref SCR_ComboModalHandler m_ModalHandler
override void HandlerDeattached(Widget w)
override bool OnFocus(Widget w, int x, int y)
void OnCreateElement(Widget elementWidget, int index)
override void RemoveItem(int item, bool last=false)
override bool OnFocusLost(Widget w, int x, int y)
override void HandlerAttached(Widget w)
ref array< Widget > m_aElementWidgets
override bool SetCurrentItem(int i, bool playSound=false, bool animate=false)
override int AddItem(string item, bool last=false, Managed data=null)
VerticalLayoutWidget m_wContent
override void HandlerDeattached(Widget w)
override bool OnModalClickOut(Widget modalRoot, int x, int y, int button)
ref ScriptInvoker m_OnModalClickOut
void SetupOwners(SCR_ComboBoxComponent owner, ChimeraMenuBase menu)
SCR_ComboBoxComponent m_Owner
void OnMenuUpdate(float tDelta)
static ScriptInvokerMenu GetOnMenuFocusLost()
static void SetActiveWidgetInteractionState(bool isActive, int delay=0)
Base class for all final Reforger interactive elements.
void SetEnabled(bool enabled, bool animate=true)
SCR_FieldOfViewSettings Attribute
EActionTrigger
WidgetFlags
Widget flags. See enf::Widget::SetFlags().
Definition WidgetFlags.c:14
ScriptInvokerBase< func > ScriptInvoker
Definition tools.c:134