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