mirror of
https://github.com/gui-cs/Terminal.Gui.git
synced 2025-12-30 17:57:57 +01:00
Fixes bugs where unnecessary Draw operations were happening in LayoutAndDraw. In some cases causing everything to always be drawn.
Refactored `NeedsDraw` logic into a modular implementation in `View.NeedsDraw.cs`, introducing methods to manage drawing states more effectively. Updated `Menus.cs` event handlers to include null checks for robustness. Improved margin drawing logic in `Margin.cs` with better performance and debugging assertions. Added comprehensive unit tests in `NeedsDrawTests.cs` and `StaticDrawTests.cs` to validate the new drawing logic, including edge cases and static `View.Draw` behavior. Removed redundant tests from `ViewDrawingFlowTests.cs`. Refactored diagnostic flags handling in `UICatalogRunnable.cs` for clarity. Performed general code cleanup, leveraging modern C# features and improving maintainability.
This commit is contained in:
@@ -6,222 +6,7 @@ namespace ViewBaseTests.Drawing;
|
||||
|
||||
public class ViewDrawingFlowTests () : FakeDriverBase
|
||||
{
|
||||
#region NeedsDraw Tests
|
||||
|
||||
[Fact]
|
||||
public void NeedsDraw_InitiallyFalse_WhenNotVisible ()
|
||||
{
|
||||
var view = new View { Visible = false };
|
||||
view.BeginInit ();
|
||||
view.EndInit ();
|
||||
|
||||
Assert.False (view.NeedsDraw);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NeedsDraw_TrueAfterSetNeedsDraw ()
|
||||
{
|
||||
var view = new View { X = 0, Y = 0, Width = 10, Height = 10 };
|
||||
view.BeginInit ();
|
||||
view.EndInit ();
|
||||
view.LayoutSubViews ();
|
||||
|
||||
view.SetNeedsDraw ();
|
||||
|
||||
Assert.True (view.NeedsDraw);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NeedsDraw_ClearedAfterDraw ()
|
||||
{
|
||||
IDriver driver = CreateFakeDriver (80, 25);
|
||||
driver.Clip = new Region (driver.Screen);
|
||||
|
||||
var view = new View
|
||||
{
|
||||
X = 0,
|
||||
Y = 0,
|
||||
Width = 10,
|
||||
Height = 10,
|
||||
Driver = driver
|
||||
};
|
||||
view.BeginInit ();
|
||||
view.EndInit ();
|
||||
view.LayoutSubViews ();
|
||||
|
||||
view.SetNeedsDraw ();
|
||||
Assert.True (view.NeedsDraw);
|
||||
|
||||
view.Draw ();
|
||||
|
||||
Assert.False (view.NeedsDraw);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SetNeedsDraw_WithRectangle_UpdatesNeedsDrawRect ()
|
||||
{
|
||||
var view = new View { Driver = CreateFakeDriver (), X = 0, Y = 0, Width = 20, Height = 20 };
|
||||
view.BeginInit ();
|
||||
view.EndInit ();
|
||||
view.LayoutSubViews ();
|
||||
|
||||
// After layout, view will have NeedsDrawRect set to the viewport
|
||||
// We need to clear it first
|
||||
view.Draw ();
|
||||
Assert.False (view.NeedsDraw);
|
||||
Assert.Equal (Rectangle.Empty, view.NeedsDrawRect);
|
||||
|
||||
var rect = new Rectangle (5, 5, 10, 10);
|
||||
view.SetNeedsDraw (rect);
|
||||
|
||||
Assert.True (view.NeedsDraw);
|
||||
Assert.Equal (rect, view.NeedsDrawRect);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SetNeedsDraw_MultipleRectangles_Expands ()
|
||||
{
|
||||
IDriver driver = CreateFakeDriver (80, 25);
|
||||
driver.Clip = new Region (driver.Screen);
|
||||
|
||||
var view = new View { X = 0, Y = 0, Width = 30, Height = 30, Driver = driver };
|
||||
view.BeginInit ();
|
||||
view.EndInit ();
|
||||
view.LayoutSubViews ();
|
||||
|
||||
// After layout, clear NeedsDraw
|
||||
view.Draw ();
|
||||
Assert.False (view.NeedsDraw);
|
||||
|
||||
view.SetNeedsDraw (new Rectangle (5, 5, 10, 10));
|
||||
view.SetNeedsDraw (new Rectangle (15, 15, 10, 10));
|
||||
|
||||
// Should expand to cover the entire viewport when we have overlapping regions
|
||||
// The current implementation expands to viewport size
|
||||
Rectangle expected = new Rectangle (0, 0, 30, 30);
|
||||
Assert.Equal (expected, view.NeedsDrawRect);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SetNeedsDraw_NotVisible_DoesNotSet ()
|
||||
{
|
||||
var view = new View
|
||||
{
|
||||
X = 0,
|
||||
Y = 0,
|
||||
Width = 10,
|
||||
Height = 10,
|
||||
Visible = false
|
||||
};
|
||||
view.BeginInit ();
|
||||
view.EndInit ();
|
||||
|
||||
view.SetNeedsDraw ();
|
||||
|
||||
Assert.False (view.NeedsDraw);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SetNeedsDraw_PropagatesToSuperView ()
|
||||
{
|
||||
var parent = new View { X = 0, Y = 0, Width = 50, Height = 50 };
|
||||
var child = new View { X = 10, Y = 10, Width = 20, Height = 20 };
|
||||
parent.Add (child);
|
||||
parent.BeginInit ();
|
||||
parent.EndInit ();
|
||||
parent.LayoutSubViews ();
|
||||
|
||||
child.SetNeedsDraw ();
|
||||
|
||||
Assert.True (child.NeedsDraw);
|
||||
Assert.True (parent.SubViewNeedsDraw);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SetNeedsDraw_SetsAdornmentsNeedsDraw ()
|
||||
{
|
||||
var view = new View { X = 0, Y = 0, Width = 20, Height = 20 };
|
||||
view.Border!.Thickness = new Thickness (1);
|
||||
view.Padding!.Thickness = new Thickness (1);
|
||||
view.BeginInit ();
|
||||
view.EndInit ();
|
||||
view.LayoutSubViews ();
|
||||
|
||||
view.SetNeedsDraw ();
|
||||
|
||||
Assert.True (view.Border!.NeedsDraw);
|
||||
Assert.True (view.Padding!.NeedsDraw);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region SubViewNeedsDraw Tests
|
||||
|
||||
[Fact]
|
||||
public void SubViewNeedsDraw_InitiallyFalse ()
|
||||
{
|
||||
IDriver driver = CreateFakeDriver (80, 25);
|
||||
driver.Clip = new Region (driver.Screen);
|
||||
|
||||
var view = new View { Width = 10, Height = 10, Driver = driver };
|
||||
view.BeginInit ();
|
||||
view.EndInit ();
|
||||
view.Draw (); // Draw once to clear initial NeedsDraw
|
||||
|
||||
Assert.False (view.SubViewNeedsDraw);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SetSubViewNeedsDraw_PropagatesUp ()
|
||||
{
|
||||
var grandparent = new View { X = 0, Y = 0, Width = 100, Height = 100 };
|
||||
var parent = new View { X = 10, Y = 10, Width = 50, Height = 50 };
|
||||
var child = new View { X = 5, Y = 5, Width = 20, Height = 20 };
|
||||
|
||||
grandparent.Add (parent);
|
||||
parent.Add (child);
|
||||
grandparent.BeginInit ();
|
||||
grandparent.EndInit ();
|
||||
grandparent.LayoutSubViews ();
|
||||
|
||||
child.SetSubViewNeedsDraw ();
|
||||
|
||||
Assert.True (child.SubViewNeedsDraw);
|
||||
Assert.True (parent.SubViewNeedsDraw);
|
||||
Assert.True (grandparent.SubViewNeedsDraw);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SubViewNeedsDraw_ClearedAfterDraw ()
|
||||
{
|
||||
IDriver driver = CreateFakeDriver (80, 25);
|
||||
driver.Clip = new Region (driver.Screen);
|
||||
|
||||
var parent = new View
|
||||
{
|
||||
X = 0,
|
||||
Y = 0,
|
||||
Width = 50,
|
||||
Height = 50,
|
||||
Driver = driver
|
||||
};
|
||||
var child = new View { X = 10, Y = 10, Width = 20, Height = 20 };
|
||||
parent.Add (child);
|
||||
parent.BeginInit ();
|
||||
parent.EndInit ();
|
||||
parent.LayoutSubViews ();
|
||||
|
||||
child.SetNeedsDraw ();
|
||||
Assert.True (parent.SubViewNeedsDraw);
|
||||
|
||||
parent.Draw ();
|
||||
|
||||
Assert.False (parent.SubViewNeedsDraw);
|
||||
Assert.False (child.SubViewNeedsDraw);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region Draw Visibility Tests
|
||||
|
||||
[Fact]
|
||||
|
||||
Reference in New Issue
Block a user