GUIHelper.cs 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. using UnityEngine;
  2. using System.Collections.Generic;
  3. namespace SingularityGroup.HotReload.Editor {
  4. internal enum InvertibleIcon {
  5. BugReport,
  6. Events,
  7. EventsNew,
  8. Recompile,
  9. Logo,
  10. Close,
  11. FoldoutOpen,
  12. FoldoutClosed,
  13. Spinner,
  14. Stop,
  15. Start,
  16. }
  17. internal static class GUIHelper {
  18. private static readonly Dictionary<InvertibleIcon, string> supportedInvertibleIcons = new Dictionary<InvertibleIcon, string> {
  19. { InvertibleIcon.BugReport, "report_bug" },
  20. { InvertibleIcon.Events, "events" },
  21. { InvertibleIcon.Recompile, "refresh" },
  22. { InvertibleIcon.Logo, "logo" },
  23. { InvertibleIcon.Close, "close" },
  24. { InvertibleIcon.FoldoutOpen, "foldout_open" },
  25. { InvertibleIcon.FoldoutClosed, "foldout_closed" },
  26. { InvertibleIcon.Spinner, "icon_loading_star_light_mode_96" },
  27. { InvertibleIcon.Stop, "Icn_Stop" },
  28. { InvertibleIcon.Start, "Icn_play" },
  29. };
  30. private static readonly Dictionary<InvertibleIcon, Texture2D> invertibleIconCache = new Dictionary<InvertibleIcon, Texture2D>();
  31. private static readonly Dictionary<InvertibleIcon, Texture2D> invertibleIconInvertedCache = new Dictionary<InvertibleIcon, Texture2D>();
  32. private static readonly Dictionary<string, Texture2D> iconCache = new Dictionary<string, Texture2D>();
  33. internal static Texture2D InvertTextureColor(Texture2D originalTexture) {
  34. if (!originalTexture) {
  35. return originalTexture;
  36. }
  37. // Get the original pixels from the texture
  38. Color[] originalPixels = originalTexture.GetPixels();
  39. // Create a new array for the inverted colors
  40. Color[] invertedPixels = new Color[originalPixels.Length];
  41. // Iterate through the pixels and invert the colors while preserving the alpha channel
  42. for (int i = 0; i < originalPixels.Length; i++) {
  43. Color originalColor = originalPixels[i];
  44. Color invertedColor = new Color(1 - originalColor.r, 1 - originalColor.g, 1 - originalColor.b, originalColor.a);
  45. invertedPixels[i] = invertedColor;
  46. }
  47. // Create a new texture and set its pixels
  48. Texture2D invertedTexture = new Texture2D(originalTexture.width, originalTexture.height);
  49. invertedTexture.SetPixels(invertedPixels);
  50. // Apply the changes to the texture
  51. invertedTexture.Apply();
  52. return invertedTexture;
  53. }
  54. internal static Texture2D GetInvertibleIcon(InvertibleIcon invertibleIcon) {
  55. Texture2D iconTexture;
  56. var cache = HotReloadWindowStyles.IsDarkMode ? invertibleIconInvertedCache : invertibleIconCache;
  57. if (!cache.TryGetValue(invertibleIcon, out iconTexture) || !iconTexture) {
  58. var type = invertibleIcon == InvertibleIcon.EventsNew ? InvertibleIcon.Events : invertibleIcon;
  59. iconTexture = Resources.Load<Texture2D>(supportedInvertibleIcons[type]);
  60. // we assume icons are for light mode by default
  61. // therefore if its dark mode we should invert them
  62. if (HotReloadWindowStyles.IsDarkMode) {
  63. iconTexture = InvertTextureColor(iconTexture);
  64. }
  65. cache[type] = iconTexture;
  66. // we combine dot image with Events icon to create a new alert version
  67. if (invertibleIcon == InvertibleIcon.EventsNew) {
  68. var redDot = Resources.Load<Texture2D>("red_dot");
  69. iconTexture = CombineImages(iconTexture, redDot);
  70. cache[InvertibleIcon.EventsNew] = iconTexture;
  71. }
  72. }
  73. return cache[invertibleIcon];
  74. }
  75. internal static Texture2D GetLocalIcon(string iconName) {
  76. Texture2D iconTexture;
  77. if (!iconCache.TryGetValue(iconName, out iconTexture) || !iconTexture) {
  78. iconTexture = Resources.Load<Texture2D>(iconName);
  79. iconCache[iconName] = iconTexture;
  80. }
  81. return iconTexture;
  82. }
  83. static Texture2D CombineImages(Texture2D image1, Texture2D image2) {
  84. if (!image1 || !image2) {
  85. return image1;
  86. }
  87. var combinedImage = new Texture2D(Mathf.Max(image1.width, image2.width), Mathf.Max(image1.height, image2.height));
  88. for (int y = 0; y < combinedImage.height; y++) {
  89. for (int x = 0; x < combinedImage.width; x++) {
  90. Color color1 = x < image1.width && y < image1.height ? image1.GetPixel(x, y) : Color.clear;
  91. Color color2 = x < image2.width && y < image2.height ? image2.GetPixel(x, y) : Color.clear;
  92. combinedImage.SetPixel(x, y, Color.Lerp(color1, color2, color2.a));
  93. }
  94. }
  95. combinedImage.Apply();
  96. return combinedImage;
  97. }
  98. private static readonly Dictionary<Color, Texture2D> textureColorCache = new Dictionary<Color, Texture2D>();
  99. internal static Texture2D ConvertTextureToColor(Color color) {
  100. Texture2D texture;
  101. if (!textureColorCache.TryGetValue(color, out texture) || !texture) {
  102. texture = new Texture2D(1, 1);
  103. texture.SetPixel(0, 0, color);
  104. texture.Apply();
  105. textureColorCache[color] = texture;
  106. }
  107. return texture;
  108. }
  109. private static readonly Dictionary<string, Texture2D> grayTextureCache = new Dictionary<string, Texture2D>();
  110. private static readonly Dictionary<string, Color> colorFactor = new Dictionary<string, Color> {
  111. { "error", new Color(0.6f, 0.587f, 0.114f) },
  112. };
  113. internal static Texture2D ConvertToGrayscale(string localIcon) {
  114. Texture2D _texture;
  115. if (!grayTextureCache.TryGetValue(localIcon, out _texture) || !_texture) {
  116. var icon = GUIHelper.GetLocalIcon(localIcon);
  117. // Create a copy of the texture
  118. Texture2D copiedTexture = new Texture2D(icon.width, icon.height, TextureFormat.RGBA32, false);
  119. // Convert the copied texture to grayscale
  120. Color[] pixels = icon.GetPixels();
  121. for (int i = 0; i < pixels.Length; i++) {
  122. Color pixel = pixels[i];
  123. Color factor;
  124. if (!colorFactor.TryGetValue(localIcon, out factor)) {
  125. factor = new Color(0.299f, 0.587f, 0.114f);
  126. }
  127. float grayscale = factor.r * pixel.r + factor.g * pixel.g + factor.b * pixel.b;
  128. pixels[i] = new Color(grayscale, grayscale, grayscale, pixel.a); // Preserve alpha channel
  129. }
  130. copiedTexture.SetPixels(pixels);
  131. copiedTexture.Apply();
  132. // Store the grayscale texture in the cache
  133. grayTextureCache[localIcon] = copiedTexture;
  134. return copiedTexture;
  135. }
  136. return _texture;
  137. }
  138. }
  139. }