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

MorganKryze / ConsoleAppVisuals / 8264147656

13 Mar 2024 10:45AM UTC coverage: 95.25%. Remained the same
8264147656

push

github

MorganKryze
🌟 selector char managed locally in the element and not in the core class

987 of 1120 branches covered (88.13%)

Branch coverage included in aggregate %.

20 of 20 new or added lines in 3 files covered. (100.0%)

2 existing lines in 2 files now uncovered.

1981 of 1996 relevant lines covered (99.25%)

721.27 hits per line

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

96.67
/src/ConsoleAppVisuals/elements/interactive_elements/ScrollingMenu.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.Elements;
6

7
/// <summary>
8
/// Defines the scrolling menu 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/">Example Project</a></description></item>
15
/// </list>
16
/// </remarks>
17
public class ScrollingMenu : InteractiveElement<int>
18
{
19
    #region Fields
20
    private string _question;
21
    private string[] _choices;
22
    private int _defaultIndex;
23
    private Placement _placement;
24
    private char _selector = DEFAULT_CURSOR;
42✔
25
    #endregion
26

27
    #region Constants
28
    /// <summary>
29
    /// The default cursor of the menu.
30
    /// </summary>
31
    /// <remarks>
32
    /// Can be updated with the <see cref="UpdateSelector(char)"/> method.
33
    /// </remarks>
34
    public const char DEFAULT_CURSOR = '>';
35
    #endregion
36

37
    #region Properties
38
    /// <summary>
39
    /// The placement of the menu on the console.
40
    /// </summary>
41
    public override Placement Placement => _placement;
15✔
42

43
    /// <summary>
44
    /// The height of the menu.
45
    /// </summary>
46
    public override int Height => _choices.Length + 2;
3✔
47

48
    /// <summary>
49
    /// The width of the menu.
50
    /// </summary>
51
    public override int Width =>
52
        Math.Max(_question.Length + 1, _choices.Max((string s) => s.Length) + 4);
12✔
53

54
    /// <summary>
55
    /// The question to ask the user.
56
    /// </summary>
57
    public string Question => _question;
6✔
58

59
    /// <summary>
60
    /// The different choices of the menu.
61
    /// </summary>
62
    public string[] Choices => _choices;
6✔
63

64
    /// <summary>
65
    /// The index of the default choice(initially 0).
66
    /// </summary>
67
    public int DefaultIndex => _defaultIndex;
6✔
68

69
    /// <summary>
70
    /// The selector char of the menu.
71
    /// </summary>
72
    public char Selector => _selector;
3✔
73

74
    #endregion
75

76
    #region Constructor
77
    /// <summary>
78
    /// The constructor of the ScrollingMenu class.
79
    /// </summary>
80
    /// <param name="question">The question to ask the user.</param>
81
    /// <param name="defaultIndex">The index of the default choice(initially 0).</param>
82
    /// <param name="placement">The placement of the menu on the console.</param>
83
    /// <param name="choices">The different choices of the menu.</param>
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/">Example Project</a></description></item>
89
    /// </list>
90
    /// </remarks>
91
    public ScrollingMenu(
42✔
92
        string question,
42✔
93
        int defaultIndex = 0,
42✔
94
        Placement placement = Placement.TopCenter,
42✔
95
        params string[] choices
42✔
96
    )
42✔
97
    {
98
        _question = question;
42✔
99
        _defaultIndex = defaultIndex;
42✔
100
        _placement = placement;
42✔
101
        _choices = choices;
42✔
102
    }
42✔
103
    #endregion
104

105
    #region Methods
106
    /// <summary>
107
    /// This method is used to update the question of the menu.
108
    /// </summary>
109
    /// <param name="question">The new question of the menu.</param>
110
    /// <remarks>
111
    /// For more information, refer to the following resources:
112
    /// <list type="bullet">
113
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
114
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
115
    /// </list>
116
    /// </remarks>
117
    public void UpdateQuestion(string question)
118
    {
119
        _question = question;
3✔
120
    }
3✔
121

122
    /// <summary>
123
    /// This method is used to update the choices of the menu.
124
    /// </summary>
125
    /// <param name="choices">The new choices of the menu.</param>
126
    /// <remarks>
127
    /// For more information, refer to the following resources:
128
    /// <list type="bullet">
129
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
130
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
131
    /// </list>
132
    /// </remarks>
133
    public void UpdateChoices(params string[] choices)
134
    {
135
        _choices = choices;
3✔
136
    }
3✔
137

138
    /// <summary>
139
    /// This method is used to update the default index of the menu.
140
    /// </summary>
141
    /// <param name="defaultIndex">The new default index of the menu.</param>
142
    /// <remarks>
143
    /// For more information, refer to the following resources:
144
    /// <list type="bullet">
145
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
146
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
147
    /// </list>
148
    /// </remarks>
149
    public void UpdateDefaultIndex(int defaultIndex)
150
    {
151
        _defaultIndex = defaultIndex;
3✔
152
    }
3✔
153

154
    /// <summary>
155
    /// This method is used to update the placement of the menu.
156
    /// </summary>
157
    /// <param name="placement">The new placement of the menu.</param>
158
    /// <remarks>
159
    /// For more information, refer to the following resources:
160
    /// <list type="bullet">
161
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
162
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
163
    /// </list>
164
    /// </remarks>
165
    public void UpdatePlacement(Placement placement)
166
    {
167
        _placement = placement;
6✔
168
    }
6✔
169

170
    /// <summary>
171
    /// This method is used to update the selector of the menu.
172
    /// </summary>
173
    /// <param name="selector">The new selector of the menu.</param>
174
    /// <remarks>
175
    /// For more information, refer to the following resources:
176
    /// <list type="bullet">
177
    /// <item><description><a href="https://morgankryze.github.io/ConsoleAppVisuals/">Documentation</a></description></item>
178
    /// <item><description><a href="https://github.com/MorganKryze/ConsoleAppVisuals/blob/main/example/">Example Project</a></description></item>
179
    /// </list>
180
    /// </remarks>
181
    public void UpdateSelector(char selector)
182
    {
183
        _selector = selector;
3✔
184
    }
3✔
185

186
    /// <summary>
187
    /// This method is used to draw the menu on the console.
188
    /// </summary>
189
    [Visual]
190
    protected override void RenderElementActions()
191
    {
192
        EqualizeChoicesLength(_choices);
193
        Core.WriteContinuousString(_question, Line, false, 1500, 50);
194
        int lineChoice = Line + 2;
195
        bool delay = true;
196
        bool loop = true;
197
        while (loop)
198
        {
199
            DisplayChoices(_defaultIndex, _placement, _choices, lineChoice, delay);
200
            delay = false;
201

202
            switch (Console.ReadKey(intercept: true).Key)
203
            {
204
                case ConsoleKey.UpArrow:
205
                case ConsoleKey.Z:
206
                    _defaultIndex = (_defaultIndex == 0) ? _choices.Length - 1 : _defaultIndex - 1;
207
                    break;
208
                case ConsoleKey.DownArrow:
209
                case ConsoleKey.S:
210
                    _defaultIndex = (_defaultIndex == _choices.Length - 1) ? 0 : _defaultIndex + 1;
211
                    break;
212
                case ConsoleKey.Enter:
213
                    SendResponse(
214
                        this,
215
                        new InteractionEventArgs<int>(Output.Selected, _defaultIndex)
216
                    );
217
                    loop = false;
218
                    break;
219
                case ConsoleKey.Escape:
220
                    SendResponse(
221
                        this,
222
                        new InteractionEventArgs<int>(Output.Escaped, _defaultIndex)
223
                    );
224
                    loop = false;
225
                    break;
226
                case ConsoleKey.Backspace:
227
                    SendResponse(
228
                        this,
229
                        new InteractionEventArgs<int>(Output.Deleted, _defaultIndex)
230
                    );
231
                    loop = false;
232
                    break;
233
            }
234
        }
235
    }
236

237
    [Visual]
238
    private static void EqualizeChoicesLength(string[] choices)
239
    {
UNCOV
240
        int totalWidth = (choices.Length != 0) ? choices.Max((string s) => s.Length) : 0;
×
241
        for (int i = 0; i < choices.Length; i++)
242
        {
243
            choices[i] = choices[i].PadRight(totalWidth);
244
        }
245
    }
246

247
    [Visual]
248
    private void DisplayChoices(
249
        int defaultIndex,
250
        Placement placement,
251
        string[] choices,
252
        int lineChoice,
253
        bool delay = false
254
    )
255
    {
256
        string[] array = new string[choices.Length];
257
        for (int i = 0; i < choices.Length; i++)
258
        {
259
            array[i] = (i == defaultIndex) ? $" {Selector} {choices[i]}  " : $"   {choices[i]}  ";
260
            Core.WritePositionedString(
261
                array[i],
262
                placement.ToTextAlignment(),
263
                i == defaultIndex,
264
                lineChoice + i
265
            );
266
            if (delay)
267
                Thread.Sleep(30);
268
        }
269
    }
270
    #endregion
271
}
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