From 283356433d0665cdf2fe6e4e8b9f4db3262eb396 Mon Sep 17 00:00:00 2001 From: Ross Ferguson Date: Sat, 20 Jun 2020 09:34:55 +0100 Subject: [PATCH 01/44] ComboBox multiple fixes. Dim.Fill() incorrectly calculated. List height not resizing. SetSource() not immeadiately updating list. Double click not selecting item. Example now demo resizes with view --- Example/demo.cs | 5 +- Terminal.Gui/Views/ComboBox.cs | 104 ++++++++++---------------- UICatalog/Scenarios/ListsAndCombos.cs | 4 +- 3 files changed, 43 insertions(+), 70 deletions(-) diff --git a/Example/demo.cs b/Example/demo.cs index 1195db8ab..dda4a3d7a 100644 --- a/Example/demo.cs +++ b/Example/demo.cs @@ -459,11 +459,12 @@ static class Demo { .OrderBy (x => x).ToList (); } } - var list = new ComboBox () { X = 0, Y = 0, Width = Dim.Fill(), Height = Dim.Fill() }; + var list = new ComboBox () { Width = Dim.Fill(), Height = Dim.Fill() }; list.SetSource(items.ToList()); list.SelectedItemChanged += (object sender, ustring text) => { Application.RequestStop (); }; - var d = new Dialog ("Select source file", 40, 12) { list }; + var d = new Dialog () { Title = "Select source file", Width = Dim.Percent (50), Height = Dim.Percent (50) }; + d.Add (list); Application.Run (d); MessageBox.Query (60, 10, "Selected file", list.Text.ToString() == "" ? "Nothing selected" : list.Text.ToString(), "Ok"); diff --git a/Terminal.Gui/Views/ComboBox.cs b/Terminal.Gui/Views/ComboBox.cs index 99e306412..73b2b21a7 100644 --- a/Terminal.Gui/Views/ComboBox.cs +++ b/Terminal.Gui/Views/ComboBox.cs @@ -4,10 +4,6 @@ // Authors: // Ross Ferguson (ross.c.ferguson@btinternet.com) // -// TODO: -// LayoutComplete() resize Height implement -// Cursor rolls of end of list when Height = Dim.Fill() and list fills frame -// using System; using System.Collections; @@ -33,6 +29,7 @@ namespace Terminal.Gui { get => source; set { source = value; + Search_Changed (""); SetNeedsDisplay (); } } @@ -88,7 +85,6 @@ namespace Terminal.Gui { /// public ComboBox (Rect rect, IList source) : base (rect) { - SetSource (source); this.height = rect.Height; this.width = rect.Width; @@ -96,6 +92,7 @@ namespace Terminal.Gui { listview = new ListView (rect, source) { LayoutStyle = LayoutStyle.Computed }; Initialize (); + SetSource (source); } static IListDataSource MakeWrapper (IList source) @@ -108,12 +105,14 @@ namespace Terminal.Gui { ColorScheme = Colors.Base; search.TextChanged += Search_Changed; + listview.OpenSelectedItem += (ListViewItemEventArgs a) => Selected(); // On resize LayoutComplete += (LayoutEventArgs a) => { search.Width = Bounds.Width; listview.Width = autoHide ? Bounds.Width - 1 : Bounds.Width; + listview.Height = CalculatetHeight (); }; listview.SelectedItemChanged += (ListViewItemEventArgs e) => { @@ -135,30 +134,20 @@ namespace Terminal.Gui { ColorScheme = autoHide ? Colors.Base : ColorScheme = null; - // Needs to be re-applied for LayoutStyle.Computed - // If Dim or Pos are null, these are the from the parametrized constructor - listview.Y = 1; + listview.Y = Pos.Bottom (search); - if (Width == null) { - listview.Width = CalculateWidth (); - search.Width = width; - } else { - width = GetDimAsInt (Width, vertical: false); - search.Width = width; - listview.Width = CalculateWidth (); - } + if (Width != null && width == 0) // new ComboBox() { Width = + width = Bounds.Width; - if (Height == null) { - var h = CalculatetHeight (); - listview.Height = h; - this.Height = h + 1; // adjust view to account for search box - } else { - if (height == 0) - height = GetDimAsInt (Height, vertical: true); + search.Width = width; + listview.Width = CalculateWidth (); - listview.Height = CalculatetHeight (); - this.Height = height + 1; // adjust view to account for search box - } + if (Height != null && height == 0) // new ComboBox() { Height = + height = Bounds.Height; + + listview.Height = CalculatetHeight (); + + SetNeedsLayout (); if (this.Text != null) Search_Changed (Text); @@ -216,21 +205,7 @@ namespace Terminal.Gui { } if (e.Key == Key.Enter && listview.HasFocus) { - if (listview.Source.Count == 0 || searchset.Count == 0) { - text = ""; - return true; - } - - SetValue((string)searchset [listview.SelectedItem]); - search.CursorPosition = search.Text.Length; - Search_Changed (search.Text); - OnSelectedChanged (); - - searchset.Clear(); - listview.Clear (); - listview.Height = 0; - this.SetFocus(search); - + Selected (); return true; } @@ -289,14 +264,28 @@ namespace Terminal.Gui { search.TextChanged += Search_Changed; } + private void Selected() + { + if (listview.Source.Count == 0 || searchset.Count == 0) { + text = ""; + return; + } + + SetValue ((string)searchset [listview.SelectedItem]); + search.CursorPosition = search.Text.Length; + Search_Changed (search.Text); + Reset (keepSearchText: true); + } + /// /// Reset to full original list /// - private void Reset() + private void Reset(bool keepSearchText = false) { - search.Text = text = ""; - OnSelectedChanged(); + if(!keepSearchText) + search.Text = text = ""; + OnSelectedChanged (); ResetSearchSet (); listview.SetSource(searchset); @@ -333,15 +322,6 @@ namespace Terminal.Gui { this.SuperView?.BringSubviewToFront (this); } - /// - /// Internal height of dynamic search list - /// - /// - private int CalculatetHeight () - { - return Math.Min (height, searchset.Count); - } - /// /// Internal width of search list /// @@ -352,21 +332,13 @@ namespace Terminal.Gui { } /// - /// Get Dim as integer value + /// Internal height of dynamic search list /// - /// - /// - /// n - private int GetDimAsInt (Dim dim, bool vertical) + /// + private int CalculatetHeight () { - if (dim is Dim.DimAbsolute) - return dim.Anchor (0); - else { // Dim.Fill Dim.Factor - if(autoHide) - return vertical ? dim.Anchor (SuperView.Bounds.Height) : dim.Anchor (SuperView.Bounds.Width); - else - return vertical ? dim.Anchor (Bounds.Height) : dim.Anchor (Bounds.Width); - } + var h = (Height is Dim.DimAbsolute) ? height : Bounds.Height; + return Math.Min (Math.Max (0, h - 1), searchset.Count); } } } diff --git a/UICatalog/Scenarios/ListsAndCombos.cs b/UICatalog/Scenarios/ListsAndCombos.cs index 19d10539c..7418c3c4d 100644 --- a/UICatalog/Scenarios/ListsAndCombos.cs +++ b/UICatalog/Scenarios/ListsAndCombos.cs @@ -26,14 +26,14 @@ namespace UICatalog.Scenarios { var lbListView = new Label ("Listview") { ColorScheme = Colors.TopLevel, X = 0, - Width = 30 + Width = Dim.Percent (40) }; var listview = new ListView (items) { X = 0, Y = Pos.Bottom (lbListView) + 1, Height = Dim.Fill(2), - Width = 30 + Width = Dim.Percent (40) }; listview.OpenSelectedItem += (ListViewItemEventArgs e) => lbListView.Text = items [listview.SelectedItem]; Win.Add (lbListView, listview); From a869b9c6dd00dee61f55df7094ab2e602aeacc8c Mon Sep 17 00:00:00 2001 From: Ross Ferguson Date: Sat, 20 Jun 2020 10:48:32 +0100 Subject: [PATCH 02/44] Fixed AllViewsTester.cs crash --- Terminal.Gui/Views/ComboBox.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Terminal.Gui/Views/ComboBox.cs b/Terminal.Gui/Views/ComboBox.cs index 73b2b21a7..74708f884 100644 --- a/Terminal.Gui/Views/ComboBox.cs +++ b/Terminal.Gui/Views/ComboBox.cs @@ -338,7 +338,7 @@ namespace Terminal.Gui { private int CalculatetHeight () { var h = (Height is Dim.DimAbsolute) ? height : Bounds.Height; - return Math.Min (Math.Max (0, h - 1), searchset.Count); + return Math.Min (Math.Max (0, h - 1), searchset?.Count ?? 0); } } } From e164ca2233b6392245e83f3eda182f1d721bec79 Mon Sep 17 00:00:00 2001 From: Ross Ferguson Date: Sat, 20 Jun 2020 12:15:08 +0100 Subject: [PATCH 03/44] Add constructor that takes a text argument --- Terminal.Gui/Views/ComboBox.cs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Terminal.Gui/Views/ComboBox.cs b/Terminal.Gui/Views/ComboBox.cs index 74708f884..a5af2a12c 100644 --- a/Terminal.Gui/Views/ComboBox.cs +++ b/Terminal.Gui/Views/ComboBox.cs @@ -78,6 +78,19 @@ namespace Terminal.Gui { Initialize (); } + /// + /// Public constructor + /// + /// + public ComboBox (ustring text) : base () + { + search = new TextField (""); + listview = new ListView () { LayoutStyle = LayoutStyle.Computed, CanFocus = true }; + + Initialize (); + Text = text; + } + /// /// Public constructor /// From cfcf8efb59d75f7c506b6fa9499351af894b1530 Mon Sep 17 00:00:00 2001 From: Ross Ferguson Date: Sat, 20 Jun 2020 09:34:55 +0100 Subject: [PATCH 04/44] ComboBox multiple fixes. Dim.Fill() incorrectly calculated. List height not resizing. SetSource() not immeadiately updating list. Double click not selecting item. Example now demo resizes with view --- Example/demo.cs | 5 +- Terminal.Gui/Views/ComboBox.cs | 104 ++++++++++---------------- UICatalog/Scenarios/ListsAndCombos.cs | 4 +- 3 files changed, 43 insertions(+), 70 deletions(-) diff --git a/Example/demo.cs b/Example/demo.cs index 1195db8ab..dda4a3d7a 100644 --- a/Example/demo.cs +++ b/Example/demo.cs @@ -459,11 +459,12 @@ static class Demo { .OrderBy (x => x).ToList (); } } - var list = new ComboBox () { X = 0, Y = 0, Width = Dim.Fill(), Height = Dim.Fill() }; + var list = new ComboBox () { Width = Dim.Fill(), Height = Dim.Fill() }; list.SetSource(items.ToList()); list.SelectedItemChanged += (object sender, ustring text) => { Application.RequestStop (); }; - var d = new Dialog ("Select source file", 40, 12) { list }; + var d = new Dialog () { Title = "Select source file", Width = Dim.Percent (50), Height = Dim.Percent (50) }; + d.Add (list); Application.Run (d); MessageBox.Query (60, 10, "Selected file", list.Text.ToString() == "" ? "Nothing selected" : list.Text.ToString(), "Ok"); diff --git a/Terminal.Gui/Views/ComboBox.cs b/Terminal.Gui/Views/ComboBox.cs index 99e306412..73b2b21a7 100644 --- a/Terminal.Gui/Views/ComboBox.cs +++ b/Terminal.Gui/Views/ComboBox.cs @@ -4,10 +4,6 @@ // Authors: // Ross Ferguson (ross.c.ferguson@btinternet.com) // -// TODO: -// LayoutComplete() resize Height implement -// Cursor rolls of end of list when Height = Dim.Fill() and list fills frame -// using System; using System.Collections; @@ -33,6 +29,7 @@ namespace Terminal.Gui { get => source; set { source = value; + Search_Changed (""); SetNeedsDisplay (); } } @@ -88,7 +85,6 @@ namespace Terminal.Gui { /// public ComboBox (Rect rect, IList source) : base (rect) { - SetSource (source); this.height = rect.Height; this.width = rect.Width; @@ -96,6 +92,7 @@ namespace Terminal.Gui { listview = new ListView (rect, source) { LayoutStyle = LayoutStyle.Computed }; Initialize (); + SetSource (source); } static IListDataSource MakeWrapper (IList source) @@ -108,12 +105,14 @@ namespace Terminal.Gui { ColorScheme = Colors.Base; search.TextChanged += Search_Changed; + listview.OpenSelectedItem += (ListViewItemEventArgs a) => Selected(); // On resize LayoutComplete += (LayoutEventArgs a) => { search.Width = Bounds.Width; listview.Width = autoHide ? Bounds.Width - 1 : Bounds.Width; + listview.Height = CalculatetHeight (); }; listview.SelectedItemChanged += (ListViewItemEventArgs e) => { @@ -135,30 +134,20 @@ namespace Terminal.Gui { ColorScheme = autoHide ? Colors.Base : ColorScheme = null; - // Needs to be re-applied for LayoutStyle.Computed - // If Dim or Pos are null, these are the from the parametrized constructor - listview.Y = 1; + listview.Y = Pos.Bottom (search); - if (Width == null) { - listview.Width = CalculateWidth (); - search.Width = width; - } else { - width = GetDimAsInt (Width, vertical: false); - search.Width = width; - listview.Width = CalculateWidth (); - } + if (Width != null && width == 0) // new ComboBox() { Width = + width = Bounds.Width; - if (Height == null) { - var h = CalculatetHeight (); - listview.Height = h; - this.Height = h + 1; // adjust view to account for search box - } else { - if (height == 0) - height = GetDimAsInt (Height, vertical: true); + search.Width = width; + listview.Width = CalculateWidth (); - listview.Height = CalculatetHeight (); - this.Height = height + 1; // adjust view to account for search box - } + if (Height != null && height == 0) // new ComboBox() { Height = + height = Bounds.Height; + + listview.Height = CalculatetHeight (); + + SetNeedsLayout (); if (this.Text != null) Search_Changed (Text); @@ -216,21 +205,7 @@ namespace Terminal.Gui { } if (e.Key == Key.Enter && listview.HasFocus) { - if (listview.Source.Count == 0 || searchset.Count == 0) { - text = ""; - return true; - } - - SetValue((string)searchset [listview.SelectedItem]); - search.CursorPosition = search.Text.Length; - Search_Changed (search.Text); - OnSelectedChanged (); - - searchset.Clear(); - listview.Clear (); - listview.Height = 0; - this.SetFocus(search); - + Selected (); return true; } @@ -289,14 +264,28 @@ namespace Terminal.Gui { search.TextChanged += Search_Changed; } + private void Selected() + { + if (listview.Source.Count == 0 || searchset.Count == 0) { + text = ""; + return; + } + + SetValue ((string)searchset [listview.SelectedItem]); + search.CursorPosition = search.Text.Length; + Search_Changed (search.Text); + Reset (keepSearchText: true); + } + /// /// Reset to full original list /// - private void Reset() + private void Reset(bool keepSearchText = false) { - search.Text = text = ""; - OnSelectedChanged(); + if(!keepSearchText) + search.Text = text = ""; + OnSelectedChanged (); ResetSearchSet (); listview.SetSource(searchset); @@ -333,15 +322,6 @@ namespace Terminal.Gui { this.SuperView?.BringSubviewToFront (this); } - /// - /// Internal height of dynamic search list - /// - /// - private int CalculatetHeight () - { - return Math.Min (height, searchset.Count); - } - /// /// Internal width of search list /// @@ -352,21 +332,13 @@ namespace Terminal.Gui { } /// - /// Get Dim as integer value + /// Internal height of dynamic search list /// - /// - /// - /// n - private int GetDimAsInt (Dim dim, bool vertical) + /// + private int CalculatetHeight () { - if (dim is Dim.DimAbsolute) - return dim.Anchor (0); - else { // Dim.Fill Dim.Factor - if(autoHide) - return vertical ? dim.Anchor (SuperView.Bounds.Height) : dim.Anchor (SuperView.Bounds.Width); - else - return vertical ? dim.Anchor (Bounds.Height) : dim.Anchor (Bounds.Width); - } + var h = (Height is Dim.DimAbsolute) ? height : Bounds.Height; + return Math.Min (Math.Max (0, h - 1), searchset.Count); } } } diff --git a/UICatalog/Scenarios/ListsAndCombos.cs b/UICatalog/Scenarios/ListsAndCombos.cs index 19d10539c..7418c3c4d 100644 --- a/UICatalog/Scenarios/ListsAndCombos.cs +++ b/UICatalog/Scenarios/ListsAndCombos.cs @@ -26,14 +26,14 @@ namespace UICatalog.Scenarios { var lbListView = new Label ("Listview") { ColorScheme = Colors.TopLevel, X = 0, - Width = 30 + Width = Dim.Percent (40) }; var listview = new ListView (items) { X = 0, Y = Pos.Bottom (lbListView) + 1, Height = Dim.Fill(2), - Width = 30 + Width = Dim.Percent (40) }; listview.OpenSelectedItem += (ListViewItemEventArgs e) => lbListView.Text = items [listview.SelectedItem]; Win.Add (lbListView, listview); From f3b1b075406ec90631bfd8cb2fe3c283d5695e92 Mon Sep 17 00:00:00 2001 From: Ross Ferguson Date: Sat, 20 Jun 2020 10:48:32 +0100 Subject: [PATCH 05/44] Fixed AllViewsTester.cs crash --- Terminal.Gui/Views/ComboBox.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Terminal.Gui/Views/ComboBox.cs b/Terminal.Gui/Views/ComboBox.cs index 73b2b21a7..74708f884 100644 --- a/Terminal.Gui/Views/ComboBox.cs +++ b/Terminal.Gui/Views/ComboBox.cs @@ -338,7 +338,7 @@ namespace Terminal.Gui { private int CalculatetHeight () { var h = (Height is Dim.DimAbsolute) ? height : Bounds.Height; - return Math.Min (Math.Max (0, h - 1), searchset.Count); + return Math.Min (Math.Max (0, h - 1), searchset?.Count ?? 0); } } } From 6f9758542778f1cf41bcd31e66232ce6ed6fc19d Mon Sep 17 00:00:00 2001 From: Ross Ferguson Date: Sat, 20 Jun 2020 12:15:08 +0100 Subject: [PATCH 06/44] Add constructor that takes a text argument --- Terminal.Gui/Views/ComboBox.cs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Terminal.Gui/Views/ComboBox.cs b/Terminal.Gui/Views/ComboBox.cs index 74708f884..a5af2a12c 100644 --- a/Terminal.Gui/Views/ComboBox.cs +++ b/Terminal.Gui/Views/ComboBox.cs @@ -78,6 +78,19 @@ namespace Terminal.Gui { Initialize (); } + /// + /// Public constructor + /// + /// + public ComboBox (ustring text) : base () + { + search = new TextField (""); + listview = new ListView () { LayoutStyle = LayoutStyle.Computed, CanFocus = true }; + + Initialize (); + Text = text; + } + /// /// Public constructor /// From acacd0c9e72985f8cb1fd92d866ae08e0afc7e66 Mon Sep 17 00:00:00 2001 From: Ross Ferguson Date: Sat, 20 Jun 2020 19:56:12 +0100 Subject: [PATCH 07/44] Accomodate upstream changes --- Example/demo.cs | 4 ++-- Terminal.Gui/Views/ComboBox.cs | 8 ++++---- UICatalog/Scenarios/ListsAndCombos.cs | 8 ++++---- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Example/demo.cs b/Example/demo.cs index dda4a3d7a..08ba4c240 100644 --- a/Example/demo.cs +++ b/Example/demo.cs @@ -450,13 +450,13 @@ static class Demo { static void ComboBoxDemo () { - IList items = new List (); + List items = new List (); foreach (var dir in new [] { "/etc", @"\windows\System32" }) { if (Directory.Exists (dir)) { items = Directory.GetFiles (dir).Union (Directory.GetDirectories (dir)) .Select (Path.GetFileName) .Where (x => char.IsLetterOrDigit (x [0])) - .OrderBy (x => x).ToList (); + .OrderBy (x => x).Select (x => ustring.Make (x)).ToList (); } } var list = new ComboBox () { Width = Dim.Fill(), Height = Dim.Fill() }; diff --git a/Terminal.Gui/Views/ComboBox.cs b/Terminal.Gui/Views/ComboBox.cs index a5af2a12c..8f2022186 100644 --- a/Terminal.Gui/Views/ComboBox.cs +++ b/Terminal.Gui/Views/ComboBox.cs @@ -131,7 +131,7 @@ namespace Terminal.Gui { listview.SelectedItemChanged += (ListViewItemEventArgs e) => { if(searchset.Count > 0) - SetValue ((string)searchset [listview.SelectedItem]); + SetValue ((ustring)searchset [listview.SelectedItem]); }; Application.Loaded += (Application.ResizedEventArgs a) => { @@ -224,7 +224,7 @@ namespace Terminal.Gui { if (e.Key == Key.CursorDown && search.HasFocus && listview.SelectedItem == 0 && searchset.Count > 0) { // jump to list this.SetFocus (listview); - SetValue ((string)searchset [listview.SelectedItem]); + SetValue ((ustring)searchset [listview.SelectedItem]); return true; } @@ -284,7 +284,7 @@ namespace Terminal.Gui { return; } - SetValue ((string)searchset [listview.SelectedItem]); + SetValue ((ustring)searchset [listview.SelectedItem]); search.CursorPosition = search.Text.Length; Search_Changed (search.Text); Reset (keepSearchText: true); @@ -326,7 +326,7 @@ namespace Terminal.Gui { if (string.IsNullOrEmpty (search.Text.ToString ())) ResetSearchSet (); else - searchset = source.ToList().Cast().Where (x => x.StartsWith (search.Text.ToString (), StringComparison.CurrentCultureIgnoreCase)).ToList(); + searchset = source.ToList().Cast().Where (x => x.ToString().StartsWith (search.Text.ToString (), StringComparison.CurrentCultureIgnoreCase)).ToList(); listview.SetSource (searchset); listview.Height = CalculatetHeight (); diff --git a/UICatalog/Scenarios/ListsAndCombos.cs b/UICatalog/Scenarios/ListsAndCombos.cs index 7418c3c4d..c007a69b3 100644 --- a/UICatalog/Scenarios/ListsAndCombos.cs +++ b/UICatalog/Scenarios/ListsAndCombos.cs @@ -12,13 +12,13 @@ namespace UICatalog.Scenarios { public override void Setup () { - List items = new List (); + List items = new List (); foreach (var dir in new [] { "/etc", @"\windows\System32" }) { if (Directory.Exists (dir)) { items = Directory.GetFiles (dir).Union(Directory.GetDirectories(dir)) - .Select (Path.GetFileName) - .Where (x => char.IsLetterOrDigit (x [0])) - .OrderBy (x => x).ToList (); + .Select (Path.GetFileName) + .Where (x => char.IsLetterOrDigit (x [0])) + .OrderBy (x => x).Select(x => ustring.Make(x)).ToList() ; } } From 4df3c4e774b39b4cd06a48498b9e9381f500d4dd Mon Sep 17 00:00:00 2001 From: Ross Ferguson Date: Sat, 20 Jun 2020 21:39:32 +0100 Subject: [PATCH 08/44] Fix unit test --- Terminal.Gui/Views/ComboBox.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Terminal.Gui/Views/ComboBox.cs b/Terminal.Gui/Views/ComboBox.cs index 8f2022186..615ce3255 100644 --- a/Terminal.Gui/Views/ComboBox.cs +++ b/Terminal.Gui/Views/ComboBox.cs @@ -326,7 +326,7 @@ namespace Terminal.Gui { if (string.IsNullOrEmpty (search.Text.ToString ())) ResetSearchSet (); else - searchset = source.ToList().Cast().Where (x => x.ToString().StartsWith (search.Text.ToString (), StringComparison.CurrentCultureIgnoreCase)).ToList(); + searchset = source.ToList().Cast().Where (x => x.ToString().StartsWith (search.Text.ToString (), StringComparison.CurrentCultureIgnoreCase)).ToList(); listview.SetSource (searchset); listview.Height = CalculatetHeight (); From cd9e84b0c48b9f2bb837b667abc551d732bdf5d5 Mon Sep 17 00:00:00 2001 From: Ross Ferguson Date: Tue, 23 Jun 2020 08:59:49 +0100 Subject: [PATCH 09/44] ComboBox. Bracket single statements. Minor Re-factor --- Terminal.Gui/Views/ComboBox.cs | 154 +++++++++++++++++++++++---------- 1 file changed, 109 insertions(+), 45 deletions(-) diff --git a/Terminal.Gui/Views/ComboBox.cs b/Terminal.Gui/Views/ComboBox.cs index 615ce3255..cca4a8681 100644 --- a/Terminal.Gui/Views/ComboBox.cs +++ b/Terminal.Gui/Views/ComboBox.cs @@ -9,6 +9,7 @@ using System; using System.Collections; using System.Collections.Generic; using System.Linq; + using NStack; namespace Terminal.Gui { @@ -43,9 +44,9 @@ namespace Terminal.Gui { /// public void SetSource (IList source) { - if (source == null) + if (source == null) { Source = null; - else { + } else { Source = MakeWrapper (source); } } @@ -70,7 +71,7 @@ namespace Terminal.Gui { /// /// Public constructor /// - public ComboBox () : base() + public ComboBox () : base () { search = new TextField (""); listview = new ListView () { LayoutStyle = LayoutStyle.Computed, CanFocus = true }; @@ -113,16 +114,15 @@ namespace Terminal.Gui { return new ListWrapper (source); } - private void Initialize() + private void Initialize () { ColorScheme = Colors.Base; search.TextChanged += Search_Changed; - listview.OpenSelectedItem += (ListViewItemEventArgs a) => Selected(); + listview.OpenSelectedItem += (ListViewItemEventArgs a) => Selected (); // On resize LayoutComplete += (LayoutEventArgs a) => { - search.Width = Bounds.Width; listview.Width = autoHide ? Bounds.Width - 1 : Bounds.Width; listview.Height = CalculatetHeight (); @@ -130,8 +130,9 @@ namespace Terminal.Gui { listview.SelectedItemChanged += (ListViewItemEventArgs e) => { - if(searchset.Count > 0) + if (searchset.Count > 0) { SetValue ((ustring)searchset [listview.SelectedItem]); + } }; Application.Loaded += (Application.ResizedEventArgs a) => { @@ -149,47 +150,72 @@ namespace Terminal.Gui { listview.Y = Pos.Bottom (search); - if (Width != null && width == 0) // new ComboBox() { Width = + if (Width != null && width == 0) { // new ComboBox() { Width = width = Bounds.Width; + } search.Width = width; listview.Width = CalculateWidth (); - if (Height != null && height == 0) // new ComboBox() { Height = + if (Height != null && height == 0) { // new ComboBox() { Height = height = Bounds.Height; + } listview.Height = CalculatetHeight (); SetNeedsLayout (); - if (this.Text != null) + if (this.Text != null) { Search_Changed (Text); + } - if (autoHide) + if (autoHide) { listview.ColorScheme = Colors.Menu; - else + } else { search.ColorScheme = Colors.Menu; + } }; search.MouseClick += Search_MouseClick; - this.Add(listview, search); - this.SetFocus(search); + this.Add (listview, search); + this.SetFocus (search); } - private void Search_MouseClick (MouseEventArgs e) - { - if (e.MouseEvent.Flags != MouseFlags.Button1Clicked) - return; +#if COMBO_FEATURE + bool isShow = false; +#endif + private void Search_MouseClick (MouseEventArgs me) + { +#if !COMBO_FEATURE + + if (me.MouseEvent.Flags != MouseFlags.Button1Clicked) + return; +#else + if (me.MouseEvent.X == Bounds.Right - 1 && me.MouseEvent.Y == Bounds.Top && me.MouseEvent.Flags == MouseFlags.Button1Pressed + && search.Text == "" && autoHide) { + + if (isShow) { + HideList (); + isShow = false; + } else { + searchset = Source.ToList().Cast().ToList(); // force deep copy + ShowList (); + isShow = true; + } + } + else +#endif SuperView.SetFocus (search); } /// public override bool OnEnter () { - if (!search.HasFocus) + if (!search.HasFocus) { this.SetFocus (search); + } search.CursorPosition = search.Text.Length; @@ -209,11 +235,25 @@ namespace Terminal.Gui { return true; } +#if COMBO_FEATURE /// - public override bool ProcessKey(KeyEvent e) + public override void Redraw (Rect bounds) + { + base.Redraw (bounds); + + if (!autoHide) { + return; + } + + Move (Bounds.Right - 1, 0); + Driver.AddRune (Driver.DownArrow); + } +#endif + /// + public override bool ProcessKey (KeyEvent e) { if (e.Key == Key.Tab) { - base.ProcessKey(e); + base.ProcessKey (e); return false; // allow tab-out to next control } @@ -228,11 +268,11 @@ namespace Terminal.Gui { return true; } - if (e.Key == Key.CursorUp && search.HasFocus) // stop odd behavior on KeyUp when search has focus + if (e.Key == Key.CursorUp && search.HasFocus) { // stop odd behavior on KeyUp when search has focus return true; + } - if (e.Key == Key.CursorUp && listview.HasFocus && listview.SelectedItem == 0 && searchset.Count > 0) // jump back to search - { + if (e.Key == Key.CursorUp && listview.HasFocus && listview.SelectedItem == 0 && searchset.Count > 0) { // jump back to search search.CursorPosition = search.Text.Length; this.SetFocus (search); return true; @@ -246,22 +286,20 @@ namespace Terminal.Gui { } // Unix emulation - if (e.Key == Key.ControlU) - { - Reset(); + if (e.Key == Key.ControlU) { + Reset (); return true; } - return base.ProcessKey(e); + return base.ProcessKey (e); } /// /// The currently selected list item /// - public ustring Text + public ustring Text { - get - { + get { return text; } set { @@ -269,7 +307,7 @@ namespace Terminal.Gui { } } - private void SetValue(ustring text) + private void SetValue (ustring text) { search.TextChanged -= Search_Changed; this.text = search.Text = text; @@ -277,7 +315,7 @@ namespace Terminal.Gui { search.TextChanged += Search_Changed; } - private void Selected() + private void Selected () { if (listview.Source.Count == 0 || searchset.Count == 0) { text = ""; @@ -293,46 +331,72 @@ namespace Terminal.Gui { /// /// Reset to full original list /// - private void Reset(bool keepSearchText = false) + private void Reset (bool keepSearchText = false) { - if(!keepSearchText) + if (!keepSearchText) { search.Text = text = ""; + } OnSelectedChanged (); ResetSearchSet (); - listview.SetSource(searchset); + listview.SetSource (searchset); listview.Height = CalculatetHeight (); - this.SetFocus(search); + this.SetFocus (search); } - private void ResetSearchSet() + private void ResetSearchSet () { if (autoHide) { - if (searchset == null) + if (searchset == null) { searchset = new List (); - else + } else { searchset.Clear (); - } else + } + } else { searchset = source.ToList (); + } } private void Search_Changed (ustring text) { - if (source == null) // Object initialization + if (source == null) { // Object initialization return; + } - if (string.IsNullOrEmpty (search.Text.ToString ())) + if (string.IsNullOrEmpty (search.Text.ToString ())) { ResetSearchSet (); - else - searchset = source.ToList().Cast().Where (x => x.ToString().StartsWith (search.Text.ToString (), StringComparison.CurrentCultureIgnoreCase)).ToList(); + } else { + searchset = source.ToList ().Cast ().Where (x => x.ToString ().StartsWith (search.Text.ToString (), StringComparison.CurrentCultureIgnoreCase)).ToList (); + } + ShowList (); + } + + /// + /// Show the search list + /// + /// + /// Consider making public + private void ShowList() + { listview.SetSource (searchset); listview.Height = CalculatetHeight (); listview.Redraw (new Rect (0, 0, width, height)); // for any view behind this this.SuperView?.BringSubviewToFront (this); + + } + + /// + /// Hide the search list + /// + /// + /// Consider making public + private void HideList() + { + Reset (); } /// From 1d859e3c4f93ea9ae344bfd2eda31201a80223f3 Mon Sep 17 00:00:00 2001 From: BDisp Date: Tue, 23 Jun 2020 20:55:49 +0100 Subject: [PATCH 10/44] Fixes #723 Views now are notified when they are added or removing. --- Terminal.Gui/Core/Responder.cs | 12 ++++++++++++ Terminal.Gui/Core/View.cs | 26 ++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/Terminal.Gui/Core/Responder.cs b/Terminal.Gui/Core/Responder.cs index c6fd75c74..d980c3261 100644 --- a/Terminal.Gui/Core/Responder.cs +++ b/Terminal.Gui/Core/Responder.cs @@ -164,6 +164,18 @@ namespace Terminal.Gui { return false; } + /// + /// Method invoked when a view is added. + /// + /// The view added. + public virtual void OnAddedView (View view) { } + + /// + /// Method invoked when a view being removing. + /// + /// The view being removing. + public virtual void OnRemovingView (View view) { } + /// /// Method invoked when a view gets focus. /// diff --git a/Terminal.Gui/Core/View.cs b/Terminal.Gui/Core/View.cs index 6531b56f9..e8ab2ba6a 100644 --- a/Terminal.Gui/Core/View.cs +++ b/Terminal.Gui/Core/View.cs @@ -142,6 +142,16 @@ namespace Terminal.Gui { View focused = null; Direction focusDirection; + /// + /// Event fired when the view is added. + /// + public Action AddedView; + + /// + /// Event fired when the view is being removing. + /// + public Action RemovingView; + /// /// Event fired when the view gets focus. /// @@ -488,6 +498,7 @@ namespace Terminal.Gui { subviews = new List (); subviews.Add (view); view.container = this; + OnAddedView (view); if (view.CanFocus) CanFocus = true; SetNeedsLayout (); @@ -532,6 +543,7 @@ namespace Terminal.Gui { if (view == null || subviews == null) return; + OnRemovingView (view); SetNeedsLayout (); SetNeedsDisplay (); var touched = view.Frame; @@ -861,6 +873,20 @@ namespace Terminal.Gui { public bool Handled { get; set; } } + /// + public override void OnAddedView (View view) + { + AddedView?.Invoke (view); + base.OnAddedView (view); + } + + /// + public override void OnRemovingView (View view) + { + RemovingView?.Invoke (view); + base.OnRemovingView (view); + } + /// public override bool OnEnter () { From 5e2c94949df7a9efb83a86562064bfb8e5c255e6 Mon Sep 17 00:00:00 2001 From: BDisp Date: Wed, 24 Jun 2020 13:38:59 +0100 Subject: [PATCH 11/44] Removing unnecessary base call. --- Terminal.Gui/Core/View.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/Terminal.Gui/Core/View.cs b/Terminal.Gui/Core/View.cs index e8ab2ba6a..7ffad8657 100644 --- a/Terminal.Gui/Core/View.cs +++ b/Terminal.Gui/Core/View.cs @@ -877,14 +877,12 @@ namespace Terminal.Gui { public override void OnAddedView (View view) { AddedView?.Invoke (view); - base.OnAddedView (view); } /// public override void OnRemovingView (View view) { RemovingView?.Invoke (view); - base.OnRemovingView (view); } /// From 81c4b3a0e5a42a4e9a552088de4b05acc3435d22 Mon Sep 17 00:00:00 2001 From: BDisp Date: Wed, 24 Jun 2020 17:47:42 +0100 Subject: [PATCH 12/44] Made changes as suggested. --- Terminal.Gui/Core/Responder.cs | 12 ------------ Terminal.Gui/Core/View.cs | 30 ++++++++++++++++++------------ 2 files changed, 18 insertions(+), 24 deletions(-) diff --git a/Terminal.Gui/Core/Responder.cs b/Terminal.Gui/Core/Responder.cs index d980c3261..c6fd75c74 100644 --- a/Terminal.Gui/Core/Responder.cs +++ b/Terminal.Gui/Core/Responder.cs @@ -164,18 +164,6 @@ namespace Terminal.Gui { return false; } - /// - /// Method invoked when a view is added. - /// - /// The view added. - public virtual void OnAddedView (View view) { } - - /// - /// Method invoked when a view being removing. - /// - /// The view being removing. - public virtual void OnRemovingView (View view) { } - /// /// Method invoked when a view gets focus. /// diff --git a/Terminal.Gui/Core/View.cs b/Terminal.Gui/Core/View.cs index 7ffad8657..8ff25f88f 100644 --- a/Terminal.Gui/Core/View.cs +++ b/Terminal.Gui/Core/View.cs @@ -143,14 +143,14 @@ namespace Terminal.Gui { Direction focusDirection; /// - /// Event fired when the view is added. + /// Event fired when a subview is being added to this view. /// - public Action AddedView; + public Action Adding; /// - /// Event fired when the view is being removing. + /// Event fired when a subview is being removed from this view. /// - public Action RemovingView; + public Action Removing; /// /// Event fired when the view gets focus. @@ -498,7 +498,7 @@ namespace Terminal.Gui { subviews = new List (); subviews.Add (view); view.container = this; - OnAddedView (view); + OnAdding (view); if (view.CanFocus) CanFocus = true; SetNeedsLayout (); @@ -543,7 +543,7 @@ namespace Terminal.Gui { if (view == null || subviews == null) return; - OnRemovingView (view); + OnRemoving (view); SetNeedsLayout (); SetNeedsDisplay (); var touched = view.Frame; @@ -873,16 +873,22 @@ namespace Terminal.Gui { public bool Handled { get; set; } } - /// - public override void OnAddedView (View view) + /// + /// Method invoked when a subview is being added to this view. + /// + /// The subview being added. + public virtual void OnAdding (View view) { - AddedView?.Invoke (view); + Adding?.Invoke (view); } - /// - public override void OnRemovingView (View view) + /// + /// Method invoked when a subview is being removed from this view. + /// + /// The subview being removed. + public virtual void OnRemoving (View view) { - RemovingView?.Invoke (view); + Removing?.Invoke (view); } /// From ecf9ba0c1c15876cdeec9540a2c389de8c43af60 Mon Sep 17 00:00:00 2001 From: BDisp Date: Thu, 25 Jun 2020 14:24:50 +0100 Subject: [PATCH 13/44] The current view is called once instead of being called for each SubView added. --- Terminal.Gui/Core/View.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Terminal.Gui/Core/View.cs b/Terminal.Gui/Core/View.cs index 8ff25f88f..c832eb7a8 100644 --- a/Terminal.Gui/Core/View.cs +++ b/Terminal.Gui/Core/View.cs @@ -879,7 +879,7 @@ namespace Terminal.Gui { /// The subview being added. public virtual void OnAdding (View view) { - Adding?.Invoke (view); + view.Adding?.Invoke (this); } /// @@ -888,7 +888,7 @@ namespace Terminal.Gui { /// The subview being removed. public virtual void OnRemoving (View view) { - Removing?.Invoke (view); + view.Removing?.Invoke (this); } /// From ef3c020c226b85a0146ee9209d0254a990fc2ecc Mon Sep 17 00:00:00 2001 From: Ross Ferguson Date: Sun, 28 Jun 2020 12:12:34 +0100 Subject: [PATCH 14/44] ComboBox. Supports Unicode. Add dropdown arrow from @BDisp. Support PageUp / PageDown --- Terminal.Gui/Views/ComboBox.cs | 166 ++++++++++++-------------- UICatalog/Scenarios/AllViewsTester.cs | 2 +- 2 files changed, 80 insertions(+), 88 deletions(-) diff --git a/Terminal.Gui/Views/ComboBox.cs b/Terminal.Gui/Views/ComboBox.cs index c2cc19ee9..41523acb4 100644 --- a/Terminal.Gui/Views/ComboBox.cs +++ b/Terminal.Gui/Views/ComboBox.cs @@ -8,8 +8,6 @@ using System; using System.Collections; using System.Collections.Generic; -using System.Linq; - using NStack; namespace Terminal.Gui { @@ -30,8 +28,11 @@ namespace Terminal.Gui { get => source; set { source = value; - Search_Changed (""); - SetNeedsDisplay (); + + if(isAdded) { + Search_Changed (""); + SetNeedsDisplay (); + } } } @@ -64,9 +65,8 @@ namespace Terminal.Gui { ustring text = ""; readonly TextField search; readonly ListView listview; - int height; - int width; bool autoHide = true; + bool isAdded; /// /// Public constructor @@ -99,10 +99,7 @@ namespace Terminal.Gui { /// public ComboBox (Rect rect, IList source) : base (rect) { - this.height = rect.Height; - this.width = rect.Width; - - search = new TextField ("") { Width = width }; + search = new TextField ("") { Width = rect.Width }; listview = new ListView (rect, source) { LayoutStyle = LayoutStyle.Computed }; Initialize (); @@ -119,8 +116,14 @@ namespace Terminal.Gui { ColorScheme = Colors.Base; search.TextChanged += Search_Changed; + search.MouseClick += Search_MouseClick; + + listview.Y = Pos.Bottom (search); listview.OpenSelectedItem += (ListViewItemEventArgs a) => Selected (); + this.Add (listview, search); + this.SetFocus (search); + // On resize LayoutComplete += (LayoutEventArgs a) => { search.Width = Bounds.Width; @@ -131,11 +134,18 @@ namespace Terminal.Gui { listview.SelectedItemChanged += (ListViewItemEventArgs e) => { if (searchset.Count > 0) { - SetValue ((ustring)searchset [listview.SelectedItem]); + SetValue (searchset [listview.SelectedItem]); } }; + // This is needed in addition to 'Adding' to trigger the capture the Bounds.Width & Height Application.Loaded += (Application.ResizedEventArgs a) => { + SetNeedsLayout (); + Search_Changed (Text); + }; + + Adding += (View v) => { + // Determine if this view is hosted inside a dialog for (View view = this.SuperView; view != null; view = view.SuperView) { if (view is Dialog) { @@ -144,70 +154,43 @@ namespace Terminal.Gui { } } - ResetSearchSet (); - ColorScheme = autoHide ? Colors.Base : ColorScheme = null; - listview.Y = Pos.Bottom (search); - - if (Width != null && width == 0) { // new ComboBox() { Width = - width = Bounds.Width; - } - - search.Width = width; - listview.Width = CalculateWidth (); - - if (Height != null && height == 0) { // new ComboBox() { Height = - height = Bounds.Height; - } - - listview.Height = CalculatetHeight (); - SetNeedsLayout (); - - if (this.Text != null) { - Search_Changed (Text); - } + Search_Changed (Text); if (autoHide) { listview.ColorScheme = Colors.Menu; } else { search.ColorScheme = Colors.Menu; } + + isAdded = true; }; - - search.MouseClick += Search_MouseClick; - - this.Add (listview, search); - this.SetFocus (search); } -#if COMBO_FEATURE bool isShow = false; -#endif private void Search_MouseClick (MouseEventArgs me) { -#if !COMBO_FEATURE - - if (me.MouseEvent.Flags != MouseFlags.Button1Clicked) - return; -#else if (me.MouseEvent.X == Bounds.Right - 1 && me.MouseEvent.Y == Bounds.Top && me.MouseEvent.Flags == MouseFlags.Button1Pressed - && search.Text == "" && autoHide) { + && search.Text == "" && autoHide) { if (isShow) { HideList (); isShow = false; } else { - searchset = Source.ToList().Cast().ToList(); // force deep copy + // force deep copy + foreach (var item in Source.ToList()) { + searchset.Add (item); + } + ShowList (); isShow = true; } + } else { + SuperView.SetFocus (search); } - else -#endif - SuperView.SetFocus (search); } /// @@ -235,7 +218,6 @@ namespace Terminal.Gui { return true; } -#if COMBO_FEATURE /// public override void Redraw (Rect bounds) { @@ -248,7 +230,7 @@ namespace Terminal.Gui { Move (Bounds.Right - 1, 0); Driver.AddRune (Driver.DownArrow); } -#endif + /// public override bool ProcessKey (KeyEvent e) { @@ -262,9 +244,9 @@ namespace Terminal.Gui { return true; } - if (e.Key == Key.CursorDown && search.HasFocus && listview.SelectedItem == 0 && searchset.Count > 0) { // jump to list + if (e.Key == Key.CursorDown && search.HasFocus && searchset.Count > 0) { // jump to list this.SetFocus (listview); - SetValue ((ustring)searchset [listview.SelectedItem]); + SetValue (searchset [listview.SelectedItem]); return true; } @@ -279,6 +261,16 @@ namespace Terminal.Gui { return true; } + if(e.Key == Key.PageDown) { + listview.MovePageDown (); + return true; + } + + if (e.Key == Key.PageUp) { + listview.MovePageUp (); + return true; + } + if (e.Key == Key.Esc) { this.SetFocus (search); search.Text = text = ""; @@ -298,8 +290,7 @@ namespace Terminal.Gui { /// /// The currently selected list item /// - public new ustring Text - { + public new ustring Text { get { return text; } @@ -308,10 +299,10 @@ namespace Terminal.Gui { } } - private void SetValue (ustring text) + private void SetValue (object text) { search.TextChanged -= Search_Changed; - this.text = search.Text = text; + this.text = search.Text = text.ToString(); search.CursorPosition = 0; search.TextChanged += Search_Changed; } @@ -323,9 +314,10 @@ namespace Terminal.Gui { return; } - SetValue ((ustring)searchset [listview.SelectedItem]); - search.CursorPosition = search.Text.Length; + SetValue (searchset [listview.SelectedItem]); + search.CursorPosition = search.Text.RuneCount; Search_Changed (search.Text); + OnSelectedChanged (); Reset (keepSearchText: true); } @@ -338,7 +330,6 @@ namespace Terminal.Gui { search.Text = text = ""; } - OnSelectedChanged (); ResetSearchSet (); listview.SetSource (searchset); @@ -347,16 +338,20 @@ namespace Terminal.Gui { this.SetFocus (search); } - private void ResetSearchSet () + private void ResetSearchSet (bool noCopy = false) { - if (autoHide) { - if (searchset == null) { - searchset = new List (); - } else { - searchset.Clear (); - } - } else { - searchset = source.ToList (); + if (searchset == null) { + searchset = new List (); + } else { + searchset.Clear (); + } + + if (autoHide || noCopy) + return; + + // force deep copy + foreach (var item in Source.ToList ()) { + searchset.Add (item); } } @@ -366,10 +361,16 @@ namespace Terminal.Gui { return; } - if (string.IsNullOrEmpty (search.Text.ToString ())) { + if (ustring.IsNullOrEmpty (search.Text)) { ResetSearchSet (); } else { - searchset = source.ToList ().Cast ().Where (x => x.ToString ().StartsWith (search.Text.ToString (), StringComparison.CurrentCultureIgnoreCase)).ToList (); + ResetSearchSet (noCopy: true); + + foreach (var item in source.ToList ()) { // Iterate to preserver object type and force deep copy + if (item.ToString().StartsWith (search.Text.ToString(), StringComparison.CurrentCultureIgnoreCase)) { + searchset.Add (item); + } + } } ShowList (); @@ -380,14 +381,12 @@ namespace Terminal.Gui { /// /// /// Consider making public - private void ShowList() + private void ShowList () { listview.SetSource (searchset); listview.Height = CalculatetHeight (); - - listview.Redraw (new Rect (0, 0, width, height)); // for any view behind this + listview.Redraw (new Rect (0, 0, Bounds.Width, Bounds.Height)); // Ensure list shrinks in Dialog this.SuperView?.BringSubviewToFront (this); - } /// @@ -395,28 +394,21 @@ namespace Terminal.Gui { /// /// /// Consider making public - private void HideList() + private void HideList () { Reset (); } - /// - /// Internal width of search list - /// - /// - private int CalculateWidth () - { - return autoHide ? Math.Max (1, width - 1) : width; - } - /// /// Internal height of dynamic search list /// /// private int CalculatetHeight () { - var h = (Height is Dim.DimAbsolute) ? height : Bounds.Height; - return Math.Min (Math.Max (0, h - 1), searchset?.Count ?? 0); + if (Bounds.Height == 0) + return 0; + + return Math.Min (Bounds.Height - 1, searchset?.Count ?? 0); } } } diff --git a/UICatalog/Scenarios/AllViewsTester.cs b/UICatalog/Scenarios/AllViewsTester.cs index 32bc6f48d..6efe6f820 100644 --- a/UICatalog/Scenarios/AllViewsTester.cs +++ b/UICatalog/Scenarios/AllViewsTester.cs @@ -369,7 +369,7 @@ namespace UICatalog { // If the view supports a Source property, set it so we have something to look at if (view != null && view.GetType ().GetProperty ("Source") != null && view.GetType().GetProperty("Source").PropertyType == typeof(Terminal.Gui.IListDataSource)) { - var source = new ListWrapper (new List () { ustring.Make ("List Item #1"), ustring.Make ("List Item #2"), ustring.Make ("List Item #3")}); + var source = new ListWrapper (new List () { ustring.Make ("Test Text #1"), ustring.Make ("Test Text #2"), ustring.Make ("Test Text #3") }); view?.GetType ().GetProperty ("Source")?.GetSetMethod ()?.Invoke (view, new [] { source }); } From 92dda816a516148eed82f45c26f261d03cd2d023 Mon Sep 17 00:00:00 2001 From: BDisp Date: Mon, 29 Jun 2020 18:25:28 +0100 Subject: [PATCH 15/44] Removed Loaded event and changed LayoutComplete event. --- Terminal.Gui/Views/ComboBox.cs | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/Terminal.Gui/Views/ComboBox.cs b/Terminal.Gui/Views/ComboBox.cs index 41523acb4..2ed8f83e7 100644 --- a/Terminal.Gui/Views/ComboBox.cs +++ b/Terminal.Gui/Views/ComboBox.cs @@ -126,9 +126,13 @@ namespace Terminal.Gui { // On resize LayoutComplete += (LayoutEventArgs a) => { - search.Width = Bounds.Width; - listview.Width = autoHide ? Bounds.Width - 1 : Bounds.Width; - listview.Height = CalculatetHeight (); + if (!autoHide && search.Frame.Width != Bounds.Width || + autoHide && search.Frame.Width != Bounds.Width - 1) { + search.Width = listview.Width = autoHide ? Bounds.Width - 1 : Bounds.Width; + listview.Height = CalculatetHeight (); + search.SetRelativeLayout (Bounds); + listview.SetRelativeLayout (Bounds); + } }; listview.SelectedItemChanged += (ListViewItemEventArgs e) => { @@ -138,12 +142,6 @@ namespace Terminal.Gui { } }; - // This is needed in addition to 'Adding' to trigger the capture the Bounds.Width & Height - Application.Loaded += (Application.ResizedEventArgs a) => { - SetNeedsLayout (); - Search_Changed (Text); - }; - Adding += (View v) => { // Determine if this view is hosted inside a dialog From 0f4ddf44c58c876fd62fdd2191ea698728e4a18e Mon Sep 17 00:00:00 2001 From: Ross Ferguson Date: Tue, 30 Jun 2020 09:06:36 +0100 Subject: [PATCH 16/44] Correct width/height --- Terminal.Gui/Views/ComboBox.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Terminal.Gui/Views/ComboBox.cs b/Terminal.Gui/Views/ComboBox.cs index 2ed8f83e7..5dc91e829 100644 --- a/Terminal.Gui/Views/ComboBox.cs +++ b/Terminal.Gui/Views/ComboBox.cs @@ -128,7 +128,8 @@ namespace Terminal.Gui { LayoutComplete += (LayoutEventArgs a) => { if (!autoHide && search.Frame.Width != Bounds.Width || autoHide && search.Frame.Width != Bounds.Width - 1) { - search.Width = listview.Width = autoHide ? Bounds.Width - 1 : Bounds.Width; + search.Width = Bounds.Width; + listview.Width = listview.Width = autoHide ? Bounds.Width - 1 : Bounds.Width; listview.Height = CalculatetHeight (); search.SetRelativeLayout (Bounds); listview.SetRelativeLayout (Bounds); From 6182eab9e03b2325ceff149e14f3e0827c5a74fc Mon Sep 17 00:00:00 2001 From: BDisp Date: Tue, 23 Jun 2020 20:55:49 +0100 Subject: [PATCH 17/44] Fixes #723 Views now are notified when they are added or removing. --- Terminal.Gui/Core/Responder.cs | 12 ++++++++++++ Terminal.Gui/Core/View.cs | 26 ++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/Terminal.Gui/Core/Responder.cs b/Terminal.Gui/Core/Responder.cs index c6fd75c74..d980c3261 100644 --- a/Terminal.Gui/Core/Responder.cs +++ b/Terminal.Gui/Core/Responder.cs @@ -164,6 +164,18 @@ namespace Terminal.Gui { return false; } + /// + /// Method invoked when a view is added. + /// + /// The view added. + public virtual void OnAddedView (View view) { } + + /// + /// Method invoked when a view being removing. + /// + /// The view being removing. + public virtual void OnRemovingView (View view) { } + /// /// Method invoked when a view gets focus. /// diff --git a/Terminal.Gui/Core/View.cs b/Terminal.Gui/Core/View.cs index 77f402f50..36e4db537 100644 --- a/Terminal.Gui/Core/View.cs +++ b/Terminal.Gui/Core/View.cs @@ -124,6 +124,16 @@ namespace Terminal.Gui { TextFormatter viewText; + /// + /// Event fired when the view is added. + /// + public Action AddedView; + + /// + /// Event fired when the view is being removing. + /// + public Action RemovingView; + /// /// Event fired when the view gets focus. /// @@ -552,6 +562,7 @@ namespace Terminal.Gui { subviews = new List (); subviews.Add (view); view.container = this; + OnAddedView (view); if (view.CanFocus) CanFocus = true; SetNeedsLayout (); @@ -596,6 +607,7 @@ namespace Terminal.Gui { if (view == null || subviews == null) return; + OnRemovingView (view); SetNeedsLayout (); SetNeedsDisplay (); var touched = view.Frame; @@ -933,6 +945,20 @@ namespace Terminal.Gui { public bool Handled { get; set; } } + /// + public override void OnAddedView (View view) + { + AddedView?.Invoke (view); + base.OnAddedView (view); + } + + /// + public override void OnRemovingView (View view) + { + RemovingView?.Invoke (view); + base.OnRemovingView (view); + } + /// public override bool OnEnter () { From fa96f467cc4f6276600c6c174abfad0cf0d3408d Mon Sep 17 00:00:00 2001 From: BDisp Date: Wed, 24 Jun 2020 13:38:59 +0100 Subject: [PATCH 18/44] Removing unnecessary base call. --- Terminal.Gui/Core/View.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/Terminal.Gui/Core/View.cs b/Terminal.Gui/Core/View.cs index 36e4db537..c0b1e8c20 100644 --- a/Terminal.Gui/Core/View.cs +++ b/Terminal.Gui/Core/View.cs @@ -949,14 +949,12 @@ namespace Terminal.Gui { public override void OnAddedView (View view) { AddedView?.Invoke (view); - base.OnAddedView (view); } /// public override void OnRemovingView (View view) { RemovingView?.Invoke (view); - base.OnRemovingView (view); } /// From 0d9b1d96ea7d2bdc05b4603b657667f66b7df043 Mon Sep 17 00:00:00 2001 From: BDisp Date: Wed, 24 Jun 2020 17:47:42 +0100 Subject: [PATCH 19/44] Made changes as suggested. --- Terminal.Gui/Core/Responder.cs | 12 ------------ Terminal.Gui/Core/View.cs | 30 ++++++++++++++++++------------ 2 files changed, 18 insertions(+), 24 deletions(-) diff --git a/Terminal.Gui/Core/Responder.cs b/Terminal.Gui/Core/Responder.cs index d980c3261..c6fd75c74 100644 --- a/Terminal.Gui/Core/Responder.cs +++ b/Terminal.Gui/Core/Responder.cs @@ -164,18 +164,6 @@ namespace Terminal.Gui { return false; } - /// - /// Method invoked when a view is added. - /// - /// The view added. - public virtual void OnAddedView (View view) { } - - /// - /// Method invoked when a view being removing. - /// - /// The view being removing. - public virtual void OnRemovingView (View view) { } - /// /// Method invoked when a view gets focus. /// diff --git a/Terminal.Gui/Core/View.cs b/Terminal.Gui/Core/View.cs index c0b1e8c20..8fc7a436e 100644 --- a/Terminal.Gui/Core/View.cs +++ b/Terminal.Gui/Core/View.cs @@ -125,14 +125,14 @@ namespace Terminal.Gui { TextFormatter viewText; /// - /// Event fired when the view is added. + /// Event fired when a subview is being added to this view. /// - public Action AddedView; + public Action Adding; /// - /// Event fired when the view is being removing. + /// Event fired when a subview is being removed from this view. /// - public Action RemovingView; + public Action Removing; /// /// Event fired when the view gets focus. @@ -562,7 +562,7 @@ namespace Terminal.Gui { subviews = new List (); subviews.Add (view); view.container = this; - OnAddedView (view); + OnAdding (view); if (view.CanFocus) CanFocus = true; SetNeedsLayout (); @@ -607,7 +607,7 @@ namespace Terminal.Gui { if (view == null || subviews == null) return; - OnRemovingView (view); + OnRemoving (view); SetNeedsLayout (); SetNeedsDisplay (); var touched = view.Frame; @@ -945,16 +945,22 @@ namespace Terminal.Gui { public bool Handled { get; set; } } - /// - public override void OnAddedView (View view) + /// + /// Method invoked when a subview is being added to this view. + /// + /// The subview being added. + public virtual void OnAdding (View view) { - AddedView?.Invoke (view); + Adding?.Invoke (view); } - /// - public override void OnRemovingView (View view) + /// + /// Method invoked when a subview is being removed from this view. + /// + /// The subview being removed. + public virtual void OnRemoving (View view) { - RemovingView?.Invoke (view); + Removing?.Invoke (view); } /// From 3eeb1d8b5261dd866fe50d0a242dddabbf25ca4c Mon Sep 17 00:00:00 2001 From: BDisp Date: Thu, 25 Jun 2020 14:24:50 +0100 Subject: [PATCH 20/44] The current view is called once instead of being called for each SubView added. --- Terminal.Gui/Core/View.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Terminal.Gui/Core/View.cs b/Terminal.Gui/Core/View.cs index 8fc7a436e..14ccde46c 100644 --- a/Terminal.Gui/Core/View.cs +++ b/Terminal.Gui/Core/View.cs @@ -951,7 +951,7 @@ namespace Terminal.Gui { /// The subview being added. public virtual void OnAdding (View view) { - Adding?.Invoke (view); + view.Adding?.Invoke (this); } /// @@ -960,7 +960,7 @@ namespace Terminal.Gui { /// The subview being removed. public virtual void OnRemoving (View view) { - Removing?.Invoke (view); + view.Removing?.Invoke (this); } /// From 4790a52639b818a96fe07a2b4e7d97a55f88d3dd Mon Sep 17 00:00:00 2001 From: Ross Ferguson Date: Tue, 30 Jun 2020 17:49:41 +0100 Subject: [PATCH 21/44] ComboBox. Use SuperView to determine if control has been added to a container view --- Terminal.Gui/Views/ComboBox.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Terminal.Gui/Views/ComboBox.cs b/Terminal.Gui/Views/ComboBox.cs index 5dc91e829..803b12f4a 100644 --- a/Terminal.Gui/Views/ComboBox.cs +++ b/Terminal.Gui/Views/ComboBox.cs @@ -29,7 +29,8 @@ namespace Terminal.Gui { set { source = value; - if(isAdded) { + // Only need to refresh list if its been added to a container view + if(SuperView != null && SuperView.Subviews.Contains(this)) { Search_Changed (""); SetNeedsDisplay (); } @@ -66,7 +67,6 @@ namespace Terminal.Gui { readonly TextField search; readonly ListView listview; bool autoHide = true; - bool isAdded; /// /// Public constructor @@ -163,8 +163,6 @@ namespace Terminal.Gui { } else { search.ColorScheme = Colors.Menu; } - - isAdded = true; }; } From cba29d6585cfcc9537a3f85adb114198b216d50f Mon Sep 17 00:00:00 2001 From: BDisp Date: Tue, 30 Jun 2020 17:56:24 +0100 Subject: [PATCH 22/44] Change from Adding to Added. --- Terminal.Gui/Core/View.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Terminal.Gui/Core/View.cs b/Terminal.Gui/Core/View.cs index 14ccde46c..be569d2e9 100644 --- a/Terminal.Gui/Core/View.cs +++ b/Terminal.Gui/Core/View.cs @@ -127,7 +127,7 @@ namespace Terminal.Gui { /// /// Event fired when a subview is being added to this view. /// - public Action Adding; + public Action Added; /// /// Event fired when a subview is being removed from this view. @@ -562,7 +562,7 @@ namespace Terminal.Gui { subviews = new List (); subviews.Add (view); view.container = this; - OnAdding (view); + OnAdded (view); if (view.CanFocus) CanFocus = true; SetNeedsLayout (); @@ -949,9 +949,9 @@ namespace Terminal.Gui { /// Method invoked when a subview is being added to this view. /// /// The subview being added. - public virtual void OnAdding (View view) + public virtual void OnAdded (View view) { - view.Adding?.Invoke (this); + view.Added?.Invoke (this); } /// From e0d50af4e530659452a46ce0a3419017061523be Mon Sep 17 00:00:00 2001 From: Ross Ferguson Date: Tue, 30 Jun 2020 20:41:15 +0100 Subject: [PATCH 23/44] Accomodate changes for PR #724 --- Terminal.Gui/Views/ComboBox.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Terminal.Gui/Views/ComboBox.cs b/Terminal.Gui/Views/ComboBox.cs index 803b12f4a..5a6b6e243 100644 --- a/Terminal.Gui/Views/ComboBox.cs +++ b/Terminal.Gui/Views/ComboBox.cs @@ -143,7 +143,7 @@ namespace Terminal.Gui { } }; - Adding += (View v) => { + Added += (View v) => { // Determine if this view is hosted inside a dialog for (View view = this.SuperView; view != null; view = view.SuperView) { From cffdba52c92783dc9bc508d76fd1bf3807971e4b Mon Sep 17 00:00:00 2001 From: BDisp Date: Wed, 1 Jul 2020 00:31:32 +0100 Subject: [PATCH 24/44] Added and Removing tests. --- UnitTests/ViewTests.cs | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/UnitTests/ViewTests.cs b/UnitTests/ViewTests.cs index 43473921b..4ba0c1c4f 100644 --- a/UnitTests/ViewTests.cs +++ b/UnitTests/ViewTests.cs @@ -135,5 +135,26 @@ namespace Terminal.Gui { sub2.Width = Dim.Width (sub2); Assert.Throws (() => root.LayoutSubviews ()); } + + [Fact] + public void Added_Removing () + { + var v = new View (new Rect (0, 0, 10, 24)); + var t = new View (); + + v.Added += (View e) => { + Assert.True (v.SuperView == e); + }; + + v.Removing += (View e) => { + Assert.True (v.SuperView == e); + }; + + t.Add (v); + Assert.True (t.Subviews.Count == 1); + + t.Remove (v); + Assert.True (t.Subviews.Count == 0); + } } } From b99dbfee8b0137955b8e0938b166f90ce04e1af6 Mon Sep 17 00:00:00 2001 From: Ross Ferguson Date: Wed, 1 Jul 2020 09:03:31 +0100 Subject: [PATCH 25/44] ComboBox wire source directly to ListView --- Terminal.Gui/Views/ComboBox.cs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/Terminal.Gui/Views/ComboBox.cs b/Terminal.Gui/Views/ComboBox.cs index 5a6b6e243..9923c657a 100644 --- a/Terminal.Gui/Views/ComboBox.cs +++ b/Terminal.Gui/Views/ComboBox.cs @@ -49,7 +49,8 @@ namespace Terminal.Gui { if (source == null) { Source = null; } else { - Source = MakeWrapper (source); + listview.SetSource (source); + Source = listview.Source; } } @@ -106,11 +107,6 @@ namespace Terminal.Gui { SetSource (source); } - static IListDataSource MakeWrapper (IList source) - { - return new ListWrapper (source); - } - private void Initialize () { ColorScheme = Colors.Base; From f722f96688bdb04e8e40792068295db1ddf2dbc4 Mon Sep 17 00:00:00 2001 From: Ross Ferguson Date: Thu, 2 Jul 2020 07:59:31 +0100 Subject: [PATCH 26/44] ComboBox. Allow user to set ColorScheme --- Terminal.Gui/Views/ComboBox.cs | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/Terminal.Gui/Views/ComboBox.cs b/Terminal.Gui/Views/ComboBox.cs index 9923c657a..81dd94eda 100644 --- a/Terminal.Gui/Views/ComboBox.cs +++ b/Terminal.Gui/Views/ComboBox.cs @@ -88,7 +88,7 @@ namespace Terminal.Gui { { search = new TextField (""); listview = new ListView () { LayoutStyle = LayoutStyle.Computed, CanFocus = true }; - + Initialize (); Text = text; } @@ -101,7 +101,7 @@ namespace Terminal.Gui { public ComboBox (Rect rect, IList source) : base (rect) { search = new TextField ("") { Width = rect.Width }; - listview = new ListView (rect, source) { LayoutStyle = LayoutStyle.Computed }; + listview = new ListView (rect, source) { LayoutStyle = LayoutStyle.Computed, ColorScheme = Colors.Base }; Initialize (); SetSource (source); @@ -109,8 +109,6 @@ namespace Terminal.Gui { private void Initialize () { - ColorScheme = Colors.Base; - search.TextChanged += Search_Changed; search.MouseClick += Search_MouseClick; @@ -149,21 +147,26 @@ namespace Terminal.Gui { } } - ColorScheme = autoHide ? Colors.Base : ColorScheme = null; - SetNeedsLayout (); + SetNeedsDisplay (); Search_Changed (Text); - - if (autoHide) { - listview.ColorScheme = Colors.Menu; - } else { - search.ColorScheme = Colors.Menu; - } }; } bool isShow = false; + /// + public new ColorScheme ColorScheme { + get { + return base.ColorScheme; + } + set { + listview.ColorScheme = value; + base.ColorScheme = value; + SetNeedsDisplay (); + } + } + private void Search_MouseClick (MouseEventArgs me) { if (me.MouseEvent.X == Bounds.Right - 1 && me.MouseEvent.Y == Bounds.Top && me.MouseEvent.Flags == MouseFlags.Button1Pressed From ef5b1143176de33f7364c8bf17fdedc76f73182a Mon Sep 17 00:00:00 2001 From: Jamie D Date: Thu, 2 Jul 2020 09:34:11 +0100 Subject: [PATCH 27/44] ListView - handle null collection --- Terminal.Gui/Views/ListView.cs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/Terminal.Gui/Views/ListView.cs b/Terminal.Gui/Views/ListView.cs index e6add2e6e..160b8d696 100644 --- a/Terminal.Gui/Views/ListView.cs +++ b/Terminal.Gui/Views/ListView.cs @@ -551,15 +551,17 @@ namespace Terminal.Gui { /// public ListWrapper (IList source) { - count = source.Count; - marks = new BitArray (count); - this.src = source; + if (source != null) { + count = source.Count; + marks = new BitArray (count); + this.src = source; + } } /// /// Gets the number of items in the . /// - public int Count => src.Count; + public int Count => Convert.ToInt32 (src?.Count); void RenderUstr (ConsoleDriver driver, ustring ustr, int col, int line, int width) { @@ -594,7 +596,7 @@ namespace Terminal.Gui { container.Move (col, line); var t = src [item]; if (t == null) { - RenderUstr (driver, ustring.Make(""), col, line, width); + RenderUstr (driver, ustring.Make (""), col, line, width); } else { if (t is ustring) { RenderUstr (driver, (ustring)t, col, line, width); From e5647b9299c388b9991c06cb00b38bc0f2e0e70b Mon Sep 17 00:00:00 2001 From: Jamie D Date: Thu, 2 Jul 2020 18:12:14 +0100 Subject: [PATCH 28/44] keep to int --- Terminal.Gui/Views/ListView.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Terminal.Gui/Views/ListView.cs b/Terminal.Gui/Views/ListView.cs index 160b8d696..c36baf729 100644 --- a/Terminal.Gui/Views/ListView.cs +++ b/Terminal.Gui/Views/ListView.cs @@ -561,7 +561,11 @@ namespace Terminal.Gui { /// /// Gets the number of items in the . /// - public int Count => Convert.ToInt32 (src?.Count); + public int Count { + get { + return src?.Count != null ? src.Count : 0; + } + } void RenderUstr (ConsoleDriver driver, ustring ustr, int col, int line, int width) { From 4caa852db2f8e4e48c4a8185b690bbe8eb714a0b Mon Sep 17 00:00:00 2001 From: Jamie D Date: Thu, 2 Jul 2020 19:30:54 +0100 Subject: [PATCH 29/44] be more concise --- Terminal.Gui/Views/ListView.cs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/Terminal.Gui/Views/ListView.cs b/Terminal.Gui/Views/ListView.cs index c36baf729..01c6e6a77 100644 --- a/Terminal.Gui/Views/ListView.cs +++ b/Terminal.Gui/Views/ListView.cs @@ -561,11 +561,7 @@ namespace Terminal.Gui { /// /// Gets the number of items in the . /// - public int Count { - get { - return src?.Count != null ? src.Count : 0; - } - } + public int Count => src != null ? src.Count : 0; void RenderUstr (ConsoleDriver driver, ustring ustr, int col, int line, int width) { From 4fc50aae903de8b04ca7534886533640f242f139 Mon Sep 17 00:00:00 2001 From: BDisp Date: Thu, 2 Jul 2020 23:53:32 +0100 Subject: [PATCH 30/44] Allowing multi-thread toplevels. --- Terminal.Gui/Core/Application.cs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/Terminal.Gui/Core/Application.cs b/Terminal.Gui/Core/Application.cs index 4ca0d9907..a54b9bcf4 100644 --- a/Terminal.Gui/Core/Application.cs +++ b/Terminal.Gui/Core/Application.cs @@ -586,16 +586,23 @@ namespace Terminal.Gui { MainLoop.MainIteration (); Iteration?.Invoke (); - } else if (wait == false) + } else if (wait == false) { return; - if (state.Toplevel.NeedDisplay != null && (!state.Toplevel.NeedDisplay.IsEmpty || state.Toplevel.childNeedsDisplay)) { + } + if (state.Toplevel != Top && (!Top.NeedDisplay.IsEmpty || Top.childNeedsDisplay)) { + Top.Redraw (Top.Bounds); + state.Toplevel.SetNeedsDisplay (state.Toplevel.Bounds); + } + if (!state.Toplevel.NeedDisplay.IsEmpty || state.Toplevel.childNeedsDisplay) { state.Toplevel.Redraw (state.Toplevel.Bounds); - if (DebugDrawBounds) + if (DebugDrawBounds) { DrawBounds (state.Toplevel); + } state.Toplevel.PositionCursor (); Driver.Refresh (); - } else + } else { Driver.UpdateCursor (); + } } } From aa51de0bf0fc99af99d8e7634634d908f366b7d4 Mon Sep 17 00:00:00 2001 From: BDisp Date: Thu, 2 Jul 2020 23:57:50 +0100 Subject: [PATCH 31/44] Improvement the Application.Top in Demo. --- Example/demo.cs | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/Example/demo.cs b/Example/demo.cs index a845c9088..87f29b0e1 100644 --- a/Example/demo.cs +++ b/Example/demo.cs @@ -237,12 +237,13 @@ static class Demo { // static void Editor () { - var tframe = Application.Top.Frame; - Application.Top.RemoveAll (); + Application.Init (); + var ntop = Application.Top; + var menu = new MenuBar (new MenuBarItem [] { new MenuBarItem ("_File", new MenuItem [] { - new MenuItem ("_Close", "", () => { if (Quit ()) {Application.RequestStop (); } }), + new MenuItem ("_Close", "", () => { if (Quit ()) { running = MainApp; Application.RequestStop (); } }), }), new MenuBarItem ("_Edit", new MenuItem [] { new MenuItem ("_Copy", "", null), @@ -267,15 +268,13 @@ static class Demo { }; ntop.Add (win); - var text = new TextView (new Rect (0, 0, tframe.Width - 2, tframe.Height - 3)); + var text = new TextView () { X = 0, Y = 0, Width = Dim.Fill (), Height = Dim.Fill () }; if (fname != null) text.Text = System.IO.File.ReadAllText (fname); win.Add (text); Application.Run (ntop, false); - Application.Top.RemoveAll (); - Main (); } static bool Quit () @@ -534,11 +533,19 @@ static class Demo { } #endregion + public static Action running = MainApp; + static void Main () + { + while (running != null) { + running.Invoke (); + } + } + public static Label ml; public static MenuBar menu; public static CheckBox menuKeysStyle; public static CheckBox menuAutoMouseNav; - static void Main () + static void MainApp () { if (Debugger.IsAttached) CultureInfo.DefaultThreadCurrentUICulture = CultureInfo.GetCultureInfo ("en-US"); @@ -578,14 +585,14 @@ static class Demo { menu = new MenuBar (new MenuBarItem [] { new MenuBarItem ("_File", new MenuItem [] { - new MenuItem ("Text _Editor Demo", "", () => { Editor (); }), + new MenuItem ("Text _Editor Demo", "", () => { running = Editor; Application.RequestStop (); }), new MenuItem ("_New", "Creates new file", NewFile), new MenuItem ("_Open", "", Open), new MenuItem ("_Hex", "", () => ShowHex (top)), new MenuItem ("_Close", "", () => Close ()), new MenuItem ("_Disabled", "", () => { }, () => false), null, - new MenuItem ("_Quit", "", () => { if (Quit ()) top.Running = false; }) + new MenuItem ("_Quit", "", () => { if (Quit ()) { running = null; top.Running = false; } }) }), new MenuBarItem ("_Edit", new MenuItem [] { new MenuItem ("_Copy", "", Copy), @@ -648,9 +655,8 @@ static class Demo { new StatusItem(Key.F1, "~F1~ Help", () => Help()), new StatusItem(Key.F2, "~F2~ Load", Load), new StatusItem(Key.F3, "~F3~ Save", Save), - new StatusItem(Key.ControlQ, "~^Q~ Quit", () => { if (Quit ()) top.Running = false; }), - }) { - }; + new StatusItem(Key.ControlQ, "~^Q~ Quit", () => { if (Quit ()) { running = null; top.Running = false; } }) + }); win.Add (drag, dragText); @@ -671,7 +677,7 @@ static class Demo { top.Add (win); //top.Add (menu); top.Add (menu, statusBar); - Application.Run (); + Application.Run (top, false); } private static void Win_KeyPress (View.KeyEventEventArgs e) From 67785f7e7f0ea6595d3ff163bd688edaadc16306 Mon Sep 17 00:00:00 2001 From: BDisp Date: Fri, 3 Jul 2020 01:04:18 +0100 Subject: [PATCH 32/44] Forgot shutdown the driver at exit. --- Example/demo.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Example/demo.cs b/Example/demo.cs index 87f29b0e1..1ce10262c 100644 --- a/Example/demo.cs +++ b/Example/demo.cs @@ -539,6 +539,7 @@ static class Demo { while (running != null) { running.Invoke (); } + Application.Shutdown (); } public static Label ml; From de5a30bb90854e238998910e48c34646783a00f2 Mon Sep 17 00:00:00 2001 From: Ross Ferguson Date: Fri, 3 Jul 2020 05:22:00 +0100 Subject: [PATCH 33/44] ComboBox hand pick @BDisp changes:- Test dir more robust "\Windows" Use ListViewItemEventArgs --- Example/demo.cs | 4 ++-- Terminal.Gui/Views/ComboBox.cs | 4 ++-- UICatalog/Scenarios/ListsAndCombos.cs | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Example/demo.cs b/Example/demo.cs index e8a5349e4..f56c067f1 100644 --- a/Example/demo.cs +++ b/Example/demo.cs @@ -451,7 +451,7 @@ static class Demo { static void ComboBoxDemo () { List items = new List (); - foreach (var dir in new [] { "/etc", @"\windows\System32" }) { + foreach (var dir in new [] { "/etc", @$"{Environment.GetEnvironmentVariable ("SystemRoot")}\System32" }) { if (Directory.Exists (dir)) { items = Directory.GetFiles (dir).Union (Directory.GetDirectories (dir)) .Select (Path.GetFileName) @@ -461,7 +461,7 @@ static class Demo { } var list = new ComboBox () { Width = Dim.Fill(), Height = Dim.Fill() }; list.SetSource(items.ToList()); - list.SelectedItemChanged += (object sender, ustring text) => { Application.RequestStop (); }; + list.SelectedItemChanged += (object sender, ListViewItemEventArgs text) => { Application.RequestStop (); }; var d = new Dialog () { Title = "Select source file", Width = Dim.Percent (50), Height = Dim.Percent (50) }; d.Add (list); diff --git a/Terminal.Gui/Views/ComboBox.cs b/Terminal.Gui/Views/ComboBox.cs index 81dd94eda..dda8e9604 100644 --- a/Terminal.Gui/Views/ComboBox.cs +++ b/Terminal.Gui/Views/ComboBox.cs @@ -61,7 +61,7 @@ namespace Terminal.Gui { /// Client code can hook up to this event, it is /// raised when the selection has been confirmed. /// - public event EventHandler SelectedItemChanged; + public event EventHandler SelectedItemChanged; IList searchset; ustring text = ""; @@ -209,7 +209,7 @@ namespace Terminal.Gui { { // Note: Cannot rely on "listview.SelectedItem != lastSelectedItem" because the list is dynamic. // So we cannot optimize. Ie: Don't call if not changed - SelectedItemChanged?.Invoke (this, search.Text); + SelectedItemChanged?.Invoke (this, new ListViewItemEventArgs(listview.SelectedItem, search.Text)); return true; } diff --git a/UICatalog/Scenarios/ListsAndCombos.cs b/UICatalog/Scenarios/ListsAndCombos.cs index c007a69b3..065fbe263 100644 --- a/UICatalog/Scenarios/ListsAndCombos.cs +++ b/UICatalog/Scenarios/ListsAndCombos.cs @@ -13,7 +13,7 @@ namespace UICatalog.Scenarios { public override void Setup () { List items = new List (); - foreach (var dir in new [] { "/etc", @"\windows\System32" }) { + foreach (var dir in new [] { "/etc", @$"{Environment.GetEnvironmentVariable ("SystemRoot")}\System32" }) { if (Directory.Exists (dir)) { items = Directory.GetFiles (dir).Union(Directory.GetDirectories(dir)) .Select (Path.GetFileName) @@ -53,7 +53,7 @@ namespace UICatalog.Scenarios { }; comboBox.SetSource (items); - comboBox.SelectedItemChanged += (object sender, ustring text) => lbComboBox.Text = text; + comboBox.SelectedItemChanged += (object sender, ListViewItemEventArgs text) => lbComboBox.Text = (ustring)text.Value; Win.Add (lbComboBox, comboBox); } } From caa43eb37118414ac0d35a18c9e5076eec25f386 Mon Sep 17 00:00:00 2001 From: BDisp Date: Fri, 3 Jul 2020 23:38:34 +0100 Subject: [PATCH 34/44] Fixes #743. Added View argument to the Enter and Leave events. --- Terminal.Gui/Core/Responder.cs | 10 +++-- Terminal.Gui/Core/View.cs | 65 +++++++++++++++++++-------------- Terminal.Gui/Views/Menu.cs | 2 +- Terminal.Gui/Views/TextField.cs | 4 +- UnitTests/ResponderTests.cs | 4 +- UnitTests/ViewTests.cs | 4 +- 6 files changed, 50 insertions(+), 39 deletions(-) diff --git a/Terminal.Gui/Core/Responder.cs b/Terminal.Gui/Core/Responder.cs index c6fd75c74..15bb22b05 100644 --- a/Terminal.Gui/Core/Responder.cs +++ b/Terminal.Gui/Core/Responder.cs @@ -24,11 +24,12 @@ namespace Terminal.Gui { /// true if can focus; otherwise, false. public virtual bool CanFocus { get; set; } + internal bool hasFocus; /// /// Gets or sets a value indicating whether this has focus. /// /// true if has focus; otherwise, false. - public virtual bool HasFocus { get; internal set; } + public virtual bool HasFocus { get { return hasFocus; } } // Key handling /// @@ -133,7 +134,6 @@ namespace Terminal.Gui { return false; } - /// /// Method invoked when a mouse event is generated /// @@ -167,8 +167,9 @@ namespace Terminal.Gui { /// /// Method invoked when a view gets focus. /// + /// The view that is losing focus. /// true, if the event was handled, false otherwise. - public virtual bool OnEnter () + public virtual bool OnEnter (View view) { return false; } @@ -176,8 +177,9 @@ namespace Terminal.Gui { /// /// Method invoked when a view loses focus. /// + /// The view that is getting focus. /// true, if the event was handled, false otherwise. - public virtual bool OnLeave () + public virtual bool OnLeave (View view) { return false; } diff --git a/Terminal.Gui/Core/View.cs b/Terminal.Gui/Core/View.cs index 77f402f50..b798be760 100644 --- a/Terminal.Gui/Core/View.cs +++ b/Terminal.Gui/Core/View.cs @@ -898,23 +898,27 @@ namespace Terminal.Gui { /// public override bool HasFocus { get { - return base.HasFocus; + return hasFocus; } - internal set { - if (base.HasFocus != value) - if (value) - OnEnter (); - else - OnLeave (); - SetNeedsDisplay (); - base.HasFocus = value; + } - // Remove focus down the chain of subviews if focus is removed - if (!value && focused != null) { - focused.OnLeave (); - focused.HasFocus = false; - focused = null; - } + void SetHasFocus (bool value, View view) + { + if (hasFocus != value) { + hasFocus = value; + } + if (value) { + OnEnter (view); + } else { + OnLeave (view); + } + SetNeedsDisplay (); + + // Remove focus down the chain of subviews if focus is removed + if (!value && focused != null) { + focused.OnLeave (focused); + focused.hasFocus = false; + focused = null; } } @@ -925,35 +929,40 @@ namespace Terminal.Gui { /// /// Constructs. /// - public FocusEventArgs () { } + /// The view that gets or loses focus. + public FocusEventArgs (View view) { View = view; } /// /// Indicates if the current focus event has already been processed and the driver should stop notifying any other event subscriber. /// Its important to set this value to true specially when updating any View's layout from inside the subscriber method. /// public bool Handled { get; set; } + /// + /// Indicates the current view that gets or loses focus. + /// + public View View { get; set; } } /// - public override bool OnEnter () + public override bool OnEnter (View view) { - FocusEventArgs args = new FocusEventArgs (); + FocusEventArgs args = new FocusEventArgs (view); Enter?.Invoke (args); if (args.Handled) return true; - if (base.OnEnter ()) + if (base.OnEnter (view)) return true; return false; } /// - public override bool OnLeave () + public override bool OnLeave (View view) { - FocusEventArgs args = new FocusEventArgs (); + FocusEventArgs args = new FocusEventArgs (view); Leave?.Invoke (args); if (args.Handled) return true; - if (base.OnLeave ()) + if (base.OnLeave (view)) return true; return false; @@ -1123,10 +1132,10 @@ namespace Terminal.Gui { throw new ArgumentException ("the specified view is not part of the hierarchy of this view"); if (focused != null) - focused.HasFocus = false; + focused.SetHasFocus (false, view); focused = view; - focused.HasFocus = true; + focused.SetHasFocus (true, view); focused.EnsureFocus (); // Send focus upwards @@ -1320,7 +1329,7 @@ namespace Terminal.Gui { continue; } if (w.CanFocus && focused_idx != -1) { - focused.HasFocus = false; + focused.SetHasFocus (false, w); if (w != null && w.CanFocus) w.FocusLast (); @@ -1330,7 +1339,7 @@ namespace Terminal.Gui { } } if (focused != null) { - focused.HasFocus = false; + focused.SetHasFocus (false, focused); focused = null; } return false; @@ -1362,7 +1371,7 @@ namespace Terminal.Gui { continue; } if (w.CanFocus && focused_idx != -1) { - focused.HasFocus = false; + focused.SetHasFocus (false, w); if (w != null && w.CanFocus) w.FocusFirst (); @@ -1372,7 +1381,7 @@ namespace Terminal.Gui { } } if (focused != null) { - focused.HasFocus = false; + focused.SetHasFocus (false, focused); focused = null; } return false; diff --git a/Terminal.Gui/Views/Menu.cs b/Terminal.Gui/Views/Menu.cs index 554424f5e..aa71c87bf 100644 --- a/Terminal.Gui/Views/Menu.cs +++ b/Terminal.Gui/Views/Menu.cs @@ -535,7 +535,7 @@ namespace Terminal.Gui { if (item == null || !item.IsEnabled ()) disabled = true; if (item != null && !disabled) current = me.Y - 1; - HasFocus = true; + hasFocus = true; SetNeedsDisplay (); CheckSubMenu (); return true; diff --git a/Terminal.Gui/Views/TextField.cs b/Terminal.Gui/Views/TextField.cs index 2fa43f832..1624b6e34 100644 --- a/Terminal.Gui/Views/TextField.cs +++ b/Terminal.Gui/Views/TextField.cs @@ -93,14 +93,14 @@ namespace Terminal.Gui { } /// - public override bool OnLeave () + public override bool OnLeave (View view) { if (Application.mouseGrabView != null && Application.mouseGrabView == this) Application.UngrabMouse (); if (SelectedLength != 0 && !(Application.mouseGrabView is MenuBar)) ClearAllSelection (); - return base.OnLeave (); + return base.OnLeave (view); } /// diff --git a/UnitTests/ResponderTests.cs b/UnitTests/ResponderTests.cs index 1e662a608..43e9cf186 100644 --- a/UnitTests/ResponderTests.cs +++ b/UnitTests/ResponderTests.cs @@ -32,8 +32,8 @@ namespace Terminal.Gui { Assert.False (r.MouseEvent (new MouseEvent () { Flags = MouseFlags.AllEvents })); Assert.False (r.OnMouseEnter (new MouseEvent () { Flags = MouseFlags.AllEvents })); Assert.False (r.OnMouseLeave (new MouseEvent () { Flags = MouseFlags.AllEvents })); - Assert.False (r.OnEnter ()); - Assert.False (r.OnLeave ()); + Assert.False (r.OnEnter (new View ())); + Assert.False (r.OnLeave (new View ())); } } } diff --git a/UnitTests/ViewTests.cs b/UnitTests/ViewTests.cs index 43473921b..4904ff684 100644 --- a/UnitTests/ViewTests.cs +++ b/UnitTests/ViewTests.cs @@ -102,8 +102,8 @@ namespace Terminal.Gui { Assert.False (r.MouseEvent (new MouseEvent () { Flags = MouseFlags.AllEvents })); Assert.False (r.OnMouseEnter (new MouseEvent () { Flags = MouseFlags.AllEvents })); Assert.False (r.OnMouseLeave (new MouseEvent () { Flags = MouseFlags.AllEvents })); - Assert.False (r.OnEnter ()); - Assert.False (r.OnLeave ()); + Assert.False (r.OnEnter (new View ())); + Assert.False (r.OnLeave (new View ())); // TODO: Add more } From 89afea2e7dfa59c5b103566db6087dd86c674e30 Mon Sep 17 00:00:00 2001 From: BDisp Date: Fri, 3 Jul 2020 23:46:11 +0100 Subject: [PATCH 35/44] Fixing the ComboBox OnEnter. --- Terminal.Gui/Views/ComboBox.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Terminal.Gui/Views/ComboBox.cs b/Terminal.Gui/Views/ComboBox.cs index aff1f2c6f..2c3e4d5df 100644 --- a/Terminal.Gui/Views/ComboBox.cs +++ b/Terminal.Gui/Views/ComboBox.cs @@ -184,7 +184,7 @@ namespace Terminal.Gui { } /// - public override bool OnEnter () + public override bool OnEnter (View view) { if (!search.HasFocus) this.SetFocus (search); From 670595d48856ed2a8fb16d5aa0ab8042757a3750 Mon Sep 17 00:00:00 2001 From: Ross Ferguson Date: Sat, 4 Jul 2020 03:24:57 +0100 Subject: [PATCH 36/44] ComboBox. Use Clear() instead of Redraw() --- Terminal.Gui/Views/ComboBox.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Terminal.Gui/Views/ComboBox.cs b/Terminal.Gui/Views/ComboBox.cs index dda8e9604..644d3b4c1 100644 --- a/Terminal.Gui/Views/ComboBox.cs +++ b/Terminal.Gui/Views/ComboBox.cs @@ -380,8 +380,8 @@ namespace Terminal.Gui { private void ShowList () { listview.SetSource (searchset); + listview.Clear (); // Ensure list shrinks in Dialog as you type listview.Height = CalculatetHeight (); - listview.Redraw (new Rect (0, 0, Bounds.Width, Bounds.Height)); // Ensure list shrinks in Dialog this.SuperView?.BringSubviewToFront (this); } From f9d55c9d082ffed373d86f01ee02b49caac7876b Mon Sep 17 00:00:00 2001 From: BDisp Date: Sat, 4 Jul 2020 09:43:18 +0100 Subject: [PATCH 37/44] Ensures the HasFocus property only can be set by the SetHasFocus method. Removed unnecessary code in Menu. --- Terminal.Gui/Core/Responder.cs | 3 +-- Terminal.Gui/Core/View.cs | 1 + Terminal.Gui/Views/Menu.cs | 2 -- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/Terminal.Gui/Core/Responder.cs b/Terminal.Gui/Core/Responder.cs index 15bb22b05..52fce4b21 100644 --- a/Terminal.Gui/Core/Responder.cs +++ b/Terminal.Gui/Core/Responder.cs @@ -24,12 +24,11 @@ namespace Terminal.Gui { /// true if can focus; otherwise, false. public virtual bool CanFocus { get; set; } - internal bool hasFocus; /// /// Gets or sets a value indicating whether this has focus. /// /// true if has focus; otherwise, false. - public virtual bool HasFocus { get { return hasFocus; } } + public virtual bool HasFocus { get; } // Key handling /// diff --git a/Terminal.Gui/Core/View.cs b/Terminal.Gui/Core/View.cs index b798be760..762c3702f 100644 --- a/Terminal.Gui/Core/View.cs +++ b/Terminal.Gui/Core/View.cs @@ -895,6 +895,7 @@ namespace Terminal.Gui { } } + bool hasFocus; /// public override bool HasFocus { get { diff --git a/Terminal.Gui/Views/Menu.cs b/Terminal.Gui/Views/Menu.cs index aa71c87bf..40d53fa22 100644 --- a/Terminal.Gui/Views/Menu.cs +++ b/Terminal.Gui/Views/Menu.cs @@ -535,8 +535,6 @@ namespace Terminal.Gui { if (item == null || !item.IsEnabled ()) disabled = true; if (item != null && !disabled) current = me.Y - 1; - hasFocus = true; - SetNeedsDisplay (); CheckSubMenu (); return true; } From b9c8758d2d603b2ad4f1e01eed0ae8f6560dd045 Mon Sep 17 00:00:00 2001 From: Ross Ferguson Date: Sun, 5 Jul 2020 01:50:59 +0100 Subject: [PATCH 38/44] ComboBox. Adhere to ListView interface, added:- SelectedItem (read only) from @BDisp OpenSelectedItem --- Example/demo.cs | 7 ++-- Terminal.Gui/Views/ComboBox.cs | 50 ++++++++++++++++++++++----- UICatalog/Scenarios/ListsAndCombos.cs | 7 ++-- 3 files changed, 50 insertions(+), 14 deletions(-) diff --git a/Example/demo.cs b/Example/demo.cs index edb9ef34b..da61d517b 100644 --- a/Example/demo.cs +++ b/Example/demo.cs @@ -449,7 +449,8 @@ static class Demo { static void ComboBoxDemo () { - List items = new List (); + //TODO: Duplicated code in ListsAndCombos.cs Consider moving to shared assembly + var items = new List (); foreach (var dir in new [] { "/etc", @$"{Environment.GetEnvironmentVariable ("SystemRoot")}\System32" }) { if (Directory.Exists (dir)) { items = Directory.GetFiles (dir).Union (Directory.GetDirectories (dir)) @@ -459,8 +460,8 @@ static class Demo { } } var list = new ComboBox () { Width = Dim.Fill(), Height = Dim.Fill() }; - list.SetSource(items.ToList()); - list.SelectedItemChanged += (object sender, ListViewItemEventArgs text) => { Application.RequestStop (); }; + list.SetSource(items); + list.OpenSelectedItem += (ListViewItemEventArgs text) => { Application.RequestStop (); }; var d = new Dialog () { Title = "Select source file", Width = Dim.Percent (50), Height = Dim.Percent (50) }; d.Add (list); diff --git a/Terminal.Gui/Views/ComboBox.cs b/Terminal.Gui/Views/ComboBox.cs index 644d3b4c1..7323fdf91 100644 --- a/Terminal.Gui/Views/ComboBox.cs +++ b/Terminal.Gui/Views/ComboBox.cs @@ -55,13 +55,14 @@ namespace Terminal.Gui { } /// - /// Changed event, raised when the selection has been confirmed. + /// This event is raised when the selected item in the has changed. /// - /// - /// Client code can hook up to this event, it is - /// raised when the selection has been confirmed. - /// - public event EventHandler SelectedItemChanged; + public Action SelectedItemChanged; + + /// + /// This event is raised when the user Double Clicks on an item or presses ENTER to open the selected item. + /// + public Action OpenSelectedItem; IList searchset; ustring text = ""; @@ -153,6 +154,12 @@ namespace Terminal.Gui { }; } + /// + /// Gets the index of the currently selected item in the + /// + /// The selected item or -1 none selected. + public int SelectedItem { private set; get; } + bool isShow = false; /// @@ -209,7 +216,19 @@ namespace Terminal.Gui { { // Note: Cannot rely on "listview.SelectedItem != lastSelectedItem" because the list is dynamic. // So we cannot optimize. Ie: Don't call if not changed - SelectedItemChanged?.Invoke (this, new ListViewItemEventArgs(listview.SelectedItem, search.Text)); + SelectedItemChanged?.Invoke (new ListViewItemEventArgs(SelectedItem, search.Text)); + + return true; + } + + /// + /// Invokes the OnOpenSelectedItem event if it is defined. + /// + /// + public virtual bool OnOpenSelectedItem () + { + var value = search.Text; + OpenSelectedItem?.Invoke (new ListViewItemEventArgs (SelectedItem, value)); return true; } @@ -301,6 +320,8 @@ namespace Terminal.Gui { this.text = search.Text = text.ToString(); search.CursorPosition = 0; search.TextChanged += Search_Changed; + SelectedItem = GetSelectedItemFromSource (this.text); + OnSelectedChanged (); } private void Selected () @@ -313,10 +334,23 @@ namespace Terminal.Gui { SetValue (searchset [listview.SelectedItem]); search.CursorPosition = search.Text.RuneCount; Search_Changed (search.Text); - OnSelectedChanged (); + OnOpenSelectedItem (); Reset (keepSearchText: true); } + private int GetSelectedItemFromSource (ustring value) + { + if (source == null) { + return -1; + } + for (int i = 0; i < source.Count; i++) { + if (source.ToList () [i].ToString () == value) { + return i; + } + } + return -1; + } + /// /// Reset to full original list /// diff --git a/UICatalog/Scenarios/ListsAndCombos.cs b/UICatalog/Scenarios/ListsAndCombos.cs index 065fbe263..7d44e8a89 100644 --- a/UICatalog/Scenarios/ListsAndCombos.cs +++ b/UICatalog/Scenarios/ListsAndCombos.cs @@ -12,7 +12,8 @@ namespace UICatalog.Scenarios { public override void Setup () { - List items = new List (); + //TODO: Duplicated code in Demo.cs Consider moving to shared assembly + var items = new List (); foreach (var dir in new [] { "/etc", @$"{Environment.GetEnvironmentVariable ("SystemRoot")}\System32" }) { if (Directory.Exists (dir)) { items = Directory.GetFiles (dir).Union(Directory.GetDirectories(dir)) @@ -35,7 +36,7 @@ namespace UICatalog.Scenarios { Height = Dim.Fill(2), Width = Dim.Percent (40) }; - listview.OpenSelectedItem += (ListViewItemEventArgs e) => lbListView.Text = items [listview.SelectedItem]; + listview.SelectedItemChanged += (ListViewItemEventArgs e) => lbListView.Text = items [listview.SelectedItem]; Win.Add (lbListView, listview); // ComboBox @@ -53,7 +54,7 @@ namespace UICatalog.Scenarios { }; comboBox.SetSource (items); - comboBox.SelectedItemChanged += (object sender, ListViewItemEventArgs text) => lbComboBox.Text = (ustring)text.Value; + comboBox.SelectedItemChanged += (ListViewItemEventArgs text) => lbComboBox.Text = items[comboBox.SelectedItem]; Win.Add (lbComboBox, comboBox); } } From a1202fe55e8031cb7887689464575fb96e032ddb Mon Sep 17 00:00:00 2001 From: BDisp Date: Sun, 5 Jul 2020 02:04:40 +0100 Subject: [PATCH 39/44] Changed focused to this. --- Terminal.Gui/Core/View.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Terminal.Gui/Core/View.cs b/Terminal.Gui/Core/View.cs index 762c3702f..47481724e 100644 --- a/Terminal.Gui/Core/View.cs +++ b/Terminal.Gui/Core/View.cs @@ -1382,7 +1382,7 @@ namespace Terminal.Gui { } } if (focused != null) { - focused.SetHasFocus (false, focused); + focused.SetHasFocus (false, this); focused = null; } return false; From 7a32bcf6af2d041b5ad58edc507c9b74cc9aa505 Mon Sep 17 00:00:00 2001 From: BDisp Date: Sun, 5 Jul 2020 21:10:24 +0100 Subject: [PATCH 40/44] Fixing some bugs. --- Terminal.Gui/Core/View.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Terminal.Gui/Core/View.cs b/Terminal.Gui/Core/View.cs index 47481724e..b7ec0c0b6 100644 --- a/Terminal.Gui/Core/View.cs +++ b/Terminal.Gui/Core/View.cs @@ -917,8 +917,8 @@ namespace Terminal.Gui { // Remove focus down the chain of subviews if focus is removed if (!value && focused != null) { - focused.OnLeave (focused); - focused.hasFocus = false; + focused.OnLeave (view); + focused.SetHasFocus (false, view); focused = null; } } @@ -1135,8 +1135,9 @@ namespace Terminal.Gui { if (focused != null) focused.SetHasFocus (false, view); + var f = focused; focused = view; - focused.SetHasFocus (true, view); + focused.SetHasFocus (true, f); focused.EnsureFocus (); // Send focus upwards @@ -1340,7 +1341,7 @@ namespace Terminal.Gui { } } if (focused != null) { - focused.SetHasFocus (false, focused); + focused.SetHasFocus (false, this); focused = null; } return false; From e8972f43addafca5f7b1a2b1be1a5ec7bdd576af Mon Sep 17 00:00:00 2001 From: BDisp Date: Mon, 6 Jul 2020 00:38:07 +0100 Subject: [PATCH 41/44] Changed to removed because it is safer to perform actions after deletion. --- Terminal.Gui/Core/View.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Terminal.Gui/Core/View.cs b/Terminal.Gui/Core/View.cs index be569d2e9..ba408a7b5 100644 --- a/Terminal.Gui/Core/View.cs +++ b/Terminal.Gui/Core/View.cs @@ -132,7 +132,7 @@ namespace Terminal.Gui { /// /// Event fired when a subview is being removed from this view. /// - public Action Removing; + public Action Removed; /// /// Event fired when the view gets focus. @@ -607,12 +607,12 @@ namespace Terminal.Gui { if (view == null || subviews == null) return; - OnRemoving (view); SetNeedsLayout (); SetNeedsDisplay (); var touched = view.Frame; subviews.Remove (view); view.container = null; + OnRemoved (view); if (subviews.Count < 1) this.CanFocus = false; @@ -958,9 +958,9 @@ namespace Terminal.Gui { /// Method invoked when a subview is being removed from this view. /// /// The subview being removed. - public virtual void OnRemoving (View view) + public virtual void OnRemoved (View view) { - view.Removing?.Invoke (this); + view.Removed?.Invoke (this); } /// From e0c6067b3914845a684cd79266b4b38c6c34227f Mon Sep 17 00:00:00 2001 From: BDisp Date: Mon, 6 Jul 2020 00:45:56 +0100 Subject: [PATCH 42/44] Fixing the Removed test. --- UnitTests/ViewTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/UnitTests/ViewTests.cs b/UnitTests/ViewTests.cs index 4ba0c1c4f..4adb55374 100644 --- a/UnitTests/ViewTests.cs +++ b/UnitTests/ViewTests.cs @@ -146,8 +146,8 @@ namespace Terminal.Gui { Assert.True (v.SuperView == e); }; - v.Removing += (View e) => { - Assert.True (v.SuperView == e); + v.Removed += (View e) => { + Assert.True (v.SuperView == null); }; t.Add (v); From d464525d61dcfdbd50c2c083c06dc6bef173b3d5 Mon Sep 17 00:00:00 2001 From: Ross Ferguson Date: Mon, 6 Jul 2020 05:06:49 +0100 Subject: [PATCH 43/44] ComboBox. Wire-up Home/End keys down to listview --- Terminal.Gui/Views/ComboBox.cs | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/Terminal.Gui/Views/ComboBox.cs b/Terminal.Gui/Views/ComboBox.cs index 7323fdf91..10190ff5e 100644 --- a/Terminal.Gui/Views/ComboBox.cs +++ b/Terminal.Gui/Views/ComboBox.cs @@ -276,13 +276,31 @@ namespace Terminal.Gui { return true; } - if(e.Key == Key.PageDown) { - listview.MovePageDown (); + if(e.Key == Key.PageDown) { + if (listview.SelectedItem != -1) { + listview.MovePageDown (); + } return true; } - if (e.Key == Key.PageUp) { - listview.MovePageUp (); + if (e.Key == Key.PageUp) { + if (listview.SelectedItem != -1) { + listview.MovePageUp (); + } + return true; + } + + if (e.Key == Key.Home) { + if (listview.SelectedItem != -1) { + listview.MoveHome (); + } + return true; + } + + if(e.Key == Key.End) { + if(listview.SelectedItem != -1) { + listview.MoveEnd (); + } return true; } From 3800a233b34e6a468be5f8147962fae4da71e3c2 Mon Sep 17 00:00:00 2001 From: Ross Ferguson Date: Mon, 6 Jul 2020 13:05:19 +0100 Subject: [PATCH 44/44] ComboBox. Fix #742 --- Terminal.Gui/Views/ComboBox.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Terminal.Gui/Views/ComboBox.cs b/Terminal.Gui/Views/ComboBox.cs index 10190ff5e..c00f8c235 100644 --- a/Terminal.Gui/Views/ComboBox.cs +++ b/Terminal.Gui/Views/ComboBox.cs @@ -254,6 +254,12 @@ namespace Terminal.Gui { return false; // allow tab-out to next control } + if(e.Key == Key.BackTab) { + base.ProcessKey (e); + this.FocusPrev (); + return false; // allow tab-out to prev control + } + if (e.Key == Key.Enter && listview.HasFocus) { Selected (); return true;