From b958e1de03fad59b5be8b9bbba497ef9331766b9 Mon Sep 17 00:00:00 2001 From: yunus bozkurtaca Date: Fri, 23 May 2025 17:23:21 +0300 Subject: [PATCH 1/8] options button added and delete button moved inside of it. --- .../Editor/Editor Windows/Icons/options.png | Bin 0 -> 173 bytes .../Editor Windows/Icons/options.png.meta | 127 ++++++++++++++++++ .../ScriptableObjectEditorWindow.cs | 41 +++--- 3 files changed, 151 insertions(+), 17 deletions(-) create mode 100644 Assets/Editor/Editor Windows/Icons/options.png create mode 100644 Assets/Editor/Editor Windows/Icons/options.png.meta diff --git a/Assets/Editor/Editor Windows/Icons/options.png b/Assets/Editor/Editor Windows/Icons/options.png new file mode 100644 index 0000000000000000000000000000000000000000..c9ea295d8fb58017cd0f0d336940279ab524850c GIT binary patch literal 173 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjjKx9jP7LeL$-D$|(mh=qLp;3S zUUB4VFc4rq@Fe|L(cegy7Yo@_n*{{#%)9J6bDGe@qaSMitZ=x*lpwuC`{dn+TRT-U zLKXl3 literal 0 HcmV?d00001 diff --git a/Assets/Editor/Editor Windows/Icons/options.png.meta b/Assets/Editor/Editor Windows/Icons/options.png.meta new file mode 100644 index 0000000..e18bbb6 --- /dev/null +++ b/Assets/Editor/Editor Windows/Icons/options.png.meta @@ -0,0 +1,127 @@ +fileFormatVersion: 2 +guid: 788dc88cfd779234395738446dd2eade +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 1 + wrapV: 1 + wrapW: 0 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 8 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: 5e97eb03825dee720800000000000000 + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Editor/Editor Windows/ScriptableObjectEditorWindow.cs b/Assets/Editor/Editor Windows/ScriptableObjectEditorWindow.cs index dedfc87..1ec3681 100644 --- a/Assets/Editor/Editor Windows/ScriptableObjectEditorWindow.cs +++ b/Assets/Editor/Editor Windows/ScriptableObjectEditorWindow.cs @@ -43,7 +43,7 @@ public static string[] BasicFilters // textures: private Texture2D spaceIcon; private Texture2D orientationIcon; - private Texture2D deleteConfigIcon; + private Texture2D ConfigOptionsIcon; private Texture2D addConfigIcon; private Texture2D refreshIcon; private Texture2D filtersIcon; @@ -58,8 +58,8 @@ public static string[] BasicFilters GUILayoutOption[] AddConfigButtonOptions; GUIStyle buttonStyle; // delete config button styles: - GUIContent deleteConfigButton; - GUILayoutOption[] deleteConfigButtonOptions; + GUIContent ConfigOptionsButton; + GUILayoutOption[] ConfigOoptionsButtonOptions; // label styles: GUIStyle centeredLabelStyle; @@ -155,15 +155,15 @@ private void SetupButtonStyles() } // 'delete config' button styles - if (deleteConfigIcon != null) + if (ConfigOptionsIcon != null) { - deleteConfigButton = new GUIContent(deleteConfigIcon, "delete config permanently"); - deleteConfigButtonOptions = new GUILayoutOption[] { GUILayout.Height(20), GUILayout.Width(20) }; + ConfigOptionsButton = new GUIContent(ConfigOptionsIcon, "delete config permanently"); + ConfigOoptionsButtonOptions = new GUILayoutOption[] { GUILayout.Height(20), GUILayout.Width(20) }; } else { - deleteConfigButton = new GUIContent("del", "delete config permanently"); - deleteConfigButtonOptions = new GUILayoutOption[] { GUILayout.Width(30) }; + ConfigOptionsButton = new GUIContent("del", "delete config permanently"); + ConfigOoptionsButtonOptions = new GUILayoutOption[] { GUILayout.Width(30) }; } } @@ -327,7 +327,7 @@ private void LoadIcons() { spaceIcon = AssetDatabase.LoadAssetAtPath("Assets/Editor/Editor Windows/Icons/space.png"); orientationIcon = AssetDatabase.LoadAssetAtPath("Assets/Editor/Editor Windows/Icons/orientation.png"); - deleteConfigIcon = AssetDatabase.LoadAssetAtPath("Assets/Editor/Editor Windows/Icons/delete.png"); + ConfigOptionsIcon = AssetDatabase.LoadAssetAtPath("Assets/Editor/Editor Windows/Icons/options.png"); addConfigIcon = AssetDatabase.LoadAssetAtPath("Assets/Editor/Editor Windows/Icons/add file.png"); refreshIcon = AssetDatabase.LoadAssetAtPath("Assets/Editor/Editor Windows/Icons/refresh.png"); filtersIcon = AssetDatabase.LoadAssetAtPath("Assets/Editor/Editor Windows/Icons/filter.png"); @@ -340,9 +340,9 @@ private void LoadIcons() { Debug.LogError("orientation Icon not found in: Assets/Editor/Editor Windows/Icons/orientation.png"); } - if(deleteConfigIcon == null) + if(ConfigOptionsIcon == null) { - Debug.LogError("deleteConfig Icon not found in: Assets/Editor/Editor Windows/Icons/delete.png"); + Debug.LogError("ConfigOptions Icon not found in: Assets/Editor/Editor Windows/Icons/options.png"); } if (addConfigIcon == null) { @@ -446,7 +446,7 @@ private void PutPropertiesForObject_V(List Configs) where T : ScriptableOb EditorGUILayout.BeginHorizontal(); GUIContent propertyContent = new GUIContent(fileName, fileName); EditorGUILayout.LabelField(propertyContent, EditorStyles.miniBoldLabel, GUILayout.MinWidth(PropertyMinWidth)); - DeleteButton(Config); + OptionsButton(Config); EditorGUILayout.EndHorizontal(); SerializedObject serializedObject = new(Config); @@ -490,24 +490,31 @@ private void PutPropertiesForObject_V(List Configs) where T : ScriptableOb } } - private void DeleteButton(T Config) where T : ScriptableObject + private void OptionsButton(T Config) where T : ScriptableObject { GUIStyle buttonStyle = new GUIStyle(GUI.skin.button); - if (deleteConfigIcon != null) + if (ConfigOptionsIcon != null) { buttonStyle.padding = new RectOffset(2, 2, 2, 2); buttonStyle.imagePosition = ImagePosition.ImageOnly; } - if (GUILayout.Button(deleteConfigButton, buttonStyle, deleteConfigButtonOptions)) + if (GUILayout.Button(ConfigOptionsButton, buttonStyle, ConfigOoptionsButtonOptions)) { - // Delete the selected ScriptableObject asset - DeleteConfig(Config); + ShowOptionsMenu(Config); } } + private void ShowOptionsMenu(T Config) where T : ScriptableObject + { + GenericMenu menu = new GenericMenu(); + + menu.AddItem(new GUIContent("Delete Config"), false, () => DeleteConfig(Config)); + + menu.ShowAsContext(); + } /// /// create a Horizontal (parameters will be horizontal) table for the properties of the object From 0b4833a7269ff0071ace9dcf99074cf179c546d2 Mon Sep 17 00:00:00 2001 From: yunus bozkurtaca Date: Fri, 23 May 2025 17:25:31 +0300 Subject: [PATCH 2/8] focus on project window option added --- .../ScriptableObjectEditorWindow.cs | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/Assets/Editor/Editor Windows/ScriptableObjectEditorWindow.cs b/Assets/Editor/Editor Windows/ScriptableObjectEditorWindow.cs index 1ec3681..c2aed61 100644 --- a/Assets/Editor/Editor Windows/ScriptableObjectEditorWindow.cs +++ b/Assets/Editor/Editor Windows/ScriptableObjectEditorWindow.cs @@ -512,6 +512,8 @@ private void ShowOptionsMenu(T Config) where T : ScriptableObject GenericMenu menu = new GenericMenu(); menu.AddItem(new GUIContent("Delete Config"), false, () => DeleteConfig(Config)); + menu.AddSeparator(""); + menu.AddItem(new GUIContent("Show In Project Folder"), false, () => ShowInProjectFolders(Config)); menu.ShowAsContext(); } @@ -568,13 +570,13 @@ private void PutPropertiesForObject_H(List Configs) where T : ScriptableOb string fileName = System.IO.Path.GetFileNameWithoutExtension(filePath); if (fileName == "") throw new System.Exception(); - // Display a delete button for the asset - DeleteButton(Config); - // Display the file name for the asset GUIContent propertyContent = new GUIContent(fileName, fileName); EditorGUILayout.LabelField(propertyContent, EditorStyles.miniBoldLabel, GUILayout.Width(120)); + // Display a delete button for the asset + OptionsButton(Config); + SerializedObject serializedObject = new(Config); SerializedProperty property = serializedObject.GetIterator(); @@ -621,6 +623,13 @@ private void DeleteConfig(T Config) where T : ScriptableObject } } + private void ShowInProjectFolders(T Config) where T : ScriptableObject + { + string path = AssetDatabase.GetAssetPath(Config); + EditorUtility.FocusProjectWindow(); + Selection.activeObject = AssetDatabase.LoadAssetAtPath(path); + } + public static float CalculatePropertyHeight(List configs, SerializedProperty property) where T : ScriptableObject { float maxHeight = 0f; From c11f506139a6b075eb11f36757042dfbfdd71d95 Mon Sep 17 00:00:00 2001 From: yunus bozkurtaca Date: Fri, 23 May 2025 17:25:56 +0300 Subject: [PATCH 3/8] filters button minor size adjustment --- Assets/Editor/Editor Windows/ScriptableObjectEditorWindow.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Assets/Editor/Editor Windows/ScriptableObjectEditorWindow.cs b/Assets/Editor/Editor Windows/ScriptableObjectEditorWindow.cs index c2aed61..ffc2f98 100644 --- a/Assets/Editor/Editor Windows/ScriptableObjectEditorWindow.cs +++ b/Assets/Editor/Editor Windows/ScriptableObjectEditorWindow.cs @@ -668,7 +668,7 @@ public ConfigTypeSelectionPopup(List selectedTypes, Action onSelectionChan public override Vector2 GetWindowSize() { - return new Vector2(200, 500); // Define the dimensions of the popup window + return new Vector2(200, 400); // Define the dimensions of the popup window } public override void OnGUI(Rect rect) From 7f4e486ac0adfcaf9801b0e671bf1d9379b7d5cc Mon Sep 17 00:00:00 2001 From: yunus bozkurtaca Date: Fri, 23 May 2025 17:44:06 +0300 Subject: [PATCH 4/8] special namespace added --- .../ConfigTypeSelectionPopup.cs | 63 + .../ConfigTypeSelectionPopup.cs.meta | 11 + .../ScriptableObjectEditorWindow.cs | 1058 ++++++++--------- 3 files changed, 579 insertions(+), 553 deletions(-) create mode 100644 Assets/Editor/Editor Windows/ConfigTypeSelectionPopup.cs create mode 100644 Assets/Editor/Editor Windows/ConfigTypeSelectionPopup.cs.meta diff --git a/Assets/Editor/Editor Windows/ConfigTypeSelectionPopup.cs b/Assets/Editor/Editor Windows/ConfigTypeSelectionPopup.cs new file mode 100644 index 0000000..09f4707 --- /dev/null +++ b/Assets/Editor/Editor Windows/ConfigTypeSelectionPopup.cs @@ -0,0 +1,63 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using UnityEditor; +using UnityEngine; + +namespace ScriptableObjectManager +{ + + // Custom Popup Window for Config Type Selection + internal class ConfigTypeSelectionPopup : PopupWindowContent + { + private readonly List SelectedTypes; + private readonly List AvailableTypes; + private readonly Action OnSelectionChanged; + private Vector2 ScrollPos = new(); + + public ConfigTypeSelectionPopup(List selectedTypes, Action onSelectionChanged, List availableTypes) + { + this.SelectedTypes = selectedTypes; + this.OnSelectionChanged = onSelectionChanged; + this.AvailableTypes = availableTypes; + } + + public override Vector2 GetWindowSize() + { + return new Vector2(200, 400); // Define the dimensions of the popup window + } + + public override void OnGUI(Rect rect) + { + GUILayout.Label("Select Config Types", EditorStyles.boldLabel); + + if (AvailableTypes.Count > 0) + { + ScrollPos = EditorGUILayout.BeginScrollView(ScrollPos); + + // Display each available type with a toggle to enable or disable it + foreach (var type in AvailableTypes) + { + bool isSelected = SelectedTypes.Contains(type); + bool toggle = EditorGUILayout.Toggle(type.Name, isSelected); + + if (toggle && !isSelected) + { + SelectedTypes.Add(type); // Add the type to the selection list + OnSelectionChanged.Invoke(); + ScriptableObjectEditorWindow.BasicFilters = SelectedTypes.Select(t => t.Name).ToArray(); + } + else if (!toggle && isSelected) + { + SelectedTypes.Remove(type); // Remove the type from the selection list + OnSelectionChanged.Invoke(); + ScriptableObjectEditorWindow.BasicFilters = SelectedTypes.Select(t => t.Name).ToArray(); + } + } + // Close the scrollable area within the popup + EditorGUILayout.EndScrollView(); + } + } + } + +} diff --git a/Assets/Editor/Editor Windows/ConfigTypeSelectionPopup.cs.meta b/Assets/Editor/Editor Windows/ConfigTypeSelectionPopup.cs.meta new file mode 100644 index 0000000..06bb933 --- /dev/null +++ b/Assets/Editor/Editor Windows/ConfigTypeSelectionPopup.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4b7d03e7a1e149747ba47b250170c625 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Editor/Editor Windows/ScriptableObjectEditorWindow.cs b/Assets/Editor/Editor Windows/ScriptableObjectEditorWindow.cs index ffc2f98..9dee34b 100644 --- a/Assets/Editor/Editor Windows/ScriptableObjectEditorWindow.cs +++ b/Assets/Editor/Editor Windows/ScriptableObjectEditorWindow.cs @@ -4,702 +4,654 @@ using System; using System.Linq; -public class ScriptableObjectEditorWindow : EditorWindow +namespace ScriptableObjectManager { - //prefs: - public const string BASIC_FILTERS_PREF = "basic_filters"; - public const string PROPERTY_SPACE_PREF = "property_space"; - public const string TABLE_ORIENTATION_PREF = "table_orientation"; - private const char SEPARATOR = '|'; // Filtrelerde kullanılmayacak özel bir karakter - public static string[] BasicFilters + public class ScriptableObjectEditorWindow : EditorWindow { - get - { - string savedFilters = EditorPrefs.GetString(BASIC_FILTERS_PREF, ""); - return string.IsNullOrEmpty(savedFilters) - ? new string[0] - : savedFilters.Split(new[] { SEPARATOR }, StringSplitOptions.RemoveEmptyEntries); - } - set - { - string filtersString = string.Join(SEPARATOR.ToString(), value); - EditorPrefs.SetString(BASIC_FILTERS_PREF, filtersString); - } - } + //prefs: + public const string BASIC_FILTERS_PREF = "basic_filters"; + public const string PROPERTY_SPACE_PREF = "property_space"; + public const string TABLE_ORIENTATION_PREF = "table_orientation"; + private const char SEPARATOR = '|'; // Filtrelerde kullanılmayacak özel bir karakter - // layout: - private readonly float PropertyMinWidth = 40; - private float PropertySpace = 5; - private Vector2 ScrollPosMain = new(); - private readonly GUILayoutOption[] GUIL_StandartOptions = new GUILayoutOption[] { GUILayout.MinWidth(100), GUILayout.ExpandWidth(true) }; - private readonly GUILayoutOption[] GUIL_DefaultOptions = new GUILayoutOption[] { GUILayout.MinWidth(150), GUILayout.ExpandWidth(true) }; - private bool OrientationVertical = true; // Determines the orientation of the layout (true: vertical. false: horizontal) - // data: - private List> groupedConfigs; // Stores ScriptableObjects grouped by their class types in nested lists - private List selectedTypes = new(); // Tracks which ScriptableObject types are currently selected for display - private List availableTypes = new(); // Holds all unique ScriptableObject types found in the project - - // textures: - private Texture2D spaceIcon; - private Texture2D orientationIcon; - private Texture2D ConfigOptionsIcon; - private Texture2D addConfigIcon; - private Texture2D refreshIcon; - private Texture2D filtersIcon; - - // Buttons Styles: - GUIContent spaceButton; - GUIContent orientationButton; - GUIContent refreshButton; - GUIContent filtersButton; - // create config button styles: - GUIContent AddConfigButton; - GUILayoutOption[] AddConfigButtonOptions; - GUIStyle buttonStyle; - // delete config button styles: - GUIContent ConfigOptionsButton; - GUILayoutOption[] ConfigOoptionsButtonOptions; - - // label styles: - GUIStyle centeredLabelStyle; - - // window: - [MenuItem("Window/Game Config Editor")] - public static void ShowWindow() - { - GetWindow("Game Config Editor"); - } - - private void OnEnable() - { - // Load the saved property space from EditorPrefs - float propSpace = EditorPrefs.GetFloat(PROPERTY_SPACE_PREF, -2); - if (propSpace == -2) + public static string[] BasicFilters { - // If no space is set, use the default value - PropertySpace = -1; - EditorPrefs.SetFloat(PROPERTY_SPACE_PREF, PropertySpace); + get + { + string savedFilters = EditorPrefs.GetString(BASIC_FILTERS_PREF, ""); + return string.IsNullOrEmpty(savedFilters) + ? new string[0] + : savedFilters.Split(new[] { SEPARATOR }, StringSplitOptions.RemoveEmptyEntries); + } + set + { + string filtersString = string.Join(SEPARATOR.ToString(), value); + EditorPrefs.SetString(BASIC_FILTERS_PREF, filtersString); + } } - else PropertySpace = propSpace; - - // Load the saved table orientation from EditorPrefs - OrientationVertical = EditorPrefs.GetBool(TABLE_ORIENTATION_PREF, true); - - // Initialize the editor by discovering available types and organizing ScriptableObjects accordingly - LoadAvailableTypes(); - GroupScriptableObjectsByType(); - // Load icons for UI buttons - LoadIcons(); + // layout: + private readonly float PropertyMinWidth = 40; + private float PropertySpace = 5; + private Vector2 ScrollPosMain = new(); + private readonly GUILayoutOption[] GUIL_StandartOptions = new GUILayoutOption[] { GUILayout.MinWidth(100), GUILayout.ExpandWidth(true) }; + private readonly GUILayoutOption[] GUIL_DefaultOptions = new GUILayoutOption[] { GUILayout.MinWidth(150), GUILayout.ExpandWidth(true) }; + private bool OrientationVertical = true; // Determines the orientation of the layout (true: vertical. false: horizontal) + // data: + private List> groupedConfigs; // Stores ScriptableObjects grouped by their class types in nested lists + private List selectedTypes = new(); // Tracks which ScriptableObject types are currently selected for display + private List availableTypes = new(); // Holds all unique ScriptableObject types found in the project + + // textures: + private Texture2D spaceIcon; + private Texture2D orientationIcon; + private Texture2D ConfigOptionsIcon; + private Texture2D addConfigIcon; + private Texture2D refreshIcon; + private Texture2D filtersIcon; + + // Buttons Styles: + GUIContent spaceButton; + GUIContent orientationButton; + GUIContent refreshButton; + GUIContent filtersButton; + // create config button styles: + GUIContent AddConfigButton; + GUILayoutOption[] AddConfigButtonOptions; + GUIStyle buttonStyle; + // delete config button styles: + GUIContent ConfigOptionsButton; + GUILayoutOption[] ConfigOoptionsButtonOptions; + + // label styles: + GUIStyle centeredLabelStyle; + + // window: + [MenuItem("Window/Game Config Editor")] + public static void ShowWindow() + { + GetWindow("Game Config Editor"); + } + + private void OnEnable() + { + // Load the saved property space from EditorPrefs + float propSpace = EditorPrefs.GetFloat(PROPERTY_SPACE_PREF, -2); + if (propSpace == -2) + { + // If no space is set, use the default value + PropertySpace = -1; + EditorPrefs.SetFloat(PROPERTY_SPACE_PREF, PropertySpace); + } + else PropertySpace = propSpace; - // setup styles - SetupButtonStyles(); - } + // Load the saved table orientation from EditorPrefs + OrientationVertical = EditorPrefs.GetBool(TABLE_ORIENTATION_PREF, true); - /// - /// Sets up the GUI buttons with their respective icons and tooltips. - /// - private void SetupButtonStyles() - { - // GUI content for space button - if (spaceIcon != null) - { - spaceButton = new GUIContent(spaceIcon, "change space between parameters"); - } - else - { - spaceButton = new GUIContent("space", "change space between parameters"); - } + // Initialize the editor by discovering available types and organizing ScriptableObjects accordingly + LoadAvailableTypes(); + GroupScriptableObjectsByType(); - // GUI content for orientation button - if (orientationIcon != null) - { - orientationButton = new GUIContent(orientationIcon, "change the table orientation"); - } - else - { - orientationButton = new GUIContent("rotate", "change the table orientation"); - } + // Load icons for UI buttons + LoadIcons(); - // GUI content for refresh button - if (refreshIcon != null) - { - refreshButton = new GUIContent(refreshIcon, "refresh"); - } - else - { - refreshButton = new GUIContent("refresh", "refresh"); + // setup styles + SetupButtonStyles(); } - // GUI content for filters button - if (filtersIcon != null) + /// + /// Sets up the GUI buttons with their respective icons and tooltips. + /// + private void SetupButtonStyles() { - filtersButton = new GUIContent(filtersIcon, "filters"); - } - else - { - filtersButton = new GUIContent("filters", "filters"); - } + // GUI content for space button + if (spaceIcon != null) + { + spaceButton = new GUIContent(spaceIcon, "change space between parameters"); + } + else + { + spaceButton = new GUIContent("space", "change space between parameters"); + } - // 'create config' button styles - if (addConfigIcon != null) - { - AddConfigButton = new GUIContent(addConfigIcon, "create new config"); - AddConfigButtonOptions = new GUILayoutOption[] { GUILayout.Height(20), GUILayout.Width(20) }; - } - else - { - AddConfigButton = new GUIContent("Add new", "create new config"); - AddConfigButtonOptions = new GUILayoutOption[] { GUILayout.Width(65) }; - } + // GUI content for orientation button + if (orientationIcon != null) + { + orientationButton = new GUIContent(orientationIcon, "change the table orientation"); + } + else + { + orientationButton = new GUIContent("rotate", "change the table orientation"); + } - // 'delete config' button styles - if (ConfigOptionsIcon != null) - { - ConfigOptionsButton = new GUIContent(ConfigOptionsIcon, "delete config permanently"); - ConfigOoptionsButtonOptions = new GUILayoutOption[] { GUILayout.Height(20), GUILayout.Width(20) }; - } - else - { - ConfigOptionsButton = new GUIContent("del", "delete config permanently"); - ConfigOoptionsButtonOptions = new GUILayoutOption[] { GUILayout.Width(30) }; - } - } + // GUI content for refresh button + if (refreshIcon != null) + { + refreshButton = new GUIContent(refreshIcon, "refresh"); + } + else + { + refreshButton = new GUIContent("refresh", "refresh"); + } - private void OnGUI() - { - EditorGUILayout.BeginHorizontal(); + // GUI content for filters button + if (filtersIcon != null) + { + filtersButton = new GUIContent(filtersIcon, "filters"); + } + else + { + filtersButton = new GUIContent("filters", "filters"); + } - // A button to set space between properties - if (GUILayout.Button(spaceButton, GUILayout.Width(50))) - { - SetSpace(); - } + // 'create config' button styles + if (addConfigIcon != null) + { + AddConfigButton = new GUIContent(addConfigIcon, "create new config"); + AddConfigButtonOptions = new GUILayoutOption[] { GUILayout.Height(20), GUILayout.Width(20) }; + } + else + { + AddConfigButton = new GUIContent("Add new", "create new config"); + AddConfigButtonOptions = new GUILayoutOption[] { GUILayout.Width(65) }; + } - // A button to change the orientation of the table - if (GUILayout.Button(orientationButton, GUILayout.Width(50))) - { - if (OrientationVertical) + // 'delete config' button styles + if (ConfigOptionsIcon != null) { - OrientationVertical = false; - EditorPrefs.SetBool(TABLE_ORIENTATION_PREF, OrientationVertical); + ConfigOptionsButton = new GUIContent(ConfigOptionsIcon, "delete config permanently"); + ConfigOoptionsButtonOptions = new GUILayoutOption[] { GUILayout.Height(20), GUILayout.Width(20) }; } else { - OrientationVertical = true; - EditorPrefs.SetBool(TABLE_ORIENTATION_PREF, OrientationVertical); + ConfigOptionsButton = new GUIContent("del", "delete config permanently"); + ConfigOoptionsButtonOptions = new GUILayoutOption[] { GUILayout.Width(30) }; } } - EditorGUILayout.Space(); - - // A button to refresh the list of ScriptableObjects - if (GUILayout.Button(refreshButton, GUILayout.Width(50))) + private void OnGUI() { - RefreshAll(); - } + EditorGUILayout.BeginHorizontal(); - // Display a popup window at the mouse position for basic filters - if (GUILayout.Button(filtersButton, GUILayout.Width(50))) - { - Vector2 mousePosition = Event.current.mousePosition; - PopupWindow.Show(new Rect(mousePosition.x, mousePosition.y + 20, 0, 0), new ConfigTypeSelectionPopup(selectedTypes, GroupScriptableObjectsByType, availableTypes)); - } - EditorGUILayout.EndHorizontal(); + // A button to set space between properties + if (GUILayout.Button(spaceButton, GUILayout.Width(50))) + { + SetSpace(); + } - EditorGUILayout.Space(5); + // A button to change the orientation of the table + if (GUILayout.Button(orientationButton, GUILayout.Width(50))) + { + if (OrientationVertical) + { + OrientationVertical = false; + EditorPrefs.SetBool(TABLE_ORIENTATION_PREF, OrientationVertical); + } + else + { + OrientationVertical = true; + EditorPrefs.SetBool(TABLE_ORIENTATION_PREF, OrientationVertical); + } + } - // if there is no SO loaded or selected from filters show a message - if (selectedTypes == null || selectedTypes.Count == 0 || groupedConfigs == null || groupedConfigs.Count == 0) - { - EditorGUILayout.LabelField("[No Config Selected]", EditorStyles.boldLabel); - return; - } + EditorGUILayout.Space(); - // show configs - ScrollPosMain = EditorGUILayout.BeginScrollView(ScrollPosMain); - if (groupedConfigs.Count != 0) - { - foreach (var configGroup in groupedConfigs) + // A button to refresh the list of ScriptableObjects + if (GUILayout.Button(refreshButton, GUILayout.Width(50))) { - // Only display groups that match the selected types or if no specific types are filtered - if (selectedTypes.Count == 0 || !selectedTypes.Contains(configGroup[0].GetType())) - continue; + RefreshAll(); + } - GUILayout.Space(20); + // Display a popup window at the mouse position for basic filters + if (GUILayout.Button(filtersButton, GUILayout.Width(50))) + { + Vector2 mousePosition = Event.current.mousePosition; + PopupWindow.Show(new Rect(mousePosition.x, mousePosition.y + 20, 0, 0), new ConfigTypeSelectionPopup(selectedTypes, GroupScriptableObjectsByType, availableTypes)); + } + EditorGUILayout.EndHorizontal(); - EditorGUILayout.BeginHorizontal(); + EditorGUILayout.Space(5); - // 'create config' button styles - if (addConfigIcon != null) - { - buttonStyle = new GUIStyle(GUI.skin.button); - buttonStyle.padding = new RectOffset(2, 2, 2, 2); - buttonStyle.imagePosition = ImagePosition.ImageOnly; - } + // if there is no SO loaded or selected from filters show a message + if (selectedTypes == null || selectedTypes.Count == 0 || groupedConfigs == null || groupedConfigs.Count == 0) + { + EditorGUILayout.LabelField("[No Config Selected]", EditorStyles.boldLabel); + return; + } - // create config button: - if (GUILayout.Button(AddConfigButton, buttonStyle, AddConfigButtonOptions)) + // show configs + ScrollPosMain = EditorGUILayout.BeginScrollView(ScrollPosMain); + if (groupedConfigs.Count != 0) + { + foreach (var configGroup in groupedConfigs) { - AddNewSO(configGroup[0].GetType()); - } + // Only display groups that match the selected types or if no specific types are filtered + if (selectedTypes.Count == 0 || !selectedTypes.Contains(configGroup[0].GetType())) + continue; - // show name of the ScriptableObject type - centeredLabelStyle = new GUIStyle(EditorStyles.boldLabel); - centeredLabelStyle.fontSize = 16; - GUILayout.Label(configGroup[0].GetType().Name, centeredLabelStyle); + GUILayout.Space(20); - EditorGUILayout.EndHorizontal(); - - // table: - if (OrientationVertical) - { EditorGUILayout.BeginHorizontal(); - PutPropertiesForObject_V(configGroup); - EditorGUILayout.EndHorizontal(); - } - else - { - EditorGUILayout.BeginVertical("box"); - PutPropertiesForObject_H(configGroup); - EditorGUILayout.EndVertical(); + + // 'create config' button styles + if (addConfigIcon != null) + { + buttonStyle = new GUIStyle(GUI.skin.button); + buttonStyle.padding = new RectOffset(2, 2, 2, 2); + buttonStyle.imagePosition = ImagePosition.ImageOnly; + } + + // create config button: + if (GUILayout.Button(AddConfigButton, buttonStyle, AddConfigButtonOptions)) + { + AddNewSO(configGroup[0].GetType()); + } + + // show name of the ScriptableObject type + centeredLabelStyle = new GUIStyle(EditorStyles.boldLabel); + centeredLabelStyle.fontSize = 16; + GUILayout.Label(configGroup[0].GetType().Name, centeredLabelStyle); + + EditorGUILayout.EndHorizontal(); + + // table: + if (OrientationVertical) + { + EditorGUILayout.BeginHorizontal(); + PutPropertiesForObject_V(configGroup); + EditorGUILayout.EndHorizontal(); + } + else + { + EditorGUILayout.BeginVertical("box"); + PutPropertiesForObject_H(configGroup); + EditorGUILayout.EndVertical(); + } } } + EditorGUILayout.EndScrollView(); } - EditorGUILayout.EndScrollView(); - } - private void SetSpace() - { - float propSpace = EditorPrefs.GetFloat(PROPERTY_SPACE_PREF, -2); - if (propSpace == -2) - { - // If no space is set, use the default value - PropertySpace = -1; - EditorPrefs.SetFloat(PROPERTY_SPACE_PREF, PropertySpace); - } - else + private void SetSpace() { - // If space is already set, increase it by 1 - PropertySpace += 1; + float propSpace = EditorPrefs.GetFloat(PROPERTY_SPACE_PREF, -2); + if (propSpace == -2) + { + // If no space is set, use the default value + PropertySpace = -1; + EditorPrefs.SetFloat(PROPERTY_SPACE_PREF, PropertySpace); + } + else + { + // If space is already set, increase it by 1 + PropertySpace += 1; - // If the space exceeds 5, reset it to 0 - if (PropertySpace > 5) PropertySpace = -1; + // If the space exceeds 5, reset it to 0 + if (PropertySpace > 5) PropertySpace = -1; - // Save the new space value - EditorPrefs.SetFloat(PROPERTY_SPACE_PREF, PropertySpace); + // Save the new space value + EditorPrefs.SetFloat(PROPERTY_SPACE_PREF, PropertySpace); - Debug.Log("Property Space: " + PropertySpace); + Debug.Log("Property Space: " + PropertySpace); + } } - } - - private void RefreshAll() - { - LoadAvailableTypes(); - GroupScriptableObjectsByType(); - } - void AddNewSO(Type type) - { - // Create a new instance of the selected ScriptableObject type - ScriptableObject newConfig = ScriptableObject.CreateInstance(type); - - // Save file panel that works within the project (Assets/) - string path = EditorUtility.SaveFilePanelInProject( - "Save Config", - type.Name + ".asset", - "asset", - "Please enter a file name to save the ScriptableObject.", - "Assets/Resources/ScriptableObjects" - ); - - if (!string.IsNullOrEmpty(path)) + private void RefreshAll() { - AssetDatabase.CreateAsset(newConfig, path); - AssetDatabase.SaveAssets(); - AssetDatabase.Refresh(); + LoadAvailableTypes(); + GroupScriptableObjectsByType(); } - RefreshAll(); - } - private void LoadIcons() - { - spaceIcon = AssetDatabase.LoadAssetAtPath("Assets/Editor/Editor Windows/Icons/space.png"); - orientationIcon = AssetDatabase.LoadAssetAtPath("Assets/Editor/Editor Windows/Icons/orientation.png"); - ConfigOptionsIcon = AssetDatabase.LoadAssetAtPath("Assets/Editor/Editor Windows/Icons/options.png"); - addConfigIcon = AssetDatabase.LoadAssetAtPath("Assets/Editor/Editor Windows/Icons/add file.png"); - refreshIcon = AssetDatabase.LoadAssetAtPath("Assets/Editor/Editor Windows/Icons/refresh.png"); - filtersIcon = AssetDatabase.LoadAssetAtPath("Assets/Editor/Editor Windows/Icons/filter.png"); - - if (spaceIcon == null) - { - Debug.LogError("space Icon not found in: Assets/Editor/Editor Windows/Icons/space.png"); - } - if (orientationIcon == null) - { - Debug.LogError("orientation Icon not found in: Assets/Editor/Editor Windows/Icons/orientation.png"); - } - if(ConfigOptionsIcon == null) - { - Debug.LogError("ConfigOptions Icon not found in: Assets/Editor/Editor Windows/Icons/options.png"); - } - if (addConfigIcon == null) - { - Debug.LogError("addConfig Icon not found in: Assets/Editor/Editor Windows/Icons/add file.png"); - } - if (refreshIcon == null) - { - Debug.LogError("refresh Icon not found in: Assets/Editor/Editor Windows/Icons/refresh.png"); - } - if (filtersIcon == null) + void AddNewSO(Type type) { - Debug.LogError("filters Icon not found in: Assets/Editor/Editor Windows/Icons/filter.png"); - } - } + // Create a new instance of the selected ScriptableObject type + ScriptableObject newConfig = ScriptableObject.CreateInstance(type); - private void LoadAvailableTypes() - { - selectedTypes.Clear(); - // Scan the "ScriptableObjects" folder to find all unique ScriptableObject types - availableTypes = Resources.LoadAll("ScriptableObjects").Select(t => t.GetType()).Distinct().ToList(); - foreach (var filter in BasicFilters) - { - if (string.IsNullOrEmpty(filter)) - continue; - // Add any additional types specified in the basic filters - var type = availableTypes.FirstOrDefault(t => t.Name == filter); - if (type != null) + // Save file panel that works within the project (Assets/) + string path = EditorUtility.SaveFilePanelInProject( + "Save Config", + type.Name + ".asset", + "asset", + "Please enter a file name to save the ScriptableObject.", + "Assets/Resources/ScriptableObjects" + ); + + if (!string.IsNullOrEmpty(path)) { - selectedTypes.Add(type); + AssetDatabase.CreateAsset(newConfig, path); + AssetDatabase.SaveAssets(); + AssetDatabase.Refresh(); } + RefreshAll(); } - } - private void GroupScriptableObjectsByType() - { - // Fetch all ScriptableObjects from a designated folder and organize them into groups based on their class types - var configs = Resources.LoadAll("").ToList(); - - groupedConfigs = configs - .GroupBy(c => c.GetType()) - .Where(g => selectedTypes.Count == 0 || selectedTypes.Contains(g.Key)) // Only include groups matching the current type filter - .Select(g => g.ToList()) // Convert each group into a list of ScriptableObjects - .ToList(); - } + private void LoadIcons() + { + spaceIcon = AssetDatabase.LoadAssetAtPath("Assets/Editor/Editor Windows/Icons/space.png"); + orientationIcon = AssetDatabase.LoadAssetAtPath("Assets/Editor/Editor Windows/Icons/orientation.png"); + ConfigOptionsIcon = AssetDatabase.LoadAssetAtPath("Assets/Editor/Editor Windows/Icons/options.png"); + addConfigIcon = AssetDatabase.LoadAssetAtPath("Assets/Editor/Editor Windows/Icons/add file.png"); + refreshIcon = AssetDatabase.LoadAssetAtPath("Assets/Editor/Editor Windows/Icons/refresh.png"); + filtersIcon = AssetDatabase.LoadAssetAtPath("Assets/Editor/Editor Windows/Icons/filter.png"); + if (spaceIcon == null) + { + Debug.LogError("space Icon not found in: Assets/Editor/Editor Windows/Icons/space.png"); + } + if (orientationIcon == null) + { + Debug.LogError("orientation Icon not found in: Assets/Editor/Editor Windows/Icons/orientation.png"); + } + if (ConfigOptionsIcon == null) + { + Debug.LogError("ConfigOptions Icon not found in: Assets/Editor/Editor Windows/Icons/options.png"); + } + if (addConfigIcon == null) + { + Debug.LogError("addConfig Icon not found in: Assets/Editor/Editor Windows/Icons/add file.png"); + } + if (refreshIcon == null) + { + Debug.LogError("refresh Icon not found in: Assets/Editor/Editor Windows/Icons/refresh.png"); + } + if (filtersIcon == null) + { + Debug.LogError("filters Icon not found in: Assets/Editor/Editor Windows/Icons/filter.png"); + } + } - /// - /// create a vertival table for the properties of the object - /// - private void PutPropertiesForObject_V(List Configs) where T : ScriptableObject - { - try + private void LoadAvailableTypes() { - EditorGUILayout.BeginVertical("box", GUILayout.Width(170)); - try + selectedTypes.Clear(); + // Scan the "ScriptableObjects" folder to find all unique ScriptableObject types + availableTypes = Resources.LoadAll("ScriptableObjects").Select(t => t.GetType()).Distinct().ToList(); + foreach (var filter in BasicFilters) { - // An empty label to align property names properly in the UI - EditorGUILayout.LabelField("", GUILayout.MinWidth(PropertyMinWidth)); - - // Iterate through the properties of the first ScriptableObject to display their names - SerializedObject serializedObject = new(Configs[0]); - SerializedProperty property = serializedObject.GetIterator(); - - bool ShouldNext = property.NextVisible(true); - while (ShouldNext) + if (string.IsNullOrEmpty(filter)) + continue; + // Add any additional types specified in the basic filters + var type = availableTypes.FirstOrDefault(t => t.Name == filter); + if (type != null) { - if (property.propertyType != SerializedPropertyType.ArraySize && property.name != "m_Script" && property.name != "data") // Exclude internal Unity fields and arrays - { - // Show the name of each property as a label - EditorGUILayout.LabelField(property.name, GUIL_StandartOptions); - // if any property is bigger than expected this will calculate extra space needed (ex: array properties can expand) - if (property.isExpanded) - GUILayout.Space(CalculatePropertyHeight(Configs, property) - EditorGUIUtility.singleLineHeight); - GUILayout.Space(PropertySpace); - } - ShouldNext = property.NextVisible(false); // Move to the next property, skipping nested children + selectedTypes.Add(type); } } - catch - { - // If an error occurs, refresh the type list and regroup the objects - LoadAvailableTypes(); - GroupScriptableObjectsByType(); - } - EditorGUILayout.EndVertical(); + } + + private void GroupScriptableObjectsByType() + { + // Fetch all ScriptableObjects from a designated folder and organize them into groups based on their class types + var configs = Resources.LoadAll("").ToList(); + + groupedConfigs = configs + .GroupBy(c => c.GetType()) + .Where(g => selectedTypes.Count == 0 || selectedTypes.Contains(g.Key)) // Only include groups matching the current type filter + .Select(g => g.ToList()) // Convert each group into a list of ScriptableObjects + .ToList(); + } - if (Configs.Count == 0) - return; // Exit if there are no configurations to display - foreach (var Config in Configs) + /// + /// create a vertival table for the properties of the object + /// + private void PutPropertiesForObject_V(List Configs) where T : ScriptableObject + { + try { - EditorGUILayout.BeginVertical("box"); + EditorGUILayout.BeginVertical("box", GUILayout.Width(170)); try { - // Retrieve and display the asset's file name without its extension - string filePath = AssetDatabase.GetAssetPath(Config); - string fileName = System.IO.Path.GetFileNameWithoutExtension(filePath); - if (fileName == "") throw new System.Exception(); - - // Display the file name and a delete button for the asset - EditorGUILayout.BeginHorizontal(); - GUIContent propertyContent = new GUIContent(fileName, fileName); - EditorGUILayout.LabelField(propertyContent, EditorStyles.miniBoldLabel, GUILayout.MinWidth(PropertyMinWidth)); - OptionsButton(Config); - EditorGUILayout.EndHorizontal(); + // An empty label to align property names properly in the UI + EditorGUILayout.LabelField("", GUILayout.MinWidth(PropertyMinWidth)); - SerializedObject serializedObject = new(Config); + // Iterate through the properties of the first ScriptableObject to display their names + SerializedObject serializedObject = new(Configs[0]); SerializedProperty property = serializedObject.GetIterator(); - // Iterate through all properties to create editable fields based on their types bool ShouldNext = property.NextVisible(true); while (ShouldNext) { - if (property.propertyType != SerializedPropertyType.ArraySize && property.name != "m_Script" && property.name != "data") // Skip unwanted properties + if (property.propertyType != SerializedPropertyType.ArraySize && property.name != "m_Script" && property.name != "data") // Exclude internal Unity fields and arrays { - EditorGUILayout.PropertyField(property, GUIContent.none, true, GUIL_DefaultOptions); + // Show the name of each property as a label + EditorGUILayout.LabelField(property.name, GUIL_StandartOptions); + // if any property is bigger than expected this will calculate extra space needed (ex: array properties can expand) if (property.isExpanded) - { - float extraSpace = CalculatePropertyHeight(Configs, property); - extraSpace -= EditorGUI.GetPropertyHeight(property); - GUILayout.Space(extraSpace); - } + GUILayout.Space(CalculatePropertyHeight(Configs, property) - EditorGUIUtility.singleLineHeight); GUILayout.Space(PropertySpace); - serializedObject.ApplyModifiedProperties(); } - ShouldNext = property.NextVisible(false); // Advance to the next property, excluding nested fields + ShouldNext = property.NextVisible(false); // Move to the next property, skipping nested children } - property.Reset(); } catch { - // Handle errors by refreshing the type list and regrouping + // If an error occurs, refresh the type list and regroup the objects LoadAvailableTypes(); GroupScriptableObjectsByType(); } EditorGUILayout.EndVertical(); - } - } - catch - { - // Catch any top-level errors and reset the data - LoadAvailableTypes(); - GroupScriptableObjectsByType(); - } - } - - private void OptionsButton(T Config) where T : ScriptableObject - { - - GUIStyle buttonStyle = new GUIStyle(GUI.skin.button); + if (Configs.Count == 0) + return; // Exit if there are no configurations to display - if (ConfigOptionsIcon != null) - { - buttonStyle.padding = new RectOffset(2, 2, 2, 2); - buttonStyle.imagePosition = ImagePosition.ImageOnly; - } - - if (GUILayout.Button(ConfigOptionsButton, buttonStyle, ConfigOoptionsButtonOptions)) - { - ShowOptionsMenu(Config); - } - } - - private void ShowOptionsMenu(T Config) where T : ScriptableObject - { - GenericMenu menu = new GenericMenu(); - - menu.AddItem(new GUIContent("Delete Config"), false, () => DeleteConfig(Config)); - menu.AddSeparator(""); - menu.AddItem(new GUIContent("Show In Project Folder"), false, () => ShowInProjectFolders(Config)); - - menu.ShowAsContext(); - } - - /// - /// create a Horizontal (parameters will be horizontal) table for the properties of the object - /// - private void PutPropertiesForObject_H(List Configs) where T : ScriptableObject - { - try - { - // property names on horizontal line: - EditorGUILayout.BeginHorizontal(); - try - { - // An empty label to align property names properly in the UI - EditorGUILayout.LabelField("", GUILayout.Width(152)); - - // Iterate through the properties of the first ScriptableObject to display their names - SerializedObject serializedObject = new(Configs[0]); - SerializedProperty property = serializedObject.GetIterator(); - - bool ShouldNext = property.NextVisible(true); - while (ShouldNext) + foreach (var Config in Configs) { - if (property.propertyType != SerializedPropertyType.ArraySize && property.name != "m_Script" && property.name != "data") // Exclude internal Unity fields and arrays + EditorGUILayout.BeginVertical("box"); + try { - // Show the name of each property as a label - EditorGUILayout.LabelField(property.name, GUIL_StandartOptions); + // Retrieve and display the asset's file name without its extension + string filePath = AssetDatabase.GetAssetPath(Config); + string fileName = System.IO.Path.GetFileNameWithoutExtension(filePath); + if (fileName == "") throw new System.Exception(); + + // Display the file name and a delete button for the asset + EditorGUILayout.BeginHorizontal(); + GUIContent propertyContent = new GUIContent(fileName, fileName); + EditorGUILayout.LabelField(propertyContent, EditorStyles.miniBoldLabel, GUILayout.MinWidth(PropertyMinWidth)); + OptionsButton(Config); + EditorGUILayout.EndHorizontal(); + + SerializedObject serializedObject = new(Config); + SerializedProperty property = serializedObject.GetIterator(); + + // Iterate through all properties to create editable fields based on their types + bool ShouldNext = property.NextVisible(true); + while (ShouldNext) + { + if (property.propertyType != SerializedPropertyType.ArraySize && property.name != "m_Script" && property.name != "data") // Skip unwanted properties + { + EditorGUILayout.PropertyField(property, GUIContent.none, true, GUIL_DefaultOptions); + if (property.isExpanded) + { + float extraSpace = CalculatePropertyHeight(Configs, property); + extraSpace -= EditorGUI.GetPropertyHeight(property); + GUILayout.Space(extraSpace); + } + GUILayout.Space(PropertySpace); + serializedObject.ApplyModifiedProperties(); + } + ShouldNext = property.NextVisible(false); // Advance to the next property, excluding nested fields + } + property.Reset(); } - ShouldNext = property.NextVisible(false); // Move to the next property, skipping nested children + catch + { + // Handle errors by refreshing the type list and regrouping + LoadAvailableTypes(); + GroupScriptableObjectsByType(); + } + EditorGUILayout.EndVertical(); } + } catch { - // If an error occurs, refresh the type list and regroup the objects + // Catch any top-level errors and reset the data LoadAvailableTypes(); GroupScriptableObjectsByType(); } - EditorGUILayout.EndHorizontal(); + } - // Exit if there are no configurations to display - if (Configs.Count == 0) - return; + private void OptionsButton(T Config) where T : ScriptableObject + { + + GUIStyle buttonStyle = new GUIStyle(GUI.skin.button); - // Iterate through each ScriptableObject in the list - foreach (var Config in Configs) + if (ConfigOptionsIcon != null) { + buttonStyle.padding = new RectOffset(2, 2, 2, 2); + buttonStyle.imagePosition = ImagePosition.ImageOnly; + } + + if (GUILayout.Button(ConfigOptionsButton, buttonStyle, ConfigOoptionsButtonOptions)) + { + ShowOptionsMenu(Config); + } + } + + private void ShowOptionsMenu(T Config) where T : ScriptableObject + { + GenericMenu menu = new GenericMenu(); + + menu.AddItem(new GUIContent("Delete Config"), false, () => DeleteConfig(Config)); + + menu.AddSeparator(""); + menu.AddItem(new GUIContent("Show In Project Folder"), false, () => ShowInProjectFolders(Config)); + menu.ShowAsContext(); + } + + /// + /// create a Horizontal (parameters will be horizontal) table for the properties of the object + /// + private void PutPropertiesForObject_H(List Configs) where T : ScriptableObject + { + try + { + // property names on horizontal line: EditorGUILayout.BeginHorizontal(); try { - // Retrieve and display the asset's file name without its extension - string filePath = AssetDatabase.GetAssetPath(Config); - string fileName = System.IO.Path.GetFileNameWithoutExtension(filePath); - if (fileName == "") throw new System.Exception(); - - // Display the file name for the asset - GUIContent propertyContent = new GUIContent(fileName, fileName); - EditorGUILayout.LabelField(propertyContent, EditorStyles.miniBoldLabel, GUILayout.Width(120)); - - // Display a delete button for the asset - OptionsButton(Config); + // An empty label to align property names properly in the UI + EditorGUILayout.LabelField("", GUILayout.Width(152)); - SerializedObject serializedObject = new(Config); + // Iterate through the properties of the first ScriptableObject to display their names + SerializedObject serializedObject = new(Configs[0]); SerializedProperty property = serializedObject.GetIterator(); - // Iterate through all properties to create editable fields based on their types bool ShouldNext = property.NextVisible(true); while (ShouldNext) { - if (property.propertyType != SerializedPropertyType.ArraySize && property.name != "m_Script" && property.name != "data") // Skip unwanted properties + if (property.propertyType != SerializedPropertyType.ArraySize && property.name != "m_Script" && property.name != "data") // Exclude internal Unity fields and arrays { - EditorGUILayout.PropertyField(property, GUIContent.none, true, GUIL_DefaultOptions); - serializedObject.ApplyModifiedProperties(); + // Show the name of each property as a label + EditorGUILayout.LabelField(property.name, GUIL_StandartOptions); } - ShouldNext = property.NextVisible(false); // Advance to the next property, excluding nested fields + ShouldNext = property.NextVisible(false); // Move to the next property, skipping nested children } - property.Reset(); } catch { - // Handle errors by refreshing the type list and regrouping + // If an error occurs, refresh the type list and regroup the objects LoadAvailableTypes(); GroupScriptableObjectsByType(); } EditorGUILayout.EndHorizontal(); - GUILayout.Space(PropertySpace); - } - } - catch - { - // Catch any top-level errors and reset the data - LoadAvailableTypes(); - GroupScriptableObjectsByType(); - } - } + // Exit if there are no configurations to display + if (Configs.Count == 0) + return; - private void DeleteConfig(T Config) where T : ScriptableObject - { - if (EditorUtility.DisplayDialog("Delete Config", "Are you sure you want to delete this config? \n\nYou cannot undo delete assets action.", "Yes", "No")) - { - AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(Config)); - AssetDatabase.SaveAssets(); - AssetDatabase.Refresh(); - GroupScriptableObjectsByType(); // Refresh the list after deletion - } - } + // Iterate through each ScriptableObject in the list + foreach (var Config in Configs) + { + EditorGUILayout.BeginHorizontal(); + try + { + // Retrieve and display the asset's file name without its extension + string filePath = AssetDatabase.GetAssetPath(Config); + string fileName = System.IO.Path.GetFileNameWithoutExtension(filePath); + if (fileName == "") throw new System.Exception(); - private void ShowInProjectFolders(T Config) where T : ScriptableObject - { - string path = AssetDatabase.GetAssetPath(Config); - EditorUtility.FocusProjectWindow(); - Selection.activeObject = AssetDatabase.LoadAssetAtPath(path); - } + // Display the file name for the asset + GUIContent propertyContent = new GUIContent(fileName, fileName); + EditorGUILayout.LabelField(propertyContent, EditorStyles.miniBoldLabel, GUILayout.Width(120)); - public static float CalculatePropertyHeight(List configs, SerializedProperty property) where T : ScriptableObject - { - float maxHeight = 0f; + // Display a delete button for the asset + OptionsButton(Config); + GUILayout.Space(3); - foreach (var config in configs) - { - SerializedObject serializedObject = new(config); - SerializedProperty targetProperty = serializedObject.FindProperty(property.propertyPath); + SerializedObject serializedObject = new(Config); + SerializedProperty property = serializedObject.GetIterator(); - if (targetProperty != null) + // Iterate through all properties to create editable fields based on their types + bool ShouldNext = property.NextVisible(true); + while (ShouldNext) + { + if (property.propertyType != SerializedPropertyType.ArraySize && property.name != "m_Script" && property.name != "data") // Skip unwanted properties + { + EditorGUILayout.PropertyField(property, GUIContent.none, true, GUIL_DefaultOptions); + serializedObject.ApplyModifiedProperties(); + } + ShouldNext = property.NextVisible(false); // Advance to the next property, excluding nested fields + } + property.Reset(); + } + catch + { + // Handle errors by refreshing the type list and regrouping + LoadAvailableTypes(); + GroupScriptableObjectsByType(); + } + EditorGUILayout.EndHorizontal(); + GUILayout.Space(PropertySpace); + } + } + catch { - float height = EditorGUI.GetPropertyHeight(targetProperty, true); - maxHeight = Mathf.Max(maxHeight, height); + // Catch any top-level errors and reset the data + LoadAvailableTypes(); + GroupScriptableObjectsByType(); } } - return maxHeight; - } - -} -// Custom Popup Window for Config Type Selection -public class ConfigTypeSelectionPopup : PopupWindowContent -{ - private readonly List SelectedTypes; - private readonly List AvailableTypes; - private readonly Action OnSelectionChanged; - private Vector2 ScrollPos = new(); - - public ConfigTypeSelectionPopup(List selectedTypes, Action onSelectionChanged, List availableTypes) - { - this.SelectedTypes = selectedTypes; - this.OnSelectionChanged = onSelectionChanged; - this.AvailableTypes = availableTypes; - } - - public override Vector2 GetWindowSize() - { - return new Vector2(200, 400); // Define the dimensions of the popup window - } + private void DeleteConfig(T Config) where T : ScriptableObject + { + if (EditorUtility.DisplayDialog("Delete Config", "Are you sure you want to delete this config? \n\nYou cannot undo delete assets action.", "Yes", "No")) + { + AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(Config)); + AssetDatabase.SaveAssets(); + AssetDatabase.Refresh(); + GroupScriptableObjectsByType(); // Refresh the list after deletion + } + } - public override void OnGUI(Rect rect) - { - GUILayout.Label("Select Config Types", EditorStyles.boldLabel); + private void ShowInProjectFolders(T Config) where T : ScriptableObject + { + string path = AssetDatabase.GetAssetPath(Config); + EditorUtility.FocusProjectWindow(); + Selection.activeObject = AssetDatabase.LoadAssetAtPath(path); + } - if (AvailableTypes.Count > 0) + public static float CalculatePropertyHeight(List configs, SerializedProperty property) where T : ScriptableObject { - ScrollPos = EditorGUILayout.BeginScrollView(ScrollPos); + float maxHeight = 0f; - // Display each available type with a toggle to enable or disable it - foreach (var type in AvailableTypes) + foreach (var config in configs) { - bool isSelected = SelectedTypes.Contains(type); - bool toggle = EditorGUILayout.Toggle(type.Name, isSelected); + SerializedObject serializedObject = new(config); + SerializedProperty targetProperty = serializedObject.FindProperty(property.propertyPath); - if (toggle && !isSelected) + if (targetProperty != null) { - SelectedTypes.Add(type); // Add the type to the selection list - OnSelectionChanged.Invoke(); - ScriptableObjectEditorWindow.BasicFilters = SelectedTypes.Select(t => t.Name).ToArray(); - } - else if (!toggle && isSelected) - { - SelectedTypes.Remove(type); // Remove the type from the selection list - OnSelectionChanged.Invoke(); - ScriptableObjectEditorWindow.BasicFilters = SelectedTypes.Select(t => t.Name).ToArray(); + float height = EditorGUI.GetPropertyHeight(targetProperty, true); + maxHeight = Mathf.Max(maxHeight, height); } } - // Close the scrollable area within the popup - EditorGUILayout.EndScrollView(); + + return maxHeight; } + } } \ No newline at end of file From 1fb78da8d25f31b113674c70d48a3d020e82059b Mon Sep 17 00:00:00 2001 From: yunus bozkurtaca Date: Fri, 23 May 2025 18:37:48 +0300 Subject: [PATCH 5/8] config rename option added --- Assets/Editor/Editor Windows/Icons/check.png | Bin 0 -> 273 bytes .../Editor Windows/Icons/check.png.meta | 127 ++++++++++++++++++ .../ScriptableObjectEditorWindow.cs | 99 ++++++++++++-- .../{TestConfig 2.asset => TestConfig3.asset} | 2 +- ...ig 2.asset.meta => TestConfig3.asset.meta} | 0 5 files changed, 218 insertions(+), 10 deletions(-) create mode 100644 Assets/Editor/Editor Windows/Icons/check.png create mode 100644 Assets/Editor/Editor Windows/Icons/check.png.meta rename Assets/Resources/ScriptableObjects/{TestConfig 2.asset => TestConfig3.asset} (96%) rename Assets/Resources/ScriptableObjects/{TestConfig 2.asset.meta => TestConfig3.asset.meta} (100%) diff --git a/Assets/Editor/Editor Windows/Icons/check.png b/Assets/Editor/Editor Windows/Icons/check.png new file mode 100644 index 0000000000000000000000000000000000000000..7fdd200afe0af064a734e699040c46dc798870cf GIT binary patch literal 273 zcmV+s0q*{ZP)Px#%Sl8*R7gwhl1mE0KoCT$5JYgV_`QfLukB_0iylD)pC~G$m~=E|A(-W4cyGF@ zt%^Ta%-3HKCj2`Q0aHn1+p~16uS@{UB@NGD+Yijr0$?F&@Ctr83tP&$04yc-v*4u! zz)Dgt5B^dBj3iBLH?tlOtR;0Lc$R=GcyGJ$ECDu>Iz`}_5dk;J!FK&70k)FbMd7&} zB$A`;8nBbpdIuhsoJj6TJ@0w6h2ff}l6T?Z1WERM0xv9xV#xa+MpOp=pP*2Bm3MFg X0uMwPm~M_^00000NkvXXu0mjfU<7Je literal 0 HcmV?d00001 diff --git a/Assets/Editor/Editor Windows/Icons/check.png.meta b/Assets/Editor/Editor Windows/Icons/check.png.meta new file mode 100644 index 0000000..f98b568 --- /dev/null +++ b/Assets/Editor/Editor Windows/Icons/check.png.meta @@ -0,0 +1,127 @@ +fileFormatVersion: 2 +guid: 0b1630592316867468f0cd45b7397c03 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 1 + wrapV: 1 + wrapW: 0 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 8 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: 5e97eb03825dee720800000000000000 + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Editor/Editor Windows/ScriptableObjectEditorWindow.cs b/Assets/Editor/Editor Windows/ScriptableObjectEditorWindow.cs index 9dee34b..d09f15e 100644 --- a/Assets/Editor/Editor Windows/ScriptableObjectEditorWindow.cs +++ b/Assets/Editor/Editor Windows/ScriptableObjectEditorWindow.cs @@ -43,6 +43,11 @@ public static string[] BasicFilters private List selectedTypes = new(); // Tracks which ScriptableObject types are currently selected for display private List availableTypes = new(); // Holds all unique ScriptableObject types found in the project + // rename operation: + bool isRenaming = false; + ScriptableObject ObjectToRename = null; + string renameText = ""; + // textures: private Texture2D spaceIcon; private Texture2D orientationIcon; @@ -50,19 +55,21 @@ public static string[] BasicFilters private Texture2D addConfigIcon; private Texture2D refreshIcon; private Texture2D filtersIcon; + private Texture2D checkIcon; // Buttons Styles: GUIContent spaceButton; GUIContent orientationButton; GUIContent refreshButton; GUIContent filtersButton; + GUIContent checkButton; // create config button styles: GUIContent AddConfigButton; GUILayoutOption[] AddConfigButtonOptions; GUIStyle buttonStyle; // delete config button styles: GUIContent ConfigOptionsButton; - GUILayoutOption[] ConfigOoptionsButtonOptions; + GUILayoutOption[] ConfigOptionsButtonOptions; // label styles: GUIStyle centeredLabelStyle; @@ -144,6 +151,15 @@ private void SetupButtonStyles() { filtersButton = new GUIContent("filters", "filters"); } + // GUI content for check button + if (checkIcon != null) + { + checkButton = new GUIContent(checkIcon, "check"); + } + else + { + checkButton = new GUIContent("ok", "check"); + } // 'create config' button styles if (addConfigIcon != null) @@ -157,16 +173,16 @@ private void SetupButtonStyles() AddConfigButtonOptions = new GUILayoutOption[] { GUILayout.Width(65) }; } - // 'delete config' button styles + // 'Config Options' button styles if (ConfigOptionsIcon != null) { - ConfigOptionsButton = new GUIContent(ConfigOptionsIcon, "delete config permanently"); - ConfigOoptionsButtonOptions = new GUILayoutOption[] { GUILayout.Height(20), GUILayout.Width(20) }; + ConfigOptionsButton = new GUIContent(ConfigOptionsIcon, "Options"); + ConfigOptionsButtonOptions = new GUILayoutOption[] { GUILayout.Height(20), GUILayout.Width(20) }; } else { - ConfigOptionsButton = new GUIContent("del", "delete config permanently"); - ConfigOoptionsButtonOptions = new GUILayoutOption[] { GUILayout.Width(30) }; + ConfigOptionsButton = new GUIContent("opt", "Options"); + ConfigOptionsButtonOptions = new GUILayoutOption[] { GUILayout.Width(30) }; } } @@ -334,6 +350,7 @@ private void LoadIcons() addConfigIcon = AssetDatabase.LoadAssetAtPath("Assets/Editor/Editor Windows/Icons/add file.png"); refreshIcon = AssetDatabase.LoadAssetAtPath("Assets/Editor/Editor Windows/Icons/refresh.png"); filtersIcon = AssetDatabase.LoadAssetAtPath("Assets/Editor/Editor Windows/Icons/filter.png"); + checkIcon = AssetDatabase.LoadAssetAtPath("Assets/Editor/Editor Windows/Icons/check.png"); if (spaceIcon == null) { @@ -359,6 +376,10 @@ private void LoadIcons() { Debug.LogError("filters Icon not found in: Assets/Editor/Editor Windows/Icons/filter.png"); } + if (checkIcon == null) + { + Debug.LogError("check Icon not found in: Assets/Editor/Editor Windows/Icons/check.png"); + } } private void LoadAvailableTypes() @@ -504,7 +525,7 @@ private void OptionsButton(T Config) where T : ScriptableObject buttonStyle.imagePosition = ImagePosition.ImageOnly; } - if (GUILayout.Button(ConfigOptionsButton, buttonStyle, ConfigOoptionsButtonOptions)) + if (GUILayout.Button(ConfigOptionsButton, buttonStyle, ConfigOptionsButtonOptions)) { ShowOptionsMenu(Config); } @@ -515,7 +536,7 @@ private void ShowOptionsMenu(T Config) where T : ScriptableObject GenericMenu menu = new GenericMenu(); menu.AddItem(new GUIContent("Delete Config"), false, () => DeleteConfig(Config)); - + menu.AddItem(new GUIContent("Rename Config"), false, () => { isRenaming = true; ObjectToRename = Config; renameText = ""; }); menu.AddSeparator(""); menu.AddItem(new GUIContent("Show In Project Folder"), false, () => ShowInProjectFolders(Config)); menu.ShowAsContext(); @@ -575,8 +596,60 @@ private void PutPropertiesForObject_H(List Configs) where T : ScriptableOb // Display the file name for the asset GUIContent propertyContent = new GUIContent(fileName, fileName); - EditorGUILayout.LabelField(propertyContent, EditorStyles.miniBoldLabel, GUILayout.Width(120)); + + + Rect elementRect = GUILayoutUtility.GetRect(120, 120, 18, 18, GUILayout.Width(120)); + + if (isRenaming && ObjectToRename != null && ObjectToRename == Config) + { + GUI.SetNextControlName("RenameField"); + + // Display a text field for renaming the asset.if renameText is empty, show the file name until the user types something + renameText = EditorGUI.TextField(elementRect, renameText == "" ? fileName : renameText); + + Event e = Event.current; + + if (isRenaming && e.type == EventType.MouseDown && !elementRect.Contains(e.mousePosition)) + { + isRenaming = false; + GUI.FocusControl(null); + e.Use(); // Olayı tüketiyoruz + } + if (GUILayout.Button(checkButton, buttonStyle, ConfigOptionsButtonOptions)) + { + AssetDatabase.RenameAsset(filePath, renameText); + AssetDatabase.SaveAssets(); + isRenaming = false; + renameText = ""; + ObjectToRename = null; + GUI.FocusControl(null); + } + + if (Event.current.keyCode == KeyCode.Return || Event.current.keyCode == KeyCode.KeypadEnter) + { + AssetDatabase.RenameAsset(filePath, renameText); + AssetDatabase.SaveAssets(); + isRenaming = false; + renameText = ""; + ObjectToRename = null; + GUI.FocusControl(null); + } + else if (Event.current.keyCode == KeyCode.Escape) + { + renameText = ""; + isRenaming = false; + ObjectToRename = null; + GUI.FocusControl(null); + } + + EditorGUI.FocusTextInControl("RenameField"); + } + else + { + EditorGUI.LabelField(elementRect, propertyContent, EditorStyles.miniBoldLabel); + } + // Display a delete button for the asset OptionsButton(Config); GUILayout.Space(3); @@ -653,5 +726,13 @@ public static float CalculatePropertyHeight(List configs, SerializedProper return maxHeight; } + void OnLostFocus() + { + isRenaming = false; + ObjectToRename = null; + renameText = ""; + GUI.FocusControl(null); + } + } } \ No newline at end of file diff --git a/Assets/Resources/ScriptableObjects/TestConfig 2.asset b/Assets/Resources/ScriptableObjects/TestConfig3.asset similarity index 96% rename from Assets/Resources/ScriptableObjects/TestConfig 2.asset rename to Assets/Resources/ScriptableObjects/TestConfig3.asset index 1648680..846b516 100644 --- a/Assets/Resources/ScriptableObjects/TestConfig 2.asset +++ b/Assets/Resources/ScriptableObjects/TestConfig3.asset @@ -10,7 +10,7 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: b23340d9b453ca740945f54769125bb1, type: 3} - m_Name: TestConfig 2 + m_Name: TestConfig3 m_EditorClassIdentifier: number: 22 value: 0 diff --git a/Assets/Resources/ScriptableObjects/TestConfig 2.asset.meta b/Assets/Resources/ScriptableObjects/TestConfig3.asset.meta similarity index 100% rename from Assets/Resources/ScriptableObjects/TestConfig 2.asset.meta rename to Assets/Resources/ScriptableObjects/TestConfig3.asset.meta From 7d4a9c139a10e9a7ffba2840da40a9344195ebd6 Mon Sep 17 00:00:00 2001 From: yunus bozkurtaca Date: Fri, 23 May 2025 19:02:04 +0300 Subject: [PATCH 6/8] rename option visual update --- .../ScriptableObjectEditorWindow.cs | 36 ++++++++++--------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/Assets/Editor/Editor Windows/ScriptableObjectEditorWindow.cs b/Assets/Editor/Editor Windows/ScriptableObjectEditorWindow.cs index d09f15e..bf4e25d 100644 --- a/Assets/Editor/Editor Windows/ScriptableObjectEditorWindow.cs +++ b/Assets/Editor/Editor Windows/ScriptableObjectEditorWindow.cs @@ -45,6 +45,7 @@ public static string[] BasicFilters // rename operation: bool isRenaming = false; + bool FinishRenaming = false; ScriptableObject ObjectToRename = null; string renameText = ""; @@ -524,11 +525,21 @@ private void OptionsButton(T Config) where T : ScriptableObject buttonStyle.padding = new RectOffset(2, 2, 2, 2); buttonStyle.imagePosition = ImagePosition.ImageOnly; } - - if (GUILayout.Button(ConfigOptionsButton, buttonStyle, ConfigOptionsButtonOptions)) + if (isRenaming && ObjectToRename != null && ObjectToRename == Config) { - ShowOptionsMenu(Config); + if (GUILayout.Button(checkIcon, buttonStyle, ConfigOptionsButtonOptions)) + { + FinishRenaming = true; + } } + else + { + if (GUILayout.Button(ConfigOptionsButton, buttonStyle, ConfigOptionsButtonOptions)) + { + ShowOptionsMenu(Config); + } + } + } private void ShowOptionsMenu(T Config) where T : ScriptableObject @@ -598,7 +609,7 @@ private void PutPropertiesForObject_H(List Configs) where T : ScriptableOb GUIContent propertyContent = new GUIContent(fileName, fileName); - Rect elementRect = GUILayoutUtility.GetRect(120, 120, 18, 18, GUILayout.Width(120)); + Rect elementRect = GUILayoutUtility.GetRect(120, 18, GUILayout.Width(120)); if (isRenaming && ObjectToRename != null && ObjectToRename == Config) { @@ -609,28 +620,21 @@ private void PutPropertiesForObject_H(List Configs) where T : ScriptableOb Event e = Event.current; + // textfield + confirm button (for mouse event it must also contain the button area) + elementRect.width = 145; if (isRenaming && e.type == EventType.MouseDown && !elementRect.Contains(e.mousePosition)) { isRenaming = false; GUI.FocusControl(null); - e.Use(); // Olayı tüketiyoruz - } - - if (GUILayout.Button(checkButton, buttonStyle, ConfigOptionsButtonOptions)) - { - AssetDatabase.RenameAsset(filePath, renameText); - AssetDatabase.SaveAssets(); - isRenaming = false; - renameText = ""; - ObjectToRename = null; - GUI.FocusControl(null); + e.Use(); } - if (Event.current.keyCode == KeyCode.Return || Event.current.keyCode == KeyCode.KeypadEnter) + if (FinishRenaming || Event.current.keyCode == KeyCode.Return || Event.current.keyCode == KeyCode.KeypadEnter) { AssetDatabase.RenameAsset(filePath, renameText); AssetDatabase.SaveAssets(); isRenaming = false; + FinishRenaming = false; renameText = ""; ObjectToRename = null; GUI.FocusControl(null); From 5db49e4ff319cf088b20aa383d2c84c69de2af78 Mon Sep 17 00:00:00 2001 From: yunus bozkurtaca Date: Fri, 23 May 2025 19:05:12 +0300 Subject: [PATCH 7/8] vertical table mode rename option added --- .../ScriptableObjectEditorWindow.cs | 47 ++++++++++++++++++- .../{TestConfig.asset => TestConfig2.asset} | 2 +- ...nfig.asset.meta => TestConfig2.asset.meta} | 0 3 files changed, 47 insertions(+), 2 deletions(-) rename Assets/Resources/ScriptableObjects/{TestConfig.asset => TestConfig2.asset} (96%) rename Assets/Resources/ScriptableObjects/{TestConfig.asset.meta => TestConfig2.asset.meta} (100%) diff --git a/Assets/Editor/Editor Windows/ScriptableObjectEditorWindow.cs b/Assets/Editor/Editor Windows/ScriptableObjectEditorWindow.cs index bf4e25d..032e708 100644 --- a/Assets/Editor/Editor Windows/ScriptableObjectEditorWindow.cs +++ b/Assets/Editor/Editor Windows/ScriptableObjectEditorWindow.cs @@ -470,7 +470,52 @@ private void PutPropertiesForObject_V(List Configs) where T : ScriptableOb // Display the file name and a delete button for the asset EditorGUILayout.BeginHorizontal(); GUIContent propertyContent = new GUIContent(fileName, fileName); - EditorGUILayout.LabelField(propertyContent, EditorStyles.miniBoldLabel, GUILayout.MinWidth(PropertyMinWidth)); + + Rect elementRect = GUILayoutUtility.GetRect(120, 18); + + if (isRenaming && ObjectToRename != null && ObjectToRename == Config) + { + GUI.SetNextControlName("RenameField"); + + // Display a text field for renaming the asset.if renameText is empty, show the file name until the user types something + renameText = EditorGUI.TextField(elementRect, renameText == "" ? fileName : renameText); + + Event e = Event.current; + + // textfield + confirm button (for mouse event it must also contain the button area) + elementRect.width += 25; + if (isRenaming && e.type == EventType.MouseDown && !elementRect.Contains(e.mousePosition)) + { + isRenaming = false; + GUI.FocusControl(null); + e.Use(); + } + + if (FinishRenaming || Event.current.keyCode == KeyCode.Return || Event.current.keyCode == KeyCode.KeypadEnter) + { + AssetDatabase.RenameAsset(filePath, renameText); + AssetDatabase.SaveAssets(); + isRenaming = false; + FinishRenaming = false; + renameText = ""; + ObjectToRename = null; + GUI.FocusControl(null); + } + else if (Event.current.keyCode == KeyCode.Escape) + { + renameText = ""; + isRenaming = false; + ObjectToRename = null; + GUI.FocusControl(null); + } + + EditorGUI.FocusTextInControl("RenameField"); + } + else + { + EditorGUI.LabelField(elementRect, propertyContent, EditorStyles.miniBoldLabel); + } + OptionsButton(Config); EditorGUILayout.EndHorizontal(); diff --git a/Assets/Resources/ScriptableObjects/TestConfig.asset b/Assets/Resources/ScriptableObjects/TestConfig2.asset similarity index 96% rename from Assets/Resources/ScriptableObjects/TestConfig.asset rename to Assets/Resources/ScriptableObjects/TestConfig2.asset index 086f1d1..91eef47 100644 --- a/Assets/Resources/ScriptableObjects/TestConfig.asset +++ b/Assets/Resources/ScriptableObjects/TestConfig2.asset @@ -10,7 +10,7 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: b23340d9b453ca740945f54769125bb1, type: 3} - m_Name: TestConfig + m_Name: TestConfig2 m_EditorClassIdentifier: number: -13 value: 0 diff --git a/Assets/Resources/ScriptableObjects/TestConfig.asset.meta b/Assets/Resources/ScriptableObjects/TestConfig2.asset.meta similarity index 100% rename from Assets/Resources/ScriptableObjects/TestConfig.asset.meta rename to Assets/Resources/ScriptableObjects/TestConfig2.asset.meta From 8e7927a83e352c9af960ea3b53afdd063f14a3d0 Mon Sep 17 00:00:00 2001 From: yunus bozkurtaca Date: Fri, 23 May 2025 19:08:10 +0300 Subject: [PATCH 8/8] options button minor visual update --- Assets/Editor/Editor Windows/ScriptableObjectEditorWindow.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Assets/Editor/Editor Windows/ScriptableObjectEditorWindow.cs b/Assets/Editor/Editor Windows/ScriptableObjectEditorWindow.cs index 032e708..4ad3513 100644 --- a/Assets/Editor/Editor Windows/ScriptableObjectEditorWindow.cs +++ b/Assets/Editor/Editor Windows/ScriptableObjectEditorWindow.cs @@ -568,8 +568,10 @@ private void OptionsButton(T Config) where T : ScriptableObject if (ConfigOptionsIcon != null) { buttonStyle.padding = new RectOffset(2, 2, 2, 2); + buttonStyle.margin = new RectOffset(0, 0, 0, 0); buttonStyle.imagePosition = ImagePosition.ImageOnly; } + if (isRenaming && ObjectToRename != null && ObjectToRename == Config) { if (GUILayout.Button(checkIcon, buttonStyle, ConfigOptionsButtonOptions)) @@ -584,7 +586,6 @@ private void OptionsButton(T Config) where T : ScriptableObject ShowOptionsMenu(Config); } } - } private void ShowOptionsMenu(T Config) where T : ScriptableObject