浏览代码

Added other types

Tig 1 年之前
父节点
当前提交
cebf1773af

+ 104 - 9
Terminal.Gui/Views/NumericUpDown.cs

@@ -1,3 +1,4 @@
+#nullable enable
 using System.ComponentModel;
 using Terminal.Gui;
 
@@ -5,7 +6,7 @@ using Terminal.Gui;
 ///     Enables the user to increase or decrease a value by clicking on the up or down buttons.
 /// </summary>
 /// <remarks>
-///     Supports the following types: <see cref="int"/>, <see cref="long"/>, <see cref="float"/>, <see cref="double"/>,
+///     Supports the following types: <see cref="int"/>, <see cref="long"/>, <see cref="double"/>, <see cref="double"/>,
 ///     <see cref="decimal"/>.
 ///     Supports only one digit of precision.
 /// </remarks>
@@ -21,7 +22,7 @@ public class NumericUpDown<T> : View
     {
         Type type = typeof (T);
 
-        if (!(type == typeof (int) || type == typeof (long) || type == typeof (float) || type == typeof (double) || type == typeof (decimal)))
+        if (!(type == typeof (int) || type == typeof (long) || type == typeof (double) || type == typeof (float) || type == typeof (double) || type == typeof (decimal)))
         {
             // Support object for AllViewsTester
             if (type != typeof (object))
@@ -30,6 +31,45 @@ public class NumericUpDown<T> : View
             }
         }
 
+        switch (typeof (T))
+        {
+            case { } i when i == typeof (int):
+                Minimum = (dynamic)int.MinValue;
+                Maximum = (dynamic)int.MaxValue;
+                Increment = (dynamic)1;
+
+                break;
+
+            case { } i when i == typeof (long):
+                Minimum = (dynamic)long.MinValue;
+                Maximum = (dynamic)long.MaxValue;
+                Increment = (dynamic)1;
+
+                break;
+
+            case { } i when i == typeof (double):
+                Minimum = (dynamic)double.MinValue;
+                Maximum = (dynamic)double.MaxValue;
+                Increment = (dynamic)1;
+
+                break;
+
+            case { } i when i == typeof (float):
+                Minimum = (dynamic)float.MinValue;
+                Maximum = (dynamic)float.MaxValue;
+                Increment = (dynamic)1;
+
+                break;
+
+
+            case { } i when i == typeof (decimal):
+                Minimum = (dynamic)decimal.MinValue;
+                Maximum = (dynamic)decimal.MaxValue;
+                Increment = (dynamic)1;
+
+                break;
+        }
+
         Width = Dim.Auto (DimAutoStyle.Content); //Dim.Function (() => Digits + 2); // button + 3 for number + button
         Height = Dim.Auto (DimAutoStyle.Content);
 
@@ -86,8 +126,11 @@ public class NumericUpDown<T> : View
                             return false;
                         }
 
-                        Value = (dynamic)Value + 1;
-                        _number.Text = Value?.ToString () ?? string.Empty;
+                        if (Value is { })
+                        {
+                            Value = (dynamic)Value + Increment;
+                            _number.Text = Value?.ToString () ?? string.Empty;
+                        }
 
                         return true;
                     });
@@ -101,8 +144,11 @@ public class NumericUpDown<T> : View
                             return false;
                         }
 
-                        Value = (dynamic)Value - 1;
-                        _number.Text = Value.ToString () ?? string.Empty;
+                        if (Value is { })
+                        {
+                            Value = (dynamic)Value - Increment;
+                            _number.Text = Value.ToString () ?? string.Empty;
+                        }
 
                         return true;
                     });
@@ -112,9 +158,15 @@ public class NumericUpDown<T> : View
 
         return;
 
-        void OnDownButtonOnAccept (object s, HandledEventArgs e) { InvokeCommand (Command.ScrollDown); }
+        void OnDownButtonOnAccept (object s, HandledEventArgs e)
+        {
+            InvokeCommand (Command.ScrollDown);
+        }
 
