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}