public void OnInspectorGUI(Spline spline)
        {
            m_Spline = spline;

            if (SpriteShapeTool.instance != null)
            {
                if (SpriteShapeTool.instance.splineEditor != null)
                {
                    SpriteShapeTool.instance.splineEditor.GetAngleRange = GetAngleRange;
                }
            }

            EditorGUI.BeginChangeCheck();

            if (GUI.enabled && SplineEditorCache.GetSelection().Count > 0)
            {
                EditorGUILayout.LabelField(Contents.pointLabel, EditorStyles.boldLabel);

                DoTangentGUI();
                DoPointInspector();
                SnappingUtility.enabled = EditorGUILayout.Toggle(Contents.enableSnapLabel, SnappingUtility.enabled);
            }

            if (EditorGUI.EndChangeCheck())
            {
                SetDirty();
            }
        }
Beispiel #2
0
        private void ValidateTangents(bool rightTangentChanged)
        {
            var selection    = SplineEditorCache.GetSelection();
            var mode         = GetTangentMode(selection.single);
            var leftTangent  = GetLeftTangent(selection.single);
            var rightTangent = GetRightTangent(selection.single);

            if (mode == TangentMode.Continuous)
            {
                if (rightTangentChanged && rightTangent.magnitude > 0)
                {
                    var len = leftTangent.magnitude;
                    var rta = rightTangent.normalized;
                    leftTangent = -rta * len;
                }
                else if (leftTangent.magnitude > 0)
                {
                    var len = rightTangent.magnitude;
                    var lta = leftTangent.normalized;
                    rightTangent = -lta * len;
                }
            }

            SetLeftTangent(selection.single, leftTangent);
            SetRightTangent(selection.single, rightTangent);

            SplineEditorCache.instance.rightTangentChanged = rightTangentChanged;

            UpdateTangentCache();
        }
Beispiel #3
0
        private void ClearSelection()
        {
            SplineEditorCache.RigisterUndo("Edit Selection");
            SplineEditorCache.ClearSelection();

            GUI.changed = true;
        }
Beispiel #4
0
        private void DrawPoints()
        {
            if (currentEvent.type != EventType.Repaint)
            {
                return;
            }

            for (int index = 0; index < GetPointCount(); index++)
            {
                var position = GetPosition(index);

                if (m_ActivePointIndex == index)
                {
                    GetPointCapActive(0, position, Quaternion.LookRotation(GetForwardVector(), GetUpVector()), GetHandleSize(position), currentEvent.type);
                }
                else if (m_HoveredPointIndex == index && GUIUtility.hotControl == 0)
                {
                    GetPointCapHovered(0, position, Quaternion.LookRotation(GetForwardVector(), GetUpVector()), GetHandleSize(position), currentEvent.type);
                }
                else if (SplineEditorCache.GetSelection().IsSelected(index))
                {
                    GetPointCapSelected(0, position, Quaternion.LookRotation(GetForwardVector(), GetUpVector()), GetHandleSize(position), currentEvent.type);
                }
                else
                {
                    GetPointCapNormal(0, position, Quaternion.LookRotation(GetForwardVector(), GetUpVector()), GetHandleSize(position), currentEvent.type);
                }
            }
        }
        private int GetAngleRange(int index)
        {
            int startPoint           = 0;
            SpriteShapeController sc = SplineEditorCache.GetTarget();

            return(GetAngleRange(sc, index, ref startPoint));
        }
