• 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/FloatSelector.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 FloatSelector : InteractiveElement<float>
18
{
19
    #region Fields
20
    private readonly string _question;
21
    private readonly float _minimumValue;
22
    private readonly float _maximumValue;
23
    private readonly float _startValue;
24
    private readonly float _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((float)Math.Round(_maximumValue, 1))} {Core.GetSelector.Item2} ".Length
×
53
        );
×
54
    #endregion
55

56
    #region Constructor
57
    /// <summary>
58
    /// The constructor of the FloatSelector 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 FloatSelector(
×
76
        string question,
×
77
        float min,
×
78
        float max,
×
79
        float start = 0,
×
80
        float 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 float CheckMin(float min, float 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 float CheckMax(float min, float 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 float CheckStart(float start, float min, float 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 float CheckStep(float step, float min, float 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
        float 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(
159
                        this,
160
                        new InteractionEventArgs<float>(Output.Select, currentNumber)
161
                    );
162
                    return;
163
                case ConsoleKey.Escape:
164
                    SendResponse(this, new InteractionEventArgs<float>(Output.Exit, currentNumber));
165
                    return;
166
                default:
167
                    break;
168
            }
169
            Thread.Sleep(1);
170
        }
171
    }
172

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

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

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

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