UI Toolbox logoUI Toolbox

OnScreenKeyboard

OnScreenKeyboard is a keyboard on the screen for a player with a gamepad. It opens by itself when a gamepad moves the focus to a text field, or when the player presses A on a focused text field. It docks at the bottom of the workspace of the field, or of the panel outside a workspace.

The focus stays on the field. The keys send key events to the field, so the caret, the selection, maxLength and the number filter of a number field work as with a hardware keyboard. A hardware key, a pointer press outside the keyboard or a focus change closes the keyboard.

You do not have to add the keyboard. A Toolbox control in a panel, or a UIDocument in a loaded scene, makes the keyboard open by itself in that panel. The keyboard is made at the first open.

// A panel that the keyboard does not find, such as one made in code after the scene loaded
OnScreenKeyboard.Attach(document.rootVisualElement.panel);

// No automatic open anywhere
OnScreenKeyboard.AutoOpen = false;

// No automatic open for one field, and an open from code
OnScreenKeyboard.SetAutoOpen(chatLine, false);
keyboard.Open(chatLine);

A keyboard declared in UXML is used in place of the one that is made. Use it to set the attributes:

<UIToolbox.OnScreenKeyboard max-suggestions="4" />

Buttons

Button Action
D-pad Moves between the keys. The suggestions are the top row.
A Presses the current key or suggestion.
B Backspace. On an empty field, B closes the keyboard.
X Space.
Y Shift.
LB, RB Moves the caret left and right.
Right stick left and right Chooses a suggestion.
Right stick click Types the chosen suggestion, or the first one.
Start Done: submits the field and closes the keyboard.

Kinds of field

The kind of the field picks the layout and turns the suggestions on or off.

Kind Field Layout Suggestions
Text A TextField Letters and symbols. A capital at the start of the text and of each sentence. Yes
Name The class tb-osk-kind--name Letters and symbols. A capital at the start of each word. Yes
Email The class tb-osk-kind--email Letters and symbols, with @ and .com keys. Yes
Url The class tb-osk-kind--url Letters and symbols, with / and .com keys. Yes
Number An IntegerField, FloatField or other number field A number pad. No
Password A TextField with isPasswordField Letters and symbols. No, and no learned words
OnScreenKeyboard.SetKind(mailField, TextFieldKind.Email);
<ui:TextField label="Email" class="tb-osk-kind--email" />
<ui:TextField label="Seed" class="tb-osk-off" />

The class tb-osk-off on a field or on a parent of it turns the automatic open off for the field.

Word completion

The suggestions come from OnScreenKeyboard.Completer, a WordCompleter. The default is WordCompleter.English, which all keyboards share.

  1. The names of Completer.Names, such as the characters and the places of the game. Their case stays.
  2. The learned words, the most used first. A word is learned when the player types it and then a space or a punctuation mark, accepts it as a suggestion, or presses done after it.
  3. The words of the list, the most common first, then the shortest. The list is the word list of the spell checker, in six sections from common to rare.

A suggestion takes the case of the typed letters: "The" gives "Then", and "THE" gives "THEN".

var completer = WordCompleter.English;
completer.Names.UnionWith(new[] { "Aldebaran", "Mirefen", "Quillon" });

Keep the learned words

The learned words stay in memory and are lost when the game stops. The keyboard does not write files unless you set a store. Set Store to keep the words between sessions:

// A JSON file in Application.persistentDataPath/UIToolbox/learned-words.json
WordCompleter.English.Store = new JsonWordStore();

The keyboard saves the words when it closes. Call Save() to save them at another time, and ForgetLearnedWords() to remove them, such as from a privacy option.

For a cloud save or your own save file, write an IWordStore:

public sealed class SaveGameWordStore : IWordStore
{
    public IReadOnlyDictionary<string, int> Load() => SaveGame.Current.LearnedWords;
    public void Save(IReadOnlyDictionary<string, int> words) => SaveGame.Current.LearnedWords = new(words);
}
Member Description
WordCompleter.English The US English completer.
WordCompleter.FromText(text), new WordCompleter(words) A completer from another list. A "# n" line starts section n: the words of a lower section come first.
Complete(prefix, max) Up to max words that start with the prefix.
Names The names that come first.
Learn(word), LearnedWords Counts a use of a word, and the learned words with their counts. A word with fewer than two letters, or with a digit, is not learned.
Store, Save(), ForgetLearnedWords() Keep, save and remove the learned words. A store error is logged as a warning.

Layouts

A KeyboardLayout is the keys of the keyboard as text. Make one with Create > UI Toolbox > Keyboard Layout and set it on the layout attribute, or make one in code with KeyboardLayout.FromText.

[letters ABC]
q w e r t y u i o p
a s d f g h j k l
{shift*1.5} z x c v b n m {backspace*1.5}
{>symbols*1.5} {left} , {space*4} . {right} {done*1.5}
[symbols ?123]
1 2 3 4 5 6 7 8 9 0
...
// The layout of all letter fields, or of one kind
keyboard.Layout = germanLayout;
keyboard.SetLayout(TextFieldKind.Number, phonePad);

KeyboardLayout.Default(kind) gives the built-in US QWERTY layouts.

Platform keyboards

On a console or a Steam Deck, the platform has its own keyboard. Set OnScreenKeyboard.PlatformKeyboard to use it. When its TryOpen returns true, it opens in place of the on-screen keyboard. When it returns false, the on-screen keyboard opens.

public sealed class SteamKeyboard : IPlatformKeyboard
{
    public bool TryOpen(string text, TextFieldKind kind, int maxLength, Action<string?> done)
    {
        if (!SteamUtils.IsSteamRunningOnSteamDeck()) return false;
        // Your call to SteamUtils.ShowGamepadTextInput. Its dismissed callback calls done with the new text, or with null on a cancel.
        return ShowSteamTextInput(text, kind == TextFieldKind.Password, maxLength, done);
    }
}

OnScreenKeyboard.PlatformKeyboard = new SteamKeyboard();

The keyboard sets the value of a text field to the new text. A number field gets the text as typed keys, and commits it.

Events and members

Member Description
Open(field), Close(), IsOpen Open the keyboard for a text field, close it, and whether it is open. Open throws an ArgumentException for an element that is not a text field.
Target, Kind The field and its kind.
MaxSuggestions The maximum number of suggestions. Default 3.
KeyPressed A key was pressed: the id of a special key, such as "shift", or the text of the key.
Submitted The player pressed done in the field.
Closed The keyboard closed.
OnScreenKeyboard.KindOf(field) The kind of a field.

Styling

Class Element
tb-osk The keyboard.
tb-osk__suggestions, tb-osk__suggestion The suggestion row and a suggestion.
tb-osk__suggestion--chosen The suggestion that the right stick chose.
tb-osk__keys, tb-osk__row, tb-osk__key The key rows, a row and a key.
tb-osk__key--current The key or suggestion that A presses.
tb-osk__key--glyph, tb-osk__key--page A key with a PromptFont glyph, such as shift, and a key that opens a page.
tb-osk__key--shift, --backspace, --space, --left, --right, --done The special keys.
tb-osk__gap An empty space in a row.
tb-osk--shift Shift is on.
tb-osk--no-suggestions The field gets no suggestions. The suggestion row hides.
Variable Default Use
--tb-osk-background --tb-color-surface The keyboard background.
--tb-osk-key --tb-color-surface-alt A key.
--tb-osk-key-hover --tb-color-surface-hover A key under the pointer.
--tb-osk-key-special --tb-color-surface-hover A special key.
--tb-osk-key-text --tb-color-text The text of the keys.
--tb-osk-current --tb-color-accent The current key, and the shift key when shift is on.
--tb-osk-current-text --tb-color-accent-text The text of the current key.
--tb-osk-key-height 44px The height of a key.
--tb-osk-max-width 880px The maximum width of the rows.

The variables are set on .tb-osk. Set them in a rule for .tb-osk in a style sheet that loads after the Toolbox sheet.