Beispiel #6
0
        private void ResetTangents(int pointIndex)
        {
            Vector3 position     = GetPosition(pointIndex);
            Vector3 positionNext = GetPosition(SplineUtility.NextIndex(pointIndex, GetPointCount()));
            Vector3 positionPrev = GetPosition(SplineUtility.PreviousIndex(pointIndex, GetPointCount()));
            Vector3 forward      = Vector3.forward;

            if (SplineEditorCache.IsValid() && SplineEditorCache.GetTarget() != null)
            {
                forward = SplineEditorCache.GetTarget().transform.forward;
            }

            float scale = Mathf.Min((positionNext - position).magnitude, (positionPrev - position).magnitude) * 0.33f;

            Vector3 leftTangent  = (positionPrev - position).normalized * scale;
            Vector3 rightTangent = (positionNext - position).normalized * scale;

            if (GetTangentMode(pointIndex) == TangentMode.Continuous)
            {
                SplineUtility.CalculateTangents(position, positionPrev, positionNext, forward, scale, out rightTangent, out leftTangent);
            }

            SetLeftTangent(pointIndex, leftTangent);
            SetRightTangent(pointIndex, rightTangent);
        }
Beispiel #7
0
        public void SetTangentModeUseThisOne(int pointIndex, TangentMode mode)
        {
            SetTangentMode(pointIndex, mode);

            if (SplineEditorCache.IsValid() && SplineEditorCache.GetTarget() != null)
            {
                if (mode == TangentMode.Continuous)
                {
                    SetLeftTangent(pointIndex, SplineEditorCache.instance.GetLeftTangentContinous(pointIndex));
                    SetRightTangent(pointIndex, SplineEditorCache.instance.GetRightTangentContinous(pointIndex));
                }
                if (mode == TangentMode.Broken)
                {
                    SetLeftTangent(pointIndex, SplineEditorCache.instance.GetLeftTangentBroken(pointIndex));
                    SetRightTangent(pointIndex, SplineEditorCache.instance.GetRightTangentBroken(pointIndex));
                }
            }

            if (mode == TangentMode.Continuous || mode == TangentMode.Broken)
            {
                if (GetLeftTangent(pointIndex).sqrMagnitude == 0f && GetRightTangent(pointIndex).sqrMagnitude == 0f)
                {
                    ResetTangents(pointIndex);
                }
            }

            SetDirty();
        }
Beispiel #8
0
        public void CycleSpriteIndex()
        {
            var selection   = SplineEditorCache.GetSelection();
            var spriteShape = SplineEditorCache.GetTarget().spriteShape;

            if (selection.single == -1 || spriteShape == null)
            {
                return;
            }

            Debug.Assert(SplineEditorCache.GetTarget() != null);

            var angleRangeIndex = GetAngleRange(selection.single);

            if (angleRangeIndex != -1)
            {
                var angleRange  = spriteShape.angleRanges[angleRangeIndex];
                var spriteIndex = 0;
                if (angleRange.sprites.Count > 0)
                {
                    spriteIndex = (GetSpriteIndex(selection.single) + 1) % angleRange.sprites.Count;
                }

                RegisterUndo();
                SetSpriteIndex(selection.single, spriteIndex);
                SetDirty();
            }
        }
