diff --git a/Cargo.toml b/Cargo.toml index aacb9af..42b62e9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -99,6 +99,10 @@ required-features = ["ratatui-crossterm", "search"] name = "ratatui_termion" required-features = ["ratatui-termion"] +[[example]] +name = "termwiz" +required-features = ["ratatui-termwiz"] + [workspace] members = [ "bench", diff --git a/examples/termwiz.rs b/examples/termwiz.rs new file mode 100644 index 0000000..eade9a3 --- /dev/null +++ b/examples/termwiz.rs @@ -0,0 +1,67 @@ +use ratatui::backend::TermwizBackend; +use ratatui::widgets::{Block, Borders}; +use ratatui::Terminal; +use std::error::Error; +use std::time::{Duration, Instant}; +use termwiz::input::InputEvent; +use termwiz::terminal::Terminal as TermwizTerminal; +use tui_textarea::{Input, Key, TextArea}; + +const TICK_RATE: Duration = Duration::from_millis(100); + +fn main() -> Result<(), Box> { + let backend = TermwizBackend::new()?; + let mut term = Terminal::new(backend)?; + term.hide_cursor()?; + + let mut textarea = TextArea::default(); + textarea.set_block( + Block::default() + .borders(Borders::ALL) + .title("Termwiz Minimal Example"), + ); + let mut last_tick = Instant::now(); + + // The event loop + loop { + term.draw(|f| { + let widget = textarea.widget(); + f.render_widget(widget, f.size()); + })?; + + let timeout = TICK_RATE + .checked_sub(last_tick.elapsed()) + .unwrap_or_else(|| Duration::from_secs(0)); + + if let Some(input) = term + .backend_mut() + .buffered_terminal_mut() + .terminal() + .poll_input(Some(timeout))? + { + if let InputEvent::Resized { cols, rows } = input { + term.backend_mut() + .buffered_terminal_mut() + .resize(cols, rows); + } else { + match input.into() { + Input { key: Key::Esc, .. } => break, + input => { + textarea.input(input); + } + } + } + } + + if last_tick.elapsed() >= TICK_RATE { + last_tick = Instant::now(); + } + } + + term.show_cursor()?; + term.flush()?; + drop(term); // Leave terminal raw mode to print the following line + + println!("Lines: {:?}", textarea.lines()); + Ok(()) +} diff --git a/src/input.rs b/src/input.rs index 439e5a3..b858fc5 100644 --- a/src/input.rs +++ b/src/input.rs @@ -9,8 +9,8 @@ use arbitrary::Arbitrary; use termion::event::{Event as TermionEvent, Key as TermionKey, MouseEvent as TermionMouseEvent}; #[cfg(feature = "ratatui-termwiz")] use termwiz::input::{ - InputEvent as TermwizInputEvent, KeyEvent as TermwizKeyEvent, MouseEvent as TermwizMouseEvent, - PixelMouseEvent, + InputEvent as TermwizInputEvent, KeyEvent as TermwizKeyEvent, + MouseButtons as TermwizMouseButtons, MouseEvent as TermwizMouseEvent, PixelMouseEvent, }; /// Backend-agnostic key input kind. @@ -269,26 +269,34 @@ impl From for Input { } } +#[cfg(feature = "ratatui-termwiz")] +impl From for Key { + /// Convert [`termwiz::input::MouseButtons`] to [`Key`]. + fn from(buttons: TermwizMouseButtons) -> Self { + if buttons.contains(TermwizMouseButtons::VERT_WHEEL) { + if buttons.contains(TermwizMouseButtons::WHEEL_POSITIVE) { + Key::MouseScrollUp + } else { + Key::MouseScrollDown + } + } else { + Key::Null + } + } +} + #[cfg(feature = "ratatui-termwiz")] impl From for Input { /// Convert [`termwiz::input::MouseEvent`] to [`Input`]. fn from(mouse: TermwizMouseEvent) -> Self { - use termwiz::input::{Modifiers, MouseButtons}; + use termwiz::input::Modifiers; let TermwizMouseEvent { mouse_buttons, modifiers, .. } = mouse; - let key = if mouse_buttons.contains(MouseButtons::VERT_WHEEL) { - if mouse_buttons.contains(MouseButtons::WHEEL_POSITIVE) { - Key::MouseScrollDown - } else { - Key::MouseScrollUp - } - } else { - Key::Null - }; + let key = Key::from(mouse_buttons); let ctrl = modifiers.contains(Modifiers::CTRL); let alt = modifiers.contains(Modifiers::ALT); @@ -300,22 +308,14 @@ impl From for Input { impl From for Input { /// Convert [`termwiz::input::PixelMouseEvent`] to [`Input`]. fn from(mouse: PixelMouseEvent) -> Self { - use termwiz::input::{Modifiers, MouseButtons}; + use termwiz::input::Modifiers; let PixelMouseEvent { mouse_buttons, modifiers, .. } = mouse; - let key = if mouse_buttons.contains(MouseButtons::VERT_WHEEL) { - if mouse_buttons.contains(MouseButtons::WHEEL_POSITIVE) { - Key::MouseScrollDown - } else { - Key::MouseScrollUp - } - } else { - Key::Null - }; + let key = Key::from(mouse_buttons); let ctrl = modifiers.contains(Modifiers::CTRL); let alt = modifiers.contains(Modifiers::ALT);