diff --git a/Sharprompt.Tests/PropertyMetadataTests.cs b/Sharprompt.Tests/PropertyMetadataTests.cs index 50114c4..da6799a 100644 --- a/Sharprompt.Tests/PropertyMetadataTests.cs +++ b/Sharprompt.Tests/PropertyMetadataTests.cs @@ -17,7 +17,7 @@ public void Basic() var metadata = PropertyMetadataFactory.Create(new BasicModel()); Assert.NotNull(metadata); - Assert.Equal(1, metadata.Count); + Assert.Single(metadata); Assert.Equal(typeof(string), metadata[0].Type); Assert.Equal(FormType.Input, metadata[0].DetermineFormType()); @@ -27,7 +27,7 @@ public void Basic() Assert.False(metadata[0].IsCollection); Assert.Null(metadata[0].DefaultValue); Assert.Null(metadata[0].Order); - Assert.Equal(1, metadata[0].Validators.Count); + Assert.Single(metadata[0].Validators); } [Fact] @@ -36,7 +36,7 @@ public void Basic_DefaultValue() var metadata = PropertyMetadataFactory.Create(new BasicModel { Value = "sample" }); Assert.NotNull(metadata); - Assert.Equal(1, metadata.Count); + Assert.Single(metadata); Assert.Equal(typeof(string), metadata[0].Type); Assert.Equal("sample", metadata[0].DefaultValue); @@ -182,7 +182,7 @@ public void BindIgnore() var metadata = PropertyMetadataFactory.Create(new BindIgnoreModel()); Assert.NotNull(metadata); - Assert.Equal(1, metadata.Count); + Assert.Single(metadata); } [Fact] @@ -191,7 +191,7 @@ public void ReadOnly() var metadata = PropertyMetadataFactory.Create(new ReadOnlyModel()); Assert.NotNull(metadata); - Assert.Equal(1, metadata.Count); + Assert.Single(metadata); } [Fact] diff --git a/Sharprompt.Tests/Sharprompt.Tests.csproj b/Sharprompt.Tests/Sharprompt.Tests.csproj index 2afb8cf..d1cc8fd 100644 --- a/Sharprompt.Tests/Sharprompt.Tests.csproj +++ b/Sharprompt.Tests/Sharprompt.Tests.csproj @@ -7,9 +7,9 @@ - - - + + + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/Sharprompt/Drivers/DefaultConsoleDriver.cs b/Sharprompt/Drivers/DefaultConsoleDriver.cs index 7337a30..3da5577 100644 --- a/Sharprompt/Drivers/DefaultConsoleDriver.cs +++ b/Sharprompt/Drivers/DefaultConsoleDriver.cs @@ -76,7 +76,7 @@ public ConsoleKeyInfo ReadKey() { var keyInfo = Console.ReadKey(true); - if (keyInfo.Key == ConsoleKey.C && keyInfo.Modifiers == ConsoleModifiers.Control) + if (keyInfo is { Key: ConsoleKey.C, Modifiers: ConsoleModifiers.Control }) { CancellationCallback.Invoke(); } diff --git a/Sharprompt/Forms/FormBase.cs b/Sharprompt/Forms/FormBase.cs index 27c4484..b9090de 100644 --- a/Sharprompt/Forms/FormBase.cs +++ b/Sharprompt/Forms/FormBase.cs @@ -29,6 +29,8 @@ protected FormBase() protected Dictionary> KeyHandlerMaps { get; set; } = new(); + protected int Width => _consoleDriver.WindowWidth; + protected int Height => _consoleDriver.WindowHeight; public void Dispose() => _formRenderer.Dispose(); diff --git a/Sharprompt/Forms/MultiSelectForm.cs b/Sharprompt/Forms/MultiSelectForm.cs index 2c245fe..e5980dc 100644 --- a/Sharprompt/Forms/MultiSelectForm.cs +++ b/Sharprompt/Forms/MultiSelectForm.cs @@ -42,6 +42,8 @@ public MultiSelectForm(MultiSelectOptions options) protected override void InputTemplate(OffscreenBuffer offscreenBuffer) { + _paginator.UpdatePageSize(Math.Min(_options.PageSize, Height - 2)); + offscreenBuffer.WritePrompt(_options.Message); offscreenBuffer.Write(_paginator.FilterKeyword); diff --git a/Sharprompt/Forms/SelectForm.cs b/Sharprompt/Forms/SelectForm.cs index 43dba12..31f08b6 100644 --- a/Sharprompt/Forms/SelectForm.cs +++ b/Sharprompt/Forms/SelectForm.cs @@ -31,6 +31,8 @@ public SelectForm(SelectOptions options) protected override void InputTemplate(OffscreenBuffer offscreenBuffer) { + _paginator.UpdatePageSize(Math.Min(_options.PageSize, Height - 2)); + offscreenBuffer.WritePrompt(_options.Message); offscreenBuffer.Write(_paginator.FilterKeyword); diff --git a/Sharprompt/Internal/OffscreenBuffer.cs b/Sharprompt/Internal/OffscreenBuffer.cs index a4acae4..99efe56 100644 --- a/Sharprompt/Internal/OffscreenBuffer.cs +++ b/Sharprompt/Internal/OffscreenBuffer.cs @@ -74,24 +74,28 @@ public void RenderToConsole() _cursorBottom = _consoleDriver.CursorTop; - if (_pushedCursor is not null) + if (_pushedCursor is null) + { + return; + } + + var physicalLeft = _pushedCursor.Left % _consoleDriver.BufferWidth; + var physicalTop = _pushedCursor.Top + (_pushedCursor.Left / _consoleDriver.BufferWidth); + + var consoleTop = _cursorBottom - WrittenLineCount + physicalTop; + + if (_pushedCursor.Left > 0 && physicalLeft == 0) { - var physicalLeft = _pushedCursor.Left % _consoleDriver.BufferWidth; - var physicalTop = _pushedCursor.Top + (_pushedCursor.Left / _consoleDriver.BufferWidth); + _consoleDriver.WriteLine(); - var consoleTop = _cursorBottom - WrittenLineCount + physicalTop; - if (_pushedCursor.Left > 0 && physicalLeft == 0) + if (consoleTop == _consoleDriver.BufferHeight) { - _consoleDriver.WriteLine(); - if (consoleTop == _consoleDriver.BufferHeight) - { - _cursorBottom--; - consoleTop--; - } + _cursorBottom--; + consoleTop--; } - - _consoleDriver.SetCursorPosition(physicalLeft, consoleTop); } + + _consoleDriver.SetCursorPosition(physicalLeft, consoleTop); } public void ClearConsole(int cursorBottom, int writtenLineCount) diff --git a/Sharprompt/Internal/Paginator.cs b/Sharprompt/Internal/Paginator.cs index dd35123..c8f4cf3 100644 --- a/Sharprompt/Internal/Paginator.cs +++ b/Sharprompt/Internal/Paginator.cs @@ -18,9 +18,9 @@ public Paginator(IEnumerable items, int pageSize, Optional defaultValue, F } private readonly T[] _items; - private readonly int _pageSize; private readonly Func _textSelector; + private int _pageSize; private T[] _filteredItems = Array.Empty(); private int _selectedIndex = -1; @@ -94,11 +94,24 @@ public void UpdateFilter(string keyword) FilterKeyword = keyword; _selectedIndex = -1; - CurrentPage = 0; UpdateFilteredItems(); } + public void UpdatePageSize(int newPageSize) + { + if (_pageSize == newPageSize) + { + return; + } + + TryGetSelectedItem(out var selectedItem); + + _pageSize = newPageSize <= 0 ? _items.Length : Math.Min(newPageSize, _items.Length); + + InitializeDefaults(Optional.Create(selectedItem)); + } + public IEnumerator GetEnumerator() => (IEnumerator)_filteredItems.GetEnumerator(); IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); @@ -109,6 +122,11 @@ private void UpdateFilteredItems() .ToArray(); PageCount = (_filteredItems.Length - 1) / _pageSize + 1; + + if (CurrentPage >= PageCount) + { + CurrentPage = 0; + } } private void InitializeDefaults(Optional defaultValue) diff --git a/Sharprompt/Internal/RenderScope.cs b/Sharprompt/Internal/RenderScope.cs index a12e1d5..1992073 100644 --- a/Sharprompt/Internal/RenderScope.cs +++ b/Sharprompt/Internal/RenderScope.cs @@ -10,8 +10,8 @@ public RenderScope(OffscreenBuffer offscreenBuffer, IConsoleDriver consoleDriver { _offscreenBuffer = offscreenBuffer; _consoleDriver = consoleDriver; - _cursorBottom = cursorBottom; - _writtenLineCount = writtenLineCount; + _cursorBottom = Math.Min(cursorBottom, _consoleDriver.WindowHeight - 1); + _writtenLineCount = Math.Min(writtenLineCount, _consoleDriver.WindowHeight - 1); _offscreenBuffer.ClearBuffer(); }