From c310716fcdfffd2df8bee59cf9b4e68c68078b83 Mon Sep 17 00:00:00 2001 From: BDisp Date: Wed, 29 Apr 2020 16:08:25 +0100 Subject: [PATCH] Faster handling of the mouse in ScrollView with the addition of an uninterrupted click on the mouse features. Changed the Wakeup method to reset the events to update the screen. (#409) --- Terminal.Gui/Drivers/WindowsDriver.cs | 27 ++++++++++++++++++- Terminal.Gui/Views/ScrollView.cs | 39 +++++++++++++++++++-------- 2 files changed, 54 insertions(+), 12 deletions(-) diff --git a/Terminal.Gui/Drivers/WindowsDriver.cs b/Terminal.Gui/Drivers/WindowsDriver.cs index c884868df..44c865c0e 100644 --- a/Terminal.Gui/Drivers/WindowsDriver.cs +++ b/Terminal.Gui/Drivers/WindowsDriver.cs @@ -499,7 +499,9 @@ namespace Terminal.Gui { void IMainLoopDriver.Wakeup () { - tokenSource.Cancel (); + //tokenSource.Cancel (); + eventReady.Reset (); + eventReady.Set (); } bool IMainLoopDriver.EventsPending (bool wait) @@ -610,6 +612,7 @@ namespace Terminal.Gui { } WindowsConsole.ButtonState? LastMouseButtonPressed = null; + bool IsButtonPressed = false; bool IsButtonReleased = false; bool IsButtonDoubleClicked = false; Point point; @@ -632,6 +635,7 @@ namespace Terminal.Gui { // map to the correct clicked event. if ((LastMouseButtonPressed != null || IsButtonReleased) && mouseEvent.ButtonState != 0) { LastMouseButtonPressed = null; + IsButtonPressed = false; IsButtonReleased = false; } @@ -663,6 +667,26 @@ namespace Terminal.Gui { }; } LastMouseButtonPressed = mouseEvent.ButtonState; + IsButtonPressed = true; + + if ((mouseFlag & MouseFlags.ReportMousePosition) == 0) { + Task.Run (async () => { + while (IsButtonPressed) { + await Task.Delay (200); + var me = new MouseEvent () { + X = mouseEvent.MousePosition.X, + Y = mouseEvent.MousePosition.Y, + Flags = mouseFlag + }; + + if (IsButtonPressed && (mouseFlag & MouseFlags.ReportMousePosition) == 0) { + mouseHandler (me); + mainLoop.Driver.Wakeup (); + } + } + }); + } + } else if ((mouseEvent.EventFlags == 0 || mouseEvent.EventFlags == WindowsConsole.EventFlags.MouseMoved) && LastMouseButtonPressed != null && !IsButtonReleased && !IsButtonDoubleClicked) { switch (LastMouseButtonPressed) { @@ -678,6 +702,7 @@ namespace Terminal.Gui { mouseFlag = MouseFlags.Button4Released; break; } + IsButtonPressed = false; IsButtonReleased = true; } else if ((mouseEvent.EventFlags == 0 || mouseEvent.EventFlags == WindowsConsole.EventFlags.MouseMoved) && IsButtonReleased) { diff --git a/Terminal.Gui/Views/ScrollView.cs b/Terminal.Gui/Views/ScrollView.cs index 318fba3df..58faca45f 100644 --- a/Terminal.Gui/Views/ScrollView.cs +++ b/Terminal.Gui/Views/ScrollView.cs @@ -114,21 +114,19 @@ namespace Terminal.Gui { var by1 = position * bh / Size; var by2 = (position + bh) * bh / Size; - Move (col, 0); Driver.AddRune ('^'); Move (col, Bounds.Height - 1); Driver.AddRune ('v'); for (int y = 0; y < bh; y++) { Move (col, y+1); - - if (y < by1 || y > by2) + if (y < by1 - 1 || y > by2) special = Driver.Stipple; else { - if (by2 - by1 == 0) + if (by2 - by1 == 0 && by1 < bh - 1) special = Driver.Diamond; else { - if (y == by1) + if (y == by1 - 1) special = Driver.TopTee; else if (y == by2) special = Driver.BottomTee; @@ -192,7 +190,8 @@ namespace Terminal.Gui { public override bool MouseEvent(MouseEvent me) { - if (me.Flags != MouseFlags.Button1Clicked) + if (me.Flags != MouseFlags.Button1Pressed && me.Flags != MouseFlags.Button1Clicked && + !me.Flags.HasFlag (MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition)) return false; int location = vertical ? me.Y : me.X; @@ -208,11 +207,23 @@ namespace Terminal.Gui { if (location == 0) { if (pos > 0) SetPosition (pos - 1); - } else if (location == barsize + 1){ + } else if (location == barsize + 1) { if (pos + 1 + barsize < Size) SetPosition (pos + 1); } else { - Console.WriteLine ("TODO at ScrollBarView"); + var b1 = pos * barsize / Size; + var b2 = (pos + barsize) * barsize / Size; + + if (b2 == 0 && location == 1 && pos == 0 || + (b2 == barsize && location == barsize) || + (location > b1 && location < b2)) { + return true; + } else if (location <= barsize) { + if (location > 1 && location >= b2) + SetPosition (Math.Min (pos + barsize, Size)); + else if (location <= b2 && pos > 0 || pos > 0) + SetPosition (Math.Max (pos - barsize, 0)); + } } } @@ -309,7 +320,7 @@ namespace Terminal.Gui { set { if (value == showHorizontalScrollIndicator) return; - + showHorizontalScrollIndicator = value; SetNeedsDisplay (); if (value) @@ -338,7 +349,7 @@ namespace Terminal.Gui { set { if (value == showVerticalScrollIndicator) return; - + showVerticalScrollIndicator = value; SetNeedsDisplay (); if (value) @@ -431,7 +442,7 @@ namespace Terminal.Gui { var nx = Math.Max (-contentSize.Width, contentOffset.X - cols); if (nx == contentOffset.X) return false; - + ContentOffset = new Point (nx, contentOffset.Y); return true; } @@ -461,6 +472,12 @@ namespace Terminal.Gui { case Key.CursorRight: return ScrollRight (1); + case Key.Home: + return ScrollUp (contentSize.Height); + + case Key.End: + return ScrollDown (contentSize.Height); + } return false; }