Sfoglia il codice sorgente

Merge pull request #165 from tig/tznind-gradients

Added Border Settings & BorderSettings.Gradient
Thomas Nind 1 anno fa
parent
commit
097a800617

+ 9 - 14
Terminal.Gui/Drawing/FillPair.cs

@@ -1,16 +1,14 @@
-
 namespace Terminal.Gui;
 
-
 /// <summary>
-/// Describes a pair of <see cref="IFill"/> which cooperate in creating
-/// <see cref="Attribute"/>.  One gives foreground color while other gives background.
+///     Describes a pair of <see cref="IFill"/> which cooperate in creating
+///     <see cref="Attribute"/>. One gives foreground color while other gives background.
 /// </summary>
 public class FillPair
 {
     /// <summary>
-    /// Creates a new instance using the provided fills for foreground and background
-    /// color when assembling <see cref="Attribute"/>.
+    ///     Creates a new instance using the provided fills for foreground and background
+    ///     color when assembling <see cref="Attribute"/>.
     /// </summary>
     /// <param name="fore"></param>
     /// <param name="back"></param>
@@ -21,26 +19,23 @@ public class FillPair
     }
 
     /// <summary>
-    /// The fill which provides point based foreground color.
+    ///     The fill which provides point based foreground color.
     /// </summary>
     public IFill Foreground { get; init; }
 
     /// <summary>
-    /// The fill which provides point based background color.
+    ///     The fill which provides point based background color.
     /// </summary>
     public IFill Background { get; init; }
 
     /// <summary>
-    /// Returns the color pair (foreground+background) to use when rendering
-    /// a rune at the given <paramref name="point"/>.
+    ///     Returns the color pair (foreground+background) to use when rendering
+    ///     a rune at the given <paramref name="point"/>.
     /// </summary>
     /// <param name="point"></param>
     /// <returns></returns>
     public Attribute GetAttribute (Point point)
     {
-        return new Attribute (
-            Foreground.GetColor (point),
-            Background.GetColor (point)
-            );
+        return new (Foreground.GetColor (point), Background.GetColor (point));
     }
 }

+ 74 - 64
Terminal.Gui/Drawing/Gradient.cs

@@ -1,34 +1,30 @@
-// This code is a C# port from python library Terminal Text Effects  https://github.com/ChrisBuilds/terminaltexteffects/
+// This code is a C# port from python library Terminal Text Effects  https://github.com/ChrisBuilds/terminaltexteffects/
 
 namespace Terminal.Gui;
 
-using System;
-using System.Collections.Generic;
-using System.Linq;
-
 /// <summary>
-/// Describes the pattern that a <see cref="Gradient"/> results in e.g. <see cref="Vertical"/>, <see cref="Horizontal"/> etc
+///     Describes the pattern that a <see cref="Gradient"/> results in e.g. <see cref="Vertical"/>,
+///     <see cref="Horizontal"/> etc
 /// </summary>
 public enum GradientDirection
 {
     /// <summary>
-    /// Color varies along Y axis but is constant on X axis.
+    ///     Color varies along Y axis but is constant on X axis.
     /// </summary>
     Vertical,
 
     /// <summary>
-    /// Color varies along X axis but is constant on Y axis.
+    ///     Color varies along X axis but is constant on Y axis.
     /// </summary>
     Horizontal,
 
-
     /// <summary>
-    /// Color varies by distance from center (i.e. in circular ripples)
+    ///     Color varies by distance from center (i.e. in circular ripples)
     /// </summary>
     Radial,
 
     /// <summary>
-    /// Color varies by X and Y axis (i.e. a slanted gradient)
+    ///     Color varies by X and Y axis (i.e. a slanted gradient)
     /// </summary>
     Diagonal
 }
@@ -41,22 +37,24 @@ public enum GradientDirection
 public class Gradient
 {
     /// <summary>
-    /// The discrete colors that will make up the <see cref="Gradient"/>.
+    ///     The discrete colors that will make up the <see cref="Gradient"/>.
     /// </summary>
-    public List<Color> Spectrum { get; private set; }
+    public List<Color> Spectrum { get; }
+
     private readonly bool _loop;
     private readonly List<Color> _stops;
     private readonly List<int> _steps;
 
-
     /// <summary>
-    /// Creates a new instance of the <see cref="Gradient"/> class which hosts a <see cref="Spectrum"/>
-    /// of colors including all <paramref name="stops"/> and <paramref name="steps"/> interpolated colors
-    /// between each corresponding pair.
+    ///     Creates a new instance of the <see cref="Gradient"/> class which hosts a <see cref="Spectrum"/>
+    ///     of colors including all <paramref name="stops"/> and <paramref name="steps"/> interpolated colors
+    ///     between each corresponding pair.
     /// </summary>
     /// <param name="stops">The colors to use in the spectrum (N)</param>
-    /// <param name="steps">The number of colors to generate between each pair (must be N-1 numbers).
-    /// If only one step is passed then it is assumed to be the same distance for all pairs.</param>
+    /// <param name="steps">
+    ///     The number of colors to generate between each pair (must be N-1 numbers).
+    ///     If only one step is passed then it is assumed to be the same distance for all pairs.
+    /// </param>
     /// <param name="loop">True to duplicate the first stop and step so that the gradient repeats itself</param>
     /// <exception cref="ArgumentException"></exception>
     public Gradient (IEnumerable<Color> stops, IEnumerable<int> steps, bool loop = false)
@@ -73,13 +71,13 @@ public class Gradient
         // If multiple colors and only 1 step assume same distance applies to all steps
         if (_stops.Count > 2 && _steps.Count == 1)
         {
-            _steps = Enumerable.Repeat (_steps.Single (),_stops.Count() - 1).ToList();
+            _steps = Enumerable.Repeat (_steps.Single (), _stops.Count () - 1).ToList ();
         }
 
         if (_steps.Any (step => step < 1))
         {
             throw new ArgumentException ("Steps must be greater than 0.");
-        }   
+        }
 
         if (_steps.Count != _stops.Count - 1)
         {
@@ -91,11 +89,13 @@ public class Gradient
     }
 
     /// <summary>
-    /// Returns the color to use at the given part of the spectrum
+    ///     Returns the color to use at the given part of the spectrum
     /// </summary>
-    /// <param name="fraction">Proportion of the way through the spectrum, must be between 
-    /// 0 and 1 (inclusive).  Returns the last color if <paramref name="fraction"/> is
-    /// <see cref="double.NaN"/>.</param>
+    /// <param name="fraction">
+    ///     Proportion of the way through the spectrum, must be between
+    ///     0 and 1 (inclusive).  Returns the last color if <paramref name="fraction"/> is
+    ///     <see cref="double.NaN"/>.
+    /// </param>
     /// <returns></returns>
     /// <exception cref="ArgumentOutOfRangeException"></exception>
     public Color GetColorAtFraction (double fraction)
@@ -105,30 +105,32 @@ public class Gradient
             return Spectrum.Last ();
         }
 
-        if (fraction < 0 || fraction > 1)
+        if (fraction is < 0 or > 1)
         {
-            throw new ArgumentOutOfRangeException (nameof (fraction), "Fraction must be between 0 and 1.");
+            throw new ArgumentOutOfRangeException (nameof (fraction), @"Fraction must be between 0 and 1.");
         }
 
-        int index = (int)(fraction * (Spectrum.Count - 1));
+        var index = (int)(fraction * (Spectrum.Count - 1));
+
         return Spectrum [index];
     }
 
     private List<Color> GenerateGradient (IEnumerable<int> steps)
     {
-        List<Color> gradient = new List<Color> ();
+        List<Color> gradient = new ();
 
         if (_stops.Count == 1)
         {
-            for (int i = 0; i < steps.Sum (); i++)
+            for (var i = 0; i < steps.Sum (); i++)
             {
                 gradient.Add (_stops [0]);
             }
+
             return gradient;
         }
 
-        var stopsToUse = _stops.ToList ();
-        var stepsToUse = _steps.ToList ();
+        List<Color> stopsToUse = _stops.ToList ();
+        List<int> stepsToUse = _steps.ToList ();
 
         if (_loop)
         {
@@ -137,9 +139,9 @@ public class Gradient
         }
 
         var colorPairs = stopsToUse.Zip (stopsToUse.Skip (1), (start, end) => new { start, end });
-        var stepsList = stepsToUse;
+        List<int> stepsList = stepsToUse;
 
-        foreach (var (colorPair, thesteps) in colorPairs.Zip (stepsList, (pair, step) => (pair, step)))
+        foreach ((var colorPair, int thesteps) in colorPairs.Zip (stepsList, (pair, step) => (pair, step)))
         {
             gradient.AddRange (InterpolateColors (colorPair.start, colorPair.end, thesteps));
         }
@@ -147,28 +149,29 @@ public class Gradient
         return gradient;
     }
 
-    private IEnumerable<Color> InterpolateColors (Color start, Color end, int steps)
+    private static IEnumerable<Color> InterpolateColors (Color start, Color end, int steps)
     {
-        for (int step = 0; step < steps; step++)
+        for (var step = 0; step < steps; step++)
         {
             double fraction = (double)step / steps;
-            int r = (int)(start.R + fraction * (end.R - start.R));
-            int g = (int)(start.G + fraction * (end.G - start.G));
-            int b = (int)(start.B + fraction * (end.B - start.B));
-            yield return new Color (r, g, b);
+            var r = (int)(start.R + fraction * (end.R - start.R));
+            var g = (int)(start.G + fraction * (end.G - start.G));
+            var b = (int)(start.B + fraction * (end.B - start.B));
+
+            yield return new (r, g, b);
         }
+
         yield return end; // Ensure the last color is included
     }
 
-
     /// <summary>
-    /// <para>
-    /// Creates a mapping starting at 0,0 and going to <paramref name="maxRow"/> and <paramref name="maxColumn"/>
-    /// (inclusively) using the supplied <paramref name="direction"/>.
-    /// </para>
-    /// <para>
-    /// Note that this method is inclusive i.e. passing 1/1 results in 4 mapped coordinates.
-    /// </para>
+    ///     <para>
+    ///         Creates a mapping starting at 0,0 and going to <paramref name="maxRow"/> and <paramref name="maxColumn"/>
+    ///         (inclusively) using the supplied <paramref name="direction"/>.
+    ///     </para>
+    ///     <para>
+    ///         Note that this method is inclusive i.e. passing 1/1 results in 4 mapped coordinates.
+    ///     </para>
     /// </summary>
     /// <param name="maxRow"></param>
     /// <param name="maxColumn"></param>
