瀏覽代碼

Added mouse support. update charmap

Tig 7 月之前
父節點
當前提交
f6b65c6f08

+ 7 - 3
Terminal.Gui/Input/Mouse/MouseBinding.cs

@@ -10,11 +10,15 @@ public record struct MouseBinding
 {
     /// <summary>Initializes a new instance.</summary>
     /// <param name="commands">The commands this mouse binding will invoke.</param>
-    /// <param name="mouseEventArgs">The mouse event arguments, to be passed as context.</param>
-    public MouseBinding (Command [] commands, MouseEventArgs? mouseEventArgs)
+    /// <param name="mouseFlags">The mouse flags that trigger this binding.</param>
+    public MouseBinding (Command [] commands, MouseFlags mouseFlags)
     {
         Commands = commands;
-        MouseEventArgs = mouseEventArgs;
+
+        MouseEventArgs = new MouseEventArgs()
+        {
+            Flags = mouseFlags
+        };
     }
 
     /// <summary>The commands this key binding will invoke.</summary>

+ 35 - 35
Terminal.Gui/Input/Mouse/MouseBindings.cs

@@ -2,7 +2,7 @@
 namespace Terminal.Gui;
 
 /// <summary>
-///     Provides a collection of <see cref="MouseBinding"/> objects bound to a combination of <see cref="MouseEventArgs"/>.
+///     Provides a collection of <see cref="MouseBinding"/> objects bound to a combination of <see cref="MouseFlags"/>.
 /// </summary>
 /// <seealso cref="View.MouseBindings"/>
 /// <seealso cref="Command"/>
@@ -17,7 +17,7 @@ public class MouseBindings
     /// <summary>Adds a <see cref="MouseBinding"/> to the collection.</summary>
     /// <param name="mouseEventArgs"></param>
     /// <param name="binding"></param>
-    public void Add (MouseEventArgs mouseEventArgs, MouseBinding binding)
+    public void Add (MouseFlags mouseEventArgs, MouseBinding binding)
     {
         if (TryGet (mouseEventArgs, out MouseBinding _))
         {
@@ -49,9 +49,9 @@ public class MouseBindings
     ///     will be
     ///     consumed if any took effect.
     /// </param>
-    public void Add (MouseEventArgs mouseEventArgs, params Command [] commands)
+    public void Add (MouseFlags mouseEventArgs, params Command [] commands)
     {
-        if (mouseEventArgs.Flags == MouseFlags.None)
+        if (mouseEventArgs == MouseFlags.None)
         {
             throw new ArgumentException (@"Invalid MouseFlag", nameof (commands));
         }
@@ -72,7 +72,7 @@ public class MouseBindings
     // TODO: Add a dictionary comparer that ignores Scope
     // TODO: This should not be public!
     /// <summary>The collection of <see cref="MouseBinding"/> objects.</summary>
-    public Dictionary<MouseEventArgs, MouseBinding> Bindings { get; } = new ();
+    public Dictionary<MouseFlags, MouseBinding> Bindings { get; } = new ();
 
     /// <summary>Removes all <see cref="MouseBinding"/> objects from the collection.</summary>
     public void Clear () { Bindings.Clear (); }
@@ -84,20 +84,20 @@ public class MouseBindings
     /// <param name="command"></param>
     public void Clear (params Command [] command)
     {
-        KeyValuePair<MouseEventArgs, MouseBinding> [] kvps = Bindings
+        KeyValuePair<MouseFlags, MouseBinding> [] kvps = Bindings
                                                              .Where (kvp => kvp.Value.Commands.SequenceEqual (command))
                                                              .ToArray ();
 
-        foreach (KeyValuePair<MouseEventArgs, MouseBinding> kvp in kvps)
+        foreach (KeyValuePair<MouseFlags, MouseBinding> kvp in kvps)
         {
             Remove (kvp.Key);
         }
     }
 
-    /// <summary>Gets the <see cref="MouseBinding"/> for the specified combination of <see cref="MouseEventArgs"/>.</summary>
+    /// <summary>Gets the <see cref="MouseBinding"/> for the specified combination of <see cref="MouseFlags"/>.</summary>
     /// <param name="mouseEventArgs"></param>
     /// <returns></returns>
-    public MouseBinding Get (MouseEventArgs mouseEventArgs)
+    public MouseBinding Get (MouseFlags mouseEventArgs)
     {
         if (TryGet (mouseEventArgs, out MouseBinding binding))
         {
@@ -108,24 +108,24 @@ public class MouseBindings
     }
 
     /// <summary>
-    ///     Gets combination of <see cref="MouseEventArgs"/> bound to the set of commands specified by
+    ///     Gets combination of <see cref="MouseFlags"/> bound to the set of commands specified by
     ///     <paramref name="commands"/>.
     /// </summary>
     /// <param name="commands">The set of commands to search.</param>
     /// <returns>
-    ///     The combination of <see cref="MouseEventArgs"/> bound to the set of commands specified by
+    ///     The combination of <see cref="MouseFlags"/> bound to the set of commands specified by
     ///     <paramref name="commands"/>. An empty list if the set of caommands was not found.
     /// </returns>
-    public IEnumerable<MouseEventArgs> GetAllMouseEventArgsFromCommands (params Command [] commands)
+    public IEnumerable<MouseFlags> GetAllMouseFlagsFromCommands (params Command [] commands)
     {
         return Bindings.Where (a => a.Value.Commands.SequenceEqual (commands)).Select (a => a.Key);
     }
 
     /// <summary>
-    ///     Gets the <see cref="MouseEventArgs"/> that are bound.
+    ///     Gets the <see cref="MouseFlags"/> that are bound.
     /// </summary>
     /// <returns></returns>
-    public IEnumerable<MouseEventArgs> GetBoundMouseEventArgs () { return Bindings.Keys; }
+    public IEnumerable<MouseFlags> GetBoundMouseFlags () { return Bindings.Keys; }
 
     /// <summary>Gets the array of <see cref="Command"/>s bound to <paramref name="mouseEventArgs"/> if it exists.</summary>
     /// <param name="mouseEventArgs">The key to check.</param>
@@ -134,7 +134,7 @@ public class MouseBindings
     ///     array
     ///     if not.
     /// </returns>
-    public Command [] GetCommands (MouseEventArgs mouseEventArgs)
+    public Command [] GetCommands (MouseFlags mouseEventArgs)
     {
         if (TryGet (mouseEventArgs, out MouseBinding bindings))
         {
@@ -145,22 +145,22 @@ public class MouseBindings
     }
 
     /// <summary>
-    ///     Gets the first combination of <see cref="MouseEventArgs"/> bound to the set of commands specified by
+    ///     Gets the first combination of <see cref="MouseFlags"/> bound to the set of commands specified by
     ///     <paramref name="commands"/>.
     /// </summary>
     /// <param name="commands">The set of commands to search.</param>
     /// <returns>
-    ///     The first combination of <see cref="MouseEventArgs"/> bound to the set of commands specified by
+    ///     The first combination of <see cref="MouseFlags"/> bound to the set of commands specified by
     ///     <paramref name="commands"/>. <see langword="null"/> if the set of caommands was not found.
     /// </returns>
-    public MouseEventArgs? GetMouseEventArgsFromCommands (params Command [] commands)
+    public MouseFlags? GetMouseFlagsFromCommands (params Command [] commands)
     {
         return Bindings.FirstOrDefault (a => a.Value.Commands.SequenceEqual (commands)).Key;
     }
 
     /// <summary>Removes a <see cref="MouseBinding"/> from the collection.</summary>
     /// <param name="mouseEventArgs"></param>
-    public void Remove (MouseEventArgs mouseEventArgs)
+    public void Remove (MouseFlags mouseEventArgs)
     {
         if (!TryGet (mouseEventArgs, out MouseBinding _))
         {
@@ -170,15 +170,15 @@ public class MouseBindings
         Bindings.Remove (mouseEventArgs);
     }
 
-    /// <summary>Replaces the commands already bound to a combination of <see cref="MouseEventArgs"/>.</summary>
+    /// <summary>Replaces the commands already bound to a combination of <see cref="MouseFlags"/>.</summary>
     /// <remarks>
     ///     <para>
-    ///         If the combination of <see cref="MouseEventArgs"/> is not already bound, it will be added.
+    ///         If the combination of <see cref="MouseFlags"/> is not already bound, it will be added.
     ///     </para>
     /// </remarks>
-    /// <param name="mouseEventArgs">The combination of <see cref="MouseEventArgs"/> bound to the command to be replaced.</param>
+    /// <param name="mouseEventArgs">The combination of <see cref="MouseFlags"/> bound to the command to be replaced.</param>
     /// <param name="commands">The set of commands to replace the old ones with.</param>
-    public void ReplaceCommands (MouseEventArgs mouseEventArgs, params Command [] commands)
+    public void ReplaceCommands (MouseFlags mouseEventArgs, params Command [] commands)
     {
         if (TryGet (mouseEventArgs, out MouseBinding binding))
         {
@@ -190,26 +190,26 @@ public class MouseBindings
         }
     }
 
-    /// <summary>Replaces a <see cref="MouseEventArgs"/> combination already bound to a set of <see cref="Command"/>s.</summary>
+    /// <summary>Replaces a <see cref="MouseFlags"/> combination already bound to a set of <see cref="Command"/>s.</summary>
     /// <remarks></remarks>
-    /// <param name="oldMouseEventArgs">The <see cref="MouseEventArgs"/> to be replaced.</param>
-    /// <param name="newMouseEventArgs">
-    ///     The new <see cref="MouseEventArgs"/> to be used. If <see cref="Key.Empty"/> no action
+    /// <param name="oldMouseFlags">The <see cref="MouseFlags"/> to be replaced.</param>
+    /// <param name="newMouseFlags">
+    ///     The new <see cref="MouseFlags"/> to be used. If <see cref="Key.Empty"/> no action
     ///     will be taken.
     /// </param>
-    public void ReplaceKey (MouseEventArgs oldMouseEventArgs, MouseEventArgs newMouseEventArgs)
+    public void ReplaceKey (MouseFlags oldMouseFlags, MouseFlags newMouseFlags)
     {
-        if (!TryGet (oldMouseEventArgs, out MouseBinding _))
+        if (!TryGet (oldMouseFlags, out MouseBinding _))
         {
-            throw new InvalidOperationException ($"Key {oldMouseEventArgs} is not bound.");
+            throw new InvalidOperationException ($"Key {oldMouseFlags} is not bound.");
         }
 
-        MouseBinding value = Bindings [oldMouseEventArgs];
-        Remove (oldMouseEventArgs);
-        Add (newMouseEventArgs, value);
+        MouseBinding value = Bindings [oldMouseFlags];
+        Remove (oldMouseFlags);
+        Add (newMouseFlags, value);
     }
 
-    /// <summary>Gets the commands bound with the specified <see cref="MouseEventArgs"/>.</summary>
+    /// <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">
@@ -217,7 +217,7 @@ public class MouseBindings
     ///     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 (MouseEventArgs mouseEventArgs, out MouseBinding binding)
+    public bool TryGet (MouseFlags mouseEventArgs, out MouseBinding binding)
     {
         binding = new ([], mouseEventArgs);
 

+ 54 - 0
Terminal.Gui/Resources/Strings.Designer.cs

@@ -1437,6 +1437,42 @@ namespace Terminal.Gui.Resources {
             }
         }
         
+        /// <summary>
+        ///   Looks up a localized string similar to Copy Code_point.
+        /// </summary>
+        internal static string charMapCopyCP {
+            get {
+                return ResourceManager.GetString("charMapCopyCP", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Copy _Glyph.
+        /// </summary>
+        internal static string charMapCopyGlyph {
+            get {
+                return ResourceManager.GetString("charMapCopyGlyph", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Getting Codepoint Information.
+        /// </summary>
+        internal static string charMapCPInfoDlgTitle {
+            get {
+                return ResourceManager.GetString("charMapCPInfoDlgTitle", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Codepoint Information from.
+        /// </summary>
+        internal static string charMapInfoDlgInfoLabel {
+            get {
+                return ResourceManager.GetString("charMapInfoDlgInfoLabel", resourceCulture);
+            }
+        }
+        
         /// <summary>
         ///   Looks up a localized string similar to Co_lors.
         /// </summary>
@@ -1518,6 +1554,24 @@ namespace Terminal.Gui.Resources {
             }
         }
         
+        /// <summary>
+        ///   Looks up a localized string similar to Error.
+        /// </summary>
+        internal static string error {
+            get {
+                return ResourceManager.GetString("error", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to failed getting.
+        /// </summary>
+        internal static string failedGetting {
+            get {
+                return ResourceManager.GetString("failedGetting", resourceCulture);
+            }
+        }
+        
         /// <summary>
         ///   Looks up a localized string similar to Any Files.
         /// </summary>

+ 18 - 0
Terminal.Gui/Resources/Strings.resx

@@ -721,4 +721,22 @@
   <data name="ctxColors" xml:space="preserve">
     <value>Co_lors</value>
   </data>
+  <data name="charMapCPInfoDlgTitle" xml:space="preserve">
+    <value>Getting Codepoint Information</value>
+  </data>
+  <data name="charMapCopyGlyph" xml:space="preserve">
+    <value>Copy _Glyph</value>
+  </data>
+  <data name="charMapCopyCP" xml:space="preserve">
+    <value>Copy Code_point</value>
+  </data>
+  <data name="charMapInfoDlgInfoLabel" xml:space="preserve">
+    <value>Codepoint Information from</value>
+  </data>
+  <data name="error" xml:space="preserve">
+    <value>Error</value>
+  </data>
+  <data name="failedGetting" xml:space="preserve">
+    <value>failed getting</value>
+  </data>
 </root>

+ 2 - 0
Terminal.Gui/View/View.Command.cs

@@ -5,6 +5,8 @@ namespace Terminal.Gui;
 
 public partial class View // Command APIs
 {
+    private Dictionary<Command, CommandImplementation> CommandImplementations { get; } = new ();
+
     #region Default Implementation
 
     /// <summary>

+ 2 - 4
Terminal.Gui/View/View.Keyboard.cs

@@ -502,8 +502,6 @@ public partial class View // Keyboard APIs
     /// <summary>Gets the key bindings for this view.</summary>
     public KeyBindings KeyBindings { get; internal set; } = null!;
 
-    private Dictionary<Command, CommandImplementation> CommandImplementations { get; } = new ();
-
     /// <summary>
     ///     INTERNAL API: Invokes any commands bound to <paramref name="key"/> on this view, adornments, and subviews.
     /// </summary>
@@ -526,7 +524,7 @@ public partial class View // Keyboard APIs
         //   `InvokeKeyBindings` returns `false`. Continue passing the event (return `false` from `OnInvokeKeyBindings`)..
         // * If key bindings were found, and any handled the key (at least one `Command` returned `true`),
         //   `InvokeKeyBindings` returns `true`. Continue passing the event (return `false` from `OnInvokeKeyBindings`).
-        bool?  handled = InvokeCommands (key, scope);
+        bool?  handled = InvokeCommandsBoundToKey (key, scope);
 
         if (handled is true)
         {
@@ -681,7 +679,7 @@ public partial class View // Keyboard APIs
     ///     <see langword="true"/> if at least one command was invoked and handled (or cancelled); input processing should
     ///     stop.
     /// </returns>
-    protected bool? InvokeCommands (Key key, KeyBindingScope scope)
+    protected bool? InvokeCommandsBoundToKey (Key key, KeyBindingScope scope)
     {
         if (!KeyBindings.TryGet (key, scope, out KeyBinding binding))
         {

+ 176 - 74
Terminal.Gui/View/View.Mouse.cs

@@ -1,10 +1,46 @@
 #nullable enable
 using System.ComponentModel;
+using System.Diagnostics;
 
 namespace Terminal.Gui;
 
 public partial class View // Mouse APIs
 {
+    /// <summary>Gets the mouse bindings for this view.</summary>
+    public MouseBindings MouseBindings { get; internal set; } = null!;
+
+    private void SetupMouse ()
+    {
+        MouseBindings = new ();
+
+        MouseBindings.Add (MouseFlags.Button1Clicked, Command.Select);
+    }
+
+
+    /// <summary>
+    ///     Invokes the Commands bound to the MouseFlags specified by <paramref name="mouseEventArgs"/>.
+    ///     <para>See <see href="../docs/mouse.md">for an overview of Terminal.Gui mouse APIs.</see></para>
+    /// </summary>
+    /// <param name="mouseEventArgs">The mouse event passed.</param>
+    /// <returns>
+    ///     <see langword="null"/> if no command was invoked; input processing should continue.
+    ///     <see langword="false"/> if at least one command was invoked and was not handled (or cancelled); input processing
+    ///     should continue.
+    ///     <see langword="true"/> if at least one command was invoked and handled (or cancelled); input processing should
+    ///     stop.
+    /// </returns>
+    protected bool? InvokeCommandsBoundToMouse (MouseEventArgs mouseEventArgs)
+    {
+        if (!MouseBindings.TryGet (mouseEventArgs.Flags, out MouseBinding binding))
+        {
+            return null;
+        }
+
+        binding.MouseEventArgs = mouseEventArgs;
+
+        return InvokeCommands<MouseBinding> (binding.Commands, binding);
+    }
+
     #region MouseEnterLeave
 
     private bool _hovering;
@@ -269,14 +305,18 @@ public partial class View // Mouse APIs
             }
         }
 
+        // We get here if the view did not handle the mouse event via OnMouseEvent/MouseEvent and
+        // it did not handle the press/release/clicked events via HandlePress/HandleRelease/HandleClicked
         if (mouseEvent.IsSingleDoubleOrTripleClicked)
         {
-            // If it's a click, and we didn't handle it, then we need to generate a click event
-            // We get here if the view did not handle the mouse event via OnMouseEvent/MouseEvent and
-            // it did not handle the press/release/clicked events via HandlePress/HandleRelease/HandleClicked
             return RaiseMouseClickEvent (mouseEvent);
         }
 
+        if (mouseEvent.IsWheel)
+        {
+            return RaiseMouseWheelEvent (mouseEvent);
+        }
+
         return false;
     }
 
@@ -320,6 +360,96 @@ public partial class View // Mouse APIs
 
     #endregion Low Level Mouse Events
 
+    #region Mouse Pressed Events
+
+    /// <summary>
+    ///     INTERNAL For cases where the view is grabbed and the mouse is clicked, this method handles the released event (typically
+    ///     when <see cref="WantContinuousButtonPressed"/> or <see cref="HighlightStyle"/> are set).
+    /// </summary>
+    /// <remarks>
+    ///     Marked internal just to support unit tests
+    /// </remarks>
+    /// <param name="mouseEvent"></param>
+    /// <returns><see langword="true"/>, if the event was handled, <see langword="false"/> otherwise.</returns>
+    internal bool WhenGrabbedHandleReleased (MouseEventArgs mouseEvent)
+    {
+        mouseEvent.Handled = false;
+
+        if (mouseEvent.IsReleased)
+        {
+            if (Application.MouseGrabView == this)
+            {
+                SetPressedHighlight (HighlightStyle.None);
+            }
+
+            return mouseEvent.Handled = true;
+        }
+
+        return false;
+    }
+
+    /// <summary>
+    ///     INTERNAL For cases where the view is grabbed and the mouse is clicked, this method handles the released event (typically
+    ///     when <see cref="WantContinuousButtonPressed"/> or <see cref="HighlightStyle"/> are set).
+    /// </summary>
+    /// <remarks>
+    ///     <para>
+    ///         Marked internal just to support unit tests
+    ///     </para>
+    /// </remarks>
+    /// <param name="mouseEvent"></param>
+    /// <returns><see langword="true"/>, if the event was handled, <see langword="false"/> otherwise.</returns>
+    private bool WhenGrabbedHandlePressed (MouseEventArgs mouseEvent)
+    {
+        mouseEvent.Handled = false;
+
+        if (mouseEvent.IsPressed)
+        {
+            // The first time we get pressed event, grab the mouse and set focus
+            if (Application.MouseGrabView != this)
+            {
+                Application.GrabMouse (this);
+
+                if (!HasFocus && CanFocus)
+                {
+                    // Set the focus, but don't invoke Accept
+                    SetFocus ();
+                }
+
+                mouseEvent.Handled = true;
+            }
+
+            if (Viewport.Contains (mouseEvent.Position))
+            {
+                if (this is not Adornment
+                    && SetPressedHighlight (HighlightStyle.HasFlag (HighlightStyle.Pressed) ? HighlightStyle.Pressed : HighlightStyle.None))
+                {
+                    return true;
+                }
+            }
+            else
+            {
+                if (this is not Adornment
+                    && SetPressedHighlight (HighlightStyle.HasFlag (HighlightStyle.PressedOutside) ? HighlightStyle.PressedOutside : HighlightStyle.None))
+
+                {
+                    return true;
+                }
+            }
+
+            if (WantContinuousButtonPressed && Application.MouseGrabView == this)
+            {
+                return RaiseMouseClickEvent (mouseEvent);
+            }
+
+            return mouseEvent.Handled = true;
+        }
+
+        return false;
+    }
+
+    #endregion Mouse Pressed Events
+
     #region Mouse Click Events
 
     /// <summary>Raises the <see cref="OnMouseClick"/>/<see cref="MouseClick"/> event.</summary>
@@ -358,9 +488,8 @@ public partial class View // Mouse APIs
 
         // Post-conditions
 
-        // Always invoke Select command on MouseClick
         // By default, this will raise Selecting/OnSelecting - Subclasses can override this via AddCommand (Command.Select ...).
-        args.Handled = InvokeCommand<MouseBinding> (Command.Select, new ([Command.Select], args)) == true;
+        args.Handled = InvokeCommandsBoundToMouse (args) == true;
 
         return args.Handled;
     }
@@ -428,93 +557,61 @@ public partial class View // Mouse APIs
         return false;
     }
 
-    /// <summary>
-    ///     INTERNAL For cases where the view is grabbed and the mouse is clicked, this method handles the released event (typically
-    ///     when <see cref="WantContinuousButtonPressed"/> or <see cref="HighlightStyle"/> are set).
-    /// </summary>
-    /// <remarks>
-    ///     Marked internal just to support unit tests
-    /// </remarks>
-    /// <param name="mouseEvent"></param>
-    /// <returns><see langword="true"/>, if the event was handled, <see langword="false"/> otherwise.</returns>
-    internal bool WhenGrabbedHandleReleased (MouseEventArgs mouseEvent)
-    {
-        mouseEvent.Handled = false;
 
-        if (mouseEvent.IsReleased)
-        {
-            if (Application.MouseGrabView == this)
-            {
-                SetPressedHighlight (HighlightStyle.None);
-            }
+    #endregion Mouse Clicked Events
 
-            return mouseEvent.Handled = true;
-        }
 
-        return false;
-    }
+    #region Mouse Wheel Events
 
-    /// <summary>
-    ///     INTERNAL For cases where the view is grabbed and the mouse is clicked, this method handles the released event (typically
-    ///     when <see cref="WantContinuousButtonPressed"/> or <see cref="HighlightStyle"/> are set).
-    /// </summary>
+    /// <summary>Raises the <see cref="OnMouseWheel"/>/<see cref="MouseWheel"/> event.</summary>
     /// <remarks>
-    ///     <para>
-    ///         Marked internal just to support unit tests
-    ///     </para>
     /// </remarks>
-    /// <param name="mouseEvent"></param>
     /// <returns><see langword="true"/>, if the event was handled, <see langword="false"/> otherwise.</returns>
-    private bool WhenGrabbedHandlePressed (MouseEventArgs mouseEvent)
+    protected bool RaiseMouseWheelEvent (MouseEventArgs args)
     {
-        mouseEvent.Handled = false;
-
-        if (mouseEvent.IsPressed)
+        // Pre-conditions
+        if (!Enabled)
         {
-            // The first time we get pressed event, grab the mouse and set focus
-            if (Application.MouseGrabView != this)
-            {
-                Application.GrabMouse (this);
+            // QUESTION: Is this right? Should a disabled view eat mouse?
+            return args.Handled = false;
+        }
 
-                if (!HasFocus && CanFocus)
-                {
-                    // Set the focus, but don't invoke Accept
-                    SetFocus ();
-                }
+        // Cancellable event
 
-                mouseEvent.Handled = true;
-            }
+        if (OnMouseWheel (args) || args.Handled)
+        {
+            return args.Handled;
+        }
 
-            if (Viewport.Contains (mouseEvent.Position))
-            {
-                if (this is not Adornment
-                    && SetPressedHighlight (HighlightStyle.HasFlag (HighlightStyle.Pressed) ? HighlightStyle.Pressed : HighlightStyle.None))
-                {
-                    return true;
-                }
-            }
-            else
-            {
-                if (this is not Adornment
-                    && SetPressedHighlight (HighlightStyle.HasFlag (HighlightStyle.PressedOutside) ? HighlightStyle.PressedOutside : HighlightStyle.None))
+        MouseWheel?.Invoke (this, args);
 
-                {
-                    return true;
-                }
-            }
+        if (args.Handled)
+        {
+            return true;
+        }
 
-            if (WantContinuousButtonPressed && Application.MouseGrabView == this)
-            {
-                return RaiseMouseClickEvent (mouseEvent);
-            }
+        // Post-conditions
 
-            return mouseEvent.Handled = true;
-        }
+        args.Handled = InvokeCommandsBoundToMouse (args) == true;
 
-        return false;
+        return args.Handled;
     }
 
-    #endregion Mouse Click Events
+    /// <summary>
+    ///     Called when a mouse wheel event occurs. Check <see cref="MouseEventArgs.Flags"/> to see which wheel was moved was clicked.
+    /// </summary>
+    /// <remarks>
+    /// </remarks>
+    /// <param name="args"></param>
+    /// <returns><see langword="true"/>, if the event was handled, <see langword="false"/> otherwise.</returns>
+    protected virtual bool OnMouseWheel (MouseEventArgs args) { return false; }
+
+    /// <summary>Raised when a mouse wheel event occurs.</summary>
+    /// <remarks>
+    /// </remarks>
+    public event EventHandler<MouseEventArgs>? MouseWheel;
+
+    #endregion Mouse Wheel Events
 
     #region Highlight Handling
 
@@ -720,4 +817,9 @@ public partial class View // Mouse APIs
 
         return viewsUnderMouse;
     }
+
+    private void DisposeMouse ()
+    {
+
+    }
 }

+ 2 - 1
Terminal.Gui/View/View.cs

@@ -147,7 +147,7 @@ public partial class View : IDisposable, ISupportInitializeNotification
 
         SetupKeyboard ();
 
-        //SetupMouse ();
+        SetupMouse ();
 
         SetupText ();
 
@@ -550,6 +550,7 @@ public partial class View : IDisposable, ISupportInitializeNotification
     {
         LineCanvas.Dispose ();
 
+        DisposeMouse ();
         DisposeKeyboard ();
         DisposeAdornments ();
         DisposeScrollBars ();

+ 147 - 189
UICatalog/Scenarios/CharacterMap/CharMap.cs → Terminal.Gui/Views/CharMap/CharMap.cs

@@ -1,13 +1,10 @@
 #nullable enable
-using System;
+using System.Diagnostics.CodeAnalysis;
 using System.Globalization;
-using System.Linq;
-using System.Net.Http;
-using System.Text;
 using System.Text.Json;
-using Terminal.Gui;
+using Terminal.Gui.Resources;
 
-namespace UICatalog.Scenarios;
+namespace Terminal.Gui;
 
 /// <summary>
 ///     A scrollable map of the Unicode codepoints.
@@ -32,97 +29,24 @@ public class CharMap : View, IDesignable
         CanFocus = true;
         CursorVisibility = CursorVisibility.Default;
 
-        AddCommand (
-                    Command.Up,
-                    () =>
-                    {
-                        SelectedCodePoint -= 16;
-
-                        return true;
-                    }
-                   );
-
-        AddCommand (
-                    Command.Down,
-                    () =>
-                    {
-                        SelectedCodePoint += 16;
-
-                        return true;
-                    }
-                   );
-
-        AddCommand (
-                    Command.Left,
-                    () =>
-                    {
-                        SelectedCodePoint--;
+        AddCommand (Command.Up, commandContext => Move (commandContext, -16));
+        AddCommand (Command.Down, commandContext => Move (commandContext, 16));
+        AddCommand (Command.Left, commandContext => Move (commandContext, -1));
+        AddCommand (Command.Right, commandContext => Move (commandContext, 1));
 
-                        return true;
-                    }
-                   );
+        AddCommand (Command.PageUp, commandContext => Move (commandContext, -(Viewport.Height - HEADER_HEIGHT / _rowHeight) * 16));
+        AddCommand (Command.PageDown, commandContext => Move (commandContext, (Viewport.Height - HEADER_HEIGHT / _rowHeight) * 16));
+        AddCommand (Command.Start, commandContext => Move (commandContext, -SelectedCodePoint));
+        AddCommand (Command.End, commandContext => Move (commandContext, MAX_CODE_POINT - SelectedCodePoint));
 
-        AddCommand (
-                    Command.Right,
-                    () =>
-                    {
-                        SelectedCodePoint++;
+        AddCommand (Command.ScrollDown, () => ScrollVertical (1));
+        AddCommand (Command.ScrollUp, () => ScrollVertical (-1));
+        AddCommand (Command.ScrollRight, () => ScrollHorizontal (1));
+        AddCommand (Command.ScrollLeft, () => ScrollHorizontal (-1));
 
-                        return true;
-                    }
-                   );
-
-        AddCommand (
-                    Command.PageUp,
-                    () =>
-                    {
-                        int page = (Viewport.Height - HEADER_HEIGHT / _rowHeight) * 16;
-                        SelectedCodePoint -= page;
-
-                        return true;
-                    }
-                   );
-
-        AddCommand (
-                    Command.PageDown,
-                    () =>
-                    {
-                        int page = (Viewport.Height - HEADER_HEIGHT / _rowHeight) * 16;
-                        SelectedCodePoint += page;
-
-                        return true;
-                    }
-                   );
-
-        AddCommand (
-                    Command.Start,
-                    () =>
-                    {
-                        SelectedCodePoint = 0;
-
-                        return true;
-                    }
-                   );
-
-        AddCommand (
-                    Command.End,
-                    () =>
-                    {
-                        SelectedCodePoint = MAX_CODE_POINT;
-
-                        return true;
-                    }
-                   );
-
-        AddCommand (
-                    Command.Accept,
-                    () =>
-                    {
-                        ShowDetails ();
-
-                        return true;
-                    }
-                   );
+        AddCommand (Command.Accept, HandleAcceptCommand);
+        AddCommand (Command.Select, HandleSelectCommand);
+        AddCommand (Command.Context, HandleContextCommand);
 
         KeyBindings.Add (Key.CursorUp, Command.Up);
         KeyBindings.Add (Key.CursorDown, Command.Down);
@@ -132,8 +56,14 @@ public class CharMap : View, IDesignable
         KeyBindings.Add (Key.PageDown, Command.PageDown);
         KeyBindings.Add (Key.Home, Command.Start);
         KeyBindings.Add (Key.End, Command.End);
+        KeyBindings.Add (ContextMenu.DefaultKey, Command.Context);
 
-        MouseClick += Handle_MouseClick;
+        MouseBindings.Add (MouseFlags.Button1DoubleClicked, Command.Accept);
+        MouseBindings.Add (MouseFlags.Button3Clicked, Command.Context);
+        MouseBindings.Add (MouseFlags.WheeledDown, Command.ScrollDown);
+        MouseBindings.Add (MouseFlags.WheeledUp, Command.ScrollUp);
+        MouseBindings.Add (MouseFlags.WheeledLeft, Command.ScrollLeft);
+        MouseBindings.Add (MouseFlags.WheeledRight, Command.ScrollRight);
 
         SetContentSize (new (COLUMN_WIDTH * 16 + RowLabelWidth, MAX_CODE_POINT / 16 * _rowHeight + HEADER_HEIGHT));
 
@@ -169,6 +99,18 @@ public class CharMap : View, IDesignable
         VerticalScrollBar.Y = HEADER_HEIGHT; // Header
     }
 
+    private bool? Move (ICommandContext? commandContext, int cpOffset)
+    {
+        if (RaiseSelecting (commandContext) is true)
+        {
+            return true;
+        }
+
+        SelectedCodePoint += cpOffset;
+
+        return true;
+    }
+
     private void ScrollToMakeCursorVisible (Point offsetToNewCursor)
     {
         // Adjust vertical scrolling
@@ -203,6 +145,7 @@ public class CharMap : View, IDesignable
         return new (x, y);
     }
 
+    /// <inheritdoc/>
     public override Point? PositionCursor ()
     {
         Point cursor = GetCursor (SelectedCodePoint);
@@ -297,6 +240,7 @@ public class CharMap : View, IDesignable
 
     private static int RowLabelWidth => $"U+{MAX_CODE_POINT:x5}".Length + 1;
 
+    /// <inheritdoc/>
     protected override bool OnDrawingContent ()
     {
         if (Viewport.Height == 0 || Viewport.Width == 0)
@@ -465,79 +409,91 @@ public class CharMap : View, IDesignable
     #region Mouse Handling
 
     // TODO: Use this to demonstrate using a popover to show glyph info on hover
-    public event EventHandler<ListViewItemEventArgs>? Hover;
+    // public event EventHandler<ListViewItemEventArgs>? Hover;
 
-    /// <inheritdoc />
-    protected override bool OnMouseEvent (MouseEventArgs mouseEvent)
+    private bool? HandleSelectCommand (ICommandContext? commandContext)
     {
-        if (mouseEvent.Flags == MouseFlags.WheeledDown)
+        Point position = GetCursor (SelectedCodePoint);
+
+        if (commandContext is CommandContext<MouseBinding> { Binding.MouseEventArgs: { } } mouseCommandContext)
         {
-            if (Viewport.Y + Viewport.Height - HEADER_HEIGHT < GetContentSize ().Height)
+            // If the mouse is clicked on the headers, map it to the first glyph of the row/col
+            position = mouseCommandContext.Binding.MouseEventArgs.Position;
+
+            if (position.Y == 0)
             {
-                ScrollVertical (1);
+                position = position with { Y = GetCursor (SelectedCodePoint).Y };
+            }
+
+            if (position.X < RowLabelWidth || position.X > RowLabelWidth + 16 * COLUMN_WIDTH - 1)
+            {
+                position = position with { X = GetCursor (SelectedCodePoint).X };
             }
-            return mouseEvent.Handled = true;
         }
 
-        if (mouseEvent.Flags == MouseFlags.WheeledUp)
+        if (RaiseSelecting (commandContext) is true)
         {
-            ScrollVertical (-1);
-            return mouseEvent.Handled = true;
+            return true;
         }
 
-        if (mouseEvent.Flags == MouseFlags.WheeledRight)
+        if (!TryGetCodePointFromPosition (position, out int cp))
         {
-            if (Viewport.X + Viewport.Width < GetContentSize ().Width)
-            {
-                ScrollHorizontal (1);
-            }
-            return mouseEvent.Handled = true;
+            return false;
         }
 
-        if (mouseEvent.Flags == MouseFlags.WheeledLeft)
+        if (cp != SelectedCodePoint)
         {
-            ScrollHorizontal (-1);
-            return mouseEvent.Handled = true;
+            if (!HasFocus && CanFocus)
+            {
+                SetFocus ();
+            }
+
+            SelectedCodePoint = cp;
         }
 
-        return false;
+        return true;
     }
 
-    private void Handle_MouseClick (object? sender, MouseEventArgs me)
-    {
-        if (me.Flags != MouseFlags.ReportMousePosition && me.Flags != MouseFlags.Button1Clicked && me.Flags != MouseFlags.Button1DoubleClicked)
-        {
-            return;
-        }
+    [RequiresUnreferencedCode ("AOT")]
+    [RequiresDynamicCode ("AOT")]
 
-        if (me.Position.Y == 0)
+    private bool? HandleAcceptCommand (ICommandContext? commandContext)
+    {
+        if (RaiseAccepting (commandContext) is true)
         {
-            me.Position = me.Position with { Y = GetCursor (SelectedCodePoint).Y };
+            return true;
         }
 
-        if (me.Position.X < RowLabelWidth || me.Position.X > RowLabelWidth + 16 * COLUMN_WIDTH - 1)
+        if (commandContext is CommandContext<MouseBinding> { Binding.MouseEventArgs: { } } mouseCommandContext)
         {
-            me.Position = me.Position with { X = GetCursor (SelectedCodePoint).X };
-        }
+            if (!HasFocus && CanFocus)
+            {
+                SetFocus ();
+            }
 
-        int row = (me.Position.Y - 1 - -Viewport.Y) / _rowHeight; // -1 for header
-        int col = (me.Position.X - RowLabelWidth - -Viewport.X) / COLUMN_WIDTH;
+            if (!TryGetCodePointFromPosition (mouseCommandContext.Binding.MouseEventArgs.Position, out int cp))
+            {
+                return false;
+            }
 
-        if (col > 15)
-        {
-            col = 15;
+            SelectedCodePoint = cp;
         }
 
-        int val = row * 16 + col;
+        ShowDetails ();
 
-        if (val > MAX_CODE_POINT)
-        {
-            return;
-        }
+        return true;
+    }
 
-        if (me.Flags == MouseFlags.ReportMousePosition)
+    private bool? HandleContextCommand (ICommandContext? commandContext)
+    {
+        int newCodePoint = SelectedCodePoint;
+
+        if (commandContext is CommandContext<MouseBinding> { Binding.MouseEventArgs: { } } mouseCommandContext)
         {
-            Hover?.Invoke (this, new (val, null));
+            if (!TryGetCodePointFromPosition (mouseCommandContext.Binding.MouseEventArgs.Position, out newCodePoint))
+            {
+                return false;
+            }
         }
 
         if (!HasFocus && CanFocus)
@@ -545,62 +501,64 @@ public class CharMap : View, IDesignable
             SetFocus ();
         }
 
-        me.Handled = true;
+        SelectedCodePoint = newCodePoint;
 
-        if (me.Flags == MouseFlags.Button1Clicked)
+        _contextMenu = new ()
         {
-            SelectedCodePoint = val;
+            Position = ViewportToScreen (GetCursor (SelectedCodePoint))
+        };
 
-            return;
-        }
+        MenuBarItem menuItems = new (
+                                     [
+                                         new (
+                                              Strings.charMapCopyGlyph,
+                                              "",
+                                              CopyGlyph,
+                                              null,
+                                              null,
+                                              (KeyCode)Key.G.WithCtrl
+                                             ),
+                                         new (
+                                              Strings.charMapCopyCP,
+                                              "",
+                                              CopyCodePoint,
+                                              null,
+                                              null,
+                                              (KeyCode)Key.P.WithCtrl
+                                             )
+                                     ]
+                                    );
+        _contextMenu.Show (menuItems);
 
-        if (me.Flags == MouseFlags.Button1DoubleClicked)
-        {
-            SelectedCodePoint = val;
-            ShowDetails ();
+        return true;
+    }
 
-            return;
-        }
+    private bool TryGetCodePointFromPosition (Point position, out int codePoint)
+    {
+        int row = (position.Y - 1 - -Viewport.Y) / _rowHeight; // -1 for header
+        int col = (position.X - RowLabelWidth - -Viewport.X) / COLUMN_WIDTH;
 
-        if (me.Flags == _contextMenu.MouseFlags)
+        if (col > 15)
         {
-            SelectedCodePoint = val;
+            col = 15;
+        }
 
-            _contextMenu = new ()
-            {
-                Position = new (me.Position.X + 1, me.Position.Y + 1)
-            };
+        codePoint = row * 16 + col;
 
-            MenuBarItem menuItems = new (
-                                         new MenuItem []
-                                         {
-                                             new (
-                                                  "_Copy Glyph",
-                                                  "",
-                                                  CopyGlyph,
-                                                  null,
-                                                  null,
-                                                  (KeyCode)Key.C.WithCtrl
-                                                 ),
-                                             new (
-                                                  "Copy Code _Point",
-                                                  "",
-                                                  CopyCodePoint,
-                                                  null,
-                                                  null,
-                                                  (KeyCode)Key.C.WithCtrl
-                                                              .WithShift
-                                                 )
-                                         }
-                                        );
-            _contextMenu.Show (menuItems);
+        if (codePoint > MAX_CODE_POINT)
+        {
+            return false;
         }
+
+        return true;
     }
 
     #endregion Mouse Handling
 
     #region Details Dialog
 
+    [RequiresUnreferencedCode ("AOT")]
+    [RequiresDynamicCode ("AOT")]
     private void ShowDetails ()
     {
         UcdApiClient? client = new ();
@@ -609,12 +567,12 @@ public class CharMap : View, IDesignable
 
         Dialog? waitIndicator = new ()
         {
-            Title = "Getting Code Point Information",
+            Title = Strings.charMapCPInfoDlgTitle,
             X = Pos.Center (),
             Y = Pos.Center (),
             Width = 40,
             Height = 10,
-            Buttons = [new () { Text = "_Cancel" }]
+            Buttons = [new () { Text = Strings.btnCancel }]
         };
 
         var errorLabel = new Label
@@ -641,7 +599,7 @@ public class CharMap : View, IDesignable
                                {
                                    try
                                    {
-                                       decResponse = await client.GetCodepointDec (SelectedCodePoint);
+                                       decResponse = await client.GetCodepointDec (SelectedCodePoint).ConfigureAwait (false);
                                        Application.Invoke (() => waitIndicator.RequestStop ());
                                    }
                                    catch (HttpRequestException e)
@@ -676,15 +634,15 @@ public class CharMap : View, IDesignable
                                                         document.RootElement,
                                                         new
                                                             JsonSerializerOptions
-                                                        { WriteIndented = true }
+                                                            { WriteIndented = true }
                                                        );
             }
 
             var title = $"{ToCamelCase (name!)} - {new Rune (SelectedCodePoint)} U+{SelectedCodePoint:x5}";
 
-            Button? copyGlyph = new () { Text = "Copy _Glyph" };
-            Button? copyCodepoint = new () { Text = "Copy Code _Point" };
-            Button? cancel = new () { Text = "Cancel" };
+            Button? copyGlyph = new () { Text = Strings.charMapCopyGlyph };
+            Button? copyCodepoint = new () { Text = Strings.charMapCopyCP };
+            Button? cancel = new () { Text = Strings.btnCancel };
 
             var dlg = new Dialog { Title = title, Buttons = [copyGlyph, copyCodepoint, cancel] };
 
@@ -747,7 +705,7 @@ public class CharMap : View, IDesignable
             label = new ()
             {
                 Text =
-                    $"Code Point Information from {UcdApiClient.BaseUrl}codepoint/dec/{SelectedCodePoint}:",
+                    $"{Strings.charMapInfoDlgInfoLabel} {UcdApiClient.BaseUrl}codepoint/dec/{SelectedCodePoint}:",
                 X = 0,
                 Y = Pos.Bottom (label)
             };
@@ -771,9 +729,9 @@ public class CharMap : View, IDesignable
         else
         {
             MessageBox.ErrorQuery (
-                                   "Code Point API",
-                                   $"{UcdApiClient.BaseUrl}codepoint/dec/{SelectedCodePoint} did not return a result for\r\n {new Rune (SelectedCodePoint)} U+{SelectedCodePoint:x5}.",
-                                   "_Ok"
+                                   Strings.error,
+                                   $"{UcdApiClient.BaseUrl}codepoint/dec/{SelectedCodePoint} {Strings.failedGetting}{Environment.NewLine}{new Rune (SelectedCodePoint)} U+{SelectedCodePoint:x5}.",
+                                   Strings.btnOk
                                   );
         }
 

+ 10 - 14
UICatalog/Scenarios/CharacterMap/UcdApiClient.cs → Terminal.Gui/Views/CharMap/UcdApiClient.cs

@@ -1,48 +1,44 @@
 #nullable enable
-using System;
-using System.Net.Http;
-using System.Threading.Tasks;
-
-namespace UICatalog.Scenarios;
+namespace Terminal.Gui;
 
 /// <summary>
 ///     A helper class for accessing the ucdapi.org API.
 /// </summary>
-public class UcdApiClient
+internal class UcdApiClient
 {
     public const string BaseUrl = "https://ucdapi.org/unicode/latest/";
     private static readonly HttpClient _httpClient = new ();
 
     public async Task<string> GetChars (string chars)
     {
-        HttpResponseMessage response = await _httpClient.GetAsync ($"{BaseUrl}chars/{Uri.EscapeDataString (chars)}");
+        HttpResponseMessage response = await _httpClient.GetAsync ($"{BaseUrl}chars/{Uri.EscapeDataString (chars)}").ConfigureAwait (false);
         response.EnsureSuccessStatusCode ();
 
-        return await response.Content.ReadAsStringAsync ();
+        return await response.Content.ReadAsStringAsync ().ConfigureAwait (false);
     }
 
     public async Task<string> GetCharsName (string chars)
     {
         HttpResponseMessage response =
-            await _httpClient.GetAsync ($"{BaseUrl}chars/{Uri.EscapeDataString (chars)}/name");
+            await _httpClient.GetAsync ($"{BaseUrl}chars/{Uri.EscapeDataString (chars)}/name").ConfigureAwait (false);
         response.EnsureSuccessStatusCode ();
 
-        return await response.Content.ReadAsStringAsync ();
+        return await response.Content.ReadAsStringAsync ().ConfigureAwait (false);
     }
 
     public async Task<string> GetCodepointDec (int dec)
     {
-        HttpResponseMessage response = await _httpClient.GetAsync ($"{BaseUrl}codepoint/dec/{dec}");
+        HttpResponseMessage response = await _httpClient.GetAsync ($"{BaseUrl}codepoint/dec/{dec}").ConfigureAwait (false);
         response.EnsureSuccessStatusCode ();
 
-        return await response.Content.ReadAsStringAsync ();
+        return await response.Content.ReadAsStringAsync ().ConfigureAwait (false);
     }
 
     public async Task<string> GetCodepointHex (string hex)
     {
-        HttpResponseMessage response = await _httpClient.GetAsync ($"{BaseUrl}codepoint/hex/{hex}");
+        HttpResponseMessage response = await _httpClient.GetAsync ($"{BaseUrl}codepoint/hex/{hex}").ConfigureAwait (false);
         response.EnsureSuccessStatusCode ();
 
-        return await response.Content.ReadAsStringAsync ();
+        return await response.Content.ReadAsStringAsync ().ConfigureAwait (false);
     }
 }

+ 1 - 3
UICatalog/Scenarios/CharacterMap/UnicodeRange.cs → Terminal.Gui/Views/CharMap/UnicodeRange.cs

@@ -1,10 +1,8 @@
 #nullable enable
-using System.Collections.Generic;
-using System.Linq;
 using System.Reflection;
 using System.Text.Unicode;
 
-namespace UICatalog.Scenarios;
+namespace Terminal.Gui;
 
 /// <summary>
 ///     Represents all of the Uniicode ranges.from System.Text.Unicode.UnicodeRange plus

+ 1 - 1
Terminal.Gui/Views/ColorPicker.16.cs

@@ -133,7 +133,7 @@ public class ColorPicker16 : View
     ///<inheritdoc/>
     protected override bool OnDrawingContent ()
     {
-        SetAttribute (HasFocus ? ColorScheme.Focus : GetNormalColor ());
+        SetAttribute (HasFocus ? GetFocusColor () : GetNormalColor ());
         var colorIndex = 0;
 
         for (var y = 0; y < Math.Max (2, Viewport.Height / BoxHeight); y++)

+ 4 - 2
Terminal.Gui/Views/ColorPicker.Prompt.cs

@@ -1,4 +1,6 @@
-namespace Terminal.Gui;
+using Terminal.Gui.Resources;
+
+namespace Terminal.Gui;
 
 public partial class ColorPicker
 {
@@ -42,7 +44,7 @@ public partial class ColorPicker
         {
             X = Pos.Center () + 5,
             Y = 4,
-            Text = "Cancel",
+            Text = Strings.btnCancel,
             Width = Dim.Auto ()
         };
 

+ 1 - 1
Terminal.Gui/Views/TextField.cs

@@ -402,7 +402,7 @@ public class TextField : View
         ContextMenu = new () { Host = this };
         ContextMenu.KeyChanged += ContextMenu_KeyChanged;
 
-        KeyBindings.Add (ContextMenu.Key, KeyBindingScope.HotKey, Command.Context);
+        KeyBindings.Add (ContextMenu.Key, Command.Context);
 
         KeyBindings.Remove (Key.Space);
     }

+ 1 - 1
Terminal.Gui/Views/TextView.cs

@@ -2413,7 +2413,7 @@ public class TextView : View
         ContextMenu = new ();
         ContextMenu.KeyChanged += ContextMenu_KeyChanged!;
 
-        KeyBindings.Add ((KeyCode)ContextMenu.Key, KeyBindingScope.HotKey, Command.Context);
+        KeyBindings.Add (ContextMenu.Key, Command.Context);
     }
 
     private void TextView_Added1 (object? sender, SuperViewChangedEventArgs e) { throw new NotImplementedException (); }

+ 1 - 1
UICatalog/Scenario.cs

@@ -219,7 +219,7 @@ public class Scenario : IDisposable
     private void OnApplicationOnIteration (object? s, IterationEventArgs a)
     {
         BenchmarkResults.IterationCount++;
-        if (BenchmarkResults.IterationCount > BENCHMARK_MAX_NATURAL_ITERATIONS + (_demoKeys.Count * BENCHMARK_KEY_PACING))
+        if (BenchmarkResults.IterationCount > BENCHMARK_MAX_NATURAL_ITERATIONS + (_demoKeys!.Count * BENCHMARK_KEY_PACING))
         {
             Application.RequestStop ();
         }

+ 23 - 41
UICatalog/Scenarios/Editors/EventLog.cs

@@ -1,8 +1,6 @@
 #nullable enable
 using System;
 using System.Collections.ObjectModel;
-using System.Diagnostics.Tracing;
-using System.Text;
 using Terminal.Gui;
 
 namespace UICatalog.Scenarios;
@@ -22,12 +20,15 @@ public class EventLog : ListView
 
         X = Pos.AnchorEnd ();
         Y = 0;
-        Width = Dim.Func (() =>
+
+        Width = Dim.Func (
+                          () =>
                           {
                               if (!IsInitialized)
                               {
                                   return 0;
                               }
+
                               return Math.Min (SuperView!.Viewport.Width / 3, MaxLength + GetAdornmentsThickness ().Horizontal);
                           });
         Height = Dim.Fill ();
@@ -42,17 +43,18 @@ public class EventLog : ListView
         HorizontalScrollBar.AutoShow = true;
         VerticalScrollBar.AutoShow = true;
 
-        AddCommand (Command.DeleteAll,
-                   () =>
-                   {
-                       _eventSource.Clear ();
+        AddCommand (
+                    Command.DeleteAll,
+                    () =>
+                    {
+                        _eventSource.Clear ();
 
-                       return true;
-                   });
+                        return true;
+                    });
 
         KeyBindings.Add (Key.Delete, Command.DeleteAll);
-
     }
+
     public ExpanderButton? ExpandButton { get; }
 
     private readonly ObservableCollection<string> _eventSource = [];
@@ -74,37 +76,16 @@ public class EventLog : ListView
             if (_viewToLog is { })
             {
                 _viewToLog.Initialized += (s, args) =>
-                                             {
-                                                 View? sender = s as View;
-                                                 Log ($"Initialized: {GetIdentifyingString (sender)}");
-                                             };
-
-                _viewToLog.MouseClick += (s, args) =>
-                {
-                    Log ($"MouseClick: {args}");
-                };
-
-                _viewToLog.HandlingHotKey += (s, args) =>
-                                        {
-                                            if (args.Context is CommandContext<KeyBinding> keyCommandContext)
-                                            {
-                                                Log ($"HandlingHotKey: {args.Context.Command} {keyCommandContext.Binding.Data}");
-                                            }
-                                        };
-                _viewToLog.Selecting += (s, args) =>
-                                        {
-                                            if (args.Context is CommandContext<KeyBinding> keyCommandContext)
-                                            {
-                                                Log ($"Selecting: {args.Context.Command} {keyCommandContext.Binding.Data}");
-                                            }
-                                        };
-                _viewToLog.Accepting += (s, args) =>
-                                        {
-                                            if (args.Context is CommandContext<KeyBinding> keyCommandContext)
-                                            {
-                                                Log ($"Accepting: {args.Context.Command} {keyCommandContext.Binding.Data}");
-                                            }
-                                        };
+                                          {
+                                              var sender = s as View;
+                                              Log ($"Initialized: {GetIdentifyingString (sender)}");
+                                          };
+
+                _viewToLog.MouseClick += (s, args) => { Log ($"MouseClick: {args}"); };
+                _viewToLog.MouseWheel += (s, args) => { Log ($"MouseWheel: {args}"); };
+                _viewToLog.HandlingHotKey += (s, args) => { Log ($"HandlingHotKey: {args.Context}"); };
+                _viewToLog.Selecting += (s, args) => { Log ($"Selecting: {args.Context}"); };
+                _viewToLog.Accepting += (s, args) => { Log ($"Accepting: {args.Context}"); };
             }
         }
     }
@@ -120,6 +101,7 @@ public class EventLog : ListView
         Border?.Add (ExpandButton!);
         Source = new ListWrapper<string> (_eventSource);
     }
+
     private string GetIdentifyingString (View? view)
     {
         if (view is null)

+ 2 - 2
UICatalog/Scenarios/TableEditor.cs

@@ -65,8 +65,8 @@ public class TableEditor : Scenario
              "Cuneiform Numbers and Punctuation"
             ),
         new (
-             (uint)(UICatalog.Scenarios.UnicodeRange.Ranges.Max (r => r.End) - 16),
-             (uint)UICatalog.Scenarios.UnicodeRange.Ranges.Max (r => r.End),
+             (uint)(Terminal.Gui.UnicodeRange.Ranges.Max (r => r.End) - 16),
+             (uint)Terminal.Gui.UnicodeRange.Ranges.Max (r => r.End),
              "End"
             ),
         new (0x0020, 0x007F, "Basic Latin"),