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

MorganKryze / ConsoleAppVisuals / 8098839542

29 Feb 2024 03:54PM UTC coverage: 95.086% (-0.9%) from 95.94%
8098839542

push

github

MorganKryze
📖 slight update of readme

925 of 1050 branches covered (88.1%)

Branch coverage included in aggregate %.

1784 of 1799 relevant lines covered (99.17%)

280.13 hits per line

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

94.68
/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 major class of the library. The window is used to collect the elements of the console and draw them.
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/Program.cs">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 window without the need to call it.
22
    /// </summary>
23
    [ExcludeFromCodeCoverage]
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
    public const bool DEFAULT_VISIBILITY = false;
40
    #endregion
41

42
    #region Properties: NextId, NumberOfElements
43
    /// <summary>
44
    /// Gives the next id number each time a new element is added to the window.
45
    /// </summary>
46
    public static int NextId => s_elements.Count;
1,200✔
47

48
    /// <summary>
49
    /// Gives the number of elements in the window.
50
    /// </summary>
51
    public static int CountElements => s_elements.Count;
15✔
52

53
    /// <summary>
54
    /// Gives the list of elements in the window.
55
    /// </summary>
56
    public static List<Element> GetElements => s_elements;
39✔
57
    #endregion
58

59
    #region Basic Methods: Get, Add, Insert, Remove, RemoveAll
60
    /// <summary>
61
    /// This method returns the first element of the given type.
62
    /// </summary>
63
    /// <typeparam name="T">The type of the element.</typeparam>
64
    /// <returns>The element with the given type if it exists, null otherwise.</returns>
65
    /// <remarks>
66
    /// For more information, refer to the following resources:
67
    /// <list type="bullet">
68
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
69
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/Program.cs">Example Project</a></description></item>
70
    /// </list>
71
    /// </remarks>
72
    public static T? GetElement<T>()
73
        where T : Element
74
    {
75
        return s_elements.Find(element => element.GetType() == typeof(T)) as T;
66✔
76
    }
77

78
    /// <summary>
79
    /// This method returns the element with the given id.
80
    /// </summary>
81
    /// <param name="id">The id of the element.</param>
82
    /// <returns>The element with the given id if it exists, null otherwise.</returns>
83
    /// <exception cref="ArgumentOutOfRangeException">Thrown when the id is out of range.</exception>
84
    /// <remarks>
85
    /// For more information, refer to the following resources:
86
    /// <list type="bullet">
87
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
88
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/Program.cs">Example Project</a></description></item>
89
    /// </list>
90
    /// </remarks>
91
    public static T? GetElement<T>(int id)
92
        where T : Element
93
    {
94
        if (id < 0 || id >= s_elements.Count)
15✔
95
        {
96
            throw new ArgumentOutOfRangeException(nameof(id), "Invalid element ID.");
6✔
97
        }
98
        return (T)s_elements[id];
9✔
99
    }
100

101
    /// <summary>
102
    /// This method returns the first visible element with the given type.
103
    /// </summary>
104
    /// <typeparam name="T">The type of the element.</typeparam>
105
    /// <returns>The visible element with the given type if it exists, null otherwise.</returns>
106
    /// <remarks>
107
    /// For more information, refer to the following resources:
108
    /// <list type="bullet">
109
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
110
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/Program.cs">Example Project</a></description></item>
111
    /// </list>
112
    /// </remarks>
113
    public static T? GetVisibleElement<T>()
114
        where T : Element
115
    {
116
        return s_elements.Find(element => element.GetType() == typeof(T) && element.Visibility)
39✔
117
            as T;
24✔
118
    }
119

120
    /// <summary>
121
    /// This method adds elements to the window.
122
    /// </summary>
123
    /// <param name="elements">The elements to be added.</param>
124
    /// <remarks>
125
    /// For more information, refer to the following resources:
126
    /// <list type="bullet">
127
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
128
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/Program.cs">Example Project</a></description></item>
129
    /// </list>