Beispiel #9
0
        private void DrawTangents()
        {
            ISelection selection = SplineEditorCache.GetSelection();

            int selectedPoint = selection.single;

            if (selectedPoint == -1 || GetTangentMode(selectedPoint) == TangentMode.Linear || currentEvent.type != EventType.Repaint)
            {
                return;
            }

            Vector3 position     = GetPosition(selectedPoint);
            Vector3 leftTangent  = GetLeftTangent(selectedPoint);
            Vector3 rightTangent = GetRightTangent(selection.single);

            Color color = kTangentColor;

            DrawTangentLine(position, leftTangent, color);

            if (GetTangentMode(selectedPoint) == TangentMode.Broken)
            {
                color = kTangentColorAlternative;
            }

            DrawTangentLine(position, rightTangent, color);

            if (m_ActiveTangentPointIndex != -1)
            {
                if (m_DragLeftTangent)
                {
                    GetTangentCapActive(0, leftTangent + position, Quaternion.identity, GetHandleSize(leftTangent + position), EventType.Repaint);
                    GetTangentCapNormal(0, rightTangent + position, Quaternion.identity, GetHandleSize(rightTangent + position), EventType.Repaint);
                }
                else
                {
                    GetTangentCapNormal(0, leftTangent + position, Quaternion.identity, GetHandleSize(leftTangent + position), EventType.Repaint);
                    GetTangentCapActive(0, rightTangent + position, Quaternion.identity, GetHandleSize(rightTangent + position), EventType.Repaint);
                }
            }
            else if (GUIUtility.hotControl == 0 && m_HoveredTangentPoint != -1)
            {
                if (m_HoveredLeftTangent)
                {
                    GetTangentCapHovered(0, leftTangent + position, Quaternion.identity, GetHandleSize(leftTangent + position), EventType.Repaint);
                    GetTangentCapNormal(0, rightTangent + position, Quaternion.identity, GetHandleSize(rightTangent + position), EventType.Repaint);
                }
                else
                {
                    GetTangentCapNormal(0, leftTangent + position, Quaternion.identity, GetHandleSize(leftTangent + position), EventType.Repaint);
                    GetTangentCapHovered(0, rightTangent + position, Quaternion.identity, GetHandleSize(rightTangent + position), EventType.Repaint);
                }
            }
            else
            {
                GetTangentCapNormal(0, leftTangent + position, Quaternion.identity, GetHandleSize(leftTangent + position), EventType.Repaint);
                GetTangentCapNormal(0, rightTangent + position, Quaternion.identity, GetHandleSize(rightTangent + position), EventType.Repaint);
            }
        }
        private int ResolveSpriteIndex(List <int> spriteIndices, ISelection selection, ref List <int> startPoints)
        {
            var spriteIndexValue     = spriteIndices.FirstOrDefault();
            SpriteShapeController sc = SplineEditorCache.GetTarget();

            if (sc == null || sc.spriteShape == null)
            {
                return(-1);
            }

            // Either SpriteShape Asset or SpriteShape Data has changed.
            List <ShapeAngleRange> angleRanges = GetAngleRangeSorted(sc.spriteShape);

            if (m_SpriteShapeHashCode != sc.spriteShapeHashCode)
            {
                GenerateSegments(sc, angleRanges);
                m_SpriteShapeHashCode = sc.spriteShapeHashCode;
                m_SelectedPoint       = -1;
            }

            if (sc.spriteShape != null)
            {
                if (selection.single != -1)
                {
                    m_SelectedAngleRange = GetAngleRange(sc, selection.single, ref m_SelectedPoint);
                    startPoints.Add(m_SelectedPoint);
                    spriteIndexValue = m_Spline.GetSpriteIndex(m_SelectedPoint);
                }
                else
                {
                    m_SelectedAngleRange = -1;
                    foreach (var index in selection)
                    {
                        int startPoint = index;
                        int angleRange = GetAngleRange(sc, index, ref startPoint);
                        if (m_SelectedAngleRange != -1 && angleRange != m_SelectedAngleRange)
                        {
                            m_SelectedAngleRange = -1;
                            break;
                        }
                        startPoints.Add(startPoint);
                        m_SelectedAngleRange = angleRange;
                    }
                }
            }

            if (m_SelectedAngleRange != -1)
            {
                spriteSelector.UpdateSprites(sc.spriteShape.angleRanges[m_SelectedAngleRange].sprites.ToArray());
            }
            else
            {
                spriteIndexValue = -1;
            }
            return(spriteIndexValue);
        }
Beispiel #11
0
        private void RegisterUndoOnSliderChangedOnce()
        {
            Debug.Assert(GUIUtility.hotControl != 0);

            if (m_SliderChanged == false)
            {
                m_SliderChanged = true;
                RegisterUndo();
                SplineEditorCache.RigisterUndo();
            }
        }
