Rasagar/Library/PackageCache/com.unity.test-framework/UnityEditor.TestRunner/GUI/Controls/SelectionDropDown.cs
2024-08-26 23:07:20 +03:00

168 lines
6.1 KiB
C#

using System;
using UnityEngine;
namespace UnityEditor.TestTools.TestRunner.GUI.Controls
{
/// <summary>
/// A DropDown editor control accepting <see cref="ISelectionDropDownContentProvider" />-based content providers.
/// </summary>
internal class SelectionDropDown : PopupWindowContent
{
private static readonly int k_ControlId = typeof(SelectionDropDown).GetHashCode();
private readonly ISelectionDropDownContentProvider m_ContentProvider;
private readonly Vector2 m_ContentSize;
private Vector2 m_ScrollPosition = Vector2.zero;
/// <summary>
/// Creates a new instance of the <see cref="SelectionDropDown" /> editor control.
/// </summary>
/// <param name="contentProvider">The content provider to use.</param>
public SelectionDropDown(ISelectionDropDownContentProvider contentProvider)
{
m_ContentProvider = contentProvider;
var width = CalculateContentWidth();
var height = CalculateContentHeight();
m_ContentSize = new Vector2(width, height);
}
public override void OnOpen()
{
base.OnOpen();
editorWindow.wantsMouseMove = true;
editorWindow.wantsMouseEnterLeaveWindow = true;
}
public override void OnClose()
{
GUIUtility.hotControl = 0;
base.OnClose();
}
public override Vector2 GetWindowSize()
{
return m_ContentSize;
}
public override void OnGUI(Rect rect)
{
var evt = Event.current;
var contentRect = new Rect(Styles.TopMargin, 0, 1, m_ContentSize.y);
m_ScrollPosition = UnityEngine.GUI.BeginScrollView(rect, m_ScrollPosition, contentRect);
{
var yPos = Styles.TopMargin;
for (var i = 0; i < m_ContentProvider.Count; ++i)
{
var itemRect = new Rect(0, yPos, rect.width, Styles.LineHeight);
var separatorOffset = 0f;
switch (evt.type)
{
case EventType.Repaint:
var content = new GUIContent(m_ContentProvider.GetName(i));
var hover = itemRect.Contains(evt.mousePosition);
var on = m_ContentProvider.IsSelected(i);
Styles.MenuItem.Draw(itemRect, content, hover, false, on, false);
separatorOffset = DrawSeparator(i, itemRect);
break;
case EventType.MouseDown:
if (evt.button == 0 && itemRect.Contains(evt.mousePosition))
{
m_ContentProvider.SelectItem(i);
if (!m_ContentProvider.IsMultiSelection)
{
editorWindow.Close();
}
evt.Use();
}
break;
case EventType.MouseEnterWindow:
GUIUtility.hotControl = k_ControlId;
evt.Use();
break;
case EventType.MouseLeaveWindow:
GUIUtility.hotControl = 0;
evt.Use();
break;
case EventType.MouseUp:
case EventType.MouseMove:
evt.Use();
break;
}
yPos += Styles.LineHeight + separatorOffset;
}
}
UnityEngine.GUI.EndScrollView();
}
private float CalculateContentWidth()
{
var maxItemWidth = 0f;
for (var i = 0; i < m_ContentProvider.Count; ++i)
{
var itemContent = new GUIContent(m_ContentProvider.GetName(i));
var itemWidth = Styles.MenuItem.CalcSize(itemContent).x;
maxItemWidth = Mathf.Max(itemWidth, maxItemWidth);
}
return maxItemWidth;
}
private float CalculateContentHeight()
{
return m_ContentProvider.Count * Styles.LineHeight
+ m_ContentProvider.SeparatorIndices.Length * Styles.SeparatorHeight
+ Styles.TopMargin + Styles.BottomMargin;
}
private float DrawSeparator(int i, Rect itemRect)
{
if (Array.IndexOf(m_ContentProvider.SeparatorIndices, i) < 0)
{
return 0f;
}
var separatorRect = GetSeparatorRect(itemRect);
DrawRect(separatorRect, Styles.SeparatorColor);
return Styles.SeparatorHeight;
}
private static Rect GetSeparatorRect(Rect itemRect)
{
var x = itemRect.x + Styles.SeparatorMargin;
var y = itemRect.y + itemRect.height + Styles.SeparatorHeight * 0.15f;
var width = itemRect.width - 2 * Styles.SeparatorMargin;
const float height = 1f;
return new Rect(x, y, width, height);
}
private static void DrawRect(Rect rect, Color color)
{
var originalColor = UnityEngine.GUI.color;
UnityEngine.GUI.color *= color;
UnityEngine.GUI.DrawTexture(rect, EditorGUIUtility.whiteTexture);
UnityEngine.GUI.color = originalColor;
}
private static class Styles
{
public const float LineHeight = EditorGUI.kSingleLineHeight;
public const float TopMargin = 3f;
public const float BottomMargin = 1f;
public const float SeparatorHeight = 4f;
public const float SeparatorMargin = 3f;
public static readonly GUIStyle MenuItem = "MenuItem";
public static readonly Color SeparatorColor = EditorGUIUtility.isProSkin
? new Color(0.32f, 0.32f, 0.32f, 1.333f)
: new Color(0.6f, 0.6f, 0.6f, 1.333f);
}
}
}