diff --git a/PromptPlus.sln b/PromptPlus.sln index 63e1905b..c34f02b0 100644 --- a/PromptPlus.sln +++ b/PromptPlus.sln @@ -98,7 +98,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SliderSwitchSamples", "Samp EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ChartSamples", "Samples\ChartSamples\ChartSamples.csproj", "{A0697CC0-24A0-48D4-BB7D-57A7DE3DBFAB}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CalendarSamples", "Samples\CalendarSamples\CalendarSamples.csproj", "{248BA41C-17EF-42E3-A9B4-17FF7FA1311B}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CalendarSamples", "Samples\CalendarSamples\CalendarSamples.csproj", "{248BA41C-17EF-42E3-A9B4-17FF7FA1311B}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PipelineSamples", "Samples\PipelineSamples\PipelineSamples.csproj", "{184F90B1-EBF2-4D34-88B3-9D7A252CB2B4}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -341,6 +343,12 @@ Global {248BA41C-17EF-42E3-A9B4-17FF7FA1311B}.local|Any CPU.Build.0 = Debug|Any CPU {248BA41C-17EF-42E3-A9B4-17FF7FA1311B}.Release|Any CPU.ActiveCfg = Release|Any CPU {248BA41C-17EF-42E3-A9B4-17FF7FA1311B}.Release|Any CPU.Build.0 = Release|Any CPU + {184F90B1-EBF2-4D34-88B3-9D7A252CB2B4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {184F90B1-EBF2-4D34-88B3-9D7A252CB2B4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {184F90B1-EBF2-4D34-88B3-9D7A252CB2B4}.local|Any CPU.ActiveCfg = Debug|Any CPU + {184F90B1-EBF2-4D34-88B3-9D7A252CB2B4}.local|Any CPU.Build.0 = Debug|Any CPU + {184F90B1-EBF2-4D34-88B3-9D7A252CB2B4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {184F90B1-EBF2-4D34-88B3-9D7A252CB2B4}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -383,6 +391,7 @@ Global {3702034B-7D26-4BC3-AB1E-864C2EE2D785} = {F85DFC6B-0BBA-4B8D-BBF7-8FE175FE165C} {A0697CC0-24A0-48D4-BB7D-57A7DE3DBFAB} = {F85DFC6B-0BBA-4B8D-BBF7-8FE175FE165C} {248BA41C-17EF-42E3-A9B4-17FF7FA1311B} = {F85DFC6B-0BBA-4B8D-BBF7-8FE175FE165C} + {184F90B1-EBF2-4D34-88B3-9D7A252CB2B4} = {F85DFC6B-0BBA-4B8D-BBF7-8FE175FE165C} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {2E883401-DEB0-496F-A6BC-8AA0F44BC5B9} diff --git a/README.md b/README.md index d2ff36d3..56b1a6d1 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,16 @@ - [License](#license) - [API Reference](https://fracerqueira.github.io/PromptPlus/apis/apis.html) -## What's News in V.4.0 +## What news in V4.0.2 +- New Control Pipeline + - PromptPlus.Pipeline(T startvalue) +- Changed WaitControl to take context value in tasks and return context in result + - There are small break-chages +- Add Answer key check equals "Yes"/"No" using config values + - IsYesResponseKey(this ConsoleKeyInfo keyinfo) + - IsNoResponseKey(this ConsoleKeyInfo keyinfo) + +## What's News in V4.0.1 ### Newest controls and color improvement and layout @@ -132,6 +141,13 @@ dotnet run --project [name of sample] For each snapshot, the title is **name of projet** sample in folder **samples** +### Pipeline + +[**Top**](#table-of-contents) | [PipelineSamples](https://github.com/FRACerqueira/PromptPlus/tree/main/Samples/PipelineSamples) + +**Not have snapshot** + + ### Input [**Top**](#table-of-contents) | [InputBasicSamples](https://github.com/FRACerqueira/PromptPlus/tree/main/Samples/InputBasicSamples) diff --git a/Samples/ConsoleFeaturesSamples/Program.cs b/Samples/ConsoleFeaturesSamples/Program.cs index 4843d5eb..5c73c3e8 100644 --- a/Samples/ConsoleFeaturesSamples/Program.cs +++ b/Samples/ConsoleFeaturesSamples/Program.cs @@ -4,207 +4,210 @@ using PPlus; using PPlus.Controls; -Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US"); - -PromptPlus.Clear(); - -Console.WriteLine("\U0001F4BD"); - -PromptPlus.WriteLine("[RGB(255,0,0) ON WHITE]Test[YELLOW] COLOR [/] BACK COLOR [/] other text"); -PromptPlus.WriteLine("[#ff0000 ON WHITE]Test [YELLOW] COLOR [/] BACK COLOR [/] other text"); -PromptPlus.WriteLine("[RED ON WHITE]Test[YELLOW] COLOR [/] BACK COLOR [/] other text"); - -PromptPlus.WriteLine("Test", new Style(Color.White, Color.Red, Overflow.None)); -PromptPlus.WriteLine("Test", new Style(new Color(255, 255, 255), Color.Red, Overflow.None)); -PromptPlus.WriteLine("Test", new Style(Color.FromConsoleColor(ConsoleColor.White), Color.Red, Overflow.None)); -PromptPlus.WriteLine("Test", new Style(Color.FromInt32(255), Color.Red, Overflow.None)); -PromptPlus.WriteLine("Test", new Style(Color.FromHtml("#ffffff"), Color.Red, Overflow.None)); +namespace ConsoleFeaturesSamples +{ + internal class Program + { + static void Main() + { + PromptPlus.WriteLine("[RGB(255,0,0) ON WHITE]Test[YELLOW] COLOR [/] BACK COLOR [/] other text"); + PromptPlus.WriteLine("[#ff0000 ON WHITE]Test [YELLOW] COLOR [/] BACK COLOR [/] other text"); + PromptPlus.WriteLine("[RED ON WHITE]Test[YELLOW] COLOR [/] BACK COLOR [/] other text"); -PromptPlus.DoubleDash($"PromptPlus Style.OverflowEllipsis"); -PromptPlus.WriteLine("[RED ON WHITE]TESTE[YELLOW] COLOR [/] BACK COLOR [/]" + "asdajsdkldksdkasasdadasdadjashkjdahsdashdjkashdkashdkashdkashdakshdkashdkashdaskhdaskdhaskdhaskdhaskdhaskdhsakdhaskdhaskjdj", style: Style.OverflowEllipsis); + PromptPlus.WriteLine("Test", new Style(Color.White, Color.Red, Overflow.None)); + PromptPlus.WriteLine("Test", new Style(new Color(255, 255, 255), Color.Red, Overflow.None)); + PromptPlus.WriteLine("Test", new Style(Color.FromConsoleColor(ConsoleColor.White), Color.Red, Overflow.None)); + PromptPlus.WriteLine("Test", new Style(Color.FromInt32(255), Color.Red, Overflow.None)); + PromptPlus.WriteLine("Test", new Style(Color.FromHtml("#ffffff"), Color.Red, Overflow.None)); -PromptPlus.DoubleDash($"PromptPlus Style.OverflowCrop"); -PromptPlus.WriteLine("[RED ON WHITE]TESTE[YELLOW] COLOR [/] BACK COLOR [/]" + "asdajsdkldksdkasasdadasdadjashkjdahsdashdjkashdkashdkashdkashdakshdkashdkashdaskhdaskdhaskdhaskdhaskdhaskdhsakdhaskdhaskjdj", style: Style.OverflowCrop); + PromptPlus.DoubleDash($"PromptPlus Style.OverflowEllipsis"); + PromptPlus.WriteLine("[RED ON WHITE]TESTE[YELLOW] COLOR [/] BACK COLOR [/]" + "asdajsdkldksdkasasdadasdadjashkjdahsdashdjkashdkashdkashdkashdakshdkashdkashdaskhdaskdhaskdhaskdhaskdhaskdhsakdhaskdhaskjdj", style: Style.OverflowEllipsis); -PromptPlus.DoubleDash($"PromptPlus default"); -PromptPlus.WriteLine("[RED ON WHITE]TESTE[YELLOW] COLOR [/] BACK COLOR [/]" + "asdajsdkldksdkasasdadasdadjashkjdahsdashdjkashdkashdkashdkashdakshdkashdkashdaskhdaskdhaskdhaskdhaskdhaskdhsakdhaskdhaskjdj"); + PromptPlus.DoubleDash($"PromptPlus Style.OverflowCrop"); + PromptPlus.WriteLine("[RED ON WHITE]TESTE[YELLOW] COLOR [/] BACK COLOR [/]" + "asdajsdkldksdkasasdadasdadjashkjdahsdashdjkashdkashdkashdkashdakshdkashdkashdaskhdaskdhaskdhaskdhaskdhaskdhsakdhaskdhaskjdj", style: Style.OverflowCrop); -PromptPlus - .KeyPress() - .Config(cfg => cfg.HideAfterFinish(true)) - .Spinner(SpinnersType.DotsScrolling) - .Run(); + PromptPlus.DoubleDash($"PromptPlus default"); + PromptPlus.WriteLine("[RED ON WHITE]TESTE[YELLOW] COLOR [/] BACK COLOR [/]" + "asdajsdkldksdkasasdadasdadjashkjdahsdashdjkashdkashdkashdkashdakshdkashdkashdaskhdaskdhaskdhaskdhaskdhaskdhsakdhaskdhaskjdj"); -PromptPlus.Setup((cfg) => -{ - cfg.PadLeft = 2; - cfg.PadRight = 2; - cfg.BackgroundColor = ConsoleColor.Blue; - cfg.Culture = new CultureInfo("en-us"); -}); - -PromptPlus.SingleDash($"[yellow]Console Information[/]", DashOptions.DoubleBorder, 1 /*extra lines*/); -PromptPlus.WriteLine($"IsTerminal: {PromptPlus.IsTerminal}"); -PromptPlus.WriteLine($"IsUnicodeSupported: {PromptPlus.IsUnicodeSupported}"); -PromptPlus.WriteLine($"OutputEncoding: {PromptPlus.OutputEncoding.EncodingName}"); -PromptPlus.WriteLine($"ColorDepth: {PromptPlus.ColorDepth}"); -PromptPlus.WriteLine($"BackgroundColor: {PromptPlus.BackgroundColor}"); -PromptPlus.WriteLine($"ForegroundColor: {PromptPlus.ForegroundColor}"); -PromptPlus.WriteLine($"SupportsAnsi: {PromptPlus.SupportsAnsi}"); -PromptPlus.WriteLine($"Buffers(Width/Height): {PromptPlus.BufferWidth}/{PromptPlus.BufferHeight}"); -PromptPlus.WriteLine($"PadScreen(Left/Right): {PromptPlus.PadLeft}/{PromptPlus.PadRight}\n"); - -PromptPlus - .KeyPress() - .Config(cfg => - { - cfg.HideAfterFinish(true) - .ShowTooltip(false) - .ApplyStyle(StyleControls.Tooltips,Style.Plain.Foreground(Color.Grey100)); - }) - .Spinner(SpinnersType.Balloon) - .Run(); + PromptPlus + .KeyPress() + .Config(cfg => cfg.HideAfterFinish(true)) + .Spinner(SpinnersType.DotsScrolling) + .Run(); -PromptPlus.Clear(); - - -PromptPlus.DoubleDash($"[yellow]Sample Colors capacities [/]", DashOptions.HeavyBorder, 1); -PromptPlus.Write("|"); -for (var i = 0; i < 8; i++) -{ - var backgroundColor = Color.FromInt32(i); - var foregroundColor = backgroundColor.GetInvertedColor(); - PromptPlus.Write(string.Format(" {0,-9}", i), new Style(foregroundColor, backgroundColor)); - if ((i + 1) % 8 == 0) - { - PromptPlus.WriteLine("|"); - } -} + PromptPlus.Setup((cfg) => + { + cfg.PadLeft = 2; + cfg.PadRight = 2; + cfg.BackgroundColor = ConsoleColor.Blue; + cfg.Culture = new CultureInfo("en-us"); + }); + + PromptPlus.SingleDash($"[yellow]Console Information[/]", DashOptions.DoubleBorder, 1 /*extra lines*/); + PromptPlus.WriteLine($"IsTerminal: {PromptPlus.IsTerminal}"); + PromptPlus.WriteLine($"IsUnicodeSupported: {PromptPlus.IsUnicodeSupported}"); + PromptPlus.WriteLine($"OutputEncoding: {PromptPlus.OutputEncoding.EncodingName}"); + PromptPlus.WriteLine($"ColorDepth: {PromptPlus.ColorDepth}"); + PromptPlus.WriteLine($"BackgroundColor: {PromptPlus.BackgroundColor}"); + PromptPlus.WriteLine($"ForegroundColor: {PromptPlus.ForegroundColor}"); + PromptPlus.WriteLine($"SupportsAnsi: {PromptPlus.SupportsAnsi}"); + PromptPlus.WriteLine($"Buffers(Width/Height): {PromptPlus.BufferWidth}/{PromptPlus.BufferHeight}"); + PromptPlus.WriteLine($"PadScreen(Left/Right): {PromptPlus.PadLeft}/{PromptPlus.PadRight}\n"); + + PromptPlus + .KeyPress() + .Config(cfg => + { + cfg.HideAfterFinish(true) + .ShowTooltip(false) + .ApplyStyle(StyleControls.Tooltips, Style.Plain.Foreground(Color.Grey100)); + }) + .Spinner(SpinnersType.Balloon) + .Run(); + + PromptPlus.Clear(); + + + PromptPlus.DoubleDash($"[yellow]Sample Colors capacities [/]", DashOptions.HeavyBorder, 1); + PromptPlus.Write("|"); + for (var i = 0; i < 8; i++) + { + var backgroundColor = Color.FromInt32(i); + var foregroundColor = backgroundColor.GetInvertedColor(); + PromptPlus.Write(string.Format(" {0,-9}", i), new Style(foregroundColor, backgroundColor)); + if ((i + 1) % 8 == 0) + { + PromptPlus.WriteLine("|"); + } + } -if (PromptPlus.ColorDepth >= ColorSystem.Standard) -{ - PromptPlus.WriteLine(); - PromptPlus.DoubleDash($"[yellow]Sample Colors capacities Standard[/]", DashOptions.HeavyBorder, 1); - PromptPlus.Write("|"); - for (var i = 0; i < 16; i++) - { - var backgroundColor = Color.FromInt32(i); - var foregroundColor = backgroundColor.GetInvertedColor(); - PromptPlus.Write(string.Format(" {0,-9}", i), new Style(foregroundColor, backgroundColor)); - if ((i + 1) % 8 == 0) - { - PromptPlus.WriteLine("|"); - if ((i + 1) % 16 != 0) + if (PromptPlus.ColorDepth >= ColorSystem.Standard) { + PromptPlus.WriteLine(); + PromptPlus.DoubleDash($"[yellow]Sample Colors capacities Standard[/]", DashOptions.HeavyBorder, 1); PromptPlus.Write("|"); + for (var i = 0; i < 16; i++) + { + var backgroundColor = Color.FromInt32(i); + var foregroundColor = backgroundColor.GetInvertedColor(); + PromptPlus.Write(string.Format(" {0,-9}", i), new Style(foregroundColor, backgroundColor)); + if ((i + 1) % 8 == 0) + { + PromptPlus.WriteLine("|"); + if ((i + 1) % 16 != 0) + { + PromptPlus.Write("|"); + } + } + } } - } - } -} -if (PromptPlus.ColorDepth >= ColorSystem.EightBit) -{ - PromptPlus.WriteLine(); - PromptPlus.DoubleDash($"[yellow]Sample Colors capacities EightBit[/]", DashOptions.HeavyBorder, 1); - for (var i = 0; i < 16; i++) - { - PromptPlus.Write("|"); - for (var j = 0; j < 16; j++) - { - var number = i * 16 + j; - var backgroundColor = Color.FromInt32(number); - var foregroundColor = backgroundColor.GetInvertedColor(); - PromptPlus.Write(string.Format(" {0,-4}", number), new Style(foregroundColor, backgroundColor)); - } - PromptPlus.WriteLine("|"); - } -} -if (PromptPlus.ColorDepth >= ColorSystem.TrueColor) -{ - PromptPlus.WriteLine(); - PromptPlus.DoubleDash($"[yellow]Sample Colors capacities TrueColor[/]", DashOptions.HeavyBorder, 1); - for (var y = 0; y < 15; y++) - { - PromptPlus.Write("|"); - for (var x = 0; x < 90; x++) - { - var l = 0.1f + ((y / (float)15) * 0.7f); - var h = x / (float)80; - var (r1, g1, b1) = ColorFromHSL(h, l, 1.0f); - var (r2, g2, b2) = ColorFromHSL(h, l + (0.7f / 10), 1.0f); - var background = new Color((byte)(r1 * 255), (byte)(g1 * 255), (byte)(b1 * 255)); - var foreground = new Color((byte)(r2 * 255), (byte)(g2 * 255), (byte)(b2 * 255)); - PromptPlus.Write("▄", new Style(foreground, background)); - } - PromptPlus.WriteLine("|"); - } -} -PromptPlus.WriteLines(2); -PromptPlus.KeyPress("End Sample!, Press any key", cfg => - { - cfg.ShowTooltip(false); - cfg.ApplyStyle(StyleControls.Tooltips, Style.Plain.Foreground(Style.Plain.Background.GetInvertedColor())); - }) - .Run(); - - -static (float, float, float) ColorFromHSL(double h, double l, double s) -{ - double r = 0, g = 0, b = 0; - if (l != 0) - { - if (s == 0) - { - r = g = b = l; - } - else - { - double temp2; - if (l < 0.5) + if (PromptPlus.ColorDepth >= ColorSystem.EightBit) { - temp2 = l * (1.0 + s); + PromptPlus.WriteLine(); + PromptPlus.DoubleDash($"[yellow]Sample Colors capacities EightBit[/]", DashOptions.HeavyBorder, 1); + for (var i = 0; i < 16; i++) + { + PromptPlus.Write("|"); + for (var j = 0; j < 16; j++) + { + var number = i * 16 + j; + var backgroundColor = Color.FromInt32(number); + var foregroundColor = backgroundColor.GetInvertedColor(); + PromptPlus.Write(string.Format(" {0,-4}", number), new Style(foregroundColor, backgroundColor)); + } + PromptPlus.WriteLine("|"); + } } - else + if (PromptPlus.ColorDepth >= ColorSystem.TrueColor) { - temp2 = l + s - (l * s); + PromptPlus.WriteLine(); + PromptPlus.DoubleDash($"[yellow]Sample Colors capacities TrueColor[/]", DashOptions.HeavyBorder, 1); + for (var y = 0; y < 15; y++) + { + PromptPlus.Write("|"); + for (var x = 0; x < 90; x++) + { + var l = 0.1f + ((y / (float)15) * 0.7f); + var h = x / (float)80; + var (r1, g1, b1) = ColorFromHSL(h, l, 1.0f); + var (r2, g2, b2) = ColorFromHSL(h, l + (0.7f / 10), 1.0f); + var background = new Color((byte)(r1 * 255), (byte)(g1 * 255), (byte)(b1 * 255)); + var foreground = new Color((byte)(r2 * 255), (byte)(g2 * 255), (byte)(b2 * 255)); + PromptPlus.Write("▄", new Style(foreground, background)); + } + PromptPlus.WriteLine("|"); + } } + PromptPlus.WriteLines(2); + PromptPlus.KeyPress("End Sample!, Press any key", cfg => + { + cfg.ShowTooltip(false); + cfg.ApplyStyle(StyleControls.Tooltips, Style.Plain.Foreground(Style.Plain.Background.GetInvertedColor())); + }) + .Run(); - var temp1 = 2.0 * l - temp2; - - r = GetColorComponent(temp1, temp2, h + 1.0 / 3.0); - g = GetColorComponent(temp1, temp2, h); - b = GetColorComponent(temp1, temp2, h - 1.0 / 3.0); - } - } - - return ((float)r, (float)g, (float)b); -} -static double GetColorComponent(double temp1, double temp2, double temp3) -{ - if (temp3 < 0.0) - { - temp3 += 1.0; - } - else if (temp3 > 1.0) - { - temp3 -= 1.0; - } + static (float, float, float) ColorFromHSL(double h, double l, double s) + { + double r = 0, g = 0, b = 0; + if (l != 0) + { + if (s == 0) + { + r = g = b = l; + } + else + { + double temp2; + if (l < 0.5) + { + temp2 = l * (1.0 + s); + } + else + { + temp2 = l + s - (l * s); + } + + var temp1 = 2.0 * l - temp2; + + r = GetColorComponent(temp1, temp2, h + 1.0 / 3.0); + g = GetColorComponent(temp1, temp2, h); + b = GetColorComponent(temp1, temp2, h - 1.0 / 3.0); + } + } + + return ((float)r, (float)g, (float)b); - if (temp3 < 1.0 / 6.0) - { - return temp1 + (temp2 - temp1) * 6.0 * temp3; - } - else if (temp3 < 0.5) - { - return temp2; - } - else if (temp3 < 2.0 / 3.0) - { - return temp1 + ((temp2 - temp1) * ((2.0 / 3.0) - temp3) * 6.0); - } - else - { - return temp1; + } + static double GetColorComponent(double temp1, double temp2, double temp3) + { + if (temp3 < 0.0) + { + temp3 += 1.0; + } + else if (temp3 > 1.0) + { + temp3 -= 1.0; + } + + if (temp3 < 1.0 / 6.0) + { + return temp1 + (temp2 - temp1) * 6.0 * temp3; + } + else if (temp3 < 0.5) + { + return temp2; + } + else if (temp3 < 2.0 / 3.0) + { + return temp1 + ((temp2 - temp1) * ((2.0 / 3.0) - temp3) * 6.0); + } + else + { + return temp1; + } + } + } } } diff --git a/Samples/MultiSelectBasicSamples/Properties/launchSettings.json b/Samples/MultiSelectBasicSamples/Properties/launchSettings.json new file mode 100644 index 00000000..33504c94 --- /dev/null +++ b/Samples/MultiSelectBasicSamples/Properties/launchSettings.json @@ -0,0 +1,8 @@ +{ + "profiles": { + "WSL": { + "commandName": "WSL2", + "distributionName": "" + } + } +} \ No newline at end of file diff --git a/Samples/PipelineSamples/PipelineSamples.csproj b/Samples/PipelineSamples/PipelineSamples.csproj new file mode 100644 index 00000000..001b416c --- /dev/null +++ b/Samples/PipelineSamples/PipelineSamples.csproj @@ -0,0 +1,14 @@ + + + + Exe + net7.0 + enable + enable + + + + + + + diff --git a/Samples/PipelineSamples/Program.cs b/Samples/PipelineSamples/Program.cs new file mode 100644 index 00000000..c2cbda26 --- /dev/null +++ b/Samples/PipelineSamples/Program.cs @@ -0,0 +1,196 @@ +using System.Globalization; +using PPlus; + +namespace PipelineSamples +{ + internal class Program + { + private enum Mypipes + { + FirstName, + LastName, + Confirm + } + + private class MyClassPipeline + { + public string FirtName { get; set; } = string.Empty; + public string LastName { get; set; } = string.Empty; + } + + static void Main(string[] args) + { + Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US"); + + PromptPlus.Clear(); + + PromptPlus.DoubleDash("Control Pipeline"); + + var pl = PromptPlus.Pipeline(new MyClassPipeline()) + .AddPipe("First Name", + (eventpipe, stoptoken) => + { + var result = PromptPlus.Input(eventpipe.CurrentPipe,"If first name is empty not get lastname and not confim inputs") + .Default(eventpipe.Input.FirtName ?? string.Empty) + .Run(); + if (result.IsAborted) + { + eventpipe.AbortPipeline(); + } + else + { + eventpipe.Input.FirtName = result.Value; + } + }) + .AddPipe("Last Name", + (eventpipe, stoptoken) => + { + var result = PromptPlus.Input(eventpipe.CurrentPipe) + .Default(eventpipe.Input.LastName ?? string.Empty) + .Run(); + if (result.IsAborted) + { + eventpipe.AbortPipeline(); + } + else + { + eventpipe.Input.LastName = result.Value; + } + }, + (eventpipe, stoptoken) => + { + if (eventpipe.Input.FirtName?.Length > 0) + { + return true; + } + return false; + }) + .AddPipe("Confirm", + (eventpipe, stoptoken) => + { + var result = PromptPlus.Confirm(eventpipe.CurrentPipe) + .Run(); + if (result.IsAborted) + { + eventpipe.AbortPipeline(); + } + else + { + if (!result.Value.IsYesResponseKey()) + { + eventpipe.NextPipe("First Name"); + } + } + }) + .Run(); + + + if (!pl.IsAborted) + { + if ((pl.Value.Context.FirtName!.Trim() + pl.Value.Context.LastName!.Trim()).Length > 0) + { + var last = pl.Value.Context.LastName!.Trim(); + if (last.Length > 0) + { + last = $", {last}"; + } + PromptPlus.WriteLine($"You input is {pl.Value.Context.FirtName!}{last}"); + } + else + { + PromptPlus.WriteLine($"You input is empty"); + } + } + + PromptPlus.DoubleDash("Control Pipeline by enum"); + + var pl1 = PromptPlus.Pipeline(new MyClassPipeline()) + .AddPipe(Mypipes.FirstName, + (eventpipe, stoptoken) => + { + var result = PromptPlus.Input("Your First Name", "If first name is empty not get lastname and not confim inputs") + .Default(eventpipe.Input.FirtName ?? string.Empty) + .Run(); + if (result.IsAborted) + { + eventpipe.AbortPipeline(); + } + else + { + eventpipe.Input.FirtName = result.Value; + } + }) + .AddPipe(Mypipes.LastName, + (eventpipe, stoptoken) => + { + var result = PromptPlus.Input("Your Last Name") + .Default(eventpipe.Input.LastName ?? string.Empty) + .Run(); + if (result.IsAborted) + { + eventpipe.AbortPipeline(); + } + else + { + eventpipe.Input.LastName = result.Value; + } + }, + (eventpipe, stoptoken) => + { + if (eventpipe.Input.FirtName?.Length > 0) + { + return true; + } + return false; + }) + .AddPipe(Mypipes.Confirm, + (eventpipe, stoptoken) => + { + var result = PromptPlus.Confirm("Confirm all inputs") + .Run(); + if (result.IsAborted) + { + eventpipe.AbortPipeline(); + } + else + { + if (!result.Value.IsYesResponseKey()) + { + eventpipe.NextPipe(Mypipes.FirstName); + } + } + }, + (eventpipe, stoptoken) => + { + if (eventpipe.Input.FirtName?.Length > 0) + { + return true; + } + return false; + }) + .Run(); + + if (!pl1.IsAborted) + { + if ((pl1.Value.Context.FirtName!.Trim() + pl1.Value.Context.LastName!.Trim()).Length > 0) + { + var last = pl1.Value.Context.LastName!.Trim(); + if (last.Length > 0) + { + last = $", {last}"; + } + PromptPlus.WriteLine($"You input is {pl1.Value.Context.FirtName!}{last}"); + } + else + { + PromptPlus.WriteLine($"You input is empty"); + } + } + + PromptPlus.WriteLines(2); + PromptPlus.KeyPress("End Sample!, Press any key", cfg => cfg.ShowTooltip(false)) + .Run(); + + } + } +} \ No newline at end of file diff --git a/Samples/WaitTasksSamples/Program.cs b/Samples/WaitTasksSamples/Program.cs index 0c55bef7..7c6619a9 100644 --- a/Samples/WaitTasksSamples/Program.cs +++ b/Samples/WaitTasksSamples/Program.cs @@ -23,23 +23,23 @@ static void Main(string[] args) .Run(); PromptPlus.DoubleDash($"Control:WaitProcess - normal usage sequencial mode"); - var wt1 = PromptPlus.WaitProcess("wait process", "main desc") + var wt1 = PromptPlus.WaitProcess("wait process", "main desc") .Finish($"end wait all process") .Interaction(steps1, (ctrl, item) => { ctrl.AddStep(StepMode.Sequential, $"id{item}",null, - (cts) => + (eventw, cts) => { cts.WaitHandle.WaitOne(TimeSpan.FromSeconds(item)); }); }) .ShowElapsedTime() .AddStep(StepMode.Sequential, "id5-10", "Desc 5 and 10", - (cts) => + (eventw, cts) => { cts.WaitHandle.WaitOne(TimeSpan.FromSeconds(5)); }, - (cts) => + (eventw, cts) => { cts.WaitHandle.WaitOne(TimeSpan.FromSeconds(10)); }) @@ -47,7 +47,7 @@ static void Main(string[] args) if (!wt1.IsAborted) { - foreach (var item in wt1.Value) + foreach (var item in wt1.Value.States) { PromptPlus.WriteLine($"You task {item.Id} - {item.Description}, {item.Status}, {item.ElapsedTime}, {item.StepMode}"); } @@ -63,24 +63,24 @@ static void Main(string[] args) PromptPlus.DoubleDash($"Control:WaitProcess - normal usage Parallel mode"); - wt1 = PromptPlus.WaitProcess("wait process", "main desc") + wt1 = PromptPlus.WaitProcess("wait process", "main desc") .Finish($"end wait all process") .TaskTitle("MyProcess") .Interaction(steps2, (ctrl, item) => { ctrl.AddStep(StepMode.Parallel, $"id{item}",null, - (cts) => + (eventw, cts) => { cts.WaitHandle.WaitOne(TimeSpan.FromSeconds(item)); }); }) .ShowElapsedTime() .AddStep(StepMode.Parallel, "id5-10", "Desc 5 and 10", - (cts) => + (eventw, cts) => { cts.WaitHandle.WaitOne(TimeSpan.FromSeconds(5)); }, - (cts) => + (eventw, cts) => { cts.WaitHandle.WaitOne(TimeSpan.FromSeconds(10)); }) @@ -88,7 +88,7 @@ static void Main(string[] args) if (!wt1.IsAborted) { - foreach (var item in wt1.Value) + foreach (var item in wt1.Value.States) { PromptPlus.WriteLine($"You task {item.Id} - {item.Description}, {item.Status}, {item.ElapsedTime}, {item.StepMode}"); } diff --git a/Src/Controls/Pipeline/EventPipe.cs b/Src/Controls/Pipeline/EventPipe.cs new file mode 100644 index 00000000..aa55d06c --- /dev/null +++ b/Src/Controls/Pipeline/EventPipe.cs @@ -0,0 +1,94 @@ +using System; +using System.Collections.ObjectModel; + +namespace PPlus.Controls +{ + /// + /// Represents the event to pipe with with all Methods to change sequence + /// + /// Typeof Input + public class EventPipe + { + private EventPipe() + { + throw new PromptPlusException("EventPipe CTOR NotImplemented"); + } + + internal EventPipe(ref T value,string? from, string? current, string? to, ReadOnlyCollection listpipes) + { + FromPipe = from; + CurrentPipe = current; + ToPipe = to; + Pipes = listpipes; + Input = value; + } + + /// + /// Input value + /// + public T Input { get; set; } + + /// + /// From Pipe + /// + public string CurrentPipe { get; } + + /// + /// From Pipe + /// + public string FromPipe { get; } + + /// + /// Next Pipe + /// + public string ToPipe { get; private set; } + + /// + /// List Pipes + /// + public ReadOnlyCollection Pipes { get; } + + + /// + /// Set Next Pipe. + /// + public void NextPipe(string value) + { + if (!Pipes.Contains(value)) + { + throw new PromptPlusException($"Not found pipe {value}"); + } + ToPipe = value; + } + + /// + /// Set Next Pipe. + /// + public void NextPipe(TID value) where TID : Enum + { + if (!Pipes.Contains(value.ToString())) + { + throw new PromptPlusException($"Not found pipe {value}"); + } + ToPipe = value.ToString(); + } + + /// + /// End Pipeline. + /// + public void EndPipeline() + { + ToPipe = null; + } + + /// + /// Abort Pipeline. + /// + public void AbortPipeline() + { + ToPipe = null; + CancelPipeLine = true; + } + internal bool CancelPipeLine { get; private set; } + } +} \ No newline at end of file diff --git a/Src/Controls/Pipeline/IControlPipeline.cs b/Src/Controls/Pipeline/IControlPipeline.cs new file mode 100644 index 00000000..f09f1d69 --- /dev/null +++ b/Src/Controls/Pipeline/IControlPipeline.cs @@ -0,0 +1,38 @@ +using System; +using System.Threading; + +namespace PPlus.Controls +{ + /// + /// + /// Represents the interface with all Methods of the Pipeline control + /// + /// typeof return + public interface IControlPipeline : IPromptControls> + { + /// + /// Add the pipe + /// + /// The unique id to pipe + /// The handler to execute. See to modified sequence + /// The condition to start pipe. If true execute pipe, otherwise goto next pipe. See to modified sequence + /// + IControlPipeline AddPipe(string idpipe,Action, CancellationToken> command, Func, CancellationToken, bool> condition = null); + + /// + /// Add the pipe by enum ID + /// + /// The unique id to pipe + /// The handler to execute. See to modified sequence + /// The condition to start pipe. If true execute pipe, otherwise goto next pipe. See to modified sequence + /// + IControlPipeline AddPipe(TID idpipe, Action, CancellationToken> command, Func, CancellationToken, bool> condition = null) where TID: Enum; + + /// + /// Custom config the control. + /// + /// Action to apply changes. + /// + IControlPipeline Config(Action context); + } +} diff --git a/Src/Controls/Pipeline/PipeRunningStatus.cs b/Src/Controls/Pipeline/PipeRunningStatus.cs new file mode 100644 index 00000000..379571f4 --- /dev/null +++ b/Src/Controls/Pipeline/PipeRunningStatus.cs @@ -0,0 +1,45 @@ +using System; + +namespace PPlus.Controls +{ + /// + /// Represents the running status of the tube + /// + public readonly struct PipeRunningStatus + { + /// + /// Create a PipeRunningStatus + /// + /// + /// Do not use this constructor! + /// + public PipeRunningStatus() + { + throw new PromptPlusException("PipeStatus CTOR NotImplemented"); + } + + internal PipeRunningStatus(string pipe, PipeStatus status,TimeSpan elapsedtime) + { + Pipe = pipe; + Status = status; + Elapsedtime = elapsedtime; + } + + /// + /// Get pipes id + /// + public string Pipe { get; } + + + /// + /// Get status pipes + /// + public PipeStatus Status { get; } + + /// + /// Get Elapsedtime pipe + /// + public TimeSpan Elapsedtime { get; } + + } +} diff --git a/Src/Controls/Pipeline/PipeStatus.cs b/Src/Controls/Pipeline/PipeStatus.cs new file mode 100644 index 00000000..c7ca7dcd --- /dev/null +++ b/Src/Controls/Pipeline/PipeStatus.cs @@ -0,0 +1,25 @@ +namespace PPlus.Controls +{ + /// + /// Represents the status of the tube + /// + public enum PipeStatus + { + /// + /// Pipe has executed + /// + Executed, + /// + /// Pipe has Jumped, Not valid condition. + /// + Jumped, + /// + /// Pipe has canceled + /// + Canceled, + /// + /// Pipe not executed + /// + Waiting + } +} diff --git a/Src/Controls/Pipeline/PipelineControl.cs b/Src/Controls/Pipeline/PipelineControl.cs new file mode 100644 index 00000000..286883e1 --- /dev/null +++ b/Src/Controls/Pipeline/PipelineControl.cs @@ -0,0 +1,168 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Diagnostics; +using System.Linq; +using System.Threading; +using PPlus.Controls.Objects; + +namespace PPlus.Controls +{ + internal class PipelineControl : BaseControl>, IControlPipeline + { + private readonly PipelineOptions _options; + private EventPipe _currentevent; + private ReadOnlyCollection _pipes; + private List _runpipes; + private T _context; + public PipelineControl(IConsoleControl console, PipelineOptions options) : base(console, options) + { + _options = options; + } + + #region IControlPipeline + + public IControlPipeline AddPipe(string idpipe, Action, CancellationToken> command, Func, CancellationToken, bool> condition = null) + { + _options.AddPipe(idpipe, command); + if (condition != null) + { + _options.Conditions.Add(idpipe, condition); + } + return this; + } + + public IControlPipeline AddPipe(TID idpipe, Action, CancellationToken> command, Func, CancellationToken, bool> condition = null) where TID : Enum + { + _options.AddPipe(idpipe.ToString(), command); + if (condition != null) + { + _options.Conditions.Add(idpipe.ToString(), condition); + } + return this; + } + + public IControlPipeline Config(Action context) + { + context?.Invoke(_options); + return this; + } + + #endregion + + public override ResultPrompt> TryResult(CancellationToken cancellationToken) + { + var index = _runpipes.FindIndex(x => x.Pipe == _currentevent.CurrentPipe); + if (index != -1) + { + for (int i = index+1; i < _pipes.Count; i++) + { + _runpipes[i] = new PipeRunningStatus(_runpipes[i].Pipe, PipeStatus.Waiting, TimeSpan.Zero); + } + } + _runpipes[index] = new PipeRunningStatus( + _runpipes[index].Pipe, + !_currentevent.CancelPipeLine ? PipeStatus.Executed : PipeStatus.Canceled, + _runpipes[index].Elapsedtime); + _currentevent = NextPipe(_currentevent, cancellationToken); + return new ResultPrompt>(new ResultPipeline(_currentevent.Input, _runpipes.ToArray()), _currentevent.CancelPipeLine, _currentevent.CurrentPipe != null, false, false); + } + + private EventPipe NextPipe(EventPipe curevent, CancellationToken cancellationToken) + { + if (curevent.ToPipe == null || curevent.CurrentPipe == null) + { + return new EventPipe(ref _context, curevent.CurrentPipe, null, null, _pipes); + } + var from = curevent.CurrentPipe; + var cur = curevent.ToPipe; + string to = null; + if (_pipes.IndexOf(cur) + 1 < _pipes.Count) + { + to = _pipes[_pipes.IndexOf(cur) + 1]; + } + var newevent = new EventPipe(ref _context, from, cur, to, _pipes); + while (cur != null && _options.Conditions.TryGetValue(cur, out var condition)) + { + var sw = new Stopwatch(); + sw.Start(); + if (!condition.Invoke(newevent, cancellationToken)) + { + sw.Stop(); + var index = _runpipes.FindIndex(x => x.Pipe == cur); + _runpipes[index] = new PipeRunningStatus(cur, PipeStatus.Jumped, sw.Elapsed); + newevent = NextPipe(newevent,cancellationToken); + cur = newevent.CurrentPipe; + } + else + { + sw.Stop(); + break; + } + } + return newevent; + } + + public override string InitControl(CancellationToken cancellationToken) + { + _context = _options.CurrentValue; + if (_options.Pipes.Count == 0) + { + _currentevent = new EventPipe(ref _context, null, null, null, _pipes); + return string.Empty; + } + _runpipes = new List(); + _pipes = _options.Pipes.Keys.ToList().AsReadOnly(); + _runpipes.AddRange(_pipes.Select(x => new PipeRunningStatus(x, PipeStatus.Waiting, TimeSpan.Zero))); + var first = _pipes[0]; + string next = null; + if (_pipes.Count > 1) + { + next = _pipes[1]; + } + _currentevent = new EventPipe(ref _context, null, first, next, _pipes); + while (first != null && _options.Conditions.TryGetValue(first, out var condition)) + { + var sw = new Stopwatch(); + sw.Start(); + if (!condition.Invoke(_currentevent, cancellationToken)) + { + sw.Stop(); + var index = _runpipes.FindIndex(x => x.Pipe == _currentevent.CurrentPipe); + _runpipes[index] = new PipeRunningStatus(_currentevent.CurrentPipe, PipeStatus.Jumped, sw.Elapsed); + _currentevent = NextPipe(_currentevent, cancellationToken); + first = _currentevent.CurrentPipe; + } + else + { + sw.Stop(); + break; + } + } + return string.Empty; + } + + public override void InputTemplate(ScreenBuffer screenBuffer) + { + if (_currentevent.CurrentPipe != null) + { + var sw = new Stopwatch(); + sw.Start(); + _options.Pipes[_currentevent.CurrentPipe].Invoke(_currentevent, CancellationToken); + sw.Stop(); + var index = _runpipes.FindIndex(x => x.Pipe == _currentevent.CurrentPipe); + _runpipes[index] = new PipeRunningStatus(_runpipes[index].Pipe, _runpipes[index].Status, sw.Elapsed); + } + } + + public override void FinishTemplate(ScreenBuffer screenBuffer, ResultPipeline result, bool aborted) + { + //none + } + + public override void FinalizeControl(CancellationToken cancellationToken) + { + //none + } + } +} diff --git a/Src/Controls/Pipeline/PipelineExtensions.cs b/Src/Controls/Pipeline/PipelineExtensions.cs new file mode 100644 index 00000000..285053b9 --- /dev/null +++ b/Src/Controls/Pipeline/PipelineExtensions.cs @@ -0,0 +1,41 @@ +// *************************************************************************************** +// MIT LICENCE +// The maintenance and evolution is maintained by the PromptPlus project under MIT license +// *************************************************************************************** + +using PPlus.Controls; +using System; + +namespace PPlus +{ + public static partial class PromptPlus + { + /// + /// Create Pipeline Control + /// + /// type of return + /// Initial value + /// + public static IControlPipeline Pipeline(T startvalue) + { + return Pipeline(startvalue, null); + } + + /// + /// Create Pipeline Control + /// + /// type of return + /// Initial value + /// The config action + /// + public static IControlPipeline Pipeline(T startvalue, Action config) + { + var opt = new PipelineOptions(false) + { + CurrentValue = startvalue + }; + config?.Invoke(opt); + return new PipelineControl(_consoledrive, opt); + } + } +} \ No newline at end of file diff --git a/Src/Controls/Pipeline/PipelineOptions.cs b/Src/Controls/Pipeline/PipelineOptions.cs new file mode 100644 index 00000000..448b30e9 --- /dev/null +++ b/Src/Controls/Pipeline/PipelineOptions.cs @@ -0,0 +1,45 @@ +// *************************************************************************************** +// MIT LICENCE +// The maintenance and evolution is maintained by the PromptPlus project under MIT license +// *************************************************************************************** + +using System; +using System.Collections.Generic; +using System.Threading; + +namespace PPlus.Controls +{ + internal class PipelineOptions : BaseOptions + { + private PipelineOptions() + { + throw new PromptPlusException("PipelineOptions CTOR NotImplemented"); + } + + internal PipelineOptions(bool showcursor) : base(showcursor) + { + Pipes = new Dictionary, CancellationToken>>(); + Conditions = new Dictionary, CancellationToken, bool>>(); + } + + public T CurrentValue { get; set; } + + public Dictionary, CancellationToken>> Pipes { get; } + public Dictionary, CancellationToken, bool>> Conditions { get; } + + public void AddPipe(string key, Action, CancellationToken> value) + { + Pipes.Add(key, value); + } + + public void AddCondition(string key, Func, CancellationToken, bool> value) + { + Conditions.Add(key, value); + } + + public string CurrentPipe { get; set; } + public bool AbortPipeline { get; set; } + public bool FinishedPipeline { get; set; } + + } +} diff --git a/Src/Controls/ResultPipeline.cs b/Src/Controls/ResultPipeline.cs new file mode 100644 index 00000000..bcb2e281 --- /dev/null +++ b/Src/Controls/ResultPipeline.cs @@ -0,0 +1,41 @@ +// *************************************************************************************** +// MIT LICENCE +// The maintenance and evolution is maintained by the PromptPlus project under MIT license +// *************************************************************************************** + +namespace PPlus.Controls +{ + /// + /// Represents The Result to Pipeline Controls + /// + /// Typeof return + public readonly struct ResultPipeline + { + /// + /// Create a ResultPipeline + /// + /// + /// Do not use this constructor! + /// + public ResultPipeline() + { + throw new PromptPlusException("ResultPipeline CTOR NotImplemented"); + } + + internal ResultPipeline(T conext, PipeRunningStatus[] pipes) + { + Context = conext; + Pipes = pipes; + } + + /// + /// Get conext value + /// + public T Context { get; } + + /// + /// Get running status of pipeline + /// + public PipeRunningStatus[] Pipes { get; } + } +} diff --git a/Src/Controls/ResultProgessBar.cs b/Src/Controls/ResultProgessBar.cs index 0c148ed7..21ef5316 100644 --- a/Src/Controls/ResultProgessBar.cs +++ b/Src/Controls/ResultProgessBar.cs @@ -8,6 +8,7 @@ namespace PPlus.Controls /// /// Represents The Result to ProgessBar Controls /// + /// Typeof return public readonly struct ResultProgessBar { /// @@ -28,7 +29,7 @@ internal ResultProgessBar(T conext ,double lastvalue) } /// - /// Get conext Result + /// Get conext value /// public T Context { get; } diff --git a/Src/Controls/ResultPrompt.cs b/Src/Controls/ResultPrompt.cs index 5eef558d..47beb555 100644 --- a/Src/Controls/ResultPrompt.cs +++ b/Src/Controls/ResultPrompt.cs @@ -8,6 +8,7 @@ namespace PPlus.Controls /// /// Represents The Result to Controls /// + /// Typeof return public struct ResultPrompt { /// diff --git a/Src/Controls/ResultWaitProcess.cs b/Src/Controls/ResultWaitProcess.cs new file mode 100644 index 00000000..b9bc602a --- /dev/null +++ b/Src/Controls/ResultWaitProcess.cs @@ -0,0 +1,43 @@ +// *************************************************************************************** +// MIT LICENCE +// The maintenance and evolution is maintained by the PromptPlus project under MIT license +// *************************************************************************************** + +using System.Collections.Generic; + +namespace PPlus.Controls +{ + /// + /// Represents The Result to WaitProcess Controls + /// + /// Typeof return + public readonly struct ResultWaitProcess + { + /// + /// Create a ResultPipeline + /// + /// + /// Do not use this constructor! + /// + public ResultWaitProcess() + { + throw new PromptPlusException("ResultWaitProcess CTOR NotImplemented"); + } + + internal ResultWaitProcess(T conext, StateProcess[] stateprocess) + { + Context = conext; + States = stateprocess; + } + + /// + /// Get conext value + /// + public T Context { get; } + + /// + /// Get State of process + /// + public StateProcess[] States { get; } + } +} diff --git a/Src/Controls/SelectColletion/IControlMultiSelect.cs b/Src/Controls/SelectColletion/IControlMultiSelect.cs index c10f68ef..f2de5a3d 100644 --- a/Src/Controls/SelectColletion/IControlMultiSelect.cs +++ b/Src/Controls/SelectColletion/IControlMultiSelect.cs @@ -13,6 +13,7 @@ namespace PPlus.Controls /// /// Represents the interface with all Methods of the MultiSelect control /// + /// typeof return public interface IControlMultiSelect : IPromptControls> { /// diff --git a/Src/Controls/SelectColletion/IControlSelect.cs b/Src/Controls/SelectColletion/IControlSelect.cs index 63c44652..c214fb17 100644 --- a/Src/Controls/SelectColletion/IControlSelect.cs +++ b/Src/Controls/SelectColletion/IControlSelect.cs @@ -13,6 +13,7 @@ namespace PPlus.Controls /// /// Represents the interface with all Methods of the Select control /// + /// typeof return public interface IControlSelect : IPromptControls { /// diff --git a/Src/Controls/TasksProcess/EventWaitProcess.cs b/Src/Controls/TasksProcess/EventWaitProcess.cs new file mode 100644 index 00000000..f9ea723a --- /dev/null +++ b/Src/Controls/TasksProcess/EventWaitProcess.cs @@ -0,0 +1,92 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Diagnostics; +using System.Linq; +using System.Linq.Expressions; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace PPlus.Controls +{ + /// + /// Represents the event to task process with with conex value + /// + /// Typeof Input + public class EventWaitProcess : IDisposable + { + private T _value = default; + private readonly SemaphoreSlim semaphore = new(1, 1); + private bool _disposed; + + private EventWaitProcess() + { + throw new PromptPlusException("EventWaitProcess CTOR NotImplemented"); + } + + internal EventWaitProcess(ref T value, bool cancelnextalltasks) + { + _value = value; + CancelAllNextTasks = cancelnextalltasks; + } + + + /// + /// Get/set Context value + /// + public T Context + { + get + { + T aux; + semaphore.Wait(); + aux = _value; + semaphore.Release(); + return aux; + } + set + { + semaphore.Wait(); + _value = value; + semaphore.Release(); + } + } + + /// + /// Get/Set Cancel all next tasks. + /// + public bool CancelAllNextTasks { get; set; } + + + #region IDisposable + + /// + /// Dispose + /// + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + /// + /// Dispose + /// + /// if disposing + protected virtual void Dispose(bool disposing) + { + if (!_disposed) + { + if (disposing) + { + semaphore.Dispose(); + } + _disposed = true; + } + } + + #endregion + } +} + diff --git a/Src/Controls/TasksProcess/IControlProgressBar.cs b/Src/Controls/TasksProcess/IControlProgressBar.cs index e96a16d8..658e182e 100644 --- a/Src/Controls/TasksProcess/IControlProgressBar.cs +++ b/Src/Controls/TasksProcess/IControlProgressBar.cs @@ -14,6 +14,7 @@ namespace PPlus.Controls /// /// Represents the interface with all Methods of the ProgressBar control /// + /// typeof return public interface IControlProgressBar :IPromptControls> { /// diff --git a/Src/Controls/TasksProcess/IControlWait.cs b/Src/Controls/TasksProcess/IControlWait.cs index 4e464d04..f2160c5a 100644 --- a/Src/Controls/TasksProcess/IControlWait.cs +++ b/Src/Controls/TasksProcess/IControlWait.cs @@ -13,52 +13,58 @@ namespace PPlus.Controls /// /// Represents the interface with all Methods of the WaitTimer/WaitProcess control /// - public interface IControlWait : IPromptControls> + /// typeof return + public interface IControlWait : IPromptControls> { /// /// Execute a action foreach item of colletion passed as a parameter /// - /// typeof item /// Colletion for interaction /// Action to execute - /// - IControlWait Interaction(IEnumerable values, Action action); + /// + IControlWait Interaction(IEnumerable values, Action,T1> action); /// /// Maximum number of concurrent tasks enable. Default vaue is number of processors. /// /// Number of concurrent tasks - /// - IControlWait MaxDegreeProcess(int value); + /// + IControlWait MaxDegreeProcess(int value); + /// + /// Set Contex value for all tasks + /// + /// Context value + /// + IControlWait Context(T value); /// /// Overwrite Task Title . Default task title comes from the embedded resource. /// /// TaskTitle Task - /// - IControlWait TaskTitle(string value); + /// + IControlWait TaskTitle(string value); /// /// Define if show Elapsed Time for each task. /// - /// - IControlWait ShowElapsedTime(); + /// + IControlWait ShowElapsedTime(); /// /// Custom config the control. /// /// Action to apply changes. - /// - IControlWait Config(Action context); + /// + IControlWait Config(Action context); /// /// Finish answer to show when Wait process is completed. /// /// Text Finish answer - /// - IControlWait Finish(string text); + /// + IControlWait Finish(string text); /// /// Overwrite . Default value is SpinnersType.Ascii @@ -68,16 +74,16 @@ public interface IControlWait : IPromptControls> /// Style of spinner. /// Number of mileseconds foreach interation of spinner. Valid only to SpinnersType.custom, otherwise will be ignored /// IEnumerable values for custom spinner. Valid only to SpinnersType.custom, otherwise will be ignored - /// - IControlWait Spinner(SpinnersType spinnersType, Style? SpinnerStyle = null, int? speedAnimation = null, IEnumerable? customspinner = null); + /// + IControlWait Spinner(SpinnersType spinnersType, Style? SpinnerStyle = null, int? speedAnimation = null, IEnumerable? customspinner = null); /// /// Add list of tasks to execute. /// /// Sequential or parallel execution /// list of tasks - /// - IControlWait AddStep(StepMode stepMode, params Action[] process); + /// + IControlWait AddStep(StepMode stepMode, params Action, CancellationToken>[] process); /// /// Add list of tasks to execute with title and description @@ -86,7 +92,7 @@ public interface IControlWait : IPromptControls> /// Id of tasks /// Label of tasks /// list of tasks - /// - IControlWait AddStep(StepMode stepMode, string? id, string? label, params Action[] process); + /// + IControlWait AddStep(StepMode stepMode, string? id, string? label, params Action,CancellationToken>[] process); } } diff --git a/Src/Controls/TasksProcess/ProgressBarControl.cs b/Src/Controls/TasksProcess/ProgressBarControl.cs index a600e426..4b7d0608 100644 --- a/Src/Controls/TasksProcess/ProgressBarControl.cs +++ b/Src/Controls/TasksProcess/ProgressBarControl.cs @@ -28,6 +28,7 @@ internal class ProgressBarControl : BaseControl>,IControl private (int CursorLeft, int CursorTop) _spinnerCursor; private (int CursorLeft, int CursorTop) _progressbarCursor; private int lastline = -1; + private T _context; public ProgressBarControl(IConsoleControl console, ProgressBarOptions options) : base(console, options) { @@ -42,10 +43,12 @@ public override string InitControl(CancellationToken cancellationToken) { throw new PromptPlusException("Not have UpdateHandler to run"); } + + _context = _options.ValueResult; _ticketStep = double.Parse(_options.Witdth.ToString()) / (int.Parse(_options.Maxvalue.ToString()) - int.Parse(_options.Minvalue.ToString())); _ctsesc = new CancellationTokenSource(); _lnkcts = CancellationTokenSource.CreateLinkedTokenSource(_ctsesc.Token, cancellationToken); - _handler = new UpdateProgressBar(_options.ValueResult, _options.StartWith, _options.Minvalue, _options.Maxvalue, ""); + _handler = new UpdateProgressBar(ref _context, _options.StartWith, _options.Minvalue, _options.Maxvalue, ""); return _handler.Value.ToString(); } @@ -82,6 +85,7 @@ protected virtual void Dispose(bool disposing) _process?.Dispose(); _lnkcts?.Dispose(); _ctsesc?.Dispose(); + _handler?.Dispose(); } _disposed = true; diff --git a/Src/Controls/TasksProcess/ProgressBarExtensions.cs b/Src/Controls/TasksProcess/ProgressBarExtensions.cs index 5410d357..c2bc6200 100644 --- a/Src/Controls/TasksProcess/ProgressBarExtensions.cs +++ b/Src/Controls/TasksProcess/ProgressBarExtensions.cs @@ -24,7 +24,7 @@ public static IControlProgressBar ProgressBar(string prompt, string? des /// /// Create Progress Bar Control /// - /// Typeof T + /// Typeof return /// The type Progress Bar. /// The prompt text to write /// The instance result @@ -38,10 +38,10 @@ public static IControlProgressBar ProgressBar(ProgressBarType barType, str /// /// Create instance Progress Bar Control /// - /// Typeof T + /// Typeof return /// The type Progress Bar. /// The prompt text to write - /// The instance result + /// The starting value for the result /// The description text to write /// The config action /// diff --git a/Src/Controls/TasksProcess/UpdateProgressBar.cs b/Src/Controls/TasksProcess/UpdateProgressBar.cs index ea4f9cda..4a926fb1 100644 --- a/Src/Controls/TasksProcess/UpdateProgressBar.cs +++ b/Src/Controls/TasksProcess/UpdateProgressBar.cs @@ -3,28 +3,31 @@ // The maintenance and evolution is maintained by the PromptPlus project under MIT license // *************************************************************************************** +using System; +using System.Threading; + namespace PPlus.Controls { /// /// Represents the commands to update values of Progress Bar /// /// typeof instance result - public class UpdateProgressBar + public class UpdateProgressBar : IDisposable { private string _lastdescription; private double? _lastvalue; - private readonly object _root; + private readonly SemaphoreSlim semaphore = new(1, 1); + private bool _disposed; private UpdateProgressBar() { throw new PromptPlusException("UpdateProgressBar CTOR NotImplemented"); } - internal UpdateProgressBar(T context, double value,double min, double max, string desc) + internal UpdateProgressBar(ref T context, double value,double min, double max, string desc) { _lastvalue = null; _lastdescription = desc; - _root = new object(); Context = context; Finish = false; Value = value; @@ -34,25 +37,24 @@ internal UpdateProgressBar(T context, double value,double min, double max, strin internal bool HasChange() { - lock (_root) + var result = false; + semaphore.Wait(); + if (_lastdescription != Description) { - var result = false; - if (_lastdescription != Description) - { - _lastdescription = Description; - result = true; - } - if (!_lastvalue.HasValue || _lastvalue != Value) - { - _lastvalue = Value; - result = true; - } - if (Finish) - { - result = true; - } - return result; + _lastdescription = Description; + result = true; + } + if (!_lastvalue.HasValue || _lastvalue != Value) + { + _lastvalue = Value; + result = true; } + if (Finish) + { + result = true; + } + semaphore.Release(); + return result; } /// @@ -91,18 +93,17 @@ internal bool HasChange() /// new current value public void Update(double value) { - lock (_root) + semaphore.Wait(); + if (value > Maxvalue) { - if (value > Maxvalue) - { - value = Maxvalue; - } - if (value < Minvalue) - { - value = Minvalue; - } - Value = value; + value = Maxvalue; + } + if (value < Minvalue) + { + value = Minvalue; } + Value = value; + semaphore.Release(); } /// @@ -111,7 +112,39 @@ public void Update(double value) /// new description public void ChangeDescription(string value) { + semaphore.Wait(); Description = value; + semaphore.Release(); } - } + + + #region IDisposable + + /// + /// Dispose + /// + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + /// + /// Dispose + /// + /// if disposing + protected virtual void Dispose(bool disposing) + { + if (!_disposed) + { + if (disposing) + { + semaphore.Dispose(); + } + _disposed = true; + } + } + + #endregion + } } diff --git a/Src/Controls/TasksProcess/WaitControl.cs b/Src/Controls/TasksProcess/WaitControl.cs index a18e9abf..dc2c6c1b 100644 --- a/Src/Controls/TasksProcess/WaitControl.cs +++ b/Src/Controls/TasksProcess/WaitControl.cs @@ -14,9 +14,9 @@ namespace PPlus.Controls { - internal class WaitControl : BaseControl>, IControlWait, IDisposable + internal class WaitControl : BaseControl>, IControlWait, IDisposable { - private readonly WaitOptions _options; + private readonly WaitOptions _options; private CancellationTokenSource _lnkcts; private CancellationTokenSource _ctsesc; private Task _process; @@ -24,8 +24,11 @@ internal class WaitControl : BaseControl>, IControlWai private (int CursorLeft, int CursorTop) _initialCursor; private (int CursorLeft, int CursorTop) _spinnerCursor; private int _promptlines; + private EventWaitProcess _event; + private T _context; - public WaitControl(IConsoleControl console, WaitOptions options) : base(console, options) + + public WaitControl(IConsoleControl console, WaitOptions options) : base(console, options) { _options = options; } @@ -36,6 +39,8 @@ public override string InitControl(CancellationToken cancellationToken) { throw new PromptPlusException("Not have process to run"); } + _context = _options.Context; + _event = new EventWaitProcess(ref _context, false); _ctsesc = new CancellationTokenSource(); _lnkcts = CancellationTokenSource.CreateLinkedTokenSource(_ctsesc.Token, cancellationToken); return string.Empty; @@ -68,6 +73,7 @@ protected virtual void Dispose(bool disposing) _process?.Dispose(); _lnkcts?.Dispose(); _ctsesc?.Dispose(); + _event?.Dispose(); } _disposed = true; @@ -78,7 +84,7 @@ protected virtual void Dispose(bool disposing) #region IControlWait - public IControlWait Interaction(IEnumerable values, Action action) + public IControlWait Interaction(IEnumerable values, Action, T1> action) { foreach (var item in values) { @@ -86,30 +92,37 @@ public IControlWait Interaction(IEnumerable values, Action ShowElapsedTime() { _options.ShowElapsedTime = true; return this; } - public IControlWait Config(Action context) + public IControlWait Context(T value) + { + _options.Context = value; + return this; + } + + + public IControlWait Config(Action context) { context?.Invoke(_options); return this; } - public IControlWait Finish(string value) + public IControlWait Finish(string value) { _options.Finish = value; return this; } - public IControlWait TaskTitle(string value) + public IControlWait TaskTitle(string value) { _options.OverWriteTitlekName = value; return this; } - public IControlWait Spinner(SpinnersType spinnersType, Style? spinnerStyle = null, int? speedAnimation = null, IEnumerable? customspinner = null) + public IControlWait Spinner(SpinnersType spinnersType, Style? spinnerStyle = null, int? speedAnimation = null, IEnumerable? customspinner = null) { if (spinnersType == SpinnersType.Custom && customspinner.Any()) { @@ -128,7 +141,7 @@ public IControlWait Spinner(SpinnersType spinnersType, Style? spinnerStyle = nul } - public IControlWait MaxDegreeProcess(int value) + public IControlWait MaxDegreeProcess(int value) { if (value < 1) { @@ -138,12 +151,12 @@ public IControlWait MaxDegreeProcess(int value) return this; } - public IControlWait AddStep(StepMode stepMode, params Action[] process) + public IControlWait AddStep(StepMode stepMode, params Action, CancellationToken>[] process) { return AddStep(stepMode, string.Empty, string.Empty, process); } - public IControlWait AddStep(StepMode stepMode, string id, string description, params Action[] process) + public IControlWait AddStep(StepMode stepMode, string id, string description, params Action,CancellationToken>[] process) { foreach (var item in process) { @@ -167,7 +180,7 @@ public override void InputTemplate(ScreenBuffer screenBuffer) _process ??= Task.Run(() => RunAllTasks(_lnkcts.Token), CancellationToken.None); } - public override ResultPrompt> TryResult(CancellationToken cancellationToken) + public override ResultPrompt> TryResult(CancellationToken cancellationToken) { var abort = false; while (!_lnkcts.IsCancellationRequested) @@ -203,10 +216,10 @@ public override ResultPrompt> TryResult(CancellationTo abort = true; _ctsesc.Cancel(); } - return new ResultPrompt>(_options.States, abort); + return new ResultPrompt>(new ResultWaitProcess(_event.Context,_options.States.ToArray()), abort); } - public override void FinishTemplate(ScreenBuffer screenBuffer, IEnumerable result, bool aborted) + public override void FinishTemplate(ScreenBuffer screenBuffer, ResultWaitProcess result, bool aborted) { _ctsesc.Cancel(); if (aborted) @@ -282,7 +295,7 @@ private void RunAllTasks(CancellationToken cancelationtoken) { samedesc = (firstdesc == _options.States[i].Description); } - if (!cancelationtoken.IsCancellationRequested) + if (!cancelationtoken.IsCancellationRequested && !_event.CancelAllNextTasks) { var act = _options.Steps[i]; using var waitHandle = new AutoResetEvent(false); @@ -297,7 +310,7 @@ private void RunAllTasks(CancellationToken cancelationtoken) tm.Start(); try { - act.Invoke(cancelationtoken); + act.Invoke(_event,cancelationtoken); actsta = cancelationtoken.IsCancellationRequested? TaskStatus.Canceled: TaskStatus.RanToCompletion; } catch (Exception ex) diff --git a/Src/Controls/TasksProcess/WaitExtensions.cs b/Src/Controls/TasksProcess/WaitExtensions.cs index c0e0c721..bc817585 100644 --- a/Src/Controls/TasksProcess/WaitExtensions.cs +++ b/Src/Controls/TasksProcess/WaitExtensions.cs @@ -16,10 +16,21 @@ public static partial class PromptPlus /// /// The prompt text to write /// The description text to write - /// IEnumerable after Run method. - public static IControlWait WaitProcess(string prompt, string description=null) + /// + public static IControlWait WaitProcess(string prompt, string description = null) { - return WaitProcess(prompt,description, null); + return WaitProcess(prompt, description, null); + } + + /// + /// Create Wait Control + /// + /// The prompt text to write + /// The description text to write + /// + public static IControlWait WaitProcess(string prompt, string description = null) + { + return WaitProcess(prompt, description, null); } /// @@ -28,17 +39,37 @@ public static IControlWait WaitProcess(string prompt, string description=null) /// The prompt text to write /// The description text to write /// The config action - /// IEnumerable after Run method. - public static IControlWait WaitProcess(string prompt, string description, Action config = null) + /// + public static IControlWait WaitProcess(string prompt, string description, Action config = null) { - var opt = new WaitOptions(false) + var opt = new WaitOptions(false) { WaitTime = false, OptPrompt = prompt, OptDescription = description, }; config?.Invoke(opt); - return new WaitControl(_consoledrive, opt); + return new WaitControl(_consoledrive, opt); + } + + + /// + /// Create Wait Control + /// + /// The prompt text to write + /// The description text to write + /// The config action + /// + public static IControlWait WaitProcess(string prompt, string description, Action config = null) + { + var opt = new WaitOptions(false) + { + WaitTime = false, + OptPrompt = prompt, + OptDescription = description, + }; + config?.Invoke(opt); + return new WaitControl(_consoledrive, opt); } /// @@ -50,11 +81,10 @@ public static IControlWait WaitProcess(string prompt, string description, Action /// True show Countdown, otherwise 'no' /// The config action /// for control - public static void WaitTimer(string prompt, TimeSpan delay, SpinnersType spinnersType = SpinnersType.Ascii, bool showCountdown = false, Action config = null, CancellationToken? cancellationToken = null) { var cts = cancellationToken ?? CancellationToken.None; - var opt = new WaitOptions(false) + var opt = new WaitOptions(false) { WaitTime = true, TimeDelay = delay, @@ -64,9 +94,10 @@ public static void WaitTimer(string prompt, TimeSpan delay, SpinnersType spinner opt.HideAfterFinish(true); opt.EnabledAbortKey(false); config?.Invoke(opt); - var aux = new WaitControl(_consoledrive, opt); + var aux = new WaitControl(_consoledrive, opt); + aux.Context(null); aux.Spinner(spinnersType); - aux.AddStep(StepMode.Sequential, (cts) => + aux.AddStep(StepMode.Sequential, (eventw, cts) => { cts.WaitHandle.WaitOne(delay); }); diff --git a/Src/Controls/TasksProcess/WaitOptions.cs b/Src/Controls/TasksProcess/WaitOptions.cs index 4cb857ef..cff981fa 100644 --- a/Src/Controls/TasksProcess/WaitOptions.cs +++ b/Src/Controls/TasksProcess/WaitOptions.cs @@ -10,7 +10,7 @@ namespace PPlus.Controls { - internal class WaitOptions : BaseOptions + internal class WaitOptions : BaseOptions { private WaitOptions() { @@ -22,11 +22,12 @@ internal WaitOptions(bool showcursor) : base(showcursor) Steps = new(); States = new(); } + public T Context { get; set; } = default; public TimeSpan TimeDelay { get; set; } public string OverWriteTitlekName { get; set; } public bool WaitTime { get; set; } public bool ShowCountdown { get; set; } - public List> Steps { get; set; } + public List, CancellationToken>> Steps { get; set; } public List States { get; set; } public Style SpinnerStyle { get; set; } = PromptPlus.StyleSchema.Prompt(); public string? Finish { get; set; } diff --git a/Src/Controls/TreeDiagram/IControlTreeViewMultiSelect.cs b/Src/Controls/TreeDiagram/IControlTreeViewMultiSelect.cs index 78da606f..922b024a 100644 --- a/Src/Controls/TreeDiagram/IControlTreeViewMultiSelect.cs +++ b/Src/Controls/TreeDiagram/IControlTreeViewMultiSelect.cs @@ -12,6 +12,7 @@ namespace PPlus.Controls /// /// Represents the interface with all Methods of the TreeViewMultiSelect control /// + /// type of return public interface IControlTreeViewMultiSelect : IPromptControls { /// diff --git a/Src/Controls/TreeDiagram/IControlTreeViewSelect.cs b/Src/Controls/TreeDiagram/IControlTreeViewSelect.cs index 3b9fc7f5..a3ea75ea 100644 --- a/Src/Controls/TreeDiagram/IControlTreeViewSelect.cs +++ b/Src/Controls/TreeDiagram/IControlTreeViewSelect.cs @@ -12,6 +12,7 @@ namespace PPlus.Controls /// /// Represents the interface with all Methods of the TreeView control /// + /// type of return public interface IControlTreeViewSelect : IPromptControls { /// diff --git a/Src/Drivers/ConsoleDriveMemory.cs b/Src/Drivers/ConsoleDriveMemory.cs index 8cca357b..c7681086 100644 --- a/Src/Drivers/ConsoleDriveMemory.cs +++ b/Src/Drivers/ConsoleDriveMemory.cs @@ -304,17 +304,17 @@ private int CountLines(Segment[] segments, int left, int width, int padleft) { return 1; } + var pos = left; foreach (var segment in segments.Where(x => !x.IsAnsiControl)) { var overflow = segment.Style.OverflowStrategy; var parts = segment.Text.Split(Environment.NewLine, StringSplitOptions.RemoveEmptyEntries); + if (pos < padleft) + { + pos = padleft; + } foreach (var (_, first, last, part) in parts.Enumerate()) { - var pos = left; - if (pos < padleft) - { - pos = padleft; - } if (part != null) { pos += part.GetWidth(); @@ -355,6 +355,7 @@ private int CountLines(Segment[] segments, int left, int width, int padleft) if (!first) { qtd++; + pos = padleft; } } } diff --git a/Src/Drivers/ConsoleDriveWindows.cs b/Src/Drivers/ConsoleDriveWindows.cs index 315469aa..727fa0ec 100644 --- a/Src/Drivers/ConsoleDriveWindows.cs +++ b/Src/Drivers/ConsoleDriveWindows.cs @@ -8,6 +8,7 @@ using System; using System.IO; using System.Linq; +using System.Security.Cryptography; using System.Text; using System.Threading; @@ -252,14 +253,14 @@ private int CountLines(Segment[] segments, int left, int width, int padleft) { return 1; } + int pos = left; foreach (var segment in segments.Where(x => !x.IsAnsiControl)) { var overflow = segment.Style.OverflowStrategy; var parts = segment.Text.Split(Environment.NewLine, StringSplitOptions.RemoveEmptyEntries); foreach (var (_, first, last, part) in parts.Enumerate()) { - var pos = left; - if (pos < padleft) + if (first && pos < padleft) { pos = padleft; } @@ -302,6 +303,7 @@ private int CountLines(Segment[] segments, int left, int width, int padleft) if (!first) { qtd++; + pos = padleft; } } } diff --git a/Src/Drivers/ConsoleKeyInfoExtensions.cs b/Src/Drivers/ConsoleKeyInfoExtensions.cs index ee12fa21..50303615 100644 --- a/Src/Drivers/ConsoleKeyInfoExtensions.cs +++ b/Src/Drivers/ConsoleKeyInfoExtensions.cs @@ -79,6 +79,36 @@ public static bool IsPressEnterKey(this ConsoleKeyInfo keyinfo, bool emacskeys = return (keyinfo.KeyChar == 13 && keyinfo.Modifiers == 0) || (keyinfo.KeyChar == 10 && keyinfo.Modifiers == 0) || (emacskeys && keyinfo.Key == ConsoleKey.J && keyinfo.Modifiers == ConsoleModifiers.Control); } + + /// + /// Check ConsoleKeyInfo is Yes key + /// + /// to check + /// true if equal otherwise false. + public static bool IsYesResponseKey(this ConsoleKeyInfo keyinfo) + { + if (!PromptPlus.Config.YesChar.HasValue) + { + return false; + } + return char.ToLowerInvariant(keyinfo.KeyChar) == char.ToLowerInvariant(PromptPlus.Config.YesChar.Value) && keyinfo.Modifiers == 0; + } + + /// + /// Check ConsoleKeyInfo is Yes key + /// + /// to check + /// true if equal otherwise false. + public static bool IsNoResponseKey(this ConsoleKeyInfo keyinfo) + { + if (!PromptPlus.Config.NoChar.HasValue) + { + return false; + } + return char.ToLowerInvariant(keyinfo.KeyChar) == char.ToLowerInvariant(PromptPlus.Config.NoChar.Value) && keyinfo.Modifiers == 0; + } + + /// /// Check ConsoleKeyInfo is Lowers Current Word Emacs Key ///
Alt+L = Lowers the case of every character from the cursor's position to the end of the current words
diff --git a/Src/NugetREADME.md b/Src/NugetREADME.md index 0a7ac12a..2ae7ea18 100644 --- a/Src/NugetREADME.md +++ b/Src/NugetREADME.md @@ -10,7 +10,16 @@ PromptPlus **Supports 4/8/24-bit colors** in the terminal with auto-detection of **PromptPlus** was developed in c# with the **netstandard2.1**, **.Net 6** and **.Net 7** target frameworks. -## What news in PromptPlus V4.0.1 +## What news in V4.0.2 +- New Control Pipeline + - PromptPlus.Pipeline(T startvalue) +- Changed WaitControl to take context value in tasks and return context in result + - There are small break-chages +- Add Answer key check equals "Yes"/"No" using config values + - IsYesResponseKey(this ConsoleKeyInfo keyinfo) + - IsNoResponseKey(this ConsoleKeyInfo keyinfo) + +## What news in V4.0.1 - Fixed duplicate tooltip in calendar - New console engine - Supports 4/8/24-bit colors @@ -19,7 +28,7 @@ PromptPlus **Supports 4/8/24-bit colors** in the terminal with auto-detection of - New support feature colors - All controls have been improved to accept color customization, new features and new design. - Added new filter for colletion by "Contains" or "StartsWith" -- Added powerful new controls (eg:Calendar, Chartbar, Treeview, wait tasks Parallel/Sequential, 8 progress bar types, wait timer, 19 spinners types, Gradient colors and more) +- Added powerful new controls (eg:Pipeline, Calendar, Chartbar, Treeview, wait tasks Parallel/Sequential, 8 progress bar types, wait timer, 19 spinners types, Gradient colors and more) ## **PromptPlus Controls - Sample Usage** diff --git a/Src/PromptPlus.csproj b/Src/PromptPlus.csproj index 1bb326d3..a4270e58 100644 --- a/Src/PromptPlus.csproj +++ b/Src/PromptPlus.csproj @@ -30,7 +30,7 @@ PromptPlus NugetREADME.md https://fracerqueira.github.io/PromptPlus - 4.0.1 + 4.0.2 icon.png © 2021 - Fernando Cerqueira False diff --git a/Src/README.txt b/Src/README.txt index aa3c1d17..588f0695 100644 --- a/Src/README.txt +++ b/Src/README.txt @@ -6,7 +6,7 @@ |_| |_| \___/|_| |_| |_| .__/ \__|_| |_|\__,_|___/ |_| -Welcome to PromptPlus v4.0.0 +Welcome to PromptPlus v4.0.2 ========================================================= Interactive command-line toolkit for .Net core with powerful controls and commands @@ -29,8 +29,19 @@ PromptPlus was developed in c# with target frameworks: - .NET 6 - .NET 7 -*** What news in PromptPlus V4.0.1 *** ---------------------------------------- +*** What news in V4.0.2 *** +--------------------------- + +- New Control Pipeline + - PromptPlus.Pipeline(T startvalue) +- Changed WaitControl to take context value in tasks and return context in result + - There are small break-chages +- Add Answer key check equals "Yes"/"No" using config values + - IsYesResponseKey(this ConsoleKeyInfo keyinfo) + - IsNoResponseKey(this ConsoleKeyInfo keyinfo) + +*** What news in V4.0.1 *** +--------------------------- - Fixed duplicate tooltip in calendar - New console engine - Supports 4/8/24-bit colors @@ -39,7 +50,7 @@ PromptPlus was developed in c# with target frameworks: - New support feature colors - All controls have been improved to accept color customization, new features and new design. - Added new filter for colletion by "Contains" or "StartsWith" -- Added powerful new controls (eg: Calendar, Chartbar, Treeview, wait tasks Parallel/Sequential, +- Added powerful new controls (eg: Pipeline, Calendar, Chartbar, Treeview, wait tasks Parallel/Sequential, 8 progress bar types, wait timer, 19 spinners types, Gradient colors and more) **PromptPlus Controls - Sample Usage** diff --git a/UnitTests/Controls/TaskWaitControl/WaitControlTests.cs b/UnitTests/Controls/TaskWaitControl/WaitControlTests.cs index c6b39ea0..feae21b1 100644 --- a/UnitTests/Controls/TaskWaitControl/WaitControlTests.cs +++ b/UnitTests/Controls/TaskWaitControl/WaitControlTests.cs @@ -9,10 +9,10 @@ public class WaitControlTests : BaseTest [Fact] public void Should_ValidInitControlPrompt1() { - var ctrl = (WaitControl)PromptPlus + var ctrl = (WaitControl)PromptPlus .WaitProcess("P") - .AddStep(StepMode.Sequential,(cts) => - { + .AddStep(StepMode.Sequential, (_, cts) => + { }); ActionOnDispose = () => ctrl.FinalizeControl(CancellationToken.None); @@ -24,9 +24,9 @@ public void Should_ValidInitControlPrompt1() [Fact] public void Should_ValidInitControlPrompt2() { - var ctrl = (WaitControl)PromptPlus - .WaitProcess("P","D") - .AddStep(StepMode.Sequential, (cts) => + var ctrl = (WaitControl)PromptPlus + .WaitProcess("P", "D") + .AddStep(StepMode.Sequential, (_, cts) => { }); @@ -39,10 +39,10 @@ public void Should_ValidInitControlPrompt2() [Fact] public void Should_OverwriteCultureTaskName() { - var ctrl = (WaitControl)PromptPlus + var ctrl = (WaitControl)PromptPlus .WaitProcess("P", "D") .TaskTitle("XXXXXXXXXXXX") - .AddStep(StepMode.Sequential, "task1", "desc task1", (cts) => + .AddStep(StepMode.Sequential, "task1", "desc task1", (_, cts) => { Thread.Sleep(500); }); @@ -58,7 +58,7 @@ public void Should_OverwriteCultureTaskName() ctrl.InputTemplate(new ScreenBuffer()); var result = ctrl.TryResult(CancellationToken.None); Assert.False(result.IsRunning); - Assert.True(result.Value.Count() == 1); + Assert.True(result.Value.States.Count() == 1); }); }); Assert.Contains("XXXXXXXXXXXX", output); @@ -67,11 +67,11 @@ public void Should_OverwriteCultureTaskName() [Fact] public void Should_Interaction() { - var ctrl = (WaitControl)PromptPlus + var ctrl = (WaitControl)PromptPlus .WaitProcess("P", "D") .Interaction(new string[2] { "", "" }, (ctrl, _) => { - ctrl.AddStep(StepMode.Sequential, (cts) => + ctrl.AddStep(StepMode.Sequential, (_, cts) => { }); }); @@ -85,8 +85,8 @@ public void Should_Interaction() ctrl.InputTemplate(new ScreenBuffer()); var result = ctrl.TryResult(CancellationToken.None); Assert.True(!result.IsRunning); - Assert.True(result.Value.Count() == 2); - Assert.True(result.Value.First().Status == TaskStatus.RanToCompletion); + Assert.True(result.Value.States.Count() == 2); + Assert.True(result.Value.States.First().Status == TaskStatus.RanToCompletion); }); } @@ -94,9 +94,9 @@ public void Should_Interaction() [Fact] public void Should_Runtask1() { - var ctrl = (WaitControl)PromptPlus + var ctrl = (WaitControl)PromptPlus .WaitProcess("P", "D") - .AddStep(StepMode.Sequential,"task1","desc task1" ,(cts) => + .AddStep(StepMode.Sequential, "task1", "desc task1", (_, cts) => { Thread.Sleep(250); }); @@ -112,9 +112,9 @@ public void Should_Runtask1() ctrl.InputTemplate(new ScreenBuffer()); var result = ctrl.TryResult(CancellationToken.None); Assert.True(!result.IsRunning); - Assert.True(result.Value.Count() == 1); - Assert.True(result.Value.First().Status == TaskStatus.RanToCompletion); - Assert.True(result.Value.First().ElapsedTime > TimeSpan.FromMilliseconds(250)); + Assert.True(result.Value.States.Count() == 1); + Assert.True(result.Value.States.First().Status == TaskStatus.RanToCompletion); + Assert.True(result.Value.States.First().ElapsedTime > TimeSpan.FromMilliseconds(250)); }); }); Assert.Contains("desc task1", output); @@ -124,9 +124,9 @@ public void Should_Runtask1() [Fact] public void Should_RuntaskWithException() { - var ctrl = (WaitControl)PromptPlus + var ctrl = (WaitControl)PromptPlus .WaitProcess("P", "D") - .AddStep(StepMode.Sequential, "task1", "desc task1", (cts) => + .AddStep(StepMode.Sequential, "task1", "desc task1", (_, cts) => { cts.WaitHandle.WaitOne(400); throw new Exception(); @@ -139,14 +139,14 @@ public void Should_RuntaskWithException() var output = PromptPlus.RecordOutput(() => { ctrl.InputTemplate(new ScreenBuffer()); - ResultPrompt>? result = null; + ResultPrompt>? result = null; CompletesIn(3000, () => { result = ctrl.TryResult(CancellationToken.None); - },true); + }, true); Assert.False(result!.Value.IsRunning); - Assert.True(result!.Value.Value.Count() == 1); - Assert.True(result!.Value.Value.First().Status == TaskStatus.Faulted); + Assert.True(result!.Value.Value.States.Count() == 1); + Assert.True(result!.Value.Value.States.First().Status == TaskStatus.Faulted); }); Assert.Contains("desc task1", output); } @@ -154,8 +154,9 @@ public void Should_RuntaskWithException() [Fact] public void Should_showAcceptInputEsc() { - var ctrl = (WaitControl)PromptPlus.WaitProcess("P", "D") - .AddStep(StepMode.Parallel, (_) => { }); + var ctrl = (WaitControl)PromptPlus + .WaitProcess("P", "D") + .AddStep(StepMode.Parallel, (_, _) => { }); ActionOnDispose = () => ctrl.FinalizeControl(CancellationToken.None); ctrl.InitControl(CancellationToken.None); @@ -174,11 +175,11 @@ public void Should_showAcceptInputEsc() [Fact] public void Should_notshowAcceptInputEsc() { - var ctrl = (WaitControl)PromptPlus.WaitProcess("P", "D", (cfg) => + var ctrl = (WaitControl)PromptPlus.WaitProcess("P", "D", (cfg) => { cfg.EnabledAbortKey(false); }) - .AddStep(StepMode.Parallel, (_) => { }); + .AddStep(StepMode.Parallel, (_, _) => { }); ActionOnDispose = () => ctrl.FinalizeControl(CancellationToken.None); ctrl.InitControl(CancellationToken.None); @@ -197,11 +198,11 @@ public void Should_notshowAcceptInputEsc() [Fact] public void Should_AcceptInputTemplateCustomTooltip() { - var ctrl = (WaitControl)PromptPlus.WaitProcess("P", "D", (cfg) => + var ctrl = (WaitControl)PromptPlus.WaitProcess("P", "D", (cfg) => { cfg.Tooltips("CustomTooltip"); }) - .AddStep(StepMode.Parallel, (_) => { }); + .AddStep(StepMode.Parallel, (_, _) => { }); ActionOnDispose = () => ctrl.FinalizeControl(CancellationToken.None); ctrl.InitControl(CancellationToken.None); @@ -214,14 +215,14 @@ public void Should_AcceptInputTemplateCustomTooltip() var result = ctrl.TryResult(CancellationToken.None); }); }); - Assert.Contains("CustomTooltip",output); + Assert.Contains("CustomTooltip", output); } [Fact] public void Should_TryResulAcceptEsc() { - var ctrl = (WaitControl)PromptPlus.WaitProcess("P", "D") - .AddStep(StepMode.Sequential, (cts) => + var ctrl = (WaitControl)PromptPlus.WaitProcess("P", "D") + .AddStep(StepMode.Sequential, (_, cts) => { cts.WaitHandle.WaitOne(5000); }); @@ -243,12 +244,12 @@ public void Should_TryResulAcceptEsc() [Fact] public void Should_TryResulNotAcceptEsc() { - var ctrl = (WaitControl)PromptPlus.WaitProcess("P", "D") - .AddStep(StepMode.Sequential, (cts) => + var ctrl = (WaitControl)PromptPlus.WaitProcess("P", "D") + .AddStep(StepMode.Sequential, (_, cts) => { cts.WaitHandle.WaitOne(2000); }) - .Config((cfg) => + .Config((cfg) => { cfg.EnabledAbortKey(false); }); @@ -264,17 +265,17 @@ public void Should_TryResulNotAcceptEsc() var result = ctrl.TryResult(CancellationToken.None); Assert.True(!result.IsAborted); Assert.False(result.IsRunning); - Assert.True(result.Value.First().ElapsedTime > TimeSpan.FromSeconds(2)); + Assert.True(result.Value.States.First().ElapsedTime > TimeSpan.Zero); }); } [Fact] public void Should_TryResultAbort() { - var ctrl = (WaitControl)PromptPlus.WaitProcess("P", "D") - .AddStep(StepMode.Sequential, (cts) => + var ctrl = (WaitControl)PromptPlus.WaitProcess("P", "D") + .AddStep(StepMode.Sequential, (_, cts) => { - cts.WaitHandle.WaitOne(5000); + cts.WaitHandle.WaitOne(5000); }); ActionOnDispose = () => ctrl.FinalizeControl(CancellationToken.None); @@ -297,13 +298,152 @@ public void Should_TryResultAbort() }); } + [Fact] + public void Should_EventAbortSequential() + { + var ctrl = (WaitControl)PromptPlus.WaitProcess("P", "D") + .MaxDegreeProcess(2) + .AddStep(StepMode.Sequential, (_, cts) => + { + cts.WaitHandle.WaitOne(1000); + }) + .AddStep(StepMode.Sequential, (evt, cts) => + { + evt.CancelAllNextTasks = true; + cts.WaitHandle.WaitOne(2000); + + }) + .AddStep(StepMode.Sequential, (_, cts) => + { + cts.WaitHandle.WaitOne(5000); + }) + .AddStep(StepMode.Sequential, (_, cts) => + { + cts.WaitHandle.WaitOne(5000); + }); + + ActionOnDispose = () => ctrl.FinalizeControl(CancellationToken.None); + + + using var cts = new CancellationTokenSource(); + + ctrl.InitControl(cts.Token); + + ctrl.InputTemplate(new ScreenBuffer()); + + CompletesIn(8000, () => + { + var result = ctrl.TryResult(cts.Token); + Assert.False(result.IsAborted); + Assert.Equal(2,result.Value.States.Count(x => x.Status == TaskStatus.Canceled)); + }); + } + + [Fact] + public void Should_EventChangeConext() + { + var root = new object(); + var ctrl = (WaitControl)PromptPlus.WaitProcess("P", "D") + .MaxDegreeProcess(2) + .Context(0) + .AddStep(StepMode.Parallel, (evt, cts) => + { + //not thread-safed + lock (root) + { + evt.Context++; + } + }) + .AddStep(StepMode.Parallel, (evt, cts) => + { + //not thread-safed + lock (root) + { + evt.Context++; + } + }) + .AddStep(StepMode.Parallel, (evt, cts) => + { + //not thread-safed + lock (root) + { + evt.Context++; + } + }) + .AddStep(StepMode.Parallel, (evt, cts) => + { + //not thread-safed + lock (root) + { + evt.Context++; + } + }); + + ActionOnDispose = () => ctrl.FinalizeControl(CancellationToken.None); + + + using var cts = new CancellationTokenSource(); + + ctrl.InitControl(cts.Token); + + ctrl.InputTemplate(new ScreenBuffer()); + + CompletesIn(1000, () => + { + var result = ctrl.TryResult(cts.Token); + Assert.False(result.IsAborted); + Assert.Equal(4, result.Value.Context); + }); + } + + [Fact] + public void Should_EventAbortParallel() + { + var ctrl = (WaitControl)PromptPlus.WaitProcess("P", "D") + .MaxDegreeProcess(2) + .AddStep(StepMode.Parallel, (evt, cts) => + { + evt.CancelAllNextTasks = true; + cts.WaitHandle.WaitOne(1000); + }) + .AddStep(StepMode.Parallel, (_, cts) => + { + cts.WaitHandle.WaitOne(2000); + + }) + .AddStep(StepMode.Parallel, (_, cts) => + { + cts.WaitHandle.WaitOne(5000); + }) + .AddStep(StepMode.Parallel, (_, cts) => + { + cts.WaitHandle.WaitOne(5000); + }); + + ActionOnDispose = () => ctrl.FinalizeControl(CancellationToken.None); + + + using var cts = new CancellationTokenSource(); + + ctrl.InitControl(cts.Token); + + ctrl.InputTemplate(new ScreenBuffer()); + + CompletesIn(8000, () => + { + var result = ctrl.TryResult(cts.Token); + Assert.False(result.IsAborted); + Assert.True(result.Value.States.Count(x => x.Status == TaskStatus.Canceled) >=2); + }); + } + [Fact] public void Should_AcceptCustomFinish() { - var ctrl = (WaitControl)PromptPlus.WaitProcess("P", "D") + var ctrl = (WaitControl)PromptPlus.WaitProcess("P", "D") .Finish("FinishTest") - .AddStep(StepMode.Parallel, (_) => { }); + .AddStep(StepMode.Parallel, (_, _) => { }); ActionOnDispose = () => ctrl.FinalizeControl(CancellationToken.None); ctrl.InitControl(CancellationToken.None); @@ -314,7 +454,7 @@ public void Should_AcceptCustomFinish() { ctrl.InputTemplate(new ScreenBuffer()); ctrl.TryResult(CancellationToken.None); - ctrl.FinishTemplate(new ScreenBuffer(),new StateProcess[] { },false); + ctrl.FinishTemplate(new ScreenBuffer(), new ResultWaitProcess(new object(), Array.Empty()), false); }); }); Assert.Contains("FinishTest", output); @@ -323,8 +463,8 @@ public void Should_AcceptCustomFinish() [Fact] public void Should_AcceptFinishAbort() { - var ctrl = (WaitControl)PromptPlus.WaitProcess("P", "D") - .AddStep(StepMode.Parallel, (_) => { }); + var ctrl = (WaitControl)PromptPlus.WaitProcess("P", "D") + .AddStep(StepMode.Parallel, (_, _) => { }); ActionOnDispose = () => ctrl.FinalizeControl(CancellationToken.None); ctrl.InitControl(CancellationToken.None); @@ -335,7 +475,7 @@ public void Should_AcceptFinishAbort() { ctrl.InputTemplate(new ScreenBuffer()); ctrl.TryResult(CancellationToken.None); - ctrl.FinishTemplate(new ScreenBuffer(), new StateProcess[] { }, true); + ctrl.FinishTemplate(new ScreenBuffer(), new ResultWaitProcess(new object(), Array.Empty()), true); }); }); var partmsg = Messages.CanceledKey.Split()[0]; @@ -345,16 +485,16 @@ public void Should_AcceptFinishAbort() [Fact] public void Should_WaitTime() { - var opt = new WaitOptions(false) + var opt = new WaitOptions(false) { WaitTime = true, TimeDelay = TimeSpan.FromSeconds(1), ShowCountdown = true, OptPrompt = "P" }; - var ctrl = new WaitControl((IConsoleControl)PromptPlus.Console, opt); + var ctrl = new WaitControl((IConsoleControl)PromptPlus.Console, opt); ctrl.Spinner(SpinnersType.Ascii); - ctrl.AddStep(StepMode.Sequential, (cts) => + ctrl.AddStep(StepMode.Sequential, (_, cts) => { cts.WaitHandle.WaitOne(TimeSpan.FromSeconds(1)); }); @@ -368,7 +508,7 @@ public void Should_WaitTime() var result = ctrl.TryResult(CancellationToken.None); Assert.False(result.IsAborted); Assert.False(result.IsRunning); - Assert.True(result.Value.First().ElapsedTime >= TimeSpan.FromSeconds(1)); + Assert.True(result.Value.States.First().ElapsedTime > TimeSpan.Zero); }); } @@ -376,11 +516,11 @@ public void Should_WaitTime() [Fact] public void Should_MaxDegreeProcess() { - var ctrl = (WaitControl)PromptPlus.WaitProcess("P", "D") + var ctrl = (WaitControl)PromptPlus.WaitProcess("P", "D") .MaxDegreeProcess(1) - .AddStep(StepMode.Parallel, (_) => { }) - .AddStep(StepMode.Parallel, (_) => { }) - .AddStep(StepMode.Parallel, (_) => { }); + .AddStep(StepMode.Parallel, (_, _) => { }) + .AddStep(StepMode.Parallel, (_, _) => { }) + .AddStep(StepMode.Parallel, (_, _) => { }); ActionOnDispose = () => ctrl.FinalizeControl(CancellationToken.None); @@ -392,7 +532,7 @@ public void Should_MaxDegreeProcess() { ctrl.InputTemplate(new ScreenBuffer()); var result = ctrl.TryResult(CancellationToken.None); - Assert.True(result.Value.Count() == 3); + Assert.True(result.Value.States.Count() == 3); Assert.True(!result.IsRunning); }); }); diff --git a/docs/apis/apis.md b/docs/apis/apis.md index 22fd1f21..9a0d891c 100644 --- a/docs/apis/apis.md +++ b/docs/apis/apis.md @@ -72,6 +72,10 @@ - [Config](./pplus.controls.config.md) +- [EventPipe<T>](./pplus.controls.eventpipe-1.md) + +- [EventWaitProcess<T>](./pplus.controls.eventwaitprocess-1.md) + - [FilterMode](./pplus.controls.filtermode.md) - [FormatTime](./pplus.controls.formattime.md) @@ -106,6 +110,8 @@ - [IControlMultiSelectBrowser](./pplus.controls.icontrolmultiselectbrowser.md) +- [IControlPipeline<T>](./pplus.controls.icontrolpipeline-1.md) + - [IControlProgressBar<T>](./pplus.controls.icontrolprogressbar-1.md) - [IControlSelect<T>](./pplus.controls.icontrolselect-1.md) @@ -120,7 +126,7 @@ - [IControlTreeViewSelect<T>](./pplus.controls.icontroltreeviewselect-1.md) -- [IControlWait](./pplus.controls.icontrolwait.md) +- [IControlWait<T>](./pplus.controls.icontrolwait-1.md) - [IPromptConfig](./pplus.controls.ipromptconfig.md) @@ -138,6 +144,10 @@ - [MaskedType](./pplus.controls.maskedtype.md) +- [PipeRunningStatus](./pplus.controls.piperunningstatus.md) + +- [PipeStatus](./pplus.controls.pipestatus.md) + - [PolicyInvalidDate](./pplus.controls.policyinvaliddate.md) - [ProgressBarType](./pplus.controls.progressbartype.md) @@ -146,10 +156,14 @@ - [ResultMasked](./pplus.controls.resultmasked.md) +- [ResultPipeline<T>](./pplus.controls.resultpipeline-1.md) + - [ResultProgessBar<T>](./pplus.controls.resultprogessbar-1.md) - [ResultPrompt<T>](./pplus.controls.resultprompt-1.md) +- [ResultWaitProcess<T>](./pplus.controls.resultwaitprocess-1.md) + - [SliderBarType](./pplus.controls.sliderbartype.md) - [SpinnersType](./pplus.controls.spinnerstype.md) diff --git a/docs/apis/pplus.controls.eventpipe-1.md b/docs/apis/pplus.controls.eventpipe-1.md new file mode 100644 index 00000000..d6e9b173 --- /dev/null +++ b/docs/apis/pplus.controls.eventpipe-1.md @@ -0,0 +1,138 @@ +# PromptPlus API:EventPipe + +[![Build](https://github.com/FRACerqueira/PromptPlus/workflows/Build/badge.svg)](https://github.com/FRACerqueira/PromptPlus/actions/workflows/build.yml) +[![Publish](https://github.com/FRACerqueira/PromptPlus/actions/workflows/publish.yml/badge.svg)](https://github.com/FRACerqueira/PromptPlus/actions/workflows/publish.yml) +[![License](https://img.shields.io/github/license/FRACerqueira/PromptPlus)](https://github.com/FRACerqueira/PromptPlus/blob/master/LICENSE) +[![NuGet](https://img.shields.io/nuget/v/PromptPlus)](https://www.nuget.org/packages/PromptPlus/) +[![Downloads](https://img.shields.io/nuget/dt/PromptPlus)](https://www.nuget.org/packages/PromptPlus/) + +[**Back to List Api**](./apis.md) + +# EventPipe<T> + +Namespace: PPlus.Controls + +Represents the event to pipe with with all Methods to change sequence + +```csharp +public class EventPipe +``` + +#### Type Parameters + +`T`
+Typeof Input + +Inheritance [Object](https://docs.microsoft.com/en-us/dotnet/api/system.object) → [EventPipe<T>](./pplus.controls.eventpipe-1.md) + +## Properties + +### **CurrentPipe** + +From Pipe + +```csharp +public string CurrentPipe { get; } +``` + +#### Property Value + +[String](https://docs.microsoft.com/en-us/dotnet/api/system.string)
+ +###
**FromPipe** + +From Pipe + +```csharp +public string FromPipe { get; } +``` + +#### Property Value + +[String](https://docs.microsoft.com/en-us/dotnet/api/system.string)
+ +###
**Input** + +Input value + +```csharp +public T Input { get; set; } +``` + +#### Property Value + +T
+ +###
**Pipes** + +List Pipes + +```csharp +public ReadOnlyCollection Pipes { get; } +``` + +#### Property Value + +[ReadOnlyCollection<String>](https://docs.microsoft.com/en-us/dotnet/api/system.collections.objectmodel.readonlycollection-1)
+ +###
**ToPipe** + +Next Pipe + +```csharp +public string ToPipe { get; private set; } +``` + +#### Property Value + +[String](https://docs.microsoft.com/en-us/dotnet/api/system.string)
+ +## Methods + +###
**AbortPipeline()** + +Abort Pipeline. + +```csharp +public void AbortPipeline() +``` + +### **EndPipeline()** + +End Pipeline. + +```csharp +public void EndPipeline() +``` + +### **NextPipe(String)** + +Set Next Pipe. + +```csharp +public void NextPipe(string value) +``` + +#### Parameters + +`value` [String](https://docs.microsoft.com/en-us/dotnet/api/system.string)
+ +###
**NextPipe<TID>(TID)** + +Set Next Pipe. + +```csharp +public void NextPipe(TID value) +``` + +#### Type Parameters + +`TID`
+ +#### Parameters + +`value` TID
+ + +- - - +[**Back to List Api**](./apis.md) diff --git a/docs/apis/pplus.controls.eventwaitprocess-1.md b/docs/apis/pplus.controls.eventwaitprocess-1.md new file mode 100644 index 00000000..0e12245f --- /dev/null +++ b/docs/apis/pplus.controls.eventwaitprocess-1.md @@ -0,0 +1,80 @@ +# PromptPlus API:EventWaitProcess + +[![Build](https://github.com/FRACerqueira/PromptPlus/workflows/Build/badge.svg)](https://github.com/FRACerqueira/PromptPlus/actions/workflows/build.yml) +[![Publish](https://github.com/FRACerqueira/PromptPlus/actions/workflows/publish.yml/badge.svg)](https://github.com/FRACerqueira/PromptPlus/actions/workflows/publish.yml) +[![License](https://img.shields.io/github/license/FRACerqueira/PromptPlus)](https://github.com/FRACerqueira/PromptPlus/blob/master/LICENSE) +[![NuGet](https://img.shields.io/nuget/v/PromptPlus)](https://www.nuget.org/packages/PromptPlus/) +[![Downloads](https://img.shields.io/nuget/dt/PromptPlus)](https://www.nuget.org/packages/PromptPlus/) + +[**Back to List Api**](./apis.md) + +# EventWaitProcess<T> + +Namespace: PPlus.Controls + +Represents the event to task process with with conex value + +```csharp +public class EventWaitProcess : System.IDisposable +``` + +#### Type Parameters + +`T`
+Typeof Input + +Inheritance [Object](https://docs.microsoft.com/en-us/dotnet/api/system.object) → [EventWaitProcess<T>](./pplus.controls.eventwaitprocess-1.md)
+Implements [IDisposable](https://docs.microsoft.com/en-us/dotnet/api/system.idisposable) + +## Properties + +###
**CancelAllNextTasks** + +Get/Set Cancel all next tasks. + +```csharp +public bool CancelAllNextTasks { get; set; } +``` + +#### Property Value + +[Boolean](https://docs.microsoft.com/en-us/dotnet/api/system.boolean)
+ +###
**Context** + +Get/set Context value + +```csharp +public T Context { get; set; } +``` + +#### Property Value + +T
+ +## Methods + +###
**Dispose()** + +Dispose + +```csharp +public void Dispose() +``` + +### **Dispose(Boolean)** + +Dispose + +```csharp +protected void Dispose(bool disposing) +``` + +#### Parameters + +`disposing` [Boolean](https://docs.microsoft.com/en-us/dotnet/api/system.boolean)
+if disposing + + +- - - +[**Back to List Api**](./apis.md) diff --git a/docs/apis/pplus.controls.icontrolmultiselect-1.md b/docs/apis/pplus.controls.icontrolmultiselect-1.md index ea7c9ea8..d5dbcad0 100644 --- a/docs/apis/pplus.controls.icontrolmultiselect-1.md +++ b/docs/apis/pplus.controls.icontrolmultiselect-1.md @@ -21,6 +21,7 @@ public interface IControlMultiSelect : IPromptControls> #### Type Parameters `T`
+typeof return Implements IPromptControls<IEnumerable<T>> diff --git a/docs/apis/pplus.controls.icontrolpipeline-1.md b/docs/apis/pplus.controls.icontrolpipeline-1.md new file mode 100644 index 00000000..f340be0e --- /dev/null +++ b/docs/apis/pplus.controls.icontrolpipeline-1.md @@ -0,0 +1,99 @@ +# PromptPlus API:IControlPipeline + +[![Build](https://github.com/FRACerqueira/PromptPlus/workflows/Build/badge.svg)](https://github.com/FRACerqueira/PromptPlus/actions/workflows/build.yml) +[![Publish](https://github.com/FRACerqueira/PromptPlus/actions/workflows/publish.yml/badge.svg)](https://github.com/FRACerqueira/PromptPlus/actions/workflows/publish.yml) +[![License](https://img.shields.io/github/license/FRACerqueira/PromptPlus)](https://github.com/FRACerqueira/PromptPlus/blob/master/LICENSE) +[![NuGet](https://img.shields.io/nuget/v/PromptPlus)](https://www.nuget.org/packages/PromptPlus/) +[![Downloads](https://img.shields.io/nuget/dt/PromptPlus)](https://www.nuget.org/packages/PromptPlus/) + +[**Back to List Api**](./apis.md) + +# IControlPipeline<T> + +Namespace: PPlus.Controls + +Represents the interface with all Methods of the Pipeline control + +```csharp +public interface IControlPipeline : IPromptControls> +``` + +#### Type Parameters + +`T`
+typeof return + +Implements IPromptControls<ResultPipeline<T>> + +## Methods + +###
**AddPipe(String, Action<EventPipe<T>, CancellationToken>, Func<EventPipe<T>, CancellationToken, Boolean>)** + +Add the pipe + +```csharp +IControlPipeline AddPipe(string idpipe, Action, CancellationToken> command, Func, CancellationToken, Boolean> condition) +``` + +#### Parameters + +`idpipe` [String](https://docs.microsoft.com/en-us/dotnet/api/system.string)
+The unique id to pipe + +`command` Action<EventPipe<T>, CancellationToken>
+The handler to execute. See [EventPipe<T>](./pplus.controls.eventpipe-1.md) to modified sequence + +`condition` Func<EventPipe<T>, CancellationToken, Boolean>
+The condition to start pipe. If true execute pipe, otherwise goto next pipe. See [EventPipe<T>](./pplus.controls.eventpipe-1.md) to modified sequence + +#### Returns + +[IControlPipeline<T>](./pplus.controls.icontrolpipeline-1.md) + +###
**AddPipe<TID>(TID, Action<EventPipe<T>, CancellationToken>, Func<EventPipe<T>, CancellationToken, Boolean>)** + +Add the pipe by enum ID + +```csharp +IControlPipeline AddPipe(TID idpipe, Action, CancellationToken> command, Func, CancellationToken, Boolean> condition) +``` + +#### Type Parameters + +`TID`
+ +#### Parameters + +`idpipe` TID
+The unique id to pipe + +`command` Action<EventPipe<T>, CancellationToken>
+The handler to execute. See [EventPipe<T>](./pplus.controls.eventpipe-1.md) to modified sequence + +`condition` Func<EventPipe<T>, CancellationToken, Boolean>
+The condition to start pipe. If true execute pipe, otherwise goto next pipe. See [EventPipe<T>](./pplus.controls.eventpipe-1.md) to modified sequence + +#### Returns + +[IControlPipeline<T>](./pplus.controls.icontrolpipeline-1.md) + +###
**Config(Action<IPromptConfig>)** + +Custom config the control. + +```csharp +IControlPipeline Config(Action context) +``` + +#### Parameters + +`context` [Action<IPromptConfig>](https://docs.microsoft.com/en-us/dotnet/api/system.action-1)
+Action to apply changes. [IPromptConfig](./pplus.controls.ipromptconfig.md) + +#### Returns + +[IControlPipeline<T>](./pplus.controls.icontrolpipeline-1.md) + + +- - - +[**Back to List Api**](./apis.md) diff --git a/docs/apis/pplus.controls.icontrolprogressbar-1.md b/docs/apis/pplus.controls.icontrolprogressbar-1.md index 9ab0f21d..bd5dde63 100644 --- a/docs/apis/pplus.controls.icontrolprogressbar-1.md +++ b/docs/apis/pplus.controls.icontrolprogressbar-1.md @@ -21,6 +21,7 @@ public interface IControlProgressBar : IPromptControls> #### Type Parameters `T`
+typeof return Implements IPromptControls<ResultProgessBar<T>> diff --git a/docs/apis/pplus.controls.icontrolselect-1.md b/docs/apis/pplus.controls.icontrolselect-1.md index 3371d257..ab14f970 100644 --- a/docs/apis/pplus.controls.icontrolselect-1.md +++ b/docs/apis/pplus.controls.icontrolselect-1.md @@ -21,6 +21,7 @@ public interface IControlSelect : IPromptControls #### Type Parameters `T`
+typeof return Implements IPromptControls<T> diff --git a/docs/apis/pplus.controls.icontroltreeviewmultiselect-1.md b/docs/apis/pplus.controls.icontroltreeviewmultiselect-1.md index 9d080014..a297dfc8 100644 --- a/docs/apis/pplus.controls.icontroltreeviewmultiselect-1.md +++ b/docs/apis/pplus.controls.icontroltreeviewmultiselect-1.md @@ -21,6 +21,7 @@ public interface IControlTreeViewMultiSelect : IPromptControls #### Type Parameters `T`
+type of return Implements IPromptControls<T[]> diff --git a/docs/apis/pplus.controls.icontroltreeviewselect-1.md b/docs/apis/pplus.controls.icontroltreeviewselect-1.md index a8547f0c..f0a35527 100644 --- a/docs/apis/pplus.controls.icontroltreeviewselect-1.md +++ b/docs/apis/pplus.controls.icontroltreeviewselect-1.md @@ -21,6 +21,7 @@ public interface IControlTreeViewSelect : IPromptControls #### Type Parameters `T`
+type of return Implements IPromptControls<T> diff --git a/docs/apis/pplus.controls.icontrolwait-1.md b/docs/apis/pplus.controls.icontrolwait-1.md new file mode 100644 index 00000000..2d5a51a1 --- /dev/null +++ b/docs/apis/pplus.controls.icontrolwait-1.md @@ -0,0 +1,226 @@ +# PromptPlus API:IControlWait + +[![Build](https://github.com/FRACerqueira/PromptPlus/workflows/Build/badge.svg)](https://github.com/FRACerqueira/PromptPlus/actions/workflows/build.yml) +[![Publish](https://github.com/FRACerqueira/PromptPlus/actions/workflows/publish.yml/badge.svg)](https://github.com/FRACerqueira/PromptPlus/actions/workflows/publish.yml) +[![License](https://img.shields.io/github/license/FRACerqueira/PromptPlus)](https://github.com/FRACerqueira/PromptPlus/blob/master/LICENSE) +[![NuGet](https://img.shields.io/nuget/v/PromptPlus)](https://www.nuget.org/packages/PromptPlus/) +[![Downloads](https://img.shields.io/nuget/dt/PromptPlus)](https://www.nuget.org/packages/PromptPlus/) + +[**Back to List Api**](./apis.md) + +# IControlWait<T> + +Namespace: PPlus.Controls + +Represents the interface with all Methods of the WaitTimer/WaitProcess control + +```csharp +public interface IControlWait : IPromptControls> +``` + +#### Type Parameters + +`T`
+typeof return + +Implements IPromptControls<ResultWaitProcess<T>> + +## Methods + +###
**AddStep(StepMode, params Action<EventWaitProcess<T>, CancellationToken>[])** + +Add list of tasks to execute. + +```csharp +IControlWait AddStep(StepMode stepMode, params Action, CancellationToken>[] process) +``` + +#### Parameters + +`stepMode` [StepMode](./pplus.controls.stepmode.md)
+Sequential or parallel execution + +`process` Action<EventWaitProcess<T>, CancellationToken>[]
+list of tasks + +#### Returns + +[IControlWait<T>](./pplus.controls.icontrolwait-1.md) + +###
**AddStep(StepMode, String, String, params Action<EventWaitProcess<T>, CancellationToken>[])** + +Add list of tasks to execute with title and description + +```csharp +IControlWait AddStep(StepMode stepMode, string id, string label, params Action, CancellationToken>[] process) +``` + +#### Parameters + +`stepMode` [StepMode](./pplus.controls.stepmode.md)
+Sequential or parallel execution + +`id` [String](https://docs.microsoft.com/en-us/dotnet/api/system.string)
+Id of tasks + +`label` [String](https://docs.microsoft.com/en-us/dotnet/api/system.string)
+Label of tasks + +`process` Action<EventWaitProcess<T>, CancellationToken>[]
+list of tasks + +#### Returns + +[IControlWait<T>](./pplus.controls.icontrolwait-1.md) + +###
**Config(Action<IPromptConfig>)** + +Custom config the control. + +```csharp +IControlWait Config(Action context) +``` + +#### Parameters + +`context` [Action<IPromptConfig>](https://docs.microsoft.com/en-us/dotnet/api/system.action-1)
+Action to apply changes. [IPromptConfig](./pplus.controls.ipromptconfig.md) + +#### Returns + +[IControlWait<T>](./pplus.controls.icontrolwait-1.md) + +###
**Context(T)** + +Set Contex value for all tasks + +```csharp +IControlWait Context(T value) +``` + +#### Parameters + +`value` T
+Context value + +#### Returns + +[IControlWait<T>](./pplus.controls.icontrolwait-1.md) + +###
**Finish(String)** + +Finish answer to show when Wait process is completed. + +```csharp +IControlWait Finish(string text) +``` + +#### Parameters + +`text` [String](https://docs.microsoft.com/en-us/dotnet/api/system.string)
+Text Finish answer + +#### Returns + +[IControlWait<T>](./pplus.controls.icontrolwait-1.md) + +###
**Interaction<T1>(IEnumerable<T1>, Action<IControlWait<T>, T1>)** + +Execute a action foreach item of colletion passed as a parameter + +```csharp +IControlWait Interaction(IEnumerable values, Action, T1> action) +``` + +#### Type Parameters + +`T1`
+ +#### Parameters + +`values` IEnumerable<T1>
+Colletion for interaction + +`action` Action<IControlWait<T>, T1>
+Action to execute + +#### Returns + +[IControlWait<T>](./pplus.controls.icontrolwait-1.md) + +###
**MaxDegreeProcess(Int32)** + +Maximum number of concurrent tasks enable. Default vaue is number of processors. + +```csharp +IControlWait MaxDegreeProcess(int value) +``` + +#### Parameters + +`value` [Int32](https://docs.microsoft.com/en-us/dotnet/api/system.int32)
+Number of concurrent tasks + +#### Returns + +[IControlWait<T>](./pplus.controls.icontrolwait-1.md) + +###
**ShowElapsedTime()** + +Define if show Elapsed Time for each task. + +```csharp +IControlWait ShowElapsedTime() +``` + +#### Returns + +[IControlWait<T>](./pplus.controls.icontrolwait-1.md) + +### **Spinner(SpinnersType, Nullable<Style>, Nullable<Int32>, IEnumerable<String>)** + +Overwrite [SpinnersType](./pplus.controls.spinnerstype.md). Default value is SpinnersType.Ascii +
When use custom spinner, if has unicode values console does not support it, the rendering may not be as expected + +```csharp +IControlWait Spinner(SpinnersType spinnersType, Nullable