예제 #1
0
        private void CreateListData(SerializedProperty property)
        {
            var parent = GetGrandParentPath(property);

            // Try to find the grand parent in SortableListData
            var data = listIndex.Find(listData => listData.Parent.Equals(parent));

            if (data == null)
            {
                data = new SortableListData(parent);
                listIndex.Add(data);
            }

            data.AddProperty(property);
            var attr = property.GetAttributes <ReorderableAttribute>();

            if (attr != null && attr.Length == 1)
            {
                var arrayAttr = (ReorderableAttribute)attr[0];
                if (arrayAttr != null)
                {
                    HandleReorderableOptions(arrayAttr, property, data);
                }
            }
        }
        private void CreateListData(SerializedProperty property)
        {
            string parent = GetGrandParentPath(property);

            // Try to find the grand parent in SortableListData
            SortableListData data = listIndex.Find(listData => listData.Parent.Equals(parent));

            if (data == null)
            {
                data = new SortableListData(parent);
                listIndex.Add(data);
            }

            data.AddProperty(property);
            object[] attr = property.GetAttributes <SortableArrayAttribute>();
            if (attr != null && attr.Length == 1)
            {
                SortableArrayAttribute arrayAttr = (SortableArrayAttribute)attr[0];
                if (arrayAttr != null && string.IsNullOrEmpty(arrayAttr.ElementHeader) == false)
                {
                    data.ElementHeaderCallback = delegate(int i)
                    {
                        return(string.Format("{0} {1}", arrayAttr.ElementHeader, (arrayAttr.HeaderZeroIndex ? i : i + 1)));
                    };
                }
            }
        }
예제 #3
0
        /// <summary>
        /// Given a SerializedProperty, return the automatic ReorderableList assigned to it if any
        /// </summary>
        /// <param name="property"></param>
        /// <returns></returns>
        protected ReorderableList GetSortableList(SerializedProperty property)
        {
            if (listIndex.Count == 0)
            {
                return(null);
            }

            string parent = GetGrandParentPath(property);

            SortableListData data = listIndex.Find(listData => listData.Parent.Equals(parent));

            if (data == null)
            {
                return(null);
            }

            return(data.GetPropertyList(property));
        }
예제 #4
0
        /// <summary>
        /// Set a drag and drop handler function on a SerializedObject's ReorderableList, if any
        /// </summary>
        /// <param name="property"></param>
        /// <param name="handler"></param>
        /// <returns></returns>
        protected bool SetDragDropHandler(SerializedProperty property, Action <SerializedProperty, Object[]> handler)
        {
            if (listIndex.Count == 0)
            {
                return(false);
            }

            string parent = GetGrandParentPath(property);

            SortableListData data = listIndex.Find(listData => listData.Parent.Equals(parent));

            if (data == null)
            {
                return(false);
            }

            data.SetDropHandler(property, handler);
            return(true);
        }
        /// <summary>
        /// Draw a SerializedProperty as a ReorderableList if it was found during
        /// initialization, otherwise use EditorGUILayout.PropertyField
        /// </summary>
        /// <param name="property"></param>
        protected void DrawPropertySortableArray(SerializedProperty property)
        {
            // Try to get the sortable list this property belongs to
            SortableListData listData = null;

            if (listIndex.Count > 0)
            {
                listData = listIndex.Find(data => property.propertyPath.StartsWith(data.Parent));
            }

            if (listData != null)
            {
                // Try to show the list
                if (listData.DoLayoutProperty(property) == false)
                {
                    EditorGUILayout.PropertyField(property, false);
                    if (property.isExpanded)
                    {
                        EditorGUI.indentLevel++;
                        SerializedProperty targetProp = serializedObject.FindProperty(property.propertyPath);
                        IterateSerializedProp(targetProp);
                        EditorGUI.indentLevel--;
                    }
                }
            }
            else
            {
                SerializedProperty targetProp = serializedObject.FindProperty(property.propertyPath);
                bool restoreEnable            = GUI.enabled;
                if (targetProp.propertyPath.StartsWith("m_"))
                {
                    GUI.enabled = false;
                }
                EditorGUILayout.PropertyField(targetProp, targetProp.isExpanded);
                GUI.enabled = restoreEnable;
            }
        }
