From 72ea740a7435dc20bfa7f6aed7ff068a6986e676 Mon Sep 17 00:00:00 2001 From: Tig Date: Mon, 21 Oct 2024 09:52:56 -0600 Subject: [PATCH] More shortcut stuff --- Terminal.Gui/Views/Shortcut.cs | 139 +++++++++++-------------------- UICatalog/Scenarios/Shortcuts.cs | 31 +++++-- UnitTests/Views/ShortcutTests.cs | 39 +++++---- 3 files changed, 96 insertions(+), 113 deletions(-) diff --git a/Terminal.Gui/Views/Shortcut.cs b/Terminal.Gui/Views/Shortcut.cs index 3deaebd2f..21523ad69 100644 --- a/Terminal.Gui/Views/Shortcut.cs +++ b/Terminal.Gui/Views/Shortcut.cs @@ -127,6 +127,11 @@ public class Shortcut : View, IOrientation, IDesignable Key = key; Title = commandText ?? string.Empty; Action = action; + + SuperViewRendersLineCanvas = true; + Border.Settings &= ~BorderSettings.Title; + + ShowHide (); } // Helper to set Width consistently @@ -135,45 +140,15 @@ public class Shortcut : View, IOrientation, IDesignable // TODO: PosAlign.CalculateMinDimension is a hack. Need to figure out a better way of doing this. return Dim.Auto ( DimAutoStyle.Content, - Dim.Func (() => - { - return PosAlign.CalculateMinDimension (0, Subviews, Dimension.Width); - }), - Dim.Func (() => - { - return PosAlign.CalculateMinDimension (0, Subviews, Dimension.Width); - }))!; - } - - /// - public override void EndInit () - { - base.EndInit (); - - SuperViewRendersLineCanvas = true; - Border.Settings &= ~BorderSettings.Title; - - ShowHide (); - - // Force Width to DimAuto to calculate natural width and then set it back - Dim? savedDim = Width; - Width = GetWidthDimAuto (); - // Force a SRL) - SetRelativeLayout (Application.Screen.Size); - _minimumNatrualWidth = Frame.Width; - Width = savedDim; - - SetCommandViewDefaultLayout (); - SetHelpViewDefaultLayout (); - SetKeyViewDefaultLayout (); - - SetColors (); + Dim.Func (() => PosAlign.CalculateMinDimension (0, Subviews, Dimension.Width)), + Dim.Func (() => PosAlign.CalculateMinDimension (0, Subviews, Dimension.Width)))!; } private AlignmentModes _alignmentModes = AlignmentModes.StartToEnd | AlignmentModes.IgnoreFirstOrLast; - // This is used to calculate the minimum width of the Shortcut when the width is NOT Dim.Auto - // It is calculated by setting Width to DimAuto temporarily and forcing layout + // 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; /// @@ -218,29 +193,41 @@ public class Shortcut : View, IOrientation, IDesignable if (CommandView.Visible) { Add (CommandView); + SetCommandViewDefaultLayout (); } if (HelpView.Visible && !string.IsNullOrEmpty (HelpView.Text)) { Add (HelpView); + SetHelpViewDefaultLayout (); } if (KeyView.Visible && Key != Key.Empty) { Add (KeyView); + 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 (); } private Thickness GetMarginThickness () { - if (Orientation == Orientation.Vertical) - { - return new (1, 0, 1, 0); - } - 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) { @@ -257,61 +244,39 @@ public class Shortcut : View, IOrientation, IDesignable int currentWidth = Frame.Width; - // If our width is smaller than the natural width then reduce width of HelpView first. + // Frame.Width is smaller than the natural width. Reduce width of HelpView first. // Then KeyView. // Don't ever reduce CommandView (it should spill). - // When Horizontal, Key is first, then Help, then Command. - // When Vertical, Command is first, then Help, then Key. - // BUGBUG: This does not do what the above says. // TODO: Add Unit tests for this. - if (currentWidth < _minimumNatrualWidth) + int delta = _minimumNatrualWidth.Value - currentWidth; + _maxHelpWidth = int.Max (0, GetContentSize().Width - CommandView.Frame.Width - KeyView.Frame.Width); + if (_maxHelpWidth < 3) { - int delta = _minimumNatrualWidth.Value - currentWidth; - int maxHelpWidth = int.Max (0, HelpView.Text.GetColumns () + Margin.Thickness.Horizontal - delta); - - switch (maxHelpWidth) + Thickness t = GetMarginThickness (); + switch (_maxHelpWidth) { - case 0: - // Hide HelpView - HelpView.Visible = false; - HelpView.X = 0; - - break; - - case 1: - // Scrunch it by removing margins - HelpView.Margin.Thickness = new (0, 0, 0, 0); - - break; - case 2: + // Scrunch just the right margin - Thickness t = GetMarginThickness (); HelpView.Margin.Thickness = new (t.Right, t.Top, t.Left - 1, t.Bottom); break; - default: - // Default margin - HelpView.Margin.Thickness = GetMarginThickness (); + case 0: + case 1: + // Scrunch it by removing both margins + HelpView.Margin.Thickness = new (t.Right - 1, t.Top, t.Left - 1, t.Bottom); break; - } - if (maxHelpWidth > 0) - { - HelpView.X = Pos.Align (Alignment.End, AlignmentModes); - - // Leverage Dim.Auto's max: - HelpView.Width = Dim.Auto (DimAutoStyle.Text, maximumContentDim: maxHelpWidth); - HelpView.Visible = true; } } else { // Reset to default - SetHelpViewDefaultLayout (); + HelpView.Margin.Thickness = GetMarginThickness (); } + KeyView.SetLayoutNeeded(); } } @@ -395,14 +360,7 @@ public class Shortcut : View, IOrientation, IDesignable /// . /// /// - /// - /// Horizontal orientation arranges the command, help, and key parts of each s from right to - /// left - /// Vertical orientation arranges the command, help, and key parts of each s from left to - /// right. - /// /// - public Orientation Orientation { get => _orientationHelper.Orientation; @@ -512,12 +470,8 @@ public class Shortcut : View, IOrientation, IDesignable Title = _commandView.Text; _commandView.Selecting += CommandViewOnSelecting; - _commandView.Accepting += CommandViewOnAccepted; - SetCommandViewDefaultLayout (); - SetHelpViewDefaultLayout (); - SetKeyViewDefaultLayout (); ShowHide (); UpdateKeyBindings (Key.Empty); @@ -565,18 +519,21 @@ public class Shortcut : View, IOrientation, IDesignable /// /// The subview that displays the help text for the command. Internal for unit testing. /// - internal View HelpView { get; } = new (); + public View HelpView { get; } = new (); private void SetHelpViewDefaultLayout () { HelpView.Margin.Thickness = GetMarginThickness (); HelpView.X = Pos.Align (Alignment.End, AlignmentModes); HelpView.Y = 0; //Pos.Center (); - HelpView.Width = Dim.Auto (DimAutoStyle.Text); + _maxHelpWidth = HelpView.Text.GetColumns (); + HelpView.Width = Dim.Auto (DimAutoStyle.Text, maximumContentDim: Dim.Func ((() => _maxHelpWidth))); HelpView.Height = CommandView?.Visible == true ? Dim.Height (CommandView) : 1; HelpView.Visible = true; HelpView.VerticalTextAlignment = Alignment.Center; + HelpView.TextAlignment = Alignment.Start; + HelpView.TextFormatter.WordWrap = false; HelpView.HighlightStyle = HighlightStyle.None; } @@ -668,7 +625,7 @@ public class Shortcut : View, IOrientation, IDesignable /// Gets the subview that displays the key. Internal for unit testing. /// - internal View KeyView { get; } = new (); + public View KeyView { get; } = new (); private int _minimumKeyTextSize; @@ -694,14 +651,13 @@ public class Shortcut : View, IOrientation, IDesignable } } - private int GetMinimumKeyViewSize () { return MinimumKeyTextSize; } private void SetKeyViewDefaultLayout () { KeyView.Margin.Thickness = GetMarginThickness (); KeyView.X = Pos.Align (Alignment.End, AlignmentModes); KeyView.Y = 0; - KeyView.Width = Dim.Auto (DimAutoStyle.Text, Dim.Func (GetMinimumKeyViewSize)); + KeyView.Width = Dim.Auto (DimAutoStyle.Text, minimumContentDim: Dim.Func (() => MinimumKeyTextSize)); KeyView.Height = CommandView?.Visible == true ? Dim.Height (CommandView) : 1; KeyView.Visible = true; @@ -810,7 +766,6 @@ public class Shortcut : View, IOrientation, IDesignable return true; } - /// protected override void Dispose (bool disposing) { diff --git a/UICatalog/Scenarios/Shortcuts.cs b/UICatalog/Scenarios/Shortcuts.cs index b0a3803e9..5fd8ee760 100644 --- a/UICatalog/Scenarios/Shortcuts.cs +++ b/UICatalog/Scenarios/Shortcuts.cs @@ -39,6 +39,7 @@ public class Shortcuts : Scenario var eventLog = new ListView { X = Pos.AnchorEnd (), + Y = 0, Height = Dim.Fill (4), ColorScheme = Colors.ColorSchemes ["Toplevel"], Source = new ListWrapper (eventSource), @@ -50,12 +51,11 @@ public class Shortcuts : Scenario var vShortcut1 = new Shortcut { - Orientation = Orientation.Vertical, X = 0, - Width = 35, + Width = Dim.Fill () - Dim.Width (eventLog), Title = "A_pp Shortcut", Key = Key.F1, - Text = "Width is 35", + Text = "Width is DimFIll", KeyBindingScope = KeyBindingScope.Application, }; @@ -63,7 +63,6 @@ public class Shortcuts : Scenario var vShortcut2 = new Shortcut { - Orientation = Orientation.Vertical, X = 0, Y = Pos.Bottom (vShortcut1), Width = 35, @@ -88,7 +87,6 @@ public class Shortcuts : Scenario var vShortcut3 = new Shortcut { - Orientation = Orientation.Vertical, X = 0, Y = Pos.Bottom (vShortcut2), CommandView = new CheckBox @@ -242,6 +240,27 @@ public class Shortcuts : Scenario Application.Top.Add (vShortcut7); vShortcut7.SetFocus (); + var framedShortcut = new Shortcut + { + X = 0, + Y = Pos.Bottom(vShortcut7) + 1, + Width = Dim.Auto(), + Title = "C", + Key = Key.K, + Text = "H", + BorderStyle = LineStyle.Dotted, + Arrangement = ViewArrangement.Resizable, + CanFocus = false, + // Orientation = Orientation.Horizontal, + //AlignmentModes = AlignmentModes.EndToStart + + }; + framedShortcut.Orientation = Orientation.Horizontal; + framedShortcut.Padding.Thickness = new (0, 1, 0, 0); + 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"]; + Application.Top.Add (framedShortcut); // Horizontal var hShortcut1 = new Shortcut @@ -395,8 +414,6 @@ public class Shortcuts : Scenario }; } } - - //((CheckBox)vShortcut5.CommandView).OnToggle (); } private void Button_Clicked (object sender, CommandEventArgs e) diff --git a/UnitTests/Views/ShortcutTests.cs b/UnitTests/Views/ShortcutTests.cs index 0458526cc..63a7ae3be 100644 --- a/UnitTests/Views/ShortcutTests.cs +++ b/UnitTests/Views/ShortcutTests.cs @@ -20,8 +20,6 @@ public class ShortcutTests public void Size_Defaults () { var shortcut = new Shortcut (); - shortcut.BeginInit(); - shortcut.EndInit (); shortcut.Layout (); Assert.Equal (2, shortcut.Frame.Width); @@ -45,8 +43,6 @@ public class ShortcutTests Key = Key.A, HelpText = "0" }; - shortcut.BeginInit (); - shortcut.EndInit (); shortcut.Layout (); Assert.Equal (8, shortcut.Frame.Width); Assert.Equal (1, shortcut.Frame.Height); @@ -70,8 +66,6 @@ public class ShortcutTests Key = Key.A, HelpText = "0" }; - shortcut.BeginInit (); - shortcut.EndInit (); shortcut.Layout (); Assert.Equal (9, shortcut.Frame.Width); Assert.Equal (1, shortcut.Frame.Height); @@ -116,10 +110,15 @@ public class ShortcutTests } [Theory] - [InlineData (5, 0, 3, 6)] - [InlineData (6, 0, 3, 6)] - [InlineData (7, 0, 3, 6)] - [InlineData (8, 0, 3, 6)] + [InlineData (0, 0, 3, 3)] + [InlineData (1, 0, 3, 3)] + [InlineData (2, 0, 3, 3)] + [InlineData (3, 0, 3, 3)] + [InlineData (4, 0, 3, 3)] + [InlineData (5, 0, 3, 3)] + [InlineData (6, 0, 3, 3)] + [InlineData (7, 0, 3, 4)] + [InlineData (8, 0, 3, 5)] [InlineData (9, 0, 3, 6)] [InlineData (10, 0, 4, 7)] [InlineData (11, 0, 5, 8)] @@ -132,9 +131,22 @@ public class ShortcutTests Text = "H", Key = Key.K }; + shortcut.Layout (); - shortcut.LayoutSubviews (); - shortcut.SetRelativeLayout (new (100, 100)); + // 01234 + // -C--K + + // 012345 + // -C--K- + + // 0123456 + // -C-H-K- + + // 01234567 + // -C--H-K- + + // 012345678 + // -C--H--K- // 0123456789 // -C--H--K- @@ -424,8 +436,7 @@ public class ShortcutTests Title = "C" }; Application.Top.Add (shortcut); - Application.Top.SetRelativeLayout (new (100, 100)); - Application.Top.LayoutSubviews (); + Application.Top.Layout (); var accepted = 0; shortcut.Accepting += (s, e) => accepted++;