| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408 | using System;using System.Collections;using System.Collections.Generic;using System.Linq;using System.Text;using UnityEditor;using UnityEditorInternal;using UnityEngine;using Random = UnityEngine.Random;namespace EnhancedHierarchy {    public static partial class Preferences {        public const string DEVELOPER_EMAIL = "samuelschultze@gmail.com";        public static Action onResetPreferences = new Action(() => { });        public static readonly List<GUIContent> contents = new List<GUIContent>();        public static readonly Version pluginVersion = new Version(2, 4, 5);        public static readonly DateTime pluginDate = new DateTime(2020, 05, 04);        private static readonly GUIContent resetSettingsContent = new GUIContent("Use Defaults", "Reset all settings to default");        private static readonly GUIContent unlockAllContent = new GUIContent("Unlock All Objects", "Unlock all objects in the current scene, it's highly recommended to do this when disabling or removing the extension to prevent data loss\nThis might take a few seconds on large scenes");        private static readonly GUIContent mailDeveloperContent = new GUIContent("Support Email", "Request support from the developer\n\n" + DEVELOPER_EMAIL);        private static readonly GUIContent versionContent = new GUIContent(string.Format("Version: {0} ({1:d})", pluginVersion, pluginDate));        private static Vector2 scroll;        private static ReorderableList leftIconsList, rightIconsList, rowColorsList;        private static readonly string[] minilabelsNames;        private static GenericMenu LeftIconsMenu { get { return GetGenericMenuForIcons(LeftIcons, IconBase.AllLeftIcons); } }        private static GenericMenu RightIconsMenu { get { return GetGenericMenuForIcons(RightIcons, IconBase.AllRightIcons); } }        private static GenericMenu RowColorsMenu {            get {                var menu = new GenericMenu();                var randomColor = Random.ColorHSV(0f, 1f, 0.5f, 1f, 1f, 1f);                randomColor.a = 0.3019608f;                for (var i = 0; i < 32; i++) {                    if (PerLayerRowColors.Value.Contains(new LayerColor(i)))                        continue;                    var mode = PerLayerRowColors.Value.LastOrDefault().mode;                    var layerName = LayerMask.LayerToName(i);                    var layer = new LayerColor(i, randomColor, mode);                    if (string.IsNullOrEmpty(layerName))                        layerName = string.Format("Layer: {0}", i);                    menu.AddItem(new GUIContent(layerName), false, () => {                        rowColorsList.list.Add(layer);                        PerLayerRowColors.ForceSave();                    });                }                return menu;            }        }        private static GenericMenu GetGenericMenuForIcons<T>(PrefItem<T> preferenceItem, IconBase[] icons)where T : IList {            var menu = new GenericMenu();            foreach (var i in icons) {                var icon = i;                if (!preferenceItem.Value.Contains(icon) && icon != IconBase.none && icon != IconBase.none)                    menu.AddItem(new GUIContent(icon.Name), false, () => {                        preferenceItem.Value.Add(icon);                        preferenceItem.ForceSave();                    });            }            return menu;        }        private static ReorderableList GenerateReordableList<T>(PrefItem<T> preferenceItem)where T : IList {            var result = new ReorderableList(preferenceItem.Value, typeof(T), true, true, true, true);            result.elementHeight = 18f;            result.drawHeaderCallback = rect => { rect.xMin -= EditorGUI.indentLevel * 16f; EditorGUI.LabelField(rect, preferenceItem, EditorStyles.boldLabel); };            result.onChangedCallback += list => preferenceItem.ForceSave();            result.drawElementCallback = (rect, index, focused, active) => {                var icon = result.list[index] as IconBase;                if (icon == null) {                    EditorGUI.LabelField(rect, "INVALID ICON");                    return;                }                var content = Utility.GetTempGUIContent(icon.Name, icon.PreferencesTooltip, icon.PreferencesPreview);                var whiteTexture = content.image ? content.image.name.Contains("eh_icon_white") : true;                using(new GUIColor((whiteTexture && !EditorGUIUtility.isProSkin) ? Styles.backgroundColorEnabled : Color.white))                EditorGUI.LabelField(rect, content);            };            onResetPreferences += () => result.list = preferenceItem.Value;            return result;        }        #if UNITY_2018_3_OR_NEWER        [SettingsProvider]        private static SettingsProvider RetrieveSettingsProvider() {            var settingsProvider = new SettingsProvider("Preferences/Enhanced Hierarchy", SettingsScope.User, contents.Select(c => c.text));            settingsProvider.guiHandler = new Action<string>((str) => OnPreferencesGUI(str));            return settingsProvider;        }        #else        [PreferenceItem("Hierarchy")]        private static void OnPreferencesGUI() {            OnPreferencesGUI(string.Empty);        }        #endif        private static void OnPreferencesGUI(string search) {            scroll = EditorGUILayout.BeginScrollView(scroll, false, false);            EditorGUILayout.Separator();            Enabled.DoGUI();            EditorGUILayout.Separator();            EditorGUILayout.HelpBox("Each item has a tooltip explaining what it does, keep the mouse over it to see.", MessageType.Info);            EditorGUILayout.Separator();            using(Enabled.GetEnabledScope()) {                using(new GUIIndent("Misc settings")) {                    using(new GUIIndent("Margins")) {                        RightMargin.DoGUISlider(-50, 50);                        using(new GUIEnabled(Reflected.HierarchyArea.Supported)) {                            LeftMargin.DoGUISlider(-50, 50);                            Indent.DoGUISlider(0, 35);                        }                        if (!Reflected.HierarchyArea.Supported)                            EditorGUILayout.HelpBox("Custom Indent and Margins are not supported in this Unity version", MessageType.Warning);                    }                    IconsSize.DoGUISlider(13, 23);                    TreeOpacity.DoGUISlider(0f, 1f);                    using(new GUIIndent()) {                        using(SelectOnTree.GetFadeScope(TreeOpacity.Value > 0.01f))                        SelectOnTree.DoGUI();                        using(TreeStemProportion.GetFadeScope(TreeOpacity.Value > 0.01f))                        TreeStemProportion.DoGUISlider(0f, 1f);                    }                    Tooltips.DoGUI();                    using(new GUIIndent())                    using(RelevantTooltipsOnly.GetFadeScope(Tooltips))                    RelevantTooltipsOnly.DoGUI();                    if (EnhancedSelectionSupported)                        EnhancedSelection.DoGUI();                    Trailing.DoGUI();                    ChangeAllSelected.DoGUI();                    NumericChildExpand.DoGUI();                    using(new GUIEnabled(Reflected.IconWidthSupported))                    DisableNativeIcon.DoGUI();                    using(HideDefaultIcon.GetFadeScope(IsButtonEnabled(new Icons.GameObjectIcon())))                    HideDefaultIcon.DoGUI();                    using(OpenScriptsOfLogs.GetFadeScope(IsButtonEnabled(new Icons.Warnings())))                    OpenScriptsOfLogs.DoGUI();                    GUI.changed = false;                    using(AllowSelectingLockedObjects.GetFadeScope(IsButtonEnabled(new Icons.Lock())))                    AllowSelectingLockedObjects.DoGUI();                    #if !UNITY_2019_3_OR_NEWER                    using(new GUIEnabled(false))                    #endif                    using(AllowPickingLockedObjects.GetFadeScope(IsButtonEnabled(new Icons.Lock())))                    AllowPickingLockedObjects.DoGUI();                    HoverTintColor.DoGUI();                }                using(new GUIIndent("Row separators")) {                    LineSize.DoGUISlider(0, 6);                    using(LineColor.GetFadeScope(LineSize > 0))                    LineColor.DoGUI();                    OddRowColor.DoGUI();                    EvenRowColor.DoGUI();                    GUI.changed = false;                    var rect = EditorGUILayout.GetControlRect(false, rowColorsList.GetHeight());                    rect.xMin += EditorGUI.indentLevel * 16f;                    rowColorsList.DoList(rect);                }                GUI.changed = false;                MiniLabels.Value[0] = EditorGUILayout.Popup("Mini Label Top", MiniLabels.Value[0], minilabelsNames);                MiniLabels.Value[1] = EditorGUILayout.Popup("Mini Label Bottom", MiniLabels.Value[1], minilabelsNames);                if (GUI.changed) {                    MiniLabels.ForceSave();                    RecreateMiniLabelProviders();                }                // MiniLabel.DoGUI();                using(new GUIIndent()) {                    using(SmallerMiniLabel.GetFadeScope(miniLabelProviders.Length > 0))                    SmallerMiniLabel.DoGUI();                    using(HideDefaultTag.GetFadeScope(MiniLabelTagEnabled))                    HideDefaultTag.DoGUI();                    using(HideDefaultLayer.GetFadeScope(MiniLabelLayerEnabled))                    HideDefaultLayer.DoGUI();                    using(CentralizeMiniLabelWhenPossible.GetFadeScope(miniLabelProviders.Length >= 2))                    CentralizeMiniLabelWhenPossible.DoGUI();                }                LeftSideButtonPref.DoGUI();                using(new GUIIndent())                using(LeftmostButton.GetFadeScope(LeftSideButton != IconBase.none))                LeftmostButton.DoGUI();                using(new GUIIndent("Children behaviour on change")) {                    using(LockAskMode.GetFadeScope(IsButtonEnabled(new Icons.Lock())))                    LockAskMode.DoGUI();                    using(LayerAskMode.GetFadeScope(IsButtonEnabled(new Icons.Layer()) || MiniLabelLayerEnabled))                    LayerAskMode.DoGUI();                    using(TagAskMode.GetFadeScope(IsButtonEnabled(new Icons.Tag()) || MiniLabelTagEnabled))                    TagAskMode.DoGUI();                    using(StaticAskMode.GetFadeScope(IsButtonEnabled(new Icons.Static())))                    StaticAskMode.DoGUI();                    using(IconAskMode.GetFadeScope(IsButtonEnabled(new Icons.GameObjectIcon())))                    IconAskMode.DoGUI();                    EditorGUILayout.HelpBox(string.Format("Pressing down {0} while clicking on a button will make it temporary have the opposite children change mode", Utility.CtrlKey), MessageType.Info);                }                leftIconsList.displayAdd = LeftIconsMenu.GetItemCount() > 0;                leftIconsList.DoLayoutList();                rightIconsList.displayAdd = RightIconsMenu.GetItemCount() > 0;                rightIconsList.DoLayoutList();                EditorGUILayout.HelpBox("Alt + Click on child expand toggle makes it expand all the grandchildren too", MessageType.Info);                if (IsButtonEnabled(new Icons.Memory()))                    EditorGUILayout.HelpBox("\"Memory Used\" may create garbage and consequently framerate stutterings, leave it disabled if maximum performance is important for your project", MessageType.Warning);                if (IsButtonEnabled(new Icons.Lock()))                    EditorGUILayout.HelpBox("Remember to always unlock your game objects when removing or disabling this extension, as you won't be able to unlock without it and may lose scene data", MessageType.Warning);                GUI.enabled = true;                EditorGUILayout.EndScrollView();                using(new EditorGUILayout.HorizontalScope()) {                    GUILayout.FlexibleSpace();                    EditorGUILayout.LabelField(versionContent, GUILayout.Width(170f));                }                using(new EditorGUILayout.HorizontalScope()) {                    if (GUILayout.Button(resetSettingsContent, GUILayout.Width(120f)))                        onResetPreferences();                    // if (GUILayout.Button(unlockAllContent, GUILayout.Width(120f)))                    //     Utility.UnlockAllObjects();                    if (GUILayout.Button(mailDeveloperContent, GUILayout.Width(120f)))                        OpenSupportEmail();                }                EditorGUILayout.Separator();                Styles.ReloadTooltips();                EditorApplication.RepaintHierarchyWindow();            }        }        public static void OpenSupportEmail(Exception e = null) {            Application.OpenURL(GetEmailURL(e));        }        private static string GetEmailURL(Exception e) {            var full = new StringBuilder();            var body = new StringBuilder();            #if UNITY_2018_1_OR_NEWER            Func<string, string> EscapeURL = url => { return UnityEngine.Networking.UnityWebRequest.EscapeURL(url).Replace("+", "%20"); };            #else            Func<string, string> EscapeURL = url => { return WWW.EscapeURL(url).Replace("+", "%20"); };            #endif            body.Append(EscapeURL("\r\nDescribe your problem or make your request here\r\n"));            body.Append(EscapeURL("\r\nAdditional Information:"));            body.Append(EscapeURL("\r\nVersion: " + pluginVersion.ToString(3)));            body.Append(EscapeURL("\r\nUnity " + InternalEditorUtility.GetFullUnityVersion()));            body.Append(EscapeURL("\r\n" + SystemInfo.operatingSystem));            if (e != null)                body.Append(EscapeURL("\r\n" + e));            full.Append("mailto:");            full.Append(DEVELOPER_EMAIL);            full.Append("?subject=");            full.Append(EscapeURL("Enhanced Hierarchy - Support"));            full.Append("&body=");            full.Append(body);            return full.ToString();        }        private static LayerColor LayerColorField(Rect rect, LayerColor layerColor) {            var value = layerColor;            var rect1 = rect;            var rect2 = rect;            var rect3 = rect;            var rect4 = rect;            rect1.xMax = rect1.xMin + 175f;            rect2.xMin = rect1.xMax;            rect2.xMax = rect2.xMin + 80f;            rect3.xMin = rect2.xMax;            rect3.xMax = rect3.xMin + 100;            rect4.xMin = rect3.xMax;            value.layer = EditorGUI.LayerField(rect1, value.layer);            value.layer = EditorGUI.DelayedIntField(rect2, value.layer);            value.color = EditorGUI.ColorField(rect3, value.color);            value.mode = (TintMode)EditorGUI.EnumPopup(rect4, value.mode);            if (value.layer > 31 || value.layer < 0)                return layerColor;            return value;        }        private static void DoGUI(this PrefItem<int> prefItem) {            if (prefItem.Drawing)                prefItem.Value = EditorGUILayout.IntField(prefItem, prefItem);        }        private static void DoGUI(this PrefItem<float> prefItem) {            if (prefItem.Drawing)                prefItem.Value = EditorGUILayout.FloatField(prefItem, prefItem);        }        private static void DoGUISlider(this PrefItem<int> prefItem, int min, int max) {            if (prefItem.Drawing)                prefItem.Value = EditorGUILayout.IntSlider(prefItem, prefItem, min, max);        }        private static void DoGUISlider(this PrefItem<float> prefItem, float min, float max) {            if (prefItem.Drawing)                prefItem.Value = EditorGUILayout.Slider(prefItem, prefItem, min, max);        }        private static void DoGUI(this PrefItem<bool> prefItem) {            if (prefItem.Drawing)                prefItem.Value = EditorGUILayout.Toggle(prefItem, prefItem);        }        private static void DoGUI(this PrefItem<string> prefItem) {            if (prefItem.Drawing)                prefItem.Value = EditorGUILayout.TextField(prefItem.Label, prefItem);        }        private static void DoGUI(this PrefItem<Color> prefItem) {            if (prefItem.Drawing)                prefItem.Value = EditorGUILayout.ColorField(prefItem, prefItem);        }        private static void DoGUI<T>(this PrefItem<T> prefItem)where T : struct, IConvertible {            if (prefItem.Drawing)                prefItem.Value = (T)(object)EditorGUILayout.EnumPopup(prefItem, (Enum)(object)prefItem.Value);        }        private static void DoGUI(this PrefItem<IconData> prefItem) {            if (!prefItem.Drawing)                return;            var icons = IconBase.AllLeftOfNameIcons;            var index = Array.IndexOf(icons, prefItem.Value.Icon);            var labels = (from icon in icons select new GUIContent(icon)).ToArray();            index = EditorGUILayout.Popup(prefItem, index, labels);            if (index < 0 || index >= icons.Length)                return;            if (prefItem.Value.Icon.Name == icons[index].Name)                return;            prefItem.Value.Icon = icons[index];            prefItem.ForceSave();        }    }}
 |