Sfoglia il codice sorgente

Added all views tester for draw/layout.
Made Adornment support being a subview for testing purposes.

Tig 9 mesi fa
parent
commit
262c6710ac

+ 27 - 3
Terminal.Gui/View/Adornment/Adornment.cs

@@ -1,6 +1,7 @@
 #nullable enable
 using System.ComponentModel;
 using Terminal.Gui;
+using static Terminal.Gui.SpinnerStyle;
 using Attribute = Terminal.Gui.Attribute;
 
 /// <summary>
@@ -15,7 +16,7 @@ using Attribute = Terminal.Gui.Attribute;
 ///         mouse input. Each can be customized by manipulating their Subviews.
 ///     </para>
 /// </remarsk>
-public class Adornment : View
+public class Adornment : View, IDesignable
 {
     /// <inheritdoc/>
     public Adornment ()
@@ -63,6 +64,7 @@ public class Adornment : View
             {
                 Parent?.SetAdornmentFrames ();
                 SetLayoutNeeded ();
+                SetNeedsDisplay ();
                 //Parent?.SetLayoutNeeded ();
 
                 OnThicknessChanged ();
@@ -88,9 +90,12 @@ public class Adornment : View
     ///     Adornments cannot be used as sub-views (see <see cref="Parent"/>); setting this property will throw
     ///     <see cref="InvalidOperationException"/>.
     /// </summary>
+    /// <remarks>
+    ///     While there are no real use cases for an Adornment being a subview, it is not explicitly dis-allowed to support testing. E.g. in AllViewsTester.
+    /// </remarks>
     public override View? SuperView
     {
-        get => null!;
+        get => base.SuperView!;
         set => throw new InvalidOperationException (@"Adornments can not be Subviews or have SuperViews. Use Parent instead.");
     }
 
@@ -115,7 +120,7 @@ public class Adornment : View
     /// </remarks>
     public override Rectangle Viewport
     {
-        get => Frame with { Location = Point.Empty };
+        get => base.Viewport;
         set => throw new InvalidOperationException (@"The Viewport of an Adornment cannot be modified.");
     }
 
@@ -124,6 +129,14 @@ public class Adornment : View
     {
         if (Parent is null)
         {
+            // While there are no real use cases for an Adornment being a subview, we support it for
+            // testing. E.g. in AllViewsTester.
+            if (SuperView is { })
+            {
+                Point super = SuperView.ViewportToScreen (Frame.Location);
+
+                return new (super, Frame.Size);
+            }
             return Frame;
         }
 
@@ -254,4 +267,15 @@ public class Adornment : View
     //    }
     //}
     #endregion Mouse Support
+
+
+    /// <inheritdoc/>
+    bool IDesignable.EnableForDesign ()
+    {
+        Thickness = new (3);
+        Frame = new (0, 0, 10, 10);
+        Diagnostics = ViewDiagnosticFlags.Padding;
+
+        return true;
+    }
 }

+ 7 - 4
Terminal.Gui/View/Adornment/Border.cs

@@ -191,7 +191,7 @@ public class Border : Adornment
             // TODO: Make Border.LineStyle inherit from the SuperView hierarchy
             // TODO: Right now, Window and FrameView use CM to set BorderStyle, which negates
             // TODO: all this.
-            return Parent!.SuperView?.BorderStyle ?? LineStyle.None;
+            return Parent?.SuperView?.BorderStyle ?? LineStyle.None;
         }
         set => _lineStyle = value;
     }
@@ -634,12 +634,15 @@ public class Border : Adornment
         int maxTitleWidth = Math.Max (
                                       0,
                                       Math.Min (
-                                                Parent!.TitleTextFormatter.FormatAndGetSize ().Width,
+                                                Parent?.TitleTextFormatter.FormatAndGetSize ().Width ?? 0,
                                                 Math.Min (screenBounds.Width - 4, borderBounds.Width - 4)
                                                )
                                      );
 
-        Parent.TitleTextFormatter.ConstrainToSize = new (maxTitleWidth, 1);
+        if (Parent is { })
+        {
+            Parent.TitleTextFormatter.ConstrainToSize = new (maxTitleWidth, 1);
+        }
 
         int sideLineLength = borderBounds.Height;
         bool canDrawBorder = borderBounds is { Width: > 0, Height: > 0 };
@@ -678,7 +681,7 @@ public class Border : Adornment
             }
         }
 
-        if (canDrawBorder && Thickness.Top > 0 && maxTitleWidth > 0 && Settings.FastHasFlags (BorderSettings.Title) && !string.IsNullOrEmpty (Parent?.Title))
+        if (Parent is {} && canDrawBorder && Thickness.Top > 0 && maxTitleWidth > 0 && Settings.FastHasFlags (BorderSettings.Title) && !string.IsNullOrEmpty (Parent?.Title))
         {
             Attribute focus = Parent.GetNormalColor ();
 

+ 3 - 3
Terminal.Gui/Views/ColorPicker.16.cs

@@ -135,7 +135,7 @@ public class ColorPicker16 : View
     {
         base.OnDrawContent (viewport);
 
-        Driver.SetAttribute (HasFocus ? ColorScheme.Focus : GetNormalColor ());
+        Driver?.SetAttribute (HasFocus ? ColorScheme.Focus : GetNormalColor ());
         var colorIndex = 0;
 
         for (var y = 0; y < Math.Max (2, viewport.Height / BoxHeight); y++)
@@ -149,7 +149,7 @@ public class ColorPicker16 : View
                     continue;
                 }
 
-                Driver.SetAttribute (new ((ColorName16)foregroundColorIndex, (ColorName16)colorIndex));
+                Driver?.SetAttribute (new ((ColorName16)foregroundColorIndex, (ColorName16)colorIndex));
                 bool selected = x == Cursor.X && y == Cursor.Y;
                 DrawColorBox (x, y, selected);
                 colorIndex++;
@@ -223,7 +223,7 @@ public class ColorPicker16 : View
             for (var zoomedX = 0; zoomedX < BoxWidth; zoomedX++)
             {
                 Move (x * BoxWidth + zoomedX, y * BoxHeight + zoomedY);
-                Driver.AddRune ((Rune)' ');
+                Driver?.AddRune ((Rune)' ');
                 index++;
             }
         }

