mirror of
https://github.com/gui-cs/Terminal.Gui.git
synced 2025-12-26 15:57:56 +01:00
Some work on ListView
This commit is contained in:
@@ -31,13 +31,13 @@
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="Mono.Posix" />
|
||||
<Reference Include="NStack">
|
||||
<HintPath>..\packages\NStack.Core.0.7.0\lib\netstandard1.5\NStack.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.ValueTuple">
|
||||
<HintPath>..\packages\System.ValueTuple.4.4.0\lib\net461\System.ValueTuple.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="mscorlib" />
|
||||
<Reference Include="NStack">
|
||||
<HintPath>..\packages\NStack.Core.0.8.0\lib\netstandard1.5\NStack.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="Properties\" />
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ListView widget renders a list of data.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// </remarks>
|
||||
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;
|
||||
/// <summary>
|
||||
/// Gets or sets the IListDataSource backing this view.
|
||||
/// </summary>
|
||||
/// <value>The source.</value>
|
||||
public IListDataSource Source {
|
||||
get => source;
|
||||
set {
|
||||
if (value == null)
|
||||
throw new ArgumentNullException ("value");
|
||||
source = value;
|
||||
top = 0;
|
||||
selected = 0;
|
||||
SetNeedsDisplay ();
|
||||
}
|
||||
}
|
||||
|
||||
bool allowsMarking;
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this <see cref="T:Terminal.Gui.ListView"/> allows items to be marked.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if allows marking elements of the list; otherwise, <c>false</c>.</value>
|
||||
public bool AllowsMarking {
|
||||
get => allowsMarking;
|
||||
set {
|
||||
allowsMarking = value;
|
||||
SetNeedsDisplay ();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the item that is displayed at the top of the listview
|
||||
/// </summary>
|
||||
/// <value>The top item.</value>
|
||||
public int TopItem {
|
||||
get => top;
|
||||
set {
|
||||
if (top < 0 || top >= source.Count)
|
||||
throw new ArgumentException ("value");
|
||||
top = value;
|
||||
SetNeedsDisplay ();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the currently selecteded item.
|
||||
/// </summary>
|
||||
/// <value>The selected item.</value>
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="NStack.Core" version="0.7.0" targetFramework="net461" />
|
||||
<package id="NStack.Core" version="0.8.0" targetFramework="net461" />
|
||||
<package id="System.ValueTuple" version="4.4.0" targetFramework="net461" />
|
||||
</packages>
|
||||
Reference in New Issue
Block a user