void GetPropertyData(object key, object val, ReorderableList rList, int index, out PropertyCacheData keyData, out PropertyCacheData valData) { keyData = null; valData = null; if (m_ListKeyPropertys.TryGetValue(new KeyValuePair <ReorderableList, int>(rList, index), out var key_cache)) { if (key_cache.data == key) { keyData = key_cache; } } if (m_ListValuePropertys.TryGetValue(new KeyValuePair <ReorderableList, int>(rList, index), out var val_cache)) { if (val_cache.data == val) { valData = val_cache; } } if (keyData == null) { var property = SerializedPropertyParser.From(key, out var serializedObject, out var field); keyData = new PropertyCacheData { data = key, serializedObject = serializedObject, property = property, field = field, }; m_ListKeyPropertys[new KeyValuePair <ReorderableList, int>(rList, index)] = keyData; } if (valData == null) { var property = SerializedPropertyParser.From(val, out var serializedObject, out var field); valData = new PropertyCacheData { data = val, serializedObject = serializedObject, property = property, field = field, }; m_ListValuePropertys[new KeyValuePair <ReorderableList, int>(rList, index)] = valData; } }
void DrawReorderableList(Component component, FieldInfo field, IDictionary dict) { var id = new KeyValuePair <Component, string>(component, field.Name); bool addCallback = false; if (!m_DictionaryLists.ContainsKey(id)) { addCallback = true; m_DictionaryLists[id] = new ReorderableList(new List <KeyValuePair <object, object> >(), typeof(KeyValuePair <object, object>), true, true, true, true); } var rList = m_DictionaryLists[id]; rList.list.Clear(); foreach (var key in dict.Keys.Cast <object>()) { rList.list.Add(new KeyValuePair <object, object>(key, dict[key])); } if (addCallback) { rList.drawElementCallback = DrawItem; rList.onAddCallback = AddItem; rList.onRemoveCallback = RemoveItem; rList.onReorderCallback = ReorderList; rList.drawHeaderCallback = DrawHeader; rList.elementHeightCallback = GetItemHeight; } rList.DoLayoutList(); void DrawHeader(Rect rect) { EditorGUI.LabelField(rect, field.Name); } float GetItemHeight(int index) { var kvp = (KeyValuePair <object, object>)rList.list[index]; object key = kvp.Key; object val = kvp.Value; GetPropertyData(key, val, rList, index, out var keyData, out var valData); float keyHeight = SerializedPropertyParser.GetPropertyHeight(keyData.property); float valHeight = SerializedPropertyParser.GetPropertyHeight(valData.property); return(Mathf.Max(keyHeight, valHeight) + 8); } void DrawItem(Rect rect, int index, bool selected, bool focused) { var kvp = (KeyValuePair <object, object>)rList.list[index]; object key = kvp.Key; object val = kvp.Value; float keyWidth = rect.width * 0.45f - 40; float valWidth = rect.width - keyWidth; Rect keyPosition = new Rect(rect.x, rect.y, keyWidth - 16, rect.height); Rect valPosition = new Rect(rect.x + keyWidth, rect.y, valWidth - 8, rect.height); GetPropertyData(key, val, rList, index, out var keyData, out var valData); EditorGUI.BeginChangeCheck(); SerializedPropertyParser.PropertyField(keyData.serializedObject, keyData.property, keyData.field, new Rect(rect.x, rect.y, keyWidth - 16, rect.height), ref key); SerializedPropertyParser.PropertyField(valData.serializedObject, valData.property, valData.field, new Rect(rect.x + keyWidth, rect.y, valWidth - 8, rect.height), ref val); if (EditorGUI.EndChangeCheck()) { rList.list[index] = new KeyValuePair <object, object>(key, val); ListUpdated(); } } void AddItem(ReorderableList list) { Type[] arguments = dict.GetType().GetGenericArguments(); Type keyType = arguments[0]; Type valueType = arguments[1]; dict.Add(GetDefault(keyType), GetDefault(valueType)); object GetDefault(Type type) { if (type == null) { return(null); } if (type == typeof(string)) { return(""); } return(Activator.CreateInstance(type)); } } void RemoveItem(ReorderableList list) { ReorderableList.defaultBehaviours.DoRemoveButton(list); ListUpdated(); } void ReorderList(ReorderableList list) { ListUpdated(); } void ListUpdated() { dict.Clear(); foreach (var kvpObj in rList.list) { var kvp = (KeyValuePair <object, object>)kvpObj; dict.Add(kvp.Key, kvp.Value); } } }