Kaynağa Gözat

Merge pull request #1075 from BDisp/get-toplevel-subviews

Fixes #1071. Toplevel.GetTopLevelSubviews (). Changed from HashSet<View> to IList<View>.
Charlie Kindel 4 yıl önce
ebeveyn
işleme
d321fa0dc5

+ 1 - 0
Terminal.Gui/ConsoleDrivers/FakeDriver/FakeDriver.cs

@@ -391,6 +391,7 @@ namespace Terminal.Gui {
 
 				keyHandler (new KeyEvent (map, keyModifiers));
 				keyUpHandler (new KeyEvent (map, keyModifiers));
+				keyModifiers = new KeyModifiers ();
 			};
 		}
 

+ 1 - 1
Terminal.Gui/Core/Event.cs

@@ -392,7 +392,7 @@ namespace Terminal.Gui {
 		/// Gets a value indicating whether the Shift key was pressed.
 		/// </summary>
 		/// <value><c>true</c> if is shift; otherwise, <c>false</c>.</value>
-		public bool IsShift => keyModifiers.Shift;
+		public bool IsShift => keyModifiers.Shift || Key == Key.BackTab;
 
 		/// <summary>
 		/// Gets a value indicating whether the Alt key was pressed (real or synthesized)

+ 24 - 24
Terminal.Gui/Core/Toplevel.cs

@@ -195,7 +195,7 @@ namespace Terminal.Gui {
 			if (base.ProcessKey (keyEvent))
 				return true;
 
-			switch (keyEvent.Key) {
+			switch (ShortcutHelper.GetModifiersKey (keyEvent)) {
 			case Key.Q | Key.CtrlMask:
 				// FIXED: stop current execution of this container
 				Application.RequestStop ();
@@ -217,27 +217,32 @@ namespace Terminal.Gui {
 				var old = GetDeepestFocusedSubview (Focused);
 				if (!FocusNext ())
 					FocusNext ();
-				if (old != Focused) {
+				if (old != Focused && old != Focused?.Focused) {
 					old?.SetNeedsDisplay ();
 					Focused?.SetNeedsDisplay ();
 				} else {
-					FocusNearestView (GetToplevelSubviews (true));
+					FocusNearestView (SuperView?.TabIndexes, Direction.Forward);
 				}
 				return true;
+			case Key.BackTab | Key.ShiftMask:
 			case Key.CursorLeft:
 			case Key.CursorUp:
-			case Key.BackTab:
 				old = GetDeepestFocusedSubview (Focused);
 				if (!FocusPrev ())
 					FocusPrev ();
-				if (old != Focused) {
+				if (old != Focused && old != Focused?.Focused) {
 					old?.SetNeedsDisplay ();
 					Focused?.SetNeedsDisplay ();
 				} else {
-					FocusNearestView (GetToplevelSubviews (false));
+					FocusNearestView (SuperView?.TabIndexes?.Reverse(), Direction.Backward);
 				}
 				return true;
-
+			case Key.Tab | Key.CtrlMask:
+				Application.Top.FocusNext ();
+				return true;
+			case Key.Tab | Key.ShiftMask | Key.CtrlMask:
+				Application.Top.FocusPrev ();
+				return true;
 			case Key.L | Key.CtrlMask:
 				Application.Refresh ();
 				return true;
@@ -272,39 +277,34 @@ namespace Terminal.Gui {
 			return view;
 		}
 
-		IEnumerable<View> GetToplevelSubviews (bool isForward)
-		{
-			if (SuperView == null) {
-				return null;
-			}
-
-			HashSet<View> views = new HashSet<View> ();
-
-			foreach (var v in SuperView.Subviews) {
-				views.Add (v);
-			}
-
-			return isForward ? views : views.Reverse ();
-		}
-
-		void FocusNearestView (IEnumerable<View> views)
+		void FocusNearestView (IEnumerable<View> views, Direction direction)
 		{
 			if (views == null) {
 				return;
 			}
 
 			bool found = false;
+			bool focusProcessed = false;
+			int idx = 0;
 
 			foreach (var v in views) {
 				if (v == this) {
 					found = true;
 				}
 				if (found && v != this) {
-					v.EnsureFocus ();
+					if (direction == Direction.Forward) {
+						SuperView?.FocusNext ();
+					} else {
+						SuperView?.FocusPrev ();
+					}
+					focusProcessed = true;
 					if (SuperView.Focused != null && SuperView.Focused != this) {
 						return;
 					}
+				} else if (found && !focusProcessed && idx == views.Count () - 1) {
+					views.ToList () [0].SetFocus ();
 				}
+				idx++;
 			}
 		}
 

+ 1 - 1
UICatalog/Scenarios/WindowsAndFrameViews.cs

@@ -108,7 +108,7 @@ namespace UICatalog {
 				var frameView = new FrameView ("This is a Sub-FrameView") {
 					X = Pos.Percent (50),
 					Y = 1,
-					Width = Dim.Percent (100),
+					Width = Dim.Percent (100, true), // Or Dim.Percent (50)
 					Height = 5,
 					ColorScheme = Colors.Base,
 					Text = "The Text in the FrameView",

+ 36 - 4
UnitTests/ViewTests.cs

@@ -6,7 +6,7 @@ using System.Linq;
 using Terminal.Gui;
 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 {
@@ -27,9 +27,9 @@ namespace Terminal.Gui {
 			Assert.Null (r.ColorScheme);
 			Assert.Equal (Dim.Sized (0), r.Width);
 			Assert.Equal (Dim.Sized (0), r.Height);
-			// BUGBUG: Pos needs eqality implemented
-			//Assert.Equal (Pos.At (0), r.X);
-			//Assert.Equal (Pos.At (0), r.Y);
+			// FIXED: Pos needs equality implemented
+			Assert.Equal (Pos.At (0), r.X);
+			Assert.Equal (Pos.At (0), r.Y);
 			Assert.False (r.IsCurrentTop);
 			Assert.Empty (r.Id);
 			Assert.Empty (r.Subviews);
@@ -1077,5 +1077,37 @@ namespace Terminal.Gui {
 			Assert.True (view.Frame.IsEmpty);
 			Assert.True (view.Bounds.IsEmpty);
 		}
+
+		[Fact]
+		public void FocusNearestView_Ensure_Focus_Ordered ()
+		{
+			var top = new Toplevel ();
+
+			var win = new Window ();
+			var winSubview = new View ("WindowSubview") {
+				CanFocus = true
+			};
+			win.Add (winSubview);
+			top.Add (win);
+
+			var frm = new FrameView ();
+			var frmSubview = new View ("FrameSubview") {
+				CanFocus = true
+			};
+			frm.Add (frmSubview);
+			top.Add (frm);
+
+			top.ProcessKey (new KeyEvent (Key.Tab, new KeyModifiers ()));
+			Assert.Equal ($"WindowSubview", top.MostFocused.Text);
+			top.ProcessKey (new KeyEvent (Key.Tab, new KeyModifiers ()));
+			Assert.Equal ("FrameSubview", top.MostFocused.Text);
+			top.ProcessKey (new KeyEvent (Key.Tab, new KeyModifiers ()));
+			Assert.Equal ($"WindowSubview", top.MostFocused.Text);
+
+			top.ProcessKey (new KeyEvent (Key.BackTab | Key.ShiftMask, new KeyModifiers ()));
+			Assert.Equal ("FrameSubview", top.MostFocused.Text);
+			top.ProcessKey (new KeyEvent (Key.BackTab | Key.ShiftMask, new KeyModifiers ()));
+			Assert.Equal ($"WindowSubview", top.MostFocused.Text);
+		}
 	}
 }