RenderEmpty fixes

This commit is contained in:
2023-08-17 16:41:44 +02:00
parent df4fe93c81
commit 9d36336808
6 changed files with 70 additions and 27 deletions

View File

@@ -7,6 +7,24 @@ namespace TerminalUI.Controls;
public sealed partial class Border<T> : ContentView<Border<T>, T>, IDisplayView
{
private record struct RenderState(
Position Position,
Size Size,
Thickness BorderThickness,
Thickness Padding,
char TopChar,
char LeftChar,
char RightChar,
char BottomChar,
char TopLeftChar,
char TopRightChar,
char BottomLeftChar,
char BottomRightChar,
IColor? Fill
);
private RenderState _lastRenderState;
[Notify] private Thickness _borderThickness = 1;
[Notify] private Thickness _padding = 0;
[Notify] private char _topChar = '─';
@@ -60,6 +78,27 @@ public sealed partial class Border<T> : ContentView<Border<T>, T>, IDisplayView
var foregroundColor = Foreground ?? renderContext.Foreground;
var fillColor = Fill ?? Background ?? renderContext.Background;
var renderState = new RenderState(
position,
size,
_borderThickness,
_padding,
_topChar,
_leftChar,
_rightChar,
_bottomChar,
_topLeftChar,
_topRightChar,
_bottomLeftChar,
_bottomRightChar,
fillColor
);
var skipBorderRender = !renderContext.ForceRerender && !NeedsRerender(renderState);
if (!skipBorderRender)
{
_lastRenderState = renderState;
}
var childPosition = new Position(X: position.X + _borderThickness.Left, Y: position.Y + _borderThickness.Top);
var childSize = new Size(
Width: size.Width - _borderThickness.Left - _borderThickness.Right,
@@ -96,7 +135,7 @@ public sealed partial class Border<T> : ContentView<Border<T>, T>, IDisplayView
SetStyleColor(renderContext, foregroundColor, backgroundColor);
}
var updateCellsOnly = !contentRendered;
var updateCellsOnly = !contentRendered || skipBorderRender;
RenderTopBorder(renderContext, position, size, updateCellsOnly);
RenderBottomBorder(renderContext, position, size, updateCellsOnly);
RenderLeftBorder(renderContext, position, size, updateCellsOnly);
@@ -120,6 +159,7 @@ public sealed partial class Border<T> : ContentView<Border<T>, T>, IDisplayView
childPositionWithoutPadding,
childSizeWithoutPadding
);
}
//Write back the changes to the original array
Array2DHelper.CombineArray2Ds(
@@ -129,11 +169,12 @@ public sealed partial class Border<T> : ContentView<Border<T>, T>, IDisplayView
renderContext.UpdatedCells,
(a, b) => (a ?? false) || (b ?? false)
);
}
return contentRendered;
}
private bool NeedsRerender(RenderState renderState) => renderState != _lastRenderState;
private void RenderTopBorder(in RenderContext renderContext, Position position, Size size, bool updateCellsOnly)
{
position = position with {X = position.X + _borderThickness.Left};

View File

@@ -44,11 +44,10 @@ public abstract partial class ContentView<TConcrete, T>
private bool DefaultContentRender(in RenderContext renderContext, Position position, Size size)
{
if (Content is null || !Content.IsVisible)
if (Content is null)
{
if (_placeholderRenderDone) return false;
_placeholderRenderDone = true;
RenderEmpty(renderContext, position, size, false);
return true;
}

View File

@@ -239,8 +239,7 @@ public sealed class Grid<T> : ChildCollectionView<Grid<T>, T>, IVisibilityChange
if (!viewsByPosition.TryGetValue((column, row), out var children))
{
RenderEmpty(context, renderPosition, renderSize, false);
return true;
return false;
}
var needsRerender = children.Any(forceRerenderChildren.Contains);
@@ -248,7 +247,6 @@ public sealed class Grid<T> : ChildCollectionView<Grid<T>, T>, IVisibilityChange
if (needsRerender)
{
updatedContext = context with {ForceRerender = true};
RenderEmpty(updatedContext, renderPosition, renderSize, false);
}
//This implies that children further back in the list will be rendered on top of children placed before in the list.

View File

@@ -218,6 +218,7 @@ public sealed partial class ListView<TDataContext, TItem> : View<ListView<TDataC
}
var deltaX = 0;
var anyRendered = false;
for (var i = renderStartIndex; i < _listViewItemLength; i++)
{
var item = listViewItems[i];
@@ -229,13 +230,13 @@ public sealed partial class ListView<TDataContext, TItem> : View<ListView<TDataC
width = size.Width - deltaX;
}
item.Render(renderContext, position with {X = position.X + deltaX}, size with {Width = width});
anyRendered =
item.Render(renderContext, position with {X = position.X + deltaX}, size with {Width = width})
|| anyRendered;
deltaX = nextDeltaX;
}
//TODO: render empty to remaining space
return true;
return anyRendered;
}
private bool RenderVertical(in RenderContext renderContext, Position position, Size size)
@@ -289,9 +290,6 @@ public sealed partial class ListView<TDataContext, TItem> : View<ListView<TDataC
deltaY += requestedItemSize.Height;
}
// TODO: this should only render if deltaY is changed compared to last render or if last render was a horizontal
RenderEmpty(renderContext, position with {Y = position.Y + deltaY}, size with {Height = size.Height - deltaY}, false);
return anyRendered;
}

View File

@@ -64,10 +64,11 @@ public sealed partial class TextBlock<T> : View<TextBlock<T>, T>, IDisplayView
if (_textLines is null)
{
if (_placeholderRenderDone)
if (!_placeholderRenderDone)
{
_placeholderRenderDone = true;
RenderEmpty(renderContext, position, size, skipRender);
return true;
}
return false;

View File

@@ -146,7 +146,13 @@ public class RenderEngine : IRenderEngine
}
driver.ResetStyle();
Array2DHelper.RenderEmpty(driver, _updatedCells, _filledCells, _applicationContext.EmptyCharacter, initialPosition, size);
Array2DHelper.RenderEmpty(
driver,
_updatedCells,
_filledCells,
_applicationContext.EmptyCharacter,
initialPosition,
size);
(_lastFilledCells, _filledCells) = (_filledCells, _lastFilledCells);