using System.Collections.Generic; using UnityEditor; using UnityEngine; namespace Ubisoft.Hotel.Logger.Editor { [CustomEditor(typeof(ChannelsPreset))] internal sealed class ChannelsPresetEditorEditor : HtUnityEditor { private const string BUTTON_CLEAR = "Clear"; private const string TOOLTIP_CLEAR = "Clear 'Channel Settings' list"; private const string BUTTON_ENABLE_ALL = "Enable all"; private const string TOOLTIP_ENABLE_ALL = "Enable all channels in 'Channel Settings' list along with 'Other Channels'"; private const string BUTTON_DISABLE_ALL = "Disable all"; private const string TOOLTIP_DISABLE_ALL = "Disable all Channel Settings in 'Channel Settings' list along with 'Other Channels'"; private const string BUTTON_SORT = "Sort"; private const string TOOLTIP_SORT = "Sort 'Channel Settings' list in alphabetical order"; private const string BUTTON_LOAD_FROM_HTLOGGER = "Load from HtLogger"; private const string TOOLTIP_LOAD_FROM_HTLOGGER = "Clear this object and load the channels currently handled by HtLogger. This option is only available in play mode"; private const string BUTTON_LOAD = "Load"; private const string TOOLTIP_LOAD = "Load a preset from disk into this object"; private const string BUTTON_SAVE = "Save"; private const string TOOLTIP_SAVE = "Save this preset to disk"; private const string FILE_EXTENSION = "asset"; private const string DOT_FILE_EXTENSION = "." + FILE_EXTENSION; private ChannelsPreset ChannelsPreset { get { return target as ChannelsPreset; } } protected override void ExtendedOnInspectorGUI() { EditorGUI.indentLevel++; base.ExtendedOnInspectorGUI(); GUILayout.BeginHorizontal(); if (GUILayout.Button(new GUIContent(BUTTON_CLEAR, TOOLTIP_CLEAR))) { ChannelsPreset.Clear(); } if (GUILayout.Button(new GUIContent(BUTTON_ENABLE_ALL, TOOLTIP_ENABLE_ALL))) { ChannelsPreset.EnableAll(); } if (GUILayout.Button(new GUIContent(BUTTON_DISABLE_ALL, TOOLTIP_DISABLE_ALL))) { ChannelsPreset.DisableAll(); } if (GUILayout.Button(new GUIContent(BUTTON_SORT, TOOLTIP_SORT))) { ChannelsPreset.Sort(); } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); if (GUI.enabled) { GUI.enabled = Application.isPlaying; if (GUILayout.Button(new GUIContent(BUTTON_LOAD_FROM_HTLOGGER, TOOLTIP_LOAD_FROM_HTLOGGER))) { LoadFromHtLogger(); } GUI.enabled = true; } if (GUILayout.Button(new GUIContent(BUTTON_LOAD, TOOLTIP_LOAD))) { Load(); } if (GUILayout.Button(new GUIContent(BUTTON_SAVE, TOOLTIP_SAVE))) { Save(); } GUILayout.EndHorizontal(); EditorGUI.indentLevel--; } private string GetRootPlatformFullPath() { string unityPath = ChannelsPreset.RootUnityPath; if (string.IsNullOrEmpty(unityPath)) { unityPath = AssetDatabase.GetAssetPath(ChannelsPreset); unityPath = HtAssetDatabase.UnityPathGetDirectoryName(unityPath); } return HtAssetDatabase.UnityPathToPlatformPath(unityPath, true); } protected override void DrawProperty(SerializedProperty prop) { bool draw = true; if (prop.name == ChannelsPreset.ATT_ROOT_UNITY_PATH || prop.name == ChannelsPreset.ATT_NAME) { draw = false; } if (draw) { base.DrawProperty(prop); } } protected override void OnPropertyChanged() { // Validate the change ChannelsPreset.Validate(); // If it's playing then the consumer has edited it to see the changes immediately if (Application.isPlaying) { HtLogger.Instance.ApplyChannelsPreset(target as ChannelsPreset); } } /// /// Clear the target object and load it with the channels currently handled by HtLogger. /// private void LoadFromHtLogger() { // Clear ChannelsPreset and load all channels currently handled by HtLogger ChannelsPreset.Clear(); List channels = HtLogger.Instance.Channels; if (channels != null) { int count = channels.Count; for (int i = 0; i < count; ++i) { ChannelsPreset.AddChannel(channels[i].Name, HtLogger.Instance.IsChannelEnabled(channels[i])); } ChannelsPreset.Sort(); } // Make sure that the target object is saved to disk. HtAssetDatabase.NeedsToSaveAssets = true; } /// /// Load a ChannelsPreset read from disk into the ChannelsPreset target object. /// private void Load() { // Open a dialog to select the file to load string path = EditorUtility.OpenFilePanel(TOOLTIP_LOAD, GetRootPlatformFullPath(), FILE_EXTENSION); // AssetDatabase expects a Unity path but EditorUtility.OpenFilePanel() returns a platform full path. string unityPath = HtAssetDatabase.PlatformPathToUnityPath(path, true); // Attempts to load a ChannelPreset object from the provided path. ChannelsPreset preset = AssetDatabase.LoadAssetAtPath(unityPath, typeof(ChannelsPreset)) as ChannelsPreset; if (preset == null) { Debug.EditorLogError($"The chosen file {Debug.FormatTextInUserContext(path)} is not a valid ChannelsPreset object."); } else { string thisName = ChannelsPreset.Name; // Copy the loaded object into the target object. ChannelsPreset.CopyFrom(preset); ChannelsPreset.Name = thisName; // Make sure that the target object is saved to disk. HtAssetDatabase.NeedsToSaveAssets = true; } } /// /// Save the ChannelsPreset target object to disk. /// private void Save() { // Add the extension so if the file already exists a popup warning the user about the situation will be triggered. string fileName = string.IsNullOrEmpty(ChannelsPreset.Name) ? string.Empty : $"{ChannelsPreset.Name}{DOT_FILE_EXTENSION}"; // Open a dialog to choose the destination folder. Current ChannelsPreset name is used as a file name. string path = EditorUtility.SaveFilePanel(TOOLTIP_SAVE, GetRootPlatformFullPath(), fileName, FILE_EXTENSION); if (path.Length != 0) { // Since EditorUtility.SaveFilePanel() returns the platform full path it needs to be translated into a Unity path string unityPath = HtAssetDatabase.PlatformPathToUnityPath(path, true); // Make sure that the name contains the required extension. string unityPathWithExt = unityPath; if (!unityPathWithExt.EndsWith(DOT_FILE_EXTENSION)) { unityPathWithExt += DOT_FILE_EXTENSION; } // Make sure that the user has introduced a different path, otherwise there's no need to save string thisUnityPath = AssetDatabase.GetAssetPath(ChannelsPreset); if (unityPath != thisUnityPath) { // Check if a file with this name already exists. If so then it is deleted. if (HtAssetDatabase.ExistsFile(unityPathWithExt)) { HtAssetDatabase.DeleteFile(unityPathWithExt, true); } // Remove the extension from fileName fileName = HtAssetDatabase.GetUnityPathLastEntry(unityPath); unityPath = unityPath.Replace(fileName, ""); if (fileName.EndsWith(DOT_FILE_EXTENSION)) { fileName = fileName.Replace(DOT_FILE_EXTENSION, ""); } // Create a new scriptable object in the path stated with the name stated. ChannelsPreset returnValue = HtUnityEditorFactory.CreateScriptableObject(typeof(ChannelsPreset), unityPath, fileName) as ChannelsPreset; returnValue.name = fileName; // Copy this object into this new scriptable object to preserve the copy returnValue.CopyFrom(ChannelsPreset); returnValue.Name = fileName; // Make sure that the target object is saved to disk. HtAssetDatabase.NeedsToSaveAssets = true; } } } } }