using NStack;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Xml.Linq;
using Terminal.Gui.Graphs;
namespace Terminal.Gui {
public class Container : View
{
public Container ()
{
IgnoreBorderPropertyOnRedraw = true;
}
public virtual void OnDrawSubViews (Rect clipRect)
{
if (Subviews == null) {
return;
}
foreach (var view in Subviews) {
if (!view.NeedDisplay.IsEmpty || view.ChildNeedsDisplay || view.LayoutNeeded) {
if (true) {//) && (view.Frame.IntersectsWith (boundsAdjustedForBorder) || boundsAdjustedForBorder.X < 0 || bounds.Y < 0)) {
if (view.LayoutNeeded) {
view.LayoutSubviews ();
}
// Draw the subview
// Use the view's bounds (view-relative; Location will always be (0,0)
if (view.Visible && view.Frame.Width > 0 && view.Frame.Height > 0) {
var rect = view.Bounds;
//view.OnDrawContent (rect);
view.Redraw (rect);
//view.OnDrawContentComplete (rect);
}
}
view.NeedDisplay = Rect.Empty;
view.ChildNeedsDisplay = false;
}
}
}
public override void OnDrawContent (Rect viewport)
{
if (!ustring.IsNullOrEmpty (TextFormatter.Text)) {
Clear (viewport);
SetChildNeedsDisplay ();
// Draw any Text
if (TextFormatter != null) {
TextFormatter.NeedsFormat = true;
}
Rect containerBounds = GetContainerBounds ();
TextFormatter?.Draw (ViewToScreen (viewport), HasFocus ? ColorScheme.Focus : GetNormalColor (),
HasFocus ? ColorScheme.HotFocus : Enabled ? ColorScheme.HotNormal : ColorScheme.Disabled,
containerBounds);
}
//base.OnDrawContent (viewport);
}
public override void OnDrawContentComplete (Rect viewport)
{
//base.OnDrawContentComplete (viewport);
}
public override void Redraw (Rect bounds)
{
if (!CanBeVisible (this)) {
return;
}
if (ColorScheme != null) {
Driver.SetAttribute (HasFocus ? ColorScheme.Focus : ColorScheme.Normal);
}
OnDrawContent (bounds);
OnDrawSubViews (bounds);
OnDrawContentComplete (bounds);
}
}
public class Frame : Container {
public Label DiagnosticsLabel { get; set; }
public BorderStyle BorderStyle { get; set; } = BorderStyle.None;
public Frame ()
{
IgnoreBorderPropertyOnRedraw = true;
DiagnosticsLabel = new Label () {
AutoSize = false,
X = 0,
Y = Pos.AnchorEnd (1),
Width = Dim.Fill (),
TextAlignment = TextAlignment.Centered
};
Add (DiagnosticsLabel);
SetNeedsLayout ();
}
public Thickness Thickness { get; set; }
public override void OnDrawContent (Rect viewport)
{
// do nothing
}
public override void Redraw (Rect bounds)
{
if (ColorScheme != null) {
Driver.SetAttribute (HasFocus ? ColorScheme.Focus : ColorScheme.Normal);
}
if (Text != null) {
Thickness?.Draw (Frame, $"{Text} {DiagnosticsLabel?.Text}");
}
if (BorderStyle != BorderStyle.None) {
var lc = new LineCanvas ();
lc.AddLine (Frame.Location, Frame.Width - 1, Orientation.Horizontal, BorderStyle);
lc.AddLine (Frame.Location, Frame.Height - 1, Orientation.Vertical, BorderStyle);
lc.AddLine (new Point (Frame.X, Frame.Y + Frame.Height - 1), Frame.Width - 1, Orientation.Horizontal, BorderStyle);
lc.AddLine (new Point (Frame.X + Frame.Width - 1, Frame.Y), Frame.Height - 1, Orientation.Vertical, BorderStyle);
lc.Draw (this, Frame);
Driver.DrawWindowTitle (Frame, $"{Text} {Thickness}", 0, 0, 0, 0);
}
base.Redraw (bounds);
}
}
public class View2 : Container {
public Frame Margin { get; set; }
public new Frame Border { get; set; }
public Frame Padding{ get; set; }
public View2 ()
{
IgnoreBorderPropertyOnRedraw = true;
Margin = new Frame () {
Text = "Margin",
Thickness = new Thickness (0),
ColorScheme = Colors.ColorSchemes ["Error"]
};
//Margin.DiagnosticsLabel.Text = "Margin";
Border = new Frame () {
Text = "Border",
BorderStyle = BorderStyle.Single,
Thickness = new Thickness (1),
ColorScheme = Colors.ColorSchemes ["Dialog"]
};
Padding = new Frame () {
Text = "Padding",
Thickness = new Thickness (0),
ColorScheme = Colors.ColorSchemes ["Toplevel"]
};
SetNeedsLayout ();
}
string title;
///
/// The title to be displayed for this .
///
/// The title.
public string Title {
get => title;
set {
title = value;
SetNeedsDisplay ();
}
}
public override Rect Bounds {
get {
if (Padding == null || Border == null || Margin == null) {
return Frame;
}
var frameRelativeBounds = Padding.Thickness.GetInnerRect(Border.Thickness.GetInnerRect (Margin.Thickness.GetInnerRect (new Rect(Point.Empty, Frame.Size))));
return frameRelativeBounds;
}
set {
throw new InvalidOperationException ("It makes no sense to explicitly set Bounds.");
Frame = new Rect (Frame.Location, value.Size
+ new Size(Margin.Thickness.Right, Margin.Thickness.Bottom)
+ new Size (Border.Thickness.Right, Border.Thickness.Bottom)
+ new Size (Border.Thickness.Right, Border.Thickness.Bottom));
}
}
public override void LayoutSubviews ()
{
Margin.X = Frame.Location.X;
Margin.Y = Frame.Location.Y;
Margin.Width = Frame.Size.Width;
Margin.Height = Frame.Size.Height;
Margin.SetNeedsLayout ();
Margin.LayoutSubviews ();
Margin.SetNeedsDisplay ();
var border = Margin.Thickness.GetInnerRect (Frame);
Border.X = border.Location.X;
Border.Y = border.Location.Y;
Border.Width = border.Size.Width;
Border.Height = border.Size.Height;
Border.SetNeedsLayout ();
Border.LayoutSubviews ();
Border.SetNeedsDisplay ();
var padding = Border.Thickness.GetInnerRect (border);
Padding.X = padding.Location.X;
Padding.Y = padding.Location.Y;
Padding.Width = padding.Size.Width;
Padding.Height = padding.Size.Height;
Padding.SetNeedsLayout ();
Padding.LayoutSubviews ();
Padding.SetNeedsDisplay ();
//Bounds = Padding.Thickness.GetInnerRect (padding);
base.LayoutSubviews ();
}
public virtual void OnDrawFrames (Rect frame)
{
Margin.Redraw (Margin.Bounds);
Border.Redraw (Border.Bounds);
Padding.Redraw (Border.Bounds);
var border = Margin.Thickness.GetInnerRect (frame);
var padding = Border.Thickness.GetInnerRect (border);
var content = Padding.Thickness.GetInnerRect (padding);
// Draw the diagnostics label on the bottom of the content
var tf = new TextFormatter () {
Text = $"Content {Bounds}",
Alignment = TextAlignment.Centered,
VerticalAlignment = VerticalTextAlignment.Bottom
};
tf.Draw (content, ColorScheme.Normal, ColorScheme.Normal);
}
public override void Redraw (Rect bounds)
{
if (!CanBeVisible (this)) {
return;
}
if (ColorScheme != null) {
Driver.SetAttribute (HasFocus ? ColorScheme.Focus : ColorScheme.Normal);
}
OnDrawFrames (Frame);
base.Redraw (bounds);
}
protected override void Dispose (bool disposing)
{
base.Dispose (disposing);
Margin?.Dispose ();
Margin = null;
Border?.Dispose ();
Border = null;
Padding?.Dispose ();
Padding = null;
}
}
}