• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

MorganKryze / ConsoleAppVisuals / 7465772104

09 Jan 2024 07:11PM UTC coverage: 12.896% (+0.8%) from 12.086%
7465772104

push

github

MorganKryze
✅ (visual) add attribute to ignore

216 of 1544 branches covered (0.0%)

Branch coverage included in aggregate %.

4 of 15 new or added lines in 5 files covered. (26.67%)

4 existing lines in 2 files now uncovered.

321 of 2620 relevant lines covered (12.25%)

22.11 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

11.98
/src/ConsoleAppVisuals/Core.cs
1
/*
2
    MIT License 2023 MorganKryze
3
    For full license information, please visit: https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/LICENSE
4
*/
5

6
using System.Diagnostics.CodeAnalysis;
7
namespace ConsoleAppVisuals;
8

9
/// <summary>
10
/// The <see cref="Core"/> class contains visual elements for a console app.
11
/// </summary>
12
public static class Core
13
{
14
    #region Constants
15
    /// <summary>
16
    /// This constant is used to define the negative anchor to put inside a string to be recognized as negative.
17
    /// </summary>
18
    public const string NEGATIVE_ANCHOR = "/neg";
19
    #endregion
20

21
    #region Attributes
22

23
    [Obsolete(
24
        "This field is deprecated, please use the Window class elements instead. will be removed on v3.1.0",
25
        false
26
    )]
27
    private static (string[]?, int?) s_title;
28
    private static TextStyler s_styler = new();
×
29
    private static (char, char) s_Selector = ('▶', '◀');
×
30

31
    [Visual]
32
    private static int s_previousWindowWidth = Console.WindowWidth;
×
33

34
    [Visual]
35
    private static int s_previousWindowHeight = Console.WindowHeight;
×
36
    private static (ConsoleColor, ConsoleColor) s_colorPanel = (
×
37
        ConsoleColor.White,
×
38
        ConsoleColor.Black
×
39
    );
×
40
    private static (ConsoleColor, ConsoleColor) s_initialColorPanel = (
×
41
        s_colorPanel.Item1,
×
42
        s_colorPanel.Item2
×
43
    );
×
44

45
    [Visual]
46
    private static (ConsoleColor, ConsoleColor) s_terminalColorPanel = (
×
47
        Console.ForegroundColor,
×
48
        Console.BackgroundColor
×
49
    );
×
50
    private static (ConsoleColor, ConsoleColor) s_savedColorPanel;
51

52
    [Obsolete(
53
        "This field is deprecated, please use the Window class elements instead. will be removed on v3.1.0",
54
        false
55
    )]
56
    private static (string, string, string) defaultHeader = (
×
57
        "Header Left",
×
58
        "Header Center",
×
59
        "Header Right"
×
60
    );
×
61

62
    [Obsolete(
63
        "This field is deprecated, please use the Window class elements instead. will be removed on v3.1.0",
64
        false
65
    )]
66
    private static (string, string, string) defaultFooter = (
×
67
        "Footer Left",
×
68
        "Footer Center",
×
69
        "Footer Right"
×
70
    );
×
71
    private static readonly Random s_rnd = new();
×
72
    #endregion
73

74
    #region Properties
75
    /// <summary>
76
    /// This property is used to get the selector of the console menus.
77
    /// </summary>
78
    public static (char, char) GetSelector => s_Selector;
×
79

80
    /// <summary>
81
    /// This property is used to get the height of the title.
82
    /// </summary>
83

84
    [Obsolete(
85
        "This method is deprecated, please use the Window class elements instead. will be removed on v3.1.0",
86
        false
87
    )]
88
    public static int? TitleHeight => s_title.Item1?.Length + 2 * s_title.Item2;
×
89

90
    /// <summary>
91
    /// This property is used to get the height of the header.
92
    /// </summary>
93

94
    [Obsolete(
95
        "This method is deprecated, please use the Window class elements instead. will be removed on v3.1.0",
96
        false
97
    )]
98
    public static int HeaderHeight => TitleHeight ?? 0;
×
99

100
    /// <summary>
101
    /// This property is used to get the height of the footer.
102
    /// </summary>
103

104
    [Obsolete(
105
        "This method is deprecated, please use the Window class elements instead. will be removed on v3.1.0",
106
        false
107
    )]
108
    public static int FooterHeight => Console.WindowHeight - 1;
×
109

110
    /// <summary>
111
    /// This property is used to get the start line of the content.
112
    /// </summary>
113

114
    [Obsolete(
115
        "This method is deprecated, please use the Window class elements instead. will be removed on v3.1.0",
116
        false
117
    )]
118
    public static int ContentHeight => HeaderHeight + 2;
×
119

120
    /// <summary>
121
    /// This property is used to get the colors of the console.
122
    /// </summary>
123
    /// <returns>A tuple containing the font color and the background color.</returns>
124
    public static (ConsoleColor, ConsoleColor) GetColorPanel => s_colorPanel;
×
125

126
    /// <summary>
127
    /// This property is used to check if the screen has been updated.
128
    /// </summary>
129
    /// <returns>True if the screen has been updated, false otherwise.</returns>
130
    /// <remarks>The screen is updated if the window size has changed or if the color panel has changed.</remarks>
131
    [Visual]
132
    public static bool IsScreenUpdated =>
133
        Console.WindowWidth != s_previousWindowWidth
134
        || Console.WindowHeight != s_previousWindowHeight
135
        || s_colorPanel != s_initialColorPanel;
136
    #endregion
137

138
    #region Low abstraction level methods
139
    /// <summary>
140
    /// This method is used to set the selector of the console menus.
141
    /// </summary>
142
    /// <param name="onward">The new selector facing forward.</param>
143
    /// <param name="backward">The new selector facing backward.</param>
144
    /// <remarks>
145
    /// For more information, refer to the following resources:
146
    /// <list type="bullet">
147
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
148
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/Program.cs">Example Project</a></description></item>
149
    /// </list>
150
    /// </remarks>
151
    public static void SetSelector(char onward, char backward)
152
    {
153
        s_Selector = (onward, backward);
×
154
    }
×
155

156
    /// <summary>
157
    /// This method changes the font color of the console.
158
    /// </summary>
159
    /// <param name="color">The new font color.</param>
160
    /// <remarks>
161
    /// For more information, refer to the following resources:
162
    /// <list type="bullet">
163
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
164
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/Program.cs">Example Project</a></description></item>
165
    /// </list>
166
    /// </remarks>
167
    public static void SetForegroundColor(ConsoleColor color)
168
    {
169
        s_colorPanel.Item1 = color;
×
170
        Console.ForegroundColor = color;
×
171
    }
×
172

173
    /// <summary>
174
    /// This method changes the background color of the console.
175
    /// </summary>
176
    /// <param name="color">The new background color.</param>
177
    /// <remarks>
178
    /// For more information, refer to the following resources:
179
    /// <list type="bullet">
180
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
181
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/Program.cs">Example Project</a></description></item>
182
    /// </list>
183
    /// </remarks>
184
    public static void SetBackgroundColor(ConsoleColor color)
185
    {
186
        s_colorPanel.Item2 = color;
×
187
        Console.BackgroundColor = color;
×
188
    }
×
189

190
    /// <summary>
191
    /// This method is used to save the current color panel.
192
    /// </summary>
193
    /// <remarks>
194
    /// For more information, refer to the following resources:
195
    /// <list type="bullet">
196
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
197
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/Program.cs">Example Project</a></description></item>
198
    /// </list>
199
    /// </remarks>
200
    public static void SaveColorPanel() => s_savedColorPanel = s_colorPanel;
×
201

202
    /// <summary>
203
    /// This method is used to load the saved color panel.
204
    /// </summary>
205
    /// <remarks>
206
    /// For more information, refer to the following resources:
207
    /// <list type="bullet">
208
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
209
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/Program.cs">Example Project</a></description></item>
210
    /// </list>
211
    /// </remarks>
212
    public static void LoadSavedColorPanel() => s_colorPanel = s_savedColorPanel;
×
213

214
    /// <summary>
215
    /// This method is used to load the terminal color panel.
216
    /// </summary>
217
    /// <remarks>
218
    /// For more information, refer to the following resources:
219
    /// <list type="bullet">
220
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
221
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/Program.cs">Example Project</a></description></item>
222
    /// </list>
223
    /// </remarks>
NEW
224
    public static void LoadTerminalColorPanel() => s_colorPanel = s_terminalColorPanel;
×
225

226
    /// <summary>
227
    /// This method is used to set the dimensions of the console to the Core variables associated. This does not change the actual dimensions of the console.
228
    /// </summary>
229
    /// <remarks>
230
    /// For more information, refer to the following resources:
231
    /// <list type="bullet">
232
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
233
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/Program.cs">Example Project</a></description></item>
234
    /// </list>
235
    /// </remarks>
236
    [Visual]
237
    public static void SetConsoleDimensions()
238
    {
239
        s_previousWindowWidth = Console.WindowWidth;
240
        s_previousWindowHeight = Console.WindowHeight;
241
    }
242

243
    /// <summary>
244
    /// This method is used to set the title of the console.
245
    /// </summary>
246
    /// <param name="str">The title input.</param>
247
    /// <param name="margin">The upper and lower margin of the title.</param>
248
    /// <remarks>Refer to the example project to understand how to implement it available at https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/Program.cs </remarks>
249
    [Obsolete(
250
        "This method is deprecated, please use the Window class elements instead. will be removed on v3.1.0",
251
        false
252
    )]
253
    public static void SetTitle(string str, int margin = 1) =>
254
        s_title = (s_styler.StyleTextToStringArray(str), margin);
×
255

256
    /// <summary>
257
    /// This method is used to set a new styler for the application.
258
    /// </summary>
259
    /// <param name="path">The path of the new styler files.</param>
260
    /// <remarks>
261
    /// For more information, refer to the following resources:
262
    /// <list type="bullet">
263
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
264
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/Program.cs">Example Project</a></description></item>
265
    /// </list>
266
    /// </remarks>
267
    public static void SetStyler(string path)
268
    {
269
        s_styler = new TextStyler(path);
×
270
    }
×
271

272
    /// <summary>
273
    /// This method is used to style a string.
274
    /// </summary>
275
    /// <param name="str">The string to style.</param>
276
    /// <returns>The styled string.</returns>
277
    /// <remarks>
278
    /// For more information, refer to the following resources:
279
    /// <list type="bullet">
280
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
281
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/Program.cs">Example Project</a></description></item>
282
    /// </list>
283
    /// </remarks>
284
    public static string[] StyleText(string str) => s_styler.StyleTextToStringArray(str);
×
285

286
    /// <summary>
287
    /// This method is used to set the default header.
288
    /// </summary>
289
    /// <param name="left">The default header left input.</param>
290
    /// <param name="center">The default header center input.</param>
291
    /// <param name="right">The default header right input.</param>
292
    /// <remarks>Refer to the example project to understand how to implement it available at https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/Program.cs </remarks>
293
    [Obsolete(
294
        "This method is deprecated, please use the Window class elements instead. will be removed on v3.1.0",
295
        false
296
    )]
297
    public static void SetDefaultHeader(string left, string center, string right) =>
298
        defaultHeader = (left, center, right);
×
299

300
    /// <summary>
301
    /// This method is used to set the default footer.
302
    /// </summary>
303
    /// <param name="left">The default footer left input.</param>
304
    /// <param name="center">The default footer center input.</param>
305
    /// <param name="right">The default footer right input.</param>
306
    /// <remarks>Refer to the example project to understand how to implement it available at https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/Program.cs </remarks>
307
    [Obsolete(
308
        "This method is deprecated, please use the Window class elements instead. will be removed on v3.1.0",
309
        false
310
    )]
311
    public static void SetDefaultFooter(string left, string center, string right) =>
312
        defaultFooter = (left, center, right);
×
313

314
    /// <summary>
315
    /// This methods is used to get a random color from a selection.
316
    /// </summary>
317
    /// <returns>A random color.</returns>
318
    /// <remarks>
319
    /// For more information, refer to the following resources:
320
    /// <list type="bullet">
321
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
322
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/Program.cs">Example Project</a></description></item>
323
    /// </list>
324
    /// </remarks>
325
    public static ConsoleColor GetRandomColor()
326
    {
327
        var colors = new List<ConsoleColor>
×
328
        {
×
329
            ConsoleColor.Red,
×
330
            ConsoleColor.Green,
×
331
            ConsoleColor.Blue,
×
332
            ConsoleColor.Yellow,
×
333
            ConsoleColor.Magenta,
×
334
            ConsoleColor.Cyan
×
335
        };
×
336
        return colors[s_rnd.Next(colors.Count)];
×
337
    }
338

339
    /// <summary>
340
    /// This method is used to restore the default colors of the console.
341
    /// </summary>
342
    /// <remarks>
343
    /// For more information, refer to the following resources:
344
    /// <list type="bullet">
345
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
346
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/Program.cs">Example Project</a></description></item>
347
    /// </list>
348
    /// </remarks>
349
    public static void RestoreColorPanel()
350
    {
351
        Console.ForegroundColor = s_initialColorPanel.Item1;
×
352
        Console.BackgroundColor = s_initialColorPanel.Item2;
×
353
        s_colorPanel = s_initialColorPanel;
×
354
    }
×
355

356
    /// <summary>
357
    /// This method changes the font and background colors of the console in order to apply
358
    /// a negative to highlight the text or not.
359
    /// </summary>
360
    /// <param name="negative">If true, the text is highlighted.</param>
361
    /// <remarks>
362
    /// For more information, refer to the following resources:
363
    /// <list type="bullet">
364
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
365
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/Program.cs">Example Project</a></description></item>
366
    /// </list>
367
    /// </remarks>
368
    public static void ApplyNegative(bool negative = false)
369
    {
370
        Console.ForegroundColor = negative ? s_colorPanel.Item2 : s_colorPanel.Item1;
×
371
        Console.BackgroundColor = negative ? s_colorPanel.Item1 : s_colorPanel.Item2;
×
372
    }
×
373

374
    /// <summary>
375
    /// This method is used to update the screen display if it has encountered a change.
376
    /// </summary>
377
    /// <remarks>Refer to the example project to understand how to implement it available at https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/Program.cs </remarks>
378
    [Obsolete(
379
        "This method is deprecated, please use the Window class elements instead. will be removed on v3.1.0",
380
        false
381
    )]
382
    public static void UpdateScreen()
383
    {
384
        if (IsScreenUpdated)
×
385
        {
386
            s_previousWindowWidth = Console.WindowWidth;
×
387
            s_previousWindowHeight = Console.WindowHeight;
×
388
            s_initialColorPanel = (s_colorPanel.Item1, s_colorPanel.Item2);
×
389
            WriteFullScreen();
×
390
        }
391
    }
×
392

393
    /// <summary>
394
    /// This method is used to Clear a specified line in the console.
395
    /// </summary>
396
    /// <param name="line">The line to clear.If null, will be cleared where the cursor is.</param>
397
    [Obsolete(
398
        "This method is deprecated, please use the Window class elements instead. will be removed on v3.1.0",
399
        false
400
    )]
401
    public static void ClearLine(int? line)
402
    {
403
        line ??= Console.CursorTop;
×
404
        ApplyNegative(default);
×
405
        WritePositionedString("".PadRight(Console.WindowWidth), TextAlignment.Left, default, line);
×
406
    }
×
407

408
    /// <summary>
409
    /// This method clears a specified part of the console.
410
    /// </summary>
411
    /// <param name="line">The index of the first line to clear.</param>
412
    /// <param name="length">The number of lines to clear.</param>
413
    /// <remarks>Refer to the example project to understand how to implement it available at https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/Program.cs </remarks>
414
    [Obsolete(
415
        "This method is deprecated, please use the Window class elements instead. will be removed on v3.1.0",
416
        false
417
    )]
418
    public static void ClearMultipleLines(int? line, int? length)
419
    {
420
        line ??= Console.CursorTop;
×
421
        length ??= 1;
×
422
        for (int i = (int)line; i < line + length; i++)
×
423
            ClearLine(i);
×
424
    }
×
425

426
    /// <summary>
427
    /// This method clears the console EXCEPT the header and above, and the footer and below
428
    /// </summary>
429
    /// <remarks>Refer to the example project to understand how to implement it available at https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/Program.cs </remarks>
430
    [Obsolete(
431
        "This method is deprecated, please use the Window class elements instead. will be removed on v3.1.0",
432
        false
433
    )]
434
    public static void ClearContent()
435
    {
436
        for (int i = ContentHeight - 1; i < FooterHeight; i++)
×
437
            ClearLine(i);
×
438
    }
×
439

440
    /// <summary>
441
    /// This method clears the window and resets the color panel to the default one.
442
    /// </summary>
443
    [Obsolete(
444
        "This method is deprecated, please use the Window class elements instead. will be removed on v3.1.0",
445
        false
446
    )]
447
    public static void ClearWindow(bool continuous = true, bool resetColorPanel = true)
448
    {
449
        if (resetColorPanel)
×
450
            s_colorPanel = s_terminalColorPanel;
×
451
        if (continuous)
×
452
        {
453
            for (int i = 0; i < Console.WindowHeight; i++)
×
454
            {
455
                WriteContinuousString("".PadRight(Console.WindowWidth), i, false, 100, 10);
×
456
            }
457
        }
458
        else
459
        {
460
            for (int i = 0; i < Console.WindowHeight; i++)
×
461
            {
462
                WritePositionedString(
×
463
                    "".PadRight(Console.WindowWidth),
×
464
                    TextAlignment.Center,
×
465
                    false,
×
466
                    i
×
467
                );
×
468
            }
469
        }
470
    }
×
471
    #endregion
472

473
    #region Middle abstraction level methods
474
    /// <summary>
475
    /// This method is used to write a string positioned in the console.
476
    /// </summary>
477
    /// <param name="str">The string to write.</param>
478
    /// <param name="align">The position of the string in the console.</param>
479
    /// <param name="negative">If true, the text is highlighted.</param>
480
    /// <param name="line">The line where the string is written in the console. If null, will be written where the cursor is.</param>
481
    /// <param name="writeLine">If true, the string is written with a line break.</param>
482
    /// <remarks>
483
    /// For more information, refer to the following resources:
484
    /// <list type="bullet">
485
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
486
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/Program.cs">Example Project</a></description></item>
487
    /// </list>
488
    /// </remarks>
489
    [Visual]
490
    public static void WritePositionedString(
491
        string str,
492
        TextAlignment align = TextAlignment.Center,
493
        bool negative = false,
494
        int? line = null,
495
        bool writeLine = false
496
    )
497
    {
498
        ApplyNegative(negative);
499
        var negativeRng = str.GetRangeAndRemoveNegativeAnchors();
500
        str = negativeRng.Item1;
501
        line ??= Console.CursorTop;
502
        if (str.Length < Console.WindowWidth)
503
            switch (align)
504
            {
505
                case TextAlignment.Left:
506
                    Console.SetCursorPosition(0, (int)line);
507
                    break;
508
                case TextAlignment.Center:
509
                    Console.SetCursorPosition((Console.WindowWidth - str.Length) / 2, (int)line);
510
                    break;
511
                case TextAlignment.Right:
512
                    Console.SetCursorPosition(Console.WindowWidth - str.Length, (int)line);
513
                    break;
514
            }
515
        else
516
            Console.SetCursorPosition(0, (int)line);
517
        if (writeLine)
518
        {
519
            if (negativeRng.Item2 is not null)
520
            {
521
                Console.Write(str[..negativeRng.Item2.Value.Item1]);
522
                ApplyNegative(true);
523
                Console.Write(str[negativeRng.Item2.Value.Item2..]);
524
                ApplyNegative(default);
525
                Console.WriteLine();
526
            }
527
            else
528
            {
529
                Console.WriteLine(str);
530
            }
531
        }
532
        else
533
        {
534
            if (negativeRng.Item2 is not null)
535
            {
536
                Console.Write(negativeRng.Item1[..negativeRng.Item2.Value.Item1]);
537
                ApplyNegative(true);
538
                Console.Write(
539
                    negativeRng.Item1[negativeRng.Item2.Value.Item1..negativeRng.Item2.Value.Item2]
540
                );
541
                ApplyNegative(default);
542
                Console.Write(negativeRng.Item1[negativeRng.Item2.Value.Item2..]);
543
            }
544
            else
545
            {
546
                Console.Write(str);
547
            }
548
        }
549
        ApplyNegative(default);
550
    }
551

552
    /// <summary>
553
    /// This method is used to write a string continuously in the console.
554
    /// The string is written letter by letter on the console.
555
    /// </summary>
556
    /// <param name="str">The string to write.</param>
557
    /// <param name="line">The line where the string is written in the console. If null, will be written where the cursor is.</param>
558
    /// <param name="negative">If true, the text is highlighted.</param>
559
    /// <param name="printTime">The total time to write the string in ms.</param>
560
    /// <param name="additionalTime">The additional time to wait after the string is written in ms.</param>
561
    /// <param name="length">The length of the string. If null, the length is the window width.</param>
562
    /// <param name="align">The alignment of the string.</param>
563
    /// <param name="writeLine">If true, the string is written with a line break.</param>
564
    /// <remarks>
565
    /// For more information, refer to the following resources:
566
    /// <list type="bullet">
567
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
568
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/Program.cs">Example Project</a></description></item>
569
    /// </list>
570
    /// </remarks>
571
    [Visual]
572
    public static void WriteContinuousString(
573
        string str,
574
        int? line,
575
        bool negative = false,
576
        int printTime = 2000,
577
        int additionalTime = 1000,
578
        int length = -1,
579
        TextAlignment align = TextAlignment.Center,
580
        bool writeLine = false
581
    )
582
    {
583
        line ??= Console.CursorTop;
584
        length = length == -1 ? Console.WindowWidth : length;
585
        int timeInterval = printTime / str.Length;
586
        for (int i = 0; i <= str.Length; i++)
587
        {
588
            StringBuilder continuous = new StringBuilder();
589
            for (int j = 0; j < i; j++)
590
                continuous.Append(str[j]);
591
            string continuousStr = continuous.ToString().PadRight(str.Length);
592
            WritePositionedString(
593
                continuousStr.ResizeString(length, align, default),
594
                align,
595
                negative,
596
                line,
597
                writeLine
598
            );
599
            Thread.Sleep(timeInterval);
600

601
            if (Console.KeyAvailable)
602
            {
603
                ConsoleKeyInfo keyPressed = Console.ReadKey(true);
604
                if (keyPressed.Key == ConsoleKey.Enter || keyPressed.Key == ConsoleKey.Escape)
605
                {
606
                    break;
607
                }
608
            }
609
        }
610
        WritePositionedString(str.ResizeString(length, align, default), align, negative, line);
611
        Thread.Sleep(additionalTime);
612
    }
613

614
    /// <summary>
615
    /// This method is used to write a styled string in the console.
616
    /// </summary>
617
    /// <param name="text">The styled string to write.</param>
618
    /// <param name="line">The line where the string is written in the console. If null, will be written from the ContentHeight.</param>
619
    /// <param name="width">The width of the string. If null, the width is the window width.</param>
620
    /// <param name="margin">The upper and lower margin.</param>
621
    /// <param name="align">The alignment of the string.</param>
622
    /// <param name="negative">If true, the text is highlighted.</param>
623
    /// <remarks>
624
    /// For more information, refer to the following resources:
625
    /// <list type="bullet">
626
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
627
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/Program.cs">Example Project</a></description></item>
628
    /// </list>
629
    /// </remarks>
630
    [Visual]
631
    public static void WritePositionedStyledText(
632
        string[]? text = null,
633
        int? line = null,
634
        int? width = null,
635
        int? margin = null,
636
        TextAlignment align = TextAlignment.Center,
637
        bool negative = false
638
    )
639
    {
640
        line ??= Console.CursorTop;
641
        margin ??= 0;
642
        if (text is not null)
643
        {
644
            Console.SetCursorPosition(0, line ?? Window.GetLineAvailable(align.ToPlacement()));
645

646
            for (int i = 0; i < margin; i++)
647
                WritePositionedString(
648
                    "".ResizeString(width ?? Console.WindowWidth, align),
649
                    align,
650
                    negative,
651
                    (line ?? Window.GetLineAvailable(align.ToPlacement())) + i,
652
                    true
653
                );
654
            for (int i = 0; i < text.Length; i++)
655
                WritePositionedString(
656
                    text[i].ResizeString(width ?? Console.WindowWidth, align),
657
                    align,
658
                    negative,
659
                    (line ?? Window.GetLineAvailable(align.ToPlacement())) + margin + i,
660
                    true
661
                );
662
            for (int i = 0; i < margin; i++)
663
                WritePositionedString(
664
                    "".ResizeString(width ?? Console.WindowWidth, align),
665
                    align,
666
                    negative,
667
                    (line ?? Window.GetLineAvailable(align.ToPlacement()))
668
                        + margin
669
                        + text.Length
670
                        + i,
671
                    true
672
                );
673
        }
674
    }
675

676
    /// <summary>
677
    /// This method prints a paragraph in the console.
678
    /// </summary>
679
    /// <param name="equalizeLengths">Whether or not the lines of the paragraph should be equalized to the same length.</param>
680
    /// <param name="align">The alignment of the paragraph.</param>
681
    /// <param name="negative">If true, the paragraph is printed in the negative colors.</param>
682
    /// <param name="line">The height of the paragraph.</param>
683
    /// <param name="text">The lines of the paragraph.</param>
684
    /// <remarks>
685
    /// For more information, refer to the following resources:
686
    /// <list type="bullet">
687
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
688
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/Program.cs">Example Project</a></description></item>
689
    /// </list>
690
    /// </remarks>
691
    [Visual]
692
    public static void WriteMultiplePositionedLines(
693
        bool equalizeLengths = true,
694
        TextAlignment align = TextAlignment.Center,
695
        bool negative = false,
696
        int? line = null,
697
        params string[] text
698
    )
699
    {
700
        line ??= Console.CursorTop;
701
        if (equalizeLengths)
702
        {
703
            int maxLength = text.Length > 0 ? text.Max(s => s.Length) : 0;
×
704
            foreach (string str in text)
705
            {
706
                WritePositionedString(str.ResizeString(maxLength, align), align, negative, line++);
707
                if (line >= Console.WindowHeight - 1)
708
                    break;
709
            }
710
        }
711
        else
712
        {
713
            foreach (string str in text)
714
            {
715
                WritePositionedString(str, align, negative, line++);
716
                if (line >= Console.WindowHeight - 1)
717
                    break;
718
            }
719
        }
720
    }
721

722
    /// <summary>
723
    /// This method prints the title in the console.
724
    /// </summary>
725
    /// <remarks>Refer to the example project to understand how to implement it available at https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/Program.cs </remarks>
726
    [Obsolete(
727
        "This method is deprecated, please use the Window class elements instead. will be removed on v3.1.0",
728
        false
729
    )]
730
    public static void WriteTitle() =>
731
        WritePositionedStyledText(
×
732
            s_title.Item1,
×
733
            0,
×
734
            Console.WindowWidth,
×
735
            s_title.Item2,
×
736
            TextAlignment.Center,
×
737
            false
×
738
        );
×
739

740
    /// <summary>
741
    /// This method prints a header in the console.
742
    /// </summary>
743
    /// <param name="continuous">If true, the header is not continuously printed.</param>
744
    /// <param name="header">The header to print.</param>
745
    /// <remarks>Refer to the example project to understand how to implement it available at https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/Program.cs </remarks>
746
    [Obsolete(
747
        "This method is deprecated, please use the Window class elements instead. will be removed on v3.1.0",
748
        false
749
    )]
750
    public static void WriteHeader(bool continuous = true, (string, string, string)? header = null)
751
    {
752
        (string, string, string) _banner = header ?? defaultHeader;
×
753
        if (continuous)
×
754
            WriteContinuousString(_banner.BannerToString(), HeaderHeight, true);
×
755
        else
756
            WritePositionedString(_banner.BannerToString(), default, true, HeaderHeight);
×
757
    }
×
758

759
    /// <summary>
760
    /// This method prints a footer in the console.
761
    /// </summary>
762
    /// <param name="continuous">If true, the footer is not continuously printed.</param>
763
    /// <param name="footer">The footer to print.</param>
764
    /// <remarks>Refer to the example project to understand how to implement it available at https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/Program.cs </remarks>
765
    [Obsolete(
766
        "This method is deprecated, please use the Window class elements instead. will be removed on v3.1.0",
767
        false
768
    )]
769
    public static void WriteFooter(bool continuous = true, (string, string, string)? footer = null)
770
    {
771
        (string, string, string) _banner = footer ?? defaultFooter;
×
772
        ApplyNegative(true);
×
773
        if (continuous)
×
774
            WriteContinuousString(_banner.BannerToString(), FooterHeight, true);
×
775
        else
776
            WritePositionedString(_banner.BannerToString(), default, true, FooterHeight);
×
777
    }
×
778

779
    /// <summary>
780
    /// This method prints a message in the console and gets a string written by the user.
781
    /// </summary>
782
    /// <param name="message">The message to print.</param>
783
    /// <param name="defaultValue">The default value of the string.</param>
784
    /// <param name="line">The line where the message will be printed.</param>
785
    /// <param name="continuous">If true, the message is not continuously printed.</param>
786
    /// <returns>A tuple containing the status of the prompt (Output.Exit : pressed escape, Output.Select : pressed enter) and the string written by the user.</returns>
787
    /// <remarks>Refer to the example project to understand how to implement it available at https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/Program.cs </remarks>
788
    [Obsolete(
789
        "This method is deprecated, please use the Window class elements instead. will be removed on v3.1.0",
790
        false
791
    )]
792
    public static (Output, string) WritePrompt(
793
        string message,
794
        string? defaultValue = null,
795
        int? line = null,
796
        bool continuous = true
797
    )
798
    {
799
        line ??= ContentHeight;
×
800
        defaultValue ??= "";
×
801
        if (continuous)
×
802
            WriteContinuousString(message, line, negative: false, 1500, 50);
×
803
        else
804
            WritePositionedString(
×
805
                message,
×
806
                TextAlignment.Center,
×
807
                negative: false,
×
808
                line,
×
809
                writeLine: true
×
810
            );
×
811

812
        var field = new StringBuilder(defaultValue);
×
813
        ConsoleKeyInfo key;
814
        Console.CursorVisible = true;
×
815
        do
816
        {
817
            ClearLine(line + 2);
×
818
            Console.SetCursorPosition(0, Console.CursorTop);
×
819
            Console.Write("{0," + (Console.WindowWidth / 2 - message.Length / 2 + 2) + "}", "> ");
×
820
            Console.Write($"{field}");
×
821
            key = Console.ReadKey();
×
822
            if (key.Key == ConsoleKey.Backspace && field.Length > 0)
×
823
                field.Remove(field.Length - 1, 1);
×
824
            else if (key.Key != ConsoleKey.Enter && key.Key != ConsoleKey.Escape)
×
825
                field.Append(key.KeyChar);
×
826
        } while (key.Key != ConsoleKey.Enter && key.Key != ConsoleKey.Escape);
×
827
        Console.CursorVisible = false;
×
828
        return key.Key == ConsoleKey.Enter
×
829
            ? (Output.Select, field.ToString())
×
830
            : (Output.Exit, field.ToString());
×
831
    }
832

833
    /// <summary>
834
    /// This method prints a menu in the console and gets the choice of the user.
835
    /// </summary>
836
    /// <param name="question">The question to print.</param>
837
    /// <param name="defaultIndex">The default index of the menu.</param>
838
    /// <param name="placement">The placement of the menu.</param>
839
    /// <param name="line">The line where the menu is printed.</param>
840
    /// <param name="choices">The choices of the menu.</param>
841
    /// <returns>A tuple containing the status of the prompt (Output.Exit : pressed escape, Output.Delete : pressed backspace, Output.Select : pressed enter) and the index of the choice of the user.</returns>
842
    [Obsolete(
843
        "This method is deprecated, please use the Window class elements instead. will be removed on v3.1.0",
844
        false
845
    )]
846
    public static (Output, int) ScrollingMenuSelector(
847
        string question,
848
        int defaultIndex = 0,
849
        Placement placement = Placement.TopCenter,
850
        int? line = null,
851
        params string[] choices
852
    )
853
    {
854
        line ??= ContentHeight;
×
855
        line = Math.Clamp(line.Value, ContentHeight, FooterHeight - choices.Length - 2);
×
856
        defaultIndex = Math.Clamp(defaultIndex, 0, choices.Length - 1);
×
857
        EqualizeChoicesLength(choices);
×
858

859
        WriteContinuousString(question, line, false, 1500, 50);
×
860
        int lineChoice = line.Value + 2;
×
861
        bool delay = true;
×
862
        while (true)
863
        {
864
            DisplayChoices(defaultIndex, choices, lineChoice, delay);
×
865
            delay = false;
×
866
            switch (Console.ReadKey(intercept: true).Key)
×
867
            {
868
                case ConsoleKey.UpArrow:
869
                case ConsoleKey.Z:
870
                    defaultIndex = (defaultIndex == 0) ? choices.Length - 1 : defaultIndex - 1;
×
871
                    break;
×
872
                case ConsoleKey.DownArrow:
873
                case ConsoleKey.S:
874
                    defaultIndex = (defaultIndex == choices.Length - 1) ? 0 : defaultIndex + 1;
×
875
                    break;
×
876
                case ConsoleKey.Enter:
877
                    ClearMultipleLines(line, choices.Length + 2);
×
878
                    return (Output.Select, defaultIndex);
×
879
                case ConsoleKey.Escape:
880
                    ClearMultipleLines(line, choices.Length + 2);
×
881
                    return (Output.Exit, defaultIndex);
×
882
                case ConsoleKey.Backspace:
883
                    ClearMultipleLines(line, choices.Length + 2);
×
884
                    return (Output.Delete, defaultIndex);
×
885
            }
886
        }
887

888
        static void EqualizeChoicesLength(string[] choices)
889
        {
890
            int totalWidth = (choices.Length != 0) ? choices.Max((string s) => s.Length) : 0;
×
891
            for (int i = 0; i < choices.Length; i++)
×
892
            {
893
                choices[i] = choices[i].PadRight(totalWidth);
×
894
            }
895
        }
×
896

897
        static void DisplayChoices(
898
            int defaultIndex,
899
            string[] choices,
900
            int lineChoice,
901
            bool delay = false
902
        )
903
        {
904
            string[] array = new string[choices.Length];
×
905
            for (int i = 0; i < choices.Length; i++)
×
906
            {
907
                array[i] =
×
908
                    (i == defaultIndex)
×
909
                        ? $" {s_Selector.Item1} {choices[i]}  "
×
910
                        : $"   {choices[i]}  ";
×
911
                WritePositionedString(
×
912
                    array[i],
×
913
                    TextAlignment.Center,
×
914
                    i == defaultIndex,
×
915
                    lineChoice + i
×
916
                );
×
917
                if (delay)
×
918
                    Thread.Sleep(30);
×
919
            }
920
        }
×
921
    }
922

923
    /// <summary>
924
    /// This method prints a menu in the console and gets the choice of the user.
925
    /// </summary>
926
    /// <param name="question">The question to print.</param>
927
    /// <param name="min">The minimum value of the number.</param>
928
    /// <param name="max">The maximum value of the number.</param>
929
    /// <param name="start">The starting value of the number.</param>
930
    /// <param name="step">The step of the number.</param>
931
    /// <param name="line">The line where the menu is printed.</param>
932
    /// <param name="roundedCorners">If true, the corners of the menu are rounded.</param>
933
    /// <returns>A tuple containing the status of the prompt (Output.Exit : pressed escape, Output.Delete : pressed backspace, Output.Select : pressed enter) and the number chosen by the user.</returns>
934
    /// <remarks>Refer to the example project to understand how to implement it available at https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/Program.cs </remarks>
935
    [Obsolete(
936
        "This method is deprecated, please use the Window class elements instead. will be removed on v3.1.0",
937
        false
938
    )]
939
    public static (Output, float) ScrollingNumberSelector(
940
        string question,
941
        float min,
942
        float max,
943
        float start = 0,
944
        float step = 100,
945
        int? line = null,
946
        bool roundedCorners = false
947
    )
948
    {
949
        line ??= ContentHeight;
×
950
        string corners = roundedCorners ? "╭╮╰╯" : "┌┐└┘";
×
951
        WriteContinuousString(question, line, default, 1500, 50);
×
952
        float currentNumber = start;
×
953
        int lineSelector = (int)line + 4;
×
954
        while (true)
×
955
        {
956
            WritePositionedString(
×
957
                BuildLine(Direction.Up),
×
958
                TextAlignment.Center,
×
959
                false,
×
960
                lineSelector - 2
×
961
            );
×
962
            WritePositionedString(
×
963
                BuildNumber((float)Math.Round(NextNumber(Direction.Up), 1)),
×
964
                TextAlignment.Center,
×
965
                false,
×
966
                lineSelector - 1
×
967
            );
×
968
            WritePositionedString(
×
969
                $" {s_Selector.Item1} {BuildNumber((float)Math.Round(currentNumber, 1))} {s_Selector.Item2} ",
×
970
                TextAlignment.Center,
×
971
                true,
×
972
                lineSelector
×
973
            );
×
974
            WritePositionedString(
×
975
                BuildNumber((float)Math.Round(NextNumber(Direction.Down), 1)),
×
976
                TextAlignment.Center,
×
977
                false,
×
978
                lineSelector + 1
×
979
            );
×
980
            WritePositionedString(
×
981
                BuildLine(Direction.Down),
×
982
                TextAlignment.Center,
×
983
                false,
×
984
                lineSelector + 2
×
985
            );
×
986

987
            switch (Console.ReadKey(true).Key)
×
988
            {
989
                case ConsoleKey.UpArrow:
990
                case ConsoleKey.Z:
991
                    currentNumber = NextNumber(Direction.Up);
×
992
                    break;
×
993
                case ConsoleKey.DownArrow:
994
                case ConsoleKey.S:
995
                    currentNumber = NextNumber(Direction.Down);
×
996
                    break;
×
997
                case ConsoleKey.Enter:
998
                    ClearMultipleLines(line, 4);
×
999
                    return (Output.Select, currentNumber);
×
1000
                case ConsoleKey.Escape:
1001
                    ClearMultipleLines(line, 4);
×
1002
                    return (Output.Exit, currentNumber);
×
1003
                case ConsoleKey.Backspace:
1004
                    ClearMultipleLines(line, 4);
×
1005
                    return (Output.Delete, currentNumber);
×
1006
            }
1007
            Thread.Sleep(1);
×
1008
            ClearMultipleLines(lineSelector - 2, 5);
×
1009
        }
1010
        float NextNumber(Direction direction)
1011
        {
1012
            if (direction == Direction.Up)
×
1013
            {
1014
                if (currentNumber + step <= max)
×
1015
                    return currentNumber + step;
×
1016
                else if (currentNumber + step > max)
×
1017
                    return min;
×
1018
            }
1019
            else
1020
            {
1021
                if (currentNumber - step >= min)
×
1022
                    return currentNumber - step;
×
1023
                else if (currentNumber - step < min)
×
1024
                    return max;
×
1025
            }
1026
            return currentNumber;
×
1027
        }
1028
        string BuildLine(Direction direction)
1029
        {
1030
            StringBuilder line = new();
×
1031
            for (int i = 0; i < max.ToString().Length + 2; i++)
×
1032
                line.Append('─');
×
1033
            if (direction == Direction.Up)
×
1034
                line.Insert(0, corners[0].ToString(), 1).Append(corners[1], 1);
×
1035
            else
1036
                line.Insert(0, corners[2].ToString(), 1).Append(corners[3], 1);
×
1037
            return line.ToString();
×
1038
        }
1039
        string BuildNumber(float number)
1040
        {
1041
            StringBuilder numberStr = new();
×
1042
            numberStr.Append("│ ");
×
1043
            numberStr.Append(
×
1044
                number.ToString().ResizeString(max.ToString().Length, TextAlignment.Center)
×
1045
            );
×
1046
            numberStr.Append(" │");
×
1047
            return numberStr.ToString();
×
1048
        }
1049
    }
1050

1051
    /// <summary>
1052
    /// This method prints a loading screen in the console.
1053
    /// </summary>
1054
    /// <param name="message">The message to print.</param>
1055
    /// <param name="line">The line where the message will be printed.</param>
1056
    /// <remarks>Refer to the example project to understand how to implement it available at https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/Program.cs </remarks>
1057
    [Obsolete(
1058
        "This method is deprecated, please use the Window class elements instead. will be removed on v3.1.0",
1059
        false
1060
    )]
1061
    public static void LoadingBar(string message = "[ Loading... ]", int? line = null)
1062
    {
1063
        line ??= ContentHeight;
×
1064
        WritePositionedString(
×
1065
            message.ResizeString(Console.WindowWidth, TextAlignment.Center),
×
1066
            default,
×
1067
            default,
×
1068
            line,
×
1069
            true
×
1070
        );
×
1071
        StringBuilder loadingBar = new();
×
1072
        for (int j = 0; j < message.Length; j++)
×
1073
            loadingBar.Append('█');
×
1074
        WriteContinuousString(loadingBar.ToString(), ContentHeight + 2);
×
1075
    }
×
1076
    #endregion
1077

1078
    #region High abstraction level methods
1079
    /// <summary>
1080
    /// This method prints a loading bar in the console linked with a process percentage so that the loading bar is updated.
1081
    /// </summary>
1082
    /// <param name="message">The message to print.</param>
1083
    /// <param name="processPercentage">The percentage of the process.</param>
1084
    /// <param name="line">The line where the message will be printed.</param>
1085
    [Obsolete(
1086
        "This method is deprecated, please use the Window class elements instead. will be removed on v3.1.0",
1087
        false
1088
    )]
1089
    public static void ProcessLoadingBar(
1090
        string message,
1091
        ref float processPercentage,
1092
        int? line = null
1093
    )
1094
    {
1095
        static void BuildBar(string message, float processPercentage, int? line)
1096
        {
1097
            StringBuilder _loadingBar = new();
×
1098
            for (int j = 0; j <= (int)(message.Length * processPercentage); j++)
×
1099
            {
1100
                _loadingBar.Append('█');
×
1101
            }
1102
            WritePositionedString(
×
1103
                _loadingBar.ToString().ResizeString(message.Length, TextAlignment.Left),
×
1104
                TextAlignment.Center,
×
1105
                default,
×
1106
                line + 2,
×
1107
                default
×
1108
            );
×
1109
        }
×
1110

1111
        line ??= ContentHeight;
×
1112
        WritePositionedString(message, TextAlignment.Center, default, line, true);
×
1113
        while (processPercentage <= 1f)
×
1114
        {
1115
            BuildBar(message, processPercentage, line);
×
1116
        }
1117
        BuildBar(message, 1, line);
×
1118
        Thread.Sleep(3000);
×
1119
        processPercentage = 0f;
×
1120
    }
×
1121

1122
    /// <summary>
1123
    /// This method prints a full screen in the console with a title, a header and a footer.
1124
    /// </summary>
1125
    /// <param name="title">The title of the screen.</param>
1126
    /// <param name="continuous">If true, the title is not continuously printed.</param>
1127
    /// <param name="header">The header of the screen.</param>
1128
    /// <param name="footer">The footer of the screen.</param>
1129
    [Obsolete(
1130
        "This method is deprecated, please use the Window class elements instead. will be removed on v3.1.0",
1131
        false
1132
    )]
1133
    public static void WriteFullScreen(
1134
        string? title = null,
1135
        bool continuous = false,
1136
        (string, string, string)? header = null,
1137
        (string, string, string)? footer = null
1138
    )
1139
    {
1140
        header ??= defaultHeader;
×
1141
        footer ??= defaultFooter;
×
1142
        Console.CursorVisible = false;
×
1143
        Console.Clear();
×
1144
        if (title is not null)
×
1145
        {
1146
            SetTitle(title);
×
1147
            WriteTitle();
×
1148
        }
1149
        else if (s_title.Item1 is not null)
×
1150
            WriteTitle();
×
1151
        WriteHeader(continuous, header);
×
1152
        WriteFooter(continuous, footer);
×
1153
        ClearContent();
×
1154
    }
×
1155

1156
    /// <summary>
1157
    /// This method exits the program.
1158
    /// </summary>
1159
    /// <param name="message">The message to print on the exit of the program.</param>
1160
    /// <remarks>Refer to the example project to understand how to implement it available at https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/Program.cs </remarks>
1161
    [Obsolete(
1162
        "This method is deprecated, please use the Window class elements instead. will be removed on v3.1.0",
1163
        false
1164
    )]
1165
    public static void ExitProgram(string message = "[ Exiting the program... ]")
1166
    {
1167
        ClearContent();
×
1168
        LoadingBar(message);
×
1169
        ClearWindow();
×
1170
        Console.CursorVisible = true;
×
1171
        Environment.Exit(0);
×
1172
    }
×
1173
    #endregion
1174

1175
    #region Extensions
1176
    /// <summary>
1177
    /// This method builds a string with a specific size and a specific placement.
1178
    /// </summary>
1179
    /// <param name="str">The string to build.</param>
1180
    /// <param name="size">The size of the string.</param>
1181
    /// <param name="align">The alignment of the string.</param>
1182
    /// <param name="truncate">If true, the string is truncated if it is too long.</param>
1183
    /// <returns>The built string.</returns>
1184
    /// <remarks>
1185
    /// For more information, refer to the following resources:
1186
    /// <list type="bullet">
1187
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
1188
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/Program.cs">Example Project</a></description></item>
1189
    /// </list>
1190
    /// </remarks>
1191
    public static string ResizeString(
1192
        this string str,
1193
        int size,
1194
        TextAlignment align = TextAlignment.Center,
1195
        bool truncate = true
1196
    )
1197
    {
1198
        int padding = size - str.Length;
9✔
1199
        if (truncate && padding < 0)
9!
1200
            switch (align)
1201
            {
1202
                case TextAlignment.Left:
1203
                    return str.Substring(0, size);
×
1204
                case TextAlignment.Center:
1205
                    return str.Substring((-padding) / 2, size);
×
1206
                case TextAlignment.Right:
1207
                    return str.Substring(-padding, size);
×
1208
            }
1209
        else
1210
            switch (align)
1211
            {
1212
                case TextAlignment.Left:
1213
                    return str.PadRight(size);
3✔
1214
                case TextAlignment.Center:
1215
                    return str.PadLeft(padding / 2 + padding % 2 + str.Length)
3✔
1216
                        .PadRight(padding + str.Length);
3✔
1217
                case TextAlignment.Right:
1218
                    return str.PadLeft(size);
3✔
1219
            }
1220
        return str;
×
1221
    }
1222

1223
    /// <summary>
1224
    /// Insert a specified string into another string, at a specified position.
1225
    /// </summary>
1226
    /// <param name="inserted">The string that receives the other.</param>
1227
    /// <param name="toInsert">The string to insert.</param>
1228
    /// <param name="position">The placement of the string to insert.</param>
1229
    /// <param name="truncate">Whether or not the string is truncate.</param>
1230
    /// <returns>The final string after computing.</returns>
1231
    /// <remarks>
1232
    /// For more information, refer to the following resources:
1233
    /// <list type="bullet">
1234
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
1235
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/Program.cs">Example Project</a></description></item>
1236
    /// </list>
1237
    /// </remarks>
1238
    public static string InsertString(
1239
        this string inserted,
1240
        string toInsert,
1241
        Placement position = Placement.TopCenter,
1242
        bool truncate = true
1243
    )
1244
    {
1245
        if (inserted.Length < toInsert.Length)
18!
1246
        {
1247
            throw new ArgumentException(
×
1248
                "The string to insert is longer than the string to insert into"
×
1249
            );
×
1250
        }
1251
        switch (position)
1252
        {
1253
            case Placement.TopCenter:
1254
            case Placement.BottomCenterFullWidth:
1255
            case Placement.TopCenterFullWidth:
1256
                int center = inserted.Length / 2;
6✔
1257
                int start = center - (toInsert.Length / 2);
6✔
1258
                if (truncate)
6!
1259
                {
1260
                    return inserted.Remove(start, toInsert.Length).Insert(start, toInsert);
6✔
1261
                }
1262
                else
1263
                {
1264
                    return inserted.Insert(start, toInsert);
×
1265
                }
1266
            case Placement.TopLeft:
1267
                if (truncate)
6!
1268
                {
1269
                    return inserted.Remove(0, toInsert.Length).Insert(0, toInsert);
6✔
1270
                }
1271
                else
1272
                {
1273
                    return inserted.Insert(0, toInsert);
×
1274
                }
1275
            case Placement.TopRight:
1276
                if (truncate)
6!
1277
                {
1278
                    return inserted
6✔
1279
                        .Remove(inserted.Length - toInsert.Length, toInsert.Length)
6✔
1280
                        .Insert(inserted.Length - toInsert.Length, toInsert);
6✔
1281
                }
1282
                else
1283
                {
1284
                    return inserted.Insert(inserted.Length - toInsert.Length, toInsert);
×
1285
                }
1286
            default:
1287
                throw new ArgumentException("The placement is not valid");
×
1288
        }
1289
    }
1290

1291
    /// <summary>
1292
    /// This method is used to convert the banner tuple into a string.
1293
    /// </summary>
1294
    /// <param name="banner">The banner tuple.</param>
1295
    /// <returns>Converts the banner to a string.</returns>
1296
    /// <remarks>
1297
    /// For more information, refer to the following resources:
1298
    /// <list type="bullet">
1299
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
1300
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/Program.cs">Example Project</a></description></item>
1301
    /// </list>
1302
    /// </remarks>
1303
    [Visual]
1304
    public static string BannerToString(this (string, string, string) banner) =>
1305
        " "
1306
        + banner.Item1
1307
        + banner.Item2.ResizeString(
1308
            Console.WindowWidth - 2 - banner.Item1.Length - banner.Item3.Length,
1309
            TextAlignment.Center,
1310
            true
1311
        )
1312
        + banner.Item3
1313
        + " ";
1314

1315
    /// <summary>
1316
    /// This method is used to get the range of a negative sequence in a string and remove the negative anchors.
1317
    /// </summary>
1318
    /// <param name="str">The string to check.</param>
1319
    /// <returns>The string without the negative anchors and the range of the negative sequence.</returns>
1320
    /// <remarks>
1321
    /// For more information, refer to the following resources:
1322
    /// <list type="bullet">
1323
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
1324
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/Program.cs">Example Project</a></description></item>
1325
    /// </list>
1326
    /// </remarks>
1327
    public static (string, (int, int)?) GetRangeAndRemoveNegativeAnchors(this string str)
1328
    {
1329
        int negStart = str.IndexOf(NEGATIVE_ANCHOR);
6✔
1330
        int negEnd = str.IndexOf(NEGATIVE_ANCHOR, negStart + 1);
6✔
1331
        if (negStart == -1 || negEnd == -1)
6!
1332
            return (str, null);
×
1333

1334
        negEnd -= NEGATIVE_ANCHOR.Length;
6✔
1335
        string newStr = str.Replace(NEGATIVE_ANCHOR, "");
6✔
1336
        return (newStr, (negStart, negEnd));
6✔
1337
    }
1338

1339
    /// <summary>
1340
    /// This method is used to convert a Placement into a TextAlignment.
1341
    /// </summary>
1342
    /// <param name="placement">The placement to convert.</param>
1343
    /// <returns>The converted placement.</returns>
1344
    /// <exception cref="ArgumentException">Thrown when the placement is not valid.</exception>
1345
    /// <remarks>
1346
    /// For more information, refer to the following resources:
1347
    /// <list type="bullet">
1348
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
1349
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/Program.cs">Example Project</a></description></item>
1350
    /// </list>
1351
    /// </remarks>
1352
    public static TextAlignment ToTextAlignment(this Placement placement)
1353
    {
1354
        return placement switch
18✔
1355
        {
18✔
1356
            Placement.TopCenter => TextAlignment.Center,
3✔
1357
            Placement.TopLeft => TextAlignment.Left,
3✔
1358
            Placement.TopRight => TextAlignment.Right,
3✔
1359
            Placement.BottomCenterFullWidth => TextAlignment.Center,
3✔
1360
            Placement.TopCenterFullWidth => TextAlignment.Center,
3✔
1361
            _ => throw new ArgumentException("The placement is not valid"),
3✔
1362
        };
18✔
1363
    }
1364

1365
    /// <summary>
1366
    /// This method is used to convert a TextAlignment into a Placement.
1367
    /// </summary>
1368
    /// <param name="align">The alignment to convert.</param>
1369
    /// <returns>The converted alignment.</returns>
1370
    /// <exception cref="ArgumentException">Thrown when the alignment is not valid.</exception>
1371
    /// <remarks>
1372
    /// For more information, refer to the following resources:
1373
    /// <list type="bullet">
1374
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
1375
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/Program.cs">Example Project</a></description></item>
1376
    /// </list>
1377
    /// </remarks>
1378
    public static Placement ToPlacement(this TextAlignment align)
1379
    {
1380
        return align switch
12✔
1381
        {
12✔
1382
            TextAlignment.Center => Placement.TopCenter,
3✔
1383
            TextAlignment.Left => Placement.TopLeft,
3✔
1384
            TextAlignment.Right => Placement.TopRight,
3✔
1385
            _ => throw new ArgumentException("The alignment is not valid"),
3✔
1386
        };
12✔
1387
    }
1388
    #endregion
1389
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc