modifiers.rs
1 use embedded_graphics_simulator::{ 2 OutputSettings, SimulatorDisplay, SimulatorEvent, Window, sdl2::Keycode, 3 }; 4 use mousefood::{embedded_graphics::geometry, error::Error, prelude::*}; 5 use ratatui::{ 6 Frame, Terminal, 7 backend::Backend, 8 style::*, 9 widgets::{Block, Paragraph, Wrap}, 10 }; 11 use std::{cell::RefCell, rc::Rc}; 12 13 fn main() -> Result<(), Error> { 14 let mut simulator_window = Window::new( 15 "mousefood simulator", 16 &OutputSettings { 17 scale: 4, 18 ..Default::default() 19 }, 20 ); 21 simulator_window.set_max_fps(30); 22 23 let mut display = SimulatorDisplay::<Bgr565>::new(geometry::Size::new(128, 64)); 24 25 let events: Rc<RefCell<Vec<SimulatorEvent>>> = Rc::new(RefCell::new(Vec::new())); 26 let events_cb = events.clone(); 27 28 let backend_config = EmbeddedBackendConfig { 29 flush_callback: Box::new(move |display| { 30 simulator_window.update(display); 31 let mut ev = events_cb.borrow_mut(); 32 ev.clear(); 33 ev.extend(simulator_window.events()); 34 }), 35 color_theme: ColorTheme::tokyo_night(), 36 ..Default::default() 37 }; 38 let backend: EmbeddedBackend<SimulatorDisplay<_>, _> = 39 EmbeddedBackend::new(&mut display, backend_config); 40 41 let mut terminal = Terminal::new(backend)?; 42 let mut cursor_x: u16 = 1; 43 let mut cursor_y: u16 = 1; 44 45 loop { 46 terminal.draw(|frame| draw(frame, cursor_x, cursor_y))?; 47 48 for event in events.borrow().iter() { 49 match event { 50 SimulatorEvent::KeyDown { keycode, .. } => match *keycode { 51 Keycode::Up | Keycode::W => { 52 cursor_y = cursor_y.saturating_sub(1); 53 } 54 Keycode::Down | Keycode::S => { 55 cursor_y = cursor_y.saturating_add(1); 56 } 57 Keycode::Left | Keycode::A => { 58 cursor_x = cursor_x.saturating_sub(1); 59 } 60 Keycode::Right | Keycode::D => { 61 cursor_x = cursor_x.saturating_add(1); 62 } 63 _ => {} 64 }, 65 SimulatorEvent::Quit => return Ok(()), 66 _ => {} 67 } 68 } 69 70 if let Ok(size) = terminal.backend_mut().size() { 71 cursor_x = cursor_x.min(size.width.saturating_sub(1)); 72 cursor_y = cursor_y.min(size.height.saturating_sub(1)); 73 } 74 } 75 } 76 77 fn draw(frame: &mut Frame, cursor_x: u16, cursor_y: u16) { 78 use ratatui::{ 79 style::Modifier, 80 text::{Line, Span}, 81 }; 82 83 let line = Line::from(vec![ 84 Span::styled(format!("F:{} ", frame.count()), Style::new().yellow()), 85 Span::styled("RED ", Style::new().fg(Color::Red)), 86 Span::styled( 87 "DIM ", 88 Style::new().fg(Color::Red).add_modifier(Modifier::DIM), 89 ), 90 Span::styled("UNDR ", Style::new().add_modifier(Modifier::UNDERLINED)), 91 Span::styled("SLOW ", Style::new().add_modifier(Modifier::SLOW_BLINK)), 92 Span::styled("FAST ", Style::new().add_modifier(Modifier::RAPID_BLINK)), 93 Span::styled("REV ", Style::new().add_modifier(Modifier::REVERSED)), 94 Span::styled("HIDE ", Style::new().add_modifier(Modifier::HIDDEN)), 95 Span::styled("XOUT ", Style::new().add_modifier(Modifier::CROSSED_OUT)), 96 Span::styled( 97 "D+U ", 98 Style::new().add_modifier(Modifier::DIM | Modifier::UNDERLINED), 99 ), 100 // combos 101 Span::styled( 102 "GHOST ", 103 Style::new() 104 .fg(Color::DarkGray) 105 .add_modifier(Modifier::DIM | Modifier::ITALIC), 106 ), 107 Span::styled( 108 "ALARM ", 109 Style::new() 110 .fg(Color::Red) 111 .add_modifier(Modifier::RAPID_BLINK | Modifier::REVERSED), 112 ), 113 Span::styled( 114 "DEAD ", 115 Style::new() 116 .fg(Color::Gray) 117 .add_modifier(Modifier::CROSSED_OUT | Modifier::DIM), 118 ), 119 Span::styled( 120 "SHOUT ", 121 Style::new() 122 .fg(Color::Yellow) 123 .add_modifier(Modifier::BOLD | Modifier::UNDERLINED), 124 ), 125 Span::styled( 126 "HAUNT ", 127 Style::new() 128 .fg(Color::Magenta) 129 .add_modifier(Modifier::SLOW_BLINK | Modifier::DIM), 130 ), 131 Span::styled( 132 "CRIT", 133 Style::new() 134 .fg(Color::White) 135 .bg(Color::Red) 136 .add_modifier(Modifier::BOLD | Modifier::RAPID_BLINK), 137 ), 138 ]); 139 140 let paragraph = Paragraph::new(vec![line]).wrap(Wrap { trim: true }); 141 let bordered_block = Block::bordered() 142 .border_style(Style::new().yellow()) 143 .title("Mods"); 144 frame.render_widget(paragraph.block(bordered_block), frame.area()); 145 frame.set_cursor_position((cursor_x, cursor_y)); 146 }