Forked from p-groarke/ResizeReorderableListExample.cs
Last active
December 19, 2018 08:32
-
-
Save PostEpoch/3d17f3892e671a4ae17873ec4e8a0926 to your computer and use it in GitHub Desktop.
Resize Unity Reorderable List example.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Originally from MALQUA | |
// https://feedback.unity3d.com/suggestions/custom-element-size-in-reorderable-list | |
// http://i.imgur.com/fIbBorr.gifv | |
// and SOCAPEX | |
// https://gist.github.com/Socapex/1d9b45507464681d530b | |
// Modified by Jesse Hamburger | |
using UnityEngine; | |
using UnityEditor; | |
using UnityEditorInternal; | |
using System; | |
using System.Linq; | |
using System.Collections.Generic; | |
[CustomEditor(typeof(SomeClass))] | |
public class SomeClassEditor : Editor { | |
private ReorderableList whateverList; | |
private void OnEnable() { | |
//DrawReorderabltBarKitList(); | |
whateverList = CreateList(serializedObject, serializedObject.FindProperty("barDisplayKits"), "Bar Display Kits", "numberOfBarsInKit", 5); | |
} | |
public override void OnInspectorGUI() { | |
serializedObject.Update(); // Needed for free good editor functionality | |
whateverList.DoLayoutList(); | |
serializedObject.ApplyModifiedProperties(); // Needed for zero-hassle good editor functionality | |
} | |
/// <summary> | |
/// Creates a reorderable list for a property in the inspector for this type where each element expands when selected. | |
/// </summary> | |
/// <param name="obj">The Serialized Object for which to return a reorderable list. Required by ReorderableList constructor.</param> | |
/// <param name="prop">The Serialized Property that this list will read/write user input data from/to.</param> | |
/// <param name="label">The header label for this list.</param> | |
/// <param name="elementLabelPropertyName">The property name to use as a label for each element in the list.</param> | |
/// <param name="expandedLines">Number of lines of the element when expanded. Wish this could be handled automatically, but I can't figure out how to make it do so.</param> | |
/// <returns>null</returns> | |
ReorderableList CreateList( | |
SerializedObject obj, | |
SerializedProperty prop, | |
string label, | |
string elementLabelPropertyName, | |
int expandedLines | |
) { | |
ReorderableList list = new ReorderableList(obj, prop, true, true, true, true); | |
list.drawHeaderCallback = rect => { | |
EditorGUI.LabelField(rect, label); | |
}; | |
// Initialize a temporary list of element heights to be used later on in the draw function | |
List<float> heights = new List<float>(prop.arraySize); | |
// Main draw callback for the reorderable list | |
list.drawElementCallback = ( rect, index, active, focused ) => { | |
SerializedProperty element = list.serializedProperty.GetArrayElementAtIndex(index); | |
// Sprite s = (element.objectReferenceValue as GameObject); | |
// Manage the height of this element | |
bool foldout = active; | |
float height = EditorGUIUtility.singleLineHeight * 1.25f; // multiply by 1.25 to give each property a little breathing room | |
if ( foldout ) { | |
height = EditorGUIUtility.singleLineHeight * expandedLines + 2; // +2 is to give each element a bit of padding on the bottom | |
} | |
// Manage heights of each element | |
/// TODO: heights should really based on the GetPropertyHeight of property type, rather | |
/// than some random function parameter that we input, but I can't get GetPropertyHeight | |
/// to be properly here... at least for custom property drawers. | |
try { | |
heights[index] = height; | |
} catch ( ArgumentOutOfRangeException e ) { | |
Debug.LogWarning(e.Message); | |
} finally { | |
float[] floats = heights.ToArray(); | |
Array.Resize(ref floats, prop.arraySize); | |
heights = floats.ToList(); | |
} | |
// Add a bit of padding to the top of each element | |
rect.y += 2; | |
// If we have our element selected, show our property | |
if ( foldout ) { | |
EditorGUI.PropertyField(rect, element); | |
} else { | |
string valueType = element.FindPropertyRelative(elementLabelPropertyName).type; | |
string stringValue = ""; | |
/// TODO: This should really be split out into a separate parsing function that | |
/// returns the appropriate value, but for my purposes this is fine. Will do later! | |
if ( valueType == "string" ) { | |
stringValue = element.FindPropertyRelative(elementLabelPropertyName).stringValue; | |
} else if ( valueType == "int" ) { | |
stringValue = element.FindPropertyRelative(elementLabelPropertyName).intValue.ToString(); | |
} | |
string closedLabel = element.FindPropertyRelative(elementLabelPropertyName).displayName + "" + stringValue; | |
EditorGUI.LabelField(rect, closedLabel); | |
} | |
}; | |
// Adjust heights based on whether or not an element is selected. | |
list.elementHeightCallback = ( index ) => { | |
Repaint(); | |
float height = 0; | |
try { | |
height = heights[index]; | |
} catch ( ArgumentOutOfRangeException e ) { | |
Debug.LogWarning(e.Message); | |
} finally { | |
float[] floats = heights.ToArray(); | |
Array.Resize(ref floats, prop.arraySize); | |
heights = floats.ToList(); | |
} | |
return height; | |
}; | |
// Set the color of the selected list item | |
list.drawElementBackgroundCallback = ( rect, index, active, focused ) => { | |
rect.height = heights[index]; | |
Texture2D tex = new Texture2D(1, 1); | |
tex.SetPixel(0, 0, new Color(0.1f, 0.33f, 1f, 0.33f)); | |
tex.Apply(); | |
if ( active ) | |
GUI.DrawTexture(rect, tex as Texture); | |
}; | |
/* | |
/// Uncomment this section if you want a little dropdown list for the | |
/// "add element to list" button. | |
list.onAddDropdownCallback = ( rect, li ) => { | |
var menu = new GenericMenu(); | |
menu.AddItem(new GUIContent("Add Element"), false, () => { | |
serializedObject.Update(); | |
li.serializedProperty.arraySize++; | |
serializedObject.ApplyModifiedProperties(); | |
}); | |
menu.ShowAsContext(); | |
float[] floats = heights.ToArray(); | |
Array.Resize(ref floats, prop.arraySize); | |
heights = floats.ToList(); | |
}; | |
*/ | |
return list; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment