graphix_package_gui/widgets/
qr_code.rs1use 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 =
27 data.t.as_deref().and_then(|s| match widget::qr_code::Data::new(s) {
28 Ok(d) => Some(d),
29 Err(e) => {
30 error!("qr_code: failed to encode data: {e}");
31 None
32 }
33 });
34 Ok(Box::new(Self {
35 data,
36 cell_size: TRef::new(cell_size).context("qr_code tref cell_size")?,
37 qr_data,
38 }))
39 }
40}
41
42impl<X: GXExt> super::GuiWidget<X> for QrCodeW<X> {
43 fn handle_update(
44 &mut self,
45 _rt: &tokio::runtime::Handle,
46 id: ExprId,
47 v: &Value,
48 ) -> Result<bool> {
49 let mut changed = false;
50 changed |=
51 self.cell_size.update(id, v).context("qr_code update cell_size")?.is_some();
52 if let Some(_) = self.data.update(id, v).context("qr_code update data")? {
53 self.qr_data = self.data.t.as_deref().and_then(|s| {
54 match widget::qr_code::Data::new(s) {
55 Ok(d) => Some(d),
56 Err(e) => {
57 error!("qr_code: failed to encode data: {e}");
58 None
59 }
60 }
61 });
62 changed = true;
63 }
64 Ok(changed)
65 }
66
67 fn view(&self) -> IcedElement<'_> {
68 match &self.qr_data {
69 Some(data) => {
70 let mut qr = widget::QRCode::new(data);
71 if let Some(Some(sz)) = self.cell_size.t {
72 qr = qr.cell_size(sz as f32);
73 }
74 qr.into()
75 }
76 None => iced_widget::Space::new().into(),
77 }
78 }
79}