Skip to content

tyy-dev/TerminalGui.Extensions

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

23 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

TerminalGui.Extensions

A fluent extension library for Terminal.Gui that provides intuitive builder patterns and extension methods

Quick Start

using Terminal.Gui;
using TerminalGui.Extensions.Extensions.ViewExtensions;

public class SettingsWindow : Window
{
    public SettingsWindow()
    {
        Title = "Settings";
        this.WithFill();

        // Use the fluent builder pattern
        this.Builder()
            .AddFrameView(out FrameView audioFrame, title: "Audio")
            .AddFrameView(out FrameView displayFrame, title: "Display");

        audioFrame.WithFillAuto();
        displayFrame.WithFillAuto();

        // Build audio settings
        audioFrame.Builder()
            .AddLabel(out _, text: "Master Volume:")
            .AddNumericUpDown(
                out NumericUpDownConstrained<int> nudVolume,
                value: 80,
                step: 5,
                min: 0,
                max: 100,
                format: "{0}%")
            .AddCheckBox(out CheckBox chkMute, text: "Mute All");

        // Build display settings
        displayFrame.Builder()
            .AddOptionSelector(
                out OptionSelector themeSelector,
                labels: ["Dark", "Light", "Solarized"],
                value: 0)
            .AddCheckBox(
                out CheckBox chkAnimations,
                text: "Enable Animations",
                checkedState: CheckState.Checked);

        // Create tabs with the specialized TabsBuilder
        this.Builder()
            .AddTabs(out var tabs)
            .AddTab("General", generalBuilder =>
            {
                generalBuilder
                    .AddLabel(out _, text: "Player Name:")
                    .AddTextField(out TextField tfName, text: "Player 1")
                    .AddLabel(out _, text: "Difficulty:")
                    .AddOptionSelector(out OptionSelector diffSelector, labels: ["Easy", "Normal", "Hard"], value: 1);
            })
            .AddTab("Keybinds", keybindsBuilder =>
            {
                keybindsBuilder.GetView().MakeScrollable();
                keybindsBuilder
                    .AddLabel(out _, text: "Move Up:")
                    .AddTextField(out _, text: "W", readOnly: true)
                    .AddLabel(out _, text: "Move Down:")
                    .AddTextField(out _, text: "S", readOnly: true)
                    .AddLabel(out _, text: "Interact:")
                    .AddTextField(out _, text: "E", readOnly: true);
            })
            .Done(); // Return to the parent builder

        // Add status bar
        this.Builder()
            .AddStatusBar(out _, statusBar => statusBar
                .AddShortcut(text: "Save", key: Key.S.WithCtrl)
                .AddShortcut(text: "Close", key: Key.Esc));

        // Event handlers
        themeSelector.OnValueChanged(e => ApplyTheme(e.NewValue ?? 0));

        chkMute.OnValueChanging(e =>
        {
            bool isChecked = e.NewValue == CheckState.Checked;
            nudVolume.Max = isChecked ? 0 : 100;
            if (isChecked) nudVolume.Value = 0;
        });
    }

    private static void ApplyTheme(int themeIndex) { /* ... */ }
}

Features

🎯 Fluent Builder Pattern

  • Chain method calls for readable, declarative UI construction
  • Automatic vertical layout with NextPosY (customizable)
  • Out parameters for immediate access to created views

🔧 Comprehensive View Support

All major Terminal.Gui controls with fluent builders:

  • Containers: FrameView, Window, Dialog, Tabs, Wizard
  • Input: TextField, TextView, NumericUpDown, CheckBox, DatePicker
  • Selection: OptionSelector, FlagSelector, DropDownList, ListView
  • Display: Label, Link, Markdown, ImageView, ProgressBar, GraphView
  • Data: TableView, TreeView, HexView
  • Navigation: Menu, MenuBar, StatusBar, Tabs
  • Graphics: Line, Bar, ColorPicker, ImageView
  • And many more...

📋 Specialized Builders

TabsBuilder

Manage tabs with ease:

this.Builder()
    .AddTabs(out var tabs)
    .WithTabSide(Side.Top)
    .WithTabSpacing(2)
    .AddTab("Home", builder => 
        builder.AddLabel(out _, "Welcome!"))
    .AddTab("Settings", builder => 
        builder.AddCheckBox(out _, "Enable feature"))
    .SelectTab(0)
    .OnValueChanged(e => Console.WriteLine($"Switched to tab: {e.NewValue}"))
    .Done();

