diff --git a/Terminal.Gui/Application/Application.Driver.cs b/Terminal.Gui/Application/Application.Driver.cs
index c2f6431db..cdfd51ec5 100644
--- a/Terminal.Gui/Application/Application.Driver.cs
+++ b/Terminal.Gui/Application/Application.Driver.cs
@@ -8,6 +8,7 @@ public static partial class Application // Driver abstractions
/// Gets the that has been selected. See also .
public static ConsoleDriver? Driver { get; internal set; }
+ // BUGBUG: Force16Colors should be nullable.
///
/// Gets or sets whether will be forced to output only the 16 colors defined in
/// . The default is , meaning 24-bit (TrueColor) colors will be output
@@ -16,6 +17,7 @@ public static partial class Application // Driver abstractions
[SerializableConfigurationProperty (Scope = typeof (SettingsScope))]
public static bool Force16Colors { get; set; }
+ // BUGBUG: ForceDriver should be nullable.
///
/// Forces the use of the specified driver (one of "fake", "ansi", "curses", "net", or "windows"). If not
/// specified, the driver is selected based on the platform.
diff --git a/Terminal.Gui/Application/Application.Keyboard.cs b/Terminal.Gui/Application/Application.Keyboard.cs
index 18881d6c5..97b566166 100644
--- a/Terminal.Gui/Application/Application.Keyboard.cs
+++ b/Terminal.Gui/Application/Application.Keyboard.cs
@@ -49,6 +49,11 @@ public static partial class Application // Keyboard handling
{
if (binding.Value.BoundView is { })
{
+ if (!binding.Value.BoundView.Enabled)
+ {
+ return false;
+ }
+
bool? handled = binding.Value.BoundView?.InvokeCommands (binding.Value.Commands, binding.Key, binding.Value);
if (handled != null && (bool)handled)
diff --git a/Terminal.Gui/Drawing/Glyphs.cs b/Terminal.Gui/Drawing/Glyphs.cs
index c3b72711f..f3a0334bf 100644
--- a/Terminal.Gui/Drawing/Glyphs.cs
+++ b/Terminal.Gui/Drawing/Glyphs.cs
@@ -20,6 +20,11 @@
///
public class GlyphDefinitions
{
+ // IMPORTANT: If you change these, make sure to update the ./Resources/config.json file as
+ // IMPORTANT: it is the source of truth for the default glyphs at runtime.
+ // IMPORTANT: Configuration Manager test SaveDefaults uses this class to generate the default config file
+ // IMPORTANT: in ./UnitTests/bin/Debug/netX.0/config.json
+
/// File icon. Defaults to ☰ (Trigram For Heaven)
public Rune File { get; set; } = (Rune)'☰';
diff --git a/Terminal.Gui/Input/KeyBindings.cs b/Terminal.Gui/Input/KeyBindings.cs
index 59a97bfd6..71777d804 100644
--- a/Terminal.Gui/Input/KeyBindings.cs
+++ b/Terminal.Gui/Input/KeyBindings.cs
@@ -1,5 +1,7 @@
#nullable enable
+using static System.Formats.Asn1.AsnWriter;
+
namespace Terminal.Gui;
///
@@ -17,7 +19,7 @@ public class KeyBindings
public KeyBindings () { }
/// Initializes a new instance bound to .
- public KeyBindings (View boundView) { BoundView = boundView; }
+ public KeyBindings (View? boundView) { BoundView = boundView; }
/// Adds a to the collection.
///
@@ -27,7 +29,12 @@ public class KeyBindings
{
if (BoundView is { } && binding.Scope.FastHasFlags (KeyBindingScope.Application))
{
- throw new ArgumentException ("Application scoped KeyBindings must be added via Application.KeyBindings.Add");
+ throw new InvalidOperationException ("Application scoped KeyBindings must be added via Application.KeyBindings.Add");
+ }
+
+ if (BoundView is { } && boundViewForAppScope is null)
+ {
+ boundViewForAppScope = BoundView;
}
if (TryGet (key, out KeyBinding _))
@@ -78,6 +85,10 @@ public class KeyBindings
{
throw new ArgumentException ("Application scoped KeyBindings must be added via Application.KeyBindings.Add");
}
+ else
+ {
+ // boundViewForAppScope = BoundView;
+ }
if (key is null || !key.IsValid)
{
@@ -93,11 +104,9 @@ public class KeyBindings
if (TryGet (key, out KeyBinding binding))
{
throw new InvalidOperationException (@$"A key binding for {key} exists ({binding}).");
-
- //Bindings [key] = new (commands, scope, BoundView);
}
- Add (key, new KeyBinding (commands, scope, BoundView), boundViewForAppScope);
+ Add (key, new KeyBinding (commands, scope, boundViewForAppScope), boundViewForAppScope);
}
///
@@ -120,9 +129,14 @@ public class KeyBindings
///
public void Add (Key key, KeyBindingScope scope, params Command [] commands)
{
+ if (BoundView is null && !scope.FastHasFlags (KeyBindingScope.Application))
+ {
+ throw new InvalidOperationException ("BoundView cannot be null.");
+ }
+
if (BoundView is { } && scope.FastHasFlags (KeyBindingScope.Application))
{
- throw new ArgumentException ("Application scoped KeyBindings must be added via Application.KeyBindings.Add");
+ throw new InvalidOperationException ("Application scoped KeyBindings must be added via Application.KeyBindings.Add");
}
if (key == Key.Empty || !key.IsValid)
@@ -140,7 +154,7 @@ public class KeyBindings
throw new InvalidOperationException (@$"A key binding for {key} exists ({binding}).");
}
- Add (key, new KeyBinding (commands, scope, BoundView));
+ Add (key, new KeyBinding (commands, scope, BoundView), BoundView);
}
///
@@ -219,14 +233,22 @@ public class KeyBindings
/// The collection of objects.
public Dictionary Bindings { get; } = new (new KeyEqualityComparer ());
+ ///
+ /// Gets the keys that are bound.
+ ///
+ ///
+ public IEnumerable GetBoundKeys ()
+ {
+ return Bindings.Keys;
+ }
+
///
/// The view that the are bound to.
///
///
- /// If , the are not bound to a . This is used for
- /// Application.KeyBindings.
+ /// If the KeyBindings object is being used for Application.KeyBindings.
///
- public View? BoundView { get; }
+ internal View? BoundView { get; }
/// Removes all objects from the collection.
public void Clear () { Bindings.Clear (); }
@@ -312,7 +334,7 @@ public class KeyBindings
/// Optional View for bindings.
public void Remove (Key key, View? boundViewForAppScope = null)
{
- if (!TryGet (key, out KeyBinding binding))
+ if (!TryGet (key, out KeyBinding _))
{
return;
}
@@ -371,6 +393,11 @@ public class KeyBindings
/// if the Key is bound; otherwise .
public bool TryGet (Key key, out KeyBinding binding)
{
+ //if (BoundView is null)
+ //{
+ // throw new InvalidOperationException ("KeyBindings must be bound to a View to use this method.");
+ //}
+
binding = new (Array.Empty (), KeyBindingScope.Disabled, null);
if (key.IsValid)
@@ -394,6 +421,11 @@ public class KeyBindings
{
if (!key.IsValid)
{
+ //if (BoundView is null)
+ //{
+ // throw new InvalidOperationException ("KeyBindings must be bound to a View to use this method.");
+ //}
+
binding = new (Array.Empty (), KeyBindingScope.Disabled, null);
return false;
}
diff --git a/Terminal.Gui/Resources/config.json b/Terminal.Gui/Resources/config.json
index 07ba33650..ca6ab6a84 100644
--- a/Terminal.Gui/Resources/config.json
+++ b/Terminal.Gui/Resources/config.json
@@ -16,14 +16,173 @@
// to throw exceptions.
"ConfigurationManager.ThrowOnJsonErrors": false,
- "Application.NextTabKey": "Tab",
- "Application.PrevTabKey": "Shift+Tab",
- "Application.NextTabGroupKey": "F6",
- "Application.PrevTabGroupKey": "Shift+F6",
- "Application.QuitKey": "Esc",
- "Application.ArrangeKey": "Ctrl+F5",
+ // --------------- Application Settings ---------------
"Key.Separator": "+",
+ "Application.ArrangeKey": "Ctrl+F5",
+ "Application.Force16Colors": false,
+ //"Application.ForceDriver": "", // TODO: ForceDriver should be nullable
+ "Application.IsMouseDisabled": false,
+ "Application.NextTabGroupKey": "F6",
+ "Application.NextTabKey": "Tab",
+ "Application.PrevTabGroupKey": "Shift+F6",
+ "Application.PrevTabKey": "Shift+Tab",
+ "Application.QuitKey": "Esc",
+
+ // --------------- Colors ---------------
+
+
+ // --------------- View Specific Settings ---------------
+ "ContextMenu.DefaultKey": "Shift+F10",
+ "FileDialog.MaxSearchResults": 10000,
+ "FileDialogStyle.DefaultUseColors": false,
+ "FileDialogStyle.DefaultUseUnicodeCharacters": false,
+
+ // --------------- Glyphs ---------------
+ "Glyphs": {
+ "File": "☰",
+ "Folder": "꤉",
+ "HorizontalEllipsis": "…",
+ "VerticalFourDots": "⁞",
+ "CheckStateChecked": "☑",
+ "CheckStateUnChecked": "☐",
+ "CheckStateNone": "☒",
+ "Selected": "◉",
+ "UnSelected": "○",
+ "RightArrow": "►",
+ "LeftArrow": "◄",
+ "DownArrow": "▼",
+ "UpArrow": "▲",
+ "LeftDefaultIndicator": "►",
+ "RightDefaultIndicator": "◄",
+ "LeftBracket": "⟦",
+ "RightBracket": "⟧",
+ "BlocksMeterSegment": "▌",
+ "ContinuousMeterSegment": "█",
+ "Stipple": "░",
+ "Diamond": "◊",
+ "Close": "✘",
+ "Minimize": "❏",
+ "Maximize": "✽",
+ "Dot": "∙",
+ "BlackCircle": "●",
+ "Expand": "+",
+ "Collapse": "-",
+ "IdenticalTo": "≡",
+ "Move": "◊",
+ "SizeHorizontal": "↔",
+ "SizeVertical": "↕",
+ "SizeTopLeft": "↖",
+ "SizeTopRight": "↗",
+ "SizeBottomRight": "↘",
+ "SizeBottomLeft": "↙",
+ "Apple": "\uD83C\uDF4E",
+ "AppleBMP": "❦",
+ "HLine": "─",
+ "VLine": "│",
+ "HLineDbl": "═",
+ "VLineDbl": "║",
+ "HLineHvDa2": "╍",
+ "VLineHvDa3": "┇",
+ "HLineHvDa3": "┅",
+ "HLineHvDa4": "┉",
+ "VLineHvDa2": "╏",
+ "VLineHvDa4": "┋",
+ "HLineDa2": "╌",
+ "VLineDa3": "┆",
+ "HLineDa3": "┄",
+ "HLineDa4": "┈",
+ "VLineDa2": "╎",
+ "VLineDa4": "┊",
+ "HLineHv": "━",
+ "VLineHv": "┃",
+ "HalfLeftLine": "╴",
+ "HalfTopLine": "╵",
+ "HalfRightLine": "╶",
+ "HalfBottomLine": "╷",
+ "HalfLeftLineHv": "╸",
+ "HalfTopLineHv": "╹",
+ "HalfRightLineHv": "╺",
+ "HalfBottomLineLt": "╻",
+ "RightSideLineLtHv": "╼",
+ "BottomSideLineLtHv": "╽",
+ "LeftSideLineHvLt": "╾",
+ "TopSideLineHvLt": "╿",
+ "ULCorner": "┌",
+ "ULCornerDbl": "╔",
+ "ULCornerR": "╭",
+ "ULCornerHv": "┏",
+ "ULCornerHvLt": "┎",
+ "ULCornerLtHv": "┍",
+ "ULCornerDblSingle": "╓",
+ "ULCornerSingleDbl": "╒",
+ "LLCorner": "└",
+ "LLCornerHv": "┗",
+ "LLCornerHvLt": "┖",
+ "LLCornerLtHv": "┕",
+ "LLCornerDbl": "╚",
+ "LLCornerSingleDbl": "╘",
+ "LLCornerDblSingle": "╙",
+ "LLCornerR": "╰",
+ "URCorner": "┐",
+ "URCornerDbl": "╗",
+ "URCornerR": "╮",
+ "URCornerHv": "┓",
+ "URCornerHvLt": "┑",
+ "URCornerLtHv": "┒",
+ "URCornerDblSingle": "╖",
+ "URCornerSingleDbl": "╕",
+ "LRCorner": "┘",
+ "LRCornerDbl": "╝",
+ "LRCornerR": "╯",
+ "LRCornerHv": "┛",
+ "LRCornerDblSingle": "╜",
+ "LRCornerSingleDbl": "╛",
+ "LRCornerLtHv": "┙",
+ "LRCornerHvLt": "┚",
+ "LeftTee": "├",
+ "LeftTeeDblH": "╞",
+ "LeftTeeDblV": "╟",
+ "LeftTeeDbl": "╠",
+ "LeftTeeHvH": "┝",
+ "LeftTeeHvV": "┠",
+ "LeftTeeHvDblH": "┣",
+ "RightTee": "┤",
+ "RightTeeDblH": "╡",
+ "RightTeeDblV": "╢",
+ "RightTeeDbl": "╣",
+ "RightTeeHvH": "┥",
+ "RightTeeHvV": "┨",
+ "RightTeeHvDblH": "┫",
+ "TopTee": "┬",
+ "TopTeeDblH": "╤",
+ "TopTeeDblV": "╥",
+ "TopTeeDbl": "╦",
+ "TopTeeHvH": "┯",
+ "TopTeeHvV": "┰",
+ "TopTeeHvDblH": "┳",
+ "BottomTee": "┴",
+ "BottomTeeDblH": "╧",
+ "BottomTeeDblV": "╨",
+ "BottomTeeDbl": "╩",
+ "BottomTeeHvH": "┷",
+ "BottomTeeHvV": "┸",
+ "BottomTeeHvDblH": "┻",
+ "Cross": "┼",
+ "CrossDblH": "╪",
+ "CrossDblV": "╫",
+ "CrossDbl": "╬",
+ "CrossHvH": "┿",
+ "CrossHvV": "╂",
+ "CrossHv": "╋",
+ "ShadowVerticalStart": "▖",
+ "ShadowVertical": "▌",
+ "ShadowHorizontalStart": "▝",
+ "ShadowHorizontal": "▀",
+ "ShadowHorizontalEnd": "▘"
+ },
+
+ // --------------- Themes -----------------
"Theme": "Default",
"Themes": [
{
diff --git a/Terminal.Gui/View/Layout/DimAuto.cs b/Terminal.Gui/View/Layout/DimAuto.cs
index 2d7f04479..8f5716b1e 100644
--- a/Terminal.Gui/View/Layout/DimAuto.cs
+++ b/Terminal.Gui/View/Layout/DimAuto.cs
@@ -35,7 +35,7 @@ public record DimAuto (Dim? MaximumContentDim, Dim? MinimumContentDim, DimAutoSt
int screenX4 = dimension == Dimension.Width ? Application.Screen.Width * 4 : Application.Screen.Height * 4;
int autoMax = MaximumContentDim?.GetAnchor (superviewContentSize) ?? screenX4;
- Debug.Assert (autoMin <= autoMax, "MinimumContentDim must be less than or equal to MaximumContentDim.");
+ Debug.WriteLineIf (autoMin > autoMax, "MinimumContentDim must be less than or equal to MaximumContentDim.");
if (Style.FastHasFlags (DimAutoStyle.Text))
{
diff --git a/Terminal.Gui/View/View.Drawing.cs b/Terminal.Gui/View/View.Drawing.cs
index 79ab737f7..f571893a2 100644
--- a/Terminal.Gui/View/View.Drawing.cs
+++ b/Terminal.Gui/View/View.Drawing.cs
@@ -55,6 +55,7 @@ public partial class View // Drawing APIs
// Draw the Border and Padding.
// We clip to the frame to prevent drawing outside the frame.
saved = ClipFrame ();
+
DoDrawBorderAndPadding ();
SetClip (saved);
@@ -71,7 +72,7 @@ public partial class View // Drawing APIs
DoSetAttribute ();
DoClearViewport ();
- // Draw the subviews
+ // Draw the subviews only if needed
if (SubViewNeedsDraw)
{
DoSetAttribute ();
@@ -166,6 +167,13 @@ public partial class View // Drawing APIs
private void DoDrawBorderAndPadding ()
{
+ if (SubViewNeedsDraw)
+ {
+ // A Subview may add to the LineCanvas. This ensures any Adornment LineCanvas updates happen.
+ Border?.SetNeedsDraw ();
+ Padding?.SetNeedsDraw ();
+ }
+
if (OnDrawingBorderAndPadding ())
{
return;
diff --git a/Terminal.Gui/View/View.Hierarchy.cs b/Terminal.Gui/View/View.Hierarchy.cs
index 4f9b089a1..5a0705ada 100644
--- a/Terminal.Gui/View/View.Hierarchy.cs
+++ b/Terminal.Gui/View/View.Hierarchy.cs
@@ -256,6 +256,67 @@ public partial class View // SuperView/SubView hierarchy management (SuperView,
return top;
}
+ ///
+ /// Gets whether is in the Subview hierarchy of .
+ ///
+ /// The View at the start of the hierarchy.
+ /// The View to test.
+ /// Will search the subview hierarchy of the adornments if true.
+ ///
+ public static bool IsInHierarchy (View? start, View? view, bool includeAdornments = false)
+ {
+ if (view is null || start is null)
+ {
+ return false;
+ }
+
+ if (view == start)
+ {
+ return true;
+ }
+
+ foreach (View subView in start.Subviews)
+ {
+ if (view == subView)
+ {
+ return true;
+ }
+
+ bool found = IsInHierarchy (subView, view, includeAdornments);
+
+ if (found)
+ {
+ return found;
+ }
+ }
+
+ if (includeAdornments)
+ {
+ bool found = IsInHierarchy (start.Padding, view, includeAdornments);
+
+ if (found)
+ {
+ return found;
+ }
+
+ found = IsInHierarchy (start.Border, view, includeAdornments);
+
+ if (found)
+ {
+ return found;
+ }
+
+ found = IsInHierarchy (start.Margin, view, includeAdornments);
+
+ if (found)
+ {
+ return found;
+ }
+ }
+
+ return false;
+ }
+
#region SubViewOrdering
///
diff --git a/Terminal.Gui/View/View.Keyboard.cs b/Terminal.Gui/View/View.Keyboard.cs
index 87c5a1ce6..642c34635 100644
--- a/Terminal.Gui/View/View.Keyboard.cs
+++ b/Terminal.Gui/View/View.Keyboard.cs
@@ -690,7 +690,7 @@ public partial class View // Keyboard APIs
#if DEBUG
- if (Application.KeyBindings.TryGet (key, KeyBindingScope.Focused | KeyBindingScope.HotKey, out KeyBinding b))
+ if (Application.KeyBindings.TryGet (key, out KeyBinding b))
{
Debug.WriteLine (
$"WARNING: InvokeKeyBindings ({key}) - An Application scope binding exists for this key. The registered view will not invoke Command.");
diff --git a/Terminal.Gui/View/View.Navigation.cs b/Terminal.Gui/View/View.Navigation.cs
index cbd2963c4..6799edb9d 100644
--- a/Terminal.Gui/View/View.Navigation.cs
+++ b/Terminal.Gui/View/View.Navigation.cs
@@ -357,6 +357,7 @@ public partial class View // Focus and cross-view navigation management (TabStop
///
internal bool RestoreFocus ()
{
+ // Ignore TabStop
View [] indicies = GetFocusChain (NavigationDirection.Forward, null);
if (Focused is null && _previouslyFocused is { } && indicies.Contains (_previouslyFocused))
@@ -495,7 +496,7 @@ public partial class View // Focus and cross-view navigation management (TabStop
///
private (bool focusSet, bool cancelled) SetHasFocusTrue (View? currentFocusedView, bool traversingUp = false)
{
- Debug.Assert (SuperView is null || ApplicationNavigation.IsInHierarchy (SuperView, this));
+ Debug.Assert (SuperView is null || View.IsInHierarchy (SuperView, this));
// Pre-conditions
if (_hasFocus)
diff --git a/Terminal.Gui/Views/Bar.cs b/Terminal.Gui/Views/Bar.cs
index bece84078..05bcc1101 100644
--- a/Terminal.Gui/Views/Bar.cs
+++ b/Terminal.Gui/Views/Bar.cs
@@ -20,7 +20,7 @@ public class Bar : View, IOrientation, IDesignable
public Bar () : this ([]) { }
///
- public Bar (IEnumerable shortcuts)
+ public Bar (IEnumerable? shortcuts)
{
CanFocus = true;
@@ -28,20 +28,16 @@ public class Bar : View, IOrientation, IDesignable
Height = Dim.Auto ();
_orientationHelper = new (this);
- _orientationHelper.OrientationChanging += (sender, e) => OrientationChanging?.Invoke (this, e);
- _orientationHelper.OrientationChanged += (sender, e) => OrientationChanged?.Invoke (this, e);
// Initialized += Bar_Initialized;
MouseEvent += OnMouseEvent;
- if (shortcuts is null)
+ if (shortcuts is { })
{
- return;
- }
-
- foreach (Shortcut shortcut in shortcuts)
- {
- Add (shortcut);
+ foreach (Shortcut shortcut in shortcuts)
+ {
+ Add (shortcut);
+ }
}
}
@@ -243,7 +239,6 @@ public class Bar : View, IOrientation, IDesignable
{
View barItem = Subviews [index];
- barItem.X = 0;
barItem.ColorScheme = ColorScheme;
@@ -254,6 +249,7 @@ public class Bar : View, IOrientation, IDesignable
if (barItem is Shortcut scBarItem)
{
+ barItem.X = 0;
scBarItem.MinimumKeyTextSize = minKeyWidth;
scBarItem.Width = scBarItem.GetWidthDimAuto ();
barItem.Layout (Application.Screen.Size);
@@ -278,14 +274,20 @@ public class Bar : View, IOrientation, IDesignable
foreach (var subView in Subviews)
{
- subView.Width = Dim.Auto (DimAutoStyle.Auto, minimumContentDim: _maxBarItemWidth);
+ if (subView is not Line)
+ {
+ subView.Width = Dim.Auto (DimAutoStyle.Auto, minimumContentDim: _maxBarItemWidth);
+ }
}
}
else
{
foreach (var subView in Subviews)
{
- subView.Width = Dim.Fill();
+ if (subView is not Line)
+ {
+ subView.Width = Dim.Fill ();
+ }
}
}
diff --git a/Terminal.Gui/Views/Line.cs b/Terminal.Gui/Views/Line.cs
index 82b7499e1..9d2889373 100644
--- a/Terminal.Gui/Views/Line.cs
+++ b/Terminal.Gui/Views/Line.cs
@@ -1,6 +1,10 @@
namespace Terminal.Gui;
-/// Draws a single line using the specified by .
+///
+/// Draws a single line using the specified by .
+///
+///
+///
public class Line : View, IOrientation
{
private readonly OrientationHelper _orientationHelper;
@@ -8,14 +12,13 @@ public class Line : View, IOrientation
/// Constructs a Line object.
public Line ()
{
- BorderStyle = LineStyle.Single;
- Border.Thickness = new Thickness (0);
- SuperViewRendersLineCanvas = true;
+ CanFocus = false;
+
+ base.SuperViewRendersLineCanvas = true;
_orientationHelper = new (this);
_orientationHelper.Orientation = Orientation.Horizontal;
- _orientationHelper.OrientationChanging += (sender, e) => OrientationChanging?.Invoke (this, e);
- _orientationHelper.OrientationChanged += (sender, e) => OrientationChanged?.Invoke (this, e);
+ OnOrientationChanged(Orientation);
}
@@ -45,10 +48,12 @@ public class Line : View, IOrientation
{
case Orientation.Horizontal:
Height = 1;
+ Width = Dim.Fill ();
break;
case Orientation.Vertical:
Width = 1;
+ Height = Dim.Fill ();
break;
@@ -56,48 +61,20 @@ public class Line : View, IOrientation
}
#endregion
- ///
- public override void SetBorderStyle (LineStyle value)
- {
- // The default changes the thickness. We don't want that. We just set the style.
- Border.LineStyle = value;
- }
-
///
protected override bool OnDrawingContent ()
{
- LineCanvas lc = LineCanvas;
-
- if (SuperViewRendersLineCanvas)
- {
- lc = SuperView?.LineCanvas;
- }
-
- if (SuperView is Adornment adornment)
- {
- lc = adornment.Parent?.LineCanvas;
- }
-
Point pos = ViewportToScreen (Viewport).Location;
int length = Orientation == Orientation.Horizontal ? Frame.Width : Frame.Height;
- if (SuperView is {} && SuperViewRendersLineCanvas && Orientation == Orientation.Horizontal)
- {
- pos.Offset (-SuperView.Border.Thickness.Left, 0);
- length += SuperView.Border.Thickness.Horizontal;
- }
-
- if (SuperView is { } && SuperViewRendersLineCanvas && Orientation == Orientation.Vertical)
- {
- pos.Offset (0, -SuperView.Border.Thickness.Top);
- length += SuperView.Border.Thickness.Vertical;
- }
- lc?.AddLine (
+ LineCanvas?.AddLine (
pos,
length,
Orientation,
BorderStyle
);
+
+ //SuperView?.SetNeedsDraw ();
return true;
}
}
diff --git a/Terminal.Gui/Views/Shortcut.cs b/Terminal.Gui/Views/Shortcut.cs
index 175f8f569..f10bb423b 100644
--- a/Terminal.Gui/Views/Shortcut.cs
+++ b/Terminal.Gui/Views/Shortcut.cs
@@ -67,7 +67,7 @@ public class Shortcut : View, IOrientation, IDesignable
///
/// The text to display for the command.
/// The help text to display.
- public Shortcut (View targetView, Command command, string commandText, string helpText)
+ public Shortcut (View targetView, Command command, string commandText, string? helpText = null)
: this (
targetView?.KeyBindings.GetKeyFromCommands (command)!,
commandText,
@@ -75,7 +75,7 @@ public class Shortcut : View, IOrientation, IDesignable
helpText)
{
_targetView = targetView;
- _command = command;
+ Command = command;
}
///
@@ -92,7 +92,7 @@ public class Shortcut : View, IOrientation, IDesignable
/// The help text to display.
public Shortcut (Key key, string? commandText, Action? action, string? helpText = null)
{
- Id = "_shortcut";
+ Id = $"shortcut:{commandText}";
HighlightStyle = HighlightStyle.None;
CanFocus = true;
@@ -280,7 +280,15 @@ public class Shortcut : View, IOrientation, IDesignable
private readonly View? _targetView; // If set, _command will be invoked
- private readonly Command _command; // Used when _targetView is set
+ ///
+ /// Gets the target that the will be invoked on.
+ ///
+ public View? TargetView => _targetView;
+
+ ///
+ /// Gets the that will be invoked on when the Shortcut is activated.
+ ///
+ public Command Command { get; }
private void AddCommands ()
{
@@ -319,6 +327,11 @@ public class Shortcut : View, IOrientation, IDesignable
return true;
}
+ if (ctx.Command != Command.Accept)
+ {
+ // return false;
+ }
+
if (Action is { })
{
Action.Invoke ();
@@ -329,7 +342,7 @@ public class Shortcut : View, IOrientation, IDesignable
if (_targetView is { })
{
- _targetView.InvokeCommand (_command);
+ _targetView.InvokeCommand (Command);
}
return cancel;
@@ -616,7 +629,7 @@ public class Shortcut : View, IOrientation, IDesignable
if (_keyBindingScope == KeyBindingScope.Application)
{
- Application.KeyBindings.Remove (Key);
+ Application.KeyBindings.Remove (Key, this);
}
if (_keyBindingScope is KeyBindingScope.HotKey or KeyBindingScope.Focused)
@@ -691,10 +704,10 @@ public class Shortcut : View, IOrientation, IDesignable
{
if (oldKey != Key.Empty)
{
- Application.KeyBindings.Remove (oldKey);
+ Application.KeyBindings.Remove (oldKey, this);
}
- Application.KeyBindings.Remove (Key);
+ Application.KeyBindings.Remove (Key, this);
Application.KeyBindings.Add (Key, this, Command.HotKey);
}
else
diff --git a/UICatalog/Scenarios/KeyBindings.cs b/UICatalog/Scenarios/KeyBindings.cs
index afb69ec4e..2b5de89ac 100644
--- a/UICatalog/Scenarios/KeyBindings.cs
+++ b/UICatalog/Scenarios/KeyBindings.cs
@@ -80,10 +80,10 @@ public sealed class KeyBindings : Scenario
};
appWindow.Add (appBindingsListView);
- foreach (var appBinding in Application.KeyBindings.Bindings)
+ foreach (var key in Application.KeyBindings.GetBoundKeys())
{
- var commands = Application.KeyBindings.GetCommands (appBinding.Key);
- appBindings.Add ($"{appBinding.Key} -> {appBinding.Value.BoundView?.GetType ().Name} - {commands [0]}");
+ var binding = Application.KeyBindings.Get (key);
+ appBindings.Add ($"{key} -> {binding.BoundView?.GetType ().Name} - {binding.Commands [0]}");
}
ObservableCollection hotkeyBindings = new ();
diff --git a/UICatalog/Scenarios/Shortcuts.cs b/UICatalog/Scenarios/Shortcuts.cs
index e1d1f171b..5390e015d 100644
--- a/UICatalog/Scenarios/Shortcuts.cs
+++ b/UICatalog/Scenarios/Shortcuts.cs
@@ -1,11 +1,9 @@
+#nullable enable
+
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
-using System.ComponentModel;
-using System.Diagnostics;
using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
using System.Timers;
using Terminal.Gui;
@@ -29,10 +27,10 @@ public class Shortcuts : Scenario
// Setting everything up in Loaded handler because we change the
// QuitKey and it only sticks if changed after init
- private void App_Loaded (object sender, EventArgs e)
+ private void App_Loaded (object? sender, EventArgs e)
{
Application.QuitKey = Key.F4.WithCtrl;
- Application.Top.Title = GetQuitKeyAndName ();
+ Application.Top!.Title = GetQuitKeyAndName ();
ObservableCollection eventSource = new ();
@@ -47,7 +45,8 @@ public class Shortcuts : Scenario
BorderStyle = LineStyle.Double,
Title = "E_vents"
};
- eventLog.Width = Dim.Func (() => Math.Min (eventLog.SuperView!.Viewport.Width / 2, eventLog?.MaxLength + eventLog.GetAdornmentsThickness ().Horizontal ?? 0));
+ eventLog.Width = Dim.Func (() => Math.Min (Application.Top.Viewport.Width / 2, eventLog?.MaxLength + eventLog!.GetAdornmentsThickness ().Horizontal ?? 0));
+ eventLog.Width = Dim.Func (() => Math.Min (eventLog.SuperView!.Viewport.Width / 2, eventLog?.MaxLength + eventLog!.GetAdornmentsThickness ().Horizontal ?? 0));
Application.Top.Add (eventLog);
var alignKeysShortcut = new Shortcut
@@ -55,7 +54,7 @@ public class Shortcuts : Scenario
Id = "alignKeysShortcut",
X = 0,
Y = 0,
- Width = Dim.Fill () - Dim.Width (eventLog),
+ Width = Dim.Fill ()! - Dim.Width (eventLog),
HelpText = "Fill to log",
CommandView = new CheckBox
{
@@ -67,6 +66,7 @@ public class Shortcuts : Scenario
KeyBindingScope = KeyBindingScope.HotKey,
};
+ // ((CheckBox)vShortcut3.CommandView).CheckedStateChanging += (_, args) =>
((CheckBox)alignKeysShortcut.CommandView).CheckedStateChanging += (s, e) =>
{
if (alignKeysShortcut.CommandView is CheckBox cb)
@@ -80,6 +80,7 @@ public class Shortcuts : Scenario
if (e.NewValue == CheckState.Checked)
{
+ max = (from Shortcut? peer in enumerable select peer.Key.ToString ().GetColumns ()).Prepend (max).Max ();
foreach (var view in enumerable)
{
var peer = (Shortcut)view;
@@ -87,7 +88,7 @@ public class Shortcuts : Scenario
}
}
- foreach (var view in enumerable)
+ foreach (View view in enumerable)
{
var peer = (Shortcut)view;
peer.MinimumKeyTextSize = max;
@@ -101,7 +102,7 @@ public class Shortcuts : Scenario
Id = "commandFirstShortcut",
X = 0,
Y = Pos.Bottom (alignKeysShortcut),
- Width = Dim.Fill () - Dim.Width (eventLog),
+ Width = Dim.Fill ()! - Dim.Width (eventLog),
HelpText = "Show Command first",
CommandView = new CheckBox
{
@@ -122,7 +123,6 @@ public class Shortcuts : Scenario
eventSource.Add ($"{commandFirstShortcut.Id}.CommandView.CheckedStateChanging: {cb.Text}");
eventLog.MoveDown ();
- var max = 0;
IEnumerable toAlign = Application.Top.Subviews.Where (v => v is Shortcut { Width: not DimAbsolute });
IEnumerable enumerable = toAlign as View [] ?? toAlign.ToArray ();
@@ -148,7 +148,7 @@ public class Shortcuts : Scenario
Id = "canFocusShortcut",
X = 0,
Y = Pos.Bottom (commandFirstShortcut),
- Width = Dim.Fill () - Dim.Width (eventLog),
+ Width = Dim.Fill ()! - Dim.Width (eventLog),
Key = Key.F4,
HelpText = "Changes all Command.CanFocus",
KeyBindingScope = KeyBindingScope.HotKey,
@@ -194,7 +194,7 @@ public class Shortcuts : Scenario
Id = "buttonShortcut",
X = 0,
Y = Pos.Bottom (appShortcut),
- Width = Dim.Fill () - Dim.Width (eventLog),
+ Width = Dim.Fill ()! - Dim.Width (eventLog),
HelpText = "Accepting pops MB",
CommandView = new Button
{
@@ -217,7 +217,7 @@ public class Shortcuts : Scenario
X = 0,
Y = Pos.Bottom (buttonShortcut),
Key = Key.F2,
- Width = Dim.Fill () - Dim.Width (eventLog),
+ Width = Dim.Fill ()! - Dim.Width (eventLog),
KeyBindingScope = KeyBindingScope.HotKey,
CommandView = new RadioGroup
{
@@ -228,8 +228,12 @@ public class Shortcuts : Scenario
((RadioGroup)radioGroupShortcut.CommandView).SelectedItemChanged += (o, args) =>
{
- eventSource.Add ($"SelectedItemChanged: {o.GetType ().Name} - {args.SelectedItem}");
- eventLog.MoveDown ();
+ if (o is { })
+ {
+ eventSource.Add (
+ $"SelectedItemChanged: {o.GetType ().Name} - {args.SelectedItem}");
+ eventLog.MoveDown ();
+ }
};
Application.Top.Add (radioGroupShortcut);
@@ -239,7 +243,7 @@ public class Shortcuts : Scenario
Id = "sliderShortcut",
X = 0,
Y = Pos.Bottom (radioGroupShortcut),
- Width = Dim.Fill () - Dim.Width (eventLog),
+ Width = Dim.Fill ()! - Dim.Width (eventLog),
KeyBindingScope = KeyBindingScope.HotKey,
HelpText = "Sliders work!",
CommandView = new Slider
@@ -250,12 +254,12 @@ public class Shortcuts : Scenario
Key = Key.F5,
};
- ((Slider)sliderShortcut.CommandView).Options = new () { new () { Legend = "A" }, new () { Legend = "B" }, new () { Legend = "C" } };
+ ((Slider)sliderShortcut.CommandView).Options = [new () { Legend = "A" }, new () { Legend = "B" }, new () { Legend = "C" }];
((Slider)sliderShortcut.CommandView).SetOption (0);
((Slider)sliderShortcut.CommandView).OptionsChanged += (o, args) =>
{
- eventSource.Add ($"OptionsChanged: {o.GetType ().Name} - {string.Join (",", ((Slider)o).GetSetOptions ())}");
+ eventSource.Add ($"OptionsChanged: {o?.GetType ().Name} - {string.Join (",", ((Slider)o!)!.GetSetOptions ())}");
eventLog.MoveDown ();
};
@@ -314,11 +318,20 @@ public class Shortcuts : Scenario
Arrangement = ViewArrangement.RightResizable | ViewArrangement.BottomResizable,
};
framedShortcut.Orientation = Orientation.Horizontal;
- framedShortcut.Padding.Thickness = new (0, 1, 0, 0);
- framedShortcut.Padding.Diagnostics = ViewDiagnosticFlags.Ruler;
- framedShortcut.CommandView.Margin.ColorScheme = framedShortcut.CommandView.ColorScheme = Colors.ColorSchemes ["Error"];
- framedShortcut.HelpView.Margin.ColorScheme = framedShortcut.HelpView.ColorScheme = Colors.ColorSchemes ["Dialog"];
- framedShortcut.KeyView.Margin.ColorScheme = framedShortcut.KeyView.ColorScheme = Colors.ColorSchemes ["Menu"];
+
+ if (framedShortcut.Padding is { })
+ {
+ framedShortcut.Padding.Thickness = new (0, 1, 0, 0);
+ framedShortcut.Padding.Diagnostics = ViewDiagnosticFlags.Ruler;
+ }
+
+ if (framedShortcut.CommandView.Margin is { })
+ {
+ framedShortcut.CommandView.Margin.ColorScheme = framedShortcut.CommandView.ColorScheme = Colors.ColorSchemes ["Error"];
+ framedShortcut.HelpView.Margin!.ColorScheme = framedShortcut.HelpView.ColorScheme = Colors.ColorSchemes ["Dialog"];
+ framedShortcut.KeyView.Margin!.ColorScheme = framedShortcut.KeyView.ColorScheme = Colors.ColorSchemes ["Menu"];
+ }
+
framedShortcut.ColorScheme = Colors.ColorSchemes ["Toplevel"];
Application.Top.Add (framedShortcut);
@@ -423,13 +436,16 @@ public class Shortcuts : Scenario
bgColor.ColorChanged += (o, args) =>
{
- eventSource.Add ($"ColorChanged: {o.GetType ().Name} - {args.CurrentValue}");
- eventLog.MoveDown ();
-
- Application.Top.ColorScheme = new ColorScheme (Application.Top.ColorScheme)
+ if (o is { })
{
- Normal = new Attribute (Application.Top.ColorScheme.Normal.Foreground, args.CurrentValue),
- };
+ eventSource.Add ($"ColorChanged: {o.GetType ().Name} - {args.CurrentValue}");
+ eventLog.MoveDown ();
+
+ Application.Top.ColorScheme = new ColorScheme (Application.Top.ColorScheme)
+ {
+ Normal = new (Application.Top!.GetNormalColor ().Foreground, args.CurrentValue),
+ };
+ }
};
bgColorShortcut.CommandView = bgColor;
@@ -494,10 +510,10 @@ public class Shortcuts : Scenario
}
}
- private void Button_Clicked (object sender, CommandEventArgs e)
+ private void Button_Clicked (object? sender, CommandEventArgs e)
{
e.Cancel = true;
- View view = sender as View;
- MessageBox.Query ("Hi", $"You clicked {view!.Text}", "_Ok");
+ View? view = sender as View;
+ MessageBox.Query ("Hi", $"You clicked {view?.Text}", "_Ok");
}
}
diff --git a/UnitTests/Application/KeyboardTests.cs b/UnitTests/Application/KeyboardTests.cs
index 4c33361e6..99ea9df29 100644
--- a/UnitTests/Application/KeyboardTests.cs
+++ b/UnitTests/Application/KeyboardTests.cs
@@ -159,16 +159,14 @@ public class KeyboardTests
}
[Fact]
- [AutoInitShutdown]
public void KeyBinding_OnKeyDown ()
{
+ Application.Top = new Toplevel ();
var view = new ScopedKeyBindingView ();
var keyWasHandled = false;
view.KeyDownNotHandled += (s, e) => keyWasHandled = true;
- var top = new Toplevel ();
- top.Add (view);
- Application.Begin (top);
+ Application.Top.Add (view);
Application.RaiseKeyDownEvent (Key.A);
Assert.False (keyWasHandled);
@@ -200,7 +198,8 @@ public class KeyboardTests
Assert.True (view.ApplicationCommand);
Assert.True (view.HotKeyCommand);
Assert.False (view.FocusedCommand);
- top.Dispose ();
+ Application.Top.Dispose ();
+ Application.ResetState (true);
}
[Fact]
diff --git a/UnitTests/Application/SynchronizatonContextTests.cs b/UnitTests/Application/SynchronizatonContextTests.cs
index fce4a3250..ce099fd10 100644
--- a/UnitTests/Application/SynchronizatonContextTests.cs
+++ b/UnitTests/Application/SynchronizatonContextTests.cs
@@ -33,7 +33,7 @@ public class SyncrhonizationContextTests
Task.Run (
() =>
{
- Thread.Sleep (1_000);
+ Thread.Sleep (500);
// non blocking
context.Post (
@@ -68,7 +68,7 @@ public class SyncrhonizationContextTests
Task.Run (
() =>
{
- Thread.Sleep (1_000);
+ Thread.Sleep (500);
// blocking
context.Send (
diff --git a/UnitTests/Dialogs/DialogTests.cs b/UnitTests/Dialogs/DialogTests.cs
index b76498620..9320b8403 100644
--- a/UnitTests/Dialogs/DialogTests.cs
+++ b/UnitTests/Dialogs/DialogTests.cs
@@ -39,7 +39,7 @@ public class DialogTests
Width = width,
Height = 1,
ButtonAlignment = Alignment.Center,
- Buttons = [new Button { Text = btn1Text }]
+ Buttons = [new() { Text = btn1Text }]
};
// Create with no top or bottom border to simplify testing button layout (no need to account for title etc..)
@@ -67,7 +67,7 @@ public class DialogTests
Width = width,
Height = 1,
ButtonAlignment = Alignment.Fill,
- Buttons = [new Button { Text = btn1Text }]
+ Buttons = [new() { Text = btn1Text }]
};
// Create with no top or bottom border to simplify testing button layout (no need to account for title etc..)
@@ -94,7 +94,7 @@ public class DialogTests
Width = width,
Height = 1,
ButtonAlignment = Alignment.End,
- Buttons = [new Button { Text = btn1Text }]
+ Buttons = [new() { Text = btn1Text }]
};
// Create with no top or bottom border to simplify testing button layout (no need to account for title etc..)
@@ -122,7 +122,7 @@ public class DialogTests
Width = width,
Height = 1,
ButtonAlignment = Alignment.Start,
- Buttons = [new Button { Text = btn1Text }]
+ Buttons = [new() { Text = btn1Text }]
};
// Create with no top or bottom border to simplify testing button layout (no need to account for title etc..)
@@ -169,17 +169,16 @@ public class DialogTests
int width = buttonRow.Length;
d.SetBufferSize (buttonRow.Length, 3);
-
// Default - Center
(runstate, Dialog dlg) = BeginButtonTestDialog (
- title,
- width,
- Alignment.Center,
- new Button { Text = btn1Text },
- new Button { Text = btn2Text },
- new Button { Text = btn3Text },
- new Button { Text = btn4Text }
- );
+ title,
+ width,
+ Alignment.Center,
+ new Button { Text = btn1Text },
+ new Button { Text = btn2Text },
+ new Button { Text = btn3Text },
+ new Button { Text = btn4Text }
+ );
TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output);
End (runstate);
dlg.Dispose ();
@@ -189,14 +188,14 @@ public class DialogTests
Assert.Equal (width, buttonRow.Length);
(runstate, dlg) = BeginButtonTestDialog (
- title,
- width,
- Alignment.Fill,
- new Button { Text = btn1Text },
- new Button { Text = btn2Text },
- new Button { Text = btn3Text },
- new Button { Text = btn4Text }
- );
+ title,
+ width,
+ Alignment.Fill,
+ new Button { Text = btn1Text },
+ new Button { Text = btn2Text },
+ new Button { Text = btn3Text },
+ new Button { Text = btn4Text }
+ );
TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output);
End (runstate);
dlg.Dispose ();
@@ -206,14 +205,14 @@ public class DialogTests
Assert.Equal (width, buttonRow.Length);
(runstate, dlg) = BeginButtonTestDialog (
- title,
- width,
- Alignment.End,
- new Button { Text = btn1Text },
- new Button { Text = btn2Text },
- new Button { Text = btn3Text },
- new Button { Text = btn4Text }
- );
+ title,
+ width,
+ Alignment.End,
+ new Button { Text = btn1Text },
+ new Button { Text = btn2Text },
+ new Button { Text = btn3Text },
+ new Button { Text = btn4Text }
+ );
TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output);
End (runstate);
dlg.Dispose ();
@@ -223,14 +222,14 @@ public class DialogTests
Assert.Equal (width, buttonRow.Length);
(runstate, dlg) = BeginButtonTestDialog (
- title,
- width,
- Alignment.Start,
- new Button { Text = btn1Text },
- new Button { Text = btn2Text },
- new Button { Text = btn3Text },
- new Button { Text = btn4Text }
- );
+ title,
+ width,
+ Alignment.Start,
+ new Button { Text = btn1Text },
+ new Button { Text = btn2Text },
+ new Button { Text = btn3Text },
+ new Button { Text = btn4Text }
+ );
TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output);
End (runstate);
dlg.Dispose ();
@@ -285,14 +284,14 @@ public class DialogTests
$"{CM.Glyphs.VLine}{CM.Glyphs.LeftBracket} yes {CM.Glyphs.LeftBracket} no {CM.Glyphs.LeftBracket} maybe {CM.Glyphs.LeftBracket} never {CM.Glyphs.RightBracket}{CM.Glyphs.VLine}";
(runstate, dlg) = BeginButtonTestDialog (
- title,
- width,
- Alignment.Fill,
- new Button { Text = btn1Text },
- new Button { Text = btn2Text },
- new Button { Text = btn3Text },
- new Button { Text = btn4Text }
- );
+ title,
+ width,
+ Alignment.Fill,
+ new Button { Text = btn1Text },
+ new Button { Text = btn2Text },
+ new Button { Text = btn3Text },
+ new Button { Text = btn4Text }
+ );
TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output);
End (runstate);
dlg.Dispose ();
@@ -302,14 +301,14 @@ public class DialogTests
Assert.Equal (width, buttonRow.Length);
(runstate, dlg) = BeginButtonTestDialog (
- title,
- width,
- Alignment.End,
- new Button { Text = btn1Text },
- new Button { Text = btn2Text },
- new Button { Text = btn3Text },
- new Button { Text = btn4Text }
- );
+ title,
+ width,
+ Alignment.End,
+ new Button { Text = btn1Text },
+ new Button { Text = btn2Text },
+ new Button { Text = btn3Text },
+ new Button { Text = btn4Text }
+ );
TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output);
End (runstate);
dlg.Dispose ();
@@ -318,14 +317,14 @@ public class DialogTests
buttonRow = $"{CM.Glyphs.VLine}{btn1}{btn2}{btn3}{CM.Glyphs.LeftBracket} neve{CM.Glyphs.VLine}";
(runstate, dlg) = BeginButtonTestDialog (
- title,
- width,
- Alignment.Start,
- new Button { Text = btn1Text },
- new Button { Text = btn2Text },
- new Button { Text = btn3Text },
- new Button { Text = btn4Text }
- );
+ title,
+ width,
+ Alignment.Start,
+ new Button { Text = btn1Text },
+ new Button { Text = btn2Text },
+ new Button { Text = btn3Text },
+ new Button { Text = btn4Text }
+ );
TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output);
End (runstate);
dlg.Dispose ();
@@ -361,14 +360,14 @@ public class DialogTests
// Default - Center
(runstate, Dialog dlg) = BeginButtonTestDialog (
- title,
- width,
- Alignment.Center,
- new Button { Text = btn1Text },
- new Button { Text = btn2Text },
- new Button { Text = btn3Text },
- new Button { Text = btn4Text }
- );
+ title,
+ width,
+ Alignment.Center,
+ new Button { Text = btn1Text },
+ new Button { Text = btn2Text },
+ new Button { Text = btn3Text },
+ new Button { Text = btn4Text }
+ );
TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output);
End (runstate);
dlg.Dispose ();
@@ -378,14 +377,14 @@ public class DialogTests
Assert.Equal (width, buttonRow.Length);
(runstate, dlg) = BeginButtonTestDialog (
- title,
- width,
- Alignment.Fill,
- new Button { Text = btn1Text },
- new Button { Text = btn2Text },
- new Button { Text = btn3Text },
- new Button { Text = btn4Text }
- );
+ title,
+ width,
+ Alignment.Fill,
+ new Button { Text = btn1Text },
+ new Button { Text = btn2Text },
+ new Button { Text = btn3Text },
+ new Button { Text = btn4Text }
+ );
TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output);
End (runstate);
dlg.Dispose ();
@@ -395,14 +394,14 @@ public class DialogTests
Assert.Equal (width, buttonRow.Length);
(runstate, dlg) = BeginButtonTestDialog (
- title,
- width,
- Alignment.End,
- new Button { Text = btn1Text },
- new Button { Text = btn2Text },
- new Button { Text = btn3Text },
- new Button { Text = btn4Text }
- );
+ title,
+ width,
+ Alignment.End,
+ new Button { Text = btn1Text },
+ new Button { Text = btn2Text },
+ new Button { Text = btn3Text },
+ new Button { Text = btn4Text }
+ );
TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output);
End (runstate);
dlg.Dispose ();
@@ -412,14 +411,14 @@ public class DialogTests
Assert.Equal (width, buttonRow.Length);
(runstate, dlg) = BeginButtonTestDialog (
- title,
- width,
- Alignment.Start,
- new Button { Text = btn1Text },
- new Button { Text = btn2Text },
- new Button { Text = btn3Text },
- new Button { Text = btn4Text }
- );
+ title,
+ width,
+ Alignment.Start,
+ new Button { Text = btn1Text },
+ new Button { Text = btn2Text },
+ new Button { Text = btn3Text },
+ new Button { Text = btn4Text }
+ );
TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output);
End (runstate);
dlg.Dispose ();
@@ -457,14 +456,14 @@ public class DialogTests
// Default - Center
(runstate, Dialog dlg) = BeginButtonTestDialog (
- title,
- width,
- Alignment.Center,
- new Button { Text = btn1Text },
- new Button { Text = btn2Text },
- new Button { Text = btn3Text },
- new Button { Text = btn4Text }
- );
+ title,
+ width,
+ Alignment.Center,
+ new Button { Text = btn1Text },
+ new Button { Text = btn2Text },
+ new Button { Text = btn3Text },
+ new Button { Text = btn4Text }
+ );
TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output);
End (runstate);
dlg.Dispose ();
@@ -474,14 +473,14 @@ public class DialogTests
Assert.Equal (width, buttonRow.GetColumns ());
(runstate, dlg) = BeginButtonTestDialog (
- title,
- width,
- Alignment.Fill,
- new Button { Text = btn1Text },
- new Button { Text = btn2Text },
- new Button { Text = btn3Text },
- new Button { Text = btn4Text }
- );
+ title,
+ width,
+ Alignment.Fill,
+ new Button { Text = btn1Text },
+ new Button { Text = btn2Text },
+ new Button { Text = btn3Text },
+ new Button { Text = btn4Text }
+ );
TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output);
End (runstate);
dlg.Dispose ();
@@ -491,14 +490,14 @@ public class DialogTests
Assert.Equal (width, buttonRow.GetColumns ());
(runstate, dlg) = BeginButtonTestDialog (
- title,
- width,
- Alignment.End,
- new Button { Text = btn1Text },
- new Button { Text = btn2Text },
- new Button { Text = btn3Text },
- new Button { Text = btn4Text }
- );
+ title,
+ width,
+ Alignment.End,
+ new Button { Text = btn1Text },
+ new Button { Text = btn2Text },
+ new Button { Text = btn3Text },
+ new Button { Text = btn4Text }
+ );
TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output);
End (runstate);
dlg.Dispose ();
@@ -508,14 +507,14 @@ public class DialogTests
Assert.Equal (width, buttonRow.GetColumns ());
(runstate, dlg) = BeginButtonTestDialog (
- title,
- width,
- Alignment.Start,
- new Button { Text = btn1Text },
- new Button { Text = btn2Text },
- new Button { Text = btn3Text },
- new Button { Text = btn4Text }
- );
+ title,
+ width,
+ Alignment.Start,
+ new Button { Text = btn1Text },
+ new Button { Text = btn2Text },
+ new Button { Text = btn3Text },
+ new Button { Text = btn4Text }
+ );
TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output);
End (runstate);
dlg.Dispose ();
@@ -542,11 +541,11 @@ public class DialogTests
d.SetBufferSize (width, 1);
(runstate, Dialog dlg) = BeginButtonTestDialog (
- title,
- width,
- Alignment.Center,
- new Button { Text = btnText }
- );
+ title,
+ width,
+ Alignment.Center,
+ new Button { Text = btnText }
+ );
// Center
TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output);
@@ -559,11 +558,11 @@ public class DialogTests
Assert.Equal (width, buttonRow.Length);
(runstate, dlg) = BeginButtonTestDialog (
- title,
- width,
- Alignment.Fill,
- new Button { Text = btnText }
- );
+ title,
+ width,
+ Alignment.Fill,
+ new Button { Text = btnText }
+ );
TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output);
End (runstate);
dlg.Dispose ();
@@ -574,11 +573,11 @@ public class DialogTests
Assert.Equal (width, buttonRow.Length);
(runstate, dlg) = BeginButtonTestDialog (
- title,
- width,
- Alignment.End,
- new Button { Text = btnText }
- );
+ title,
+ width,
+ Alignment.End,
+ new Button { Text = btnText }
+ );
TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output);
End (runstate);
dlg.Dispose ();
@@ -589,11 +588,11 @@ public class DialogTests
Assert.Equal (width, buttonRow.Length);
(runstate, dlg) = BeginButtonTestDialog (
- title,
- width,
- Alignment.Start,
- new Button { Text = btnText }
- );
+ title,
+ width,
+ Alignment.Start,
+ new Button { Text = btnText }
+ );
TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output);
End (runstate);
dlg.Dispose ();
@@ -606,11 +605,11 @@ public class DialogTests
d.SetBufferSize (width, 1);
(runstate, dlg) = BeginButtonTestDialog (
- title,
- width,
- Alignment.Center,
- new Button { Text = btnText }
- );
+ title,
+ width,
+ Alignment.Center,
+ new Button { Text = btnText }
+ );
TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output);
End (runstate);
dlg.Dispose ();
@@ -621,11 +620,11 @@ public class DialogTests
Assert.Equal (width, buttonRow.Length);
(runstate, dlg) = BeginButtonTestDialog (
- title,
- width,
- Alignment.Fill,
- new Button { Text = btnText }
- );
+ title,
+ width,
+ Alignment.Fill,
+ new Button { Text = btnText }
+ );
TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output);
End (runstate);
dlg.Dispose ();
@@ -636,11 +635,11 @@ public class DialogTests
Assert.Equal (width, buttonRow.Length);
(runstate, dlg) = BeginButtonTestDialog (
- title,
- width,
- Alignment.End,
- new Button { Text = btnText }
- );
+ title,
+ width,
+ Alignment.End,
+ new Button { Text = btnText }
+ );
TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output);
End (runstate);
dlg.Dispose ();
@@ -651,11 +650,11 @@ public class DialogTests
Assert.Equal (width, buttonRow.Length);
(runstate, dlg) = BeginButtonTestDialog (
- title,
- width,
- Alignment.Start,
- new Button { Text = btnText }
- );
+ title,
+ width,
+ Alignment.Start,
+ new Button { Text = btnText }
+ );
TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output);
End (runstate);
dlg.Dispose ();
@@ -687,13 +686,13 @@ public class DialogTests
d.SetBufferSize (buttonRow.Length, 3);
(runstate, Dialog dlg) = BeginButtonTestDialog (
- title,
- width,
- Alignment.Center,
- new Button { Text = btn1Text },
- new Button { Text = btn2Text },
- new Button { Text = btn3Text }
- );
+ title,
+ width,
+ Alignment.Center,
+ new Button { Text = btn1Text },
+ new Button { Text = btn2Text },
+ new Button { Text = btn3Text }
+ );
TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output);
End (runstate);
dlg.Dispose ();
@@ -703,13 +702,13 @@ public class DialogTests
Assert.Equal (width, buttonRow.Length);
(runstate, dlg) = BeginButtonTestDialog (
- title,
- width,
- Alignment.Fill,
- new Button { Text = btn1Text },
- new Button { Text = btn2Text },
- new Button { Text = btn3Text }
- );
+ title,
+ width,
+ Alignment.Fill,
+ new Button { Text = btn1Text },
+ new Button { Text = btn2Text },
+ new Button { Text = btn3Text }
+ );
TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output);
End (runstate);
dlg.Dispose ();
@@ -719,13 +718,13 @@ public class DialogTests
Assert.Equal (width, buttonRow.Length);
(runstate, dlg) = BeginButtonTestDialog (
- title,
- width,
- Alignment.End,
- new Button { Text = btn1Text },
- new Button { Text = btn2Text },
- new Button { Text = btn3Text }
- );
+ title,
+ width,
+ Alignment.End,
+ new Button { Text = btn1Text },
+ new Button { Text = btn2Text },
+ new Button { Text = btn3Text }
+ );
TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output);
End (runstate);
dlg.Dispose ();
@@ -735,13 +734,13 @@ public class DialogTests
Assert.Equal (width, buttonRow.Length);
(runstate, dlg) = BeginButtonTestDialog (
- title,
- width,
- Alignment.Start,
- new Button { Text = btn1Text },
- new Button { Text = btn2Text },
- new Button { Text = btn3Text }
- );
+ title,
+ width,
+ Alignment.Start,
+ new Button { Text = btn1Text },
+ new Button { Text = btn2Text },
+ new Button { Text = btn3Text }
+ );
TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output);
End (runstate);
dlg.Dispose ();
@@ -771,12 +770,12 @@ public class DialogTests
d.SetBufferSize (buttonRow.Length, 3);
(runstate, Dialog dlg) = BeginButtonTestDialog (
- title,
- width,
- Alignment.Center,
- new Button { Text = btn1Text },
- new Button { Text = btn2Text }
- );
+ title,
+ width,
+ Alignment.Center,
+ new Button { Text = btn1Text },
+ new Button { Text = btn2Text }
+ );
TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output);
End (runstate);
dlg.Dispose ();
@@ -786,12 +785,12 @@ public class DialogTests
Assert.Equal (width, buttonRow.Length);
(runstate, dlg) = BeginButtonTestDialog (
- title,
- width,
- Alignment.Fill,
- new Button { Text = btn1Text },
- new Button { Text = btn2Text }
- );
+ title,
+ width,
+ Alignment.Fill,
+ new Button { Text = btn1Text },
+ new Button { Text = btn2Text }
+ );
TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output);
End (runstate);
dlg.Dispose ();
@@ -801,12 +800,12 @@ public class DialogTests
Assert.Equal (width, buttonRow.Length);
(runstate, dlg) = BeginButtonTestDialog (
- title,
- width,
- Alignment.End,
- new Button { Text = btn1Text },
- new Button { Text = btn2Text }
- );
+ title,
+ width,
+ Alignment.End,
+ new Button { Text = btn1Text },
+ new Button { Text = btn2Text }
+ );
TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output);
End (runstate);
dlg.Dispose ();
@@ -816,12 +815,12 @@ public class DialogTests
Assert.Equal (width, buttonRow.Length);
(runstate, dlg) = BeginButtonTestDialog (
- title,
- width,
- Alignment.Start,
- new Button { Text = btn1Text },
- new Button { Text = btn2Text }
- );
+ title,
+ width,
+ Alignment.Start,
+ new Button { Text = btn1Text },
+ new Button { Text = btn2Text }
+ );
TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output);
End (runstate);
dlg.Dispose ();
@@ -855,8 +854,8 @@ public class DialogTests
Button button1, button2;
// Default (Center)
- button1 = new Button { Text = btn1Text };
- button2 = new Button { Text = btn2Text };
+ button1 = new() { Text = btn1Text };
+ button2 = new() { Text = btn2Text };
(runstate, dlg) = BeginButtonTestDialog (title, width, Alignment.Center, button1, button2);
button1.Visible = false;
RunIteration (ref runstate, firstIteration);
@@ -867,8 +866,8 @@ public class DialogTests
// Justify
Assert.Equal (width, buttonRow.Length);
- button1 = new Button { Text = btn1Text };
- button2 = new Button { Text = btn2Text };
+ button1 = new() { Text = btn1Text };
+ button2 = new() { Text = btn2Text };
(runstate, dlg) = BeginButtonTestDialog (title, width, Alignment.Fill, button1, button2);
button1.Visible = false;
RunIteration (ref runstate, firstIteration);
@@ -879,8 +878,8 @@ public class DialogTests
// Right
Assert.Equal (width, buttonRow.Length);
- button1 = new Button { Text = btn1Text };
- button2 = new Button { Text = btn2Text };
+ button1 = new() { Text = btn1Text };
+ button2 = new() { Text = btn2Text };
(runstate, dlg) = BeginButtonTestDialog (title, width, Alignment.End, button1, button2);
button1.Visible = false;
RunIteration (ref runstate, firstIteration);
@@ -890,8 +889,8 @@ public class DialogTests
// Left
Assert.Equal (width, buttonRow.Length);
- button1 = new Button { Text = btn1Text };
- button2 = new Button { Text = btn2Text };
+ button1 = new() { Text = btn1Text };
+ button2 = new() { Text = btn2Text };
(runstate, dlg) = BeginButtonTestDialog (title, width, Alignment.Start, button1, button2);
button1.Visible = false;
RunIteration (ref runstate, firstIteration);
@@ -1020,7 +1019,7 @@ public class DialogTests
Dialog.DefaultBorderStyle = LineStyle.Single;
Dialog.DefaultShadow = ShadowStyle.None;
Button.DefaultShadow = ShadowStyle.None;
-
+
Iteration += (s, a) =>
{
iterations++;
@@ -1151,7 +1150,7 @@ public class DialogTests
_output
);
- Assert.False (Top!.NewKeyDownEvent (Key.Enter));
+ Assert.False (Top.NewKeyDownEvent (Key.Enter));
break;
case 4:
@@ -1194,7 +1193,7 @@ public class DialogTests
[AutoInitShutdown]
public void Location_Default ()
{
- var d = new Dialog ()
+ var d = new Dialog
{
Width = Dim.Percent (85),
Height = Dim.Percent (85)
@@ -1253,86 +1252,6 @@ public class DialogTests
d.Dispose ();
}
-// [Fact]
-// [AutoInitShutdown]
-// public void Location_When_Not_Application_Top_Not_Default ()
-// {
-// var top = new Toplevel ();
-// top.BorderStyle = LineStyle.Double;
-
-// int iterations = -1;
-
-// // Override CM
-// Window.DefaultBorderStyle = LineStyle.Single;
-// Dialog.DefaultButtonAlignment = Alignment.Center;
-// Dialog.DefaultBorderStyle = LineStyle.Single;
-// Dialog.DefaultShadow = ShadowStyle.None;
-
-// Iteration += (s, a) =>
-// {
-// iterations++;
-
-// if (iterations == 0)
-// {
-// var d = new Dialog { X = 5, Y = 5, Height = 3, Width = 5 };
-// RunState rs = Begin (d);
-
-// Assert.Equal (new (5, 5), d.Frame.Location);
-
-// TestHelpers.AssertDriverContentsWithFrameAre (
-// @"
-//╔══════════════════╗
-//║ ║
-//║ ║
-//║ ║
-//║ ║
-//║ ┌───┐ ║
-//║ │ │ ║
-//║ └───┘ ║
-//║ ║
-//╚══════════════════╝",
-// _output
-// );
-// End (rs);
-// d.Dispose ();
-
-// d = new ()
-// {
-// X = 5, Y = 5,
-// Width = Dim.Percent (85),
-// Height = Dim.Percent (85)
-
-// };
-// rs = Begin (d);
-
-// TestHelpers.AssertDriverContentsWithFrameAre (
-// @"
-//╔══════════════════╗
-//║ ║
-//║ ║
-//║ ║
-//║ ║
-//║ ┌──────────────
-//║ │
-//║ │
-//║ │
-//╚════│ ",
-// _output
-// );
-// End (rs);
-// d.Dispose ();
-// }
-// else if (iterations > 0)
-// {
-// RequestStop ();
-// }
-// };
-
-// ((FakeDriver)Driver).SetBufferSize (20, 10);
-// Run (top);
-// top.Dispose ();
-// }
-
[Fact]
[AutoInitShutdown]
public void One_Button_Works ()
@@ -1353,11 +1272,11 @@ public class DialogTests
d.SetBufferSize (buttonRow.Length, 10);
(runstate, Dialog dlg) = BeginButtonTestDialog (
- title,
- width,
- Alignment.Center,
- new Button { Text = btnText }
- );
+ title,
+ width,
+ Alignment.Center,
+ new Button { Text = btnText }
+ );
TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output);
End (runstate);
dlg.Dispose ();
@@ -1367,7 +1286,7 @@ public class DialogTests
[AutoInitShutdown]
public void Size_Default ()
{
- var d = new Dialog ()
+ var d = new Dialog
{
Width = Dim.Percent (85),
Height = Dim.Percent (85)
diff --git a/UnitTests/Input/KeyBindingTests.cs b/UnitTests/Input/KeyBindingTests.cs
index af95eff47..edade4239 100644
--- a/UnitTests/Input/KeyBindingTests.cs
+++ b/UnitTests/Input/KeyBindingTests.cs
@@ -1,4 +1,5 @@
-using Xunit.Abstractions;
+using Terminal.Gui.EnumExtensions;
+using Xunit.Abstractions;
namespace Terminal.Gui.InputTests;
@@ -10,11 +11,19 @@ public class KeyBindingTests
[Fact]
public void Add_Invalid_Key_Throws ()
{
- var keyBindings = new KeyBindings ();
+ var keyBindings = new KeyBindings (new View ());
List commands = new ();
Assert.Throws (() => keyBindings.Add (Key.Empty, KeyBindingScope.HotKey, Command.Accept));
}
+ [Fact]
+ public void Add_BoundView_Null_Non_AppScope_Throws ()
+ {
+ var keyBindings = new KeyBindings ();
+ List commands = new ();
+ Assert.Throws (() => keyBindings.Add (Key.Empty, KeyBindingScope.HotKey, Command.Accept));
+ }
+
[Fact]
public void Add_Multiple_Adds ()
{
@@ -53,32 +62,41 @@ public class KeyBindingTests
Assert.Contains (Command.HotKey, resultCommands);
}
+
// Add should not allow duplicates
[Fact]
- public void Add_Throws_If_Exists ()
+ public void Add_With_Bound_View_Throws_If_App_Scope ()
{
- var keyBindings = new KeyBindings ();
- keyBindings.Add (Key.A, KeyBindingScope.Application, Command.HotKey);
+ var keyBindings = new KeyBindings (new View ());
Assert.Throws (() => keyBindings.Add (Key.A, KeyBindingScope.Application, Command.Accept));
+ }
+
+ // Add should not allow duplicates
+ [Fact]
+ public void Add_With_Throws_If_Exists ()
+ {
+ var keyBindings = new KeyBindings (new View ());
+ keyBindings.Add (Key.A, KeyBindingScope.HotKey, Command.HotKey);
+ Assert.Throws (() => keyBindings.Add (Key.A, KeyBindingScope.HotKey, Command.Accept));
Command [] resultCommands = keyBindings.GetCommands (Key.A);
Assert.Contains (Command.HotKey, resultCommands);
- keyBindings = new ();
+ keyBindings = new (new View ());
keyBindings.Add (Key.A, KeyBindingScope.Focused, Command.HotKey);
Assert.Throws (() => keyBindings.Add (Key.A, KeyBindingScope.Focused, Command.Accept));
resultCommands = keyBindings.GetCommands (Key.A);
Assert.Contains (Command.HotKey, resultCommands);
- keyBindings = new ();
+ keyBindings = new (new View ());
keyBindings.Add (Key.A, KeyBindingScope.HotKey, Command.HotKey);
- Assert.Throws (() => keyBindings.Add (Key.A, KeyBindingScope.Focused, Command.Accept));
+ Assert.Throws (() => keyBindings.Add (Key.A, KeyBindingScope.HotKey, Command.Accept));
resultCommands = keyBindings.GetCommands (Key.A);
Assert.Contains (Command.HotKey, resultCommands);
- keyBindings = new ();
+ keyBindings = new (new View ());
keyBindings.Add (Key.A, new KeyBinding (new [] { Command.HotKey }, KeyBindingScope.HotKey));
Assert.Throws (() => keyBindings.Add (Key.A, new KeyBinding (new [] { Command.Accept }, KeyBindingScope.HotKey)));
@@ -207,11 +225,11 @@ public class KeyBindingTests
[Fact]
public void ReplaceKey_Replaces ()
{
- var keyBindings = new KeyBindings ();
- keyBindings.Add (Key.A, KeyBindingScope.Application, Command.HotKey);
- keyBindings.Add (Key.B, KeyBindingScope.Application, Command.HotKey);
- keyBindings.Add (Key.C, KeyBindingScope.Application, Command.HotKey);
- keyBindings.Add (Key.D, KeyBindingScope.Application, Command.HotKey);
+ var keyBindings = new KeyBindings (new ());
+ keyBindings.Add (Key.A, KeyBindingScope.Focused, Command.HotKey);
+ keyBindings.Add (Key.B, KeyBindingScope.Focused, Command.HotKey);
+ keyBindings.Add (Key.C, KeyBindingScope.Focused, Command.HotKey);
+ keyBindings.Add (Key.D, KeyBindingScope.Focused, Command.HotKey);
keyBindings.ReplaceKey (Key.A, Key.E);
Assert.Empty (keyBindings.GetCommands (Key.A));
@@ -233,9 +251,9 @@ public class KeyBindingTests
[Fact]
public void ReplaceKey_Replaces_Leaves_Old_Binding ()
{
- var keyBindings = new KeyBindings ();
- keyBindings.Add (Key.A, KeyBindingScope.Application, Command.Accept);
- keyBindings.Add (Key.B, KeyBindingScope.Application, Command.HotKey);
+ var keyBindings = new KeyBindings (new ());
+ keyBindings.Add (Key.A, KeyBindingScope.Focused, Command.Accept);
+ keyBindings.Add (Key.B, KeyBindingScope.Focused, Command.HotKey);
keyBindings.ReplaceKey (keyBindings.GetKeyFromCommands (Command.Accept), Key.C);
Assert.Empty (keyBindings.GetCommands (Key.A));
@@ -264,7 +282,7 @@ public class KeyBindingTests
[InlineData (KeyBindingScope.Application)]
public void Scope_Add_Adds (KeyBindingScope scope)
{
- var keyBindings = new KeyBindings ();
+ var keyBindings = new KeyBindings (scope.FastHasFlags(KeyBindingScope.Application) ? null : new ());
Command [] commands = { Command.Right, Command.Left };
var key = new Key (Key.A);
@@ -288,7 +306,7 @@ public class KeyBindingTests
[InlineData (KeyBindingScope.Application)]
public void Scope_Get_Filters (KeyBindingScope scope)
{
- var keyBindings = new KeyBindings ();
+ var keyBindings = new KeyBindings (scope.FastHasFlags (KeyBindingScope.Application) ? null : new ());
Command [] commands = { Command.Right, Command.Left };
var key = new Key (Key.A);
@@ -308,7 +326,7 @@ public class KeyBindingTests
[InlineData (KeyBindingScope.Application)]
public void Scope_TryGet_Filters (KeyBindingScope scope)
{
- var keyBindings = new KeyBindings ();
+ var keyBindings = new KeyBindings (scope.FastHasFlags (KeyBindingScope.Application) ? null : new ());
Command [] commands = { Command.Right, Command.Left };
var key = new Key (Key.A);
diff --git a/UnitTests/View/Draw/AllViewsDrawTests.cs b/UnitTests/View/Draw/AllViewsDrawTests.cs
index 376f53d82..fa865068b 100644
--- a/UnitTests/View/Draw/AllViewsDrawTests.cs
+++ b/UnitTests/View/Draw/AllViewsDrawTests.cs
@@ -42,11 +42,14 @@ public class AllViewsDrawTests (ITestOutputHelper _output) : TestsAllViews
Assert.Equal (1, layoutStartedCount);
Assert.Equal (1, layoutCompleteCount);
- view.SetNeedsDraw ();
- view.Draw ();
+ if (view.Visible)
+ {
+ view.SetNeedsDraw ();
+ view.Draw ();
- Assert.Equal (1, drawCompleteCount);
- Assert.Equal (1, layoutStartedCount);
- Assert.Equal (1, layoutCompleteCount);
+ Assert.Equal (1, drawCompleteCount);
+ Assert.Equal (1, layoutStartedCount);
+ Assert.Equal (1, layoutCompleteCount);
+ }
}
}
diff --git a/UnitTests/View/SubviewTests.cs b/UnitTests/View/SubviewTests.cs
index 34826427d..8dc057457 100644
--- a/UnitTests/View/SubviewTests.cs
+++ b/UnitTests/View/SubviewTests.cs
@@ -499,4 +499,112 @@ public class SubviewTests
superView.MoveSubviewTowardsEnd (subview2);
Assert.Equal (subview2, superView.Subviews [^1]);
}
+
+ [Fact]
+ public void IsInHierarchy_ViewIsNull_ReturnsFalse ()
+ {
+ // Arrange
+ var start = new View ();
+
+ // Act
+ var result = View.IsInHierarchy (start, null);
+
+ // Assert
+ Assert.False (result);
+ }
+
+ [Fact]
+ public void IsInHierarchy_StartIsNull_ReturnsFalse ()
+ {
+ // Arrange
+ var view = new View ();
+
+ // Act
+ var result = View.IsInHierarchy (null, view);
+
+ // Assert
+ Assert.False (result);
+ }
+
+ [Fact]
+ public void IsInHierarchy_ViewIsStart_ReturnsTrue ()
+ {
+ // Arrange
+ var start = new View ();
+
+ // Act
+ var result = View.IsInHierarchy (start, start);
+
+ // Assert
+ Assert.True (result);
+ }
+
+ [Fact]
+ public void IsInHierarchy_ViewIsDirectSubview_ReturnsTrue ()
+ {
+ // Arrange
+ var start = new View ();
+ var subview = new View ();
+ start.Add (subview);
+
+ // Act
+ var result = View.IsInHierarchy (start, subview);
+
+ // Assert
+ Assert.True (result);
+ }
+
+ [Fact]
+ public void IsInHierarchy_ViewIsNestedSubview_ReturnsTrue ()
+ {
+ // Arrange
+ var start = new View ();
+ var subview = new View ();
+ var nestedSubview = new View ();
+ start.Add (subview);
+ subview.Add (nestedSubview);
+
+ // Act
+ var result = View.IsInHierarchy (start, nestedSubview);
+
+ // Assert
+ Assert.True (result);
+ }
+
+ [Fact]
+ public void IsInHierarchy_ViewIsNotInHierarchy_ReturnsFalse ()
+ {
+ // Arrange
+ var start = new View ();
+ var subview = new View ();
+
+ // Act
+ var result = View.IsInHierarchy (start, subview);
+
+ // Assert
+ Assert.False (result);
+ }
+
+ [Theory]
+ [CombinatorialData]
+ public void IsInHierarchy_ViewIsInAdornments_ReturnsTrue (bool includeAdornments)
+ {
+ // Arrange
+ var start = new View ()
+ {
+ Id = "start"
+ };
+ var inPadding = new View ()
+ {
+ Id = "inPadding"
+ };
+
+ start.Padding.Add (inPadding);
+
+ // Act
+ var result = View.IsInHierarchy (start, inPadding, includeAdornments: includeAdornments);
+
+ // Assert
+ Assert.Equal(includeAdornments, result);
+ }
}
diff --git a/UnitTests/Views/DateFieldTests.cs b/UnitTests/Views/DateFieldTests.cs
index f02fcf5df..b0adc8707 100644
--- a/UnitTests/Views/DateFieldTests.cs
+++ b/UnitTests/Views/DateFieldTests.cs
@@ -188,7 +188,7 @@ public class DateFieldTests
DateTime date = DateTime.Parse ("1/1/1971");
- foreach (CultureInfo culture in CultureInfo.GetCultures (CultureTypes.AllCultures))
+ foreach (CultureInfo culture in CultureInfo.GetCultures (CultureTypes.NeutralCultures))
{
CultureInfo.CurrentCulture = culture;
string separator = culture.DateTimeFormat.DateSeparator.Trim ();
diff --git a/UnitTests/Views/ToplevelTests.cs b/UnitTests/Views/ToplevelTests.cs
index e39cd739a..8c45ad6f0 100644
--- a/UnitTests/Views/ToplevelTests.cs
+++ b/UnitTests/Views/ToplevelTests.cs
@@ -1,8 +1,6 @@
-using Xunit.Abstractions;
+namespace Terminal.Gui.ViewsTests;
-namespace Terminal.Gui.ViewsTests;
-
-public partial class ToplevelTests (ITestOutputHelper output)
+public partial class ToplevelTests ()
{
[Fact]
public void Constructor_Default ()
diff --git a/UnitTests/Views/ViewDisposalTest.cs b/UnitTests/Views/ViewDisposalTest.cs
index 1c70f5335..f171ff708 100644
--- a/UnitTests/Views/ViewDisposalTest.cs
+++ b/UnitTests/Views/ViewDisposalTest.cs
@@ -32,8 +32,8 @@ public class ViewDisposalTest (ITestOutputHelper output)
private WeakReference DoTest ()
{
GetSpecialParams ();
- var container = new View ();
- Toplevel top = new ();
+ var container = new View () { Id = "container" };
+ Toplevel top = new () { Id = "top" };
List views = GetViews ();
foreach (Type view in views)
@@ -51,6 +51,7 @@ public class ViewDisposalTest (ITestOutputHelper output)
}
Assert.NotNull (instance);
+ instance.Id = $"{view.Name}";
container.Add (instance);
output.WriteLine ($"Added instance of {view}!");
}