diff --git a/Terminal.Gui/Views/ScrollBarView.cs b/Terminal.Gui/Views/ScrollBarView.cs index c3963a602..bc238b1ad 100644 --- a/Terminal.Gui/Views/ScrollBarView.cs +++ b/Terminal.Gui/Views/ScrollBarView.cs @@ -166,8 +166,8 @@ namespace Terminal.Gui { get => position; set { if (position != value) { - if (CanScroll (value - position, out int max, vertical) || max > 0) { - if (max > 0 && max == value - position) { + if (CanScroll (value - position, out int max, vertical)) { + if (max == value - position) { position = value; } else { position = Math.Max (position + max, 0); @@ -222,22 +222,6 @@ namespace Terminal.Gui { } } - void SetWidthHeight () - { - if (showBothScrollIndicator) { - Width = vertical ? 1 : Dim.Width (Host) - 1; - Height = vertical ? Dim.Height (Host) - 1 : 1; - otherScrollBarView.Width = otherScrollBarView.vertical ? 1 : Dim.Width (Host) - 1; - otherScrollBarView.Height = otherScrollBarView.vertical ? Dim.Height (Host) - 1 : 1; - } else if (showScrollIndicator) { - Width = vertical ? 1 : Dim.Width (Host) - 0; - Height = vertical ? Dim.Height (Host) - 0 : 1; - } else if (otherScrollBarView != null && otherScrollBarView.showScrollIndicator) { - otherScrollBarView.Width = otherScrollBarView.vertical ? 1 : Dim.Width (Host) - 0; - otherScrollBarView.Height = otherScrollBarView.vertical ? Dim.Height (Host) - 0 : 1; - } - } - /// /// Get or sets if the view-port is kept always visible in the area of this /// @@ -310,7 +294,7 @@ namespace Terminal.Gui { } else { contentBottomRightCorner.Visible = false; } - if (showBothScrollIndicator) { + if (showScrollIndicator) { Redraw (Bounds); } if (otherScrollBarView.showScrollIndicator) { @@ -349,6 +333,23 @@ namespace Terminal.Gui { return pending; } + void SetWidthHeight () + { + if (showBothScrollIndicator) { + Width = vertical ? 1 : Dim.Width (Host) - 1; + Height = vertical ? Dim.Height (Host) - 1 : 1; + + otherScrollBarView.Width = otherScrollBarView.vertical ? 1 : Dim.Width (Host) - 1; + otherScrollBarView.Height = otherScrollBarView.vertical ? Dim.Height (Host) - 1 : 1; + } else if (showScrollIndicator) { + Width = vertical ? 1 : Dim.Width (Host) - 0; + Height = vertical ? Dim.Height (Host) - 0 : 1; + } else if (otherScrollBarView != null && otherScrollBarView.showScrollIndicator) { + otherScrollBarView.Width = otherScrollBarView.vertical ? 1 : Dim.Width (Host) - 0; + otherScrollBarView.Height = otherScrollBarView.vertical ? Dim.Height (Host) - 0 : 1; + } + } + int posTopTee; int posLeftTee; int posBottomTee; @@ -535,6 +536,7 @@ namespace Terminal.Gui { && (Application.mouseGrabView == null || Application.mouseGrabView != this)) { Application.GrabMouse (this); } else if (me.Flags == MouseFlags.Button1Released && Application.mouseGrabView != null && Application.mouseGrabView == this) { + lastLocation = -1; Application.UngrabMouse (); return true; } else if (showScrollIndicator && (me.Flags == MouseFlags.WheeledDown || me.Flags == MouseFlags.WheeledUp || @@ -542,9 +544,6 @@ namespace Terminal.Gui { return Host.MouseEvent (me); } - if (!me.Flags.HasFlag (MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition)) { - lastLocation = -1; - } if (location == 0) { if (pos > 0) { Position = pos - 1; @@ -562,51 +561,66 @@ namespace Terminal.Gui { b1 = Math.Max (b1 - 1, 0); } - if (location > b1 && location <= b2 + 1) { - if (me.Flags == MouseFlags.Button1Pressed || me.Flags == MouseFlags.Button1Clicked) { - if (location == 1 && posTopLeftTee <= 2) { - Position = 0; - } else if (location == barsize) { - CanScroll (Size - pos, out int nv, vertical); - if (nv > 0) { - Position = Math.Min (pos + nv, Size); - } - } else if (location < posTopLeftTee) { - if (CanScroll (-barsize, out int nv, vertical)) { - Position = pos + nv; - } + if (lastLocation == -1 && me.Flags == MouseFlags.Button1Pressed || me.Flags == MouseFlags.Button1Clicked) { + if (location == 1) { + if (location < posTopLeftTee && CanScroll (-barsize, out int nv, vertical)) { + Position = pos + nv; } - } else if (me.Flags.HasFlag (MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition)) { - var mb = (b2 - b1) / 2; - var ml = mb + b1 + (mb == 0 ? 1 : 0); - if ((location > 1 || (location == 1 && posTopLeftTee > 1)) && ((location >= b1 && location <= ml) || (location < lastLocation && lastLocation > -1))) { - lastLocation = location; - var np = location * Size / barsize; - if (CanScroll (np - pos, out int nv, vertical)) { - Position = pos + nv; - } - } else if (location != barsize && location > lastLocation) { - var np = location * Size / barsize; - if (CanScroll (np - pos, out int nv, vertical)) { - Position = pos + nv; - } - } else if (location == 1 && posTopLeftTee <= 2) { + if (location == posTopLeftTee) { Position = 0; - } else if (location == barsize) { - CanScroll (Size - pos, out int nv, vertical); - if (nv > 0) { - Position = Math.Min (pos + nv, Size); - } } - } - } else { - if (location >= b2 + 1 && location > posTopLeftTee && location > b1 && location > posBottomRightTee && posBottomRightTee > 0) { - CanScroll (location, out int nv, vertical); - if (nv > 0) { + } else if (location == barsize) { + if (location > posBottomRightTee && CanScroll (barsize, out int nv, vertical)) { + Position = pos + nv; + } + if (location == posBottomRightTee && CanScroll (Size - pos, out nv, vertical)) { + Position = Math.Min (pos + nv, Size); + } + } else if (location < posTopLeftTee) { + if (CanScroll (-barsize, out int nv, vertical)) { + Position = pos + nv; + } + } else if (location > posBottomRightTee) { + if (CanScroll (barsize, out int nv, vertical)) { + Position = pos + nv; + } + } + } else if (me.Flags.HasFlag (MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition)) { + var posBarLength = posBottomRightTee - posTopLeftTee; + + if (lastLocation > -1 || + location > 1 && location < barsize && location >= posTopLeftTee && location <= posBottomRightTee) { + if (lastLocation == -1) { + lastLocation = location; + return true; + } + + var np = location * Size / barsize - lastLocation; + if (CanScroll (np - pos, out int nv, vertical)) { + Position = pos + nv; + } + + if (location > lastLocation && location == barsize) { + if (CanScroll (Size - pos, out nv, vertical)) { + Position = Math.Min (pos + nv, Size); + } + } else if (location < lastLocation && location == 1 && b2 <= 2) { + Position = 0; + } + } else if (location > posBottomRightTee) { + if (CanScroll (barsize, out int nv, vertical)) { + Position = pos + nv; + } + } else if (location < posTopLeftTee) { + if (CanScroll (-barsize, out int nv, vertical)) { + Position = pos + nv; + } + } else if (location == 1 && b2 <= 2) { + Position = 0; + } else if (location == barsize) { + if (CanScroll (Size - pos, out int nv, vertical)) { Position = Math.Min (pos + nv, Size); } - } else if (location <= b1) { - Position = Math.Max (pos - barsize - location, 0); } } } @@ -623,9 +637,9 @@ namespace Terminal.Gui { var s = isVertical ? (KeepContentAlwaysInViewport ? Host.Bounds.Height + (showBothScrollIndicator ? -2 : -1) : 0) : (KeepContentAlwaysInViewport ? Host.Bounds.Width + (showBothScrollIndicator ? -2 : -1) : 0); - var newSize = Math.Min (size, position + n); - max = size > s + newSize ? n : size - (s + position) - 1; - if (size > s + newSize) { + var newSize = Math.Max (Math.Min (size - s, position + n), 0); + max = size > s + newSize ? (newSize == 0 ? -position : n) : size - (s + position) - 1; + if (size >= s + newSize && max != 0) { return true; } return false; diff --git a/UnitTests/ScrollBarViewTests.cs b/UnitTests/ScrollBarViewTests.cs index 8fcc73cc2..6532abae3 100644 --- a/UnitTests/ScrollBarViewTests.cs +++ b/UnitTests/ScrollBarViewTests.cs @@ -58,7 +58,6 @@ namespace Terminal.Gui { _scrollBar.Position = _hostView.Top; _scrollBar.OtherScrollBarView.Size = _hostView.Cols; _scrollBar.OtherScrollBarView.Position = _hostView.Left; - _scrollBar.ColorScheme = _scrollBar.OtherScrollBarView.ColorScheme = _hostView.ColorScheme; _scrollBar.Refresh (); } @@ -111,16 +110,6 @@ namespace Terminal.Gui { Assert.Throws (null, () => h.OtherScrollBarView = v); } - [Fact] - public void Scrolling_With_Default_Constructor_Do_Not_Scroll () - { - var sbv = new ScrollBarView { - Position = 1 - }; - Assert.NotEqual (1, sbv.Position); - Assert.Equal (0, sbv.Position); - } - [Fact] public void Hosting_Two_Horizontal_ScrollBarView_Throws_ArgumentException () { @@ -134,15 +123,22 @@ namespace Terminal.Gui { Assert.Throws (null, () => h.OtherScrollBarView = v); } + [Fact] + public void Scrolling_With_Default_Constructor_Do_Not_Scroll () + { + var sbv = new ScrollBarView { + Position = 1 + }; + Assert.NotEqual (1, sbv.Position); + Assert.Equal (0, sbv.Position); + } + [Fact] public void Hosting_A_View_To_A_ScrollBarView () { RemoveHandlers (); _scrollBar = new ScrollBarView (_hostView, true); - _scrollBar.OtherScrollBarView = new ScrollBarView (_hostView, false); - _scrollBar.OtherScrollBarView = _scrollBar.OtherScrollBarView; - _scrollBar.OtherScrollBarView.OtherScrollBarView = _scrollBar; Assert.True (_scrollBar.IsVertical); Assert.False (_scrollBar.OtherScrollBarView.IsVertical); @@ -241,7 +237,8 @@ namespace Terminal.Gui { AddHandlers (); - Assert.Equal (_scrollBar.OtherScrollBarView, _scrollBar.OtherScrollBarView); + Assert.NotNull (_scrollBar.OtherScrollBarView); + Assert.NotEqual (_scrollBar, _scrollBar.OtherScrollBarView); Assert.Equal (_scrollBar.OtherScrollBarView.OtherScrollBarView, _scrollBar); } @@ -298,10 +295,14 @@ namespace Terminal.Gui { _scrollBar.Position = 50; Assert.Equal (_scrollBar.Position, _scrollBar.Size - 1); Assert.Equal (_scrollBar.Position, _hostView.Top); + Assert.Equal (29, _scrollBar.Position); + Assert.Equal (29, _hostView.Top); _scrollBar.OtherScrollBarView.Position = 150; Assert.Equal (_scrollBar.OtherScrollBarView.Position, _scrollBar.OtherScrollBarView.Size - 1); Assert.Equal (_scrollBar.OtherScrollBarView.Position, _hostView.Left); + Assert.Equal (99, _scrollBar.OtherScrollBarView.Position); + Assert.Equal (99, _hostView.Left); } [Fact] @@ -314,6 +315,8 @@ namespace Terminal.Gui { _hostView.Redraw (_hostView.Bounds); Assert.True (_scrollBar.ShowScrollIndicator); Assert.True (_scrollBar.Visible); + Assert.Equal ("Dim.Absolute(1)", _scrollBar.Width.ToString ()); + Assert.Equal (1, _scrollBar.Bounds.Width); Assert.Equal ("Dim.Combine(DimView(side=Height, target=HostView()({X=0,Y=0,Width=80,Height=25}))-Dim.Absolute(1))", _scrollBar.Height.ToString ()); Assert.Equal (24, _scrollBar.Bounds.Height); @@ -322,43 +325,76 @@ namespace Terminal.Gui { Assert.Equal ("Dim.Combine(DimView(side=Width, target=HostView()({X=0,Y=0,Width=80,Height=25}))-Dim.Absolute(1))", _scrollBar.OtherScrollBarView.Width.ToString ()); Assert.Equal (79, _scrollBar.OtherScrollBarView.Bounds.Width); + Assert.Equal ("Dim.Absolute(1)", _scrollBar.OtherScrollBarView.Height.ToString ()); + Assert.Equal (1, _scrollBar.OtherScrollBarView.Bounds.Height); _hostView.Lines = 10; _hostView.Redraw (_hostView.Bounds); Assert.False (_scrollBar.ShowScrollIndicator); Assert.False (_scrollBar.Visible); + Assert.Equal ("Dim.Absolute(1)", _scrollBar.Width.ToString ()); + Assert.Equal (1, _scrollBar.Bounds.Width); Assert.Equal ("Dim.Combine(DimView(side=Height, target=HostView()({X=0,Y=0,Width=80,Height=25}))-Dim.Absolute(1))", _scrollBar.Height.ToString ()); Assert.Equal (24, _scrollBar.Bounds.Height); + Assert.True (_scrollBar.OtherScrollBarView.ShowScrollIndicator); + Assert.True (_scrollBar.OtherScrollBarView.Visible); + Assert.Equal ("Dim.Combine(DimView(side=Width, target=HostView()({X=0,Y=0,Width=80,Height=25}))-Dim.Absolute(0))", + _scrollBar.OtherScrollBarView.Width.ToString ()); + Assert.Equal (80, _scrollBar.OtherScrollBarView.Bounds.Width); + Assert.Equal ("Dim.Absolute(1)", _scrollBar.OtherScrollBarView.Height.ToString ()); + Assert.Equal (1, _scrollBar.OtherScrollBarView.Bounds.Height); _hostView.Cols = 60; _hostView.Redraw (_hostView.Bounds); + Assert.False (_scrollBar.ShowScrollIndicator); + Assert.False (_scrollBar.Visible); + Assert.Equal ("Dim.Absolute(1)", _scrollBar.Width.ToString ()); + Assert.Equal (1, _scrollBar.Bounds.Width); + Assert.Equal ("Dim.Combine(DimView(side=Height, target=HostView()({X=0,Y=0,Width=80,Height=25}))-Dim.Absolute(1))", + _scrollBar.Height.ToString ()); + Assert.Equal (24, _scrollBar.Bounds.Height); Assert.False (_scrollBar.OtherScrollBarView.ShowScrollIndicator); Assert.False (_scrollBar.OtherScrollBarView.Visible); Assert.Equal ("Dim.Combine(DimView(side=Width, target=HostView()({X=0,Y=0,Width=80,Height=25}))-Dim.Absolute(0))", _scrollBar.OtherScrollBarView.Width.ToString ()); Assert.Equal (80, _scrollBar.OtherScrollBarView.Bounds.Width); + Assert.Equal ("Dim.Absolute(1)", _scrollBar.OtherScrollBarView.Height.ToString ()); + Assert.Equal (1, _scrollBar.OtherScrollBarView.Bounds.Height); _hostView.Lines = 40; _hostView.Redraw (_hostView.Bounds); Assert.True (_scrollBar.ShowScrollIndicator); Assert.True (_scrollBar.Visible); + Assert.Equal ("Dim.Absolute(1)", _scrollBar.Width.ToString ()); + Assert.Equal (1, _scrollBar.Bounds.Width); Assert.Equal ("Dim.Combine(DimView(side=Height, target=HostView()({X=0,Y=0,Width=80,Height=25}))-Dim.Absolute(0))", _scrollBar.Height.ToString ()); Assert.Equal (25, _scrollBar.Bounds.Height); + Assert.False (_scrollBar.OtherScrollBarView.ShowScrollIndicator); + Assert.False (_scrollBar.OtherScrollBarView.Visible); + Assert.Equal ("Dim.Combine(DimView(side=Width, target=HostView()({X=0,Y=0,Width=80,Height=25}))-Dim.Absolute(0))", + _scrollBar.OtherScrollBarView.Width.ToString ()); + Assert.Equal (80, _scrollBar.OtherScrollBarView.Bounds.Width); + Assert.Equal ("Dim.Absolute(1)", _scrollBar.OtherScrollBarView.Height.ToString ()); + Assert.Equal (1, _scrollBar.OtherScrollBarView.Bounds.Height); _hostView.Cols = 120; _hostView.Redraw (_hostView.Bounds); + Assert.True (_scrollBar.ShowScrollIndicator); + Assert.True (_scrollBar.Visible); + Assert.Equal ("Dim.Absolute(1)", _scrollBar.Width.ToString ()); + Assert.Equal (1, _scrollBar.Bounds.Width); + Assert.Equal ("Dim.Combine(DimView(side=Height, target=HostView()({X=0,Y=0,Width=80,Height=25}))-Dim.Absolute(1))", + _scrollBar.Height.ToString ()); + Assert.Equal (24, _scrollBar.Bounds.Height); Assert.True (_scrollBar.OtherScrollBarView.ShowScrollIndicator); Assert.True (_scrollBar.OtherScrollBarView.Visible); Assert.Equal ("Dim.Combine(DimView(side=Width, target=HostView()({X=0,Y=0,Width=80,Height=25}))-Dim.Absolute(1))", _scrollBar.OtherScrollBarView.Width.ToString ()); Assert.Equal (79, _scrollBar.OtherScrollBarView.Bounds.Width); - Assert.True (_scrollBar.ShowScrollIndicator); - Assert.True (_scrollBar.Visible); - Assert.Equal ("Dim.Combine(DimView(side=Height, target=HostView()({X=0,Y=0,Width=80,Height=25}))-Dim.Absolute(1))", - _scrollBar.Height.ToString ()); - Assert.Equal (24, _scrollBar.Bounds.Height); + Assert.Equal ("Dim.Absolute(1)", _scrollBar.OtherScrollBarView.Height.ToString ()); + Assert.Equal (1, _scrollBar.OtherScrollBarView.Bounds.Height); } } }