A game about forced loneliness, made by TACStudios
1using UnityEngine;
2using UnityEditor;
3
4namespace UnityEditor.U2D.Common.Path.GUIFramework
5{
6 /// <summary>
7 /// An implementation of an IGUIState that represents a generic GUI state.
8 /// </summary>
9 internal class GUIState : IGUIState
10 {
11 private Handles.CapFunction nullCap = (int c, Vector3 p , Quaternion r, float s, EventType ev) => {};
12
13 /// <summary>
14 /// The current mouse position.
15 /// </summary>
16 public Vector2 mousePosition
17 {
18 get { return Event.current.mousePosition; }
19 }
20
21 /// <summary>
22 /// The currently pressed button.
23 /// </summary>
24 public int mouseButton
25 {
26 get { return Event.current.button; }
27 }
28
29 /// <summary>
30 /// The current number of mouse clicks.
31 /// </summary>
32 public int clickCount
33 {
34 get { return Event.current.clickCount; }
35 set { Event.current.clickCount = Mathf.Max(0, value); }
36 }
37
38 /// <summary>
39 /// Indicates whether the shift key is pressed.
40 /// </summary>
41 public bool isShiftDown
42 {
43 get { return Event.current.shift; }
44 }
45
46 /// <summary>
47 /// Indicates whether the alt key is pressed.
48 /// </summary>
49 public bool isAltDown
50 {
51 get { return Event.current.alt; }
52 }
53 /// <summary>
54 /// Indicates whether the action key is pressed.
55 /// </summary>
56 public bool isActionKeyDown
57 {
58 get { return EditorGUI.actionKey; }
59 }
60
61 /// <summary>
62 /// The KeyCode of the currently pressed key.
63 /// </summary>
64 public KeyCode keyCode
65 {
66 get { return Event.current.keyCode; }
67 }
68
69 /// <summary>
70 /// The type of the current event.
71 /// </summary>
72 public EventType eventType
73 {
74 get { return Event.current.type; }
75 }
76
77 /// <summary>
78 /// The name of the current event's command.
79 /// </summary>
80 public string commandName
81 {
82 get { return Event.current.commandName; }
83 }
84
85 /// <summary>
86 /// The closest control to the event.
87 /// </summary>
88 public int nearestControl
89 {
90 get { return HandleUtility.nearestControl; }
91 set { HandleUtility.nearestControl = value; }
92 }
93
94 /// <summary>
95 /// Hot Control
96 /// </summary>
97 public int hotControl
98 {
99 get { return GUIUtility.hotControl; }
100 set { GUIUtility.hotControl = value; }
101 }
102
103 /// <summary>
104 /// Indicates whether the GUI has changed.
105 /// </summary>
106 public bool changed
107 {
108 get { return GUI.changed; }
109 set { GUI.changed = value; }
110 }
111
112 /// <summary>
113 /// Gets the ID of a nested control by a hint and focus type.
114 /// </summary>
115 /// <param name="hint">The hint this function uses to identify the control ID.</param>
116 /// <param name="focusType">The focus Type</param>
117 /// <returns>Returns the ID of the control that matches the hint and focus type.</returns>
118 public int GetControlID(int hint, FocusType focusType)
119 {
120 return GUIUtility.GetControlID(hint, focusType);
121 }
122
123 /// <summary>
124 /// Adds a control to the GUIState.
125 /// </summary>
126 /// <param name="controlID">The ID of the control to add.</param>
127 /// <param name="distance">The distance from the camera to the control.</param>
128 public void AddControl(int controlID, float distance)
129 {
130 HandleUtility.AddControl(controlID, distance);
131 }
132
133 /// <summary>
134 /// Checks whether a slider value has changed.
135 /// </summary>
136 /// <param name="id">The ID of the slider to check.</param>
137 /// <param name="sliderData">The slider's data.</param>
138 /// <param name="newPosition">The new position of the slider.</param>
139 /// <returns>Returns `true` if the slider has changed. Otherwise, returns `false`.</returns>
140 public bool Slider(int id, SliderData sliderData, out Vector3 newPosition)
141 {
142 if (mouseButton == 0 && eventType == EventType.MouseDown)
143 {
144 hotControl = 0;
145 nearestControl = id;
146 }
147
148 EditorGUI.BeginChangeCheck();
149 newPosition = Handles.Slider2D(id, sliderData.position, sliderData.forward, sliderData.right, sliderData.up, 1f, nullCap, Vector2.zero);
150 return EditorGUI.EndChangeCheck();
151 }
152
153 /// <summary>
154 /// Uses the current event.
155 /// </summary>
156 public void UseEvent()
157 {
158 Event.current.Use();
159 }
160
161 /// <summary>
162 /// Repaints the GUI.
163 /// </summary>
164 public void Repaint()
165 {
166 HandleUtility.Repaint();
167 }
168
169 /// <summary>
170 /// Checks if the current camera is valid.
171 /// </summary>
172 /// <returns>Returns `true` if the current camera is not null. Otherwise, returns `false`.</returns>
173 public bool HasCurrentCamera()
174 {
175 return Camera.current != null;
176 }
177
178 /// <summary>
179 /// Gets the size of the handle.
180 /// </summary>
181 /// <param name="position">The position of the handle.</param>
182 /// <returns>Returns the size of the handle.</returns>
183 public float GetHandleSize(Vector3 position)
184 {
185 var scale = HasCurrentCamera() ? 0.01f : 0.05f;
186 return HandleUtility.GetHandleSize(position) * scale;
187 }
188
189 /// <summary>
190 /// Measures the GUI-space distance between two points of a segment.
191 /// </summary>
192 /// <param name="p1">The first point.</param>
193 /// <param name="p2">The seconde point.</param>
194 /// <returns>Returns the GUI-space distance between p1 and p2.</returns>
195 public float DistanceToSegment(Vector3 p1, Vector3 p2)
196 {
197 p1 = HandleUtility.WorldToGUIPoint(p1);
198 p2 = HandleUtility.WorldToGUIPoint(p2);
199
200 return HandleUtility.DistancePointToLineSegment(Event.current.mousePosition, p1, p2);
201 }
202
203 /// <summary>
204 /// Measures the distance to a circle.
205 /// </summary>
206 /// <param name="center">The center of the circle.</param>
207 /// <param name="radius">The radius of the circle.</param>
208 /// <returns>Returns the distance to a circle with the specified center and radius.</returns>
209 public float DistanceToCircle(Vector3 center, float radius)
210 {
211 return HandleUtility.DistanceToCircle(center, radius);
212 }
213
214 /// <summary>
215 /// Transforms a GUI-space position into world space.
216 /// </summary>
217 /// <param name="guiPosition">The GUI position</param>
218 /// <param name="planeNormal">The plane normal.</param>
219 /// <param name="planePos">The plane position.</param>
220 /// <returns>Returns the world-space position of `guiPosition`.</returns>
221 public Vector3 GUIToWorld(Vector2 guiPosition, Vector3 planeNormal, Vector3 planePos)
222 {
223 Vector3 worldPos = Handles.inverseMatrix.MultiplyPoint(guiPosition);
224
225 if (Camera.current)
226 {
227 Ray ray = HandleUtility.GUIPointToWorldRay(guiPosition);
228
229 planeNormal = Handles.matrix.MultiplyVector(planeNormal);
230
231 planePos = Handles.matrix.MultiplyPoint(planePos);
232
233 Plane plane = new Plane(planeNormal, planePos);
234
235 float distance = 0f;
236 if (plane.Raycast(ray, out distance))
237 {
238 worldPos = Handles.inverseMatrix.MultiplyPoint(ray.GetPoint(distance));
239 }
240 }
241
242 return worldPos;
243 }
244 }
245}