Add support for default choice in selection prompt

Closes #234
This commit is contained in:
Patrik Svensson 2021-01-15 16:32:32 +01:00 committed by Patrik Svensson
parent 63bae278a9
commit 913a7b1e37
3 changed files with 82 additions and 7 deletions

View File

@ -23,6 +23,11 @@ namespace Spectre.Console
/// </summary> /// </summary>
public List<T> Choices { get; } public List<T> Choices { get; }
/// <summary>
/// Gets the initially selected choices.
/// </summary>
public HashSet<int> Selected { get; }
/// <summary> /// <summary>
/// Gets or sets the converter to get the display string for a choice. By default /// Gets or sets the converter to get the display string for a choice. By default
/// the corresponding <see cref="TypeConverter"/> is used. /// the corresponding <see cref="TypeConverter"/> is used.
@ -52,6 +57,7 @@ namespace Spectre.Console
public MultiSelectionPrompt() public MultiSelectionPrompt()
{ {
Choices = new List<T>(); Choices = new List<T>();
Selected = new HashSet<int>();
} }
/// <inheritdoc/> /// <inheritdoc/>
@ -73,7 +79,7 @@ namespace Spectre.Console
var converter = Converter ?? TypeConverterHelper.ConvertToString; var converter = Converter ?? TypeConverterHelper.ConvertToString;
var list = new RenderableMultiSelectionList<T>(console, Title, PageSize, Choices, converter, HighlightStyle); var list = new RenderableMultiSelectionList<T>(console, Title, PageSize, Choices, Selected, converter, HighlightStyle);
using (new RenderHookScope(console, list)) using (new RenderHookScope(console, list))
{ {
console.Cursor.Hide(); console.Cursor.Hide();

View File

@ -44,6 +44,73 @@ namespace Spectre.Console
return obj; return obj;
} }
/// <summary>
/// Marks an item as selected.
/// </summary>
/// <typeparam name="T">The prompt result type.</typeparam>
/// <param name="obj">The prompt.</param>
/// <param name="index">The index of the item to select.</param>
/// <returns>The same instance so that multiple calls can be chained.</returns>
public static MultiSelectionPrompt<T> Select<T>(this MultiSelectionPrompt<T> obj, int index)
{
if (obj is null)
{
throw new ArgumentNullException(nameof(obj));
}
if (index < 0)
{
throw new ArgumentException("Index must be greater than zero", nameof(index));
}
obj.Selected.Add(index);
return obj;
}
/// <summary>
/// Marks multiple items as selected.
/// </summary>
/// <typeparam name="T">The prompt result type.</typeparam>
/// <param name="obj">The prompt.</param>
/// <param name="indices">The indices of the items to select.</param>
/// <returns>The same instance so that multiple calls can be chained.</returns>
public static MultiSelectionPrompt<T> Select<T>(this MultiSelectionPrompt<T> obj, params int[] indices)
{
if (obj is null)
{
throw new ArgumentNullException(nameof(obj));
}
foreach (var index in indices)
{
Select(obj, index);
}
return obj;
}
/// <summary>
/// Marks multiple items as selected.
/// </summary>
/// <typeparam name="T">The prompt result type.</typeparam>
/// <param name="obj">The prompt.</param>
/// <param name="indices">The indices of the items to select.</param>
/// <returns>The same instance so that multiple calls can be chained.</returns>
public static MultiSelectionPrompt<T> Select<T>(this MultiSelectionPrompt<T> obj, IEnumerable<int> indices)
{
if (obj is null)
{
throw new ArgumentNullException(nameof(obj));
}
foreach (var index in indices)
{
Select(obj, index);
}
return obj;
}
/// <summary> /// <summary>
/// Adds multiple choices. /// Adds multiple choices.
/// </summary> /// </summary>

View File

@ -17,14 +17,15 @@ namespace Spectre.Console
public RenderableMultiSelectionList( public RenderableMultiSelectionList(
IAnsiConsole console, string? title, int pageSize, IAnsiConsole console, string? title, int pageSize,
List<T> choices, Func<T, string>? converter, Style? highlightStyle) List<T> choices, HashSet<int> selections,
Func<T, string>? converter, Style? highlightStyle)
: base(console, pageSize, choices, converter) : base(console, pageSize, choices, converter)
{ {
_console = console ?? throw new ArgumentNullException(nameof(console)); _console = console ?? throw new ArgumentNullException(nameof(console));
_title = title; _title = title;
_highlightStyle = highlightStyle ?? new Style(foreground: Color.Blue); _highlightStyle = highlightStyle ?? new Style(foreground: Color.Blue);
Selections = new HashSet<int>(); Selections = new HashSet<int>(selections);
} }
public void Select() public void Select()
@ -52,7 +53,8 @@ namespace Spectre.Console
return pageSize; return pageSize;
} }
protected override IRenderable Build(int pointerIndex, bool scrollable, IEnumerable<(int Original, int Index, string Item)> choices) protected override IRenderable Build(int pointerIndex, bool scrollable,
IEnumerable<(int Original, int Index, string Item)> choices)
{ {
var list = new List<IRenderable>(); var list = new List<IRenderable>();