From 73a9dc37c48587e4d042ada19ece2296b17b0fe5 Mon Sep 17 00:00:00 2001 From: Tig Date: Wed, 24 Jul 2024 14:15:32 -0600 Subject: [PATCH] Fixed nullable warnings 2 --- .../Application/Application.Initialization.cs | 32 ++-- .../Application/Application.Keyboard.cs | 6 +- Terminal.Gui/Application/Application.Mouse.cs | 14 +- .../Application/Application.Overlapped.cs | 20 +-- Terminal.Gui/Application/Application.Run.cs | 74 +++++---- .../Application/Application.Toplevel.cs | 6 +- Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs | 5 +- Terminal.Gui/View/Adornment/Margin.cs | 4 +- Terminal.Gui/View/Adornment/ShadowView.cs | 2 +- Terminal.Gui/View/Layout/Dim.cs | 2 +- Terminal.Gui/View/Layout/DimView.cs | 2 +- Terminal.Gui/View/Layout/Pos.cs | 4 +- Terminal.Gui/View/Layout/PosView.cs | 2 +- Terminal.Gui/Views/Menu/MenuBar.cs | 2 +- UICatalog/UICatalog.cs | 2 +- UnitTests/Views/MenuBarTests.cs | 142 ++++++++---------- UnitTests/Views/ToplevelTests.cs | 9 +- 17 files changed, 154 insertions(+), 174 deletions(-) diff --git a/Terminal.Gui/Application/Application.Initialization.cs b/Terminal.Gui/Application/Application.Initialization.cs index 2e184b285..0d9b2caf5 100644 --- a/Terminal.Gui/Application/Application.Initialization.cs +++ b/Terminal.Gui/Application/Application.Initialization.cs @@ -36,7 +36,7 @@ public static partial class Application // Initialization (Init/Shutdown) /// [RequiresUnreferencedCode ("AOT")] [RequiresDynamicCode ("AOT")] - public static void Init (ConsoleDriver driver = null, string driverName = null) { InternalInit (driver, driverName); } + public static void Init (ConsoleDriver? driver = null, string? driverName = null) { InternalInit (driver, driverName); } internal static bool _initialized; internal static int _mainThreadId = -1; @@ -53,8 +53,8 @@ public static partial class Application // Initialization (Init/Shutdown) [RequiresUnreferencedCode ("AOT")] [RequiresDynamicCode ("AOT")] internal static void InternalInit ( - ConsoleDriver driver = null, - string driverName = null, + ConsoleDriver? driver = null, + string? driverName = null, bool calledViaRunT = false ) { @@ -114,17 +114,17 @@ public static partial class Application // Initialization (Init/Shutdown) } else { - List drivers = GetDriverTypes (); - Type driverType = drivers.FirstOrDefault (t => t.Name.Equals (ForceDriver, StringComparison.InvariantCultureIgnoreCase)); + List drivers = GetDriverTypes (); + Type? driverType = drivers.FirstOrDefault (t => t!.Name.Equals (ForceDriver, StringComparison.InvariantCultureIgnoreCase)); if (driverType is { }) { - Driver = (ConsoleDriver)Activator.CreateInstance (driverType); + Driver = (ConsoleDriver)Activator.CreateInstance (driverType)!; } else { throw new ArgumentException ( - $"Invalid driver name: {ForceDriver}. Valid names are {string.Join (", ", drivers.Select (t => t.Name))}" + $"Invalid driver name: {ForceDriver}. Valid names are {string.Join (", ", drivers.Select (t => t!.Name))}" ); } } @@ -132,7 +132,7 @@ public static partial class Application // Initialization (Init/Shutdown) try { - MainLoop = Driver.Init (); + MainLoop = Driver!.Init (); } catch (InvalidOperationException ex) { @@ -159,22 +159,22 @@ public static partial class Application // Initialization (Init/Shutdown) InitializedChanged?.Invoke (null, new (in _initialized)); } - private static void Driver_SizeChanged (object sender, SizeChangedEventArgs e) { OnSizeChanging (e); } - private static void Driver_KeyDown (object sender, Key e) { OnKeyDown (e); } - private static void Driver_KeyUp (object sender, Key e) { OnKeyUp (e); } - private static void Driver_MouseEvent (object sender, MouseEvent e) { OnMouseEvent (e); } + private static void Driver_SizeChanged (object? sender, SizeChangedEventArgs e) { OnSizeChanging (e); } + private static void Driver_KeyDown (object? sender, Key e) { OnKeyDown (e); } + private static void Driver_KeyUp (object? sender, Key e) { OnKeyUp (e); } + private static void Driver_MouseEvent (object? sender, MouseEvent e) { OnMouseEvent (e); } /// Gets of list of types that are available. /// [RequiresUnreferencedCode ("AOT")] - public static List GetDriverTypes () + public static List GetDriverTypes () { // use reflection to get the list of drivers - List driverTypes = new (); + List driverTypes = new (); foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies ()) { - foreach (Type type in asm.GetTypes ()) + foreach (Type? type in asm.GetTypes ()) { if (type.IsSubclassOf (typeof (ConsoleDriver)) && !type.IsAbstract) { @@ -207,5 +207,5 @@ public static partial class Application // Initialization (Init/Shutdown) /// /// Intended to support unit tests that need to know when the application has been initialized. /// - public static event EventHandler> InitializedChanged; + public static event EventHandler>? InitializedChanged; } diff --git a/Terminal.Gui/Application/Application.Keyboard.cs b/Terminal.Gui/Application/Application.Keyboard.cs index bc6507c86..10419bf80 100644 --- a/Terminal.Gui/Application/Application.Keyboard.cs +++ b/Terminal.Gui/Application/Application.Keyboard.cs @@ -98,7 +98,7 @@ public static partial class Application // Keyboard handling /// and events. /// Fired after and before . /// - public static event EventHandler KeyDown; + public static event EventHandler? KeyDown; /// /// Called by the when the user presses a key. Fires the event @@ -199,7 +199,7 @@ public static partial class Application // Keyboard handling /// and events. /// Fired after . /// - public static event EventHandler KeyUp; + public static event EventHandler? KeyUp; /// /// Called by the when the user releases a key. Fires the event @@ -304,7 +304,7 @@ public static partial class Application // Keyboard handling { if (OverlappedTop is { }) { - RequestStop (Current); + RequestStop (Current!); } else { diff --git a/Terminal.Gui/Application/Application.Mouse.cs b/Terminal.Gui/Application/Application.Mouse.cs index 61fc6d63e..713e6375d 100644 --- a/Terminal.Gui/Application/Application.Mouse.cs +++ b/Terminal.Gui/Application/Application.Mouse.cs @@ -9,32 +9,32 @@ public static partial class Application // Mouse handling public static bool IsMouseDisabled { get; set; } /// The current object that wants continuous mouse button pressed events. - public static View WantContinuousButtonPressedView { get; private set; } + public static View? WantContinuousButtonPressedView { get; private set; } /// /// Gets the view that grabbed the mouse (e.g. for dragging). When this is set, all mouse events will be routed to /// this view until the view calls or the mouse is released. /// - public static View MouseGrabView { get; private set; } + public static View? MouseGrabView { get; private set; } /// Invoked when a view wants to grab the mouse; can be canceled. - public static event EventHandler GrabbingMouse; + public static event EventHandler? GrabbingMouse; /// Invoked when a view wants un-grab the mouse; can be canceled. - public static event EventHandler UnGrabbingMouse; + public static event EventHandler? UnGrabbingMouse; /// Invoked after a view has grabbed the mouse. - public static event EventHandler GrabbedMouse; + public static event EventHandler? GrabbedMouse; /// Invoked after a view has un-grabbed the mouse. - public static event EventHandler UnGrabbedMouse; + public static event EventHandler? UnGrabbedMouse; /// /// Grabs the mouse, forcing all mouse events to be routed to the specified view until /// is called. /// /// View that will receive all mouse events until is invoked. - public static void GrabMouse (View view) + public static void GrabMouse (View? view) { if (view is null) { diff --git a/Terminal.Gui/Application/Application.Overlapped.cs b/Terminal.Gui/Application/Application.Overlapped.cs index 1ac547fde..26e931c98 100644 --- a/Terminal.Gui/Application/Application.Overlapped.cs +++ b/Terminal.Gui/Application/Application.Overlapped.cs @@ -11,7 +11,7 @@ internal static class ViewNavigation /// /// /// - internal static View GetDeepestFocusedSubview (View view) + internal static View? GetDeepestFocusedSubview (View? view) { if (view is null) { @@ -30,7 +30,7 @@ internal static class ViewNavigation } /// - /// Sets the focus to the next view in the list. If the last view is focused, the first view is focused. + /// Sets the focus to the next view in the list. If the last view is focused, the first view is focused. /// /// /// @@ -56,11 +56,11 @@ internal static class ViewNavigation { if (direction == NavigationDirection.Forward) { - Application.Current.SuperView?.FocusNext (); + Application.Current!.SuperView?.FocusNext (); } else { - Application.Current.SuperView?.FocusPrev (); + Application.Current!.SuperView?.FocusPrev (); } focusProcessed = true; @@ -83,7 +83,7 @@ internal static class ViewNavigation /// internal static void MoveNextView () { - View old = GetDeepestFocusedSubview (Application.Current.Focused); + View? old = GetDeepestFocusedSubview (Application.Current!.Focused); if (!Application.Current.FocusNext ()) { @@ -105,8 +105,8 @@ internal static class ViewNavigation { if (Application.OverlappedTop is null) { - Toplevel top = Application.Current.Modal ? Application.Current : Application.Top; - top.FocusNext (); + Toplevel? top = Application.Current!.Modal ? Application.Current : Application.Top; + top!.FocusNext (); if (top.Focused is null) { @@ -124,7 +124,7 @@ internal static class ViewNavigation internal static void MovePreviousView () { - View old = GetDeepestFocusedSubview (Application.Current.Focused); + View? old = GetDeepestFocusedSubview (Application.Current!.Focused); if (!Application.Current.FocusPrev ()) { @@ -146,8 +146,8 @@ internal static class ViewNavigation { if (Application.OverlappedTop is null) { - Toplevel top = Application.Current.Modal ? Application.Current : Application.Top; - top.FocusPrev (); + Toplevel? top = Application.Current!.Modal ? Application.Current : Application.Top; + top!.FocusPrev (); if (top.Focused is null) { diff --git a/Terminal.Gui/Application/Application.Run.cs b/Terminal.Gui/Application/Application.Run.cs index 541ad7141..bbff9c1ba 100644 --- a/Terminal.Gui/Application/Application.Run.cs +++ b/Terminal.Gui/Application/Application.Run.cs @@ -8,7 +8,7 @@ public static partial class Application // Run (Begin, Run, End, Stop) { // When `End ()` is called, it is possible `RunState.Toplevel` is a different object than `Top`. // This variable is set in `End` in this case so that `Begin` correctly sets `Top`. - private static Toplevel _cachedRunStateToplevel; + private static Toplevel? _cachedRunStateToplevel; /// /// Notify that a new was created ( was called). The token is @@ -19,7 +19,7 @@ public static partial class Application // Run (Begin, Run, End, Stop) /// must also subscribe to and manually dispose of the token /// when the application is done. /// - public static event EventHandler NotifyNewRunState; + public static event EventHandler? NotifyNewRunState; /// Notify that an existent is stopping ( was called). /// @@ -27,7 +27,7 @@ public static partial class Application // Run (Begin, Run, End, Stop) /// must also subscribe to and manually dispose of the token /// when the application is done. /// - public static event EventHandler NotifyStopRunState; + public static event EventHandler? NotifyStopRunState; /// Building block API: Prepares the provided for execution. /// @@ -96,9 +96,9 @@ public static partial class Application // Run (Begin, Run, End, Stop) throw new ObjectDisposedException (Top.GetType ().FullName); } } - else if (OverlappedTop is { } && toplevel != Top && _topLevels.Contains (Top)) + else if (OverlappedTop is { } && toplevel != Top && _topLevels.Contains (Top!)) { - Top.OnLeave (toplevel); + Top!.OnLeave (toplevel); } // BUGBUG: We should not depend on `Id` internally. @@ -120,7 +120,7 @@ public static partial class Application // Run (Begin, Run, End, Stop) } else { - Toplevel dup = _topLevels.FirstOrDefault (x => x.Id == toplevel.Id); + Toplevel? dup = _topLevels.FirstOrDefault (x => x.Id == toplevel.Id); if (dup is null) { @@ -150,7 +150,7 @@ public static partial class Application // Run (Begin, Run, End, Stop) if (toplevel.Visible) { Current?.OnDeactivate (toplevel); - Toplevel previousCurrent = Current; + Toplevel previousCurrent = Current!; Current = toplevel; Current.OnActivate (previousCurrent); @@ -161,11 +161,10 @@ public static partial class Application // Run (Begin, Run, End, Stop) refreshDriver = false; } } - else if ((OverlappedTop != null - && toplevel != OverlappedTop + else if ((toplevel != OverlappedTop && Current?.Modal == true && !_topLevels.Peek ().Modal) - || (OverlappedTop is { } && toplevel != OverlappedTop && Current?.Running == false)) + || (toplevel != OverlappedTop && Current?.Running == false)) { refreshDriver = false; MoveCurrent (toplevel); @@ -173,10 +172,10 @@ public static partial class Application // Run (Begin, Run, End, Stop) else { refreshDriver = false; - MoveCurrent (Current); + MoveCurrent (Current!); } - toplevel.SetRelativeLayout (Driver.Screen.Size); + toplevel.SetRelativeLayout (Driver!.Screen.Size); toplevel.LayoutSubviews (); toplevel.PositionToplevels (); @@ -216,7 +215,7 @@ public static partial class Application // Run (Begin, Run, End, Stop) internal static bool PositionCursor (View view) { // Find the most focused view and position the cursor there. - View mostFocused = view?.MostFocused; + View? mostFocused = view?.MostFocused; if (mostFocused is null) { @@ -233,7 +232,7 @@ public static partial class Application // Run (Begin, Run, End, Stop) // If the view is not visible or enabled, don't position the cursor if (!mostFocused.Visible || !mostFocused.Enabled) { - Driver.GetCursorVisibility (out CursorVisibility current); + Driver!.GetCursorVisibility (out CursorVisibility current); if (current != CursorVisibility.Invisible) { @@ -245,7 +244,7 @@ public static partial class Application // Run (Begin, Run, End, Stop) // If the view is not visible within it's superview, don't position the cursor Rectangle mostFocusedViewport = mostFocused.ViewportToScreen (mostFocused.Viewport with { Location = Point.Empty }); - Rectangle superViewViewport = mostFocused.SuperView?.ViewportToScreen (mostFocused.SuperView.Viewport with { Location = Point.Empty }) ?? Driver.Screen; + Rectangle superViewViewport = mostFocused.SuperView?.ViewportToScreen (mostFocused.SuperView.Viewport with { Location = Point.Empty }) ?? Driver!.Screen; if (!superViewViewport.IntersectsWith (mostFocusedViewport)) { @@ -254,7 +253,7 @@ public static partial class Application // Run (Begin, Run, End, Stop) Point? cursor = mostFocused.PositionCursor (); - Driver.GetCursorVisibility (out CursorVisibility currentCursorVisibility); + Driver!.GetCursorVisibility (out CursorVisibility currentCursorVisibility); if (cursor is { }) { @@ -306,7 +305,7 @@ public static partial class Application // Run (Begin, Run, End, Stop) /// The created object. The caller is responsible for disposing this object. [RequiresUnreferencedCode ("AOT")] [RequiresDynamicCode ("AOT")] - public static Toplevel Run (Func errorHandler = null, ConsoleDriver driver = null) { return Run (errorHandler, driver); } + public static Toplevel Run (Func? errorHandler = null, ConsoleDriver? driver = null) { return Run (errorHandler, driver); } /// /// Runs the application by creating a -derived object of type T and calling @@ -331,7 +330,7 @@ public static partial class Application // Run (Begin, Run, End, Stop) /// The created T object. The caller is responsible for disposing this object. [RequiresUnreferencedCode ("AOT")] [RequiresDynamicCode ("AOT")] - public static T Run (Func errorHandler = null, ConsoleDriver driver = null) + public static T Run (Func? errorHandler = null, ConsoleDriver? driver = null) where T : Toplevel, new () { if (!_initialized) @@ -385,7 +384,7 @@ public static partial class Application // Run (Begin, Run, End, Stop) /// RELEASE builds only: Handler for any unhandled exceptions (resumes when returns true, /// rethrows when null). /// - public static void Run (Toplevel view, Func errorHandler = null) + public static void Run (Toplevel view, Func? errorHandler = null) { ArgumentNullException.ThrowIfNull (view); @@ -460,7 +459,7 @@ public static partial class Application // Run (Begin, Run, End, Stop) /// reset, repeating the invocation. If it returns false, the timeout will stop and be removed. The returned value is a /// token that can be used to stop the timeout by calling . /// - public static object AddTimeout (TimeSpan time, Func callback) { return MainLoop?.AddTimeout (time, callback); } + public static object AddTimeout (TimeSpan time, Func callback) { return MainLoop!.AddTimeout (time, callback); } /// Removes a previously scheduled timeout /// The token parameter is the value returned by . @@ -498,8 +497,7 @@ public static partial class Application // Run (Begin, Run, End, Stop) public static void Refresh () { // TODO: Figure out how to remove this call to ClearContents. Refresh should just repaint damaged areas, not clear - Driver.ClearContents (); - View last = null; + Driver!.ClearContents (); foreach (Toplevel v in _topLevels.Reverse ()) { @@ -509,8 +507,6 @@ public static partial class Application // Run (Begin, Run, End, Stop) v.SetSubViewNeedsDisplay (); v.Draw (); } - - last = v; } Driver.Refresh (); @@ -518,11 +514,11 @@ public static partial class Application // Run (Begin, Run, End, Stop) /// This event is raised on each iteration of the main loop. /// See also - public static event EventHandler Iteration; + public static event EventHandler? Iteration; /// The driver for the application /// The main loop. - internal static MainLoop MainLoop { get; private set; } + internal static MainLoop? MainLoop { get; private set; } /// /// Set to true to cause to be called after the first iteration. Set to false (the default) to @@ -661,17 +657,17 @@ public static partial class Application // Run (Begin, Run, End, Stop) /// property on the currently running to false. /// /// - public static void RequestStop (Toplevel top = null) + public static void RequestStop (Toplevel? top = null) { - if (OverlappedTop is null || top is null || (OverlappedTop is null && top is { })) + if (OverlappedTop is null || top is null) { top = Current; } if (OverlappedTop != null - && top.IsOverlappedContainer + && top!.IsOverlappedContainer && top?.Running == true - && (Current?.Modal == false || (Current?.Modal == true && Current?.Running == false))) + && (Current?.Modal == false || Current is { Modal: true, Running: false })) { OverlappedTop.RequestStop (); } @@ -679,7 +675,7 @@ public static partial class Application // Run (Begin, Run, End, Stop) && top != Current && Current?.Running == true && Current?.Modal == true - && top.Modal + && top!.Modal && top.Running) { var ev = new ToplevelClosingEventArgs (Current); @@ -708,13 +704,13 @@ public static partial class Application // Run (Begin, Run, End, Stop) && top != Current && Current?.Modal == false && Current?.Running == true - && !top.Running) + && !top!.Running) || (OverlappedTop != null && top != OverlappedTop && top != Current && Current?.Modal == false && Current?.Running == false - && !top.Running + && !top!.Running && _topLevels.ToArray () [1].Running)) { MoveCurrent (top); @@ -722,7 +718,7 @@ public static partial class Application // Run (Begin, Run, End, Stop) else if (OverlappedTop != null && Current != top && Current?.Running == true - && !top.Running + && !top!.Running && Current?.Modal == true && top.Modal) { @@ -734,9 +730,9 @@ public static partial class Application // Run (Begin, Run, End, Stop) && Current == top && OverlappedTop?.Running == true && Current?.Running == true - && top.Running + && top!.Running && Current?.Modal == true - && top.Modal) + && top!.Modal) { // The OverlappedTop was requested to stop inside a modal Toplevel which is the Current and top, // both are the same, so needed to set the Current.Running to false too. @@ -747,13 +743,13 @@ public static partial class Application // Run (Begin, Run, End, Stop) { Toplevel currentTop; - if (top == Current || (Current?.Modal == true && !top.Modal)) + if (top == Current || (Current?.Modal == true && !top!.Modal)) { - currentTop = Current; + currentTop = Current!; } else { - currentTop = top; + currentTop = top!; } if (!currentTop.Running) diff --git a/Terminal.Gui/Application/Application.Toplevel.cs b/Terminal.Gui/Application/Application.Toplevel.cs index d8996a383..e272ea7aa 100644 --- a/Terminal.Gui/Application/Application.Toplevel.cs +++ b/Terminal.Gui/Application/Application.Toplevel.cs @@ -10,7 +10,7 @@ public static partial class Application // Toplevel handling /// The object used for the application on startup () /// The top. - public static Toplevel Top { get; private set; } + public static Toplevel? Top { get; private set; } // TODO: Determine why this can't just return _topLevels.Peek()? /// @@ -22,7 +22,7 @@ public static partial class Application // Toplevel handling /// This will only be distinct from in scenarios where is . /// /// The current. - public static Toplevel Current { get; private set; } + public static Toplevel? Current { get; private set; } /// /// If is not already Current and visible, finds the last Modal Toplevel in the stack and makes it Current. @@ -195,7 +195,7 @@ public static partial class Application // Toplevel handling /// Event handlers can set to to prevent /// from changing it's size to match the new terminal size. /// - public static event EventHandler SizeChanging; + public static event EventHandler? SizeChanging; /// /// Called when the application's size changes. Sets the size of all s and fires the diff --git a/Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs b/Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs index cad728b72..8e6a08d59 100644 --- a/Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs @@ -1,3 +1,4 @@ +#nullable enable // // ConsoleDriver.cs: Base class for Terminal.Gui ConsoleDriver implementations. // @@ -16,7 +17,7 @@ public abstract class ConsoleDriver { // As performance is a concern, we keep track of the dirty lines and only refresh those. // This is in addition to the dirty flag on each cell. - internal bool [] _dirtyLines; + internal bool []? _dirtyLines; // QUESTION: When non-full screen apps are supported, will this represent the app size, or will that be in Application? /// Gets the location and size of the terminal screen. @@ -443,7 +444,7 @@ public abstract class ConsoleDriver public abstract bool SetCursorVisibility (CursorVisibility visibility); /// The event fired when the terminal is resized. - public event EventHandler SizeChanged; + public event EventHandler? SizeChanged; /// Suspends the application (e.g. on Linux via SIGTSTP) and upon resume, resets the console driver. /// This is only implemented in . diff --git a/Terminal.Gui/View/Adornment/Margin.cs b/Terminal.Gui/View/Adornment/Margin.cs index 046965e32..8ef63fe04 100644 --- a/Terminal.Gui/View/Adornment/Margin.cs +++ b/Terminal.Gui/View/Adornment/Margin.cs @@ -222,10 +222,10 @@ public class Margin : Adornment // Adjust the shadow such that it is drawn aligned with the Border if (ShadowStyle != ShadowStyle.None && _rightShadow is { } && _bottomShadow is { }) { - _rightShadow.Y = Parent.Border.Thickness.Top > 0 + _rightShadow.Y = Parent is { } && Parent.Border.Thickness.Top > 0 ? Parent.Border.Thickness.Top - (Parent.Border.Thickness.Top > 2 && Parent.Border.Settings.FastHasFlags (BorderSettings.Title) ? 1 : 0) : 1; - _bottomShadow.X = Parent.Border.Thickness.Left > 0 ? Parent.Border.Thickness.Left : 1; + _bottomShadow.X = Parent is { } && Parent.Border.Thickness.Left > 0 ? Parent.Border.Thickness.Left : 1; } } } diff --git a/Terminal.Gui/View/Adornment/ShadowView.cs b/Terminal.Gui/View/Adornment/ShadowView.cs index c5e7a428a..ad06dc754 100644 --- a/Terminal.Gui/View/Adornment/ShadowView.cs +++ b/Terminal.Gui/View/Adornment/ShadowView.cs @@ -15,7 +15,7 @@ internal class ShadowView : View { var attr = Attribute.Default; - if (adornment.Parent.SuperView is { }) + if (adornment.Parent?.SuperView is { }) { attr = adornment.Parent.SuperView.GetNormalColor (); } diff --git a/Terminal.Gui/View/Layout/Dim.cs b/Terminal.Gui/View/Layout/Dim.cs index 7dfc6eb2e..3102d5d3c 100644 --- a/Terminal.Gui/View/Layout/Dim.cs +++ b/Terminal.Gui/View/Layout/Dim.cs @@ -232,7 +232,7 @@ public abstract class Dim } var newDim = new DimCombine (AddOrSubtract.Add, left, right); - (left as DimView)?.Target.SetNeedsLayout (); + (left as DimView)?.Target?.SetNeedsLayout (); return newDim; } diff --git a/Terminal.Gui/View/Layout/DimView.cs b/Terminal.Gui/View/Layout/DimView.cs index 09ea96800..e95efd4fb 100644 --- a/Terminal.Gui/View/Layout/DimView.cs +++ b/Terminal.Gui/View/Layout/DimView.cs @@ -30,7 +30,7 @@ public class DimView : Dim public override bool Equals (object? other) { return other is DimView abs && abs.Target == Target && abs.Dimension == Dimension; } /// - public override int GetHashCode () { return Target.GetHashCode (); } + public override int GetHashCode () { return Target!.GetHashCode (); } /// /// Gets the View the dimension is anchored to. diff --git a/Terminal.Gui/View/Layout/Pos.cs b/Terminal.Gui/View/Layout/Pos.cs index 853bfa0ab..63e14b67f 100644 --- a/Terminal.Gui/View/Layout/Pos.cs +++ b/Terminal.Gui/View/Layout/Pos.cs @@ -379,7 +379,7 @@ public abstract class Pos if (left is PosView view) { - view.Target.SetNeedsLayout (); + view.Target?.SetNeedsLayout (); } return newPos; @@ -408,7 +408,7 @@ public abstract class Pos if (left is PosView view) { - view.Target.SetNeedsLayout (); + view.Target?.SetNeedsLayout (); } return newPos; diff --git a/Terminal.Gui/View/Layout/PosView.cs b/Terminal.Gui/View/Layout/PosView.cs index fdf5bf784..8ceba980f 100644 --- a/Terminal.Gui/View/Layout/PosView.cs +++ b/Terminal.Gui/View/Layout/PosView.cs @@ -28,7 +28,7 @@ public class PosView (View? view, Side side) : Pos public override bool Equals (object? other) { return other is PosView abs && abs.Target == Target && abs.Side == Side; } /// - public override int GetHashCode () { return Target.GetHashCode (); } + public override int GetHashCode () { return Target!.GetHashCode (); } /// public override string ToString () diff --git a/Terminal.Gui/Views/Menu/MenuBar.cs b/Terminal.Gui/Views/Menu/MenuBar.cs index 0b4e574de..3428b2c93 100644 --- a/Terminal.Gui/Views/Menu/MenuBar.cs +++ b/Terminal.Gui/Views/Menu/MenuBar.cs @@ -1594,7 +1594,7 @@ public class MenuBar : View, IDesignable /// - public bool EnableForDesign (in TContext context) where TContext : notnull + public bool EnableForDesign (ref readonly TContext context) where TContext : notnull { if (context is not Func actionFn) { diff --git a/UICatalog/UICatalog.cs b/UICatalog/UICatalog.cs index dd18f0bd1..a2cc9a474 100644 --- a/UICatalog/UICatalog.cs +++ b/UICatalog/UICatalog.cs @@ -715,7 +715,7 @@ internal class UICatalogApp } ColorScheme = Colors.ColorSchemes [_topLevelColorScheme]; - Application.Top.SetNeedsDisplay (); + Application.Top!.SetNeedsDisplay (); }; schemeMenuItems.Add (item); } diff --git a/UnitTests/Views/MenuBarTests.cs b/UnitTests/Views/MenuBarTests.cs index 35d08beff..6f9de4683 100644 --- a/UnitTests/Views/MenuBarTests.cs +++ b/UnitTests/Views/MenuBarTests.cs @@ -1,6 +1,4 @@ -using UICatalog.Scenarios; -using Xunit.Abstractions; - +using Xunit.Abstractions; namespace Terminal.Gui.ViewsTests; @@ -34,13 +32,13 @@ public class MenuBarTests (ITestOutputHelper output) Assert.True ( menu.NewMouseEvent ( - new() { Position = new (0, 0), Flags = MouseFlags.Button1Pressed, View = menu } + new () { Position = new (0, 0), Flags = MouseFlags.Button1Pressed, View = menu } ) ); Assert.True ( menu._openMenu.NewMouseEvent ( - new() { Position = new (0, 0), Flags = MouseFlags.Button1Clicked, View = menu._openMenu } + new () { Position = new (0, 0), Flags = MouseFlags.Button1Clicked, View = menu._openMenu } ) ); Application.MainLoop.RunIteration (); @@ -54,7 +52,7 @@ public class MenuBarTests (ITestOutputHelper output) Assert.True ( menu.NewMouseEvent ( - new() { Position = new (0, 0), Flags = MouseFlags.Button1Pressed, View = menu } + new () { Position = new (0, 0), Flags = MouseFlags.Button1Pressed, View = menu } ) ); Application.Refresh (); @@ -63,16 +61,14 @@ public class MenuBarTests (ITestOutputHelper output) @$" Nullable Checked ┌──────────────────────┐ -│ { - CM.Glyphs.CheckStateNone -} Check this out 你 │ +│ {CM.Glyphs.CheckStateNone} Check this out 你 │ └──────────────────────┘", output ); Assert.True ( menu._openMenu.NewMouseEvent ( - new() { Position = new (0, 0), Flags = MouseFlags.Button1Clicked, View = menu._openMenu } + new () { Position = new (0, 0), Flags = MouseFlags.Button1Clicked, View = menu._openMenu } ) ); Application.MainLoop.RunIteration (); @@ -84,13 +80,13 @@ public class MenuBarTests (ITestOutputHelper output) Assert.True ( menu.NewMouseEvent ( - new() { Position = new (0, 0), Flags = MouseFlags.Button1Pressed, View = menu } + new () { Position = new (0, 0), Flags = MouseFlags.Button1Pressed, View = menu } ) ); Assert.True ( menu._openMenu.NewMouseEvent ( - new() { Position = new (0, 0), Flags = MouseFlags.Button1Clicked, View = menu._openMenu } + new () { Position = new (0, 0), Flags = MouseFlags.Button1Clicked, View = menu._openMenu } ) ); Application.MainLoop.RunIteration (); @@ -185,7 +181,7 @@ public class MenuBarTests (ITestOutputHelper output) Assert.True (menuBar.WantMousePositionReports); Assert.False (menuBar.IsMenuOpen); - menuBar = new() { Menus = [] }; + menuBar = new () { Menus = [] }; Assert.Equal (0, menuBar.X); Assert.Equal (0, menuBar.Y); Assert.IsType (menuBar.Width); @@ -296,7 +292,7 @@ public class MenuBarTests (ITestOutputHelper output) Assert.True ( menu.NewMouseEvent ( - new() { Position = new (0, 0), Flags = MouseFlags.Button1Pressed, View = menu } + new () { Position = new (0, 0), Flags = MouseFlags.Button1Pressed, View = menu } ) ); top.Draw (); @@ -317,7 +313,7 @@ public class MenuBarTests (ITestOutputHelper output) Assert.True ( top.Subviews [1] .NewMouseEvent ( - new() { Position = new (0, 2), Flags = MouseFlags.Button1Clicked, View = top.Subviews [1] } + new () { Position = new (0, 2), Flags = MouseFlags.Button1Clicked, View = top.Subviews [1] } ) ); top.Subviews [1].Draw (); @@ -338,7 +334,7 @@ public class MenuBarTests (ITestOutputHelper output) Assert.True ( top.Subviews [1] .NewMouseEvent ( - new() { Position = new (0, 2), Flags = MouseFlags.ReportMousePosition, View = top.Subviews [1] } + new () { Position = new (0, 2), Flags = MouseFlags.ReportMousePosition, View = top.Subviews [1] } ) ); top.Subviews [1].Draw (); @@ -516,7 +512,7 @@ public class MenuBarTests (ITestOutputHelper output) output ); - Application.OnMouseEvent (new() { Position = new (20, 5), Flags = MouseFlags.Button1Clicked }); + Application.OnMouseEvent (new () { Position = new (20, 5), Flags = MouseFlags.Button1Clicked }); firstIteration = false; @@ -549,7 +545,7 @@ public class MenuBarTests (ITestOutputHelper output) { menu.OpenMenu (); - Application.OnMouseEvent (new() { Position = new (20, 5 + i), Flags = MouseFlags.Button1Clicked }); + Application.OnMouseEvent (new () { Position = new (20, 5 + i), Flags = MouseFlags.Button1Clicked }); firstIteration = false; Application.RunIteration (ref rsDialog, ref firstIteration); @@ -705,7 +701,7 @@ public class MenuBarTests (ITestOutputHelper output) output ); - Application.OnMouseEvent (new() { Position = new (20, 5), Flags = MouseFlags.Button1Clicked }); + Application.OnMouseEvent (new () { Position = new (20, 5), Flags = MouseFlags.Button1Clicked }); firstIteration = false; @@ -727,7 +723,7 @@ public class MenuBarTests (ITestOutputHelper output) { menu.OpenMenu (); - Application.OnMouseEvent (new() { Position = new (20, 5 + i), Flags = MouseFlags.Button1Clicked }); + Application.OnMouseEvent (new () { Position = new (20, 5 + i), Flags = MouseFlags.Button1Clicked }); firstIteration = false; Application.RunIteration (ref rs, ref firstIteration); @@ -1253,15 +1249,15 @@ wo MenuItem mbiCurrent = null; MenuItem miCurrent = null; - MenuBar menu = new MenuBar (); - menu.EnableForDesign ( - new Func (s => - { - miAction = s as string; + var menu = new MenuBar (); - return true; - }) - ); + Func fn = s => + { + miAction = s as string; + + return true; + }; + menu.EnableForDesign (ref fn); menu.Key = KeyCode.F9; menu.MenuOpening += (s, e) => mbiCurrent = e.CurrentMenu; @@ -1303,15 +1299,17 @@ wo MenuItem mbiCurrent = null; MenuItem miCurrent = null; - MenuBar menu = new MenuBar (); - menu.EnableForDesign ( - new Func (s => - { - miAction = s as string; + var menu = new MenuBar (); - return true; - }) - ); + menu.EnableForDesign ( + new Func ( + s => + { + miAction = s as string; + + return true; + }) + ); menu.Key = KeyCode.F9; menu.MenuOpening += (s, e) => mbiCurrent = e.CurrentMenu; @@ -1478,13 +1476,13 @@ wo top.Add (menu); Application.Begin (top); - Assert.True (menu.NewMouseEvent (new() { Position = new (1, 0), Flags = MouseFlags.Button1Pressed, View = menu })); + Assert.True (menu.NewMouseEvent (new () { Position = new (1, 0), Flags = MouseFlags.Button1Pressed, View = menu })); Assert.True (menu.IsMenuOpen); top.Draw (); TestHelpers.AssertDriverContentsAre (expectedMenu.ExpectedSubMenuOpen (0), output); - Assert.True (menu.NewMouseEvent (new() { Position = new (1, 0), Flags = MouseFlags.Button1Pressed, View = menu })); + Assert.True (menu.NewMouseEvent (new () { Position = new (1, 0), Flags = MouseFlags.Button1Pressed, View = menu })); Assert.False (menu.IsMenuOpen); top.Draw (); TestHelpers.AssertDriverContentsAre (expectedMenu.ClosedMenuText, output); @@ -1985,7 +1983,7 @@ wo top.Remove (menu); // Now test WITH HotKeys - menu = new() + menu = new () { Menus = [ @@ -2114,9 +2112,9 @@ wo { Menus = [ - new() { Title = "Test 1", Action = () => { } }, + new () { Title = "Test 1", Action = () => { } }, - new() { Title = "Test 2", Action = () => { } } + new () { Title = "Test 2", Action = () => { } } ] }; @@ -2204,7 +2202,7 @@ wo // open the menu Assert.True ( menu.NewMouseEvent ( - new() { Position = new (1, 0), Flags = MouseFlags.Button1Pressed, View = menu } + new () { Position = new (1, 0), Flags = MouseFlags.Button1Pressed, View = menu } ) ); Assert.True (menu.IsMenuOpen); @@ -2213,7 +2211,7 @@ wo Assert.True ( mCurrent.NewMouseEvent ( - new() { Position = new (1, 1), Flags = MouseFlags.ReportMousePosition, View = mCurrent } + new () { Position = new (1, 1), Flags = MouseFlags.ReportMousePosition, View = mCurrent } ) ); Assert.True (menu.IsMenuOpen); @@ -2222,7 +2220,7 @@ wo Assert.True ( mCurrent.NewMouseEvent ( - new() { Position = new (1, 1), Flags = MouseFlags.ReportMousePosition, View = mCurrent } + new () { Position = new (1, 1), Flags = MouseFlags.ReportMousePosition, View = mCurrent } ) ); Assert.True (menu.IsMenuOpen); @@ -2231,7 +2229,7 @@ wo Assert.True ( mCurrent.NewMouseEvent ( - new() { Position = new (1, 2), Flags = MouseFlags.ReportMousePosition, View = mCurrent } + new () { Position = new (1, 2), Flags = MouseFlags.ReportMousePosition, View = mCurrent } ) ); Assert.True (menu.IsMenuOpen); @@ -2241,7 +2239,7 @@ wo // close the menu Assert.True ( menu.NewMouseEvent ( - new() { Position = new (1, 0), Flags = MouseFlags.Button1Pressed, View = menu } + new () { Position = new (1, 0), Flags = MouseFlags.Button1Pressed, View = menu } ) ); Assert.False (menu.IsMenuOpen); @@ -2411,7 +2409,7 @@ Edit // Click on Edit Assert.True ( menu.NewMouseEvent ( - new() { Position = new (10, 0), Flags = MouseFlags.Button1Pressed, View = menu } + new () { Position = new (10, 0), Flags = MouseFlags.Button1Pressed, View = menu } ) ); Assert.True (menu.IsMenuOpen); @@ -2421,7 +2419,7 @@ Edit // Click on Paste Assert.True ( mCurrent.NewMouseEvent ( - new() { Position = new (10, 2), Flags = MouseFlags.ReportMousePosition, View = mCurrent } + new () { Position = new (10, 2), Flags = MouseFlags.ReportMousePosition, View = mCurrent } ) ); Assert.True (menu.IsMenuOpen); @@ -2435,7 +2433,7 @@ Edit // Edit menu is open. Click on the menu at Y = -1, which is outside the menu. Assert.False ( mCurrent.NewMouseEvent ( - new() { Position = new (10, i), Flags = MouseFlags.ReportMousePosition, View = menu } + new () { Position = new (10, i), Flags = MouseFlags.ReportMousePosition, View = menu } ) ); } @@ -2444,7 +2442,7 @@ Edit // Edit menu is open. Click on the menu at Y = i. Assert.True ( mCurrent.NewMouseEvent ( - new() { Position = new (10, i), Flags = MouseFlags.ReportMousePosition, View = mCurrent } + new () { Position = new (10, i), Flags = MouseFlags.ReportMousePosition, View = mCurrent } ) ); } @@ -2609,7 +2607,7 @@ Edit Application.Begin (top); Assert.True (tf.HasFocus); - Assert.True (menu.NewMouseEvent (new() { Position = new (1, 0), Flags = MouseFlags.Button1Pressed, View = menu })); + Assert.True (menu.NewMouseEvent (new () { Position = new (1, 0), Flags = MouseFlags.Button1Pressed, View = menu })); Assert.True (menu.IsMenuOpen); Assert.False (tf.HasFocus); top.Draw (); @@ -2617,7 +2615,7 @@ Edit Assert.True ( menu.NewMouseEvent ( - new() { Position = new (8, 0), Flags = MouseFlags.ReportMousePosition, View = menu } + new () { Position = new (8, 0), Flags = MouseFlags.ReportMousePosition, View = menu } ) ); Assert.True (menu.IsMenuOpen); @@ -2627,7 +2625,7 @@ Edit Assert.True ( menu.NewMouseEvent ( - new() { Position = new (15, 0), Flags = MouseFlags.ReportMousePosition, View = menu } + new () { Position = new (15, 0), Flags = MouseFlags.ReportMousePosition, View = menu } ) ); Assert.True (menu.IsMenuOpen); @@ -2637,7 +2635,7 @@ Edit Assert.True ( menu.NewMouseEvent ( - new() { Position = new (8, 0), Flags = MouseFlags.ReportMousePosition, View = menu } + new () { Position = new (8, 0), Flags = MouseFlags.ReportMousePosition, View = menu } ) ); Assert.True (menu.IsMenuOpen); @@ -2647,7 +2645,7 @@ Edit Assert.True ( menu.NewMouseEvent ( - new() { Position = new (1, 0), Flags = MouseFlags.ReportMousePosition, View = menu } + new () { Position = new (1, 0), Flags = MouseFlags.ReportMousePosition, View = menu } ) ); Assert.True (menu.IsMenuOpen); @@ -2655,7 +2653,7 @@ Edit top.Draw (); TestHelpers.AssertDriverContentsAre (expectedMenu.ExpectedSubMenuOpen (0), output); - Assert.True (menu.NewMouseEvent (new() { Position = new (8, 0), Flags = MouseFlags.Button1Pressed, View = menu })); + Assert.True (menu.NewMouseEvent (new () { Position = new (8, 0), Flags = MouseFlags.Button1Pressed, View = menu })); Assert.False (menu.IsMenuOpen); Assert.True (tf.HasFocus); top.Draw (); @@ -2991,7 +2989,7 @@ Edit Assert.True ( menu.NewMouseEvent ( - new() { Position = new (1, 0), Flags = MouseFlags.Button1Pressed, View = menu } + new () { Position = new (1, 0), Flags = MouseFlags.Button1Pressed, View = menu } ) ); top.Draw (); @@ -3010,7 +3008,7 @@ Edit Assert.False ( menu.NewMouseEvent ( - new() + new () { Position = new (1, 2), Flags = MouseFlags.ReportMousePosition, View = Application.Top.Subviews [1] } @@ -3033,7 +3031,7 @@ Edit Assert.False ( menu.NewMouseEvent ( - new() + new () { Position = new (1, 1), Flags = MouseFlags.ReportMousePosition, View = Application.Top.Subviews [1] } @@ -3055,7 +3053,7 @@ Edit Assert.False ( menu.NewMouseEvent ( - new() { Position = new (70, 2), Flags = MouseFlags.Button1Clicked, View = Application.Top } + new () { Position = new (70, 2), Flags = MouseFlags.Button1Clicked, View = Application.Top } ) ); top.Draw (); @@ -3488,7 +3486,7 @@ Edit Assert.True ( menu.NewMouseEvent ( - new() { Position = new (1, 0), Flags = MouseFlags.Button1Pressed, View = menu } + new () { Position = new (1, 0), Flags = MouseFlags.Button1Pressed, View = menu } ) ); top.Draw (); @@ -3505,7 +3503,7 @@ Edit Assert.False ( menu.NewMouseEvent ( - new() { Position = new (1, 2), Flags = MouseFlags.Button1Clicked, View = Application.Top.Subviews [1] } + new () { Position = new (1, 2), Flags = MouseFlags.Button1Clicked, View = Application.Top.Subviews [1] } ) ); top.Draw (); @@ -3523,7 +3521,7 @@ Edit Assert.False ( menu.NewMouseEvent ( - new() { Position = new (1, 1), Flags = MouseFlags.Button1Clicked, View = Application.Top.Subviews [2] } + new () { Position = new (1, 1), Flags = MouseFlags.Button1Clicked, View = Application.Top.Subviews [2] } ) ); top.Draw (); @@ -3540,7 +3538,7 @@ Edit Assert.False ( menu.NewMouseEvent ( - new() { Position = new (70, 2), Flags = MouseFlags.Button1Clicked, View = Application.Top } + new () { Position = new (70, 2), Flags = MouseFlags.Button1Clicked, View = Application.Top } ) ); top.Draw (); @@ -3619,13 +3617,7 @@ Edit public string ExpectedBottomRow (int i) { - return $"{ - CM.Glyphs.LLCorner - }{ - new (CM.Glyphs.HLine.ToString () [0], Menus [i].Children [0].TitleLength + 3) - }{ - CM.Glyphs.LRCorner - } \n"; + return $"{CM.Glyphs.LLCorner}{new (CM.Glyphs.HLine.ToString () [0], Menus [i].Children [0].TitleLength + 3)}{CM.Glyphs.LRCorner} \n"; } // The 3 spaces at end are a result of Menu.cs line 1062 where `pos` is calculated (` + spacesAfterTitle`) @@ -3654,13 +3646,7 @@ Edit // 1 space before the Title and 2 spaces after the Title/Check/Help public string ExpectedTopRow (int i) { - return $"{ - CM.Glyphs.ULCorner - }{ - new (CM.Glyphs.HLine.ToString () [0], Menus [i].Children [0].TitleLength + 3) - }{ - CM.Glyphs.URCorner - } \n"; + return $"{CM.Glyphs.ULCorner}{new (CM.Glyphs.HLine.ToString () [0], Menus [i].Children [0].TitleLength + 3)}{CM.Glyphs.URCorner} \n"; } // Padding for the X of the sub menu Frame diff --git a/UnitTests/Views/ToplevelTests.cs b/UnitTests/Views/ToplevelTests.cs index 2d4a0a323..624da69ac 100644 --- a/UnitTests/Views/ToplevelTests.cs +++ b/UnitTests/Views/ToplevelTests.cs @@ -491,7 +491,7 @@ public partial class ToplevelTests (ITestOutputHelper output) Assert.Equal (tf1W2, top.MostFocused); Assert.True (Application.OnKeyDown (Key.CursorRight)); // move char to right in tf1W2 Assert.Equal (win2, top.Focused); - Assert.Equal (tf1W2, top.MostFocused); + Assert.Equal (tf1W2, top.MostFocused); Assert.True (Application.OnKeyDown (Key.CursorDown)); // move down to next view (tvW2) Assert.Equal (win2, top.Focused); Assert.Equal (tvW2, top.MostFocused); @@ -504,7 +504,7 @@ public partial class ToplevelTests (ITestOutputHelper output) Assert.Equal (win2, top.Focused); Assert.Equal (tvW2, top.MostFocused); tvW2.AllowsTab = false; - Assert.True (Application.OnKeyDown (Key.Tab.WithShift)); + Assert.True (Application.OnKeyDown (Key.Tab.WithShift)); Assert.Equal (win2, top.Focused); Assert.Equal (tf1W2, top.MostFocused); Assert.True (Application.OnKeyDown (Key.CursorLeft)); @@ -563,9 +563,6 @@ public partial class ToplevelTests (ITestOutputHelper output) [Fact] public void Added_Event_Should_Not_Be_Used_To_Initialize_Toplevel_Events () { - Key alternateForwardKey = default; - Key alternateBackwardKey = default; - Key quitKey = default; var wasAdded = false; var view = new View (); @@ -588,7 +585,7 @@ public partial class ToplevelTests (ITestOutputHelper output) Application.Shutdown (); } - + [Fact] [AutoInitShutdown] public void Mouse_Drag_On_Top_With_Superview_Null ()