From 379d7a849201f93bf0d416eca42fc2e2313dec71 Mon Sep 17 00:00:00 2001 From: BDisp Date: Sat, 25 Feb 2023 22:26:04 +0000 Subject: [PATCH] Fixes 2342. Border: can't change border color in window by Border.BorderBrush. (#2345) * Fixes 2342. Border: can't change border color in window by Border.BorderBrush. * Fixes border initialization. --------- Co-authored-by: Tig --- Terminal.Gui/Core/Border.cs | 63 +++++++++++++++++++---- Terminal.Gui/Core/ConsoleDriver.cs | 6 +-- Terminal.Gui/Core/Window.cs | 19 +++---- Terminal.Gui/Views/FrameView.cs | 14 +++-- UICatalog/Scenarios/BordersComparisons.cs | 5 +- UnitTests/Core/BorderTests.cs | 14 ++++- 6 files changed, 86 insertions(+), 35 deletions(-) diff --git a/Terminal.Gui/Core/Border.cs b/Terminal.Gui/Core/Border.cs index 2bf9244b6..a928681ff 100644 --- a/Terminal.Gui/Core/Border.cs +++ b/Terminal.Gui/Core/Border.cs @@ -331,6 +331,7 @@ namespace Terminal.Gui { private Point effect3DOffset = new Point (1, 1); private Attribute? effect3DBrush; private ustring title = ustring.Empty; + private View child; /// /// Specifies the for a view. @@ -447,8 +448,47 @@ namespace Terminal.Gui { /// /// Gets or sets the single child element of a . /// - [JsonIgnore] - public View Child { get; set; } + public View Child { + get => child; + set { + child = value; + if (child != null && Parent != null) { + Parent.Initialized += Parent_Initialized; + Parent.Removed += Parent_Removed; + } + } + } + + private void Parent_Removed (View obj) + { + BorderBrush = default; + Background = default; + child.Removed -= Parent_Removed; + } + + private void Parent_Initialized (object s, EventArgs e) + { + SetMarginFrameTitleBrush (); + child.Initialized -= Parent_Initialized; + } + + private void SetMarginFrameTitleBrush () + { + if (child != null) { + var view = Parent?.Border != null ? Parent : child; + if (view.ColorScheme != null) { + if (borderBrush == default) { + BorderBrush = view.GetNormalColor ().Foreground; + } + if (background == default) { + Background = view.GetNormalColor ().Background; + } + return; + } + } + BorderBrush = default; + Background = default; + } /// /// Gets the parent parent if any. @@ -611,7 +651,7 @@ namespace Terminal.Gui { Child.Clear (borderRect); } - driver.SetAttribute (savedAttribute); + driver.SetAttribute (new Attribute (BorderBrush, Background)); // Draw margin frame if (DrawMarginFrame) { @@ -635,6 +675,7 @@ namespace Terminal.Gui { driver.DrawWindowFrame (borderRect, 1, 1, 1, 1, BorderStyle != BorderStyle.None, fill: true, this); } } + driver.SetAttribute (savedAttribute); } private void DrawChildBorder (Rect frame, bool fill = true) @@ -747,7 +788,7 @@ namespace Terminal.Gui { } } - driver.SetAttribute (savedAttribute); + driver.SetAttribute (new Attribute (BorderBrush, Background)); // Draw the MarginFrame if (DrawMarginFrame) { @@ -944,7 +985,7 @@ namespace Terminal.Gui { } } - driver.SetAttribute (savedAttribute); + driver.SetAttribute (new Attribute (BorderBrush, Background)); // Draw the MarginFrame if (DrawMarginFrame) { @@ -1026,9 +1067,9 @@ namespace Terminal.Gui { { var driver = Application.Driver; if (DrawMarginFrame) { - driver.SetAttribute (Child.GetNormalColor ()); - if (Child.HasFocus) - driver.SetAttribute (Child.ColorScheme.HotNormal); + driver.SetAttribute (new Attribute (BorderBrush, Background)); + if (view.HasFocus) + driver.SetAttribute (new Attribute (Child.ColorScheme.HotNormal.Foreground, Background)); var padding = view.Border.GetSumThickness (); Rect scrRect; if (view == Child) { @@ -1037,7 +1078,7 @@ namespace Terminal.Gui { 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, + driver.DrawWindowTitle (scrRect, Parent.Border.Title, padding.Left, padding.Top, padding.Right, padding.Bottom); } } @@ -1053,9 +1094,9 @@ namespace Terminal.Gui { { var driver = Application.Driver; if (DrawMarginFrame) { - driver.SetAttribute (view.GetNormalColor ()); + driver.SetAttribute (new Attribute (BorderBrush, Background)); if (view.HasFocus) { - driver.SetAttribute (view.ColorScheme.HotNormal); + driver.SetAttribute (new Attribute (view.ColorScheme.HotNormal.Foreground, Background)); } var padding = Parent.Border.GetSumThickness (); var scrRect = Parent.ViewToScreen (new Rect (0, 0, rect.Width, rect.Height)); diff --git a/Terminal.Gui/Core/ConsoleDriver.cs b/Terminal.Gui/Core/ConsoleDriver.cs index e0527a6ce..1a815797b 100644 --- a/Terminal.Gui/Core/ConsoleDriver.cs +++ b/Terminal.Gui/Core/ConsoleDriver.cs @@ -89,7 +89,7 @@ namespace Terminal.Gui { } /// - /// + /// Indicates the RGB for true colors. /// public class TrueColor { /// @@ -119,7 +119,7 @@ namespace Terminal.Gui { } /// - /// + /// Converts true color to console color. /// /// public Color ToConsoleColor () @@ -504,7 +504,7 @@ namespace Terminal.Gui { public bool Equals (string x, string y) { if (x != null && y != null) { - return x.ToLowerInvariant () == y.ToLowerInvariant (); + return string.Equals (x, y, StringComparison.InvariantCultureIgnoreCase); } return false; } diff --git a/Terminal.Gui/Core/Window.cs b/Terminal.Gui/Core/Window.cs index ff9f3233b..d95b64d4d 100644 --- a/Terminal.Gui/Core/Window.cs +++ b/Terminal.Gui/Core/Window.cs @@ -38,6 +38,9 @@ namespace Terminal.Gui { if (!OnTitleChanging (title, value)) { var old = title; title = value; + if (Border != null) { + Border.Title = title; + } OnTitleChanged (old, title); } SetNeedsDisplay (); @@ -192,10 +195,13 @@ namespace Terminal.Gui { Border = new Border () { BorderStyle = DefaultBorderStyle, Padding = new Thickness (padding), - BorderBrush = ColorScheme.Normal.Background + Title = title }; } else { Border = border; + if (ustring.IsNullOrEmpty (border.Title)) { + border.Title = title; + } } AdjustContentView (frame); } @@ -287,9 +293,6 @@ namespace Terminal.Gui { /// public override void Redraw (Rect bounds) { - var padding = Border.GetSumThickness (); - var scrRect = ViewToScreen (new Rect (0, 0, Frame.Width, Frame.Height)); - if (!NeedDisplay.IsEmpty || ChildNeedsDisplay || LayoutNeeded) { Driver.SetAttribute (GetNormalColor ()); Clear (); @@ -298,7 +301,6 @@ namespace Terminal.Gui { var savedClip = contentView.ClipToBounds (); // Redraw our contentView - // DONE: smartly constrict contentView.Bounds to just be what intersects with the 'bounds' we were passed contentView.Redraw (!NeedDisplay.IsEmpty || ChildNeedsDisplay || LayoutNeeded ? contentView.Bounds : bounds); Driver.Clip = savedClip; @@ -306,14 +308,7 @@ namespace Terminal.Gui { ClearNeedsDisplay (); Driver.SetAttribute (GetNormalColor ()); - //Driver.DrawWindowFrame (scrRect, padding.Left + borderLength, padding.Top + borderLength, padding.Right + borderLength, padding.Bottom + borderLength, - // Border.BorderStyle != BorderStyle.None, fill: true, Border.BorderStyle); Border.DrawContent (this, false); - if (HasFocus) - Driver.SetAttribute (ColorScheme.HotNormal); - if (Border.DrawMarginFrame) - Driver.DrawWindowTitle (scrRect, Title, padding.Left, padding.Top, padding.Right, padding.Bottom); - Driver.SetAttribute (GetNormalColor ()); } /// diff --git a/Terminal.Gui/Views/FrameView.cs b/Terminal.Gui/Views/FrameView.cs index eb63f2f26..82123ea5e 100644 --- a/Terminal.Gui/Views/FrameView.cs +++ b/Terminal.Gui/Views/FrameView.cs @@ -67,6 +67,9 @@ namespace Terminal.Gui { get => title; set { title = value; + if (Border != null) { + Border.Title = title; + } SetNeedsDisplay (); } } @@ -160,9 +163,13 @@ namespace Terminal.Gui { if (border == null) { Border = new Border () { BorderStyle = DefaultBorderStyle - }; + Title = title + }; } else { Border = border; + if (ustring.IsNullOrEmpty (border.Title)) { + border.Title = title; + } } AdjustContentView (frame, views); } @@ -261,12 +268,8 @@ namespace Terminal.Gui { /// public override void Redraw (Rect bounds) { - var padding = Border.GetSumThickness (); - var scrRect = ViewToScreen (new Rect (0, 0, Frame.Width, Frame.Height)); - if (!NeedDisplay.IsEmpty) { Driver.SetAttribute (GetNormalColor ()); - //Driver.DrawWindowFrame (scrRect, padding + 1, padding + 1, padding + 1, padding + 1, border: true, fill: true); Clear (); } @@ -274,6 +277,7 @@ namespace Terminal.Gui { contentView.Redraw (!NeedDisplay.IsEmpty ? contentView.Bounds : bounds); Driver.Clip = savedClip; + ClearLayoutNeeded (); ClearNeedsDisplay (); if (!IgnoreBorderPropertyOnRedraw) { diff --git a/UICatalog/Scenarios/BordersComparisons.cs b/UICatalog/Scenarios/BordersComparisons.cs index 20964b5b7..3ea642d3b 100644 --- a/UICatalog/Scenarios/BordersComparisons.cs +++ b/UICatalog/Scenarios/BordersComparisons.cs @@ -12,9 +12,10 @@ namespace UICatalog.Scenarios { var borderStyle = BorderStyle.Double; var drawMarginFrame = false; var borderThickness = new Thickness (1, 2, 3, 4); - var borderBrush = Colors.Base.HotFocus.Foreground; + var borderBrush = Color.BrightMagenta; + ; var padding = new Thickness (1, 2, 3, 4); - var background = Colors.Base.HotNormal.Foreground; + var background = Color.Cyan; var effect3D = true; var win = new Window (new Rect (5, 5, 40, 20), "Test", 8, diff --git a/UnitTests/Core/BorderTests.cs b/UnitTests/Core/BorderTests.cs index bcd6bf67e..c59b085ce 100644 --- a/UnitTests/Core/BorderTests.cs +++ b/UnitTests/Core/BorderTests.cs @@ -228,7 +228,12 @@ namespace Terminal.Gui.CoreTests { var color = (Attribute)driver.Contents [r, c, 1]; var rune = (Rune)driver.Contents [r, c, 0]; - Assert.Equal (Color.Black, color.Background); + if (r == frame.Y - drawMarginFrame || r == frame.Bottom + drawMarginFrame - 1 + || c == frame.X - drawMarginFrame || c == frame.Right + drawMarginFrame - 1) { + Assert.Equal (Color.BrightGreen, color.Background); + } else { + Assert.Equal (Color.Black, color.Background); + } if (c == frame.X - drawMarginFrame && r == frame.Y - drawMarginFrame) { Assert.Equal (uLCorner, rune); } else if (c == frame.Right && r == frame.Y - drawMarginFrame) { @@ -457,7 +462,12 @@ namespace Terminal.Gui.CoreTests { var color = (Attribute)driver.Contents [r, c, 1]; var rune = (Rune)driver.Contents [r, c, 0]; - Assert.Equal (Color.Black, color.Background); + if (r == frame.Y + sumThickness.Top || r == frame.Bottom - sumThickness.Bottom - 1 + || c == frame.X + sumThickness.Left || c == frame.Right - sumThickness.Right - 1) { + Assert.Equal (Color.BrightGreen, color.Background); + } else { + Assert.Equal (Color.Black, color.Background); + } if (c == frame.X + sumThickness.Left && r == frame.Y + sumThickness.Top) { Assert.Equal (uLCorner, rune); } else if (c == frame.Right - drawMarginFrame - sumThickness.Right