diff --git a/Terminal.Gui/Drawing/Thickness.cs b/Terminal.Gui/Drawing/Thickness.cs index d96ab73ea..ba9acc87d 100644 --- a/Terminal.Gui/Drawing/Thickness.cs +++ b/Terminal.Gui/Drawing/Thickness.cs @@ -88,9 +88,10 @@ public record struct Thickness /// Thickness. /// /// 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 Rectangle Draw (Rectangle rect, string label = null) + public Rectangle Draw (Rectangle rect, ViewDiagnosticFlags diagnosticFlags = ViewDiagnosticFlags.Off, string label = null) { if (rect.Size.Width < 1 || rect.Size.Height < 1) { @@ -103,7 +104,7 @@ public record struct Thickness Rune topChar = clearChar; Rune bottomChar = clearChar; - if (View.Diagnostics.HasFlag (ViewDiagnosticFlags.Padding)) + if (diagnosticFlags.HasFlag (ViewDiagnosticFlags.Padding)) { leftChar = (Rune)'L'; rightChar = (Rune)'R'; @@ -155,7 +156,7 @@ public record struct Thickness ); } - if (View.Diagnostics.HasFlag (ViewDiagnosticFlags.Ruler)) + if (diagnosticFlags.HasFlag (ViewDiagnosticFlags.Ruler)) { // PERF: This can almost certainly be simplified down to a single point offset and fewer calls to Draw // Top @@ -187,7 +188,7 @@ public record struct Thickness } } - if (View.Diagnostics.HasFlag (ViewDiagnosticFlags.Padding)) + if (diagnosticFlags.HasFlag (ViewDiagnosticFlags.Padding)) { // Draw the diagnostics label on the bottom string text = label is null ? string.Empty : $"{label} {this}"; diff --git a/Terminal.Gui/View/Adornment/Adornment.cs b/Terminal.Gui/View/Adornment/Adornment.cs index d04d61359..248c88feb 100644 --- a/Terminal.Gui/View/Adornment/Adornment.cs +++ b/Terminal.Gui/View/Adornment/Adornment.cs @@ -42,6 +42,11 @@ public class Adornment : View #region Thickness + /// + /// + /// + public ViewDiagnosticFlags Diagnostics { get; set; } = View.Diagnostics; + private Thickness _thickness = Thickness.Empty; /// Defines the rectangle that the will use to draw its content. @@ -51,6 +56,7 @@ public class Adornment : View set { Thickness current = _thickness; + _thickness = value; if (current != _thickness) @@ -154,7 +160,7 @@ public class Adornment : View Driver?.SetAttribute (normalAttr); // This just draws/clears the thickness, not the insides. - Thickness.Draw (screen, ToString ()); + Thickness.Draw (screen, Diagnostics, ToString ()); if (!string.IsNullOrEmpty (TextFormatter.Text)) { diff --git a/Terminal.Gui/View/Adornment/Margin.cs b/Terminal.Gui/View/Adornment/Margin.cs index 97dc0f093..2a7593659 100644 --- a/Terminal.Gui/View/Adornment/Margin.cs +++ b/Terminal.Gui/View/Adornment/Margin.cs @@ -86,7 +86,7 @@ public class Margin : Adornment } // This just draws/clears the thickness, not the insides. - Thickness.Draw (screen, ToString ()); + Thickness.Draw (screen, Diagnostics, ToString ()); if (Subviews.Count > 0) { diff --git a/Terminal.Gui/View/Layout/PosAlign.cs b/Terminal.Gui/View/Layout/PosAlign.cs index f54a48c79..ee0bca119 100644 --- a/Terminal.Gui/View/Layout/PosAlign.cs +++ b/Terminal.Gui/View/Layout/PosAlign.cs @@ -1,6 +1,7 @@ #nullable enable using System.ComponentModel; +using System.Text.RegularExpressions; namespace Terminal.Gui; @@ -123,7 +124,7 @@ public record PosAlign : Pos } else { - groupViews = us.SuperView!.Subviews; + groupViews = us.SuperView!.Subviews.Where (v => HasGroupId (v, dimension, GroupId)).ToList (); } AlignAndUpdateGroup (GroupId, groupViews, dimension, superviewDimension); diff --git a/Terminal.Gui/View/View.Adornments.cs b/Terminal.Gui/View/View.Adornments.cs index 0c3220752..67729e349 100644 --- a/Terminal.Gui/View/View.Adornments.cs +++ b/Terminal.Gui/View/View.Adornments.cs @@ -142,7 +142,7 @@ public partial class View // Adornments LineStyle old = Border?.LineStyle ?? LineStyle.None; CancelEventArgs e = new (ref old, ref value); - if (OnBorderStyleChanging (e)|| e.Cancel) + if (OnBorderStyleChanging (e) || e.Cancel) { return; } diff --git a/Terminal.Gui/View/View.Layout.cs b/Terminal.Gui/View/View.Layout.cs index a2f9d5bb1..d64c6676c 100644 --- a/Terminal.Gui/View/View.Layout.cs +++ b/Terminal.Gui/View/View.Layout.cs @@ -352,6 +352,7 @@ public partial class View // Layout APIs { // Implicit layout is ok here because all Pos/Dim are Absolute values. Layout (); + SetLayoutNeeded (); } } } @@ -406,6 +407,7 @@ public partial class View // Layout APIs { // Implicit layout is ok here because all Pos/Dim are Absolute values. Layout (); + SetLayoutNeeded (); } } } @@ -463,6 +465,7 @@ public partial class View // Layout APIs { // Implicit layout is ok here because all Pos/Dim are Absolute values. Layout (); + SetLayoutNeeded (); } } } @@ -521,6 +524,7 @@ public partial class View // Layout APIs { // Implicit layout is ok here because all Pos/Dim are Absolute values. Layout (); + SetLayoutNeeded (); } } } @@ -554,7 +558,7 @@ public partial class View // Layout APIs { LayoutSubviews (); - Debug.Assert(!NeedsLayout); + // Debug.Assert(!NeedsLayout); return true; } diff --git a/Terminal.Gui/Views/Bar.cs b/Terminal.Gui/Views/Bar.cs index be81134e2..8cc5e3176 100644 --- a/Terminal.Gui/Views/Bar.cs +++ b/Terminal.Gui/Views/Bar.cs @@ -31,7 +31,7 @@ public class Bar : View, IOrientation, IDesignable _orientationHelper.OrientationChanging += (sender, e) => OrientationChanging?.Invoke (this, e); _orientationHelper.OrientationChanged += (sender, e) => OrientationChanged?.Invoke (this, e); - // Initialized += Bar_Initialized; + // Initialized += Bar_Initialized; MouseEvent += OnMouseEvent; if (shortcuts is null) @@ -120,7 +120,8 @@ public class Bar : View, IOrientation, IDesignable /// public void OnOrientationChanged (Orientation newOrientation) { - LayoutBarItems (SuperView?.GetContentSize() ?? Application.Screen.Size); + // BUGBUG: this should not be SuperView.GetContentSize + LayoutBarItems (SuperView?.GetContentSize () ?? Application.Screen.Size); } #endregion @@ -136,6 +137,7 @@ public class Bar : View, IOrientation, IDesignable set { _alignmentModes = value; + SetNeedsDisplay (); SetLayoutNeeded (); } } @@ -164,6 +166,7 @@ public class Bar : View, IOrientation, IDesignable } SetNeedsDisplay (); + SetLayoutNeeded (); } // TODO: Move this to View @@ -187,6 +190,7 @@ public class Bar : View, IOrientation, IDesignable { Remove (toRemove); SetNeedsDisplay (); + SetLayoutNeeded (); } return toRemove as Shortcut; @@ -221,63 +225,72 @@ public class Bar : View, IOrientation, IDesignable break; case Orientation.Vertical: - // Set the overall size of the Bar and arrange the views vertically - - var minKeyWidth = 0; - - List shortcuts = Subviews.Where (s => s is Shortcut && s.Visible).Cast ().ToList (); - foreach (Shortcut shortcut in shortcuts) + if (Width!.Has (out _)) { - // Let DimAuto do its thing to get the minimum width of each CommandView and HelpView - //shortcut.CommandView.SetRelativeLayout (new Size (int.MaxValue, int.MaxValue)); - minKeyWidth = int.Max (minKeyWidth, shortcut.KeyView.Text.GetColumns ()); + // Set the overall size of the Bar and arrange the views vertically + + var minKeyWidth = 0; + + List shortcuts = Subviews.Where (s => s is Shortcut && s.Visible).Cast ().ToList (); + + foreach (Shortcut shortcut in shortcuts) + { + // Get the largest width of all KeyView's + minKeyWidth = int.Max (minKeyWidth, shortcut.KeyView.Text.GetColumns ()); + } + + var _maxBarItemWidth = 0; + + for (var index = 0; index < Subviews.Count; index++) + { + View barItem = Subviews [index]; + + barItem.X = 0; + + barItem.ColorScheme = ColorScheme; + + if (!barItem.Visible) + { + continue; + } + + if (barItem is Shortcut scBarItem) + { + scBarItem.MinimumKeyTextSize = minKeyWidth; + scBarItem.Width = scBarItem.GetWidthDimAuto (); + barItem.Layout (Application.Screen.Size); + _maxBarItemWidth = Math.Max (_maxBarItemWidth, barItem.Frame.Width); + } + + if (prevBarItem == null) + { + // TODO: Just use Pos.Align! + barItem.Y = 0; + } + else + { + // TODO: Just use Pos.Align! + // Align the view to the bottom of the previous view + barItem.Y = Pos.Bottom (prevBarItem); + } + + prevBarItem = barItem; + + } + + foreach (var subView in Subviews) + { + subView.Width = Dim.Auto (DimAutoStyle.Auto, minimumContentDim: _maxBarItemWidth); + } } - - var _maxBarItemWidth = 0; - var totalHeight = 0; - - for (var index = 0; index < Subviews.Count; index++) + else { - View barItem = Subviews [index]; - - barItem.ColorScheme = ColorScheme; - - if (!barItem.Visible) + foreach (var subView in Subviews) { - continue; + subView.Width = Dim.Fill(); } - - if (barItem is Shortcut scBarItem) - { - scBarItem.MinimumKeyTextSize = minKeyWidth; - - _maxBarItemWidth = Math.Max (_maxBarItemWidth, scBarItem.Frame.Width); - } - - if (prevBarItem == null) - { - barItem.Y = 0; - } - else - { - // Align the view to the bottom of the previous view - barItem.Y = Pos.Bottom (prevBarItem); - } - - prevBarItem = barItem; - - barItem.X = 0; - totalHeight += barItem.Frame.Height; } - - foreach (View barItem in Subviews) - { - barItem.Width = _maxBarItemWidth; - } - - Height = Dim.Auto (DimAutoStyle.Content, totalHeight); - break; } } diff --git a/Terminal.Gui/Views/ColorPicker.16.cs b/Terminal.Gui/Views/ColorPicker.16.cs index 6c9ee05e3..5504e623e 100644 --- a/Terminal.Gui/Views/ColorPicker.16.cs +++ b/Terminal.Gui/Views/ColorPicker.16.cs @@ -67,8 +67,12 @@ public class ColorPicker16 : View /// Moves the selected item index to the next row. /// - public virtual bool MoveDown () + private bool MoveDown (CommandContext ctx) { + if (RaiseSelecting (ctx) == true) + { + return true; + } if (Cursor.Y < _rows - 1) { SelectedColor += _cols; @@ -79,8 +83,13 @@ public class ColorPicker16 : View /// Moves the selected item index to the previous column. /// - public virtual bool MoveLeft () + private bool MoveLeft (CommandContext ctx) { + if (RaiseSelecting (ctx) == true) + { + return true; + } + if (Cursor.X > 0) { SelectedColor--; @@ -91,8 +100,12 @@ public class ColorPicker16 : View /// Moves the selected item index to the next column. /// - public virtual bool MoveRight () + private bool MoveRight (CommandContext ctx) { + if (RaiseSelecting (ctx) == true) + { + return true; + } if (Cursor.X < _cols - 1) { SelectedColor++; @@ -103,8 +116,12 @@ public class ColorPicker16 : View /// Moves the selected item index to the previous row. /// - public virtual bool MoveUp () + private bool MoveUp (CommandContext ctx) { + if (RaiseSelecting (ctx) == true) + { + return true; + } if (Cursor.Y > 0) { SelectedColor -= _cols; @@ -164,13 +181,24 @@ public class ColorPicker16 : View /// Add the commands. private void AddCommands () { - AddCommand (Command.Left, () => MoveLeft ()); - AddCommand (Command.Right, () => MoveRight ()); - AddCommand (Command.Up, () => MoveUp ()); - AddCommand (Command.Down, () => MoveDown ()); + AddCommand (Command.Left, (ctx) => MoveLeft (ctx)); + AddCommand (Command.Right, (ctx) => MoveRight (ctx)); + AddCommand (Command.Up, (ctx) => MoveUp (ctx)); + AddCommand (Command.Down, (ctx) => MoveDown (ctx)); + + AddCommand (Command.Select, (ctx) => + { + bool set = false; + if (ctx.Data is MouseEventArgs me) + { + Cursor = new (me.Position.X / _boxWidth, me.Position.Y / _boxHeight); + set = true; + } + return RaiseAccepting (ctx) == true || set; + }); } - /// Add the KeyBindinds. + /// Add the KeyBindings. private void AddKeyBindings () { KeyBindings.Add (Key.CursorLeft, Command.Left); @@ -181,15 +209,6 @@ public class ColorPicker16 : View // TODO: Decouple Cursor from SelectedColor so that mouse press-and-hold can show the color under the cursor. - private void ColorPicker_MouseClick (object sender, MouseEventArgs me) - { - // if (CanFocus) - { - Cursor = new (me.Position.X / _boxWidth, me.Position.Y / _boxHeight); - SetFocus (); - me.Handled = true; - } - } /// Draw a box for one color. /// X location. @@ -265,7 +284,5 @@ public class ColorPicker16 : View Width = Dim.Auto (minimumContentDim: _boxWidth * _cols); Height = Dim.Auto (minimumContentDim: _boxHeight * _rows); SetContentSize (new (_boxWidth * _cols, _boxHeight * _rows)); - - MouseClick += ColorPicker_MouseClick; } } diff --git a/Terminal.Gui/Views/HexView.cs b/Terminal.Gui/Views/HexView.cs index 8c614062b..2a247875d 100644 --- a/Terminal.Gui/Views/HexView.cs +++ b/Terminal.Gui/Views/HexView.cs @@ -198,6 +198,7 @@ public class HexView : View, IDesignable Address = 0; } + SetLayoutNeeded (); SetNeedsDisplay (); } } @@ -577,6 +578,8 @@ public class HexView : View, IDesignable /// protected void RaisePositionChanged () { + SetNeedsDisplay (); + HexViewEventArgs args = new (Address, Position, BytesPerLine); OnPositionChanged (args); PositionChanged?.Invoke (this, args); diff --git a/Terminal.Gui/Views/RadioGroup.cs b/Terminal.Gui/Views/RadioGroup.cs index f929d0ce5..6e5830b05 100644 --- a/Terminal.Gui/Views/RadioGroup.cs +++ b/Terminal.Gui/Views/RadioGroup.cs @@ -52,9 +52,9 @@ public class RadioGroup : View, IDesignable, IOrientation // Accept (Enter key) - Raise Accept event - DO NOT advance state AddCommand (Command.Accept, RaiseAccepting); - // Hotkey - ctx may indicate a radio item hotkey was pressed. Beahvior depends on HasFocus + // Hotkey - ctx may indicate a radio item hotkey was pressed. Behavior depends on HasFocus // If HasFocus and it's this.HotKey invoke Select command - DO NOT raise Accept - // If it's a radio item HotKey select that item and raise Seelcted event - DO NOT raise Accept + // If it's a radio item HotKey select that item and raise Selected event - DO NOT raise Accept // If nothing is selected, select first and raise Selected event - DO NOT raise Accept AddCommand (Command.HotKey, ctx => diff --git a/Terminal.Gui/Views/Shortcut.cs b/Terminal.Gui/Views/Shortcut.cs index 21523ad69..dcb886c86 100644 --- a/Terminal.Gui/Views/Shortcut.cs +++ b/Terminal.Gui/Views/Shortcut.cs @@ -96,6 +96,10 @@ public class Shortcut : View, IOrientation, IDesignable HighlightStyle = HighlightStyle.None; CanFocus = true; + + SuperViewRendersLineCanvas = true; + Border.Settings &= ~BorderSettings.Title; + Width = GetWidthDimAuto (); Height = Dim.Auto (DimAutoStyle.Content, 1); @@ -111,8 +115,9 @@ public class Shortcut : View, IOrientation, IDesignable { Id = "CommandView", Width = Dim.Auto (), - Height = Dim.Auto (DimAutoStyle.Auto, 1) + Height = Dim.Fill() }; + Title = commandText ?? string.Empty; HelpView.Id = "_helpView"; HelpView.CanFocus = false; @@ -120,36 +125,31 @@ public class Shortcut : View, IOrientation, IDesignable KeyView.Id = "_keyView"; KeyView.CanFocus = false; - - LayoutStarted += OnLayoutStarted; - key ??= Key.Empty; Key = key; - Title = commandText ?? string.Empty; + Action = action; - SuperViewRendersLineCanvas = true; - Border.Settings &= ~BorderSettings.Title; + LayoutStarted += OnLayoutStarted; ShowHide (); } // Helper to set Width consistently - private Dim GetWidthDimAuto () + public Dim GetWidthDimAuto () { - // TODO: PosAlign.CalculateMinDimension is a hack. Need to figure out a better way of doing this. return Dim.Auto ( DimAutoStyle.Content, - Dim.Func (() => PosAlign.CalculateMinDimension (0, Subviews, Dimension.Width)), - Dim.Func (() => PosAlign.CalculateMinDimension (0, Subviews, Dimension.Width)))!; - } + minimumContentDim: Dim.Func (() => _minimumNaturalWidth ?? 0), + maximumContentDim: Dim.Func (() => _minimumNaturalWidth ?? 0))!; +} private AlignmentModes _alignmentModes = AlignmentModes.StartToEnd | AlignmentModes.IgnoreFirstOrLast; // This is used to calculate the minimum width of the Shortcut when Width is NOT Dim.Auto // It is calculated by setting Width to DimAuto temporarily and forcing layout. // Once Frame.Width gets below this value, LayoutStarted makes HelpView an KeyView smaller. - private int? _minimumNatrualWidth; + private int? _minimumNaturalWidth; /// protected override bool OnHighlight (CancelEventArgs args) @@ -208,60 +208,48 @@ public class Shortcut : View, IOrientation, IDesignable SetKeyViewDefaultLayout (); } - // Force Width to DimAuto to calculate natural width and then set it back - Dim? savedDim = Width; - Width = GetWidthDimAuto (); - // Force a SRL) - CommandView.SetRelativeLayout (Application.Screen.Size); - HelpView.SetRelativeLayout (Application.Screen.Size); - KeyView.SetRelativeLayout (Application.Screen.Size); - SetRelativeLayout (Application.Screen.Size); - _minimumNatrualWidth = Frame.Width; - Width = savedDim; - SetColors (); } + // Force Width to DimAuto to calculate natural width and then set it back + private void ForceCalculateNaturalWidth () + { + // Get the natural size of each subview + CommandView.SetRelativeLayout (Application.Screen.Size); + HelpView.SetRelativeLayout (Application.Screen.Size); + KeyView.SetRelativeLayout (Application.Screen.Size); + + _minimumNaturalWidth = PosAlign.CalculateMinDimension (0, Subviews, Dimension.Width); + + // Reset our relative layout + SetRelativeLayout (SuperView?.GetContentSize() ?? Application.Screen.Size); + } + + // TODO: Enable setting of the margin thickness private Thickness GetMarginThickness () { return new (1, 0, 1, 0); } - private int _maxHelpWidth = 0; // When layout starts, we need to adjust the layout of the HelpView and KeyView private void OnLayoutStarted (object? sender, LayoutEventArgs e) { + ShowHide (); + ForceCalculateNaturalWidth (); + if (Width is DimAuto widthAuto) { - _minimumNatrualWidth = Frame.Width; - } + + } else { - if (string.IsNullOrEmpty (HelpView.Text)) - { - return; - } - - int currentWidth = Frame.Width; - - // Frame.Width is smaller than the natural width. Reduce width of HelpView first. - // Then KeyView. - // Don't ever reduce CommandView (it should spill). - // TODO: Add Unit tests for this. - int delta = _minimumNatrualWidth.Value - currentWidth; - _maxHelpWidth = int.Max (0, GetContentSize().Width - CommandView.Frame.Width - KeyView.Frame.Width); + // Frame.Width is smaller than the natural width. Reduce width of HelpView. + _maxHelpWidth = int.Max (0, GetContentSize ().Width - CommandView.Frame.Width - KeyView.Frame.Width); if (_maxHelpWidth < 3) { Thickness t = GetMarginThickness (); switch (_maxHelpWidth) { - case 2: - - // Scrunch just the right margin - HelpView.Margin.Thickness = new (t.Right, t.Top, t.Left - 1, t.Bottom); - - break; - case 0: case 1: // Scrunch it by removing both margins @@ -269,6 +257,12 @@ public class Shortcut : View, IOrientation, IDesignable break; + case 2: + + // Scrunch just the right margin + HelpView.Margin.Thickness = new (t.Right, t.Top, t.Left - 1, t.Bottom); + + break; } } else @@ -276,7 +270,6 @@ public class Shortcut : View, IOrientation, IDesignable // Reset to default HelpView.Margin.Thickness = GetMarginThickness (); } - KeyView.SetLayoutNeeded(); } } @@ -472,7 +465,7 @@ public class Shortcut : View, IOrientation, IDesignable _commandView.Selecting += CommandViewOnSelecting; _commandView.Accepting += CommandViewOnAccepted; - ShowHide (); + //ShowHide (); UpdateKeyBindings (Key.Empty); return; @@ -500,8 +493,11 @@ public class Shortcut : View, IOrientation, IDesignable { CommandView.Margin.Thickness = GetMarginThickness (); CommandView.X = Pos.Align (Alignment.End, AlignmentModes); - CommandView.Y = 0; //Pos.Center (); - HelpView.HighlightStyle = HighlightStyle.None; + + CommandView.VerticalTextAlignment = Alignment.Center; + CommandView.TextAlignment = Alignment.Start; + CommandView.TextFormatter.WordWrap = false; + CommandView.HighlightStyle = HighlightStyle.None; } private void Shortcut_TitleChanged (object? sender, EventArgs e) @@ -516,6 +512,9 @@ public class Shortcut : View, IOrientation, IDesignable #region Help + // The maximum width of the HelpView. Calculated in OnLayoutStarted and used in HelpView.Width (Dim.Auto/Func). + private int _maxHelpWidth = 0; + /// /// The subview that displays the help text for the command. Internal for unit testing. /// @@ -525,10 +524,9 @@ public class Shortcut : View, IOrientation, IDesignable { HelpView.Margin.Thickness = GetMarginThickness (); HelpView.X = Pos.Align (Alignment.End, AlignmentModes); - HelpView.Y = 0; //Pos.Center (); _maxHelpWidth = HelpView.Text.GetColumns (); HelpView.Width = Dim.Auto (DimAutoStyle.Text, maximumContentDim: Dim.Func ((() => _maxHelpWidth))); - HelpView.Height = CommandView?.Visible == true ? Dim.Height (CommandView) : 1; + HelpView.Height = Dim.Fill (); HelpView.Visible = true; HelpView.VerticalTextAlignment = Alignment.Center; @@ -644,6 +642,8 @@ public class Shortcut : View, IOrientation, IDesignable _minimumKeyTextSize = value; SetKeyViewDefaultLayout (); + + // TODO: Prob not needed CommandView.SetLayoutNeeded (); HelpView.SetLayoutNeeded (); KeyView.SetLayoutNeeded (); @@ -656,9 +656,8 @@ public class Shortcut : View, IOrientation, IDesignable { KeyView.Margin.Thickness = GetMarginThickness (); KeyView.X = Pos.Align (Alignment.End, AlignmentModes); - KeyView.Y = 0; KeyView.Width = Dim.Auto (DimAutoStyle.Text, minimumContentDim: Dim.Func (() => MinimumKeyTextSize)); - KeyView.Height = CommandView?.Visible == true ? Dim.Height (CommandView) : 1; + KeyView.Height = Dim.Fill (); KeyView.Visible = true; @@ -706,11 +705,12 @@ public class Shortcut : View, IOrientation, IDesignable get => base.ColorScheme; set { - base.ColorScheme = value; + base.ColorScheme = _nonFocusColorScheme = value; SetColors (); } } + private ColorScheme? _nonFocusColorScheme; /// /// internal void SetColors (bool highlight = false) @@ -718,11 +718,16 @@ public class Shortcut : View, IOrientation, IDesignable // Border should match superview. if (Border is { }) { - Border.ColorScheme = SuperView?.ColorScheme; + // Border.ColorScheme = SuperView?.ColorScheme; } if (HasFocus || highlight) { + if (_nonFocusColorScheme is null) + { + _nonFocusColorScheme = base.ColorScheme; + } + base.ColorScheme ??= new (Attribute.Default); // When we have focus, we invert the colors @@ -736,7 +741,15 @@ public class Shortcut : View, IOrientation, IDesignable } else { - base.ColorScheme = SuperView?.ColorScheme ?? base.ColorScheme; + if (_nonFocusColorScheme is { }) + { + base.ColorScheme = _nonFocusColorScheme; + //_nonFocusColorScheme = null; + } + else + { + base.ColorScheme = SuperView?.ColorScheme ?? base.ColorScheme; + } } // Set KeyView's colors to show "hot" diff --git a/UICatalog/Scenarios/AllViewsTester.cs b/UICatalog/Scenarios/AllViewsTester.cs index 0392ee7a1..804ab8c3c 100644 --- a/UICatalog/Scenarios/AllViewsTester.cs +++ b/UICatalog/Scenarios/AllViewsTester.cs @@ -50,7 +50,6 @@ public class AllViewsTester : Scenario { // Don't create a sub-win (Scenario.Win); just use Application.Top Application.Init (); - // ConfigurationManager.Apply (); var app = new Window { @@ -315,8 +314,11 @@ public class AllViewsTester : Scenario Height = Dim.Fill (), // + 1 for status bar CanFocus = true, TabStop = TabBehavior.TabGroup, - ColorScheme = Colors.ColorSchemes ["Dialog"] + ColorScheme = Colors.ColorSchemes ["Base"] }; + _hostPane.Padding.Thickness = new (1); + _hostPane.Padding.Diagnostics = ViewDiagnosticFlags.Ruler; + _hostPane.Padding.ColorScheme = Colors.ColorSchemes ["Error"]; _hostPane.LayoutStarted += (sender, args) => { diff --git a/UICatalog/Scenarios/Bars.cs b/UICatalog/Scenarios/Bars.cs index b0d226148..7a4f388b8 100644 --- a/UICatalog/Scenarios/Bars.cs +++ b/UICatalog/Scenarios/Bars.cs @@ -136,6 +136,7 @@ public class Bars : Scenario Y = Pos.Bottom (label), }; ConfigureMenu (bar); + bar.Arrangement = ViewArrangement.RightResizable; menuLikeExamples.Add (bar); diff --git a/UICatalog/Scenarios/HexEditor.cs b/UICatalog/Scenarios/HexEditor.cs index 134f8d410..2aa32c905 100644 --- a/UICatalog/Scenarios/HexEditor.cs +++ b/UICatalog/Scenarios/HexEditor.cs @@ -41,6 +41,7 @@ public class HexEditor : Scenario Title = _fileName ?? "Untitled", BorderStyle = LineStyle.Rounded, }; + _hexView.Arrangement = ViewArrangement.Resizable; _hexView.Edited += _hexView_Edited; _hexView.PositionChanged += _hexView_PositionChanged; app.Add (_hexView); diff --git a/UICatalog/Scenarios/PosAlignDemo.cs b/UICatalog/Scenarios/PosAlignDemo.cs index 765a8e452..69f8de760 100644 --- a/UICatalog/Scenarios/PosAlignDemo.cs +++ b/UICatalog/Scenarios/PosAlignDemo.cs @@ -399,9 +399,10 @@ public sealed class PosAlignDemo : Scenario var v = new View { Title = $"{i}", + Text = $"{i}", BorderStyle = LineStyle.Dashed, - Height = 3, - Width = 5 + Height = Dim.Auto (), + Width = Dim.Auto() + 2 }; v.X = Pos.Align (widthAligner.Alignment, widthAligner.AlignmentModes, i / 3); diff --git a/UICatalog/Scenarios/Shortcuts.cs b/UICatalog/Scenarios/Shortcuts.cs index 5fd8ee760..cdc7e2269 100644 --- a/UICatalog/Scenarios/Shortcuts.cs +++ b/UICatalog/Scenarios/Shortcuts.cs @@ -38,6 +38,7 @@ public class Shortcuts : Scenario var eventLog = new ListView { + Id = "eventLog", X = Pos.AnchorEnd (), Y = 0, Height = Dim.Fill (4), @@ -46,70 +47,35 @@ public class Shortcuts : Scenario BorderStyle = LineStyle.Double, Title = "E_vents" }; - eventLog.Width = Dim.Func (() => Math.Min (Application.Top.Viewport.Width / 2, eventLog?.MaxLength + eventLog.GetAdornmentsThickness ().Horizontal ?? 0)); + eventLog.Width = Dim.Func (() => Math.Min (eventLog.SuperView!.Viewport.Width / 2, eventLog?.MaxLength + eventLog.GetAdornmentsThickness ().Horizontal ?? 0)); Application.Top.Add (eventLog); - var vShortcut1 = new Shortcut + var alignKeysShortcut = new Shortcut { + Id = "alignKeysShortcut", X = 0, + Y = 0, Width = Dim.Fill () - Dim.Width (eventLog), - Title = "A_pp Shortcut", - Key = Key.F1, - Text = "Width is DimFIll", - KeyBindingScope = KeyBindingScope.Application, - }; - - Application.Top.Add (vShortcut1); - - var vShortcut2 = new Shortcut - { - X = 0, - Y = Pos.Bottom (vShortcut1), - Width = 35, - Key = Key.F2, - Text = "Width is 35", - KeyBindingScope = KeyBindingScope.HotKey, - CommandView = new RadioGroup - { - Orientation = Orientation.Vertical, - RadioLabels = ["O_ne", "T_wo", "Th_ree", "Fo_ur"], - CanFocus = false - }, - }; - - ((RadioGroup)vShortcut2.CommandView).SelectedItemChanged += (o, args) => - { - eventSource.Add ($"SelectedItemChanged: {o.GetType ().Name} - {args.SelectedItem}"); - eventLog.MoveDown (); - }; - - Application.Top.Add (vShortcut2); - - var vShortcut3 = new Shortcut - { - X = 0, - Y = Pos.Bottom (vShortcut2), + HelpText = "Fill to log", CommandView = new CheckBox { - Text = "_Align", + Text = "_Align Keys", CanFocus = false, HighlightStyle = HighlightStyle.None, }, Key = Key.F5.WithCtrl.WithAlt.WithShift, - HelpText = "Width is Fill", - Width = Dim.Fill () - Dim.Width (eventLog), KeyBindingScope = KeyBindingScope.HotKey, }; - ((CheckBox)vShortcut3.CommandView).CheckedStateChanging += (s, e) => + ((CheckBox)alignKeysShortcut.CommandView).CheckedStateChanging += (s, e) => { - if (vShortcut3.CommandView is CheckBox cb) + if (alignKeysShortcut.CommandView is CheckBox cb) { - eventSource.Add ($"{vShortcut3.Id}.CommandView.CheckedStateChanging: {cb.Text}"); + eventSource.Add ($"{alignKeysShortcut.Id}.CommandView.CheckedStateChanging: {cb.Text}"); eventLog.MoveDown (); var max = 0; - IEnumerable toAlign = Application.Top.Subviews.Where (v => v is Shortcut { Orientation: Orientation.Vertical, Width: not DimAbsolute }); + IEnumerable toAlign = Application.Top.Subviews.Where (v => v is Shortcut { Width: not DimAbsolute }); IEnumerable enumerable = toAlign as View [] ?? toAlign.ToArray (); if (e.NewValue == CheckState.Checked) @@ -117,9 +83,7 @@ public class Shortcuts : Scenario foreach (var view in enumerable) { var peer = (Shortcut)view; - - // DANGER: KeyView is internal so we can't access it. So we assume this is how it works. - max = Math.Max (max, peer.Key.ToString ().GetColumns ()); + max = Math.Max (max, peer.KeyView.Text.GetColumns ()); } } @@ -130,149 +94,245 @@ public class Shortcuts : Scenario } } }; - Application.Top.Add (vShortcut3); + Application.Top.Add (alignKeysShortcut); - var vShortcut4 = new Shortcut + var commandFirstShortcut = new Shortcut { - Orientation = Orientation.Vertical, + Id = "commandFirstShortcut", X = 0, - Y = Pos.Bottom (vShortcut3), - Width = Dim.Width (vShortcut3), + Y = Pos.Bottom (alignKeysShortcut), + Width = Dim.Fill () - Dim.Width (eventLog), + HelpText = "Show Command first", + CommandView = new CheckBox + { + Text = "Command _First", + CanFocus = false, + HighlightStyle = HighlightStyle.None, + }, + Key = Key.F.WithCtrl, + KeyBindingScope = KeyBindingScope.HotKey, + }; + ((CheckBox)commandFirstShortcut.CommandView).CheckedState = + commandFirstShortcut.AlignmentModes.HasFlag (AlignmentModes.EndToStart) ? CheckState.UnChecked : CheckState.Checked; + + ((CheckBox)commandFirstShortcut.CommandView).CheckedStateChanging += (s, e) => + { + if (commandFirstShortcut.CommandView is CheckBox cb) + { + eventSource.Add ($"{commandFirstShortcut.Id}.CommandView.CheckedStateChanging: {cb.Text}"); + eventLog.MoveDown (); + + var max = 0; + IEnumerable toAlign = Application.Top.Subviews.Where (v => v is Shortcut { Width: not DimAbsolute }); + IEnumerable enumerable = toAlign as View [] ?? toAlign.ToArray (); + + foreach (var view in enumerable) + { + var peer = (Shortcut)view; + if (e.NewValue == CheckState.Checked) + { + peer.AlignmentModes &= ~AlignmentModes.EndToStart; + } + else + { + peer.AlignmentModes |= AlignmentModes.EndToStart; + } + } + } + }; + + Application.Top.Add (commandFirstShortcut); + + var canFocusShortcut = new Shortcut + { + Id = "canFocusShortcut", + X = 0, + Y = Pos.Bottom (commandFirstShortcut), + Width = Dim.Fill () - Dim.Width (eventLog), + Key = Key.F4, + HelpText = "Changes all Command.CanFocus", + KeyBindingScope = KeyBindingScope.HotKey, + CommandView = new CheckBox { Text = "_CanFocus" }, + }; + + ((CheckBox)canFocusShortcut.CommandView).CheckedStateChanging += (s, e) => + { + if (canFocusShortcut.CommandView is CheckBox cb) + { + eventSource.Add ($"Toggle: {cb.Text}"); + eventLog.MoveDown (); + //cb.CanFocus = e.NewValue == CheckState.Checked; + + foreach (Shortcut peer in Application.Top.Subviews.Where (v => v is Shortcut)!) + { + if (peer.CanFocus) + { + peer.CommandView.CanFocus = e.NewValue == CheckState.Checked; + } + } + } + }; + Application.Top.Add (canFocusShortcut); + + var appShortcut = new Shortcut + { + Id = "appShortcut", + X = 0, + Y = Pos.Bottom (canFocusShortcut), + Width = Dim.Fill (Dim.Func (() => eventLog.Frame.Width)), + Title = "A_pp Shortcut", + Key = Key.F1, + Text = "Width is DimFill", + KeyBindingScope = KeyBindingScope.Application, + }; + + Application.Top.Add (appShortcut); + + + var buttonShortcut = new Shortcut + { + Id = "buttonShortcut", + X = 0, + Y = Pos.Bottom (appShortcut), + Width = Dim.Fill () - Dim.Width (eventLog), + HelpText = "Accepting pops MB", CommandView = new Button { Title = "_Button", ShadowStyle = ShadowStyle.None, HighlightStyle = HighlightStyle.None }, - HelpText = "Width is Fill", Key = Key.K, KeyBindingScope = KeyBindingScope.HotKey, }; - var button = (Button)vShortcut4.CommandView; - vShortcut4.Accepting += Button_Clicked; + var button = (Button)buttonShortcut.CommandView; + buttonShortcut.Accepting += Button_Clicked; - Application.Top.Add (vShortcut4); + Application.Top.Add (buttonShortcut); - var vShortcut5 = new Shortcut + + var radioGroupShortcut = new Shortcut { - Orientation = Orientation.Vertical, + Id = "radioGroupShortcut", X = 0, - Y = Pos.Bottom (vShortcut4), - Width = Dim.Width (vShortcut4), - - Key = Key.F4, - HelpText = "CommandView.CanFocus", + Y = Pos.Bottom (buttonShortcut), + Key = Key.F2, + Width = Dim.Fill () - Dim.Width (eventLog), KeyBindingScope = KeyBindingScope.HotKey, - CommandView = new CheckBox { Text = "_CanFocus" }, - }; - - ((CheckBox)vShortcut5.CommandView).CheckedStateChanging += (s, e) => - { - if (vShortcut5.CommandView is CheckBox cb) - { - eventSource.Add ($"Toggle: {cb.Text}"); - eventLog.MoveDown (); - - //foreach (Shortcut peer in Application.Top.Subviews.Where (v => v is Shortcut)!) - //{ - // if (peer.CanFocus) - // { - // peer.CommandView.CanFocus = e.NewValue == CheckState.Checked; - // } - //} - } - }; - Application.Top.Add (vShortcut5); - - var vShortcutSlider = new Shortcut - { - Orientation = Orientation.Vertical, - X = 0, - Y = Pos.Bottom (vShortcut5), - HelpText = "Width is Fill", - Width = Dim.Width (vShortcut5), - - KeyBindingScope = KeyBindingScope.HotKey, - CommandView = new Slider + CommandView = new RadioGroup { Orientation = Orientation.Vertical, + RadioLabels = ["O_ne", "T_wo", "Th_ree", "Fo_ur"], + }, + }; + + ((RadioGroup)radioGroupShortcut.CommandView).SelectedItemChanged += (o, args) => + { + eventSource.Add ($"SelectedItemChanged: {o.GetType ().Name} - {args.SelectedItem}"); + eventLog.MoveDown (); + }; + + Application.Top.Add (radioGroupShortcut); + + var sliderShortcut = new Shortcut + { + Id = "sliderShortcut", + X = 0, + Y = Pos.Bottom (radioGroupShortcut), + Width = Dim.Fill () - Dim.Width (eventLog), + KeyBindingScope = KeyBindingScope.HotKey, + HelpText = "Sliders work!", + CommandView = new Slider + { + Orientation = Orientation.Horizontal, AllowEmpty = true }, Key = Key.F5, }; - ((Slider)vShortcutSlider.CommandView).Options = new () { new () { Legend = "A" }, new () { Legend = "B" }, new () { Legend = "C" } }; - ((Slider)vShortcutSlider.CommandView).SetOption (0); + ((Slider)sliderShortcut.CommandView).Options = new () { new () { Legend = "A" }, new () { Legend = "B" }, new () { Legend = "C" } }; + ((Slider)sliderShortcut.CommandView).SetOption (0); - ((Slider)vShortcutSlider.CommandView).OptionsChanged += (o, args) => + ((Slider)sliderShortcut.CommandView).OptionsChanged += (o, args) => { eventSource.Add ($"OptionsChanged: {o.GetType ().Name} - {string.Join (",", ((Slider)o).GetSetOptions ())}"); eventLog.MoveDown (); }; - Application.Top.Add (vShortcutSlider); + Application.Top.Add (sliderShortcut); - var vShortcut6 = new Shortcut + + var noCommandShortcut = new Shortcut { - Orientation = Orientation.Vertical, + Id = "noCommandShortcut", X = 0, - Y = Pos.Bottom (vShortcutSlider), - Width = Dim.Width (vShortcutSlider), + Y = Pos.Bottom (sliderShortcut), + Width = Dim.Width (sliderShortcut), + HelpText = "No Command", + Key = Key.D0 + }; - Title = "_No Key", + Application.Top.Add (noCommandShortcut); + + var noKeyShortcut = new Shortcut + { + Id = "noKeyShortcut", + X = 0, + Y = Pos.Bottom (noCommandShortcut), + Width = Dim.Width (noCommandShortcut), + + Title = "No Ke_y", HelpText = "Keyless", }; - Application.Top.Add (vShortcut6); + Application.Top.Add (noKeyShortcut); - var vShortcut7 = new Shortcut + var noHelpShortcut = new Shortcut { - Orientation = Orientation.Vertical, + Id = "noHelpShortcut", X = 0, - Y = Pos.Bottom (vShortcut6), - Width = Dim.Width (vShortcutSlider), + Y = Pos.Bottom (noKeyShortcut), + Width = Dim.Width (noKeyShortcut), Key = Key.F6, Title = "Not _very much help", HelpText = "", }; - Application.Top.Add (vShortcut7); - vShortcut7.SetFocus (); + Application.Top.Add (noHelpShortcut); + noHelpShortcut.SetFocus (); var framedShortcut = new Shortcut { + Id = "framedShortcut", X = 0, - Y = Pos.Bottom(vShortcut7) + 1, - Width = Dim.Auto(), - Title = "C", - Key = Key.K, - Text = "H", + Y = Pos.Bottom (noHelpShortcut) + 1, + Title = "Framed", + Key = Key.K.WithCtrl, + Text = "Resize frame", BorderStyle = LineStyle.Dotted, - Arrangement = ViewArrangement.Resizable, - CanFocus = false, - // Orientation = Orientation.Horizontal, - //AlignmentModes = AlignmentModes.EndToStart - + Arrangement = ViewArrangement.RightResizable | ViewArrangement.BottomResizable, }; framedShortcut.Orientation = Orientation.Horizontal; framedShortcut.Padding.Thickness = new (0, 1, 0, 0); + framedShortcut.Padding.Diagnostics = ViewDiagnosticFlags.Ruler; framedShortcut.CommandView.Margin.ColorScheme = framedShortcut.CommandView.ColorScheme = Colors.ColorSchemes ["Error"]; framedShortcut.HelpView.Margin.ColorScheme = framedShortcut.HelpView.ColorScheme = Colors.ColorSchemes ["Dialog"]; framedShortcut.KeyView.Margin.ColorScheme = framedShortcut.KeyView.ColorScheme = Colors.ColorSchemes ["Menu"]; + framedShortcut.ColorScheme = Colors.ColorSchemes ["Toplevel"]; Application.Top.Add (framedShortcut); // Horizontal - var hShortcut1 = new Shortcut + var progressShortcut = new Shortcut { + Id = "progressShortcut", X = Pos.Align (Alignment.Start, AlignmentModes.IgnoreFirstOrLast, 1), - Y = Pos.Bottom (eventLog) + 1, + Y = Pos.AnchorEnd () - 1, Key = Key.F7, HelpText = "Horizontal", - CanFocus = false }; - hShortcut1.CommandView = new ProgressBar + progressShortcut.CommandView = new ProgressBar { Text = "Progress", Title = "P", @@ -281,9 +341,9 @@ public class Shortcuts : Scenario Height = 1, ProgressBarStyle = ProgressBarStyle.Continuous }; - hShortcut1.CommandView.Width = 10; - hShortcut1.CommandView.Height = 1; - hShortcut1.CommandView.CanFocus = false; + progressShortcut.CommandView.Width = 10; + progressShortcut.CommandView.Height = 1; + progressShortcut.CommandView.CanFocus = false; Timer timer = new (10) { @@ -291,7 +351,7 @@ public class Shortcuts : Scenario }; timer.Elapsed += (o, args) => { - if (hShortcut1.CommandView is ProgressBar pb) + if (progressShortcut.CommandView is ProgressBar pb) { if (pb.Fraction == 1.0) { @@ -306,73 +366,91 @@ public class Shortcuts : Scenario }; timer.Start (); - Application.Top.Add (hShortcut1); + Application.Top.Add (progressShortcut); var textField = new TextField () { Text = "Edit me", Width = 10, Height = 1, - CanFocus = true }; - var hShortcut2 = new Shortcut + var textFieldShortcut = new Shortcut { - Orientation = Orientation.Horizontal, + Id = "textFieldShortcut", X = Pos.Align (Alignment.Start, AlignmentModes.IgnoreFirstOrLast, 1), - Y = Pos.Top (hShortcut1), + Y = Pos.AnchorEnd () - 1, Key = Key.F8, HelpText = "TextField", CanFocus = true, CommandView = textField, }; + textField.CanFocus = true; - Application.Top.Add (hShortcut2); + Application.Top.Add (textFieldShortcut); - var hShortcutBG = new Shortcut + var bgColorShortcut = new Shortcut { - Orientation = Orientation.Horizontal, - X = Pos.Align (Alignment.Start, AlignmentModes.IgnoreFirstOrLast, 1) - 1, - Y = Pos.Top (hShortcut2), + Id = "bgColorShortcut", + X = Pos.Align (Alignment.Start, AlignmentModes.IgnoreFirstOrLast, 1), + Y = Pos.AnchorEnd (), Key = Key.F9, - HelpText = "BG Color", - CanFocus = false + HelpText = "Cycles BG Color", }; var bgColor = new ColorPicker16 () { BoxHeight = 1, BoxWidth = 1, - CanFocus = false }; + + bgColorShortcut.Selecting += (o, args) => + { + //args.Cancel = true; + }; + + bgColorShortcut.Accepting += (o, args) => + { + if (bgColor.SelectedColor == ColorName16.White) + { + bgColor.SelectedColor = ColorName16.Black; + + return; + } + bgColor.SelectedColor++; + args.Cancel = true; + }; + bgColor.ColorChanged += (o, args) => { + eventSource.Add ($"ColorChanged: {o.GetType ().Name} - {args.CurrentValue}"); + eventLog.MoveDown (); + Application.Top.ColorScheme = new ColorScheme (Application.Top.ColorScheme) { Normal = new Attribute (Application.Top.ColorScheme.Normal.Foreground, args.CurrentValue), }; }; - hShortcutBG.CommandView = bgColor; + bgColorShortcut.CommandView = bgColor; - Application.Top.Add (hShortcutBG); + Application.Top.Add (bgColorShortcut); - var hShortcut3 = new Shortcut + var appQuitShortcut = new Shortcut { - Orientation = Orientation.Horizontal, + Id = "appQuitShortcut", X = Pos.Align (Alignment.Start, AlignmentModes.IgnoreFirstOrLast, 1), - Y = Pos.Top (hShortcut2), + Y = Pos.AnchorEnd () - 1, Key = Key.Esc, KeyBindingScope = KeyBindingScope.Application, Title = "Quit", HelpText = "App Scope", - CanFocus = false }; - hShortcut3.Accepting += (o, args) => + appQuitShortcut.Accepting += (o, args) => { Application.RequestStop (); }; - Application.Top.Add (hShortcut3); + Application.Top.Add (appQuitShortcut); foreach (View sh in Application.Top.Subviews.Where (v => v is Shortcut)!) { diff --git a/UnitTests/Drawing/ThicknessTests.cs b/UnitTests/Drawing/ThicknessTests.cs index 064b45628..1a8fac228 100644 --- a/UnitTests/Drawing/ThicknessTests.cs +++ b/UnitTests/Drawing/ThicknessTests.cs @@ -54,14 +54,12 @@ public class ThicknessTests (ITestOutputHelper output) ((FakeDriver)Application.Driver!).SetBufferSize (60, 60); var t = new Thickness (0, 0, 0, 0); var r = new Rectangle (5, 5, 40, 15); - View.Diagnostics |= ViewDiagnosticFlags.Padding; Application.Driver?.FillRect ( new Rectangle (0, 0, Application.Driver!.Cols, Application.Driver!.Rows), (Rune)' ' ); - t.Draw (r, "Test"); - View.Diagnostics = ViewDiagnosticFlags.Off; + t.Draw (r, ViewDiagnosticFlags.Padding, "Test"); TestHelpers.AssertDriverContentsWithFrameAre ( @" @@ -71,14 +69,12 @@ public class ThicknessTests (ITestOutputHelper output) t = new Thickness (1, 1, 1, 1); r = new Rectangle (5, 5, 40, 15); - View.Diagnostics |= ViewDiagnosticFlags.Padding; Application.Driver?.FillRect ( new Rectangle (0, 0, Application.Driver!.Cols, Application.Driver!.Rows), (Rune)' ' ); - t.Draw (r, "Test"); - View.Diagnostics = ViewDiagnosticFlags.Off; + t.Draw (r, ViewDiagnosticFlags.Padding, "Test"); TestHelpers.AssertDriverContentsWithFrameAre ( @" @@ -102,14 +98,12 @@ public class ThicknessTests (ITestOutputHelper output) t = new Thickness (1, 2, 3, 4); r = new Rectangle (5, 5, 40, 15); - View.Diagnostics |= ViewDiagnosticFlags.Padding; Application.Driver?.FillRect ( new Rectangle (0, 0, Application.Driver!.Cols, Application.Driver!.Rows), (Rune)' ' ); - t.Draw (r, "Test"); - View.Diagnostics = ViewDiagnosticFlags.Off; + t.Draw (r, ViewDiagnosticFlags.Padding, "Test"); TestHelpers.AssertDriverContentsWithFrameAre ( @" @@ -133,14 +127,12 @@ public class ThicknessTests (ITestOutputHelper output) t = new Thickness (-1, 1, 1, 1); r = new Rectangle (5, 5, 40, 15); - View.Diagnostics |= ViewDiagnosticFlags.Padding; Application.Driver?.FillRect ( new Rectangle (0, 0, Application.Driver!.Cols, Application.Driver!.Rows), (Rune)' ' ); - t.Draw (r, "Test"); - View.Diagnostics = ViewDiagnosticFlags.Off; + t.Draw (r, ViewDiagnosticFlags.Padding, "Test"); TestHelpers.AssertDriverContentsWithFrameAre ( @" @@ -179,9 +171,7 @@ public class ThicknessTests (ITestOutputHelper output) var r = new Rectangle (2, 2, 40, 15); Application.RunIteration (ref rs); - View.Diagnostics |= ViewDiagnosticFlags.Ruler; - t.Draw (r, "Test"); - View.Diagnostics = ViewDiagnosticFlags.Off; + t.Draw (r, ViewDiagnosticFlags.Ruler, "Test"); TestHelpers.AssertDriverContentsAre ( @" @@ -212,9 +202,7 @@ public class ThicknessTests (ITestOutputHelper output) r = new Rectangle (1, 1, 40, 15); top.SetNeedsDisplay (); Application.RunIteration (ref rs); - View.Diagnostics |= ViewDiagnosticFlags.Ruler; - t.Draw (r, "Test"); - View.Diagnostics = ViewDiagnosticFlags.Off; + t.Draw (r, ViewDiagnosticFlags.Ruler, "Test"); TestHelpers.AssertDriverContentsAre ( @" @@ -245,9 +233,7 @@ public class ThicknessTests (ITestOutputHelper output) r = new Rectangle (2, 2, 40, 15); top.SetNeedsDisplay (); Application.RunIteration (ref rs); - View.Diagnostics |= ViewDiagnosticFlags.Ruler; - t.Draw (r, "Test"); - View.Diagnostics = ViewDiagnosticFlags.Off; + t.Draw (r, ViewDiagnosticFlags.Ruler, "Test"); TestHelpers.AssertDriverContentsWithFrameAre ( @" @@ -278,9 +264,7 @@ public class ThicknessTests (ITestOutputHelper output) r = new Rectangle (5, 5, 40, 15); top.SetNeedsDisplay (); Application.RunIteration (ref rs); - View.Diagnostics |= ViewDiagnosticFlags.Ruler; - t.Draw (r, "Test"); - View.Diagnostics = ViewDiagnosticFlags.Off; + t.Draw (r, ViewDiagnosticFlags.Ruler, "Test"); TestHelpers.AssertDriverContentsWithFrameAre ( @" diff --git a/UnitTests/View/Adornment/MarginTests.cs b/UnitTests/View/Adornment/MarginTests.cs index 39d2afd8d..236e11666 100644 --- a/UnitTests/View/Adornment/MarginTests.cs +++ b/UnitTests/View/Adornment/MarginTests.cs @@ -9,6 +9,8 @@ public class MarginTests (ITestOutputHelper output) public void Margin_Uses_SuperView_ColorScheme () { ((FakeDriver)Application.Driver!).SetBufferSize (5, 5); + View.Diagnostics = ViewDiagnosticFlags.Padding; + var view = new View { Height = 3, Width = 3 }; view.Margin.Thickness = new (1); @@ -27,7 +29,6 @@ public class MarginTests (ITestOutputHelper output) superView.BeginInit (); superView.EndInit (); - View.Diagnostics = ViewDiagnosticFlags.Padding; view.SetNeedsDisplay(); view.Draw (); View.Diagnostics = ViewDiagnosticFlags.Off; diff --git a/UnitTests/View/Adornment/PaddingTests.cs b/UnitTests/View/Adornment/PaddingTests.cs index 9c1fe21ea..b346e4425 100644 --- a/UnitTests/View/Adornment/PaddingTests.cs +++ b/UnitTests/View/Adornment/PaddingTests.cs @@ -11,6 +11,7 @@ public class PaddingTests (ITestOutputHelper output) ((FakeDriver)Application.Driver!).SetBufferSize (5, 5); var view = new View { Height = 3, Width = 3 }; view.Padding.Thickness = new (1); + view.Padding.Diagnostics = ViewDiagnosticFlags.Padding; view.ColorScheme = new() { @@ -22,9 +23,7 @@ public class PaddingTests (ITestOutputHelper output) view.BeginInit (); view.EndInit (); - View.Diagnostics = ViewDiagnosticFlags.Padding; view.Draw (); - View.Diagnostics = ViewDiagnosticFlags.Off; TestHelpers.AssertDriverContentsAre ( @" diff --git a/UnitTests/View/Draw/DrawTests.cs b/UnitTests/View/Draw/DrawTests.cs index a61bd3a89..2c305d5e1 100644 --- a/UnitTests/View/Draw/DrawTests.cs +++ b/UnitTests/View/Draw/DrawTests.cs @@ -43,7 +43,7 @@ public class DrawTests (ITestOutputHelper _output) Width = 3, Height = 3 }; view.Margin.Thickness = new (1); - View.Diagnostics = ViewDiagnosticFlags.Padding; + view.Margin.Diagnostics = ViewDiagnosticFlags.Padding; view.BeginInit (); view.EndInit (); view.Draw (); @@ -59,8 +59,6 @@ public class DrawTests (ITestOutputHelper _output) view.AddRune (1, 1, Rune.ReplacementChar); Assert.Equal ((Rune)'M', Application.Driver?.Contents! [3, 3].Rune); - - View.Diagnostics = ViewDiagnosticFlags.Off; } [Theory] diff --git a/UnitTests/View/Layout/Dim.FillTests.cs b/UnitTests/View/Layout/Dim.FillTests.cs index 9defdf8aa..5e1ba315a 100644 --- a/UnitTests/View/Layout/Dim.FillTests.cs +++ b/UnitTests/View/Layout/Dim.FillTests.cs @@ -16,8 +16,7 @@ public class DimFillTests (ITestOutputHelper output) RunState rs = Application.Begin (top); ((FakeDriver)Application.Driver!).SetBufferSize (32, 5); - //view.SetNeedsLayout (); - top.LayoutSubviews (); + top.Layout (); //view.SetRelativeLayout (new (0, 0, 32, 5)); Assert.Equal (32, view.Frame.Width); @@ -61,7 +60,7 @@ public class DimFillTests (ITestOutputHelper output) super.Add (view); super.BeginInit (); super.EndInit (); - super.LayoutSubviews (); + super.Layout (); Assert.Equal (25, super.Frame.Width); Assert.Equal (25, super.Frame.Height); @@ -103,7 +102,7 @@ public class DimFillTests (ITestOutputHelper output) super.Add (view); super.BeginInit (); super.EndInit (); - super.LayoutSubviews (); + super.Layout (); Assert.Equal (25, super.Frame.Width); Assert.Equal (25, super.Frame.Height); @@ -167,7 +166,7 @@ public class DimFillTests (ITestOutputHelper output) super.Add (view); view.Text = "New text\nNew line"; - super.LayoutSubviews (); + super.Layout (); Rectangle expectedViewBounds = new (0, 0, 30, 80); Assert.Equal (expectedViewBounds, view.Viewport); diff --git a/UnitTests/Views/HexViewTests.cs b/UnitTests/Views/HexViewTests.cs index 1468a07bf..b4c78b64b 100644 --- a/UnitTests/Views/HexViewTests.cs +++ b/UnitTests/Views/HexViewTests.cs @@ -24,6 +24,7 @@ public class HexViewTests var hv = new HexView (LoadStream (null, out long _)) { Width = width, Height = 10, AddressWidth = 0 }; hv.Layout (); + Assert.Equal (width, hv.Frame.Width); Assert.Equal (expectedBpl, hv.BytesPerLine); } @@ -370,20 +371,21 @@ public class HexViewTests Application.Top = new Toplevel (); Application.Top.Add (hv); - hv.Layout (); + Application.Top.Layout (); Assert.True (hv.NewKeyDownEvent (Key.End)); Assert.Equal (MEM_STRING_LENGTH - 1, hv.DisplayStart); Assert.Equal (MEM_STRING_LENGTH, hv.Address); hv.Source = new MemoryStream (); + Application.Top.Layout (); Assert.Equal (0, hv.DisplayStart); Assert.Equal (0, hv.Address); hv.Source = LoadStream (null, out _); hv.Width = Dim.Fill (); hv.Height = Dim.Fill (); - Application.Top.LayoutSubviews (); + Application.Top.Layout (); Assert.Equal (0, hv.DisplayStart); Assert.Equal (0, hv.Address); @@ -392,8 +394,10 @@ public class HexViewTests Assert.Equal (MEM_STRING_LENGTH, hv.Address); hv.Source = new MemoryStream (); + Application.Top.Layout (); Assert.Equal (0, hv.DisplayStart); Assert.Equal (0, hv.Address); + Application.Top.Dispose (); Application.ResetState (true); } diff --git a/UnitTests/Views/ShortcutTests.cs b/UnitTests/Views/ShortcutTests.cs index 63a7ae3be..691d86288 100644 --- a/UnitTests/Views/ShortcutTests.cs +++ b/UnitTests/Views/ShortcutTests.cs @@ -95,20 +95,51 @@ public class ShortcutTests { var shortcut = new Shortcut { - Title = command, HelpText = help, - Key = key + Key = key, + Title = command, }; - Assert.IsType (shortcut.Width); - Assert.IsType (shortcut.Height); - shortcut.SetRelativeLayout (new (100, 100)); + shortcut.Layout(); // |0123456789 // | C H K | Assert.Equal (expectedWidth, shortcut.Frame.Width); + + shortcut = new Shortcut + { + HelpText = help, + Title = command, + Key = key + }; + + shortcut.Layout (); + Assert.Equal (expectedWidth, shortcut.Frame.Width); + + shortcut = new Shortcut + { + HelpText = help, + Key = key, + Title = command, + }; + + shortcut.Layout (); + Assert.Equal (expectedWidth, shortcut.Frame.Width); + + shortcut = new Shortcut + { + Key = key, + HelpText = help, + Title = command, + }; + + shortcut.Layout (); + Assert.Equal (expectedWidth, shortcut.Frame.Width); + } + + [Theory] [InlineData (0, 0, 3, 3)] [InlineData (1, 0, 3, 3)] diff --git a/UnitTests/Views/WindowTests.cs b/UnitTests/Views/WindowTests.cs index 554593d23..2400773e7 100644 --- a/UnitTests/Views/WindowTests.cs +++ b/UnitTests/Views/WindowTests.cs @@ -121,6 +121,7 @@ public class WindowTests { // Parameterless using var defaultWindow = new Window (); + defaultWindow.Layout (); Assert.NotNull (defaultWindow); Assert.Equal (string.Empty, defaultWindow.Title); @@ -148,6 +149,7 @@ public class WindowTests // Empty Rect using var windowWithFrameRectEmpty = new Window { Frame = Rectangle.Empty, Title = "title" }; + windowWithFrameRectEmpty.Layout (); Assert.NotNull (windowWithFrameRectEmpty); Assert.Equal ("title", windowWithFrameRectEmpty.Title); Assert.True (windowWithFrameRectEmpty.CanFocus);