-        void OnUpButtonOnAccept (object s, HandledEventArgs e) { InvokeCommand (Command.ScrollUp); }
+        void OnUpButtonOnAccept (object s, HandledEventArgs e)
+        {
+            InvokeCommand (Command.ScrollUp);
+        }
     }
 
     private void _up_Enter (object sender, FocusEventArgs e) { throw new NotImplementedException (); }
@@ -143,8 +195,18 @@ public class NumericUpDown<T> : View
                 return;
             }
 
+            if (Comparer<T>.Default.Compare (value, Minimum) < 0)
+            {
+                value = Minimum;
+            }
+
+            if (Comparer<T>.Default.Compare (value, Maximum) > 0)
+            {
+                value = Maximum;
+            }
+
             _value = value;
-            _number.Text = _value.ToString ();
+            _number.Text = _value?.ToString () ?? string.Empty;
             ValueChanged?.Invoke (this, new (ref _value));
         }
     }
@@ -166,6 +228,39 @@ public class NumericUpDown<T> : View
     ///     plus the buttons. The default is 3.
     /// </summary>
     public int Digits { get; set; } = 3;
+
+    private T _minimum;
+
+    /// <summary>
+    /// 
+    /// </summary>
+    public T Minimum
+    {
+        get { return _minimum; }
+        set { _minimum = value; }
+    }
+
+    private T _maximum;
+
+    /// <summary>
+    /// 
+    /// </summary>
+    public T Maximum
+    {
+        get { return _maximum; }
+        set { _maximum = value; }
+    }
+
+    private T _increment;
+
+    /// <summary>
+    /// 
+    /// </summary>
+    public T Increment
+    {
+        get { return _increment; }
+        set { _increment = value; }
+    }
 }
 
 

+ 4 - 4
UICatalog/Scenarios/AdornmentEditor.cs

@@ -78,10 +78,10 @@ public class AdornmentEditor : View
         AdornmentChanged?.Invoke (this, EventArgs.Empty);
     }
 
-    private Buttons.NumericUpDown<int> _topEdit;
-    private Buttons.NumericUpDown<int> _leftEdit;
-    private Buttons.NumericUpDown<int> _bottomEdit;
-    private Buttons.NumericUpDown<int> _rightEdit;
+    private NumericUpDown<int> _topEdit;
+    private NumericUpDown<int> _leftEdit;
+    private NumericUpDown<int> _bottomEdit;
+    private NumericUpDown<int> _rightEdit;
 
     public AdornmentEditor ()
     {

+ 0 - 154
UICatalog/Scenarios/Buttons.cs

@@ -395,159 +395,5 @@ public class Buttons : Scenario
         main.Dispose ();
         Application.Shutdown ();
     }