@@ -176,63 +179,69 @@ public class Gradient
     /// <returns></returns>
     public Dictionary<Point, Color> BuildCoordinateColorMapping (int maxRow, int maxColumn, GradientDirection direction)
     {
-        var gradientMapping = new Dictionary<Point, Color> ();
+        Dictionary<Point, Color> gradientMapping = new ();
 
         switch (direction)
         {
             case GradientDirection.Vertical:
-                for (int row = 0; row <= maxRow; row++)
+                for (var row = 0; row <= maxRow; row++)
                 {
                     double fraction = maxRow == 0 ? 1.0 : (double)row / maxRow;
                     Color color = GetColorAtFraction (fraction);
-                    for (int col = 0; col <= maxColumn; col++)
+
+                    for (var col = 0; col <= maxColumn; col++)
                     {
-                        gradientMapping [new Point (col, row)] = color;
+                        gradientMapping [new (col, row)] = color;
                     }
                 }
+
                 break;
 
             case GradientDirection.Horizontal:
-                for (int col = 0; col <= maxColumn; col++)
+                for (var col = 0; col <= maxColumn; col++)
                 {
                     double fraction = maxColumn == 0 ? 1.0 : (double)col / maxColumn;
                     Color color = GetColorAtFraction (fraction);
-                    for (int row = 0; row <= maxRow; row++)
+
+                    for (var row = 0; row <= maxRow; row++)
                     {
-                        gradientMapping [new Point (col, row)] = color;
+                        gradientMapping [new (col, row)] = color;
                     }
                 }
+
                 break;
 
             case GradientDirection.Radial:
-                for (int row = 0; row <= maxRow; row++)
+                for (var row = 0; row <= maxRow; row++)
                 {
-                    for (int col = 0; col <= maxColumn; col++)
+                    for (var col = 0; col <= maxColumn; col++)
                     {
-                        double distanceFromCenter = FindNormalizedDistanceFromCenter (maxRow, maxColumn, new Point (col, row));
+                        double distanceFromCenter = FindNormalizedDistanceFromCenter (maxRow, maxColumn, new (col, row));
                         Color color = GetColorAtFraction (distanceFromCenter);
-                        gradientMapping [new Point (col, row)] = color;
+                        gradientMapping [new (col, row)] = color;
                     }
                 }
+
                 break;
 
             case GradientDirection.Diagonal:
-                for (int row = 0; row <= maxRow; row++)
+                for (var row = 0; row <= maxRow; row++)
                 {
-                    for (int col = 0; col <= maxColumn; col++)
+                    for (var col = 0; col <= maxColumn; col++)
                     {
                         double fraction = ((double)row * 2 + col) / (maxRow * 2 + maxColumn);
                         Color color = GetColorAtFraction (fraction);
-                        gradientMapping [new Point (col, row)] = color;
+                        gradientMapping [new (col, row)] = color;
                     }
                 }
+
                 break;
         }
 
         return gradientMapping;
     }
 
-    private double FindNormalizedDistanceFromCenter (int maxRow, int maxColumn, Point coord)
+    private static double FindNormalizedDistanceFromCenter (int maxRow, int maxColumn, Point coord)
     {
         double centerX = maxColumn / 2.0;
         double centerY = maxRow / 2.0;
@@ -240,6 +249,7 @@ public class Gradient
         double dy = coord.Y - centerY;
         double distance = Math.Sqrt (dx * dx + dy * dy);
         double maxDistance = Math.Sqrt (centerX * centerX + centerY * centerY);
+
         return distance / maxDistance;
     }
-}
+}

+ 14 - 13
Terminal.Gui/Drawing/GradientFill.cs

@@ -1,17 +1,17 @@
 namespace Terminal.Gui;
 
 /// <summary>
-/// Implementation of <see cref="IFill"/> that uses a color gradient (including
-/// radial, diagonal etc).
+///     Implementation of <see cref="IFill"/> that uses a color gradient (including
+///     radial, diagonal etc.).
 /// </summary>
 public class GradientFill : IFill
 {
-    private Dictionary<Point, Color> _map;
+    private readonly Dictionary<Point, Color> _map;
 
     /// <summary>
-    /// Creates a new instance of the <see cref="GradientFill"/> class that can return
-    /// color for any point in the given <paramref name="area"/> using the provided
-    /// <paramref name="gradient"/> and <paramref name="direction"/>.
+    ///     Creates a new instance of the <see cref="GradientFill"/> class that can return
+    ///     color for any point in the given <paramref name="area"/> using the provided
+    ///     <paramref name="gradient"/> and <paramref name="direction"/>.
     /// </summary>
     /// <param name="area"></param>
     /// <param name="gradient"></param>
@@ -19,23 +19,24 @@ public class GradientFill : IFill
     public GradientFill (Rectangle area, Gradient gradient, GradientDirection direction)
     {
         _map = gradient.BuildCoordinateColorMapping (area.Height - 1, area.Width - 1, direction)
-            .ToDictionary (
-                kvp => new Point (kvp.Key.X + area.X, kvp.Key.Y + area.Y),
-                kvp => kvp.Value);
+                       .ToDictionary (
+                                      kvp => new Point (kvp.Key.X + area.X, kvp.Key.Y + area.Y),
+                                      kvp => kvp.Value);
     }
 
     /// <summary>
-    /// Returns the color to use for the given <paramref name="point"/> or Black if it
-    /// lies outside of the prepared gradient area (see constructor).
+    ///     Returns the color to use for the given <paramref name="point"/> or Black if it
+    ///     lies outside the prepared gradient area (see constructor).
     /// </summary>
     /// <param name="point"></param>
     /// <returns></returns>
     public Color GetColor (Point point)
     {
-        if (_map.TryGetValue (point, out var color))
+        if (_map.TryGetValue (point, out Color color))
         {
             return color;
         }
-        return new Color (0, 0, 0); // Default to black if point not found
+
+        return new (0, 0); // Default to black if point not found
     }
 }

+ 4 - 5
Terminal.Gui/Drawing/IFill.cs

@@ -1,15 +1,14 @@
-
-namespace Terminal.Gui;
+namespace Terminal.Gui;
 
 /// <summary>
-/// Describes an area fill (e.g. solid color or gradient).
+///     Describes an area fill (e.g. solid color or gradient).
 /// </summary>
 public interface IFill
 {
     /// <summary>
-    /// Returns the color that should be used at the given point
+    ///     Returns the color that should be used at the given point
     /// </summary>
     /// <param name="point"></param>
     /// <returns></returns>
     Color GetColor (Point point);
-}
+}

+ 14 - 15
Terminal.Gui/Drawing/LineCanvas.cs

@@ -5,9 +5,9 @@ namespace Terminal.Gui;
 public class LineCanvas : IDisposable
 {
     /// <summary>
-    /// Optional <see cref="FillPair"/> which when present overrides the <see cref="StraightLine.Attribute"/>
-    /// (colors) of lines in the canvas.  This can be used e.g. to apply a global <see cref="GradientFill"/> 
-    /// across all lines.
+    ///     Optional <see cref="FillPair"/> which when present overrides the <see cref="StraightLine.Attribute"/>
+    ///     (colors) of lines in the canvas. This can be used e.g. to apply a global <see cref="GradientFill"/>
+    ///     across all lines.
     /// </summary>
     public FillPair? Fill { get; set; }
 
@@ -142,7 +142,7 @@ public class LineCanvas : IDisposable
     )
     {
         _cachedViewport = Rectangle.Empty;
-        _lines.Add (new StraightLine (start, length, orientation, style, attribute));
+        _lines.Add (new (start, length, orientation, style, attribute));
     }
 
     /// <summary>Adds a new line to the canvas</summary>
@@ -190,7 +190,7 @@ public class LineCanvas : IDisposable
 
                 if (cell is { })
                 {
-                    map.Add (new Point (x, y), cell);
+                    map.Add (new (x, y), cell);
                 }
             }
         }
@@ -225,7 +225,7 @@ public class LineCanvas : IDisposable
 
                 if (rune is { })
                 {
-                    map.Add (new Point (x, y), rune.Value);
+                    map.Add (new (x, y), rune.Value);
                 }
             }
         }
@@ -333,8 +333,7 @@ public class LineCanvas : IDisposable
 
     private Attribute? GetAttributeForIntersects (IntersectionDefinition? [] intersects)
     {
-        return Fill != null ? Fill.GetAttribute (intersects [0]!.Point) :
-            intersects [0]!.Line.Attribute;
+        return Fill != null ? Fill.GetAttribute (intersects [0]!.Point) : intersects [0]!.Line.Attribute;
     }
 
     private Cell? GetCellForIntersects (ConsoleDriver driver, IntersectionDefinition? [] intersects)
@@ -439,12 +438,12 @@ public class LineCanvas : IDisposable
                        useThickDotted ? Glyphs.VLineHvDa4 : Glyphs.VLine;
 
             default:
-                throw new Exception (
-                                     "Could not find resolver or switch case for "
-                                     + nameof (runeType)
-                                     + ":"
-                                     + runeType
-                                    );
+                throw new (
+                           "Could not find resolver or switch case for "
+                           + nameof (runeType)
+                           + ":"
+                           + runeType
+                          );
         }
     }
 
@@ -854,4 +853,4 @@ public class LineCanvas : IDisposable
             _normal = Glyphs.URCorner;
         }
     }
-}
+}

+ 8 - 15
Terminal.Gui/Drawing/SolidFill.cs

@@ -1,31 +1,24 @@
 namespace Terminal.Gui;
 
-
 /// <summary>
-/// <see cref="IFill"/> implementation that uses a solid color for all points
+///     <see cref="IFill"/> implementation that uses a solid color for all points
 /// </summary>
 public class SolidFill : IFill
 {
-    readonly Color _color;
+    private readonly Color _color;
 
     /// <summary>
-    /// Creates a new instance of the <see cref="SolidFill"/> class which will return
-    /// the provided <paramref name="color"/> regardless of which point is requested.
+    ///     Creates a new instance of the <see cref="SolidFill"/> class which will return
+    ///     the provided <paramref name="color"/> regardless of which point is requested.
     /// </summary>
     /// <param name="color"></param>
-    public SolidFill (Color color)
-    {
-        _color = color;
-    }
+    public SolidFill (Color color) { _color = color; }
 
     /// <summary>
-    /// Returns the color this instance was constructed with regardless of
-    /// which <paramref name="point"/> is being colored.
+    ///     Returns the color this instance was constructed with regardless of
+    ///     which <paramref name="point"/> is being colored.
     /// </summary>
     /// <param name="point"></param>
     /// <returns></returns>
-    public Color GetColor (Point point)
-    {
-        return _color;
-    }
+    public Color GetColor (Point point) { return _color; }
 }

+ 39 - 32
Terminal.Gui/Drawing/StraightLine.cs

@@ -45,6 +45,7 @@ public class StraightLine
     ///     Gets the rectangle that describes the bounds of the canvas. Location is the coordinates of the line that is
     ///     furthest left/top and Size is defined by the line that extends the furthest right/bottom.
     /// </summary>
