Arma Reforger Explorer 1.7.0.54
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
Loading...
Searching...
No Matches
SCR_MapToolInteractionUI.c
Go to the documentation of this file.
1void ScriptInvokerWidgetBool(Widget widget, bool state);
3
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 [Attribute(desc: "When activation is disabled then this will allow for resetting the rotation of the tool")]
20 bool m_bCanResetRotation;
21}
22
24class SCR_MapToolInteractionUI : SCR_MapUIBaseComponent
25{
26 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
27 protected const float ROTATION_DEADZONE = 0.02;
28 static bool s_bIsDragging = false;
29 static bool s_bIsRotating = false;
30 static bool s_bCanDragOffScreen = false;
31 static float s_fDragTime;
32
33 static protected ref ScriptInvoker<Widget> s_OnDragWidget = new ScriptInvoker();
34 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
35 static protected ref ScriptInvoker<Widget> s_OnActivateTool = new ScriptInvoker();
36
37 static protected Widget s_DraggedWidget;
38 static protected Widget s_RotatedWidget;
39
40 static protected SCR_MapCursorModule s_CursorModule;
41 static protected SCR_MapCursorInfo s_CursorInfo;
42
43 // Invokers
44 //------------------------------------------------------------------------------------------------
46 static ScriptInvoker GetOnDragWidgetInvoker()
47 {
48 return s_OnDragWidget;
49 }
50
51 //------------------------------------------------------------------------------------------------
53 static ScriptInvokerBase<ScriptInvokerWidgetBool> GetOnDragEndInvoker()
54 {
55 return s_OnDragEnd;
56 }
57
58 //------------------------------------------------------------------------------------------------
60 static ScriptInvoker GetOnActivateToolInvoker()
61 {
62 return s_OnActivateTool;
63 }
64
65 //------------------------------------------------------------------------------------------------
67 static void ActivateAction()
68 {
69 array<Widget> widgets = SCR_MapCursorModule.GetMapWidgetsUnderCursor();
70 SCR_MapElementMoveComponent moveComp;
71
72 if (!CanBeManipulated(widgets))
73 return;
74
75 foreach ( Widget widget : widgets )
76 {
77 moveComp = SCR_MapElementMoveComponent.Cast(widget.FindHandler(SCR_MapElementMoveComponent));
78 if (!moveComp || !moveComp.m_bCanActivate)
79 continue;
80
81 s_OnActivateTool.Invoke(widget);
82 return;
83 }
84 }
85
86 //------------------------------------------------------------------------------------------------
89 static bool StartDrag()
90 {
91 if (s_bIsDragging)
92 return false;
93
94 s_fDragTime = 0;
95
96 if (s_CursorInfo)
97 {
98 s_CursorInfo.lastX = s_CursorInfo.x;
99 s_CursorInfo.lastY = s_CursorInfo.y;
100 }
101
102 array<Widget> widgets = SCR_MapCursorModule.GetMapWidgetsUnderCursor();
103 SCR_MapElementMoveComponent moveComp;
104
105 if (!CanBeManipulated(widgets))
106 return false;
107
108 foreach ( Widget widget : widgets )
109 {
110 moveComp = SCR_MapElementMoveComponent.Cast(widget.FindHandler(SCR_MapElementMoveComponent));
111 if (moveComp)
112 {
113 if (!moveComp.m_bCanDrag)
114 continue;
115
116 s_DraggedWidget = widget;
117 s_bCanDragOffScreen = moveComp.m_bCanDragOffScreen;
118 break;
119 }
120 }
121
122 if (s_DraggedWidget)
123 {
124 s_bIsDragging = true;
125 s_OnDragWidget.Invoke(s_DraggedWidget);
126
127 SCR_UISoundEntity.SoundEvent(SCR_SoundEvent.SOUND_MAP_GADGET_GRAB);
128
129 return true;
130 }
131
132 return false;
133 }
134
135 //------------------------------------------------------------------------------------------------
138 static bool StartRotate()
139 {
140 if (s_CursorInfo)
141 {
142 s_CursorInfo.lastX = s_CursorInfo.x;
143 s_CursorInfo.lastY = s_CursorInfo.y;
144 }
145
146 array<Widget> widgets = SCR_MapCursorModule.GetMapWidgetsUnderCursor();
147 SCR_MapElementMoveComponent moveComp;
148
149 if (!CanBeManipulated(widgets))
150 return false;
151
152 foreach ( Widget widget : widgets )
153 {
154 moveComp = SCR_MapElementMoveComponent.Cast(widget.FindHandler(SCR_MapElementMoveComponent));
155 if (moveComp)
156 {
157 if (!moveComp.m_bCanRotate)
158 continue;
159
160 s_RotatedWidget = widget;
161 break;
162 }
163 }
164
165 if (s_RotatedWidget)
166 {
167 s_bIsRotating = true;
168 return true;
169 }
170
171 return false;
172 }
173
174 //------------------------------------------------------------------------------------------------
178 static bool CanBeManipulated(array<Widget> tracedWidgets)
179 {
180 foreach ( Widget widget : tracedWidgets )
181 {
182 if (ButtonWidget.Cast(widget))
183 return false;
184 }
185
186 return true;
187 }
188
189 //------------------------------------------------------------------------------------------------
191 static void EndDrag()
192 {
193 s_bIsDragging = false;
194 s_OnDragEnd.Invoke(s_DraggedWidget, s_fDragTime >= HOLD_DRAG_EVENT_TIME);
195
196 s_DraggedWidget = null;
197 s_OnDragWidget.Invoke(null, false);
198
199 SCR_UISoundEntity.SoundEvent(SCR_SoundEvent.SOUND_MAP_GADGET_RELEASE);
200 }
201
202 //------------------------------------------------------------------------------------------------
204 static void EndRotate()
205 {
206 s_bIsRotating = false;
207 s_RotatedWidget = null;
208 }
209
210 //------------------------------------------------------------------------------------------------
213 static void DragWidget(notnull Widget widget)
214 {
215 int screenX = GetGame().GetWorkspace().GetWidth();
216 int screenY = GetGame().GetWorkspace().GetHeight();
217
218 float widgetX, widgetY, fx, fy, minX, minY, maxX, maxY;
219
220 // mouse position difference
221 fx = s_CursorInfo.x - s_CursorInfo.lastX;
222 fy = s_CursorInfo.y - s_CursorInfo.lastY;
223
224 // no change
225 if (fx == 0 && fy == 0)
226 return;
227
228 // new pos
229 vector pos = FrameSlot.GetPos(widget);
230 fx = fx + pos[0];
231 fy = fy + pos[1];
232
234 widget.GetScreenSize(widgetX, widgetY);
235
236 if (!s_bCanDragOffScreen)
237 {
239 WorkspaceWidget workspace = GetGame().GetWorkspace();
240 minX = workspace.DPIUnscale(-widgetX/2);
241 minY = workspace.DPIUnscale(-widgetY/2);
242 maxX = workspace.DPIUnscale(screenX) - workspace.DPIUnscale(widgetX/2);
243 maxY = workspace.DPIUnscale(screenY) - workspace.DPIUnscale(widgetY/2);
244
245 // avoid moving the element off screen
246 fx = Math.Clamp(fx, minX, maxX);
247 fy = Math.Clamp(fy, minY, maxY);
248 }
249
250 // set new postion
251 FrameSlot.SetPos(widget, fx, fy);
252
253 s_CursorInfo.lastX = s_CursorInfo.x;
254 s_CursorInfo.lastY = s_CursorInfo.y;
255 }
256
257 //------------------------------------------------------------------------------------------------
260 static void RotateWidget(notnull Widget widget)
261 {
262 ImageWidget image = ImageWidget.Cast(widget.GetChildren());
263 if (!image)
264 return;
265
266 // TODO ImageWidget.GetPivot(float x, float y)
267 // float fx, fy, minX, minY, maxX, maxY;
268
269 // mouse position difference
270 float fx = s_CursorInfo.x - s_CursorInfo.lastX;
271 float fy = s_CursorInfo.y - s_CursorInfo.lastY;
272
273 // no change
274 if (fx == 0 && fy == 0)
275 return;
276
278 float widgetX, widgetY, widgetH, widgetV, centerX, centerY;
279 widget.GetScreenPos(widgetX, widgetY);
280 widget.GetScreenSize(widgetH, widgetV);
281 centerX = widgetX + widgetH/2;
282 centerY = widgetY + widgetV/2;
283
284 // Get current angle versus previous angle
285 WorkspaceWidget workspace = GetGame().GetWorkspace();
286 widgetH = workspace.DPIUnscale(widgetH);
287 centerX = workspace.DPIUnscale(centerX);
288 centerY = workspace.DPIUnscale(centerY);
289
290 float newAngle = Math.RAD2DEG * Math.Atan2(s_CursorInfo.x - centerX, s_CursorInfo.y - centerY);
291 float lastAngle = Math.RAD2DEG * Math.Atan2(s_CursorInfo.lastX - centerX, s_CursorInfo.lastY - centerY);
292
293 float rotation = SCR_Math.FixAngle(newAngle - lastAngle, 180);
294
295 // Slow down rotation near the center
296 vector grip = Vector(s_CursorInfo.x - centerX, s_CursorInfo.y - centerY, 0);
297 float rotationScale = 1;
298 if (widgetH > 0 && ROTATION_DEADZONE > 0)
299 rotationScale = Math.Clamp(grip.Length() / (widgetH * ROTATION_DEADZONE), 0, 1);
300
301 rotation *= rotationScale * rotationScale;
302
303 // Apply new rotation
304 image.SetRotation(image.GetRotation() - rotation);
305
306 s_CursorInfo.lastX = s_CursorInfo.x;
307 s_CursorInfo.lastY = s_CursorInfo.y;
308 }
309
310 //------------------------------------------------------------------------------------------------
311 override void OnMapOpen(MapConfiguration config)
312 {
313 super.OnMapOpen(config);
314
315 s_CursorModule = SCR_MapCursorModule.Cast(m_MapEntity.GetMapModule(SCR_MapCursorModule));
316 s_CursorInfo = s_CursorModule.GetCursorInfo();
317 }
318
319 //------------------------------------------------------------------------------------------------
320 override void OnMapClose(MapConfiguration config)
321 {
322 s_OnDragWidget.Clear();
323 s_OnDragEnd.Clear();
324 s_OnActivateTool.Clear();
325 s_DraggedWidget = null;
326 s_RotatedWidget = null;
327 s_bIsDragging = false;
328 s_bIsRotating = false;
329 s_fDragTime = 0;
330 s_CursorModule = null;
331 s_CursorInfo = null;
332
333 super.OnMapClose(config);
334 }
335
336 //------------------------------------------------------------------------------------------------
337 override void Update(float timeSlice)
338 {
339 if (s_bIsDragging)
340 {
341 DragWidget(s_DraggedWidget);
342 s_fDragTime += timeSlice;
343 }
344 else if (s_bIsRotating)
345 {
346 RotateWidget(s_RotatedWidget);
347 }
348 }
349}
ArmaReforgerScripted GetGame()
Definition game.c:1398
void ActivateAction()
Action listener callback.
SCR_MapEntity m_MapEntity
SCR_MapElementMoveComponent HOLD_DRAG_EVENT_TIME
Component for interacting with map tools.
func ScriptInvokerWidgetBool
const float ROTATION_DEADZONE
UI Textures DeployMenu Briefing conflict_HintBanner_1_UI desc
Attach this component to a widget in a map layout to configure interactions.
void OnMapOpen(MapConfiguration config)
void OnMapClose(MapConfiguration config)
SCR_FieldOfViewSettings Attribute
RespawnSystemComponentClass GameComponentClass vector vector rotation
proto native vector Vector(float x, float y, float z)
ScriptInvokerBase< func > ScriptInvoker
Definition tools.c:134