|
@@ -11,10 +11,10 @@ namespace Terminal.Gui.Graphs {
|
|
/// </summary>
|
|
/// </summary>
|
|
public class LineCanvas {
|
|
public class LineCanvas {
|
|
|
|
|
|
-
|
|
|
|
|
|
+
|
|
private List<StraightLine> lines = new List<StraightLine> ();
|
|
private List<StraightLine> lines = new List<StraightLine> ();
|
|
|
|
|
|
- Dictionary<IntersectionRuneType, IntersectionRuneResolver> runeResolvers = new Dictionary<IntersectionRuneType, IntersectionRuneResolver> {
|
|
|
|
|
|
+ Dictionary<IntersectionRuneType, IntersectionRuneResolver> runeResolvers = new Dictionary<IntersectionRuneType, IntersectionRuneResolver> {
|
|
{IntersectionRuneType.ULCorner,new ULIntersectionRuneResolver()},
|
|
{IntersectionRuneType.ULCorner,new ULIntersectionRuneResolver()},
|
|
{IntersectionRuneType.URCorner,new URIntersectionRuneResolver()},
|
|
{IntersectionRuneType.URCorner,new URIntersectionRuneResolver()},
|
|
{IntersectionRuneType.LLCorner,new LLIntersectionRuneResolver()},
|
|
{IntersectionRuneType.LLCorner,new LLIntersectionRuneResolver()},
|
|
@@ -48,21 +48,22 @@ namespace Terminal.Gui.Graphs {
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// <summary>
|
|
/// Evaluate all currently defined lines that lie within
|
|
/// 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
|
|
/// shows what characters (if any) should be rendered at each
|
|
/// point so that all lines connect up correctly with appropriate
|
|
/// point so that all lines connect up correctly with appropriate
|
|
/// intersection symbols.
|
|
/// intersection symbols.
|
|
/// <returns></returns>
|
|
/// <returns></returns>
|
|
/// </summary>
|
|
/// </summary>
|
|
/// <param name="inArea"></param>
|
|
/// <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
|
|
// 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
|
|
var intersects = lines
|
|
.Select (l => l.Intersects (x, y))
|
|
.Select (l => l.Intersects (x, y))
|
|
@@ -70,45 +71,26 @@ namespace Terminal.Gui.Graphs {
|
|
.ToArray ();
|
|
.ToArray ();
|
|
|
|
|
|
// TODO: use Driver and LineStyle to map
|
|
// TODO: use Driver and LineStyle to map
|
|
- canvas [y, x] = GetRuneForIntersects (Application.Driver, intersects);
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return canvas;
|
|
|
|
- }
|
|
|
|
|
|
+ var rune = GetRuneForIntersects (Application.Driver, intersects);
|
|
|
|
|
|
- /// <summary>
|
|
|
|
- /// Draws all the lines that lie within the <paramref name="bounds"/> onto
|
|
|
|
- /// the <paramref name="view"/> client area. This method should be called from
|
|
|
|
- /// <see cref="View.Redraw(Rect)"/>.
|
|
|
|
- /// </summary>
|
|
|
|
- /// <param name="view"></param>
|
|
|
|
- /// <param name="bounds"></param>
|
|
|
|
- public void Draw (View view, Rect bounds)
|
|
|
|
- {
|
|
|
|
- var runes = GenerateImage (bounds);
|
|
|
|
-
|
|
|
|
- for (int y = bounds.Y; y < bounds.Height; y++) {
|
|
|
|
- for (int x = bounds.X; x < bounds.Width; x++) {
|
|
|
|
- var rune = runes [y, x];
|
|
|
|
-
|
|
|
|
- if (rune.HasValue) {
|
|
|
|
- view.AddRune (x, y, rune.Value);
|
|
|
|
|
|
+ if(rune != null)
|
|
|
|
+ {
|
|
|
|
+ map.Add(new Point(x,y),rune.Value);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ return map;
|
|
}
|
|
}
|
|
|
|
|
|
- private abstract class IntersectionRuneResolver
|
|
|
|
- {
|
|
|
|
|
|
+ private abstract class IntersectionRuneResolver {
|
|
readonly Rune round;
|
|
readonly Rune round;
|
|
readonly Rune doubleH;
|
|
readonly Rune doubleH;
|
|
readonly Rune doubleV;
|
|
readonly Rune doubleV;
|
|
readonly Rune doubleBoth;
|
|
readonly Rune doubleBoth;
|
|
readonly Rune normal;
|
|
readonly Rune normal;
|
|
|
|
|
|
- public IntersectionRuneResolver(Rune round, Rune doubleH, Rune doubleV, Rune doubleBoth, Rune normal)
|
|
|
|
|
|
+ public IntersectionRuneResolver (Rune round, Rune doubleH, Rune doubleV, Rune doubleBoth, Rune normal)
|
|
{
|
|
{
|
|
this.round = round;
|
|
this.round = round;
|
|
this.doubleH = doubleH;
|
|
this.doubleH = doubleH;
|
|
@@ -121,17 +103,15 @@ namespace Terminal.Gui.Graphs {
|
|
{
|
|
{
|
|
var useRounded = intersects.Any (i => i.Line.Style == BorderStyle.Rounded && i.Line.Length != 0);
|
|
var useRounded = intersects.Any (i => i.Line.Style == BorderStyle.Rounded && i.Line.Length != 0);
|
|
|
|
|
|
- bool doubleHorizontal = intersects.Any(l=>l.Line.Orientation == Orientation.Horizontal && l.Line.Style == BorderStyle.Double);
|
|
|
|
- bool doubleVertical = intersects.Any(l=>l.Line.Orientation == Orientation.Vertical && l.Line.Style == BorderStyle.Double);
|
|
|
|
|
|
+ bool doubleHorizontal = intersects.Any (l => l.Line.Orientation == Orientation.Horizontal && l.Line.Style == BorderStyle.Double);
|
|
|
|
+ bool doubleVertical = intersects.Any (l => l.Line.Orientation == Orientation.Vertical && l.Line.Style == BorderStyle.Double);
|
|
|
|
|
|
|
|
|
|
- if(doubleHorizontal)
|
|
|
|
- {
|
|
|
|
- return doubleVertical ? doubleBoth : doubleH;
|
|
|
|
|
|
+ if (doubleHorizontal) {
|
|
|
|
+ return doubleVertical ? doubleBoth : doubleH;
|
|
}
|
|
}
|
|
-
|
|
|
|
- if(doubleVertical)
|
|
|
|
- {
|
|
|
|
|
|
+
|
|
|
|
+ if (doubleVertical) {
|
|
return doubleV;
|
|
return doubleV;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -139,75 +119,71 @@ namespace Terminal.Gui.Graphs {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- private class ULIntersectionRuneResolver : IntersectionRuneResolver
|
|
|
|
- {
|
|
|
|
- public ULIntersectionRuneResolver() :
|
|
|
|
- base('╭','╒','╓','╔','┌')
|
|
|
|
|
|
+ private class ULIntersectionRuneResolver : IntersectionRuneResolver {
|
|
|
|
+ public ULIntersectionRuneResolver () :
|
|
|
|
+ base ('╭', '╒', '╓', '╔', '┌')
|
|
{
|
|
{
|
|
-
|
|
|
|
|
|
+
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- private class URIntersectionRuneResolver : IntersectionRuneResolver
|
|
|
|
- {
|
|
|
|
|
|
+ private class URIntersectionRuneResolver : IntersectionRuneResolver {
|
|
|
|
|
|
- public URIntersectionRuneResolver() :
|
|
|
|
- base('╮','╕','╖','╗','┐')
|
|
|
|
|
|
+ public URIntersectionRuneResolver () :
|
|
|
|
+ base ('╮', '╕', '╖', '╗', '┐')
|
|
{
|
|
{
|
|
-
|
|
|
|
|
|
+
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- private class LLIntersectionRuneResolver : IntersectionRuneResolver
|
|
|
|
- {
|
|
|
|
|
|
+ private class LLIntersectionRuneResolver : IntersectionRuneResolver {
|
|
|
|
|
|
- public LLIntersectionRuneResolver() :
|
|
|
|
- base('╰','╘','╙','╚','└')
|
|
|
|
|
|
+ public LLIntersectionRuneResolver () :
|
|
|
|
+ base ('╰', '╘', '╙', '╚', '└')
|
|
{
|
|
{
|
|
-
|
|
|
|
|
|
+
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- private class LRIntersectionRuneResolver : IntersectionRuneResolver
|
|
|
|
- {
|
|
|
|
- public LRIntersectionRuneResolver() :
|
|
|
|
- base('╯','╛','╜','╝','┘')
|
|
|
|
|
|
+ private class LRIntersectionRuneResolver : IntersectionRuneResolver {
|
|
|
|
+ public LRIntersectionRuneResolver () :
|
|
|
|
+ base ('╯', '╛', '╜', '╝', '┘')
|
|
{
|
|
{
|
|
-
|
|
|
|
|
|
+
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- private class TopTeeIntersectionRuneResolver : IntersectionRuneResolver
|
|
|
|
- {
|
|
|
|
- public TopTeeIntersectionRuneResolver():
|
|
|
|
- base('┬','╤','╥','╦','┬'){
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
|
|
+ private class TopTeeIntersectionRuneResolver : IntersectionRuneResolver {
|
|
|
|
+ public TopTeeIntersectionRuneResolver () :
|
|
|
|
+ base ('┬', '╤', '╥', '╦', '┬')
|
|
|
|
+ {
|
|
|
|
+
|
|
|
|
+ }
|
|
}
|
|
}
|
|
- private class LeftTeeIntersectionRuneResolver : IntersectionRuneResolver
|
|
|
|
- {
|
|
|
|
- public LeftTeeIntersectionRuneResolver():
|
|
|
|
- base('├','╞','╟','╠','├'){
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
|
|
+ private class LeftTeeIntersectionRuneResolver : IntersectionRuneResolver {
|
|
|
|
+ public LeftTeeIntersectionRuneResolver () :
|
|
|
|
+ base ('├', '╞', '╟', '╠', '├')
|
|
|
|
+ {
|
|
|
|
+
|
|
|
|
+ }
|
|
}
|
|
}
|
|
- private class RightTeeIntersectionRuneResolver : IntersectionRuneResolver
|
|
|
|
- {
|
|
|
|
- public RightTeeIntersectionRuneResolver():
|
|
|
|
- base('┤','╡','╢','╣','┤'){
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
|
|
+ private class RightTeeIntersectionRuneResolver : IntersectionRuneResolver {
|
|
|
|
+ public RightTeeIntersectionRuneResolver () :
|
|
|
|
+ base ('┤', '╡', '╢', '╣', '┤')
|
|
|
|
+ {
|
|
|
|
+
|
|
|
|
+ }
|
|
}
|
|
}
|
|
- private class BottomTeeIntersectionRuneResolver : IntersectionRuneResolver
|
|
|
|
- {
|
|
|
|
- public BottomTeeIntersectionRuneResolver():
|
|
|
|
- base('┴','╧','╨','╩','┴'){
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
|
|
+ private class BottomTeeIntersectionRuneResolver : IntersectionRuneResolver {
|
|
|
|
+ public BottomTeeIntersectionRuneResolver () :
|
|
|
|
+ base ('┴', '╧', '╨', '╩', '┴')
|
|
|
|
+ {
|
|
|
|
+
|
|
|
|
+ }
|
|
}
|
|
}
|
|
- private class CrosshairIntersectionRuneResolver : IntersectionRuneResolver
|
|
|
|
- {
|
|
|
|
- public CrosshairIntersectionRuneResolver():
|
|
|
|
- base('┼','╪','╫','╬','┼'){
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
|
|
+ private class CrosshairIntersectionRuneResolver : IntersectionRuneResolver {
|
|
|
|
+ public CrosshairIntersectionRuneResolver () :
|
|
|
|
+ base ('┼', '╪', '╫', '╬', '┼')
|
|
|
|
+ {
|
|
|
|
+
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
private Rune? GetRuneForIntersects (ConsoleDriver driver, IntersectionDefinition [] intersects)
|
|
private Rune? GetRuneForIntersects (ConsoleDriver driver, IntersectionDefinition [] intersects)
|
|
@@ -217,7 +193,7 @@ namespace Terminal.Gui.Graphs {
|
|
|
|
|
|
var runeType = GetRuneTypeForIntersects (intersects);
|
|
var runeType = GetRuneTypeForIntersects (intersects);
|
|
|
|
|
|
- if(runeResolvers.ContainsKey (runeType)) {
|
|
|
|
|
|
+ if (runeResolvers.ContainsKey (runeType)) {
|
|
return runeResolvers [runeType].GetRuneForIntersects (driver, intersects);
|
|
return runeResolvers [runeType].GetRuneForIntersects (driver, intersects);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -228,13 +204,13 @@ namespace Terminal.Gui.Graphs {
|
|
// TODO: maybe make these resolvers to for simplicity?
|
|
// TODO: maybe make these resolvers to for simplicity?
|
|
// or for dotted lines later on or that kind of thing?
|
|
// or for dotted lines later on or that kind of thing?
|
|
switch (runeType) {
|
|
switch (runeType) {
|
|
- case IntersectionRuneType.None:
|
|
|
|
|
|
+ case IntersectionRuneType.None:
|
|
return null;
|
|
return null;
|
|
- case IntersectionRuneType.Dot:
|
|
|
|
|
|
+ case IntersectionRuneType.Dot:
|
|
return (Rune)'.';
|
|
return (Rune)'.';
|
|
- case IntersectionRuneType.HLine:
|
|
|
|
|
|
+ case IntersectionRuneType.HLine:
|
|
return useDouble ? driver.HDLine : driver.HLine;
|
|
return useDouble ? driver.HDLine : driver.HLine;
|
|
- case IntersectionRuneType.VLine:
|
|
|
|
|
|
+ case IntersectionRuneType.VLine:
|
|
return useDouble ? driver.VDLine : driver.VLine;
|
|
return useDouble ? driver.VDLine : driver.VLine;
|
|
default: throw new Exception ("Could not find resolver or switch case for " + nameof (runeType) + ":" + runeType);
|
|
default: throw new Exception ("Could not find resolver or switch case for " + nameof (runeType) + ":" + runeType);
|
|
}
|
|
}
|
|
@@ -243,7 +219,7 @@ namespace Terminal.Gui.Graphs {
|
|
|
|
|
|
private IntersectionRuneType GetRuneTypeForIntersects (IntersectionDefinition [] intersects)
|
|
private IntersectionRuneType GetRuneTypeForIntersects (IntersectionDefinition [] intersects)
|
|
{
|
|
{
|
|
- if(intersects.All(i=>i.Line.Length == 0)) {
|
|
|
|
|
|
+ if (intersects.All (i => i.Line.Length == 0)) {
|
|
return IntersectionRuneType.Dot;
|
|
return IntersectionRuneType.Dot;
|
|
}
|
|
}
|
|
|
|
|