From a9501d7cedaa3de34492f306ae6f04a5e5f251d2 Mon Sep 17 00:00:00 2001 From: tznind Date: Sat, 24 Aug 2024 14:02:37 +0100 Subject: [PATCH 1/4] Add ColorPicker (true color) --- src/Design.cs | 8 +- src/TerminalGuiDesigner.csproj | 16 ++-- src/ToCode/Property.cs | 4 + src/UI/Windows/ColorPicker.Designer.cs | 42 ++++---- tests/UnitTests.csproj | 10 +- tests/ViewFactoryTests.cs | 127 +------------------------ 6 files changed, 49 insertions(+), 158 deletions(-) diff --git a/src/Design.cs b/src/Design.cs index 12e1ddae..71716320 100644 --- a/src/Design.cs +++ b/src/Design.cs @@ -449,7 +449,7 @@ public IEnumerable GetSiblings() { yield break; } - + foreach (var v in this.View.SuperView.Subviews) { if (v == this.View) @@ -763,6 +763,12 @@ private IEnumerable LoadDesignableProperties() { yield return this.CreateProperty(nameof(CheckBox.CheckedState)); } + if (this.View is ColorPicker cp) + { + yield return this.CreateSubProperty(nameof(ColorPickerStyle.ColorModel),nameof(ColorPicker.Style),cp.Style); + yield return this.CreateSubProperty(nameof(ColorPickerStyle.ShowColorName), nameof(ColorPicker.Style), cp.Style); + yield return this.CreateSubProperty(nameof(ColorPickerStyle.ShowTextFields), nameof(ColorPicker.Style), cp.Style); + } if (this.View is ListView lv) { diff --git a/src/TerminalGuiDesigner.csproj b/src/TerminalGuiDesigner.csproj index 75db0b25..6eac84cf 100644 --- a/src/TerminalGuiDesigner.csproj +++ b/src/TerminalGuiDesigner.csproj @@ -139,18 +139,18 @@ - + - - + + - - + + - - - + + + diff --git a/src/ToCode/Property.cs b/src/ToCode/Property.cs index b46c8bdd..4df3c3a1 100644 --- a/src/ToCode/Property.cs +++ b/src/ToCode/Property.cs @@ -471,6 +471,10 @@ private void CallRefreshMethodsIfAny() { t.Update(); } + if (this.Design.View is ColorPicker cp) + { + cp.ApplyStyleChanges(); + } this.Design.View.SetNeedsDisplay(); } diff --git a/src/UI/Windows/ColorPicker.Designer.cs b/src/UI/Windows/ColorPicker.Designer.cs index 6ac2f7c0..553b4d41 100644 --- a/src/UI/Windows/ColorPicker.Designer.cs +++ b/src/UI/Windows/ColorPicker.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. // @@ -45,7 +45,7 @@ private void InitializeComponent() { this.cpForeground = new Terminal.Gui.ColorPicker(); this.lblForeground = new Terminal.Gui.Label(); this.Width = Dim.Fill(2); - this.Height = 20; + this.Height = 17; this.X = Pos.Center(); this.Y = Pos.Center(); this.Visible = true; @@ -55,7 +55,7 @@ private void InitializeComponent() { this.Title = "Color Picker"; this.lblForeground.Width = 11; this.lblForeground.Height = 1; - this.lblForeground.X = 1; + this.lblForeground.X = 0; this.lblForeground.Y = 0; this.lblForeground.Visible = true; this.lblForeground.Arrangement = Terminal.Gui.ViewArrangement.Fixed; @@ -63,8 +63,8 @@ private void InitializeComponent() { this.lblForeground.Text = "Foreground:"; this.lblForeground.TextAlignment = Terminal.Gui.Alignment.Start; this.Add(this.lblForeground); - this.cpForeground.Width = 32; - this.cpForeground.Height = 4; + this.cpForeground.Width = Dim.Fill(1); + this.cpForeground.Height = Dim.Auto(); this.cpForeground.X = 2; this.cpForeground.Y = 1; this.cpForeground.Visible = true; @@ -72,31 +72,37 @@ private void InitializeComponent() { this.cpForeground.Data = "cpForeground"; this.cpForeground.Text = ""; this.cpForeground.TextAlignment = Terminal.Gui.Alignment.Start; + this.cpForeground.Style.ColorModel = Terminal.Gui.ColorModel.HSV; + this.cpForeground.Style.ShowColorName = true; + this.cpForeground.Style.ShowTextFields = true; this.Add(this.cpForeground); this.lblBackground.Width = 11; this.lblBackground.Height = 1; - this.lblBackground.X = 1; - this.lblBackground.Y = 5; + this.lblBackground.X = 0; + this.lblBackground.Y = 6; this.lblBackground.Visible = true; this.lblBackground.Arrangement = Terminal.Gui.ViewArrangement.Fixed; this.lblBackground.Data = "lblBackground"; this.lblBackground.Text = "Background:"; this.lblBackground.TextAlignment = Terminal.Gui.Alignment.Start; this.Add(this.lblBackground); - this.cpBackground.Width = 32; - this.cpBackground.Height = 4; + this.cpBackground.Width = Dim.Fill(1); + this.cpBackground.Height = Dim.Auto(); this.cpBackground.X = 2; - this.cpBackground.Y = 6; + this.cpBackground.Y = 7; this.cpBackground.Visible = true; this.cpBackground.Arrangement = Terminal.Gui.ViewArrangement.Fixed; this.cpBackground.Data = "cpBackground"; this.cpBackground.Text = ""; this.cpBackground.TextAlignment = Terminal.Gui.Alignment.Start; + this.cpBackground.Style.ColorModel = Terminal.Gui.ColorModel.HSV; + this.cpBackground.Style.ShowColorName = true; + this.cpBackground.Style.ShowTextFields = true; this.Add(this.cpBackground); this.lblResult.Width = Dim.Auto(); this.lblResult.Height = 1; - this.lblResult.X = 1; - this.lblResult.Y = 11; + this.lblResult.X = 0; + this.lblResult.Y = 12; this.lblResult.Visible = true; this.lblResult.Arrangement = Terminal.Gui.ViewArrangement.Fixed; this.lblResult.Data = "lblResult"; @@ -105,8 +111,8 @@ private void InitializeComponent() { this.Add(this.lblResult); this.lblPreview.Width = Dim.Fill(0); this.lblPreview.Height = 1; - this.lblPreview.X = 1; - this.lblPreview.Y = 12; + this.lblPreview.X = -1; + this.lblPreview.Y = 13; this.lblPreview.Visible = true; this.lblPreview.Arrangement = Terminal.Gui.ViewArrangement.Fixed; this.lblPreview.Data = "lblPreview"; @@ -115,8 +121,8 @@ private void InitializeComponent() { this.Add(this.lblPreview); this.btnOk.Width = 8; this.btnOk.Height = Dim.Auto(); - this.btnOk.X = 10; - this.btnOk.Y = 17; + this.btnOk.X = Pos.Left(btnCancel) - 10; + this.btnOk.Y = 14; this.btnOk.Visible = true; this.btnOk.Arrangement = Terminal.Gui.ViewArrangement.Fixed; this.btnOk.Data = "btnOk"; @@ -126,8 +132,8 @@ private void InitializeComponent() { this.Add(this.btnOk); this.btnCancel.Width = 10; this.btnCancel.Height = Dim.Auto(); - this.btnCancel.X = 28; - this.btnCancel.Y = 17; + this.btnCancel.X = Pos.Percent(48); + this.btnCancel.Y = 14; this.btnCancel.Visible = true; this.btnCancel.Arrangement = Terminal.Gui.ViewArrangement.Fixed; this.btnCancel.Data = "btnCancel"; diff --git a/tests/UnitTests.csproj b/tests/UnitTests.csproj index a8c63418..e474475a 100644 --- a/tests/UnitTests.csproj +++ b/tests/UnitTests.csproj @@ -28,11 +28,11 @@ - - - - - + + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/tests/ViewFactoryTests.cs b/tests/ViewFactoryTests.cs index e5d5ca0d..74337e42 100644 --- a/tests/ViewFactoryTests.cs +++ b/tests/ViewFactoryTests.cs @@ -2,6 +2,7 @@ using System.Diagnostics.CodeAnalysis; using System.Reflection; using System.Runtime.CompilerServices; +using Terminal.Gui.TextValidateProviders; namespace UnitTests; @@ -54,132 +55,6 @@ private static IEnumerable Create_And_CreateT_Type_Provider private static IEnumerable ViewFactory_SupportedViewTypes => ViewFactory.SupportedViewTypes; - [Test] - [TestCaseSource( nameof( Create_And_CreateT_Type_Provider ) )] - [Parallelizable(ParallelScope.Children)] - [Category( "Change Control" )] - [Description( "This test makes sure that both the generic and non-generic Create methods return objects with the same property values" )] - [Obsolete("Can be removed once non-generic ViewFactory.Create method is no longer in use.")] - public void Create_And_CreateT_ReturnEquivalentInstancesForSameInputs( T dummyInvalidObject ) - where T : View, new( ) - { - if (dummyInvalidObject is StatusBar) - { - return; - } - - T? createdByNonGeneric = ViewFactory.Create( typeof( T ) ) as T; - Assume.That( createdByNonGeneric, Is.Not.Null.And.InstanceOf( ) ); - - T createdByGeneric = ViewFactory.Create( ); - Assume.That( createdByGeneric, Is.Not.Null.And.InstanceOf( ) ); - - PropertyInfo[] publicPropertiesOfType = typeof( T ).GetProperties( BindingFlags.Instance | BindingFlags.Public ).Where( static p => p.CanRead ).ToArray( ); - Assert.Multiple( ( ) => - { - foreach ( PropertyInfo property in publicPropertiesOfType ) - { - // The purpose of this test is to confirm that generic and typeof(x) ViewFactory create methods create identical Views (in terms of properties). - // The following properties do not support equality well and are safe to assume get the same values regardless of which ViewFactory route creates them - if (property.PropertyType == typeof(KeyBindings)) - { - continue; - } - if (property.PropertyType == typeof(SliderStyle)) - { - continue; - } - if (property.PropertyType == typeof(Shortcut)) - { - continue; - } - - switch ( dummyInvalidObject, property ) - { - case (ComboBox, { Name: "Subviews" }): - case (MenuBar, { Name: "Menus" }): - case (TableView, { Name: "Table" }): - case (TabView, { Name: "Tabs" }): - case (TabView, { Name: "SelectedTab" }): - case (TabView, { Name: "Subviews" }): - case (DatePicker, { Name: "Subviews" }): - case (DatePicker, { Name: "Date" }): - // Warn about these, until they are implemented (WIP) - Assert.Warn( $"{property.Name} not yet checked on {typeof( T ).Name}" ); - continue; - case (ScrollView, { Name: "Subviews" }): - case (TileView, { Name: "Subviews" }): - case (TileView, { Name: "Tiles" }): - case (_, { Name: "ContextMenu" }): - case (_, { Name: "OverlappedTop" }): - continue; - case (Window, _): - // Safe to skip these, as we don't set them in Create - continue; - } - - object? nonGenericPropertyValue = property.GetValue( createdByNonGeneric ); - object? genericPropertyValue = property.GetValue( createdByGeneric ); - - // First, if they're both null, we're good so just skip it. - if ( nonGenericPropertyValue is null && genericPropertyValue is null ) - { - continue; - } - - // If one or the other isn't null, assert they both are not null - Assert.Multiple( ( ) => - { - Assert.That( nonGenericPropertyValue, Is.Not.Null ); - Assert.That( genericPropertyValue, Is.Not.Null ); - } ); - - // Special cases for certain properties by property type, property name, and/or tested view type. - // In general, we could actually skip basically everything that isn't explicitly in Create, - // but doing it this way allows us to just test everything and only skip what we absolutely have to. - switch ( dummyInvalidObject, property ) - { - case (_, not null) when property.PropertyType.IsAssignableTo( typeof( Dim ) ): - - if(nonGenericPropertyValue is DimAuto) - { - // TODO: https://github.com/gui-cs/Terminal.Gui/issues/3521 - Assert.Warn("Disabled this test case because of https://github.com/gui-cs/Terminal.Gui/issues/3521"); - continue; - } - - if (nonGenericPropertyValue is KeyBindings) - { - continue; - } - - Assert.That( (Dim)nonGenericPropertyValue!, Is.EqualTo( (Dim)genericPropertyValue! ) ); - continue; - case (_, not null) when property.PropertyType.IsAssignableTo( typeof( TextFormatter ) ): - TextFormatter nonGenericTextFormatter = (TextFormatter)nonGenericPropertyValue!; - TextFormatter genericTextFormatter = (TextFormatter)genericPropertyValue!; - Assert.That( nonGenericTextFormatter.ToCodePrimitiveExpression( ), Is.EqualTo( genericTextFormatter.ToCodePrimitiveExpression( ) ) ); - continue; - case (_, { Name: "TabIndexes" }): - var nonGenericTabIndexes = (ReadOnlyCollection)nonGenericPropertyValue!; - var genericTabIndexes = (ReadOnlyCollection)genericPropertyValue!; - Assert.That( - nonGenericTabIndexes, - Is.EquivalentTo( genericTabIndexes ) - .Using( CompareTwoViews ) ); - continue; - case (_, not null) when property.PropertyType.IsAssignableTo(typeof(Adornment)): - Assert.That(((Adornment)nonGenericPropertyValue!).ToString(), Is.EqualTo(((Adornment)genericPropertyValue!).ToString())); - continue; - } - - Assert.That( - nonGenericPropertyValue, - Is.EqualTo( genericPropertyValue ), - $"Property {property!.Name} of type {property.ReflectedType!.Name} mismatch. Generic: {genericPropertyValue} Non-Generic: {nonGenericPropertyValue}" ); - } - } ); - } [Test] [TestCaseSource( nameof( Create_And_CreateT_Type_Provider ) )] From 3bec676b42368a1ad518dd5858f441769d8f7f6b Mon Sep 17 00:00:00 2001 From: tznind Date: Sat, 24 Aug 2024 14:09:51 +0100 Subject: [PATCH 2/4] Remove all parallelization in tests, Terminal.Gui now has static Application init stuff that breaks with parallel tests --- tests/DimExtensionsTests.cs | 2 +- tests/KeyMapTests.cs | 2 +- tests/KeyboardManagerTests.cs | 2 +- tests/ObjectExtensionsTests.cs | 2 +- tests/StatusBarTests.cs | 2 +- tests/StringExtensionTests.cs | 2 +- tests/ViewFactoryTests.cs | 14 +++++++------- 7 files changed, 13 insertions(+), 13 deletions(-) diff --git a/tests/DimExtensionsTests.cs b/tests/DimExtensionsTests.cs index 2b2b75e9..6d60fcbe 100644 --- a/tests/DimExtensionsTests.cs +++ b/tests/DimExtensionsTests.cs @@ -6,7 +6,7 @@ namespace UnitTests; [TestOf( typeof( DimExtensions ) )] [Category( "Core" )] [Category( "Terminal.Gui Extensions" )] -[Parallelizable( ParallelScope.Children )] +[NonParallelizable] internal class DimExtensionsTests { [Test] diff --git a/tests/KeyMapTests.cs b/tests/KeyMapTests.cs index 86d88a7e..d4fd8c0d 100644 --- a/tests/KeyMapTests.cs +++ b/tests/KeyMapTests.cs @@ -6,7 +6,7 @@ namespace UnitTests; [TestOf( typeof( KeyMap ) )] [Category( "Core" )] [Category( "UI" )] -[Parallelizable( ParallelScope.All )] +[NonParallelizable] internal class KeyMapTests { private const string ExpectedKeysYamlContent = diff --git a/tests/KeyboardManagerTests.cs b/tests/KeyboardManagerTests.cs index 5887c246..604cf9a4 100644 --- a/tests/KeyboardManagerTests.cs +++ b/tests/KeyboardManagerTests.cs @@ -71,7 +71,7 @@ public void Backspace_WithDateFieldSelected( ) } [Test] - [Parallelizable(ParallelScope.Self)] + [NonParallelizable] public void ButtonRename( ) { Button v = ViewFactory.Create