Remove the Draw method from LineCanvas and make GenerateImage easier to use

This commit is contained in:
Thomas
2023-02-14 22:11:18 +00:00
parent a10d4b78ec
commit 85a4471004
3 changed files with 36 additions and 86 deletions

View File

@@ -48,64 +48,39 @@ namespace Terminal.Gui.Graphs {
}
/// <summary>
/// Evaluate all currently defined lines that lie within
/// <paramref name="inArea"/> and generate a 'bitmap' that
/// <paramref name="inArea"/> 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.
/// <returns></returns>
/// </summary>
/// <param name="inArea"></param>
/// <returns>Map as 2D array where first index is rows and second is column</returns>
public Rune? [,] GenerateImage (Rect inArea)
/// <returns>Mapping of all the points within <paramref name="inArea"/> to
/// line or intersection runes which should be drawn there.</returns>
public Dictionary<Point,Rune> GenerateImage (Rect inArea)
{
Rune? [,] canvas = new Rune? [inArea.Height, inArea.Width];
var map = new Dictionary<Point,Rune>();
// 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;
}
/// <summary>
/// Draws all the lines that lie within the <paramref name="sourceRect"/> onto
/// the <paramref name="view"/> client area at given <paramref name="drawOffset"/>.
/// This method should be called from
/// <see cref="View.Redraw(Rect)"/>.
/// </summary>
/// <param name="view"></param>
/// <param name="sourceRect">The area of the canvas to draw.</param>
/// <param name="drawOffset">The point within the client area of
/// <paramref name="view"/> to draw at.</param>
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 {

View File

@@ -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)

View File

@@ -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 ();
}
/// <summary>
/// Creates a new <see cref="View"/> into which a <see cref="LineCanvas"/> 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;
}