1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
use std::{io, time::Duration};
use crate::{sheet::register::Register, tui, widgets::{logview::LogView, sheetview::SheetView}};
use ratatui::{
crossterm::event::{self, Event, KeyCode, KeyEvent, KeyEventKind, KeyModifiers},
prelude::*,
widgets::Block,
};
pub struct App<'a> {
exit: bool,
view: SheetView<'a>,
logview: Option<LogView<'a>>,
}
impl App<'_> {
pub fn new() -> Self {
let sheet_id = Register::create(200, 1000);
let sheet = Register::get(sheet_id).unwrap();
{
let mut sheet = sheet.write().unwrap();
for row in 0..sheet.height() {
for column in 0..sheet.width() {
sheet.set_cell(row, column, format!("{}/{}", row, column).into());
}
}
}
let view = SheetView::new(sheet_id).block(Block::bordered().title("Sheet"));
Self { exit: false, view, logview: None }
}
pub fn run(&mut self, terminal: &mut tui::Tui) -> io::Result<()> {
while !self.exit {
terminal.draw(|frame| self.render_frame(frame))?;
self.handle_events()?;
}
Ok(())
}
fn render_frame(&mut self, frame: &mut Frame) {
frame.render_widget(self, frame.size());
}
fn handle_events(&mut self) -> io::Result<()> {
if event::poll(Duration::from_millis(100))? {
match event::read()? {
Event::Key(key_event) if key_event.kind == KeyEventKind::Press => {
self.handle_key_event(key_event)
}
_ => {}
}
}
Ok(())
}
fn handle_key_event(&mut self, key_event: KeyEvent) {
match key_event.code {
KeyCode::Char('q') if key_event.modifiers == KeyModifiers::CONTROL => self.exit(),
KeyCode::Char('l') if key_event.modifiers == KeyModifiers::CONTROL => {
match self.logview {
Some(_) => self.logview = None,
None => self.logview = Some(LogView::new().block(Block::bordered().title(" Log "))),
}
}
_ => self.view.handle_key_event(key_event),
}
}
fn exit(&mut self) {
self.exit = true;
}
}
impl Widget for &mut App<'_> {
fn render(self, area: Rect, buf: &mut Buffer)
where
Self: Sized,
{
match &mut self.logview {
Some(logview) => {
let layout = Layout::vertical([Constraint::Min(2), Constraint::Length(15)]).split(area);
self.view.render(layout[0], buf);
logview.render(layout[1], buf);
},
None => self.view.render(area, buf),
}
}
}
|