Singularity/Library/PackageCache/com.unity.2d.spriteshape@7.0.7/Editor/AngleRangeView.cs

337 lines
12 KiB
C#
Raw Normal View History

2024-05-06 14:45:45 -04:00
using UnityEditor;
using UnityEngine;
using UnityEditor.Sprites;
using System.Collections;
using System.Collections.Generic;
namespace UnityEditor.U2D
{
public enum AngleRangeAction
{
SelectRange,
ModifyRange,
CreateRange,
ModifySelector,
RemoveRange,
}
public interface IAngleRangeView
{
int hoveredRangeIndex { get; }
void RequestFocusIndex(int index);
float GetAngleFromPosition(Rect rect, float angleOffset);
void Repaint();
void SetupLayout(Rect rect, float angleOffset, float radius);
bool DoAngleRange(int index, Rect rect, float radius, float angleOffset, ref float start, ref float end, bool snap, bool disabled, Color gradientMin, Color gradientMid, Color gradientMax);
bool DoSelectAngleRange(int currentSelected, out int newSelected);
bool DoCreateRange(Rect rect, float radius, float angleOffset, float start, float end);
void DoCreateRangeTooltip();
bool DoSelector(Rect rect, float angleOffset, float radius, float angle, out float newAngle);
bool DoRemoveRange();
bool IsActionActive(AngleRangeAction action);
bool IsActionTriggering(AngleRangeAction action);
bool IsActionFinishing(AngleRangeAction action);
void DrawAngleRangeOutline(Rect rect, float start, float end, float angleOffset, float radius);
}
public class AngleRangeView : IAngleRangeView
{
const string kDeleteCommandName = "Delete";
const string kSoftDeleteCommandName = "SoftDelete";
static readonly int kAngleRangeHashCode = "AngleRange".GetHashCode();
static readonly int kCreateRangeHashCode = "CreateRange".GetHashCode();
static readonly int kSelectorHashCode = "Selector".GetHashCode();
private static Color kHightlightColor = new Color(0.25f, 0.5f, 1.0f);
private static Color kNoKeboardFocusColor = new Color(0.3f, 0.5f, 0.65f);
private static class Contents
{
public static readonly GUIContent addRangeTooltip = new GUIContent("", "Click to add a new range");
}
private int m_FocusedRangeControlID = -1;
private int m_HoveredRangeIndex = -1;
private int m_HoveredRangeID = -1;
private int m_HoveredHandleID = -1;
private int m_HotHandleID = -1;
private int m_CreateRangeControlID = -1;
private int m_SelectorControlID = -1;
private int m_RequestFocusIndex = -1;
public int hoveredRangeIndex { get { return m_HoveredRangeIndex; } }
public void RequestFocusIndex(int index)
{
GUIUtility.keyboardControl = 0;
m_RequestFocusIndex = index;
}
public float GetAngleFromPosition(Rect rect, float angleOffset)
{
return Mathf.RoundToInt(SpriteShapeHandleUtility.PosToAngle(Event.current.mousePosition, rect.center, -angleOffset));
}
public void Repaint()
{
HandleUtility.Repaint();
}
public void SetupLayout(Rect rect, float angleOffset, float radius)
{
m_CreateRangeControlID = GUIUtility.GetControlID(kCreateRangeHashCode, FocusType.Passive);
m_SelectorControlID = GUIUtility.GetControlID(kSelectorHashCode, FocusType.Passive);
LayoutCreateRange(rect, angleOffset, radius);
if (Event.current.type == EventType.Layout)
{
m_HoveredRangeIndex = -1;
m_HoveredRangeID = -1;
m_HoveredHandleID = -1;
if (GUIUtility.hotControl == 0)
{
m_HotHandleID = -1;
}
}
}
private void LayoutCreateRange(Rect rect, float angleOffset, float radius)
{
if (Event.current.type == EventType.Layout)
{
var mousePosition = Event.current.mousePosition;
var distance = SpriteShapeHandleUtility.DistanceToArcWidth(mousePosition, rect.center, 0f, 360f, radius, AngleRangeGUI.kRangeWidth, angleOffset);
HandleUtility.AddControl(m_CreateRangeControlID, distance);
}
}
public bool DoAngleRange(int index, Rect rect, float radius, float angleOffset, ref float start, ref float end, bool snap, bool disabled, Color gradientMin, Color gradientMid, Color gradientMax)
{
var changed = false;
var controlID = GUIUtility.GetControlID(kAngleRangeHashCode, FocusType.Passive);
var leftHandleId = GUIUtility.GetControlID(AngleRangeGUI.kLeftHandleHashCode, FocusType.Passive);
var rightHandleId = GUIUtility.GetControlID(AngleRangeGUI.kRightHandleHashCode, FocusType.Passive);
if (Event.current.type == EventType.Layout)
{
var distance = SpriteShapeHandleUtility.DistanceToArcWidth(Event.current.mousePosition, rect.center, start, end, radius, AngleRangeGUI.kRangeWidth, angleOffset);
HandleUtility.AddControl(controlID, distance);
if (HandleUtility.nearestControl == controlID)
{
m_HoveredRangeIndex = index;
m_HoveredRangeID = controlID;
}
}
if (IsActionTriggering(AngleRangeAction.ModifyRange))
{
m_HotHandleID = m_HoveredHandleID;
GrabKeyboardFocus(controlID);
}
if (m_RequestFocusIndex == index)
{
GrabKeyboardFocus(controlID);
if (Event.current.type == EventType.Repaint)
m_RequestFocusIndex = -1;
}
using (new EditorGUI.DisabledScope(disabled))
{
var midAngle = (end - start) * 0.5f + start;
var t = 2f * (midAngle + 180f) / 360f;
var color = gradientMin;
if (t < 1f)
color = Color.Lerp(gradientMin, gradientMid, t);
else
color = Color.Lerp(gradientMid, gradientMax, t - 1f);
if (!disabled)
{
color = kNoKeboardFocusColor;
if (HasKeyboardFocus())
color = kHightlightColor;
}
EditorGUI.BeginChangeCheck();
AngleRangeGUI.AngleRangeField(rect, leftHandleId, rightHandleId, ref start, ref end, angleOffset, radius, snap, false, false, color);
changed = EditorGUI.EndChangeCheck();
}
//Extra Layout from handles
if (Event.current.type == EventType.Layout &&
(HandleUtility.nearestControl == leftHandleId || HandleUtility.nearestControl == rightHandleId))
{
m_HoveredRangeIndex = index;
m_HoveredRangeID = controlID;
m_HoveredHandleID = HandleUtility.nearestControl;
}
return changed;
}
public bool DoSelectAngleRange(int currentSelected, out int newSelected)
{
newSelected = currentSelected;
if (IsActionTriggering(AngleRangeAction.SelectRange))
{
newSelected = m_HoveredRangeIndex;
GUI.changed = true;
Repaint();
HandleUtility.nearestControl = m_SelectorControlID;
return true;
}
return false;
}
public bool DoCreateRange(Rect rect, float radius, float angleOffset, float start, float end)
{
if (IsActionTriggering(AngleRangeAction.CreateRange))
{
GUI.changed = true;
HandleUtility.nearestControl = m_SelectorControlID;
return true;
}
if (IsActionActive(AngleRangeAction.CreateRange))
{
DrawAngleRangeOutline(rect, start, end, angleOffset, radius);
if (Event.current.type == EventType.MouseMove)
Repaint();
}
return false;
}
public void DoCreateRangeTooltip()
{
if (IsActionActive(AngleRangeAction.CreateRange))
{
var mousePosition = Event.current.mousePosition;
EditorGUI.LabelField(new Rect(mousePosition, new Vector2(1f, 20f)), Contents.addRangeTooltip);
}
}
public bool DoSelector(Rect rect, float angleOffset, float radius, float angle, out float newAngle)
{
EditorGUI.BeginChangeCheck();
newAngle = AngleRangeGUI.AngleField(rect, m_SelectorControlID, angle, angleOffset, Vector2.down * 7.5f, angle, 15f, radius - AngleRangeGUI.kRangeWidth, true, true, false, SpriteShapeHandleUtility.PlayHeadCap);
return EditorGUI.EndChangeCheck();
}
public bool DoRemoveRange()
{
EventType eventType = Event.current.type;
if (IsActionTriggering(AngleRangeAction.RemoveRange))
{
Event.current.Use();
GUI.changed = true;
return true;
}
return false;
}
public bool IsActionActive(AngleRangeAction action)
{
if (GUIUtility.hotControl != 0)
return false;
if (action == AngleRangeAction.SelectRange)
return HandleUtility.nearestControl == m_HoveredRangeID;
if (action == AngleRangeAction.ModifyRange)
return HandleUtility.nearestControl == m_HoveredHandleID;
if (action == AngleRangeAction.CreateRange)
return HandleUtility.nearestControl == m_CreateRangeControlID;
if (action == AngleRangeAction.ModifySelector)
return HandleUtility.nearestControl == m_SelectorControlID;
if (action == AngleRangeAction.RemoveRange)
return HasKeyboardFocus();
return false;
}
public bool IsActionHot(AngleRangeAction action)
{
if (GUIUtility.hotControl == 0)
return false;
if (action == AngleRangeAction.ModifyRange)
return GUIUtility.hotControl == m_HotHandleID;
return false;
}
public bool IsActionTriggering(AngleRangeAction action)
{
if (!IsActionActive(action))
return false;
EventType eventType = Event.current.type;
if (action == AngleRangeAction.RemoveRange)
{
if ((eventType == EventType.ValidateCommand || eventType == EventType.ExecuteCommand)
&& (Event.current.commandName == kSoftDeleteCommandName || Event.current.commandName == kDeleteCommandName))
{
if (eventType == EventType.ExecuteCommand)
return true;
Event.current.Use();
}
return false;
}
return eventType == EventType.MouseDown && Event.current.button == 0;
}
public bool IsActionFinishing(AngleRangeAction action)
{
if (!IsActionHot(action))
return false;
return (Event.current.type == EventType.MouseUp && Event.current.button == 0) || Event.current.type == EventType.Ignore;
}
public void DrawAngleRangeOutline(Rect rect, float start, float end, float angleOffset, float radius)
{
if (Event.current.type == EventType.Repaint)
SpriteShapeHandleUtility.DrawRangeOutline(start, end, angleOffset, rect.center, radius, AngleRangeGUI.kRangeWidth - 1f);
}
private void GrabKeyboardFocus(int controlID)
{
m_FocusedRangeControlID = controlID;
GUIUtility.keyboardControl = controlID;
}
private bool HasKeyboardFocus()
{
return GUIUtility.keyboardControl == m_FocusedRangeControlID;
}
}
}