130
    /// </remarks>
131
    public static void AddElement(params Element[] elements)
132
    {
133
        foreach (var element in elements)
624✔
134
        {
135
            s_elements.Add(element);
156✔
136
            if (!element.IsInteractive && AllowVisibilityToggle(element.Id))
156✔
137
            {
138
                element.ToggleVisibility();
57✔
139
            }
140
        }
141
    }
156✔
142

143
    /// <summary>
144
    /// This method inserts an element to the window at the given id.
145
    /// </summary>
146
    /// <param name="element">The element to be inserted.</param>
147
    /// <param name="id">The id of the element.</param>
148
    /// <exception cref="ArgumentOutOfRangeException">Thrown when the id is out of range.</exception>
149
    /// <remarks>
150
    /// For more information, refer to the following resources:
151
    /// <list type="bullet">
152
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
153
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/Program.cs">Example Project</a></description></item>
154
    /// </list>
155
    /// </remarks>
156
    public static void InsertElement(Element element, int id)
157
    {
158
        if (id < 0 || id > s_elements.Count)
9✔
159
        {
160
            throw new ArgumentOutOfRangeException(nameof(id), "Invalid element ID.");
6✔
161
        }
162
        s_elements.Insert(id, element);
3✔
163
    }
3✔
164

165
    /// <summary>
166
    /// This method removes the element with the given id.
167
    /// </summary>
168
    /// <param name="id">The id of the element.</param>
169
    /// <exception cref="ArgumentOutOfRangeException">Thrown when the id is out of range.</exception>
170
    /// <remarks>
171
    /// For more information, refer to the following resources:
172
    /// <list type="bullet">
173
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
174
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/Program.cs">Example Project</a></description></item>
175
    /// </list>
176
    /// </remarks>
177
    public static void RemoveElement(int id)
178
    {
179
        if (id < 0 || id >= s_elements.Count)
9✔
180
        {
181
            throw new ArgumentOutOfRangeException(nameof(id), "Invalid element ID.");
6✔
182
        }
183
        s_elements.RemoveAt(id);
3✔
184
        UpdateIDs();
3✔
185
    }
3✔
186

187
    /// <summary>
188
    /// This method removes the given element.
189
    /// </summary>
190
    /// <param name="elements">The elements to be removed.</param>
191
    /// <exception cref="ElementNotFoundException">Thrown when the element is invalid.</exception>
192
    /// <returns>True if the element is successfully removed, false otherwise.</returns>
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 bool RemoveElement(params Element[] elements)
201
    {
202
        bool state = true;
9✔
203

204
        foreach (var element in elements)
33✔
205
        {
206
            if (!s_elements.Contains(element))
9✔
207
            {
208
                throw new ElementNotFoundException("Invalid element. Not found in the window.");
3✔
209
            }
210
            state &= s_elements.Remove(element);
6✔
211
        }
212

213
        UpdateIDs();
6✔
214
        return state;
6✔
215
    }
216

217
    /// <summary>
218
    /// This method removes the first element with the given type.
219
    /// </summary>
220
    /// <typeparam name="T">The type of the element.</typeparam>
221
    /// <exception cref="ElementNotFoundException">Thrown when the element is invalid.</exception>
222
    /// <returns>True if the element is successfully removed, false otherwise.</returns>
223
    /// <remarks>
224
    /// For more information, refer to the following resources:
225
    /// <list type="bullet">
226
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
227
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/Program.cs">Example Project</a></description></item>
228
    /// </list>
229
    /// </remarks>
230
    public static bool RemoveElement<T>()
231
        where T : Element
232
    {
233
        var element =
12✔
234
            GetElement<T>()
12✔
235
            ?? throw new ElementNotFoundException("Invalid element. Not found in the window.");
12✔
236
        var state = s_elements.Remove(element);
9✔
237
        UpdateIDs();
9✔
238
        return state;
9✔
239
    }
240

241
    /// <summary>
