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.
This commit is contained in:
Tig
2024-04-13 09:56:46 -06:00
parent 7926781d3c
commit b83b392ccd
8 changed files with 79 additions and 26 deletions

View File

@@ -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));
}
/// <summary>Gets the <see cref="Frame"/> with a screen-relative location.</summary>
/// <returns>The location and size of the view in screen-relative coordinates.</returns>
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)
{

View File

@@ -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;

View File

@@ -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;
}
}
}
}
/// <summary>
/// Fired when the <see cref="Frame"/> changes. This event is fired after the <see cref="Frame"/> has been updated.
/// </summary>
[CanBeNull]
public event EventHandler<DrawEventArgs> ViewportChanged;
/// <summary>
/// Called when the <see cref="Frame"/> changes. Invokes the <see cref="ViewportChanged"/> event.
/// </summary>
/// <param name="e"></param>
protected virtual void OnViewportChanged (DrawEventArgs e)
{
ViewportChanged?.Invoke (this, e);
}
/// <summary>
/// Converts a <see cref="Viewport"/>-relative location to a screen-relative location.
/// </summary>

View File

@@ -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
/// <see cref="View"/>
/// </param>
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
/// <summary>

View File

@@ -3,8 +3,8 @@
/// <summary>Args for events that relate to specific <see cref="View"/></summary>
public class ViewEventArgs : EventArgs
{
/// <summary>Creates a new instance of the <see cref="Terminal.Gui.View"/> class.</summary>
/// <param name="view"></param>
/// <summary>Creates a new instance of the <see cref="Terminal.Gui.ViewEventArgs"/> class.</summary>
/// <param name="view">The view that the event is about.</param>
public ViewEventArgs (View view) { View = view; }
/// <summary>The view that the event is about.</summary>
@@ -18,25 +18,40 @@ public class ViewEventArgs : EventArgs
/// <summary>Event arguments for the <see cref="View.LayoutComplete"/> event.</summary>
public class LayoutEventArgs : EventArgs
{
/// <summary>Creates a new instance of the <see cref="Terminal.Gui.LayoutEventArgs"/> class.</summary>
/// <param name="oldContentSize">The view that the event is about.</param>
public LayoutEventArgs (Size oldContentSize) { OldContentSize = oldContentSize; }
/// <summary>The viewport of the <see cref="View"/> before it was laid out.</summary>
public Rectangle OldViewport { get; set; }
public Size OldContentSize { get; set; }
}
/// <summary>Event args for draw events</summary>
public class DrawEventArgs : EventArgs
{
/// <summary>Creates a new instance of the <see cref="DrawEventArgs"/> class.</summary>
/// <param name="rect">
/// Gets the view-relative rectangle describing the currently visible viewport into the
/// <param name="newViewport">
/// The Content-relative rectangle describing the new visible viewport into the
/// <see cref="View"/>.
/// </param>
public DrawEventArgs (Rectangle rect) { Rectangle = rect; }
/// <param name="oldViewport">
/// The Content-relative rectangle describing the old visible viewport into the
/// <see cref="View"/>.
/// </param>
public DrawEventArgs (Rectangle newViewport, Rectangle oldViewport)
{
NewViewport = newViewport;
OldViewport = oldViewport;
}
/// <summary>If set to true, the draw operation will be canceled, if applicable.</summary>
public bool Cancel { get; set; }
/// <summary>Gets the view-relative rectangle describing the currently visible viewport into the <see cref="View"/>.</summary>
public Rectangle Rectangle { get; }
/// <summary>Gets the Content-relative rectangle describing the old visible viewport into the <see cref="View"/>.</summary>
public Rectangle OldViewport { get; }
/// <summary>Gets the Content-relative rectangle describing the currently visible viewport into the <see cref="View"/>.</summary>
public Rectangle NewViewport { get; }
}
/// <summary>Defines the event arguments for <see cref="View.SetFocus()"/></summary>

View File

@@ -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;

View File

@@ -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);
};

View File

@@ -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;