浏览代码

Merge branch 'copilot/restructure-scenarios-standalone' of https://github.com/gui-cs/Terminal.Gui into copilot/restructure-scenarios-standalone

Tig 1 周之前
父节点
当前提交
cca90e38e5

+ 3 - 0
Examples/Example/Example.cs

@@ -20,6 +20,9 @@ using Terminal.Gui.Views;
 ConfigurationManager.RuntimeConfig = """{ "Theme": "Light" }""";
 ConfigurationManager.Enable (ConfigLocations.All);
 
+// Setup automatic key injection for testing
+ExampleContextInjector.SetupAutomaticInjection ();
+
 // Check for test context to determine driver
 string? contextJson = Environment.GetEnvironmentVariable (ExampleContext.ENVIRONMENT_VARIABLE_NAME);
 string? driverName = null;

+ 3 - 0
Examples/FluentExample/Program.cs

@@ -13,6 +13,9 @@ using Terminal.Gui.Views;
 [assembly: ExampleDemoKeyStrokes (KeyStrokes = ["CursorDown", "CursorDown", "CursorRight", "Enter"], Order = 1)]
 [assembly: ExampleDemoKeyStrokes (KeyStrokes = ["Esc"], DelayMs = 100, Order = 2)]
 
+// Setup automatic key injection for testing
+ExampleContextInjector.SetupAutomaticInjection ();
+
 // Check for test context to determine driver
 string? contextJson = Environment.GetEnvironmentVariable (ExampleContext.ENVIRONMENT_VARIABLE_NAME);
 string? driverName = null;

+ 3 - 0
Examples/RunnableWrapperExample/Program.cs

@@ -16,6 +16,9 @@ using Terminal.Gui.Views;
 [assembly: ExampleDemoKeyStrokes (KeyStrokes = ["Enter", "Esc"], DelayMs = 100, Order = 4)]
 [assembly: ExampleDemoKeyStrokes (KeyStrokes = ["Enter", "Esc"], DelayMs = 100, Order = 5)]
 
+// Setup automatic key injection for testing
+ExampleContextInjector.SetupAutomaticInjection ();
+
 // Check for test context to determine driver
 string? contextJson = Environment.GetEnvironmentVariable (ExampleContext.ENVIRONMENT_VARIABLE_NAME);
 string? driverName = null;

+ 1 - 126
Terminal.Gui/Drivers/FakeDriver/FakeComponentFactory.cs

@@ -1,5 +1,4 @@
 using System.Collections.Concurrent;
-using Terminal.Gui.Examples;
 
 namespace Terminal.Gui.Drivers;
 
@@ -29,30 +28,7 @@ public class FakeComponentFactory : ComponentFactoryImpl<ConsoleKeyInfo>
     /// <inheritdoc/>
     public override IInput<ConsoleKeyInfo> CreateInput ()
     {
-        // Use provided input instance or create a new one if none was provided
-        FakeInput fakeInput = _input ?? new FakeInput ();
-
-        // Check for test context in environment variable
-        string? contextJson = Environment.GetEnvironmentVariable (ExampleContext.ENVIRONMENT_VARIABLE_NAME);
-
-        if (!string.IsNullOrEmpty (contextJson))
-        {
-            ExampleContext? context = ExampleContext.FromJson (contextJson);
-
-            if (context is { })
-            {
-                foreach (string keyStr in context.KeysToInject)
-                {
-                    if (Key.TryParse (keyStr, out Key? key) && key is { })
-                    {
-                        ConsoleKeyInfo consoleKeyInfo = ConvertKeyToConsoleKeyInfo (key);
-                        fakeInput.AddInput (consoleKeyInfo);
-                    }
-                }
-            }
-        }
-
-        return fakeInput;
+        return _input ?? new FakeInput ();
     }
 
     /// <inheritdoc/>
@@ -66,105 +42,4 @@ public class FakeComponentFactory : ComponentFactoryImpl<ConsoleKeyInfo>
     {
         return _sizeMonitor ?? new SizeMonitorImpl (consoleOutput);
     }
