Rusty_tui/input_box.rs
1// inputBox.rs
2
3use std::io::{self, Read, Write}; // Importing necessary modules for input/output operations
4
5/// A structure representing an input box that allows the user to enter text.
6pub struct InputBox {
7 pub input: String, // The text entered by the user
8 pub placeholder: String, // A placeholder text to display when input is empty
9 pub x: u16, // The x-coordinate (horizontal position) where the input box will be drawn
10 pub y: u16, // The y-coordinate (vertical position) where the input box will be drawn
11}
12
13impl InputBox {
14 /// Creates a new InputBox instance.
15 ///
16 /// # Arguments
17 ///
18 /// * `input` - A string slice that holds the initial text of the input box.
19 /// * `placeholder` - A string slice that holds the placeholder text to display.
20 /// * `x` - The horizontal position (x-coordinate) where the input box will be drawn.
21 /// * `y` - The vertical position (y-coordinate) where the input box will be drawn.
22 ///
23 /// # Returns
24 ///
25 /// A new instance of `InputBox`.
26 pub fn new(input: &str, placeholder: &str, x: u16, y: u16) -> Self {
27 InputBox {
28 input: input.to_string(), // Convert the input string slice into a String
29 placeholder: placeholder.to_string(), // Convert the placeholder string slice into a String
30 x, // Set the x-coordinate
31 y, // Set the y-coordinate
32 }
33 }
34
35 /// Retrieves input from the user and updates the input box.
36 ///
37 /// This function displays the input box at the specified position and handles user input,
38 /// including entering characters and using the backspace key.
39 ///
40 /// # Returns
41 ///
42 /// An `io::Result<String>` that contains the input entered by the user or an error if
43 /// the read operation fails.
44 ///
45 /// # Example
46 ///
47 /// ```
48 /// let mut input_box = InputBox::new("", "Enter text here", 5, 10);
49 /// let user_input = input_box.get_input().unwrap(); // Gets user input
50 /// ```
51 pub fn get_input(&mut self) -> io::Result<String> {
52 let mut stdout = io::stdout(); // Handle to standard output
53 let mut stdin = io::stdin(); // Handle to standard input
54
55 // Move the cursor to the specified (x, y) position
56 print!("\x1B[{};{}H", self.y + 1, self.x + 1);
57 stdout.flush()?;
58
59 // Display the placeholder if input is empty
60 if self.input.is_empty() {
61 print!("{}", self.placeholder);
62 } else {
63 print!("{}", self.input);
64 }
65 stdout.flush()?;
66
67 // Read input from the user
68 let mut buffer = [0; 1]; // Buffer to hold a single byte of input
69 loop {
70 stdin.read_exact(&mut buffer)?; // Read a single byte
71 match buffer[0] {
72 b'\n' => break, // Break the loop on Enter key
73 b'\x08' | b'\x7F' => {
74 // Handle Backspace key (ASCII codes for backspace)
75 if !self.input.is_empty() {
76 self.input.pop(); // Remove last character from input
77 // Move cursor back and clear the character
78 print!("\x1B[1D \x1B[1D"); // Move cursor left and overwrite with space
79 }
80 }
81 c => {
82 self.input.push(c as char); // Append character to input
83 print!("{}", c as char); // Print the character
84 }
85 }
86 stdout.flush()?; // Flush the output to display the input in real-time
87 }
88
89 Ok(self.input.clone()) // Return the input string
90 }
91}