| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290 | // Animancer // https://kybernetik.com.au/animancer // Copyright 2018-2024 Kybernetik //#if UNITY_EDITORusing Animancer.TransitionLibraries;using System;using UnityEditor;using UnityEngine;namespace Animancer.Editor.TransitionLibraries{    /// <summary>[Editor-Only]    /// A dummy object for tracking the selection within the <see cref="TransitionLibraryWindow"/>    /// and showing its details in the Inspector.    /// </summary>    /// https://kybernetik.com.au/animancer/api/Animancer.Editor.TransitionLibraries/TransitionLibrarySelection    [AnimancerHelpUrl(typeof(TransitionLibrarySelection))]    public class TransitionLibrarySelection : ScriptableObject    {        /************************************************************************************************************************/        /// <summary>[Editor-Only] Types of objects can be selected.</summary>        public enum SelectionType        {            /// <summary>Nothing selected.</summary>            None,            /// <summary>The main library.</summary>            Library,            /// <summary>A from-transition.</summary>            FromTransition,            /// <summary>A to-transition.</summary>            ToTransition,            /// <summary>A fade duration modifier.</summary>            Modifier,        }        /************************************************************************************************************************/        [SerializeField] private TransitionLibraryWindow _Window;        [SerializeField] private SelectionType _Type;        [SerializeField] private int _FromIndex = -1;        [SerializeField] private int _ToIndex = -1;        [SerializeField] private int _Version;        /// <summary>The window this selection is associated with.</summary>        public TransitionLibraryWindow Window            => _Window;        /// <summary>The type of selected object.</summary>        public SelectionType Type            => _Type;        /// <summary>The index of the <see cref="FromTransition"/>.</summary>        public int FromIndex            => _FromIndex;        /// <summary>The index of the <see cref="ToTransition"/>.</summary>        public int ToIndex            => _ToIndex;        /// <summary>The number of times this selection has been changed.</summary>        public int Version            => _Version;        /************************************************************************************************************************/        /// <summary>The transition the current selection is coming from.</summary>        public TransitionAssetBase FromTransition { get; private set; }        /// <summary>The transition the current selection is going to.</summary>        public TransitionAssetBase ToTransition { get; private set; }        /// <summary>The <see cref="ITransition.FadeDuration"/> of the current selection.</summary>        public float FadeDuration { get; private set; }        /// <summary>Does the current selection have a modified <see cref="FadeDuration"/>?</summary>        public bool HasModifier { get; private set; }        /************************************************************************************************************************/        [NonSerialized] private object _Selected;        /// <summary>The currently selected object.</summary>        public object Selected        {            get            {                Validate();                return _Selected;            }        }        /************************************************************************************************************************/        /// <summary>Deselects the current object if it isn't valid.</summary>        public bool Validate()        {            if (IsValid())                return true;            Deselect();            return false;        }        /// <summary>Is the current selection valid?</summary>        public bool IsValid()        {            if (this == null ||                _Window == null ||                Selection.activeObject != this)                return false;            var library = _Window.SourceObject;            if (library == null)                return false;            FromTransition = null;            ToTransition = null;            FadeDuration = float.NaN;            HasModifier = false;            switch (_Type)            {                case SelectionType.Library:                    name = "Transition Library";                    _Selected = library;                    return library != null;                case SelectionType.FromTransition:                    name = "From Transition";                    if (!_Window.Data.Transitions.TryGet(_FromIndex, out var transition))                        return false;                    FromTransition = transition;                    FadeDuration = transition.TryGetFadeDuration();                    _Selected = transition;                    return true;                case SelectionType.ToTransition:                    name = "To Transition";                    if (!_Window.Data.Transitions.TryGet(_ToIndex, out transition))                        return false;                    ToTransition = transition;                    FadeDuration = transition.TryGetFadeDuration();                    _Selected = transition;                    return true;                case SelectionType.Modifier:                    name = "Transition Modifier";                    var hasTransitions = _Window.Data.TryGetTransition(_FromIndex, out transition);                    FromTransition = transition;                    hasTransitions |= _Window.Data.TryGetTransition(_ToIndex, out transition);                    ToTransition = transition;                    if (_Window.Data.TryGetModifier(_FromIndex, _ToIndex, out var modifier))                    {                        HasModifier = true;                    }                    else if (hasTransitions)                    {                        modifier = modifier.WithFadeDuration(transition.TryGetFadeDuration());                    }                    else                    {                        return false;                    }                    FadeDuration = modifier.FadeDuration;                    _Selected = modifier;                    return true;                default:                    return false;            };        }        /************************************************************************************************************************/        /// <summary>Sets the <see cref="Selected"/> object.</summary>        /// <remarks>        /// We can't simply set the <see cref="Selection.activeObject"/>        /// because it might not be a <see cref="UnityEngine.Object"/>        /// and if it is then we don't want the Project window to move to it.        /// <para></para>        /// So instead, we select this dummy object and <see cref="TransitionLibrarySelectionEditor"/>        /// draws a custom Inspector for the target object.        /// </remarks>        public void Select(            TransitionLibraryWindow window,            object select,            int index,            SelectionType type)        {            switch (type)            {                case SelectionType.Library:                    _FromIndex = -1;                    _ToIndex = -1;                    break;                case SelectionType.FromTransition:                    _FromIndex = index;                    _ToIndex = -1;                    break;                case SelectionType.ToTransition:                    _FromIndex = -1;                    _ToIndex = index;                    break;                case SelectionType.Modifier:                    if (select is TransitionModifierDefinition modifier)                    {                        _FromIndex = modifier.FromIndex;                        _ToIndex = modifier.ToIndex;                        break;                    }                    else                    {                        Deselect();                        return;                    }                default:                    Deselect();                    throw new ArgumentException($"Unhandled {nameof(SelectionType)}", nameof(type));            }            _Window = window;            _Type = type;            _Selected = select;            _Version++;            Selection.activeObject = this;            Validate();        }        /************************************************************************************************************************/        /// <summary>Clears the <see cref="Selected"/> object.</summary>        public void Deselect()        {            _Window = null;            _Type = default;            _FromIndex = -1;            _ToIndex = -1;            _Selected = null;            _Version++;            if (Selection.activeObject == this)                Selection.activeObject = null;        }        /************************************************************************************************************************/        /// <summary>Handles selection changes.</summary>        public void OnSelectionChange()        {            if (Selection.activeObject == this)                return;            Deselect();            if (_Window != null)                _Window.Repaint();        }        /************************************************************************************************************************/        /// <summary>Selects this object if it contains a valid selection.</summary>        protected virtual void OnEnable()        {            if (Selected != null)                Selection.activeObject = this;        }        /************************************************************************************************************************/    }}#endif
 |