LineDrawing.cs 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Reflection.Metadata.Ecma335;
  4. using Terminal.Gui;
  5. using Terminal.Gui.Graphs;
  6. namespace UICatalog.Scenarios {
  7. [ScenarioMetadata (Name: "Line Drawing", Description: "Demonstrates LineCanvas.")]
  8. [ScenarioCategory ("Controls")]
  9. [ScenarioCategory ("Layout")]
  10. public class LineDrawing : Scenario {
  11. public override void Setup ()
  12. {
  13. var toolsWidth = 8;
  14. var canvas = new DrawingArea {
  15. Width = Dim.Fill (-toolsWidth),
  16. Height = Dim.Fill ()
  17. };
  18. var tools = new ToolsView (toolsWidth) {
  19. Y = 1,
  20. X = Pos.AnchorEnd (toolsWidth + 1),
  21. Height = Dim.Fill (),
  22. Width = Dim.Fill ()
  23. };
  24. tools.ColorChanged += (c) => canvas.SetColor (c);
  25. tools.SetStyle += (b) => canvas.BorderStyle = b;
  26. Win.Add (canvas);
  27. Win.Add (tools);
  28. Win.Add (new Label (" -Tools-") { X = Pos.AnchorEnd (toolsWidth + 1) });
  29. }
  30. class ToolsView : View {
  31. LineCanvas grid;
  32. public event Action<Color> ColorChanged;
  33. public event Action<BorderStyle> SetStyle;
  34. Dictionary<Point, Color> swatches = new Dictionary<Point, Color> {
  35. { new Point(1,1),Color.Red},
  36. { new Point(3,1),Color.Green},
  37. { new Point(5,1),Color.BrightBlue},
  38. { new Point(7,1),Color.Black},
  39. { new Point(1,3),Color.White},
  40. };
  41. public ToolsView (int width)
  42. {
  43. grid = new LineCanvas ();
  44. grid.AddLine (new Point (0, 0), int.MaxValue, Orientation.Vertical, BorderStyle.Single);
  45. grid.AddLine (new Point (0, 0), width, Orientation.Horizontal, BorderStyle.Single);
  46. grid.AddLine (new Point (width, 0), int.MaxValue, Orientation.Vertical, BorderStyle.Single);
  47. grid.AddLine (new Point (0, 2), width, Orientation.Horizontal, BorderStyle.Single);
  48. grid.AddLine (new Point (2, 0), int.MaxValue, Orientation.Vertical, BorderStyle.Single);
  49. grid.AddLine (new Point (4, 0), int.MaxValue, Orientation.Vertical, BorderStyle.Single);
  50. grid.AddLine (new Point (6, 0), int.MaxValue, Orientation.Vertical, BorderStyle.Single);
  51. grid.AddLine (new Point (0, 4), width, Orientation.Horizontal, BorderStyle.Single);
  52. }
  53. public override void Redraw (Rect bounds)
  54. {
  55. base.Redraw (bounds);
  56. Driver.SetAttribute (new Terminal.Gui.Attribute (Color.DarkGray, ColorScheme.Normal.Background));
  57. grid.Draw (this, bounds);
  58. foreach (var swatch in swatches) {
  59. Driver.SetAttribute (new Terminal.Gui.Attribute (swatch.Value, ColorScheme.Normal.Background));
  60. AddRune (swatch.Key.X, swatch.Key.Y, '█');
  61. }
  62. Driver.SetAttribute (new Terminal.Gui.Attribute (ColorScheme.Normal.Foreground, ColorScheme.Normal.Background));
  63. AddRune (3, 3, Application.Driver.HDLine);
  64. AddRune (5, 3, Application.Driver.HLine);
  65. AddRune (7, 3, Application.Driver.ULRCorner);
  66. }
  67. public override bool OnMouseEvent (MouseEvent mouseEvent)
  68. {
  69. if (mouseEvent.Flags.HasFlag (MouseFlags.Button1Clicked)) {
  70. foreach (var swatch in swatches) {
  71. if (mouseEvent.X == swatch.Key.X && mouseEvent.Y == swatch.Key.Y) {
  72. ColorChanged?.Invoke (swatch.Value);
  73. return true;
  74. }
  75. }
  76. if (mouseEvent.X == 3 && mouseEvent.Y == 3) {
  77. SetStyle?.Invoke (BorderStyle.Double);
  78. return true;
  79. }
  80. if (mouseEvent.X == 5 && mouseEvent.Y == 3) {
  81. SetStyle?.Invoke (BorderStyle.Single);
  82. return true;
  83. }
  84. if (mouseEvent.X == 7 && mouseEvent.Y == 3) {
  85. SetStyle?.Invoke (BorderStyle.Rounded);
  86. return true;
  87. }
  88. }
  89. return base.OnMouseEvent (mouseEvent);
  90. }
  91. }
  92. class DrawingArea : View {
  93. /// <summary>
  94. /// Index into <see cref="canvases"/> by color.
  95. /// </summary>
  96. Dictionary<Color, int> colorLayers = new Dictionary<Color, int> ();
  97. List<LineCanvas> canvases = new List<LineCanvas> ();
  98. int currentColor;
  99. Point? currentLineStart = null;
  100. public BorderStyle BorderStyle { get; internal set; }
  101. public DrawingArea ()
  102. {
  103. AddCanvas (Color.White);
  104. }
  105. private void AddCanvas (Color c)
  106. {
  107. if (colorLayers.ContainsKey (c)) {
  108. return;
  109. }
  110. canvases.Add (new LineCanvas ());
  111. colorLayers.Add (c, canvases.Count - 1);
  112. currentColor = canvases.Count - 1;
  113. }
  114. public override void Redraw (Rect bounds)
  115. {
  116. base.Redraw (bounds);
  117. foreach (var kvp in colorLayers) {
  118. Driver.SetAttribute (new Terminal.Gui.Attribute (kvp.Key, ColorScheme.Normal.Background));
  119. canvases [kvp.Value].Draw (this, bounds);
  120. }
  121. }
  122. public override bool OnMouseEvent (MouseEvent mouseEvent)
  123. {
  124. if (mouseEvent.Flags.HasFlag (MouseFlags.Button1Pressed)) {
  125. if (currentLineStart == null) {
  126. currentLineStart = new Point (mouseEvent.X, mouseEvent.Y);
  127. }
  128. } else {
  129. if (currentLineStart != null) {
  130. var start = currentLineStart.Value;
  131. var end = new Point (mouseEvent.X, mouseEvent.Y);
  132. var orientation = Orientation.Vertical;
  133. var length = end.Y - start.Y;
  134. // if line is wider than it is tall switch to horizontal
  135. if (Math.Abs (start.X - end.X) > Math.Abs (start.Y - end.Y)) {
  136. orientation = Orientation.Horizontal;
  137. length = end.X - start.X;
  138. }
  139. canvases [currentColor].AddLine (
  140. start,
  141. length,
  142. orientation,
  143. BorderStyle);
  144. currentLineStart = null;
  145. SetNeedsDisplay ();
  146. }
  147. }
  148. return base.OnMouseEvent (mouseEvent);
  149. }
  150. internal void SetColor (Color c)
  151. {
  152. AddCanvas (c);
  153. currentColor = colorLayers [c];
  154. }
  155. }
  156. }
  157. }