+ 1 - 1
Terminal.Gui/Views/ColorPicker.cs

@@ -103,7 +103,7 @@ public partial class ColorPicker : View
     {
         base.OnDrawContent (viewport);
         Attribute normal = GetNormalColor ();
-        Driver.SetAttribute (new (SelectedColor, normal.Background));
+        Driver?.SetAttribute (new (SelectedColor, normal.Background));
         int y = _bars.Count + (Style.ShowColorName ? 1 : 0);
         AddRune (13, y, (Rune)'■');
     }

+ 2 - 2
Terminal.Gui/Views/TextField.cs

@@ -997,11 +997,11 @@ public class TextField : View
             }
         }
 
-        Driver.SetAttribute (GetFocusColor ());
+        Driver?.SetAttribute (GetFocusColor ());
 
         for (int i = col; i < width; i++)
         {
-            Driver.AddRune ((Rune)' ');
+            Driver?.AddRune ((Rune)' ');
         }
 
         PositionCursor ();

+ 1 - 1
UICatalog/Scenarios/AllViewsTester.cs

@@ -360,7 +360,6 @@ public class AllViewsTester : Scenario
 
         // Instantiate view
         var view = (View)Activator.CreateInstance (type);
-
         if (view is IDesignable designable)
         {
             designable.EnableForDesign (ref _demoText);
@@ -384,6 +383,7 @@ public class AllViewsTester : Scenario
         view.Initialized += CurrentView_Initialized;
         view.LayoutComplete += CurrentView_LayoutComplete;
 
+        view.Id = "_curView";
         _curView = view;
         _hostPane.Add (_curView);
     }

+ 47 - 0
UnitTests/View/Draw/AllViewsDrawTests.cs

@@ -0,0 +1,47 @@
+using Xunit.Abstractions;
+
+namespace Terminal.Gui.LayoutTests;
+
+public class AllViewsDrawTests (ITestOutputHelper _output) : TestsAllViews
+{
+    [Theory]
+    [MemberData (nameof (AllViewTypes))]
+    public void AllViews_Does_Not_Layout (Type viewType)
+    {
+        var view = (View)CreateInstanceIfNotGeneric (viewType);
+
+        if (view == null)
+        {
+            _output.WriteLine ($"Ignoring {viewType} - It's a Generic");
+
+            return;
+        }
+
+        if (view is IDesignable designable)
+        {
+            designable.EnableForDesign ();
+        }
+
+        var drawContentCount = 0;
+        view.DrawContent += (s, e) => drawContentCount++;
+
+        var layoutStartedCount = 0;
+        view.LayoutStarted += (s, e) => layoutStartedCount++;
+
+        var layoutCompleteCount = 0;
+        view.LayoutComplete += (s, e) => layoutCompleteCount++;
+
+        view.SetLayoutNeeded ();
+        view.Layout ();
+
+        Assert.Equal (0, drawContentCount);
+        Assert.Equal (1, layoutStartedCount);
+        Assert.Equal (1, layoutCompleteCount);
+
+        view.Draw ();
+
+        Assert.Equal (1, drawContentCount);
+        Assert.Equal (1, layoutStartedCount);
+        Assert.Equal (1, layoutCompleteCount);
+    }
+}

+ 41 - 0
UnitTests/View/Layout/LayoutTests.cs

@@ -0,0 +1,41 @@
+using Xunit.Abstractions;
+
+namespace Terminal.Gui.LayoutTests;
+
+public class LayoutTests (ITestOutputHelper _output) : TestsAllViews
+{
+    [Theory]
+    [MemberData (nameof (AllViewTypes))]
+    public void AllViews_Layout_Does_Not_Draw (Type viewType)
+    {
+        var view = (View)CreateInstanceIfNotGeneric (viewType);
+
+        if (view == null)
+        {
+            _output.WriteLine ($"Ignoring {viewType} - It's a Generic");
+
+            return;
+        }
+
+        if (view is IDesignable designable)
+        {
+            designable.EnableForDesign ();
+        }
+
+        var drawContentCount = 0;
+        view.DrawContent += (s, e) => drawContentCount++;
+
+        var layoutStartedCount = 0;
+        view.LayoutStarted += (s, e) => layoutStartedCount++;
+
+        var layoutCompleteCount = 0;
+        view.LayoutComplete += (s, e) => layoutCompleteCount++;
+
+        view.SetLayoutNeeded ();
+        view.Layout ();
+
+        Assert.Equal (0, drawContentCount);
+        Assert.Equal (1, layoutStartedCount);
+        Assert.Equal (1, layoutCompleteCount);
+    }
+}

+ 2 - 0
UnitTests/View/Layout/SetLayoutTests.cs

@@ -807,4 +807,6 @@ public class SetLayoutTests (ITestOutputHelper output)
         Assert.Equal (19, v2.Frame.Height);
         t.Dispose ();
     }
+
+
 }