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); }
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(); }