mirror of
https://github.com/gui-cs/Terminal.Gui.git
synced 2025-12-26 15:57:56 +01:00
ComboBox. Support parameterless constructor. Update scenario demo
This commit is contained in:
@@ -24,15 +24,28 @@ namespace Terminal.Gui {
|
||||
/// </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>
|
||||
@@ -41,24 +54,34 @@ namespace Terminal.Gui {
|
||||
/// <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) {
|
||||
@@ -70,10 +93,31 @@ namespace Terminal.Gui {
|
||||
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;
|
||||
@@ -83,17 +127,24 @@ namespace Terminal.Gui {
|
||||
|
||||
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/>
|
||||
@@ -128,7 +179,7 @@ namespace Terminal.Gui {
|
||||
Changed?.Invoke (this, text);
|
||||
|
||||
searchset.Clear();
|
||||
listview.SetSource(new List<string> ());
|
||||
listview.Clear ();
|
||||
listview.Height = 0;
|
||||
this.SetFocus(search);
|
||||
|
||||
@@ -141,6 +192,9 @@ namespace Terminal.Gui {
|
||||
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;
|
||||
@@ -204,6 +258,9 @@ namespace Terminal.Gui {
|
||||
|
||||
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
|
||||
@@ -226,12 +283,30 @@ namespace Terminal.Gui {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Internal width
|
||||
/// Internal width of search list
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private int CalculateWidth()
|
||||
private int CalculateWidth ()
|
||||
{
|
||||
return autoHide? Math.Max (1, width - 1) : width;
|
||||
return autoHide ? Math.Max (1, width - 1) : width;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get DimAbsolute as integer value
|
||||
/// </summary>
|
||||
/// <param name="dim"></param>
|
||||
/// <returns></returns>
|
||||
private int GetDimAsInt(Dim dim)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,10 +15,9 @@ namespace UICatalog.Scenarios {
|
||||
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 ();
|
||||
}
|
||||
}
|
||||
@@ -45,11 +44,14 @@ namespace UICatalog.Scenarios {
|
||||
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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user