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

MorganKryze / ConsoleAppVisuals / 8114215569

01 Mar 2024 04:29PM UTC coverage: 85.767% (-9.3%) from 95.093%
8114215569

push

github

MorganKryze
🤖 moved to publish

865 of 1072 branches covered (80.69%)

Branch coverage included in aggregate %.

1708 of 1928 relevant lines covered (88.59%)

273.5 hits per line

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

65.07
/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;
105✔
51

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

57
    /// <summary>
58
    /// Gives the list of elements in the window.
59
    /// </summary>
60
    public static List<Element> Elements => s_elements;
39✔
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);
120✔
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;
66✔
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)
15✔
111
        {
112
            throw new ArgumentOutOfRangeException(nameof(id), "Invalid element ID.");
6✔
113
        }
114
        return (T)s_elements[id];
9✔
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)
30✔
133
            as T;
18✔
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)
396✔
150
        {
151
            element.Id = NextId;
99✔
152
            s_elements.Add(element);
99✔
153
            if (AllowVisibilityToggle(element.Id))
99✔
154
            {
155
                element.ToggleVisibility();
96✔
156
            }
157
        }
158
    }
99✔
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)
9✔
176
        {
177
            throw new ArgumentOutOfRangeException(nameof(id), "Invalid element ID.");
6✔
178
        }
179
        s_elements.Insert(id, element);
3✔
180
    }
3✔
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 =
12✔
199
            GetElement<T>()
12✔
200
            ?? throw new ElementNotFoundException("Invalid element. Not found in the window.");
12✔
201
        var state = s_elements.Remove(element);
9✔
202
        UpdateIDs();
9✔
203
        return state;
9✔
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)
9✔
221
        {
222
            throw new ArgumentOutOfRangeException(nameof(id), "Invalid element ID.");
6✔
223
        }
224
        s_elements.RemoveAt(id);
3✔
225
        UpdateIDs();
3✔
226
    }
3✔
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;
9✔
244

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

254
        UpdateIDs();
6✔
255
        return state;
6✔
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();
1,014✔
271
    }
1,014✔
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
            s_elements[id].RenderElement();
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
            element.RenderElement();
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
            element.RenderElement();
355
        }
356
    }
357

358
    /// <summary>
359
    /// After activating the visibility of an interactive element, this method will return the response for the user.
360
    /// </summary>
361
    /// <param name="clear">If true, the element will be cleared afterward.</param>
362
    /// <typeparam name="T">The type of interactive element.</typeparam>
363
    /// <typeparam name="TResponse">The type of the response (int, string, float...).</typeparam>
364
    /// <returns>The response of the user.</returns>
365
    /// <exception cref="ElementNotFoundException">Thrown when the element is invalid.</exception>
366
    /// <remarks>
367
    /// For more information, refer to the following resources:
368
    /// <list type="bullet">
369
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
370
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
371
    /// </list>
372
    /// </remarks>
373
    [Visual]
374
    public static InteractionEventArgs<TResponse>? GetResponse<T, TResponse>(bool clear = true)
375
        where T : InteractiveElement<TResponse>
376
    {
377
        var element =
378
            GetVisibleElement<T>()
379
            ?? throw new ElementNotFoundException("Invalid element. Not found in the window.");
380
        DeactivateElement<T>(clear);
381
        return element.GetInteractionResponse;
382
    }
383

384
    /// <summary>
385
    /// This method attempts to activate the visibility of all elements.
386
    /// </summary>
387
    /// <remarks>
388
    /// For more information, refer to the following resources:
389
    /// <list type="bullet">
390
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
391
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
392
    /// </list>
393
    /// </remarks>
394
    public static void ActivateAllElements()
395
    {
396
        foreach (var element in s_elements)
24✔
397
        {
398
            if (!element.Visibility)
6!
399
            {
400
                element.ToggleVisibility();
×
401
            }
402
        }
403
    }
6✔
404

405
    /// <summary>
406
    /// This method to deactivate the visibility of the element with the given id.
407
    /// </summary>
408
    /// <param name="id">The id of the element.</param>
409
    /// <param name="clear">If true, the element will be cleared from the console.</param>
410
    /// <exception cref="ArgumentOutOfRangeException">Thrown when the id is out of range.</exception>
