diff --git a/Assets/ZFolderIcons.meta b/Assets/ZFolderIcons.meta new file mode 100644 index 0000000..833191c --- /dev/null +++ b/Assets/ZFolderIcons.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: e439084cec60bc94dafe5b98c4da7dcc +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ZFolderIcons/CozetteVector.ttf b/Assets/ZFolderIcons/CozetteVector.ttf new file mode 100644 index 0000000..05ba976 Binary files /dev/null and b/Assets/ZFolderIcons/CozetteVector.ttf differ diff --git a/Assets/ZFolderIcons/CozetteVector.ttf.meta b/Assets/ZFolderIcons/CozetteVector.ttf.meta new file mode 100644 index 0000000..1779cde --- /dev/null +++ b/Assets/ZFolderIcons/CozetteVector.ttf.meta @@ -0,0 +1,21 @@ +fileFormatVersion: 2 +guid: 78d74b9d68578864f928989b03e03bbb +TrueTypeFontImporter: + externalObjects: {} + serializedVersion: 4 + fontSize: 16 + forceTextureCase: -2 + characterSpacing: 0 + characterPadding: 1 + includeFontData: 1 + fontNames: + - CozetteVector + fallbackFontReferences: [] + customCharacters: + fontRenderingMode: 0 + ascentCalculationMode: 1 + useLegacyBoundsCalculation: 0 + shouldRoundAdvanceValue: 1 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ZFolderIcons/ExtraIcons.meta b/Assets/ZFolderIcons/ExtraIcons.meta new file mode 100644 index 0000000..72e081d --- /dev/null +++ b/Assets/ZFolderIcons/ExtraIcons.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: b6d096bc62a8f1e498a98e3722766b77 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ZFolderIcons/ExtraIcons/ScriptHashtag.png b/Assets/ZFolderIcons/ExtraIcons/ScriptHashtag.png new file mode 100644 index 0000000..b7d638d Binary files /dev/null and b/Assets/ZFolderIcons/ExtraIcons/ScriptHashtag.png differ diff --git a/Assets/ZFolderIcons/ExtraIcons/ScriptHashtag.png.meta b/Assets/ZFolderIcons/ExtraIcons/ScriptHashtag.png.meta new file mode 100644 index 0000000..1e0c26b --- /dev/null +++ b/Assets/ZFolderIcons/ExtraIcons/ScriptHashtag.png.meta @@ -0,0 +1,127 @@ +fileFormatVersion: 2 +guid: b6d1ddbaa0d99de45909cb04c0f0e5f4 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 12 + 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: 1 + 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: Server + 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/ZFolderIcons/Project.Plugins.ZFolderIcons.asmdef b/Assets/ZFolderIcons/Project.Plugins.ZFolderIcons.asmdef new file mode 100644 index 0000000..627c753 --- /dev/null +++ b/Assets/ZFolderIcons/Project.Plugins.ZFolderIcons.asmdef @@ -0,0 +1,3 @@ +{ + "name": "Project.Plugins.ZFolderIcons" +} diff --git a/Assets/ZFolderIcons/Project.Plugins.ZFolderIcons.asmdef.meta b/Assets/ZFolderIcons/Project.Plugins.ZFolderIcons.asmdef.meta new file mode 100644 index 0000000..3faa0eb --- /dev/null +++ b/Assets/ZFolderIcons/Project.Plugins.ZFolderIcons.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 9d8ac3893a2ccdf40aaf2fe4f42a5b14 +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ZFolderIcons/ZFolderIcons.cs b/Assets/ZFolderIcons/ZFolderIcons.cs new file mode 100644 index 0000000..d4f91f3 --- /dev/null +++ b/Assets/ZFolderIcons/ZFolderIcons.cs @@ -0,0 +1,346 @@ +#if UNITY_EDITOR && UNITY_2021_3_OR_NEWER +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Text.RegularExpressions; +using UnityEditor; +using UnityEngine; +using UnityEngine.Windows; + +[InitializeOnLoad] +public class ZFolderIcons : EditorWindow +{ + private static GUIStyle DirectoryLabelStyle; + private static GUIStyle MonoScriptLabelStyle; + private const float maxHeight = 18f; + + private static Texture2D scriptIconTexture; + + private static Dictionary PreDefinedFolderLabels = new Dictionary + { + { + new Regex(@"^Script(s)?$", RegexOptions.IgnoreCase), + "C#" + }, + { + new Regex(@"^Plugin(s)?$", RegexOptions.IgnoreCase), + "Plug" + }, + { + new Regex(@"^Resource(s)?$", RegexOptions.IgnoreCase), + "Res" + }, + { + new Regex(@"^Editor$", RegexOptions.IgnoreCase), + "Edit" + }, + { + new Regex(@"^Prefab(s)?$", RegexOptions.IgnoreCase), + "PF" + }, + { + new Regex(@"^Tile(s)?Palette(s)?$", RegexOptions.IgnoreCase), + "Tile" + }, + }; + + static ZFolderIcons() + { + EditorApplication.projectWindowItemOnGUI += OnProjectWindowItemGUI; + } + + private static void OnProjectWindowItemGUI(string guid, Rect selectionRect) + { + if (selectionRect.height < maxHeight) + return; + + // Get the asset path based on the GUID + string assetPath = AssetDatabase.GUIDToAssetPath(guid); + + // Check if the asset is a folder and not in the base project folder + // Use "&& assetPath.Count(c => c == '/') >= 2" to ignore base assets folder + + // TODO: Impliment AssetDatabase.GetMainAssetTypeFromGUID(new GUID(guid)).IsSubclassOf(typeof(ScriptableObject)) + + Type objectType = null; + if (AssetDatabase.IsValidFolder(assetPath)) + { + DoFolderIcons(assetPath, selectionRect); + } + else + { + objectType = AssetDatabase.GetMainAssetTypeFromGUID(new GUID(guid)); + } + + if (objectType == null) return; + if (objectType == typeof(MonoScript)) // Is script object + { + DoMonoScriptIcon(assetPath, selectionRect); + } + } + + static void DoFolderIcons(string folderPath, Rect selectionRect) + { + // Calculate the position for the custom label + Rect labelRect = new Rect(selectionRect.x + selectionRect.width * 0.15f, selectionRect.y + selectionRect.width * 0.4f, selectionRect.width, selectionRect.height); + + string folderName = Path.GetFileName(folderPath); + + // Create GUIStyle if it hasn't been created yet + if (DirectoryLabelStyle == null) + { + DirectoryLabelStyle = new GUIStyle(EditorStyles.miniLabel); + DirectoryLabelStyle.alignment = TextAnchor.UpperLeft; // Adjust the font size as desired + DirectoryLabelStyle.normal.textColor = Color.black; // Set the text color + + TryAssignFont(ref DirectoryLabelStyle); + } + DirectoryLabelStyle.fontSize = (int)(selectionRect.width * 0.35f); // Adjust the font size as desired + + string labelText; + if (TryGetPreDefinedLabel(folderName, out string label)) + { + labelText = label; + } + else if (folderName.Count(char.IsUpper) >= 2) + { + labelText = new string(folderName.Where(x => char.IsUpper(x)).Take(4).ToArray()); + } + else + { + labelText = new(folderName.Take(4).ToArray()); + } + + // Draw the custom label with black color + var previousColor = GUI.color; + GUI.color = Color.black; + EditorGUI.LabelField(labelRect, labelText, DirectoryLabelStyle); + GUI.color = previousColor; + + DrawFolderColorStrip(folderName, selectionRect); + } + + static void DrawFolderColorStrip(string seedString, Rect selectionRect) + { + Color stripColor = GetRandomColor(seedString); + + // Calculate the position for the strip + Rect stripRect = new Rect( + x: selectionRect.x + selectionRect.width * 0.175f, + y: selectionRect.y + selectionRect.width * 0.725f, + width: selectionRect.width * 0.64f, + height: selectionRect.height * 0.05f); + + // Draw the custom label with black color + var previousColor = GUI.color; + EditorGUI.DrawRect(stripRect, stripColor); + GUI.color = previousColor; + } + + static void DoMonoScriptIcon(string scriptPath, Rect selectionRect) + { + // Calculate the position for the white overlay + Rect overwriteOverlayRect = new Rect(selectionRect.x + selectionRect.width * 0.25f, selectionRect.y + selectionRect.width * 0.20f, selectionRect.width*0.5f, selectionRect.height*0.5f); + var previousColor = GUI.color; + + if (!Application.isPlaying) + { + // Draw the custom rect with white color + previousColor = GUI.color; + float shadeOfWhite = 247; + GUI.color = new Color(shadeOfWhite / 255f, shadeOfWhite / 255f, shadeOfWhite / 255f); + EditorGUI.DrawRect(overwriteOverlayRect, GUI.color); + GUI.color = previousColor; + } + else + { + //Did not work + + + //// Gets playmode tint color + //string prefPlaymodeTint = EditorPrefs.GetString("Playmode tint", "").Replace("Playmode tint;", ""); + //string[] rgba = prefPlaymodeTint.Split(";"); + //Color color = new Color(float.Parse(rgba[0]), float.Parse(rgba[1]), float.Parse(rgba[2]), float.Parse(rgba[3])); + + //// Draw the custom rect with play color tint + //previousColor = GUI.color; + //GUI.color = color; + //EditorGUI.DrawRect(overwriteOverlayRect, GUI.color); + //GUI.color = previousColor; + + // Draw the custom rect with white color + previousColor = GUI.color; + float shadeOfWhite = 247; + GUI.color = new Color(shadeOfWhite / 255f, shadeOfWhite / 255f, shadeOfWhite / 255f); + EditorGUI.DrawRect(overwriteOverlayRect, GUI.color); + GUI.color = previousColor; + } + + + string scriptName = Path.GetFileName(scriptPath); + + const int maxLength = 8; + string labelText; + { + // Use LINQ to iterate through each character and insert a line break before uppercase letters + labelText = new string(scriptName.SelectMany(c => char.IsUpper(c) ? new char[] { '\n', c } : new[] { c }).ToArray()); + labelText = labelText.TrimStart('\n').Replace(".cs", ""); + labelText = string.Join('\n', MergeLooseCapitalStrings(labelText.Split('\n'))); + labelText = string.Join('\n', labelText.Split('\n').Select(x => x.Length > 6 ? new string(x.Take(maxLength).ToArray()) + "…" : x)); + } + + // Calculate the position for the custom label + Rect labelRect = new Rect(selectionRect.x + selectionRect.width * 0.15f, selectionRect.y + selectionRect.width * 0.1f, selectionRect.width, selectionRect.height); + + // Create GUIStyle if it hasn't been created yet + if (MonoScriptLabelStyle == null) + { + MonoScriptLabelStyle = new GUIStyle(EditorStyles.miniLabel); + MonoScriptLabelStyle.alignment = TextAnchor.UpperLeft; // Adjust the font size as desired + MonoScriptLabelStyle.normal.textColor = Color.black; // Set the text color + + TryAssignFont(ref MonoScriptLabelStyle); + } + MonoScriptLabelStyle.fontSize = (int)(selectionRect.width * 0.2f); // Adjust the font size as desired + + // Draw the custom label with black color + previousColor = GUI.color; + GUI.color = Color.black; + EditorGUI.LabelField(labelRect, labelText, MonoScriptLabelStyle); + GUI.color = previousColor; + + // Custom icon rect + Rect customIconRect = new Rect(selectionRect.x + selectionRect.width * 0.62f, selectionRect.y + selectionRect.width * 0.645f, selectionRect.width * 0.25f, selectionRect.height * 0.25f); + + // Load texture if null + if (scriptIconTexture == null) + { + if (TryGetScriptIcon(out Texture2D icon)) + { + scriptIconTexture = icon; + } + else + { + return; // Couldn't get icon, so don't draw it + } + } + + // Draw the custom icon + GUI.DrawTexture(customIconRect, scriptIconTexture); + } + + public static bool TryGetPreDefinedLabel(string folderName, out string label) + { + foreach (var regex in PreDefinedFolderLabels.Keys) + { + if (regex.IsMatch(folderName)) + { + label = PreDefinedFolderLabels[regex]; + return true; + } + } + + label = "Error"; + return false; + } + + static bool TryGetScriptIcon(out Texture2D icon) + { + if (FindFolder("ExtraIcons", out string path)) + { + icon = AssetDatabase.LoadAssetAtPath(path + "/ScriptHashtag.png"); + return true; + } + else + { + icon = null; + return false; + } + } + + static bool FindFolder(string folderName, out string path) + { + string[] guids = AssetDatabase.FindAssets("t:Folder " + folderName); + + if (guids.Length > 0) + { + path = AssetDatabase.GUIDToAssetPath(guids[0]); + return true; + } + else + { + path = null; + return false; + } + } + + static string[] MergeLooseCapitalStrings(string[] arr) + { + List result = new List(); + string currentString = ""; + + foreach (string s in arr) + { + if (IsUpperCase(s)) + { + currentString += s; + } + else if (!string.IsNullOrEmpty(currentString)) + { + result.Add(currentString + s); + currentString = ""; + } + else + { + result.Add(s); + } + } + + if (!string.IsNullOrEmpty(currentString)) + { + result.Add(currentString); + } + + return result.ToArray(); + } + + static Func IsUpperCase = s => !string.IsNullOrEmpty(s) && s.All(char.IsUpper); + + /// + /// Generates a semi random color out of a seed + /// + /// Used to generate the color + /// A semi random color + public static Color GetRandomColor(string seed) + { + int intSeed = seed.Select(c=>(int)c).Sum(); + + System.Random random = new System.Random(intSeed); + + // Generate random values for R, G, and B components between 0 and 1. + float r = (float)random.NextDouble(); + float g = (float)random.NextDouble(); + float b = (float)random.NextDouble(); + + // Create and return the color. + return new Color(r, g, b); + } + + private static void TryAssignFont(ref GUIStyle guiFont) + { + string[] guids = AssetDatabase.FindAssets("t:Font CozetteVector", new[] { "Assets/Plugins/ZFolderIcons" }); + + + if (guids.Length <= 0) + { + return; // Couldn't find font asset + } + + string path = AssetDatabase.GUIDToAssetPath(guids[0]); + guiFont.font = AssetDatabase.LoadAssetAtPath(path); + } +} +#endif diff --git a/Assets/ZFolderIcons/ZFolderIcons.cs.meta b/Assets/ZFolderIcons/ZFolderIcons.cs.meta new file mode 100644 index 0000000..bbd2f9c --- /dev/null +++ b/Assets/ZFolderIcons/ZFolderIcons.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 492e529bdc9cf034989956b1d941225e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: