Отображение Enum сортированного по алфавиту [РЕШЕНИЕ]

Раздел, посвящённый всему, что связано с программированием для Редактора Юнити. Скрипты Редактора, Wizards и прочее.

Отображение Enum сортированного по алфавиту [РЕШЕНИЕ]

Сообщение Neodrop 08 авг 2014, 19:08

Дружеский подгон сообществу. Драйвер для отображения Enum, сортированного по алфавиту.
Кинуть файл куда угодно, только не в Editor папку.

EnumCustomDrawer.cs


Использование :
Синтаксис:
Используется csharp
        [EnumAlphabeticalSorted]
        public KeyCode keyCode;
 


EnumAlphabetical.jpg


Синтаксис:
Используется csharp
//Created by Neodrop. mailto:neodrop@unity3d.ru

using System;
using System.Collections.Generic;
using UnityEngine;

#if UNITY_EDITOR
using UnityEditor;
#endif

[AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = false)]
public sealed class EnumAlphabeticalSortedAttribute : PropertyAttribute
{

}

#if UNITY_EDITOR
[CustomPropertyDrawer(typeof (EnumAlphabeticalSortedAttribute))]
public class EnumCustomDrawer : PropertyDrawer
{
    private const string StrDelimitter = "/";

    public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
    {
        return property.propertyType != SerializedPropertyType.Enum ? 2 + base.GetPropertyHeight(property, label) * 3 : base.GetPropertyHeight(property, label);
    }

    private void AddDelimitter(GUIContent cnt)
    {
        if (!string.IsNullOrEmpty(cnt.text))
        {
            cnt.text = cnt.text[0].ToString().ToUpper() + StrDelimitter + cnt.text;
        }
    }

    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    {
        if(property.propertyType != SerializedPropertyType.Enum)
        {
            position.height -= base.GetPropertyHeight(property, label) + 2;
            EditorGUI.HelpBox(position, "Use EnumAlphabeticalSortedAttribute for Enum type variables only.", MessageType.Error);
            position.height = base.GetPropertyHeight(property, label);
            position.y += 2 + base.GetPropertyHeight(property, label)*2;
            EditorGUI.PropertyField(position, property, label);
            return;
        }

        List<string> _strs = new List<string>(property.enumNames);
        _strs.Sort();
        string[] enumNames = _strs.ToArray();

        EditorGUI.showMixedValue = property.hasMultipleDifferentValues;
        {
            GUIContent[] contents = new GUIContent[enumNames.Length];
            int contentsCount = contents.Length;
            for (int i = 0; i < contentsCount; i++)
            {
                contents[i] = new GUIContent(enumNames[i]);
                AddDelimitter(contents[i]);
            }

            property.enumValueIndex = EditorGUI.Popup(position, label, property.enumValueIndex, contents);
        }
        EditorGUI.showMixedValue = false;
    }
}
#endif

#endif

 
У вас нет доступа для просмотра вложений в этом сообщении.
Добавить neodrop в Skype
Изображение
"Спасибо!" нашему порталу, вы сможете сказать ЗДЕСЬ.
Если проблема не решается честно, нужно её обмануть! || Per stupiditas at Astra!
Страх порождает слабость. Бесстрашных поражают пули.
Протратившись на блядях байтах, на битах не экономят.
Аватара пользователя
Neodrop
Админ
 
Сообщения: 8480
Зарегистрирован: 08 окт 2008, 15:42
Откуда: Питер
Skype: neodrop
  • Сайт

Re: Отображение Enum сортированного по алфавиту

Сообщение Neodrop 08 авг 2014, 19:31

Подправил алфавитную сортировку.
Добавить neodrop в Skype
Изображение
"Спасибо!" нашему порталу, вы сможете сказать ЗДЕСЬ.
Если проблема не решается честно, нужно её обмануть! || Per stupiditas at Astra!
Страх порождает слабость. Бесстрашных поражают пули.
Протратившись на блядях байтах, на битах не экономят.
Аватара пользователя
Neodrop
Админ
 
