Fixes #2569. Borders scenarios needed to be refactored. (#2570)

* Fixes #2569. Borders scenarios needed to be refactored.

* Fix border title with width equal to 4 and thickness top grater than 1.

* Improves border manipulation on borders scenarios.

* Prevents null value on the margin, border and padding thickness on the border scenarios.

* Remove NStack using dependence and fix prior commit.

* Refactoring the Frames scenario.

* Deleted borders scenarios.

* I did not realize that it was changed to SetSubViewNeedsDisplay.

* Re-layout; fixed colorpicker; fixed radio group

* Remove Thickness.IsEmpty as requested.

* Change the Frames scenario as requested.

---------

Co-authored-by: Tig Kindel <tig@users.noreply.github.com>
This commit is contained in:
BDisp
2023-05-01 06:00:51 +01:00
committed by GitHub
parent be67e0f09f
commit 105ff9ab54
23 changed files with 934 additions and 1118 deletions

View File

@@ -56,7 +56,7 @@ namespace Terminal.Gui {
// For Unit testing - ignores UseSystemConsole
internal static bool _forceFakeConsole;
private static bool? _enableConsoleScrolling;
/// <summary>
/// The current <see cref="ConsoleDriver.EnableConsoleScrolling"/> used in the terminal.
@@ -119,7 +119,7 @@ namespace Terminal.Gui {
File.Exists (Path.Combine (assemblyLocation, cultureInfo.Name, resourceFilename))
).ToList ();
}
#region Initialization (Init/Shutdown)
/// <summary>
@@ -357,7 +357,7 @@ namespace Terminal.Gui {
/// For debug (see DEBUG_IDISPOSABLE define) purposes; the runstate instances that have been created
/// </summary>
public static List<RunState> Instances = new List<RunState> ();
/// <summary>
/// Creates a new RunState object.
/// </summary>
@@ -618,7 +618,7 @@ namespace Terminal.Gui {
}
#endif
}
}
}
/// <summary>
/// Triggers a refresh of the entire display.
@@ -630,6 +630,7 @@ namespace Terminal.Gui {
foreach (var v in _toplevels.Reverse ()) {
if (v.Visible) {
v.SetNeedsDisplay ();
v.SetSubViewNeedsDisplay ();
v.Redraw (v.Bounds);
}
last = v;
@@ -763,7 +764,7 @@ namespace Terminal.Gui {
firstIteration = false;
if (state.Toplevel != Top
&& (!Top._needsDisplay.IsEmpty || Top._childNeedsDisplay || Top.LayoutNeeded)) {
&& (!Top._needsDisplay.IsEmpty || Top._subViewNeedsDisplay || Top.LayoutNeeded)) {
state.Toplevel.SetNeedsDisplay (state.Toplevel.Bounds);
Top.Redraw (Top.Bounds);
foreach (var top in _toplevels.Reverse ()) {
@@ -775,14 +776,14 @@ namespace Terminal.Gui {
}
if (_toplevels.Count == 1 && state.Toplevel == Top
&& (Driver.Cols != state.Toplevel.Frame.Width || Driver.Rows != state.Toplevel.Frame.Height)
&& (!state.Toplevel._needsDisplay.IsEmpty || state.Toplevel._childNeedsDisplay || state.Toplevel.LayoutNeeded)) {
&& (!state.Toplevel._needsDisplay.IsEmpty || state.Toplevel._subViewNeedsDisplay || state.Toplevel.LayoutNeeded)) {
Driver.SetAttribute (Colors.TopLevel.Normal);
state.Toplevel.Clear (new Rect (0, 0, Driver.Cols, Driver.Rows));
}
if (!state.Toplevel._needsDisplay.IsEmpty || state.Toplevel._childNeedsDisplay || state.Toplevel.LayoutNeeded
if (!state.Toplevel._needsDisplay.IsEmpty || state.Toplevel._subViewNeedsDisplay || state.Toplevel.LayoutNeeded
|| OverlappedChildNeedsDisplay ()) {
state.Toplevel.Redraw (state.Toplevel.Bounds);
//if (state.Toplevel.SuperView != null) {
@@ -796,7 +797,7 @@ namespace Terminal.Gui {
Driver.UpdateCursor ();
}
if (state.Toplevel != Top && !state.Toplevel.Modal
&& (!Top._needsDisplay.IsEmpty || Top._childNeedsDisplay || Top.LayoutNeeded)) {
&& (!Top._needsDisplay.IsEmpty || Top._subViewNeedsDisplay || Top.LayoutNeeded)) {
Top.Redraw (Top.Bounds);
}
}
@@ -892,7 +893,7 @@ namespace Terminal.Gui {
NotifyStopRunState?.Invoke (top, new ToplevelEventArgs (top));
}
}
/// <summary>
/// Building block API: completes the execution of a <see cref="Toplevel"/> that was started with <see cref="Begin(Toplevel)"/> .
/// </summary>

View File

@@ -344,6 +344,26 @@ namespace Terminal.Gui {
/// </summary>
internal string schemeBeingSet = "";
/// <summary>
/// Creates a new instance.
/// </summary>
public ColorScheme() { }
/// <summary>
/// Creates a new instance, initialized with the values from <paramref name="scheme"/>.
/// </summary>
/// <param name="scheme">The scheme to initlize the new instance with.</param>
public ColorScheme (ColorScheme scheme) : base()
{
if (scheme != null) {
_normal = scheme.Normal;
_focus = scheme.Focus;
_hotNormal = scheme.HotNormal;
_disabled = scheme.Disabled;
_hotFocus = scheme.HotFocus;
}
}
/// <summary>
/// The foreground and background color for text when the view is not focused, hot, or disabled.
/// </summary>

View File

@@ -124,9 +124,13 @@ namespace Terminal.Gui {
if (Thickness == Thickness.Empty) return;
if (ColorScheme != null) {
Driver.SetAttribute (ColorScheme.Normal);
Driver.SetAttribute (GetNormalColor ());
} else {
Driver.SetAttribute (Parent.GetNormalColor ());
if (Id == "Padding") {
Driver.SetAttribute (new Attribute (Parent.ColorScheme.HotNormal.Background, Parent.ColorScheme.HotNormal.Foreground));
} else {
Driver.SetAttribute (Parent.GetNormalColor ());
}
}
//Driver.SetAttribute (Colors.Error.Normal);
@@ -154,43 +158,51 @@ namespace Terminal.Gui {
var topTitleLineY = borderBounds.Y;
var titleY = borderBounds.Y;
var titleBarsLength = 0; // the little vertical thingies
var maxTitleWidth = Math.Min (Parent.Title.ConsoleWidth, screenBounds.Width - 4);
var maxTitleWidth = Math.Min (Parent.Title.ConsoleWidth, Math.Min (screenBounds.Width - 4, borderBounds.Width - 4));
var sideLineLength = borderBounds.Height;
var canDrawBorder = borderBounds.Width > 0 && borderBounds.Height > 0;
if (!ustring.IsNullOrEmpty (Parent?.Title)) {
if (Thickness.Top == 2) {
topTitleLineY = borderBounds.Y - 1;
titleY = topTitleLineY + 1;
titleBarsLength = 2;
}
// ┌────┐
//┌┘View└
//│
if (Thickness.Top == 3) {
topTitleLineY = borderBounds.Y - (Thickness.Top - 1);
titleY = topTitleLineY + 1;
titleBarsLength = 3;
sideLineLength++;
}
// ┌────┐
//┌┘View└
//│
if (Thickness.Top > 3) {
topTitleLineY = borderBounds.Y - 2;
titleY = topTitleLineY + 1;
titleBarsLength = 3;
sideLineLength++;
}
if (Thickness.Top == 2) {
topTitleLineY = borderBounds.Y - 1;
titleY = topTitleLineY + 1;
titleBarsLength = 2;
}
// ┌────┐
//┌┘View└
//│
if (Thickness.Top == 3) {
topTitleLineY = borderBounds.Y - (Thickness.Top - 1);
titleY = topTitleLineY + 1;
titleBarsLength = 3;
sideLineLength++;
}
// ┌────┐
//┌┘View└
//│
if (Thickness.Top > 3) {
topTitleLineY = borderBounds.Y - 2;
titleY = topTitleLineY + 1;
titleBarsLength = 3;
sideLineLength++;
}
if (Id == "Border" && Thickness.Top > 0 && maxTitleWidth > 0 && !ustring.IsNullOrEmpty (Parent?.Title)) {
if (Id == "Border" && canDrawBorder && Thickness.Top > 0 && maxTitleWidth > 0 && !ustring.IsNullOrEmpty (Parent?.Title)) {
var prevAttr = Driver.GetAttribute ();
Driver.SetAttribute (Parent.HasFocus ? Parent.GetHotNormalColor () : Parent.GetNormalColor ());
DrawTitle (new Rect (borderBounds.X, titleY, Math.Min (borderBounds.Width - 4, Parent.Title.ConsoleWidth), 1), Parent?.Title);
if (ColorScheme != null) {
Driver.SetAttribute (HasFocus ? GetHotNormalColor () : GetNormalColor ());
} else {
Driver.SetAttribute (Parent.HasFocus ? Parent.GetHotNormalColor () : Parent.GetNormalColor ());
}
DrawTitle (new Rect (borderBounds.X, titleY, maxTitleWidth, 1), Parent?.Title);
Driver.SetAttribute (prevAttr);
}
if (Id == "Border" && BorderStyle != LineStyle.None) {
if (Id == "Border" && canDrawBorder && BorderStyle != LineStyle.None) {
LineCanvas lc = Parent?.LineCanvas;
var drawTop = Thickness.Top > 0 && Frame.Width > 1 && Frame.Height > 1;
@@ -198,48 +210,56 @@ namespace Terminal.Gui {
var drawBottom = Thickness.Bottom > 0 && Frame.Width > 1;
var drawRight = Thickness.Right > 0 && (Frame.Height > 1 || Thickness.Top == 0);
var prevAttr = Driver.GetAttribute ();
if (ColorScheme != null) {
Driver.SetAttribute (GetNormalColor ());
} else {
Driver.SetAttribute (Parent.GetNormalColor ());
}
if (drawTop) {
// ╔╡Title╞═════╗
// ╔╡╞═════╗
if (Frame.Width < 4 || ustring.IsNullOrEmpty (Parent?.Title)) {
if (borderBounds.Width < 4 || ustring.IsNullOrEmpty (Parent?.Title)) {
// ╔╡╞╗ should be ╔══╗
lc.AddLine (new Point (borderBounds.Location.X, titleY), borderBounds.Width, Orientation.Horizontal, BorderStyle);
lc.AddLine (new Point (borderBounds.Location.X, titleY), borderBounds.Width, Orientation.Horizontal, BorderStyle, Driver.GetAttribute ());
} else {
// ┌────┐
//┌┘View└
//│
if (Thickness.Top == 2) {
lc.AddLine (new Point (borderBounds.X + 1, topTitleLineY), Math.Min (borderBounds.Width - 2, maxTitleWidth + 2), Orientation.Horizontal, BorderStyle);
lc.AddLine (new Point (borderBounds.X + 1, topTitleLineY), Math.Min (borderBounds.Width - 2, maxTitleWidth + 2), Orientation.Horizontal, BorderStyle, Driver.GetAttribute ());
}
// ┌────┐
//┌┘View└
//│
if (Thickness.Top > 2) {
lc.AddLine (new Point (borderBounds.X + 1, topTitleLineY), Math.Min (borderBounds.Width - 2, maxTitleWidth + 2), Orientation.Horizontal, BorderStyle);
lc.AddLine (new Point (borderBounds.X + 1, topTitleLineY + 2), Math.Min (borderBounds.Width - 2, maxTitleWidth + 2), Orientation.Horizontal, BorderStyle);
if (borderBounds.Width >= 4 && Thickness.Top > 2) {
lc.AddLine (new Point (borderBounds.X + 1, topTitleLineY), Math.Min (borderBounds.Width - 2, maxTitleWidth + 2), Orientation.Horizontal, BorderStyle, Driver.GetAttribute ());
lc.AddLine (new Point (borderBounds.X + 1, topTitleLineY + 2), Math.Min (borderBounds.Width - 2, maxTitleWidth + 2), Orientation.Horizontal, BorderStyle, Driver.GetAttribute ());
}
// ╔╡Title╞═════╗
// Add a short horiz line for ╔╡
lc.AddLine (new Point (borderBounds.Location.X, titleY), 2, Orientation.Horizontal, BorderStyle);
lc.AddLine (new Point (borderBounds.Location.X, titleY), 2, Orientation.Horizontal, BorderStyle, Driver.GetAttribute ());
// Add a vert line for ╔╡
lc.AddLine (new Point (borderBounds.X + 1, topTitleLineY), titleBarsLength, Orientation.Vertical, LineStyle.Single);
lc.AddLine (new Point (borderBounds.X + 1, topTitleLineY), titleBarsLength, Orientation.Vertical, LineStyle.Single, Driver.GetAttribute ());
// Add a vert line for ╞
lc.AddLine (new Point (borderBounds.X + 1 + Math.Min (borderBounds.Width - 2, maxTitleWidth + 2) - 1, topTitleLineY), titleBarsLength, Orientation.Vertical, LineStyle.Single);
lc.AddLine (new Point (borderBounds.X + 1 + Math.Min (borderBounds.Width - 2, maxTitleWidth + 2) - 1, topTitleLineY), titleBarsLength, Orientation.Vertical, LineStyle.Single, Driver.GetAttribute ());
// Add the right hand line for ╞═════╗
lc.AddLine (new Point (borderBounds.X + 1 + Math.Min (borderBounds.Width - 2, maxTitleWidth + 2) - 1, titleY), borderBounds.Width - Math.Min (borderBounds.Width - 2, maxTitleWidth + 2), Orientation.Horizontal, BorderStyle);
lc.AddLine (new Point (borderBounds.X + 1 + Math.Min (borderBounds.Width - 2, maxTitleWidth + 2) - 1, titleY), borderBounds.Width - Math.Min (borderBounds.Width - 2, maxTitleWidth + 2), Orientation.Horizontal, BorderStyle, Driver.GetAttribute ());
}
}
if (drawLeft) {
lc.AddLine (new Point (borderBounds.Location.X, titleY), sideLineLength, Orientation.Vertical, BorderStyle);
lc.AddLine (new Point (borderBounds.Location.X, titleY), sideLineLength, Orientation.Vertical, BorderStyle, Driver.GetAttribute ());
}
if (drawBottom) {
lc.AddLine (new Point (borderBounds.X, borderBounds.Y + borderBounds.Height - 1), borderBounds.Width, Orientation.Horizontal, BorderStyle);
lc.AddLine (new Point (borderBounds.X, borderBounds.Y + borderBounds.Height - 1), borderBounds.Width, Orientation.Horizontal, BorderStyle, Driver.GetAttribute ());
}
if (drawRight) {
lc.AddLine (new Point (borderBounds.X + borderBounds.Width - 1, titleY), sideLineLength, Orientation.Vertical, BorderStyle);
lc.AddLine (new Point (borderBounds.X + borderBounds.Width - 1, titleY), sideLineLength, Orientation.Vertical, BorderStyle, Driver.GetAttribute ());
}
Driver.SetAttribute (prevAttr);
// TODO: This should be moved to LineCanvas as a new BorderStyle.Ruler
if ((ConsoleDriver.Diagnostics & ConsoleDriver.DiagnosticFlags.FrameRuler) == ConsoleDriver.DiagnosticFlags.FrameRuler) {
@@ -251,8 +271,12 @@ namespace Terminal.Gui {
// Redraw title
if (drawTop && Id == "Border" && maxTitleWidth > 0 && !ustring.IsNullOrEmpty (Parent?.Title)) {
var prevAttr = Driver.GetAttribute ();
Driver.SetAttribute (Parent.HasFocus ? Parent.GetHotNormalColor () : Parent.GetNormalColor ());
prevAttr = Driver.GetAttribute ();
if (ColorScheme != null) {
Driver.SetAttribute (HasFocus ? GetHotNormalColor () : GetNormalColor ());
} else {
Driver.SetAttribute (Parent.HasFocus ? Parent.GetHotNormalColor () : Parent.GetNormalColor ());
}
DrawTitle (new Rect (borderBounds.X, titleY, Parent.Title.ConsoleWidth, 1), Parent?.Title);
Driver.SetAttribute (prevAttr);
}

View File

@@ -345,6 +345,7 @@ namespace Terminal.Gui {
case 3: tside = "bottom"; break;
default: tside = "unknown"; break;
}
// Note: We do not checkt `Target` for null here to intentionally throw if so
return $"View({tside},{Target.ToString ()})";
}

View File

@@ -76,12 +76,12 @@ namespace Terminal.Gui {
}
/// <summary>
/// Removes the <see cref="_needsDisplay"/> and the <see cref="_childNeedsDisplay"/> setting on this view.
/// Removes the <see cref="_needsDisplay"/> and the <see cref="_subViewNeedsDisplay"/> setting on this view.
/// </summary>
protected void ClearNeedsDisplay ()
{
_needsDisplay = Rect.Empty;
_childNeedsDisplay = false;
_subViewNeedsDisplay = false;
}
// The view-relative region that needs to be redrawn
@@ -102,9 +102,9 @@ namespace Terminal.Gui {
/// <param name="region">The view-relative region that needs to be redrawn.</param>
public void SetNeedsDisplay (Rect region)
{
if (_needsDisplay.IsEmpty)
if (_needsDisplay.IsEmpty) {
_needsDisplay = region;
else {
} else {
var x = Math.Min (_needsDisplay.X, region.X);
var y = Math.Min (_needsDisplay.Y, region.Y);
var w = Math.Max (_needsDisplay.Width, region.Width);
@@ -125,18 +125,18 @@ namespace Terminal.Gui {
}
}
internal bool _childNeedsDisplay { get; private set; }
internal bool _subViewNeedsDisplay { get; private set; }
/// <summary>
/// Indicates that any Subviews (in the <see cref="Subviews"/> list) need to be repainted.
/// </summary>
public void SetSubViewNeedsDisplay ()
{
if (_childNeedsDisplay) {
if (_subViewNeedsDisplay) {
return;
}
_childNeedsDisplay = true;
if (_superView != null && !_superView._childNeedsDisplay)
_subViewNeedsDisplay = true;
if (_superView != null && !_superView._subViewNeedsDisplay)
_superView.SetSubViewNeedsDisplay ();
}
@@ -410,8 +410,8 @@ namespace Terminal.Gui {
LineCanvas.Clear ();
}
if (Subviews.Select (s => s.SuperViewRendersLineCanvas).Count () > 0) {
foreach (var subview in Subviews.Where (s => s.SuperViewRendersLineCanvas)) {
if (Subviews.Where (s => s.SuperViewRendersLineCanvas).Count () > 0) {
foreach (var subview in Subviews.Where (s => s.SuperViewRendersLineCanvas == true)) {
// Combine the LineCavas'
LineCanvas.Merge (subview.LineCanvas);
subview.LineCanvas.Clear ();

View File

@@ -379,6 +379,10 @@ namespace Terminal.Gui {
/// </remarks>
public bool GetMinimumBounds (out Size size)
{
if (!IsInitialized) {
size = new Size (0, 0);
return false;
}
size = Bounds.Size;
if (!AutoSize && !ustring.IsNullOrEmpty (TextFormatter.Text)) {
@@ -962,7 +966,7 @@ namespace Terminal.Gui {
var aSize = true;
var nBoundsSize = GetAutoSize ();
if (nBoundsSize != Bounds.Size) {
if (IsInitialized && nBoundsSize != Bounds.Size) {
if (ForceValidatePosDim) {
aSize = SetWidthHeight (nBoundsSize);
} else {
@@ -1007,7 +1011,13 @@ namespace Terminal.Gui {
/// <returns>The <see cref="Size"/> required to fit the text.</returns>
public Size GetAutoSize ()
{
var rect = TextFormatter.CalcRect (Bounds.X, Bounds.Y, TextFormatter.Text, TextFormatter.Direction);
int x = 0;
int y = 0;
if (IsInitialized) {
x = Bounds.X;
y = Bounds.Y;
}
var rect = TextFormatter.CalcRect (x, y,TextFormatter.Text, TextFormatter.Direction);
var newWidth = rect.Size.Width - GetHotKeySpecifierLength () + Margin.Thickness.Horizontal + Border.Thickness.Horizontal + Padding.Thickness.Horizontal;
var newHeight = rect.Size.Height - GetHotKeySpecifierLength (false) + Margin.Thickness.Vertical + Border.Thickness.Vertical + Padding.Thickness.Vertical;
return new Size (newWidth, newHeight);

View File

@@ -1,34 +1,79 @@
using System;
using System.Reflection;
using NStack;
using static Terminal.Gui.SpinnerStyle;
namespace Terminal.Gui {
/// <summary>
/// Event arguments for the <see cref="Color"/> events.
/// </summary>
public class ColorEventArgs : EventArgs {
/// <summary>
/// Initializes a new instance of <see cref="ColorEventArgs"/>
/// </summary>
public ColorEventArgs ()
{
}
/// <summary>
/// The new Thickness.
/// </summary>
public Color Color { get; set; }
/// <summary>
/// The previous Thickness.
/// </summary>
public Color PreviousColor { get; set; }
}
/// <summary>
/// The <see cref="ColorPicker"/> <see cref="View"/> Color picker.
/// </summary>
public class ColorPicker : View {
/// <summary>
/// Number of colors on a line.
/// </summary>
private static readonly int colorsPerLine = 8;
private int _selectColorIndex = (int)Color.Black;
/// <summary>
/// Number of color lines.
/// Columns of color boxes
/// </summary>
private static readonly int lineCount = 2;
private int _cols = 8;
/// <summary>
/// Horizontal zoom.
/// Rows of color boxes
/// </summary>
private static readonly int horizontalZoom = 4;
private int _rows = 2;
/// <summary>
/// Vertical zoom.
/// Width of a color box
/// </summary>
private static readonly int verticalZoom = 2;
public int BoxWidth {
get => _boxWidth;
set {
if (_boxWidth != value) {
_boxWidth = value;
SetNeedsLayout ();
}
}
}
private int _boxWidth = 4;
/// <summary>
/// Height of a color box
/// </summary>
public int BoxHeight {
get => _boxHeight;
set {
if (_boxHeight != value) {
_boxHeight = value;
SetNeedsLayout ();
}
}
}
private int _boxHeight = 2;
// Cursor runes.
private static readonly Rune [] cursorRunes = new Rune []
private static readonly Rune [] _cursorRunes = new Rune []
{
0x250C, 0x2500, 0x2500, 0x2510,
0x2514, 0x2500, 0x2500, 0x2518
@@ -39,11 +84,11 @@ namespace Terminal.Gui {
/// </summary>
public Point Cursor {
get {
return new Point (selectColorIndex % colorsPerLine, selectColorIndex / colorsPerLine);
return new Point (_selectColorIndex % _cols, _selectColorIndex / _cols);
}
set {
var colorIndex = value.Y * colorsPerLine + value.X;
var colorIndex = value.Y * _cols + value.X;
SelectedColor = (Color)colorIndex;
}
}
@@ -51,21 +96,23 @@ namespace Terminal.Gui {
/// <summary>
/// Fired when a color is picked.
/// </summary>
public event EventHandler ColorChanged;
private int selectColorIndex = (int)Color.Black;
public event EventHandler<ColorEventArgs> ColorChanged;
/// <summary>
/// Selected color.
/// </summary>
public Color SelectedColor {
get {
return (Color)selectColorIndex;
return (Color)_selectColorIndex;
}
set {
selectColorIndex = (int)value;
ColorChanged?.Invoke (this, EventArgs.Empty);
Color prev = (Color)_selectColorIndex;
_selectColorIndex = (int)value;
ColorChanged?.Invoke (this, new ColorEventArgs () {
PreviousColor = prev,
Color = value,
});
SetNeedsDisplay ();
}
}
@@ -73,48 +120,19 @@ namespace Terminal.Gui {
/// <summary>
/// Initializes a new instance of <see cref="ColorPicker"/>.
/// </summary>
public ColorPicker () : base ("Color Picker")
public ColorPicker ()
{
Initialize ();
SetInitialProperties ();
}
/// <summary>
/// Initializes a new instance of <see cref="ColorPicker"/>.
/// </summary>
/// <param name="title">Title.</param>
public ColorPicker (ustring title) : base (title)
{
Initialize ();
}
/// <summary>
/// Initializes a new instance of <see cref="ColorPicker"/>.
/// </summary>
/// <param name="point">Location point.</param>
/// <param name="title">Title.</param>
public ColorPicker (Point point, ustring title) : this (point.X, point.Y, title)
{
}
/// <summary>
/// Initializes a new instance of <see cref="ColorPicker"/>.
/// </summary>
/// <param name="x">X location.</param>
/// <param name="y">Y location.</param>
/// <param name="title">Title</param>
public ColorPicker (int x, int y, ustring title) : base (x, y, title)
{
Initialize ();
}
private void Initialize()
private void SetInitialProperties ()
{
CanFocus = true;
Width = colorsPerLine * horizontalZoom;
Height = lineCount * verticalZoom + 1;
AddCommands ();
AddKeyBindings ();
LayoutStarted += (o, a) => {
Bounds = new Rect (Bounds.Location, new Size (_cols * BoxWidth, _rows * BoxHeight));
};
}
/// <summary>
@@ -147,9 +165,9 @@ namespace Terminal.Gui {
Driver.SetAttribute (HasFocus ? ColorScheme.Focus : GetNormalColor ());
var colorIndex = 0;
for (var y = 0; y < (Height.Anchor (0) - 1) / verticalZoom; y++) {
for (var x = 0; x < Width.Anchor (0) / horizontalZoom; x++) {
var foregroundColorIndex = y == 0 ? colorIndex + colorsPerLine : colorIndex - colorsPerLine;
for (var y = 0; y < (Bounds.Height / BoxHeight); y++) {
for (var x = 0; x < (Bounds.Width / BoxWidth); x++) {
var foregroundColorIndex = y == 0 ? colorIndex + _cols : colorIndex - _cols;
Driver.SetAttribute (Driver.MakeAttribute ((Color)foregroundColorIndex, (Color)colorIndex));
var selected = x == Cursor.X && y == Cursor.Y;
DrawColorBox (x, y, selected);
@@ -168,20 +186,36 @@ namespace Terminal.Gui {
{
var index = 0;
for (var zommedY = 0; zommedY < verticalZoom; zommedY++) {
for (var zommedX = 0; zommedX < horizontalZoom; zommedX++) {
Move (x * horizontalZoom + zommedX, y * verticalZoom + zommedY + 1);
if (selected) {
var character = cursorRunes [index];
Driver.AddRune (character);
} else {
Driver.AddRune (' ');
}
for (var zoomedY = 0; zoomedY < BoxHeight; zoomedY++) {
for (var zoomedX = 0; zoomedX < BoxWidth; zoomedX++) {
Move (x * BoxWidth + zoomedX, y * BoxHeight + zoomedY);
Driver.AddRune (' ');
index++;
}
}
if (selected) {
DrawFocusRect (new Rect (x * BoxWidth, y * BoxHeight, BoxWidth, BoxHeight));
}
}
private void DrawFocusRect (Rect rect)
{
var lc = new LineCanvas ();
if (rect.Width == 1) {
lc.AddLine (rect.Location, rect.Height, Orientation.Vertical, LineStyle.Dotted);
} else if (rect.Height == 1) {
lc.AddLine (rect.Location, rect.Width, Orientation.Horizontal, LineStyle.Dotted);
} else {
lc.AddLine (rect.Location, rect.Width, Orientation.Horizontal, LineStyle.Dotted);
lc.AddLine (new Point (rect.Location.X, rect.Location.Y + rect.Height - 1), rect.Width, Orientation.Horizontal, LineStyle.Dotted);
lc.AddLine (rect.Location, rect.Height, Orientation.Vertical, LineStyle.Dotted);
lc.AddLine (new Point (rect.Location.X + rect.Width - 1, rect.Location.Y), rect.Height, Orientation.Vertical, LineStyle.Dotted);
}
foreach (var p in lc.GetMap ()) {
AddRune (p.Key.X, p.Key.Y, p.Value);
}
}
/// <summary>
@@ -200,7 +234,7 @@ namespace Terminal.Gui {
/// <returns></returns>
public virtual bool MoveRight ()
{
if (Cursor.X < colorsPerLine - 1) SelectedColor++;
if (Cursor.X < _cols - 1) SelectedColor++;
return true;
}
@@ -210,7 +244,7 @@ namespace Terminal.Gui {
/// <returns></returns>
public virtual bool MoveUp ()
{
if (Cursor.Y > 0) SelectedColor -= colorsPerLine;
if (Cursor.Y > 0) SelectedColor -= _cols;
return true;
}
@@ -220,7 +254,7 @@ namespace Terminal.Gui {
/// <returns></returns>
public virtual bool MoveDown ()
{
if (Cursor.Y < lineCount - 1) SelectedColor += colorsPerLine;
if (Cursor.Y < _rows - 1) SelectedColor += _cols;
return true;
}
@@ -237,11 +271,12 @@ namespace Terminal.Gui {
///<inheritdoc/>
public override bool MouseEvent (MouseEvent me)
{
if (!me.Flags.HasFlag (MouseFlags.Button1Clicked) || !CanFocus)
if (!me.Flags.HasFlag (MouseFlags.Button1Clicked) || !CanFocus) {
return false;
}
SetFocus ();
Cursor = new Point (me.X / horizontalZoom, (me.Y - 1) / verticalZoom);
Cursor = new Point ((me.X - GetFramesThickness ().Left) / _boxWidth, (me.Y - GetFramesThickness ().Top) / _boxHeight);
return true;
}

View File

@@ -26,7 +26,7 @@ namespace Terminal.Gui {
/// <param name="selected">The index of the item to be selected, the value is clamped to the number of items.</param>
public RadioGroup (ustring [] radioLabels, int selected = 0) : base ()
{
Initialize (Rect.Empty, radioLabels, selected);
SetInitalProperties (Rect.Empty, radioLabels, selected);
}
/// <summary>
@@ -37,7 +37,7 @@ namespace Terminal.Gui {
/// <param name="selected">The index of item to be selected, the value is clamped to the number of items.</param>
public RadioGroup (Rect rect, ustring [] radioLabels, int selected = 0) : base (rect)
{
Initialize (rect, radioLabels, selected);
SetInitalProperties (rect, radioLabels, selected);
}
/// <summary>
@@ -52,7 +52,7 @@ namespace Terminal.Gui {
this (MakeRect (x, y, radioLabels != null ? radioLabels.ToList () : null), radioLabels, selected)
{ }
void Initialize (Rect rect, ustring [] radioLabels, int selected)
void SetInitalProperties (Rect rect, ustring [] radioLabels, int selected)
{
if (radioLabels == null) {
this.radioLabels = new List<ustring> ();
@@ -61,11 +61,7 @@ namespace Terminal.Gui {
}
this.selected = selected;
if (rect == Rect.Empty) {
SetWidthHeight (this.radioLabels);
} else {
Frame = rect;
}
Frame = rect;
CanFocus = true;
HotKeySpecifier = new Rune ('_');
@@ -82,6 +78,13 @@ namespace Terminal.Gui {
AddKeyBinding (Key.Home, Command.TopHome);
AddKeyBinding (Key.End, Command.BottomEnd);
AddKeyBinding (Key.Space, Command.Accept);
LayoutStarted += RadioGroup_LayoutStarted;
}
private void RadioGroup_LayoutStarted (object sender, EventArgs e)
{
SetWidthHeight (radioLabels);
}
/// <summary>
@@ -118,13 +121,9 @@ namespace Terminal.Gui {
switch (displayMode) {
case DisplayModeLayout.Vertical:
var r = MakeRect (0, 0, radioLabels);
if (IsAdded && LayoutStyle == LayoutStyle.Computed) {
Width = r.Width;
Height = radioLabels.Count;
} else {
Frame = new Rect (Frame.Location, new Size (r.Width, radioLabels.Count));
}
Bounds = new Rect (Bounds.Location, new Size (r.Width, radioLabels.Count));
break;
case DisplayModeLayout.Horizontal:
CalculateHorizontalPositions ();
var length = 0;
@@ -136,7 +135,7 @@ namespace Terminal.Gui {
Width = hr.Width;
Height = 1;
} else {
Frame = new Rect (Frame.Location, new Size (hr.Width, radioLabels.Count));
Bounds = new Rect (Bounds.Location, new Size (hr.Width, radioLabels.Count));
}
break;
}
@@ -150,8 +149,9 @@ namespace Terminal.Gui {
int width = 0;
foreach (var s in radioLabels)
width = Math.Max (s.ConsoleWidth + 3, width);
foreach (var s in radioLabels) {
width = Math.Max (s.ConsoleWidth + 2, width);
}
return new Rect (x, y, width, radioLabels.Count);
}
@@ -189,24 +189,12 @@ namespace Terminal.Gui {
}
}
//// Redraws the RadioGroup
//void Update(List<ustring> newRadioLabels)
//{
// for (int i = 0; i < radioLabels.Count; i++) {
// Move(0, i);
// Driver.SetAttribute(ColorScheme.Normal);
// Driver.AddStr(ustring.Make(new string (' ', radioLabels[i].ConsoleWidth + 4)));
// }
// if (newRadioLabels.Count != radioLabels.Count) {
// SetWidthHeight(newRadioLabels);
// }
//}
///<inheritdoc/>
public override void Redraw (Rect bounds)
{
base.Redraw (bounds);
Driver.SetAttribute (GetNormalColor ());
Clear ();
for (int i = 0; i < radioLabels.Count; i++) {
switch (DisplayMode) {
case DisplayModeLayout.Vertical:
@@ -387,11 +375,14 @@ namespace Terminal.Gui {
}
SetFocus ();
var pos = displayMode == DisplayModeLayout.Horizontal ? me.X : me.Y;
int boundsX = me.X - GetFramesThickness ().Left;
int boundsY = me.Y - GetFramesThickness ().Top;
var pos = displayMode == DisplayModeLayout.Horizontal ? boundsX : boundsY;
var rCount = displayMode == DisplayModeLayout.Horizontal ? horizontal.Last ().pos + horizontal.Last ().length : radioLabels.Count;
if (pos < rCount) {
var c = displayMode == DisplayModeLayout.Horizontal ? horizontal.FindIndex ((x) => x.pos <= me.X && x.pos + x.length - 2 >= me.X) : me.Y;
var c = displayMode == DisplayModeLayout.Horizontal ? horizontal.FindIndex ((x) => x.pos <= boundsX && x.pos + x.length - 2 >= boundsX) : boundsY;
if (c > -1) {
cursor = SelectedItem = c;
SetNeedsDisplay ();

View File

@@ -633,14 +633,14 @@ namespace Terminal.Gui {
maxWidth = top.SuperView.Bounds.Width;
superView = top.SuperView;
}
// BUGBUG: v2 hack for now
var mfLength = top.Border?.Thickness.Top > 0 ? 2 : 1;
if (superView.Margin != null && superView == top.SuperView) {
maxWidth -= superView.GetFramesThickness ().Left + superView.GetFramesThickness ().Right;
}
if (top.Frame.Width <= maxWidth) {
nx = Math.Max (targetX, 0);
nx = nx + top.Frame.Width > maxWidth ? Math.Max (maxWidth - top.Frame.Width, 0) : nx;
if (nx + mfLength > top.Frame.X + top.Frame.Width) {
nx = Math.Max (top.Frame.Right - mfLength, 0);
if (nx > top.Frame.X + top.Frame.Width) {
nx = Math.Max (top.Frame.Right, 0);
}
} else {
nx = targetX;
@@ -680,11 +680,14 @@ namespace Terminal.Gui {
} else {
maxWidth = statusVisible ? top.SuperView.Frame.Height - 1 : top.SuperView.Frame.Height;
}
if (superView.Margin != null && superView == top.SuperView) {
maxWidth -= superView.GetFramesThickness ().Top + superView.GetFramesThickness ().Bottom;
}
ny = Math.Min (ny, maxWidth);
if (top.Frame.Height <= maxWidth) {
ny = ny + top.Frame.Height >= maxWidth ? Math.Max (maxWidth - top.Frame.Height, menuVisible ? 1 : 0) : ny;
if (ny + mfLength > top.Frame.Y + top.Frame.Height) {
ny = Math.Max (top.Frame.Bottom - mfLength, 0);
ny = ny + top.Frame.Height > maxWidth ? Math.Max (maxWidth - top.Frame.Height, menuVisible ? 1 : 0) : ny;
if (ny > top.Frame.Y + top.Frame.Height) {
ny = Math.Max (top.Frame.Bottom, 0);
}
}
//System.Diagnostics.Debug.WriteLine ($"ny:{ny}, rHeight:{rHeight}");
@@ -713,9 +716,13 @@ namespace Terminal.Gui {
var superView = GetLocationThatFits (top, top.Frame.X, top.Frame.Y,
out int nx, out int ny, out _, out StatusBar sb);
bool layoutSubviews = false;
var maxWidth = 0;
if (superView.Margin != null && superView == top.SuperView) {
maxWidth -= superView.GetFramesThickness ().Left + superView.GetFramesThickness ().Right;
}
if ((superView != top || top?.SuperView != null || (top != Application.Top && top.Modal)
|| (top?.SuperView == null && top.IsOverlapped))
&& (top.Frame.X + top.Frame.Width > Driver.Cols || ny > top.Frame.Y) && top.LayoutStyle == LayoutStyle.Computed) {
&& (top.Frame.X + top.Frame.Width > maxWidth || ny > top.Frame.Y) && top.LayoutStyle == LayoutStyle.Computed) {
if ((top.X == null || top.X is Pos.PosAbsolute) && top.Frame.X != nx) {
top.X = nx;
@@ -750,7 +757,7 @@ namespace Terminal.Gui {
return;
}
if (!_needsDisplay.IsEmpty || _childNeedsDisplay || LayoutNeeded) {
if (!_needsDisplay.IsEmpty || _subViewNeedsDisplay || LayoutNeeded) {
Driver.SetAttribute (GetNormalColor ());
Clear (ViewToScreen (bounds));
LayoutSubviews ();
@@ -773,6 +780,7 @@ namespace Terminal.Gui {
if (view.Frame.IntersectsWith (bounds) && !OutsideTopFrame (this)) {
view.SetNeedsLayout ();
view.SetNeedsDisplay (view.Bounds);
view.SetSubViewNeedsDisplay ();
}
}
base.Redraw (Bounds);

View File

@@ -97,7 +97,7 @@ namespace Terminal.Gui {
}
foreach (var top in _toplevels) {
if (top != Current && top.Visible && (!top._needsDisplay.IsEmpty || top._childNeedsDisplay || top.LayoutNeeded)) {
if (top != Current && top.Visible && (!top._needsDisplay.IsEmpty || top._subViewNeedsDisplay || top.LayoutNeeded)) {
OverlappedTop.SetSubViewNeedsDisplay ();
return true;
}

View File

@@ -1,113 +0,0 @@
using Terminal.Gui;
namespace UICatalog.Scenarios {
[ScenarioMetadata (Name: "Borders Comparisons", Description: "Compares Window, Toplevel and FrameView borders.")]
[ScenarioCategory ("Layout")]
[ScenarioCategory ("Borders")]
public class BordersComparisons : Scenario {
public override void Init ()
{
Application.Init ();
var borderStyle = LineStyle.Double;
var borderThickness = new Thickness (1, 2, 3, 4);
var padding = 1;
Application.Top.Text = $"Border Thickness: {borderThickness}\nPadding: {padding}";
var win = new Window (new Rect (5, 5, 40, 20)) { Title = "Window" };
var tf1 = new TextField ("1234567890") { Width = 10 };
var button = new Button ("Press me!") {
X = Pos.Center (),
Y = Pos.Center (),
};
button.Clicked += (s,e) => MessageBox.Query (20, 7, "Hi", "I'm a Window?", "Yes", "No");
var label = new Label ("I'm a Window") {
X = Pos.Center (),
Y = Pos.Center () - 1,
};
var tv = new TextView () {
Y = Pos.AnchorEnd (2),
Width = 10,
Height = Dim.Fill (),
Text = "1234567890"
};
var tf2 = new TextField ("1234567890") {
X = Pos.AnchorEnd (10),
Y = Pos.AnchorEnd (1),
Width = 10
};
win.Add (tf1, button, label, tv, tf2);
Application.Top.Add (win);
var topLevel = new Toplevel (new Rect (50, 5, 40, 20));
//topLevel.Border.Thickness = borderThickness;
//topLevel.Border.BorderStyle = borderStyle;
//topLevel.Padding.Thickness = paddingThickness;
var tf3 = new TextField ("1234567890") { Width = 10 };
var button2 = new Button ("Press me!") {
X = Pos.Center (),
Y = Pos.Center (),
};
button2.Clicked += (s,e) => MessageBox.Query (20, 7, "Hi", "I'm a Toplevel?", "Yes", "No");
var label2 = new Label ("I'm a Toplevel") {
X = Pos.Center (),
Y = Pos.Center () - 1,
};
var tv2 = new TextView () {
Y = Pos.AnchorEnd (2),
Width = 10,
Height = Dim.Fill (),
Text = "1234567890"
};
var tf4 = new TextField ("1234567890") {
X = Pos.AnchorEnd (10),
Y = Pos.AnchorEnd (1),
Width = 10
};
topLevel.Add (tf3, button2, label2, tv2, tf4);
Application.Top.Add (topLevel);
var frameView = new FrameView (new Rect (95, 5, 40, 20), "FrameView", null);
frameView.Border.Thickness = borderThickness;
frameView.Border.BorderStyle = borderStyle;
//frameView.Padding.Thickness = paddingThickness;
var tf5 = new TextField ("1234567890") { Width = 10 };
var button3 = new Button ("Press me!") {
X = Pos.Center (),
Y = Pos.Center (),
};
button3.Clicked += (s,e) => MessageBox.Query (20, 7, "Hi", "I'm a FrameView?", "Yes", "No");
var label3 = new Label ("I'm a FrameView") {
X = Pos.Center (),
Y = Pos.Center () - 1,
};
var tv3 = new TextView () {
Y = Pos.AnchorEnd (2),
Width = 10,
Height = Dim.Fill (),
Text = "1234567890"
};
var tf6 = new TextField ("1234567890") {
X = Pos.AnchorEnd (10),
Y = Pos.AnchorEnd (1),
Width = 10
};
frameView.Add (tf5, button3, label3, tv3, tf6);
Application.Top.Add (frameView);
Application.Run ();
}
public override void Run ()
{
// Do nothing
}
}
}

View File

@@ -1,301 +0,0 @@
using System;
using System.Globalization;
using System.Linq;
using Terminal.Gui;
namespace UICatalog.Scenarios {
public class BordersOnContainers : Window {
public BordersOnContainers (NStack.ustring title, string typeName, View smartView)
{
var borderStyle = LineStyle.Double;
var borderThickness = new Thickness (1, 2, 3, 4);
var borderBrush = Colors.Base.HotFocus.Foreground;
var padding = new Thickness (1, 2, 3, 4);
var background = Colors.Base.HotNormal.Foreground;
smartView.X = Pos.Center ();
smartView.Y = 0;
smartView.Width = 40;
smartView.Height = 20;
smartView.BorderStyle = borderStyle;
smartView.ColorScheme = Colors.TopLevel;
var tf1 = new TextField ("1234567890") { Width = 10 };
var button = new Button ("Press me!") {
X = Pos.Center (),
Y = Pos.Center (),
};
button.Clicked += (s, e) => MessageBox.Query (20, 7, "Hi", $"I'm a {typeName}?", "Yes", "No");
var label = new Label ($"I'm a {typeName}") {
X = Pos.Center (),
Y = Pos.Center () - 1,
};
var tf2 = new TextField ("1234567890") {
X = Pos.AnchorEnd (10),
Y = Pos.AnchorEnd (1),
Width = 10
};
var tv = new TextView () {
Y = Pos.AnchorEnd (2),
Width = 10,
Height = Dim.Fill (),
Text = "1234567890"
};
smartView.Add (tf1, button, label, tf2, tv);
Add (new Label ("Padding:") {
X = Pos.Center () - 23,
});
var paddingTopEdit = new TextField ("") {
X = Pos.Center () - 22,
Y = 1,
Width = 5
};
paddingTopEdit.TextChanging += (s, e) => {
try {
smartView.Padding.Thickness = new Thickness (smartView.Padding.Thickness.Left,
int.Parse (e.NewText.ToString ()), smartView.Padding.Thickness.Right,
smartView.Padding.Thickness.Bottom);
} catch {
if (!e.NewText.IsEmpty) {
e.Cancel = true;
}
}
};
paddingTopEdit.Text = $"{smartView.Padding.Thickness.Top}";
Add (paddingTopEdit);
var paddingLeftEdit = new TextField ("") {
X = Pos.Center () - 30,
Y = 2,
Width = 5
};
paddingLeftEdit.TextChanging += (s, e) => {
try {
smartView.Padding.Thickness = new Thickness (int.Parse (e.NewText.ToString ()),
smartView.Padding.Thickness.Top, smartView.Padding.Thickness.Right,
smartView.Padding.Thickness.Bottom);
} catch {
if (!e.NewText.IsEmpty) {
e.Cancel = true;
}
}
};
paddingLeftEdit.Text = $"{smartView.Padding.Thickness.Left}";
Add (paddingLeftEdit);
var paddingRightEdit = new TextField ("") {
X = Pos.Center () - 15,
Y = 2,
Width = 5
};
paddingRightEdit.TextChanging += (s, e) => {
try {
smartView.Padding.Thickness = new Thickness (smartView.Padding.Thickness.Left,
smartView.Padding.Thickness.Top, int.Parse (e.NewText.ToString ()),
smartView.Padding.Thickness.Bottom);
} catch {
if (!e.NewText.IsEmpty) {
e.Cancel = true;
}
}
};
paddingRightEdit.Text = $"{smartView.Padding.Thickness.Right}";
Add (paddingRightEdit);
var paddingBottomEdit = new TextField ("") {
X = Pos.Center () - 22,
Y = 3,
Width = 5
};
paddingBottomEdit.TextChanging += (s, e) => {
try {
smartView.Padding.Thickness = new Thickness (smartView.Padding.Thickness.Left,
smartView.Padding.Thickness.Top, smartView.Padding.Thickness.Right,
int.Parse (e.NewText.ToString ()));
} catch {
if (!e.NewText.IsEmpty) {
e.Cancel = true;
}
}
};
paddingBottomEdit.Text = $"{smartView.Padding.Thickness.Bottom}";
Add (paddingBottomEdit);
var replacePadding = new Button ("Replace all based on top") {
X = Pos.Left (paddingLeftEdit),
Y = 5
};
replacePadding.Clicked += (s, e) => {
smartView.Padding.Thickness = new Thickness (smartView.Padding.Thickness.Top);
if (paddingTopEdit.Text.IsEmpty) {
paddingTopEdit.Text = "0";
}
paddingBottomEdit.Text = paddingLeftEdit.Text = paddingRightEdit.Text = paddingTopEdit.Text;
};
Add (replacePadding);
Add (new Label ("Border:") {
X = Pos.Center () + 11,
});
var borderTopEdit = new TextField ("") {
X = Pos.Center () + 12,
Y = 1,
Width = 5
};
borderTopEdit.TextChanging += (s, e) => {
try {
smartView.Border.Thickness = new Thickness (smartView.Border.Thickness.Left,
int.Parse (e.NewText.ToString ()), smartView.Border.Thickness.Right,
smartView.Border.Thickness.Bottom);
} catch {
if (!e.NewText.IsEmpty) {
e.Cancel = true;
}
}
};
borderTopEdit.Text = $"{smartView.Border.Thickness.Top}";
Add (borderTopEdit);
var borderLeftEdit = new TextField ("") {
X = Pos.Center () + 5,
Y = 2,
Width = 5
};
borderLeftEdit.TextChanging += (s, e) => {
try {
smartView.Border.Thickness = new Thickness (int.Parse (e.NewText.ToString ()),
smartView.Border.Thickness.Top, smartView.Border.Thickness.Right,
smartView.Border.Thickness.Bottom);
} catch {
if (!e.NewText.IsEmpty) {
e.Cancel = true;
}
}
};
borderLeftEdit.Text = $"{smartView.Border.Thickness.Left}";
Add (borderLeftEdit);
var borderRightEdit = new TextField ("") {
X = Pos.Center () + 19,
Y = 2,
Width = 5
};
borderRightEdit.TextChanging += (s, e) => {
try {
smartView.Border.Thickness = new Thickness (smartView.Border.Thickness.Left,
smartView.Border.Thickness.Top, int.Parse (e.NewText.ToString ()),
smartView.Border.Thickness.Bottom);
} catch {
if (!e.NewText.IsEmpty) {
e.Cancel = true;
}
}
};
borderRightEdit.Text = $"{smartView.Border.Thickness.Right}";
Add (borderRightEdit);
var borderBottomEdit = new TextField ("") {
X = Pos.Center () + 12,
Y = 3,
Width = 5
};
borderBottomEdit.TextChanging += (s, e) => {
try {
smartView.Border.Thickness = new Thickness (smartView.Border.Thickness.Left,
smartView.Border.Thickness.Top, smartView.Border.Thickness.Right,
int.Parse (e.NewText.ToString ()));
} catch {
if (!e.NewText.IsEmpty) {
e.Cancel = true;
}
}
};
borderBottomEdit.Text = $"{smartView.Border.Thickness.Bottom}";
Add (borderBottomEdit);
var replaceBorder = new Button ("Replace all based on top") {
X = Pos.Left (borderLeftEdit),
Y = 5
};
replaceBorder.Clicked += (s, e) => {
smartView.Border.Thickness = new Thickness (smartView.Border.Thickness.Top);
if (borderTopEdit.Text.IsEmpty) {
borderTopEdit.Text = "0";
}
borderBottomEdit.Text = borderLeftEdit.Text = borderRightEdit.Text = borderTopEdit.Text;
};
Add (replaceBorder);
smartView.Y = Pos.Center () + 4;
Add (new Label ("BorderStyle:"));
var borderStyleEnum = Enum.GetValues (typeof (LineStyle)).Cast<LineStyle> ().ToList ();
var rbBorderStyle = new RadioGroup (borderStyleEnum.Select (
e => NStack.ustring.Make (e.ToString ())).ToArray ()) {
X = 2,
Y = 1,
SelectedItem = (int)smartView.BorderStyle
};
Add (rbBorderStyle);
rbBorderStyle.SelectedItemChanged += (s, e) => {
smartView.BorderStyle = (LineStyle)e.SelectedItem;
smartView.SetNeedsDisplay ();
};
Add (new Label ("Background:") {
Y = 12
});
var colorEnum = Enum.GetValues (typeof (Color)).Cast<Color> ().ToList ();
var rbBackground = new RadioGroup (colorEnum.Select (
e => NStack.ustring.Make (e.ToString ())).ToArray ()) {
X = 2,
Y = 13,
//SelectedItem = (int)smartView.BorderFrame.BackgroundColor
};
rbBackground.SelectedItemChanged += (s, e) => {
// smartView.Border.BackgroundColor = (Color)e.SelectedItem;
smartView.Border.ColorScheme = new ColorScheme() {
Normal = new Terminal.Gui.Attribute(Color.Red, Color.White),
HotNormal = new Terminal.Gui.Attribute (Color.Magenta, Color.White),
Disabled = new Terminal.Gui.Attribute (Color.Gray, Color.White),
Focus = new Terminal.Gui.Attribute (Color.Blue, Color.White),
HotFocus = new Terminal.Gui.Attribute (Color.BrightBlue, Color.White),
};
};
Add (rbBackground);
Add (new Label ("BorderBrush:") {
X = Pos.AnchorEnd (20),
Y = 5
});
var rbBorderBrush = new RadioGroup (colorEnum.Select (
e => NStack.ustring.Make (e.ToString ())).ToArray ()) {
X = Pos.AnchorEnd (18),
Y = 6,
//SelectedItem = (int)smartView.Border.ForgroundColor
};
rbBorderBrush.SelectedItemChanged += (s, e) => {
//smartView.Border.ForgroundColor = (Color)e.SelectedItem;
};
Add (rbBorderBrush);
Add (smartView);
Title = title;
}
}
}

View File

@@ -1,25 +0,0 @@
using Terminal.Gui;
namespace UICatalog.Scenarios {
[ScenarioMetadata (Name: "Borders on FrameView", Description: "Demonstrate FrameView borders manipulation.")]
[ScenarioCategory ("Layout")]
[ScenarioCategory ("Borders")]
public class BordersOnFrameView : Scenario {
public override void Init ()
{
Application.Init ();
var boc = new BordersOnContainers (
$"{Application.QuitKey} to Quit - Scenario: {GetName ()}",
"FrameView",
new FrameView ());
Application.Run (boc);
Application.Shutdown ();
}
public override void Run ()
{
}
}
}

View File

@@ -1,25 +0,0 @@
using Terminal.Gui;
namespace UICatalog.Scenarios {
[ScenarioMetadata (Name: "Borders on Window", Description: "Demonstrates Window borders manipulation.")]
[ScenarioCategory ("Layout")]
[ScenarioCategory ("Borders")]
public class BordersOnWindow : Scenario {
public override void Init ()
{
Application.Init ();
var boc = new BordersOnContainers (
$"{Application.QuitKey} to Quit - Scenario: {GetName ()}",
"Window",
new Window ());
Application.Run (boc);
Application.Shutdown ();
}
public override void Run ()
{
}
}
}

View File

@@ -19,17 +19,17 @@ namespace UICatalog.Scenarios {
/// <summary>
/// Foreground color label.
/// </summary>
private Label foregroundColorLabel;
private Label _foregroundColorLabel;
/// <summary>
/// Background color Label.
/// </summary>
private Label backgroundColorLabel;
private Label _backgroundColorLabel;
/// <summary>
/// Demo label.
/// </summary>
private Label demoLabel;
private View _demoView;
/// <summary>
/// Setup the scenario.
@@ -40,36 +40,57 @@ namespace UICatalog.Scenarios {
Win.Title = this.GetName ();
// Foreground ColorPicker.
foregroundColorPicker = new ColorPicker ("Foreground Color");
foregroundColorPicker = new ColorPicker () {
Title = "Foreground Color",
X = 0,
Y = 0,
BoxHeight = 3,
BoxWidth = 6,
BorderStyle = LineStyle.Single
};
foregroundColorPicker.ColorChanged += ForegroundColor_ColorChanged;
Win.Add (foregroundColorPicker);
foregroundColorLabel = new Label {
_foregroundColorLabel = new Label {
X = Pos.Left (foregroundColorPicker),
Y = Pos.Bottom (foregroundColorPicker) + 1
};
Win.Add (foregroundColorLabel);
Win.Add (_foregroundColorLabel);
// Background ColorPicker.
backgroundColorPicker = new ColorPicker ("Background Color");
backgroundColorPicker = new ColorPicker () {
Title = "Background Color",
Y = 0,
BoxHeight = 1,
BoxWidth = 4,
BorderStyle = LineStyle.Single
};
backgroundColorPicker.X = Pos.AnchorEnd () - (Pos.Right (backgroundColorPicker) - Pos.Left (backgroundColorPicker));
backgroundColorPicker.ColorChanged += BackgroundColor_ColorChanged;
Win.Add (backgroundColorPicker);
backgroundColorLabel = new Label ();
backgroundColorLabel.X = Pos.AnchorEnd () - (Pos.Right (backgroundColorLabel) - Pos.Left (backgroundColorLabel));
backgroundColorLabel.Y = Pos.Bottom (backgroundColorPicker) + 1;
Win.Add (backgroundColorLabel);
_backgroundColorLabel = new Label ();
_backgroundColorLabel.X = Pos.AnchorEnd () - (Pos.Right (_backgroundColorLabel) - Pos.Left (_backgroundColorLabel));
_backgroundColorLabel.Y = Pos.Bottom (backgroundColorPicker) + 1;
Win.Add (_backgroundColorLabel);
// Demo Label.
demoLabel = new Label ("Lorem Ipsum");
demoLabel.X = Pos.Center ();
demoLabel.Y = 1;
Win.Add (demoLabel);
_demoView = new View () {
Title = "Color Sample",
Text = "Lorem Ipsum",
TextAlignment = TextAlignment.Centered,
VerticalTextAlignment = VerticalTextAlignment.Middle,
BorderStyle = LineStyle.Heavy,
X = Pos.Center (),
Y = Pos.Center (),
Height = 5,
Width = 20
};
Win.Add (_demoView);
// Set default colors.
backgroundColorPicker.SelectedColor = demoLabel.SuperView.ColorScheme.Normal.Background;
foregroundColorPicker.SelectedColor = demoLabel.SuperView.ColorScheme.Normal.Foreground;
backgroundColorPicker.SelectedColor = _demoView.SuperView.ColorScheme.Normal.Background;
foregroundColorPicker.SelectedColor = _demoView.SuperView.ColorScheme.Normal.Foreground;
}
/// <summary>
@@ -77,7 +98,7 @@ namespace UICatalog.Scenarios {
/// </summary>
private void ForegroundColor_ColorChanged (object sender, EventArgs e)
{
UpdateColorLabel (foregroundColorLabel, foregroundColorPicker);
UpdateColorLabel (_foregroundColorLabel, foregroundColorPicker);
UpdateDemoLabel ();
}
@@ -86,7 +107,7 @@ namespace UICatalog.Scenarios {
/// </summary>
private void BackgroundColor_ColorChanged (object sender, EventArgs e)
{
UpdateColorLabel (backgroundColorLabel, backgroundColorPicker);
UpdateColorLabel (_backgroundColorLabel, backgroundColorPicker);
UpdateDemoLabel ();
}
@@ -102,7 +123,7 @@ namespace UICatalog.Scenarios {
/// <summary>
/// Update Demo Label.
/// </summary>
private void UpdateDemoLabel () => demoLabel.ColorScheme = new ColorScheme () {
private void UpdateDemoLabel () => _demoView.ColorScheme = new ColorScheme () {
Normal = new Terminal.Gui.Attribute (foregroundColorPicker.SelectedColor, backgroundColorPicker.SelectedColor)
};
}

View File

@@ -1,4 +1,5 @@
using System;
using NStack;
using System;
using System.Linq;
using Terminal.Gui;
@@ -7,245 +8,330 @@ namespace UICatalog.Scenarios {
[ScenarioCategory ("Layout")]
[ScenarioCategory ("Borders")]
public class Frames : Scenario {
public class FrameEditor : View {
private Thickness _thickness;
private TextField _topEdit;
private TextField _leftEdit;
private TextField _rightEdit;
private TextField _bottomEdit;
private bool _isUpdating;
public class ThicknessEditor : View {
private Thickness thickness;
private ColorPicker _foregroundColorPicker;
private ColorPicker _backgroundColorPicker;
public Terminal.Gui.Attribute Color { get; set; }
public Thickness Thickness {
get => thickness;
get => _thickness;
set {
thickness = value;
ThicknessChanged?.Invoke (this, new ThicknessEventArgs () { Thickness = Thickness });
if (_isUpdating) {
return;
}
_thickness = value;
ThicknessChanged?.Invoke (this, new ThicknessEventArgs () { Thickness = Thickness });
if (IsInitialized) {
_isUpdating = true;
if (_topEdit.Text != _thickness.Top.ToString ()) {
_topEdit.Text = _thickness.Top.ToString ();
}
if (_leftEdit.Text != _thickness.Left.ToString ()) {
_leftEdit.Text = _thickness.Left.ToString ();
}
if (_rightEdit.Text != _thickness.Right.ToString ()) {
_rightEdit.Text = _thickness.Right.ToString ();
}
if (_bottomEdit.Text != _thickness.Bottom.ToString ()) {
_bottomEdit.Text = _thickness.Bottom.ToString ();
}
_isUpdating = false;
}
}
}
public event EventHandler<ThicknessEventArgs> ThicknessChanged;
public event EventHandler<Terminal.Gui.Attribute> AttributeChanged;
public ThicknessEditor ()
public FrameEditor ()
{
Margin.Thickness = new Thickness (0);
BorderStyle = LineStyle.Single;
BorderStyle = LineStyle.Double;
Initialized += FrameEditor_Initialized; ;
}
public override void BeginInit ()
void FrameEditor_Initialized (object sender, EventArgs e)
{
base.BeginInit ();
var editWidth = 3;
var topEdit = new TextField ("") {
_topEdit = new TextField ("") {
X = Pos.Center (),
Y = 0,
Width = 5
Width = editWidth
};
topEdit.TextChanging += (s, e) => {
try {
Thickness = new Thickness (Thickness.Left,
int.Parse (e.NewText.ToString ()), Thickness.Right,
Thickness.Bottom);
} catch {
if (!e.NewText.IsEmpty) {
e.Cancel = true;
}
}
};
topEdit.Text = $"{Thickness.Top}";
_topEdit.TextChanging += Edit_TextChanging;
Add (_topEdit);
Add (topEdit);
_leftEdit = new TextField ("") {
X = Pos.Left (_topEdit) - editWidth,
Y = Pos.Bottom (_topEdit),
Width = editWidth
};
_leftEdit.TextChanging += Edit_TextChanging;
Add (_leftEdit);
var leftEdit = new TextField ("") {
X = 0,
Y = Pos.Bottom (topEdit),
Width = 5
_rightEdit = new TextField ("") {
X = Pos.Right (_topEdit),
Y = Pos.Bottom (_topEdit),
Width = editWidth
};
leftEdit.TextChanging += (s, e) => {
try {
Thickness = new Thickness (int.Parse (e.NewText.ToString ()),
Thickness.Top, Thickness.Right,
Thickness.Bottom);
} catch {
if (!e.NewText.IsEmpty) {
e.Cancel = true;
}
}
};
leftEdit.Text = $"{Thickness.Left}";
Add (leftEdit);
_rightEdit.TextChanging += Edit_TextChanging;
Add (_rightEdit);
var rightEdit = new TextField ("") {
X = Pos.Right (topEdit),
Y = Pos.Bottom (topEdit),
Width = 5
};
rightEdit.TextChanging += (s, e) => {
try {
Thickness = new Thickness (Thickness.Left,
Thickness.Top, int.Parse (e.NewText.ToString ()),
Thickness.Bottom);
} catch {
if (!e.NewText.IsEmpty) {
e.Cancel = true;
}
}
};
rightEdit.Text = $"{Thickness.Right}";
Add (rightEdit);
var bottomEdit = new TextField ("") {
_bottomEdit = new TextField ("") {
X = Pos.Center (),
Y = Pos.Bottom (leftEdit),
Width = 5
Y = Pos.Bottom (_leftEdit),
Width = editWidth
};
bottomEdit.TextChanging += (s, e) => {
try {
Thickness = new Thickness (Thickness.Left,
Thickness.Top, Thickness.Right,
int.Parse (e.NewText.ToString ()));
} catch {
if (!e.NewText.IsEmpty) {
e.Cancel = true;
}
}
};
bottomEdit.Text = $"{Thickness.Bottom}";
Add (bottomEdit);
_bottomEdit.TextChanging += Edit_TextChanging;
Add (_bottomEdit);
var copyTop = new Button ("Copy Top") {
X = Pos.Center (),
Y = Pos.AnchorEnd (1)
X = Pos.Center () + 1,
Y = Pos.Bottom (_bottomEdit)
};
copyTop.Clicked += (s, e) => {
Thickness = new Thickness (Thickness.Top);
if (topEdit.Text.IsEmpty) {
topEdit.Text = "0";
if (_topEdit.Text.IsEmpty) {
_topEdit.Text = "0";
}
bottomEdit.Text = leftEdit.Text = rightEdit.Text = topEdit.Text;
_bottomEdit.Text = _leftEdit.Text = _rightEdit.Text = _topEdit.Text;
};
Add (copyTop);
// Foreground ColorPicker.
_foregroundColorPicker = new ColorPicker () {
Title = "FG",
BoxWidth = 1,
BoxHeight = 1,
X = -1,
Y = Pos.Bottom (copyTop) + 1,
BorderStyle = LineStyle.Single,
SuperViewRendersLineCanvas = true
};
_foregroundColorPicker.ColorChanged += (o, a) =>
AttributeChanged?.Invoke (this,
new Terminal.Gui.Attribute (_foregroundColorPicker.SelectedColor, _backgroundColorPicker.SelectedColor));
Add (_foregroundColorPicker);
// Background ColorPicker.
_backgroundColorPicker = new ColorPicker () {
Title = "BG",
BoxWidth = 1,
BoxHeight = 1,
X = Pos.Right (_foregroundColorPicker) - 1,
Y = Pos.Top (_foregroundColorPicker),
BorderStyle = LineStyle.Single,
SuperViewRendersLineCanvas = true
};
_backgroundColorPicker.ColorChanged += (o, a) =>
AttributeChanged?.Invoke (this,
new Terminal.Gui.Attribute (
_foregroundColorPicker.SelectedColor,
_backgroundColorPicker.SelectedColor));
Add (_backgroundColorPicker);
_topEdit.Text = $"{Thickness.Top}";
_leftEdit.Text = $"{Thickness.Left}";
_rightEdit.Text = $"{Thickness.Right}";
_bottomEdit.Text = $"{Thickness.Bottom}";
LayoutSubviews ();
Height = Margin.Thickness.Vertical + Border.Thickness.Vertical + Padding.Thickness.Vertical + 4;
Width = 20;
Height = GetFramesThickness ().Vertical + 4 + 4;
Width = GetFramesThickness ().Horizontal + _foregroundColorPicker.Frame.Width * 2 - 3;
}
private void Edit_TextChanging (object sender, TextChangingEventArgs e)
{
try {
if (string.IsNullOrEmpty (e.NewText.ToString ())) {
e.Cancel = true;
((TextField)sender).Text = "0";
return;
}
switch (sender.ToString ()) {
case var s when s == _topEdit.ToString ():
Thickness = new Thickness (Thickness.Left,
int.Parse (e.NewText.ToString ()), Thickness.Right,
Thickness.Bottom);
break;
case var s when s == _leftEdit.ToString ():
Thickness = new Thickness (int.Parse (e.NewText.ToString ()),
Thickness.Top, Thickness.Right,
Thickness.Bottom);
break;
case var s when s == _rightEdit.ToString ():
Thickness = new Thickness (Thickness.Left,
Thickness.Top, int.Parse (e.NewText.ToString ()),
Thickness.Bottom);
break;
case var s when s == _bottomEdit.ToString ():
Thickness = new Thickness (Thickness.Left,
Thickness.Top, Thickness.Right,
int.Parse (e.NewText.ToString ()));
break;
}
} catch {
if (!e.NewText.IsEmpty) {
e.Cancel = true;
}
}
}
}
public class FramesEditor : Window {
public FramesEditor (NStack.ustring title, View viewToEdit)
private View _viewToEdit;
private FrameEditor _marginEditor;
private FrameEditor _borderEditor;
private FrameEditor _paddingEditor;
public FramesEditor (ustring title, View viewToEdit)
{
viewToEdit.Margin.ColorScheme = Colors.ColorSchemes ["Toplevel"];
var marginEditor = new ThicknessEditor () {
X = 20,
this._viewToEdit = viewToEdit;
viewToEdit.Margin.ColorScheme = new ColorScheme (Colors.ColorSchemes ["Toplevel"]);
_marginEditor = new FrameEditor () {
X = 0,
Y = 0,
Title = "Margin",
Thickness = viewToEdit.Margin.Thickness,
SuperViewRendersLineCanvas = true
};
marginEditor.ThicknessChanged += (s, a) => {
try {
viewToEdit.Margin.Thickness = a.Thickness;
} catch {
_marginEditor.ThicknessChanged += Editor_ThicknessChanged;
_marginEditor.AttributeChanged += Editor_AttributeChanged; ;
Add (_marginEditor);
viewToEdit.Margin.Thickness = a.PreviousThickness;
}
};
Add (marginEditor);
viewToEdit.Border.ColorScheme = Colors.ColorSchemes ["Base"];
var borderEditor = new ThicknessEditor () {
X = Pos.Right(marginEditor) - 1,
Y = 0,
viewToEdit.Border.ColorScheme = new ColorScheme (Colors.ColorSchemes ["Base"]);
_borderEditor = new FrameEditor () {
X = Pos.Left (_marginEditor),
Y = Pos.Bottom (_marginEditor),
Title = "Border",
Thickness = viewToEdit.Border.Thickness,
SuperViewRendersLineCanvas = true
};
borderEditor.ThicknessChanged += (s, a) => {
try {
viewToEdit.Border.Thickness = a.Thickness;
} catch {
viewToEdit.Border.Thickness = a.PreviousThickness;
}
};
Add (borderEditor);
_borderEditor.ThicknessChanged += Editor_ThicknessChanged;
_borderEditor.AttributeChanged += Editor_AttributeChanged;
Add (_borderEditor);
viewToEdit.Padding.ColorScheme = Colors.ColorSchemes ["Error"];
var paddingEditor = new ThicknessEditor () {
X = Pos.Right (borderEditor) - 1,
Y = 0,
Title = "Padding",
Thickness = viewToEdit.Padding.Thickness,
};
paddingEditor.ThicknessChanged += (s, a) => {
try {
viewToEdit.Padding.Thickness = a.Thickness;
} catch {
viewToEdit.Padding.Thickness = a.PreviousThickness;
}
};
Add (paddingEditor);
viewToEdit.Y = Pos.Center () + 4;
Add (new Label ("BorderStyle:"));
viewToEdit.Padding.ColorScheme = new ColorScheme (Colors.ColorSchemes ["Error"]);
var colorEnum = Enum.GetValues (typeof (Color)).Cast<Color> ().ToList ();
var borderStyleEnum = Enum.GetValues (typeof (LineStyle)).Cast<LineStyle> ().ToList ();
var rbBorderStyle = new RadioGroup (borderStyleEnum.Select (
e => NStack.ustring.Make (e.ToString ())).ToArray ()) {
X = 2,
Y = 1,
SelectedItem = (int)viewToEdit.Border.BorderStyle
X = Pos.Right (_borderEditor) - 1,
Y = Pos.Top (_borderEditor),
SelectedItem = (int)viewToEdit.Border.BorderStyle,
BorderStyle = LineStyle.Double,
Title = "Border Style",
SuperViewRendersLineCanvas = true
};
Add (rbBorderStyle);
rbBorderStyle.SelectedItemChanged += (s, e) => {
var prevBorderStyle = viewToEdit.BorderStyle;
viewToEdit.Border.BorderStyle = (LineStyle)e.SelectedItem;
if (viewToEdit.Border.BorderStyle == LineStyle.None) {
viewToEdit.Border.Thickness = new Thickness (0);
} else if (prevBorderStyle == LineStyle.None && viewToEdit.Border.BorderStyle != LineStyle.None) {
viewToEdit.Border.Thickness = new Thickness (1);
}
_borderEditor.Thickness = new Thickness (viewToEdit.Border.Thickness.Left, viewToEdit.Border.Thickness.Top,
viewToEdit.Border.Thickness.Right, viewToEdit.Border.Thickness.Bottom);
viewToEdit.SetNeedsDisplay ();
};
//Add (new Label ("Background:") {
// Y = 5
//});
var ckbTitle = new CheckBox ("Show Title") {
BorderStyle = LineStyle.Double,
X = Pos.Left (_borderEditor),
Y = Pos.Bottom (_borderEditor) - 1,
Width = Dim.Width (_borderEditor),
Checked = true,
SuperViewRendersLineCanvas = true
};
Add (ckbTitle);
//var colorEnum = Enum.GetValues (typeof (Color)).Cast<Color> ().ToList ();
//var rbBackground = new RadioGroup (colorEnum.Select (
// e => NStack.ustring.Make (e.ToString ())).ToArray ()) {
_paddingEditor = new FrameEditor () {
X = Pos.Left (_borderEditor),
Y = Pos.Bottom (rbBorderStyle),
Title = "Padding",
Thickness = viewToEdit.Padding.Thickness,
SuperViewRendersLineCanvas = true
};
_paddingEditor.ThicknessChanged += Editor_ThicknessChanged;
_paddingEditor.AttributeChanged += Editor_AttributeChanged;
Add (_paddingEditor);
// X = 2,
// Y = 6,
// SelectedItem = (int)viewToEdit.Border.BackgroundColor
//};
//rbBackground.SelectedItemChanged += (s, e) => {
// if (viewToEdit.Border != null) {
// viewToEdit.Border.BackgroundColor = (Color)e.SelectedItem;
// }
//};
//Add (rbBackground);
//Add (new Label ("BorderBrush:") {
// X = Pos.AnchorEnd (20),
// Y = 5
//});
//var rbBorderBrush = new RadioGroup (colorEnum.Select (
// e => NStack.ustring.Make (e.ToString ())).ToArray ()) {
// X = Pos.AnchorEnd (18),
// Y = 6,
// SelectedItem = (int)viewToEdit.Border.ForgroundColor
//};
//rbBorderBrush.SelectedItemChanged += (s, e) => {
// if (viewToEdit.Border != null) {
// viewToEdit.Border.ForgroundColor = (Color)e.SelectedItem;
// }
//};
//Add (rbBorderBrush);
viewToEdit.X = Pos.Center ();
viewToEdit.Y = Pos.Bottom (marginEditor);
viewToEdit.Width = 60;
viewToEdit.Height = 25;
viewToEdit.X = Pos.Right (rbBorderStyle);
viewToEdit.Y = 0;
viewToEdit.Width = Dim.Fill ();
viewToEdit.Height = Dim.Fill ();
Add (viewToEdit);
LayoutSubviews ();
viewToEdit.LayoutComplete += (s, e) => {
if (ckbTitle.Checked == true) {
viewToEdit.Title = viewToEdit.ToString ();
} else {
viewToEdit.Title = string.Empty;
}
};
Title = title;
}
private void Editor_AttributeChanged (object sender, Terminal.Gui.Attribute attr)
{
switch (sender.ToString ()) {
case var s when s == _marginEditor.ToString ():
_viewToEdit.Margin.ColorScheme = new ColorScheme (_viewToEdit.Margin.ColorScheme) { Normal = attr };
break;
case var s when s == _borderEditor.ToString ():
_viewToEdit.Border.ColorScheme = new ColorScheme (_viewToEdit.Border.ColorScheme) { Normal = attr };
break;
case var s when s == _paddingEditor.ToString ():
_viewToEdit.Padding.ColorScheme = new ColorScheme (_viewToEdit.Padding.ColorScheme) { Normal = attr };
break;
}
}
private void Editor_ThicknessChanged (object sender, ThicknessEventArgs e)
{
try {
switch (sender.ToString ()) {
case var s when s == _marginEditor.ToString ():
_viewToEdit.Margin.Thickness = e.Thickness;
break;
case var s when s == _borderEditor.ToString ():
_viewToEdit.Border.Thickness = e.Thickness;
break;
case var s when s == _paddingEditor.ToString ():
_viewToEdit.Padding.Thickness = e.Thickness;
break;
}
} catch {
switch (sender.ToString ()) {
case var s when s == _marginEditor.ToString ():
_viewToEdit.Margin.Thickness = e.PreviousThickness;
break;
case var s when s == _borderEditor.ToString ():
_viewToEdit.Border.Thickness = e.PreviousThickness;
break;
case var s when s == _paddingEditor.ToString ():
_viewToEdit.Padding.Thickness = e.PreviousThickness;
break;
}
}
}
}
public override void Init ()
@@ -256,34 +342,33 @@ namespace UICatalog.Scenarios {
Application.Top.ColorScheme = Colors.ColorSchemes [TopLevelColorScheme];
var view = new Window ();
var tf1 = new TextField ("1234567890") { Width = 10 };
var tf1 = new TextField ("TextField") { Width = 10 };
var button = new Button ("Press me!") {
X = Pos.Center (),
Y = Pos.Center (),
};
button.Clicked += (s, e) => MessageBox.Query (20, 7, "Hi", $"I'm a {view.GetType().Name}?", "Yes", "No");
button.Clicked += (s, e) => MessageBox.Query (20, 7, "Hi", $"Am I a {view.GetType ().Name}?", "Yes", "No");
var label = new Label ($"I'm a {view.GetType ().Name}") {
X = Pos.Center (),
Y = Pos.Center () - 1,
};
var tf2 = new TextField ("1234567890") {
var tf2 = new Button ("Button") {
X = Pos.AnchorEnd (10),
Y = Pos.AnchorEnd (1),
Width = 10
};
var tv = new TextView () {
var tv = new Label () {
Y = Pos.AnchorEnd (2),
Width = 10,
Width = 25,
Height = Dim.Fill (),
Text = "1234567890"
Text = "Label\nY=AnchorEnd(2),Height=Dim.Fill()"
};
view.Margin.Thickness = new Thickness (3);
view.Margin.ColorScheme = Colors.ColorSchemes ["Dialog"];
view.Padding.Thickness = new Thickness (1);
view.Add (tf1, button, label, tf2, tv);
view.LayoutComplete += (s, e) => view.Title = view.ToString ();
var editor = new FramesEditor (
$"{Application.QuitKey} to Quit - Scenario: {GetName ()}",

View File

@@ -3,253 +3,20 @@ using System.Linq;
using Terminal.Gui;
namespace UICatalog.Scenarios {
[ScenarioMetadata (Name: "_ View Experiments", Description: "v2 View Experiments")]
[ScenarioMetadata (Name: "View Experiments", Description: "v2 View Experiments")]
[ScenarioCategory ("Controls")]
public class ViewExperiments : Scenario {
public class ThicknessEditor : View {
private Thickness thickness;
public Thickness Thickness {
get => thickness;
set {
thickness = value;
ThicknessChanged?.Invoke (this, new ThicknessEventArgs () { Thickness = Thickness });
}
}
public event EventHandler<ThicknessEventArgs> ThicknessChanged;
public ThicknessEditor ()
{
Margin.Thickness = new Thickness (0);
Border.Thickness = new Thickness (1);
}
public override void BeginInit ()
{
base.BeginInit ();
var topEdit = new TextField ("") {
X = Pos.Center (),
Y = 0,
Width = 5
};
topEdit.TextChanging += (s, e) => {
try {
Thickness = new Thickness (Thickness.Left,
int.Parse (e.NewText.ToString ()), Thickness.Right,
Thickness.Bottom);
} catch {
if (!e.NewText.IsEmpty) {
e.Cancel = true;
}
}
};
topEdit.Text = $"{Thickness.Top}";
Add (topEdit);
var leftEdit = new TextField ("") {
X = 0,
Y = Pos.Bottom (topEdit),
Width = 5
};
leftEdit.TextChanging += (s, e) => {
try {
Thickness = new Thickness (int.Parse (e.NewText.ToString ()),
Thickness.Top, Thickness.Right,
Thickness.Bottom);
} catch {
if (!e.NewText.IsEmpty) {
e.Cancel = true;
}
}
};
leftEdit.Text = $"{Thickness.Left}";
Add (leftEdit);
var rightEdit = new TextField ("") {
X = Pos.Right (topEdit),
Y = Pos.Bottom (topEdit),
Width = 5
};
rightEdit.TextChanging += (s, e) => {
try {
Thickness = new Thickness (Thickness.Left,
Thickness.Top, int.Parse (e.NewText.ToString ()),
Thickness.Bottom);
} catch {
if (!e.NewText.IsEmpty) {
e.Cancel = true;
}
}
};
rightEdit.Text = $"{Thickness.Right}";
Add (rightEdit);
var bottomEdit = new TextField ("") {
X = Pos.Center (),
Y = Pos.Bottom (leftEdit),
Width = 5
};
bottomEdit.TextChanging += (s, e) => {
try {
Thickness = new Thickness (Thickness.Left,
Thickness.Top, Thickness.Right,
int.Parse (e.NewText.ToString ()));
} catch {
if (!e.NewText.IsEmpty) {
e.Cancel = true;
}
}
};
bottomEdit.Text = $"{Thickness.Bottom}";
Add (bottomEdit);
var copyTop = new Button ("Copy Top") {
X = Pos.Center (),
Y = Pos.AnchorEnd (1)
};
copyTop.Clicked += (s, e) => {
Thickness = new Thickness (Thickness.Top);
if (topEdit.Text.IsEmpty) {
topEdit.Text = "0";
}
bottomEdit.Text = leftEdit.Text = rightEdit.Text = topEdit.Text;
};
Add (copyTop);
//LayoutSubviews ();
Height = Margin.Thickness.Vertical + Border.Thickness.Vertical + Padding.Thickness.Vertical + 4;
Width = 20;
}
}
public class FramesEditor : Window {
public FramesEditor (NStack.ustring title, View viewToEdit)
{
viewToEdit.Margin.ColorScheme = Colors.ColorSchemes ["Toplevel"];
var marginEditor = new ThicknessEditor () {
X = 0,
Y = 0,
Title = "Margin",
Thickness = viewToEdit.Margin.Thickness,
};
marginEditor.Margin.Thickness = new Thickness (0, 0, 1, 0);
marginEditor.ThicknessChanged += (s, a) => {
viewToEdit.Margin.Thickness = a.Thickness;
};
Add (marginEditor);
viewToEdit.Border.ColorScheme = Colors.ColorSchemes ["Base"];
var borderEditor = new ThicknessEditor () {
X = Pos.Right (marginEditor),
Y = 0,
Title = "Border",
Thickness = viewToEdit.Border.Thickness,
};
borderEditor.Margin.Thickness = new Thickness (0, 0, 1, 0);
borderEditor.ThicknessChanged += (s, a) => {
viewToEdit.Border.Thickness = a.Thickness;
};
Add (borderEditor);
var styleLabel = new Label ("BorderStyle: ") {
X = Pos.Right (borderEditor),
Y = 0
};
Add (styleLabel);
var borderStyleEnum = Enum.GetValues (typeof (LineStyle)).Cast<LineStyle> ().ToList ();
var rbBorderStyle = new RadioGroup (borderStyleEnum.Select (
e => NStack.ustring.Make (e.ToString ())).ToArray ()) {
X = Pos.Left (styleLabel),
Y = Pos.Bottom (styleLabel),
SelectedItem = (int)viewToEdit.Border.BorderStyle
};
rbBorderStyle.SelectedItemChanged += (s, e) => {
viewToEdit.Border.BorderStyle = (LineStyle)e.SelectedItem;
viewToEdit.SetNeedsDisplay ();
};
Add (rbBorderStyle);
viewToEdit.Padding.ColorScheme = Colors.ColorSchemes ["Error"];
var paddingEditor = new ThicknessEditor () {
X = Pos.Right (styleLabel),
Y = 0,
Title = "Padding",
Thickness = viewToEdit.Padding.Thickness,
};
paddingEditor.ThicknessChanged += (s, a) => {
viewToEdit.Padding.Thickness = a.Thickness;
};
Add (paddingEditor);
viewToEdit.Y = Pos.Center () + 4;
//rbBorderStyle.SelectedItemChanged += (e) => {
// viewToEdit.Border.BorderStyle = (BorderStyle)e.SelectedItem;
// viewToEdit.SetNeedsDisplay ();
//};
//Add (new Label ("Background:") {
// Y = 5
//});
//var colorEnum = Enum.GetValues (typeof (Color)).Cast<Color> ().ToList ();
//var rbBackground = new RadioGroup (colorEnum.Select (
// e => NStack.ustring.Make (e.ToString ())).ToArray ()) {
// X = 2,
// Y = 6,
// SelectedItem = (int)viewToEdit.Border.BackgroundColor
//};
//rbBackground.SelectedItemChanged += (e) => {
// if (viewToEdit.Border != null) {
// viewToEdit.Border.BackgroundColor = (Color)e.SelectedItem;
// }
//};
//Add (rbBackground);
//Add (new Label ("BorderBrush:") {
// X = Pos.AnchorEnd (20),
// Y = 5
//});
//var rbBorderBrush = new RadioGroup (colorEnum.Select (
// e => NStack.ustring.Make (e.ToString ())).ToArray ()) {
// X = Pos.AnchorEnd (18),
// Y = 6,
// SelectedItem = (int)viewToEdit.Border.ForgroundColor
//};
//rbBorderBrush.SelectedItemChanged += (e) => {
// if (viewToEdit.Border != null) {
// viewToEdit.Border.ForgroundColor = (Color)e.SelectedItem;
// }
//};
//Add (rbBorderBrush);
Height = 8;
Title = title;
}
}
public override void Init ()
{
Application.Init ();
ConfigurationManager.Themes.Theme = Theme;
ConfigurationManager.Apply ();
Application.Top.ColorScheme = Colors.ColorSchemes [TopLevelColorScheme];
}
public override void Setup ()
{
//ConsoleDriver.Diagnostics |= ConsoleDriver.DiagnosticFlags.FramePadding;
var containerLabel = new Label () {
X = 0,
Y = 0,
@@ -270,11 +37,10 @@ namespace UICatalog.Scenarios {
//Application.Top.Add (view);
//view.InitializeFrames ();
view.Margin.Thickness = new Thickness (2, 2, 2, 2);
view.Margin.ColorScheme = Colors.ColorSchemes ["Toplevel"];
view.Margin.Data = "Margin";
view.Border.Thickness = new Thickness (2);
view.Border.Thickness = new Thickness (3);
view.Border.BorderStyle = LineStyle.Single;
view.Border.ColorScheme = view.ColorScheme;
view.Border.Data = "Border";
@@ -454,18 +220,13 @@ namespace UICatalog.Scenarios {
view.X = Pos.Center ();
var editor = new FramesEditor ($"Frame Editor", view) {
var editor = new Frames.FramesEditor ($"Frames Editor", view) {
X = 0,
Y = Pos.Bottom (containerLabel),
Width = Dim.Fill (),
};
Application.Top.Add (editor);
view.Y = Pos.Bottom (editor);
view.Width = Dim.Fill ();
view.Height = Dim.Fill ();
Application.Top.Add (view);
}
}
}

View File

@@ -181,6 +181,7 @@ namespace Terminal.Gui.DialogTests {
// This is because of PostionTopLevels and EnsureVisibleBounds
Assert.Equal (new Point (3, 2), d.Frame.Location);
Assert.Equal (new Size (17, 8), d.Frame.Size);
TestHelpers.AssertDriverContentsWithFrameAre (@"
╔══════════════════╗
║ ║

View File

@@ -288,7 +288,7 @@ namespace Terminal.Gui.DrawingTests {
}
[Fact ()]
public void GetInsideTests_Positive_Thickness_Non_Empty_Size()
public void GetInsideTests_Positive_Thickness_Non_Empty_Size ()
{
var t = new Thickness (1, 1, 1, 1);
@@ -493,7 +493,7 @@ namespace Terminal.Gui.DrawingTests {
Application.Top.Add (f);
Application.Begin (Application.Top);
((FakeDriver)Application.Driver).SetBufferSize (45, 20);
var t = new Thickness (0, 0, 0, 0);
var r = new Rect (2, 2, 40, 15);
@@ -633,4 +633,3 @@ namespace Terminal.Gui.DrawingTests {
}
}
}

View File

@@ -50,7 +50,7 @@ namespace Terminal.Gui.ViewTests {
[InlineData (3)]
public void Border_With_Title_Size_Height (int height)
{
var win = new Window () {
var win = new Window () {
Title = "1234",
Width = Dim.Fill (),
Height = Dim.Fill ()
@@ -93,7 +93,7 @@ namespace Terminal.Gui.ViewTests {
_ = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
}
[Theory, AutoInitShutdown]
[InlineData (0)]
[InlineData (1)]
@@ -195,7 +195,6 @@ namespace Terminal.Gui.ViewTests {
break;
}
_ = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
}
[Fact, AutoInitShutdown]
@@ -270,5 +269,338 @@ namespace Terminal.Gui.ViewTests {
_ = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
}
[Theory, AutoInitShutdown]
[InlineData (0)]
[InlineData (1)]
[InlineData (2)]
[InlineData (3)]
[InlineData (4)]
[InlineData (5)]
[InlineData (6)]
[InlineData (7)]
[InlineData (8)]
[InlineData (9)]
[InlineData (10)]
public void Border_With_Title_Border_Double_Thickness_Top_Two_Size_Width (int width)
{
var win = new Window () {
Title = "1234",
Width = Dim.Fill (),
Height = Dim.Fill (),
BorderStyle = LineStyle.Double,
};
win.Border.Thickness.Top = 2;
var rs = Application.Begin (win);
bool firstIteration = false;
((FakeDriver)Application.Driver).SetBufferSize (width, 4);
Application.RunMainLoopIteration (ref rs, true, ref firstIteration);
var expected = string.Empty;
switch (width) {
case 1:
Assert.Equal (new Rect (0, 0, 1, 4), win.Frame);
expected = @"
║";
break;
case 2:
Assert.Equal (new Rect (0, 0, 2, 4), win.Frame);
expected = @"
╔╗
║║
╚╝";
break;
case 3:
Assert.Equal (new Rect (0, 0, 3, 4), win.Frame);
expected = @"
╔═╗
║ ║
╚═╝";
break;
case 4:
Assert.Equal (new Rect (0, 0, 4, 4), win.Frame);
expected = @"
╒╕
╔╛╘╗
║ ║
╚══╝";
break;
case 5:
Assert.Equal (new Rect (0, 0, 5, 4), win.Frame);
expected = @"
╒═╕
╔╛1╘╗
║ ║
╚═══╝";
break;
case 6:
Assert.Equal (new Rect (0, 0, 6, 4), win.Frame);
expected = @"
╒══╕
╔╛12╘╗
║ ║
╚════╝";
break;
case 7:
Assert.Equal (new Rect (0, 0, 7, 4), win.Frame);
expected = @"
╒═══╕
╔╛123╘╗
║ ║
╚═════╝";
break;
case 8:
Assert.Equal (new Rect (0, 0, 8, 4), win.Frame);
expected = @"
╒════╕
╔╛1234╘╗
║ ║
╚══════╝";
break;
case 9:
Assert.Equal (new Rect (0, 0, 9, 4), win.Frame);
expected = @"
╒════╕
╔╛1234╘═╗
║ ║
╚═══════╝";
break;
case 10:
Assert.Equal (new Rect (0, 0, 10, 4), win.Frame);
expected = @"
╒════╕
╔╛1234╘══╗
║ ║
╚════════╝";
break;
}
_ = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
}
[Theory, AutoInitShutdown]
[InlineData (0)]
[InlineData (1)]
[InlineData (2)]
[InlineData (3)]
[InlineData (4)]
[InlineData (5)]
[InlineData (6)]
[InlineData (7)]
[InlineData (8)]
[InlineData (9)]
[InlineData (10)]
public void Border_With_Title_Border_Double_Thickness_Top_Three_Size_Width (int width)
{
var win = new Window () {
Title = "1234",
Width = Dim.Fill (),
Height = Dim.Fill (),
BorderStyle = LineStyle.Double,
};
win.Border.Thickness.Top = 3;
var rs = Application.Begin (win);
bool firstIteration = false;
((FakeDriver)Application.Driver).SetBufferSize (width, 4);
Application.RunMainLoopIteration (ref rs, true, ref firstIteration);
var expected = string.Empty;
switch (width) {
case 1:
Assert.Equal (new Rect (0, 0, 1, 4), win.Frame);
expected = @"
║";
break;
case 2:
Assert.Equal (new Rect (0, 0, 2, 4), win.Frame);
expected = @"
╔╗
║║
╚╝";
break;
case 3:
Assert.Equal (new Rect (0, 0, 3, 4), win.Frame);
expected = @"
╔═╗
║ ║
╚═╝";
break;
case 4:
Assert.Equal (new Rect (0, 0, 4, 4), win.Frame);
expected = @"
╒╕
╔╡╞╗
║╘╛║
╚══╝";
break;
case 5:
Assert.Equal (new Rect (0, 0, 5, 4), win.Frame);
expected = @"
╒═╕
╔╡1╞╗
║╘═╛║
╚═══╝";
break;
case 6:
Assert.Equal (new Rect (0, 0, 6, 4), win.Frame);
expected = @"
╒══╕
╔╡12╞╗
║╘══╛║
╚════╝";
break;
case 7:
Assert.Equal (new Rect (0, 0, 7, 4), win.Frame);
expected = @"
╒═══╕
╔╡123╞╗
║╘═══╛║
╚═════╝";
break;
case 8:
Assert.Equal (new Rect (0, 0, 8, 4), win.Frame);
expected = @"
╒════╕
╔╡1234╞╗
║╘════╛║
╚══════╝";
break;
case 9:
Assert.Equal (new Rect (0, 0, 9, 4), win.Frame);
expected = @"
╒════╕
╔╡1234╞═╗
║╘════╛ ║
╚═══════╝";
break;
case 10:
Assert.Equal (new Rect (0, 0, 10, 4), win.Frame);
expected = @"
╒════╕
╔╡1234╞══╗
║╘════╛ ║
╚════════╝";
break;
}
_ = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
}
[Theory, AutoInitShutdown]
[InlineData (0)]
[InlineData (1)]
[InlineData (2)]
[InlineData (3)]
[InlineData (4)]
[InlineData (5)]
[InlineData (6)]
[InlineData (7)]
[InlineData (8)]
[InlineData (9)]
[InlineData (10)]
public void Border_With_Title_Border_Double_Thickness_Top_Four_Size_Width (int width)
{
var win = new Window () {
Title = "1234",
Width = Dim.Fill (),
Height = Dim.Fill (),
BorderStyle = LineStyle.Double,
};
win.Border.Thickness.Top = 4;
var rs = Application.Begin (win);
bool firstIteration = false;
((FakeDriver)Application.Driver).SetBufferSize (width, 5);
Application.RunMainLoopIteration (ref rs, true, ref firstIteration);
var expected = string.Empty;
switch (width) {
case 1:
Assert.Equal (new Rect (0, 0, 1, 5), win.Frame);
expected = @"
║";
break;
case 2:
Assert.Equal (new Rect (0, 0, 2, 5), win.Frame);
expected = @"
╔╗
║║
╚╝";
break;
case 3:
Assert.Equal (new Rect (0, 0, 3, 5), win.Frame);
expected = @"
╔═╗
║ ║
╚═╝";
break;
case 4:
Assert.Equal (new Rect (0, 0, 4, 5), win.Frame);
expected = @"
╒╕
╔╡╞╗
║╘╛║
╚══╝";
break;
case 5:
Assert.Equal (new Rect (0, 0, 5, 5), win.Frame);
expected = @"
╒═╕
╔╡1╞╗
║╘═╛║
╚═══╝";
break;
case 6:
Assert.Equal (new Rect (0, 0, 6, 5), win.Frame);
expected = @"
╒══╕
╔╡12╞╗
║╘══╛║
╚════╝";
break;
case 7:
Assert.Equal (new Rect (0, 0, 7, 5), win.Frame);
expected = @"
╒═══╕
╔╡123╞╗
║╘═══╛║
╚═════╝";
break;
case 8:
Assert.Equal (new Rect (0, 0, 8, 5), win.Frame);
expected = @"
╒════╕
╔╡1234╞╗
║╘════╛║
╚══════╝";
break;
case 9:
Assert.Equal (new Rect (0, 0, 9, 5), win.Frame);
expected = @"
╒════╕
╔╡1234╞═╗
║╘════╛ ║
╚═══════╝";
break;
case 10:
Assert.Equal (new Rect (0, 0, 10, 5), win.Frame);
expected = @"
╒════╕
╔╡1234╞══╗
║╘════╛ ║
╚════════╝";
break;
}
_ = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
}
}
}

View File

@@ -563,7 +563,7 @@ namespace Terminal.Gui.ViewTests {
// BUGBUG: v2 - _needsDisplay needs debugging - test disabled for now.
//Assert.Equal (new Rect (new Point (0, 0), rect.Size), view._needsDisplay);
Assert.True (view.LayoutNeeded);
Assert.False (view._childNeedsDisplay);
Assert.False (view._subViewNeedsDisplay);
Assert.False (view._addingView);
view._addingView = true;
Assert.True (view._addingView);

View File

@@ -14,19 +14,11 @@ namespace Terminal.Gui.ViewsTests {
Assert.Equal (Color.Black, colorPicker.SelectedColor);
Assert.Equal (new Point (0, 0), colorPicker.Cursor);
Assert.True (colorPicker.CanFocus);
Assert.Equal (new Rect (0, 0, 32, 5), colorPicker.Frame);
colorPicker = new ColorPicker (5, 10, "Title");
Assert.Equal (Color.Black, colorPicker.SelectedColor);
Assert.Equal (new Point (0, 0), colorPicker.Cursor);
Assert.True (colorPicker.CanFocus);
Assert.Equal (new Rect (5, 10, 32, 5), colorPicker.Frame);
colorPicker = new ColorPicker (new Point (10, 15), "Title");
Assert.Equal (Color.Black, colorPicker.SelectedColor);
Assert.Equal (new Point (0, 0), colorPicker.Cursor);
Assert.True (colorPicker.CanFocus);
Assert.Equal (new Rect (10, 15, 32, 5), colorPicker.Frame);
colorPicker.BeginInit ();
colorPicker.EndInit ();
colorPicker.LayoutSubviews ();
Assert.Equal (new Rect (0, 0, 32, 4), colorPicker.Frame);
}
[Fact]

View File

@@ -35,7 +35,7 @@ namespace Terminal.Gui.ViewsTests {
Assert.Null (rg.Y);
Assert.Null (rg.Width);
Assert.Null (rg.Height);
Assert.Equal (new Rect (0, 0, 7, 1), rg.Frame);
Assert.Equal (new Rect (0, 0, 0, 0), rg.Frame);
Assert.Equal (0, rg.SelectedItem);
rg = new RadioGroup (new Rect (1, 2, 20, 5), new NStack.ustring [] { "Test" });
@@ -57,7 +57,7 @@ namespace Terminal.Gui.ViewsTests {
Assert.Null (rg.Y);
Assert.Null (rg.Width);
Assert.Null (rg.Height);
Assert.Equal (new Rect (1, 2, 7, 1), rg.Frame);
Assert.Equal (new Rect (1, 2, 6, 1), rg.Frame);
Assert.Equal (0, rg.SelectedItem);
}
@@ -76,8 +76,7 @@ namespace Terminal.Gui.ViewsTests {
var rg = new RadioGroup (new NStack.ustring [] { "Test", "New Test 你" });
var win = new Window () {
Width = Dim.Fill (),
Height = Dim.Fill (),
Title = "Test Demo 你"
Height = Dim.Fill ()
};
win.Add (rg);
Application.Top.Add (win);
@@ -89,10 +88,10 @@ namespace Terminal.Gui.ViewsTests {
Assert.Equal (2, rg.RadioLabels.Length);
Assert.Equal (0, rg.X);
Assert.Equal (0, rg.Y);
Assert.Equal (14, rg.Width);
Assert.Equal (2, rg.Height);
Assert.Equal (13, rg.Frame.Width);
Assert.Equal (2, rg.Frame.Height);
var expected = @"
┤Test Demo 你├──────────────┐
────────────────────────────┐
│● Test │
│◌ New Test 你 │
│ │
@@ -113,7 +112,7 @@ namespace Terminal.Gui.ViewsTests {
Assert.Equal (1, rg.Height);
expected = @"
┤Test Demo 你├──────────────┐
────────────────────────────┐
│● Test ◌ New Test 你 │
│ │
│ │
@@ -133,7 +132,7 @@ namespace Terminal.Gui.ViewsTests {
Assert.Equal (23, rg.Width);
Assert.Equal (1, rg.Height);
expected = @"
┤Test Demo 你├──────────────┐
────────────────────────────┐
│● Test ◌ New Test 你 │
│ │
│ │