+
     // PERF: Probably better to store the rectangle rather than make a new one on every single access to Viewport.
     internal Rectangle Viewport
     {
@@ -115,22 +116,24 @@ public class StraightLine
 
         if (StartsAt (x, y))
         {
-            return new IntersectionDefinition (p,
-                                               GetTypeByLength (
-                                                                IntersectionType.StartLeft,
-                                                                IntersectionType.PassOverHorizontal,
-                                                                IntersectionType.StartRight
-                                                               ),
-                                               this
-                                              );
+            return new (
+                        p,
+                        GetTypeByLength (
+                                         IntersectionType.StartLeft,
+                                         IntersectionType.PassOverHorizontal,
+                                         IntersectionType.StartRight
+                                        ),
+                        this
+                       );
         }
 
         if (EndsAt (x, y))
         {
-            return new IntersectionDefinition (p,
-                                               Length < 0 ? IntersectionType.StartRight : IntersectionType.StartLeft,
-                                               this
-                                              );
+            return new (
+                        p,
+                        Length < 0 ? IntersectionType.StartRight : IntersectionType.StartLeft,
+                        this
+                       );
         }
 
         int xmin = Math.Min (Start.X, Start.X + Length);
@@ -138,10 +141,11 @@ public class StraightLine
 
         if (xmin < x && xmax > x)
         {
-            return new IntersectionDefinition (p,
-                                               IntersectionType.PassOverHorizontal,
-                                               this
-                                              );
+            return new (
+                        p,
+                        IntersectionType.PassOverHorizontal,
+                        this
+                       );
         }
 
         return null;
@@ -158,22 +162,24 @@ public class StraightLine
 
         if (StartsAt (x, y))
         {
-            return new IntersectionDefinition (p,
-                                               GetTypeByLength (
-                                                                IntersectionType.StartUp,
-                                                                IntersectionType.PassOverVertical,
-                                                                IntersectionType.StartDown
-                                                               ),
-                                               this
-                                              );
+            return new (
+                        p,
+                        GetTypeByLength (
+                                         IntersectionType.StartUp,
+                                         IntersectionType.PassOverVertical,
+                                         IntersectionType.StartDown
+                                        ),
+                        this
+                       );
         }
 
         if (EndsAt (x, y))
         {
-            return new IntersectionDefinition (p,
-                                               Length < 0 ? IntersectionType.StartDown : IntersectionType.StartUp,
-                                               this
-                                              );
+            return new (
+                        p,
+                        Length < 0 ? IntersectionType.StartDown : IntersectionType.StartUp,
+                        this
+                       );
         }
 
         int ymin = Math.Min (Start.Y, Start.Y + Length);
@@ -181,10 +187,11 @@ public class StraightLine
 
         if (ymin < y && ymax > y)
         {
-            return new IntersectionDefinition (p,
-                                               IntersectionType.PassOverVertical,
-                                               this
-                                              );
+            return new (
+                        p,
+                        IntersectionType.PassOverVertical,
+                        this
+                       );
         }
 
         return null;

+ 94 - 50
Terminal.Gui/View/Adornment/Border.cs

@@ -78,7 +78,7 @@ public class Border : Adornment
         if ((Parent?.Arrangement & ViewArrangement.Movable) != 0)
         {
             HighlightStyle |= HighlightStyle.Hover;
-        }   
+        }
 #endif
 
         base.BeginInit ();
@@ -149,31 +149,32 @@ public class Border : Adornment
         }
     }
 
-    Rectangle GetBorderRectangle (Rectangle screenRect)
+    private Rectangle GetBorderRectangle (Rectangle screenRect)
     {
         return new (
-                                      screenRect.X + Math.Max (0, Thickness.Left - 1),
-                                      screenRect.Y + Math.Max (0, Thickness.Top - 1),
-                                      Math.Max (
-                                                0,
-                                                screenRect.Width
-                                                - Math.Max (
-                                                            0,
-                                                            Math.Max (0, Thickness.Left - 1)
-                                                            + Math.Max (0, Thickness.Right - 1)
-                                                           )
-                                               ),
-                                      Math.Max (
-                                                0,
-                                                screenRect.Height
-                                                - Math.Max (
-                                                            0,
-                                                            Math.Max (0, Thickness.Top - 1)
-                                                            + Math.Max (0, Thickness.Bottom - 1)
-                                                           )
-                                               )
-                                     );
+                    screenRect.X + Math.Max (0, Thickness.Left - 1),
+                    screenRect.Y + Math.Max (0, Thickness.Top - 1),
+                    Math.Max (
+                              0,
+                              screenRect.Width
+                              - Math.Max (
+                                          0,
+                                          Math.Max (0, Thickness.Left - 1)
+                                          + Math.Max (0, Thickness.Right - 1)
+                                         )
+                             ),
+                    Math.Max (
+                              0,
+                              screenRect.Height
+                              - Math.Max (
+                                          0,
+                                          Math.Max (0, Thickness.Top - 1)
+                                          + Math.Max (0, Thickness.Bottom - 1)
+                                         )
+                             )
+                   );
     }
+
     /// <summary>
     ///     Sets the style of the border by changing the <see cref="Thickness"/>. This is a helper API for setting the
     ///     <see cref="Thickness"/> to <c>(1,1,1,1)</c> and setting the line style of the views that comprise the border. If
@@ -196,21 +197,22 @@ public class Border : Adornment
         set => _lineStyle = value;
     }
 
-    private bool _showTitle = true;
+    private BorderSettings _settings = BorderSettings.Title;
 
     /// <summary>
-    ///     Gets or sets whether the title should be shown. The default is <see langword="true"/>.
+    ///     Gets or sets the settings for the border.
     /// </summary>
-    public bool ShowTitle
+    public BorderSettings Settings
     {
-        get => _showTitle;
+        get => _settings;
         set
         {
-            if (value == _showTitle)
+            if (value == _settings)
             {
                 return;
             }
-            _showTitle = value;
+
+            _settings = value;
 
             Parent?.SetNeedsDisplay ();
         }
@@ -225,6 +227,7 @@ public class Border : Adornment
         if (!Parent.Arrangement.HasFlag (ViewArrangement.Movable))
         {
             e.Cancel = true;
+
             return;
         }
 
@@ -235,9 +238,9 @@ public class Border : Adornment
                 _savedForeColor = ColorScheme.Normal.Foreground;
             }
 
-            ColorScheme cs = new ColorScheme (ColorScheme)
+            var cs = new ColorScheme (ColorScheme)
             {
-                Normal = new Attribute (ColorScheme.Normal.Foreground.GetHighlightColor (), ColorScheme.Normal.Background)
+                Normal = new (ColorScheme.Normal.Foreground.GetHighlightColor (), ColorScheme.Normal.Background)
             };
             ColorScheme = cs;
         }
@@ -254,12 +257,13 @@ public class Border : Adornment
 
         if (e.NewValue == HighlightStyle.None && _savedForeColor.HasValue)
         {
-            ColorScheme cs = new ColorScheme (ColorScheme)
+            var cs = new ColorScheme (ColorScheme)
             {
-                Normal = new Attribute (_savedForeColor.Value, ColorScheme.Normal.Background)
+                Normal = new (_savedForeColor.Value, ColorScheme.Normal.Background)
             };
             ColorScheme = cs;
         }
+
         Parent?.SetNeedsDisplay ();
         e.Cancel = true;
     }
@@ -267,7 +271,7 @@ public class Border : Adornment
     private Point? _dragPosition;
     private Point _startGrabPoint;
 
-    /// <inheritdoc />
+    /// <inheritdoc/>
     protected internal override bool OnMouseEvent (MouseEvent mouseEvent)
     {
         if (base.OnMouseEvent (mouseEvent))
@@ -322,16 +326,17 @@ public class Border : Adornment
 
                 _dragPosition = mouseEvent.Position;
 
-                Point parentLoc = Parent.SuperView?.ScreenToViewport (new (mouseEvent.ScreenPosition.X, mouseEvent.ScreenPosition.Y)) ?? mouseEvent.ScreenPosition;
+                Point parentLoc = Parent.SuperView?.ScreenToViewport (new (mouseEvent.ScreenPosition.X, mouseEvent.ScreenPosition.Y))
+                                  ?? mouseEvent.ScreenPosition;
 
                 GetLocationEnsuringFullVisibility (
-                                     Parent,
-                                     parentLoc.X - _startGrabPoint.X,
-                                     parentLoc.Y - _startGrabPoint.Y,
-                                     out int nx,
-                                     out int ny,
-                                     out _
-                                    );
+                                                   Parent,
+                                                   parentLoc.X - _startGrabPoint.X,
+                                                   parentLoc.Y - _startGrabPoint.Y,
+                                                   out int nx,
+                                                   out int ny,
+                                                   out _
+                                                  );
 
                 Parent.X = nx;
                 Parent.Y = ny;
@@ -352,7 +357,6 @@ public class Border : Adornment
         return false;
     }
 
