Browse Source

Fixes #1577 - Add Support for Colored ListView Items (#1578)

* We can now choose the color (background and foreground/text) we want to display each item.

* Added RowRender event.

* Colored ListView in action.

Co-authored-by: BDisp <[email protected]>
Aurélien VERBEKE 3 years ago
parent
commit
64d14d325d
2 changed files with 62 additions and 0 deletions
  1. 44 0
      Terminal.Gui/Views/ListView.cs
  2. 18 0
      UICatalog/Scenarios/ListViewWithSelection.cs

+ 44 - 0
Terminal.Gui/Views/ListView.cs

@@ -347,6 +347,12 @@ namespace Terminal.Gui {
 					for (int c = 0; c < f.Width; c++)
 						Driver.AddRune (' ');
 				} else {
+					var rowEventArgs = new ListViewRowEventArgs (item);
+					OnRowRender (rowEventArgs);
+					if (rowEventArgs.RowAttribute != null && current != rowEventArgs.RowAttribute) {
+						current = (Attribute)rowEventArgs.RowAttribute;
+						Driver.SetAttribute (current);
+					}
 					if (allowsMarking) {
 						Driver.AddRune (source.IsMarked (item) ? (AllowsMultipleSelection ? Driver.Checked : Driver.Selected) : (AllowsMultipleSelection ? Driver.UnChecked : Driver.UnSelected));
 						Driver.AddRune (' ');
@@ -366,6 +372,11 @@ namespace Terminal.Gui {
 		/// </summary>
 		public event Action<ListViewItemEventArgs> OpenSelectedItem;
 
+		/// <summary>
+		/// This event is invoked when this <see cref="ListView"/> is being drawn before rendering.
+		/// </summary>
+		public event Action<ListViewRowEventArgs> RowRender;
+
 		///<inheritdoc/>
 		public override bool ProcessKey (KeyEvent kb)
 		{
@@ -665,6 +676,15 @@ namespace Terminal.Gui {
 			return true;
 		}
 
+		/// <summary>
+		/// Virtual method that will invoke the <see cref="RowRender"/>.
+		/// </summary>
+		/// <param name="rowEventArgs"></param>
+		public virtual void OnRowRender (ListViewRowEventArgs rowEventArgs)
+		{
+			RowRender?.Invoke (rowEventArgs);
+		}
+
 		///<inheritdoc/>
 		public override bool OnEnter (View view)
 		{
@@ -921,4 +941,28 @@ namespace Terminal.Gui {
 			Value = value;
 		}
 	}
+
+	/// <summary>
+	/// <see cref="EventArgs"/> used by the <see cref="ListView.RowRender"/> event.
+	/// </summary>
+	public class ListViewRowEventArgs : EventArgs {
+		/// <summary>
+		/// The current row being rendered.
+		/// </summary>
+		public int Row { get; }
+		/// <summary>
+		/// The <see cref="Attribute"/> used by current row or
+		/// null to maintain the current attribute.
+		/// </summary>
+		public Attribute? RowAttribute { get; set; }
+
+		/// <summary>
+		/// Initializes with the current row.
+		/// </summary>
+		/// <param name="row"></param>
+		public ListViewRowEventArgs (int row)
+		{
+			Row = row;
+		}
+	}
 }

+ 18 - 0
UICatalog/Scenarios/ListViewWithSelection.cs

@@ -4,6 +4,7 @@ using System.Collections;
 using System.Collections.Generic;
 using System.Linq;
 using Terminal.Gui;
+using Attribute = Terminal.Gui.Attribute;
 
 namespace UICatalog.Scenarios {
 	[ScenarioMetadata (Name: "List View With Selection", Description: "ListView with columns and selection")]
@@ -53,6 +54,7 @@ namespace UICatalog.Scenarios {
 				AllowsMarking = false,
 				AllowsMultipleSelection = false
 			};
+			_listView.RowRender += ListView_RowRender;
 			Win.Add (_listView);
 
 			var _scrollBar = new ScrollBarView (_listView, true);
@@ -92,6 +94,22 @@ namespace UICatalog.Scenarios {
 			Win.Add (keepCheckBox);
 		}
 
+		private void ListView_RowRender (ListViewRowEventArgs obj)
+		{
+			if (obj.Row == _listView.SelectedItem) {
+				return;
+			}
+			if (_listView.AllowsMarking && _listView.Source.IsMarked (obj.Row)) {
+				obj.RowAttribute = new Attribute (Color.BrightRed, Color.BrightYellow);
+				return;
+			}
+			if (obj.Row % 2 == 0) {
+				obj.RowAttribute = new Attribute (Color.BrightGreen, Color.Magenta);
+			} else {
+				obj.RowAttribute = new Attribute (Color.BrightMagenta, Color.Green);
+			}
+		}
+
 		private void _customRenderCB_Toggled (bool prev)
 		{
 			if (prev) {