Super rough sketch of what generics solution would look like

This commit is contained in:
tznind
2024-12-09 16:59:17 +00:00
parent 9f4d30db2b
commit bf8879537c
4 changed files with 46 additions and 3 deletions

View File

@@ -11,7 +11,7 @@ namespace Terminal.Gui;
/// <seealso cref="Application.KeyBindings"/>
/// <seealso cref="View.KeyBindings"/>
/// <seealso cref="Command"/>
public record struct KeyBinding
public record struct KeyBinding : IInputBinding
{
/// <summary>Initializes a new instance.</summary>
/// <param name="commands">The commands this key binding will invoke.</param>

View File

@@ -0,0 +1,7 @@
#nullable enable
namespace Terminal.Gui;
public interface IInputBinding
{
Command [] Commands { get; set; }
}

View File

@@ -6,7 +6,7 @@ namespace Terminal.Gui;
/// Provides a collection of <see cref="Command"/> objects for mouse events.
/// </summary>
/// <seealso cref="Command"/>
public record struct MouseBinding
public record struct MouseBinding : IInputBinding
{
/// <summary>Initializes a new instance.</summary>
/// <param name="commands">The commands this mouse binding will invoke.</param>

View File

@@ -1,12 +1,48 @@
#nullable enable
namespace Terminal.Gui;
public abstract class Bindings<TKey, TBind> where TKey: Enum where TBind : IInputBinding, new()
{
private readonly Dictionary<TKey, TBind> _bindings = new ();
/// <summary>Adds a <see cref="MouseBinding"/> to the collection.</summary>
/// <param name="mouseEventArgs"></param>
/// <param name="binding"></param>
public void Add (TKey mouseEventArgs, TBind binding)
{
if (TryGet (mouseEventArgs, out TBind _))
{
throw new InvalidOperationException (@$"A binding for {mouseEventArgs} exists ({binding}).");
}
// IMPORTANT: Add a COPY of the mouseEventArgs. This is needed because ConfigurationManager.Apply uses DeepMemberWiseCopy
// IMPORTANT: update the memory referenced by the key, and Dictionary uses caching for performance, and thus
// IMPORTANT: Apply will update the Dictionary with the new mouseEventArgs, but the old mouseEventArgs will still be in the dictionary.
// IMPORTANT: See the ConfigurationManager.Illustrate_DeepMemberWiseCopy_Breaks_Dictionary test for details.
_bindings.Add (mouseEventArgs, binding);
}
/// <summary>Gets the commands bound with the specified <see cref="MouseFlags"/>.</summary>
/// <remarks></remarks>
/// <param name="mouseEventArgs">The key to check.</param>
/// <param name="binding">
/// When this method returns, contains the commands bound with the specified mouse flags, if the mouse flags are
/// found; otherwise, null. This parameter is passed uninitialized.
/// </param>
/// <returns><see langword="true"/> if the mouse flags are bound; otherwise <see langword="false"/>.</returns>
public bool TryGet (TKey mouseEventArgs, out TBind? binding)
{
return _bindings.TryGetValue (mouseEventArgs, out binding);
}
}
/// <summary>
/// Provides a collection of <see cref="MouseBinding"/> objects bound to a combination of <see cref="MouseFlags"/>.
/// </summary>
/// <seealso cref="View.MouseBindings"/>
/// <seealso cref="Command"/>
public class MouseBindings
public class MouseBindings : Bindings<MouseFlags,MouseBinding>
{
/// <summary>
/// Initializes a new instance. This constructor is used when the <see cref="MouseBindings"/> are not bound to a