2024-01-11 02:04:43 +00:00
|
|
|
#![allow(clippy::cognitive_complexity)]
|
|
|
|
|
|
|
|
use std::io;
|
|
|
|
|
2024-01-11 02:21:34 +00:00
|
|
|
use keyfork_crossterm::event::KeyEventKind;
|
|
|
|
pub use keyfork_crossterm::{
|
2024-01-11 02:04:43 +00:00
|
|
|
cursor,
|
|
|
|
event::{self, Event, KeyCode, KeyEvent},
|
|
|
|
execute, queue, style,
|
|
|
|
terminal::{self, ClearType},
|
|
|
|
Command,
|
|
|
|
};
|
|
|
|
|
|
|
|
#[macro_use]
|
|
|
|
mod macros;
|
|
|
|
mod test;
|
|
|
|
|
|
|
|
const MENU: &str = r#"Crossterm interactive test
|
|
|
|
|
|
|
|
Controls:
|
|
|
|
|
|
|
|
- 'q' - quit interactive test (or return to this menu)
|
|
|
|
- any other key - continue with next step
|
|
|
|
|
|
|
|
Available tests:
|
|
|
|
|
|
|
|
1. cursor
|
|
|
|
2. color (foreground, background)
|
|
|
|
3. attributes (bold, italic, ...)
|
|
|
|
4. input
|
|
|
|
5. synchronized output
|
|
|
|
|
|
|
|
Select test to run ('1', '2', ...) or hit 'q' to quit.
|
|
|
|
"#;
|
|
|
|
|
|
|
|
fn run<W>(w: &mut W) -> io::Result<()>
|
|
|
|
where
|
|
|
|
W: io::Write,
|
|
|
|
{
|
|
|
|
execute!(w, terminal::EnterAlternateScreen)?;
|
|
|
|
|
|
|
|
terminal::enable_raw_mode()?;
|
|
|
|
|
|
|
|
loop {
|
|
|
|
queue!(
|
|
|
|
w,
|
|
|
|
style::ResetColor,
|
|
|
|
terminal::Clear(ClearType::All),
|
|
|
|
cursor::Hide,
|
|
|
|
cursor::MoveTo(1, 1)
|
|
|
|
)?;
|
|
|
|
|
|
|
|
for line in MENU.split('\n') {
|
|
|
|
queue!(w, style::Print(line), cursor::MoveToNextLine(1))?;
|
|
|
|
}
|
|
|
|
|
|
|
|
w.flush()?;
|
|
|
|
|
|
|
|
match read_char()? {
|
|
|
|
'1' => test::cursor::run(w)?,
|
|
|
|
'2' => test::color::run(w)?,
|
|
|
|
'3' => test::attribute::run(w)?,
|
|
|
|
'4' => test::event::run(w)?,
|
|
|
|
'5' => test::synchronized_output::run(w)?,
|
|
|
|
'q' => {
|
|
|
|
execute!(w, cursor::SetCursorStyle::DefaultUserShape).unwrap();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
_ => {}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
execute!(
|
|
|
|
w,
|
|
|
|
style::ResetColor,
|
|
|
|
cursor::Show,
|
|
|
|
terminal::LeaveAlternateScreen
|
|
|
|
)?;
|
|
|
|
|
|
|
|
terminal::disable_raw_mode()
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn read_char() -> std::io::Result<char> {
|
|
|
|
loop {
|
|
|
|
if let Ok(Event::Key(KeyEvent {
|
|
|
|
code: KeyCode::Char(c),
|
|
|
|
kind: KeyEventKind::Press,
|
|
|
|
modifiers: _,
|
|
|
|
state: _,
|
|
|
|
})) = event::read()
|
|
|
|
{
|
|
|
|
return Ok(c);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn buffer_size() -> io::Result<(u16, u16)> {
|
|
|
|
terminal::size()
|
|
|
|
}
|
|
|
|
|
|
|
|
fn main() -> std::io::Result<()> {
|
|
|
|
let mut stdout = io::stdout();
|
|
|
|
run(&mut stdout)
|
|
|
|
}
|