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