private void InitReorderedList() { if (prefEntryHolder == null) { var tmp = Resources.FindObjectsOfTypeAll <PreferenceEntryHolder>(); if (tmp.Length > 0) { prefEntryHolder = tmp[0]; } else { prefEntryHolder = ScriptableObject.CreateInstance <PreferenceEntryHolder>(); } } if (serializedObject == null) { serializedObject = new SerializedObject(prefEntryHolder); } userDefList = new ReorderableList(serializedObject, serializedObject.FindProperty("userDefList"), false, true, true, true); unityDefList = new ReorderableList(serializedObject, serializedObject.FindProperty("unityDefList"), false, true, false, false); relSpliterPos = EditorPrefs.GetFloat("BGTools.PlayerPrefsEditor.RelativeSpliterPosition", 100 / position.width); userDefList.drawHeaderCallback = (Rect rect) => { EditorGUI.LabelField(rect, "User defined"); }; userDefList.drawElementBackgroundCallback = OnDrawElementBackgroundCallback; userDefList.drawElementCallback = (Rect rect, int index, bool isActive, bool isFocused) => { var element = userDefList.serializedProperty.GetArrayElementAtIndex(index); SerializedProperty key = element.FindPropertyRelative("m_key"); SerializedProperty type = element.FindPropertyRelative("m_typeSelection"); SerializedProperty strValue = element.FindPropertyRelative("m_strValue"); SerializedProperty intValue = element.FindPropertyRelative("m_intValue"); SerializedProperty floatValue = element.FindPropertyRelative("m_floatValue"); float spliterPos = relSpliterPos * rect.width; rect.y += 2; EditorGUI.BeginChangeCheck(); EditorGUI.LabelField(new Rect(rect.x, rect.y, spliterPos - 1, EditorGUIUtility.singleLineHeight), new GUIContent(key.stringValue, key.stringValue)); GUI.enabled = false; EditorGUI.PropertyField(new Rect(rect.x + spliterPos + 1, rect.y, 60, EditorGUIUtility.singleLineHeight), type, GUIContent.none); GUI.enabled = !showLoadingIndicatorOverlay; switch ((PreferenceEntry.PrefTypes)type.enumValueIndex) { case PreferenceEntry.PrefTypes.Float: EditorGUI.DelayedFloatField(new Rect(rect.x + spliterPos + 62, rect.y, rect.width - spliterPos - 60, EditorGUIUtility.singleLineHeight), floatValue, GUIContent.none); break; case PreferenceEntry.PrefTypes.Int: EditorGUI.DelayedIntField(new Rect(rect.x + spliterPos + 62, rect.y, rect.width - spliterPos - 60, EditorGUIUtility.singleLineHeight), intValue, GUIContent.none); break; case PreferenceEntry.PrefTypes.String: EditorGUI.DelayedTextField(new Rect(rect.x + spliterPos + 62, rect.y, rect.width - spliterPos - 60, EditorGUIUtility.singleLineHeight), strValue, GUIContent.none); break; } if (EditorGUI.EndChangeCheck()) { entryAccessor.IgnoreNextChange(); switch ((PreferenceEntry.PrefTypes)type.enumValueIndex) { case PreferenceEntry.PrefTypes.Float: PlayerPrefs.SetFloat(key.stringValue, floatValue.floatValue); break; case PreferenceEntry.PrefTypes.Int: PlayerPrefs.SetInt(key.stringValue, intValue.intValue); break; case PreferenceEntry.PrefTypes.String: PlayerPrefs.SetString(key.stringValue, strValue.stringValue); break; } PlayerPrefs.Save(); } }; userDefList.onRemoveCallback = (ReorderableList l) => { userDefList.ReleaseKeyboardFocus(); unityDefList.ReleaseKeyboardFocus(); if (EditorUtility.DisplayDialog("Warning!", "Are you sure you want to delete this entry from PlayerPrefs? ", "Yes", "No")) { entryAccessor.IgnoreNextChange(); PlayerPrefs.DeleteKey(l.serializedProperty.GetArrayElementAtIndex(l.index).FindPropertyRelative("m_key").stringValue); PlayerPrefs.Save(); ReorderableList.defaultBehaviours.DoRemoveButton(l); PrepareData(); GUIUtility.ExitGUI(); } }; userDefList.onAddDropdownCallback = (Rect buttonRect, ReorderableList l) => { var menu = new GenericMenu(); foreach (PreferenceEntry.PrefTypes type in Enum.GetValues(typeof(PreferenceEntry.PrefTypes))) { menu.AddItem(new GUIContent(type.ToString()), false, () => { TextFieldDialog.OpenDialog("Create new property", "Key for the new property:", prefKeyValidatorList, (key) => { entryAccessor.IgnoreNextChange(); switch (type) { case PreferenceEntry.PrefTypes.Float: PlayerPrefs.SetFloat(key, 0.0f); break; case PreferenceEntry.PrefTypes.Int: PlayerPrefs.SetInt(key, 0); break; case PreferenceEntry.PrefTypes.String: PlayerPrefs.SetString(key, string.Empty); break; } PlayerPrefs.Save(); PrepareData(); Focus(); }, this); }); } menu.ShowAsContext(); }; unityDefList.drawElementBackgroundCallback = OnDrawElementBackgroundCallback; unityDefList.drawElementCallback = (Rect rect, int index, bool isActive, bool isFocused) => { var element = unityDefList.serializedProperty.GetArrayElementAtIndex(index); SerializedProperty key = element.FindPropertyRelative("m_key"); SerializedProperty type = element.FindPropertyRelative("m_typeSelection"); SerializedProperty strValue = element.FindPropertyRelative("m_strValue"); SerializedProperty intValue = element.FindPropertyRelative("m_intValue"); SerializedProperty floatValue = element.FindPropertyRelative("m_floatValue"); float spliterPos = relSpliterPos * rect.width; rect.y += 2; GUI.enabled = false; EditorGUI.LabelField(new Rect(rect.x, rect.y, spliterPos - 1, EditorGUIUtility.singleLineHeight), new GUIContent(key.stringValue, key.stringValue)); EditorGUI.PropertyField(new Rect(rect.x + spliterPos + 1, rect.y, 60, EditorGUIUtility.singleLineHeight), type, GUIContent.none); switch ((PreferenceEntry.PrefTypes)type.enumValueIndex) { case PreferenceEntry.PrefTypes.Float: EditorGUI.DelayedFloatField(new Rect(rect.x + spliterPos + 62, rect.y, rect.width - spliterPos - 60, EditorGUIUtility.singleLineHeight), floatValue, GUIContent.none); break; case PreferenceEntry.PrefTypes.Int: EditorGUI.DelayedIntField(new Rect(rect.x + spliterPos + 62, rect.y, rect.width - spliterPos - 60, EditorGUIUtility.singleLineHeight), intValue, GUIContent.none); break; case PreferenceEntry.PrefTypes.String: EditorGUI.DelayedTextField(new Rect(rect.x + spliterPos + 62, rect.y, rect.width - spliterPos - 60, EditorGUIUtility.singleLineHeight), strValue, GUIContent.none); break; } GUI.enabled = !showLoadingIndicatorOverlay; }; unityDefList.drawHeaderCallback = (Rect rect) => { EditorGUI.LabelField(rect, "Unity defined"); }; }