using NStack;
using System;
using System.Collections.Generic;
using Terminal.Gui.Graphs;
using System.Text.Json.Serialization;
namespace Terminal.Gui {
///
/// Specifies the border style for a and to be used by the class.
///
public enum BorderStyle {
///
/// No border is drawn.
///
None,
///
/// The border is drawn with a single line limits.
///
Single,
///
/// The border is drawn with a double line limits.
///
Double,
///
/// The border is drawn with a single line and rounded corners limits.
///
Rounded
}
///
/// Describes the thickness of a frame around a rectangle. Four values describe
/// the , , , and sides
/// of the rectangle, respectively.
///
public class Thickness : IEquatable {
private int validate (int width)
{
if (width < 0) {
throw new ArgumentException ("Thickness widths cannot be negative.");
}
return width;
}
///
/// Gets or sets the width of the left side of the rectangle.
///
[JsonInclude]
public int Left;
///
/// Gets or sets the width of the upper side of the rectangle.
///
[JsonInclude]
public int Top;
///
/// Gets or sets the width of the right side of the rectangle.
///
[JsonInclude]
public int Right;
///
/// Gets or sets the width of the lower side of the rectangle.
///
[JsonInclude]
public int Bottom;
///
/// Initializes a new instance of the class with all widths
/// set to 0.
///
public Thickness () { }
///
/// Initializes a new instance of the class with a uniform width to each side.
///
///
public Thickness (int width) : this (width, width, width, width) { }
///
/// Initializes a new instance of the class that has specific
/// widths applied to each side of the rectangle.
///
///
///
///
///
public Thickness (int left, int top, int right, int bottom)
{
Left = left;
Top = top;
Right = right;
Bottom = bottom;
}
///
/// Returns a rectangle describing the location and size of the inner area of
/// with the thickness widths subracted. The height and width of the retunred rect may be zero.
///
/// The source rectangle
///
public Rect GetInnerRect (Rect rect)
{
var width = rect.Size.Width - (Left + Right);
var height = rect.Size.Height - (Top + Bottom);
var size = new Size (Math.Max (0, width), Math.Max (0, height));
return new Rect (new Point (rect.X + Left, rect.Y + Top), size);
}
///
/// Draws the thickness rectangle with an optional diagnostics label.
///
/// The location and size of the rectangle that bounds the thickness rectangle, in
/// screen coordinates.
/// The diagnostics label to draw on the bottom of the .
/// The inner rectangle remaining to be drawn.
public Rect Draw (Rect rect, string label = null)
{
// Draw the Top side
for (var r = rect.Y; r < Math.Min (rect.Y + rect.Height, rect.Y + Top); r++) {
for (var c = rect.X; c < rect.X + rect.Width; c++) {
Application.Driver.Move (c, r);
Application.Driver.AddRune (' ');
}
}
// Draw the Left side
for (var r = rect.Y; r < rect.Y + rect.Height; r++) {
for (var c = rect.X; c < Math.Min (rect.X + rect.Width, rect.X + Left); c++) {
Application.Driver.Move (c, r);
Application.Driver.AddRune (' ');
}
}
// Draw the Right side
for (var r = rect.Y; r < rect.Y + rect.Height; r++) {
for (var c = rect.X + Math.Max (0, rect.Width - Right); c < rect.X + rect.Width; c++) {
Application.Driver.Move (c, r);
Application.Driver.AddRune (' ');
}
}
// Draw the Bottom side
for (var r = rect.Y + Math.Max (0, rect.Height - Bottom); r < rect.Y + rect.Height; r++) {
for (var c = rect.X; c < rect.X + rect.Width; c++) {
Application.Driver.Move (c, r);
Application.Driver.AddRune (' ');
}
}
// Draw the diagnostics label on the bottom
var tf = new TextFormatter () {
Text = label == null ? string.Empty : $"{label} {this}",
Alignment = TextAlignment.Centered,
VerticalAlignment = VerticalTextAlignment.Bottom
};
tf.Draw (rect, Application.Driver.CurrentAttribute, Application.Driver.CurrentAttribute);
return GetInnerRect (rect);
}
// TODO: add operator overloads
///
/// Gets an empty thickness.
///
public static Thickness Empty => new Thickness (0);
public override bool Equals (object obj)
{
//Check for null and compare run-time types.
if ((obj == null) || !this.GetType ().Equals (obj.GetType ())) {
return false;
} else {
return Equals ((Thickness)obj);
}
}
/// Returns the thickness widths of the Thickness formatted as a string.
/// The thickness widths as a string.
public override string ToString ()
{
return $"(Left={Left},Top={Top},Right={Right},Bottom={Bottom})";
}
// IEquitable
public bool Equals (Thickness other)
{
return other is not null &&
Left == other.Left &&
Right == other.Right &&
Top == other.Top &&
Bottom == other.Bottom;
}
public override int GetHashCode ()
{
int hashCode = 1380952125;
hashCode = hashCode * -1521134295 + Left.GetHashCode ();
hashCode = hashCode * -1521134295 + Right.GetHashCode ();
hashCode = hashCode * -1521134295 + Top.GetHashCode ();
hashCode = hashCode * -1521134295 + Bottom.GetHashCode ();
return hashCode;
}
public static bool operator == (Thickness left, Thickness right)
{
return EqualityComparer.Default.Equals (left, right);
}
public static bool operator != (Thickness left, Thickness right)
{
return !(left == right);
}
}
///
/// Draws a border, background, or both around another element.
///
public class Border {
private int marginFrame => DrawMarginFrame ? 1 : 0;
/////
///// A sealed derived class to implement feature.
///// This is only a wrapper to get borders on a toplevel and is recommended using another
///// derived, like where is possible to have borders with or without
///// border line or spacing around.
/////
//public sealed class ToplevelContainer : Toplevel {
// ///
// public override Border Border {
// get => base.Border;
// set {
// if (base.Border != null && base.Border.Child != null && value.Child == null) {
// value.Child = base.Border.Child;
// }
// base.Border = value;
// if (value == null) {
// return;
// }
// Rect frame;
// if (Border.Child != null && (Border.Child.Width is Dim || Border.Child.Height is Dim)) {
// frame = Rect.Empty;
// } else {
// frame = Frame;
// }
// AdjustContentView (frame);
// Border.BorderChanged += Border_BorderChanged;
// }
// }
// void Border_BorderChanged (Border border)
// {
// Rect frame;
// if (Border.Child != null && (Border.Child.Width is Dim || Border.Child.Height is Dim)) {
// frame = Rect.Empty;
// } else {
// frame = Frame;
// }
// AdjustContentView (frame);
// }
// ///
// /// Initializes with default null values.
// ///
// public ToplevelContainer () : this (null, string.Empty) { }
// ///
// /// Initializes a with a
// ///
// /// The border.
// /// The title.
// public ToplevelContainer (Border border, string title = null)
// {
// Initialize (Rect.Empty, border, title ?? string.Empty);
// }
// ///
// /// Initializes a with a
// ///
// /// The frame.
// /// The border.
// /// The title.
// public ToplevelContainer (Rect frame, Border border, string title = null) : base (frame)
// {
// Initialize (frame, border, title ?? string.Empty);
// }
// private void Initialize (Rect frame, Border border, string title)
// {
// ColorScheme = Colors.TopLevel;
// if (border == null) {
// Border = new Border () {
// BorderStyle = BorderStyle.Single,
// BorderBrush = ColorScheme.Normal.Background,
// Title = (ustring)title
// };
// } else {
// Border = border;
// }
// AdjustContentView (frame);
// }
// void AdjustContentView (Rect frame)
// {
// var borderLength = Border.DrawMarginFrame ? 1 : 0;
// var sumPadding = Border.GetSumThickness ();
// var wp = new Point ();
// var wb = new Size ();
// if (frame == Rect.Empty) {
// wp.X = borderLength + sumPadding.Left;
// wp.Y = borderLength + sumPadding.Top;
// wb.Width = borderLength + sumPadding.Right;
// wb.Height = borderLength + sumPadding.Bottom;
// if (Border.Child == null) {
// Border.Child = new ChildContentView (this) {
// X = wp.X,
// Y = wp.Y,
// Width = Dim.Fill (wb.Width),
// Height = Dim.Fill (wb.Height)
// };
// } else {
// Border.Child.X = wp.X;
// Border.Child.Y = wp.Y;
// Border.Child.Width = Dim.Fill (wb.Width);
// Border.Child.Height = Dim.Fill (wb.Height);
// }
// } else {
// wb.Width = (2 * borderLength) + sumPadding.Right + sumPadding.Left;
// wb.Height = (2 * borderLength) + sumPadding.Bottom + sumPadding.Top;
// var cFrame = new Rect (borderLength + sumPadding.Left, borderLength + sumPadding.Top, frame.Width - wb.Width, frame.Height - wb.Height);
// if (Border.Child == null) {
// Border.Child = new ChildContentView (cFrame, this);
// } else {
// Border.Child.Frame = cFrame;
// }
// }
// if (Subviews?.Count == 0)
// base.Add (Border.Child);
// Border.ChildContainer = this;
// }
// ///
// public override void Add (View view)
// {
// Border.Child.Add (view);
// if (view.CanFocus) {
// CanFocus = true;
// }
// AddMenuStatusBar (view);
// }
// ///
// public override void Remove (View view)
// {
// if (view == null) {
// return;
// }
// SetNeedsDisplay ();
// var touched = view.Frame;
// Border.Child.Remove (view);
// if (Border.Child.InternalSubviews.Count < 1) {
// CanFocus = false;
// }
// RemoveMenuStatusBar (view);
// }
// ///
// public override void RemoveAll ()
// {
// Border.Child.RemoveAll ();
// }
// ///
// public override void Redraw (Rect bounds)
// {
// if (!NeedDisplay.IsEmpty) {
// Driver.SetAttribute (GetNormalColor ());
// Clear ();
// }
// var savedClip = Border.Child.ClipToBounds ();
// Border.Child.Redraw (Border.Child.Bounds);
// Driver.Clip = savedClip;
// ClearLayoutNeeded ();
// ClearNeedsDisplay ();
// Driver.SetAttribute (GetNormalColor ());
// Border.DrawContent (this, false);
// if (HasFocus)
// Driver.SetAttribute (ColorScheme.HotNormal);
// if (Border.DrawMarginFrame) {
// if (!ustring.IsNullOrEmpty (Border.Title))
// Border.DrawTitle (this);
// else
// Border.DrawTitle (this, Frame);
// }
// Driver.SetAttribute (GetNormalColor ());
// // Checks if there are any SuperView view which intersect with this window.
// if (SuperView != null) {
// SuperView.SetNeedsLayout ();
// SuperView.SetNeedsDisplay ();
// }
// }
// ///
// public override void OnCanFocusChanged ()
// {
// if (Border.Child != null) {
// Border.Child.CanFocus = CanFocus;
// }
// base.OnCanFocusChanged ();
// }
//}
//private class ChildContentView : View {
// View instance;
// public ChildContentView (Rect frame, View instance) : base (frame)
// {
// this.instance = instance;
// }
// public ChildContentView (View instance)
// {
// this.instance = instance;
// }
// public override bool MouseEvent (MouseEvent mouseEvent)
// {
// return instance.MouseEvent (mouseEvent);
// }
//}
///
/// Invoked when any property of Border changes (except ).
///
public event Action BorderChanged;
private BorderStyle borderStyle;
private bool drawMarginFrame;
private Thickness borderThickness = new Thickness (0);
private Color borderBrush;
private Color background;
private Thickness padding = new Thickness (0);
private bool effect3D;
private Point effect3DOffset = new Point (1, 1);
private Attribute? effect3DBrush;
private ustring title = ustring.Empty;
///
/// Specifies the for a view.
///
[JsonInclude, JsonConverter (typeof(JsonStringEnumConverter))]
public BorderStyle BorderStyle {
get => borderStyle;
set {
if (value != BorderStyle.None && !drawMarginFrame) {
// Ensures drawn the border lines.
drawMarginFrame = true;
}
borderStyle = value;
OnBorderChanged ();
}
}
///
/// Gets or sets if a margin frame is drawn around the regardless the
///
[JsonInclude]
public bool DrawMarginFrame {
get => drawMarginFrame;
set {
if (borderStyle != BorderStyle.None
&& (!value || !drawMarginFrame)) {
// Ensures drawn the border lines.
drawMarginFrame = true;
} else {
drawMarginFrame = value;
}
OnBorderChanged ();
}
}
///
/// Gets or sets the relative of a .
///
[JsonInclude]
public Thickness BorderThickness {
get => borderThickness;
set {
borderThickness = value;
OnBorderChanged ();
}
}
///
/// Gets or sets the that draws the outer border color.
///
[JsonInclude, JsonConverter (typeof (Configuration.ColorJsonConverter))]
public Color BorderBrush {
get => borderBrush;
set {
borderBrush = value;
OnBorderChanged ();
}
}
///
/// Gets or sets the that fills the area between the bounds of a .
///
[JsonInclude, JsonConverter (typeof (Configuration.ColorJsonConverter))]
public Color Background {
get => background;
set {
background = value;
OnBorderChanged ();
}
}
///
/// Gets or sets a value that describes the amount of space between a
/// and its child element.
///
[JsonInclude]
public Thickness Padding {
get => padding;
set {
padding = value;
OnBorderChanged ();
}
}
/////
///// Gets the rendered width of this element.
/////
//[JsonIgnore]
//public int ActualWidth {
// get {
// var driver = Application.Driver;
// if (Parent?.Border == null) {
// return Math.Min (Child?.Frame.Width + (2 * marginFrame) + Padding.Right
// + BorderThickness.Right + Padding.Left + BorderThickness.Left ?? 0, driver.Cols);
// }
// return Math.Min (Parent.Frame.Width, driver.Cols);
// }
//}
/////
///// Gets the rendered height of this element.
/////
//[JsonIgnore]
//public int ActualHeight {
// get {
// var driver = Application.Driver;
// if (Parent?.Border == null) {
// return Math.Min (Child?.Frame.Height + (2 * marginFrame) + Padding.Bottom
// + BorderThickness.Bottom + Padding.Top + BorderThickness.Top ?? 0, driver.Rows);
// }
// return Math.Min (Parent.Frame.Height, driver.Rows);
// }
//}
/////
///// Gets or sets the single child element of a .
/////
//[JsonIgnore]
//public View Child { get; set; }
/////
///// Gets the parent parent if any.
/////
//[JsonIgnore]
//public View Parent { get => Child?.SuperView; }
/////
///// Gets or private sets by the
/////
//[JsonIgnore]
//public ToplevelContainer ChildContainer { get; private set; }
///
/// Gets or sets the 3D effect around the .
///
[JsonInclude]
public bool Effect3D {
get => effect3D;
set {
effect3D = value;
OnBorderChanged ();
}
}
///
/// Get or sets the offset start position for the
///
[JsonInclude]
public Point Effect3DOffset {
get => effect3DOffset;
set {
effect3DOffset = value;
OnBorderChanged ();
}
}
///
/// Gets or sets the color for the
///
[JsonInclude, JsonConverter (typeof (Configuration.AttributeJsonConverter))]
public Attribute? Effect3DBrush {
get {
if (effect3DBrush == null && effect3D) {
return effect3DBrush = new Attribute (Color.Gray, Color.DarkGray);
} else {
return effect3DBrush;
}
}
set {
effect3DBrush = value;
OnBorderChanged ();
}
}
/////
///// The title to be displayed for this view.
/////
//[JsonIgnore]
//public ustring Title {
// get => title;
// set {
// title = value;
// OnBorderChanged ();
// }
//}
/////
///// Calculate the sum of the and the
/////
///// The total of the
//public Thickness GetSumThickness ()
//{
// return new Thickness () {
// Left = Padding.Left + BorderThickness.Left,
// Top = Padding.Top + BorderThickness.Top,
// Right = Padding.Right + BorderThickness.Right,
// Bottom = Padding.Bottom + BorderThickness.Bottom
// };
//}
/////
///// Drawn the more the
///// more the and the .
/////
///// The view to draw.
///// If it will clear or not the content area.
//public void DrawContent (View view = null, bool fill = true)
//{
// if (Child == null) {
// Child = view;
// }
// if (Parent?.Border != null) {
// DrawParentBorder (Parent.ViewToScreen (Parent.Bounds), fill);
// } else {
// DrawChildBorder (Child.ViewToScreen (Child.Bounds), fill);
// }
//}
/////
///// Same as but drawing full frames for all borders.
/////
//public void DrawFullContent ()
//{
// var borderThickness = BorderThickness;
// var padding = Padding;
// var marginFrame = DrawMarginFrame ? 1 : 0;
// var driver = Application.Driver;
// Rect scrRect;
// if (Parent?.Border != null) {
// scrRect = Parent.ViewToScreen (Parent.Bounds);
// } else {
// scrRect = Child.ViewToScreen (Child.Bounds);
// }
// Rect borderRect;
// if (Parent?.Border != null) {
// borderRect = scrRect;
// } else {
// borderRect = new Rect () {
// X = scrRect.X - marginFrame - padding.Left - borderThickness.Left,
// Y = scrRect.Y - marginFrame - padding.Top - borderThickness.Top,
// Width = ActualWidth,
// Height = ActualHeight
// };
// }
// var savedAttribute = driver.GetAttribute ();
// // Draw 3D effects
// if (Effect3D) {
// driver.SetAttribute ((Attribute)Effect3DBrush);
// var effectBorder = new Rect () {
// X = borderRect.X + Effect3DOffset.X,
// Y = borderRect.Y + Effect3DOffset.Y,
// Width = ActualWidth,
// Height = ActualHeight
// };
// //Child.Clear (effectBorder);
// for (int r = effectBorder.Y; r < Math.Min (effectBorder.Bottom, driver.Rows); r++) {
// for (int c = effectBorder.X; c < Math.Min (effectBorder.Right, driver.Cols); c++) {
// AddRuneAt (driver, c, r, (Rune)driver.Contents [r, c, 0]);
// }
// }
// }
// // Draw border thickness
// driver.SetAttribute (new Attribute (BorderBrush));
// Child.Clear (borderRect);
// borderRect = new Rect () {
// X = borderRect.X + borderThickness.Left,
// Y = borderRect.Y + borderThickness.Top,
// Width = Math.Max (borderRect.Width - borderThickness.Right - borderThickness.Left, 0),
// Height = Math.Max (borderRect.Height - borderThickness.Bottom - borderThickness.Top, 0)
// };
// if (borderRect != scrRect) {
// // Draw padding
// driver.SetAttribute (new Attribute (Background));
// Child.Clear (borderRect);
// }
// driver.SetAttribute (savedAttribute);
// // Draw margin frame
// if (DrawMarginFrame) {
// if (Parent?.Border != null) {
// var sumPadding = GetSumThickness ();
// borderRect = new Rect () {
// X = scrRect.X + sumPadding.Left,
// Y = scrRect.Y + sumPadding.Top,
// Width = Math.Max (scrRect.Width - sumPadding.Right - sumPadding.Left, 0),
// Height = Math.Max (scrRect.Height - sumPadding.Bottom - sumPadding.Top, 0)
// };
// } else {
// borderRect = new Rect () {
// X = borderRect.X + padding.Left,
// Y = borderRect.Y + padding.Top,
// Width = Math.Max (borderRect.Width - padding.Right - padding.Left, 0),
// Height = Math.Max (borderRect.Height - padding.Bottom - padding.Top, 0)
// };
// }
// if (borderRect.Width > 0 && borderRect.Height > 0) {
// driver.DrawWindowFrame (borderRect, 1, 1, 1, 1, BorderStyle != BorderStyle.None, fill: true, this);
// }
// }
//}
//private void DrawChildBorder (Rect frame, bool fill = true)
//{
// var drawMarginFrame = DrawMarginFrame ? 1 : 0;
// var sumThickness = GetSumThickness ();
// var padding = Padding;
// var effect3DOffset = Effect3DOffset;
// var driver = Application.Driver;
// var savedAttribute = driver.GetAttribute ();
// driver.SetAttribute (new Attribute (BorderBrush));
// // Draw the upper BorderThickness
// for (int r = frame.Y - drawMarginFrame - sumThickness.Top;
// r < frame.Y - drawMarginFrame - padding.Top; r++) {
// for (int c = frame.X - drawMarginFrame - sumThickness.Left;
// c < Math.Min (frame.Right + drawMarginFrame + sumThickness.Right, driver.Cols); c++) {
// AddRuneAt (driver, c, r, ' ');
// }
// }
// // Draw the left BorderThickness
// for (int r = frame.Y - drawMarginFrame - padding.Top;
// r < Math.Min (frame.Bottom + drawMarginFrame + padding.Bottom, driver.Rows); r++) {
// for (int c = frame.X - drawMarginFrame - sumThickness.Left;
// c < frame.X - drawMarginFrame - padding.Left; c++) {
// AddRuneAt (driver, c, r, ' ');
// }
// }
// // Draw the right BorderThickness
// for (int r = frame.Y - drawMarginFrame - padding.Top;
// r < Math.Min (frame.Bottom + drawMarginFrame + padding.Bottom, driver.Rows); r++) {
// for (int c = frame.Right + drawMarginFrame + padding.Right;
// c < Math.Min (frame.Right + drawMarginFrame + sumThickness.Right, driver.Cols); c++) {
// AddRuneAt (driver, c, r, ' ');
// }
// }
// // Draw the lower BorderThickness
// for (int r = frame.Bottom + drawMarginFrame + padding.Bottom;
// r < Math.Min (frame.Bottom + drawMarginFrame + sumThickness.Bottom, driver.Rows); r++) {
// for (int c = frame.X - drawMarginFrame - sumThickness.Left;
// c < Math.Min (frame.Right + drawMarginFrame + sumThickness.Right, driver.Cols); c++) {
// AddRuneAt (driver, c, r, ' ');
// }
// }
// driver.SetAttribute (new Attribute (Background));
// // Draw the upper Padding
// for (int r = frame.Y - drawMarginFrame - padding.Top;
// r < frame.Y - drawMarginFrame; r++) {
// for (int c = frame.X - drawMarginFrame - padding.Left;
// c < Math.Min (frame.Right + drawMarginFrame + padding.Right, driver.Cols); c++) {
// AddRuneAt (driver, c, r, ' ');
// }
// }
// // Draw the left Padding
// for (int r = frame.Y - drawMarginFrame;
// r < Math.Min (frame.Bottom + drawMarginFrame, driver.Rows); r++) {
// for (int c = frame.X - drawMarginFrame - padding.Left;
// c < frame.X - drawMarginFrame; c++) {
// AddRuneAt (driver, c, r, ' ');
// }
// }
// // Draw the right Padding
// for (int r = frame.Y - drawMarginFrame;
// r < Math.Min (frame.Bottom + drawMarginFrame, driver.Rows); r++) {
// for (int c = frame.Right + drawMarginFrame;
// c < Math.Min (frame.Right + drawMarginFrame + padding.Right, driver.Cols); c++) {
// AddRuneAt (driver, c, r, ' ');
// }
// }
// // Draw the lower Padding
// for (int r = frame.Bottom + drawMarginFrame;
// r < Math.Min (frame.Bottom + drawMarginFrame + padding.Bottom, driver.Rows); r++) {
// for (int c = frame.X - drawMarginFrame - padding.Left;
// c < Math.Min (frame.Right + drawMarginFrame + padding.Right, driver.Cols); c++) {
// AddRuneAt (driver, c, r, ' ');
// }
// }
// driver.SetAttribute (savedAttribute);
// // Draw the MarginFrame
// if (DrawMarginFrame) {
// var rect = new Rect () {
// X = frame.X - drawMarginFrame,
// Y = frame.Y - drawMarginFrame,
// Width = frame.Width + (2 * drawMarginFrame),
// Height = frame.Height + (2 * drawMarginFrame)
// };
// if (rect.Width > 0 && rect.Height > 0) {
// driver.DrawWindowFrame (rect, 1, 1, 1, 1, BorderStyle != BorderStyle.None, fill, this);
// DrawTitle (Child);
// }
// //var rect = Child.ViewToScreen (new Rect (-1, -1, Child.Frame.Width + 2, Child.Frame.Height + 2));
// //if (rect.Width > 0 && rect.Height > 0) {
// // var lc = new LineCanvas ();
// // lc.AddLine (rect.Location, rect.Width-1, Orientation.Horizontal, BorderStyle);
// // lc.AddLine (rect.Location, rect.Height-1, Orientation.Vertical, BorderStyle);
// // lc.AddLine (new Point (rect.X, rect.Y + rect.Height-1), rect.Width, Orientation.Horizontal, BorderStyle);
// // lc.AddLine (new Point (rect.X + rect.Width-1, rect.Y), rect.Height, Orientation.Vertical, BorderStyle);
// // //driver.SetAttribute (new Attribute(Color.Red, Color.BrightYellow));
// // foreach (var p in lc.GenerateImage (rect)) {
// // AddRuneAt (driver, p.Key.X, p.Key.Y, p.Value);
// // }
// // DrawTitle (Child);
// //}
// }
// if (Effect3D) {
// driver.SetAttribute ((Attribute)Effect3DBrush);
// // Draw the upper Effect3D
// for (int r = frame.Y - drawMarginFrame - sumThickness.Top + effect3DOffset.Y;
// r >= 0 && r < frame.Y - drawMarginFrame - sumThickness.Top; r++) {
// for (int c = frame.X - drawMarginFrame - sumThickness.Left + effect3DOffset.X;
// c >= 0 && c < Math.Min (frame.Right + drawMarginFrame + sumThickness.Right + effect3DOffset.X, driver.Cols); c++) {
// AddRuneAt (driver, c, r, (Rune)driver.Contents [r, c, 0]);
// }
// }
// // Draw the left Effect3D
// for (int r = frame.Y - drawMarginFrame - sumThickness.Top + effect3DOffset.Y;
// r >= 0 && r < Math.Min (frame.Bottom + drawMarginFrame + sumThickness.Bottom + effect3DOffset.Y, driver.Rows); r++) {
// for (int c = frame.X - drawMarginFrame - sumThickness.Left + effect3DOffset.X;
// c >= 0 && c < frame.X - drawMarginFrame - sumThickness.Left; c++) {
// AddRuneAt (driver, c, r, (Rune)driver.Contents [r, c, 0]);
// }
// }
// // Draw the right Effect3D
// for (int r = frame.Y - drawMarginFrame - sumThickness.Top + effect3DOffset.Y;
// r >= 0 && r < Math.Min (frame.Bottom + drawMarginFrame + sumThickness.Bottom + effect3DOffset.Y, driver.Rows); r++) {
// for (int c = frame.Right + drawMarginFrame + sumThickness.Right;
// c >= 0 && c < Math.Min (frame.Right + drawMarginFrame + sumThickness.Right + effect3DOffset.X, driver.Cols); c++) {
// AddRuneAt (driver, c, r, (Rune)driver.Contents [r, c, 0]);
// }
// }
// // Draw the lower Effect3D
// for (int r = frame.Bottom + drawMarginFrame + sumThickness.Bottom;
// r >= 0 && r < Math.Min (frame.Bottom + drawMarginFrame + sumThickness.Bottom + effect3DOffset.Y, driver.Rows); r++) {
// for (int c = frame.X - drawMarginFrame - sumThickness.Left + effect3DOffset.X;
// c >= 0 && c < Math.Min (frame.Right + drawMarginFrame + sumThickness.Right + effect3DOffset.X, driver.Cols); c++) {
// AddRuneAt (driver, c, r, (Rune)driver.Contents [r, c, 0]);
// }
// }
// }
// driver.SetAttribute (savedAttribute);
//}
//private void DrawParentBorder (Rect frame, bool fill = true)
//{
// var sumThickness = GetSumThickness ();
// var borderThickness = BorderThickness;
// var effect3DOffset = Effect3DOffset;
// var driver = Application.Driver;
// var savedAttribute = driver.GetAttribute ();
// driver.SetAttribute (new Attribute (BorderBrush));
// // Draw the upper BorderThickness
// for (int r = frame.Y;
// r < Math.Min (frame.Y + borderThickness.Top, frame.Bottom); r++) {
// for (int c = frame.X;
// c < Math.Min (frame.Right, driver.Cols); c++) {
// AddRuneAt (driver, c, r, ' ');
// }
// }
// // Draw the left BorderThickness
// for (int r = Math.Min (frame.Y + borderThickness.Top, frame.Bottom);
// r < Math.Min (frame.Bottom - borderThickness.Bottom, driver.Rows); r++) {
// for (int c = frame.X;
// c < Math.Min (frame.X + borderThickness.Left, frame.Right); c++) {
// AddRuneAt (driver, c, r, ' ');
// }
// }
// // Draw the right BorderThickness
// for (int r = Math.Min (frame.Y + borderThickness.Top, frame.Bottom);
// r < Math.Min (frame.Bottom - borderThickness.Bottom, driver.Rows); r++) {
// for (int c = Math.Max (frame.Right - borderThickness.Right, frame.X);
// c < Math.Min (frame.Right, driver.Cols); c++) {
// AddRuneAt (driver, c, r, ' ');
// }
// }
// // Draw the lower BorderThickness
// for (int r = Math.Max (frame.Bottom - borderThickness.Bottom, frame.Y);
// r < Math.Min (frame.Bottom, driver.Rows); r++) {
// for (int c = frame.X;
// c < Math.Min (frame.Right, driver.Cols); c++) {
// AddRuneAt (driver, c, r, ' ');
// }
// }
// driver.SetAttribute (new Attribute (Background));
// // Draw the upper Padding
// for (int r = frame.Y + borderThickness.Top;
// r < Math.Min (frame.Y + sumThickness.Top, frame.Bottom - borderThickness.Bottom); r++) {
// for (int c = frame.X + borderThickness.Left;
// c < Math.Min (frame.Right - borderThickness.Right, driver.Cols); c++) {
// AddRuneAt (driver, c, r, ' ');
// }
// }
// // Draw the left Padding
// for (int r = frame.Y + sumThickness.Top;
// r < Math.Min (frame.Bottom - sumThickness.Bottom, driver.Rows); r++) {
// for (int c = frame.X + borderThickness.Left;
// c < Math.Min (frame.X + sumThickness.Left, frame.Right - borderThickness.Right); c++) {
// AddRuneAt (driver, c, r, ' ');
// }
// }
// // Draw the right Padding
// for (int r = frame.Y + sumThickness.Top;
// r < Math.Min (frame.Bottom - sumThickness.Bottom, driver.Rows); r++) {
// for (int c = Math.Max (frame.Right - sumThickness.Right, frame.X + sumThickness.Left);
// c < Math.Max (frame.Right - borderThickness.Right, frame.X + sumThickness.Left); c++) {
// AddRuneAt (driver, c, r, ' ');
// }
// }
// // Draw the lower Padding
// for (int r = Math.Max (frame.Bottom - sumThickness.Bottom, frame.Y + borderThickness.Top);
// r < Math.Min (frame.Bottom - borderThickness.Bottom, driver.Rows); r++) {
// for (int c = frame.X + borderThickness.Left;
// c < Math.Min (frame.Right - borderThickness.Right, driver.Cols); c++) {
// AddRuneAt (driver, c, r, ' ');
// }
// }
// driver.SetAttribute (savedAttribute);
// // Draw the MarginFrame
// if (DrawMarginFrame) {
// var rect = new Rect () {
// X = frame.X + sumThickness.Left,
// Y = frame.Y + sumThickness.Top,
// Width = Math.Max (frame.Width - sumThickness.Right - sumThickness.Left, 0),
// Height = Math.Max (frame.Height - sumThickness.Bottom - sumThickness.Top, 0)
// };
// if (rect.Width > 0 && rect.Height > 0) {
// driver.DrawWindowFrame (rect, 1, 1, 1, 1, BorderStyle != BorderStyle.None, fill, this);
// DrawTitle (Parent);
// }
// }
// if (Effect3D) {
// driver.SetAttribute ((Attribute)Effect3DBrush);
// // Draw the upper Effect3D
// for (int r = Math.Max (frame.Y + effect3DOffset.Y, 0);
// r < frame.Y; r++) {
// for (int c = Math.Max (frame.X + effect3DOffset.X, 0);
// c < Math.Min (frame.Right + effect3DOffset.X, driver.Cols); c++) {
// AddRuneAt (driver, c, r, (Rune)driver.Contents [r, c, 0]);
// }
// }
// // Draw the left Effect3D
// for (int r = Math.Max (frame.Y + effect3DOffset.Y, 0);
// r < Math.Min (frame.Bottom + effect3DOffset.Y, driver.Rows); r++) {
// for (int c = Math.Max (frame.X + effect3DOffset.X, 0);
// c < frame.X; c++) {
// AddRuneAt (driver, c, r, (Rune)driver.Contents [r, c, 0]);
// }
// }
// // Draw the right Effect3D
// for (int r = Math.Max (frame.Y + effect3DOffset.Y, 0);
// r < Math.Min (frame.Bottom + effect3DOffset.Y, driver.Rows); r++) {
// for (int c = frame.Right;
// c < Math.Min (frame.Right + effect3DOffset.X, driver.Cols); c++) {
// AddRuneAt (driver, c, r, (Rune)driver.Contents [r, c, 0]);
// }
// }
// // Draw the lower Effect3D
// for (int r = frame.Bottom;
// r < Math.Min (frame.Bottom + effect3DOffset.Y, driver.Rows); r++) {
// for (int c = Math.Max (frame.X + effect3DOffset.X, 0);
// c < Math.Min (frame.Right + effect3DOffset.X, driver.Cols); c++) {
// AddRuneAt (driver, c, r, (Rune)driver.Contents [r, c, 0]);
// }
// }
// }
// driver.SetAttribute (savedAttribute);
//}
//private void AddRuneAt (ConsoleDriver driver, int col, int row, Rune ch)
//{
// if (col < driver.Cols && row < driver.Rows && col > 0 && driver.Contents [row, col, 2] == 0
// && Rune.ColumnWidth ((char)driver.Contents [row, col - 1, 0]) > 1) {
// driver.Contents [row, col, 1] = driver.GetAttribute ();
// return;
// }
// driver.Move (col, row);
// driver.AddRune (ch);
//}
/////
///// Draws the view to the screen.
/////
///// The view.
//public void DrawTitle (View view)
//{
// var driver = Application.Driver;
// if (DrawMarginFrame) {
// driver.SetAttribute (Child.GetNormalColor ());
// if (Child.HasFocus)
// driver.SetAttribute (Child.ColorScheme.HotNormal);
// var padding = view.Border.GetSumThickness ();
// Rect scrRect;
// if (view == Child) {
// scrRect = view.ViewToScreen (new Rect (0, 0, view.Frame.Width + 2, view.Frame.Height + 2));
// scrRect = new Rect (scrRect.X - 1, scrRect.Y - 1, scrRect.Width, scrRect.Height);
// driver.DrawWindowTitle (scrRect, Title, 0, 0, 0, 0);
// } else {
// scrRect = view.ViewToScreen (new Rect (0, 0, view.Frame.Width, view.Frame.Height));
// driver.DrawWindowTitle (scrRect, Title,
// padding.Left, padding.Top, padding.Right, padding.Bottom);
// }
// }
// driver.SetAttribute (Child.GetNormalColor ());
//}
/////
///// Draws the to the screen.
/////
///// The view.
///// The frame.
//public void DrawTitle (View view, Rect rect)
//{
// var driver = Application.Driver;
// if (DrawMarginFrame) {
// driver.SetAttribute (view.GetNormalColor ());
// if (view.HasFocus) {
// driver.SetAttribute (view.ColorScheme.HotNormal);
// }
// var padding = Parent.Border.GetSumThickness ();
// var scrRect = Parent.ViewToScreen (new Rect (0, 0, rect.Width, rect.Height));
// driver.DrawWindowTitle (scrRect, view.Text,
// padding.Left, padding.Top, padding.Right, padding.Bottom);
// }
// driver.SetAttribute (view.GetNormalColor ());
//}
///
/// Invoke the event.
///
public virtual void OnBorderChanged ()
{
BorderChanged?.Invoke (this);
}
}
}