Skip to content

Commit

Permalink
Doc updates. Code cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
tig committed Dec 8, 2024
1 parent 5a0b350 commit f673ef3
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 131 deletions.
93 changes: 0 additions & 93 deletions Terminal.Gui/EnumExtensions/KeyBindingScopeExtensions.cs

This file was deleted.

2 changes: 1 addition & 1 deletion Terminal.Gui/Input/Keyboard/KeyBinding.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
namespace Terminal.Gui;

/// <summary>
/// Provides a collection of <see cref="Command"/> objects that are scoped to <see cref="KeyBindingScope"/>.
/// Provides a collection of <see cref="Command"/> objects stored in <see cref="KeyBindings"/>.
/// </summary>
/// <seealso cref="Application.KeyBindings"/>
/// <seealso cref="View.KeyBindings"/>
Expand Down
26 changes: 0 additions & 26 deletions Terminal.Gui/Input/Keyboard/KeyBindingScope.cs

This file was deleted.

47 changes: 36 additions & 11 deletions docfx/docs/keyboard.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Keyboard Events
# Keyboard Deep Dive

## Tenets for Terminal.Gui Keyboard Handling (Unless you know better ones...)

Expand All @@ -14,19 +14,34 @@ Tenets higher in the list have precedence over tenets lower in the list.

* **If It's Hot, It Works** - If a View with a @Terminal.Gui.View.HotKey is visible, and the HotKey is visible, the user should be able to press that HotKey and whatever behavior is defined for it should work. For example, in v1, when a Modal view was active, the HotKeys on MenuBar continued to show "hot". In v2 we strive to ensure this doesn't happen.


## Keyboard APIs

*Terminal.Gui* provides the following APIs for handling keyboard input:

### **[Key](~/api/Terminal.Gui.Key.yml)**

The `Key` class provides a platform-independent abstraction for common keyboard operations. It is used for processing keyboard input and raising keyboard events. This class provides a high-level abstraction with helper methods and properties for common keyboard operations. Use this class instead of the low-level `KeyCode` enum when possible.
* **Key** - @Terminal.Gui.Key provides a platform-independent abstraction for common keyboard operations. It is used for processing keyboard input and raising keyboard events. This class provides a high-level abstraction with helper methods and properties for common keyboard operations. Use this class instead of the low-level `KeyCode` enum when possible.
* **Key Bindings** - Key Bindings provide a declarative method for handling keyboard input in View implementations. The View calls @Terminal.Gui.AddCommand to declare it supports a particular command and then uses @Terminal.Gui.KeyBindings to indicate which key presses will invoke the command.
* **Key Events** - The Key Bindings API is rich enough to support the vast majority of use-cases. However, in some cases subscribing directly to key events is needed (e.g. when capturing arbitrary typing by a user). Use @Terminal.Gui.View.KeyDown and related events in these cases.

See [Key](~/api/Terminal.Gui.Key.yml) for more details.
Each of these APIs are described more fully below.

### **[Key Bindings](~/api/Terminal.Gui.KeyBindings.yml)**

Key Bindings is the preferred way of handling keyboard input in View implementations. The View calls @Terminal.Gui.AddCommand to declare it supports a particular command and then uses @Terminal.Gui.KeyBindings to indicate which key presses will invoke the command. For example, if a View wants to respond to the user pressing the up arrow key to scroll up it would do this

```cs
public MyView : View
{
AddCommand (Command.ScrollUp, () => ScrollVertical (-1));
KeyBindings.Add (Key.CursorUp, Command.ScrollUp);
}
```

The `Character Map` Scenario includes a View called `CharMap` that is a good example of the Key Bindings API.

The [Command](~/api/Terminal.Gui.Command.yml) enum lists generic operations that are implemented by views. For example `Command.Accept` in a `Button` results in the `Accepting` event
firing while in `TableView` it is bound to `CellActivated`. Not all commands
are implemented by all views (e.g. you cannot scroll in a `Button`). Use the @Terminal.Gui.View.GetSupportedCommands() method to determine which commands are implemented by a `View`.

The default key for activating a button is `Space`. You can change this using
`KeyBindings.ReplaceKey()`:

Expand All @@ -35,11 +50,21 @@ var btn = new Button () { Title = "Press me" };
btn.KeyBindings.ReplaceKey (btn.KeyBindings.GetKeyFromCommands (Command.Accept));
```

The [Command](~/api/Terminal.Gui.Command.yml) enum lists generic operations that are implemented by views. For example `Command.Accept` in a `Button` results in the `Clicked` event
firing while in `TableView` it is bound to `CellActivated`. Not all commands
are implemented by all views (e.g. you cannot scroll in a `Button`). Use the @Terminal.Gui.View.GetSupportedCommands() method to determine which commands are implemented by a `View`.
Key Bindings can be added at the `Application` or `View` level.

For **Application-scoped Key Bindings** there are two categories of Application-scoped Key Bindings:

1) **Application Command Key Bindings** - Bindings for `Command`s supported by @Terminal.Gui.Application. For example, @Terminal.Gui.Application.QuitKey, which is bound to `Command.Quit` and results in @Terminal.Gui.Application.RequestStop being called.
2) **Application Key Bindings** - Bindings for `Command`s supported on arbitrary `Views` that are meant to be invoked regardless of which part of the application is visible/active.

Use @Terminal.Gui.Application.KeyBindings to add or modify Application-scoped Key Bindings.

**View-scoped Key Bindings** also have two categories:

1) **HotKey Bindings** - These bind to `Command`s that will be invoked regardless of whether the View has focus or not. The most common use-case for `HotKey` bindings is @Terminal.Gui.View.HotKey. For example, a `Button` with a `Title` of `_OK`, the user can press `Alt-O` and the button will be accepted regardless of whether it has focus or not. Add and modify HotKey bindings with @Terminal.Gui.View.HotKeyBindings.
2) **Focused Bindings** - These bind to `Command`s that will be invoked only when the View has focus. Focused Key Bindings are the easiest way to enable a View to support responding to key events. Add and modify Focused bindings with @Terminal.Gui.View.KeyBindings.

Key Bindings can be added at the `Application` or `View` level. For Application-scoped Key Bindings see @Terminal.Gui.Application.Navigation. For View-scoped Key Bindings see @Terminal.Gui.View.KeyBindings.
**Application-Scoped** Key Bindings

### **@"Terminal.Gui.View.HotKey"**

Expand All @@ -57,7 +82,7 @@ The Command can be invoked even if the `View` that defines them is not focused o

[MenuBar](~/api/Terminal.Gui.MenuBar.yml), [ContextMenu](~/api/Terminal.Gui.ContextMenu.yml), and [StatusBar](~/api/Terminal.Gui.StatusBar.yml) support `Shortcut`s.

### **Handling Keyboard Events**
### **Key Events**

Keyboard events are retrieved from [Console Drivers](drivers.md) each iteration of the [Application](~/api/Terminal.Gui.Application.yml) [Main Loop](mainloop.md). The console driver raises the @Terminal.Gui.ConsoleDriver.KeyDown and @Terminal.Gui.ConsoleDriver.KeyUp events which invoke @Terminal.Gui.Application.RaiseKeyDown(Terminal.Gui.Key) and @Terminal.Gui.Application.RaiseKeyUp(Terminal.Gui.Key) respectively.

Expand Down

0 comments on commit f673ef3

Please sign in to comment.