242
    /// This method removes all elements from the window.
243
    /// </summary>
244
    /// <remarks>
245
    /// For more information, refer to the following resources:
246
    /// <list type="bullet">
247
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
248
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/Program.cs">Example Project</a></description></item>
249
    /// </list>
250
    /// </remarks>
251
    public static void RemoveAllElements()
252
    {
253
        s_elements.Clear();
1,119✔
254
    }
1,119✔
255
    #endregion
256

257
    #region Manipulation Methods: ActivateElement, ActivateAllElements, DeactivateElement, DeactivateAllElements
258
    /// <summary>
259
    /// This method attempts to activate the visibility of the element with the given id.
260
    /// </summary>
261
    /// <param name="id">The id of the element.</param>
262
    /// <param name="render">If true, the element will be rendered.</param>
263
    /// <exception cref="ArgumentOutOfRangeException">Thrown when the id is out of range.</exception>
264
    /// <remarks>
265
    /// For more information, refer to the following resources:
266
    /// <list type="bullet">
267
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
268
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/Program.cs">Example Project</a></description></item>
269
    /// </list>
270
    /// </remarks>
271
    [Visual]
272
    public static void ActivateElement(int id, bool render = true)
273
    {
274
        if (id < 0 || id >= s_elements.Count)
275
        {
276
            throw new ArgumentOutOfRangeException(nameof(id), "Invalid element ID.");
277
        }
278
        if (!s_elements[id].Visibility)
279
        {
280
            s_elements[id].ToggleVisibility();
281
        }
282
        if (render)
283
        {
284
            s_elements[id].RenderElement();
285
        }
286
    }
287

288
    /// <summary>
289
    /// This method attempts to activate the visibility of the given element.
290
    /// </summary>
291
    /// <param name="element">The element to be activated.</param>
292
    /// <param name="render">If true, the element will be rendered.</param>
293
    /// <exception cref="ElementNotFoundException">Thrown when the element is invalid.</exception>
294
    [Visual]
295
    public static void ActivateElement(Element element, bool render = true)
296
    {
297
        if (!s_elements.Contains(element))
298
        {
299
            throw new ElementNotFoundException("Invalid element. Not found in the window.");
300
        }
301
        if (!element.Visibility)
302
        {
303
            element.ToggleVisibility();
304
        }
305
        if (render)
306
        {
307
            element.RenderElement();
308
        }
309
    }
310

311
    /// <summary>
312
    /// This method attempts to activate the visibility of the first element of the given type.
313
    /// </summary>
314
    /// <param name="render">If true, the element will be rendered.</param>
315
    /// <typeparam name="T">The type of the element.</typeparam>
316
    /// <exception cref="ElementNotFoundException">Thrown when the element is invalid.</exception>
317
    /// <remarks>
318
    /// For more information, refer to the following resources:
319
    /// <list type="bullet">
320
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
321
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/Program.cs">Example Project</a></description></item>
322
    /// </list>
323
    /// </remarks>
324
    [Visual]
325
    public static void ActivateElement<T>(bool render = true)
326
        where T : Element
327
    {
328
        var element =
329
            GetElement<T>()
330
            ?? throw new ElementNotFoundException("Invalid element. Not found in the window.");
331
        if (!element.Visibility)
332
        {
333
            element.ToggleVisibility();
334
        }
335
        if (render)
336
        {
337
            element.RenderElement();
338
        }
339
    }
340

341
    /// <summary>
342
    /// After activating the visibility of an interactive element, this method will return the response for the user.
343
    /// </summary>
344
    /// <param name="clear">If true, the element will be cleared.</param>
345
    /// <typeparam name="T">The type of interactive element.</typeparam>
346
    /// <typeparam name="TResponse">The type of the response (int, string, float...).</typeparam>
347
    /// <returns>The response of the user.</returns>
348
    /// <exception cref="ElementNotFoundException">Thrown when the element is invalid.</exception>
349
    /// <remarks>
