浏览代码

Remove cruft and implement SetDelay keystroke command

- Removed test context detection cruft from examples
- Examples now use Application.Create(example: true) directly
- Updated ExampleDemoKeyStrokesAttribute to support "SetDelay:nnn" command
- Removed DelayMs parameter from attribute
- Default delay between keys is 100ms
- SetDelay command changes delay for subsequent keys in sequence
- Metadata moved after using statements (before code)
- All examples cleaned up and building successfully

This addresses @tig's feedback for cleaner examples and better delay control.

Co-authored-by: tig <[email protected]>
copilot-swe-agent[bot] 1 周之前
父节点
当前提交
ef263f6dd7

+ 8 - 20
Examples/Example/Example.cs

@@ -6,34 +6,22 @@
 
 using Terminal.Gui.App;
 using Terminal.Gui.Configuration;
-using Terminal.Gui.Examples;
 using Terminal.Gui.ViewBase;
 using Terminal.Gui.Views;
 
-[assembly: ExampleMetadata ("Simple Example", "A basic login form demonstrating Terminal.Gui fundamentals")]
-[assembly: ExampleCategory ("Getting Started")]
-[assembly: ExampleDemoKeyStrokes (KeyStrokes = ["a", "d", "m", "i", "n", "Tab", "p", "a", "s", "s", "w", "o", "r", "d", "Enter"], DelayMs = 500, Order = 1)]
-[assembly: ExampleDemoKeyStrokes (KeyStrokes = ["Enter"], DelayMs = 500, Order = 2)]
-[assembly: ExampleDemoKeyStrokes (KeyStrokes = ["Esc"], DelayMs = 100, Order = 3)]
+// Example metadata
+[assembly: Terminal.Gui.Examples.ExampleMetadata ("Simple Example", "A basic login form demonstrating Terminal.Gui fundamentals")]
+[assembly: Terminal.Gui.Examples.ExampleCategory ("Getting Started")]
+[assembly: Terminal.Gui.Examples.ExampleDemoKeyStrokes (KeyStrokes = ["SetDelay:500", "a", "d", "m", "i", "n", "Tab", "p", "a", "s", "s", "w", "o", "r", "d", "Enter"], Order = 1)]
+[assembly: Terminal.Gui.Examples.ExampleDemoKeyStrokes (KeyStrokes = ["SetDelay:500", "Enter"], Order = 2)]
+[assembly: Terminal.Gui.Examples.ExampleDemoKeyStrokes (KeyStrokes = ["SetDelay:100", "Esc"], Order = 3)]
 
 // Override the default configuration for the application to use the Light theme
 ConfigurationManager.RuntimeConfig = """{ "Theme": "Light" }""";
 ConfigurationManager.Enable (ConfigLocations.All);
 
-// Check for test context to determine driver
-string? contextJson = Environment.GetEnvironmentVariable (ExampleContext.ENVIRONMENT_VARIABLE_NAME);
-string? driverName = null;
-var isExample = false;
-
-if (!string.IsNullOrEmpty (contextJson))
-{
-    ExampleContext? context = ExampleContext.FromJson (contextJson);
-    driverName = context?.DriverName;
-    isExample = true;
-}
-
-IApplication app = Application.Create (example: isExample);
-app.Init (driverName);
+IApplication app = Application.Create (example: true);
+app.Init ();
 app.Run<ExampleWindow> ();
 
 // Dispose the app to clean up and enable Console.WriteLine below

+ 8 - 21
Examples/FluentExample/Program.cs

@@ -3,31 +3,18 @@
 
 using Terminal.Gui.App;
 using Terminal.Gui.Drawing;
-using Terminal.Gui.Examples;
 using Terminal.Gui.ViewBase;
 using Terminal.Gui.Views;
 
-[assembly: ExampleMetadata ("Fluent API Example", "Demonstrates the fluent IApplication API with IRunnable pattern")]
-[assembly: ExampleCategory ("API Patterns")]
-[assembly: ExampleCategory ("Controls")]
-[assembly: ExampleDemoKeyStrokes (KeyStrokes = ["CursorDown", "CursorDown", "CursorRight", "Enter"], Order = 1)]
-[assembly: ExampleDemoKeyStrokes (KeyStrokes = ["Esc"], DelayMs = 100, Order = 2)]
+// Example metadata
+[assembly: Terminal.Gui.Examples.ExampleMetadata ("Fluent API Example", "Demonstrates the fluent IApplication API with IRunnable pattern")]
+[assembly: Terminal.Gui.Examples.ExampleCategory ("API Patterns")]
+[assembly: Terminal.Gui.Examples.ExampleCategory ("Controls")]
+[assembly: Terminal.Gui.Examples.ExampleDemoKeyStrokes (KeyStrokes = ["CursorDown", "CursorDown", "CursorRight", "Enter"], Order = 1)]
+[assembly: Terminal.Gui.Examples.ExampleDemoKeyStrokes (KeyStrokes = ["SetDelay:100", "Esc"], Order = 2)]
 
