diff --git a/Terminal.Gui/Text/TextFormatter.cs b/Terminal.Gui/Text/TextFormatter.cs
index ac8dc293c..b8dfa3d57 100644
--- a/Terminal.Gui/Text/TextFormatter.cs
+++ b/Terminal.Gui/Text/TextFormatter.cs
@@ -45,11 +45,52 @@ public class TextFormatter
if (_autoSize)
{
- Size = CalcRect (0, 0, _text, Direction, TabWidth).Size;
+ Size = GetAutoSize ();
}
}
}
+ private Size GetAutoSize ()
+ {
+ Size size = CalcRect (0, 0, Text, Direction, TabWidth).Size;
+ return size with
+ {
+ Width = size.Width - GetHotKeySpecifierLength (),
+ Height = size.Height - GetHotKeySpecifierLength (false)
+ };
+
+ }
+ ///
+ /// Gets the width or height of the characters
+ /// in the property.
+ ///
+ ///
+ /// Only the first HotKey specifier found in is supported.
+ ///
+ ///
+ /// If (the default) the width required for the HotKey specifier is returned. Otherwise the
+ /// height
+ /// is returned.
+ ///
+ ///
+ /// The number of characters required for the . If the text
+ /// direction specified
+ /// by does not match the parameter, 0 is returned.
+ ///
+ public int GetHotKeySpecifierLength (bool isWidth = true)
+ {
+ if (isWidth)
+ {
+ return TextFormatter.IsHorizontalDirection (Direction) && Text?.Contains ((char)HotKeySpecifier.Value) == true
+ ? Math.Max (HotKeySpecifier.GetColumns (), 0)
+ : 0;
+ }
+
+ return TextFormatter.IsVerticalDirection (Direction) && Text?.Contains ((char)HotKeySpecifier.Value) == true
+ ? Math.Max (HotKeySpecifier.GetColumns (), 0)
+ : 0;
+ }
+
///
/// Gets the cursor position of the . If the is defined, the cursor will
/// be positioned over it.
@@ -67,11 +108,12 @@ public class TextFormatter
if (AutoSize)
{
- Size = CalcRect (0, 0, Text, Direction, TabWidth).Size;
+ Size = GetAutoSize ();
}
}
}
+
///
/// Determines if the viewport width will be used or only the text width will be used,
/// If all the viewport area will be filled with whitespaces and the same background color
@@ -150,7 +192,7 @@ public class TextFormatter
{
if (AutoSize)
{
- _size = EnableNeedsFormat (CalcRect (0, 0, Text, Direction, TabWidth).Size);
+ _size = EnableNeedsFormat (GetAutoSize());
}
else
{
@@ -176,7 +218,7 @@ public class TextFormatter
if (AutoSize)
{
- Size = CalcRect (0, 0, _text, Direction, TabWidth).Size;
+ Size = GetAutoSize (); ;
}
}
}
diff --git a/Terminal.Gui/View/Layout/ViewLayout.cs b/Terminal.Gui/View/Layout/ViewLayout.cs
index 23a6102fa..4c4891a6e 100644
--- a/Terminal.Gui/View/Layout/ViewLayout.cs
+++ b/Terminal.Gui/View/Layout/ViewLayout.cs
@@ -101,6 +101,11 @@ public partial class View
_frame = frame;
OnViewportChanged (new (IsInitialized ? Viewport : Rectangle.Empty, oldViewport));
+
+ if (!TextFormatter.AutoSize)
+ {
+ TextFormatter.Size = ContentSize;
+ }
}
/// Gets the with a screen-relative location.
@@ -274,6 +279,12 @@ public partial class View
return;
}
+ if (_height is Dim.DimAuto)
+ {
+ // Reset ContentSize to Viewport
+ _contentSize = Size.Empty;
+ }
+
_height = value ?? throw new ArgumentNullException (nameof (value), @$"{nameof (Height)} cannot be null");
OnResizeNeeded ();
@@ -314,6 +325,12 @@ public partial class View
return;
}
+ if (_width is Dim.DimAuto)
+ {
+ // Reset ContentSize to Viewport
+ _contentSize = Size.Empty;
+ }
+
_width = value ?? throw new ArgumentNullException (nameof (value), @$"{nameof (Width)} cannot be null");
OnResizeNeeded ();
@@ -341,6 +358,7 @@ public partial class View
/// will left unchanged.
///
///
+ [ObsoleteAttribute ("Use Dim.Auto instead.", false)]
public virtual bool AutoSize
{
get => _height is Dim.DimAuto && _width is Dim.DimAuto;
@@ -352,6 +370,7 @@ public partial class View
if (value)
{
UpdateTextFormatterText ();
+
if (IsInitialized)
{
Height = Dim.Auto (Dim.DimAutoStyle.Text);
@@ -368,12 +387,14 @@ public partial class View
{
_height = ContentSize.Height;
_width = ContentSize.Width;
+
+ // Force ContentSize to be reset to Viewport
+ _contentSize = Size.Empty;
OnResizeNeeded ();
}
}
}
-
///// Determines if the View's can be set to a new value.
///// TrySetHeight can only be called when AutoSize is true (or being set to true).
/////
@@ -706,7 +727,7 @@ public partial class View
if (viewToMove?.SuperView is null || viewToMove == Application.Top || viewToMove?.SuperView == Application.Top)
{
- menuVisible = Application.Top.MenuBar?.Visible == true;
+ menuVisible = Application.Top?.MenuBar?.Visible == true;
}
else
{
@@ -736,8 +757,8 @@ public partial class View
if (viewToMove?.SuperView is null || viewToMove == Application.Top || viewToMove?.SuperView == Application.Top)
{
- statusVisible = Application.Top.StatusBar?.Visible == true;
- statusBar = Application.Top.StatusBar;
+ statusVisible = Application.Top?.StatusBar?.Visible == true;
+ statusBar = Application.Top?.StatusBar;
}
else
{
@@ -764,14 +785,14 @@ public partial class View
maxDimension = statusVisible ? viewToMove.SuperView.Viewport.Height - 1 : viewToMove.SuperView.Viewport.Height;
}
- if (superView.Margin is { } && superView == viewToMove.SuperView)
+ if (superView?.Margin is { } && superView == viewToMove?.SuperView)
{
maxDimension -= superView.GetAdornmentsThickness ().Top + superView.GetAdornmentsThickness ().Bottom;
}
ny = Math.Min (ny, maxDimension);
- if (viewToMove.Frame.Height <= maxDimension)
+ if (viewToMove?.Frame.Height <= maxDimension)
{
ny = ny + viewToMove.Frame.Height > maxDimension
? Math.Max (maxDimension - viewToMove.Frame.Height, menuVisible ? 1 : 0)
@@ -926,7 +947,9 @@ public partial class View
if (bad != null)
{
throw new InvalidOperationException (
- @$"{view.GetType ().Name}.{name} = {bad.GetType ().Name} which depends on the SuperView's dimensions and the SuperView uses Dim.Auto.");
+ $"{view.GetType ().Name}.{name} = {bad.GetType ().Name} "
+ + $"which depends on the SuperView's dimensions and the SuperView uses Dim.Auto."
+ );
}
}
@@ -990,8 +1013,6 @@ public partial class View
Application.Top is { } && Application.Top != this && Application.Top.IsInitialized ? Application.Top.ContentSize :
Application.Driver?.Screen.Size ?? new (int.MaxValue, int.MaxValue);
-
-
SetTextFormatterSize ();
SetRelativeLayout (contentSize);
@@ -1003,7 +1024,6 @@ public partial class View
SetNeedsDisplay ();
SetNeedsLayout ();
-
}
internal bool LayoutNeeded { get; private set; } = true;
@@ -1264,12 +1284,14 @@ public partial class View
if (ReferenceEquals (from.SuperView, to))
{
throw new InvalidOperationException (
- $"ComputedLayout for \"{superView}\": \"{to}\" references a SubView (\"{from}\")."
+ $"ComputedLayout for \"{superView}\": \"{to}\" "
+ + $"references a SubView (\"{from}\")."
);
}
throw new InvalidOperationException (
- $"ComputedLayout for \"{superView}\": \"{from}\" linked with \"{to}\" was not found. Did you forget to add it to {superView}?"
+ $"ComputedLayout for \"{superView}\": \"{from}\" "
+ + $"linked with \"{to}\" was not found. Did you forget to add it to {superView}?"
);
}
}
@@ -1282,9 +1304,12 @@ public partial class View
private Pos VerifyIsInitialized (Pos pos, string member)
{
#if DEBUG
- if (pos is not Pos.PosAbsolute && LayoutStyle == LayoutStyle.Computed && !IsInitialized)
+ if ((pos.ReferencesOtherViews () || pos.ReferencesOtherViews ()) && !IsInitialized)
{
- Debug.WriteLine ($"WARNING: \"{this}\" has not been initialized; {member} is indeterminate ({pos}). This is potentially a bug.");
+ Debug.WriteLine (
+ $"WARNING: The {pos} of {this} is dependent on other views and {member} "
+ + $"is being accessed before the View has been initialized. This is likely a bug."
+ );
}
#endif // DEBUG
return pos;
@@ -1294,9 +1319,13 @@ public partial class View
private Dim VerifyIsInitialized (Dim dim, string member)
{
#if DEBUG
- if (dim is not Dim.DimAbsolute && LayoutStyle == LayoutStyle.Computed && !IsInitialized)
+ if ((dim.ReferencesOtherViews () || dim.ReferencesOtherViews ()) && !IsInitialized)
{
- Debug.WriteLine ($"WARNING: \"{this}\" has not been initialized; {member} is indeterminate: ({dim}). This is potentially a bug.");
+ Debug.WriteLine (
+ $"WARNING: The {member} of {this} is dependent on other views and is "
+ + $"is being accessed before the View has been initialized. This is likely a bug. "
+ + $"{member} is {dim}"
+ );
}
#endif // DEBUG
return dim;
diff --git a/Terminal.Gui/View/ViewDrawing.cs b/Terminal.Gui/View/ViewDrawing.cs
index a252a4c76..9a0823343 100644
--- a/Terminal.Gui/View/ViewDrawing.cs
+++ b/Terminal.Gui/View/ViewDrawing.cs
@@ -577,7 +577,7 @@ public partial class View
///
public void SetNeedsDisplay ()
{
- if (IsInitialized)
+ //if (IsInitialized)
{
SetNeedsDisplay (Viewport);
}
@@ -597,12 +597,12 @@ public partial class View
/// The content-relative region that needs to be redrawn.
public void SetNeedsDisplay (Rectangle region)
{
- if (!IsInitialized)
- {
- _needsDisplayRect = region;
+ //if (!IsInitialized)
+ //{
+ // _needsDisplayRect = region;
- return;
- }
+ // return;
+ //}
if (_needsDisplayRect.IsEmpty)
{
diff --git a/Terminal.Gui/View/ViewKeyboard.cs b/Terminal.Gui/View/ViewKeyboard.cs
index 52aa07da9..687491997 100644
--- a/Terminal.Gui/View/ViewKeyboard.cs
+++ b/Terminal.Gui/View/ViewKeyboard.cs
@@ -205,7 +205,7 @@ public partial class View
}
set
{
- TitleTextFormatter.HotKeySpecifier = value;
+ TitleTextFormatter.HotKeySpecifier = TextFormatter.HotKeySpecifier = value;
SetHotKeyFromTitle ();
}
}
diff --git a/Terminal.Gui/View/ViewText.cs b/Terminal.Gui/View/ViewText.cs
index d7a754207..4377143c9 100644
--- a/Terminal.Gui/View/ViewText.cs
+++ b/Terminal.Gui/View/ViewText.cs
@@ -243,8 +243,9 @@ public partial class View
//Dim.DimAuto heightAuto = Height as Dim.DimAuto;
// TODO: This is a hack. Figure out how to move this into DimDimAuto
- if ((Width is Dim.DimAuto widthAuto && widthAuto._style != Dim.DimAutoStyle.Subviews)
- || (Height is Dim.DimAuto heightAuto && heightAuto._style != Dim.DimAutoStyle.Subviews))
+ // Use _width & _height instead of Width & Height to avoid debug spew
+ if ((_width is Dim.DimAuto widthAuto && widthAuto._style != Dim.DimAutoStyle.Subviews)
+ || (_height is Dim.DimAuto heightAuto && heightAuto._style != Dim.DimAutoStyle.Subviews))
{
// This updates TextFormatter.Size to the text size
TextFormatter.AutoSize = true;
diff --git a/Terminal.Gui/Views/CheckBox.cs b/Terminal.Gui/Views/CheckBox.cs
index 656e42ba3..9146836e9 100644
--- a/Terminal.Gui/Views/CheckBox.cs
+++ b/Terminal.Gui/Views/CheckBox.cs
@@ -20,8 +20,8 @@ public class CheckBox : View
_charChecked = Glyphs.Checked;
_charUnChecked = Glyphs.UnChecked;
- Width = Dim.Auto (Dim.DimAutoStyle.Text);
Height = 1;
+ Width = Dim.Auto (Dim.DimAutoStyle.Text);
CanFocus = true;
@@ -191,11 +191,11 @@ public class CheckBox : View
private string GetFormatterText ()
{
- if (AutoSize || string.IsNullOrEmpty (Title) || Frame.Width <= 2)
+ if (Width is Dim.DimAuto || string.IsNullOrEmpty (Title) || ContentSize.Width <= 2)
{
return Text;
}
- return Text [..Math.Min (Frame.Width - 2, Text.GetRuneCount ())];
+ return Text [..Math.Min (ContentSize.Width - 2, Text.GetRuneCount ())];
}
}
diff --git a/Terminal.Gui/Views/Menu/Menu.cs b/Terminal.Gui/Views/Menu/Menu.cs
index 62d847c65..c36e68740 100644
--- a/Terminal.Gui/Views/Menu/Menu.cs
+++ b/Terminal.Gui/Views/Menu/Menu.cs
@@ -751,7 +751,7 @@ internal sealed class Menu : View
if (index == _currentChild)
{
- return ColorScheme.Focus;
+ return GetFocusColor ();
}
return !item.IsEnabled () ? ColorScheme.Disabled : GetNormalColor ();
@@ -787,7 +787,7 @@ internal sealed class Menu : View
Driver.SetAttribute (
item is null ? GetNormalColor () :
- i == _currentChild ? ColorScheme.Focus : GetNormalColor ()
+ i == _currentChild ? GetFocusColor() : GetNormalColor ()
);
if (item is null && BorderStyle != LineStyle.None)
@@ -890,13 +890,14 @@ internal sealed class Menu : View
{
var tf = new TextFormatter
{
+ AutoSize = true,
Alignment = TextAlignment.Centered, HotKeySpecifier = MenuBar.HotKeySpecifier, Text = textToDraw
};
// The -3 is left/right border + one space (not sure what for)
tf.Draw (
ViewportToScreen (new (1, i, Frame.Width - 3, 1)),
- i == _currentChild ? ColorScheme.Focus : GetNormalColor (),
+ i == _currentChild ? GetFocusColor () : GetNormalColor (),
i == _currentChild ? ColorScheme.HotFocus : ColorScheme.HotNormal,
SuperView?.ViewportToScreen (SuperView.Viewport) ?? Rectangle.Empty
);
@@ -906,7 +907,7 @@ internal sealed class Menu : View
DrawHotString (
textToDraw,
i == _currentChild ? ColorScheme.HotFocus : ColorScheme.HotNormal,
- i == _currentChild ? ColorScheme.Focus : GetNormalColor ()
+ i == _currentChild ? GetFocusColor () : GetNormalColor ()
);
}
diff --git a/Terminal.Gui/Views/Menu/MenuBar.cs b/Terminal.Gui/Views/Menu/MenuBar.cs
index de8f9f9d7..5306d1673 100644
--- a/Terminal.Gui/Views/Menu/MenuBar.cs
+++ b/Terminal.Gui/Views/Menu/MenuBar.cs
@@ -738,7 +738,7 @@ public class MenuBar : View
case false:
if (_openMenu is { })
{
- Application.Current.Remove (_openMenu);
+ Application.Current?.Remove (_openMenu);
}
SetNeedsDisplay ();
@@ -822,7 +822,12 @@ public class MenuBar : View
Rectangle superViewFrame = SuperView is null ? Driver.Screen : SuperView.Frame;
View sv = SuperView is null ? Application.Current : SuperView;
- Point viewportOffset = sv.GetViewportOffsetFromFrame ();
+ if (sv is null)
+ {
+ // Support Unit Tests
+ return Point.Empty;
+ }
+ Point viewportOffset = sv?.GetViewportOffsetFromFrame () ?? Point.Empty;
return new (
superViewFrame.X - sv.Frame.X - viewportOffset.X,
@@ -964,7 +969,7 @@ public class MenuBar : View
if (_openMenu is { })
{
- Application.Current.Remove (_openMenu);
+ Application.Current?.Remove (_openMenu);
_openMenu.Dispose ();
_openMenu = null;
}
@@ -1001,7 +1006,15 @@ public class MenuBar : View
openCurrentMenu = _openMenu;
openCurrentMenu._previousSubFocused = _openMenu;
- Application.Current.Add (_openMenu);
+ if (Application.Current is { })
+ {
+ Application.Current.Add (_openMenu);
+ }
+ else
+ {
+ _openMenu.BeginInit();
+ _openMenu.EndInit();
+ }
_openMenu.SetFocus ();
break;
@@ -1059,7 +1072,14 @@ public class MenuBar : View
openCurrentMenu._previousSubFocused = last._previousSubFocused;
_openSubMenu.Add (openCurrentMenu);
- Application.Current.Add (openCurrentMenu);
+ Application.Current?.Add (openCurrentMenu);
+
+ if (!openCurrentMenu.IsInitialized)
+ {
+ // Supports unit tests
+ openCurrentMenu.BeginInit ();
+ openCurrentMenu.EndInit ();
+ }
}
_selectedSub = _openSubMenu.Count - 1;
diff --git a/Terminal.Gui/Views/Toplevel.cs b/Terminal.Gui/Views/Toplevel.cs
index e5f4b64b1..5c9ca2414 100644
--- a/Terminal.Gui/Views/Toplevel.cs
+++ b/Terminal.Gui/Views/Toplevel.cs
@@ -389,6 +389,12 @@ public partial class Toplevel : View
out int ny,
out StatusBar sb
);
+
+ if (superView is null)
+ {
+ return;
+ }
+
var layoutSubviews = false;
var maxWidth = 0;
diff --git a/UnitTests/Text/TextFormatterTests.cs b/UnitTests/Text/TextFormatterTests.cs
index b0937cefc..a879c9d5d 100644
--- a/UnitTests/Text/TextFormatterTests.cs
+++ b/UnitTests/Text/TextFormatterTests.cs
@@ -3638,4 +3638,30 @@ ek")]
TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output);
}
+
+
+ [Theory]
+ [InlineData ("1234", 4)]
+ [InlineData ("_1234", 4)]
+ public void AutoSize_HotKey_Size_Correct (string text, int expected)
+ {
+ // Horizontal
+ TextFormatter tf = new ()
+ {
+ AutoSize = true,
+ HotKeySpecifier = (Rune)'_',
+ Text = text,
+ };
+ Assert.Equal (new (expected, 1), tf.Size);
+
+ // Vertical
+ tf = new ()
+ {
+ HotKeySpecifier = (Rune)'_',
+ Direction = TextDirection.TopBottom_LeftRight,
+ Text = text,
+ AutoSize = true,
+ };
+ Assert.Equal (new (1, expected), tf.Size);
+ }
}
diff --git a/UnitTests/View/DrawTests.cs b/UnitTests/View/DrawTests.cs
index 3dfa1787c..6cfa1b98d 100644
--- a/UnitTests/View/DrawTests.cs
+++ b/UnitTests/View/DrawTests.cs
@@ -1,12 +1,11 @@
#nullable enable
using System.Text;
using Xunit.Abstractions;
-using static System.Net.Mime.MediaTypeNames;
namespace Terminal.Gui.ViewTests;
[Trait ("Category", "Output")]
-public class DrawTests (ITestOutputHelper output)
+public class DrawTests (ITestOutputHelper _output)
{
[Fact]
[SetupFakeDriver]
@@ -90,7 +89,7 @@ public class DrawTests (ITestOutputHelper output)
┌─┐
│X│
└─┘",
- output);
+ _output);
Rectangle toFill = new (x, y, width, height);
view.FillRect (toFill);
@@ -99,7 +98,7 @@ public class DrawTests (ITestOutputHelper output)
┌─┐
│ │
└─┘",
- output);
+ _output);
// Now try to clear beyond Viewport (invalid; clipping should prevent)
superView.SetNeedsDisplay ();
@@ -109,7 +108,7 @@ public class DrawTests (ITestOutputHelper output)
┌─┐
│X│
└─┘",
- output);
+ _output);
toFill = new (-width, -height, width, height);
view.FillRect (toFill);
TestHelpers.AssertDriverContentsWithFrameAre (
@@ -117,7 +116,7 @@ public class DrawTests (ITestOutputHelper output)
┌─┐
│X│
└─┘",
- output);
+ _output);
// Now try to clear beyond Viewport (valid)
superView.SetNeedsDisplay ();
@@ -127,7 +126,7 @@ public class DrawTests (ITestOutputHelper output)
┌─┐
│X│
└─┘",
- output);
+ _output);
toFill = new (-1, -1, width + 1, height + 1);
view.FillRect (toFill);
TestHelpers.AssertDriverContentsWithFrameAre (
@@ -135,7 +134,7 @@ public class DrawTests (ITestOutputHelper output)
┌─┐
│ │
└─┘",
- output);
+ _output);
// Now clear too much size
superView.SetNeedsDisplay ();
@@ -145,7 +144,7 @@ public class DrawTests (ITestOutputHelper output)
┌─┐
│X│
└─┘",
- output);
+ _output);
toFill = new (0, 0, width * 2, height * 2);
view.FillRect (toFill);
TestHelpers.AssertDriverContentsWithFrameAre (
@@ -153,7 +152,7 @@ public class DrawTests (ITestOutputHelper output)
┌─┐
│ │
└─┘",
- output);
+ _output);
}
[Theory]
@@ -183,7 +182,7 @@ public class DrawTests (ITestOutputHelper output)
┌─┐
│X│
└─┘",
- output);
+ _output);
view.Clear ();
TestHelpers.AssertDriverContentsWithFrameAre (
@@ -191,7 +190,7 @@ public class DrawTests (ITestOutputHelper output)
┌─┐
│ │
└─┘",
- output);
+ _output);
}
[Theory]
@@ -222,7 +221,7 @@ public class DrawTests (ITestOutputHelper output)
┌─┐
│X│
└─┘",
- output);
+ _output);
view.Clear ();
TestHelpers.AssertDriverContentsWithFrameAre (
@@ -230,7 +229,7 @@ public class DrawTests (ITestOutputHelper output)
┌─┐
│ │
└─┘",
- output);
+ _output);
}
@@ -266,9 +265,9 @@ public class DrawTests (ITestOutputHelper output)
│豈 │
└────────┘
""";
- TestHelpers.AssertDriverContentsWithFrameAre (expectedOutput, output);
+ TestHelpers.AssertDriverContentsWithFrameAre (expectedOutput, _output);
- TestHelpers.AssertDriverContentsAre (expectedOutput, output);
+ TestHelpers.AssertDriverContentsAre (expectedOutput, _output);
// This test has nothing to do with color - removing as it is not relevant and fragile
}
@@ -323,7 +322,7 @@ public class DrawTests (ITestOutputHelper output)
└────────────────────────────┘
""";
- Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expectedOutput, output);
+ Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expectedOutput, _output);
Assert.Equal (new Rectangle (0, 0, 30, 10), pos);
Application.End (rsDiag);
@@ -371,7 +370,7 @@ public class DrawTests (ITestOutputHelper output)
s
t
""",
- output
+ _output
);
TestHelpers.AssertDriverAttributesAre (
@@ -410,7 +409,7 @@ public class DrawTests (ITestOutputHelper output)
┌┐
└┘
""",
- output
+ _output
);
}
@@ -429,7 +428,7 @@ public class DrawTests (ITestOutputHelper output)
view.Draw ();
- TestHelpers.AssertDriverContentsWithFrameAre (string.Empty, output);
+ TestHelpers.AssertDriverContentsWithFrameAre (string.Empty, _output);
}
[Fact]
@@ -453,7 +452,7 @@ public class DrawTests (ITestOutputHelper output)
│
│
""",
- output
+ _output
);
}
@@ -478,7 +477,7 @@ public class DrawTests (ITestOutputHelper output)
│
│
""",
- output
+ _output
);
}
@@ -504,7 +503,7 @@ public class DrawTests (ITestOutputHelper output)
┌┐
""",
- output
+ _output
);
}
@@ -581,7 +580,7 @@ public class DrawTests (ITestOutputHelper output)
3V
4i
""",
- output
+ _output
);
content.X = -1;
@@ -596,12 +595,12 @@ public class DrawTests (ITestOutputHelper output)
V
i
""",
- output
+ _output
);
content.X = -2;
Application.Refresh ();
- TestHelpers.AssertDriverContentsWithFrameAre (@"", output);
+ TestHelpers.AssertDriverContentsWithFrameAre (@"", _output);
content.X = 0;
content.Y = -1;
@@ -616,7 +615,7 @@ public class DrawTests (ITestOutputHelper output)
4i
5e
""",
- output
+ _output
);
content.Y = -6;
@@ -631,7 +630,7 @@ public class DrawTests (ITestOutputHelper output)
9
0
""",
- output
+ _output
);
content.Y = -19;
@@ -642,17 +641,17 @@ public class DrawTests (ITestOutputHelper output)
9
""",
- output
+ _output
);
content.Y = -20;
Application.Refresh ();
- TestHelpers.AssertDriverContentsWithFrameAre ("", output);
+ TestHelpers.AssertDriverContentsWithFrameAre ("", _output);
content.X = -2;
content.Y = 0;
Application.Refresh ();
- TestHelpers.AssertDriverContentsWithFrameAre ("", output);
+ TestHelpers.AssertDriverContentsWithFrameAre ("", _output);
}
[Fact]
@@ -698,7 +697,7 @@ public class DrawTests (ITestOutputHelper output)
01234
subVi
""",
- output
+ _output
);
content.X = -1;
@@ -710,7 +709,7 @@ public class DrawTests (ITestOutputHelper output)
12345
ubVie
""",
- output
+ _output
);
content.Y = -1;
@@ -721,17 +720,17 @@ public class DrawTests (ITestOutputHelper output)
ubVie
""",
- output
+ _output
);
content.Y = -2;
Application.Refresh ();
- TestHelpers.AssertDriverContentsWithFrameAre ("", output);
+ TestHelpers.AssertDriverContentsWithFrameAre ("", _output);
content.X = -20;
content.Y = 0;
Application.Refresh ();
- TestHelpers.AssertDriverContentsWithFrameAre ("", output);
+ TestHelpers.AssertDriverContentsWithFrameAre ("", _output);
}
[Fact]
@@ -783,7 +782,7 @@ public class DrawTests (ITestOutputHelper output)
3V
4i
""",
- output
+ _output
);
content.X = -1;
@@ -798,12 +797,12 @@ public class DrawTests (ITestOutputHelper output)
V
i
""",
- output
+ _output
);
content.X = -2;
Application.Refresh ();
- TestHelpers.AssertDriverContentsWithFrameAre (@"", output);
+ TestHelpers.AssertDriverContentsWithFrameAre (@"", _output);
content.X = 0;
content.Y = -1;
@@ -818,7 +817,7 @@ public class DrawTests (ITestOutputHelper output)
4i
5e
""",
- output
+ _output
);
content.Y = -6;
@@ -833,7 +832,7 @@ public class DrawTests (ITestOutputHelper output)
9
0
""",
- output
+ _output
);
content.Y = -19;
@@ -844,17 +843,17 @@ public class DrawTests (ITestOutputHelper output)
9
""",
- output
+ _output
);
content.Y = -20;
Application.Refresh ();
- TestHelpers.AssertDriverContentsWithFrameAre ("", output);
+ TestHelpers.AssertDriverContentsWithFrameAre ("", _output);
content.X = -2;
content.Y = 0;
Application.Refresh ();
- TestHelpers.AssertDriverContentsWithFrameAre ("", output);
+ TestHelpers.AssertDriverContentsWithFrameAre ("", _output);
}
[Theory]
@@ -866,7 +865,7 @@ public class DrawTests (ITestOutputHelper output)
var view = new View { Width = 10, Height = 1 };
view.DrawHotString (expected, Attribute.Default, Attribute.Default);
- TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
+ TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
}
// TODO: The tests below that use Label should use View instead.
@@ -901,9 +900,9 @@ public class DrawTests (ITestOutputHelper output)
│𝔹 │
└────────┘
""";
- TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
+ TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
- TestHelpers.AssertDriverContentsAre (expected, output);
+ TestHelpers.AssertDriverContentsAre (expected, _output);
// This test has nothing to do with color - removing as it is not relevant and fragile
}
@@ -1040,4 +1039,91 @@ public class DrawTests (ITestOutputHelper output)
// Shutdown must be called to safely clean up Application if Init has been called
Application.Shutdown ();
}
+
+ //TODO: Expand this test to cover Vertical Alignment as well
+ [SetupFakeDriver]
+ [Theory]
+ [InlineData ("0 2 4", TextAlignment.Left, @"
+0 2 4**
+*******
+*******
+*******
+*******
+*******
+*******")]
+ [InlineData ("0 2 4", TextAlignment.Right, @"
+**0 2 4
+*******
+*******
+*******
+*******
+*******
+*******")]
+ [InlineData ("0 2 4", TextAlignment.Centered, @"
+*0 2 4*
+*******
+*******
+*******
+*******
+*******
+*******")]
+
+ [InlineData ("0 2 4", TextAlignment.Justified, @"
+0 2 4
+*******
+*******
+*******
+*******
+*******
+*******")]
+
+ [InlineData ("0 2 4", TextAlignment.Left, @"
+0 2 4**
+*******
+*******
+*******
+*******
+*******
+*******")]
+ [InlineData ("0 你 4", TextAlignment.Right, @"
+*0 你 4
+*******
+*******
+*******
+*******
+*******
+*******")]
+ [InlineData ("0 你 4", TextAlignment.Centered, @"
+0 你 4*
+*******
+*******
+*******
+*******
+*******
+*******")]
+
+ [InlineData ("0 你 4", TextAlignment.Justified, @"
+0 你 4
+*******
+*******
+*******
+*******
+*******
+*******")]
+ public void Daw_Text_Alignment (string text, TextAlignment textAlignment, string expectedText)
+ {
+ View view = new ()
+ {
+ TextAlignment = textAlignment,
+ Text = text,
+ Width = 7,
+ Height = 7
+ };
+
+ Assert.Equal (new Size (7, 7), view.TextFormatter.Size);
+ Assert.True (view.NeedsDisplay);
+ Application.Driver.FillRect (view.Frame, (Rune)'*');
+ view.Draw ();
+ TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output);
+ }
}
diff --git a/UnitTests/View/Layout/Dim.AutoTests.cs b/UnitTests/View/Layout/Dim.AutoTests.cs
index d99c4e960..2db422a66 100644
--- a/UnitTests/View/Layout/Dim.AutoTests.cs
+++ b/UnitTests/View/Layout/Dim.AutoTests.cs
@@ -3,10 +3,6 @@ using System.Text;
using Xunit.Abstractions;
using static Terminal.Gui.Dim;
-
-// Alias Console to MockConsole so we don't accidentally use Console
-using Console = Terminal.Gui.FakeConsole;
-
namespace Terminal.Gui.PosDimTests;
public class DimAutoTests (ITestOutputHelper output)
@@ -788,6 +784,105 @@ public class DimAutoTests (ITestOutputHelper output)
Assert.True (view.TextFormatter.AutoSize);
}
+ [Theory]
+ [InlineData ("1234", 4)]
+ [InlineData ("_1234", 4)]
+ public void Width_Auto_HotKey_TextFormatter_Size_Correct (string text, int expected)
+ {
+ View view = new ()
+ {
+ Text = text,
+ Height = 1,
+ Width = Dim.Auto ()
+ };
+ Assert.Equal (new (expected, 1), view.TextFormatter.Size);
+ }
+
+ [Theory]
+ [InlineData ("1234", 4)]
+ [InlineData ("_1234", 4)]
+ public void Height_Auto_HotKey_TextFormatter_Size_Correct (string text, int expected)
+ {
+ View view = new ()
+ {
+ HotKeySpecifier = (Rune)'_',
+ Text = text,
+ Width = Auto (),
+ Height = 1,
+ };
+ Assert.Equal (new (expected, 1), view.TextFormatter.Size);
+
+ view = new ()
+ {
+ HotKeySpecifier = (Rune)'_',
+ TextDirection = TextDirection.TopBottom_LeftRight,
+ Text = text,
+ Width = 1,
+ Height = Auto (),
+ };
+ Assert.Equal (new (1, expected), view.TextFormatter.Size);
+ }
+
+
+ [SetupFakeDriver]
+ [Fact]
+ public void DimAuto_ChangeToANonDimAuto_Resets_ContentSize ()
+ {
+ View view = new ()
+ {
+ Width = Auto (),
+ Height = Auto (),
+ Text = "01234"
+ };
+
+ Assert.Equal (new Rectangle (0, 0, 5, 1), view.Frame);
+ Assert.Equal (new Size (5, 1), view.ContentSize);
+
+ // Change text to a longer string
+ view.Text = "0123456789";
+
+ Assert.Equal (new Rectangle (0, 0, 10, 1), view.Frame);
+ Assert.Equal (new Size (10, 1), view.ContentSize);
+
+ // If ContentSize was reset, these should cause it to update
+ view.Width = 5;
+ view.Height = 1;
+
+ Assert.Equal (new Size (5, 1), view.ContentSize);
+ }
+ [SetupFakeDriver]
+ [Fact]
+ public void DimAuto_ChangeNonDimAuto_Via_AutoSize_False_Resets_ContentSize ()
+ {
+ View view = new ()
+ {
+ Width = Auto (),
+ Height = Auto(),
+ Text = "01234"
+ };
+
+ Assert.Equal (new Rectangle (0, 0, 5, 1), view.Frame);
+ Assert.Equal (new Size (5, 1), view.ContentSize);
+
+ // Change text to a longer string
+ view.Text = "0123456789";
+
+ Assert.Equal (new Rectangle (0, 0, 10, 1), view.Frame);
+ Assert.Equal (new Size (10, 1), view.ContentSize);
+
+ // Cause Width/Height to be set to absolute. This should reset ContentSize
+ view.AutoSize = false;
+
+ Assert.Equal (new Rectangle (0, 0, 10, 1), view.Frame);
+ Assert.Equal (new Size (10, 1), view.ContentSize);
+
+ // If ContentSize was reset, these should cause it to update
+ view.Width = 5;
+ view.Height = 1;
+
+ Assert.Equal(new Size (5,1), view.ContentSize);
+ }
+
// Test variations of Frame
}
diff --git a/UnitTests/View/Layout/Dim.Tests.cs b/UnitTests/View/Layout/Dim.Tests.cs
index 113ae01c2..6e5e9bbd3 100644
--- a/UnitTests/View/Layout/Dim.Tests.cs
+++ b/UnitTests/View/Layout/Dim.Tests.cs
@@ -520,11 +520,11 @@ public class DimTests
Assert.Equal ("Absolute(50)", v4.Height.ToString ());
Assert.Equal (50, v4.Frame.Width);
Assert.Equal (50, v4.Frame.Height);
- #if DEBUG
+#if DEBUG
Assert.Equal ($"Combine(View(Width,Button(v1){v1.Frame})-View(Width,Button(v3){v3.Viewport}))", v5.Width.ToString ());
- #else
+#else
Assert.Equal ($"Combine(View(Height,Button(){v1.Frame})-View(Height,Button(){v3.Viewport}))", v5.Height.ToString ( ));
- #endif
+#endif
Assert.Equal (38, v5.Frame.Width); // 47-9=38
Assert.Equal (80, v5.Frame.Height); // 89-9=80
@@ -586,8 +586,6 @@ public class DimTests
Assert.Equal (19, v3.Frame.Height);
v4.Text = "Button4";
- v4.AutoSize = false;
- Assert.Equal (new (4, 1), v4.Frame.Size);
v4.AutoSize = true;
Assert.Equal (Dim.Auto (DimAutoStyle.Text), v4.Width);
Assert.Equal (Dim.Auto (DimAutoStyle.Text), v4.Height);
@@ -683,7 +681,7 @@ public class DimTests
dim = Dim.Sized (testVal);
Assert.Equal ($"Absolute({testVal})", dim.ToString ());
}
-
+
// TODO: This actually a SetRelativeLayout/LayoutSubViews test and should be moved
// TODO: A new test that calls SetRelativeLayout directly is needed.
[Fact]
diff --git a/UnitTests/View/Text/AutoSizeTrueTests.cs b/UnitTests/View/Text/AutoSizeTrueTests.cs
index 9cd91199d..6c4b1cad6 100644
--- a/UnitTests/View/Text/AutoSizeTrueTests.cs
+++ b/UnitTests/View/Text/AutoSizeTrueTests.cs
@@ -821,7 +821,7 @@ public class AutoSizeTrueTests
Assert.Equal (5, text.Length);
Assert.False (label.AutoSize);
Assert.Equal (new (0, 0, 3, 0), label.Frame);
- Assert.Equal (new (5, 1), label.TextFormatter.Size);
+ //Assert.Equal (new (5, 1), label.TextFormatter.Size);
Assert.Single (label.TextFormatter.GetLines ());
Assert.Equal (new (0, 0, 10, 4), win.Frame);
@@ -843,7 +843,7 @@ public class AutoSizeTrueTests
win.Draw ();
Assert.Equal (Rectangle.Empty, label.Frame);
- Assert.Equal (new (5, 1), label.TextFormatter.Size);
+// Assert.Equal (new (5, 1), label.TextFormatter.Size);
//Exception exception = Record.Exception (
// () => Assert.Equal (
diff --git a/UnitTests/Views/ButtonTests.cs b/UnitTests/Views/ButtonTests.cs
index fbf0c29d2..502a16f1d 100644
--- a/UnitTests/Views/ButtonTests.cs
+++ b/UnitTests/Views/ButtonTests.cs
@@ -268,15 +268,14 @@ public class ButtonTests (ITestOutputHelper output)
{
var btn1 = new Button
{
- X = 0,
- Y = 0,
+ Text = text,
Width = width,
Height = height,
- Text = text
};
Assert.Equal (new Size (expectedWidth, expectedHeight), btn1.Frame.Size);
Assert.Equal (new Size (expectedWidth, expectedHeight), btn1.Viewport.Size);
+ Assert.Equal (new Size (expectedWidth, expectedHeight), btn1.ContentSize);
Assert.Equal (new Size (expectedWidth, expectedHeight), btn1.TextFormatter.Size);
btn1.Dispose ();
@@ -293,8 +292,6 @@ public class ButtonTests (ITestOutputHelper output)
{
var btn1 = new Button
{
- X = 0,
- Y = 0,
Width = width,
Height = height,
};
@@ -396,6 +393,10 @@ public class ButtonTests (ITestOutputHelper output)
btn.Dispose ();
btn = new () { Text = "_Test", IsDefault = true };
+ Assert.Equal (new (10, 1), btn.TextFormatter.Size);
+
+
+
btn.BeginInit ();
btn.EndInit ();
Assert.Equal ('_', btn.HotKeySpecifier.Value);
@@ -413,6 +414,10 @@ public class ButtonTests (ITestOutputHelper output)
btn.SetRelativeLayout (new (100, 100));
// 0123456789012345678901234567890123456789
// [* Test *]
+ Assert.Equal ('_', btn.HotKeySpecifier.Value);
+ Assert.Equal (10, btn.TextFormatter.Format ().Length);
+ Assert.Equal (new (10, 1), btn.TextFormatter.Size);
+ Assert.Equal (new (10, 1), btn.ContentSize);
Assert.Equal (new (0, 0, 10, 1), btn.Viewport);
Assert.Equal (new (0, 0, 10, 1), btn.Frame);
Assert.Equal (KeyCode.T, btn.HotKey);
diff --git a/UnitTests/Views/CheckBoxTests.cs b/UnitTests/Views/CheckBoxTests.cs
index 697628f4f..c308cbfd5 100644
--- a/UnitTests/Views/CheckBoxTests.cs
+++ b/UnitTests/Views/CheckBoxTests.cs
@@ -491,11 +491,9 @@ public class CheckBoxTests
Assert.Equal (TextAlignment.Justified, checkBox1.TextAlignment);
Assert.Equal (new (1, 1, 25, 1), checkBox1.Frame);
- Assert.Equal (_size25x1, checkBox1.TextFormatter.Size);
Assert.Equal (TextAlignment.Justified, checkBox2.TextAlignment);
Assert.Equal (new (1, 2, 25, 1), checkBox2.Frame);
- Assert.Equal (_size25x1, checkBox2.TextFormatter.Size);
-
+
var expected = @$"
┌┤Test Demo 你├──────────────┐
│ │
diff --git a/UnitTests/Views/MenuBarTests.cs b/UnitTests/Views/MenuBarTests.cs
index 9a53bfaee..8c91ff9cb 100644
--- a/UnitTests/Views/MenuBarTests.cs
+++ b/UnitTests/Views/MenuBarTests.cs
@@ -3068,15 +3068,15 @@ Edit
};
menu.UseKeysUpDownAsKeysLeftRight = true;
- var top = new Toplevel ();
- top.Add (menu);
- Application.Begin (top);
+ menu.BeginInit();
+ menu.EndInit();
- Assert.Equal (Point.Empty, new Point (menu.Frame.X, menu.Frame.Y));
- Assert.False (menu.UseSubMenusSingleFrame);
+ menu.OpenMenu();
+ menu.ColorScheme = menu._openMenu.ColorScheme = new ColorScheme (Attribute.Default);
+ Assert.True (menu.IsMenuOpen);
- Assert.True (menu.NewKeyDownEvent (menu.Key));
- top.Draw ();
+ menu.Draw ();
+ menu._openMenu.Draw ();
var expected = @"
Numbers
@@ -3086,8 +3086,10 @@ Edit
_ = TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
- Assert.True (Application.Top.Subviews [1].NewKeyDownEvent (Key.CursorDown));
- top.Draw ();
+ Assert.True (menu._openMenu.NewKeyDownEvent (Key.CursorDown));
+ menu.Draw ();
+ menu._openMenu.Draw ();
+ menu.openCurrentMenu.Draw ();
expected = @"
Numbers
@@ -3354,17 +3356,17 @@ Edit
)
]
};
- var top = new Toplevel ();
- top.Add (menu);
- Application.Begin (top);
- Assert.Equal (Point.Empty, new Point (menu.Frame.X, menu.Frame.Y));
- Assert.False (menu.UseSubMenusSingleFrame);
menu.UseSubMenusSingleFrame = true;
- Assert.True (menu.UseSubMenusSingleFrame);
+ menu.BeginInit ();
+ menu.EndInit ();
- Assert.True (menu.NewKeyDownEvent (menu.Key));
- top.Draw ();
+ menu.OpenMenu ();
+ Assert.True (menu.IsMenuOpen);
+
+ menu.Draw ();
+ menu.ColorScheme = menu._openMenu.ColorScheme = new ColorScheme (Attribute.Default);
+ menu._openMenu.Draw ();
var expected = @"
Numbers
@@ -3374,9 +3376,11 @@ Edit
_ = TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
- Assert.True (Application.Top.Subviews [1].NewKeyDownEvent (Key.CursorDown));
- Assert.True (Application.Top.Subviews [1].NewKeyDownEvent (Key.Enter));
- top.Draw ();
+ Assert.True (menu._openMenu.NewKeyDownEvent (Key.CursorDown));
+ Assert.True (menu._openMenu.NewKeyDownEvent (Key.Enter));
+ menu.Draw ();
+ menu._openMenu.Draw ();
+ menu.openCurrentMenu.Draw ();
expected = @"
Numbers