RenderEmpty fixes
This commit is contained in:
@@ -7,6 +7,24 @@ namespace TerminalUI.Controls;
|
|||||||
|
|
||||||
public sealed partial class Border<T> : ContentView<Border<T>, T>, IDisplayView
|
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 _borderThickness = 1;
|
||||||
[Notify] private Thickness _padding = 0;
|
[Notify] private Thickness _padding = 0;
|
||||||
[Notify] private char _topChar = '─';
|
[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 foregroundColor = Foreground ?? renderContext.Foreground;
|
||||||
var fillColor = Fill ?? Background ?? renderContext.Background;
|
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 childPosition = new Position(X: position.X + _borderThickness.Left, Y: position.Y + _borderThickness.Top);
|
||||||
var childSize = new Size(
|
var childSize = new Size(
|
||||||
Width: size.Width - _borderThickness.Left - _borderThickness.Right,
|
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);
|
SetStyleColor(renderContext, foregroundColor, backgroundColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
var updateCellsOnly = !contentRendered;
|
var updateCellsOnly = !contentRendered || skipBorderRender;
|
||||||
RenderTopBorder(renderContext, position, size, updateCellsOnly);
|
RenderTopBorder(renderContext, position, size, updateCellsOnly);
|
||||||
RenderBottomBorder(renderContext, position, size, updateCellsOnly);
|
RenderBottomBorder(renderContext, position, size, updateCellsOnly);
|
||||||
RenderLeftBorder(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,
|
childPositionWithoutPadding,
|
||||||
childSizeWithoutPadding
|
childSizeWithoutPadding
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
//Write back the changes to the original array
|
//Write back the changes to the original array
|
||||||
Array2DHelper.CombineArray2Ds(
|
Array2DHelper.CombineArray2Ds(
|
||||||
@@ -129,11 +169,12 @@ public sealed partial class Border<T> : ContentView<Border<T>, T>, IDisplayView
|
|||||||
renderContext.UpdatedCells,
|
renderContext.UpdatedCells,
|
||||||
(a, b) => (a ?? false) || (b ?? false)
|
(a, b) => (a ?? false) || (b ?? false)
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
return contentRendered;
|
return contentRendered;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool NeedsRerender(RenderState renderState) => renderState != _lastRenderState;
|
||||||
|
|
||||||
private void RenderTopBorder(in RenderContext renderContext, Position position, Size size, bool updateCellsOnly)
|
private void RenderTopBorder(in RenderContext renderContext, Position position, Size size, bool updateCellsOnly)
|
||||||
{
|
{
|
||||||
position = position with {X = position.X + _borderThickness.Left};
|
position = position with {X = position.X + _borderThickness.Left};
|
||||||
|
|||||||
@@ -44,11 +44,10 @@ public abstract partial class ContentView<TConcrete, T>
|
|||||||
|
|
||||||
private bool DefaultContentRender(in RenderContext renderContext, Position position, Size size)
|
private bool DefaultContentRender(in RenderContext renderContext, Position position, Size size)
|
||||||
{
|
{
|
||||||
if (Content is null || !Content.IsVisible)
|
if (Content is null)
|
||||||
{
|
{
|
||||||
if (_placeholderRenderDone) return false;
|
if (_placeholderRenderDone) return false;
|
||||||
_placeholderRenderDone = true;
|
_placeholderRenderDone = true;
|
||||||
RenderEmpty(renderContext, position, size, false);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -239,8 +239,7 @@ public sealed class Grid<T> : ChildCollectionView<Grid<T>, T>, IVisibilityChange
|
|||||||
|
|
||||||
if (!viewsByPosition.TryGetValue((column, row), out var children))
|
if (!viewsByPosition.TryGetValue((column, row), out var children))
|
||||||
{
|
{
|
||||||
RenderEmpty(context, renderPosition, renderSize, false);
|
return false;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var needsRerender = children.Any(forceRerenderChildren.Contains);
|
var needsRerender = children.Any(forceRerenderChildren.Contains);
|
||||||
@@ -248,7 +247,6 @@ public sealed class Grid<T> : ChildCollectionView<Grid<T>, T>, IVisibilityChange
|
|||||||
if (needsRerender)
|
if (needsRerender)
|
||||||
{
|
{
|
||||||
updatedContext = context with {ForceRerender = true};
|
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.
|
//This implies that children further back in the list will be rendered on top of children placed before in the list.
|
||||||
|
|||||||
@@ -218,6 +218,7 @@ public sealed partial class ListView<TDataContext, TItem> : View<ListView<TDataC
|
|||||||
}
|
}
|
||||||
|
|
||||||
var deltaX = 0;
|
var deltaX = 0;
|
||||||
|
var anyRendered = false;
|
||||||
for (var i = renderStartIndex; i < _listViewItemLength; i++)
|
for (var i = renderStartIndex; i < _listViewItemLength; i++)
|
||||||
{
|
{
|
||||||
var item = listViewItems[i];
|
var item = listViewItems[i];
|
||||||
@@ -229,13 +230,13 @@ public sealed partial class ListView<TDataContext, TItem> : View<ListView<TDataC
|
|||||||
width = size.Width - deltaX;
|
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;
|
deltaX = nextDeltaX;
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: render empty to remaining space
|
return anyRendered;
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool RenderVertical(in RenderContext renderContext, Position position, Size size)
|
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;
|
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;
|
return anyRendered;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -64,10 +64,11 @@ public sealed partial class TextBlock<T> : View<TextBlock<T>, T>, IDisplayView
|
|||||||
|
|
||||||
if (_textLines is null)
|
if (_textLines is null)
|
||||||
{
|
{
|
||||||
if (_placeholderRenderDone)
|
if (!_placeholderRenderDone)
|
||||||
{
|
{
|
||||||
_placeholderRenderDone = true;
|
_placeholderRenderDone = true;
|
||||||
RenderEmpty(renderContext, position, size, skipRender);
|
RenderEmpty(renderContext, position, size, skipRender);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -146,7 +146,13 @@ public class RenderEngine : IRenderEngine
|
|||||||
}
|
}
|
||||||
|
|
||||||
driver.ResetStyle();
|
driver.ResetStyle();
|
||||||
Array2DHelper.RenderEmpty(driver, _updatedCells, _filledCells, _applicationContext.EmptyCharacter, initialPosition, size);
|
Array2DHelper.RenderEmpty(
|
||||||
|
driver,
|
||||||
|
_updatedCells,
|
||||||
|
_filledCells,
|
||||||
|
_applicationContext.EmptyCharacter,
|
||||||
|
initialPosition,
|
||||||
|
size);
|
||||||
|
|
||||||
(_lastFilledCells, _filledCells) = (_filledCells, _lastFilledCells);
|
(_lastFilledCells, _filledCells) = (_filledCells, _lastFilledCells);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user