-
     /// <inheritdoc/>
     protected override void Dispose (bool disposing)
     {
@@ -403,7 +407,7 @@ public class Border : Adornment
         // ...thickness extends outward (border/title is always as far in as possible)
         // PERF: How about a call to Rectangle.Offset?
 
-        var borderBounds = GetBorderRectangle (screenBounds);
+        Rectangle borderBounds = GetBorderRectangle (screenBounds);
         int topTitleLineY = borderBounds.Y;
         int titleY = borderBounds.Y;
         var titleBarsLength = 0; // the little vertical thingies
@@ -421,7 +425,7 @@ public class Border : Adornment
         int sideLineLength = borderBounds.Height;
         bool canDrawBorder = borderBounds is { Width: > 0, Height: > 0 };
 
-        if (ShowTitle)
+        if (Settings.FastHasFlags (BorderSettings.Title))
         {
             if (Thickness.Top == 2)
             {
@@ -453,9 +457,10 @@ public class Border : Adornment
             }
         }
 
-        if (canDrawBorder && Thickness.Top > 0 && maxTitleWidth > 0 && ShowTitle && !string.IsNullOrEmpty (Parent?.Title))
+        if (canDrawBorder && Thickness.Top > 0 && maxTitleWidth > 0 && Settings.FastHasFlags (BorderSettings.Title) && !string.IsNullOrEmpty (Parent?.Title))
         {
-            var focus = Parent.GetNormalColor ();
+            Attribute focus = Parent.GetNormalColor ();
+
             if (Parent.SuperView is { } && Parent.SuperView?.Subviews!.Count (s => s.CanFocus) > 1)
             {
                 // Only use focus color if there are multiple focusable views
@@ -492,7 +497,7 @@ public class Border : Adornment
             {
                 // ╔╡Title╞═════╗
                 // ╔╡╞═════╗
-                if (borderBounds.Width < 4 || !ShowTitle || string.IsNullOrEmpty (Parent?.Title))
+                if (borderBounds.Width < 4 || !Settings.FastHasFlags (BorderSettings.Title) || string.IsNullOrEmpty (Parent?.Title))
                 {
                     // ╔╡╞╗ should be ╔══╗
                     lc.AddLine (
@@ -631,7 +636,7 @@ public class Border : Adornment
             Driver.SetAttribute (prevAttr);
 
             // TODO: This should be moved to LineCanvas as a new BorderStyle.Ruler
-            if (View.Diagnostics.HasFlag (ViewDiagnosticFlags.Ruler))
+            if (Diagnostics.HasFlag (ViewDiagnosticFlags.Ruler))
             {
                 // Top
                 var hruler = new Ruler { Length = screenBounds.Width, Orientation = Orientation.Horizontal };
@@ -642,7 +647,7 @@ public class Border : Adornment
                 }
 
                 // Redraw title 
-                if (drawTop && maxTitleWidth > 0 && ShowTitle)
+                if (drawTop && maxTitleWidth > 0 && Settings.FastHasFlags (BorderSettings.Title))
                 {
                     Parent.TitleTextFormatter.Draw (
                                                     new (borderBounds.X + 2, titleY, maxTitleWidth, 1),
@@ -670,6 +675,45 @@ public class Border : Adornment
                     vruler.Draw (new (screenBounds.X + screenBounds.Width - 1, screenBounds.Y + 1), 1);
                 }
             }
+
+            // TODO: This should not be done on each draw?
+            if (Settings.FastHasFlags (BorderSettings.Gradient))
+            {
+                SetupGradientLineCanvas (lc, screenBounds);
+            }
+            else
+            {
+                lc.Fill = null;
+            }
         }
     }
+
+    private void SetupGradientLineCanvas (LineCanvas lc, Rectangle rect)
+    {
+        GetAppealingGradientColors (out List<Color> stops, out List<int> steps);
+
+        var g = new Gradient (stops, steps);
+
+        var fore = new GradientFill (rect, g, GradientDirection.Diagonal);
+        var back = new SolidFill (GetNormalColor ().Background);
+
+        lc.Fill = new (fore, back);
+    }
+
+    private static void GetAppealingGradientColors (out List<Color> stops, out List<int> steps)
+    {
+        // Define the colors of the gradient stops with more appealing colors
+        stops = new()
+        {
+            new (0, 128, 255), // Bright Blue
+            new (0, 255, 128), // Bright Green
+            new (255, 255), // Bright Yellow
+            new (255, 128), // Bright Orange
+            new (255, 0, 128) // Bright Pink
+        };
+
+        // Define the number of steps between each color for smoother transitions
+        // If we pass only a single value then it will assume equal steps between all pairs
+        steps = new() { 15 };
+    }
 }

+ 26 - 0
Terminal.Gui/View/Adornment/BorderSettings.cs

@@ -0,0 +1,26 @@
+using Terminal.Gui.Analyzers.Internal.Attributes;
+
+namespace Terminal.Gui;
+
+/// <summary>
+/// Determines the settings for <see cref="Border"/>.
+/// </summary>
+[Flags]
+[GenerateEnumExtensionMethods (FastHasFlags = true)]
+public enum BorderSettings
+{
+    /// <summary>
+    /// No settings.
+    /// </summary>
+    None = 0,
+
+    /// <summary>
+    /// Show the title.
+    /// </summary>
+    Title = 1,
+
+    /// <summary>
+    /// Use <see cref="GradientFill"/> to draw the border.
+    /// </summary>
+    Gradient = 2,
+}

+ 1 - 1
Terminal.Gui/View/Adornment/Margin.cs

@@ -223,7 +223,7 @@ public class Margin : Adornment
         if (ShadowStyle != ShadowStyle.None && _rightShadow is { } && _bottomShadow is { })
         {
             _rightShadow.Y = Parent.Border.Thickness.Top > 0
-                                 ? Parent.Border.Thickness.Top - (Parent.Border.Thickness.Top > 2 && Parent.Border.ShowTitle ? 1 : 0)
+                                 ? Parent.Border.Thickness.Top - (Parent.Border.Thickness.Top > 2 && Parent.Border.Settings.FastHasFlags (BorderSettings.Title) ? 1 : 0)
                                  : 1;
             _bottomShadow.X = Parent.Border.Thickness.Left > 0 ? Parent.Border.Thickness.Left : 1;
         }

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

@@ -104,7 +104,7 @@ public class Shortcut : View
         void OnInitialized (object sender, EventArgs e)
         {
             SuperViewRendersLineCanvas = true;
-            Border.ShowTitle = false;
+            Border.Settings &= ~BorderSettings.Title;
 
             ShowHide ();
 

+ 49 - 9
UICatalog/Scenarios/BorderEditor.cs

@@ -9,29 +9,30 @@ public class BorderEditor : AdornmentEditor
 {
     private CheckBox _ckbTitle;
     private RadioGroup _rbBorderStyle;
+    private CheckBox _ckbGradient;
 
     public BorderEditor ()
     {
         Title = "_Border";
         Initialized += BorderEditor_Initialized;
         AdornmentChanged += BorderEditor_AdornmentChanged;
-
     }
 
     private void BorderEditor_AdornmentChanged (object sender, EventArgs e)
     {
-        _ckbTitle.State = ((Border)AdornmentToEdit).ShowTitle ? CheckState.Checked : CheckState.UnChecked;
+        _ckbTitle.State = ((Border)AdornmentToEdit).Settings.FastHasFlags (BorderSettings.Title) ? CheckState.Checked : CheckState.UnChecked;
         _rbBorderStyle.SelectedItem = (int)((Border)AdornmentToEdit).LineStyle;
+        _ckbGradient.State = ((Border)AdornmentToEdit).Settings.FastHasFlags (BorderSettings.Gradient) ? CheckState.Checked : CheckState.UnChecked;
     }
 
     private void BorderEditor_Initialized (object sender, EventArgs e)
     {
-
         List<LineStyle> borderStyleEnum = Enum.GetValues (typeof (LineStyle)).Cast<LineStyle> ().ToList ();
 
-        _rbBorderStyle = new RadioGroup
+        _rbBorderStyle = new()
         {
             X = 0,
+
             // BUGBUG: Hack until dimauto is working properly
             Y = Pos.Bottom (Subviews [^1]),
             Width = Dim.Width (Subviews [^2]) + Dim.Width (Subviews [^1]) - 1,
@@ -46,21 +47,34 @@ public class BorderEditor : AdornmentEditor
 
         _rbBorderStyle.SelectedItemChanged += OnRbBorderStyleOnSelectedItemChanged;
 
-        _ckbTitle = new CheckBox
+        _ckbTitle = new()
         {
             X = 0,
             Y = Pos.Bottom (_rbBorderStyle),
 
             State = CheckState.Checked,
             SuperViewRendersLineCanvas = true,
-            Text = "Show Title",
+            Text = "Title",
             Enabled = AdornmentToEdit is { }
         };
 
-
         _ckbTitle.Toggle += OnCkbTitleOnToggle;
         Add (_ckbTitle);
 
+        _ckbGradient = new ()
+        {
+            X = 0,
+            Y = Pos.Bottom (_ckbTitle),
+
+            State = CheckState.Checked,
+            SuperViewRendersLineCanvas = true,
+            Text = "Gradient",
+            Enabled = AdornmentToEdit is { }
+        };
+
+        _ckbGradient.Toggle += OnCkbGradientOnToggle;
+        Add (_ckbGradient);
+
         return;
 
         void OnRbBorderStyleOnSelectedItemChanged (object s, SelectedItemChangedArgs e)
@@ -81,6 +95,32 @@ public class BorderEditor : AdornmentEditor
             LayoutSubviews ();
         }
 
-        void OnCkbTitleOnToggle (object sender, CancelEventArgs<CheckState> args) { ((Border)AdornmentToEdit).ShowTitle = args.NewValue == CheckState.Checked; }
+        void OnCkbTitleOnToggle (object sender, CancelEventArgs<CheckState> args)
+        {
+            if (args.NewValue == CheckState.Checked)
+
+            {
+                ((Border)AdornmentToEdit).Settings |= BorderSettings.Title;
+            }
+            else
+
+            {
+                ((Border)AdornmentToEdit).Settings &= ~BorderSettings.Title;
+            }
+        }
+
+        void OnCkbGradientOnToggle (object sender, CancelEventArgs<CheckState> args)
+        {
+            if (args.NewValue == CheckState.Checked)
+
+            {
+                ((Border)AdornmentToEdit).Settings |= BorderSettings.Gradient;
+            }
+            else
+
+            {
+                ((Border)AdornmentToEdit).Settings &= ~BorderSettings.Gradient;
+            }
+        }
     }
-}
+}

+ 102 - 104
UICatalog/Scenarios/TextEffectsScenario.cs

@@ -1,22 +1,24 @@
-using System;
 using System.Collections.Generic;
-using System.Text;
-using System.Threading;
 using Terminal.Gui;
 
 namespace UICatalog.Scenarios;
 
 [ScenarioMetadata ("Text Effects", "Text Effects.")]
 [ScenarioCategory ("Colors")]
+[ScenarioCategory ("Text and Formatting")]
 public class TextEffectsScenario : Scenario
 {
     private TabView _tabView;
 
-    public static bool LoopingGradient = false;
+    /// <summary>
+    ///     Enable or disable looping of the gradient colors.
+    /// </summary>
+    public static bool LoopingGradient;
 
     public override void Main ()
     {
         Application.Init ();
+
         var w = new Window
         {
             Width = Dim.Fill (),
@@ -24,57 +26,56 @@ public class TextEffectsScenario : Scenario
             Title = "Text Effects Scenario"
         };
 
-        w.Loaded += (s, e) =>
-        {
-            SetupGradientLineCanvas (w, w.Frame.Size);
-        };
-        w.SizeChanging += (s, e) =>
-        {
-            if (e.Size.HasValue)
-            {
-                SetupGradientLineCanvas (w, e.Size.Value);
-            }
-        };
+        w.Loaded += (s, e) => { SetupGradientLineCanvas (w, w.Frame.Size); };
 
-        w.ColorScheme = new ColorScheme
+        w.SizeChanging += (s, e) =>
+                          {
+                              if (e.Size.HasValue)
+                              {
+                                  SetupGradientLineCanvas (w, e.Size.Value);
+                              }
+                          };
+
+        w.ColorScheme = new ()
         {
-            Normal = new Terminal.Gui.Attribute (ColorName.White, ColorName.Black),
-            Focus = new Terminal.Gui.Attribute (ColorName.Black, ColorName.White),
-            HotNormal = new Terminal.Gui.Attribute (ColorName.White, ColorName.Black),
-            HotFocus = new Terminal.Gui.Attribute (ColorName.White, ColorName.Black),
-            Disabled = new Terminal.Gui.Attribute (ColorName.Gray, ColorName.Black)
+            Normal = new (ColorName.White, ColorName.Black),
+            Focus = new (ColorName.Black, ColorName.White),
+            HotNormal = new (ColorName.White, ColorName.Black),
+            HotFocus = new (ColorName.White, ColorName.Black),
+            Disabled = new (ColorName.Gray, ColorName.Black)
         };
 
         // Creates a window that occupies the entire terminal with a title.
-        _tabView = new TabView ()
+        _tabView = new ()
         {
             Width = Dim.Fill (),
-            Height = Dim.Fill (),
+            Height = Dim.Fill ()
         };
 
-        var gradientsView = new GradientsView ()
+        var gradientsView = new GradientsView
         {
             Width = Dim.Fill (),
-            Height = Dim.Fill (),
+            Height = Dim.Fill ()
         };
-        var t1 = new Tab ()
+
+        var t1 = new Tab
         {
             View = gradientsView,
             DisplayText = "Gradients"
         };
 
-
-        var cbLooping = new CheckBox ()
+        var cbLooping = new CheckBox
         {
             Text = "Looping",
             Y = Pos.AnchorEnd (1)
         };
+
         cbLooping.Toggle += (s, e) =>
-        {
-            LoopingGradient = e.NewValue == CheckState.Checked;
-            SetupGradientLineCanvas (w, w.Frame.Size);
-            _tabView.SetNeedsDisplay ();
-        };
+                            {
+                                LoopingGradient = e.NewValue == CheckState.Checked;
+                                SetupGradientLineCanvas (w, w.Frame.Size);
+                                _tabView.SetNeedsDisplay ();
+                            };
 
         gradientsView.Add (cbLooping);
 
@@ -86,50 +87,50 @@ public class TextEffectsScenario : Scenario
         w.Dispose ();
 
         Application.Shutdown ();
-        this.Dispose ();
+        Dispose ();
     }
 
-
-    private void SetupGradientLineCanvas (View w, Size size)
+    private static void SetupGradientLineCanvas (View w, Size size)
     {
-        GetAppealingGradientColors (out var stops, out var steps);
+        GetAppealingGradientColors (out List<Color> stops, out List<int> steps);
 
         var g = new Gradient (stops, steps, LoopingGradient);
 
         var fore = new GradientFill (
-            new Rectangle (0, 0, size.Width, size.Height), g, GradientDirection.Diagonal);
-        var back = new SolidFill (new Terminal.Gui.Color (ColorName.Black));
-
-        w.LineCanvas.Fill = new FillPair (
-            fore,
-            back);
+                                     new (0, 0, size.Width, size.Height),
+                                     g,
+                                     GradientDirection.Diagonal);
+        var back = new SolidFill (new (ColorName.Black));
+
+        w.LineCanvas.Fill = new (
+                                 fore,
+                                 back);
     }
 
     public static void GetAppealingGradientColors (out List<Color> stops, out List<int> steps)
     {
         // Define the colors of the gradient stops with more appealing colors
-        stops = new List<Color>
-        {
-            new Color(0, 128, 255),    // Bright Blue
-            new Color(0, 255, 128),    // Bright Green
-            new Color(255, 255, 0),    // Bright Yellow
-            new Color(255, 128, 0),    // Bright Orange
-            new Color(255, 0, 128)     // Bright Pink
-        };
+        stops =
+        [
+            new (0, 128, 255), // Bright Blue
+            new (0, 255, 128), // Bright Green
+            new (255, 255), // Bright Yellow
+            new (255, 128), // Bright Orange
+            new (255, 0, 128)
+        ];
 
         // Define the number of steps between each color for smoother transitions
         // If we pass only a single value then it will assume equal steps between all pairs
-        steps = new List<int> { 15 };
+        steps = [15];
     }
 }
 
-
 internal class GradientsView : View
 {
-    private const int GradientWidth = 30;
-    private const int GradientHeight = 15;
-    private const int LabelHeight = 1;
-    private const int GradientWithLabelHeight = GradientHeight + LabelHeight + 1; // +1 for spacing
+    private const int GRADIENT_WIDTH = 30;
+    private const int GRADIENT_HEIGHT = 15;
+    private const int LABEL_HEIGHT = 1;
+    private const int GRADIENT_WITH_LABEL_HEIGHT = GRADIENT_HEIGHT + LABEL_HEIGHT + 1; // +1 for spacing
 
     public override void OnDrawContent (Rectangle viewport)
     {
@@ -137,10 +138,10 @@ internal class GradientsView : View
 
         DrawTopLineGradient (viewport);
 
-        int x = 2;
-        int y = 3;
+        var x = 2;
+        var y = 3;
 
-        var gradients = new List<(string Label, GradientDirection Direction)>
+        List<(string Label, GradientDirection Direction)> gradients = new ()
         {
             ("Horizontal", GradientDirection.Horizontal),
             ("Vertical", GradientDirection.Vertical),
@@ -148,74 +149,74 @@ internal class GradientsView : View
             ("Diagonal", GradientDirection.Diagonal)
         };
 
-        foreach (var (label, direction) in gradients)
+        foreach ((string label, GradientDirection direction) in gradients)
         {
-            if (x + GradientWidth > viewport.Width)
+            if (x + GRADIENT_WIDTH > viewport.Width)
             {
                 x = 2; // Reset to left margin
-                y += GradientWithLabelHeight; // Move down to next row
+                y += GRADIENT_WITH_LABEL_HEIGHT; // Move down to next row
             }
 
             DrawLabeledGradientArea (label, direction, x, y);
-            x += GradientWidth + 2; // Move right for next gradient, +2 for spacing
+            x += GRADIENT_WIDTH + 2; // Move right for next gradient, +2 for spacing
         }
     }
 
     private void DrawLabeledGradientArea (string label, GradientDirection direction, int xOffset, int yOffset)
     {
         DrawGradientArea (direction, xOffset, yOffset);
-        CenterText (label, xOffset, yOffset + GradientHeight); // Adjusted for text below the gradient
+        CenterText (label, xOffset, yOffset + GRADIENT_HEIGHT); // Adjusted for text below the gradient
     }
 
     private void CenterText (string text, int xOffset, int yOffset)
     {
-        if(yOffset+1 >= Viewport.Height)
+        if (yOffset + 1 >= Viewport.Height)
         {
             // Not enough space for label
             return;
         }
 
-        var width = text.Length;
-        var x = xOffset + (GradientWidth - width) / 2; // Center the text within the gradient area width
+        int width = text.Length;
+        int x = xOffset + (GRADIENT_WIDTH - width) / 2; // Center the text within the gradient area width
         Driver.SetAttribute (GetNormalColor ());
-        Move (x, yOffset+1);
+        Move (x, yOffset + 1);
         Driver.AddStr (text);
     }
 
     private void DrawGradientArea (GradientDirection direction, int xOffset, int yOffset)
     {
         // Define the colors of the gradient stops
-        var stops = new List<Color>
-        {
-            new Color(255, 0, 0),    // Red
-            new Color(0, 255, 0),    // Green
-            new Color(238, 130, 238)  // Violet
-        };
+        List<Color> stops =
+        [
+            new (255, 0), // Red
+            new (0, 255), // Green
+            new (238, 130, 238)
+        ];
 
         // Define the number of steps between each color
-        var steps = new List<int> { 10, 10 }; // 10 steps between Red -> Green, and Green -> Blue
+        List<int> steps = [10, 10]; // 10 steps between Red -> Green, and Green -> Blue
 
         // Create the gradient
-        var radialGradient = new Gradient (stops, steps, loop: TextEffectsScenario.LoopingGradient);
+        var radialGradient = new Gradient (stops, steps, TextEffectsScenario.LoopingGradient);
 
         // Define the size of the rectangle
-        int maxRow = GradientHeight; // Adjusted to keep aspect ratio
-        int maxColumn = GradientWidth;
+        int maxRow = GRADIENT_HEIGHT; // Adjusted to keep aspect ratio
+        int maxColumn = GRADIENT_WIDTH;
 
         // Build the coordinate-color mapping for a radial gradient
-        var gradientMapping = radialGradient.BuildCoordinateColorMapping (maxRow, maxColumn, direction);
+        Dictionary<Point, Color> gradientMapping = radialGradient.BuildCoordinateColorMapping (maxRow, maxColumn, direction);
 
         // Print the gradient
-        for (int row = 0; row <= maxRow; row++)
+        for (var row = 0; row <= maxRow; row++)
         {
-            for (int col = 0; col <= maxColumn; col++)
+            for (var col = 0; col <= maxColumn; col++)
             {
                 var coord = new Point (col, row);
-                var color = gradientMapping [coord];
+                Color color = gradientMapping [coord];
 
                 SetColor (color);
 
-                AddRune (col + xOffset, row + yOffset, new Rune ('█'));
+                AddRune (col + xOffset, row + yOffset, new ('█'));
             }
         }
     }
@@ -223,44 +224,41 @@ internal class GradientsView : View
     private void DrawTopLineGradient (Rectangle viewport)
     {
         // Define the colors of the rainbow
-        var stops = new List<Color>
-        {
-            new Color(255, 0, 0),     // Red
-            new Color(255, 165, 0),   // Orange
-            new Color(255, 255, 0),   // Yellow
-            new Color(0, 128, 0),     // Green
-            new Color(0, 0, 255),     // Blue
-            new Color(75, 0, 130),    // Indigo
-            new Color(238, 130, 238)  // Violet
-        };
+        List<Color> stops =
+        [
+            new (255, 0), // Red
+            new (255, 165), // Orange
+            new (255, 255), // Yellow
+            new (0, 128), // Green
+            new (0, 0, 255), // Blue
+            new (75, 0, 130), // Indigo
+            new (238, 130, 238)
+        ];
 
         // Define the number of steps between each color
-        var steps = new List<int>
-        {
+        List<int> steps =
+        [
             20, // between Red and Orange
             20, // between Orange and Yellow
             20, // between Yellow and Green
             20, // between Green and Blue
             20, // between Blue and Indigo
-            20  // between Indigo and Violet
-        };
+            20
+        ];
 
         // Create the gradient
         var rainbowGradient = new Gradient (stops, steps, TextEffectsScenario.LoopingGradient);
 
-        for (int x = 0; x < viewport.Width; x++)
+        for (var x = 0; x < viewport.Width; x++)
         {
             double fraction = (double)x / (viewport.Width - 1);
             Color color = rainbowGradient.GetColorAtFraction (fraction);
 
             SetColor (color);
 
-            AddRune (x, 0, new Rune ('█'));
+            AddRune (x, 0, new ('█'));
         }
     }
 
-    private void SetColor (Color color)
-    {
-        Application.Driver.SetAttribute (new Attribute (color, color));
-    }
+    private static void SetColor (Color color) { Application.Driver.SetAttribute (new (color, color)); }
 }

+ 2 - 4
UnitTests/Drawing/FillPairTests.cs

@@ -1,4 +1,4 @@
-using System;
+using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
@@ -8,7 +8,6 @@ namespace Terminal.Gui.DrawingTests;
 
 public class FillPairTests
 {
-
     [Fact]
     public void GetAttribute_ReturnsCorrectColors ()
     {
@@ -21,11 +20,10 @@ public class FillPairTests
         var fillPair = new FillPair (foregroundFill, backgroundFill);
 
         // Act
-        var resultAttribute = fillPair.GetAttribute (new Point (0, 0));
+        Attribute resultAttribute = fillPair.GetAttribute (new (0, 0));
 
         // Assert
         Assert.Equal (foregroundColor, resultAttribute.Foreground);
         Assert.Equal (backgroundColor, resultAttribute.Background);
     }
 }
-

+ 26 - 26
UnitTests/Drawing/GradientFillTests.cs

@@ -2,21 +2,21 @@
 
 public class GradientFillTests
 {
-    private Gradient _gradient;
+    private readonly Gradient _gradient;
 
     public GradientFillTests ()
     {
         // Define the colors of the gradient stops
-        var stops = new List<Color>
+        List<Color> stops = new List<Color>
         {
-            new Color(255, 0, 0),    // Red
-            new Color(0, 0, 255)     // Blue
+            new (255, 0), // Red
+            new (0, 0, 255) // Blue
         };
 
         // Define the number of steps between each color
-        var steps = new List<int> { 10 }; // 10 steps between Red -> Blue
+        List<int> steps = new() { 10 }; // 10 steps between Red -> Blue
 
-        _gradient = new Gradient (stops, steps, loop: false);
+        _gradient = new (stops, steps);
     }
 
     [Fact]
@@ -31,13 +31,13 @@ public class GradientFillTests
         var bottomLeft = new Point (0, area.Height - 1);
         var bottomRight = new Point (area.Width - 1, area.Height - 1);
 
-        var topLeftColor = gradientFill.GetColor (topLeft);
-        var topRightColor = gradientFill.GetColor (topRight);
-        var bottomLeftColor = gradientFill.GetColor (bottomLeft);
-        var bottomRightColor = gradientFill.GetColor (bottomRight);
+        Color topLeftColor = gradientFill.GetColor (topLeft);
+        Color topRightColor = gradientFill.GetColor (topRight);
+        Color bottomLeftColor = gradientFill.GetColor (bottomLeft);
+        Color bottomRightColor = gradientFill.GetColor (bottomRight);
 
         // Expected colors
-        var expectedTopLeftColor = new Color (255, 0, 0); // Red
+        var expectedTopLeftColor = new Color (255, 0); // Red
         var expectedBottomRightColor = new Color (0, 0, 255); // Blue
 
         Assert.Equal (expectedTopLeftColor, topLeftColor);
@@ -56,13 +56,13 @@ public class GradientFillTests
         var bottomLeft = new Point (5, area.Bottom - 1);
         var bottomRight = new Point (area.Right - 1, area.Bottom - 1);
 
-        var topLeftColor = gradientFill.GetColor (topLeft);
-        var topRightColor = gradientFill.GetColor (topRight);
-        var bottomLeftColor = gradientFill.GetColor (bottomLeft);
-        var bottomRightColor = gradientFill.GetColor (bottomRight);
+        Color topLeftColor = gradientFill.GetColor (topLeft);
+        Color topRightColor = gradientFill.GetColor (topRight);
+        Color bottomLeftColor = gradientFill.GetColor (bottomLeft);
+        Color bottomRightColor = gradientFill.GetColor (bottomRight);
 
         // Expected colors
-        var expectedTopLeftColor = new Color (255, 0, 0); // Red
+        var expectedTopLeftColor = new Color (255, 0); // Red
         var expectedBottomRightColor = new Color (0, 0, 255); // Blue
 
         Assert.Equal (expectedTopLeftColor, topLeftColor);
@@ -75,15 +75,15 @@ public class GradientFillTests
         var area = new Rectangle (0, 0, 10, 10);
         var gradientFill = new GradientFill (area, _gradient, GradientDirection.Diagonal);
 
-        for (int row = 0; row < area.Height; row++)
+        for (var row = 0; row < area.Height; row++)
         {
-            int previousRed = 255;
-            int previousBlue = 0;
+            var previousRed = 255;
+            var previousBlue = 0;
 
-            for (int col = 0; col < area.Width; col++)
+            for (var col = 0; col < area.Width; col++)
             {
                 var point = new Point (col, row);
-                var color = gradientFill.GetColor (point);
+                Color color = gradientFill.GetColor (point);
 
                 // Check if the current color is 'more blue' and 'less red' as it goes right and down
                 Assert.True (color.R <= previousRed, $"Failed at ({col}, {row}): {color.R} > {previousRed}");
@@ -95,15 +95,15 @@ public class GradientFillTests
             }
         }
 
-        for (int col = 0; col < area.Width; col++)
+        for (var col = 0; col < area.Width; col++)
         {
-            int previousRed = 255;
-            int previousBlue = 0;
+            var previousRed = 255;
+            var previousBlue = 0;
 
-            for (int row = 0; row < area.Height; row++)
+            for (var row = 0; row < area.Height; row++)
             {
                 var point = new Point (col, row);
-                var color = gradientFill.GetColor (point);
+                Color color = gradientFill.GetColor (point);
 
                 // Check if the current color is 'more blue' and 'less red' as it goes right and down
                 Assert.True (color.R <= previousRed, $"Failed at ({col}, {row}): {color.R} > {previousRed}");

+ 81 - 83
UnitTests/Drawing/GradientTests.cs

@@ -1,5 +1,4 @@
-
-namespace Terminal.Gui.DrawingTests;
+namespace Terminal.Gui.DrawingTests;
 
 public class GradientTests
 {
@@ -7,8 +6,8 @@ public class GradientTests
     public static IEnumerable<object []> GradientDirectionValues ()
     {
         return typeof (GradientDirection).GetEnumValues ()
-            .Cast<GradientDirection> ()
-            .Select (direction => new object [] { direction });
+                                         .Cast<GradientDirection> ()
+                                         .Select (direction => new object [] { direction });
     }
 
     [Theory]
@@ -16,16 +15,16 @@ public class GradientTests
     public void GradientIsInclusive_2_by_2 (GradientDirection direction)
     {
         // Define the colors of the gradient stops
-        var stops = new List<Color>
-            {
-                new Color(255, 0, 0),    // Red
-                new Color(0, 0, 255)     // Blue
-            };
+        List<Color> stops = new()
+        {
+            new (255, 0), // Red
+            new (0, 0, 255) // Blue
+        };
 
         // Define the number of steps between each color
-        var steps = new List<int> { 10 }; // 10 steps between Red -> Blue
+        List<int> steps = new() { 10 }; // 10 steps between Red -> Blue
 
-        var g = new Gradient (stops, steps, loop: false);
+        var g = new Gradient (stops, steps);
         Assert.Equal (4, g.BuildCoordinateColorMapping (1, 1, direction).Count);
     }
 
@@ -34,77 +33,77 @@ public class GradientTests
     public void GradientIsInclusive_1_by_1 (GradientDirection direction)
     {
         // Define the colors of the gradient stops
-        var stops = new List<Color>
-            {
-                new Color(255, 0, 0),    // Red
-                new Color(0, 0, 255)     // Blue
-            };
+        List<Color> stops = new()
+        {
+            new (255, 0), // Red
+            new (0, 0, 255) // Blue
+        };
 
         // Define the number of steps between each color
-        var steps = new List<int> { 10 }; // 10 steps between Red -> Blue
+        List<int> steps = new() { 10 }; // 10 steps between Red -> Blue
 
-        var g = new Gradient (stops, steps, loop: false);
+        var g = new Gradient (stops, steps);
 
         // Note that maxRow and maxCol are inclusive so this results in 1x1 area i.e. a single cell. 
-        var c = Assert.Single (g.BuildCoordinateColorMapping (0, 0, direction));
-        Assert.Equal (c.Key, new Point(0,0));
-        Assert.Equal (c.Value, new Color (0, 0, 255));
+        KeyValuePair<Point, Color> c = Assert.Single (g.BuildCoordinateColorMapping (0, 0, direction));
+        Assert.Equal (c.Key, new (0, 0));
+        Assert.Equal (c.Value, new (0, 0, 255));
     }
 
     [Fact]
     public void SingleColorStop ()
     {
-        var stops = new List<Color> { new Color (255, 0, 0) }; // Red
-        var steps = new List<int> { };
+        List<Color> stops = new() { new (255, 0) }; // Red
+        List<int> steps = new ();
 
-        var g = new Gradient (stops, steps, loop: false);
-        Assert.All (g.Spectrum, color => Assert.Equal (new Color (255, 0, 0), color));
+        var g = new Gradient (stops, steps);
+        Assert.All (g.Spectrum, color => Assert.Equal (new (255, 0), color));
     }
 
     [Fact]
     public void LoopingGradient_CorrectColors ()
     {
-        var stops = new List<Color>
-            {
-                new Color(255, 0, 0),    // Red
-                new Color(0, 0, 255)     // Blue
-            };
+        List<Color> stops = new()
+        {
+            new (255, 0), // Red
+            new (0, 0, 255) // Blue
+        };
 
-        var steps = new List<int> { 10 };
+        List<int> steps = new() { 10 };
 
-        var g = new Gradient (stops, steps, loop: true);
-        Assert.Equal (new Color (255, 0, 0), g.Spectrum.First ());
-        Assert.Equal (new Color (255, 0, 0), g.Spectrum.Last ());
+        var g = new Gradient (stops, steps, true);
+        Assert.Equal (new (255, 0), g.Spectrum.First ());
+        Assert.Equal (new (255, 0), g.Spectrum.Last ());
     }
 
     [Fact]
     public void DifferentStepSizes ()
     {
-        var stops = new List<Color>
-            {
-                new Color(255, 0, 0),    // Red
-                new Color(0, 255, 0),    // Green
-                new Color(0, 0, 255)     // Blue
-            };
+        List<Color> stops = new List<Color>
+        {
+            new (255, 0), // Red
+            new (0, 255), // Green
+            new (0, 0, 255) // Blue
+        };
 
-        var steps = new List<int> { 5, 15 }; // Different steps
+        List<int> steps = new() { 5, 15 }; // Different steps
 
-        var g = new Gradient (stops, steps, loop: false);
+        var g = new Gradient (stops, steps);
         Assert.Equal (22, g.Spectrum.Count);
     }
 
     [Fact]
     public void FractionOutOfRange_ThrowsException ()
     {
-        var stops = new List<Color>
-            {
-                new Color(255, 0, 0),    // Red
-                new Color(0, 0, 255)     // Blue
-            };
+        List<Color> stops = new()
+        {
+            new (255, 0), // Red
+            new (0, 0, 255) // Blue
+        };
 
-        var steps = new List<int> { 10 };
+        List<int> steps = new() { 10 };
 
-        var g = new Gradient (stops, steps, loop: false);
+        var g = new Gradient (stops, steps);
 
         Assert.Throws<ArgumentOutOfRangeException> (() => g.GetColorAtFraction (-0.1));
         Assert.Throws<ArgumentOutOfRangeException> (() => g.GetColorAtFraction (1.1));
@@ -113,30 +112,30 @@ public class GradientTests
     [Fact]
     public void NaNFraction_ReturnsLastColor ()
     {
-        var stops = new List<Color>
-            {
-                new Color(255, 0, 0),    // Red
-                new Color(0, 0, 255)     // Blue
-            };
+        List<Color> stops = new()
+        {
+            new (255, 0), // Red
+            new (0, 0, 255) // Blue
+        };
 
-        var steps = new List<int> { 10 };
+        List<int> steps = new() { 10 };
 
-        var g = new Gradient (stops, steps, loop: false);
-        Assert.Equal (new Color (0, 0, 255), g.GetColorAtFraction (double.NaN));
+        var g = new Gradient (stops, steps);
+        Assert.Equal (new (0, 0, 255), g.GetColorAtFraction (double.NaN));
     }
 
     [Fact]
     public void Constructor_SingleStepProvided_ReplicatesForAllPairs ()
     {
-        var stops = new List<Color>
-    {
-        new Color(255, 0, 0),    // Red
-        new Color(0, 255, 0),    // Green
-        new Color(0, 0, 255)     // Blue
-    };
+        List<Color> stops = new List<Color>
+        {
+            new (255, 0), // Red
+            new (0, 255), // Green
+            new (0, 0, 255) // Blue
+        };
 
-        var singleStep = new List<int> { 5 }; // Single step provided
-        var gradient = new Gradient (stops, singleStep, loop: false);
+        List<int> singleStep = new() { 5 }; // Single step provided
+        var gradient = new Gradient (stops, singleStep);
 
         Assert.NotNull (gradient.Spectrum);
         Assert.Equal (12, gradient.Spectrum.Count); // 5 steps Red -> Green + 5 steps Green -> Blue + 2 end colors
@@ -145,31 +144,30 @@ public class GradientTests
     [Fact]
     public void Constructor_InvalidStepsLength_ThrowsArgumentException ()
     {
-        var stops = new List<Color>
-    {
-        new Color(255, 0, 0),    // Red
-        new Color(0, 0, 255)     // Blue
-    };
-
-        var invalidSteps = new List<int> { 5, 5 }; // Invalid length (N-1 expected)
-        Assert.Throws<ArgumentException> (() => new Gradient (stops, invalidSteps, loop: false));
+        List<Color> stops = new()
+        {
+            new (255, 0), // Red
+            new (0, 0, 255) // Blue
+        };
+
+        List<int> invalidSteps = new() { 5, 5 }; // Invalid length (N-1 expected)
+        Assert.Throws<ArgumentException> (() => new Gradient (stops, invalidSteps));
     }
 
     [Fact]
     public void Constructor_ValidStepsLength_DoesNotThrow ()
     {
-        var stops = new List<Color>
-    {
-        new Color(255, 0, 0),    // Red
-        new Color(0, 255, 0),    // Green
-        new Color(0, 0, 255)     // Blue
-    };
+        List<Color> stops = new List<Color>
+        {
+            new (255, 0), // Red
+            new (0, 255), // Green
+            new (0, 0, 255) // Blue
+        };
 
-        var validSteps = new List<int> { 5, 5 }; // Valid length (N-1)
-        var gradient = new Gradient (stops, validSteps, loop: false);
+        List<int> validSteps = new() { 5, 5 }; // Valid length (N-1)
+        var gradient = new Gradient (stops, validSteps);
 
         Assert.NotNull (gradient.Spectrum);
         Assert.Equal (12, gradient.Spectrum.Count); // 5 steps Red -> Green + 5 steps Green -> Blue + 2 end colors
     }
-
-}
+}

+ 48 - 48
UnitTests/Drawing/LineCanvasTests.cs

@@ -3,7 +3,7 @@ using Xunit.Abstractions;
 
 namespace Terminal.Gui.DrawingTests;
 
-public class LineCanvasTests (ITestOutputHelper output)
+public class LineCanvasTests (ITestOutputHelper _output)
 {
     [Theory]
 
@@ -294,7 +294,7 @@ public class LineCanvasTests (ITestOutputHelper output)
         lc.AddLine (new (x1, y1), len1, o1, s1);
         lc.AddLine (new (x2, y2), len2, o2, s2);
 
-        TestHelpers.AssertEqual (output, expected, lc.ToString ());
+        TestHelpers.AssertEqual (_output, expected, lc.ToString ());
         v.Dispose ();
     }
 
@@ -503,7 +503,7 @@ public class LineCanvasTests (ITestOutputHelper output)
         Assert.Equal (new (x, y, 4, 2), lc.Viewport);
 
         TestHelpers.AssertEqual (
-                                 output,
+                                 _output,
                                  @"
 ╔╡╞╗
 ║  ║",
@@ -553,7 +553,7 @@ public class LineCanvasTests (ITestOutputHelper output)
         Assert.Equal (new (x, y, 4, 2), lc.Viewport);
 
         TestHelpers.AssertEqual (
-                                 output,
+                                 _output,
                                  @"
 ╔╡╞╗
 ║  ║",
@@ -596,7 +596,7 @@ public class LineCanvasTests (ITestOutputHelper output)
 
         // Add a line at 5, 5 that's has length of 1
         canvas.AddLine (new (x, y), 1, orientation, LineStyle.Single);
-        TestHelpers.AssertEqual (output, $"{expected}", $"{canvas}");
+        TestHelpers.AssertEqual (_output, $"{expected}", $"{canvas}");
     }
 
     // X is offset by 2
@@ -653,7 +653,7 @@ public class LineCanvasTests (ITestOutputHelper output)
         canvas.AddLine (new (x, y), length, orientation, LineStyle.Single);
 
         var result = canvas.ToString ();
-        TestHelpers.AssertEqual (output, expected, result);
+        TestHelpers.AssertEqual (_output, expected, result);
     }
 
     [Fact]
@@ -680,7 +680,7 @@ public class LineCanvasTests (ITestOutputHelper output)
 
         // Add a line at 0, 0 that's has length of 0
         lc.AddLine (Point.Empty, 0, orientation, LineStyle.Single);
-        TestHelpers.AssertEqual (output, expected, $"{lc}");
+        TestHelpers.AssertEqual (_output, expected, $"{lc}");
     }
 
     [InlineData (Orientation.Horizontal, "┼")]
@@ -701,7 +701,7 @@ public class LineCanvasTests (ITestOutputHelper output)
 
         // Add a line at 0, 0 that's has length of 0
         lc.AddLine (Point.Empty, 0, orientation, LineStyle.Single);
-        TestHelpers.AssertEqual (output, expected, $"{lc}");
+        TestHelpers.AssertEqual (_output, expected, $"{lc}");
     }
 
     [InlineData (Orientation.Horizontal, "╥")]
@@ -724,7 +724,7 @@ public class LineCanvasTests (ITestOutputHelper output)
 
         // Add a line at 0, 0 that's has length of 0
         lc.AddLine (Point.Empty, 0, orientation, LineStyle.Single);
-        TestHelpers.AssertEqual (output, expected, $"{lc}");
+        TestHelpers.AssertEqual (_output, expected, $"{lc}");
     }
 
     [Fact]
@@ -740,7 +740,7 @@ public class LineCanvasTests (ITestOutputHelper output)
             @"
 ┌─
 │ ";
-        TestHelpers.AssertEqual (output, looksLike, $"{Environment.NewLine}{canvas}");
+        TestHelpers.AssertEqual (_output, looksLike, $"{Environment.NewLine}{canvas}");
     }
 
     [Fact]
@@ -767,7 +767,7 @@ public class LineCanvasTests (ITestOutputHelper output)
 ┣━━━━╋━━━┫
 ┃    ┃   ┃
 ┗━━━━┻━━━┛";
-        TestHelpers.AssertDriverContentsAre (looksLike, output);
+        TestHelpers.AssertDriverContentsAre (looksLike, _output);
         v.Dispose ();
     }
 
@@ -798,7 +798,7 @@ public class LineCanvasTests (ITestOutputHelper output)
 │    │   │
 ┕━━━━┷━━━┙
 ";
-        TestHelpers.AssertDriverContentsAre (looksLike, output);
+        TestHelpers.AssertDriverContentsAre (looksLike, _output);
         v.Dispose ();
     }
 
