Fixed nullable warnings 2

This commit is contained in:
Tig
2024-07-24 14:15:32 -06:00
parent 0c56dfeb5a
commit 73a9dc37c4
17 changed files with 154 additions and 174 deletions

View File

@@ -36,7 +36,7 @@ public static partial class Application // Initialization (Init/Shutdown)
/// </param>
[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<Type> drivers = GetDriverTypes ();
Type driverType = drivers.FirstOrDefault (t => t.Name.Equals (ForceDriver, StringComparison.InvariantCultureIgnoreCase));
List<Type?> 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); }
/// <summary>Gets of list of <see cref="ConsoleDriver"/> types that are available.</summary>
/// <returns></returns>
[RequiresUnreferencedCode ("AOT")]
public static List<Type> GetDriverTypes ()
public static List<Type?> GetDriverTypes ()
{
// use reflection to get the list of drivers
List<Type> driverTypes = new ();
List<Type?> 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)
/// <remarks>
/// Intended to support unit tests that need to know when the application has been initialized.
/// </remarks>
public static event EventHandler<EventArgs<bool>> InitializedChanged;
public static event EventHandler<EventArgs<bool>>? InitializedChanged;
}

View File

@@ -98,7 +98,7 @@ public static partial class Application // Keyboard handling
/// <see cref="KeyDown"/> and <see cref="KeyUp"/> events.
/// <para>Fired after <see cref="KeyDown"/> and before <see cref="KeyUp"/>.</para>
/// </remarks>
public static event EventHandler<Key> KeyDown;
public static event EventHandler<Key>? KeyDown;
/// <summary>
/// Called by the <see cref="ConsoleDriver"/> when the user presses a key. Fires the <see cref="KeyDown"/> event
@@ -199,7 +199,7 @@ public static partial class Application // Keyboard handling
/// <see cref="KeyDown"/> and <see cref="KeyUp"/> events.
/// <para>Fired after <see cref="KeyDown"/>.</para>
/// </remarks>
public static event EventHandler<Key> KeyUp;
public static event EventHandler<Key>? KeyUp;
/// <summary>
/// Called by the <see cref="ConsoleDriver"/> when the user releases a key. Fires the <see cref="KeyUp"/> event
@@ -304,7 +304,7 @@ public static partial class Application // Keyboard handling
{
if (OverlappedTop is { })
{
RequestStop (Current);
RequestStop (Current!);
}
else
{

View File

@@ -9,32 +9,32 @@ public static partial class Application // Mouse handling
public static bool IsMouseDisabled { get; set; }
/// <summary>The current <see cref="View"/> object that wants continuous mouse button pressed events.</summary>
public static View WantContinuousButtonPressedView { get; private set; }
public static View? WantContinuousButtonPressedView { get; private set; }
/// <summary>
/// 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 <see cref="UngrabMouse"/> or the mouse is released.
/// </summary>
public static View MouseGrabView { get; private set; }
public static View? MouseGrabView { get; private set; }
/// <summary>Invoked when a view wants to grab the mouse; can be canceled.</summary>
public static event EventHandler<GrabMouseEventArgs> GrabbingMouse;
public static event EventHandler<GrabMouseEventArgs>? GrabbingMouse;
/// <summary>Invoked when a view wants un-grab the mouse; can be canceled.</summary>
public static event EventHandler<GrabMouseEventArgs> UnGrabbingMouse;
public static event EventHandler<GrabMouseEventArgs>? UnGrabbingMouse;
/// <summary>Invoked after a view has grabbed the mouse.</summary>
public static event EventHandler<ViewEventArgs> GrabbedMouse;
public static event EventHandler<ViewEventArgs>? GrabbedMouse;
/// <summary>Invoked after a view has un-grabbed the mouse.</summary>
public static event EventHandler<ViewEventArgs> UnGrabbedMouse;
public static event EventHandler<ViewEventArgs>? UnGrabbedMouse;
/// <summary>
/// Grabs the mouse, forcing all mouse events to be routed to the specified view until <see cref="UngrabMouse"/>
/// is called.
/// </summary>
/// <param name="view">View that will receive all mouse events until <see cref="UngrabMouse"/> is invoked.</param>
public static void GrabMouse (View view)
public static void GrabMouse (View? view)
{
if (view is null)
{

View File

@@ -11,7 +11,7 @@ internal static class ViewNavigation
/// </summary>
/// <param name="view"></param>
/// <returns></returns>
internal static View GetDeepestFocusedSubview (View view)
internal static View? GetDeepestFocusedSubview (View? view)
{
if (view is null)
{
@@ -30,7 +30,7 @@ internal static class ViewNavigation
}
/// <summary>
/// Sets the focus to the next view in the <see cref="TabIndexes"/> list. If the last view is focused, the first view is focused.
/// Sets the focus to the next view in the <see cref="View.TabIndexes"/> list. If the last view is focused, the first view is focused.
/// </summary>
/// <param name="viewsInTabIndexes"></param>
/// <param name="direction"></param>
@@ -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
/// </summary>
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)
{

View File

@@ -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;
/// <summary>
/// Notify that a new <see cref="RunState"/> was created (<see cref="Begin(Toplevel)"/> was called). The token is
@@ -19,7 +19,7 @@ public static partial class Application // Run (Begin, Run, End, Stop)
/// must also subscribe to <see cref="NotifyStopRunState"/> and manually dispose of the <see cref="RunState"/> token
/// when the application is done.
/// </remarks>
public static event EventHandler<RunStateEventArgs> NotifyNewRunState;
public static event EventHandler<RunStateEventArgs>? NotifyNewRunState;
/// <summary>Notify that an existent <see cref="RunState"/> is stopping (<see cref="End(RunState)"/> was called).</summary>
/// <remarks>
@@ -27,7 +27,7 @@ public static partial class Application // Run (Begin, Run, End, Stop)
/// must also subscribe to <see cref="NotifyStopRunState"/> and manually dispose of the <see cref="RunState"/> token
/// when the application is done.
/// </remarks>
public static event EventHandler<ToplevelEventArgs> NotifyStopRunState;
public static event EventHandler<ToplevelEventArgs>? NotifyStopRunState;
/// <summary>Building block API: Prepares the provided <see cref="Toplevel"/> for execution.</summary>
/// <returns>
@@ -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)
/// <returns>The created <see cref="Toplevel"/> object. The caller is responsible for disposing this object.</returns>
[RequiresUnreferencedCode ("AOT")]
[RequiresDynamicCode ("AOT")]
public static Toplevel Run (Func<Exception, bool> errorHandler = null, ConsoleDriver driver = null) { return Run<Toplevel> (errorHandler, driver); }
public static Toplevel Run (Func<Exception, bool>? errorHandler = null, ConsoleDriver? driver = null) { return Run<Toplevel> (errorHandler, driver); }
/// <summary>
/// Runs the application by creating a <see cref="Toplevel"/>-derived object of type <c>T</c> and calling
@@ -331,7 +330,7 @@ public static partial class Application // Run (Begin, Run, End, Stop)
/// <returns>The created T object. The caller is responsible for disposing this object.</returns>
[RequiresUnreferencedCode ("AOT")]
[RequiresDynamicCode ("AOT")]
public static T Run<T> (Func<Exception, bool> errorHandler = null, ConsoleDriver driver = null)
public static T Run<T> (Func<Exception, bool>? 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).
/// </param>
public static void Run (Toplevel view, Func<Exception, bool> errorHandler = null)
public static void Run (Toplevel view, Func<Exception, bool>? 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 <see cref="RemoveTimeout(object)"/>.
/// </remarks>
public static object AddTimeout (TimeSpan time, Func<bool> callback) { return MainLoop?.AddTimeout (time, callback); }
public static object AddTimeout (TimeSpan time, Func<bool> callback) { return MainLoop!.AddTimeout (time, callback); }
/// <summary>Removes a previously scheduled timeout</summary>
/// <remarks>The token parameter is the value returned by <see cref="AddTimeout"/>.</remarks>
@@ -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)
/// <summary>This event is raised on each iteration of the main loop.</summary>
/// <remarks>See also <see cref="Timeout"/></remarks>
public static event EventHandler<IterationEventArgs> Iteration;
public static event EventHandler<IterationEventArgs>? Iteration;
/// <summary>The <see cref="MainLoop"/> driver for the application</summary>
/// <value>The main loop.</value>
internal static MainLoop MainLoop { get; private set; }
internal static MainLoop? MainLoop { get; private set; }
/// <summary>
/// Set to true to cause <see cref="End"/> 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 <see cref="Toplevel"/> to false.
/// </para>
/// </remarks>
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)

View File

@@ -10,7 +10,7 @@ public static partial class Application // Toplevel handling
/// <summary>The <see cref="Toplevel"/> object used for the application on startup (<seealso cref="Top"/>)</summary>
/// <value>The top.</value>
public static Toplevel Top { get; private set; }
public static Toplevel? Top { get; private set; }
// TODO: Determine why this can't just return _topLevels.Peek()?
/// <summary>
@@ -22,7 +22,7 @@ public static partial class Application // Toplevel handling
/// This will only be distinct from <see cref="Application.Top"/> in scenarios where <see cref="Toplevel.IsOverlappedContainer"/> is <see langword="true"/>.
/// </remarks>
/// <value>The current.</value>
public static Toplevel Current { get; private set; }
public static Toplevel? Current { get; private set; }
/// <summary>
/// If <paramref name="topLevel"/> 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 <see cref="SizeChangedEventArgs.Cancel"/> to <see langword="true"/> to prevent
/// <see cref="Application"/> from changing it's size to match the new terminal size.
/// </remarks>
public static event EventHandler<SizeChangedEventArgs> SizeChanging;
public static event EventHandler<SizeChangedEventArgs>? SizeChanging;
/// <summary>
/// Called when the application's size changes. Sets the size of all <see cref="Toplevel"/>s and fires the

View File

@@ -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?
/// <summary>Gets the location and size of the terminal screen.</summary>
@@ -443,7 +444,7 @@ public abstract class ConsoleDriver
public abstract bool SetCursorVisibility (CursorVisibility visibility);
/// <summary>The event fired when the terminal is resized.</summary>
public event EventHandler<SizeChangedEventArgs> SizeChanged;
public event EventHandler<SizeChangedEventArgs>? SizeChanged;
/// <summary>Suspends the application (e.g. on Linux via SIGTSTP) and upon resume, resets the console driver.</summary>
/// <remarks>This is only implemented in <see cref="CursesDriver"/>.</remarks>

View File

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

View File

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

View File

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

View File

@@ -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; }
/// <inheritdoc/>
public override int GetHashCode () { return Target.GetHashCode (); }
public override int GetHashCode () { return Target!.GetHashCode (); }
/// <summary>
/// Gets the View the dimension is anchored to.

View File

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

View File

@@ -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; }
/// <inheritdoc/>
public override int GetHashCode () { return Target.GetHashCode (); }
public override int GetHashCode () { return Target!.GetHashCode (); }
/// <inheritdoc/>
public override string ToString ()

View File

@@ -1594,7 +1594,7 @@ public class MenuBar : View, IDesignable
/// <inheritdoc />
public bool EnableForDesign<TContext> (in TContext context) where TContext : notnull
public bool EnableForDesign<TContext> (ref readonly TContext context) where TContext : notnull
{
if (context is not Func<string, bool> actionFn)
{

View File

@@ -715,7 +715,7 @@ internal class UICatalogApp
}
ColorScheme = Colors.ColorSchemes [_topLevelColorScheme];
Application.Top.SetNeedsDisplay ();
Application.Top!.SetNeedsDisplay ();
};
schemeMenuItems.Add (item);
}

View File

@@ -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<DimFill> (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<object, bool> (s =>
{
miAction = s as string;
var menu = new MenuBar ();
return true;
})
);
Func<object, bool> 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<object, bool> (s =>
{
miAction = s as string;
var menu = new MenuBar ();
return true;
})
);
menu.EnableForDesign (
new Func<object, bool> (
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

View File

@@ -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 ()