Bläddra i källkod

Fixes #1266. Using Ctrl+PageUp/PageDown to allowing navigate through windows. (#1283)

* Fixes #1266. Using Ctrl+PageUp/PageDown to allowing navigate through windows.

* No need to change TextView.

* Added configurable navigations keys.
BDisp 4 år sedan
förälder
incheckning
5b490a8c8f

+ 9 - 0
Terminal.Gui/Core/Application.cs

@@ -110,6 +110,15 @@ namespace Terminal.Gui {
 			}
 		}
 
+		/// <summary>
+		/// Alternative key to navigate forwards through all views. Ctrl+Tab is always used.
+		/// </summary>
+		public static Key AlternateForwardKey { get; set; } = Key.PageDown | Key.CtrlMask;
+		/// <summary>
+		/// Alternative key to navigate backwards through all views. Shift+Ctrl+Tab is always used.
+		/// </summary>
+		public static Key AlternateBackwardKey { get; set; } = Key.PageUp | Key.CtrlMask;
+
 		/// <summary>
 		/// The <see cref="MainLoop"/>  driver for the application
 		/// </summary>

+ 8 - 0
Terminal.Gui/Core/Toplevel.cs

@@ -238,10 +238,18 @@ namespace Terminal.Gui {
 				}
 				return true;
 			case Key.Tab | Key.CtrlMask:
+			case Key key when key == Application.AlternateForwardKey: // Needed on Unix
 				Application.Top.FocusNext ();
+				if (Application.Top.Focused == null) {
+					Application.Top.FocusNext ();
+				}
 				return true;
 			case Key.Tab | Key.ShiftMask | Key.CtrlMask:
+			case Key key when key == Application.AlternateBackwardKey: // Needed on Unix
 				Application.Top.FocusPrev ();
+				if (Application.Top.Focused == null) {
+					Application.Top.FocusPrev ();
+				}
 				return true;
 			case Key.L | Key.CtrlMask:
 				Application.Refresh ();

+ 1 - 1
Terminal.Gui/Views/TextView.cs

@@ -2017,7 +2017,7 @@ namespace Terminal.Gui {
 					StopSelecting ();
 				}
 				int nPageDnShift = Frame.Height - 1;
