Skip to content

Commit

Permalink
Merge pull request #607 from fergusonr/combobox_fixes
Browse files Browse the repository at this point in the history
ComboBox. Support parameterless constructor. Update scenario demo
  • Loading branch information
tig authored Jun 4, 2020
2 parents d6205e4 + b71d72f commit 254b779
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 26 deletions.
121 changes: 98 additions & 23 deletions Terminal.Gui/Views/ComboBox.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,28 @@ public class ComboBox : View {
/// </remarks>
public event EventHandler<ustring> Changed;

readonly IList<string> listsource;
IList<string> listsource;
IList<string> searchset;
ustring text = "";
readonly TextField search;
readonly ListView listview;
readonly int height;
readonly int width;
TextField search;
ListView listview;
int x;
int y;
int height;
int width;
bool autoHide = true;

/// <summary>
/// Public constructor
/// </summary>
public ComboBox () : base()
{
search = new TextField ("") { LayoutStyle = LayoutStyle.Computed };
listview = new ListView () { LayoutStyle = LayoutStyle.Computed, CanFocus = true /* why? */ };

Initialize ();
}

/// <summary>
/// Public constructor
/// </summary>
Expand All @@ -41,24 +54,34 @@ public class ComboBox : View {
/// <param name="w">The width</param>
/// <param name="h">The height</param>
/// <param name="source">Auto completion source</param>
public ComboBox(int x, int y, int w, int h, IList<string> source)
public ComboBox (int x, int y, int w, int h, IList<string> source)
{
listsource = new List<string>(source);
SetSource (source);
this.x = x;
this.y = y;
height = h;
width = w;
search = new TextField(x, y, w, "");
search.Changed += Search_Changed;

listview = new ListView(new Rect(x, y + 1, w, 0), listsource.ToList())
{
search = new TextField (x, y, w, "");

listview = new ListView (new Rect (x, y + 1, w, 0), listsource.ToList ()) {
LayoutStyle = LayoutStyle.Computed,
};

Initialize ();
}

private void Initialize()
{
search.Changed += Search_Changed;

listview.SelectedChanged += (object sender, ListViewItemEventArgs e) => {
if(searchset.Count > 0)
SetValue (searchset [listview.SelectedItem]);
};

LayoutComplete += (sender, a) => {
// TODO: LayoutComplete event breaks cursor up/down. Revert to Application.Loaded
Application.Loaded += (sender, a) => {
// Determine if this view is hosted inside a dialog
for (View view = this.SuperView; view != null; view = view.SuperView) {
if (view is Dialog) {
Expand All @@ -70,10 +93,31 @@ public ComboBox(int x, int y, int w, int h, IList<string> source)
searchset = autoHide ? new List<string> () : listsource;

// Needs to be re-applied for LayoutStyle.Computed
listview.X = x;
listview.Y = y + 1;
listview.Width = CalculateWidth();
listview.Height = CalculatetHeight ();
// If Dim or Pos are null, these are the from the parametrized constructor
if (X == null)
listview.X = x;

if (Y == null)
listview.Y = y + 1;
else
listview.Y = Pos.Bottom (search);

if (Width == null)
listview.Width = CalculateWidth ();
else {
width = GetDimAsInt (Width);
listview.Width = CalculateWidth ();
}

if (Height == null)
listview.Height = CalculatetHeight ();
else {
height = GetDimAsInt (Height);
listview.Height = CalculatetHeight ();
}

if (this.Text != null)
Search_Changed (search, Text);

if (autoHide)
listview.ColorScheme = Colors.Menu;
Expand All @@ -83,17 +127,24 @@ public ComboBox(int x, int y, int w, int h, IList<string> source)

search.MouseClick += Search_MouseClick;

this.Add(listview);
this.Add(search);
this.Add(listview, search);
this.SetFocus(search);
}

/// <summary>
/// Set search list source
/// </summary>
public void SetSource(IList<string> source)
{
listsource = new List<string> (source);
}

private void Search_MouseClick (object sender, MouseEventEventArgs e)
{
if (e.MouseEvent.Flags != MouseFlags.Button1Clicked)
return;

SuperView.SetFocus (((View)sender));
SuperView.SetFocus ((View)sender);
}

///<inheritdoc/>
Expand Down Expand Up @@ -128,7 +179,7 @@ public override bool ProcessKey(KeyEvent e)
Changed?.Invoke (this, text);

searchset.Clear();
listview.SetSource(new List<string> ());
listview.Clear ();
listview.Height = 0;
this.SetFocus(search);

Expand All @@ -141,6 +192,9 @@ public override bool ProcessKey(KeyEvent e)
return true;
}

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
{
search.CursorPosition = search.Text.Length;
Expand Down Expand Up @@ -204,6 +258,9 @@ private void Reset()

private void Search_Changed (object sender, ustring text)
{
if (listsource == null) // Object initialization
return;

if (string.IsNullOrEmpty (search.Text.ToString()))
searchset = autoHide ? new List<string> () : listsource;
else
Expand All @@ -226,12 +283,30 @@ private int CalculatetHeight ()
}

/// <summary>
/// Internal width
/// Internal width of search list
/// </summary>
/// <returns></returns>
private int CalculateWidth ()
{
return autoHide ? Math.Max (1, width - 1) : width;
}

/// <summary>
/// Get DimAbsolute as integer value
/// </summary>
/// <param name="dim"></param>
/// <returns></returns>
private int CalculateWidth()
private int GetDimAsInt(Dim dim)
{
return autoHide? Math.Max (1, width - 1) : width;
if (!(dim is Dim.DimAbsolute))
throw new ArgumentException ("Dim must be an absolute value");

// Anchor in the case of DimAbsolute returns absolute value. No documentation on what Anchor() does so not sure if this will change in the future.
//
// TODO: Does Dim need:-
// public static implicit operator int (Dim d)
//
return dim.Anchor (0);
}
}
}
8 changes: 5 additions & 3 deletions UICatalog/Scenarios/ListsAndCombos.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,9 @@ public override void Setup ()
List<string> items = new List<string> ();
foreach (var dir in new [] { "/etc", @"\windows\System32" }) {
if (Directory.Exists (dir)) {
items = Directory.GetFiles (dir)
items = Directory.GetFiles (dir).Union(Directory.GetDirectories(dir))
.Select (Path.GetFileName)
.Where (x => char.IsLetterOrDigit (x [0]))
.Distinct ()
.OrderBy (x => x).ToList ();
}
}
Expand All @@ -45,11 +44,14 @@ public override void Setup ()
Width = 30
};

var comboBox = new ComboBox (0, 0, 30, 10, items) {
var comboBox = new ComboBox() {
X = Pos.Right(listview) + 1 ,
Y = Pos.Bottom (lbListView) +1,
Height = 10,
Width = 30
};
comboBox.SetSource (items);

comboBox.Changed += (object sender, ustring text) => lbComboBox.Text = text;
Win.Add (lbComboBox, comboBox);
}
Expand Down

0 comments on commit 254b779

Please sign in to comment.