Aptivi - Deprecated Manuals
ProjectsWebsiteBlog
Nitrocid KS v0.1.0 Beta 3 - Manual
Nitrocid KS v0.1.0 Beta 3 - Manual
  • 👋Welcome!
  • Versions and Compatibility
    • 🔱Supported Versions
    • 🕘EOL Versions
    • 🗞️Version Release Notes
      • ✨v0.0.1.x series
      • 🌈v0.0.2.x series
      • 👥v0.0.3.x series
      • 🛠️v0.0.4.x series
      • 🕔v0.0.5.x series
        • ⌚v0.0.5.0 Beta Versions
      • 📕v0.0.6.x series
        • 📄v0.0.6.0 Beta Versions
      • 🔌v0.0.7.x series
        • ⚡v0.0.7.0 Beta Versions
      • 🌌v0.0.8.x series
      • 💌v0.0.9.x series
      • 📜v0.0.10.x series
      • ✏️v0.0.11.x series
      • ⚙️v0.0.12.x series
      • 🌐v0.0.13.x series
      • 🏃‍♀️v0.0.14.x series
      • ⏳v0.0.15.x series
      • ⭐v0.0.16.x series
      • 🌃v0.0.17.x series
      • 🥁v0.0.18.x series
      • 🔧v0.0.19.x series
      • 🍀v0.0.20.x series
      • 🧰v0.0.21.x series
      • 📱v0.0.22.x series
      • 🖥️v0.0.23.x series
      • 👾v0.0.24.x series
      • 🔮v0.1.x.x series
        • ⚠️Known issues for 0.1.0 Beta
    • 👍Compatibility Notes for KS API Revisions
      • 🔼Upgrading from API v1.0
      • 🔼Upgrading from API v1.1
      • 🔼Upgrading from API v1.2
      • 🔼Upgrading from API v1.3
      • 🔼Upgrading from API v2.0
      • 🔼Upgrading from API v2.1
      • 🔼Upgrading to API v3.0
        • ⬆️From 0.0.24.x to 0.1.0 Beta 1
        • ⬆️From 0.1.0 Beta 1 to 0.1.0 Beta 2
        • ⬆️From 0.1.0 Beta 2 to 0.1.0 Beta 3
  • Installation and Maintenance
    • 📀Installing the Kernel
      • 💻Windows
      • 🍎macOS
      • 🐧Linux
      • 📱Android
    • ⏫Upgrading the Kernel
      • 💻Windows
      • 🍎macOS
      • 🐧Linux
      • 📱Android
    • 📦Dependency Information
  • Fundamentals
    • 🌽What is the Kernel?
    • 👾What is Nitrocid KS?
    • ⭐Simulated Kernel Features
      • 🌟Extra Features
        • 🌏More Networking
          • 🗃️FTP Client
          • 🔒SFTP Client
          • 📰RSS Client
          • 🌐HTTP Client
          • 📧Mail Client
        • 🎮Games and Amusements
          • 🔤Hangman
          • 🏇BackRace
          • ☄️Meteor
          • 🎰Russian Roulette
          • ☄️ShipDuet
          • 🐍Snaker
          • 🔢Solver
          • ⌨️SpeedPress
          • 🔠Wordle
        • 🖊️More Editors
          • 🖊️JSON Editor
          • 🗄️SQL Editor
        • 🧰Common Programs
          • 📦Archive
          • ☕Caffeine
          • 🗓️Calendar
          • 🔢Calculator
          • 👥Contacts
          • 👩‍💻Git Shell
          • 🎧Music Player
          • 🗒️Notes
          • 🔌SSH Connection
          • ⏰Stopwatch and Timer
          • ☑️To-do List
          • ⚖️Unit Converter
          • ☀️Weather
        • 🪄ChatGPT Client
        • 🖼️Docking
        • 🌏Language Studio
        • 🎨Theme Studio
      • 👤Accounts
        • 👥Groups
        • 🔓Permissions
      • ✏️Editors
        • 📝Text Editor
        • 💾Hex Editor
      • 🐚Shells
        • 📄Commands List
        • 📄Addon Commands List
      • 📂Files and Folders
      • 🌎Networking
      • 🇺🇸Languages
      • 🌌Screensavers
      • 💿Bootable Simulation
  • Advanced and Power Users
    • ⚒️Building the Kernel
      • 🪟Building on Windows
      • 🍎Building on macOS
      • 🐧Building on Linux
      • 📱Building on Android
    • 🧰Kernel Modifications
      • 🏗️Build your...
        • 🧪Your Mod
        • 🪄Your Splash
      • 📉Analyzers for Mods
      • 📈Analyzer Diagnostics
        • 📉Text - NKS0001
        • 📉ConsoleBase - NKS0002
        • 📉ConsoleBase - NKS0003
        • 📉ConsoleBase - NKS0004
        • 📉ConsoleBase - NKS0005
        • 📉ConsoleBase - NKS0006
        • 📉ConsoleBase - NKS0007
        • 📉ConsoleBase - NKS0008
        • 📉ConsoleBase - NKS0009
        • 📉Files - NKS0010
        • 📉Files - NKS0011
        • 📉Files - NKS0012
        • 📉Files - NKS0013
        • 📉Files - NKS0014
        • 📉Files - NKS0015
        • 📉Files - NKS0016
        • 📉Files - NKS0017
        • 📉Files - NKS0018
        • 📉Files - NKS0019
        • 📉Files - NKS0020
        • 📉Files - NKS0021
        • 📉Files - NKS0022
        • 📉Files - NKS0023
        • 📉Kernel - NKS0024
        • 📉Kernel - NKS0025
        • 📉Kernel - NKS0026
        • 📉Kernel - NKS0027
        • 📉Kernel - NKS0031
        • 📉Kernel - NKS0032
        • 📉Kernel - NKS0033
        • 📉Kernel - NKS0037
        • 📉Kernel - NKS0038
        • 📉Kernel - NKS0039
        • 📉Kernel - NKS0040
        • 📉Kernel - NKS0041
        • 📉Kernel - NKS0042
        • 📉Kernel - NKS0043
        • 📉Kernel - NKS0052
        • 📉Kernel - NKS0053
        • 📉Languages - NKS0044
        • 📉Languages - NKS0045
        • 📉Languages - NKS0046
        • 📉Network - NKS0051
        • 📉Text - NKS0047
        • 📉Text - NKS0048
        • 📉Text - NKS0049
        • 📉Text - NKS0050
        • 📉Text - NKS0054
        • 📉Text - NKS0055
      • 🔧Kernel Modification Management
      • 📞Inter-Mod Communication
      • 📞Inter-Addon Communication
    • 🦠Diagnostics
      • 🔬Debugging
        • 🧬Local Debugging
        • 🛰️Remote Debugging
      • 🧪Testing
      • 💉Other Diagnostics
    • ⚒️Inner Workings
      • 🔧Kernel Settings
        • ⛏️Mechanics of Settings App
        • 🔩Settings Format
        • ⚙️Custom Settings
      • 🐚Shell Structure
        • ❔Help System
        • 🗜️Command Parsing
        • 🔋Command Information
        • ⏲️Command Switch Management
        • 🎚️Command Switch Information
        • ⏳Shell History
        • 📜Shell Scripting
        • 📟Shell Presets
        • 💠Extra Shell Features
      • 🌍Multilingual Kernel
        • 🌐Custom Languages
      • 🖥️Console Manipulation
        • 🧩Console Wrappers
        • 🖥️Console Screen
      • 🖲️Console Input
        • ⌨️Interactive TUI
        • 📽️Presentation System
      • ♦️Inner Essentials
        • 🪧Kernel Placeholders
        • 🔐The Permissions
        • 👥The Users
        • 📞Kernel Threads
        • 🔌Kernel Drivers
        • 🎛️Kernel Arguments
        • 📒Kernel Journaling
        • 📡Remote Procedure
        • 🗃️Nitrocid Filesystem
        • 🌃Screensaver Internals
        • 💦Splash Internals
        • 🖥️Kernel Platform
        • 🎨Theme Internals
        • ⛱️Color Internals
        • 🔏Privacy Consents
        • 🔔System Notifications
        • ✉️MAL and MOTD
        • ⌛Progress Handlers
        • ✒️Assembly Signing
        • 🎰Random Number Generation
        • 🌍Network Tools
      • 🌀Miscellaneous APIs
  • 🧱Project Dependencies
  • Report an issue
  • Source code
  • API Reference
