From 3e7d2ef570196b03ca3b8323988160b98960b4d9 Mon Sep 17 00:00:00 2001 From: Thomas Nind <31306100+tznind@users.noreply.github.com> Date: Sun, 6 Feb 2022 22:44:33 +0000 Subject: [PATCH] Fixes #1584 - ComboBox is hiding elements below from being clicked/focused (#1585) * Fixes #1584 * Fixes https://github.com/migueldeicaza/gui.cs/issues/1584#issuecomment-1027987475 * Fixes some bugs with SelectedItem. * Ensures updating the ComboBox text on leaving the control. Co-authored-by: BDisp --- Terminal.Gui/Views/ComboBox.cs | 45 +++++++++++--- UICatalog/Scenarios/ComboBoxIteration.cs | 78 ++++++++++++++++++++++++ UICatalog/Scenarios/ListsAndCombos.cs | 2 +- 3 files changed, 116 insertions(+), 9 deletions(-) create mode 100644 UICatalog/Scenarios/ComboBoxIteration.cs diff --git a/Terminal.Gui/Views/ComboBox.cs b/Terminal.Gui/Views/ComboBox.cs index 8a2d430a8..aa8a82245 100644 --- a/Terminal.Gui/Views/ComboBox.cs +++ b/Terminal.Gui/Views/ComboBox.cs @@ -31,6 +31,8 @@ namespace Terminal.Gui { // Only need to refresh list if its been added to a container view if (SuperView != null && SuperView.Subviews.Contains (this)) { + SelectedItem = -1; + search.Text = ""; Search_Changed (""); SetNeedsDisplay (); } @@ -64,7 +66,7 @@ namespace Terminal.Gui { /// public event Action OpenSelectedItem; - readonly IList searchset = new List (); + readonly IList searchset = new List (); ustring text = ""; readonly TextField search; readonly ListView listview; @@ -156,13 +158,29 @@ namespace Terminal.Gui { }; } + private bool isShow = false; + private int selectedItem = -1; + /// /// Gets the index of the currently selected item in the /// /// The selected item or -1 none selected. - public int SelectedItem { private set; get; } + public int SelectedItem { + get => selectedItem; + set { + if (selectedItem != value && (value == -1 + || (source != null && value > -1 && value < source.Count))) { - bool isShow = false; + selectedItem = value; + if (selectedItem != -1) { + SetValue (source.ToList () [selectedItem].ToString (), true); + } else { + SetValue ("", true); + } + OnSelectedChanged (); + } + } + } /// public new ColorScheme ColorScheme { @@ -244,6 +262,11 @@ namespace Terminal.Gui { /// public override bool OnLeave (View view) { + if (source?.Count > 0 && selectedItem > -1 && selectedItem < source.Count - 1 + && text != source.ToList () [selectedItem].ToString ()) { + + SetValue (source.ToList () [selectedItem].ToString ()); + } if (autoHide && isShow && view != this && view != search && view != listview) { isShow = false; HideList (); @@ -392,22 +415,26 @@ namespace Terminal.Gui { } } - private void SetValue (object text) + private void SetValue (object text, bool isFromSelectedItem = false) { search.TextChanged -= Search_Changed; this.text = search.Text = text.ToString (); search.CursorPosition = 0; search.TextChanged += Search_Changed; - SelectedItem = GetSelectedItemFromSource (this.text); - OnSelectedChanged (); + if (!isFromSelectedItem) { + selectedItem = GetSelectedItemFromSource (this.text); + OnSelectedChanged (); + } } private void Selected () { isShow = false; listview.TabStop = false; + if (listview.Source.Count == 0 || (searchset?.Count ?? 0) == 0) { text = ""; + HideList (); return; } @@ -416,6 +443,7 @@ namespace Terminal.Gui { Search_Changed (search.Text); OnOpenSelectedItem (); Reset (keepSearchText: true); + HideList (); } private int GetSelectedItemFromSource (ustring value) @@ -452,7 +480,7 @@ namespace Terminal.Gui { private void ResetSearchSet (bool noCopy = false) { - searchset.Clear (); + searchset.Clear (); if (autoHide || noCopy) return; @@ -496,7 +524,7 @@ namespace Terminal.Gui { /// Consider making public private void ShowList () { - listview.SetSource (searchset); + listview.SetSource (searchset); listview.Clear (); // Ensure list shrinks in Dialog as you type listview.Height = CalculatetHeight (); this.SuperView?.BringSubviewToFront (this); @@ -513,6 +541,7 @@ namespace Terminal.Gui { Reset (SelectedItem > -1); listview.Clear (rect); listview.TabStop = false; + SuperView?.SendSubviewToBack (this); SuperView?.SetNeedsDisplay (rect); } diff --git a/UICatalog/Scenarios/ComboBoxIteration.cs b/UICatalog/Scenarios/ComboBoxIteration.cs new file mode 100644 index 000000000..0cda1edf2 --- /dev/null +++ b/UICatalog/Scenarios/ComboBoxIteration.cs @@ -0,0 +1,78 @@ +using System.Collections.Generic; +using Terminal.Gui; + +namespace UICatalog.Scenarios { + [ScenarioMetadata (Name: "ComboBoxIteration", Description: "ComboBox iteration.")] + [ScenarioCategory ("Controls")] + public class ComboBoxIteration : Scenario { + public override void Setup () + { + var items = new List () { "one", "two", "three" }; + + var lbListView = new Label () { + AutoSize = false, + Width = 10, + Height = 1 + }; + Win.Add (lbListView); + + var listview = new ListView (items) { + Y = Pos.Bottom (lbListView) + 1, + Width = 10, + Height = Dim.Fill (2) + }; + Win.Add (listview); + + var lbComboBox = new Label () { + ColorScheme = Colors.TopLevel, + X = Pos.Right (lbListView) + 1, + Width = Dim.Percent (40) + }; + + var comboBox = new ComboBox () { + X = Pos.Right (listview) + 1, + Y = Pos.Bottom (lbListView) + 1, + Height = Dim.Fill (2), + Width = Dim.Percent (40) + }; + comboBox.SetSource (items); + + listview.SelectedItemChanged += (e) => { + lbListView.Text = items [e.Item]; + comboBox.SelectedItem = e.Item; + }; + + comboBox.SelectedItemChanged += (ListViewItemEventArgs text) => { + if (text.Item != -1) { + lbComboBox.Text = text.Value.ToString (); + listview.SelectedItem = text.Item; + } + }; + Win.Add (lbComboBox, comboBox); + Win.Add (new TextField { X = Pos.Right (listview) + 1, Y = Pos.Top (comboBox) + 3, Height = 1, Width = 20 }); + + var btnTwo = new Button ("Two") { + X = Pos.Right (comboBox) + 1, + }; + btnTwo.Clicked += () => { + items = new List () { "one", "two" }; + comboBox.SetSource (items); + listview.SetSource (items); + listview.SelectedItem = 0; + }; + Win.Add (btnTwo); + + var btnThree = new Button ("Three") { + X = Pos.Right (comboBox) + 1, + Y = Pos.Top (comboBox) + }; + btnThree.Clicked += () => { + items = new List () { "one", "two", "three" }; + comboBox.SetSource (items); + listview.SetSource (items); + listview.SelectedItem = 0; + }; + Win.Add (btnThree); + } + } +} \ No newline at end of file diff --git a/UICatalog/Scenarios/ListsAndCombos.cs b/UICatalog/Scenarios/ListsAndCombos.cs index ed06a6639..42f121457 100644 --- a/UICatalog/Scenarios/ListsAndCombos.cs +++ b/UICatalog/Scenarios/ListsAndCombos.cs @@ -80,7 +80,7 @@ namespace UICatalog.Scenarios { }; comboBox.SetSource (items); - comboBox.SelectedItemChanged += (ListViewItemEventArgs text) => lbComboBox.Text = items[comboBox.SelectedItem]; + comboBox.SelectedItemChanged += (ListViewItemEventArgs text) => lbComboBox.Text = text.Value.ToString (); Win.Add (lbComboBox, comboBox); var scrollBarCbx = new ScrollBarView (comboBox.Subviews [1], true);