Esempio n. 1
0
        protected override void DrawPropertyLayout(GUIContent label)
        {
            var  entry            = this.ValueEntry;
            bool valueNeedsFixing = entry.ValueState == PropertyValueState.NullReference &&
                                    entry.SerializationBackend == SerializationBackend.Unity;

            if (valueNeedsFixing)
            {
                bool possibleRecursion = false;

                var prop = entry.Property.Parent;

                while (prop != null)
                {
                    if (prop.ValueEntry != null && (prop.ValueEntry.TypeOfValue == typeof(T) || prop.ValueEntry.BaseValueType == typeof(T)))
                    {
                        // We have a possible recursion
                        possibleRecursion = true;
                        break;
                    }

                    prop = prop.Parent;
                }

                if (possibleRecursion)
                {
                    SirenixEditorGUI.ErrorMessageBox("Possible Unity serialization recursion detected; cutting off drawing pre-emptively.");
                    return; // Get out of here
                }

                // If no recursion, fix value in layout
                if (Event.current.type == EventType.Layout)
                {
                    for (int i = 0; i < entry.ValueCount; i++)
                    {
                        object value = UnitySerializationUtility.CreateDefaultUnityInitializedObject(typeof(T));
                        entry.WeakValues.ForceSetValue(i, value);
                    }

                    entry.ApplyChanges();

                    var tree = entry.Property.Tree;

                    if (tree.UnitySerializedObject != null)
                    {
                        tree.UnitySerializedObject.ApplyModifiedPropertiesWithoutUndo();
                        Undo.RecordObjects(tree.UnitySerializedObject.targetObjects, "Odin inspector value changed");
                    }

                    entry.Property.Update(true);
                }
            }

            this.CallNextDrawer(label);
        }
