-
Notifications
You must be signed in to change notification settings - Fork 0
TextInput
Wire name textinput · Go type trinkets.TextInput · Renders on terminal and graphical
A single-line editable text field. It owns a caret, a selection, an undo-free edit model, clipboard actions with a right-click menu, and input-method composition; it is the trinket a text-entry keystroke is delivered to.
new textinput placeholder="Search…"
w=new window title="Find" width=360 height=120 children={
p=new panel layout=vbox spacing=0 children={
new label caption="Find what:"
q=new textinput placeholder="type to search"
new button caption="Find" default action=find.go
}
}
query=w.p.q
q := ui.TextInput("query")
q.OnChange(func(s string) { /* every edit, with the new text */ })
q.SetText("initial")Set at construction, or later with set.
| Property | Type | Default | Meaning |
|---|---|---|---|
text |
string | "" |
The editable content. Server-authoritative — see Who owns the text. |
placeholder |
string | "" |
Shown, dimmed, only while text is empty. |
Plus the common properties every trinket carries:
enabled visible name min_width min_height max_width max_height
column_units row_units font acc_name stretch align fg bg.
A live host answers for itself.
conn.Describe()returns the running service's property registry, with types, defaults and tips, which is the authority if this table and your build disagree.
| Event | Fields | Fires |
|---|---|---|
change |
trinket (uint), text (string) |
After every edit that alters the content — a typed character, a deletion, a paste, a committed composition. Not on caret movement or selection changes. |
change does not fire for a set text=… from the client; only user edits
are reported, so a write-through cannot echo back and loop.
Go
q := ui.TextInput("query") // handle, subscribed to "change"
q.Text() // the client-side replica's text
q.SetText("hello") // writes through to replica and display
q.OnChange(func(s string) { … })Python
q = ui.text_input("query")
q.text()
q.set_text("hello")
q.on_change(lambda s: ...)C
uint64_t q = kt_ui_id(ui, "query");
kt_set(conn, q, "text=\"hello\"");
kt_on(conn, q, "change", on_change, NULL);
/* inside on_change: const char *s = kt_event_text(ev, "text"); */Each client keeps a replica of the text so Text() is a local read rather
than a round trip. SetText updates the replica and sends the property in one
call; incoming change events update it before your handler runs.
Bindings come from the keymap, so a host or application can rebind any of
them; these are the defaults. ^X is Control-X, M- is Mega, s- is Super,
S- is Shift.
| Key | Does |
|---|---|
Left Right
|
Move the caret; collapse a selection if one is up. |
S-Left S-Right
|
Extend the selection by one character. |
Home End
|
Caret to start / end. |
S-Home S-End
|
Select to start / end. |
^A |
The Emacs home cycle: at the start with nothing selected, select all and put the caret at the end; otherwise, go to the start. |
^E |
Caret to end. |
Backspace, Delete
|
Erase behind the caret, or the selection. |
FDel |
Erase ahead of the caret. |
^U |
Clear the field. |
M-a, s-a (macOS) |
Select all. |
^X ^C ^V
|
Cut, copy, paste. |
Return |
Fires the field's activate handler — the "submit" gesture. Does not insert. |
Anything that types a character inserts it, replacing the selection if there is one. Which chords type is the host's answer, not this trinket's: a chord the host watched is settled by what it observed the keyboard produce, including observing that it produced nothing (a dead key arming an accent). Where there is no host to ask — the terminal backend — a one-character key name is the character.
| Gesture | Does |
|---|---|
| Click | Place the caret, take focus. |
| Shift-click | Extend the selection to the click. |
| Double-click | Select the word under the pointer. |
| Triple-click | Select all. |
| Drag | Extend the selection; past either edge it auto-scrolls, and keeps scrolling while the pointer is held still out there, faster the further out it is. |
| Right-click | Context menu: Cut, Copy, Paste, — , Select All. |
The multi-click run is 400 ms between clicks; a slower click restarts it.
The display service holds the text and is the authority on it. A client's
Text() reads a replica kept in step by change events, so it is current
as of the last event delivered — not a synchronous read of the field. Two
clients driving the same field see the same content because both are mirroring
the same server-side value.
An input method's in-flight composition is painted at the caret, underlined
and in the caret's colour, and is not in text — it enters only when the
platform commits it, at which point it arrives as ordinary typed input and
raises one change. Dead keys, preedit spans and press-and-hold character
palettes all resolve through this path on both surfaces. A read-only or
disabled field declines the composition rather than showing it somewhere it
could never land.
The caret blinks, and any keystroke or click makes it immediately visible so it never appears to swallow input during its dark phase. On the terminal surface the field asks the platform for the real hardware caret, so the outer terminal's own cursor sits where the text will go — which is also what a screen reader and an OS input method follow.
Role TextInput, or PasswordInput when the echo mode hides the content.
The value is exposed; read-only and disabled are reported as states. Set
acc_name where the visible label is not adjacent.
The default size hint is 20 characters wide by one row tall, measured in the
field's effective font — so it is 20 characters at any font size, not a fixed
pixel box. It is an inline trinket, so a vertical box layout gives it
horizontal margins. Constrain it with min_width / max_width or let
stretch take the row.
These exist on the Go type and have no protocol property yet. In-process applications can use them; protocol clients cannot.
| Go | Does |
|---|---|
SetReadOnly(bool) |
Field displays and selects but does not edit. |
SetMaxLength(int) |
Cap the content length; -1 is unlimited. |
SetEchoMode(EchoMode) |
EchoNormal, EchoPassword, EchoPasswordOnEdit, EchoNoEcho. |
SetCursorPosition(int) / CursorPosition()
|
Caret index. |
SelectAll(), ClearSelection(), SelectedText(), HasSelection()
|
Selection. |
SetOnReturnPressed(func()) |
The activate handler Return fires. |
Copy(), Cut(), Paste()
|
The clipboard actions the context menu calls. |
They are interaction state rather than construction state, which is why they
are queued behind the set verb and event slices rather than being added as
build-time properties.
Common Properties · Editor — multi-line · ComboBox — a text field with a list · Properties and Values · Events
KittyTK — image/tty Trinket Kit · MIT licensed · alpha, 0.1.x
Repository · Issues · Support on ko-fi
Sibling projects: PurfecTerm (terminal emulator) · mew (text editor) · PawScript (language)
Getting Started
Installation Building from Source Running a Display Host Your First Application Examples
Protocol
Protocol Overview Object Model Properties and Values Events Templates and Aliases Common Properties Introspection Transports and Security
Clients
Go Client Python Client C Client
Application Objects
Application · MenuBar · Window · MessageBox
Output Trinkets
Label · ProgressBar · StatusBar
Input Trinkets
TextInput · Editor · Terminal
Button · CheckBox · RadioButton
ListView · ComboBox · TreeView
Layout Trinkets
TabTrinket · Panel
ScrollArea · MDIPane
Separator · Spacer · Splitter
Other Trinkets
Layout Helpers