Powered by GitBook
On this page
  • Can I make one, too?
  • Colors for the TUI
  • LastOnOverflow()
  • AcceptsEmptyData
  • HandleExit()
  • Instance
Edit on GitHub
  1. Advanced and Power Users
  2. Inner Workings
  3. Console Input

Interactive TUI

Your apps are now interactive

Last updated 1 year ago

The interactive TUI allows you to make your apps interactive if they provide one or two data sources, which consist of a list of strings, integers, and even class instances, to make getting information about them easier. The interactive TUI renders the screen in two panes, the top being a status bar, and the bottom being a list of key bindings. For clarification, the ifm command uses the double pane interactive TUI and the taskman command uses the single pane interactive TUI with info in the second pane:

Double-paned interactive TUI with the ability to switch between two panes
Single-paned interactive TUI

You can exit out of any interactive TUI application by pressing the ESC key on your keyboard.

These are some of the controls, alongside the custom defined controls for a specific TUI, that you can use:

Key
Action

Up Arrow

Moves up one element in the current pane

Down Arrow

Moves down one element in the current pane

Home

Moves to the first element

End

Moves to the last element

Page Up

One page backward

Page Down

One page forward

I

Gives you more information about a selected element if there is one

K

Shows you a list of available bindings

Tab

Switches the sides

