Terminal.Gui icon indicating copy to clipboard operation
Terminal.Gui copied to clipboard

Mouse API makes it way too hard to track button pressed

Open tig opened this issue 1 year ago • 22 comments

To illustrate what I think is wrong with the current Terminal.Gui (and v1) API in this regard, consider this class.

    public class MouseDemo : View
    {
        public MouseDemo ()
        {
            CanFocus = true;
            MouseEvent += (s, e) =>
                          {
                              if (e.MouseEvent.Flags.HasFlag (MouseFlags.Button1Pressed))
                              {
                                  ColorScheme = Colors.ColorSchemes ["Toplevel"];
                              }
                              if (e.MouseEvent.Flags.HasFlag (MouseFlags.Button1Released))
                              {
                                  ColorScheme = Colors.ColorSchemes ["Dialog"];
                              }
                          };
            MouseLeave += (s, e) => { ColorScheme = Colors.ColorSchemes ["Dialog"]; };
        }
    }

I want this view to show the "TopLevel" colorscheme while button1 is pressed; when button1 is released, or the mouse leaves the view, the color should go back to "Dialog".

Here's how it behaves now. Note that if I press button1 outside of the view and drag into the view, the color changes to "Toplevel". This is not what I want. The current API provides me no way of knowing that the Button1Pressed flag was set while the mouse was outsdie of my view.

5DhZHvn 1

Now, I can work around this like this, but this is awful.

    public class MouseDemo : View
    {
        private bool _button1PressedOnEnter = false;
        public MouseDemo ()
        {
            CanFocus = true;
            MouseEvent += (s, e) =>
                          {
                              if (e.MouseEvent.Flags.HasFlag (MouseFlags.Button1Pressed))
                              {
                                  if (!_button1PressedOnEnter)
                                  {
                                      ColorScheme = Colors.ColorSchemes ["Toplevel"];
                                  }
                              }
                              if (e.MouseEvent.Flags.HasFlag (MouseFlags.Button1Released))
                              {
                                  ColorScheme = Colors.ColorSchemes ["Dialog"];
                                  _button1PressedOnEnter = false;
                              }
                          };
            MouseLeave += (s, e) =>
                          {
                              ColorScheme = Colors.ColorSchemes ["Dialog"];
                              _button1PressedOnEnter = false;
                          };
            MouseEnter += (s, e) =>
                          {
                              _button1PressedOnEnter = e.MouseEvent.Flags.HasFlag (MouseFlags.Button1Pressed);
                          };
        }
    }

FWIW, the impact of this behavior can be seen (in v1 and v2) in theWindows & FrameViews scenario.

Press button1 while in the Bounds of 1 - Windows Loop... and drag up.

ENpcvt9 1

I think there should be a View.MouseButton1Pressed and View.MouseButton1Released event.

Originally posted by @tig in https://github.com/gui-cs/Terminal.Gui/discussions/3290#discussioncomment-8672790

tig avatar Mar 11 '24 16:03 tig