暂无描述
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

SpriteSelector.cs 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. using System;
  2. using UnityEngine;
  3. namespace UnityEditor.U2D
  4. {
  5. internal class SpriteSelector
  6. {
  7. int m_SelectedSprite = 0;
  8. Sprite[] m_SpriteList = null;
  9. Texture[] m_Thumbnails;
  10. Vector2 m_ScrollPos;
  11. public int selectedIndex
  12. {
  13. get { return m_SelectedSprite; }
  14. set { m_SelectedSprite = value; }
  15. }
  16. internal static class Styles
  17. {
  18. public static GUIStyle gridList = "GridList";
  19. public static GUIContent spriteList = EditorGUIUtility.TrTextContent("Sprite Variant");
  20. public static GUIContent missingSprites = EditorGUIUtility.TrTextContent("No brushes defined.");
  21. public static GUIStyle localGrid = null;
  22. }
  23. public SpriteSelector()
  24. {
  25. m_SpriteList = null;
  26. }
  27. public void UpdateSprites(Sprite[] sprites)
  28. {
  29. m_SpriteList = sprites;
  30. UpdateSelection(0);
  31. }
  32. public void UpdateSelection(int newSelectedBrush)
  33. {
  34. m_SelectedSprite = newSelectedBrush;
  35. }
  36. private static int CalcTotalHorizSpacing(int xCount, GUIStyle style, GUIStyle firstStyle, GUIStyle midStyle, GUIStyle lastStyle)
  37. {
  38. if (xCount < 2)
  39. return 0;
  40. if (xCount == 2)
  41. return Mathf.Max(firstStyle.margin.right, lastStyle.margin.left);
  42. int internalSpace = Mathf.Max(midStyle.margin.left, midStyle.margin.right);
  43. return Mathf.Max(firstStyle.margin.right, midStyle.margin.left) + Mathf.Max(midStyle.margin.right, lastStyle.margin.left) + internalSpace * (xCount - 3);
  44. }
  45. // Helper function: Get all mouse rects
  46. private static Rect[] CalcMouseRects(Rect position, GUIContent[] contents, int xCount, float elemWidth, float elemHeight, GUIStyle style, GUIStyle firstStyle, GUIStyle midStyle, GUIStyle lastStyle, bool addBorders, GUI.ToolbarButtonSize buttonSize)
  47. {
  48. int count = contents.Length;
  49. int x = 0;
  50. float xPos = position.xMin, yPos = position.yMin;
  51. GUIStyle currentStyle = style;
  52. Rect[] retval = new Rect[count];
  53. if (count > 1)
  54. currentStyle = firstStyle;
  55. for (int i = 0; i < count; i++)
  56. {
  57. float w = 0;
  58. switch (buttonSize)
  59. {
  60. case GUI.ToolbarButtonSize.Fixed:
  61. w = elemWidth;
  62. break;
  63. case GUI.ToolbarButtonSize.FitToContents:
  64. w = currentStyle.CalcSize(contents[i]).x;
  65. break;
  66. }
  67. if (!addBorders)
  68. retval[i] = new Rect(xPos, yPos, w, elemHeight);
  69. else
  70. retval[i] = currentStyle.margin.Add(new Rect(xPos, yPos, w, elemHeight));
  71. //we round the values to the dpi-aware pixel grid
  72. retval[i] = GUIUtility.AlignRectToDevice(retval[i]);
  73. GUIStyle nextStyle = midStyle;
  74. if (i == count - 2 || i == xCount - 2)
  75. nextStyle = lastStyle;
  76. xPos = retval[i].xMax + Mathf.Max(currentStyle.margin.right, nextStyle.margin.left);
  77. x++;
  78. if (x >= xCount)
  79. {
  80. x = 0;
  81. yPos += elemHeight + Mathf.Max(style.margin.top, style.margin.bottom);
  82. xPos = position.xMin;
  83. nextStyle = firstStyle;
  84. }
  85. currentStyle = nextStyle;
  86. }
  87. return retval;
  88. }
  89. static void DrawRectangleOutline(Rect rect, Color color)
  90. {
  91. Color currentColor = Handles.color;
  92. Handles.color = color;
  93. // Draw viewport outline
  94. Vector3[] points = new Vector3[5];
  95. points[0] = new Vector3(rect.x, rect.y, 0.0f);
  96. points[1] = new Vector3(rect.x + rect.width, rect.y, 0.0f);
  97. points[2] = new Vector3(rect.x + rect.width, rect.y + rect.height, 0.0f);
  98. points[3] = new Vector3(rect.x, rect.y + rect.height, 0.0f);
  99. points[4] = new Vector3(rect.x, rect.y, 0.0f);
  100. Handles.DrawPolyLine(points);
  101. Handles.color = currentColor;
  102. }
  103. // Make a button grid
  104. private static int DoButtonGrid(Rect position, int selected, GUIContent[] contents, string[] controlNames, int xCount, GUIStyle style, GUIStyle firstStyle, GUIStyle midStyle, GUIStyle lastStyle, GUI.ToolbarButtonSize buttonSize, bool[] contentsEnabled = null)
  105. {
  106. int count = contents.Length;
  107. if (count == 0)
  108. return selected;
  109. if (xCount <= 0)
  110. {
  111. Debug.LogWarning("You are trying to create a SelectionGrid with zero or less elements to be displayed in the horizontal direction. Set xCount to a positive value.");
  112. return selected;
  113. }
  114. if (contentsEnabled != null && contentsEnabled.Length != count)
  115. throw new ArgumentException("contentsEnabled");
  116. // Figure out how large each element should be
  117. int rows = count / xCount;
  118. if (count % xCount != 0)
  119. rows++;
  120. float totalHorizSpacing = CalcTotalHorizSpacing(xCount, style, firstStyle, midStyle, lastStyle);
  121. float totalVerticalSpacing = Mathf.Max(style.margin.top, style.margin.bottom) * (rows - 1);
  122. float elemWidth = (position.width - totalHorizSpacing) / xCount;
  123. float elemHeight = (position.height - totalVerticalSpacing) / rows;
  124. if (style.fixedWidth != 0)
  125. elemWidth = style.fixedWidth;
  126. if (style.fixedHeight != 0)
  127. elemHeight = style.fixedHeight;
  128. Rect[] buttonRects = CalcMouseRects(position, contents, xCount, elemWidth, elemHeight, style, firstStyle, midStyle, lastStyle, false, buttonSize);
  129. GUIStyle selectedButtonStyle = null;
  130. int selectedButtonID = 0;
  131. for (int buttonIndex = 0; buttonIndex < count; ++buttonIndex)
  132. {
  133. bool wasEnabled = GUI.enabled;
  134. GUI.enabled &= (contentsEnabled == null || contentsEnabled[buttonIndex]);
  135. var buttonRect = buttonRects[buttonIndex];
  136. var content = contents[buttonIndex];
  137. if (controlNames != null)
  138. GUI.SetNextControlName(controlNames[buttonIndex]);
  139. var id = GUIUtility.GetControlID("ButtonGrid".GetHashCode(), FocusType.Passive, buttonRect);
  140. if (buttonIndex == selected)
  141. selectedButtonID = id;
  142. switch (Event.current.GetTypeForControl(id))
  143. {
  144. case EventType.MouseDown:
  145. if (buttonRect.Contains(Event.current.mousePosition))
  146. {
  147. GUIUtility.hotControl = id;
  148. Event.current.Use();
  149. }
  150. break;
  151. case EventType.MouseDrag:
  152. if (GUIUtility.hotControl == id)
  153. Event.current.Use();
  154. break;
  155. case EventType.MouseUp:
  156. if (GUIUtility.hotControl == id)
  157. {
  158. GUIUtility.hotControl = 0;
  159. Event.current.Use();
  160. GUI.changed = true;
  161. return buttonIndex;
  162. }
  163. break;
  164. case EventType.Repaint:
  165. var buttonStyle = count == 1 ? style : (buttonIndex == 0 ? firstStyle : (buttonIndex == count - 1 ? lastStyle : midStyle));
  166. var isSelected = selected == buttonIndex;
  167. if (!isSelected)
  168. {
  169. GUI.DrawTexture(buttonRect, content.image, ScaleMode.ScaleToFit, true);
  170. GUI.Label(new Rect(buttonRect.x, buttonRect.y, 32, 32), buttonIndex.ToString());
  171. }
  172. else
  173. selectedButtonStyle = buttonStyle;
  174. break;
  175. }
  176. GUI.enabled = wasEnabled;
  177. }
  178. // draw selected button at the end so it overflows nicer
  179. if (selectedButtonStyle != null)
  180. {
  181. var buttonRect = buttonRects[selected];
  182. var content = contents[selected];
  183. var wasEnabled = GUI.enabled;
  184. GUI.enabled &= (contentsEnabled == null || contentsEnabled[selected]);
  185. GUI.DrawTexture(new Rect(buttonRect.x + 4, buttonRect.y + 4, buttonRect.width - 8, buttonRect.height - 8), content.image, ScaleMode.ScaleToFit, true);
  186. DrawRectangleOutline(buttonRect, GUI.skin.settings.selectionColor);
  187. GUI.Label(new Rect(buttonRect.x, buttonRect.y, 32, 32), selected.ToString());
  188. GUI.enabled = wasEnabled;
  189. }
  190. return selected;
  191. }
  192. // Get Temp Texture Contents for Sprites.
  193. private static GUIContent[] Temp(Texture[] images)
  194. {
  195. GUIContent[] retval = new GUIContent[images.Length];
  196. for (int i = 0; i < images.Length; i++)
  197. {
  198. retval[i] = new GUIContent(images[i]);
  199. }
  200. return retval;
  201. }
  202. public Sprite GetActiveSprite()
  203. {
  204. if (m_SelectedSprite >= m_SpriteList.Length)
  205. m_SelectedSprite = 0;
  206. return m_SpriteList[m_SelectedSprite];
  207. }
  208. public bool ShowGUI(int selectedIndex)
  209. {
  210. bool repaint = false;
  211. if (m_SpriteList == null || m_SpriteList.Length == 0)
  212. return false;
  213. int approxSize = 64;
  214. int approxHolderSize = 66;
  215. if (Styles.localGrid == null)
  216. {
  217. Styles.localGrid = new GUIStyle(Styles.gridList);
  218. Styles.localGrid.fixedWidth = approxSize;
  219. Styles.localGrid.fixedHeight = approxSize;
  220. }
  221. m_SelectedSprite = (selectedIndex > m_SpriteList.Length) ? 0 : selectedIndex;
  222. EditorGUILayout.BeginHorizontal();
  223. {
  224. GUILayout.Label(Styles.spriteList, EditorStyles.label, GUILayout.Width(EditorGUIUtility.labelWidth - 5));
  225. int cviewwidth = (int)(EditorGUIUtility.currentViewWidth - EditorGUIUtility.labelWidth - approxSize);
  226. int columns = (int)(cviewwidth) / approxSize;
  227. columns = columns == 0 ? 1 : columns;
  228. int rows = (int)Mathf.Ceil((m_SpriteList.Length + columns - 1) / columns);
  229. int lyColumns = (rows == 1) ? (approxHolderSize): (approxHolderSize * 2);
  230. GUILayout.BeginVertical("box", new GUILayoutOption[] { GUILayout.Height(lyColumns) } );
  231. {
  232. m_ScrollPos = EditorGUILayout.BeginScrollView(m_ScrollPos, new GUILayoutOption[] { GUILayout.Height(lyColumns) });
  233. int newBrush = SpriteSelectionGrid(m_SelectedSprite, m_SpriteList, approxSize, Styles.localGrid, Styles.missingSprites, columns, rows);
  234. if (newBrush != m_SelectedSprite)
  235. {
  236. UpdateSelection(newBrush);
  237. repaint = true;
  238. }
  239. EditorGUILayout.EndScrollView();
  240. }
  241. GUILayout.EndVertical();
  242. }
  243. EditorGUILayout.EndHorizontal();
  244. EditorGUILayout.Space();
  245. return repaint;
  246. }
  247. int SpriteSelectionGrid(int selected, Sprite[] sprites, int approxSize, GUIStyle style, GUIContent emptyString, int columns, int rows)
  248. {
  249. int retval = 0;
  250. if (sprites.Length != 0)
  251. {
  252. Rect r = GUILayoutUtility.GetRect((float)columns * approxSize, (float)rows * approxSize);
  253. Event evt = Event.current;
  254. if (evt.type == EventType.MouseDown && evt.clickCount == 2 && r.Contains(evt.mousePosition))
  255. evt.Use();
  256. m_Thumbnails = PreviewTexturesFromSprites(sprites);
  257. retval = DoButtonGrid(r, selected, Temp(m_Thumbnails), null, (int)columns, style, style, style, style, GUI.ToolbarButtonSize.FitToContents);
  258. }
  259. else
  260. GUILayout.Label(emptyString);
  261. return retval;
  262. }
  263. internal static Texture[] PreviewTexturesFromSprites(Sprite[] sprites)
  264. {
  265. Texture[] retval = new Texture[sprites.Length];
  266. for (int i = 0; i < sprites.Length; i++)
  267. retval[i] = AssetPreview.GetAssetPreview(sprites[i]) ?? Texture2D.whiteTexture;
  268. return retval;
  269. }
  270. }
  271. } //namespace