Skip to content

Commit

Permalink
Merge pull request gui-cs#3459 from tig/v2_3453-LayoutSubViews-Conten…
Browse files Browse the repository at this point in the history
…tSize

Fixes gui-cs#3453. `LayoutSubviews` should use `ContentSize`
  • Loading branch information
tig authored May 8, 2024
2 parents febf267 + 6d047e0 commit f3ed172
Show file tree
Hide file tree
Showing 11 changed files with 99 additions and 109 deletions.
6 changes: 4 additions & 2 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }}'

Expand Down
2 changes: 1 addition & 1 deletion Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -833,7 +833,7 @@ bool IsButtonClickedOrDoubleClicked (MouseFlags flag)
/// <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);
Expand Down
10 changes: 4 additions & 6 deletions Terminal.Gui/ConsoleDrivers/WindowsDriver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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 ()
{
Expand All @@ -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)
{
Expand Down Expand Up @@ -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 ();
}
Expand Down
3 changes: 2 additions & 1 deletion Terminal.Gui/Drawing/Justification.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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; }
Expand All @@ -118,6 +118,7 @@ public int [] Justify (int [] sizes)
/// </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)
Expand Down
2 changes: 1 addition & 1 deletion Terminal.Gui/Text/TextFormatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -662,7 +662,7 @@ public Size FormatAndGetSize ()
/// <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>
Expand Down
9 changes: 5 additions & 4 deletions Terminal.Gui/View/Layout/ViewLayout.cs
Original file line number Diff line number Diff line change
Expand Up @@ -670,9 +670,10 @@ public virtual void LayoutSubviews ()

CheckDimAuto ();

LayoutAdornments ();
var contentSize = ContentSize.GetValueOrDefault ();
OnLayoutStarted (new (contentSize));

OnLayoutStarted (new (ContentSize.GetValueOrDefault ()));
LayoutAdornments ();

SetTextFormatterSize ();

Expand All @@ -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.
Expand All @@ -699,7 +700,7 @@ public virtual void LayoutSubviews ()

LayoutNeeded = false;

OnLayoutComplete (new (ContentSize.GetValueOrDefault ()));
OnLayoutComplete (new (contentSize));
}

private void LayoutSubview (View v, Size contentSize)
Expand Down
1 change: 1 addition & 0 deletions Terminal.sln.DotSettings
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
11 changes: 4 additions & 7 deletions UnitTests/View/FindDeepestViewTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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
Expand All @@ -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)
{
Expand Down Expand Up @@ -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!));
}
}
123 changes: 61 additions & 62 deletions UnitTests/View/Layout/LayoutTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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 ();
}
}
17 changes: 4 additions & 13 deletions UnitTests/View/Layout/ViewportTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down Expand Up @@ -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 ()
{
Expand Down
24 changes: 12 additions & 12 deletions UnitTests/View/MouseTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);

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

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

Expand Down

0 comments on commit f3ed172

Please sign in to comment.