Beispiel #12
0
        private int GetAngleRangeLocal(int index)
        {
            var selection       = SplineEditorCache.GetSelection();
            var spriteShape     = SplineEditorCache.GetTarget().spriteShape;
            var nextIndex       = SplineUtility.NextIndex(selection.single, GetPointCount());
            var pos1            = GetLocalPosition(selection.single);
            var pos2            = GetLocalPosition(nextIndex);
            var angle           = SplineUtility.SlopeAngle(pos1, pos2) + 90;
            var angleRangeIndex = SpriteShapeEditorUtility.GetRangeIndexFromAngle(spriteShape, angle);

            return(angleRangeIndex);
        }
        private void SelectionChanged()
        {
            if (target == null)
            {
                return;
            }

            if (target != SplineEditorCache.GetTarget())
            {
                SplineEditorCache.RigisterUndo();
            }

            InvalidateShapeEditor();
        }
Beispiel #14
0
        private void LayoutTangents()
        {
            ISelection selection = SplineEditorCache.GetSelection();

            int selectedPoint = selection.single;

            if (selectedPoint == -1 || selectedPoint >= GetPointCount())
            {
                return;
            }

            if (GetTangentMode(selectedPoint) == TangentMode.Linear)
            {
                return;
            }

            int tangentId = GUIUtility.GetControlID(m_TangentHashCode, FocusType.Passive);

            Vector3 position = GetPosition(selectedPoint);

            if (currentEvent.type == EventType.Layout)
            {
                Vector3 leftTangentPosition = GetLeftTangent(selectedPoint);
                GetTangentCapNormal(tangentId, leftTangentPosition + position, Quaternion.identity, GetHandleSize(leftTangentPosition + position), EventType.Layout);

                if (HandleUtility.nearestControl == tangentId)
                {
                    m_HoveredTangentPoint = selectedPoint;
                    m_HoveredLeftTangent  = true;
                    m_HoveredPointIndex   = -1;
                }
            }

            tangentId = GUIUtility.GetControlID(m_TangentHashCode, FocusType.Passive);

            if (currentEvent.type == EventType.Layout)
            {
                Vector3 rightTangentPosition = GetRightTangent(selection.single);
                GetTangentCapNormal(tangentId, rightTangentPosition + position, Quaternion.identity, GetHandleSize(rightTangentPosition + position), EventType.Layout);

                if (HandleUtility.nearestControl == tangentId)
                {
                    m_HoveredTangentPoint = selectedPoint;
                    m_HoveredLeftTangent  = false;
                    m_HoveredPointIndex   = -1;
                }
            }
        }
Beispiel #15
0
        private void MoveSelectedPoints(Vector3 delta)
        {
            ISelection selection = SplineEditorCache.GetSelection();

            RegisterUndo();

            if (delta.sqrMagnitude < float.Epsilon)
            {
                return;
            }

            foreach (int index in selection)
            {
                SetPosition(index, GetPosition(index) + delta);
            }
        }
Beispiel #16
0
        public void CycleTangentMode()
        {
            var selection = SplineEditorCache.GetSelection();

            if (selection.single == -1)
            {
                return;
            }

            RegisterUndo();

            var oldMode = GetTangentMode(selection.single);
            var newMode = GetNextTangentMode(oldMode);

            SetTangentModeUseThisOne(selection.single, newMode);
        }
        private bool InitializeCheck()
        {
            if (target != SplineEditorCache.GetTarget())
            {
                InvalidateShapeEditor();
                SplineEditorCache.ClearSelection();
                SplineEditorCache.SetTarget(target);
            }

            if (target != null && m_SplineEditor == null)
            {
                SetupSpriteShapeEditor(target.spline);
            }

            return(target != null);
        }
        private void DoRectSelectionGUI()
        {
            Debug.Assert(m_Spline != null);

            var selection = SplineEditorCache.GetSelection();

            if (m_RectSelectionID == -1)
            {
                m_RectSelectionID = GUIUtility.GetControlID("RectSelection".GetHashCode(), FocusType.Passive);
            }

            if (Event.current.GetTypeForControl(m_RectSelectionID) == EventType.MouseDown && Event.current.button == 0)
            {
                if (!Event.current.shift && !EditorGUI.actionKey)
                {
                    SplineEditorCache.RigisterUndo("Edit Selection");
                    SplineEditorCache.ClearSelection();
                    GUI.changed = true;
                }
            }

            if (Event.current.GetTypeForControl(m_RectSelectionID) == EventType.MouseUp && Event.current.button == 0)
            {
                SplineEditorCache.RigisterUndo("Edit Selection");

                selection.EndSelection(true);

                GUI.changed = true;
            }

            EditorGUI.BeginChangeCheck();

            var selectionRect = m_RectSelectionTool.Do(m_RectSelectionID, GetTransform().position);

            if (EditorGUI.EndChangeCheck())
            {
                selection.BeginSelection();

                for (int i = 0; i < m_Spline.GetPointCount(); ++i)
                {
                    if (selectionRect.Contains(HandleUtility.WorldToGUIPoint(LocalToWorld(m_Spline.GetPosition(i))), true))
                    {
                        selection.Select(i, true);
                    }
                }
            }
        }