411
    /// <remarks>
412
    /// For more information, refer to the following resources:
413
    /// <list type="bullet">
414
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
415
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
416
    /// </list>
417
    /// </remarks>
418
    public static void DeactivateElement(int id, bool clear = true)
419
    {
420
        if (id < 0 || id >= s_elements.Count)
6✔
421
        {
422
            throw new ArgumentOutOfRangeException(nameof(id), "Invalid element ID.");
3✔
423
        }
424
        if (s_elements[id].Visibility)
3✔
425
        {
426
            s_elements[id].ToggleVisibility();
3✔
427
            if (clear)
3✔
428
            {
429
                s_elements[id].Clear();
3✔
430
            }
431
        }
432
    }
3✔
433

434
    /// <summary>
435
    /// This method deactivate the visibility of the element with the given type.
436
    /// </summary>
437
    /// <param name="element">The element to be deactivated.</param>
438
    /// <param name="clear">If true, the element will be cleared from the console.</param>
439
    /// <exception cref="ElementNotFoundException">Thrown when the element is invalid.</exception>
440
    /// <remarks>
441
    /// For more information, refer to the following resources:
442
    /// <list type="bullet">
443
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
444
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
445
    /// </list>
446
    /// </remarks>
447
    public static void DeactivateElement(Element element, bool clear = true)
448
    {
449
        if (!s_elements.Contains(element))
9✔
450
        {
451
            throw new ElementNotFoundException("Invalid element. Not found in the window.");
3✔
452
        }
453

454
        if (element.Visibility)
6✔
455
        {
456
            element.ToggleVisibility();
6✔
457
            if (clear)
6✔
458
            {
459
                element.Clear();
3✔
460
            }
461
        }
462
    }
6✔
463

464
    /// <summary>
465
    /// This method deactivate the visibility of the first element with the given type.
466
    /// </summary>
467
    /// <param name="clear">If true, the element will be cleared.</param>
468
    /// <typeparam name="T">The type of the element.</typeparam>
469
    /// <exception cref="ElementNotFoundException">Thrown when the element is invalid.</exception>
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 DeactivateElement<T>(bool clear = true)
478
        where T : Element
479
    {
480
        var element =
9✔
481
            GetVisibleElement<T>()
9✔
482
            ?? throw new ElementNotFoundException("Invalid element. Not found in the window.");
9✔
483
        if (element.Visibility)
6✔
484
        {
485
            element.ToggleVisibility();
6✔
486
            if (clear)
6✔
487
            {
488
                element.Clear();
3✔
489
            }
490
        }
491
    }
6✔
492

493
    /// <summary>
494
    /// This method deactivate the visibility of all elements.
495
    /// </summary>
496
    /// <remarks>
497
    /// For more information, refer to the following resources:
498
    /// <list type="bullet">
499
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
500
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
501
    /// </list>
502
    /// </remarks>
503
    public static void DeactivateAllElements()
504
    {
505
        foreach (var element in s_elements)
12✔
506
        {
507
            if (element.Visibility)
3✔
508
            {
509
                element.ToggleVisibility();
3✔
510
            }
511
        }
512
    }
3✔
513
    #endregion
514

515
    #region Utility Methods: AllowVisibilityToggle, GetLineAvailable, Clear, StopExecution, Refresh
516
    [ExcludeFromCodeCoverage]
517
    private static void UpdateIDs()
518
    {
519
        for (int i = 0; i < s_elements.Count; i++)
520
        {
521
            s_elements[i].Id = i;
522
        }
523
    }
524

525
    /// <summary>
526
    /// This method checks if the element can be toggled to visible.
527
    /// </summary>
528
    /// <param name="id">The id of the element.</param>
529
    /// <returns>True if the element can be toggled to visible, false otherwise.</returns>
530
    public static bool AllowVisibilityToggle(int id)
531
    {
532
        if (s_elements[id].IsInteractive)
198✔
533
        {
534
            int numberOfVisibleInteractiveElements = s_elements.Count(element =>
156✔
535
                element.IsInteractive && element.Visibility
168✔
536
            );
156✔
537
            return numberOfVisibleInteractiveElements == 0;
156✔
538
        }
539
        else
540
        {
541
            int numberOfVisibleElements = s_elements.Count(element =>
42✔
542
                element.GetType() == s_elements[id].GetType() && element.Visibility
48!
543
            );
42✔
544
            return numberOfVisibleElements < s_elements[id].MaxNumberOfThisElement;
42✔
545
        }
546
    }