// Or configure an existing Tabs instance
tabs.TabsBuilder()
    .AddTab("New Tab", new View())
    .SelectTab("Home")
    .ClearTabs();

🎨 Layout Helpers

// Fill available space
view.WithFill();
view.WithFill(widthAdjust: -2, heightAdjust: -1);

// Auto-size to content
view.WithAuto();

// Mix fill width with auto height
view.WithFillAuto();

// Custom layout
view.WithLayout(
    width: Dim.Percent(50),
    height: Dim.Fill() - 2,
    x: Pos.Center(),
    y: Pos.Bottom(parentView) + 1);

// Make scrollable
view.MakeScrollable();

🎪 Event Extensions

Fluent event subscription for all views:

button
    .OnAccepted(e => Console.WriteLine("Button clicked!"))
    .OnMouseEnter(e => button.ColorScheme = highlightScheme)
    .OnMouseLeave(e => button.ColorScheme = normalScheme);

textField
    .OnValueChanged(e => Validate(e.NewValue))
    .OnKeyDown(e => HandleSpecialKeys(e.Key));

Table of Contents

ViewBuilder

ViewBuilder.cs

Notes

  • All Add methods return the ViewBuilder instance for chaining.
  • All Add(...) methods return the added child via an out parameter as the first parameter.
  • Parameters with null defaults retain their class's initialization values.
  • The text parameter defaults to "{typeName} {parent.SubViews.Count}" (e.g., "Button 3") if not provided.

Properties

NextPosY

A function that determines how to position a new child relative to the previously added child. Takes the last added child as input and returns the Y position to use for the new child, or null to skip auto-positioning.

By default this is Pos.Bottom, which ensures that each new child is placed directly below the last added child.

NextPosX

Does the exact same as NextPosY, but for the X position. By default no auto-positioning is applied for X.

SkipAutoPositioning

If true, skips any auto-positioning logic for any future added children, unless set to false again. It is suggested to set this property when using view.WithLayout(...) if you do not want auto-positioning to interfere with the layout.

Core Methods

GetView()

Returns the parent View associated with the builder.

GetLastChildAdded()

viewBuilder.AddButton(out _, "a button");
Button? button = viewBuilder.GetLastChildAdded() as Button;

Add(...)

windowBuilder.Add(out Button button, new(), btn => btn.Text = "Click me");

// You can also add a ViewBuilder directly:
ViewBuilder<Menu> menuBuilder = new Menu().Builder();
menuBuilder.AddLabel(out Label label, "Menu 1");
windowBuilder.Add(menuBuilder, out Menu menu);

Add Methods

Every view type follows the same pattern — two overloads:

  1. Pass a pre-constructed instance: AddXxx(Xxx instance)
  2. Use named parameters with an out reference: AddXxx(out Xxx xxxOut, ...)
