From 45550c9cf01f096a6bd323741b4df6dfc0f83200 Mon Sep 17 00:00:00 2001 From: BDisp Date: Fri, 10 Jul 2020 15:15:28 +0100 Subject: [PATCH 1/4] Added support for ISupportInitializeNotification interface. --- Terminal.Gui/Core/View.cs | 52 ++++++++++- UnitTests/ViewTests.cs | 175 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 225 insertions(+), 2 deletions(-) diff --git a/Terminal.Gui/Core/View.cs b/Terminal.Gui/Core/View.cs index 4ad5e6081..c62225228 100644 --- a/Terminal.Gui/Core/View.cs +++ b/Terminal.Gui/Core/View.cs @@ -13,6 +13,7 @@ using System; using System.Collections; using System.Collections.Generic; +using System.ComponentModel; using System.Diagnostics; using System.Linq; using NStack; @@ -110,7 +111,7 @@ namespace Terminal.Gui { /// frames for the vies that use . /// /// - public partial class View : Responder, IEnumerable { + public partial class View : Responder, IEnumerable, ISupportInitializeNotification { internal enum Direction { Forward, @@ -665,7 +666,9 @@ namespace Terminal.Gui { CanFocus = true; view.tabIndex = tabIndexes.IndexOf (view); } - + if (IsInitialized) { + view.BeginInit (); + } SetNeedsLayout (); SetNeedsDisplay (); } @@ -1653,6 +1656,13 @@ namespace Terminal.Gui { /// public Action LayoutComplete; + /// + /// Event called only once when the is being initialized for the first time. + /// Allows configurations and assignments to be performed before the being shown. + /// This derived from to allow notify all the views that are being initialized. + /// + public event EventHandler Initialized; + /// /// Raises the event. Called from before all sub-views have been laid out. /// @@ -1757,6 +1767,12 @@ namespace Terminal.Gui { } } + /// + /// Get or sets if the was already initialized. + /// This derived from to allow notify all the views that are being initialized. + /// + public bool IsInitialized { get; set; } + /// /// Pretty prints the View /// @@ -1848,5 +1864,37 @@ namespace Terminal.Gui { } base.Dispose (disposing); } + + /// + /// This derived from to allow notify all the views that are beginning initialized. + /// + public void BeginInit () + { + if (!IsInitialized) { + Initialized?.Invoke (this, new EventArgs ()); + } + if (subviews?.Count > 0) { + foreach (var view in subviews) { + if (!view.IsInitialized) { + view.BeginInit (); + } + } + } + } + + /// + /// This derived from to allow notify all the views that are ending initialized. + /// + public void EndInit () + { + IsInitialized = true; + if (subviews?.Count > 0) { + foreach (var view in subviews) { + if (!view.IsInitialized) { + view.EndInit (); + } + } + } + } } } diff --git a/UnitTests/ViewTests.cs b/UnitTests/ViewTests.cs index 3bceac0fb..fec7fd00f 100644 --- a/UnitTests/ViewTests.cs +++ b/UnitTests/ViewTests.cs @@ -543,5 +543,180 @@ namespace Terminal.Gui { Assert.Equal (2, v3.TabIndex); Assert.True (v3.TabStop); } + + [Fact] + public void Initialized_Event_Comparing_With_Added_Event () + { + Application.Init (new FakeDriver (), new NetMainLoop (() => FakeConsole.ReadKey (true))); + + var t = new Toplevel () { Id = "0", }; + + var w = new Window () {Id = "t", Width = Dim.Fill (), Height = Dim.Fill () }; + var v1 = new View () { Id = "v1", Width = Dim.Fill (), Height = Dim.Fill () }; + var v2 = new View () { Id = "v2", Width = Dim.Fill (), Height = Dim.Fill () }; + var sv1 = new View () { Id = "sv1", Width = Dim.Fill (), Height = Dim.Fill () }; + + int tc = 0, wc = 0, v1c = 0, v2c = 0, sv1c = 0; + + w.Added += (e) => { + Assert.Equal (e.Frame.Width, w.Frame.Width); + Assert.Equal (e.Frame.Height, w.Frame.Height); + }; + v1.Added += (e) => { + Assert.Equal (e.Frame.Width, v1.Frame.Width); + Assert.Equal (e.Frame.Height, v1.Frame.Height); + }; + v2.Added += (e) => { + Assert.Equal (e.Frame.Width, v2.Frame.Width); + Assert.Equal (e.Frame.Height, v2.Frame.Height); + }; + sv1.Added += (e) => { + Assert.Equal (e.Frame.Width, sv1.Frame.Width); + Assert.Equal (e.Frame.Height, sv1.Frame.Height); + }; + + t.Initialized += (s, e) => { + tc++; + Assert.Equal (1, tc); + Assert.Equal (0, wc); + Assert.Equal (0, v1c); + Assert.Equal (0, v2c); + Assert.Equal (0, sv1c); + + Assert.True (t.CanFocus); + Assert.True (w.CanFocus); + Assert.False (v1.CanFocus); + Assert.False (v2.CanFocus); + Assert.False (sv1.CanFocus); + + Application.Refresh (); + }; + w.Initialized += (s, e) => { + wc++; + Assert.Equal (t.Frame.Width, w.Frame.Width); + Assert.Equal (t.Frame.Height, w.Frame.Height); + }; + v1.Initialized += (s, e) => { + v1c++; + Assert.Equal (t.Frame.Width, v1.Frame.Width); + Assert.Equal (t.Frame.Height, v1.Frame.Height); + }; + v2.Initialized += (s, e) => { + v2c++; + Assert.Equal (t.Frame.Width, v2.Frame.Width); + Assert.Equal (t.Frame.Height, v2.Frame.Height); + }; + sv1.Initialized += (s, e) => { + sv1c++; + Assert.Equal (t.Frame.Width, sv1.Frame.Width); + Assert.Equal (t.Frame.Height, sv1.Frame.Height); + Assert.False (sv1.CanFocus); + sv1.CanFocus = true; + Assert.True (sv1.CanFocus); + }; + + v1.Add (sv1); + w.Add (v1, v2); + t.Add (w); + + Application.Iteration = () => { + Application.Refresh (); + t.Running = false; + }; + + Application.Run (t, true); + Application.Shutdown (true); + + Assert.Equal (1, tc); + Assert.Equal (1, wc); + Assert.Equal (1, v1c); + Assert.Equal (1, v2c); + Assert.Equal (1, sv1c); + + Assert.True (t.CanFocus); + Assert.True (w.CanFocus); + Assert.False (v1.CanFocus); + Assert.False (v2.CanFocus); + Assert.True (sv1.CanFocus); + } + + [Fact] + public void Initialized_Event_Will_Be_Invoked_When_Added_Dynamically () + { + Application.Init (new FakeDriver (), new NetMainLoop (() => FakeConsole.ReadKey (true))); + + var t = new Toplevel () { Id = "0", }; + + var w = new Window () { Id = "t", Width = Dim.Fill (), Height = Dim.Fill () }; + var v1 = new View () { Id = "v1", Width = Dim.Fill (), Height = Dim.Fill () }; + var v2 = new View () { Id = "v2", Width = Dim.Fill (), Height = Dim.Fill () }; + + int tc = 0, wc = 0, v1c = 0, v2c = 0, sv1c = 0; + + t.Initialized += (s, e) => { + tc++; + Assert.Equal (1, tc); + Assert.Equal (0, wc); + Assert.Equal (0, v1c); + Assert.Equal (0, v2c); + Assert.Equal (0, sv1c); + + Assert.True (t.CanFocus); + Assert.True (w.CanFocus); + Assert.False (v1.CanFocus); + Assert.False (v2.CanFocus); + + Application.Refresh (); + }; + w.Initialized += (s, e) => { + wc++; + Assert.Equal (t.Frame.Width, w.Frame.Width); + Assert.Equal (t.Frame.Height, w.Frame.Height); + }; + v1.Initialized += (s, e) => { + v1c++; + Assert.Equal (t.Frame.Width, v1.Frame.Width); + Assert.Equal (t.Frame.Height, v1.Frame.Height); + }; + v2.Initialized += (s, e) => { + v2c++; + Assert.Equal (t.Frame.Width, v2.Frame.Width); + Assert.Equal (t.Frame.Height, v2.Frame.Height); + }; + w.Add (v1, v2); + t.Add (w); + + Application.Iteration = () => { + var sv1 = new View () { Id = "sv1", Width = Dim.Fill (), Height = Dim.Fill () }; + + sv1.Initialized += (s, e) => { + sv1c++; + Assert.NotEqual (t.Frame.Width, sv1.Frame.Width); + Assert.NotEqual (t.Frame.Height, sv1.Frame.Height); + Assert.False (sv1.CanFocus); + sv1.CanFocus = true; + Assert.True (sv1.CanFocus); + }; + + v1.Add (sv1); + + Application.Refresh (); + t.Running = false; + }; + + Application.Run (t, true); + Application.Shutdown (true); + + Assert.Equal (1, tc); + Assert.Equal (1, wc); + Assert.Equal (1, v1c); + Assert.Equal (1, v2c); + Assert.Equal (1, sv1c); + + Assert.True (t.CanFocus); + Assert.True (w.CanFocus); + Assert.False (v1.CanFocus); + Assert.False (v2.CanFocus); + } } } From adae58bbf7228ed1ebbf3df5a67486a6de466904 Mon Sep 17 00:00:00 2001 From: BDisp Date: Fri, 10 Jul 2020 19:05:58 +0100 Subject: [PATCH 2/4] Fixed for dynamically added view. --- Terminal.Gui/Core/View.cs | 10 ++++++---- UnitTests/ViewTests.cs | 3 +++ 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/Terminal.Gui/Core/View.cs b/Terminal.Gui/Core/View.cs index 24a2ca606..cba2baf75 100644 --- a/Terminal.Gui/Core/View.cs +++ b/Terminal.Gui/Core/View.cs @@ -621,13 +621,18 @@ namespace Terminal.Gui { container.ChildNeedsDisplay (); if (subviews == null) return; - foreach (var view in subviews) + foreach (var view in subviews) { + if (IsInitialized && !view.IsInitialized) { + view.BeginInit (); + view.EndInit (); + } if (view.Frame.IntersectsWith (region)) { var childRegion = Rect.Intersect (view.Frame, region); childRegion.X -= view.Frame.X; childRegion.Y -= view.Frame.Y; view.SetNeedsDisplay (childRegion); } + } } internal bool childNeedsDisplay; @@ -666,9 +671,6 @@ namespace Terminal.Gui { CanFocus = true; view.tabIndex = tabIndexes.IndexOf (view); } - if (IsInitialized) { - view.BeginInit (); - } SetNeedsLayout (); SetNeedsDisplay (); } diff --git a/UnitTests/ViewTests.cs b/UnitTests/ViewTests.cs index fec7fd00f..378d42e75 100644 --- a/UnitTests/ViewTests.cs +++ b/UnitTests/ViewTests.cs @@ -700,6 +700,9 @@ namespace Terminal.Gui { v1.Add (sv1); + while (!sv1.CanFocus) { + } + Application.Refresh (); t.Running = false; }; From 315b93726c42f878feb78fac63dca74c69d30a4a Mon Sep 17 00:00:00 2001 From: BDisp Date: Fri, 10 Jul 2020 19:20:05 +0100 Subject: [PATCH 3/4] Revert "Fixed for dynamically added view." This reverts commit adae58bbf7228ed1ebbf3df5a67486a6de466904. --- Terminal.Gui/Core/View.cs | 10 ++++------ UnitTests/ViewTests.cs | 3 --- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/Terminal.Gui/Core/View.cs b/Terminal.Gui/Core/View.cs index cba2baf75..24a2ca606 100644 --- a/Terminal.Gui/Core/View.cs +++ b/Terminal.Gui/Core/View.cs @@ -621,18 +621,13 @@ namespace Terminal.Gui { container.ChildNeedsDisplay (); if (subviews == null) return; - foreach (var view in subviews) { - if (IsInitialized && !view.IsInitialized) { - view.BeginInit (); - view.EndInit (); - } + foreach (var view in subviews) if (view.Frame.IntersectsWith (region)) { var childRegion = Rect.Intersect (view.Frame, region); childRegion.X -= view.Frame.X; childRegion.Y -= view.Frame.Y; view.SetNeedsDisplay (childRegion); } - } } internal bool childNeedsDisplay; @@ -671,6 +666,9 @@ namespace Terminal.Gui { CanFocus = true; view.tabIndex = tabIndexes.IndexOf (view); } + if (IsInitialized) { + view.BeginInit (); + } SetNeedsLayout (); SetNeedsDisplay (); } diff --git a/UnitTests/ViewTests.cs b/UnitTests/ViewTests.cs index 378d42e75..fec7fd00f 100644 --- a/UnitTests/ViewTests.cs +++ b/UnitTests/ViewTests.cs @@ -700,9 +700,6 @@ namespace Terminal.Gui { v1.Add (sv1); - while (!sv1.CanFocus) { - } - Application.Refresh (); t.Running = false; }; From a62ce82cc772b0ad4f7c898700ef3136fcb30eb9 Mon Sep 17 00:00:00 2001 From: BDisp Date: Fri, 10 Jul 2020 19:27:28 +0100 Subject: [PATCH 4/4] Moved to the end. --- Terminal.Gui/Core/View.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Terminal.Gui/Core/View.cs b/Terminal.Gui/Core/View.cs index 24a2ca606..d6a14e6b7 100644 --- a/Terminal.Gui/Core/View.cs +++ b/Terminal.Gui/Core/View.cs @@ -666,11 +666,11 @@ namespace Terminal.Gui { CanFocus = true; view.tabIndex = tabIndexes.IndexOf (view); } + SetNeedsLayout (); + SetNeedsDisplay (); if (IsInitialized) { view.BeginInit (); } - SetNeedsLayout (); - SetNeedsDisplay (); } ///