diff --git a/Showcase/NumericUpDown.Designer.cs b/Showcase/NumericUpDown.Designer.cs
new file mode 100644
index 00000000..5afbe074
--- /dev/null
+++ b/Showcase/NumericUpDown.Designer.cs
@@ -0,0 +1,209 @@
+
+//------------------------------------------------------------------------------
+
+//
+// This code was generated by:
+// TerminalGuiDesigner v2.0.0.0
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+// -----------------------------------------------------------------------------
+namespace Showcase {
+ using System;
+ using Terminal.Gui;
+ using System.Collections;
+ using System.Collections.Generic;
+ using System.Collections.ObjectModel;
+ using System.Drawing;
+
+
+ public partial class NumericUpDown : Terminal.Gui.Window {
+
+ private Terminal.Gui.Label lblInt;
+
+ private Terminal.Gui.NumericUpDown numericUpDownInt;
+
+ private Terminal.Gui.Label lblInt64;
+
+ private Terminal.Gui.NumericUpDown numericUpDownInt64;
+
+ private Terminal.Gui.Label label3;
+
+ private Terminal.Gui.NumericUpDown numericUpDown2;
+
+ private Terminal.Gui.Label label6;
+
+ private Terminal.Gui.NumericUpDown numericUpDownSingle;
+
+ private Terminal.Gui.Label label;
+
+ private Terminal.Gui.NumericUpDown numericUpDownDecimal;
+
+ private Terminal.Gui.Label label4;
+
+ private Terminal.Gui.NumericUpDown numericUpDown3;
+
+ private Terminal.Gui.Label label5;
+
+ private void InitializeComponent() {
+ this.label5 = new Terminal.Gui.Label();
+ this.numericUpDown3 = new Terminal.Gui.NumericUpDown();
+ this.label4 = new Terminal.Gui.Label();
+ this.numericUpDownDecimal = new Terminal.Gui.NumericUpDown();
+ this.label = new Terminal.Gui.Label();
+ this.numericUpDownSingle = new Terminal.Gui.NumericUpDown();
+ this.label6 = new Terminal.Gui.Label();
+ this.numericUpDown2 = new Terminal.Gui.NumericUpDown();
+ this.label3 = new Terminal.Gui.Label();
+ this.numericUpDownInt64 = new Terminal.Gui.NumericUpDown();
+ this.lblInt64 = new Terminal.Gui.Label();
+ this.numericUpDownInt = new Terminal.Gui.NumericUpDown();
+ this.lblInt = new Terminal.Gui.Label();
+ this.Width = Dim.Fill(0);
+ this.Height = Dim.Fill(0);
+ this.X = 0;
+ this.Y = 0;
+ this.Visible = true;
+ this.Arrangement = (Terminal.Gui.ViewArrangement.Movable | Terminal.Gui.ViewArrangement.Overlapped);
+ this.Modal = false;
+ this.TextAlignment = Terminal.Gui.Alignment.Start;
+ this.Title = "";
+ this.lblInt.Width = Dim.Auto();
+ this.lblInt.Height = 1;
+ this.lblInt.X = 0;
+ this.lblInt.Y = 0;
+ this.lblInt.Visible = true;
+ this.lblInt.Arrangement = Terminal.Gui.ViewArrangement.Fixed;
+ this.lblInt.Data = "lblInt";
+ this.lblInt.Text = "Int:";
+ this.lblInt.TextAlignment = Terminal.Gui.Alignment.Start;
+ this.Add(this.lblInt);
+ this.numericUpDownInt.Width = Dim.Auto();
+ this.numericUpDownInt.Height = Dim.Auto();
+ this.numericUpDownInt.X = 9;
+ this.numericUpDownInt.Y = 0;
+ this.numericUpDownInt.Visible = true;
+ this.numericUpDownInt.Arrangement = Terminal.Gui.ViewArrangement.Fixed;
+ this.numericUpDownInt.Data = "numericUpDownInt";
+ this.numericUpDownInt.TextAlignment = Terminal.Gui.Alignment.Start;
+ this.numericUpDownInt.Value = 1;
+ this.numericUpDownInt.Increment = 2;
+ this.Add(this.numericUpDownInt);
+ this.lblInt64.Width = Dim.Auto();
+ this.lblInt64.Height = 1;
+ this.lblInt64.X = 0;
+ this.lblInt64.Y = 1;
+ this.lblInt64.Visible = true;
+ this.lblInt64.Arrangement = Terminal.Gui.ViewArrangement.Fixed;
+ this.lblInt64.Data = "lblInt64";
+ this.lblInt64.Text = "Int64:";
+ this.lblInt64.TextAlignment = Terminal.Gui.Alignment.Start;
+ this.Add(this.lblInt64);
+ this.numericUpDownInt64.Width = Dim.Auto();
+ this.numericUpDownInt64.Height = Dim.Auto();
+ this.numericUpDownInt64.X = 9;
+ this.numericUpDownInt64.Y = 1;
+ this.numericUpDownInt64.Visible = true;
+ this.numericUpDownInt64.Arrangement = Terminal.Gui.ViewArrangement.Fixed;
+ this.numericUpDownInt64.Data = "numericUpDownInt64";
+ this.numericUpDownInt64.TextAlignment = Terminal.Gui.Alignment.Start;
+ this.numericUpDownInt64.Value = 8943589458974;
+ this.numericUpDownInt64.Increment = 1;
+ this.Add(this.numericUpDownInt64);
+ this.label3.Width = Dim.Auto();
+ this.label3.Height = 1;
+ this.label3.X = 0;
+ this.label3.Y = 2;
+ this.label3.Visible = true;
+ this.label3.Arrangement = Terminal.Gui.ViewArrangement.Fixed;
+ this.label3.Data = "label3";
+ this.label3.Text = "Double:";
+ this.label3.TextAlignment = Terminal.Gui.Alignment.Start;
+ this.Add(this.label3);
+ this.numericUpDown2.Width = Dim.Auto();
+ this.numericUpDown2.Height = Dim.Auto();
+ this.numericUpDown2.X = 9;
+ this.numericUpDown2.Y = 2;
+ this.numericUpDown2.Visible = true;
+ this.numericUpDown2.Arrangement = Terminal.Gui.ViewArrangement.Fixed;
+ this.numericUpDown2.Data = "numericUpDown2";
+ this.numericUpDown2.TextAlignment = Terminal.Gui.Alignment.Start;
+ this.numericUpDown2.Value = 32.3D;
+ this.numericUpDown2.Increment = 0.01D;
+ this.Add(this.numericUpDown2);
+ this.label6.Width = Dim.Auto();
+ this.label6.Height = 1;
+ this.label6.X = 0;
+ this.label6.Y = 3;
+ this.label6.Visible = true;
+ this.label6.Arrangement = Terminal.Gui.ViewArrangement.Fixed;
+ this.label6.Data = "label6";
+ this.label6.Text = "Single:";
+ this.label6.TextAlignment = Terminal.Gui.Alignment.Start;
+ this.Add(this.label6);
+ this.numericUpDownSingle.Width = Dim.Auto();
+ this.numericUpDownSingle.Height = Dim.Auto();
+ this.numericUpDownSingle.X = 9;
+ this.numericUpDownSingle.Y = 3;
+ this.numericUpDownSingle.Visible = true;
+ this.numericUpDownSingle.Arrangement = Terminal.Gui.ViewArrangement.Fixed;
+ this.numericUpDownSingle.Data = "numericUpDownSingle";
+ this.numericUpDownSingle.TextAlignment = Terminal.Gui.Alignment.Start;
+ this.numericUpDownSingle.Value = 1F;
+ this.numericUpDownSingle.Increment = 1F;
+ this.Add(this.numericUpDownSingle);
+ this.label.Width = Dim.Auto();
+ this.label.Height = 1;
+ this.label.X = 0;
+ this.label.Y = 4;
+ this.label.Visible = true;
+ this.label.Arrangement = Terminal.Gui.ViewArrangement.Fixed;
+ this.label.Data = "label";
+ this.label.Text = "Decimal:";
+ this.label.TextAlignment = Terminal.Gui.Alignment.Start;
+ this.Add(this.label);
+ this.numericUpDownDecimal.Width = Dim.Auto();
+ this.numericUpDownDecimal.Height = Dim.Auto();
+ this.numericUpDownDecimal.X = 9;
+ this.numericUpDownDecimal.Y = 4;
+ this.numericUpDownDecimal.Visible = true;
+ this.numericUpDownDecimal.Arrangement = Terminal.Gui.ViewArrangement.Fixed;
+ this.numericUpDownDecimal.Data = "numericUpDownDecimal";
+ this.numericUpDownDecimal.TextAlignment = Terminal.Gui.Alignment.Start;
+ this.numericUpDownDecimal.Value = 0.00000000001m;
+ this.numericUpDownDecimal.Increment = 0.00000000000001m;
+ this.Add(this.numericUpDownDecimal);
+ this.label4.Width = Dim.Auto();
+ this.label4.Height = 1;
+ this.label4.X = 0;
+ this.label4.Y = 7;
+ this.label4.Visible = true;
+ this.label4.Arrangement = Terminal.Gui.ViewArrangement.Fixed;
+ this.label4.Data = "label4";
+ this.label4.Text = "Single:";
+ this.label4.TextAlignment = Terminal.Gui.Alignment.Start;
+ this.Add(this.label4);
+ this.numericUpDown3.Width = Dim.Auto();
+ this.numericUpDown3.Height = Dim.Auto();
+ this.numericUpDown3.X = 8;
+ this.numericUpDown3.Y = 7;
+ this.numericUpDown3.Visible = true;
+ this.numericUpDown3.Arrangement = Terminal.Gui.ViewArrangement.Fixed;
+ this.numericUpDown3.Data = "numericUpDown3";
+ this.numericUpDown3.TextAlignment = Terminal.Gui.Alignment.Start;
+ this.numericUpDown3.Value = float.PositiveInfinity;
+ this.numericUpDown3.Increment = 1F;
+ this.Add(this.numericUpDown3);
+ this.label5.Width = Dim.Auto();
+ this.label5.Height = 1;
+ this.label5.X = 12;
+ this.label5.Y = 7;
+ this.label5.Visible = true;
+ this.label5.Arrangement = Terminal.Gui.ViewArrangement.Fixed;
+ this.label5.Data = "label5";
+ this.label5.Text = "(Supports infinitiy!?)";
+ this.label5.TextAlignment = Terminal.Gui.Alignment.Start;
+ this.Add(this.label5);
+ }
+ }
+}
diff --git a/Showcase/NumericUpDown.cs b/Showcase/NumericUpDown.cs
new file mode 100644
index 00000000..30c732b0
--- /dev/null
+++ b/Showcase/NumericUpDown.cs
@@ -0,0 +1,20 @@
+
+//------------------------------------------------------------------------------
+
+//
+// This code was generated by:
+// TerminalGuiDesigner v2.0.0.0
+// You can make changes to this file and they will not be overwritten when saving.
+//
+// -----------------------------------------------------------------------------
+namespace Showcase {
+ using Terminal.Gui;
+
+
+ public partial class NumericUpDown {
+
+ public NumericUpDown() {
+ InitializeComponent();
+ }
+ }
+}
diff --git a/Showcase/Program.cs b/Showcase/Program.cs
new file mode 100644
index 00000000..a34e6b7c
--- /dev/null
+++ b/Showcase/Program.cs
@@ -0,0 +1,46 @@
+using System.Collections.ObjectModel;
+using System.Runtime.InteropServices.ComTypes;
+using Terminal.Gui;
+
+namespace Showcase
+{
+ internal class Program
+ {
+ private static Type[] views = new[]
+ {
+ typeof(NumericUpDown)
+
+ };
+ static void Main(string[] args)
+ {
+ Application.Init();
+
+ var w = new Window()
+ {
+ Title = "Showcase"
+ };
+
+ var lv = new ListView()
+ {
+ Width = Dim.Fill(),
+ Height = Dim.Fill(),
+ };
+ w.Add(lv);
+ lv.SetSource(new ObservableCollection(views));
+
+
+ lv.KeyDown += (_, e) =>
+ {
+ if (e.KeyCode == KeyCode.Enter)
+ {
+ var v = (Toplevel)Activator.CreateInstance(views[lv.SelectedItem]);
+ e.Handled = true;
+ Application.Run(v);
+ }
+ };
+
+ Application.Run(w);
+ Application.Shutdown();
+ }
+ }
+}
diff --git a/Showcase/README.md b/Showcase/README.md
new file mode 100644
index 00000000..b6b689fe
--- /dev/null
+++ b/Showcase/README.md
@@ -0,0 +1,5 @@
+# Showcase
+
+This project contains only .Designer.cs files created by TerminalGuiDesigner.
+
+The purpose of the project is to ensure backwards compatibility issues are detected quickly as well as providing more structure for manual testing
\ No newline at end of file
diff --git a/Showcase/Showcase.csproj b/Showcase/Showcase.csproj
new file mode 100644
index 00000000..41aa7203
--- /dev/null
+++ b/Showcase/Showcase.csproj
@@ -0,0 +1,14 @@
+
+
+
+ Exe
+ net8.0
+ enable
+ enable
+
+
+
+
+
+
+
diff --git a/Showcase/Slider.Designer.cs b/Showcase/Slider.Designer.cs
new file mode 100644
index 00000000..7ad8e1f7
--- /dev/null
+++ b/Showcase/Slider.Designer.cs
@@ -0,0 +1,144 @@
+
+//------------------------------------------------------------------------------
+
+//
+// This code was generated by:
+// TerminalGuiDesigner v2.0.0.0
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+// -----------------------------------------------------------------------------
+namespace Showcase {
+ using System;
+ using Terminal.Gui;
+ using System.Collections;
+ using System.Collections.Generic;
+ using System.Collections.ObjectModel;
+ using System.Drawing;
+
+
+ public partial class Slider : Terminal.Gui.Window {
+
+ private Terminal.Gui.Label label;
+
+ private Terminal.Gui.Slider slider1;
+
+ private Terminal.Gui.Label lblStringSlider;
+
+ private Terminal.Gui.Slider slider2;
+
+ private Terminal.Gui.Label lblStringSliderThin;
+
+ private Terminal.Gui.Slider slider3;
+
+ private void InitializeComponent() {
+ this.slider3 = new Terminal.Gui.Slider();
+ this.lblStringSliderThin = new Terminal.Gui.Label();
+ this.slider2 = new Terminal.Gui.Slider();
+ this.lblStringSlider = new Terminal.Gui.Label();
+ this.slider1 = new Terminal.Gui.Slider();
+ this.label = new Terminal.Gui.Label();
+ this.Width = Dim.Fill(0);
+ this.Height = Dim.Fill(0);
+ this.X = 0;
+ this.Y = 0;
+ this.Visible = true;
+ this.Arrangement = (Terminal.Gui.ViewArrangement.Movable | Terminal.Gui.ViewArrangement.Overlapped);
+ this.Modal = false;
+ this.TextAlignment = Terminal.Gui.Alignment.Start;
+ this.Title = "";
+ this.label.Width = Dim.Auto();
+ this.label.Height = 1;
+ this.label.X = 0;
+ this.label.Y = 0;
+ this.label.Visible = true;
+ this.label.Arrangement = Terminal.Gui.ViewArrangement.Fixed;
+ this.label.Data = "label";
+ this.label.Text = "Int Slider (0 to 1):";
+ this.label.TextAlignment = Terminal.Gui.Alignment.Start;
+ this.Add(this.label);
+ this.slider1.Width = 20;
+ this.slider1.Height = 2;
+ this.slider1.X = 24;
+ this.slider1.Y = 0;
+ this.slider1.Visible = true;
+ this.slider1.Arrangement = Terminal.Gui.ViewArrangement.Fixed;
+ this.slider1.Options = new System.Collections.Generic.List>(new Terminal.Gui.SliderOption[] {
+ new Terminal.Gui.SliderOption("0", new System.Text.Rune('0'), 0),
+ new Terminal.Gui.SliderOption("1", new System.Text.Rune('1'), 1)});
+ this.slider1.Orientation = Terminal.Gui.Orientation.Horizontal;
+ this.slider1.RangeAllowSingle = false;
+ this.slider1.AllowEmpty = false;
+ this.slider1.MinimumInnerSpacing = 1;
+ this.slider1.LegendsOrientation = Terminal.Gui.Orientation.Horizontal;
+ this.slider1.ShowLegends = true;
+ this.slider1.ShowEndSpacing = false;
+ this.slider1.Type = Terminal.Gui.SliderType.Single;
+ this.slider1.Data = "slider1";
+ this.slider1.TextAlignment = Terminal.Gui.Alignment.Start;
+ this.Add(this.slider1);
+ this.lblStringSlider.Width = Dim.Auto();
+ this.lblStringSlider.Height = 1;
+ this.lblStringSlider.X = 0;
+ this.lblStringSlider.Y = 2;
+ this.lblStringSlider.Visible = true;
+ this.lblStringSlider.Arrangement = Terminal.Gui.ViewArrangement.Fixed;
+ this.lblStringSlider.Data = "lblStringSlider";
+ this.lblStringSlider.Text = "String Slider (Wide):";
+ this.lblStringSlider.TextAlignment = Terminal.Gui.Alignment.Start;
+ this.Add(this.lblStringSlider);
+ this.slider2.Width = 31;
+ this.slider2.Height = 2;
+ this.slider2.X = Pos.Right(lblStringSlider) + 2;
+ this.slider2.Y = 2;
+ this.slider2.Visible = true;
+ this.slider2.Arrangement = Terminal.Gui.ViewArrangement.Fixed;
+ this.slider2.Options = new System.Collections.Generic.List>(new Terminal.Gui.SliderOption[] {
+ new Terminal.Gui.SliderOption("Fish", new System.Text.Rune('F'), "Fish"),
+ new Terminal.Gui.SliderOption("Cat", new System.Text.Rune('C'), "Cat"),
+ new Terminal.Gui.SliderOption("Ball", new System.Text.Rune('B'), "Ball")});
+ this.slider2.Orientation = Terminal.Gui.Orientation.Horizontal;
+ this.slider2.RangeAllowSingle = false;
+ this.slider2.AllowEmpty = false;
+ this.slider2.MinimumInnerSpacing = 1;
+ this.slider2.LegendsOrientation = Terminal.Gui.Orientation.Horizontal;
+ this.slider2.ShowLegends = true;
+ this.slider2.ShowEndSpacing = false;
+ this.slider2.Type = Terminal.Gui.SliderType.Single;
+ this.slider2.Data = "slider2";
+ this.slider2.TextAlignment = Terminal.Gui.Alignment.Start;
+ this.Add(this.slider2);
+ this.lblStringSliderThin.Width = Dim.Auto();
+ this.lblStringSliderThin.Height = 1;
+ this.lblStringSliderThin.X = 0;
+ this.lblStringSliderThin.Y = 4;
+ this.lblStringSliderThin.Visible = true;
+ this.lblStringSliderThin.Arrangement = Terminal.Gui.ViewArrangement.Fixed;
+ this.lblStringSliderThin.Data = "lblStringSliderThin";
+ this.lblStringSliderThin.Text = "String Slider (Thin):";
+ this.lblStringSliderThin.TextAlignment = Terminal.Gui.Alignment.Start;
+ this.Add(this.lblStringSliderThin);
+ this.slider3.Width = 6;
+ this.slider3.Height = 2;
+ this.slider3.X = Pos.Right(lblStringSliderThin) + 2;
+ this.slider3.Y = 4;
+ this.slider3.Visible = true;
+ this.slider3.Arrangement = Terminal.Gui.ViewArrangement.Fixed;
+ this.slider3.Options = new System.Collections.Generic.List>(new Terminal.Gui.SliderOption[] {
+ new Terminal.Gui.SliderOption("Fish", new System.Text.Rune('F'), "Fish"),
+ new Terminal.Gui.SliderOption("Cat", new System.Text.Rune('C'), "Cat"),
+ new Terminal.Gui.SliderOption("Ball", new System.Text.Rune('B'), "Ball")});
+ this.slider3.Orientation = Terminal.Gui.Orientation.Horizontal;
+ this.slider3.RangeAllowSingle = false;
+ this.slider3.AllowEmpty = false;
+ this.slider3.MinimumInnerSpacing = 1;
+ this.slider3.LegendsOrientation = Terminal.Gui.Orientation.Horizontal;
+ this.slider3.ShowLegends = true;
+ this.slider3.ShowEndSpacing = false;
+ this.slider3.Type = Terminal.Gui.SliderType.Single;
+ this.slider3.Data = "slider3";
+ this.slider3.TextAlignment = Terminal.Gui.Alignment.Start;
+ this.Add(this.slider3);
+ }
+ }
+}
diff --git a/Showcase/Slider.cs b/Showcase/Slider.cs
new file mode 100644
index 00000000..b74cacdd
--- /dev/null
+++ b/Showcase/Slider.cs
@@ -0,0 +1,20 @@
+
+//------------------------------------------------------------------------------
+
+//
+// This code was generated by:
+// TerminalGuiDesigner v2.0.0.0
+// You can make changes to this file and they will not be overwritten when saving.
+//
+// -----------------------------------------------------------------------------
+namespace Showcase {
+ using Terminal.Gui;
+
+
+ public partial class Slider {
+
+ public Slider() {
+ InitializeComponent();
+ }
+ }
+}
diff --git a/src/Design.cs b/src/Design.cs
index 71716320..a789ef8b 100644
--- a/src/Design.cs
+++ b/src/Design.cs
@@ -50,6 +50,7 @@ public class Design
typeof(TabView),
typeof(TreeView),
typeof(Dialog),
+ typeof(NumericUpDown)
};
///
@@ -213,17 +214,24 @@ public Design CreateSubControlDesign(string name, View subView)
if (subView is TextView txt)
{
// prevent control from responding to events
- txt.MouseClick += this.SuppressNativeClickEvents;
+ txt.MouseClick += (s, e) => this.SuppressNativeClickEvents(s, e);
txt.KeyDown += this.SuppressNativeKeyboardEvents;
}
if (subView is TextField tf)
{
// prevent control from responding to events
- tf.MouseClick += this.SuppressNativeClickEvents;
+ tf.MouseClick += (s,e)=>this.SuppressNativeClickEvents(s,e);
tf.KeyDown += SuppressNativeKeyboardEvents;
}
+ if (subView.GetType().IsGenericType(typeof(Slider<>)))
+ {
+ // TODO: Does not seem to work
+ subView.MouseEvent += (s, e) => SuppressNativeClickEvents(s, e,true);
+ subView.MouseClick += (s, e) => SuppressNativeClickEvents(s,e, true);
+ }
+
if (subView is TreeView tree)
{
tree.AddObject(new TreeNode("Example Branch 1")
@@ -244,6 +252,14 @@ public Design CreateSubControlDesign(string name, View subView)
tree.AddObject(new TreeNode($"Example Leaf {l}"));
}
}
+
+ // Disable click events for sub controls. This allows you to prevent clicking
+ // in non designed subcomponents e.g. the bar of a true color picker.
+ foreach (var v in subView.GetAllNonDesignableSubviews())
+ {
+ v.MouseClick += (s,e)=>this.SuppressNativeClickEvents(s,e,true);
+ v.MouseEvent += (s, e) => this.SuppressNativeClickEvents(s, e, true);
+ }
var d = new Design(this.SourceCode, name, subView);
return d;
@@ -610,10 +626,17 @@ private void CreateSubControlDesigns(View view)
}
}
- private void SuppressNativeClickEvents(object? sender, MouseEventEventArgs obj)
+ private void SuppressNativeClickEvents(object? sender, MouseEventEventArgs obj, bool alsoSuppressClick = false)
{
- // Suppress everything except single click (selection)
- obj.Handled = obj.MouseEvent.Flags != MouseFlags.Button1Clicked;
+ if (alsoSuppressClick)
+ {
+ obj.Handled = true;
+ }
+ else
+ {
+ // Suppress everything except single click (selection)
+ obj.Handled = obj.MouseEvent.Flags != MouseFlags.Button1Clicked;
+ }
}
private void SuppressNativeKeyboardEvents(object? sender, Key e)
@@ -850,6 +873,15 @@ private IEnumerable LoadDesignableProperties()
{
yield return this.CreateProperty(nameof(RadioGroup.RadioLabels));
}
+
+ if (viewType.IsGenericType(typeof(NumericUpDown<>)))
+ {
+ yield return this.CreateProperty(nameof(NumericUpDown.Value));
+ yield return this.CreateProperty(nameof(NumericUpDown.Increment));
+
+ // TODO: Probably needs some thought
+ // yield return this.CreateProperty(nameof(NumericUpDown.Format));
+ }
}
private Property CreateTreeObjectsProperty(Type viewType)
@@ -879,7 +911,7 @@ private bool ShowTextProperty()
}
// Do not let Text be set on Slider or Slider<> implementations as weird stuff happens
- if(this.View.GetType().Name.StartsWith("Slider") || View is RadioGroup)
+ if(this.View.GetType().Name.StartsWith("Slider") || View is RadioGroup || View.GetType().IsGenericType(typeof(NumericUpDown<>)))
{
return false;
}
diff --git a/src/TTypes.cs b/src/TTypes.cs
index 54891b8f..a8846499 100644
--- a/src/TTypes.cs
+++ b/src/TTypes.cs
@@ -45,6 +45,18 @@ public static IEnumerable GetSupportedTTypesForGenericViewOfType(Type view
return new[] { typeof(int), typeof(string), typeof(int), typeof(double), typeof(bool) };
}
+ if (viewType == typeof(NumericUpDown<>))
+ {
+ return new[]
+ {
+ typeof(int),
+ typeof(long),
+ typeof(double),
+ typeof(float),
+ typeof(decimal)
+ };
+ }
+
if (viewType == typeof(TreeView<>))
{
return new[] { typeof(object), typeof(FileSystemInfo) };
diff --git a/src/TerminalGuiDesigner.sln b/src/TerminalGuiDesigner.sln
index a6ea7300..1cf838bd 100644
--- a/src/TerminalGuiDesigner.sln
+++ b/src/TerminalGuiDesigner.sln
@@ -16,6 +16,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTests", "..\tests\UnitTests.csproj", "{A207B4E2-4821-4710-A0C2-25236DE7FE99}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Showcase", "..\Showcase\Showcase.csproj", "{32B7F842-1495-405B-B24B-55C48268FFA5}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -30,6 +32,10 @@ Global
{A207B4E2-4821-4710-A0C2-25236DE7FE99}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A207B4E2-4821-4710-A0C2-25236DE7FE99}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A207B4E2-4821-4710-A0C2-25236DE7FE99}.Release|Any CPU.Build.0 = Release|Any CPU
+ {32B7F842-1495-405B-B24B-55C48268FFA5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {32B7F842-1495-405B-B24B-55C48268FFA5}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {32B7F842-1495-405B-B24B-55C48268FFA5}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {32B7F842-1495-405B-B24B-55C48268FFA5}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/src/UI/ValueFactory.cs b/src/UI/ValueFactory.cs
index eda75e2d..8f38fbdd 100644
--- a/src/UI/ValueFactory.cs
+++ b/src/UI/ValueFactory.cs
@@ -11,155 +11,92 @@ namespace TerminalGuiDesigner.UI
{
static class ValueFactory
{
+ public static readonly Type[] ConvertChangeTypeSupports = new Type[]
+ {
+ typeof(byte),
+ typeof(sbyte),
+ typeof(short),
+ typeof(ushort),
+ typeof(int),
+ typeof(uint),
+ typeof(long),
+ typeof(ulong),
+ typeof(float),
+ typeof(double),
+ typeof(decimal),
+ typeof(bool),
+ typeof(char),
+ typeof(string),
+ typeof(DateTime),
+
+ typeof(byte?),
+ typeof(sbyte?),
+ typeof(short?),
+ typeof(ushort?),
+ typeof(int?),
+ typeof(uint?),
+ typeof(long?),
+ typeof(ulong?),
+ typeof(float?),
+ typeof(double?),
+ typeof(decimal?),
+ typeof(bool?),
+ typeof(char?),
+ typeof(DateTime?)
+ };
+
internal static bool GetNewValue(string propertyName, Design design, Type type, object? oldValue, out object? newValue, bool allowMultiLine)
{
newValue = null;
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(SliderOption<>))
{
- var designer = new SliderOptionEditor(type.GetGenericArguments()[0], oldValue);
- Application.Run(designer);
-
- if (!designer.Cancelled)
- {
- newValue = designer.Result;
- return true;
- }
- else
- {
- // user canceled designing the Option
- return false;
- }
+ return RunEditor(new SliderOptionEditor(type.GetGenericArguments()[0], oldValue), out newValue);
}
- else
- if (type== typeof(ColorScheme))
+ if (type == typeof(ColorScheme))
{
return GetNewColorSchemeValue(design, out newValue);
}
- else
- if (type == typeof(Attribute) ||
- type == typeof(Attribute?))
+ if (type == typeof(Attribute) || type == typeof(Attribute?))
{
- // if its an Attribute or nullableAttribute
- var picker = new ColorPicker((Attribute?)oldValue);
- Application.Run(picker);
-
- if (!picker.Cancelled)
- {
- newValue = picker.Result;
- return true;
- }
- else
- {
- // user cancelled designing the Color
- newValue = null;
- return false;
- }
+ return RunEditor(new ColorPicker((Attribute?)oldValue), out newValue);
}
- else
- if (type== typeof(ITextValidateProvider))
+ if (type == typeof(Pos))
{
- string? oldPattern = oldValue is TextRegexProvider r ? (string?)r.Pattern.ToPrimitive() : null;
- if (Modals.GetString("New Validation Pattern", "Regex Pattern", oldPattern, out var newPattern))
- {
- newValue = string.IsNullOrWhiteSpace(newPattern) ? null : new TextRegexProvider(newPattern);
- return true;
- }
-
- // user cancelled entering a pattern
- newValue = null;
- return false;
+ return RunEditor(new PosEditor(design, (Pos)oldValue ?? throw new Exception("Pos property was unexpectedly null")), out newValue);
}
- else
- if (type== typeof(Pos))
+ if (type == typeof(Size))
{
- // user is editing a Pos
- var designer = new PosEditor(design, (Pos)oldValue?? throw new Exception("Pos property was unexpectedly null"));
-
- Application.Run(designer);
-
- if (!designer.Cancelled)
- {
- newValue = designer.Result;
- return true;
- }
- else
- {
- // user cancelled designing the Pos
- newValue = null;
- return false;
- }
+ return RunEditor(new SizeEditor((Size)(oldValue ?? throw new Exception($"Property {propertyName} is of Type Size but its current value is null"))), out newValue);
}
- else
- if (type== typeof(Size))
+ if (type == typeof(Point))
{
- // user is editing a Size
- var oldSize = (Size)(oldValue ?? throw new Exception($"Property {propertyName} is of Type Size but it's current value is null"));
- var designer = new SizeEditor(oldSize);
+ var oldPoint = (Point)(oldValue ?? throw new Exception($"Property {propertyName} is of Type Point but its current value is null"));
+ var result = RunEditor(new PointEditor(oldPoint.X, oldPoint.Y), out newValue);
- Application.Run(designer);
-
- if (!designer.Cancelled)
- {
- newValue = designer.Result;
- return true;
- }
- else
+ if (newValue != null)
{
- // user cancelled designing the Pos
- newValue = null;
- return false;
+ newValue = new Point((int)((PointF)newValue).X, (int)((PointF)newValue).Y);
}
+ return result;
+
}
- else
- if (type== typeof(PointF))
+ if (type == typeof(PointF))
{
- // user is editing a PointF
- var oldPointF = (PointF)(oldValue ?? throw new Exception($"Property {propertyName} is of Type PointF but it's current value is null"));
- var designer = new PointEditor(oldPointF.X, oldPointF.Y);
-
- Application.Run(designer);
-
- if (!designer.Cancelled)
- {
- newValue = new PointF(designer.ResultX, designer.ResultY);
- return true;
- }
- else
- {
- // user cancelled designing the Pos
- newValue = null;
- return false;
- }
+ var oldPointF = (PointF)(oldValue ?? throw new Exception($"Property {propertyName} is of Type PointF but its current value is null"));
+ return RunEditor(new PointEditor(oldPointF.X, oldPointF.Y), out newValue);
}
- else
- if (type== typeof(Dim))
+ if (type == typeof(Dim))
{
- // user is editing a Dim
- var designer = new DimEditor(design, (Dim)oldValue);
- Application.Run(designer);
-
- if (!designer.Cancelled)
- {
- newValue = designer.Result;
- return true;
- }
- else
- {
- // user cancelled designing the Dim
- newValue = null;
- return false;
- }
+ return RunEditor(new DimEditor(design, (Dim)oldValue), out newValue);
}
- else
- if (type== typeof(bool))
+ if (type == typeof(bool))
{
int answer = ChoicesDialog.Query(propertyName, $"New value for {type}", "Yes", "No");
-
newValue = answer == 0 ? true : false;
return answer != -1;
}
- else
+
if (
type.IsGenericType(typeof(IEnumerable<>)) ||
type.IsAssignableTo(typeof(IList))
@@ -183,12 +120,12 @@ internal static bool GetNewValue(string propertyName, Design design, Type type,
}
else
{
- var designer = new ArrayEditor(design,type.GetElementTypeEx(), (IList)oldValue);
+ var designer = new ArrayEditor(design, type.GetElementTypeEx(), (IList)oldValue);
Application.Run(designer);
if (!designer.Cancelled)
{
- newValue = designer.Result;
+ newValue = designer.ResultAsList;
return true;
}
else
@@ -198,10 +135,9 @@ internal static bool GetNewValue(string propertyName, Design design, Type type,
return false;
}
}
-
}
else
- if (type== typeof(IListDataSource))
+ if (type == typeof(IListDataSource))
{
// TODO : Make this work with non strings e.g.
// if user types a bunch of numbers in or dates
@@ -232,38 +168,12 @@ internal static bool GetNewValue(string propertyName, Design design, Type type,
}
}
else
- if (type== typeof(int)
- || type== typeof(int?)
- || type== typeof(uint)
- || type== typeof(uint?))
+ if (ConvertChangeTypeSupports.Contains(type))
{
- // deals with null, int and uint
- var v = oldValue == null ? null : (int?)Convert.ToInt32(oldValue);
-
- if (Modals.GetInt(propertyName, "New Int Value", v, out var resultInt))
- {
- // change back to uint/int/null
- newValue = resultInt == null ? null : Convert.ChangeType(resultInt, type);
- return true;
- }
- }
- else
- if (type== typeof(int)
- || type== typeof(int?))
- {
- if (Modals.Getint(propertyName, "New int Value", (int?)oldValue, out var resultInt))
- {
- newValue = resultInt;
- return true;
- }
- }
- else
- if (type== typeof(char?)
- || type== typeof(char))
- {
- if (Modals.GetChar(propertyName, "New Single Character", oldValue is null ? null : (char?)oldValue.ToPrimitive() ?? null, out var resultChar))
+ var oldValueConverted = oldValue == null ? null : Convert.ChangeType(oldValue, type);
+ if (Modals.GetString(propertyName, $"New {type.Name} Value", oldValueConverted?.ToString(), out var result, allowMultiLine))
{
- newValue = resultChar;
+ newValue = string.IsNullOrWhiteSpace(result) ? null : Convert.ChangeType(result, type);
return true;
}
}
@@ -283,7 +193,6 @@ internal static bool GetNewValue(string propertyName, Design design, Type type,
var fd = new FileDialog();
fd.AllowsMultipleSelection = false;
-
int answer = ChoicesDialog.Query(propertyName, $"Directory or File?", "Directory", "File", "Cancel");
if (answer < 0 || answer >= 2)
@@ -301,7 +210,7 @@ internal static bool GetNewValue(string propertyName, Design design, Type type,
}
else
{
- newValue = pickDir ?
+ newValue = pickDir ?
new DirectoryInfo(fd.Path) : new FileInfo(fd.Path);
return true;
}
@@ -316,6 +225,20 @@ internal static bool GetNewValue(string propertyName, Design design, Type type,
newValue = null;
return false;
}
+
+ private static bool RunEditor(T editor, out object? result) where T : Dialog, IValueGetterDialog
+ {
+ Application.Run(editor);
+ if (editor.Cancelled)
+ {
+ result = null;
+ return false;
+ }
+
+ result = editor.Result;
+ return true;
+ }
+
internal static bool GetNewValue(Design design, Property property, object? oldValue, out object? newValue)
{
if (property is InstanceOfProperty inst)
@@ -343,7 +266,7 @@ internal static bool GetNewValue(Design design, Property property, object? oldVa
}
else
{
- return GetNewValue(property.PropertyInfo.Name, design, property.PropertyInfo.PropertyType,oldValue, out newValue, ValueFactory.AllowMultiLine(property));
+ return GetNewValue(property.PropertyInfo.Name, design, property.PropertyInfo.PropertyType, oldValue, out newValue, ValueFactory.AllowMultiLine(property));
}
}
@@ -416,6 +339,6 @@ private static bool GetNewColorSchemeValue(Design design, out object? newValue)
newValue = null;
return false;
}
- }
+ }
}
}
diff --git a/src/UI/Windows/ArrayEditor.cs b/src/UI/Windows/ArrayEditor.cs
index 5d493ef7..15f820ba 100644
--- a/src/UI/Windows/ArrayEditor.cs
+++ b/src/UI/Windows/ArrayEditor.cs
@@ -9,13 +9,14 @@
// -----------------------------------------------------------------------------
using System.Collections.ObjectModel;
+using JetBrains.Annotations;
namespace TerminalGuiDesigner.UI.Windows {
using System.Collections;
using Terminal.Gui;
using TerminalGuiDesigner.ToCode;
- public partial class ArrayEditor {
+ public partial class ArrayEditor : IValueGetterDialog {
///
/// True if the editing was aborted.
@@ -28,7 +29,10 @@ public partial class ArrayEditor {
///
/// The new array
///
- public IList Result { get; private set; }
+ [CanBeNull]
+ public object Result => ResultAsList;
+ public IList ResultAsList { get; private set; }
+
///
/// Creates a new instance of the editor configured to build lists of
@@ -43,14 +47,14 @@ public ArrayEditor(Design design, Type elementType, IList oldValue) {
this.elementType = elementType;
Type listType = typeof(List<>).MakeGenericType(elementType);
- Result = (IList)Activator.CreateInstance(listType);
+ ResultAsList = (IList)Activator.CreateInstance(listType);
foreach(var e in oldValue)
{
- Result.Add(e);
+ ResultAsList.Add(e);
}
- lvElements.Source = Result.ToListDataSource();
+ lvElements.Source = ResultAsList.ToListDataSource();
lvElements.KeyDown += LvElements_KeyDown;
btnOk.Accept += BtnOk_Clicked;
btnCancel.Accept += BtnCancel_Clicked;
@@ -67,14 +71,14 @@ private void BtnMoveUp_Clicked(object sender, EventArgs e)
// Moving up means reducing the index by 1
var idx = lvElements.SelectedItem;
- if (idx >= 1 && idx < Result.Count)
+ if (idx >= 1 && idx < ResultAsList.Count)
{
- var toMove = Result[idx];
+ var toMove = ResultAsList[idx];
var newIndex = idx - 1;
- Result.RemoveAt(idx);
- Result.Insert(newIndex, toMove);
+ ResultAsList.RemoveAt(idx);
+ ResultAsList.Insert(newIndex, toMove);
- lvElements.Source = Result.ToListDataSource();
+ lvElements.Source = ResultAsList.ToListDataSource();
lvElements.SelectedItem = newIndex;
lvElements.SetNeedsDisplay();
}
@@ -85,14 +89,14 @@ private void BtnMoveDown_Clicked(object sender, EventArgs e)
// Moving up means increasing the index by 1
var idx = lvElements.SelectedItem;
- if (idx >= 0 && idx < Result.Count-1)
+ if (idx >= 0 && idx < ResultAsList.Count-1)
{
- var toMove = Result[idx];
+ var toMove = ResultAsList[idx];
var newIndex = idx + 1;
- Result.RemoveAt(idx);
- Result.Insert(newIndex, toMove);
+ ResultAsList.RemoveAt(idx);
+ ResultAsList.Insert(newIndex, toMove);
- lvElements.Source = Result.ToListDataSource();
+ lvElements.Source = ResultAsList.ToListDataSource();
lvElements.SelectedItem = newIndex;
lvElements.SetNeedsDisplay();
}
@@ -111,11 +115,11 @@ private void DeleteSelectedItem()
{
var idx = lvElements.SelectedItem;
- if (idx >= 0 && idx < Result.Count)
+ if (idx >= 0 && idx < ResultAsList.Count)
{
- Result.RemoveAt(idx);
+ ResultAsList.RemoveAt(idx);
- lvElements.Source = Result.ToListDataSource();
+ lvElements.Source = ResultAsList.ToListDataSource();
lvElements.SetNeedsDisplay();
lvElements.SelectedItem = 0;
}
@@ -125,29 +129,29 @@ private void BtnAddElement_Clicked(object sender, EventArgs e)
{
if(ValueFactory.GetNewValue("Element Value", design, this.elementType,null, out var newValue,true))
{
- Result.Add(newValue);
+ ResultAsList.Add(newValue);
}
- lvElements.Source = Result.ToListDataSource();
- lvElements.SelectedItem = Result.Count - 1;
+ lvElements.Source = ResultAsList.ToListDataSource();
+ lvElements.SelectedItem = ResultAsList.Count - 1;
lvElements.SetNeedsDisplay();
}
private void BtnEdit_Clicked(object sender, EventArgs e)
{
var idx = lvElements.SelectedItem;
- if (idx >= 0 && idx < Result.Count)
+ if (idx >= 0 && idx < ResultAsList.Count)
{
- var toEdit = Result[idx];
+ var toEdit = ResultAsList[idx];
if (ValueFactory.GetNewValue("Element Value", design, this.elementType, toEdit, out var newValue, true))
{
// Replace old with new
- Result.RemoveAt(idx);
- Result.Insert(idx, newValue);
+ ResultAsList.RemoveAt(idx);
+ ResultAsList.Insert(idx, newValue);
}
- lvElements.Source = Result.ToListDataSource();
+ lvElements.Source = ResultAsList.ToListDataSource();
lvElements.SelectedItem = idx;
lvElements.SetNeedsDisplay();
}
diff --git a/src/UI/Windows/ColorPicker.cs b/src/UI/Windows/ColorPicker.cs
index 7cc28c5e..0959281d 100644
--- a/src/UI/Windows/ColorPicker.cs
+++ b/src/UI/Windows/ColorPicker.cs
@@ -15,12 +15,12 @@ namespace TerminalGuiDesigner.UI.Windows;
///
/// Prompts user to pick a two to make an .
///
-public partial class ColorPicker
+public partial class ColorPicker : IValueGetterDialog
{
///
/// The combination of foreground and background the user chose.
///
- public Terminal.Gui.Attribute? Result { get; internal set; }
+ public object Result { get; internal set; }
///
/// True if user closed dialog with cancel.
diff --git a/src/UI/Windows/ColorSchemeEditor.cs b/src/UI/Windows/ColorSchemeEditor.cs
index 3903fc24..c91f1dc9 100644
--- a/src/UI/Windows/ColorSchemeEditor.cs
+++ b/src/UI/Windows/ColorSchemeEditor.cs
@@ -115,10 +115,10 @@ private MutableColorScheme Clone(ColorScheme scheme)
private Terminal.Gui.Attribute PickNewColorsFor(Terminal.Gui.Attribute current)
{
- var pick = new ColorPicker(current);
+ var pick = new Windows.ColorPicker(current);
Application.Run(pick);
- return pick.Cancelled ? current : pick.Result ?? current;
+ return pick.Cancelled ? current : (Attribute?)pick.Result ?? current;
}
private void SetColorPatches()
diff --git a/src/UI/Windows/DimEditor.cs b/src/UI/Windows/DimEditor.cs
index 1697ed5d..3ac81a44 100644
--- a/src/UI/Windows/DimEditor.cs
+++ b/src/UI/Windows/DimEditor.cs
@@ -7,6 +7,8 @@
//
//------------------------------------------------------------------------------
+using JetBrains.Annotations;
+
namespace TerminalGuiDesigner.UI.Windows;
using Terminal.Gui;
@@ -16,7 +18,7 @@ namespace TerminalGuiDesigner.UI.Windows;
///
/// Editor for the class.
///
-public partial class DimEditor : Dialog
+public partial class DimEditor : Dialog, IValueGetterDialog
{
private Design design;
@@ -24,7 +26,8 @@ public partial class DimEditor : Dialog
/// The final value user has configured based on
/// radio buttons and text box values.
///
- public Dim Result { get; private set; }
+ [CanBeNull]
+ public object Result { get; private set; }
///
/// True if dialog was canceled.
diff --git a/src/UI/Windows/IValueGetterDialog.cs b/src/UI/Windows/IValueGetterDialog.cs
new file mode 100644
index 00000000..7bca25f4
--- /dev/null
+++ b/src/UI/Windows/IValueGetterDialog.cs
@@ -0,0 +1,8 @@
+#nullable disable
+namespace TerminalGuiDesigner.UI.Windows;
+
+public interface IValueGetterDialog
+{
+ public object? Result { get; }
+ public bool Cancelled { get; }
+}
\ No newline at end of file
diff --git a/src/UI/Windows/Modals.cs b/src/UI/Windows/Modals.cs
index 12205c30..51f68295 100644
--- a/src/UI/Windows/Modals.cs
+++ b/src/UI/Windows/Modals.cs
@@ -39,27 +39,6 @@ public static bool GetInt(string windowTitle, string entryLabel, int? initialVal
return false;
}
- internal static bool Getint(string windowTitle, string entryLabel, int? initialValue, out int? result)
- {
- if (GetString(windowTitle, entryLabel, initialValue.ToString(), out var newValue))
- {
- if (string.IsNullOrWhiteSpace(newValue))
- {
- result = null;
- return true;
- }
-
- if (int.TryParse(newValue, out var r))
- {
- result = r;
- return true;
- }
- }
-
- result = 0;
- return false;
- }
-
internal static bool GetArray(string windowTitle, string entryLabel, Type arrayElement, Array? initialValue, out Array? result)
{
var dlg = new GetTextDialog(
diff --git a/src/UI/Windows/PointEditor.cs b/src/UI/Windows/PointEditor.cs
index a495bd0c..4daaef18 100644
--- a/src/UI/Windows/PointEditor.cs
+++ b/src/UI/Windows/PointEditor.cs
@@ -7,6 +7,9 @@
//
//------------------------------------------------------------------------------
+using JetBrains.Annotations;
+using TerminalGuiDesigner.UI.Windows;
+
namespace TerminalGuiDesigner;
using System;
using Terminal.Gui;
@@ -14,7 +17,7 @@ namespace TerminalGuiDesigner;
///
/// Pop-up editor for creating a .
///
-public partial class PointEditor {
+public partial class PointEditor : IValueGetterDialog {
///
/// Gets a value indicating whether user cancelled the dialog before
@@ -32,6 +35,8 @@ public partial class PointEditor {
///
public float ResultY {get;private set;}
+ [CanBeNull] public object Result => new PointF(ResultX, ResultY);
+
///
/// Creates a new instance of the class.
///
diff --git a/src/UI/Windows/PosEditor.cs b/src/UI/Windows/PosEditor.cs
index a1ea77ec..7b65d2b9 100644
--- a/src/UI/Windows/PosEditor.cs
+++ b/src/UI/Windows/PosEditor.cs
@@ -7,6 +7,8 @@
//
//------------------------------------------------------------------------------
+using JetBrains.Annotations;
+
namespace TerminalGuiDesigner.UI.Windows;
using Terminal.Gui;
@@ -18,7 +20,7 @@ namespace TerminalGuiDesigner.UI.Windows;
///
/// Editor for the type.
///
-public partial class PosEditor : Dialog {
+public partial class PosEditor : Dialog, IValueGetterDialog {
private Design design;
@@ -26,7 +28,8 @@ public partial class PosEditor : Dialog {
/// Users configured (assembled from radio button
/// selected and text values entered - offset etc).
///
- public Pos Result { get; private set; }
+ [CanBeNull]
+ public object Result { get; private set; }
///
/// True if user cancelled the dialog instead of hitting Ok.
diff --git a/src/UI/Windows/SizeEditor.cs b/src/UI/Windows/SizeEditor.cs
index 5b35961c..afe00549 100644
--- a/src/UI/Windows/SizeEditor.cs
+++ b/src/UI/Windows/SizeEditor.cs
@@ -14,13 +14,13 @@ namespace TerminalGuiDesigner.UI.Windows;
///
/// Popup editor for the class.
///
-public partial class SizeEditor
+public partial class SizeEditor : IValueGetterDialog
{
///
/// The users edited
///
- public Size Result { get; private set; }
+ public object? Result { get; private set; }
///
/// True if user cancelled the dialog instead of hitting "Ok".
diff --git a/src/UI/Windows/SliderOptionEditor.Designer.cs b/src/UI/Windows/SliderOptionEditor.Designer.cs
index 38d01acb..b19f3a85 100644
--- a/src/UI/Windows/SliderOptionEditor.Designer.cs
+++ b/src/UI/Windows/SliderOptionEditor.Designer.cs
@@ -3,7 +3,7 @@
//
// This code was generated by:
-// TerminalGuiDesigner v1.1.0.0
+// TerminalGuiDesigner v2.0.0.0
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
//
@@ -13,6 +13,8 @@ namespace TerminalGuiDesigner.UI.Windows {
using Terminal.Gui;
using System.Collections;
using System.Collections.Generic;
+ using System.Collections.ObjectModel;
+ using System.Drawing;
public partial class SliderOptionEditor : Terminal.Gui.Dialog {
@@ -52,34 +54,23 @@ private void InitializeComponent() {
this.label2 = new Terminal.Gui.Label();
this.tfLegend = new Terminal.Gui.TextField();
this.label = new Terminal.Gui.Label();
- this.redOnBlack = new Terminal.Gui.ColorScheme(
- new Terminal.Gui.Attribute(Terminal.Gui.Color.Red, Terminal.Gui.Color.Black),
- new Terminal.Gui.Attribute(Terminal.Gui.Color.Red, Terminal.Gui.Color.Yellow),
- new Terminal.Gui.Attribute(Terminal.Gui.Color.BrightRed, Terminal.Gui.Color.Black),
- new Terminal.Gui.Attribute(Terminal.Gui.Color.Gray, Terminal.Gui.Color.Black),
- new Terminal.Gui.Attribute(Terminal.Gui.Color.BrightRed, Terminal.Gui.Color.Yellow)
- );
-
- this.tgDefault = new Terminal.Gui.ColorScheme(
- new Terminal.Gui.Attribute(Terminal.Gui.Color.White, Terminal.Gui.Color.Blue),
- new Terminal.Gui.Attribute(Terminal.Gui.Color.Black, Terminal.Gui.Color.Gray),
- new Terminal.Gui.Attribute(Terminal.Gui.Color.BrightCyan, Terminal.Gui.Color.Blue),
- new Terminal.Gui.Attribute(Terminal.Gui.Color.Yellow, Terminal.Gui.Color.Blue),
- new Terminal.Gui.Attribute(Terminal.Gui.Color.BrightBlue, Terminal.Gui.Color.Gray)
- );
+ this.redOnBlack = new Terminal.Gui.ColorScheme(new Terminal.Gui.Attribute(4291104543u, 4278979596u), new Terminal.Gui.Attribute(4291104543u, 4286595104u), new Terminal.Gui.Attribute(4293347414u, 4278979596u), new Terminal.Gui.Attribute(4291611852u, 4278979596u), new Terminal.Gui.Attribute(4293347414u, 4286595104u));
+ this.tgDefault = new Terminal.Gui.ColorScheme(new Terminal.Gui.Attribute(4294111986u, 4278204378u), new Terminal.Gui.Attribute(4278979596u, 4291611852u), new Terminal.Gui.Attribute(4284602070u, 4278204378u), new Terminal.Gui.Attribute(4286595104u, 4278204378u), new Terminal.Gui.Attribute(4282087679u, 4291611852u));
this.Width = 50;
this.Height = 8;
this.X = Pos.Center();
this.Y = Pos.Center();
this.Visible = true;
+ this.Arrangement = Terminal.Gui.ViewArrangement.Movable;
this.Modal = true;
this.TextAlignment = Terminal.Gui.Alignment.Start;
this.Title = "OptionEditor";
- this.label.Width = 4;
+ this.label.Width = Dim.Auto();
this.label.Height = 1;
this.label.X = 6;
this.label.Y = 0;
this.label.Visible = true;
+ this.label.Arrangement = Terminal.Gui.ViewArrangement.Fixed;
this.label.Data = "label";
this.label.Text = "Legend:";
this.label.TextAlignment = Terminal.Gui.Alignment.Start;
@@ -89,16 +80,18 @@ private void InitializeComponent() {
this.tfLegend.X = 14;
this.tfLegend.Y = 0;
this.tfLegend.Visible = true;
+ this.tfLegend.Arrangement = Terminal.Gui.ViewArrangement.Fixed;
this.tfLegend.Secret = false;
this.tfLegend.Data = "tfLegend";
this.tfLegend.Text = "";
this.tfLegend.TextAlignment = Terminal.Gui.Alignment.Start;
this.Add(this.tfLegend);
- this.label2.Width = 4;
+ this.label2.Width = Dim.Auto();
this.label2.Height = 1;
this.label2.X = 0;
this.label2.Y = 1;
this.label2.Visible = true;
+ this.label2.Arrangement = Terminal.Gui.ViewArrangement.Fixed;
this.label2.Data = "label2";
this.label2.Text = "Abbreviation:";
this.label2.TextAlignment = Terminal.Gui.Alignment.Start;
@@ -108,25 +101,28 @@ private void InitializeComponent() {
this.tfLegendAbbr.X = 14;
this.tfLegendAbbr.Y = 1;
this.tfLegendAbbr.Visible = true;
+ this.tfLegendAbbr.Arrangement = Terminal.Gui.ViewArrangement.Fixed;
this.tfLegendAbbr.Secret = false;
this.tfLegendAbbr.Data = "tfLegendAbbr";
this.tfLegendAbbr.Text = "";
this.tfLegendAbbr.TextAlignment = Terminal.Gui.Alignment.Start;
this.Add(this.tfLegendAbbr);
- this.lblOneChar.Width = 10;
+ this.lblOneChar.Width = Dim.Auto();
this.lblOneChar.Height = 1;
this.lblOneChar.X = 0;
this.lblOneChar.Y = 2;
this.lblOneChar.Visible = true;
+ this.lblOneChar.Arrangement = Terminal.Gui.ViewArrangement.Fixed;
this.lblOneChar.Data = "lblOneChar";
this.lblOneChar.Text = "(Single Char) ";
this.lblOneChar.TextAlignment = Terminal.Gui.Alignment.Center;
this.Add(this.lblOneChar);
- this.label3.Width = 4;
+ this.label3.Width = Dim.Auto();
this.label3.Height = 1;
- this.label3.X = 7;
+ this.label3.X = 8;
this.label3.Y = 3;
this.label3.Visible = true;
+ this.label3.Arrangement = Terminal.Gui.ViewArrangement.Fixed;
this.label3.Data = "label3";
this.label3.Text = "Data:";
this.label3.TextAlignment = Terminal.Gui.Alignment.Start;
@@ -136,6 +132,7 @@ private void InitializeComponent() {
this.tfData.X = 14;
this.tfData.Y = 3;
this.tfData.Visible = true;
+ this.tfData.Arrangement = Terminal.Gui.ViewArrangement.Fixed;
this.tfData.Secret = false;
this.tfData.Data = "tfData";
this.tfData.Text = "";
@@ -146,6 +143,7 @@ private void InitializeComponent() {
this.lblType.X = 0;
this.lblType.Y = 4;
this.lblType.Visible = true;
+ this.lblType.Arrangement = Terminal.Gui.ViewArrangement.Fixed;
this.lblType.Data = "lblType";
this.lblType.Text = "( Type ) ";
this.lblType.TextAlignment = Terminal.Gui.Alignment.Center;
@@ -155,6 +153,7 @@ private void InitializeComponent() {
this.btnOk.X = 11;
this.btnOk.Y = 5;
this.btnOk.Visible = true;
+ this.btnOk.Arrangement = Terminal.Gui.ViewArrangement.Fixed;
this.btnOk.Data = "btnOk";
this.btnOk.Text = "Ok";
this.btnOk.TextAlignment = Terminal.Gui.Alignment.Center;
@@ -165,6 +164,7 @@ private void InitializeComponent() {
this.btnCancel.X = 23;
this.btnCancel.Y = 5;
this.btnCancel.Visible = true;
+ this.btnCancel.Arrangement = Terminal.Gui.ViewArrangement.Fixed;
this.btnCancel.Data = "btnCancel";
this.btnCancel.Text = "Cancel";
this.btnCancel.TextAlignment = Terminal.Gui.Alignment.Center;
diff --git a/src/UI/Windows/SliderOptionEditor.cs b/src/UI/Windows/SliderOptionEditor.cs
index fcaab054..c30255db 100644
--- a/src/UI/Windows/SliderOptionEditor.cs
+++ b/src/UI/Windows/SliderOptionEditor.cs
@@ -7,13 +7,16 @@
// You can make changes to this file and they will not be overwritten when saving.
//
// -----------------------------------------------------------------------------
+
+
namespace TerminalGuiDesigner.UI.Windows {
using System.Reflection;
using System.Text;
using Terminal.Gui;
- public partial class SliderOptionEditor {
+ public partial class SliderOptionEditor : IValueGetterDialog
+ {
private readonly Type genericTypeArgument;
private readonly Type sliderOptionType;
diff --git a/src/ViewExtensions.cs b/src/ViewExtensions.cs
index 7253b95e..fc9de70b 100644
--- a/src/ViewExtensions.cs
+++ b/src/ViewExtensions.cs
@@ -252,6 +252,8 @@ public static bool IsBorderlessContainerView(this View v)
/// The at the given screen location or null if none found.
public static View? HitTest(this View w, MouseEvent m, out bool isBorder, out bool isLowerRight, params View[] ignoring)
{
+ ignoring = ignoring.Union(w.GetAllNonDesignableSubviews()).ToArray();
+
// hide the views while we perform the hit test
foreach (View v in ignoring)
{
@@ -301,6 +303,7 @@ public static bool IsBorderlessContainerView(this View v)
return hit is Adornment a ? a.Parent : hit;
}
+
///
///
/// Sometimes returns what the library considers
@@ -394,6 +397,32 @@ public static IEnumerable OrderViewsByScreenPosition(IEnumerable vie
.ThenBy(v => v.Frame.X);
}
+ ///
+ /// Returns all subviews that are not Designable. Beware that designs can be nested
+ /// e.g. calling this on a root view with return subviews that belong to other designed
+ /// components that were added to the root designed window.
+ ///
+ ///
+ ///
+ public static IEnumerable GetAllNonDesignableSubviews(this View view)
+ {
+ var alsoIgnore = new List();
+ RecursivelyIgnoreAllNonDesignableSubviews(view, alsoIgnore);
+ return alsoIgnore;
+ }
+ private static void RecursivelyIgnoreAllNonDesignableSubviews(View view, List alsoIgnore)
+ {
+ foreach (var sub in view.Subviews)
+ {
+ if (sub.Data is not Design)
+ {
+ alsoIgnore.Add(sub);
+ }
+
+ RecursivelyIgnoreAllNonDesignableSubviews(sub, alsoIgnore);
+ }
+ }
+
private static bool HasNoBorderProperty(this View v)
{
if (v.Border == null || v.BorderStyle == LineStyle.None)
@@ -403,4 +432,6 @@ private static bool HasNoBorderProperty(this View v)
return false;
}
+
+
}
diff --git a/src/ViewFactory.cs b/src/ViewFactory.cs
index 3b2c7267..8b8b3154 100644
--- a/src/ViewFactory.cs
+++ b/src/ViewFactory.cs
@@ -40,11 +40,7 @@ public static class ViewFactory
// BUG These seem to cause stack overflows in CreateSubControlDesigns (see TestAddView_RoundTrip)
typeof( Wizard ),
typeof( WizardStep ),
-
- // TODO: Requires tests and comprehensive testing, also its generic so that's more complicated
- typeof(NumericUpDown),
- typeof(NumericUpDown<>),
-
+
// Ignore menu bar v2 for now
typeof(MenuBarv2),
@@ -134,6 +130,8 @@ public static T Create(int? width = null, int? height = null, string? text =
T newView = new( );
+
+
switch ( newView )
{
case Button:
@@ -145,11 +143,17 @@ public static T Create(int? width = null, int? height = null, string? text =
newView.Width = Dim.Auto();
break;
case ColorPicker:
- SetDefaultDimensions(newView, width ?? 20, height ?? 4);
+ newView.Width = width ?? 20;
+ newView.Height = Dim.Auto();
break;
// leave with default dimensions
case ColorPicker16:
+ case NumericUpDown:
+ case NumericUpDown:
+ case NumericUpDown:
+ case NumericUpDown:
+ case NumericUpDown:
break;
case TextView:
SetDefaultDimensions(newView, width ?? 10, height ?? 4);
diff --git a/tests/ColorPickerTests.cs b/tests/ColorPickerTests.cs
index bc23f969..1ef49a4d 100644
--- a/tests/ColorPickerTests.cs
+++ b/tests/ColorPickerTests.cs
@@ -26,7 +26,7 @@ public void ColorPickerCanSerializeStyle()
{
Assume.That(v.Style.ColorModel,Is.Not.EqualTo(ColorModel.RGB));
- var prop = d.GetDesignableProperty(nameof(ColorPicker.Style) + "." + nameof(ColorPickerStyle.ColorModel))
+ var prop = d.GetDesignableProperty(nameof(ColorPickerStyle.ColorModel))
?? throw new("Property was unexpectedly not designable");
// We change to RGB
diff --git a/tests/NumericUpDownTests.cs b/tests/NumericUpDownTests.cs
new file mode 100644
index 00000000..3a621516
--- /dev/null
+++ b/tests/NumericUpDownTests.cs
@@ -0,0 +1,40 @@
+namespace UnitTests;
+
+[Category("Core")]
+[TestFixture(typeof(int))]
+[TestFixture(typeof(long))]
+[TestFixture(typeof(double))]
+[TestFixture(typeof(float))]
+[TestFixture(typeof(decimal))]
+public class NumericUpDownTests : Tests
+ where T : notnull
+{
+
+ [Test]
+ [Category("Code Generation")]
+ public void NumericUpDownPreserveValue()
+ {
+ T testValue = (T)Convert.ChangeType(1.25, typeof(T));
+ using var backIn = RoundTrip>( (d, v) =>
+ {
+
+ // Expected designable properties
+ Assert.That(d.GetDesignableProperty("Text"), Is.Null);
+ Assert.That(v.Text, Is.EqualTo("0"));
+ Assert.That(v.GetActualText(),Is.EqualTo("0"));
+
+ // Expected default properties when created by ViewFactory
+ Assert.That(v.Width?.IsAuto(out _, out _, out _), Is.True);
+
+ // Your test logic here
+ v.Value = testValue;
+ v.Increment = testValue;
+
+ }, out _);
+
+ // Assertions here
+ Assert.That(backIn.Value,Is.EqualTo(testValue));
+ Assert.That(backIn.Increment, Is.EqualTo(testValue));
+ }
+}
+
diff --git a/tests/Tests.cs b/tests/Tests.cs
index 9a01b5e9..af59c7ef 100644
--- a/tests/Tests.cs
+++ b/tests/Tests.cs
@@ -5,7 +5,7 @@
namespace UnitTests;
[RequiresThread]
-internal class Tests
+public class Tests
{
[ThreadStatic]
private static bool? _init;
diff --git a/tests/ViewFactoryTests.cs b/tests/ViewFactoryTests.cs
index ab836ab7..ba0f48ec 100644
--- a/tests/ViewFactoryTests.cs
+++ b/tests/ViewFactoryTests.cs
@@ -188,9 +188,6 @@ private static Type[] KnownUnsupportedTypes_ExpectedTypes( )
typeof( Wizard ),
typeof( WizardStep ),
-
- typeof(NumericUpDown),
- typeof(NumericUpDown<>),
typeof( MenuBarv2 ),
typeof( Shortcut )
};