Method View Type Notable Parameters
AddBar Bar alignmentModes, orientation
AddButton Button text, isDefault, noDecorations, noPadding, hotKeySpecifier
AddCharMap CharMap selectedCodePoint, showGlyphWidths, startCodePoint, value, showUnicodeCategory
AddCheckBox CheckBox text, checkedState, allowCheckedStateNone, hotKeySpecifier
AddRadioButton CheckBox Same as CheckBox but with RadioStyle = true
AddColorPicker ColorPicker selectedColor, style, text
AddColorPicker16 ColorPicker16 selectedColor, boxWidth, boxHeight
AddDatePicker DatePicker date, culture, text
AddDialog Dialog title, buttons, buttonAlignment, buttonAlignmentModes, result
AddDropDownList DropDownList source, text, readOnly, secret
AddFileDialog FileDialog title, path, allowedTypes, allowsMultipleSelection, mustExist, openMode
AddFrameView FrameView title
AddGraphView GraphView cellSize, scrollOffset, graphColor, marginLeft, marginBottom, axisX, axisY
AddHexView HexView source, readOnly, bytesPerLine, addressWidth, address
AddLabel Label text, hotKeySpecifier
AddLine Line length, orientation, lineStyle
AddLinearSelector<T> LinearSelector<T> options, orientation, allowEmpty, showLegends, type, style, minimumInnerSpacing, ...
AddListView ListView source, selectedItem, value, showMarks, markMultiple
AddMenu Menu menuItems, orientation, alignmentModes, superMenuItem, value
AddMenuItem MenuItem commandText, helpText, action, key, subMenu, ...
AddMenuBar MenuBar menus, key
AddMenuBarItem MenuBarItem commandText, targetView, command, popoverMenu
AddNumericUpDown<T> NumericUpDownConstrained<T> value, format, step, min, max
AddOpenDialog OpenDialog title, path, allowedTypes, allowsMultipleSelection, mustExist, openMode
AddOptionSelector OptionSelector text, orientation, styles, labels, focusedItem, value, values, ...
AddOptionSelector<TEnum> OptionSelector<TEnum> text, orientation, styles, value, ...
AddPopoverMenu PopoverMenu root, key, mouseFlags
AddProgressBar ProgressBar text, fraction, format, style, segmentCharacter, bidirectionalMarquee
AddSaveDialog SaveDialog title, path, allowedTypes, mustExist
AddScrollBar ScrollBar orientation, increment, visibleContentSize, scrollableContentSize, value, visibilityMode
AddScrollSlider ScrollSlider orientation, size, position, visibleContentSize, sliderPadding
AddShortcut Shortcut text, key, action, helpText, bindKeyToApplication, command, targetView, ...
AddSpinnerView SpinnerView style, autoSpin, spinDelay, spinBounce, spinReverse, sequence
AddStatusBar StatusBar shortcuts or configureShortcuts callback, orientation, alignmentModes
AddTextField TextField text, readOnly, secret, insertionPoint, ...
AddTextView TextView text, readOnly, multiline, wordWrap, tabWidth, scrollBars, ...
AddTreeView TreeView multiSelect, allowLetterBasedNavigation, maxDepth, treeBuilder, style, ...
AddWindow Window title, views (auto-added children), returns addedViews via second out parameter
AddWizard Wizard title, currentStep, buttons, buttonAlignment, buttonAlignmentModes
Examples

AddButton

viewBuilder.AddButton(new() { Text = "Button 1" });

viewBuilder.AddButton(
    out Button button,
    text: "Button 2",
    isDefault: false,
    noDecorations: false,
    noPadding: false,
    hotKeySpecifier: new(';'));

AddCheckBox / AddRadioButton

viewBuilder.AddCheckBox(
    out CheckBox checkBox,
    text: "Checkbox 1",
    checkedState: CheckState.Checked,
    allowCheckedStateNone: false);

viewBuilder.AddRadioButton(
    out CheckBox radioButton,
    text: "Option A",
    checkedState: CheckState.Checked);

AddLabel

viewBuilder.AddLabel(out Label label, text: "Hello, World!");

AddNumericUpDown

viewBuilder.AddNumericUpDown(
    out NumericUpDownConstrained<double> nud,
    value: 50.0,
    step: 1.0,
    format: "Value: {0}",
    min: 0.0,
    max: 100.0);

AddWindow

viewBuilder.AddWindow(new());

viewBuilder.AddWindow(
    out Window subWindow,
    out List<View> addedViews,
    views: [new Label() { Text = "Hello, World!" }]);

AddMenuBar

viewBuilder.AddMenuBar(out MenuBar menuBar, menus: [
    new MenuBarItem() { Title = "File" }
]);

AddProgressBar

viewBuilder.AddProgressBar(
    out ProgressBar progressBar,
    text: "Loading",
    fraction: 0.5f,
    style: ProgressBarStyle.Continuous);

AddOptionSelector

viewBuilder.AddOptionSelector(
    out OptionSelector os,
    labels: ["Option A", "Option B", "Option C"],
    value: 0);

viewBuilder.AddOptionSelector(
    out OptionSelector<MyEnum> enumSelector,
    value: MyEnum.FirstValue);

Specialized Builders

TabsBuilder

TabsBuilder.cs

A specialized fluent builder for configuring and managing Tabs views. Returned by ViewBuilder.AddTabs(...) or accessible via tabs.TabsBuilder().

Creating a TabsBuilder

From ViewBuilder (most common):

this.Builder()
    .AddTabs(out var tabs)
    .AddTab("Home", builder => 
        builder.AddLabel(out _, "Welcome!"))
    .AddTab("Settings", builder => 
        builder.AddCheckBox(out _, "Enable Feature"))
    .Done(); // Returns to the parent ViewBuilder

From existing Tabs instance:

tabs.TabsBuilder()
    .AddTab("New Tab", new View())
    .SelectTab(0);

TabsBuilder Methods

