tznind 1 year ago
parent
commit
be764b7903

+ 22 - 3
Terminal.Gui/Drawing/FillPair.cs

@@ -10,16 +10,35 @@ namespace Terminal.Gui;
 /// </summary>
 public class FillPair
 {
+    /// <summary>
+    /// 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>
     public FillPair (GradientFill fore, SolidFill back)
     {
         Foreground = fore;
         Background = back;
     }
 
-    IFill Foreground { get; set; }
-    IFill Background { get; set; }
+    /// <summary>
+    /// The fill which provides point based foreground color.
+    /// </summary>
+    public IFill Foreground { get; init; }
 
-    internal Attribute? GetAttribute (Point point)
+    /// <summary>
+    /// 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"/>.
+    /// </summary>
+    /// <param name="point"></param>
+    /// <returns></returns>
+    public Attribute GetAttribute (Point point)
     {
         return new Attribute (
             Foreground.GetColor (point),

+ 35 - 12
Terminal.Gui/Drawing/Gradient.cs

@@ -6,6 +6,36 @@ 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
+/// </summary>
+public enum GradientDirection
+{
+    /// <summary>
+    /// 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.
+    /// </summary>
+    Horizontal,
+
+
+    /// <summary>
+    /// 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)
+    /// </summary>
+    Diagonal
+}
+
+/// <summary>
+/// Describes
+/// </summary>
 public class Gradient
 {
     public List<Color> Spectrum { get; private set; }
@@ -13,13 +43,6 @@ public class Gradient
     private readonly List<Color> _stops;
     private readonly List<int> _steps;
 
-    public enum Direction
-    {
-        Vertical,
-        Horizontal,
-        Radial,
-        Diagonal
-    }
 
     public Gradient (IEnumerable<Color> stops, IEnumerable<int> steps, bool loop = false)
     {
@@ -83,13 +106,13 @@ public class Gradient
         }
     }
 
-    public Dictionary<Point, Color> BuildCoordinateColorMapping (int maxRow, int maxColumn, Direction direction)
+    public Dictionary<Point, Color> BuildCoordinateColorMapping (int maxRow, int maxColumn, GradientDirection direction)
     {
         var gradientMapping = new Dictionary<Point, Color> ();
 
         switch (direction)
         {
-            case Direction.Vertical:
+            case GradientDirection.Vertical:
                 for (int row = 0; row <= maxRow; row++)
                 {
                     double fraction = maxRow == 0 ? 1.0 : (double)row / maxRow;
@@ -101,7 +124,7 @@ public class Gradient
                 }
                 break;
 
-            case Direction.Horizontal:
+            case GradientDirection.Horizontal:
                 for (int col = 0; col <= maxColumn; col++)
                 {
                     double fraction = maxColumn == 0 ? 1.0 : (double)col / maxColumn;
@@ -113,7 +136,7 @@ public class Gradient
                 }
                 break;
 
-            case Direction.Radial:
+            case GradientDirection.Radial:
                 for (int row = 0; row <= maxRow; row++)
                 {
                     for (int col = 0; col <= maxColumn; col++)
@@ -125,7 +148,7 @@ public class Gradient
                 }
                 break;
 
-            case Direction.Diagonal:
+            case GradientDirection.Diagonal:
                 for (int row = 0; row <= maxRow; row++)
                 {
                     for (int col = 0; col <= maxColumn; col++)

+ 15 - 1
Terminal.Gui/Drawing/GradientFill.cs

@@ -8,11 +8,25 @@ public class GradientFill : IFill
 {
     private Dictionary<Point, Color> _map;
 
-    public GradientFill (Rectangle area, Gradient gradient, Gradient.Direction direction)
+    /// <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"/>.
+    /// </summary>
+    /// <param name="area"></param>
+    /// <param name="gradient"></param>
+    /// <param name="direction"></param>
+    public GradientFill (Rectangle area, Gradient gradient, GradientDirection direction)
     {
         _map = gradient.BuildCoordinateColorMapping (area.Height, area.Width, direction);
     }
 
+    /// <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).
+    /// </summary>
+    /// <param name="point"></param>
+    /// <returns></returns>
     public Color GetColor (Point point)
     {
         if (_map.TryGetValue (point, out var color))

+ 12 - 4
Terminal.Gui/Drawing/LineCanvas.cs

@@ -4,7 +4,13 @@ namespace Terminal.Gui;
 /// <summary>Facilitates box drawing and line intersection detection and rendering.  Does not support diagonal lines.</summary>
 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.
+    /// </summary>
     public FillPair? Fill { get; set; }
+
     private readonly List<StraightLine> _lines = [];
 
     private readonly Dictionary<IntersectionRuneType, IntersectionRuneResolver> _runeResolvers = new ()
@@ -86,7 +92,7 @@ public class LineCanvas : IDisposable
                     viewport = Rectangle.Union (viewport, _lines [i].Viewport);
                 }
 
-                if (viewport is {Width: 0} or {Height: 0})
+                if (viewport is { Width: 0 } or { Height: 0 })
                 {
                     viewport = viewport with
                     {
@@ -325,9 +331,11 @@ public class LineCanvas : IDisposable
     /// <returns></returns>
     private bool Exactly (HashSet<IntersectionType> intersects, params IntersectionType [] types) { return intersects.SetEquals (types); }
 
-    private Attribute? GetAttributeForIntersects (IntersectionDefinition? [] intersects) { 
-        return Fill != null ? Fill.GetAttribute(intersects [0]!.Point):
-            intersects [0]!.Line.Attribute; }
+    private Attribute? GetAttributeForIntersects (IntersectionDefinition? [] intersects)
+    {
+        return Fill != null ? Fill.GetAttribute (intersects [0]!.Point) :
+            intersects [0]!.Line.Attribute;
+    }
 
     private Cell? GetCellForIntersects (ConsoleDriver driver, IntersectionDefinition? [] intersects)
     {

+ 12 - 0
Terminal.Gui/Drawing/SolidFill.cs

@@ -8,10 +8,22 @@ public class SolidFill : IFill
 {
     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.
+    /// </summary>
+    /// <param name="color"></param>
     public SolidFill (Color color)
     {
         _color = color;
     }
+
+    /// <summary>
+    /// 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;

+ 10 - 12
Terminal.Gui/Drawing/StraightLine.cs

@@ -111,10 +111,11 @@ public class StraightLine
             return null;
         }
 
+        var p = new Point (x, y);
+
         if (StartsAt (x, y))
         {
-            return new IntersectionDefinition (
-                                               new Point (x, y),
+            return new IntersectionDefinition (p,
                                                GetTypeByLength (
                                                                 IntersectionType.StartLeft,
                                                                 IntersectionType.PassOverHorizontal,
@@ -126,8 +127,7 @@ public class StraightLine
 
         if (EndsAt (x, y))
         {
-            return new IntersectionDefinition (
-                                               new Point (x, y),
+            return new IntersectionDefinition (p,
                                                Length < 0 ? IntersectionType.StartRight : IntersectionType.StartLeft,
                                                this
                                               );
@@ -138,8 +138,7 @@ public class StraightLine
 
         if (xmin < x && xmax > x)
         {
-            return new IntersectionDefinition (
-                                               new Point (x, y),
+            return new IntersectionDefinition (p,
                                                IntersectionType.PassOverHorizontal,
                                                this
                                               );
@@ -155,10 +154,11 @@ public class StraightLine
             return null;
         }
 
+        var p = new Point (x, y);
+
         if (StartsAt (x, y))
         {
-            return new IntersectionDefinition (
-                                               new Point (x, y),
+            return new IntersectionDefinition (p,
                                                GetTypeByLength (
                                                                 IntersectionType.StartUp,
                                                                 IntersectionType.PassOverVertical,
@@ -170,8 +170,7 @@ public class StraightLine
 
         if (EndsAt (x, y))
         {
-            return new IntersectionDefinition (
-                                               new Point (x, y),
+            return new IntersectionDefinition (p,
                                                Length < 0 ? IntersectionType.StartDown : IntersectionType.StartUp,
                                                this
                                               );
@@ -182,8 +181,7 @@ public class StraightLine
 
         if (ymin < y && ymax > y)
         {
-            return new IntersectionDefinition (
-                                               new Point (x, y),
+            return new IntersectionDefinition (p,
                                                IntersectionType.PassOverVertical,
                                                this
                                               );

+ 18 - 17
UICatalog/Scenarios/TextEffectsScenario.cs

@@ -19,7 +19,7 @@ public class TextEffectsScenario : Scenario
         Application.Init ();
         var w = new Window
         {
-            Width = Dim.Fill(),
+            Width = Dim.Fill (),
             Height = Dim.Fill (),
             Title = "Text Effects Scenario"
         };
@@ -30,13 +30,13 @@ public class TextEffectsScenario : Scenario
             // TODO: Does not work
             //  SetupGradientLineCanvas (tabView, tabView.Frame.Size);
         };
-        w.SizeChanging += (s,e)=>
+        w.SizeChanging += (s, e) =>
         {
-            if(e.Size.HasValue)
+            if (e.Size.HasValue)
             {
                 SetupGradientLineCanvas (w, e.Size.Value);
             }
-            
+
             // TODO: Does not work
             //SetupGradientLineCanvas (tabView, tabView.Frame.Size);
         };
@@ -44,7 +44,7 @@ public class TextEffectsScenario : Scenario
         w.ColorScheme = new ColorScheme
         {
             Normal = new Terminal.Gui.Attribute (ColorName.White, ColorName.Black),
-            Focus = new Terminal.Gui.Attribute (ColorName.Black,ColorName.White),
+            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)
@@ -67,7 +67,7 @@ public class TextEffectsScenario : Scenario
             DisplayText = "Gradients"
         };
 
-        tabView.AddTab (t1,false);
+        tabView.AddTab (t1, false);
 
         w.Add (tabView);
 
@@ -86,7 +86,7 @@ public class TextEffectsScenario : Scenario
         var g = new Gradient (stops, steps);
 
         var fore = new GradientFill (
-            new Rectangle (0, 0, size.Width, size.Height), g, Gradient.Direction.Diagonal);
+            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 (
@@ -107,7 +107,7 @@ public class TextEffectsScenario : Scenario
         };
 
         // Define the number of steps between each color for smoother transitions
-        steps = new List<int> { 15,15, 15, 15 };
+        steps = new List<int> { 15, 15, 15, 15 };
     }
 }
 
@@ -125,24 +125,25 @@ internal class GradientsView : View
 
         if (viewport.Height < 25) // Not enough space, render in a single line
         {
-            DrawGradientArea (Gradient.Direction.Horizontal, x, y);
-            DrawGradientArea (Gradient.Direction.Vertical, x + 32, y);
-            DrawGradientArea (Gradient.Direction.Radial, x + 64, y);
-            DrawGradientArea (Gradient.Direction.Diagonal, x + 96, y);
+            DrawGradientArea (GradientDirection.Horizontal, x, y);
+            DrawGradientArea (GradientDirection.Horizontal, x, y);
+            DrawGradientArea (GradientDirection.Vertical, x + 32, y);
+            DrawGradientArea (GradientDirection.Radial, x + 64, y);
+            DrawGradientArea (GradientDirection.Diagonal, x + 96, y);
         }
         else // Enough space, render in two lines
         {
-            DrawGradientArea (Gradient.Direction.Horizontal, x, y);
-            DrawGradientArea (Gradient.Direction.Vertical, x + 32, y);
-            DrawGradientArea (Gradient.Direction.Radial, x, y + 17);
-            DrawGradientArea (Gradient.Direction.Diagonal, x + 32, y + 17);
+            DrawGradientArea (GradientDirection.Horizontal, x, y);
+            DrawGradientArea (GradientDirection.Vertical, x + 32, y);
+            DrawGradientArea (GradientDirection.Radial, x, y + 17);
+            DrawGradientArea (GradientDirection.Diagonal, x + 32, y + 17);
         }
     }
 
 
 
 
-    private void DrawGradientArea (Gradient.Direction direction, int xOffset, int yOffset)
+    private void DrawGradientArea (GradientDirection direction, int xOffset, int yOffset)
     {
         // Define the colors of the gradient stops
         var stops = new List<Color>

+ 5 - 5
UnitTests/TextEffects/New/GradientFillTests.cs

@@ -25,13 +25,13 @@ public class GradientFillTests
     public void TestGradientFillCorners ()
     {
         var area = new Rectangle (0, 0, 10, 10);
-        var gradientFill = new GradientFill (area, _gradient, Gradient.Direction.Diagonal);
+        var gradientFill = new GradientFill (area, _gradient, GradientDirection.Diagonal);
 
         // Test the corners
         var topLeft = new Point (0, 0);
-        var topRight = new Point (area.Width - 1, 0);
-        var bottomLeft = new Point (0, area.Height - 1);
-        var bottomRight = new Point (area.Width - 1, area.Height - 1);
+        var topRight = new Point (area.Width, 0);
+        var bottomLeft = new Point (0, area.Height );
+        var bottomRight = new Point (area.Width, area.Height);
 
         var topLeftColor = gradientFill.GetColor (topLeft);
         var topRightColor = gradientFill.GetColor (topRight);
@@ -62,7 +62,7 @@ public class GradientFillTests
     public void TestGradientFillColorTransition ()
     {
         var area = new Rectangle (0, 0, 10, 10);
-        var gradientFill = new GradientFill (area, _gradient, Gradient.Direction.Diagonal);
+        var gradientFill = new GradientFill (area, _gradient, GradientDirection.Diagonal);
 
         for (int row = 0; row < area.Height; row++)
         {