Skip to content

Commit 82eff23

Browse files
committed
Merge branch 'main' of tig:migueldeicaza/gui.cs
2 parents 63d50cc + d68a2e8 commit 82eff23

File tree

4 files changed

+150
-1
lines changed

4 files changed

+150
-1
lines changed

Terminal.Gui/Views/TableView.cs

+59
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ public CellActivatedEventArgs (DataTable t, int col, int row)
6060
private TableStyle style = new TableStyle ();
6161
private Key cellActivationKey = Key.Enter;
6262

63+
Point? scrollLeftPoint;
64+
Point? scrollRightPoint;
65+
6366
/// <summary>
6467
/// The default maximum cell width for <see cref="TableView.MaxCellWidth"/> and <see cref="ColumnStyle.MaxWidth"/>
6568
/// </summary>
@@ -261,6 +264,9 @@ public override void Redraw (Rect bounds)
261264
Move (0, 0);
262265
var frame = Frame;
263266

267+
scrollRightPoint = null;
268+
scrollLeftPoint = null;
269+
264270
// What columns to render at what X offset in viewport
265271
var columnsToRender = CalculateViewport (bounds).ToArray ();
266272

@@ -420,19 +426,46 @@ private void RenderHeaderUnderline (int row, int availableWidth, ColumnToRender
420426

421427
for (int c = 0; c < availableWidth; c++) {
422428

429+
// Start by assuming we just draw a straight line the
430+
// whole way but update to instead draw a header indicator
431+
// or scroll arrow etc
423432
var rune = Driver.HLine;
424433

425434
if (Style.ShowVerticalHeaderLines) {
426435
if (c == 0) {
436+
// for first character render line
427437
rune = Style.ShowVerticalCellLines ? Driver.LeftTee : Driver.LLCorner;
438+
439+
// unless we have horizontally scrolled along
440+
// in which case render an arrow, to indicate user
441+
// can scroll left
442+
if(Style.ShowHorizontalScrollIndicators && ColumnOffset > 0)
443+
{
444+
rune = Driver.LeftArrow;
445+
scrollLeftPoint = new Point(c,row);
446+
}
447+
428448
}
429449
// if the next column is the start of a header
430450
else if (columnsToRender.Any (r => r.X == c + 1)) {
431451

432452
/*TODO: is ┼ symbol in Driver?*/
433453
rune = Style.ShowVerticalCellLines ? '┼' : Driver.BottomTee;
434454
} else if (c == availableWidth - 1) {
455+
456+
// for the last character in the table
435457
rune = Style.ShowVerticalCellLines ? Driver.RightTee : Driver.LRCorner;
458+
459+
// unless there is more of the table we could horizontally
460+
// scroll along to see. In which case render an arrow,
461+
// to indicate user can scroll right
462+
if(Style.ShowHorizontalScrollIndicators &&
463+
ColumnOffset + columnsToRender.Length < Table.Columns.Count)
464+
{
465+
rune = Driver.RightArrow;
466+
scrollRightPoint = new Point(c,row);
467+
}
468+
436469
}
437470
// if the next console column is the lastcolumns end
438471
else if (Style.ExpandLastColumn == false &&
@@ -898,6 +931,24 @@ public override bool MouseEvent (MouseEvent me)
898931

899932
if (me.Flags.HasFlag (MouseFlags.Button1Clicked)) {
900933

934+
if (scrollLeftPoint != null
935+
&& scrollLeftPoint.Value.X == me.X
936+
&& scrollLeftPoint.Value.Y == me.Y)
937+
{
938+
ColumnOffset--;
939+
EnsureValidScrollOffsets ();
940+
SetNeedsDisplay ();
941+
}
942+
943+
if (scrollRightPoint != null
944+
&& scrollRightPoint.Value.X == me.X
945+
&& scrollRightPoint.Value.Y == me.Y)
946+
{
947+
ColumnOffset++;
948+
EnsureValidScrollOffsets ();
949+
SetNeedsDisplay ();
950+
}
951+
901952
var hit = ScreenToCell (me.X, me.Y);
902953
if (hit != null) {
903954

@@ -1369,6 +1420,14 @@ public class TableStyle {
13691420
/// </summary>
13701421
public bool ShowVerticalHeaderLines { get; set; } = true;
13711422

1423+
/// <summary>
1424+
/// True to render a arrows on the right/left of the table when
1425+
/// there are more column(s) that can be scrolled to. Requires
1426+
/// <see cref="ShowHorizontalHeaderUnderline"/> to be true.
1427+
/// Defaults to true
1428+
/// </summary>
1429+
public bool ShowHorizontalScrollIndicators { get; set; } = true;
1430+
13721431
/// <summary>
13731432
/// True to invert the colors of the first symbol of the selected cell in the <see cref="TableView"/>.
13741433
/// This gives the appearance of a cursor for when the <see cref="ConsoleDriver"/> doesn't otherwise show

UICatalog/Scenarios/TableEditor.cs

+9-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ public class TableEditor : Scenario
2020
private MenuItem miHeaderOverline;
2121
private MenuItem miHeaderMidline;
2222
private MenuItem miHeaderUnderline;
23+
private MenuItem miShowHorizontalScrollIndicators;
2324
private MenuItem miCellLines;
2425
private MenuItem miFullRowSelect;
2526
private MenuItem miExpandLastColumn;
@@ -55,7 +56,8 @@ public override void Setup ()
5556
miAlwaysShowHeaders = new MenuItem ("_AlwaysShowHeaders", "", () => ToggleAlwaysShowHeader()){Checked = tableView.Style.AlwaysShowHeaders, CheckType = MenuItemCheckStyle.Checked },
5657
miHeaderOverline = new MenuItem ("_HeaderOverLine", "", () => ToggleOverline()){Checked = tableView.Style.ShowHorizontalHeaderOverline, CheckType = MenuItemCheckStyle.Checked },
5758
miHeaderMidline = new MenuItem ("_HeaderMidLine", "", () => ToggleHeaderMidline()){Checked = tableView.Style.ShowVerticalHeaderLines, CheckType = MenuItemCheckStyle.Checked },
58-
miHeaderUnderline =new MenuItem ("_HeaderUnderLine", "", () => ToggleUnderline()){Checked = tableView.Style.ShowHorizontalHeaderUnderline, CheckType = MenuItemCheckStyle.Checked },
59+
miHeaderUnderline = new MenuItem ("_HeaderUnderLine", "", () => ToggleUnderline()){Checked = tableView.Style.ShowHorizontalHeaderUnderline, CheckType = MenuItemCheckStyle.Checked },
60+
miShowHorizontalScrollIndicators = new MenuItem ("_HorizontalScrollIndicators", "", () => ToggleHorizontalScrollIndicators()){Checked = tableView.Style.ShowHorizontalScrollIndicators, CheckType = MenuItemCheckStyle.Checked },
5961
miFullRowSelect =new MenuItem ("_FullRowSelect", "", () => ToggleFullRowSelect()){Checked = tableView.FullRowSelect, CheckType = MenuItemCheckStyle.Checked },
6062
miCellLines =new MenuItem ("_CellLines", "", () => ToggleCellLines()){Checked = tableView.Style.ShowVerticalCellLines, CheckType = MenuItemCheckStyle.Checked },
6163
miExpandLastColumn = new MenuItem ("_ExpandLastColumn", "", () => ToggleExpandLastColumn()){Checked = tableView.Style.ExpandLastColumn, CheckType = MenuItemCheckStyle.Checked },
@@ -205,6 +207,12 @@ private void ToggleUnderline ()
205207
tableView.Style.ShowHorizontalHeaderUnderline = miHeaderUnderline.Checked;
206208
tableView.Update();
207209
}
210+
private void ToggleHorizontalScrollIndicators ()
211+
{
212+
miShowHorizontalScrollIndicators.Checked = !miShowHorizontalScrollIndicators.Checked;
213+
tableView.Style.ShowHorizontalScrollIndicators = miShowHorizontalScrollIndicators.Checked;
214+
tableView.Update();
215+
}
208216
private void ToggleFullRowSelect ()
209217
{
210218
miFullRowSelect.Checked = !miFullRowSelect.Checked;

UICatalog/Scenarios/TreeUseCases.cs

+3
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ private void LoadRooms ()
7575

7676
if (currentTree != null) {
7777
Win.Remove (currentTree);
78+
currentTree.Dispose ();
7879
}
7980

8081

@@ -148,6 +149,7 @@ private void LoadArmies (bool useDelegate)
148149

149150
if (currentTree != null) {
150151
Win.Remove (currentTree);
152+
currentTree.Dispose ();
151153
}
152154

153155

@@ -180,6 +182,7 @@ private void LoadSimpleNodes ()
180182
{
181183
if (currentTree != null) {
182184
Win.Remove (currentTree);
185+
currentTree.Dispose ();
183186
}
184187

185188

UnitTests/TableViewTests.cs

+79
Original file line numberDiff line numberDiff line change
@@ -778,6 +778,85 @@ public void ScrollRight_WithoutSmoothScrolling ()
778778
Application.Shutdown ();
779779
}
780780

781+
782+
[Fact]
783+
public void ScrollIndicators ()
784+
{
785+
GraphViewTests.InitFakeDriver ();
786+
787+
var tableView = new TableView ();
788+
tableView.ColorScheme = Colors.TopLevel;
789+
790+
// 3 columns are visibile
791+
tableView.Bounds = new Rect (0, 0, 7, 5);
792+
tableView.Style.ShowHorizontalHeaderUnderline = true;
793+
tableView.Style.ShowHorizontalHeaderOverline = false;
794+
tableView.Style.AlwaysShowHeaders = true;
795+
tableView.Style.SmoothHorizontalScrolling = true;
796+
797+
var dt = new DataTable ();
798+
dt.Columns.Add ("A");
799+
dt.Columns.Add ("B");
800+
dt.Columns.Add ("C");
801+
dt.Columns.Add ("D");
802+
dt.Columns.Add ("E");
803+
dt.Columns.Add ("F");
804+
805+
dt.Rows.Add (1, 2, 3, 4, 5, 6);
806+
807+
tableView.Table = dt;
808+
809+
// select last visible column
810+
tableView.SelectedColumn = 2; // column C
811+
812+
tableView.Redraw (tableView.Bounds);
813+
814+
// user can only scroll right so sees right indicator
815+
// Because first column in table is A
816+
string expected =
817+
@"
818+
│A│B│C│
819+
├─┼─┼─►
820+
│1│2│3│";
821+
822+
GraphViewTests.AssertDriverContentsAre (expected, output);
823+
824+
825+
// Scroll right
826+
tableView.ProcessKey (new KeyEvent () { Key = Key.CursorRight });
827+
828+
829+
// since A is now pushed off screen we get indicator showing
830+
// that user can scroll left to see first column
831+
tableView.Redraw (tableView.Bounds);
832+
833+
expected =
834+
@"
835+
│B│C│D│
836+
◄─┼─┼─►
837+
│2│3│4│";
838+
839+
GraphViewTests.AssertDriverContentsAre (expected, output);
840+
841+
842+
// Scroll right twice more (to end of columns)
843+
tableView.ProcessKey (new KeyEvent () { Key = Key.CursorRight });
844+
tableView.ProcessKey (new KeyEvent () { Key = Key.CursorRight });
845+
846+
tableView.Redraw (tableView.Bounds);
847+
848+
expected =
849+
@"
850+
│D│E│F│
851+
◄─┼─┼─┤
852+
│4│5│6│";
853+
854+
GraphViewTests.AssertDriverContentsAre (expected, output);
855+
856+
// Shutdown must be called to safely clean up Application if Init has been called
857+
Application.Shutdown ();
858+
}
859+
781860
/// <summary>
782861
/// Builds a simple table of string columns with the requested number of columns and rows
783862
/// </summary>

0 commit comments

Comments
 (0)