Method Description
WithScrollOffset(int) Configure horizontal scroll offset for tab headers
WithTabDepth(int) Set height of the tab header area
WithLineStyle(LineStyle) Configure line style for tab borders
WithTabSide(Side) Set which side tabs appear (Top, Bottom, Left, Right)
WithTabSpacing(int) Configure space between tab headers
AddTab(title, Action<ViewBuilder<View>>) Add a tab and configure its content via builder callback
AddTab(title, View) Add a tab with an existing view as content
AddTab<TView>(title, out TView) Add a typed tab and get a builder for its content
RemoveTabAt(int) Remove tab at specified index
ClearTabs() Remove all tabs
SelectTab(int) Select tab by index
SelectTab(string) Select tab by title
OnValueChanged(handler) Attach handler to tab selection changed event
OnValueChanging(handler) Attach handler to tab selection changing event (cancellable)
Done() Return to parent ViewBuilder (only when created via AddTabs)

TabsBuilder Examples

Basic tabs with fluent content
this.Builder()
    .AddTabs(out var tabs)
    .WithTabSide(Side.Top)
    .AddTab("Profile", builder =>
    {
        builder
            .AddLabel(out _, "Username:")
            .AddTextField(out var username, "Player1")
            .AddLabel(out _, "Level:")
            .AddNumericUpDown(out var level, value: 5);
    })
    .AddTab("Inventory", builder =>
    {
        builder.AddListView(out var list, source: items);
    })
    .SelectTab(0)
    .OnValueChanged(e => Console.WriteLine($"Switched to: {e.NewValue?.Title}"))
    .Done();
Advanced tab management
var tabBuilder = tabs.TabsBuilder();

// Add dynamic tabs
for (int i = 0; i < 5; i++)
{
    int index = i; // Capture
    tabBuilder.AddTab($"Tab {i}", builder =>
        builder.AddButton(out _, $"Button in tab {index}"));
}

// Select specific tab
tabBuilder.SelectTab("Tab 2");

// Remove last tab
var count = tabs.TabCollection.Count();
if (count > 0)
    tabBuilder.RemoveTabAt(count - 1);
Typed tab views
this.Builder()
    .AddTabs(out var tabs)
    .AddTab("Editor", out FrameView editorFrame)
    .AddButton(out _, "Save")
    .AddButton(out _, "Load")
    .Done() // Returns from the editorFrame builder
    .AddTab("Preview", out View previewView)
    .AddLabel(out _, "Preview content here")
    .Done() // Returns from the previewView builder
    .Done(); // Returns from the TabsBuilder to parent ViewBuilder

View Extensions

ViewBaseExtensions.cs

Builder()

Creates a ViewBuilder<T> instance for any View.

ViewBuilder<Window> builder = view.Builder();
builder.AddButton(out _, "Button Text");

ConfigureWithBuilder(...)

Creates a builder via Builder() and passes it to the callback.

view.ConfigureWithBuilder(viewBuilder =>
{
    viewBuilder.AddButton(out _, "Button Text");
});

WithLayout(...)

view.WithLayout(
    width: Dim.Fill(),
    height: Dim.Fill(),
    x: Pos.Center(),
    y: Pos.Center()
);

view.WithLayout(
    width: Dim.Auto(),
    height: Dim.Auto()
);

WithFill(...)

Sets both width and height to Dim.Fill().

view.WithFill();
view.WithFill(widthAdjust: -2, heightAdjust: -1);

WithAuto(...)

Sets both width and height to Dim.Auto().

view.WithAuto();
view.WithAuto(widthAdjust: 2);

WithFillAuto(...)

view.WithFillAuto();
view.WithFillAuto(widthAdjust: -1);

MakeScrollable()

Configures the view as scrollable content with a vertical scroll bar. Automatically tracks the content size based on subview positions.

view.MakeScrollable();

Subview Search

FindSubView<T>() — Finds the first direct child of the given type.

FindAllSubViews<T>() — Recursively finds all descendants of the given type.

Button? btn = view.FindSubView<Button>();
IEnumerable<Label> allLabels = view.FindAllSubViews<Label>();

Command Event Wrappers

Method Wraps
OnAccepted(callback) view.Accepted += ...
OnAccepting(callback) view.Accepting += ...
OnActivating(callback) view.Activating += ...
OnActivated(callback) view.Activated += ...
OnHandlingHotKey(callback) view.HandlingHotKey += ...
OnHotKeyCommand(callback) view.HotKeyCommand += ...
OnCommandNotBound(callback) view.CommandNotBound += ...
view.OnAccepting(args => ...);