-
-    /// <summary>
-    /// Enables the user to increase or decrease a value by clicking on the up or down buttons.
-    /// </summary>
-    /// <remarks>
-    ///     Supports the following types: <see cref="int"/>, <see cref="long"/>, <see cref="float"/>, <see cref="double"/>, <see cref="decimal"/>.
-    ///     Supports only one digit of precision.
-    /// </remarks>
-    public class NumericUpDown<T> : View
-    {
-        private readonly Button _down;
-        // TODO: Use a TextField instead of a Label
-        private readonly View _number;
-        private readonly Button _up;
-
-        public NumericUpDown ()
-        {
-            Type type = typeof (T);
-            if (!(type == typeof (int) || type == typeof (long) || type == typeof (float) || type == typeof (double) || type == typeof (decimal)))
-            {
-                throw new InvalidOperationException ("T must be a numeric type that supports addition and subtraction.");
-            }
-
-            Width = Dim.Auto (DimAutoStyle.Content); //Dim.Function (() => Digits + 2); // button + 3 for number + button
-            Height = Dim.Auto (DimAutoStyle.Content);
-
-            _down = new ()
-            {
-                Height = 1,
-                Width = 1,
-                NoPadding = true,
-                NoDecorations = true,
-                Title = $"{CM.Glyphs.DownArrow}",
-                WantContinuousButtonPressed = true,
-                CanFocus = false,
-                ShadowStyle = ShadowStyle.None,
-            };
-
-            _number = new ()
-            {
-                Text = Value.ToString (),
-                X = Pos.Right (_down),
-                Y = Pos.Top (_down),
-                Width = Dim.Func (() => Digits),
-                Height = 1,
-                TextAlignment = Alignment.Center,
-                CanFocus = true
-            };
-
-            _up = new ()
-            {
-                X = Pos.AnchorEnd (),
-                Y = Pos.Top (_number),
-                Height = 1,
-                Width = 1,
-                NoPadding = true,
-                NoDecorations = true,
-                Title = $"{CM.Glyphs.UpArrow}",
-                WantContinuousButtonPressed = true,
-                CanFocus = false,
-                ShadowStyle = ShadowStyle.None,
-            };
-
-            CanFocus = true;
-
-            _down.Accept += OnDownButtonOnAccept;
-            _up.Accept += OnUpButtonOnAccept;
-
-            Add (_down, _number, _up);
-
-
-            AddCommand (Command.ScrollUp, () =>
-                                          {
-                                              Value = (dynamic)Value + 1;
-                                              _number.Text = Value.ToString ();
-
-                                              return true;
-                                          });
-            AddCommand (Command.ScrollDown, () =>
-                                            {
-                                                Value = (dynamic)Value - 1;
-                                                _number.Text = Value.ToString ();
-
-                                                return true;
-                                            });
-
-            KeyBindings.Add (Key.CursorUp, Command.ScrollUp);
-            KeyBindings.Add (Key.CursorDown, Command.ScrollDown);
-
-            return;
-
-            void OnDownButtonOnAccept (object s, HandledEventArgs e)
-            {
-                InvokeCommand (Command.ScrollDown);
-            }
-
-            void OnUpButtonOnAccept (object s, HandledEventArgs e)
-            {
-                InvokeCommand (Command.ScrollUp);
-            }
-        }
-
-        private void _up_Enter (object sender, FocusEventArgs e)
-        {
-            throw new NotImplementedException ();
-        }
-
-        private T _value;
-
-        /// <summary>
-        /// The value that will be incremented or decremented.
-        /// </summary>
-        public T Value
-        {
-            get => _value;
-            set
-            {
-                if (_value.Equals (value))
-                {
-                    return;
-                }
-
-                T oldValue = value;
-                CancelEventArgs<T> args = new (ref _value, ref value);
-                ValueChanging?.Invoke (this, args);
-
-                if (args.Cancel)
-                {
-                    return;
-                }
-
-                _value = value;
-                _number.Text = _value.ToString ();
-                ValueChanged?.Invoke (this, new (ref _value));
-            }
-        }
-
-        /// <summary>
-        /// Fired when the value is about to change. Set <see cref="CancelEventArgs{T}.Cancel"/> to true to prevent the change.
-        /// </summary>
-        [CanBeNull]
-        public event EventHandler<CancelEventArgs<T>> ValueChanging;
-
-        /// <summary>
-        /// Fired when the value has changed.
-        /// </summary>
-        [CanBeNull]
-        public event EventHandler<EventArgs<T>> ValueChanged;
-
-        /// <summary>
-        /// The number of digits to display. The <see cref="View.Viewport"/> will be resized to fit this number of characters plus the buttons. The default is 3.
-        /// </summary>
-        public int Digits { get; set; } = 3;
-    }
 }
 

+ 2 - 2
UICatalog/Scenarios/ContentScrolling.cs

@@ -229,7 +229,7 @@ public class ContentScrolling : Scenario
             Y = Pos.Bottom (cbAllowYGreaterThanContentHeight)
         };
 
