From b83b392ccdd7bd59433e87e3502300a2dfbd72d4 Mon Sep 17 00:00:00 2001 From: Tig Date: Sat, 13 Apr 2024 09:56:46 -0600 Subject: [PATCH] Updated View and Event classes for viewport and content size handling Updated several classes to improve viewport and content size handling. Added `SetFrame` method to `View` class in `ViewLayout.cs` and replaced direct `_frame` property setting. Updated `OnLayoutStarted` and `OnLayoutComplete` methods to take `ContentSize` instead of `oldViewport`. Added `ViewportChanged` event and `OnViewportChanged` method to `View` class in `ViewContent.cs`. Updated `DrawEventArgs` and `LayoutEventArgs` classes in `ViewEventArgs.cs` to include new and old viewport properties and removed `Rectangle` property. Updated `OnDrawContentComplete` method in `ViewDrawing.cs` to take `DrawEventArgs` instead of `Rectangle`. Updated `SetViewport` method in `ViewContent.cs` to trigger `OnViewportChanged` event. Added check in `ListView.cs` for view initialization before setting `ContentSize` and `Viewport`. Updated `FileDialog` class in `FileDialog.cs` to use `NewViewport.Width` instead of `e.Rectangle.Width`. Updated `ViewEventArgs` class in `ViewEventArgs.cs` to include a `view` parameter in its constructor. --- Terminal.Gui/View/Layout/ViewLayout.cs | 24 +++++++++++++++----- Terminal.Gui/View/ViewAdornments.cs | 6 ++--- Terminal.Gui/View/ViewContent.cs | 27 ++++++++++++++++++---- Terminal.Gui/View/ViewDrawing.cs | 7 ++++-- Terminal.Gui/View/ViewEventArgs.cs | 31 +++++++++++++++++++------- Terminal.Gui/View/ViewText.cs | 2 +- Terminal.Gui/Views/FileDialog.cs | 2 +- Terminal.Gui/Views/ListView.cs | 6 ++++- 8 files changed, 79 insertions(+), 26 deletions(-) diff --git a/Terminal.Gui/View/Layout/ViewLayout.cs b/Terminal.Gui/View/Layout/ViewLayout.cs index 8d35d7c3b..0b5e21f2f 100644 --- a/Terminal.Gui/View/Layout/ViewLayout.cs +++ b/Terminal.Gui/View/Layout/ViewLayout.cs @@ -69,7 +69,7 @@ public partial class View return; } - _frame = value with { Width = Math.Max (value.Width, 0), Height = Math.Max (value.Height, 0) }; + SetFrame (value with { Width = Math.Max (value.Width, 0), Height = Math.Max (value.Height, 0) }); // If Frame gets set, by definition, the View is now LayoutStyle.Absolute, so // set all Pos/Dim to Absolute values. @@ -86,6 +86,19 @@ public partial class View } } + private void SetFrame (Rectangle frame) + { + Rectangle oldViewport = Rectangle.Empty; + if (IsInitialized) + { + oldViewport = Viewport; + } + // This is the only place where _frame should be set directly. Use Frame = or SetFrame instead. + _frame = frame; + + OnViewportChanged (new (IsInitialized ? Viewport : Rectangle.Empty, oldViewport)); + } + /// Gets the with a screen-relative location. /// The location and size of the view in screen-relative coordinates. public virtual Rectangle FrameToScreen () @@ -861,8 +874,7 @@ public partial class View LayoutAdornments (); - Rectangle oldViewport = Viewport; - OnLayoutStarted (new () { OldViewport = oldViewport }); + OnLayoutStarted (new (ContentSize)); SetTextFormatterSize (); @@ -889,7 +901,7 @@ public partial class View LayoutNeeded = false; - OnLayoutComplete (new () { OldViewport = oldViewport }); + OnLayoutComplete (new (ContentSize)); } private void LayoutSubview (View v, Size contentSize) { @@ -1163,7 +1175,7 @@ public partial class View { // Set the frame. Do NOT use `Frame` as it overwrites X, Y, Width, and Height, making // the view LayoutStyle.Absolute. - _frame = r; + SetFrame (r); if (_x is Pos.PosAbsolute) { @@ -1195,7 +1207,7 @@ public partial class View { // Set the frame. Do NOT use `Frame` as it overwrites X, Y, Width, and Height, making // the view LayoutStyle.Absolute. - _frame = _frame with { Size = autosize }; + SetFrame (_frame with { Size = autosize }); if (autosize.Width == 0) { diff --git a/Terminal.Gui/View/ViewAdornments.cs b/Terminal.Gui/View/ViewAdornments.cs index 1168798f4..4efd92b52 100644 --- a/Terminal.Gui/View/ViewAdornments.cs +++ b/Terminal.Gui/View/ViewAdornments.cs @@ -151,7 +151,7 @@ public partial class View if (Margin.Frame.Size != Frame.Size) { - Margin._frame = Rectangle.Empty with { Size = Frame.Size }; + Margin.SetFrame (Rectangle.Empty with { Size = Frame.Size }); Margin.X = 0; Margin.Y = 0; Margin.Width = Frame.Size.Width; @@ -170,7 +170,7 @@ public partial class View if (border != Border.Frame) { - Border._frame = border; + Border.SetFrame (border); Border.X = border.Location.X; Border.Y = border.Location.Y; Border.Width = border.Size.Width; @@ -189,7 +189,7 @@ public partial class View if (padding != Padding.Frame) { - Padding._frame = padding; + Padding.SetFrame (padding); Padding.X = padding.Location.X; Padding.Y = padding.Location.Y; Padding.Width = padding.Size.Width; diff --git a/Terminal.Gui/View/ViewContent.cs b/Terminal.Gui/View/ViewContent.cs index 20692d86c..2f086b809 100644 --- a/Terminal.Gui/View/ViewContent.cs +++ b/Terminal.Gui/View/ViewContent.cs @@ -207,8 +207,11 @@ public partial class View _viewportSettings = value; - // Force set Viewport to cause settings to be applied as needed - SetViewport (Viewport); + if (IsInitialized) + { + // Force set Viewport to cause settings to be applied as needed + SetViewport (Viewport); + } } } @@ -287,6 +290,7 @@ public partial class View private void SetViewport (Rectangle viewport) { + Rectangle oldViewport = viewport; ApplySettings (ref viewport); Thickness thickness = GetAdornmentsThickness (); @@ -305,6 +309,7 @@ public partial class View SetNeedsLayout (); } + OnViewportChanged (new (IsInitialized ? Viewport : Rectangle.Empty, oldViewport)); return; } @@ -353,10 +358,24 @@ public partial class View newViewport.Y = 0; } } - } } - + + /// + /// Fired when the changes. This event is fired after the has been updated. + /// + [CanBeNull] + public event EventHandler ViewportChanged; + + /// + /// Called when the changes. Invokes the event. + /// + /// + protected virtual void OnViewportChanged (DrawEventArgs e) + { + ViewportChanged?.Invoke (this, e); + } + /// /// Converts a -relative location to a screen-relative location. /// diff --git a/Terminal.Gui/View/ViewDrawing.cs b/Terminal.Gui/View/ViewDrawing.cs index fd10d4a00..ecb14bdcc 100644 --- a/Terminal.Gui/View/ViewDrawing.cs +++ b/Terminal.Gui/View/ViewDrawing.cs @@ -182,7 +182,7 @@ public partial class View } // Invoke DrawContentEvent - var dev = new DrawEventArgs (Viewport); + var dev = new DrawEventArgs (Viewport, Rectangle.Empty); DrawContent?.Invoke (this, dev); if (!dev.Cancel) @@ -489,7 +489,10 @@ public partial class View /// The viewport-relative rectangle describing the currently visible viewport into the /// /// - public virtual void OnDrawContentComplete (Rectangle viewport) { DrawContentComplete?.Invoke (this, new (viewport)); } + public virtual void OnDrawContentComplete (Rectangle viewport) + { + DrawContentComplete?.Invoke (this, new (viewport, Rectangle.Empty)); + } // TODO: Make this cancelable /// diff --git a/Terminal.Gui/View/ViewEventArgs.cs b/Terminal.Gui/View/ViewEventArgs.cs index 2a2a8875f..a53575f2e 100644 --- a/Terminal.Gui/View/ViewEventArgs.cs +++ b/Terminal.Gui/View/ViewEventArgs.cs @@ -3,8 +3,8 @@ /// Args for events that relate to specific public class ViewEventArgs : EventArgs { - /// Creates a new instance of the class. - /// + /// Creates a new instance of the class. + /// The view that the event is about. public ViewEventArgs (View view) { View = view; } /// The view that the event is about. @@ -18,25 +18,40 @@ public class ViewEventArgs : EventArgs /// Event arguments for the event. public class LayoutEventArgs : EventArgs { + /// Creates a new instance of the class. + /// The view that the event is about. + public LayoutEventArgs (Size oldContentSize) { OldContentSize = oldContentSize; } + /// The viewport of the before it was laid out. - public Rectangle OldViewport { get; set; } + public Size OldContentSize { get; set; } } /// Event args for draw events public class DrawEventArgs : EventArgs { /// Creates a new instance of the class. - /// - /// Gets the view-relative rectangle describing the currently visible viewport into the + /// + /// The Content-relative rectangle describing the new visible viewport into the /// . /// - public DrawEventArgs (Rectangle rect) { Rectangle = rect; } + /// + /// The Content-relative rectangle describing the old visible viewport into the + /// . + /// + public DrawEventArgs (Rectangle newViewport, Rectangle oldViewport) + { + NewViewport = newViewport; + OldViewport = oldViewport; + } /// If set to true, the draw operation will be canceled, if applicable. public bool Cancel { get; set; } - /// Gets the view-relative rectangle describing the currently visible viewport into the . - public Rectangle Rectangle { get; } + /// Gets the Content-relative rectangle describing the old visible viewport into the . + public Rectangle OldViewport { get; } + + /// Gets the Content-relative rectangle describing the currently visible viewport into the . + public Rectangle NewViewport { get; } } /// Defines the event arguments for diff --git a/Terminal.Gui/View/ViewText.cs b/Terminal.Gui/View/ViewText.cs index f155b3216..96c33e56e 100644 --- a/Terminal.Gui/View/ViewText.cs +++ b/Terminal.Gui/View/ViewText.cs @@ -365,7 +365,7 @@ public partial class View // TODO: This is a hack. //_width = size.Width; //_height = size.Height; - _frame = new (_frame.Location, size); + SetFrame (new (_frame.Location, size)); //throw new InvalidOperationException ("This is a hack."); return true; diff --git a/Terminal.Gui/Views/FileDialog.cs b/Terminal.Gui/Views/FileDialog.cs index 905223418..0e4f95c2c 100644 --- a/Terminal.Gui/Views/FileDialog.cs +++ b/Terminal.Gui/Views/FileDialog.cs @@ -519,7 +519,7 @@ public class FileDialog : Dialog _allowedTypeMenuBar.DrawContentComplete += (s, e) => { - _allowedTypeMenuBar.Move (e.Rectangle.Width - 1, 0); + _allowedTypeMenuBar.Move (e.NewViewport.Width - 1, 0); Driver.AddRune (Glyphs.DownArrow); }; diff --git a/Terminal.Gui/Views/ListView.cs b/Terminal.Gui/Views/ListView.cs index 5cceaa9b3..1e743fab4 100644 --- a/Terminal.Gui/Views/ListView.cs +++ b/Terminal.Gui/Views/ListView.cs @@ -265,7 +265,11 @@ public class ListView : View _source = value; ContentSize = new Size (_source?.Length ?? Viewport.Width, _source?.Count ?? Viewport.Width); - Viewport = Viewport with { Y = 0 }; + if (IsInitialized) + { + Viewport = Viewport with { Y = 0 }; + } + KeystrokeNavigator.Collection = _source?.ToList (); _selected = -1; _lastSelectedItem = -1;