547

548
    /// <summary>
549
    /// This method gets the last line available to draw an element on the console from a placement.
550
    /// </summary>
551
    /// <param name="placement">The placement of the element.</param>
552
    /// <returns>The last line available to draw an element on the console from a placement.</returns>
553
    /// <exception cref="ArgumentOutOfRangeException">Thrown when the placement is invalid.</exception>
554
    /// <remarks>
555
    /// For more information, refer to the following resources:
556
    /// <list type="bullet">
557
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
558
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
559
    /// </list>
560
    /// </remarks>
561
    public static int GetLineAvailable(Placement placement)
562
    {
563
        return placement switch
3!
564
        {
3✔
565
            Placement.TopCenterFullWidth
3✔
566
                => s_elements
×
567
                    .Where(e => e.Placement == Placement.TopCenterFullWidth && e.Visibility)
×
568
                    .Sum(e => e.Height)
×
569
                    + s_elements
×
570
                        .Where(e => e.Placement == Placement.TopCenter && e.Visibility)
×
571
                        .Sum(e => e.Height)
×
572
                    + s_elements
×
573
                        .Where(e => e.Placement == Placement.TopLeft && e.Visibility)
×
574
                        .Sum(e => e.Height)
×
575
                    + s_elements
×
576
                        .Where(e => e.Placement == Placement.TopRight && e.Visibility)
×
577
                        .Sum(e => e.Height),
×
578
            Placement.TopCenter
3✔
579
                => s_elements
×
580
                    .Where(e => e.Placement == Placement.TopCenterFullWidth && e.Visibility)
×
581
                    .Sum(e => e.Height)
×
582
                    + s_elements
×
583
                        .Where(e => e.Placement == Placement.TopCenter && e.Visibility)
×
584
                        .Sum(e => e.Height),
×
585
            Placement.TopLeft
3✔
586
                => s_elements
×
587
                    .Where(e => e.Placement == Placement.TopCenterFullWidth && e.Visibility)
×
588
                    .Sum(e => e.Height)
×
589
                    + s_elements
×
590
                        .Where(e => e.Placement == Placement.TopLeft && e.Visibility)
×
591
                        .Sum(e => e.Height),
×
592

3✔
593
            Placement.TopRight
3✔
594
                => s_elements
×
595
                    .Where(e => e.Placement == Placement.TopCenterFullWidth && e.Visibility)
×
596
                    .Sum(e => e.Height)
×
597
                    + s_elements
×
598
                        .Where(e => e.Placement == Placement.TopRight && e.Visibility)
×
599
                        .Sum(e => e.Height),
×
600
            Placement.BottomCenterFullWidth
3✔
601
                => Console.WindowHeight
3✔
602
                    - s_elements
3✔
603
                        .Where(e => e.Placement == Placement.BottomCenterFullWidth && e.Visibility)
×
604
                        .Sum(e => e.Height),
3✔
605
            _ => throw new ArgumentOutOfRangeException(nameof(placement), "Invalid placement.")
×
606
        };
3✔
607
    }
608

609
    /// <summary>
610
    /// This method checks if the line is valid under the console constraints.
611
    /// </summary>
612
    /// <param name="line">The line to be checked.</param>
613
    /// <returns>The line if it is valid.</returns>
614
    /// <exception cref="ArgumentOutOfRangeException">Thrown when the line is out of range.</exception>
615
    /// <remarks>
616
    /// For more information, refer to the following resources:
617
    /// <list type="bullet">
618
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
619
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
620
    /// </list>
621
    /// </remarks>
622
    public static int? CheckLine(int? line)
623
    {
624
        int minLine = 0;
9✔
625
        int maxLine = Console.WindowHeight == 0 ? 0 : Console.WindowHeight - 1;
9!
626
        if (line is null)
9✔
627
        {
628
            return line;
3✔
629
        }
630
        if (line < minLine || line > maxLine)
6✔
631
        {
632
            throw new ArgumentOutOfRangeException(
3✔
633
                nameof(line),
3✔
634
                $"Invalid line. The line must be between 0 and {maxLine}."
3✔
635
            );
3✔
636
        }
637
        return line;
3✔
638
    }
