Skip to main content

graphix_package_gui/widgets/
qr_code.rs

1use super::{GuiW, IcedElement};
2use anyhow::{Context, Result};
3use arcstr::ArcStr;
4use graphix_compiler::expr::ExprId;
5use graphix_rt::{GXExt, GXHandle, TRef};
6use iced_widget as widget;
7use log::error;
8use netidx::publisher::Value;
9use tokio::try_join;
10
11pub(crate) struct QrCodeW<X: GXExt> {
12    data: TRef<X, String>,
13    cell_size: TRef<X, Option<f64>>,
14    qr_data: Option<widget::qr_code::Data>,
15}
16
17impl<X: GXExt> QrCodeW<X> {
18    pub(crate) async fn compile(gx: GXHandle<X>, source: Value) -> Result<GuiW<X>> {
19        let [(_, cell_size), (_, data)] =
20            source.cast_to::<[(ArcStr, u64); 2]>().context("qr_code flds")?;
21        let (cell_size, data) = try_join! {
22            gx.compile_ref(cell_size),
23            gx.compile_ref(data),
24        }?;
25        let data = TRef::new(data).context("qr_code tref data")?;
26        let qr_data = data.t.as_deref().and_then(|s| match widget::qr_code::Data::new(s) {
27            Ok(d) => Some(d),
28            Err(e) => {
29                error!("qr_code: failed to encode data: {e}");
30                None
31            }
32        });
33        Ok(Box::new(Self {
34            data,
35            cell_size: TRef::new(cell_size).context("qr_code tref cell_size")?,
36            qr_data,
37        }))
38    }
39}
40
41impl<X: GXExt> super::GuiWidget<X> for QrCodeW<X> {
42    fn handle_update(
43        &mut self,
44        _rt: &tokio::runtime::Handle,
45        id: ExprId,
46        v: &Value,
47    ) -> Result<bool> {
48        let mut changed = false;
49        changed |=
50            self.cell_size.update(id, v).context("qr_code update cell_size")?.is_some();
51        if let Some(_) = self.data.update(id, v).context("qr_code update data")? {
52            self.qr_data = self.data.t.as_deref().and_then(
53                |s| match widget::qr_code::Data::new(s) {
54                    Ok(d) => Some(d),
55                    Err(e) => {
56                        error!("qr_code: failed to encode data: {e}");
57                        None
58                    }
59                },
60            );
61            changed = true;
62        }
63        Ok(changed)
64    }
65
66    fn view(&self) -> IcedElement<'_> {
67        match &self.qr_data {
68            Some(data) => {
69                let mut qr = widget::QRCode::new(data);
70                if let Some(Some(sz)) = self.cell_size.t {
71                    qr = qr.cell_size(sz as f32);
72                }
73                qr.into()
74            }
75            None => iced_widget::Space::new().into(),
76        }
77    }
78}