-
-// Check for test context to determine driver
-string? contextJson = Environment.GetEnvironmentVariable (ExampleContext.ENVIRONMENT_VARIABLE_NAME);
-string? driverName = null;
-var isExample = false;
-
-if (!string.IsNullOrEmpty (contextJson))
-{
-    ExampleContext? context = ExampleContext.FromJson (contextJson);
-    driverName = context?.DriverName;
-    isExample = true;
-}
-
-IApplication? app = Application.Create (example: isExample)
-                               .Init (driverName)
+IApplication? app = Application.Create (example: true)
+                               .Init ()
                                .Run<ColorPickerView> ();
 
 // Run the application with fluent API - automatically creates, runs, and disposes the runnable

+ 12 - 24
Examples/RunnableWrapperExample/Program.cs

@@ -3,33 +3,21 @@
 
 using Terminal.Gui.App;
 using Terminal.Gui.Drawing;
-using Terminal.Gui.Examples;
 using Terminal.Gui.ViewBase;
 using Terminal.Gui.Views;
 
-[assembly: ExampleMetadata ("Runnable Wrapper Example", "Shows how to wrap any View to make it runnable without implementing IRunnable")]
-[assembly: ExampleCategory ("API Patterns")]
-[assembly: ExampleCategory ("Views")]
-[assembly: ExampleDemoKeyStrokes (KeyStrokes = ["t", "e", "s", "t", "Esc"], Order = 1)]
-[assembly: ExampleDemoKeyStrokes (KeyStrokes = ["Enter", "Esc"], DelayMs = 100, Order = 2)]
-[assembly: ExampleDemoKeyStrokes (KeyStrokes = ["Enter", "Esc"], DelayMs = 100, Order = 3)]
-[assembly: ExampleDemoKeyStrokes (KeyStrokes = ["Enter", "Esc"], DelayMs = 100, Order = 4)]
-[assembly: ExampleDemoKeyStrokes (KeyStrokes = ["Enter", "Esc"], DelayMs = 100, Order = 5)]
-
-// Check for test context to determine driver
-string? contextJson = Environment.GetEnvironmentVariable (ExampleContext.ENVIRONMENT_VARIABLE_NAME);
-string? driverName = null;
-var isExample = false;
-
-if (!string.IsNullOrEmpty (contextJson))
-{
-    ExampleContext? context = ExampleContext.FromJson (contextJson);
-    driverName = context?.DriverName;
-    isExample = true;
-}
-
-IApplication app = Application.Create (example: isExample);
-app.Init (driverName);
+// Example metadata
+[assembly: Terminal.Gui.Examples.ExampleMetadata ("Runnable Wrapper Example", "Shows how to wrap any View to make it runnable without implementing IRunnable")]
+[assembly: Terminal.Gui.Examples.ExampleCategory ("API Patterns")]
+[assembly: Terminal.Gui.Examples.ExampleCategory ("Views")]
+[assembly: Terminal.Gui.Examples.ExampleDemoKeyStrokes (KeyStrokes = ["t", "e", "s", "t", "Esc"], Order = 1)]
+[assembly: Terminal.Gui.Examples.ExampleDemoKeyStrokes (KeyStrokes = ["SetDelay:100", "Enter", "Esc"], Order = 2)]
+[assembly: Terminal.Gui.Examples.ExampleDemoKeyStrokes (KeyStrokes = ["SetDelay:100", "Enter", "Esc"], Order = 3)]
+[assembly: Terminal.Gui.Examples.ExampleDemoKeyStrokes (KeyStrokes = ["SetDelay:100", "Enter", "Esc"], Order = 4)]
+[assembly: Terminal.Gui.Examples.ExampleDemoKeyStrokes (KeyStrokes = ["SetDelay:100", "Enter", "Esc"], Order = 5)]
+
+IApplication app = Application.Create (example: true);
+app.Init ();
 
 // Example 1: Use extension method with result extraction
 var textField = new TextField { Width = 40, Text = "Default text" };

+ 29 - 0
Terminal.Gui/App/ApplicationImpl.Lifecycle.cs

@@ -452,6 +452,9 @@ internal partial class ApplicationImpl
         // Sort by Order and collect all keystrokes
         var sortedSequences = demoKeyAttributes.OrderBy<Terminal.Gui.Examples.ExampleDemoKeyStrokesAttribute, int> (a => a.Order);
 
