use std::io::Stdout;
use std::thread::sleep;
use std::time::Duration;
use rich_rs::{
Align, Console, ConsoleOptions, Layout, Live, LiveOptions, Measurement, Renderable, Segments,
Style, Text, VerticalAlignMethod,
};
struct Clock;
impl Renderable for Clock {
fn render(&self, _console: &Console<Stdout>, _options: &ConsoleOptions) -> Segments {
use std::time::{SystemTime, UNIX_EPOCH};
let now = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap_or_default();
let total_secs = now.as_secs();
let secs = total_secs % 60;
let mins = (total_secs / 60) % 60;
let hours = (total_secs / 3600) % 24;
let time_str = format!("{:02}:{:02}:{:02} UTC", hours, mins, secs);
let text = Text::styled(&time_str, Style::parse("bold magenta").unwrap_or_default());
text.render(_console, _options)
}
fn measure(&self, _console: &Console<Stdout>, _options: &ConsoleOptions) -> Measurement {
Measurement::new(12, 12)
}
}
fn main() -> std::io::Result<()> {
let layout = Layout::new();
let header = Layout::new().with_name("header").with_size(1);
let main = Layout::new().with_name("main").with_ratio(1);
let footer = Layout::new().with_name("footer").with_size(10);
layout.split_column(vec![header.clone(), main.clone(), footer]);
let side = Layout::new().with_name("side");
let body = Layout::new().with_name("body").with_ratio(2);
main.split_row(vec![side.clone(), body.clone()]);
let side_top = Layout::new();
let side_bottom = Layout::new();
side.split_column(vec![side_top, side_bottom]);
let body_text = Text::from_markup(
"This is a demonstration of [bold cyan]rich.Layout[/]\n\nHit Ctrl+C to exit",
false,
)
.unwrap_or_else(|_| {
Text::plain("This is a demonstration of rich.Layout\n\nHit Ctrl+C to exit")
});
let body_content =
Align::center(Box::new(body_text)).with_vertical(VerticalAlignMethod::Middle);
if let Some(body_layout) = layout.get("body") {
body_layout.update(body_content);
}
if let Some(header_layout) = layout.get("header") {
header_layout.update(Clock);
}
let options = LiveOptions {
screen: true,
refresh_per_second: 1.0,
..Default::default()
};
let mut live = Live::with_options(Box::new(layout.clone()), options);
live.start(true)?;
loop {
if let Some(header_layout) = layout.get("header") {
header_layout.update(Clock);
}
live.update(Box::new(layout.clone()), true)?;
sleep(Duration::from_secs(1));
}
}