Skip to content

Instantly share code, notes, and snippets.

@buddylindsey
Created May 20, 2024 04:11
Show Gist options
  • Save buddylindsey/e6b50021aa9433f22e482c10acb8a49e to your computer and use it in GitHub Desktop.
Save buddylindsey/e6b50021aa9433f22e482c10acb8a49e to your computer and use it in GitHub Desktop.
An example of using Widget with ratatui in a slimmed down manner
use crossterm::{
event::{self, Event, KeyCode},
terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
ExecutableCommand,
};
use ratatui::{prelude::*, widgets::*};
use std::io::{self, stdout, Error};
#[derive(Debug, Default)]
struct App {
pub mode: Mode,
}
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
enum Mode {
#[default]
Running,
Quit,
}
struct Banner {
pub text: String,
}
impl Widget for &Banner {
fn render(self, area: Rect, buf: &mut Buffer) {
let title_block = Block::default()
.borders(Borders::ALL)
.style(Style::default());
Paragraph::new(Text::styled(&self.text, Style::default()))
.block(title_block)
.render(area, buf);
}
}
impl App {
pub fn run(&mut self, terminal: &mut Terminal<impl Backend>) -> Result<(), Error> {
while self.is_running() {
self.draw(terminal)?;
self.handle_keypress()?;
}
Ok(())
}
fn is_running(&self) -> bool {
self.mode != Mode::Quit
}
fn draw(&self, terminal: &mut Terminal<impl Backend>) -> Result<(), Error> {
terminal.draw(|frame| {
frame.render_widget(self, frame.size());
})?;
Ok(())
}
pub fn handle_keypress(&mut self) -> Result<(), Error> {
if let Event::Key(key) = event::read()? {
match self.mode {
Mode::Running => match key.code {
KeyCode::Char('q') => self.mode = Mode::Quit,
_ => {}
},
Mode::Quit => {}
}
}
Ok(())
}
fn render_title_bar(&self, area: Rect, buf: &mut Buffer) {
let banner = Banner {
text: "Title 1".to_string(),
};
banner.render(area, buf);
}
fn render_middle_bar(&self, area: Rect, buf: &mut Buffer) {
let banner = Banner {
text: "Title 2".to_string(),
};
banner.render(area, buf);
}
}
impl Widget for &App {
fn render(self, area: Rect, buf: &mut Buffer) {
let vertical = Layout::vertical([Constraint::Length(3), Constraint::Length(3)]);
let [title_bar, middle_bar] = vertical.areas(area);
self.render_title_bar(title_bar, buf);
self.render_middle_bar(middle_bar, buf);
}
}
fn main() -> Result<(), Error> {
let mut terminal = Terminal::new(CrosstermBackend::new(io::stdout()))?;
let _ = enable_raw_mode();
stdout().execute(EnterAlternateScreen)?;
App::default().run(&mut terminal)?;
let _ = disable_raw_mode();
stdout().execute(LeaveAlternateScreen)?;
Ok(())
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment