diff --git a/Terminal.Gui/Views/TableView.cs b/Terminal.Gui/Views/TableView.cs
index 7ce5b0e0d..db18988ea 100644
--- a/Terminal.Gui/Views/TableView.cs
+++ b/Terminal.Gui/Views/TableView.cs
@@ -579,6 +579,22 @@ namespace Terminal.Gui {
return true;
}
+ ///
+ /// Positions the cursor in the area of the screen in which the start of the active cell is rendered. Calls base implementation if active cell is not visible due to scrolling or table is loaded etc
+ ///
+ public override void PositionCursor()
+ {
+ if(Table == null) {
+ base.PositionCursor();
+ return;
+ }
+
+ var screenPoint = CellToScreen(SelectedColumn,SelectedRow);
+
+ if(screenPoint != null)
+ Move(screenPoint.Value.X,screenPoint.Value.Y);
+ }
+
///
public override bool MouseEvent (MouseEvent me)
{
@@ -625,23 +641,12 @@ namespace Terminal.Gui {
if(me.Flags == MouseFlags.Button1Clicked) {
- var viewPort = CalculateViewport(Bounds);
-
- var headerHeight = ShouldRenderHeaders()? GetHeaderHeight():0;
+ var hit = ScreenToCell(me.OfX,me.OfY);
- var col = viewPort.LastOrDefault(c=>c.X <= me.OfX);
-
- // Click is on the header section of rendered UI
- if(me.OfY < headerHeight)
- return false;
-
- var rowIdx = RowOffset - headerHeight + me.OfY;
-
- if(col != null && rowIdx >= 0) {
+ if(hit != null) {
- SelectedRow = rowIdx;
- SelectedColumn = col.Column.Ordinal;
-
+ SelectedRow = hit.Value.Y;
+ SelectedColumn = hit.Value.X;
Update();
}
}
@@ -649,6 +654,68 @@ namespace Terminal.Gui {
return false;
}
+ ///
+ /// Returns the column and row of that corresponds to a given point on the screen (relative to the control client area). Returns null if the point is in the header, no table is loaded or outside the control bounds
+ ///
+ /// X offset from the top left of the control
+ /// Y offset from the top left of the control
+ ///
+ public Point? ScreenToCell (int clientX, int clientY)
+ {
+ if(Table == null)
+ return null;
+
+ var viewPort = CalculateViewport(Bounds);
+
+ var headerHeight = ShouldRenderHeaders()? GetHeaderHeight():0;
+
+ var col = viewPort.LastOrDefault(c=>c.X <= clientX);
+
+ // Click is on the header section of rendered UI
+ if(clientY < headerHeight)
+ return null;
+
+ var rowIdx = RowOffset - headerHeight + clientY;
+
+ if(col != null && rowIdx >= 0) {
+
+ return new Point(col.Column.Ordinal,rowIdx);
+ }
+
+ return null;
+ }
+
+ ///
+ /// Returns the screen position (relative to the control client area) that the given cell is rendered or null if it is outside the current scroll area or no table is loaded
+ ///
+ /// The index of the column you are looking for, use
+ /// The index of the row in that you are looking for
+ ///
+ public Point? CellToScreen (int tableColumn, int tableRow)
+ {
+ if(Table == null)
+ return null;
+
+ var viewPort = CalculateViewport(Bounds);
+
+ var headerHeight = ShouldRenderHeaders()? GetHeaderHeight():0;
+
+ var colHit = viewPort.FirstOrDefault(c=>c.Column.Ordinal == tableColumn);
+
+ // current column is outside the scroll area
+ if(colHit == null)
+ return null;
+
+ // the cell is too far up above the current scroll area
+ if(RowOffset > tableRow)
+ return null;
+
+ // the cell is way down below the scroll area and off the screen
+ if(tableRow > RowOffset + (Bounds.Height - headerHeight))
+ return null;
+
+ return new Point(colHit.X,tableRow + headerHeight - RowOffset);
+ }
///
/// Updates the view to reflect changes to and to ( / ) etc
///