瀏覽代碼

Merge pull request #627 from BDisp/button-text-alignment

Added TextAlignment to the Button. Update FSarpExample.
Charlie Kindel 5 年之前
父節點
當前提交
57e6953ea9
共有 3 個文件被更改,包括 124 次插入16 次删除
  1. 81 13
      Terminal.Gui/Views/Button.cs
  2. 2 2
      Terminal.Gui/Views/Label.cs
  3. 41 1
      UICatalog/Scenarios/Buttons.cs

+ 81 - 13
Terminal.Gui/Views/Button.cs

@@ -30,6 +30,7 @@ namespace Terminal.Gui {
 		Rune hot_key;
 		int hot_pos = -1;
 		bool is_default;
+		TextAlignment textAlignment = TextAlignment.Centered;
 
 		/// <summary>
 		/// Gets or sets whether the <see cref="Button"/> is the default action to activate in a dialog.
@@ -118,7 +119,6 @@ namespace Terminal.Gui {
 			this.IsDefault = is_default;
 		}
 
-
 		int SetWidthHeight (ustring text, bool is_default)
 		{
 			int w = text.Length + 4 + (is_default ? 2 : 0);
@@ -145,6 +145,15 @@ namespace Terminal.Gui {
 			}
 		}
 
+		///<inheritdoc/>
+		public TextAlignment TextAlignment {
+			get => textAlignment;
+			set {
+				textAlignment = value;
+				SetNeedsDisplay ();
+			}
+		}
+
 		internal void Update ()
 		{
 			if (IsDefault)
@@ -176,24 +185,84 @@ namespace Terminal.Gui {
 			SetNeedsDisplay ();
 		}
 
+		int c_hot_pos;
+
 		///<inheritdoc/>
 		public override void Redraw (Rect bounds)
 		{
 			Driver.SetAttribute (HasFocus ? ColorScheme.Focus : ColorScheme.Normal);
 			Move (0, 0);
-			Driver.AddStr (shown_text);
 
-			if (hot_pos != -1) {
-				Move (hot_pos, 0);
+			var caption = shown_text;
+			c_hot_pos = hot_pos;
+			int start;
+
+			if (Frame.Width > shown_text.Length + 1) {
+				switch (TextAlignment) {
+				case TextAlignment.Left:
+					caption += new string (' ', Frame.Width - caption.Length);
+					break;
+				case TextAlignment.Right:
+					start = Frame.Width - caption.Length;
+					caption = $"{new string (' ', Frame.Width - caption.Length)}{caption}";
+					if (c_hot_pos > -1) {
+						c_hot_pos += start;
+					}
+					break;
+				case TextAlignment.Centered:
+					start = Frame.Width / 2 - caption.Length / 2;
+					caption = $"{new string (' ', start)}{caption}{new string (' ', Frame.Width - caption.Length - start)}";
+					if (c_hot_pos > -1) {
+						c_hot_pos += start;
+					}
+					break;
+				case TextAlignment.Justified:
+					var words = caption.ToString ().Split (new string [] { " " }, StringSplitOptions.RemoveEmptyEntries);
+					var wLen = GetWordsLength (words);
+					var space = (Frame.Width - wLen) / (caption.Length - wLen);
+					caption = "";
+					for (int i = 0; i < words.Length; i++) {
+						if (i == words.Length - 1) {
+							caption += new string (' ', Frame.Width - caption.Length - 1);
+							caption += words [i];
+						} else {
+							caption += words [i];
+						}
+						if (i < words.Length - 1) {
+							caption += new string (' ', space);
+						}
+					}
+					if (c_hot_pos > -1) {
+						c_hot_pos += space - 1;
+					}
+					break;
+				}
+			}
+
+			Driver.AddStr (caption);
+
+			if (c_hot_pos != -1) {
+				Move (c_hot_pos, 0);
 				Driver.SetAttribute (HasFocus ? ColorScheme.HotFocus : ColorScheme.HotNormal);
 				Driver.AddRune (hot_key);
 			}
 		}
 
+		int GetWordsLength (string[] words)
+		{
+			int length = 0;
+
+			for (int i = 0; i < words.Length; i++) {
+				length += words [i].Length;
+			}
+
+			return length;
+		}
+
 		///<inheritdoc/>
 		public override void PositionCursor ()
 		{
-			Move (hot_pos == -1 ? 1 : hot_pos, 0);
+			Move (c_hot_pos == -1 ? 1 : c_hot_pos, 0);
 		}
 
 		bool CheckKey (KeyEvent key)
@@ -219,8 +288,7 @@ namespace Terminal.Gui {
 		public override bool ProcessColdKey (KeyEvent kb)
 		{
 			if (IsDefault && kb.KeyValue == '\n') {
-				if (Clicked != null)
-					Clicked ();
+				Clicked?.Invoke ();
 				return true;
 			}
 			return CheckKey (kb);
@@ -231,8 +299,7 @@ namespace Terminal.Gui {
 		{
 			var c = kb.KeyValue;
 			if (c == '\n' || c == ' ' || Rune.ToUpper ((uint)c) == hot_key) {
-				if (Clicked != null)
-					Clicked ();
+				Clicked?.Invoke ();
 				return true;
 			}
 			return base.ProcessKey (kb);
@@ -242,11 +309,12 @@ namespace Terminal.Gui {
 		public override bool MouseEvent (MouseEvent me)
 		{
 			if (me.Flags == MouseFlags.Button1Clicked) {
-				SuperView.SetFocus (this);
-				SetNeedsDisplay ();
+				if (!HasFocus) {
+					SuperView.SetFocus (this);
+					SetNeedsDisplay ();
+				}
 
-				if (Clicked != null)
-					Clicked ();
+				Clicked?.Invoke ();
 				return true;
 			}
 			return false;

+ 2 - 2
Terminal.Gui/Views/Label.cs

@@ -260,7 +260,7 @@ namespace Terminal.Gui {
 		}
 
 		/// <summary>
-		/// Computes the the max width of a line or multilines needed to render by the Label control
+		/// Computes the max width of a line or multilines needed to render by the Label control
 		/// </summary>
 		/// <returns>Max width of lines.</returns>
 		/// <param name="text">Text, may contain newlines.</param>
@@ -285,7 +285,7 @@ namespace Terminal.Gui {
 		}
 
 		/// <summary>
-		/// Controls the text-alignemtn property of the label, changing it will redisplay the <see cref="Label"/>.
+		/// Controls the text-alignment property of the label, changing it will redisplay the <see cref="Label"/>.
 		/// </summary>
 		/// <value>The text alignment.</value>
 		public TextAlignment TextAlignment {

+ 41 - 1
UICatalog/Scenarios/Buttons.cs

@@ -1,5 +1,6 @@
 using NStack;
 using System;
+using System.Collections.Generic;
 using Terminal.Gui;
 
 namespace UICatalog {
@@ -87,7 +88,7 @@ namespace UICatalog {
 				Y = y
 			});
 
-			button.Clicked = () => button.Text += "!"; 
+			button.Clicked = () => button.Text += "!";
 
 			Win.Add (new Button ("Lets see if this will move as \"Text Changer\" grows") {
 				X = Pos.Right (button) + 10,
@@ -128,6 +129,45 @@ namespace UICatalog {
 			};
 			Win.Add (sizeBtn);
 
+			Win.Add (new Label ("Size This Button via Frame 'Text Alignment'") {
+				X = Pos.Right (moveBtn) + 20,
+				Y = Pos.Top (moveBtn) - 4,
+			});
+
+			List<string> txtAligs = new List<string> () {
+				"Left",
+				"Right",
+				"Centered",
+				"Justified"
+			};
+
+			var lvTextAlig = new ListView (txtAligs) {
+				X = Pos.Right (moveBtn) + 20,
+				Y = Pos.Top (moveBtn) - 3,
+				Width = 20,
+				Height = 4,
+				ColorScheme = Colors.TopLevel
+			};
+
+			lvTextAlig.SelectedChanged += (o, e) => {
+				switch (e.Value) {
+				case "Left":
+					sizeBtn.TextAlignment = TextAlignment.Left;
+					break;
+				case "Right":
+					sizeBtn.TextAlignment = TextAlignment.Right;
+					break;
+				case "Centered":
+					sizeBtn.TextAlignment = TextAlignment.Centered;
+					break;
+				case "Justified":
+					sizeBtn.TextAlignment = TextAlignment.Justified;
+					break;
+				}
+			};
+
+			Win.Add (lvTextAlig);
+
 			// Demo changing hotkey
 			ustring MoveHotkey (ustring txt)
 			{