@@ -830,7 +830,7 @@ public class LineCanvasTests (ITestOutputHelper output)
 ┖────┸───┚
 
 ";
-        TestHelpers.AssertDriverContentsAre (looksLike, output);
+        TestHelpers.AssertDriverContentsAre (looksLike, _output);
         v.Dispose ();
     }
 
@@ -848,7 +848,7 @@ public class LineCanvasTests (ITestOutputHelper output)
             @"
 ┌─
 │ ";
-        TestHelpers.AssertEqual (output, looksLike, $"{Environment.NewLine}{canvas}");
+        TestHelpers.AssertEqual (_output, looksLike, $"{Environment.NewLine}{canvas}");
     }
 
     [Fact]
@@ -878,7 +878,7 @@ public class LineCanvasTests (ITestOutputHelper output)
         Assert.Equal (2, map.Count);
 
         TestHelpers.AssertEqual (
-                                 output,
+                                 _output,
                                  @"
  ─",
@@ -891,7 +891,7 @@ public class LineCanvasTests (ITestOutputHelper output)
     public void ToString_Empty ()
     {
         var lc = new LineCanvas ();
-        TestHelpers.AssertEqual (output, string.Empty, lc.ToString ());
+        TestHelpers.AssertEqual (_output, string.Empty, lc.ToString ());
     }
 
     //                  012
@@ -910,7 +910,7 @@ public class LineCanvasTests (ITestOutputHelper output)
     {
         var lc = new LineCanvas ();
         lc.AddLine (new (x, y), 3, Orientation.Horizontal, LineStyle.Double);
-        TestHelpers.AssertEqual (output, expected, $"{lc}");
+        TestHelpers.AssertEqual (_output, expected, $"{lc}");
     }
 
     [InlineData (0, 0, 0, 0, "═══")]
@@ -935,7 +935,7 @@ public class LineCanvasTests (ITestOutputHelper output)
         lc.AddLine (new (x1, y1), 3, Orientation.Horizontal, LineStyle.Double);
         lc.AddLine (new (x2, y2), 3, Orientation.Horizontal, LineStyle.Double);
 
-        TestHelpers.AssertEqual (output, expected, $"{lc}");
+        TestHelpers.AssertEqual (_output, expected, $"{lc}");
     }
 
     //		[Fact, SetupFakeDriver]
