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

MorganKryze / ConsoleAppVisuals / 14841854468

05 May 2025 05:00PM UTC coverage: 96.045% (-0.2%) from 96.208%
14841854468

push

github

MorganKryze
📖 docs: new RN update

958 of 1071 branches covered (89.45%)

Branch coverage included in aggregate %.

2175 of 2191 relevant lines covered (99.27%)

246.13 hits per line

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

86.96
/src/ConsoleAppVisuals/elements/animated_elements/FakeLoadingBar.cs
1
/*
2
    Copyright (c) 2024 Yann M. Vidamment (MorganKryze)
3
    Licensed under GNU GPL v2.0. See full license at: https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/LICENSE.md
4
*/
5
namespace ConsoleAppVisuals.AnimatedElements;
6

7
/// <summary>
8
/// The <see cref="FakeLoadingBar"/> is an animated element that simulates a loading bar with a fixed duration.
9
/// </summary>
10
/// <remarks>
11
/// For more information, consider visiting the documentation available <a href="https://morgankryze.github.io/ConsoleAppVisuals/">here</a>.
12
/// </remarks>
13
public class FakeLoadingBar : AnimatedElement
14
{
15
    #region Constants
16
    const char LOADING_BAR_CHAR = 'â–ˆ';
17
    const int DEFAULT_HEIGHT = 5;
18
    const string DEFAULT_TEXT = "Loading ...";
19
    const int DEFAULT_WIDTH = 0;
20
    const Placement DEFAULT_PLACEMENT = Placement.TopCenter;
21
    const int DEFAULT_PROCESS_DURATION = 2000;
22
    const int DEFAULT_ADDITIONAL_DURATION = 1000;
23
    const BordersType DEFAULT_BORDERS_TYPE = BordersType.SingleStraight;
24
    #endregion
25

26
    #region Fields
27
    private string _text;
28
    private int _barWidth;
29
    private Placement _placement;
30
    private int _processDuration;
31
    private int _additionalDuration;
32
    private readonly Borders _borders;
33
    #endregion
34

35
    #region Default Properties
36
    /// <summary>
37
    /// Gets the height of the loading bar.
38
    /// </summary>
39
    public override int Height => DEFAULT_HEIGHT + 2;
1✔
40

41
    /// <summary>
42
    /// Gets the width of the loading bar.
43
    /// </summary>
44
    public override int Width => (_barWidth > 0 ? _barWidth : _text.Length) + 6;
2!
45

46
    /// <summary>
47
    /// Gets the placement of the loading bar.
48
    /// </summary>
49
    public override Placement Placement => _placement;
46✔
50
    #endregion
51

52
    #region Properties
53
    /// <summary>
54
    /// Gets the text of the loading bar.
55
    /// </summary>
56
    public string Text => _text;
4✔
57

58
    /// <summary>
59
    /// Gets the explicit width of the loading bar.
60
    /// </summary>
61
    public int BarWidth => _barWidth;
×
62

63
    /// <summary>
64
    /// Gets the duration of the loading bar.
65
    /// </summary>
66
    public int ProcessDuration => _processDuration;
2✔
67

68
    /// <summary>
69
    /// Gets the additional duration of the loading bar at the end.
70
    /// </summary>
71
    public int AdditionalDuration => _additionalDuration;
2✔
72

73
    /// <summary>
74
    /// Gets the borders of the loading bar.
75
    /// </summary>
76
    public Borders Borders => _borders;
×
77

78
    /// <summary>
79
    /// Gets the border type of the loading bar.
80
    /// </summary>
81
    public BordersType BordersType => _borders.Type;
×
82
    #endregion
83

84
    #region Constructor
85
    /// <summary>
86
    /// The <see cref="FakeLoadingBar"/> is an animated element that simulates a loading bar with a fixed duration.
87
    /// </summary>
88
    /// <param name="text">The text of the loading bar.</param>
89
    /// <param name="barWidth">The width of the loading bar. If 0 or less than text length, text length is used.</param>
90
    /// <param name="placement">The placement of the loading bar.</param>
91
    /// <param name="processDuration">The duration of the loading bar.</param>
92
    /// <param name="additionalDuration">The additional duration of the loading bar at the end.</param>
93
    /// <param name="bordersType">The type of borders to display around the loading bar.</param>
94
    /// <remarks>
95
    /// For more information, consider visiting the documentation available <a href="https://morgankryze.github.io/ConsoleAppVisuals/">here</a>.
96
    /// </remarks>
97
    public FakeLoadingBar(
27✔
98
        string text = DEFAULT_TEXT,
27✔
99
        int barWidth = DEFAULT_WIDTH,
27✔
100
        Placement placement = DEFAULT_PLACEMENT,
27✔
101
        int processDuration = DEFAULT_PROCESS_DURATION,
27✔
102
        int additionalDuration = DEFAULT_ADDITIONAL_DURATION,
27✔
103
        BordersType bordersType = DEFAULT_BORDERS_TYPE
27✔
104
    )
27✔
105
    {
106
        // Account for border size in max width calculation
107
        if (Console.WindowWidth - 5 >= 0)
27!
108
        {
109
            _text = text[..Math.Min(text.Length, Console.WindowWidth - 5)];
×
110
        }
111
        else
112
        {
113
            _text = text[..Math.Min(text.Length, 0)];
27✔
114
        }
115

116
        // Set the bar width, ensuring it's at least as wide as the text
117
        _barWidth = barWidth > 0 ? Math.Max(barWidth, _text.Length) : 0;
27!
118

119
        _placement = placement;
27✔
120
        _processDuration = processDuration;
27✔
121
        _additionalDuration = additionalDuration;
27✔
122
        _borders = new Borders(bordersType);
27✔
123
    }
27✔
124
    #endregion
125

126
    #region Update Methods
127
    /// <summary>
128
    /// Updates the text of the loading bar.
129
    /// </summary>
130
    /// <param name="text">The new text of the loading bar.</param>
131
    /// <remarks>
132
    /// For more information, consider visiting the documentation available <a href="https://morgankryze.github.io/ConsoleAppVisuals/">here</a>.
133
    /// </remarks>
134
    public void UpdateText(string text)
135
    {
136
        if (text.Length == 0)
5✔
137
        {
138
            throw new ArgumentException("The text cannot be empty.", nameof(text));
1✔
139
        }
140
        _text = text;
4✔
141
    }
4✔
142

143
    /// <summary>
144
    /// Updates the placement of the loading bar.
145
    /// </summary>
146
    /// <param name="placement">The new placement of the loading bar.</param>
147
    /// <remarks>
148
    /// For more information, consider visiting the documentation available <a href="https://morgankryze.github.io/ConsoleAppVisuals/">here</a>.
149
    /// </remarks>
150
    public void UpdatePlacement(Placement placement)
151
    {
152
        _placement = placement;
1✔
153
    }
1✔
154

155
    /// <summary>
156
    /// Updates the duration of the loading bar.
157
    /// </summary>
158
    /// <param name="processDuration">The new duration of the loading bar.</param>
159
    /// <exception cref="ArgumentOutOfRangeException">Throw when the process duration is negative.</exception>
160
    /// <remarks>
161
    /// For more information, consider visiting the documentation available <a href="https://morgankryze.github.io/ConsoleAppVisuals/">here</a>.
162
    /// </remarks>
163
    public void UpdateProcessDuration(int processDuration)
164
    {
165
        if (processDuration < 0)
2✔
166
        {
167
            throw new ArgumentOutOfRangeException(
1✔
168
                nameof(processDuration),
1✔
169
                "The process duration must be greater than or equal to 0."
1✔
170
            );
1✔
171
        }
172
        _processDuration = processDuration;
1✔
173
    }
1✔
174

175
    /// <summary>
176
    /// Updates the additional duration of the loading bar.
177
    /// </summary>
178
    /// <param name="additionalDuration">The new additional duration of the loading bar.</param>
179
    /// <exception cref="ArgumentOutOfRangeException">The additional duration of the loading bar cannot be negative.</exception>
180
    /// <remarks>
181
    /// For more information, consider visiting the documentation available <a href="https://morgankryze.github.io/ConsoleAppVisuals/">here</a>.
182
    /// </remarks>
183
    public void UpdateAdditionalDuration(int additionalDuration)
184
    {
185
        if (additionalDuration < 0)
2✔
186
        {
187
            throw new ArgumentOutOfRangeException(
1✔
188
                nameof(additionalDuration),
1✔
189
                "The additional duration must be greater than or equal to 0."
1✔
190
            );
1✔
191
        }
192
        _additionalDuration = additionalDuration;
1✔
193
    }
1✔
194

195
    /// <summary>
196
    /// Updates the borders type of the loading bar.
197
    /// </summary>
198
    /// <param name="bordersType">The new border type of the loading bar.</param>
199
    /// <remarks>
200
    /// For more information, consider visiting the documentation available <a href="https://morgankryze.github.io/ConsoleAppVisuals/">here</a>.
201
    /// </remarks>
202
    public void UpdateBordersType(BordersType bordersType)
203
    {
204
        _borders.UpdateBordersType(bordersType);
×
205
    }
×
206

207
    /// <summary>
208
    /// Updates the width of the loading bar.
209
    /// </summary>
210
    /// <param name="barWidth">The new width of the loading bar. If 0, text length is used.</param>
211
    /// <remarks>
212
    /// For more information, consider visiting the documentation available <a href="https://morgankryze.github.io/ConsoleAppVisuals/">here</a>.
213
    /// </remarks>
214
    public void UpdateBarWidth(int barWidth)
215
    {
216
        if (barWidth < 0)
2✔
217
        {
218
            throw new ArgumentOutOfRangeException(
1✔
219
                nameof(barWidth),
1✔
220
                "The bar width must be greater than or equal to 0."
1✔
221
            );
1✔
222
        }
223
        _barWidth = barWidth;
1✔
224
    }
1✔
225
    #endregion
226

227
    #region Rendering
228
    /// <summary>
229
    /// Defines the actions to perform when the element is called to be rendered on the console.
230
    /// </summary>
231
    [Visual]
232
    protected override void RenderElementActions()
233
    {
234
        // Determine content width (text or explicit width, whichever is greater)
235
        int contentWidth = _barWidth > 0 ? _barWidth : _text.Length;
236

237
        // Calculate consistent widths
238
        int outerWidth = contentWidth + 4; // +4 for consistent outer border (includes padding)
239
        int innerWidth = contentWidth; // Inner border width matches content width
240

241
        // Rest of method remains the same, just using contentWidth instead of _text.Length
242

243
        // Get current cursor position to restore later
244
        int originalLeft = Console.CursorLeft;
245
        int originalTop = Console.CursorTop;
246

247
        // OUTER BORDER - TOP
248
        string topBorder =
249
            _borders.TopLeft + new string(_borders.Horizontal, outerWidth) + _borders.TopRight;
250
        Core.WritePositionedString(topBorder, _placement, false, Line, false);
251

252
        // OUTER BORDER - TEXT LINE
253
        string textLine =
254
            _borders.Vertical + " " + _text.PadRight(contentWidth + 2) + " " + _borders.Vertical;
255
        Core.WritePositionedString(textLine, _placement, false, Line + 1, false);
256

257
        // INNER BORDER - TOP
258
        string innerTopBorder =
259
            _borders.Vertical
260
            + " "
261
            + _borders.TopLeft
262
            + new string(_borders.Horizontal, innerWidth)
263
            + _borders.TopRight
264
            + " "
265
            + _borders.Vertical;
266
        Core.WritePositionedString(innerTopBorder, _placement, false, Line + 2, false);
267

268
        // INNER BORDER - EMPTY BAR AREA
269
        string innerEmptyBar =
270
            _borders.Vertical
271
            + " "
272
            + _borders.Vertical
273
            + new string(' ', innerWidth)
274
            + _borders.Vertical
275
            + " "
276
            + _borders.Vertical;
277
        Core.WritePositionedString(innerEmptyBar, _placement, false, Line + 3, false);
278

279
        // INNER BORDER - BOTTOM
280
        string innerBottomBorder =
281
            _borders.Vertical
282
            + " "
283
            + _borders.BottomLeft
284
            + new string(_borders.Horizontal, innerWidth)
285
            + _borders.BottomRight
286
            + " "
287
            + _borders.Vertical;
288
        Core.WritePositionedString(innerBottomBorder, _placement, false, Line + 4, false);
289

290
        // OUTER BORDER - BOTTOM
291
        string bottomBorder =
292
            _borders.BottomLeft
293
            + new string(_borders.Horizontal, outerWidth)
294
            + _borders.BottomRight;
295
        Core.WritePositionedString(bottomBorder, _placement, false, Line + 5, false);
296

297
        // Position cursor for animation
298
        int barLineTop = Line + 3; // Position at the empty bar line
299
        int barLeft;
300

301
        // Calculate horizontal position based on placement
302
        switch (_placement)
303
        {
304
            case Placement.TopLeft:
305
                barLeft = 3; // Left outer border + space + inner border
306
                break;
307
            case Placement.TopRight:
308
                barLeft = Console.WindowWidth - outerWidth + 3;
309
                break;
310
            case Placement.TopCenter:
311
            case Placement.TopCenterFullWidth:
312
            case Placement.BottomCenterFullWidth:
313
            default:
314
                barLeft = (Console.WindowWidth - outerWidth) / 2 + 3;
315
                break;
316
        }
317

318
        // Animate the loading bar inside inner border (limiting to innerWidth)
319
        Console.SetCursorPosition(barLeft - 1, barLineTop);
320
        for (int i = 0; i < innerWidth; i++)
321
        {
322
            Console.Write(LOADING_BAR_CHAR);
323
            Thread.Sleep(_processDuration / innerWidth);
324
        }
325

326
        // Additional wait at the end
327
        Thread.Sleep(_additionalDuration);
328

329
        // Restore cursor position
330
        Console.SetCursorPosition(originalLeft, originalTop);
331
    }
332
    #endregion
333
}
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

© 2025 Coveralls, Inc