소스 검색

Merge pull request #607 from fergusonr/combobox_fixes

ComboBox. Support parameterless constructor. Update scenario demo
Charlie Kindel 5 년 전
부모
커밋
254b7799a6
2개의 변경된 파일103개의 추가작업 그리고 26개의 파일을 삭제
  1. 98 23
      Terminal.Gui/Views/ComboBox.cs
  2. 5 3
      UICatalog/Scenarios/ListsAndCombos.cs

+ 98 - 23
Terminal.Gui/Views/ComboBox.cs

@@ -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 ()
+		{
+			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);
 		}
 	}
 }

+ 5 - 3
UICatalog/Scenarios/ListsAndCombos.cs

@@ -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);
 		}