Keyboard Event Wrappers

Method Wraps
OnKeyDown(callback) view.KeyDown += ...
OnKeyDownNotHandled(callback) view.KeyDownNotHandled += ...

Mouse Event Wrappers

Method Wraps
OnMouseEvent(callback) view.MouseEvent += ...
OnMouseEnter(callback) view.MouseEnter += ...
OnMouseLeave(callback) view.MouseLeave += ...
OnMouseStateChanged(callback) view.MouseStateChanged += ...
OnMouseHoldRepeatChanged(callback) view.MouseHoldRepeatChanged += ...
OnMouseHoldRepeatChanging(callback) view.MouseHoldRepeatChanging += ...

Focus Event Wrappers

Method Wraps
OnHasFocusChanged(callback) view.HasFocusChanged += ...
OnHasFocusChanging(callback) view.HasFocusChanging += ...
OnFocusedChanged(callback) view.FocusedChanged += ...
OnAdvancingFocus(callback) view.AdvancingFocus += ...
OnCanFocusChanged(callback) view.CanFocusChanged += ...

Lifecycle Event Wrappers

Method Wraps
OnInitialized(callback) view.Initialized += ...
OnDisposing(callback) view.Disposing += ...
OnRemoved(callback) view.Removed += ...
OnSuperViewChanged(callback) view.SuperViewChanged += ...
OnSuperViewChanging(callback) view.SuperViewChanging += ...
OnSubViewAdded(callback) view.SubViewAdded += ...
OnSubViewRemoved(callback) view.SubViewRemoved += ...

State Change Event Wrappers

Method Wraps
OnVisibleChanged(callback) view.VisibleChanged += ...
OnVisibleChanging(callback) view.VisibleChanging += ...
OnEnabledChanged(callback) view.EnabledChanged += ...
OnTextChanged(callback) view.TextChanged += ...
OnTitleChanged(callback) view.TitleChanged += ...
OnTitleChanging(callback) view.TitleChanging += ...
OnBorderStyleChanged(callback) view.BorderStyleChanged += ...
OnHotKeyChanged(callback) view.HotKeyChanged += ...
OnSchemeChanged(callback) view.SchemeChanged += ...
OnSchemeChanging(callback) view.SchemeChanging += ...
OnSchemeNameChanged(callback) view.SchemeNameChanged += ...
OnSchemeNameChanging(callback) view.SchemeNameChanging += ...
OnContentSizeChanged(callback) view.ContentSizeChanged += ...
OnContentSizeChanging(callback) view.ContentSizeChanging += ...

Layout Event Wrappers

Method Wraps
OnSubViewsLaidOut(callback) view.SubViewsLaidOut += ...
OnSubViewLayout(callback) view.SubViewLayout += ...
OnFrameChanged(callback) view.FrameChanged += ...
OnHeightChanged(callback) view.HeightChanged += ...
OnHeightChanging(callback) view.HeightChanging += ...
OnWidthChanged(callback) view.WidthChanged += ...
OnWidthChanging(callback) view.WidthChanging += ...

Drawing Event Wrappers

Method Wraps
OnDrawComplete(callback) view.DrawComplete += ...
OnDrawingContent(callback) view.DrawingContent += ...
OnDrawingSubViews(callback) view.DrawingSubViews += ...
OnDrawingText(callback) view.DrawingText += ...
OnDrewText(callback) view.DrewText += ...
OnClearingViewport(callback) view.ClearingViewport += ...
OnClearedViewport(callback) view.ClearedViewport += ...
OnViewportChanged(callback) view.ViewportChanged += ...
OnGettingAttributeForRole(callback) view.GettingAttributeForRole += ...
OnGettingScheme(callback) view.GettingScheme += ...

Bar Extensions

BarExtensions.cs

Method Wraps
OnOrientationChanged(callback) bar.OrientationChanged += ...
OnOrientationChanging(callback) bar.OrientationChanging += ...

CheckBox Extensions

CheckBoxExtensions.cs

IsChecked

bool isChecked = checkbox.IsChecked; // Equal to checkbox.CheckedState == CheckState.Checked;
checkbox.IsChecked = true; // Equal to checkbox.CheckedState = CheckState.Checked;

Event Wrappers

