test
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
|
||||
namespace UnityEditor.TestTools.TestRunner.GUI.Controls
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides methods for dealing with common bit operations.
|
||||
/// </summary>
|
||||
internal static class BitUtility
|
||||
{
|
||||
/// <summary>
|
||||
/// Evaluates the cardinality of an integer, treating the value as a bit set.
|
||||
/// Optimization based on http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel.
|
||||
/// </summary>
|
||||
/// <param name="integer">The input integer value.</param>
|
||||
/// <returns>The number of bits set in the provided input integer value.</returns>
|
||||
internal static int GetCardinality(int integer)
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
integer = integer - ((integer >> 1) & 0x55555555);
|
||||
integer = (integer & 0x33333333) + ((integer >> 2) & 0x33333333);
|
||||
integer = (((integer + (integer >> 4)) & 0xF0F0F0F) * 0x1010101) >> 24;
|
||||
}
|
||||
|
||||
return integer;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 24a5f331fec74c9aa9e1e5d74b5a9589
|
||||
timeCreated: 1601747849
|
@@ -0,0 +1,118 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.TestTools.TestRunner.GUI.Controls
|
||||
{
|
||||
/// <summary>
|
||||
/// A flag enum content provider to be used with the <see cref="SelectionDropDown" /> control.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The flag enum type.</typeparam>
|
||||
internal class FlagEnumContentProvider<T> : ISelectionDropDownContentProvider where T : Enum
|
||||
{
|
||||
private readonly Action<T> m_ValueChangedCallback;
|
||||
private readonly T[] m_Values;
|
||||
internal Func<string, string> DisplayNameGenerator = ObjectNames.NicifyVariableName;
|
||||
private T m_CurrentValue;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="FlagEnumContentProvider{T}" /> class.
|
||||
/// </summary>
|
||||
/// <param name="initialValue">The initial selection value.</param>
|
||||
/// <param name="valueChangedCallback">The callback to be invoked on selection change.</param>
|
||||
/// <exception cref="ArgumentException">
|
||||
/// Thrown if the generic enum parameter type is not integer based
|
||||
/// or if the initial selection value is empty.
|
||||
/// </exception>
|
||||
/// <exception cref="ArgumentNullException">Thrown if the provided change callback is null.</exception>
|
||||
public FlagEnumContentProvider(T initialValue, Action<T> valueChangedCallback)
|
||||
{
|
||||
if (Enum.GetUnderlyingType(typeof(T)) != typeof(int))
|
||||
{
|
||||
throw new ArgumentException("Argument underlying type must be integer.");
|
||||
}
|
||||
|
||||
if ((int)(object)initialValue == 0)
|
||||
{
|
||||
throw new ArgumentException("The initial value must not be an empty set.", nameof(initialValue));
|
||||
}
|
||||
|
||||
if (valueChangedCallback == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(valueChangedCallback), "The value change callback must not be null.");
|
||||
}
|
||||
|
||||
m_CurrentValue = initialValue;
|
||||
m_Values = (T[])Enum.GetValues(typeof(T));
|
||||
m_ValueChangedCallback = valueChangedCallback;
|
||||
}
|
||||
|
||||
public int Count => m_Values.Length;
|
||||
public bool IsMultiSelection => true;
|
||||
|
||||
public string GetName(int index)
|
||||
{
|
||||
return ValidateIndexBounds(index) ? DisplayNameGenerator(m_Values[index].ToString()) : string.Empty;
|
||||
}
|
||||
|
||||
public int[] SeparatorIndices => new int[0];
|
||||
|
||||
public bool IsSelected(int index)
|
||||
{
|
||||
return ValidateIndexBounds(index) && IsSet(m_Values[index]);
|
||||
}
|
||||
|
||||
public void SelectItem(int index)
|
||||
{
|
||||
if (!ValidateIndexBounds(index))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ChangeValue(m_Values[index]))
|
||||
{
|
||||
m_ValueChangedCallback(m_CurrentValue);
|
||||
}
|
||||
}
|
||||
|
||||
private bool ChangeValue(T flag)
|
||||
{
|
||||
var value = flag;
|
||||
var count = GetSetCount();
|
||||
|
||||
if (IsSet(value))
|
||||
{
|
||||
if (count == 1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
m_CurrentValue = FlagEnumUtility.RemoveFlag(m_CurrentValue, flag);
|
||||
return true;
|
||||
}
|
||||
|
||||
m_CurrentValue = FlagEnumUtility.SetFlag(m_CurrentValue, flag);
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool IsSet(T flag)
|
||||
{
|
||||
return FlagEnumUtility.HasFlag(m_CurrentValue, flag);
|
||||
}
|
||||
|
||||
private int GetSetCount()
|
||||
{
|
||||
return BitUtility.GetCardinality((int)(object)m_CurrentValue);
|
||||
}
|
||||
|
||||
private bool ValidateIndexBounds(int index)
|
||||
{
|
||||
if (index < 0 || index >= Count)
|
||||
{
|
||||
Debug.LogError($"Requesting item index {index} from a collection of size {Count}");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d31403ec6b334194bdeb4c5ebad64097
|
||||
timeCreated: 1600072403
|
@@ -0,0 +1,74 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.TestTools.TestRunner.GUI.Controls
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides methods for dealing with common enumerator operations.
|
||||
/// </summary>
|
||||
internal static class FlagEnumUtility
|
||||
{
|
||||
/// <summary>
|
||||
/// Checks for the presence of a flag in a flag enum value.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to check for the presence of the flag.</param>
|
||||
/// <param name="flag">The flag whose presence is to be checked.</param>
|
||||
/// <typeparam name="T">The flag enum type.</typeparam>
|
||||
/// <returns></returns>
|
||||
internal static bool HasFlag<T>(T value, T flag) where T : Enum
|
||||
{
|
||||
ValidateUnderlyingType<T>();
|
||||
|
||||
var intValue = (int)(object)value;
|
||||
var intFlag = (int)(object)flag;
|
||||
return (intValue & intFlag) == intFlag;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets a flag in a flag enum value.
|
||||
/// </summary>
|
||||
/// <param name="value">The value where the flag should be set.</param>
|
||||
/// <param name="flag">The flag to be set.</param>
|
||||
/// <typeparam name="T">The flag enum type.</typeparam>
|
||||
/// <returns>The input value with the flag set.</returns>
|
||||
internal static T SetFlag<T>(T value, T flag) where T : Enum
|
||||
{
|
||||
ValidateUnderlyingType<T>();
|
||||
|
||||
var intValue = (int)(object)value;
|
||||
var intFlag = (int)(object)flag;
|
||||
var result = intValue | intFlag;
|
||||
return (T)Enum.ToObject(typeof(T), result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes a flag in a flag enum value.
|
||||
/// </summary>
|
||||
/// <param name="value">The value where the flag should be removed.</param>
|
||||
/// <param name="flag">The flag to be removed.</param>
|
||||
/// <typeparam name="T">The flag enum type.</typeparam>
|
||||
/// <returns>The input value with the flag removed.</returns>
|
||||
internal static T RemoveFlag<T>(T value, T flag) where T : Enum
|
||||
{
|
||||
ValidateUnderlyingType<T>();
|
||||
|
||||
var intValue = (int)(object)value;
|
||||
var intFlag = (int)(object)flag;
|
||||
var result = intValue & ~intFlag;
|
||||
return (T)Enum.ToObject(typeof(T), result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validates that the underlying type of an enum is integer.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The enum type.</typeparam>
|
||||
/// <exception cref="ArgumentException">Thrown if the underlying type of the enum type parameter is not integer.</exception>
|
||||
private static void ValidateUnderlyingType<T>() where T : Enum
|
||||
{
|
||||
if (Enum.GetUnderlyingType(typeof(T)) != typeof(int))
|
||||
{
|
||||
throw new ArgumentException("Argument underlying type must be integer.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ea6cc55375344f10834cf6fa65197525
|
||||
timeCreated: 1600072466
|
@@ -0,0 +1,101 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.TestTools.TestRunner.GUI.Controls
|
||||
{
|
||||
/// <summary>
|
||||
/// A generic type content provider to be used with the <see cref="SelectionDropDown" /> control.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of values represented by content elements.</typeparam>
|
||||
internal class GenericItemContentProvider<T> : ISelectionDropDownContentProvider where T : IEquatable<T>
|
||||
{
|
||||
private readonly ISelectableItem<T>[] m_Items;
|
||||
private readonly Action<T> m_ValueChangedCallback;
|
||||
private T m_CurrentValue;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="GenericItemContentProvider{T}" /> class.
|
||||
/// </summary>
|
||||
/// <param name="initialValue">The initial selection value.</param>
|
||||
/// <param name="items">The set of selectable items.</param>
|
||||
/// <param name="separatorIndices">The indices of items which should be followed by separator lines.</param>
|
||||
/// <param name="valueChangedCallback"></param>
|
||||
/// <exception cref="ArgumentNullException">Thrown if any of the provided arguments is null, except for the separator indices.</exception>
|
||||
/// <exception cref="ArgumentException">Thrown if the set of items is empty or does not contain the initial selection value.</exception>
|
||||
public GenericItemContentProvider(T initialValue, ISelectableItem<T>[] items, int[] separatorIndices, Action<T> valueChangedCallback)
|
||||
{
|
||||
if (initialValue == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(initialValue), "The initial selection value must not be null.");
|
||||
}
|
||||
|
||||
if (items == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(items), "The set of items must not be null.");
|
||||
}
|
||||
|
||||
if (valueChangedCallback == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(valueChangedCallback), "The value change callback must not be null.");
|
||||
}
|
||||
|
||||
if (items.Length == 0)
|
||||
{
|
||||
throw new ArgumentException("The set of items must not be empty.", nameof(items));
|
||||
}
|
||||
|
||||
if (!items.Any(i => i.Value.Equals(initialValue)))
|
||||
{
|
||||
throw new ArgumentException("The initial selection value must be in the items set.", nameof(items));
|
||||
}
|
||||
|
||||
m_CurrentValue = initialValue;
|
||||
m_Items = items;
|
||||
SeparatorIndices = separatorIndices ?? new int[0];
|
||||
m_ValueChangedCallback = valueChangedCallback;
|
||||
}
|
||||
|
||||
public int Count => m_Items.Length;
|
||||
public bool IsMultiSelection => false;
|
||||
|
||||
public string GetName(int index)
|
||||
{
|
||||
return ValidateIndexBounds(index) ? m_Items[index].DisplayName : string.Empty;
|
||||
}
|
||||
|
||||
public int[] SeparatorIndices { get; }
|
||||
|
||||
public void SelectItem(int index)
|
||||
{
|
||||
if (!ValidateIndexBounds(index))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsSelected(index))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_CurrentValue = m_Items[index].Value;
|
||||
m_ValueChangedCallback(m_CurrentValue);
|
||||
}
|
||||
|
||||
public bool IsSelected(int index)
|
||||
{
|
||||
return ValidateIndexBounds(index) && m_Items[index].Value.Equals(m_CurrentValue);
|
||||
}
|
||||
|
||||
private bool ValidateIndexBounds(int index)
|
||||
{
|
||||
if (index < 0 || index >= Count)
|
||||
{
|
||||
Debug.LogError($"Requesting item index {index} from a collection of size {Count}");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7348ecf02a70497d9a09bd05ad2038ac
|
||||
timeCreated: 1600072422
|
@@ -0,0 +1,20 @@
|
||||
using System;
|
||||
|
||||
namespace UnityEditor.TestTools.TestRunner.GUI.Controls
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines a content element which can be used with the <see cref="GenericItemContentProvider{T}" /> content provider.
|
||||
/// </summary>
|
||||
internal interface ISelectableItem<out T>
|
||||
{
|
||||
/// <summary>
|
||||
/// The value represented by this item.
|
||||
/// </summary>
|
||||
T Value { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The name to be used when displaying this item.
|
||||
/// </summary>
|
||||
string DisplayName { get; }
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7b076e8f3150431baf926fe9ee030b1e
|
||||
timeCreated: 1600072411
|
@@ -0,0 +1,46 @@
|
||||
using System;
|
||||
|
||||
namespace UnityEditor.TestTools.TestRunner.GUI.Controls
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines a content provider that can be used with the <see cref="SelectionDropDown" /> control.
|
||||
/// </summary>
|
||||
internal interface ISelectionDropDownContentProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// The total number of items to display.
|
||||
/// </summary>
|
||||
int Count { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Multiple selection support.
|
||||
/// Multiple selection dropdowns don't get closed on selection change.
|
||||
/// </summary>
|
||||
bool IsMultiSelection { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The indices of items which should be followed by separator lines.
|
||||
/// </summary>
|
||||
int[] SeparatorIndices { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns the display name of the item at the specified index.
|
||||
/// </summary>
|
||||
/// <param name="index">The index of the item whose display name is to be returned.</param>
|
||||
/// <returns>The display name of the item at the specified index.</returns>
|
||||
string GetName(int index);
|
||||
|
||||
/// <summary>
|
||||
/// Signals a request to select the item at the specified index.
|
||||
/// </summary>
|
||||
/// <param name="index">The index of the item to be selected.</param>
|
||||
void SelectItem(int index);
|
||||
|
||||
/// <summary>
|
||||
/// Returns the selection status of the item at the specified index.
|
||||
/// </summary>
|
||||
/// <param name="index">The index of the item whose selection status is to be returned.</param>
|
||||
/// <returns><c>true</c> if the item is currently selected; otherwise, <c>false</c>. </returns>
|
||||
bool IsSelected(int index);
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c2247a4dfeae4607949780b219a7d3c8
|
||||
timeCreated: 1600072397
|
@@ -0,0 +1,82 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.TestTools.TestRunner.GUI.Controls
|
||||
{
|
||||
internal class MultiValueContentProvider<T> : ISelectionDropDownContentProvider where T : IEquatable<T>
|
||||
{
|
||||
private T[] m_Values;
|
||||
private bool[] m_Selected;
|
||||
private Action<T[]> m_SelectionChangeCallback;
|
||||
|
||||
public MultiValueContentProvider(T[] values, T[] selectedValues, Action<T[]> selectionChangeCallback)
|
||||
{
|
||||
m_Values = values ?? throw new ArgumentNullException(nameof(values));
|
||||
if (selectedValues == null)
|
||||
{
|
||||
m_Selected = new bool[values.Length];
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Selected = values.Select(value => selectedValues.Contains(value)).ToArray();
|
||||
}
|
||||
m_SelectionChangeCallback = selectionChangeCallback;
|
||||
}
|
||||
|
||||
public int Count
|
||||
{
|
||||
get { return m_Values.Length; }
|
||||
}
|
||||
|
||||
public bool IsMultiSelection
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
public int[] SeparatorIndices
|
||||
{
|
||||
get { return new int[0]; }
|
||||
}
|
||||
public string GetName(int index)
|
||||
{
|
||||
if (!ValidateIndexBounds(index))
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
return m_Values[index].ToString();
|
||||
}
|
||||
|
||||
public void SelectItem(int index)
|
||||
{
|
||||
if (!ValidateIndexBounds(index))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_Selected[index] = !m_Selected[index];
|
||||
m_SelectionChangeCallback.Invoke(m_Values.Where((v, i) => m_Selected[i]).ToArray());
|
||||
}
|
||||
|
||||
public bool IsSelected(int index)
|
||||
{
|
||||
if (!ValidateIndexBounds(index))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return m_Selected[index];
|
||||
}
|
||||
|
||||
private bool ValidateIndexBounds(int index)
|
||||
{
|
||||
if (index < 0 || index >= Count)
|
||||
{
|
||||
Debug.LogError($"Requesting item index {index} from a collection of size {Count}");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fb736ed47b6da4b499431bf9c6de5890
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
|
||||
namespace UnityEditor.TestTools.TestRunner.GUI.Controls
|
||||
{
|
||||
/// <summary>
|
||||
/// A default implementation of the <see cref="ISelectableItem{T}" /> interface.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the value represented by this content element.</typeparam>
|
||||
internal class SelectableItemContent<T> : ISelectableItem<T>
|
||||
{
|
||||
private readonly string m_DisplayName;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="SelectableItemContent{T}" /> class
|
||||
/// </summary>
|
||||
/// <param name="itemValue">The value represented by this item.</param>
|
||||
/// <param name="displayName">The display name of this item.</param>
|
||||
public SelectableItemContent(T itemValue, string displayName)
|
||||
{
|
||||
Value = itemValue;
|
||||
m_DisplayName = displayName;
|
||||
}
|
||||
|
||||
public T Value { get; }
|
||||
|
||||
public string DisplayName => m_DisplayName ?? string.Empty;
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f7d5e5417ccd4aa0bfa39228c674f142
|
||||
timeCreated: 1600072417
|
@@ -0,0 +1,167 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f8f9b43d4e034c2d997f4eb6a0d85a96
|
||||
timeCreated: 1600072477
|
Reference in New Issue
Block a user