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;
19 [
Attribute(
desc:
"When activation is disabled then this will allow for resetting the rotation of the tool")]
20 bool m_bCanResetRotation;
28 static bool s_bIsDragging =
false;
29 static bool s_bIsRotating =
false;
30 static bool s_bCanDragOffScreen =
false;
31 static float s_fDragTime;
34 static protected ref ScriptInvokerBase<ScriptInvokerWidgetBool> s_OnDragEnd =
new ScriptInvokerBase<ScriptInvokerWidgetBool>();
37 static protected Widget s_DraggedWidget;
38 static protected Widget s_RotatedWidget;
40 static protected SCR_MapCursorModule s_CursorModule;
48 return s_OnDragWidget;
53 static ScriptInvokerBase<ScriptInvokerWidgetBool> GetOnDragEndInvoker()
62 return s_OnActivateTool;
69 array<Widget> widgets = SCR_MapCursorModule.GetMapWidgetsUnderCursor();
70 SCR_MapElementMoveComponent moveComp;
72 if (!CanBeManipulated(widgets))
75 foreach ( Widget widget : widgets )
77 moveComp = SCR_MapElementMoveComponent.Cast(widget.FindHandler(SCR_MapElementMoveComponent));
78 if (!moveComp || !moveComp.m_bCanActivate)
81 s_OnActivateTool.Invoke(widget);
89 static bool StartDrag()
98 s_CursorInfo.lastX = s_CursorInfo.x;
99 s_CursorInfo.lastY = s_CursorInfo.y;
102 array<Widget> widgets = SCR_MapCursorModule.GetMapWidgetsUnderCursor();
103 SCR_MapElementMoveComponent moveComp;
105 if (!CanBeManipulated(widgets))
108 foreach ( Widget widget : widgets )
110 moveComp = SCR_MapElementMoveComponent.Cast(widget.FindHandler(SCR_MapElementMoveComponent));
113 if (!moveComp.m_bCanDrag)
116 s_DraggedWidget = widget;
117 s_bCanDragOffScreen = moveComp.m_bCanDragOffScreen;
124 s_bIsDragging =
true;
125 s_OnDragWidget.Invoke(s_DraggedWidget);
127 SCR_UISoundEntity.SoundEvent(SCR_SoundEvent.SOUND_MAP_GADGET_GRAB);
138 static bool StartRotate()
142 s_CursorInfo.lastX = s_CursorInfo.x;
143 s_CursorInfo.lastY = s_CursorInfo.y;
146 array<Widget> widgets = SCR_MapCursorModule.GetMapWidgetsUnderCursor();
147 SCR_MapElementMoveComponent moveComp;
149 if (!CanBeManipulated(widgets))
152 foreach ( Widget widget : widgets )
154 moveComp = SCR_MapElementMoveComponent.Cast(widget.FindHandler(SCR_MapElementMoveComponent));
157 if (!moveComp.m_bCanRotate)
160 s_RotatedWidget = widget;
167 s_bIsRotating =
true;
178 static bool CanBeManipulated(array<Widget> tracedWidgets)
180 foreach ( Widget widget : tracedWidgets )
182 if (ButtonWidget.Cast(widget))
191 static void EndDrag()
193 s_bIsDragging =
false;
196 s_DraggedWidget = null;
197 s_OnDragWidget.Invoke(null,
false);
199 SCR_UISoundEntity.SoundEvent(SCR_SoundEvent.SOUND_MAP_GADGET_RELEASE);
204 static void EndRotate()
206 s_bIsRotating =
false;
207 s_RotatedWidget = null;
213 static void DragWidget(notnull Widget widget)
215 int screenX =
GetGame().GetWorkspace().GetWidth();
216 int screenY =
GetGame().GetWorkspace().GetHeight();
218 float widgetX, widgetY, fx, fy, minX, minY, maxX, maxY;
221 fx = s_CursorInfo.x - s_CursorInfo.lastX;
222 fy = s_CursorInfo.y - s_CursorInfo.lastY;
225 if (fx == 0 && fy == 0)
229 vector pos = FrameSlot.GetPos(widget);
234 widget.GetScreenSize(widgetX, widgetY);
236 if (!s_bCanDragOffScreen)
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);
246 fx = Math.Clamp(fx, minX, maxX);
247 fy = Math.Clamp(fy, minY, maxY);
251 FrameSlot.SetPos(widget, fx, fy);
253 s_CursorInfo.lastX = s_CursorInfo.x;
254 s_CursorInfo.lastY = s_CursorInfo.y;
260 static void RotateWidget(notnull Widget widget)
262 ImageWidget image = ImageWidget.Cast(widget.GetChildren());
270 float fx = s_CursorInfo.x - s_CursorInfo.lastX;
271 float fy = s_CursorInfo.y - s_CursorInfo.lastY;
274 if (fx == 0 && fy == 0)
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;
285 WorkspaceWidget workspace =
GetGame().GetWorkspace();
286 widgetH = workspace.DPIUnscale(widgetH);
287 centerX = workspace.DPIUnscale(centerX);
288 centerY = workspace.DPIUnscale(centerY);
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);
293 float rotation = SCR_Math.FixAngle(newAngle - lastAngle, 180);
296 vector grip =
Vector(s_CursorInfo.x - centerX, s_CursorInfo.y - centerY, 0);
297 float rotationScale = 1;
301 rotation *= rotationScale * rotationScale;
304 image.SetRotation(image.GetRotation() -
rotation);
306 s_CursorInfo.lastX = s_CursorInfo.x;
307 s_CursorInfo.lastY = s_CursorInfo.y;
313 super.OnMapOpen(config);
315 s_CursorModule = SCR_MapCursorModule.Cast(
m_MapEntity.GetMapModule(SCR_MapCursorModule));
316 s_CursorInfo = s_CursorModule.GetCursorInfo();
322 s_OnDragWidget.Clear();
324 s_OnActivateTool.Clear();
325 s_DraggedWidget = null;
326 s_RotatedWidget = null;
327 s_bIsDragging =
false;
328 s_bIsRotating =
false;
330 s_CursorModule = null;
333 super.OnMapClose(config);
341 DragWidget(s_DraggedWidget);
342 s_fDragTime += timeSlice;
344 else if (s_bIsRotating)
346 RotateWidget(s_RotatedWidget);
ArmaReforgerScripted GetGame()
SCR_MapEntity m_MapEntity
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)