Browse Source

Merge pull request #3459 from tig/v2_3453-LayoutSubViews-ContentSize

Fixes #3453. `LayoutSubviews` should use `ContentSize`
Tig 1 year ago
parent
commit
f3ed17227d

+ 4 - 2
.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 }}' 
 

+ 1 - 1
Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs

@@ -833,7 +833,7 @@ internal class CursesDriver : ConsoleDriver
     /// <returns></returns>
     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);

+ 4 - 6
Terminal.Gui/ConsoleDrivers/WindowsDriver.cs

@@ -2344,11 +2344,9 @@ internal class WindowsMainLoop : IMainLoopDriver
 
 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 @@ internal class WindowsClipboard : ClipboardBase
                 return string.Empty;
             }
 
-            nint handle = GetClipboardData (_cfUnicodeText);
+            nint handle = GetClipboardData (CF_UNICODE_TEXT);
 
             if (handle == nint.Zero)
             {
@@ -2431,7 +2429,7 @@ internal class WindowsClipboard : ClipboardBase
                 GlobalUnlock (target);
             }
 
-            if (SetClipboardData (_cfUnicodeText, hGlobal) == default (nint))
+            if (SetClipboardData (CF_UNICODE_TEXT, hGlobal) == default (nint))
             {
                 ThrowWin32 ();
             }

+ 2 - 1
Terminal.Gui/Drawing/Justification.cs

@@ -96,7 +96,7 @@ public class Justifier
     public int ContainerSize { get; set; }
 
     /// <summary>
-    ///     Gets or sets whether <see cref="Justify"/> puts a space is placed between items. Default is <see langword="false"/>. If <see langword="true"/>, a space will be
+    ///     Gets or sets whether <see cref="Justify(int[])"/> puts a space is placed between items. Default is <see langword="false"/>. If <see langword="true"/>, a space will be
     ///     placed between each item, which is useful for justifying text.
     /// </summary>
     public bool PutSpaceBetweenItems { get; set; }
@@ -118,6 +118,7 @@ public class Justifier
     /// </summary>
     /// <param name="sizes">The sizes of the items to justify.</param>
     /// <param name="justification">The justification style.</param>
+    /// <param name="putSpaceBetweenItems"></param>
     /// <param name="containerSize">The size of the container.</param>
     /// <returns>The locations of the items, from left to right.</returns>
     public static int [] Justify (Justification justification, bool putSpaceBetweenItems, int containerSize, int [] sizes)

+ 1 - 1
Terminal.Gui/Text/TextFormatter.cs

@@ -662,7 +662,7 @@ public class TextFormatter
     /// <remarks>
     ///     <para>
     ///         If the text needs to be formatted (if <see cref="NeedsFormat"/> is <see langword="true"/>)
-    ///         <see cref="Format(string, int, bool, bool, bool, int, TextDirection, bool)"/> will be called and upon return
+    ///         <see cref="Format()"/> will be called and upon return
     ///         <see cref="NeedsFormat"/> will be <see langword="false"/>.
     ///     </para>
     ///     <para>

+ 5 - 4
Terminal.Gui/View/Layout/ViewLayout.cs

@@ -670,9 +670,10 @@ public partial class View
 
         CheckDimAuto ();
 
-        LayoutAdornments ();
+        var contentSize = ContentSize.GetValueOrDefault ();
+        OnLayoutStarted (new (contentSize));
 
-        OnLayoutStarted (new (ContentSize.GetValueOrDefault ()));
+        LayoutAdornments ();
 
         SetTextFormatterSize ();
 
@@ -684,7 +685,7 @@ public partial class View
 
         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 partial class View
 
         LayoutNeeded = false;
 
-        OnLayoutComplete (new (ContentSize.GetValueOrDefault ()));
+        OnLayoutComplete (new (contentSize));
     }
 
     private void LayoutSubview (View v, Size contentSize)

+ 1 - 0
Terminal.sln.DotSettings

