using UnityEngine;
using UnityEditor;
namespace UnityEditor.U2D.Path.GUIFramework
{
///
/// An implementation of an IGUIState that represents a generic GUI state.
///
public class GUIState : IGUIState
{
private Handles.CapFunction nullCap = (int c, Vector3 p , Quaternion r, float s, EventType ev) => {};
///
/// The current mouse position.
///
public Vector2 mousePosition
{
get { return Event.current.mousePosition; }
}
///
/// The currently pressed button.
///
public int mouseButton
{
get { return Event.current.button; }
}
///
/// The current number of mouse clicks.
///
public int clickCount
{
get { return Event.current.clickCount; }
set { Event.current.clickCount = Mathf.Max(0, value); }
}
///
/// Indicates whether the shift key is pressed.
///
public bool isShiftDown
{
get { return Event.current.shift; }
}
///
/// Indicates whether the alt key is pressed.
///
public bool isAltDown
{
get { return Event.current.alt; }
}
///
/// Indicates whether the action key is pressed.
///
public bool isActionKeyDown
{
get { return EditorGUI.actionKey; }
}
///
/// The KeyCode of the currently pressed key.
///
public KeyCode keyCode
{
get { return Event.current.keyCode; }
}
///
/// The type of the current event.
///
public EventType eventType
{
get { return Event.current.type; }
}
///
/// The name of the current event's command.
///
public string commandName
{
get { return Event.current.commandName; }
}
///
/// The closest control to the event.
///
public int nearestControl
{
get { return HandleUtility.nearestControl; }
set { HandleUtility.nearestControl = value; }
}
///
/// Hot Control
///
public int hotControl
{
get { return GUIUtility.hotControl; }
set { GUIUtility.hotControl = value; }
}
///
/// Indicates whether the GUI has changed.
///
public bool changed
{
get { return GUI.changed; }
set { GUI.changed = value; }
}
///
/// Gets the ID of a nested control by a hint and focus type.
///
/// The hint this function uses to identify the control ID.
/// The focus Type
/// Returns the ID of the control that matches the hint and focus type.
public int GetControlID(int hint, FocusType focusType)
{
return GUIUtility.GetControlID(hint, focusType);
}
///
/// Adds a control to the GUIState.
///
/// The ID of the control to add.
/// The distance from the camera to the control.
public void AddControl(int controlID, float distance)
{
HandleUtility.AddControl(controlID, distance);
}
///
/// Checks whether a slider value has changed.
///
/// The ID of the slider to check.
/// The slider's data.
/// The new position of the slider.
/// Returns `true` if the slider has changed. Otherwise, returns `false`.
public bool Slider(int id, SliderData sliderData, out Vector3 newPosition)
{
if (mouseButton == 0 && eventType == EventType.MouseDown)
{
hotControl = 0;
nearestControl = id;
}
EditorGUI.BeginChangeCheck();
newPosition = Handles.Slider2D(id, sliderData.position, sliderData.forward, sliderData.right, sliderData.up, 1f, nullCap, Vector2.zero);
return EditorGUI.EndChangeCheck();
}
///
/// Uses the current event.
///
public void UseEvent()
{
Event.current.Use();
}
///
/// Repaints the GUI.
///
public void Repaint()
{
HandleUtility.Repaint();
}
///
/// Checks if the current camera is valid.
///
/// Returns `true` if the current camera is not null. Otherwise, returns `false`.
public bool HasCurrentCamera()
{
return Camera.current != null;
}
///
/// Gets the size of the handle.
///
/// The position of the handle.
/// Returns the size of the handle.
public float GetHandleSize(Vector3 position)
{
var scale = HasCurrentCamera() ? 0.01f : 0.05f;
return HandleUtility.GetHandleSize(position) * scale;
}
///
/// Measures the GUI-space distance between two points of a segment.
///
/// The first point.
/// The seconde point.
/// Returns the GUI-space distance between p1 and p2.
public float DistanceToSegment(Vector3 p1, Vector3 p2)
{
p1 = HandleUtility.WorldToGUIPoint(p1);
p2 = HandleUtility.WorldToGUIPoint(p2);
return HandleUtility.DistancePointToLineSegment(Event.current.mousePosition, p1, p2);
}
///
/// Measures the distance to a circle.
///
/// The center of the circle.
/// The radius of the circle.
/// Returns the distance to a circle with the specified center and radius.
public float DistanceToCircle(Vector3 center, float radius)
{
return HandleUtility.DistanceToCircle(center, radius);
}
///
/// Transforms a GUI-space position into world space.
///
/// The GUI position
/// The plane normal.
/// The plane position.
/// Returns the world-space position of `guiPosition`.
public Vector3 GUIToWorld(Vector2 guiPosition, Vector3 planeNormal, Vector3 planePos)
{
Vector3 worldPos = Handles.inverseMatrix.MultiplyPoint(guiPosition);
if (Camera.current)
{
Ray ray = HandleUtility.GUIPointToWorldRay(guiPosition);
planeNormal = Handles.matrix.MultiplyVector(planeNormal);
planePos = Handles.matrix.MultiplyPoint(planePos);
Plane plane = new Plane(planeNormal, planePos);
float distance = 0f;
if (plane.Raycast(ray, out distance))
{
worldPos = Handles.inverseMatrix.MultiplyPoint(ray.GetPoint(distance));
}
}
return worldPos;
}
}
}