diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 000000000..2d4f2dce7 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,24 @@ +{ + "name": "Terminal.Gui Codespace", + "image": "mcr.microsoft.com/vscode/devcontainers/dotnet:0.201.7-5.0", + "settings": { + "terminal.integrated.defaultProfile.linux": "pwsh" + }, + "extensions": [ + "eamodio.gitlens", + "ms-dotnettools.csharp", + "VisualStudioExptTeam.vscodeintellicode", + "ms-vscode.powershell", + "cschleiden.vscode-github-actions", + "redhat.vscode-yaml", + "bierner.markdown-preview-github-styles", + "ban.spellright", + "jmrog.vscode-nuget-package-manager", + "coenraads.bracket-pair-colorizer", + "vscode-icons-team.vscode-icons", + "editorconfig.editorconfig" + ], + "postCreateCommand": "dotnet restore && dotnet build --configuration Release --no-restore && dotnet test --configuration Debug --no-restore --verbosity normal --collect:'XPlat Code Coverage' --settings UnitTests/coverlet.runsettings", +} + +// Built with ❤ by [Pipeline Foundation](https://pipeline.foundation) diff --git a/Terminal.Gui/Core/View.cs b/Terminal.Gui/Core/View.cs index 4104b2a59..f721feedf 100644 --- a/Terminal.Gui/Core/View.cs +++ b/Terminal.Gui/Core/View.cs @@ -1988,8 +1988,10 @@ namespace Terminal.Gui { get => textFormatter.Text; set { textFormatter.Text = value; - ResizeView (autoSize); - if (textFormatter.Size != Bounds.Size) { + var canResize = ResizeView (autoSize); + if (canResize && textFormatter.Size != Bounds.Size) { + Bounds = new Rect (new Point (Bounds.X, Bounds.Y), textFormatter.Size); + } else if (!canResize && textFormatter.Size != Bounds.Size) { textFormatter.Size = Bounds.Size; } SetNeedsLayout (); @@ -2085,7 +2087,9 @@ namespace Terminal.Gui { var aSize = autoSize; Rect nBounds = TextFormatter.CalcRect (Bounds.X, Bounds.Y, Text, textFormatter.Direction); - + if (textFormatter.Size != nBounds.Size) { + textFormatter.Size = nBounds.Size; + } if ((textFormatter.Size != Bounds.Size || textFormatter.Size != nBounds.Size) && (((width == null || width is Dim.DimAbsolute) && (Bounds.Width == 0 || autoSize && Bounds.Width != nBounds.Width)) diff --git a/Terminal.Gui/Views/ScrollBarView.cs b/Terminal.Gui/Views/ScrollBarView.cs index 1b7a15205..c89070783 100644 --- a/Terminal.Gui/Views/ScrollBarView.cs +++ b/Terminal.Gui/Views/ScrollBarView.cs @@ -298,11 +298,15 @@ namespace Terminal.Gui { } var pending = CheckBothScrollBars (this); - CheckBothScrollBars (otherScrollBarView, pending); + if (otherScrollBarView != null) { + CheckBothScrollBars (otherScrollBarView, pending); + } SetWidthHeight (); SetRelativeLayout (Bounds); - OtherScrollBarView.SetRelativeLayout (OtherScrollBarView.Bounds); + if (otherScrollBarView != null) { + OtherScrollBarView.SetRelativeLayout (OtherScrollBarView.Bounds); + } if (showBothScrollIndicator) { if (contentBottomRightCorner != null) { @@ -321,7 +325,7 @@ namespace Terminal.Gui { if (showScrollIndicator) { Redraw (Bounds); } - if (otherScrollBarView.showScrollIndicator) { + if (otherScrollBarView != null && otherScrollBarView.showScrollIndicator) { otherScrollBarView.Redraw (otherScrollBarView.Bounds); } } diff --git a/UnitTests/GraphViewTests.cs b/UnitTests/GraphViewTests.cs index 0dde704a1..51273a981 100644 --- a/UnitTests/GraphViewTests.cs +++ b/UnitTests/GraphViewTests.cs @@ -1382,6 +1382,56 @@ namespace Terminal.Gui.Views { // Shutdown must be called to safely clean up Application if Init has been called Application.Shutdown (); } + + [Theory] + [InlineData (true)] + [InlineData (false)] + public void LabelChangeText_RendersCorrectly (bool useFill) + { + var driver = new FakeDriver (); + Application.Init (driver, new FakeMainLoop (() => FakeConsole.ReadKey (true))); + driver.Init (() => { }); + + // create a wide window + var mount = new View () { + Width = 100, + Height = 100 + }; + + try { + // Create a label with a short text + var lbl1 = new Label ("ff"); + + // Specify that the label should be very wide + if (useFill) { + lbl1.Width = Dim.Fill (); + } else { + lbl1.Width = 100; + } + + //put label into view + mount.Add (lbl1); + + // render view + lbl1.ColorScheme = new ColorScheme (); + Assert.Equal (1, lbl1.Height); + mount.Redraw (mount.Bounds); + + // should have the initial text + GraphViewTests.AssertDriverContentsAre ("ff", null); + + // change the text and redraw + lbl1.Text = "ff1234"; + mount.Redraw (mount.Bounds); + + // should have the new text rendered + GraphViewTests.AssertDriverContentsAre ("ff1234", null); + + + } finally { + Application.Shutdown (); + } + } } public class AxisIncrementToRenderTests { diff --git a/UnitTests/ScrollBarViewTests.cs b/UnitTests/ScrollBarViewTests.cs index 7cda55699..36fccd7c8 100644 --- a/UnitTests/ScrollBarViewTests.cs +++ b/UnitTests/ScrollBarViewTests.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using Xunit; @@ -6,7 +7,7 @@ using Xunit; namespace Terminal.Gui.Views { public class ScrollBarViewTests { - // This class enables test functions annoated with the [InitShutdown] attribute + // This class enables test functions annotated with the [InitShutdown] attribute // to have a function called before the test function is called and after. // // This is necessary because a) Application is a singleton and Init/Shutdown must be called @@ -55,7 +56,7 @@ namespace Terminal.Gui.Views { private static HostView _hostView; private ScrollBarView _scrollBar; - private bool _added; + private bool _added; private void AddHandlers () { @@ -444,5 +445,75 @@ namespace Terminal.Gui.Views { Assert.Equal ("Dim.Absolute(1)", _scrollBar.OtherScrollBarView.Height.ToString ()); Assert.Equal (1, _scrollBar.OtherScrollBarView.Bounds.Height); } + + [Fact] + public void Constructor_ShowBothScrollIndicator_False_Refresh_Does_Not_Throws_An_Object_Null_Exception () + { + var exception = Record.Exception (() => { + Application.Init (new FakeDriver (), new FakeMainLoop (() => FakeConsole.ReadKey (true))); + + var top = Application.Top; + + var win = new Window () { + X = 0, + Y = 0, + Width = Dim.Fill (), + Height = Dim.Fill () + }; + + List source = new List (); + + for (int i = 0; i < 50; i++) { + source.Add ($"item {i}"); + } + + var listView = new ListView (source) { + X = 0, + Y = 0, + Width = Dim.Fill (), + Height = Dim.Fill () + }; + win.Add (listView); + + var newScrollBarView = new ScrollBarView (listView, true, false) { + KeepContentAlwaysInViewport = true + }; + win.Add (newScrollBarView); + + newScrollBarView.ChangedPosition += () => { + listView.TopItem = newScrollBarView.Position; + if (listView.TopItem != newScrollBarView.Position) { + newScrollBarView.Position = listView.TopItem; + } + Assert.Equal (newScrollBarView.Position, listView.TopItem); + listView.SetNeedsDisplay (); + }; + + listView.DrawContent += (e) => { + newScrollBarView.Size = listView.Source.Count - 1; + Assert.Equal (newScrollBarView.Size, listView.Source.Count); + newScrollBarView.Position = listView.TopItem; + Assert.Equal (newScrollBarView.Position, listView.TopItem); + newScrollBarView.Refresh (); + }; + + top.Ready += () => { + newScrollBarView.Position = 45; + Assert.Equal (newScrollBarView.Position, newScrollBarView.Size - listView.TopItem + (listView.TopItem - listView.Bounds.Height)); + Assert.Equal (newScrollBarView.Position, listView.TopItem); + Assert.Equal (27, newScrollBarView.Position); + Assert.Equal (27, listView.TopItem); + Application.RequestStop (); + }; + + top.Add (win); + + Application.Run (); + + Application.Shutdown (); + + }); + Assert.Null (exception); + } } } diff --git a/UnitTests/UnitTests.csproj b/UnitTests/UnitTests.csproj index cf72fc76f..7c9428e50 100644 --- a/UnitTests/UnitTests.csproj +++ b/UnitTests/UnitTests.csproj @@ -16,7 +16,7 @@ - +