DayZ 1.24
Loading...
Searching...
No Matches
RadialMenu.c
Go to the documentation of this file.
6
8{
9 protected Widget m_Parent;
18
19 protected float m_AngleRadOffset;
21
22 //widget
23 static const string RADIAL_SELECTOR = "RadialSelector";
24 static const string RADIAL_SELECTOR_IMAGE = "SelectorImage";
25 static const string RADIAL_SELECTOR_POINTER = "SelectorPointer";
26 static const string RADIAL_DELIMITER_CONTAINER = "RadialDelimiterContainer";
27 static const string RADIAL_ITEM_CARD_CONTAINER = "RadialItemCardContainer";
28
29 //controls
33 protected float m_ControllerAngle;
34 protected float m_ControllerTilt;
35
36 //controller
37 protected int m_ControllerTimout;
38 protected bool m_IsControllerTimoutEnabled = true; //enables/disables controller deselect timeout reset
39 protected const float CONTROLLER_DESELECT_TIMEOUT = 1000; //timeout [ms] after which selection is automatically deselect when controller is not active
40 protected const float CONTROLLER_TILT_TRESHOLD_SELECT = 0.8; //tilt value (0.0-1.0) for controller sticks after which the selection will be selected
41 protected const float CONTROLLER_TILT_TRESHOLD_EXECUTE = 1.0; //tilt value (0.0-1.0) for controller sticks after which the selection will be executed
42
43 //mouse
44 protected bool m_WidgetInitialized;
45 protected const float MOUSE_SAFE_ZONE_RADIUS = 120; //Radius [px] of safe zone where every previous selection is deselected
46
47 //References
48 protected float m_RadiusOffset; //Radius [% of the main container size]
49 protected float m_ExecuteDistanceOffset; //Distance offset [% of the main container size] after which the selection will be automatically executed
50 protected float m_OffsetFromTop; //first item in the menu won't be directly on top but offset by a rad angle value (clock-wise)
51 protected float m_ItemCardRadiusOffset; //Radius [% of the main container size] for item cards
52 protected string m_DelimiterLayout; //layout file name with path
53
56
57 /*
58
59 RADIAL MENU EVENTS
60
61 Mouse:
62 OnMouseSelect
63 OnMouseDeselect
64 OnMouseExecute - unused, press events used instead
65 OnMousePressLeft
66 OnMousePressRight
67
68 Controller:
69 OnControllerSelect
70 OnControllerDeselect
71 OnControllerExecute - unused, press events used instead
72 OnControllerPressSelect
73 OnControllerPressBack
74
75 Common:
76 OnControlsChanged - controls has been changed (mouse<->controller)
77
78 */
79
80
81 //============================================
82 // RadialMenu
83 //============================================
85 {
86 m_Instance = this;
87
88 //set default control type
89#ifdef PLATFORM_CONSOLE
90 Input inp = GetGame().GetInput();
91 if (inp && inp.IsEnabledMouseAndKeyboardEvenOnServer())
93 else
95#endif
96#ifdef PLATFORM_WINDOWS
98#endif
99
100 m_SelectInputWrapper = GetUApi().GetInputByID(UAUISelect).GetPersistentWrapper();
101 m_BackInputWrapper = GetUApi().GetInputByID(UAUIBack).GetPersistentWrapper();
102
103 //radial cards
105 m_UpdateTimer = new Timer();
106 m_UpdateTimer.Run(0.01, this, "Update", NULL, true);
107 }
108
110 {
111 }
112
114 {
115 return m_Instance;
116 }
117
118 //Set handler
120 {
122 m_RadialSelector = w.FindAnyWidget(RADIAL_SELECTOR);
125
127 m_RadialSelectorDisabledColor = ARGB(255, 150, 150, 150);
128
129 //parent
130 m_Parent = w;
131 m_Parent.SetHandler(this);
132 }
133
134 //controls
136 {
137 if (m_ControlType != type)
138 {
139 m_ControlType = type;
140 GetGame().GameScript.CallFunction(m_RegisteredClass, "OnControlsChanged", NULL, type);
141 }
142 }
143
145 {
147 return true;
148
149 return false;
150 }
151
153 {
154 if (m_ControlType == RadialMenuControlType.CONTROLLER)
155 return true;
156
157 return false;
158 }
159
164
166 {
167 return m_WidgetInitialized;
168 }
169
170 //============================================
171 // Setup
172 //============================================
174 {
176 if (m_UpdateTimer && !m_UpdateTimer.IsRunning())
177 m_UpdateTimer.Run(0.01, this, "Update", NULL, true);
178 }
179
180 //Set radial menu parameters
181 //Radius offset [% of the main container size]
186
187 //Distance offset [% of the main container size] after which the selection will be automatically executed
192
193 //First item in the menu won't be directly on top but offset by a rad angle value (clock-wise)
198
199 //Radius [% of the main container size] for item cards
204
205 //Enable/Disable controller timeout
210
215
216 //============================================
217 // Visual
218 //============================================
219 //hide_selector => shows/hides radial selector when refreshing radial menu
220 void Refresh(bool hide_selector = true)
221 {
223 if (item_cards_count > 0)
225 float angle_rad = -Math.PI / 2;
226
227 //--PARAM top offset--
228 if (m_OffsetFromTop != 0)
230 //--------------------
231
232 //delete all delimiters
235 {
236 Widget del_child = delimiters_panel.GetChildren();
237 while (del_child)
238 {
240 del_child = del_child.GetSibling();
241
242 delete child_to_destroy1;
243 }
244 }
245
246 //Position item cards, crate radial delimiters
248 Widget item_card = item_cards_panel.GetChildren();
249
250 //get radius
251 float original_r = GetRadius();
252 float item_cards_r = original_r;
253
254 //--PARAM top offset--....
255 if (m_ItemCardRadiusOffset != 0)
256 {
258 if (item_cards_r < 0) item_cards_r = 0; //min radius is 0
259 }
260
261 m_RadialItemCards.Clear();
262 for (int i = 0; i < item_cards_count; ++i)
263 {
264 //position item cards
265 if (item_card)
266 {
267 //creates circle from simple widget items
270
273
274 item_card.SetPos(pos_x, pos_y);
275
276 //store item card
278
279 //get next child
280 item_card = item_card.GetSibling();
281 }
282 //-------------------------
283
284 //create delimiter
286 {
287 Widget delimiter_widget = GetGame().GetWorkspace().CreateWidgets(m_DelimiterLayout, delimiters_panel);
289 delimiter_widget.SetPos(0, 0);
290 delimiter_widget.SetRotation(0, 0, GetAngleInDegrees(delim_angle_rad) + 90);
291 }
292
293 //calculate next angle
295 }
296
297 //hide selector on refresh
298 if (hide_selector)
300 }
301
302 //Radial selector
304 {
306 {
307 int item_count = m_RadialItemCards.Count();
308 if (item_count > 1)
309 {
311 m_RadialSelector.SetRotation(0, 0, angle_deg + 90); //rotate widget according to its desired rotation
312
313 //set radial selector size
314 float progress = (1 / item_count) * 2;
315 m_RadialSelectorImage.SetMaskProgress(progress);
316
317 m_RadialSelector.Show(true);
318
319 bool grey_selector = selected_item.GetFlags() & WidgetFlags.DISABLED;
320 if (!grey_selector)
321 {
324 }
325 else
326 {
329 }
330 }
331 }
332 }
333
334 protected void HideRadialSelector()
335 {
337 m_RadialSelector.Show(false);
338 }
339
340 //============================================
341 // Widget size calculations
342 //============================================
343 protected int GetItemCardsCount()
344 {
345 Widget child = m_ItemCardsContainer.GetChildren();
346 int count = 0;
347
348 while (child)
349 {
350 ++count;
351
352 child = child.GetSibling();
353 }
354
355 return count;
356 }
357
358 protected float GetRadius()
359 {
360 float radius = Math.AbsFloat(GetParentMinSize() * 0.5);
361
362 //PARAM --radius--
363 if (m_RadiusOffset > 0)
364 return radius * m_RadiusOffset;
365 //----------------
366
367 return radius;
368 }
369
370 protected void GetParentCenter(out float center_x, out float center_y)
371 {
372 if (m_Parent)
373 {
374 float wx;
375 float wy;
376 m_Parent.GetScreenPos(wx, wy);
377
378 float ww;
379 float wh;
380 m_Parent.GetScreenSize(ww, wh);
381
382 center_x = wx + ww / 2; //center
383 center_y = wy + wh / 2;
384 }
385 }
386
387 protected float GetParentMinSize()
388 {
389 if (m_Parent)
390 {
391 float size_x;
392 float size_y;
393 m_Parent.GetScreenSize(size_x, size_y);
394
395 return Math.Min(size_x, size_y);
396 }
397
398 return 0;
399 }
400
401 //============================================
402 // Angle calculations
403 //============================================
404 //get object by angle (degrees)
406 {
407 for (int i = 0; i < m_RadialItemCards.Count(); ++i)
408 {
409 Widget w = m_RadialItemCards.GetKey(i);
412 float min_angle = w_angle - offset;
413 float max_angle = w_angle + offset;
414
415 if (min_angle < 0) min_angle += 360; //clamp 0-360
416 if (max_angle > 360) max_angle -= 360;
417
418 if (min_angle > max_angle) //angle radius is in the cycling point 360->
419 {
420 if (min_angle <= deg_angle) //is cursor position also before this point
421 {
422 if (deg_angle > max_angle)
423 return w;
424 }
425 else //is cursor position after this point
426 {
427 if (deg_angle < max_angle)
428 return w;
429 }
430 }
431 else
432 {
433 if (deg_angle >= min_angle && deg_angle < max_angle) //min, max angles are within 0-360 radius
434 return w;
435 }
436 }
437
438 return NULL;
439 }
440
441 //returns GUI compatible mouse-to-parent angle
442 protected float GetMousePointerAngle()
443 {
444 int mouse_x;
445 int mouse_y;
447
448 float center_x;
449 float center_y;
451
452 float tan_x = mouse_x - center_x;
453 float tan_y = mouse_y - center_y;
454 float angle = Math.Atan2(tan_y, tan_x);
455
456 return angle;
457 }
458
459 //returns distance from parent center
460 protected float GetMouseDistance()
461 {
462 int mouse_x;
463 int mouse_y;
465
466 float center_x;
467 float center_y;
469
471
472 return distance;
473 }
474
475 //return angle 0-360 deg
476 protected float GetAngleInDegrees(float rad_angle)
477 {
478 float rad_deg = rad_angle * Math.RAD2DEG;
479
480 int angle_mp = rad_deg / 360;
481
482 if (rad_deg < 0)
483 {
484 rad_deg = rad_deg - (360 * angle_mp);
485 rad_deg += 360;
486 }
487
488 return rad_deg;
489 }
490
491 //============================================
492 // Update
493 //============================================
494 //mouse
495 int last_time = -1;
496 protected void Update()
497 {
498 if (this && !m_RegisteredClass)
499 {
500 m_UpdateTimer.Stop();
501 return;
502 }
503
504 //get delta time
505 if (last_time < 0)
506 last_time = GetGame().GetTime();
507 int delta_time = GetGame().GetTime() - last_time;
508 last_time = GetGame().GetTime();
509
510 //controls
511 if (this && m_RegisteredClass && m_RegisteredClass.IsVisible())
512 {
513 //mouse controls
515 {
518
519 //--PARAM --safe zone radius--
521 {
522 //Deselect
523 GetGame().GameScript.CallFunction(m_RegisteredClass, "OnMouseDeselect", NULL, m_SelectedObject);
525 //hide selector
527 }
528 else
529 {
530 //Deselect
531 GetGame().GameScript.CallFunction(m_RegisteredClass, "OnMouseDeselect", NULL, m_SelectedObject);
532
533 //Select
535 GetGame().GameScript.CallFunction(m_RegisteredClass, "OnMouseSelect", NULL, m_SelectedObject);
536 //show selector
538 }
539 }
540 //controller controls
541 else if (IsUsingController())
542 {
544
545 //Controller tilt
546 if (m_ControllerAngle > -1 && m_ControllerTilt > -1)
547 {
548 //Right analogue stick
550 //Select
551 if (w_selected)
552 {
554 {
556 {
557 //Deselect
558 GetGame().GameScript.CallFunction(m_RegisteredClass, "OnControllerDeselect", NULL, m_SelectedObject);
559
560 //Select new object
562 GetGame().GameScript.CallFunction(m_RegisteredClass, "OnControllerSelect", NULL, m_SelectedObject);
563 //show selector
565 }
566 }
567 }
568 else
569 {
570 GetGame().GameScript.CallFunction(m_RegisteredClass, "OnControllerDeselect", NULL, m_SelectedObject);
572 //hide selector
574 }
575 }
576 //if controller is giving no feedback
577 else
578 {
580 {
582
584 {
585 GetGame().GameScript.CallFunction(m_RegisteredClass, "OnControllerDeselect", NULL, m_SelectedObject);
587 //hide selector
589
590 m_ControllerTimout = 0; //reset controller timeout
591 }
592 }
593 }
594
595 m_ControllerAngle = -1; //reset angle and tilt
596 m_ControllerTilt = -1;
597 }
598
599 m_WidgetInitialized = true;
600 }
601 }
602
604 {
605 float new_angle = 360 - angle;
606 int angle_mp = new_angle / 360;
607
608 new_angle = new_angle - (360 * angle_mp);
609
610 return new_angle;
611 }
612
613 //============================================
614 // Controls
615 //============================================
617 {
618 Input input = GetGame().GetInput();
619
620 //Controller radial
621 float angle;
622 float tilt;
623 input.GetGamepadThumbDirection(GamepadButton.THUMB_RIGHT, angle, tilt);
625
628 m_ControllerTimout = 0; //reset controller timeout
629
630 //Controller buttons
631 //Select (A,cross)
632 if (m_SelectInputWrapper.InputP().LocalPress())
633 GetGame().GameScript.CallFunction(m_RegisteredClass, "OnControllerPressSelect", NULL, m_SelectedObject);
634
635 //Back (B,circle)
636 if (m_BackInputWrapper.InputP().LocalPress())
637 GetGame().GameScript.CallFunction(m_RegisteredClass, "OnControllerPressBack", NULL, m_SelectedObject);
638 }
639
640 override bool OnMouseButtonUp(Widget w, int x, int y, int button)
641 {
642 if (button == MouseState.LEFT && m_SelectedObject/* && w == m_SelectedObject*/)
643 {
644 //Execute
645 GetGame().GameScript.CallFunction(m_RegisteredClass, "OnMousePressLeft", NULL, m_SelectedObject);
646
647 return true;
648 }
649
650 if (button == MouseState.RIGHT)
651 {
652 //Back one level
653 GetGame().GameScript.CallFunction(m_RegisteredClass, "OnMousePressRight", NULL, NULL);
654
655 return true;
656 }
657
658 return false;
659 }
660}
static AnimSoundObjectBuilderBank GetInstance()
Icon x
Icon y
class OptionSelectorMultistate extends OptionSelector class_name
ref map< Widget, float > m_RadialItemCards
Definition RadialMenu.c:17
static const string RADIAL_ITEM_CARD_CONTAINER
Definition RadialMenu.c:27
float m_AngleRadOffset
Definition RadialMenu.c:19
UAIDWrapper m_SelectInputWrapper
Definition RadialMenu.c:31
UAIDWrapper m_BackInputWrapper
Definition RadialMenu.c:32
float GetMousePointerAngle()
Definition RadialMenu.c:442
bool IsUsingController()
Definition RadialMenu.c:152
float m_RadiusOffset
Definition RadialMenu.c:48
void RegisterClass(UIScriptedMenu class_name)
Definition RadialMenu.c:173
bool m_WidgetInitialized
Definition RadialMenu.c:44
const float CONTROLLER_DESELECT_TIMEOUT
Definition RadialMenu.c:39
static const string RADIAL_SELECTOR
Definition RadialMenu.c:23
void HideRadialSelector()
Definition RadialMenu.c:334
Widget m_SelectedObject
Definition RadialMenu.c:16
Widget m_ItemCardsContainer
Definition RadialMenu.c:10
void UpdataControllerInput()
Definition RadialMenu.c:616
ImageWidget m_RadialSelectorImage
Definition RadialMenu.c:12
void SetExecuteDistOffset(float execute_dist_offset)
Definition RadialMenu.c:188
string m_DelimiterLayout
Definition RadialMenu.c:52
float m_ItemCardRadiusOffset
Definition RadialMenu.c:51
RadialMenuControlType m_ControlType
Definition RadialMenu.c:30
bool m_IsControllerTimoutEnabled
Definition RadialMenu.c:38
void SetWidgetInitialized(bool state)
Definition RadialMenu.c:160
float NormalizeInvertAngle(float angle)
Definition RadialMenu.c:603
void SetOffsetFromTop(float offset_from_top)
Definition RadialMenu.c:194
void SetRadiusOffset(float radius_offset)
Definition RadialMenu.c:182
void GetParentCenter(out float center_x, out float center_y)
Definition RadialMenu.c:370
void ShowRadialSelector(Widget selected_item)
Definition RadialMenu.c:303
static const string RADIAL_SELECTOR_POINTER
Definition RadialMenu.c:25
float GetMouseDistance()
Definition RadialMenu.c:460
Widget m_RadialSelector
Definition RadialMenu.c:11
ref UIScriptedMenu m_RegisteredClass
Definition RadialMenu.c:54
RadialMenuControlType
Definition RadialMenu.c:2
@ CONTROLLER
Definition RadialMenu.c:4
@ MOUSE
Definition RadialMenu.c:3
float m_OffsetFromTop
Definition RadialMenu.c:50
const float MOUSE_SAFE_ZONE_RADIUS
Definition RadialMenu.c:45
ImageWidget m_RadialSelectorPointerImage
Definition RadialMenu.c:13
int m_RadialSelectorDisabledColor
Definition RadialMenu.c:15
float m_ControllerTilt
Definition RadialMenu.c:34
int GetItemCardsCount()
Definition RadialMenu.c:343
static ref RadialMenu m_Instance
Definition RadialMenu.c:55
bool IsUsingMouse()
Definition RadialMenu.c:144
void SetControlType(RadialMenuControlType type)
Definition RadialMenu.c:135
float GetRadius()
Definition RadialMenu.c:358
const float CONTROLLER_TILT_TRESHOLD_SELECT
Definition RadialMenu.c:40
bool IsWidgetInitialized()
Definition RadialMenu.c:165
const float CONTROLLER_TILT_TRESHOLD_EXECUTE
Definition RadialMenu.c:41
static const string RADIAL_SELECTOR_IMAGE
Definition RadialMenu.c:24
int last_time
Definition RadialMenu.c:495
float m_ControllerAngle
Definition RadialMenu.c:33
int m_RadialSelectorOriginalColor
Definition RadialMenu.c:14
void SetWidgetProperties(string delimiter_layout)
Definition RadialMenu.c:211
static const string RADIAL_DELIMITER_CONTAINER
Definition RadialMenu.c:26
int m_ControllerTimout
Definition RadialMenu.c:37
void ActivateControllerTimeout(bool state)
Definition RadialMenu.c:206
void SetItemCardRadiusOffset(float item_card_radius_offset)
Definition RadialMenu.c:200
float GetParentMinSize()
Definition RadialMenu.c:387
void ~RadialMenu()
Definition RadialMenu.c:109
void RadialMenu()
Definition RadialMenu.c:84
float GetAngleInDegrees(float rad_angle)
Definition RadialMenu.c:476
Widget GetObjectByDegAngle(float deg_angle)
Definition RadialMenu.c:405
ref Timer m_UpdateTimer
Definition RadialMenu.c:20
float m_ExecuteDistanceOffset
Definition RadialMenu.c:49
Widget m_Parent
Definition SizeToChild.c:86
proto native UAInputAPI GetUApi()
Definition input.c:11
Definition EnMath.c:7
map: item x vector(index, width, height)
Definition EnWidgets.c:651
void OnWidgetScriptInit(Widget w)
Definition SizeToChild.c:14
proto native UAInput InputP()
static proto native float Distance(vector v1, vector v2)
Returns the distance between tips of two 3D vectors.
proto native CGame GetGame()
GamepadButton
Definition EnSystem.c:341
proto native vector Vector(float x, float y, float z)
Vector constructor from components.
static proto float Min(float x, float y)
Returns smaller of two given values.
static proto float Cos(float angle)
Returns cosinus of angle in radians.
static proto float Atan2(float y, float x)
Returns angle in radians from tangent.
static proto float Sin(float angle)
Returns sinus of angle in radians.
static const float RAD2DEG
Definition EnMath.c:16
static proto float AbsFloat(float f)
Returns absolute value.
static const float PI
Definition EnMath.c:12
MouseState
Definition EnSystem.c:311
proto void GetMousePos(out int x, out int y)
bool OnMouseButtonUp(Widget w, int x, int y, int button)
WidgetFlags
Definition EnWidgets.c:58
int ARGB(int a, int r, int g, int b)
Definition proto.c:322