From 401c872b311f5b8e3eb643e78e87ca99ae8af298 Mon Sep 17 00:00:00 2001 From: Miguel de Icaza Date: Thu, 29 Aug 2019 11:55:33 -0400 Subject: [PATCH] ListView: simple selection implemented --- Example/demo.cs | 42 ++++++++++++++++++++++++++++++++++ Terminal.Gui/Views/ListView.cs | 31 +++++++++++++++++++++---- 2 files changed, 69 insertions(+), 4 deletions(-) diff --git a/Example/demo.cs b/Example/demo.cs index 0c55a2ea0..34a78ec2e 100644 --- a/Example/demo.cs +++ b/Example/demo.cs @@ -1,6 +1,8 @@ using Terminal.Gui; using System; using Mono.Terminal; +using System.Collections; +using System.Collections.Generic; static class Demo { @@ -255,6 +257,43 @@ static class Demo { } + #region Selection Demo + + static void ListSelectionDemo () + { + var d = new Dialog ("Selection Demo", 60, 20, + new Button ("Ok", is_default: true) { Clicked = () => { Application.RequestStop (); } }, + new Button ("Cancel") { Clicked = () => { Application.RequestStop (); } }); + + var animals = new List () { "Alpaca", "Llama", "Lion", "Shark", "Goat" }; + var msg = new Label ("Use space bar or control-t to toggle selection") { + X = 1, + Y = 1, + Width = Dim.Fill () - 1, + Height = 1 + }; + + var list = new ListView (animals) { + X = 1, + Y = 3, + Width = Dim.Fill () - 4, + Height = Dim.Fill () - 4, + AllowsMarking = true + }; + d.Add (msg, list); + Application.Run (d); + + var result = ""; + for (int i = 0; i < animals.Count; i++) { + if (list.Source.IsMarked (i)) { + result += animals [i] + " "; + } + } + MessageBox.Query (60, 10, "Selected Animals", result == "" ? "No animals selected" : result, "Ok"); + } + #endregion + + public static Label ml; static void Main () { @@ -289,6 +328,9 @@ static class Demo { new MenuItem ("C_ut", "", null), new MenuItem ("_Paste", "", null) }), + new MenuBarItem ("_List Demos", new MenuItem [] { + new MenuItem ("Select Items", "", ListSelectionDemo), + }), }); ShowEntries (win); diff --git a/Terminal.Gui/Views/ListView.cs b/Terminal.Gui/Views/ListView.cs index f8db83cb9..729a898c5 100644 --- a/Terminal.Gui/Views/ListView.cs +++ b/Terminal.Gui/Views/ListView.cs @@ -85,6 +85,11 @@ namespace Terminal.Gui { /// providing your own rendering via the IListDataSource implementation) or call SetSource /// when you are providing an IList. /// + /// + /// When AllowsMark is set to true, then the rendering will prefix the list rendering with + /// [x] or [ ] and bind the space character to toggle the selection. If you desire a different + /// marking style do not set the property and provide your own custom rendering. + /// /// public class ListView : View { int top; @@ -182,9 +187,15 @@ namespace Terminal.Gui { bool allowsMarking; /// - /// Gets or sets a value indicating whether this allows items to be marked. + /// Gets or sets a value indicating whether this allows items to be marked. /// - /// true if allows marking elements of the list; otherwise, false. + /// true if allows marking elements of the list; otherwise, false. + /// + /// + /// If set to true, this will default to rendering the marked with "[x]", and unmarked valued with "[ ]" + /// spaces. If you desire a different rendering, you need to implement your own renderer. This will + /// also by default process the space character as a toggle for the selection. + /// public bool AllowsMarking { get => allowsMarking; set { @@ -292,6 +303,7 @@ namespace Terminal.Gui { var f = Frame; var item = top; bool focused = HasFocus; + int col = allowsMarking ? 4 : 0; for (int row = 0; row < f.Height; row++, item++) { bool isSelected = item == selected; @@ -302,12 +314,15 @@ namespace Terminal.Gui { current = newcolor; } + Move (0, row); if (source == null || item >= source.Count) { - Move(0, row); for (int c = 0; c < f.Width; c++) Driver.AddRune(' '); } else { - Source.Render(this, Driver, isSelected, item, 0, row, f.Width); + if (allowsMarking) { + Driver.AddStr (source.IsMarked (item) ? "[x] " : "[ ] "); + } + Source.Render(this, Driver, isSelected, item, col, row, f.Width-col); } } } @@ -381,6 +396,14 @@ namespace Terminal.Gui { SetNeedsDisplay (); } return true; + + case Key.Space: + if (allowsMarking) { + Source.SetMark (SelectedItem, !Source.IsMarked (SelectedItem)); + SetNeedsDisplay (); + return true; + } + break; } return base.ProcessKey (kb); }