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

MorganKryze / ConsoleAppVisuals / 8280803682

14 Mar 2024 12:36PM UTC coverage: 95.189% (-0.06%) from 95.25%
8280803682

push

github

MorganKryze
✅ rename file to coverage

987 of 1120 branches covered (88.13%)

Branch coverage included in aggregate %.

1981 of 1998 relevant lines covered (99.15%)

720.55 hits per line

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

97.32
/src/ConsoleAppVisuals/Core.cs
1
/*
2
    GNU GPL License 2024 MorganKryze(Yann Vidamment)
3
    For full license information, please visit: https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/LICENSE
4
*/
5
namespace ConsoleAppVisuals;
6

7
/// <summary>
8
/// The <see cref="Core"/> class contains all the interactions between the application and the console.
9
/// </summary>
10
public static class Core
11
{
12
    #region Constants
13
    /// <summary>
14
    /// This constant is used to define the negative anchor to put inside a string to be recognized as negative.
15
    /// </summary>
16
    public const string NEGATIVE_ANCHOR = "/neg";
17
    #endregion
18

19
    #region Fields
20
    [Visual]
21
    private static int s_previousWindowWidth = Console.WindowWidth;
3✔
22

23
    [Visual]
24
    private static int s_previousWindowHeight = Console.WindowHeight;
3✔
25
    private static (ConsoleColor, ConsoleColor) s_colorPanel = (
3✔
26
        ConsoleColor.White,
3✔
27
        ConsoleColor.Black
3✔
28
    );
3✔
29
    private static (ConsoleColor, ConsoleColor) s_initialColorPanel = (
3✔
30
        s_colorPanel.Item1,
3✔
31
        s_colorPanel.Item2
3✔
32
    );
3✔
33

34
    [Visual]
35
    private static (ConsoleColor, ConsoleColor) s_terminalColorPanel = (
3✔
36
        Console.ForegroundColor,
3✔
37
        Console.BackgroundColor
3✔
38
    );
3✔
39
    private static (ConsoleColor, ConsoleColor) s_savedColorPanel;
40

41
    private static readonly Random s_rnd = new();
3✔
42
    #endregion
43

44
    #region Properties
45
    /// <summary>
46
    /// This property is used to get the colors of the console.
47
    /// </summary>
48
    public static (ConsoleColor, ConsoleColor) GetColorPanel => s_colorPanel;
9✔
49

50
    /// <summary>
51
    /// This property is used to get the initial colors of the console.
52
    /// </summary>
53
    public static (ConsoleColor, ConsoleColor) GetInitialColorPanel => s_initialColorPanel;
3✔
54
    #endregion
55

56
    #region Low abstraction level methods
57
    /// <summary>
58
    /// This method is used to check if the screen has been updated.
59
    /// </summary>
60
    /// <returns>True if the screen has been updated, false otherwise.</returns>
61
    /// <remarks>
62
    /// For more information, refer to the following resources:
63
    /// <list type="bullet">
64
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
65
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
66
    /// </list>
67
    /// </remarks>
68
    [Visual]
69
    public static bool IsScreenUpdated()
70
    {
71
        var isUpdated =
72
            Console.WindowWidth != s_previousWindowWidth
73
            || Console.WindowHeight != s_previousWindowHeight
74
            || s_colorPanel != s_initialColorPanel;
75
        if (isUpdated)
76
        {
77
            SetConsoleDimensions();
78
        }
79
        return isUpdated;
80
    }
81

82
    /// <summary>
83
    /// This method changes the font color of the console.
84
    /// </summary>
85
    /// <param name="color">The new font color.</param>
86
    /// <remarks>
87
    /// For more information, refer to the following resources:
88
    /// <list type="bullet">
89
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
90
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
91
    /// </list>
92
    /// </remarks>
93
    [Visual]
94
    public static void SetForegroundColor(ConsoleColor color)
95
    {
96
        s_colorPanel.Item1 = color;
97
        Console.ForegroundColor = color;
98
    }
99

100
    /// <summary>
101
    /// This method changes the background color of the console.
102
    /// </summary>
103
    /// <param name="color">The new background color.</param>
104
    /// <remarks>
105
    /// For more information, refer to the following resources:
106
    /// <list type="bullet">
107
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
108
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
109
    /// </list>
110
    /// </remarks>
111
    [Visual]
112
    public static void SetBackgroundColor(ConsoleColor color)
113
    {
114
        s_colorPanel.Item2 = color;
115
        Console.BackgroundColor = color;
116
    }
117

118
    /// <summary>
119
    /// This method is used to save the current color panel.
120
    /// </summary>
121
    /// <remarks>
122
    /// For more information, refer to the following resources:
123
    /// <list type="bullet">
124
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
125
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
126
    /// </list>
127
    /// </remarks>
128
    [Visual]
129
    public static void SaveColorPanel() => s_savedColorPanel = s_colorPanel;
130

131
    /// <summary>
132
    /// This method is used to load the saved color panel.
133
    /// </summary>
134
    /// <remarks>
135
    /// For more information, refer to the following resources:
136
    /// <list type="bullet">
137
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
138
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
139
    /// </list>
140
    /// </remarks>
141
    [Visual]
142
    public static void LoadSavedColorPanel() => s_colorPanel = s_savedColorPanel;
143

144
    /// <summary>
145
    /// This method is used to load the terminal color panel.
146
    /// </summary>
147
    /// <remarks>
148
    /// For more information, refer to the following resources:
149
    /// <list type="bullet">
150
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
151
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
152
    /// </list>
153
    /// </remarks>
154
    [Visual]
155
    public static void LoadTerminalColorPanel() => s_colorPanel = s_terminalColorPanel;
156

157
    /// <summary>
158
    /// 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.
159
    /// </summary>
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/">Example Project</a></description></item>
165
    /// </list>
166
    /// </remarks>
167
    [Visual]
168
    public static void SetConsoleDimensions()
169
    {
170
        s_previousWindowWidth = Console.WindowWidth;
171
        s_previousWindowHeight = Console.WindowHeight;
172
    }
173

174
    /// <summary>
175
    /// This methods is used to get a random color from a selection.
176
    /// </summary>
177
    /// <returns>A random color.</returns>
178
    /// <remarks>
179
    /// For more information, refer to the following resources:
180
    /// <list type="bullet">
181
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
182
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
183
    /// </list>
184
    /// </remarks>
185
    public static ConsoleColor GetRandomColor()
186
    {
187
        var colors = new List<ConsoleColor>
3✔
188
        {
3✔
189
            ConsoleColor.Red,
3✔
190
            ConsoleColor.Green,
3✔
191
            ConsoleColor.Blue,
3✔
192
            ConsoleColor.Yellow,
3✔
193
            ConsoleColor.Magenta,
3✔
194
            ConsoleColor.Cyan
3✔
195
        };
3✔
196
        return colors[s_rnd.Next(colors.Count)];
3✔
197
    }
198

199
    /// <summary>
200
    /// This method is used to restore the default colors of the console.
201
    /// </summary>
202
    /// <remarks>
203
    /// For more information, refer to the following resources:
204
    /// <list type="bullet">
205
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
206
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
207
    /// </list>
208
    /// </remarks>
209
    [Visual]
210
    public static void RestoreColorPanel()
211
    {
212
        Console.ForegroundColor = s_initialColorPanel.Item1;
213
        Console.BackgroundColor = s_initialColorPanel.Item2;
214
        s_colorPanel = s_initialColorPanel;
215
    }
216

217
    /// <summary>
218
    /// This method changes the font and background colors of the console in order to apply
219
    /// a negative to highlight the text or not.
220
    /// </summary>
221
    /// <param name="negative">If true, the text is highlighted.</param>
222
    /// <remarks>
223
    /// For more information, refer to the following resources:
224
    /// <list type="bullet">
225
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
226
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
227
    /// </list>
228
    /// </remarks>
229
    [Visual]
230
    public static void ApplyNegative(bool negative = false)
231
    {
232
        Console.ForegroundColor = negative ? s_colorPanel.Item2 : s_colorPanel.Item1;
233
        Console.BackgroundColor = negative ? s_colorPanel.Item1 : s_colorPanel.Item2;
234
    }
235

236
    #endregion
237

238
    #region Middle abstraction level methods
239
    /// <summary>
240
    /// This method is used to write a string positioned in the console.
241
    /// </summary>
242
    /// <param name="str">The string to write.</param>
243
    /// <param name="align">The position of the string in the console.</param>
244
    /// <param name="negative">If true, the text is highlighted.</param>
245
    /// <param name="line">The line where the string is written in the console. If null, will be written where the cursor is.</param>
246
    /// <param name="writeLine">If true, the string is written with a line break.</param>
247
    /// <remarks>
248
    /// For more information, refer to the following resources:
249
    /// <list type="bullet">
250
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
251
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
252
    /// </list>
253
    /// </remarks>
254
    [Visual]
255
    public static void WritePositionedString(
256
        string str,
257
        TextAlignment align = TextAlignment.Center,
258
        bool negative = false,
259
        int? line = null,
260
        bool writeLine = false
261
    )
262
    {
263
        ApplyNegative(negative);
264
        var negativeRng = str.GetRangeAndRemoveNegativeAnchors();
265
        str = negativeRng.Item1;
266
        line ??= Console.CursorTop;
267
        if (str.Length < Console.WindowWidth)
268
            switch (align)
269
            {
270
                case TextAlignment.Left:
271
                    Console.SetCursorPosition(0, (int)line);
272
                    break;
273
                case TextAlignment.Center:
274
                    Console.SetCursorPosition((Console.WindowWidth - str.Length) / 2, (int)line);
275
                    break;
276
                case TextAlignment.Right:
277
                    Console.SetCursorPosition(Console.WindowWidth - str.Length, (int)line);
278
                    break;
279
            }
280
        else
281
            Console.SetCursorPosition(0, (int)line);
282
        if (writeLine)
283
        {
284
            if (negativeRng.Item2 is not null)
285
            {
286
                Console.Write(str[..negativeRng.Item2.Value.Item1]);
287
                ApplyNegative(true);
288
                Console.Write(str[negativeRng.Item2.Value.Item2..]);
289
                ApplyNegative(default);
290
                Console.WriteLine();
291
            }
292
            else
293
            {
294
                Console.WriteLine(str);
295
            }
296
        }
297
        else
298
        {
299
            if (negativeRng.Item2 is not null)
300
            {
301
                Console.Write(negativeRng.Item1[..negativeRng.Item2.Value.Item1]);
302
                ApplyNegative(true);
303
                Console.Write(
304
                    negativeRng.Item1[negativeRng.Item2.Value.Item1..negativeRng.Item2.Value.Item2]
305
                );
306
                ApplyNegative(default);
307
                Console.Write(negativeRng.Item1[negativeRng.Item2.Value.Item2..]);
308
            }
309
            else
310
            {
311
                Console.Write(str);
312
            }
313
        }
314
        ApplyNegative(default);
315
    }
316

317
    /// <summary>
318
    /// This method is used to write a string continuously in the console.
319
    /// The string is written letter by letter on the console.
320
    /// </summary>
321
    /// <param name="str">The string to write.</param>
322
    /// <param name="line">The line where the string is written in the console. If null, will be written where the cursor is.</param>
323
    /// <param name="negative">If true, the text is highlighted.</param>
324
    /// <param name="printTime">The total time to write the string in ms.</param>
325
    /// <param name="additionalTime">The additional time to wait after the string is written in ms.</param>
326
    /// <param name="length">The length of the string. If null, the length is the window width.</param>
327
    /// <param name="align">The alignment of the string.</param>
328
    /// <param name="writeLine">If true, the string is written with a line break.</param>
329
    /// <remarks>
330
    /// For more information, refer to the following resources:
331
    /// <list type="bullet">
332
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
333
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
334
    /// </list>
335
    /// </remarks>
336
    [Visual]
337
    public static void WriteContinuousString(
338
        string str,
339
        int? line,
340
        bool negative = false,
341
        int printTime = 2000,
342
        int additionalTime = 1000,
343
        int length = -1,
344
        TextAlignment align = TextAlignment.Center,
345
        bool writeLine = false
346
    )
347
    {
348
        line ??= Console.CursorTop;
349
        length = length == -1 ? Console.WindowWidth : length;
350
        int timeInterval = printTime / str.Length;
351
        for (int i = 0; i <= str.Length; i++)
352
        {
353
            StringBuilder continuous = new StringBuilder();
354
            for (int j = 0; j < i; j++)
355
                continuous.Append(str[j]);
356
            string continuousStr = continuous.ToString().PadRight(str.Length);
357
            WritePositionedString(
358
                continuousStr.ResizeString(length, align, default),
359
                align,
360
                negative,
361
                line,
362
                writeLine
363
            );
364
            Thread.Sleep(timeInterval);
365

366
            if (Console.KeyAvailable)
367
            {
368
                ConsoleKeyInfo keyPressed = Console.ReadKey(true);
369
                if (keyPressed.Key == ConsoleKey.Enter || keyPressed.Key == ConsoleKey.Escape)
370
                {
371
                    break;
372
                }
373
            }
374
        }
375
        WritePositionedString(str.ResizeString(length, align, default), align, negative, line);
376
        Thread.Sleep(additionalTime);
377
    }
378

379
    /// <summary>
380
    /// This method is used to write a styled string in the console.
381
    /// </summary>
382
    /// <param name="text">The styled string to write.</param>
383
    /// <param name="line">The line where the string is written in the console. If null, will be written from the ContentHeight.</param>
384
    /// <param name="width">The width of the string. If null, the width is the window width.</param>
385
    /// <param name="margin">The upper and lower margin.</param>
386
    /// <param name="align">The alignment of the string.</param>
387
    /// <param name="negative">If true, the text is highlighted.</param>
388
    /// <remarks>
389
    /// For more information, refer to the following resources:
390
    /// <list type="bullet">
391
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
392
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
393
    /// </list>
394
    /// </remarks>
395
    [Visual]
396
    public static void WritePositionedStyledText(
397
        string[]? text = null,
398
        int? line = null,
399
        int? width = null,
400
        int? margin = null,
401
        TextAlignment align = TextAlignment.Center,
402
        bool negative = false
403
    )
404
    {
405
        line ??= Console.CursorTop;
406
        margin ??= 0;
407
        if (text is not null)
408
        {
409
            Console.SetCursorPosition(0, line ?? Window.GetLineAvailable(align.ToPlacement()));
410

411
            for (int i = 0; i < margin; i++)
412
                WritePositionedString(
413
                    "".ResizeString(width ?? Console.WindowWidth, align),
414
                    align,
415
                    negative,
416
                    (line ?? Window.GetLineAvailable(align.ToPlacement())) + i,
417
                    true
418
                );
419
            for (int i = 0; i < text.Length; i++)
420
                WritePositionedString(
421
                    text[i].ResizeString(width ?? Console.WindowWidth, align),
422
                    align,
423
                    negative,
424
                    (line ?? Window.GetLineAvailable(align.ToPlacement())) + margin + i,
425
                    true
426
                );
427
            for (int i = 0; i < margin; i++)
428
                WritePositionedString(
429
                    "".ResizeString(width ?? Console.WindowWidth, align),
430
                    align,
431
                    negative,
432
                    (line ?? Window.GetLineAvailable(align.ToPlacement()))
433
                        + margin
434
                        + text.Length
435
                        + i,
436
                    true
437
                );
438
        }
439
    }
440

441
    /// <summary>
442
    /// This method prints a paragraph in the console.
443
    /// </summary>
444
    /// <param name="equalizeLengths">Whether or not the lines of the paragraph should be equalized to the same length.</param>
445
    /// <param name="align">The alignment of the paragraph.</param>
446
    /// <param name="negative">If true, the paragraph is printed in the negative colors.</param>
447
    /// <param name="line">The height of the paragraph.</param>
448
    /// <param name="text">The lines of the paragraph.</param>
449
    /// <remarks>
450
    /// For more information, refer to the following resources:
451
    /// <list type="bullet">
452
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
453
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
454
    /// </list>
455
    /// </remarks>
456
    [Visual]
457
    public static void WriteMultiplePositionedLines(
458
        bool equalizeLengths = true,
459
        TextAlignment align = TextAlignment.Center,
460
        bool negative = false,
461
        int? line = null,
462
        params string[] text
463
    )
464
    {
465
        line ??= Console.CursorTop;
466
        if (equalizeLengths)
467
        {
468
            int maxLength = text.Length > 0 ? text.Max(s => s.Length) : 0;
×
469
            foreach (string str in text)
470
            {
471
                WritePositionedString(str.ResizeString(maxLength, align), align, negative, line++);
472
                if (line >= Console.WindowHeight - 1)
473
                    break;
474
            }
475
        }
476
        else
477
        {
478
            foreach (string str in text)
479
            {
480
                WritePositionedString(str, align, negative, line++);
481
                if (line >= Console.WindowHeight - 1)
482
                    break;
483
            }
484
        }
485
    }
486

487
    /// <summary>
488
    /// This method is used to clear a paragraph in the console.
489
    /// </summary>
490
    /// <param name="placement">The placement of the paragraph.</param>
491
    /// <param name="line">The height of the paragraph.</param>
492
    /// <param name="text">The lines of the paragraph.</param>
493
    /// <remarks>
494
    /// For more information, refer to the following resources:
495
    /// <list type="bullet">
496
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
497
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
498
    /// </list>
499
    /// </remarks>
500
    [Visual]
501
    public static void ClearMultiplePositionedLines(
502
        Placement placement,
503
        int line,
504
        params string[] text
505
    )
506
    {
507
        foreach (string str in text)
508
        {
509
            WritePositionedString(str, placement.ToTextAlignment(), false, line++);
510
            if (line >= Console.WindowHeight - 1)
511
                break;
512
        }
513
    }
514

515
    /// <summary>
516
    /// This method is used for debug purposes. It overrites any text in the console at a specified placement.
517
    /// </summary>
518
    /// <param name="placement">The placement of the debug mark.</param>
519
    /// <param name="lines">The lines of the debug mark.</param>
520
    /// <remarks>
521
    /// For more information, refer to the following resources:
522
    /// <list type="bullet">
523
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
524
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
525
    /// </list>
526
    /// </remarks>
527
    [Visual]
528
    public static void WriteDebugMark(
529
        Placement placement = Placement.TopRight,
530
        params string[] lines
531
    )
532
    {
533
        placement = placement switch
534
        {
535
            Placement.TopLeft => Placement.TopLeft,
536
            Placement.TopCenter => Placement.TopCenter,
537
            Placement.TopRight => Placement.TopRight,
538
            _ => Placement.TopRight
539
        };
540

541
        (int, int) cursorPosition = (Console.CursorLeft, Console.CursorTop);
542
        const int DEFAULT_LENGHT = 7;
543

544
        var finalLines = new List<string>();
545

546
        int maxLength =
547
            lines.Length > 0
548
                ? (
549
                    lines.Max(s => s.Length) < DEFAULT_LENGHT
×
550
                        ? DEFAULT_LENGHT
551
                        : lines.Max(s => s.Length)
×
552
                )
553
                : DEFAULT_LENGHT;
554

555
        finalLines.Add(
556
            "┌Debug"
557
                + (maxLength != DEFAULT_LENGHT ? new string('─', maxLength - DEFAULT_LENGHT) : "")
558
                + "─//─┐"
559
        );
560
        if (lines.Length is 0)
561
        {
562
            finalLines.Add("│ " + " ".ResizeString(maxLength, TextAlignment.Left) + " │");
563
        }
564
        else
565
        {
566
            foreach (string line in lines)
567
            {
568
                finalLines.Add("│ " + line.ResizeString(maxLength, TextAlignment.Left) + " │");
569
            }
570
        }
571

572
        finalLines.Add(
573
            "└─//───"
574
                + (maxLength != DEFAULT_LENGHT ? new string('─', maxLength - DEFAULT_LENGHT) : "")
575
                + "───┘"
576
        );
577

578
        WriteMultiplePositionedLines(
579
            false,
580
            placement.ToTextAlignment(),
581
            false,
582
            0,
583
            finalLines.ToArray()
584
        );
585

586
        Console.SetCursorPosition(cursorPosition.Item1, cursorPosition.Item2);
587
    }
588
    #endregion
589

590
    #region Extensions
591
    /// <summary>
592
    /// This method builds a string with a specific size and a specific placement.
593
    /// </summary>
594
    /// <param name="str">The string to build.</param>
595
    /// <param name="size">The size of the string.</param>
596
    /// <param name="align">The alignment of the string.</param>
597
    /// <param name="truncate">If true, the string is truncated if it is too long.</param>
598
    /// <returns>The built string.</returns>
599
    /// <remarks>
600
    /// For more information, refer to the following resources:
601
    /// <list type="bullet">
602
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
603
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
604
    /// </list>
605
    /// </remarks>
606
    public static string ResizeString(
607
        this string str,
608
        int size,
609
        TextAlignment align = TextAlignment.Center,
610
        bool truncate = true
611
    )
612
    {
613
        int padding = size - str.Length;
297✔
614
        if (truncate && padding < 0)
297✔
615
            switch (align)
616
            {
617
                case TextAlignment.Left:
618
                    return str.Substring(0, size);
3✔
619
                case TextAlignment.Center:
620
                    return str.Substring((-padding) / 2, size);
3✔
621
                case TextAlignment.Right:
622
                    return str.Substring(-padding, size);
3✔
623
            }
624
        else if (padding > 0)
288✔
625
            switch (align)
626
            {
627
                case TextAlignment.Left:
628
                    return str.PadRight(size);
3✔
629
                case TextAlignment.Center:
630
                    return str.PadLeft(padding / 2 + padding % 2 + str.Length)
273✔
631
                        .PadRight(padding + str.Length);
273✔
632
                case TextAlignment.Right:
633
                    return str.PadLeft(size);
3✔
634
            }
635
        return str;
9✔
636
    }
637

638
    /// <summary>
639
    /// Insert a specified string into another string, at a specified position.
640
    /// </summary>
641
    /// <param name="inserted">The string that receives the other.</param>
642
    /// <param name="toInsert">The string to insert.</param>
643
    /// <param name="position">The placement of the string to insert.</param>
644
    /// <returns>The final string after computing.</returns>
645
    /// <remarks>
646
    /// For more information, refer to the following resources:
647
    /// <list type="bullet">
648
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
649
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
650
    /// </list>
651
    /// </remarks>
652
    public static string InsertString(
653
        this string inserted,
654
        string toInsert,
655
        Placement position = Placement.TopCenter
656
    )
657
    {
658
        if (inserted.Length < toInsert.Length)
27✔
659
        {
660
            throw new ArgumentException(
6✔
661
                "The string to insert is longer than the string to insert into"
6✔
662
            );
6✔
663
        }
664
        switch (position)
665
        {
666
            case Placement.TopCenter:
667
            case Placement.BottomCenterFullWidth:
668
            case Placement.TopCenterFullWidth:
669
                int center = inserted.Length / 2;
6✔
670
                int start = center - (toInsert.Length / 2);
6✔
671
                return inserted.Remove(start, toInsert.Length).Insert(start, toInsert);
6✔
672
            case Placement.TopLeft:
673
                return inserted.Remove(0, toInsert.Length).Insert(0, toInsert);
6✔
674
            case Placement.TopRight:
675
                return inserted
6✔
676
                    .Remove(inserted.Length - toInsert.Length, toInsert.Length)
6✔
677
                    .Insert(inserted.Length - toInsert.Length, toInsert);
6✔
678
            default:
679
                throw new ArgumentException("The placement is not valid");
3✔
680
        }
681
    }
682

683
    /// <summary>
684
    /// This method is used to convert the banner tuple into a string.
685
    /// </summary>
686
    /// <param name="banner">The banner tuple.</param>
687
    /// <returns>Converts the banner to a string.</returns>
688
    /// <remarks>
689
    /// For more information, refer to the following resources:
690
    /// <list type="bullet">
691
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
692
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
693
    /// </list>
694
    /// </remarks>
695
    [Visual]
696
    public static string BannerToString(this (string, string, string) banner)
697
    {
698
        string centeredText = banner.Item2.ResizeString(
699
            Console.WindowWidth - 2,
700
            TextAlignment.Center,
701
            true
702
        );
703

704
        string leftAndCenter = banner.Item1 + centeredText.Substring(banner.Item1.Length);
705

706
        string fullBanner =
707
            leftAndCenter.Substring(0, leftAndCenter.Length - banner.Item3.Length) + banner.Item3;
708

709
        return " " + fullBanner + " ";
710
    }
711

712
    /// <summary>
713
    /// This method is used to get the range of a negative sequence in a string and remove the negative anchors.
714
    /// </summary>
715
    /// <param name="str">The string to check.</param>
716
    /// <returns>The string without the negative anchors and the range of the negative sequence.</returns>
717
    /// <remarks>
718
    /// For more information, refer to the following resources:
719
    /// <list type="bullet">
720
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
721
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
722
    /// </list>
723
    /// </remarks>
724
    public static (string, (int, int)?) GetRangeAndRemoveNegativeAnchors(this string str)
725
    {
726
        int negStart = str.IndexOf(NEGATIVE_ANCHOR);
9✔
727
        int negEnd = str.IndexOf(NEGATIVE_ANCHOR, negStart + 1);
9✔
728
        if (negStart == -1 || negEnd == -1)
9✔
729
            return (str, null);
3✔
730

731
        negEnd -= NEGATIVE_ANCHOR.Length;
6✔
732
        string newStr = str.Replace(NEGATIVE_ANCHOR, "");
6✔
733
        return (newStr, (negStart, negEnd));
6✔
734
    }
735

736
    /// <summary>
737
    /// This method is used to convert a Placement into a TextAlignment.
738
    /// </summary>
739
    /// <param name="placement">The placement to convert.</param>
740
    /// <returns>The converted placement.</returns>
741
    /// <exception cref="ArgumentException">Thrown when the placement is not valid.</exception>
742
    /// <remarks>
743
    /// For more information, refer to the following resources:
744
    /// <list type="bullet">
745
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
746
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
747
    /// </list>
748
    /// </remarks>
749
    public static TextAlignment ToTextAlignment(this Placement placement)
750
    {
751
        return placement switch
18✔
752
        {
18✔
753
            Placement.TopCenter => TextAlignment.Center,
3✔
754
            Placement.TopLeft => TextAlignment.Left,
3✔
755
            Placement.TopRight => TextAlignment.Right,
3✔
756
            Placement.BottomCenterFullWidth => TextAlignment.Center,
3✔
757
            Placement.TopCenterFullWidth => TextAlignment.Center,
3✔
758
            _ => throw new ArgumentException("The placement is not valid"),
3✔
759
        };
18✔
760
    }
761

762
    /// <summary>
763
    /// This method is used to convert a TextAlignment into a Placement.
764
    /// </summary>
765
    /// <param name="align">The alignment to convert.</param>
766
    /// <returns>The converted alignment.</returns>
767
    /// <exception cref="ArgumentException">Thrown when the alignment is not valid.</exception>
768
    /// <remarks>
769
    /// For more information, refer to the following resources:
770
    /// <list type="bullet">
771
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
772
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
773
    /// </list>
774
    /// </remarks>
775
    public static Placement ToPlacement(this TextAlignment align)
776
    {
777
        return align switch
12✔
778
        {
12✔
779
            TextAlignment.Center => Placement.TopCenter,
3✔
780
            TextAlignment.Left => Placement.TopLeft,
3✔
781
            TextAlignment.Right => Placement.TopRight,
3✔
782
            _ => throw new ArgumentException("The alignment is not valid"),
3✔
783
        };
12✔
784
    }
785
    #endregion
786
}
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