Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Terminal.Gui/Input/IAcceptTarget.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace Terminal.Gui;
namespace Terminal.Gui.Input;

/// <summary>
/// Interface for views that handle <see cref="Command.Accept"/> as terminal destinations.
Expand Down
7 changes: 7 additions & 0 deletions Tests/UnitTestsParallelizable/ViewBase/ViewCommandTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1279,6 +1279,13 @@ public void Button_Implements_IAcceptTarget ()
Assert.IsAssignableFrom<IAcceptTarget> (button);
}

// Copilot
[Fact]
public void IAcceptTarget_Is_In_Input_Namespace ()
{
Assert.Equal ("Terminal.Gui.Input", typeof (IAcceptTarget).Namespace);
}

// CoPilot - ChatGPT o1
[Fact]
public void NonIAcceptTarget_Handled_Does_Not_Redirect ()
Expand Down
4 changes: 2 additions & 2 deletions docfx/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ grep "ClassName" docfx/_site/xrefmap.yml | grep "^- uid:"
| `Command`, `CommandRouting`, `ICommandContext`, `CommandContext`, `ICommandBinding`, `CommandBridge` | `Terminal.Gui.Input.` |
| `View` | `Terminal.Gui.ViewBase.View` |
| All view classes (`Button`, `CheckBox`, `Dialog`, etc.) | `Terminal.Gui.Views.` |
| `IAcceptTarget` | `Terminal.Gui.` |
| `IAcceptTarget` | `Terminal.Gui.Input.` |

### Syntax

Expand All @@ -85,7 +85,7 @@ grep "ClassName" docfx/_site/xrefmap.yml | grep "^- uid:"
| `ICommandContext` | `Terminal.Gui.Input.ICommandContext` |
| `CommandContext` | `Terminal.Gui.Input.CommandContext` |
| `CommandBridge` | `Terminal.Gui.Input.CommandBridge` |
| `IAcceptTarget` | `Terminal.Gui.IAcceptTarget` |
| `IAcceptTarget` | `Terminal.Gui.Input.IAcceptTarget` |
| `View` | `Terminal.Gui.ViewBase.View` |
| `View.CommandsToBubbleUp` | `Terminal.Gui.ViewBase.View.CommandsToBubbleUp` |
| `View.DefaultAcceptView` | `Terminal.Gui.ViewBase.View.DefaultAcceptView` |
Expand Down
2 changes: 1 addition & 1 deletion docfx/docs/command-diagrams.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ flowchart TD
- `DispatchDown` creates a new context with `Routing = DispatchingDown`, suppressing re-bubbling in the target and preventing infinite recursion.
- `TextField.DefaultAcceptHandler` skips its own <xref:Terminal.Gui.ViewBase.View.DefaultAcceptView> redirect because `acceptWillBubble = true` — this prevents double-handling.
- <xref:Terminal.Gui.ViewBase.View.DefaultAcceptView> is a property on each view that returns the first `IAcceptTarget { IsDefault: true }` SubView (typically a <xref:Terminal.Gui.Views.Button>). It is not inherited from the SuperView.
- <xref:Terminal.Gui.Views.Button> returns `true` from `DefaultAcceptHandler` because it implements <xref:Terminal.Gui.IAcceptTarget>.
- <xref:Terminal.Gui.Views.Button> returns `true` from `DefaultAcceptHandler` because it implements <xref:Terminal.Gui.Input.IAcceptTarget>.

### Level 3: Complete Flow with MenuBarItem, Menu, and MenuItem

Expand Down
14 changes: 7 additions & 7 deletions docfx/docs/command.md
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,7 @@ Bound to `Key.Enter`.
4. If not handled, redirects to <xref:Terminal.Gui.ViewBase.View.DefaultAcceptView> via `DispatchDown` (unless Accept will also bubble to an ancestor — prevents double-path)
5. For `BubblingUp` with a dispatch target, calls <xref:Terminal.Gui.ViewBase.View.RaiseAccepted*>
6. Calls <xref:Terminal.Gui.ViewBase.View.RaiseAccepted*>
7. Returns `true` if: redirected, will bubble to ancestor, routing is `BubblingUp`, or view is <xref:Terminal.Gui.IAcceptTarget>
7. Returns `true` if: redirected, will bubble to ancestor, routing is `BubblingUp`, or view is <xref:Terminal.Gui.Input.IAcceptTarget>

### `DefaultHotKeyHandler` (<xref:Terminal.Gui.Input.Command.HotKey>)

Expand Down Expand Up @@ -404,7 +404,7 @@ Called by <xref:Terminal.Gui.ViewBase.View.RaiseActivating*>, <xref:Terminal.Gui

1. If already handled → return `true`
2. If routing is `DispatchingDown` → return `false` (prevents re-entry)
3. For <xref:Terminal.Gui.Input.Command.Accept>: handles <xref:Terminal.Gui.ViewBase.View.DefaultAcceptView> + <xref:Terminal.Gui.IAcceptTarget> redirect logic
3. For <xref:Terminal.Gui.Input.Command.Accept>: handles <xref:Terminal.Gui.ViewBase.View.DefaultAcceptView> + <xref:Terminal.Gui.Input.IAcceptTarget> redirect logic
4. If command is in `SuperView.CommandsToBubbleUp` → invoke on SuperView with `Routing = BubblingUp`
5. Handles `Padding` edge cases (checks Padding's parent)

Expand All @@ -420,14 +420,14 @@ protected bool? DispatchDown (View target, ICommandContext? ctx)

Creates a <xref:Terminal.Gui.Input.CommandContext> with `Routing = CommandRouting.DispatchingDown` and invokes on the target. <xref:Terminal.Gui.ViewBase.View.TryBubbleUp*> checks for `DispatchingDown` and skips bubbling, preventing infinite recursion.

### <xref:Terminal.Gui.ViewBase.View.DefaultAcceptView> and <xref:Terminal.Gui.IAcceptTarget>
### <xref:Terminal.Gui.ViewBase.View.DefaultAcceptView> and <xref:Terminal.Gui.Input.IAcceptTarget>

<xref:Terminal.Gui.ViewBase.View.DefaultAcceptView> identifies the SubView that receives <xref:Terminal.Gui.Input.Command.Accept> when no other handles it. Defaults to the first `IAcceptTarget { IsDefault: true }` SubView (typically a <xref:Terminal.Gui.Views.Button>).

<xref:Terminal.Gui.IAcceptTarget> affects flow in three ways:
<xref:Terminal.Gui.Input.IAcceptTarget> affects flow in three ways:
1. **Resolution**: <xref:Terminal.Gui.ViewBase.View.DefaultAcceptView> searches for `IAcceptTarget { IsDefault: true }`
2. **Return value**: `DefaultAcceptHandler` returns `true` for <xref:Terminal.Gui.IAcceptTarget> views
3. **Redirect**: Non-default <xref:Terminal.Gui.IAcceptTarget> sources bubble up when a <xref:Terminal.Gui.ViewBase.View.DefaultAcceptView> exists
2. **Return value**: `DefaultAcceptHandler` returns `true` for <xref:Terminal.Gui.Input.IAcceptTarget> views
3. **Redirect**: Non-default <xref:Terminal.Gui.Input.IAcceptTarget> sources bubble up when a <xref:Terminal.Gui.ViewBase.View.DefaultAcceptView> exists

## CommandBridge

Expand Down Expand Up @@ -650,7 +650,7 @@ When an inner <xref:Terminal.Gui.Views.CheckBox> activates (via click/space), th

1. **<xref:Terminal.Gui.ViewBase.View> base**: Space → <xref:Terminal.Gui.Input.Command.Activate>, Enter → <xref:Terminal.Gui.Input.Command.Accept>, `LeftButtonReleased` → <xref:Terminal.Gui.Input.Command.Activate>. Subclasses override or extend.

2. **<xref:Terminal.Gui.Views.Button>**: Implements <xref:Terminal.Gui.IAcceptTarget>. All interactions map to <xref:Terminal.Gui.Input.Command.Accept>.
2. **<xref:Terminal.Gui.Views.Button>**: Implements <xref:Terminal.Gui.Input.IAcceptTarget>. All interactions map to <xref:Terminal.Gui.Input.Command.Accept>.

3. **Selector views**: Use `ConsumeDispatch=true`. Inner <xref:Terminal.Gui.Views.CheckBox> commands are consumed; don't propagate to SuperView.

Expand Down
Loading