use std::io; use crossterm::event::{self, Event, KeyCode, KeyEvent, KeyEventKind}; use ratatui::{ buffer::Buffer, layout::{Rect, Constraint, Layout, Spacing}, style::Stylize, symbols::{border, merge::MergeStrategy}, text::{Line, Text}, widgets::{Block, Paragraph, Widget}, DefaultTerminal, Frame, }; fn main() -> io::Result<()> { ratatui::run(|terminal| { loop { terminal.draw(render)?; let should_exit: bool = exit_app()?; if should_exit { break; } } Ok(()) }) } fn render(frame: &mut Frame) { use Constraint::{Fill, Length, Min}; let [top_area, rest_area] = Layout::vertical([Fill(1), Fill(12)]).areas(frame.area()); let [main_area, output_area] = Layout::vertical([Fill(9), Fill(3)]) .spacing(Spacing::Overlap(1)) .areas(rest_area); let [left_main_area, right_main_area] = Layout::horizontal([Fill(2), Fill(5)]) .spacing(Spacing::Overlap(1)) .areas(main_area); let [left_output_area, right_output_area] = Layout::horizontal([Fill(5), Fill(1)]) .spacing(Spacing::Overlap(1)) .areas(output_area); frame.render_widget(Block::bordered(), top_area); frame.render_widget(Block::bordered().merge_borders(MergeStrategy::Exact), left_output_area); frame.render_widget(Block::bordered().merge_borders(MergeStrategy::Exact), right_output_area); frame.render_widget(Block::bordered().merge_borders(MergeStrategy::Exact), left_main_area); frame.render_widget(Block::bordered().merge_borders(MergeStrategy::Exact), right_main_area); } fn exit_app() -> io::Result { match event::read()? { Event::Key(key) if key.kind == KeyEventKind::Press => match key.code { KeyCode::Char('q') => return Ok(true), _ => {} }, _ => {} } Ok(false) }