Skip to main content

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}