Method Equivalent
OnValueChanged(callback) checkbox.ValueChanged += ...
OnValueChanging(callback) checkbox.ValueChanging += ...
checkbox.OnValueChanged(e => Console.WriteLine($"Changed from {e.OldValue} to {e.NewValue}"));
checkbox.OnValueChanging(e => {
    if (e.NewValue == CheckState.None)
        e.Handled = true; // cancel the change
});

CheckState Extensions

CheckBoxExtensions.cs

static ConvertCheckState(...)

CheckState state1 = CheckState.ConvertCheckState(true);  // CheckState.Checked
CheckState state2 = CheckState.ConvertCheckState(false); // CheckState.UnChecked
CheckState state3 = CheckState.ConvertCheckState(null);  // CheckState.None
bool? value1 = CheckState.ConvertCheckState(CheckState.Checked);   // true
bool? value2 = CheckState.ConvertCheckState(CheckState.UnChecked); // false
bool? value3 = CheckState.ConvertCheckState(CheckState.None);      // null

IsChecked

CheckState state = CheckState.UnChecked;
bool? isChecked = state.IsChecked; // false

ColorPicker Extensions

ColorPickerExtensions.cs

Method Wraps
OnValueChanged(callback) colorPicker.ValueChanged += ...
OnValueChanging(callback) colorPicker.ValueChanging += ...

DatePicker Extensions

DatePickerExtensions.cs

Method Wraps
OnValueChanged(callback) datePicker.ValueChanged += ...
OnValueChanging(callback) datePicker.ValueChanging += ...

FlagSelector Extensions

FlagSelectorExtensions.cs

FlagSelector

Method Wraps
OnValueChanged(callback) flagSelector.ValueChanged += ...
OnValueChanging(callback) flagSelector.ValueChanging += ...
OnOrientationChanged(callback) flagSelector.OrientationChanged += ...
OnOrientationChanging(callback) flagSelector.OrientationChanging += ...

FlagSelector<TFlagsEnum>

Method Wraps
OnValueChanged(callback) flagSelector.ValueChanged += ...

HexView Extensions

HexViewExtensions.cs

Method Wraps
OnEdited(callback) hexView.Edited += ...
OnPositionChanged(callback) hexView.PositionChanged += ...

Line Extensions

LineExtensions.cs

Method Wraps
OnOrientationChanged(callback) line.OrientationChanged += ...
OnOrientationChanging(callback) line.OrientationChanging += ...

ListView Extensions

ListViewExtensions.cs

GetSelectedItem<T>(...)

Returns the currently selected item from the source list, or default when nothing is selected.

IList<string> items = ["Apple", "Banana", "Cherry"];
string? selected = listView.GetSelectedItem(items);

WithScrollBars(...)

listView.WithScrollBars(vertical: true, horizontal: false);
Method Wraps
OnValueChanged(callback) listView.ValueChanged += ...
OnValueChanging(callback) listView.ValueChanging += ...
OnCollectionChanged(callback) listView.CollectionChanged += ...
OnSourceChanged(callback) listView.SourceChanged += ...
OnRowRender(callback) listView.RowRender += ...

Menu Extensions

MenuExtensions.cs

Method Wraps
OnSelectedMenuItemChanged(callback) menu.SelectedMenuItemChanged += ...
OnValueChanged(callback) menu.ValueChanged += ...
OnValueChanging(callback) menu.ValueChanging += ...

MenuBar Extensions

MenuBarExtensions.cs

Method Wraps
OnKeyChanged(callback) menuBar.KeyChanged += ...

NumericUpDown Extensions

NumericUpDownExtensions.cs

Method Wraps
OnValueChanged(callback) numericUpDown.ValueChanged += ...
OnValueChanging(callback) numericUpDown.ValueChanging += ...
OnFormatChanged(callback) numericUpDown.FormatChanged += ...
OnIncrementChanged(callback) numericUpDown.IncrementChanged += ...
numericUpDown.OnValueChanged(e => Console.WriteLine($"New: {e.NewValue}"));
numericUpDown.OnValueChanging(e => {
    if (e.NewValue < 0) e.Handled = true; // cancel negative values
});

OptionSelector Extensions

OptionSelectorExtensions.cs

OptionSelector

Method Wraps
OnValueChanged(callback) optionSelector.ValueChanged += ...
OnValueChanging(callback) optionSelector.ValueChanging += ...
OnOrientationChanged(callback) optionSelector.OrientationChanged += ...
OnOrientationChanging(callback) optionSelector.OrientationChanging += ...