Beispiel #19
0
        private void Framing()
        {
            if (GetPointCount() == 0)
            {
                return;
            }

            ISelection selection = SplineEditorCache.GetSelection();

            if (currentEvent.commandName == "FrameSelected" && selection.Count > 0)
            {
                switch (currentEvent.type)
                {
                case EventType.ExecuteCommand:
                    Bounds bounds = default(Bounds);

                    if (selection.Count == 0)
                    {
                        bounds = new Bounds(GetPosition(0), Vector3.zero);

                        for (int index = 1; index < GetPointCount(); ++index)
                        {
                            bounds.Encapsulate(GetPosition(index));
                        }
                    }
                    else
                    {
                        bounds = new Bounds(GetPosition(selection.any), Vector3.zero);

                        foreach (int index in selection)
                        {
                            bounds.Encapsulate(GetPosition(index));
                        }
                    }

                    Frame(bounds);

                    currentEvent.Use();
                    break;

                case EventType.ValidateCommand:
                    currentEvent.Use();
                    break;
                }
            }
        }
Beispiel #20
0
        private void SelectPoint(int index)
        {
            ISelection selection = SplineEditorCache.GetSelection();

            bool additive    = currentEvent.shift;
            bool subtractive = EditorGUI.actionKey;

            SplineEditorCache.RigisterUndo("Edit Selection");

            if (!additive && !subtractive)
            {
                SplineEditorCache.ClearSelection();
            }

            selection.Select(index, (!selection.IsSelected(index) || additive) && !subtractive);

            GUI.changed = true;
        }
Beispiel #21
0
        public void MirrorTangent()
        {
            if (SpriteShapeTool.instance.isActive && SplineEditorCache.IsValid() && SplineEditorCache.GetTarget() != null)
            {
                var selection = SplineEditorCache.GetSelection();

                if (selection.Count != 1)
                {
                    return;
                }

                var mode = GetTangentMode(selection.single);

                if (mode == TangentMode.Linear)
                {
                    return;
                }

                var leftTangent  = GetLeftTangent(selection.single);
                var rightTangent = GetRightTangent(selection.single);

                if (!Mathf.Approximately((leftTangent + rightTangent).sqrMagnitude, 0f))
                {
                    if (GUIUtility.hotControl == 0)
                    {
                        Undo.RegisterCompleteObjectUndo(SplineEditorCache.GetTarget(), "Mirror Tangents");
                    }

                    if (SplineEditorCache.instance.rightTangentChanged)
                    {
                        SetLeftTangent(selection.single, rightTangent * -1);
                    }
                    else
                    {
                        SetRightTangent(selection.single, leftTangent * -1);
                    }

                    UpdateTangentCache();
                }
            }
        }
