Arma Reforger Explorer  1.1.0.42
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
SCR_BaseContextMenuEditorUIComponent.c
Go to the documentation of this file.
1 //------------------------------------------------------------------------------------------------
3 {
4  [Attribute("", UIWidgets.ResourceNamePicker, "Button", "layout")]
5  protected ResourceName m_ButtonPath;
6 
7  [Attribute("VLayout", UIWidgets.EditBox)]
8  protected string m_VLayoutWidgetName;
9 
10  [Attribute("BottomBar")]
11  protected string m_sBottomBarName;
12 
13  [Attribute("250", desc: "Screen width of the button prefab")]
14  protected int m_ButtonPrefabSizeX;
15  [Attribute("34", desc: "Screen height of the button prefab")]
16  protected int m_ButtonPrefabSizeY;
17 
18  [Attribute("4")]
19  protected float m_fMenuMouseOffsetX;
20 
21  [Attribute("0.025", "Fade delay in seconds. For every new button that is added the delay increases slightly")]
22  protected float m_fFadeDelayNextButton;
23 
24  [Attribute("4", "How fast each button appears")]
25  protected float m_fButtonFadeSpeed;
26 
27  protected InputManager m_InputManager;
28  protected WorkspaceWidget m_WorkSpace;
29 
30  protected Widget m_ContextMenu;
31  protected Widget m_VLayout;
32  protected SCR_FadeUIComponent m_BottomBarFadeUI;
33 
34  protected vector m_MouseDownScreenPos;
35  protected vector m_MouseDownWorldPos;
36 
37  protected ref map<Widget, SCR_BaseEditorAction> m_ButtonActions = new map<Widget, SCR_BaseEditorAction>;
38 
39  protected SCR_BaseActionsEditorComponent m_EditorActionsComponent;
40  protected SCR_EditorManagerEntity m_EditorManager;
41  protected SCR_CursorEditorUIComponent m_CursorComponent;
42  protected SCR_MouseAreaEditorUIComponent m_MouseArea;
43 
44  protected int m_ActionFlagsOnOpen;
45 
46  protected ref ScriptInvoker m_OnContextMenuToggle = new ScriptInvoker();
47 
48  void CloseContextMenu()
49  {
50  if (m_ContextMenu) m_ContextMenu.SetVisible(false);
51  if (m_WorkSpace) m_WorkSpace.SetFocusedWidget(null);
52 
53  m_OnContextMenuToggle.Invoke(false);
54  }
55  ScriptInvoker GetOnContextMenuToggle()
56  {
57  return m_OnContextMenuToggle;
58  }
59 
60  protected void OnInputDeviceIsGamepad(bool isGamepad)
61  {
62  CloseContextMenu();
63  }
64 
65  protected void PopulateContextMenu(vector cursorWorldPosition)
66  {
67  array<ref SCR_EditorActionData> actions = {};
68  m_EditorActionsComponent.GetAndEvaluateActions(cursorWorldPosition, actions, m_ActionFlagsOnOpen);
69  m_BottomBarFadeUI.GetFadeWidget().SetVisible(false);
70 
71  float fadeDelay = 0;
72 
73  Widget lastButtonLayout;
74 
75  // Add Context Action buttons
76  for (int i = 0; i < actions.Count(); i++)
77  {
78  SCR_BaseEditorAction action = actions[i].GetAction();
79 
80  // Don't show actions in context menu that can't be performed
81  bool canBePerformed = actions[i].GetCanBePerformed();
82  if (!canBePerformed)
83  continue;
84 
85  SCR_UIInfo info = action.GetInfo();
86  // Create button layout
87  Widget buttonLayout = m_WorkSpace.CreateWidgets(m_ButtonPath, m_VLayout);
88  lastButtonLayout = buttonLayout;
89 
91 
92  ButtonActionComponent.GetOnAction(buttonLayout).Insert(OnContextMenuOptionClicked);
93 
94  contextMenuButtonComponent.SetData(info, action.GetShortcut(), canBePerformed);
95 
96  SCR_LinkTooltipTargetEditorUIComponent.SetInfo(buttonLayout, info, action);
97 
98  m_ButtonActions.Set(buttonLayout, action);
99 
100  SCR_FadeUIComponent fadeComponent = SCR_FadeUIComponent.Cast(buttonLayout.FindHandler(SCR_FadeUIComponent));
101  if (fadeComponent)
102  {
103  fadeComponent.SetFadeInSpeed(m_fButtonFadeSpeed);
104  fadeComponent.DelayedFadeIn(fadeDelay * 1000, true);
105  fadeDelay += m_fFadeDelayNextButton;
106  }
107  }
108 
109  // Hide the divider for lastButtonLayout
110  if (lastButtonLayout)
111  {
112  Widget divider = lastButtonLayout.FindAnyWidget("Stripe");
113 
114  if (divider)
115  divider.SetVisible(false);
116  }
117 
118 
119  if (m_BottomBarFadeUI)
120  m_BottomBarFadeUI.DelayedFadeIn(fadeDelay * 1000, true);
121  }
122 
123  bool IsContextMenuOpen()
124  {
125  return m_ContextMenu != null && m_ContextMenu.IsVisibleInHierarchy();
126  }
127 
128  protected void OpenContextMenu()
129  {
130  if (!m_InputManager.IsUsingMouseAndKeyboard() || !m_EditorActionsComponent)
131  {
132  return;
133  }
134 
135  // Remove existing button widgets
136  RemoveButtonWidgets();
137 
138  m_MouseDownWorldPos = GetCursorWorldPos();
139 
140  PopulateContextMenu(m_MouseDownWorldPos);
141 
142  // Get context menu size and screen size
143  float contextMenuWidth, contextMenuHeight, screenWidth, screenHeight;
144  m_WorkSpace.GetScreenSize(screenWidth, screenHeight);
145 
146  // Convert to reference resolution
147  screenWidth = m_WorkSpace.DPIUnscale(screenWidth);
148  screenHeight = m_WorkSpace.DPIUnscale(screenHeight);
149 
150  contextMenuHeight = m_ButtonActions.Count() * m_ButtonPrefabSizeY;
151  contextMenuWidth = m_ButtonPrefabSizeX;
152 
153 
154 
155  // If context menu goes offscreen, move to other side of cursor for both x and y
156  if (m_MouseDownScreenPos[0] + contextMenuWidth > screenWidth)
157  {
158  m_MouseDownScreenPos[0] = (m_MouseDownScreenPos[0]) - (contextMenuWidth + m_fMenuMouseOffsetX);
159  }
160  else
161  {
162  m_MouseDownScreenPos[0] = m_MouseDownScreenPos[0] + m_fMenuMouseOffsetX;
163  }
164  if (m_MouseDownScreenPos[1] + contextMenuHeight > screenHeight)
165  {
166  m_MouseDownScreenPos[1] = (m_MouseDownScreenPos[1]) - contextMenuHeight;
167  }
168 
169  // Set Context menu position
170  FrameSlot.SetPos(m_ContextMenu, m_MouseDownScreenPos[0], m_MouseDownScreenPos[1]);
171  // Show context menu
172  if (m_ButtonActions.Count() > 0)
173  {
174  m_ContextMenu.SetVisible(true);
175  m_OnContextMenuToggle.Invoke(true);
176  }
177  }
178 
179  protected vector GetCursorWorldPos()
180  {
181  vector cursorWorldPosition;
182 
183  if (!m_CursorComponent)
184  m_CursorComponent = SCR_CursorEditorUIComponent.Cast(GetRootComponent().FindComponent(SCR_CursorEditorUIComponent));
185 
186  if (m_CursorComponent && m_CursorComponent.GetCursorWorldPos(cursorWorldPosition))
187  return cursorWorldPosition;
188 
189  return vector.Zero;
190  }
191 
192  protected void RemoveButtonWidgets()
193  {
194  Widget childWidget = m_VLayout.GetChildren();
195 
196  while (childWidget)
197  {
198  childWidget.RemoveFromHierarchy();
199  childWidget = m_VLayout.GetChildren();
200  }
201 
202  m_ButtonActions.Clear();
203  }
204 
205  protected void OnMouseLeftDown()
206  {
207  if (!IsContextMenuOpen()) return;
208 
209  float mouseX, mouseY, layoutX1, layoutY1, layoutX2, layoutY2, layoutWidth, layoutHeight;
210  mouseX = m_InputManager.GetActionValue("MouseX");
211  mouseY = m_InputManager.GetActionValue("MouseY");
212 
213  m_ContextMenu.GetScreenPos(layoutX1, layoutY1);
214  m_ContextMenu.GetScreenSize(layoutWidth, layoutHeight);
215  layoutX2 = layoutX1 + layoutWidth;
216  layoutY2 = layoutY1 + layoutHeight;
217 
218  // Close context menu when clicking outside of it
219  if (mouseX < layoutX1 || mouseY < layoutY1 || mouseX > layoutX2 || mouseY > layoutY2)
220  {
221  CloseContextMenu();
222  }
223  }
224 
225  protected void OnOpenActionsMenuDown()
226  {
227  CloseContextMenu();
229  if ((!m_MouseArea || m_MouseArea.IsMouseOn()) || (!hoverFilter || !hoverFilter.IsEmpty()))
230  m_MouseDownScreenPos = OnCancelDown();
231  }
232 
233  protected void OnContextMenuOptionClicked(Widget widget, float value, EActionTrigger reason)
234  {
235  SCR_BaseEditorAction action = m_ButtonActions.Get(widget);
236  if (action && m_EditorActionsComponent)
237  {
238  m_EditorActionsComponent.ActionPerform(action, m_MouseDownWorldPos, m_ActionFlagsOnOpen);
239  }
240  CloseContextMenu();
241  }
242 
243  protected void OnEditorModeChanged()
244  {
245  // Override to assign m_EditorActionsComponent
246  }
247 
248  override void HandlerAttachedScripted(Widget w)
249  {
250  super.HandlerAttachedScripted(w);
251 
252  ArmaReforgerScripted game = GetGame();
253  m_WorkSpace = game.GetWorkspace();
254  m_InputManager = game.GetInputManager();
255 
256  if (m_InputManager)
257  {
258  m_InputManager.AddActionListener("MouseLeft", EActionTrigger.DOWN, OnMouseLeftDown);
259  m_InputManager.AddActionListener("EditorContextMenuClose", EActionTrigger.DOWN, CloseContextMenu);
260  }
261 
262  if (m_ButtonPath.IsEmpty())
263  {
264  Print("Button prefab not set on (actions/waypoint) ContextMenuEditorUIComponent", LogLevel.ERROR);
265  }
266 
267  game.OnInputDeviceIsGamepadInvoker().Insert(OnInputDeviceIsGamepad);
268 
270 
271  m_EditorManager.GetOnModeChange().Insert(OnEditorModeChanged);
272 
273  m_CursorComponent = SCR_CursorEditorUIComponent.Cast(GetRootComponent().FindComponent(SCR_CursorEditorUIComponent));
274  m_MouseArea = SCR_MouseAreaEditorUIComponent.Cast(GetRootComponent().FindComponent(SCR_MouseAreaEditorUIComponent));
275 
276  OnEditorModeChanged();
277 
279  m_ContextMenu.SetVisible(false);
280  m_VLayout = m_ContextMenu.FindAnyWidget(m_VLayoutWidgetName);
281 
282  if (!m_VLayout)
283  {
284  Print("Vertical layout not found on (actions/waypoint) ContextMenuEditorUIComponent, see m_VLayoutWidgetName", LogLevel.ERROR);
285  }
286 
287  Widget bottomBar = w.FindAnyWidget(m_sBottomBarName);
288  if (bottomBar)
289  {
290  m_BottomBarFadeUI = SCR_FadeUIComponent.Cast(bottomBar.FindHandler(SCR_FadeUIComponent));
291  if (m_BottomBarFadeUI)
292  {
293  m_BottomBarFadeUI.SetFadeInSpeed(m_fButtonFadeSpeed);
294  bottomBar.SetVisible(false);
295  }
296  }
297  }
298 
299  override void HandlerDeattached(Widget w)
300  {
301  super.HandlerDeattached(w);
302 
303  if (m_InputManager)
304  {
305  m_InputManager.RemoveActionListener("MouseLeft", EActionTrigger.DOWN, OnMouseLeftDown);
306  m_InputManager.RemoveActionListener("EditorContextMenuClose", EActionTrigger.DOWN, CloseContextMenu);
307  }
308  if (m_EditorManager)
309  {
310  m_EditorManager.GetOnModeChange().Remove(OnEditorModeChanged);
311  }
312 
314  GetGame().OnInputDeviceIsGamepadInvoker().Remove(OnInputDeviceIsGamepad);
315  }
316 };
SCR_BaseEditorAction
Definition: SCR_BaseEditorAction.c:24
m_MouseArea
private SCR_MouseAreaEditorUIComponent m_MouseArea
Definition: SCR_CursorEditorUIComponent.c:38
EEditableEntityState
EEditableEntityState
Definition: EEditableEntityState.c:37
SCR_CursorEditorUIComponent
Definition: SCR_CursorEditorUIComponent.c:3
SCR_FadeUIComponent
Definition: SCR_FadeUIComponent.c:1
m_InputManager
protected InputManager m_InputManager
Definition: SCR_BaseManualCameraComponent.c:15
GetGame
ArmaReforgerScripted GetGame()
Definition: game.c:1424
desc
UI Textures DeployMenu Briefing conflict_HintBanner_1_UI desc
Definition: SCR_RespawnBriefingComponent.c:17
Attribute
typedef Attribute
Post-process effect of scripted camera.
SCR_MouseAreaEditorUIComponent
Definition: SCR_MouseAreaEditorUIComponent.c:3
SCR_BaseContextMenuEditorUIComponent
Definition: SCR_BaseContextMenuEditorUIComponent.c:2
SCR_ContextMenuButtonEditorUIComponent
Definition: SCR_ContextMenuButtonEditorUIComponent.c:1
m_EditorActionsComponent
protected SCR_ToolbarActionsEditorComponent m_EditorActionsComponent
Definition: SCR_ActionsToolbarEditorUIComponent.c:22
ButtonActionComponent
Component to execute action when the button or its shortcut is pressed.
Definition: ButtonActionComponent.c:2
m_EditorManager
protected SCR_EditorManagerEntity m_EditorManager
Definition: SCR_VotingEditor.c:5
SCR_BaseEditableEntityFilter
Definition: SCR_BaseEditableEntityFilter.c:13
SCR_UIInfo
Definition: SCR_UIInfo.c:7
SCR_BaseEditorUIComponent
Definition: SCR_BaseEditorUIComponent.c:3
m_CursorComponent
protected SCR_CursorEditorUIComponent m_CursorComponent
Definition: SCR_EntitiesEditorUIComponent.c:16
m_ContextMenu
protected SCR_BaseContextMenuEditorUIComponent m_ContextMenu
Definition: SCR_TooltipManagerEditorUIComponent.c:24
OnInputDeviceIsGamepadInvoker
ScriptInvoker OnInputDeviceIsGamepadInvoker()
Definition: game.c:246
GetWidget
protected Widget GetWidget()
Definition: SCR_VonDisplay.c:155
SCR_EditorManagerEntity
Definition: SCR_EditorManagerEntity.c:26