예제 #6
0
        /// <summary>
        /// Draw a SerializedProperty as a ReorderableList if it was found during
        /// initialization, otherwise use EditorGUILayout.PropertyField
        /// </summary>
        /// <param name="property"></param>
        protected void DrawPropertySortableArray(SerializedProperty property)
        {
            // Try to get the sortable list this property belongs to
            SortableListData listData = null;

            if (listIndex.Count > 0)
            {
                listData = listIndex.Find(data => property.propertyPath.StartsWith(data.Parent));
            }

            Editor scriptableEditor;
            bool   isScriptableEditor = editableIndex.TryGetValue(property.propertyPath, out scriptableEditor);

            // Has ReorderableList
            if (listData != null)
            {
                // Try to show the list
                if (listData.DoLayoutProperty(property) == false)
                {
                    EditorGUILayout.PropertyField(property, false);
                    if (property.isExpanded)
                    {
                        EditorGUI.indentLevel++;
                        SerializedProperty targetProp = serializedObject.FindProperty(property.propertyPath);
                        IterateDrawProperty(targetProp);
                        EditorGUI.indentLevel--;
                    }
                }
            }
            // Else try to draw ScriptableObject editor
            else if (isScriptableEditor)
            {
                bool hasHeader = property.HasAttribute <HeaderAttribute>();
                bool hasSpace  = property.HasAttribute <SpaceAttribute>();

                float foldoutSpace = hasHeader ? 24 : 7;
                if (hasHeader && hasSpace)
                {
                    foldoutSpace = 31;
                }

                hasSpace |= hasHeader;

                // No data in property, draw property field with create button
                if (scriptableEditor == null)
                {
                    bool doCreate;
                    using (new EditorGUILayout.HorizontalScope())
                    {
                        EditorGUILayout.PropertyField(property, uiExpandWidth);
                        using (new EditorGUILayout.VerticalScope(uiWidth50))
                        {
                            if (hasSpace)
                            {
                                GUILayout.Space(10);
                            }
                            doCreate = GUILayout.Button(labelBtnCreate, EditorStyles.miniButton);
                        }
                    }

                    if (doCreate)
                    {
                        Type propType     = property.GetTypeReflection();
                        var  createdAsset = CreateAssetWithSavePrompt(propType, "Assets");
                        if (createdAsset != null)
                        {
                            property.objectReferenceValue = createdAsset;
                            property.isExpanded           = true;
                        }
                    }
                }
                // Has data in property, draw foldout and editor
                else
                {
                    EditorGUILayout.PropertyField(property);

                    Rect rectFoldout = GUILayoutUtility.GetLastRect();
                    rectFoldout.width = 20;
                    if (hasSpace)
                    {
                        rectFoldout.yMin += foldoutSpace;
                    }

                    property.isExpanded = EditorGUI.Foldout(rectFoldout, property.isExpanded, GUIContent.none);

                    if (property.isExpanded)
                    {
                        EditorGUI.indentLevel++;
                        using (new EditorGUILayout.VerticalScope(styleEditBox))
                        {
                            var restoreIndent = EditorGUI.indentLevel;
                            EditorGUI.indentLevel = 1;
                            scriptableEditor.serializedObject.Update();
                            scriptableEditor.OnInspectorGUI();
                            scriptableEditor.serializedObject.ApplyModifiedProperties();
                            EditorGUI.indentLevel = restoreIndent;
                        }
                        EditorGUI.indentLevel--;
                    }
                }
            }
            else
            {
                SerializedProperty targetProp = serializedObject.FindProperty(property.propertyPath);

                bool isStartProp = targetProp.propertyPath.StartsWith("m_");
                using (new EditorGUI.DisabledScope(isStartProp))
                {
                    EditorGUILayout.PropertyField(targetProp, targetProp.isExpanded);
                }
            }
        }
예제 #7
0
        private void HandleReorderableOptions(ReorderableAttribute arrayAttr, SerializedProperty property, SortableListData data)
        {
            // Custom element header
            if (string.IsNullOrEmpty(arrayAttr.ElementHeader) == false)
            {
                data.ElementHeaderCallback = i => string.Format("{0} {1}", arrayAttr.ElementHeader, (arrayAttr.HeaderZeroIndex ? i : i + 1));
            }

            // Draw property as single line
            if (arrayAttr.ElementSingleLine)
            {
                var list = data.GetPropertyList(property);
#if UNITY_5_3_OR_NEWER
                list.elementHeightCallback         = index => EditorGUIUtility.singleLineHeight + 6;
                list.drawElementBackgroundCallback = (rect, index, active, focused) =>
                {
                    if (focused == false)
                    {
                        return;
                    }
                    if (styleHighlight == null)
                    {
                        styleHighlight = GUI.skin.FindStyle("MeTransitionSelectHead");
                    }
                    GUI.Box(rect, GUIContent.none, styleHighlight);
                };
#endif

                list.drawElementCallback = (rect, index, active, focused) =>
                {
                    var element = property.GetArrayElementAtIndex(index);
                    element.isExpanded = false;

                    int childCount = data.GetElementCount(property);
                    if (childCount < 1)
                    {
                        return;
                    }

                    rect.y      += 3;
                    rect.height -= 6;

                    if (element.NextVisible(true))
                    {
                        float restoreWidth = EditorGUIUtility.labelWidth;
                        EditorGUIUtility.labelWidth /= childCount;

                        float padding = 5f;
                        float width   = rect.width - padding * (childCount - 1);
                        width /= childCount;

                        Rect childRect = new Rect(rect)
                        {
                            width = width
                        };
                        int depth = element.Copy().depth;
                        do
                        {
                            if (element.depth != depth)
                            {
                                break;
                            }

                            if (childCount <= 2)
                            {
                                EditorGUI.PropertyField(childRect, element, false);
                            }
                            else
                            {
                                EditorGUI.PropertyField(childRect, element, GUIContent.none, false);
                            }
                            childRect.x += width + padding;
                        } while (element.NextVisible(false));

                        EditorGUIUtility.labelWidth = restoreWidth;
                    }
                };
            }
        }
        private void CreateListData(SerializedProperty property)
        {
            string parent = GetGrandParentPath(property);

            // Try to find the grand parent in SortableListData
            SortableListData data = listIndex.Find(listData => listData.Parent.Equals(parent));
            if (data == null)
            {
                data = new SortableListData(parent);
                listIndex.Add(data);
            }

            data.AddProperty(property);
        }
