Unity3D Пользовательский редактор изменения фокуса с EditorGUILayout.LabelField - PullRequest
0 голосов
/ 26 октября 2019

У меня проблема с пользовательским редактором, мой фокус редактирования изменяется без каких-либо действий с моей стороны. По сути, это экран моего пользовательского редактора в нейтральном состоянии (только что добавлена ​​пустая сущность перевода):

enter image description here

И это экран, когда мойфокус получил изменение без причины. Как вы можете видеть, мой редактор обнаружил, что 2 клавиши были одинаковыми, и уведомил об этом сообщением в верхней части окна, проблема в том, что я фактически редактировал поле «ключ» во втором блоке, и мой фокус изменился на первомкоробка (выделена синим цветом). Если я не отображаю предупреждающее сообщение, у меня нет проблем, поэтому я думаю, что оно оттуда исходит ..

enter image description here

Это моеСкрипт специального редактора:

    [CustomEditor(typeof(InternationalizationDatabaseSO))]
    public class InternationalizationDatabaseSOEditor : Editor
    {
        #region Constantes
        private const string ITEMS_PROPERTY_NAME = "_mItems";

        private const string ITEM_CATEGORY_NAME = "_mCategory";
        private const string ITEM_KEY_NAME = "_mKey";
        private const string ITEM_VALUES_NAME = "_mValues";

        private const string ITEM_VALUE_LANGUAGE = "_mLanguage";
        private const string ITEM_VALUE_VALUE = "_mValue";
        #endregion

        #region Attributs
        private InternationalizationDatabaseSO _mDatabase;
        #endregion

        #region Methods
        private void OnEnable()
        {
            Init();
        }

        private void Init()
        {
            _mDatabase = target as InternationalizationDatabaseSO;
        }

        public override void OnInspectorGUI()
        {
            serializedObject.Update();

            SerializedProperty itemsProperty = serializedObject.FindProperty(ITEMS_PROPERTY_NAME);

            int arraySize = itemsProperty.arraySize;

            EditorGUI.BeginDisabledGroup(false);
            {
                EditorGUILayout.BeginHorizontal();
                {
                    GUILayout.FlexibleSpace();
                    if (OnInspectorGUIButton("+", 40, 25, Color.white, Color.green))
                    {
                        itemsProperty.arraySize++;
                        itemsProperty.GetArrayElementAtIndex(itemsProperty.arraySize - 1).FindPropertyRelative(ITEM_CATEGORY_NAME).stringValue = "";
                        itemsProperty.GetArrayElementAtIndex(itemsProperty.arraySize - 1).FindPropertyRelative(ITEM_KEY_NAME).stringValue = "";
                        serializedObject.ApplyModifiedProperties();
                        Init();
                        return;
                    }
                }
                EditorGUILayout.EndHorizontal();
                EditorGUILayout.Space();

                for(int i = 0; i < arraySize; i++)
                {
                    if(OnInspectorGUIItem(i) == false)
                    {
                        serializedObject.ApplyModifiedProperties();
                        Init();
                        return;
                    }
                }
            }

            EditorGUI.EndDisabledGroup();
            serializedObject.ApplyModifiedProperties();
        }

        private bool OnInspectorGUIItem(int index)
        {
            SerializedProperty itemsProperty = serializedObject.FindProperty(ITEMS_PROPERTY_NAME);

            SerializedProperty itemCategory = itemsProperty.GetArrayElementAtIndex(index).FindPropertyRelative(ITEM_CATEGORY_NAME);
            SerializedProperty itemKey = itemsProperty.GetArrayElementAtIndex(index).FindPropertyRelative(ITEM_KEY_NAME);

            EditorGUI.indentLevel += 1;

            EditorGUILayout.BeginVertical(GUI.skin.box);
            {
                EditorGUILayout.Space();
                EditorGUILayout.BeginHorizontal();
                {
                    EditorGUILayout.BeginVertical();
                    {
                        if(KeyAlreadyExist(index, itemKey.stringValue))
                        {
                            OnInspectorGUIText("Key already exists", 12, Color.red, FontStyle.Bold, false);
                        }
                        OnInspectorGUIText("Key : " + itemKey.stringValue, 12, FontStyle.Normal, false);
                    }
                    EditorGUILayout.EndVertical();

                    GUILayout.FlexibleSpace();
                    if(OnInspectorGUIButton("-", 40, 25, Color.white, Color.red))
                    {
                        itemCategory.stringValue = "";
                        itemKey.stringValue = "";
                        itemsProperty.DeleteArrayElementAtIndex(index);
                        return false;
                    }
                }
                EditorGUILayout.EndHorizontal();

                EditorGUILayout.Space();

                EditorGUILayout.BeginVertical();
                {
                    GUIStyle style = EditorStyles.foldout;
                    style.fontSize = 15;
                    style.fontStyle = FontStyle.Bold;


                    itemCategory.isExpanded = EditorGUILayout.Foldout(itemCategory.isExpanded, "General informations", style);
                    if(itemCategory.isExpanded)
                    {
                        EditorGUILayout.Space();
                        EditorGUILayout.PropertyField(itemCategory, new GUIContent("Category"));
                        EditorGUILayout.PropertyField(itemKey, new GUIContent("Key"));
                    }

                    if(OnInspectorGUIItemLanguage(index, itemsProperty.GetArrayElementAtIndex(index)) == false)
                    {
                        return false;
                    }
                }
                EditorGUILayout.EndVertical();
            }
            EditorGUILayout.EndVertical();
            EditorGUI.indentLevel -= 1;
            return true;
        }

        private bool OnInspectorGUIItemLanguage(int index, SerializedProperty propertyItem)
        {
            EditorGUILayout.BeginVertical();
            {
                GUIStyle style = EditorStyles.foldout;
                style.fontSize = 15;
                style.normal.textColor = Color.black;
                style.fontStyle = FontStyle.Bold;

                SerializedProperty itemValues = propertyItem.FindPropertyRelative(ITEM_VALUES_NAME);
                itemValues.isExpanded = EditorGUILayout.Foldout(itemValues.isExpanded, "Languages informations", style);
                if(itemValues.isExpanded)
                {
                    EditorGUILayout.Space();
                    EditorGUILayout.BeginVertical();
                    {
                        EditorGUILayout.BeginHorizontal();
                        {
                            int nbTranslation = itemValues.arraySize;
                            EditorGUILayout.LabelField("Nb translation : " + nbTranslation);
                            GUILayout.FlexibleSpace();
                            if (OnInspectorGUIButton("+", 20, 20, Color.white, Color.green))
                            {
                                itemValues.arraySize++;
                                itemValues.GetArrayElementAtIndex(itemValues.arraySize - 1).FindPropertyRelative(ITEM_VALUE_LANGUAGE).intValue = 0;
                                itemValues.GetArrayElementAtIndex(itemValues.arraySize - 1).FindPropertyRelative(ITEM_VALUE_VALUE).stringValue = "";
                                return false;
                            }
                        }
                        EditorGUILayout.EndHorizontal();
                        EditorGUILayout.Space();  
                        if (itemValues.arraySize > 0)
                        {
                            string translatedLanguages = "{";
                            foreach (InternationalizationDatabaseItemLanguage item in _mDatabase.Items[index].Values)
                            {
                                translatedLanguages += item.Language.ToString() + ", ";
                            }
                            if (translatedLanguages.Length > 2)
                            {
                                translatedLanguages = translatedLanguages.Remove(translatedLanguages.Length - 2);
                            }
                            translatedLanguages += "}";

                            //EditorStyles.label.stretchHeight = true;
                            EditorStyles.label.wordWrap = true;
                            EditorGUILayout.LabelField("Translated : \n" + translatedLanguages);
                            EditorGUILayout.Space();

                            for (int i = 0; i < itemValues.arraySize; i++)
                            {
                                EditorGUILayout.BeginVertical(GUI.skin.box);
                                {
                                    EditorGUILayout.Space();
                                    InternationalizationDatabaseItemLanguage item = _mDatabase.Items[index].Values[i];
                                    SerializedProperty propLanguage = itemValues.GetArrayElementAtIndex(i).FindPropertyRelative(ITEM_VALUE_LANGUAGE);
                                    SerializedProperty propValue = itemValues.GetArrayElementAtIndex(i).FindPropertyRelative(ITEM_VALUE_VALUE);

                                    EditorGUILayout.BeginHorizontal();
                                    {
                                        if (LanguageAlreadyExist(index, i, _mDatabase.Items[index].Values[i].Language))
                                        {
                                            OnInspectorGUIText("Warning language translation already exist", 12, Color.red, FontStyle.Bold, false);
                                        }

                                        GUILayout.FlexibleSpace();
                                        if (OnInspectorGUIButton("-", 20, 20, Color.white, Color.red))
                                        {
                                            itemValues.DeleteArrayElementAtIndex(i);
                                            return false;
                                        }
                                    }
                                    EditorGUILayout.EndHorizontal();

                                    EditorGUILayout.Space();
                                    EditorGUILayout.PropertyField(propLanguage, new GUIContent("Language"));
                                    EditorGUILayout.PrefixLabel("Translation");
                                    propValue.stringValue = EditorGUILayout.TextArea(propValue.stringValue, GUILayout.Height(80));

                                }
                                EditorGUILayout.Space();
                                EditorGUILayout.EndVertical();
                                EditorGUILayout.Space();
                            }
                        }
                    }
                    EditorGUILayout.EndVertical();
                }
            }

            EditorGUILayout.EndVertical();
            EditorGUILayout.Space();
            return true;
        }

        private bool KeyAlreadyExist(int currentIndex, string key)
        {
            for(int i = 0; i < _mDatabase.Items.Count; i++)
            {
                InternationalizationDatabaseItem item = _mDatabase.Items[i];
                if(currentIndex != i && item.Key == key && string.IsNullOrEmpty(key) == false)
                {
                    return true;
                }
            }

            return false;
        }

        private bool LanguageAlreadyExist(int indexInDatabase, int currentIndex, SystemLanguage language)
        {
            for (int i = 0; i < _mDatabase.Items[indexInDatabase].Values.Count; i++)
            {
                InternationalizationDatabaseItemLanguage item = _mDatabase.Items[indexInDatabase].Values[i];
                if (currentIndex != i && item.Language == language)
                {
                    return true;
                }
            }

            return false;
        }

        private void OnInspectorGUIText(string text, FontStyle fontStyle, bool prefixLabel)
        {
            GUIStyle style = new GUIStyle();
            style.fontStyle = fontStyle;
            style.wordWrap = true;

            if (prefixLabel)
            {
                EditorGUILayout.PrefixLabel(text, GUIStyle.none, style);
            }
            else
            {
                EditorGUILayout.LabelField(text, style);
            }
        }

        private void OnInspectorGUIText(string text, int fontSize, FontStyle fontStyle, bool prefixLabel)
        {
            GUIStyle style = new GUIStyle();
            style.fontSize = fontSize;
            style.fontStyle = fontStyle;
            style.wordWrap = true;

            if (prefixLabel)
            {
                EditorGUILayout.PrefixLabel(text, GUIStyle.none, style);
            }
            else
            {
                EditorGUILayout.LabelField(text, style);
            }
        }

        private void OnInspectorGUIText(string text, int fontSize, Color textColor, FontStyle fontStyle, bool prefixLabel)
        {
            GUIStyle style = new GUIStyle();
            style.fontSize = fontSize;
            style.normal.textColor = textColor;
            style.fontStyle = fontStyle;
            style.wordWrap = true;

            if(prefixLabel)
            {
                EditorGUILayout.PrefixLabel(text, GUIStyle.none, style);
            }
            else
            {
                EditorGUILayout.LabelField(text, style);
            }
        }

        private bool OnInspectorGUIButton(string label, int width, int height, Color textColor, Color backgroundColor)
        {
            Color saveColor = GUI.backgroundColor;
            GUILayoutOption[] options = { GUILayout.Width(width), GUILayout.Height(height) };
            GUIStyle style = new GUIStyle(GUI.skin.button);
            style.normal.textColor = textColor;
            GUI.backgroundColor = backgroundColor;

            bool pressed = GUILayout.Button(label, style, options);
            GUI.backgroundColor = saveColor;

            return pressed;
        }

        #endregion
    }

Есть ли у вас какие-либо предложения? Спасибо

Хорошего дня.

Ответы [ 2 ]

0 голосов
/ 27 октября 2019

Хорошо, наконец-то понял это, я имею в виду, я еще не совсем уверен, почему это происходит, но нашел обходной путь благодаря: https://forum.unity.com/threads/editor-gui-inputfield-loses-focus-when-gui-updates.542147/

По сути, я просто всегда отображаю LabelField,но если ошибки нет, я просто устанавливаю errorMessage на пустую строку

0 голосов
/ 26 октября 2019

Вы уверены, что не делитесь ссылкой на одно и то же свойство в обоих полях?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...