Bläddra i källkod

enabled events for WizardStep.Title changing

Charlie Kindel 3 år sedan
förälder
incheckning
065d88eed5
3 ändrade filer med 122 tillägg och 16 borttagningar
  1. 66 3
      Terminal.Gui/Windows/Wizard.cs
  2. 6 5
      UICatalog/Scenarios/Wizards.cs
  3. 50 8
      UnitTests/WizardTests.cs

+ 66 - 3
Terminal.Gui/Windows/Wizard.cs

@@ -33,10 +33,73 @@ namespace Terminal.Gui {
 			/// <summary>
 			/// The title of the <see cref="WizardStep"/>.
 			/// </summary>
-			public ustring Title { get => title; set => title = value; }
-			// TODO: Update Wizard title when step title is changed if step is current - this will require step to slueth it's parent 
+			public ustring Title {
+				get => title;
+				set {
+					if (!OnTitleChanging (value)) {
+						title = value;
+						OnTitleChanged (title);
+					}
+					SetNeedsDisplay ();
+				}
+			}
+
 			private ustring title;
 
+			/// <summary>
+			/// An <see cref="EventArgs"/> which allows passing a cancelable new <see cref="Title"/> value event.
+			/// </summary>
+			public class TitleEventArgs : EventArgs {
+				/// <summary>
+				/// The new Window Title.
+				/// </summary>
+				public ustring NewTitle { get; set; }
+
+				/// <summary>
+				/// Flag which allows cancelling changing to the new TItle value.
+				/// </summary>
+				public bool Cancel { get; set; }
+
+				/// <summary>
+				/// Initializes a new instance of <see cref="TitleEventArgs"/>
+				/// </summary>
+				/// <param name="newTitle">The new <see cref="Window.Title"/> to be replaced.</param>
+				public TitleEventArgs (ustring newTitle)
+				{
+					NewTitle = newTitle;
+				}
+			}
+			/// <summary>
+			/// Called before the <see cref="Window.Title"/> changes. Invokes the <see cref="TitleChanging"/> event, which can be cancelled.
+			/// </summary>
+			/// <returns>`true` if an event handler cancelled the Title change.</returns>
+			public virtual bool OnTitleChanging (ustring newTitle)
+			{
+				var args = new TitleEventArgs (newTitle);
+				TitleChanging?.Invoke (args);
+				return args.Cancel;
+			}
+
+			/// <summary>
+			/// Event fired when the <see cref="Window.Title"/> is changing. Set <see cref="TitleEventArgs.Cancel"/> to 
+			/// `true` to cancel the Title change.
+			/// </summary>
+			public event Action<TitleEventArgs> TitleChanging;
+
+			/// <summary>
+			/// Called when the <see cref="Window.Title"/> has been changed. Invokes the <see cref="TitleChanged"/> event.
+			/// </summary>
+			public virtual void OnTitleChanged (ustring newTitle)
+			{
+				var args = new TitleEventArgs (title);
+				TitleChanged?.Invoke (args);
+			}
+
+			/// <summary>
+			/// Event fired after the <see cref="Window.Title"/> has been changed. 
+			/// </summary>
+			public event Action<TitleEventArgs> TitleChanged;
+
 			// The controlPane is a separate view, so when devs add controls to the Step and help is visible, Y = Pos.AnchorEnd()
 			// will work as expected.
 			private View controlPane = new FrameView ();
@@ -446,7 +509,7 @@ namespace Terminal.Gui {
 			steps.AddLast (newStep);
 			this.Add (newStep);
 			newStep.EnabledChanged += UpdateButtonsAndTitle;
-			//newStep.TitleChanged += UpdateButtonsAndTitle;
+			newStep.TitleChanged += (args) => UpdateButtonsAndTitle();
 			UpdateButtonsAndTitle ();
 		}
 

+ 6 - 5
UICatalog/Scenarios/Wizards.cs

@@ -150,7 +150,7 @@ namespace UICatalog.Scenarios {
 					// Add 2nd step
 					var secondStep = new Wizard.WizardStep ("Second Step");
 					wizard.AddStep (secondStep);
-					secondStep.HelpText = "This is the help text for the Second Step.\n\nPress the button to see a message box.\n\nEnter First Name too.";
+					secondStep.HelpText = "This is the help text for the Second Step.\n\nPress the button demo changing the Title.\n\nIf First Name is empty the step will prevent moving to the next step.";
 
 					View viewForControls = secondStep.Controls;
 					ustring frameMsg = "Added to WizardStep.Controls";
@@ -161,19 +161,20 @@ namespace UICatalog.Scenarios {
 
 					var buttonLbl = new Label () { Text = "Second Step Button: ", AutoSize = true, X = 1, Y = 1 };
 					var button = new Button () {
-						Text = "Press Me",
+						Text = "Press Me to Rename Step",
 						X = Pos.Right (buttonLbl),
 						Y = Pos.Top (buttonLbl)
 					};
 					button.Clicked += () => {
-						MessageBox.Query ("Wizard Scenario", "The Second Step Button was pressed.");
+						secondStep.Title = "2nd Step";
+						MessageBox.Query ("Wizard Scenario", "This Wizard Step's title was changed to '2nd Step'");
 					};
 					viewForControls.Add (buttonLbl, button);
 					var lbl = new Label () { Text = "First Name: ", AutoSize = true, X = 1, Y = Pos.Bottom (buttonLbl) };
-					var firstNameField = new TextField () { Width = 30, X = Pos.Right (lbl), Y = Pos.Top (lbl) };
+					var firstNameField = new TextField () { Text = "Number", Width = 30, X = Pos.Right (lbl), Y = Pos.Top (lbl) };
 					viewForControls.Add (lbl, firstNameField);
 					lbl = new Label () { Text = "Last Name:  ", AutoSize = true, X = 1, Y = Pos.Bottom (lbl) };
-					var lastNameField = new TextField () { Width = 30, X = Pos.Right (lbl), Y = Pos.Top (lbl) };
+					var lastNameField = new TextField () { Text = "Six", Width = 30, X = Pos.Right (lbl), Y = Pos.Top (lbl) };
 					viewForControls.Add (lbl, lastNameField);
 					var thirdStepEnabledCeckBox = new CheckBox () { Text = "Enable Step _3", Checked = false, X = Pos.Left (lastNameField), Y = Pos.Bottom (lastNameField) };
 					viewForControls.Add (thirdStepEnabledCeckBox);

+ 50 - 8
UnitTests/WizardTests.cs

@@ -26,24 +26,66 @@ namespace Terminal.Gui.Views {
 		}
 
 		// =========== WizardStep Tests
+
 		[Fact, AutoInitShutdown]
-		public void WizardStep_Title ()
+		public void WizardStep_ButtonText ()
 		{
-			// Verify default title
+			// Verify default button text
 
 			// Verify set actually changes property
 
-			// Verify set changes Wizard title (TODO: NOT YET IMPLEMENTED)
+			// Verify set actually changes buttons for the current step
 		}
 
-		[Fact, AutoInitShutdown]
-		public void WizardStep_ButtonText ()
+
+		[Fact]
+		public void WizardStep_Set_Title_Fires_TitleChanging ()
 		{
-			// Verify default button text
+			var r = new Window ();
+			Assert.Null (r.Title);
 
-			// Verify set actually changes property
+			string expectedAfter = null;
+			string expectedDuring = null;
+			bool cancel = false;
+			r.TitleChanging += (args) => {
+				Assert.Equal (expectedDuring, args.NewTitle);
+				args.Cancel = cancel;
+			};
+
+			r.Title = expectedDuring = expectedAfter = "title";
+			Assert.Equal (expectedAfter, r.Title.ToString ());
+
+			r.Title = expectedDuring = expectedAfter = "a different title";
+			Assert.Equal (expectedAfter, r.Title.ToString ());
+
+			// Now setup cancelling the change and change it back to "title"
+			cancel = true;
+			r.Title = expectedDuring = "title";
+			Assert.Equal (expectedAfter, r.Title.ToString ());
+			r.Dispose ();
+
+		}
+
+		[Fact]
+		public void WizardStep_Set_Title_Fires_TitleChanged ()
+		{
+			var r = new Window ();
+			Assert.Null (r.Title);
+
+			string expected = null;
+			r.TitleChanged += (args) => {
+				Assert.Equal (r.Title, args.NewTitle);
+			};
+
+			expected = "title";
+			r.Title = expected;
+			Assert.Equal (expected, r.Title.ToString ());
+
+			expected = "another title";
+			r.Title = expected;
+			Assert.Equal (expected, r.Title.ToString ());
+			r.Dispose ();
 
-			// Verify set actually changes buttons for the current step
 		}
 
 		// =========== Wizard Tests