Created
May 20, 2024 04:11
-
-
Save buddylindsey/e6b50021aa9433f22e482c10acb8a49e to your computer and use it in GitHub Desktop.
An example of using Widget with ratatui in a slimmed down manner
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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