public Rect Render(Rect position, SerializedProperty property, GUIContent label) { if (property.serializedObject.targetObject == null) { return(position); } if (playModeState == PlayModeStateChange.ExitingEditMode || playModeState == PlayModeStateChange.ExitingPlayMode) { return(position); } DrawerState state = GetDrawerState(property); SerializedProperty collection = property.FindPropertyRelative("values"); if (collection == null) { Debug.Log(property.name); } if (!ReorderableCollection.ListStates.ContainsKey(GetFullPath(collection))) { var newList = new ReorderableCollection(property, collection); newList.DrawHeaderAreaHandlers.Add(DrawTitle); newList.DrawElement += DrawElement; newList.DrawAddElement = DrawAddElement; newList.GetElementHeight = GetElementHeight; newList.Reorder += OnReorder; } state.Property = property; state.Height = 0; Rect startPosition = position; DisplayState listState = ReorderableCollection.ListStates[GetFullPath(collection)]; Color cachedColor = UnityEngine.GUI.color; var settings = PackageSettings.Settings.GetListSettings(collection); if (settings != null && settings.Color != Color.white) { UnityEngine.GUI.color = settings.Color; } if (collection != null) { position = DrawCollection(position, property, collection, label); } state.Height = position.y - startPosition.y; UnityEngine.GUI.color = cachedColor; return(position); }
public static DrawerState GetDrawerState(SerializedProperty property) { string propertyPath = GetFullPath(property); DrawerState state; if (!DrawerStates.ContainsKey(propertyPath)) { state = new DrawerState(property); DrawerStates.Add(GetFullPath(property), state); state.Property = property; state.Height = 0; } else { state = DrawerStates[propertyPath]; } return(state); }
public ReorderableCollection(SerializedProperty property, SerializedProperty collection) { bool allowDrag = true; object pathReference = SerializationReflection.GetPathReference(property); if (pathReference != null) { Type sortedType = SerializationReflection.GetPathReference(property).GetType(); while (sortedType != null) { if (sortedType.GetInterface("SortedCollection`1") != null) { allowDrag = false; break; } sortedType = sortedType.BaseType; } } string collectionPath = CollectionDisplay.GetFullPath(collection); DisplayState listState; if (ListStates.ContainsKey(collectionPath)) { ListStates.Remove(collectionPath); } listState = new DisplayState(); ListStates.Add(collectionPath, listState); listState.Collection = collection; listState.List = this; DrawerState drawerState = CollectionDisplay.GetDrawerState(property); var newList = new ReorderableList(collection.serializedObject, collection) { draggable = allowDrag, }; newList.showDefaultBackground = false; newList.onReorderCallbackWithDetails = (ReorderableList list, int oldIndex, int newIndex) => { Reorder?.Invoke(drawerState.Property, listState.Collection, oldIndex, newIndex); }; newList.drawHeaderCallback = (Rect position) => { SerializedProperty hasLostValue = drawerState.Property.FindPropertyRelative("hasLostValue"); if (hasLostValue != null && hasLostValue.boolValue == true) { EditorUtility.DisplayDialog("Collection Error", "You've attempted to change an element in a way that prevents it from being added to the collection. The element will be moved to the Add Element area of the list so you can change the element and add it back in.", "Okay"); ListStates[CollectionDisplay.GetFullPath(listState.Collection)].AddingElement = true; hasLostValue.boolValue = false; } Rect startPosition = position; DrawHeaderBackground(position, drawerState.Property, listState.Collection); DrawSettingsButton(position, drawerState.Property, listState.Collection); position.y += DrawSettings(position, drawerState.Property, listState.Collection); for (var i = 0; i < DrawHeaderAreaHandlers.Count; i++) { position.y += DrawHeaderAreaHandlers[i].Invoke(position, drawerState.Property, listState.Collection); } listState.LastHeaderHeight = position.y - startPosition.y; newList.headerHeight = listState.LastHeaderHeight; }; newList.drawElementCallback += (Rect position, int index, bool isActive, bool isFocused) => { position.y += 2; var pageRange = GetPageDisplayRange(listState.Collection); if (index >= pageRange.x && index < pageRange.y) { EditorGUI.BeginDisabledGroup(listState.AddingElement); DrawElement?.Invoke(position, index, drawerState.Property, listState.Collection); EditorGUI.EndDisabledGroup(); } }; newList.drawElementBackgroundCallback = (Rect position, int index, bool isActive, bool isFocused) => { if (Mathf.Approximately(position.height, 0)) { return; } Rect backgroundPos = position; backgroundPos.yMin -= 2; backgroundPos.yMax += 2; boxBackground.fixedHeight = backgroundPos.height; boxBackground.fixedWidth = backgroundPos.width; Color guiColor = UnityEngine.GUI.color; if (isActive) { UnityEngine.GUI.color = UnityEngine.GUI.skin.settings.selectionColor; } if (index % 2 == 0) { UnityEngine.GUI.color = Color.Lerp(UnityEngine.GUI.color, Color.black, .1f); } if (Event.current.type == EventType.Repaint) { boxBackground.Draw(position, false, isActive, true, false); } UnityEngine.GUI.color = guiColor; position.xMin += 2; position.xMax -= 3; }; newList.elementHeightCallback += (int index) => { int pageSize = GetItemsPerPage(listState.Collection); int pageStartIndex = (listState.CurrentPageSet * listState.PageSetSize * pageSize) + (listState.CurrentPage * pageSize); int pageEndIndex = pageStartIndex + pageSize; if (index >= pageStartIndex && index < pageEndIndex && (GetElementHeight != null)) { return(GetElementHeight(index, drawerState.Property, listState.Collection) + 2); } return(0); }; newList.drawFooterCallback = (Rect position) => { DrawFooterBackground(position, drawerState.Property, listState.Collection); DrawAddRemoveButtons(position, drawerState.Property, listState.Collection); Rect startPosition = position; for (var i = 0; i < DrawFooterAreaHandlers.Count; i++) { position.y += DrawFooterAreaHandlers[i].Invoke(position, drawerState.Property, listState.Collection); } position.y += DrawPageSelection(position, drawerState.Property, listState.Collection); if (listState.List.DrawCustomAdd) { position.y += DrawAddArea(position, property, collection); } listState.LastFooterHeight = position.y - startPosition.y; listState.LastFooterHeight += 4; List.footerHeight = listState.LastFooterHeight; }; newList.onRemoveCallback += (ReorderableList targetList) => { if (targetList.index > -1) { int pageSize = GetItemsPerPage(listState.Collection); int pageStartIndex = GetPageDisplayRange(listState.Collection).x; listState.Collection.DeleteArrayElementAtIndex(pageStartIndex + targetList.index); } }; newList.onAddCallback += (ReorderableList targetList) => { if (DrawCustomAdd) { ListStates[collectionPath].AddingElement = !ListStates[collectionPath].AddingElement; if (ListStates[collectionPath].AddingElement) { SerializationReflection.CallPrivateMethod(property, "ClearTemp"); } } else { listState.Collection.InsertArrayElementAtIndex(listState.Collection.arraySize); } }; List = newList; }