+        // Default delay between keys is 100ms
+        int currentDelay = 100;
+
         foreach (var attr in sortedSequences)
         {
             // Handle KeyStrokes array
@@ -459,8 +462,28 @@ internal partial class ApplicationImpl
             {
                 foreach (string keyStr in attr.KeyStrokes)
                 {
+                    // Check for SetDelay command
+                    if (keyStr.StartsWith ("SetDelay:", StringComparison.OrdinalIgnoreCase))
+                    {
+                        string delayValue = keyStr.Substring ("SetDelay:".Length);
+
+                        if (int.TryParse (delayValue, out int newDelay))
+                        {
+                            currentDelay = newDelay;
+                        }
+
+                        continue;
+                    }
+
+                    // Regular key
                     if (Input.Key.TryParse (keyStr, out Input.Key? key) && key is { })
                     {
+                        // Apply delay before sending key
+                        if (currentDelay > 0)
+                        {
+                            System.Threading.Thread.Sleep (currentDelay);
+                        }
+
                         Keyboard?.RaiseKeyDownEvent (key);
                     }
                 }
@@ -473,6 +496,12 @@ internal partial class ApplicationImpl
                 {
                     for (var i = 0; i < attr.RepeatCount; i++)
                     {
+                        // Apply delay before sending key
+                        if (currentDelay > 0)
+                        {
+                            System.Threading.Thread.Sleep (currentDelay);
+                        }
+
                         Keyboard?.RaiseKeyDownEvent (key);
                     }
                 }

+ 1 - 5
Terminal.Gui/Examples/DemoKeyStrokeSequence.cs

@@ -7,14 +7,10 @@ public class DemoKeyStrokeSequence
 {
     /// <summary>
     ///     Gets or sets the array of keystroke names to inject.
+    ///     Can include special "SetDelay:nnn" commands to change the delay between keys.
     /// </summary>
     public string [] KeyStrokes { get; set; } = [];
 
-    /// <summary>
-    ///     Gets or sets the delay in milliseconds before injecting these keystrokes.
-    /// </summary>
-    public int DelayMs { get; set; } = 0;
-
     /// <summary>
     ///     Gets or sets the order in which this sequence should be executed.
     /// </summary>

+ 8 - 8
Terminal.Gui/Examples/ExampleDemoKeyStrokesAttribute.cs

@@ -9,11 +9,15 @@ namespace Terminal.Gui.Examples;
 ///         Multiple instances of this attribute can be applied to a single assembly to define a sequence
 ///         of keystroke injections. The <see cref="Order"/> property controls the execution sequence.
 ///     </para>
+///     <para>
+///         Keystrokes can include special "SetDelay:nnn" entries to change the delay between subsequent keys.
+///         The default delay is 100ms. For example: KeyStrokes = ["SetDelay:500", "Enter", "SetDelay:100", "Tab"]
+///     </para>
 /// </remarks>
 /// <example>
 ///     <code>
-///     [assembly: ExampleDemoKeyStrokes(RepeatKey = "CursorDown", RepeatCount = 5, Order = 1, DelayMs = 100)]
-///     [assembly: ExampleDemoKeyStrokes(KeyStrokes = new[] { "Enter" }, Order = 2, DelayMs = 200)]
+///     [assembly: ExampleDemoKeyStrokes(RepeatKey = "CursorDown", RepeatCount = 5, Order = 1)]
+///     [assembly: ExampleDemoKeyStrokes(KeyStrokes = ["SetDelay:500", "Enter", "SetDelay:100", "Esc"], Order = 2)]
 ///     </code>
 /// </example>
 [AttributeUsage (AttributeTargets.Assembly, AllowMultiple = true)]
@@ -21,7 +25,8 @@ public class ExampleDemoKeyStrokesAttribute : System.Attribute
 {
     /// <summary>
     ///     Gets or sets an array of keystroke names to inject.
-    ///     Each string should be a valid key name that can be parsed by <see cref="Input.Key.TryParse"/>.
+    ///     Each string should be a valid key name that can be parsed by <see cref="Input.Key.TryParse"/>,
+    ///     or a special "SetDelay:nnn" command to change the delay between subsequent keys.
     /// </summary>
     public string []? KeyStrokes { get; set; }
 
@@ -37,11 +42,6 @@ public class ExampleDemoKeyStrokesAttribute : System.Attribute
     /// </summary>
     public int RepeatCount { get; set; } = 1;
 
-    /// <summary>
-    ///     Gets or sets the delay in milliseconds before injecting these keystrokes.
-    /// </summary>
-    public int DelayMs { get; set; } = 0;
-
     /// <summary>
     ///     Gets or sets the order in which this keystroke sequence should be executed
     ///     relative to other <see cref="ExampleDemoKeyStrokesAttribute"/> instances.

+ 0 - 1
Terminal.Gui/Examples/ExampleDiscovery.cs

@@ -110,7 +110,6 @@ public static class ExampleDiscovery
                                new ()
                                {
                                    KeyStrokes = keys.ToArray (),
-                                   DelayMs = attr.DelayMs,
                                    Order = attr.Order
                                });
             }