350
    /// For more information, refer to the following resources:
351
    /// <list type="bullet">
352
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
353
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/Program.cs">Example Project</a></description></item>
354
    /// </list>
355
    /// </remarks>
356
    [Visual]
357
    public static InteractionEventArgs<TResponse>? GetResponse<T, TResponse>(bool clear = true)
358
        where T : InteractiveElement<TResponse>
359
    {
360
        var element =
361
            GetVisibleElement<T>()
362
            ?? throw new ElementNotFoundException("Invalid element. Not found in the window.");
363
        DeactivateElement<T>(clear);
364
        return element.GetInteractionResponse;
365
    }
366

367
    /// <summary>
368
    /// This method attempts to activate the visibility of all elements.
369
    /// </summary>
370
    /// <remarks>
371
    /// For more information, refer to the following resources:
372
    /// <list type="bullet">
373
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
374
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/Program.cs">Example Project</a></description></item>
375
    /// </list>
376
    /// </remarks>
377
    public static void ActivateAllElements()
378
    {
379
        foreach (var element in s_elements)
48✔
380
        {
381
            if (!element.Visibility)
15✔
382
            {
383
                element.ToggleVisibility();
6✔
384
            }
385
        }
386
    }
9✔
387

388
    /// <summary>
389
    /// This method to deactivate the visibility of the element with the given id.
390
    /// </summary>
391
    /// <param name="id">The id of the element.</param>
392
    /// <param name="clear">If true, the element will be cleared.</param>
393
    /// <exception cref="ArgumentOutOfRangeException">Thrown when the id is out of range.</exception>
394
    /// <remarks>
395
    /// For more information, refer to the following resources:
396
    /// <list type="bullet">
397
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
398
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/Program.cs">Example Project</a></description></item>
399
    /// </list>
400
    /// </remarks>
401
    public static void DeactivateElement(int id, bool clear = true)
402
    {
403
        if (id < 0 || id >= s_elements.Count)
6✔
404
        {
405
            throw new ArgumentOutOfRangeException(nameof(id), "Invalid element ID.");
3✔
406
        }
407
        if (s_elements[id].Visibility)
3✔
408
        {
409
            s_elements[id].ToggleVisibility();
3✔
410
            if (clear)
3✔
411
            {
412
                s_elements[id].Clear();
3✔
413
            }
414
        }
415
        Render();
3✔
416
    }
3✔
417

418
    /// <summary>
419
    /// This method deactivate the visibility of the element with the given type.
420
    /// </summary>
421
    /// <param name="element">The element to be deactivated.</param>
422
    /// <param name="clear">If true, the element will be cleared.</param>
423
    /// <exception cref="ElementNotFoundException">Thrown when the element is invalid.</exception>
424
    /// <remarks>
425
    /// For more information, refer to the following resources:
426
    /// <list type="bullet">
427
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
428
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/Program.cs">Example Project</a></description></item>
429
    /// </list>
430
    /// </remarks>
431
    public static void DeactivateElement(Element element, bool clear = true)
432
    {
433
        if (!s_elements.Contains(element))
9✔
434
        {
435
            throw new ElementNotFoundException("Invalid element. Not found in the window.");
3✔
436
        }
437

438
        if (element.Visibility)
6✔
439
        {
440
            element.ToggleVisibility();
6✔
441
            if (clear)
6✔
442
            {
443
                element.Clear();
3✔
444
            }
445
        }
446
    }
6✔
447

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

477
    /// <summary>
478
    /// This method deactivate the visibility of all elements.
479
    /// </summary>
480
    /// <remarks>
481
    /// For more information, refer to the following resources:
482
    /// <list type="bullet">
483
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
484
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/Program.cs">Example Project</a></description></item>
485
    /// </list>
486
    /// </remarks>
487
    public static void DeactivateAllElements()