@@ -995,7 +995,7 @@ public class LineCanvasTests (ITestOutputHelper output)
 
         v.Draw ();
 
-        TestHelpers.AssertDriverContentsAre (expected, output);
+        TestHelpers.AssertDriverContentsAre (expected, _output);
         v.Dispose ();
     }
 
@@ -1014,7 +1014,7 @@ public class LineCanvasTests (ITestOutputHelper output)
             @"    
 ┌─
 │";
-        TestHelpers.AssertDriverContentsAre (looksLike, output);
+        TestHelpers.AssertDriverContentsAre (looksLike, _output);
         v.Dispose ();
     }
 
@@ -1037,7 +1037,7 @@ public class LineCanvasTests (ITestOutputHelper output)
 ──
 │";
-        TestHelpers.AssertDriverContentsAre (looksLike, output);
+        TestHelpers.AssertDriverContentsAre (looksLike, _output);
         v.Dispose ();
     }
 
@@ -1055,7 +1055,7 @@ public class LineCanvasTests (ITestOutputHelper output)
         var looksLike =
             @"    
 ──";
-        TestHelpers.AssertDriverContentsAre (looksLike, output);
+        TestHelpers.AssertDriverContentsAre (looksLike, _output);
         v.Dispose ();
     }
 
@@ -1071,7 +1071,7 @@ public class LineCanvasTests (ITestOutputHelper output)
         var looksLike =
             @" 
 ══";
-        TestHelpers.AssertDriverContentsAre (looksLike, output);
+        TestHelpers.AssertDriverContentsAre (looksLike, _output);
         v.Dispose ();
     }
 
@@ -1090,7 +1090,7 @@ public class LineCanvasTests (ITestOutputHelper output)
             @"    
 │";
-        TestHelpers.AssertDriverContentsAre (looksLike, output);
+        TestHelpers.AssertDriverContentsAre (looksLike, _output);
         v.Dispose ();
     }
 
@@ -1107,7 +1107,7 @@ public class LineCanvasTests (ITestOutputHelper output)
             @"    
 ║";
-        TestHelpers.AssertDriverContentsAre (looksLike, output);
+        TestHelpers.AssertDriverContentsAre (looksLike, _output);
         v.Dispose ();
     }
 
@@ -1135,7 +1135,7 @@ public class LineCanvasTests (ITestOutputHelper output)
 ╠════╬═══╣
 ║    ║   ║
 ╚════╩═══╝";
-        TestHelpers.AssertDriverContentsAre (looksLike, output);
+        TestHelpers.AssertDriverContentsAre (looksLike, _output);
         v.Dispose ();
     }
 
@@ -1166,7 +1166,7 @@ public class LineCanvasTests (ITestOutputHelper output)
 │    │   │
 ╘════╧═══╛
 ";
-        TestHelpers.AssertDriverContentsAre (looksLike, output);
+        TestHelpers.AssertDriverContentsAre (looksLike, _output);
         v.Dispose ();
     }
 
@@ -1203,7 +1203,7 @@ public class LineCanvasTests (ITestOutputHelper output)
 ├────┼───┤
 │    │   │
 ╰────┴───╯";
-        TestHelpers.AssertDriverContentsAre (looksLike, output);
+        TestHelpers.AssertDriverContentsAre (looksLike, _output);
         v.Dispose ();
     }
 