639

640
    /// <summary>
641
    /// This method stops the execution of the program until a key is pressed.
642
    /// </summary>
643
    /// <remarks>
644
    /// For more information, refer to the following resources:
645
    /// <list type="bullet">
646
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
647
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
648
    /// </list>
649
    /// </remarks>
650
    [Visual]
651
    public static void StopExecution(ConsoleKey key = ConsoleKey.Enter)
652
    {
653
        while (Console.ReadKey(intercept: true).Key != key)
654
        {
655
            Thread.Sleep(10);
656
        }
657
    }
658

659
    /// <summary>
660
    /// This method draws all visible elements of the window on the console.
661
    /// </summary>
662
    /// <remarks>
663
    /// For more information, refer to the following resources:
664
    /// <list type="bullet">
665
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
666
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
667
    /// </list>
668
    /// </remarks>
669
    public static void Render()
670
    {
671
        Clear();
×
672
        Core.IsScreenUpdated();
×
673
        foreach (var element in s_elements)
×
674
        {
675
            element.RenderElement();
×
676
        }
677
    }
×
678

679
    /// <summary>
680
    /// This method draws all given visible elements of the window on the console.
681
    /// </summary>
682
    /// <param name="elements">The elements to be drawn.</param>
683
    /// <exception cref="ElementNotFoundException">Thrown when the element is not found in the window.</exception>
684
    /// <remarks>
685
    /// For more information, refer to the following resources:
686
    /// <list type="bullet">
687
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
688
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
689
    /// </list>
690
    /// </remarks>
691
    public static void Render(params Element[] elements)
692
    {
693
        if (Core.IsScreenUpdated())
×
694
        {
695
            Render();
×
696
            return;
×
697
        }
698

699
        foreach (var element in elements)
×
700
        {
701
            if (!s_elements.Contains(element))
×
702
            {
703
                throw new ElementNotFoundException($"Element {element} is not in the Window.");
×
704
            }
705
            element.RenderElement();
×
706
        }
707
    }
×
708

709
    /// <summary>
710
    /// This method draws all the space of the visible elements of the window on the console.
711
    /// </summary>
712
    /// <returns>True if the space of the elements is successfully drawn, false otherwise.</returns>
713
    /// <remarks>
714
    /// For more information, refer to the following resources:
715
    /// <list type="bullet">
716
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
717
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
718
    /// </list>
719
    /// </remarks>
720
    public static bool RenderElementsSpace()
721
    {
722
        foreach (var element in s_elements)
12✔
723
        {
724
            element.RenderElementSpace();
3✔
725
        }
726
        return true;
3✔
727
    }
728

729
    /// <summary>
730
    /// This method clears the console.
731
    /// </summary>
732
    /// <param name="continuous">If true, the window will be cleared continuously.</param>
733
    /// <returns>True if the window is successfully cleared, false otherwise.</returns>
734
    /// <remarks>
735
    /// For more information, refer to the following resources:
736
    /// <list type="bullet">
737
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
738
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
739
    /// </list>
740
    /// </remarks>
741
    public static bool Clear(bool continuous = false)
742
    {
743
        if (continuous)
3!
744
        {
745
            for (int i = 0; i < Console.WindowHeight; i++)
6!
746
            {
747
                Core.WriteContinuousString("".PadRight(Console.WindowWidth), i, false, 100, 10);
×
748
            }
749
        }
750
        else
751
        {
752
            for (int i = 0; i < Console.WindowHeight; i++)
×
753
            {
754
                Core.WritePositionedString(
×
755
                    "".PadRight(Console.WindowWidth),
×
756
                    TextAlignment.Center,
×
757
                    false,
×
758
                    i
×
759
                );
×
760
            }
761
        }
762
        return true;
3✔
763
    }
764

765
    /// <summary>
766
    /// This method clears the window and exit the program.
767
    /// </summary>
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
    [ExcludeFromCodeCoverage]
776
    public static void Close()
777
    {
778
        Core.LoadTerminalColorPanel();
779
        Clear(true);
780
        Console.CursorVisible = true;
781
        Environment.Exit(0);
782
    }
783
    #endregion
784
}
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