StackPanel child visibility change handler

This commit is contained in:
2023-08-12 09:13:44 +02:00
parent 16bdc1ed40
commit b73846c6ff
2 changed files with 41 additions and 6 deletions

View File

@@ -9,10 +9,10 @@ namespace TerminalUI.Controls;
public class Grid<T> : ChildContainerView<T>, IVisibilityChangeHandler public class Grid<T> : ChildContainerView<T>, IVisibilityChangeHandler
{ {
private readonly List<IView> _forceRerenderChildren = new();
private readonly object _forceRerenderChildrenLock = new();
private List<RowDefinition> _rowDefinitions = new() {RowDefinition.Star(1)}; private List<RowDefinition> _rowDefinitions = new() {RowDefinition.Star(1)};
private List<ColumnDefinition> _columnDefinitions = new() {ColumnDefinition.Star(1)}; private List<ColumnDefinition> _columnDefinitions = new() {ColumnDefinition.Star(1)};
private List<IView> _forceRerenderChildren = new();
private readonly object _forceRerenderChildrenLock = new();
private ILogger<Grid<T>>? Logger => ApplicationContext?.LoggerFactory?.CreateLogger<Grid<T>>(); private ILogger<Grid<T>>? Logger => ApplicationContext?.LoggerFactory?.CreateLogger<Grid<T>>();
private delegate void WithSizes(RenderContext renderContext, ReadOnlySpan<int> widths, ReadOnlySpan<int> heights); private delegate void WithSizes(RenderContext renderContext, ReadOnlySpan<int> widths, ReadOnlySpan<int> heights);
@@ -156,7 +156,7 @@ public class Grid<T> : ChildContainerView<T>, IVisibilityChangeHandler
IReadOnlyList<IView> forceRerenderChildren; IReadOnlyList<IView> forceRerenderChildren;
lock (_forceRerenderChildrenLock) lock (_forceRerenderChildrenLock)
{ {
forceRerenderChildren = _forceRerenderChildren; forceRerenderChildren = _forceRerenderChildren.ToList();
_forceRerenderChildren.Clear(); _forceRerenderChildren.Clear();
} }

View File

@@ -1,11 +1,13 @@
using System.Collections.ObjectModel; using PropertyChanged.SourceGenerator;
using PropertyChanged.SourceGenerator;
using TerminalUI.Models; using TerminalUI.Models;
using TerminalUI.Traits;
namespace TerminalUI.Controls; namespace TerminalUI.Controls;
public partial class StackPanel<T> : ChildContainerView<T> public partial class StackPanel<T> : ChildContainerView<T>, IVisibilityChangeHandler
{ {
private readonly List<IView> _forceRerenderChildren = new();
private readonly object _forceRerenderChildrenLock = new();
private readonly Dictionary<IView, Size> _requestedSizes = new(); private readonly Dictionary<IView, Size> _requestedSizes = new();
[Notify] private Orientation _orientation = Orientation.Vertical; [Notify] private Orientation _orientation = Orientation.Vertical;
@@ -41,12 +43,29 @@ public partial class StackPanel<T> : ChildContainerView<T>
{ {
var delta = 0; var delta = 0;
var neededRerender = false; var neededRerender = false;
IReadOnlyList<IView> forceRerenderChildren;
lock (_forceRerenderChildrenLock)
{
forceRerenderChildren = _forceRerenderChildren.ToList();
_forceRerenderChildren.Clear();
}
foreach (var child in Children) foreach (var child in Children)
{ {
if (!child.IsVisible) continue; if (!child.IsVisible) continue;
if (!_requestedSizes.TryGetValue(child, out var childSize)) throw new Exception("Child size not found"); if (!_requestedSizes.TryGetValue(child, out var childSize)) throw new Exception("Child size not found");
if (forceRerenderChildren.Contains(child))
{
renderContext = new RenderContext(
renderContext.ConsoleDriver,
true,
renderContext.Foreground,
renderContext.Background
);
}
var childPosition = Orientation == Orientation.Vertical var childPosition = Orientation == Orientation.Vertical
? position with {Y = position.Y + delta} ? position with {Y = position.Y + delta}
: position with {X = position.X + delta}; : position with {X = position.X + delta};
@@ -74,4 +93,20 @@ public partial class StackPanel<T> : ChildContainerView<T>
return neededRerender; return neededRerender;
} }
public void ChildVisibilityChanged(IView child)
{
var viewToForceRerender = child;
while (viewToForceRerender.VisualParent != null && viewToForceRerender.VisualParent != this)
{
viewToForceRerender = viewToForceRerender.VisualParent;
}
if (viewToForceRerender.VisualParent != this) return;
lock (_forceRerenderChildrenLock)
{
_forceRerenderChildren.Add(viewToForceRerender);
}
}
} }