#nullable enable
namespace Terminal.Gui;
///
/// Provides a user interface for displaying and selecting flags.
/// Flags can be set from a dictionary or directly from an enum type.
///
public sealed class FlagSelector : FlagSelector where TEnum : struct, Enum
{
///
/// Initializes a new instance of the class.
///
public FlagSelector ()
{
SetFlags ();
}
///
/// Gets or sets the value of the selected flags.
///
public new TEnum? Value
{
get => base.Value.HasValue ? (TEnum)Enum.ToObject (typeof (TEnum), base.Value.Value) : (TEnum?)null;
set => base.Value = value.HasValue ? Convert.ToUInt32 (value.Value) : (uint?)null;
}
///
/// Set the display names for the flags.
///
/// A function that converts enum values to display names
///
/// This method allows changing the display names of the flags while keeping the flag values hard-defined by the enum type.
///
///
///
/// // Use enum values with custom display names
/// var flagSelector = new FlagSelector<FlagSelectorStyles>();
/// flagSelector.SetFlagNames(f => f switch {
/// FlagSelectorStyles.ShowNone => "Show None Value",
/// FlagSelectorStyles.ShowValueEdit => "Show Value Editor",
/// FlagSelectorStyles.All => "Everything",
/// _ => f.ToString()
/// });
///
///
public void SetFlagNames (Func nameSelector)
{
Dictionary flagsDictionary = Enum.GetValues ()
.ToDictionary (f => Convert.ToUInt32 (f), nameSelector);
base.SetFlags (flagsDictionary);
}
private void SetFlags ()
{
Dictionary flagsDictionary = Enum.GetValues ()
.ToDictionary (f => Convert.ToUInt32 (f), f => f.ToString ());
base.SetFlags (flagsDictionary);
}
///
/// Prevents calling the base SetFlags method with arbitrary flag values.
///
///
public override void SetFlags (IReadOnlyDictionary flags)
{
throw new InvalidOperationException ("Setting flag values directly is not allowed. Use SetFlagNames to change display names.");
}
///
protected override CheckBox CreateCheckBox (string name, uint flag)
{
var checkbox = base.CreateCheckBox (name, flag);
checkbox.CheckedStateChanged += (sender, args) =>
{
TEnum? newValue = Value;
if (checkbox.CheckedState == CheckState.Checked)
{
if (flag == default!)
{
newValue = new TEnum ();
}
else
{
newValue = (TEnum)Enum.ToObject (typeof (TEnum), Convert.ToUInt32 (newValue) | flag);
}
}
else
{
newValue = (TEnum)Enum.ToObject (typeof (TEnum), Convert.ToUInt32 (newValue) & ~flag);
}
Value = newValue;
};
return checkbox;
}
}