rustic_rs/commands/tui/widgets/
text_input.rs1use super::{Draw, Event, Frame, KeyCode, KeyEvent, ProcessEvent, Rect, SizedWidget, Style};
2
3use crossterm::event::KeyModifiers;
4use tui_textarea::{CursorMove, TextArea};
5
6pub struct TextInput {
7 textarea: TextArea<'static>,
8 lines: u16,
9 changeable: bool,
10}
11
12pub enum TextInputResult {
13 Cancel,
14 Input(String),
15 None,
16}
17
18impl TextInput {
19 pub fn new(text: Option<&str>, initial: &str, lines: u16, changeable: bool) -> Self {
20 let mut textarea = TextArea::default();
21 textarea.set_style(Style::default());
22 if let Some(text) = text {
23 textarea.set_placeholder_text(text);
24 }
25 _ = textarea.insert_str(initial);
26 if !changeable {
27 textarea.move_cursor(CursorMove::Top);
28 }
29 Self {
30 textarea,
31 lines,
32 changeable,
33 }
34 }
35}
36
37impl SizedWidget for TextInput {
38 fn height(&self) -> Option<u16> {
39 Some(self.lines)
40 }
41}
42
43impl Draw for TextInput {
44 fn draw(&mut self, area: Rect, f: &mut Frame<'_>) {
45 f.render_widget(&self.textarea, area);
46 }
47}
48
49impl ProcessEvent for TextInput {
50 type Result = TextInputResult;
51 fn input(&mut self, event: Event) -> TextInputResult {
52 if let Event::Key(key) = event {
53 let KeyEvent {
54 code, modifiers, ..
55 } = key;
56 if self.changeable {
57 match (code, modifiers) {
58 (KeyCode::Esc, _) => return TextInputResult::Cancel,
59 (KeyCode::Enter, _) if self.lines == 1 => {
60 return TextInputResult::Input(self.textarea.lines().join("\n"));
61 }
62 (KeyCode::Char('s'), KeyModifiers::CONTROL) => {
63 return TextInputResult::Input(self.textarea.lines().join("\n"));
64 }
65 _ => {
66 _ = self.textarea.input(event);
67 }
68 }
69 } else {
70 match (code, modifiers) {
71 (KeyCode::Esc | KeyCode::Enter | KeyCode::Char('q' | 'x'), _) => {
72 return TextInputResult::Cancel;
73 }
74 (KeyCode::Home, _) => {
75 self.textarea.move_cursor(CursorMove::Top);
76 }
77 (KeyCode::End, _) => {
78 self.textarea.move_cursor(CursorMove::Bottom);
79 }
80 (KeyCode::PageDown | KeyCode::PageUp | KeyCode::Up | KeyCode::Down, _) => {
81 _ = self.textarea.input(key);
82 }
83 _ => {}
84 }
85 }
86 }
87 TextInputResult::None
88 }
89}