@@ -1235,7 +1235,7 @@ public class LineCanvasTests (ITestOutputHelper output)
 ╙────╨───╜
 
 ";
-        TestHelpers.AssertDriverContentsAre (looksLike, output);
+        TestHelpers.AssertDriverContentsAre (looksLike, _output);
         v.Dispose ();
     }
 
@@ -1262,7 +1262,7 @@ public class LineCanvasTests (ITestOutputHelper output)
 ├────┼───┤
 │    │   │
 └────┴───┘";
-        TestHelpers.AssertEqual (output, looksLike, $"{Environment.NewLine}{canvas}");
+        TestHelpers.AssertEqual (_output, looksLike, $"{Environment.NewLine}{canvas}");
     }
 
     [Fact]
@@ -1300,15 +1300,15 @@ public class LineCanvasTests (ITestOutputHelper output)
         var looksLike = @"
 ╔╡╞══╗
 ║    ║";
-        TestHelpers.AssertEqual (output, looksLike, $"{Environment.NewLine}{lc}");
+        TestHelpers.AssertEqual (_output, looksLike, $"{Environment.NewLine}{lc}");
     }
 
     [Fact]
     public void LineCanvas_UsesFillCorrectly ()
     {
         // Arrange
-        var foregroundColor = new Color (255, 0, 0); // Red
-        var backgroundColor = new Color (0, 0, 0);   // Black
+        var foregroundColor = new Color (255, 0); // Red
+        var backgroundColor = new Color (0, 0); // Black
         var foregroundFill = new SolidFill (foregroundColor);
         var backgroundFill = new SolidFill (backgroundColor);
         var fillPair = new FillPair (foregroundFill, backgroundFill);
@@ -1319,11 +1319,11 @@ public class LineCanvasTests (ITestOutputHelper output)
         };
 
         // Act
-        lineCanvas.AddLine (new Point (0, 0), 5, Orientation.Horizontal, LineStyle.Single);
-        var cellMap = lineCanvas.GetCellMap ();
+        lineCanvas.AddLine (new (0, 0), 5, Orientation.Horizontal, LineStyle.Single);
+        Dictionary<Point, Cell?> cellMap = lineCanvas.GetCellMap ();
 
         // Assert
-        foreach (var cell in cellMap.Values)
+        foreach (Cell? cell in cellMap.Values)
         {
             Assert.NotNull (cell);
             Assert.Equal (foregroundColor, cell.Value.Attribute.Value.Foreground);
@@ -1335,9 +1335,9 @@ public class LineCanvasTests (ITestOutputHelper output)
     public void LineCanvas_LineColorIgnoredBecauseOfFill ()
     {
         // Arrange
-        var foregroundColor = new Color (255, 0, 0); // Red
-        var backgroundColor = new Color (0, 0, 0);   // Black
-        var lineColor = new Attribute (new Color (0, 255, 0), new Color (255, 255, 255)); // Green on White
+        var foregroundColor = new Color (255, 0); // Red
+        var backgroundColor = new Color (0, 0); // Black
+        var lineColor = new Attribute (new Color (0, 255), new Color (255, 255, 255)); // Green on White
         var foregroundFill = new SolidFill (foregroundColor);
         var backgroundFill = new SolidFill (backgroundColor);
         var fillPair = new FillPair (foregroundFill, backgroundFill);
@@ -1348,11 +1348,11 @@ public class LineCanvasTests (ITestOutputHelper output)
         };
 
         // Act
-        lineCanvas.AddLine (new Point (0, 0), 5, Orientation.Horizontal, LineStyle.Single, lineColor);
-        var cellMap = lineCanvas.GetCellMap ();
+        lineCanvas.AddLine (new (0, 0), 5, Orientation.Horizontal, LineStyle.Single, lineColor);
+        Dictionary<Point, Cell?> cellMap = lineCanvas.GetCellMap ();
 
         // Assert
-        foreach (var cell in cellMap.Values)
+        foreach (Cell? cell in cellMap.Values)
         {
             Assert.NotNull (cell);
             Assert.Equal (foregroundColor, cell.Value.Attribute.Value.Foreground);
@@ -1364,8 +1364,8 @@ public class LineCanvasTests (ITestOutputHelper output)
     public void LineCanvas_IntersectingLinesUseFillCorrectly ()
     {
         // Arrange
-        var foregroundColor = new Color (255, 0, 0); // Red
-        var backgroundColor = new Color (0, 0, 0);   // Black
+        var foregroundColor = new Color (255, 0); // Red
+        var backgroundColor = new Color (0, 0); // Black
         var foregroundFill = new SolidFill (foregroundColor);
         var backgroundFill = new SolidFill (backgroundColor);
         var fillPair = new FillPair (foregroundFill, backgroundFill);
@@ -1376,12 +1376,12 @@ public class LineCanvasTests (ITestOutputHelper output)
         };
 
         // Act
-        lineCanvas.AddLine (new Point (0, 0), 5, Orientation.Horizontal, LineStyle.Single);
-        lineCanvas.AddLine (new Point (2, -2), 5, Orientation.Vertical, LineStyle.Single);
-        var cellMap = lineCanvas.GetCellMap ();
+        lineCanvas.AddLine (new (0, 0), 5, Orientation.Horizontal, LineStyle.Single);
+        lineCanvas.AddLine (new (2, -2), 5, Orientation.Vertical, LineStyle.Single);
+        Dictionary<Point, Cell?> cellMap = lineCanvas.GetCellMap ();
 
         // Assert
-        foreach (var cell in cellMap.Values)
+        foreach (Cell? cell in cellMap.Values)
         {
             Assert.NotNull (cell);
             Assert.Equal (foregroundColor, cell.Value.Attribute.Value.Foreground);

+ 3 - 4
UnitTests/Drawing/SolidFillTests.cs

@@ -1,4 +1,3 @@
-
 namespace Terminal.Gui.DrawingTests;
 
 public class SolidFillTests
@@ -11,7 +10,7 @@ public class SolidFillTests
         var solidFill = new SolidFill (expectedColor);
 
         // Act
-        var resultColor = solidFill.GetColor (new Point (0, 0));
+        Color resultColor = solidFill.GetColor (new (0, 0));
 
         // Assert
         Assert.Equal (expectedColor, resultColor);
@@ -30,9 +29,9 @@ public class SolidFillTests
         var solidFill = new SolidFill (expectedColor);
 
         // Act
-        var resultColor = solidFill.GetColor (new Point (x, y));
+        Color resultColor = solidFill.GetColor (new (x, y));
 
         // Assert
         Assert.Equal (expectedColor, resultColor);
     }
-}
+}

+ 11 - 14
UnitTests/Drawing/StraightLineExtensionsTests.cs

@@ -2,11 +2,8 @@
 
 namespace Terminal.Gui.DrawingTests;
 
-public class StraightLineExtensionsTests
+public class StraightLineExtensionsTests (ITestOutputHelper output)
 {
-    private readonly ITestOutputHelper _output;
-    public StraightLineExtensionsTests (ITestOutputHelper output) { _output = output; }
-
     [Fact]
     [AutoInitShutdown]
     public void LineCanvasIntegrationTest ()
@@ -18,7 +15,7 @@ public class StraightLineExtensionsTests
         lc.AddLine (new Point (0, 4), -5, Orientation.Vertical, LineStyle.Single);
 
         TestHelpers.AssertEqual (
-                                 _output,
+                                 output,
                                  @"
 ┌────────┐
 │        │
@@ -32,7 +29,7 @@ public class StraightLineExtensionsTests
         lc = new LineCanvas (origLines.Exclude (Point.Empty, 10, Orientation.Horizontal));
 
         TestHelpers.AssertEqual (
-                                 _output,
+                                 output,
                                  @"
 │        │
 │        │
@@ -44,7 +41,7 @@ public class StraightLineExtensionsTests
         lc = new LineCanvas (origLines.Exclude (new Point (0, 1), 10, Orientation.Horizontal));
 
         TestHelpers.AssertEqual (
-                                 _output,
+                                 output,
                                  @"
 ┌────────┐
           
@@ -57,7 +54,7 @@ public class StraightLineExtensionsTests
         lc = new LineCanvas (origLines.Exclude (new Point (0, 2), 10, Orientation.Horizontal));
 
         TestHelpers.AssertEqual (
-                                 _output,
+                                 output,
                                  @"
 ┌────────┐
 │        │
@@ -70,7 +67,7 @@ public class StraightLineExtensionsTests
         lc = new LineCanvas (origLines.Exclude (new Point (0, 3), 10, Orientation.Horizontal));
 
         TestHelpers.AssertEqual (
-                                 _output,
+                                 output,
                                  @"
 ┌────────┐
 │        │
@@ -83,7 +80,7 @@ public class StraightLineExtensionsTests
         lc = new LineCanvas (origLines.Exclude (new Point (0, 4), 10, Orientation.Horizontal));
 
         TestHelpers.AssertEqual (
-                                 _output,
+                                 output,
                                  @"
 ┌────────┐
 │        │
@@ -95,7 +92,7 @@ public class StraightLineExtensionsTests
         lc = new LineCanvas (origLines.Exclude (Point.Empty, 10, Orientation.Vertical));
 
         TestHelpers.AssertEqual (
-                                 _output,
+                                 output,
                                  @"
 ────────┐
@@ -108,7 +105,7 @@ public class StraightLineExtensionsTests
         lc = new LineCanvas (origLines.Exclude (new Point (1, 0), 10, Orientation.Vertical));
 
         TestHelpers.AssertEqual (
-                                 _output,
+                                 output,
                                  @"
 ┌ ───────┐
 │        │
@@ -121,7 +118,7 @@ public class StraightLineExtensionsTests
         lc = new LineCanvas (origLines.Exclude (new Point (8, 0), 10, Orientation.Vertical));
 
         TestHelpers.AssertEqual (
-                                 _output,
+                                 output,
                                  @"
 ┌─────── ┐
 │        │
@@ -134,7 +131,7 @@ public class StraightLineExtensionsTests
         lc = new LineCanvas (origLines.Exclude (new Point (9, 0), 10, Orientation.Vertical));
 
         TestHelpers.AssertEqual (
-                                 _output,
+                                 output,
                                  @"
 ┌────────

+ 4 - 5
UnitTests/Drawing/StraightLineTests.cs

@@ -2,10 +2,9 @@
 
 namespace Terminal.Gui.DrawingTests;
 
-public class StraightLineTests
+public class StraightLineTests (ITestOutputHelper output)
 {
-    private readonly ITestOutputHelper output;
-    public StraightLineTests (ITestOutputHelper output) { this.output = output; }
+    private readonly ITestOutputHelper _output = output;
 
     [InlineData (
                     Orientation.Horizontal,
@@ -320,8 +319,8 @@ public class StraightLineTests
         int expectedHeight
     )
     {
-        var sl = new StraightLine (new Point (x, y), length, orientation, LineStyle.Single);
+        var sl = new StraightLine (new (x, y), length, orientation, LineStyle.Single);
 
-        Assert.Equal (new Rectangle (expectedX, expectedY, expectedWidth, expectedHeight), sl.Viewport);
+        Assert.Equal (new (expectedX, expectedY, expectedWidth, expectedHeight), sl.Viewport);
     }
 }