using System; using CC_Functions.Misc; namespace CC_Functions.Commandline.TUI { /// /// Provides a control to select a number from a range of numbers /// public class Slider : Control { /// /// Generates a new slider /// public Slider() { Input += (screen, args) => { switch (args.Info.Key) { case ConsoleKey.LeftArrow: _value -= StepSize; if (_value < MinValue) _value = MinValue; Value = _value; break; case ConsoleKey.RightArrow: _value += StepSize; if (_value > MaxValue) _value = MaxValue; Value = _value; break; } }; } /// /// The maximum value for this slider /// /// Thrown if too low/high public int MaxValue { get => _maxValue; set { if (value > MinValue && value >= Value) _maxValue = value; else throw new ArgumentOutOfRangeException("MaxValue must be larger than MinValue and equal to or larger than Value"); } } /// /// The minimal value for this slider /// /// Thrown if too low/high public int MinValue { get => _minValue; set { if (value < MaxValue && value <= Value) _minValue = value; else throw new ArgumentOutOfRangeException("MaxValue must be larger than MinValue and equal to or smaller than Value"); } } /// /// The current value of this slider /// /// Thrown if too low/high public int Value { get => _value; set { if (value <= MaxValue && value >= MinValue) _value = value; else throw new ArgumentOutOfRangeException("Value must be between MinValue and MaxValue"); } } /// /// The size of steps in this slider /// public int StepSize = 1; private int _value = 5; private int _maxValue = 10; private int _minValue = 0; /// public override Pixel[,] Render() { int delta = MaxValue - MinValue; int litValLen = Math.Max(MaxValue.ToString().Length, MinValue.ToString().Length); int prevpts = Math.Max((Value - MinValue) * Size.Width / delta - litValLen - 2, 0); int postpts = Math.Max(Size.Width - prevpts - litValLen - 2, 0); char[,] rend = $"{new string('=', prevpts)}[{Value.ToString($"D{litValLen}")}]{new string('=', postpts)}".ToNdArray2D(); int f1 = rend.GetLength(0); int f2 = rend.GetLength(1); Pixel[,] output = new Pixel[f1, f2]; output.Populate(new Pixel()); for (int i = 0; i < f1; i++) for (int j = 0; j < f2; j++) output[i, j] = new Pixel(Selected ? ForeColor : BackColor, Selected ? BackColor : ForeColor, rend[i, j]); return output; } /// public override bool Selectable { get; } = true; } }