OptionSelector<TEnum>

Method Wraps
OnValueChanged(callback) optionSelector.ValueChanged += ...

ScrollBar Extensions

ScrollBarExtensions.cs

Method Wraps
OnOrientationChanged(callback) scrollBar.OrientationChanged += ...
OnOrientationChanging(callback) scrollBar.OrientationChanging += ...
OnScrollableContentSizeChanged(callback) scrollBar.ScrollableContentSizeChanged += ...
OnScrolled(callback) scrollBar.Scrolled += ...
OnSliderPositionChanged(callback) scrollBar.SliderPositionChanged += ...
OnValueChanged(callback) scrollBar.ValueChanged += ...
OnValueChanging(callback) scrollBar.ValueChanging += ...

ScrollSlider Extensions

ScrollSliderExtensions.cs

Method Wraps
OnOrientationChanged(callback) scrollSlider.OrientationChanged += ...
OnOrientationChanging(callback) scrollSlider.OrientationChanging += ...
OnPositionChanged(callback) scrollSlider.PositionChanged += ...
OnPositionChanging(callback) scrollSlider.PositionChanging += ...
OnScrolled(callback) scrollSlider.Scrolled += ...

PopoverMenu Extensions

PopoverMenuExtensions.cs

Method Wraps
OnKeyChanged(callback) popoverMenu.KeyChanged += ...

Shortcut Extensions

ShortcutExtensions.cs

Method Wraps
OnOrientationChanged(callback) shortcut.OrientationChanged += ...
OnOrientationChanging(callback) shortcut.OrientationChanging += ...

TextField Extensions

TextFieldExtensions.cs

Method Wraps
OnValueChanged(callback) textField.ValueChanged += ...
OnValueChanging(callback) textField.ValueChanging += ...
OnTextChanging(callback) textField.TextChanging += ...
textField.OnValueChanged(e => Console.WriteLine($"New: {e.NewValue}"));
textField.OnTextChanging(e => {
    if (e.Result?.Contains("bad") == true) e.Result = null; // cancel
});

TextView Extensions

TextViewExtensions.cs

Method Wraps
OnContentsChanged(callback) textView.ContentsChanged += ...
OnDrawNormalColor(callback) textView.DrawNormalColor += ...
OnDrawReadOnlyColor(callback) textView.DrawReadOnlyColor += ...
OnDrawSelectionColor(callback) textView.DrawSelectionColor += ...
OnDrawUsedColor(callback) textView.DrawUsedColor += ...
OnUnwrappedCursorPositionChanged(callback) textView.UnwrappedCursorPositionChanged += ...

Wizard Extensions

WizardExtensions.cs

Method Wraps
OnMovingBack(callback) wizard.MovingBack += ...
OnMovingNext(callback) wizard.MovingNext += ...
OnStepChanged(callback) wizard.StepChanged += ...
OnStepChanging(callback) wizard.StepChanging += ...

Custom Views

NumericUpDownConstrained<T>

NumericUpDownConstrained.cs

A NumericUpDown<T> subclass with dynamically settable Min and Max constraints. The constraints are enforced via the ValueChanging event and update immediately when the properties change.

Setting Min or Max to null disables the corresponding constraint.

var nud = new NumericUpDownConstrained<int> { Min = 0, Max = 100, Value = 50 };

// Constraints are dynamic — update them at any time:
nud.Max = 200;
nud.Min = null; // remove lower bound

The AddNumericUpDown(...) builder method creates a NumericUpDownConstrained<T> by default:

viewBuilder.AddNumericUpDown(
    out NumericUpDownConstrained<double> nud,
    value: 10.0,
    step: 0.5,
    min: 0.0,
    max: 100.0);

// Later, adjust the constraint dynamically:
nud.Max = newCapacity;

MessageBox Extensions

MessageBoxExtensions.cs

static MessageBox.Confirm(...)

bool confirmed = MessageBox.Confirm(App, "Are you sure?");
bool confirmed2 = MessageBox.Confirm(App,
    message: "Proceed?",
    yesText: "Confirm",
    noText: "Cancel");

static MessageBox.Error(...)

MessageBox.Error(App, "Something went wrong.");
MessageBox.Error(App,
    message: "Something went wrong.",
    title: "Error",
    okText: "Close");

