mirror of
https://github.com/gui-cs/Terminal.Gui.git
synced 2025-12-30 09:47:58 +01:00
Merge branch 'develop' into splitcontainer
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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)]
|
||||
|
||||
Reference in New Issue
Block a user