-				if (currentRow > 0 && currentRow < model.Count) {
+				if (currentRow >= 0 && currentRow < model.Count) {
 					if (columnTrack == -1)
 						columnTrack = currentColumn;
 					currentRow = (currentRow + nPageDnShift) > model.Count

+ 104 - 3
UnitTests/ApplicationTests.cs

@@ -4,7 +4,7 @@ using System.Threading;
 using System.Threading.Tasks;
 using Xunit;
 
-// Alais Console to MockConsole so we don't accidentally use Console
+// Alias Console to MockConsole so we don't accidentally use Console
 using Console = Terminal.Gui.FakeConsole;
 
 namespace Terminal.Gui.Core {
@@ -19,7 +19,7 @@ namespace Terminal.Gui.Core {
 		[Fact]
 		public void Init_Shutdown_Cleans_Up ()
 		{
-			// Verify inital state is per spec
+			// Verify initial state is per spec
 			Pre_Init_State ();
 
 			Application.Init (new FakeDriver (), new FakeMainLoop (() => FakeConsole.ReadKey (true)));
@@ -175,7 +175,7 @@ namespace Terminal.Gui.Core {
 			// Setup Mock driver
 			Init ();
 
-			// Setup some fake kepresses (This)
+			// Setup some fake keypresses (This)
 			var input = "Tests";
 
 			// Put a control-q in at the end
@@ -268,5 +268,106 @@ namespace Terminal.Gui.Core {
 			Application.Shutdown ();
 			Assert.Null (SynchronizationContext.Current);
 		}
+
+		[Fact]
+		public void AlternateForwardKey_AlternateBackwardKey_Tests ()
+		{
+			Init ();
+
+			var top = Application.Top;
+			var w1 = new Window ();
+			var v1 = new TextField ();
+			var v2 = new TextView ();
+			w1.Add (v1, v2);
+
+			var w2 = new Window ();
+			var v3 = new CheckBox ();
+			var v4 = new Button ();
+			w2.Add (v3, v4);
+
+			top.Add (w1, w2);
+
+			Application.Iteration += () => {
+				Assert.True (v1.HasFocus);
+				// Using default keys.
+				top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.Tab,
+					new KeyModifiers () { Ctrl = true }));
+				Assert.True (v2.HasFocus);
+				top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.Tab,
+					new KeyModifiers () { Ctrl = true }));
+				Assert.True (v3.HasFocus);
+				top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.Tab,
+					new KeyModifiers () { Ctrl = true }));
+				Assert.True (v4.HasFocus);
+				top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.Tab,
+					new KeyModifiers () { Ctrl = true }));
+				Assert.True (v1.HasFocus);
+
+				top.ProcessKey (new KeyEvent (Key.ShiftMask | Key.CtrlMask | Key.Tab,
+					new KeyModifiers () { Shift = true, Ctrl = true }));
+				Assert.True (v4.HasFocus);
+				top.ProcessKey (new KeyEvent (Key.ShiftMask | Key.CtrlMask | Key.Tab,
+					new KeyModifiers () { Shift = true, Ctrl = true }));
+				Assert.True (v3.HasFocus);
+				top.ProcessKey (new KeyEvent (Key.ShiftMask | Key.CtrlMask | Key.Tab,
+					new KeyModifiers () { Shift = true, Ctrl = true }));
+				Assert.True (v2.HasFocus);
+				top.ProcessKey (new KeyEvent (Key.ShiftMask | Key.CtrlMask | Key.Tab,
+					new KeyModifiers () { Shift = true, Ctrl = true }));
+				Assert.True (v1.HasFocus);
+
+				top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.PageDown,
+					new KeyModifiers () { Ctrl = true }));
+				Assert.True (v2.HasFocus);
+				top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.PageDown,
+					new KeyModifiers () { Ctrl = true }));
+				Assert.True (v3.HasFocus);
+				top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.PageDown,
+					new KeyModifiers () { Ctrl = true }));
+				Assert.True (v4.HasFocus);
+				top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.PageDown,
+					new KeyModifiers () { Ctrl = true }));
+				Assert.True (v1.HasFocus);
+
+				top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.PageUp,
+					new KeyModifiers () { Ctrl = true }));
+				Assert.True (v4.HasFocus);
+				top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.PageUp,
+					new KeyModifiers () { Ctrl = true }));
+				Assert.True (v3.HasFocus);
+				top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.PageUp,
+					new KeyModifiers () { Ctrl = true }));
+				Assert.True (v2.HasFocus);
+				top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.PageUp,
+					new KeyModifiers () { Ctrl = true }));
+				Assert.True (v1.HasFocus);
+
+				// Using another's alternate keys.
+				Application.AlternateForwardKey = Key.F7;
+				Application.AlternateBackwardKey = Key.F6;
+
+				top.ProcessKey (new KeyEvent (Key.F7, new KeyModifiers ()));
+				Assert.True (v2.HasFocus);
+				top.ProcessKey (new KeyEvent (Key.F7, new KeyModifiers ()));
+				Assert.True (v3.HasFocus);
+				top.ProcessKey (new KeyEvent (Key.F7, new KeyModifiers ()));
+				Assert.True (v4.HasFocus);
+				top.ProcessKey (new KeyEvent (Key.F7, new KeyModifiers ()));
+				Assert.True (v1.HasFocus);
+
+				top.ProcessKey (new KeyEvent (Key.F6, new KeyModifiers ()));
+				Assert.True (v4.HasFocus);
+				top.ProcessKey (new KeyEvent (Key.F6, new KeyModifiers ()));
+				Assert.True (v3.HasFocus);
+				top.ProcessKey (new KeyEvent (Key.F6, new KeyModifiers ()));
+				Assert.True (v2.HasFocus);
+				top.ProcessKey (new KeyEvent (Key.F6, new KeyModifiers ()));
+				Assert.True (v1.HasFocus);
+
+				Application.RequestStop ();
+			};
+
+			Application.Run (top);
+		}
 	}
 }