Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 31 additions & 9 deletions Terminal.Gui/App/ApplicationImpl.Screen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,11 @@ private void RaiseScreenChangedEvent (Rectangle screen)
runnableView.SetNeedsLayout ();
}
}

if (Popovers?.GetActivePopover () is View { Visible: true } visiblePopover)
{
visiblePopover.SetNeedsLayout ();
}
}

private void Driver_SizeChanged (object? sender, SizeChangedEventArgs e)
Expand Down Expand Up @@ -117,16 +122,9 @@ public void LayoutAndDraw (bool forceRedraw = false)

List<View?> views = [.. SessionStack.Select (r => r.Runnable! as View)!];

if (Popovers?.GetActivePopover () is { Visible: true } visiblePopover)
if (Popovers?.GetActivePopover () is View { Visible: true, NeedsLayout: true } visiblePopoverNeedingLayout)
{
visiblePopover.SetNeedsDraw ();
visiblePopover.SetNeedsLayout ();

// Need View for views.Insert
if (visiblePopover is View popoverView)
{
views.Insert (0, popoverView);
}
views.Insert (0, visiblePopoverNeedingLayout);
}

// Layout
Expand Down Expand Up @@ -240,6 +238,30 @@ public void LayoutAndDraw (bool forceRedraw = false)
// Draw
bool needsDraw = forceRedraw || views.Any (v => v is { NeedsDraw: true } or { SubViewNeedsDraw: true });

if (Popovers?.GetActivePopover () is View { Visible: true } visiblePopover)
{
if (needsDraw)
{
visiblePopover.SetNeedsDraw ();

if (!views.Contains (visiblePopover))
{
views.Insert (0, visiblePopover);
}
}
else if (visiblePopover.NeedsDraw || visiblePopover.SubViewNeedsDraw)
{
visiblePopover.SetNeedsDraw ();

if (!views.Contains (visiblePopover))
{
views.Insert (0, visiblePopover);
}

needsDraw = true;
}
}

if (Driver is { } && (neededLayout || needsDraw))
{
Logging.Redraws.Add (1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -286,12 +286,184 @@ public void LayoutAndDraw_ScreenResize_LayoutsVisiblePopover ()
top.Dispose ();
}

// CoPilot - ChatGPT v4
[Fact]
public void LayoutAndDraw_VisibleIdlePopover_DoesNotRaiseLayoutAndDrawComplete ()
{
// Arrange
using IApplication app = Application.Create ();
app.Init (DriverRegistry.Names.ANSI);
app.Driver!.SetScreenSize (80, 25);

Runnable top = new () { App = app };
SessionToken? token = app.Begin (top);

PopoverTestClass popover = new ()
{
App = app,
Width = 10,
Height = 5
};
app.Popovers!.Register (popover);
app.Popovers.Show (popover);

// Clear the initial invalidation caused by showing the popover.
app.LayoutAndDraw ();

int layoutAndDrawCompleteCount = 0;
app.LayoutAndDrawComplete += CountLayoutAndDrawComplete;

// Act
app.LayoutAndDraw ();

// Assert
Assert.Equal (0, layoutAndDrawCompleteCount);

app.LayoutAndDrawComplete -= CountLayoutAndDrawComplete;
app.End (token!);
top.Dispose ();

return;

void CountLayoutAndDrawComplete (object? _, EventArgs __) => layoutAndDrawCompleteCount++;
}

// CoPilot - ChatGPT v4
[Fact]
public void LayoutAndDraw_VisiblePopoverNeedingDraw_RaisesLayoutAndDrawComplete ()
{
// Arrange
using IApplication app = Application.Create ();
app.Init (DriverRegistry.Names.ANSI);
app.Driver!.SetScreenSize (80, 25);

Runnable top = new () { App = app };
SessionToken? token = app.Begin (top);

PopoverTestClass popover = new ()
{
App = app,
Width = 10,
Height = 5
};
app.Popovers!.Register (popover);
app.Popovers.Show (popover);
app.LayoutAndDraw ();

int layoutAndDrawCompleteCount = 0;
app.LayoutAndDrawComplete += CountLayoutAndDrawComplete;
popover.SetNeedsDraw ();

// Act
app.LayoutAndDraw ();

// Assert
Assert.Equal (1, layoutAndDrawCompleteCount);

app.LayoutAndDrawComplete -= CountLayoutAndDrawComplete;
app.End (token!);
top.Dispose ();

return;

void CountLayoutAndDrawComplete (object? _, EventArgs __) => layoutAndDrawCompleteCount++;
}

// CoPilot - ChatGPT v4
[Fact]
public void LayoutAndDraw_VisiblePopoverNeedingLayout_RaisesLayoutAndDrawComplete ()
{
// Arrange
using IApplication app = Application.Create ();
app.Init (DriverRegistry.Names.ANSI);
app.Driver!.SetScreenSize (80, 25);

Runnable top = new () { App = app };
SessionToken? token = app.Begin (top);

PopoverTestClass popover = new ()
{
App = app,
Width = 10,
Height = 5
};
app.Popovers!.Register (popover);
app.Popovers.Show (popover);
app.LayoutAndDraw ();

int layoutAndDrawCompleteCount = 0;
app.LayoutAndDrawComplete += CountLayoutAndDrawComplete;
popover.SetNeedsLayout ();

// Act
app.LayoutAndDraw ();

// Assert
Assert.Equal (1, layoutAndDrawCompleteCount);

app.LayoutAndDrawComplete -= CountLayoutAndDrawComplete;
app.End (token!);
top.Dispose ();

return;

void CountLayoutAndDrawComplete (object? _, EventArgs __) => layoutAndDrawCompleteCount++;
}

// CoPilot - ChatGPT v4
[Fact]
public void LayoutAndDraw_UnderlyingViewNeedsDraw_RedrawsPopoverWithoutLayout ()
{
// Arrange
using IApplication app = Application.Create ();
app.Init (DriverRegistry.Names.ANSI);
app.Driver!.SetScreenSize (80, 25);

Runnable top = new () { App = app };

View content = new ()
{
Width = 10,
Height = 5
};
top.Add (content);

SessionToken? token = app.Begin (top);

PopoverTestClass popover = new ()
{
App = app,
Width = 10,
Height = 5
};
app.Popovers!.Register (popover);
app.Popovers.Show (popover);

app.LayoutAndDraw ();
popover.DrawCompleteCount = 0;
popover.LayoutPassCount = 0;

content.SetNeedsDraw ();

// Act
app.LayoutAndDraw ();

// Assert
Assert.Equal (1, popover.DrawCompleteCount);
Assert.Equal (0, popover.LayoutPassCount);

app.End (token!);
top.Dispose ();
}

public class PopoverTestClass : View, IPopoverView
{
public List<Key> HandledKeys { get; } = [];

public int NewCommandInvokeCount { get; private set; }

public int DrawCompleteCount { get; set; }

public int LayoutPassCount { get; set; }

public bool HandleNewCommand { get; set; }
Expand Down Expand Up @@ -380,6 +552,12 @@ protected override bool OnKeyDown (Key key)
return false;
}

protected override void OnDrawComplete (DrawContext? context)
{
DrawCompleteCount++;
base.OnDrawComplete (context);
}

protected override void OnSubViewLayout (LayoutEventArgs args)
{
LayoutPassCount++;
Expand Down
Loading