From 7419e124a3b3836681ad564aaa51f88f96cff910 Mon Sep 17 00:00:00 2001 From: Assaf Tirangel Date: Sat, 1 Jul 2023 01:11:34 +0300 Subject: [PATCH] Adds prompt tree --- examples/Console/Prompt/Program.cs | 58 +++++++++++++++++++ examples/Console/Prompt/SelectableItem.cs | 25 ++++++++ .../Prompts/MultiSelectionPromptExtensions.cs | 40 +++++++++++++ 3 files changed, 123 insertions(+) create mode 100644 examples/Console/Prompt/SelectableItem.cs diff --git a/examples/Console/Prompt/Program.cs b/examples/Console/Prompt/Program.cs index 0008bfa37..baf66aa8d 100644 --- a/examples/Console/Prompt/Program.cs +++ b/examples/Console/Prompt/Program.cs @@ -1,3 +1,5 @@ +using System.Collections.Generic; +using System.Linq; using Spectre.Console; namespace Prompt @@ -26,6 +28,9 @@ public static void Main(string[] args) WriteDivider("Lists"); var fruit = AskFruit(); + WriteDivider("Prompt Tree"); + var deepSpaceObjects = AskDeepSpaceObjects(); + WriteDivider("Choices"); var sport = AskSport(); @@ -52,6 +57,7 @@ public static void Main(string[] args) .BorderColor(Color.Grey) .AddRow("[grey]Name[/]", name) .AddRow("[grey]Favorite fruit[/]", fruit) + .AddRow("[grey]Favorite DSOs[/]", string.Join(", ", deepSpaceObjects)) .AddRow("[grey]Favorite sport[/]", sport) .AddRow("[grey]Age[/]", age.ToString()) .AddRow("[grey]Password[/]", password) @@ -119,6 +125,58 @@ public static string AskFruit() return fruit; } + public static IEnumerable AskDeepSpaceObjects() + { + var tree = + new SelectableItems( + "All", + new SelectableItems( + "Galaxies", + new SelectableItem("Milky Way"), + new SelectableItem("M33 (Triangulum)"), + new SelectableItem("M51 (Whirlpool)"), + new SelectableItems( + "M31 (Andromeda)", + new SelectableItem("Andromeda's Parachute"), + new SelectableItem("G1 (Mayall II)"), + new SelectableItem("NGC 206"))), + new SelectableItems( + "Globular Clusters", + new SelectableItem("NGC 5139 (Omega Centauri)"), + new SelectableItem("M13 (Hercules)"), + new SelectableItem("M3"), + new SelectableItem("M5")), + new SelectableItems( + "Open Clusters", + new SelectableItem("M45 (The Pleiades)"), + new SelectableItem("M44 (The Beehive Cluster)"), + new SelectableItem("M6 (the Butterfly Cluster)"), + new SelectableItem("M7 (Ptolemy's Cluster)")), + new SelectableItems( + "Nebulas", + new SelectableItem("M42 (Orion Nebula)"), + new SelectableItem("M16 (Eagle Nebula)"), + new SelectableItem("M6 (the Butterfly Cluster)"), + new SelectableItem("M7 (Ptolemy's Cluster)"))); + + return AnsiConsole.Prompt( + new MultiSelectionPrompt() + .AddChoiceTree( + tree, + selectableItem => + selectableItem is SelectableItems selectableItems + ? selectableItems.Children + : Enumerable.Empty()) + .PageSize(10) + .Title("What are your favorite DSOs?") + .HighlightStyle( + new Style( + Color.Black, + Color.SteelBlue1)) + .UseConverter(selectable => selectable.Name)) + .Select(selectableItem => selectableItem.Name); + } + public static string AskSport() { return AnsiConsole.Prompt( diff --git a/examples/Console/Prompt/SelectableItem.cs b/examples/Console/Prompt/SelectableItem.cs new file mode 100644 index 000000000..30d341b27 --- /dev/null +++ b/examples/Console/Prompt/SelectableItem.cs @@ -0,0 +1,25 @@ +using System.Collections.Generic; + +namespace Prompt +{ + internal class SelectableItem + { + public string Name { get; set; } + + public SelectableItem(string name) + { + Name = name; + } + } + + internal class SelectableItems : SelectableItem + { + public IEnumerable Children { get; set; } + + public SelectableItems(string name, params SelectableItem[] children) : + base(name) + { + Children = children; + } + } +} \ No newline at end of file diff --git a/src/Spectre.Console/Prompts/MultiSelectionPromptExtensions.cs b/src/Spectre.Console/Prompts/MultiSelectionPromptExtensions.cs index a4aaecf51..a881e367e 100644 --- a/src/Spectre.Console/Prompts/MultiSelectionPromptExtensions.cs +++ b/src/Spectre.Console/Prompts/MultiSelectionPromptExtensions.cs @@ -147,6 +147,46 @@ public static MultiSelectionPrompt AddChoiceGroup(this MultiSelectionPromp return obj; } + /// + /// Adds choice tree. + /// + /// The prompt result type. + /// The prompt. + /// The tree's root. + /// A function to get node child choices. + /// The same instance so that multiple calls can be chained. + public static MultiSelectionPrompt AddChoiceTree(this MultiSelectionPrompt obj, T rootChoice, Func> getChildChoices) + where T : notnull + { + var multiSelectionItem = obj.AddChoice(rootChoice); + AddChildChoice( + getChildChoices, + rootChoice, + multiSelectionItem, + rootChoice: true); + return obj; + + static void AddChildChoice( + Func> getChildChoices, + T parentChoice, + ISelectionItem selectionItem, + bool rootChoice = false) + { + if (!rootChoice) + { + selectionItem = selectionItem.AddChild(parentChoice); + } + + foreach (var childChoice in getChildChoices(parentChoice)) + { + AddChildChoice( + getChildChoices, + childChoice, + selectionItem); + } + } + } + /// /// Marks an item as selected. ///