using System;
using System.Linq;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;
using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine.Serialization;
using System.IO;
namespace Hierarchy2
{
[Serializable]
internal class HierarchySettings : ScriptableObject
{
[Serializable]
public struct ThemeData
{
public Color colorRowEven;
public Color colorRowOdd;
public Color colorGrid;
public Color colorTreeView;
public Color colorLockIcon;
public Color tagColor;
public Color layerColor;
public Color comSelBGColor;
public Color selectionColor;
public Color colorHeaderTitle;
public Color colorHeaderBackground;
public ThemeData(ThemeData themeData)
{
colorRowEven = themeData.colorRowEven;
colorRowOdd = themeData.colorRowOdd;
colorGrid = themeData.colorGrid;
colorTreeView = themeData.colorTreeView;
colorLockIcon = themeData.colorLockIcon;
tagColor = themeData.tagColor;
layerColor = themeData.layerColor;
comSelBGColor = themeData.comSelBGColor;
selectionColor = themeData.selectionColor;
colorHeaderTitle = themeData.colorHeaderTitle;
colorHeaderBackground = themeData.colorHeaderBackground;
}
public void BlendMultiply(Color blend)
{
colorRowEven = colorRowEven * blend;
colorRowOdd = colorRowOdd * blend;
colorGrid = colorGrid * blend;
colorTreeView = colorTreeView * blend;
colorLockIcon = colorLockIcon * blend;
tagColor = tagColor * blend;
layerColor = layerColor * blend;
comSelBGColor = comSelBGColor * blend;
selectionColor = selectionColor * blend;
colorHeaderTitle = colorHeaderTitle * blend;
colorHeaderBackground = colorHeaderBackground * blend;
}
}
///Define background color using prefix.
[Serializable]
public struct InstantBackgroundColor
{
public bool active;
public bool useStartWith, useTag, useLayer;
public string startWith;
public string tag;
public LayerMask layer;
public Color color;
}
public enum ComponentSize
{
Small,
Normal,
Large
}
public enum ElementAlignment
{
AfterName,
Right
}
[Flags]
public enum ContentDisplay
{
Component = (1 << 0),
Tag = (1 << 1),
Layer = (1 << 2)
}
private static HierarchySettings instance;
public ThemeData personalTheme;
public ThemeData professionalTheme;
public ThemeData playmodeTheme;
private bool useThemePlaymode = false;
public ThemeData usedTheme
{
get
{
if (EditorApplication.isPlayingOrWillChangePlaymode)
{
if (useThemePlaymode == false)
{
playmodeTheme = new ThemeData(EditorGUIUtility.isProSkin ? professionalTheme : personalTheme);
playmodeTheme.BlendMultiply(GUI.color);
useThemePlaymode = true;
}
return playmodeTheme;
}
else
{
useThemePlaymode = false;
return EditorGUIUtility.isProSkin ? professionalTheme : personalTheme;
}
}
}
[HideInInspector] public bool activeHierarchy = true;
public bool displayCustomObjectIcon = true;
public bool displayTreeView = true;
public bool displayRowBackground = true;
public bool displayGrid = false;
[HideInInspector] public bool displayStaticButton = true;
public int offSetIconAfterName = 8;
public bool displayComponents = true;
public ElementAlignment componentAlignment = ElementAlignment.AfterName;
public enum ComponentDisplayMode
{
All = 0,
ScriptOnly = 1,
Specified = 2,
Ignore = 3
}
public ComponentDisplayMode componentDisplayMode = ComponentDisplayMode.Ignore;
public string[] components = new string[] {"Transform", "RectTransform"};
[HideInInspector] public int componentLimited = 0;
[Range(12, 16)] public int componentSize = 16;
public int componentSpacing = 0;
public bool displayTag = true;
public ElementAlignment tagAlignment = ElementAlignment.AfterName;
public bool displayLayer = true;
public ElementAlignment layerAlignment = ElementAlignment.AfterName;
[HideInInspector] public bool applyStaticTargetAndChild = true;
public bool applyTagTargetAndChild = false;
public bool applyLayerTargetAndChild = true;
public string separatorStartWith = "--->";
public string separatorDefaultTag = "Untagged";
public bool useInstantBackground = false;
public List instantBackgroundColors = new List();
public bool onlyDisplayWhileMouseEnter = false;
public ContentDisplay contentDisplay = ContentDisplay.Component | ContentDisplay.Tag | ContentDisplay.Layer;
public delegate void OnSettingsChangedCallback(string param);
public OnSettingsChangedCallback onSettingsChanged;
public void OnSettingsChanged(string param = "")
{
switch (param)
{
case nameof(componentSize):
if (componentSize % 2 != 0) componentSize -= 1;
break;
case nameof(componentSpacing):
if (componentSpacing < 0) componentSpacing = 0;
break;
}
onSettingsChanged?.Invoke(param);
hideFlags = HideFlags.None;
}
[SettingsProvider]
static SettingsProvider UIElementSettingsProvider()
{
var provider = new SettingsProvider("Project/Hierarchy", SettingsScope.Project)
{
label = "Hierarchy",
activateHandler = (searchContext, rootElement) =>
{
var settings = GetAssets();
float TITLE_MARGIN_TOP = 14;
float TITLE_MARGIN_BOTTOM = 8;
float CONTENT_MARGIN_LEFT = 10;
HorizontalLayout horizontalLayout = new HorizontalLayout();
horizontalLayout.style.backgroundColor = new Color(0, 0, 0, 0.2f);
horizontalLayout.style.paddingTop = 4;
horizontalLayout.style.paddingBottom = 10;
rootElement.Add(horizontalLayout);
Label hierarchyTitle = new Label("Hierarchy");
hierarchyTitle.StyleFontSize(20);
hierarchyTitle.StyleMargin(10, 0, 2, 2);
hierarchyTitle.StyleFont(FontStyle.Bold);
horizontalLayout.Add(hierarchyTitle);
Label importButton = new Label();
importButton.text = " Import";
importButton.style.unityFontStyleAndWeight = FontStyle.Italic;
Color importExportButtonColor = new Color32(102, 157, 246, 255);
importButton.style.color = importExportButtonColor;
importButton.RegisterCallback(evt => instance.ImportFromJson());
horizontalLayout.Add(importButton);
Label exportButton = new Label();
exportButton.text = "| Export";
exportButton.style.unityFontStyleAndWeight = FontStyle.Italic;
exportButton.style.color = importExportButtonColor;
exportButton.RegisterCallback(evt => instance.ExportToJson());
horizontalLayout.Add(exportButton);
ScrollView scrollView = new ScrollView();
rootElement.Add(scrollView);
VerticalLayout verticalLayout = new VerticalLayout();
verticalLayout.StylePadding(8, 8, 8, 8);
scrollView.Add(verticalLayout);
var Object = new Label("Object");
Object.StyleFont(FontStyle.Bold);
Object.StyleMargin(0, 0, 0, TITLE_MARGIN_BOTTOM);
verticalLayout.Add(Object);
var displayCustomObjectIcon = new Toggle("Display Custom Icon");
displayCustomObjectIcon.value = settings.displayCustomObjectIcon;
displayCustomObjectIcon.RegisterValueChangedCallback((evt) =>
{
Undo.RecordObject(settings, "Change Settings");
settings.displayCustomObjectIcon = evt.newValue;
settings.OnSettingsChanged(nameof(settings.displayCustomObjectIcon));
});
displayCustomObjectIcon.StyleMarginLeft(CONTENT_MARGIN_LEFT);
verticalLayout.Add(displayCustomObjectIcon);
var View = new Label("View");
View.StyleFont(FontStyle.Bold);
View.StyleMargin(0, 0, TITLE_MARGIN_TOP, TITLE_MARGIN_BOTTOM);
verticalLayout.Add(View);
var displayRowBackground = new Toggle("Display RowBackground");
displayRowBackground.value = settings.displayRowBackground;
displayRowBackground.RegisterValueChangedCallback((evt) =>
{
Undo.RecordObject(settings, "Change Settings");
settings.displayRowBackground = evt.newValue;
settings.OnSettingsChanged(nameof(settings.displayRowBackground));
});
displayRowBackground.StyleMarginLeft(CONTENT_MARGIN_LEFT);
verticalLayout.Add(displayRowBackground);
var displayTreeView = new Toggle("Display TreeView");
displayTreeView.value = settings.displayTreeView;
displayTreeView.RegisterValueChangedCallback((evt) =>
{
Undo.RecordObject(settings, "Change Settings");
settings.displayTreeView = evt.newValue;
settings.OnSettingsChanged(nameof(settings.displayTreeView));
});
displayTreeView.StyleMarginLeft(CONTENT_MARGIN_LEFT);
verticalLayout.Add(displayTreeView);
var displayGrid = new Toggle("Display Grid");
displayGrid.value = settings.displayGrid;
displayGrid.RegisterValueChangedCallback((evt) =>
{
Undo.RecordObject(settings, "Change Settings");
settings.displayGrid = evt.newValue;
settings.OnSettingsChanged(nameof(settings.displayGrid));
});
displayGrid.StyleMarginLeft(CONTENT_MARGIN_LEFT);
verticalLayout.Add(displayGrid);
var Components = new Label("Components");
Components.StyleFont(FontStyle.Bold);
Components.StyleMargin(0, 0, TITLE_MARGIN_TOP, TITLE_MARGIN_BOTTOM);
verticalLayout.Add(Components);
var displayComponents = new Toggle("Display Components Icon");
displayComponents.value = settings.displayComponents;
displayComponents.RegisterValueChangedCallback((evt) =>
{
Undo.RecordObject(settings, "Change Settings");
settings.displayComponents = evt.newValue;
settings.OnSettingsChanged(nameof(settings.displayComponents));
});
displayComponents.StyleMarginLeft(CONTENT_MARGIN_LEFT);
verticalLayout.Add(displayComponents);
var componentAlignment = new EnumField(settings.componentAlignment);
componentAlignment.label = "Component Alignment";
componentAlignment.RegisterValueChangedCallback((evt) =>
{
Undo.RecordObject(settings, "Change Settings");
settings.componentAlignment = (ElementAlignment) evt.newValue;
settings.OnSettingsChanged(nameof(settings.componentAlignment));
});
componentAlignment.StyleMarginLeft(CONTENT_MARGIN_LEFT);
verticalLayout.Add(componentAlignment);
var componentDisplayMode = new EnumField(settings.componentDisplayMode);
componentDisplayMode.label = "Component Display Mode";
componentDisplayMode.StyleMarginLeft(CONTENT_MARGIN_LEFT);
verticalLayout.Add(componentDisplayMode);
var componentListInput = new TextField("Components");
componentListInput.value = string.Join(" ", settings.components);
componentListInput.StyleMarginLeft(CONTENT_MARGIN_LEFT);
verticalLayout.Add(componentListInput);
componentListInput.RegisterValueChangedCallback((evt) =>
{
Undo.RecordObject(settings, "Change Settings");
settings.components = evt.newValue.Split(' ');
settings.OnSettingsChanged(nameof(settings.components));
});
componentDisplayMode.RegisterValueChangedCallback((evt) =>
{
Undo.RecordObject(settings, "Change Settings");
settings.componentDisplayMode = (ComponentDisplayMode) evt.newValue;
switch (settings.componentDisplayMode)
{
case ComponentDisplayMode.Specified:
componentListInput.StyleDisplay(true);
break;
case ComponentDisplayMode.Ignore:
componentListInput.StyleDisplay(true);
break;
case ComponentDisplayMode.All:
componentListInput.StyleDisplay(false);
break;
case ComponentDisplayMode.ScriptOnly:
componentListInput.StyleDisplay(false);
break;
}
settings.OnSettingsChanged(nameof(settings.componentDisplayMode));
});
var componentSizeEnum = ComponentSize.Normal;
switch (settings.componentSize)
{
case 12:
componentSizeEnum = ComponentSize.Small;
break;
case 14:
componentSizeEnum = ComponentSize.Normal;
break;
case 16:
componentSizeEnum = ComponentSize.Large;
break;
}
var componentSize = new EnumField(componentSizeEnum);
componentSize.label = "Component Size";
componentSize.StyleMarginLeft(CONTENT_MARGIN_LEFT);
componentSize.RegisterValueChangedCallback((evt) =>
{
Undo.RecordObject(settings, "Change Settings");
switch (evt.newValue)
{
case ComponentSize.Small:
settings.componentSize = 12;
break;
case ComponentSize.Normal:
settings.componentSize = 14;
break;
case ComponentSize.Large:
settings.componentSize = 16;
break;
}
settings.OnSettingsChanged(nameof(settings.componentSize));
});
verticalLayout.Add(componentSize);
var componentSpacing = new IntegerField();
componentSpacing.label = "Component Spacing";
componentSpacing.value = settings.componentSpacing;
componentSpacing.StyleMarginLeft(CONTENT_MARGIN_LEFT);
componentSpacing.RegisterValueChangedCallback((evt) =>
{
Undo.RecordObject(settings, "Change Settings");
settings.componentSpacing = evt.newValue;
settings.OnSettingsChanged(nameof(settings.componentSpacing));
});
verticalLayout.Add(componentSpacing);
var TagAndLayer = new Label("Tag And Layer");
TagAndLayer.StyleFont(FontStyle.Bold);
TagAndLayer.StyleMargin(0, 0, TITLE_MARGIN_TOP, TITLE_MARGIN_BOTTOM);
verticalLayout.Add(TagAndLayer);
var displayTag = new Toggle("Display Tag");
displayTag.value = settings.displayTag;
displayTag.RegisterValueChangedCallback((evt) =>
{
Undo.RecordObject(settings, "Change Settings");
settings.displayTag = evt.newValue;
settings.OnSettingsChanged(nameof(settings.displayTag));
});
displayTag.StyleMarginLeft(CONTENT_MARGIN_LEFT);
verticalLayout.Add(displayTag);
var applyTagTargetAndChild = new Toggle("Tag Recursive Change");
applyTagTargetAndChild.value = settings.applyTagTargetAndChild;
applyTagTargetAndChild.RegisterValueChangedCallback((evt) =>
{
Undo.RecordObject(settings, "Change Settings");
settings.applyTagTargetAndChild = evt.newValue;
settings.OnSettingsChanged(nameof(settings.applyTagTargetAndChild));
});
applyTagTargetAndChild.StyleMarginLeft(CONTENT_MARGIN_LEFT);
verticalLayout.Add(applyTagTargetAndChild);
var tagAlignment = new EnumField(settings.tagAlignment);
tagAlignment.label = "Tag Alignment";
tagAlignment.RegisterValueChangedCallback((evt) =>
{
Undo.RecordObject(settings, "Change Settings");
settings.tagAlignment = (ElementAlignment) evt.newValue;
settings.OnSettingsChanged(nameof(settings.tagAlignment));
});
tagAlignment.StyleMarginLeft(CONTENT_MARGIN_LEFT);
verticalLayout.Add(tagAlignment);
var displayLayer = new Toggle("Display Layer");
displayLayer.value = settings.displayLayer;
displayLayer.RegisterValueChangedCallback((evt) =>
{
Undo.RecordObject(settings, "Change Settings");
settings.displayLayer = evt.newValue;
settings.OnSettingsChanged(nameof(settings.displayLayer));
});
displayLayer.style.marginTop = 8;
displayLayer.StyleMarginLeft(CONTENT_MARGIN_LEFT);
verticalLayout.Add(displayLayer);
var applyLayerTargetAndChild = new Toggle("Layer Recursive Change");
applyLayerTargetAndChild.value = settings.applyLayerTargetAndChild;
applyLayerTargetAndChild.RegisterValueChangedCallback((evt) =>
{
Undo.RecordObject(settings, "Change Settings");
settings.applyLayerTargetAndChild = evt.newValue;
settings.OnSettingsChanged(nameof(settings.applyLayerTargetAndChild));
});
applyLayerTargetAndChild.StyleMarginLeft(CONTENT_MARGIN_LEFT);
verticalLayout.Add(applyLayerTargetAndChild);
var layerAlignment = new EnumField(settings.layerAlignment);
layerAlignment.label = "Layer Alignment";
layerAlignment.RegisterValueChangedCallback((evt) =>
{
Undo.RecordObject(settings, "Change Settings");
settings.layerAlignment = (ElementAlignment) evt.newValue;
settings.OnSettingsChanged(nameof(settings.layerAlignment));
});
layerAlignment.StyleMarginLeft(CONTENT_MARGIN_LEFT);
verticalLayout.Add(layerAlignment);
var advanced = new Label("Advanced");
advanced.StyleFont(FontStyle.Bold);
advanced.StyleMargin(0, 0, TITLE_MARGIN_TOP, TITLE_MARGIN_BOTTOM);
verticalLayout.Add(advanced);
var separatorStartWith = new TextField();
separatorStartWith.label = "Separator StartWith";
separatorStartWith.StyleMarginLeft(CONTENT_MARGIN_LEFT);
separatorStartWith.value = settings.separatorStartWith;
separatorStartWith.RegisterValueChangedCallback((evt) =>
{
Undo.RecordObject(settings, "Change Settings");
settings.separatorStartWith = evt.newValue == String.Empty ? "--->" : evt.newValue;
settings.OnSettingsChanged(nameof(settings.separatorStartWith));
});
verticalLayout.Add(separatorStartWith);
var headerDefaultTag = new TagField();
headerDefaultTag.label = "Separator Default Tag";
headerDefaultTag.value = settings.separatorDefaultTag;
headerDefaultTag.RegisterValueChangedCallback((evt) =>
{
Undo.RecordObject(settings, "Change Settings");
settings.separatorDefaultTag = evt.newValue;
settings.OnSettingsChanged(nameof(settings.separatorDefaultTag));
});
headerDefaultTag.StyleMarginLeft(CONTENT_MARGIN_LEFT);
headerDefaultTag.StyleMarginBottom(4);
verticalLayout.Add(headerDefaultTag);
SerializedObject serializedSetting = new SerializedObject(settings);
IMGUIContainer instantBackgroundIMGUI = new IMGUIContainer(() =>
{
EditorGUILayout.BeginHorizontal();
settings.useInstantBackground = EditorGUILayout.Toggle("Use Instant Background", settings.useInstantBackground);
EditorGUILayout.BeginVertical("helpbox");
EditorGUILayout.PropertyField(serializedSetting.FindProperty(nameof(instantBackgroundColors)), GUIContent.none);
EditorGUILayout.EndVertical();
EditorGUILayout.EndHorizontal();
serializedSetting.ApplyModifiedProperties();
});
instantBackgroundIMGUI.StyleMarginTop(7);
instantBackgroundIMGUI.StyleMarginLeft(CONTENT_MARGIN_LEFT);
verticalLayout.Add(instantBackgroundIMGUI);
var onlyDisplayWhileMouseHovering = new Toggle("Display Hovering");
onlyDisplayWhileMouseHovering.tooltip = "Only display while mouse hovering";
onlyDisplayWhileMouseHovering.StyleMarginTop(7);
onlyDisplayWhileMouseHovering.value = settings.onlyDisplayWhileMouseEnter;
onlyDisplayWhileMouseHovering.RegisterValueChangedCallback((evt) =>
{
Undo.RecordObject(settings, "Change Settings");
settings.onlyDisplayWhileMouseEnter = evt.newValue;
settings.OnSettingsChanged(nameof(settings.onlyDisplayWhileMouseEnter));
});
onlyDisplayWhileMouseHovering.StyleMarginLeft(CONTENT_MARGIN_LEFT);
verticalLayout.Add(onlyDisplayWhileMouseHovering);
var contentMaskEnumFlags = new EnumFlagsField(settings.contentDisplay);
contentMaskEnumFlags.StyleDisplay(onlyDisplayWhileMouseHovering.value);
contentMaskEnumFlags.label = "Content Mask";
onlyDisplayWhileMouseHovering.RegisterValueChangedCallback((evt) => { contentMaskEnumFlags.StyleDisplay(evt.newValue); });
contentMaskEnumFlags.RegisterValueChangedCallback((evt) =>
{
Undo.RecordObject(settings, "Change Settings");
settings.contentDisplay = (ContentDisplay) evt.newValue;
settings.OnSettingsChanged(nameof(settings.contentDisplay));
});
contentMaskEnumFlags.style.marginLeft = CONTENT_MARGIN_LEFT;
verticalLayout.Add(contentMaskEnumFlags);
var Theme = new Label("Theme");
Theme.StyleFont(FontStyle.Bold);
Theme.StyleMargin(0, 0, TITLE_MARGIN_TOP, TITLE_MARGIN_BOTTOM);
verticalLayout.Add(Theme);
if (EditorApplication.isPlayingOrWillChangePlaymode)
{
EditorHelpBox themeWarningPlaymode =
new EditorHelpBox("This setting only available on edit mode.", MessageType.Info);
verticalLayout.Add(themeWarningPlaymode);
}
else
{
EditorHelpBox selectionColorHelpBox = new EditorHelpBox(
"Theme selection color require editor assembly recompile to take affect.\nBy selecting any script, right click -> Reimport. it will force the editor to recompile.",
MessageType.Info);
selectionColorHelpBox.StyleDisplay(false);
verticalLayout.Add(selectionColorHelpBox);
ColorField colorRowEven = new ColorField("Row Even");
colorRowEven.value = settings.usedTheme.colorRowEven;
colorRowEven.StyleMarginLeft(CONTENT_MARGIN_LEFT);
colorRowEven.RegisterValueChangedCallback((evt) =>
{
Undo.RecordObject(settings, "Change Settings");
if (EditorGUIUtility.isProSkin)
settings.professionalTheme.colorRowEven = evt.newValue;
else
settings.personalTheme.colorRowEven = evt.newValue;
settings.OnSettingsChanged();
});
verticalLayout.Add(colorRowEven);
ColorField colorRowOdd = new ColorField("Row Odd");
colorRowOdd.value = settings.usedTheme.colorRowOdd;
colorRowOdd.StyleMarginLeft(CONTENT_MARGIN_LEFT);
colorRowOdd.RegisterValueChangedCallback((evt) =>
{
Undo.RecordObject(settings, "Change Settings");
if (EditorGUIUtility.isProSkin)
settings.professionalTheme.colorRowOdd = evt.newValue;
else
settings.personalTheme.colorRowOdd = evt.newValue;
settings.OnSettingsChanged();
});
verticalLayout.Add(colorRowOdd);
ColorField colorGrid = new ColorField("Grid Color");
colorGrid.value = settings.usedTheme.colorGrid;
colorGrid.StyleMarginLeft(CONTENT_MARGIN_LEFT);
colorGrid.RegisterValueChangedCallback((evt) =>
{
Undo.RecordObject(settings, "Change Settings");
if (EditorGUIUtility.isProSkin)
settings.professionalTheme.colorGrid = evt.newValue;
else
settings.personalTheme.colorGrid = evt.newValue;
settings.OnSettingsChanged();
});
verticalLayout.Add(colorGrid);
ColorField colorTreeView = new ColorField("TreeView");
colorTreeView.value = settings.usedTheme.colorTreeView;
colorTreeView.StyleMarginLeft(CONTENT_MARGIN_LEFT);
colorTreeView.RegisterValueChangedCallback((evt) =>
{
Undo.RecordObject(settings, "Change Settings");
if (EditorGUIUtility.isProSkin)
settings.professionalTheme.colorTreeView = evt.newValue;
else
settings.personalTheme.colorTreeView = evt.newValue;
settings.OnSettingsChanged();
});
verticalLayout.Add(colorTreeView);
ColorField colorLockIcon = new ColorField("Lock Icon");
colorLockIcon.value = settings.usedTheme.colorLockIcon;
colorLockIcon.StyleMarginLeft(CONTENT_MARGIN_LEFT);
colorLockIcon.RegisterValueChangedCallback((evt) =>
{
Undo.RecordObject(settings, "Change Settings");
if (EditorGUIUtility.isProSkin)
settings.professionalTheme.colorLockIcon = evt.newValue;
else
settings.personalTheme.colorLockIcon = evt.newValue;
settings.OnSettingsChanged();
});
verticalLayout.Add(colorLockIcon);
ColorField tagColor = new ColorField("Tag Text");
tagColor.value = settings.usedTheme.tagColor;
tagColor.StyleMarginLeft(CONTENT_MARGIN_LEFT);
tagColor.RegisterValueChangedCallback((evt) =>
{
Undo.RecordObject(settings, "Change Settings");
if (EditorGUIUtility.isProSkin)
settings.professionalTheme.tagColor = evt.newValue;
else
settings.personalTheme.tagColor = evt.newValue;
settings.OnSettingsChanged();
});
verticalLayout.Add(tagColor);
ColorField layerColor = new ColorField("Layer Text");
layerColor.value = settings.usedTheme.layerColor;
layerColor.StyleMarginLeft(CONTENT_MARGIN_LEFT);
layerColor.RegisterValueChangedCallback((evt) =>
{
Undo.RecordObject(settings, "Change Settings");
if (EditorGUIUtility.isProSkin)
settings.professionalTheme.layerColor = evt.newValue;
else
settings.personalTheme.layerColor = evt.newValue;
settings.OnSettingsChanged();
});
verticalLayout.Add(layerColor);
ColorField colorHeaderTitle = new ColorField("Header Title");
colorHeaderTitle.value = settings.usedTheme.colorHeaderTitle;
colorHeaderTitle.StyleMarginLeft(CONTENT_MARGIN_LEFT);
colorHeaderTitle.RegisterValueChangedCallback((evt) =>
{
Undo.RecordObject(settings, "Change Settings");
if (EditorGUIUtility.isProSkin)
settings.professionalTheme.colorHeaderTitle = evt.newValue;
else
settings.personalTheme.colorHeaderTitle = evt.newValue;
settings.OnSettingsChanged();
});
verticalLayout.Add(colorHeaderTitle);
ColorField colorHeaderBackground = new ColorField("Header Background");
colorHeaderBackground.value = settings.usedTheme.colorHeaderBackground;
colorHeaderBackground.StyleMarginLeft(CONTENT_MARGIN_LEFT);
colorHeaderBackground.RegisterValueChangedCallback((evt) =>
{
Undo.RecordObject(settings, "Change Settings");
if (EditorGUIUtility.isProSkin)
settings.professionalTheme.colorHeaderBackground = evt.newValue;
else
settings.personalTheme.colorHeaderBackground = evt.newValue;
settings.OnSettingsChanged();
});
verticalLayout.Add(colorHeaderBackground);
ColorField comSelBGColor = new ColorField("Component Selection");
comSelBGColor.value = settings.usedTheme.comSelBGColor;
comSelBGColor.StyleMarginLeft(CONTENT_MARGIN_LEFT);
comSelBGColor.RegisterValueChangedCallback((evt) =>
{
Undo.RecordObject(settings, "Change Settings");
if (EditorGUIUtility.isProSkin)
settings.professionalTheme.comSelBGColor = evt.newValue;
else
settings.personalTheme.comSelBGColor = evt.newValue;
settings.OnSettingsChanged();
});
verticalLayout.Add(comSelBGColor);
}
Undo.undoRedoPerformed -= OnUndoRedoPerformed;
Undo.undoRedoPerformed += OnUndoRedoPerformed;
},
deactivateHandler = () => Undo.undoRedoPerformed -= OnUndoRedoPerformed,
keywords = new HashSet(new[] {"Hierarchy"})
};
return provider;
}
private static void OnUndoRedoPerformed()
{
SettingsService.NotifySettingsProviderChanged();
if (instance != null)
{
instance.onSettingsChanged?.Invoke(nameof(instance.components)); // Refresh components on undo & redo
}
}
internal static HierarchySettings GetAssets()
{
if (instance != null)
return instance;
var guids = AssetDatabase.FindAssets(string.Format("t:{0}", typeof(HierarchySettings).Name));
for (int i = 0; i < guids.Length; i++)
{
instance = AssetDatabase.LoadAssetAtPath(AssetDatabase.GUIDToAssetPath(guids[i]));
if (instance != null)
return instance;
}
return instance = CreateAssets();
}
internal static HierarchySettings CreateAssets()
{
string path = EditorUtility.SaveFilePanelInProject("Save as...", "Hierarchy 2 Settings", "asset", "");
if (path.Length > 0)
{
HierarchySettings settings = ScriptableObject.CreateInstance();
AssetDatabase.CreateAsset(settings, path);
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
EditorUtility.FocusProjectWindow();
Selection.activeObject = settings;
return settings;
}
return null;
}
internal bool ImportFromJson()
{
string path = EditorUtility.OpenFilePanel("Import Hierarchy 2 settings", "", "json");
if (path.Length > 0)
{
string json = string.Empty;
using (StreamReader sr = new StreamReader(path))
{
json = sr.ReadToEnd();
}
if (string.IsNullOrEmpty(json)) return false;
JsonUtility.FromJsonOverwrite(json, this);
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
return true;
}
return false;
}
internal TextAsset ExportToJson()
{
string path = EditorUtility.SaveFilePanelInProject("Export Hierarchy 2 settings as...", "Hierarchy 2 Settings", "json", "");
if (path.Length > 0)
{
string json = JsonUtility.ToJson(instance, true);
using (StreamWriter sw = new StreamWriter(path))
{
sw.Write(json);
}
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
EditorUtility.FocusProjectWindow();
TextAsset asset = AssetDatabase.LoadAssetAtPath(path);
Selection.activeObject = asset;
return asset;
}
return null;
}
}
[CustomEditor(typeof(HierarchySettings))]
internal class SettingsInspector : Editor
{
HierarchySettings settings;
void OnEnable() => settings = target as HierarchySettings;
public override void OnInspectorGUI()
{
EditorGUILayout.HelpBox("Go to Edit -> Project Settings -> Hierarchy tab", MessageType.Info);
if (GUILayout.Button("Open Settings"))
SettingsService.OpenProjectSettings("Project/Hierarchy");
}
}
}