View2.cs 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. using NStack;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.ComponentModel;
  5. using System.Xml.Linq;
  6. using Terminal.Gui.Graphs;
  7. namespace Terminal.Gui {
  8. public class Container : View
  9. {
  10. public Container ()
  11. {
  12. IgnoreBorderPropertyOnRedraw = true;
  13. }
  14. public virtual void OnDrawSubViews (Rect clipRect)
  15. {
  16. if (Subviews == null) {
  17. return;
  18. }
  19. foreach (var view in Subviews) {
  20. if (!view.NeedDisplay.IsEmpty || view.ChildNeedsDisplay || view.LayoutNeeded) {
  21. if (true) {//) && (view.Frame.IntersectsWith (boundsAdjustedForBorder) || boundsAdjustedForBorder.X < 0 || bounds.Y < 0)) {
  22. if (view.LayoutNeeded) {
  23. view.LayoutSubviews ();
  24. }
  25. // Draw the subview
  26. // Use the view's bounds (view-relative; Location will always be (0,0)
  27. if (view.Visible && view.Frame.Width > 0 && view.Frame.Height > 0) {
  28. var rect = view.Bounds;
  29. //view.OnDrawContent (rect);
  30. view.Redraw (rect);
  31. //view.OnDrawContentComplete (rect);
  32. }
  33. }
  34. view.NeedDisplay = Rect.Empty;
  35. view.ChildNeedsDisplay = false;
  36. }
  37. }
  38. }
  39. public override void OnDrawContent (Rect viewport)
  40. {
  41. if (!ustring.IsNullOrEmpty (TextFormatter.Text)) {
  42. Clear (viewport);
  43. SetChildNeedsDisplay ();
  44. // Draw any Text
  45. if (TextFormatter != null) {
  46. TextFormatter.NeedsFormat = true;
  47. }
  48. Rect containerBounds = GetContainerBounds ();
  49. TextFormatter?.Draw (ViewToScreen (viewport), HasFocus ? ColorScheme.Focus : GetNormalColor (),
  50. HasFocus ? ColorScheme.HotFocus : Enabled ? ColorScheme.HotNormal : ColorScheme.Disabled,
  51. containerBounds);
  52. }
  53. //base.OnDrawContent (viewport);
  54. }
  55. public override void OnDrawContentComplete (Rect viewport)
  56. {
  57. //base.OnDrawContentComplete (viewport);
  58. }
  59. public override void Redraw (Rect bounds)
  60. {
  61. if (!CanBeVisible (this)) {
  62. return;
  63. }
  64. if (ColorScheme != null) {
  65. Driver.SetAttribute (HasFocus ? ColorScheme.Focus : ColorScheme.Normal);
  66. }
  67. OnDrawContent (bounds);
  68. OnDrawSubViews (bounds);
  69. OnDrawContentComplete (bounds);
  70. }
  71. }
  72. public class Frame : Container {
  73. public Label DiagnosticsLabel { get; set; }
  74. public BorderStyle BorderStyle { get; set; } = BorderStyle.None;
  75. public Frame ()
  76. {
  77. IgnoreBorderPropertyOnRedraw = true;
  78. DiagnosticsLabel = new Label () {
  79. AutoSize = false,
  80. X = 0,
  81. Y = Pos.AnchorEnd (1),
  82. Width = Dim.Fill (),
  83. TextAlignment = TextAlignment.Centered
  84. };
  85. Add (DiagnosticsLabel);
  86. SetNeedsLayout ();
  87. }
  88. public Thickness Thickness { get; set; }
  89. public override void OnDrawContent (Rect viewport)
  90. {
  91. // do nothing
  92. }
  93. public override void Redraw (Rect bounds)
  94. {
  95. if (ColorScheme != null) {
  96. Driver.SetAttribute (HasFocus ? ColorScheme.Focus : ColorScheme.Normal);
  97. }
  98. if (Text != null) {
  99. Thickness?.Draw (Frame, $"{Text} {DiagnosticsLabel?.Text}");
  100. }
  101. if (BorderStyle != BorderStyle.None) {
  102. var lc = new LineCanvas ();
  103. lc.AddLine (Frame.Location, Frame.Width - 1, Orientation.Horizontal, BorderStyle);
  104. lc.AddLine (Frame.Location, Frame.Height - 1, Orientation.Vertical, BorderStyle);
  105. lc.AddLine (new Point (Frame.X, Frame.Y + Frame.Height - 1), Frame.Width - 1, Orientation.Horizontal, BorderStyle);
  106. lc.AddLine (new Point (Frame.X + Frame.Width - 1, Frame.Y), Frame.Height - 1, Orientation.Vertical, BorderStyle);
  107. foreach (var p in lc.GenerateImage(Frame)) {
  108. Driver.Move (p.Key.X, p.Key.Y);
  109. Driver.AddRune (p.Value);
  110. }
  111. Driver.DrawWindowTitle (Frame, $"{Text} {Thickness}", 0, 0, 0, 0);
  112. }
  113. base.Redraw (bounds);
  114. }
  115. }
  116. public class View2 : Container {
  117. public Frame Margin { get; set; }
  118. public new Frame Border { get; set; }
  119. public Frame Padding{ get; set; }
  120. public View2 ()
  121. {
  122. IgnoreBorderPropertyOnRedraw = true;
  123. Margin = new Frame () {
  124. Text = "Margin",
  125. Thickness = new Thickness (0),
  126. ColorScheme = Colors.ColorSchemes ["Error"]
  127. };
  128. //Margin.DiagnosticsLabel.Text = "Margin";
  129. Border = new Frame () {
  130. Text = "Border",
  131. BorderStyle = BorderStyle.Single,
  132. Thickness = new Thickness (1),
  133. ColorScheme = Colors.ColorSchemes ["Dialog"]
  134. };
  135. Padding = new Frame () {
  136. Text = "Padding",
  137. Thickness = new Thickness (0),
  138. ColorScheme = Colors.ColorSchemes ["Toplevel"]
  139. };
  140. SetNeedsLayout ();
  141. }
  142. string title;
  143. /// <summary>
  144. /// The title to be displayed for this <see cref="View2"/>.
  145. /// </summary>
  146. /// <value>The title.</value>
  147. public string Title {
  148. get => title;
  149. set {
  150. title = value;
  151. SetNeedsDisplay ();
  152. }
  153. }
  154. public override Rect Bounds {
  155. get {
  156. if (Padding == null || Border == null || Margin == null) {
  157. return Frame;
  158. }
  159. var frameRelativeBounds = Padding.Thickness.GetInnerRect(Border.Thickness.GetInnerRect (Margin.Thickness.GetInnerRect (new Rect(Point.Empty, Frame.Size))));
  160. return frameRelativeBounds;
  161. }
  162. set {
  163. throw new InvalidOperationException ("It makes no sense to explicitly set Bounds.");
  164. Frame = new Rect (Frame.Location, value.Size
  165. + new Size(Margin.Thickness.Right, Margin.Thickness.Bottom)
  166. + new Size (Border.Thickness.Right, Border.Thickness.Bottom)
  167. + new Size (Border.Thickness.Right, Border.Thickness.Bottom));
  168. }
  169. }
  170. public override void LayoutSubviews ()
  171. {
  172. Margin.X = Frame.Location.X;
  173. Margin.Y = Frame.Location.Y;
  174. Margin.Width = Frame.Size.Width;
  175. Margin.Height = Frame.Size.Height;
  176. Margin.SetNeedsLayout ();
  177. Margin.LayoutSubviews ();
  178. Margin.SetNeedsDisplay ();
  179. var border = Margin.Thickness.GetInnerRect (Frame);
  180. Border.X = border.Location.X;
  181. Border.Y = border.Location.Y;
  182. Border.Width = border.Size.Width;
  183. Border.Height = border.Size.Height;
  184. Border.SetNeedsLayout ();
  185. Border.LayoutSubviews ();
  186. Border.SetNeedsDisplay ();
  187. var padding = Border.Thickness.GetInnerRect (border);
  188. Padding.X = padding.Location.X;
  189. Padding.Y = padding.Location.Y;
  190. Padding.Width = padding.Size.Width;
  191. Padding.Height = padding.Size.Height;
  192. Padding.SetNeedsLayout ();
  193. Padding.LayoutSubviews ();
  194. Padding.SetNeedsDisplay ();
  195. //Bounds = Padding.Thickness.GetInnerRect (padding);
  196. base.LayoutSubviews ();
  197. }
  198. public virtual void OnDrawFrames (Rect frame)
  199. {
  200. Margin.Redraw (Margin.Bounds);
  201. Border.Redraw (Border.Bounds);
  202. Padding.Redraw (Border.Bounds);
  203. var border = Margin.Thickness.GetInnerRect (frame);
  204. var padding = Border.Thickness.GetInnerRect (border);
  205. var content = Padding.Thickness.GetInnerRect (padding);
  206. // Draw the diagnostics label on the bottom of the content
  207. var tf = new TextFormatter () {
  208. Text = $"Content {Bounds}",
  209. Alignment = TextAlignment.Centered,
  210. VerticalAlignment = VerticalTextAlignment.Bottom
  211. };
  212. tf.Draw (content, ColorScheme.Normal, ColorScheme.Normal);
  213. }
  214. public override void Redraw (Rect bounds)
  215. {
  216. if (!CanBeVisible (this)) {
  217. return;
  218. }
  219. if (ColorScheme != null) {
  220. Driver.SetAttribute (HasFocus ? ColorScheme.Focus : ColorScheme.Normal);
  221. }
  222. OnDrawFrames (Frame);
  223. base.Redraw (bounds);
  224. }
  225. protected override void Dispose (bool disposing)
  226. {
  227. base.Dispose (disposing);
  228. Margin?.Dispose ();
  229. Margin = null;
  230. Border?.Dispose ();
  231. Border = null;
  232. Padding?.Dispose ();
  233. Padding = null;
  234. }
  235. }
  236. }