mirror of
https://github.com/gui-cs/Terminal.Gui.git
synced 2026-01-02 01:03:29 +01:00
Fixed stoopid screen bug
This commit is contained in:
@@ -3,28 +3,13 @@ namespace Terminal.Gui;
|
||||
|
||||
public static partial class Application // Screen related stuff
|
||||
{
|
||||
private static Size _screenSize = new (2048, 2048);
|
||||
|
||||
/// <summary>
|
||||
/// INTERNAL API for Unit Tests. Only works if there's no driver.
|
||||
/// </summary>
|
||||
/// <param name="size"></param>
|
||||
internal static void SetScreenSize (Size size)
|
||||
{
|
||||
if (Driver is { })
|
||||
{
|
||||
throw new InvalidOperationException ("Cannot set the screen size when the ConsoleDriver is already initialized.");
|
||||
}
|
||||
_screenSize = size;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the size of the screen. This is the size of the screen as reported by the <see cref="ConsoleDriver"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// If the <see cref="ConsoleDriver"/> has not been initialized, this will return a default size of 2048x2048; useful for unit tests.
|
||||
/// </remarks>
|
||||
public static Rectangle Screen => Driver?.Screen ?? new (new (0, 0), _screenSize);
|
||||
public static Rectangle Screen => Driver?.Screen ?? new (new (0, 0), new (2048, 2048));
|
||||
|
||||
/// <summary>Invoked when the terminal's size changed. The new size of the terminal is provided.</summary>
|
||||
/// <remarks>
|
||||
|
||||
@@ -62,7 +62,8 @@ public class Adornment : View
|
||||
if (current != _thickness)
|
||||
{
|
||||
Parent?.SetAdornmentFrames ();
|
||||
Parent?.SetLayoutNeeded ();
|
||||
SetLayoutNeeded ();
|
||||
//Parent?.SetLayoutNeeded ();
|
||||
|
||||
OnThicknessChanged ();
|
||||
}
|
||||
|
||||
@@ -167,7 +167,7 @@ public partial class View // Layout APIs
|
||||
|
||||
#region Frame
|
||||
|
||||
private Rectangle _frame;
|
||||
private Rectangle? _frame;
|
||||
|
||||
/// <summary>Gets or sets the absolute location and dimension of the view.</summary>
|
||||
/// <value>
|
||||
@@ -199,7 +199,7 @@ public partial class View // Layout APIs
|
||||
{
|
||||
//Debug.WriteLine("Frame_get with _layoutNeeded");
|
||||
}
|
||||
return _frame;
|
||||
return _frame ?? Rectangle.Empty;
|
||||
}
|
||||
set
|
||||
{
|
||||
@@ -207,10 +207,10 @@ public partial class View // Layout APIs
|
||||
if (SetFrame (value with { Width = Math.Max (value.Width, 0), Height = Math.Max (value.Height, 0) }))
|
||||
{
|
||||
// If Frame gets set, set all Pos/Dim to Absolute values.
|
||||
_x = _frame.X;
|
||||
_y = _frame.Y;
|
||||
_width = _frame.Width;
|
||||
_height = _frame.Height;
|
||||
_x = _frame!.Value.X;
|
||||
_y = _frame!.Value.Y;
|
||||
_width = _frame!.Value.Width;
|
||||
_height = _frame!.Value.Height;
|
||||
|
||||
// Implicit layout is ok here because we are setting the Frame directly.
|
||||
Layout ();
|
||||
@@ -308,6 +308,18 @@ public partial class View // Layout APIs
|
||||
return frame;
|
||||
}
|
||||
|
||||
// helper for X, Y, Width, Height setters to ensure consistency
|
||||
private void PosDimSet ()
|
||||
{
|
||||
SetLayoutNeeded ();
|
||||
|
||||
if (_x is PosAbsolute && _y is PosAbsolute && _width is DimAbsolute && _height is DimAbsolute)
|
||||
{
|
||||
// Implicit layout is ok here because all Pos/Dim are Absolute values.
|
||||
Layout ();
|
||||
}
|
||||
}
|
||||
|
||||
private Pos _x = Pos.Absolute (0);
|
||||
|
||||
/// <summary>Gets or sets the X position for the view (the column).</summary>
|
||||
@@ -346,22 +358,10 @@ public partial class View // Layout APIs
|
||||
|
||||
_x = value ?? throw new ArgumentNullException (nameof (value), @$"{nameof (X)} cannot be null");
|
||||
|
||||
SetLayoutNeeded ();
|
||||
|
||||
if (IsAbsoluteLayout ())
|
||||
{
|
||||
// Implicit layout is ok here because all Pos/Dim are Absolute values.
|
||||
Layout ();
|
||||
SetLayoutNeeded ();
|
||||
}
|
||||
PosDimSet ();
|
||||
}
|
||||
}
|
||||
|
||||
private bool IsAbsoluteLayout ()
|
||||
{
|
||||
return _x is PosAbsolute && _y is PosAbsolute && _width is DimAbsolute && _height is DimAbsolute;
|
||||
}
|
||||
|
||||
private Pos _y = Pos.Absolute (0);
|
||||
|
||||
|
||||
@@ -400,15 +400,7 @@ public partial class View // Layout APIs
|
||||
}
|
||||
|
||||
_y = value ?? throw new ArgumentNullException (nameof (value), @$"{nameof (Y)} cannot be null");
|
||||
|
||||
SetLayoutNeeded ();
|
||||
|
||||
if (IsAbsoluteLayout ())
|
||||
{
|
||||
// Implicit layout is ok here because all Pos/Dim are Absolute values.
|
||||
Layout ();
|
||||
SetLayoutNeeded ();
|
||||
}
|
||||
PosDimSet ();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -459,14 +451,7 @@ public partial class View // Layout APIs
|
||||
// Reset TextFormatter - Will be recalculated in SetTextFormatterSize
|
||||
TextFormatter.ConstrainToHeight = null;
|
||||
|
||||
SetLayoutNeeded ();
|
||||
|
||||
if (IsAbsoluteLayout ())
|
||||
{
|
||||
// Implicit layout is ok here because all Pos/Dim are Absolute values.
|
||||
Layout ();
|
||||
SetLayoutNeeded ();
|
||||
}
|
||||
PosDimSet ();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -517,15 +502,7 @@ public partial class View // Layout APIs
|
||||
|
||||
// Reset TextFormatter - Will be recalculated in SetTextFormatterSize
|
||||
TextFormatter.ConstrainToWidth = null;
|
||||
|
||||
SetLayoutNeeded ();
|
||||
|
||||
if (IsAbsoluteLayout ())
|
||||
{
|
||||
// Implicit layout is ok here because all Pos/Dim are Absolute values.
|
||||
Layout ();
|
||||
SetLayoutNeeded ();
|
||||
}
|
||||
PosDimSet ();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
#nullable enable
|
||||
using System.Text;
|
||||
using Microsoft.VisualStudio.TestPlatform.Utilities;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Terminal.Gui.ViewTests;
|
||||
|
||||
[Trait ("Category", "Output")]
|
||||
@@ -116,7 +112,7 @@ public class NeedsDisplayTests ()
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NeedsDisplay_False_After_SetRelativeLayout ()
|
||||
public void NeedsDisplay_False_After_SetRelativeLayout_Absolute_Dims ()
|
||||
{
|
||||
var view = new View { Width = 2, Height = 2 };
|
||||
Assert.True (view.NeedsDisplay);
|
||||
@@ -131,16 +127,22 @@ public class NeedsDisplayTests ()
|
||||
Assert.False (view.NeedsDisplay);
|
||||
|
||||
view.SetLayoutNeeded ();
|
||||
|
||||
// SRL won't change anything since the view is Absolute
|
||||
view.SetRelativeLayout (Application.Screen.Size);
|
||||
Assert.True (view.NeedsDisplay);
|
||||
|
||||
view.NeedsDisplay = false;
|
||||
|
||||
// SRL won't change anything since the view is Absolute. However, Layout has not been called
|
||||
view.SetRelativeLayout (new (10, 10));
|
||||
Assert.True (view.NeedsDisplay);
|
||||
}
|
||||
|
||||
view = new View { Width = Dim.Percent (50), Height = Dim.Percent (50) };
|
||||
[Fact]
|
||||
public void NeedsDisplay_False_After_SetRelativeLayout_Relative_Dims ()
|
||||
{
|
||||
var view = new View { Width = Dim.Percent (50), Height = Dim.Percent (50) };
|
||||
View superView = new ()
|
||||
{
|
||||
Id = "superView",
|
||||
@@ -164,18 +166,25 @@ public class NeedsDisplayTests ()
|
||||
superView.SetRelativeLayout (Application.Screen.Size);
|
||||
Assert.True (view.NeedsDisplay);
|
||||
Assert.True (superView.NeedsDisplay);
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public void NeedsDisplay_False_After_SetRelativeLayout_10x10 ()
|
||||
{
|
||||
View superView = new ()
|
||||
{
|
||||
Id = "superView",
|
||||
Width = Dim.Fill (),
|
||||
Height = Dim.Fill ()
|
||||
};
|
||||
Assert.True (superView.NeedsDisplay);
|
||||
|
||||
superView.Layout ();
|
||||
|
||||
superView.NeedsDisplay = false;
|
||||
superView.SetRelativeLayout (new (10, 10));
|
||||
Assert.True (superView.NeedsDisplay);
|
||||
Assert.True (view.NeedsDisplay);
|
||||
|
||||
superView.Layout ();
|
||||
|
||||
view.SetRelativeLayout (new (11, 11));
|
||||
Assert.True (superView.NeedsDisplay);
|
||||
Assert.True (view.NeedsDisplay);
|
||||
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -258,7 +267,7 @@ public class NeedsDisplayTests ()
|
||||
view.Frame = new (3, 3, 6, 6); // Grow right/bottom 1
|
||||
Assert.Equal (new (3, 3, 6, 6), view.Frame);
|
||||
Assert.Equal (new (0, 0, 6, 6), view.Viewport);
|
||||
Assert.Equal (new (0, 0, 6, 6), view._needsDisplayRect);
|
||||
Assert.Equal (new (0, 0, 6, 6), view._needsDisplayRect);
|
||||
|
||||
view.Frame = new (3, 3, 5, 5); // Shrink right/bottom 1
|
||||
Assert.Equal (new (3, 3, 5, 5), view.Frame);
|
||||
@@ -278,7 +287,7 @@ public class NeedsDisplayTests ()
|
||||
view.Frame = new (3, 3, 6, 6); // Grow right/bottom 1
|
||||
Assert.Equal (new (3, 3, 6, 6), view.Frame);
|
||||
Assert.Equal (new (1, 1, 6, 6), view.Viewport);
|
||||
Assert.Equal (new (1, 1, 6, 6), view._needsDisplayRect);
|
||||
Assert.Equal (new (1, 1, 6, 6), view._needsDisplayRect);
|
||||
|
||||
view.Frame = new (3, 3, 5, 5);
|
||||
Assert.Equal (new (3, 3, 5, 5), view.Frame);
|
||||
|
||||
@@ -994,9 +994,10 @@ public partial class DimAutoTests (ITestOutputHelper output)
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[SetupFakeDriver]
|
||||
public void DimAutoStyle_Content_Pos_AnchorEnd_Locates_Correctly ()
|
||||
{
|
||||
Application.SetScreenSize (new Size (10, 10));
|
||||
(((FakeDriver)Application.Driver)!).SetBufferSize(10,10);
|
||||
|
||||
DimAutoTestView view = new (Auto (DimAutoStyle.Content), Auto (DimAutoStyle.Content));
|
||||
|
||||
|
||||
@@ -22,14 +22,171 @@ public class FrameTests (ITestOutputHelper output)
|
||||
{
|
||||
Rectangle frame = new (1, 2, 3, 4);
|
||||
View view = new ();
|
||||
Assert.False (view.NeedsLayout);
|
||||
Assert.Equal (Rectangle.Empty, view.Frame);
|
||||
|
||||
view.BeginInit ();
|
||||
view.EndInit ();
|
||||
view.Frame = frame;
|
||||
Assert.Equal (frame, view.Frame);
|
||||
Assert.False (view.NeedsLayout);
|
||||
|
||||
Assert.Equal(view.X, frame.X);
|
||||
Assert.Equal (view.Y, frame.Y);
|
||||
Assert.Equal (view.Width, frame.Width);
|
||||
Assert.Equal (view.Height, frame.Height);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Frame_Initializer_Sets ()
|
||||
{
|
||||
Rectangle frame = new (1, 2, 3, 4);
|
||||
View view = new ()
|
||||
{
|
||||
Frame = frame,
|
||||
};
|
||||
|
||||
Assert.Equal (frame, view.Frame);
|
||||
Assert.False (view.NeedsLayout);
|
||||
Assert.Equal (frame.Size, view.Viewport.Size);
|
||||
|
||||
|
||||
Assert.Equal (view.X, frame.X);
|
||||
Assert.Equal (view.Y, frame.Y);
|
||||
Assert.Equal (view.Width, frame.Width);
|
||||
Assert.Equal (view.Height, frame.Height);
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public void Frame_Empty_Initializer_Sets ()
|
||||
{
|
||||
Rectangle frame = new (1, 2, 3, 4);
|
||||
View view = new ()
|
||||
{
|
||||
Frame = frame,
|
||||
};
|
||||
|
||||
Assert.Equal (frame, view.Frame);
|
||||
Assert.False (view.NeedsLayout);
|
||||
Assert.Equal (frame.Size, view.Viewport.Size);
|
||||
|
||||
Assert.Equal (view.X, frame.X);
|
||||
Assert.Equal (view.Y, frame.Y);
|
||||
Assert.Equal (view.Width, frame.Width);
|
||||
Assert.Equal (view.Height, frame.Height);
|
||||
|
||||
view.Frame = Rectangle.Empty;
|
||||
Assert.Equal (Rectangle.Empty, view.Frame);
|
||||
Assert.False (view.NeedsLayout);
|
||||
Assert.Equal (Rectangle.Empty.Size, view.Viewport.Size);
|
||||
|
||||
Assert.Equal (view.X, Rectangle.Empty.X);
|
||||
Assert.Equal (view.Y, Rectangle.Empty.Y);
|
||||
Assert.Equal (view.Width, Rectangle.Empty.Width);
|
||||
Assert.Equal (view.Height, Rectangle.Empty.Height);
|
||||
|
||||
view.Width = Dim.Fill ();
|
||||
view.Height = Dim.Fill ();
|
||||
Assert.True (view.NeedsLayout);
|
||||
view.Layout ();
|
||||
Assert.False (view.NeedsLayout);
|
||||
Assert.Equal (Application.Screen, view.Frame);
|
||||
|
||||
view.Frame = Rectangle.Empty;
|
||||
Assert.Equal (Rectangle.Empty, view.Frame);
|
||||
Assert.False (view.NeedsLayout);
|
||||
Assert.Equal (Rectangle.Empty.Size, view.Viewport.Size);
|
||||
|
||||
Assert.Equal (view.X, Rectangle.Empty.X);
|
||||
Assert.Equal (view.Y, Rectangle.Empty.Y);
|
||||
Assert.Equal (view.Width, Rectangle.Empty.Width);
|
||||
Assert.Equal (view.Height, Rectangle.Empty.Height);
|
||||
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public void Frame_Empty_Initializer_Overrides_Base ()
|
||||
{
|
||||
// Prove TestView is correct
|
||||
FrameTestView view = new ();
|
||||
Assert.True (view.NeedsLayout);
|
||||
|
||||
view.Layout ();
|
||||
Assert.Equal (new Rectangle(10, 20, 30, 40), view.Frame);
|
||||
Assert.Equal (10, view.X.GetAnchor(0));
|
||||
Assert.Equal (20, view.Y.GetAnchor(0));
|
||||
Assert.Equal (30, view.Width!.GetAnchor(0));
|
||||
Assert.Equal (40, view.Height!.GetAnchor(0));
|
||||
Assert.Equal (new Rectangle (0, 0, 30, 40), view.Viewport);
|
||||
|
||||
// Set Frame via init
|
||||
Rectangle frame = new (1, 2, 3, 4);
|
||||
view = new ()
|
||||
{
|
||||
Frame = frame,
|
||||
};
|
||||
Assert.Equal (frame, view.Frame);
|
||||
Assert.False (view.NeedsLayout);
|
||||
Assert.Equal (frame.Size, view.Viewport.Size);
|
||||
|
||||
Assert.Equal (view.X, frame.X);
|
||||
Assert.Equal (view.Y, frame.Y);
|
||||
Assert.Equal (view.Width, frame.Width);
|
||||
Assert.Equal (view.Height, frame.Height);
|
||||
|
||||
// Set Frame via init to empty
|
||||
frame = Rectangle.Empty;
|
||||
view = new ()
|
||||
{
|
||||
Frame = frame,
|
||||
};
|
||||
Assert.Equal (frame, view.Frame);
|
||||
Assert.False (view.NeedsLayout);
|
||||
Assert.Equal (frame.Size, view.Viewport.Size);
|
||||
|
||||
Assert.Equal (view.X, frame.X);
|
||||
Assert.Equal (view.Y, frame.Y);
|
||||
Assert.Equal (view.Width, frame.Width);
|
||||
Assert.Equal (view.Height, frame.Height);
|
||||
|
||||
// Set back to original state
|
||||
view.X = Pos.Func (() => 10);
|
||||
view.Y = Pos.Func (() => 20);
|
||||
view.Width = Dim.Func (() => 30);
|
||||
view.Height = Dim.Func (() => 40);
|
||||
Assert.True (view.NeedsLayout);
|
||||
|
||||
view.Layout ();
|
||||
Assert.Equal (new Rectangle (10, 20, 30, 40), view.Frame);
|
||||
Assert.Equal (10, view.X.GetAnchor (0));
|
||||
Assert.Equal (20, view.Y.GetAnchor (0));
|
||||
Assert.Equal (30, view.Width!.GetAnchor (0));
|
||||
Assert.Equal (40, view.Height!.GetAnchor (0));
|
||||
Assert.Equal (new Rectangle (0, 0, 30, 40), view.Viewport);
|
||||
|
||||
view.Frame = frame;
|
||||
Assert.Equal (frame, view.Frame);
|
||||
Assert.False (view.NeedsLayout);
|
||||
Assert.Equal (frame.Size, view.Viewport.Size);
|
||||
|
||||
Assert.Equal (view.X, frame.X);
|
||||
Assert.Equal (view.Y, frame.Y);
|
||||
Assert.Equal (view.Width, frame.Width);
|
||||
Assert.Equal (view.Height, frame.Height);
|
||||
}
|
||||
|
||||
private class FrameTestView : View
|
||||
{
|
||||
public FrameTestView ()
|
||||
{
|
||||
X = Pos.Func (() => 10);
|
||||
Y = Pos.Func (() => 20);
|
||||
Width = Dim.Func (() => 30);
|
||||
Height = Dim.Func (() => 40);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Moved this test from AbsoluteLayoutTests
|
||||
// TODO: Refactor as Theory
|
||||
[Fact]
|
||||
|
||||
@@ -154,8 +154,6 @@ public class WindowTests
|
||||
Assert.Equal ("title", windowWithFrameRectEmpty.Title);
|
||||
Assert.True (windowWithFrameRectEmpty.CanFocus);
|
||||
Assert.False (windowWithFrameRectEmpty.HasFocus);
|
||||
Assert.Equal (Rectangle.Empty, windowWithFrameRectEmpty.Viewport);
|
||||
Assert.Equal (Rectangle.Empty, windowWithFrameRectEmpty.Frame);
|
||||
Assert.Null (windowWithFrameRectEmpty.Focused);
|
||||
Assert.NotNull (windowWithFrameRectEmpty.ColorScheme);
|
||||
Assert.Equal (0, windowWithFrameRectEmpty.X);
|
||||
|
||||
Reference in New Issue
Block a user