Skip to content

Commit 9002acf

Browse files
committed
WIP move more to bind base class
1 parent bf88795 commit 9002acf

File tree

1 file changed

+50
-55
lines changed

1 file changed

+50
-55
lines changed

Terminal.Gui/Input/Mouse/MouseBindings.cs

Lines changed: 50 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,17 @@
11
#nullable enable
2+
using System.Collections.Generic;
3+
24
namespace Terminal.Gui;
35

46
public abstract class Bindings<TKey, TBind> where TKey: Enum where TBind : IInputBinding, new()
57
{
6-
private readonly Dictionary<TKey, TBind> _bindings = new ();
8+
protected readonly Dictionary<TKey, TBind> _bindings = new ();
9+
private readonly Func<Command [], TKey, TBind> _constructBinding;
10+
11+
protected Bindings (Func<Command [], TKey, TBind> constructBinding)
12+
{
13+
_constructBinding = constructBinding;
14+
}
715

816
/// <summary>Adds a <see cref="MouseBinding"/> to the collection.</summary>
917
/// <param name="mouseEventArgs"></param>
@@ -35,37 +43,7 @@ public bool TryGet (TKey mouseEventArgs, out TBind? binding)
3543
{
3644
return _bindings.TryGetValue (mouseEventArgs, out binding);
3745
}
38-
}
39-
40-
/// <summary>
41-
/// Provides a collection of <see cref="MouseBinding"/> objects bound to a combination of <see cref="MouseFlags"/>.
42-
/// </summary>
43-
/// <seealso cref="View.MouseBindings"/>
44-
/// <seealso cref="Command"/>
45-
public class MouseBindings : Bindings<MouseFlags,MouseBinding>
46-
{
47-
/// <summary>
48-
/// Initializes a new instance. This constructor is used when the <see cref="MouseBindings"/> are not bound to a
49-
/// <see cref="View"/>. This is used for Application.MouseBindings and unit tests.
50-
/// </summary>
51-
public MouseBindings () { }
5246

53-
/// <summary>Adds a <see cref="MouseBinding"/> to the collection.</summary>
54-
/// <param name="mouseEventArgs"></param>
55-
/// <param name="binding"></param>
56-
public void Add (MouseFlags mouseEventArgs, MouseBinding binding)
57-
{
58-
if (TryGet (mouseEventArgs, out MouseBinding _))
59-
{
60-
throw new InvalidOperationException (@$"A binding for {mouseEventArgs} exists ({binding}).");
61-
}
62-
63-
// IMPORTANT: Add a COPY of the mouseEventArgs. This is needed because ConfigurationManager.Apply uses DeepMemberWiseCopy
64-
// IMPORTANT: update the memory referenced by the key, and Dictionary uses caching for performance, and thus
65-
// IMPORTANT: Apply will update the Dictionary with the new mouseEventArgs, but the old mouseEventArgs will still be in the dictionary.
66-
// IMPORTANT: See the ConfigurationManager.Illustrate_DeepMemberWiseCopy_Breaks_Dictionary test for details.
67-
_bindings.Add (mouseEventArgs, binding);
68-
}
6947

7048
/// <summary>
7149
/// <para>Adds a new mouse flag combination that will trigger the commands in <paramref name="commands"/>.</para>
@@ -85,9 +63,9 @@ public void Add (MouseFlags mouseEventArgs, MouseBinding binding)
8563
/// will be
8664
/// consumed if any took effect.
8765
/// </param>
88-
public void Add (MouseFlags mouseFlags, params Command [] commands)
66+
public void Add (TKey mouseFlags, params Command [] commands)
8967
{
90-
if (mouseFlags == MouseFlags.None)
68+
if (EqualityComparer<TKey>.Default.Equals (mouseFlags, default))
9169
{
9270
throw new ArgumentException (@"Invalid MouseFlag", nameof (mouseFlags));
9371
}
@@ -97,21 +75,19 @@ public void Add (MouseFlags mouseFlags, params Command [] commands)
9775
throw new ArgumentException (@"At least one command must be specified", nameof (commands));
9876
}
9977

100-
if (TryGet (mouseFlags, out MouseBinding binding))
78+
if (TryGet (mouseFlags, out var binding))
10179
{
10280
throw new InvalidOperationException (@$"A binding for {mouseFlags} exists ({binding}).");
10381
}
10482

105-
Add (mouseFlags, new MouseBinding (commands, mouseFlags));
83+
Add (mouseFlags, _constructBinding(commands,mouseFlags));
10684
}
10785

