// MIT License - Copyright (c) 2025 wallstop // Full license text: https://github.com/wallstop/unity-helpers/blob/main/LICENSE namespace WallstopStudios.UnityHelpers.Editor.CustomDrawers { using System; using System.Collections.Generic; using UnityEngine; /// /// Shared solid-color button styling used by the serialized dictionary and set inspectors. /// Keeps the palette consistent between drawers (add/overwrite/remove/reset, etc). /// internal static class SolidButtonStyles { private static readonly Color ThemeRemoveColor = new(0.92f, 0.29f, 0.33f, 1f); private static readonly Color ThemeAddColor = new(0.25f, 0.68f, 0.38f, 1f); private static readonly Color ThemeOverwriteColor = new(0.98f, 0.82f, 0.27f, 1f); private static readonly Color ThemeResetColor = new(0.7f, 0.7f, 0.7f, 1f); private static readonly Color ThemeSortColor = new(0.24f, 0.52f, 0.88f, 1f); private static readonly Color ThemeDisabledColor = new(0.6f, 0.6f, 0.6f, 1f); private static readonly Dictionary< (string action, bool enabled), GUIStyle > ButtonStyleCache = new(); private static readonly Dictionary ColorTextureCache = new(); private static readonly RectOffset ZeroMargin = new(0, 0, 0, 0); private static readonly RectOffset StandardPadding = new(8, 8, 3, 3); internal static Color DisabledColor => ThemeDisabledColor; internal static GUIStyle GetSolidButtonStyle(string action, bool enabled) { if (string.IsNullOrEmpty(action)) { action = "Default"; } (string, bool) cacheKey = (action, enabled); if (ButtonStyleCache.TryGetValue(cacheKey, out GUIStyle cached)) { return cached; } GUIStyle baseStyle = new(GUI.skin.button) { alignment = TextAnchor.MiddleCenter, margin = ZeroMargin, padding = StandardPadding, }; Color baseColor = enabled ? GetActionColor(action) : ThemeDisabledColor; Color hoverColor = enabled ? AdjustValue(baseColor, 0.08f) : baseColor; Color pressedColor = enabled ? AdjustValue(baseColor, -0.08f) : baseColor; Color textColor = enabled ? GetLegibleTextColor(baseColor) : AdjustAlpha(GetLegibleTextColor(baseColor), 0.6f); Texture2D normalTexture = GetSolidTexture(baseColor); Texture2D hoverTexture = GetSolidTexture(hoverColor); Texture2D pressedTexture = GetSolidTexture(pressedColor); baseStyle.normal.background = normalTexture; baseStyle.hover.background = hoverTexture; baseStyle.active.background = pressedTexture; baseStyle.focused.background = normalTexture; baseStyle.onNormal.background = normalTexture; baseStyle.onHover.background = hoverTexture; baseStyle.onActive.background = pressedTexture; baseStyle.onFocused.background = normalTexture; baseStyle.normal.textColor = textColor; baseStyle.hover.textColor = textColor; baseStyle.active.textColor = textColor; baseStyle.focused.textColor = textColor; baseStyle.onNormal.textColor = textColor; baseStyle.onHover.textColor = textColor; baseStyle.onActive.textColor = textColor; baseStyle.onFocused.textColor = textColor; ButtonStyleCache[cacheKey] = baseStyle; return baseStyle; } private static Color GetActionColor(string action) { switch (action) { case "Add": return ThemeAddColor; case "Overwrite": case "AddEmpty": return ThemeOverwriteColor; case "Reset": return ThemeResetColor; case "Remove": case "ClearAll": return ThemeRemoveColor; case "Sort": return ThemeSortColor; default: return ThemeResetColor; } } private static Color AdjustValue(Color color, float delta) { Color.RGBToHSV(color, out float h, out float s, out float v); v = Mathf.Clamp01(v + delta); Color result = Color.HSVToRGB(h, s, v); result.a = color.a; return result; } private static Color AdjustAlpha(Color color, float multiplier) { color.a *= multiplier; return color; } private static Color GetLegibleTextColor(Color background) { float luminance = 0.299f * background.r + 0.587f * background.g + 0.114f * background.b; return luminance > 0.55f ? Color.black : Color.white; } private static Texture2D GetSolidTexture(Color color) { if (ColorTextureCache.TryGetValue(color, out Texture2D cached)) { return cached; } Texture2D texture = new(1, 1) { hideFlags = HideFlags.HideAndDontSave, filterMode = FilterMode.Point, }; texture.SetPixel(0, 0, color); texture.Apply(); ColorTextureCache[color] = texture; return texture; } } }