예제 #9
0
        /// <summary>
        /// Draw a SerializedProperty as a ReorderableList if it was found during
        /// initialization, otherwise use EditorGUILayout.PropertyField
        /// </summary>
        /// <param name="property"></param>
        protected void DrawPropertySortableArray(SerializedProperty property)
        {
            // Try to get the sortable list this property belongs to
            SortableListData listData = null;

            if (listIndex.Count > 0)
            {
                listData = listIndex.Find(data => property.propertyPath.StartsWith(data.Parent));
            }

            Editor scriptableEditor;
            bool   isScriptableEditor = editableIndex.TryGetValue(property.propertyPath, out scriptableEditor);

            if (listData != null)
            {
                // Try to show the list
                if (listData.DoLayoutProperty(property) == false)
                {
                    EditorGUILayout.PropertyField(property, false);
                    if (property.isExpanded)
                    {
                        EditorGUI.indentLevel++;
                        SerializedProperty targetProp = serializedObject.FindProperty(property.propertyPath);
                        IterateDrawProperty(targetProp);
                        EditorGUI.indentLevel--;
                    }
                }
            }
            else if (isScriptableEditor)
            {
                if (scriptableEditor == null)
                {
                    using (new EditorGUILayout.HorizontalScope())
                    {
                        EditorGUILayout.PropertyField(property, uiExpandWidth);
                        if (GUILayout.Button(labelBtnCreate, EditorStyles.miniButton, uiWidth50))
                        {
                            Type propType     = property.GetTypeReflection();
                            var  createdAsset = CreateAssetWithSavePrompt(propType, "Assets");
                            if (createdAsset != null)
                            {
                                property.objectReferenceValue = createdAsset;
                            }
                        }
                    }
                }
                else
                {
                    EditorGUILayout.PropertyField(property);
                    Rect rectFoldout = GUILayoutUtility.GetLastRect();
                    rectFoldout.width   = 20;
                    property.isExpanded = EditorGUI.Foldout(rectFoldout, property.isExpanded, GUIContent.none);

                    if (property.isExpanded)
                    {
                        EditorGUI.indentLevel++;
                        scriptableEditor.OnInspectorGUI();
                        GUILayout.Box(GUIContent.none, uiHeight2, uiExpandWidth);
                        EditorGUI.indentLevel--;
                    }
                }
            }
            else
            {
                SerializedProperty targetProp = serializedObject.FindProperty(property.propertyPath);

                bool isStartProp = targetProp.propertyPath.StartsWith("m_");
                using (new EditorGUI.DisabledScope(isStartProp))
                {
                    EditorGUILayout.PropertyField(targetProp, targetProp.isExpanded);
                }
            }
        }
        private void HandleReorderableOptions(ReorderableAttribute arrayAttr, SerializedProperty property, SortableListData data)
        {
            // Custom element header
            if (string.IsNullOrEmpty(arrayAttr.ElementHeader) == false)
            {
                data.ElementHeaderCallback = i => string.Format("{0} {1}", arrayAttr.ElementHeader, (arrayAttr.HeaderZeroIndex ? i : i + 1));
            }

            // Draw property as single line
            if (arrayAttr.ElementSingleLine)
            {
                var list = data.GetPropertyList(property);
                list.elementHeightCallback = index => EditorGUIUtility.singleLineHeight;
                list.drawElementCallback   = (rect, index, active, focused) =>
                {
                    var element    = property.GetArrayElementAtIndex(index);
                    int childCount = element.Copy().CountRemaining();
                    childCount -= (property.arraySize - 1) - index;

                    if (element.NextVisible(true))
                    {
                        float restoreWidth = EditorGUIUtility.labelWidth;
                        EditorGUIUtility.labelWidth /= childCount;

                        float padding = 5f;
                        float width   = rect.width - padding * (childCount - 1);
                        width /= childCount;

                        Rect childRect = new Rect(rect)
                        {
                            width = width
                        };
                        int depth = element.Copy().depth;
                        do
                        {
                            if (element.depth != depth)
                            {
                                break;
                            }
                            if (childCount <= 2)
                            {
                                EditorGUI.PropertyField(childRect, element, false);
                            }
                            else
                            {
                                EditorGUI.PropertyField(childRect, element, GUIContent.none, false);
                            }
                            childRect.x += width + padding;
                        } while (element.NextVisible(false));

                        EditorGUIUtility.labelWidth = restoreWidth;
                    }
                };
            }
        }
