scrin-widgets 0.1.0

Plug-and-play Ratatui widgets and Aisling terminal effects for Scrin TUIs.
Documentation
use std::{io, time::Duration};

use crossterm::{
    execute,
    terminal::{EnterAlternateScreen, LeaveAlternateScreen, disable_raw_mode, enable_raw_mode},
};
use ratatui::{
    Terminal,
    backend::CrosstermBackend,
    layout::{Constraint, Direction, Layout},
    widgets::{Block, Paragraph, Wrap},
};
use scrin_widgets::{AislingExt, AislingPalette, GlyphRain, NebulaGauge, SignalPanel};

type Tui = Terminal<CrosstermBackend<io::Stdout>>;

fn main() -> io::Result<()> {
    let mut terminal = setup_terminal()?;
    let result = run(&mut terminal);
    restore_terminal(terminal)?;
    result
}

fn setup_terminal() -> io::Result<Tui> {
    enable_raw_mode()?;
    let mut stdout = io::stdout();
    execute!(stdout, EnterAlternateScreen)?;
    Terminal::new(CrosstermBackend::new(stdout))
}

fn restore_terminal(mut terminal: Tui) -> io::Result<()> {
    disable_raw_mode()?;
    execute!(terminal.backend_mut(), LeaveAlternateScreen)?;
    terminal.show_cursor()
}

fn run(terminal: &mut Tui) -> io::Result<()> {
    let tick = 37;

    terminal.draw(|frame| {
        let rows = Layout::default()
            .direction(Direction::Vertical)
            .constraints([
                Constraint::Min(8),
                Constraint::Length(7),
                Constraint::Length(5),
            ])
            .split(frame.area());

        frame.render_widget(
            GlyphRain::new(tick)
                .density(30)
                .block(Block::bordered().title("glyph rain")),
            rows[0],
        );

        let columns = Layout::default()
            .direction(Direction::Horizontal)
            .constraints([Constraint::Percentage(50), Constraint::Percentage(50)])
            .split(rows[1]);

        frame.render_widget(
            NebulaGauge::new(0.72)
                .tick(tick)
                .label("dream-link 72%")
                .block(Block::bordered().title("nebula gauge")),
            columns[0],
        );

        frame.render_widget(
            SignalPanel::new("relay")
                .line("status: luminous")
                .line("route: scrin://aisling")
                .tick(tick),
            columns[1],
        );

        frame.render_widget(
            Paragraph::new("Wrap any existing Ratatui widget with `.aisling()` for shimmer, scanlines, and edge glow.")
                .block(Block::bordered().title("plug and play"))
                .wrap(Wrap { trim: true })
                .aisling()
                .tick(tick)
                .palette(AislingPalette::dream())
                .intensity(7),
            rows[2],
        );
    })?;

    std::thread::sleep(Duration::from_secs(3));
    Ok(())
}