widgets
@profile(t2);
import ui from "ui";
import widgets from "widgets";
var volume: i64 = 50;
fn on_save() { }
fn on_volume(v: i64) { volume = v; }
component Settings {
view {
ui.Column {
widgets.Label { text: "Volume"; fg: #FFFFFF; }
widgets.Slider { min_val: 0; max_val: 100; value: 50; on_change: on_volume; }
widgets.Button { label: "Save"; bg: #368CE2; on_click: on_save; }
}
}
}Every widget also takes width, height and grow, its size in a
ui.Column or ui.Row (Column and Row). With
grow: 0 a widget takes its own size: a Label its text’s, a Button
its label’s, a Checkbox its box and label, a TextInput its text’s (at
least 80 pixels), an Image its picture’s, a Slider 120 x 20 and a
ProgressBar 120 x 8.
Every prop has a default: leave a color at its zero value (#00000000),
or a size at 0, and the widget paints it with the active theme,
which theme.set can switch while the program runs. To set props for
many widgets at once, write a #style rule.
| Widget | Props | Events |
|---|---|---|
Label | text: string, fg, size (default: the theme’s, 14) | |
Button | label: string, bg (set: a colored button in that color), fg, border, text_size; states hovered, active, disabled | on_click() |
TextInput | value: string, placeholder: string, bg, fg, border_color, text_size; states hovered, focused | on_change(value: []const u8), on_submit(value: []const u8) |
Checkbox | checked: bool, label: string, text_color, check_color, text_size; states hovered, active | on_toggle(new_checked: bool) |
Slider | min_val, max_val, value, bg, track_color, thumb_color; states hovered, active | on_change(new_value: i64) |
ProgressBar | value, max_value (default 100), bg, fill_color | |
Panel | bg, border | |
Scrollable | direction: ScrollDir, content_w, content_h | |
Image | src: *gfx.Surface (from image), bg |
The look of a state
Each color prop of a widget with states has a variant per state, named
<state>_<prop>: the color while that state is on. Left at zero, the
theme’s look for that state is used.
| Widget | State props |
|---|---|
Button | hovered_bg, hovered_fg, hovered_border, active_bg, active_fg, active_border (the ring while pressed), disabled_bg, disabled_fg, disabled_border |
TextInput | hovered_bg, hovered_fg, hovered_border_color, focused_bg, focused_fg, focused_border_color |
Checkbox | hovered_text_color, hovered_check_color, active_text_color, active_check_color |
Slider | hovered_bg, hovered_track_color, hovered_thumb_color, active_bg, active_track_color, active_thumb_color |
widgets.Button { label: "Delete"; bg: #B03030; hovered_bg: #C04040; active_bg: #902020; }With transition: 150 (milliseconds) a widget fades to a state’s
colors instead of switching, along transition_ease
(widget transitions).
When two states are on, the stronger one shows: disabled over
active (pressed) over hovered, and focused over hovered. In a
#style rule the same is written
:hovered { bg: #C04040; }.
- A
Buttonfireson_clickwhen pressed and released inside it. - A
TextInputtakes focus when clicked; it edits with the arrow keys, Home, End, Backspace and Delete (Shift selects), fireson_changeafter each edit andon_submiton Return. The text it hands over is valid during the handler: copy it ("{value}") to keep it. - Its
valueprop is the text to show. Bound to avarwhose generated setteron_changecalls, the field is controlled:widgets.TextInput { value: query; on_change: set_query; }keepsqueryand the field in step. Whenvaluechanges from outside (code assignsquery), the field adopts the new text and keeps the caret, clamped to the new length. Inside the component,text()is the text being edited. CheckboxandSliderreport what the user asked for and leave the value to you: store it and pass it back as the prop.
Test a form without a window with ui.headless.
Last modified: