Arma Reforger Explorer 1.7.0.54
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
Loading...
Searching...
No Matches
SCR_FieldManualUI.c
Go to the documentation of this file.
2{
7
14
15 protected string m_sLastSearch;
16
18 protected ref array<ref SCR_FieldManualConfigEntry> m_aAllEntries;
24
26
28
31
32 protected bool m_bIsInEntryViewMode;
33 protected bool m_bIsInSearchMode;
34 protected bool m_bOpenedFromOutside;
35
36 protected bool m_bArmaWarning;
37
38 protected float m_fSliderYPos;
39
40 protected static const int TILES_GRID_WIDTH = 5;
41 protected static const string SEARCH_RESULT_KEY = "#AR-FieldManual_SearchResult";
42 protected static const string SEARCH_NO_RESULT_KEY = "#AR-FieldManual_SearchResult_None";
43 protected static const string SCROLL_NAME = "mainScroll";
44 protected static const int ENTRY_INPUT_REFRESH_DELAY = 500; // min time in ms before KBM/pad entry refreshes
45 protected static const int ENTRY_SCROLL_INPUT_REFRESH_DELAY = 1000 / 60; // time in ms between KBM/pad entry scroll refreshes
46
47 //------------------------------------------------------------------------------------------------
48 protected override void OnMenuOpen()
49 {
50 super.OnMenuOpen();
51
52 Widget rootWidget = GetRootWidget();
53 SCR_ConfigUIComponent component = SCR_ConfigUIComponent.Cast(rootWidget.FindHandler(SCR_ConfigUIComponent));
54 if (!component)
55 {
56 Print("No config component found | " + __FILE__ + ": " + __LINE__, LogLevel.WARNING);
57 Close();
58 return;
59 }
60
61 SCR_FieldManualConfigRoot configRoot = SCR_FieldManualConfigLoader.LoadConfigRoot(component.m_ConfigPath);
62 if (!configRoot)
63 {
64 Print("Could not load provided config | " + __FILE__ + ": " + __LINE__, LogLevel.WARNING);
65 Close();
66 return;
67 }
68
69 m_ConfigRoot = configRoot;
71
72 // which background do you want, gents?
73 bool isMainMenu = GetGame().m_bIsMainMenuOpen;
74 Widget blur = GetRootWidget().FindAnyWidget("Blur");
75 Widget backgroundImage = GetRootWidget().FindAnyWidget("MenuBackground");
76 if (blur && isMainMenu)
77 blur.RemoveFromHierarchy();
78
79 if (backgroundImage && !isMainMenu)
80 backgroundImage.RemoveFromHierarchy();
81
82 Widget menuFrame = rootWidget.FindAnyWidget("MenuFrame");
83 TextWidget menuTitle = TextWidget.Cast(menuFrame.FindAnyWidget("Title"));
84 VerticalLayoutWidget menuCategoryList = VerticalLayoutWidget.Cast(rootWidget.FindAnyWidget("CategoryList"));
85 GridLayoutWidget menuGridLayout = GridLayoutWidget.Cast(rootWidget.FindAnyWidget("GridLayout"));
86 if (!menuFrame || !menuTitle || !menuCategoryList || !menuGridLayout)
87 {
88 Print("Important elements (menu frame & title, category list, grid layout) are missing | " + __FILE__ + ": " + __LINE__, LogLevel.WARNING);
89 Close();
90 return;
91 }
92
93 Widget readingWidget = rootWidget.FindAnyWidget("ReadingWidget");
94
95 TextWidget entryTitle = TextWidget.Cast(readingWidget.FindAnyWidget("EntryTitle"));
96 Widget entryFrame = readingWidget.FindAnyWidget("EntryFrame");
97 if (!readingWidget || !entryTitle || !entryFrame)
98 {
99 Print(string.Format("missing one: reading widget (%1), entryTitle (%2), entryFrame (%3) | " + FilePath.StripPath(__FILE__) + ":" + __LINE__, readingWidget != null, entryTitle != null, entryFrame != null), LogLevel.WARNING);
100 Close();
101 return;
102 }
103
104 SCR_InputButtonComponent backButtonMenuFrame = SCR_InputButtonComponent.GetInputButtonComponent(UIConstants.BUTTON_BACK, menuFrame);
105 if (!backButtonMenuFrame || !backButtonMenuFrame.m_OnClicked)
106 {
107 Print(string.Format("missing menu frame's back button menu (%1) or m_OnClicked (%2) | " + FilePath.StripPath(__FILE__) + ":" + __LINE__, backButtonMenuFrame != null, backButtonMenuFrame.m_OnClicked != null), LogLevel.WARNING);
108 Close();
109 return;
110 }
111
112 m_MenuBtnBack = backButtonMenuFrame;
113
114 m_wMenuTitle = menuTitle;
115 m_wMenuCategoryList = menuCategoryList;
116 m_wMenuGridLayout = menuGridLayout;
117
118 m_wReadingWidget = readingWidget;
119 m_wPageEntryTitle = entryTitle;
120 m_wPageFrame = entryFrame;
121
122 // breadcrumbs is not mandatory
124
125 // scrolling reset is not mandatory
126 m_wGridScrollLayoutWidget = ScrollLayoutWidget.Cast(rootWidget.FindAnyWidget("GridScrollLayout"));
127
128 // searchbar functionality is not mandatory
129 m_MenuSearchbar = SCR_EditBoxSearchComponent.Cast(SCR_EditBoxSearchComponent.GetEditBoxComponent("Searchbar", rootWidget));
130 if (m_MenuSearchbar && m_MenuSearchbar.m_OnConfirm)
131 m_MenuSearchbar.m_OnConfirm.Insert(ProcessSearch);
132
133 // Server Queue
134 m_wLoadingServerQueue = rootWidget.FindAnyWidget("ServerQueue");
136
137 m_MenuBtnBack.m_OnActivated.Insert(CloseMenuOrReadingPanel);
138
139#ifdef WORKBENCH
140 InputManager inputManager = GetGame().GetInputManager();
141 if (inputManager)
142 {
143 inputManager.AddActionListener(UIConstants.MENU_ACTION_OPEN_WB, EActionTrigger.DOWN, CloseMenuOrReadingPanel);
144 inputManager.AddActionListener(UIConstants.MENU_ACTION_BACK_WB, EActionTrigger.DOWN, CloseMenuOrReadingPanel);
145 }
146#endif // WORKBENCH
147
150 }
151
152 //------------------------------------------------------------------------------------------------
153 protected override void OnMenuShow()
154 {
155 super.OnMenuShow();
156
160
161 //SCR_AnalyticsApplication.GetInstance().OpenFieldManual();
162 }
163
164 //------------------------------------------------------------------------------------------------
165 protected override void OnMenuHide()
166 {
167 super.OnMenuHide();
168
169 //SCR_AnalyticsApplication.GetInstance().CloseFieldManual();
170 }
171
172#ifdef WORKBENCH
173 //------------------------------------------------------------------------------------------------
174 protected override void OnMenuClose()
175 {
176 super.OnMenuClose();
177
178 InputManager inputManager = GetGame().GetInputManager();
179 if (inputManager)
180 {
181 inputManager.RemoveActionListener(UIConstants.MENU_ACTION_OPEN_WB, EActionTrigger.DOWN, CloseMenuOrReadingPanel);
182 inputManager.RemoveActionListener(UIConstants.MENU_ACTION_BACK_WB, EActionTrigger.DOWN, CloseMenuOrReadingPanel);
183 }
184 }
185#endif // WORKBENCH
186
187 //------------------------------------------------------------------------------------------------
190 {
192 m_bIsInSearchMode = false;
193
196
197 FlipButtonState(w, true);
198
203 if (resetTiles)
205 }
206
207 //------------------------------------------------------------------------------------------------
210 protected bool FlipButtonState(Widget w, bool state)
211 {
212 ButtonWidget btnWidget = ButtonWidget.Cast(w);
213 if (!btnWidget)
214 return false;
215
216 SCR_ModularButtonComponent btnModularComponent = SCR_ModularButtonComponent.Cast(btnWidget.FindHandler(SCR_ModularButtonComponent));
217 if (!btnModularComponent)
218 return false;
219
220 btnModularComponent.SetToggled(state);
221
222 return true;
223 }
224
225 //------------------------------------------------------------------------------------------------
229 {
230 m_bIsInSearchMode = false;
232
234
236 }
237
238 //------------------------------------------------------------------------------------------------
240 protected Widget CreateTileWidget(notnull SCR_FieldManualConfigEntry entry, notnull Widget parent)
241 {
242 Widget createdWidget = GetGame().GetWorkspace().CreateWidgets(m_ConfigRoot.m_MenuEntryTileLayout, parent);
243 if (!createdWidget)
244 {
245 Print("could not create tile widget for entry | " + FilePath.StripPath(__FILE__) + ":" + __LINE__, LogLevel.WARNING);
246 return null;
247 }
248
250 if (cardComp)
251 {
252 cardComp.SetImage(entry.m_Image);
253 cardComp.SetBackgroundImage(m_ConfigRoot.m_aTileBackgrounds.GetRandomElement());
254 cardComp.SetText(entry.m_sTitle);
255 }
256
257 return createdWidget;
258 }
259
260 //------------------------------------------------------------------------------------------------
262 // used in SCR_FieldManualSubCategoryScriptedWidgetEventHandler.OnClick
263 protected void SetTilesByWidget(Widget widget)
264 {
266
267 if (!subCategory)
268 return;
269
270 if (m_BreadCrumbsComponent && subCategory.m_Parent)
271 m_BreadCrumbsComponent.Set(subCategory.m_Parent.m_sTitle, subCategory.m_sTitle);
272
273 SetTiles(subCategory.m_aEntries);
274 }
275
276 //------------------------------------------------------------------------------------------------
278 protected void SetTiles(array<ref SCR_FieldManualConfigEntry> entries)
279 {
281 return;
282
283 SCR_WidgetHelper.RemoveAllChildren(m_wMenuGridLayout);
284
285 if (!entries || entries.IsEmpty())
286 return;
287
288 m_mWidgetEntryMap.Clear();
289
290 int column, line;
291 Widget assetCard;
292 ButtonWidget button;
293 foreach (SCR_FieldManualConfigEntry entry : entries)
294 {
295 assetCard = CreateTileWidget(entry, m_wMenuGridLayout);
296 if (!assetCard)
297 continue;
298
299 GridSlot.SetColumn(assetCard, column);
300 GridSlot.SetRow(assetCard, line);
301
302 column++;
303 if (column >= TILES_GRID_WIDTH)
304 {
305 column = 0;
306 line++;
307 }
308
309 button = ButtonWidget.Cast(SCR_WidgetHelper.GetWidgetOrChild(assetCard, "AssetCard0"));
310 if (button)
311 {
312 button.AddHandler(m_EntryButtonEventHandler);
313 m_mWidgetEntryMap.Insert(button, entry);
314 }
315 }
316
318 m_wGridScrollLayoutWidget.SetSliderPos(0, 0);
319 }
320
321 //------------------------------------------------------------------------------------------------
324 {
326 return;
327
328 SCR_WidgetHelper.RemoveAllChildren(m_wPageFrame);
329
330 m_bIsInEntryViewMode = entry != null;
331
334
335
337 {
338 if (m_BreadCrumbsComponent && m_CurrentEntry && m_CurrentEntry.m_Parent && m_CurrentEntry.m_Parent.m_Parent)
339 m_BreadCrumbsComponent.Set(m_CurrentEntry.m_Parent.m_Parent.m_sTitle, m_CurrentEntry.m_Parent.m_sTitle);
340
342 m_CurrentEntry = null;
343 return;
344 }
345
346 float x;
348
349 if (m_BreadCrumbsComponent && entry.m_Parent && entry.m_Parent.m_Parent)
350 m_BreadCrumbsComponent.Set(entry.m_Parent.m_Parent.m_sTitle, entry.m_Parent.m_sTitle, entry.m_sTitle);
351
352 m_CurrentEntry = entry;
353
354 m_wPageEntryTitle.SetText(entry.m_sTitle);
355
356 Widget readingWidget = entry.CreateWidget(m_wPageFrame);
358 if (weaponEntry)
359 FillEntry_Weapon(readingWidget, weaponEntry);
360 }
361
362 //------------------------------------------------------------------------------------------------
365 {
366 if (!m_CurrentEntry || !m_CurrentEntry.CanRefresh())
367 return;
368
369 // safety to not saturate the call queue if someone has fun using pad and kbm at the same time
370 GetGame().GetCallqueue().Remove(RefreshCurrentEntry); // in case it was added
371 GetGame().GetCallqueue().CallLater(RefreshCurrentEntry, ENTRY_INPUT_REFRESH_DELAY, false);
372 }
373
374 //------------------------------------------------------------------------------------------------
376 protected void RefreshCurrentEntry()
377 {
378 if (!m_CurrentEntry.CanRefresh())
379 return;
380
381 float x, y;
382 ScrollLayoutWidget scroll = ScrollLayoutWidget.Cast(m_wPageFrame.FindWidget(SCROLL_NAME)); // a bit ugly?
383 if (scroll)
384 scroll.GetSliderPos(x, y);
385
387
388 if (!scroll)
389 return;
390
391 scroll = ScrollLayoutWidget.Cast(m_wPageFrame.FindWidget(SCROLL_NAME));
392 if (scroll)
393 SetScrollAfterRefresh(scroll, x, y);
394 }
395
396 //------------------------------------------------------------------------------------------------
397 protected void SetScrollAfterRefresh(notnull ScrollLayoutWidget scroll, float x, float y)
398 {
399 float w, h;
400 scroll.GetScreenSize(w, h);
401 if (h <= 0) // ugly, but no other choice as setting scroll right after Widget creation does nothing
402 {
403 GetGame().GetCallqueue().CallLater(SetScrollAfterRefresh, ENTRY_SCROLL_INPUT_REFRESH_DELAY, false, scroll, x, y);
404 }
405 else
406 {
407 GetGame().GetCallqueue().Remove(SetScrollAfterRefresh); // safety, as spam occured
408 scroll.SetSliderPos(x, y);
409 }
410 }
411
412 //------------------------------------------------------------------------------------------------
416 {
417 if (entryId == EFieldManualEntryId.NONE)
418 {
419 SetCurrentEntry(null);
420 return;
421 }
422
424 {
425 if (entry.m_eId == entryId)
426 {
428 SetCurrentEntry(entry);
429 return;
430 }
431 }
432
433 SetCurrentEntry(null);
434 }
435
436 //------------------------------------------------------------------------------------------------
438 protected void SetCurrentEntryByWidget(Widget widget)
439 {
441 if (!entry)
442 return;
443
444 SetCurrentEntry(entry);
445 }
446
447 //------------------------------------------------------------------------------------------------
448 protected void FillEntry_Weapon(notnull Widget widget, notnull SCR_FieldManualConfigEntry_Weapon entry)
449 {
450 Widget weaponRender = widget.FindAnyWidget("weaponRender");
451 if (true /* remove later */ || !FillEntry_Weapon_Render(RenderTargetWidget.Cast(weaponRender), entry.m_sWeaponEntityPath))
452 if (weaponRender)
453 weaponRender.RemoveFromHierarchy();
454
455 FillEntry_Weapon_Statistics(widget.FindAnyWidget("statsLayout"), entry);
456 }
457
458 //------------------------------------------------------------------------------------------------
459 protected bool FillEntry_Weapon_Render(RenderTargetWidget renderTarget, ResourceName weaponResourceName)
460 {
461 if (!renderTarget || !weaponResourceName)
462 return false;
463
464 Resource resource = Resource.Load(weaponResourceName);
465 IEntity entity = GetGame().SpawnEntityPrefabLocal(resource, null, null);
466 if (!entity)
467 return false;
468
469 ChimeraWorld world = ChimeraWorld.CastFrom(GetGame().GetWorld());
470 if (!world)
471 return false;
472
473 ItemPreviewManagerEntity manager = world.GetItemPreviewManager();
474 if (!manager)
475 return false;
476
477 ItemPreviewWidget renderPreview = ItemPreviewWidget.Cast(renderTarget);
478 if (!renderPreview)
479 return false;
480
481 manager.SetPreviewItem(renderPreview, entity);
482 return true;
483 }
484
485 //------------------------------------------------------------------------------------------------
487 {
488 if (!statsLayout)
489 return;
490
491 SCR_FieldManualUI_WeaponStatsHelper weaponStatsHelper = entry.m_WeaponStatsHelper;
492 if (!weaponStatsHelper)
493 {
494 SCR_WidgetHelper.RemoveAllChildren(statsLayout);
495 return;
496 }
497
498 FillEntry_Weapon_Statistics_Mass(statsLayout, weaponStatsHelper);
499 FillEntry_Weapon_Statistics_SightAdjustments(statsLayout, weaponStatsHelper);
500 FillEntry_Weapon_Statistics_DefaultSightAdjustment(statsLayout, weaponStatsHelper);
501 FillEntry_Weapon_Statistics_RateOfFire(statsLayout, weaponStatsHelper);
502 FillEntry_Weapon_Statistics_MuzzleVelocity(statsLayout, weaponStatsHelper);
503 FillEntry_Weapon_Statistics_FireModes(statsLayout, weaponStatsHelper);
504 }
505
506 //------------------------------------------------------------------------------------------------
507 protected void FillEntry_Weapon_Statistics_Mass(notnull Widget statsLayout, notnull SCR_FieldManualUI_WeaponStatsHelper weaponStatsHelper)
508 {
510 if (!statsMass)
511 return;
512
513 float mass = weaponStatsHelper.GetMass();
514 if (mass < 0)
515 statsMass.RemoveWidgetFromHierarchy();
516 else
517 statsMass.SetTranslatedValue("#AR-ValueUnit_Short_Kilograms", mass.ToString(-1, 2));
518 }
519
520 //------------------------------------------------------------------------------------------------
521 protected void FillEntry_Weapon_Statistics_SightAdjustments(notnull Widget statsLayout, notnull SCR_FieldManualUI_WeaponStatsHelper weaponStatsHelper)
522 {
523 SCR_FieldManual_StatisticsLineComponent statsSightAdjustments = SCR_FieldManual_StatisticsLineComponent.GetComponent(statsLayout, "statsSightAdjustments");
524 if (!statsSightAdjustments)
525 return;
526
527 array<int> sightDistanceSettings = weaponStatsHelper.GetSightDistanceSettings();
528 if (!sightDistanceSettings || sightDistanceSettings.IsEmpty())
529 {
530 statsSightAdjustments.RemoveWidgetFromHierarchy();
531 return;
532 }
533
534 array<string> settingsStr = {};
535 foreach (int sightDistanceSetting : sightDistanceSettings)
536 {
537 settingsStr.Insert(WidgetManager.Translate("#AR-ValueUnit_Short_Meters", sightDistanceSetting));
538 }
539
540 statsSightAdjustments.SetValue(ArrayJoin(settingsStr));
541 }
542
543 //------------------------------------------------------------------------------------------------
544 protected void FillEntry_Weapon_Statistics_DefaultSightAdjustment(notnull Widget statsLayout, notnull SCR_FieldManualUI_WeaponStatsHelper weaponStatsHelper)
545 {
546 SCR_FieldManual_StatisticsLineComponent statsDefaultSightAdjustment = SCR_FieldManual_StatisticsLineComponent.GetComponent(statsLayout, "statsDefaultSightAdjustment");
547 if (!statsDefaultSightAdjustment)
548 return;
549
550 int defaultSightDistanceSetting = weaponStatsHelper.GetDefaultSightDistanceSetting();
551 if (defaultSightDistanceSetting < 0)
552 statsDefaultSightAdjustment.RemoveWidgetFromHierarchy();
553 else
554 statsDefaultSightAdjustment.SetTranslatedValue("#AR-ValueUnit_Short_Meters", defaultSightDistanceSetting.ToString());
555 }
556
557 //------------------------------------------------------------------------------------------------
558 protected void FillEntry_Weapon_Statistics_RateOfFire(notnull Widget statsLayout, notnull SCR_FieldManualUI_WeaponStatsHelper weaponStatsHelper)
559 {
561 if (!statsRateOfFire)
562 return;
563
564 if (weaponStatsHelper.GetRateOfFire() < 1)
565 statsRateOfFire.RemoveWidgetFromHierarchy();
566 else
567 statsRateOfFire.SetTranslatedValue("#AR-ValueUnit_Short_RoundsPerMinute", weaponStatsHelper.GetRateOfFire().ToString());
568 }
569
570 //------------------------------------------------------------------------------------------------
571 protected void FillEntry_Weapon_Statistics_MuzzleVelocity(notnull Widget statsLayout, notnull SCR_FieldManualUI_WeaponStatsHelper weaponStatsHelper)
572 {
573 SCR_FieldManual_StatisticsLineComponent statsMuzzleVelocity = SCR_FieldManual_StatisticsLineComponent.GetComponent(statsLayout, "statsMuzzleVelocity");
574 if (!statsMuzzleVelocity)
575 return;
576
577 if (weaponStatsHelper.m_iMuzzleVelocity < 1)
578 statsMuzzleVelocity.RemoveWidgetFromHierarchy();
579 else
580 statsMuzzleVelocity.SetTranslatedValue("#AR-ValueUnit_Short_MetersPerSeconds", weaponStatsHelper.m_iMuzzleVelocity.ToString());
581 }
582
583 //------------------------------------------------------------------------------------------------
584 protected void FillEntry_Weapon_Statistics_FireModes(notnull Widget statsLayout, notnull SCR_FieldManualUI_WeaponStatsHelper weaponStatsHelper)
585 {
587 if (!statsFireModes)
588 return;
589
590 array<string> fireModes = weaponStatsHelper.GetFireModes();
591 if (!fireModes || fireModes.IsEmpty())
592 statsFireModes.RemoveWidgetFromHierarchy();
593 else
594 statsFireModes.SetValue(ArrayJoin(fireModes));
595 }
596
597 //------------------------------------------------------------------------------------------------
599 // TODO: break down in smaller methods?
600 protected void SetAllEntriesAndParents()
601 {
602 m_aAllEntries.Clear();
603 array<SCR_FieldManualConfigCategory> categoriesToRemove = {};
604 array<SCR_FieldManualConfigCategory> subCategoriesToRemove = {};
605 array<SCR_FieldManualConfigEntry> entriesToRemove = {};
606 foreach (SCR_FieldManualConfigCategory category : m_ConfigRoot.m_aCategories)
607 {
608 if (!category.m_bEnabled)
609 {
610 categoriesToRemove.Insert(category);
611 continue;
612 }
613
614 subCategoriesToRemove.Clear();
615 foreach (SCR_FieldManualConfigCategory subCategory : category.m_aCategories) // only two levels are supported by the UI for now
616 {
617 if (!subCategory.m_bEnabled)
618 {
619 subCategoriesToRemove.Insert(subCategory);
620 continue;
621 }
622
623 entriesToRemove.Clear();
624 foreach (SCR_FieldManualConfigEntry entry : subCategory.m_aEntries)
625 {
626 if (!entry.m_bEnabled || entry.m_aContent.IsEmpty())
627 {
628 entriesToRemove.Insert(entry);
629 continue;
630 }
631
632 entry.m_Parent = subCategory;
633 m_aAllEntries.Insert(entry);
634 }
635
636 foreach (SCR_FieldManualConfigEntry entry : entriesToRemove)
637 {
638 subCategory.m_aEntries.RemoveItemOrdered(entry);
639 }
640
641 if (subCategory.m_aEntries.IsEmpty() && subCategory.m_aCategories.IsEmpty())
642 {
643 subCategoriesToRemove.Insert(subCategory);
644 continue;
645 }
646
647 subCategory.m_Parent = category;
648 }
649
650 foreach (SCR_FieldManualConfigCategory subCategory : subCategoriesToRemove)
651 {
652 category.m_aCategories.RemoveItemOrdered(subCategory);
653 }
654
655 if (category.m_aEntries.IsEmpty() && category.m_aCategories.IsEmpty())
656 categoriesToRemove.Insert(category);
657 }
658
659 foreach (SCR_FieldManualConfigCategory category : categoriesToRemove)
660 {
661 m_ConfigRoot.m_aCategories.RemoveItemOrdered(category);
662 }
663 }
664
665 //------------------------------------------------------------------------------------------------
668 {
669 if (!m_ConfigRoot || !m_ConfigRoot.m_aCategories || !m_wMenuCategoryList)
670 return;
671
674 SCR_WidgetHelper.RemoveAllChildren(m_wMenuCategoryList);
675
676 if (m_wMenuTitle)
677 m_wMenuTitle.SetText(m_ConfigRoot.m_sTitle);
678
679 Widget subCategoryWidget;
680 ButtonWidget button;
681 foreach (SCR_FieldManualConfigCategory category : m_ConfigRoot.m_aCategories)
682 {
683 category.CreateWidget(m_wMenuCategoryList);
684
685 foreach (SCR_FieldManualConfigCategory subCategory : category.m_aCategories)
686 {
687 subCategoryWidget = subCategory.CreateWidget(m_wMenuCategoryList);
688 button = ButtonWidget.Cast(subCategoryWidget);
689 if (button)
690 {
691 button.AddHandler(m_SubCategoryButtonEventHandler);
692 m_mWidgetSubCategoryMap.Insert(button, subCategory);
693
696 }
697 }
698 }
699 }
700
701 //------------------------------------------------------------------------------------------------
703 protected void OpenFirstSubCategory()
704 {
706 GetGame().GetCallqueue().CallLater(GetGame().GetWorkspace().SetFocusedWidget, 0, false, m_wFirstSubCategoryButton, false);
707 }
708
709 //------------------------------------------------------------------------------------------------
712 {
714 GetGame().GetCallqueue().CallLater(FocusLastSelectedEntry, 0, false, m_wLastSelectedWidget, false);
715 }
716
717 //------------------------------------------------------------------------------------------------
719 protected void FocusLastSelectedEntry(Widget w = null)
720 {
721 if (w)
723
725 GetGame().GetWorkspace().SetFocusedWidget(m_wLastSelectedWidget);
726 }
727
728 //------------------------------------------------------------------------------------------------
730 // used in SCR_FieldManualSubCategoryScriptedWidgetEventHandler.OnClick
731 protected void ResetLastSearch()
732 {
733 m_sLastSearch = string.Empty;
734 }
735
736 //------------------------------------------------------------------------------------------------
738 protected void ProcessSearch(SCR_EditBoxSearchComponent searchbox, string search)
739 {
740 search = search.Trim();
741
742 if (search.IsEmpty())
743 {
747
748 return;
749 }
750
753
755
756 if (!m_bArmaWarning && search.Contains("ArmA"))
757 {
758 m_bArmaWarning = true;
759
761 m_BreadCrumbsComponent.Set("#AR-FieldManual_Page_EasterEgg_ArmA_BreadCrumbs");
762
764 ArmaEntry.m_sTitle = "#AR-FieldManual_Page_EasterEgg_ArmA_Title";
766 ArmaPiece.m_sText = "#AR-FieldManual_Page_EasterEgg_ArmA_Text";
767 ArmaEntry.m_aContent.Insert(ArmaPiece);
768 SetCurrentEntry(ArmaEntry);
769
770 EditBoxWidget searchEditBox = EditBoxWidget.Cast(GetRootWidget().FindAnyWidget("Searchbar").FindAnyWidget("EditBox"));
771 string searchText = searchEditBox.GetText();
772 searchText.Replace("ArmA", "Arma");
773 searchEditBox.SetText(searchText);
774
776
777 return;
778 }
779
780 m_bIsInSearchMode = true;
781
782 string originalSearch = search;
783 search.ToLower();
784 if (search == m_sLastSearch)
785 return;
786
787 m_sLastSearch = search;
788
789 array<ref SCR_FieldManualConfigEntry> entries = {};
790
791 if (!m_sLastSearch.IsEmpty())
792 {
793 array<int> indexList = {};
794
795 array<string> allEntriesKeys = {};
797 {
798 allEntriesKeys.Insert(entry.m_sTitle);
799 }
800
801 WidgetManager.SearchLocalized(m_sLastSearch, allEntriesKeys, indexList);
802
803 foreach (int index : indexList)
804 {
805 entries.Insert(m_aAllEntries.Get(index));
806 }
807 }
808
810 {
811 if (entries.IsEmpty())
812 m_BreadCrumbsComponent.SetRichFormat(SEARCH_NO_RESULT_KEY, originalSearch);
813 else
814 m_BreadCrumbsComponent.SetRichFormat(SEARCH_RESULT_KEY, originalSearch, entries.Count().ToString());
815 }
816
817 SetTiles(entries);
818 }
819
820 //------------------------------------------------------------------------------------------------
822 protected void CloseReadingPanel()
823 {
824 SetCurrentEntry(null);
825 }
826
827 //------------------------------------------------------------------------------------------------
831 protected void CloseMenuOrReadingPanel()
832 {
835 else
836 Close();
837 }
838
839 //------------------------------------------------------------------------------------------------
842 {
844 m_wLoadingServerQueue.SetVisible(true);
845 }
846
847 //------------------------------------------------------------------------------------------------
850 {
852 m_wLoadingServerQueue.SetVisible(false);
853 }
854
855 //------------------------------------------------------------------------------------------------
856 //----- STATIC METHODS
857 //------------------------------------------------------------------------------------------------
858
859 //------------------------------------------------------------------------------------------------
862 {
863 SCR_FieldManualUI ui = SCR_FieldManualUI.Cast(GetGame().GetMenuManager().OpenMenu(ChimeraMenuPreset.FieldManualDialog));
864 ui.OpenEntry(entryId);
865 return ui;
866 }
867
868 //------------------------------------------------------------------------------------------------
869 //----- my little helper!
870 //------------------------------------------------------------------------------------------------
872 protected static string ArrayJoin(notnull array<string> entries)
873 {
874 int count = entries.Count();
875 switch (count)
876 {
877 case 0: return "-";
878 case 1: return entries[0];
879 case 2: return WidgetManager.Translate("#AR-General_List_Short_2", entries[0], entries[1]);
880 case 3: return WidgetManager.Translate("#AR-General_List_Short_3", entries[0], entries[1], entries[2]);
881 case 4: return WidgetManager.Translate("#AR-General_List_Short_4", entries[0], entries[1], entries[2], entries[3]);
882 case 5: return WidgetManager.Translate("#AR-General_List_Short_5", entries[0], entries[1], entries[2], entries[3], entries[4]);
883 }
884 Print(string.Format("Too many list entries to join as a string - missing #AR-General_List_Short_%1 translation?", count), LogLevel.WARNING);
885 return WidgetManager.Translate("#AR-General_List_Short_5", entries[0], entries[1], entries[2], entries[3], entries[4]);
886 }
887
888 //------------------------------------------------------------------------------------------------
889 //----- CONSTRUCTOR / DESTRUCTOR
890 //------------------------------------------------------------------------------------------------
891
892 //------------------------------------------------------------------------------------------------
893 // constructor
895 {
896 m_aAllEntries = {};
899
900 ScriptInvoker inputDeviceIsGamepadInvoker = GetGame().OnInputDeviceIsGamepadInvoker();
901 if (inputDeviceIsGamepadInvoker)
902 inputDeviceIsGamepadInvoker.Insert(QueueRefreshCurrentEntry);
903 }
904
905 //------------------------------------------------------------------------------------------------
906 // destructor
908 {
909 ScriptInvoker inputDeviceIsGamepadInvoker = GetGame().OnInputDeviceIsGamepadInvoker();
910 if (inputDeviceIsGamepadInvoker)
911 inputDeviceIsGamepadInvoker.Remove(QueueRefreshCurrentEntry);
912 }
913}
ChimeraMenuPreset
Menu presets.
EFieldManualEntryId
used to grab the first id-matching Field Manual entry
ArmaReforgerScripted GetGame()
Definition game.c:1398
SCR_DestructionSynchronizationComponentClass ScriptComponentClass int index
Widget GetRootWidget()
proto native void Close()
Input management system for user interactions.
override void OnMenuClose()
Object holding reference to resource. In destructor release the resource.
Definition Resource.c:25
void SetBackgroundImage(ResourceName imageName)
static SCR_FieldManual_StatisticsLineComponent GetComponent(notnull Widget parentWidget, string widgetName)
void SetTranslatedValue(string value, string parameter1="")
Widget CreateWidget(notnull Widget parent)
To be overridden by child classes to call CreateWidgetFromLayout.
void OpenEntry(EFieldManualEntryId entryId)
void SetTiles(array< ref SCR_FieldManualConfigEntry > entries)
sets main Field Manual grid tiles from entries
static SCR_FieldManualUI Open(EFieldManualEntryId entryId)
opens the first entry matching the EFieldManualEntryId enum value
override void OnMenuShow()
Widget CreateTileWidget(notnull SCR_FieldManualConfigEntry entry, notnull Widget parent)
creates a tile and sets its image, background & text
void SetScrollAfterRefresh(notnull ScrollLayoutWidget scroll, float x, float y)
static const string SEARCH_RESULT_KEY
ScrollLayoutWidget m_wGridScrollLayoutWidget
void FocusLastSelectedEntry(Widget w=null)
Focus the last selected valid widget.
void FillEntry_Weapon_Statistics_Mass(notnull Widget statsLayout, notnull SCR_FieldManualUI_WeaponStatsHelper weaponStatsHelper)
ref array< ref SCR_FieldManualConfigEntry > m_aAllEntries
void RefreshCurrentEntry()
Re-creates the current entry (called by callqueue added in QueueRefreshCurrentEntry).
void OnSubCategoryClicked(Widget w)
void FillEntry_Weapon_Statistics_MuzzleVelocity(notnull Widget statsLayout, notnull SCR_FieldManualUI_WeaponStatsHelper weaponStatsHelper)
override void OnMenuHide()
ref map< Widget, ref SCR_FieldManualConfigCategory > m_mWidgetSubCategoryMap
void SetTilesByWidget(Widget widget)
sets entry tiles from a sub-category's widget
void ProcessSearch(SCR_EditBoxSearchComponent searchbox, string search)
the search process itself - finds entries and set tiles
void SetAllEntriesAndParents()
one-time call that goes through all categories and entries and adds enabled entries to a one-level ar...
void HideQueueMessage()
Hide the Server Queue.
ref SCR_FieldManualEntryScriptedWidgetEventHandler m_EntryButtonEventHandler
void CloseReadingPanel()
closes the reading panel (sets the current entry to null)
SCR_BreadCrumbsComponent m_BreadCrumbsComponent
VerticalLayoutWidget m_wMenuCategoryList
void SetCurrentEntry(SCR_FieldManualConfigEntry entry)
Sets the current entry to read - can be null (leave reading mode) or any SCR_FieldManualConfigEntry.
void OpenLastSelectedSubCategory()
Open the last selected Sub Category and selected it.
void ShowQueueMessage()
Show the Server Queue.
SCR_FieldManualConfigEntry m_CurrentEntry
static const int ENTRY_INPUT_REFRESH_DELAY
ButtonWidget m_wFirstSubCategoryButton
void FillEntry_Weapon(notnull Widget widget, notnull SCR_FieldManualConfigEntry_Weapon entry)
static const int TILES_GRID_WIDTH
void FillEntry_Weapon_Statistics_FireModes(notnull Widget statsLayout, notnull SCR_FieldManualUI_WeaponStatsHelper weaponStatsHelper)
void FillEntry_Weapon_Statistics_DefaultSightAdjustment(notnull Widget statsLayout, notnull SCR_FieldManualUI_WeaponStatsHelper weaponStatsHelper)
void OnTileClicked(Widget w)
void FillEntry_Weapon_Statistics_RateOfFire(notnull Widget statsLayout, notnull SCR_FieldManualUI_WeaponStatsHelper weaponStatsHelper)
static const string SEARCH_NO_RESULT_KEY
bool FillEntry_Weapon_Render(RenderTargetWidget renderTarget, ResourceName weaponResourceName)
TextWidget m_wPageEntryTitle
GridLayoutWidget m_wMenuGridLayout
static const int ENTRY_SCROLL_INPUT_REFRESH_DELAY
void ResetLastSearch()
resets last search value
SCR_InputButtonComponent m_MenuBtnBack
void QueueRefreshCurrentEntry()
Add current entry's refresh to callqueue (used by KBM/Gamepad switching event).
static const string SCROLL_NAME
SCR_EditBoxSearchComponent m_MenuSearchbar
void FillEntry_Weapon_Statistics(Widget statsLayout, SCR_FieldManualConfigEntry_Weapon entry)
bool FlipButtonState(Widget w, bool state)
void CreateCategoryMenuWidgets()
Create main categories buttons list.
static string ArrayJoin(notnull array< string > entries)
joins strings with a stringtable separator - from 0 to 5 entries
void OpenFirstSubCategory()
Open the first sub-category, showing its entries.
void FillEntry_Weapon_Statistics_SightAdjustments(notnull Widget statsLayout, notnull SCR_FieldManualUI_WeaponStatsHelper weaponStatsHelper)
void SetCurrentEntryByWidget(Widget widget)
sets the read entry linked from that widget
ref SCR_FieldManualConfigRoot m_ConfigRoot
ref map< Widget, ref SCR_FieldManualConfigEntry > m_mWidgetEntryMap
override void OnMenuOpen()
ref SCR_FieldManualSubCategoryScriptedWidgetEventHandler m_SubCategoryButtonEventHandler
static SCR_InputButtonComponent GetInputButtonComponent(string name, notnull Widget parent, bool searchAllChildren=true)
Definition Types.c:486
proto void Print(void var, LogLevel level=LogLevel.NORMAL)
Prints content of variable to console/log.
LogLevel
Enum with severity of the logging message.
Definition LogLevel.c:14
EActionTrigger
ScriptInvokerBase< func > ScriptInvoker
Definition tools.c:134