osui::elements::input
The Input element provides a basic interactive text input field for your OSUI applications. It allows users to type, backspace, delete characters, and move the cursor within the input area.
Input Struct
pub struct Input {
pub state: State<String>, // Reactive state holding the input string
cursor: usize, // Current cursor position within the string
}
Associated Methods
Input::new() -> Self
Creates a new Input instance with an empty String for its state and the cursor at position 0.
Example:
use osui::prelude::*;
let my_input = Input::new();
Element Trait Implementation
render(&mut self, scope: &mut RenderScope, render_context: &RenderContext)
This method is responsible for drawing the input field's current text and the cursor.
- It retrieves the current string from
self.state. - It calls
scope.draw_text(0, 0, &s)to render the entire input string. - Cursor Rendering (Focus Indicator): If
render_context.is_focused()istrue(meaning thisInputwidget has keyboard focus), it draws an "inverted" character at the currentself.cursorposition. If the cursor is at the end of the string, it draws an inverted space. This visually indicates where the user is typing.
event(&mut self, event: &dyn Event)
This method handles incoming crossterm::event::Events, specifically keyboard input, when the Input widget is focused.
It checks if the event is a KeyEvent and if modifiers (other than Shift) are present, it ignores the event to prevent unintended actions (e.g., Ctrl+C).
It then matches on KeyCode:
KeyCode::Char(c): Inserts the charactercat thecursorposition in thestatestring and incrementscursor.KeyCode::Backspace: Ifcursor > 0, removes the character before the cursor and decrementscursor.KeyCode::Delete: Ifcursoris not at the end of the string, removes the character at thecursorposition.KeyCode::Left: Movescursorone position to the left (if not already at0).KeyCode::Right: Movescursorone position to the right (if not already at the end of the string). After any modification, theInput'sstateis automatically marked as changed (due toDerefMutonState::get()), triggering a re-render.
as_any(&self) -> &dyn std::any::Any / as_any_mut(&mut self) -> &mut dyn std::any::Any
Standard implementations for downcasting.
Usage in rsx!
The Input element needs to be part of the widget tree. For it to receive keyboard input, it must be the focused widget. You typically achieve this using the Focused component (provided by RelativeFocusExtension).
use osui::prelude::*;
fn main() -> std::io::Result<()> {
let screen = Screen::new();
screen.extension(InputExtension); // Essential for keyboard input
screen.extension(RelativeFocusExtension::new()); // Manages focus
rsx! {
FlexCol, gap: 1, {
"Username:"
@Transform::new().dimensions(30, 1).padding(1, 0); // Give it some padding
@Style { background: Background::Outline(0xAAAAAA), foreground: Some(0xFFFFFF) };
@Focused; // This input will be focused by default
Input { }
"Password:"
@Transform::new().dimensions(30, 1).padding(1, 0);
@Style { background: Background::RoundedOutline(0xAAAAAA), foreground: Some(0xFFFFFF) };
Input { } // This input will only be focused via navigation (e.g., Shift+Down arrow)
}
}
.draw(&screen);
screen.run()
}
Accessing Input Value:
The Input element manages its own State<String>. If you need to access the typed value from another part of your application (e.g., when a submit button is pressed), you would typically:
- Inject your own
State<String>: Instead ofInput { }, you could modifyInput::new()or create a customInputvariant that takes an externalState<String>to bind to. - Get component by ID: If using
IdExtension, you could assign anIdto theInputwidget, then later retrieve theArc<Widget>by ID and callwidget.get::<Input>()to access itsstatefield.
The Input element provides a crucial interactive component for building forms and dynamic data entry in your TUI.