Esempio n. 2
0
        private void DrawToolbar()
        {
            SirenixEditorGUI.BeginHorizontalToolbar();
            {
                // Label
                if (info.DropZone != null && DragAndDropManager.IsDragInProgress && info.DropZone.IsAccepted == false)
                {
                    GUIHelper.PushGUIEnabled(false);
                }

                if (info.Property.ValueEntry.ListLengthChangedFromPrefab)
                {
                    GUIHelper.PushIsBoldLabel(true);
                }

                if (info.ListConfig.HideFoldoutWhileEmpty && info.IsEmpty || info.CustomListDrawerOptions.Expanded)
                {
                    GUILayout.Label(info.Label, GUILayoutOptions.ExpandWidth(false));
                }
                else
                {
                    info.Toggled.Value = SirenixEditorGUI.Foldout(info.Toggled.Value, info.Label ?? GUIContent.none);
                }

                if (info.Property.ValueEntry.ListLengthChangedFromPrefab)
                {
                    GUIHelper.PopIsBoldLabel();
                }

                if (info.CustomListDrawerOptions.Expanded)
                {
                    info.Toggled.Value = true;
                }

                if (info.DropZone != null && DragAndDropManager.IsDragInProgress && info.DropZone.IsAccepted == false)
                {
                    GUIHelper.PopGUIEnabled();
                }

                GUILayout.FlexibleSpace();

                // Item Count
                if (info.CustomListDrawerOptions.ShowItemCountHasValue ? info.CustomListDrawerOptions.ShowItemCount : info.ListConfig.ShowItemCount)
                {
                    if (info.Property.ValueEntry.ValueState == PropertyValueState.CollectionLengthConflict)
                    {
                        GUILayout.Label(info.Count + " / " + info.CollectionResolver.MaxCollectionLength + " items", EditorStyles.centeredGreyMiniLabel);
                    }
                    else
                    {
                        GUILayout.Label(info.IsEmpty ? "Empty" : info.Count + " items", EditorStyles.centeredGreyMiniLabel);
                    }
                }

                bool paging     = info.CustomListDrawerOptions.PagingHasValue ? info.CustomListDrawerOptions.ShowPaging : true;
                bool hidePaging =
                    info.ListConfig.HidePagingWhileCollapsed && info.Toggled.Value == false ||
                    info.ListConfig.HidePagingWhileOnlyOnePage && info.Count <= info.NumberOfItemsPerPage;

                int numberOfItemsPrPage = Math.Max(1, info.NumberOfItemsPerPage);
                int numberOfPages       = Mathf.CeilToInt(info.Count / (float)numberOfItemsPrPage);
                int pageIndex           = info.Count == 0 ? 0 : (info.StartIndex / numberOfItemsPrPage) % info.Count;

                // Paging
                if (paging)
                {
                    bool disablePaging = paging && !hidePaging && (DragAndDropManager.IsDragInProgress || info.ShowAllWhilePaging || info.Toggled.Value == false);
                    if (disablePaging)
                    {
                        GUIHelper.PushGUIEnabled(false);
                    }

                    if (!hidePaging)
                    {
                        if (pageIndex == 0)
                        {
                            GUIHelper.PushGUIEnabled(false);
                        }

                        if (SirenixEditorGUI.ToolbarButton(EditorIcons.TriangleLeft, true))
                        {
                            if (Event.current.button == 0)
                            {
                                info.StartIndex -= numberOfItemsPrPage;
                            }
                            else
                            {
                                info.StartIndex = 0;
                            }
                        }
                        if (pageIndex == 0)
                        {
                            GUIHelper.PopGUIEnabled();
                        }

                        var userPageIndex = EditorGUILayout.IntField((numberOfPages == 0 ? 0 : (pageIndex + 1)), GUILayoutOptions.Width(10 + numberOfPages.ToString(CultureInfo.InvariantCulture).Length * 10)) - 1;
                        if (pageIndex != userPageIndex)
                        {
                            info.StartIndex = userPageIndex * numberOfItemsPrPage;
                        }

                        GUILayout.Label("/ " + numberOfPages);

                        if (pageIndex == numberOfPages - 1)
                        {
                            GUIHelper.PushGUIEnabled(false);
                        }

                        if (SirenixEditorGUI.ToolbarButton(EditorIcons.TriangleRight, true))
                        {
                            if (Event.current.button == 0)
                            {
                                info.StartIndex += numberOfItemsPrPage;
                            }
                            else
                            {
                                info.StartIndex = numberOfItemsPrPage * numberOfPages;
                            }
                        }
                        if (pageIndex == numberOfPages - 1)
                        {
                            GUIHelper.PopGUIEnabled();
                        }
                    }

                    pageIndex = info.Count == 0 ? 0 : (info.StartIndex / numberOfItemsPrPage) % info.Count;

                    var newStartIndex = Mathf.Clamp(pageIndex * numberOfItemsPrPage, 0, Mathf.Max(0, info.Count - 1));
                    if (newStartIndex != info.StartIndex)
                    {
                        info.StartIndex = newStartIndex;
                        var newPageIndex = info.Count == 0 ? 0 : (info.StartIndex / numberOfItemsPrPage) % info.Count;
                        if (pageIndex != newPageIndex)
                        {
                            pageIndex       = newPageIndex;
                            info.StartIndex = Mathf.Clamp(pageIndex * numberOfItemsPrPage, 0, Mathf.Max(0, info.Count - 1));
                        }
                    }

                    info.EndIndex = Mathf.Min(info.StartIndex + numberOfItemsPrPage, info.Count);

                    if (disablePaging)
                    {
                        GUIHelper.PopGUIEnabled();
                    }
                }
                else
                {
                    info.StartIndex = 0;
                    info.EndIndex   = info.Count;
                }

                if (paging && hidePaging == false && info.ListConfig.ShowExpandButton)
                {
                    if (info.Count < 300)
                    {
                        if (SirenixEditorGUI.ToolbarButton(info.ShowAllWhilePaging ? EditorIcons.TriangleUp : EditorIcons.TriangleDown, true))
                        {
                            info.ShowAllWhilePaging = !info.ShowAllWhilePaging;
                        }
                    }
                    else
                    {
                        info.ShowAllWhilePaging = false;
                    }
                }

                // Add Button
                if (info.IsReadOnly == false && !info.HideAddButton)
                {
                    info.ObjectPicker = ObjectPicker.GetObjectPicker(info, info.CollectionResolver.ElementType);
                    var superHackyAddFunctionWeSeriouslyNeedANewListDrawer = CollectionDrawerStaticInfo.NextCustomAddFunction;
                    CollectionDrawerStaticInfo.NextCustomAddFunction = null;

                    if (SirenixEditorGUI.ToolbarButton(EditorIcons.Plus))
                    {
                        if (superHackyAddFunctionWeSeriouslyNeedANewListDrawer != null)
                        {
                            superHackyAddFunctionWeSeriouslyNeedANewListDrawer();
                        }
                        else if (info.GetCustomAddFunction != null)
                        {
                            var objs = new object[info.Property.Tree.WeakTargets.Count];

                            for (int i = 0; i < objs.Length; i++)
                            {
                                objs[i] = info.GetCustomAddFunction(info.Property.ParentValues[i]);
                            }

                            info.CollectionResolver.QueueAdd(objs);
                        }
                        else if (info.GetCustomAddFunctionVoid != null)
                        {
                            info.GetCustomAddFunctionVoid(info.Property.ParentValues[0]);

                            this.Property.ValueEntry.WeakValues.ForceMarkDirty();
                        }
                        else if (info.CustomListDrawerOptions.AlwaysAddDefaultValue)
                        {
                            var objs = new object[info.Property.Tree.WeakTargets.Count];

                            if (info.Property.ValueEntry.SerializationBackend == SerializationBackend.Unity)
                            {
                                for (int i = 0; i < objs.Length; i++)
                                {
                                    objs[i] = UnitySerializationUtility.CreateDefaultUnityInitializedObject(info.CollectionResolver.ElementType);
                                }
                            }
                            else
                            {
                                for (int i = 0; i < objs.Length; i++)
                                {
                                    if (info.CollectionResolver.ElementType.IsValueType)
                                    {
                                        objs[i] = Activator.CreateInstance(info.CollectionResolver.ElementType);
                                    }
                                    else
                                    {
                                        objs[i] = null;
                                    }
                                }
                            }

                            //info.ListValueChanger.AddListElement(objs, "Add default value");
                            info.CollectionResolver.QueueAdd(objs);
                        }
                        else if (info.CollectionResolver.ElementType.InheritsFrom <UnityEngine.Object>() && Event.current.modifiers == EventModifiers.Control)
                        {
                            info.CollectionResolver.QueueAdd(new object[info.Property.Tree.WeakTargets.Count]);
                        }
                        else
                        {
                            info.ObjectPicker.ShowObjectPicker(
                                null,
                                info.Property.GetAttribute <AssetsOnlyAttribute>() == null,
                                GUIHelper.GetCurrentLayoutRect(),
                                info.Property.ValueEntry.SerializationBackend == SerializationBackend.Unity);
                        }
                    }

                    info.JumpToNextPageOnAdd = paging && (info.Count % numberOfItemsPrPage == 0) && (pageIndex + 1 == numberOfPages);
                }

                if (info.OnTitleBarGUI != null)
                {
                    info.OnTitleBarGUI(info.Property.ParentValues[0]);
                }
            }
            SirenixEditorGUI.EndHorizontalToolbar();
        }