Arma Reforger Explorer  1.1.0.42
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
SCR_RadialMenuDisplay.c
Go to the documentation of this file.
1 //------------------------------------------------------------------------------------------------
8 {
9  protected const string HINT_BASE = "<action name='%1' hideEmpty='1'/>";
10  protected const float CHANGE_CONTENT_OPACITY = 0.4;
11  protected const float ENTRY_ANIMATION_SCALE = 1.25;
12  protected const float ENTRY_ANIMATION_SPEED = 7.5;
13 
14  [Attribute("150", UIWidgets.Slider, "Entries distance from menu center in pixels", "0 1000 1")]
15  protected int m_iEntriesRadius;
16 
17  [Attribute("0")]
18  protected float m_fSelectedIndicatorOffset;
19 
20  // Widget name refs
21  [Attribute(desc: "Widget name for menu base wrapper that hould all important parts of radial circle")]
22  protected string m_sBaseWidget;
23 
24  [Attribute("1", desc: "Adjust base size in callback based on invoker from SCR_RadialMenu")]
25  protected bool m_bForceSize;
26 
27  [Attribute("0", desc: "Skips the slower fade animation on entry perform")]
28  protected bool m_bFastFadeOnPerform;
29 
30  [Attribute( desc: "Widget name for storing entry separator widgets")]
31  protected string m_sDividersParent;
32 
33  [Attribute( ".edds", desc: "Texture used for creating dividing lines")]
34  protected ResourceName m_sDividerTexture;
35 
36  [Attribute("0", UIWidgets.Slider, "Dividers distance from menu center in pixels", "0 1000 1")]
37  protected int m_iDividersRadius;
38 
39  [Attribute("120")]
40  protected int m_iDividerSize;
41 
42  [Attribute("1", UIWidgets.Slider, "Dividers texture opacity", "0 1 0.01")]
43  protected float m_fDividersOpacity;
44 
45  [Attribute(desc: "Widget name for storing segment widgets of each entry")]
46  protected string m_sSegmentsParent;
47 
48  [Attribute(".layout", desc: "Layout used for creating segment. Serves for entry split and colorize", params: "layout")]
49  protected ResourceName m_sSegmentLayout;
50 
51  [Attribute(desc: "Image widget name for displaying where player is pointing to")]
52  protected string m_sSelectorLine;
53 
54  [Attribute(desc: "Widget name for poiting selection arrow")]
55  protected string m_sSelectorArrow;
56 
57  [Attribute(desc: "Widget name for selection pointing innner selector")]
58  protected string m_sInnerSelector;
59 
60  [Attribute(desc: "Image widget name for highlighting currently selected entry")]
61  protected string m_sSelectedIndicator;
62 
63  [Attribute(desc: "Image widget name for selection feedback")]
64  protected string m_sSelectedIndicatorFeedback;
65 
66  [Attribute(desc: "Text widget name for displaying name of currently selected entry")]
67  protected string m_sSelectedName;
68 
69  [Attribute(desc: "Rich text widget name for displaying key e.g. required for quick use of selected entry")]
70  protected string m_sActionHint;
71 
72  [Attribute(desc: "Text widget name for displaying entry description or hint")]
73  protected string m_sDescription;
74 
75  [Attribute(desc: "Widget name with breadcrumbs component to find reference for breadcrumbs")]
76  protected string m_sBreadCrumbs;
77 
78  [Attribute("ImgInnerBackground", desc: "Name of image widget for inner circle background")]
79  protected string m_sInnerBackround;
80 
81  [Attribute(desc: "Widget holding icon and shadow of crosshair")]
82  protected string m_sCrosshairWrap;
83 
84  [Attribute(desc: "Front blur widget for animation effects")]
85  protected string m_sBlur;
86 
87  [Attribute(desc: "Widget name for entry hint wrapper")]
88  protected string m_sHintWrapper;
89 
90  [Attribute("325", UIWidgets.Slider, "Hint distance from center in pixels", "0 500 1")]
91  protected float m_fHintRadius;
92 
93  [Attribute("1000", UIWidgets.Slider, "Time to display hint in miliseconds", "0 5000 1")]
94  protected int m_iHintDisplayDelay;
95 
96  [Attribute("100")]
97  protected int m_iCategoryIconRadius;
98 
99  [Attribute(".layout", desc: "Layout used for number hint", params: "layout")]
100  protected ResourceName m_sNumberHintLayout;
101 
102  [Attribute(desc: "Widget name for storing number hints widgets of each entry")]
103  protected string m_sNumberHintParent;
104 
105  [Attribute("320", UIWidgets.Slider, "Entry number hints distance from center in pixels", "0 500 1")]
106  protected float m_fNumberHintRadius;
107 
108  protected Widget m_wBase;
109  protected Widget m_wDividersParent;
110  protected ref array<Widget> m_aDividers = {};
111  protected Widget m_wSegmentsParent;
112  protected ref array<SCR_RadialMenuSegmentComponent> m_aSegments = {};
113 
114  protected Widget m_wNumberHints;
115  protected ref array<SCR_RadialMenuNumberHintComponent> m_aNumberHints = {};
116 
117  protected ImageWidget m_wSelectorArrow;
118  protected ImageWidget m_wInnerSelector;
119  protected ImageWidget m_wSelectorLine;
120  protected ImageWidget m_wSelectedIndicator;
121  protected ImageWidget m_wSelectedIndicatorFeedback;
122  protected TextWidget m_wSelectedName;
123  protected TextWidget m_wActionHint;
124  protected TextWidget m_wDescription;
125  protected ImageWidget m_wInnerBackround;
126  protected Widget m_wCrosshairWrap;
127  protected BlurWidget m_wBlur;
128 
129  protected Widget m_wHintWrapper;
130 
131  protected SCR_RadialMenu m_RadialMenu;
132  protected SCR_BreadCrumbsComponent m_BreadCrumbs;
133 
134  protected float m_fSelectorArrowRadius;
135 
136  // Values to dynamic
137  protected float m_fDynamicEntriesRadius;
138  protected float m_fDynamicDividerSize;
139  protected float m_fDynamicDividersRadius;
140  protected float m_SizeRatio;
141 
142  protected int m_iPrevCategoryLevel = 0;
143 
144  //------------------------------------------------------------------------------------------------
145  // Override
146  //------------------------------------------------------------------------------------------------
147 
148  //------------------------------------------------------------------------------------------------
150  override void DisplayStartDraw(IEntity owner)
151  {
152  super.DisplayStartDraw(owner);
153 
154  // Find widgets
155  m_wBase = GetRootWidget().FindAnyWidget(m_sBaseWidget);
156  m_wDividersParent = GetRootWidget().FindAnyWidget(m_sDividersParent);
157  m_wSegmentsParent = GetRootWidget().FindAnyWidget(m_sSegmentsParent);
158 
159  m_wSelectorArrow = ImageWidget.Cast(GetRootWidget().FindAnyWidget(m_sSelectorArrow));
160  m_wInnerSelector = ImageWidget.Cast(GetRootWidget().FindAnyWidget(m_sInnerSelector));
161  m_wSelectorLine = ImageWidget.Cast(GetRootWidget().FindAnyWidget(m_sSelectorLine));
162  m_wSelectedIndicator = ImageWidget.Cast(GetRootWidget().FindAnyWidget(m_sSelectedIndicator));
163  m_wSelectedIndicatorFeedback = ImageWidget.Cast(GetRootWidget().FindAnyWidget(m_sSelectedIndicatorFeedback));
164 
165  m_wSelectedName = TextWidget.Cast(GetRootWidget().FindAnyWidget(m_sSelectedName));
166  m_wDescription = TextWidget.Cast(GetRootWidget().FindAnyWidget(m_sDescription));
167 
168  m_wActionHint = TextWidget.Cast(GetRootWidget().FindAnyWidget(m_sActionHint));
169 
170  m_wInnerBackround = ImageWidget.Cast(GetRootWidget().FindAnyWidget(m_sInnerBackround));
171  m_wCrosshairWrap = GetRootWidget().FindAnyWidget(m_sCrosshairWrap);
172  m_wBlur = BlurWidget.Cast(GetRootWidget().FindAnyWidget(m_sBlur));
173 
174  m_wHintWrapper = GetRootWidget().FindAnyWidget(m_sHintWrapper);
175 
176  m_wNumberHints = GetRootWidget().FindAnyWidget(m_sNumberHintParent);
177 
178  // Find breadcrubms
179  Widget breadCrumbs = GetRootWidget().FindAnyWidget(m_sBreadCrumbs);
180  if (breadCrumbs)
181  m_BreadCrumbs = SCR_BreadCrumbsComponent.Cast(breadCrumbs.FindHandler(SCR_BreadCrumbsComponent));
182 
183  // Selection
184  if (m_wSelectedIndicator)
185  m_wSelectedIndicator.SetVisible(false);
186 
187  if (m_wSelectedIndicatorFeedback)
188  {
189  m_wSelectedIndicatorFeedback.SetVisible(true);
190  m_wSelectedIndicatorFeedback.SetOpacity(0);
191  AnimateWidget.StopAnimation(m_wSelectedIndicatorFeedback, WidgetAnimationOpacity);
192  }
193 
194  if (m_wBlur)
195  m_wBlur.SetOpacity(0);
196 
197  // Details
198  if (m_wDescription)
199  m_wDescription.SetVisible(false);
200 
201  if (m_wActionHint)
202  m_wActionHint.SetVisible(false);
203  }
204 
205  //------------------------------------------------------------------------------------------------
206  override void DisplayStopDraw(IEntity owner)
207  {
208  super.DisplayStopDraw(owner);
209 
210  if (m_RadialMenu)
211  {
212  m_RadialMenu.GetOnDisplaySizeChange().Remove(OnDisplaySizeChange);
213  m_RadialMenu.GetOnSetActionHint().Remove(OnSetActionHint);
214  }
215  }
216 
217  //------------------------------------------------------------------------------------------------
218  override void DisplayUpdate(IEntity owner, float timeSlice)
219  {
220  if (!m_bShown || !m_RadialMenu)
221  return;
222 
223  VisualizeSelection(m_RadialMenu.GetPointingAngle());
224 
225  // Show hints
226  m_wNumberHints.SetVisible(
227  m_RadialMenu &&
228  m_RadialMenu.GetUseQuickActions() &&
229  GetGame().GetInputManager().IsUsingMouseAndKeyboard());
230  }
231 
232  //------------------------------------------------------------------------------------------------
233  override void SetupMenu(SCR_SelectionMenu menu)
234  {
235  if (m_Menu)
236  m_Menu.GetOnOpenCategory().Remove(OnMenuOpenCategory);
237 
238  if (m_RadialMenu)
239  {
240  m_RadialMenu.GetOnDisplaySizeChange().Remove(OnDisplaySizeChange);
241  m_RadialMenu.GetOnSetActionHint().Remove(OnSetActionHint);
242  }
243 
244  super.SetupMenu(menu);
245 
246  m_RadialMenu = SCR_RadialMenu.Cast(m_Menu);
247  if (!m_RadialMenu)
248  return;
249 
250  m_RadialMenu.GetOnDisplaySizeChange().Insert(OnDisplaySizeChange);
251  m_RadialMenu.GetOnSetActionHint().Insert(OnSetActionHint);
252  m_RadialMenu.GetOnOpenCategory().Insert(OnMenuOpenCategory);
253  }
254 
255  //------------------------------------------------------------------------------------------------
256  override protected void OnMenuOpen()
257  {
258  super.OnMenuOpen();
259  SetupSelectionVisuals();
260 
261  if (m_wSelectedIndicatorFeedback)
262  m_wSelectedIndicatorFeedback.SetOpacity(0);
263 
264  // Crosshair
265  SCR_RadialMenuControllerInputs radialInputs;
266  if (m_RadialMenu)
267  radialInputs = SCR_RadialMenuControllerInputs.Cast(m_RadialMenu.GetControllerInputs());
268 
269  if (radialInputs)
270  {
271  ShowCrosshair(radialInputs.m_bShowCrosshair);
272  ShowInnerBackground(radialInputs.m_bShowInnerBackground);
273  }
274  }
275 
276  //------------------------------------------------------------------------------------------------
277  override protected void OnShownFinished(Widget w, float targetOpacity, WidgetAnimationOpacity anim = null)
278  {
279  super.OnShownFinished(w, targetOpacity, anim);
280 
281  if (m_Menu && m_Menu.IsOpened())
282  SetupMenuCenter();
283  }
284 
285  //------------------------------------------------------------------------------------------------
286  protected void SetupMenuCenter()
287  {
288  if (!m_RadialMenu || !m_wBase)
289  return;
290 
291  // Screen pos
292  float posX, posY;
293  m_wBase.GetScreenPos(posX, posY);
294 
295  float sizeX, sizeY;
296  m_wBase.GetScreenSize(sizeX, sizeY);
297 
298  float x = posX + sizeX * 0.5;
299  float y = posY + sizeY * 0.5;
300  m_RadialMenu.SetMenuCenterPos(Vector(x, y, 0));
301  GetGame().GetInputManager().SetCursorPosition(x, y);
302  }
303 
304  //------------------------------------------------------------------------------------------------
305  override protected void OnMenuClose()
306  {
307  if (!m_RadialMenu)
308  return;
309 
310  if (m_RadialMenu.GetEntryPerformed() && !m_bFastFadeOnPerform)
311  Show(false, UIConstants.FADE_RATE_DEFAULT, EAnimationCurve.EASE_IN_EXPO);
312  else
313  Show(false, UIConstants.FADE_RATE_FAST);
314  }
315 
316  //------------------------------------------------------------------------------------------------
317  override protected void OnMenuEntriesUpdate(SCR_SelectionMenu menu, array<ref SCR_SelectionMenuEntry> entries)
318  {
319  if (!m_Menu.IsOpened())
320  return;
321 
322  super.OnMenuEntriesUpdate(menu, entries);
323 
324  SetupSelectionVisuals();
325  }
326 
327  //------------------------------------------------------------------------------------------------
328  override protected void SetupEntryWidget(notnull SCR_SelectionMenuEntry entry, notnull Widget widget, int id)
329  {
330  float angle = SetupFrameSlotPosition(widget, id, m_fDynamicEntriesRadius, m_RadialMenu.GetEntriesAngleDistance());
331 
332  // Set icon size
334  widget.FindHandler(SCR_SelectionMenuEntryIconComponent));
335 
337 
338  if (iconEntryCmp)
339  {
340  float entrySize = iconEntryCmp.GetOriginalSize() * m_SizeRatio;
341  iconEntryCmp.SetLayoutSize(entrySize);
342  }
343 
344  // Add elements for entry
345  CreateEntrySegment(entry, widget, id);
346 
347  // Add number hint
348  if (m_RadialMenu && m_RadialMenu.GetUseQuickActions())
349  CreateNumberHint(id);
350  }
351 
352  //------------------------------------------------------------------------------------------------
354  protected void CreateNumberHint(int id)
355  {
356  // up to 9
357  if (id >= SCR_RadialMenuControllerInputs.MAX_HINTS)
358  return;
359 
360  Widget hint = GetGame().GetWorkspace().CreateWidgets(m_sNumberHintLayout, m_wNumberHints);
361  if (!hint)
362  return;
363 
364  // Position
365  float angle = m_RadialMenu.GetEntriesAngleDistance() * id * Math.DEG2RAD;
366  vector vec = GetPointOnCircle(m_fNumberHintRadius, angle);
367  FrameSlot.SetPos(hint, vec[0], vec[1]);
368 
369  // Id
371  if (!hintCmp)
372  return;
373 
374  hintCmp.SetMessages((id + 1).ToString(), "");
375  m_aNumberHints.Insert(hintCmp);
376  }
377 
378  //------------------------------------------------------------------------------------------------
380  override protected void OnMenuEntrySelected(SCR_SelectionMenu menu, SCR_SelectionMenuEntry entry, int id)
381  {
382  // Selection
383  if (m_wSelectedIndicator)
384  {
385  m_wSelectedIndicator.SetVisible(entry != null && entry.IsEnabled());
386 
387  float angle = m_RadialMenu.GetEntriesAngleDistance() * id;
388  float offset = m_fSelectedIndicatorOffset - m_RadialMenu.GetEntriesAngleDistance() * 0.5;
389  m_wSelectedIndicator.SetRotation(angle + offset);
390 
391  if (m_wSelectedIndicatorFeedback)
392  m_wSelectedIndicatorFeedback.SetRotation(angle + offset);
393  }
394 
395  // Info
396  if (m_wSelectedName)
397  {
398  m_wSelectedName.SetVisible(entry != null);
399 
400  if (entry)
401  m_wSelectedName.SetText(entry.GetName());
402  }
403 
404  // Visualize segments selection
405  if (m_aSegments.IsIndexValid(m_iLastSelectedId))
406  {
407  if (m_LastSelectedEntry && m_LastSelectedEntry.IsEnabled())
408  m_aSegments[m_iLastSelectedId].GetBackgroundWidget().SetVisible(true);
409  }
410 
411  if (m_aSegments.IsIndexValid(id))
412  m_aSegments[id].GetBackgroundWidget().SetVisible(false);
413 
414  // // Update number hints
415  if (m_aNumberHints.IsIndexValid(m_iLastSelectedId))
416  m_aNumberHints[m_iLastSelectedId].Highlight(false);
417 
418  if (m_aNumberHints.IsIndexValid(id))
419  m_aNumberHints[id].Highlight(true);
420 
421 
422  // Update selection
423  m_LastSelectedEntry = entry;
424  m_iLastSelectedId = id;
425 
426  // Display description
427  if (m_wDescription)
428  {
429  m_wDescription.SetVisible(entry && !entry.GetDescription().IsEmpty());
430 
431  if (entry)
432  m_wDescription.SetText(entry.GetDescription());
433  }
434 
435  // Display action hint
436  if (m_wActionHint)
437  m_wActionHint.SetVisible(entry && !m_wActionHint.GetText().IsEmpty());
438 
439  // Place hint
440  SetupEntryHint("", id);
441  }
442 
443  //------------------------------------------------------------------------------------------------
444  override protected void OnMenuEntryPerform(SCR_SelectionMenu menu, SCR_SelectionMenuEntry entry)
445  {
446  if (m_wSelectedIndicatorFeedback)
447  {
448  m_wSelectedIndicatorFeedback.SetOpacity(0);
449 
450  if (!AnimateWidget.IsAnimating(m_wSelectedIndicatorFeedback))
451  AnimateWidget.Opacity(m_wSelectedIndicatorFeedback, CHANGE_CONTENT_OPACITY, UIConstants.FADE_RATE_FAST);
452  }
453 
454  // Animate entry
455  if (!entry || !entry.GetEntryComponent())
456  return;
457 
458  Widget entryW = entry.GetEntryComponent().GetRootWidget().GetChildren();
459 
460  // Prevent starting animation again
461  if (AnimateWidget.IsAnimating(entryW))
462  return;
463 
464  float originalSize = entry.GetEntryComponent().GetAdjustedSize();
465  float size[2] = {originalSize * ENTRY_ANIMATION_SCALE, originalSize * ENTRY_ANIMATION_SCALE};
466 
467  WidgetAnimationFrameSize anim = AnimateWidget.Size(entryW, size, ENTRY_ANIMATION_SPEED);
468  anim.SetRepeat(true);
469  anim.GetOnCycleCompleted().Insert(OnEntrySizeAnimCycleCompleted);
470  }
471 
472  //------------------------------------------------------------------------------------------------
473  protected void OnEntrySizeAnimCycleCompleted(WidgetAnimationBase anim)
474  {
475  anim.SetRepeat(false);
476  anim.Stop();
477 
478  AnimateWidget.Opacity(m_wSelectedIndicatorFeedback, 0, UIConstants.FADE_RATE_FAST);
479 
480  anim.GetOnCycleCompleted().Remove(OnEntrySizeAnimCycleCompleted);
481  }
482 
483  //------------------------------------------------------------------------------------------------
485  override protected void ClearEntryWidgets()
486  {
487  super.ClearEntryWidgets();
488 
489  if (m_aSegments.Count() != m_aDividers.Count())
490  {
491  DebugPrint("ClearEntryWidgets", "Different entries");
492  }
493 
494  // Clear segments and dividers
495  for (int i = 0, count = m_aSegments.Count(); i < count; i++)
496  {
497  m_aSegments[i].GetRootWidget().RemoveFromHierarchy();
498  m_aDividers[i].RemoveFromHierarchy();
499 
500  if (m_aNumberHints.IsIndexValid(i))
501  m_aNumberHints[i].GetRoot().RemoveFromHierarchy();
502  }
503 
504  m_aSegments.Clear();
505  m_aDividers.Clear();
506  m_aNumberHints.Clear();
507  }
508 
509  //------------------------------------------------------------------------------------------------
510  // Custom
511  //------------------------------------------------------------------------------------------------
512 
513  //------------------------------------------------------------------------------------------------
515  protected vector GetPointOnCircle(float radius, float degrees)
516  {
517  // - half PI because 90 deg offset left
518  return Vector(
519  radius * Math.Cos(degrees - 0.5 * Math.PI),
520  radius * Math.Sin(degrees - 0.5 * Math.PI),
521  0.0);
522  }
523 
524  //------------------------------------------------------------------------------------------------
525  protected void VisualizeSelection(float selectionAngle)
526  {
527  // Check widgets
528  if (m_wSelectorArrow)
529  m_wSelectorArrow.SetVisible(!m_RadialMenu.IsPointingToCenter());
530 
531  if (m_wInnerSelector)
532  m_wInnerSelector.SetVisible(!m_RadialMenu.IsPointingToCenter());
533 
534  m_wSelectorLine.SetVisible(!m_RadialMenu.IsPointingToCenter());
535  m_wSelectorLine.SetRotation(selectionAngle - 180);
536 
537  // Gamepad
538  if (!m_wSelectorArrow)
539  return;
540 
541  if (m_fSelectorArrowRadius == 0 && m_wSelectorArrow)
542  m_fSelectorArrowRadius = FrameSlot.GetPosY(m_wSelectorArrow) * m_SizeRatio;
543 
544  if (m_fSelectorArrowRadius == 0)
545  return;
546 
547  // Check center
548  vector vec = GetPointOnCircle(-m_fSelectorArrowRadius, selectionAngle * Math.DEG2RAD);
549  FrameSlot.SetPos(m_wSelectorArrow, vec[0], vec[1]);
550 
551  m_wSelectorArrow.SetRotation(selectionAngle);
552 
553  if (m_wInnerSelector)
554  {
555  m_wInnerSelector.SetRotation(selectionAngle);
556  }
557  }
558 
559  //------------------------------------------------------------------------------------------------
561  protected float SetupFrameSlotPosition(out notnull Widget widget, int id, float distance, float angle, float angleOffset = 0)
562  {
563  // Calculate
564  float degs = angle * id + angleOffset;
565  vector point = GetPointOnCircle(distance, degs * Math.DEG2RAD);
566 
567  // Set position - set entry layout to menu center to more easily place entry around the circle
568  FrameSlot.SetPos(widget, point[0], point[1]);
569  FrameSlot.SetAlignment(widget, 0.5, 0.5);
570  FrameSlot.SetAnchorMin(widget, 0.5, 0.5);
571  FrameSlot.SetAnchorMax(widget, 0.5, 0.5);
572 
573  return degs;
574  }
575 
576  //------------------------------------------------------------------------------------------------
578  protected void CreateEntrySegment(notnull SCR_SelectionMenuEntry entry, notnull Widget widget, int id)
579  {
580  if (!m_wSegmentsParent || m_sSegmentLayout.IsEmpty())
581  {
582  DebugPrint("CreateEntrySegment", "Can't create segments!");
583  return;
584  }
585 
586  Widget segment = GetGame().GetWorkspace().CreateWidgets(m_sSegmentLayout, m_wSegmentsParent);
588 
589  float angleDist = m_RadialMenu.GetEntriesAngleDistance();
590  float range = angleDist / 360;
591  // distance * list position - half -> to be in entry center
592  float rot = angleDist * id - angleDist * 0.5;
593  bool isCategory = SCR_SelectionMenuCategoryEntry.Cast(entry);
594 
595  segmentCmp.SetupSegment(range, angleDist * id, isCategory);
596 
597  // Register
598  m_aSegments.Insert(segmentCmp);
599 
600  // Add divider
601  if (m_wDividersParent && !m_sDividerTexture.IsEmpty())
602  {
603  CreateDivider(id);
604  }
605 
607  widget.FindHandler(SCR_SelectionMenuEntryComponent));
608 
609  // Visual setup
610  VisualizeEnableEntry(comp, id, entry.IsEnabled());
611  }
612 
613  //------------------------------------------------------------------------------------------------
615  protected void CreateDivider(int id)
616  {
617  if (!m_wDividersParent || m_sDividerTexture.IsEmpty())
618  {
619  DebugPrint("CreateDivider", "Can't create segments!");
620  return;
621  }
622 
623  Widget divider = GetGame().GetWorkspace().CreateWidget(WidgetType.ImageWidgetTypeID,
624  WidgetFlags.VISIBLE | WidgetFlags.STRETCH | WidgetFlags.BLEND | WidgetFlags.INHERIT_CLIPPING,
625  Color.FromInt(Color.WHITE),
626  0,
627  m_wDividersParent
628  );
629 
630  // Setup divider widget
631  ImageWidget imgDivider = ImageWidget.Cast(divider);
632 
633  imgDivider.LoadImageTexture(0, m_sDividerTexture);
634  imgDivider.SetOpacity(m_fDividersOpacity);
635  FrameSlot.SetSize(divider, m_fDynamicDividerSize, m_fDynamicDividerSize);
636 
637  float angleDist = m_RadialMenu.GetEntriesAngleDistance();
638  float angle = SetupFrameSlotPosition(divider, id, m_fDynamicDividersRadius, angleDist, angleDist * 0.5);
639 
640  imgDivider.SetRotation(angle);
641 
642  // Register
643  m_aDividers.Insert(divider)
644  }
645 
646  //------------------------------------------------------------------------------------------------
647  protected void SetupEntryHint(string text, int id)
648  {
649  if (!m_wHintWrapper)
650  return;
651 
652  m_wHintWrapper.SetOpacity(0);
653  AnimateWidget.StopAnimation(m_wHintWrapper, WidgetAnimationOpacity);
654 
655  GetGame().GetCallqueue().Remove(DisplayEntryHint);
656  // Call later to display hint only if player stays longer on single entry
657  // Intend is to prevent cluttering screen with hints if playuer knows immidiatelly what action does
658  GetGame().GetCallqueue().CallLater(DisplayEntryHint, m_iHintDisplayDelay);
659 
660  // Set position
661  float angle = m_RadialMenu.GetEntriesAngleDistance() * id * Math.DEG2RAD;
662  vector vec = GetPointOnCircle(m_fHintRadius, angle);
663 
664  float width = FrameSlot.GetSizeX(m_wHintWrapper);
665  vec[0] = vec[0] + Math.Sin(angle) * width * 0.5;
666 
667  // Apply to frame widget
668  FrameSlot.SetPos(m_wHintWrapper, vec[0], vec[1]);
669  }
670 
671  //------------------------------------------------------------------------------------------------
672  protected void DisplayEntryHint()
673  {
674  AnimateWidget.Opacity(m_wHintWrapper, 1, UIConstants.FADE_RATE_DEFAULT);
675  }
676 
677  //------------------------------------------------------------------------------------------------
678  void VisualizeEnableEntry(notnull SCR_SelectionMenuEntryComponent entry, int id, bool enable)
679  {
680  if (!m_aSegments.IsIndexValid(id))
681  return;
682 
683  m_aSegments[id].GetBackgroundWidget().SetVisible(enable);
684  entry.SetEnabled(enable);
685  }
686 
687  //------------------------------------------------------------------------------------------------
689  protected void OnDisplaySizeChange(SCR_RadialMenu menu, float size)
690  {
691  // Ratio to menu large size
692  m_SizeRatio = 1;
693 
694  if (m_bForceSize)
695  m_SizeRatio = size / menu.SIZE_LARGE;
696 
697  // Setup sizes
698  m_fDynamicEntriesRadius = m_iEntriesRadius * m_SizeRatio;
699  m_fDynamicDividerSize = m_iDividerSize * m_SizeRatio;
700  m_fDynamicDividersRadius = m_iDividersRadius * m_SizeRatio;
701 
702  if (m_bForceSize)
703  FrameSlot.SetSize(m_wBase, size, size);
704  }
705 
706  //------------------------------------------------------------------------------------------------
708  protected void OnSetActionHint(SCR_RadialMenu menu, string action)
709  {
710  // Setup widget
711  if (!action.IsEmpty())
712  m_wActionHint.SetTextFormat(HINT_BASE, action);
713  else
714  m_wActionHint.SetTextFormat(string.Empty);
715 
716  m_wActionHint.SetVisible(m_RadialMenu.GetSelectionEntry() && !m_wActionHint.GetText().IsEmpty());
717  }
718 
719  //------------------------------------------------------------------------------------------------
720  protected void OnMenuOpenCategory(SCR_SelectionMenu menu, SCR_SelectionMenuCategoryEntry category, int level)
721  {
722  if (!category)
723  {
724  if (m_BreadCrumbs)
725  m_BreadCrumbs.Clear();
726 
727  m_iPrevCategoryLevel = 0;
728 
729  return;
730  }
731 
732  if (m_BreadCrumbs)
733  {
734  if (m_iPrevCategoryLevel < level)
735  m_BreadCrumbs.AddBreadCrumbElement(category);
736  else
737  m_BreadCrumbs.RemoveLastBreadCrumbElement();
738  }
739 
740  // Update level
741  m_iPrevCategoryLevel = level;
742 
743  // Call update later to update it once fadeout is done so fadein can start after animation is done
744  GetGame().GetCallqueue().CallLater(LateMenuEntriesUpdate, 1000 / UIConstants.FADE_RATE_SUPER_FAST);
745 
746  if (m_wRoot)
747  m_wRoot.SetOpacity(CHANGE_CONTENT_OPACITY);
748 
749  if (m_wBlur)
750  m_wBlur.SetOpacity(1);
751  }
752 
753  //------------------------------------------------------------------------------------------------
754  protected void LateMenuEntriesUpdate()
755  {
756  SetupSelectionVisuals();
757 
758  if (m_wRoot)
759  AnimateWidget.Opacity(m_wRoot, 1, UIConstants.FADE_RATE_SUPER_FAST);
760 
761  if (m_wBlur)
762  m_wBlur.SetOpacity(0);
763  }
764 
765  //------------------------------------------------------------------------------------------------
766  protected void ChangeCategoryOpen(SCR_SelectionMenu menu, SCR_SelectionMenuCategoryEntry category, int level)
767  {
768  if (!category)
769  {
770  if (m_BreadCrumbs)
771  m_BreadCrumbs.Clear();
772 
773  m_iPrevCategoryLevel = 0;
774 
775  return;
776  }
777 
778  if (m_BreadCrumbs)
779  {
780  if (m_iPrevCategoryLevel < level)
781  m_BreadCrumbs.AddBreadCrumbElement(category);
782  else
783  m_BreadCrumbs.RemoveLastBreadCrumbElement();
784  }
785 
786  // Update level
787  m_iPrevCategoryLevel = level;
788 
789  Show(true, UIConstants.FADE_RATE_FAST);
790  }
791 
792  //------------------------------------------------------------------------------------------------
793  protected void SetupSelectionVisuals()
794  {
795  if (!m_wSelectedIndicator || !m_wSelectorLine)
796  return;
797 
798  // Set selection segment from angles to percents
799  float range = m_RadialMenu.GetEntriesAngleDistance() / 360;
800 
801  m_wSelectedIndicator.SetMaskProgress(range);
802 
803  m_wSelectorLine.SetMaskRange(range * 0.5);
804  m_wSelectorLine.SetMaskTransitionWidth(range * 0.5);
805 
806  if (m_wSelectedIndicatorFeedback)
807  m_wSelectedIndicatorFeedback.SetMaskProgress(range);
808  }
809 
810  //------------------------------------------------------------------------------------------------
811  void ShowInnerBackground(bool show)
812  {
813  if (m_wInnerBackround)
814  m_wInnerBackround.SetVisible(show);
815  }
816 
817  //------------------------------------------------------------------------------------------------
818  void ShowCrosshair(bool show)
819  {
820  if (m_wCrosshairWrap)
821  m_wCrosshairWrap.SetVisible(show);
822  }
823 };
m_bShown
protected bool m_bShown
Definition: SCR_InfoDisplay.c:61
SCR_RadialMenuNumberHintComponent
Definition: SCR_RadialMenuNumberHintComponent.c:6
m_wRoot
protected Widget m_wRoot
Definition: SCR_ScenarioFrameworkLayerTaskDefend.c:59
SCR_SelectionMenuCategoryEntry
Definition: SCR_SelectionMenuCategory.c:6
SCR_RadialMenuDisplay
Definition: SCR_RadialMenuDisplay.c:7
UIConstants
Definition: Constants.c:130
GetGame
ArmaReforgerScripted GetGame()
Definition: game.c:1424
SCR_SelectionMenuEntryIconComponent
Definition: SCR_SelectionMenuEntryIconComponent.c:2
desc
UI Textures DeployMenu Briefing conflict_HintBanner_1_UI desc
Definition: SCR_RespawnBriefingComponent.c:17
GetRootWidget
Widget GetRootWidget()
Definition: SCR_UITaskManagerComponent.c:160
Show
override void Show(WorkspaceWidget pWorkspace, Widget pToolTipWidget, float desiredPosX, float desiredPosY)
Definition: SCR_ScriptedWidgetTooltip.c:55
SCR_SelectionMenu
Definition: SCR_SelectionMenu.c:6
Attribute
typedef Attribute
Post-process effect of scripted camera.
distance
float distance
Definition: SCR_DestructibleTreeV2.c:29
m_sDescription
string m_sDescription
Definition: SCR_FlashlightComponent.c:3
SCR_SelectionMenuEntryComponent
Definition: SCR_SelectionMenuEntryComponent.c:6
m_RadialMenu
protected SCR_RadialMenu m_RadialMenu
Definition: SCR_PlayerControllerCommandingComponent.c:17
GetInputManager
protected InputManager GetInputManager()
Definition: SCR_BaseManualCameraComponent.c:65
params
Configs ServerBrowser KickDialogs params
Definition: SCR_NotificationSenderComponent.c:24
SCR_SelectionMenuDisplay
Definition: SCR_SelectionMenuDisplay.c:7
SCR_SelectionMenuEntry
Definition: SCR_SelectionMenuEntry.c:7
SCR_RadialMenuSegmentComponent
Definition: SCR_RadialMenuSegmentComponent.c:4
SCR_BreadCrumbsComponent
Definition: SCR_BreadCrumbsComponent.c:1
SCR_RadialMenu
Definition: SCR_RadialMenu.c:8
BaseContainerProps
SCR_AIGoalReaction_Follow BaseContainerProps
Handles insects that are supposed to be spawned around selected prefabs defined in prefab names array...
Definition: SCR_AIGoalReaction.c:468
category
params category
Definition: SCR_VehicleDamageManagerComponent.c:180
SCR_RadialMenuControllerInputs
Definition: SCR_RadialMenu.c:784