| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251 | // Animancer // https://kybernetik.com.au/animancer // Copyright 2018-2024 Kybernetik //#if UNITY_EDITOR#pragma warning disable CS0649 // Field is never assigned to, and will always have its default value.using System;using UnityEditor;using UnityEngine;namespace Animancer.Editor.Tools{    /// <summary>[Editor-Only] [Pro-Only]     /// A <see cref="SpriteModifierTool"/> for modifying <see cref="Sprite"/> detauls.    /// </summary>    /// <remarks>    /// <strong>Documentation:</strong>    /// <see href="https://kybernetik.com.au/animancer/docs/manual/tools/modify-sprites">    /// Modify Sprites</see>    /// </remarks>    /// https://kybernetik.com.au/animancer/api/Animancer.Editor.Tools/ModifySpritesTool    ///     [Serializable]    public class ModifySpritesTool : SpriteModifierTool    {        /************************************************************************************************************************/        [SerializeField] private OffsetRectMode _RectMode;        [SerializeField] private Rect _RectOffset;        [SerializeField] private bool _SetPivot;        [SerializeField] private Vector2 _Pivot;        [SerializeField] private bool _SetAlignment;        [SerializeField] private SpriteAlignment _Alignment;        [SerializeField] private bool _SetBorder;        [SerializeField] private RectOffset _Border;        [SerializeField] private bool _ShowDetails;        /************************************************************************************************************************/        private enum OffsetRectMode { None, Add, Subtract }        private static readonly string[] OffsetRectModes = { "None", "Add", "Subtract" };        private SerializedProperty _SerializedProperty;        /************************************************************************************************************************/        /// <inheritdoc/>        public override int DisplayOrder => 1;        /// <inheritdoc/>        public override string Name => "Modify Sprites";        /// <inheritdoc/>        public override string HelpURL => Strings.DocsURLs.ModifySprites;        /// <inheritdoc/>        public override string Instructions        {            get            {                if (Sprites.Count == 0)                    return "Select the Sprites you want to modify.";                if (!IsValidModification())                    return "The current Rect Offset would move some Sprites outside the texture bounds.";                return "Enter the desired modifications and click Apply.";            }        }        /************************************************************************************************************************/        /// <inheritdoc/>        public override void OnEnable(int index)        {            base.OnEnable(index);            _SerializedProperty = AnimancerToolsWindow.Instance.FindSerializedPropertyForTool(this);            _SerializedProperty = _SerializedProperty.FindPropertyRelative(nameof(_RectMode));        }        /************************************************************************************************************************/        /// <inheritdoc/>        public override void DoBodyGUI()        {            base.DoBodyGUI();            var area = AnimancerGUI.LayoutSingleLineRect();            area.xMin += 4;            using (var label = PooledGUIContent.Acquire("Offset Rects", null))                area = EditorGUI.PrefixLabel(area, label);            AnimancerToolsWindow.BeginChangeCheck();            var selected = (OffsetRectMode)GUI.Toolbar(area, (int)_RectMode, OffsetRectModes);            AnimancerToolsWindow.EndChangeCheck(ref _RectMode, selected);            using (var property = _SerializedProperty.Copy())            {                property.serializedObject.Update();                var depth = property.depth;                while (property.Next(false) && property.depth >= depth)                {                    EditorGUILayout.PropertyField(property, true);                }                property.serializedObject.ApplyModifiedProperties();            }            GUI.enabled = false;            for (int i = 0; i < Sprites.Count; i++)            {                if (_ShowDetails)                    GUILayout.BeginVertical(GUI.skin.box);                var sprite = Sprites[i] = AnimancerGUI.DoObjectFieldGUI("", Sprites[i], false);                if (_ShowDetails)                {                    if (_RectMode != OffsetRectMode.None)                        EditorGUILayout.RectField("Rect", sprite.rect);                    if (_SetPivot)                        EditorGUILayout.Vector2Field("Pivot", sprite.pivot);                    if (_SetBorder)                        EditorGUILayout.Vector4Field("Border", sprite.border);                    GUILayout.EndVertical();                }            }            GUILayout.BeginHorizontal();            {                GUILayout.FlexibleSpace();                GUI.enabled = Sprites.Count > 0 && IsValidModification();                if (GUILayout.Button("Apply"))                {                    AnimancerGUI.Deselect();                    AskAndApply();                }            }            GUILayout.EndHorizontal();        }        /************************************************************************************************************************/        private bool IsValidModification()        {            switch (_RectMode)            {                default:                case OffsetRectMode.None:                    return true;                case OffsetRectMode.Add:                case OffsetRectMode.Subtract:                    break;            }            var offset = GetOffset();            var sprites = Sprites;            for (int i = 0; i < sprites.Count; i++)            {                var sprite = sprites[i];                var rect = Add(sprite.rect, offset);                if (rect.xMin < 0 ||                    rect.yMin < 0 ||                    rect.xMax >= sprite.texture.width ||                    rect.xMax >= sprite.texture.height)                {                    return false;                }            }            return true;        }        /************************************************************************************************************************/        private Rect GetOffset()        {            return _RectMode switch            {                OffsetRectMode.Add                    => _RectOffset,                OffsetRectMode.Subtract                    => new(-_RectOffset.x, -_RectOffset.y, -_RectOffset.width, -_RectOffset.height),                _                    => throw new InvalidOperationException($"Can't {nameof(GetOffset)} when the mode is {_RectMode}."),            };        }        private static Rect Add(Rect a, Rect b)        {            a.x += b.x;            a.y += b.y;            a.width += b.width;            a.height += b.height;            return a;        }        /************************************************************************************************************************/        /// <inheritdoc/>        protected override string AreYouSure => "Are you sure you want to modify the borders of these Sprites?";        /************************************************************************************************************************/        /// <inheritdoc/>        protected override void Modify(SpriteDataEditor data, int index, Sprite sprite)        {            switch (_RectMode)            {                default:                case OffsetRectMode.None:                    break;                case OffsetRectMode.Add:                case OffsetRectMode.Subtract:                    var rect = data.GetRect(index);                    rect = Add(rect, GetOffset());                    data.SetRect(index, rect);                    break;            }            if (_SetPivot)                data.SetPivot(index, _Pivot);            if (_SetAlignment)                data.SetAlignment(index, _Alignment);            if (_SetBorder)                data.SetBorder(index, new(_Border.left, _Border.bottom, _Border.right, _Border.top));        }        /************************************************************************************************************************/    }}#endif
 |