123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118 |
- 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;
- }
- }
- }
|