diff --git a/Terminal.Gui/Views/IListDataSource.cs b/Terminal.Gui/Views/IListDataSource.cs new file mode 100644 index 000000000..981642f0b --- /dev/null +++ b/Terminal.Gui/Views/IListDataSource.cs @@ -0,0 +1,63 @@ +#nullable enable +using System.Collections; +using System.Collections.Specialized; + +namespace Terminal.Gui; + +/// Implement to provide custom rendering for a . +public interface IListDataSource : IDisposable +{ + /// + /// Event to raise when an item is added, removed, or moved, or the entire list is refreshed. + /// + event NotifyCollectionChangedEventHandler CollectionChanged; + + /// Returns the number of elements to display + int Count { get; } + + /// Returns the maximum length of elements to display + int Length { get; } + + /// + /// Allow suspending the event from being invoked, + /// if , otherwise is . + /// + bool SuspendCollectionChangedEvent { get; set; } + + /// Should return whether the specified item is currently marked. + /// , if marked, otherwise. + /// Item index. + bool IsMarked (int item); + + /// This method is invoked to render a specified item, the method should cover the entire provided width. + /// The render. + /// The list view to render. + /// Describes whether the item being rendered is currently selected by the user. + /// The index of the item to render, zero for the first item and so on. + /// The column where the rendering will start + /// The line where the rendering will be done. + /// The width that must be filled out. + /// The index of the string to be displayed. + /// + /// The default color will be set before this method is invoked, and will be based on whether the item is selected + /// or not. + /// + void Render ( + ListView listView, + bool selected, + int item, + int col, + int line, + int width, + int start = 0 + ); + + /// Flags the item as marked. + /// Item index. + /// If set to value. + void SetMark (int item, bool value); + + /// Return the source as IList. + /// + IList ToList (); +} diff --git a/Terminal.Gui/Views/ListView.cs b/Terminal.Gui/Views/ListView.cs index 4f8b17803..efb6a9e51 100644 --- a/Terminal.Gui/Views/ListView.cs +++ b/Terminal.Gui/Views/ListView.cs @@ -1,68 +1,9 @@ using System.Collections; using System.Collections.ObjectModel; using System.Collections.Specialized; -using static Terminal.Gui.SpinnerStyle; namespace Terminal.Gui; -/// Implement to provide custom rendering for a . -public interface IListDataSource : IDisposable -{ - /// - /// Event to raise when an item is added, removed, or moved, or the entire list is refreshed. - /// - event NotifyCollectionChangedEventHandler CollectionChanged; - - /// Returns the number of elements to display - int Count { get; } - - /// Returns the maximum length of elements to display - int Length { get; } - - /// - /// Allow suspending the event from being invoked, - /// if , otherwise is . - /// - bool SuspendCollectionChangedEvent { get; set; } - - /// Should return whether the specified item is currently marked. - /// , if marked, otherwise. - /// Item index. - bool IsMarked (int item); - - /// This method is invoked to render a specified item, the method should cover the entire provided width. - /// The render. - /// The list view to render. - /// Describes whether the item being rendered is currently selected by the user. - /// The index of the item to render, zero for the first item and so on. - /// The column where the rendering will start - /// The line where the rendering will be done. - /// The width that must be filled out. - /// The index of the string to be displayed. - /// - /// The default color will be set before this method is invoked, and will be based on whether the item is selected - /// or not. - /// - void Render ( - ListView listView, - bool selected, - int item, - int col, - int line, - int width, - int start = 0 - ); - - /// Flags the item as marked. - /// Item index. - /// If set to value. - void SetMark (int item, bool value); - - /// Return the source as IList. - /// - IList ToList (); -} - /// /// ListView renders a scrollable list of data where each item can be activated to perform an /// action. @@ -200,7 +141,7 @@ public class ListView : View, IDesignable return !SetFocus (); }); - AddCommand (Command.SelectAll, (ctx) => MarkAll((bool)ctx.KeyBinding?.Context!)); + AddCommand (Command.SelectAll, (ctx) => MarkAll ((bool)ctx.KeyBinding?.Context!)); // Default keybindings for all ListViews KeyBindings.Add (Key.CursorUp, Command.Up); @@ -353,7 +294,7 @@ public class ListView : View, IDesignable SetContentSize (new Size (_source?.Length ?? Viewport.Width, _source?.Count ?? Viewport.Width)); if (IsInitialized) { - // Viewport = Viewport with { Y = 0 }; + // Viewport = Viewport with { Y = 0 }; } KeystrokeNavigator.Collection = _source?.ToList (); @@ -453,11 +394,11 @@ public class ListView : View, IDesignable /// Ensures the selected item is always visible on the screen. public void EnsureSelectedItemVisible () { + // TODO: This check is not needed. if (SuperView?.IsInitialized == true) { - if (_selected < Viewport.Y) + if (_selected <= Viewport.Y) { - // TODO: The Max check here is not needed because, by default, Viewport enforces staying w/in ContentArea (View.ScrollSettings). Viewport = Viewport with { Y = _selected }; } else if (Viewport.Height > 0 && _selected >= Viewport.Y + Viewport.Height) @@ -485,7 +426,7 @@ public class ListView : View, IDesignable return Source.IsMarked (SelectedItem); } - // BUGBUG: Shouldn't this retrn Source.IsMarked (SelectedItem) + // BUGBUG: Shouldn't this return Source.IsMarked (SelectedItem) return false; } @@ -515,7 +456,10 @@ public class ListView : View, IDesignable if (me.Flags == MouseFlags.WheeledDown) { - ScrollVertical (1); + if (Viewport.Y + Viewport.Height < GetContentSize ().Height) + { + ScrollVertical (1); + } return true; } @@ -529,7 +473,10 @@ public class ListView : View, IDesignable if (me.Flags == MouseFlags.WheeledRight) { - ScrollHorizontal (1); + if (Viewport.X + Viewport.Width < GetContentSize ().Width) + { + ScrollHorizontal (1); + } return true; } @@ -1209,7 +1156,7 @@ public class ListWrapper : IListDataSource, IDisposable var maxLength = 0; - for (var i = 0; i < _source.Count; i++) + for (var i = 0; i < _source!.Count; i++) { object t = _source [i]; int l; diff --git a/UICatalog/Scenarios/CharacterMap/CharMap.cs b/UICatalog/Scenarios/CharacterMap/CharMap.cs index 6f4093a36..8b7d283ad 100644 --- a/UICatalog/Scenarios/CharacterMap/CharMap.cs +++ b/UICatalog/Scenarios/CharacterMap/CharMap.cs @@ -472,7 +472,10 @@ public class CharMap : View, IDesignable { if (mouseEvent.Flags == MouseFlags.WheeledDown) { - ScrollVertical (1); + if (Viewport.Y + Viewport.Height - HEADER_HEIGHT < GetContentSize ().Height) + { + ScrollVertical (1); + } return mouseEvent.Handled = true; } @@ -484,7 +487,10 @@ public class CharMap : View, IDesignable if (mouseEvent.Flags == MouseFlags.WheeledRight) { - ScrollHorizontal (1); + if (Viewport.X + Viewport.Width < GetContentSize ().Width) + { + ScrollHorizontal (1); + } return mouseEvent.Handled = true; } @@ -496,7 +502,7 @@ public class CharMap : View, IDesignable return false; } - + private void Handle_MouseClick (object? sender, MouseEventArgs me) { if (me.Flags != MouseFlags.ReportMousePosition && me.Flags != MouseFlags.Button1Clicked && me.Flags != MouseFlags.Button1DoubleClicked)