Arma Reforger Explorer  1.1.0.42
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
SCR_MapToolInteractionUI.c
Go to the documentation of this file.
1 void ScriptInvokerWidgetBool(Widget widget, bool state);
3 
5 class SCR_MapElementMoveComponent : ScriptedWidgetComponent
6 {
7  [Attribute(defvalue: "1", uiwidget: UIWidgets.CheckBox, desc: "Allows the widget to be dragged")]
8  bool m_bCanDrag;
9 
10  [Attribute(defvalue: "0", uiwidget: UIWidgets.CheckBox, desc: "Allows to drag widget further off screen then default: half the size of the widget")]
11  bool m_bCanDragOffScreen;
12 
13  [Attribute(defvalue: "0", uiwidget: UIWidgets.CheckBox, desc: "Allows the widget to be rotated")]
14  bool m_bCanRotate;
15 
16  [Attribute(defvalue: "0", uiwidget: UIWidgets.CheckBox, desc: "Allows the widget to be activated")]
17  bool m_bCanActivate;
18 }
19 
21 class SCR_MapToolInteractionUI : SCR_MapUIBaseComponent
22 {
23  protected const float HOLD_DRAG_EVENT_TIME = 0.2; // seconds, drag event will start immediately but the end event will use this timer to determine if drag happened or not and send it as param
24  protected const float ROTATION_DEADZONE = 0.02;
25  static bool s_bIsDragging = false;
26  static bool s_bIsRotating = false;
27  static bool s_bCanDragOffScreen = false;
28  static float s_fDragTime;
29 
30  static protected ref ScriptInvoker<Widget> s_OnDragWidget = new ScriptInvoker();
31  static protected ref ScriptInvokerBase<ScriptInvokerWidgetBool> s_OnDragEnd = new ScriptInvokerBase<ScriptInvokerWidgetBool>(); // Widget which was being dragged + bool if it was a real drag or only click
32  static protected ref ScriptInvoker<Widget> s_OnActivateTool = new ScriptInvoker();
33 
34  static protected Widget s_DraggedWidget;
35  static protected Widget s_RotatedWidget;
36 
39 
40  // Invokers
41  //------------------------------------------------------------------------------------------------
43  static ScriptInvoker GetOnDragWidgetInvoker()
44  {
45  return s_OnDragWidget;
46  }
47 
48  //------------------------------------------------------------------------------------------------
50  static ScriptInvokerBase<ScriptInvokerWidgetBool> GetOnDragEndInvoker()
51  {
52  return s_OnDragEnd;
53  }
54 
55  //------------------------------------------------------------------------------------------------
57  static ScriptInvoker GetOnActivateToolInvoker()
58  {
59  return s_OnActivateTool;
60  }
61 
62  //------------------------------------------------------------------------------------------------
64  static void ActivateAction()
65  {
66  array<Widget> widgets = SCR_MapCursorModule.GetMapWidgetsUnderCursor();
68 
69  if (!CanBeManipulated(widgets))
70  return;
71 
72  foreach ( Widget widget : widgets )
73  {
74  moveComp = SCR_MapElementMoveComponent.Cast(widget.FindHandler(SCR_MapElementMoveComponent));
75  if (!moveComp || !moveComp.m_bCanActivate)
76  continue;
77 
78  s_OnActivateTool.Invoke(widget);
79  return;
80  }
81  }
82 
83  //------------------------------------------------------------------------------------------------
86  static bool StartDrag()
87  {
88  if (s_bIsDragging)
89  return false;
90 
91  s_fDragTime = 0;
92 
93  array<Widget> widgets = SCR_MapCursorModule.GetMapWidgetsUnderCursor();
95 
96  if (!CanBeManipulated(widgets))
97  return false;
98 
99  foreach ( Widget widget : widgets )
100  {
101  moveComp = SCR_MapElementMoveComponent.Cast(widget.FindHandler(SCR_MapElementMoveComponent));
102  if (moveComp)
103  {
104  if (!moveComp.m_bCanDrag)
105  continue;
106 
107  s_DraggedWidget = widget;
108  s_bCanDragOffScreen = moveComp.m_bCanDragOffScreen;
109  break;
110  }
111  }
112 
113  if (s_DraggedWidget)
114  {
115  s_bIsDragging = true;
116  s_OnDragWidget.Invoke(s_DraggedWidget);
117 
118  SCR_UISoundEntity.SoundEvent(SCR_SoundEvent.SOUND_MAP_GADGET_GRAB);
119 
120  return true;
121  }
122 
123  return false;
124  }
125 
126  //------------------------------------------------------------------------------------------------
129  static bool StartRotate()
130  {
131  array<Widget> widgets = SCR_MapCursorModule.GetMapWidgetsUnderCursor();
133 
134  if (!CanBeManipulated(widgets))
135  return false;
136 
137  foreach ( Widget widget : widgets )
138  {
139  moveComp = SCR_MapElementMoveComponent.Cast(widget.FindHandler(SCR_MapElementMoveComponent));
140  if (moveComp)
141  {
142  if (!moveComp.m_bCanRotate)
143  continue;
144 
145  s_RotatedWidget = widget;
146  break;
147  }
148  }
149 
150  if (s_RotatedWidget)
151  {
152  s_bIsRotating = true;
153  return true;
154  }
155 
156  return false;
157  }
158 
159  //------------------------------------------------------------------------------------------------
163  static bool CanBeManipulated(array<Widget> tracedWidgets)
164  {
165  foreach ( Widget widget : tracedWidgets )
166  {
167  if (ButtonWidget.Cast(widget))
168  return false;
169  }
170 
171  return true;
172  }
173 
174  //------------------------------------------------------------------------------------------------
176  static void EndDrag()
177  {
178  s_bIsDragging = false;
179  s_OnDragEnd.Invoke(s_DraggedWidget, s_fDragTime >= HOLD_DRAG_EVENT_TIME);
180 
181  s_DraggedWidget = null;
182  s_OnDragWidget.Invoke(null, false);
183 
184  SCR_UISoundEntity.SoundEvent(SCR_SoundEvent.SOUND_MAP_GADGET_RELEASE);
185  }
186 
187  //------------------------------------------------------------------------------------------------
189  static void EndRotate()
190  {
191  s_bIsRotating = false;
192  s_RotatedWidget = null;
193  }
194 
195  //------------------------------------------------------------------------------------------------
199  void DragWidget(Widget widget, SCR_MapCursorInfo cursorInfo)
200  {
201  int screenX = GetGame().GetWorkspace().GetWidth();
202  int screenY = GetGame().GetWorkspace().GetHeight();
203 
204  float widgetX, widgetY, fx, fy, minX, minY, maxX, maxY;
205 
206  // mouse position difference
207  fx = cursorInfo.x - cursorInfo.lastX;
208  fy = cursorInfo.y - cursorInfo.lastY;
209 
210  // no change
211  if (fx == 0 && fy == 0)
212  return;
213 
214  // new pos
215  vector pos = FrameSlot.GetPos(widget);
216  fx = fx + pos[0];
217  fy = fy + pos[1];
218 
220  widget.GetScreenSize(widgetX, widgetY);
221 
222  if (!s_bCanDragOffScreen)
223  {
225  WorkspaceWidget workspace = GetGame().GetWorkspace();
226  minX = workspace.DPIUnscale(-widgetX/2);
227  minY = workspace.DPIUnscale(-widgetY/2);
228  maxX = workspace.DPIUnscale(screenX) - workspace.DPIUnscale(widgetX/2);
229  maxY = workspace.DPIUnscale(screenY) - workspace.DPIUnscale(widgetY/2);
230 
231  // avoid moving the element off screen
232  fx = Math.Clamp(fx, minX, maxX);
233  fy = Math.Clamp(fy, minY, maxY);
234  }
235 
236  // set new postion
237  FrameSlot.SetPos(widget, fx, fy);
238  }
239 
240  //------------------------------------------------------------------------------------------------
244  static void RotateWidget(notnull Widget widget, SCR_MapCursorInfo cursorInfo)
245  {
246  ImageWidget image = ImageWidget.Cast(widget.GetChildren());
247  if (!image)
248  return;
249 
250  // TODO ImageWidget.GetPivot(float x, float y)
251  float fx, fy, minX, minY, maxX, maxY;
252 
253  // mouse position difference
254  fx = cursorInfo.x - cursorInfo.lastX;
255  fy = cursorInfo.y - cursorInfo.lastY;
256 
257  // no change
258  if (fx == 0 && fy == 0)
259  return;
260 
262  float widgetX, widgetY, widgetH, widgetV, centerX, centerY;
263  widget.GetScreenPos(widgetX, widgetY);
264  widget.GetScreenSize(widgetH, widgetV);
265  centerX = widgetX + widgetH/2;
266  centerY = widgetY + widgetV/2;
267 
268  // Get current angle versus previous angle
269  WorkspaceWidget workspace = GetGame().GetWorkspace();
270  widgetH = workspace.DPIUnscale(widgetH);
271  centerX = workspace.DPIUnscale(centerX);
272  centerY = workspace.DPIUnscale(centerY);
273 
274  float newAngle = Math.RAD2DEG * Math.Atan2(cursorInfo.x - centerX, cursorInfo.y - centerY);
275  float lastAngle = Math.RAD2DEG * Math.Atan2(cursorInfo.lastX - centerX, cursorInfo.lastY - centerY);
276 
277  float rotation = fixAngle_180_180(newAngle - lastAngle);
278 
279  // Slow down rotation near the center
280  vector grip = Vector(cursorInfo.x - centerX, cursorInfo.y - centerY, 0);
281  float rotationScale = 1;
282  if (widgetH > 0 && ROTATION_DEADZONE > 0)
283  rotationScale = Math.Clamp(grip.Length() / (widgetH * ROTATION_DEADZONE), 0, 1);
284 
285  rotation *= rotationScale * rotationScale;
286 
287  // Apply new rotation
288  image.SetRotation(image.GetRotation() - rotation);
289  }
290 
291  //------------------------------------------------------------------------------------------------
292  override void OnMapOpen(MapConfiguration config)
293  {
294  super.OnMapOpen(config);
295 
297  m_CursorInfo = m_CursorModule.GetCursorInfo();
298  }
299 
300  //------------------------------------------------------------------------------------------------
301  override void OnMapClose(MapConfiguration config)
302  {
303  s_OnDragWidget.Clear();
304  s_OnDragEnd.Clear();
305  s_OnActivateTool.Clear();
306  s_DraggedWidget = null;
307  s_RotatedWidget = null;
308  s_bIsDragging = false;
309  s_bIsRotating = false;
310  s_fDragTime = 0;
311 
312  super.OnMapClose(config);
313  }
314 
315  //------------------------------------------------------------------------------------------------
316  override void Update(float timeSlice)
317  {
318  if (s_bIsDragging)
319  {
320  DragWidget(s_DraggedWidget, m_CursorInfo);
321  s_fDragTime += timeSlice;
322  }
323  else if (s_bIsRotating)
324  {
325  RotateWidget(s_RotatedWidget, m_CursorInfo);
326  }
327  }
328 }
OnMapOpen
override void OnMapOpen(MapConfiguration config)
Definition: SCR_MapToolInteractionUI.c:292
DragWidget
void DragWidget(Widget widget, SCR_MapCursorInfo cursorInfo)
Definition: SCR_MapToolInteractionUI.c:199
m_MapEntity
protected SCR_MapEntity m_MapEntity
Definition: SCR_MapGadgetComponent.c:14
HOLD_DRAG_EVENT_TIME
SCR_MapElementMoveComponent HOLD_DRAG_EVENT_TIME
Component for interacting with map tools.
ActivateAction
override void ActivateAction()
Definition: SCR_ConsumableItemComponent.c:188
SCR_UISoundEntity
Definition: SCR_UISoundEntity.c:7
GetGame
ArmaReforgerScripted GetGame()
Definition: game.c:1424
SCR_SoundEvent
Definition: SCR_SoundEvent.c:1
desc
UI Textures DeployMenu Briefing conflict_HintBanner_1_UI desc
Definition: SCR_RespawnBriefingComponent.c:17
func
func
Definition: SCR_AIThreatSystem.c:5
OnMapClose
override void OnMapClose(MapConfiguration config)
Definition: SCR_MapToolInteractionUI.c:301
SCR_MapCursorModule
Map cursor behavior and mode setup.
Definition: SCR_MapCursorModule.c:39
m_CursorModule
protected SCR_MapCursorModule m_CursorModule
Definition: SCR_MapToolInteractionUI.c:37
Attribute
typedef Attribute
Post-process effect of scripted camera.
rotation
RespawnSystemComponentClass GameComponentClass vector vector rotation
Definition: RespawnSystemComponent.c:23
SCR_MapElementMoveComponent
Attach this component to a widget in a map layout to configure interactions.
Definition: SCR_MapToolInteractionUI.c:5
m_CursorInfo
protected SCR_MapCursorInfo m_CursorInfo
Definition: SCR_MapToolInteractionUI.c:38
ROTATION_DEADZONE
const protected float ROTATION_DEADZONE
Definition: SCR_MapToolInteractionUI.c:24
SCR_MapCursorInfo
Cursor data.
Definition: SCR_MapCursorModule.c:3
fixAngle_180_180
float fixAngle_180_180(float pAngle)
Definition: CharacterCameraBase.c:14
SCR_MapUIBaseComponent
Definition: SCR_MapUIBaseComponent.c:3
ScriptInvokerWidgetBool
func ScriptInvokerWidgetBool
Definition: SCR_MapToolInteractionUI.c:2
Update
override void Update(float timeSlice)
Definition: SCR_MapToolInteractionUI.c:316