text input¶
the text-entry blob wraps the engine text field. it is the one foundation widget that holds text the user types, so it comes in two flavors: uncontrolled, where the entry remembers its own text, and controlled, where your code owns the text and the entry mirrors it.
write it as Goo.TextEntry. the engine also has a Sandbox.UI.TextEntry, so the namespace keeps the two apart.
uncontrolled: the entry owns its text¶
the simplest entry seeds itself once with InitialText and then keeps its own text as the user types. add a Placeholder for the empty-state hint.
new Goo.TextEntry { InitialText = "type me", Placeholder = "search" }
you read the result through OnSubmit, which fires when the user presses enter, or OnChange, which fires on every keystroke. both hand you the current string.
controlled: your code owns the text¶
bind Value to a field and update that field from OnChange. your field is then always the latest text, ready to read anywhere else in Build.
string _value = "";
protected override Container Build() => new Container
{
Children =
{
new Goo.TextEntry
{
Value = _value,
Placeholder = "controlled",
OnChange = v => _value = v,
OnSubmit = v => Log.Info($"submitted: {v}"),
},
},
};
set Value or InitialText, never both. Value means controlled, InitialText means uncontrolled. setting both is ambiguous and the framework flags it. the field-backed pattern here is the same state idea you used for the counter.
numeric entries¶
set Numeric to accept numbers only. MinValue and MaxValue clamp the range, NumberFormat controls how the value displays, and MaxLength caps how many characters fit.
new Goo.TextEntry
{
InitialText = "42.00",
Numeric = true,
MinValue = 0,
MaxValue = 100,
NumberFormat = "0.00",
MaxLength = 8,
}
disabled and multiline¶
Disabled makes an entry that cannot be focused or edited. pair it with a lower Opacity so it reads as inert.
new Goo.TextEntry { InitialText = "can't focus me", Disabled = true } with { Opacity = 0.5f }
Multiline lets the field hold more than one line. enter inserts a newline instead of submitting, so OnSubmit does not fire on a multiline entry.
new Goo.TextEntry { InitialText = "line one\nline two", Multiline = true }
focus, blur, and cancel¶
three more callbacks track the field's focus life. OnFocus fires when the entry gains focus, OnBlur fires when it loses focus and hands you the final text, and OnCancel fires when the user presses escape. use them for commit-on-click-out, focus-driven styling, or escape-to-abort.
new Goo.TextEntry
{
InitialText = "edit me",
OnFocus = () => Log.Info("focused"),
OnBlur = final => Log.Info($"left with: {final}"),
OnCancel = () => Log.Info("escaped"),
}
OnBlur fires on every focus loss, including the ones caused by submitting (enter) and cancelling (escape), which both blur the field before they fire their own callback. so if you wire OnSubmit and OnBlur together, both run on enter, with OnBlur first. branch on the more specific callback when you need to tell a plain click-out apart from a submit or a cancel.
styling¶
TextEntry carries the full container style surface, the richest facade of any blob: font, padding, border, background, radius, hover and focus colors, the lot. style it exactly as you would a container.
new Goo.TextEntry
{
InitialText = "type me",
FontSize = 18,
Padding = 12,
BorderRadius = 6,
BorderWidth = 1,
BorderColor = new Color(0.3f, 0.3f, 0.35f),
BackgroundColor = new Color(0.18f, 0.18f, 0.22f),
FontColor = new Color(0.95f, 0.95f, 0.97f),
Width = 320,
}
content reference¶
| property | type | notes |
|---|---|---|
| Value | string? | controlled text, bound to your field |
| InitialText | string? | uncontrolled seed text, applied once |
| Placeholder | string? | hint shown while empty |
| MaxLength | int? | cap on typed length |
| Disabled | bool | non-focusable, non-editable |
| Numeric | bool | accept numbers only |
| MinValue | float? | numeric clamp floor (with Numeric) |
| MaxValue | float? | numeric clamp ceiling (with Numeric) |
| NumberFormat | string? | numeric display format, e.g. "0.00" |
| Multiline | bool | allow newlines, suppresses OnSubmit on enter |
| Key | string? | stable identity across rebuilds |
events and key¶
TextEntry adds text and focus callbacks on top of the shared mouse events. for the full property surface see textentry reference.
| property | type | notes |
|---|---|---|
| OnChange | Action |
fires per keystroke with current text |
| OnSubmit | Action |
fires on enter, single-line only |
| OnFocus | Action? | fires when the entry gains focus |
| OnBlur | Action |
fires on focus loss with final text, also fires before submit and cancel |
| OnCancel | Action? | fires when the user presses escape |
| OnClick | Action |
shared mouse events, see events |
| OnMouseEnter | Action |
|
| OnMouseLeave | Action |
|
| OnMouseDown | Action |
|
| OnMouseUp | Action |
|
| OnMouseMove | Action |
see also¶
- your-first-counter - the state-in-a-field pattern a controlled entry builds on
- textentry reference - the full property surface for TextEntry
- container - the full style surface a TextEntry inherits
- events - the mouse event model and
MousePanelEventpayload