예제 #11
0
        /// <summary>
        /// Draw a SerializedProperty as a ReorderableList if it was found during
        /// initialization, otherwise use EditorGUILayout.PropertyField
        /// </summary>
        /// <param name="property"></param>
        protected void DrawPropertySortableArray(SerializedProperty property)
        {
            // Try to get the sortable list this property belongs to
            SortableListData listData = null;

            if (listIndex.Count > 0)
            {
                listData = listIndex.Find(data => property.propertyPath.StartsWith(data.Parent));
            }

            Editor scriptableEditor;
            bool   isScriptableEditor = editableIndex.TryGetValue(property.propertyPath, out scriptableEditor);

            // Has ReorderableList
            if (listData != null)
            {
                // Try to show the list
                if (listData.DoLayoutProperty(property) == false)
                {
                    EditorGUILayout.PropertyField(property, false);
                    if (property.isExpanded)
                    {
                        EditorGUI.indentLevel++;
                        SerializedProperty targetProp = serializedObject.FindProperty(property.propertyPath);
                        IterateDrawProperty(targetProp);
                        EditorGUI.indentLevel--;
                    }
                }
            }
            // Else try to draw ScriptableObject editor
            else if (isScriptableEditor)
            {
                bool hasHeader = property.HasAttribute <HeaderAttribute>();
                bool hasSpace  = property.HasAttribute <SpaceAttribute>();

                float foldoutSpace = hasHeader ? 24 : 7;
                if (hasHeader && hasSpace)
                {
                    foldoutSpace = 31;
                }

                hasSpace |= hasHeader;

                // No data in property, draw property field with create button
                if (scriptableEditor == null)
                {
                    bool        doCreate;
                    List <Type> subclasses = new List <Type>();
                    using (new EditorGUILayout.HorizontalScope())
                    {
                        EditorGUILayout.PropertyField(property, uiExpandWidth);
                        using (new EditorGUILayout.VerticalScope(uiWidth50))
                        {
                            using (new EditorGUILayout.HorizontalScope())
                            {
                                Type propType = property.GetTypeReflection();
                                subclasses = Assembly.GetAssembly(propType).GetTypes().Where(x => x.IsSubclassOf(propType)).ToList();

                                if (subclasses.Count > 0)
                                {
                                    string keyname = this.GetType().Name + target.name;
                                    if (!nv.editor.EditorData.Instance.HasData <int>(keyname, property.propertyPath))
                                    {
                                        nv.editor.EditorData.Instance.SetData <int>(0, keyname, property.propertyPath);
                                    }

                                    int selection = nv.editor.EditorData.Instance.GetData <int>(keyname, property.propertyPath);
                                    selection = EditorGUILayout.Popup(selection, subclasses.Select(x => x.Name).ToArray());
                                    nv.editor.EditorData.Instance.SetData <int>(selection, keyname, property.propertyPath);
                                }

                                if (hasSpace)
                                {
                                    GUILayout.Space(10);
                                }
                                doCreate = GUILayout.Button(labelBtnCreate, EditorStyles.miniButton);
                            }
                        }
                    }

                    if (doCreate)
                    {
                        string keyname  = this.GetType().Name + target.name;
                        Type   propType = property.GetTypeReflection();
                        if (subclasses.Count > 0)
                        {
                            int selection = nv.editor.EditorData.Instance.GetData <int>(keyname, property.propertyPath);
                            propType = subclasses[selection];
                        }

                        string pwd = nv.editor.EditorData.Instance.GetData <string>(keyname, property.propertyPath);
                        if (string.IsNullOrEmpty(pwd))
                        {
                            pwd = Application.dataPath;
                        }

                        var createdAsset = CreateAssetWithSavePrompt(propType, ref pwd);
                        if (createdAsset != null)
                        {
                            nv.editor.EditorData.Instance.SetData <string>(pwd, keyname, property.propertyPath);
                            property.objectReferenceValue = createdAsset;
                            property.isExpanded           = true;
                        }
                    }
                }
                // Has data in property, draw foldout and editor
                else
                {
                    EditorGUILayout.PropertyField(property);

                    Rect rectFoldout = GUILayoutUtility.GetLastRect();
                    rectFoldout.width = 20;
                    if (hasSpace)
                    {
                        rectFoldout.yMin += foldoutSpace;
                    }

                    property.isExpanded = EditorGUI.Foldout(rectFoldout, property.isExpanded, GUIContent.none);

                    if (property.isExpanded)
                    {
                        EditorGUI.indentLevel++;
                        using (new EditorGUILayout.VerticalScope(styleEditBox))
                        {
                            var restoreIndent = EditorGUI.indentLevel;
                            EditorGUI.indentLevel = 1;
                            scriptableEditor.serializedObject.Update();
                            scriptableEditor.OnInspectorGUI();
                            scriptableEditor.serializedObject.ApplyModifiedProperties();
                            EditorGUI.indentLevel = restoreIndent;
                        }
                        EditorGUI.indentLevel--;
                    }
                }
            }
            else
            {
                SerializedProperty targetProp = serializedObject.FindProperty(property.propertyPath);

                bool isStartProp = targetProp.propertyPath.StartsWith("m_");
#if UNITY_5_5_OR_NEWER
                using (new EditorGUI.DisabledScope(isStartProp))
                {
                    EditorGUILayout.PropertyField(targetProp, targetProp.isExpanded);
                }
#else
                EditorGUI.BeginDisabledGroup(isStartProp);
                EditorGUILayout.PropertyField(targetProp, targetProp.isExpanded);
                EditorGUI.EndDisabledGroup();
#endif
            }
        }