8 protected const int OPEN_DELAY = 200;
15 protected string m_sOpenSound;
18 protected string m_sCloseSound;
21 protected string m_sSelectionSound;
24 protected string m_sPerformSound;
27 protected string m_sEnterCategorySound;
30 protected string m_sLeaveCategorySound;
35 protected ref array<ref SCR_SelectionMenuEntry> m_aRootEntries = {};
36 protected ref array<ref SCR_SelectionMenuEntry> m_aEntries = {};
38 protected int m_iSelectedEntryId;
41 protected bool m_bOpened;
42 protected bool m_bEntryPerformed;
43 protected bool m_bUsingAlternativeToggle;
44 protected bool m_bClosingMenu;
45 protected bool m_bOpenedForTime;
48 protected ref array<SCR_SelectionMenuCategoryEntry> m_aSelectedCategories = {};
51 protected ref ScriptInvoker<SCR_SelectionMenu> m_OnBeforeOpen;
52 protected ref ScriptInvoker<SCR_SelectionMenu> m_OnOpen;
53 protected ref ScriptInvoker<SCR_SelectionMenu> m_OnClose;
54 protected ref ScriptInvoker<SCR_SelectionMenu, SCR_SelectionMenuEntry, int> m_OnSelect;
55 protected ref ScriptInvoker<SCR_SelectionMenu, SCR_SelectionMenuEntry> m_OnPerform;
56 protected ref ScriptInvoker<SCR_SelectionMenu, SCR_SelectionMenuCategoryEntry, int> m_OnOpenCategory;
58 protected ref ScriptInvoker<SCR_SelectionMenu, SCR_SelectionMenuEntry> m_OnAddEntry;
59 protected ref ScriptInvoker<SCR_SelectionMenu, SCR_SelectionMenuEntry> m_OnRemoveEntry;
60 protected ref ScriptInvoker<SCR_SelectionMenu, array<ref SCR_SelectionMenuEntry>> m_OnUpdateEntries;
62 protected ref ScriptInvoker<SCR_SelectionMenu, SCR_SelectionMenuControllerInputs> m_OnControllerChanged;
65 protected void InvokeOnBeforeOpen()
68 m_OnBeforeOpen.Invoke(
this);
72 ScriptInvoker GetOnBeforeOpen()
75 m_OnBeforeOpen =
new ScriptInvoker();
77 return m_OnBeforeOpen;
81 protected void InvokeOnOpen()
84 m_OnOpen.Invoke(
this);
88 ScriptInvoker GetOnOpen()
91 m_OnOpen =
new ScriptInvoker();
97 protected void InvokeOnClose()
100 m_OnClose.Invoke(
this);
104 ScriptInvoker GetOnClose()
107 m_OnClose =
new ScriptInvoker();
116 m_OnSelect.Invoke(
this, entry,
id);
120 ScriptInvoker GetOnSelect()
123 m_OnSelect =
new ScriptInvoker();
132 m_OnPerform.Invoke(
this, entry);
136 ScriptInvoker GetOnPerform()
139 m_OnPerform =
new ScriptInvoker();
147 if (m_OnOpenCategory)
148 m_OnOpenCategory.Invoke(
this, entry, level);
152 ScriptInvoker GetOnOpenCategory()
154 if (!m_OnOpenCategory)
155 m_OnOpenCategory =
new ScriptInvoker();
157 return m_OnOpenCategory;
164 m_OnAddEntry.Invoke(
this, entry);
168 ScriptInvoker GetOnAddEntry()
171 m_OnAddEntry =
new ScriptInvoker();
180 m_OnRemoveEntry.Invoke(
this, entry);
184 ScriptInvoker GetOnRemoveEntry()
186 if (!m_OnRemoveEntry)
187 m_OnRemoveEntry =
new ScriptInvoker();
189 return m_OnRemoveEntry;
193 protected void InvokeOnUpdateEntries(array<ref SCR_SelectionMenuEntry> entries)
195 if (m_OnUpdateEntries)
196 m_OnUpdateEntries.Invoke(
this, entries);
200 ScriptInvoker GetOnUpdateEntries()
202 if (!m_OnUpdateEntries)
203 m_OnUpdateEntries =
new ScriptInvoker();
205 return m_OnUpdateEntries;
211 if (m_OnControllerChanged)
212 m_OnControllerChanged.Invoke(
this, inputs);
216 ScriptInvoker GetOnControllerChanged()
218 if (!m_OnControllerChanged)
219 m_OnControllerChanged =
new ScriptInvoker();
221 return m_OnControllerChanged;
231 InvokeOnBeforeOpen();
234 if (m_ControllerInputs.m_bPreventEmptyMenuOpen &&
m_aEntries.IsEmpty())
241 m_bEntryPerformed =
false;
242 m_bClosingMenu =
false;
243 m_bUsingAlternativeToggle =
false;
246 m_bOpenedForTime =
false;
248 if (!m_ControllerInputs.m_sToggleActionAlternative.IsEmpty())
249 GetGame().GetCallqueue().CallLater(AllowClosing, OPEN_DELAY);
254 if (m_ControllerInputs.m_bOpenInRoot)
260 PlaySound(m_sOpenSound);
263 GetGame().GetCallqueue().CallLater(UpdateEntries);
268 protected void AllowClosing()
271 m_bOpenedForTime =
true;
274 if (m_bClosingMenu && !m_bUsingAlternativeToggle)
280 m_bClosingMenu =
false;
285 protected void OnOpen(){}
291 m_bClosingMenu =
true;
293 if (!m_bOpenedForTime)
297 if (m_ControllerInputs && m_ControllerInputs.m_bPerformOnClose && m_SelectedEntry && !m_bEntryPerformed)
298 PerformEntry(m_SelectedEntry);
301 m_bUsingAlternativeToggle =
false;
306 if (!m_bEntryPerformed || !m_SelectedEntry)
307 PlaySound(m_sCloseSound);
312 protected void OnClose(){}
315 void Update(
float timeSlice)
319 GetGame().GetInputManager().ActivateContext(m_Inputs.m_sContext);
321 if (m_ControllerInputs)
322 GetGame().GetInputManager().ActivateContext(m_ControllerInputs.m_sControllerContext);
329 protected void OnUpdate(
float timeSlice){}
338 protected void PlaySound(
string sound)
340 if (!sound.IsEmpty())
350 protected void SelectEntry() {}
355 if (!entry.IsEnabled())
366 m_bEntryPerformed =
true;
368 if (m_ControllerInputs.m_bCloseOnPerform)
382 PlaySound(m_sPerformSound);
384 InvokeOnPerform(entry);
387 m_bEntryPerformed =
false;
396 m_aSelectedCategories.Insert(
category);
401 for (
int i = 0, count =
category.GetEntries().Count(); i < count; i++)
407 InvokeOnOpenCategory(
category, m_aSelectedCategories.Count());
408 InvokeOnUpdateEntries(
category.GetEntries());
410 PlaySound(m_sEnterCategorySound);
414 protected void LeaveCategory()
420 m_aSelectedCategories.RemoveItem(
category);
429 array<ref SCR_SelectionMenuEntry> catEntries =
category.GetEntries();
432 for (
int i = 0, count = catEntries.Count(); i < count; i++)
440 for (
int i = 0, count = m_aRootEntries.Count(); i < count; i++)
446 InvokeOnOpenCategory(
category, m_aSelectedCategories.Count());
449 PlaySound(m_sLeaveCategorySound);
454 protected void OpenInRoot()
456 m_aSelectedCategories.Clear();
459 for (
int i = 0, count = m_aRootEntries.Count(); i < count; i++)
464 InvokeOnOpenCategory(
null, 0);
476 m_aRootEntries.Insert(newEntry);
480 m_aRootEntries.Insert(entry);
483 if (!CurrentCategory())
486 InvokeOnAddEntry(entry);
506 void AddEntries(notnull array<ref SCR_SelectionMenuEntry> entries,
bool replace =
false)
511 m_aRootEntries.Clear();
513 if (!CurrentCategory())
518 for (
int i = 0, count = entries.Count(); i < count; i++)
520 AddEntry(entries[i]);
523 if (!CurrentCategory())
544 void UpdateSelectedEntries(notnull array<ref SCR_SelectionMenuEntry> entries)
546 InvokeOnUpdateEntries(entries);
559 m_aRootEntries.RemoveItem(entry);
562 if (!CurrentCategory())
573 m_aRootEntries.Clear();
576 if (!CurrentCategory())
588 if (m_aSelectedCategories.IsEmpty())
591 return m_aSelectedCategories[m_aSelectedCategories.Count() - 1];
601 display.SetupMenu(
this);
610 protected void AddActionListeners()
612 if (m_ControllerInputs.m_bCloseOnReleaseOpen)
613 GetGame().GetInputManager().AddActionListener(m_ControllerInputs.m_sOpenAction, EActionTrigger.UP, OnOpenInputRelease);
615 if (!m_ControllerInputs.m_sToggleActionAlternative.IsEmpty())
616 GetGame().GetInputManager().AddActionListener(m_ControllerInputs.m_sToggleActionAlternative, EActionTrigger.DOWN, OnAlternativeToggleInput);
618 if (!m_Inputs.m_sPerformAction.IsEmpty())
619 GetGame().GetInputManager().AddActionListener(m_Inputs.m_sPerformAction, EActionTrigger.DOWN, OnPerformInput);
621 if (!m_Inputs.m_sBackAction.IsEmpty())
622 GetGame().GetInputManager().AddActionListener(m_Inputs.m_sBackAction, EActionTrigger.DOWN, OnBackInput);
627 protected void RemoveActionListeners()
629 if (!m_ControllerInputs || !m_Inputs)
632 GetGame().GetInputManager().RemoveActionListener(m_ControllerInputs.m_sOpenAction, EActionTrigger.UP, OnOpenInputRelease);
633 GetGame().GetInputManager().RemoveActionListener(m_ControllerInputs.m_sToggleActionAlternative, EActionTrigger.DOWN, OnAlternativeToggleInput);
634 GetGame().GetInputManager().RemoveActionListener(m_Inputs.m_sPerformAction, EActionTrigger.DOWN, OnPerformInput);
635 GetGame().GetInputManager().RemoveActionListener(m_Inputs.m_sBackAction, EActionTrigger.DOWN, OnBackInput);
640 protected void OnOpenInputRelease(
float value, EActionTrigger reason)
642 if (m_bUsingAlternativeToggle)
650 protected void OnPerformInput()
653 PerformEntry(m_SelectedEntry);
657 protected void OnBackInput()
660 m_SelectedEntry =
null;
663 if (CurrentCategory())
675 protected void OnAlternativeToggleInput()
677 m_bUsingAlternativeToggle =
true;
695 controls.m_Owner = owner;
697 if (m_ControllerInputs != controls)
698 InvokeOnControllerChanged(controls);
700 m_ControllerInputs = controls;
706 return m_ControllerInputs;
712 return m_SelectedEntry;
716 int GetSelectedEntryId()
718 return m_iSelectedEntryId;
722 bool GetEntryPerformed()
724 return m_bEntryPerformed;
728 array<ref SCR_SelectionMenuEntry> GetEntries()
730 array<ref SCR_SelectionMenuEntry> entries = {};
732 for (
int i = 0, count =
m_aEntries.Count(); i < count; i++)
752 return m_Display !=
null;
760 protected void DebugPrint(
string method,
string msg)
762 Print(
string.Format(
"[SCR_SelectionMenu] - %1() - '%2'", method, msg), LogLevel.DEBUG);
773 [
Attribute(
"",
desc:
"Input context used for menu controls")]
776 [
Attribute(
"",
desc:
"Action used for closing menu or moving back between the layers")]
777 string m_sBackAction;
779 [
Attribute(
"",
desc:
"Input action used for performing selected entry")]
780 string m_sPerformAction;
798 [
Attribute(
"",
desc:
"Input context used for extra menu controls from controller entity")]
799 string m_sControllerContext;
801 [
Attribute(
"",
desc:
"Action for opening (and closing) radial menu")]
802 string m_sOpenAction;
804 [
Attribute(
"",
desc:
"Alternative action for always toggling menu")]
805 string m_sToggleActionAlternative;
807 [
Attribute(
"1",
desc:
"If this field is checked - Menu is closed if open input is released. Otherwise separate close input has to be used")]
808 bool m_bCloseOnReleaseOpen;
810 [
Attribute(
"1",
desc:
"If this field is checked - Perform entry(call entry action) when closing menu and having selected entry")]
811 bool m_bPerformOnClose;
813 [
Attribute(
"0",
desc:
"If this field is checked - Close the menu after performing the entry (selecting enabled entry)")]
814 bool m_bCloseOnPerform;
816 [
Attribute(
"1",
desc:
"Checked - on opening menu is always filled with root entries. Otherwise menu will stay in last category.")]
819 [
Attribute(
"0",
desc:
"If checked, menu won't open if there are no entries in the menu")]
820 bool m_bPreventEmptyMenuOpen;
822 [
Attribute(
"1", UIWidgets.Slider,
desc:
"Unchecked will prevent opening of radial menu while character is unconcious.")]
823 bool m_bShowWhileUnconcious;
826 void SCR_SelectionMenuOpening(
string openAction =
"")
828 if (!openAction.IsEmpty())
829 m_sOpenAction = openAction;
834 bool IsControllingMenu(IEntity controller)
848 protected ref array<ref SCR_SelectionMenuEntry> m_aEntries;
851 array<ref SCR_SelectionMenuEntry> GetEntries()
853 array<ref SCR_SelectionMenuEntry> entries = {};
855 for (
int i = 0, count =
m_aEntries.Count(); i < count; i++)
872 [
Attribute(
"-1",
desc:
"Adjust how final render preview size should be big by current icon size multiplicaiton")]
873 float m_fIconSizeXMultiplier;
875 [
Attribute(
desc:
"If true colorize item shadow in Radial Menu to medical color")]
876 bool m_bShowMedicalColor;