Editor/Widgets/EnumControl.cs
using Sandbox;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Panelize;
public abstract class EnumControl<T> : Widget where T : struct, Enum
{
public Dictionary<T, DisplayInfo> DisplayOverrides { get; set; } = new();
/// <summary>
/// Display items in this order.
/// </summary>
public List<T> ValueOverrides { get; set; } = new();
public T Value { get; protected set; }
public Action<T> OnValueChanged { get; set; }
public EnumControl(T defaultValue = default)
{
Value = default;
}
public virtual void SetValue(T value)
{
Value = value;
OnValueChanged?.Invoke( value );
}
public void SetDisplay( T value, string icon = "", string name = "", string description = "", string group = "" )
{
bool iconChanged = !string.IsNullOrEmpty( icon );
bool nameChanged = !string.IsNullOrEmpty( name );
bool descriptionChanged = !string.IsNullOrEmpty( description );
bool groupChanged = !string.IsNullOrEmpty( group );
if ( DisplayOverrides.TryGetValue( value, out var o ) )
{
if(iconChanged)
o.Icon = icon;
if ( nameChanged )
o.Name = name;
if(descriptionChanged)
o.Description = description;
if ( groupChanged )
o.Group = group;
DisplayOverrides[value] = o;
}
else
{
DisplayInfo info = new();
DisplayInfo existing = DisplayInfo.ForEnumValues<T>()
.Where(e => e.value.Equals(value)).FirstOrDefault().info;
info.Icon = iconChanged ? icon : existing.Icon;
info.Name = nameChanged ? name : existing.Name;
info.Description = descriptionChanged ? description : existing.Description;
info.Group = groupChanged ? group : existing.Group;
info.Browsable = true;
DisplayOverrides.Add( value, info );
}
}
/// <summary>
/// Set order of values to be displayed.
/// Values not in list are not displayed.
/// </summary>
/// <param name="values"></param>
public void SetOrder( params T[] values )
{
ValueOverrides = values.ToList();
}
public (T, DisplayInfo)[] GetValueDisplays()
{
var valueDisplays = DisplayInfo.ForEnumValues<T>();
if ( ValueOverrides != null && ValueOverrides.Count > 0 )
{
valueDisplays = valueDisplays
.IntersectBy( ValueOverrides, kv => kv.value )
.OrderBy( kv => ValueOverrides.IndexOf( kv.value ) )
.ToArray();
}
if(DisplayOverrides.Count > 0)
{
List<(T value, DisplayInfo info)> newDisplays = new();
foreach((T value, DisplayInfo info) in valueDisplays)
{
if(DisplayOverrides.ContainsKey(value))
{
DisplayInfo o = DisplayOverrides[value];
newDisplays.Add( (value, o) );
}
else
{
newDisplays.Add( (value, info) );
}
}
valueDisplays = newDisplays.ToArray();
}
return valueDisplays;
}
public DisplayInfo GetValueDisplay(T value)
{
if(DisplayOverrides.ContainsKey(value))
{
return DisplayOverrides[value];
}
return DisplayInfo.ForEnumValues<T>()
.Where( e => e.value.Equals( value ) ).FirstOrDefault().info;
}
}