Browse Source

Merge pull request #485 from BDisp/list-view-open-item

List view open item
Charlie Kindel 5 years ago
parent
commit
6ff943efd2
2 changed files with 150 additions and 63 deletions
  1. 141 61
      Terminal.Gui/Views/ListView.cs
  2. 9 2
      UICatalog/Program.cs

+ 141 - 61
Terminal.Gui/Views/ListView.cs

@@ -63,6 +63,12 @@ namespace Terminal.Gui {
 		/// <param name="item">Item index.</param>
 		/// <param name="value">If set to <c>true</c> value.</param>
 		void SetMark (int item, bool value);
+
+		/// <summary>
+		/// Return the source as IList.
+		/// </summary>
+		/// <returns></returns>
+		IList ToList ();
 	}
 
 	/// <summary>
@@ -257,7 +263,7 @@ namespace Terminal.Gui {
 		/// Redraws the ListView
 		/// </summary>
 		/// <param name="region">Region.</param>
-		public override void Redraw(Rect region)
+		public override void Redraw (Rect region)
 		{
 			var current = ColorScheme.Focus;
 			Driver.SetAttribute (current);
@@ -279,12 +285,12 @@ namespace Terminal.Gui {
 				Move (0, row);
 				if (source == null || item >= source.Count) {
 					for (int c = 0; c < f.Width; c++)
-						Driver.AddRune(' ');
+						Driver.AddRune (' ');
 				} else {
 					if (allowsMarking) {
 						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>
 		/// This event is raised when the cursor selection has changed.
 		/// </summary>
-		public event Action SelectedChanged;
+		public event EventHandler<ListViewItemEventArgs> SelectedChanged;
 
 		/// <summary>
 		/// This event is raised on Enter key or Double Click to open the selected item.
 		/// </summary>
-		public event EventHandler OpenSelectedItem;
+		public event EventHandler<ListViewItemEventArgs> OpenSelectedItem;
 
 		/// <summary>
 		/// Handles cursor movement for this view, passes all other events.
@@ -312,27 +318,27 @@ namespace Terminal.Gui {
 			switch (kb.Key) {
 			case Key.CursorUp:
 			case Key.ControlP:
-				return MoveUp();
+				return MoveUp ();
 
 			case Key.CursorDown:
 			case Key.ControlN:
-				return MoveDown();
+				return MoveDown ();
 
 			case Key.ControlV:
 			case Key.PageDown:
-				return MovePageDown();
+				return MovePageDown ();
 
 			case Key.PageUp:
-				return MovePageUp();
+				return MovePageUp ();
 
 			case Key.Space:
-				if (MarkUnmarkRow())
+				if (MarkUnmarkRow ())
 					return true;
 				else
 					break;
 
 			case Key.Enter:
-				OpenSelectedItem?.Invoke (this, new EventArgs ());
+				OnOpenSelectedItem ();
 				break;
 
 			}
@@ -340,7 +346,7 @@ namespace Terminal.Gui {
 		}
 
 		/// <summary>
-		/// 
+		/// Prevents marking if it's not allowed mark and if it's not allows multiple selection.
 		/// </summary>
 		/// <returns></returns>
 		public virtual bool AllowsAll ()
@@ -359,13 +365,14 @@ namespace Terminal.Gui {
 		}
 
 		/// <summary>
-		/// 
+		/// Marks an unmarked row.
 		/// </summary>
 		/// <returns></returns>
-		public virtual bool MarkUnmarkRow(){
+		public virtual bool MarkUnmarkRow ()
+		{
 			if (AllowsAll ()) {
-				Source.SetMark(SelectedItem, !Source.IsMarked(SelectedItem));
-				SetNeedsDisplay();
+				Source.SetMark (SelectedItem, !Source.IsMarked (SelectedItem));
+				SetNeedsDisplay ();
 				return true;
 			}
 
@@ -373,84 +380,114 @@ namespace Terminal.Gui {
 		}
 
 		/// <summary>
-		/// 
+		/// Moves to the next page.
 		/// </summary>
 		/// <returns></returns>
-		public virtual bool MovePageUp(){
+		public virtual bool MovePageUp ()
+		{
 			int n = (selected - Frame.Height);
 			if (n < 0)
 				n = 0;
-			if (n != selected){
+			if (n != selected) {
 				selected = n;
 				top = selected;
-				if (SelectedChanged != null)
-					SelectedChanged();
-				SetNeedsDisplay();
+				OnSelectedChanged ();
+				SetNeedsDisplay ();
 			}
 
 			return true;
 		}
 
 		/// <summary>
-		/// 
+		/// Moves to the previous page.
 		/// </summary>
 		/// <returns></returns>
-		public virtual bool MovePageDown(){
+		public virtual bool MovePageDown ()
+		{
 			var n = (selected + Frame.Height);
 			if (n > source.Count)
 				n = source.Count - 1;
-			if (n != selected){
+			if (n != selected) {
 				selected = n;
 				if (source.Count >= Frame.Height)
 					top = selected;
 				else
 					top = 0;
-				if (SelectedChanged != null)
-					SelectedChanged();
-				SetNeedsDisplay();
+				OnSelectedChanged ();
+				SetNeedsDisplay ();
 			}
 
 			return true;
 		}
 
 		/// <summary>
-		/// 
+		/// Moves to the next row.
 		/// </summary>
 		/// <returns></returns>
-		public virtual bool MoveDown(){
-			if (selected + 1 < source.Count){
+		public virtual bool MoveDown ()
+		{
+			if (selected + 1 < source.Count) {
 				selected++;
 				if (selected >= top + Frame.Height)
 					top++;
-				if (SelectedChanged != null)
-					SelectedChanged();
-				SetNeedsDisplay();
+				OnSelectedChanged ();
+				SetNeedsDisplay ();
 			}
 
 			return true;
 		}
 
 		/// <summary>
-		/// 
+		/// Moves to the previous row.
 		/// </summary>
 		/// <returns></returns>
-		public virtual bool MoveUp(){
-			if (selected > 0){
+		public virtual bool MoveUp ()
+		{
+			if (selected > 0) {
 				selected--;
 				if (selected < top)
 					top = selected;
-				if (SelectedChanged != null)
-					SelectedChanged();
-				SetNeedsDisplay();
+				OnSelectedChanged ();
+				SetNeedsDisplay ();
 			}
 
 			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>
 		/// Positions the cursor in this view
 		/// </summary>
-		public override void PositionCursor()
+		public override void PositionCursor ()
 		{
 			if (allowsMarking)
 				Move (1, selected - top);
@@ -461,7 +498,8 @@ namespace Terminal.Gui {
 		///<inheritdoc cref="MouseEvent(Gui.MouseEvent)"/>
 		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;
 
 			if (!HasFocus)
@@ -470,6 +508,14 @@ namespace Terminal.Gui {
 			if (source == null)
 				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)
 				return true;
 
@@ -479,10 +525,10 @@ namespace Terminal.Gui {
 				SetNeedsDisplay ();
 				return true;
 			}
-			SelectedChanged?.Invoke ();
+			OnSelectedChanged ();
 			SetNeedsDisplay ();
 			if (me.Flags == MouseFlags.Button1DoubleClicked)
-				OpenSelectedItem?.Invoke (this, new EventArgs ());
+				OnOpenSelectedItem ();
 			return true;
 		}
 	}
@@ -497,7 +543,7 @@ namespace Terminal.Gui {
 		int count;
 
 		/// <summary>
-		/// constructor
+		/// Constructor based on a source.
 		/// </summary>
 		/// <param name="source"></param>
 		public ListWrapper (IList source)
@@ -508,7 +554,7 @@ namespace Terminal.Gui {
 		}
 
 		/// <summary>
-		/// Count of items.
+		/// Returns the amount of items in the source.
 		/// </summary>
 		public int Count => src.Count;
 
@@ -519,7 +565,7 @@ namespace Terminal.Gui {
 			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)
+				if (used + count >= width)
 					break;
 				driver.AddRune (rune);
 				used += count;
@@ -531,15 +577,15 @@ namespace Terminal.Gui {
 		}
 
 		/// <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>
-		/// <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)
 		{
 			container.Move (col, line);
@@ -553,10 +599,10 @@ namespace Terminal.Gui {
 		}
 
 		/// <summary>
-		/// Returns true of the item is marked. false if not.
+		/// Returns true if the item is marked, false otherwise.
 		/// </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)
 		{
 			if (item >= 0 && item < count)
@@ -565,14 +611,48 @@ namespace Terminal.Gui {
 		}
 
 		/// <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>
-		/// <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)
 		{
 			if (item >= 0 && item < count)
 				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;
+		}
 	}
 }

+ 9 - 2
UICatalog/Program.cs

@@ -1,5 +1,6 @@
 using NStack;
 using System;
+using System.Collections;
 using System.Collections.Generic;
 using System.Diagnostics;
 using System.Globalization;
@@ -119,7 +120,7 @@ namespace UICatalog {
 			_rightPane.Add (_scenarioListView);
 
 			_categoryListView.SelectedItem = 0;
-			CategoryListView_SelectedChanged ();
+			_categoryListView.OnSelectedChanged ();
 
 			_statusBar = new StatusBar (new StatusItem [] {
 				//new StatusItem(Key.F1, "~F1~ Help", () => Help()),
@@ -228,6 +229,12 @@ namespace UICatalog {
 					used++;
 				}
 			}
+
+			public IList ToList ()
+			{
+				return Scenarios;
+			}
+
 		}
 
 		/// <summary>
@@ -255,7 +262,7 @@ namespace UICatalog {
 			}
 		}
 
-		private static void CategoryListView_SelectedChanged ()
+		private static void CategoryListView_SelectedChanged (object sender, ListViewItemEventArgs e)
 		{
 			var item = _categories [_categoryListView.SelectedItem];
 			List<Type> newlist;