|
@@ -63,6 +63,12 @@ namespace Terminal.Gui {
|
|
/// <param name="item">Item index.</param>
|
|
/// <param name="item">Item index.</param>
|
|
/// <param name="value">If set to <c>true</c> value.</param>
|
|
/// <param name="value">If set to <c>true</c> value.</param>
|
|
void SetMark (int item, bool value);
|
|
void SetMark (int item, bool value);
|
|
|
|
+
|
|
|
|
+ /// <summary>
|
|
|
|
+ /// Return the source as IList.
|
|
|
|
+ /// </summary>
|
|
|
|
+ /// <returns></returns>
|
|
|
|
+ IList ToList ();
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// <summary>
|
|
@@ -257,7 +263,7 @@ namespace Terminal.Gui {
|
|
/// Redraws the ListView
|
|
/// Redraws the ListView
|
|
/// </summary>
|
|
/// </summary>
|
|
/// <param name="region">Region.</param>
|
|
/// <param name="region">Region.</param>
|
|
- public override void Redraw(Rect region)
|
|
|
|
|
|
+ public override void Redraw (Rect region)
|
|
{
|
|
{
|
|
var current = ColorScheme.Focus;
|
|
var current = ColorScheme.Focus;
|
|
Driver.SetAttribute (current);
|
|
Driver.SetAttribute (current);
|
|
@@ -279,12 +285,12 @@ namespace Terminal.Gui {
|
|
Move (0, row);
|
|
Move (0, row);
|
|
if (source == null || item >= source.Count) {
|
|
if (source == null || item >= source.Count) {
|
|
for (int c = 0; c < f.Width; c++)
|
|
for (int c = 0; c < f.Width; c++)
|
|
- Driver.AddRune(' ');
|
|
|
|
|
|
+ Driver.AddRune (' ');
|
|
} else {
|
|
} else {
|
|
if (allowsMarking) {
|
|
if (allowsMarking) {
|
|
Driver.AddStr (source.IsMarked (item) ? (AllowsMultipleSelection ? "[x] " : "(o)") : (AllowsMultipleSelection ? "[ ] " : "( )"));
|
|
Driver.AddStr (source.IsMarked (item) ? (AllowsMultipleSelection ? "[x] " : "(o)") : (AllowsMultipleSelection ? "[ ] " : "( )"));
|
|
}
|
|
}
|
|
- Source.Render(this, Driver, isSelected, item, col, row, f.Width-col);
|
|
|
|
|
|
+ Source.Render (this, Driver, isSelected, item, col, row, f.Width - col);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -292,12 +298,12 @@ namespace Terminal.Gui {
|
|
/// <summary>
|
|
/// <summary>
|
|
/// This event is raised when the cursor selection has changed.
|
|
/// This event is raised when the cursor selection has changed.
|
|
/// </summary>
|
|
/// </summary>
|
|
- public event Action SelectedChanged;
|
|
|
|
|
|
+ public event EventHandler<ListViewItemEventArgs> SelectedChanged;
|
|
|
|
|
|
/// <summary>
|
|
/// <summary>
|
|
/// This event is raised on Enter key or Double Click to open the selected item.
|
|
/// This event is raised on Enter key or Double Click to open the selected item.
|
|
/// </summary>
|
|
/// </summary>
|
|
- public event EventHandler OpenSelectedItem;
|
|
|
|
|
|
+ public event EventHandler<ListViewItemEventArgs> OpenSelectedItem;
|
|
|
|
|
|
/// <summary>
|
|
/// <summary>
|
|
/// Handles cursor movement for this view, passes all other events.
|
|
/// Handles cursor movement for this view, passes all other events.
|
|
@@ -312,27 +318,27 @@ namespace Terminal.Gui {
|
|
switch (kb.Key) {
|
|
switch (kb.Key) {
|
|
case Key.CursorUp:
|
|
case Key.CursorUp:
|
|
case Key.ControlP:
|
|
case Key.ControlP:
|
|
- return MoveUp();
|
|
|
|
|
|
+ return MoveUp ();
|
|
|
|
|
|
case Key.CursorDown:
|
|
case Key.CursorDown:
|
|
case Key.ControlN:
|
|
case Key.ControlN:
|
|
- return MoveDown();
|
|
|
|
|
|
+ return MoveDown ();
|
|
|
|
|
|
case Key.ControlV:
|
|
case Key.ControlV:
|
|
case Key.PageDown:
|
|
case Key.PageDown:
|
|
- return MovePageDown();
|
|
|
|
|
|
+ return MovePageDown ();
|
|
|
|
|
|
case Key.PageUp:
|
|
case Key.PageUp:
|
|
- return MovePageUp();
|
|
|
|
|
|
+ return MovePageUp ();
|
|
|
|
|
|
case Key.Space:
|
|
case Key.Space:
|
|
- if (MarkUnmarkRow())
|
|
|
|
|
|
+ if (MarkUnmarkRow ())
|
|
return true;
|
|
return true;
|
|
else
|
|
else
|
|
break;
|
|
break;
|
|
|
|
|
|
case Key.Enter:
|
|
case Key.Enter:
|
|
- OpenSelectedItem?.Invoke (this, new EventArgs ());
|
|
|
|
|
|
+ OnOpenSelectedItem ();
|
|
break;
|
|
break;
|
|
|
|
|
|
}
|
|
}
|
|
@@ -340,7 +346,7 @@ namespace Terminal.Gui {
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// <summary>
|
|
- ///
|
|
|
|
|
|
+ /// Prevents marking if it's not allowed mark and if it's not allows multiple selection.
|
|
/// </summary>
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
/// <returns></returns>
|
|
public virtual bool AllowsAll ()
|
|
public virtual bool AllowsAll ()
|
|
@@ -359,13 +365,14 @@ namespace Terminal.Gui {
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// <summary>
|
|
- ///
|
|
|
|
|
|
+ /// Marks an unmarked row.
|
|
/// </summary>
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
/// <returns></returns>
|
|
- public virtual bool MarkUnmarkRow(){
|
|
|
|
|
|
+ public virtual bool MarkUnmarkRow ()
|
|
|
|
+ {
|
|
if (AllowsAll ()) {
|
|
if (AllowsAll ()) {
|
|
- Source.SetMark(SelectedItem, !Source.IsMarked(SelectedItem));
|
|
|
|
- SetNeedsDisplay();
|
|
|
|
|
|
+ Source.SetMark (SelectedItem, !Source.IsMarked (SelectedItem));
|
|
|
|
+ SetNeedsDisplay ();
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -373,84 +380,114 @@ namespace Terminal.Gui {
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// <summary>
|
|
- ///
|
|
|
|
|
|
+ /// Moves to the next page.
|
|
/// </summary>
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
/// <returns></returns>
|
|
- public virtual bool MovePageUp(){
|
|
|
|
|
|
+ public virtual bool MovePageUp ()
|
|
|
|
+ {
|
|
int n = (selected - Frame.Height);
|
|
int n = (selected - Frame.Height);
|
|
if (n < 0)
|
|
if (n < 0)
|
|
n = 0;
|
|
n = 0;
|
|
- if (n != selected){
|
|
|
|
|
|
+ if (n != selected) {
|
|
selected = n;
|
|
selected = n;
|
|
top = selected;
|
|
top = selected;
|
|
- if (SelectedChanged != null)
|
|
|
|
- SelectedChanged();
|
|
|
|
- SetNeedsDisplay();
|
|
|
|
|
|
+ OnSelectedChanged ();
|
|
|
|
+ SetNeedsDisplay ();
|
|
}
|
|
}
|
|
|
|
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// <summary>
|
|
- ///
|
|
|
|
|
|
+ /// Moves to the previous page.
|
|
/// </summary>
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
/// <returns></returns>
|
|
- public virtual bool MovePageDown(){
|
|
|
|
|
|
+ public virtual bool MovePageDown ()
|
|
|
|
+ {
|
|
var n = (selected + Frame.Height);
|
|
var n = (selected + Frame.Height);
|
|
if (n > source.Count)
|
|
if (n > source.Count)
|
|
n = source.Count - 1;
|
|
n = source.Count - 1;
|
|
- if (n != selected){
|
|
|
|
|
|
+ if (n != selected) {
|
|
selected = n;
|
|
selected = n;
|
|
if (source.Count >= Frame.Height)
|
|
if (source.Count >= Frame.Height)
|
|
top = selected;
|
|
top = selected;
|
|
else
|
|
else
|
|
top = 0;
|
|
top = 0;
|
|
- if (SelectedChanged != null)
|
|
|
|
- SelectedChanged();
|
|
|
|
- SetNeedsDisplay();
|
|
|
|
|
|
+ OnSelectedChanged ();
|
|
|
|
+ SetNeedsDisplay ();
|
|
}
|
|
}
|
|
|
|
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// <summary>
|
|
- ///
|
|
|
|
|
|
+ /// Moves to the next row.
|
|
/// </summary>
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
/// <returns></returns>
|
|
- public virtual bool MoveDown(){
|
|
|
|
- if (selected + 1 < source.Count){
|
|
|
|
|
|
+ public virtual bool MoveDown ()
|
|
|
|
+ {
|
|
|
|
+ if (selected + 1 < source.Count) {
|
|
selected++;
|
|
selected++;
|
|
if (selected >= top + Frame.Height)
|
|
if (selected >= top + Frame.Height)
|
|
top++;
|
|
top++;
|
|
- if (SelectedChanged != null)
|
|
|
|
- SelectedChanged();
|
|
|
|
- SetNeedsDisplay();
|
|
|
|
|
|
+ OnSelectedChanged ();
|
|
|
|
+ SetNeedsDisplay ();
|
|
}
|
|
}
|
|
|
|
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// <summary>
|
|
- ///
|
|
|
|
|
|
+ /// Moves to the previous row.
|
|
/// </summary>
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
/// <returns></returns>
|
|
- public virtual bool MoveUp(){
|
|
|
|
- if (selected > 0){
|
|
|
|
|
|
+ public virtual bool MoveUp ()
|
|
|
|
+ {
|
|
|
|
+ if (selected > 0) {
|
|
selected--;
|
|
selected--;
|
|
if (selected < top)
|
|
if (selected < top)
|
|
top = selected;
|
|
top = selected;
|
|
- if (SelectedChanged != null)
|
|
|
|
- SelectedChanged();
|
|
|
|
- SetNeedsDisplay();
|
|
|
|
|
|
+ OnSelectedChanged ();
|
|
|
|
+ SetNeedsDisplay ();
|
|
}
|
|
}
|
|
|
|
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ int lastSelectedItem = -1;
|
|
|
|
+
|
|
|
|
+ /// <summary>
|
|
|
|
+ /// Invokes the SelectedChanged event if it is defined.
|
|
|
|
+ /// </summary>
|
|
|
|
+ /// <returns></returns>
|
|
|
|
+ public virtual bool OnSelectedChanged ()
|
|
|
|
+ {
|
|
|
|
+ if (selected != lastSelectedItem) {
|
|
|
|
+ var value = source.ToList () [selected];
|
|
|
|
+ SelectedChanged?.Invoke (this, new ListViewItemEventArgs (selected, value));
|
|
|
|
+ lastSelectedItem = selected;
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /// <summary>
|
|
|
|
+ /// Invokes the OnOpenSelectedItem event if it is defined.
|
|
|
|
+ /// </summary>
|
|
|
|
+ /// <returns></returns>
|
|
|
|
+ public virtual bool OnOpenSelectedItem ()
|
|
|
|
+ {
|
|
|
|
+ var value = source.ToList () [selected];
|
|
|
|
+ OpenSelectedItem?.Invoke (this, new ListViewItemEventArgs (selected, value));
|
|
|
|
+
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+
|
|
/// <summary>
|
|
/// <summary>
|
|
/// Positions the cursor in this view
|
|
/// Positions the cursor in this view
|
|
/// </summary>
|
|
/// </summary>
|
|
- public override void PositionCursor()
|
|
|
|
|
|
+ public override void PositionCursor ()
|
|
{
|
|
{
|
|
if (allowsMarking)
|
|
if (allowsMarking)
|
|
Move (1, selected - top);
|
|
Move (1, selected - top);
|
|
@@ -461,7 +498,8 @@ namespace Terminal.Gui {
|
|
///<inheritdoc cref="MouseEvent(Gui.MouseEvent)"/>
|
|
///<inheritdoc cref="MouseEvent(Gui.MouseEvent)"/>
|
|
public override bool MouseEvent(MouseEvent me)
|
|
public override bool MouseEvent(MouseEvent me)
|
|
{
|
|
{
|
|
- if (!me.Flags.HasFlag (MouseFlags.Button1Clicked) && !me.Flags.HasFlag (MouseFlags.Button1DoubleClicked))
|
|
|
|
|
|
+ if (!me.Flags.HasFlag (MouseFlags.Button1Clicked) && !me.Flags.HasFlag (MouseFlags.Button1DoubleClicked) &&
|
|
|
|
+ me.Flags != MouseFlags.WheeledDown && me.Flags != MouseFlags.WheeledUp)
|
|
return false;
|
|
return false;
|
|
|
|
|
|
if (!HasFocus)
|
|
if (!HasFocus)
|
|
@@ -470,6 +508,14 @@ namespace Terminal.Gui {
|
|
if (source == null)
|
|
if (source == null)
|
|
return false;
|
|
return false;
|
|
|
|
|
|
|
|
+ if (me.Flags == MouseFlags.WheeledDown) {
|
|
|
|
+ MoveDown ();
|
|
|
|
+ return true;
|
|
|
|
+ } else if (me.Flags == MouseFlags.WheeledUp) {
|
|
|
|
+ MoveUp ();
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+
|
|
if (me.Y + top >= source.Count)
|
|
if (me.Y + top >= source.Count)
|
|
return true;
|
|
return true;
|
|
|
|
|
|
@@ -479,10 +525,10 @@ namespace Terminal.Gui {
|
|
SetNeedsDisplay ();
|
|
SetNeedsDisplay ();
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
- SelectedChanged?.Invoke ();
|
|
|
|
|
|
+ OnSelectedChanged ();
|
|
SetNeedsDisplay ();
|
|
SetNeedsDisplay ();
|
|
if (me.Flags == MouseFlags.Button1DoubleClicked)
|
|
if (me.Flags == MouseFlags.Button1DoubleClicked)
|
|
- OpenSelectedItem?.Invoke (this, new EventArgs ());
|
|
|
|
|
|
+ OnOpenSelectedItem ();
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -497,7 +543,7 @@ namespace Terminal.Gui {
|
|
int count;
|
|
int count;
|
|
|
|
|
|
/// <summary>
|
|
/// <summary>
|
|
- /// constructor
|
|
|
|
|
|
+ /// Constructor based on a source.
|
|
/// </summary>
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
/// <param name="source"></param>
|
|
public ListWrapper (IList source)
|
|
public ListWrapper (IList source)
|
|
@@ -508,7 +554,7 @@ namespace Terminal.Gui {
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// <summary>
|
|
- /// Count of items.
|
|
|
|
|
|
+ /// Returns the amount of items in the source.
|
|
/// </summary>
|
|
/// </summary>
|
|
public int Count => src.Count;
|
|
public int Count => src.Count;
|
|
|
|
|
|
@@ -519,7 +565,7 @@ namespace Terminal.Gui {
|
|
for (int i = 0; i < byteLen;) {
|
|
for (int i = 0; i < byteLen;) {
|
|
(var rune, var size) = Utf8.DecodeRune (ustr, i, i - byteLen);
|
|
(var rune, var size) = Utf8.DecodeRune (ustr, i, i - byteLen);
|
|
var count = Rune.ColumnWidth (rune);
|
|
var count = Rune.ColumnWidth (rune);
|
|
- if (used+count >= width)
|
|
|
|
|
|
+ if (used + count >= width)
|
|
break;
|
|
break;
|
|
driver.AddRune (rune);
|
|
driver.AddRune (rune);
|
|
used += count;
|
|
used += count;
|
|
@@ -531,15 +577,15 @@ namespace Terminal.Gui {
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// <summary>
|
|
- /// Renders an item in the the list.
|
|
|
|
|
|
+ /// Method that render to the appropriate type based on the type of the item passed to it.
|
|
/// </summary>
|
|
/// </summary>
|
|
- /// <param name="container"></param>
|
|
|
|
- /// <param name="driver"></param>
|
|
|
|
- /// <param name="marked"></param>
|
|
|
|
- /// <param name="item"></param>
|
|
|
|
- /// <param name="col"></param>
|
|
|
|
- /// <param name="line"></param>
|
|
|
|
- /// <param name="width"></param>
|
|
|
|
|
|
+ /// <param name="container">The ListView.</param>
|
|
|
|
+ /// <param name="driver">The driver used by the caller.</param>
|
|
|
|
+ /// <param name="marked">Informs if it's marked or not.</param>
|
|
|
|
+ /// <param name="item">The item.</param>
|
|
|
|
+ /// <param name="col">The col where to move.</param>
|
|
|
|
+ /// <param name="line">The line where to move.</param>
|
|
|
|
+ /// <param name="width">The item width.</param>
|
|
public void Render (ListView container, ConsoleDriver driver, bool marked, int item, int col, int line, int width)
|
|
public void Render (ListView container, ConsoleDriver driver, bool marked, int item, int col, int line, int width)
|
|
{
|
|
{
|
|
container.Move (col, line);
|
|
container.Move (col, line);
|
|
@@ -553,10 +599,10 @@ namespace Terminal.Gui {
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// <summary>
|
|
- /// Returns true of the item is marked. false if not.
|
|
|
|
|
|
+ /// Returns true if the item is marked, false otherwise.
|
|
/// </summary>
|
|
/// </summary>
|
|
- /// <param name="item"></param>
|
|
|
|
- /// <returns></returns>
|
|
|
|
|
|
+ /// <param name="item">The item.</param>
|
|
|
|
+ /// <returns><c>true</c>If is marked.<c>false</c>otherwise.</returns>
|
|
public bool IsMarked (int item)
|
|
public bool IsMarked (int item)
|
|
{
|
|
{
|
|
if (item >= 0 && item < count)
|
|
if (item >= 0 && item < count)
|
|
@@ -565,14 +611,48 @@ namespace Terminal.Gui {
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// <summary>
|
|
- /// Sets the marked state of an item.
|
|
|
|
|
|
+ /// Sets the item as marked or unmarked based on the value is true or false, respectively.
|
|
/// </summary>
|
|
/// </summary>
|
|
- /// <param name="item"></param>
|
|
|
|
- /// <param name="value"></param>
|
|
|
|
|
|
+ /// <param name="item">The item</param>
|
|
|
|
+ /// <param name="value"><true>Marks the item.</true><false>Unmarked the item.</false>The value.</param>
|
|
public void SetMark (int item, bool value)
|
|
public void SetMark (int item, bool value)
|
|
{
|
|
{
|
|
if (item >= 0 && item < count)
|
|
if (item >= 0 && item < count)
|
|
marks [item] = value;
|
|
marks [item] = value;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ /// <summary>
|
|
|
|
+ /// Returns the source as IList.
|
|
|
|
+ /// </summary>
|
|
|
|
+ /// <returns></returns>
|
|
|
|
+ public IList ToList ()
|
|
|
|
+ {
|
|
|
|
+ return src;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /// <summary>
|
|
|
|
+ /// Gets the item and value to use in an event handler.
|
|
|
|
+ /// </summary>
|
|
|
|
+ public class ListViewItemEventArgs : EventArgs {
|
|
|
|
+ /// <summary>
|
|
|
|
+ /// The item.
|
|
|
|
+ /// </summary>
|
|
|
|
+ public int Item { get; }
|
|
|
|
+ /// <summary>
|
|
|
|
+ /// The item value.
|
|
|
|
+ /// </summary>
|
|
|
|
+ public object Value { get; }
|
|
|
|
+
|
|
|
|
+ /// <summary>
|
|
|
|
+ /// Constructor to sets the item and value passed from.
|
|
|
|
+ /// </summary>
|
|
|
|
+ /// <param name="item">The item.</param>
|
|
|
|
+ /// <param name="value">The item value</param>
|
|
|
|
+ public ListViewItemEventArgs (int item, object value)
|
|
|
|
+ {
|
|
|
|
+ Item = item;
|
|
|
|
+ Value = value;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|