Skip to main content

TextInput

Struct TextInput 

Source
pub struct TextInput<'a> { /* private fields */ }
Expand description

A single-line editable text field: the stateless drawing half of TextInputState, the same split List has with ListState.

Draws state.value() (masked with mask if set, or placeholder while state.value() is empty), scrolled horizontally by state.scroll() and clipped to surface.area()’s width, with a caret cell at the cursor’s display column. Neither scrolling nor the caret’s column is byte- or char-based: both go through retroglyph_core::text::width_usize, the same display-width measurement truncate uses, so a value containing a double-width character (CJK, most emoji) still puts the caret in the right screen column.

This widget does not call TextInputState::ensure_visible: like List/ListState::ensure_visible, that’s the caller’s job, once per frame, with the actual current field width (which can change on resize).

The caret always renders as an inverted-color cell (caret_style), not by driving a real terminal cursor via a backend’s Cursor facet: render only has a Surface, not a Backend, and a cell-drawn caret renders identically (including in headless snapshot tests) on every backend. An app that wants a blinking, backend-native caret instead can position one itself from state.cursor()/state.scroll() alongside this widget.

As an InteractiveWidget, sense is Sense::click: a click (or Tab) focuses the field the same way it would a Button, via the shared Interaction’s FocusRing. Routing keystrokes to whichever field currently holds focus is still the app’s job, via TextInputState::handle_event: InteractiveWidget::render never sees raw input events, only the already-resolved Response, so it can’t do that itself. What Enter does, validation, and layout are the app’s job too. IME/text composition and multi-line editing are out of scope for this crate entirely.

§Examples

use retroglyph_core::grid::{Grid, Rect};
use retroglyph_ui::state::TextInputState;
use retroglyph_ui::widget::{StatefulWidget, TextInput};
use retroglyph_ui::Surface;

let mut state = TextInputState::new();
state.set_value("hello");

let area = Rect::new(0, 0, 10, 1);
let mut grid = Grid::new(10, 1);
TextInput::new().render(&mut Surface::new(&mut grid, area, 0), &mut state);

Implementations§

Source§

impl<'a> TextInput<'a>

Source

pub fn new() -> Self

An empty-placeholder, unmasked text input, styled from Theme::DARK (as if TextInput::theme had been called); call TextInput::theme/TextInput::theme_on for a different Theme.

Source

pub const fn placeholder(self, placeholder: &'a str) -> Self

Text shown, in placeholder_style, when state.value() is empty.

Source

pub const fn mask(self, mask: char) -> Self

Render every character of state.value() as mask instead of its real glyph, e.g. '*' for a password field. Column math (scrolling, caret position) still uses the real value’s display width, not the mask’s: masking only ever substitutes one fixed-width glyph, so this is exact as long as mask itself is a single-column character.

Source

pub const fn style(self, style: Style) -> Self

Set the style of the value/placeholder text (placeholder uses placeholder_style instead of this while shown).

Source

pub const fn placeholder_style(self, style: Style) -> Self

Set the style of the placeholder text, shown in place of the value while it’s empty.

Source

pub const fn caret_style(self, style: Style) -> Self

Set the style of the caret cell.

Source

pub fn theme(self, theme: Theme) -> Self

Applies theme’s named roles: style becomes theme.fg on theme.panel_bg, placeholder_style becomes theme.dim on the same background, and caret_style becomes theme.bg on theme.accent. See List::theme for why an explicit background is baked in rather than left unset.

Source

pub fn theme_on(self, theme: Theme, bg: Color) -> Self

Same as TextInput::theme, but text is drawn on bg instead of theme.panel_bg.

Trait Implementations§

Source§

impl<'a> Clone for TextInput<'a>

Source§

fn clone(&self) -> TextInput<'a>

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<'a> Copy for TextInput<'a>

Source§

impl<'a> Debug for TextInput<'a>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for TextInput<'_>

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl<Id> InteractiveWidget<Id> for TextInput<'_>

Source§

fn sense(&self) -> Sense

Sense::click, the same as Button/List: a click focuses the field (and joins the shared Interaction’s Tab order) via Sense::FOCUSABLE, which Sense::click already includes. This impl’s render still never reads response: routing keystrokes to whichever field holds focus, and calling TextInputState::handle_event on it, is the caller’s job, the same as List leaves arrow-key row navigation to the caller.

Source§

type State = TextInputState

State that outlives one render call, e.g. a selection index or scroll offset. () for widgets that have none.
Source§

fn render( &self, surface: &mut Surface<'_>, state: &mut Self::State, _response: Response<Id>, )

Draw into surface, styled by response, which the caller already resolved (via Interaction::interact) for surface.area() and sense.
Source§

impl MinSize for TextInput<'_>

Source§

fn min_size(&self, density: Density) -> Size

placeholder’s display width (0 with no placeholder set) plus 2 columns of padding on each side, matching Button’s own padding, one row tall, floored at density’s min_target_size so an empty field still claims a usable click/tap target.

Source§

impl StatefulWidget for TextInput<'_>

Source§

type State = TextInputState

The externally owned state this widget reads and/or updates while rendering.
Source§

fn render(&self, surface: &mut Surface<'_>, state: &mut Self::State)

Draw this widget into surface, filling surface.area(), using and/or updating state. Read more

Auto Trait Implementations§

§

impl<'a> Freeze for TextInput<'a>

§

impl<'a> RefUnwindSafe for TextInput<'a>

§

impl<'a> Send for TextInput<'a>

§

impl<'a> Sync for TextInput<'a>

§

impl<'a> Unpin for TextInput<'a>

§

impl<'a> UnsafeUnpin for TextInput<'a>

§

impl<'a> UnwindSafe for TextInput<'a>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<C> WithAlpha for C
where C: Copy,

§

fn with_alpha_first<A>(self, alpha: A) -> AlphaFirst<A, Self>

Wraps self with alpha, storing alpha before the color in memory (see [AlphaFirst]).
§

fn with_alpha_last<A>(self, alpha: A) -> AlphaLast<A, Self>

Wraps self with alpha, storing alpha after the color in memory (see [AlphaLast]).