108-
private readonly Dictionary<MouseFlags, MouseBinding> _bindings = new ();
109-
11086
/// <summary>
11187
/// Gets the bindings.
11288
/// </summary>
11389
/// <returns></returns>
114-
public IEnumerable<KeyValuePair<MouseFlags, MouseBinding>> GetBindings ()
90+
public IEnumerable<KeyValuePair<TKey, TBind>> GetBindings ()
11591
{
11692
return _bindings;
11793
}
@@ -126,11 +102,11 @@ public IEnumerable<KeyValuePair<MouseFlags, MouseBinding>> GetBindings ()
126102
/// <param name="command"></param>
127103
public void Clear (params Command [] command)
128104
{
129-
KeyValuePair<MouseFlags, MouseBinding> [] kvps = _bindings
130-
.Where (kvp => kvp.Value.Commands.SequenceEqual (command))
131-
.ToArray ();
105+
KeyValuePair<TKey, TBind> [] kvps = _bindings
106+
.Where (kvp => kvp.Value.Commands.SequenceEqual (command))
107+
.ToArray ();
132108

133-
foreach (KeyValuePair<MouseFlags, MouseBinding> kvp in kvps)
109+
foreach (KeyValuePair<TKey, TBind> kvp in kvps)
134110
{
135111
Remove (kvp.Key);
136112
}
@@ -139,16 +115,46 @@ public void Clear (params Command [] command)
139115
/// <summary>Gets the <see cref="MouseBinding"/> for the specified combination of <see cref="MouseFlags"/>.</summary>
140116
/// <param name="mouseEventArgs"></param>
141117
/// <returns></returns>
142-
public MouseBinding Get (MouseFlags mouseEventArgs)
118+
public TBind? Get (TKey mouseEventArgs)
143119
{
144-
if (TryGet (mouseEventArgs, out MouseBinding binding))
120+
if (TryGet (mouseEventArgs, out var binding))
145121
{
146122
return binding;
147123
}
148124

149125
throw new InvalidOperationException ($"{mouseEventArgs} is not bound.");
150126
}
151127

128+
129+
/// <summary>Removes a <see cref="MouseBinding"/> from the collection.</summary>
130+
/// <param name="mouseEventArgs"></param>
131+
public void Remove (TKey mouseEventArgs)
132+
{
133+
if (!TryGet (mouseEventArgs, out var _))
134+
{
135+
return;
136+
}
137+
138+
_bindings.Remove (mouseEventArgs);
139+
}
140+
}
141+
142+
/// <summary>
143+
/// Provides a collection of <see cref="MouseBinding"/> objects bound to a combination of <see cref="MouseFlags"/>.
144+
/// </summary>
145+
/// <seealso cref="View.MouseBindings"/>
146+
/// <seealso cref="Command"/>
147+
public class MouseBindings : Bindings<MouseFlags,MouseBinding>
148+
{
149+
/// <summary>
150+
/// Initializes a new instance. This constructor is used when the <see cref="MouseBindings"/> are not bound to a
151+
/// <see cref="View"/>. This is used for Application.MouseBindings and unit tests.
152+
/// </summary>
153+
public MouseBindings ():base(
154+
(commands, flags)=> new MouseBinding (commands, flags)) { }
155+
156+
157+
152158
/// <summary>
153159
/// Gets combination of <see cref="MouseFlags"/> bound to the set of commands specified by
154160
/// <paramref name="commands"/>.
@@ -200,17 +206,6 @@ public MouseFlags GetMouseFlagsFromCommands (params Command [] commands)
200206
return _bindings.FirstOrDefault (a => a.Value.Commands.SequenceEqual (commands)).Key;
201207
}
202208

203-
/// <summary>Removes a <see cref="MouseBinding"/> from the collection.</summary>
204-
/// <param name="mouseEventArgs"></param>
205-
public void Remove (MouseFlags mouseEventArgs)
206-
{
207-
if (!TryGet (mouseEventArgs, out MouseBinding _))
208-
{
209-
return;
210-
}
211-
212-
_bindings.Remove (mouseEventArgs);
213-
}
214209

215210
/// <summary>Replaces the commands already bound to a combination of <see cref="MouseFlags"/>.</summary>
216211
/// <remarks>

0 commit comments

Comments
 (0)