Browse Source

Added Scenario and expanded API

Tig 1 year ago
parent
commit
c0fc83bd78

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

@@ -146,7 +146,8 @@ public class NumericUpDown<T> : View where T : notnull
     /// <remarks>
     ///     <para>
     ///         <see cref="ValueChanging"/> and <see cref="ValueChanged"/> events are raised when the value changes.
-    ///         The <see cref="ValueChanging"/> event can be canceled the change setting <see cref="CancelEventArgs{T}.Cancel"/> to
+    ///         The <see cref="ValueChanging"/> event can be canceled the change setting
+    ///         <see cref="CancelEventArgs{T}.Cancel"/> to
     ///         <see langword="true"/>.
     ///     </para>
     /// </remarks>
@@ -175,6 +176,17 @@ public class NumericUpDown<T> : View where T : notnull
         }
     }
 
+    /// <summary>
+    ///     Raised when the value is about to change. Set <see cref="CancelEventArgs{T}.Cancel"/> to true to prevent the
+    ///     change.
+    /// </summary>
+    public event EventHandler<CancelEventArgs<T>>? ValueChanging;
+
+    /// <summary>
+    ///     Raised when the value has changed.
+    /// </summary>
+    public event EventHandler<EventArgs<T>>? ValueChanged;
+
     private string _format = "{0}";
 
     /// <summary>
@@ -191,30 +203,47 @@ public class NumericUpDown<T> : View where T : notnull
             }
 
             _format = value;
+
+            FormatChanged?.Invoke (this, new (value));
             SetText ();
         }
     }
 
+    /// <summary>
+    ///     Raised when <see cref="Format"/> has changed.
+    /// </summary>
+    public event EventHandler<EventArgs<string>>? FormatChanged;
+
     private void SetText ()
     {
         _number.Text = string.Format (Format, _value);
         Text = _number.Text;
     }
 
-    /// <summary>
-    ///     Raised when the value is about to change. Set <see cref="CancelEventArgs{T}.Cancel"/> to true to prevent the
-    ///     change.
-    /// </summary>
-    public event EventHandler<CancelEventArgs<T>>? ValueChanging;
+    private T _increment;
 
     /// <summary>
-    ///     Raised when the value has changed.
     /// </summary>
-    public event EventHandler<EventArgs<T>>? ValueChanged;
+    public T Increment
+    {
+        get => _increment;
+        set
+        {
+            if (_increment == (dynamic)value)
+            {
+                return;
+            }
+
+            _increment = value;
+
+            IncrementChanged?.Invoke (this, new (value));
+        }
+    }
 
     /// <summary>
+    ///     Raised when <see cref="Increment"/> has changed.
     /// </summary>
-    public T Increment { get; set; }
+    public event EventHandler<EventArgs<T>>? IncrementChanged;
 }
 
 /// <summary>

+ 10 - 10
UICatalog/Scenarios/Buttons.cs

@@ -388,16 +388,16 @@ public class Buttons : Scenario
         enableCB.Toggle += (s, e) => { repeatButton.Enabled = !repeatButton.Enabled; };
         main.Add (label, repeatButton, enableCB);
 
