Drawing.cs 5.4 KB

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