graphix-package-tui 0.7.0

A dataflow language for UIs and network programming, TUI package
Documentation
use super::{SpanV, StyleV, TuiW, TuiWidget};
use anyhow::{Context, Result};
use arcstr::ArcStr;
use async_trait::async_trait;
use crossterm::event::Event;
use graphix_compiler::expr::ExprId;
use graphix_rt::{GXExt, GXHandle, TRef};
use netidx::publisher::Value;
use ratatui::{layout::Rect, widgets::Gauge, Frame};
use tokio::try_join;

pub(super) struct GaugeW<X: GXExt> {
    gauge_style: TRef<X, Option<StyleV>>,
    label: TRef<X, Option<SpanV>>,
    ratio: TRef<X, f64>,
    style: TRef<X, Option<StyleV>>,
    use_unicode: TRef<X, Option<bool>>,
}

impl<X: GXExt> GaugeW<X> {
    pub(super) async fn compile(gx: GXHandle<X>, v: Value) -> Result<TuiW> {
        let [(_, gauge_style), (_, label), (_, ratio), (_, style), (_, use_unicode)] =
            v.cast_to::<[(ArcStr, u64); 5]>()?;
        let (gauge_style, label, ratio, style, use_unicode) = try_join! {
            gx.compile_ref(gauge_style),
            gx.compile_ref(label),
            gx.compile_ref(ratio),
            gx.compile_ref(style),
            gx.compile_ref(use_unicode)
        }?;
        Ok(Box::new(Self {
            gauge_style: TRef::new(gauge_style).context("gage tref gauge_style")?,
            label: TRef::new(label).context("gage tref label")?,
            ratio: TRef::new(ratio).context("gage tref ratio")?,
            style: TRef::new(style).context("gage tref style")?,
            use_unicode: TRef::new(use_unicode).context("gage tref use_unicode")?,
        }))
    }
}

#[async_trait]
impl<X: GXExt> TuiWidget for GaugeW<X> {
    async fn handle_event(&mut self, _e: Event, _v: Value) -> Result<()> {
        Ok(())
    }

    async fn handle_update(&mut self, id: ExprId, v: Value) -> Result<()> {
        self.gauge_style.update(id, &v).context("gage update gauge_style")?;
        self.label.update(id, &v).context("gage update label")?;
        self.ratio.update(id, &v).context("gage update ratio")?;
        self.style.update(id, &v).context("gage update style")?;
        self.use_unicode.update(id, &v).context("gage update use_unicode")?;
        Ok(())
    }

    fn draw(&mut self, frame: &mut Frame, rect: Rect) -> Result<()> {
        let mut g = Gauge::default().ratio(self.ratio.t.unwrap_or(0.0));
        if let Some(Some(s)) = &self.label.t {
            g = g.label(s.0.clone());
        }
        if let Some(Some(s)) = &self.style.t {
            g = g.style(s.0);
        }
        if let Some(Some(s)) = &self.gauge_style.t {
            g = g.gauge_style(s.0);
        }
        if let Some(Some(u)) = self.use_unicode.t {
            g = g.use_unicode(u);
        }
        frame.render_widget(g, rect);
        Ok(())
    }
}