general messing around

This commit is contained in:
Tig
2025-04-02 14:54:42 -06:00
parent ba7fb2181e
commit 366cd8985c
4 changed files with 96 additions and 25 deletions

View File

@@ -24,7 +24,7 @@ public class FlagSelector : View, IOrientation, IDesignable
// Accept (Enter key or DoubleClick) - Raise Accept event - DO NOT advance state
AddCommand (Command.Accept, HandleAcceptCommand);
CreateSubViews ();
CreateCheckBoxes ();
}
private bool? HandleAcceptCommand (ICommandContext? ctx) { return RaiseAccepting (ctx); }
@@ -101,7 +101,7 @@ public class FlagSelector : View, IOrientation, IDesignable
_styles = value;
CreateSubViews ();
CreateCheckBoxes ();
}
}
@@ -112,7 +112,8 @@ public class FlagSelector : View, IOrientation, IDesignable
public virtual void SetFlags (IReadOnlyDictionary<uint, string> flags)
{
Flags = flags;
CreateSubViews ();
CreateCheckBoxes ();
UpdateChecked ();
}
@@ -170,14 +171,57 @@ public class FlagSelector : View, IOrientation, IDesignable
SetFlags (flagsDictionary);
}
private IReadOnlyDictionary<uint, string>? _flags;
/// <summary>
/// Gets the flag values and names.
/// </summary>
public IReadOnlyDictionary<uint, string>? Flags { get; internal set; }
public IReadOnlyDictionary<uint, string>? Flags
{
get => _flags;
internal set
{
_flags = value;
if (_value is null)
{
Value = Convert.ToUInt16 (_flags?.Keys.ElementAt (0));
}
}
}
private TextField? ValueEdit { get; set; }
private void CreateSubViews ()
private bool _assignHotKeysToCheckBoxes;
/// <summary>
/// If <see langword="true"/> the CheckBoxes will each be automatically assigned a hotkey.
/// <see cref="UsedHotKeys"/> will be used to ensure unique keys are assigned. Set <see cref="UsedHotKeys"/>
/// before setting <see cref="Flags"/> with any hotkeys that may conflict with other Views.
/// </summary>
public bool AssignHotKeysToCheckBoxes
{
get => _assignHotKeysToCheckBoxes;
set
{
if (_assignHotKeysToCheckBoxes == value)
{
return;
}
_assignHotKeysToCheckBoxes = value;
CreateCheckBoxes ();
UpdateChecked();
}
}
/// <summary>
/// Gets the list of hotkeys already used by the CheckBoxes or that should not be used if
/// <see cref="AssignHotKeysToCheckBoxes"/>
/// is enabled.
/// </summary>
public List<Key> UsedHotKeys { get; } = [];
private void CreateCheckBoxes ()
{
if (Flags is null)
{
@@ -189,14 +233,14 @@ public class FlagSelector : View, IOrientation, IDesignable
cb.Dispose ();
}
if (Styles.HasFlag (FlagSelectorStyles.ShowNone) && !Flags.ContainsKey (default!))
if (Styles.HasFlag (FlagSelectorStyles.ShowNone) && !Flags.ContainsKey (0))
{
Add (CreateCheckBox ("None", default!));
Add (CreateCheckBox ("None", 0));
}
for (var index = 0; index < Flags.Count; index++)
{
if (!Styles.HasFlag (FlagSelectorStyles.ShowNone) && Flags.ElementAt (index).Key == default!)
if (!Styles.HasFlag (FlagSelectorStyles.ShowNone) && Flags.ElementAt (index).Key == 0)
{
continue;
}
@@ -224,6 +268,7 @@ public class FlagSelector : View, IOrientation, IDesignable
}
/// <summary>
///
/// </summary>
@@ -232,10 +277,33 @@ public class FlagSelector : View, IOrientation, IDesignable
/// <returns></returns>
protected virtual CheckBox CreateCheckBox (string name, uint flag)
{
string nameWithHotKey = name;
if (AssignHotKeysToCheckBoxes)
{
// Find the first char in label that is [a-z], [A-Z], or [0-9]
for (var i = 0; i < name.Length; i++)
{
char c = char.ToLowerInvariant (name [i]);
if (UsedHotKeys.Contains (new (c)) || !char.IsAsciiLetterOrDigit (c))
{
continue;
}
if (char.IsAsciiLetterOrDigit (c))
{
char? hotChar = c;
nameWithHotKey = name.Insert (i, HotKeySpecifier.ToString ());
UsedHotKeys.Add (new (hotChar));
break;
}
}
}
var checkbox = new CheckBox
{
CanFocus = false,
Title = name,
Title = nameWithHotKey,
Id = name,
Data = flag,
HighlightStyle = HighlightStyle
@@ -357,7 +425,7 @@ public class FlagSelector : View, IOrientation, IDesignable
f => f switch
{
FlagSelectorStyles.None => "_No Style",
FlagSelectorStyles.ShowNone => "Show _None Value Style",
FlagSelectorStyles.ShowNone => "_Show None Value Style",
FlagSelectorStyles.ShowValueEdit => "Show _Value Editor Style",
FlagSelectorStyles.All => "_All Styles",
_ => f.ToString ()

View File

@@ -5,7 +5,7 @@ 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.
/// </summary>
public class FlagSelector<TEnum> : FlagSelector where TEnum : struct, Enum
public sealed class FlagSelector<TEnum> : FlagSelector where TEnum : struct, Enum
{
/// <summary>
/// Initializes a new instance of the <see cref="FlagSelector{TEnum}"/> class.
@@ -34,7 +34,7 @@ public class FlagSelector<TEnum> : FlagSelector where TEnum : struct, Enum
/// <example>
/// <code>
/// // Use enum values with custom display names
/// var flagSelector = new FlagSelector();
/// var flagSelector = new FlagSelector&lt;FlagSelectorStyles&gt();
/// flagSelector.SetFlagNames(f => f switch {
/// FlagSelectorStyles.ShowNone => "Show None Value",
/// FlagSelectorStyles.ShowValueEdit => "Show Value Editor",

View File

@@ -281,23 +281,24 @@ public class RadioGroup : View, IDesignable, IOrientation
// Pick a unique hotkey for each radio label
for (var labelIndex = 0; labelIndex < value.Length; labelIndex++)
{
string label = value [labelIndex];
string? newLabel = label;
string name = value [labelIndex];
string? nameWithHotKey = name;
if (AssignHotKeysToRadioLabels)
{
// Find the first char in label that is [a-z], [A-Z], or [0-9]
for (var i = 0; i < label.Length; i++)
for (var i = 0; i < name.Length; i++)
{
if (UsedHotKeys.Contains (new (label [i])) || !char.IsAsciiLetterOrDigit (label [i]))
char c = char.ToLowerInvariant (name [i]);
if (UsedHotKeys.Contains (new (c)) || !char.IsAsciiLetterOrDigit (c))
{
continue;
}
if (char.IsAsciiLetterOrDigit (label [i]))
if (char.IsAsciiLetterOrDigit (c))
{
char? hotChar = label [i];
newLabel = label.Insert (i, HotKeySpecifier.ToString ());
char? hotChar = c;
nameWithHotKey = name.Insert (i, HotKeySpecifier.ToString ());
UsedHotKeys.Add (new (hotChar));
break;
@@ -305,9 +306,9 @@ public class RadioGroup : View, IDesignable, IOrientation
}
}
_radioLabels.Add (newLabel);
_radioLabels.Add (nameWithHotKey);
if (TextFormatter.FindHotKey (newLabel, HotKeySpecifier, out _, out Key hotKey))
if (TextFormatter.FindHotKey (nameWithHotKey, HotKeySpecifier, out _, out Key hotKey))
{
AddKeyBindingsForHotKey (Key.Empty, hotKey, labelIndex);
}

View File

@@ -240,12 +240,14 @@ public class UICatalogTop : Toplevel
Styles = FlagSelectorStyles.ShowNone,
HighlightStyle = HighlightStyle.None,
};
_diagnosticFlagsSelector.UsedHotKeys.Add (Key.D);
_diagnosticFlagsSelector.AssignHotKeysToCheckBoxes = true;
_diagnosticFlagsSelector.Value = Diagnostics;
_diagnosticFlagsSelector.ValueChanged += (sender, args) =>
{
_diagnosticFlags = (ViewDiagnosticFlags)_diagnosticFlagsSelector.Value;
Diagnostics = _diagnosticFlags;
};
{
_diagnosticFlags = (ViewDiagnosticFlags)_diagnosticFlagsSelector.Value;
Diagnostics = _diagnosticFlags;
};
menuItems.Add (
new MenuItemv2