Forráskód Böngészése

Allow key events to traverse the TopLevel hierarchy unless IsModal=true (#262)

It's quite common for key events to flow up the containment hierarchy in
UI frameworks. This could simplify management of global hotkeys that can
be placed in a top-level "App" and have all views shown subsequently just
"inherit" that behavior as long as they let the key event flow.

Propagating keys upwards is typically undesirable in modal dialogs, so we
set it to true in the `Dialog` base class.

Make sure we make a copy of the items since a key handler could modify the
top-level collection (i.e. by closing a dialog in between this processing).
Daniel Cazzulino 5 éve
szülő
commit
c072e29a68
2 módosított fájl, 29 hozzáadás és 8 törlés
  1. 28 8
      Terminal.Gui/Core.cs
  2. 1 0
      Terminal.Gui/Dialogs/Dialog.cs

+ 28 - 8
Terminal.Gui/Core.cs

@@ -1323,6 +1323,13 @@ namespace Terminal.Gui {
 			get => true;
 			get => true;
 		}
 		}
 
 
+		/// <summary>
+		/// Determines whether the <see cref="Toplevel"/> is modal or not. 
+		/// Causes <see cref="ProcessKey(KeyEvent)"/> to propagate keys upwards 
+		/// by default unless set to <see langword="true"/>.
+		/// </summary>
+		public bool Modal { get; set; }
+
 		public override bool ProcessKey (KeyEvent keyEvent)
 		public override bool ProcessKey (KeyEvent keyEvent)
 		{
 		{
 			if (base.ProcessKey (keyEvent))
 			if (base.ProcessKey (keyEvent))
@@ -1790,15 +1797,28 @@ namespace Terminal.Gui {
 
 
 		static void ProcessKeyEvent (KeyEvent ke)
 		static void ProcessKeyEvent (KeyEvent ke)
 		{
 		{
-			if (Current.ProcessHotKey (ke))
-				return;
+			var chain = toplevels.ToList();
+			foreach (var topLevel in chain) {
+				if (topLevel.Modal)
+					break;
+				if (topLevel.ProcessHotKey (ke))
+					return;
+			}
 
 
-			if (Current.ProcessKey (ke))
-				return;
-			
-			// Process the key normally
-			if (Current.ProcessColdKey (ke))
-				return;
+			foreach (var topLevel in chain) {
+				if (topLevel.Modal)
+					break;
+				if (topLevel.ProcessKey (ke))
+					return;
+			}
+
+			foreach (var topLevel in chain) {
+				if (topLevel.Modal)
+					break;
+				// Process the key normally
+				if (topLevel.ProcessColdKey (ke))
+					return;
+			}
 		}
 		}
 
 
 		static View FindDeepestView (View start, int x, int y, out int resx, out int resy)
 		static View FindDeepestView (View start, int x, int y, out int resx, out int resy)

+ 1 - 0
Terminal.Gui/Dialogs/Dialog.cs

@@ -38,6 +38,7 @@ namespace Terminal.Gui {
 			Width = width;
 			Width = width;
 			Height = height;
 			Height = height;
 			ColorScheme = Colors.Dialog;
 			ColorScheme = Colors.Dialog;
+			Modal = true;
 
 
 			if (buttons != null) {
 			if (buttons != null) {
 				foreach (var b in buttons) {
 				foreach (var b in buttons) {