Skip to content

Commit

Permalink
Builds CollectionNavigator support into UI Catalog for TableView (#2584)
Browse files Browse the repository at this point in the history
* Builds collectionnav support into UI cat for TableView

* Fixes keyboard mapping

* MultiSelect = false for TableView

* MultiSelect = false doesn't unbind ctrl-a
  • Loading branch information
tig committed May 1, 2023
1 parent 105ff9a commit 5cf90b8
Show file tree
Hide file tree
Showing 11 changed files with 114 additions and 83 deletions.
8 changes: 4 additions & 4 deletions Terminal.Gui/View/ViewKeyboard.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public virtual Key HotKey {
var v = value == Key.Unknown ? Key.Null : value;
if (_hotKey != Key.Null && ContainsKeyBinding (Key.Space | _hotKey)) {
if (v == Key.Null) {
ClearKeybinding (Key.Space | _hotKey);
ClearKeyBinding (Key.Space | _hotKey);
} else {
ReplaceKeyBinding (Key.Space | _hotKey, Key.Space | v);
}
Expand Down Expand Up @@ -273,7 +273,7 @@ public bool ContainsKeyBinding (Key key)
/// <summary>
/// Removes all bound keys from the View and resets the default bindings.
/// </summary>
public void ClearKeybindings ()
public void ClearKeyBindings ()
{
KeyBindings.Clear ();
}
Expand All @@ -282,7 +282,7 @@ public void ClearKeybindings ()
/// Clears the existing keybinding (if any) for the given <paramref name="key"/>.
/// </summary>
/// <param name="key"></param>
public void ClearKeybinding (Key key)
public void ClearKeyBinding (Key key)
{
KeyBindings.Remove (key);
}
Expand All @@ -292,7 +292,7 @@ public void ClearKeybinding (Key key)
/// keys bound to the same command and this method will clear all of them.
/// </summary>
/// <param name="command"></param>
public void ClearKeybinding (params Command [] command)
public void ClearKeyBinding (params Command [] command)
{
foreach (var kvp in KeyBindings.Where (kvp => kvp.Value.SequenceEqual (command)).ToArray ()) {
KeyBindings.Remove (kvp.Key);
Expand Down
2 changes: 1 addition & 1 deletion Terminal.Gui/Views/Button.cs
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ public override Key HotKey {
var v = value == Key.Unknown ? Key.Null : value;
if (base.HotKey != Key.Null && ContainsKeyBinding (Key.Space | base.HotKey)) {
if (v == Key.Null) {
ClearKeybinding (Key.Space | base.HotKey);
ClearKeyBinding (Key.Space | base.HotKey);
} else {
ReplaceKeyBinding (Key.Space | base.HotKey, Key.Space | v);
}
Expand Down
2 changes: 1 addition & 1 deletion Terminal.Gui/Views/ListView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ public bool AllowsMarking {
if (allowsMarking) {
AddKeyBinding (Key.Space, Command.ToggleChecked);
} else {
ClearKeybinding (Key.Space);
ClearKeyBinding (Key.Space);
}

SetNeedsDisplay ();
Expand Down
101 changes: 50 additions & 51 deletions Terminal.Gui/Views/TableView/TableView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Collections.Generic;
using System.Data;
using System.Linq;
using static Terminal.Gui.SpinnerStyle;

namespace Terminal.Gui {

Expand Down Expand Up @@ -38,7 +39,13 @@ public class TableView : View {
/// <summary>
/// The data table to render in the view. Setting this property automatically updates and redraws the control.
/// </summary>
public ITableSource Table { get => table; set { table = value; Update (); } }
public ITableSource Table {
get => table;
set {
table = value;
Update ();
}
}

/// <summary>
/// Contains options for changing how the table is rendered
Expand Down Expand Up @@ -285,9 +292,9 @@ public override void Redraw (Rect bounds)
continue;

// No more data
if(rowToRender >= Table.Rows) {
if (rowToRender >= Table.Rows) {

if(rowToRender == Table.Rows && Style.ShowHorizontalBottomline) {
if (rowToRender == Table.Rows && Style.ShowHorizontalBottomline) {
RenderBottomLine (line, bounds.Width, columnsToRender);
}

Expand Down Expand Up @@ -383,7 +390,7 @@ private void RenderHeaderMidline (int row, ColumnToRender [] columnsToRender)
var current = columnsToRender [i];

var colStyle = Style.GetColumnStyleIfAny (current.Column);
var colName = table.ColumnNames[current.Column];
var colName = table.ColumnNames [current.Column];

RenderSeparator (current.X - 1, row, true);

Expand Down Expand Up @@ -507,7 +514,7 @@ private void RenderBottomLine (int row, int availableWidth, ColumnToRender [] co
}
// if the next column is the start of a header
else if (columnsToRender.Any (r => r.X == c + 1)) {
rune = Driver.BottomTee;
rune = Driver.BottomTee;
} else if (c == availableWidth - 1) {

// for the last character in the table
Expand Down Expand Up @@ -610,7 +617,7 @@ private void RenderRow (int row, int rowToRender, ColumnToRender [] columnsToRen
if (!FullRowSelect)
Driver.SetAttribute (Enabled ? rowScheme.Normal : rowScheme.Disabled);

if(style.AlwaysUseNormalColorForVerticalCellLines && style.ShowVerticalCellLines) {
if (style.AlwaysUseNormalColorForVerticalCellLines && style.ShowVerticalCellLines) {

Driver.SetAttribute (rowScheme.Normal);
}
Expand All @@ -630,7 +637,7 @@ private void RenderRow (int row, int rowToRender, ColumnToRender [] columnsToRen
AddRune (0, row, Driver.VLine);
AddRune (Bounds.Width - 1, row, Driver.VLine);
}

}

/// <summary>
Expand Down Expand Up @@ -694,7 +701,7 @@ void AddRuneAt (ConsoleDriver d, int col, int row, Rune ch)
private string TruncateOrPad (object originalCellValue, string representation, int availableHorizontalSpace, ColumnStyle colStyle)
{
if (string.IsNullOrEmpty (representation))
return new string(' ',availableHorizontalSpace);
return new string (' ', availableHorizontalSpace);

// if value is not wide enough
if (representation.Sum (c => Rune.ColumnWidth (c)) < availableHorizontalSpace) {
Expand Down Expand Up @@ -723,6 +730,8 @@ private string TruncateOrPad (object originalCellValue, string representation, i
return new string (representation.TakeWhile (c => (availableHorizontalSpace -= Rune.ColumnWidth (c)) > 0).ToArray ());
}



/// <inheritdoc/>
public override bool ProcessKey (KeyEvent keyEvent)
{
Expand Down Expand Up @@ -761,7 +770,7 @@ public void SetSelection (int col, int row, bool extendExistingSelection)
if (extendExistingSelection) {

// If we are extending current selection but there isn't one
if (MultiSelectedRegions.Count == 0 || MultiSelectedRegions.All(m=>m.IsToggled)) {
if (MultiSelectedRegions.Count == 0 || MultiSelectedRegions.All (m => m.IsToggled)) {
// Create a new region between the old active cell and the new cell
var rect = CreateTableSelection (SelectedColumn, SelectedRow, col, row);
MultiSelectedRegions.Push (rect);
Expand Down Expand Up @@ -928,14 +937,13 @@ public void SelectAll ()
/// <returns></returns>
public IEnumerable<Point> GetAllSelectedCells ()
{
if (TableIsNullOrInvisible () || Table.Rows == 0)
{
return Enumerable.Empty<Point>();
if (TableIsNullOrInvisible () || Table.Rows == 0) {
return Enumerable.Empty<Point> ();
}

EnsureValidSelection ();

var toReturn = new HashSet<Point>();
var toReturn = new HashSet<Point> ();

// If there are one or more rectangular selections
if (MultiSelect && MultiSelectedRegions.Any ()) {
Expand All @@ -950,26 +958,26 @@ public IEnumerable<Point> GetAllSelectedCells ()
for (int y = yMin; y < yMax; y++) {
for (int x = xMin; x < xMax; x++) {
if (IsSelected (x, y)) {
toReturn.Add(new Point (x, y));
toReturn.Add (new Point (x, y));
}
}
}
}
}

// if there are no region selections then it is just the active cell

// if we are selecting the full row
if (FullRowSelect) {
// all cells in active row are selected
for (int x = 0; x < Table.Columns; x++) {
toReturn.Add(new Point (x, SelectedRow));
toReturn.Add (new Point (x, SelectedRow));
}
} else {
// Not full row select and no multi selections
toReturn.Add(new Point (SelectedColumn, SelectedRow));
toReturn.Add (new Point (SelectedColumn, SelectedRow));
}

return toReturn;
return toReturn;
}

/// <summary>
Expand Down Expand Up @@ -1001,8 +1009,8 @@ private void ToggleCurrentCellSelection ()
return;
}

var regions = GetMultiSelectedRegionsContaining(selectedColumn, selectedRow).ToArray();
var toggles = regions.Where(s=>s.IsToggled).ToArray ();
var regions = GetMultiSelectedRegionsContaining (selectedColumn, selectedRow).ToArray ();
var toggles = regions.Where (s => s.IsToggled).ToArray ();

// Toggle it off
if (toggles.Any ()) {
Expand All @@ -1015,17 +1023,14 @@ private void ToggleCurrentCellSelection ()
MultiSelectedRegions.Push (region);
}
} else {

// user is toggling selection within a rectangular
// select. So toggle the full region
if(regions.Any())
{
foreach(var r in regions)
{
if (regions.Any ()) {
foreach (var r in regions) {
r.IsToggled = true;
}
}
else{
} else {
// Toggle on a single cell selection
MultiSelectedRegions.Push (
CreateTableSelection (selectedColumn, SelectedRow, selectedColumn, selectedRow, true)
Expand Down Expand Up @@ -1060,28 +1065,23 @@ public bool IsSelected (int col, int row)
return false;
}

if(GetMultiSelectedRegionsContaining(col,row).Any())
{
if (GetMultiSelectedRegionsContaining (col, row).Any ()) {
return true;
}

return row == SelectedRow &&
(col == SelectedColumn || FullRowSelect);
}

private IEnumerable<TableSelection> GetMultiSelectedRegionsContaining(int col, int row)
private IEnumerable<TableSelection> GetMultiSelectedRegionsContaining (int col, int row)
{
if(!MultiSelect)
{
return Enumerable.Empty<TableSelection>();
if (!MultiSelect) {
return Enumerable.Empty<TableSelection> ();
}

if(FullRowSelect)
{

if (FullRowSelect) {
return MultiSelectedRegions.Where (r => r.Rect.Bottom > row && r.Rect.Top <= row);
}
else
{
} else {
return MultiSelectedRegions.Where (r => r.Rect.Contains (col, row));
}
}
Expand Down Expand Up @@ -1388,7 +1388,7 @@ private bool TableIsNullOrInvisible ()
{
return Table == null ||
Table.Columns <= 0 ||
Enumerable.Range(0,Table.Columns).All (
Enumerable.Range (0, Table.Columns).All (
c => (Style.GetColumnStyleIfAny (c)?.Visible ?? true) == false);
}

Expand Down Expand Up @@ -1424,8 +1424,8 @@ private bool TryGetNearestVisibleColumn (int columnIndex, bool lookRight, bool a
}

// get the column visibility by index (if no style visible is true)
bool [] columnVisibility =
Enumerable.Range(0,Table.Columns)
bool [] columnVisibility =
Enumerable.Range (0, Table.Columns)
.Select (c => this.Style.GetColumnStyleIfAny (c)?.Visible ?? true)
.ToArray ();

Expand Down Expand Up @@ -1526,7 +1526,7 @@ public void EnsureSelectedCellIsVisible ()
/// </summary>
protected virtual void OnSelectedCellChanged (SelectedCellChangedEventArgs args)
{
SelectedCellChanged?.Invoke (this,args);
SelectedCellChanged?.Invoke (this, args);
}

/// <summary>
Expand All @@ -1548,7 +1548,7 @@ private IEnumerable<ColumnToRender> CalculateViewport (Rect bounds, int padding
{
if (TableIsNullOrInvisible ()) {
return Enumerable.Empty<ColumnToRender> ();
}
}

var toReturn = new List<ColumnToRender> ();
int usedSpace = 0;
Expand All @@ -1568,7 +1568,7 @@ private IEnumerable<ColumnToRender> CalculateViewport (Rect bounds, int padding
var lastColumn = Table.Columns - 1;

// TODO : Maybe just a for loop?
foreach (var col in Enumerable.Range(0,Table.Columns).Skip (ColumnOffset)) {
foreach (var col in Enumerable.Range (0, Table.Columns).Skip (ColumnOffset)) {

int startingIdxForCurrentHeader = usedSpace;
var colStyle = Style.GetColumnStyleIfAny (col);
Expand Down Expand Up @@ -1618,12 +1618,11 @@ private IEnumerable<ColumnToRender> CalculateViewport (Rect bounds, int padding
var isVeryLast = lastColumn == col;

// there is space
toReturn.Add(new ColumnToRender (col, startingIdxForCurrentHeader, colWidth, isVeryLast));
toReturn.Add (new ColumnToRender (col, startingIdxForCurrentHeader, colWidth, isVeryLast));
first = false;
}

if(Style.ExpandLastColumn)
{
if (Style.ExpandLastColumn) {
var last = toReturn.Last ();
last.Width = Math.Max (last.Width, availableHorizontalSpace - last.X);
}
Expand All @@ -1648,7 +1647,7 @@ private bool ShouldRenderHeaders ()
/// <returns></returns>
private int CalculateMaxCellWidth (int col, int rowsToRender, ColumnStyle colStyle)
{
int spaceRequired = table.ColumnNames[col].Sum (c => Rune.ColumnWidth (c));
int spaceRequired = table.ColumnNames [col].Sum (c => Rune.ColumnWidth (c));

// if table has no rows
if (RowOffset < 0)
Expand All @@ -1660,7 +1659,7 @@ private int CalculateMaxCellWidth (int col, int rowsToRender, ColumnStyle colSty
//expand required space if cell is bigger than the last biggest cell or header
spaceRequired = Math.Max (
spaceRequired,
GetRepresentation (Table [i,col], colStyle).Sum (c => Rune.ColumnWidth (c)));
GetRepresentation (Table [i, col], colStyle).Sum (c => Rune.ColumnWidth (c)));
}

// Don't require more space than the style allows
Expand Down Expand Up @@ -1861,7 +1860,7 @@ public class TableStyle {
/// </summary>
public bool ShowHorizontalScrollIndicators { get; set; } = true;


/// <summary>
/// Gets or sets a flag indicating whether there should be a horizontal line after all the data
/// in the table. Defaults to <see langword="false"/>.
Expand Down
2 changes: 1 addition & 1 deletion Terminal.Gui/Views/Wizard/Wizard.cs
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ public Wizard () : base () {
TitleChanged += Wizard_TitleChanged;

if (Modal) {
ClearKeybinding (Command.QuitToplevel);
ClearKeyBinding (Command.QuitToplevel);
AddKeyBinding (Key.Esc, Command.QuitToplevel);
}
SetNeedsLayout ();
Expand Down
2 changes: 1 addition & 1 deletion UICatalog/KeyBindingsDialog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ private void ApplyKeyBindingsToAllKnownViews ()
if(supported.Contains(kvp.Key))
{
// if the key was bound to any other commands clear that
view.ClearKeybinding (kvp.Key);
view.ClearKeyBinding (kvp.Key);
view.AddKeyBinding (kvp.Value,kvp.Key);
}

Expand Down
2 changes: 1 addition & 1 deletion UICatalog/Scenarios/ASCIICustomButton.cs
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ public ScrollViewTestWindow ()
};
}

scrollView.ClearKeybindings ();
scrollView.ClearKeyBindings ();

buttons = new List<Button> ();
Button prevButton = null;
Expand Down
4 changes: 2 additions & 2 deletions UICatalog/Scenarios/Text.cs
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,8 @@ void TextView_DrawContent (object sender, DrawEventArgs e)
textView.AddKeyBinding (keyTab, Command.Tab);
textView.AddKeyBinding (keyBackTab, Command.BackTab);
} else {
textView.ClearKeybinding (keyTab);
textView.ClearKeybinding (keyBackTab);
textView.ClearKeyBinding (keyTab);
textView.ClearKeyBinding (keyBackTab);
}
textView.AllowsTab = (bool)e.NewValue;
};
Expand Down
Loading

0 comments on commit 5cf90b8

Please sign in to comment.