├── .gitattributes
├── .gitignore
├── ConsoleProgressBar.sln
├── ConsoleProgressBar
├── ConsoleProgressBar.csproj
├── ConsoleProgressBar.csproj.user
├── ConsoleProgressBar.xml
├── Element.cs
├── ElementList.cs
├── Extensions
│ ├── ElementExtensions.cs
│ ├── StringExtensions.cs
│ └── TimeSpanExtensions.cs
├── Layout.Body.cs
├── Layout.Margin.cs
├── Layout.Marquee.cs
├── Layout._.cs
├── ProgressBar.cs
├── Text.Body.cs
├── Text.Description.cs
└── Text._.cs
├── ConsoleProgressBarDemo
├── ConsoleProgressBarDemo.csproj
├── DemoProgressBar.cs
└── Program.cs
├── LICENSE
├── README.md
└── docs
├── ConsoleProgressBar.Extensions
├── ElementExtensions.md
├── StringExtensions.md
└── TimeSpanExtensions.md
├── ConsoleProgressBar
└── ProgressBar.md
├── img
├── ProgressBarConsole-Default-Writing.gif
├── ProgressBarConsole-Default.gif
├── ProgressBarConsole-Demo.gif
├── ProgressBarConsole-Demo2.gif
├── ProgressBarConsole-Demo3.gif
├── ProgressBarConsole-Demo4.gif
├── ProgressBarConsole-Example01.gif
├── ProgressBarConsole-Example02.gif
├── ProgressBarConsole-Example03.gif
├── ProgressBarConsole-Example04.gif
├── ProgressBarConsole-Example05.gif
├── ProgressBarConsole-Example06.gif
├── ProgressBarConsole-Example07.gif
├── ProgressBarConsole-Example08.gif
├── ProgressBarConsole-Example09.gif
├── ProgressBarConsole-Example10.gif
├── ProgressBarConsole-Example11.gif
└── ProgressBarConsole-Example_Usage1.gif
└── index.md
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .vs
2 | obj
3 | bin
4 | .cr
5 |
--------------------------------------------------------------------------------
/ConsoleProgressBar.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.30804.86
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConsoleProgressBar", "ConsoleProgressBar\ConsoleProgressBar.csproj", "{415D677E-01C5-46D0-B91A-4F78D06B47FE}"
7 | EndProject
8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConsoleProgressBarDemo", "ConsoleProgressBarDemo\ConsoleProgressBarDemo.csproj", "{C0CA7D84-1CDF-48B0-813B-48983ABACE7B}"
9 | EndProject
10 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Documentation", "Documentation", "{80ACAE36-3714-4C19-B52B-ECC2BB13F33B}"
11 | ProjectSection(SolutionItems) = preProject
12 | README.md = README.md
13 | EndProjectSection
14 | EndProject
15 | Global
16 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
17 | Debug|Any CPU = Debug|Any CPU
18 | Release|Any CPU = Release|Any CPU
19 | EndGlobalSection
20 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
21 | {415D677E-01C5-46D0-B91A-4F78D06B47FE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
22 | {415D677E-01C5-46D0-B91A-4F78D06B47FE}.Debug|Any CPU.Build.0 = Debug|Any CPU
23 | {415D677E-01C5-46D0-B91A-4F78D06B47FE}.Release|Any CPU.ActiveCfg = Release|Any CPU
24 | {415D677E-01C5-46D0-B91A-4F78D06B47FE}.Release|Any CPU.Build.0 = Release|Any CPU
25 | {C0CA7D84-1CDF-48B0-813B-48983ABACE7B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
26 | {C0CA7D84-1CDF-48B0-813B-48983ABACE7B}.Debug|Any CPU.Build.0 = Debug|Any CPU
27 | {C0CA7D84-1CDF-48B0-813B-48983ABACE7B}.Release|Any CPU.ActiveCfg = Release|Any CPU
28 | {C0CA7D84-1CDF-48B0-813B-48983ABACE7B}.Release|Any CPU.Build.0 = Release|Any CPU
29 | EndGlobalSection
30 | GlobalSection(SolutionProperties) = preSolution
31 | HideSolutionNode = FALSE
32 | EndGlobalSection
33 | GlobalSection(ExtensibilityGlobals) = postSolution
34 | SolutionGuid = {BFD762A6-09CC-411D-B56E-B49F4A1A6F98}
35 | EndGlobalSection
36 | EndGlobal
37 |
--------------------------------------------------------------------------------
/ConsoleProgressBar/ConsoleProgressBar.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard2.1
5 | iluvadev.$(MSBuildProjectName.Replace(" ", "_"))
6 | iluvadev.$(MSBuildProjectName)
7 | True
8 | iluvadev
9 | Copyright (c) 2021, iluvadev, and released under MIT License.
10 | Simple and versatile ProgressBar for Console Applications, written in C#, .Net Standard 2.1. Progress and/or Marquee, with estimated remaining time, custom layouts, dynamic text, colors and more.
11 | https://github.com/iluvadev/ConsoleProgressBar
12 | https://github.com/iluvadev/ConsoleProgressBar
13 | git
14 | progress-bar;console;library;netstandard
15 | 1.1.0
16 | 1.1.0
17 | MIT
18 | True
19 | $(AssemblyVersion)
20 |
21 |
22 |
23 | C:\Dev\iluvadev\projects\ConsoleProgressBar\ConsoleProgressBar\ConsoleProgressBar.xml
24 |
25 |
26 |
--------------------------------------------------------------------------------
/ConsoleProgressBar/ConsoleProgressBar.csproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | true
5 |
6 |
--------------------------------------------------------------------------------
/ConsoleProgressBar/ConsoleProgressBar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | iluvadev.ConsoleProgressBar
5 |
6 |
7 |
8 |
9 | An element of a ProgressBar
10 |
11 |
12 |
13 |
14 |
15 | Ctor
16 |
17 |
18 |
19 |
20 | Ctor
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 | Sets the ProgressBar element visible (or not)
29 |
30 |
31 |
32 |
33 |
34 |
35 | Sets the ProgressBar element visible (or not)
36 |
37 |
38 |
39 |
40 |
41 |
42 | Gets the ProgressBar element visibility
43 |
44 |
45 |
46 |
47 |
48 |
49 | Sets the Value of the ProgressBar element
50 |
51 |
52 |
53 |
54 |
55 |
56 | Sets the Value of the ProgressBar element
57 |
58 |
59 |
60 |
61 |
62 |
63 | Gets the Value of the ProgressBar element
64 |
65 |
66 |
67 |
68 |
69 |
70 | Sets the ForegroundColor of the ProgressBar element
71 |
72 |
73 |
74 |
75 |
76 |
77 | Sets the ForegroundColor of the ProgressBar element
78 |
79 |
80 |
81 |
82 |
83 |
84 | Gets the ForegroundColor of the ProgressBar element
85 |
86 |
87 |
88 |
89 |
90 |
91 | Sets the BackgroundColor of the ProgressBar element
92 |
93 |
94 |
95 |
96 |
97 |
98 | Sets the BackgroundColor of the ProgressBar element
99 |
100 |
101 |
102 |
103 |
104 |
105 | Gets the BackgroundColor of the ProgressBar element
106 |
107 |
108 |
109 |
110 |
111 |
112 | A list of Elements of a ProgressBar
113 |
114 |
115 |
116 |
117 |
118 | The List of Elements of a Progressbar
119 |
120 |
121 |
122 |
123 | Clears the List of elements of a ProgressBar
124 |
125 |
126 |
127 |
128 |
129 | Adds new Element to the List
130 |
131 |
132 |
133 |
134 |
135 | Extensions for Element
136 |
137 |
138 |
139 |
140 | Returns a list of Actions to write the element in Console
141 |
142 |
143 |
144 | Function to Transform the value before write
145 |
146 |
147 |
148 |
149 | Returns a list of Actions to write the element in Console
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 | Extensions for String
159 |
160 |
161 |
162 |
163 | Returns a string that occupy all console line/s
164 |
165 | The string to write in console
166 | To allow print the string in muliple lines or only in one:
167 | True: The text can be represented in more than one Console line (fill spaces to the end of last line)
168 | False: The text must be represented in only ONE line (truncate to fit or fill spaces to the end of line)
169 |
170 |
171 |
172 |
173 |
174 | Returns a string with exactly maxChars: Truncates string value or fill with spaces to fits exact length
175 |
176 |
177 |
178 | Text appended when it is truncated. Default: "..."
179 |
180 |
181 |
182 |
183 | TimeSpan extensions
184 |
185 |
186 |
187 |
188 | Gets a textual Sumarized for remaining time: X days, or Y hours, or Z minutes, etc.
189 |
190 |
191 |
192 |
193 |
194 |
195 | Gets a textual Sumarized for remaining time: X days, or Y hours, or Z minutes, etc.
196 |
197 |
198 |
199 |
200 |
201 |
202 | Converts a TimeSpan to String, showing all hours
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 | Converts a TimeSpan to String, showing all hours
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 | Definition of a Layout for a ProgressBar representation
219 |
220 |
221 |
222 |
223 | Definition of the Layout used to Render the Body of the ProgressBar
224 |
225 |
226 |
227 |
228 | Element To show in Pending Section
229 |
230 |
231 |
232 |
233 | Element to show in Progress Section
234 |
235 |
236 |
237 |
238 | Layout for the Text
239 |
240 |
241 |
242 |
243 | Sets the LayoutBody value for Pending and Progress elements
244 |
245 |
246 |
247 |
248 |
249 |
250 | Sets the LayoutBody value for Pending and Progress elements
251 |
252 |
253 |
254 |
255 |
256 |
257 | Sets the ForegroundColor for Pending and Progress elements
258 |
259 |
260 |
261 |
262 |
263 |
264 | Sets the ForegroundColor for Pending and Progress elements
265 |
266 |
267 |
268 |
269 |
270 |
271 | Sets the BackgroundColor for Pending and Progress elements
272 |
273 |
274 |
275 |
276 |
277 |
278 | Sets the BackgroundColor for Pending and Progress elements
279 |
280 |
281 |
282 |
283 |
284 |
285 | Ctor
286 |
287 |
288 |
289 |
290 | Definition of the Layout used to Render the Margins of the ProgressBar
291 |
292 |
293 |
294 |
295 | Element to show at the Margin Left (Start of the ProgressBar)
296 |
297 |
298 |
299 |
300 | Element to show at the Margin Right (End of the ProgressBar)
301 |
302 |
303 |
304 |
305 | Sets the LayoutMargin value for Start and End elements
306 |
307 |
308 |
309 |
310 |
311 |
312 | Sets the LayoutMargin value for Start and End elements
313 |
314 |
315 |
316 |
317 |
318 |
319 | Sets the ForegroundColor for Start and End elements
320 |
321 |
322 |
323 |
324 |
325 |
326 | Sets the ForegroundColor for Start and End elements
327 |
328 |
329 |
330 |
331 |
332 |
333 | Sets the BackgroundColor for Start and End elements
334 |
335 |
336 |
337 |
338 |
339 |
340 | Sets the BackgroundColor for Start and End elements
341 |
342 |
343 |
344 |
345 |
346 |
347 | Sets the visibility for Start and End elements
348 |
349 |
350 |
351 |
352 |
353 |
354 | Sets the visibility for Start and End elements
355 |
356 |
357 |
358 |
359 |
360 |
361 | Return the length of Margins
362 |
363 |
364 |
365 |
366 |
367 |
368 | Ctor
369 |
370 |
371 |
372 |
373 | Definition for the Marquee
374 | The Marquee is a char that moves around the ProgressBar
375 |
376 |
377 |
378 |
379 | Marquee definition when it moves over 'Pending' section
380 |
381 |
382 |
383 |
384 | Marquee definition when it moves over 'Progress' section
385 |
386 |
387 |
388 |
389 | Sets the Marqee definition when it moves over 'Pending' or 'Progress' section
390 |
391 |
392 |
393 |
394 |
395 |
396 | Sets the Marqee definition when it moves over 'Pending' or 'Progress' section
397 |
398 |
399 |
400 |
401 |
402 |
403 | Sets the Marqee Foreground Color when it moves over 'Pending' or 'Progress' section
404 |
405 |
406 |
407 |
408 |
409 |
410 | Sets the Marqee Foreground Color when it moves over 'Pending' or 'Progress' section
411 |
412 |
413 |
414 |
415 |
416 |
417 | Sets the Marqee Background Color when it moves over 'Pending' or 'Progress' section
418 |
419 |
420 |
421 |
422 |
423 |
424 | Sets the Marqee Background Color when it moves over 'Pending' or 'Progress' section
425 |
426 |
427 |
428 |
429 |
430 |
431 | Sets the Marqee Visibility when it moves over 'Pending' or 'Progress' section
432 |
433 |
434 |
435 |
436 |
437 |
438 | Sets the Marqee Visibility when it moves over 'Pending' or 'Progress' section
439 |
440 |
441 |
442 |
443 |
444 |
445 | Ctor
446 |
447 |
448 |
449 |
450 | Layout definition for Margins
451 |
452 |
453 |
454 |
455 | Layout definition for Marquee (character moving around the ProgressBar)
456 |
457 |
458 |
459 |
460 | Layout definition for Body
461 |
462 |
463 |
464 |
465 | Width of entire ProgressBar
466 | Default = 30
467 |
468 |
469 |
470 |
471 | Gets the internal Width of the ProgressBar
472 |
473 |
474 |
475 |
476 | Returns the Actions to do in order to Render the ProgressBar with this Layout
477 |
478 |
479 |
480 |
481 |
482 |
483 | A ProgressBar for Console
484 |
485 |
486 |
487 |
488 | Layout of the ProgressBar
489 |
490 |
491 |
492 |
493 | Text definitions for the ProgressBar
494 |
495 |
496 |
497 |
498 | Tag object
499 |
500 |
501 |
502 |
503 | The Maximum value
504 | Default = 100
505 |
506 |
507 |
508 |
509 | The current Value
510 | If Value is greater than Maximum, then updates Maximum value
511 |
512 |
513 |
514 |
515 | Percentage of progress
516 |
517 |
518 |
519 |
520 | Indicates if the ProgressBar has Progress defined (Maximum defined)
521 |
522 |
523 |
524 |
525 | The amount by which to increment the ProgressBar with each call to the PerformStep() method.
526 | Default = 1
527 |
528 |
529 |
530 |
531 | The Name of the Curent Element
532 |
533 |
534 |
535 |
536 | True to Print the ProgressBar always in last Console Line
537 | False to Print the ProgressBar fixed in Console (Current position at Starting)
538 | You can Write at Console and ProgressBar will always be below your lines
539 | Default = true
540 |
541 |
542 |
543 |
544 | Delay for repaint and recalculate all ProgressBar
545 | Default = 75
546 |
547 |
548 |
549 |
550 | True if ProgressBar is Started
551 |
552 |
553 |
554 |
555 | True if ProgressBar is Paused
556 |
557 |
558 |
559 |
560 | True if ProgresBar is Done: when disposing or Progress is finished
561 |
562 |
563 |
564 |
565 | Processing time (time paused excluded)
566 |
567 |
568 |
569 |
570 | Processing time per element (median)
571 |
572 |
573 |
574 |
575 | Estimated time finish (to Value = Maximum)
576 |
577 |
578 |
579 |
580 | A Lock for Writing to Console
581 |
582 |
583 |
584 |
585 | Creates an instance of ConsoleProgressBar
586 |
587 | Initial position of the ProgressBar
588 | True if ProgressBar starts automatically
589 |
590 |
591 |
592 | Starts the ProgressBar
593 |
594 |
595 |
596 |
597 | Pauses the ProgressBar
598 |
599 |
600 |
601 |
602 | Resume the ProgresBar
603 |
604 |
605 |
606 |
607 | Assigns the current Value, and optionally current ElementName and Tag
608 | If Value is greater than Maximum, updates Maximum as Value
609 |
610 |
611 |
612 |
613 |
614 |
615 |
616 | Advances the current position of the progress bar by the amount of the Step property
617 |
618 | The name of the new Element
619 |
620 |
621 |
622 |
623 | Advances the current position of the progress bar by the amount of the Step property
624 |
625 | Step to perform
626 | The name of the new Element
627 |
628 |
629 |
630 |
631 | WriteLine in Console when ProgressBar is running
632 |
633 |
634 |
635 |
636 | WriteLine in Console when ProgressBar is running
637 |
638 |
639 |
640 |
641 |
642 | WriteLine in Console when ProgressBar is running
643 |
644 |
645 |
646 |
647 |
648 |
649 | WriteLine in Console when ProgressBar is running
650 |
651 |
652 |
653 |
654 |
655 |
656 |
657 |
658 | Renders in Console the ProgressBar
659 |
660 |
661 |
662 |
663 | Unrenders (remove) from Console last ProgressBar printed
664 |
665 |
666 |
667 |
668 | Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
669 |
670 |
671 |
672 |
673 | Definitions for Texts in a ProgressBar
674 |
675 |
676 |
677 |
678 | Definition for the Texts in a ProgressBar
679 |
680 |
681 |
682 |
683 | Text in Body definition when ProgressBar is "Processing"
684 |
685 |
686 |
687 |
688 | Text in Body definition when ProgressBar is "Paused"
689 |
690 |
691 |
692 |
693 | Text in Body definition when ProgressBar is "Done"
694 |
695 |
696 |
697 |
698 | Sets the Body Text visibility
699 |
700 |
701 |
702 |
703 |
704 |
705 | Sets the Body Text visibility
706 |
707 |
708 |
709 |
710 |
711 |
712 | Sets the Body Text definition in all ProgressBar states ("Processing", "Paused", "Done")
713 |
714 |
715 |
716 |
717 |
718 |
719 | Sets the Body Text definition in all ProgressBar states ("Processing", "Paused", "Done")
720 |
721 |
722 |
723 |
724 |
725 |
726 | Sets the Body Text Foreground Color
727 |
728 |
729 |
730 |
731 |
732 |
733 | Sets the Body Text Foreground Color
734 |
735 |
736 |
737 |
738 |
739 |
740 | Sets the Body Text Background Color
741 |
742 |
743 |
744 |
745 |
746 |
747 | Sets the Body Text Background Color
748 |
749 |
750 |
751 |
752 |
753 |
754 | Ctor
755 |
756 |
757 |
758 |
759 | Gets the current Text Body definition by the ProgressBar context ("Processing", "Paused" or "Done")
760 |
761 |
762 |
763 |
764 |
765 |
766 | Definition for the Description lines in a ProgressBar
767 |
768 |
769 |
770 |
771 | Description lines definition when ProgressBar is "Processing"
772 |
773 |
774 |
775 |
776 | Description lines definition when ProgressBar is "Paused"
777 |
778 |
779 |
780 |
781 | Description lines definition when ProgressBar is "Done"
782 |
783 |
784 |
785 |
786 | Indentation for Description lines
787 |
788 |
789 |
790 |
791 | Ctor
792 |
793 |
794 |
795 |
796 | Clears Description Lines
797 |
798 |
799 |
800 |
801 |
802 | Gets the current Description Lines definition by the ProgressBar context ("Processing", "Paused" or "Done")
803 |
804 |
805 |
806 |
807 |
808 |
809 | Definition of the text in the same line as ProgressBar (Body)
810 |
811 |
812 |
813 |
814 | Definition of the texts in the lines below a ProgressBar (Description)
815 |
816 |
817 |
818 |
819 |
--------------------------------------------------------------------------------
/ConsoleProgressBar/Element.cs:
--------------------------------------------------------------------------------
1 | // Description: ProgressBar for Console Applications, with advanced features.
2 | // Project site: https://github.com/iluvadev/ConsoleProgressBar
3 | // Issues: https://github.com/iluvadev/ConsoleProgressBar/issues
4 | // License (MIT): https://github.com/iluvadev/ConsoleProgressBar/blob/main/LICENSE
5 | //
6 | // Copyright (c) 2021, iluvadev, and released under MIT License.
7 | //
8 |
9 | using System;
10 |
11 | namespace iluvadev.ConsoleProgressBar
12 | {
13 | ///
14 | /// An element of a ProgressBar
15 | ///
16 | ///
17 | public class Element
18 | {
19 | private Func _ValueGetter;
20 | private Func _ForegroundColorGetter;
21 | private Func _BackgroundColorGetter;
22 | private Func _VisibleGetter;
23 |
24 | ///
25 | /// Ctor
26 | ///
27 | public Element() { }
28 |
29 | ///
30 | /// Ctor
31 | ///
32 | ///
33 | ///
34 | ///
35 | public Element(T value, ConsoleColor foregroundColor, ConsoleColor backgroundColor)
36 | {
37 | SetValue(value);
38 | SetForegroundColor(foregroundColor);
39 | SetBackgroundColor(backgroundColor);
40 | }
41 |
42 | ///
43 | /// Sets the ProgressBar element visible (or not)
44 | ///
45 | ///
46 | ///
47 | public Element SetVisible(bool show)
48 | => SetVisible(pb => show);
49 |
50 | ///
51 | /// Sets the ProgressBar element visible (or not)
52 | ///
53 | ///
54 | ///
55 | public Element SetVisible(Func showGetter)
56 | {
57 | _VisibleGetter = showGetter;
58 | return this;
59 | }
60 | ///
61 | /// Gets the ProgressBar element visibility
62 | ///
63 | ///
64 | ///
65 | public bool GetVisible(ProgressBar progressBar)
66 | => _VisibleGetter?.Invoke(progressBar) ?? true;
67 |
68 | ///
69 | /// Sets the Value of the ProgressBar element
70 | ///
71 | ///
72 | ///
73 | public Element SetValue(T value) => SetValue(pb => value);
74 |
75 | ///
76 | /// Sets the Value of the ProgressBar element
77 | ///
78 | ///
79 | ///
80 | public Element SetValue(Func valueGetter)
81 | {
82 | _ValueGetter = valueGetter;
83 | return this;
84 | }
85 |
86 | ///
87 | /// Gets the Value of the ProgressBar element
88 | ///
89 | ///
90 | ///
91 | public virtual T GetValue(ProgressBar progressBar)
92 | => GetVisible(progressBar) && _ValueGetter != null ? _ValueGetter.Invoke(progressBar)
93 | : default;
94 |
95 | ///
96 | /// Sets the ForegroundColor of the ProgressBar element
97 | ///
98 | ///
99 | ///
100 | public Element SetForegroundColor(ConsoleColor foregroundColor)
101 | => SetForegroundColor(pb => foregroundColor);
102 |
103 | ///
104 | /// Sets the ForegroundColor of the ProgressBar element
105 | ///
106 | ///
107 | ///
108 | public Element SetForegroundColor(Func foregroundColorGetter)
109 | {
110 | _ForegroundColorGetter = foregroundColorGetter;
111 | return this;
112 | }
113 |
114 | ///
115 | /// Gets the ForegroundColor of the ProgressBar element
116 | ///
117 | ///
118 | ///
119 | public virtual ConsoleColor? GetForegroundColor(ProgressBar progressBar)
120 | => (GetVisible(progressBar) && _ForegroundColorGetter != null) ? _ForegroundColorGetter.Invoke(progressBar)
121 | : (ConsoleColor?)null;
122 |
123 | ///
124 | /// Sets the BackgroundColor of the ProgressBar element
125 | ///
126 | ///
127 | ///
128 | public Element SetBackgroundColor(ConsoleColor backgroundColor)
129 | => SetBackgroundColor(pb => backgroundColor);
130 |
131 | ///
132 | /// Sets the BackgroundColor of the ProgressBar element
133 | ///
134 | ///
135 | ///
136 | public Element SetBackgroundColor(Func backgroundColorGetter)
137 | {
138 | _BackgroundColorGetter = backgroundColorGetter;
139 | return this;
140 | }
141 |
142 | ///
143 | /// Gets the BackgroundColor of the ProgressBar element
144 | ///
145 | ///
146 | ///
147 | public virtual ConsoleColor? GetBackgroundColor(ProgressBar progressBar)
148 | => (GetVisible(progressBar) && _BackgroundColorGetter != null) ? _BackgroundColorGetter.Invoke(progressBar)
149 | : (ConsoleColor?)null;
150 | }
151 |
152 | }
153 |
--------------------------------------------------------------------------------
/ConsoleProgressBar/ElementList.cs:
--------------------------------------------------------------------------------
1 | // Description: ProgressBar for Console Applications, with advanced features.
2 | // Project site: https://github.com/iluvadev/ConsoleProgressBar
3 | // Issues: https://github.com/iluvadev/ConsoleProgressBar/issues
4 | // License (MIT): https://github.com/iluvadev/ConsoleProgressBar/blob/main/LICENSE
5 | //
6 | // Copyright (c) 2021, iluvadev, and released under MIT License.
7 | //
8 |
9 | using System.Collections.Generic;
10 |
11 | namespace iluvadev.ConsoleProgressBar
12 | {
13 | ///
14 | /// A list of Elements of a ProgressBar
15 | ///
16 | ///
17 | public class ElementList
18 | {
19 | ///
20 | /// The List of Elements of a Progressbar
21 | ///
22 | public List> List { get; } = new List>();
23 |
24 | ///
25 | /// Clears the List of elements of a ProgressBar
26 | ///
27 | ///
28 | public ElementList Clear()
29 | {
30 | List.Clear();
31 | return this;
32 | }
33 |
34 | ///
35 | /// Adds new Element to the List
36 | ///
37 | ///
38 | public Element AddNew()
39 | {
40 | var line = new Element();
41 | List.Add(line);
42 | return line;
43 | }
44 | }
45 |
46 | }
47 |
--------------------------------------------------------------------------------
/ConsoleProgressBar/Extensions/ElementExtensions.cs:
--------------------------------------------------------------------------------
1 | // Description: ProgressBar for Console Applications, with advanced features.
2 | // Project site: https://github.com/iluvadev/ConsoleProgressBar
3 | // Issues: https://github.com/iluvadev/ConsoleProgressBar/issues
4 | // License (MIT): https://github.com/iluvadev/ConsoleProgressBar/blob/main/LICENSE
5 | //
6 | // Copyright (c) 2021, iluvadev, and released under MIT License.
7 | //
8 |
9 | using System;
10 | using System.Collections.Generic;
11 |
12 | namespace iluvadev.ConsoleProgressBar.Extensions
13 | {
14 | ///
15 | /// Extensions for Element
16 | ///
17 | public static class ElementExtensions
18 | {
19 | ///
20 | /// Returns a list of Actions to write the element in Console
21 | ///
22 | ///
23 | ///
24 | /// Function to Transform the value before write
25 | ///
26 | public static List GetRenderActions(this Element element, ProgressBar progressBar, Func valueTransformer = null)
27 | {
28 | var list = new List();
29 |
30 | if (progressBar == null || element == null || !element.GetVisible(progressBar))
31 | return list;
32 |
33 | var foregroundColor = element.GetForegroundColor(progressBar);
34 | if (foregroundColor.HasValue) list.Add(() => Console.ForegroundColor = foregroundColor.Value);
35 |
36 | var backgroundColor = element.GetBackgroundColor(progressBar);
37 | if (backgroundColor.HasValue) list.Add(() => Console.BackgroundColor = backgroundColor.Value);
38 |
39 | string value = element.GetValue(progressBar);
40 | if (valueTransformer != null) value = valueTransformer.Invoke(value);
41 |
42 | list.Add(() => Console.Write(value));
43 | list.Add(() => Console.ResetColor());
44 |
45 | return list;
46 | }
47 |
48 | ///
49 | /// Returns a list of Actions to write the element in Console
50 | ///
51 | ///
52 | ///
53 | ///
54 | ///
55 | public static List GetRenderActions(this Element element, ProgressBar progressBar, int repetition = 1)
56 | {
57 | var list = new List();
58 |
59 | if (progressBar == null || repetition < 1 || element == null || !element.GetVisible(progressBar))
60 | return list;
61 |
62 | var foregroundColor = element.GetForegroundColor(progressBar);
63 | if (foregroundColor.HasValue) list.Add(() => Console.ForegroundColor = foregroundColor.Value);
64 |
65 | var backgroundColor = element.GetBackgroundColor(progressBar);
66 | if (backgroundColor.HasValue) list.Add(() => Console.BackgroundColor = backgroundColor.Value);
67 |
68 | char value = element.GetValue(progressBar);
69 | list.Add(() => Console.Write(new string(value, repetition)));
70 | list.Add(() => Console.ResetColor());
71 |
72 | return list;
73 | }
74 | }
75 |
76 | }
77 |
--------------------------------------------------------------------------------
/ConsoleProgressBar/Extensions/StringExtensions.cs:
--------------------------------------------------------------------------------
1 | // Description: ProgressBar for Console Applications, with advanced features.
2 | // Project site: https://github.com/iluvadev/ConsoleProgressBar
3 | // Issues: https://github.com/iluvadev/ConsoleProgressBar/issues
4 | // License (MIT): https://github.com/iluvadev/ConsoleProgressBar/blob/main/LICENSE
5 | //
6 | // Copyright (c) 2021, iluvadev, and released under MIT License.
7 | //
8 |
9 | using System;
10 |
11 | namespace iluvadev.ConsoleProgressBar.Extensions
12 | {
13 | ///
14 | /// Extensions for String
15 | ///
16 | public static class StringExtensions
17 | {
18 | ///
19 | /// Returns a string that occupy all console line/s
20 | ///
21 | /// The string to write in console
22 | /// To allow print the string in muliple lines or only in one:
23 | /// True: The text can be represented in more than one Console line (fill spaces to the end of last line)
24 | /// False: The text must be represented in only ONE line (truncate to fit or fill spaces to the end of line)
25 | ///
26 | ///
27 | public static string AdaptToConsole(this string value, bool allowMultipleLines = true)
28 | {
29 | int maxWidth = Console.BufferWidth;
30 |
31 | if (allowMultipleLines)
32 | maxWidth *= Math.DivRem(value.Length, maxWidth, out _) + 1;
33 |
34 | return AdaptToMaxWidth(value, maxWidth);
35 | }
36 |
37 | ///
38 | /// Returns a string with exactly maxChars: Truncates string value or fill with spaces to fits exact length
39 | ///
40 | ///
41 | ///
42 | /// Text appended when it is truncated. Default: "..."
43 | ///
44 | public static string AdaptToMaxWidth(this string value, int maxWidth, string append = "...")
45 | {
46 | value ??= "";
47 | int len = value.Length;
48 |
49 | if (maxWidth <= 0) return "";
50 | else if (len == maxWidth) return value;
51 | else if (len < maxWidth) return value.PadRight(maxWidth);
52 | else return value[..(maxWidth - append.Length)] + append;
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/ConsoleProgressBar/Extensions/TimeSpanExtensions.cs:
--------------------------------------------------------------------------------
1 | // Description: ProgressBar for Console Applications, with advanced features.
2 | // Project site: https://github.com/iluvadev/ConsoleProgressBar
3 | // Issues: https://github.com/iluvadev/ConsoleProgressBar/issues
4 | // License (MIT): https://github.com/iluvadev/ConsoleProgressBar/blob/main/LICENSE
5 | //
6 | // Copyright (c) 2021, iluvadev, and released under MIT License.
7 | //
8 |
9 | using System;
10 |
11 | namespace iluvadev.ConsoleProgressBar.Extensions
12 | {
13 | ///
14 | /// TimeSpan extensions
15 | ///
16 | public static class TimeSpanExtensions
17 | {
18 | ///
19 | /// Gets a textual Sumarized for remaining time: X days, or Y hours, or Z minutes, etc.
20 | ///
21 | ///
22 | ///
23 | public static string ToStringAsSumarizedRemainingText(this TimeSpan? ts)
24 | => ts.HasValue ? ToStringAsSumarizedRemainingText(ts.Value) : "unknown";
25 |
26 | ///
27 | /// Gets a textual Sumarized for remaining time: X days, or Y hours, or Z minutes, etc.
28 | ///
29 | ///
30 | ///
31 | public static string ToStringAsSumarizedRemainingText(this TimeSpan ts)
32 | {
33 | int units;
34 | if ((units = Convert.ToInt32(Math.Round(ts.TotalDays))) > 1) return $"{units} days";
35 | else if ((Convert.ToInt32(Math.Floor(ts.TotalDays))) == 1) return $"a day";
36 | else if ((units = Convert.ToInt32(Math.Round(ts.TotalHours))) > 1) return $"{units} hours";
37 | else if ((Convert.ToInt32(Math.Floor(ts.TotalHours))) == 1) return $"an hour";
38 | else if ((units = Convert.ToInt32(Math.Round(ts.TotalMinutes))) > 1) return $"{units} minutes";
39 | else if ((Convert.ToInt32(Math.Floor(ts.TotalMinutes))) == 1) return $"a minute";
40 | else if ((units = Convert.ToInt32(Math.Round(ts.TotalSeconds))) > 1) return $"{units} seconds";
41 | else if ((Convert.ToInt32(Math.Floor(ts.TotalSeconds))) == 1) return $"a second";
42 | else return "a moment";
43 | }
44 |
45 | ///
46 | /// Converts a TimeSpan to String, showing all hours
47 | ///
48 | ///
49 | ///
50 | ///
51 | public static string ToStringWithAllHours(this TimeSpan? ts, bool includeMilliseconds = true)
52 | => ts.HasValue ? ToStringWithAllHours(ts.Value, includeMilliseconds)
53 | : "unknown";
54 |
55 | ///
56 | /// Converts a TimeSpan to String, showing all hours
57 | ///
58 | ///
59 | ///
60 | ///
61 | public static string ToStringWithAllHours(this TimeSpan ts, bool includeMilliseconds = true)
62 | => includeMilliseconds ? $"{ts.TotalHours:F0}{ts:\\:mm\\:ss\\.fff}"
63 | : $"{ts.TotalHours:F0}{ts:\\:mm\\:ss}";
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/ConsoleProgressBar/Layout.Body.cs:
--------------------------------------------------------------------------------
1 | // Description: ProgressBar for Console Applications, with advanced features.
2 | // Project site: https://github.com/iluvadev/ConsoleProgressBar
3 | // Issues: https://github.com/iluvadev/ConsoleProgressBar/issues
4 | // License (MIT): https://github.com/iluvadev/ConsoleProgressBar/blob/main/LICENSE
5 | //
6 | // Copyright (c) 2021, iluvadev, and released under MIT License.
7 | //
8 |
9 | using System;
10 |
11 | namespace iluvadev.ConsoleProgressBar
12 | {
13 | public partial class Layout
14 | {
15 | ///
16 | /// Definition of the Layout used to Render the Body of the ProgressBar
17 | ///
18 | public class LayoutBody
19 | {
20 | /* Examples of ProgressBar:
21 | * - Marquee is a Character moving around the ProgressBar
22 | *
23 | * With Progress available (Maximum defined):
24 | * [■■■■■■■■■■■■········] -> Without Marquee
25 | * [■■■■■■■■■■■■····+···] -> With Marquee (in pending space)
26 | * [■■■■■■■■#■■■········] -> With Marquee (in progress space)
27 | *
28 | * Without Progress available (don't have Maximum):
29 | * [·······■············] -> Marquee is always displayed
30 | */
31 |
32 | ///
33 | /// Element To show in Pending Section
34 | ///
35 | public Element Pending { get; } = new Element();
36 |
37 | ///
38 | /// Element to show in Progress Section
39 | ///
40 | public Element Progress { get; } = new Element();
41 |
42 | ///
43 | /// Layout for the Text
44 | ///
45 | public Element Text { get; } = new Element();
46 |
47 | ///
48 | /// Sets the LayoutBody value for Pending and Progress elements
49 | ///
50 | ///
51 | ///
52 | public LayoutBody SetValue(char value)
53 | => SetValue(pb => value);
54 | ///
55 | /// Sets the LayoutBody value for Pending and Progress elements
56 | ///
57 | ///
58 | ///
59 | public LayoutBody SetValue(Func valueGetter)
60 | {
61 | Pending.SetValue(valueGetter);
62 | Progress.SetValue(valueGetter);
63 | return this;
64 | }
65 |
66 | ///
67 | /// Sets the ForegroundColor for Pending and Progress elements
68 | ///
69 | ///
70 | ///
71 | public LayoutBody SetForegroundColor(ConsoleColor foregroundColor)
72 | => SetForegroundColor(pb => foregroundColor);
73 |
74 | ///
75 | /// Sets the ForegroundColor for Pending and Progress elements
76 | ///
77 | ///
78 | ///
79 | public LayoutBody SetForegroundColor(Func foregroundColorGetter)
80 | {
81 | Pending.SetForegroundColor(foregroundColorGetter);
82 | Progress.SetForegroundColor(foregroundColorGetter);
83 | return this;
84 | }
85 |
86 | ///
87 | /// Sets the BackgroundColor for Pending and Progress elements
88 | ///
89 | ///
90 | ///
91 | public LayoutBody SetBackgroundColor(ConsoleColor backgroundColor)
92 | => SetBackgroundColor(pb => backgroundColor);
93 | ///
94 | /// Sets the BackgroundColor for Pending and Progress elements
95 | ///
96 | ///
97 | ///
98 | public LayoutBody SetBackgroundColor(Func backgroundColorGetter)
99 | {
100 | Pending.SetBackgroundColor(backgroundColorGetter);
101 | Progress.SetBackgroundColor(backgroundColorGetter);
102 | return this;
103 | }
104 |
105 | ///
106 | /// Ctor
107 | ///
108 | public LayoutBody()
109 | {
110 | Pending.SetValue('·').SetForegroundColor(ConsoleColor.DarkGray);
111 | Progress.SetValue('■').SetForegroundColor(ConsoleColor.DarkGreen);
112 | Text.SetVisible(false);
113 | }
114 | }
115 |
116 | }
117 | }
--------------------------------------------------------------------------------
/ConsoleProgressBar/Layout.Margin.cs:
--------------------------------------------------------------------------------
1 | // Description: ProgressBar for Console Applications, with advanced features.
2 | // Project site: https://github.com/iluvadev/ConsoleProgressBar
3 | // Issues: https://github.com/iluvadev/ConsoleProgressBar/issues
4 | // License (MIT): https://github.com/iluvadev/ConsoleProgressBar/blob/main/LICENSE
5 | //
6 | // Copyright (c) 2021, iluvadev, and released under MIT License.
7 | //
8 |
9 | using System;
10 |
11 | namespace iluvadev.ConsoleProgressBar
12 | {
13 | public partial class Layout
14 | {
15 | ///
16 | /// Definition of the Layout used to Render the Margins of the ProgressBar
17 | ///
18 | public class LayoutMargin
19 | {
20 | /* Examples of ProgressBar:
21 | * - Marquee is a Character moving around the ProgressBar
22 | *
23 | * With Progress available (Maximum defined):
24 | * [■■■■■■■■■■■■········] -> Without Marquee
25 | * [■■■■■■■■■■■■····+···] -> With Marquee (in pending space)
26 | * [■■■■■■■■#■■■········] -> With Marquee (in progress space)
27 | *
28 | * Without Progress available (don't have Maximum):
29 | * [·······■············] -> Marquee is always displayed
30 | */
31 |
32 | ///
33 | /// Element to show at the Margin Left (Start of the ProgressBar)
34 | ///
35 | public Element Start { get; } = new Element();
36 |
37 | ///
38 | /// Element to show at the Margin Right (End of the ProgressBar)
39 | ///
40 | public Element End { get; } = new Element();
41 |
42 | ///
43 | /// Sets the LayoutMargin value for Start and End elements
44 | ///
45 | ///
46 | ///
47 | public LayoutMargin SetValue(string value)
48 | => SetValue(pb => value);
49 |
50 | ///
51 | /// Sets the LayoutMargin value for Start and End elements
52 | ///
53 | ///
54 | ///
55 | public LayoutMargin SetValue(Func valueGetter)
56 | {
57 | Start.SetValue(valueGetter);
58 | End.SetValue(valueGetter);
59 | return this;
60 | }
61 |
62 | ///
63 | /// Sets the ForegroundColor for Start and End elements
64 | ///
65 | ///
66 | ///
67 | public LayoutMargin SetForegroundColor(ConsoleColor foregroundColor)
68 | => SetForegroundColor(pb => foregroundColor);
69 |
70 | ///
71 | /// Sets the ForegroundColor for Start and End elements
72 | ///
73 | ///
74 | ///
75 | public LayoutMargin SetForegroundColor(Func foregroundColorGetter)
76 | {
77 | Start.SetForegroundColor(foregroundColorGetter);
78 | End.SetForegroundColor(foregroundColorGetter);
79 | return this;
80 | }
81 |
82 | ///
83 | /// Sets the BackgroundColor for Start and End elements
84 | ///
85 | ///
86 | ///
87 | public LayoutMargin SetBackgroundColor(ConsoleColor backgroundColor)
88 | => SetBackgroundColor(pb => backgroundColor);
89 |
90 | ///
91 | /// Sets the BackgroundColor for Start and End elements
92 | ///
93 | ///
94 | ///
95 | public LayoutMargin SetBackgroundColor(Func backgroundColorGetter)
96 | {
97 | Start.SetBackgroundColor(backgroundColorGetter);
98 | End.SetBackgroundColor(backgroundColorGetter);
99 | return this;
100 | }
101 |
102 | ///
103 | /// Sets the visibility for Start and End elements
104 | ///
105 | ///
106 | ///
107 | public LayoutMargin SetVisible(bool visible)
108 | => SetVisible(pb => visible);
109 |
110 | ///
111 | /// Sets the visibility for Start and End elements
112 | ///
113 | ///
114 | ///
115 | public LayoutMargin SetVisible(Func showGetter)
116 | {
117 | Start.SetVisible(showGetter);
118 | End.SetVisible(showGetter);
119 | return this;
120 | }
121 |
122 | ///
123 | /// Return the length of Margins
124 | ///
125 | ///
126 | ///
127 | public int GetLength(ProgressBar progressBar)
128 | => (Start.GetValue(progressBar)?.Length ?? 0) + (End.GetValue(progressBar)?.Length ?? 0);
129 |
130 | ///
131 | /// Ctor
132 | ///
133 | public LayoutMargin()
134 | {
135 | Start.SetValue("[").SetForegroundColor(ConsoleColor.DarkBlue);
136 | End.SetValue("]").SetForegroundColor(ConsoleColor.DarkBlue);
137 | }
138 | }
139 |
140 | }
141 | }
--------------------------------------------------------------------------------
/ConsoleProgressBar/Layout.Marquee.cs:
--------------------------------------------------------------------------------
1 | // Description: ProgressBar for Console Applications, with advanced features.
2 | // Project site: https://github.com/iluvadev/ConsoleProgressBar
3 | // Issues: https://github.com/iluvadev/ConsoleProgressBar/issues
4 | // License (MIT): https://github.com/iluvadev/ConsoleProgressBar/blob/main/LICENSE
5 | //
6 | // Copyright (c) 2021, iluvadev, and released under MIT License.
7 | //
8 |
9 | using System;
10 |
11 | namespace iluvadev.ConsoleProgressBar
12 | {
13 |
14 | public partial class Layout
15 | {
16 | ///
17 | /// Definition for the Marquee
18 | /// The Marquee is a char that moves around the ProgressBar
19 | ///
20 | public class LayoutMarquee
21 | {
22 | /* Examples of ProgressBar:
23 | * - Marquee is a Character moving around the ProgressBar
24 | *
25 | * With Progress available (Maximum defined):
26 | * [■■■■■■■■■■■■········] -> Without Marquee
27 | * [■■■■■■■■■■■■····+···] -> With Marquee (in pending space)
28 | * [■■■■■■■■#■■■········] -> With Marquee (in progress space)
29 | *
30 | * Without Progress available (don't have Maximum):
31 | * [·······■············] -> Marquee is always displayed
32 | */
33 |
34 | ///
35 | /// Marquee definition when it moves over 'Pending' section
36 | ///
37 | public Element OverPending { get; } = new Element();
38 |
39 | ///
40 | /// Marquee definition when it moves over 'Progress' section
41 | ///
42 | public Element OverProgress { get; } = new Element();
43 |
44 | ///
45 | /// Sets the Marqee definition when it moves over 'Pending' or 'Progress' section
46 | ///
47 | ///
48 | ///
49 | public LayoutMarquee SetValue(char value) => SetValue(pb => value);
50 |
51 | ///
52 | /// Sets the Marqee definition when it moves over 'Pending' or 'Progress' section
53 | ///
54 | ///
55 | ///
56 | public LayoutMarquee SetValue(Func valueGetter)
57 | {
58 | OverPending.SetValue(valueGetter);
59 | OverProgress.SetValue(valueGetter);
60 | return this;
61 | }
62 |
63 | ///
64 | /// Sets the Marqee Foreground Color when it moves over 'Pending' or 'Progress' section
65 | ///
66 | ///
67 | ///
68 | public LayoutMarquee SetForegroundColor(ConsoleColor foregroundColor)
69 | => SetForegroundColor(pb => foregroundColor);
70 |
71 | ///
72 | /// Sets the Marqee Foreground Color when it moves over 'Pending' or 'Progress' section
73 | ///
74 | ///
75 | ///
76 | public LayoutMarquee SetForegroundColor(Func foregroundColorGetter)
77 | {
78 | OverPending.SetForegroundColor(foregroundColorGetter);
79 | OverProgress.SetForegroundColor(foregroundColorGetter);
80 | return this;
81 | }
82 |
83 | ///
84 | /// Sets the Marqee Background Color when it moves over 'Pending' or 'Progress' section
85 | ///
86 | ///
87 | ///
88 | public LayoutMarquee SetBackgroundColor(ConsoleColor backgroundColor)
89 | => SetBackgroundColor(pb => backgroundColor);
90 |
91 | ///
92 | /// Sets the Marqee Background Color when it moves over 'Pending' or 'Progress' section
93 | ///
94 | ///
95 | ///
96 | public LayoutMarquee SetBackgroundColor(Func backgroundColorGetter)
97 | {
98 | OverPending.SetBackgroundColor(backgroundColorGetter);
99 | OverProgress.SetBackgroundColor(backgroundColorGetter);
100 | return this;
101 | }
102 |
103 | ///
104 | /// Sets the Marqee Visibility when it moves over 'Pending' or 'Progress' section
105 | ///
106 | ///
107 | ///
108 | public LayoutMarquee SetVisible(bool visible)
109 | => SetVisible(pb => visible);
110 |
111 | ///
112 | /// Sets the Marqee Visibility when it moves over 'Pending' or 'Progress' section
113 | ///
114 | ///
115 | ///
116 | public LayoutMarquee SetVisible(Func showGetter)
117 | {
118 | OverPending.SetVisible(showGetter);
119 | OverProgress.SetVisible(showGetter);
120 | return this;
121 | }
122 |
123 | ///
124 | /// Ctor
125 | ///
126 | public LayoutMarquee()
127 | {
128 | OverPending.SetValue(pb => pb.HasProgress ? '+' : '■')
129 | .SetForegroundColor(pb => pb.HasProgress ? ConsoleColor.Yellow : ConsoleColor.Green);
130 |
131 | OverProgress.SetValue('■')
132 | .SetForegroundColor(ConsoleColor.Yellow);
133 | }
134 | }
135 | }
136 | }
--------------------------------------------------------------------------------
/ConsoleProgressBar/Layout._.cs:
--------------------------------------------------------------------------------
1 | // Description: ProgressBar for Console Applications, with advanced features.
2 | // Project site: https://github.com/iluvadev/ConsoleProgressBar
3 | // Issues: https://github.com/iluvadev/ConsoleProgressBar/issues
4 | // License (MIT): https://github.com/iluvadev/ConsoleProgressBar/blob/main/LICENSE
5 | //
6 | // Copyright (c) 2021, iluvadev, and released under MIT License.
7 | //
8 |
9 | using iluvadev.ConsoleProgressBar.Extensions;
10 | using System;
11 | using System.Collections.Generic;
12 |
13 | namespace iluvadev.ConsoleProgressBar
14 | {
15 | ///
16 | /// Definition of a Layout for a ProgressBar representation
17 | ///
18 | public partial class Layout
19 | {
20 | /* Examples of ProgressBar:
21 | * - Marquee is a Character moving around the ProgressBar
22 | *
23 | * With Progress available (Maximum defined):
24 | * [■■■■■■■■■■■■········] -> Without Marquee
25 | * [■■■■■■■■■■■■····+···] -> With Marquee (in pending space)
26 | * [■■■■■■■■#■■■········] -> With Marquee (in progress space)
27 | *
28 | * Without Progress available (don't have Maximum):
29 | * [·······■············] -> Marquee is always displayed
30 | */
31 |
32 | ///
33 | /// Layout definition for Margins
34 | ///
35 | public LayoutMargin Margins { get; } = new LayoutMargin();
36 |
37 | ///
38 | /// Layout definition for Marquee (character moving around the ProgressBar)
39 | ///
40 | public LayoutMarquee Marquee { get; } = new LayoutMarquee();
41 |
42 | ///
43 | /// Layout definition for Body
44 | ///
45 | public LayoutBody Body { get; } = new LayoutBody();
46 |
47 |
48 | ///
49 | /// Width of entire ProgressBar
50 | /// Default = 30
51 | ///
52 | public int ProgressBarWidth { get; set; } = 30;
53 |
54 | ///
55 | /// Gets the internal Width of the ProgressBar
56 | ///
57 | public int GetInnerWidth(ProgressBar progressBar)
58 | => Math.Max(ProgressBarWidth - Margins.GetLength(progressBar), 0);
59 |
60 | ///
61 | /// Returns the Actions to do in order to Render the ProgressBar with this Layout
62 | ///
63 | ///
64 | ///
65 | internal List GetRenderActions(ProgressBar progressBar)
66 | {
67 | // [■■■■■■■■■■■■········] -> Without Marquee
68 | // [■■■■■■■■■■■■····+···] -> Marquee over Pending space
69 | // [■■■■■■■■#■■■········] -> Marquee over Progress space
70 | // [·····+··············] -> Marquee withot progress
71 | var list = new List();
72 |
73 | int innerWidth = GetInnerWidth(progressBar);
74 | int progressLenght = progressBar.HasProgress ? Convert.ToInt32(progressBar.Percentage / (100f / innerWidth)) : 0;
75 | int pendingLenght = innerWidth - progressLenght;
76 |
77 | bool marqueeInProgress = progressBar.HasProgress &&
78 | progressBar.MarqueePosition >= 0 && progressBar.MarqueePosition < progressLenght &&
79 | Marquee.OverProgress.GetVisible(progressBar);
80 | bool marqueeInPending = progressBar.MarqueePosition >= progressLenght &&
81 | Marquee.OverPending.GetVisible(progressBar);
82 |
83 | int progressBeforeMarqueeLength = progressLenght;
84 | if (marqueeInProgress) progressBeforeMarqueeLength = progressBar.MarqueePosition;
85 |
86 | int progressAfterMarqueeLength = 0;
87 | if (marqueeInProgress) progressAfterMarqueeLength = progressLenght - progressBeforeMarqueeLength - 1;
88 |
89 | int pendingBeforeMarqueeLength = pendingLenght;
90 | if (marqueeInPending) pendingBeforeMarqueeLength = progressBar.MarqueePosition - progressLenght;
91 |
92 | int pendingAfterMarqueeLength = 0;
93 | if (marqueeInPending) pendingAfterMarqueeLength = pendingLenght - pendingBeforeMarqueeLength - 1;
94 |
95 | string innerText = "";
96 | if (Body.Text.GetVisible(progressBar))
97 | innerText = (Body.Text.GetValue(progressBar) ?? "").AdaptToMaxWidth(innerWidth);
98 |
99 | string textProgressBeforeMarquee = string.IsNullOrEmpty(innerText) ?
100 | new string(Body.Progress.GetValue(progressBar), progressBeforeMarqueeLength)
101 | : innerText.Substring(0, progressBeforeMarqueeLength);
102 |
103 | char? charProgressMarquee = null;
104 | if (marqueeInProgress) charProgressMarquee = string.IsNullOrEmpty(innerText) ?
105 | Marquee.OverProgress.GetValue(progressBar)
106 | : innerText[progressBar.MarqueePosition];
107 |
108 | string textProgressAfterMarquee = string.IsNullOrEmpty(innerText) ?
109 | new string(Body.Progress.GetValue(progressBar), progressAfterMarqueeLength)
110 | : innerText.Substring(progressBar.MarqueePosition + 1, progressAfterMarqueeLength);
111 |
112 | string textPendingBeforeMarquee = string.IsNullOrEmpty(innerText) ?
113 | new string(Body.Pending.GetValue(progressBar), pendingBeforeMarqueeLength)
114 | : innerText.Substring(progressLenght, pendingBeforeMarqueeLength);
115 |
116 | char? charPendingMarquee = null;
117 | if (marqueeInPending) charPendingMarquee = string.IsNullOrEmpty(innerText) ?
118 | Marquee.OverPending.GetValue(progressBar)
119 | : innerText[progressBar.MarqueePosition];
120 |
121 | string textPendingAfterMarquee = string.IsNullOrEmpty(innerText) ?
122 | new string(Body.Pending.GetValue(progressBar), pendingAfterMarqueeLength)
123 | : innerText.Substring(progressBar.MarqueePosition + 1, pendingAfterMarqueeLength);
124 |
125 | //Margin: Start
126 | list.AddRange(Margins.Start.GetRenderActions(progressBar));
127 |
128 | //Body: Progress before Marquee
129 | if (!string.IsNullOrEmpty(textProgressBeforeMarquee))
130 | {
131 | var elementProgressBeforeMarquee = new Element(textProgressBeforeMarquee,
132 | Body.Progress.GetForegroundColor(progressBar) ?? Console.ForegroundColor,
133 | Body.Progress.GetBackgroundColor(progressBar) ?? Console.BackgroundColor);
134 | list.AddRange(elementProgressBeforeMarquee.GetRenderActions(progressBar));
135 | }
136 |
137 | //Body: Marquee in progress
138 | if (charProgressMarquee.HasValue)
139 | {
140 | var elementProgressMarquee = new Element(charProgressMarquee.Value,
141 | Marquee.OverProgress.GetForegroundColor(progressBar) ?? Console.ForegroundColor,
142 | Marquee.OverProgress.GetBackgroundColor(progressBar) ?? Console.BackgroundColor);
143 | list.AddRange(elementProgressMarquee.GetRenderActions(progressBar));
144 | }
145 |
146 | //Body: Progress after Marquee
147 | if (!string.IsNullOrEmpty(textProgressAfterMarquee))
148 | {
149 | var elementProgressAfterMarquee = new Element(textProgressAfterMarquee,
150 | Body.Progress.GetForegroundColor(progressBar) ?? Console.ForegroundColor,
151 | Body.Progress.GetBackgroundColor(progressBar) ?? Console.BackgroundColor);
152 | list.AddRange(elementProgressAfterMarquee.GetRenderActions(progressBar));
153 | }
154 |
155 | //Body: Pending before Marquee
156 | if (!string.IsNullOrEmpty(textPendingBeforeMarquee))
157 | {
158 | var elementPendingBeforeMarquee = new Element(textPendingBeforeMarquee,
159 | Body.Pending.GetForegroundColor(progressBar) ?? Console.ForegroundColor,
160 | Body.Pending.GetBackgroundColor(progressBar) ?? Console.BackgroundColor);
161 | list.AddRange(elementPendingBeforeMarquee.GetRenderActions(progressBar));
162 | }
163 |
164 | //Body: Marquee in Pending
165 | if (charPendingMarquee.HasValue)
166 | {
167 | var elementPendingMarquee = new Element(charPendingMarquee.Value,
168 | Marquee.OverPending.GetForegroundColor(progressBar) ?? Console.ForegroundColor,
169 | Marquee.OverPending.GetBackgroundColor(progressBar) ?? Console.BackgroundColor);
170 | list.AddRange(elementPendingMarquee.GetRenderActions(progressBar));
171 | }
172 |
173 | //Body: Pending after Marquee
174 | if (!string.IsNullOrEmpty(textPendingAfterMarquee))
175 | {
176 | var elementPendingAfterMarquee = new Element(textPendingAfterMarquee,
177 | Body.Pending.GetForegroundColor(progressBar) ?? Console.ForegroundColor,
178 | Body.Pending.GetBackgroundColor(progressBar) ?? Console.BackgroundColor);
179 | list.AddRange(elementPendingAfterMarquee.GetRenderActions(progressBar));
180 | }
181 |
182 | //Margin: End
183 | list.AddRange(Margins.End.GetRenderActions(progressBar));
184 |
185 | return list;
186 | }
187 | }
188 | }
189 |
--------------------------------------------------------------------------------
/ConsoleProgressBar/ProgressBar.cs:
--------------------------------------------------------------------------------
1 | // Description: ProgressBar for Console Applications, with advanced features.
2 | // Project site: https://github.com/iluvadev/ConsoleProgressBar
3 | // Issues: https://github.com/iluvadev/ConsoleProgressBar/issues
4 | // License (MIT): https://github.com/iluvadev/ConsoleProgressBar/blob/main/LICENSE
5 | //
6 | // Copyright (c) 2021, iluvadev, and released under MIT License.
7 | //
8 |
9 | using iluvadev.ConsoleProgressBar.Extensions;
10 | using System;
11 | using System.Collections.Generic;
12 | using System.Diagnostics;
13 | using System.Linq;
14 | using System.Threading;
15 | using System.Threading.Tasks;
16 |
17 | namespace iluvadev.ConsoleProgressBar
18 | {
19 | ///
20 | /// A ProgressBar for Console
21 | ///
22 | public class ProgressBar : IDisposable
23 | {
24 | private Layout _Layout = null;
25 | ///
26 | /// Layout of the ProgressBar
27 | ///
28 | public Layout Layout
29 | {
30 | get => _Layout ??= new Layout();
31 | set => _Layout = value;
32 | }
33 |
34 | private Text _Text = null;
35 | ///
36 | /// Text definitions for the ProgressBar
37 | ///
38 | public Text Text
39 | {
40 | get=> _Text ??= new Text();
41 | set => _Text = value;
42 | }
43 |
44 | ///
45 | /// Tag object
46 | ///
47 | public object Tag { get; set; }
48 |
49 | ///
50 | /// The Maximum value
51 | /// Default = 100
52 | ///
53 | public int? Maximum { get; set; } = 100;
54 |
55 | private int _Value = 0;
56 | ///
57 | /// The current Value
58 | /// If Value is greater than Maximum, then updates Maximum value
59 | ///
60 | public int Value
61 | {
62 | get => _Value;
63 | set => SetValue(value);
64 | }
65 |
66 | ///
67 | /// Percentage of progress
68 | ///
69 | public int? Percentage => Maximum.HasValue ? (Maximum.Value != 0 ? ((Value * 100) / Maximum.Value) : 100) : (int?)null;
70 |
71 | ///
72 | /// Indicates if the ProgressBar has Progress defined (Maximum defined)
73 | ///
74 | public bool HasProgress => Maximum.HasValue;
75 |
76 | ///
77 | /// The amount by which to increment the ProgressBar with each call to the PerformStep() method.
78 | /// Default = 1
79 | ///
80 | public int Step { get; set; } = 1;
81 |
82 | ///
83 | /// The Name of the Curent Element
84 | ///
85 | public string ElementName { get; set; }
86 |
87 |
88 | private bool _FixedInBottom = false;
89 | ///
90 | /// True to Print the ProgressBar always in last Console Line
91 | /// False to Print the ProgressBar fixed in Console (Current position at Starting)
92 | /// You can Write at Console and ProgressBar will always be below your lines
93 | /// Default = true
94 | ///
95 | public bool FixedInBottom
96 | {
97 | get => _FixedInBottom;
98 | set
99 | {
100 | if (_FixedInBottom != value)
101 | {
102 | Unrender();
103 | _FixedInBottom = value;
104 | Render();
105 | }
106 | }
107 | }
108 |
109 | ///
110 | /// Delay for repaint and recalculate all ProgressBar
111 | /// Default = 75
112 | ///
113 | public int Delay { get; set; } = 75;
114 |
115 |
116 | ///
117 | /// True if ProgressBar is Started
118 | ///
119 | public bool IsStarted { get; private set; }
120 |
121 | ///
122 | /// True if ProgressBar is Paused
123 | ///
124 | public bool IsPaused { get; private set; }
125 |
126 | ///
127 | /// True if ProgresBar is Done: when disposing or Progress is finished
128 | ///
129 | public bool IsDone => CancelThread || (HasProgress && Value == Maximum);
130 |
131 | ///
132 | /// Processing time (time paused excluded)
133 | ///
134 | public TimeSpan TimeProcessing => ProgressStopwatch.Elapsed;
135 |
136 | ///
137 | /// Processing time per element (median)
138 | ///
139 | public TimeSpan? TimePerElement => TicksPerElement.HasValue ? new TimeSpan(TicksPerElement.Value) : (TimeSpan?)null;
140 |
141 | ///
142 | /// Estimated time finish (to Value = Maximum)
143 | ///
144 | public TimeSpan? TimeRemaining => TicksRemaining.HasValue ? new TimeSpan(TicksRemaining.Value) : (TimeSpan?)null;
145 |
146 | ///
147 | /// A Lock for Writing to Console
148 | ///
149 | public static readonly object ConsoleWriterLock = new object();
150 |
151 | internal int MarqueePosition { get; set; } = -1;
152 | private int MarqueeIncrement { get; set; } = 1;
153 |
154 | private bool CancelThread { get; set; }
155 |
156 | private Stopwatch ProgressStopwatch { get; set; }
157 | private long? TicksCompletedElements { get; set; }
158 | private long? TicksPerElement => TicksCompletedElements.HasValue && Value > 0 ? TicksCompletedElements.Value / Value : (long?)null;
159 | private long? TicksRemaining
160 | {
161 | get
162 | {
163 | if (!Maximum.HasValue || !TicksPerElement.HasValue || !TicksCompletedElements.HasValue) return (long?)null;
164 | long currentTicks = ProgressStopwatch.ElapsedTicks;
165 | long currentElementTicks = currentTicks - TicksCompletedElements.Value;
166 | long elementTicks = (currentElementTicks <= TicksPerElement.Value) ? TicksPerElement.Value : currentTicks / (Value + 1);
167 | long totalTicks = elementTicks * Maximum.Value;
168 | return Math.Max(totalTicks - currentTicks, 0);
169 | }
170 | }
171 |
172 | private int _ConsoleRow = -1;
173 | private int _NumberLastLinesWritten = -1;
174 |
175 | ///
176 | /// Creates an instance of ConsoleProgressBar
177 | ///
178 | /// Initial position of the ProgressBar
179 | /// True if ProgressBar starts automatically
180 | public ProgressBar(int? initialPosition = null, bool autoStart = true)
181 | {
182 | ProgressStopwatch = new Stopwatch();
183 | if (initialPosition.HasValue) _ConsoleRow = initialPosition.Value;
184 | if (autoStart) Start();
185 | }
186 |
187 | ///
188 | /// Starts the ProgressBar
189 | ///
190 | public void Start()
191 | {
192 | if (IsStarted) Resume();
193 | else (new Thread(ThreadAction) { IsBackground = true }).Start();
194 | }
195 |
196 | private void ThreadAction()
197 | {
198 | ProgressStopwatch.Start();
199 | IsStarted = true;
200 | while (!CancelThread)
201 | {
202 | if (!IsPaused)
203 | {
204 | try
205 | {
206 | UpdateMarqueePosition();
207 | Render();
208 | Task.Delay(Delay).Wait();
209 | }
210 | catch { }
211 | }
212 | }
213 | }
214 |
215 | ///
216 | /// Pauses the ProgressBar
217 | ///
218 | public void Pause()
219 | {
220 | IsPaused = true;
221 | ProgressStopwatch.Stop();
222 | Render();
223 | }
224 |
225 | ///
226 | /// Resume the ProgresBar
227 | ///
228 | public void Resume()
229 | {
230 | ProgressStopwatch.Start();
231 | IsPaused = false;
232 | Render();
233 | }
234 |
235 | ///
236 | /// Assigns the current Value, and optionally current ElementName and Tag
237 | /// If Value is greater than Maximum, updates Maximum as Value
238 | ///
239 | ///
240 | ///
241 | ///
242 | public void SetValue(int value, string elementName = null, object tag = null)
243 | {
244 | if (value > Maximum) Maximum = value;
245 | _Value = value;
246 | TicksCompletedElements = value > 0 ? ProgressStopwatch.ElapsedTicks : (long?)null;
247 |
248 | if (elementName != null) ElementName = elementName;
249 | if (tag != null) Tag = tag;
250 | }
251 |
252 | ///
253 | /// Advances the current position of the progress bar by the amount of the Step property
254 | ///
255 | /// The name of the new Element
256 | ///
257 | public void PerformStep(string elementName = null, object tag = null) => PerformStep(Step, elementName, tag);
258 |
259 | ///
260 | /// Advances the current position of the progress bar by the amount of the Step property
261 | ///
262 | /// Step to perform
263 | /// The name of the new Element
264 | ///
265 | public void PerformStep(int step, string elementName = null, object tag = null)
266 | {
267 | if (elementName != null) ElementName = elementName;
268 | if (tag != null) Tag = tag;
269 | Value += step;
270 | }
271 | ///
272 | /// WriteLine in Console when ProgressBar is running
273 | ///
274 | public void WriteLine() => WriteLine("", null, null, true);
275 | ///
276 | /// WriteLine in Console when ProgressBar is running
277 | ///
278 | ///
279 | public void WriteLine(string value) => WriteLine(value, null, null, true);
280 | ///
281 | /// WriteLine in Console when ProgressBar is running
282 | ///
283 | ///
284 | ///
285 | public void WriteLine(string value, bool truncateToOneLine) => WriteLine(value, null, null, truncateToOneLine);
286 | ///
287 | /// WriteLine in Console when ProgressBar is running
288 | ///
289 | ///
290 | ///
291 | ///
292 | ///
293 | public void WriteLine(string value, ConsoleColor? foregroundColor = null, ConsoleColor? backgroundColor = null, bool truncateToOneLine = true)
294 | {
295 | var actions = new List();
296 |
297 | if (foregroundColor.HasValue) actions.Add(() => Console.ForegroundColor = foregroundColor.Value);
298 | if (backgroundColor.HasValue) actions.Add(() => Console.BackgroundColor = backgroundColor.Value);
299 | actions.Add(() => Console.Write(value.AdaptToConsole(!truncateToOneLine) + Environment.NewLine));
300 |
301 | lock (ConsoleWriterLock)
302 | {
303 | if (foregroundColor.HasValue)
304 | {
305 | var oldColor = Console.ForegroundColor;
306 | actions.Add(() => Console.ForegroundColor = oldColor);
307 | }
308 | if (backgroundColor.HasValue)
309 | {
310 | var oldColor = Console.BackgroundColor;
311 | actions.Add(() => Console.BackgroundColor = oldColor);
312 | }
313 | actions.ForEach(a => a.Invoke());
314 | }
315 |
316 | //If FixedInBottom and we written over the ProgressBar -> Print it again
317 | if (FixedInBottom && _NumberLastLinesWritten > 0 && Console.CursorTop >= _ConsoleRow)
318 | Render();
319 | }
320 |
321 | ///
322 | /// Renders in Console the ProgressBar
323 | ///
324 | public void Render()
325 | {
326 | List actionsProgressBar = GetRenderActionsForProgressBarAndText();
327 | string emptyLine = " ".AdaptToConsole();
328 |
329 | //Lock Write to console
330 | lock (ConsoleWriterLock)
331 | {
332 | int oldCursorLeft = Console.CursorLeft;
333 | int oldCursorTop = Console.CursorTop;
334 | bool oldCursorVisible = Console.CursorVisible;
335 | ConsoleColor oldForegroundColor = Console.ForegroundColor;
336 | ConsoleColor oldBackgroundColor = Console.BackgroundColor;
337 |
338 | //Hide Cursor
339 | Console.CursorVisible = false;
340 |
341 | //Position
342 | if (FixedInBottom)
343 | {
344 | if (_ConsoleRow < Console.WindowHeight - _NumberLastLinesWritten)
345 | {
346 | int newConsoleRow = Console.WindowHeight - _NumberLastLinesWritten;
347 | if (_NumberLastLinesWritten > 0 && _ConsoleRow >= 0)
348 | {
349 | //Clear old ProgressBar
350 | Console.SetCursorPosition(0, _ConsoleRow);
351 | for (int i = _ConsoleRow; i < newConsoleRow; i++)
352 | Console.WriteLine(emptyLine);
353 | }
354 | _ConsoleRow = newConsoleRow;
355 | }
356 | //if (oldCursorTop >= _ConsoleRow)
357 | //{
358 | // //oldCursorTop is near or over: Keep 2 empty lines between Text and ProgressBar (avoid flickering)
359 | // Console.SetCursorPosition(0, oldCursorTop);
360 | // Console.WriteLine(emptyLine);
361 | // Console.WriteLine(emptyLine);
362 | // _ConsoleRow = oldCursorTop + 2;
363 | //}
364 |
365 | int scrollMargin = Math.Max((Console.WindowHeight - _NumberLastLinesWritten) / 3, 2);
366 | if (_ConsoleRow - oldCursorTop <= scrollMargin / 2)
367 | {
368 | //oldCursorTop is near or over: Keep a margin between Text and ProgressBar (avoid flickering)
369 | Console.SetCursorPosition(0, oldCursorTop);
370 | for (int i = oldCursorTop; i < _ConsoleRow + _NumberLastLinesWritten; i++)
371 | Console.WriteLine(emptyLine);
372 | _ConsoleRow = oldCursorTop + scrollMargin;
373 | }
374 | }
375 | else if (_ConsoleRow < 0)
376 | _ConsoleRow = oldCursorTop;
377 | Console.SetCursorPosition(0, _ConsoleRow);
378 |
379 | //ProgressBar and Text
380 | actionsProgressBar.ForEach(a => a.Invoke());
381 |
382 | // Restore Cursor Position, Colors and Cursor visible
383 | Console.SetCursorPosition(oldCursorLeft, oldCursorTop);
384 | Console.ForegroundColor = oldForegroundColor;
385 | Console.BackgroundColor = oldBackgroundColor;
386 | if (oldCursorVisible) Console.CursorVisible = oldCursorVisible;
387 | }
388 | }
389 |
390 | ///
391 | /// Unrenders (remove) from Console last ProgressBar printed
392 | ///
393 | public void Unrender()
394 | {
395 | if (_ConsoleRow < 0 || _NumberLastLinesWritten <= 0)
396 | return;
397 |
398 | string emptyLine = " ".AdaptToConsole();
399 |
400 | //Lock Write to console
401 | lock (ConsoleWriterLock)
402 | {
403 | int oldCursorLeft = Console.CursorLeft;
404 | int oldCursorTop = Console.CursorTop;
405 | bool oldCursorVisible = Console.CursorVisible;
406 |
407 | //Hide Cursor
408 | Console.CursorVisible = false;
409 |
410 | int initialRow = _ConsoleRow;
411 | if (FixedInBottom)
412 | initialRow = Math.Max(_ConsoleRow, oldCursorTop);
413 |
414 | //Position
415 | Console.SetCursorPosition(0, initialRow);
416 |
417 | //Remove lines
418 | for (int i = initialRow; i < _ConsoleRow + _NumberLastLinesWritten; i++)
419 | Console.WriteLine(emptyLine);
420 |
421 | // Restore Cursor Position and Cursor Visible
422 | Console.SetCursorPosition(oldCursorLeft, oldCursorTop);
423 | if (oldCursorVisible) Console.CursorVisible = oldCursorVisible;
424 | }
425 | }
426 |
427 | private List GetRenderActionsForProgressBarAndText()
428 | {
429 | int oldLinesWritten = _NumberLastLinesWritten;
430 | string emptyLine = " ".AdaptToConsole();
431 |
432 | // ProgressBar
433 | List list = Layout.GetRenderActions(this);
434 |
435 | // Text in same line
436 | var maxTextLenght = Console.BufferWidth - Layout.ProgressBarWidth;
437 | if (maxTextLenght >= 10) //Text will be printed if there are 10 chars or more
438 | {
439 | var text = Text.Body.GetCurrentText(this);
440 | if (text != null)
441 | list.AddRange(text.GetRenderActions(this, s => (" " + s).AdaptToMaxWidth(maxTextLenght)));
442 | }
443 | list.Add(() => Console.Write(Environment.NewLine));
444 | _NumberLastLinesWritten = 1;
445 |
446 | // Descriptions
447 | var descriptionList = Text.Description.GetCurrentDefinitionList(this)?.List?.Where(d => d != null && d.GetVisible(this));
448 | if (descriptionList != null && descriptionList.Any())
449 | {
450 | int indentationLen = Text.Description.Indentation.GetValue(this)?.Length ?? 0;
451 | var maxDescLenght = Console.BufferWidth - indentationLen;
452 | foreach (var description in descriptionList)
453 | {
454 | if (indentationLen > 0) list.AddRange(Text.Description.Indentation.GetRenderActions(this));
455 | list.AddRange(description.GetRenderActions(this, s => s.AdaptToMaxWidth(maxDescLenght) + Environment.NewLine));
456 | _NumberLastLinesWritten++;
457 | }
458 | }
459 |
460 | // Clear old lines
461 | if (oldLinesWritten > _NumberLastLinesWritten)
462 | {
463 | for (int i = 0; i < oldLinesWritten - _NumberLastLinesWritten; i++)
464 | list.Add(() => Console.WriteLine(emptyLine));
465 | }
466 | return list;
467 | }
468 |
469 | private void UpdateMarqueePosition()
470 | {
471 | int newProgressPosition = MarqueePosition + MarqueeIncrement;
472 | if (newProgressPosition < 0 || newProgressPosition >= Layout.GetInnerWidth(this))
473 | MarqueeIncrement *= -1;
474 |
475 | MarqueePosition += MarqueeIncrement;
476 | }
477 |
478 | ///
479 | /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
480 | ///
481 | public void Dispose()
482 | {
483 | CancelThread = true;
484 | Layout.Marquee.SetVisible(false);
485 | //UpdateRemainingTime();
486 | Render();
487 | if (FixedInBottom && _NumberLastLinesWritten > 0 && _ConsoleRow >= 0)
488 | Console.CursorTop = _ConsoleRow + _NumberLastLinesWritten;
489 |
490 | if (ProgressStopwatch.IsRunning)
491 | ProgressStopwatch.Stop();
492 | ProgressStopwatch.Reset();
493 | }
494 | }
495 | }
496 |
--------------------------------------------------------------------------------
/ConsoleProgressBar/Text.Body.cs:
--------------------------------------------------------------------------------
1 | // Description: ProgressBar for Console Applications, with advanced features.
2 | // Project site: https://github.com/iluvadev/ConsoleProgressBar
3 | // Issues: https://github.com/iluvadev/ConsoleProgressBar/issues
4 | // License (MIT): https://github.com/iluvadev/ConsoleProgressBar/blob/main/LICENSE
5 | //
6 | // Copyright (c) 2021, iluvadev, and released under MIT License.
7 | //
8 |
9 | using iluvadev.ConsoleProgressBar.Extensions;
10 | using System;
11 |
12 | namespace iluvadev.ConsoleProgressBar
13 | {
14 | public partial class Text
15 | {
16 | ///
17 | /// Definition for the Texts in a ProgressBar
18 | ///
19 | public class TextBody
20 | {
21 | ///
22 | /// Text in Body definition when ProgressBar is "Processing"
23 | ///
24 | public Element Processing { get; } = new Element();
25 |
26 | ///
27 | /// Text in Body definition when ProgressBar is "Paused"
28 | ///
29 | public Element Paused { get; } = new Element();
30 |
31 | ///
32 | /// Text in Body definition when ProgressBar is "Done"
33 | ///
34 | public Element Done { get; } = new Element();
35 |
36 | ///
37 | /// Sets the Body Text visibility
38 | ///
39 | ///
40 | ///
41 | public TextBody SetVisible(bool show)
42 | => SetVisible(pb => show);
43 |
44 | ///
45 | /// Sets the Body Text visibility
46 | ///
47 | ///
48 | ///
49 | public TextBody SetVisible(Func showGetter)
50 | {
51 | Processing.SetVisible(showGetter);
52 | Paused.SetVisible(showGetter);
53 | Done.SetVisible(showGetter);
54 | return this;
55 | }
56 |
57 | ///
58 | /// Sets the Body Text definition in all ProgressBar states ("Processing", "Paused", "Done")
59 | ///
60 | ///
61 | ///
62 | public TextBody SetValue(string value)
63 | => SetValue(pb => value);
64 |
65 | ///
66 | /// Sets the Body Text definition in all ProgressBar states ("Processing", "Paused", "Done")
67 | ///
68 | ///
69 | ///
70 | public TextBody SetValue(Func valueGetter)
71 | {
72 | Processing.SetValue(valueGetter);
73 | Paused.SetValue(valueGetter);
74 | Done.SetValue(valueGetter);
75 | return this;
76 | }
77 |
78 | ///
79 | /// Sets the Body Text Foreground Color
80 | ///
81 | ///
82 | ///
83 | public TextBody SetForegroundColor(ConsoleColor foregroundColor)
84 | => SetForegroundColor(pb => foregroundColor);
85 |
86 | ///
87 | /// Sets the Body Text Foreground Color
88 | ///
89 | ///
90 | ///
91 | public TextBody SetForegroundColor(Func foregroundColorGetter)
92 | {
93 | Processing.SetForegroundColor(foregroundColorGetter);
94 | Paused.SetForegroundColor(foregroundColorGetter);
95 | Done.SetForegroundColor(foregroundColorGetter);
96 | return this;
97 | }
98 |
99 | ///
100 | /// Sets the Body Text Background Color
101 | ///
102 | ///
103 | ///
104 | public TextBody SetBackgroundColor(ConsoleColor backgroundColor)
105 | => SetBackgroundColor(pb => backgroundColor);
106 |
107 | ///
108 | /// Sets the Body Text Background Color
109 | ///
110 | ///
111 | ///
112 | public TextBody SetBackgroundColor(Func backgroundColorGetter)
113 | {
114 | Processing.SetBackgroundColor(backgroundColorGetter);
115 | Paused.SetBackgroundColor(backgroundColorGetter);
116 | Done.SetBackgroundColor(backgroundColorGetter);
117 | return this;
118 | }
119 |
120 | ///
121 | /// Ctor
122 | ///
123 | public TextBody()
124 | {
125 | Processing.SetValue(pb => pb.HasProgress ?
126 | $"{pb.Value} of {pb.Maximum} in {pb.TimeProcessing.ToStringWithAllHours()}, remaining: {pb.TimeRemaining.ToStringAsSumarizedRemainingText()}"
127 | : $"Processing... ({pb.Value} in {pb.TimeProcessing.ToStringWithAllHours()})")
128 | .SetForegroundColor(ConsoleColor.Cyan);
129 |
130 | Paused.SetValue(pb => pb.HasProgress ?
131 | $"Paused... Running time: {pb.TimeProcessing.ToStringWithAllHours()}"
132 | : $"{pb.Value} of {pb.Maximum} in {pb.TimeProcessing.ToStringWithAllHours()} (paused)")
133 | .SetForegroundColor(ConsoleColor.DarkCyan);
134 |
135 | Done.SetValue("Done!")
136 | .SetForegroundColor(ConsoleColor.DarkYellow);
137 | }
138 |
139 | ///
140 | /// Gets the current Text Body definition by the ProgressBar context ("Processing", "Paused" or "Done")
141 | ///
142 | ///
143 | ///
144 | public Element GetCurrentText(ProgressBar progressBar)
145 | {
146 | if (progressBar == null) return null;
147 | else if (progressBar.IsPaused) return Paused;
148 | else if (progressBar.IsDone) return Done;
149 | else if (progressBar.IsStarted) return Processing;
150 | else return null;
151 | }
152 | }
153 |
154 | }
155 | }
156 |
--------------------------------------------------------------------------------
/ConsoleProgressBar/Text.Description.cs:
--------------------------------------------------------------------------------
1 | // Description: ProgressBar for Console Applications, with advanced features.
2 | // Project site: https://github.com/iluvadev/ConsoleProgressBar
3 | // Issues: https://github.com/iluvadev/ConsoleProgressBar/issues
4 | // License (MIT): https://github.com/iluvadev/ConsoleProgressBar/blob/main/LICENSE
5 | //
6 | // Copyright (c) 2021, iluvadev, and released under MIT License.
7 | //
8 |
9 | using iluvadev.ConsoleProgressBar.Extensions;
10 | using System;
11 |
12 | namespace iluvadev.ConsoleProgressBar
13 | {
14 | public partial class Text
15 | {
16 | ///
17 | /// Definition for the Description lines in a ProgressBar
18 | ///
19 | public class TextDescription
20 | {
21 | ///
22 | /// Description lines definition when ProgressBar is "Processing"
23 | ///
24 | public ElementList Processing { get; } = new ElementList();
25 |
26 | ///
27 | /// Description lines definition when ProgressBar is "Paused"
28 | ///
29 | public ElementList Paused { get; } = new ElementList();
30 |
31 | ///
32 | /// Description lines definition when ProgressBar is "Done"
33 | ///
34 | public ElementList Done { get; } = new ElementList();
35 |
36 | ///
37 | /// Indentation for Description lines
38 | ///
39 | public Element Indentation { get; }
40 | = new Element();
41 |
42 | ///
43 | /// Ctor
44 | ///
45 | public TextDescription()
46 | {
47 | Processing.AddNew().SetValue(pb => pb.ElementName)
48 | .SetVisible(pb => !string.IsNullOrEmpty(pb.ElementName))
49 | .SetForegroundColor(ConsoleColor.DarkYellow);
50 |
51 | Paused.AddNew().SetValue("[Paused]")
52 | .SetForegroundColor(ConsoleColor.DarkCyan);
53 |
54 | Done.AddNew().SetValue(pb => $"{pb.Value} in {pb.TimeProcessing.ToStringWithAllHours()} ({pb.TimePerElement.ToStringWithAllHours()} each one)")
55 | .SetForegroundColor(ConsoleColor.DarkGray);
56 |
57 | Indentation.SetValue(" -> ").SetForegroundColor(ConsoleColor.DarkBlue);
58 | }
59 |
60 | ///
61 | /// Clears Description Lines
62 | ///
63 | ///
64 | public TextDescription Clear()
65 | {
66 | Processing.Clear();
67 | Paused.Clear();
68 | Done.Clear();
69 | return this;
70 | }
71 |
72 | ///
73 | /// Gets the current Description Lines definition by the ProgressBar context ("Processing", "Paused" or "Done")
74 | ///
75 | ///
76 | ///
77 | public ElementList GetCurrentDefinitionList(ProgressBar progressBar)
78 | {
79 | if (progressBar == null) return null;
80 | else if (progressBar.IsPaused) return Paused;
81 | else if (progressBar.IsDone) return Done;
82 | else if (progressBar.IsStarted) return Processing;
83 | else return null;
84 | }
85 | }
86 |
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/ConsoleProgressBar/Text._.cs:
--------------------------------------------------------------------------------
1 | // Description: ProgressBar for Console Applications, with advanced features.
2 | // Project site: https://github.com/iluvadev/ConsoleProgressBar
3 | // Issues: https://github.com/iluvadev/ConsoleProgressBar/issues
4 | // License (MIT): https://github.com/iluvadev/ConsoleProgressBar/blob/main/LICENSE
5 | //
6 | // Copyright (c) 2021, iluvadev, and released under MIT License.
7 | //
8 |
9 | namespace iluvadev.ConsoleProgressBar
10 | {
11 | ///
12 | /// Definitions for Texts in a ProgressBar
13 | ///
14 | public partial class Text
15 | {
16 | ///
17 | /// Definition of the text in the same line as ProgressBar (Body)
18 | ///
19 | public TextBody Body { get; } = new TextBody();
20 |
21 | ///
22 | /// Definition of the texts in the lines below a ProgressBar (Description)
23 | ///
24 | public TextDescription Description { get; } = new TextDescription();
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/ConsoleProgressBarDemo/ConsoleProgressBarDemo.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | netcoreapp3.1
6 | iluvadev.$(MSBuildProjectName)
7 | iluvadev.$(MSBuildProjectName.Replace(" ", "_"))
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/ConsoleProgressBarDemo/DemoProgressBar.cs:
--------------------------------------------------------------------------------
1 | using iluvadev.ConsoleProgressBar;
2 | using System;
3 | using System.Threading.Tasks;
4 |
5 | namespace iluvadev.ConsoleProgressBarDemo
6 | {
7 | internal class DemoProgressBar
8 | {
9 | public static void Example01()
10 | {
11 | const int max = 500;
12 |
13 | //Create the ProgressBar
14 | // Maximum: The Max value in ProgressBar (Default is 100)
15 | using (var pb = new ProgressBar { Maximum = max })
16 | {
17 | for (int i = 0; i < max; i++)
18 | {
19 | Task.Delay(10).Wait(); //Do something
20 | pb.PerformStep(); //Step in ProgressBar (Default is 1)
21 | }
22 | }
23 | }
24 |
25 | public static void Example02()
26 | {
27 | const int max = 1000;
28 |
29 | //Create the ProgressBar
30 | // initialPosition: Console Line to put the ProgressBar (optional, last Console line is assumed)
31 | // autoStart: Optional, default true
32 | // Maximum: The Max value in ProgressBar (Default is 100)
33 | // Step: The increment when performStep (Default is 1)
34 | using (var pb = new ProgressBar(initialPosition: 3, autoStart: false) { Maximum = max, Step = 2 })
35 | {
36 | pb.Start(); // autoStart=false -> we need start manually
37 | for (int i = 0; i < max; i += pb.Step)
38 | {
39 | Task.Delay(10).Wait(); //Do something
40 | pb.PerformStep(); //Step in ProgressBar
41 | }
42 | }
43 | }
44 |
45 | public static void Example03()
46 | {
47 | const int max = 500;
48 |
49 | //Create the ProgressBar
50 | // Maximum: The Max value in ProgressBar (Default is 100)
51 | using (var pb = new ProgressBar() { Maximum = null })
52 | {
53 | for (int i = 0; i < max; i++)
54 | {
55 | Task.Delay(10).Wait(); //Do something
56 | pb.PerformStep(); //Step in ProgressBar (Default is 1)
57 | }
58 | }
59 | }
60 |
61 | public static void Example04()
62 | {
63 | const int max = 500;
64 |
65 | //Create the ProgressBar
66 | using (var pb = new ProgressBar() { Maximum = max })
67 | {
68 | //Set "Processing Text" Visible = false
69 | pb.Text.Body.Processing.SetVisible(false);
70 |
71 | for (int i = 0; i < max; i++)
72 | {
73 | Task.Delay(10).Wait(); //Do something
74 | pb.PerformStep(); //Step in ProgressBar (Default is 1)
75 | }
76 | }
77 | }
78 | public static void Example05()
79 | {
80 | const int max = 500;
81 |
82 | //Create the ProgressBar
83 | using (var pb = new ProgressBar() { Maximum = max })
84 | {
85 | //Setting fixed "Processing Text"
86 | pb.Text.Body.Processing.SetValue("Processing, please wait...");
87 |
88 | //Setting "Done Text"
89 | pb.Text.Body.Done.SetValue("Well done!!");
90 |
91 | //Clear "Description Text"
92 | pb.Text.Description.Clear();
93 |
94 | for (int i = 0; i < max; i++)
95 | {
96 | Task.Delay(10).Wait(); //Do something
97 | pb.PerformStep(); //Step in ProgressBar (Default is 1)
98 | }
99 | }
100 | }
101 |
102 | public static void Example06()
103 | {
104 | const int max = 500;
105 |
106 | //Create the ProgressBar
107 | using (var pb = new ProgressBar() { Maximum = max })
108 | {
109 | //Setting "Processing Text" with context
110 | pb.Text.Body.Processing.SetValue(pb => ($"Processing {pb.ElementName}, please wait..."));
111 |
112 | //Setting "Done Text" with context
113 | pb.Text.Body.Done.SetValue(pb => $"Processed {pb.Maximum} in {pb.TimeProcessing.TotalSeconds}s.");
114 |
115 | //Clear "Description Text"
116 | pb.Text.Description.Clear();
117 |
118 | for (int i = 0; i < max; i++)
119 | {
120 | string elementName = Guid.NewGuid().ToString();
121 |
122 | Task.Delay(10).Wait(); //Do something
123 | pb.PerformStep(elementName); //Step in ProgressBar. Setting current ElementName
124 | }
125 | }
126 | }
127 | public static void Example07()
128 | {
129 | const int max = 500;
130 |
131 | //Create the ProgressBar
132 | using (var pb = new ProgressBar() { Maximum = max })
133 | {
134 | //Clear "Description Text"
135 | pb.Text.Description.Clear();
136 |
137 | //Setting "Description Text" when "Processing"
138 | pb.Text.Description.Processing.AddNew().SetValue(pb => $"Element: {pb.ElementName}");
139 | pb.Text.Description.Processing.AddNew().SetValue(pb => $"Count: {pb.Value}");
140 | pb.Text.Description.Processing.AddNew().SetValue(pb => $"Processing time: {pb.TimeProcessing.TotalSeconds}s.");
141 | pb.Text.Description.Processing.AddNew().SetValue(pb => $"Estimated remaining time: {pb.TimeRemaining?.TotalSeconds}s.");
142 |
143 | //Setting "Description Text" when "Done"
144 | pb.Text.Description.Done.AddNew().SetValue(pb => $"{pb.Value} elements in {pb.TimeProcessing.TotalSeconds}s.");
145 |
146 | for (int i = 0; i < max; i++)
147 | {
148 | string elementName = Guid.NewGuid().ToString();
149 |
150 | Task.Delay(10).Wait(); //Do something
151 | pb.PerformStep(elementName); //Step in ProgressBar. Setting current ElementName
152 | }
153 | }
154 | }
155 |
156 | public static void Example08()
157 | {
158 | const int max = 150;
159 |
160 | //Create the ProgressBar
161 | using (var pb = new ProgressBar() { Maximum = max, FixedInBottom = true })
162 | {
163 | //Clear "Description Text"
164 | pb.Text.Description.Clear();
165 |
166 | for (int i = 0; i < max; i++)
167 | {
168 | string elementName = Guid.NewGuid().ToString();
169 |
170 | Task.Delay(50).Wait(); //Do something
171 | pb.PerformStep(); //Step in ProgressBar (Default is 1)
172 |
173 | //Writing on Console with ProgressBar
174 | pb.WriteLine($"> [{DateTime.Now:HH:mm:ss.fff}]: Processed {i}: {elementName}");
175 | }
176 | }
177 | }
178 |
179 | public static void Example09()
180 | {
181 | const int max = 500;
182 |
183 | //Create the ProgressBar
184 | using (var pb = new ProgressBar(autoStart: false) { Maximum = max })
185 | {
186 | // Hide Text
187 | pb.Text.Body.SetVisible(false);
188 |
189 | // Clear "Description Text"
190 | pb.Text.Description.Clear();
191 |
192 | // Setting "Description Indentation", with color
193 | pb.Text.Description.Indentation.SetValue("└───> ")
194 | .SetForegroundColor(ConsoleColor.Cyan);
195 |
196 | // Setting "Description Text" when "Done", with color
197 | pb.Text.Description.Done.AddNew().SetValue(pb => $"{pb.Value} elements in {pb.TimeProcessing.TotalSeconds}s.")
198 | .SetForegroundColor(ConsoleColor.DarkBlue);
199 |
200 | // Hide "Margins"
201 | pb.Layout.Margins.SetVisible(false);
202 |
203 | // Setting "Body" layout
204 | pb.Layout.Body.SetValue('─');
205 | pb.Layout.Body.Progress.SetForegroundColor(ConsoleColor.DarkGreen);
206 | pb.Layout.Body.Pending.SetForegroundColor(ConsoleColor.DarkRed);
207 |
208 | // Setting "Marquee" layout
209 | pb.Layout.Marquee.SetValue('─');
210 | pb.Layout.Marquee.OverProgress.SetForegroundColor(ConsoleColor.Yellow);
211 | pb.Layout.Marquee.OverPending.SetForegroundColor(ConsoleColor.DarkYellow);
212 |
213 | // Setting ProgressBar width
214 | pb.Layout.ProgressBarWidth = Console.BufferWidth;
215 |
216 | pb.Start();
217 |
218 | for (int i = 0; i < max; i++)
219 | {
220 | Task.Delay(10).Wait(); //Do something
221 | pb.PerformStep(); //Step in ProgressBar (Default is 1)
222 | }
223 | }
224 | }
225 |
226 | public static void Example10()
227 | {
228 | const int max = 500;
229 |
230 | //Create the ProgressBar
231 | using (var pb = new ProgressBar(autoStart: false) { Maximum = max })
232 | {
233 | // Hide Text
234 | pb.Text.Body.SetVisible(false);
235 |
236 | // Clear "Description Text"
237 | pb.Text.Description.Clear();
238 |
239 | // Hide "Margins"
240 | pb.Layout.Margins.SetVisible(false);
241 |
242 | // Hide "Marquee"
243 | pb.Layout.Marquee.SetVisible(false);
244 |
245 | // Setting Body Colors
246 | pb.Layout.Body.Pending.SetForegroundColor(ConsoleColor.White).SetBackgroundColor(ConsoleColor.DarkRed);
247 | pb.Layout.Body.Progress.SetForegroundColor(ConsoleColor.Black).SetBackgroundColor(ConsoleColor.DarkGreen);
248 |
249 | // Setting Body Text (internal text), from Layout
250 | pb.Layout.Body.Text.SetVisible(true).SetValue(pb =>
251 | {
252 | if (pb.IsDone)
253 | return $"{pb.Value} elements processed in {pb.TimeProcessing.TotalSeconds}s.";
254 | else
255 | return $"{pb.Percentage}%... Remaining: {pb.TimeRemaining?.TotalSeconds}s. - Current: {pb.ElementName}";
256 | });
257 |
258 | // Setting ProgressBar width
259 | pb.Layout.ProgressBarWidth = Console.BufferWidth;
260 |
261 | pb.Start();
262 |
263 | for (int i = 0; i < max; i++)
264 | {
265 | string elementName = Guid.NewGuid().ToString();
266 |
267 | Task.Delay(10).Wait(); //Do something
268 | pb.PerformStep(elementName); //Step in ProgressBar. Setting current ElementName
269 | }
270 | }
271 | }
272 |
273 | public static void Example11()
274 | {
275 | const int max = 500;
276 |
277 | //Create the ProgressBar
278 | using (var pb = new ProgressBar(autoStart: false) { Maximum = max })
279 | {
280 | // Hide Text
281 | pb.Text.Body.SetVisible(false);
282 |
283 | // Clear "Description Text"
284 | pb.Text.Description.Clear();
285 |
286 | // Hide "Description Indentation"
287 | pb.Text.Description.Indentation.SetVisible(false);
288 |
289 | // Setting "Description" when "Processing", with color
290 | pb.Text.Description.Processing.AddNew().SetValue(pb => $"{pb.ElementName}...")
291 | .SetForegroundColor(ConsoleColor.DarkGray);
292 |
293 |
294 | // Hide "Margins"
295 | pb.Layout.Margins.SetVisible(false);
296 |
297 | // Set "Marquee" Color
298 | pb.Layout.Marquee.SetBackgroundColor(ConsoleColor.Black);
299 |
300 | // Setting Body Colors
301 | pb.Layout.Body.SetBackgroundColor(ConsoleColor.Black);
302 | pb.Layout.Body.Pending.SetForegroundColor(ConsoleColor.Red);
303 | pb.Layout.Body.Progress.SetForegroundColor(pb => pb.IsDone ? ConsoleColor.Cyan : ConsoleColor.Green);
304 |
305 | // Setting Body Text (internal text), from Layout
306 | string textDone = "----------------Done----------------";
307 | string text = "-------------Processing-------------";
308 | pb.Layout.Body.Text.SetVisible(true).SetValue(pb => pb.IsDone ? textDone : text);
309 |
310 | // Setting ProgressBar width
311 | pb.Layout.ProgressBarWidth = text.Length;
312 |
313 | pb.Start();
314 |
315 | for (int i = 0; i < max; i++)
316 | {
317 | string elementName = Guid.NewGuid().ToString();
318 |
319 | Task.Delay(10).Wait(); //Do something
320 | pb.PerformStep(elementName); //Step in ProgressBar. Setting current ElementName
321 | }
322 | }
323 | }
324 | }
325 | }
326 |
--------------------------------------------------------------------------------
/ConsoleProgressBarDemo/Program.cs:
--------------------------------------------------------------------------------
1 | // Description: ProgressBar for Console Applications, with advanced features.
2 | // Project site: https://github.com/iluvadev/ConsoleProgressBar
3 | // Issues: https://github.com/iluvadev/ConsoleProgressBar/issues
4 | // License (MIT): https://github.com/iluvadev/ConsoleProgressBar/blob/main/LICENSE
5 | //
6 | // Copyright (c) 2021, iluvadev, and released under MIT License.
7 | //
8 |
9 |
10 | using iluvadev.ConsoleProgressBar;
11 | using iluvadev.ConsoleProgressBar.Extensions;
12 | using System;
13 | using System.Collections.Generic;
14 | using System.Threading.Tasks;
15 |
16 | namespace iluvadev.ConsoleProgressBarDemo
17 | {
18 | class Program
19 | {
20 | static void Main(string[] args)
21 | {
22 | Console.ReadKey();
23 |
24 | DemoProgressBar.Example11();
25 | //Example2();
26 |
27 | Console.ReadKey();
28 |
29 |
30 | //Console.WriteLine();
31 | //Console.WriteLine();
32 | //Console.WriteLine(" ProgressBarConsole with customization: ");
33 | ////Console.ReadKey();
34 | //ProgressBarLayout pgLayout2 = new ProgressBarLayout
35 | //{
36 | // Start = "",
37 | // End = ">",
38 | // Pending = ' ',
39 | // Progress = '█',
40 | // MarqueeAlone = '-',
41 | // MarqueeInProgressPending = '·',
42 | // MarqueeInProgress = '▓',
43 | //};
44 | //using (var pg = new ProgressBarConsole(pgLayout2)
45 | //{
46 | // ProgressTextFunc = (pb) => pb.Text ?? $"Please, press any key. Time waiting: {pb.ProcessingTime.TotalSeconds}s",
47 | // Value = 0,
48 | // Maximum = 0,
49 | // InnerLength = 5,
50 | // MarqueeDelay = 100,
51 | // ShowProgress = false
52 | //})
53 | //{
54 | // var key = Console.ReadKey(true);
55 | // pg.Text = $"Thanks! The key is {key.KeyChar}";
56 | //}
57 | ////Console.ReadKey();
58 |
59 | //Console.WriteLine("All done! Press enter to exit");
60 | //Console.ReadLine();
61 | }
62 |
63 |
64 | private static void Example2()
65 | {
66 | Random random = new Random(Guid.NewGuid().GetHashCode());
67 | //Randomize elementNames
68 | var elementNames = new List();
69 | for (int i = 0; i < 1000; i++)
70 | {
71 | var randomNum = random.Next(200) + 20;
72 | string elementName = "";
73 | for (int j = 0; j < randomNum; j++)
74 | elementName += (char)(random.Next(25) + 65);
75 | elementNames.Add(elementName);
76 | }
77 |
78 | Console.ReadKey();
79 | Console.Clear();
80 | Console.SetCursorPosition(0, 0);
81 | Console.Write("ProgressBar 5:");
82 | Console.CursorVisible = false;
83 | Task taskPb1 = new Task(() =>
84 | {
85 | using (var pb = new ProgressBar(1, false) { Maximum = 500 })
86 | {
87 | pb.Text.Description.Clear();
88 | pb.Layout.Marquee.SetVisible(false);
89 | pb.Layout.Margins.SetVisible(false);
90 | pb.Layout.Body.Pending.SetForegroundColor(ConsoleColor.White).SetBackgroundColor(ConsoleColor.DarkRed);
91 | pb.Layout.Body.Progress.SetForegroundColor(ConsoleColor.Black).SetBackgroundColor(ConsoleColor.DarkGreen);
92 | pb.Layout.ProgressBarWidth = Console.BufferWidth;
93 |
94 | pb.Layout.Body.Text.SetVisible(true).SetValue(p =>
95 | {
96 | if (p.IsDone)
97 | return $"{p.Value} elements processed in {p.TimeProcessing.ToStringWithAllHours()}";
98 | else
99 | return $"{p.Percentage}%... Remaining: {p.TimeRemaining.ToStringWithAllHours(false)} - Current: {p.ElementName}";
100 | });
101 |
102 | pb.Start();
103 | for (int i = 0; i < 500; i++)
104 | {
105 | Task.Delay(10).Wait();
106 | pb.PerformStep(elementNames[i % elementNames.Count]);
107 | }
108 | }
109 | });
110 | taskPb1.Start();
111 |
112 | Console.SetCursorPosition(0, 4);
113 | Console.Write("ProgressBar 6:");
114 | Console.CursorVisible = false;
115 | Task taskPb2 = new Task(() =>
116 | {
117 | using (var pb = new ProgressBar(5, false) { Maximum = 500 })
118 | {
119 | pb.Text.Body.Done
120 | .SetValue(p => $"Progress Bar 6: {p.Value} elements processed in {p.TimeProcessing.ToStringWithAllHours()}")
121 | .SetForegroundColor(p => ConsoleColor.Green);
122 |
123 | string text = "------Processing------";
124 | string textDone = "---------Done---------";
125 | pb.Layout.Margins.SetVisible(false);
126 | pb.Layout.ProgressBarWidth = text.Length + pb.Layout.Margins.GetLength(pb);
127 | pb.Layout.Body.Text.SetVisible(true).SetValue(p => p.IsDone ? textDone : text);
128 | pb.Layout.Body.Progress.SetForegroundColor(ConsoleColor.Green);
129 | pb.Layout.Body.Pending.SetForegroundColor(ConsoleColor.DarkRed);
130 | pb.Layout.Body.SetBackgroundColor(ConsoleColor.Black);
131 | pb.Layout.Marquee.SetBackgroundColor(ConsoleColor.Black);
132 | pb.Text.Description.Clear();
133 |
134 | pb.Start();
135 | for (int i = 0; i < 500; i++)
136 | {
137 | Task.Delay(15).Wait();
138 | pb.PerformStep(elementNames[i % elementNames.Count]);
139 | }
140 | }
141 | });
142 | taskPb2.Start();
143 |
144 | //Console.SetCursorPosition(0, 8);
145 | //Console.Write("ProgressBar 3:");
146 | //Console.CursorVisible = false;
147 | //Task taskPb3 = new Task(() =>
148 | //{
149 | // using (var pb = new ProgressBar(9, false) { Maximum = 500 })
150 | // {
151 | // pb.Layout.ProgressBarWidth = Console.BufferWidth;
152 | // pb.Layout.Body.Pending.SetValue('─');
153 | // pb.Layout.Marquee.OverPending.SetValue('─');
154 |
155 | // pb.Start();
156 | // for (int i = 0; i < 500; i++)
157 | // {
158 | // Task.Delay(20).Wait();
159 | // pb.PerformStep(elementNames[i % elementNames.Count]);
160 | // }
161 | // }
162 | //});
163 | //taskPb3.Start();
164 |
165 | //Console.SetCursorPosition(0, 13);
166 | //Console.Write("ProgressBar 4:");
167 | //Console.CursorVisible = false;
168 | //Task taskPb4 = new Task(() =>
169 | //{
170 | // using (var pb = new ProgressBar(14, false) { Maximum = null })
171 | // {
172 | // pb.Layout.ProgressBarWidth = 15;
173 | // pb.Layout.Margins.SetVisible(false);
174 | // pb.Layout.Body.Pending.SetValue('■').SetForegroundColor(ConsoleColor.Magenta);
175 | // pb.Layout.Marquee.OverPending.SetValue('■');
176 |
177 | // pb.Description.Clear();
178 | // pb.Description.Processing.AddNew().SetValue(p => p.Value.ToString()).SetForegroundColor(ConsoleColor.Yellow);
179 | // pb.Description.Processing.AddNew().SetValue(p => p.TimeProcessing.ToStringWithAllHours()).SetForegroundColor(ConsoleColor.Cyan);
180 |
181 | // pb.Start();
182 | // for (int i = 0; i < 500; i++)
183 | // {
184 | // Task.Delay(25).Wait();
185 | // pb.PerformStep(elementNames[i % elementNames.Count]);
186 | // }
187 | // }
188 | //});
189 | //taskPb4.Start();
190 |
191 | Task.WaitAll(taskPb1, taskPb2);
192 | }
193 |
194 | private static void Example3()
195 | {
196 | Random random = new Random(Guid.NewGuid().GetHashCode());
197 | //Randomize elementNames
198 | var elementNames = new List();
199 | for (int i = 0; i < 1000; i++)
200 | {
201 | var randomNum = random.Next(200) + 20;
202 | string elementName = "";
203 | for (int j = 0; j < randomNum; j++)
204 | elementName += (char)(random.Next(25) + 65);
205 | elementNames.Add(elementName);
206 | }
207 |
208 | Console.ReadKey();
209 | Console.Clear();
210 | Console.SetCursorPosition(0, 0);
211 | Console.Write("ProgressBar 7:");
212 | Console.CursorVisible = false;
213 |
214 | using (var pb = new ProgressBar() { Maximum = 500 })
215 | {
216 | pb.WriteLine();
217 | pb.WriteLine();
218 | for (int i = 0; i < 500; i++)
219 | {
220 | Task.Delay(10).Wait();
221 | pb.PerformStep(elementNames[i % elementNames.Count]);
222 | if ((i + 1) % 100 == 0)
223 | pb.WriteLine($"We can write... Element {i + 1} processed");
224 | }
225 | }
226 | }
227 |
228 | private static void Example4()
229 | {
230 | Random random = new Random(Guid.NewGuid().GetHashCode());
231 | //Randomize elementNames
232 | var elementNames = new List();
233 | for (int i = 0; i < 1000; i++)
234 | {
235 | var randomNum = random.Next(200) + 20;
236 | string elementName = "";
237 | for (int j = 0; j < randomNum; j++)
238 | elementName += (char)(random.Next(25) + 65);
239 | elementNames.Add(elementName);
240 | }
241 |
242 | Console.ReadKey();
243 | Console.Clear();
244 | Console.SetCursorPosition(0, 0);
245 | Console.WriteLine("ProgressBar 8:");
246 | Console.WriteLine("=============");
247 | Console.WriteLine();
248 | Console.CursorVisible = false;
249 |
250 | using (var pb = new ProgressBar(autoStart: false) { Maximum = 70 })
251 | {
252 | pb.FixedInBottom = true;
253 | pb.Start();
254 | for (int i = 0; i < 70; i++)
255 | {
256 | Task.Delay(120).Wait();
257 | string elementName = elementNames[i % elementNames.Count].ToLowerInvariant();
258 | pb.PerformStep(elementName);
259 | pb.WriteLine($"[Processed at {pb.TimeProcessing.ToStringWithAllHours(true)}] '{elementName}'", false);
260 | }
261 | }
262 | }
263 |
264 | private static void Example5()
265 | {
266 | Random random = new Random(Guid.NewGuid().GetHashCode());
267 | //Randomize elementNames
268 | var elementNames = new List();
269 | for (int i = 0; i < 1000; i++)
270 | {
271 | var randomNum = random.Next(200) + 20;
272 | string elementName = "";
273 | for (int j = 0; j < randomNum; j++)
274 | elementName += (char)(random.Next(25) + 65);
275 | elementNames.Add(elementName);
276 | }
277 |
278 | Console.ReadKey();
279 | Console.Clear();
280 | Console.SetCursorPosition(0, 0);
281 | Console.Write("Dynamic layout:");
282 | Console.CursorVisible = false;
283 | Task taskPb1 = new Task(() =>
284 | {
285 | using (var pb = new ProgressBar(1, false) { Maximum = 100 })
286 | {
287 |
288 | pb.Layout.Marquee.SetVisible(false);
289 | pb.Text.Description.Clear();
290 | pb.Text.Body.SetValue(pb => $"{pb.Percentage} %")
291 | .SetForegroundColor(pb =>
292 | {
293 | if (pb.Percentage < 20) return ConsoleColor.DarkRed;
294 | else if (pb.Percentage < 40) return ConsoleColor.Red;
295 | else if (pb.Percentage < 60) return ConsoleColor.DarkYellow;
296 | else if (pb.Percentage < 80) return ConsoleColor.DarkGreen;
297 | return ConsoleColor.Green;
298 | });
299 |
300 | pb.Layout.Marquee.SetVisible(false);
301 | pb.Layout.Margins.SetVisible(false);
302 | pb.Layout.Body.SetForegroundColor(pb =>
303 | {
304 | if (pb.Percentage < 20) return ConsoleColor.DarkRed;
305 | else if (pb.Percentage < 40) return ConsoleColor.Red;
306 | else if (pb.Percentage < 60) return ConsoleColor.DarkYellow;
307 | else if (pb.Percentage < 80) return ConsoleColor.DarkGreen;
308 | return ConsoleColor.Green;
309 | }).SetBackgroundColor(ConsoleColor.Black);
310 | pb.Layout.Body.Pending.SetValue('─').SetForegroundColor(ConsoleColor.DarkGray);
311 | pb.Layout.Body.Progress.SetValue('■');
312 | pb.Layout.ProgressBarWidth = Console.BufferWidth / 2;
313 |
314 | pb.Start();
315 | for (int i = 0; i < 100; i++)
316 | {
317 | Task.Delay(random.Next(100)).Wait();
318 | pb.PerformStep();
319 | }
320 | }
321 | });
322 | taskPb1.Start();
323 |
324 | Console.SetCursorPosition(0, 4);
325 | Console.Write("Dynamic descriptions:");
326 | Console.CursorVisible = false;
327 | Task taskPb2 = new Task(() =>
328 | {
329 | using (var pb = new ProgressBar(5, false) { Maximum = 500 })
330 | {
331 | pb.Text.Body.Done
332 | .SetValue(p => $"Progress Bar 2: {p.Value} elements processed in {p.TimeProcessing.ToStringWithAllHours()}")
333 | .SetForegroundColor(p => ConsoleColor.Green);
334 |
335 | pb.Text.Description.Clear();
336 |
337 | pb.Start();
338 | for (int i = 0; i < 500; i++)
339 | {
340 | Task.Delay(10).Wait();
341 | if ((i + 1) % 50 == 0)
342 | {
343 | var current = i + 1;
344 | var currentProcessing = pb.TimeProcessing;
345 | var currentRemaining = pb.TimeRemaining;
346 | pb.Text.Description.Processing.AddNew().SetValue(pb => $"{current} elements processed in {currentProcessing.ToStringWithAllHours()}, remaining: {currentRemaining.ToStringWithAllHours()}; ({pb.TimeRemaining.ToStringWithAllHours()}) ");
347 | //.SetForegroundColor(pb =>
348 | //{
349 | // var dif = (pb.Value - current) % 78;
350 | // if (dif < 10) return ConsoleColor.White;
351 | // else if (dif < 20) return ConsoleColor.DarkBlue;
352 | // else if (dif < 30) return ConsoleColor.Yellow;
353 | // else if (dif < 40) return ConsoleColor.DarkGreen;
354 | // return ConsoleColor.Magenta;
355 | //});
356 | pb.Text.Description.Done.AddNew().SetValue($"{i + 1} elements processed in {pb.TimeProcessing.TotalSeconds} secs.");
357 | }
358 | pb.PerformStep(elementNames[i % elementNames.Count]);
359 | }
360 | }
361 | });
362 | taskPb2.Start();
363 |
364 |
365 |
366 | Task.WaitAll(taskPb1, taskPb2);
367 | }
368 |
369 | private static void Example_Usage1()
370 | {
371 | const int max = 500;
372 |
373 | //Create the ProgressBar
374 | using (var pb = new ProgressBar { Maximum = max })
375 | {
376 | for (int i = 0; i < max; i++)
377 | {
378 | Task.Delay(50).Wait(); //Do thinks
379 | pb.PerformStep(); //Step in ProgressBar
380 | }
381 | }
382 | }
383 | }
384 | }
385 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 iluvadev
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://www.buymeacoffee.com/iluvadev)
2 |
3 | # ConsoleProgressBar
4 | A versatile and easy to use ProgressBar for Console applications, written in C#.
5 |
6 | Is **.Net Standard 2.1** (cross-platform ready).
7 |
8 | ## Features
9 | * Simple to use with many configuration options
10 | * Can show or hide a *Marquee*: a char that moves around the ProgressBar
11 | * Maximum is optional: If `Maximum` is `null`, no progress will be shown (but you can show Marquee)
12 | * Automatically calculates `Percentage` and *Estimated Remaining Time* (`TimeRemaining`)
13 | * Optional `Text` in the same line as ProgressBar
14 | * Optional multiple `Descriptions` under ProgressBar
15 | * Colors in all components: in ProgressBar `Layout` elements, in `Text` and `Descriptions`
16 |
17 | You can define dynamic content or values, with lambda expressions for:
18 | * Background and Foreground Colors of `Layout` elements, `Text` and `Descriptions`
19 | * Content of `Text` and `Descriptions`
20 | * Characters used in `Layout` to represent ProgressBar
21 |
22 | ### How it works
23 | ProgressBar creates an internal Thread. In this thread the component updates its representation in Console every few time.
24 | This time is configurable, modifying the ``Delay`` property (default: 75ms)
25 |
26 |
27 |
28 | ## Examples with images
29 | ### Default ProgressBar:
30 |
31 | 
32 | #### Code:
33 | ```csharp
34 | const int max = 500;
35 |
36 | //Create the ProgressBar
37 | using (var pb = new ProgressBar { Maximum = max })
38 | {
39 | for (int i = 0; i < max; i++)
40 | {
41 | Task.Delay(10).Wait(); //Do something
42 | pb.PerformStep(); //Step in ProgressBar (Default is 1)
43 | }
44 | }
45 | ```
46 | ### With params:
47 |
48 | 
49 | #### Code:
50 | ```csharp
51 | const int max = 1000;
52 |
53 | //Create the ProgressBar
54 | // initialPosition: Console Line to put the ProgressBar (optional, last Console line is assumed)
55 | // autoStart: Optional, default true
56 | // Maximum: The Max value in ProgressBar (Default is 100)
57 | // Step: The increment when performStep (Default is 1)
58 | using (var pb = new ProgressBar(initialPosition: 3, autoStart: false) { Maximum = max, Step = 2})
59 | {
60 | pb.Start(); // autoStart=false -> we need start manually
61 | for (int i = 0; i < max; i+=pb.Step)
62 | {
63 | Task.Delay(10).Wait(); //Do something
64 | pb.PerformStep(); //Step in ProgressBar
65 | }
66 | }
67 | ```
68 | ### Without Maximum:
69 | 
70 | #### Code:
71 | ```csharp
72 | const int max = 500;
73 |
74 | //Create the ProgressBar
75 | // Maximum: The Max value in ProgressBar (Default is 100)
76 | using (var pb = new ProgressBar() { Maximum = null })
77 | {
78 | for (int i = 0; i < max; i++)
79 | {
80 | Task.Delay(10).Wait(); //Do something
81 | pb.PerformStep(); //Step in ProgressBar (Default is 1)
82 | }
83 | }
84 | ```
85 | ### Setting text:
86 | 
87 | #### Code:
88 | ```csharp
89 | const int max = 500;
90 |
91 | //Create the ProgressBar
92 | using (var pb = new ProgressBar() { Maximum = max })
93 | {
94 | //Setting fixed "Processing Text"
95 | pb.Text.Body.Processing.SetValue("Processing, please wait...");
96 |
97 | //Setting "Done Text"
98 | pb.Text.Body.Done.SetValue("Well done!!");
99 |
100 | //Clear "Description Text"
101 | pb.Text.Description.Clear();
102 |
103 | for (int i = 0; i < max; i++)
104 | {
105 | Task.Delay(10).Wait(); //Do something
106 | pb.PerformStep(); //Step in ProgressBar (Default is 1)
107 | }
108 | }
109 | ```
110 | ### Setting contextual text:
111 | 
112 | #### Code:
113 | ```csharp
114 | const int max = 500;
115 |
116 | //Create the ProgressBar
117 | using (var pb = new ProgressBar() { Maximum = max })
118 | {
119 | //Setting "Processing Text" with context
120 | pb.Text.Body.Processing.SetValue(pb => ($"Processing {pb.ElementName}, please wait..."));
121 |
122 | //Setting "Done Text" with context
123 | pb.Text.Body.Done.SetValue(pb => $"Processed {pb.Maximum} in {pb.TimeProcessing.TotalSeconds}s.");
124 |
125 | //Clear "Description Text"
126 | pb.Text.Description.Clear();
127 |
128 | for (int i = 0; i < max; i++)
129 | {
130 | string elementName = Guid.NewGuid().ToString();
131 |
132 | Task.Delay(10).Wait(); //Do something
133 | pb.PerformStep(elementName); //Step in ProgressBar. Setting current ElementName
134 | }
135 | }
136 | ```
137 | ### Setting descriptions:
138 | 
139 | #### Code:
140 | ```csharp
141 | const int max = 500;
142 |
143 | //Create the ProgressBar
144 | using (var pb = new ProgressBar() { Maximum = max })
145 | {
146 | //Clear "Description Text"
147 | pb.Text.Description.Clear();
148 |
149 | //Setting "Description Text" when "Processing"
150 | pb.Text.Description.Processing.AddNew().SetValue(pb => $"Element: {pb.ElementName}");
151 | pb.Text.Description.Processing.AddNew().SetValue(pb => $"Count: {pb.Value}");
152 | pb.Text.Description.Processing.AddNew().SetValue(pb => $"Processing time: {pb.TimeProcessing.TotalSeconds}s.");
153 | pb.Text.Description.Processing.AddNew().SetValue(pb => $"Estimated remaining time: {pb.TimeRemaining?.TotalSeconds}s.");
154 |
155 | //Setting "Description Text" when "Done"
156 | pb.Text.Description.Done.AddNew().SetValue(pb => $"{pb.Value} elements in {pb.TimeProcessing.TotalSeconds}s.");
157 |
158 | for (int i = 0; i < max; i++)
159 | {
160 | string elementName = Guid.NewGuid().ToString();
161 |
162 | Task.Delay(10).Wait(); //Do something
163 | pb.PerformStep(elementName); //Step in ProgressBar. Setting current ElementName
164 | }
165 | }
166 | ```
167 | ### Writing on Console:
168 | 
169 | #### Code:
170 | ```csharp
171 | const int max = 150;
172 |
173 | //Create the ProgressBar
174 | using (var pb = new ProgressBar() { Maximum = max, FixedInBottom = true })
175 | {
176 | //Clear "Description Text"
177 | pb.Text.Description.Clear();
178 |
179 | for (int i = 0; i < max; i++)
180 | {
181 | string elementName = Guid.NewGuid().ToString();
182 |
183 | Task.Delay(50).Wait(); //Do something
184 | pb.PerformStep(); //Step in ProgressBar (Default is 1)
185 |
186 | //Writing on Console with ProgressBar
187 | pb.WriteLine($"> [{DateTime.Now:HH:mm:ss.fff}]: Processed {i}: {elementName}");
188 | }
189 | }
190 | ```
191 | ### Styling (1):
192 | 
193 | #### Code:
194 | ```csharp
195 | const int max = 500;
196 |
197 | //Create the ProgressBar
198 | using (var pb = new ProgressBar(autoStart: false) { Maximum = max })
199 | {
200 | // Hide Text
201 | pb.Text.Body.SetVisible(false);
202 |
203 | // Clear "Description Text"
204 | pb.Text.Description.Clear();
205 |
206 | // Setting "Description Indentation", with color
207 | pb.Text.Description.Indentation.SetValue("└───> ")
208 | .SetForegroundColor(ConsoleColor.Cyan);
209 |
210 | // Setting "Description Text" when "Done", with color
211 | pb.Text.Description.Done.AddNew().SetValue(pb => $"{pb.Value} elements in {pb.TimeProcessing.TotalSeconds}s.")
212 | .SetForegroundColor(ConsoleColor.DarkBlue);
213 |
214 | // Hide "Margins"
215 | pb.Layout.Margins.SetVisible(false);
216 |
217 | // Setting "Body" layout
218 | pb.Layout.Body.SetValue('─');
219 | pb.Layout.Body.Progress.SetForegroundColor(ConsoleColor.DarkGreen);
220 | pb.Layout.Body.Pending.SetForegroundColor(ConsoleColor.DarkRed);
221 |
222 | // Setting "Marquee" layout
223 | pb.Layout.Marquee.SetValue('─');
224 | pb.Layout.Marquee.OverProgress.SetForegroundColor(ConsoleColor.Yellow);
225 | pb.Layout.Marquee.OverPending.SetForegroundColor(ConsoleColor.DarkYellow);
226 |
227 | // Setting ProgressBar width
228 | pb.Layout.ProgressBarWidth = Console.BufferWidth;
229 |
230 | pb.Start();
231 |
232 | for (int i = 0; i < max; i++)
233 | {
234 | Task.Delay(10).Wait(); //Do something
235 | pb.PerformStep(); //Step in ProgressBar (Default is 1)
236 | }
237 | }
238 | ```
239 | ### Styling (2):
240 | 
241 | #### Code:
242 | ```csharp
243 | const int max = 500;
244 |
245 | //Create the ProgressBar
246 | using (var pb = new ProgressBar(autoStart: false) { Maximum = max })
247 | {
248 | // Hide Text
249 | pb.Text.Body.SetVisible(false);
250 |
251 | // Clear "Description Text"
252 | pb.Text.Description.Clear();
253 |
254 | // Hide "Margins"
255 | pb.Layout.Margins.SetVisible(false);
256 |
257 | // Hide "Marquee"
258 | pb.Layout.Marquee.SetVisible(false);
259 |
260 | // Setting Body Colors
261 | pb.Layout.Body.Pending.SetForegroundColor(ConsoleColor.White)
262 | .SetBackgroundColor(ConsoleColor.DarkRed);
263 | pb.Layout.Body.Progress.SetForegroundColor(ConsoleColor.Black)
264 | .SetBackgroundColor(ConsoleColor.DarkGreen);
265 |
266 | // Setting Body Text (internal text), from Layout
267 | pb.Layout.Body.Text.SetVisible(true).SetValue(pb =>
268 | {
269 | if (pb.IsDone)
270 | return $"{pb.Value} elements processed in {pb.TimeProcessing.TotalSeconds}s.";
271 | else
272 | return $"{pb.Percentage}%... Remaining: {pb.TimeRemaining?.TotalSeconds}s. - Current: {pb.ElementName}";
273 | });
274 |
275 | // Setting ProgressBar width
276 | pb.Layout.ProgressBarWidth = Console.BufferWidth;
277 |
278 | pb.Start();
279 |
280 | for (int i = 0; i < max; i++)
281 | {
282 | string elementName = Guid.NewGuid().ToString();
283 |
284 | Task.Delay(10).Wait(); //Do something
285 | pb.PerformStep(elementName); //Step in ProgressBar. Setting current ElementName
286 | }
287 | }
288 | ```
289 | ### Styling (3):
290 | 
291 | #### Code:
292 | ```csharp
293 | const int max = 500;
294 |
295 | //Create the ProgressBar
296 | using (var pb = new ProgressBar(autoStart: false) { Maximum = max })
297 | {
298 | // Hide Text
299 | pb.Text.Body.SetVisible(false);
300 |
301 | // Clear "Description Text"
302 | pb.Text.Description.Clear();
303 |
304 | // Hide "Description Indentation"
305 | pb.Text.Description.Indentation.SetVisible(false);
306 |
307 | // Setting "Description" when "Processing", with color
308 | pb.Text.Description.Processing.AddNew().SetValue(pb => $"{pb.ElementName}...")
309 | .SetForegroundColor(ConsoleColor.DarkGray);
310 |
311 |
312 | // Hide "Margins"
313 | pb.Layout.Margins.SetVisible(false);
314 |
315 | // Set "Marquee" Color
316 | pb.Layout.Marquee.SetBackgroundColor(ConsoleColor.Black);
317 |
318 | // Setting Body Colors
319 | pb.Layout.Body.SetBackgroundColor(ConsoleColor.Black);
320 | pb.Layout.Body.Pending.SetForegroundColor(ConsoleColor.Red);
321 | pb.Layout.Body.Progress.SetForegroundColor(pb => pb.IsDone ? ConsoleColor.Cyan : ConsoleColor.Green);
322 |
323 | // Setting Body Text (internal text), from Layout
324 | string textDone = "----------------Done----------------";
325 | string text = "-------------Processing-------------";
326 | pb.Layout.Body.Text.SetVisible(true).SetValue(pb => pb.IsDone ? textDone : text);
327 |
328 | // Setting ProgressBar width
329 | pb.Layout.ProgressBarWidth = text.Length;
330 |
331 | pb.Start();
332 |
333 | for (int i = 0; i < max; i++)
334 | {
335 | string elementName = Guid.NewGuid().ToString();
336 |
337 | Task.Delay(10).Wait(); //Do something
338 | pb.PerformStep(elementName); //Step in ProgressBar. Setting current ElementName
339 | }
340 | }
341 | ```
342 | ### Other Style examples:
343 |
344 | 
345 |
346 | 
347 |
348 |
349 | ## Install
350 | [](https://www.nuget.org/packages/iluvadev.ConsoleProgressBar/)
351 |
352 | Go to [Nuget project page](https://www.nuget.org/packages/iluvadev.ConsoleProgressBar/) to see options
353 |
354 |
355 |
--------------------------------------------------------------------------------
/docs/ConsoleProgressBar.Extensions/ElementExtensions.md:
--------------------------------------------------------------------------------
1 | # ElementExtensions
2 |
3 | `Namespace: ConsoleProgressBar.Extensions`
4 |
5 | ```csharp
6 | public static class ElementExtensions
7 | ```
8 |
9 | ## Static Methods
10 |
11 | | Type | Name | Summary |
12 | | --- | --- | --- |
13 | | `List` | GetRenderActions(this `Element` element, `ProgressBar` progressBar, `Func` valueTransformer = null) | Returns a list of Actions to write the element in Console |
14 | | `List` | GetRenderActions(this `Element` element, `ProgressBar` progressBar, `Int32` repetition = 1) | Returns a list of Actions to write the element in Console |
15 |
16 | ---
17 |
18 | [`< Back`](../)
19 |
--------------------------------------------------------------------------------
/docs/ConsoleProgressBar.Extensions/StringExtensions.md:
--------------------------------------------------------------------------------
1 | # StringExtensions
2 |
3 | `Namespace: ConsoleProgressBar.Extensions`
4 |
5 | ```csharp
6 | public static class StringExtensions
7 | ```
8 |
9 | ## Static Methods
10 |
11 | | Type | Name | Summary |
12 | | --- | --- | --- |
13 | | `String` | AdaptToConsole(this `String` value, `Boolean` allowMultipleLines = True) | Returns a string that occupy all console line/s |
14 | | `String` | AdaptToMaxWidth(this `String` value, `Int32` maxWidth, `String` append = ...) | Returns a string with exactly maxChars: Truncates string value or fill with spaces to fits exact length |
15 |
16 | ---
17 |
18 | [`< Back`](../)
19 |
--------------------------------------------------------------------------------
/docs/ConsoleProgressBar.Extensions/TimeSpanExtensions.md:
--------------------------------------------------------------------------------
1 | # TimeSpanExtensions
2 |
3 | `Namespace: ConsoleProgressBar.Extensions`
4 |
5 | ```csharp
6 | public static class TimeSpanExtensions
7 | ```
8 |
9 | ## Static Methods
10 |
11 | | Type | Name | Summary |
12 | | --- | --- | --- |
13 | | `String` | ToStringAsSumarizedRemainingText(this `Nullable` ts) | Gets a textual Sumarized for remaining time: X days, or Y hours, or Z minutes, etc. |
14 | | `String` | ToStringAsSumarizedRemainingText(this `TimeSpan` ts) | Gets a textual Sumarized for remaining time: X days, or Y hours, or Z minutes, etc. |
15 | | `String` | ToStringWithAllHours(this `Nullable` ts, `Boolean` includeMilliseconds = True) | Converts a TimeSpan to String, showing all hours |
16 | | `String` | ToStringWithAllHours(this `TimeSpan` ts, `Boolean` includeMilliseconds = True) | Converts a TimeSpan to String, showing all hours |
17 |
18 | ---
19 |
20 | [`< Back`](../)
21 |
--------------------------------------------------------------------------------
/docs/ConsoleProgressBar/ProgressBar.md:
--------------------------------------------------------------------------------
1 | # ProgressBar
2 |
3 | `Namespace: ConsoleProgressBar`
4 |
5 | A ProgressBar for Console
6 |
7 | ```csharp
8 | public class ProgressBar
9 | : IDisposable
10 | ```
11 |
12 | ## Properties
13 |
14 | | Type | Name | Summary |
15 | | --- | --- | --- |
16 | | `Int32` | Delay | Delay for repaint and recalculate all ProgressBar Default = 75 |
17 | | `DescriptionDefinition` | Description | Description of the ProgressBar |
18 | | `String` | ElementName | The Name of the Curent Element |
19 | | `Boolean` | FixedInBottom | True to Print the ProgressBar always in last Console Line False to Print the ProgressBar fixed in Console (Current position at Starting) You can Write at Console and ProgressBar will always be below your lines Default = true |
20 | | `Boolean` | HasProgress | Indicates if the ProgressBar has Progress defined (Maximum defined) |
21 | | `Boolean` | IsDone | True if ProgresBar is Done: when disposing or Progress is finished |
22 | | `Boolean` | IsPaused | True if ProgressBar is Paused |
23 | | `Boolean` | IsStarted | True if ProgressBar is Started |
24 | | `LayoutDefinition` | Layout | Layout of the ProgressBar |
25 | | `Nullable` | Maximum | The Maximum value Default = 100 |
26 | | `Nullable` | Percentage | Percentage of progress |
27 | | `Int32` | Step | The amount by which to increment the ProgressBar with each call to the PerformStep() method. Default = 1 |
28 | | `Object` | Tag | Tag object |
29 | | `TextDefinition` | Text | Text of the ProgressBar |
30 | | `Nullable` | TimePerElement | Processing time per element (median) |
31 | | `TimeSpan` | TimeProcessing | Processing time (time paused excluded) |
32 | | `Nullable` | TimeRemaining | Estimated time finish (to Value = Maximum) |
33 | | `Int32` | Value | The current Value If Value is greater than Maximum, then updates Maximum value |
34 |
35 | ## Methods
36 |
37 | | Type | Name | Summary |
38 | | --- | --- | --- |
39 | | `void` | Dispose() | Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. |
40 | | `void` | Pause() | Pauses the ProgressBar |
41 | | `void` | PerformStep(`String` elementName = null, `Object` tag = null) | Advances the current position of the progress bar by the amount of the Step property |
42 | | `void` | Print() | Prints in Console the ProgressBar |
43 | | `void` | Resume() | Resume the ProgresBar |
44 | | `void` | SetValue(`Int32` value, `String` elementName = null, `Object` tag = null) | Assigns the current Value, and optionally current ElementName and Tag If Value is greater than Maximum, updates Maximum as Value |
45 | | `void` | Start() | Starts the ProgressBar |
46 | | `void` | Unprint() | Unprints (remove) from Console last ProgressBar printed |
47 | | `void` | WriteLine(`String` value, `Boolean` truncateToOneLine = True) | |
48 | | `void` | WriteLine(`String` value, `Nullable` foregroundColor = null, `Nullable` backgroundColor = null, `Boolean` truncateToOneLine = True) | |
49 |
50 | ## Static Fields
51 |
52 | | Type | Name | Summary |
53 | | --- | --- | --- |
54 | | `Object` | ConsoleWriterLock | A Lock for Writing to Console |
55 |
56 | ---
57 |
58 | [`< Back`](../)
59 |
--------------------------------------------------------------------------------
/docs/img/ProgressBarConsole-Default-Writing.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iluvadev/ConsoleProgressBar/08b3d7b5b5a49f313043ef2a1cfa73f9ddea0467/docs/img/ProgressBarConsole-Default-Writing.gif
--------------------------------------------------------------------------------
/docs/img/ProgressBarConsole-Default.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iluvadev/ConsoleProgressBar/08b3d7b5b5a49f313043ef2a1cfa73f9ddea0467/docs/img/ProgressBarConsole-Default.gif
--------------------------------------------------------------------------------
/docs/img/ProgressBarConsole-Demo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iluvadev/ConsoleProgressBar/08b3d7b5b5a49f313043ef2a1cfa73f9ddea0467/docs/img/ProgressBarConsole-Demo.gif
--------------------------------------------------------------------------------
/docs/img/ProgressBarConsole-Demo2.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iluvadev/ConsoleProgressBar/08b3d7b5b5a49f313043ef2a1cfa73f9ddea0467/docs/img/ProgressBarConsole-Demo2.gif
--------------------------------------------------------------------------------
/docs/img/ProgressBarConsole-Demo3.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iluvadev/ConsoleProgressBar/08b3d7b5b5a49f313043ef2a1cfa73f9ddea0467/docs/img/ProgressBarConsole-Demo3.gif
--------------------------------------------------------------------------------
/docs/img/ProgressBarConsole-Demo4.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iluvadev/ConsoleProgressBar/08b3d7b5b5a49f313043ef2a1cfa73f9ddea0467/docs/img/ProgressBarConsole-Demo4.gif
--------------------------------------------------------------------------------
/docs/img/ProgressBarConsole-Example01.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iluvadev/ConsoleProgressBar/08b3d7b5b5a49f313043ef2a1cfa73f9ddea0467/docs/img/ProgressBarConsole-Example01.gif
--------------------------------------------------------------------------------
/docs/img/ProgressBarConsole-Example02.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iluvadev/ConsoleProgressBar/08b3d7b5b5a49f313043ef2a1cfa73f9ddea0467/docs/img/ProgressBarConsole-Example02.gif
--------------------------------------------------------------------------------
/docs/img/ProgressBarConsole-Example03.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iluvadev/ConsoleProgressBar/08b3d7b5b5a49f313043ef2a1cfa73f9ddea0467/docs/img/ProgressBarConsole-Example03.gif
--------------------------------------------------------------------------------
/docs/img/ProgressBarConsole-Example04.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iluvadev/ConsoleProgressBar/08b3d7b5b5a49f313043ef2a1cfa73f9ddea0467/docs/img/ProgressBarConsole-Example04.gif
--------------------------------------------------------------------------------
/docs/img/ProgressBarConsole-Example05.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iluvadev/ConsoleProgressBar/08b3d7b5b5a49f313043ef2a1cfa73f9ddea0467/docs/img/ProgressBarConsole-Example05.gif
--------------------------------------------------------------------------------
/docs/img/ProgressBarConsole-Example06.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iluvadev/ConsoleProgressBar/08b3d7b5b5a49f313043ef2a1cfa73f9ddea0467/docs/img/ProgressBarConsole-Example06.gif
--------------------------------------------------------------------------------
/docs/img/ProgressBarConsole-Example07.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iluvadev/ConsoleProgressBar/08b3d7b5b5a49f313043ef2a1cfa73f9ddea0467/docs/img/ProgressBarConsole-Example07.gif
--------------------------------------------------------------------------------
/docs/img/ProgressBarConsole-Example08.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iluvadev/ConsoleProgressBar/08b3d7b5b5a49f313043ef2a1cfa73f9ddea0467/docs/img/ProgressBarConsole-Example08.gif
--------------------------------------------------------------------------------
/docs/img/ProgressBarConsole-Example09.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iluvadev/ConsoleProgressBar/08b3d7b5b5a49f313043ef2a1cfa73f9ddea0467/docs/img/ProgressBarConsole-Example09.gif
--------------------------------------------------------------------------------
/docs/img/ProgressBarConsole-Example10.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iluvadev/ConsoleProgressBar/08b3d7b5b5a49f313043ef2a1cfa73f9ddea0467/docs/img/ProgressBarConsole-Example10.gif
--------------------------------------------------------------------------------
/docs/img/ProgressBarConsole-Example11.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iluvadev/ConsoleProgressBar/08b3d7b5b5a49f313043ef2a1cfa73f9ddea0467/docs/img/ProgressBarConsole-Example11.gif
--------------------------------------------------------------------------------
/docs/img/ProgressBarConsole-Example_Usage1.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iluvadev/ConsoleProgressBar/08b3d7b5b5a49f313043ef2a1cfa73f9ddea0467/docs/img/ProgressBarConsole-Example_Usage1.gif
--------------------------------------------------------------------------------
/docs/index.md:
--------------------------------------------------------------------------------
1 | # ConsoleProgressBar
2 |
3 | ## `ConsoleProgressBar`
4 |
5 | - [`ProgressBar`](ConsoleProgressBar/ProgressBar)
6 |
7 | ## `ConsoleProgressBar.Extensions`
8 |
9 | - [`ElementExtensions`](ConsoleProgressBar.Extensions/ElementExtensions)
10 | - [`StringExtensions`](ConsoleProgressBar.Extensions/StringExtensions)
11 | - [`TimeSpanExtensions`](ConsoleProgressBar.Extensions/TimeSpanExtensions)
12 |
--------------------------------------------------------------------------------