Сообщения: 8480
Зарегистрирован: 08 окт 2008, 15:42
Откуда: Питер
Skype: neodrop
  • Сайт

Re: Отображение Enum сортированного по алфавиту [РЕШЕНИЕ]

Сообщение BlackMamba 08 авг 2014, 21:58

(3A4OT)
просто и полезно
mail: _gdeMoiGusi@gmail.com
skype: Ellseworth
Аватара пользователя
BlackMamba
UNITрон
 
Сообщения: 305
Зарегистрирован: 06 янв 2011, 16:16
Откуда: Москва

Re: Отображение Enum сортированного по алфавиту [РЕШЕНИЕ]

Сообщение AShim3D 11 авг 2014, 14:03

Спасибо, годная вещь.
Только почему-то у меня неправильные значения присваивает (не те, что в редакторе отображаются).

Можно слегка модифицировать и справить эту неприятность:
Синтаксис:
Используется csharp
// Created by Neodrop. mailto:neodrop@unity3d.ru
// Added AllowMultiple by AShim. mailto:ashim.3d@gmail.com

using System;
using System.Collections.Generic;
using UnityEngine;

#if UNITY_EDITOR
using System.Linq;
using UnityEditor;
#endif

[AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = false)]
public sealed class EnumAlphabeticalSortedAttribute: PropertyAttribute {
       
        public bool ShowDelimitter = true;
        public System.Type Type;
       
} // class EnumAlphabeticalSortedAttribute

#if UNITY_EDITOR
[CustomPropertyDrawer(typeof (EnumAlphabeticalSortedAttribute))]
public class EnumCustomDrawer: PropertyDrawer {
       
        private class NameValue {
                public string name;
                public int value;
                public int fakeIndex;
        } // class NameValue
       
        bool showDelimitter {
                get {
                        return ((EnumAlphabeticalSortedAttribute)attribute).ShowDelimitter;
                }
        } // showDelimitter
       
        Type type {
                get {
                        return ((EnumAlphabeticalSortedAttribute)attribute).Type;
                }
        } // type
       
        private const string StrDelimitter = "/";
       
        public override float GetPropertyHeight(SerializedProperty property, GUIContent label) {
                return property.propertyType != SerializedPropertyType.Enum ? 2 + base.GetPropertyHeight(property, label) * 3 : base.GetPropertyHeight(property, label);
        } // GetPropertyHeight()
       
        private void AddDelimitter(GUIContent cnt) {
                if (!string.IsNullOrEmpty(cnt.text)) {
                        cnt.text = cnt.text[0].ToString().ToUpper() + StrDelimitter + cnt.text;
                }
        } // AddDelimitter()
       
        public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) {
                if(property.propertyType != SerializedPropertyType.Enum) {
                        position.height -= base.GetPropertyHeight(property, label) + 2;
                        EditorGUI.HelpBox(position, "Use EnumAlphabeticalSortedAttribute for Enum type variables only.", MessageType.Error);
                        position.height = base.GetPropertyHeight(property, label);
                        position.y += 2 + base.GetPropertyHeight(property, label)*2;
                        EditorGUI.PropertyField(position, property, label);
                        return;
                }
                int fakeIndex = 0;
                List<NameValue> nameValues = new List<NameValue>(
                        from x
                        in property.enumNames
                        select new NameValue {
                                name = x,
                                value = (int)(Enum.Parse(type, x)),
                                fakeIndex = fakeIndex++
                        }
                );
                nameValues.Sort((x, y) => x.name.CompareTo(y.name));
                int[] optionValues = new int[nameValues.Count];
                EditorGUI.showMixedValue = property.hasMultipleDifferentValues;
                GUIContent[] contents = new GUIContent[nameValues.Count];
                int contentsCount = contents.Length;
                for (int i = 0; i < contentsCount; i++) {
                        contents[i] = new GUIContent(nameValues[i].name);
                        optionValues[i] = nameValues[i].value;
                        if (showDelimitter) {
                                AddDelimitter(contents[i]);
                        }
                }
                int index = nameValues.IndexOf(nameValues.Find((x) => x.fakeIndex == property.enumValueIndex));
                bool gui_changed = GUI.changed;
                GUI.changed = false;
                int newIndex = EditorGUI.IntPopup(position, label, nameValues.Find((x) => x.fakeIndex == property.enumValueIndex).value, contents, optionValues);
                if (GUI.changed) {
                        property.enumValueIndex = nameValues.Find((x) => x.value == newIndex).fakeIndex;
                } else {
                        GUI.changed = gui_changed;
                }
                EditorGUI.showMixedValue = false;
        } // OnGUI()
       
} // class EnumCustomDrawer
#endif
 