-        Buttons.NumericUpDown<int> contentSizeWidth = new Buttons.NumericUpDown<int>
+        NumericUpDown<int> contentSizeWidth = new NumericUpDown<int>
         {
             Value = view.GetContentSize ().Width,
             X = Pos.Right (labelContentSize) + 1,
@@ -256,7 +256,7 @@ public class ContentScrolling : Scenario
             Y = Pos.Top (labelContentSize)
         };
 
-        Buttons.NumericUpDown<int> contentSizeHeight = new Buttons.NumericUpDown<int>
+        NumericUpDown<int> contentSizeHeight = new NumericUpDown<int>
         {
             Value = view.GetContentSize ().Height,
             X = Pos.Right (labelComma) + 1,

+ 1 - 1
UICatalog/Scenarios/PosAlignDemo.cs

@@ -236,7 +236,7 @@ public sealed class PosAlignDemo : Scenario
             }
         ];
 
-        Buttons.NumericUpDown<int> addedViewsUpDown = new()
+        NumericUpDown<int> addedViewsUpDown = new()
         {
             Width = 9,
             Title = "Added",

+ 1 - 1
UICatalog/Scenarios/Sliders.cs

@@ -407,7 +407,7 @@ public class Sliders : Scenario
             Text = "Min _Inner Spacing:",
         };
 
-        Buttons.NumericUpDown<int> innerSpacingUpDown = new ()
+        NumericUpDown<int> innerSpacingUpDown = new ()
         {
             X = Pos.Right (label) + 1
         };

+ 160 - 0
UnitTests/Views/NumericUpDownTests.cs

