#define Graph_And_Chart_PRO using ChartAndGraph; using System; using System.Collections.Generic; using System.Linq; using System.Text; using UnityEditor; using UnityEngine; namespace Assets { [CustomEditor(typeof(RadarChart), true)] class RadarChartInspector : Editor { bool mCategories = false; bool mGroups = false; string mCategoryError = null; string mNewCategoryName = ""; string mNewGroupName = ""; string mGroupError = null; GUIStyle mRedStyle; GUIStyle mBold; HashSet mAllNames = new HashSet(); GUIStyle mSplitter; List mToRemove = new List(); List mToUp = new List(); Dictionary mOperations = new Dictionary(); ChartDataEditor mWindow; bool mUpdateWindow = false; Texture mSettings; GUIContent MaxRadarValue = new GUIContent("Max Value :", "All radar values are scale according to this value"); GUIContent MinRadarValue = new GUIContent("Min Value :", "All radar values are scale according to this value"); RenameWindow mRenameWindow; string[] NonCanvas = new string[] { "LinePrefab", "PointPrefab", "Seperation", "Curve", "FillSmoothing" }; public void OnEnable() { mRedStyle = new GUIStyle(); mRedStyle.normal.textColor = Color.red; mSplitter = new GUIStyle(); mSplitter.normal.background = EditorGUIUtility.whiteTexture; mSplitter.stretchWidth = true; mSplitter.margin = new RectOffset(0, 0, 7, 7); } public void Splitter() { Rect position = GUILayoutUtility.GetRect(GUIContent.none, mSplitter, GUILayout.Height(1f)); if (Event.current.type == EventType.Repaint) { Color restoreColor = GUI.color; GUI.color = new Color(0.5f, 0.5f, 0.5f); mSplitter.Draw(position, false, false, false, false); GUI.color = restoreColor; } } private void DoOperations(SerializedProperty items, int size, string type) { mToRemove.Clear(); mToUp.Clear(); bool up = false; for (int i = 0; i < size; i++) { SerializedProperty entry = items.GetArrayElementAtIndex(i); if (entry == null) continue; SerializedProperty nameProp = entry.FindPropertyRelative("Name"); string name = null; if (nameProp == null) name = entry.stringValue; else name = nameProp.stringValue; string arg = type + "|" + name; string res = null; if (up == true) { mToUp.Add(i); up = false; } if (mOperations.TryGetValue(arg, out res)) { if (res == "remove") mToRemove.Add(i); if (res == "up" && i > 0) mToUp.Add(i); if (res == "down") up = true; mOperations.Remove(arg); } } for (int i = 0; i < mToRemove.Count; i++) items.DeleteArrayElementAtIndex(mToRemove[i]); for (int i = 0; i < mToUp.Count; i++) { int cur = mToUp[i]; items.MoveArrayElement(cur, cur - 1); } } private void NamedItemEditor(SerializedProperty data, string type, string property, string caption, ref string errorMessage, ref bool foldout, ref string newName) { SerializedProperty items = data.FindPropertyRelative(property); items.isExpanded = EditorGUILayout.Foldout(items.isExpanded, caption); //bool up, down; mAllNames.Clear(); int size = items.arraySize; if (Event.current.type == EventType.Layout) DoOperations(items, size, type); size = items.arraySize; if (items.isExpanded) { EditorGUI.indentLevel++; for (int i = 0; i < size; i++) { SerializedProperty entry = items.GetArrayElementAtIndex(i); if (entry == null) continue; SerializedProperty nameProp = entry.FindPropertyRelative("Name"); string name = null; if (nameProp == null) name = entry.stringValue; else name = nameProp.stringValue; mAllNames.Add(name); EditorGUILayout.BeginHorizontal(); bool toogle = false; if (nameProp != null) toogle = entry.isExpanded = EditorGUILayout.Foldout(entry.isExpanded, name); else { toogle = false; EditorGUILayout.LabelField(name); } GUILayout.FlexibleSpace(); if (GUILayout.Button("...")) DoContext(type, name); EditorGUILayout.EndHorizontal(); if (toogle) { EditorGUI.indentLevel++; if (nameProp != null) { SerializedProperty end = entry.GetEndProperty(true); entry.Next(true); if (SerializedProperty.EqualContents(entry, end) == false) { do { if (entry.name != "Name") { if(target is CanvasRadarChart) { if (NonCanvas.Contains(entry.name)) continue; } else { if (entry.name == "LineHover" || entry.name == "PointHover") continue; } EditorGUILayout.PropertyField(entry, true); } } while (entry.Next(entry.name == "Materials") && SerializedProperty.EqualContents(entry, end) == false); } } EditorGUI.indentLevel--; } } if (errorMessage != null) EditorGUILayout.LabelField(errorMessage, mRedStyle); EditorGUILayout.LabelField(string.Format("Add new {0} :", type)); //Rect indentAdd = EditorGUI.IndentedRect(new Rect(0f, 0f, 1000f, 1000f)); EditorGUILayout.BeginHorizontal(); newName = EditorGUILayout.TextField(newName); //GUILayout.Space(indentAdd.xMin); if (GUILayout.Button("Add")) { bool error = false; if (newName.Trim().Length == 0) { errorMessage = "Name can't be empty"; error = true; } else if (ChartEditorCommon.IsAlphaNum(newName) == false) { errorMessage = "Name conatins invalid characters"; error = true; } else if (mAllNames.Contains(newName)) { errorMessage = string.Format("A {0} named {1} already exists in this chart", type, newName); error = true; } if (error == false) { errorMessage = null; items.InsertArrayElementAtIndex(size); SerializedProperty newItem = items.GetArrayElementAtIndex(size); SerializedProperty newItemName = newItem.FindPropertyRelative("Name"); if (newItemName == null) newItem.stringValue = newName; else newItemName.stringValue = newName; newName = ""; UpdateWindow(); } } EditorGUILayout.EndHorizontal(); EditorGUI.indentLevel--; } else { errorMessage = null; } UpdateWindow(); } void callback(object val) { KeyValuePair pair = (KeyValuePair)val; mOperations[pair.Key] = pair.Value; } bool RenameGroup(string fromName, string toName) { RadarChart radarChart = (RadarChart)serializedObject.targetObject; try { radarChart.DataSource.RenameGroup(fromName, toName); } catch (Exception) { return false; } serializedObject.Update(); if (radarChart.gameObject.activeInHierarchy) radarChart.GenerateChart(); else EditorUtility.SetDirty(radarChart); return true; } bool RenameCategory(string fromName, string toName) { RadarChart radarChart = (RadarChart)serializedObject.targetObject; try { radarChart.DataSource.RenameCategory(fromName, toName); } catch (Exception) { return false; } serializedObject.Update(); if (radarChart.gameObject.activeInHierarchy) radarChart.GenerateChart(); else EditorUtility.SetDirty(radarChart); return true; } void RenameCalled(object val) { var data = (KeyValuePair)val; RenameWindow window = EditorWindow.GetWindow(); mRenameWindow = window; if (data.Key == "category") window.ShowDialog(data.Value, data.Key, RenameCategory); else if (data.Key == "group") window.ShowDialog(data.Value, data.Key, RenameGroup); } void DoContext(string type, string name) { string arg = type + "|" + name; GenericMenu menu = new GenericMenu(); menu.AddItem(new GUIContent("Move Up"), false, callback, new KeyValuePair(arg, "up")); menu.AddItem(new GUIContent("Move Down"), false, callback, new KeyValuePair(arg, "down")); menu.AddItem(new GUIContent("Remove"), false, callback, new KeyValuePair(arg, "remove")); menu.AddItem(new GUIContent("Rename.."), false, RenameCalled, new KeyValuePair(type, name)); menu.ShowAsContext(); } void UpdateWindow() { mUpdateWindow = true; } void OnDisable() { if (mRenameWindow != null) { mRenameWindow.Close(); mRenameWindow = null; } if (mWindow != null) { mWindow.Close(); mWindow = null; } } public override void OnInspectorGUI() { base.OnInspectorGUI(); serializedObject.Update(); SerializedProperty radarData = serializedObject.FindProperty("Data"); EditorGUILayout.BeginVertical(); Splitter(); if (mBold == null) { mBold = new GUIStyle(EditorStyles.foldout); } EditorGUILayout.LabelField("Data", EditorStyles.boldLabel); EditorGUI.indentLevel++; NamedItemEditor(radarData, "category", "mCategories", "Categories", ref mCategoryError, ref mCategories, ref mNewCategoryName); NamedItemEditor(radarData, "group", "mGroups", "Groups", ref mGroupError, ref mGroups, ref mNewGroupName); SerializedProperty maxProp = radarData.FindPropertyRelative("maxValue"); SerializedProperty minProp = radarData.FindPropertyRelative("minValue"); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField(MaxRadarValue, EditorStyles.boldLabel); SerializedProperty automaticProp = radarData.FindPropertyRelative("automaticMaxValue"); bool automatic = automaticProp.boolValue; automatic = GUILayout.Toggle(automatic, "Auto"); GUILayout.FlexibleSpace(); automaticProp.boolValue = automatic; EditorGUILayout.EndHorizontal(); if (automatic == false) { EditorGUILayout.PropertyField(maxProp); if (0f > maxProp.doubleValue) maxProp.doubleValue = 0.001f; } EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField(MinRadarValue, EditorStyles.boldLabel); automaticProp = radarData.FindPropertyRelative("automaticMinValue"); automatic = automaticProp.boolValue; automatic = GUILayout.Toggle(automatic, "Auto"); GUILayout.FlexibleSpace(); automaticProp.boolValue = automatic; EditorGUILayout.EndHorizontal(); if (automatic == false) { EditorGUILayout.PropertyField(minProp); } if (GUILayout.Button("Edit Values...") && mWindow == null) mWindow = ChartDataEditor.ShowForObject(serializedObject); //} EditorGUI.indentLevel--; EditorGUILayout.EndVertical(); serializedObject.ApplyModifiedProperties(); if (mUpdateWindow == true) { mUpdateWindow = false; if (mWindow != null) { mWindow.SetEditedObject(serializedObject); mWindow.Repaint(); } } } } }