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

MorganKryze / ConsoleAppVisuals / 8158191062

05 Mar 2024 02:47PM UTC coverage: 86.165% (+0.9%) from 85.231%
8158191062

push

github

MorganKryze
📖 (readme) update roadmap

931 of 1144 branches covered (81.38%)

Branch coverage included in aggregate %.

1803 of 2029 relevant lines covered (88.86%)

412.64 hits per line

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

68.04
/src/ConsoleAppVisuals/Window.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 Window class manages the elements that are to be displayed on the console.
9
/// </summary>
10
/// <remarks>
11
/// For more information, refer to the following resources:
12
/// <list type="bullet">
13
/// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
14
/// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
15
/// </list>
16
/// </remarks>
17
public static class Window
18
{
19
    #region Setup
20
    /// <summary>
21
    /// This method sets up the console as soon as the Program starts.
22
    /// </summary>
23
    [Visual]
24
    static Window()
25
    {
26
        Console.Clear();
27
        Console.CursorVisible = false;
28
    }
29
    #endregion
30

31
    #region Fields: s_elements
32
    private static readonly List<Element> s_elements = new();
33
    #endregion
34

35
    #region Constants: DefaultVisibility
36
    /// <summary>
37
    /// The default visibility of the elements when they are added to the window.
38
    /// </summary>
39
    /// <remarks>
40
    /// This value should not be changed.
41
    /// Each time the user adds an element to the window, it will try to toggle the visibility of the element.
42
    /// </remarks>
43
    public const bool DEFAULT_VISIBILITY = false;
44
    #endregion
45

46
    #region Properties: NextId, NumberOfElements, Elements
47
    /// <summary>
48
    /// Gives the next id number each time a new element is added to the window.
49
    /// </summary>
50
    public static int NextId => s_elements.Count;
66✔
51

52
    /// <summary>
53
    /// Gives the number of elements in the window.
54
    /// </summary>
55
    public static int CountElements => s_elements.Count;
10✔
56

57
    /// <summary>
58
    /// Gives the list of elements in the window.
59
    /// </summary>
60
    public static List<Element> Elements => s_elements;
26✔
61
    #endregion
62

63
    #region Managing Methods: Get, Add, Insert, Remove, RemoveAll
64

65
    /// <summary>
66
    /// This method returns a range of elements given a start and end ids.
67
    /// </summary>
68
    /// <param name="start">The start id of the range.</param>
69
    /// <param name="end">The end id of the range.</param>
70
    /// <returns>The range of elements from the start to the end id.</returns>
71
    public static List<Element> GetRange(int start, int end)
72
    {
73
        return s_elements.GetRange(start, end);
80✔
74
    }
75

76
    /// <summary>
77
    /// This method returns the first element of the given type.
78
    /// </summary>
79
    /// <typeparam name="T">The type of the element.</typeparam>
80
    /// <returns>The element with the given type if it exists, null otherwise.</returns>
81
    /// <remarks>
82
    /// For more information, refer to the following resources:
83
    /// <list type="bullet">
84
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
85
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
86
    /// </list>
87
    /// </remarks>
88
    public static T? GetElement<T>()
89
        where T : Element
90
    {
91
        return s_elements.Find(element => element.GetType() == typeof(T)) as T;
32✔
92
    }
93

94
    /// <summary>
95
    /// This method returns the first element of the given type and id.
96
    /// </summary>
97
    /// <param name="id">The id of the element.</param>
98
    /// <returns>The element with the given id if it exists, null otherwise.</returns>
99
    /// <exception cref="ArgumentOutOfRangeException">Thrown when the id is out of range.</exception>
100
    /// <remarks>
101
    /// For more information, refer to the following resources:
102
    /// <list type="bullet">
103
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
104
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
105
    /// </list>
106
    /// </remarks>
107
    public static T? GetElement<T>(int id)
108
        where T : Element
109
    {
110
        if (id < 0 || id >= s_elements.Count)
10✔
111
        {
112
            throw new ArgumentOutOfRangeException(nameof(id), "Invalid element ID.");
4✔
113
        }
114
        return (T)s_elements[id];
6✔
115
    }
116

117
    /// <summary>
118
    /// This method returns the first visible element with the given type.
119
    /// </summary>
120
    /// <typeparam name="T">The type of the element.</typeparam>
121
    /// <returns>The visible element with the given type if it exists, null otherwise.</returns>
122
    /// <remarks>
123
    /// For more information, refer to the following resources:
124
    /// <list type="bullet">
125
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
126
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
127
    /// </list>
128
    /// </remarks>
129
    public static T? GetVisibleElement<T>()
130
        where T : Element
131
    {
132
        return s_elements.Find(element => element.GetType() == typeof(T) && element.Visibility)
20✔
133
            as T;
12✔
134
    }
135

136
    /// <summary>
137
    /// This method adds elements to the window.
138
    /// </summary>
139
    /// <param name="elements">The elements to be added.</param>
140
    /// <remarks>
141
    /// For more information, refer to the following resources:
142
    /// <list type="bullet">
143
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
144
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
145
    /// </list>
146
    /// </remarks>
147
    public static void AddElement(params Element[] elements)
148
    {
149
        foreach (var element in elements)
248✔
150
        {
151
            element.Id = NextId;
62✔
152
            s_elements.Add(element);
62✔
153
            if (!element.IsInteractive && AllowVisibilityToggle(element.Id))
62✔
154
            {
155
                element.ToggleVisibility();
12✔
156
            }
157
        }
158
    }
62✔
159

160
    /// <summary>
161
    /// This method inserts an element to the window at the given id.
162
    /// </summary>
163
    /// <param name="element">The element to be inserted.</param>
164
    /// <param name="id">The id of the element.</param>
165
    /// <exception cref="ArgumentOutOfRangeException">Thrown when the id is out of range.</exception>
166
    /// <remarks>
167
    /// For more information, refer to the following resources:
168
    /// <list type="bullet">
169
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
170
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
171
    /// </list>
172
    /// </remarks>
173
    public static void InsertElement(Element element, int id)
174
    {
175
        if (id < 0 || id > s_elements.Count)
6✔
176
        {
177
            throw new ArgumentOutOfRangeException(nameof(id), "Invalid element ID.");
4✔
178
        }
179
        s_elements.Insert(id, element);
2✔
180
    }
2✔
181

182
    /// <summary>
183
    /// This method removes the first element with the given type.
184
    /// </summary>
185
    /// <typeparam name="T">The type of the element.</typeparam>
186
    /// <exception cref="ElementNotFoundException">Thrown when the element is invalid.</exception>
187
    /// <returns>True if the element is successfully removed, false otherwise.</returns>
188
    /// <remarks>
189
    /// For more information, refer to the following resources:
190
    /// <list type="bullet">
191
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
192
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
193
    /// </list>
194
    /// </remarks>
195
    public static bool RemoveElement<T>()
196
        where T : Element
197
    {
198
        var element =
8✔
199
            GetElement<T>()
8✔
200
            ?? throw new ElementNotFoundException("Invalid element. Not found in the window.");
8✔
201
        var state = s_elements.Remove(element);
6✔
202
        UpdateIDs();
6✔
203
        return state;
6✔
204
    }
205

206
    /// <summary>
207
    /// This method removes the element with the given id.
208
    /// </summary>
209
    /// <param name="id">The id of the element.</param>
210
    /// <exception cref="ArgumentOutOfRangeException">Thrown when the id is out of range.</exception>
211
    /// <remarks>
212
    /// For more information, refer to the following resources:
213
    /// <list type="bullet">
214
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
215
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
216
    /// </list>
217
    /// </remarks>
218
    public static void RemoveElement(int id)
219
    {
220
        if (id < 0 || id >= s_elements.Count)
6✔
221
        {
222
            throw new ArgumentOutOfRangeException(nameof(id), "Invalid element ID.");
4✔
223
        }
224
        s_elements.RemoveAt(id);
2✔
225
        UpdateIDs();
2✔
226
    }
2✔
227

228
    /// <summary>
229
    /// This method removes the given element.
230
    /// </summary>
231
    /// <param name="elements">The elements to be removed.</param>
232
    /// <exception cref="ElementNotFoundException">Thrown when the element is invalid.</exception>
233
    /// <returns>True if the element is successfully removed, false otherwise.</returns>
234
    /// <remarks>
235
    /// For more information, refer to the following resources:
236
    /// <list type="bullet">
237
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
238
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
239
    /// </list>
240
    /// </remarks>
241
    public static bool RemoveElement(params Element[] elements)
242
    {
243
        bool state = true;
6✔
244

245
        foreach (var element in elements)
22✔
246
        {
247
            if (!s_elements.Contains(element))
6✔
248
            {
249
                throw new ElementNotFoundException("Invalid element. Not found in the window.");
2✔
250
            }
251
            state &= s_elements.Remove(element);
4✔
252
        }
253

254
        UpdateIDs();
4✔
255
        return state;
4✔
256
    }
257

258
    /// <summary>
259
    /// This method removes all elements from the window.
260
    /// </summary>
261
    /// <remarks>
262
    /// For more information, refer to the following resources:
263
    /// <list type="bullet">
264
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
265
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
266
    /// </list>
267
    /// </remarks>
268
    public static void RemoveAllElements()
269
    {
270
        s_elements.Clear();
672✔
271
    }
672✔
272
    #endregion
273

274
    #region Visibility Methods: ActivateElement, ActivateAllElements, DeactivateElement, DeactivateAllElements
275
    /// <summary>
276
    /// This method attempts to activate the visibility of the element with the given id.
277
    /// </summary>
278
    /// <param name="id">The id of the element.</param>
279
    /// <param name="render">If true, the element will be rendered.</param>
280
    /// <exception cref="ArgumentOutOfRangeException">Thrown when the id is out of range.</exception>
281
    /// <remarks>
282
    /// For more information, refer to the following resources:
283
    /// <list type="bullet">
284
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
285
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
286
    /// </list>
287
    /// </remarks>
288
    [Visual]
289
    public static void ActivateElement(int id, bool render = true)
290
    {
291
        if (id < 0 || id >= s_elements.Count)
292
        {
293
            throw new ArgumentOutOfRangeException(nameof(id), "Invalid element ID.");
294
        }
295
        if (!s_elements[id].Visibility)
296
        {
297
            s_elements[id].ToggleVisibility();
298
        }
299
        if (render)
300
        {
301
            Render(s_elements[id]);
302
        }
303
    }
304

305
    /// <summary>
306
    /// This method attempts to activate the visibility of the given element.
307
    /// </summary>
308
    /// <param name="element">The element to be activated.</param>
309
    /// <param name="render">If true, the element will be rendered.</param>
310
    /// <exception cref="ElementNotFoundException">Thrown when the element is invalid.</exception>
311
    [Visual]
312
    public static void ActivateElement(Element element, bool render = true)
313
    {
314
        if (!s_elements.Contains(element))
315
        {
316
            throw new ElementNotFoundException("Invalid element. Not found in the window.");
317
        }
318
        if (!element.Visibility)
319
        {
320
            element.ToggleVisibility();
321
        }
322
        if (render)
323
        {
324
            Render(element);
325
        }
326
    }
327

328
    /// <summary>
329
    /// This method attempts to activate the visibility of the first element of the given type.
330
    /// </summary>
331
    /// <param name="render">If true, the element will be rendered.</param>
332
    /// <typeparam name="T">The type of the element.</typeparam>
333
    /// <exception cref="ElementNotFoundException">Thrown when the element is invalid.</exception>
334
    /// <remarks>
335
    /// For more information, refer to the following resources:
336
    /// <list type="bullet">
337
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
338
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
339
    /// </list>
340
    /// </remarks>
341
    [Visual]
342
    public static void ActivateElement<T>(bool render = true)
343
        where T : Element
344
    {
345
        var element =
346
            GetElement<T>()
347
            ?? throw new ElementNotFoundException("Invalid element. Not found in the window.");
348
        if (!element.Visibility)
349
        {
350
            element.ToggleVisibility();
351
        }
352
        if (render)
353
        {
354
            Render(element);
355
        }
356
    }
357

358
    /// <summary>
359
    /// This method attempts to activate the visibility of all elements.
360
    /// </summary>
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/">Example Project</a></description></item>
366
    /// </list>
367
    /// </remarks>
368
    public static void ActivateAllElements()
369
    {
370
        foreach (var element in s_elements)
16✔
371
        {
372
            if (!element.Visibility)
4✔
373
            {
374
                element.ToggleVisibility();
4✔
375
            }
376
        }
377
    }
4✔
378

379
    /// <summary>
380
    /// This method to deactivate the visibility of the element with the given id.
381
    /// </summary>
382
    /// <param name="id">The id of the element.</param>
383
    /// <param name="clear">If true, the element will be cleared from the console.</param>
384
    /// <exception cref="ArgumentOutOfRangeException">Thrown when the id is out of range.</exception>
385
    /// <remarks>
386
    /// For more information, refer to the following resources:
387
    /// <list type="bullet">
388
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
389
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
390
    /// </list>
391
    /// </remarks>
392
    public static void DeactivateElement(int id, bool clear = true)
393
    {
394
        if (id < 0 || id >= s_elements.Count)
4✔
395
        {
396
            throw new ArgumentOutOfRangeException(nameof(id), "Invalid element ID.");
2✔
397
        }
398
        if (s_elements[id].Visibility)
2✔
399
        {
400
            s_elements[id].ToggleVisibility();
2✔
401
            if (clear)
2✔
402
            {
403
                s_elements[id].Clear();
2✔
404
            }
405
        }
406
    }
2✔
407

408
    /// <summary>
409
    /// This method deactivate the visibility of the element with the given type.
410
    /// </summary>
411
    /// <param name="element">The element to be deactivated.</param>
412
    /// <param name="clear">If true, the element will be cleared from the console.</param>
413
    /// <exception cref="ElementNotFoundException">Thrown when the element is invalid.</exception>
414
    /// <remarks>
415
    /// For more information, refer to the following resources:
416
    /// <list type="bullet">
417
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
418
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
419
    /// </list>
420
    /// </remarks>
421
    public static void DeactivateElement(Element element, bool clear = true)
422
    {
423
        if (!s_elements.Contains(element))
6✔
424
        {
425
            throw new ElementNotFoundException("Invalid element. Not found in the window.");
2✔
426
        }
427

428
        if (element.Visibility)
4✔
429
        {
430
            element.ToggleVisibility();
4✔
431
            if (clear)
4✔
432
            {
433
                element.Clear();
2✔
434
            }
435
        }
436
    }
4✔
437

438
    /// <summary>
439
    /// This method deactivate the visibility of the first element with the given type.
440
    /// </summary>
441
    /// <param name="clear">If true, the element will be cleared.</param>
442
    /// <typeparam name="T">The type of the element.</typeparam>
443
    /// <exception cref="ElementNotFoundException">Thrown when the element is invalid.</exception>
444
    /// <remarks>
445
    /// For more information, refer to the following resources:
446
    /// <list type="bullet">
447
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
448
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
449
    /// </list>
450
    /// </remarks>
451
    public static void DeactivateElement<T>(bool clear = true)
452
        where T : Element
453
    {
454
        var element =
6✔
455
            GetVisibleElement<T>()
6✔
456
            ?? throw new ElementNotFoundException("Invalid element. Not found in the window.");
6✔
457
        if (element.Visibility)
4✔
458
        {
459
            element.ToggleVisibility();
4✔
460
            if (clear)
4✔
461
            {
462
                element.Clear();
2✔
463
            }
464
        }
465
    }
4✔
466

467
    /// <summary>
468
    /// This method deactivate the visibility of all elements.
469
    /// </summary>
470
    /// <remarks>
471
    /// For more information, refer to the following resources:
472
    /// <list type="bullet">
473
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
474
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
475
    /// </list>
476
    /// </remarks>
477
    public static void DeactivateAllElements()
478
    {
479
        foreach (var element in s_elements)
8✔
480
        {
481
            if (element.Visibility)
2✔
482
            {
483
                element.ToggleVisibility();
2✔
484
            }
485
        }
486
    }
2✔
487
    #endregion
488

489
    #region Utility Methods: AllowVisibilityToggle, GetLineAvailable, Clear, StopExecution, Refresh
490
    [ExcludeFromCodeCoverage]
491
    private static void UpdateIDs()
492
    {
493
        for (int i = 0; i < s_elements.Count; i++)
494
        {
495
            s_elements[i].Id = i;
496
        }
497
    }
498

499
    /// <summary>
500
    /// This method checks if the element can be toggled to visible.
501
    /// </summary>
502
    /// <param name="id">The id of the element.</param>
503
    /// <returns>True if the element can be toggled to visible, false otherwise.</returns>
504
    public static bool AllowVisibilityToggle(int id)
505
    {
506
        if (s_elements[id].IsInteractive)
46✔
507
        {
508
            int numberOfVisibleInteractiveElements = s_elements.Count(element =>
18✔
509
                element.IsInteractive && element.Visibility
18!
510
            );
18✔
511
            return numberOfVisibleInteractiveElements == 0;
18✔
512
        }
513
        else
514
        {
515
            int numberOfVisibleElements = s_elements.Count(element =>
28✔
516
                element.GetType() == s_elements[id].GetType() && element.Visibility
32!
517
            );
28✔
518
            return numberOfVisibleElements < s_elements[id].MaxNumberOfThisElement;
28✔
519
        }
520
    }
521

522
    /// <summary>
523
    /// This method gets the last line available to draw an element on the console from a placement.
524
    /// </summary>
525
    /// <param name="placement">The placement of the element.</param>
526
    /// <returns>The last line available to draw an element on the console from a placement.</returns>
527
    /// <exception cref="ArgumentOutOfRangeException">Thrown when the placement is invalid.</exception>
528
    /// <remarks>
529
    /// For more information, refer to the following resources:
530
    /// <list type="bullet">
531
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
532
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
533
    /// </list>
534
    /// </remarks>
535
    public static int GetLineAvailable(Placement placement)
536
    {
537
        return placement switch
2!
538
        {
2✔
539
            Placement.TopCenterFullWidth
2✔
540
                => s_elements
×
541
                    .Where(e => e.Placement == Placement.TopCenterFullWidth && e.Visibility)
×
542
                    .Sum(e => e.Height)
×
543
                    + s_elements
×
544
                        .Where(e => e.Placement == Placement.TopCenter && e.Visibility)
×
545
                        .Sum(e => e.Height)
×
546
                    + s_elements
×
547
                        .Where(e => e.Placement == Placement.TopLeft && e.Visibility)
×
548
                        .Sum(e => e.Height)
×
549
                    + s_elements
×
550
                        .Where(e => e.Placement == Placement.TopRight && e.Visibility)
×
551
                        .Sum(e => e.Height),
×
552
            Placement.TopCenter
2✔
553
                => s_elements
×
554
                    .Where(e => e.Placement == Placement.TopCenterFullWidth && e.Visibility)
×
555
                    .Sum(e => e.Height)
×
556
                    + s_elements
×
557
                        .Where(e => e.Placement == Placement.TopCenter && e.Visibility)
×
558
                        .Sum(e => e.Height),
×
559
            Placement.TopLeft
2✔
560
                => s_elements
×
561
                    .Where(e => e.Placement == Placement.TopCenterFullWidth && e.Visibility)
×
562
                    .Sum(e => e.Height)
×
563
                    + s_elements
×
564
                        .Where(e => e.Placement == Placement.TopLeft && e.Visibility)
×
565
                        .Sum(e => e.Height),
×
566

2✔
567
            Placement.TopRight
2✔
568
                => s_elements
×
569
                    .Where(e => e.Placement == Placement.TopCenterFullWidth && e.Visibility)
×
570
                    .Sum(e => e.Height)
×
571
                    + s_elements
×
572
                        .Where(e => e.Placement == Placement.TopRight && e.Visibility)
×
573
                        .Sum(e => e.Height),
×
574
            Placement.BottomCenterFullWidth
2✔
575
                => (Console.WindowHeight == 0 ? 0 : Console.WindowHeight - 1)
2!
576
                    - s_elements
2✔
577
                        .Where(e => e.Placement == Placement.BottomCenterFullWidth && e.Visibility)
×
578
                        .Sum(e => e.Height),
2✔
579
            _ => throw new ArgumentOutOfRangeException(nameof(placement), "Invalid placement.")
×
580
        };
2✔
581
    }
582

583
    /// <summary>
584
    /// This method checks if the line is valid under the console constraints.
585
    /// </summary>
586
    /// <param name="line">The line to be checked.</param>
587
    /// <returns>The line if it is valid.</returns>
588
    /// <exception cref="ArgumentOutOfRangeException">Thrown when the line is out of range.</exception>
589
    /// <remarks>
590
    /// For more information, refer to the following resources:
591
    /// <list type="bullet">
592
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
593
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
594
    /// </list>
595
    /// </remarks>
596
    public static int? CheckLine(int? line)
597
    {
598
        int minLine = 0;
22✔
599
        int maxLine = Console.WindowHeight == 0 ? 0 : Console.WindowHeight - 1;
22!
600
        if (line is null)
22✔
601
        {
602
            return line;
18✔
603
        }
604
        if (line < minLine || line > maxLine)
4✔
605
        {
606
            throw new ArgumentOutOfRangeException(
2✔
607
                nameof(line),
2✔
608
                $"Invalid line. The line must be between 0 and {maxLine}."
2✔
609
            );
2✔
610
        }
611
        return line;
2✔
612
    }
613

614
    /// <summary>
615
    /// This method stops the execution of the program until a key is pressed.
616
    /// </summary>
617
    /// <param name="key">The key to be pressed to continue the execution.</param>
618
    /// <remarks>
619
    /// For more information, refer to the following resources:
620
    /// <list type="bullet">
621
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
622
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
623
    /// </list>
624
    /// </remarks>
625
    [Visual]
626
    public static void Freeze(ConsoleKey key = ConsoleKey.Enter)
627
    {
628
        while (Console.ReadKey(intercept: true).Key != key)
629
        {
630
            Thread.Sleep(10);
631
        }
632
    }
633

634
    /// <summary>
635
    /// This method draws all visible elements of the window on the console.
636
    /// </summary>
637
    /// <remarks>
638
    /// For more information, refer to the following resources:
639
    /// <list type="bullet">
640
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
641
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
642
    /// </list>
643
    /// </remarks>
644
    public static void Render()
645
    {
646
        Clear();
6✔
647
        Core.IsScreenUpdated();
6✔
648
        foreach (var element in s_elements)
22✔
649
        {
650
            element.RenderElement();
6✔
651
        }
652
    }
4✔
653

654
    /// <summary>
655
    /// This method draws all given visible elements of the window on the console.
656
    /// </summary>
657
    /// <param name="elements">The elements to be drawn.</param>
658
    /// <exception cref="ElementNotFoundException">Thrown when the element is not found in the window.</exception>
659
    /// <remarks>
660
    /// For more information, refer to the following resources:
661
    /// <list type="bullet">
662
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
663
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
664
    /// </list>
665
    /// </remarks>
666
    public static void Render(params Element[] elements)
667
    {
668
        if (Core.IsScreenUpdated())
6!
669
        {
670
            Render();
6✔
671
            return;
4✔
672
        }
673

674
        foreach (var element in elements)
×
675
        {
676
            if (!s_elements.Contains(element))
×
677
            {
678
                throw new ElementNotFoundException($"Element {element} is not in the Window.");
×
679
            }
680
            element.RenderElement();
×
681
        }
682
    }
×
683

684
    /// <summary>
685
    /// This method draws all the space of the visible elements of the window on the console.
686
    /// </summary>
687
    /// <returns>True if the space of the elements is successfully drawn, false otherwise.</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
    public static bool RenderElementsSpace()
696
    {
697
        foreach (var element in s_elements)
8✔
698
        {
699
            element.RenderElementSpace();
2✔
700
        }
701
        return true;
2✔
702
    }
703

704
    /// <summary>
705
    /// This method clears the console.
706
    /// </summary>
707
    /// <param name="continuous">If true, the window will be cleared continuously.</param>
708
    /// <param name="startLine">The start line of the window to be cleared.</param>
709
    /// <param name="length">The number of lines to be cleared.</param>
710
    /// <param name="step">The step of the window to be cleared.</param>
711
    /// <returns>True if the window is successfully cleared, false otherwise.</returns>
712
    /// <remarks>
713
    /// For more information, refer to the following resources:
714
    /// <list type="bullet">
715
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
716
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
717
    /// </list>
718
    /// </remarks>
719
    public static bool Clear(
720
        bool continuous = false,
721
        int? startLine = null,
722
        int? length = null,
723
        int step = 1
724
    )
725
    {
726
        int stepMax = Console.WindowHeight == 0 ? 1 : Console.WindowHeight;
8!
727
        startLine = CheckLine(startLine) ?? 0;
8✔
728
        length = CheckLine(startLine + length) ?? Console.WindowHeight;
8!
729
        if (step < 1 || step > stepMax)
8!
730
        {
731
            throw new ArgumentOutOfRangeException(
×
732
                nameof(step),
×
733
                "Invalid step, less than 0 or greater than the window height."
×
734
            );
×
735
        }
736

737
        for (int i = (int)startLine; i < (int)length; i += step)
16!
738
        {
739
            if (continuous)
×
740
            {
741
                Core.WriteContinuousString("".PadRight(Console.WindowWidth), i, false, 100, 10);
×
742
            }
743
            else
744
            {
745
                Core.WritePositionedString(
×
746
                    "".PadRight(Console.WindowWidth),
×
747
                    TextAlignment.Center,
×
748
                    false,
×
749
                    i
×
750
                );
×
751
            }
752
        }
753
        return true;
8✔
754
    }
755

756
    /// <summary>
757
    /// This method clears the window and exit the program.
758
    /// </summary>
759
    /// <remarks>
760
    /// For more information, refer to the following resources:
761
    /// <list type="bullet">
762
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
763
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
764
    /// </list>
765
    /// </remarks>
766
    [ExcludeFromCodeCoverage]
767
    public static void Close()
768
    {
769
        Core.LoadTerminalColorPanel();
770
        Clear(true);
771
        Console.CursorVisible = true;
772
        Environment.Exit(0);
773
    }
774
    #endregion
775
}
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