From b637e1723d0890b7ead4092fe8aeb8e052bc604f Mon Sep 17 00:00:00 2001 From: BobSong <605277374@qq.com> Date: Sat, 30 Aug 2025 21:06:37 +0800 Subject: [PATCH] =?UTF-8?q?=E7=A7=BB=E9=99=A4=E6=8A=A5=E9=94=99=E7=9A=84VF?= =?UTF-8?q?olders?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Assets/Plugins/vFolders/Read me.pdf | Bin 47718 -> 0 bytes Assets/Plugins/vFolders/Read me.pdf.meta | 7 - Assets/Plugins/vFolders/VFolders.asmdef | 16 - Assets/Plugins/vFolders/VFolders.asmdef.meta | 7 - Assets/Plugins/vFolders/VFolders.cs | 1613 ---------- Assets/Plugins/vFolders/VFolders.cs.meta | 11 - Assets/Plugins/vFolders/VFoldersCache.cs | 102 - Assets/Plugins/vFolders/VFoldersCache.cs.meta | 11 - Assets/Plugins/vFolders/VFoldersController.cs | 521 ---- .../vFolders/VFoldersController.cs.meta | 11 - Assets/Plugins/vFolders/VFoldersData.cs | 145 - Assets/Plugins/vFolders/VFoldersData.cs.meta | 11 - Assets/Plugins/vFolders/VFoldersGUI.cs | 1278 -------- Assets/Plugins/vFolders/VFoldersGUI.cs.meta | 11 - Assets/Plugins/vFolders/VFoldersHistory.cs | 403 --- .../Plugins/vFolders/VFoldersHistory.cs.meta | 11 - Assets/Plugins/vFolders/VFoldersIconEditor.cs | 5 - .../vFolders/VFoldersIconEditor.cs.meta | 11 - Assets/Plugins/vFolders/VFoldersLibs.cs | 2667 ----------------- Assets/Plugins/vFolders/VFoldersLibs.cs.meta | 11 - Assets/Plugins/vFolders/VFoldersMenu.cs | 128 - Assets/Plugins/vFolders/VFoldersMenu.cs.meta | 11 - Assets/Plugins/vFolders/VFoldersMenuItems.cs | 5 - .../vFolders/VFoldersMenuItems.cs.meta | 11 - Assets/Plugins/vFolders/VFoldersNavbar.cs | 1395 --------- .../Plugins/vFolders/VFoldersNavbar.cs.meta | 11 - Assets/Plugins/vFolders/VFoldersPalette.cs | 268 -- .../Plugins/vFolders/VFoldersPalette.cs.meta | 11 - .../Plugins/vFolders/VFoldersPaletteEditor.cs | 1375 --------- .../vFolders/VFoldersPaletteEditor.cs.meta | 11 - .../Plugins/vFolders/VFoldersPaletteWindow.cs | 783 ----- .../vFolders/VFoldersPaletteWindow.cs.meta | 11 - 32 files changed, 10872 deletions(-) delete mode 100644 Assets/Plugins/vFolders/Read me.pdf delete mode 100644 Assets/Plugins/vFolders/Read me.pdf.meta delete mode 100644 Assets/Plugins/vFolders/VFolders.asmdef delete mode 100644 Assets/Plugins/vFolders/VFolders.asmdef.meta delete mode 100644 Assets/Plugins/vFolders/VFolders.cs delete mode 100644 Assets/Plugins/vFolders/VFolders.cs.meta delete mode 100644 Assets/Plugins/vFolders/VFoldersCache.cs delete mode 100644 Assets/Plugins/vFolders/VFoldersCache.cs.meta delete mode 100644 Assets/Plugins/vFolders/VFoldersController.cs delete mode 100644 Assets/Plugins/vFolders/VFoldersController.cs.meta delete mode 100644 Assets/Plugins/vFolders/VFoldersData.cs delete mode 100644 Assets/Plugins/vFolders/VFoldersData.cs.meta delete mode 100644 Assets/Plugins/vFolders/VFoldersGUI.cs delete mode 100644 Assets/Plugins/vFolders/VFoldersGUI.cs.meta delete mode 100644 Assets/Plugins/vFolders/VFoldersHistory.cs delete mode 100644 Assets/Plugins/vFolders/VFoldersHistory.cs.meta delete mode 100644 Assets/Plugins/vFolders/VFoldersIconEditor.cs delete mode 100644 Assets/Plugins/vFolders/VFoldersIconEditor.cs.meta delete mode 100644 Assets/Plugins/vFolders/VFoldersLibs.cs delete mode 100644 Assets/Plugins/vFolders/VFoldersLibs.cs.meta delete mode 100644 Assets/Plugins/vFolders/VFoldersMenu.cs delete mode 100644 Assets/Plugins/vFolders/VFoldersMenu.cs.meta delete mode 100644 Assets/Plugins/vFolders/VFoldersMenuItems.cs delete mode 100644 Assets/Plugins/vFolders/VFoldersMenuItems.cs.meta delete mode 100644 Assets/Plugins/vFolders/VFoldersNavbar.cs delete mode 100644 Assets/Plugins/vFolders/VFoldersNavbar.cs.meta delete mode 100644 Assets/Plugins/vFolders/VFoldersPalette.cs delete mode 100644 Assets/Plugins/vFolders/VFoldersPalette.cs.meta delete mode 100644 Assets/Plugins/vFolders/VFoldersPaletteEditor.cs delete mode 100644 Assets/Plugins/vFolders/VFoldersPaletteEditor.cs.meta delete mode 100644 Assets/Plugins/vFolders/VFoldersPaletteWindow.cs delete mode 100644 Assets/Plugins/vFolders/VFoldersPaletteWindow.cs.meta diff --git a/Assets/Plugins/vFolders/Read me.pdf b/Assets/Plugins/vFolders/Read me.pdf deleted file mode 100644 index 48106d2d31242422bbb651291085e275178589e0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 47718 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
gu+jAqv=X|_N?Sf((K&z(HYOh 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 O449COP5QnJ;r{}7lgwWL diff --git a/Assets/Plugins/vFolders/Read me.pdf.meta b/Assets/Plugins/vFolders/Read me.pdf.meta deleted file mode 100644 index 90fb2598b..000000000 --- a/Assets/Plugins/vFolders/Read me.pdf.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 6c1da0cc833e64f4c96ba170387ea7a6 -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Plugins/vFolders/VFolders.asmdef b/Assets/Plugins/vFolders/VFolders.asmdef deleted file mode 100644 index d3d34ab31..000000000 --- a/Assets/Plugins/vFolders/VFolders.asmdef +++ /dev/null @@ -1,16 +0,0 @@ -{ - "name": "VFolders", - "rootNamespace": "", - "references": [], - "includePlatforms": [ - "Editor" - ], - "excludePlatforms": [], - "allowUnsafeCode": false, - "overrideReferences": false, - "precompiledReferences": [], - "autoReferenced": true, - "defineConstraints": [], - "versionDefines": [], - "noEngineReferences": false -} \ No newline at end of file diff --git a/Assets/Plugins/vFolders/VFolders.asmdef.meta b/Assets/Plugins/vFolders/VFolders.asmdef.meta deleted file mode 100644 index a4528fa07..000000000 --- a/Assets/Plugins/vFolders/VFolders.asmdef.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 3331bc437f3a24586b7e86e7bdd62b5e -AssemblyDefinitionImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Plugins/vFolders/VFolders.cs b/Assets/Plugins/vFolders/VFolders.cs deleted file mode 100644 index 4510e12d0..000000000 --- a/Assets/Plugins/vFolders/VFolders.cs +++ /dev/null @@ -1,1613 +0,0 @@ -#if UNITY_EDITOR -using System.Collections; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Reflection; -using UnityEngine; -using UnityEditor; -using UnityEditor.ShortcutManagement; -using UnityEngine.UIElements; -using UnityEngine.SceneManagement; -using UnityEditor.SceneManagement; -using UnityEditor.IMGUI.Controls; -using Type = System.Type; -using static VFolders.Libs.VUtils; -using static VFolders.Libs.VGUI; -// using static VTools.VDebug; -using static VFolders.VFoldersData; -using static VFolders.VFoldersCache; - - - -namespace VFolders -{ - public static class VFolders - { - - static void WrappedGUI(EditorWindow window) - { - var navbarHeight = 26; - - var isOneColumn = window.GetMemberValue("m_ViewMode") == 0; - - void navbarGui() - { - if (!navbars_byWindow.ContainsKey(window)) - navbars_byWindow[window] = new VFoldersNavbar(window); - - var navbarRect = window.position.SetPos(0, 0).SetHeight(navbarHeight); - - navbars_byWindow[window].OnGUI(navbarRect); - - - } - void hideDefaultTopBar() - { - if (curEvent.isLayout || typeof(GUILayoutUtility).GetMemberValue("current")?.GetMemberValue("topLevel")?.GetMemberValue("entries").Count != 1) // prevents exception on focus by vTabs shift-scroll // doesnt always work. tbh not sure why it works at all - Space(-123); - - } - void defaultGuiWithOffset() - { - var defaultTopBarHeight = 20; - var topOffset = navbarHeight - defaultTopBarHeight; - - var m_Pos_original = window.GetFieldValue("m_Pos"); - - - - - GUI.BeginGroup(m_Pos_original.SetPos(0, 0).AddHeightFromBottom(-topOffset)); - - window.SetFieldValue("m_Pos", m_Pos_original.AddHeightFromBottom(-topOffset)); - - - try { window.InvokeMethod("OnGUI"); } - catch (System.Exception exception) - { - if (exception.InnerException is ExitGUIException) - throw exception.InnerException; - else - throw exception; - - // GUIUtility.ExitGUI() works by throwing ExitGUIException, which just exits imgui loop and doesn't appear in console - // but if ExitGUI is called from a reflected method (OnGUI in this case), the exception becomes TargetInvokationException - // which gets logged to console (only if debugger is attached, for some reason) - // so here in such cases we rethrow the original ExitGUIException - - } - - - window.SetFieldValue("m_Pos", m_Pos_original); - - GUI.EndGroup(); - - } - void treeViewShadow() - { - if (!curEvent.isRepaint) return; - - var shadowLength = 30; - var shadowPos = 21; - var shadowGreyscale = isDarkTheme ? .1f : .28f; - var shadowAlpha = .35f; - - var minScrollPos = 10; - var maxScrollPos = 20; - - - var scrollPos = window.GetMemberValue(isOneColumn ? "m_AssetTree" : "m_FolderTree").GetMemberValue("state").scrollPos.y; - - var opacity = ((scrollPos - minScrollPos) / (maxScrollPos - minScrollPos)).Clamp01(); - - - var rectWidth = isOneColumn ? window.position.width : window.GetMemberValue("m_TreeViewRect").width;// - 12; - - var rect = window.position.SetPos(0, 0).MoveY(shadowPos).SetHeight(shadowLength).SetWidth(rectWidth); - - - - var clipAtY = navbarHeight + 1; - - GUI.BeginClip(window.position.SetPos(0, clipAtY)); - - rect.MoveY(-clipAtY).DrawCurtainDown(Greyscale(shadowGreyscale, shadowAlpha * opacity)); - - GUI.EndClip(); - - - - - if (isOneColumn) return; - - var dividerRect = window.GetMemberValue("m_TreeViewRect").SetWidthFromRight(1).MoveX(1); - - var dividerColor = Greyscale(.16f); - - dividerRect.Draw(dividerColor); - - - } - void listAreaShadow() - { - if (isOneColumn) return; - if (!curEvent.isRepaint) return; - - - var shadowLength = 30; - var shadowPos = navbarHeight + 17; - var shadowGreyscale = isDarkTheme ? .1f : .28f; - var shadowAlpha = .35f; - - var minScrollPos = 10; - var maxScrollPos = 20; - - - var scrollPos = window.GetMemberValue("m_ListAreaState").GetMemberValue("m_ScrollPosition").y; - - var opacity = ((scrollPos - minScrollPos) / (maxScrollPos - minScrollPos)).Clamp01(); - - - var rectX = window.GetMemberValue("m_TreeViewRect").width + 1; - var rectWidth = window.position.width - rectX;// - 12; - - var rect = window.position.SetPos(rectX, 0).MoveY(shadowPos).SetHeight(shadowLength).SetWidth(rectWidth); - - - - var clipAtY = navbarHeight + 22; - - GUI.BeginClip(window.position.SetPos(0, clipAtY)); - - rect.MoveY(-clipAtY).DrawCurtainDown(Greyscale(shadowGreyscale, shadowAlpha * opacity)); - - GUI.EndClip(); - - - - if (isDarkTheme) - window.position.SetPos(rectX, clipAtY - 1).SetSize(12321, 1).Draw(Greyscale(.175f)); // line under breadcrumbs - - } - - - - var doNavbarFirst = GUI.GetNameOfFocusedControl() == "navbar search field" || curEvent.keyCode == KeyCode.Escape; - - if (doNavbarFirst) - navbarGui(); - - hideDefaultTopBar(); - defaultGuiWithOffset(); - treeViewShadow(); - listAreaShadow(); - - if (!doNavbarFirst) - navbarGui(); - - } - - static Dictionary navbars_byWindow = new(); - - - - static void UpdateGUIWrapping(EditorWindow window) - { - if (!window.hasFocus) return; - - var isLocked = window.GetMemberValue("isLocked"); - var isVTabsActive = t_VTabs != null && !EditorPrefsCached.GetBool("vTabs-pluginDisabled", false); - - var curOnGUIMethod = window.GetMemberValue("m_Parent").GetMemberValue("m_OnGUI").Method; - - var isWrapped = curOnGUIMethod == mi_WrappedBrowserOnGUI; - var shouldBeWrapped = VFoldersMenu.navigationBarEnabled && !(isVTabsActive && isLocked) && curOnGUIMethod != mi_VFavorites_WrappedOnGUI; - - void wrap() - { - var hostView = window.GetMemberValue("m_Parent"); - - var newDelegate = typeof(VFolders).GetMethod(nameof(WrappedGUI), maxBindingFlags).CreateDelegate(t_EditorWindowDelegate, window); - - hostView.SetMemberValue("m_OnGUI", newDelegate); - - window.Repaint(); - - } - void unwrap() - { - var hostView = window.GetMemberValue("m_Parent"); - - var originalDelegate = hostView.InvokeMethod("CreateDelegate", "OnGUI"); - - hostView.SetMemberValue("m_OnGUI", originalDelegate); - - window.Repaint(); - - } - - - if (shouldBeWrapped && !isWrapped) - wrap(); - - if (!shouldBeWrapped && isWrapped) - unwrap(); - - } - static void UpdateGUIWrappingForAllBrowsers() => allBrowsers.ForEach(r => UpdateGUIWrapping(r)); - - static void OnDomainReloaded() => toCallInGUI += UpdateGUIWrappingForAllBrowsers; - - static void OnWindowUnmaximized() => UpdateGUIWrappingForAllBrowsers(); - - static void OnBrowserFocused() => UpdateGUIWrapping(EditorWindow.focusedWindow); - - static void OnDelayCall() => UpdateGUIWrappingForAllBrowsers(); - - - - - - static void CheckIfFocusedWindowChanged() - { - if (prevFocusedWindow != EditorWindow.focusedWindow) - if (EditorWindow.focusedWindow?.GetType() == t_ProjectBrowser) - OnBrowserFocused(); - - prevFocusedWindow = EditorWindow.focusedWindow; - - } - - static EditorWindow prevFocusedWindow; - - - - static void CheckIfWindowWasUnmaximized() - { - var isMaximized = EditorWindow.focusedWindow?.maximized == true; - - if (!isMaximized && wasMaximized) - OnWindowUnmaximized(); - - wasMaximized = isMaximized; - - } - - static bool wasMaximized; - - - - static void OnSomeGUI() - { - toCallInGUI?.Invoke(); - toCallInGUI = null; - - CheckIfFocusedWindowChanged(); - - } - - static void ProjectWindowItemOnGUI(string _, Rect __) => OnSomeGUI(); - static void HierarchyWindowItemOnGUI(int _, Rect __) => OnSomeGUI(); - - static System.Action toCallInGUI; - - - - static void DelayCallLoop() - { - OnDelayCall(); - - EditorApplication.delayCall -= DelayCallLoop; - EditorApplication.delayCall += DelayCallLoop; - - } - - - - - - - - - - - - - - - static void ItemGUI(Rect itemRect, string guid, int instanceId) - { - EditorWindow window; - - void findWindow() - { - if (allBrowsers.Count() == 1) { window = allBrowsers.First(); return; } - - - var pointInsideWindow = EditorGUIUtility.GUIToScreenPoint(itemRect.center); - - window = allBrowsers.FirstOrDefault(r => r.position.AddHeight(30).Contains(pointInsideWindow) && r.hasFocus); - - } - void updateWindow() - { - if (!window) return; // happens on half-visible rows during expand animation - - if (curEvent.isLayout && !lastEventWasLayout) - UpdateWindow_Layout(window); - - if (curEvent.isRepaint && !lastEventWasRepaint) - UpdateWindow_Repaint(window); - - - lastEventWasLayout = curEvent.isLayout; - lastEventWasRepaint = curEvent.isRepaint; - - } - void catchScrollInputForController() - { - if (!window) return; - if (!controllers_byWindow.ContainsKey(window)) return; - - if (curEvent.isScroll) - controllers_byWindow[window].animatingScroll = false; - - } - void callGUI() - { - if (!window) return; - if (!guis_byWindow.ContainsKey(window)) return; - - - var gui = guis_byWindow[window]; - - if (itemRect.height == 16) - gui.RowGUI(itemRect, guid, instanceId); - else - gui.CellGUI(itemRect, guid, instanceId); - - } - - findWindow(); - updateWindow(); - catchScrollInputForController(); - callGUI(); - - } - - static void ItemGUI_2021_3_and_older(string guid, Rect itemRect) - { - var instanceId = typeof(AssetDatabase).InvokeMethod("GetMainAssetOrInProgressProxyInstanceID", guid.ToPath()); - - ItemGUI(itemRect, guid, instanceId); - - } - static void ItemGUI_2022_1_and_newer(int instanceId, Rect itemRect) - { - var guid = AssetDatabase.GetAssetPath(instanceId).ToGuid(); - - ItemGUI(itemRect, guid, instanceId); - - } - - static bool lastEventWasLayout; - static bool lastEventWasRepaint; - - - - static void UpdateWindow_Layout(EditorWindow window) - { - if (!guis_byWindow.TryGetValue(window, out var gui)) - gui = guis_byWindow[window] = new(window); - - if (!controllers_byWindow.TryGetValue(window, out var controller)) - controller = controllers_byWindow[window] = new(window); - - if (!histories_byWindow.TryGetValue(window, out var history)) - history = histories_byWindow[window] = new(window); - - - gui.UpdateState_Layout(); - gui.UpdateFoldersFirst(); - - controller.UpdateState(); - controller.UpdateExpandQueue(); - controller.UpdateScrollAnimation(); - controller.UpdateHighlightAnimation(); - - history.UpdateState(); - history.CheckTreeStateChange(); - history.CheckFolderPathChange(); - - } - static void UpdateWindow_Repaint(EditorWindow window) - { - if (guis_byWindow.ContainsKey(window)) - guis_byWindow[window].UpdateState_Repaint(); - } - - public static Dictionary guis_byWindow = new(); - public static Dictionary controllers_byWindow = new(); - public static Dictionary histories_byWindow => VFoldersHistorySingleton.instance.histories_byWindow; - - - - - - - - - public static Texture2D GetSmallFolderIcon(FolderInfo folderInfo, bool removeColor = false) - { - var hasColor = folderInfo.hasColor && !removeColor; - var hasIcon = folderInfo.hasIcon; - - var color = hasColor ? folderInfo.color : default; - var iconNameOrPath = hasIcon ? folderInfo.iconNameOrPath : ""; - - var isEmpty = folderInfo.folderState.isEmpty; - - var key = new object[] { iconNameOrPath, color, isEmpty, isDarkTheme }.Aggregate(0, (hash, r) => (hash * 2) ^ r.GetHashCode()); - - - Texture2D icon = null; - - void getCached() - { - if (!cache.HasIcon(key)) return; - - icon = cache.GetIcon(key); - - } - void generateAndCache() - { - if (icon != null) return; - if (Event.current != null) return; // interactions with gpu in OnGUI may interfere with gui rendering - - var iconSizeX = hasIcon ? 36 : 32; - var iconSizeY = 32; - - var assetIconSize = 20; // 20 21 - var assetIconOffsetX = 16; - var assetIconOffsetY = -2; // -2 -3 - - var folderIconSize = iconSizeY; - var folderIconOffsetY_ifHasAssetIcon = 1; - - Color[] iconPixels; - - Texture2D folderIcon; - Color[] folderIconPixels; - - - void createIcon() - { - icon = new Texture2D(iconSizeX, iconSizeY, TextureFormat.RGBA32, 1, false); - icon.hideFlags = HideFlags.DontSave; - icon.SetPropertyValue("pixelsPerPoint", 2); - - iconPixels = new Color[iconSizeX * iconSizeY]; - - } - void createFolderIcon() - { - var folderIconName = hasColor ? (isEmpty ? "FolderEmpty On Icon" : "Folder On Icon") : - (isEmpty ? "FolderEmpty Icon" : "Folder Icon"); - - - folderIcon = EditorGUIUtility.FindTexture(folderIconName); - - if (folderIcon.width != folderIconSize) - folderIcon = folderIcon.CreateResizedCopy(folderIconSize, folderIconSize); - else - folderIcon = folderIcon.CreateCopy(); - - folderIconPixels = folderIcon.GetPixels(0); - - } - void copyFolderIcon() - { - if (!hasIcon) { iconPixels = folderIconPixels; return; } - - for (int x = 0; x < folderIcon.width; x++) - for (int y = 0; y < folderIcon.height - folderIconOffsetY_ifHasAssetIcon; y++) - iconPixels[x + (y + folderIconOffsetY_ifHasAssetIcon) * icon.width] = folderIconPixels[x + y * folderIcon.width]; - - } - void applyColor() - { - if (!hasColor) return; - - for (int i = 0; i < iconPixels.Length; i++) - iconPixels[i] *= (color * 1.06f).SetAlpha(1); - - } - void insertAssetIcon() - { - if (!hasIcon) return; - - - var assetIconOriginal = EditorIcons.GetIcon(iconNameOrPath); - - if (!assetIconOriginal) return; - - - var prevFilter = assetIconOriginal.filterMode; - - assetIconOriginal.filterMode = FilterMode.Bilinear; - var assetIconPixels_bilinear = assetIconOriginal.CreateResizedCopy(assetIconSize, assetIconSize).GetPixels(); - - assetIconOriginal.filterMode = FilterMode.Point; - var assetIconPixels_point = assetIconOriginal.CreateResizedCopy(assetIconSize, assetIconSize).GetPixels(); - - - assetIconOriginal.filterMode = prevFilter; - - - for (int x = 0; x < iconSizeX; x++) - for (int y = 0; y < iconSizeY; y++) - { - var xAssetIcon = x - assetIconOffsetX; - var yAssetIcon = y - assetIconOffsetY - folderIconOffsetY_ifHasAssetIcon; - - if (!xAssetIcon.IsInRange(0, assetIconSize - 1)) continue; - if (!yAssetIcon.IsInRange(0, assetIconSize - 1)) continue; - - - var innerRadius = (iconNameOrPath == "AudioClip Icon" ? .2f : .4f); - var isInnerPixel = (new Vector2(xAssetIcon, yAssetIcon) / (assetIconSize - 1) - Vector2.one * .5f).magnitude < innerRadius; - - var isOutlinePixel = false; - var outlineRadius = isInnerPixel ? 2 : 1; - for (int xx = xAssetIcon - outlineRadius; xx <= xAssetIcon + outlineRadius; xx++) - if (!isOutlinePixel) - for (int yy = yAssetIcon - outlineRadius; yy <= yAssetIcon + outlineRadius; yy++) - if (!isOutlinePixel) - if (xx.IsInRange(0, assetIconSize - 1) && yy.IsInRange(0, assetIconSize - 1)) - if (assetIconPixels_bilinear[xx + yy * assetIconSize].a > .2f) - isOutlinePixel = true; - - - var pxBilinear = assetIconPixels_bilinear[xAssetIcon + yAssetIcon * assetIconSize]; - var pxPoint = assetIconPixels_point[xAssetIcon + yAssetIcon * assetIconSize]; - var pxCombined = new Color(pxPoint.r, pxPoint.g, pxPoint.b, pxBilinear.a); - - if (pxCombined.a == 0 && !isOutlinePixel) continue; - - iconPixels[x + y * iconSizeX] = pxCombined; - - } - - } - - - createIcon(); - createFolderIcon(); - copyFolderIcon(); - applyColor(); - insertAssetIcon(); - - icon.SetPixels(iconPixels); - icon.Apply(); - - cache.AddIcon(key, icon); - - } - void queueGeneration() - { - if (icon != null) return; - - toGenerateInUpdate.Add(generateAndCache); - - } - - - getCached(); - generateAndCache(); - queueGeneration(); - - return icon ?? EditorGUIUtility.FindTexture(isEmpty ? "FolderEmpty Icon" : "Project@2x"); - - } - - static void GenerateIconsInUpdate() - { - foreach (var r in toGenerateInUpdate) - r.Invoke(); - - toGenerateInUpdate.Clear(); - - } - - static List toGenerateInUpdate = new(); - - - - public static void DrawBigFolderIcon(Rect rect, FolderInfo folderInfo) - { - Rect folderIconRect; - Rect assetIconRect; - - - void calcRects() - { - folderIconRect = rect.SetHeight(rect.width); - -#if !UNITY_2022_3_OR_NEWER - if (Application.platform == RuntimePlatform.OSXEditor) - if (folderIconRect.width > 64) - folderIconRect = folderIconRect.SetSizeFromMid(64, 64); -#endif - - - var assetIconOffsetMin = new Vector2(4.5f, 3.5f); - var assetIconSizeMin = 10; - - var assetIconOffsetMax = new Vector2(19, 15); - var assetIconSizeMax = 24.5f; // 25 - - var t = ((folderIconRect.width - 16) / (64 - 16)); - -#if !UNITY_2022_3_OR_NEWER - if (Application.platform == RuntimePlatform.OSXEditor) - t = t.Clamp01(); -#endif - - var assetIconOffset = MathUtil.Lerp(assetIconOffsetMin, assetIconOffsetMax, t); - var assetIconSize = MathUtil.Lerp(assetIconSizeMin, assetIconSizeMax, t); - - assetIconRect = folderIconRect.Move(assetIconOffset).SetSizeFromMid(assetIconSize, assetIconSize).AlignToPixelGrid(); - - } - - void color() - { - if (!folderInfo.hasColor) return; - - - SetGUIColor(folderInfo.color.SetAlpha(1)); - - GUI.DrawTexture(folderIconRect, EditorGUIUtility.FindTexture(folderInfo.folderState.isEmpty ? "FolderEmpty On Icon" : "Folder On Icon")); - - ResetGUIColor(); - - } - void assetIcon() - { - if (!folderInfo.hasIcon) return; - - - var texture = EditorIcons.GetIcon(folderInfo.iconNameOrPath); - - if (!texture) return; - - if (texture.width < texture.height) assetIconRect = assetIconRect.SetWidthFromMid(assetIconRect.height * texture.width / texture.height); - if (texture.height < texture.width) assetIconRect = assetIconRect.SetHeightFromMid(assetIconRect.width * texture.height / texture.width); - - - - void material() - { - if (!outlineMaterial) - outlineMaterial = new Material(Shader.Find("Hidden/Internal-GUITextureClipText")); - - outlineMaterial.color = isDarkTheme ? Greyscale(.2f, .6f) : Greyscale(.75f); - - // .color needs to be updated continiously because it gets reset on some editor events - // only happens when internal shader is used - - } - - void shadow() - { - var contrast = isDarkTheme ? .6f : .2f; // was .65 then .6 - - assetIconRect.SetSizeFromMid(assetIconRect.width * .8f).DrawBlurred(Greyscale(.2f, contrast), assetIconRect.width * .55f); - - } - void outline() - { - var outlineRect = assetIconRect.Resize(rect.height >= 70 && EditorGUIUtility.pixelsPerPoint >= 2 ? -1f / EditorGUIUtility.pixelsPerPoint : 0).AlignToPixelGrid(); - - EditorGUI.DrawPreviewTexture(outlineRect.Move(-1, -1), texture, outlineMaterial); - EditorGUI.DrawPreviewTexture(outlineRect.Move(-1, 1), texture, outlineMaterial); - EditorGUI.DrawPreviewTexture(outlineRect.Move(1, 1), texture, outlineMaterial); - EditorGUI.DrawPreviewTexture(outlineRect.Move(1, -1), texture, outlineMaterial); - - } - void background() - { - for (int i = 0; i < assetIconRect.size.x; i++) - EditorGUI.DrawPreviewTexture(assetIconRect.Resize(i * .5f + 1), texture, outlineMaterial); - - } - void icon() - { - GUI.DrawTexture(assetIconRect, texture); - } - - material(); - - shadow(); - outline(); - background(); - icon(); - - } - - - calcRects(); - - color(); - assetIcon(); - - } - - static Material outlineMaterial; - - - - - - - - - - - - - - - - - - public static Texture2D GetSmallFolderIcon_forVTabs(string folderGuid) - { - var folderInfo = GetFolderInfo(folderGuid); - - if (folderInfo.hasColor || folderInfo.hasIcon) - return GetSmallFolderIcon(folderInfo); - - return null; - - } - - public static void DrawBigFolderIcon_forVFavorites(Rect rect, string folderGuid) - { - DrawBigFolderIcon(rect, GetFolderInfo(folderGuid)); - } - - public static void SetIcon(string folderPath, string iconName, bool recursive = false) - { - var folderData = GetFolderData(folderPath.ToGuid(), createDataIfDoesntExist: true); - - folderData.iconNameOrGuid = iconName ?? ""; - folderData.isIconRecursive = recursive; - - - folderInfoCache.Clear(); - - EditorApplication.RepaintProjectWindow(); - - } - public static void SetColor(string folderPath, int colorIndex, bool recursive = false) - { - var folderData = GetFolderData(folderPath.ToGuid(), createDataIfDoesntExist: true); - - folderData.colorIndex = colorIndex; - folderData.isColorRecursive = recursive; - - - folderInfoCache.Clear(); - - EditorApplication.RepaintProjectWindow(); - - } - - - - - - - - - - - - - - - - - - static void Shortcuts() // globalEventHandler - { - if (!curEvent.isKeyDown) return; - if (curEvent.keyCode == KeyCode.None) return; - if (EditorWindow.mouseOverWindow is not EditorWindow hoveredWindow) return; - if (hoveredWindow.GetType() != t_ProjectBrowser) return; - - void toggleExpanded() - { - if (!curEvent.isKeyDown) return; - if (curEvent.keyCode != KeyCode.E) return; - if (curEvent.holdingAnyModifierKey) return; - if (!VFoldersMenu.toggleExpandedEnabled) return; - - if (lastHoveredTreeItem == null) return; - if (!lastHoveredRowRect_screenSpace.Contains(lastKnownMousePosition_screenSpace)) return; - - curEvent.Use(); - - if (lastHoveredTreeItem.children == null) return; - if (lastHoveredTreeItem.children.Count == 0) return; - - - controllers_byWindow[hoveredWindow].ToggleExpanded(lastHoveredTreeItem); - - } - void collapseEverything() - { - if (!curEvent.isKeyDown) return; - if (curEvent.keyCode != KeyCode.E) return; - if (curEvent.modifiers != (EventModifiers.Shift | EventModifiers.Command) && curEvent.modifiers != (EventModifiers.Shift | EventModifiers.Control)) return; - if (!VFoldersMenu.collapseEverythingEnabled) return; - - curEvent.Use(); - - - controllers_byWindow[hoveredWindow].CollapseAll(); - - } - void collapseEverythingElse() - { - if (!curEvent.isKeyDown) return; - if (curEvent.keyCode != KeyCode.E) return; - if (curEvent.modifiers != EventModifiers.Shift) return; - if (!VFoldersMenu.collapseEverythingElseEnabled) return; - - if (lastHoveredTreeItem == null) return; - if (!lastHoveredRowRect_screenSpace.Contains(lastKnownMousePosition_screenSpace)) return; - - curEvent.Use(); - - if (lastHoveredTreeItem.children == null) return; - if (lastHoveredTreeItem.children.Count == 0) return; - - - controllers_byWindow[hoveredWindow].Isolate(lastHoveredTreeItem); - - } - - toggleExpanded(); - collapseEverything(); - collapseEverythingElse(); - - } - - public static TreeViewItem lastHoveredTreeItem; - - public static Rect lastHoveredRowRect_screenSpace; - - public static Vector2 lastKnownMousePosition_screenSpace; - - - - - - - - - - - - - - - - - - public static FolderInfo GetFolderInfo(string guid) - { - if (folderInfoCache.TryGetValue(guid, out var cachedFolderInfo)) return cachedFolderInfo; - - - var folderInfo = new FolderInfo(); - - var folderData = folderInfo.folderData = GetFolderData(guid, createDataIfDoesntExist: false); - var folderState = folderInfo.folderState = GetFolderState(guid); - - - var recursiveIconNameOrGuid = ""; - var recursiveColorIndex = 0; - - var ruledIconNameOrGuid = ""; - var ruledColorIndex = 0; - - void checkRules() - { - if (rules == null) - rules = TypeCache.GetMethodsWithAttribute() - .Where(r => r.IsStatic - && r.GetParameters().Count() == 1 - && r.GetParameters().First().ParameterType == typeof(Folder)).ToList(); - - if (!rules.Any()) return; - - - - var folder = new Folder(guid); - - foreach (var rule in rules) - rule.Invoke(null, new[] { folder }); - - - ruledIconNameOrGuid = folder.icon; - ruledColorIndex = folder.color; - - - } - void checkRecursion(string path, int depth) - { - if (!path.HasParentPath()) return; - - var parentFolderData = GetFolderData(path.GetParentPath().ToGuid(), createDataIfDoesntExist: false); - - if (parentFolderData != null) - { - - if (parentFolderData.isIconRecursive && parentFolderData.iconNameOrGuid != "") - if (recursiveIconNameOrGuid == "") - recursiveIconNameOrGuid = parentFolderData.iconNameOrGuid; - - if (parentFolderData.isColorRecursive && parentFolderData.colorIndex != 0) - if (recursiveColorIndex == 0) - recursiveColorIndex = parentFolderData.colorIndex; - - - if (parentFolderData.isColorRecursive && parentFolderData.colorIndex != 0) - folderInfo.maxColorRecursionDepth = depth + 1; - - } - - - - checkRecursion(path.GetParentPath(), depth + 1); - - } - void setIcon() - { - var iconNameOrGuid = ""; - - if (folderData != null && folderData.iconNameOrGuid != "") - iconNameOrGuid = folderData.iconNameOrGuid; - - else if (recursiveIconNameOrGuid != "") - iconNameOrGuid = recursiveIconNameOrGuid; - - else if (ruledIconNameOrGuid != "") - iconNameOrGuid = ruledIconNameOrGuid; - - else if (VFoldersMenu.autoIconsEnabled && folderState.autoIconName != "" && folderData?.isIconRecursive != true) - iconNameOrGuid = folderState.autoIconName; - - - - if (iconNameOrGuid == "" || iconNameOrGuid == "none") { folderInfo.hasIcon = false; return; } - - folderInfo.hasIcon = true; - folderInfo.hasIconByRecursion = recursiveIconNameOrGuid != ""; - - folderInfo.iconNameOrPath = iconNameOrGuid.Length == 32 ? iconNameOrGuid.ToPath() - : iconNameOrGuid; - - } - void setColor() - { - var colorIndex = 0; - - if (folderData != null && folderData.colorIndex > 0) - colorIndex = folderData.colorIndex; - - else if (recursiveColorIndex != 0) - colorIndex = recursiveColorIndex; - - else if (ruledColorIndex != 0) - colorIndex = ruledColorIndex; - - - - if (colorIndex == 0) { folderInfo.hasColor = false; return; } - - folderInfo.hasColor = true; - folderInfo.hasColorByRecursion = recursiveColorIndex != 0; - - - - - var brightness = palette?.colorBrightness ?? 1; - var saturation = palette?.colorSaturation ?? 1; - - - var rawColor = palette ? palette.colors[colorIndex - 1] : VFoldersPalette.GetDefaultColor(colorIndex - 1); - - var brightenedColor = MathUtil.Lerp(Greyscale(.2f), rawColor, brightness); - - Color.RGBToHSV(brightenedColor, out float h, out float s, out float v); - var saturatedColor = Color.HSVToRGB(h, s * saturation, v); - - - folderInfo.color = saturatedColor; - - } - - checkRules(); - checkRecursion(guid.ToPath(), 0); - setIcon(); - setColor(); - - - return folderInfoCache[guid] = folderInfo; - - } - - public class FolderInfo - { - public string iconNameOrPath = ""; - public bool hasIcon; - public bool hasIconByRecursion; - - public Color color; - public bool hasColor; - public bool hasColorByRecursion; - public int maxColorRecursionDepth; - - - public FolderData folderData; - public FolderState folderState; - - } - - public static Dictionary folderInfoCache = new(); - - public static List rules = null; - - - - public static FolderData GetFolderData(string guid, bool createDataIfDoesntExist) - { - if (!data) return null; - - FolderData folderData = null; - - void fromScripableObject() - { - if (VFoldersData.storeDataInMetaFiles) return; - - data.folderDatas_byGuid.TryGetValue(guid, out folderData); - - - if (folderData != null || !createDataIfDoesntExist) return; - - folderData = new FolderData(); - - data.folderDatas_byGuid[guid] = folderData; - - } - void fromMetaFile() - { - if (!VFoldersData.storeDataInMetaFiles) return; - - folderDatasFromMetaFiles_byGuid.TryGetValue(guid, out folderData); - - - - if (folderData != null) return; - - var importer = AssetImporter.GetAtPath(guid.ToPath()); - - try { folderData = JsonUtility.FromJson(importer.userData); } catch { } - - folderDatasFromMetaFiles_byGuid[guid] = folderData; - - - - if (folderData != null || !createDataIfDoesntExist) return; - - folderData = new FolderData(); - - folderDatasFromMetaFiles_byGuid[guid] = folderData; - - } - - fromScripableObject(); - fromMetaFile(); - - return folderData; - - } - - public static Dictionary folderDatasFromMetaFiles_byGuid = new(); - - - - public static FolderState GetFolderState(string guid) - { - FolderState folderState = null; - - void getCached() - { - cache.folderStates_byGuid.TryGetValue(guid, out folderState); - } - void create() - { - if (folderState != null) return; - - folderState = new FolderState(); - - folderState.needsUpdate = true; - - cache.folderStates_byGuid[guid] = folderState; - - } - void update() - { - if (!folderState.needsUpdate) return; - if (!Directory.Exists(guid.ToPath())) { folderState.needsUpdate = false; return; } - - - var typesInFolder = Directory.GetFiles(guid.ToPath(), "*.*").Select(r => AssetDatabase.GetMainAssetTypeAtPath(r)).Where(r => r != null); - - void isEmpty() - { - folderState.isEmpty = !Directory.EnumerateFileSystemEntries(guid.ToPath()).Any(); - } - void contentMinimap() - { - var iconNames = new List(); - - void fill() - { - foreach (var type in typesInFolder) - - if (type == typeof(Texture2D)) - iconNames.Add("Texture Icon"); - - else if (type == typeof(GameObject)) - iconNames.Add("Prefab Icon"); - - else if (type.BaseType == typeof(ScriptableObject) || type.BaseType?.BaseType == typeof(ScriptableObject)) - iconNames.Add("ScriptableObject Icon"); - - else if (type == typeof(MonoScript)) - iconNames.Add("cs Script Icon"); - - else if (AssetPreview.GetMiniTypeThumbnail(type)?.name is string iconName) - iconNames.Add(iconName); - - } - void filter() - { - iconNames = iconNames.Distinct().ToList(); - - - for (int i = 0; i < iconNames.Count; i++) - if (iconNames[i].StartsWith("d_")) - iconNames[i] = iconNames[i].Substring(2); - - - - iconNames.Remove("DefaultAsset Icon"); - iconNames.Remove("TextAsset Icon"); - - - - if (iconNames.Contains("cs Script Icon")) - iconNames.Remove("AssemblyDefinitionAsset Icon"); - - if (iconNames.Contains("Shader Icon")) - iconNames.Remove("ShaderInclude Icon"); - - } - void order() - { - var order = new List - { - - "SceneAsset Icon", - - - "Prefab Icon", - "Mesh Icon", - "Material Icon", - "Texture Icon", - - - "cs Script Icon", - "Shader Icon", - "ComputeShader Icon", - "ShaderInclude Icon", - - - "ScriptableObject Icon", - - }; - - iconNames = iconNames.OrderBy(r => order.IndexOf(r) is int i && i != -1 ? i : 1232) - .ThenBy(r => r) - .ToList(); - } - - fill(); - filter(); - order(); - - folderState.contentMinimapIconNames = iconNames; - - } - void autoIcon() - { - folderState.autoIconName = ""; - - - if (!typesInFolder.Any()) return; - if (!typesInFolder.All(r => r == typesInFolder.First()) && !typesInFolder.All(r => typeof(ScriptableObject).IsAssignableFrom(r))) return; - - var type = typesInFolder.First(); - - - if (type == typeof(SceneAsset)) - folderState.autoIconName = "SceneAsset Icon"; - - else if (type == typeof(GameObject)) - folderState.autoIconName = "Prefab Icon"; - - else if (type == typeof(Material)) - folderState.autoIconName = "Material Icon"; - - else if (type == typeof(Texture)) - folderState.autoIconName = "Texture Icon"; - - else if (type == typeof(TerrainData)) - folderState.autoIconName = "TerrainData Icon"; - - else if (type == typeof(AudioClip)) - folderState.autoIconName = "AudioClip Icon"; - - else if (type == typeof(Shader)) - folderState.autoIconName = "Shader Icon"; - - else if (type == typeof(ComputeShader)) - folderState.autoIconName = "ComputeShader Icon"; - - else if (type == typeof(MonoScript) || type == typeof(UnityEditorInternal.AssemblyDefinitionAsset) || type == typeof(UnityEditorInternal.AssemblyDefinitionReferenceAsset)) - folderState.autoIconName = "cs Script Icon"; - - else if (typeof(ScriptableObject).IsAssignableFrom(type)) - folderState.autoIconName = "ScriptableObject Icon"; - - } - - - isEmpty(); - contentMinimap(); - autoIcon(); - - folderState.needsUpdate = false; - - } - - getCached(); - create(); - update(); - - return folderState; - - } - - class FolderStateChangeDetector : AssetPostprocessor - { -#if UNITY_2021_1_OR_NEWER - static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths, bool didDomainReload) -#else - static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths) -#endif - { - foreach (var path in importedAssets.Concat(deletedAssets).Concat(movedAssets).Concat(movedFromAssetPaths)) - if (path.HasParentPath()) - if (cache.folderStates_byGuid.TryGetValue(path.GetParentPath().ToGuid(), out var folderState)) - folderState.needsUpdate = true; // todo only clear folderinfo cache here? - } - } - - public static VFoldersCache cache => VFoldersCache.instance; - - - - public static void OnProjectChanged() => folderInfoCache.Clear(); - public static void OnDataSerialization() => folderInfoCache.Clear(); - - - - - - - - - - - - - - - - - [InitializeOnLoadMethod] - static void Init() - { - if (VFoldersMenu.pluginDisabled) return; - - void subscribe() - { - - // gui - -#if UNITY_2022_1_OR_NEWER - EditorApplication.projectWindowItemInstanceOnGUI -= ItemGUI_2022_1_and_newer; - EditorApplication.projectWindowItemInstanceOnGUI = ItemGUI_2022_1_and_newer + EditorApplication.projectWindowItemInstanceOnGUI; -#else - EditorApplication.projectWindowItemOnGUI -= ItemGUI_2021_3_and_older; - EditorApplication.projectWindowItemOnGUI = ItemGUI_2021_3_and_older + EditorApplication.projectWindowItemOnGUI; -#endif - - - - // wrapping updaters - - EditorApplication.projectWindowItemOnGUI -= ProjectWindowItemOnGUI; - EditorApplication.projectWindowItemOnGUI += ProjectWindowItemOnGUI; - - EditorApplication.hierarchyWindowItemOnGUI -= HierarchyWindowItemOnGUI; - EditorApplication.hierarchyWindowItemOnGUI += HierarchyWindowItemOnGUI; - - EditorApplication.delayCall -= DelayCallLoop; - EditorApplication.delayCall += DelayCallLoop; - - EditorApplication.update -= CheckIfFocusedWindowChanged; - EditorApplication.update += CheckIfFocusedWindowChanged; - - - - // shortcuts - - var globalEventHandler = typeof(EditorApplication).GetFieldValue("globalEventHandler"); - typeof(EditorApplication).SetFieldValue("globalEventHandler", Shortcuts + (globalEventHandler - Shortcuts)); - - - - // other - - EditorApplication.update -= GenerateIconsInUpdate; - EditorApplication.update += GenerateIconsInUpdate; - - EditorApplication.projectChanged -= OnProjectChanged; - EditorApplication.projectChanged += OnProjectChanged; - - - } - void loadData() - { - data = AssetDatabase.LoadAssetAtPath(ProjectPrefs.GetString("vFolders-lastKnownDataPath")); - - - if (data) return; - - data = AssetDatabase.FindAssets("t:VFoldersData").Select(guid => AssetDatabase.LoadAssetAtPath(guid.ToPath())).FirstOrDefault(); - - - if (!data) return; - - ProjectPrefs.SetString("vFolders-lastKnownDataPath", data.GetPath()); - - } - void loadPalette() - { - palette = AssetDatabase.LoadAssetAtPath(ProjectPrefs.GetString("vFolders-lastKnownPalettePath")); - - - if (palette) return; - - palette = AssetDatabase.FindAssets("t:VFoldersPalette").Select(guid => AssetDatabase.LoadAssetAtPath(guid.ToPath())).FirstOrDefault(); - - - if (!palette) return; - - ProjectPrefs.SetString("vFolders-lastKnownPalettePath", palette.GetPath()); - - } - void loadDataAndPaletteDelayed() - { - if (!data) - EditorApplication.delayCall += () => EditorApplication.delayCall += loadData; - - if (!palette) - EditorApplication.delayCall += () => EditorApplication.delayCall += loadPalette; - - // AssetDatabase isn't up to date at this point (it gets updated after InitializeOnLoadMethod) - // and if current AssetDatabase state doesn't contain the data - it won't be loaded during Init() - // so here we schedule an additional, delayed attempt to load the data - // this addresses reports of data loss when trying to load it on a new machine - - } - void migrateDataFromV1() - { - if (!data) return; - if (ProjectPrefs.GetBool("vFolders-dataMigrationFromV1Attempted", false)) return; - - ProjectPrefs.SetBool("vFolders-dataMigrationFromV1Attempted", true); - - var lines = System.IO.File.ReadAllLines(data.GetPath()); - - if (lines.Length < 15 || !lines[14].Contains("folderDatasByGuid")) return; - - var guids = new List(); - var icons = new List(); - var colors = new List(); - - void parseGudis() - { - for (int i = 16; i < lines.Length; i++) - { - if (lines[i].Contains("values:")) break; - - var startIndex = lines[i].IndexOf("- ") + 2; - - if (startIndex < lines[i].Length) - guids.Add(lines[i].Substring(startIndex)); - else - guids.Add(""); - - } - - } - void parseIcons() - { - for (int i = 0; i < guids.Count; i++) - if (lines[29 + i * 5 + 3] is string line) - if (line.Length > line.IndexOf(": ") + 2) - icons.Add(line.Substring(line.IndexOf(": ") + 2)); - else - icons.Add(""); - - } - void parseColors() - { - for (int i = 0; i < guids.Count; i++) - if (lines[29 + i * 5 + 1] is string line) - if (line.Length > line.IndexOf(": ") + 2) - colors.Add(int.Parse(line.Substring(line.IndexOf(": ") + 2))); - else - colors.Add(0); - - } - - void remapColors() - { - for (int i = 0; i < colors.Count; i++) - if (colors[i] == 10) - colors[i] = 1; - else if (colors[i] != 0) - colors[i]++; - - } - void fillData() - { - for (int i = 0; i < guids.Count; i++) - if (icons[i] != "" || colors[i] != 0) - data.folderDatas_byGuid[guids[i]] = new FolderData { iconNameOrGuid = icons[i], colorIndex = colors[i] }; - - data.Dirty(); - data.Save(); - - } - - - try - { - parseGudis(); - parseIcons(); - parseColors(); - - remapColors(); - fillData(); - - } - catch { } - - } - void fixIconNamesForUnity6() - { - if (!Application.unityVersion.Contains("6000")) return; - if (ProjectPrefs.GetBool("vFolders-iconNamesForUnity6Fixed", false)) return; - if (!palette) return; - if (!data) return; - - foreach (var iconRow in palette.iconRows) - if (iconRow.builtinIcons.Contains("PhysicMaterial Icon")) - iconRow.builtinIcons[iconRow.builtinIcons.IndexOf("PhysicMaterial Icon")] = "PhysicsMaterial Icon"; - - foreach (var folderData in data.folderDatas_byGuid.Values) - if (folderData.iconNameOrGuid == "PhysicMaterial Icon") - folderData.iconNameOrGuid = "PhysicsMaterial Icon"; - - ProjectPrefs.SetBool("vFolders-iconNamesForUnity6Fixed", true); - - } - - subscribe(); - loadData(); - loadPalette(); - loadDataAndPaletteDelayed(); - migrateDataFromV1(); - fixIconNamesForUnity6(); - - OnDomainReloaded(); - - } - - public static VFoldersData data; - public static VFoldersPalette palette; - - - - - - static IEnumerable allBrowsers => _allBrowsers ??= t_ProjectBrowser.GetFieldValue("s_ProjectBrowsers").Cast(); - static IEnumerable _allBrowsers; - - static Type t_ProjectBrowser = typeof(Editor).Assembly.GetType("UnityEditor.ProjectBrowser"); - static Type t_HostView = typeof(Editor).Assembly.GetType("UnityEditor.HostView"); - static Type t_EditorWindowDelegate = t_HostView.GetNestedType("EditorWindowDelegate", maxBindingFlags); - - static Type t_VTabs = Type.GetType("VTabs.VTabs") ?? Type.GetType("VTabs.VTabs, VTabs, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"); - static Type t_VFavorites = Type.GetType("VFavorites.VFavorites") ?? Type.GetType("VFavorites.VFavorites, VFavorites, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"); - - static MethodInfo mi_WrappedBrowserOnGUI = typeof(VFolders).GetMethod(nameof(WrappedGUI), maxBindingFlags); - static MethodInfo mi_VFavorites_WrappedOnGUI = t_VFavorites?.GetMethod("WrappedOnGUI", maxBindingFlags); - - - - - - const string version = "2.1.5"; - - } - - #region Rules - - public class RuleAttribute : System.Attribute { } - - public class Folder - { - public string path => guid.ToPath(); - public string name => path.Split('/').Last(); - - public int color = 0; - public string icon = ""; - - - - public Folder(string guid) => this.guid = guid; - - string guid; - - - } - - - - #endregion - -} -#endif diff --git a/Assets/Plugins/vFolders/VFolders.cs.meta b/Assets/Plugins/vFolders/VFolders.cs.meta deleted file mode 100644 index 726886f6b..000000000 --- a/Assets/Plugins/vFolders/VFolders.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: cb4ae53db31ef4fdfbfc47484afb8192 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Plugins/vFolders/VFoldersCache.cs b/Assets/Plugins/vFolders/VFoldersCache.cs deleted file mode 100644 index 87086b459..000000000 --- a/Assets/Plugins/vFolders/VFoldersCache.cs +++ /dev/null @@ -1,102 +0,0 @@ -#if UNITY_EDITOR -using System.Collections; -using System.Collections.Generic; -using UnityEngine; -using UnityEditor; -using UnityEditor.ShortcutManagement; -using System.Reflection; -using System.Linq; -using UnityEngine.UIElements; -using UnityEngine.SceneManagement; -using UnityEditor.SceneManagement; -using static VFolders.Libs.VUtils; -using static VFolders.Libs.VGUI; -// using static VTools.VDebug; - -namespace VFolders -{ - [FilePath("Library/vFolders Cache.asset", FilePathAttribute.Location.ProjectFolder)] - public class VFoldersCache : ScriptableSingleton - { - - public Texture2D GetIcon(int key) - { - if (instance.iconTextures_byKey.ContainsKey(key)) - return instance.iconTextures_byKey[key]; - - if (instance.iconTextureDatas_byKey.ContainsKey(key)) - return instance.iconTextures_byKey[key] = instance.iconTextureDatas_byKey[key].GetTexture(); - - return null; - - } - - public void AddIcon(int key, Texture2D icon) - { - instance.iconTextures_byKey[key] = icon; - instance.iconTextureDatas_byKey[key] = new TextureData(icon); - - instance.Save(true); - - } - public bool HasIcon(int key) => instance.iconTextureDatas_byKey.ContainsKey(key); - - public Dictionary iconTextures_byKey = new(); - public SerializableDictionary iconTextureDatas_byKey = new(); - - [System.Serializable] - public class TextureData - { - public byte[] rawData; - public int width; - public int height; - public TextureFormat format; - public int mipCount; - public float pixelsPerPoint; - - public TextureData(Texture2D t) - { - rawData = t.GetRawTextureData(); - width = t.width; - height = t.height; - format = t.format; - mipCount = t.mipmapCount; - pixelsPerPoint = t.GetPropertyValue("pixelsPerPoint"); - - } - - public Texture2D GetTexture() - { - var t = new Texture2D(width, height, format, mipCount, false); - t.LoadRawTextureData(rawData); - t.SetPropertyValue("pixelsPerPoint", pixelsPerPoint); - t.hideFlags = HideFlags.DontSave; - t.Apply(); - - return t; - - } - - } - - - - - public SerializableDictionary folderStates_byGuid = new(); - - [System.Serializable] - public class FolderState - { - public bool isEmpty; - - public List contentMinimapIconNames = new(); - - public string autoIconName = ""; - - public bool needsUpdate; - - } - - } -} -#endif diff --git a/Assets/Plugins/vFolders/VFoldersCache.cs.meta b/Assets/Plugins/vFolders/VFoldersCache.cs.meta deleted file mode 100644 index 8cdb8933a..000000000 --- a/Assets/Plugins/vFolders/VFoldersCache.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 69c14c9fceb5b4c968f55fe5786a0bee -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Plugins/vFolders/VFoldersController.cs b/Assets/Plugins/vFolders/VFoldersController.cs deleted file mode 100644 index d15ecb32c..000000000 --- a/Assets/Plugins/vFolders/VFoldersController.cs +++ /dev/null @@ -1,521 +0,0 @@ -#if UNITY_EDITOR -using System.Collections; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Reflection; -using UnityEngine; -using UnityEditor; -using UnityEditor.ShortcutManagement; -using UnityEngine.UIElements; -using UnityEngine.SceneManagement; -using UnityEditor.SceneManagement; -using UnityEditor.IMGUI.Controls; -using Type = System.Type; -using static VFolders.Libs.VUtils; -using static VFolders.Libs.VGUI; -// using static VTools.VDebug; -using static VFolders.VFolders; -using static VFolders.VFoldersData; -using static VFolders.VFoldersCache; - - - -namespace VFolders -{ - public class VFoldersController - { - - public void UpdateExpandQueue() - { - if (treeViewAnimatesExpansion) return; - - if (!expandQueue_toAnimate.Any()) - { - if (!expandQueue_toCollapseAfterAnimation.Any()) return; - - foreach (var id in expandQueue_toCollapseAfterAnimation) - SetExpanded_withoutAnimation(id, false); - - expandQueue_toCollapseAfterAnimation.Clear(); - - return; - } - - - var iid = expandQueue_toAnimate.First().id; - var expand = expandQueue_toAnimate.First().expand; - - - if (expandedIds.Contains(iid) != expand) - SetExpanded_withAnimation(iid, expand); - - expandQueue_toAnimate.RemoveAt(0); - - - window.Repaint(); - - } - - public List expandQueue_toAnimate = new(); - public List expandQueue_toCollapseAfterAnimation = new(); - - public struct ExpandQueueEntry { public int id; public bool expand; } - - public bool animatingExpansion => expandQueue_toAnimate.Any() || expandQueue_toCollapseAfterAnimation.Any(); - - - - - - - public void UpdateScrollAnimation() - { - if (!animatingScroll) return; - - - var lerpSpeed = 10; - - var lerpedScrollPos = MathUtil.SmoothDamp(currentScrollPos, targetScrollPos, lerpSpeed, ref scrollPosDerivative, editorDeltaTime); - - SetScrollPos(lerpedScrollPos); - - window.Repaint(); - - - - if (lerpedScrollPos.DistanceTo(targetScrollPos) > .4f) return; - - SetScrollPos(targetScrollPos); - - animatingScroll = false; - - - } - - public float targetScrollPos; - public float scrollPosDerivative; - - public bool animatingScroll; - - - - - - - - public void UpdateHighlightAnimation() - { - if (!animatingHighlight) return; - - - var lerpSpeed = 1.2f; - - MathUtil.SmoothDamp(ref highlightAmount, 0, lerpSpeed, ref highlightDerivative, editorDeltaTime); - - window.Repaint(); - - - - if (highlightAmount > .05f) return; - - highlightAmount = 0; - - animatingHighlight = false; - - - } - - public float highlightAmount; - public float highlightDerivative; - - public bool animatingHighlight; - - public string folderToHighlight; - - - - - - - - public void UpdateState() - { - isOneColumn = window.GetFieldValue("m_ViewMode") == 0; - - treeViewController = window.GetFieldValue(isOneColumn ? "m_AssetTree" : "m_FolderTree"); - treeViewControllerData = treeViewController?.GetPropertyValue("data"); - - - - var treeViewState = treeViewController?.GetPropertyValue("state"); - - currentScrollPos = treeViewState?.scrollPos.y ?? 0; - - expandedIds = treeViewState?.expandedIDs ?? new List(); - - - - var treeViewAnimator = treeViewController?.GetMemberValue("m_ExpansionAnimator"); - var treeViewAnimatorSetup = treeViewAnimator?.GetMemberValue("m_Setup"); - - treeViewAnimatesScroll = treeViewController?.GetMemberValue("m_FramingAnimFloat").isAnimating ?? false; - - treeViewAnimatesExpansion = treeViewAnimator?.GetMemberValue("isAnimating") ?? false; - - } - - bool isOneColumn; - - object treeViewController; - object treeViewControllerData; - - public float currentScrollPos; - - public List expandedIds = new(); - - public bool treeViewAnimatesScroll; - public bool treeViewAnimatesExpansion; - - public int GetRowIndex(int instanceId) - { - return treeViewControllerData.InvokeMethod("GetRow", instanceId); - } - - - - - - - - - - - - - - - - - public void ToggleExpanded(TreeViewItem item) - { - SetExpanded_withAnimation(item.id, !expandedIds.Contains(item.id)); - - window.Repaint(); - - } - - public void CollapseAll() - { - - var idsToCollapse_roots = expandedIds.Where(id => EditorUtility.InstanceIDToObject(id).GetPath() is string path && - path.HasParentPath() && - (path.GetParentPath() == "Assets" || path.GetParentPath() == "Packages")); - - - var idsToCollapse_children = expandedIds.Where(id => EditorUtility.InstanceIDToObject(id).GetPath() is string path && - !path.IsNullOrEmpty() && - path != "Assets" && - path != "Packages" && - !idsToCollapse_roots.Contains(id)); - - - expandQueue_toCollapseAfterAnimation = idsToCollapse_children.ToList(); - - expandQueue_toAnimate = idsToCollapse_roots.Select(id => new ExpandQueueEntry { id = id, expand = false }) - .OrderBy(row => GetRowIndex(row.id)).ToList(); - - - StartScrollAnimation(targetScrollPos: 0); - - - window.Repaint(); - - } - - public void Isolate(TreeViewItem targetItem) - { - - List getParents(TreeViewItem item) - { - var parents = new List(); - - while (item.parent != null) - parents.Add(item = item.parent); - - return parents; - - } - - var targetItemParents = getParents(targetItem); - - - - var expandedVisibleItems = new List(); - - foreach (var expandedId in expandedIds) - if (GetRowIndex(expandedId) is int rowIndex && rowIndex != -1) - expandedVisibleItems.Add(treeViewControllerData.InvokeMethod("GetItem", rowIndex)); - - - - var itemsToCollapse = expandedVisibleItems.ToList(); - - itemsToCollapse.Remove(targetItem); - itemsToCollapse.RemoveAll(r => targetItemParents.Contains(r)); - itemsToCollapse.RemoveAll(r => itemsToCollapse.Intersect(getParents(r)).Any()); - - - - expandQueue_toAnimate = itemsToCollapse.Select(item => new ExpandQueueEntry { id = item.id, expand = false }) - .Append(new ExpandQueueEntry { id = targetItem.id, expand = true }) - .OrderBy(r => GetRowIndex(r.id)).ToList(); - - - window.Repaint(); - - } - - - - - - public void StartExpandAnimation(List targetExpandedIds) - { - - var toExpand = targetExpandedIds.Except(expandedIds).ToHashSet(); - var toCollapse = expandedIds.Except(targetExpandedIds).ToHashSet(); - - - - // hanlde non-animated expansions/collapses - - bool hasParentToCollapse(int id) - { - var o = Resources.InstanceIDToObject(id); - - if (!o) return false; - - - var assetPath = AssetDatabase.GetAssetPath(o); - - if (!assetPath.HasParentPath()) return false; - if (assetPath == "Assets") return false; - - - var parentAsset = AssetDatabase.LoadAssetAtPath(assetPath.GetParentPath()); - - if (!parentAsset) return false; // packages item - - - var parentId = parentAsset.GetInstanceID(); - - return toCollapse.Contains(parentId) - || hasParentToCollapse(parentId); - - } - bool areAllParentsExpanded(int id) - { - var o = Resources.InstanceIDToObject(id); - - if (!o) return true; - - - var assetPath = AssetDatabase.GetAssetPath(o); - - if (!assetPath.HasParentPath()) return true; - if (assetPath == "Assets") return true; - - - var parentAsset = AssetDatabase.LoadAssetAtPath(assetPath.GetParentPath()); - - if (!parentAsset) return true; // packages item - - - var parentId = parentAsset.GetInstanceID(); - - return expandedIds.Contains(parentId) - && areAllParentsExpanded(parentId); - - } - - var toExpand_beforeAnimation = toExpand.Where(id => !areAllParentsExpanded(id)).ToHashSet(); - var toCollapse_afterAnimation = toCollapse.Where(id => hasParentToCollapse(id)).ToHashSet(); - - - foreach (var id in toExpand_beforeAnimation) - SetExpanded_withoutAnimation(id, true); - - foreach (var id in toCollapse_afterAnimation) - expandQueue_toCollapseAfterAnimation.Add(id); - - - toExpand.ExceptWith(toExpand_beforeAnimation); - toCollapse.ExceptWith(toCollapse_afterAnimation); - - - - - // setup animation - - expandQueue_toAnimate = toCollapse.Select(id => new ExpandQueueEntry { id = id, expand = false }) - .Concat(toExpand.Select(id => new ExpandQueueEntry { id = id, expand = true })) - .OrderBy(r => GetRowIndex(r.id)).ToList(); - - } - - public void SetExpandedIds(List targetExpandedIds) - { - treeViewControllerData.InvokeMethod("SetExpandedIDs", targetExpandedIds.ToArray()); - } - public void SetExpanded_withAnimation(int instanceId, bool expanded) - { - treeViewController.InvokeMethod("ChangeFoldingForSingleItem", instanceId, expanded); - } - public void SetExpanded_withoutAnimation(int instanceId, bool expanded) - { - treeViewControllerData.InvokeMethod("SetExpanded", instanceId, expanded); - } - - - - public void StartScrollAnimation(float targetScrollPos) - { - if (targetScrollPos.DistanceTo(currentScrollPos) < .05f) return; - - this.targetScrollPos = targetScrollPos; - - animatingScroll = true; - - } - - public void SetScrollPos(float targetScrollPos) - { - treeViewController.GetPropertyValue("state").scrollPos = Vector2.up * targetScrollPos; - } - - - - - public void RevealFolder(string path, bool expand, bool highlight, bool snapToTopMargin) - { - - int getId(string path) => AssetDatabase.LoadAssetAtPath(path).GetInstanceID(); - - - var idsToExpand = new List(); - - if (expand) - idsToExpand.Add(getId(path)); - - var cur = path; - while (!(cur = cur.GetParentPath()).IsNullOrEmpty()) - idsToExpand.Add(getId(cur)); - - idsToExpand.RemoveAll(r => expandedIds.Contains(r)); - - - - - foreach (var id in idsToExpand.SkipLast(1)) - SetExpanded_withoutAnimation(id, true); - - if (idsToExpand.Any()) - SetExpanded_withAnimation(idsToExpand.Last(), true); - - - - - var rowCount = treeViewControllerData.GetMemberValue("m_Rows").Count; - var maxScrollPos = rowCount * 16 - window.position.height + (isOneColumn ? 49.9f : 45.9f); - - var rowIndex = treeViewControllerData.InvokeMethod("GetRow", getId(path)); - var rowPos = rowIndex * 16f + (isOneColumn ? 11 : 23); - - var scrollAreaHeight = window.GetMemberValue("m_TreeViewRect").height; - - - - - var margin = 48; - - var targetScrollPos = 0f; - - if (snapToTopMargin) - targetScrollPos = (rowPos - margin).Min(maxScrollPos) - .Max(0); - else - targetScrollPos = currentScrollPos.Min(rowPos - margin) - .Max(rowPos - scrollAreaHeight + margin) - .Min(maxScrollPos) - .Max(0); - if (targetScrollPos < 25) - targetScrollPos = 0; - - StartScrollAnimation(targetScrollPos); - - - - - - if (!highlight) return; - - highlightAmount = 2.2f; - - animatingHighlight = true; - - folderToHighlight = path; - - - } - - public void OpenFolder(string path) - { - // update search - window.GetMemberValue("m_SearchFilter").InvokeMethod("ClearSearch"); - window.GetMemberValue("m_SearchFilter").SetMemberValue("folders", new[] { path }); - - - // update folder tree - window.GetMemberValue("m_FolderTree").InvokeMethod("SetSelection", new[] { AssetDatabase.LoadAssetAtPath(path).GetInstanceID() }, false); - - - // update list area - var listAreaRect = window.GetMemberValue("m_ListAreaRect"); - var searchFilter = window.GetMemberValue("m_SearchFilter"); - var checkThumbnails = false; - var assetToInstanceId = (System.Func)((s) => typeof(AssetDatabase).InvokeMethod("GetMainAssetInstanceID", s)); - - window.GetMemberValue("m_ListArea")?.InvokeMethod("InitForSearch", listAreaRect, HierarchyType.Assets, searchFilter, checkThumbnails, assetToInstanceId); - - - // updat breadcrumbs - window.GetMemberValue("m_BreadCrumbs").Clear(); - - - - // pretty much the same as ProjectBrowser.ShowFolderContents() - // but without m_FolderTree.SetSelection() - - } - - - - - - - - - - - - - public VFoldersController(EditorWindow window) => this.window = window; - - public EditorWindow window; - - public VFoldersGUI gui => VFolders.guis_byWindow[window]; - - } -} -#endif \ No newline at end of file diff --git a/Assets/Plugins/vFolders/VFoldersController.cs.meta b/Assets/Plugins/vFolders/VFoldersController.cs.meta deleted file mode 100644 index 290180f45..000000000 --- a/Assets/Plugins/vFolders/VFoldersController.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 380edf2cfb553464d9f7ec73602e93d1 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Plugins/vFolders/VFoldersData.cs b/Assets/Plugins/vFolders/VFoldersData.cs deleted file mode 100644 index 630bf5cc6..000000000 --- a/Assets/Plugins/vFolders/VFoldersData.cs +++ /dev/null @@ -1,145 +0,0 @@ -#if UNITY_EDITOR -using System.Collections; -using System.Collections.Generic; -using UnityEngine; -using UnityEngine.Serialization; -using UnityEditor; -using UnityEditor.ShortcutManagement; -using System.Reflection; -using System.Linq; -using UnityEngine.UIElements; -using UnityEngine.SceneManagement; -using UnityEditor.SceneManagement; -using static VFolders.Libs.VUtils; -using static VFolders.Libs.VGUI; -// using static VTools.VDebug; - - -namespace VFolders -{ - public class VFoldersData : ScriptableObject, ISerializationCallbackReceiver - { - - public SerializableDictionary folderDatas_byGuid = new(); - - [System.Serializable] - public class FolderData - { - public string iconNameOrGuid = ""; - public int colorIndex = 0; - - public bool isIconRecursive; - public bool isColorRecursive; - - } - - public void OnBeforeSerialize() => VFolders.OnDataSerialization(); - public void OnAfterDeserialize() { } - - - - - public List bookmarks = new(); - - [System.Serializable] - public class Bookmark - { - - public string name => isDeleted ? "Deleted" : guid.ToPath().GetFilename(); - - - public bool isDeleted => !AssetDatabase.IsValidFolder(guid.ToPath()); - - - - public Bookmark(Object o) => guid = o.GetGuid(); - - public string guid; - - } - - - - - - - - - [CustomEditor(typeof(VFoldersData))] - class Editor : UnityEditor.Editor - { - public override void OnInspectorGUI() - { - var style = new GUIStyle(EditorStyles.label) { wordWrap = true }; - - void normal() - { - if (storeDataInMetaFiles) return; - - SetGUIEnabled(false); - BeginIndent(0); - - Space(10); - EditorGUILayout.LabelField("This file stores data about which icons and colors are assigned to folders, along with bookmarks from navigation bar.", style); - - Space(6); - GUILayout.Label("If there are multiple people working on the project, it's better to store icon and color data in .meta files of folders to avoid merge conflicts. To do that, click the ⋮ button at the top right corner and enable Team Mode.", style); - - EndIndent(10); - ResetGUIEnabled(); - } - void meta() - { - if (!storeDataInMetaFiles) return; - - SetGUIEnabled(false); - BeginIndent(0); - - Space(10); - EditorGUILayout.LabelField("Icon and color data is currently stored in folders .meta files of folders, and this file only contains bookmarks from navigation bar.", style); - - Space(6); - GUILayout.Label("If you want all data to be stored in this file, click the ⋮ button at the top right corner and disable Team Mode.", style); - - EndIndent(10); - ResetGUIEnabled(); - } - - normal(); - meta(); - - } - } - - public static bool storeDataInMetaFiles { get => EditorPrefsCached.GetBool("vFolders-teamModeEnabled", false); set => EditorPrefsCached.SetBool("vFolders-teamModeEnabled", value); } - - - - [ContextMenu("Enable Team Mode", isValidateFunction: false, priority: 1)] - public void EnableTeamMode() - { - var option = EditorUtility.DisplayDialogComplex("Licensing notice", - "To use vFolders 2 within a team, licenses must be purchased for each individual user as per the Asset Store EULA.\n\n Sharing one license across the team is illegal and considered piracy.", - "Acknowledge", - "Cancel", - "Purchase more seats"); - if (option == 0) - storeDataInMetaFiles = true; - - if (option == 2) - Application.OpenURL("https://prf.hn/click/camref:1100lGLBn/pubref:teammode/destination:https://assetstore.unity.com/packages/tools/utilities/vfolders-2-255470"); - // Application.OpenURL("https://assetstore.unity.com/packages/slug/255470"); - - } - - [ContextMenu("Disable Team Mode", isValidateFunction: false, priority: 2)] - public void DisableTeamMode() => storeDataInMetaFiles = false; - - [ContextMenu("Enable Team Mode", isValidateFunction: true, priority: 1)] bool asd() => !storeDataInMetaFiles; - [ContextMenu("Disable Team Mode", isValidateFunction: true, priority: 2)] bool ads() => storeDataInMetaFiles; - - - - } -} -#endif \ No newline at end of file diff --git a/Assets/Plugins/vFolders/VFoldersData.cs.meta b/Assets/Plugins/vFolders/VFoldersData.cs.meta deleted file mode 100644 index 30bf11c43..000000000 --- a/Assets/Plugins/vFolders/VFoldersData.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: adb9c12a8c6c949f7af83a3d238359d0 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Plugins/vFolders/VFoldersGUI.cs b/Assets/Plugins/vFolders/VFoldersGUI.cs deleted file mode 100644 index 51333d7e5..000000000 --- a/Assets/Plugins/vFolders/VFoldersGUI.cs +++ /dev/null @@ -1,1278 +0,0 @@ -#if UNITY_EDITOR -using System.Collections; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Reflection; -using UnityEngine; -using UnityEditor; -using UnityEditor.ShortcutManagement; -using UnityEngine.UIElements; -using UnityEngine.SceneManagement; -using UnityEditor.SceneManagement; -using UnityEditor.IMGUI.Controls; -using Type = System.Type; -using static VFolders.Libs.VUtils; -using static VFolders.Libs.VGUI; -// using static VTools.VDebug; -using static VFolders.VFolders; -using static VFolders.VFoldersData; -using static VFolders.VFoldersCache; - - - -namespace VFolders -{ - public class VFoldersGUI - { - - public void RowGUI(Rect rowRect, string guid, int instanceId) - { - var fullRowRect = rowRect.AddWidthFromRight(rowRect.x); - - var isRowHovered = fullRowRect.IsHovered(); - - var isListArea = rowRect.x == 14; - - var isFolder = AssetDatabase.IsValidFolder(guid.ToPath()); - var isAsset = !isFolder && !guid.IsNullOrEmpty(); - var isFavorite = !isFolder && !isAsset && rowRect.x != 16; - - var isFavoritesRoot = rowRect.x == 16 && !isFolder && rowRect.y == 0; - var isAssetsRoot = rowRect.x == 16 && isFolder && guid.ToPath() == "Assets"; - var isPackagesRoot = rowRect.x == 16 && !isFavoritesRoot && !isAssetsRoot && guid.IsNullOrEmpty(); - - var useMinimalMode = VFoldersMenu.minimalModeEnabled && !isListArea; - var useBackgroundColors = (VFoldersMenu.backgroundColorsEnabled || useMinimalMode) && !isListArea; - var useHierarchyLines = VFoldersMenu.hierarchyLinesEnabled && !isListArea; - var useContentMinimap = VFoldersMenu.contentMinimapEnabled; - var useZebraStriping = VFoldersMenu.zebraStripingEnabled; - - - - TreeViewItem treeItem = null; - - var isRowSelected = false; - var isRowBeingRenamed = false; - - void setObjects() - { - if (isListArea) return; - - if (!curEvent.isRepaint) // only needed for drawing, - if (!curEvent.isMouseUp) // altClick, - if (!isRowHovered) // and setting last hovered tree item - return; - - - void set_treeItem_byRect() - { - if (treeViewAnimatesExpansion) return; - - var offest = isTwoColumns ? -15 : -4; - - - if ((rowRect.y + offest) % 16 != 0) return; - - var rowIndex = ((rowRect.y + offest) / 16).ToInt(); - - - if (rowIndex < 0 || rowIndex >= rows.Count) return; - if (rows == null) return; - - treeItem = rows[rowIndex]; - - } - void set_treeItem_byInstanceId() - { - if (treeItem != null) return; - if (isFavorite || isFavoritesRoot) return; - - treeItem = treeViewController?.InvokeMethod("FindItem", instanceId); - - } - - set_treeItem_byRect(); - set_treeItem_byInstanceId(); - - } - void setState() - { - void set_isRowSelected_oneColumn() - { - if (!curEvent.isRepaint) return; - if (isListArea) return; - if (treeItem == null) return; - if (isTwoColumns) return; - - - var dragging = treeView_dragSelectionList?.Any() == true; - - isRowSelected = dragging ? (treeView_dragSelectionList.Contains(treeItem.id)) : Selection.Contains(treeItem.id); - - } - void set_isRowSelected_twoColumns() - { - if (!curEvent.isRepaint) return; - if (isListArea) return; - if (treeItem == null) return; - if (!isTwoColumns) return; - - - var dragging = treeView_dragSelectionList != null - && treeView_dragSelectionList.Any(); - - isRowSelected = dragging ? (treeView_dragSelectionList.Contains(treeItem.id)) : treeView_normalSelectionList != null && treeView_normalSelectionList.Contains(treeItem.id); - - } - void set_lastHovered() - { - if (isListArea) return; - if (!isRowHovered) return; - - lastHoveredRowRect_screenSpace = EditorGUIUtility.GUIToScreenRect(fullRowRect); - lastHoveredTreeItem = treeItem; - - } - void set_lastKnownMousePosition() - { - if (!curEvent.isRepaint) return; - - lastKnownMousePosition_screenSpace = curEvent.mousePosition_screenSpace; - - } - - set_isRowSelected_oneColumn(); - set_isRowSelected_twoColumns(); - set_lastHovered(); - set_lastKnownMousePosition(); - - isRowBeingRenamed = renamingRow && isRowSelected; - - } - - void drawing() - { - if (!curEvent.isRepaint) { hierarchyLines_isFirstRowDrawn = false; return; } - - - - var folderInfo = GetFolderInfo(guid); - - var rowHasColor = useBackgroundColors && folderInfo.hasColor; - - var rowHasCustomIcon = !isFolder ? false - : useBackgroundColors ? folderInfo.hasIcon - : folderInfo.hasIcon || folderInfo.hasColor; - var rowHasIcon = !useMinimalMode ? true - : rowHasCustomIcon || isAsset || isFavorite || isRowBeingRenamed; - - - var hideName = rowHasColor || !rowHasIcon; - var hideDefaultIcon = rowHasCustomIcon || !rowHasIcon; - - var drawTriangle = rowHasColor && treeItem?.hasChildren == true; - var drawName = rowHasColor || !rowHasIcon; - var drawDefaultIcon = (rowHasColor && !rowHasCustomIcon) && rowHasIcon; - - var makeTriangleBrighter = rowHasColor && isDarkTheme; - var makeNameBrighter = rowHasColor && isDarkTheme; - var makeIconBrighter = rowHasColor && isFolder; - - - - var defaultBackground = isListArea ? Greyscale(isDarkTheme ? .2f : .75f) - : GUIColors.windowBackground; - if (isRowSelected) - if (!isRowBeingRenamed) - defaultBackground = isTreeFocused ? GUIColors.selectedBackground - : Greyscale(isDarkTheme ? .3f : .68f); - - - - void hideName_() - { - if (!hideName) return; - if (isFavorite) return; - - var name = isListArea ? guid.ToPath().GetFilename() : treeItem != null ? treeItem.displayName : "Favorites"; - - var nameRect = rowRect.SetWidth(name.GetLabelWidth() + 3).MoveX(16).MoveX(isListArea ? 3 : 0); - - nameRect.Draw(defaultBackground); - - } - void hideDefaultIcon_() - { - if (!hideDefaultIcon) return; - - var iconRect = rowRect.SetWidth(16).MoveX(isListArea ? 3 : 0); - - - if (isListArea) - { - SetGUIColor(defaultBackground); - - GUI.DrawTexture(iconRect, EditorIcons.GetIcon("Folder On Icon")); - - ResetGUIColor(); - - } - else - iconRect.Draw(defaultBackground); - - } - - void color() - { - if (!rowHasColor) return; - - - - var color = (isDarkTheme ? Color.Lerp(folderInfo.color, Greyscale(.05f), .42f) - : Color.Lerp(folderInfo.color, Greyscale(.8f), .5f)).SetAlpha(1); - if (isRowHovered) - color *= isDarkTheme ? 1.1f : .92f; - - if (isRowSelected) - color *= isDarkTheme ? 1.2f : .8f; - - if (palette?.colorGradientsEnabled == false) - color = MathUtil.Lerp(color, Greyscale(.2f), isDarkTheme ? .25f : .03f); - - if (folderInfo.hasColorByRecursion) - color = MathUtil.Lerp(color, Greyscale(isDarkTheme ? .24f : .8f), .45f); - - - - - - - var colorRect = rowRect.AddWidthFromRight(30).AddWidth(16); - - if (folderInfo.hasColorByRecursion) - colorRect = colorRect.AddWidthFromRight(folderInfo.maxColorRecursionDepth * 14); - - if (!isRowSelected && !folderInfo.hasColorByRecursion) - colorRect = colorRect.AddHeightFromMid(EditorGUIUtility.pixelsPerPoint >= 2 ? -.5f : -1); - - if (folderInfo.hasColorByRecursion) - colorRect = colorRect.MoveY(EditorGUIUtility.pixelsPerPoint >= 2 ? -.25f : -.5f); - - if (palette?.colorGradientsEnabled == false) { colorRect.Draw(color); return; } - - - var hasLeftGradient = colorRect.x > 4; - - if (hasLeftGradient) - colorRect = colorRect.AddWidthFromRight(3); - - - - var leftGradientWith = hasLeftGradient ? 22 : 0; - var rightGradientWidth = (fullRowRect.width * .77f).Min(colorRect.width - leftGradientWith); - - var leftGradientRect = colorRect.SetWidth(leftGradientWith); - var rightGradientRect = colorRect.SetWidthFromRight(rightGradientWidth); - - var flatColorRect = colorRect.SetX(leftGradientRect.xMax).SetXMax(rightGradientRect.x); - - - - - - - leftGradientRect.AddWidth(1).DrawCurtainLeft(color); - - flatColorRect.AddWidth(1).Draw(color); - - rightGradientRect.Draw(color.MultiplyAlpha(.1f)); - rightGradientRect.DrawCurtainRight(color); - - - } - void triangle() - { - if (!drawTriangle) return; - - - var triangleRect = rowRect.MoveX(-15).SetWidth(16).Resize(-1); - - GUI.Label(triangleRect, EditorGUIUtility.IconContent(expandedIds.Contains(treeItem.id) ? "IN_foldout_on" : "IN_foldout")); - - - if (!makeTriangleBrighter) return; - - GUI.Label(triangleRect, EditorGUIUtility.IconContent(expandedIds.Contains(treeItem.id) ? "IN_foldout_on" : "IN_foldout")); - - } - void name() - { - if (!drawName) return; - if (isRowBeingRenamed) return; - - - var nameRect = rowRect.MoveX(18).AddHeight(1); ; - - if (isListArea) - nameRect = nameRect.MoveX(3); - - if (!rowHasIcon) - nameRect = nameRect.MoveX(-17); - - if (makeNameBrighter) - nameRect = nameRect.MoveX(-2).MoveY(-.5f); - - - - var styleName = makeNameBrighter ? "WhiteLabel" : "TV Line"; - - if (isFavoritesRoot || isAssetsRoot || isPackagesRoot) - styleName = "BoldLabel"; - - - - var name = isFavoritesRoot ? "Favorites" : - isPackagesRoot ? "Packages" : - isListArea || treeItem == null ? guid.ToPath().GetFilename() : - treeItem.displayName; - - - - if (makeNameBrighter) - SetGUIColor(Greyscale(isRowSelected ? 1 : .93f)); - - GUI.skin.GetStyle(styleName).Draw(nameRect, name, false, false, isRowSelected, isTreeFocused && styleName != "BoldLabel"); - - if (makeNameBrighter) - ResetGUIColor(); - - } - void defaultIcon() - { - if (!drawDefaultIcon) return; - - - var iconRect = rowRect.SetWidth(16).MoveX(isListArea ? 3 : 0); - - var icon = isAsset ? AssetDatabase.GetCachedIcon(guid.ToPath()) - : makeIconBrighter ? EditorIcons.GetIcon(folderInfo.folderState.isEmpty ? "FolderEmpty On Icon" : "Folder On Icon") - : EditorIcons.GetIcon(folderInfo.folderState.isEmpty ? "FolderEmpty Icon" : "Folder Icon"); - - - SetLabelAlignmentCenter(); - - if (makeIconBrighter) - SetGUIColor(Greyscale(.88f)); - - GUI.DrawTexture(iconRect, icon); - - if (makeIconBrighter) - ResetGUIColor(); - - ResetLabelStyle(); - - } - void customIcon() - { - if (!rowHasCustomIcon) return; - - - var icon = GetSmallFolderIcon(folderInfo, removeColor: useBackgroundColors); - - if (useMinimalMode && folderInfo.hasIcon) - icon = EditorIcons.GetIcon(folderInfo.iconNameOrPath); - - if (!icon) return; - - - var iconRect = rowRect.SetWidth(16).MoveX(isListArea ? 3 : 0); - - iconRect = iconRect.SetWidth(iconRect.height / icon.height * icon.width); - - - GUI.DrawTexture(iconRect, icon); - - } - - void hierarchyLines() - { - if (!useHierarchyLines) return; - if (isListArea) return; - if (treeItem == null) return; - - - var lineThickness = 1f; - var lineColor = isDarkTheme ? Greyscale(1, .165f) : Greyscale(0, .23f); - - var depth = ((rowRect.x - 16) / 14).RoundToInt(); - - bool isLastChild(TreeViewItem item) => item.parent?.children?.LastOrDefault() == item; - bool hasChilren(TreeViewItem item) => item.children != null && item.children.Count > 0; - - void calcVerticalGaps_beforeFirstRowDrawn() - { - if (hierarchyLines_isFirstRowDrawn) return; - - hierarchyLines_verticalGaps.Clear(); - - var curItem = treeItem.parent; - var curDepth = depth - 1; - - while (curItem != null && curItem.parent != null) - { - if (isLastChild(curItem)) - hierarchyLines_verticalGaps.Add(curDepth - 1); - - curItem = curItem.parent; - curDepth--; - } - - } - void updateVerticalGaps_beforeNextRowDrawn() - { - if (isLastChild(treeItem)) - hierarchyLines_verticalGaps.Add(depth - 1); - - if (depth < hierarchyLines_prevRowDepth) - hierarchyLines_verticalGaps.RemoveAll(r => r >= depth); - - } - - void drawVerticals() - { - for (int i = 1; i < depth; i++) - if (!hierarchyLines_verticalGaps.Contains(i)) - rowRect.SetX(9 + i * 14 - lineThickness / 2) - .SetWidth(lineThickness) - .SetHeight(isLastChild(treeItem) && i == depth - 1 ? 8 + lineThickness / 2 : 16) - .Draw(lineColor); - - } - void drawHorizontals() - { - if (depth == 0) return; - if (depth == 1) return; - - rowRect.MoveX(-21) - .SetHeightFromMid(lineThickness) - .SetWidth(hasChilren(treeItem) ? 7 : 17) - .AddWidthFromRight(-lineThickness / 2f) - .Draw(lineColor); - - } - - - - calcVerticalGaps_beforeFirstRowDrawn(); - - drawVerticals(); - drawHorizontals(); - - updateVerticalGaps_beforeNextRowDrawn(); - - hierarchyLines_prevRowDepth = depth; - hierarchyLines_isFirstRowDrawn = true; - - } - void zebraStriping_() - { - if (!useZebraStriping) return; - - - var contrast = isDarkTheme ? .033f : .05f; - - - var firstRowY = isOneColumn ? 4 : -1; - - var t = 1 - (rowRect.y - firstRowY).PingPong(16f) / 16f; - - if (isRowHovered || isRowSelected) - if (!VFoldersPaletteWindow.instance || VFoldersPaletteWindow.instance.guids.Contains(guid)) - t = 1; - - if (t.Approx(0)) return; - - - - fullRowRect.Draw(Greyscale(isDarkTheme ? 1 : 0, contrast * t)); - - - } - void highlight_() - { - if (!controller.animatingHighlight) return; - if (guid.ToPath() != controller.folderToHighlight) return; - - - var highlightBrightness = isDarkTheme ? .16f : .35f; - - - var highlightAmount = controller.highlightAmount.Clamp01(); - - highlightAmount = highlightAmount * highlightAmount * (3 - 2 * highlightAmount); - - - fullRowRect.AddWidthFromRight(123).Draw(Greyscale(1, highlightBrightness * highlightAmount)); - - } - void hoverHighlight() - { - if (!VFoldersPaletteWindow.instance) - if (!rowRect.IsHovered()) return; - - if (VFoldersPaletteWindow.instance) - if (VFoldersPaletteWindow.instance.guids.Count > 1 || VFoldersPaletteWindow.instance.guids.First() != guid || !paletteOpenedOnRow) return; - - - fullRowRect.Draw(Greyscale(isDarkTheme ? 1 : 0, .06f)); - - } - - void contentMinimap() - { - if (!isFolder) return; - if (!useContentMinimap) return; - if (guid.IsNullOrEmpty()) return; - - void icon(Rect rect, string name) - { - var icon = EditorIcons.GetIcon(name); - - if (!icon) return; - - - SetGUIColor(Greyscale(1, isDarkTheme ? .5f : .7f)); - - GUI.DrawTexture(rect, icon); - - ResetGUIColor(); - - } - - - var iconDistance = 13; - var minButtonX = rowRect.x + guid.ToPath().GetFilename().GetLabelWidth() + iconDistance + 2; - var iconRect = fullRowRect.SetWidthFromRight(iconDistance).SetSizeFromMid(12, 12).MoveX(-1.5f); - - foreach (var iconName in folderInfo.folderState.contentMinimapIconNames) - { - if (iconRect.x < minButtonX) continue; - - icon(iconRect, iconName); - - iconRect = iconRect.MoveX(-iconDistance); - - } - - } - - - - fullRowRect.MarkInteractive(); - - hideName_(); - hideDefaultIcon_(); - - color(); - triangle(); - defaultIcon(); - customIcon(); - name(); - - hierarchyLines(); - zebraStriping_(); - highlight_(); - hoverHighlight(); - - contentMinimap(); - - } - - void altDrag() - { - if (!curEvent.holdingAlt) return; - - void mouseDown() - { - if (!curEvent.isMouseDown) return; - if (!isRowHovered) return; - - mouseDownPos = curEvent.mousePosition; - - } - void mouseDrag() - { - if (!curEvent.isMouseDrag) return; - if ((curEvent.mousePosition - mouseDownPos).magnitude < 5) return; - if (!rowRect.Contains(mouseDownPos)) return; - if (!rowRect.Contains(curEvent.mousePosition - curEvent.mouseDelta)) return; - if (DragAndDrop.objectReferences.Any()) return; - - DragAndDrop.PrepareStartDrag(); - DragAndDrop.objectReferences = new[] { AssetDatabase.LoadAssetAtPath(guid.ToPath()) }; - DragAndDrop.StartDrag(guid.ToPath().GetFilename()); - - } - - mouseDown(); - mouseDrag(); - - // altdrag has to be set up manually before altClick - // because altClick will use() mouseDown event to prevent selection change - - } - void altClick() - { - if (!isRowHovered) return; - if (!curEvent.holdingAlt) return; - if (!isFolder) return; - - void mouseDown() - { - if (!curEvent.isMouseDown) return; - - curEvent.Use(); - - } - void mouseUp() - { - if (!curEvent.isMouseUp) return; - - var selectedGuids = isListArea - ? - Selection.objects.Where(r => r is DefaultAsset).Select(r => r.GetPath().ToGuid()) - : -#if UNITY_2021_1_OR_NEWER - treeViewController.GetFieldValue("m_CachedSelection").GetFieldValue>("m_List") -#else - treeViewController?.GetMemberValue("state").GetMemberValue>("selectedIDs") -#endif - .Select(id => treeViewController.InvokeMethod("FindItem", id)) - .Where(r => r?.GetType().Name == "FolderTreeItem") - .Select(r => r.GetPropertyValue("Guid")) - .Where(r => r != null); - - - var editMultiSelection = selectedGuids.Count() > 1 && selectedGuids.Contains(guid); - - var guidsToEdit = (editMultiSelection ? selectedGuids.Where(r => AssetDatabase.IsValidFolder(r.ToPath())) : new[] { guid }).ToList(); - - - if (VFoldersPaletteWindow.instance && VFoldersPaletteWindow.instance.guids.SequenceEqual(guidsToEdit)) { VFoldersPaletteWindow.instance.Close(); return; } - - var openNearRect = rowRect; - var position = EditorGUIUtility.GUIToScreenPoint(new Vector2(curEvent.mousePosition.x + 20, openNearRect.y - 13)); - - if (!VFoldersPaletteWindow.instance) - VFoldersPaletteWindow.CreateInstance(position); - - VFoldersPaletteWindow.instance.Init(guidsToEdit); - VFoldersPaletteWindow.instance.Focus(); - - VFoldersPaletteWindow.instance.targetPosition = position; - - paletteOpenedOnRow = true; - paletteOpenedOnCell = false; - - if (editMultiSelection) - Selection.objects = null; - } - - mouseDown(); - mouseUp(); - - } - - - - setObjects(); - setState(); - - drawing(); - - altDrag(); - altClick(); - - } - - List hierarchyLines_verticalGaps = new(); - bool hierarchyLines_isFirstRowDrawn; - int hierarchyLines_prevRowDepth; - - Vector2 mouseDownPos; - - bool paletteOpenedOnRow; - - - - - public void CellGUI(Rect cellRect, string guid, int instanceId) - { - var isFolder = AssetDatabase.IsValidFolder(guid.ToPath()); - - void setLastVisibleSelectedForAltClick() - { - if (!isFolder) return; - if (!curEvent.isRepaint) return; - if (!Selection.objects.Contains(AssetDatabase.LoadAssetAtPath(guid.ToPath()))) return; - - lastVisibleSelectedCellRect = cellRect; - - } - - void drawing() - { - if (!curEvent.isRepaint) { namesDrawnForGuids.Clear(); return; } - - var folderInfo = isFolder ? GetFolderInfo(guid) : null; - var showingSecondNameLine = false; - - void hideIcon() - { - if (!isFolder) return; - if (!folderInfo.hasColor) return; - - cellRect.SetHeight(cellRect.width).Resize(4).Draw(EditorGUIUtility.isProSkin ? Greyscale(.2f) : Greyscale(.75f)); - - } - void icon() - { - if (!isFolder) return; - if (!folderInfo.hasColor && !folderInfo.hasIcon) return; - - DrawBigFolderIcon(cellRect, folderInfo); - - } - void twoLineName() - { - if (namesDrawnForGuids.Contains(guid)) return; // disables two-line names on subassets - if (!VFoldersMenu.twoLineNamesEnabled) return; - - - var isSelected = listArea_dragSelectionList.Any() ? listArea_dragSelectionList.Contains(instanceId) : Selection.instanceIDs.Contains(instanceId); - - var isCellBeingRenamed = isSelected && renamingCell; - - if (isCellBeingRenamed) return; - - - - var maxLineWidth = cellRect.width + 14; - - var name = guid.ToPath().GetFilename(withExtension: false); // Resources.InstanceIDToObject(instanceId).name; - - - string firstLine = null; - string secondLine = null; - - Rect firstLineRect = default; - Rect secondLineRect = default; - - - void getCachedLines() - { - if (twoLineNamesCachedForCellWidth != cellRect.width) - twoLineNamesCache.Clear(); - - if (!twoLineNamesCache.ContainsKey(name)) return; - - - firstLine = twoLineNamesCache[name].Item1; - secondLine = twoLineNamesCache[name].Item2; - - } - void calcLines() - { - if (twoLineNamesCache.ContainsKey(name)) return; - if (name.GetLabelWidth() < maxLineWidth) - { - firstLine = name; - - twoLineNamesCache[name] = (firstLine, secondLine); - twoLineNamesCachedForCellWidth = cellRect.width; - - return; - - } - - - var separators = new[] { ' ', '_', '-', '.' }; - - var splitIndexes_separators = Enumerable.Range(1, name.Length - 2).Where(i => separators.Contains(name[i])).Select(i => i + 1); - var splitIndexes_camelcase = Enumerable.Range(2, name.Length - 2).Where(i => name[i].IsUpper() && name[i - 1].IsLower() && !separators.Contains(name[i - 1])); - var splitIndexes_all = Enumerable.Range(1, name.Length - 1); - - bool splitSucceeded = false; - - - string fit(string s, IEnumerable splitIndexes, bool splitToRight, bool addEllipsis = false) - { - foreach (var i in splitToRight ? splitIndexes : splitIndexes.Reverse()) - { - var substring = splitToRight ? s[i..] : s[..i]; - - substring = substring.Trim(); - - if (addEllipsis) - substring += "…"; - - - - if (substring.GetLabelWidth() < maxLineWidth) - return substring; - - } - - return null; - - } - - void truncate() - { - if (splitIndexes_separators.Any()) return; - if (splitIndexes_camelcase.Any()) return; - - firstLine = fit(name, splitIndexes_all, splitToRight: false, addEllipsis: true); - - splitSucceeded = true; - - } - void split_clean() - { - if (splitSucceeded) return; - - - firstLine = null; - firstLine ??= fit(name, splitIndexes_separators, splitToRight: false); - firstLine ??= fit(name, splitIndexes_camelcase, splitToRight: false); - - if (firstLine == null) return; - - - - secondLine = name.Remove(firstLine); - - splitSucceeded = secondLine.GetLabelWidth() < maxLineWidth; - - } - void split_withEllipsis() - { - if (splitSucceeded) return; - - - secondLine = null; - secondLine ??= fit(name, splitIndexes_separators, splitToRight: true); - secondLine ??= fit(name, splitIndexes_camelcase, splitToRight: true); - secondLine ??= fit(name, splitIndexes_all, splitToRight: true); - - - - firstLine = name.Remove(secondLine).Trim(); - - if (firstLine.GetLabelWidth() > maxLineWidth) - firstLine = fit(firstLine, Enumerable.Range(0, firstLine.Length), splitToRight: false, addEllipsis: true); - - } - - - truncate(); - split_clean(); - split_withEllipsis(); - - firstLine = firstLine.Trim(); - secondLine = secondLine?.Trim(); - - twoLineNamesCache[name] = (firstLine, secondLine); - twoLineNamesCachedForCellWidth = cellRect.width; - - } - void calcLineRects() - { - firstLineRect = cellRect.SetHeightFromBottom(12).AddHeight(2).SetWidthFromMid(maxLineWidth).MoveY(-1); - - if (secondLine.IsNullOrEmpty()) return; - - if (isFolder) - firstLineRect = firstLineRect.MoveY(-4); - else - firstLineRect = firstLineRect.MoveY(-1); - - - - secondLineRect = firstLineRect.MoveY(12); - - } - - void hideDefaultName() - { - if (!curEvent.isRepaint) return; - - var defaultNameRect = cellRect.SetHeightFromBottom(16).AddHeight(2).AddWidthFromMid(12); - var maskColor = isDarkTheme ? Greyscale(.2f) : Greyscale(.75f); - - defaultNameRect.Draw(maskColor); - - } - void selectedbackground() - { - if (!isSelected) return; - - - var backgroundColor = isListAreaFocused ? GUIColors.selectedBackground : Greyscale(isDarkTheme ? .3f : .68f); - - - - var longestLine = secondLine?.Length > firstLine.Length ? secondLine : firstLine; - - var backgroundRect = firstLineRect.SetWidthFromMid(longestLine.GetLabelWidth(fontSize: 10) + 2).SetHeightFromMid(14); - - if (!secondLine.IsNullOrEmpty()) - backgroundRect = backgroundRect.SetYMax(secondLineRect.SetHeightFromMid(14).yMax); - - - - backgroundRect.DrawRounded(backgroundColor, 4); - - } - void drawName() - { - SetLabelAlignmentCenter(); - SetLabelFontSize(10); - SetGUIColor(isSelected && isListAreaFocused ? Greyscale(123, 123) : Greyscale(1)); - - GUI.Label(firstLineRect, firstLine); - - if (secondLine != null) - GUI.Label(secondLineRect, secondLine); - - ResetGUIColor(); - ResetLabelStyle(); - - } - - - getCachedLines(); - calcLines(); - calcLineRects(); - - hideDefaultName(); - selectedbackground(); - drawName(); - - showingSecondNameLine = secondLine != null; - - namesDrawnForGuids.Add(guid); - - } - void hoverHighlight() - { - - var highlightColor = isDarkTheme ? Greyscale(1, .058f) : Greyscale(0, .07f); - - - var highlightRect = cellRect.Resize(-2).AddHeight(4).AddWidthFromMid(4); - - if (showingSecondNameLine) - highlightRect = highlightRect.AddHeight(8); - - - - var hoverRect = cellRect.AddWidthFromMid(gridHorizontalSpacing).AddHeight(gridVerticalSpacing); - - hoverRect.MarkInteractive(); - - - - - if (!VFoldersPaletteWindow.instance) - if (!hoverRect.IsHovered()) return; - - if (VFoldersPaletteWindow.instance) - if (!VFoldersPaletteWindow.instance.guids.Contains(guid) || !paletteOpenedOnCell) return; - - - highlightRect.DrawRounded(highlightColor, 5); - - } - - hideIcon(); - icon(); - twoLineName(); - hoverHighlight(); - - } - - void altDrag() - { - if (!isFolder) return; - if (!curEvent.holdingAlt) return; - - void mouseDown() - { - if (!curEvent.isMouseDown) return; - if (!cellRect.IsHovered()) return; - - mouseDownPos = curEvent.mousePosition; - - } - void mouseDrag() - { - if (!curEvent.isMouseDrag) return; - if ((curEvent.mousePosition - mouseDownPos).magnitude < 5) return; - if (!cellRect.Contains(mouseDownPos)) return; - if (!cellRect.Contains(curEvent.mousePosition - curEvent.mouseDelta)) return; - if (DragAndDrop.objectReferences.Any()) return; - - DragAndDrop.PrepareStartDrag(); - DragAndDrop.objectReferences = new[] { AssetDatabase.LoadAssetAtPath(guid.ToPath()) }; - DragAndDrop.StartDrag(guid.ToPath().GetFilename()); - - } - - mouseDown(); - mouseDrag(); - - } - void altClick() - { - if (!isFolder) return; - if (!cellRect.IsHovered()) return; - if (!curEvent.holdingAlt) return; - - void mouseDown() - { - if (!curEvent.isMouseDown) return; - - curEvent.Use(); - - } - void mouseUp() - { - if (!curEvent.isMouseUp) return; - - var selectedFoldersGuids = Selection.objects.Where(r => r is DefaultAsset).Select(r => r.GetPath().ToGuid()); - - var editMultiSelection = selectedFoldersGuids.Count() > 1 && selectedFoldersGuids.Contains(guid); - - var guidsToEdit = (editMultiSelection ? selectedFoldersGuids : new[] { guid }).ToList(); - - - if (VFoldersPaletteWindow.instance && VFoldersPaletteWindow.instance.guids.SequenceEqual(guidsToEdit)) { VFoldersPaletteWindow.instance.Close(); return; } - - var openNearRect = editMultiSelection ? lastVisibleSelectedCellRect : cellRect; - var position = EditorGUIUtility.GUIToScreenPoint(new Vector2(openNearRect.xMax + 10, openNearRect.y - 5)); - - if (!VFoldersPaletteWindow.instance) - VFoldersPaletteWindow.CreateInstance(position); - - VFoldersPaletteWindow.instance.Init(guidsToEdit); - VFoldersPaletteWindow.instance.Focus(); - - VFoldersPaletteWindow.instance.targetPosition = position; - - paletteOpenedOnCell = true; - paletteOpenedOnRow = false; - - if (editMultiSelection) - Selection.objects = null; - } - - mouseDown(); - mouseUp(); - - } - - - setLastVisibleSelectedForAltClick(); - - drawing(); - - altDrag(); - altClick(); - - } - - Rect lastVisibleSelectedCellRect; - - HashSet namesDrawnForGuids = new(); - - Dictionary twoLineNamesCache = new(); - - float twoLineNamesCachedForCellWidth; - - bool paletteOpenedOnCell; - - - - - - - - - - - - public void UpdateState_Layout() - { - isOneColumn = window.GetFieldValue("m_ViewMode") == 0; - - - listArea = isTwoColumns ? window.GetFieldValue("m_ListArea") : null; - - treeViewController = window.GetFieldValue(isTwoColumns ? "m_FolderTree" : "m_AssetTree"); - treeViewControllerData = treeViewController?.GetPropertyValue("data"); - - rows = treeViewControllerData?.InvokeMethod>("GetRows"); - - - var treeViewState = treeViewController?.GetPropertyValue("state"); - - expandedIds = treeViewState?.expandedIDs ?? new List(); - - - - var treeViewAnimator = treeViewController?.GetMemberValue("m_ExpansionAnimator"); - - treeViewAnimatesExpansion = treeViewAnimator?.GetMemberValue("isAnimating") ?? false; - - } - public void UpdateState_Repaint() - { - var treeViewControlID = window.GetFieldValue("m_TreeViewKeyboardControlID"); - var listAreaControlID = window.GetFieldValue("m_ListKeyboardControlID"); - - isTreeFocused = EditorWindow.focusedWindow == window && (GUIUtility.keyboardControl == treeViewControlID || treeViewControlID == 0 || treeViewControlID == -1); - isListAreaFocused = EditorWindow.focusedWindow == window && (GUIUtility.keyboardControl == listAreaControlID || listAreaControlID == 0 || listAreaControlID == -1); - - renamingRow = EditorGUIUtility.editingTextField && treeViewController?.GetMemberValue("state")?.GetMemberValue("renameOverlay")?.InvokeMethod("IsRenaming") == true; - renamingCell = EditorGUIUtility.editingTextField && listArea?.InvokeMethod("GetRenameOverlay")?.InvokeMethod("IsRenaming") == true; - - - - var grid = listArea?.GetMemberValue("m_LocalAssets")?.GetMemberValue("m_Grid"); - - gridHorizontalSpacing = grid?.GetMemberValue("horizontalSpacing") ?? 0; - gridVerticalSpacing = grid?.GetMemberValue("verticalSpacing") ?? 0; - - - - listArea_dragSelectionList = listArea?.GetMemberValue("m_LocalAssets")?.GetMemberValue>("m_DragSelection") ?? new(); - treeView_dragSelectionList = treeViewController?.GetFieldValue("m_DragSelection")?.GetFieldValue>("m_List") ?? new(); - treeView_normalSelectionList = isTwoColumns ? treeViewController?.GetFieldValue("m_CachedSelection")?.GetFieldValue>("m_List") ?? new() : null; - - - // only treeView_normalSelectionList must be updated in repaint, the rest can be moved to UpdateState_Layout - // but they are all grouped here since they are only used for drawing - - } - - bool isOneColumn; - bool isTwoColumns => !isOneColumn; - - bool treeViewAnimatesExpansion; - - public object listArea; - - public object treeViewController; - public object treeViewControllerData; - - public IList rows; - - public List expandedIds = new(); - - bool isTreeFocused; - bool isListAreaFocused; - - bool renamingRow; - bool renamingCell; - - float gridVerticalSpacing; - float gridHorizontalSpacing; - - List listArea_dragSelectionList = new(); - List treeView_dragSelectionList = new(); - List treeView_normalSelectionList = new(); - - - - - - - - - - - - - - public void UpdateFoldersFirst() - { - if (!VFoldersMenu.foldersFirstEnabled) return; - if (Application.platform != RuntimePlatform.OSXEditor) return; - - void oneColumn() - { - if (isTwoColumns) return; - if (foldersFirst_initedForOneColumn) return; - - - var m_AssetTree = window.GetFieldValue("m_AssetTree"); - - if (m_AssetTree == null) return; - - m_AssetTree.GetPropertyValue("data").SetPropertyValue("foldersFirst", true); - m_AssetTree.InvokeMethod("ReloadData"); - - - foldersFirst_initedForOneColumn = true; - foldersFirst_initedForTwoColumns = false; - - } - void twoColumns() - { - if (!isTwoColumns) return; - if (foldersFirst_initedForTwoColumns) return; - - - var m_ListArea = window.GetFieldValue("m_ListArea"); - - if (m_ListArea == null) return; - - m_ListArea.SetPropertyValue("foldersFirst", true); - window.InvokeMethod("InitListArea"); - - - foldersFirst_initedForOneColumn = false; - foldersFirst_initedForTwoColumns = true; - - } - - oneColumn(); - twoColumns(); - - } - - bool foldersFirst_initedForOneColumn; - bool foldersFirst_initedForTwoColumns; - - - - - - - - - - - - - public VFoldersGUI(EditorWindow window) => this.window = window; - - public EditorWindow window; - - public VFoldersController controller => VFolders.controllers_byWindow[window]; - - } -} -#endif diff --git a/Assets/Plugins/vFolders/VFoldersGUI.cs.meta b/Assets/Plugins/vFolders/VFoldersGUI.cs.meta deleted file mode 100644 index f66fff0d3..000000000 --- a/Assets/Plugins/vFolders/VFoldersGUI.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 0743ead56bea942af9c21d27c5c45b62 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Plugins/vFolders/VFoldersHistory.cs b/Assets/Plugins/vFolders/VFoldersHistory.cs deleted file mode 100644 index 2f928fc33..000000000 --- a/Assets/Plugins/vFolders/VFoldersHistory.cs +++ /dev/null @@ -1,403 +0,0 @@ -#if UNITY_EDITOR -using System.Collections; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Reflection; -using UnityEngine; -using UnityEditor; -using UnityEditor.ShortcutManagement; -using UnityEngine.UIElements; -using UnityEngine.SceneManagement; -using UnityEditor.SceneManagement; -using UnityEditor.IMGUI.Controls; -using Type = System.Type; -using static VFolders.Libs.VUtils; -using static VFolders.Libs.VGUI; -// using static VTools.VDebug; -using static VFolders.VFolders; -using static VFolders.VFoldersData; -using static VFolders.VFoldersCache; - - - -namespace VFolders -{ - [System.Serializable] - public class VFoldersHistory - { - - public void CheckTreeStateChange() - { - if (!VFoldersMenu.navigationBarEnabled) return; - if (!isOneColumn) return; - - if (lastTreeState == null) { lastTreeState = new() { scrollPos = currentScrollPos, expandedIds = expandedIds.ToList() }; return; } - - - var curTreeState = new TreeState(); - - var targetScrollPosChanged = false; - var targetExpandedIdsChanged = false; - - - - void set_curState_scrollPos() - { - if (controller.animatingScroll) - curTreeState.scrollPos = controller.targetScrollPos; - else - curTreeState.scrollPos = currentScrollPos; - - } - void set_curState_expandedIds() - { - var expandedIdsHashset = expandedIds.ToHashSet(); - - - - if (treeViewAnimatesExpansion) - if (animatingItemTragetExpanded_fromTreeViewExpandAnimator == true) - expandedIdsHashset.UnionWith(new HashSet() { animatingItemId_fromTreeViewExpandAnimator }); - else - expandedIdsHashset.ExceptWith(new HashSet() { animatingItemId_fromTreeViewExpandAnimator }); - - - - if (controller.animatingExpansion) - { - foreach (var r in controller.expandQueue_toAnimate) - if (r.expand) - expandedIdsHashset.UnionWith(new HashSet() { r.id }); - else - expandedIdsHashset.ExceptWith(new HashSet() { r.id }); - - expandedIdsHashset.ExceptWith(controller.expandQueue_toCollapseAfterAnimation.ToHashSet()); - } - - - curTreeState.expandedIds = expandedIdsHashset.ToList(); - - } - - void checkScrollPosChange() - { - if (framesSinceLastExpansionAnimation < 2) return; - if (framesSinceLastScrollAnimation < 2) return; - - if (curTreeState.scrollPos == lastTreeState.scrollPos) return; - - - - if (EditorApplication.timeSinceStartup - lastScrollTime > 2 || lastTargetStateChangeWasExpandedIds) - targetScrollPosChanged = true; - - lastScrollTime = EditorApplication.timeSinceStartup; - - } - void checkExpandedIdsChange() - { - if (lastTreeState.expandedIds.ToHashSet().SetEquals(curTreeState.expandedIds.ToHashSet())) return; - - targetExpandedIdsChanged = true; - - // lastTargetState.expandedIds.LogAll("lastTargetState"); - // curTargetState.expandedIds.LogAll("curTargetState"); - - } - - void registerStateChange() - { - if (!targetScrollPosChanged && !targetExpandedIdsChanged) return; - - - prevTreeStates.Add(lastTreeState); - nextTreeStates.Clear(); - - lastTargetStateChangeWasExpandedIds = targetExpandedIdsChanged; - - - if (prevTreeStates.Count > 50) - prevTreeStates.RemoveAt(0); - - - // if (targetScrollPosChanged && targetExpandedIdsChanged) - // "expand and scroll".Log(); - // else if (targetScrollPosChanged) - // "scroll".Log(); - // else if (targetExpandedIdsChanged) - // "expand".Log(); - - } - - void updateCountersSinceAnimation() - { - if (controller.animatingExpansion || treeViewAnimatesExpansion) - framesSinceLastExpansionAnimation = 0; - else - framesSinceLastExpansionAnimation++; - - if (controller.animatingScroll || treeViewAnimatesScroll) - framesSinceLastScrollAnimation = 0; - else - framesSinceLastScrollAnimation++; - - } - - - - set_curState_scrollPos(); - set_curState_expandedIds(); - - checkScrollPosChange(); - checkExpandedIdsChange(); - - registerStateChange(); - - updateCountersSinceAnimation(); - - - lastTreeState = curTreeState; - - } - - int framesSinceLastExpansionAnimation; - int framesSinceLastScrollAnimation; - - public double lastScrollTime = 0; - - bool lastTargetStateChangeWasExpandedIds; - - [System.NonSerialized] TreeState lastTreeState = null; - - - - public void CheckFolderPathChange() - { - if (!VFoldersMenu.navigationBarEnabled) return; - if (isOneColumn) return; - - var curFolderPath = window.GetMemberValue("m_SearchFilter").GetMemberValue("folders").FirstOrDefault(); - - if (curFolderPath.IsNullOrEmpty()) return; - - if (lastFolderPath.IsNullOrEmpty()) lastFolderPath = curFolderPath; - if (curFolderPath == lastFolderPath) return; - - - prevFolderPaths.Add(lastFolderPath); - nextFolderPaths.Clear(); - - if (prevFolderPaths.Count > 50) - prevFolderPaths.RemoveAt(0); - - - lastFolderPath = curFolderPath; - - } - - string lastFolderPath = ""; - - - - - - - - public void UpdateState() - { - if (!VFoldersMenu.navigationBarEnabled) return; - - - isOneColumn = window.GetFieldValue("m_ViewMode") == 0; - - var treeViewController = window.GetFieldValue(isOneColumn ? "m_AssetTree" : "m_FolderTree"); - var treeViewControllerData = treeViewController?.GetPropertyValue("data"); - - - - var treeViewControllerState = treeViewController?.GetPropertyValue("state"); - - currentScrollPos = treeViewControllerState?.scrollPos.y ?? 0; - - expandedIds = treeViewControllerState?.expandedIDs ?? new List(); - - - - var treeViewAnimator = treeViewController?.GetMemberValue("m_ExpansionAnimator"); - var treeViewAnimatorSetup = treeViewAnimator?.GetMemberValue("m_Setup"); - - treeViewAnimatesScroll = treeViewController?.GetMemberValue("m_FramingAnimFloat").isAnimating ?? false; - - treeViewAnimatesExpansion = treeViewAnimator?.GetMemberValue("isAnimating") ?? false; - animatingItemTragetExpanded_fromTreeViewExpandAnimator = treeViewAnimatorSetup?.GetMemberValue("expanding") ?? false; - animatingItemId_fromTreeViewExpandAnimator = treeViewAnimatorSetup?.GetMemberValue("item").GetMemberValue("id") ?? 0; - - } - - public bool isOneColumn; - public bool isTwoColumns => !isOneColumn; - - public bool isSearchActive; - - public float currentScrollPos; - - public List expandedIds = new(); - - public bool treeViewAnimatesScroll; - - public bool treeViewAnimatesExpansion; - public bool animatingItemTragetExpanded_fromTreeViewExpandAnimator; - public int animatingItemId_fromTreeViewExpandAnimator; - - - - - - - - - - - - - - - public void MoveBack_OneColumn(bool withAnimation = true) - { - var prevState = prevTreeStates.Last(); - - prevTreeStates.Remove(prevState); - nextTreeStates.Add(lastTreeState); - lastTreeState = prevState; - - - if (withAnimation) - { - controller.StartScrollAnimation(prevState.scrollPos); - controller.StartExpandAnimation(prevState.expandedIds); - } - else - { - controller.SetScrollPos(prevState.scrollPos); - controller.SetExpandedIds(prevState.expandedIds); - } - - } - public void MoveForward_OneColumn(bool withAnimation = true) - { - var nextState = nextTreeStates.Last(); - - nextTreeStates.Remove(nextState); - prevTreeStates.Add(lastTreeState); - lastTreeState = nextState; - - - if (withAnimation) - { - controller.StartScrollAnimation(nextState.scrollPos); - controller.StartExpandAnimation(nextState.expandedIds); - } - else - { - controller.SetScrollPos(nextState.scrollPos); - controller.SetExpandedIds(nextState.expandedIds); - } - - } - - public List prevTreeStates = new(); - public List nextTreeStates = new(); - - - - public void MoveBack_TwoColumns(bool withAnimation = true) - { - var prevPath = prevFolderPaths.Last(); - - prevFolderPaths.RemoveLast(); - nextFolderPaths.Add(lastFolderPath); - lastFolderPath = prevPath; - - - if (withAnimation) - { - controller.RevealFolder(prevPath, expand: false, highlight: false, snapToTopMargin: false); - controller.OpenFolder(prevPath); - } - else - { - window.InvokeMethod("ShowFolderContents", AssetDatabase.LoadAssetAtPath(prevPath).GetInstanceID(), true); - } - - } - public void MoveForward_TwoColumns(bool withAnimation = true) - { - var nextPath = nextFolderPaths.Last(); - - nextFolderPaths.RemoveLast(); - prevFolderPaths.Add(lastFolderPath); - lastFolderPath = nextPath; - - - if (withAnimation) - { - controller.RevealFolder(nextPath, expand: false, highlight: false, snapToTopMargin: false); - controller.OpenFolder(nextPath); - } - else - { - window.InvokeMethod("ShowFolderContents", AssetDatabase.LoadAssetAtPath(nextPath).GetInstanceID(), true); - } - - } - - public List prevFolderPaths = new(); - public List nextFolderPaths = new(); - - - - - - - - - - - - - - [System.Serializable] - public class TreeState - { - public List expandedIds = new(); - - public float scrollPos; - - } - - - - - - - - - public VFoldersHistory(EditorWindow window) => this.window = window; - - EditorWindow window; - - VFoldersGUI gui => VFolders.guis_byWindow[window]; - VFoldersController controller => VFolders.controllers_byWindow[window]; - - } - - - public class VFoldersHistorySingleton : ScriptableSingleton - { - public SerializableDictionary histories_byWindow = new(); - } - - -} -#endif \ No newline at end of file diff --git a/Assets/Plugins/vFolders/VFoldersHistory.cs.meta b/Assets/Plugins/vFolders/VFoldersHistory.cs.meta deleted file mode 100644 index a0fc8da05..000000000 --- a/Assets/Plugins/vFolders/VFoldersHistory.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 2d3e0e15bb2714894bdfb696f7509428 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Plugins/vFolders/VFoldersIconEditor.cs b/Assets/Plugins/vFolders/VFoldersIconEditor.cs deleted file mode 100644 index 028ed4216..000000000 --- a/Assets/Plugins/vFolders/VFoldersIconEditor.cs +++ /dev/null @@ -1,5 +0,0 @@ - -// this file was present in a previus version and is supposed to be deleted now -// but asset store update delivery system doesn't allow deleting files -// so instead this file is now emptied -// feel free to delete it if you want diff --git a/Assets/Plugins/vFolders/VFoldersIconEditor.cs.meta b/Assets/Plugins/vFolders/VFoldersIconEditor.cs.meta deleted file mode 100644 index 759e21270..000000000 --- a/Assets/Plugins/vFolders/VFoldersIconEditor.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: fc2d205dd3ec1446d843e566b05c2eda -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Plugins/vFolders/VFoldersLibs.cs b/Assets/Plugins/vFolders/VFoldersLibs.cs deleted file mode 100644 index 7a44a3b17..000000000 --- a/Assets/Plugins/vFolders/VFoldersLibs.cs +++ /dev/null @@ -1,2667 +0,0 @@ - -#if UNITY_EDITOR -using System.Collections; -using System.Collections.Generic; -using System.IO; -using System.Text; -using System.Text.RegularExpressions; -using System.Reflection; -using System.Linq; -using UnityEngine; -using UnityEngine.Rendering; -using UnityEngine.Experimental.Rendering; -using UnityEditor; -using Type = System.Type; -using static VFolders.Libs.VUtils; -using static VFolders.Libs.VGUI; - - - -namespace VFolders.Libs -{ - public static class VUtils - { - - #region Reflection - - - public static object GetFieldValue(this object o, string fieldName) - { - var type = o as Type ?? o.GetType(); - var target = o is Type ? null : o; - - - if (type.GetFieldInfo(fieldName) is FieldInfo fieldInfo) - return fieldInfo.GetValue(target); - - - throw new System.Exception($"Field '{fieldName}' not found in type '{type.Name}' and its parent types"); - - } - public static object GetPropertyValue(this object o, string propertyName) - { - var type = o as Type ?? o.GetType(); - var target = o is Type ? null : o; - - - if (type.GetPropertyInfo(propertyName) is PropertyInfo propertyInfo) - return propertyInfo.GetValue(target); - - - throw new System.Exception($"Property '{propertyName}' not found in type '{type.Name}' and its parent types"); - - } - public static object GetMemberValue(this object o, string memberName) - { - var type = o as Type ?? o.GetType(); - var target = o is Type ? null : o; - - - if (type.GetFieldInfo(memberName) is FieldInfo fieldInfo) - return fieldInfo.GetValue(target); - - if (type.GetPropertyInfo(memberName) is PropertyInfo propertyInfo) - return propertyInfo.GetValue(target); - - - throw new System.Exception($"Member '{memberName}' not found in type '{type.Name}' and its parent types"); - - } - - public static void SetFieldValue(this object o, string fieldName, object value) - { - var type = o as Type ?? o.GetType(); - var target = o is Type ? null : o; - - - if (type.GetFieldInfo(fieldName) is FieldInfo fieldInfo) - fieldInfo.SetValue(target, value); - - - else throw new System.Exception($"Field '{fieldName}' not found in type '{type.Name}' and its parent types"); - - } - public static void SetPropertyValue(this object o, string propertyName, object value) - { - var type = o as Type ?? o.GetType(); - var target = o is Type ? null : o; - - - if (type.GetPropertyInfo(propertyName) is PropertyInfo propertyInfo) - propertyInfo.SetValue(target, value); - - - else throw new System.Exception($"Property '{propertyName}' not found in type '{type.Name}' and its parent types"); - - } - public static void SetMemberValue(this object o, string memberName, object value) - { - var type = o as Type ?? o.GetType(); - var target = o is Type ? null : o; - - - if (type.GetFieldInfo(memberName) is FieldInfo fieldInfo) - fieldInfo.SetValue(target, value); - - else if (type.GetPropertyInfo(memberName) is PropertyInfo propertyInfo) - propertyInfo.SetValue(target, value); - - - else throw new System.Exception($"Member '{memberName}' not found in type '{type.Name}' and its parent types"); - - } - - public static object InvokeMethod(this object o, string methodName, params object[] parameters) // todo handle null params (can't get their type) - { - var type = o as Type ?? o.GetType(); - var target = o is Type ? null : o; - - - if (type.GetMethodInfo(methodName, parameters.Select(r => r.GetType()).ToArray()) is MethodInfo methodInfo) - return methodInfo.Invoke(target, parameters); - - - throw new System.Exception($"Method '{methodName}' not found in type '{type.Name}', its parent types and interfaces"); - - } - - - public static T GetFieldValue(this object o, string fieldName) => (T)o.GetFieldValue(fieldName); - public static T GetPropertyValue(this object o, string propertyName) => (T)o.GetPropertyValue(propertyName); - public static T GetMemberValue(this object o, string memberName) => (T)o.GetMemberValue(memberName); - public static T InvokeMethod(this object o, string methodName, params object[] parameters) => (T)o.InvokeMethod(methodName, parameters); - - - - - public static FieldInfo GetFieldInfo(this Type type, string fieldName) - { - if (fieldInfoCache.TryGetValue(type, out var fieldInfosByNames)) - if (fieldInfosByNames.TryGetValue(fieldName, out var fieldInfo)) - return fieldInfo; - - - if (!fieldInfoCache.ContainsKey(type)) - fieldInfoCache[type] = new Dictionary(); - - for (var curType = type; curType != null; curType = curType.BaseType) - if (curType.GetField(fieldName, maxBindingFlags) is FieldInfo fieldInfo) - return fieldInfoCache[type][fieldName] = fieldInfo; - - - return fieldInfoCache[type][fieldName] = null; - - } - public static PropertyInfo GetPropertyInfo(this Type type, string propertyName) - { - if (propertyInfoCache.TryGetValue(type, out var propertyInfosByNames)) - if (propertyInfosByNames.TryGetValue(propertyName, out var propertyInfo)) - return propertyInfo; - - - if (!propertyInfoCache.ContainsKey(type)) - propertyInfoCache[type] = new Dictionary(); - - for (var curType = type; curType != null; curType = curType.BaseType) - if (curType.GetProperty(propertyName, maxBindingFlags) is PropertyInfo propertyInfo) - return propertyInfoCache[type][propertyName] = propertyInfo; - - - return propertyInfoCache[type][propertyName] = null; - - } - public static MethodInfo GetMethodInfo(this Type type, string methodName, params Type[] argumentTypes) - { - var methodHash = methodName.GetHashCode() ^ argumentTypes.Aggregate(0, (hash, r) => hash ^= r.GetHashCode()); - - - if (methodInfoCache.TryGetValue(type, out var methodInfosByHashes)) - if (methodInfosByHashes.TryGetValue(methodHash, out var methodInfo)) - return methodInfo; - - - - if (!methodInfoCache.ContainsKey(type)) - methodInfoCache[type] = new Dictionary(); - - for (var curType = type; curType != null; curType = curType.BaseType) - if (curType.GetMethod(methodName, maxBindingFlags, null, argumentTypes, null) is MethodInfo methodInfo) - return methodInfoCache[type][methodHash] = methodInfo; - - foreach (var interfaceType in type.GetInterfaces()) - if (interfaceType.GetMethod(methodName, maxBindingFlags, null, argumentTypes, null) is MethodInfo methodInfo) - return methodInfoCache[type][methodHash] = methodInfo; - - - - return methodInfoCache[type][methodHash] = null; - - } - - static Dictionary> fieldInfoCache = new(); - static Dictionary> propertyInfoCache = new(); - static Dictionary> methodInfoCache = new(); - - - - - public const BindingFlags maxBindingFlags = (BindingFlags)62; - - - - - - - - - #endregion - - #region Linq - - - public static T NextTo(this IEnumerable e, T to) => e.SkipWhile(r => !r.Equals(to)).Skip(1).FirstOrDefault(); - public static T PreviousTo(this IEnumerable e, T to) => e.Reverse().SkipWhile(r => !r.Equals(to)).Skip(1).FirstOrDefault(); - public static T NextToOtFirst(this IEnumerable e, T to) => e.NextTo(to) ?? e.First(); - public static T PreviousToOrLast(this IEnumerable e, T to) => e.PreviousTo(to) ?? e.Last(); - - public static Dictionary MergeDictionaries(IEnumerable> dicts) - { - if (dicts.Count() == 0) return null; - if (dicts.Count() == 1) return dicts.First(); - - var mergedDict = new Dictionary(dicts.First()); - - foreach (var dict in dicts.Skip(1)) - foreach (var r in dict) - if (!mergedDict.ContainsKey(r.Key)) - mergedDict.Add(r.Key, r.Value); - - return mergedDict; - } - - public static IEnumerable InsertFirst(this IEnumerable ie, T t) => new[] { t }.Concat(ie); - - public static int IndexOfFirst(this List list, System.Func f) => list.FirstOrDefault(f) is T t ? list.IndexOf(t) : -1; - public static int IndexOfLast(this List list, System.Func f) => list.LastOrDefault(f) is T t ? list.IndexOf(t) : -1; - - public static void SortBy(this List list, System.Func keySelector) where T2 : System.IComparable => list.Sort((q, w) => keySelector(q).CompareTo(keySelector(w))); - - public static void RemoveValue(this IDictionary dictionary, TValue value) - { - if (dictionary.FirstOrDefault(r => r.Value.Equals(value)) is var kvp) - dictionary.Remove(kvp); - } - - public static void ForEach(this IEnumerable sequence, System.Action action) { foreach (T item in sequence) action(item); } - - - - public static T AddAt(this List l, T r, int i) - { - if (i < 0) i = 0; - if (i >= l.Count) - l.Add(r); - else - l.Insert(i, r); - return r; - } - public static T RemoveLast(this List l) - { - if (!l.Any()) return default; - - var r = l.Last(); - - l.RemoveAt(l.Count - 1); - - return r; - } - - public static void Add(this List list, params T[] items) - { - foreach (var r in items) - list.Add(r); - } - - - - - - - #endregion - - #region Math - - - public static class MathUtil // MathUtils name is taken by UnityEditor.MathUtils - { - - public static float TriangleArea(Vector2 A, Vector2 B, Vector2 C) => Vector3.Cross(A - B, A - C).z.Abs() / 2; - - public static Vector2 LineIntersection(Vector2 A, Vector2 B, Vector2 C, Vector2 D) - { - var a1 = B.y - A.y; - var b1 = A.x - B.x; - var c1 = a1 * A.x + b1 * A.y; - - var a2 = D.y - C.y; - var b2 = C.x - D.x; - var c2 = a2 * C.x + b2 * C.y; - - var d = a1 * b2 - a2 * b1; - - var x = (b2 * c1 - b1 * c2) / d; - var y = (a1 * c2 - a2 * c1) / d; - - return new Vector2(x, y); - - } - - - - - public static float Lerp(float f1, float f2, float t) => Mathf.LerpUnclamped(f1, f2, t); - public static float Lerp(ref float f1, float f2, float t) - { - return f1 = Lerp(f1, f2, t); - } - - public static Vector2 Lerp(Vector2 f1, Vector2 f2, float t) => Vector2.LerpUnclamped(f1, f2, t); - public static Vector2 Lerp(ref Vector2 f1, Vector2 f2, float t) - { - return f1 = Lerp(f1, f2, t); - } - - public static Vector3 Lerp(Vector3 f1, Vector3 f2, float t) => Vector3.LerpUnclamped(f1, f2, t); - public static Vector3 Lerp(ref Vector3 f1, Vector3 f2, float t) - { - return f1 = Lerp(f1, f2, t); - } - - public static Color Lerp(Color f1, Color f2, float t) => Color.LerpUnclamped(f1, f2, t); - public static Color Lerp(ref Color f1, Color f2, float t) - { - return f1 = Lerp(f1, f2, t); - } - - - public static float Lerp(float current, float target, float speed, float deltaTime) => Mathf.Lerp(current, target, GetLerpT(speed, deltaTime)); - public static float Lerp(ref float current, float target, float speed, float deltaTime) - { - return current = Lerp(current, target, speed, deltaTime); - } - - public static Vector2 Lerp(Vector2 current, Vector2 target, float speed, float deltaTime) => Vector2.Lerp(current, target, GetLerpT(speed, deltaTime)); - public static Vector2 Lerp(ref Vector2 current, Vector2 target, float speed, float deltaTime) - { - return current = Lerp(current, target, speed, deltaTime); - } - - public static Vector3 Lerp(Vector3 current, Vector3 target, float speed, float deltaTime) => Vector3.Lerp(current, target, GetLerpT(speed, deltaTime)); - public static Vector3 Lerp(ref Vector3 current, Vector3 target, float speed, float deltaTime) - { - return current = Lerp(current, target, speed, deltaTime); - } - - public static float SmoothDamp(float current, float target, float speed, ref float derivative, float deltaTime, float maxSpeed) => Mathf.SmoothDamp(current, target, ref derivative, .5f / speed, maxSpeed, deltaTime); - public static float SmoothDamp(float current, float target, float speed, ref float derivative, float deltaTime) - { - return Mathf.SmoothDamp(current, target, ref derivative, .5f / speed, Mathf.Infinity, deltaTime); - } - public static float SmoothDamp(float current, float target, float speed, ref float derivative) - { - return SmoothDamp(current, target, speed, ref derivative, Time.deltaTime); - } - public static float SmoothDamp(ref float current, float target, float speed, ref float derivative, float deltaTime, float maxSpeed) - { - return current = SmoothDamp(current, target, speed, ref derivative, deltaTime, maxSpeed); - } - public static float SmoothDamp(ref float current, float target, float speed, ref float derivative, float deltaTime) - { - return current = SmoothDamp(current, target, speed, ref derivative, deltaTime); - } - public static float SmoothDamp(ref float current, float target, float speed, ref float derivative) - { - return current = SmoothDamp(current, target, speed, ref derivative, Time.deltaTime); - } - - public static Vector2 SmoothDamp(Vector2 current, Vector2 target, float speed, ref Vector2 derivative, float deltaTime) => Vector2.SmoothDamp(current, target, ref derivative, .5f / speed, Mathf.Infinity, deltaTime); - public static Vector2 SmoothDamp(Vector2 current, Vector2 target, float speed, ref Vector2 derivative) - { - return SmoothDamp(current, target, speed, ref derivative, Time.deltaTime); - } - public static Vector2 SmoothDamp(ref Vector2 current, Vector2 target, float speed, ref Vector2 derivative, float deltaTime) - { - return current = SmoothDamp(current, target, speed, ref derivative, deltaTime); - } - public static Vector2 SmoothDamp(ref Vector2 current, Vector2 target, float speed, ref Vector2 derivative) - { - return current = SmoothDamp(current, target, speed, ref derivative, Time.deltaTime); - } - - public static Vector3 SmoothDamp(Vector3 current, Vector3 target, float speed, ref Vector3 derivative, float deltaTime) => Vector3.SmoothDamp(current, target, ref derivative, .5f / speed, Mathf.Infinity, deltaTime); - public static Vector3 SmoothDamp(Vector3 current, Vector3 target, float speed, ref Vector3 derivative) - { - return SmoothDamp(current, target, speed, ref derivative, Time.deltaTime); - } - public static Vector3 SmoothDamp(ref Vector3 current, Vector3 target, float speed, ref Vector3 derivative, float deltaTime) - { - return current = SmoothDamp(current, target, speed, ref derivative, deltaTime); - } - public static Vector3 SmoothDamp(ref Vector3 current, Vector3 target, float speed, ref Vector3 derivative) - { - return current = SmoothDamp(current, target, speed, ref derivative, Time.deltaTime); - } - - - public static float GetLerpT(float lerpSpeed, float deltaTime) => 1 - Mathf.Exp(-lerpSpeed * 2f * deltaTime); - public static float GetLerpT(float lerpSpeed) - { - return GetLerpT(lerpSpeed, Time.deltaTime); - } - - - - } - - - public static float DistanceTo(this float f1, float f2) => Mathf.Abs(f1 - f2); - public static float DistanceTo(this Vector2 f1, Vector2 f2) => (f1 - f2).magnitude; - public static float DistanceTo(this Vector3 f1, Vector3 f2) => (f1 - f2).magnitude; - - public static float Sign(this float f) => f == 0 ? 0 : Mathf.Sign(f); - - public static int Abs(this int f) => Mathf.Abs(f); - public static float Abs(this float f) => Mathf.Abs(f); - - public static int Clamp(this int f, int f0, int f1) => Mathf.Clamp(f, f0, f1); - public static float Clamp(this float f, float f0, float f1) => Mathf.Clamp(f, f0, f1); - - - public static float Clamp01(this float f) => Mathf.Clamp(f, 0, 1); - public static Vector2 Clamp01(this Vector2 f) => new(f.x.Clamp01(), f.y.Clamp01()); - public static Vector3 Clamp01(this Vector3 f) => new(f.x.Clamp01(), f.y.Clamp01(), f.z.Clamp01()); - - - public static int Pow(this int f, int pow) => (int)Mathf.Pow(f, pow); - public static float Pow(this float f, float pow) => Mathf.Pow(f, pow); - - public static float Round(this float f) => Mathf.Round(f); - public static float Ceil(this float f) => Mathf.Ceil(f); - public static float Floor(this float f) => Mathf.Floor(f); - - public static int RoundToInt(this float f) => Mathf.RoundToInt(f); - public static int CeilToInt(this float f) => Mathf.CeilToInt(f); - public static int FloorToInt(this float f) => Mathf.FloorToInt(f); - - public static int ToInt(this float f) => (int)f; - public static float ToFloat(this int f) => (float)f; - public static float ToFloat(this double f) => (float)f; - - - - public static float Sqrt(this float f) => Mathf.Sqrt(f); - - public static int Max(this int f, int ff) => Mathf.Max(f, ff); - public static int Min(this int f, int ff) => Mathf.Min(f, ff); - public static float Max(this float f, float ff) => Mathf.Max(f, ff); - public static float Min(this float f, float ff) => Mathf.Min(f, ff); - - public static float ClampMin(this float f, float limitMin) => Mathf.Max(f, limitMin); - public static float ClampMax(this float f, float limitMax) => Mathf.Min(f, limitMax); - - - public static float Loop(this float f, float boundMin, float boundMax) - { - while (f < boundMin) f += boundMax - boundMin; - while (f > boundMax) f -= boundMax - boundMin; - return f; - } - public static float Loop(this float f, float boundMax) => f.Loop(0, boundMax); - - public static float PingPong(this float f, float boundMin, float boundMax) => boundMin + Mathf.PingPong(f - boundMin, boundMax - boundMin); - public static float PingPong(this float f, float boundMax) => f.PingPong(0, boundMax); - - - public static float ProjectOn(this Vector2 v, Vector2 on) => Vector3.Project(v, on).magnitude; - public static float ProjectOn(this Vector3 v, Vector3 on) => Vector3.Project(v, on).magnitude; - - public static float AngleTo(this Vector2 v, Vector2 to) => Vector2.Angle(v, to); - - public static Vector2 Rotate(this Vector2 v, float deg) => Quaternion.AngleAxis(deg, Vector3.forward) * v; - - public static float Smoothstep(this float f) { f = f.Clamp01(); return f * f * (3 - 2 * f); } - - public static float InverseLerp(this Vector2 v, Vector2 a, Vector2 b) - { - var ab = b - a; - var av = v - a; - return Vector2.Dot(av, ab) / Vector2.Dot(ab, ab); - } - - - public static bool IsOdd(this int i) => i % 2 == 1; - public static bool IsEven(this int i) => i % 2 == 0; - - public static bool IsInRange(this int i, int a, int b) => i >= a && i <= b; - public static bool IsInRange(this float i, float a, float b) => i >= a && i <= b; - - public static bool IsInRangeOf(this int i, IList list) => i.IsInRange(0, list.Count - 1); - public static bool IsInRangeOf(this int i, T[] array) => i.IsInRange(0, array.Length - 1); - - public static bool Approx(this float f1, float f2) => Mathf.Approximately(f1, f2); - - - - [System.Serializable] - public class GaussianKernel - { - public static float[,] GenerateArray(int size, float sharpness = .5f) - { - float[,] kr = new float[size, size]; - - if (size == 1) { kr[0, 0] = 1; return kr; } - - - var sigma = 1f - Mathf.Pow(sharpness, .1f) * .99999f; - var radius = (size / 2f).FloorToInt(); - - - var a = -2f * radius * radius / Mathf.Log(sigma); - var sum = 0f; - - for (int y = 0; y < size; y++) - for (int x = 0; x < size; x++) - { - var rX = size % 2 == 1 ? (x - radius) : (x - radius) + .5f; - var rY = size % 2 == 1 ? (y - radius) : (y - radius) + .5f; - var dist = Mathf.Sqrt(rX * rX + rY * rY); - kr[x, y] = Mathf.Exp(-dist * dist / a); - sum += kr[x, y]; - } - - for (int y = 0; y < size; y++) - for (int x = 0; x < size; x++) - kr[x, y] /= sum; - - return kr; - } - - - - public GaussianKernel(bool isEvenSize = false, int radius = 7, float sharpness = .5f) - { - this.isEvenSize = isEvenSize; - this.radius = radius; - this.sharpness = sharpness; - } - - public bool isEvenSize = false; - public int radius = 7; - public float sharpness = .5f; - - public int size => radius * 2 + (isEvenSize ? 0 : 1); - public float sigma => 1 - Mathf.Pow(sharpness, .1f) * .99999f; - - public float[,] Array2d() // todo test and use GenerateArray - { - float[,] kr = new float[size, size]; - - if (size == 1) { kr[0, 0] = 1; return kr; } - - var a = -2f * radius * radius / Mathf.Log(sigma); - var sum = 0f; - - for (int y = 0; y < size; y++) - for (int x = 0; x < size; x++) - { - var rX = size % 2 == 1 ? (x - radius) : (x - radius) + .5f; - var rY = size % 2 == 1 ? (y - radius) : (y - radius) + .5f; - var dist = Mathf.Sqrt(rX * rX + rY * rY); - kr[x, y] = Mathf.Exp(-dist * dist / a); - sum += kr[x, y]; - } - - for (int y = 0; y < size; y++) - for (int x = 0; x < size; x++) - kr[x, y] /= sum; - - return kr; - } - public float[] ArrayFlat() - { - var gk = Array2d(); - float[] flat = new float[size * size]; - - for (int i = 0; i < size; i++) - for (int j = 0; j < size; j++) - flat[(i * size + j)] = gk[i, j]; - - return flat; - } - - } - - - - - - - - #endregion - - #region Lerping - - - public static float LerpT(float lerpSpeed, float deltaTime) => 1 - Mathf.Exp(-lerpSpeed * 2f * deltaTime); - public static float LerpT(float lerpSpeed) => LerpT(lerpSpeed, Time.deltaTime); - - public static float Lerp(float f1, float f2, float t) => Mathf.LerpUnclamped(f1, f2, t); - public static float Lerp(ref float f1, float f2, float t) => f1 = Lerp(f1, f2, t); - - public static Vector2 Lerp(Vector2 f1, Vector2 f2, float t) => Vector2.LerpUnclamped(f1, f2, t); - public static Vector2 Lerp(ref Vector2 f1, Vector2 f2, float t) => f1 = Lerp(f1, f2, t); - - public static Vector3 Lerp(Vector3 f1, Vector3 f2, float t) => Vector3.LerpUnclamped(f1, f2, t); - public static Vector3 Lerp(ref Vector3 f1, Vector3 f2, float t) => f1 = Lerp(f1, f2, t); - - public static Color Lerp(Color f1, Color f2, float t) => Color.LerpUnclamped(f1, f2, t); - public static Color Lerp(ref Color f1, Color f2, float t) => f1 = Lerp(f1, f2, t); - - - public static float Lerp(float current, float target, float speed, float deltaTime) => Mathf.Lerp(current, target, LerpT(speed, deltaTime)); - public static float Lerp(ref float current, float target, float speed, float deltaTime) => current = Lerp(current, target, speed, deltaTime); - - public static Vector2 Lerp(Vector2 current, Vector2 target, float speed, float deltaTime) => Vector2.Lerp(current, target, LerpT(speed, deltaTime)); - public static Vector2 Lerp(ref Vector2 current, Vector2 target, float speed, float deltaTime) => current = Lerp(current, target, speed, deltaTime); - - public static Vector3 Lerp(Vector3 current, Vector3 target, float speed, float deltaTime) => Vector3.Lerp(current, target, LerpT(speed, deltaTime)); - public static Vector3 Lerp(ref Vector3 current, Vector3 target, float speed, float deltaTime) => current = Lerp(current, target, speed, deltaTime); - - public static float SmoothDamp(float current, float target, float speed, ref float derivative, float deltaTime, float maxSpeed) => Mathf.SmoothDamp(current, target, ref derivative, .5f / speed, maxSpeed, deltaTime); - public static float SmoothDamp(ref float current, float target, float speed, ref float derivative, float deltaTime, float maxSpeed) => current = SmoothDamp(current, target, speed, ref derivative, deltaTime, maxSpeed); - public static float SmoothDamp(float current, float target, float speed, ref float derivative, float deltaTime) => Mathf.SmoothDamp(current, target, ref derivative, .5f / speed, Mathf.Infinity, deltaTime); - public static float SmoothDamp(ref float current, float target, float speed, ref float derivative, float deltaTime) => current = SmoothDamp(current, target, speed, ref derivative, deltaTime); - public static float SmoothDamp(float current, float target, float speed, ref float derivative) => SmoothDamp(current, target, speed, ref derivative, Time.deltaTime); - public static float SmoothDamp(ref float current, float target, float speed, ref float derivative) => current = SmoothDamp(current, target, speed, ref derivative, Time.deltaTime); - - public static Vector2 SmoothDamp(Vector2 current, Vector2 target, float speed, ref Vector2 derivative, float deltaTime) => Vector2.SmoothDamp(current, target, ref derivative, .5f / speed, Mathf.Infinity, deltaTime); - public static Vector2 SmoothDamp(ref Vector2 current, Vector2 target, float speed, ref Vector2 derivative, float deltaTime) => current = SmoothDamp(current, target, speed, ref derivative, deltaTime); - public static Vector2 SmoothDamp(Vector2 current, Vector2 target, float speed, ref Vector2 derivative) => SmoothDamp(current, target, speed, ref derivative, Time.deltaTime); - public static Vector2 SmoothDamp(ref Vector2 current, Vector2 target, float speed, ref Vector2 derivative) => current = SmoothDamp(current, target, speed, ref derivative, Time.deltaTime); - - public static Vector3 SmoothDamp(Vector3 current, Vector3 target, float speed, ref Vector3 derivative, float deltaTime) => Vector3.SmoothDamp(current, target, ref derivative, .5f / speed, Mathf.Infinity, deltaTime); - public static Vector3 SmoothDamp(ref Vector3 current, Vector3 target, float speed, ref Vector3 derivative, float deltaTime) => current = SmoothDamp(current, target, speed, ref derivative, deltaTime); - public static Vector3 SmoothDamp(Vector3 current, Vector3 target, float speed, ref Vector3 derivative) => SmoothDamp(current, target, speed, ref derivative, Time.deltaTime); - public static Vector3 SmoothDamp(ref Vector3 current, Vector3 target, float speed, ref Vector3 derivative) => current = SmoothDamp(current, target, speed, ref derivative, Time.deltaTime); - - - - - - - #endregion - - #region Colors - - - public class ColorUtils - { - public static Color HSLToRGB(float h, float s, float l) - { - float hue2Rgb(float v1, float v2, float vH) - { - if (vH < 0f) - vH += 1f; - - if (vH > 1f) - vH -= 1f; - - if (6f * vH < 1f) - return v1 + (v2 - v1) * 6f * vH; - - if (2f * vH < 1f) - return v2; - - if (3f * vH < 2f) - return v1 + (v2 - v1) * (2f / 3f - vH) * 6f; - - return v1; - } - - if (s.Approx(0)) return new Color(l, l, l); - - float k1; - - if (l < .5f) - k1 = l * (1f + s); - else - k1 = l + s - s * l; - - - var k2 = 2f * l - k1; - - float r, g, b; - r = hue2Rgb(k2, k1, h + 1f / 3); - g = hue2Rgb(k2, k1, h); - b = hue2Rgb(k2, k1, h - 1f / 3); - - return new Color(r, g, b); - } - public static Color LCHtoRGB(float l, float c, float h) - { - l *= 100; - c *= 100; - h *= 360; - - double xw = 0.948110; - double yw = 1.00000; - double zw = 1.07304; - - float a = c * Mathf.Cos(Mathf.Deg2Rad * h); - float b = c * Mathf.Sin(Mathf.Deg2Rad * h); - - float fy = (l + 16) / 116; - float fx = fy + (a / 500); - float fz = fy - (b / 200); - - float x = (float)System.Math.Round(xw * ((System.Math.Pow(fx, 3) > 0.008856) ? System.Math.Pow(fx, 3) : ((fx - 16 / 116) / 7.787)), 5); - float y = (float)System.Math.Round(yw * ((System.Math.Pow(fy, 3) > 0.008856) ? System.Math.Pow(fy, 3) : ((fy - 16 / 116) / 7.787)), 5); - float z = (float)System.Math.Round(zw * ((System.Math.Pow(fz, 3) > 0.008856) ? System.Math.Pow(fz, 3) : ((fz - 16 / 116) / 7.787)), 5); - - float r = x * 3.2406f - y * 1.5372f - z * 0.4986f; - float g = -x * 0.9689f + y * 1.8758f + z * 0.0415f; - float bValue = x * 0.0557f - y * 0.2040f + z * 1.0570f; - - r = r > 0.0031308f ? 1.055f * (float)System.Math.Pow(r, 1 / 2.4) - 0.055f : r * 12.92f; - g = g > 0.0031308f ? 1.055f * (float)System.Math.Pow(g, 1 / 2.4) - 0.055f : g * 12.92f; - bValue = bValue > 0.0031308f ? 1.055f * (float)System.Math.Pow(bValue, 1 / 2.4) - 0.055f : bValue * 12.92f; - - // r = (float)System.Math.Round(System.Math.Max(0, System.Math.Min(1, r))); - // g = (float)System.Math.Round(System.Math.Max(0, System.Math.Min(1, g))); - // bValue = (float)System.Math.Round(System.Math.Max(0, System.Math.Min(1, bValue))); - - return new Color(r, g, bValue); - - } - - } - - - public static Color Greyscale(float brightness, float alpha = 1) => new(brightness, brightness, brightness, alpha); - - public static Color SetAlpha(this Color color, float alpha) { color.a = alpha; return color; } - public static Color MultiplyAlpha(this Color color, float k) { color.a *= k; return color; } - - - - - - #endregion - - #region Rects - - - public static Rect Resize(this Rect rect, float px) { rect.x += px; rect.y += px; rect.width -= px * 2; rect.height -= px * 2; return rect; } - - public static Rect SetPos(this Rect rect, Vector2 v) => rect.SetPos(v.x, v.y); - public static Rect SetPos(this Rect rect, float x, float y) { rect.x = x; rect.y = y; return rect; } - - public static Rect SetX(this Rect rect, float x) => rect.SetPos(x, rect.y); - public static Rect SetY(this Rect rect, float y) => rect.SetPos(rect.x, y); - public static Rect SetXMax(this Rect rect, float xMax) { rect.xMax = xMax; return rect; } - public static Rect SetYMax(this Rect rect, float yMax) { rect.yMax = yMax; return rect; } - - public static Rect SetMidPos(this Rect r, Vector2 v) => r.SetPos(v).MoveX(-r.width / 2).MoveY(-r.height / 2); - public static Rect SetMidPos(this Rect r, float x, float y) => r.SetMidPos(new Vector2(x, y)); - - public static Rect Move(this Rect rect, Vector2 v) { rect.position += v; return rect; } - public static Rect Move(this Rect rect, float x, float y) { rect.x += x; rect.y += y; return rect; } - public static Rect MoveX(this Rect rect, float px) { rect.x += px; return rect; } - public static Rect MoveY(this Rect rect, float px) { rect.y += px; return rect; } - - public static Rect SetWidth(this Rect rect, float f) { rect.width = f; return rect; } - public static Rect SetWidthFromMid(this Rect rect, float px) { rect.x += rect.width / 2; rect.width = px; rect.x -= rect.width / 2; return rect; } - public static Rect SetWidthFromRight(this Rect rect, float px) { rect.x += rect.width; rect.width = px; rect.x -= rect.width; return rect; } - - public static Rect SetHeight(this Rect rect, float f) { rect.height = f; return rect; } - public static Rect SetHeightFromMid(this Rect rect, float px) { rect.y += rect.height / 2; rect.height = px; rect.y -= rect.height / 2; return rect; } - public static Rect SetHeightFromBottom(this Rect rect, float px) { rect.y += rect.height; rect.height = px; rect.y -= rect.height; return rect; } - - public static Rect AddWidth(this Rect rect, float f) => rect.SetWidth(rect.width + f); - public static Rect AddWidthFromMid(this Rect rect, float f) => rect.SetWidthFromMid(rect.width + f); - public static Rect AddWidthFromRight(this Rect rect, float f) => rect.SetWidthFromRight(rect.width + f); - - public static Rect AddHeight(this Rect rect, float f) => rect.SetHeight(rect.height + f); - public static Rect AddHeightFromMid(this Rect rect, float f) => rect.SetHeightFromMid(rect.height + f); - public static Rect AddHeightFromBottom(this Rect rect, float f) => rect.SetHeightFromBottom(rect.height + f); - - public static Rect SetSize(this Rect rect, Vector2 v) => rect.SetWidth(v.x).SetHeight(v.y); - public static Rect SetSize(this Rect rect, float w, float h) => rect.SetWidth(w).SetHeight(h); - public static Rect SetSize(this Rect rect, float f) { rect.height = rect.width = f; return rect; } - - public static Rect SetSizeFromMid(this Rect r, Vector2 v) => r.Move(r.size / 2).SetSize(v).Move(-v / 2); - public static Rect SetSizeFromMid(this Rect r, float x, float y) => r.SetSizeFromMid(new Vector2(x, y)); - public static Rect SetSizeFromMid(this Rect r, float f) => r.SetSizeFromMid(new Vector2(f, f)); - - public static Rect AlignToPixelGrid(this Rect r) => GUIUtility.AlignRectToDevice(r); - - - - - - #endregion - - #region Textures - - - public static Texture2D CreateTexture2D(int width, int height, GraphicsFormat graphicsFormat = GraphicsFormat.R8G8B8A8_SRGB, bool useMips = false) - { - return new Texture2D(width, height, graphicsFormat, useMips ? TextureCreationFlags.MipChain : TextureCreationFlags.None); - } - - public static RenderTexture CreateRT(int width, int height, GraphicsFormat graphicsFormat = GraphicsFormat.R8G8B8A8_SRGB, bool useMips = false, bool autoGenerateMips = true, bool useDepth = false) - { - var rt = new RenderTexture(width, height, useDepth ? 24 : 0, graphicsFormat); - - rt.useMipMap = useMips; - rt.autoGenerateMips = autoGenerateMips; - - rt.enableRandomWrite = true; - - return rt; - - } - public static RenderTexture GetTemporaryRT(int width, int height, GraphicsFormat graphicsFormat = GraphicsFormat.R8G8B8A8_SRGB, bool useMips = false, bool autoGenerateMips = true, bool useDepth = false) - { - var rt = RenderTexture.GetTemporary(width, height, useDepth ? 24 : 0, graphicsFormat); - - rt.useMipMap = useMips; - rt.autoGenerateMips = autoGenerateMips; - - rt.enableRandomWrite = true; - - return rt; - - } - - public static RenderTexture CreateRT(this RenderTextureDescriptor descriptor) => new(descriptor); - public static RenderTexture CreateRT(this RenderTextureDescriptor descriptor, int resolution) - { - descriptor.width = descriptor.height = resolution; - - return descriptor.CreateRT(); - - } - public static RenderTexture CreateRT(this RenderTextureDescriptor descriptor, int width, int height) - { - descriptor.width = width; - descriptor.height = height; - - return descriptor.CreateRT(); - - } - public static RenderTexture CreateRT(this RenderTextureDescriptor descriptor, float resolution) => descriptor.GetTemporaryRT(Mathf.RoundToInt(resolution)); - public static RenderTexture CreateRT(this RenderTextureDescriptor descriptor, float width, float height) => descriptor.CreateRT(Mathf.RoundToInt(width), Mathf.RoundToInt(height)); - public static RenderTexture GetTemporaryRT(this RenderTextureDescriptor descriptor) => RenderTexture.GetTemporary(descriptor); - public static RenderTexture GetTemporaryRT(this RenderTextureDescriptor descriptor, int resolution) - { - descriptor.width = descriptor.height = resolution; - - return descriptor.GetTemporaryRT(); - - } - public static RenderTexture GetTemporaryRT(this RenderTextureDescriptor descriptor, int width, int height) - { - descriptor.width = width; - descriptor.height = height; - - return descriptor.GetTemporaryRT(); - - } - public static RenderTexture GetTemporaryRT(this RenderTextureDescriptor descriptor, float resolution) => descriptor.GetTemporaryRT(Mathf.RoundToInt(resolution)); - public static RenderTexture GetTemporaryRT(this RenderTextureDescriptor descriptor, float width, float height) => descriptor.GetTemporaryRT(Mathf.RoundToInt(width), Mathf.RoundToInt(height)); - - public static void ReleaseTemporary(this RenderTexture rt) { if (rt) RenderTexture.ReleaseTemporary(rt); } - - - - public static Texture2D ToTexture2D(this RenderTexture rt) - { - var texture2D = CreateTexture2D(rt.width, rt.height, rt.graphicsFormat, rt.useMipMap); - - texture2D.ReadPixelsFrom(rt); - texture2D.Apply(); - - return texture2D; - - } - public static RenderTexture ToRenderTexture(this Texture2D texture2d) - { - var rt = CreateRT(texture2d.width, texture2d.height, texture2d.graphicsFormat, texture2d.mipmapCount > 1); - - Graphics.CopyTexture(texture2d, rt); - - return rt; - - } - - - public static void ReadPixelsFrom(this Texture2D texture2D, RenderTexture renderTexture) - { - var prevActive = RenderTexture.active; - - RenderTexture.active = renderTexture; - - texture2D.ReadPixels(new Rect(0, 0, renderTexture.width, renderTexture.height), 0, 0); - - RenderTexture.active = prevActive; - - } - // public static void CopyTo(this RenderTexture source, Texture2D target) // todo to readpixels overload - // { - // var prevActive = RenderTexture.active; - - // RenderTexture.active = source; - - // target.ReadPixels(new Rect(0, 0, source.width, source.height), 0, 0); - // target.Apply(); - - // RenderTexture.active = prevActive; - - - // // somewhere in unity source code reading is done like this, but it throws out of bounds read exception on win: - - // // if (!SystemInfo.graphicsUVStartsAtTop || SystemInfo.graphicsDeviceType == GraphicsDeviceType.Metal) - // // texture2d.ReadPixels(new Rect(0, 0, texture2d.width, texture2d.height), 0, 0); - // // else - // // texture2d.ReadPixels(new Rect(0, texture2d.height, texture2d.width, texture2d.height), 0, 0); - - // // this was used in the legacy rt.CopyToTexture2D extension method - - // } - - public static Texture2D CreateCopy(this Texture2D texture2d) - { - var copy = CreateTexture2D(texture2d.width, texture2d.height, texture2d.graphicsFormat, texture2d.mipmapCount > 1); - - Graphics.CopyTexture(texture2d, copy); - - return copy; - - } - public static Texture2D CreateResizedCopy(this Texture2D texture2d, int w, int h) - { - var rt = GetTemporaryRT(w, h, texture2d.graphicsFormat.GetCompatibleForRendering(), false); - - Graphics.Blit(texture2d, rt); - - - var resizedCopy = CreateTexture2D(w, h, texture2d.graphicsFormat.GetCompatibleForRendering(), texture2d.mipmapCount > 1); - - resizedCopy.ReadPixelsFrom(rt); - resizedCopy.Apply(); - - if (RenderTexture.active == rt) - RenderTexture.active = null; - - rt.ReleaseTemporary(); - - - return resizedCopy; - - } - - - public static void FillWithColor(this Texture2D texture2d, Color color) - { - var pixels = new Color32[texture2d.width * texture2d.height]; - - var color32 = (Color32)color; - - for (int i = 0; i < pixels.Length; i++) - pixels[i] = color32; - - texture2d.SetPixels32(pixels); - texture2d.Apply(); - - } - public static RenderTexture FillWithColor(this RenderTexture rt, Color color) // todo builtin shader or GL.clear - { - var mat = new Material(Shader.Find("Hidden/VBlitColor")); - - mat.SetColor("_color", color); - - Graphics.Blit(null, rt, mat); - - mat.Destroy(); - - return rt; - - } - - - - public static GraphicsFormat GetCompatibleForRendering(this GraphicsFormat graphicsFormat) - { - if ((int)graphicsFormat == 88) // unsupported on dx11 but GetCompatibleFormat() doesn't think so - if (PlayerSettings.colorSpace == ColorSpace.Linear) - return GraphicsFormat.R8G8B8A8_SRGB; - else - return GraphicsFormat.R8G8B8A8_UNorm; - -#if UNITY_2023_2_OR_NEWER - return SystemInfo.GetCompatibleFormat(graphicsFormat, GraphicsFormatUsage.Render); -#else - return SystemInfo.GetCompatibleFormat(graphicsFormat, FormatUsage.Render); -#endif - - } - - - -#if UNITY_EDITOR - - public static void SavePNG(this Texture2D texture2d, string path) => File.WriteAllBytes(path, texture2d.EncodeToPNG()); - - public static void SetImportSettings(this Texture2D texture2d, int? maxSize = null, bool? useMips = null, bool? sRGB = null, bool? isReadable = null, bool? useCompression = null) - { - var importer = texture2d.GetImporter(); - - if (useCompression != null) - importer.textureCompression = useCompression.GetValueOrDefault() ? TextureImporterCompression.Compressed : TextureImporterCompression.Uncompressed; - - if (sRGB != null) - importer.sRGBTexture = sRGB.GetValueOrDefault(); - - if (maxSize != null) - importer.maxTextureSize = maxSize.GetValueOrDefault(); - - if (useMips != null) - importer.mipmapEnabled = useMips.GetValueOrDefault(); - - - // if (texture2d.format == TextureFormat.R16 || texture2d.format == TextureFormat.RG32) - if (texture2d.format == TextureFormat.R16) - { - var platformSettings = importer.GetDefaultPlatformTextureSettings(); - - platformSettings.format = TextureImporterFormat.R16; - - if (maxSize != null) - platformSettings.maxTextureSize = maxSize.GetValueOrDefault(); - - importer.SetPlatformTextureSettings(platformSettings); - - } - - } - - public static TextureImporter GetImporter(this Texture2D t) => (TextureImporter)AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(t)); - -#endif - - - - - - - - #endregion - - #region Objects - - - public static Object[] FindObjects(Type type) - { -#if UNITY_2023_1_OR_NEWER - return Object.FindObjectsByType(type, FindObjectsSortMode.None); -#else - return Object.FindObjectsOfType(type); -#endif - } - public static T[] FindObjects() where T : Object - { -#if UNITY_2023_1_OR_NEWER - return Object.FindObjectsByType(FindObjectsSortMode.None); -#else - return Object.FindObjectsOfType(); -#endif - } - - public static void Destroy(this Object r) - { - if (Application.isPlaying) - Object.Destroy(r); - else - Object.DestroyImmediate(r); - - } - - public static void DestroyImmediate(this Object o) => Object.DestroyImmediate(o); - - - - - - #endregion - - #region Text - - - public static class TextUtils - { - public static string FormatDistance(float meters) - { - int m = (int)meters; - - if (m < 1000) - return m + " m"; - else - return (m / 1000) + "." + (m / 100) % 10 + " km"; - - } - public static string FormatLong(long l) => System.String.Format("{0:n0}", l); - public static string FormatInt(int l) => FormatLong((long)l); - public static string FormatTime(long ms, bool includeMs = false) - { - System.TimeSpan t = System.TimeSpan.FromMilliseconds(ms); - var s = ""; - if (t.Hours != 0) s += " " + t.Hours + " hour" + GetCountSuffix(t.Hours); - if (t.Minutes != 0) s += " " + t.Minutes + " minute" + GetCountSuffix(t.Minutes); - if (t.Seconds != 0) s += " " + t.Seconds + " second" + GetCountSuffix(t.Seconds); - if (t.Milliseconds != 0 && includeMs) s += " " + t.Milliseconds + " millisecond" + GetCountSuffix(t.Milliseconds); - - if (s == "") - if (includeMs) s = "0 milliseconds"; - else s = "0 seconds"; - - return s.Trim(); - } - public static string FormatFileSize(long bytes, bool sizeUnknownIfNotMoreThanZero = false) - { - if (sizeUnknownIfNotMoreThanZero && bytes == 0) return "Size unknown"; - - var ss = new[] { "B", "KB", "MB", "GB", "TB" }; - var bprev = bytes; - int i = 0; - while (bytes >= 1024 && i++ < ss.Length - 1) bytes = (bprev = bytes) / 1024; - - if (bytes < 0) return "? B"; - if (i < 3) return string.Format("{0:0.#} ", bytes) + ss[i]; - return string.Format("{0:0.##} ", bytes) + ss[i]; - } - - static string GetCountSuffix(long c) => c % 10 != 1 ? "s" : ""; - - public static string GetLoremIpsum(int words = 2) - { - var s = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur Excepteur sint occaecat cupidatat non proident sunt in culpa qui officia deserunt mollit anim id est laborum"; - var ws = s.Split(' ').Select(r => r.ToLower().Trim(new[] { ',', '.' })); - ws = ws.OrderBy(r => UnityEngine.Random.Range(0, 1232)).Take(words); - var ss = string.Join(" ", ws); - return char.ToUpper(ss[0]) + ss.Substring(1); - } - - } - - - public static bool IsEmpty(this string s) => s == ""; - public static bool IsNullOrEmpty(this string s) => string.IsNullOrEmpty(s); - - public static bool IsLower(this char c) => System.Char.IsLower(c); - public static bool IsUpper(this char c) => System.Char.IsUpper(c); - public static bool IsDigit(this char c) => System.Char.IsDigit(c); - public static bool IsLetter(this char c) => System.Char.IsLetter(c); - public static bool IsWhitespace(this char c) => System.Char.IsWhiteSpace(c); - - public static char ToLower(this char c) => System.Char.ToLower(c); - public static char ToUpper(this char c) => System.Char.ToUpper(c); - - - - public static string Decamelcase(this string s) - { - return Regex.Replace(Regex.Replace(s, @"(\P{Ll})(\P{Ll}\p{Ll})", "$1 $2"), @"(\p{Ll})(\P{Ll})", "$1 $2"); - } - public static string FormatVariableName(this string s, bool lowercaseFollowingWords = true) - { - return string.Join(" ", s.Decamelcase() - .Split(' ') - .Select(r => new[] { "", "and", "or", "with", "without", "by", "from" }.Contains(r.ToLower()) || (lowercaseFollowingWords && !s.Trim().StartsWith(r)) ? r.ToLower() - : r.Substring(0, 1).ToUpper() + r.Substring(1))).Trim(' '); - } - - public static string Remove(this string s, string toRemove) - { - if (toRemove == "") return s; - return s.Replace(toRemove, ""); - } - - - - - - - #endregion - - #region Paths - - - public static bool HasParentPath(this string path) => path.LastIndexOf('/') > 0; - public static string GetParentPath(this string path) => path.HasParentPath() ? path.Substring(0, path.LastIndexOf('/')) : ""; - - public static string ToGlobalPath(this string localPath) => Application.dataPath + "/" + localPath.Substring(0, localPath.Length - 1); - public static string ToLocalPath(this string globalPath) => "Assets" + globalPath.Remove(Application.dataPath); - - - - public static string CombinePath(this string p, string p2) => Path.Combine(p, p2); - - public static bool IsSubpathOf(this string path, string of) => path.StartsWith(of + "/") || of == ""; - - public static string GetDirectory(this string pathOrDirectory) - { - var directory = pathOrDirectory.Contains('.') ? pathOrDirectory.Substring(0, pathOrDirectory.LastIndexOf('/')) : pathOrDirectory; - - if (directory.Contains('.')) - directory = directory.Substring(0, directory.LastIndexOf('/')); - - return directory; - - } - - public static bool DirectoryExists(this string pathOrDirectory) => Directory.Exists(pathOrDirectory.GetDirectory()); - - public static string EnsureDirExists(this string pathOrDirectory) // todo to EnsureDirectoryExists - { - var directory = pathOrDirectory.GetDirectory(); - - if (directory.HasParentPath() && !Directory.Exists(directory.GetParentPath())) - EnsureDirExists(directory.GetParentPath()); - - if (!Directory.Exists(directory)) - Directory.CreateDirectory(directory); - - return pathOrDirectory; - - } - - - - public static string ClearDir(this string dir) - { - if (!Directory.Exists(dir)) return dir; - - var diri = new DirectoryInfo(dir); - foreach (var r in diri.EnumerateFiles()) r.Delete(); - foreach (var r in diri.EnumerateDirectories()) r.Delete(true); - - return dir; - } - - - - - - -#if UNITY_EDITOR - - public static string EnsurePathIsUnique(this string path) - { - if (!path.DirectoryExists()) return path; - - var s = AssetDatabase.GenerateUniqueAssetPath(path); // returns empty if parent dir doesnt exist - - return s == "" ? path : s; - - } - - public static void EnsureDirExistsAndRevealInFinder(string dir) - { - EnsureDirExists(dir); - UnityEditor.EditorUtility.OpenWithDefaultApp(dir); - } - -#endif - - - - #endregion - - #region AssetDatabase - -#if UNITY_EDITOR - - public static AssetImporter GetImporter(this Object t) => AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(t)); - - public static string ToPath(this string guid) => AssetDatabase.GUIDToAssetPath(guid); // returns empty string if not found - public static List ToPaths(this IEnumerable guids) => guids.Select(r => r.ToPath()).ToList(); - - public static string GetFilename(this string path, bool withExtension = false) => withExtension ? Path.GetFileName(path) : Path.GetFileNameWithoutExtension(path); // prev GetName - public static string GetExtension(this string path) => Path.GetExtension(path); - - - public static string ToGuid(this string pathInProject) => AssetDatabase.AssetPathToGUID(pathInProject); - public static List ToGuids(this IEnumerable pathsInProject) => pathsInProject.Select(r => r.ToGuid()).ToList(); - - public static string GetPath(this Object o) => AssetDatabase.GetAssetPath(o); - public static string GetGuid(this Object o) => AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(o)); - - public static string GetScriptPath(string scriptName) => AssetDatabase.FindAssets("t: script " + scriptName, null).FirstOrDefault()?.ToPath() ?? "scirpt not found"; - - - public static bool IsValidGuid(this string guid) => AssetDatabase.AssetPathToGUID(AssetDatabase.GUIDToAssetPath(guid), AssetPathToGUIDOptions.OnlyExistingAssets) != ""; - - - - // toremove - public static Object LoadGuid(this string guid) => AssetDatabase.LoadAssetAtPath(guid.ToPath(), typeof(Object)); - public static T LoadGuid(this string guid) where T : Object => AssetDatabase.LoadAssetAtPath(guid.ToPath()); - - - - - public static List FindAllAssetsOfType_guids(Type type) => AssetDatabase.FindAssets("t:" + type.Name).ToList(); - public static List FindAllAssetsOfType_guids(Type type, string path) => AssetDatabase.FindAssets("t:" + type.Name, new[] { path }).ToList(); - public static List FindAllAssetsOfType() where T : Object => FindAllAssetsOfType_guids(typeof(T)).Select(r => (T)r.LoadGuid()).ToList(); - public static List FindAllAssetsOfType(string path) where T : Object => FindAllAssetsOfType_guids(typeof(T), path).Select(r => (T)r.LoadGuid()).ToList(); - - public static T Reimport(this T t) where T : Object { AssetDatabase.ImportAsset(t.GetPath(), ImportAssetOptions.ForceUpdate); return t; } - -#endif - - - - - - #endregion - - #region Serialization - - - [System.Serializable] - public class SerializableDictionary : Dictionary, ISerializationCallbackReceiver - { - [SerializeField] List keys = new(); - [SerializeField] List values = new(); - - public void OnBeforeSerialize() - { - keys.Clear(); - values.Clear(); - - foreach (KeyValuePair kvp in this) - { - keys.Add(kvp.Key); - values.Add(kvp.Value); - } - - } - public void OnAfterDeserialize() - { - this.Clear(); - - for (int i = 0; i < keys.Count; i++) - this[keys[i]] = values[i]; - - } - - } - - - - - - #endregion - - #region GlobalID - -#if UNITY_EDITOR - - [System.Serializable] - public struct GlobalID : System.IEquatable - { - public Object GetObject() => GlobalObjectId.GlobalObjectIdentifierToObjectSlow(globalObjectId); - public int GetObjectInstanceId() => GlobalObjectId.GlobalObjectIdentifierToInstanceIDSlow(globalObjectId); - - - public string guid => globalObjectId.assetGUID.ToString(); - public ulong fileId => globalObjectId.targetObjectId; - - public bool isNull => globalObjectId.identifierType == 0; - public bool isAsset => globalObjectId.identifierType == 1; - public bool isSceneObject => globalObjectId.identifierType == 2; - - public GlobalObjectId globalObjectId => _globalObjectId.Equals(default) && globalObjectIdString != null && GlobalObjectId.TryParse(globalObjectIdString, out var r) ? _globalObjectId = r : _globalObjectId; - public GlobalObjectId _globalObjectId; - - public GlobalID(Object o) => globalObjectIdString = (_globalObjectId = GlobalObjectId.GetGlobalObjectIdSlow(o)).ToString(); - public GlobalID(string s) => globalObjectIdString = GlobalObjectId.TryParse(s, out _globalObjectId) ? s : s; - - public string globalObjectIdString; - - - - public bool Equals(GlobalID other) => this.globalObjectIdString.Equals(other.globalObjectIdString); - - public static bool operator ==(GlobalID a, GlobalID b) => a.Equals(b); - public static bool operator !=(GlobalID a, GlobalID b) => !a.Equals(b); - - public override bool Equals(object other) => other is GlobalID otherglobalID && this.Equals(otherglobalID); - public override int GetHashCode() => globalObjectIdString == null ? 0 : globalObjectIdString.GetHashCode(); - - - public override string ToString() => globalObjectIdString; - - } - - public static GlobalID GetGlobalID(this Object o) => new(o); - public static GlobalID[] GetGlobalIDs(this IEnumerable instanceIds) - { - var unityGlobalIds = new GlobalObjectId[instanceIds.Count()]; - - GlobalObjectId.GetGlobalObjectIdsSlow(instanceIds.ToArray(), unityGlobalIds); - - var globalIds = unityGlobalIds.Select(r => new GlobalID(r.ToString())); - - return globalIds.ToArray(); - - } - - public static Object[] GetObjects(this IEnumerable globalIDs) - { - var goids = globalIDs.Select(r => r.globalObjectId).ToArray(); - - var objects = new Object[goids.Length]; - - GlobalObjectId.GlobalObjectIdentifiersToObjectsSlow(goids, objects); - - return objects; - - } - public static int[] GetObjectInstanceIds(this IEnumerable globalIDs) - { - var goids = globalIDs.Select(r => r.globalObjectId).ToArray(); - - var iids = new int[goids.Length]; - - GlobalObjectId.GlobalObjectIdentifiersToInstanceIDsSlow(goids, iids); - - return iids; - - } - - -#endif - - - - - #endregion - - #region Editor - -#if UNITY_EDITOR - - - public static class EditorUtils - { - - public static void OpenFolder(string path) - { - var folder = AssetDatabase.LoadAssetAtPath(path, typeof(Object)); - - var t = typeof(Editor).Assembly.GetType("UnityEditor.ProjectBrowser"); - var w = (EditorWindow)t.GetField("s_LastInteractedProjectBrowser").GetValue(null); - - var m_ListAreaState = t.GetField("m_ListAreaState", maxBindingFlags).GetValue(w); - - m_ListAreaState.GetType().GetField("m_SelectedInstanceIDs").SetValue(m_ListAreaState, new List { folder.GetInstanceID() }); - - t.GetMethod("OpenSelectedFolders", maxBindingFlags).Invoke(null, null); - - } - - public static void PingObject(Object o, bool select = false, bool focusProjectWindow = true) - { - if (select) - { - Selection.activeObject = null; - Selection.activeObject = o; - } - if (focusProjectWindow) EditorUtility.FocusProjectWindow(); - EditorGUIUtility.PingObject(o); - - } - public static void PingObject(string guid, bool select = false, bool focusProjectWindow = true) => PingObject(AssetDatabase.LoadAssetAtPath(guid.ToPath())); - - public static EditorWindow OpenObjectPicker(Object obj = null, bool allowSceneObjects = false, string searchFilter = "", int controlID = 0) where T : Object - { - EditorGUIUtility.ShowObjectPicker(obj, allowSceneObjects, searchFilter, controlID); - - return Resources.FindObjectsOfTypeAll(typeof(Editor).Assembly.GetType("UnityEditor.ObjectSelector")).FirstOrDefault() as EditorWindow; - - } - public static EditorWindow OpenColorPicker(System.Action colorChangedCallback, Color color, bool showAlpha = true, bool hdr = false) - { - typeof(Editor).Assembly.GetType("UnityEditor.ColorPicker").InvokeMethod("Show", colorChangedCallback, color, showAlpha, hdr); - - return typeof(Editor).Assembly.GetType("UnityEditor.ColorPicker").GetPropertyValue("instance"); - - } - - - - public static bool CheckUnityVersion(string versionQuery) - { - if (versionQueryCache.TryGetValue(versionQuery, out var cachedResult)) return cachedResult; - - if (versionQuery.Any(r => r.IsLetter() && !versionQuery.EndsWith(" or older") && !versionQuery.EndsWith(" or newer"))) throw new System.ArgumentException("Invalid unity version query"); - - - - - var curVersion = new string(Application.unityVersion.TakeWhile(r => !r.IsLetter()).ToArray()); - - var curMajor = int.Parse(curVersion.Split('.')[0]); - var curMinor = int.Parse(curVersion.Split('.')[1]); - var curPatch = int.Parse(curVersion.Split('.')[2]); - - - - - - var givenVersion = new string(versionQuery.TakeWhile(r => !r.IsWhitespace()).ToArray()); - - var isMinorGiven = givenVersion.Count(r => r == '.') >= 1; - var isPatchGiven = givenVersion.Count(r => r == '.') >= 2; - - var givenMajor = int.Parse(givenVersion.Split('.')[0]); - var givenMinor = isMinorGiven ? int.Parse(givenVersion.Split('.')[1]) : 0; - var givenPatch = isPatchGiven ? int.Parse(givenVersion.Split('.')[2]) : 0; - - - - - - - var curVersionCanBeNewer = versionQuery.Contains("or newer"); - var curVersionCanBeOlder = versionQuery.Contains("or older"); - - - if (curMajor > givenMajor) return versionQueryCache[versionQuery] = curVersionCanBeNewer; - if (curMajor < givenMajor) return versionQueryCache[versionQuery] = curVersionCanBeOlder; - - if (!isMinorGiven) return versionQueryCache[versionQuery] = true; - - - if (curMinor > givenMinor) return versionQueryCache[versionQuery] = curVersionCanBeNewer; - if (curMinor < givenMinor) return versionQueryCache[versionQuery] = curVersionCanBeOlder; - - if (!isPatchGiven) return versionQueryCache[versionQuery] = true; - - - if (curPatch > givenPatch) return versionQueryCache[versionQuery] = curVersionCanBeNewer; - if (curPatch < givenPatch) return versionQueryCache[versionQuery] = curVersionCanBeOlder; - - return versionQueryCache[versionQuery] = true; - - - - - // query examples: - // - // "2022.3.5 or newer" - // "2022.3.5 or older" - // "2022.3 or older" - // "2022.3" - // "2022" - - } - - static Dictionary versionQueryCache = new(); - - - - public static void SetSymbolDefinedInAsmdef(string asmdefName, string symbol, bool defined) - { - var isDefined = IsSymbolDefinedInAsmdef(asmdefName, symbol); - var shouldBeDefined = defined; - - if (shouldBeDefined && !isDefined) - DefineSymbolInAsmdef(asmdefName, symbol); - - if (!shouldBeDefined && isDefined) - UndefineSymbolInAsmdef(asmdefName, symbol); - - } - public static bool IsSymbolDefinedInAsmdef(string asmdefName, string symbol) - { - var path = AssetDatabase.FindAssets("t: asmdef " + asmdefName, null).First().ToPath(); - var importer = AssetImporter.GetAtPath(path); - - var editorType = typeof(Editor).Assembly.GetType("UnityEditor.AssemblyDefinitionImporterInspector"); - var editor = Editor.CreateEditor(importer, editorType); - - var state = editor.GetFieldValue("m_ExtraDataTargets").First(); - - - var definesList = state.GetFieldValue("versionDefines"); - var isSymbolDefined = Enumerable.Range(0, definesList.Count).Any(i => definesList[i].GetFieldValue("define") == symbol); - - - Object.DestroyImmediate(editor); - - return isSymbolDefined; - - } - - static void DefineSymbolInAsmdef(string asmdefName, string symbol) - { - var path = AssetDatabase.FindAssets("t: asmdef " + asmdefName, null).First().ToPath(); - var importer = AssetImporter.GetAtPath(path); - - var editorType = typeof(Editor).Assembly.GetType("UnityEditor.AssemblyDefinitionImporterInspector"); - var editor = Editor.CreateEditor(importer, editorType); - - var state = editor.GetFieldValue("m_ExtraDataTargets").First(); - - - var definesList = state.GetFieldValue("versionDefines"); - - var defineType = definesList.GetType().GenericTypeArguments[0]; - var newDefine = System.Activator.CreateInstance(defineType); - - newDefine.SetFieldValue("name", "Unity"); - newDefine.SetFieldValue("define", symbol); - - definesList.Add(newDefine); - - - editor.InvokeMethod("Apply"); - - Object.DestroyImmediate(editor); - - } - static void UndefineSymbolInAsmdef(string asmdefName, string symbol) - { - var path = AssetDatabase.FindAssets("t: asmdef " + asmdefName, null).First().ToPath(); - var importer = AssetImporter.GetAtPath(path); - - var editorType = typeof(Editor).Assembly.GetType("UnityEditor.AssemblyDefinitionImporterInspector"); - var editor = Editor.CreateEditor(importer, editorType); - - var state = editor.GetFieldValue("m_ExtraDataTargets").First(); - - - var definesList = state.GetFieldValue("versionDefines"); - - var defineIndex = Enumerable.Range(0, definesList.Count).First(i => definesList[i].GetFieldValue("define") == symbol); - - definesList.RemoveAt(defineIndex); - - - editor.InvokeMethod("Apply"); - - Object.DestroyImmediate(editor); - - } - - - - - public static int GetCurrendUndoGroupIndex() - { - var args = new object[] { _dummyList, 0 }; - - typeof(Undo).GetMethodInfo("GetRecords", typeof(List), typeof(int).MakeByRefType()) - .Invoke(null, args); - - - return (int)args[1]; - - } - - static List _dummyList = new(); - - - - - - public static void Hide(string path) - { - if (IsHidden(path)) return; - - if (File.Exists(path)) - File.Move(path, path + "~"); - - - path += ".meta"; - if (File.Exists(path)) - File.Move(path, path + "~"); - } - public static void Unhide(string path) - { - if (!IsHidden(path)) return; - if (path.EndsWith("~")) path = path.Substring(0, path.Length - 1); - - if (File.Exists(path + "~")) - File.Move(path + "~", path); - - path += ".meta"; - if (File.Exists(path + "~")) - File.Move(path + "~", path); - } - public static bool IsHidden(string path) => path.EndsWith("~") || File.Exists(path + "~"); - - - public static void CopyDirectoryDeep(string sourcePath, string destinationPath) - { - CopyDirectoryRecursively(sourcePath, destinationPath); - - var metas = GetFilesRecursively(destinationPath, (f) => f.EndsWith(".meta")); - var guidTable = new List<(string originalGuid, string newGuid)>(); - - foreach (string meta in metas) - { - StreamReader file = new(meta); - file.ReadLine(); - string guidLine = file.ReadLine(); - file.Close(); - string originalGuid = guidLine.Substring(6, guidLine.Length - 6); - string newGuid = GUID.Generate().ToString().Replace("-", ""); - guidTable.Add((originalGuid, newGuid)); - } - - var allFiles = GetFilesRecursively(destinationPath); - - foreach (string fileToModify in allFiles) - { - string content = File.ReadAllText(fileToModify); - - foreach (var guidPair in guidTable) - { - content = content.Replace(guidPair.originalGuid, guidPair.newGuid); - } - - File.WriteAllText(fileToModify, content); - } - - AssetDatabase.Refresh(); - } - - private static void CopyDirectoryRecursively(string sourceDirName, string destDirName) - { - DirectoryInfo dir = new(sourceDirName); - - DirectoryInfo[] dirs = dir.GetDirectories(); - - if (!Directory.Exists(destDirName)) - { - Directory.CreateDirectory(destDirName); - } - - FileInfo[] files = dir.GetFiles(); - foreach (FileInfo file in files) - { - string temppath = Path.Combine(destDirName, file.Name); - file.CopyTo(temppath, false); - } - - foreach (DirectoryInfo subdir in dirs) - { - string temppath = Path.Combine(destDirName, subdir.Name); - CopyDirectoryRecursively(subdir.FullName, temppath); - } - } - - private static List GetFilesRecursively(string path, System.Func criteria = null, List files = null) - { - if (files == null) - { - files = new List(); - } - - files.AddRange(Directory.GetFiles(path).Where(f => criteria == null || criteria(f))); - - foreach (string directory in Directory.GetDirectories(path)) - { - GetFilesRecursively(directory, criteria, files); - } - - return files; - } - - - - - - // for non-extension methods - - } - - - public static class EditorPrefsCached - { - public static int GetInt(string key, int defaultValue = 0) - { - if (ints_byKey.ContainsKey(key)) - return ints_byKey[key]; - else - return ints_byKey[key] = EditorPrefs.GetInt(key, defaultValue); - - } - public static bool GetBool(string key, bool defaultValue = false) - { - if (bools_byKey.ContainsKey(key)) - return bools_byKey[key]; - else - return bools_byKey[key] = EditorPrefs.GetBool(key, defaultValue); - - } - public static float GetFloat(string key, float defaultValue = 0) - { - if (floats_byKey.ContainsKey(key)) - return floats_byKey[key]; - else - return floats_byKey[key] = EditorPrefs.GetFloat(key, defaultValue); - - } - public static string GetString(string key, string defaultValue = "") - { - if (strings_byKey.ContainsKey(key)) - return strings_byKey[key]; - else - return strings_byKey[key] = EditorPrefs.GetString(key, defaultValue); - - } - - public static void SetInt(string key, int value) - { - ints_byKey[key] = value; - - EditorPrefs.SetInt(key, value); - - } - public static void SetBool(string key, bool value) - { - bools_byKey[key] = value; - - EditorPrefs.SetBool(key, value); - - } - public static void SetFloat(string key, float value) - { - floats_byKey[key] = value; - - EditorPrefs.SetFloat(key, value); - - } - public static void SetString(string key, string value) - { - strings_byKey[key] = value; - - EditorPrefs.SetString(key, value); - - } - - - static Dictionary ints_byKey = new(); - static Dictionary bools_byKey = new(); - static Dictionary floats_byKey = new(); - static Dictionary strings_byKey = new(); - - } - - public static class ProjectPrefs - { - public static int GetInt(string key, int defaultValue = 0) => EditorPrefsCached.GetInt(key + projectId, defaultValue); - public static bool GetBool(string key, bool defaultValue = false) => EditorPrefsCached.GetBool(key + projectId, defaultValue); - public static float GetFloat(string key, float defaultValue = 0) => EditorPrefsCached.GetFloat(key + projectId, defaultValue); - public static string GetString(string key, string defaultValue = "") => EditorPrefsCached.GetString(key + projectId, defaultValue); - - public static void SetInt(string key, int value) => EditorPrefsCached.SetInt(key + projectId, value); - public static void SetBool(string key, bool value) => EditorPrefsCached.SetBool(key + projectId, value); - public static void SetFloat(string key, float value) => EditorPrefsCached.SetFloat(key + projectId, value); - public static void SetString(string key, string value) => EditorPrefsCached.SetString(key + projectId, value); - - - - public static bool HasKey(string key) => EditorPrefs.HasKey(key + projectId); - public static void DeleteKey(string key) => EditorPrefs.DeleteKey(key + projectId); - - - - public static int projectId => PlayerSettings.productGUID.GetHashCode(); - - } - - - - public static void RecordUndo(this Object o, string operationName = "") => Undo.RecordObject(o, operationName); - public static void Dirty(this Object o) => UnityEditor.EditorUtility.SetDirty(o); - public static void Save(this Object o) => AssetDatabase.SaveAssetIfDirty(o); - - - - public static void SelectInInspector(this Object[] objects, bool frameInHierarchy = false, bool frameInProject = false) - { - void setHierarchyLocked(bool isLocked) => allHierarchies.ForEach(r => r?.GetMemberValue("m_SceneHierarchy")?.SetMemberValue("m_RectSelectInProgress", true)); - void setProjectLocked(bool isLocked) => allProjectBrowsers.ForEach(r => r?.SetMemberValue("m_InternalSelectionChange", isLocked)); - - - if (!frameInHierarchy) setHierarchyLocked(true); - if (!frameInProject) setProjectLocked(true); - - Selection.objects = objects?.ToArray(); - - if (!frameInHierarchy) EditorApplication.delayCall += () => setHierarchyLocked(false); - if (!frameInProject) EditorApplication.delayCall += () => setProjectLocked(false); - - } - public static void SelectInInspector(this Object obj, bool frameInHierarchy = false, bool frameInProject = false) => new[] { obj }.SelectInInspector(frameInHierarchy, frameInProject); - - static IEnumerable allHierarchies => _allHierarchies ??= typeof(Editor).Assembly.GetType("UnityEditor.SceneHierarchyWindow").GetFieldValue("s_SceneHierarchyWindows").Cast(); - static IEnumerable _allHierarchies; - - static IEnumerable allProjectBrowsers => _allProjectBrowsers ??= typeof(Editor).Assembly.GetType("UnityEditor.ProjectBrowser").GetFieldValue("s_ProjectBrowsers").Cast(); - static IEnumerable _allProjectBrowsers; - - - - public static void MoveTo(this EditorWindow window, Vector2 position, bool ensureFitsOnScreen = true) - { - if (!ensureFitsOnScreen) { window.position = window.position.SetPos(position); return; } - - var windowRect = window.position; - var unityWindowRect = EditorGUIUtility.GetMainWindowPosition(); - - position.x = position.x.Max(unityWindowRect.position.x); - position.y = position.y.Max(unityWindowRect.position.y); - - position.x = position.x.Min(unityWindowRect.xMax - windowRect.width); - position.y = position.y.Min(unityWindowRect.yMax - windowRect.height); - - window.position = windowRect.SetPos(position); - - } - - - -#endif - - #endregion - - } - - public static class VGUI - { - - #region Drawing - - - public static Rect Draw(this Rect rect, Color color) - { - EditorGUI.DrawRect(rect, color); - - return rect; - - } - public static Rect Draw(this Rect rect) => rect.Draw(Color.black); - - public static Rect DrawOutline(this Rect rect, Color color, float thickness = 1) - { - - rect.SetWidth(thickness).Draw(color); - rect.SetWidthFromRight(thickness).Draw(color); - - rect.SetHeight(thickness).Draw(color); - rect.SetHeightFromBottom(thickness).Draw(color); - - - return rect; - - } - public static Rect DrawOutline(this Rect rect, float thickness = 1) => rect.DrawOutline(Color.black, thickness); - - - - - public static Rect DrawRounded(this Rect rect, Color color, int cornerRadius) - { - if (!curEvent.isRepaint) return rect; - - cornerRadius = cornerRadius.Min((rect.height / 2).FloorToInt()).Min((rect.width / 2).FloorToInt()); - - if (cornerRadius < 0) return rect; - - GUIStyle style; - - void getStyle() - { - if (_roundedStylesByCornerRadius.TryGetValue(cornerRadius, out style)) return; - - var pixelsPerPoint = 2; - - var res = cornerRadius * 2 * pixelsPerPoint; - var pixels = new Color[res * res]; - - var white = Greyscale(1, 1); - var clear = Greyscale(1, 0); - var halfRes = res / 2; - - for (int x = 0; x < res; x++) - for (int y = 0; y < res; y++) - { - var sqrMagnitude = (new Vector2(x - halfRes + .5f, y - halfRes + .5f)).sqrMagnitude; - pixels[x + y * res] = sqrMagnitude <= halfRes * halfRes ? white : clear; - } - - var texture = new Texture2D(res, res); - texture.SetPropertyValue("pixelsPerPoint", pixelsPerPoint); - texture.hideFlags = HideFlags.DontSave; - texture.SetPixels(pixels); - texture.Apply(); - - - - style = new GUIStyle(); - style.normal.background = texture; - style.alignment = TextAnchor.MiddleCenter; - style.border = new RectOffset(cornerRadius, cornerRadius, cornerRadius, cornerRadius); - - - _roundedStylesByCornerRadius[cornerRadius] = style; - - } - void draw() - { - SetGUIColor(color); - - style.Draw(rect, false, false, false, false); - - ResetGUIColor(); - - } - - getStyle(); - draw(); - - return rect; - - } - public static Rect DrawRounded(this Rect rect, Color color, float cornerRadius) => rect.DrawRounded(color, cornerRadius.RoundToInt()); - - static Dictionary _roundedStylesByCornerRadius = new(); - - - - - public static Rect DrawBlurred(this Rect rect, Color color, int blurRadius) - { - if (!curEvent.isRepaint) return rect; - - var pixelsPerPoint = .5f; - // var pixelsPerPoint = 1f; - - var blurRadiusScaled = (blurRadius * pixelsPerPoint).RoundToInt().Max(1).Min(123); - - var croppedRectWidth = (rect.width * pixelsPerPoint).RoundToInt().Min(blurRadiusScaled * 2); - var croppedRectHeight = (rect.height * pixelsPerPoint).RoundToInt().Min(blurRadiusScaled * 2); - - var textureWidth = croppedRectWidth + blurRadiusScaled * 2; - var textureHeight = croppedRectHeight + blurRadiusScaled * 2; - - if (textureWidth <= 0 || textureWidth > 1232) return rect; - if (textureHeight <= 0 || textureHeight > 1232) return rect; - - - GUIStyle style; - - void getStyle() - { - if (_blurredStylesByTextureSize.TryGetValue((textureWidth, textureHeight), out style)) return; - - // VDebug.LogStart(blurRadius + ""); - - var pixels = new Color[textureWidth * textureHeight]; - var kernel = GaussianKernel.GenerateArray(blurRadiusScaled * 2 + 1); - - for (int x = 0; x < textureWidth; x++) - for (int y = 0; y < textureHeight; y++) - { - var sum = 0f; - - for (int xSample = (x - blurRadiusScaled).Max(blurRadiusScaled); xSample <= (x + blurRadiusScaled).Min(textureWidth - 1 - blurRadiusScaled); xSample++) - for (int ySample = (y - blurRadiusScaled).Max(blurRadiusScaled); ySample <= (y + blurRadiusScaled).Min(textureHeight - 1 - blurRadiusScaled); ySample++) - sum += kernel[blurRadiusScaled + xSample - x, blurRadiusScaled + ySample - y]; - - pixels[x + y * textureWidth] = Greyscale(1, sum); - - } - - var texture = new Texture2D(textureWidth, textureHeight); - texture.SetPropertyValue("pixelsPerPoint", pixelsPerPoint); - texture.hideFlags = HideFlags.DontSave; - texture.SetPixels(pixels); - texture.Apply(); - - - style = new GUIStyle(); - style.normal.background = texture; - style.alignment = TextAnchor.MiddleCenter; - - var borderX = ((textureWidth / 2f - 1) / pixelsPerPoint).FloorToInt(); - var borderY = ((textureHeight / 2f - 1) / pixelsPerPoint).FloorToInt(); - style.border = new RectOffset(borderX, borderX, borderY, borderY); - - _blurredStylesByTextureSize[(textureWidth, textureHeight)] = style; - - // VDebug.LogFinish(); - - } - void draw() - { - SetGUIColor(color); - - style.Draw(rect.SetSizeFromMid(rect.width + blurRadius * 2, rect.height + blurRadius * 2), false, false, false, false); - - ResetGUIColor(); - - } - - getStyle(); - draw(); - - return rect; - - } - public static Rect DrawBlurred(this Rect rect, Color color, float blurRadius) => rect.DrawBlurred(color, blurRadius.RoundToInt()); - - static Dictionary<(int, int), GUIStyle> _blurredStylesByTextureSize = new(); - - - - - static void DrawCurtain(this Rect rect, Color color, int dir) - { - void genTextures() - { - if (_gradientTextures != null) return; - - _gradientTextures = new Texture2D[4]; - - // var pixels = Enumerable.Range(0, 256).Select(r => Greyscale(1, r / 255f)); - var pixels = Enumerable.Range(0, 256).Select(r => Greyscale(1, (r / 255f).Smoothstep())); - - var up = new Texture2D(1, 256); - up.SetPixels(pixels.Reverse().ToArray()); - up.Apply(); - up.hideFlags = HideFlags.DontSave; - up.wrapMode = TextureWrapMode.Clamp; - _gradientTextures[0] = up; - - var down = new Texture2D(1, 256); - down.SetPixels(pixels.ToArray()); - down.Apply(); - down.hideFlags = HideFlags.DontSave; - down.wrapMode = TextureWrapMode.Clamp; - _gradientTextures[1] = down; - - var left = new Texture2D(256, 1); - left.SetPixels(pixels.ToArray()); - left.Apply(); - left.hideFlags = HideFlags.DontSave; - left.wrapMode = TextureWrapMode.Clamp; - _gradientTextures[2] = left; - - var right = new Texture2D(256, 1); - right.SetPixels(pixels.Reverse().ToArray()); - right.Apply(); - right.hideFlags = HideFlags.DontSave; - right.wrapMode = TextureWrapMode.Clamp; - _gradientTextures[3] = right; - - } - void draw() - { - SetGUIColor(color); - - GUI.DrawTexture(rect, _gradientTextures[dir]); - - ResetGUIColor(); - - } - - genTextures(); - draw(); - - } - - static Texture2D[] _gradientTextures; - - public static void DrawCurtainUp(this Rect rect, Color color) => rect.DrawCurtain(color, 0); - public static void DrawCurtainDown(this Rect rect, Color color) => rect.DrawCurtain(color, 1); - public static void DrawCurtainLeft(this Rect rect, Color color) => rect.DrawCurtain(color, 2); - public static void DrawCurtainRight(this Rect rect, Color color) => rect.DrawCurtain(color, 3); - - - - - - - #endregion - - #region Events - - - public class WrappedEvent - { - public Event e; - - public bool isRepaint => e.type == EventType.Repaint; - public bool isLayout => e.type == EventType.Layout; - public bool isUsed => e.type == EventType.Used; - public bool isMouseLeaveWindow => e.type == EventType.MouseLeaveWindow; - public bool isMouseEnterWindow => e.type == EventType.MouseEnterWindow; - public bool isContextClick => e.type == EventType.ContextClick; - - public bool isKeyDown => e.type == EventType.KeyDown; - public bool isKeyUp => e.type == EventType.KeyUp; - public KeyCode keyCode => e.keyCode; - public char characted => e.character; - - public bool isExecuteCommand => e.type == EventType.ExecuteCommand; - public string commandName => e.commandName; - - public bool isMouse => e.isMouse; - public bool isMouseDown => e.type == EventType.MouseDown; - public bool isMouseUp => e.type == EventType.MouseUp; - public bool isMouseDrag => e.type == EventType.MouseDrag; - public bool isMouseMove => e.type == EventType.MouseMove; - public bool isScroll => e.type == EventType.ScrollWheel; - public int mouseButton => e.button; - public int clickCount => e.clickCount; - public Vector2 mousePosition => e.mousePosition; - public Vector2 mousePosition_screenSpace => GUIUtility.GUIToScreenPoint(e.mousePosition); - public Vector2 mouseDelta => e.delta; - - public bool isDragUpdate => e.type == EventType.DragUpdated; - public bool isDragPerform => e.type == EventType.DragPerform; - public bool isDragExit => e.type == EventType.DragExited; - - public EventModifiers modifiers => e.modifiers; - public bool holdingAnyModifierKey => modifiers != EventModifiers.None; - - public bool holdingAlt => e.alt; - public bool holdingShift => e.shift; - public bool holdingCtrl => e.control; - public bool holdingCmd => e.command; - public bool holdingCmdOrCtrl => e.command || e.control; - - public bool holdingAltOnly => e.modifiers == EventModifiers.Alt; // in some sessions FunctionKey is always pressed? - public bool holdingShiftOnly => e.modifiers == EventModifiers.Shift; // in some sessions FunctionKey is always pressed? - public bool holdingCtrlOnly => e.modifiers == EventModifiers.Control; - public bool holdingCmdOnly => e.modifiers == EventModifiers.Command; - public bool holdingCmdOrCtrlOnly => (e.modifiers == EventModifiers.Command || e.modifiers == EventModifiers.Control); - - public EventType type => e.type; - - public void Use() => e?.Use(); - - - public WrappedEvent(Event e) => this.e = e; - - public override string ToString() => e.ToString(); - - } - - public static WrappedEvent Wrap(this Event e) => new(e); - - public static WrappedEvent curEvent => _curEvent ??= typeof(Event).GetFieldValue("s_Current").Wrap(); - static WrappedEvent _curEvent; - - - - - - #endregion - - #region Shortcuts - - - public static Rect lastRect => GUILayoutUtility.GetLastRect(); - - public static bool isDarkTheme => EditorGUIUtility.isProSkin; - - public static bool IsHovered(this Rect r) => r.Contains(curEvent.mousePosition); - - public static float GetLabelWidth(this string s) => GUI.skin.label.CalcSize(new GUIContent(s)).x; - public static float GetLabelWidth(this string s, int fontSize) - { - SetLabelFontSize(fontSize); - - var r = s.GetLabelWidth(); - - ResetLabelStyle(); - - return r; - - } - public static float GetLabelWidth(this string s, bool isBold) - { - if (isBold) - SetLabelBold(); - - var r = s.GetLabelWidth(); - - if (isBold) - ResetLabelStyle(); - - return r; - - } - public static float GetLabelWidth(this string s, int fontSize, bool isBold) - { - if (isBold) - SetLabelBold(); - - SetLabelFontSize(fontSize); - - var r = s.GetLabelWidth(); - - ResetLabelStyle(); - - return r; - - } - - public static void SetGUIEnabled(bool enabled) { _prevGuiEnabled = GUI.enabled; GUI.enabled = enabled; } - public static void ResetGUIEnabled() => GUI.enabled = _prevGuiEnabled; - static bool _prevGuiEnabled = true; - - public static void SetLabelFontSize(int size) => GUI.skin.label.fontSize = size; - public static void SetLabelBold() => GUI.skin.label.fontStyle = FontStyle.Bold; - public static void SetLabelAlignmentCenter() => GUI.skin.label.alignment = TextAnchor.MiddleCenter; - public static void ResetLabelStyle() - { - GUI.skin.label.fontSize = 0; - GUI.skin.label.fontStyle = FontStyle.Normal; - GUI.skin.label.alignment = TextAnchor.MiddleLeft; - GUI.skin.label.wordWrap = false; - } - - - public static void SetGUIColor(Color c) - { - _guiColorStack.Push(GUI.color); - - GUI.color *= c; - - } - public static void ResetGUIColor() - { - GUI.color = _guiColorStack.Pop(); - } - - static Stack _guiColorStack = new(); - - - - public static float editorDeltaTime = .0166f; - - static void EditorDeltaTime_Update() - { - editorDeltaTime = (float)(EditorApplication.timeSinceStartup - _lastUpdateTime); - - _lastUpdateTime = EditorApplication.timeSinceStartup; - - } - static double _lastUpdateTime; - - [InitializeOnLoadMethod] - static void EditorDeltaTime_Subscribe() - { - EditorApplication.update -= EditorDeltaTime_Update; - EditorApplication.update += EditorDeltaTime_Update; - } - - - - - #endregion - - #region Controls - - - public static bool IconButton(Rect rect, string iconName, float iconSize = default, Color color = default, Color colorHovered = default, Color colorPressed = default) - { - var id = EditorGUIUtility.GUIToScreenRect(rect).GetHashCode();// GUIUtility.GetControlID(FocusType.Passive, rect); - var isPressed = id == _pressedIconButtonId; - - var wasActivated = false; - - void icon() - { - if (!curEvent.isRepaint) return; - - - if (color == default) - color = Color.white; - - if (colorHovered == default) - colorHovered = Color.white; - - if (colorPressed == default) - colorPressed = Color.white.SetAlpha(.6f); - - - if (rect.IsHovered()) - color = colorHovered; - - if (isPressed) - color = colorPressed; - - - if (iconSize == default) - iconSize = rect.width.Min(rect.height); - - var iconRect = rect.SetSizeFromMid(iconSize); - - - - SetGUIColor(color); - - GUI.DrawTexture(iconRect, EditorIcons.GetIcon(iconName)); - - ResetGUIColor(); - - - } - void mouseDown() - { - if (!curEvent.isMouseDown) return; - if (!rect.IsHovered()) return; - - _pressedIconButtonId = id; - - curEvent.Use(); - - } - void mouseUp() - { - if (!curEvent.isMouseUp) return; - if (!isPressed) return; - - _pressedIconButtonId = 0; - - if (rect.IsHovered()) - wasActivated = true; - - curEvent.Use(); - - } - void mouseDrag() - { - if (!curEvent.isMouseDrag) return; - if (!isPressed) return; - - curEvent.Use(); - - } - - rect.MarkInteractive(); - - icon(); - mouseDown(); - mouseUp(); - mouseDrag(); - - return wasActivated; - - } - - static int _pressedIconButtonId; - - - - - - #endregion - - #region Layout - - - public static void Space(float px = 6) => GUILayout.Space(px); - - public static Rect ExpandWidthLabelRect() { GUILayout.Label(""/* , GUILayout.Height(0) */, GUILayout.ExpandWidth(true)); return lastRect; } - public static Rect ExpandWidthLabelRect(float height) { GUILayout.Label("", GUILayout.Height(height), GUILayout.ExpandWidth(true)); return lastRect; } - - - - - public static void BeginIndent(float f) - { - GUILayout.BeginHorizontal(); - GUILayout.Space(f); - GUILayout.BeginVertical(); - - _indentLabelWidthStack.Push(EditorGUIUtility.labelWidth); - - EditorGUIUtility.labelWidth -= f; - } - - public static void EndIndent(float f = 0) - { - GUILayout.EndVertical(); - GUILayout.Space(f); - GUILayout.EndHorizontal(); - - EditorGUIUtility.labelWidth = _indentLabelWidthStack.Pop(); - } - static Stack _indentLabelWidthStack = new(); - - - - - - public static void Horizontal() { if (__hor) GUILayout.EndHorizontal(); else GUILayout.BeginHorizontal(); __hor = !__hor; } - public static void Vertical() { if (__v) GUILayout.EndVertical(); else GUILayout.BeginVertical(); __v = !__v; } - public static void Area(Rect r) { if (__a) GUILayout.EndArea(); else GUILayout.BeginArea(r); __a = !__a; } - public static void Area() { if (__a) GUILayout.EndArea(); __a = !__a; } - public static void ResetUIBools() { __a = __hor = __v = false; _prevGuiEnabled = true; } - static bool __hor, __a, __v; - - - - - - #endregion - - #region GUIColors - - - public static class GUIColors - { - public static Color windowBackground => isDarkTheme ? Greyscale(.22f) : Greyscale(.78f); // prev backgroundCol - public static Color pressedButtonBackground => isDarkTheme ? new Color(.48f, .76f, 1f, 1f) * 1.4f : new Color(.48f, .7f, 1f, 1f) * 1.2f; // prev pressedButtonCol - public static Color greyedOutTint => Greyscale(.7f); - public static Color selectedBackground => isDarkTheme ? new Color(.17f, .365f, .535f) : new Color(.2f, .375f, .555f) * 1.2f; - } - - - - - #endregion - - #region EditorIcons - - - public static partial class EditorIcons - { - public static Texture2D GetIcon(string iconNameOrPath) - { - if (icons_byName.TryGetValue(iconNameOrPath, out var cachedResult) && cachedResult != null) return cachedResult; - - Texture2D icon = null; - - void getCustom() - { - if (icon) return; - if (!customIcons.ContainsKey(iconNameOrPath)) return; - - var pngBytesString = customIcons[iconNameOrPath]; - var pngBytes = pngBytesString.Split("-").Select(r => System.Convert.ToByte(r, 16)).ToArray(); - - icon = new Texture2D(1, 1); - - icon.LoadImage(pngBytes); - - } - void getBuiltin() - { - if (icon) return; - - icon = typeof(EditorGUIUtility).InvokeMethod("LoadIcon", iconNameOrPath) as Texture2D; - - } - void getEmpty() - { - if (icon) return; - - icon = new Texture2D(1, 1); - - } - - getCustom(); - getBuiltin(); - getEmpty(); - - return icons_byName[iconNameOrPath] = icon; - - } - - static Dictionary icons_byName = new(); - - - static Dictionary customIcons = new() - { - ["Chevron Left"] = "89-50-4E-47-0D-0A-1A-0A-00-00-00-0D-49-48-44-52-00-00-00-40-00-00-00-40-08-06-00-00-00-AA-69-71-DE-00-00-00-09-70-48-59-73-00-00-0B-13-00-00-0B-13-01-00-9A-9C-18-00-00-00-01-73-52-47-42-00-AE-CE-1C-E9-00-00-00-04-67-41-4D-41-00-00-B1-8F-0B-FC-61-05-00-00-01-29-49-44-41-54-78-01-ED-9B-CD-71-83-30-14-06-3F-A5-02-4A-71-09-A4-A3-B4-94-0A-28-01-77-10-77-90-16-D2-81-A2-A7-21-A7-FC-8C-A4-60-23-9E-76-67-34-1C-2C-1F-76-2D-30-C3-08-09-00-00-60-58-82-3A-25-C6-38-A7-C3-25-8D-29-8D-6B-08-E1-AA-11-48-E2-53-1A-6B-FC-CE-62-9F-C9-33-9B-FC-5B-FC-9D-55-5E-29-90-FF-62-D6-8E-3C-A9-03-B6-A5-6D-BF-EE-A5-60-7A-C9-9C-62-0E-0F-50-29-6F-F8-B9-0E-54-2C-FB-BB-9D-02-87-D1-28-BF-C8-03-8D-F2-36-FF-FC-CB-1F-79-E4-91-47-1E-79-E4-91-47-1E-79-E4-91-F7-21-6F-C4-C1-E5-5F-62-1D-7E-E4-8D-24-F3-3E-B2-FC-74-76-F9-2E-1E-8A-9E-9A-B3-9F-02-7B-AC-80-D7-8A-B9-F6-E4-77-ED-2D-C2-BF-88-A3-DF-03-18-44-10-11-32-44-10-11-32-44-10-11-32-44-10-11-32-44-10-11-32-44-10-11-32-44-50-73-04-5F-FB-04-1B-23-CC-DA-91-43-1F-89-85-10-3E-D2-E1-39-8D-5B-C5-D7-7C-ED-13-6C-88-E0-73-BF-70-C5-E9-30-CB-2B-05-11-7C-EC-13-FC-8B-2D-C2-F2-83-FC-1A-EF-F0-37-D8-FB-0B-13-36-EC-1A-71-1B-E6-85-09-00-00-80-C7-F1-09-79-C0-DD-81-D6-B5-69-91-00-00-00-00-49-45-4E-44-AE-42-60-82", - ["Chevron Right"] = "89-50-4E-47-0D-0A-1A-0A-00-00-00-0D-49-48-44-52-00-00-00-40-00-00-00-40-08-06-00-00-00-AA-69-71-DE-00-00-00-09-70-48-59-73-00-00-0B-13-00-00-0B-13-01-00-9A-9C-18-00-00-00-01-73-52-47-42-00-AE-CE-1C-E9-00-00-00-04-67-41-4D-41-00-00-B1-8F-0B-FC-61-05-00-00-01-1A-49-44-41-54-78-01-ED-9B-D1-0D-82-30-10-86-AF-4E-C0-28-8E-80-1B-39-82-1B-39-02-6C-00-1B-B8-82-1B-9C-6D-D0-27-05-69-4B-48-B9-7E-5F-D2-F0-40-5F-FE-2F-B4-47-9A-AB-08-00-00-40-B5-38-D9-08-55-6D-FD-E3-EC-47-E3-47-EF-9C-EB-A5-06-7C-F0-C6-8F-4E-BF-B9-87-77-62-9D-77-D0-39-06-D3-12-C2-67-AF-FF-29-5A-C2-49-F2-68-57-CC-09-FB-42-57-AA-84-5C-01-CF-95-F3-8A-95-90-2B-60-8C-98-5B-F4-97-90-CC-4C-05-38-EC-9E-10-8D-4E-65-70-88-73-80-04-24-20-01-09-48-40-02-12-90-80-04-24-20-01-09-48-40-42-04-37-B1-44-82-84-87-58-23-41-C2-A6-CB-20-F7-48-0C-72-A8-7A-09-68-DA-26-78-15-0B-24-86-1F-C4-02-5A-F3-3F-00-E1-09-4F-78-C2-13-9E-F0-84-27-3C-E1-09-4F-78-3B-E7-7B-BA-DC-27-68-3E-FC-9A-3E-C1-A2-C3-EF-D1-27-F8-21-74-94-5D-9C-73-6B-5B-EB-76-61-AF-3E-C1-22-C3-67-A3-06-5A-65-B3-D1-E5-3E-41-DB-E1-03-3A-95-C1-5F-95-A0-3B-42-F8-AD-2F-4C-84-11-D6-F9-58-CD-85-09-00-00-80-E3-F2-02-5D-3B-DF-D0-96-78-5C-6E-00-00-00-00-49-45-4E-44-AE-42-60-82", - ["Search_"] = "89-50-4E-47-0D-0A-1A-0A-00-00-00-0D-49-48-44-52-00-00-00-20-00-00-00-20-08-06-00-00-00-73-7A-7A-F4-00-00-00-09-70-48-59-73-00-00-0B-13-00-00-0B-13-01-00-9A-9C-18-00-00-00-01-73-52-47-42-00-AE-CE-1C-E9-00-00-00-04-67-41-4D-41-00-00-B1-8F-0B-FC-61-05-00-00-02-00-49-44-41-54-78-01-ED-56-3D-4F-02-41-10-1D-3E-22-C6-C4-CA-D0-9A-58-6B-87-8D-12-6B-0B-1B-7F-07-85-89-95-F4-34-D6-F2-07-2C-FD-23-D0-41-A2-8D-FF-00-8A-0B-0D-7A-70-7C-1C-EB-7B-B8-47-16-C4-70-7B-77-1C-0D-2F-B9-DC-DE-DD-CE-CE-DB-99-D9-37-27-B2-C7-8E-91-B1-99-EC-38-CE-71-A1-50-38-E0-78-34-1A-8D-8B-C5-E2-97-6C-1B-4A-A9-43-38-AB-8E-C7-E3-CF-D9-6C-E6-29-0D-DF-F7-5D-BE-C3-B7-1A-E7-C8-36-E0-BA-EE-1D-1C-39-6A-03-40-CC-E5-5C-49-12-9E-E7-55-B0-B0-AF-1D-F8-93-C9-A4-81-77-0F-B8-97-79-E9-71-DB-20-E1-83-44-45-92-00-77-13-38-47-04-BA-83-C1-E0-FA-BF-B9-20-71-85-39-3D-83-44-BC-48-30-9F-0C-A9-5E-B0-D7-E9-74-8E-36-D9-70-0E-89-6A-C2-4E-AC-9A-D0-45-35-07-43-1D-D6-0E-51-2A-07-51-63-D1-4A-54-B0-B2-B5-F3-B6-58-02-36-4D-DA-72-8D-B0-36-59-F3-81-E7-3C-9B-CD-9E-72-8C-75-5E-C5-12-B0-79-E3-3D-9F-CF-9F-71-AD-30-36-4B-04-28-32-B9-5C-6E-9E-F3-4C-26-D3-12-4B-4C-A7-D3-96-B6-2D-04-82-65-45-60-17-58-22-40-79-65-0D-71-8C-7B-49-2C-81-D0-97-B4-AD-CB-B5-24-0A-8C-22-6C-8A-25-70-04-DB-B6-45-F8-07-3C-42-86-FA-59-1D-43-E3-F8-D6-24-2A-28-22-81-FE-53-5C-C2-0A-11-45-2B-E8-0B-2A-6E-73-32-A5-98-0B-87-90-E2-6E-62-52-6C-90-58-34-A3-40-98-90-DB-D5-66-D4-80-F3-45-C3-62-03-A3-ED-70-38-BC-C1-AB-0B-89-0B-1D-09-57-6D-00-53-16-EC-1C-24-6E-F1-3C-82-DD-37-08-5F-4A-5C-A8-DF-1F-92-1A-2B-1B-42-E3-1A-ED-D7-D3-3F-24-D5-20-E7-DC-39-9D-1B-73-26-F8-7E-2F-49-81-F2-DA-EF-F7-4F-78-AD-93-5A-38-3B-E7-CE-D5-F2-CF-CA-14-A9-8A-DE-9C-6C-C1-B0-73-E7-AB-69-42-6A-5E-24-2D-30-EC-DC-F9-1A-12-8F-92-16-50-0B-4F-6B-8A-F5-5D-D2-04-76-5C-37-09-20-3D-75-49-1B-28-C0-67-5C-1F-74-0E-0E-79-D9-63-8F-15-FC-00-17-02-EB-AB-1A-4B-B3-E7-00-00-00-00-49-45-4E-44-AE-42-60-82", - ["Cross"] = "89-50-4E-47-0D-0A-1A-0A-00-00-00-0D-49-48-44-52-00-00-00-20-00-00-00-20-08-06-00-00-00-73-7A-7A-F4-00-00-00-09-70-48-59-73-00-00-0B-13-00-00-0B-13-01-00-9A-9C-18-00-00-00-01-73-52-47-42-00-AE-CE-1C-E9-00-00-00-04-67-41-4D-41-00-00-B1-8F-0B-FC-61-05-00-00-00-C5-49-44-41-54-78-01-ED-96-D1-0D-83-30-0C-44-9D-4E-D0-51-BA-02-13-B5-23-A4-1B-A4-13-31-42-3B-4A-37-70-8D-6A-04-42-E0-D8-88-E0-1F-3F-29-8A-50-1C-DF-05-48-62-80-20-08-9C-49-D2-20-22-5E-A9-BB-53-1B-FA-67-4A-E9-0B-0A-66-F3-06-5E-DA-79-6B-89-32-4E-BC-39-71-55-9C-63-47-B2-14-7F-01-3D-37-6A-BD-64-82-C7-7A-8E-1D-A9-9A-06-29-E1-62-35-9B-6F-C2-12-7B-B8-89-66-E2-1A-81-E6-E2-0A-13-ED-C5-2B-26-CE-11-57-98-D8-25-6E-D9-86-FE-B8-7E-02-D7-9F-10-3D-B7-21-7A-1E-44-96-C4-4D-4C-D0-E4-62-49-B8-61-22-4B-1A-B5-6D-38-BF-C7-3F-D4-3A-E9-6E-E7-B1-8E-63-55-68-0A-92-07-3F-16-63-41-92-E1-BF-80-B2-BB-20-09-82-E0-0C-7E-54-36-6A-69-F6-3F-13-EF-00-00-00-00-49-45-4E-44-AE-42-60-82", - ["Plus"] = "89-50-4E-47-0D-0A-1A-0A-00-00-00-0D-49-48-44-52-00-00-00-20-00-00-00-20-08-06-00-00-00-73-7A-7A-F4-00-00-00-09-70-48-59-73-00-00-0B-13-00-00-0B-13-01-00-9A-9C-18-00-00-00-01-73-52-47-42-00-AE-CE-1C-E9-00-00-00-04-67-41-4D-41-00-00-B1-8F-0B-FC-61-05-00-00-00-A7-49-44-41-54-78-01-ED-D5-01-09-84-30-14-06-E0-7F-C7-05-B8-06-77-0D-CE-08-46-31-C2-1A-68-04-4D-A0-51-8C-A0-0D-B4-81-0D-E6-13-14-C6-10-C5-4D-11-E1-FF-60-F8-78-0C-F7-B3-E1-04-88-02-18-63-B4-8C-04-77-98-17-5F-64-F0-F4-82-BF-C8-AA-BF-F0-14-12-E0-14-0C-C0-00-0C-A0-D6-9A-72-B1-A4-F2-F8-61-5B-6C-CD-E9-64-D4-3B-F3-1B-A5-54-81-3D-D3-D5-6A-AE-A3-DD-F5-D6-8E-E0-83-EB-0C-6E-E3-ED-36-64-9B-72-49-3A-95-7F-6C-8B-71-EC-08-7A-79-77-85-B3-48-C8-CA-DA-DA-12-9E-F8-19-32-00-03-3C-3A-40-67-D5-2D-EE-30-FF-37-34-88-02-8C-19-03-9B-84-46-97-A8-ED-00-00-00-00-49-45-4E-44-AE-42-60-82", - ["Plus Thicker"] = "89-50-4E-47-0D-0A-1A-0A-00-00-00-0D-49-48-44-52-00-00-00-20-00-00-00-20-08-06-00-00-00-73-7A-7A-F4-00-00-00-09-70-48-59-73-00-00-0B-13-00-00-0B-13-01-00-9A-9C-18-00-00-00-01-73-52-47-42-00-AE-CE-1C-E9-00-00-00-04-67-41-4D-41-00-00-B1-8F-0B-FC-61-05-00-00-00-A1-49-44-41-54-78-01-ED-96-D1-09-84-30-10-44-27-C7-15-70-D7-81-25-D9-C1-9D-95-A8-1D-D9-89-25-C4-0E-4C-07-71-85-80-12-22-91-B8-E8-CF-3C-98-8F-2C-21-79-10-D8-0D-40-48-21-DE-FB-5A-32-4B-AC-E4-87-BB-91-4B-47-BF-61-51-C8-0B-E5-7C-A0-C0-15-01-15-28-40-01-0A-98-B8-10-BA-5A-87-3C-55-B4-9E-32-FB-9D-A4-37-C6-0C-39-01-9B-38-5C-0B-27-02-DF-7D-21-F5-04-2A-1D-EE-48-20-2E-BC-13-9B-1A-49-7B-42-A4-8A-D6-13-F2-F4-D0-22-4C-C1-47-87-91-0A-14-A0-00-05-B4-04-1C-EE-46-9A-CF-3F-34-A3-F5-6B-5E-83-90-42-16-B4-42-4C-CD-3F-8F-0E-C4-00-00-00-00-49-45-4E-44-AE-42-60-82", - ["Collapse"] = "89-50-4E-47-0D-0A-1A-0A-00-00-00-0D-49-48-44-52-00-00-00-20-00-00-00-20-08-06-00-00-00-73-7A-7A-F4-00-00-00-09-70-48-59-73-00-00-0B-13-00-00-0B-13-01-00-9A-9C-18-00-00-00-01-73-52-47-42-00-AE-CE-1C-E9-00-00-00-04-67-41-4D-41-00-00-B1-8F-0B-FC-61-05-00-00-00-CE-49-44-41-54-78-01-ED-95-01-0D-C2-30-10-45-7F-A7-60-12-2A-01-09-93-80-04-1C-80-03-EA-60-16-70-30-1C-20-01-09-93-C0-1C-1C-BF-61-24-CD-18-0C-9A-DE-1A-92-BE-A4-49-D7-25-F7-7F-72-FF-5A-A0-90-19-33-3D-10-91-1D-F4-18-8C-31-E7-B7-7F-29-7E-10-7D-5C-A8-59-4D-3C-D4-D0-67-08-3F-E6-5A-B0-D5-34-C2-16-9C-50-48-05-DB-B5-F7-C1-45-0E-28-BC-19-53-7D-F3-7B-AC-09-05-2D-57-1F-8C-96-DF-5B-AC-05-C5-AE-33-F3-ED-CF-F4-C7-98-22-ED-87-4B-A6-85-26-14-38-CA-32-3A-A1-64-E1-46-BE-A7-41-4A-E4-35-74-4B-F8-C9-B0-48-01-0B-D5-3F-8A-3F-E9-25-45-28-59-A4-93-78-3A-68-C1-E2-2E-10-72-88-A4-42-66-8A-81-62-A0-18-C8-6E-20-1A-79-BC-0F-97-71-59-14-FE-95-3B-1B-9A-F9-A3-61-43-3F-A9-00-00-00-00-49-45-4E-44-AE-42-60-82", - }; - - } - - - - #endregion - - #region Other - - - public static void MarkInteractive(this Rect rect) - { - if (!curEvent.isRepaint) return; - - var unclippedRect = (Rect)_mi_GUIClip_UnclipToWindow.Invoke(null, new object[] { rect }); - - var curGuiView = _pi_GUIView_current.GetValue(null); - - _mi_GUIView_MarkHotRegion.Invoke(curGuiView, new object[] { unclippedRect }); - - } - - static PropertyInfo _pi_GUIView_current = typeof(Editor).Assembly.GetType("UnityEditor.GUIView").GetProperty("current", maxBindingFlags); - static MethodInfo _mi_GUIView_MarkHotRegion = typeof(Editor).Assembly.GetType("UnityEditor.GUIView").GetMethod("MarkHotRegion", maxBindingFlags); - static MethodInfo _mi_GUIClip_UnclipToWindow = typeof(GUI).Assembly.GetType("UnityEngine.GUIClip").GetMethod("UnclipToWindow", maxBindingFlags, null, new[] { typeof(Rect) }, null); - - - - - public static float GetCurrentInspectorWidth() => typeof(EditorGUIUtility).GetPropertyValue("contextWidth"); - - public static void CheckScrollbarVisibility(ref bool isScrollbarVisible) - { - GUILayout.Label("", GUILayout.Height(0), GUILayout.ExpandWidth(true)); - - if (Event.current.type == EventType.Repaint) - isScrollbarVisible = GetCurrentInspectorWidth() - 33 > lastRect.width; - - } - - - - - - - #endregion - - } - -} -#endif \ No newline at end of file diff --git a/Assets/Plugins/vFolders/VFoldersLibs.cs.meta b/Assets/Plugins/vFolders/VFoldersLibs.cs.meta deleted file mode 100644 index 0c41ce9a8..000000000 --- a/Assets/Plugins/vFolders/VFoldersLibs.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: d2528d4639fe84d44bfdfde62c65dc86 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Plugins/vFolders/VFoldersMenu.cs b/Assets/Plugins/vFolders/VFoldersMenu.cs deleted file mode 100644 index 2f48e1276..000000000 --- a/Assets/Plugins/vFolders/VFoldersMenu.cs +++ /dev/null @@ -1,128 +0,0 @@ -#if UNITY_EDITOR -using System.Collections; -using System.Collections.Generic; -using UnityEngine; -using UnityEditor; -using static VFolders.Libs.VUtils; -using static VFolders.Libs.VGUI; -// using static VTools.VDebug; - - -namespace VFolders -{ - class VFoldersMenu - { - - public static bool navigationBarEnabled { get => EditorPrefsCached.GetBool("vFolders-navigationBarEnabled", false); set => EditorPrefsCached.SetBool("vFolders-navigationBarEnabled", value); } - public static bool twoLineNamesEnabled { get => EditorPrefsCached.GetBool("vFolders-twoLineNamesEnabled", false); set => EditorPrefsCached.SetBool("vFolders-twoLineNamesEnabled", value); } - - public static bool autoIconsEnabled { get => EditorPrefsCached.GetBool("vFolders-autoIconsEnabled", false); set => EditorPrefsCached.SetBool("vFolders-autoIconsEnabled", value); } - public static bool hierarchyLinesEnabled { get => EditorPrefsCached.GetBool("vFolders-hierarchyLinesEnabled", false); set => EditorPrefsCached.SetBool("vFolders-hierarchyLinesEnabled", value); } - public static bool zebraStripingEnabled { get => EditorPrefsCached.GetBool("vFolders-zebraStripingEnabled", false); set => EditorPrefsCached.SetBool("vFolders-zebraStripingEnabled", value); } - public static bool contentMinimapEnabled { get => EditorPrefsCached.GetBool("vFolders-contentMinimapEnabled", false); set => EditorPrefsCached.SetBool("vFolders-contentMinimapEnabled", value); } - public static bool backgroundColorsEnabled { get => EditorPrefsCached.GetBool("vFolders-backgroundColorsEnabled", false); set => EditorPrefsCached.SetBool("vFolders-backgroundColorsEnabled", value); } - public static bool minimalModeEnabled { get => EditorPrefsCached.GetBool("vFolders-minimalModeEnabled", false); set => EditorPrefsCached.SetBool("vFolders-minimalModeEnabled", value); } - public static bool foldersFirstEnabled { get => EditorPrefsCached.GetBool("vFolders-foldersFirstEnabled", false); set => EditorPrefsCached.SetBool("vFolders-foldersFirstEnabled", value); } - public static bool toggleExpandedEnabled { get => EditorPrefsCached.GetBool("vFolders-toggleExpandedEnabled", true); set => EditorPrefsCached.SetBool("vFolders-toggleExpandedEnabled", value); } - public static bool collapseEverythingElseEnabled { get => EditorPrefsCached.GetBool("vFolders-collapseEverythingElseEnabled", true); set => EditorPrefsCached.SetBool("vFolders-collapseEverythingElseEnabled", value); } - public static bool collapseEverythingEnabled { get => EditorPrefsCached.GetBool("vFolders-collapseEverythingEnabled", true); set => EditorPrefsCached.SetBool("vFolders-collapseEverythingEnabled", value); } - - public static bool pluginDisabled { get => EditorPrefsCached.GetBool("vFolders-pluginDisabled", false); set => EditorPrefsCached.SetBool("vFolders-pluginDisabled", value); } - - - - - const string dir = "Tools/vFolders/"; - - const string navigationBar = dir + "Navigation bar"; - const string autoIcons = dir + "Automatic icons"; - const string twoLineNames = dir + "Two-line names"; - const string hierarchyLines = dir + "Hierarchy lines"; - const string backgroundColors = dir + "Background colors"; - const string minimalMode = dir + "Minimal mode"; - const string zebraStriping = dir + "Zebra striping"; - const string contentMinimap = dir + "Content minimap"; - const string foldersFirst = dir + "Sort folders first"; - - const string toggleExpanded = dir + "E to expand \u2215 collapse folder"; - const string collapseEverythingElse = dir + "Shift-E to isolate folder"; - const string collapseEverything = dir + "Ctrl-Shift-E to collapse all folders"; - - const string disablePlugin = dir + "Disable vFolders"; - - - - - - - [MenuItem(dir + "Features", false, 1)] static void daasddsas() { } - [MenuItem(dir + "Features", true, 1)] static bool dadsdasas123() => false; - - [MenuItem(navigationBar, false, 2)] static void dadsaadsdsadasdsadadsas() { navigationBarEnabled = !navigationBarEnabled; EditorApplication.RepaintProjectWindow(); } - [MenuItem(navigationBar, true, 2)] static bool dadsaddasdsasadadsdasadsas() { Menu.SetChecked(navigationBar, navigationBarEnabled); return !pluginDisabled; } - - [MenuItem(twoLineNames, false, 3)] static void dadsadaddssadass() { twoLineNamesEnabled = !twoLineNamesEnabled; EditorApplication.RepaintProjectWindow(); } - [MenuItem(twoLineNames, true, 3)] static bool dadsaddasdsaasddsas() { Menu.SetChecked(twoLineNames, twoLineNamesEnabled); return !pluginDisabled; } - - [MenuItem(autoIcons, false, 4)] static void dadsadadsas() { autoIconsEnabled = !autoIconsEnabled; VFolders.folderInfoCache.Clear(); EditorApplication.RepaintProjectWindow(); } - [MenuItem(autoIcons, true, 4)] static bool dadsaddasadsas() { Menu.SetChecked(autoIcons, autoIconsEnabled); return !pluginDisabled; } - - [MenuItem(hierarchyLines, false, 5)] static void dadsadadsadass() { hierarchyLinesEnabled = !hierarchyLinesEnabled; EditorApplication.RepaintProjectWindow(); } - [MenuItem(hierarchyLines, true, 5)] static bool dadsaddasaasddsas() { Menu.SetChecked(hierarchyLines, hierarchyLinesEnabled); return !pluginDisabled; } - - [MenuItem(zebraStriping, false, 6)] static void dadsadaddsasadsadass() { zebraStripingEnabled = !zebraStripingEnabled; EditorApplication.RepaintProjectWindow(); } - [MenuItem(zebraStriping, true, 6)] static bool dadsaddadassadsaasddsas() { Menu.SetChecked(zebraStriping, zebraStripingEnabled); return !pluginDisabled; } - - [MenuItem(contentMinimap, false, 7)] static void dadsadadasdsadass() { contentMinimapEnabled = !contentMinimapEnabled; EditorApplication.RepaintProjectWindow(); } - [MenuItem(contentMinimap, true, 7)] static bool dadsadddasasaasddsas() { Menu.SetChecked(contentMinimap, contentMinimapEnabled); return !pluginDisabled; } - - [MenuItem(backgroundColors, false, 8)] static void dadsadadsadsadass() { backgroundColorsEnabled = !backgroundColorsEnabled; EditorApplication.RepaintProjectWindow(); } - [MenuItem(backgroundColors, true, 8)] static bool dadsaddasadsaasddsas() { Menu.SetChecked(backgroundColors, backgroundColorsEnabled); return !pluginDisabled; } - - [MenuItem(minimalMode, false, 9)] static void dadsadadsaddsasadass() { minimalModeEnabled = !minimalModeEnabled; EditorApplication.RepaintProjectWindow(); } - [MenuItem(minimalMode, true, 9)] static bool dadsaddasadsadsaasddsas() { Menu.SetChecked(minimalMode, minimalModeEnabled); return !pluginDisabled; } -#if UNITY_EDITOR_OSX - [MenuItem(foldersFirst, false, 10)] static void dadsdsfaadsdadsas() { foldersFirstEnabled = !foldersFirstEnabled; EditorApplication.RepaintProjectWindow(); if (!foldersFirstEnabled) UnityEditor.Compilation.CompilationPipeline.RequestScriptCompilation(); } - [MenuItem(foldersFirst, true, 10)] static bool dadsasdfdadsdasadsas() { Menu.SetChecked(foldersFirst, foldersFirstEnabled); return !pluginDisabled; } -#endif - - - - [MenuItem(dir + "Shortcuts", false, 101)] static void dadsas() { } - [MenuItem(dir + "Shortcuts", true, 101)] static bool dadsas123() => false; - - [MenuItem(toggleExpanded, false, 102)] static void dadsadsadasdsadadsas() => toggleExpandedEnabled = !toggleExpandedEnabled; - [MenuItem(toggleExpanded, true, 102)] static bool dadsaddsasadadsdasadsas() { Menu.SetChecked(toggleExpanded, toggleExpandedEnabled); return !pluginDisabled; } - - [MenuItem(collapseEverythingElse, false, 103)] static void dadsadsasdadasdsadadsas() => collapseEverythingElseEnabled = !collapseEverythingElseEnabled; - [MenuItem(collapseEverythingElse, true, 103)] static bool dadsaddsdasasadadsdasadsas() { Menu.SetChecked(collapseEverythingElse, collapseEverythingElseEnabled); return !pluginDisabled; } - - [MenuItem(collapseEverything, false, 104)] static void dadsadsdasadasdsadadsas() => collapseEverythingEnabled = !collapseEverythingEnabled; - [MenuItem(collapseEverything, true, 104)] static bool dadsaddssdaasadadsdasadsas() { Menu.SetChecked(collapseEverything, collapseEverythingEnabled); return !pluginDisabled; } - - - - - [MenuItem(dir + "More", false, 1001)] static void daasadsddsas() { } - [MenuItem(dir + "More", true, 1001)] static bool dadsadsdasas123() => false; - - [MenuItem(dir + "Open manual", false, 1002)] - static void dadadssadsas() => Application.OpenURL("https://kubacho-lab.gitbook.io/vfolders-2"); - - [MenuItem(dir + "Join our Discord", false, 1003)] - static void dadasdsas() => Application.OpenURL("https://discord.gg/pUektnZeJT"); - - - - - - - [MenuItem(disablePlugin, false, 10001)] static void dadsadsdasadasdasdsadadsas() { pluginDisabled = !pluginDisabled; UnityEditor.Compilation.CompilationPipeline.RequestScriptCompilation(); } - [MenuItem(disablePlugin, true, 10001)] static bool dadsaddssdaasadsadadsdasadsas() { Menu.SetChecked(disablePlugin, pluginDisabled); return true; } - - - - - } -} -#endif \ No newline at end of file diff --git a/Assets/Plugins/vFolders/VFoldersMenu.cs.meta b/Assets/Plugins/vFolders/VFoldersMenu.cs.meta deleted file mode 100644 index 19b54b393..000000000 --- a/Assets/Plugins/vFolders/VFoldersMenu.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: f118e09f35fa241fda19f1f3b1e7c5a2 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Plugins/vFolders/VFoldersMenuItems.cs b/Assets/Plugins/vFolders/VFoldersMenuItems.cs deleted file mode 100644 index 028ed4216..000000000 --- a/Assets/Plugins/vFolders/VFoldersMenuItems.cs +++ /dev/null @@ -1,5 +0,0 @@ - -// this file was present in a previus version and is supposed to be deleted now -// but asset store update delivery system doesn't allow deleting files -// so instead this file is now emptied -// feel free to delete it if you want diff --git a/Assets/Plugins/vFolders/VFoldersMenuItems.cs.meta b/Assets/Plugins/vFolders/VFoldersMenuItems.cs.meta deleted file mode 100644 index 4bdc039c4..000000000 --- a/Assets/Plugins/vFolders/VFoldersMenuItems.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: ec6d8bc24e3ec4cb6b055630a6425686 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Plugins/vFolders/VFoldersNavbar.cs b/Assets/Plugins/vFolders/VFoldersNavbar.cs deleted file mode 100644 index 090bd4f8f..000000000 --- a/Assets/Plugins/vFolders/VFoldersNavbar.cs +++ /dev/null @@ -1,1395 +0,0 @@ -#if UNITY_EDITOR -using System.Collections; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Reflection; -using UnityEngine; -using UnityEditor; -using UnityEditor.ShortcutManagement; -using UnityEngine.UIElements; -using UnityEngine.SceneManagement; -using UnityEditor.SceneManagement; -using UnityEditor.IMGUI.Controls; -using Type = System.Type; -using static VFolders.Libs.VUtils; -using static VFolders.Libs.VGUI; -// using static VTools.VDebug; -using static VFolders.VFoldersData; -using static VFolders.VFolders; - - - -namespace VFolders -{ - public class VFoldersNavbar - { - - public void OnGUI(Rect navbarRect) - { - void updateState() - { - if (!curEvent.isLayout) return; - - - openedFolderPath = window.GetMemberValue("m_SearchFilter")?.GetMemberValue("folders")?.FirstOrDefault() ?? "Assets"; - - isOneColumn = window.GetMemberValue("m_ViewMode") == 0; - - isSearchActive = window.GetMemberValue("m_FocusSearchField") - || !window.GetMemberValue("m_SearchFieldText").IsNullOrEmpty() - || GUI.GetNameOfFocusedControl() == "navbar search field"; - - } - - void background() - { - var backgroundColor = Greyscale(isDarkTheme ? .235f : .8f); - var lineColor = Greyscale(isDarkTheme ? .13f : .58f); - - navbarRect.Draw(backgroundColor); - - navbarRect.SetHeightFromBottom(1).MoveY(1).Draw(lineColor); - - } - void hiddenMenu() - { - if (!curEvent.holdingAlt) return; - if (!curEvent.isMouseUp) return; - if (curEvent.mouseButton != 1) return; - if (!navbarRect.IsHovered()) return; - - - void selectData() - { - Selection.activeObject = data; - } - void selectPalette() - { - Selection.activeObject = palette; - } - void clearCache() - { - VFoldersCache.instance.iconTextures_byKey.Clear(); - VFoldersCache.instance.iconTextureDatas_byKey.Clear(); - VFoldersCache.instance.folderStates_byGuid.Clear(); - - VFolders.folderInfoCache.Clear(); - - bookmarkWidthsCache.Clear(); - - } - - - - GenericMenu menu = new(); - - menu.AddDisabledItem(new GUIContent("vFolders hidden menu")); - - if (isOneColumn) - { - var backForwardButtonsEnabled = EditorPrefsCached.GetBool("vFolders-showBackForwardButtonsInOneColumn", defaultValue: false); - - menu.AddSeparator(""); - menu.AddItem(new GUIContent("Show + button"), false, backForwardButtonsEnabled ? () => EditorPrefsCached.SetBool("vFolders-showBackForwardButtonsInOneColumn", false) : null); - menu.AddItem(new GUIContent("Show < > buttons"), false, backForwardButtonsEnabled ? null : () => EditorPrefsCached.SetBool("vFolders-showBackForwardButtonsInOneColumn", true)); - } - - - menu.AddSeparator(""); - menu.AddItem(new GUIContent("Select data"), false, selectData); - menu.AddItem(new GUIContent("Select palette"), false, selectPalette); - - menu.AddSeparator(""); - menu.AddItem(new GUIContent("Clear cache"), false, clearCache); - - menu.ShowAsContext(); - - } - - void backButton() - { - if (isOneColumn && !EditorPrefsCached.GetBool("vFolders-showBackForwardButtonsInOneColumn", defaultValue: false)) return; - - - var buttonRect = navbarRect.SetWidth(30).MoveX(4); - - if (Application.unityVersion.StartsWith("6000")) - buttonRect = buttonRect.MoveY(-.49f); - - - var iconName = "Chevron Left"; - var iconSize = 14; - var colorNormal = Greyscale(isDarkTheme ? .75f : .2f); - var colorHovered = Greyscale(isDarkTheme ? 1f : .2f); - var colorPressed = Greyscale(isDarkTheme ? .75f : .5f); - var colorDisabled = Greyscale(isDarkTheme ? .53f : .55f); - - - var disabled = isOneColumn ? !history.prevTreeStates.Any() : !history.prevFolderPaths.Any(); - - if (disabled) { IconButton(buttonRect, iconName, iconSize, colorDisabled, colorDisabled, colorDisabled); return; } - - - if (!IconButton(buttonRect, iconName, iconSize, colorNormal, colorHovered, colorPressed)) return; - - if (isOneColumn) - history.MoveBack_OneColumn(); - else - history.MoveBack_TwoColumns(); - - } - void forwardButton() - { - if (isOneColumn && !EditorPrefsCached.GetBool("vFolders-showBackForwardButtonsInOneColumn", defaultValue: false)) return; - - - var buttonRect = navbarRect.SetWidth(30).MoveX(30).MoveX(1).AddWidthFromMid(-6); - - if (Application.unityVersion.StartsWith("6000")) - buttonRect = buttonRect.MoveY(-.49f); - - - var iconName = "Chevron Right"; - var iconSize = 14; - var colorNormal = Greyscale(isDarkTheme ? .75f : .2f); - var colorHovered = Greyscale(isDarkTheme ? 1f : .2f); - var colorPressed = Greyscale(isDarkTheme ? .75f : .5f); - var colorDisabled = Greyscale(isDarkTheme ? .53f : .55f); - - - var disabled = isOneColumn ? !history.nextTreeStates.Any() : !history.nextFolderPaths.Any(); - - if (disabled) { IconButton(buttonRect, iconName, iconSize, colorDisabled, colorDisabled, colorDisabled); return; } - - - if (!IconButton(buttonRect, iconName, iconSize, colorNormal, colorHovered, colorPressed)) return; - - if (isOneColumn) - history.MoveForward_OneColumn(); - else - history.MoveForward_TwoColumns(); - - } - void plusButton_oneColumn() - { - if (!isOneColumn) return; - if (EditorPrefsCached.GetBool("vFolders-showBackForwardButtonsInOneColumn", defaultValue: false)) return; - - - var buttonRect = navbarRect.SetWidth(28).MoveX(4.5f); - - if (Application.unityVersion.StartsWith("6000")) - buttonRect = buttonRect.MoveY(-.49f); - - - var iconName = "Plus Thicker"; - var iconSize = 16; - var colorNormal = Greyscale(isDarkTheme ? .7f : .44f); - var colorHovered = Greyscale(isDarkTheme ? 1f : .42f); - var colorPressed = Greyscale(isDarkTheme ? .75f : .6f); - - - if (!IconButton(buttonRect, iconName, iconSize, colorNormal, colorHovered, colorPressed)) return; - - EditorUtility.DisplayPopupMenu(buttonRect.MoveX(24), "Assets/Create", null); - - } - - - void searchButton() - { - if (searchAnimationT == 1) return; - - - var buttonRect = navbarRect.SetWidthFromRight(28).MoveX(-5); - - var iconName = "Search_"; - var iconSize = 16; - var colorNormal = Greyscale(isDarkTheme ? .75f : .2f); - var colorHovered = Greyscale(isDarkTheme ? 1f : .2f); - var colorPressed = Greyscale(isDarkTheme ? .75f : .5f); - - - if (!IconButton(buttonRect, iconName, iconSize, colorNormal, colorHovered, colorPressed)) return; - - window.SetMemberValue("m_FocusSearchField", true); - - } - void plusButton_twoColumns() - { - if (isOneColumn) return; - if (searchAnimationT == 1) return; - - - var buttonRect = navbarRect.SetWidthFromRight(28).MoveX(-33); - - var iconName = "Plus"; - var iconSize = 16; - var colorNormal = Greyscale(isDarkTheme ? .735f : .44f); - var colorHovered = Greyscale(isDarkTheme ? 1f : .42f); - var colorPressed = Greyscale(isDarkTheme ? .75f : .6f); - - - if (!IconButton(buttonRect, iconName, iconSize, colorNormal, colorHovered, colorPressed)) return; - - if (curEvent.holdingAlt) - { - history.prevTreeStates.Clear(); - history.nextTreeStates.Clear(); - - history.prevFolderPaths.Clear(); - history.nextFolderPaths.Clear(); - - history.lastScrollTime = 0; - - - window.Repaint(); - - return; - - - // for debug - - } - - EditorUtility.DisplayPopupMenu(buttonRect.MoveX(24), "Assets/Create", null); - - } - void collapseAllButton_oneColumn() - { - if (!isOneColumn) return; - if (searchAnimationT == 1) return; - - - var buttonRect = navbarRect.SetWidthFromRight(28).MoveX(-33); - - var iconName = "Collapse"; - var iconSize = 16; - var colorNormal = Greyscale(isDarkTheme ? .71f : .44f); - var colorHovered = Greyscale(isDarkTheme ? 1f : .42f); - var colorPressed = Greyscale(isDarkTheme ? .75f : .6f); - - - if (!IconButton(buttonRect, iconName, iconSize, colorNormal, colorHovered, colorPressed)) return; - - controller.CollapseAll(); - - } - void bookmarks() - { - if (searchAnimationT == 1) return; - if (isSearchActive && !curEvent.isRepaint) return; - - void createData() - { - if (data) return; - if (!navbarRect.IsHovered()) return; - if (!DragAndDrop.objectReferences.Any()) return; - - data = ScriptableObject.CreateInstance(); - - AssetDatabase.CreateAsset(data, GetScriptPath("VFolders").GetParentPath().CombinePath("vFolders Data.asset")); - - } - void handleUndoRedo() - { - if (!data) return; - if (curEvent.commandName != "UndoRedoPerformed") return; - - - if (repaintNeededAfterUndoRedo) - window.Repaint(); - - repaintNeededAfterUndoRedo = false; - - - bookmarkWidthsCache.Clear(); - bookmarkCenterXCache.Clear(); - - } - void divider() - { - if (!data) return; - if (!data.bookmarks.Any()) return; - - - var dividerRect = navbarRect.SetWidthFromRight(1).SetHeightFromMid(16).MoveX(-65).MoveX(isCompactMode ? 1.5f : .5f); - - var dividerColor = Greyscale(isDarkTheme ? .33f : .64f); - - - dividerRect.Draw(dividerColor); - - } - void gui() - { - if (!data) return; - - this.navbarRect = navbarRect; - this.bookmarksRect = navbarRect.AddWidth(-69).AddWidthFromRight(-60).MoveX(2).MoveX(isCompactMode ? -3 : 0); - - BookmarksGUI(); - - } - - createData(); - handleUndoRedo(); - divider(); - gui(); - - } - - void searchField() - { - if (searchAnimationT == 0) return; - - var searchFieldRect = navbarRect.SetHeightFromMid(20).AddWidth(-33).SetWidthFromRight(240f.Min(window.position.width - (isOneColumn ? 195 : 223))).Move(-1, 2); - - - GUILayout.BeginArea(searchFieldRect); - GUILayout.BeginHorizontal(); - - - GUI.SetNextControlName("navbar search field"); - - Space(2); - window.InvokeMethod("SearchField"); - - - GUILayout.EndHorizontal(); - GUILayout.EndArea(); - - } - void searchOptions() - { - if (searchAnimationT == 0) return; - - var searchFieldRect = navbarRect.SetHeightFromMid(20).AddWidth(-33).SetWidthFromRight(240f.Min(window.position.width - (isOneColumn ? 195 : 223))).Move(-1, 2); - var searchOptionsRect = navbarRect.SetHeightFromMid(20).SetXMax(searchFieldRect.x).SetWidthFromRight(123); - - - - - GUILayout.BeginArea(searchOptionsRect); - GUILayout.BeginHorizontal(); - - - - - GUILayout.FlexibleSpace(); - - Space(3); - window.InvokeMethod("TypeDropDown"); - - var masksStartX = lastRect.x; - - - window.InvokeMethod("AssetLabelsDropDown"); - - if (!isOneColumn) - window.InvokeMethod("ButtonSaveFilter"); - - - window.InvokeMethod("ToggleHiddenPackagesVisibility"); - - Space(4); - - - - - - var maskRect = searchOptionsRect.SetWidth(1).SetX(masksStartX - 1).MoveY(-3); - var maskColor = Greyscale(isDarkTheme ? .235f : .8f); - - for (int i = 0; i < (isOneColumn ? 3 : 4); i++) - { - maskRect.Draw(maskColor); - maskRect = maskRect.MoveX(26); - } - - - - - GUILayout.EndHorizontal(); - GUILayout.EndArea(); - - - } - void closeSearchButton() - { - if (searchAnimationT == 0) return; - - - var buttonRect = navbarRect.SetWidthFromRight(30).MoveX(-4); - - var iconName = "Cross"; - var iconSize = 16; - var colorNormal = Greyscale(isDarkTheme ? .72f : .2f); - var colorHovered = Greyscale(isDarkTheme ? .9f : .2f); - var colorPressed = Greyscale(isDarkTheme ? .75f : .5f); - - - if (!IconButton(buttonRect, iconName, iconSize, colorNormal, colorHovered, colorPressed)) return; - - window.SetMemberValue("m_SearchFieldText", ""); - window.GetMemberValue("m_SearchFilter").SetMemberValue("m_NameFilter", ""); - - window.InvokeMethod("UpdateSearchDelayed"); - - GUIUtility.keyboardControl = 0; - - } - void closeSearchOnEsc() - { - if (!isSearchActive) return; - if (curEvent.keyCode != KeyCode.Escape) return; - - window.SetMemberValue("m_SearchFieldText", ""); - window.GetMemberValue("m_SearchFilter").SetMemberValue("m_NameFilter", ""); - - window.InvokeMethod("UpdateSearchDelayed"); - - GUIUtility.keyboardControl = 0; - - } - - - void searchAnimation() - { - if (!curEvent.isLayout) return; - - - var lerpSpeed = 8f; - - if (isSearchActive) - MathUtil.SmoothDamp(ref searchAnimationT, 1, lerpSpeed, ref searchAnimationDerivative, editorDeltaTime); - else - MathUtil.SmoothDamp(ref searchAnimationT, 0, lerpSpeed, ref searchAnimationDerivative, editorDeltaTime); - - - if (isSearchActive && searchAnimationT > .99f) - searchAnimationT = 1; - - if (!isSearchActive && searchAnimationT < .01f) - searchAnimationT = 0; - - - animatingSearch = searchAnimationT != 0 && searchAnimationT != 1; - - } - - void buttonsAndBookmarks() - { - SetGUIColor(Greyscale(1, (1 - searchAnimationT).Pow(2))); - GUI.BeginGroup(window.position.SetPos(0, 0).MoveX(-searchAnimationDistance * searchAnimationT)); - - searchButton(); - plusButton_twoColumns(); - collapseAllButton_oneColumn(); - bookmarks(); - - GUI.EndGroup(); - ResetGUIColor(); - - } - void search() - { - SetGUIColor(Greyscale(1, searchAnimationT.Pow(2))); - GUI.BeginGroup(window.position.SetPos(0, 0).MoveX(searchAnimationDistance * (1 - searchAnimationT))); - - searchField(); - searchOptions(); - closeSearchButton(); - closeSearchOnEsc(); - - GUI.EndGroup(); - ResetGUIColor(); - - } - - - - updateState(); - - background(); - hiddenMenu(); - - backButton(); - forwardButton(); - plusButton_oneColumn(); - - searchAnimation(); - buttonsAndBookmarks(); - search(); - - - - if (draggingBookmark || animatingDroppedBookmark || animatingGaps || animatingTooltip || animatingSearch) - window.Repaint(); - - } - - bool animatingSearch; - - float searchAnimationDistance = 90; - float searchAnimationT; - float searchAnimationDerivative; - - string openedFolderPath; - - bool isOneColumn; - bool isTwoColumns => !isOneColumn; - bool isSearchActive; - - bool isCompactMode => isOneColumn; - - Rect navbarRect; - Rect bookmarksRect; - - - - - - - - - - - - - public void BookmarksGUI() - { - void bookmark(Vector2 centerPosition, Bookmark bookmark) - { - if (bookmark == null) return; - if (!curEvent.isRepaint && !curEvent.isMouseUp) return; - - - var bookmarkRect = Rect.zero.SetSize(GetBookmarkWidth(bookmark), bookmarksRect.height).SetMidPos(centerPosition); - - var IsHovered = bookmarkRect.IsHovered(); - var isSelected = openedFolderPath == bookmark.guid.ToPath() && !isCompactMode; - var isPressed = bookmark == pressedBookmark; - var isDragged = draggingBookmark && draggedBookmark == bookmark; - - - void shadow() - { - if (!draggingBookmark) return; - if (draggedBookmark != bookmark) return; - - bookmarkRect.SetSizeFromMid(GetBookmarkWidth(bookmark) - 4, bookmarkRect.height - 4).DrawBlurred(Greyscale(0, .3f), 15); - - } - void background() - { - if (isCompactMode) return; - if (!isSelected && !IsHovered && !isDragged) return; - - if (IsHovered && draggingBookmark && draggedBookmark != bookmark) return; - - - var backgroundRect = bookmarkRect.SetSizeFromMid(bookmarkRect.width - 7, bookmarkRect.height - 8).AddWidthFromRight(1); - - - var backgroundColor = isSelected ? Greyscale(isDarkTheme ? .35f : .7f) - : Greyscale(isDarkTheme ? .31f : .75f); - var outlineColor = isSelected ? Greyscale(isDarkTheme ? .21f : .65f) - : Greyscale(isDarkTheme ? .21f : .65f, .5f); - - - backgroundRect.Resize(-1).DrawRounded(outlineColor, 6); - backgroundRect.DrawRounded(backgroundColor, 5); - - } - void backgroundCompact() - { - if (!isCompactMode) return; - - if (!IsHovered) return; - if (draggingBookmark && draggedBookmark != bookmark) return; - - - var backgroundColor = Greyscale(isDarkTheme ? .35f : .7f); - - var backgroundRect = bookmarkRect.SetSizeFromMid(bookmarkRect.width - 2, bookmarkRect.width - 4); - - backgroundRect.DrawRounded(backgroundColor, 4); - - } - void icon() - { - var folderInfo = VFolders.GetFolderInfo(bookmark.guid); - - Texture iconTexture = folderInfo.hasIcon || folderInfo.hasColor ? VFolders.GetSmallFolderIcon(folderInfo) - : EditorIcons.GetIcon("Folder Icon"); - - var iconRect = isCompactMode ? bookmarkRect.SetSizeFromMid(iconSize) : bookmarkRect.SetWidth(iconSize).SetHeightFromMid(iconSize).MoveX(bookmarkSpacing / 2); - - iconRect = iconRect.SetWidthFromMid(iconRect.height * iconTexture.width / iconTexture.height); - - - - var opacity = folderInfo.hasColor ? .96f : .92f; - - if (isSelected) - opacity = 1; - - if (isPressed && !isDragged) - opacity = .73f; - - if (bookmark.isDeleted) - opacity = .4f; - - - - SetGUIColor(Greyscale(1, opacity)); - - GUI.DrawTexture(iconRect, iconTexture); - - ResetGUIColor(); - - } - void name() - { - if (isCompactMode) return; - if (!curEvent.isRepaint) return; - - - var nameRect = bookmarkRect.MoveX(bookmarkSpacing / 2 + iconSize + iconSpacing); - - var makeExtraBright = isSelected && isDarkTheme; - - - if (!makeExtraBright) - { - var opacity = .95f; - - if (isSelected) - opacity = 1; - - if (isPressed && !isDragged) - opacity = .82f; - - if (bookmark.isDeleted) - opacity = .4f; - - - - SetGUIColor(Greyscale(1, opacity)); - - GUI.Label(nameRect, bookmark.name); - - ResetGUIColor(); - - } - - if (makeExtraBright) - { - var opacity = .85f; - - nameRect = nameRect.SetHeightFromMid(16).AddHeight(4); - - - SetGUIColor(Greyscale(1, opacity)); - - GUI.skin.GetStyle("WhiteLabel").Draw(nameRect, bookmark.name, false, false, false, false); - - ResetGUIColor(); - - } - - } - void tooltip() - { - if (!isCompactMode) return; - - if (bookmark != (draggingBookmark ? (draggedBookmark) : (lastHoveredBookmark))) return; - if (tooltipOpacity == 0) return; - - var fontSize = 11; // ,maybe 12 - var tooltipText = bookmark.isDeleted ? "Deleted" : bookmark.name; - - Rect tooltipRect; - - void set_tooltipRect() - { - var width = tooltipText.GetLabelWidth(fontSize) + 6; - var height = 16 + (fontSize - 12) * 2; - - var yOffset = 28; - var rightMargin = -1; - - - tooltipRect = Rect.zero.SetMidPos(centerPosition.x, centerPosition.y + yOffset).SetSizeFromMid(width, height); - - - var maxXMax = navbarRect.xMax - rightMargin; - - if (tooltipRect.xMax > maxXMax) - tooltipRect = tooltipRect.MoveX(maxXMax - tooltipRect.xMax); - - } - void shadow() - { - var shadowAmount = .33f; - var shadowRadius = 10; - - tooltipRect.DrawBlurred(Greyscale(0, shadowAmount).MultiplyAlpha(tooltipOpacity), shadowRadius); - - } - void background() - { - var cornerRadius = 5; - - var backgroundColor = Greyscale(isDarkTheme ? .13f : .9f); - var outerEdgeColor = Greyscale(isDarkTheme ? .25f : .6f); - var innerEdgeColor = Greyscale(isDarkTheme ? .0f : .95f); - - tooltipRect.Resize(-1).DrawRounded(outerEdgeColor.SetAlpha(tooltipOpacity.Pow(2)), cornerRadius + 1); - tooltipRect.Resize(0).DrawRounded(innerEdgeColor.SetAlpha(tooltipOpacity.Pow(2)), cornerRadius + 0); - tooltipRect.Resize(1).DrawRounded(backgroundColor.SetAlpha(tooltipOpacity), cornerRadius - 1); - - } - void text() - { - var textRect = tooltipRect.MoveY(-.5f); - - var textColor = Greyscale(1f); - - SetLabelAlignmentCenter(); - SetLabelFontSize(fontSize); - SetGUIColor(textColor.SetAlpha(tooltipOpacity)); - - GUI.Label(textRect, tooltipText); - - ResetLabelStyle(); - ResetGUIColor(); - - } - - set_tooltipRect(); - shadow(); - background(); - text(); - - } - void click() - { - if (!IsHovered) return; - if (!curEvent.isMouseUp) return; - - - curEvent.Use(); - - if (draggingBookmark) return; - if ((curEvent.mousePosition - mouseDownPosiion).magnitude > 2) return; - if (bookmark.isDeleted) return; - - - if (isOneColumn) - controller.RevealFolder(bookmark.guid.ToPath(), expand: true, highlight: true, snapToTopMargin: true); - - if (isTwoColumns) - { - controller.RevealFolder(bookmark.guid.ToPath(), expand: false, highlight: false, snapToTopMargin: false); - controller.OpenFolder(bookmark.guid.ToPath()); - } - - - lastClickedBookmark = bookmark; - - hideTooltip = true; - - } - - - bookmarkRect.MarkInteractive(); - - shadow(); - background(); - backgroundCompact(); - icon(); - name(); - tooltip(); - click(); - - } - - void normalBookmark(int i) - { - if (data.bookmarks[i] == droppedBookmark && animatingDroppedBookmark) return; - - var centerX = GetBookmarkCenterX(i); - var centerY = bookmarksRect.height / 2; - - - var minX = centerX - GetBookmarkWidth(data.bookmarks[i]) / 2; - - if (minX < bookmarksRect.x) return; - - lastBookmarkX = minX; - - - bookmark(new Vector2(centerX, centerY), data.bookmarks[i]); - - } - void normalBookmarks() - { - for (int i = 0; i < data.bookmarks.Count; i++) - normalBookmark(i); - - } - void draggedBookmark_() - { - if (!draggingBookmark) return; - - var centerX = curEvent.mousePosition.x + draggedBookmarkHoldOffset.x; - var centerY = bookmarksRect.IsHovered() ? bookmarksRect.height / 2 : curEvent.mousePosition.y; - - bookmark(new Vector2(centerX, centerY), draggedBookmark); - - } - void droppedBookmark_() - { - if (!animatingDroppedBookmark) return; - - var centerX = droppedBookmarkX; - var centerY = bookmarksRect.height / 2; - - bookmark(new Vector2(centerX, centerY), droppedBookmark); - - } - - - ClearCacheIfNeeded(); - - BookmarksMouseState(); - BookmarksDragging(); - BookmarksAnimations(); - - normalBookmarks(); - draggedBookmark_(); - droppedBookmark_(); - - } - - float iconSize = 16; - float iconSpacing = 1; - float bookmarkSpacing = 16; - - float bookmarkWidth_compactMode = 24; - - bool repaintNeededAfterUndoRedo; - - public float lastBookmarkX; - - - - - int GetBookmarkIndex(float mouseX) - { - var curBookmarkWidthSum = 0f; - - for (int i = 0; i < data.bookmarks.Count; i++) - { - curBookmarkWidthSum += GetBookmarkWidth(data.bookmarks[i]); - - if (bookmarksRect.xMax - curBookmarkWidthSum < mouseX + .5f) - return i; - } - - return data.bookmarks.Count; - - } - - float GetBookmarkWidth(Bookmark bookmark) - { - if (!animatingBookmarks) - if (bookmarkWidthsCache.TryGetValue(bookmark, out var cachedWidth)) return cachedWidth; - - - - var width = isCompactMode ? bookmarkWidth_compactMode - : bookmark.name.GetLabelWidth() + iconSize + iconSpacing + bookmarkSpacing; - - - if (!animatingBookmarks) - bookmarkWidthsCache[bookmark] = width; - else - bookmarkWidthsCache.Clear(); - - - return width; - - } - float GetBookmarkCenterX(int i, bool includeGaps = true) - { - if (!animatingBookmarks) - if (bookmarkCenterXCache.TryGetValue(i, out var cachedCenterX)) return cachedCenterX; - - - - var centerX = bookmarksRect.xMax - - GetBookmarkWidth(data.bookmarks[i.Clamp(0, data.bookmarks.Count - 1)]) / 2 - - data.bookmarks.Take(i).Sum(r => GetBookmarkWidth(r)) - - (includeGaps ? gaps.Take(i + 1).Sum() : 0); - - - if (!animatingBookmarks) - bookmarkCenterXCache[i] = centerX; - else - bookmarkCenterXCache.Clear(); - - - return centerX; - - } - - Dictionary bookmarkWidthsCache = new(); - Dictionary bookmarkCenterXCache = new(); - - - - - void ClearCacheIfNeeded() - { - var modeChanged = wasCompactMode != isCompactMode; - var windowResized = prevWindowWidth != window.position.width; - var undoPerformed = curEvent.commandName == "UndoRedoPerformed"; - var renameHappened = curEvent.commandName == "NewKeyboardFocus"; - - wasCompactMode = isCompactMode; - prevWindowWidth = window.position.width; - - - - if (!modeChanged && !windowResized && !undoPerformed && !renameHappened) return; - - bookmarkWidthsCache.Clear(); - bookmarkCenterXCache.Clear(); - - } - - bool wasCompactMode; - float prevWindowWidth; - - - - - - - - - - - - - void BookmarksMouseState() - { - void down() - { - if (!curEvent.isMouseDown) return; - if (!bookmarksRect.IsHovered()) return; - - mousePressed = true; - - mouseDownPosiion = curEvent.mousePosition; - - var pressedBookmarkIndex = GetBookmarkIndex(mouseDownPosiion.x); - - if (pressedBookmarkIndex.IsInRangeOf(data.bookmarks)) - pressedBookmark = data.bookmarks[pressedBookmarkIndex]; - - doubleclickUnhandled = curEvent.clickCount == 2; - - curEvent.Use(); - - } - void up() - { - if (!curEvent.isMouseUp) return; - - mousePressed = false; - pressedBookmark = null; - - } - void hover() - { - var hoveredBookmarkIndex = GetBookmarkIndex(curEvent.mousePosition.x); - - mouseHoversBookmark = bookmarksRect.IsHovered() && hoveredBookmarkIndex.IsInRangeOf(data.bookmarks); - - if (mouseHoversBookmark) - lastHoveredBookmark = data.bookmarks[hoveredBookmarkIndex]; - - - } - - down(); - up(); - hover(); - - } - - bool mouseHoversBookmark; - bool mousePressed; - bool doubleclickUnhandled; - - Vector2 mouseDownPosiion; - - Bookmark pressedBookmark; - Bookmark lastHoveredBookmark; - - - - - - - void BookmarksDragging() - { - void initFromOutside() - { - if (draggingBookmark) return; - if (!bookmarksRect.IsHovered()) return; - if (!curEvent.isDragUpdate) return; - if (DragAndDrop.objectReferences.FirstOrDefault() is not Object draggedObject) return; - if (draggedObject is not DefaultAsset) return; - - animatingDroppedBookmark = false; - - draggingBookmark = true; - draggingBookmarkFromInside = false; - - draggedBookmark = new Bookmark(draggedObject); - draggedBookmarkHoldOffset = Vector2.zero; - - } - void initFromInside() - { - if (draggingBookmark) return; - if (!mousePressed) return; - if ((curEvent.mousePosition - mouseDownPosiion).magnitude <= 2) return; - if (pressedBookmark == null) return; - - var i = GetBookmarkIndex(mouseDownPosiion.x); - - if (i >= data.bookmarks.Count) return; - if (i < 0) return; - - - animatingDroppedBookmark = false; - - draggingBookmark = true; - draggingBookmarkFromInside = true; - - draggedBookmark = data.bookmarks[i]; - draggedBookmarkHoldOffset = new Vector2(GetBookmarkCenterX(i) - mouseDownPosiion.x, bookmarksRect.center.y - mouseDownPosiion.y); - - gaps[i] = GetBookmarkWidth(draggedBookmark); - - - data.RecordUndo(); - - data.bookmarks.Remove(draggedBookmark); - - } - - void acceptFromOutside() - { - if (!draggingBookmark) return; - if (!curEvent.isDragPerform) return; - if (!bookmarksRect.IsHovered()) return; - - DragAndDrop.AcceptDrag(); - curEvent.Use(); - - data.RecordUndo(); - - accept(); - - data.Dirty(); - - } - void acceptFromInside() - { - if (!draggingBookmark) return; - if (!curEvent.isMouseUp) return; - if (!bookmarksRect.IsHovered()) return; - - curEvent.Use(); - EditorGUIUtility.hotControl = 0; - - DragAndDrop.PrepareStartDrag(); // fixes phantom dragged component indicator after reordering bookmarks - - data.RecordUndo(); - data.Dirty(); - - accept(); - - } - void accept() - { - draggingBookmark = false; - draggingBookmarkFromInside = false; - mousePressed = false; - - data.bookmarks.AddAt(draggedBookmark, insertDraggedBookmarkAtIndex); - - gaps[insertDraggedBookmarkAtIndex] -= GetBookmarkWidth(draggedBookmark); - gaps.AddAt(0, insertDraggedBookmarkAtIndex); - - droppedBookmark = draggedBookmark; - - droppedBookmarkX = curEvent.mousePosition.x + draggedBookmarkHoldOffset.x; - droppedBookmarkXDerivative = 0; - animatingDroppedBookmark = true; - - draggedBookmark = null; - - EditorGUIUtility.hotControl = 0; - - repaintNeededAfterUndoRedo = true; - - } - - void cancelFromOutside() - { - if (!draggingBookmark) return; - if (draggingBookmarkFromInside) return; - if (bookmarksRect.IsHovered()) return; - - draggingBookmark = false; - mousePressed = false; - - } - void cancelFromInsideAndDelete() - { - if (!draggingBookmark) return; - if (!curEvent.isMouseUp) return; - if (bookmarksRect.IsHovered()) return; - - draggingBookmark = false; - - DragAndDrop.PrepareStartDrag(); // fixes phantom dragged component indicator after reordering bookmarks - - data.Dirty(); - - repaintNeededAfterUndoRedo = true; - - } - - void update() - { - if (!draggingBookmark) return; - - DragAndDrop.visualMode = DragAndDropVisualMode.Generic; - - if (draggingBookmarkFromInside) // otherwise it breaks vTabs dragndrop - EditorGUIUtility.hotControl = EditorGUIUtility.GetControlID(FocusType.Passive); - - - - insertDraggedBookmarkAtIndex = GetBookmarkIndex(curEvent.mousePosition.x + draggedBookmarkHoldOffset.x); - - } - - void dropIntoBookmark() - { - if (draggingBookmark) return; - if (!bookmarksRect.IsHovered()) return; - if (!DragAndDrop.objectReferences.Any()) return; - if (!DragAndDrop.objectReferences.Any(r => r is not DefaultAsset)) return; - if (!DragAndDrop.objectReferences.All(r => AssetDatabase.Contains(r))) return; - - if (!mouseHoversBookmark) return; - if (lastHoveredBookmark.isDeleted) return; - - - if (curEvent.isDragUpdate) - DragAndDrop.visualMode = DragAndDropVisualMode.Move; - - - if (!curEvent.isDragPerform) return; - - DragAndDrop.AcceptDrag(); - - curEvent.Use(); - - - var oldPaths = DragAndDrop.objectReferences.Select(r => r.GetPath()).ToList(); - - var newPaths = oldPaths.Select(r => lastHoveredBookmark.guid.ToPath().CombinePath(r.GetFilename(withExtension: true))) - .Select(r => AssetDatabase.GenerateUniqueAssetPath(r)).ToList(); - - - typeof(Undo).GetMethod("RegisterAssetsMoveUndo", maxBindingFlags).Invoke(null, new object[] { oldPaths.ToArray() }); - - for (int i = 0; i < newPaths.Count; i++) - AssetDatabase.MoveAsset(oldPaths[i], newPaths[i]); - - } - - - initFromOutside(); - initFromInside(); - - acceptFromOutside(); - acceptFromInside(); - - cancelFromOutside(); - cancelFromInsideAndDelete(); - - update(); - - dropIntoBookmark(); - - } - - bool draggingBookmark; - bool draggingBookmarkFromInside; - - int insertDraggedBookmarkAtIndex; - - Vector2 draggedBookmarkHoldOffset; - - Bookmark draggedBookmark; - Bookmark droppedBookmark; - - - - - - - void BookmarksAnimations() - { - if (!curEvent.isLayout) return; - - void gaps_() - { - var makeSpaceForDraggedBookmark = draggingBookmark && bookmarksRect.IsHovered(); - - var lerpSpeed = 12; - - for (int i = 0; i < gaps.Count; i++) - if (makeSpaceForDraggedBookmark && i == insertDraggedBookmarkAtIndex) - gaps[i] = MathUtil.Lerp(gaps[i], GetBookmarkWidth(draggedBookmark), lerpSpeed, editorDeltaTime); - else - gaps[i] = MathUtil.Lerp(gaps[i], 0, lerpSpeed, editorDeltaTime); - - - - for (int i = 0; i < gaps.Count; i++) - if (gaps[i].Approx(0)) - gaps[i] = 0; - - - - animatingGaps = gaps.Any(r => r > .1f); - - - } - void droppedBookmark_() - { - if (!animatingDroppedBookmark) return; - - var lerpSpeed = 8; - - var targX = GetBookmarkCenterX(data.bookmarks.IndexOf(droppedBookmark), includeGaps: false); - - MathUtil.SmoothDamp(ref droppedBookmarkX, targX, lerpSpeed, ref droppedBookmarkXDerivative, editorDeltaTime); - - if ((droppedBookmarkX - targX).Abs() < .5f) - animatingDroppedBookmark = false; - - } - void tooltip() - { - if (!mouseHoversBookmark || lastHoveredBookmark != lastClickedBookmark) - hideTooltip = false; - - - var lerpSpeed = UnityEditorInternal.InternalEditorUtility.isApplicationActive ? 15 : 12321; - - if (mouseHoversBookmark && !draggingBookmark && !hideTooltip) - MathUtil.SmoothDamp(ref tooltipOpacity, 1, lerpSpeed, ref tooltipOpacityDerivative, editorDeltaTime); - else - MathUtil.SmoothDamp(ref tooltipOpacity, 0, lerpSpeed, ref tooltipOpacityDerivative, editorDeltaTime); - - - if (tooltipOpacity > .99f) - tooltipOpacity = 1; - - if (tooltipOpacity < .01f) - tooltipOpacity = 0; - - - animatingTooltip = tooltipOpacity != 0 && tooltipOpacity != 1; - - } - - gaps_(); - droppedBookmark_(); - tooltip(); - - } - - float droppedBookmarkX; - float droppedBookmarkXDerivative; - - float tooltipOpacity; - float tooltipOpacityDerivative; - - bool animatingDroppedBookmark; - bool animatingGaps; - bool animatingTooltip; - bool animatingBookmarks => animatingDroppedBookmark || animatingGaps; - - bool hideTooltip; - - List gaps - { - get - { - while (_gaps.Count < data.bookmarks.Count + 1) _gaps.Add(0); - while (_gaps.Count > data.bookmarks.Count + 1) _gaps.RemoveLast(); - - return _gaps; - - } - } - List _gaps = new(); - - Bookmark lastClickedBookmark; - - - - - - - - - - - - - - public VFoldersNavbar(EditorWindow window) - { - this.window = window; - - if (!VFoldersHistorySingleton.instance.histories_byWindow.TryGetValue(window, out history)) - VFoldersHistorySingleton.instance.histories_byWindow[window] = history = new VFoldersHistory(window); - - } - - public EditorWindow window; - public VFoldersHistory history; - - public VFoldersController controller => VFolders.controllers_byWindow[window]; - - - } -} -#endif \ No newline at end of file diff --git a/Assets/Plugins/vFolders/VFoldersNavbar.cs.meta b/Assets/Plugins/vFolders/VFoldersNavbar.cs.meta deleted file mode 100644 index 25cfaa7d1..000000000 --- a/Assets/Plugins/vFolders/VFoldersNavbar.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 30acd0784e948403f8f15047ab22692c -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Plugins/vFolders/VFoldersPalette.cs b/Assets/Plugins/vFolders/VFoldersPalette.cs deleted file mode 100644 index ab6eb4b5c..000000000 --- a/Assets/Plugins/vFolders/VFoldersPalette.cs +++ /dev/null @@ -1,268 +0,0 @@ -#if UNITY_EDITOR -using System.Collections; -using System.Collections.Generic; -using UnityEngine; -using UnityEditor; -using UnityEditor.ShortcutManagement; -using System.Reflection; -using System.Linq; -using UnityEngine.UIElements; -using UnityEngine.SceneManagement; -using UnityEditor.SceneManagement; -using UnityEditorInternal; -using static VFolders.Libs.VUtils; -using static VFolders.Libs.VGUI; -// using static VTools.VDebug; - - -namespace VFolders -{ - public class VFoldersPalette : ScriptableObject - { - public List colors = new(); - - public bool colorsEnabled; - - public float colorSaturation = 1; - public float colorBrightness = 1; - public bool colorGradientsEnabled = true; - - public void ResetColors() - { - colors.Clear(); - - for (int i = 0; i < colorsCount; i++) - colors.Add(GetDefaultColor(i)); - - colorsEnabled = true; - - this.Dirty(); - - } - - - public static Color GetDefaultColor(int colorIndex) - { - Color color = default; - - void grey() - { - if (colorIndex >= greyColorsCount) return; - -#if UNITY_2022_1_OR_NEWER - color = Greyscale(EditorGUIUtility.isProSkin ? .16f : .9f); -#else - color = Greyscale(EditorGUIUtility.isProSkin ? .315f : .9f); -#endif - - } - void rainbowDarkTheme() - { - if (colorIndex < greyColorsCount) return; - if (!isDarkTheme) return; - - - var t = (colorIndex - greyColorsCount.ToFloat()) / rainbowColorsCount; - - if (colorIndex == 0) - t += .01f; - - if (colorIndex == 1) - t -= .02f; - - if (colorIndex == 2) - t -= .015f; - - if (colorIndex == 3) - t -= .01f; - - if (colorIndex == 4) - t += .02f; - - if (colorIndex == 5) - t += .01f; - - - if (colorIndex == 8) - t -= .01f; - - - // color = HSLToRGB(t, .61f, .57f); - color = ColorUtils.HSLToRGB(t, .61f, .57f); - - - if (colorIndex == 0) - color *= 1.16f; - - if (colorIndex == 1) - color *= 1.17f; - - if (colorIndex == 2) - color *= 1.03f; - - if (colorIndex == 6) - color *= 1.2f; - - if (colorIndex == 7) - color *= 1.55f; - - if (colorIndex == 8) - color *= 1.2f; - - if (colorIndex == 9) - color *= 1.08f; - - - color.a = .1f; - - } - void rainbowLightTheme() - { - if (colorIndex < greyColorsCount) return; - if (isDarkTheme) return; - - color = ColorUtils.HSLToRGB((colorIndex - greyColorsCount.ToFloat()) / rainbowColorsCount, .99f, .75f); - - if (colorIndex == 0) - color *= 1.1f; - - if (colorIndex == 1) - color *= 1.05f; - - color.a = .1f; - - } - - grey(); - rainbowDarkTheme(); - rainbowLightTheme(); - - return color; - - } - - public static int greyColorsCount = 0; - public static int rainbowColorsCount = 10; - public static int colorsCount => greyColorsCount + rainbowColorsCount; - - - - - public List iconRows = new(); - - [System.Serializable] - public class IconRow - { - public List builtinIcons = new(); // names - public List customIcons = new(); // guids - - public bool enabled = true; - - public bool isCustom => !builtinIcons.Any() || customIcons.Any(); - public bool isEmpty => !builtinIcons.Any() && !customIcons.Any(); - public int iconCount => builtinIcons.Count + customIcons.Count; - - public IconRow(string[] builtinIcons) => this.builtinIcons = builtinIcons.ToList(); - public IconRow() { } - - } - - public void ResetIcons() - { - iconRows.Clear(); - - iconRows.Add(new IconRow(new[] - { - "SceneAsset Icon", - "Prefab Icon", - "PrefabModel Icon", - "Material Icon", - "Texture Icon", - "Mesh Icon", - "cs Script Icon", - "Shader Icon", - "ComputeShader Icon", - "ScriptableObject Icon", - - })); - iconRows.Add(new IconRow(new[] - { - "Light Icon", - "LightProbes Icon", - "LightmapParameters Icon", - "LightingDataAsset Icon", - "Cubemap Icon" - - })); - iconRows.Add(new IconRow(new[] - { - #if UNITY_6000_0_OR_NEWER - "PhysicsMaterial Icon", - #else - "PhysicMaterial Icon", - #endif - "BoxCollider Icon", - "TerrainCollider Icon", - "MeshCollider Icon", - "WheelCollider Icon", - "Rigidbody Icon", - - })); - iconRows.Add(new IconRow(new[] - { - "AudioClip Icon", - "AudioMixerController Icon", - "AudioMixerGroup Icon", - "AudioEchoFilter Icon", - "AudioSource Icon", - - })); - iconRows.Add(new IconRow(new[] - { - "TextAsset Icon", - "AssemblyDefinitionAsset Icon", - "TerrainData Icon", - "Terrain Icon", - "AnimatorController Icon", - "AnimationClip Icon", - "Font Icon", - "RawImage Icon", - "Settings Icon", - - })); - - this.Dirty(); - - } - - - - - [ContextMenu("Export palette")] - public void Export() - { - var packagePath = EditorUtility.SaveFilePanel("Export vFolders Palette", "", this.GetPath().GetFilename(withExtension: false), "unitypackage"); - - var iconPaths = iconRows.SelectMany(r => r.customIcons).Select(r => r.ToPath()).Where(r => !r.IsNullOrEmpty()); - - AssetDatabase.ExportPackage(iconPaths.Append(this.GetPath()).ToArray(), packagePath); - - EditorUtility.RevealInFinder(packagePath); - - } - - - - - void Reset() - { - ResetColors(); - ResetIcons(); - - VFolders.folderInfoCache.Clear(); - - } - - } -} -#endif \ No newline at end of file diff --git a/Assets/Plugins/vFolders/VFoldersPalette.cs.meta b/Assets/Plugins/vFolders/VFoldersPalette.cs.meta deleted file mode 100644 index 318740f03..000000000 --- a/Assets/Plugins/vFolders/VFoldersPalette.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 618f730fcd14941fab38169a7dde8c64 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Plugins/vFolders/VFoldersPaletteEditor.cs b/Assets/Plugins/vFolders/VFoldersPaletteEditor.cs deleted file mode 100644 index 081c9aa8a..000000000 --- a/Assets/Plugins/vFolders/VFoldersPaletteEditor.cs +++ /dev/null @@ -1,1375 +0,0 @@ -#if UNITY_EDITOR -using System.Collections; -using System.Collections.Generic; -using UnityEngine; -using UnityEditor; -using UnityEditor.ShortcutManagement; -using System.Reflection; -using System.Linq; -using UnityEditorInternal; -using UnityEngine.UIElements; -using UnityEngine.SceneManagement; -using UnityEditor.SceneManagement; -using UnityEditor.IMGUI.Controls; -using static VFolders.Libs.VUtils; -using static VFolders.Libs.VGUI; -// using static VTools.VDebug; -using static VFolders.VFoldersPalette; - - -namespace VFolders -{ - [CustomEditor(typeof(VFoldersPalette))] - class VFoldersPaletteEditor : Editor - { - - public override void OnInspectorGUI() - { - void colors() - { - var rowRect = ExpandWidthLabelRect(cellSize).SetX(rowsOffsetX).SetWidth(rowWidth + 16); - - void backgroundHovered() - { - if (!rowRect.IsHovered()) return; - if (pickingColor) return; - if (draggingRow) return; - - rowRect.Draw(hoveredRowBackground); - - } - void toggle() - { - var toggleRect = rowRect.SetWidth(16).MoveX(5); - - var prevEnabled = palette.colorsEnabled; - var newEnabled = EditorGUI.Toggle(toggleRect, palette.colorsEnabled); - - if (prevEnabled != newEnabled) - palette.RecordUndo(); - - palette.colorsEnabled = newEnabled; - - if (prevEnabled != newEnabled) - palette.Dirty(); - - } - void crossIcon() - { - var crossIconRect = rowRect.SetX(rowsOffsetX + iconsOffsetX + iconSpacing / 2).SetWidth(iconSize).SetHeightFromMid(iconSize); - - SetGUIColor(palette.colorsEnabled ? Color.white : disabledRowTint); - - GUI.DrawTexture(crossIconRect, EditorIcons.GetIcon("CrossIcon")); - - ResetGUIColor(); - - } - void color(int i) - { - var cellRect = rowRect.MoveX(iconsOffsetX + (i + 1) * cellSize).SetWidth(cellSize).SetHeightFromMid(cellSize); - - void backgroundPicking() - { - if (!pickingColor) return; - if (i != pickingColorAtIndex) return; - - cellRect.DrawRounded(pickingBackground, 2); - - } - void backgroundHovered_andStartPickingColor() - { - if (pickingColor) return; - if (!cellRect.IsHovered()) return; - - - SetGUIColor(Color.clear); - - var clicked = GUI.Button(cellRect.Resize(1), ""); - - ResetGUIColor(); - - - - - var isPressed = GUIUtility.hotControl == typeof(EditorGUIUtility).GetFieldValue("s_LastControlID"); - - cellRect.DrawRounded(Greyscale(isPressed ? .39f : .43f), 2); - - - - - if (!clicked) return; - - colorPickerWindow = EditorUtils.OpenColorPicker((c) => { palette.RecordUndo(); palette.Dirty(); palette.colors[i] = c; }, palette.colors[i], true, false); - - colorPickerWindow.MoveTo(EditorGUIUtility.GUIToScreenPoint(cellRect.Move(-3, 50).position)); - - pickingColor = true; - pickingColorAtIndex = i; - - } - void colorOutline() - { - var outlineColor = i < VFoldersPalette.greyColorsCount ? Greyscale(.0f, .4f) : Greyscale(.15f, .2f); - - if (!palette.colorsEnabled) - outlineColor *= disabledRowTint; - - - cellRect.Resize(3).DrawRounded(outlineColor, 4); - - } - void color() - { - var brightness = palette.colorBrightness; - var saturation = palette.colorSaturation; - var drawGradients = palette.colorGradientsEnabled; - - if (!palette.colorGradientsEnabled) - brightness *= isDarkTheme ? .75f : .97f; - - if (i < VFoldersPalette.greyColorsCount) - { - saturation = brightness = 1; - drawGradients = false; - } - - - var colorRaw = palette.colors[i]; - - var color = MathUtil.Lerp(Greyscale(.2f), colorRaw, brightness); - - Color.RGBToHSV(color, out float h, out float s, out float v); - color = Color.HSVToRGB(h, s * saturation, v); - - color = MathUtil.Lerp(color, colorRaw, .5f).SetAlpha(1); - - if (!palette.colorsEnabled) - color *= disabledRowTint; - - - - - cellRect.Resize(4).DrawRounded(color, 3); - - if (drawGradients) - cellRect.Resize(4).AddWidthFromRight(-2).DrawCurtainLeft(GUIColors.windowBackground.SetAlpha(.45f)); - - } - void updatePickingColor() - { - if (!pickingColor) return; - - EditorApplication.RepaintProjectWindow(); - - } - void stopPickingColor() - { - if (!pickingColor) return; - if (colorPickerWindow) return; - - pickingColor = false; - - } - - - cellRect.MarkInteractive(); - - - backgroundPicking(); - backgroundHovered_andStartPickingColor(); - - colorOutline(); - color(); - - updatePickingColor(); - stopPickingColor(); - - } - void adjustColorsButton() - { - var cellRect = rowRect.MoveX(iconsOffsetX + (palette.colors.Count + 1) * cellSize).SetWidth(cellSize).SetHeightFromMid(cellSize).MoveX(-1f); - - - var iconSize = 16; - var iconName = "Preset.Context"; - var iconColor = Greyscale(.75f, palette.colorsEnabled ? (isDarkTheme ? 1 : .8f) : .5f); - - if (!IconButton(cellRect, iconName, iconSize, iconColor)) return; - - - if (adjustColorsWindow) { adjustColorsWindow.Close(); return; } - - var windowX = 107f.Min(this.GetMemberValue("propertyViewer").position.width - 310); - var windowY = cellRect.y + 25; - var windowWidth = 270; - var windowHeight = VFoldersMenu.backgroundColorsEnabled ? 92 : 73; - - adjustColorsWindow = ScriptableObject.CreateInstance(); - adjustColorsWindow.palette = palette; - adjustColorsWindow.paletteEditor = this; - - adjustColorsWindow.ShowPopup(); - adjustColorsWindow.Focus(); - - adjustColorsWindow.position = EditorGUIUtility.GUIToScreenRect(new Rect(windowX, windowY, windowWidth, windowHeight)); - - } - - - backgroundHovered(); - toggle(); - crossIcon(); - - for (int i = 0; i < palette.colors.Count; i++) - color(i); - - adjustColorsButton(); - - Space(rowSpacing - 2); - - } - void icons() - { - void row(Rect rowRect, IconRow row) - { - var isLastRow = row == palette.iconRows.Last(); - var isDraggedRow = row == draggedRow; - var spaceForCrossIcon = 0f; - - - void updatePickingIcon() - { - if (!pickingIcon) return; - if (pickingIconAtRow != row) return; - if (pickingIconAtIndex >= row.customIcons.Count) return; // somehow happens if RecordUndo is used - - palette.RecordUndo(); - palette.Dirty(); - - row.customIcons[pickingIconAtIndex] = addIconWindow.hoveredIconName; - - } - void stopPickingIcon() - { - if (!pickingIcon) return; - if (pickingIconAtRow != row) return; - if (addIconWindow) return; - - if (pickingIconAtIndex < row.customIcons.Count) - if (row.customIcons[pickingIconAtIndex] == null) - row.customIcons.RemoveAt(pickingIconAtIndex); - - pickingIcon = false; - - } - void dragndrop() - { - if (!rowRect.IsHovered()) return; - if (!row.isCustom) return; - - if (curEvent.isDragUpdate && DragAndDrop.objectReferences.First() is Texture2D) - DragAndDrop.visualMode = DragAndDropVisualMode.Copy; - - if (!curEvent.isDragPerform) return; - if (!(DragAndDrop.objectReferences.Any(r => r is Texture2D))) return; - - DragAndDrop.AcceptDrag(); - - palette.RecordUndo(); - palette.Dirty(); - - foreach (var icon in DragAndDrop.objectReferences.Where(r => r is Texture2D)) - row.customIcons.Add(icon.GetPath().ToGuid()); - - } - - void calcSpaceForCrossIcon() - { - if (row == curFirstEnabledRow) - spaceForCrossIcon = crossIconAnimationT * cellSize; - - if (row == crossIconAnimationSourceRow) - spaceForCrossIcon = (1 - crossIconAnimationT) * cellSize; - - } - - void backgroundHovered() - { - if (!rowRect.IsHovered()) return; - if (pickingColor) return; - if (pickingIcon) return; - if (draggingRow) return; - if (DragAndDrop.objectReferences.Any() && !row.isCustom) return; - - - rowRect.Draw(hoveredRowBackground); - - } - void backgroundDragged() - { - if (!isDraggedRow) return; - - rowRect.DrawBlurred(Greyscale(0, .3f), 12); - rowRect.Draw(draggedRowBackground); - - } - void toggle() - { - var prevEnabled = row.enabled; - var newEnabled = EditorGUI.Toggle(rowRect.SetWidth(16).MoveX(5), row.enabled); - - if (prevEnabled != newEnabled) - palette.RecordUndo(); - - row.enabled = newEnabled; - - if (prevEnabled != newEnabled) - palette.Dirty(); - - } - void addIconButton() - { - if (!row.isCustom) return; - if (pickingIcon && pickingIconAtRow == row) return; - - - var cellRect = rowRect.MoveX(iconsOffsetX + row.customIcons.Count * cellSize + spaceForCrossIcon).SetWidth(cellSize).SetHeightFromMid(cellSize); - - var iconSize = 16; - var iconName = "Toolbar Plus"; - var iconColor = Greyscale(.73f, row.enabled ? (isDarkTheme ? 1 : .65f) : .5f); - - if (!IconButton(cellRect, iconName, iconSize, iconColor)) return; - - - - palette.RecordUndo(); - - row.customIcons.Add(null); - - - - var windowX = 15; - var windowY = cellRect.y + 23; - var windowWidth = (this.GetMemberValue("propertyViewer").position.width - 26).Min(679); - var windowHeight = windowWidth * 1.2f; - - windowWidth = (windowWidth / AddIconWindow.cellSize).FloorToInt() * AddIconWindow.cellSize - 3; - - - addIconWindow = ScriptableObject.CreateInstance(); - addIconWindow.palette = palette; - addIconWindow.paletteEditor = this; - - addIconWindow.ShowPopup(); - addIconWindow.Focus(); - - addIconWindow.position = EditorGUIUtility.GUIToScreenRect(new Rect(windowX, windowY, windowWidth, windowHeight)); - - addIconWindow.Init(); - - - pickingIcon = true; - pickingIconAtIndex = row.customIcons.Count - 1; - pickingIconAtRow = row; - - - } - void icon(int i) - { - var cellRect = rowRect.MoveX(iconsOffsetX + spaceForCrossIcon + i * cellSize).SetWidth(cellSize).SetHeightFromMid(cellSize); - - - void backgroundPicking() - { - if (!pickingIcon) return; - if (pickingIconAtRow != row) return; - if (pickingIconAtIndex != i) return; - - cellRect.DrawRounded(pickingBackground, 2); - - } - void backgroundHovered_andEditIconButton() - { - if (!row.isCustom) return; - if (pickingIcon) return; - if (!cellRect.IsHovered()) return; - if (DragAndDrop.objectReferences.Any()) return; - - - SetGUIColor(Color.clear); - - var clicked = GUI.Button(cellRect.Resize(1), ""); - - ResetGUIColor(); - - - - - var isPressed = GUIUtility.hotControl == typeof(EditorGUIUtility).GetFieldValue("s_LastControlID"); - - cellRect.DrawRounded(Greyscale(isPressed ? .39f : .45f), 2); - - - - - if (!clicked) return; - - GenericMenu menu = new(); - - menu.AddItem(new GUIContent("Move left"), false, i == 0 ? null : () => - { - palette.RecordUndo(); - palette.Dirty(); - - var icon = row.customIcons[i]; - - row.customIcons.RemoveAt(i); - row.customIcons.AddAt(icon, i - 1); - - }); - menu.AddItem(new GUIContent("Move right"), false, i == row.customIcons.Count - 1 ? null : () => - { - palette.RecordUndo(); - palette.Dirty(); - - var icon = row.customIcons[i]; - - row.customIcons.RemoveAt(i); - row.customIcons.AddAt(icon, i + 1); - - }); - - menu.AddSeparator(""); - - menu.AddItem(new GUIContent("Remove icon"), false, () => { palette.RecordUndo(); row.customIcons.RemoveAt(i); palette.Dirty(); }); - - - menu.ShowAsContext(); - - } - - void drawIcon() - { - var iconNameOrGuid = row.isCustom ? row.customIcons[i] : row.builtinIcons[i]; - - if (iconNameOrGuid == null) return; - - var iconNameOrPath = iconNameOrGuid.Length == 32 ? iconNameOrGuid.ToPath() : iconNameOrGuid; - var icon = EditorIcons.GetIcon(iconNameOrPath) ?? Texture2D.blackTexture; - - - var cellRect = rowRect.MoveX(iconsOffsetX + spaceForCrossIcon + i * cellSize).SetWidth(cellSize).SetHeightFromMid(cellSize); - var iconRect = cellRect.SetSizeFromMid(iconSize); - - if (icon.width < icon.height) iconRect = iconRect.SetWidthFromMid(iconRect.height * icon.width / icon.height); - if (icon.height < icon.width) iconRect = iconRect.SetHeightFromMid(iconRect.width * icon.height / icon.width); - - - - SetGUIColor(row.enabled ? Color.white : disabledRowTint); - - GUI.DrawTexture(iconRect, icon); - - ResetGUIColor(); - - } - - - cellRect.MarkInteractive(); - - backgroundPicking(); - backgroundHovered_andEditIconButton(); - - drawIcon(); - - } - - - rowRect.MarkInteractive(); - - updatePickingIcon(); - stopPickingIcon(); - dragndrop(); - - calcSpaceForCrossIcon(); - backgroundHovered(); - backgroundDragged(); - toggle(); - addIconButton(); - - for (int i = 0; i < row.iconCount; i++) - icon(i); - - } - - void updateRowsCount() - { - palette.iconRows.RemoveAll(r => r.isEmpty && r != palette.iconRows.Last()); - - if (!palette.iconRows.Last().isEmpty) - palette.iconRows.Add(new IconRow()); - - } - void updateRowGapsCount() - { - while (rowGaps.Count < palette.iconRows.Count) - rowGaps.Add(0); - - while (rowGaps.Count > palette.iconRows.Count) - rowGaps.RemoveLast(); - - } - - void normalRow(int i) - { - Space(rowGaps[i] * (cellSize + rowSpacing)); - - if (i == 0 && lastRect.y != 0) - firstRowY = lastRect.y; - - Space(cellSize + rowSpacing); - - var rowRect = Rect.zero.SetPos(rowsOffsetX, lastRect.y).SetSize(rowWidth, cellSize); - - if (curEvent.isRepaint) - if (rowRect.IsHovered()) - hoveredRow = palette.iconRows[i]; - - - row(rowRect, palette.iconRows[i]); - - } - void draggedRow_() - { - if (!draggingRow) return; - - draggedRowY = (curEvent.mousePosition.y + draggedRowHoldOffset).Clamp(firstRowY, firstRowY + (palette.iconRows.Count - 1) * (cellSize + rowSpacing)); - - var rowRect = Rect.zero.SetPos(rowsOffsetX, draggedRowY).SetSize(rowWidth, cellSize); - - row(rowRect, draggedRow); - - } - void crossIcon() - { - if (!palette.iconRows.Any(r => r.enabled)) return; - - var rect = Rect.zero.SetPos(rowsOffsetX + iconsOffsetX, crossIconY).SetSize(cellSize, cellSize).Resize(iconSpacing / 2); - - GUI.DrawTexture(rect, EditorIcons.GetIcon("CrossIcon")); - - } - - - updateRowsCount(); - updateRowGapsCount(); - - - if (curEvent.isRepaint) - hoveredRow = null; - - for (int i = 0; i < palette.iconRows.Count; i++) - normalRow(i); - - crossIcon(); - - draggedRow_(); - - - } - void tutor() - { - SetGUIEnabled(false); - - - Space(4); - GUILayout.Label("Add icons with drag-and-drop or by clicking '+'"); - - Space(4); - GUILayout.Label("Click added icon to move or remove it"); - - Space(4); - GUILayout.Label("Drag rows to reorder them"); - - - ResetGUIEnabled(); - - } - - - Space(15); - colors(); - - Space(15); - icons(); - - Space(22); - tutor(); - - UpdateAnimations(); - - UpdateDragging(); - - palette.Dirty(); - - if (draggingRow || animatingCrossIcon) - Repaint(); - - } - - float iconSize => 14; - float iconSpacing => 6; - float cellSize => iconSize + iconSpacing; - float rowSpacing = 1; - float rowsOffsetX => 14; - float iconsOffsetX => 27; - - Color hoveredRowBackground => Greyscale(isDarkTheme ? 1 : 0, .05f); - Color draggedRowBackground => Greyscale(isDarkTheme ? .3f : .9f); - Color pickingBackground => Greyscale(1, .17f); - Color disabledRowTint => Greyscale(1, .45f); - - float rowWidth => cellSize * Mathf.Max(palette.colors.Count, palette.iconRows.Max(r => r.iconCount + 1)) + 55; - - bool pickingColor; - int pickingColorAtIndex; - EditorWindow colorPickerWindow; - - bool pickingIcon; - int pickingIconAtIndex; - IconRow pickingIconAtRow; - AddIconWindow addIconWindow; - - IconRow hoveredRow; - - float firstRowY = 51; - - static AdjustColorsWindow adjustColorsWindow; - - - - - - void UpdateAnimations() - { - void lerpRowGaps() - { - if (!curEvent.isLayout) return; - - var lerpSpeed = draggingRow ? 12 : 12321; - - for (int i = 0; i < rowGaps.Count; i++) - rowGaps[i] = MathUtil.Lerp(rowGaps[i], draggingRow && i == insertDraggedRowAtIndex ? 1 : 0, lerpSpeed, editorDeltaTime); - - for (int i = 0; i < rowGaps.Count; i++) - if (rowGaps[i].Approx(0)) - rowGaps[i] = 0; - else if (rowGaps[i].Approx(1)) - rowGaps[i] = 1; - - - } - - void lerpCrossIconAnimationT() - { - if (!curEvent.isLayout) return; - - var lerpSpeed = 12; - - MathUtil.Lerp(ref crossIconAnimationT, 1, lerpSpeed, editorDeltaTime); - - } - void startCrossIconAnimation() - { - if (prevFirstEnabledRow == null) { prevFirstEnabledRow = curFirstEnabledRow; return; } - if (prevFirstEnabledRow == curFirstEnabledRow) return; - - crossIconAnimationT = 0; - crossIconAnimationSourceRow = prevFirstEnabledRow; - - prevFirstEnabledRow = curFirstEnabledRow; - - } - void stopCrossIconAnimation() - { - if (!crossIconAnimationT.Approx(1)) return; - - crossIconAnimationT = 1; - crossIconAnimationSourceRow = null; - - } - void calcCrossIconY() - { - var indexOfFirstEnabled = palette.iconRows.IndexOfFirst(r => r.enabled); - var yOfFirstEnabled = firstRowY + indexOfFirstEnabled * (cellSize + rowSpacing); - for (int i = 0; i < indexOfFirstEnabled + 1; i++) - yOfFirstEnabled += rowGaps[i] * (cellSize + rowSpacing); - - - var indexOfSourceRow = palette.iconRows.IndexOf(crossIconAnimationSourceRow); - var yOfSourceRow = firstRowY + indexOfSourceRow * (cellSize + rowSpacing); - for (int i = 0; i < indexOfSourceRow + 1; i++) - yOfSourceRow += rowGaps[i] * (cellSize + rowSpacing); - - if (crossIconAnimationSourceRow == draggedRow) - yOfSourceRow = draggedRowY; - - - crossIconY = MathUtil.Lerp(yOfSourceRow, yOfFirstEnabled, crossIconAnimationT); - - if (indexOfFirstEnabled == indexOfSourceRow) - crossIconAnimationT = 1; - - } - - - lerpRowGaps(); - - lerpCrossIconAnimationT(); - startCrossIconAnimation(); - stopCrossIconAnimation(); - calcCrossIconY(); - - } - - List rowGaps = new(); - - float crossIconY = 51; - float crossIconAnimationT = 1; - IconRow crossIconAnimationSourceRow; - bool animatingCrossIcon => crossIconAnimationT != 1; - - [System.NonSerialized] IconRow prevFirstEnabledRow; - IconRow curFirstEnabledRow => palette.iconRows.FirstOrDefault(r => r.enabled); - - - - - - - void UpdateDragging() - { - void startDragging() - { - if (draggingRow) return; - if (!curEvent.isMouseDrag) return; - if (hoveredRow == null) return; - if (hoveredRow == palette.iconRows.Last()) return; - - palette.RecordUndo(); - - draggingRow = true; - draggedRow = hoveredRow; - draggingRowFromIndex = palette.iconRows.IndexOf(hoveredRow); - draggedRowHoldOffset = firstRowY + draggingRowFromIndex * (cellSize + rowSpacing) - curEvent.mousePosition.y; - - palette.iconRows.Remove(hoveredRow); - rowGaps[draggingRowFromIndex] = 1; - - } - void updateDragging() - { - if (!draggingRow) return; - - insertDraggedRowAtIndex = ((curEvent.mousePosition.y - firstRowY) / (cellSize + rowSpacing)).FloorToInt().Clamp(0, palette.iconRows.Count - 1); - - EditorGUIUtility.hotControl = EditorGUIUtility.GetControlID(FocusType.Passive); - - } - void stopDragging() - { - if (!draggingRow) return; - if (!curEvent.isMouseUp) return; - - palette.RecordUndo(); - palette.Dirty(); - - palette.iconRows.AddAt(draggedRow, insertDraggedRowAtIndex); - - rowGaps[insertDraggedRowAtIndex] = 0; - - draggingRow = false; - draggedRow = null; - - EditorGUIUtility.hotControl = 0; - - } - - - startDragging(); - updateDragging(); - stopDragging(); - - } - - IconRow draggedRow; - bool draggingRow; - int draggingRowFromIndex; - float draggedRowHoldOffset; - float draggedRowY; - int insertDraggedRowAtIndex; - - - - - - - VFoldersPalette palette => target as VFoldersPalette; - - } - - - class AddIconWindow : EditorWindow - { - - void OnGUI() - { - void header() - { - var headerRect = Rect.zero.SetHeight(20).SetWidth(position.width); - var closeButtonRect = headerRect.SetWidthFromRight(16).SetHeightFromMid(16).Move(-3, -.5f); - - void background() - { - headerRect.Draw(EditorGUIUtility.isProSkin ? Greyscale(.18f) : Greyscale(.7f)); - } - void title() - { - SetGUIColor(Greyscale(.8f)); - SetLabelAlignmentCenter(); - - GUI.Label(headerRect.MoveY(-1), "Add icon"); - - ResetLabelStyle(); - ResetGUIColor(); - - } - void closeButton() - { - var colorNormal = isDarkTheme ? Greyscale(.55f) : Greyscale(.35f); - var colorHovered = isDarkTheme ? Greyscale(.9f) : colorNormal; - - var iconSize = 14; - - if (IconButton(closeButtonRect, "CrossIcon", iconSize, colorNormal, colorHovered)) - Close(); - - } - void escHint() - { - if (!closeButtonRect.IsHovered()) return; - - var textRect = headerRect.SetWidthFromRight(42).MoveY(-.5f).MoveX(1); - var fontSize = 11; - var color = Greyscale(.65f); - - - SetLabelFontSize(fontSize); - SetGUIColor(color); - - GUI.Label(textRect, "Esc"); - - ResetGUIColor(); - ResetLabelStyle(); - - } - - background(); - title(); - closeButton(); - escHint(); - - Space(headerRect.height); - - } - void search() - { - var backgroundRect = ExpandWidthLabelRect(height: 21).SetWidthFromMid(position.width); - var backgroundColor = isDarkTheme ? Greyscale(.25f) : Greyscale(.8f); - - backgroundRect.Draw(backgroundColor); - - - var lineRect = backgroundRect.SetHeightFromBottom(1).MoveY(.5f); - var lineColor = isDarkTheme ? Greyscale(.15f) : Greyscale(.7f); - - lineRect.Draw(lineColor); - - - var searchRect = backgroundRect.Resize(2); - - EditorGUI.BeginChangeCheck(); - - searchString = searchField.OnGUI(searchRect, searchString); - - if (EditorGUI.EndChangeCheck()) - { - GenerateRows(); - FilterIconsBySearch(); - GenerateRows(); - } - - } - void icons() - { - void row(int i) - { - var rowRect = position.SetPos(0, 0).SetHeight(cellSize).MoveY(i * rowHeight); - var iconNames = rows[i]; - - void icon(int i) - { - var iconName = iconNames[i]; - var icon = EditorIcons.GetIcon(iconName); - - var cellRect = rowRect.SetWidth(cellSize).MoveX(i * cellSize + paddingLeft); - var iconRect = cellRect.SetSizeFromMid(iconSize); - - if (icon.width < icon.height) iconRect = iconRect.SetWidthFromMid(iconRect.height * icon.width / icon.height); - if (icon.height < icon.width) iconRect = iconRect.SetHeightFromMid(iconRect.width * icon.height / icon.width); - - - - var hoverRect = cellRect.AddHeightFromMid(rowSpacing); - - hoverRect.MarkInteractive(); - - if (hoverRect.IsHovered()) - cellRect.Draw(Greyscale(isDarkTheme ? .42f : .69f)); - - - - GUI.DrawTexture(iconRect, EditorIcons.GetIcon(iconName)); - - - - if (curEvent.isRepaint) - if (hoverRect.IsHovered()) - hoveredIconName = iconName; - - if (hoverRect.IsHovered() && curEvent.isMouseDown) - Close(); - - } - - for (int ii = 0; ii < iconNames.Count; ii++) - icon(ii); - } - - - if (curEvent.isRepaint) - hoveredIconName = null; - - - scrollPos = GUILayout.BeginScrollView(new Vector2(0, scrollPos)).y; - - GUILayout.Space(rows.Count * rowHeight + 23); - - - var i0 = (scrollPos / rowHeight).FloorToInt(); - var i1 = (i0 + ((position.height - 30) / rowHeight).CeilToInt()).Min(rows.Count); - - for (int ii = i0; ii < i1; ii++) - row(ii); - - - GUILayout.EndScrollView(); - - } - void hoveredIconLabel() - { - if (hoveredIconName == null) return; - - - var nameRect = position.SetPos(0, 0).SetHeightFromBottom(18).SetWidth(hoveredIconName.GetLabelWidth() + 6).Move(1, -1); - - var shadowRect = nameRect.AddWidthFromRight(10).AddHeight(10); - - - shadowRect.DrawBlurred(GUIColors.windowBackground, 12); - shadowRect.DrawBlurred(GUIColors.windowBackground.SetAlpha(.4f), 8); - - - SetLabelAlignmentCenter(); - - GUI.Label(nameRect, hoveredIconName); - - ResetLabelStyle(); - - } - void closeOnEsc() - { - if (!curEvent.isKeyDown) return; - if (curEvent.keyCode != KeyCode.Escape) return; - - hoveredIconName = null; - - Close(); - - } - void outline() - { - if (Application.platform == RuntimePlatform.OSXEditor) return; - - position.SetPos(0, 0).DrawOutline(Greyscale(.1f)); - - } - - header(); - search(); - icons(); - hoveredIconLabel(); - closeOnEsc(); - outline(); - - paletteEditor.Repaint(); - - if (EditorWindow.focusedWindow != this) - Close(); - - } - - public static float iconSize => 16; - public static float iconSpacing => 6; - public static float cellSize => iconSize + iconSpacing; - public static float rowSpacing = 1; - - public static float rowHeight => cellSize + rowSpacing; - - public static float paddingLeft => 3; - public static float paddingRight => 3; - - public string hoveredIconName; - - static string searchString = ""; - static float scrollPos; - - - - - - void LoadAllIcons() - { - if (allIconNames != null) return; - - - (float h, float s, float v, float a) GetAverageColor(Texture2D texture) - { - - var readableTexture = new Texture2D(texture.width, texture.height, texture.format, texture.mipmapCount > 1); - - Graphics.CopyTexture(texture, readableTexture); - - var pixels = readableTexture.GetPixels32(); - - readableTexture.DestroyImmediate(); - - - float hSum = 0; - float sSum = 0; - float vSum = 0; - - int nonTransparentPxCount = pixels.Length; - int coloredPxCount = pixels.Length; - - for (var i = 0; i < pixels.Length; i++) - { - if (pixels[i].a <= .1f) { nonTransparentPxCount--; coloredPxCount--; continue; } - - Color.RGBToHSV(pixels[i], out float h, out float s, out float v); - - if (s > .1f) - hSum += h; - else - coloredPxCount--; - - sSum += s; - - vSum += v; - - } - - var hAvg = hSum / coloredPxCount; - var sAvg = sSum / nonTransparentPxCount; - var vAvg = vSum / nonTransparentPxCount; - var aAvg = nonTransparentPxCount / pixels.Length.ToFloat(); - - if (coloredPxCount == 0) - hAvg = -1; - - - return (hAvg, sAvg, vAvg, aAvg); - - } - - - - var editorAssetBundle = typeof(EditorGUIUtility).InvokeMethod("GetEditorAssetBundle"); - - allIconNames = ( - - from path in editorAssetBundle.GetAllAssetNames() - - - let icon = editorAssetBundle.LoadAsset(path) - - where icon - - - where path.StartsWith("icons/") - where !path.Contains("avatarinspector") - - where !icon.name.ToLower().StartsWith("d_") - - where !icon.name.ToLower().EndsWith(".small") - where !icon.name.ToLower().EndsWith("_sml") - - where !icon.name.Contains("@") - where !icon.name.Contains("TreeEditor") - where !icon.name.Contains("scene-template") - where !icon.name.Contains("StateMachineEditor.Background") - where !icon.name.Contains("SpeedTree") - where !icon.name.Contains("TextMesh") - where !icon.name.Contains("Profiler.Instrumentation") - where !icon.name.Contains("Profiler.Record") - where !icon.name.Contains("SocialNetworks") - where !icon.name.Contains("Groove") - - - - let avgColor = GetAverageColor(icon) - - where avgColor.a > .1f - - - - orderby avgColor.h * -3f - + avgColor.s * .09f - + avgColor.v * 0f, icon.name - - - - select icon.name - - ).ToHashSet() - .ToList(); - - } - - static List allIconNames; - - - - void FilterIconsBySearch() - { - filteredIcons = ( - - from iconName in allIconNames - - where iconName.ToLower().Contains(searchString.ToLower()) - - orderby iconName.ToLower().IndexOf(searchString.ToLower(), System.StringComparison.Ordinal) - - select iconName - - ).ToList(); - } - - static List filteredIcons; - - - - void GenerateRows() - { - - var iconsPerRow = ((position.width - paddingLeft - paddingRight) / cellSize).FloorToInt(); - - rows = new(); - - var curRow = new List(); - - foreach (var icon in filteredIcons) - { - curRow.Add(icon); - - if (curRow.Count == iconsPerRow) - { - rows.Add(curRow); - curRow = new(); - } - } - - if (curRow.Any()) - rows.Add(curRow); - - } - - static List> rows; - - - - - - - public void Init() - { - LoadAllIcons(); - FilterIconsBySearch(); - GenerateRows(); - - searchField = new(); - - } - - SearchField searchField; - - - - - - public VFoldersPalette palette; - public VFoldersPaletteEditor paletteEditor; - - } - - class AdjustColorsWindow : EditorWindow - { - void OnGUI() - { - void header() - { - var headerRect = Rect.zero.SetHeight(20).SetWidth(position.width); - var closeButtonRect = headerRect.SetWidthFromRight(16).SetHeightFromMid(16).Move(-3, -.5f); - - void background() - { - headerRect.Draw(EditorGUIUtility.isProSkin ? Greyscale(.18f) : Greyscale(.7f)); - } - void title() - { - SetGUIColor(Greyscale(.8f)); - SetLabelAlignmentCenter(); - - GUI.Label(headerRect.MoveY(-1), "Adjust colors"); - - ResetLabelStyle(); - ResetGUIColor(); - - } - void closeButton() - { - var colorNormal = isDarkTheme ? Greyscale(.55f) : Greyscale(.35f); - var colorHovered = isDarkTheme ? Greyscale(.9f) : colorNormal; - - var iconSize = 14; - - if (IconButton(closeButtonRect, "CrossIcon", iconSize, colorNormal, colorHovered)) - Close(); - - } - void escHint() - { - if (!closeButtonRect.IsHovered()) return; - - var textRect = headerRect.SetWidthFromRight(42).MoveY(-.5f).MoveX(1); - var fontSize = 11; - var color = Greyscale(.65f); - - - SetLabelFontSize(fontSize); - SetGUIColor(color); - - GUI.Label(textRect, "Esc"); - - ResetGUIColor(); - ResetLabelStyle(); - - } - void outline() - { - if (Application.platform == RuntimePlatform.OSXEditor) return; - - position.SetPos(0, 0).DrawOutline(Greyscale(.1f)); - - } - - background(); - title(); - closeButton(); - escHint(); - outline(); - - Space(headerRect.height); - - } - void body() - { - EditorGUIUtility.labelWidth = 85; - EditorGUIUtility.keyboardControl = 0; - - palette.RecordUndo(); - - - EditorGUI.BeginChangeCheck(); - - palette.colorBrightness = (EditorGUILayout.Slider("Brightness", palette.colorBrightness, 0, 2) / .1f).RoundToInt() * .1f; - palette.colorSaturation = (EditorGUILayout.Slider("Saturation", palette.colorSaturation, 0, 2) / .1f).RoundToInt() * .1f; - - if (VFoldersMenu.backgroundColorsEnabled) - palette.colorGradientsEnabled = EditorGUILayout.Toggle("Gradients", palette.colorGradientsEnabled); - - if (EditorGUI.EndChangeCheck()) - { - paletteEditor.Repaint(); - EditorApplication.RepaintProjectWindow(); - - palette.Dirty(); - - VFolders.folderInfoCache.Clear(); - - } - - - EditorGUIUtility.labelWidth = 0; - - } - void closeOnEsc() - { - if (!curEvent.isKeyDown) return; - if (curEvent.keyCode != KeyCode.Escape) return; - - Close(); - - } - - - header(); - - Space(7); - BeginIndent(10); - - body(); - - EndIndent(5); - - - - closeOnEsc(); - - if (EditorWindow.focusedWindow != this) - Close(); - - Repaint(); // for undo - - } - - public VFoldersPalette palette; - public VFoldersPaletteEditor paletteEditor; - - } - -} -#endif \ No newline at end of file diff --git a/Assets/Plugins/vFolders/VFoldersPaletteEditor.cs.meta b/Assets/Plugins/vFolders/VFoldersPaletteEditor.cs.meta deleted file mode 100644 index 2a387dfa7..000000000 --- a/Assets/Plugins/vFolders/VFoldersPaletteEditor.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 085d323b143d5403fb4beda728e65139 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Plugins/vFolders/VFoldersPaletteWindow.cs b/Assets/Plugins/vFolders/VFoldersPaletteWindow.cs deleted file mode 100644 index 5247f2d3b..000000000 --- a/Assets/Plugins/vFolders/VFoldersPaletteWindow.cs +++ /dev/null @@ -1,783 +0,0 @@ -#if UNITY_EDITOR -using System.Collections; -using System.Collections.Generic; -using UnityEngine; -using UnityEditor; -using UnityEditor.ShortcutManagement; -using System.Reflection; -using System.Linq; -using UnityEngine.UIElements; -using UnityEngine.SceneManagement; -using UnityEditor.SceneManagement; -using Type = System.Type; -using static VFolders.VFolders; -using static VFolders.VFoldersData; -using static VFolders.VFoldersPalette; -using static VFolders.VFoldersCache; -using static VFolders.Libs.VUtils; -using static VFolders.Libs.VGUI; -// using static VTools.VDebug; - - -namespace VFolders -{ - public class VFoldersPaletteWindow : EditorWindow - { - - void OnGUI() - { - if (!palette) { Close(); return; } - - int hoveredColorIndex = -1; - string hoveredIconNameOrGuid = null; - - void background() - { - position.SetPos(0, 0).Draw(windowBackground); - } - void outline() - { - if (Application.platform == RuntimePlatform.OSXEditor) return; - - position.SetPos(0, 0).DrawOutline(Greyscale(.1f)); - - } - void colors() - { - if (!palette.colorsEnabled) return; - - var rowRect = this.position.SetPos(paddingX, paddingY).SetHeight(cellSize); - - - void color(int i) - { - var cellRect = rowRect.MoveX(i * cellSize).SetWidth(cellSize).SetHeightFromMid(cellSize); - - void backgroundSelected() - { - if (!colorIndexes_initial.Contains(i)) return; - - cellRect.Resize(1).DrawRounded(selectedBackground, 2); - - } - void backgroundHovered() - { - if (!cellRect.IsHovered()) return; - - cellRect.Resize(1).DrawRounded(this.hoveredBackground, 2); - - } - void crossIcon() - { - if (i != 0) return; - - GUI.DrawTexture(cellRect.SetSizeFromMid(iconSize), EditorIcons.GetIcon("CrossIcon")); - - } - void colorOutline() - { - if (i == 0) return; - - var outlineColor = i <= VFoldersPalette.greyColorsCount ? Greyscale(.0f, .4f) : Greyscale(.15f, .2f); - - cellRect.Resize(3).DrawRounded(outlineColor, 4); - - } - void color() - { - if (i == 0) return; - - var brightness = palette.colorBrightness; - var saturation = palette.colorSaturation; - var drawGradients = palette.colorGradientsEnabled; - - if (!palette.colorGradientsEnabled) - brightness *= isDarkTheme ? .75f : .97f; - - if (i <= VFoldersPalette.greyColorsCount) - { - saturation = brightness = 1; - drawGradients = false; - } - - - var colorRaw = palette ? palette.colors[i - 1] : VFoldersPalette.GetDefaultColor(i - 1); - - var color = MathUtil.Lerp(Greyscale(.2f), colorRaw, brightness); - - Color.RGBToHSV(color, out float h, out float s, out float v); - color = Color.HSVToRGB(h, s * saturation, v); - - color = MathUtil.Lerp(color, colorRaw, .5f).SetAlpha(1); - - - - - cellRect.Resize(4).DrawRounded(color, 3); - - if (drawGradients) - cellRect.Resize(4).AddWidthFromRight(-2).DrawCurtainLeft(GUIColors.windowBackground.SetAlpha(.45f)); - - } - void recursiveIndicator() - { - if (!curEvent.isRepaint) return; - - - var isRecursive = folderDatas.First().colorIndex == i && folderDatas.First().isColorRecursive; - - if (!isRecursive) return; - - - - var iconRect = cellRect.SetSizeFromMid(16).Move(-6, -7); - var shadowRect = iconRect.Resize(3).Move(2, 1).AddWidthFromRight(3); - var shadowRadius = 4; - - shadowRect.DrawBlurred(GUIColors.windowBackground, shadowRadius); - - - SetGUIColor(Color.white * 2); - - GUI.DrawTexture(iconRect, EditorIcons.GetIcon("UnityEditor.SceneHierarchyWindow@2x")); - - ResetGUIColor(); - - - } - - void setHovered() - { - if (!cellRect.IsHovered()) return; - - hoveredColorIndex = i; - - } - void closeOnClick() - { - if (!cellRect.IsHovered()) return; - if (!curEvent.isMouseUp) return; - - curEvent.Use(); - - Close(); - - } - - - - cellRect.MarkInteractive(); - - backgroundSelected(); - backgroundHovered(); - crossIcon(); - colorOutline(); - color(); - recursiveIndicator(); - - setHovered(); - closeOnClick(); - - } - - - for (int i = 0; i < palette.colors.Count + 1; i++) - color(i); - - } - void icons() - { - void row(int i, IconRow iconRow) - { - var rowRect = this.position.SetPos(paddingX, paddingY).SetHeight(cellSize).MoveY(palette.colorsEnabled ? cellSize + spaceAfterColors : 0).MoveY(i * (cellSize + rowSpacing)); - - var isFirstEnabledRow = palette.iconRows.First(r => r.enabled) == iconRow; - - - void icon(int i) - { - var cellRect = rowRect.MoveX(i * cellSize).SetWidth(cellSize).SetHeightFromMid(cellSize); - - var isCrossIcon = isFirstEnabledRow && i == 0; - var actualIconIndex = isFirstEnabledRow ? i - 1 : i; - var isCustomIcon = !isCrossIcon && actualIconIndex >= iconRow.builtinIcons.Count; - var iconNameOrGuid = isCrossIcon ? "" : isCustomIcon ? iconRow.customIcons[actualIconIndex - iconRow.builtinIcons.Count] : iconRow.builtinIcons[actualIconIndex]; - - - void backgroundSelected() - { - if (!iconNamesOrGuids_initial.Contains(iconNameOrGuid)) return; - - cellRect.Resize(1).DrawRounded(selectedBackground, 2); - - } - void backgroundHovered() - { - if (!cellRect.IsHovered()) return; - - cellRect.Resize(1).DrawRounded(this.hoveredBackground, 2); - - } - void crossIcon() - { - if (!isCrossIcon) return; - - GUI.DrawTexture(cellRect.SetSizeFromMid(iconSize), EditorIcons.GetIcon("CrossIcon")); - - } - void normalIcon() - { - if (isCrossIcon) return; - - var iconNameOrPath = iconNameOrGuid?.Length == 32 ? iconNameOrGuid.ToPath() : iconNameOrGuid; - var icon = EditorIcons.GetIcon(iconNameOrPath) ?? Texture2D.blackTexture; - - var iconRect = cellRect.SetSizeFromMid(iconSize); - - if (icon.width < icon.height) iconRect = iconRect.SetWidthFromMid(iconRect.height * icon.width / icon.height); - if (icon.height < icon.width) iconRect = iconRect.SetHeightFromMid(iconRect.width * icon.height / icon.width); - - - GUI.DrawTexture(iconRect, icon); - - } - void recursiveIndicator() - { - if (!curEvent.isRepaint) return; - - - var isRecursive = folderDatas.First().iconNameOrGuid == iconNameOrGuid && folderDatas.First().isIconRecursive; - - if (!isRecursive) return; - - - - var iconRect = cellRect.SetSizeFromMid(16).Move(-6, -7); - var shadowRect = iconRect.Resize(3).Move(2, 1).AddWidthFromRight(3); - var shadowRadius = 4; - - shadowRect.DrawBlurred(GUIColors.windowBackground, shadowRadius); - - - - SetGUIColor(Color.white * 2); - - GUI.DrawTexture(iconRect, EditorIcons.GetIcon("UnityEditor.SceneHierarchyWindow@2x")); - - ResetGUIColor(); - - - } - - void setHovered() - { - if (!cellRect.IsHovered()) return; - - hoveredIconNameOrGuid = iconNameOrGuid; - - } - void closeOnClick() - { - if (!cellRect.IsHovered()) return; - if (!curEvent.isMouseUp) return; - - curEvent.Use(); - - Close(); - - } - - - - cellRect.MarkInteractive(); - - backgroundSelected(); - backgroundHovered(); - crossIcon(); - normalIcon(); - recursiveIndicator(); - - setHovered(); - closeOnClick(); - - } - - - for (int j = 0; j < iconRow.iconCount + (isFirstEnabledRow ? 1 : 0); j++) - icon(j); - - } - - - var i = 0; - - foreach (var iconRow in palette.iconRows) - { - if (!iconRow.enabled) continue; - if (iconRow.isEmpty) continue; - - row(i, iconRow); - - i++; - } - - } - void editPaletteButton() - { - var buttonRect = position.SetPos(0, 0).SetWidthFromRight(16).SetHeightFromBottom(16).Move(-14, -14); - var buttonColor = isDarkTheme ? Greyscale(.6f) : Greyscale(1, .6f); - - if (!IconButton(buttonRect, "Toolbar Plus", 16, buttonColor)) return; - - - palette.SelectInInspector(frameInProject: false); - - this.Close(); - - } - - void setColorsAndIcons() - { - if (!curEvent.isLayout) return; - - - if (palette.iconRows.Any(r => r.enabled)) - if (hoveredIconNameOrGuid != null) - SetIcon(hoveredIconNameOrGuid, isRecursive: curEvent.holdingAlt); - else - SetInitialIcons(); - - - if (palette.colorsEnabled) - if (hoveredColorIndex != -1) - SetColor(hoveredColorIndex, isRecursive: curEvent.holdingAlt); - else - SetInitialColors(); - - } - void updatePosition() - { - if (!curEvent.isLayout) return; - - void calcDeltaTime() - { - deltaTime = (float)(EditorApplication.timeSinceStartup - lastLayoutTime); - - if (deltaTime > .05f) - deltaTime = .0166f; - - lastLayoutTime = EditorApplication.timeSinceStartup; - - } - void resetCurPos() - { - if (currentPosition != default) return; - - currentPosition = position.position; // position.position is always int, which can't be used for lerping - - } - void lerpCurPos() - { - var speed = 9; - - MathUtil.SmoothDamp(ref currentPosition, targetPosition, speed, ref positionDeriv, deltaTime); - // MathfUtils.Lerp(ref currentPosition, targetPosition, speed, deltaTime); - - } - void setCurPos() - { - position = position.SetPos(currentPosition); - } - - calcDeltaTime(); - resetCurPos(); - lerpCurPos(); - setCurPos(); - - if (!currentPosition.magnitude.Approx(targetPosition.magnitude)) - Repaint(); - - } - void closeOnEscape() - { - if (!curEvent.isKeyDown) return; - if (curEvent.keyCode != KeyCode.Escape) return; - - SetInitialColors(); - SetInitialIcons(); - - Close(); - - } - - - RecordUndoOnDatas(); - - background(); - outline(); - colors(); - icons(); - editPaletteButton(); - - setColorsAndIcons(); - updatePosition(); - closeOnEscape(); - - - - VFolders.folderInfoCache.Clear(); - - EditorApplication.RepaintProjectWindow(); - - EditorApplication.delayCall += EditorApplication.RepaintProjectWindow; // to show icons that will be generated in update - - } - - static float iconSize => 14; - static float iconSpacing => 6; - static float cellSize => iconSize + iconSpacing; - static float spaceAfterColors => 13; - public float rowSpacing = 1; - static float paddingX => 12; - static float paddingY => 12; - - Color windowBackground => isDarkTheme ? Greyscale(.23f) : Greyscale(.75f); - Color selectedBackground => isDarkTheme ? new Color(.3f, .5f, .7f, .8f) : new Color(.3f, .5f, .7f, .6f) * 1.25f; - Color hoveredBackground => isDarkTheme ? Greyscale(1, .3f) : Greyscale(0, .1f); - - public Vector2 targetPosition; - public Vector2 currentPosition; - Vector2 positionDeriv; - float deltaTime; - double lastLayoutTime; - - - - - - - void SetIcon(string iconNameOrGuid, bool isRecursive) - { - foreach (var r in folderDatas) - { - r.isIconRecursive = isRecursive; // setting it firstbecause iconNameOrGuid setter relies on isIconRecursive - r.iconNameOrGuid = iconNameOrGuid; - } - } - void SetColor(int colorIndex, bool isRecursive) - { - foreach (var r in folderDatas) - { - r.isColorRecursive = isRecursive; - r.colorIndex = colorIndex; - } - } - - void SetInitialIcons() - { - for (int i = 0; i < folderDatas.Count; i++) - { - folderDatas[i].isIconRecursive = isIconRecursives_initial[i]; - folderDatas[i].iconNameOrGuid = iconNamesOrGuids_initial[i]; - } - } - void SetInitialColors() - { - for (int i = 0; i < folderDatas.Count; i++) - { - folderDatas[i].isColorRecursive = isColorRecursives_initial[i]; - folderDatas[i].colorIndex = colorIndexes_initial[i]; - } - } - - void RemoveEmptyFolderDatas() - { - if (VFoldersData.storeDataInMetaFiles) return; // empties removed from meta files in SaveData() - - var toRemove = folderDatas.Select(r => r.folderData).Where(r => r.iconNameOrGuid == "" && r.colorIndex == 0); - - foreach (var r in toRemove) - data.folderDatas_byGuid.RemoveValue(r); - - if (toRemove.Any()) - Undo.CollapseUndoOperations(Undo.GetCurrentGroup() - 1); - - } - - void RecordUndoOnDatas() - { - if (!VFoldersData.storeDataInMetaFiles) - if (data) - data.RecordUndo(); - - if (VFoldersData.storeDataInMetaFiles) - foreach (var r in guids) - AssetImporter.GetAtPath(r.ToPath()).RecordUndo(); - - } - void MarkDatasDirty() - { - if (!VFoldersData.storeDataInMetaFiles) - if (data) - data.Dirty(); - - if (VFoldersData.storeDataInMetaFiles) - VFolders.folderDatasFromMetaFiles_byGuid.Clear(); - - } - void SaveData() - { - if (!VFoldersData.storeDataInMetaFiles) return; - // if (!VFoldersData.storeDataInMetaFiles) { data.Save(); return; } - - for (int i = 0; i < guids.Count; i++) - if (folderDatas[i].iconNameOrGuid == "" && folderDatas[i].colorIndex == 0) - AssetImporter.GetAtPath(guids[i].ToPath()).userData = ""; - else - AssetImporter.GetAtPath(guids[i].ToPath()).userData = JsonUtility.ToJson(folderDatas[i].folderData); - - for (int i = 0; i < guids.Count; i++) - AssetImporter.GetAtPath(guids[i].ToPath()).SaveAndReimport(); - - } - - - - - - - - - - void OnLostFocus() - { - if (curEvent.holdingAlt && EditorWindow.focusedWindow?.GetType().Name == "ProjectBrowser") - CloseNextFrameIfNotRefocused(); - else - Close(); - - } - - void CloseNextFrameIfNotRefocused() - { - EditorApplication.delayCall += () => { if (EditorWindow.focusedWindow != this) Close(); }; - } - - - - - static void RepaintOnAlt() // Update - { - if (curEvent.holdingAlt != wasHoldingAlt) - if (EditorWindow.mouseOverWindow is VFoldersPaletteWindow paletteWindow) - paletteWindow.Repaint(); - - wasHoldingAlt = curEvent.holdingAlt; - - } - - static bool wasHoldingAlt; - - - - - - - - - - public void Init(List guids) - { - void createData() - { - if (VFolders.data) return; - - VFolders.data = ScriptableObject.CreateInstance(); - - AssetDatabase.CreateAsset(VFolders.data, GetScriptPath("VFolders").GetParentPath().CombinePath("vFolders Data.asset")); - - } - void createPalette() - { - if (VFolders.palette) return; - - VFolders.palette = ScriptableObject.CreateInstance(); - - AssetDatabase.CreateAsset(VFolders.palette, GetScriptPath("VFolders").GetParentPath().CombinePath("vFolders Palette.asset")); - - } - void setSize() - { - if (!palette.colorsEnabled && !palette.iconRows.Any(r => r.enabled && !r.isEmpty)) // somehow happened on first palette window opening in 2022.3.50 - palette.InvokeMethod("Reset"); - - - - var rowCellCounts = new List(); - - if (palette.colorsEnabled) - rowCellCounts.Add(palette.colors.Count + 1); - - foreach (var r in palette.iconRows.Where(r => r.enabled && !r.isEmpty)) - rowCellCounts.Add(r.iconCount + (r == palette.iconRows.First(r => r.enabled) ? 1 : 0)); - - var width = paddingX - + rowCellCounts.Max() * cellSize - + (rowCellCounts.Last() == rowCellCounts.Max() ? cellSize : 0) - + paddingX; - - - - var iconRowCount = palette.iconRows.Count(r => r.enabled && !r.isEmpty); - - var height = paddingY - + (palette.colorsEnabled ? cellSize : 0) - + (palette.colorsEnabled && palette.iconRows.Any(r => r.enabled && !r.isEmpty) ? spaceAfterColors : 0) - + cellSize * iconRowCount - + rowSpacing * (iconRowCount - 1) - + paddingY; - - - position = position.SetSize(width, height).SetPos(targetPosition); - - } - void getFolderDatas() - { - folderDatas.Clear(); - - foreach (var guid in guids) - folderDatas.Add(new FolderDataWrapper(guid)); - - } - void getInitialState() - { - iconNamesOrGuids_initial = folderDatas.Select(r => r.iconNameOrGuid).ToList(); - colorIndexes_initial = folderDatas.Select(r => r.colorIndex).ToList(); - - isIconRecursives_initial = folderDatas.Select(r => r.isIconRecursive).ToList(); - isColorRecursives_initial = folderDatas.Select(r => r.isColorRecursive).ToList(); - - } - - - this.guids = guids; - - RecordUndoOnDatas(); - - createData(); - createPalette(); - setSize(); - getFolderDatas(); - getInitialState(); - - Undo.undoRedoPerformed -= EditorApplication.RepaintProjectWindow; - Undo.undoRedoPerformed += EditorApplication.RepaintProjectWindow; - - EditorApplication.update -= RepaintOnAlt; - EditorApplication.update += RepaintOnAlt; - - } - - void OnDestroy() - { - RemoveEmptyFolderDatas(); - MarkDatasDirty(); - SaveData(); - - EditorApplication.update -= RepaintOnAlt; - - } - - public List guids = new(); - public List folderDatas = new(); - - public List iconNamesOrGuids_initial = new(); - public List colorIndexes_initial = new(); - - public List isIconRecursives_initial = new(); - public List isColorRecursives_initial = new(); - - static VFoldersPalette palette => VFolders.palette; - static VFoldersData data => VFolders.data; - - - - - - - - public static void CreateInstance(Vector2 position) - { - instance = ScriptableObject.CreateInstance(); - - instance.ShowPopup(); - - instance.position = instance.position.SetPos(position).SetSize(200, 300); - instance.targetPosition = position; - - } - - public static VFoldersPaletteWindow instance; - - - - - - - public class FolderDataWrapper - { - public string iconNameOrGuid - { - get - { - if (folderData != null && folderData.iconNameOrGuid != "") - if (folderData.iconNameOrGuid == "none") return ""; - else return folderData.iconNameOrGuid ?? ""; - - else if (VFoldersMenu.autoIconsEnabled && folderState.autoIconName != "") - return folderState.autoIconName; - - else return ""; - - } - set - { - if (VFoldersMenu.autoIconsEnabled && folderState.autoIconName != "") - if (value == folderState.autoIconName && !folderData.isIconRecursive) - folderData.iconNameOrGuid = ""; - else if (value == "") - folderData.iconNameOrGuid = "none"; - else - folderData.iconNameOrGuid = value; - - - else folderData.iconNameOrGuid = value; - - } - - } - public bool isIconRecursive { get => folderData.isIconRecursive; set => folderData.isIconRecursive = value; } - - public int colorIndex { get => folderData.colorIndex; set => folderData.colorIndex = value; } - public bool isColorRecursive { get => folderData.isColorRecursive; set => folderData.isColorRecursive = value; } - - - public FolderDataWrapper(string guid) - { - folderData = VFolders.GetFolderData(guid, createDataIfDoesntExist: true); - folderState = VFolders.GetFolderState(guid); - } - - public FolderData folderData; - public FolderState folderState; - - - // used as an interlayer between folderData and palette window to account for automatic icons - // it's the only structural difference between vFolders' PaletteWindow and vHierarchy's - - } - - - } -} -#endif \ No newline at end of file diff --git a/Assets/Plugins/vFolders/VFoldersPaletteWindow.cs.meta b/Assets/Plugins/vFolders/VFoldersPaletteWindow.cs.meta deleted file mode 100644 index 6f8ecd4cb..000000000 --- a/Assets/Plugins/vFolders/VFoldersPaletteWindow.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 68011e63381a84f3bacee6e5ee9e0b82 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: