mirror of
https://github.com/gui-cs/Terminal.Gui.git
synced 2026-02-10 04:03:41 +01:00
11 KiB
11 KiB
Terminal.Gui API Reference (Compressed)
Condensed reference for AI agents. For full details, see
docfx/docs/*.md.
Application Architecture
Instance-Based Pattern (v2)
// RECOMMENDED: Instance-based with using statement
using (IApplication app = Application.Create ().Init ())
{
app.Run<MyDialog> ();
MyResult? result = app.GetResult<MyResult> ();
}
// LEGACY (obsolete): Static Application
Application.Init ();
Application.Run (top);
Application.Shutdown ();
Key Properties
IApplication.TopRunnable- Current modal runnable (top of SessionStack)IApplication.SessionStack- Stack of running IRunnable sessionsView.App- Application context for a view (use instead of staticApplication)View.Driver- Driver access for rendering
IRunnable Pattern
Views can implement IRunnable<TResult> for typed results:
public class MyDialog : Runnable<string?>
{
protected override bool OnIsRunningChanging (bool oldValue, bool newValue)
{
if (!newValue) // Stopping
{
Result = _textField.Text; // Extract result before disposal
}
return base.OnIsRunningChanging (oldValue, newValue);
}
}
Disposal: "Whoever creates it, owns it" - Run<T>() auto-disposes, Run(instance) requires manual disposal.
View Hierarchy
Terminology (CRITICAL)
| Term | Meaning |
|---|---|
| SuperView | Container view (via Add()) |
| SubView | Contained view (added via Add()) |
| Parent/Child | Non-containment references ONLY (rare) |
View Composition (Layers)
Frame (outermost - SuperView-relative coords)
└── Margin (spacing/shadows)
└── Border (visual frame, title)
└── Padding (spacing, scrollbars)
└── Viewport (visible content window)
└── Content Area (drawable area)
Key Properties
Frame- Location/size in SuperView coordinates (includes adornments)Viewport- Visible portion of content (content-relative coords)GetContentSize()- Total content area sizeSetContentSize()- Enable scrolling by setting larger than Viewport
Layout System
Pos (Position)
view.X = 10; // Absolute
view.X = Pos.Percent (50); // Percentage of SuperView
view.X = Pos.Center (); // Centered
view.X = Pos.Right (otherView) + 1; // Relative to another view
view.X = Pos.AnchorEnd (5); // From right edge
view.X = Pos.Align (Alignment.End); // Aligned with peers
Dim (Dimension)
view.Width = 20; // Absolute
view.Width = Dim.Fill (); // Fill available space
view.Width = Dim.Percent (50); // Percentage
view.Width = Dim.Auto (); // Size to content
view.Width = Dim.Width (otherView); // Match another view
Layout Lifecycle
SetNeedsLayout()marks view for layoutLayout()calculates Frame/ViewportLayoutStartedevent raised- SubViews laid out recursively
LayoutCompleteevent raised
Command System
Core Commands
| Command | Trigger | Purpose |
|---|---|---|
Command.Activate |
Space, Click | State change (toggle, select) |
Command.Accept |
Enter, DblClick | Confirm action (submit, execute) |
Command.HotKey |
Alt+Key | Direct access regardless of focus |
Command Pattern
// Register command
AddCommand (Command.Accept, ctx =>
{
// Handle command
return true; // Handled
});
// Bind key to command
KeyBindings.Add (Key.Enter, Command.Accept);
// Bind mouse to command
MouseBindings.Add (MouseFlags.LeftButtonClicked, Command.Activate);
Activating vs Accepting
-
Activating- State change/preparation (local, no propagation)- CheckBox: toggles state
- ListView: selects item
- MenuItem: focuses item
-
Accepting- Confirms/finalizes action (propagates to SuperView)- Button: executes action
- Dialog: submits
- MenuItem: executes command
Cancellable Work Pattern (CWP)
Structure
// Internal raise method
internal void RaiseXxx (EventArgs args)
{
// 1. Do work BEFORE notifications
DoActualWork ();
// 2. Call virtual method (empty in base class)
OnXxx (args);
// 3. Raise event
Xxx?.Invoke (this, args);
}
// Virtual method - empty in base, subclasses override
protected virtual void OnXxx (EventArgs args) { }
Event Handling
// Subscribe to event
view.Accepting += (sender, e) =>
{
e.Handled = true; // Mark as handled
// e.Cancel = true; // Cancel the operation (if cancellable)
};
// Override virtual method in subclass
protected override bool OnAccepting (CommandEventArgs args)
{
if (ShouldCancel)
return true; // Cancel
return base.OnAccepting (args);
}
Common Events
| Event | Virtual Method | Cancellable | Purpose |
|---|---|---|---|
Activating |
OnActivating |
Yes | Before state change |
Accepting |
OnAccepting |
Yes | Before action confirm |
HasFocusChanging |
OnHasFocusChanging |
Yes | Before focus change |
HasFocusChanged |
OnHasFocusChanged |
No | After focus change |
DrawingContent |
OnDrawingContent |
Yes | Before content draw |
Navigation & Focus
Focus Requirements
Visible = trueEnabled = trueCanFocus = trueTabStop != TabBehavior.NoStop(for keyboard nav)
TabBehavior
| Value | Behavior |
|---|---|
NoStop |
Skip in keyboard nav (mouse can still focus) |
TabStop |
Standard Tab navigation |
TabGroup |
F6 navigation between containers |
Navigation Keys
Tab/Shift+Tab- Navigate TabStop viewsF6/Shift+F6- Navigate TabGroup containers- Arrow keys - Navigate within/between views
- HotKeys (
Alt+X) - Direct access
Focus Methods
view.SetFocus (); // Request focus
view.HasFocus // Check if focused
Application.Navigation.GetFocused () // Get most-focused view
Application.Navigation.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabStop);
Keyboard Handling
Key Bindings
// View-scoped (focused)
view.KeyBindings.Add (Key.Enter, Command.Accept);
// View-scoped (hotkey - works without focus)
view.HotKeyBindings.Add (Key.S.WithAlt, Command.HotKey);
// Application-scoped
app.Keyboard.KeyBindings.Add (Key.Q.WithCtrl, Command.Quit);
Key Processing Order
- Most-focused SubView processes first
OnKeyDown()virtual methodKeyDownevent- KeyBindings lookup → Command execution
OnKeyDownNotHandled()for unhandled keys
IKeyboard Interface
// Modern (instance-based)
App.Keyboard.KeyBindings.Add (Key.F1, Command.HotKey);
App.Keyboard.QuitKey = Key.Q.WithCtrl;
// Legacy (delegates to Application.Keyboard)
Application.KeyBindings.Add (Key.F1, Command.HotKey);
Mouse Handling
Mouse Bindings
view.MouseBindings.Add (MouseFlags.LeftButtonClicked, Command.Activate);
view.MouseBindings.Add (MouseFlags.LeftButtonDoubleClicked, Command.Accept);
Mouse Events
MouseEnter/MouseLeave- Hover trackingMouseEvent- Low-level mouse handlingHighlight- Visual feedback on hover/click
Drawing
Drawing Methods
protected override bool OnDrawingContent ()
{
Move (0, 0); // Position draw cursor
SetAttributeForRole (VisualRole.Normal); // Set colors
AddStr ("Hello"); // Draw text
AddRune ('X'); // Draw single char
return true; // Handled
}
Key Concepts
- Draw Cursor - Internal rendering position (
Move()) - Terminal Cursor - Visible cursor (
View.Cursorproperty) - Attribute - Color and text style combination
- LineCanvas - Auto-joining line drawing
Drawing Lifecycle
SetNeedsDraw()marks view for redrawDraw()called by frameworkDrawingContentevent raisedOnDrawingContent()called- Adornments drawn
- SubViews drawn recursively
Color & Theming
Scheme
view.Scheme = new Scheme
{
Normal = new Attribute (Color.White, Color.Black),
Focus = new Attribute (Color.Black, Color.White),
HotNormal = new Attribute (Color.Yellow, Color.Black),
HotFocus = new Attribute (Color.Yellow, Color.White),
Disabled = new Attribute (Color.Gray, Color.Black)
};
VisualRole
SetAttributeForRole (VisualRole.Normal); // Standard
SetAttributeForRole (VisualRole.Focus); // Focused
SetAttributeForRole (VisualRole.HotNormal); // HotKey
SetAttributeForRole (VisualRole.Disabled); // Disabled
Testing
Input Injection
VirtualTimeProvider time = new ();
using IApplication app = Application.Create (time);
app.Init (DriverRegistry.Names.ANSI);
// Inject keyboard input
app.InjectKey (Key.A);
app.InjectKey (Key.Enter);
// No real delays - uses virtual time
Test Patterns
[Fact]
public void MyView_WorksCorrectly ()
{
// Arrange
View view = new () { Width = 10, Height = 5 };
// Act
view.SetNeedsDraw ();
// Assert
Assert.True (view.NeedsDraw);
}
Avoid: Application.Init() in tests unless testing Application-specific functionality.
Common Patterns
Creating Custom Views
public class MyView : View
{
public MyView ()
{
CanFocus = true;
Width = Dim.Auto ();
Height = Dim.Auto ();
AddCommand (Command.Accept, HandleAccept);
KeyBindings.Add (Key.Enter, Command.Accept);
}
protected override bool OnDrawingContent ()
{
Move (0, 0);
AddStr ("Custom content");
return true;
}
private bool HandleAccept () => true;
}
Adding SubViews
View container = new () { Width = Dim.Fill (), Height = Dim.Fill () };
Button btn1 = new () { Text = "OK", X = 2, Y = 2 };
Button btn2 = new () { Text = "Cancel", X = Pos.Right (btn1) + 2, Y = 2 };
container.Add (btn1, btn2);
Dialogs with Results
using (IApplication app = Application.Create ().Init ())
{
app.Run<ConfirmDialog> ();
bool? confirmed = app.GetResult<bool> ();
}
Quick Reference
View Properties
| Property | Purpose |
|---|---|
X, Y |
Position (Pos) |
Width, Height |
Size (Dim) |
Frame |
SuperView-relative bounds |
Viewport |
Content-relative visible area |
Text |
View text content |
Title |
Title (shown in Border) |
Visible |
Show/hide |
Enabled |
Enable/disable |
CanFocus |
Focusable |
TabStop |
Keyboard navigation behavior |
Important Methods
| Method | Purpose |
|---|---|
Add() |
Add SubView |
Remove() |
Remove SubView |
SetFocus() |
Request focus |
SetNeedsDraw() |
Mark for redraw |
SetNeedsLayout() |
Mark for layout |
InvokeCommand() |
Execute command |
Dispose() |
Clean up resources |
Driver Names
DriverRegistry.Names.ANSI // "ansi"
DriverRegistry.Names.WINDOWS // "windows"
DriverRegistry.Names.UNIX // "unix"
DriverRegistry.Names.DOTNET // "dotnet"