@@ -0,0 +1,160 @@
+using System.ComponentModel;
+using Xunit.Abstractions;
+
+namespace Terminal.Gui.ViewsTests;
+
+public class NumericUpDownTests (ITestOutputHelper _output)
+{
+
+    [Fact]
+    public void WhenCreated_ShouldHaveDefaultValues_int ()
+    {
+        NumericUpDown<int> numericUpDown = new ();
+
+        Assert.Equal (0, numericUpDown.Value);
+        Assert.Equal (int.MinValue, numericUpDown.Minimum);
+        Assert.Equal (int.MaxValue, numericUpDown.Maximum);
+        Assert.Equal (1, numericUpDown.Increment);
+    }
+
+    [Fact]
+    public void WhenCreated_ShouldHaveDefaultValues_long ()
+    {
+        NumericUpDown<long> numericUpDown = new ();
+
+        Assert.Equal (0, numericUpDown.Value);
+        Assert.Equal (long.MinValue, numericUpDown.Minimum);
+        Assert.Equal (long.MaxValue, numericUpDown.Maximum);
+        Assert.Equal (1, numericUpDown.Increment);
+    }
+    
+    [Fact]
+    public void WhenCreated_ShouldHaveDefaultValues_float ()
+    {
+        NumericUpDown<float> numericUpDown = new ();
+
+        Assert.Equal (0F, numericUpDown.Value);
+        Assert.Equal (float.MinValue, numericUpDown.Minimum);
+        Assert.Equal (float.MaxValue, numericUpDown.Maximum);
+        Assert.Equal (1.0F, numericUpDown.Increment);
+    }
+
+    [Fact]
+    public void WhenCreated_ShouldHaveDefaultValues_double ()
+    {
+        NumericUpDown<double> numericUpDown = new ();
+
+        Assert.Equal (0F, numericUpDown.Value);
+        Assert.Equal (double.MinValue, numericUpDown.Minimum);
+        Assert.Equal (double.MaxValue, numericUpDown.Maximum);
+        Assert.Equal (1.0F, numericUpDown.Increment);
+    }
+
+    [Fact]
+    public void WhenCreated_ShouldHaveDefaultValues_decimal ()
+    {
+        NumericUpDown<decimal> numericUpDown = new ();
+
+        Assert.Equal (0, numericUpDown.Value);
+        Assert.Equal (decimal.MinValue, numericUpDown.Minimum);
+        Assert.Equal (decimal.MaxValue, numericUpDown.Maximum);
+        Assert.Equal (1, numericUpDown.Increment);
+    }
+
+    [Fact]
+    public void WhenCreatedWithCustomValues_ShouldHaveCustomValues_int ()
+    {
+        var numericUpDown = new NumericUpDown<int> ()
+        {
+            Value = 10,
+            Minimum = 5,
+            Maximum = 15,
+            Increment = 2
+        };
+
+        Assert.Equal (10, numericUpDown.Value);
+        Assert.Equal (5, numericUpDown.Minimum);
+        Assert.Equal (15, numericUpDown.Maximum);
+        Assert.Equal (2, numericUpDown.Increment);
+    }
+
+    [Fact]
+    public void WhenCreatedWithCustomValues_ShouldHaveCustomValues_float ()
+    {
+        var numericUpDown = new NumericUpDown<float> ()
+        {
+            Value = 10.5F,
+            Minimum = 5.5F,
+            Maximum = 15.5F,
+            Increment = 2.5F
+        };
+
+        Assert.Equal (10.5F, numericUpDown.Value);
+        Assert.Equal (5.5F, numericUpDown.Minimum);
+        Assert.Equal (15.5F, numericUpDown.Maximum);
+        Assert.Equal (2.5F, numericUpDown.Increment);
+    }
+
+    [Fact]
+    public void NumericUpDown_WhenCreatedWithInvalidType_ShouldThrowInvalidOperationException ()
+    {
+        Assert.Throws<InvalidOperationException> (() => new NumericUpDown<string> ());
+    }
+
+    [Fact]
+    public void NumericUpDown_WhenCreatedWithInvalidTypeObject_ShouldNotThrowInvalidOperationException ()
+    {
+        var numericUpDown = new NumericUpDown<object> ();
+
+        Assert.Equal (0, numericUpDown.Value);
+        Assert.Equal (0, numericUpDown.Minimum);
+        Assert.Equal (100, numericUpDown.Maximum);
+        Assert.Equal (1, numericUpDown.Increment);
+    }
+
+    [Fact]
+    public void NumericUpDown_WhenCreatedWithInvalidTypeObjectAndCustomValues_ShouldHaveCustomValues ()
+    {
+        var numericUpDown = new NumericUpDown<object> ()
+        {
+            Value = 10,
+            Minimum = 5,
+            Maximum = 15,
+            Increment = 2
+        };
+
+        Assert.Equal (10, numericUpDown.Value);
+        Assert.Equal (5, numericUpDown.Minimum);
+        Assert.Equal (15, numericUpDown.Maximum);
+        Assert.Equal (2, numericUpDown.Increment);
+    }
+
+    [Fact]
+    public void NumericUpDown_WhenCreated_ShouldHaveDefaultWidthAndHeight_int ()
+    {
+        var numericUpDown = new NumericUpDown<int> ();
+        numericUpDown.SetRelativeLayout(Application.Screen.Size);
+
+        Assert.Equal (5, numericUpDown.Frame.Width);
+        Assert.Equal (1, numericUpDown.Frame.Height);
+    }
+
+    [Fact]
+    public void NumericUpDown_WhenCreated_ShouldHaveDefaultWidthAndHeight_float ()
+    {
+        var numericUpDown = new NumericUpDown<float> ();
+        numericUpDown.SetRelativeLayout (Application.Screen.Size);
+
+        Assert.Equal (5, numericUpDown.Frame.Width);
+        Assert.Equal (1, numericUpDown.Frame.Height);
+    }
+
+    [Fact]
+    public void NumericUpDown_WhenCreated_ShouldHaveDefaultUpDownButtons ()
+    {
+        var numericUpDown = new NumericUpDown<int> ();
+
+        //   Assert.Equal (1, numericUpDown
+    }
+
+}