488
    {
489
        foreach (var element in s_elements)
12✔
490
        {
491
            if (element.Visibility)
3✔
492
            {
493
                element.ToggleVisibility();
3✔
494
            }
495
        }
496
        Render();
3✔
497
    }
3✔
498
    #endregion
499

500
    #region Utility Methods: AllowVisibilityToggle, GetLineAvailable, Clear, StopExecution, RenderOne, Refresh
501
    [ExcludeFromCodeCoverage]
502
    private static void UpdateIDs()
503
    {
504
        for (int i = 0; i < s_elements.Count; i++)
505
        {
506
            s_elements[i].Id = i;
507
        }
508
    }
509

510
    /// <summary>
511
    /// This method checks if the element can be toggled to visible.
512
    /// </summary>
513
    /// <param name="id">The id of the element.</param>
514
    /// <returns>True if the element can be toggled to visible, false otherwise.</returns>
515
    public static bool AllowVisibilityToggle(int id)
516
    {
517
        if (s_elements[id].IsInteractive)
156✔
518
        {
519
            int numberOfVisibleInteractiveElements = s_elements.Count(element =>
33✔
520
                element.IsInteractive && element.Visibility
39✔
521
            );
33✔
522
            return numberOfVisibleInteractiveElements == 0;
33✔
523
        }
524
        else
525
        {
526
            int numberOfVisibleElements = s_elements.Count(element =>
123✔
527
                element.GetType() == s_elements[id].GetType() && element.Visibility
150✔
528
            );
123✔
529
            return numberOfVisibleElements < s_elements[id].MaxNumberOfThisElement;
123✔
530
        }
531
    }
532

533
    /// <summary>
534
    /// Gives the last line available to draw an element on the console from a placement.
535
    /// </summary>
536
    /// <param name="placement">The placement of the element.</param>
537
    /// <returns>The last line available to draw an element on the console from a placement.</returns>
538
    /// <exception cref="ArgumentOutOfRangeException">Thrown when the placement is invalid.</exception>
539
    /// <remarks>
540
    /// For more information, refer to the following resources:
541
    /// <list type="bullet">
542
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
543
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/Program.cs">Example Project</a></description></item>
544
    /// </list>
545
    /// </remarks>
546
    public static int GetLineAvailable(Placement placement)
547
    {
548
        return placement switch
702!
549
        {
702✔
550
            Placement.TopCenterFullWidth
702✔
551
                => s_elements
57✔
552
                    .Where(e => e.Placement == Placement.TopCenterFullWidth && e.Visibility)
15✔
553
                    .Sum(e => e.Height)
3✔
554
                    + s_elements
57✔
555
                        .Where(e => e.Placement == Placement.TopCenter && e.Visibility)
15✔
556
                        .Sum(e => e.Height)
3✔
557
                    + s_elements
57✔
558
                        .Where(e => e.Placement == Placement.TopLeft && e.Visibility)
15✔
559
                        .Sum(e => e.Height)
3✔
560
                    + s_elements
57✔
561
                        .Where(e => e.Placement == Placement.TopRight && e.Visibility)
15✔
562
                        .Sum(e => e.Height),
60✔
563
            Placement.TopCenter
702✔
564
                => s_elements
534✔
565
                    .Where(e => e.Placement == Placement.TopCenterFullWidth && e.Visibility)
33✔
566
                    .Sum(e => e.Height)
24✔
567
                    + s_elements
534✔
568
                        .Where(e => e.Placement == Placement.TopCenter && e.Visibility)
33✔
569
                        .Sum(e => e.Height),
534✔
570
            Placement.TopLeft
702✔
571
                => s_elements
81✔
572
                    .Where(e => e.Placement == Placement.TopCenterFullWidth && e.Visibility)
6✔
573
                    .Sum(e => e.Height)
3✔
574
                    + s_elements
81✔
575
                        .Where(e => e.Placement == Placement.TopLeft && e.Visibility)
6!
576
                        .Sum(e => e.Height),
81✔
577

702✔
578
            Placement.TopRight
702✔
579
                => s_elements
18✔
580
                    .Where(e => e.Placement == Placement.TopCenterFullWidth && e.Visibility)
9✔
581
                    .Sum(e => e.Height)
3✔
582
                    + s_elements
18✔
583
                        .Where(e => e.Placement == Placement.TopRight && e.Visibility)
9!
584
                        .Sum(e => e.Height),
18✔
585
            Placement.BottomCenterFullWidth
702✔
586
                => Console.WindowHeight
12✔
587
                    - s_elements
12✔
588
                        .Where(e => e.Placement == Placement.BottomCenterFullWidth && e.Visibility)
6!
589
                        .Sum(e => e.Height),
12✔
590
            _ => throw new ArgumentOutOfRangeException(nameof(placement), "Invalid placement.")
×
591
        };
702✔
592
    }