// ...
catch (Exception e)
{
    MessageBox.Error(App, exception: e);
    MessageBox.Error(App,
        exception: e,
        title: e.GetType().Name);
}

static MessageBox.Info(...)

MessageBox.Info(App, "Done.");
MessageBox.Info(App,
    message: "Saved.",
    okText: "Proceed");

ApplicationExtensions

ApplicationExtensions.cs

Session Stack

Convenience methods for inspecting the IApplication.SessionStack.

Member Description
SessionCount The number of active sessions.
HasActiveSessions Whether the session stack has any active sessions.
GetCurrentSession() Peeks at the top session without removing it.
FindSession(IRunnable) Finds a session by its runnable.
public static Dialog? GetDialog()
    => Application.GetCurrentSession() is {} token
        ? token.Runnable as Dialog
        : null;

MessageBox.Info("Hello, World");
Dialog? messageBox = GetDialog();
int count = app.SessionCount;
bool hasActive = app.HasActiveSessions;

var myRunnable = ...
SessionToken? found = app.FindSession(myRunnable);

Event Wrappers

Method Wraps
OnInitializedChanged(callback) app.InitializedChanged += ...
OnIteration(callback) app.Iteration += ...
OnSessionBegun(callback) app.SessionBegun += ...
OnSessionEnded(callback) app.SessionEnded += ...
OnScreenChanged(callback) app.ScreenChanged += ...
app.OnSessionBegun(e => Console.WriteLine($"Session started: {e.State.Runnable}"));
app.OnScreenChanged(e => Console.WriteLine($"New size: {e.Value}"));

ApplicationNavigationExtensions

ApplicationNavigationExtensions.cs

OnFocusChanged(...)

wrapper for navigation.FocusedChanged += (_, args) => ...

app.Navigation.OnFocusChanged(args => ...);


DONT USE [WILL BE REMOVED]
NavigatesTo(...)

Sets the targetView's Activating handler to navigate to the given runnable.

Example using instance
ViewBuilder<MainWindow> windowBuilder = this.Builder();
windowBuilder.AddButton(out Button settingsBtn, "Go to settings Menu");

Window settings = new();
settings.Builder()
    .AddButton(out Button backButton, "Back to Main Menu");

backButton.OnActivating(_ => App.RequestStop());
app.Navigation.NavigatesTo<Window>(targetView: settingsBtn, runnableTo: settings, closeCurrent: false);
Example using class (creates fresh instance each navigation)
public class SettingsMenu : Window
{
    public SettingsMenu()
    {
        this.Builder()
            .AddButton(out Button backButton, "Back to Main Menu");
        backButton.OnActivating(_ => App.RequestStop());
    }
}
public class MainWindow : Window
{
    public MainWindow(IApplication app)
    {
        ViewBuilder<MainWindow> windowBuilder = this.Builder();
        windowBuilder.AddButton(out Button settingsBtn, "Go to settings Menu");

        app.Navigation.NavigatesTo<SettingsMenu>(targetView: settingsBtn, closeCurrent: false);
    }
}
using IApplication app = Application.Create().Init();
app.Run(new MainWindow(app));
Example using factory (creates fresh instance each navigation)
public class MainWindow : Window
{
    public MainWindow(IApplication app)
    {
        ViewBuilder<MainWindow> windowBuilder = this.Builder();
        windowBuilder.AddButton(out Button settingsBtn, "Go to settings Menu");
        app.Navigation.NavigatesTo(
            targetView: settingsBtn,
            runnableFactory: () => new SettingsMenu(),
            closeCurrent: false);
    }
}

ApplicationPopoverExtensions

ApplicationPopoverExtensions.cs

Method Wraps
OnPopoverRegistered(callback) popover.PopoverRegistered += ...
OnPopoverUnregistered(callback) popover.PopoverDeRegistered += ...
app.Popovers.OnPopoverRegistered(e => Console.WriteLine($"Registered: {e.Value}"));

RunnableExtensions

RunnableExtensions.cs

Method Wraps
OnRunningChanged(callback) runnable.IsRunningChanged += ...
OnRunningChanging(callback) runnable.IsRunningChanging += ...
OsModalChanged(callback) runnable.IsModalChanged += ...
window.OnIsRunningChanged(e => Console.WriteLine($"Running: {e.Value}"));
window.OnIsRunningChanging(e => {
    if (!canStop) e.Cancel = true;
});

About

Terminal.Gui Extensions for cleaner code

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages