diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
index 11af7dd2cd..0ae10e4677 100644
--- a/.github/workflows/publish.yml
+++ b/.github/workflows/publish.yml
@@ -43,8 +43,10 @@ jobs:
- name: Build Release
run: |
dotnet-gitversion /updateprojectfiles
- dotnet build --no-restore -c Release
-
+ Import-Module ./Scripts/Terminal.Gui.PowerShell.psd1
+ Build-Analyzers
+ dotnet build -c Release
+ Remove-Module Terminal.Gui.PowerShell
- name: Pack
run: dotnet pack -c Release --include-symbols -p:Version='${{ steps.gitversion.outputs.SemVer }}'
diff --git a/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs b/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs
index e0ab6fff61..c059a652f9 100644
--- a/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs
+++ b/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs
@@ -833,7 +833,7 @@ bool IsButtonClickedOrDoubleClicked (MouseFlags flag)
///
private static Attribute MakeColor (short foreground, short background)
{
- var v = (short)(foreground | (background << 4));
+ var v = (short)((ushort)foreground | (background << 4));
// TODO: for TrueColor - Use InitExtendedPair
Curses.InitColorPair (v, foreground, background);
diff --git a/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs b/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs
index 896487ac30..21991f4485 100644
--- a/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs
+++ b/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs
@@ -2344,11 +2344,9 @@ private void CheckWinChange ()
internal class WindowsClipboard : ClipboardBase
{
- private const uint _cfUnicodeText = 13;
+ private const uint CF_UNICODE_TEXT = 13;
- public WindowsClipboard () { IsSupported = IsClipboardFormatAvailable (_cfUnicodeText); }
-
- public override bool IsSupported { get; }
+ public override bool IsSupported { get; } = IsClipboardFormatAvailable (CF_UNICODE_TEXT);
protected override string GetClipboardDataImpl ()
{
@@ -2359,7 +2357,7 @@ protected override string GetClipboardDataImpl ()
return string.Empty;
}
- nint handle = GetClipboardData (_cfUnicodeText);
+ nint handle = GetClipboardData (CF_UNICODE_TEXT);
if (handle == nint.Zero)
{
@@ -2431,7 +2429,7 @@ protected override void SetClipboardDataImpl (string text)
GlobalUnlock (target);
}
- if (SetClipboardData (_cfUnicodeText, hGlobal) == default (nint))
+ if (SetClipboardData (CF_UNICODE_TEXT, hGlobal) == default (nint))
{
ThrowWin32 ();
}
diff --git a/Terminal.Gui/Drawing/Justification.cs b/Terminal.Gui/Drawing/Justification.cs
index 16c76c372c..f1fba56a83 100644
--- a/Terminal.Gui/Drawing/Justification.cs
+++ b/Terminal.Gui/Drawing/Justification.cs
@@ -96,7 +96,7 @@ public class Justifier
public int ContainerSize { get; set; }
///
- /// Gets or sets whether puts a space is placed between items. Default is . If , a space will be
+ /// Gets or sets whether puts a space is placed between items. Default is . If , a space will be
/// placed between each item, which is useful for justifying text.
///
public bool PutSpaceBetweenItems { get; set; }
@@ -118,6 +118,7 @@ public int [] Justify (int [] sizes)
///
/// The sizes of the items to justify.
/// The justification style.
+ ///
/// The size of the container.
/// The locations of the items, from left to right.
public static int [] Justify (Justification justification, bool putSpaceBetweenItems, int containerSize, int [] sizes)
diff --git a/Terminal.Gui/Text/TextFormatter.cs b/Terminal.Gui/Text/TextFormatter.cs
index 5d60ba89ad..925f89a389 100644
--- a/Terminal.Gui/Text/TextFormatter.cs
+++ b/Terminal.Gui/Text/TextFormatter.cs
@@ -662,7 +662,7 @@ public Size FormatAndGetSize ()
///
///
/// If the text needs to be formatted (if is )
- /// will be called and upon return
+ /// will be called and upon return
/// will be .
///
///
diff --git a/Terminal.Gui/View/Layout/ViewLayout.cs b/Terminal.Gui/View/Layout/ViewLayout.cs
index 4178e63ef6..5a03664520 100644
--- a/Terminal.Gui/View/Layout/ViewLayout.cs
+++ b/Terminal.Gui/View/Layout/ViewLayout.cs
@@ -670,9 +670,10 @@ public virtual void LayoutSubviews ()
CheckDimAuto ();
- LayoutAdornments ();
+ var contentSize = ContentSize.GetValueOrDefault ();
+ OnLayoutStarted (new (contentSize));
- OnLayoutStarted (new (ContentSize.GetValueOrDefault ()));
+ LayoutAdornments ();
SetTextFormatterSize ();
@@ -684,7 +685,7 @@ public virtual void LayoutSubviews ()
foreach (View v in ordered)
{
- LayoutSubview (v, Viewport.Size);
+ LayoutSubview (v, contentSize);
}
// If the 'to' is rooted to 'from' it's a special-case.
@@ -699,7 +700,7 @@ public virtual void LayoutSubviews ()
LayoutNeeded = false;
- OnLayoutComplete (new (ContentSize.GetValueOrDefault ()));
+ OnLayoutComplete (new (contentSize));
}
private void LayoutSubview (View v, Size contentSize)
diff --git a/Terminal.sln.DotSettings b/Terminal.sln.DotSettings
index 3bc1fab5d4..ca15b55838 100644
--- a/Terminal.sln.DotSettings
+++ b/Terminal.sln.DotSettings
@@ -387,6 +387,7 @@
<Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" />
<Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" />
<Policy><Descriptor Staticness="Static" AccessRightKinds="Private" Description="Static readonly fields (private)"><ElementKinds><Kind Name="READONLY_FIELD" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" /></Policy>
+ <Policy><Descriptor Staticness="Any" AccessRightKinds="Private" Description="Constant fields (private)"><ElementKinds><Kind Name="CONSTANT_FIELD" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="" Suffix="" Style="AA_BB" /></Policy>
<Policy><Descriptor Staticness="Instance" AccessRightKinds="Protected, ProtectedInternal, Internal, Public, PrivateProtected" Description="Instance fields (not private)"><ElementKinds><Kind Name="FIELD" /><Kind Name="READONLY_FIELD" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" /></Policy>
<Policy><Descriptor Staticness="Static" AccessRightKinds="Protected, ProtectedInternal, Internal, Public, PrivateProtected" Description="Static fields (not private)"><ElementKinds><Kind Name="FIELD" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" /></Policy>
<Policy><Descriptor Staticness="Static" AccessRightKinds="Protected, ProtectedInternal, Internal, Public, PrivateProtected" Description="Static readonly fields (not private)"><ElementKinds><Kind Name="READONLY_FIELD" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" /></Policy>
diff --git a/UnitTests/View/FindDeepestViewTests.cs b/UnitTests/View/FindDeepestViewTests.cs
index 8f99e095cc..67687702d9 100644
--- a/UnitTests/View/FindDeepestViewTests.cs
+++ b/UnitTests/View/FindDeepestViewTests.cs
@@ -8,7 +8,7 @@ namespace Terminal.Gui.ViewTests;
/// Tests View.FindDeepestView
///
///
-public class FindDeepestViewTests (ITestOutputHelper output)
+public class FindDeepestViewTests ()
{
[Theory]
[InlineData (0, 0, 0, 0, 0, -1, -1, null)]
@@ -249,7 +249,6 @@ public void Returns_Null_If_Not_Visible_And_SubView_Visible (int testX, int test
[InlineData (2, 3, true)]
[InlineData (5, 6, true)]
- [InlineData (2, 3, true)]
[InlineData (6, 7, true)]
public void Returns_Correct_If_Start_Has_Adornments (int testX, int testY, bool expectedSubViewFound)
{
@@ -303,15 +302,14 @@ public void Returns_Correct_If_Start_Has_Offset_Viewport (int offset, int testX,
}
[Theory]
+ [InlineData (9, 9, true)]
[InlineData (0, 0, false)]
[InlineData (1, 1, false)]
- [InlineData (9, 9, true)]
[InlineData (10, 10, false)]
[InlineData (7, 8, false)]
[InlineData (1, 2, false)]
[InlineData (2, 3, false)]
[InlineData (5, 6, false)]
- [InlineData (2, 3, false)]
[InlineData (6, 7, false)]
public void Returns_Correct_If_Start_Has_Adornment_WithSubview (int testX, int testY, bool expectedSubViewFound)
{
@@ -365,7 +363,7 @@ public void Returns_Adornment_If_Start_Has_Adornments (int testX, int testY, Typ
start.Add (subview);
var found = View.FindDeepestView (start, testX, testY);
- Assert.Equal (expectedAdornmentType, found.GetType ());
+ Assert.Equal (expectedAdornmentType, found!.GetType ());
}
// Test that FindDeepestView works if the subview has positive Adornments
@@ -379,7 +377,6 @@ public void Returns_Adornment_If_Start_Has_Adornments (int testX, int testY, Typ
[InlineData (1, 2, false)]
[InlineData (5, 6, false)]
- [InlineData (2, 3, true)]
[InlineData (2, 3, true)]
public void Returns_Correct_If_SubView_Has_Adornments (int testX, int testY, bool expectedSubViewFound)
{
@@ -533,6 +530,6 @@ public void Returns_Correct_With_NestedSubViews (int testX, int testY, int expec
start.Add (subviews [0]);
var found = View.FindDeepestView (start, testX, testY);
- Assert.Equal (expectedSubViewFound, subviews.IndexOf (found));
+ Assert.Equal (expectedSubViewFound, subviews.IndexOf (found!));
}
}
diff --git a/UnitTests/View/Layout/LayoutTests.cs b/UnitTests/View/Layout/LayoutTests.cs
index 94267b4081..2f00865a09 100644
--- a/UnitTests/View/Layout/LayoutTests.cs
+++ b/UnitTests/View/Layout/LayoutTests.cs
@@ -115,66 +115,65 @@ public void TopologicalSort_Recursive_Ref ()
sub2.Dispose ();
}
- //[Fact]
- //[AutoInitShutdown]
- //public void TrySetHeight_ForceValidatePosDim ()
- //{
- // var top = new View { X = 0, Y = 0, Height = 20 };
-
- // var v = new View { Height = Dim.Fill (), ValidatePosDim = true };
- // top.Add (v);
-
- // Assert.False (v.TrySetHeight (10, out int rHeight));
- // Assert.Equal (10, rHeight);
-
- // v.Height = Dim.Fill (1);
- // Assert.False (v.TrySetHeight (10, out rHeight));
- // Assert.Equal (9, rHeight);
-
- // v.Height = 0;
- // Assert.True (v.TrySetHeight (10, out rHeight));
- // Assert.Equal (10, rHeight);
- // Assert.False (v.IsInitialized);
-
- // var toplevel = new Toplevel ();
- // toplevel.Add (top);
- // Application.Begin (toplevel);
-
- // Assert.True (v.IsInitialized);
-
- // v.Height = 15;
- // Assert.True (v.TrySetHeight (5, out rHeight));
- // Assert.Equal (5, rHeight);
- //}
-
- //[Fact]
- //[AutoInitShutdown]
- //public void TrySetWidth_ForceValidatePosDim ()
- //{
- // var top = new View { X = 0, Y = 0, Width = 80 };
-
- // var v = new View { Width = Dim.Fill (), ValidatePosDim = true };
- // top.Add (v);
-
- // Assert.False (v.TrySetWidth (70, out int rWidth));
- // Assert.Equal (70, rWidth);
-
- // v.Width = Dim.Fill (1);
- // Assert.False (v.TrySetWidth (70, out rWidth));
- // Assert.Equal (69, rWidth);
-
- // v.Width = 0;
- // Assert.True (v.TrySetWidth (70, out rWidth));
- // Assert.Equal (70, rWidth);
- // Assert.False (v.IsInitialized);
-
- // var toplevel = new Toplevel ();
- // toplevel.Add (top);
- // Application.Begin (toplevel);
-
- // Assert.True (v.IsInitialized);
- // v.Width = 75;
- // Assert.True (v.TrySetWidth (60, out rWidth));
- // Assert.Equal (60, rWidth);
- //}
+ [Fact]
+ public void LayoutSubviews_Uses_ContentSize ()
+ {
+ var superView = new View ()
+ {
+ Width = 5,
+ Height = 5,
+ ContentSize = new (10, 10)
+ };
+ var view = new View ()
+ {
+ X = Pos.Center ()
+ };
+ superView.Add (view);
+
+ superView.LayoutSubviews ();
+
+ Assert.Equal (5, view.Frame.X);
+ superView.Dispose ();
+ }
+
+ // Test OnLayoutStarted/OnLayoutComplete - ensure that they are called at right times
+ [Fact]
+ public void LayoutSubviews_LayoutStarted_Complete ()
+ {
+ var superView = new View ();
+ var view = new View ();
+ superView.Add (view);
+ superView.BeginInit ();
+ superView.EndInit ();
+
+ var layoutStarted = false;
+ var layoutComplete = false;
+
+ var borderLayoutStarted = false;
+ var borderLayoutComplete = false;
+
+ view.LayoutStarted += (sender, e) => layoutStarted = true;
+ view.LayoutComplete += (sender, e) => layoutComplete = true;
+
+ view.Border.LayoutStarted += (sender, e) =>
+ {
+ Assert.True (layoutStarted);
+ borderLayoutStarted = true;
+ };
+ view.Border.LayoutComplete += (sender, e) =>
+ {
+ Assert.True (layoutStarted);
+ Assert.False (layoutComplete);
+ borderLayoutComplete = true;
+ };
+
+ superView.LayoutSubviews ();
+
+ Assert.True (borderLayoutStarted);
+ Assert.True (borderLayoutComplete);
+
+ Assert.True (layoutStarted);
+ Assert.True (layoutComplete);
+ superView.Dispose ();
+ }
}
diff --git a/UnitTests/View/Layout/ViewportTests.cs b/UnitTests/View/Layout/ViewportTests.cs
index cd576c2105..a4fa24c265 100644
--- a/UnitTests/View/Layout/ViewportTests.cs
+++ b/UnitTests/View/Layout/ViewportTests.cs
@@ -248,7 +248,7 @@ public void Set_Viewport_ValidValue_UpdatesViewport (int viewWidth, int viewHeig
view.Viewport = newViewport;
// Assert
- Assert.Equal (new Rectangle(expectedX, expectedY, viewWidth, viewHeight), view.Viewport);
+ Assert.Equal (new Rectangle (expectedX, expectedY, viewWidth, viewHeight), view.Viewport);
}
[Theory]
@@ -321,18 +321,9 @@ public void Set_Viewport_NegativeValue_NotAllowedBySettings ()
}
[Theory]
- [InlineData (0, 0, 0)]
- [InlineData (1, 0, 0)]
- [InlineData (-1, 0, 0)]
- [InlineData (10, 0, 0)]
- [InlineData (11, 0, 0)]
-
- [InlineData (0, 1, 1)]
- [InlineData (1, 1, 1)]
- [InlineData (-1, 1, 1)]
- [InlineData (10, 1, 1)]
- [InlineData (11, 1, 1)]
- public void GetViewportOffset_Returns_Offset_From_Frame (int frameX, int adornmentThickness, int expectedOffset)
+ [InlineData (0, 0)]
+ [InlineData (1, 1)]
+ public void GetViewportOffset_Returns_Offset_From_Frame (int adornmentThickness, int expectedOffset)
{
View view = new ()
{
diff --git a/UnitTests/View/MouseTests.cs b/UnitTests/View/MouseTests.cs
index e7e0fc5d9e..e03090a3dd 100644
--- a/UnitTests/View/MouseTests.cs
+++ b/UnitTests/View/MouseTests.cs
@@ -378,7 +378,7 @@ public void WantContinuousButtonPressed_False_Button_Press_Release_DoesNotClick
Assert.Equal (0, clickedCount);
me.Handled = false;
- me.Flags =clicked;
+ me.Flags = clicked;
view.NewMouseEvent (me);
Assert.Equal (1, clickedCount);
@@ -387,11 +387,11 @@ public void WantContinuousButtonPressed_False_Button_Press_Release_DoesNotClick
[Theory]
- [InlineData (MouseFlags.Button1Pressed, MouseFlags.Button1Released, MouseFlags.Button1Clicked)]
- [InlineData (MouseFlags.Button2Pressed, MouseFlags.Button2Released, MouseFlags.Button2Clicked)]
- [InlineData (MouseFlags.Button3Pressed, MouseFlags.Button3Released, MouseFlags.Button3Clicked)]
- [InlineData (MouseFlags.Button4Pressed, MouseFlags.Button4Released, MouseFlags.Button4Clicked)]
- public void WantContinuousButtonPressed_True_Button_Clicked_Clicks (MouseFlags pressed, MouseFlags released, MouseFlags clicked)
+ [InlineData (MouseFlags.Button1Clicked)]
+ [InlineData (MouseFlags.Button2Clicked)]
+ [InlineData (MouseFlags.Button3Clicked)]
+ [InlineData (MouseFlags.Button4Clicked)]
+ public void WantContinuousButtonPressed_True_Button_Clicked_Clicks (MouseFlags clicked)
{
var me = new MouseEvent ();
@@ -405,7 +405,7 @@ public void WantContinuousButtonPressed_True_Button_Clicked_Clicks (MouseFlags p
var clickedCount = 0;
view.MouseClick += (s, e) => clickedCount++;
-
+
me.Flags = clicked;
view.NewMouseEvent (me);
Assert.Equal (1, clickedCount);
@@ -414,11 +414,11 @@ public void WantContinuousButtonPressed_True_Button_Clicked_Clicks (MouseFlags p
}
[Theory]
- [InlineData (MouseFlags.Button1Pressed, MouseFlags.Button1Released, MouseFlags.Button1Clicked)]
- [InlineData (MouseFlags.Button2Pressed, MouseFlags.Button2Released, MouseFlags.Button2Clicked)]
- [InlineData (MouseFlags.Button3Pressed, MouseFlags.Button3Released, MouseFlags.Button3Clicked)]
- [InlineData (MouseFlags.Button4Pressed, MouseFlags.Button4Released, MouseFlags.Button4Clicked)]
- public void WantContinuousButtonPressed_True_Button_Press_Release_Clicks (MouseFlags pressed, MouseFlags released, MouseFlags clicked)
+ [InlineData (MouseFlags.Button1Pressed, MouseFlags.Button1Released)]
+ [InlineData (MouseFlags.Button2Pressed, MouseFlags.Button2Released)]
+ [InlineData (MouseFlags.Button3Pressed, MouseFlags.Button3Released)]
+ [InlineData (MouseFlags.Button4Pressed, MouseFlags.Button4Released)]
+ public void WantContinuousButtonPressed_True_Button_Press_Release_Clicks (MouseFlags pressed, MouseFlags released)
{
var me = new MouseEvent ();