зеркало из
https://github.com/glebtv/tui-textarea.git
synced 2026-09-08 00:15:50 +03:00
add example for usage with termwiz crate
Этот коммит содержится в:
@@ -99,6 +99,10 @@ required-features = ["ratatui-crossterm", "search"]
|
|||||||
name = "ratatui_termion"
|
name = "ratatui_termion"
|
||||||
required-features = ["ratatui-termion"]
|
required-features = ["ratatui-termion"]
|
||||||
|
|
||||||
|
[[example]]
|
||||||
|
name = "termwiz"
|
||||||
|
required-features = ["ratatui-termwiz"]
|
||||||
|
|
||||||
[workspace]
|
[workspace]
|
||||||
members = [
|
members = [
|
||||||
"bench",
|
"bench",
|
||||||
|
|||||||
67
examples/termwiz.rs
Обычный файл
67
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<dyn Error>> {
|
||||||
|
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(())
|
||||||
|
}
|
||||||
44
src/input.rs
44
src/input.rs
@@ -9,8 +9,8 @@ use arbitrary::Arbitrary;
|
|||||||
use termion::event::{Event as TermionEvent, Key as TermionKey, MouseEvent as TermionMouseEvent};
|
use termion::event::{Event as TermionEvent, Key as TermionKey, MouseEvent as TermionMouseEvent};
|
||||||
#[cfg(feature = "ratatui-termwiz")]
|
#[cfg(feature = "ratatui-termwiz")]
|
||||||
use termwiz::input::{
|
use termwiz::input::{
|
||||||
InputEvent as TermwizInputEvent, KeyEvent as TermwizKeyEvent, MouseEvent as TermwizMouseEvent,
|
InputEvent as TermwizInputEvent, KeyEvent as TermwizKeyEvent,
|
||||||
PixelMouseEvent,
|
MouseButtons as TermwizMouseButtons, MouseEvent as TermwizMouseEvent, PixelMouseEvent,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Backend-agnostic key input kind.
|
/// Backend-agnostic key input kind.
|
||||||
@@ -269,26 +269,34 @@ impl From<TermwizKeyEvent> for Input {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "ratatui-termwiz")]
|
||||||
|
impl From<TermwizMouseButtons> 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")]
|
#[cfg(feature = "ratatui-termwiz")]
|
||||||
impl From<TermwizMouseEvent> for Input {
|
impl From<TermwizMouseEvent> for Input {
|
||||||
/// Convert [`termwiz::input::MouseEvent`] to [`Input`].
|
/// Convert [`termwiz::input::MouseEvent`] to [`Input`].
|
||||||
fn from(mouse: TermwizMouseEvent) -> Self {
|
fn from(mouse: TermwizMouseEvent) -> Self {
|
||||||
use termwiz::input::{Modifiers, MouseButtons};
|
use termwiz::input::Modifiers;
|
||||||
|
|
||||||
let TermwizMouseEvent {
|
let TermwizMouseEvent {
|
||||||
mouse_buttons,
|
mouse_buttons,
|
||||||
modifiers,
|
modifiers,
|
||||||
..
|
..
|
||||||
} = mouse;
|
} = mouse;
|
||||||
let key = if mouse_buttons.contains(MouseButtons::VERT_WHEEL) {
|
let key = Key::from(mouse_buttons);
|
||||||
if mouse_buttons.contains(MouseButtons::WHEEL_POSITIVE) {
|
|
||||||
Key::MouseScrollDown
|
|
||||||
} else {
|
|
||||||
Key::MouseScrollUp
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Key::Null
|
|
||||||
};
|
|
||||||
let ctrl = modifiers.contains(Modifiers::CTRL);
|
let ctrl = modifiers.contains(Modifiers::CTRL);
|
||||||
let alt = modifiers.contains(Modifiers::ALT);
|
let alt = modifiers.contains(Modifiers::ALT);
|
||||||
|
|
||||||
@@ -300,22 +308,14 @@ impl From<TermwizMouseEvent> for Input {
|
|||||||
impl From<PixelMouseEvent> for Input {
|
impl From<PixelMouseEvent> for Input {
|
||||||
/// Convert [`termwiz::input::PixelMouseEvent`] to [`Input`].
|
/// Convert [`termwiz::input::PixelMouseEvent`] to [`Input`].
|
||||||
fn from(mouse: PixelMouseEvent) -> Self {
|
fn from(mouse: PixelMouseEvent) -> Self {
|
||||||
use termwiz::input::{Modifiers, MouseButtons};
|
use termwiz::input::Modifiers;
|
||||||
|
|
||||||
let PixelMouseEvent {
|
let PixelMouseEvent {
|
||||||
mouse_buttons,
|
mouse_buttons,
|
||||||
modifiers,
|
modifiers,
|
||||||
..
|
..
|
||||||
} = mouse;
|
} = mouse;
|
||||||
let key = if mouse_buttons.contains(MouseButtons::VERT_WHEEL) {
|
let key = Key::from(mouse_buttons);
|
||||||
if mouse_buttons.contains(MouseButtons::WHEEL_POSITIVE) {
|
|
||||||
Key::MouseScrollDown
|
|
||||||
} else {
|
|
||||||
Key::MouseScrollUp
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Key::Null
|
|
||||||
};
|
|
||||||
let ctrl = modifiers.contains(Modifiers::CTRL);
|
let ctrl = modifiers.contains(Modifiers::CTRL);
|
||||||
let alt = modifiers.contains(Modifiers::ALT);
|
let alt = modifiers.contains(Modifiers::ALT);
|
||||||
|
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user