Beispiel #22
0
        private void DeleteSelected()
        {
            ISelection selection = SplineEditorCache.GetSelection();

            if (GetPointCount() <= 2)
            {
                return;
            }

            RegisterUndo();

            List <int> indices = new List <int>(selection);

            indices.Sort();

            for (int i = indices.Count - 1; i >= 0; --i)
            {
                RemovePointAt(indices[i]);
            }

            ClearSelection();

            GUI.changed = true;
        }
 private void SetDirty()
 {
     Debug.Assert(SpriteShapeTool.instance.isActive);
     EditorUtility.SetDirty(SplineEditorCache.GetTarget());
 }
 private void RegisterUndo(string name)
 {
     Debug.Assert(SpriteShapeTool.instance.isActive);
     Undo.RegisterCompleteObjectUndo(SplineEditorCache.GetTarget(), name);
 }
        private void DoPointInspector()
        {
            var selection     = SplineEditorCache.GetSelection();
            var positions     = new List <Vector3>();
            var heights       = new List <float>();
            var spriteIndices = new List <int>();
            var corners       = new List <bool>();

            foreach (int index in selection)
            {
                positions.Add(m_Spline.GetPosition(index));
                heights.Add(m_Spline.GetHeight(index));
                spriteIndices.Add(m_Spline.GetSpriteIndex(index));
                corners.Add(m_Spline.GetCorner(index));
            }

            EditorGUIUtility.wideMode = true;

            EditorGUI.BeginChangeCheck();

            positions = MultiVector2Field(Contents.positionLabel, positions, 1.5f);

            if (EditorGUI.EndChangeCheck())
            {
                RegisterUndo("Inspector");

                for (int index = 0; index < positions.Count; index++)
                {
                    m_Spline.SetPosition(selection.ElementAt(index), positions[index]);
                }
                SceneView.RepaintAll();
            }

            EditorGUIUtility.wideMode = false;

            bool mixedValue = EditorGUI.showMixedValue;

            EditorGUI.BeginChangeCheck();

            var heightValue = heights.FirstOrDefault();

            EditorGUI.showMixedValue = heights.All(h => Mathf.Approximately(h, heightValue)) == false;

            heightValue = EditorGUILayout.Slider(Contents.heightLabel, heightValue, 0.1f, 4.0f);

            if (EditorGUI.EndChangeCheck())
            {
                RegisterUndo("Inspector");

                foreach (var index in selection)
                {
                    m_Spline.SetHeight(index, heightValue);
                }
            }

            List <int> startPoints      = new List <int>();
            var        spriteIndexValue = ResolveSpriteIndex(spriteIndices, selection, ref startPoints);

            if (spriteIndexValue != -1)
            {
                EditorGUI.BeginChangeCheck();

                spriteSelector.ShowGUI(spriteIndexValue);

                if (EditorGUI.EndChangeCheck())
                {
                    RegisterUndo("Inspector");
                    foreach (var index in startPoints)
                    {
                        m_Spline.SetSpriteIndex(index, spriteSelector.selectedIndex);
                    }
                }
            }
            EditorGUILayout.Space();

            EditorGUI.BeginChangeCheck();

            var cornerValue = corners.FirstOrDefault();

            EditorGUI.showMixedValue = corners.All(v => (v == cornerValue)) == false;

            cornerValue = EditorGUILayout.IntPopup(Contents.cornerLabel, cornerValue ? 1 : 0, Contents.cornerOptions, Contents.cornerValues) > 0;

            if (EditorGUI.EndChangeCheck())
            {
                RegisterUndo("Inspector");

                foreach (var index in selection)
                {
                    m_Spline.SetCorner(index, cornerValue);
                }
            }

            EditorGUI.showMixedValue = mixedValue;
        }
        private void DoTangentGUI()
        {
            ISelection selection = SplineEditorCache.GetSelection();

            EditorGUILayout.BeginHorizontal();

            EditorGUILayout.PrefixLabel(Contents.pointModeLabel);

            ShapeTangentMode?tangentMode = null;

            if (selection.single != -1)
            {
                tangentMode = m_Spline.GetTangentMode(selection.single);
            }
            else
            {
                foreach (int index in selection)
                {
                    if (tangentMode == null)
                    {
                        tangentMode = m_Spline.GetTangentMode(index);
                    }
                    else
                    {
                        if (tangentMode != m_Spline.GetTangentMode(index))
                        {
                            tangentMode = null;
                            break;
                        }
                    }
                }
            }

            ShapeTangentMode?prevTangentMode = tangentMode;

            GUIContent tangentStraightIcon   = Contents.tangentStraightIcon;
            GUIContent tangentCurvedIcon     = Contents.tangentCurvedIcon;
            GUIContent tangentAsymmetricIcon = Contents.tangentAsymmetricIcon;

            if (EditorGUIUtility.isProSkin)
            {
                tangentStraightIcon   = Contents.tangentStraightIconPro;
                tangentCurvedIcon     = Contents.tangentCurvedIconPro;
                tangentAsymmetricIcon = Contents.tangentAsymmetricIconPro;
            }

            if (selection.single != -1)
            {
                if (GUILayout.Toggle(tangentMode == ShapeTangentMode.Linear, tangentStraightIcon, new GUIStyle("Button"), GUILayout.Height(23), GUILayout.Width(29)))
                {
                    tangentMode = ShapeTangentMode.Linear;
                }

                if (GUILayout.Toggle(tangentMode == ShapeTangentMode.Continuous, tangentCurvedIcon, new GUIStyle("Button"), GUILayout.Height(23), GUILayout.Width(29)))
                {
                    tangentMode = ShapeTangentMode.Continuous;
                }

                if (GUILayout.Toggle(tangentMode == ShapeTangentMode.Broken, tangentAsymmetricIcon, new GUIStyle("Button"), GUILayout.Height(23), GUILayout.Width(29)))
                {
                    tangentMode = ShapeTangentMode.Broken;
                }

                if (tangentMode.HasValue && prevTangentMode.HasValue && tangentMode.Value != prevTangentMode.Value)
                {
                    RegisterUndo("Edit Tangent Mode");
                    SpriteShapeTool.instance.SetTangentMode(selection.single, tangentMode.Value);
                }
            }
            else
            {
                EditorGUI.BeginChangeCheck();

                if (GUILayout.Toggle(tangentMode == ShapeTangentMode.Linear, tangentStraightIcon, new GUIStyle("Button"), GUILayout.Height(23), GUILayout.Width(29)))
                {
                    tangentMode = ShapeTangentMode.Linear;
                }

                if (GUILayout.Toggle(tangentMode == ShapeTangentMode.Continuous, tangentCurvedIcon, new GUIStyle("Button"), GUILayout.Height(23), GUILayout.Width(29)))
                {
                    tangentMode = ShapeTangentMode.Continuous;
                }

                if (GUILayout.Toggle(tangentMode == ShapeTangentMode.Broken, tangentAsymmetricIcon, new GUIStyle("Button"), GUILayout.Height(23), GUILayout.Width(29)))
                {
                    tangentMode = ShapeTangentMode.Broken;
                }

                if (EditorGUI.EndChangeCheck())
                {
                    if (tangentMode.HasValue && prevTangentMode.HasValue && tangentMode.Value != prevTangentMode.Value)
                    {
                        RegisterUndo("Edit Tangent Mode");

                        foreach (int index in selection)
                        {
                            SpriteShapeTool.instance.SetTangentMode(index, tangentMode.Value);
                        }
                    }
                }
            }

            EditorGUILayout.EndHorizontal();
        }
 private void RegisterUndo()
 {
     Undo.RegisterCompleteObjectUndo(SplineEditorCache.GetTarget(), "Edit Sprite Shape");
 }
 private void InvalidateShapeEditor()
 {
     m_SplineEditor = null;
     m_Spline       = null;
     SplineEditorCache.SetTarget(null);
 }