LineDrawing.cs 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  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. foreach(var p in grid.GenerateImage(bounds))
  58. {
  59. this.AddRune(p.Key.X,p.Key.Y,p.Value);
  60. }
  61. foreach (var swatch in swatches) {
  62. Driver.SetAttribute (new Terminal.Gui.Attribute (swatch.Value, ColorScheme.Normal.Background));
  63. AddRune (swatch.Key.X, swatch.Key.Y, '█');
  64. }
  65. Driver.SetAttribute (new Terminal.Gui.Attribute (ColorScheme.Normal.Foreground, ColorScheme.Normal.Background));
  66. AddRune (3, 3, Application.Driver.HDLine);
  67. AddRune (5, 3, Application.Driver.HLine);
  68. AddRune (7, 3, Application.Driver.ULRCorner);
  69. }
  70. public override bool OnMouseEvent (MouseEvent mouseEvent)
  71. {
  72. if (mouseEvent.Flags.HasFlag (MouseFlags.Button1Clicked)) {
  73. foreach (var swatch in swatches) {
  74. if (mouseEvent.X == swatch.Key.X && mouseEvent.Y == swatch.Key.Y) {
  75. ColorChanged?.Invoke (swatch.Value);
  76. return true;
  77. }
  78. }
  79. if (mouseEvent.X == 3 && mouseEvent.Y == 3) {
  80. SetStyle?.Invoke (BorderStyle.Double);
  81. return true;
  82. }
  83. if (mouseEvent.X == 5 && mouseEvent.Y == 3) {
  84. SetStyle?.Invoke (BorderStyle.Single);
  85. return true;
  86. }
  87. if (mouseEvent.X == 7 && mouseEvent.Y == 3) {
  88. SetStyle?.Invoke (BorderStyle.Rounded);
  89. return true;
  90. }
  91. }
  92. return base.OnMouseEvent (mouseEvent);
  93. }
  94. }
  95. class DrawingArea : View {
  96. /// <summary>
  97. /// Index into <see cref="canvases"/> by color.
  98. /// </summary>
  99. Dictionary<Color, int> colorLayers = new Dictionary<Color, int> ();
  100. List<LineCanvas> canvases = new List<LineCanvas> ();
  101. int currentColor;
  102. Point? currentLineStart = null;
  103. public BorderStyle BorderStyle { get; internal set; }
  104. public DrawingArea ()
  105. {
  106. AddCanvas (Color.White);
  107. }
  108. private void AddCanvas (Color c)
  109. {
  110. if (colorLayers.ContainsKey (c)) {
  111. return;
  112. }
  113. canvases.Add (new LineCanvas ());
  114. colorLayers.Add (c, canvases.Count - 1);
  115. currentColor = canvases.Count - 1;
  116. }
  117. public override void Redraw (Rect bounds)
  118. {
  119. base.Redraw (bounds);
  120. foreach (var kvp in colorLayers) {
  121. Driver.SetAttribute (new Terminal.Gui.Attribute (kvp.Key, ColorScheme.Normal.Background));
  122. var canvas = canvases [kvp.Value];
  123. foreach(var p in canvas.GenerateImage(bounds))
  124. {
  125. this.AddRune(p.Key.X,p.Key.Y,p.Value);
  126. }
  127. }
  128. }
  129. public override bool OnMouseEvent (MouseEvent mouseEvent)
  130. {
  131. if (mouseEvent.Flags.HasFlag (MouseFlags.Button1Pressed)) {
  132. if (currentLineStart == null) {
  133. currentLineStart = new Point (mouseEvent.X, mouseEvent.Y);
  134. }
  135. } else {
  136. if (currentLineStart != null) {
  137. var start = currentLineStart.Value;
  138. var end = new Point (mouseEvent.X, mouseEvent.Y);
  139. var orientation = Orientation.Vertical;
  140. var length = end.Y - start.Y;
  141. // if line is wider than it is tall switch to horizontal
  142. if (Math.Abs (start.X - end.X) > Math.Abs (start.Y - end.Y)) {
  143. orientation = Orientation.Horizontal;
  144. length = end.X - start.X;
  145. }
  146. canvases [currentColor].AddLine (
  147. start,
  148. length,
  149. orientation,
  150. BorderStyle);
  151. currentLineStart = null;
  152. SetNeedsDisplay ();
  153. }
  154. }
  155. return base.OnMouseEvent (mouseEvent);
  156. }
  157. internal void SetColor (Color c)
  158. {
  159. AddCanvas (c);
  160. currentColor = colorLayers [c];
  161. }
  162. }
  163. }
  164. }