Browse Source

Simplifies the code more and makes it more understandable on the ScrollBarView.

BDisp 4 years ago
parent
commit
e7f66f8350
2 changed files with 132 additions and 82 deletions
  1. 76 62
      Terminal.Gui/Views/ScrollBarView.cs
  2. 56 20
      UnitTests/ScrollBarViewTests.cs

+ 76 - 62
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;
-			}
-		}
-
 		/// <summary>
 		/// Get or sets if the view-port is kept always visible in the area of this <see cref="ScrollBarView"/>
 		/// </summary>
@@ -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) {
+				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;
+						}
+						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 < posTopLeftTee) {
-							if (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))) {
+					} 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;
-							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) {
-							Position = 0;
-						} else if (location == barsize) {
-							CanScroll (Size - pos, out int nv, vertical);
-							if (nv > 0) {
+							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 >= b2 + 1 && location > posTopLeftTee && location > b1 && location > posBottomRightTee && posBottomRightTee > 0) {
-						CanScroll (location, out int nv, vertical);
-						if (nv > 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;

+ 56 - 20
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<ArgumentException> (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<ArgumentException> (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.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.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.Equal ("Dim.Absolute(1)", _scrollBar.OtherScrollBarView.Height.ToString ());
+			Assert.Equal (1, _scrollBar.OtherScrollBarView.Bounds.Height);
 		}
 	}
 }