@@ -387,6 +387,7 @@
 	<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PublicFields/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" /&gt;</s:String>
 	<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=StaticReadonly/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" /&gt;</s:String>
 	<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=15b5b1f1_002D457c_002D4ca6_002Db278_002D5615aedc07d3/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Static" AccessRightKinds="Private" Description="Static readonly fields (private)"&gt;&lt;ElementKinds&gt;&lt;Kind Name="READONLY_FIELD" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" /&gt;&lt;/Policy&gt;</s:String>
+	<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=236f7aa5_002D7b06_002D43ca_002Dbf2a_002D9b31bfcff09a/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Any" AccessRightKinds="Private" Description="Constant fields (private)"&gt;&lt;ElementKinds&gt;&lt;Kind Name="CONSTANT_FIELD" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AA_BB" /&gt;&lt;/Policy&gt;</s:String>
 	<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=53eecf85_002Dd821_002D40e8_002Dac97_002Dfdb734542b84/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Instance" AccessRightKinds="Protected, ProtectedInternal, Internal, Public, PrivateProtected" Description="Instance fields (not private)"&gt;&lt;ElementKinds&gt;&lt;Kind Name="FIELD" /&gt;&lt;Kind Name="READONLY_FIELD" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" /&gt;&lt;/Policy&gt;</s:String>
 	<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=70345118_002D4b40_002D4ece_002D937c_002Dbbeb7a0b2e70/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Static" AccessRightKinds="Protected, ProtectedInternal, Internal, Public, PrivateProtected" Description="Static fields (not private)"&gt;&lt;ElementKinds&gt;&lt;Kind Name="FIELD" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" /&gt;&lt;/Policy&gt;</s:String>
 	<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=c873eafb_002Dd57f_002D481d_002D8c93_002D77f6863c2f88/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Static" AccessRightKinds="Protected, ProtectedInternal, Internal, Public, PrivateProtected" Description="Static readonly fields (not private)"&gt;&lt;ElementKinds&gt;&lt;Kind Name="READONLY_FIELD" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" /&gt;&lt;/Policy&gt;</s:String>

+ 4 - 7
UnitTests/View/FindDeepestViewTests.cs

@@ -8,7 +8,7 @@ namespace Terminal.Gui.ViewTests;
 /// Tests View.FindDeepestView
 /// </summary>
 /// <param name="output"></param>
-public class FindDeepestViewTests (ITestOutputHelper output)
+public class FindDeepestViewTests ()
 {
     [Theory]
     [InlineData (0, 0, 0, 0, 0, -1, -1, null)]
@@ -249,7 +249,6 @@ public class FindDeepestViewTests (ITestOutputHelper output)
 
     [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 class FindDeepestViewTests (ITestOutputHelper output)
     }
 
     [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 class FindDeepestViewTests (ITestOutputHelper output)
         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 class FindDeepestViewTests (ITestOutputHelper output)
     [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 class FindDeepestViewTests (ITestOutputHelper output)
         start.Add (subviews [0]);
 
         var found = View.FindDeepestView (start, testX, testY);
-        Assert.Equal (expectedSubViewFound, subviews.IndexOf (found));
+        Assert.Equal (expectedSubViewFound, subviews.IndexOf (found!));
     }
 }

+ 61 - 62
UnitTests/View/Layout/LayoutTests.cs

@@ -115,66 +115,65 @@ public class LayoutTests (ITestOutputHelper output)
         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 ();
+    }
 }

+ 4 - 13
UnitTests/View/Layout/ViewportTests.cs

@@ -248,7 +248,7 @@ public class ViewportTests (ITestOutputHelper output)
         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 class ViewportTests (ITestOutputHelper output)
     }
 
     [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 ()
         {

+ 12 - 12
UnitTests/View/MouseTests.cs

@@ -378,7 +378,7 @@ public class MouseTests (ITestOutputHelper output) : TestsAllViews
         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 class MouseTests (ITestOutputHelper output) : TestsAllViews
 
 
     [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 class MouseTests (ITestOutputHelper output) : TestsAllViews
         var clickedCount = 0;
 
         view.MouseClick += (s, e) => clickedCount++;
-        
+
         me.Flags = clicked;
         view.NewMouseEvent (me);
         Assert.Equal (1, clickedCount);
@@ -414,11 +414,11 @@ public class MouseTests (ITestOutputHelper output) : TestsAllViews
     }
 
     [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 ();