From 85a44710048901399e1911d48732e33d0594e1a2 Mon Sep 17 00:00:00 2001 From: Thomas Date: Tue, 14 Feb 2023 22:11:18 +0000 Subject: [PATCH] Remove the Draw method from LineCanvas and make GenerateImage easier to use --- Terminal.Gui/Core/Graphs/LineCanvas.cs | 53 +++++++------------------ UICatalog/Scenarios/LineDrawing.cs | 15 ++++++- UnitTests/Core/LineCanvasTests.cs | 54 +++++--------------------- 3 files changed, 36 insertions(+), 86 deletions(-) diff --git a/Terminal.Gui/Core/Graphs/LineCanvas.cs b/Terminal.Gui/Core/Graphs/LineCanvas.cs index dcbf7f2a7..1b1cbe76b 100644 --- a/Terminal.Gui/Core/Graphs/LineCanvas.cs +++ b/Terminal.Gui/Core/Graphs/LineCanvas.cs @@ -48,64 +48,39 @@ namespace Terminal.Gui.Graphs { } /// /// Evaluate all currently defined lines that lie within - /// and generate a 'bitmap' that + /// and map that /// shows what characters (if any) should be rendered at each /// point so that all lines connect up correctly with appropriate /// intersection symbols. /// /// /// - /// Map as 2D array where first index is rows and second is column - public Rune? [,] GenerateImage (Rect inArea) + /// Mapping of all the points within to + /// line or intersection runes which should be drawn there. + public Dictionary GenerateImage (Rect inArea) { - Rune? [,] canvas = new Rune? [inArea.Height, inArea.Width]; + var map = new Dictionary(); // walk through each pixel of the bitmap - for (int y = 0; y < inArea.Height; y++) { - for (int x = 0; x < inArea.Width; x++) { + for (int y = inArea.Y; y < inArea.Height; y++) { + for (int x = inArea.X; x < inArea.Width; x++) { var intersects = lines - .Select (l => l.Intersects (inArea.X + x, inArea.Y + y)) + .Select (l => l.Intersects (x, y)) .Where (i => i != null) .ToArray (); // TODO: use Driver and LineStyle to map - canvas [y, x] = GetRuneForIntersects (Application.Driver, intersects); + var rune = GetRuneForIntersects (Application.Driver, intersects); - } - } - - return canvas; - } - - /// - /// Draws all the lines that lie within the onto - /// the client area at given . - /// This method should be called from - /// . - /// - /// - /// The area of the canvas to draw. - /// The point within the client area of - /// to draw at. - public void Draw (View view, Rect sourceRect, Point? drawOffset = null) - { - var offset = drawOffset ?? Point.Empty; - - var runes = GenerateImage (sourceRect); - - var runeRows = runes.GetLength (0); - var runeCols = runes.GetLength (1); - - for (int y = 0; y < runeRows; y++) { - for (int x = 0; x < runeCols; x++) { - var rune = runes [y, x]; - - if (rune.HasValue) { - view.AddRune (offset.X + x, offset.Y + y, rune.Value); + if(rune != null) + { + map.Add(new Point(x,y),rune.Value); } } } + + return map; } private abstract class IntersectionRuneResolver { diff --git a/UICatalog/Scenarios/LineDrawing.cs b/UICatalog/Scenarios/LineDrawing.cs index f3adac86d..f5670c0c4 100644 --- a/UICatalog/Scenarios/LineDrawing.cs +++ b/UICatalog/Scenarios/LineDrawing.cs @@ -71,7 +71,12 @@ namespace UICatalog.Scenarios { base.Redraw (bounds); Driver.SetAttribute (new Terminal.Gui.Attribute (Color.DarkGray, ColorScheme.Normal.Background)); - grid.Draw (this, bounds); + + + foreach(var p in grid.GenerateImage(bounds)) + { + this.AddRune(p.Key.X,p.Key.Y,p.Value); + } foreach (var swatch in swatches) { Driver.SetAttribute (new Terminal.Gui.Attribute (swatch.Value, ColorScheme.Normal.Background)); @@ -151,7 +156,13 @@ namespace UICatalog.Scenarios { foreach (var kvp in colorLayers) { Driver.SetAttribute (new Terminal.Gui.Attribute (kvp.Key, ColorScheme.Normal.Background)); - canvases [kvp.Value].Draw (this, bounds); + + var canvas = canvases [kvp.Value]; + + foreach(var p in canvas.GenerateImage(bounds)) + { + this.AddRune(p.Key.X,p.Key.Y,p.Value); + } } } public override bool OnMouseEvent (MouseEvent mouseEvent) diff --git a/UnitTests/Core/LineCanvasTests.cs b/UnitTests/Core/LineCanvasTests.cs index 77055ad54..65bc1f3a2 100644 --- a/UnitTests/Core/LineCanvasTests.cs +++ b/UnitTests/Core/LineCanvasTests.cs @@ -312,50 +312,6 @@ namespace Terminal.Gui.CoreTests { TestHelpers.AssertDriverContentsAre (looksLike, output); } - [Theory, AutoInitShutdown] - [InlineData (0, 0, @" -═══ -══ -═══")] - [InlineData (1, 0, @" -══ -═ -══")] - [InlineData (2, 0, @" -═ - -═")] - [InlineData (0, 1, @" -══ -═══")] - [InlineData (0, 2, @" -═══")] - public void TestLineCanvasRenderOffset_NoOffset (int xOffset, int yOffset, string expect) - { - var canvas = new LineCanvas (); - canvas.AddLine (new Point (0, 0), 2, Orientation.Horizontal, BorderStyle.Double); - canvas.AddLine (new Point (0, 1), 1, Orientation.Horizontal, BorderStyle.Double); - canvas.AddLine (new Point (0, 2), 2, Orientation.Horizontal, BorderStyle.Double); - - var bmp = canvas.GenerateImage (new Rect (xOffset, yOffset, 3, 3)); - var actual = BmpToString (bmp); - Assert.Equal (expect.TrimStart (), actual); - - } - - private string BmpToString (System.Rune? [,] bmp) - { - var sb = new StringBuilder (); - for (int y = 0; y < bmp.GetLength (1); y++) { - for (int x = 0; x < bmp.GetLength (0); x++) { - sb.Append (bmp [y, x]); - } - sb.AppendLine (); - } - - return sb.ToString ().TrimEnd (); - } - /// /// Creates a new into which a is rendered @@ -374,7 +330,15 @@ namespace Terminal.Gui.CoreTests { }; var canvasCopy = canvas = new LineCanvas (); - v.DrawContentComplete += (r) => canvasCopy.Draw (v, v.Bounds, new Point(offsetX,offsetY)); + v.DrawContentComplete += (r) => { + foreach(var p in canvasCopy.GenerateImage(v.Bounds)) + { + v.AddRune( + offsetX + p.Key.X, + offsetY + p.Key.Y, + p.Value); + } + }; return v; }