123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336 |
- using UnityEditor;
- using UnityEngine;
- using UnityEditor.Sprites;
- using System.Collections;
- using System.Collections.Generic;
-
- namespace UnityEditor.U2D
- {
- internal enum AngleRangeAction
- {
- SelectRange,
- ModifyRange,
- CreateRange,
- ModifySelector,
- RemoveRange,
- }
-
- internal 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);
- }
-
- internal 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;
- }
- }
- }
|