mirror of
https://github.com/gui-cs/Terminal.Gui.git
synced 2025-12-26 15:57:56 +01:00
Merge branch 'main' of tig:migueldeicaza/gui.cs
This commit is contained in:
@@ -60,6 +60,9 @@ namespace Terminal.Gui {
|
||||
private TableStyle style = new TableStyle ();
|
||||
private Key cellActivationKey = Key.Enter;
|
||||
|
||||
Point? scrollLeftPoint;
|
||||
Point? scrollRightPoint;
|
||||
|
||||
/// <summary>
|
||||
/// The default maximum cell width for <see cref="TableView.MaxCellWidth"/> and <see cref="ColumnStyle.MaxWidth"/>
|
||||
/// </summary>
|
||||
@@ -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 {
|
||||
/// </summary>
|
||||
public bool ShowVerticalHeaderLines { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// True to render a arrows on the right/left of the table when
|
||||
/// there are more column(s) that can be scrolled to. Requires
|
||||
/// <see cref="ShowHorizontalHeaderUnderline"/> to be true.
|
||||
/// Defaults to true
|
||||
/// </summary>
|
||||
public bool ShowHorizontalScrollIndicators { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// True to invert the colors of the first symbol of the selected cell in the <see cref="TableView"/>.
|
||||
/// This gives the appearance of a cursor for when the <see cref="ConsoleDriver"/> doesn't otherwise show
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 ();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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 ();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Builds a simple table of string columns with the requested number of columns and rows
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user