Add tabs to the cockpit
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful

This commit is contained in:
Isaac Mills 2025-07-20 00:44:28 -06:00
parent 852fba7b05
commit 6cac22c9d8
Signed by: fnmain
GPG key ID: B67D7410F33A0F61
4 changed files with 73 additions and 7 deletions

View file

@ -36,3 +36,6 @@ wasm-bindgen-test = "0.3.34"
# Tell `rustc` to optimize for small code size. # Tell `rustc` to optimize for small code size.
opt-level = "s" opt-level = "s"
[dependencies]
web-time = "1.1.0"

View file

@ -2,13 +2,17 @@
use ratzilla::ratatui; use ratzilla::ratatui;
use ratatui::{ use ratatui::{
layout::{Constraint, Direction, Layout},
style::{Color, Stylize}, style::{Color, Stylize},
widgets::{Block, Borders, Paragraph}, widgets::{Block, Borders, Paragraph, Tabs},
Frame, Frame,
}; };
use web_time::Instant;
#[derive(Default)] pub struct App {
pub struct App {} transition_instant: Instant,
selected_tab: usize,
}
const SPLASH: &str = r#" const SPLASH: &str = r#"
!~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ !~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -37,14 +41,55 @@ YJJJJJJJJJ????????????77777777777!!!!!!!!!!!~~~~~~
YJJJJJJJJJJJ???????????77777777777!!!!!!!!!!!~~~~~ YJJJJJJJJJJJ???????????77777777777!!!!!!!!!!!~~~~~
"#; "#;
const TABS: [&'static str; 3] = ["Whatzahoozits", "Thingamajigs", "Doohickeys"];
impl App { impl App {
pub fn new() -> Self {
Self {
transition_instant: Instant::now(),
selected_tab: 0,
}
}
pub fn draw(&mut self, frame: &mut Frame) { pub fn draw(&mut self, frame: &mut Frame) {
let layout = Layout::new(
Direction::Vertical,
[Constraint::Length(3), Constraint::Min(0)],
)
.split(frame.area());
frame.render_widget(
Tabs::new(TABS)
.select(self.selected_tab)
.fg(Color::Rgb(226, 190, 89))
.bg(Color::Black)
.block(Block::new().borders(Borders::all()).title("Coming soon")),
layout[0],
);
frame.render_widget( frame.render_widget(
Paragraph::new(SPLASH) Paragraph::new(SPLASH)
.alignment(ratatui::layout::Alignment::Center) .alignment(ratatui::layout::Alignment::Center)
.fg(Color::Rgb(226, 190, 89)) .fg(Color::Rgb(226, 190, 89))
.block(Block::new().borders(Borders::all()).title("Coming soon")), .bg(Color::Black)
frame.area(), .block(Block::new().borders(Borders::all())),
layout[1],
); );
} }
pub fn next_tab(&mut self) {
self.transition_instant = Instant::now();
if self.selected_tab == TABS.len() - 1 {
self.selected_tab = 0;
} else {
self.selected_tab += 1;
}
}
pub fn prev_tab(&mut self) {
self.transition_instant = Instant::now();
if self.selected_tab == 0 {
self.selected_tab = TABS.len() - 1;
} else {
self.selected_tab -= 1;
}
}
} }

View file

@ -5,7 +5,7 @@ use thecockpit::app::App;
fn main() { fn main() {
let mut terminal = ratatui::init(); let mut terminal = ratatui::init();
let mut app = App::default(); let mut app = App::new();
loop { loop {
terminal.draw(|frame| app.draw(frame)); terminal.draw(|frame| app.draw(frame));
@ -16,6 +16,14 @@ fn main() {
code: event::KeyCode::Char('q'), code: event::KeyCode::Char('q'),
.. ..
}) => break, }) => break,
event::Event::Key(event::KeyEvent {
code: event::KeyCode::Left,
..
}) => app.prev_tab(),
event::Event::Key(event::KeyEvent {
code: event::KeyCode::Right,
..
}) => app.next_tab(),
_ => {} _ => {}
} }
} }

View file

@ -2,6 +2,7 @@ use std::{cell::RefCell, rc::Rc};
use ratzilla::{ use ratzilla::{
backend::canvas::CanvasBackendOptions, backend::canvas::CanvasBackendOptions,
event::KeyCode,
ratatui::{ ratatui::{
widgets::{Block, Borders}, widgets::{Block, Borders},
Terminal, Terminal,
@ -31,7 +32,16 @@ pub fn run(grid_id: &str) {
.unwrap(); .unwrap();
let terminal = Terminal::new(backend).unwrap(); let terminal = Terminal::new(backend).unwrap();
let app = Rc::new(RefCell::new(App::default())); let app = Rc::new(RefCell::new(App::new()));
terminal.on_key_event({
let app = Rc::clone(&app);
move |event| match event.code {
KeyCode::Left => app.borrow_mut().prev_tab(),
KeyCode::Right => app.borrow_mut().next_tab(),
_ => {}
}
});
terminal.draw_web({ terminal.draw_web({
let app = Rc::clone(&app); let app = Rc::clone(&app);