diff --git a/Terminal.Gui/Views/TableView.cs b/Terminal.Gui/Views/TableView.cs
index 1082f68c5..07c563e11 100644
--- a/Terminal.Gui/Views/TableView.cs
+++ b/Terminal.Gui/Views/TableView.cs
@@ -60,6 +60,9 @@ namespace Terminal.Gui {
private TableStyle style = new TableStyle ();
private Key cellActivationKey = Key.Enter;
+ Point? scrollLeftPoint;
+ Point? scrollRightPoint;
+
///
/// The default maximum cell width for and
///
@@ -261,6 +264,9 @@ namespace Terminal.Gui {
Move (0, 0);
var frame = Frame;
+ scrollRightPoint = null;
+ scrollLeftPoint = null;
+
// What columns to render at what X offset in viewport
var columnsToRender = CalculateViewport (bounds).ToArray ();
@@ -420,11 +426,25 @@ namespace Terminal.Gui {
for (int c = 0; c < availableWidth; c++) {
+ // Start by assuming we just draw a straight line the
+ // whole way but update to instead draw a header indicator
+ // or scroll arrow etc
var rune = Driver.HLine;
if (Style.ShowVerticalHeaderLines) {
if (c == 0) {
+ // for first character render line
rune = Style.ShowVerticalCellLines ? Driver.LeftTee : Driver.LLCorner;
+
+ // unless we have horizontally scrolled along
+ // in which case render an arrow, to indicate user
+ // can scroll left
+ if(Style.ShowHorizontalScrollIndicators && ColumnOffset > 0)
+ {
+ rune = Driver.LeftArrow;
+ scrollLeftPoint = new Point(c,row);
+ }
+
}
// if the next column is the start of a header
else if (columnsToRender.Any (r => r.X == c + 1)) {
@@ -432,7 +452,20 @@ namespace Terminal.Gui {
/*TODO: is ┼ symbol in Driver?*/
rune = Style.ShowVerticalCellLines ? '┼' : Driver.BottomTee;
} else if (c == availableWidth - 1) {
+
+ // for the last character in the table
rune = Style.ShowVerticalCellLines ? Driver.RightTee : Driver.LRCorner;
+
+ // unless there is more of the table we could horizontally
+ // scroll along to see. In which case render an arrow,
+ // to indicate user can scroll right
+ if(Style.ShowHorizontalScrollIndicators &&
+ ColumnOffset + columnsToRender.Length < Table.Columns.Count)
+ {
+ rune = Driver.RightArrow;
+ scrollRightPoint = new Point(c,row);
+ }
+
}
// if the next console column is the lastcolumns end
else if (Style.ExpandLastColumn == false &&
@@ -898,6 +931,24 @@ namespace Terminal.Gui {
if (me.Flags.HasFlag (MouseFlags.Button1Clicked)) {
+ if (scrollLeftPoint != null
+ && scrollLeftPoint.Value.X == me.X
+ && scrollLeftPoint.Value.Y == me.Y)
+ {
+ ColumnOffset--;
+ EnsureValidScrollOffsets ();
+ SetNeedsDisplay ();
+ }
+
+ if (scrollRightPoint != null
+ && scrollRightPoint.Value.X == me.X
+ && scrollRightPoint.Value.Y == me.Y)
+ {
+ ColumnOffset++;
+ EnsureValidScrollOffsets ();
+ SetNeedsDisplay ();
+ }
+
var hit = ScreenToCell (me.X, me.Y);
if (hit != null) {
@@ -1369,6 +1420,14 @@ namespace Terminal.Gui {
///
public bool ShowVerticalHeaderLines { get; set; } = true;
+ ///
+ /// True to render a arrows on the right/left of the table when
+ /// there are more column(s) that can be scrolled to. Requires
+ /// to be true.
+ /// Defaults to true
+ ///
+ public bool ShowHorizontalScrollIndicators { get; set; } = true;
+
///
/// True to invert the colors of the first symbol of the selected cell in the .
/// This gives the appearance of a cursor for when the doesn't otherwise show
diff --git a/UICatalog/Scenarios/TableEditor.cs b/UICatalog/Scenarios/TableEditor.cs
index 224837f74..988bae7fd 100644
--- a/UICatalog/Scenarios/TableEditor.cs
+++ b/UICatalog/Scenarios/TableEditor.cs
@@ -20,6 +20,7 @@ namespace UICatalog.Scenarios {
private MenuItem miHeaderOverline;
private MenuItem miHeaderMidline;
private MenuItem miHeaderUnderline;
+ private MenuItem miShowHorizontalScrollIndicators;
private MenuItem miCellLines;
private MenuItem miFullRowSelect;
private MenuItem miExpandLastColumn;
@@ -55,7 +56,8 @@ namespace UICatalog.Scenarios {
miAlwaysShowHeaders = new MenuItem ("_AlwaysShowHeaders", "", () => ToggleAlwaysShowHeader()){Checked = tableView.Style.AlwaysShowHeaders, CheckType = MenuItemCheckStyle.Checked },
miHeaderOverline = new MenuItem ("_HeaderOverLine", "", () => ToggleOverline()){Checked = tableView.Style.ShowHorizontalHeaderOverline, CheckType = MenuItemCheckStyle.Checked },
miHeaderMidline = new MenuItem ("_HeaderMidLine", "", () => ToggleHeaderMidline()){Checked = tableView.Style.ShowVerticalHeaderLines, CheckType = MenuItemCheckStyle.Checked },
- miHeaderUnderline =new MenuItem ("_HeaderUnderLine", "", () => ToggleUnderline()){Checked = tableView.Style.ShowHorizontalHeaderUnderline, CheckType = MenuItemCheckStyle.Checked },
+ miHeaderUnderline = new MenuItem ("_HeaderUnderLine", "", () => ToggleUnderline()){Checked = tableView.Style.ShowHorizontalHeaderUnderline, CheckType = MenuItemCheckStyle.Checked },
+ miShowHorizontalScrollIndicators = new MenuItem ("_HorizontalScrollIndicators", "", () => ToggleHorizontalScrollIndicators()){Checked = tableView.Style.ShowHorizontalScrollIndicators, CheckType = MenuItemCheckStyle.Checked },
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 },
@@ -205,6 +207,12 @@ namespace UICatalog.Scenarios {
tableView.Style.ShowHorizontalHeaderUnderline = miHeaderUnderline.Checked;
tableView.Update();
}
+ private void ToggleHorizontalScrollIndicators ()
+ {
+ miShowHorizontalScrollIndicators.Checked = !miShowHorizontalScrollIndicators.Checked;
+ tableView.Style.ShowHorizontalScrollIndicators = miShowHorizontalScrollIndicators.Checked;
+ tableView.Update();
+ }
private void ToggleFullRowSelect ()
{
miFullRowSelect.Checked = !miFullRowSelect.Checked;
diff --git a/UICatalog/Scenarios/TreeUseCases.cs b/UICatalog/Scenarios/TreeUseCases.cs
index b067001d2..4a63c25aa 100644
--- a/UICatalog/Scenarios/TreeUseCases.cs
+++ b/UICatalog/Scenarios/TreeUseCases.cs
@@ -75,6 +75,7 @@ namespace UICatalog.Scenarios {
if (currentTree != null) {
Win.Remove (currentTree);
+ currentTree.Dispose ();
}
@@ -148,6 +149,7 @@ namespace UICatalog.Scenarios {
if (currentTree != null) {
Win.Remove (currentTree);
+ currentTree.Dispose ();
}
@@ -180,6 +182,7 @@ namespace UICatalog.Scenarios {
{
if (currentTree != null) {
Win.Remove (currentTree);
+ currentTree.Dispose ();
}
diff --git a/UnitTests/TableViewTests.cs b/UnitTests/TableViewTests.cs
index 5ccfdbbcd..a31985994 100644
--- a/UnitTests/TableViewTests.cs
+++ b/UnitTests/TableViewTests.cs
@@ -778,6 +778,85 @@ namespace Terminal.Gui.Views {
Application.Shutdown ();
}
+
+ [Fact]
+ public void ScrollIndicators ()
+ {
+ GraphViewTests.InitFakeDriver ();
+
+ var tableView = new TableView ();
+ tableView.ColorScheme = Colors.TopLevel;
+
+ // 3 columns are visibile
+ tableView.Bounds = new Rect (0, 0, 7, 5);
+ tableView.Style.ShowHorizontalHeaderUnderline = true;
+ tableView.Style.ShowHorizontalHeaderOverline = false;
+ tableView.Style.AlwaysShowHeaders = true;
+ tableView.Style.SmoothHorizontalScrolling = true;
+
+ var dt = new DataTable ();
+ dt.Columns.Add ("A");
+ dt.Columns.Add ("B");
+ dt.Columns.Add ("C");
+ dt.Columns.Add ("D");
+ dt.Columns.Add ("E");
+ dt.Columns.Add ("F");
+
+ dt.Rows.Add (1, 2, 3, 4, 5, 6);
+
+ tableView.Table = dt;
+
+ // select last visible column
+ tableView.SelectedColumn = 2; // column C
+
+ tableView.Redraw (tableView.Bounds);
+
+ // user can only scroll right so sees right indicator
+ // Because first column in table is A
+ string expected =
+ @"
+│A│B│C│
+├─┼─┼─►
+│1│2│3│";
+
+ GraphViewTests.AssertDriverContentsAre (expected, output);
+
+
+ // Scroll right
+ tableView.ProcessKey (new KeyEvent () { Key = Key.CursorRight });
+
+
+ // since A is now pushed off screen we get indicator showing
+ // that user can scroll left to see first column
+ tableView.Redraw (tableView.Bounds);
+
+ expected =
+ @"
+│B│C│D│
+◄─┼─┼─►
+│2│3│4│";
+
+ GraphViewTests.AssertDriverContentsAre (expected, output);
+
+
+ // Scroll right twice more (to end of columns)
+ tableView.ProcessKey (new KeyEvent () { Key = Key.CursorRight });
+ tableView.ProcessKey (new KeyEvent () { Key = Key.CursorRight });
+
+ tableView.Redraw (tableView.Bounds);
+
+ expected =
+ @"
+│D│E│F│
+◄─┼─┼─┤
+│4│5│6│";
+
+ GraphViewTests.AssertDriverContentsAre (expected, output);
+
+ // Shutdown must be called to safely clean up Application if Init has been called
+ Application.Shutdown ();
+ }
+
///
/// Builds a simple table of string columns with the requested number of columns and rows
///