From 1620462ab4fbc8e62f219cfc220fc11c28df7151 Mon Sep 17 00:00:00 2001 From: xinansky <1398581458@qq.com> Date: Thu, 26 Oct 2023 11:12:27 +0800 Subject: [PATCH] =?UTF-8?q?=E2=AD=90[update]=20AIO=20DLL?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Script/Utils/Setting/EHelper.Setting.cs | 64 +- Plugins/Editor/AIO.PrCourse.Unity.dll | Bin 830464 -> 832512 bytes Plugins/Editor/AIO.PrCourse.dll | Bin 111104 -> 111104 bytes .../ReorderableDrawer.cs | 11 +- .../ReorderableList.cs | 4650 +++++++++-------- .../Borodar.RainbowCore/CoreEditorUtility.cs | 242 +- .../ProjectRuleDrawer.cs | 56 +- .../ProjectRuleset.cs | 61 +- .../ProjectRulesetEditor.cs | 123 +- 9 files changed, 2692 insertions(+), 2515 deletions(-) diff --git a/Editor/General/Script/Utils/Setting/EHelper.Setting.cs b/Editor/General/Script/Utils/Setting/EHelper.Setting.cs index 21309417..89c0145f 100644 --- a/Editor/General/Script/Utils/Setting/EHelper.Setting.cs +++ b/Editor/General/Script/Utils/Setting/EHelper.Setting.cs @@ -6,8 +6,8 @@ using System; using System.Collections.Generic; -using System.Reflection; using UnityEditor; +using UnityEditor.Build; using UnityEngine; namespace AIO.UEditor @@ -21,25 +21,13 @@ public static class Setting { private static ICollection GetScriptingDefineSymbolsForGroup(BuildTargetGroup buildTargetGroup) { - //获得当前平台已有的的宏定义 - var GetScriptingDefineSymbols = typeof(PlayerSettings).GetMethod("GetScriptingDefineSymbolsInternal", - BindingFlags.Static | BindingFlags.NonPublic); - string str = null; - if (GetScriptingDefineSymbols != null) - { - foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) - { - if (!assembly.GetName().Name.StartsWith("UnityEditor.Build")) continue; - var namedBuildTargetType = assembly.GetType("UnityEditor.Build.NamedBuildTarget"); - var FromBuildTargetGroupMethod = namedBuildTargetType?.GetMethod("FromBuildTargetGroup", - BindingFlags.Static | BindingFlags.Public); - if (FromBuildTargetGroupMethod is null) continue; - var symbols = FromBuildTargetGroupMethod.Invoke(null, new object[] { buildTargetGroup }); - str = GetScriptingDefineSymbols.Invoke(null, new object[] { symbols }) as string; - break; - } - } - else str = PlayerSettings.GetScriptingDefineSymbolsForGroup(buildTargetGroup); + var str = +#if UNITY_2023_1_OR_NEWER + PlayerSettings.GetScriptingDefineSymbols( + NamedBuildTarget.FromBuildTargetGroup(buildTargetGroup)); +#else + PlayerSettings.GetScriptingDefineSymbolsForGroup(buildTargetGroup); +#endif return string.IsNullOrEmpty(str) ? Array.Empty() : str.Split(';'); } @@ -47,35 +35,13 @@ private static ICollection GetScriptingDefineSymbolsForGroup(BuildTarget private static void SetScriptingDefineSymbolsForGroup(BuildTargetGroup buildTargetGroup, IEnumerable verify) { - //获得当前平台已有的的宏定义 - MethodInfo SetScriptingDefineSymbols = null; - foreach (var methodInfo in typeof(PlayerSettings).GetMethods(BindingFlags.Static | BindingFlags.Public)) - { - if (methodInfo.Name != "SetScriptingDefineSymbols") continue; - var parameters = methodInfo.GetParameters(); - if (parameters.Length != 2) continue; - if (parameters[0].ParameterType != typeof(string)) continue; - if (parameters[1].ParameterType != typeof(string)) continue; - SetScriptingDefineSymbols = methodInfo; - } - var str = string.Join(";", verify); - if (SetScriptingDefineSymbols != null) - { - foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) - { - if (!assembly.GetName().Name.StartsWith("UnityEditor.Build")) continue; - var namedBuildTargetType = assembly.GetType("UnityEditor.Build.NamedBuildTarget"); - var FromBuildTargetGroupMethod = namedBuildTargetType?.GetMethod("FromBuildTargetGroup", - BindingFlags.Static | BindingFlags.Public); - if (FromBuildTargetGroupMethod is null) continue; - var Symbols = FromBuildTargetGroupMethod.Invoke(null, new object[] { buildTargetGroup }); - SetScriptingDefineSymbols.Invoke(null, new object[] { Symbols, str }); - - break; - } - } - else PlayerSettings.SetScriptingDefineSymbolsForGroup(buildTargetGroup, str); +#if UNITY_2023_1_OR_NEWER + PlayerSettings.SetScriptingDefineSymbols( + NamedBuildTarget.FromBuildTargetGroup(buildTargetGroup), str); +#else + PlayerSettings.SetScriptingDefineSymbolsForGroup(buildTargetGroup, str); +#endif } /// @@ -84,7 +50,6 @@ private static void SetScriptingDefineSymbolsForGroup(BuildTargetGroup buildTarg public static void AddScriptingDefine(BuildTargetGroup buildTargetGroup, ICollection value) { if (value is null || value.Count == 0) return; - Debug.Log($"Plugins Data Editor : AddScriptingDefine -> {buildTargetGroup}"); var verify = new List(GetScriptingDefineSymbolsForGroup(buildTargetGroup)); foreach (var v in value) { @@ -101,7 +66,6 @@ public static void AddScriptingDefine(BuildTargetGroup buildTargetGroup, ICollec public static void DelScriptingDefine(BuildTargetGroup buildTargetGroup, ICollection value) { if (value is null || value.Count == 0) return; - Debug.Log($"Plugins Data Editor : DelScriptingDefine -> {buildTargetGroup}"); var str = GetScriptingDefineSymbolsForGroup(buildTargetGroup); if (str.Count == 0) return; IList verify = new List(str); diff --git a/Plugins/Editor/AIO.PrCourse.Unity.dll b/Plugins/Editor/AIO.PrCourse.Unity.dll index de8b6ad0deeae488adf2249393ab1f7cf578f7e7..453761d5dd266a9e3a5ae0e2163dda615490ae32 100644 GIT binary patch delta 79976 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 delta 77442 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 P@nuN%e&F<4k6$E7NWZKTi#JIjy zz-gh0l#B3gkJVz00hMxdlC~dcXY5hp?dNZQ4bsL0#P!o7S21b}I4x~{7WjFU;}ZFs zU+WUi^iH1w6lG4#%%6UE6{9V$`bkER1~71(&byjXn$dW==4wXG?SZQq*Ruft=+!c; delta 158 zcmZp8!q)JFZ9)f2XAWQc#GVp9hLem8{tQ6yfRUkwd7`4oWF^LXj3&*DOxqcm7}vK7 zZ1dXO`e|j6dt+qHr@WujS8YGg&e)^G8}6=g38ak)h#RIyu42>{5D(DU&$n={-_&!Z yzq90G?@XTp6lEz+%}JYnXceQakOt5y7;ply6(%Z*F`7)*Sk0)pJ!m!KIyL~k95Z78 diff --git a/Tools~/Process/Process.Unity/Script/RainbowFolders/Borodar.RainbowCore.RList.Editor/ReorderableDrawer.cs b/Tools~/Process/Process.Unity/Script/RainbowFolders/Borodar.RainbowCore.RList.Editor/ReorderableDrawer.cs index b4ae7872..fd73f927 100644 --- a/Tools~/Process/Process.Unity/Script/RainbowFolders/Borodar.RainbowCore.RList.Editor/ReorderableDrawer.cs +++ b/Tools~/Process/Process.Unity/Script/RainbowFolders/Borodar.RainbowCore.RList.Editor/ReorderableDrawer.cs @@ -55,13 +55,10 @@ public override void OnGUI(Rect position, SerializedProperty property, GUIConten public static int GetListId(SerializedProperty property) { - if (property != null) - { - int hashCode = property.serializedObject.targetObject.GetHashCode(); - int hashCode2 = property.propertyPath.GetHashCode(); - return ((hashCode << 5) + hashCode) ^ hashCode2; - } - return 0; + if (property == null) return 0; + var hashCode = property.serializedObject.targetObject.GetHashCode(); + var hashCode2 = property.propertyPath.GetHashCode(); + return ((hashCode << 5) + hashCode) ^ hashCode2; } public static ReorderableList GetList(SerializedProperty property, string arrayPropertyName) diff --git a/Tools~/Process/Process.Unity/Script/RainbowFolders/Borodar.RainbowCore.RList.Editor/ReorderableList.cs b/Tools~/Process/Process.Unity/Script/RainbowFolders/Borodar.RainbowCore.RList.Editor/ReorderableList.cs index e9f3ef42..ac3c9fd8 100644 --- a/Tools~/Process/Process.Unity/Script/RainbowFolders/Borodar.RainbowCore.RList.Editor/ReorderableList.cs +++ b/Tools~/Process/Process.Unity/Script/RainbowFolders/Borodar.RainbowCore.RList.Editor/ReorderableList.cs @@ -5,2356 +5,2494 @@ using System.Reflection; using UnityEditor; using UnityEngine; +using Object = UnityEngine.Object; namespace AIO.RainbowCore.RList.Editor { - internal class ReorderableList - { - public enum ElementDisplayType - { - Auto, - Expandable, - SingleLine - } + internal class ReorderableList + { + public enum ElementDisplayType + { + Auto, + Expandable, + SingleLine + } - public delegate void DrawHeaderDelegate(Rect rect, GUIContent label); + public delegate void DrawHeaderDelegate(Rect rect, GUIContent label); - public delegate void DrawFooterDelegate(Rect rect); + public delegate void DrawFooterDelegate(Rect rect); - public delegate void DrawElementDelegate(Rect rect, SerializedProperty element, GUIContent label, bool selected, bool focused); + public delegate void DrawElementDelegate(Rect rect, SerializedProperty element, GUIContent label, bool selected, + bool focused); - public delegate void ActionDelegate(ReorderableList list); + public delegate void ActionDelegate(ReorderableList list); - public delegate bool ActionBoolDelegate(ReorderableList list); + public delegate bool ActionBoolDelegate(ReorderableList list); - public delegate void AddDropdownDelegate(Rect buttonRect, ReorderableList list); + public delegate void AddDropdownDelegate(Rect buttonRect, ReorderableList list); - public delegate UnityEngine.Object DragDropReferenceDelegate(UnityEngine.Object[] references, ReorderableList list); + public delegate Object DragDropReferenceDelegate(Object[] references, + ReorderableList list); - public delegate void DragDropAppendDelegate(UnityEngine.Object reference, ReorderableList list); + public delegate void DragDropAppendDelegate(Object reference, ReorderableList list); - public delegate float GetElementHeightDelegate(SerializedProperty element); + public delegate float GetElementHeightDelegate(SerializedProperty element); - public delegate float GetElementsHeightDelegate(ReorderableList list); + public delegate float GetElementsHeightDelegate(ReorderableList list); - public delegate string GetElementNameDelegate(SerializedProperty element); + public delegate string GetElementNameDelegate(SerializedProperty element); - public delegate GUIContent GetElementLabelDelegate(SerializedProperty element); + public delegate GUIContent GetElementLabelDelegate(SerializedProperty element); - public delegate void SurrogateCallback(SerializedProperty element, UnityEngine.Object objectReference, ReorderableList list); + public delegate void SurrogateCallback(SerializedProperty element, Object objectReference, + ReorderableList list); - private static class Style - { - internal const string PAGE_INFO_FORMAT = "{0} / {1}"; + private static class Style + { + internal const string PAGE_INFO_FORMAT = "{0} / {1}"; - internal static GUIContent iconToolbarPlus; + internal static GUIContent iconToolbarPlus; - internal static GUIContent iconToolbarPlusMore; + internal static GUIContent iconToolbarPlusMore; - internal static GUIContent iconToolbarMinus; + internal static GUIContent iconToolbarMinus; - internal static GUIContent iconPagePrev; + internal static GUIContent iconPagePrev; - internal static GUIContent iconPageNext; + internal static GUIContent iconPageNext; - internal static GUIContent iconPagePopup; + internal static GUIContent iconPagePopup; - internal static GUIStyle paginationText; + internal static GUIStyle paginationText; - internal static GUIStyle pageSizeTextField; + internal static GUIStyle pageSizeTextField; - internal static GUIStyle draggingHandle; + internal static GUIStyle draggingHandle; - internal static GUIStyle headerBackground; + internal static GUIStyle headerBackground; - internal static GUIStyle footerBackground; + internal static GUIStyle footerBackground; - internal static GUIStyle paginationHeader; + internal static GUIStyle paginationHeader; - internal static GUIStyle boxBackground; + internal static GUIStyle boxBackground; + + internal static GUIStyle preButton; + + internal static GUIStyle elementBackground; + + internal static GUIStyle verticalLabel; + + internal static GUIContent expandButton; + + internal static GUIContent collapseButton; + + internal static GUIContent sortAscending; + + internal static GUIContent sortDescending; + + internal static GUIContent listIcon; + + private static string GetIconName(string name) + { + if (!iconNames.ContainsKey(name)) return "d_console.erroricon"; + int.TryParse(Application.unityVersion.Split('.')[0], out var ver); + return iconNames[name].ContainsKey(ver) ? iconNames[name][ver] : "d_console.erroricon"; + } + + static Style() + { + iconToolbarPlus = EditorGUIUtility.TrIconContent("Toolbar Plus", "| Add to list"); + iconToolbarPlusMore = EditorGUIUtility.TrIconContent("Toolbar Plus More", "| Choose to add to list"); + iconToolbarMinus = EditorGUIUtility.TrIconContent("Toolbar Minus", "| Remove selection from list"); + iconPagePrev = EditorGUIUtility.TrIconContent("Animation.PrevKey", "| Previous page"); + iconPageNext = EditorGUIUtility.TrIconContent("Animation.NextKey", "| Next page"); + iconPagePopup = EditorGUIUtility.TrIconContent("UnityEditor.HierarchyWindow", "| Select page"); + paginationText = new GUIStyle + { + margin = new RectOffset(2, 2, 0, 0), + fontSize = EditorStyles.miniTextField.fontSize, + font = EditorStyles.miniFont, + normal = + { + textColor = EditorStyles.miniTextField.normal.textColor + }, + alignment = TextAnchor.UpperLeft, + clipping = TextClipping.Clip + }; + pageSizeTextField = new GUIStyle("RL Footer") + { + alignment = TextAnchor.MiddleLeft, + clipping = TextClipping.Clip, + fixedHeight = 0f, + padding = new RectOffset(3, 0, 0, 0), + overflow = new RectOffset(0, 0, -2, -3), + contentOffset = new Vector2(0f, -1f), + font = EditorStyles.miniFont, + fontSize = EditorStyles.miniTextField.fontSize, + fontStyle = FontStyle.Normal, + wordWrap = false, + normal = + { + textColor = EditorStyles.miniTextField.normal.textColor + } + }; + draggingHandle = new GUIStyle("RL DragHandle"); + headerBackground = new GUIStyle("RL Header"); + footerBackground = new GUIStyle("RL Footer"); + paginationHeader = new GUIStyle("RL Element") + { + border = new RectOffset(2, 3, 2, 3) + }; + elementBackground = new GUIStyle("RL Element") + { + border = new RectOffset(2, 3, 2, 3) + }; + verticalLabel = new GUIStyle(EditorStyles.label) + { + alignment = TextAnchor.UpperLeft, + contentOffset = new Vector2(10f, 3f) + }; + boxBackground = new GUIStyle("RL Background") + { + border = new RectOffset(6, 3, 3, 6) + }; + preButton = new GUIStyle("RL FooterButton"); + + expandButton = EditorGUIUtility.TrIconContent(GetIconName(nameof(expandButton))); + expandButton.tooltip = "Expand All Elements"; + + collapseButton = EditorGUIUtility.TrIconContent(GetIconName(nameof(collapseButton))); + collapseButton.tooltip = "Collapse All Elements"; + + sortAscending = EditorGUIUtility.TrIconContent("align_vertically_bottom"); + sortAscending.tooltip = "Sort Ascending"; + sortDescending = EditorGUIUtility.TrIconContent("align_vertically_top"); + sortDescending.tooltip = "Sort Descending"; + listIcon = EditorGUIUtility.TrIconContent("align_horizontally_right"); + } + } + + private static readonly Dictionary> iconNames = + new Dictionary> + { + { + "expandButton", new Dictionary + { + { 2023, "d_winbtn_mac_inact" }, + { 2020, "d_winbtn_win_max" }, + { 0, "winbtn_win_max" } + } + }, + { + "collapseButton", new Dictionary + { + { 2023, "d_winbtn_win_min" }, + { 2020, "d_winbtn_win_restore" }, + { 0, "winbtn_win_max" } + } + }, + }; + + private struct DragList + { + private DragElement[] elements; + + internal int StartIndex { get; private set; } + + internal int Length { get; private set; } + + internal DragElement[] Elements + { + get => elements; + set => elements = value; + } + + internal DragElement this[int index] + { + get => elements[index]; + set => elements[index] = value; + } + + internal DragList(int length) + { + Length = length; + StartIndex = 0; + elements = new DragElement[length]; + } + + internal void Resize(int start, int length) + { + StartIndex = start; + Length = length; + if (elements.Length != length) + { + Array.Resize(ref elements, length); + } + } + + internal void SortByIndex() + { + Array.Sort(elements, delegate(DragElement a, DragElement b) + { + if (b.selected) return !a.selected ? 1 : a.startIndex.CompareTo(b.startIndex); + return a.selected ? -1 : a.startIndex.CompareTo(b.startIndex); + }); + } + + internal void RecordState() + { + for (var i = 0; i < Length; i++) + { + elements[i].RecordState(); + } + } + + internal void RestoreState(SerializedProperty list) + { + for (var i = 0; i < Length; i++) + { + elements[i].RestoreState(list.GetArrayElementAtIndex(i + StartIndex)); + } + } + + internal void SortByPosition() + { + Array.Sort(elements, (a, b) => a.desiredRect.center.y.CompareTo(b.desiredRect.center.y)); + } + + internal int GetIndexFromSelection(int index) + { + return Array.FindIndex(elements, t => t.startIndex == index); + } + } + + private struct DragElement + { + internal SerializedProperty property; + + internal int startIndex; + + internal float dragOffset; + + internal bool selected; + + internal Rect rect; + + internal Rect desiredRect; + + private bool isExpanded; + + private Dictionary states; + + internal bool Overlaps(Rect value, int index, int direction) + { + if (direction < 0 && index < startIndex) + { + return desiredRect.yMin < value.center.y; + } + + if (direction > 0 && index > startIndex) + { + return desiredRect.yMax > value.center.y; + } + + return false; + } + + internal void RecordState() + { + states = new Dictionary(); + isExpanded = property.isExpanded; + Iterate(this, property, + delegate(DragElement e, SerializedProperty p, int index) { e.states[index] = p.isExpanded; }); + } + + internal void RestoreState(SerializedProperty value) + { + value.isExpanded = isExpanded; + Iterate(this, value, + delegate(DragElement e, SerializedProperty p, int index) { p.isExpanded = e.states[index]; }); + } + + private static void Iterate(DragElement element, SerializedProperty property, + Action action) + { + var serializedProperty = property.Copy(); + var endProperty = serializedProperty.GetEndProperty(); + var num = 0; + while (serializedProperty.NextVisible(enterChildren: true) && + !SerializedProperty.EqualContents(serializedProperty, endProperty)) + { + if (!serializedProperty.hasVisibleChildren) continue; + action(element, serializedProperty, num); + num++; + } + } + } + + private class SlideGroup + { + private Dictionary animIDs; + + public SlideGroup() + { + animIDs = new Dictionary(); + } + + public Rect GetRect(int id, Rect r, float easing) + { + if (Event.current.type != EventType.Repaint) + { + return r; + } + + if (!animIDs.ContainsKey(id)) + { + animIDs.Add(id, r); + return r; + } + + var rect = animIDs[id]; + if (rect.y == r.y) return r; + + var num = r.y - rect.y; + var num2 = Mathf.Abs(num); + if (num2 > rect.height * 2f) + { + r.y = num > 0f ? r.y - rect.height : r.y + rect.height; + } + else if (num2 > 0.5) + { + r.y = Mathf.Lerp(rect.y, r.y, easing); + } + + animIDs[id] = r; + HandleUtility.Repaint(); + + return r; + } + + public Rect SetRect(int id, Rect rect) + { + if (animIDs.ContainsKey(id)) + { + animIDs[id] = rect; + } + else + { + animIDs.Add(id, rect); + } + + return rect; + } + } + + private struct Pagination + { + internal bool enabled; + + internal int pageSize; + + internal int page; + + internal bool usePagination + { + get + { + if (enabled) + { + return pageSize > 0; + } + + return false; + } + } + + internal int GetVisibleLength(int total) + { + if (GetVisibleRange(total, out var start, out var end)) + { + return end - start; + } + + return total; + } + + internal int GetPageForIndex(int index) + { + return !usePagination ? 0 : Mathf.FloorToInt(index / (float)pageSize); + } + + internal int GetPageCount(int total) + { + return !usePagination ? 1 : Mathf.CeilToInt(total / (float)pageSize); + } + + internal bool GetVisibleRange(int total, out int start, out int end) + { + if (usePagination) + { + var num = pageSize; + start = Mathf.Clamp(page * num, 0, total - 1); + end = Mathf.Min(start + num, total); + return true; + } + + start = 0; + end = total; + return false; + } + } + + private class ListSelection : IEnumerable + { + private List indexes; + + internal int? firstSelected; + + public int First + { + get + { + if (indexes.Count <= 0) + { + return -1; + } + + return indexes[0]; + } + } + + public int Last + { + get + { + if (indexes.Count <= 0) + { + return -1; + } + + return indexes[indexes.Count - 1]; + } + } + + public int Length => indexes.Count; + + public int this[int index] + { + get => indexes[index]; + set + { + var num = indexes[index]; + indexes[index] = value; + if (num == firstSelected) + { + firstSelected = value; + } + } + } + + public ListSelection() + { + indexes = new List(); + } + + public ListSelection(IEnumerable indexes) + { + this.indexes = new List(indexes); + } + + public bool Contains(int index) + { + return indexes.Contains(index); + } + + public void Clear() + { + indexes.Clear(); + firstSelected = null; + } + + public void SelectWhenNoAction(int index, Event evt) + { + if (!EditorGUI.actionKey && !evt.shift) + { + Select(index); + } + } + + public void Select(int index) + { + indexes.Clear(); + indexes.Add(index); + firstSelected = index; + } + + public void Remove(int index) + { + if (indexes.Contains(index)) + { + indexes.Remove(index); + } + } + + public void AppendWithAction(int index, Event evt) + { + if (EditorGUI.actionKey) + { + if (Contains(index)) + { + Remove(index); + return; + } + + Append(index); + firstSelected = index; + } + else if (evt.shift && indexes.Count > 0 && firstSelected.HasValue) + { + indexes.Clear(); + AppendRange(firstSelected.Value, index); + } + else if (!Contains(index)) + { + Select(index); + } + } + + public void Sort() + { + if (indexes.Count > 0) + { + indexes.Sort(); + } + } + + public void Sort(Comparison comparison) + { + if (indexes.Count > 0) + { + indexes.Sort(comparison); + } + } + + public int[] ToArray() + { + return indexes.ToArray(); + } + + public ListSelection Clone() + { + return new ListSelection(ToArray()) + { + firstSelected = firstSelected + }; + } + + internal void Trim(int min, int max) + { + var num = indexes.Count; + while (--num > -1) + { + var num2 = indexes[num]; + if (num2 >= min && num2 < max) continue; + if (num2 == firstSelected && num > 0) + firstSelected = indexes[num - 1]; + indexes.RemoveAt(num); + } + } + + internal bool CanRevert(SerializedProperty list) + { + if (list.serializedObject.targetObjects.Length != 1) return false; + for (var i = 0; i < Length; i++) + { + if (list.GetArrayElementAtIndex(this[i]).isInstantiatedPrefab) + { + return true; + } + } + + return false; + } + + internal void RevertValues(object userData) + { + if (!(userData is SerializedProperty serializedProperty)) return; + for (var i = 0; i < Length; i++) + { + var arrayElementAtIndex = serializedProperty.GetArrayElementAtIndex(this[i]); + if (arrayElementAtIndex.isInstantiatedPrefab) + { + arrayElementAtIndex.prefabOverride = false; + } + } + + serializedProperty.serializedObject.ApplyModifiedProperties(); + serializedProperty.serializedObject.Update(); + HandleUtility.Repaint(); + } + + internal void Duplicate(SerializedProperty list) + { + var num = 0; + for (var i = 0; i < Length; i++) + { + this[i] += num; + list.GetArrayElementAtIndex(this[i]).DuplicateCommand(); + list.serializedObject.ApplyModifiedProperties(); + list.serializedObject.Update(); + num++; + } + + HandleUtility.Repaint(); + } + + internal void Delete(SerializedProperty list) + { + Sort(); + var num = Length; + while (--num > -1) + { + list.GetArrayElementAtIndex(this[num]).DeleteCommand(); + } + + Clear(); + list.serializedObject.ApplyModifiedProperties(); + list.serializedObject.Update(); + HandleUtility.Repaint(); + } + + private void Append(int index) + { + if (index >= 0 && !indexes.Contains(index)) + { + indexes.Add(index); + } + } + + private void AppendRange(int from, int to) + { + int num = (int)Mathf.Sign(to - from); + if (num != 0) + { + for (int i = from; i != to; i += num) + { + Append(i); + } + } + + Append(to); + } + + public IEnumerator GetEnumerator() + { + return ((IEnumerable)indexes).GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return ((IEnumerable)indexes).GetEnumerator(); + } + } + + private static class ListSort + { + private delegate int SortComparision(SerializedProperty p1, SerializedProperty p2); + + internal static void SortOnProperty(SerializedProperty list, int length, bool descending, + string propertyName) + { + BubbleSort(list, length, delegate(SerializedProperty p1, SerializedProperty p2) + { + SerializedProperty serializedProperty = p1.FindPropertyRelative(propertyName); + SerializedProperty serializedProperty2 = p2.FindPropertyRelative(propertyName); + if (serializedProperty != null && serializedProperty2 != null && + serializedProperty.propertyType == serializedProperty2.propertyType) + { + int num = Compare(serializedProperty, serializedProperty2, descending, + serializedProperty.propertyType); + if (!descending) + { + return num; + } + + return -num; + } + + return 0; + }); + } + + internal static void SortOnType(SerializedProperty list, int length, bool descending, + SerializedPropertyType type) + { + BubbleSort(list, length, delegate(SerializedProperty p1, SerializedProperty p2) + { + int num = Compare(p1, p2, descending, type); + return (!descending) ? num : (-num); + }); + } + + private static void BubbleSort(SerializedProperty list, int length, SortComparision comparision) + { + for (int i = 0; i < length; i++) + { + SerializedProperty arrayElementAtIndex = list.GetArrayElementAtIndex(i); + for (int j = i + 1; j < length; j++) + { + SerializedProperty arrayElementAtIndex2 = list.GetArrayElementAtIndex(j); + if (comparision(arrayElementAtIndex, arrayElementAtIndex2) > 0) + { + list.MoveArrayElement(j, i); + } + } + } + } + + private static int Compare(SerializedProperty p1, SerializedProperty p2, bool descending, + SerializedPropertyType type) + { + if (p1 == null || p2 == null) + { + return 0; + } + + switch (type) + { + case SerializedPropertyType.Boolean: + return p1.boolValue.CompareTo(p2.boolValue); + case SerializedPropertyType.Integer: + case SerializedPropertyType.LayerMask: + case SerializedPropertyType.Enum: + case SerializedPropertyType.Character: + return p1.longValue.CompareTo(p2.longValue); + case SerializedPropertyType.Color: + return p1.colorValue.grayscale.CompareTo(p2.colorValue.grayscale); + case SerializedPropertyType.ExposedReference: + return CompareObjects(p1.exposedReferenceValue, p2.exposedReferenceValue, descending); + case SerializedPropertyType.Float: + return p1.doubleValue.CompareTo(p2.doubleValue); + case SerializedPropertyType.ObjectReference: + return CompareObjects(p1.objectReferenceValue, p2.objectReferenceValue, descending); + case SerializedPropertyType.String: + return p1.stringValue.CompareTo(p2.stringValue); + default: + return 0; + } + } + + private static int CompareObjects(Object obj1, Object obj2, bool descending) + { + if ((bool)obj1 && (bool)obj2) + { + return obj1.name.CompareTo(obj2.name); + } + + if ((bool)obj1) + { + if (!descending) + { + return -1; + } + + return 1; + } + + if (!descending) + { + return 1; + } + + return -1; + } + } + + public struct Surrogate + { + public Type type; + + public bool exactType; + + public SurrogateCallback callback; + + internal bool enabled; + + public bool HasType + { + get + { + if (enabled) + { + return type != null; + } + + return false; + } + } + + public Surrogate(Type type) + : this(type, null) + { + } + + public Surrogate(Type type, SurrogateCallback callback) + { + this.type = type; + this.callback = callback; + enabled = true; + exactType = false; + } + + public void Invoke(SerializedProperty element, Object objectReference, ReorderableList list) + { + if (element != null && callback != null) + { + callback(element, objectReference, list); + } + } + } + + private class InvalidListException : InvalidOperationException + { + public InvalidListException() + : base("ReorderableList serializedProperty must be an array") + { + } + } + + private class MissingListException : ArgumentNullException + { + public MissingListException() : base($"ReorderableList serializedProperty is null") + { + } + } - internal static GUIStyle preButton; + private static class Internals + { + private static MethodInfo dragDropValidation; - internal static GUIStyle elementBackground; + private static object[] dragDropValidationParams; - internal static GUIStyle verticalLabel; + private static MethodInfo appendDragDrop; - internal static GUIContent expandButton; + private static object[] appendDragDropParams; - internal static GUIContent collapseButton; + static Internals() + { + dragDropValidation = Type.GetType("UnityEditor.EditorGUI, UnityEditor")? + .GetMethod("ValidateObjectFieldAssignment", BindingFlags.Static | BindingFlags.NonPublic); + appendDragDrop = typeof(SerializedProperty).GetMethod("AppendFoldoutPPtrValue", + BindingFlags.Instance | BindingFlags.NonPublic); + } - internal static GUIContent sortAscending; + internal static Object ValidateObjectDragAndDrop(Object[] references, + SerializedProperty property, Type type, bool exactType) + { + dragDropValidationParams = GetParams(ref dragDropValidationParams, 3); + dragDropValidationParams[0] = references; + dragDropValidationParams[1] = type; + dragDropValidationParams[2] = property; + return dragDropValidation.Invoke(null, dragDropValidationParams) as Object; + } - internal static GUIContent sortDescending; + internal static void AppendDragAndDropValue(Object obj, SerializedProperty list) + { + appendDragDropParams = GetParams(ref appendDragDropParams, 1); + appendDragDropParams[0] = obj; + appendDragDrop.Invoke(list, appendDragDropParams); + } - internal static GUIContent listIcon; + private static object[] GetParams(ref object[] parameters, int count) + { + if (parameters == null) + { + parameters = new object[count]; + } - static Style() - { - iconToolbarPlus = EditorGUIUtility.IconContent("Toolbar Plus", "| Add to list"); - iconToolbarPlusMore = EditorGUIUtility.IconContent("Toolbar Plus More", "| Choose to add to list"); - iconToolbarMinus = EditorGUIUtility.IconContent("Toolbar Minus", "| Remove selection from list"); - iconPagePrev = EditorGUIUtility.IconContent("Animation.PrevKey", "| Previous page"); - iconPageNext = EditorGUIUtility.IconContent("Animation.NextKey", "| Next page"); - iconPagePopup = EditorGUIUtility.IconContent("UnityEditor.HierarchyWindow", "| Select page"); - paginationText = new GUIStyle(); - paginationText.margin = new RectOffset(2, 2, 0, 0); - paginationText.fontSize = EditorStyles.miniTextField.fontSize; - paginationText.font = EditorStyles.miniFont; - paginationText.normal.textColor = EditorStyles.miniTextField.normal.textColor; - paginationText.alignment = TextAnchor.UpperLeft; - paginationText.clipping = TextClipping.Clip; - pageSizeTextField = new GUIStyle("RL Footer"); - pageSizeTextField.alignment = TextAnchor.MiddleLeft; - pageSizeTextField.clipping = TextClipping.Clip; - pageSizeTextField.fixedHeight = 0f; - pageSizeTextField.padding = new RectOffset(3, 0, 0, 0); - pageSizeTextField.overflow = new RectOffset(0, 0, -2, -3); - pageSizeTextField.contentOffset = new Vector2(0f, -1f); - pageSizeTextField.font = EditorStyles.miniFont; - pageSizeTextField.fontSize = EditorStyles.miniTextField.fontSize; - pageSizeTextField.fontStyle = FontStyle.Normal; - pageSizeTextField.wordWrap = false; - pageSizeTextField.normal.textColor = EditorStyles.miniTextField.normal.textColor; - draggingHandle = new GUIStyle("RL DragHandle"); - headerBackground = new GUIStyle("RL Header"); - footerBackground = new GUIStyle("RL Footer"); - paginationHeader = new GUIStyle("RL Element"); - paginationHeader.border = new RectOffset(2, 3, 2, 3); - elementBackground = new GUIStyle("RL Element"); - elementBackground.border = new RectOffset(2, 3, 2, 3); - verticalLabel = new GUIStyle(EditorStyles.label); - verticalLabel.alignment = TextAnchor.UpperLeft; - verticalLabel.contentOffset = new Vector2(10f, 3f); - boxBackground = new GUIStyle("RL Background"); - boxBackground.border = new RectOffset(6, 3, 3, 6); - preButton = new GUIStyle("RL FooterButton"); - expandButton = EditorGUIUtility.IconContent("winbtn_win_max"); - expandButton.tooltip = "Expand All Elements"; - collapseButton = EditorGUIUtility.IconContent("winbtn_win_min"); - collapseButton.tooltip = "Collapse All Elements"; - sortAscending = EditorGUIUtility.IconContent("align_vertically_bottom"); - sortAscending.tooltip = "Sort Ascending"; - sortDescending = EditorGUIUtility.IconContent("align_vertically_top"); - sortDescending.tooltip = "Sort Descending"; - listIcon = EditorGUIUtility.IconContent("align_horizontally_right"); - } - } - - private struct DragList - { - private int startIndex; - - private DragElement[] elements; - - private int length; - - internal int StartIndex => startIndex; - - internal int Length => length; - - internal DragElement[] Elements - { - get - { - return elements; - } - set - { - elements = value; - } - } - - internal DragElement this[int index] - { - get - { - return elements[index]; - } - set - { - elements[index] = value; - } - } - - internal DragList(int length) - { - this.length = length; - startIndex = 0; - elements = new DragElement[length]; - } - - internal void Resize(int start, int length) - { - startIndex = start; - this.length = length; - if (elements.Length != length) - { - Array.Resize(ref elements, length); - } - } - - internal void SortByIndex() - { - Array.Sort(elements, delegate(DragElement a, DragElement b) - { - if (b.selected) - { - if (!a.selected) - { - return 1; - } - return a.startIndex.CompareTo(b.startIndex); - } - return a.selected ? ((!b.selected) ? (-1) : b.startIndex.CompareTo(a.startIndex)) : a.startIndex.CompareTo(b.startIndex); - }); - } - - internal void RecordState() - { - for (int i = 0; i < length; i++) - { - elements[i].RecordState(); - } - } - - internal void RestoreState(SerializedProperty list) - { - for (int i = 0; i < length; i++) - { - elements[i].RestoreState(list.GetArrayElementAtIndex(i + startIndex)); - } - } - - internal void SortByPosition() - { - Array.Sort(elements, (DragElement a, DragElement b) => a.desiredRect.center.y.CompareTo(b.desiredRect.center.y)); - } - - internal int GetIndexFromSelection(int index) - { - return Array.FindIndex(elements, (DragElement t) => t.startIndex == index); - } - } - - private struct DragElement - { - internal SerializedProperty property; - - internal int startIndex; - - internal float dragOffset; - - internal bool selected; - - internal Rect rect; - - internal Rect desiredRect; - - private bool isExpanded; - - private Dictionary states; - - internal bool Overlaps(Rect value, int index, int direction) - { - if (direction < 0 && index < startIndex) - { - return desiredRect.yMin < value.center.y; - } - if (direction > 0 && index > startIndex) - { - return desiredRect.yMax > value.center.y; - } - return false; - } - - internal void RecordState() - { - states = new Dictionary(); - isExpanded = property.isExpanded; - Iterate(this, property, delegate(DragElement e, SerializedProperty p, int index) - { - e.states[index] = p.isExpanded; - }); - } - - internal void RestoreState(SerializedProperty property) - { - property.isExpanded = isExpanded; - Iterate(this, property, delegate(DragElement e, SerializedProperty p, int index) - { - p.isExpanded = e.states[index]; - }); - } - - private static void Iterate(DragElement element, SerializedProperty property, Action action) - { - SerializedProperty serializedProperty = property.Copy(); - SerializedProperty endProperty = serializedProperty.GetEndProperty(); - int num = 0; - while (serializedProperty.NextVisible(enterChildren: true) && !SerializedProperty.EqualContents(serializedProperty, endProperty)) - { - if (serializedProperty.hasVisibleChildren) - { - action(element, serializedProperty, num); - num++; - } - } - } - } - - private class SlideGroup - { - private Dictionary animIDs; - - public SlideGroup() - { - animIDs = new Dictionary(); - } - - public Rect GetRect(int id, Rect r, float easing) - { - if (Event.current.type != EventType.Repaint) - { - return r; - } - if (!animIDs.ContainsKey(id)) - { - animIDs.Add(id, r); - return r; - } - Rect rect = animIDs[id]; - if (rect.y != r.y) - { - float num = r.y - rect.y; - float num2 = Mathf.Abs(num); - if (num2 > rect.height * 2f) - { - r.y = ((num > 0f) ? (r.y - rect.height) : (r.y + rect.height)); - } - else if ((double)num2 > 0.5) - { - r.y = Mathf.Lerp(rect.y, r.y, easing); - } - animIDs[id] = r; - HandleUtility.Repaint(); - } - return r; - } - - public Rect SetRect(int id, Rect rect) - { - if (animIDs.ContainsKey(id)) - { - animIDs[id] = rect; - } - else - { - animIDs.Add(id, rect); - } - return rect; - } - } - - private struct Pagination - { - internal bool enabled; - - internal int pageSize; - - internal int page; - - internal bool usePagination - { - get - { - if (enabled) - { - return pageSize > 0; - } - return false; - } - } - - internal int GetVisibleLength(int total) - { - if (GetVisibleRange(total, out var start, out var end)) - { - return end - start; - } - return total; - } - - internal int GetPageForIndex(int index) - { - if (!usePagination) - { - return 0; - } - return Mathf.FloorToInt((float)index / (float)pageSize); - } - - internal int GetPageCount(int total) - { - if (!usePagination) - { - return 1; - } - return Mathf.CeilToInt((float)total / (float)pageSize); - } - - internal bool GetVisibleRange(int total, out int start, out int end) - { - if (usePagination) - { - int num = pageSize; - start = Mathf.Clamp(page * num, 0, total - 1); - end = Mathf.Min(start + num, total); - return true; - } - start = 0; - end = total; - return false; - } - } - - private class ListSelection : IEnumerable, IEnumerable - { - private List indexes; - - internal int? firstSelected; - - public int First - { - get - { - if (indexes.Count <= 0) - { - return -1; - } - return indexes[0]; - } - } - - public int Last - { - get - { - if (indexes.Count <= 0) - { - return -1; - } - return indexes[indexes.Count - 1]; - } - } - - public int Length => indexes.Count; - - public int this[int index] - { - get - { - return indexes[index]; - } - set - { - int num = indexes[index]; - indexes[index] = value; - if (num == firstSelected) - { - firstSelected = value; - } - } - } - - public ListSelection() - { - indexes = new List(); - } - - public ListSelection(int[] indexes) - { - this.indexes = new List(indexes); - } - - public bool Contains(int index) - { - return indexes.Contains(index); - } - - public void Clear() - { - indexes.Clear(); - firstSelected = null; - } - - public void SelectWhenNoAction(int index, Event evt) - { - if (!EditorGUI.actionKey && !evt.shift) - { - Select(index); - } - } - - public void Select(int index) - { - indexes.Clear(); - indexes.Add(index); - firstSelected = index; - } - - public void Remove(int index) - { - if (indexes.Contains(index)) - { - indexes.Remove(index); - } - } - - public void AppendWithAction(int index, Event evt) - { - if (EditorGUI.actionKey) - { - if (Contains(index)) - { - Remove(index); - return; - } - Append(index); - firstSelected = index; - } - else if (evt.shift && indexes.Count > 0 && firstSelected.HasValue) - { - indexes.Clear(); - AppendRange(firstSelected.Value, index); - } - else if (!Contains(index)) - { - Select(index); - } - } - - public void Sort() - { - if (indexes.Count > 0) - { - indexes.Sort(); - } - } - - public void Sort(Comparison comparison) - { - if (indexes.Count > 0) - { - indexes.Sort(comparison); - } - } - - public int[] ToArray() - { - return indexes.ToArray(); - } - - public ListSelection Clone() - { - return new ListSelection(ToArray()) - { - firstSelected = firstSelected - }; - } - - internal void Trim(int min, int max) - { - int num = indexes.Count; - while (--num > -1) - { - int num2 = indexes[num]; - if (num2 < min || num2 >= max) - { - if (num2 == firstSelected && num > 0) - { - firstSelected = indexes[num - 1]; - } - indexes.RemoveAt(num); - } - } - } - - internal bool CanRevert(SerializedProperty list) - { - if (list.serializedObject.targetObjects.Length == 1) - { - for (int i = 0; i < Length; i++) - { - if (list.GetArrayElementAtIndex(this[i]).isInstantiatedPrefab) - { - return true; - } - } - } - return false; - } - - internal void RevertValues(object userData) - { - SerializedProperty serializedProperty = userData as SerializedProperty; - for (int i = 0; i < Length; i++) - { - SerializedProperty arrayElementAtIndex = serializedProperty.GetArrayElementAtIndex(this[i]); - if (arrayElementAtIndex.isInstantiatedPrefab) - { - arrayElementAtIndex.prefabOverride = false; - } - } - serializedProperty.serializedObject.ApplyModifiedProperties(); - serializedProperty.serializedObject.Update(); - HandleUtility.Repaint(); - } - - internal void Duplicate(SerializedProperty list) - { - int num = 0; - for (int i = 0; i < Length; i++) - { - this[i] += num; - list.GetArrayElementAtIndex(this[i]).DuplicateCommand(); - list.serializedObject.ApplyModifiedProperties(); - list.serializedObject.Update(); - num++; - } - HandleUtility.Repaint(); - } - - internal void Delete(SerializedProperty list) - { - Sort(); - int num = Length; - while (--num > -1) - { - list.GetArrayElementAtIndex(this[num]).DeleteCommand(); - } - Clear(); - list.serializedObject.ApplyModifiedProperties(); - list.serializedObject.Update(); - HandleUtility.Repaint(); - } - - private void Append(int index) - { - if (index >= 0 && !indexes.Contains(index)) - { - indexes.Add(index); - } - } - - private void AppendRange(int from, int to) - { - int num = (int)Mathf.Sign(to - from); - if (num != 0) - { - for (int i = from; i != to; i += num) - { - Append(i); - } - } - Append(to); - } - - public IEnumerator GetEnumerator() - { - return ((IEnumerable)indexes).GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return ((IEnumerable)indexes).GetEnumerator(); - } - } - - private static class ListSort - { - private delegate int SortComparision(SerializedProperty p1, SerializedProperty p2); - - internal static void SortOnProperty(SerializedProperty list, int length, bool descending, string propertyName) - { - BubbleSort(list, length, delegate(SerializedProperty p1, SerializedProperty p2) - { - SerializedProperty serializedProperty = p1.FindPropertyRelative(propertyName); - SerializedProperty serializedProperty2 = p2.FindPropertyRelative(propertyName); - if (serializedProperty != null && serializedProperty2 != null && serializedProperty.propertyType == serializedProperty2.propertyType) - { - int num = Compare(serializedProperty, serializedProperty2, descending, serializedProperty.propertyType); - if (!descending) - { - return num; - } - return -num; - } - return 0; - }); - } - - internal static void SortOnType(SerializedProperty list, int length, bool descending, SerializedPropertyType type) - { - BubbleSort(list, length, delegate(SerializedProperty p1, SerializedProperty p2) - { - int num = Compare(p1, p2, descending, type); - return (!descending) ? num : (-num); - }); - } - - private static void BubbleSort(SerializedProperty list, int length, SortComparision comparision) - { - for (int i = 0; i < length; i++) - { - SerializedProperty arrayElementAtIndex = list.GetArrayElementAtIndex(i); - for (int j = i + 1; j < length; j++) - { - SerializedProperty arrayElementAtIndex2 = list.GetArrayElementAtIndex(j); - if (comparision(arrayElementAtIndex, arrayElementAtIndex2) > 0) - { - list.MoveArrayElement(j, i); - } - } - } - } - - private static int Compare(SerializedProperty p1, SerializedProperty p2, bool descending, SerializedPropertyType type) - { - if (p1 == null || p2 == null) - { - return 0; - } - switch (type) - { - case SerializedPropertyType.Boolean: - return p1.boolValue.CompareTo(p2.boolValue); - case SerializedPropertyType.Integer: - case SerializedPropertyType.LayerMask: - case SerializedPropertyType.Enum: - case SerializedPropertyType.Character: - return p1.longValue.CompareTo(p2.longValue); - case SerializedPropertyType.Color: - return p1.colorValue.grayscale.CompareTo(p2.colorValue.grayscale); - case SerializedPropertyType.ExposedReference: - return CompareObjects(p1.exposedReferenceValue, p2.exposedReferenceValue, descending); - case SerializedPropertyType.Float: - return p1.doubleValue.CompareTo(p2.doubleValue); - case SerializedPropertyType.ObjectReference: - return CompareObjects(p1.objectReferenceValue, p2.objectReferenceValue, descending); - case SerializedPropertyType.String: - return p1.stringValue.CompareTo(p2.stringValue); - default: - return 0; - } - } - - private static int CompareObjects(UnityEngine.Object obj1, UnityEngine.Object obj2, bool descending) - { - if ((bool)obj1 && (bool)obj2) - { - return obj1.name.CompareTo(obj2.name); - } - if ((bool)obj1) - { - if (!descending) - { - return -1; - } - return 1; - } - if (!descending) - { - return 1; - } - return -1; - } - } - - public struct Surrogate - { - public Type type; - - public bool exactType; - - public SurrogateCallback callback; - - internal bool enabled; - - public bool HasType - { - get - { - if (enabled) - { - return type != null; - } - return false; - } - } - - public Surrogate(Type type) - : this(type, null) - { - } - - public Surrogate(Type type, SurrogateCallback callback) - { - this.type = type; - this.callback = callback; - enabled = true; - exactType = false; - } - - public void Invoke(SerializedProperty element, UnityEngine.Object objectReference, ReorderableList list) - { - if (element != null && callback != null) - { - callback(element, objectReference, list); - } - } - } - - private class InvalidListException : InvalidOperationException - { - public InvalidListException() - : base("ReorderableList serializedProperty must be an array") - { - } - } - - private class MissingListExeption : ArgumentNullException - { - public MissingListExeption() - : base("ReorderableList serializedProperty is null") - { - } - } - - private static class Internals - { - private static MethodInfo dragDropValidation; + return parameters; + } + } - private static object[] dragDropValidationParams; + private const float ELEMENT_EDGE_TOP = 1f; - private static MethodInfo appendDragDrop; + private const float ELEMENT_EDGE_BOT = 3f; - private static object[] appendDragDropParams; + private const float ELEMENT_HEIGHT_OFFSET = 4f; - static Internals() - { - dragDropValidation = Type.GetType("UnityEditor.EditorGUI, UnityEditor").GetMethod("ValidateObjectFieldAssignment", BindingFlags.Static | BindingFlags.NonPublic); - appendDragDrop = typeof(SerializedProperty).GetMethod("AppendFoldoutPPtrValue", BindingFlags.Instance | BindingFlags.NonPublic); - } + private static int selectionHash = "ReorderableListSelection".GetHashCode(); - internal static UnityEngine.Object ValidateObjectDragAndDrop(UnityEngine.Object[] references, SerializedProperty property, Type type, bool exactType) - { - dragDropValidationParams = GetParams(ref dragDropValidationParams, 3); - dragDropValidationParams[0] = references; - dragDropValidationParams[1] = type; - dragDropValidationParams[2] = property; - return dragDropValidation.Invoke(null, dragDropValidationParams) as UnityEngine.Object; - } + private static int dragAndDropHash = "ReorderableListDragAndDrop".GetHashCode(); - internal static void AppendDragAndDropValue(UnityEngine.Object obj, SerializedProperty list) - { - appendDragDropParams = GetParams(ref appendDragDropParams, 1); - appendDragDropParams[0] = obj; - appendDragDrop.Invoke(list, appendDragDropParams); - } + private const string EMPTY_LABEL = "List is Empty"; - private static object[] GetParams(ref object[] parameters, int count) - { - if (parameters == null) - { - parameters = new object[count]; - } - return parameters; - } - } + private const string ARRAY_ERROR = "{0} is not an Array!"; - private const float ELEMENT_EDGE_TOP = 1f; + public bool canAdd; - private const float ELEMENT_EDGE_BOT = 3f; + public bool canRemove; - private const float ELEMENT_HEIGHT_OFFSET = 4f; + public bool draggable; - private static int selectionHash = "ReorderableListSelection".GetHashCode(); + public bool sortable; - private static int dragAndDropHash = "ReorderableListDragAndDrop".GetHashCode(); + public bool expandable; - private const string EMPTY_LABEL = "List is Empty"; + public bool multipleSelection; - private const string ARRAY_ERROR = "{0} is not an Array!"; + public GUIContent label; - public bool canAdd; + public float headerHeight; - public bool canRemove; + public float paginationHeight; - public bool draggable; + public float footerHeight; - public bool sortable; + public float slideEasing; - public bool expandable; + public float verticalSpacing; - public bool multipleSelection; + public bool showDefaultBackground; - public GUIContent label; + public ElementDisplayType elementDisplayType; - public float headerHeight; + public string elementNameProperty; - public float paginationHeight; + public string elementNameOverride; - public float footerHeight; + public bool elementLabels; - public float slideEasing; + public Texture elementIcon; - public float verticalSpacing; + public Surrogate surrogate; - public bool showDefaultBackground; + internal readonly int id; - public ElementDisplayType elementDisplayType; + private SerializedProperty list; - public string elementNameProperty; + private int controlID = -1; - public string elementNameOverride; + private Rect[] elementRects; - public bool elementLabels; + private GUIContent elementLabel; - public Texture elementIcon; + private GUIContent pageInfoContent; - public Surrogate surrogate; + private GUIContent pageSizeContent; - internal readonly int id; + private ListSelection selection; - private SerializedProperty list; + private SlideGroup slideGroup; - private int controlID = -1; + private int pressIndex; - private Rect[] elementRects; + private bool dragging; - private GUIContent elementLabel; + private float pressPosition; - private GUIContent pageInfoContent; + private float dragPosition; - private GUIContent pageSizeContent; + private int dragDirection; - private ListSelection selection; + private DragList dragList; - private SlideGroup slideGroup; + private ListSelection beforeDragSelection; - private int pressIndex; + private Pagination pagination; - private bool dragging; + private int dragDropControlID = -1; - private float pressPosition; + public bool paginate + { + get { return pagination.enabled; } + set { pagination.enabled = value; } + } - private float dragPosition; + public int pageSize + { + get { return pagination.pageSize; } + set { pagination.pageSize = value; } + } - private int dragDirection; + private bool doPagination + { + get + { + if (pagination.enabled) + { + return !list.serializedObject.isEditingMultipleObjects; + } - private DragList dragList; + return false; + } + } - private ListSelection beforeDragSelection; + private float elementSpacing => Mathf.Max(0f, verticalSpacing - 2f); - private Pagination pagination; + public SerializedProperty List + { + get { return list; } + internal set { list = value; } + } - private int dragDropControlID = -1; + public bool HasList + { + get + { + if (list != null) + { + return list.isArray; + } - public bool paginate - { - get - { - return pagination.enabled; - } - set - { - pagination.enabled = value; - } - } + return false; + } + } - public int pageSize - { - get - { - return pagination.pageSize; - } - set - { - pagination.pageSize = value; - } - } + public int Length + { + get + { + if (!HasList) + { + return 0; + } - private bool doPagination - { - get - { - if (pagination.enabled) - { - return !list.serializedObject.isEditingMultipleObjects; - } - return false; - } - } + if (!list.hasMultipleDifferentValues) + { + return list.arraySize; + } - private float elementSpacing => Mathf.Max(0f, verticalSpacing - 2f); + int num = list.arraySize; + Object[] targetObjects = list.serializedObject.targetObjects; + for (int i = 0; i < targetObjects.Length; i++) + { + num = Mathf.Min(new SerializedObject(targetObjects[i]).FindProperty(list.propertyPath).arraySize, + num); + } - public SerializedProperty List - { - get - { - return list; - } - internal set - { - list = value; - } - } + return num; + } + } - public bool HasList - { - get - { - if (list != null) - { - return list.isArray; - } - return false; - } - } + public int VisibleLength => pagination.GetVisibleLength(Length); - public int Length - { - get - { - if (!HasList) - { - return 0; - } - if (!list.hasMultipleDifferentValues) - { - return list.arraySize; - } - int num = list.arraySize; - UnityEngine.Object[] targetObjects = list.serializedObject.targetObjects; - for (int i = 0; i < targetObjects.Length; i++) - { - num = Mathf.Min(new SerializedObject(targetObjects[i]).FindProperty(list.propertyPath).arraySize, num); - } - return num; - } - } - - public int VisibleLength => pagination.GetVisibleLength(Length); - - public int[] Selected - { - get - { - return selection.ToArray(); - } - set - { - selection = new ListSelection(value); - } - } - - public int Index - { - get - { - return selection.First; - } - set - { - selection.Select(value); - } - } - - public bool IsDragging => dragging; - - public event DrawHeaderDelegate drawHeaderCallback; - - public event DrawFooterDelegate drawFooterCallback; - - public event DrawElementDelegate drawElementCallback; - - public event DrawElementDelegate drawElementBackgroundCallback; - - public event GetElementHeightDelegate getElementHeightCallback; - - public event GetElementsHeightDelegate getElementsHeightCallback; - - public event GetElementNameDelegate getElementNameCallback; - - public event GetElementLabelDelegate getElementLabelCallback; - - public event DragDropReferenceDelegate onValidateDragAndDropCallback; - - public event DragDropAppendDelegate onAppendDragDropCallback; - - public event ActionDelegate onReorderCallback; - - public event ActionDelegate onSelectCallback; - - public event ActionDelegate onAddCallback; - - public event AddDropdownDelegate onAddDropdownCallback; - - public event ActionDelegate onRemoveCallback; - - public event ActionDelegate onMouseUpCallback; - - public event ActionBoolDelegate onCanRemoveCallback; - - public event ActionDelegate onChangedCallback; - - public ReorderableList(SerializedProperty list) - : this(list, canAdd: true, canRemove: true, draggable: true) - { - } - - public ReorderableList(SerializedProperty list, bool canAdd, bool canRemove, bool draggable) - : this(list, canAdd, canRemove, draggable, ElementDisplayType.Auto, null, null, null) - { - } - - public ReorderableList(SerializedProperty list, bool canAdd, bool canRemove, bool draggable, ElementDisplayType elementDisplayType, string elementNameProperty, Texture elementIcon) - : this(list, canAdd, canRemove, draggable, elementDisplayType, elementNameProperty, null, elementIcon) - { - } - - public ReorderableList(SerializedProperty list, bool canAdd, bool canRemove, bool draggable, ElementDisplayType elementDisplayType, string elementNameProperty, string elementNameOverride, Texture elementIcon) - { - if (list == null) - { - throw new MissingListExeption(); - } - if (!list.isArray) - { - SerializedProperty serializedProperty = list.FindPropertyRelative("array"); - if (serializedProperty == null || !serializedProperty.isArray) - { - throw new InvalidListException(); - } - this.list = serializedProperty; - } - else - { - this.list = list; - } - this.canAdd = canAdd; - this.canRemove = canRemove; - this.draggable = draggable; - this.elementDisplayType = elementDisplayType; - this.elementNameProperty = elementNameProperty; - this.elementNameOverride = elementNameOverride; - this.elementIcon = elementIcon; - id = GetHashCode(); - list.isExpanded = true; - label = new GUIContent(list.displayName); - pageInfoContent = new GUIContent(); - pageSizeContent = new GUIContent(); - verticalSpacing = EditorGUIUtility.standardVerticalSpacing; - headerHeight = 18f; - paginationHeight = 18f; - footerHeight = 13f; - slideEasing = 0.15f; - expandable = true; - elementLabels = true; - showDefaultBackground = true; - multipleSelection = true; - pagination = default(Pagination); - elementLabel = new GUIContent(); - dragList = new DragList(0); - selection = new ListSelection(); - slideGroup = new SlideGroup(); - elementRects = new Rect[0]; - } - - public float GetHeight() - { - if (HasList) - { - float num = (doPagination ? (headerHeight + paginationHeight) : headerHeight); - if (!list.isExpanded) - { - return headerHeight; - } - return num + GetElementsHeight() + footerHeight; - } - return EditorGUIUtility.singleLineHeight; - } - - public void DoLayoutList() - { - var controlRect = EditorGUILayout.GetControlRect(false, GetHeight(), EditorStyles.largeLabel); - DoList(EditorGUI.IndentedRect(controlRect), label); - } - - public void DoList(Rect rect, GUIContent label) - { - int indentLevel = EditorGUI.indentLevel; - EditorGUI.indentLevel = 0; - Rect rect2 = rect; - rect2.height = headerHeight; - if (!HasList) - { - DrawEmpty(rect2, $"{label.text} is not an Array!", GUIStyle.none, EditorStyles.helpBox); - } - else - { - controlID = GUIUtility.GetControlID(selectionHash, FocusType.Keyboard, rect); - dragDropControlID = GUIUtility.GetControlID(dragAndDropHash, FocusType.Passive, rect); - DrawHeader(rect2, label); - if (list.isExpanded) - { - if (doPagination) - { - Rect rect3 = rect2; - rect3.y += rect2.height; - rect3.height = paginationHeight; - DrawPaginationHeader(rect3); - rect2.yMax = rect3.yMax - 1f; - } - Rect rect4 = rect; - rect4.yMin = rect2.yMax; - rect4.yMax = rect.yMax - footerHeight; - Event current = Event.current; - if (selection.Length > 1 && current.type == EventType.ContextClick && CanSelect(current.mousePosition)) - { - HandleMultipleContextClick(current); - } - if (Length > 0) - { - if (!dragging) - { - UpdateElementRects(rect4, current); - } - if (elementRects.Length != 0) - { - pagination.GetVisibleRange(elementRects.Length, out var start, out var end); - Rect rect5 = rect4; - rect5.yMin = elementRects[start].yMin; - rect5.yMax = elementRects[end - 1].yMax; - HandlePreSelection(rect5, current); - DrawElements(rect4, current); - HandlePostSelection(rect5, current); - } - } - else - { - DrawEmpty(rect4, "List is Empty", Style.boxBackground, Style.verticalLabel); - } - Rect rect6 = rect; - rect6.yMin = rect4.yMax; - rect6.xMin = rect.xMax - 58f; - DrawFooter(rect6); - } - } - EditorGUI.indentLevel = indentLevel; - } - - public SerializedProperty AddItem(T item) where T : UnityEngine.Object - { - SerializedProperty serializedProperty = AddItem(); - if (serializedProperty != null) - { - serializedProperty.objectReferenceValue = item; - } - return serializedProperty; - } - - public SerializedProperty AddItem() - { - if (HasList) - { - list.arraySize++; - selection.Select(list.arraySize - 1); - SetPageByIndex(list.arraySize - 1); - DispatchChange(); - return list.GetArrayElementAtIndex(selection.Last); - } - throw new InvalidListException(); - } - - public void Remove(int[] selection) - { - Array.Sort(selection); - int num = selection.Length; - while (--num > -1) - { - RemoveItem(selection[num]); - } - } - - public void RemoveItem(int index) - { - if (index >= 0 && index < Length) - { - SerializedProperty arrayElementAtIndex = list.GetArrayElementAtIndex(index); - if (arrayElementAtIndex.propertyType == SerializedPropertyType.ObjectReference && (bool)arrayElementAtIndex.objectReferenceValue) - { - arrayElementAtIndex.objectReferenceValue = null; - } - list.DeleteArrayElementAtIndex(index); - selection.Remove(index); - if (Length > 0) - { - selection.Select(Mathf.Max(0, index - 1)); - } - DispatchChange(); - } - } - - public SerializedProperty GetItem(int index) - { - if (index >= 0 && index < Length) - { - return list.GetArrayElementAtIndex(index); - } - return null; - } - - public int IndexOf(SerializedProperty element) - { - if (element != null) - { - int num = Length; - while (--num > -1) - { - if (SerializedProperty.EqualContents(element, list.GetArrayElementAtIndex(num))) - { - return num; - } - } - } - return -1; - } - - public void GrabKeyboardFocus() - { - GUIUtility.keyboardControl = id; - } - - public bool HasKeyboardControl() - { - return GUIUtility.keyboardControl == id; - } - - public void ReleaseKeyboardFocus() - { - if (GUIUtility.keyboardControl == id) - { - GUIUtility.keyboardControl = 0; - } - } - - public void SetPage(int page) - { - if (doPagination) - { - pagination.page = page; - } - } - - public void SetPageByIndex(int index) - { - if (doPagination) - { - pagination.page = pagination.GetPageForIndex(index); - } - } - - public int GetPage(int index) - { - if (!doPagination) - { - return 0; - } - return pagination.page; - } - - public int GetPageByIndex(int index) - { - if (!doPagination) - { - return 0; - } - return pagination.GetPageForIndex(index); - } - - private float GetElementsHeight() - { - if (this.getElementsHeightCallback != null) - { - return this.getElementsHeightCallback(this); - } - int length = Length; - if (length == 0) - { - return 28f; - } - float num = 0f; - float num2 = elementSpacing; - pagination.GetVisibleRange(length, out var start, out var end); - for (int i = start; i < end; i++) - { - num += GetElementHeight(list.GetArrayElementAtIndex(i)) + num2; - } - return num + 7f - num2; - } - - private float GetElementHeight(SerializedProperty element) - { - if (this.getElementHeightCallback != null) - { - return this.getElementHeightCallback(element) + 4f; - } - float propertyHeight = EditorGUI.GetPropertyHeight(element, GetElementLabel(element, elementLabels), IsElementExpandable(element)); - return (propertyHeight > 0f) ? (propertyHeight + 4f) : propertyHeight; - } - - private Rect GetElementDrawRect(int index, Rect desiredRect) - { - if (slideEasing <= 0f) - { - return desiredRect; - } - if (!dragging) - { - return slideGroup.SetRect(index, desiredRect); - } - return slideGroup.GetRect(dragList[index].startIndex, desiredRect, slideEasing); - } - - private Rect GetElementRenderRect(SerializedProperty element, Rect elementRect) - { - float num = (draggable ? 20 : 5); - Rect result = elementRect; - result.xMin += (IsElementExpandable(element) ? (num + 10f) : num); - result.xMax -= 6f; - result.yMin += 1f; - result.yMax -= 3f; - return result; - } - - private void DrawHeader(Rect rect, GUIContent label) - { - if (showDefaultBackground && Event.current.type == EventType.Repaint) - { - Style.headerBackground.Draw(rect, isHover: false, isActive: false, on: false, hasKeyboardFocus: false); - } - HandleDragAndDrop(rect, Event.current); - bool flag = elementDisplayType != ElementDisplayType.SingleLine; - Rect rect2 = rect; - rect2.xMin += 6f; - rect2.xMax -= (flag ? 95f : 55f); - rect2.height -= 2f; - rect2.y++; - label = EditorGUI.BeginProperty(rect2, label, list); - if (this.drawHeaderCallback != null) - { - this.drawHeaderCallback(rect2, label); - } - else if (expandable) - { - rect2.xMin += 10f; - EditorGUI.BeginChangeCheck(); - bool isExpanded = EditorGUI.Foldout(rect2, list.isExpanded, label, toggleOnLabelClick: true); - if (EditorGUI.EndChangeCheck()) - { - list.isExpanded = isExpanded; - } - } - else - { - GUI.Label(rect2, label, EditorStyles.label); - } - EditorGUI.EndProperty(); - if (flag) - { - Rect position = rect; - position.xMin = rect.xMax - 25f; - position.xMax = rect.xMax - 5f; - if (GUI.Button(position, Style.expandButton, Style.preButton)) - { - ExpandElements(expand: true); - } - Rect position2 = rect; - position2.xMin = position.xMin - 20f; - position2.xMax = position.xMin; - if (GUI.Button(position2, Style.collapseButton, Style.preButton)) - { - ExpandElements(expand: false); - } - rect.xMax = position2.xMin + 5f; - } - if (sortable) - { - Rect rect3 = rect; - rect3.xMin = rect.xMax - 25f; - rect3.xMax = rect.xMax; - Rect rect4 = rect; - rect4.xMin = rect3.xMin - 20f; - rect4.xMax = rect3.xMin; - if (EditorGUI.DropdownButton(rect3, Style.sortAscending, FocusType.Passive, Style.preButton)) - { - SortElements(rect3, descending: false); - } - if (EditorGUI.DropdownButton(rect4, Style.sortDescending, FocusType.Passive, Style.preButton)) - { - SortElements(rect4, descending: true); - } - } - } - - private void ExpandElements(bool expand) - { - if (!list.isExpanded && expand) - { - list.isExpanded = true; - } - int length = Length; - for (int i = 0; i < length; i++) - { - list.GetArrayElementAtIndex(i).isExpanded = expand; - } - } - - private void SortElements(Rect rect, bool descending) - { - int total = Length; - if (total <= 1) - { - return; - } - SerializedProperty arrayElementAtIndex = list.GetArrayElementAtIndex(0); - if (arrayElementAtIndex.propertyType == SerializedPropertyType.Generic) - { - GenericMenu genericMenu = new GenericMenu(); - SerializedProperty serializedProperty = arrayElementAtIndex.Copy(); - SerializedProperty endProperty = serializedProperty.GetEndProperty(); - bool enterChildren = true; - while (serializedProperty.NextVisible(enterChildren) && !SerializedProperty.EqualContents(serializedProperty, endProperty)) - { - genericMenu.AddItem(new GUIContent(serializedProperty.name), on: false, delegate(object userData) - { - ListSort.SortOnProperty(list, total, descending, (string)userData); - ApplyReorder(); - HandleUtility.Repaint(); - }, serializedProperty.name); - enterChildren = false; - } - genericMenu.DropDown(rect); - } - else - { - ListSort.SortOnType(list, total, descending, arrayElementAtIndex.propertyType); - ApplyReorder(); - } - } - - private void DrawEmpty(Rect rect, string label, GUIStyle backgroundStyle, GUIStyle labelStyle) - { - if (showDefaultBackground && Event.current.type == EventType.Repaint) - { - backgroundStyle.Draw(rect, isHover: false, isActive: false, on: false, hasKeyboardFocus: false); - } - EditorGUI.LabelField(rect, label, labelStyle); - } - - private void UpdateElementRects(Rect rect, Event evt) - { - int length = Length; - if (length != elementRects.Length) - { - Array.Resize(ref elementRects, length); - } - if (evt.type == EventType.Repaint) - { - Rect rect2 = rect; - float num3 = (rect2.yMin = (rect2.yMax = rect.yMin + 2f)); - float num4 = elementSpacing; - pagination.GetVisibleRange(length, out var start, out var end); - for (int i = start; i < end; i++) - { - SerializedProperty arrayElementAtIndex = list.GetArrayElementAtIndex(i); - rect2.y = rect2.yMax; - rect2.height = GetElementHeight(arrayElementAtIndex); - elementRects[i] = rect2; - rect2.yMax += num4; - } - } - } - - private void DrawElements(Rect rect, Event evt) - { - if (showDefaultBackground && evt.type == EventType.Repaint) - { - Style.boxBackground.Draw(rect, isHover: false, isActive: false, on: false, hasKeyboardFocus: false); - } - if (!dragging) - { - pagination.GetVisibleRange(Length, out var start, out var end); - for (int i = start; i < end; i++) - { - bool flag = selection.Contains(i); - DrawElement(list.GetArrayElementAtIndex(i), GetElementDrawRect(i, elementRects[i]), flag, flag && GUIUtility.keyboardControl == controlID); - } - } - else - { - if (evt.type != EventType.Repaint) - { - return; - } - int length = dragList.Length; - int length2 = selection.Length; - int j; - for (j = 0; j < length2; j++) - { - DragElement value = dragList[j]; - value.desiredRect.y = dragPosition - value.dragOffset; - dragList[j] = value; - } - j = length; - while (--j > -1) - { - DragElement value2 = dragList[j]; - if (value2.selected) - { - DrawElement(value2.property, value2.desiredRect, selected: true, focused: true); - continue; - } - Rect rect2 = value2.rect; - int num = value2.startIndex; - int num2 = ((dragDirection > 0) ? (length2 - 1) : 0); - int num3 = ((dragDirection > 0) ? (-1) : length2); - for (int num4 = num2; num4 != num3; num4 -= dragDirection) - { - DragElement dragElement = dragList[num4]; - if (dragElement.Overlaps(rect2, num, dragDirection)) - { - rect2.y -= dragElement.rect.height * (float)dragDirection; - num += dragDirection; - } - } - DrawElement(value2.property, GetElementDrawRect(j, rect2), selected: false, focused: false); - value2.desiredRect = rect2; - dragList[j] = value2; - } - } - } - - private void DrawElement(SerializedProperty element, Rect rect, bool selected, bool focused) - { - if (!(rect.height < 1f)) - { - Event current = Event.current; - if (this.drawElementBackgroundCallback != null) - { - this.drawElementBackgroundCallback(rect, element, null, selected, focused); - } - else if (current.type == EventType.Repaint) - { - Style.elementBackground.Draw(rect, isHover: false, selected, selected, focused); - EditorGUI.DrawRect(new Rect(rect.x + 1f, rect.y + rect.height - 2f, rect.width - 3f, 1f), new Color(0f, 0f, 0f, 0.2f)); - } - if (current.type == EventType.Repaint && draggable) - { - Style.draggingHandle.Draw(new Rect(rect.x + 5f, rect.y + 14f, 10f, rect.height - (rect.height - 6f)), isHover: false, isActive: false, on: false, hasKeyboardFocus: false); - } - GUIContent contents = GetElementLabel(element, elementLabels); - Rect elementRenderRect = GetElementRenderRect(element, rect); - if (this.drawElementCallback != null) - { - this.drawElementCallback(elementRenderRect, element, contents, selected, focused); - } - else - { - EditorGUI.PropertyField(elementRenderRect, element, contents, includeChildren: true); - } - int num = GUIUtility.GetControlID(contents, FocusType.Passive, rect); - if (current.GetTypeForControl(num) == EventType.ContextClick && rect.Contains(current.mousePosition)) - { - HandleSingleContextClick(current, element); - } - } - } - - private GUIContent GetElementLabel(SerializedProperty element, bool allowElementLabel) - { - if (!allowElementLabel) - { - return GUIContent.none; - } - if (this.getElementLabelCallback != null) - { - return this.getElementLabelCallback(element); - } - string text = ((this.getElementNameCallback == null) ? GetElementName(element, elementNameProperty, elementNameOverride) : this.getElementNameCallback(element)); - elementLabel.text = ((!string.IsNullOrEmpty(text)) ? text : element.displayName); - elementLabel.tooltip = element.tooltip; - elementLabel.image = elementIcon; - return elementLabel; - } - - private static string GetElementName(SerializedProperty element, string nameProperty, string nameOverride) - { - if (!string.IsNullOrEmpty(nameOverride)) - { - string propertyPath = element.propertyPath; - if (propertyPath.EndsWith("]")) - { - int num = propertyPath.LastIndexOf('[') + 1; - return $"{nameOverride} {propertyPath.Substring(num, propertyPath.Length - num - 1)}"; - } - return nameOverride; - } - if (string.IsNullOrEmpty(nameProperty)) - { - return null; - } - if (element.propertyType == SerializedPropertyType.ObjectReference && nameProperty == "name") - { - if (!element.objectReferenceValue) - { - return null; - } - return element.objectReferenceValue.name; - } - SerializedProperty serializedProperty = element.FindPropertyRelative(nameProperty); - if (serializedProperty != null) - { - switch (serializedProperty.propertyType) - { - case SerializedPropertyType.ObjectReference: - if (!serializedProperty.objectReferenceValue) - { - return null; - } - return serializedProperty.objectReferenceValue.name; - case SerializedPropertyType.Enum: - return serializedProperty.enumDisplayNames[serializedProperty.enumValueIndex]; - case SerializedPropertyType.Integer: - case SerializedPropertyType.Character: - return serializedProperty.intValue.ToString(); - case SerializedPropertyType.LayerMask: - return GetLayerMaskName(serializedProperty.intValue); - case SerializedPropertyType.String: - return serializedProperty.stringValue; - case SerializedPropertyType.Float: - return serializedProperty.floatValue.ToString(); - default: - return serializedProperty.displayName; - } - } - return null; - } - - private static string GetLayerMaskName(int mask) - { - if (mask == 0) - { - return "Nothing"; - } - if (mask < 0) - { - return "Everything"; - } - string text = string.Empty; - int num = 0; - for (int i = 0; i < 32; i++) - { - if (((1 << i) & mask) != 0) - { - if (num == 4) - { - return "Mixed ..."; - } - text = string.Concat(text, (num > 0) ? ", " : string.Empty, LayerMask.LayerToName(i)); - num++; - } - } - return text; - } - - private void DrawFooter(Rect rect) - { - if (this.drawFooterCallback != null) - { - this.drawFooterCallback(rect); - return; - } - if (Event.current.type == EventType.Repaint) - { - Style.footerBackground.Draw(rect, isHover: false, isActive: false, on: false, hasKeyboardFocus: false); - } - Rect rect2 = new Rect(rect.xMin + 4f, rect.y - 3f, 25f, 13f); - Rect position = new Rect(rect.xMax - 29f, rect.y - 3f, 25f, 13f); - EditorGUI.BeginDisabledGroup(!canAdd); - if (GUI.Button(rect2, (this.onAddDropdownCallback != null) ? Style.iconToolbarPlusMore : Style.iconToolbarPlus, Style.preButton)) - { - if (this.onAddDropdownCallback != null) - { - this.onAddDropdownCallback(rect2, this); - } - else if (this.onAddCallback != null) - { - this.onAddCallback(this); - } - else - { - AddItem(); - } - } - EditorGUI.EndDisabledGroup(); - EditorGUI.BeginDisabledGroup(!CanSelect(selection) || !canRemove || (this.onCanRemoveCallback != null && !this.onCanRemoveCallback(this))); - if (GUI.Button(position, Style.iconToolbarMinus, Style.preButton)) - { - if (this.onRemoveCallback != null) - { - this.onRemoveCallback(this); - } - else - { - Remove(selection.ToArray()); - list.serializedObject.ApplyModifiedProperties(); - list.serializedObject.Update(); - } - } - EditorGUI.EndDisabledGroup(); - } - - private void DrawPaginationHeader(Rect rect) - { - int length = Length; - int pageCount = pagination.GetPageCount(length); - int num = Mathf.Clamp(pagination.page, 0, pageCount - 1); - if (num != pagination.page) - { - pagination.page = num; - HandleUtility.Repaint(); - } - Rect position = new Rect(rect.xMin + 4f, rect.y - 1f, 17f, 14f); - Rect position2 = new Rect(position.xMax, rect.y - 1f, 17f, 14f); - Rect position3 = new Rect(position2.xMax, rect.y - 1f, 17f, 14f); - if (Event.current.type == EventType.Repaint) - { - Style.paginationHeader.Draw(rect, isHover: false, isActive: true, on: true, hasKeyboardFocus: false); - } - pageInfoContent.text = $"{pagination.page + 1} / {pageCount}"; - Rect position4 = rect; - position4.width = Style.paginationText.CalcSize(pageInfoContent).x; - position4.x = rect.xMax - position4.width - 7f; - position4.y += 2f; - GUI.Label(position4, pageInfoContent, Style.paginationText); - if (GUI.Button(position, Style.iconPagePrev, Style.preButton)) - { - pagination.page = Mathf.Max(0, pagination.page - 1); - } - if (EditorGUI.DropdownButton(position2, Style.iconPagePopup, FocusType.Passive, Style.preButton)) - { - GenericMenu genericMenu = new GenericMenu(); - for (int i = 0; i < pageCount; i++) - { - int num2 = i; - genericMenu.AddItem(new GUIContent($"Page {i + 1}"), i == pagination.page, OnPageDropDownSelect, num2); - } - genericMenu.DropDown(position2); - } - if (GUI.Button(position3, Style.iconPageNext, Style.preButton)) - { - pagination.page = Mathf.Min(pageCount - 1, pagination.page + 1); - } - pageSizeContent.text = length.ToString(); - GUIStyle pageSizeTextField = Style.pageSizeTextField; - Texture image = Style.listIcon.image; - float num3 = position3.xMax + 5f; - float num4 = position4.xMin - 5f - num3; - float num5 = image.width + 2; - float num6 = pageSizeTextField.CalcSize(pageSizeContent).x + 50f + num5; - Rect position5 = rect; - position5.x = num3 + (num4 - num6) / 2f; - position5.width = num6 - num5; - EditorGUI.BeginChangeCheck(); - EditorGUIUtility.labelWidth = num5; - EditorGUIUtility.SetIconSize(new Vector2(image.width, image.height)); - int value = EditorGUI.DelayedIntField(position5, Style.listIcon, pagination.pageSize, pageSizeTextField); - EditorGUIUtility.labelWidth = 0f; - EditorGUIUtility.SetIconSize(Vector2.zero); - if (EditorGUI.EndChangeCheck()) - { - pagination.pageSize = Mathf.Clamp(value, 0, length); - pagination.page = Mathf.Min(pagination.GetPageCount(length) - 1, pagination.page); - } - } - - private void OnPageDropDownSelect(object userData) - { - pagination.page = (int)userData; - } - - private void DispatchChange() - { - if (this.onChangedCallback != null) - { - this.onChangedCallback(this); - } - } - - private void HandleSingleContextClick(Event evt, SerializedProperty element) - { - selection.Select(IndexOf(element)); - GenericMenu genericMenu = new GenericMenu(); - if (element.isInstantiatedPrefab) - { - genericMenu.AddItem(new GUIContent(string.Concat("Revert ", GetElementLabel(element, allowElementLabel: true).text, " to Prefab")), on: false, selection.RevertValues, list); - genericMenu.AddSeparator(string.Empty); - } - HandleSharedContextClick(evt, genericMenu, "Duplicate Array Element", "Delete Array Element", "Move Array Element"); - } - - private void HandleMultipleContextClick(Event evt) - { - GenericMenu genericMenu = new GenericMenu(); - if (selection.CanRevert(list)) - { - genericMenu.AddItem(new GUIContent("Revert Values to Prefab"), on: false, selection.RevertValues, list); - genericMenu.AddSeparator(string.Empty); - } - HandleSharedContextClick(evt, genericMenu, "Duplicate Array Elements", "Delete Array Elements", "Move Array Elements"); - } - - private void HandleSharedContextClick(Event evt, GenericMenu menu, string duplicateLabel, string deleteLabel, string moveLabel) - { - menu.AddItem(new GUIContent(duplicateLabel), on: false, HandleDuplicate, list); - menu.AddItem(new GUIContent(deleteLabel), on: false, HandleDelete, list); - if (doPagination) - { - int pageCount = pagination.GetPageCount(Length); - if (pageCount > 1) - { - for (int i = 0; i < pageCount; i++) - { - string text = $"{moveLabel}/Page {i + 1}"; - menu.AddItem(new GUIContent(text), i == pagination.page, HandleMoveElement, i); - } - } - } - menu.ShowAsContext(); - evt.Use(); - } - - private void HandleMoveElement(object userData) - { - int num = (int)userData; - int page = pagination.page; - int num2 = pagination.pageSize; - int num3 = num * num2 - page * num2; - int num4 = ((num3 > 0) ? 1 : (-1)); - int length = Length; - int num5 = 0; - for (int i = 0; i < selection.Length; i++) - { - int num6 = selection[i] + num3; - num5 = ((num4 < 0) ? Mathf.Min(num5, num6) : Mathf.Max(num5, num6 - length)); - } - num3 -= num5; - UpdateDragList(0f, 0, length); - List list = new List(dragList.Elements.Where((DragElement t) => !selection.Contains(t.startIndex))); - selection.Sort(); - for (int j = 0; j < selection.Length; j++) - { - int num7 = selection[j]; - int indexFromSelection = dragList.GetIndexFromSelection(num7); - int index = Mathf.Clamp(num7 + num3, 0, list.Count); - list.Insert(index, dragList[indexFromSelection]); - } - dragList.Elements = list.ToArray(); - ReorderDraggedElements(num4, 0, null); - pagination.page = num; - HandleUtility.Repaint(); - } - - private void HandleDelete(object userData) - { - selection.Delete(userData as SerializedProperty); - DispatchChange(); - } - - private void HandleDuplicate(object userData) - { - selection.Duplicate(userData as SerializedProperty); - DispatchChange(); - } - - private void HandleDragAndDrop(Rect rect, Event evt) - { - switch (evt.GetTypeForControl(dragDropControlID)) - { - case EventType.DragUpdated: - case EventType.DragPerform: - { - if (!GUI.enabled || !rect.Contains(evt.mousePosition)) - { - break; - } - UnityEngine.Object[] objectReferences = DragAndDrop.objectReferences; - UnityEngine.Object[] array = new UnityEngine.Object[1]; - bool flag = false; - UnityEngine.Object[] array2 = objectReferences; - for (int i = 0; i < array2.Length; i++) - { - UnityEngine.Object @object = (array[0] = array2[i]); - UnityEngine.Object object2 = ValidateObjectDragAndDrop(array); - if (object2 != null) - { - DragAndDrop.visualMode = DragAndDropVisualMode.Copy; - if (evt.type == EventType.DragPerform) - { - AppendDragAndDropValue(object2); - flag = true; - DragAndDrop.activeControlID = 0; - } - else - { - DragAndDrop.activeControlID = dragDropControlID; - } - } - } - if (flag) - { - GUI.changed = true; - DragAndDrop.AcceptDrag(); - } - break; - } - case EventType.DragExited: - if (GUI.enabled) - { - HandleUtility.Repaint(); - } - break; - } - } - - private UnityEngine.Object ValidateObjectDragAndDrop(UnityEngine.Object[] references) - { - if (this.onValidateDragAndDropCallback != null) - { - return this.onValidateDragAndDropCallback(references, this); - } - if (surrogate.HasType) - { - return Internals.ValidateObjectDragAndDrop(references, null, surrogate.type, surrogate.exactType); - } - return Internals.ValidateObjectDragAndDrop(references, list, null, exactType: false); - } - - private void AppendDragAndDropValue(UnityEngine.Object obj) - { - if (this.onAppendDragDropCallback != null) - { - this.onAppendDragDropCallback(obj, this); - } - else if (surrogate.HasType) - { - surrogate.Invoke(AddItem(), obj, this); - } - else - { - Internals.AppendDragAndDropValue(obj, list); - } - DispatchChange(); - } - - private void HandlePreSelection(Rect rect, Event evt) - { - if (evt.type == EventType.MouseDrag && draggable && GUIUtility.hotControl == controlID) - { - if (selection.Length > 0 && UpdateDragPosition(evt.mousePosition, rect, dragList)) - { - GUIUtility.keyboardControl = controlID; - dragging = true; - } - evt.Use(); - } - } - - private void HandlePostSelection(Rect rect, Event evt) - { - switch (evt.GetTypeForControl(controlID)) - { - case EventType.MouseDown: - if (rect.Contains(evt.mousePosition) && IsSelectionButton(evt)) - { - int selectionIndex = GetSelectionIndex(evt.mousePosition); - if (CanSelect(selectionIndex)) - { - DoSelection(selectionIndex, GUIUtility.keyboardControl == 0 || GUIUtility.keyboardControl == controlID || evt.button == 2, evt); - } - else - { - selection.Clear(); - } - HandleUtility.Repaint(); - } - break; - case EventType.MouseUp: - if (!draggable) - { - selection.SelectWhenNoAction(pressIndex, evt); - if (this.onMouseUpCallback != null && IsPositionWithinElement(evt.mousePosition, selection.Last)) - { - this.onMouseUpCallback(this); - } - } - else if (GUIUtility.hotControl == controlID) - { - evt.Use(); - if (dragging) - { - dragging = false; - ReorderDraggedElements(dragDirection, dragList.StartIndex, delegate - { - dragList.SortByPosition(); - }); - } - else - { - selection.SelectWhenNoAction(pressIndex, evt); - if (this.onMouseUpCallback != null) - { - this.onMouseUpCallback(this); - } - } - GUIUtility.hotControl = 0; - } - HandleUtility.Repaint(); - break; - case EventType.KeyDown: - if (GUIUtility.keyboardControl != controlID) - { - break; - } - if (evt.keyCode == KeyCode.DownArrow && !dragging) - { - selection.Select(Mathf.Min(selection.Last + 1, Length - 1)); - evt.Use(); - } - else if (evt.keyCode == KeyCode.UpArrow && !dragging) - { - selection.Select(Mathf.Max(selection.Last - 1, 0)); - evt.Use(); - } - else if (evt.keyCode == KeyCode.Escape && GUIUtility.hotControl == controlID) - { - GUIUtility.hotControl = 0; - if (dragging) - { - dragging = false; - selection = beforeDragSelection; - } - evt.Use(); - } - break; - case EventType.MouseMove: - case EventType.MouseDrag: - break; - } - } - - private bool IsSelectionButton(Event evt) - { - if (evt.button != 0) - { - return evt.button == 2; - } - return true; - } - - private void DoSelection(int index, bool setKeyboardControl, Event evt) - { - if (multipleSelection) - { - selection.AppendWithAction(pressIndex = index, evt); - } - else - { - selection.Select(pressIndex = index); - } - if (this.onSelectCallback != null) - { - this.onSelectCallback(this); - } - if (draggable) - { - dragging = false; - dragPosition = (pressPosition = evt.mousePosition.y); - pagination.GetVisibleRange(Length, out var start, out var end); - UpdateDragList(dragPosition, start, end); - selection.Trim(start, end); - beforeDragSelection = selection.Clone(); - GUIUtility.hotControl = controlID; - } - if (setKeyboardControl) - { - GUIUtility.keyboardControl = controlID; - } - evt.Use(); - } - - private void UpdateDragList(float dragPosition, int start, int end) - { - dragList.Resize(start, end - start); - for (int i = start; i < end; i++) - { - SerializedProperty arrayElementAtIndex = list.GetArrayElementAtIndex(i); - Rect rect = elementRects[i]; - DragElement dragElement = default(DragElement); - dragElement.property = arrayElementAtIndex; - dragElement.dragOffset = dragPosition - rect.y; - dragElement.rect = rect; - dragElement.desiredRect = rect; - dragElement.selected = selection.Contains(i); - dragElement.startIndex = i; - DragElement value = dragElement; - dragList[i - start] = value; - } - dragList.SortByIndex(); - } - - private bool UpdateDragPosition(Vector2 position, Rect bounds, DragList dragList) - { - int index = 0; - int index2 = selection.Length - 1; - float dragOffset = dragList[index].dragOffset; - float num = dragList[index2].rect.height - dragList[index2].dragOffset; - dragPosition = Mathf.Clamp(position.y, bounds.yMin + dragOffset, bounds.yMax - num); - if (Mathf.Abs(dragPosition - pressPosition) > 1f) - { - dragDirection = (int)Mathf.Sign(dragPosition - pressPosition); - return true; - } - return false; - } - - private void ReorderDraggedElements(int direction, int offset, Action sortList) - { - dragList.RecordState(); - sortList?.Invoke(); - selection.Sort(delegate(int a, int b) - { - int indexFromSelection2 = dragList.GetIndexFromSelection(a); - int indexFromSelection3 = dragList.GetIndexFromSelection(b); - return (direction <= 0) ? indexFromSelection3.CompareTo(indexFromSelection2) : indexFromSelection2.CompareTo(indexFromSelection3); - }); - int num = selection.Length; - while (--num > -1) - { - int indexFromSelection = dragList.GetIndexFromSelection(selection[num]); - int num2 = indexFromSelection + offset; - selection[num] = num2; - list.MoveArrayElement(dragList[indexFromSelection].startIndex, num2); - } - dragList.RestoreState(list); - ApplyReorder(); - } - - private void ApplyReorder() - { - list.serializedObject.ApplyModifiedProperties(); - list.serializedObject.Update(); - if (this.onReorderCallback != null) - { - this.onReorderCallback(this); - } - DispatchChange(); - } - - private int GetSelectionIndex(Vector2 position) - { - pagination.GetVisibleRange(elementRects.Length, out var start, out var end); - for (int i = start; i < end; i++) - { - Rect rect = elementRects[i]; - if (rect.Contains(position) || (i == 0 && position.y <= rect.yMin) || (i == end - 1 && position.y >= rect.yMax)) - { - return i; - } - } - return -1; - } - - private bool CanSelect(ListSelection selection) - { - if (selection.Length <= 0) - { - return false; - } - return selection.All((int s) => CanSelect(s)); - } - - private bool CanSelect(int index) - { - if (index >= 0) - { - return index < Length; - } - return false; - } - - private bool CanSelect(Vector2 position) - { - if (selection.Length <= 0) - { - return false; - } - return selection.Any((int s) => IsPositionWithinElement(position, s)); - } - - private bool IsPositionWithinElement(Vector2 position, int index) - { - if (!CanSelect(index)) - { - return false; - } - return elementRects[index].Contains(position); - } - - private bool IsElementExpandable(SerializedProperty element) - { - switch (elementDisplayType) - { - case ElementDisplayType.Auto: - if (element.hasVisibleChildren) - { - return IsTypeExpandable(element.propertyType); - } - return false; - case ElementDisplayType.Expandable: - return true; - case ElementDisplayType.SingleLine: - return false; - default: - return false; - } - } - - private bool IsTypeExpandable(SerializedPropertyType type) - { - switch (type) - { - case SerializedPropertyType.Generic: - case SerializedPropertyType.Vector4: - case SerializedPropertyType.ArraySize: - case SerializedPropertyType.Quaternion: - return true; - default: - return false; - } - } - } -} + public int[] Selected + { + get { return selection.ToArray(); } + set { selection = new ListSelection(value); } + } + + public int Index + { + get { return selection.First; } + set { selection.Select(value); } + } + + public bool IsDragging => dragging; + + public event DrawHeaderDelegate drawHeaderCallback; + + public event DrawFooterDelegate drawFooterCallback; + + public event DrawElementDelegate drawElementCallback; + + public event DrawElementDelegate drawElementBackgroundCallback; + + public event GetElementHeightDelegate getElementHeightCallback; + + public event GetElementsHeightDelegate getElementsHeightCallback; + + public event GetElementNameDelegate getElementNameCallback; + + public event GetElementLabelDelegate getElementLabelCallback; + + public event DragDropReferenceDelegate onValidateDragAndDropCallback; + + public event DragDropAppendDelegate onAppendDragDropCallback; + + public event ActionDelegate onReorderCallback; + + public event ActionDelegate onSelectCallback; + + public event ActionDelegate onAddCallback; + + public event AddDropdownDelegate onAddDropdownCallback; + + public event ActionDelegate onRemoveCallback; + + public event ActionDelegate onMouseUpCallback; + + public event ActionBoolDelegate onCanRemoveCallback; + + public event ActionDelegate onChangedCallback; + + public ReorderableList(SerializedProperty list) + : this(list, canAdd: true, canRemove: true, draggable: true) + { + } + + public ReorderableList(SerializedProperty list, bool canAdd, bool canRemove, bool draggable) + : this(list, canAdd, canRemove, draggable, ElementDisplayType.Auto, null, null, null) + { + } + + public ReorderableList(SerializedProperty list, bool canAdd, bool canRemove, bool draggable, + ElementDisplayType elementDisplayType, string elementNameProperty, Texture elementIcon) + : this(list, canAdd, canRemove, draggable, elementDisplayType, elementNameProperty, null, elementIcon) + { + } + + public ReorderableList(SerializedProperty list, bool canAdd, bool canRemove, bool draggable, + ElementDisplayType elementDisplayType, string elementNameProperty, string elementNameOverride, + Texture elementIcon) + { + if (list == null) + { + throw new MissingListException(); + } + + if (!list.isArray) + { + SerializedProperty serializedProperty = list.FindPropertyRelative("array"); + if (serializedProperty == null || !serializedProperty.isArray) + { + throw new InvalidListException(); + } + + this.list = serializedProperty; + } + else + { + this.list = list; + } + + this.canAdd = canAdd; + this.canRemove = canRemove; + this.draggable = draggable; + this.elementDisplayType = elementDisplayType; + this.elementNameProperty = elementNameProperty; + this.elementNameOverride = elementNameOverride; + this.elementIcon = elementIcon; + id = GetHashCode(); + list.isExpanded = true; + label = new GUIContent(list.displayName); + pageInfoContent = new GUIContent(); + pageSizeContent = new GUIContent(); + verticalSpacing = EditorGUIUtility.standardVerticalSpacing; + headerHeight = 18f; + paginationHeight = 18f; + footerHeight = 13f; + slideEasing = 0.15f; + expandable = true; + elementLabels = true; + showDefaultBackground = true; + multipleSelection = true; + pagination = default(Pagination); + elementLabel = new GUIContent(); + dragList = new DragList(0); + selection = new ListSelection(); + slideGroup = new SlideGroup(); + elementRects = new Rect[0]; + } + + public float GetHeight() + { + if (!HasList) return EditorGUIUtility.singleLineHeight; + var num = doPagination ? headerHeight + paginationHeight : headerHeight; + if (!list.isExpanded) return headerHeight; + return num + GetElementsHeight() + footerHeight + 15; + } + + public void DoLayoutList() + { + var controlRect = EditorGUILayout.GetControlRect(false, GetHeight(), EditorStyles.largeLabel); + DoList(EditorGUI.IndentedRect(controlRect), label); + } + + public void DoList(Rect rect, GUIContent titleLabel) + { + var indentLevel = EditorGUI.indentLevel; + EditorGUI.indentLevel = 0; + var rect2 = rect; + rect2.height = headerHeight; + if (!HasList) + { + DrawEmpty(rect2, $"{titleLabel.text} is not an Array!", GUIStyle.none, EditorStyles.helpBox); + } + else + { + controlID = GUIUtility.GetControlID(selectionHash, FocusType.Keyboard, rect); + dragDropControlID = GUIUtility.GetControlID(dragAndDropHash, FocusType.Passive, rect); + DrawHeader(rect2, titleLabel); + if (list.isExpanded) + { + if (doPagination) + { + var rect3 = rect2; + rect3.y += rect2.height + 16f; + rect3.height = paginationHeight; + rect3.width -= 1; + rect3.xMin += 1; + DrawPaginationHeader(rect3); + rect2.yMax = rect3.yMax - 1f; + } + + var rect4 = rect; + rect4.yMin = rect2.yMax; + rect4.yMax = rect.yMax - footerHeight; + var current = Event.current; + if (selection.Length > 1 && current.type == EventType.ContextClick && + CanSelect(current.mousePosition)) + { + HandleMultipleContextClick(current); + } + + if (Length > 0) + { + if (!dragging) + { + UpdateElementRects(rect4, current); + } + + if (elementRects.Length != 0) + { + pagination.GetVisibleRange(elementRects.Length, out var start, out var end); + var rect5 = rect4; + rect5.yMin = elementRects[start].yMin; + rect5.yMax = elementRects[end - 1].yMax; + HandlePreSelection(rect5, current); + DrawElements(rect4, current); + HandlePostSelection(rect5, current); + } + } + else + { + DrawEmpty(rect4, "List is Empty", Style.boxBackground, Style.verticalLabel); + } + } + + var rect6 = rect; + rect6.yMin = rect.yMax - footerHeight; + rect6.xMin = rect.xMax - 58f; + DrawFooter(rect6); + } + + EditorGUI.indentLevel = indentLevel; + } + + public SerializedProperty AddItem(T item) where T : Object + { + SerializedProperty serializedProperty = AddItem(); + if (serializedProperty != null) + { + serializedProperty.objectReferenceValue = item; + } + + return serializedProperty; + } + + public SerializedProperty AddItem() + { + if (HasList) + { + list.arraySize++; + selection.Select(list.arraySize - 1); + SetPageByIndex(list.arraySize - 1); + DispatchChange(); + return list.GetArrayElementAtIndex(selection.Last); + } + + throw new InvalidListException(); + } + + public void Remove(int[] selection) + { + Array.Sort(selection); + int num = selection.Length; + while (--num > -1) + { + RemoveItem(selection[num]); + } + } + + public void RemoveItem(int index) + { + if (index >= 0 && index < Length) + { + SerializedProperty arrayElementAtIndex = list.GetArrayElementAtIndex(index); + if (arrayElementAtIndex.propertyType == SerializedPropertyType.ObjectReference && + (bool)arrayElementAtIndex.objectReferenceValue) + { + arrayElementAtIndex.objectReferenceValue = null; + } + + list.DeleteArrayElementAtIndex(index); + selection.Remove(index); + if (Length > 0) + { + selection.Select(Mathf.Max(0, index - 1)); + } + + DispatchChange(); + } + } + + public SerializedProperty GetItem(int index) + { + if (index >= 0 && index < Length) + { + return list.GetArrayElementAtIndex(index); + } + + return null; + } + + public int IndexOf(SerializedProperty element) + { + if (element != null) + { + int num = Length; + while (--num > -1) + { + if (SerializedProperty.EqualContents(element, list.GetArrayElementAtIndex(num))) + { + return num; + } + } + } + + return -1; + } + + public void GrabKeyboardFocus() + { + GUIUtility.keyboardControl = id; + } + + public bool HasKeyboardControl() + { + return GUIUtility.keyboardControl == id; + } + + public void ReleaseKeyboardFocus() + { + if (GUIUtility.keyboardControl == id) + { + GUIUtility.keyboardControl = 0; + } + } + + public void SetPage(int page) + { + if (doPagination) + { + pagination.page = page; + } + } + + public void SetPageByIndex(int index) + { + if (doPagination) + { + pagination.page = pagination.GetPageForIndex(index); + } + } + + public int GetPage(int index) + { + if (!doPagination) + { + return 0; + } + + return pagination.page; + } + + public int GetPageByIndex(int index) + { + if (!doPagination) + { + return 0; + } + + return pagination.GetPageForIndex(index); + } + + private float GetElementsHeight() + { + if (this.getElementsHeightCallback != null) + { + return this.getElementsHeightCallback(this); + } + + int length = Length; + if (length == 0) + { + return 28f; + } + + float num = 0f; + float num2 = elementSpacing; + pagination.GetVisibleRange(length, out var start, out var end); + for (int i = start; i < end; i++) + { + num += GetElementHeight(list.GetArrayElementAtIndex(i)) + num2; + } + + return num + 7f - num2; + } + + private float GetElementHeight(SerializedProperty element) + { + if (this.getElementHeightCallback != null) + { + return this.getElementHeightCallback(element) + 4f; + } + + float propertyHeight = EditorGUI.GetPropertyHeight(element, GetElementLabel(element, elementLabels), + IsElementExpandable(element)); + return (propertyHeight > 0f) ? (propertyHeight + 4f) : propertyHeight; + } + + private Rect GetElementDrawRect(int index, Rect desiredRect) + { + if (slideEasing <= 0f) + { + return desiredRect; + } + + if (!dragging) + { + return slideGroup.SetRect(index, desiredRect); + } + + return slideGroup.GetRect(dragList[index].startIndex, desiredRect, slideEasing); + } + + private Rect GetElementRenderRect(SerializedProperty element, Rect elementRect) + { + float num = (draggable ? 20 : 5); + Rect result = elementRect; + result.xMin += (IsElementExpandable(element) ? (num + 10f) : num); + result.xMax -= 6f; + result.yMin += 1f; + result.yMax -= 3f; + return result; + } + + private void DrawHeader(Rect rect, GUIContent titleLabel) + { + if (showDefaultBackground && Event.current.type == EventType.Repaint) + { + Style.headerBackground.Draw(rect, isHover: false, isActive: false, on: false, hasKeyboardFocus: false); + } + + HandleDragAndDrop(rect, Event.current); + var flag = elementDisplayType != ElementDisplayType.SingleLine; + var rect2 = rect; + rect2.xMin += 6f; + rect2.xMax -= flag ? 95f : 55f; + rect2.height = 15f; + rect2.y++; + titleLabel = EditorGUI.BeginProperty(rect2, titleLabel, list); + if (this.drawHeaderCallback != null) + { + drawHeaderCallback(rect2, titleLabel); + } + else if (expandable) + { + rect2.xMin += 10f; + EditorGUI.BeginChangeCheck(); + var isExpanded = EditorGUI.Foldout(rect2, list.isExpanded, titleLabel, toggleOnLabelClick: true); + if (EditorGUI.EndChangeCheck()) + { + list.isExpanded = isExpanded; + } + } + else + { + GUI.Label(rect2, titleLabel, EditorStyles.label); + } + + EditorGUI.EndProperty(); + if (flag) + { + var position = rect; + position.xMin = rect.xMax - 25f; + position.xMax = rect.xMax - 5f; + if (GUI.Button(position, Style.expandButton, Style.preButton)) + { + ExpandElements(expand: true); + } + + var position2 = rect; + position2.xMin = position.xMin - 20f; + position2.xMax = position.xMin; + if (GUI.Button(position2, Style.collapseButton, Style.preButton)) + { + ExpandElements(expand: false); + } + + rect.xMax = position2.xMin + 5f; + } + + if (!sortable) return; + var rect3 = rect; + rect3.xMin = rect.xMax - 25f; + rect3.xMax = rect.xMax; + var rect4 = rect; + rect4.xMin = rect3.xMin - 20f; + rect4.xMax = rect3.xMin; + if (EditorGUI.DropdownButton(rect3, Style.sortAscending, FocusType.Passive, Style.preButton)) + { + SortElements(rect3, descending: false); + } + + if (EditorGUI.DropdownButton(rect4, Style.sortDescending, FocusType.Passive, Style.preButton)) + { + SortElements(rect4, descending: true); + } + } + + private void ExpandElements(bool expand) + { + if (!list.isExpanded && expand) + { + list.isExpanded = true; + } + + int length = Length; + for (int i = 0; i < length; i++) + { + list.GetArrayElementAtIndex(i).isExpanded = expand; + } + } + + private void SortElements(Rect rect, bool descending) + { + int total = Length; + if (total <= 1) + { + return; + } + + SerializedProperty arrayElementAtIndex = list.GetArrayElementAtIndex(0); + if (arrayElementAtIndex.propertyType == SerializedPropertyType.Generic) + { + GenericMenu genericMenu = new GenericMenu(); + SerializedProperty serializedProperty = arrayElementAtIndex.Copy(); + SerializedProperty endProperty = serializedProperty.GetEndProperty(); + bool enterChildren = true; + while (serializedProperty.NextVisible(enterChildren) && + !SerializedProperty.EqualContents(serializedProperty, endProperty)) + { + genericMenu.AddItem(new GUIContent(serializedProperty.name), on: false, delegate(object userData) + { + ListSort.SortOnProperty(list, total, descending, (string)userData); + ApplyReorder(); + HandleUtility.Repaint(); + }, serializedProperty.name); + enterChildren = false; + } + + genericMenu.DropDown(rect); + } + else + { + ListSort.SortOnType(list, total, descending, arrayElementAtIndex.propertyType); + ApplyReorder(); + } + } + + private void DrawEmpty(Rect rect, string label, GUIStyle backgroundStyle, GUIStyle labelStyle) + { + if (showDefaultBackground && Event.current.type == EventType.Repaint) + { + backgroundStyle.Draw(rect, isHover: false, isActive: false, on: false, hasKeyboardFocus: false); + } + + EditorGUI.LabelField(rect, label, labelStyle); + } + + private void UpdateElementRects(Rect rect, Event evt) + { + int length = Length; + if (length != elementRects.Length) + { + Array.Resize(ref elementRects, length); + } + + if (evt.type == EventType.Repaint) + { + Rect rect2 = rect; + float num3 = (rect2.yMin = (rect2.yMax = rect.yMin + 2f)); + float num4 = elementSpacing; + pagination.GetVisibleRange(length, out var start, out var end); + for (int i = start; i < end; i++) + { + SerializedProperty arrayElementAtIndex = list.GetArrayElementAtIndex(i); + rect2.y = rect2.yMax; + rect2.height = GetElementHeight(arrayElementAtIndex); + elementRects[i] = rect2; + rect2.yMax += num4; + } + } + } + + private void DrawElements(Rect rect, Event evt) + { + if (showDefaultBackground && evt.type == EventType.Repaint) + { + Style.boxBackground.Draw(rect, isHover: false, isActive: false, on: false, hasKeyboardFocus: false); + } + + if (!dragging) + { + pagination.GetVisibleRange(Length, out var start, out var end); + for (int i = start; i < end; i++) + { + bool flag = selection.Contains(i); + DrawElement(list.GetArrayElementAtIndex(i), GetElementDrawRect(i, elementRects[i]), flag, + flag && GUIUtility.keyboardControl == controlID); + } + } + else + { + if (evt.type != EventType.Repaint) + { + return; + } + + int length = dragList.Length; + int length2 = selection.Length; + int j; + for (j = 0; j < length2; j++) + { + DragElement value = dragList[j]; + value.desiredRect.y = dragPosition - value.dragOffset; + dragList[j] = value; + } + + j = length; + while (--j > -1) + { + DragElement value2 = dragList[j]; + if (value2.selected) + { + DrawElement(value2.property, value2.desiredRect, selected: true, focused: true); + continue; + } + + Rect rect2 = value2.rect; + int num = value2.startIndex; + int num2 = ((dragDirection > 0) ? (length2 - 1) : 0); + int num3 = ((dragDirection > 0) ? (-1) : length2); + for (int num4 = num2; num4 != num3; num4 -= dragDirection) + { + DragElement dragElement = dragList[num4]; + if (dragElement.Overlaps(rect2, num, dragDirection)) + { + rect2.y -= dragElement.rect.height * (float)dragDirection; + num += dragDirection; + } + } + + DrawElement(value2.property, GetElementDrawRect(j, rect2), selected: false, focused: false); + value2.desiredRect = rect2; + dragList[j] = value2; + } + } + } + + private void DrawElement(SerializedProperty element, Rect rect, bool selected, bool focused) + { + if (!(rect.height < 1f)) + { + Event current = Event.current; + if (this.drawElementBackgroundCallback != null) + { + this.drawElementBackgroundCallback(rect, element, null, selected, focused); + } + else if (current.type == EventType.Repaint) + { + Style.elementBackground.Draw(rect, isHover: false, selected, selected, focused); + EditorGUI.DrawRect(new Rect(rect.x + 1f, rect.y + rect.height - 2f, rect.width - 3f, 1f), + new Color(0f, 0f, 0f, 0.2f)); + } + + if (current.type == EventType.Repaint && draggable) + { + Style.draggingHandle.Draw( + new Rect(rect.x + 5f, rect.y + 14f, 10f, rect.height - (rect.height - 6f)), isHover: false, + isActive: false, on: false, hasKeyboardFocus: false); + } + + GUIContent contents = GetElementLabel(element, elementLabels); + Rect elementRenderRect = GetElementRenderRect(element, rect); + if (this.drawElementCallback != null) + { + this.drawElementCallback(elementRenderRect, element, contents, selected, focused); + } + else + { + EditorGUI.PropertyField(elementRenderRect, element, contents, includeChildren: true); + } + + int num = GUIUtility.GetControlID(contents, FocusType.Passive, rect); + if (current.GetTypeForControl(num) == EventType.ContextClick && rect.Contains(current.mousePosition)) + { + HandleSingleContextClick(current, element); + } + } + } + + private GUIContent GetElementLabel(SerializedProperty element, bool allowElementLabel) + { + if (!allowElementLabel) + { + return GUIContent.none; + } + + if (this.getElementLabelCallback != null) + { + return this.getElementLabelCallback(element); + } + + string text = ((this.getElementNameCallback == null) + ? GetElementName(element, elementNameProperty, elementNameOverride) + : this.getElementNameCallback(element)); + elementLabel.text = ((!string.IsNullOrEmpty(text)) ? text : element.displayName); + elementLabel.tooltip = element.tooltip; + elementLabel.image = elementIcon; + return elementLabel; + } + + private static string GetElementName(SerializedProperty element, string nameProperty, string nameOverride) + { + if (!string.IsNullOrEmpty(nameOverride)) + { + string propertyPath = element.propertyPath; + if (propertyPath.EndsWith("]")) + { + int num = propertyPath.LastIndexOf('[') + 1; + return $"{nameOverride} {propertyPath.Substring(num, propertyPath.Length - num - 1)}"; + } + + return nameOverride; + } + + if (string.IsNullOrEmpty(nameProperty)) + { + return null; + } + + if (element.propertyType == SerializedPropertyType.ObjectReference && nameProperty == "name") + { + if (!element.objectReferenceValue) + { + return null; + } + + return element.objectReferenceValue.name; + } + + SerializedProperty serializedProperty = element.FindPropertyRelative(nameProperty); + if (serializedProperty != null) + { + switch (serializedProperty.propertyType) + { + case SerializedPropertyType.ObjectReference: + if (!serializedProperty.objectReferenceValue) + { + return null; + } + + return serializedProperty.objectReferenceValue.name; + case SerializedPropertyType.Enum: + return serializedProperty.enumDisplayNames[serializedProperty.enumValueIndex]; + case SerializedPropertyType.Integer: + case SerializedPropertyType.Character: + return serializedProperty.intValue.ToString(); + case SerializedPropertyType.LayerMask: + return GetLayerMaskName(serializedProperty.intValue); + case SerializedPropertyType.String: + return serializedProperty.stringValue; + case SerializedPropertyType.Float: + return serializedProperty.floatValue.ToString(); + default: + return serializedProperty.displayName; + } + } + + return null; + } + + private static string GetLayerMaskName(int mask) + { + if (mask == 0) + { + return "Nothing"; + } + + if (mask < 0) + { + return "Everything"; + } + + string text = string.Empty; + int num = 0; + for (int i = 0; i < 32; i++) + { + if (((1 << i) & mask) != 0) + { + if (num == 4) + { + return "Mixed ..."; + } + + text = string.Concat(text, (num > 0) ? ", " : string.Empty, LayerMask.LayerToName(i)); + num++; + } + } + + return text; + } + + private void DrawFooter(Rect rect) + { + if (this.drawFooterCallback != null) + { + this.drawFooterCallback(rect); + return; + } + + if (Event.current.type == EventType.Repaint) + { + Style.footerBackground.Draw(rect, isHover: false, isActive: false, on: false, hasKeyboardFocus: false); + } + + var rect2 = new Rect(rect.xMin + 4f, rect.y - 3f, 25f, 13f); + var position = new Rect(rect.xMax - 29f, rect.y - 3f, 25f, 13f); + EditorGUI.BeginDisabledGroup(!canAdd); + if (GUI.Button(rect2, + onAddDropdownCallback != null ? Style.iconToolbarPlusMore : Style.iconToolbarPlus, + Style.preButton)) + { + if (this.onAddDropdownCallback != null) + { + this.onAddDropdownCallback(rect2, this); + } + else if (this.onAddCallback != null) + { + this.onAddCallback(this); + } + else + { + AddItem(); + } + } + + EditorGUI.EndDisabledGroup(); + EditorGUI.BeginDisabledGroup(!CanSelect(selection) || !canRemove || + (this.onCanRemoveCallback != null && !this.onCanRemoveCallback(this))); + if (GUI.Button(position, Style.iconToolbarMinus, Style.preButton)) + { + if (this.onRemoveCallback != null) + { + this.onRemoveCallback(this); + } + else + { + Remove(selection.ToArray()); + list.serializedObject.ApplyModifiedProperties(); + list.serializedObject.Update(); + } + } + + EditorGUI.EndDisabledGroup(); + } + + private void DrawPaginationHeader(Rect rect) + { + var length = Length; + var pageCount = pagination.GetPageCount(length); + var num = Mathf.Clamp(pagination.page, 0, pageCount - 1); + if (num != pagination.page) + { + pagination.page = num; + HandleUtility.Repaint(); + } + + var position = new Rect(rect.xMin + 4f, rect.y - 1f, 17f, 14f); + var position2 = new Rect(position.xMax, rect.y - 1f, 17f, 14f); + var position3 = new Rect(position2.xMax, rect.y - 1f, 17f, 14f); + if (Event.current.type == EventType.Repaint) + { + Style.paginationHeader.Draw(rect, isHover: false, isActive: true, on: true, hasKeyboardFocus: false); + } + + pageInfoContent.text = $"{pagination.page + 1} / {pageCount}"; + var position4 = rect; + position4.width = Style.paginationText.CalcSize(pageInfoContent).x; + position4.x = rect.xMax - position4.width - 7f; + position4.y += 2f; + GUI.Label(position4, pageInfoContent, Style.paginationText); + if (GUI.Button(position, Style.iconPagePrev, Style.preButton)) + { + pagination.page = Mathf.Max(0, pagination.page - 1); + } + + if (EditorGUI.DropdownButton(position2, Style.iconPagePopup, FocusType.Passive, Style.preButton)) + { + GenericMenu genericMenu = new GenericMenu(); + for (int i = 0; i < pageCount; i++) + { + int num2 = i; + genericMenu.AddItem(new GUIContent($"Page {i + 1}"), i == pagination.page, OnPageDropDownSelect, + num2); + } + + genericMenu.DropDown(position2); + } + + if (GUI.Button(position3, Style.iconPageNext, Style.preButton)) + { + pagination.page = Mathf.Min(pageCount - 1, pagination.page + 1); + } + + pageSizeContent.text = length.ToString(); + GUIStyle pageSizeTextField = Style.pageSizeTextField; + Texture image = Style.listIcon.image; + float num3 = position3.xMax + 5f; + float num4 = position4.xMin - 5f - num3; + float num5 = image.width + 2; + float num6 = pageSizeTextField.CalcSize(pageSizeContent).x + 50f + num5; + Rect position5 = rect; + position5.x = num3 + (num4 - num6) / 2f; + position5.width = num6 - num5; + EditorGUI.BeginChangeCheck(); + EditorGUIUtility.labelWidth = num5; + EditorGUIUtility.SetIconSize(new Vector2(image.width, image.height)); + int value = EditorGUI.DelayedIntField(position5, Style.listIcon, pagination.pageSize, pageSizeTextField); + EditorGUIUtility.labelWidth = 0f; + EditorGUIUtility.SetIconSize(Vector2.zero); + if (EditorGUI.EndChangeCheck()) + { + pagination.pageSize = Mathf.Clamp(value, 0, length); + pagination.page = Mathf.Min(pagination.GetPageCount(length) - 1, pagination.page); + } + } + + private void OnPageDropDownSelect(object userData) + { + pagination.page = (int)userData; + } + + private void DispatchChange() + { + if (this.onChangedCallback != null) + { + this.onChangedCallback(this); + } + } + + private void HandleSingleContextClick(Event evt, SerializedProperty element) + { + selection.Select(IndexOf(element)); + GenericMenu genericMenu = new GenericMenu(); + if (element.isInstantiatedPrefab) + { + genericMenu.AddItem( + new GUIContent(string.Concat("Revert ", GetElementLabel(element, allowElementLabel: true).text, + " to Prefab")), on: false, selection.RevertValues, list); + genericMenu.AddSeparator(string.Empty); + } + + HandleSharedContextClick(evt, genericMenu, "Duplicate Array Element", "Delete Array Element", + "Move Array Element"); + } + + private void HandleMultipleContextClick(Event evt) + { + GenericMenu genericMenu = new GenericMenu(); + if (selection.CanRevert(list)) + { + genericMenu.AddItem(new GUIContent("Revert Values to Prefab"), on: false, selection.RevertValues, list); + genericMenu.AddSeparator(string.Empty); + } + + HandleSharedContextClick(evt, genericMenu, "Duplicate Array Elements", "Delete Array Elements", + "Move Array Elements"); + } + + private void HandleSharedContextClick(Event evt, GenericMenu menu, string duplicateLabel, string deleteLabel, + string moveLabel) + { + menu.AddItem(new GUIContent(duplicateLabel), on: false, HandleDuplicate, list); + menu.AddItem(new GUIContent(deleteLabel), on: false, HandleDelete, list); + if (doPagination) + { + int pageCount = pagination.GetPageCount(Length); + if (pageCount > 1) + { + for (int i = 0; i < pageCount; i++) + { + string text = $"{moveLabel}/Page {i + 1}"; + menu.AddItem(new GUIContent(text), i == pagination.page, HandleMoveElement, i); + } + } + } + + menu.ShowAsContext(); + evt.Use(); + } + + private void HandleMoveElement(object userData) + { + int num = (int)userData; + int page = pagination.page; + int num2 = pagination.pageSize; + int num3 = num * num2 - page * num2; + int num4 = ((num3 > 0) ? 1 : (-1)); + int length = Length; + int num5 = 0; + for (int i = 0; i < selection.Length; i++) + { + int num6 = selection[i] + num3; + num5 = ((num4 < 0) ? Mathf.Min(num5, num6) : Mathf.Max(num5, num6 - length)); + } + + num3 -= num5; + UpdateDragList(0f, 0, length); + List list = + new List(dragList.Elements.Where((DragElement t) => !selection.Contains(t.startIndex))); + selection.Sort(); + for (int j = 0; j < selection.Length; j++) + { + int num7 = selection[j]; + int indexFromSelection = dragList.GetIndexFromSelection(num7); + int index = Mathf.Clamp(num7 + num3, 0, list.Count); + list.Insert(index, dragList[indexFromSelection]); + } + + dragList.Elements = list.ToArray(); + ReorderDraggedElements(num4, 0, null); + pagination.page = num; + HandleUtility.Repaint(); + } + + private void HandleDelete(object userData) + { + selection.Delete(userData as SerializedProperty); + DispatchChange(); + } + + private void HandleDuplicate(object userData) + { + selection.Duplicate(userData as SerializedProperty); + DispatchChange(); + } + + private void HandleDragAndDrop(Rect rect, Event evt) + { + switch (evt.GetTypeForControl(dragDropControlID)) + { + case EventType.DragUpdated: + case EventType.DragPerform: + { + if (!GUI.enabled || !rect.Contains(evt.mousePosition)) + { + break; + } + + Object[] objectReferences = DragAndDrop.objectReferences; + Object[] array = new Object[1]; + bool flag = false; + Object[] array2 = objectReferences; + for (int i = 0; i < array2.Length; i++) + { + Object @object = (array[0] = array2[i]); + Object object2 = ValidateObjectDragAndDrop(array); + if (object2 != null) + { + DragAndDrop.visualMode = DragAndDropVisualMode.Copy; + if (evt.type == EventType.DragPerform) + { + AppendDragAndDropValue(object2); + flag = true; + DragAndDrop.activeControlID = 0; + } + else + { + DragAndDrop.activeControlID = dragDropControlID; + } + } + } + + if (flag) + { + GUI.changed = true; + DragAndDrop.AcceptDrag(); + } + + break; + } + case EventType.DragExited: + if (GUI.enabled) + { + HandleUtility.Repaint(); + } + + break; + } + } + + private Object ValidateObjectDragAndDrop(Object[] references) + { + if (this.onValidateDragAndDropCallback != null) + { + return this.onValidateDragAndDropCallback(references, this); + } + + if (surrogate.HasType) + { + return Internals.ValidateObjectDragAndDrop(references, null, surrogate.type, surrogate.exactType); + } + + return Internals.ValidateObjectDragAndDrop(references, list, null, exactType: false); + } + + private void AppendDragAndDropValue(Object obj) + { + if (this.onAppendDragDropCallback != null) + { + this.onAppendDragDropCallback(obj, this); + } + else if (surrogate.HasType) + { + surrogate.Invoke(AddItem(), obj, this); + } + else + { + Internals.AppendDragAndDropValue(obj, list); + } + + DispatchChange(); + } + + private void HandlePreSelection(Rect rect, Event evt) + { + if (evt.type == EventType.MouseDrag && draggable && GUIUtility.hotControl == controlID) + { + if (selection.Length > 0 && UpdateDragPosition(evt.mousePosition, rect, dragList)) + { + GUIUtility.keyboardControl = controlID; + dragging = true; + } + + evt.Use(); + } + } + + private void HandlePostSelection(Rect rect, Event evt) + { + switch (evt.GetTypeForControl(controlID)) + { + case EventType.MouseDown: + if (rect.Contains(evt.mousePosition) && IsSelectionButton(evt)) + { + int selectionIndex = GetSelectionIndex(evt.mousePosition); + if (CanSelect(selectionIndex)) + { + DoSelection(selectionIndex, + GUIUtility.keyboardControl == 0 || GUIUtility.keyboardControl == controlID || + evt.button == 2, evt); + } + else + { + selection.Clear(); + } + + HandleUtility.Repaint(); + } + + break; + case EventType.MouseUp: + if (!draggable) + { + selection.SelectWhenNoAction(pressIndex, evt); + if (this.onMouseUpCallback != null && + IsPositionWithinElement(evt.mousePosition, selection.Last)) + { + this.onMouseUpCallback(this); + } + } + else if (GUIUtility.hotControl == controlID) + { + evt.Use(); + if (dragging) + { + dragging = false; + ReorderDraggedElements(dragDirection, dragList.StartIndex, + delegate { dragList.SortByPosition(); }); + } + else + { + selection.SelectWhenNoAction(pressIndex, evt); + if (this.onMouseUpCallback != null) + { + this.onMouseUpCallback(this); + } + } + + GUIUtility.hotControl = 0; + } + + HandleUtility.Repaint(); + break; + case EventType.KeyDown: + if (GUIUtility.keyboardControl != controlID) + { + break; + } + + if (evt.keyCode == KeyCode.DownArrow && !dragging) + { + selection.Select(Mathf.Min(selection.Last + 1, Length - 1)); + evt.Use(); + } + else if (evt.keyCode == KeyCode.UpArrow && !dragging) + { + selection.Select(Mathf.Max(selection.Last - 1, 0)); + evt.Use(); + } + else if (evt.keyCode == KeyCode.Escape && GUIUtility.hotControl == controlID) + { + GUIUtility.hotControl = 0; + if (dragging) + { + dragging = false; + selection = beforeDragSelection; + } + + evt.Use(); + } + + break; + case EventType.MouseMove: + case EventType.MouseDrag: + break; + } + } + + private bool IsSelectionButton(Event evt) + { + if (evt.button != 0) + { + return evt.button == 2; + } + + return true; + } + + private void DoSelection(int index, bool setKeyboardControl, Event evt) + { + if (multipleSelection) + { + selection.AppendWithAction(pressIndex = index, evt); + } + else + { + selection.Select(pressIndex = index); + } + + if (this.onSelectCallback != null) + { + this.onSelectCallback(this); + } + + if (draggable) + { + dragging = false; + dragPosition = (pressPosition = evt.mousePosition.y); + pagination.GetVisibleRange(Length, out var start, out var end); + UpdateDragList(dragPosition, start, end); + selection.Trim(start, end); + beforeDragSelection = selection.Clone(); + GUIUtility.hotControl = controlID; + } + + if (setKeyboardControl) + { + GUIUtility.keyboardControl = controlID; + } + + evt.Use(); + } + + private void UpdateDragList(float dragPosition, int start, int end) + { + dragList.Resize(start, end - start); + for (int i = start; i < end; i++) + { + SerializedProperty arrayElementAtIndex = list.GetArrayElementAtIndex(i); + Rect rect = elementRects[i]; + DragElement dragElement = default(DragElement); + dragElement.property = arrayElementAtIndex; + dragElement.dragOffset = dragPosition - rect.y; + dragElement.rect = rect; + dragElement.desiredRect = rect; + dragElement.selected = selection.Contains(i); + dragElement.startIndex = i; + DragElement value = dragElement; + dragList[i - start] = value; + } + + dragList.SortByIndex(); + } + + private bool UpdateDragPosition(Vector2 position, Rect bounds, DragList dragList) + { + int index = 0; + int index2 = selection.Length - 1; + float dragOffset = dragList[index].dragOffset; + float num = dragList[index2].rect.height - dragList[index2].dragOffset; + dragPosition = Mathf.Clamp(position.y, bounds.yMin + dragOffset, bounds.yMax - num); + if (Mathf.Abs(dragPosition - pressPosition) > 1f) + { + dragDirection = (int)Mathf.Sign(dragPosition - pressPosition); + return true; + } + + return false; + } + + private void ReorderDraggedElements(int direction, int offset, Action sortList) + { + dragList.RecordState(); + sortList?.Invoke(); + selection.Sort(delegate(int a, int b) + { + int indexFromSelection2 = dragList.GetIndexFromSelection(a); + int indexFromSelection3 = dragList.GetIndexFromSelection(b); + return (direction <= 0) + ? indexFromSelection3.CompareTo(indexFromSelection2) + : indexFromSelection2.CompareTo(indexFromSelection3); + }); + int num = selection.Length; + while (--num > -1) + { + int indexFromSelection = dragList.GetIndexFromSelection(selection[num]); + int num2 = indexFromSelection + offset; + selection[num] = num2; + list.MoveArrayElement(dragList[indexFromSelection].startIndex, num2); + } + + dragList.RestoreState(list); + ApplyReorder(); + } + + private void ApplyReorder() + { + list.serializedObject.ApplyModifiedProperties(); + list.serializedObject.Update(); + if (this.onReorderCallback != null) + { + this.onReorderCallback(this); + } + + DispatchChange(); + } + + private int GetSelectionIndex(Vector2 position) + { + pagination.GetVisibleRange(elementRects.Length, out var start, out var end); + for (int i = start; i < end; i++) + { + Rect rect = elementRects[i]; + if (rect.Contains(position) || (i == 0 && position.y <= rect.yMin) || + (i == end - 1 && position.y >= rect.yMax)) + { + return i; + } + } + + return -1; + } + + private bool CanSelect(ListSelection selection) + { + if (selection.Length <= 0) + { + return false; + } + + return selection.All((int s) => CanSelect(s)); + } + + private bool CanSelect(int index) + { + if (index >= 0) + { + return index < Length; + } + + return false; + } + + private bool CanSelect(Vector2 position) + { + if (selection.Length <= 0) + { + return false; + } + + return selection.Any((int s) => IsPositionWithinElement(position, s)); + } + + private bool IsPositionWithinElement(Vector2 position, int index) + { + if (!CanSelect(index)) + { + return false; + } + + return elementRects[index].Contains(position); + } + + private bool IsElementExpandable(SerializedProperty element) + { + switch (elementDisplayType) + { + case ElementDisplayType.Auto: + if (element.hasVisibleChildren) + { + return IsTypeExpandable(element.propertyType); + } + + return false; + case ElementDisplayType.Expandable: + return true; + case ElementDisplayType.SingleLine: + return false; + default: + return false; + } + } + + private bool IsTypeExpandable(SerializedPropertyType type) + { + switch (type) + { + case SerializedPropertyType.Generic: + case SerializedPropertyType.Vector4: + case SerializedPropertyType.ArraySize: + case SerializedPropertyType.Quaternion: + return true; + default: + return false; + } + } + } +} \ No newline at end of file diff --git a/Tools~/Process/Process.Unity/Script/RainbowFolders/Borodar.RainbowCore/CoreEditorUtility.cs b/Tools~/Process/Process.Unity/Script/RainbowFolders/Borodar.RainbowCore/CoreEditorUtility.cs index c9f78668..5f6c7a4c 100644 --- a/Tools~/Process/Process.Unity/Script/RainbowFolders/Borodar.RainbowCore/CoreEditorUtility.cs +++ b/Tools~/Process/Process.Unity/Script/RainbowFolders/Borodar.RainbowCore/CoreEditorUtility.cs @@ -7,95 +7,153 @@ namespace AIO.RainbowCore { - internal static class CoreEditorUtility - { - public static readonly Color POPUP_BORDER_CLR_FREE = new Color(0.51f, 0.51f, 0.51f); - - public static readonly Color POPUP_BORDER_CLR_PRO = new Color(0.13f, 0.13f, 0.13f); - - public static readonly Color POPUP_BACKGROUND_CLR_FREE = new Color(0.83f, 0.83f, 0.83f); - - public static readonly Color POPUP_BACKGROUND_CLR_PRO = new Color(0.18f, 0.18f, 0.18f); - - public static readonly Color SEPARATOR_CLR_1_FREE = new Color(0.65f, 0.65f, 0.65f, 1f); - - public static readonly Color SEPARATOR_CLR_2_FREE = new Color(0.9f, 0.9f, 0.9f, 1f); - - public static readonly Color SEPARATOR_CLR_1_PRO = new Color(0.13f, 0.13f, 0.13f, 1f); - - public static readonly Color SEPARATOR_CLR_2_PRO = new Color(0.22f, 0.22f, 0.22f, 1f); - - public static void CreateAsset(string baseName, string forcedPath = "") where T : ScriptableObject - { - if (baseName.Contains("/")) - { - throw new ArgumentException("Base name should not contain slashes"); - } - T val = ScriptableObject.CreateInstance(); - string text; - if (!string.IsNullOrEmpty(forcedPath)) - { - text = forcedPath; - Directory.CreateDirectory(forcedPath); - } - else - { - text = AssetDatabase.GetAssetPath(Selection.activeObject); - if (string.IsNullOrEmpty(text)) - { - text = "Assets"; - } - else if (Path.GetExtension(text) != string.Empty) - { - text = text.Replace(Path.GetFileName(text), string.Empty); - } - } - string path = AssetDatabase.GenerateUniqueAssetPath(string.Concat(text, "/", baseName, ".asset")); - AssetDatabase.CreateAsset(val, path); - AssetDatabase.SaveAssets(); - EditorUtility.FocusProjectWindow(); - Selection.activeObject = val; - } - - public static IEnumerable GetAllWindowsByType(string type) - { - return from obj in Resources.FindObjectsOfTypeAll(typeof(EditorWindow)) - where obj.GetType().ToString() == type - select (EditorWindow)obj; - } - - public static bool SearchField(ref string query, ref Enum filter, Enum defaultFilter, params GUILayoutOption[] options) - { - string value = query; - Enum objB = filter; - bool result = false; - GUILayout.BeginHorizontal(); - Rect rect = GUILayoutUtility.GetRect(GUIContent.none, "ToolbarSeachTextFieldPopup", options); - rect.width -= 18f; - Rect position = rect; - position.width = 20f; - filter = EditorGUI.EnumPopup(position, filter, "label"); - if (!object.Equals(filter, objB)) - { - result = true; - } - query = EditorGUI.TextField(rect, "", query, "ToolbarSeachTextFieldPopup"); - if (query != null && !query.Equals(value)) - { - result = true; - } - Rect position2 = rect; - position2.x += rect.width; - position2.width = 18f; - if (GUI.Button(position2, "", "ToolbarSeachCancelButton")) - { - query = string.Empty; - filter = defaultFilter; - result = true; - GUIUtility.keyboardControl = 0; - } - GUILayout.EndHorizontal(); - return result; - } - } -} + internal static class CoreEditorUtility + { + public static readonly Color POPUP_BORDER_CLR_FREE = new Color(0.51f, 0.51f, 0.51f); + + public static readonly Color POPUP_BORDER_CLR_PRO = new Color(0.13f, 0.13f, 0.13f); + + public static readonly Color POPUP_BACKGROUND_CLR_FREE = new Color(0.83f, 0.83f, 0.83f); + + public static readonly Color POPUP_BACKGROUND_CLR_PRO = new Color(0.18f, 0.18f, 0.18f); + + public static readonly Color SEPARATOR_CLR_1_FREE = new Color(0.65f, 0.65f, 0.65f, 1f); + + public static readonly Color SEPARATOR_CLR_2_FREE = new Color(0.9f, 0.9f, 0.9f, 1f); + + public static readonly Color SEPARATOR_CLR_1_PRO = new Color(0.13f, 0.13f, 0.13f, 1f); + + public static readonly Color SEPARATOR_CLR_2_PRO = new Color(0.22f, 0.22f, 0.22f, 1f); + + public static void CreateAsset(string baseName, string forcedPath = "") where T : ScriptableObject + { + if (baseName.Contains("/")) + { + throw new ArgumentException("Base name should not contain slashes"); + } + + T val = ScriptableObject.CreateInstance(); + string text; + if (!string.IsNullOrEmpty(forcedPath)) + { + text = forcedPath; + Directory.CreateDirectory(forcedPath); + } + else + { + text = AssetDatabase.GetAssetPath(Selection.activeObject); + if (string.IsNullOrEmpty(text)) + { + text = "Assets"; + } + else if (Path.GetExtension(text) != string.Empty) + { + text = text.Replace(Path.GetFileName(text), string.Empty); + } + } + + string path = AssetDatabase.GenerateUniqueAssetPath(string.Concat(text, "/", baseName, ".asset")); + AssetDatabase.CreateAsset(val, path); + AssetDatabase.SaveAssets(); + EditorUtility.FocusProjectWindow(); + Selection.activeObject = val; + } + + public static IEnumerable GetAllWindowsByType(string type) + { + return from obj in Resources.FindObjectsOfTypeAll(typeof(EditorWindow)) + where obj.GetType().ToString() == type + select (EditorWindow)obj; + } + + private static GUIStyle ToolbarSearchTextFieldPopup + { + get + { + if (!(_ToolbarSearchTextFieldPopup is null)) return _ToolbarSearchTextFieldPopup; + if (int.TryParse(Application.unityVersion.Split('.')[0], out var ver)) + { + switch (ver) + { + case 2023: + _ToolbarSearchTextFieldPopup = new GUIStyle("ToolbarSearchTextFieldPopup"); + break; + default: + _ToolbarSearchTextFieldPopup = new GUIStyle("ToolbarSeachTextFieldPopup"); + break; + } + } + else _ToolbarSearchTextFieldPopup = GUIStyle.none; + + return _ToolbarSearchTextFieldPopup; + } + } + + private static GUIStyle _ToolbarSearchTextFieldPopup; + + private static GUIStyle ToolbarSearchCancelButton + { + get + { + if (!(_ToolbarSearchCancelButton is null)) return _ToolbarSearchCancelButton; + if (int.TryParse(Application.unityVersion.Split('.')[0], out var ver)) + { + switch (ver) + { + case 2023: + _ToolbarSearchCancelButton = new GUIStyle("ToolbarSearchCancelButton"); + break; + default: + _ToolbarSearchCancelButton = new GUIStyle("ToolbarSeachCancelButton"); + break; + } + } + else _ToolbarSearchCancelButton = GUIStyle.none; + + return _ToolbarSearchCancelButton; + } + } + + private static GUIStyle _ToolbarSearchCancelButton; + + + public static bool SearchField(ref string query, ref Enum filter, Enum defaultFilter, + params GUILayoutOption[] options) + { + var value = query; + var objB = filter; + var result = false; + GUILayout.BeginHorizontal(); + //"ToolbarSearchTextFieldPopup" + var rect = GUILayoutUtility.GetRect(GUIContent.none, ToolbarSearchTextFieldPopup, options); + rect.width -= 18f; + var position = rect; + position.width = 20f; + filter = EditorGUI.EnumPopup(position, filter, "label"); + if (!object.Equals(filter, objB)) + { + result = true; + } + + query = EditorGUI.TextField(rect, "", query, ToolbarSearchTextFieldPopup); + if (query != null && !query.Equals(value)) + { + result = true; + } + + var position2 = rect; + position2.x += rect.width; + position2.width = 18f; + if (GUI.Button(position2, "", ToolbarSearchCancelButton)) + { + query = string.Empty; + filter = defaultFilter; + result = true; + GUIUtility.keyboardControl = 0; + } + + GUILayout.EndHorizontal(); + return result; + } + } +} \ No newline at end of file diff --git a/Tools~/Process/Process.Unity/Script/RainbowFolders/Borodar.RainbowFolders.Settings/ProjectRuleDrawer.cs b/Tools~/Process/Process.Unity/Script/RainbowFolders/Borodar.RainbowFolders.Settings/ProjectRuleDrawer.cs index e03d44ed..54c3bf0f 100644 --- a/Tools~/Process/Process.Unity/Script/RainbowFolders/Borodar.RainbowFolders.Settings/ProjectRuleDrawer.cs +++ b/Tools~/Process/Process.Unity/Script/RainbowFolders/Borodar.RainbowFolders.Settings/ProjectRuleDrawer.cs @@ -1,7 +1,6 @@ using System; using AIO.RainbowCore; using UnityEditor; - using UnityEngine; namespace AIO.RainbowFolders.Settings @@ -77,19 +76,14 @@ public SerializedItemWrapper(SerializedProperty property) public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { - if (!property.FindPropertyRelative("IsHidden").boolValue) - { - Rect originalPosition = position; - SerializedItemWrapper item = new SerializedItemWrapper(property); - EditorGUI.BeginChangeCheck(); - DrawLabels(ref position, item); - DrawValues(ref position, originalPosition, item); - DrawPreview(ref position, originalPosition, item); - if (EditorGUI.EndChangeCheck()) - { - property.serializedObject.ApplyModifiedProperties(); - } - } + if (property.FindPropertyRelative("IsHidden").boolValue) return; + var originalPosition = position; + var item = new SerializedItemWrapper(property); + EditorGUI.BeginChangeCheck(); + DrawLabels(ref position, item); + DrawValues(ref position, originalPosition, item); + DrawPreview(ref position, originalPosition, item); + if (EditorGUI.EndChangeCheck()) property.serializedObject.ApplyModifiedProperties(); } public override float GetPropertyHeight(SerializedProperty property, GUIContent label) @@ -98,6 +92,7 @@ public override float GetPropertyHeight(SerializedProperty property, GUIContent { return 0f; } + SerializedProperty serializedProperty = property.FindPropertyRelative("IconType"); SerializedProperty serializedProperty2 = property.FindPropertyRelative("BackgroundType"); bool num = serializedProperty.intValue == 1; @@ -107,10 +102,12 @@ public override float GetPropertyHeight(SerializedProperty property, GUIContent { num2 += 32f; } + if (flag) { num2 += 16f; } + return num2; } @@ -119,8 +116,10 @@ private static void DrawLabels(ref Rect position, SerializedItemWrapper item) position.y += 8f; position.width = 92f; position.height = 16f; - ProjectRule.KeyType keyType = (ProjectRule.KeyType)Enum.GetValues(typeof(ProjectRule.KeyType)).GetValue(item.FolderKeyType.enumValueIndex); - item.FolderKeyType.enumValueIndex = (int)(ProjectRule.KeyType)(object)EditorGUI.EnumPopup(position, keyType); + ProjectRule.KeyType keyType = (ProjectRule.KeyType)Enum.GetValues(typeof(ProjectRule.KeyType)) + .GetValue(item.FolderKeyType.enumValueIndex); + item.FolderKeyType.enumValueIndex = + (int)(ProjectRule.KeyType)(object)EditorGUI.EnumPopup(position, keyType); position.y += 20f; EditorGUI.LabelField(position, "Priority"); position.y += 20f; @@ -132,6 +131,7 @@ private static void DrawLabels(ref Rect position, SerializedItemWrapper item) position.y += 17f; EditorGUI.LabelField(position, "x64"); } + position.y += 17f; EditorGUI.LabelField(position, "Recursive"); position.y += 20f; @@ -141,6 +141,7 @@ private static void DrawLabels(ref Rect position, SerializedItemWrapper item) position.y += 17f; EditorGUI.LabelField(position, "x16"); } + position.y += 17f; EditorGUI.LabelField(position, "Recursive"); } @@ -163,6 +164,7 @@ private static void DrawValues(ref Rect position, Rect originalPosition, Seriali position.y += 17f; EditorGUI.PropertyField(position, item.LargeIcon, GUIContent.none); } + position.y += 16f + (EditorGUIUtility.isProSkin ? 0f : 1f); EditorGUI.PropertyField(position, item.IconRecursive, GUIContent.none); position.y += 20f; @@ -172,6 +174,7 @@ private static void DrawValues(ref Rect position, Rect originalPosition, Seriali position.y += 17f; EditorGUI.PropertyField(position, item.Background, GUIContent.none); } + position.y += 16f + (EditorGUIUtility.isProSkin ? 0f : 1f); EditorGUI.PropertyField(position, item.BackgroundRecursive, GUIContent.none); } @@ -197,17 +200,20 @@ private static void DrawPreview(ref Rect position, Rect originalPosition, Serial } } } - if (texture2D == null) + + if (texture2D is null) { texture2D = ProjectEditorUtility.GetDefaultFolderIcon(); } - if (texture2D2 == null) + + if (texture2D2 is null) { texture2D2 = ProjectEditorUtility.GetDefaultFolderIcon(); } + position.x += position.width + 8f; position.y = originalPosition.y + 32f + 1f + 8f; - float num3 = (position.width = (position.height = 64f)); + var num3 = position.width = position.height = 64f; GUI.DrawTexture(position, texture2D2); position.y += 44f; num3 = (position.width = (position.height = 16f)); @@ -216,12 +222,15 @@ private static void DrawPreview(ref Rect position, Rect originalPosition, Serial position.width = 64f; if (item.HasBackground) { - Texture2D texture2D3 = (item.HasCustomBackground ? ((Texture2D)item.Background.objectReferenceValue) : CoreBackgroundsStorage.GetBackground(item.BackgroundType.intValue)); + Texture2D texture2D3 = (item.HasCustomBackground + ? ((Texture2D)item.Background.objectReferenceValue) + : CoreBackgroundsStorage.GetBackground(item.BackgroundType.intValue)); if (texture2D3 != null) { GUI.DrawTexture(position, texture2D3); } } + position.x += 13f; EditorGUI.LabelField(position, "Folder"); } @@ -238,6 +247,7 @@ private static void DrawIconPopupMenu(Rect rect, SerializedProperty property, bo { obj = "Custom"; } + string text = (string)obj; if (GUI.Button(rect, new GUIContent(text), "MiniPopup")) { @@ -245,7 +255,8 @@ private static void DrawIconPopupMenu(Rect rect, SerializedProperty property, bo } } - private static void DrawBackgroundPopupMenu(Rect rect, SerializedProperty property, bool hasCustomBackground, int backgroundType) + private static void DrawBackgroundPopupMenu(Rect rect, SerializedProperty property, bool hasCustomBackground, + int backgroundType) { object obj; if (!hasCustomBackground) @@ -257,6 +268,7 @@ private static void DrawBackgroundPopupMenu(Rect rect, SerializedProperty proper { obj = "Custom"; } + string text = (string)obj; if (GUI.Button(rect, new GUIContent(text), "MiniPopup")) { @@ -264,4 +276,4 @@ private static void DrawBackgroundPopupMenu(Rect rect, SerializedProperty proper } } } -} +} \ No newline at end of file diff --git a/Tools~/Process/Process.Unity/Script/RainbowFolders/Borodar.RainbowFolders.Settings/ProjectRuleset.cs b/Tools~/Process/Process.Unity/Script/RainbowFolders/Borodar.RainbowFolders.Settings/ProjectRuleset.cs index feda92ed..77799ce0 100644 --- a/Tools~/Process/Process.Unity/Script/RainbowFolders/Borodar.RainbowFolders.Settings/ProjectRuleset.cs +++ b/Tools~/Process/Process.Unity/Script/RainbowFolders/Borodar.RainbowFolders.Settings/ProjectRuleset.cs @@ -1,6 +1,7 @@ using System; using System.Collections; using System.Collections.Generic; +using System.IO; using System.Linq; using AIO.RainbowCore; using UnityEditor; @@ -39,38 +40,30 @@ public static ProjectRuleset Instance { get { - if (_instance is null) + if (!(_instance is null)) return _instance; + try { - try + if (paths is null) { - if (paths is null) - { - paths = new List(); - foreach (var guid in AssetDatabase.FindAssets($"t:{nameof(ProjectRuleset)}", - new string[] { "Packages", "Assets" })) - { - paths.Add(AssetDatabase.GUIDToAssetPath(guid)); - } - } - - foreach (var expr in paths) + paths = new List(); + foreach (var guid in AssetDatabase.FindAssets($"t:{nameof(ProjectRuleset)}", + new string[] { "Packages", "Assets" })) { - _instance = AssetDatabase.LoadAssetAtPath(expr); - if (_instance is null) continue; - _instance.UpdateOrdinals(); - OnRulesetChange = - (Action)Delegate.Combine(OnRulesetChange, new Action(_instance.UpdateOrdinals)); - _instance.UpdateDictionaries(); - OnRulesetChange = - (Action)Delegate.Combine(OnRulesetChange, new Action(_instance.UpdateDictionaries)); - return _instance; + paths.Add(AssetDatabase.GUIDToAssetPath(guid)); } } - catch (Exception e) + + foreach (var expr in paths) { - // ignored + _instance = AssetDatabase.LoadAssetAtPath(expr); + if (_instance is null) continue; + break; } } + catch (Exception) + { + // ignored + } if (_instance is null) { @@ -79,7 +72,7 @@ public static ProjectRuleset Instance _instance = Resources.Load( $"Editor/RainbowFoldersRuleset/{nameof(ProjectRuleset)}"); } - catch (Exception e) + catch (Exception) { // ignored } @@ -87,18 +80,30 @@ public static ProjectRuleset Instance if (_instance is null) { - _instance = CreateInstance(); try { + _instance = CreateInstance(); + var path = Path.Combine(Application.dataPath, "Editor", "Gen", "Settings"); + if (!Directory.Exists(path)) Directory.CreateDirectory(path); AssetDatabase.CreateAsset(_instance, $"Assets/Editor/Gen/Settings/{nameof(ProjectRuleset)}.asset"); } - catch (Exception e) + catch (Exception) { // ignored } } + if (_instance is null) + throw new NullReferenceException( + $"Can't find {nameof(ProjectRuleset)} in project. Please try to reimport Rainbow Folders package."); + + _instance.UpdateOrdinals(); + OnRulesetChange = + (Action)Delegate.Combine(OnRulesetChange, new Action(_instance.UpdateOrdinals)); + _instance.UpdateDictionaries(); + OnRulesetChange = + (Action)Delegate.Combine(OnRulesetChange, new Action(_instance.UpdateDictionaries)); return _instance; } } @@ -261,7 +266,7 @@ public void ChangeRuleBackgroundByPath(string path, CoreBackground background) private void UpdateOrdinals() { - for (int i = 0; i < Rules.Count; i++) + for (var i = 0; i < Rules.Count; i++) { Rules[i].Ordinal = i; } diff --git a/Tools~/Process/Process.Unity/Script/RainbowFolders/Borodar.RainbowFolders.Settings/ProjectRulesetEditor.cs b/Tools~/Process/Process.Unity/Script/RainbowFolders/Borodar.RainbowFolders.Settings/ProjectRulesetEditor.cs index 80340307..de48f894 100644 --- a/Tools~/Process/Process.Unity/Script/RainbowFolders/Borodar.RainbowFolders.Settings/ProjectRulesetEditor.cs +++ b/Tools~/Process/Process.Unity/Script/RainbowFolders/Borodar.RainbowFolders.Settings/ProjectRulesetEditor.cs @@ -59,15 +59,21 @@ protected void OnEnable() pageSize = 10 }; _reorderableList.onChangedCallback += delegate { OnRulesetChange(); }; - Undo.undoRedoPerformed = (Undo.UndoRedoCallback)Delegate.Remove(Undo.undoRedoPerformed, new Undo.UndoRedoCallback(OnRulesetChange)); - Undo.undoRedoPerformed = (Undo.UndoRedoCallback)Delegate.Combine(Undo.undoRedoPerformed, new Undo.UndoRedoCallback(OnRulesetChange)); + Undo.undoRedoPerformed = + (Undo.UndoRedoCallback)Delegate.Remove(Undo.undoRedoPerformed, + new Undo.UndoRedoCallback(OnRulesetChange)); + Undo.undoRedoPerformed = + (Undo.UndoRedoCallback)Delegate.Combine(Undo.undoRedoPerformed, + new Undo.UndoRedoCallback(OnRulesetChange)); } protected void OnDisable() { EDITORS.Remove(this); ClearHiddenFlags(); - Undo.undoRedoPerformed = (Undo.UndoRedoCallback)Delegate.Remove(Undo.undoRedoPerformed, new Undo.UndoRedoCallback(OnRulesetChange)); + Undo.undoRedoPerformed = + (Undo.UndoRedoCallback)Delegate.Remove(Undo.undoRedoPerformed, + new Undo.UndoRedoCallback(OnRulesetChange)); } public override void OnInspectorGUI() @@ -87,7 +93,7 @@ public override void OnInspectorGUI() DrawSearchByKeyPanel(ForceUpdate); break; default: - throw new ArgumentOutOfRangeException("SearchTab", SearchTab, null); + throw new ArgumentOutOfRangeException($"SearchTab", SearchTab, null); } if (!string.IsNullOrEmpty(_warningMessage)) @@ -110,53 +116,49 @@ private static void OnRulesetChange() private void DrawSearchByFolderPanel(bool forceUpdate) { - DefaultAsset asset = Asset; + var asset = Asset; Asset = (DefaultAsset)EditorGUILayout.ObjectField(Asset, typeof(DefaultAsset), false); - if (forceUpdate || !(Asset == asset)) + if (!forceUpdate && Asset == asset) return; + if (Asset is null) { - if (Asset == null) - { - ClearHiddenFlags(); - } - else - { - ApplyHiddenFlagsByAsset(); - } + ClearHiddenFlags(); + } + else + { + ApplyHiddenFlagsByAsset(); } } private void DrawSearchByKeyPanel(bool forceUpdate) { EditorGUILayout.BeginHorizontal(); - bool flag = CoreEditorUtility.SearchField(ref _query, ref _filter, Filter.All); + var flag = CoreEditorUtility.SearchField(ref _query, ref _filter, Filter.All); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); - if (!object.Equals(_filter, Filter.All)) + if (!Equals(_filter, Filter.All)) { - Rect rect = GUILayoutUtility.GetRect(GUIContent.none, "MiniLabel"); + var rect = GUILayoutUtility.GetRect(GUIContent.none, "MiniLabel"); rect.y += 1f; rect.width = 55f; GUI.Label(rect, $"➔ {_filter}", "MiniLabel"); } GUILayout.FlexibleSpace(); - bool matchCase = _matchCase; + var matchCase = _matchCase; _matchCase = EditorGUILayout.ToggleLeft("Match case", _matchCase, "MiniLabel", GUILayout.Width(83f)); - bool flag2 = _matchCase != matchCase; - bool useRegex = _useRegex; + var flag2 = _matchCase != matchCase; + var useRegex = _useRegex; _useRegex = EditorGUILayout.ToggleLeft("Regex", _useRegex, "MiniLabel", GUILayout.Width(58f)); - bool flag3 = _useRegex != useRegex; + var flag3 = _useRegex != useRegex; EditorGUILayout.EndHorizontal(); - if (forceUpdate || flag || flag2 || flag3) - { - _warningMessage = string.Empty; - ApplyFilters(); - } + if (!forceUpdate && !flag && !flag2 && !flag3) return; + _warningMessage = string.Empty; + ApplyFilters(); } private void ApplyFilters() { - bool flag = object.Equals(Filter.All, _filter); + var flag = Equals(Filter.All, _filter); if (string.IsNullOrEmpty(_query) && flag) { ClearHiddenFlags(); @@ -169,34 +171,34 @@ private void ApplyFilters() private void ClearHiddenFlags() { - if (_foldersProperty != null) + if (_foldersProperty is null) return; + for (var i = 0; i < _foldersProperty.arraySize; i++) { - for (int i = 0; i < _foldersProperty.arraySize; i++) - { - _foldersProperty.GetArrayElementAtIndex(i).FindPropertyRelative("IsHidden").boolValue = false; - } - - _foldersProperty.serializedObject.ApplyModifiedProperties(); - _reorderableList.canAdd = true; - _reorderableList.headerHeight = 4f; - _reorderableList.paginate = true; + _foldersProperty.GetArrayElementAtIndex(i).FindPropertyRelative("IsHidden").boolValue = false; } + + _foldersProperty.serializedObject.ApplyModifiedProperties(); + _reorderableList.canAdd = true; + _reorderableList.headerHeight = 4f; + _reorderableList.paginate = true; } private void ApplyHiddenFlagsByAsset() { - string assetPath = AssetDatabase.GetAssetPath(Asset); - string fileName = Path.GetFileName(assetPath); - foreach (ProjectRule rule in ((ProjectRuleset)base.target).Rules) + var assetPath = AssetDatabase.GetAssetPath(Asset); + var fileName = Path.GetFileName(assetPath); + foreach (var rule in ((ProjectRuleset)target).Rules) { bool flag; switch (rule.Type) { case ProjectRule.KeyType.Name: - flag = rule.Key.Equals(fileName) || (rule.IsRecursive() && assetPath.Contains(string.Concat("/", rule.Key, "/"))); + flag = rule.Key.Equals(fileName) || + (rule.IsRecursive() && assetPath.Contains(string.Concat("/", rule.Key, "/"))); break; case ProjectRule.KeyType.Path: - flag = rule.Key.Equals(assetPath) || (rule.IsRecursive() && assetPath.StartsWith(string.Concat(rule.Key, "/"))); + flag = rule.Key.Equals(assetPath) || + (rule.IsRecursive() && assetPath.StartsWith(string.Concat(rule.Key, "/"))); break; default: throw new ArgumentOutOfRangeException(); @@ -212,29 +214,32 @@ private void ApplyHiddenFlagsByAsset() private void ApplyHiddenFlagsByKey() { - Regex regex = (_useRegex ? MakeRegexFromQuery() : null); - for (int i = 0; i < _foldersProperty.arraySize; i++) + var regex = _useRegex ? MakeRegexFromQuery() : null; + for (var i = 0; i < _foldersProperty.arraySize; i++) { - SerializedProperty arrayElementAtIndex = _foldersProperty.GetArrayElementAtIndex(i); - SerializedProperty serializedProperty = arrayElementAtIndex.FindPropertyRelative("IsHidden"); - Enum filter = _filter; - if (filter is Filter) + var arrayElementAtIndex = _foldersProperty.GetArrayElementAtIndex(i); + var serializedProperty = arrayElementAtIndex.FindPropertyRelative("IsHidden"); + if (_filter is Filter filter) { - switch ((Filter)(object)filter) + switch (filter) { case Filter.All: serializedProperty.boolValue = !KeyContainsQuery(arrayElementAtIndex, regex); continue; case Filter.Name: - serializedProperty.boolValue = !KeyHasSameType(arrayElementAtIndex, ProjectRule.KeyType.Name) || !KeyContainsQuery(arrayElementAtIndex, regex); + serializedProperty.boolValue = + !KeyHasSameType(arrayElementAtIndex, ProjectRule.KeyType.Name) || + !KeyContainsQuery(arrayElementAtIndex, regex); continue; case Filter.Path: - serializedProperty.boolValue = !KeyHasSameType(arrayElementAtIndex, ProjectRule.KeyType.Path) || !KeyContainsQuery(arrayElementAtIndex, regex); + serializedProperty.boolValue = + !KeyHasSameType(arrayElementAtIndex, ProjectRule.KeyType.Path) || + !KeyContainsQuery(arrayElementAtIndex, regex); continue; } } - throw new ArgumentOutOfRangeException("_filter", _filter, null); + throw new ArgumentOutOfRangeException($"_filter", _filter, null); } _foldersProperty.serializedObject.ApplyModifiedProperties(); @@ -245,7 +250,7 @@ private void ApplyHiddenFlagsByKey() private Regex MakeRegexFromQuery() { - RegexOptions options = ((!_matchCase) ? RegexOptions.IgnoreCase : RegexOptions.None); + var options = !_matchCase ? RegexOptions.IgnoreCase : RegexOptions.None; try { return new Regex(_query, options); @@ -264,13 +269,13 @@ private static bool KeyHasSameType(SerializedProperty item, ProjectRule.KeyType private bool KeyContainsQuery(SerializedProperty item, Regex regex) { - string stringValue = item.FindPropertyRelative("Key").stringValue; + var stringValue = item.FindPropertyRelative("Key").stringValue; if (_useRegex) { return regex.Match(stringValue).Success; } - StringComparison comparisonType = (_matchCase ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase); + var comparisonType = _matchCase ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase; return stringValue.IndexOf(_query, comparisonType) >= 0; } @@ -278,11 +283,9 @@ private void DrawReorderableList() { EditorGUI.BeginChangeCheck(); _reorderableList.DoLayoutList(); - if (EditorGUI.EndChangeCheck()) - { - ProjectRuleset.OnRulesetChange(); - serializedObject.ApplyModifiedProperties(); - } + if (!EditorGUI.EndChangeCheck()) return; + ProjectRuleset.OnRulesetChange(); + serializedObject.ApplyModifiedProperties(); } } } \ No newline at end of file