From b73846c6ff4e28d2a15bb536b7d6e56d88c0f305 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81d=C3=A1m=20Kov=C3=A1cs?= Date: Sat, 12 Aug 2023 09:13:44 +0200 Subject: [PATCH] StackPanel child visibility change handler --- src/Library/TerminalUI/Controls/Grid.cs | 6 +-- src/Library/TerminalUI/Controls/StackPanel.cs | 41 +++++++++++++++++-- 2 files changed, 41 insertions(+), 6 deletions(-) diff --git a/src/Library/TerminalUI/Controls/Grid.cs b/src/Library/TerminalUI/Controls/Grid.cs index e103766..6987cdd 100644 --- a/src/Library/TerminalUI/Controls/Grid.cs +++ b/src/Library/TerminalUI/Controls/Grid.cs @@ -9,10 +9,10 @@ namespace TerminalUI.Controls; public class Grid : ChildContainerView, IVisibilityChangeHandler { + private readonly List _forceRerenderChildren = new(); + private readonly object _forceRerenderChildrenLock = new(); private List _rowDefinitions = new() {RowDefinition.Star(1)}; private List _columnDefinitions = new() {ColumnDefinition.Star(1)}; - private List _forceRerenderChildren = new(); - private readonly object _forceRerenderChildrenLock = new(); private ILogger>? Logger => ApplicationContext?.LoggerFactory?.CreateLogger>(); private delegate void WithSizes(RenderContext renderContext, ReadOnlySpan widths, ReadOnlySpan heights); @@ -156,7 +156,7 @@ public class Grid : ChildContainerView, IVisibilityChangeHandler IReadOnlyList forceRerenderChildren; lock (_forceRerenderChildrenLock) { - forceRerenderChildren = _forceRerenderChildren; + forceRerenderChildren = _forceRerenderChildren.ToList(); _forceRerenderChildren.Clear(); } diff --git a/src/Library/TerminalUI/Controls/StackPanel.cs b/src/Library/TerminalUI/Controls/StackPanel.cs index a8307fe..cb8b9e1 100644 --- a/src/Library/TerminalUI/Controls/StackPanel.cs +++ b/src/Library/TerminalUI/Controls/StackPanel.cs @@ -1,11 +1,13 @@ -using System.Collections.ObjectModel; -using PropertyChanged.SourceGenerator; +using PropertyChanged.SourceGenerator; using TerminalUI.Models; +using TerminalUI.Traits; namespace TerminalUI.Controls; -public partial class StackPanel : ChildContainerView +public partial class StackPanel : ChildContainerView, IVisibilityChangeHandler { + private readonly List _forceRerenderChildren = new(); + private readonly object _forceRerenderChildrenLock = new(); private readonly Dictionary _requestedSizes = new(); [Notify] private Orientation _orientation = Orientation.Vertical; @@ -41,12 +43,29 @@ public partial class StackPanel : ChildContainerView { var delta = 0; var neededRerender = false; + IReadOnlyList forceRerenderChildren; + lock (_forceRerenderChildrenLock) + { + forceRerenderChildren = _forceRerenderChildren.ToList(); + _forceRerenderChildren.Clear(); + } + foreach (var child in Children) { if (!child.IsVisible) continue; 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 ? position with {Y = position.Y + delta} : position with {X = position.X + delta}; @@ -74,4 +93,20 @@ public partial class StackPanel : ChildContainerView 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); + } + } } \ No newline at end of file