Browse Source

Fixes #2553 - Fix HotFocus color when FullRowSelecting being used for VLines on left/right of TableView (#2557)

* Fix HotFocus color when FullRowSelecting being used for VLines on left/right of TableView

* Add AlwaysUseNormalColorForVerticalCellLines style setting

---------

Co-authored-by: Tig <[email protected]>
Thomas Nind 2 years ago
parent
commit
5cefd5bf0b

+ 19 - 6
Terminal.Gui/Views/TableView/TableView.cs

@@ -530,10 +530,6 @@ namespace Terminal.Gui {
 			var rowScheme = (Style.RowColorGetter?.Invoke (
 				new RowColorGetterArgs (Table, rowToRender))) ?? ColorScheme;
 
-			//render start of line
-			if (style.ShowVerticalCellLines)
-				AddRune (0, row, Driver.VLine);
-
 			//start by clearing the entire line
 			Move (0, row);
 
@@ -613,6 +609,11 @@ namespace Terminal.Gui {
 				if (!FullRowSelect)
 					Driver.SetAttribute (Enabled ? rowScheme.Normal : rowScheme.Disabled);
 
+				if(style.AlwaysUseNormalColorForVerticalCellLines && style.ShowVerticalCellLines) {
+
+					Driver.SetAttribute (rowScheme.Normal);
+				}
+
 				RenderSeparator (current.X - 1, row, false);
 
 				if (Style.ExpandLastColumn == false && current.IsVeryLast) {
@@ -620,9 +621,15 @@ namespace Terminal.Gui {
 				}
 			}
 
-			//render end of line
-			if (style.ShowVerticalCellLines)
+			if (style.ShowVerticalCellLines) {
+
+				Driver.SetAttribute (rowScheme.Normal);
+
+				//render start and end of line
+				AddRune (0, row, Driver.VLine);
 				AddRune (Bounds.Width - 1, row, Driver.VLine);
+			}
+				
 		}
 
 		/// <summary>
@@ -1858,6 +1865,12 @@ namespace Terminal.Gui {
 			/// </summary>
 			public bool InvertSelectedCellFirstCharacter { get; set; } = false;
 
+			/// <summary>
+			/// Gets or sets a flag indicating whether to force <see cref="ColorScheme.Normal"/> use when rendering
+			/// vertical cell lines (even when <see cref="FullRowSelect"/> is on).
+			/// </summary>
+			public bool AlwaysUseNormalColorForVerticalCellLines { get; set; } = false;
+
 			/// <summary>
 			/// Collection of columns for which you want special rendering (e.g. custom column lengths, text alignment etc)
 			/// </summary>

+ 10 - 0
UICatalog/Scenarios/TableEditor.cs

@@ -25,6 +25,7 @@ namespace UICatalog.Scenarios {
 		private MenuItem miCellLines;
 		private MenuItem miFullRowSelect;
 		private MenuItem miExpandLastColumn;
+		private MenuItem miAlwaysUseNormalColorForVerticalCellLines;
 		private MenuItem miSmoothScrolling;
 		private MenuItem miAlternatingColors;
 		private MenuItem miCursor;
@@ -67,6 +68,7 @@ namespace UICatalog.Scenarios {
 					miFullRowSelect =new MenuItem ("_FullRowSelect", "", () => ToggleFullRowSelect()){Checked = tableView.FullRowSelect, CheckType = MenuItemCheckStyle.Checked },
 					miCellLines =new MenuItem ("_CellLines", "", () => ToggleCellLines()){Checked = tableView.Style.ShowVerticalCellLines, CheckType = MenuItemCheckStyle.Checked },
 					miExpandLastColumn = new MenuItem ("_ExpandLastColumn", "", () => ToggleExpandLastColumn()){Checked = tableView.Style.ExpandLastColumn, CheckType = MenuItemCheckStyle.Checked },
+					miAlwaysUseNormalColorForVerticalCellLines = new MenuItem ("_AlwaysUseNormalColorForVerticalCellLines", "", () => ToggleAlwaysUseNormalColorForVerticalCellLines()){Checked = tableView.Style.AlwaysUseNormalColorForVerticalCellLines, CheckType = MenuItemCheckStyle.Checked },
 					miSmoothScrolling = new MenuItem ("_SmoothHorizontalScrolling", "", () => ToggleSmoothScrolling()){Checked = tableView.Style.SmoothHorizontalScrolling, CheckType = MenuItemCheckStyle.Checked },
 					new MenuItem ("_AllLines", "", () => ToggleAllCellLines()),
 					new MenuItem ("_NoLines", "", () => ToggleNoCellLines()),
@@ -435,6 +437,14 @@ namespace UICatalog.Scenarios {
 			tableView.Update ();
 
 		}
+
+		private void ToggleAlwaysUseNormalColorForVerticalCellLines()
+		{
+			miAlwaysUseNormalColorForVerticalCellLines.Checked = !miAlwaysUseNormalColorForVerticalCellLines.Checked;
+			tableView.Style.AlwaysUseNormalColorForVerticalCellLines = (bool)miAlwaysUseNormalColorForVerticalCellLines.Checked;
+
+			tableView.Update ();
+		}
 		private void ToggleSmoothScrolling ()
 		{
 			miSmoothScrolling.Checked = !miSmoothScrolling.Checked;

+ 1 - 1
UnitTests/TestHelpers.cs

@@ -267,7 +267,7 @@ class TestHelpers {
 	/// </summary>
 	/// <param name="expectedLook">Numbers between 0 and 9 for each row/col of the console.  Must be valid indexes of <paramref name="expectedColors"/></param>
 	/// <param name="expectedColors"></param>
-	public static void AssertDriverColorsAre (string expectedLook, Attribute [] expectedColors)
+	public static void AssertDriverColorsAre (string expectedLook, params Attribute [] expectedColors)
 	{
 #pragma warning restore xUnit1013 // Public method should be marked as test
 

+ 175 - 7
UnitTests/Views/TableViewTests.cs

@@ -1786,14 +1786,14 @@ namespace Terminal.Gui.ViewsTests {
 			tableView.EnsureSelectedCellIsVisible ();
 			Assert.Equal (smooth ? 1 : 3, tableView.ColumnOffset);
 		}
-		
+
 		[Fact, AutoInitShutdown]
 		public void LongColumnTest ()
 		{
 			var tableView = new TableView ();
 
-			Application.Top.Add(tableView);
-			Application.Begin(Application.Top);
+			Application.Top.Add (tableView);
+			Application.Begin (Application.Top);
 
 			tableView.ColorScheme = Colors.TopLevel;
 
@@ -1896,8 +1896,8 @@ namespace Terminal.Gui.ViewsTests {
 			// Now test making the width too small for the MinAcceptableWidth
 			// the Column won't fit so should not be rendered
 			var driver = ((FakeDriver)Application.Driver);
-			driver.UpdateOffScreen();
-			
+			driver.UpdateOffScreen ();
+
 
 			tableView.Bounds = new Rect (0, 0, 9, 5);
 			tableView.LayoutSubviews ();
@@ -2075,7 +2075,7 @@ namespace Terminal.Gui.ViewsTests {
 		[Fact, AutoInitShutdown]
 		public void ShowHorizontalBottomLine_WithVerticalCellLines ()
 		{
-			var tableView = GetABCDEFTableView(out _);
+			var tableView = GetABCDEFTableView (out _);
 			tableView.BeginInit (); tableView.EndInit ();
 
 			tableView.ColorScheme = Colors.TopLevel;
@@ -2087,7 +2087,7 @@ namespace Terminal.Gui.ViewsTests {
 			tableView.Style.AlwaysShowHeaders = true;
 			tableView.Style.SmoothHorizontalScrolling = true;
 			tableView.Style.ShowHorizontalBottomline = true;
-						
+
 			tableView.Redraw (tableView.Bounds);
 
 			// user can only scroll right so sees right indicator
@@ -2132,6 +2132,174 @@ namespace Terminal.Gui.ViewsTests {
 			TestHelpers.AssertDriverContentsAre (expected, output);
 		}
 
+		[Fact, AutoInitShutdown]
+		public void TestFullRowSelect_SelectionColorStopsAtTableEdge_WithCellLines ()
+		{
+			var tv = GetTwoRowSixColumnTable ();
+			tv.Table.Rows.Add (1, 2, 3, 4, 5, 6);
+			tv.LayoutSubviews ();
+
+
+			tv.Bounds = new Rect (0, 0, 7, 6);
+
+			tv.FullRowSelect = true;
+			tv.Style.ShowHorizontalBottomline = true;
+
+			// Clicking in bottom row
+			tv.MouseEvent (new MouseEvent {
+				X = 1,
+				Y = 4,
+				Flags = MouseFlags.Button1Clicked
+			});
+
+			// should select that row
+			Assert.Equal (2, tv.SelectedRow);
+
+
+			tv.Redraw (tv.Bounds);
+
+			string expected =
+				@"
+│A│B│C│
+├─┼─┼─►
+│1│2│3│
+│1│2│3│
+│1│2│3│
+└─┴─┴─┘";
+
+			TestHelpers.AssertDriverContentsAre (expected, output);
+
+			var normal = tv.ColorScheme.Normal;
+			var focus = tv.ColorScheme.HotFocus = new Attribute (Color.Magenta, Color.White);
+
+			tv.Redraw (tv.Bounds);
+
+			// HotFocus color (1) should be used for rendering the selected line
+			// But should not spill into the borders.  Normal color (0) should be
+			// used for the rest.
+			expected =
+				@"
+0000000
+0000000
+0000000
+0000000
+0111110
+0000000";
+
+			TestHelpers.AssertDriverColorsAre (expected, normal, focus);
+		}
+
+		[Fact, AutoInitShutdown]
+		public void TestFullRowSelect_AlwaysUseNormalColorForVerticalCellLines ()
+		{
+			var tv = GetTwoRowSixColumnTable ();
+			tv.Table.Rows.Add (1, 2, 3, 4, 5, 6);
+			tv.LayoutSubviews ();
+
+
+			tv.Bounds = new Rect (0, 0, 7, 6);
+
+			tv.FullRowSelect = true;
+			tv.Style.ShowHorizontalBottomline = true;
+			tv.Style.AlwaysUseNormalColorForVerticalCellLines = true;
+
+			// Clicking in bottom row
+			tv.MouseEvent (new MouseEvent {
+				X = 1,
+				Y = 4,
+				Flags = MouseFlags.Button1Clicked
+			});
+
+			// should select that row
+			Assert.Equal (2, tv.SelectedRow);
+
+
+			tv.Redraw (tv.Bounds);
+
+			string expected =
+				@"
+│A│B│C│
+├─┼─┼─►
+│1│2│3│
+│1│2│3│
+│1│2│3│
+└─┴─┴─┘";
+
+			TestHelpers.AssertDriverContentsAre (expected, output);
+
+			var normal = tv.ColorScheme.Normal;
+			var focus = tv.ColorScheme.HotFocus = new Attribute (Color.Magenta, Color.White);
+
+			tv.Redraw (tv.Bounds);
+
+			// HotFocus color (1) should be used for cells only because
+			// AlwaysUseNormalColorForVerticalCellLines is true
+			expected =
+				@"
+0000000
+0000000
+0000000
+0000000
+0101010
+0000000";
+
+			TestHelpers.AssertDriverColorsAre (expected, normal, focus);
+		}
+		[Fact, AutoInitShutdown]
+		public void TestFullRowSelect_SelectionColorDoesNotStop_WhenShowVerticalCellLinesIsFalse ()
+		{
+			var tv = GetTwoRowSixColumnTable ();
+			tv.Table.Rows.Add (1, 2, 3, 4, 5, 6);
+			tv.LayoutSubviews ();
+
+
+			tv.Bounds = new Rect (0, 0, 7, 6);
+
+			tv.FullRowSelect = true;
+			tv.Style.ShowVerticalCellLines = false;
+			tv.Style.ShowVerticalHeaderLines = false;
+
+			// Clicking in bottom row
+			tv.MouseEvent (new MouseEvent {
+				X = 1,
+				Y = 4,
+				Flags = MouseFlags.Button1Clicked
+			});
+
+			// should select that row
+			Assert.Equal (2, tv.SelectedRow);
+
+
+			tv.Redraw (tv.Bounds);
+
+			string expected =
+				@"
+A B C
+───────
+1 2 3
+1 2 3
+1 2 3";
+
+			TestHelpers.AssertDriverContentsAre (expected, output);
+
+			var normal = tv.ColorScheme.Normal;
+			var focus = tv.ColorScheme.HotFocus = new Attribute (Color.Magenta, Color.White);
+
+			tv.Redraw (tv.Bounds);
+
+			// HotFocus color (1) should be used for rendering the selected line
+			// Note that because there are no vertical cell lines we use the hot focus
+			// color for the whole row
+			expected =
+				@"
+000000
+000000
+000000
+000000
+111111";
+
+			TestHelpers.AssertDriverColorsAre (expected, normal, focus);
+		}
 
 		/// <summary>
 		/// Builds a simple table of string columns with the requested number of columns and rows