593

594
    /// <summary>
595
    /// This method checks if the line is valid.
596
    /// </summary>
597
    /// <param name="line">The line to be checked.</param>
598
    /// <returns>The line if it is valid.</returns>
599
    /// <exception cref="ArgumentOutOfRangeException">Thrown when the line is out of range.</exception>
600
    /// <remarks>
601
    /// For more information, refer to the following resources:
602
    /// <list type="bullet">
603
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
604
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/Program.cs">Example Project</a></description></item>
605
    /// </list>
606
    /// </remarks>
607
    public static int? CheckLine(int? line)
608
    {
609
        int minLine = 0;
969✔
610
        int maxLine = Console.WindowHeight == 0 ? 0 : Console.WindowHeight - 1;
969!
611
        if (line is null)
969✔
612
        {
613
            return line;
681✔
614
        }
615
        if (line < minLine || line > maxLine)
288✔
616
        {
617
            throw new ArgumentOutOfRangeException(
15✔
618
                nameof(line),
15✔
619
                $"Invalid line. The line must be between 0 and {maxLine}."
15✔
620
            );
15✔
621
        }
622
        return line;
273✔
623
    }
624

625
    /// <summary>
626
    /// This method clears the window.
627
    /// </summary>
628
    /// <param name="continuous">If true, the window will be cleared continuously.</param>
629
    /// <returns>True if the window is successfully cleared, false otherwise.</returns>
630
    /// <remarks>
631
    /// For more information, refer to the following resources:
632
    /// <list type="bullet">
633
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
634
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/Program.cs">Example Project</a></description></item>
635
    /// </list>
636
    /// </remarks>
637
    public static bool Clear(bool continuous = false)
638
    {
639
        if (continuous)
15✔
640
        {
641
            for (int i = 0; i < Console.WindowHeight; i++)
6!
642
            {
643
                Core.WriteContinuousString("".PadRight(Console.WindowWidth), i, false, 100, 10);
×
644
            }
645
        }
646
        else
647
        {
648
            for (int i = 0; i < Console.WindowHeight; i++)
24!
649
            {
650
                Core.WritePositionedString(
×
651
                    "".PadRight(Console.WindowWidth),
×
652
                    TextAlignment.Center,
×
653
                    false,
×
654
                    i
×
655
                );
×
656
            }
657
        }
658
        return true;
15✔
659
    }
660

661
    /// <summary>
662
    /// This method stops the execution of the program until a key is pressed.
663
    /// </summary>
664
    /// <remarks>
665
    /// For more information, refer to the following resources:
666
    /// <list type="bullet">
667
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
668
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/Program.cs">Example Project</a></description></item>
669
    /// </list>
670
    /// </remarks>
671
    [Visual]
672
    public static void StopExecution(ConsoleKey key = ConsoleKey.Enter)
673
    {
674
        // wait until the user presses a key
675
        while (Console.ReadKey(intercept: true).Key != key)
676
        {
677
            Thread.Sleep(10);
678
        }
679
    }
680

681
    /// <summary>
682
    /// This method draws the element with the given id on the console.
683
    /// </summary>
