Browse Source

Adds Lineview (#1374)

* Added LineView

* Added tests for LineView constructor

* Fixed tests

* fix typo
Thomas Nind 4 years ago
parent
commit
02dfb2be2a
3 changed files with 253 additions and 0 deletions
  1. 106 0
      Terminal.Gui/Views/LineView.cs
  2. 107 0
      UICatalog/Scenarios/LineViewExample.cs
  3. 40 0
      UnitTests/LineViewTests.cs

+ 106 - 0
Terminal.Gui/Views/LineView.cs

@@ -0,0 +1,106 @@
+using System;
+using Terminal.Gui.Graphs;
+
+namespace Terminal.Gui.Views {
+	
+	/// <summary>
+	/// A straight line control either horizontal or vertical
+	/// </summary>
+	public class LineView : View {
+
+		/// <summary>
+		/// The rune to display at the start of the line (left end of horizontal line or top end of vertical)
+		/// If not specified then <see cref="LineRune"/> is used
+		/// </summary>
+		public Rune? StartingAnchor { get; set; }
+
+		/// <summary>
+		/// The rune to display at the end of the line (right end of horizontal line or bottom end of vertical).
+		/// If not specified then <see cref="LineRune"/> is used
+		/// </summary>
+		public Rune? EndingAnchor { get; set; }
+
+		/// <summary>
+		/// The symbol to use for drawing the line
+		/// </summary>
+		public Rune LineRune { get; set; }
+
+		/// <summary>
+		/// The direction of the line.  If you change this you will need to manually update the Width/Height
+		/// of the control to cover a relevant area based on the new direction.
+		/// </summary>
+		public Orientation Orientation { get; set; }
+
+		/// <summary>
+		/// Creates a horizontal line
+		/// </summary>
+		public LineView () : this(Orientation.Horizontal)
+		{
+
+		}
+
+		/// <summary>
+		/// Creates a horizontal or vertical line based on <paramref name="orientation"/>
+		/// </summary>
+		public LineView (Orientation orientation)
+		{
+			CanFocus = false;
+
+			switch (orientation) {
+			case Orientation.Horizontal:
+				Height = 1;
+				Width = Dim.Fill ();
+				LineRune = Driver.HLine;
+
+				break;
+			case Orientation.Vertical:
+				Height = Dim.Fill ();
+				Width = 1;
+				LineRune = Driver.VLine;
+				break;
+			default:
+				throw new ArgumentException ($"Unknown Orientation {orientation}");
+			}
+			Orientation = orientation;
+		}
+
+		/// <summary>
+		/// Draws the line including any starting/ending anchors
+		/// </summary>
+		/// <param name="bounds"></param>
+		public override void Redraw (Rect bounds)
+		{
+			base.Redraw (bounds);
+
+			Move (0, 0);
+			Driver.SetAttribute (ColorScheme.Normal);
+
+			var hLineWidth = Math.Max (1, Rune.ColumnWidth (Driver.HLine));
+
+			var dEnd = Orientation == Orientation.Horizontal ?
+				bounds.Width :
+				bounds.Height;
+
+			for (int d = 0; d < dEnd; d += hLineWidth) {
+				
+				if(Orientation == Orientation.Horizontal) {
+					Move (d, 0);
+				}
+				else {
+					Move (0,d);
+				}
+
+				Rune rune = LineRune;
+
+				if(d == 0) {
+					rune = StartingAnchor ?? LineRune;
+				} else
+				if (d == dEnd - 1) {
+					rune = EndingAnchor ?? LineRune;
+				}
+
+				Driver.AddRune (rune);
+			}
+		}
+	}
+}

+ 107 - 0
UICatalog/Scenarios/LineViewExample.cs

@@ -0,0 +1,107 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Terminal.Gui;
+using Terminal.Gui.Views;
+using static UICatalog.Scenario;
+
+namespace UICatalog.Scenarios {
+
+	[ScenarioMetadata (Name: "Line View", Description: "Demonstrates the LineView control")]
+	[ScenarioCategory ("Controls")]
+	class LineViewExample : Scenario {
+
+		public override void Setup ()
+		{
+			Win.Title = this.GetName ();
+			Win.Y = 1; // menu
+			Win.Height = Dim.Fill (1); // status bar
+			Top.LayoutSubviews ();
+
+			var menu = new MenuBar (new MenuBarItem [] {
+			new MenuBarItem ("_File", new MenuItem [] {
+				new MenuItem ("_Quit", "", () => Quit()),
+			})
+			});
+			Top.Add (menu);
+
+
+			Win.Add (new Label ("Regular Line") { Y = 0 });
+
+			// creates a horizontal line
+			var line = new LineView () {
+				Y = 1,
+			};
+
+			Win.Add (line);
+
+			Win.Add (new Label ("Double Width Line") { Y = 2 });
+
+			// creates a horizontal line
+			var doubleLine = new LineView () {
+				Y = 3,
+				LineRune = '\u2550'
+			};
+
+			Win.Add (doubleLine);
+
+			Win.Add (new Label ("Short Line") { Y = 4 });
+
+			// creates a horizontal line
+			var shortLine = new LineView () {
+				Y = 5,
+				Width = 10
+			};
+
+			Win.Add (shortLine);
+
+
+			Win.Add (new Label ("Arrow Line") { Y = 6 });
+
+			// creates a horizontal line
+			var arrowLine = new LineView () {
+				Y = 7,
+				Width = 10,
+				StartingAnchor = Application.Driver.LeftTee,
+				EndingAnchor = '>'
+			};
+
+			Win.Add (arrowLine);
+
+
+			Win.Add (new Label ("Vertical Line") { Y = 9,X=11 });
+
+			// creates a horizontal line
+			var verticalLine = new LineView (Terminal.Gui.Graphs.Orientation.Vertical) {
+				X = 25,
+			};
+
+			Win.Add (verticalLine);
+
+
+			Win.Add (new Label ("Vertical Arrow") { Y = 11, X = 28 });
+
+			// creates a horizontal line
+			var verticalArrow = new LineView (Terminal.Gui.Graphs.Orientation.Vertical) {
+				X = 27,
+				StartingAnchor = Application.Driver.TopTee,
+				EndingAnchor = 'V'
+			};
+
+			Win.Add (verticalArrow);
+
+			var statusBar = new StatusBar (new StatusItem [] {
+				new StatusItem(Key.CtrlMask | Key.Q, "~^Q~ Quit", () => Quit())
+			});
+			Top.Add (statusBar);
+
+		}
+
+		private void Quit ()
+		{
+			Application.RequestStop ();
+		}
+	}
+}

+ 40 - 0
UnitTests/LineViewTests.cs

@@ -0,0 +1,40 @@
+using Terminal.Gui;
+using Terminal.Gui.Graphs;
+using Terminal.Gui.Views;
+using Xunit;
+
+namespace UnitTests {
+	public class LineViewTests {
+
+		[Fact]
+		[AutoInitShutdown]
+		public void LineView_DefaultConstructor()
+		{
+			var horizontal = new LineView();
+
+			Assert.Equal (Orientation.Horizontal, horizontal.Orientation);
+			Assert.Equal (Dim.Fill (), horizontal.Width);
+			Assert.Equal (1, horizontal.Height);
+		}
+		[Fact]
+		[AutoInitShutdown]
+		public void LineView_Horizontal ()
+		{
+			var horizontal = new LineView (Orientation.Horizontal);
+
+			Assert.Equal (Orientation.Horizontal, horizontal.Orientation);
+			Assert.Equal (Dim.Fill (), horizontal.Width);
+			Assert.Equal (1, horizontal.Height);
+		}
+		[Fact]
+		[AutoInitShutdown]
+		public void LineView_Vertical ()
+		{
+			var vert = new LineView (Orientation.Vertical);
+
+			Assert.Equal (Orientation.Vertical, vert.Orientation);
+			Assert.Equal (Dim.Fill(), vert.Height);
+			Assert.Equal (1, vert.Width);
+		}
+	}
+}