Merge branch 'develop' into splitcontainer

This commit is contained in:
Thomas Nind
2022-12-31 14:44:48 +00:00
committed by GitHub
2 changed files with 127 additions and 1 deletions

View File

@@ -761,6 +761,41 @@ namespace Terminal.Gui {
SelectedRow = row;
}
/// <summary>
/// Unions the current selected cell (and/or regions) with the provided cell and makes
/// it the active one.
/// </summary>
/// <param name="col"></param>
/// <param name="row"></param>
private void UnionSelection (int col, int row)
{
if (!MultiSelect || TableIsNullOrInvisible()) {
return;
}
EnsureValidSelection ();
var oldColumn = SelectedColumn;
var oldRow = SelectedRow;
// move us to the new cell
SelectedColumn = col;
SelectedRow = row;
MultiSelectedRegions.Push (
CreateTableSelection (col, row)
);
// if the old cell was not part of a rectangular select
// or otherwise selected we need to retain it in the selection
if (!IsSelected (oldColumn, oldRow)) {
MultiSelectedRegions.Push (
CreateTableSelection (oldColumn, oldRow)
);
}
}
/// <summary>
/// Moves the <see cref="SelectedRow"/> and <see cref="SelectedColumn"/> by the provided offsets. Optionally starting a box selection (see <see cref="MultiSelect"/>)
/// </summary>
@@ -852,6 +887,8 @@ namespace Terminal.Gui {
/// <summary>
/// Returns all cells in any <see cref="MultiSelectedRegions"/> (if <see cref="MultiSelect"/> is enabled) and the selected cell
/// </summary>
/// <remarks>Return value is not affected by <see cref="FullRowSelect"/> (i.e. returned <see cref="Point"/>s are not expanded to
/// include all points on row).</remarks>
/// <returns></returns>
public IEnumerable<Point> GetAllSelectedCells ()
{
@@ -914,6 +951,16 @@ namespace Terminal.Gui {
return new TableSelection (new Point (pt1X, pt1Y), new Rect (left, top, right - left + 1, bot - top + 1));
}
/// <summary>
/// Returns a single point as a <see cref="TableSelection"/>
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <returns></returns>
private TableSelection CreateTableSelection (int x, int y)
{
return CreateTableSelection (x, y, x, y);
}
/// <summary>
/// <para>
/// Returns true if the given cell is selected either because it is the active cell or part of a multi cell selection (e.g. <see cref="FullRowSelect"/>).
@@ -1039,7 +1086,12 @@ namespace Terminal.Gui {
var hit = ScreenToCell (me.X, me.Y);
if (hit != null) {
SetSelection (hit.Value.X, hit.Value.Y, me.Flags.HasFlag (MouseFlags.ButtonShift));
if(MultiSelect && HasControlOrAlt(me)) {
UnionSelection(hit.Value.X, hit.Value.Y);
} else {
SetSelection (hit.Value.X, hit.Value.Y, me.Flags.HasFlag (MouseFlags.ButtonShift));
}
Update ();
}
}
@@ -1055,6 +1107,11 @@ namespace Terminal.Gui {
return false;
}
private bool HasControlOrAlt (MouseEvent me)
{
return me.Flags.HasFlag (MouseFlags.ButtonAlt) || me.Flags.HasFlag (MouseFlags.ButtonCtrl);
}
/// <summary>.
/// Returns the column and row of <see cref="Table"/> that corresponds to a given point
/// on the screen (relative to the control client area). Returns null if the point is

View File

@@ -646,6 +646,75 @@ namespace Terminal.Gui.Views {
Application.Shutdown ();
}
[Fact, AutoInitShutdown]
public void TestShiftClick_MultiSelect_TwoRowTable_FullRowSelect()
{
var tv = GetTwoRowSixColumnTable ();
tv.MultiSelect = true;
// Clicking in bottom row
tv.MouseEvent (new MouseEvent {
X = 1,
Y = 3,
Flags = MouseFlags.Button1Clicked
});
// should select that row
Assert.Equal (1, tv.SelectedRow);
// shift clicking top row
tv.MouseEvent (new MouseEvent {
X = 1,
Y = 2,
Flags = MouseFlags.Button1Clicked | MouseFlags.ButtonShift
});
// should extend the selection
Assert.Equal (0, tv.SelectedRow);
var selected = tv.GetAllSelectedCells ().ToArray();
Assert.Contains (new Point(0,0), selected);
Assert.Contains (new Point (0, 1), selected);
}
[Fact, AutoInitShutdown]
public void TestControlClick_MultiSelect_ThreeRowTable_FullRowSelect ()
{
var tv = GetTwoRowSixColumnTable ();
tv.Table.Rows.Add (1, 2, 3, 4, 5, 6);
tv.MultiSelect = true;
// Clicking in bottom row
tv.MouseEvent (new MouseEvent {
X = 1,
Y = 4,
Flags = MouseFlags.Button1Clicked
});
// should select that row
Assert.Equal (2, tv.SelectedRow);
// shift clicking top row
tv.MouseEvent (new MouseEvent {
X = 1,
Y = 2,
Flags = MouseFlags.Button1Clicked | MouseFlags.ButtonCtrl
});
// should extend the selection
// to include bottom and top row but not middle
Assert.Equal (0, tv.SelectedRow);
var selected = tv.GetAllSelectedCells ().ToArray ();
Assert.Contains (new Point (0, 0), selected);
Assert.DoesNotContain (new Point (0, 1), selected);
Assert.Contains (new Point (0, 2), selected);
}
[Theory]
[InlineData (false)]
[InlineData (true)]