View2.cs 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  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. lc.Draw (this, Frame);
  108. Driver.DrawWindowTitle (Frame, $"{Text} {Thickness}", 0, 0, 0, 0);
  109. }
  110. base.Redraw (bounds);
  111. }
  112. }
  113. public class View2 : Container {
  114. public Frame Margin { get; set; }
  115. public new Frame Border { get; set; }
  116. public Frame Padding{ get; set; }
  117. public View2 ()
  118. {
  119. IgnoreBorderPropertyOnRedraw = true;
  120. Margin = new Frame () {
  121. Text = "Margin",
  122. Thickness = new Thickness (0),
  123. ColorScheme = Colors.ColorSchemes ["Error"]
  124. };
  125. //Margin.DiagnosticsLabel.Text = "Margin";
  126. Border = new Frame () {
  127. Text = "Border",
  128. BorderStyle = BorderStyle.Single,
  129. Thickness = new Thickness (1),
  130. ColorScheme = Colors.ColorSchemes ["Dialog"]
  131. };
  132. Padding = new Frame () {
  133. Text = "Padding",
  134. Thickness = new Thickness (0),
  135. ColorScheme = Colors.ColorSchemes ["Toplevel"]
  136. };
  137. SetNeedsLayout ();
  138. }
  139. string title;
  140. /// <summary>
  141. /// The title to be displayed for this <see cref="View2"/>.
  142. /// </summary>
  143. /// <value>The title.</value>
  144. public string Title {
  145. get => title;
  146. set {
  147. title = value;
  148. SetNeedsDisplay ();
  149. }
  150. }
  151. public override Rect Bounds {
  152. get {
  153. if (Padding == null || Border == null || Margin == null) {
  154. return Frame;
  155. }
  156. var frameRelativeBounds = Padding.Thickness.GetInnerRect(Border.Thickness.GetInnerRect (Margin.Thickness.GetInnerRect (new Rect(Point.Empty, Frame.Size))));
  157. return frameRelativeBounds;
  158. }
  159. set {
  160. throw new InvalidOperationException ("It makes no sense to explicitly set Bounds.");
  161. Frame = new Rect (Frame.Location, value.Size
  162. + new Size(Margin.Thickness.Right, Margin.Thickness.Bottom)
  163. + new Size (Border.Thickness.Right, Border.Thickness.Bottom)
  164. + new Size (Border.Thickness.Right, Border.Thickness.Bottom));
  165. }
  166. }
  167. public override void LayoutSubviews ()
  168. {
  169. Margin.X = Frame.Location.X;
  170. Margin.Y = Frame.Location.Y;
  171. Margin.Width = Frame.Size.Width;
  172. Margin.Height = Frame.Size.Height;
  173. Margin.SetNeedsLayout ();
  174. Margin.LayoutSubviews ();
  175. Margin.SetNeedsDisplay ();
  176. var border = Margin.Thickness.GetInnerRect (Frame);
  177. Border.X = border.Location.X;
  178. Border.Y = border.Location.Y;
  179. Border.Width = border.Size.Width;
  180. Border.Height = border.Size.Height;
  181. Border.SetNeedsLayout ();
  182. Border.LayoutSubviews ();
  183. Border.SetNeedsDisplay ();
  184. var padding = Border.Thickness.GetInnerRect (border);
  185. Padding.X = padding.Location.X;
  186. Padding.Y = padding.Location.Y;
  187. Padding.Width = padding.Size.Width;
  188. Padding.Height = padding.Size.Height;
  189. Padding.SetNeedsLayout ();
  190. Padding.LayoutSubviews ();
  191. Padding.SetNeedsDisplay ();
  192. //Bounds = Padding.Thickness.GetInnerRect (padding);
  193. base.LayoutSubviews ();
  194. }
  195. public virtual void OnDrawFrames (Rect frame)
  196. {
  197. Margin.Redraw (Margin.Bounds);
  198. Border.Redraw (Border.Bounds);
  199. Padding.Redraw (Border.Bounds);
  200. var border = Margin.Thickness.GetInnerRect (frame);
  201. var padding = Border.Thickness.GetInnerRect (border);
  202. var content = Padding.Thickness.GetInnerRect (padding);
  203. // Draw the diagnostics label on the bottom of the content
  204. var tf = new TextFormatter () {
  205. Text = $"Content {Bounds}",
  206. Alignment = TextAlignment.Centered,
  207. VerticalAlignment = VerticalTextAlignment.Bottom
  208. };
  209. tf.Draw (content, ColorScheme.Normal, ColorScheme.Normal);
  210. }
  211. public override void Redraw (Rect bounds)
  212. {
  213. if (!CanBeVisible (this)) {
  214. return;
  215. }
  216. if (ColorScheme != null) {
  217. Driver.SetAttribute (HasFocus ? ColorScheme.Focus : ColorScheme.Normal);
  218. }
  219. OnDrawFrames (Frame);
  220. base.Redraw (bounds);
  221. }
  222. protected override void Dispose (bool disposing)
  223. {
  224. base.Dispose (disposing);
  225. Margin?.Dispose ();
  226. Margin = null;
  227. Border?.Dispose ();
  228. Border = null;
  229. Padding?.Dispose ();
  230. Padding = null;
  231. }
  232. }
  233. }