diff --git a/Terminal.Gui/Views/TableView.cs b/Terminal.Gui/Views/TableView.cs
index 7040e51e2..f2c88bf60 100644
--- a/Terminal.Gui/Views/TableView.cs
+++ b/Terminal.Gui/Views/TableView.cs
@@ -1,4 +1,5 @@
-using System;
+using NStack;
+using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
@@ -12,6 +13,8 @@ namespace Terminal.Gui.Views {
private int columnOffset;
private int rowOffset;
+ private int selectedRow;
+ private int selectedColumn;
public DataTable Table { get; private set; }
@@ -20,42 +23,37 @@ namespace Terminal.Gui.Views {
///
/// This property allows very wide tables to be rendered with horizontal scrolling
public int ColumnOffset {
- get {
- return columnOffset;
- }
+ get => columnOffset;
//try to prevent this being set to an out of bounds column
- set {
- //the value before we changed it
- var origValue = columnOffset;
-
- columnOffset = Math.Min (Table.Columns.Count - 1, Math.Max (0, value));
-
- //if value actually changed we must update UI
- if(columnOffset != origValue)
- SetNeedsDisplay();
- }
+ set => columnOffset = Math.Min (Table.Columns.Count - 1, Math.Max (0, value));
}
-
///
/// Zero indexed offset for the to display in on line 2 of the control (first line being headers)
///
/// This property allows very wide tables to be rendered with horizontal scrolling
public int RowOffset {
- get {
- return rowOffset;
- }
- set {
- //the value before we changed it
- var origValue = rowOffset;
+ get => rowOffset;
+ set => rowOffset = Math.Min (Table.Rows.Count - 1, Math.Max (0, value));
+ }
- rowOffset = Math.Min (Table.Rows.Count - 1, Math.Max (0, value));
+ ///
+ /// The index of in that the user has currently selected
+ ///
+ public int SelectedColumn {
+ get => selectedColumn;
- //if value actually changed we must update UI
- if(rowOffset != origValue)
- SetNeedsDisplay();
- }
+ //try to prevent this being set to an out of bounds column
+ set => selectedColumn = Math.Min (Table.Columns.Count - 1, Math.Max (0, value));
+ }
+
+ ///
+ /// The index of in that the user has currently selected
+ ///
+ public int SelectedRow {
+ get => selectedRow;
+ set => selectedRow = Math.Min (Table.Rows.Count - 1, Math.Max (0, value));
}
///
@@ -91,22 +89,19 @@ namespace Terminal.Gui.Views {
var frame = Frame;
- int activeColor = ColorScheme.HotNormal;
- int trackingColor = ColorScheme.HotFocus;
-
// What columns to render at what X offset in viewport
Dictionary columnsToRender = CalculateViewport(bounds);
- Driver.SetAttribute (ColorScheme.HotNormal);
+ Driver.SetAttribute (ColorScheme.Normal);
//invalidate current row (prevents scrolling around leaving old characters in the frame
Driver.AddStr(new string (' ',bounds.Width));
-
+
// Render the headers
foreach(var kvp in columnsToRender) {
Move (kvp.Value,0);
- Driver.AddStr(kvp.Key.ColumnName+ SeparatorSymbol);
+ Driver.AddStr(Truncate(kvp.Key.ColumnName+ SeparatorSymbol,bounds.Width - kvp.Value));
}
//render the cells
@@ -114,6 +109,7 @@ namespace Terminal.Gui.Views {
//invalidate current row (prevents scrolling around leaving old characters in the frame
Move (0,line);
+ Driver.SetAttribute(ColorScheme.Normal);
Driver.AddStr(new string (' ',bounds.Width));
//work out what Row to render
@@ -125,7 +121,14 @@ namespace Terminal.Gui.Views {
foreach(var kvp in columnsToRender) {
Move (kvp.Value,line);
- Driver.AddStr(GetRenderedVal(Table.Rows[rowToRender][kvp.Key]) + SeparatorSymbol);
+
+ bool isSelectedCell = rowToRender == SelectedRow && kvp.Key.Ordinal == SelectedColumn;
+
+ Driver.SetAttribute(isSelectedCell? ColorScheme.HotFocus: ColorScheme.Normal);
+
+
+ var valueToRender = GetRenderedVal(Table.Rows[rowToRender][kvp.Key]) + SeparatorSymbol;
+ Driver.AddStr(Truncate(valueToRender,bounds.Width - kvp.Value ));
}
}
@@ -138,50 +141,101 @@ namespace Terminal.Gui.Views {
}
}
-
+
+ private ustring Truncate (string valueToRender, int availableHorizontalSpace)
+ {
+ if(string.IsNullOrEmpty(valueToRender) || valueToRender.Length < availableHorizontalSpace)
+ return valueToRender;
+
+ return valueToRender.Substring(0,availableHorizontalSpace);
+ }
+
///
public override bool ProcessKey (KeyEvent keyEvent)
{
switch (keyEvent.Key) {
case Key.CursorLeft:
- ColumnOffset--;
+ SelectedColumn--;
+ RefreshViewport();
break;
case Key.CursorRight:
- ColumnOffset++;
+ SelectedColumn++;
+ RefreshViewport();
break;
case Key.CursorDown:
- RowOffset++;
+ SelectedRow++;
+ RefreshViewport();
break;
case Key.CursorUp:
- RowOffset--;
+ SelectedRow--;
+ RefreshViewport();
break;
case Key.PageUp:
- RowOffset -= Frame.Height;
+ SelectedRow -= Frame.Height;
+ RefreshViewport();
break;
- case Key.V | Key.CtrlMask:
case Key.PageDown:
- RowOffset += Frame.Height;
+ SelectedRow += Frame.Height;
+ RefreshViewport();
break;
case Key.Home | Key.CtrlMask:
- RowOffset = 0;
- ColumnOffset = 0;
+ SelectedRow = 0;
+ SelectedColumn = 0;
+ RefreshViewport();
break;
case Key.Home:
- ColumnOffset = 0;
+ SelectedColumn = 0;
+ RefreshViewport();
break;
case Key.End | Key.CtrlMask:
//jump to end of table
- RowOffset = Table.Rows.Count-1;
- ColumnOffset = Table.Columns.Count-1;
+ SelectedRow = Table.Rows.Count-1;
+ SelectedColumn = Table.Columns.Count-1;
+ RefreshViewport();
break;
case Key.End:
//jump to end of row
- ColumnOffset = Table.Columns.Count-1;
+ SelectedColumn = Table.Columns.Count-1;
+ RefreshViewport();
break;
}
PositionCursor ();
return true;
}
+
+ ///
+ /// Updates the viewport ( / ) to ensure that the users selected cell is visible and redraws control
+ ///
+ /// This always calls
+ public void RefreshViewport ()
+ {
+ //TODO: implement
+
+ Dictionary columnsToRender = CalculateViewport(Bounds);
+
+
+ //if we have scrolled too far to the left
+ if(SelectedColumn < columnsToRender.Keys.Min(col=>col.Ordinal)) {
+ ColumnOffset = SelectedColumn;
+ }
+
+ //if we have scrolled too far to the right
+ if(SelectedColumn > columnsToRender.Keys.Max(col=>col.Ordinal)) {
+ ColumnOffset = SelectedColumn;
+ }
+
+ //if we have scrolled too far down
+ if(SelectedRow > RowOffset + Bounds.Height-1) {
+ RowOffset = SelectedRow;
+ }
+ //if we have scrolled too far up
+ if(SelectedRow < RowOffset) {
+ RowOffset = SelectedRow;
+ }
+
+ SetNeedsDisplay();
+ }
+
///
/// Calculates which columns should be rendered given the in which to display and the
///