From df29c3caaedd937179d9af93d69adb10553dde1f Mon Sep 17 00:00:00 2001 From: Miguel de Icaza Date: Tue, 6 Feb 2018 22:41:55 -0500 Subject: [PATCH] Some work on ListView --- Terminal.Gui/Terminal.Gui.csproj | 6 +- Terminal.Gui/Views/ListView.cs | 127 ++++++++++++++++++++++++++++++- Terminal.Gui/packages.config | 2 +- 3 files changed, 130 insertions(+), 5 deletions(-) diff --git a/Terminal.Gui/Terminal.Gui.csproj b/Terminal.Gui/Terminal.Gui.csproj index cc5419151..099f29d2e 100644 --- a/Terminal.Gui/Terminal.Gui.csproj +++ b/Terminal.Gui/Terminal.Gui.csproj @@ -31,13 +31,13 @@ - - ..\packages\NStack.Core.0.7.0\lib\netstandard1.5\NStack.dll - ..\packages\System.ValueTuple.4.4.0\lib\net461\System.ValueTuple.dll + + ..\packages\NStack.Core.0.8.0\lib\netstandard1.5\NStack.dll + diff --git a/Terminal.Gui/Views/ListView.cs b/Terminal.Gui/Views/ListView.cs index 587c20c44..522ab3ef9 100644 --- a/Terminal.Gui/Views/ListView.cs +++ b/Terminal.Gui/Views/ListView.cs @@ -12,15 +12,140 @@ using NStack; namespace Terminal.Gui { public interface IListDataSource { int Count { get; } - + void Render (int item, int col, int line, int width); } /// /// ListView widget renders a list of data. /// + /// + /// public class ListView : View { + int top; + int selected; + + class ListWrapper : IListDataSource { + IList src; + public ListView Container; + public ConsoleDriver Driver; + + public ListWrapper (IList source) + { + this.src = source; + } + + public int Count => src.Count; + + void RenderUstr (ustring ustr, int col, int line, int width) + { + int byteLen = ustr.Length; + int used = 0; + for (int i = 0; i < byteLen;) { + (var rune, var size) = Utf8.DecodeRune (ustr, i, i - byteLen); + var count = Rune.ColumnWidth (rune); + if (used+count >= width) + break; + Driver.AddRune (rune); + used += count; + i += size; + } + for (; used < width; used++) { + Driver.AddRune (' '); + } + } + + public void Render (int item, int col, int line, int width) + { + Container.Move (col, line); + var t = src [item]; + if (t is ustring) { + RenderUstr (t as ustring, col, line, width); + } else if (t is string) { + RenderUstr (t as string, col, line, width); + } else + RenderUstr (((string)t).ToString (), col, line, width); + } + } + + IListDataSource source; + /// + /// Gets or sets the IListDataSource backing this view. + /// + /// The source. + public IListDataSource Source { + get => source; + set { + if (value == null) + throw new ArgumentNullException ("value"); + source = value; + top = 0; + selected = 0; + SetNeedsDisplay (); + } + } + + bool allowsMarking; + /// + /// Gets or sets a value indicating whether this allows items to be marked. + /// + /// true if allows marking elements of the list; otherwise, false. + public bool AllowsMarking { + get => allowsMarking; + set { + allowsMarking = value; + SetNeedsDisplay (); + } + } + + /// + /// Gets or sets the item that is displayed at the top of the listview + /// + /// The top item. + public int TopItem { + get => top; + set { + if (top < 0 || top >= source.Count) + throw new ArgumentException ("value"); + top = value; + SetNeedsDisplay (); + } + } + + /// + /// Gets or sets the currently selecteded item. + /// + /// The selected item. + public int SelectedItem { + get => selected; + set { + if (selected < 0 || selected >= source.Count) + throw new ArgumentException ("value"); + selected = value; + if (selected < top) + top = selected; + else if (selected >= top + Frame.Height) + top = selected; + } + } + + + static IListDataSource MakeWrapper (IList source) + { + return new ListWrapper (source); + } + + public ListView (Rect rect, IList source, (ustring title, int width) [] headers = null) : this (rect, MakeWrapper (source), headers) + { + ((ListWrapper)(Source)).Container = this; + ((ListWrapper)(Source)).Driver = Driver; + } + public ListView (Rect rect, IListDataSource source, (ustring title, int width) [] headers = null) : base (rect) { + if (source == null) + throw new ArgumentNullException (nameof (source)); + Source = source; } + } } diff --git a/Terminal.Gui/packages.config b/Terminal.Gui/packages.config index 62939e85c..c86d262a1 100644 --- a/Terminal.Gui/packages.config +++ b/Terminal.Gui/packages.config @@ -1,5 +1,5 @@  - + \ No newline at end of file