monorepo/editor-challenge/src/ui.rs

92 lines
2.9 KiB
Rust

use crossterm::terminal::{disable_raw_mode, enable_raw_mode};
use tui::{layout::{Alignment, Constraint, Direction, Layout}, style::{Color, Style}, widgets::{Block, BorderType, Borders, Paragraph}, Terminal};
use crate::state::AppState;
pub struct Canvas<T: tui::backend::Backend> {
top_row: usize,
terminal: Terminal<T>,
}
impl<T: tui::backend::Backend> Canvas<T> {
pub fn new(terminal: Terminal<T>) -> Self {
enable_raw_mode().unwrap();
Self {
top_row: 0,
terminal
}
}
pub fn render(&mut self, app_state: &AppState) -> Result<(), anyhow::Error>
{
self.terminal.draw(|rect| {
let size = rect.size();
let chunks = Layout::default()
.direction(Direction::Vertical)
.margin(2)
.constraints(
[
Constraint::Min(2),
Constraint::Length(3),
// Constraint::Length(3),
]
.as_ref(),
)
.split(size);
let title = Paragraph::new(
app_state
.path
.clone()
.map(|path| path.to_string_lossy().into_owned())
.unwrap_or("No file opened".to_owned()),
)
.style(Style::default().fg(Color::LightCyan))
.alignment(Alignment::Center)
.block(
Block::default()
.borders(Borders::ALL)
.style(Style::default().fg(Color::White))
.border_type(BorderType::Plain),
);
rect.render_widget(title, chunks[1]);
/*
let cp = Paragraph::new(COPYRIGHT)
.style(Style::default().fg(Color::LightCyan))
.alignment(Alignment::Center)
.block(
Block::default()
.borders(Borders::ALL)
.style(Style::default().fg(Color::White))
.title("Copyright")
.border_type(BorderType::Plain),
);
rect.render_widget(cp, chunks[2]);
*/
let (row, column) = app_state.cursor.addr();
if row == self.top_row && row >= 1 {
self.top_row -= 1;
} else if row - self.top_row == (chunks[0].height - 1).into() {
self.top_row += 1;
}
let contents = Paragraph::new(app_state.contents.contents()).scroll((self.top_row as u16, 0));
rect.render_widget(contents, chunks[0]);
rect.set_cursor(chunks[0].x + column as u16, chunks[0].y + (row - self.top_row) as u16);
})?;
Ok(())
}
}
impl<T: tui::backend::Backend> Drop for Canvas<T> {
fn drop(&mut self) {
let _ = disable_raw_mode();
let _ = self.terminal.show_cursor();
}
}