-        //var decNumericUpDown = new NumericUpDown<decimal>
-        //{
-        //    Value = 42.11m,
-        //    Increment = 11.31m,
-        //    Format = "{0:0%}",
-        //    X = 0,
-        //    Y = Pos.Bottom (enableCB) + 1,
-        //};
-
-        //main.Add (decNumericUpDown);
+        var decNumericUpDown = new NumericUpDown<int>
+        {
+            Value = 911,
+            Increment = 1,
+            Format = "{0:X}",
+            X = 0,
+            Y = Pos.Bottom (enableCB) + 1,
+        };
+
+        main.Add (decNumericUpDown);
 
         main.Ready += (s, e) =>
                       {

+ 291 - 0
UICatalog/Scenarios/NumericUpDownDemo.cs

@@ -0,0 +1,291 @@
+#nullable enable 
+using System;
+using Terminal.Gui;
+
+namespace UICatalog.Scenarios;
+
+[ScenarioMetadata ("NumericUpDown", "Demonstrates the NumericUpDown View")]
+[ScenarioCategory ("Controls")]
+public class NumericUpDownDemo : Scenario
+{
+    public override void Main ()
+    {
+        Application.Init ();
+
+        Window app = new ()
+        {
+            Title = GetQuitKeyAndName (),
+            TabStop = TabBehavior.TabGroup
+        };
+
+        var editor = new AdornmentsEditor
+        {
+            X = 0,
+            Y = 0,
+            AutoSelectViewToEdit = true,
+            TabStop = TabBehavior.NoStop
+        };
+        app.Add (editor);
+
+        NumericUpDownEditor<int> intEditor = new ()
+        {
+            X = Pos.Right (editor),
+            Y = 0,
+            Title = "int",
+        };
+
+        app.Add (intEditor);
+
+        NumericUpDownEditor<float> floatEditor = new ()
+        {
+            X = Pos.Right (intEditor),
+            Y = 0,
+            Title = "float",
+        };
+        app.Add (floatEditor);
+
+        app.Initialized += AppInitialized;
+
+        void AppInitialized (object? sender, EventArgs e)
+        {
+            floatEditor!.NumericUpDown!.Increment = 0.1F;
+            floatEditor!.NumericUpDown!.Format = "{0:0.0}";
+
+        }
+
+        Application.Run (app);
+        app.Dispose ();
+        Application.Shutdown ();
+
+    }
+
+}
+
+internal class NumericUpDownEditor<T> : View where T : notnull
+{
+    private NumericUpDown<T>? _numericUpDown;
+
+    internal NumericUpDown<T>? NumericUpDown
+    {
+        get => _numericUpDown;
+        set
+        {
+            if (value == _numericUpDown)
+            {
+                return;
+            }
+            _numericUpDown = value;
+
+            if (_numericUpDown is { } && _value is { })
+            {
+                _value.Text = _numericUpDown.Text;
+            }
+        }
+    }
+
+    private TextField? _value;
+    private TextField? _format;
+    private TextField? _increment;
+
+    internal NumericUpDownEditor ()
+    {
+        _numericUpDown = null;
+        Title = "NumericUpDownEditor";
+        BorderStyle = LineStyle.Single;
+        Width = Dim.Auto (DimAutoStyle.Content);
+        Height = Dim.Auto (DimAutoStyle.Content);
+        TabStop = TabBehavior.TabGroup;
+
+        Initialized += NumericUpDownEditorInitialized;
+
+        return;
+
+        void NumericUpDownEditorInitialized (object? sender, EventArgs e)
+        {
+            Label label = new ()
+            {
+                Title = "_Value: ",
+                Width = 12,
+            };
+            label.TextFormatter.Alignment = Alignment.End;
+            _value = new ()
+            {
+                X = Pos.Right (label),
+                Y = Pos.Top (label),
+                Width = 8,
+                Title = "Value",
+            };
+            _value.Accept += ValuedOnAccept;
+
+            void ValuedOnAccept (object? sender, EventArgs e)
+            {
+                if (_numericUpDown is null)
+                {
+                    return;
+                }
+
+                try
+                {
+                    if (string.IsNullOrEmpty (_value.Text))
+                    {
+                        // Handle empty or null text if needed
+                        _numericUpDown.Value = default!;
+                    }
+                    else
+                    {
+                        // Parse _value.Text and then convert to type T
+                        _numericUpDown.Value = (T)Convert.ChangeType (_value.Text, typeof (T));
+                    }
+
+                    _value.ColorScheme = SuperView.ColorScheme;
+
+                }
+                catch (System.FormatException)
+                {
+                    _value.ColorScheme = Colors.ColorSchemes ["Error"];
+                }
+                catch (InvalidCastException)
+                {
+                    _value.ColorScheme = Colors.ColorSchemes ["Error"];
+                }
+                finally
+                {
+                }
+
+            }
+            Add (label, _value);
+
+            label = new ()
+            {
+                Y = Pos.Bottom (_value),
+                Width = 12,
+                Title = "_Format: ",
+            };
+            label.TextFormatter.Alignment = Alignment.End;
+
+            _format = new ()
+            {
+                X = Pos.Right (label),
+                Y = Pos.Top (label),
+                Title = "Format",
+                Width = Dim.Width (_value),
+            };
+            _format.Accept += FormatOnAccept;
+
+            void FormatOnAccept (object? o, EventArgs eventArgs)
+            {
+                if (_numericUpDown is null)
+                {
+                    return;
+                }
+
+                try
+                {
+                    // Test format to ensure it's valid
+                    _ = string.Format (_format.Text, _value);
+                    _numericUpDown.Format = _format.Text;
+                    
+                    _format.ColorScheme = SuperView.ColorScheme;
+
+                }
+                catch (System.FormatException)
+                {
+                    _format.ColorScheme = Colors.ColorSchemes ["Error"];
+                }
+                catch (InvalidCastException)
+                {
+                    _format.ColorScheme = Colors.ColorSchemes ["Error"];
+                }
+                finally
+                {
+                }
+            }
+
+            Add (label, _format);
+
+            label = new ()
+            {
+                Y = Pos.Bottom (_format),
+                Width = 12,
+                Title = "_Increment: ",
+            };
+            label.TextFormatter.Alignment = Alignment.End;
+            _increment = new ()
+            {
+                X = Pos.Right (label),
+                Y = Pos.Top (label),
+                Title = "Increment",
+                Width = Dim.Width (_value),
+            };
+
+            _increment.Accept += IncrementOnAccept;
+
+            void IncrementOnAccept (object? o, EventArgs eventArgs)
+            {
+                if (_numericUpDown is null)
+                {
+                    return;
+                }
+
+                try
+                {
+                    if (string.IsNullOrEmpty (_value.Text))
+                    {
+                        // Handle empty or null text if needed
+                        _numericUpDown.Increment = default!;
+                    }
+                    else
+                    {
+                        // Parse _value.Text and then convert to type T
+                        _numericUpDown.Increment = (T)Convert.ChangeType (_increment.Text, typeof (T));
+                    }
+
+                    _increment.ColorScheme = SuperView.ColorScheme;
+
+                }
+                catch (System.FormatException)
+                {
+                    _increment.ColorScheme = Colors.ColorSchemes ["Error"];
+                }
+                catch (InvalidCastException)
+                {
+                    _increment.ColorScheme = Colors.ColorSchemes ["Error"];
+                }
+                finally
+                {
+                }
+            }
+
+            Add (label, _increment);
+
+            _numericUpDown = new ()
+            {
+                X = Pos.Center (),
+                Y = Pos.Bottom (_increment) + 1,
+                Increment = (dynamic)1,
+            };
+
+            _numericUpDown.ValueChanged += NumericUpDownOnValueChanged;
+
+            void NumericUpDownOnValueChanged (object? o, EventArgs<T> eventArgs)
+            {
+                _value.Text = _numericUpDown.Text;
+            }
+
+            _numericUpDown.IncrementChanged += NumericUpDownOnIncrementChanged;
+
+            void NumericUpDownOnIncrementChanged (object? o, EventArgs<T> eventArgs)
+            {
+                _increment.Text = _numericUpDown.Increment.ToString ();
+            }
+
+            Add (_numericUpDown);
+
+            _value.Text = _numericUpDown.Text;
+            _format.Text = _numericUpDown.Format;
+            _increment.Text = _numericUpDown.Increment.ToString ();
+        }
+    }
+
+
+}

+ 29 - 0
UnitTests/Views/NumericUpDownTests.cs

@@ -1,3 +1,4 @@
+using System.Globalization;
 using Xunit.Abstractions;
 
 namespace Terminal.Gui.ViewsTests;
@@ -184,12 +185,39 @@ public class NumericUpDownTests (ITestOutputHelper _output)
     [InlineData (.75F, "{0:0%}", "75%")]
     public void Format_decimal (float value, string format, string expectedText)
     {
+        CultureInfo currentCulture = CultureInfo.CurrentCulture;
+        CultureInfo.CurrentCulture = CultureInfo.InvariantCulture;
+
         NumericUpDown<float> numericUpDown = new NumericUpDown<float> ();
 
         numericUpDown.Format = format;
         numericUpDown.Value = value;
 
         Assert.Equal (expectedText, numericUpDown.Text);
+
+        CultureInfo.CurrentCulture = currentCulture;
+    }
+
+    [Theory]
+    [InlineData (0, "{0}", "0")]
+    [InlineData (11, "{0}", "11")]
+    [InlineData (-1, "{0}", "-1")]
+    [InlineData (911, "{0:X}", "38F")]
+    [InlineData (911, "0x{0:X04}", "0x038F")]
+
+    public void Format_int (int value, string format, string expectedText)
+    {
+        CultureInfo currentCulture = CultureInfo.CurrentCulture;
+        CultureInfo.CurrentCulture = CultureInfo.InvariantCulture;
+
+        NumericUpDown<int> numericUpDown = new NumericUpDown<int> ();
+
+        numericUpDown.Format = format;
+        numericUpDown.Value = value;
+
+        Assert.Equal (expectedText, numericUpDown.Text);
+
+        CultureInfo.CurrentCulture = currentCulture;
     }
 
     [Fact]
@@ -211,4 +239,5 @@ public class NumericUpDownTests (ITestOutputHelper _output)
 
         Assert.Equal (-1, numericUpDown.Value);
     }
+
 }