ESC

Exits the interactive TUI app

This feature is also available on Terminaux. Some of the features here might not get backported to Terminaux until the next version surfaces there.

Can I make one, too?

Yes! You can make your own interactive TUI application. Depending on your requirements, you may want to make a plan as to how would your interactive TUI application be.

For each application, you must make a class that would implement both the BaseInteractiveTui class and the IInteractiveTui interface, just like below:

MyTui.cs
internal class MyTui : BaseInteractiveTui, IInteractiveTui
{
    public override List<InteractiveTuiBinding> Bindings { get; set; } = new()
    {
        new InteractiveTuiBinding("Action", ConsoleKey.F1, (data, _) => Proceed(data))
    };

    public override IEnumerable PrimaryDataSource =>
        new string[] { "One", "Two", "Three", "Four" };

    public override void RenderStatus(object item)
    {
        string currentItem = (string)item;
        Status = currentItem;
    }

    public override string GetEntryFromItem(object item)
    {
        string currentItem = (string)item;
        return $" [{currentItem}]";
    }

    private static void Proceed(object data)
    {
        string currentItem = (string)data;
        InfoBoxColor.WriteInfoBox(currentItem);
    }
}

However, you cannot execute your interactive TUI based on your class unless you use this (assuming that you've already defined a command entry in your mod entry point class called mycommand):

MyCommand.cs
public override int Execute(CommandParameters parameters, ref string variableValue)
{
	InteractiveTuiTools.OpenInteractiveTui(new MyTui());
	return 0;
}

If everything goes well, you should see this:

And if you press your key binding, you'll get this:

When defining the interactive TUI binding, you can now set the required modifier keys by setting the bindingKeyModifiers value. Here is a constructor that supports this property:

public InteractiveTuiBinding(string bindingName, ConsoleKey bindingKeyName, ConsoleModifiers bindingKeyModifiers, Action<object, int> bindingAction)

For multiple panes, you'll have to modify your class to take two data sources and adapt it to interact with the second pane, like below: (note the highlighted parts, they are added)

MyTui.cs
internal class MyTui : BaseInteractiveTui, IInteractiveTui
{
    public override List<InteractiveTuiBinding> Bindings { get; set; } = new()
    {
        new InteractiveTuiBinding("Action", ConsoleKey.F1, (data, _) => Proceed(data)),
    };

    public override bool SecondPaneInteractable =>
        true;

    public override IEnumerable PrimaryDataSource =>
        new string[] { "One", "Two", "Three", "Four" };

    public override IEnumerable SecondaryDataSource =>
        new string[] { "Five", "Six", "Seven", "Eight", "Nine", "Ten" };

    public override void RenderStatus(object item)
    {
        string currentItem = (string)item;
        Status = currentItem;
    }

    public override string GetEntryFromItem(object item)
    {
        string currentItem = (string)item;
        return $" [{currentItem}]";
    }

    private static void Proceed(object data)
    {
        string currentItem = (string)data;
        InfoBoxColor.WriteInfoBox(currentItem);
    }
}

If everything goes well, you should be able to switch to the second pane, causing you to be able to select items from the second pane:

And if you try to execute your key binding on an item found in the second pane, you'll see this:

As of 0.1.0 Beta 3, you don't have to manually implement the switch function, since it's already implemented for double-pane interactive TUIs.

Additionally, you can make your TUI app refresh every set millisecond so that your app can update itself based on the selected data, like weather for the selected city. For this, you need an information source that is dynamic and self-updating (from the GetInfoFromItem() function), like stopwatches, random data, or even self-updating data gathered from the Internet, based on the selected item in the first pane, assuming that you know how to process them correctly.

For example, to use the Namer library to make a single-paned TUI application that gathers random names to list 10 names in the info pane, you must add a NuGet package, Namer, to your mod's dependencies. To learn more about how to use this library, consult the below page:

The code that would do this would look like this:

MyTui.cs
internal class MyTui : BaseInteractiveTui, IInteractiveTui
{
    public override List<InteractiveTuiBinding> Bindings { get; set; } = new();

    public override int RefreshInterval => 15000;

    public override IEnumerable PrimaryDataSource =>
        new string[] { "Test" };

    public override void RenderStatus(object item)
    {
        string currentItem = (string)item;
        Status = currentItem;
    }

    public override string GetEntryFromItem(object item)
    {
        string currentItem = (string)item;
        return $" [{currentItem}]";
    }
    public override string GetInfoFromItem(object item)
    {
        var namesBuilder = new StringBuilder();

        var list = NameGenerator.GenerateNames(10);
        for (int i = 0; i < list.Length; i++)
        {
            string name = list[i];
            namesBuilder.AppendLine(name);
        }

        return namesBuilder.ToString();
    }
}

If everything goes well, you should see your TUI app refresh every 15 seconds:

Colors for the TUI

You can also specify the colors for your TUI application, too! Currently, your interactive TUI uses the regular colors defined under InteractiveTuiColors, which gets its values from the kernel configuration that you can also customize.

However, you can override the TUI colors by using the new keyword on all the *Color properties to assign it a new Color value. For example, the contacts manager gets its own colors from its own colors class, which is also configurable through the kernel settings, like below:

ContactsManagerCli.cs (Beta 2)
public static new Color BackgroundColor => ContactManagerCliColors.ContactsManagerBackgroundColor;
public static new Color ForegroundColor => ContactManagerCliColors.ContactsManagerForegroundColor;
public static new Color PaneBackgroundColor => ContactManagerCliColors.ContactsManagerPaneBackgroundColor;
(...)

LastOnOverflow()

You usually don't need to override this function, as it works by checking both panes for out of bounds and, if overflown, fixing their values so that they don't overflow.

AcceptsEmptyData

You can specify if your interactive TUI accepts empty data. The interactive TUI, by default, checks for the data source in both panes and, if not found or are empty, exits.

However, if you override the value like below, it'll start up regardless of how many data is there.

public override bool AcceptsEmptyData => true;

HandleExit()

If you want to handle exiting your own TUI application in your way, you can override the HandleExit() function like this:

public override void HandleExit()
{
    (...)
}

Instance

If you want to access instance-based fields

⚒️
🖲️
⌨️
How to useHow do you use it?