keyboard input

This commit is contained in:
2024-09-21 19:08:03 +02:00
parent f47f3575de
commit 56d1691397
5 changed files with 85 additions and 64 deletions
+53 -27
View File
@@ -1,5 +1,9 @@
use std::io::{self, Write};
use crossterm::terminal::{self, disable_raw_mode, enable_raw_mode};
use std::{
io::{self, Read, Write},
str::from_utf8,
};
pub mod key;
pub mod ui;
#[derive(Clone)]
@@ -7,11 +11,10 @@ pub struct ComponentWrapper<T> {
pub component: T,
pub x: usize,
pub y: usize,
cleared_frame: String,
}
pub trait Component {
fn render(&mut self) -> String {
fn render(&self) -> String {
String::new()
}
fn run(&mut self, x: usize, y: usize) -> String {
@@ -27,31 +30,8 @@ impl<T: Component> ComponentWrapper<T> {
component,
x: 0,
y: 0,
cleared_frame: String::new(),
}
}
pub fn render(&mut self) {
self.clean();
self.cleared_frame.clear();
for (i, d) in format!("{}", self.component.render())
.split("\n")
.enumerate()
{
print!("\x1B[{};{}H{}", self.y + (i + 1), self.x, d);
self.cleared_frame += format!(
"\x1B[{};{}H{}",
self.y + (i + 1),
self.x,
" ".repeat(d.len())
)
.as_str();
}
flush();
}
pub fn clean(&self) {
print!("{}", self.cleared_frame);
flush();
}
pub fn run(&mut self) -> String {
self.component.run(self.x, self.y)
}
@@ -65,3 +45,49 @@ pub fn clear() {
pub fn flush() {
io::stdout().flush().unwrap();
}
pub fn render_frame<T: Component>(components: Vec<ComponentWrapper<T>>) {
clear();
let (w, h) = terminal::size().unwrap();
let mut frame: Vec<String> = vec![" ".repeat(w as usize); h as usize - 1];
for c in components {
for (i, line) in c.component.render().split("\n").enumerate() {
frame[c.y + i] = render_line(frame[c.y + i].clone(), line.to_string(), c.x);
}
}
print!("{}", frame.join("\n"));
flush();
}
fn render_line(frame_line: String, line: String, x: usize) -> String {
let mut result = String::new();
if x >= frame_line.len() {
return result;
}
let lchars: Vec<char> = line.chars().collect();
for (i, c) in frame_line.chars().enumerate() {
if i >= x && lchars.len() > (i - x) {
result += lchars[i - x].to_string().as_str();
} else {
result += c.to_string().as_str();
}
}
result
}
fn read_key_() -> String {
let mut buf = [0u8; 2];
io::stdin().read(&mut buf).unwrap();
let mut res = from_utf8(&buf).unwrap().to_string();
if !res.ends_with("\0") {
res += read_key_().as_str()
}
return res.strip_suffix("\0").unwrap_or(&res).to_string();
}
pub fn read_key() -> String {
enable_raw_mode().unwrap();
let res = read_key_();
disable_raw_mode().unwrap();
return res;
}