-
-    private static ConsoleKeyInfo ConvertKeyToConsoleKeyInfo (Key key)
-    {
-        ConsoleModifiers modifiers = 0;
-
-        if (key.IsShift)
-        {
-            modifiers |= ConsoleModifiers.Shift;
-        }
-
-        if (key.IsAlt)
-        {
-            modifiers |= ConsoleModifiers.Alt;
-        }
-
-        if (key.IsCtrl)
-        {
-            modifiers |= ConsoleModifiers.Control;
-        }
-
-        // Remove the modifier masks to get the base key code
-        KeyCode baseKeyCode = key.KeyCode & KeyCode.CharMask;
-
-        // Map KeyCode to ConsoleKey
-        ConsoleKey consoleKey = baseKeyCode switch
-                                {
-                                    KeyCode.A => ConsoleKey.A,
-                                    KeyCode.B => ConsoleKey.B,
-                                    KeyCode.C => ConsoleKey.C,
-                                    KeyCode.D => ConsoleKey.D,
-                                    KeyCode.E => ConsoleKey.E,
-                                    KeyCode.F => ConsoleKey.F,
-                                    KeyCode.G => ConsoleKey.G,
-                                    KeyCode.H => ConsoleKey.H,
-                                    KeyCode.I => ConsoleKey.I,
-                                    KeyCode.J => ConsoleKey.J,
-                                    KeyCode.K => ConsoleKey.K,
-                                    KeyCode.L => ConsoleKey.L,
-                                    KeyCode.M => ConsoleKey.M,
-                                    KeyCode.N => ConsoleKey.N,
-                                    KeyCode.O => ConsoleKey.O,
-                                    KeyCode.P => ConsoleKey.P,
-                                    KeyCode.Q => ConsoleKey.Q,
-                                    KeyCode.R => ConsoleKey.R,
-                                    KeyCode.S => ConsoleKey.S,
-                                    KeyCode.T => ConsoleKey.T,
-                                    KeyCode.U => ConsoleKey.U,
-                                    KeyCode.V => ConsoleKey.V,
-                                    KeyCode.W => ConsoleKey.W,
-                                    KeyCode.X => ConsoleKey.X,
-                                    KeyCode.Y => ConsoleKey.Y,
-                                    KeyCode.Z => ConsoleKey.Z,
-                                    KeyCode.D0 => ConsoleKey.D0,
-                                    KeyCode.D1 => ConsoleKey.D1,
-                                    KeyCode.D2 => ConsoleKey.D2,
-                                    KeyCode.D3 => ConsoleKey.D3,
-                                    KeyCode.D4 => ConsoleKey.D4,
-                                    KeyCode.D5 => ConsoleKey.D5,
-                                    KeyCode.D6 => ConsoleKey.D6,
-                                    KeyCode.D7 => ConsoleKey.D7,
-                                    KeyCode.D8 => ConsoleKey.D8,
-                                    KeyCode.D9 => ConsoleKey.D9,
-                                    KeyCode.Enter => ConsoleKey.Enter,
-                                    KeyCode.Esc => ConsoleKey.Escape,
-                                    KeyCode.Space => ConsoleKey.Spacebar,
-                                    KeyCode.Tab => ConsoleKey.Tab,
-                                    KeyCode.Backspace => ConsoleKey.Backspace,
-                                    KeyCode.Delete => ConsoleKey.Delete,
-                                    KeyCode.Home => ConsoleKey.Home,
-                                    KeyCode.End => ConsoleKey.End,
-                                    KeyCode.PageUp => ConsoleKey.PageUp,
-                                    KeyCode.PageDown => ConsoleKey.PageDown,
-                                    KeyCode.CursorUp => ConsoleKey.UpArrow,
-                                    KeyCode.CursorDown => ConsoleKey.DownArrow,
-                                    KeyCode.CursorLeft => ConsoleKey.LeftArrow,
-                                    KeyCode.CursorRight => ConsoleKey.RightArrow,
-                                    KeyCode.F1 => ConsoleKey.F1,
-                                    KeyCode.F2 => ConsoleKey.F2,
-                                    KeyCode.F3 => ConsoleKey.F3,
-                                    KeyCode.F4 => ConsoleKey.F4,
-                                    KeyCode.F5 => ConsoleKey.F5,
-                                    KeyCode.F6 => ConsoleKey.F6,
-                                    KeyCode.F7 => ConsoleKey.F7,
-                                    KeyCode.F8 => ConsoleKey.F8,
-                                    KeyCode.F9 => ConsoleKey.F9,
-                                    KeyCode.F10 => ConsoleKey.F10,
-                                    KeyCode.F11 => ConsoleKey.F11,
-                                    KeyCode.F12 => ConsoleKey.F12,
-                                    _ => 0
-                                };
-
-        var keyChar = '\0';
-        Rune rune = key.AsRune;
-
-        if (Rune.IsValid (rune.Value))
-        {
-            keyChar = (char)rune.Value;
-        }
-
-        return new (keyChar, consoleKey, key.IsShift, key.IsAlt, key.IsCtrl);
-    }
 }

+ 75 - 0
Terminal.Gui/Examples/ExampleContextInjector.cs

@@ -0,0 +1,75 @@
+namespace Terminal.Gui.Examples;
+
+/// <summary>
+///     Handles automatic injection of test context into running examples.
+///     This class monitors for the presence of an <see cref="ExampleContext"/> in the environment
+///     and automatically injects keystrokes via <see cref="Application.Driver"/> after the application initializes.
+/// </summary>
+public static class ExampleContextInjector
+{
+    private static bool _initialized;
+
+    /// <summary>
+    ///     Sets up automatic key injection if a test context is present in the environment.
+    ///     Call this method before calling <see cref="Application.Init"/> or <see cref="IApplication.Init"/>.
+    /// </summary>
+    /// <remarks>
+    ///     This method is safe to call multiple times - it will only set up injection once.
+    ///     The actual key injection happens after the application is initialized, via the
+    ///     <see cref="Application.InitializedChanged"/> event.
+    /// </remarks>
+    public static void SetupAutomaticInjection ()
+    {
+        if (_initialized)
+        {
+            return;
+        }
+
+        _initialized = true;
+
+        // Check for test context in environment variable
+        string? contextJson = Environment.GetEnvironmentVariable (ExampleContext.ENVIRONMENT_VARIABLE_NAME);
+
+        if (string.IsNullOrEmpty (contextJson))
+        {
+            return;
+        }
+
+        ExampleContext? context = ExampleContext.FromJson (contextJson);
+
+        if (context is null || context.KeysToInject.Count == 0)
+        {
+            return;
+        }
+
+        // Subscribe to InitializedChanged to inject keys after initialization
+        Application.InitializedChanged += OnInitializedChanged;
+
+        return;
+
+        void OnInitializedChanged (object? sender, EventArgs<bool> e)
+        {
+            if (!e.Value)
+            {
+                return;
+            }
+
+            // Application has been initialized, inject the keys
+            if (Application.Driver is null)
+            {
+                return;
+            }
+
+            foreach (string keyStr in context.KeysToInject)
+            {
+                if (Input.Key.TryParse (keyStr, out Input.Key? key) && key is { })
+                {
+                    Application.Driver.EnqueueKeyEvent (key);
+                }
+            }
+
+            // Unsubscribe after injecting keys once
+            Application.InitializedChanged -= OnInitializedChanged;
+        }
+    }
+}