Преглед изворни кода

Added exceptions for AutoSize.

BDisp пре 3 година
родитељ
комит
38bed3fd98
3 измењених фајлова са 138 додато и 54 уклоњено
  1. 37 36
      Terminal.Gui/Core/View.cs
  2. 3 3
      UnitTests/PanelViewTests.cs
  3. 98 15
      UnitTests/ViewTests.cs

+ 37 - 36
Terminal.Gui/Core/View.cs

@@ -571,9 +571,8 @@ namespace Terminal.Gui {
 
 				var isValidNewAutSize = autoSize ? IsValidAutoSizeWidth (width) : false;
 
-				if (autoSize && !isValidNewAutSize) {
-					TextFormatter.AutoSize = false;
-					autoSize = false;
+				if (IsInitialized && autoSize && !isValidNewAutSize) {
+					throw new InvalidOperationException ("Must set AutoSize to false before set the Width.");
 				}
 				SetMinWidthHeight ();
 				SetNeedsLayout ();
@@ -601,9 +600,8 @@ namespace Terminal.Gui {
 
 				var isValidNewAutSize = autoSize ? IsValidAutoSizeHeight (height) : false;
 
-				if (autoSize && !isValidNewAutSize) {
-					TextFormatter.AutoSize = false;
-					autoSize = false;
+				if (IsInitialized && autoSize && !isValidNewAutSize) {
+					throw new InvalidOperationException ("Must set AutoSize to false before set the Height.");
 				}
 				SetMinWidthHeight ();
 				SetNeedsLayout ();
@@ -633,7 +631,7 @@ namespace Terminal.Gui {
 			if (!AutoSize && !ustring.IsNullOrEmpty (TextFormatter.Text)) {
 				switch (TextFormatter.IsVerticalDirection (TextDirection)) {
 				case true:
-					var colWidth = TextFormatter.GetSumMaxCharWidth (TextFormatter.Text, 0, 1);
+					var colWidth = TextFormatter.GetSumMaxCharWidth (new List<ustring> { TextFormatter.Text }, 0, 1);
 					if (Width == null || (Width is Dim.DimAbsolute && Width.Anchor (0) < colWidth)) {
 						width = colWidth;
 						Bounds = new Rect (Bounds.X, Bounds.Y, colWidth, Bounds.Height);
@@ -2389,9 +2387,6 @@ namespace Terminal.Gui {
 
 					if ((IsInitialized && AutoSize) || (directionChanged && AutoSize && isValidOldAutSize)) {
 						ResizeView (true);
-					} else if (directionChanged && AutoSize && !isValidOldAutSize) {
-						TextFormatter.AutoSize = false;
-						autoSize = false;
 					} else if (IsInitialized) {
 						var b = new Rect (Bounds.X, Bounds.Y, Bounds.Height, Bounds.Width);
 						SetWidthHeight (b);
@@ -2411,10 +2406,10 @@ namespace Terminal.Gui {
 		/// </summary>
 		public virtual bool IsInitialized {
 			get => isInitialized;
-			set {
+			private set {
 				isInitialized = value;
 				SetMinWidthHeight ();
-				if (autoSize && !IsValidAutoSize (out _)) {
+				if (autoSize && !IsValidAutoSize (out Size autSize)) {
 					TextFormatter.AutoSize = false;
 					autoSize = false;
 				}
@@ -2512,10 +2507,8 @@ namespace Terminal.Gui {
 		bool SetWidthHeight (Rect nBounds)
 		{
 			bool aSize = false;
-			var canSizeW = SetWidth (nBounds.Width - (TextFormatter.IsHorizontalDirection (TextDirection)
-				&& TextFormatter.Text?.Contains (HotKeySpecifier) == true ? 1 : 0), out int rW);
-			var canSizeH = SetHeight (nBounds.Height - (TextFormatter.IsVerticalDirection (TextDirection)
-				&& TextFormatter.Text?.Contains (HotKeySpecifier) == true ? 1 : 0), out int rH);
+			var canSizeW = SetWidth (nBounds.Width - GetHotKeySpecifierLength (), out int rW);
+			var canSizeH = SetHeight (nBounds.Height - GetHotKeySpecifierLength (false), out int rH);
 			if (canSizeW) {
 				aSize = true;
 				width = rW;
@@ -2535,15 +2528,11 @@ namespace Terminal.Gui {
 		bool IsValidAutoSize (out Size autoSize)
 		{
 			var rect = TextFormatter.CalcRect (frame.X, frame.Y, TextFormatter.Text, TextDirection);
-			autoSize = new Size (rect.Size.Width - (TextFormatter.IsHorizontalDirection (TextDirection)
-				&& TextFormatter.Text?.Contains (HotKeySpecifier) == true ? 1 : 0),
-				rect.Size.Height - (TextFormatter.IsVerticalDirection (TextDirection)
-				&& TextFormatter.Text?.Contains (HotKeySpecifier) == true ? 1 : 0));
+			autoSize = new Size (rect.Size.Width - GetHotKeySpecifierLength (),
+				rect.Size.Height - GetHotKeySpecifierLength (false));
 			return !(!(Width is Dim.DimAbsolute) || !(Height is Dim.DimAbsolute)
-				|| frame.Size.Width != rect.Size.Width - (TextFormatter.IsHorizontalDirection (TextDirection)
-				&& TextFormatter.Text?.Contains (HotKeySpecifier) == true ? 1 : 0)
-				|| frame.Size.Height != rect.Size.Height - (TextFormatter.IsVerticalDirection (TextDirection)
-				&& TextFormatter.Text?.Contains (HotKeySpecifier) == true ? 1 : 0));
+				|| frame.Size.Width != rect.Size.Width - GetHotKeySpecifierLength ()
+				|| frame.Size.Height != rect.Size.Height - GetHotKeySpecifierLength (false));
 		}
 
 		bool IsValidAutoSizeWidth (Dim width)
@@ -2551,8 +2540,7 @@ namespace Terminal.Gui {
 			var rect = TextFormatter.CalcRect (frame.X, frame.Y, TextFormatter.Text, TextDirection);
 			var dimValue = width.Anchor (0);
 			return !(!(width is Dim.DimAbsolute) || dimValue != rect.Size.Width
-				- (TextFormatter.IsHorizontalDirection (TextDirection)
-				&& TextFormatter.Text?.Contains (HotKeySpecifier) == true ? 1 : 0));
+				- GetHotKeySpecifierLength ());
 		}
 
 		bool IsValidAutoSizeHeight (Dim height)
@@ -2560,8 +2548,25 @@ namespace Terminal.Gui {
 			var rect = TextFormatter.CalcRect (frame.X, frame.Y, TextFormatter.Text, TextDirection);
 			var dimValue = height.Anchor (0);
 			return !(!(height is Dim.DimAbsolute) || dimValue != rect.Size.Height
-				- (TextFormatter.IsVerticalDirection (TextDirection)
-				&& TextFormatter.Text?.Contains (HotKeySpecifier) == true ? 1 : 0));
+				- GetHotKeySpecifierLength (false));
+		}
+
+		/// <summary>
+		/// Get the width or height of the <see cref="TextFormatter.HotKeySpecifier"/> length.
+		/// </summary>
+		/// <param name="isWidth"><c>true</c>if is the width (default)<c>false</c>if is the height.</param>
+		/// <returns>The length of the <see cref="TextFormatter.HotKeySpecifier"/>.</returns>
+		public int GetHotKeySpecifierLength (bool isWidth = true)
+		{
+			if (isWidth) {
+				return TextFormatter.IsHorizontalDirection (TextDirection) &&
+					TextFormatter.Text?.Contains (HotKeySpecifier) == true
+					? Math.Max (Rune.ColumnWidth (HotKeySpecifier), 0) : 0;
+			} else {
+				return TextFormatter.IsVerticalDirection (TextDirection) &&
+					TextFormatter.Text?.Contains (HotKeySpecifier) == true
+					? Math.Max (Rune.ColumnWidth (HotKeySpecifier), 0) : 0;
+			}
 		}
 
 		/// <summary>
@@ -2570,10 +2575,8 @@ namespace Terminal.Gui {
 		/// <returns>The bounds size minus the <see cref="TextFormatter.HotKeySpecifier"/> length.</returns>
 		public Size GetTextFormatterBoundsSize ()
 		{
-			return new Size (TextFormatter.Size.Width - (TextFormatter.IsHorizontalDirection (TextDirection)
-				&& TextFormatter.Text.Contains (HotKeySpecifier) ? Math.Max (Rune.ColumnWidth (HotKeySpecifier), 0) : 0),
-				TextFormatter.Size.Height - (TextFormatter.IsVerticalDirection (TextDirection)
-				&& TextFormatter.Text.Contains (HotKeySpecifier) ? Math.Max (Rune.ColumnWidth (HotKeySpecifier), 0) : 0));
+			return new Size (TextFormatter.Size.Width - GetHotKeySpecifierLength (),
+				TextFormatter.Size.Height - GetHotKeySpecifierLength (false));
 		}
 
 		/// <summary>
@@ -2585,10 +2588,8 @@ namespace Terminal.Gui {
 			if (TextFormatter.Text == null)
 				return Bounds.Size;
 
-			return new Size (frame.Size.Width + (TextFormatter.IsHorizontalDirection (TextDirection)
-					&& TextFormatter.Text.Contains (HotKeySpecifier) ? Math.Max (Rune.ColumnWidth (HotKeySpecifier), 0) : 0),
-				frame.Size.Height + (TextFormatter.IsVerticalDirection (TextDirection)
-				&& TextFormatter.Text.Contains (HotKeySpecifier) ? Math.Max (Rune.ColumnWidth (HotKeySpecifier), 0) : 0));
+			return new Size (frame.Size.Width + GetHotKeySpecifierLength (),
+				frame.Size.Height + GetHotKeySpecifierLength (false));
 		}
 
 		/// <summary>

+ 3 - 3
UnitTests/PanelViewTests.cs

@@ -346,11 +346,11 @@ namespace Terminal.Gui.Views {
 			var top = Application.Top;
 			var win = new Window ();
 			var label = new Label () {
-				Width = 24,
-				Height = 13,
 				ColorScheme = Colors.TopLevel,
 				Text = "This is a test\nwith a \nPanelView",
-				TextAlignment = TextAlignment.Centered
+				TextAlignment = TextAlignment.Centered,
+				Width = 24,
+				Height = 13
 			};
 			var pv = new PanelView (label) {
 				Width = 24,

+ 98 - 15
UnitTests/ViewTests.cs

@@ -1176,7 +1176,7 @@ namespace Terminal.Gui.Core {
 			Application.Shutdown ();
 		}
 
-		[Fact]
+		[Fact, AutoInitShutdown]
 		public void SetWidth_CanSetWidth ()
 		{
 			var top = new View () {
@@ -1200,8 +1200,12 @@ namespace Terminal.Gui.Core {
 			v.Width = null;
 			Assert.True (v.SetWidth (70, out rWidth));
 			Assert.Equal (70, rWidth);
+			Assert.False (v.IsInitialized);
+
+			Application.Top.Add (top);
+			Application.Begin (Application.Top);
 
-			v.IsInitialized = true;
+			Assert.True (v.IsInitialized);
 			v.Width = Dim.Fill (1);
 			Assert.Throws<ArgumentException> (() => v.Width = 75);
 			v.LayoutStyle = LayoutStyle.Absolute;
@@ -1210,7 +1214,7 @@ namespace Terminal.Gui.Core {
 			Assert.Equal (60, rWidth);
 		}
 
-		[Fact]
+		[Fact, AutoInitShutdown]
 		public void SetHeight_CanSetHeight ()
 		{
 			var top = new View () {
@@ -1234,8 +1238,13 @@ namespace Terminal.Gui.Core {
 			v.Height = null;
 			Assert.True (v.SetHeight (10, out rHeight));
 			Assert.Equal (10, rHeight);
+			Assert.False (v.IsInitialized);
+
+			Application.Top.Add (top);
+			Application.Begin (Application.Top);
+
+			Assert.True (v.IsInitialized);
 
-			v.IsInitialized = true;
 			v.Height = Dim.Fill (1);
 			Assert.Throws<ArgumentException> (() => v.Height = 15);
 			v.LayoutStyle = LayoutStyle.Absolute;
@@ -1360,37 +1369,50 @@ namespace Terminal.Gui.Core {
 			Assert.Equal ("{X=0,Y=0,Width=8,Height=1}", label.Bounds.ToString ());
 		}
 
-		[Fact]
-		public void AutoSize_False_ResizeView_With_Dim_Fill ()
+		[Fact, AutoInitShutdown]
+		public void AutoSize_False_ResizeView_With_Dim_Fill_After_IsInitialized ()
 		{
 			var win = new Window (new Rect (0, 0, 30, 80), "");
 			var label = new Label () { Width = Dim.Fill (), Height = Dim.Fill () };
 			win.Add (label);
+			Application.Top.Add (win);
+
+			// Text is empty so height=0
+			Assert.True (label.AutoSize);
+			Assert.Equal ("{X=0,Y=0,Width=0,Height=0}", label.Bounds.ToString ());
 
 			label.Text = "New text\nNew line";
-			win.LayoutSubviews ();
+			Application.Top.LayoutSubviews ();
+
+			Assert.True (label.AutoSize);
+			Assert.Equal ("{X=0,Y=0,Width=28,Height=78}", label.Bounds.ToString ());
 
+			Application.Begin (Application.Top);
 			Assert.False (label.AutoSize);
 			Assert.Equal ("{X=0,Y=0,Width=28,Height=78}", label.Bounds.ToString ());
 		}
 
-		[Fact]
-		public void AutoSize_False_SetWidthHeight_With_Dim_Fill_And_Dim_Absolute ()
+		[Fact, AutoInitShutdown]
+		public void AutoSize_False_SetWidthHeight_With_Dim_Fill_And_Dim_Absolute_After_IsInitialized ()
 		{
 			var win = new Window (new Rect (0, 0, 30, 80), "");
 			var label = new Label () { Width = Dim.Fill () };
 			win.Add (label);
+			Application.Top.Add (win);
 
 			// Text is empty so height=0
-			Assert.False (label.AutoSize);
+			Assert.True (label.AutoSize);
 			Assert.Equal ("{X=0,Y=0,Width=0,Height=0}", label.Bounds.ToString ());
 
-			// Here the SetMinWidthHeight ensuring the minimum height
 			label.Text = "New text\nNew line";
-			win.LayoutSubviews ();
+			Application.Top.LayoutSubviews ();
+
+			Assert.True (label.AutoSize);
+			Assert.Equal ("{X=0,Y=0,Width=28,Height=2}", label.Bounds.ToString ());
 
+			Application.Begin (Application.Top);
 			Assert.False (label.AutoSize);
-			Assert.Equal ("{X=0,Y=0,Width=28,Height=1}", label.Bounds.ToString ());
+			Assert.Equal ("{X=0,Y=0,Width=28,Height=2}", label.Bounds.ToString ());
 		}
 
 		[Fact, AutoInitShutdown]
@@ -2827,8 +2849,7 @@ Y
 			var btn = new Button () {
 				X = Pos.Center (),
 				Y = Pos.Center (),
-				Text = "Say He_llo 你",
-				AutoSize = true
+				Text = "Say He_llo 你"
 			};
 
 			var win = new Window () {
@@ -2912,5 +2933,67 @@ Y
 			Assert.Equal (verticalView.TextFormatter.Size, verticalView.GetBoundsTextFormatterSize ());
 			Assert.Equal (verticalView.Frame.Size, verticalView.GetTextFormatterBoundsSize ());
 		}
+
+		[Fact, AutoInitShutdown]
+		public void AutoSize_Exceptions ()
+		{
+			var exception = Record.Exception (() => new View () { Text = "Say Hello 你", AutoSize = true, Width = 10 });
+			Assert.Null (exception);
+
+			var view1 = new View () { Text = "Say Hello view1 你", AutoSize = true, Width = 10 };
+			var view2 = new View () { Text = "Say Hello view2 你", Height = 10, AutoSize = true };
+			var view3 = new View () { Text = "Say Hello view3 你", Width = 10 };
+			var view4 = new View () {
+				Text = "Say Hello view4 你",
+				Height = 10,
+				AutoSize = true,
+				TextDirection = TextDirection.TopBottom_LeftRight
+			};
+			var view5 = new View () {
+				Text = "Say Hello view5 你",
+				Height = 10,
+				TextDirection = TextDirection.TopBottom_LeftRight
+			};
+			Application.Top.Add (view1, view2, view3, view4, view5);
+
+			Assert.False (view1.IsInitialized);
+			Assert.False (view2.IsInitialized);
+			Assert.False (view3.IsInitialized);
+			Assert.False (view4.IsInitialized);
+			Assert.False (view5.IsInitialized);
+
+			Application.Begin (Application.Top);
+
+			Assert.True (view1.IsInitialized);
+			Assert.True (view2.IsInitialized);
+			Assert.True (view3.IsInitialized);
+			Assert.True (view4.IsInitialized);
+			Assert.True (view5.IsInitialized);
+
+			Assert.False (view1.AutoSize);
+			Assert.Equal (new Rect (0, 0, 10, 1), view1.Frame);
+			Assert.True (view2.AutoSize);
+			Assert.Equal (new Rect (0, 0, 18, 1), view2.Frame);
+			Assert.False (view3.AutoSize);
+			Assert.Equal (new Rect (0, 0, 10, 1), view3.Frame);
+			Assert.True (view4.AutoSize);
+			Assert.Equal (new Rect (0, 0, 2, 17), view4.Frame);
+			Assert.False (view5.AutoSize);
+			Assert.Equal (new Rect (0, 0, 2, 10), view5.Frame);
+
+			exception = Record.Exception (() => view1.Width = 20);
+			Assert.Null (exception);
+			Assert.Equal (new Rect (0, 0, 20, 1), view1.Frame);
+			Assert.Throws<InvalidOperationException> (() => view2.Height = 10);
+			exception = Record.Exception (() => view3.Width = 20);
+			Assert.Null (exception);
+			Assert.Equal (new Rect (0, 0, 20, 1), view3.Frame);
+			exception = Record.Exception (() => view4.TextDirection = TextDirection.LeftRight_TopBottom);
+			Assert.Null (exception);
+			Assert.Equal (new Rect (0, 0, 18, 1), view4.Frame);
+			exception = Record.Exception (() => view5.TextDirection = TextDirection.LeftRight_TopBottom);
+			Assert.Null (exception);
+			Assert.Equal (new Rect (0, 0, 10, 2), view5.Frame);
+		}
 	}
 }