diff --git a/CHANGELOG-EN.md b/CHANGELOG-EN.md index ca76212a..70d5c1e3 100644 --- a/CHANGELOG-EN.md +++ b/CHANGELOG-EN.md @@ -32,6 +32,7 @@ ## Latest +* (2021.03.31) Optimized and refactor `Theme` to solve problems with the same or missing references #118 * (2021.03.30) Optimized `Tooltip` to support setting different category axis data #129 * (2021.03.29) Optimized the custom draw callback API * (2021.03.25) Added `Ganttchart` diff --git a/CHANGELOG.md b/CHANGELOG.md index ad5b91d5..a9a4c732 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,7 @@ ## Latest +* (2021.03.31) 优化和重构`Theme`,解决引用相同或丢失的问题 #118 * (2021.03.30) 优化`Tooltip`支持设置不同的类目轴数据 #129 * (2021.03.29) 优化自定义绘制回调接口,增加`onCustomDrawBeforeSerie`、`onCustomDrawAfterSerie`和`onCustomDrawTop` * (2021.03.25) 增加`GanttChart`甘特图 diff --git a/Editor/PropertyDrawers/ThemeDrawer.cs b/Editor/PropertyDrawers/ThemeDrawer.cs index ef6b3e46..5b28035b 100644 --- a/Editor/PropertyDrawers/ThemeDrawer.cs +++ b/Editor/PropertyDrawers/ThemeDrawer.cs @@ -21,89 +21,62 @@ namespace XCharts public override string ClassName { get { return "Theme"; } } public override void OnGUI(Rect pos, SerializedProperty prop, GUIContent label) { - if (prop.objectReferenceValue == null) - { - EditorGUI.ObjectField(pos, prop, new GUIContent("Theme")); - return; - } base.OnGUI(pos, prop, label); var defaultWidth = pos.width; var defaultX = pos.x; var btnWidth = 50; - ChartEditorHelper.MakeFoldout(ref m_DrawRect, ref m_ThemeModuleToggle, "Theme"); - m_Heights[m_KeyName] += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; - if (m_ThemeModuleToggle) + if (MakeFoldout(prop, "")) { - m_DrawRect.x = defaultX + defaultWidth - 3 * btnWidth - 2; - m_DrawRect.width = btnWidth; + var btnRect = new Rect(m_DrawRect); + btnRect.x = defaultX + defaultWidth - 2 * btnWidth - 2; + btnRect.y = m_DrawRect.y - EditorGUIUtility.singleLineHeight - 3; + btnRect.width = btnWidth; var chart = prop.serializedObject.targetObject as BaseChart; var lastFont = chart.theme.font; #if dUI_TextMeshPro var lastTMPFont = chart.theme.tmpFont; #endif - if (GUI.Button(m_DrawRect, new GUIContent("Reset", "Reset to theme default color"))) + if (GUI.Button(btnRect, new GUIContent("Reset", "Reset to theme default color"))) { chart.theme.ResetTheme(); chart.RefreshAllComponent(); } - m_DrawRect.x = defaultX + defaultWidth - 2 * btnWidth - 2; - m_DrawRect.width = btnWidth; - if (GUI.Button(m_DrawRect, new GUIContent("Unbind", "Unbind the Theme from another chart"))) - { - chart.UnbindTheme(); - } - m_DrawRect.x = defaultX + defaultWidth - btnWidth; - m_DrawRect.width = btnWidth; - if (GUI.Button(m_DrawRect, new GUIContent("Export", "Export theme to asset for a new theme"))) + btnRect.x = defaultX + defaultWidth - btnWidth; + btnRect.width = btnWidth; + if (GUI.Button(btnRect, new GUIContent("Export", "Export theme to asset for a new theme"))) { ExportThemeWindow.target = chart; EditorWindow.GetWindow(typeof(ExportThemeWindow)); } - - var data = (ScriptableObject)prop.objectReferenceValue; - SerializedObject serializedObject = new SerializedObject(data); - SerializedProperty newProp = serializedObject.GetIterator(); - float y = pos.y + EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; ++EditorGUI.indentLevel; - - var chartNameList = XChartsMgr.GetAllThemeNames(); + var chartNameList = XThemeMgr.GetAllThemeNames(); var lastIndex = chartNameList.IndexOf(chart.theme.themeName); + var y = pos.y + EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; var selectedIndex = EditorGUI.Popup(new Rect(pos.x, y, pos.width, EditorGUIUtility.singleLineHeight), "Theme", lastIndex, chartNameList.ToArray()); - m_Heights[m_KeyName] += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; - y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; + AddSingleLineHeight(); if (lastIndex != selectedIndex) { - GUI.changed = true; - XChartsMgr.SwitchTheme(chart, chartNameList[selectedIndex]); + XThemeMgr.SwitchTheme(chart, chartNameList[selectedIndex]); } - if (newProp.NextVisible(true)) - { - do - { - if (newProp.name == "m_Script") continue; - if (newProp.name == "m_ThemeName") continue; - if (newProp.name == "m_Theme") continue; - - AddPropertyField(pos, newProp, ref y); - - } while (newProp.NextVisible(false)); - } - if (GUI.changed) - { - chart.RefreshAllComponent(); - serializedObject.ApplyModifiedProperties(); - } - if (chart.theme.font != lastFont) - { - chart.theme.SyncFontToSubComponent(); - } -#if dUI_TextMeshPro - if (chart.theme.tmpFont != lastTMPFont) - { - chart.theme.SyncTMPFontToSubComponent(); - } -#endif + PropertyField(prop, "m_Font"); + PropertyField(prop, "m_ContrastColor"); + PropertyField(prop, "m_BackgroundColor"); + PropertyField(prop, "m_ColorPalette"); + PropertyField(prop, "m_Common"); + PropertyField(prop, "m_Title"); + PropertyField(prop, "m_SubTitle"); + PropertyField(prop, "m_Legend"); + PropertyField(prop, "m_Axis"); + PropertyField(prop, "m_RadiusAxis"); + PropertyField(prop, "m_AngleAxis"); + PropertyField(prop, "m_Polar"); + PropertyField(prop, "m_Gauge"); + PropertyField(prop, "m_Radar"); + PropertyField(prop, "m_Tooltip"); + PropertyField(prop, "m_DataZoom"); + PropertyField(prop, "m_VisualMap"); + PropertyField(prop, "m_Serie"); --EditorGUI.indentLevel; } } @@ -154,7 +127,7 @@ namespace XCharts } else { - GUILayout.Label(XChartsMgr.GetThemeAssetPath(m_ChartName)); + GUILayout.Label(XThemeMgr.GetThemeAssetPath(m_ChartName)); } GUILayout.Space(20); @@ -164,20 +137,20 @@ namespace XCharts { ShowNotification(new GUIContent("ERROR:Need input a new name!")); } - else if (XChartsMgr.ContainsTheme(m_ChartName)) + else if (XThemeMgr.ContainsTheme(m_ChartName)) { ShowNotification(new GUIContent("ERROR:The name you entered is already in use!")); } - else if (IsAssetsExist(XChartsMgr.GetThemeAssetPath(m_ChartName))) + else if (IsAssetsExist(XThemeMgr.GetThemeAssetPath(m_ChartName))) { ShowNotification(new GUIContent("ERROR:The asset is exist! \npath=" - + XChartsMgr.GetThemeAssetPath(m_ChartName))); + + XThemeMgr.GetThemeAssetPath(m_ChartName))); } else { - XChartsMgr.ExportTheme(target.theme, m_ChartName); + XThemeMgr.ExportTheme(target.theme, m_ChartName); ShowNotification(new GUIContent("SUCCESS:The theme is exported. \npath=" - + XChartsMgr.GetThemeAssetPath(m_ChartName))); + + XThemeMgr.GetThemeAssetPath(m_ChartName))); } } } diff --git a/Editor/Utility/ChartEditorHelper.cs b/Editor/Utility/ChartEditorHelper.cs index 9ae2aea9..b11f54e5 100644 --- a/Editor/Utility/ChartEditorHelper.cs +++ b/Editor/Utility/ChartEditorHelper.cs @@ -1,16 +1,17 @@ using UnityEngine; using UnityEditor; using System.Collections.Generic; -using XCharts; -public class ChartEditorHelper +namespace XCharts { + public class ChartEditorHelper + { #if UNITY_2019_3_OR_NEWER - public const float INDENT_WIDTH = 15; - public const float BOOL_WIDTH = 15; - public const float ARROW_WIDTH = 20; - public const float BLOCK_WIDTH = 4; - public const float GAP_WIDTH = 2; + public const float INDENT_WIDTH = 15; + public const float BOOL_WIDTH = 15; + public const float ARROW_WIDTH = 20; + public const float BLOCK_WIDTH = 4; + public const float GAP_WIDTH = 2; #else public const float INDENT_WIDTH = 15; public const float BOOL_WIDTH = 15; @@ -19,470 +20,471 @@ public class ChartEditorHelper public const float GAP_WIDTH = 0; #endif - public class Styles - { - public static readonly GUIStyle headerStyle = EditorStyles.boldLabel; - public static readonly GUIStyle foldoutStyle = new GUIStyle(EditorStyles.foldout) + public class Styles { - font = headerStyle.font, - fontStyle = headerStyle.fontStyle, - }; - public static readonly GUIContent iconAdd = new GUIContent("+", "Add"); - public static readonly GUIContent iconRemove = new GUIContent("-", "Remove"); - public static readonly GUIContent iconUp = new GUIContent("↑", "Up"); - public static readonly GUIContent iconDown = new GUIContent("↓", "Down"); - public static readonly GUIStyle invisibleButton = "InvisibleButton"; - } + public static readonly GUIStyle headerStyle = EditorStyles.boldLabel; + public static readonly GUIStyle foldoutStyle = new GUIStyle(EditorStyles.foldout) + { + font = headerStyle.font, + fontStyle = headerStyle.fontStyle, + }; + public static readonly GUIContent iconAdd = new GUIContent("+", "Add"); + public static readonly GUIContent iconRemove = new GUIContent("-", "Remove"); + public static readonly GUIContent iconUp = new GUIContent("↑", "Up"); + public static readonly GUIContent iconDown = new GUIContent("↓", "Down"); + public static readonly GUIStyle invisibleButton = "InvisibleButton"; + } - public static void SecondField(Rect drawRect, SerializedProperty prop) - { - RectOffset offset = new RectOffset(-(int)EditorGUIUtility.labelWidth, 0, 0, 0); - drawRect = offset.Add(drawRect); - EditorGUI.PropertyField(drawRect, prop, GUIContent.none); - drawRect = offset.Remove(drawRect); - } + public static void SecondField(Rect drawRect, SerializedProperty prop) + { + RectOffset offset = new RectOffset(-(int)EditorGUIUtility.labelWidth, 0, 0, 0); + drawRect = offset.Add(drawRect); + EditorGUI.PropertyField(drawRect, prop, GUIContent.none); + drawRect = offset.Remove(drawRect); + } - public static void MakeTwoField(ref Rect drawRect, float rectWidth, SerializedProperty arrayProp, - string name) - { - while (arrayProp.arraySize < 2) arrayProp.arraySize++; - var prop1 = arrayProp.GetArrayElementAtIndex(0); - var prop2 = arrayProp.GetArrayElementAtIndex(1); - MakeTwoField(ref drawRect, rectWidth, prop1, prop2, name); - } + public static void MakeTwoField(ref Rect drawRect, float rectWidth, SerializedProperty arrayProp, + string name) + { + while (arrayProp.arraySize < 2) arrayProp.arraySize++; + var prop1 = arrayProp.GetArrayElementAtIndex(0); + var prop2 = arrayProp.GetArrayElementAtIndex(1); + MakeTwoField(ref drawRect, rectWidth, prop1, prop2, name); + } - public static void MakeDivideList(ref Rect drawRect, float rectWidth, SerializedProperty arrayProp, - string name, int showNum) - { - while (arrayProp.arraySize < showNum) arrayProp.arraySize++; - EditorGUI.LabelField(drawRect, name); + public static void MakeDivideList(ref Rect drawRect, float rectWidth, SerializedProperty arrayProp, + string name, int showNum) + { + while (arrayProp.arraySize < showNum) arrayProp.arraySize++; + EditorGUI.LabelField(drawRect, name); #if UNITY_2019_3_OR_NEWER - var gap = 2; + var gap = 2; #else var gap = 0; #endif - var startX = drawRect.x + EditorGUIUtility.labelWidth - EditorGUI.indentLevel * INDENT_WIDTH + gap; - var dataWidTotal = (rectWidth - (startX + INDENT_WIDTH + 1)); - EditorGUI.DrawRect(new Rect(startX, drawRect.y, dataWidTotal, drawRect.height), Color.grey); - var dataWid = dataWidTotal / showNum; - var xWid = dataWid - gap; - for (int i = 0; i < 1; i++) - { - drawRect.x = startX + i * xWid; - drawRect.width = dataWid + (EditorGUI.indentLevel - 2) * 40.5f; - EditorGUI.PropertyField(drawRect, arrayProp.GetArrayElementAtIndex(i), GUIContent.none); - } - drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; - } - - public static void MakeTwoField(ref Rect drawRect, float rectWidth, SerializedProperty prop1, - SerializedProperty prop2, string name) - { - EditorGUI.LabelField(drawRect, name); - var startX = drawRect.x + EditorGUIUtility.labelWidth - EditorGUI.indentLevel * INDENT_WIDTH + GAP_WIDTH; - var diff = 14 + EditorGUI.indentLevel * 14; - var offset = diff - INDENT_WIDTH; - var tempWidth = (rectWidth - startX + diff) / 2; - var centerXRect = new Rect(startX, drawRect.y, tempWidth, drawRect.height); - var centerYRect = new Rect(centerXRect.x + tempWidth - offset, drawRect.y, tempWidth, drawRect.height); - EditorGUI.PropertyField(centerXRect, prop1, GUIContent.none); - EditorGUI.PropertyField(centerYRect, prop2, GUIContent.none); - drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; - } - - public static void MakeVector2(ref Rect drawRect, float rectWidth, SerializedProperty prop, string name) - { - EditorGUI.LabelField(drawRect, name); - var startX = drawRect.x + EditorGUIUtility.labelWidth - EditorGUI.indentLevel * INDENT_WIDTH + GAP_WIDTH; - var diff = 14 + EditorGUI.indentLevel * 14; - var offset = diff - INDENT_WIDTH; - var tempWidth = (rectWidth - startX + diff) / 2; - var centerXRect = new Rect(startX, drawRect.y, tempWidth, drawRect.height); - var centerYRect = new Rect(centerXRect.x + tempWidth - offset, drawRect.y, tempWidth, drawRect.height); - var x = EditorGUI.FloatField(centerXRect, prop.vector3Value.x); - var y = EditorGUI.FloatField(centerYRect, prop.vector3Value.y); - prop.vector3Value = new Vector3(x, y); - drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; - } - - public static void MakeJsonData(ref Rect drawRect, ref bool showTextArea, ref string inputString, - SerializedProperty prop, float currentWidth, float diff = 0) - { - SerializedProperty stringDataProp = prop.FindPropertyRelative("m_JsonData"); - SerializedProperty needParseProp = prop.FindPropertyRelative("m_DataFromJson"); - float defalutX = drawRect.x; - drawRect.x = EditorGUIUtility.labelWidth + ARROW_WIDTH + diff; - drawRect.width = currentWidth - EditorGUIUtility.labelWidth - GAP_WIDTH - diff; - if (GUI.Button(drawRect, new GUIContent("Parse JsonData", "Parse data from input json"))) - { - showTextArea = !showTextArea; - bool needParse = !showTextArea; - if (needParse) + var startX = drawRect.x + EditorGUIUtility.labelWidth - EditorGUI.indentLevel * INDENT_WIDTH + gap; + var dataWidTotal = (rectWidth - (startX + INDENT_WIDTH + 1)); + EditorGUI.DrawRect(new Rect(startX, drawRect.y, dataWidTotal, drawRect.height), Color.grey); + var dataWid = dataWidTotal / showNum; + var xWid = dataWid - gap; + for (int i = 0; i < 1; i++) { - stringDataProp.stringValue = inputString; - needParseProp.boolValue = true; + drawRect.x = startX + i * xWid; + drawRect.width = dataWid + (EditorGUI.indentLevel - 2) * 40.5f; + EditorGUI.PropertyField(drawRect, arrayProp.GetArrayElementAtIndex(i), GUIContent.none); } + drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; } - drawRect.x = defalutX; - drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; - if (showTextArea) + + public static void MakeTwoField(ref Rect drawRect, float rectWidth, SerializedProperty prop1, + SerializedProperty prop2, string name) { - drawRect.width = currentWidth; - drawRect.height = EditorGUIUtility.singleLineHeight * 4; - inputString = EditorGUI.TextArea(drawRect, inputString); - drawRect.y += EditorGUIUtility.singleLineHeight * 4 + EditorGUIUtility.standardVerticalSpacing; - drawRect.height = EditorGUIUtility.singleLineHeight; + EditorGUI.LabelField(drawRect, name); + var startX = drawRect.x + EditorGUIUtility.labelWidth - EditorGUI.indentLevel * INDENT_WIDTH + GAP_WIDTH; + var diff = 14 + EditorGUI.indentLevel * 14; + var offset = diff - INDENT_WIDTH; + var tempWidth = (rectWidth - startX + diff) / 2; + var centerXRect = new Rect(startX, drawRect.y, tempWidth, drawRect.height); + var centerYRect = new Rect(centerXRect.x + tempWidth - offset, drawRect.y, tempWidth, drawRect.height); + EditorGUI.PropertyField(centerXRect, prop1, GUIContent.none); + EditorGUI.PropertyField(centerYRect, prop2, GUIContent.none); + drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; } - } - public static bool MakeFoldout(ref Rect drawRect, ref bool moduleToggle, string content, - SerializedProperty prop = null, bool bold = false) - { - float defaultWidth = drawRect.width; - float defaultX = drawRect.x; - var style = bold ? Styles.foldoutStyle : EditorStyles.foldout; - drawRect.width = EditorGUIUtility.labelWidth - EditorGUI.indentLevel * INDENT_WIDTH; - moduleToggle = EditorGUI.Foldout(drawRect, moduleToggle, content, true, style); - MakeBool(drawRect, prop); - drawRect.width = defaultWidth; - drawRect.x = defaultX; - return moduleToggle; - } - - public static bool MakeFoldout(ref Rect drawRect, Dictionary heights, - Dictionary moduleToggle, string key, string content, SerializedProperty prop, bool bold = false) - { - float defaultWidth = drawRect.width; - float defaultX = drawRect.x; - var style = bold ? Styles.foldoutStyle : EditorStyles.foldout; - drawRect.width = EditorGUIUtility.labelWidth; - moduleToggle[key] = EditorGUI.Foldout(drawRect, moduleToggle[key], content, true, style); - if (prop != null) + public static void MakeVector2(ref Rect drawRect, float rectWidth, SerializedProperty prop, string name) { - if (prop.propertyType == SerializedPropertyType.Boolean) + EditorGUI.LabelField(drawRect, name); + var startX = drawRect.x + EditorGUIUtility.labelWidth - EditorGUI.indentLevel * INDENT_WIDTH + GAP_WIDTH; + var diff = 14 + EditorGUI.indentLevel * 14; + var offset = diff - INDENT_WIDTH; + var tempWidth = (rectWidth - startX + diff) / 2; + var centerXRect = new Rect(startX, drawRect.y, tempWidth, drawRect.height); + var centerYRect = new Rect(centerXRect.x + tempWidth - offset, drawRect.y, tempWidth, drawRect.height); + var x = EditorGUI.FloatField(centerXRect, prop.vector3Value.x); + var y = EditorGUI.FloatField(centerYRect, prop.vector3Value.y); + prop.vector3Value = new Vector3(x, y); + drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; + } + + public static void MakeJsonData(ref Rect drawRect, ref bool showTextArea, ref string inputString, + SerializedProperty prop, float currentWidth, float diff = 0) + { + SerializedProperty stringDataProp = prop.FindPropertyRelative("m_JsonData"); + SerializedProperty needParseProp = prop.FindPropertyRelative("m_DataFromJson"); + float defalutX = drawRect.x; + drawRect.x = EditorGUIUtility.labelWidth + ARROW_WIDTH + diff; + drawRect.width = currentWidth - EditorGUIUtility.labelWidth - GAP_WIDTH - diff; + if (GUI.Button(drawRect, new GUIContent("Parse JsonData", "Parse data from input json"))) { - MakeBool(drawRect, prop); - } - else - { - drawRect.x = EditorGUIUtility.labelWidth - EditorGUI.indentLevel * INDENT_WIDTH + ARROW_WIDTH; - drawRect.width = defaultWidth - drawRect.x + ARROW_WIDTH - 2; - if (XChartsSettings.editorBlockEnable) + showTextArea = !showTextArea; + bool needParse = !showTextArea; + if (needParse) { - drawRect.x += BLOCK_WIDTH; + stringDataProp.stringValue = inputString; + needParseProp.boolValue = true; } - - EditorGUI.PropertyField(drawRect, prop, GUIContent.none); } - } - - drawRect.width = defaultWidth; - drawRect.x = defaultX; - drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; - heights[key] += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; - return moduleToggle[key]; - } - - public static void MakeBool(Rect drawRect, SerializedProperty boolProp, int index = 0, string name = null) - { - float defaultWidth = drawRect.width; - float defaultX = drawRect.x; - float boolWidth = index * (BOOL_WIDTH + GAP_WIDTH); - drawRect.x = EditorGUIUtility.labelWidth - EditorGUI.indentLevel * INDENT_WIDTH + ARROW_WIDTH + boolWidth; - if (XChartsSettings.editorBlockEnable) - { - drawRect.x += BLOCK_WIDTH; - } - drawRect.width = (EditorGUI.indentLevel + 1) * BOOL_WIDTH + index * 110; - if (boolProp != null) - { - EditorGUI.PropertyField(drawRect, boolProp, GUIContent.none); - if (!string.IsNullOrEmpty(name)) + drawRect.x = defalutX; + drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; + if (showTextArea) { - drawRect.x += BOOL_WIDTH; - drawRect.width = 200; - EditorGUI.LabelField(drawRect, name); + drawRect.width = currentWidth; + drawRect.height = EditorGUIUtility.singleLineHeight * 4; + inputString = EditorGUI.TextArea(drawRect, inputString); + drawRect.y += EditorGUIUtility.singleLineHeight * 4 + EditorGUIUtility.standardVerticalSpacing; + drawRect.height = EditorGUIUtility.singleLineHeight; } } - drawRect.width = defaultWidth; - drawRect.x = defaultX; - } - public static bool MakeFoldout(ref Rect drawRect, ref float height, ref Dictionary moduleToggle, - SerializedProperty prop, string moduleName, string showPropName, bool bold = false) - { - var relativeProp = prop.FindPropertyRelative(showPropName); - var flag = MakeFoldout(ref drawRect, ref moduleToggle, prop, moduleName, relativeProp, bold); - drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; - height += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; - return flag; - } - - public static bool MakeFoldout(ref Rect drawRect, ref Dictionary moduleToggle, SerializedProperty prop, - string moduleName, SerializedProperty showProp = null, bool bold = false) - { - var key = prop.propertyPath; - if (!moduleToggle.ContainsKey(key)) + public static bool MakeFoldout(ref Rect drawRect, ref bool moduleToggle, string content, + SerializedProperty prop = null, bool bold = false) { - moduleToggle.Add(key, false); + float defaultWidth = drawRect.width; + float defaultX = drawRect.x; + var style = bold ? Styles.foldoutStyle : EditorStyles.foldout; + drawRect.width = EditorGUIUtility.labelWidth - EditorGUI.indentLevel * INDENT_WIDTH; + moduleToggle = EditorGUI.Foldout(drawRect, moduleToggle, content, true, style); + MakeBool(drawRect, prop); + drawRect.width = defaultWidth; + drawRect.x = defaultX; + return moduleToggle; } - var toggle = moduleToggle[key]; - float defaultWidth = drawRect.width; - float defaultX = drawRect.x; -#if UNITY_2019_3_OR_NEWER - drawRect.width = EditorGUIUtility.labelWidth - EditorGUI.indentLevel * INDENT_WIDTH; -#else - drawRect.width = EditorGUIUtility.labelWidth; -#endif - var displayName = string.IsNullOrEmpty(moduleName) ? prop.displayName : moduleName; - var foldoutStyle = bold ? Styles.foldoutStyle : EditorStyles.foldout; - toggle = EditorGUI.Foldout(drawRect, toggle, displayName, true, foldoutStyle); - - if (moduleToggle[key] != toggle) + public static bool MakeFoldout(ref Rect drawRect, Dictionary heights, + Dictionary moduleToggle, string key, string content, SerializedProperty prop, bool bold = false) { - moduleToggle[key] = toggle; - } - if (showProp != null) - { - drawRect.x = EditorGUIUtility.labelWidth - EditorGUI.indentLevel * INDENT_WIDTH + ARROW_WIDTH; - if (showProp.propertyType == SerializedPropertyType.Boolean) + float defaultWidth = drawRect.width; + float defaultX = drawRect.x; + var style = bold ? Styles.foldoutStyle : EditorStyles.foldout; + drawRect.width = EditorGUIUtility.labelWidth; + moduleToggle[key] = EditorGUI.Foldout(drawRect, moduleToggle[key], content, true, style); + if (prop != null) { - drawRect.width = (EditorGUI.indentLevel + 1) * BOOL_WIDTH; - } - else - { - drawRect.width = defaultWidth - drawRect.x + ARROW_WIDTH - GAP_WIDTH; + if (prop.propertyType == SerializedPropertyType.Boolean) + { + MakeBool(drawRect, prop); + } + else + { + drawRect.x = EditorGUIUtility.labelWidth - EditorGUI.indentLevel * INDENT_WIDTH + ARROW_WIDTH; + drawRect.width = defaultWidth - drawRect.x + ARROW_WIDTH - 2; + if (XChartsSettings.editorBlockEnable) + { + drawRect.x += BLOCK_WIDTH; + } + + EditorGUI.PropertyField(drawRect, prop, GUIContent.none); + } } + + drawRect.width = defaultWidth; + drawRect.x = defaultX; + drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; + heights[key] += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; + return moduleToggle[key]; + } + + public static void MakeBool(Rect drawRect, SerializedProperty boolProp, int index = 0, string name = null) + { + float defaultWidth = drawRect.width; + float defaultX = drawRect.x; + float boolWidth = index * (BOOL_WIDTH + GAP_WIDTH); + drawRect.x = EditorGUIUtility.labelWidth - EditorGUI.indentLevel * INDENT_WIDTH + ARROW_WIDTH + boolWidth; if (XChartsSettings.editorBlockEnable) { drawRect.x += BLOCK_WIDTH; } - EditorGUI.PropertyField(drawRect, showProp, GUIContent.none); - } - drawRect.width = defaultWidth; - drawRect.x = defaultX; - return toggle; - } - - public static bool MakeListWithFoldout(ref Rect drawRect, SerializedProperty listProp, bool foldout, - bool showOrder = false, bool showSize = true) - { - var height = 0f; - return MakeListWithFoldout(ref drawRect, ref height, listProp, foldout, showOrder, showSize); - } - - public static bool MakeListWithFoldout(ref Rect drawRect, ref float height, SerializedProperty listProp, - bool foldout, bool showOrder = false, bool showSize = true) - { - var rawWidth = drawRect.width; - drawRect.width = EditorGUIUtility.labelWidth + 10; - bool flag = EditorGUI.Foldout(drawRect, foldout, listProp.displayName, true); - height += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; - drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; - drawRect.width = rawWidth; - if (flag) - { - MakeList(ref drawRect, ref height, listProp, showOrder, showSize); - } - return flag; - } - - public static void MakeList(ref Rect drawRect, SerializedProperty listProp, bool showOrder = false, - bool showSize = true) - { - var height = 0f; - MakeList(ref drawRect, ref height, listProp, showOrder, showSize); - } - - public static void MakeList(ref Rect drawRect, ref float height, SerializedProperty listProp, - bool showOrder = false, bool showSize = true) - { - EditorGUI.indentLevel++; - var listSize = listProp.arraySize; - var iconWidth = 14; - var iconGap = 3f; - if (showSize) - { - if (showOrder) + drawRect.width = (EditorGUI.indentLevel + 1) * BOOL_WIDTH + index * 110; + if (boolProp != null) { - var temp = INDENT_WIDTH + GAP_WIDTH + iconGap; - var elementRect = new Rect(drawRect.x, drawRect.y, drawRect.width - iconWidth + 2, drawRect.height); - var iconRect = new Rect(drawRect.width - iconWidth + temp, drawRect.y, iconWidth, drawRect.height); - if (XChartsSettings.editorBlockEnable) + EditorGUI.PropertyField(drawRect, boolProp, GUIContent.none); + if (!string.IsNullOrEmpty(name)) { - iconRect.x += BLOCK_WIDTH; + drawRect.x += BOOL_WIDTH; + drawRect.width = 200; + EditorGUI.LabelField(drawRect, name); } - var oldColor = GUI.contentColor; - GUI.contentColor = Color.black; - if (GUI.Button(iconRect, Styles.iconAdd, Styles.invisibleButton)) - { - if (listProp.displayName.Equals("Series")) - { - AddSerieEditor.chart = listProp.serializedObject.targetObject as BaseChart; - AddSerieEditor.ShowWindow(); - } - else - { - listProp.arraySize++; - } - } - GUI.contentColor = oldColor; - listSize = listProp.arraySize; - listSize = EditorGUI.IntField(elementRect, "Size", listSize); } - else - { - listSize = EditorGUI.IntField(drawRect, "Size", listSize); - } - if (listSize < 0) listSize = 0; + drawRect.width = defaultWidth; + drawRect.x = defaultX; + } + + public static bool MakeFoldout(ref Rect drawRect, ref float height, ref Dictionary moduleToggle, + SerializedProperty prop, string moduleName, string showPropName, bool bold = false) + { + var relativeProp = prop.FindPropertyRelative(showPropName); + var flag = MakeFoldout(ref drawRect, ref moduleToggle, prop, moduleName, relativeProp, bold); drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; height += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; + return flag; + } - if (listSize != listProp.arraySize) - { - while (listSize > listProp.arraySize) listProp.arraySize++; - while (listSize < listProp.arraySize) listProp.arraySize--; - } - } - if (listSize > 30 && !XChartsSettings.editorShowAllListData) + public static bool MakeFoldout(ref Rect drawRect, ref Dictionary moduleToggle, SerializedProperty prop, + string moduleName, SerializedProperty showProp = null, bool bold = false) { - SerializedProperty element; - int num = listSize > 10 ? 10 : listSize; - for (int i = 0; i < num; i++) + var key = prop.propertyPath; + if (!moduleToggle.ContainsKey(key)) { - element = listProp.GetArrayElementAtIndex(i); - EditorGUI.PropertyField(drawRect, element, new GUIContent("Element " + i)); - drawRect.y += EditorGUI.GetPropertyHeight(element) + EditorGUIUtility.standardVerticalSpacing; - height += EditorGUI.GetPropertyHeight(element) + EditorGUIUtility.standardVerticalSpacing; + moduleToggle.Add(key, false); } - if (num >= 10) + var toggle = moduleToggle[key]; + + float defaultWidth = drawRect.width; + float defaultX = drawRect.x; +#if UNITY_2019_3_OR_NEWER + drawRect.width = EditorGUIUtility.labelWidth - EditorGUI.indentLevel * INDENT_WIDTH; +#else + drawRect.width = EditorGUIUtility.labelWidth; +#endif + var displayName = string.IsNullOrEmpty(moduleName) ? prop.displayName : moduleName; + var foldoutStyle = bold ? Styles.foldoutStyle : EditorStyles.foldout; + toggle = EditorGUI.Foldout(drawRect, toggle, displayName, true, foldoutStyle); + + if (moduleToggle[key] != toggle) { - EditorGUI.LabelField(drawRect, "..."); - drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; - height += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; - element = listProp.GetArrayElementAtIndex(listSize - 1); - EditorGUI.PropertyField(drawRect, element, new GUIContent("Element " + (listSize - 1))); - drawRect.y += EditorGUI.GetPropertyHeight(element) + EditorGUIUtility.standardVerticalSpacing; - height += EditorGUI.GetPropertyHeight(element) + EditorGUIUtility.standardVerticalSpacing; + moduleToggle[key] = toggle; } + if (showProp != null) + { + drawRect.x = EditorGUIUtility.labelWidth - EditorGUI.indentLevel * INDENT_WIDTH + ARROW_WIDTH; + if (showProp.propertyType == SerializedPropertyType.Boolean) + { + drawRect.width = (EditorGUI.indentLevel + 1) * BOOL_WIDTH; + } + else + { + drawRect.width = defaultWidth - drawRect.x + ARROW_WIDTH - GAP_WIDTH; + } + if (XChartsSettings.editorBlockEnable) + { + drawRect.x += BLOCK_WIDTH; + } + EditorGUI.PropertyField(drawRect, showProp, GUIContent.none); + } + drawRect.width = defaultWidth; + drawRect.x = defaultX; + return toggle; } - else + + public static bool MakeListWithFoldout(ref Rect drawRect, SerializedProperty listProp, bool foldout, + bool showOrder = false, bool showSize = true) { - for (int i = 0; i < listProp.arraySize; i++) + var height = 0f; + return MakeListWithFoldout(ref drawRect, ref height, listProp, foldout, showOrder, showSize); + } + + public static bool MakeListWithFoldout(ref Rect drawRect, ref float height, SerializedProperty listProp, + bool foldout, bool showOrder = false, bool showSize = true) + { + var rawWidth = drawRect.width; + drawRect.width = EditorGUIUtility.labelWidth + 10; + bool flag = EditorGUI.Foldout(drawRect, foldout, listProp.displayName, true); + height += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; + drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; + drawRect.width = rawWidth; + if (flag) + { + MakeList(ref drawRect, ref height, listProp, showOrder, showSize); + } + return flag; + } + + public static void MakeList(ref Rect drawRect, SerializedProperty listProp, bool showOrder = false, + bool showSize = true) + { + var height = 0f; + MakeList(ref drawRect, ref height, listProp, showOrder, showSize); + } + + public static void MakeList(ref Rect drawRect, ref float height, SerializedProperty listProp, + bool showOrder = false, bool showSize = true) + { + EditorGUI.indentLevel++; + var listSize = listProp.arraySize; + var iconWidth = 14; + var iconGap = 3f; + if (showSize) { - SerializedProperty element = listProp.GetArrayElementAtIndex(i); if (showOrder) { var temp = INDENT_WIDTH + GAP_WIDTH + iconGap; - var isSerie = "Serie".Equals(element.type); - var elementRect = isSerie - ? new Rect(drawRect.x, drawRect.y, drawRect.width + INDENT_WIDTH - 2 * iconGap, drawRect.height) - : new Rect(drawRect.x, drawRect.y, drawRect.width - 3 * iconWidth, drawRect.height); - EditorGUI.PropertyField(elementRect, element, new GUIContent("Element " + i)); - var iconRect = new Rect(drawRect.width - 3 * iconWidth + temp, drawRect.y, iconWidth, drawRect.height); + var elementRect = new Rect(drawRect.x, drawRect.y, drawRect.width - iconWidth + 2, drawRect.height); + var iconRect = new Rect(drawRect.width - iconWidth + temp, drawRect.y, iconWidth, drawRect.height); if (XChartsSettings.editorBlockEnable) { iconRect.x += BLOCK_WIDTH; } var oldColor = GUI.contentColor; GUI.contentColor = Color.black; - if (GUI.Button(iconRect, Styles.iconUp, Styles.invisibleButton)) + if (GUI.Button(iconRect, Styles.iconAdd, Styles.invisibleButton)) { - if (i > 0) listProp.MoveArrayElement(i, i - 1); - } - iconRect = new Rect(drawRect.width - 2 * iconWidth + temp, drawRect.y, iconWidth, drawRect.height); - if (XChartsSettings.editorBlockEnable) - { - iconRect.x += BLOCK_WIDTH; - } - if (GUI.Button(iconRect, Styles.iconDown, Styles.invisibleButton)) - { - if (i < listProp.arraySize - 1) listProp.MoveArrayElement(i, i + 1); - } - iconRect = new Rect(drawRect.width - iconWidth + temp, drawRect.y, iconWidth, drawRect.height); - if (XChartsSettings.editorBlockEnable) - { - iconRect.x += BLOCK_WIDTH; - } - if (GUI.Button(iconRect, Styles.iconRemove, Styles.invisibleButton)) - { - if (i < listProp.arraySize && i >= 0) listProp.DeleteArrayElementAtIndex(i); - } - else - { - drawRect.y += EditorGUI.GetPropertyHeight(element) + EditorGUIUtility.standardVerticalSpacing; - height += EditorGUI.GetPropertyHeight(element) + EditorGUIUtility.standardVerticalSpacing; + if (listProp.displayName.Equals("Series")) + { + AddSerieEditor.chart = listProp.serializedObject.targetObject as BaseChart; + AddSerieEditor.ShowWindow(); + } + else + { + listProp.arraySize++; + } } GUI.contentColor = oldColor; + listSize = listProp.arraySize; + listSize = EditorGUI.IntField(elementRect, "Size", listSize); } else { + listSize = EditorGUI.IntField(drawRect, "Size", listSize); + } + if (listSize < 0) listSize = 0; + drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; + height += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; + + if (listSize != listProp.arraySize) + { + while (listSize > listProp.arraySize) listProp.arraySize++; + while (listSize < listProp.arraySize) listProp.arraySize--; + } + } + if (listSize > 30 && !XChartsSettings.editorShowAllListData) + { + SerializedProperty element; + int num = listSize > 10 ? 10 : listSize; + for (int i = 0; i < num; i++) + { + element = listProp.GetArrayElementAtIndex(i); EditorGUI.PropertyField(drawRect, element, new GUIContent("Element " + i)); drawRect.y += EditorGUI.GetPropertyHeight(element) + EditorGUIUtility.standardVerticalSpacing; height += EditorGUI.GetPropertyHeight(element) + EditorGUIUtility.standardVerticalSpacing; } + if (num >= 10) + { + EditorGUI.LabelField(drawRect, "..."); + drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; + height += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; + element = listProp.GetArrayElementAtIndex(listSize - 1); + EditorGUI.PropertyField(drawRect, element, new GUIContent("Element " + (listSize - 1))); + drawRect.y += EditorGUI.GetPropertyHeight(element) + EditorGUIUtility.standardVerticalSpacing; + height += EditorGUI.GetPropertyHeight(element) + EditorGUIUtility.standardVerticalSpacing; + } } + else + { + for (int i = 0; i < listProp.arraySize; i++) + { + SerializedProperty element = listProp.GetArrayElementAtIndex(i); + if (showOrder) + { + var temp = INDENT_WIDTH + GAP_WIDTH + iconGap; + var isSerie = "Serie".Equals(element.type); + var elementRect = isSerie + ? new Rect(drawRect.x, drawRect.y, drawRect.width + INDENT_WIDTH - 2 * iconGap, drawRect.height) + : new Rect(drawRect.x, drawRect.y, drawRect.width - 3 * iconWidth, drawRect.height); + EditorGUI.PropertyField(elementRect, element, new GUIContent("Element " + i)); + var iconRect = new Rect(drawRect.width - 3 * iconWidth + temp, drawRect.y, iconWidth, drawRect.height); + if (XChartsSettings.editorBlockEnable) + { + iconRect.x += BLOCK_WIDTH; + } + var oldColor = GUI.contentColor; + GUI.contentColor = Color.black; + if (GUI.Button(iconRect, Styles.iconUp, Styles.invisibleButton)) + { + if (i > 0) listProp.MoveArrayElement(i, i - 1); + } + iconRect = new Rect(drawRect.width - 2 * iconWidth + temp, drawRect.y, iconWidth, drawRect.height); + if (XChartsSettings.editorBlockEnable) + { + iconRect.x += BLOCK_WIDTH; + } + if (GUI.Button(iconRect, Styles.iconDown, Styles.invisibleButton)) + { + if (i < listProp.arraySize - 1) listProp.MoveArrayElement(i, i + 1); + } + iconRect = new Rect(drawRect.width - iconWidth + temp, drawRect.y, iconWidth, drawRect.height); + if (XChartsSettings.editorBlockEnable) + { + iconRect.x += BLOCK_WIDTH; + } + if (GUI.Button(iconRect, Styles.iconRemove, Styles.invisibleButton)) + { + if (i < listProp.arraySize && i >= 0) listProp.DeleteArrayElementAtIndex(i); + } + else + { + drawRect.y += EditorGUI.GetPropertyHeight(element) + EditorGUIUtility.standardVerticalSpacing; + height += EditorGUI.GetPropertyHeight(element) + EditorGUIUtility.standardVerticalSpacing; + } + GUI.contentColor = oldColor; + } + else + { + EditorGUI.PropertyField(drawRect, element, new GUIContent("Element " + i)); + drawRect.y += EditorGUI.GetPropertyHeight(element) + EditorGUIUtility.standardVerticalSpacing; + height += EditorGUI.GetPropertyHeight(element) + EditorGUIUtility.standardVerticalSpacing; + } + } + } + EditorGUI.indentLevel--; } - EditorGUI.indentLevel--; - } - public static bool PropertyField(ref Rect drawRect, Dictionary heights, string key, - SerializedProperty prop) - { - if (prop == null) return false; - EditorGUI.PropertyField(drawRect, prop, true); - var hig = EditorGUI.GetPropertyHeight(prop); - drawRect.y += hig; - heights[key] += hig; - return true; - } + public static bool PropertyField(ref Rect drawRect, Dictionary heights, string key, + SerializedProperty prop) + { + if (prop == null) return false; + EditorGUI.PropertyField(drawRect, prop, true); + var hig = EditorGUI.GetPropertyHeight(prop); + drawRect.y += hig; + heights[key] += hig; + return true; + } - public static bool PropertyFieldWithMinValue(ref Rect drawRect, Dictionary heights, string key, - SerializedProperty prop, float minValue) - { - if (prop == null) return false; - EditorGUI.PropertyField(drawRect, prop, true); - if (prop.propertyType == SerializedPropertyType.Float && prop.floatValue < minValue) - prop.floatValue = minValue; - if (prop.propertyType == SerializedPropertyType.Integer && prop.intValue < minValue) - prop.intValue = (int)minValue; - var hig = EditorGUI.GetPropertyHeight(prop); - drawRect.y += hig; - heights[key] += hig; - return true; - } + public static bool PropertyFieldWithMinValue(ref Rect drawRect, Dictionary heights, string key, + SerializedProperty prop, float minValue) + { + if (prop == null) return false; + EditorGUI.PropertyField(drawRect, prop, true); + if (prop.propertyType == SerializedPropertyType.Float && prop.floatValue < minValue) + prop.floatValue = minValue; + if (prop.propertyType == SerializedPropertyType.Integer && prop.intValue < minValue) + prop.intValue = (int)minValue; + var hig = EditorGUI.GetPropertyHeight(prop); + drawRect.y += hig; + heights[key] += hig; + return true; + } - public static bool PropertyFieldWithMaxValue(ref Rect drawRect, Dictionary heights, string key, - SerializedProperty prop, float maxValue) - { - if (prop == null) return false; - EditorGUI.PropertyField(drawRect, prop, true); - if (prop.propertyType == SerializedPropertyType.Float && prop.floatValue > maxValue) - prop.floatValue = maxValue; - if (prop.propertyType == SerializedPropertyType.Integer && prop.intValue > maxValue) - prop.intValue = (int)maxValue; - var hig = EditorGUI.GetPropertyHeight(prop); - drawRect.y += hig; - heights[key] += hig; - return true; - } + public static bool PropertyFieldWithMaxValue(ref Rect drawRect, Dictionary heights, string key, + SerializedProperty prop, float maxValue) + { + if (prop == null) return false; + EditorGUI.PropertyField(drawRect, prop, true); + if (prop.propertyType == SerializedPropertyType.Float && prop.floatValue > maxValue) + prop.floatValue = maxValue; + if (prop.propertyType == SerializedPropertyType.Integer && prop.intValue > maxValue) + prop.intValue = (int)maxValue; + var hig = EditorGUI.GetPropertyHeight(prop); + drawRect.y += hig; + heights[key] += hig; + return true; + } - public static bool PropertyField(ref Rect drawRect, Dictionary heights, string key, - SerializedProperty parentProp, string relativeName) - { - return PropertyField(ref drawRect, heights, key, parentProp.FindPropertyRelative(relativeName)); - } - public static bool PropertyFieldWithMinValue(ref Rect drawRect, Dictionary heights, string key, - SerializedProperty parentProp, string relativeName, float minValue) - { - var relativeProp = parentProp.FindPropertyRelative(relativeName); - return PropertyFieldWithMinValue(ref drawRect, heights, key, relativeProp, minValue); - } - public static bool PropertyFieldWithMaxValue(ref Rect drawRect, Dictionary heights, string key, - SerializedProperty parentProp, string relativeName, float maxValue) - { - var relativeProp = parentProp.FindPropertyRelative(relativeName); - return PropertyFieldWithMaxValue(ref drawRect, heights, key, relativeProp, maxValue); + public static bool PropertyField(ref Rect drawRect, Dictionary heights, string key, + SerializedProperty parentProp, string relativeName) + { + return PropertyField(ref drawRect, heights, key, parentProp.FindPropertyRelative(relativeName)); + } + public static bool PropertyFieldWithMinValue(ref Rect drawRect, Dictionary heights, string key, + SerializedProperty parentProp, string relativeName, float minValue) + { + var relativeProp = parentProp.FindPropertyRelative(relativeName); + return PropertyFieldWithMinValue(ref drawRect, heights, key, relativeProp, minValue); + } + public static bool PropertyFieldWithMaxValue(ref Rect drawRect, Dictionary heights, string key, + SerializedProperty parentProp, string relativeName, float maxValue) + { + var relativeProp = parentProp.FindPropertyRelative(relativeName); + return PropertyFieldWithMaxValue(ref drawRect, heights, key, relativeProp, maxValue); + } } } \ No newline at end of file diff --git a/Editor/Utility/ThemeCheck.cs b/Editor/Utility/ThemeCheck.cs new file mode 100644 index 00000000..c511cba7 --- /dev/null +++ b/Editor/Utility/ThemeCheck.cs @@ -0,0 +1,60 @@ +using UnityEditor; +using UnityEngine; + +namespace XCharts +{ + internal static class ThemeCheck + { + public class ThemeAssetPostprocessor : AssetPostprocessor + { + static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, + string[] movedFromAssetsPaths) + { + foreach (var assetPath in importedAssets) + { + CheckAddedAsset(assetPath); + } + foreach (var assetPath in deletedAssets) + { + CheckDeletedAsset(assetPath); + } + } + } + + public static void CheckAddedAsset(string assetPath) + { + if (!IsThemeAsset(assetPath)) return; + var obj = AssetDatabase.LoadAssetAtPath(assetPath); + if (XChartsSettings.AddJsonTheme(obj)) + { + XThemeMgr.ReloadThemeList(); + } + } + + public static void CheckDeletedAsset(string assetPath) + { + if (!IsThemeAsset(assetPath)) return; + var themes = XChartsSettings.customThemes; + var changed = false; + + for (int i = themes.Count - 1; i >= 0; i--) + { + if (themes[i] == null) + { + themes.RemoveAt(i); + changed = true; + } + } + if (changed) + { + XThemeMgr.ReloadThemeList(); + } + } + + private static bool IsThemeAsset(string assetPath) + { + if (!assetPath.EndsWith(".json")) return false; + return true; + } + } +} \ No newline at end of file diff --git a/Editor/Utility/ThemeCheck.cs.meta b/Editor/Utility/ThemeCheck.cs.meta new file mode 100644 index 00000000..17375c18 --- /dev/null +++ b/Editor/Utility/ThemeCheck.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4b4ba2a9503ae46b1b7b1ae94ec59127 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/XChartEditor.cs b/Editor/XChartEditor.cs index 884f4b06..5dbcc5fa 100644 --- a/Editor/XChartEditor.cs +++ b/Editor/XChartEditor.cs @@ -156,7 +156,7 @@ namespace XCharts [MenuItem("XCharts/Themes Reload")] public static void ReloadTheme() { - XChartsMgr.Instance.LoadThemesFromResources(); + XThemeMgr.ReloadThemeList(); } [MenuItem("XCharts/TextMeshPro Enable")] diff --git a/Resources/XChartsSettings.asset b/Resources/XChartsSettings.asset index 30563485..45445200 100644 --- a/Resources/XChartsSettings.asset +++ b/Resources/XChartsSettings.asset @@ -37,6 +37,7 @@ MonoBehaviour: m_SerieLineSymbolSelectedSize: 8 m_SerieScatterSymbolSize: 20 m_SerieScatterSymbolSelectedSize: 30 + m_SerieCandlestickBorderWidth: 1 m_EditorBlockEnable: 1 m_EditorShowAllListData: 0 m_MaxPainter: 10 @@ -47,3 +48,5 @@ MonoBehaviour: m_VisualMapTriangeLen: 20 m_PieTooltipExtraRadius: 8 m_PieSelectedOffset: 8 + m_CustomTheme: + - {fileID: 4900000, guid: b3fe66aee71324452a87542f8be66943, type: 3} diff --git a/Runtime/API/BaseChart_API.cs b/Runtime/API/BaseChart_API.cs index 4a0ec14e..253b2ef4 100644 --- a/Runtime/API/BaseChart_API.cs +++ b/Runtime/API/BaseChart_API.cs @@ -719,12 +719,5 @@ namespace XCharts { return SeriesHelper.ContainsSerie(m_Series, serieType); } - - public void UnbindTheme() - { - var theme = m_Theme.CloneTheme(); - m_Theme = theme; - RefreshChart(); - } } } diff --git a/Runtime/Component/Theme/ChartTheme.cs b/Runtime/Component/Theme/ChartTheme.cs index 93524c5c..9e98d2c4 100644 --- a/Runtime/Component/Theme/ChartTheme.cs +++ b/Runtime/Component/Theme/ChartTheme.cs @@ -43,7 +43,7 @@ namespace XCharts /// Theme. /// 主题相关配置。 /// - public class ChartTheme : ScriptableObject + public class ChartTheme : MainComponent { [SerializeField] private Theme m_Theme = Theme.Default; [SerializeField] private string m_ThemeName = Theme.Default.ToString(); @@ -164,12 +164,6 @@ namespace XCharts } } - [NonSerialized] protected bool m_VertsDirty; - [NonSerialized] protected bool m_ComponentDirty; - public virtual bool vertsDirty { get { return m_VertsDirty; } } - public virtual bool componentDirty { get { return m_ComponentDirty; } } - public bool anyDirty { get { return vertsDirty || componentDirty; } } - public void SetDefaultFont() { #if dUI_TextMeshPro @@ -301,6 +295,13 @@ namespace XCharts case Theme.Default: CopyTheme(Default); break; case Theme.Light: CopyTheme(Light); break; case Theme.Dark: CopyTheme(Dark); break; + case Theme.Custom: + var sour = XThemeMgr.GetTheme(themeName); + if (sour != null) + { + CopyTheme(sour); + } + break; } } @@ -310,7 +311,7 @@ namespace XCharts /// public ChartTheme CloneTheme() { - var theme = ScriptableObject.CreateInstance(); + var theme = new ChartTheme(); InitChartComponentTheme(theme); theme.CopyTheme(this); return theme; @@ -326,7 +327,7 @@ namespace XCharts { get { - var theme = ScriptableObject.CreateInstance(); + var theme = new ChartTheme(); theme.theme = Theme.Default; theme.themeName = Theme.Default.ToString(); theme.contrastColor = ColorUtil.GetColor("#514D4D"); @@ -359,7 +360,7 @@ namespace XCharts { get { - var theme = ScriptableObject.CreateInstance(); + var theme = new ChartTheme(); theme.theme = Theme.Light; theme.themeName = Theme.Light.ToString(); theme.contrastColor = ColorUtil.GetColor("#514D4D"); @@ -394,8 +395,7 @@ namespace XCharts { get { - var theme = ScriptableObject.CreateInstance(); - theme.name = Theme.Dark.ToString(); + var theme = new ChartTheme(); theme.theme = Theme.Dark; theme.themeName = Theme.Dark.ToString(); theme.contrastColor = ColorUtil.GetColor("#B9B8CE"); @@ -421,8 +421,7 @@ namespace XCharts { get { - var theme = ScriptableObject.CreateInstance(); - theme.name = Theme.Custom.ToString(); + var theme = new ChartTheme(); theme.theme = Theme.Custom; theme.themeName = Theme.Custom.ToString(); theme.contrastColor = Color.clear; diff --git a/Runtime/Mgr.meta b/Runtime/Mgr.meta new file mode 100644 index 00000000..62959ec4 --- /dev/null +++ b/Runtime/Mgr.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: e7557fe74f6754d88a35691b4949434b +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Mgr/XThemeMgr.cs b/Runtime/Mgr/XThemeMgr.cs new file mode 100644 index 00000000..9b6ab84a --- /dev/null +++ b/Runtime/Mgr/XThemeMgr.cs @@ -0,0 +1,117 @@ + + +using System.Collections.Generic; +using System.IO; +using UnityEngine; +#if UNITY_EDITOR +using UnityEditor; +#endif + +namespace XCharts +{ + public static class XThemeMgr + { + + /// + /// 重新加载主题列表 + /// + public static void ReloadThemeList() + { + //Debug.Log("LoadThemesFromResources"); + XChartsMgr.Instance.m_ThemeDict.Clear(); + XChartsMgr.Instance.m_ThemeNames.Clear(); + AddTheme(ChartTheme.Default); + AddTheme(ChartTheme.Light); + AddTheme(ChartTheme.Dark); + foreach (var json in XChartsSettings.customThemes) + { + if (json != null) + { + var theme = JsonUtility.FromJson(json.text); + AddTheme(theme); + } + } + //Debug.Log("LoadThemesFromResources DONE: theme count=" + m_ThemeDict.Keys.Count); + } + + public static void AddTheme(ChartTheme theme) + { + if (!XChartsMgr.Instance.m_ThemeDict.ContainsKey(theme.themeName)) + { + XChartsMgr.Instance.m_ThemeDict.Add(theme.themeName, theme); + XChartsMgr.Instance.m_ThemeNames.Add(theme.themeName); + } + else + { + Debug.LogError("Theme name is exist:" + theme.themeName); + } + } + + public static ChartTheme GetTheme(string themeName) + { + if (!XChartsMgr.Instance.m_ThemeDict.ContainsKey(themeName)) + { + return null; + } + return XChartsMgr.Instance.m_ThemeDict[themeName]; + } + + public static List GetAllThemeNames() + { + return XChartsMgr.Instance.m_ThemeNames; + } + + public static bool ContainsTheme(string themeName) + { + return XChartsMgr.Instance.m_ThemeNames.Contains(themeName); + } + + public static void SwitchTheme(BaseChart chart, string themeName) + { + Debug.Log("SwitchTheme:" + themeName); +#if UNITY_EDITOR + if (XChartsMgr.Instance.m_ThemeDict.Count == 0) + { + ReloadThemeList(); + } +#endif + if (!XChartsMgr.Instance.m_ThemeDict.ContainsKey(themeName)) + { + Debug.LogError("SwitchTheme ERROR: not exist theme:" + themeName); + return; + } + var target = XChartsMgr.Instance.m_ThemeDict[themeName]; + chart.theme.CopyTheme(target); + chart.RefreshAllComponent(); + } + + public static bool ExportTheme(ChartTheme theme, string themeNewName) + { +#if UNITY_EDITOR + var newtheme = ChartTheme.EmptyTheme; + newtheme.CopyTheme(theme); + newtheme.theme = Theme.Custom; + newtheme.themeName = themeNewName; + + var themeFileName = "XTheme-" + newtheme.themeName; + var assetPath = string.Format("Assets/XCharts/Resources/{0}", themeFileName); + var filePath = string.Format("{0}/../{1}.json", Application.dataPath, assetPath); + var json = JsonUtility.ToJson(newtheme, true); + File.WriteAllText(filePath, json); + AssetDatabase.SaveAssets(); + AssetDatabase.Refresh(); + var obj = Resources.Load(themeFileName); + XChartsSettings.AddJsonTheme(obj); + ReloadThemeList(); + return true; +#else + return false; +#endif + } + + public static string GetThemeAssetPath(string themeName) + { + return string.Format("Assets/XCharts/Resources/XTheme-{0}.json", themeName); + } + } +} \ No newline at end of file diff --git a/Runtime/Mgr/XThemeMgr.cs.meta b/Runtime/Mgr/XThemeMgr.cs.meta new file mode 100644 index 00000000..ab8bafd1 --- /dev/null +++ b/Runtime/Mgr/XThemeMgr.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 89e200a5f63734b22820185d375f6f27 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/XChartsMgr.cs b/Runtime/XChartsMgr.cs index 4ebcbadf..4be55402 100644 --- a/Runtime/XChartsMgr.cs +++ b/Runtime/XChartsMgr.cs @@ -46,9 +46,8 @@ namespace XCharts [SerializeField] private string m_NowVersion; [SerializeField] private string m_NewVersion; [SerializeField] private List m_ChartList = new List(); - [SerializeField] private Dictionary m_ThemeDict = new Dictionary(); - - private List m_ThemeNames = new List(); + [SerializeField] internal Dictionary m_ThemeDict = new Dictionary(); + [SerializeField] internal List m_ThemeNames = new List(); private static XChartsMgr m_XCharts; public static XChartsMgr Instance @@ -87,8 +86,7 @@ namespace XCharts { SerieLabelPool.ClearAll(); m_ChartList.Clear(); - m_ThemeDict.Clear(); - LoadThemesFromResources(); + XThemeMgr.ReloadThemeList(); } public string changeLog { get; private set; } @@ -270,34 +268,6 @@ namespace XCharts SerieLabelPool.ClearAll(); } - public void LoadThemesFromResources() - { - //Debug.Log("LoadThemesFromResources"); - m_ThemeDict.Clear(); - AddTheme(ChartTheme.Default); - AddTheme(ChartTheme.Light); - AddTheme(ChartTheme.Dark); - var list = Resources.LoadAll(""); - foreach (var theme in list) - { - AddTheme(theme); - } - //Debug.Log("LoadThemesFromResources DONE: theme count=" + m_ThemeDict.Keys.Count); - } - - private void AddTheme(ChartTheme theme) - { - if (!m_ThemeDict.ContainsKey(theme.themeName)) - { - m_ThemeDict.Add(theme.themeName, theme); - m_ThemeNames.Add(theme.themeName); - } - else - { - Debug.LogError("Theme name is exist:" + theme.themeName); - } - } - public void AddChart(BaseChart chart) { var sameNameChart = GetChart(chart.chartName); @@ -341,66 +311,6 @@ namespace XCharts return m_ChartList.Contains(chart); } - public static List GetAllThemeNames() - { - return Instance.m_ThemeNames; - } - - public static bool ContainsTheme(string themeName) - { - return Instance.m_ThemeNames.Contains(themeName); - } - - public static void SwitchTheme(BaseChart chart, string themeName) - { - Debug.Log("SwitchTheme:" + themeName); - if (chart.theme.themeName.Equals(themeName)) - { - return; - } -#if UNITY_EDITOR - if (Instance.m_ThemeDict.Count == 0) - { - Instance.LoadThemesFromResources(); - } -#endif - if (!Instance.m_ThemeDict.ContainsKey(themeName)) - { - Debug.LogError("SwitchTheme ERROR: not exist theme:" + themeName); - return; - } - var target = Instance.m_ThemeDict[themeName]; - chart.theme.CopyTheme(target); - chart.RefreshAllComponent(); - } - - public static string GetThemeAssetPath(string themeName) - { - return string.Format("Assets/XCharts/Resources/XChartsTheme-{0}.asset", themeName); - } - - public static bool ExportTheme(ChartTheme theme, string themeNewName) - { -#if UNITY_EDITOR - var newtheme = ChartTheme.EmptyTheme; - newtheme.CopyTheme(theme); - newtheme.name = themeNewName; - newtheme.themeName = themeNewName; - - var themeFileName = "XChartsTheme-" + newtheme.themeName; - var assetPath = string.Format("Assets/XCharts/Resources/{0}.asset", themeFileName); - if (Resources.Load(themeFileName)) - { - AssetDatabase.DeleteAsset(assetPath); - } - AssetDatabase.CreateAsset(newtheme, assetPath); - Instance.AddTheme(newtheme); - return true; -#else - return false; -#endif - } - public static void RemoveAllChartObject() { if (Instance.m_ChartList.Count == 0) diff --git a/Runtime/XChartsSettings.cs b/Runtime/XChartsSettings.cs index 85812dc6..f8db1531 100644 --- a/Runtime/XChartsSettings.cs +++ b/Runtime/XChartsSettings.cs @@ -7,6 +7,7 @@ using UnityEngine; using System; +using System.Collections.Generic; #if dUI_TextMeshPro using TMPro; #endif @@ -63,6 +64,7 @@ namespace XCharts [SerializeField] [Range(10, 50)] protected float m_VisualMapTriangeLen = 20f; [SerializeField] [Range(1, 20)] protected float m_PieTooltipExtraRadius = 8f; [SerializeField] [Range(1, 20)] protected float m_PieSelectedOffset = 8f; + [SerializeField] protected List m_CustomThemes = new List(); public static Font font { get { return Instance.m_Font; } } #if dUI_TextMeshPro @@ -117,6 +119,7 @@ namespace XCharts public static float pieSelectedOffset { get { return Instance.m_PieSelectedOffset; } } #endregion + public static List customThemes { get { return Instance.m_CustomThemes; } } private static XChartsSettings s_Instance; public static XChartsSettings Instance @@ -146,5 +149,16 @@ namespace XCharts return s_Instance; } } + + public static bool AddJsonTheme(TextAsset theme) + { + if (theme == null) return false; + if (!Instance.m_CustomThemes.Contains(theme)) + { + Instance.m_CustomThemes.Add(theme); + return true; + } + return false; + } } } \ No newline at end of file