Использование:
Синтаксис:
Используется csharp
[EnumAlphabeticalSorted(ShowDelimitter = true, Type = typeof(KeyCode))]
public KeyCode keyCode;
 

ShowDelimitter - указывает надо ли группировать по буквам.
Type - тип поля.
Плюс: поддержка различных значений поля для группового выделения.
AShim3D
UNец
 
Сообщения: 2
Зарегистрирован: 01 окт 2012, 14:31

Re: Отображение Enum сортированного по алфавиту [РЕШЕНИЕ]

Сообщение Neodrop 12 авг 2014, 20:33

Ну, я ожидал возможного глюка с не теми значениями, но почему то у меня работало нормально ;)
Тем не менее, спасибо за правку, раз уж она понадобилась. \m/
Добавить neodrop в Skype
Изображение
"Спасибо!" нашему порталу, вы сможете сказать ЗДЕСЬ.
Если проблема не решается честно, нужно её обмануть! || Per stupiditas at Astra!
Страх порождает слабость. Бесстрашных поражают пули.
Протратившись на блядях байтах, на битах не экономят.
Аватара пользователя
Neodrop
Админ
 
Сообщения: 8480
Зарегистрирован: 08 окт 2008, 15:42
Откуда: Питер
Skype: neodrop
  • Сайт

Re: Отображение Enum сортированного по алфавиту [РЕШЕНИЕ]

Сообщение Paul Siberdt 12 авг 2014, 22:15

Охеренно, спасибо. :)
Аватара пользователя
Paul Siberdt
Адепт
 
Сообщения: 5317
Зарегистрирован: 20 июн 2009, 21:24
Откуда: Moscow, Russia
Skype: siberdt
  • Сайт

Re: Отображение Enum сортированного по алфавиту [РЕШЕНИЕ]

Сообщение Neodrop 12 мар 2015, 13:09

Новый подправленный вариант :

Синтаксис:
Используется csharp

// Created by Neodrop. mailto:neodrop@unity3d.ru
// Added AllowMultiple by AShim. mailto:ashim.3d@gmail.com

using System;
using System.Collections.Generic;
using UnityEngine;

#if UNITY_EDITOR
using System.Linq;
using UnityEditor;
#endif

[AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = false)]
public sealed class EnumAlphabeticalSortedAttribute : PropertyAttribute
{

    public bool ShowDelimitter = true;
    public System.Type Type;

    public EnumAlphabeticalSortedAttribute(Type enumType, bool showDelimitter = true)
    {
        this.ShowDelimitter = showDelimitter;
        Type = enumType;
    }

} // class EnumAlphabeticalSortedAttribute

#if UNITY_EDITOR
[CustomPropertyDrawer(typeof(EnumAlphabeticalSortedAttribute))]
public class EnumCustomDrawer : PropertyDrawer
{

    private class NameValue
    {
        public string name;
        public int value;
        public int fakeIndex;
    } // class NameValue

    bool showDelimitter
    {
        get
        {
            return ((EnumAlphabeticalSortedAttribute)attribute).ShowDelimitter;
        }
    } // showDelimitter

    Type type
    {
        get
        {
            return ((EnumAlphabeticalSortedAttribute)attribute).Type;
        }
    } // type

