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

MorganKryze / ConsoleAppVisuals / 7941534291

17 Feb 2024 12:10PM UTC coverage: 68.805% (+5.5%) from 63.31%
7941534291

push

github

MorganKryze
🚑 fix issue with width of loading bars

606 of 970 branches covered (62.47%)

Branch coverage included in aggregate %.

4 of 6 new or added lines in 2 files covered. (66.67%)

38 existing lines in 4 files now uncovered.

1282 of 1774 relevant lines covered (72.27%)

267.55 hits per line

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

0.0
/src/ConsoleAppVisuals/elements/interactive/IntSelector.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
/// Defines the number selector of the console window.
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 class IntSelector : InteractiveElement<int>
18
{
19
    #region Fields
20
    private readonly string _question;
21
    private readonly int _minimumValue;
22
    private readonly int _maximumValue;
23
    private readonly int _startValue;
24
    private readonly int _step;
25
    private readonly bool _roundedCorners;
26
    private readonly Placement _placement;
27
    private readonly int _line;
28
    #endregion
29

30
    #region Properties
31
    /// <summary>
32
    /// The placement of the selector on the console.
33
    /// </summary>
34
    public override Placement Placement => _placement;
×
35

36
    /// <summary>
37
    /// The line where the selector will be displayed.
38
    /// </summary>
39
    public override int Line => _line;
×
40

41
    /// <summary>
42
    /// The height of the selector.
43
    /// </summary>
44
    public override int Height => 7;
×
45

46
    /// <summary>
47
    /// The width of the selector.
48
    /// </summary>
49
    public override int Width =>
50
        Math.Max(
×
51
            _question.Length,
×
52
            $" {Core.GetSelector.Item1} {BuildNumber(_maximumValue)} {Core.GetSelector.Item2} ".Length
×
53
        );
×
54
    #endregion
55

56
    #region Constructor
57
    /// <summary>
58
    /// The constructor of the intSelector class.
59
    /// </summary>
60
    /// <param name="question">The question to ask the user.</param>
61
    /// <param name="min">The minimum value of the selector.</param>
62
    /// <param name="max">The maximum value of the selector.</param>
63
    /// <param name="start">The start value of the selector.</param>
64
    /// <param name="step">The step of the selector.</param>
65
    /// <param name="placement">The placement of the selector on the console.</param>
66
    /// <param name="line">The line where the selector will be displayed.</param>
67
    /// <param name="roundedCorners">Whether the corners of the selector are rounded.</param>
68
    /// <remarks>
69
    /// For more information, refer to the following resources:
70
    /// <list type="bullet">
71
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
72
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/Program.cs">Example Project</a></description></item>
73
    /// </list>
74
    /// </remarks>
75
    public IntSelector(
×
76
        string question,
×
77
        int min,
×
78
        int max,
×
79
        int start = 0,
×
80
        int step = 100,
×
81
        Placement placement = Placement.TopCenter,
×
82
        int? line = null,
×
83
        bool roundedCorners = false
×
84
    )
×
85
    {
86
        _question = question;
×
87
        _minimumValue = CheckMin(min, max);
×
88
        _maximumValue = CheckMax(min, max);
×
89
        _startValue = CheckStart(start, _minimumValue, _maximumValue);
×
90
        _step = CheckStep(step, _minimumValue, _maximumValue);
×
91
        _placement = placement;
×
92
        _line = Window.CheckLine(line) ?? Window.GetLineAvailable(_placement);
×
93
        _roundedCorners = roundedCorners;
×
94
    }
×
95

96
    private static int CheckMin(int min, int max)
97
    {
98
        if (min > max)
×
99
            throw new ArgumentException(
×
100
                "The minimum value cannot be greater than the maximum value."
×
101
            );
×
102
        return min;
×
103
    }
104

105
    private static int CheckMax(int min, int max)
106
    {
107
        if (max < min)
×
108
            throw new ArgumentException("The maximum value cannot be less than the minimum value.");
×
109
        return max;
×
110
    }
111

112
    private static int CheckStart(int start, int min, int max)
113
    {
114
        if (start < min)
×
115
            throw new ArgumentException("The start value cannot be less than the minimum value.");
×
116
        if (start > max)
×
117
            throw new ArgumentException(
×
118
                "The start value cannot be greater than the maximum value."
×
119
            );
×
120
        return start;
×
121
    }
122

123
    private static int CheckStep(int step, int min, int max)
124
    {
125
        if (step > max - min)
×
126
            throw new ArgumentException(
×
127
                "The step cannot be greater than the difference between the minimum and maximum values."
×
128
            );
×
129
        return step;
×
130
    }
131
    #endregion
132

133
    #region Methods
134
    /// <summary>
135
    /// This method is used to draw the selector on the console.
136
    /// </summary>
137
    [Visual]
138
    protected override void RenderElementActions()
139
    {
140
        Core.WriteContinuousString(_question, _line, default, 1500, 50);
141
        int currentNumber = _startValue;
142
        int lineSelector = _line + 4;
143
        while (true)
144
        {
145
            DisplayChoices(lineSelector, currentNumber);
146

147
            switch (Console.ReadKey(true).Key)
148
            {
149
                case ConsoleKey.UpArrow:
150
                case ConsoleKey.Z:
151
                    currentNumber = NextNumber(Direction.Up, currentNumber);
152
                    break;
153
                case ConsoleKey.DownArrow:
154
                case ConsoleKey.S:
155
                    currentNumber = NextNumber(Direction.Down, currentNumber);
156
                    break;
157
                case ConsoleKey.Enter:
158
                    SendResponse(this, new InteractionEventArgs<int>(Output.Select, currentNumber));
159
                    return;
160
                case ConsoleKey.Escape:
161
                    SendResponse(this, new InteractionEventArgs<int>(Output.Exit, currentNumber));
162
                    return;
163
                default:
164
                    break;
165
            }
166
            Thread.Sleep(1);
167
        }
168
    }
169

170
    [Visual]
171
    void DisplayChoices(int lineSelector, int currentNumber)
172
    {
173
        Core.WritePositionedString(
174
            BuildLine(Direction.Up),
175
            TextAlignment.Center,
176
            false,
177
            lineSelector - 2
178
        );
179
        Core.WritePositionedString(
180
            BuildNumber(NextNumber(Direction.Up, currentNumber)),
181
            TextAlignment.Center,
182
            false,
183
            lineSelector - 1
184
        );
185
        Core.WritePositionedString(
186
            $" {Core.GetSelector.Item1} {BuildNumber(currentNumber)} {Core.GetSelector.Item2} ",
187
            TextAlignment.Center,
188
            true,
189
            lineSelector
190
        );
191
        Core.WritePositionedString(
192
            BuildNumber(NextNumber(Direction.Down, currentNumber)),
193
            TextAlignment.Center,
194
            false,
195
            lineSelector + 1
196
        );
197
        Core.WritePositionedString(
198
            BuildLine(Direction.Down),
199
            TextAlignment.Center,
200
            false,
201
            lineSelector + 2
202
        );
203
    }
204

205
    int NextNumber(Direction direction, int currentNumber)
206
    {
207
        if (direction == Direction.Up)
×
208
        {
209
            if (currentNumber + _step <= _maximumValue)
×
210
                return currentNumber + _step;
×
UNCOV
211
            else if (currentNumber + _step > _maximumValue)
×
UNCOV
212
                return _minimumValue;
×
213
        }
214
        else
215
        {
216
            if (currentNumber - _step >= _minimumValue)
×
217
                return currentNumber - _step;
×
UNCOV
218
            else if (currentNumber - _step < _minimumValue)
×
219
                return _maximumValue;
×
220
        }
UNCOV
221
        return currentNumber;
×
222
    }
223

224
    string BuildLine(Direction direction)
225
    {
226
        string corners = _roundedCorners ? "╭╮╰╯" : "┌┐└┘";
×
227
        StringBuilder line = new();
×
228
        for (int i = 0; i < _maximumValue.ToString().Length + 2; i++)
×
229
            line.Append('─');
×
UNCOV
230
        if (direction == Direction.Up)
×
231
            line.Insert(0, corners[0].ToString(), 1).Append(corners[1], 1);
×
232
        else
UNCOV
233
            line.Insert(0, corners[2].ToString(), 1).Append(corners[3], 1);
×
UNCOV
234
        return line.ToString();
×
235
    }
236

237
    string BuildNumber(int number)
238
    {
239
        StringBuilder numberStr = new();
×
240
        numberStr.Append("│ ");
×
241
        numberStr.Append(
×
242
            number.ToString().ResizeString(_maximumValue.ToString().Length, TextAlignment.Center)
×
243
        );
×
UNCOV
244
        numberStr.Append(" │");
×
UNCOV
245
        return numberStr.ToString();
×
246
    }
247
    #endregion
248
}
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