684
    /// <param name="id">The id of the element.</param>
685
    /// <exception cref="ElementNotFoundException">Thrown when the id is out of range.</exception>
686
    /// <returns>True if the element is successfully drawn, false otherwise.</returns>
687
    /// <remarks>
688
    /// For more information, refer to the following resources:
689
    /// <list type="bullet">
690
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
691
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/Program.cs">Example Project</a></description></item>
692
    /// </list>
693
    /// </remarks>
694
    public static bool RenderOneElement(int id)
695
    {
696
        if (id < 0 || id >= s_elements.Count)
6✔
697
        {
698
            throw new ElementNotFoundException("Invalid element ID.");
3✔
699
        }
700
        s_elements[id].RenderElement();
3✔
701
        return true;
3✔
702
    }
703

704
    /// <summary>
705
    /// This method draws the given element on the console.
706
    /// </summary>
707
    /// <param name="element">The element to be drawn.</param>
708
    /// <exception cref="ElementNotFoundException">Thrown when the element is invalid.</exception>
709
    /// <returns>True if the element is successfully drawn, false otherwise.</returns>
710
    /// <remarks>
711
    /// For more information, refer to the following resources:
712
    /// <list type="bullet">
713
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
714
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/Program.cs">Example Project</a></description></item>
715
    /// </list>
716
    /// </remarks>
717
    public static bool RenderOneElement(Element element)
718
    {
719
        if (element == null || !s_elements.Contains(element))
6✔
720
        {
721
            throw new ElementNotFoundException("Invalid element. Not found in the window.");
3✔
722
        }
723

724
        element.RenderElement();
3✔
725
        return true;
3✔
726
    }
727

728
    /// <summary>
729
    /// This method draws all the non interactive elements of the window on the console.
730
    /// </summary>
731
    /// <remarks>
732
    /// For more information, refer to the following resources:
733
    /// <list type="bullet">
734
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
735
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/Program.cs">Example Project</a></description></item>
736
    /// </list>
737
    /// </remarks>
738
    public static void Render()
739
    {
740
        Clear();
12✔
741
        foreach (var element in s_elements)
48✔
742
        {
743
            element.RenderElement();
12✔
744
        }
745
    }
12✔
746

747
    /// <summary>
748
    /// This method is called to refresh the window when the size of the console is changed.
749
    /// </summary>
750
    /// <returns>True if the window is refreshed, false otherwise.</returns>
751
    public static bool OnResize()
752
    {
753
        if (Core.IsScreenUpdated)
6✔
754
        {
755
            Core.SetConsoleDimensions();
3✔
756
            Render();
3✔
757
            return true;
3✔
758
        }
759
        return false;
3✔
760
    }
761

762
    /// <summary>
763
    /// This method draws all the space of the elements of the window on the console.
764
    /// </summary>
765
    /// <returns>True if the space of the elements is successfully drawn, false otherwise.</returns>
766
    /// <remarks>
767
    /// For more information, refer to the following resources:
768
    /// <list type="bullet">
769
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
770
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/Program.cs">Example Project</a></description></item>
771
    /// </list>
772
    /// </remarks>
773
    public static bool RenderAllElementsSpace()
774
    {
775
        foreach (var element in s_elements)
12✔
776
        {
777
            element.RenderElementSpace();
3✔
778
        }
779
        return true;
3✔
780
    }
781

782
    /// <summary>
783
    /// This method closes the window and exit the program.
784
    /// </summary>
785
    /// <remarks>
786
    /// For more information, refer to the following resources:
787
    /// <list type="bullet">
788
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
789
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/Program.cs">Example Project</a></description></item>
790
    /// </list>
791
    /// </remarks>
792
    [ExcludeFromCodeCoverage]
793
    public static void Close()
794
    {
795
        Core.LoadTerminalColorPanel();
796
        Clear(true);
797
        Console.CursorVisible = true;
798
        Environment.Exit(0);
799
    }
800
    #endregion
801
}
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