refactor(examples): use crossterm event methods (#1792)
Crossterm 0.29 introduced methods to easily check / extract the event type. E.g. as_key_press_event() and is_key_press(). This commit updates the examples to use these methods instead of matching on the event type. This makes the code cleaner and easier to read. Also does a general cleanup of the event handling code in the examples.
This commit is contained in:
@@ -12,7 +12,7 @@
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
use color_eyre::Result;
|
||||
use crossterm::event::{self, Event, KeyCode};
|
||||
use crossterm::event;
|
||||
use ratatui::buffer::Buffer;
|
||||
use ratatui::layout::{Constraint, Layout, Position, Rect, Size};
|
||||
use ratatui::style::{Color, Style};
|
||||
@@ -55,11 +55,8 @@ impl App {
|
||||
if !event::poll(timeout)? {
|
||||
return Ok(());
|
||||
}
|
||||
if let Event::Key(key) = event::read()? {
|
||||
match key.code {
|
||||
KeyCode::Char('q') | KeyCode::Esc => self.should_quit = true,
|
||||
_ => {}
|
||||
}
|
||||
if event::read()?.is_key_press() {
|
||||
self.should_quit = true;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ use std::sync::{Arc, RwLock};
|
||||
use std::time::Duration;
|
||||
|
||||
use color_eyre::Result;
|
||||
use crossterm::event::{Event, EventStream, KeyCode, KeyEventKind};
|
||||
use crossterm::event::{Event, EventStream, KeyCode};
|
||||
use octocrab::params::pulls::Sort;
|
||||
use octocrab::params::Direction;
|
||||
use octocrab::Page;
|
||||
@@ -70,14 +70,14 @@ impl App {
|
||||
|
||||
while !self.should_quit {
|
||||
tokio::select! {
|
||||
_ = interval.tick() => { terminal.draw(|frame| self.draw(frame))?; },
|
||||
_ = interval.tick() => { terminal.draw(|frame| self.render(frame))?; },
|
||||
Some(Ok(event)) = events.next() => self.handle_event(&event),
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn draw(&self, frame: &mut Frame) {
|
||||
fn render(&self, frame: &mut Frame) {
|
||||
let vertical = Layout::vertical([Constraint::Length(1), Constraint::Fill(1)]);
|
||||
let [title_area, body_area] = vertical.areas(frame.area());
|
||||
let title = Line::from("Ratatui async example").centered().bold();
|
||||
@@ -86,14 +86,12 @@ impl App {
|
||||
}
|
||||
|
||||
fn handle_event(&mut self, event: &Event) {
|
||||
if let Event::Key(key) = event {
|
||||
if key.kind == KeyEventKind::Press {
|
||||
match key.code {
|
||||
KeyCode::Char('q') | KeyCode::Esc => self.should_quit = true,
|
||||
KeyCode::Char('j') | KeyCode::Down => self.pull_requests.scroll_down(),
|
||||
KeyCode::Char('k') | KeyCode::Up => self.pull_requests.scroll_up(),
|
||||
_ => {}
|
||||
}
|
||||
if let Some(key) = event.as_key_press_event() {
|
||||
match key.code {
|
||||
KeyCode::Char('q') | KeyCode::Esc => self.should_quit = true,
|
||||
KeyCode::Char('j') | KeyCode::Down => self.pull_requests.scroll_down(),
|
||||
KeyCode::Char('k') | KeyCode::Up => self.pull_requests.scroll_up(),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
use std::fmt;
|
||||
|
||||
use color_eyre::Result;
|
||||
use crossterm::event::{self, Event, KeyCode, KeyEventKind};
|
||||
use crossterm::event::{self, KeyCode};
|
||||
use ratatui::layout::{Constraint, Layout, Margin, Rect};
|
||||
use ratatui::style::{Color, Modifier, Style, Stylize};
|
||||
use ratatui::text::{Line, Text};
|
||||
@@ -34,21 +34,17 @@ fn run(mut terminal: DefaultTerminal) -> Result<()> {
|
||||
let mut calendar_style = StyledCalendar::Default;
|
||||
loop {
|
||||
terminal.draw(|frame| render(frame, calendar_style, selected_date))?;
|
||||
if let Event::Key(key) = event::read()? {
|
||||
if key.kind == KeyEventKind::Press {
|
||||
match key.code {
|
||||
KeyCode::Char('q') => break Ok(()),
|
||||
KeyCode::Char('s') => calendar_style = calendar_style.next(),
|
||||
KeyCode::Char('n') | KeyCode::Tab => selected_date = next_month(selected_date),
|
||||
KeyCode::Char('p') | KeyCode::BackTab => {
|
||||
selected_date = previous_month(selected_date);
|
||||
}
|
||||
KeyCode::Char('h') | KeyCode::Left => selected_date -= 1.days(),
|
||||
KeyCode::Char('j') | KeyCode::Down => selected_date += 1.weeks(),
|
||||
KeyCode::Char('k') | KeyCode::Up => selected_date -= 1.weeks(),
|
||||
KeyCode::Char('l') | KeyCode::Right => selected_date += 1.days(),
|
||||
_ => {}
|
||||
}
|
||||
if let Some(key) = event::read()?.as_key_press_event() {
|
||||
match key.code {
|
||||
KeyCode::Char('q') | KeyCode::Esc => return Ok(()),
|
||||
KeyCode::Char('s') => calendar_style = calendar_style.next(),
|
||||
KeyCode::Char('n') | KeyCode::Tab => selected_date = next_month(selected_date),
|
||||
KeyCode::Char('p') | KeyCode::BackTab => selected_date = prev_month(selected_date),
|
||||
KeyCode::Char('h') | KeyCode::Left => selected_date -= 1.days(),
|
||||
KeyCode::Char('j') | KeyCode::Down => selected_date += 1.weeks(),
|
||||
KeyCode::Char('k') | KeyCode::Up => selected_date -= 1.weeks(),
|
||||
KeyCode::Char('l') | KeyCode::Right => selected_date += 1.days(),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -65,7 +61,7 @@ fn next_month(date: Date) -> Date {
|
||||
}
|
||||
}
|
||||
|
||||
fn previous_month(date: Date) -> Date {
|
||||
fn prev_month(date: Date) -> Date {
|
||||
if date.month() == Month::January {
|
||||
date.replace_month(Month::December)
|
||||
.unwrap()
|
||||
@@ -76,7 +72,7 @@ fn previous_month(date: Date) -> Date {
|
||||
}
|
||||
}
|
||||
|
||||
/// Draw the UI with a calendar.
|
||||
/// Render the UI with a calendar.
|
||||
fn render(frame: &mut Frame, calendar_style: StyledCalendar, selected_date: Date) {
|
||||
let header = Text::from_iter([
|
||||
Line::from("Calendar Example".bold()),
|
||||
|
||||
@@ -15,7 +15,7 @@ use std::{
|
||||
|
||||
use color_eyre::Result;
|
||||
use crossterm::event::{
|
||||
self, DisableMouseCapture, EnableMouseCapture, Event, KeyCode, KeyEventKind, MouseEventKind,
|
||||
self, DisableMouseCapture, EnableMouseCapture, Event, KeyCode, KeyEvent, MouseEventKind,
|
||||
};
|
||||
use crossterm::ExecutableCommand;
|
||||
use itertools::Itertools;
|
||||
@@ -75,43 +75,33 @@ impl App {
|
||||
let tick_rate = Duration::from_millis(16);
|
||||
let mut last_tick = Instant::now();
|
||||
while !self.exit {
|
||||
terminal.draw(|frame| self.draw(frame))?;
|
||||
terminal.draw(|frame| self.render(frame))?;
|
||||
let timeout = tick_rate.saturating_sub(last_tick.elapsed());
|
||||
if event::poll(timeout)? {
|
||||
match event::read()? {
|
||||
Event::Key(key) => self.handle_key_press(key),
|
||||
Event::Mouse(event) => self.handle_mouse_event(event),
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
if last_tick.elapsed() >= tick_rate {
|
||||
if !event::poll(timeout)? {
|
||||
self.on_tick();
|
||||
last_tick = Instant::now();
|
||||
continue;
|
||||
}
|
||||
match event::read()? {
|
||||
Event::Key(key) => self.handle_key_event(key),
|
||||
Event::Mouse(event) => self.handle_mouse_event(event),
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_key_press(&mut self, key: event::KeyEvent) {
|
||||
if key.kind != KeyEventKind::Press {
|
||||
fn handle_key_event(&mut self, key: KeyEvent) {
|
||||
if !key.is_press() {
|
||||
return;
|
||||
}
|
||||
match key.code {
|
||||
KeyCode::Char('q') => self.exit = true,
|
||||
KeyCode::Down | KeyCode::Char('j') => self.y += 1.0,
|
||||
KeyCode::Up | KeyCode::Char('k') => self.y -= 1.0,
|
||||
KeyCode::Right | KeyCode::Char('l') => self.x += 1.0,
|
||||
KeyCode::Left | KeyCode::Char('h') => self.x -= 1.0,
|
||||
KeyCode::Enter => {
|
||||
self.marker = match self.marker {
|
||||
Marker::Dot => Marker::Braille,
|
||||
Marker::Braille => Marker::Block,
|
||||
Marker::Block => Marker::HalfBlock,
|
||||
Marker::HalfBlock => Marker::Bar,
|
||||
Marker::Bar => Marker::Dot,
|
||||
};
|
||||
}
|
||||
KeyCode::Char('q') | KeyCode::Esc => self.exit = true,
|
||||
KeyCode::Char('j') | KeyCode::Down => self.y += 1.0,
|
||||
KeyCode::Char('k') | KeyCode::Up => self.y -= 1.0,
|
||||
KeyCode::Char('l') | KeyCode::Right => self.x += 1.0,
|
||||
KeyCode::Char('h') | KeyCode::Left => self.x -= 1.0,
|
||||
KeyCode::Enter => self.cycle_marker(),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
@@ -127,6 +117,16 @@ impl App {
|
||||
}
|
||||
}
|
||||
|
||||
fn cycle_marker(&mut self) {
|
||||
self.marker = match self.marker {
|
||||
Marker::Dot => Marker::Braille,
|
||||
Marker::Braille => Marker::Block,
|
||||
Marker::Block => Marker::HalfBlock,
|
||||
Marker::HalfBlock => Marker::Bar,
|
||||
Marker::Bar => Marker::Dot,
|
||||
};
|
||||
}
|
||||
|
||||
fn on_tick(&mut self) {
|
||||
// bounce the ball by flipping the velocity vector
|
||||
let ball = &self.ball;
|
||||
@@ -145,7 +145,7 @@ impl App {
|
||||
self.ball.y += self.vy;
|
||||
}
|
||||
|
||||
fn draw(&self, frame: &mut Frame) {
|
||||
fn render(&self, frame: &mut Frame) {
|
||||
let header = Text::from_iter([
|
||||
"Canvas Example".bold(),
|
||||
"<q> Quit | <enter> Change Marker | <hjkl> Move".into(),
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
use color_eyre::Result;
|
||||
use crossterm::event::{self, Event, KeyCode};
|
||||
use crossterm::event::{self, KeyCode};
|
||||
use ratatui::layout::{Constraint, Layout, Rect};
|
||||
use ratatui::style::{Color, Modifier, Style, Stylize};
|
||||
use ratatui::symbols::{self, Marker};
|
||||
@@ -82,19 +82,19 @@ impl App {
|
||||
let tick_rate = Duration::from_millis(250);
|
||||
let mut last_tick = Instant::now();
|
||||
loop {
|
||||
terminal.draw(|frame| self.draw(frame))?;
|
||||
terminal.draw(|frame| self.render(frame))?;
|
||||
|
||||
let timeout = tick_rate.saturating_sub(last_tick.elapsed());
|
||||
if event::poll(timeout)? {
|
||||
if let Event::Key(key) = event::read()? {
|
||||
if key.code == KeyCode::Char('q') {
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
}
|
||||
if last_tick.elapsed() >= tick_rate {
|
||||
if !event::poll(timeout)? {
|
||||
self.on_tick();
|
||||
last_tick = Instant::now();
|
||||
continue;
|
||||
}
|
||||
if event::read()?
|
||||
.as_key_press_event()
|
||||
.is_some_and(|key| key.code == KeyCode::Char('q'))
|
||||
{
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -110,7 +110,7 @@ impl App {
|
||||
self.window[1] += 1.0;
|
||||
}
|
||||
|
||||
fn draw(&self, frame: &mut Frame) {
|
||||
fn render(&self, frame: &mut Frame) {
|
||||
let [top, bottom] = Layout::vertical([Constraint::Fill(1); 2]).areas(frame.area());
|
||||
let [animated_chart, bar_chart] =
|
||||
Layout::horizontal([Constraint::Fill(1), Constraint::Length(29)]).areas(top);
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
//! [`latest`]: https://github.com/ratatui/ratatui/tree/latest
|
||||
|
||||
use color_eyre::Result;
|
||||
use crossterm::event::{self, Event, KeyCode, KeyEventKind};
|
||||
use crossterm::event;
|
||||
use itertools::Itertools;
|
||||
use ratatui::layout::{Alignment, Constraint, Layout, Rect};
|
||||
use ratatui::style::{Color, Style, Stylize};
|
||||
@@ -27,16 +27,14 @@ fn main() -> Result<()> {
|
||||
|
||||
fn run(mut terminal: DefaultTerminal) -> Result<()> {
|
||||
loop {
|
||||
terminal.draw(draw)?;
|
||||
if let Event::Key(key) = event::read()? {
|
||||
if key.kind == KeyEventKind::Press && key.code == KeyCode::Char('q') {
|
||||
return Ok(());
|
||||
}
|
||||
terminal.draw(render)?;
|
||||
if event::read()?.is_key_press() {
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn draw(frame: &mut Frame) {
|
||||
fn render(frame: &mut Frame) {
|
||||
let layout = Layout::vertical([
|
||||
Constraint::Length(30),
|
||||
Constraint::Length(17),
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
use color_eyre::Result;
|
||||
use crossterm::event::{self, Event, KeyCode, KeyEventKind};
|
||||
use crossterm::event;
|
||||
use palette::convert::FromColorUnclamped;
|
||||
use palette::{Okhsv, Srgb};
|
||||
use ratatui::buffer::Buffer;
|
||||
@@ -104,19 +104,16 @@ impl App {
|
||||
}
|
||||
|
||||
/// Handle any events that have occurred since the last time the app was rendered.
|
||||
///
|
||||
/// Currently, this only handles the q key to quit the app.
|
||||
fn handle_events(&mut self) -> Result<()> {
|
||||
// Ensure that the app only blocks for a period that allows the app to render at
|
||||
// approximately 60 FPS (this doesn't account for the time to render the frame, and will
|
||||
// also update the app immediately any time an event occurs)
|
||||
let timeout = Duration::from_secs_f32(1.0 / 60.0);
|
||||
if event::poll(timeout)? {
|
||||
if let Event::Key(key) = event::read()? {
|
||||
if key.kind == KeyEventKind::Press && key.code == KeyCode::Char('q') {
|
||||
self.state = AppState::Quit;
|
||||
}
|
||||
}
|
||||
if !event::poll(timeout)? {
|
||||
return Ok(());
|
||||
}
|
||||
if event::read()?.is_key_press() {
|
||||
self.state = AppState::Quit;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
///
|
||||
/// [`latest`]: https://github.com/ratatui/ratatui/tree/latest
|
||||
use color_eyre::Result;
|
||||
use crossterm::event::{self, Event, KeyCode, KeyEventKind};
|
||||
use crossterm::event::{self, KeyCode};
|
||||
use itertools::Itertools;
|
||||
use ratatui::buffer::Buffer;
|
||||
use ratatui::layout::Constraint::{self, Fill, Length, Max, Min, Percentage, Ratio};
|
||||
@@ -107,8 +107,8 @@ impl App {
|
||||
}
|
||||
|
||||
fn handle_events(&mut self) -> Result<()> {
|
||||
match event::read()? {
|
||||
Event::Key(key) if key.kind == KeyEventKind::Press => match key.code {
|
||||
if let Some(key) = event::read()?.as_key_press_event() {
|
||||
match key.code {
|
||||
KeyCode::Char('q') | KeyCode::Esc => self.exit(),
|
||||
KeyCode::Char('1') => self.swap_constraint(ConstraintName::Min),
|
||||
KeyCode::Char('2') => self.swap_constraint(ConstraintName::Max),
|
||||
@@ -125,8 +125,7 @@ impl App {
|
||||
KeyCode::Char('h') | KeyCode::Left => self.prev_block(),
|
||||
KeyCode::Char('l') | KeyCode::Right => self.next_block(),
|
||||
_ => {}
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
///
|
||||
/// [`latest`]: https://github.com/ratatui/ratatui/tree/latest
|
||||
use color_eyre::Result;
|
||||
use crossterm::event::{self, Event, KeyCode, KeyEventKind};
|
||||
use crossterm::event::{self, KeyCode};
|
||||
use ratatui::buffer::Buffer;
|
||||
use ratatui::layout::Constraint::{self, Fill, Length, Max, Min, Percentage, Ratio};
|
||||
use ratatui::layout::{Layout, Rect};
|
||||
@@ -90,10 +90,7 @@ impl App {
|
||||
}
|
||||
|
||||
fn handle_events(&mut self) -> Result<()> {
|
||||
if let Event::Key(key) = event::read()? {
|
||||
if key.kind != KeyEventKind::Press {
|
||||
return Ok(());
|
||||
}
|
||||
if let Some(key) = event::read()?.as_key_press_event() {
|
||||
match key.code {
|
||||
KeyCode::Char('q') | KeyCode::Esc => self.quit(),
|
||||
KeyCode::Char('l') | KeyCode::Right => self.next(),
|
||||
|
||||
@@ -10,8 +10,8 @@ use std::{io::stdout, ops::ControlFlow, time::Duration};
|
||||
|
||||
use color_eyre::Result;
|
||||
use crossterm::event::{
|
||||
self, DisableMouseCapture, EnableMouseCapture, Event, KeyCode, MouseButton, MouseEvent,
|
||||
MouseEventKind,
|
||||
self, DisableMouseCapture, EnableMouseCapture, Event, KeyCode, KeyEvent, MouseButton,
|
||||
MouseEvent, MouseEventKind,
|
||||
};
|
||||
use crossterm::execute;
|
||||
use ratatui::buffer::Buffer;
|
||||
@@ -147,15 +147,12 @@ fn run(mut terminal: DefaultTerminal) -> Result<()> {
|
||||
let mut selected_button: usize = 0;
|
||||
let mut button_states = [State::Selected, State::Normal, State::Normal];
|
||||
loop {
|
||||
terminal.draw(|frame| draw(frame, button_states))?;
|
||||
terminal.draw(|frame| render(frame, button_states))?;
|
||||
if !event::poll(Duration::from_millis(100))? {
|
||||
continue;
|
||||
}
|
||||
match event::read()? {
|
||||
Event::Key(key) => {
|
||||
if key.kind != event::KeyEventKind::Press {
|
||||
continue;
|
||||
}
|
||||
if handle_key_event(key, &mut button_states, &mut selected_button).is_break() {
|
||||
break;
|
||||
}
|
||||
@@ -169,7 +166,7 @@ fn run(mut terminal: DefaultTerminal) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn draw(frame: &mut Frame, states: [State; 3]) {
|
||||
fn render(frame: &mut Frame, states: [State; 3]) {
|
||||
let vertical = Layout::vertical([
|
||||
Constraint::Length(1),
|
||||
Constraint::Max(3),
|
||||
@@ -201,10 +198,13 @@ fn render_buttons(frame: &mut Frame<'_>, area: Rect, states: [State; 3]) {
|
||||
}
|
||||
|
||||
fn handle_key_event(
|
||||
key: event::KeyEvent,
|
||||
key: KeyEvent,
|
||||
button_states: &mut [State; 3],
|
||||
selected_button: &mut usize,
|
||||
) -> ControlFlow<()> {
|
||||
if !key.is_press() {
|
||||
return ControlFlow::Continue(());
|
||||
}
|
||||
match key.code {
|
||||
KeyCode::Char('q') => return ControlFlow::Break(()),
|
||||
KeyCode::Left | KeyCode::Char('h') => {
|
||||
|
||||
@@ -2,9 +2,7 @@ use std::error::Error;
|
||||
use std::io;
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
use crossterm::event::{
|
||||
self, DisableMouseCapture, EnableMouseCapture, Event, KeyCode, KeyEventKind,
|
||||
};
|
||||
use crossterm::event::{self, DisableMouseCapture, EnableMouseCapture, KeyCode};
|
||||
use crossterm::execute;
|
||||
use crossterm::terminal::{
|
||||
disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen,
|
||||
@@ -56,23 +54,20 @@ where
|
||||
terminal.draw(|frame| ui::draw(frame, &mut app))?;
|
||||
|
||||
let timeout = tick_rate.saturating_sub(last_tick.elapsed());
|
||||
if event::poll(timeout)? {
|
||||
if let Event::Key(key) = event::read()? {
|
||||
if key.kind == KeyEventKind::Press {
|
||||
match key.code {
|
||||
KeyCode::Left | KeyCode::Char('h') => app.on_left(),
|
||||
KeyCode::Up | KeyCode::Char('k') => app.on_up(),
|
||||
KeyCode::Right | KeyCode::Char('l') => app.on_right(),
|
||||
KeyCode::Down | KeyCode::Char('j') => app.on_down(),
|
||||
KeyCode::Char(c) => app.on_key(c),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if last_tick.elapsed() >= tick_rate {
|
||||
if !event::poll(timeout)? {
|
||||
app.on_tick();
|
||||
last_tick = Instant::now();
|
||||
continue;
|
||||
}
|
||||
if let Some(key) = event::read()?.as_key_press_event() {
|
||||
match key.code {
|
||||
KeyCode::Char('h') | KeyCode::Left => app.on_left(),
|
||||
KeyCode::Char('j') | KeyCode::Down => app.on_down(),
|
||||
KeyCode::Char('k') | KeyCode::Up => app.on_up(),
|
||||
KeyCode::Char('l') | KeyCode::Right => app.on_right(),
|
||||
KeyCode::Char(c) => app.on_key(c),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
if app.should_quit {
|
||||
return Ok(());
|
||||
|
||||
@@ -2,8 +2,7 @@ use std::time::Duration;
|
||||
|
||||
use color_eyre::eyre::Context;
|
||||
use color_eyre::Result;
|
||||
use crossterm::event;
|
||||
use crossterm::event::{Event, KeyCode, KeyEvent, KeyEventKind};
|
||||
use crossterm::event::{self, KeyCode};
|
||||
use itertools::Itertools;
|
||||
use ratatui::buffer::Buffer;
|
||||
use ratatui::layout::{Constraint, Layout, Rect};
|
||||
@@ -50,7 +49,7 @@ impl App {
|
||||
pub fn run(mut self, mut terminal: DefaultTerminal) -> Result<()> {
|
||||
while self.is_running() {
|
||||
terminal
|
||||
.draw(|frame| self.draw(frame))
|
||||
.draw(|frame| self.render(frame))
|
||||
.wrap_err("terminal.draw")?;
|
||||
self.handle_events()?;
|
||||
}
|
||||
@@ -61,8 +60,8 @@ impl App {
|
||||
self.mode != Mode::Quit
|
||||
}
|
||||
|
||||
/// Draw a single frame of the app.
|
||||
fn draw(&self, frame: &mut Frame) {
|
||||
/// Render a single frame of the app.
|
||||
fn render(&self, frame: &mut Frame) {
|
||||
frame.render_widget(self, frame.area());
|
||||
if self.mode == Mode::Destroy {
|
||||
destroy::destroy(frame);
|
||||
@@ -78,25 +77,20 @@ impl App {
|
||||
if !event::poll(timeout)? {
|
||||
return Ok(());
|
||||
}
|
||||
match event::read()? {
|
||||
Event::Key(key) if key.kind == KeyEventKind::Press => self.handle_key_press(key),
|
||||
_ => {}
|
||||
if let Some(key) = event::read()?.as_key_press_event() {
|
||||
match key.code {
|
||||
KeyCode::Char('q') | KeyCode::Esc => self.mode = Mode::Quit,
|
||||
KeyCode::Char('h') | KeyCode::Left => self.prev_tab(),
|
||||
KeyCode::Char('l') | KeyCode::Right | KeyCode::Tab => self.next_tab(),
|
||||
KeyCode::Char('k') | KeyCode::Up => self.prev(),
|
||||
KeyCode::Char('j') | KeyCode::Down => self.next(),
|
||||
KeyCode::Char('d') | KeyCode::Delete => self.destroy(),
|
||||
_ => {}
|
||||
};
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_key_press(&mut self, key: KeyEvent) {
|
||||
match key.code {
|
||||
KeyCode::Char('q') | KeyCode::Esc => self.mode = Mode::Quit,
|
||||
KeyCode::Char('h') | KeyCode::Left => self.prev_tab(),
|
||||
KeyCode::Char('l') | KeyCode::Right | KeyCode::Tab => self.next_tab(),
|
||||
KeyCode::Char('k') | KeyCode::Up => self.prev(),
|
||||
KeyCode::Char('j') | KeyCode::Down => self.next(),
|
||||
KeyCode::Char('d') | KeyCode::Delete => self.destroy(),
|
||||
_ => {}
|
||||
};
|
||||
}
|
||||
|
||||
fn prev(&mut self) {
|
||||
match self.tab {
|
||||
Tab::About => self.about_tab.prev_row(),
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
use std::num::NonZeroUsize;
|
||||
|
||||
use color_eyre::Result;
|
||||
use crossterm::event::{self, Event, KeyCode, KeyEventKind};
|
||||
use crossterm::event::{self, KeyCode};
|
||||
use ratatui::buffer::Buffer;
|
||||
use ratatui::layout::Constraint::{self, Fill, Length, Max, Min, Percentage, Ratio};
|
||||
use ratatui::layout::{Alignment, Flex, Layout, Rect};
|
||||
@@ -168,8 +168,8 @@ impl App {
|
||||
}
|
||||
|
||||
fn handle_events(&mut self) -> Result<()> {
|
||||
match event::read()? {
|
||||
Event::Key(key) if key.kind == KeyEventKind::Press => match key.code {
|
||||
if let Some(key) = event::read()?.as_key_press_event() {
|
||||
match key.code {
|
||||
KeyCode::Char('q') | KeyCode::Esc => self.quit(),
|
||||
KeyCode::Char('l') | KeyCode::Right => self.next(),
|
||||
KeyCode::Char('h') | KeyCode::Left => self.previous(),
|
||||
@@ -180,8 +180,7 @@ impl App {
|
||||
KeyCode::Char('+') => self.increment_spacing(),
|
||||
KeyCode::Char('-') => self.decrement_spacing(),
|
||||
_ => (),
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
use std::time::Duration;
|
||||
|
||||
use color_eyre::Result;
|
||||
use crossterm::event::{self, Event, KeyCode, KeyEventKind};
|
||||
use crossterm::event::{self, KeyCode};
|
||||
use ratatui::buffer::Buffer;
|
||||
use ratatui::layout::{Alignment, Constraint, Layout, Rect};
|
||||
use ratatui::style::palette::tailwind;
|
||||
@@ -79,15 +79,14 @@ impl App {
|
||||
|
||||
fn handle_events(&mut self) -> Result<()> {
|
||||
let timeout = Duration::from_secs_f32(1.0 / 20.0);
|
||||
if event::poll(timeout)? {
|
||||
if let Event::Key(key) = event::read()? {
|
||||
if key.kind == KeyEventKind::Press {
|
||||
match key.code {
|
||||
KeyCode::Char(' ') | KeyCode::Enter => self.start(),
|
||||
KeyCode::Char('q') | KeyCode::Esc => self.quit(),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
if !event::poll(timeout)? {
|
||||
return Ok(());
|
||||
}
|
||||
if let Some(key) = event::read()?.as_key_press_event() {
|
||||
match key.code {
|
||||
KeyCode::Char(' ') | KeyCode::Enter => self.start(),
|
||||
KeyCode::Char('q') | KeyCode::Esc => self.quit(),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
|
||||
@@ -9,7 +9,7 @@ use std::time::Duration;
|
||||
|
||||
use color_eyre::eyre::Context;
|
||||
use color_eyre::Result;
|
||||
use crossterm::event::{self, Event, KeyCode};
|
||||
use crossterm::event::{self, KeyCode};
|
||||
use ratatui::widgets::Paragraph;
|
||||
use ratatui::{DefaultTerminal, Frame};
|
||||
|
||||
@@ -33,7 +33,7 @@ fn main() -> Result<()> {
|
||||
/// on events, or you could have a single application state and update it based on events.
|
||||
fn run(mut terminal: DefaultTerminal) -> Result<()> {
|
||||
loop {
|
||||
terminal.draw(draw)?;
|
||||
terminal.draw(render)?;
|
||||
if should_quit()? {
|
||||
break;
|
||||
}
|
||||
@@ -43,7 +43,7 @@ fn run(mut terminal: DefaultTerminal) -> Result<()> {
|
||||
|
||||
/// Render the application. This is where you would draw the application UI. This example draws a
|
||||
/// greeting.
|
||||
fn draw(frame: &mut Frame) {
|
||||
fn render(frame: &mut Frame) {
|
||||
let greeting = Paragraph::new("Hello World! (press 'q' to quit)");
|
||||
frame.render_widget(greeting, frame.area());
|
||||
}
|
||||
@@ -55,9 +55,11 @@ fn draw(frame: &mut Frame) {
|
||||
/// updating the application state, without blocking the event loop for too long.
|
||||
fn should_quit() -> Result<bool> {
|
||||
if event::poll(Duration::from_millis(250)).context("event poll failed")? {
|
||||
if let Event::Key(key) = event::read().context("event read failed")? {
|
||||
return Ok(KeyCode::Char('q') == key.code);
|
||||
}
|
||||
let q_pressed = event::read()
|
||||
.context("event read failed")?
|
||||
.as_key_press_event()
|
||||
.is_some_and(|key| key.code == KeyCode::Char('q'));
|
||||
return Ok(q_pressed);
|
||||
}
|
||||
Ok(false)
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
/// [`latest`]: https://github.com/ratatui/ratatui/tree/latest
|
||||
/// [OSC 8]: https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda
|
||||
use color_eyre::Result;
|
||||
use crossterm::event::{self, Event, KeyCode};
|
||||
use crossterm::event::{self, KeyCode};
|
||||
use itertools::Itertools;
|
||||
use ratatui::buffer::Buffer;
|
||||
use ratatui::layout::Rect;
|
||||
@@ -38,10 +38,11 @@ impl App {
|
||||
fn run(self, mut terminal: DefaultTerminal) -> Result<()> {
|
||||
loop {
|
||||
terminal.draw(|frame| frame.render_widget(&self.hyperlink, frame.area()))?;
|
||||
if let Event::Key(key) = event::read()? {
|
||||
if matches!(key.code, KeyCode::Char('q') | KeyCode::Esc) {
|
||||
break;
|
||||
}
|
||||
if event::read()?
|
||||
.as_key_press_event()
|
||||
.is_some_and(|key| matches!(key.code, KeyCode::Char('q') | KeyCode::Esc))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
|
||||
@@ -170,7 +170,7 @@ where
|
||||
let mut redraw = true;
|
||||
loop {
|
||||
if redraw {
|
||||
terminal.draw(|frame| draw(frame, &downloads))?;
|
||||
terminal.draw(|frame| render(frame, &downloads))?;
|
||||
}
|
||||
redraw = true;
|
||||
|
||||
@@ -222,7 +222,7 @@ where
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn draw(frame: &mut Frame, downloads: &Downloads) {
|
||||
fn render(frame: &mut Frame, downloads: &Downloads) {
|
||||
let area = frame.area();
|
||||
|
||||
let block = Block::new().title(Line::from("Progress").centered());
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
//! [`tui-textarea`]: https://crates.io/crates/tui-textarea
|
||||
|
||||
use color_eyre::Result;
|
||||
use crossterm::event::{self, Event, KeyCode, KeyEvent, KeyEventKind};
|
||||
use crossterm::event::{self, KeyCode, KeyEvent};
|
||||
use ratatui::buffer::Buffer;
|
||||
use ratatui::layout::{Constraint, Layout, Offset, Rect};
|
||||
use ratatui::style::Stylize;
|
||||
@@ -71,13 +71,12 @@ impl App {
|
||||
}
|
||||
|
||||
fn handle_events(&mut self) -> Result<()> {
|
||||
match event::read()? {
|
||||
Event::Key(event) if event.kind == KeyEventKind::Press => match event.code {
|
||||
if let Some(key) = event::read()?.as_key_press_event() {
|
||||
match key.code {
|
||||
KeyCode::Esc => self.state = AppState::Cancelled,
|
||||
KeyCode::Enter => self.state = AppState::Submitted,
|
||||
_ => self.form.on_key_press(event),
|
||||
},
|
||||
_ => {}
|
||||
_ => self.form.on_key_press(key),
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -11,22 +11,18 @@
|
||||
/// [`latest`]: https://github.com/ratatui/ratatui/tree/latest
|
||||
/// [examples]: https://github.com/ratatui/ratatui/blob/main/examples
|
||||
/// [hello-world]: https://github.com/ratatui/ratatui/blob/main/examples/apps/hello-world
|
||||
use crossterm::event::{self, Event};
|
||||
use crossterm::event;
|
||||
use ratatui::text::Text;
|
||||
use ratatui::Frame;
|
||||
|
||||
fn main() {
|
||||
let mut terminal = ratatui::init();
|
||||
loop {
|
||||
terminal.draw(draw).expect("failed to draw frame");
|
||||
if matches!(event::read().expect("failed to read event"), Event::Key(_)) {
|
||||
terminal
|
||||
.draw(|frame| frame.render_widget(Text::raw("Hello World!"), frame.area()))
|
||||
.expect("failed to draw frame");
|
||||
if event::read().expect("failed to read event").is_key_press() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
ratatui::restore();
|
||||
}
|
||||
|
||||
fn draw(frame: &mut Frame) {
|
||||
let text = Text::raw("Hello World!");
|
||||
frame.render_widget(text, frame.area());
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
/// [`latest`]: https://github.com/ratatui/ratatui/tree/latest
|
||||
use std::{error::Error, iter::once, result};
|
||||
|
||||
use crossterm::event::{self, Event, KeyCode, KeyEventKind};
|
||||
use crossterm::event;
|
||||
use itertools::Itertools;
|
||||
use ratatui::layout::{Constraint, Layout};
|
||||
use ratatui::style::{Color, Modifier, Style, Stylize};
|
||||
@@ -30,16 +30,14 @@ fn main() -> Result<()> {
|
||||
|
||||
fn run(mut terminal: DefaultTerminal) -> Result<()> {
|
||||
loop {
|
||||
terminal.draw(draw)?;
|
||||
if let Event::Key(key) = event::read()? {
|
||||
if key.kind == KeyEventKind::Press && key.code == KeyCode::Char('q') {
|
||||
return Ok(());
|
||||
}
|
||||
terminal.draw(render)?;
|
||||
if event::read()?.is_key_press() {
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn draw(frame: &mut Frame) {
|
||||
fn render(frame: &mut Frame) {
|
||||
let vertical = Layout::vertical([Constraint::Length(1), Constraint::Min(0)]);
|
||||
let [text_area, main_area] = vertical.areas(frame.area());
|
||||
frame.render_widget(
|
||||
|
||||
@@ -60,8 +60,11 @@ impl MouseDrawingApp {
|
||||
}
|
||||
|
||||
/// Quit the app if the user presses 'q' or 'Esc'
|
||||
fn on_key_event(&mut self, event: KeyEvent) {
|
||||
match event.code {
|
||||
fn on_key_event(&mut self, key: KeyEvent) {
|
||||
if !key.is_press() {
|
||||
return;
|
||||
}
|
||||
match key.code {
|
||||
KeyCode::Char(' ') => {
|
||||
self.current_color = Color::Rgb(rand::random(), rand::random(), rand::random());
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
/// [`latest`]: https://github.com/ratatui/ratatui/tree/latest
|
||||
/// [Color Eyre recipe]: https://ratatui.rs/recipes/apps/color-eyre
|
||||
use color_eyre::{eyre::bail, Result};
|
||||
use crossterm::event::{self, Event, KeyCode};
|
||||
use crossterm::event::{self, KeyCode};
|
||||
use ratatui::text::Line;
|
||||
use ratatui::widgets::{Block, Paragraph};
|
||||
use ratatui::{DefaultTerminal, Frame};
|
||||
@@ -53,9 +53,9 @@ impl App {
|
||||
|
||||
fn run(mut self, mut terminal: DefaultTerminal) -> Result<()> {
|
||||
loop {
|
||||
terminal.draw(|frame| self.draw(frame))?;
|
||||
terminal.draw(|frame| self.render(frame))?;
|
||||
|
||||
if let Event::Key(key) = event::read()? {
|
||||
if let Some(key) = event::read()?.as_key_press_event() {
|
||||
match key.code {
|
||||
KeyCode::Char('p') => panic!("intentional demo panic"),
|
||||
KeyCode::Char('e') => bail!("intentional demo error"),
|
||||
@@ -70,7 +70,7 @@ impl App {
|
||||
}
|
||||
}
|
||||
|
||||
fn draw(&self, frame: &mut Frame) {
|
||||
fn render(&self, frame: &mut Frame) {
|
||||
let text = vec![
|
||||
if self.hook_enabled {
|
||||
Line::from("HOOK IS CURRENTLY **ENABLED**")
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
///
|
||||
/// [`latest`]: https://github.com/ratatui/ratatui/tree/latest
|
||||
use color_eyre::Result;
|
||||
use crossterm::event::{self, Event, KeyCode, KeyEventKind};
|
||||
use crossterm::event::{self, KeyCode};
|
||||
use ratatui::layout::{Constraint, Flex, Layout, Rect};
|
||||
use ratatui::style::Stylize;
|
||||
use ratatui::widgets::{Block, Clear, Paragraph, Wrap};
|
||||
@@ -30,21 +30,19 @@ struct App {
|
||||
impl App {
|
||||
fn run(mut self, mut terminal: DefaultTerminal) -> Result<()> {
|
||||
loop {
|
||||
terminal.draw(|frame| self.draw(frame))?;
|
||||
terminal.draw(|frame| self.render(frame))?;
|
||||
|
||||
if let Event::Key(key) = event::read()? {
|
||||
if key.kind == KeyEventKind::Press {
|
||||
match key.code {
|
||||
KeyCode::Char('q') => return Ok(()),
|
||||
KeyCode::Char('p') => self.show_popup = !self.show_popup,
|
||||
_ => {}
|
||||
}
|
||||
if let Some(key) = event::read()?.as_key_press_event() {
|
||||
match key.code {
|
||||
KeyCode::Char('q') => return Ok(()),
|
||||
KeyCode::Char('p') => self.show_popup = !self.show_popup,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn draw(&self, frame: &mut Frame) {
|
||||
fn render(&self, frame: &mut Frame) {
|
||||
let area = frame.area();
|
||||
|
||||
let vertical = Layout::vertical([Constraint::Percentage(20), Constraint::Percentage(80)]);
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
use color_eyre::Result;
|
||||
use crossterm::event::{self, Event, KeyCode};
|
||||
use crossterm::event::{self, KeyCode};
|
||||
use ratatui::layout::{Alignment, Constraint, Layout, Margin};
|
||||
use ratatui::style::{Color, Style, Stylize};
|
||||
use ratatui::symbols::scrollbar;
|
||||
@@ -40,47 +40,52 @@ impl App {
|
||||
let tick_rate = Duration::from_millis(250);
|
||||
let mut last_tick = Instant::now();
|
||||
loop {
|
||||
terminal.draw(|frame| self.draw(frame))?;
|
||||
terminal.draw(|frame| self.render(frame))?;
|
||||
|
||||
let timeout = tick_rate.saturating_sub(last_tick.elapsed());
|
||||
if event::poll(timeout)? {
|
||||
if let Event::Key(key) = event::read()? {
|
||||
match key.code {
|
||||
KeyCode::Char('q') => return Ok(()),
|
||||
KeyCode::Char('j') | KeyCode::Down => {
|
||||
self.vertical_scroll = self.vertical_scroll.saturating_add(1);
|
||||
self.vertical_scroll_state =
|
||||
self.vertical_scroll_state.position(self.vertical_scroll);
|
||||
}
|
||||
KeyCode::Char('k') | KeyCode::Up => {
|
||||
self.vertical_scroll = self.vertical_scroll.saturating_sub(1);
|
||||
self.vertical_scroll_state =
|
||||
self.vertical_scroll_state.position(self.vertical_scroll);
|
||||
}
|
||||
KeyCode::Char('h') | KeyCode::Left => {
|
||||
self.horizontal_scroll = self.horizontal_scroll.saturating_sub(1);
|
||||
self.horizontal_scroll_state = self
|
||||
.horizontal_scroll_state
|
||||
.position(self.horizontal_scroll);
|
||||
}
|
||||
KeyCode::Char('l') | KeyCode::Right => {
|
||||
self.horizontal_scroll = self.horizontal_scroll.saturating_add(1);
|
||||
self.horizontal_scroll_state = self
|
||||
.horizontal_scroll_state
|
||||
.position(self.horizontal_scroll);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
if last_tick.elapsed() >= tick_rate {
|
||||
if !event::poll(timeout)? {
|
||||
last_tick = Instant::now();
|
||||
continue;
|
||||
}
|
||||
if let Some(key) = event::read()?.as_key_press_event() {
|
||||
match key.code {
|
||||
KeyCode::Char('q') => return Ok(()),
|
||||
KeyCode::Char('j') | KeyCode::Down => self.scroll_down(),
|
||||
KeyCode::Char('k') | KeyCode::Up => self.scroll_up(),
|
||||
KeyCode::Char('h') | KeyCode::Left => self.scroll_left(),
|
||||
KeyCode::Char('l') | KeyCode::Right => self.scroll_right(),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn scroll_down(&mut self) {
|
||||
self.vertical_scroll = self.vertical_scroll.saturating_add(1);
|
||||
self.vertical_scroll_state = self.vertical_scroll_state.position(self.vertical_scroll);
|
||||
}
|
||||
|
||||
fn scroll_up(&mut self) {
|
||||
self.vertical_scroll = self.vertical_scroll.saturating_sub(1);
|
||||
self.vertical_scroll_state = self.vertical_scroll_state.position(self.vertical_scroll);
|
||||
}
|
||||
|
||||
fn scroll_left(&mut self) {
|
||||
self.horizontal_scroll = self.horizontal_scroll.saturating_sub(1);
|
||||
self.horizontal_scroll_state = self
|
||||
.horizontal_scroll_state
|
||||
.position(self.horizontal_scroll);
|
||||
}
|
||||
|
||||
fn scroll_right(&mut self) {
|
||||
self.horizontal_scroll = self.horizontal_scroll.saturating_add(1);
|
||||
self.horizontal_scroll_state = self
|
||||
.horizontal_scroll_state
|
||||
.position(self.horizontal_scroll);
|
||||
}
|
||||
|
||||
#[expect(clippy::too_many_lines, clippy::cast_possible_truncation)]
|
||||
fn draw(&mut self, frame: &mut Frame) {
|
||||
fn render(&mut self, frame: &mut Frame) {
|
||||
let area = frame.area();
|
||||
|
||||
// Words made "loooong" to demonstrate line breaking.
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
///
|
||||
/// [`latest`]: https://github.com/ratatui/ratatui/tree/latest
|
||||
use color_eyre::Result;
|
||||
use crossterm::event::{self, Event, KeyCode, KeyEventKind, KeyModifiers};
|
||||
use crossterm::event::{self, KeyCode, KeyModifiers};
|
||||
use itertools::Itertools;
|
||||
use ratatui::layout::{Constraint, Layout, Margin, Rect};
|
||||
use ratatui::style::{self, Color, Modifier, Style, Stylize};
|
||||
@@ -173,29 +173,27 @@ impl App {
|
||||
|
||||
fn run(mut self, mut terminal: DefaultTerminal) -> Result<()> {
|
||||
loop {
|
||||
terminal.draw(|frame| self.draw(frame))?;
|
||||
terminal.draw(|frame| self.render(frame))?;
|
||||
|
||||
if let Event::Key(key) = event::read()? {
|
||||
if key.kind == KeyEventKind::Press {
|
||||
let shift_pressed = key.modifiers.contains(KeyModifiers::SHIFT);
|
||||
match key.code {
|
||||
KeyCode::Char('q') | KeyCode::Esc => return Ok(()),
|
||||
KeyCode::Char('j') | KeyCode::Down => self.next_row(),
|
||||
KeyCode::Char('k') | KeyCode::Up => self.previous_row(),
|
||||
KeyCode::Char('l') | KeyCode::Right if shift_pressed => self.next_color(),
|
||||
KeyCode::Char('h') | KeyCode::Left if shift_pressed => {
|
||||
self.previous_color();
|
||||
}
|
||||
KeyCode::Char('l') | KeyCode::Right => self.next_column(),
|
||||
KeyCode::Char('h') | KeyCode::Left => self.previous_column(),
|
||||
_ => {}
|
||||
if let Some(key) = event::read()?.as_key_press_event() {
|
||||
let shift_pressed = key.modifiers.contains(KeyModifiers::SHIFT);
|
||||
match key.code {
|
||||
KeyCode::Char('q') | KeyCode::Esc => return Ok(()),
|
||||
KeyCode::Char('j') | KeyCode::Down => self.next_row(),
|
||||
KeyCode::Char('k') | KeyCode::Up => self.previous_row(),
|
||||
KeyCode::Char('l') | KeyCode::Right if shift_pressed => self.next_color(),
|
||||
KeyCode::Char('h') | KeyCode::Left if shift_pressed => {
|
||||
self.previous_color();
|
||||
}
|
||||
KeyCode::Char('l') | KeyCode::Right => self.next_column(),
|
||||
KeyCode::Char('h') | KeyCode::Left => self.previous_column(),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn draw(&mut self, frame: &mut Frame) {
|
||||
fn render(&mut self, frame: &mut Frame) {
|
||||
let vertical = &Layout::vertical([Constraint::Min(5), Constraint::Length(4)]);
|
||||
let rects = vertical.split(frame.area());
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
///
|
||||
/// [`latest`]: https://github.com/ratatui/ratatui/tree/latest
|
||||
use color_eyre::Result;
|
||||
use crossterm::event::{self, Event, KeyCode, KeyEvent, KeyEventKind};
|
||||
use crossterm::event::{self, KeyCode, KeyEvent};
|
||||
use ratatui::buffer::Buffer;
|
||||
use ratatui::layout::{Constraint, Layout, Rect};
|
||||
use ratatui::style::palette::tailwind::{BLUE, GREEN, SLATE};
|
||||
@@ -103,7 +103,7 @@ impl App {
|
||||
fn run(mut self, mut terminal: DefaultTerminal) -> Result<()> {
|
||||
while !self.should_exit {
|
||||
terminal.draw(|frame| frame.render_widget(&mut self, frame.area()))?;
|
||||
if let Event::Key(key) = event::read()? {
|
||||
if let Some(key) = event::read()?.as_key_press_event() {
|
||||
self.handle_key(key);
|
||||
}
|
||||
}
|
||||
@@ -111,9 +111,6 @@ impl App {
|
||||
}
|
||||
|
||||
fn handle_key(&mut self, key: KeyEvent) {
|
||||
if key.kind != KeyEventKind::Press {
|
||||
return;
|
||||
}
|
||||
match key.code {
|
||||
KeyCode::Char('q') | KeyCode::Esc => self.should_exit = true,
|
||||
KeyCode::Char('h') | KeyCode::Left => self.select_none(),
|
||||
|
||||
@@ -40,7 +40,7 @@ fn main() -> Result<()> {
|
||||
let mut events = vec![]; // a buffer to store the recent events to display in the UI
|
||||
while !should_exit(&events) {
|
||||
handle_events(&mut events)?;
|
||||
terminal.draw(|frame| draw(frame, &events))?;
|
||||
terminal.draw(|frame| render(frame, &events))?;
|
||||
}
|
||||
ratatui::restore();
|
||||
|
||||
@@ -69,7 +69,7 @@ fn handle_events(events: &mut Vec<Event>) -> Result<()> {
|
||||
}
|
||||
|
||||
#[instrument(skip_all)]
|
||||
fn draw(frame: &mut Frame, events: &[Event]) {
|
||||
fn render(frame: &mut Frame, events: &[Event]) {
|
||||
// To view this event, run the example with `RUST_LOG=tracing=debug cargo run --example tracing`
|
||||
trace!(frame_count = frame.count(), event_count = events.len());
|
||||
let events = events.iter().map(|e| format!("{e:?}")).collect::<Vec<_>>();
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
///
|
||||
/// [`latest`]: https://github.com/ratatui/ratatui/tree/latest
|
||||
use color_eyre::Result;
|
||||
use crossterm::event::{self, Event, KeyCode, KeyEventKind};
|
||||
use crossterm::event::{self, KeyCode, KeyEventKind};
|
||||
use ratatui::layout::{Constraint, Layout, Position};
|
||||
use ratatui::style::{Color, Modifier, Style, Stylize};
|
||||
use ratatui::text::{Line, Span, Text};
|
||||
@@ -129,9 +129,9 @@ impl App {
|
||||
|
||||
fn run(mut self, mut terminal: DefaultTerminal) -> Result<()> {
|
||||
loop {
|
||||
terminal.draw(|frame| self.draw(frame))?;
|
||||
terminal.draw(|frame| self.render(frame))?;
|
||||
|
||||
if let Event::Key(key) = event::read()? {
|
||||
if let Some(key) = event::read()?.as_key_press_event() {
|
||||
match self.input_mode {
|
||||
InputMode::Normal => match key.code {
|
||||
KeyCode::Char('e') => {
|
||||
@@ -157,7 +157,7 @@ impl App {
|
||||
}
|
||||
}
|
||||
|
||||
fn draw(&self, frame: &mut Frame) {
|
||||
fn render(&self, frame: &mut Frame) {
|
||||
let vertical = Layout::vertical([
|
||||
Constraint::Length(1),
|
||||
Constraint::Length(3),
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
//! [`BarChart`]: https://docs.rs/ratatui/latest/ratatui/widgets/struct.BarChart.html
|
||||
|
||||
use color_eyre::Result;
|
||||
use crossterm::event::{self, Event, KeyCode, KeyEventKind};
|
||||
use crossterm::event::{self, KeyCode};
|
||||
use rand::{rng, Rng};
|
||||
use ratatui::layout::{Constraint, Layout};
|
||||
use ratatui::style::{Color, Style, Stylize};
|
||||
@@ -42,22 +42,23 @@ impl App {
|
||||
|
||||
fn run(mut self, mut terminal: DefaultTerminal) -> Result<()> {
|
||||
while !self.should_exit {
|
||||
terminal.draw(|frame| self.draw(frame))?;
|
||||
terminal.draw(|frame| self.render(frame))?;
|
||||
self.handle_events()?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_events(&mut self) -> Result<()> {
|
||||
if let Event::Key(key) = event::read()? {
|
||||
if key.kind == KeyEventKind::Press && key.code == KeyCode::Char('q') {
|
||||
self.should_exit = true;
|
||||
}
|
||||
if event::read()?
|
||||
.as_key_press_event()
|
||||
.is_some_and(|key| key.code == KeyCode::Char('q'))
|
||||
{
|
||||
self.should_exit = true;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn draw(&self, frame: &mut Frame) {
|
||||
fn render(&self, frame: &mut Frame) {
|
||||
let [title, main] = Layout::vertical([Constraint::Length(1), Constraint::Fill(1)])
|
||||
.spacing(1)
|
||||
.areas(frame.area());
|
||||
|
||||
@@ -30,8 +30,8 @@ fn main() -> Result<()> {
|
||||
fn run(mut terminal: DefaultTerminal) -> Result<()> {
|
||||
loop {
|
||||
terminal.draw(render)?;
|
||||
if matches!(event::read()?, event::Event::Key(_)) {
|
||||
break Ok(());
|
||||
if event::read()?.is_key_press() {
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
use core::iter::zip;
|
||||
|
||||
use color_eyre::Result;
|
||||
use crossterm::event::{self, Event};
|
||||
use crossterm::event;
|
||||
use ratatui::layout::{Constraint, Direction, Layout, Rect};
|
||||
use ratatui::style::{Color, Stylize};
|
||||
use ratatui::text::{Line, Span};
|
||||
@@ -35,15 +35,15 @@ fn main() -> Result<()> {
|
||||
/// Run the application.
|
||||
fn run(mut terminal: DefaultTerminal) -> Result<()> {
|
||||
loop {
|
||||
terminal.draw(draw)?;
|
||||
if matches!(event::read()?, Event::Key(_)) {
|
||||
break Ok(());
|
||||
terminal.draw(render)?;
|
||||
if event::read()?.is_key_press() {
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Draw the UI with a barchart on the left and right side.
|
||||
fn draw(frame: &mut Frame) {
|
||||
/// Render the UI with a barchart on the left and right side.
|
||||
fn render(frame: &mut Frame) {
|
||||
let vertical = Layout::vertical([Constraint::Length(1), Constraint::Fill(1)]).spacing(1);
|
||||
let horizontal = Layout::horizontal([Constraint::Fill(1); 2]).spacing(1);
|
||||
let [top, main] = vertical.areas(frame.area());
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
//! [examples readme]: https://github.com/ratatui/ratatui/blob/main/examples/README.md
|
||||
|
||||
use color_eyre::Result;
|
||||
use crossterm::event::{self, Event};
|
||||
use crossterm::event;
|
||||
use ratatui::layout::{Constraint, Layout, Rect};
|
||||
use ratatui::style::Stylize;
|
||||
use ratatui::text::{Line, Span};
|
||||
@@ -33,15 +33,15 @@ fn main() -> Result<()> {
|
||||
/// Run the application.
|
||||
fn run(mut terminal: DefaultTerminal) -> Result<()> {
|
||||
loop {
|
||||
terminal.draw(draw)?;
|
||||
if matches!(event::read()?, Event::Key(_)) {
|
||||
break Ok(());
|
||||
terminal.draw(render)?;
|
||||
if event::read()?.is_key_press() {
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Draw the UI with a title and two barcharts.
|
||||
fn draw(frame: &mut Frame) {
|
||||
/// Render the UI with a title and two barcharts.
|
||||
fn render(frame: &mut Frame) {
|
||||
let vertical = Layout::vertical([Constraint::Length(1), Constraint::Fill(1)]).spacing(1);
|
||||
let horizontal = Layout::horizontal([Constraint::Length(28), Constraint::Fill(1)]).spacing(1);
|
||||
let [top, main] = vertical.areas(frame.area());
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
//! [examples readme]: https://github.com/ratatui/ratatui/blob/main/examples/README.md
|
||||
|
||||
use color_eyre::Result;
|
||||
use crossterm::event::{self, Event};
|
||||
use crossterm::event;
|
||||
use ratatui::layout::{Constraint, Layout, Rect};
|
||||
use ratatui::style::{Style, Stylize};
|
||||
use ratatui::text::{Line, Span};
|
||||
@@ -33,15 +33,15 @@ fn main() -> Result<()> {
|
||||
/// Run the application.
|
||||
fn run(mut terminal: DefaultTerminal) -> Result<()> {
|
||||
loop {
|
||||
terminal.draw(draw)?;
|
||||
if matches!(event::read()?, Event::Key(_)) {
|
||||
break Ok(());
|
||||
terminal.draw(render)?;
|
||||
if event::read()?.is_key_press() {
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Draw the UI with various blocks.
|
||||
fn draw(frame: &mut Frame) {
|
||||
/// Render the UI with various blocks.
|
||||
fn render(frame: &mut Frame) {
|
||||
let vertical = Layout::vertical([Constraint::Length(1), Constraint::Fill(1)]).spacing(1);
|
||||
let horizontal = Layout::horizontal([Constraint::Percentage(33); 3]).spacing(1);
|
||||
let [top, main] = vertical.areas(frame.area());
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
//! [examples readme]: https://github.com/ratatui/ratatui/blob/main/examples/README.md
|
||||
|
||||
use color_eyre::Result;
|
||||
use crossterm::event::{self, Event};
|
||||
use crossterm::event;
|
||||
use ratatui::layout::{Constraint, Layout, Rect};
|
||||
use ratatui::style::{Color, Modifier, Style, Stylize};
|
||||
use ratatui::text::{Line, Span};
|
||||
@@ -35,15 +35,15 @@ fn main() -> Result<()> {
|
||||
/// Run the application.
|
||||
fn run(mut terminal: DefaultTerminal) -> Result<()> {
|
||||
loop {
|
||||
terminal.draw(draw)?;
|
||||
if matches!(event::read()?, Event::Key(_)) {
|
||||
break Ok(());
|
||||
terminal.draw(render)?;
|
||||
if event::read()?.is_key_press() {
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Draw the UI with 2 monthly calendars side by side.
|
||||
fn draw(frame: &mut Frame) {
|
||||
/// Render the UI with 2 monthly calendars side by side.
|
||||
fn render(frame: &mut Frame) {
|
||||
let vertical = Layout::vertical([Constraint::Length(1), Constraint::Fill(1)]).spacing(1);
|
||||
let horizontal = Layout::horizontal([Constraint::Percentage(50); 2]).spacing(1);
|
||||
let [top, main] = vertical.areas(frame.area());
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
//! [examples readme]: https://github.com/ratatui/ratatui/blob/main/examples/README.md
|
||||
|
||||
use color_eyre::Result;
|
||||
use crossterm::event::{self, Event};
|
||||
use crossterm::event;
|
||||
use ratatui::layout::{Constraint, Layout, Rect};
|
||||
use ratatui::style::{Color, Stylize};
|
||||
use ratatui::symbols::Marker;
|
||||
@@ -35,15 +35,15 @@ fn main() -> Result<()> {
|
||||
/// Run the application.
|
||||
fn run(mut terminal: DefaultTerminal) -> Result<()> {
|
||||
loop {
|
||||
terminal.draw(draw)?;
|
||||
if matches!(event::read()?, Event::Key(_)) {
|
||||
break Ok(());
|
||||
terminal.draw(render)?;
|
||||
if event::read()?.is_key_press() {
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Draw the UI with a canvas widget.
|
||||
fn draw(frame: &mut Frame) {
|
||||
/// Render the UI with a canvas widget.
|
||||
fn render(frame: &mut Frame) {
|
||||
let vertical = Layout::vertical([Constraint::Length(1), Constraint::Fill(1)]).spacing(1);
|
||||
let horizontal = Layout::horizontal([Constraint::Percentage(100)]).spacing(1);
|
||||
let [top, main] = vertical.areas(frame.area());
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
//! [examples readme]: https://github.com/ratatui/ratatui/blob/main/examples/README.md
|
||||
|
||||
use color_eyre::Result;
|
||||
use crossterm::event::{self, Event};
|
||||
use crossterm::event;
|
||||
use ratatui::layout::{Constraint, Layout, Rect};
|
||||
use ratatui::style::{Color, Stylize};
|
||||
use ratatui::symbols::Marker;
|
||||
@@ -34,15 +34,15 @@ fn main() -> Result<()> {
|
||||
/// Run the application.
|
||||
fn run(mut terminal: DefaultTerminal) -> Result<()> {
|
||||
loop {
|
||||
terminal.draw(draw)?;
|
||||
if matches!(event::read()?, Event::Key(_)) {
|
||||
break Ok(());
|
||||
terminal.draw(render)?;
|
||||
if event::read()?.is_key_press() {
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Draw the UI with a chart.
|
||||
fn draw(frame: &mut Frame) {
|
||||
/// Render the UI with a chart.
|
||||
fn render(frame: &mut Frame) {
|
||||
let vertical = Layout::vertical([Constraint::Length(1), Constraint::Fill(1)]).spacing(1);
|
||||
let [top, main] = vertical.areas(frame.area());
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
//! [examples readme]: https://github.com/ratatui/ratatui/blob/main/examples/README.md
|
||||
|
||||
use color_eyre::Result;
|
||||
use crossterm::event::{self, Event};
|
||||
use crossterm::event;
|
||||
use ratatui::layout::{Constraint, Layout, Rect};
|
||||
use ratatui::style::{Modifier, Style, Stylize};
|
||||
use ratatui::text::{Line, Span};
|
||||
@@ -33,15 +33,15 @@ fn main() -> Result<()> {
|
||||
/// Run the application.
|
||||
fn run(mut terminal: DefaultTerminal) -> Result<()> {
|
||||
loop {
|
||||
terminal.draw(draw)?;
|
||||
if matches!(event::read()?, Event::Key(_)) {
|
||||
break Ok(());
|
||||
terminal.draw(render)?;
|
||||
if event::read()?.is_key_press() {
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Draw the UI with various progress bars.
|
||||
fn draw(frame: &mut Frame) {
|
||||
/// Render the UI with various progress bars.
|
||||
fn render(frame: &mut Frame) {
|
||||
let vertical = Layout::vertical([
|
||||
Constraint::Length(1),
|
||||
Constraint::Max(2),
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
use core::time::Duration;
|
||||
|
||||
use color_eyre::Result;
|
||||
use crossterm::event::{self, Event, KeyCode, KeyEventKind};
|
||||
use crossterm::event::{self, KeyCode};
|
||||
use ratatui::buffer::Buffer;
|
||||
use ratatui::layout::Constraint::{Length, Min};
|
||||
use ratatui::layout::{Layout, Rect};
|
||||
@@ -71,27 +71,26 @@ impl App {
|
||||
fn handle_events(&mut self) -> Result<()> {
|
||||
let timeout = Duration::from_secs_f32(1.0 / 20.0);
|
||||
if event::poll(timeout)? {
|
||||
if let Event::Key(key) = event::read()? {
|
||||
if key.kind == KeyEventKind::Press {
|
||||
match key.code {
|
||||
KeyCode::Char(' ') => {
|
||||
// toggle start / stop
|
||||
if self.state == AppState::Stop {
|
||||
self.state = AppState::Start;
|
||||
} else {
|
||||
self.state = AppState::Stop;
|
||||
}
|
||||
}
|
||||
KeyCode::Char('r') => self.reset(),
|
||||
KeyCode::Char('q') => self.state = AppState::Quit,
|
||||
_ => {}
|
||||
}
|
||||
if let Some(key) = event::read()?.as_key_press_event() {
|
||||
match key.code {
|
||||
KeyCode::Char(' ') => self.toggle_start(),
|
||||
KeyCode::Char('r') => self.reset(),
|
||||
KeyCode::Char('q') => self.state = AppState::Quit,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn toggle_start(&mut self) {
|
||||
self.state = if self.state == AppState::Start {
|
||||
AppState::Stop
|
||||
} else {
|
||||
AppState::Start
|
||||
};
|
||||
}
|
||||
|
||||
const fn reset(&mut self) {
|
||||
self.progress = 0.0;
|
||||
self.progress_columns = 0;
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
//! [examples readme]: https://github.com/ratatui/ratatui/blob/main/examples/README.md
|
||||
|
||||
use color_eyre::Result;
|
||||
use crossterm::event::{self, Event, KeyCode};
|
||||
use crossterm::event::{self, KeyCode};
|
||||
use ratatui::layout::{Constraint, Layout, Rect};
|
||||
use ratatui::style::{Color, Modifier, Style, Stylize};
|
||||
use ratatui::text::{Line, Span};
|
||||
@@ -32,23 +32,22 @@ fn main() -> Result<()> {
|
||||
|
||||
/// Run the application.
|
||||
fn run(mut terminal: DefaultTerminal) -> Result<()> {
|
||||
let mut list_state = ListState::default();
|
||||
list_state.select_first();
|
||||
let mut list_state = ListState::default().with_selected(Some(0));
|
||||
loop {
|
||||
terminal.draw(|frame| draw(frame, &mut list_state))?;
|
||||
if let Event::Key(key) = event::read()? {
|
||||
terminal.draw(|frame| render(frame, &mut list_state))?;
|
||||
if let Some(key) = event::read()?.as_key_press_event() {
|
||||
match key.code {
|
||||
KeyCode::Char('q') => break Ok(()),
|
||||
KeyCode::Down | KeyCode::Char('j') => list_state.select_next(),
|
||||
KeyCode::Up | KeyCode::Char('k') => list_state.select_previous(),
|
||||
KeyCode::Char('j') | KeyCode::Down => list_state.select_next(),
|
||||
KeyCode::Char('k') | KeyCode::Up => list_state.select_previous(),
|
||||
KeyCode::Char('q') | KeyCode::Esc => return Ok(()),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Draw the UI with various lists.
|
||||
fn draw(frame: &mut Frame, list_state: &mut ListState) {
|
||||
/// Render the UI with various lists.
|
||||
fn render(frame: &mut Frame, list_state: &mut ListState) {
|
||||
let vertical = Layout::vertical([
|
||||
Constraint::Length(1),
|
||||
Constraint::Fill(1),
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
use std::env::args;
|
||||
|
||||
use color_eyre::Result;
|
||||
use crossterm::event::{self, Event};
|
||||
use crossterm::event;
|
||||
use ratatui::layout::{Constraint, Layout};
|
||||
use ratatui::widgets::{RatatuiLogo, RatatuiLogoSize};
|
||||
use ratatui::{DefaultTerminal, Frame, TerminalOptions, Viewport};
|
||||
@@ -41,15 +41,15 @@ fn main() -> Result<()> {
|
||||
/// Run the application.
|
||||
fn run(mut terminal: DefaultTerminal, size: RatatuiLogoSize) -> Result<()> {
|
||||
loop {
|
||||
terminal.draw(|frame| draw(frame, size))?;
|
||||
if matches!(event::read()?, Event::Key(_)) {
|
||||
break Ok(());
|
||||
terminal.draw(|frame| render(frame, size))?;
|
||||
if event::read()?.is_key_press() {
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Draw the UI with a logo.
|
||||
fn draw(frame: &mut Frame, size: RatatuiLogoSize) {
|
||||
/// Render the UI with a logo.
|
||||
fn render(frame: &mut Frame, size: RatatuiLogoSize) {
|
||||
let [top, bottom] =
|
||||
Layout::vertical([Constraint::Length(1), Constraint::Fill(1)]).areas(frame.area());
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
//! [examples readme]: https://github.com/ratatui/ratatui/blob/main/examples/README.md
|
||||
|
||||
use color_eyre::Result;
|
||||
use crossterm::event::{self, Event};
|
||||
use crossterm::event;
|
||||
use ratatui::layout::{Alignment, Constraint, Layout, Rect};
|
||||
use ratatui::style::{Color, Stylize};
|
||||
use ratatui::text::{Line, Masked, Span};
|
||||
@@ -33,15 +33,15 @@ fn main() -> Result<()> {
|
||||
/// Run the application.
|
||||
fn run(mut terminal: DefaultTerminal) -> Result<()> {
|
||||
loop {
|
||||
terminal.draw(draw)?;
|
||||
if matches!(event::read()?, Event::Key(_)) {
|
||||
break Ok(());
|
||||
terminal.draw(render)?;
|
||||
if event::read()?.is_key_press() {
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Draw the UI with various text.
|
||||
fn draw(frame: &mut Frame) {
|
||||
/// Render the UI with various text.
|
||||
fn render(frame: &mut Frame) {
|
||||
let vertical = Layout::vertical([Constraint::Length(1), Constraint::Fill(1)]).spacing(1);
|
||||
let horizontal = Layout::horizontal([Constraint::Percentage(50); 2]).spacing(1);
|
||||
let [top, main] = vertical.areas(frame.area());
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
//! [examples readme]: https://github.com/ratatui/ratatui/blob/main/examples/README.md
|
||||
|
||||
use color_eyre::Result;
|
||||
use crossterm::event::{self, Event, KeyCode};
|
||||
use crossterm::event::{self, KeyCode};
|
||||
use ratatui::layout::{Constraint, Layout, Margin, Rect};
|
||||
use ratatui::style::{Color, Stylize};
|
||||
use ratatui::symbols::scrollbar::Set;
|
||||
@@ -36,22 +36,22 @@ fn run(mut terminal: DefaultTerminal) -> Result<()> {
|
||||
let mut vertical = ScrollbarState::new(100);
|
||||
let mut horizontal = ScrollbarState::new(100);
|
||||
loop {
|
||||
terminal.draw(|frame| draw(frame, &mut vertical, &mut horizontal))?;
|
||||
if let Event::Key(key) = event::read()? {
|
||||
terminal.draw(|frame| render(frame, &mut vertical, &mut horizontal))?;
|
||||
if let Some(key) = event::read()?.as_key_press_event() {
|
||||
match key.code {
|
||||
KeyCode::Char('q') => break Ok(()),
|
||||
KeyCode::Down | KeyCode::Char('j') => vertical.next(),
|
||||
KeyCode::Up | KeyCode::Char('k') => vertical.prev(),
|
||||
KeyCode::Right | KeyCode::Char('l') => horizontal.next(),
|
||||
KeyCode::Left | KeyCode::Char('h') => horizontal.prev(),
|
||||
KeyCode::Char('q') | KeyCode::Esc => return Ok(()),
|
||||
KeyCode::Char('j') | KeyCode::Down => vertical.next(),
|
||||
KeyCode::Char('k') | KeyCode::Up => vertical.prev(),
|
||||
KeyCode::Char('l') | KeyCode::Right => horizontal.next(),
|
||||
KeyCode::Char('h') | KeyCode::Left => horizontal.prev(),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Draw the UI with vertical/horizontal scrollbars.
|
||||
fn draw(frame: &mut Frame, vertical: &mut ScrollbarState, horizontal: &mut ScrollbarState) {
|
||||
/// Render the UI with vertical/horizontal scrollbars.
|
||||
fn render(frame: &mut Frame, vertical: &mut ScrollbarState, horizontal: &mut ScrollbarState) {
|
||||
let vertical_layout = Layout::vertical([Constraint::Length(1), Constraint::Fill(1)]).spacing(1);
|
||||
let [top, main] = vertical_layout.areas(frame.area());
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
use core::time::Duration;
|
||||
|
||||
use color_eyre::Result;
|
||||
use crossterm::event::{self, Event};
|
||||
use crossterm::event;
|
||||
use ratatui::layout::{Constraint, Layout, Rect};
|
||||
use ratatui::style::{Color, Style, Stylize};
|
||||
use ratatui::text::{Line, Span};
|
||||
@@ -35,23 +35,26 @@ fn main() -> Result<()> {
|
||||
/// Run the application.
|
||||
fn run(mut terminal: DefaultTerminal) -> Result<()> {
|
||||
loop {
|
||||
terminal.draw(draw)?;
|
||||
if event::poll(Duration::from_millis(16))? && matches!(event::read()?, Event::Key(_)) {
|
||||
break Ok(());
|
||||
terminal.draw(render)?;
|
||||
// Ensure that the animations renders at 50 FPS (GIF speed)
|
||||
if !event::poll(Duration::from_secs_f64(1.0 / 50.0))? {
|
||||
continue;
|
||||
}
|
||||
if event::read()?.is_key_press() {
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Draw the UI with various sparklines.
|
||||
fn draw(frame: &mut Frame) {
|
||||
let vertical = Layout::vertical([
|
||||
/// Render the UI with various sparklines.
|
||||
fn render(frame: &mut Frame) {
|
||||
let constraints = [
|
||||
Constraint::Length(1),
|
||||
Constraint::Max(2),
|
||||
Constraint::Fill(1),
|
||||
Constraint::Fill(1),
|
||||
])
|
||||
.spacing(1);
|
||||
let [top, first, second, _] = vertical.areas(frame.area());
|
||||
];
|
||||
let [top, first, second, _] = Layout::vertical(constraints).spacing(1).areas(frame.area());
|
||||
|
||||
let title = Line::from_iter([
|
||||
Span::from("Sparkline Widget").bold(),
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
//! [examples readme]: https://github.com/ratatui/ratatui/blob/main/examples/README.md
|
||||
|
||||
use color_eyre::Result;
|
||||
use crossterm::event::{self, Event, KeyCode};
|
||||
use crossterm::event::{self, KeyCode};
|
||||
use ratatui::layout::{Constraint, Layout, Rect};
|
||||
use ratatui::style::{Color, Style, Stylize};
|
||||
use ratatui::text::{Line, Span};
|
||||
@@ -36,22 +36,24 @@ fn run(mut terminal: DefaultTerminal) -> Result<()> {
|
||||
table_state.select_first();
|
||||
table_state.select_first_column();
|
||||
loop {
|
||||
terminal.draw(|frame| draw(frame, &mut table_state))?;
|
||||
if let Event::Key(key) = event::read()? {
|
||||
terminal.draw(|frame| render(frame, &mut table_state))?;
|
||||
if let Some(key) = event::read()?.as_key_press_event() {
|
||||
match key.code {
|
||||
KeyCode::Char('q') => break Ok(()),
|
||||
KeyCode::Down | KeyCode::Char('j') => table_state.select_next(),
|
||||
KeyCode::Up | KeyCode::Char('k') => table_state.select_previous(),
|
||||
KeyCode::Right | KeyCode::Char('l') => table_state.select_next_column(),
|
||||
KeyCode::Left | KeyCode::Char('h') => table_state.select_previous_column(),
|
||||
KeyCode::Char('q') | KeyCode::Esc => return Ok(()),
|
||||
KeyCode::Char('j') | KeyCode::Down => table_state.select_next(),
|
||||
KeyCode::Char('k') | KeyCode::Up => table_state.select_previous(),
|
||||
KeyCode::Char('l') | KeyCode::Right => table_state.select_next_column(),
|
||||
KeyCode::Char('h') | KeyCode::Left => table_state.select_previous_column(),
|
||||
KeyCode::Char('g') => table_state.select_first(),
|
||||
KeyCode::Char('G') => table_state.select_last(),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Draw the UI with a table.
|
||||
fn draw(frame: &mut Frame, table_state: &mut TableState) {
|
||||
/// Render the UI with a table.
|
||||
fn render(frame: &mut Frame, table_state: &mut TableState) {
|
||||
let vertical = Layout::vertical([Constraint::Length(1), Constraint::Fill(1)]).spacing(1);
|
||||
let [top, main] = vertical.areas(frame.area());
|
||||
|
||||
@@ -66,6 +68,10 @@ fn draw(frame: &mut Frame, table_state: &mut TableState) {
|
||||
|
||||
/// Render a table with some rows and columns.
|
||||
pub fn render_table(frame: &mut Frame, area: Rect, table_state: &mut TableState) {
|
||||
let header = Row::new(["Ingredient", "Quantity", "Macros"])
|
||||
.style(Style::new().bold())
|
||||
.bottom_margin(1);
|
||||
|
||||
let rows = [
|
||||
Row::new(["Eggplant", "1 medium", "25 kcal, 6g carbs, 1g protein"]),
|
||||
Row::new(["Tomato", "2 large", "44 kcal, 10g carbs, 2g protein"]),
|
||||
@@ -73,27 +79,19 @@ pub fn render_table(frame: &mut Frame, area: Rect, table_state: &mut TableState)
|
||||
Row::new(["Bell Pepper", "1 medium", "24 kcal, 6g carbs, 1g protein"]),
|
||||
Row::new(["Garlic", "2 cloves", "9 kcal, 2g carbs, 0.4g protein"]),
|
||||
];
|
||||
|
||||
let footer = Row::new([
|
||||
"Ratatouille Recipe",
|
||||
"",
|
||||
"135 kcal, 31g carbs, 6.4g protein",
|
||||
]);
|
||||
let widths = [
|
||||
Constraint::Percentage(30),
|
||||
Constraint::Percentage(20),
|
||||
Constraint::Percentage(50),
|
||||
];
|
||||
|
||||
let table = Table::new(rows, widths)
|
||||
.header(
|
||||
Row::new(["Ingredient", "Quantity", "Macros"])
|
||||
.style(Style::new().bold())
|
||||
.bottom_margin(1),
|
||||
)
|
||||
.footer(
|
||||
Row::new([
|
||||
"Ratatouille Recipe",
|
||||
"",
|
||||
"135 kcal, 31g carbs, 6.4g protein",
|
||||
])
|
||||
.italic(),
|
||||
)
|
||||
.header(header)
|
||||
.footer(footer.italic())
|
||||
.column_spacing(1)
|
||||
.style(Color::White)
|
||||
.row_highlight_style(Style::new().on_black().bold())
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
//! [examples readme]: https://github.com/ratatui/ratatui/blob/main/examples/README.md
|
||||
|
||||
use color_eyre::Result;
|
||||
use crossterm::event::{self, Event, KeyCode};
|
||||
use crossterm::event::{self, KeyCode};
|
||||
use ratatui::layout::{Alignment, Constraint, Layout, Offset, Rect};
|
||||
use ratatui::style::{Color, Style, Stylize};
|
||||
use ratatui::text::{Line, Span};
|
||||
@@ -34,22 +34,22 @@ fn main() -> Result<()> {
|
||||
fn run(mut terminal: DefaultTerminal) -> Result<()> {
|
||||
let mut selected_tab = 0;
|
||||
loop {
|
||||
terminal.draw(|frame| draw(frame, selected_tab))?;
|
||||
if let Event::Key(key) = event::read()? {
|
||||
terminal.draw(|frame| render(frame, selected_tab))?;
|
||||
if let Some(key) = event::read()?.as_key_press_event() {
|
||||
match key.code {
|
||||
KeyCode::Char('q') => break Ok(()),
|
||||
KeyCode::Right | KeyCode::Char('l') | KeyCode::Tab => {
|
||||
KeyCode::Char('l') | KeyCode::Right | KeyCode::Tab => {
|
||||
selected_tab = (selected_tab + 1) % 3;
|
||||
}
|
||||
KeyCode::Left | KeyCode::Char('h') => selected_tab = (selected_tab + 2) % 3,
|
||||
KeyCode::Char('h') | KeyCode::Left => selected_tab = (selected_tab + 2) % 3,
|
||||
KeyCode::Char('q') | KeyCode::Esc => return Ok(()),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Draw the UI with tabs.
|
||||
fn draw(frame: &mut Frame, selected_tab: usize) {
|
||||
/// Render the UI with tabs.
|
||||
fn render(frame: &mut Frame, selected_tab: usize) {
|
||||
let vertical = Layout::vertical([Constraint::Length(1), Constraint::Fill(1)]).spacing(1);
|
||||
let [top, main] = vertical.areas(frame.area());
|
||||
|
||||
|
||||
Reference in New Issue
Block a user