    private const string StrDelimitter = "/";

    public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
    {
        return property.propertyType != SerializedPropertyType.Enum ? 2 + base.GetPropertyHeight(property, label) * 3 : base.GetPropertyHeight(property, label);
    } // GetPropertyHeight()

    private void AddDelimitter(GUIContent cnt)
    {
        if (!string.IsNullOrEmpty(cnt.text))
        {
            cnt.text = cnt.text[0].ToString().ToUpper() + StrDelimitter + cnt.text;
        }
    } // AddDelimitter()

    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    {
        if (property.propertyType != SerializedPropertyType.Enum)
        {
            position.height -= base.GetPropertyHeight(property, label) + 2;
            EditorGUI.HelpBox(position, "Use EnumAlphabeticalSortedAttribute for Enum type variables only.", MessageType.Error);
            position.height = base.GetPropertyHeight(property, label);
            position.y += 2 + base.GetPropertyHeight(property, label) * 2;
            EditorGUI.PropertyField(position, property, label);
            return;
        }
        int fakeIndex = 0;
        List<NameValue> nameValues = new List<NameValue>(
                from x
                in property.enumNames
                select new NameValue
                {
                    name = x,
                    value = (int)(Enum.Parse(type, x)),
                    fakeIndex = fakeIndex++
                }
        );
        nameValues.Sort((x, y) => x.name.CompareTo(y.name));
        int[] optionValues = new int[nameValues.Count];
        EditorGUI.showMixedValue = property.hasMultipleDifferentValues;
        GUIContent[] contents = new GUIContent[nameValues.Count];
        int contentsCount = contents.Length;
        for (int i = 0; i < contentsCount; i++)
        {
            contents[i] = new GUIContent(nameValues[i].name);
            optionValues[i] = nameValues[i].value;
            if (showDelimitter)
            {
                AddDelimitter(contents[i]);
            }
        }
        int index = nameValues.IndexOf(nameValues.Find((x) => x.fakeIndex == property.enumValueIndex));
        bool gui_changed = GUI.changed;
        GUI.changed = false;
        int newIndex = EditorGUI.IntPopup(position, label, nameValues.Find((x) => x.fakeIndex == property.enumValueIndex).value, contents, optionValues);
        if (GUI.changed)
        {
            property.enumValueIndex = nameValues.Find((x) => x.value == newIndex).fakeIndex;
        }
        else
        {
            GUI.changed = gui_changed;
        }
        EditorGUI.showMixedValue = false;
    } // OnGUI()

} // class EnumCustomDrawer
#endif

 


Изменился конструктор атрибута. Теперь так :

Синтаксис:
Используется csharp
[EnumAlphabeticalSorted(typeof(KeyCode))]
public KeyCode keyCode;
 
Добавить neodrop в Skype
Изображение
"Спасибо!" нашему порталу, вы сможете сказать ЗДЕСЬ.
Если проблема не решается честно, нужно её обмануть! || Per stupiditas at Astra!
Страх порождает слабость. Бесстрашных поражают пули.
Протратившись на блядях байтах, на битах не экономят.
Аватара пользователя
Neodrop
Админ
 
Сообщения: 8480
Зарегистрирован: 08 окт 2008, 15:42
Откуда: Питер
Skype: neodrop
  • Сайт

Re: Отображение Enum сортированного по алфавиту [РЕШЕНИЕ]

Сообщение KingPeas 26 мар 2015, 07:54

Neodrop писал(а):Новый подправленный вариант : ...


Коллега позволите ваш вариант Enum добавить в свою коллекцию PropertyDrawer?
Хочу IQ как ICQ, ну или хотя бы ICQ как IQ...
Мой первый плагин PropertyDrawerCollection
Аватара пользователя
KingPeas
UNIт
 
Сообщения: 78
Зарегистрирован: 12 сен 2012, 12:34
Откуда: Новосибирск
Skype: evgeniygurlev
  • Сайт
  • ICQ


Вернуться в Editor

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2