暫無描述
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

SelectionDropDown.cs 6.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. using System;
  2. using UnityEngine;
  3. namespace UnityEditor.TestTools.TestRunner.GUI.Controls
  4. {
  5. /// <summary>
  6. /// A DropDown editor control accepting <see cref="ISelectionDropDownContentProvider" />-based content providers.
  7. /// </summary>
  8. internal class SelectionDropDown : PopupWindowContent
  9. {
  10. private static readonly int k_ControlId = typeof(SelectionDropDown).GetHashCode();
  11. private readonly ISelectionDropDownContentProvider m_ContentProvider;
  12. private readonly Vector2 m_ContentSize;
  13. private Vector2 m_ScrollPosition = Vector2.zero;
  14. /// <summary>
  15. /// Creates a new instance of the <see cref="SelectionDropDown" /> editor control.
  16. /// </summary>
  17. /// <param name="contentProvider">The content provider to use.</param>
  18. public SelectionDropDown(ISelectionDropDownContentProvider contentProvider)
  19. {
  20. m_ContentProvider = contentProvider;
  21. var width = CalculateContentWidth();
  22. var height = CalculateContentHeight();
  23. m_ContentSize = new Vector2(width, height);
  24. }
  25. public override void OnOpen()
  26. {
  27. base.OnOpen();
  28. editorWindow.wantsMouseMove = true;
  29. editorWindow.wantsMouseEnterLeaveWindow = true;
  30. }
  31. public override void OnClose()
  32. {
  33. GUIUtility.hotControl = 0;
  34. base.OnClose();
  35. }
  36. public override Vector2 GetWindowSize()
  37. {
  38. return m_ContentSize;
  39. }
  40. public override void OnGUI(Rect rect)
  41. {
  42. var evt = Event.current;
  43. var contentRect = new Rect(Styles.TopMargin, 0, 1, m_ContentSize.y);
  44. m_ScrollPosition = UnityEngine.GUI.BeginScrollView(rect, m_ScrollPosition, contentRect);
  45. {
  46. var yPos = Styles.TopMargin;
  47. for (var i = 0; i < m_ContentProvider.Count; ++i)
  48. {
  49. var itemRect = new Rect(0, yPos, rect.width, Styles.LineHeight);
  50. var separatorOffset = 0f;
  51. switch (evt.type)
  52. {
  53. case EventType.Repaint:
  54. var content = new GUIContent(m_ContentProvider.GetName(i));
  55. var hover = itemRect.Contains(evt.mousePosition);
  56. var on = m_ContentProvider.IsSelected(i);
  57. Styles.MenuItem.Draw(itemRect, content, hover, false, on, false);
  58. separatorOffset = DrawSeparator(i, itemRect);
  59. break;
  60. case EventType.MouseDown:
  61. if (evt.button == 0 && itemRect.Contains(evt.mousePosition))
  62. {
  63. m_ContentProvider.SelectItem(i);
  64. if (!m_ContentProvider.IsMultiSelection)
  65. {
  66. editorWindow.Close();
  67. }
  68. evt.Use();
  69. }
  70. break;
  71. case EventType.MouseEnterWindow:
  72. GUIUtility.hotControl = k_ControlId;
  73. evt.Use();
  74. break;
  75. case EventType.MouseLeaveWindow:
  76. GUIUtility.hotControl = 0;
  77. evt.Use();
  78. break;
  79. case EventType.MouseUp:
  80. case EventType.MouseMove:
  81. evt.Use();
  82. break;
  83. }
  84. yPos += Styles.LineHeight + separatorOffset;
  85. }
  86. }
  87. UnityEngine.GUI.EndScrollView();
  88. }
  89. private float CalculateContentWidth()
  90. {
  91. var maxItemWidth = 0f;
  92. for (var i = 0; i < m_ContentProvider.Count; ++i)
  93. {
  94. var itemContent = new GUIContent(m_ContentProvider.GetName(i));
  95. var itemWidth = Styles.MenuItem.CalcSize(itemContent).x;
  96. maxItemWidth = Mathf.Max(itemWidth, maxItemWidth);
  97. }
  98. return maxItemWidth;
  99. }
  100. private float CalculateContentHeight()
  101. {
  102. return m_ContentProvider.Count * Styles.LineHeight
  103. + m_ContentProvider.SeparatorIndices.Length * Styles.SeparatorHeight
  104. + Styles.TopMargin + Styles.BottomMargin;
  105. }
  106. private float DrawSeparator(int i, Rect itemRect)
  107. {
  108. if (Array.IndexOf(m_ContentProvider.SeparatorIndices, i) < 0)
  109. {
  110. return 0f;
  111. }
  112. var separatorRect = GetSeparatorRect(itemRect);
  113. DrawRect(separatorRect, Styles.SeparatorColor);
  114. return Styles.SeparatorHeight;
  115. }
  116. private static Rect GetSeparatorRect(Rect itemRect)
  117. {
  118. var x = itemRect.x + Styles.SeparatorMargin;
  119. var y = itemRect.y + itemRect.height + Styles.SeparatorHeight * 0.15f;
  120. var width = itemRect.width - 2 * Styles.SeparatorMargin;
  121. const float height = 1f;
  122. return new Rect(x, y, width, height);
  123. }
  124. private static void DrawRect(Rect rect, Color color)
  125. {
  126. var originalColor = UnityEngine.GUI.color;
  127. UnityEngine.GUI.color *= color;
  128. UnityEngine.GUI.DrawTexture(rect, EditorGUIUtility.whiteTexture);
  129. UnityEngine.GUI.color = originalColor;
  130. }
  131. private static class Styles
  132. {
  133. public const float LineHeight = EditorGUI.kSingleLineHeight;
  134. public const float TopMargin = 3f;
  135. public const float BottomMargin = 1f;
  136. public const float SeparatorHeight = 4f;
  137. public const float SeparatorMargin = 3f;
  138. public static readonly GUIStyle MenuItem = "MenuItem";
  139. public static readonly Color SeparatorColor = EditorGUIUtility.isProSkin
  140. ? new Color(0.32f, 0.32f, 0.32f, 1.333f)
  141. : new Color(0.6f, 0.6f, 0.6f, 1.333f);
  142. }
  143. }
  144. }