use crate::prelude::*; //let render_with_actions = |actions| |state, frame: &mut Frame| { //let layout = Layout::default() //.direction(Direction::Horizontal) //.constraints(vec![ //Constraint::Percentage(30), //Constraint::Percentage(70), //]) //.split(frame.size()); //frame.render_widget_ref(ActionBar(actions), layout[0]); //frame.render_widget_ref(state, layout[1]); //Ok(()) //}; pub struct ActionBar<'a>(pub &'a [(&'static str, &'static str)]); impl<'a> WidgetRef for ActionBar<'a> { fn render_ref (&self, area: Rect, buf: &mut Buffer) { let layout = Layout::default() .direction(Direction::Vertical) .constraints(self.0.iter().map(|_|Constraint::Length(3)).collect::>()) .split(area); for (index, action) in self.0.iter().enumerate() { Line::raw(action.0).render(layout[index], buf); } } } pub fn draw_leaf (buffer: &mut Buffer, area: Rect, y: u16, x: u16, text: &str) { use ratatui::style::{Style, Stylize}; let border = Style::default().gray().dim(); let label = Style::default(); let side = String::from("│"); let bottom = format!("╰{}╯", "─".repeat(text.len() as usize)); buffer.set_string(area.x + x, area.y + y, &side, border); buffer.set_string(area.x + x + 1, area.y + y, format!("{text}"), label); buffer.set_string(area.x + x + text.len() as u16 + 1, area.y + y, &side, border); buffer.set_string(area.x + x, area.y + 1 + y, bottom, border); } pub fn draw_box (buffer: &mut Buffer, area: Rect) { use ratatui::style::{Style, Stylize}; let border = Style::default().gray().dim(); let top = format!("╭{}╮", "─".repeat((area.width - 2).into())); let bottom = format!("╰{}╯", "─".repeat((area.width - 2).into())); buffer.set_string(area.x, area.y, top, border); for y in (area.y + 1)..(area.y + area.height - 1) { buffer.set_string(area.x, y, format!("│"), border); buffer.set_string(area.x + area.width - 1, y, format!("│"), border); } buffer.set_string(area.x, area.y + area.height - 1, bottom, border); } pub fn draw_focus_corners (buffer: &mut Buffer, area: Rect) { use ratatui::style::{Style, Stylize}; let focus = Style::default().yellow().bold().not_dim(); buffer.set_string(area.x, area.y, "╭", focus); buffer.set_string(area.x + area.width - 1, area.y, "╮", focus); buffer.set_string(area.x, area.y + area.height - 1, "╰", focus); buffer.set_string(area.x + area.width - 1, area.y + area.height - 1, "╯", focus); } pub fn render_toolbar_vertical ( stdout: &mut std::io::Stdout, offset: (u16, u16), actions: &[(&str, &str)], ) -> Result<(u16, u16), Box> { let move_to = |col, row| MoveTo(offset.0 + col, offset.1 + row); let mut x: u16 = 1; let mut y: u16 = 0; for (name, description) in actions.iter() { stdout.queue(move_to(1, y))?.queue( PrintStyledContent(name.yellow().bold()) )?.queue(move_to(1, y + 1))?.queue( PrintStyledContent(description.yellow()) )?; y = y + 3; x = u16::max(x, usize::max(name.len(), description.len()) as u16); } Ok((x, y)) } pub fn render_box ( stdout: &mut std::io::Stdout, title: Option<&str>, x: u16, y: u16, mut w: u16, h: u16, active: bool ) -> Result<(), Box> { if let Some(title) = title { w = u16::max(w, title.len() as u16 + 4); } let back: String = std::iter::repeat(" ").take(w.saturating_sub(2) as usize).collect(); if active { let edge: String = std::iter::repeat("━").take(w.saturating_sub(2) as usize).collect(); stdout.queue(MoveTo(x, y))?.queue(PrintStyledContent(format!("┏{edge}┓").bold().yellow()))?; if let Some(title) = title { stdout.queue(MoveTo(x+1, y))?.queue(PrintStyledContent(format!(" {title} ").yellow()))?; } for row in y+1..y+h { stdout.queue(MoveTo(x, row))?.queue(PrintStyledContent("┃".bold().yellow()))?; stdout.queue(MoveTo(x+w-1, row))?.queue(PrintStyledContent("┃".bold().yellow()))?; } stdout.queue(MoveTo(x, y+h))?.queue(PrintStyledContent(format!("┗{edge}┛").bold().yellow()))?; } else { let edge: String = std::iter::repeat("─").take(w.saturating_sub(2) as usize).collect(); stdout.queue(MoveTo(x, y))?.queue(PrintStyledContent(format!("┌{edge}┐").grey().dim()))?; if let Some(title) = title { stdout.queue(MoveTo(x+1, y))?.queue(Print(format!(" {title} ")))?; } for row in y+1..y+h { stdout.queue(MoveTo(x, row))?.queue(PrintStyledContent("│".grey().dim()))?; stdout.queue(MoveTo(x+w-1, row))?.queue(PrintStyledContent("│".grey().dim()))?; } stdout.queue(MoveTo(x, y+h))?.queue(PrintStyledContent(format!("└{edge}┘").grey().dim()))?; } Ok(()) }