graphix_package_gui/widgets/
progress_bar.rs1use super::{GuiW, GuiWidget, IcedElement};
2use crate::types::LengthV;
3use anyhow::{Context, Result};
4use arcstr::ArcStr;
5use graphix_compiler::expr::ExprId;
6use graphix_rt::{GXExt, GXHandle, TRef};
7use iced_widget as widget;
8use netidx::publisher::Value;
9use tokio::try_join;
10
11pub(crate) struct ProgressBarW<X: GXExt> {
12 value: TRef<X, f64>,
13 min: TRef<X, f64>,
14 max: TRef<X, f64>,
15 width: TRef<X, LengthV>,
16 height: TRef<X, Option<f64>>,
17}
18
19impl<X: GXExt> ProgressBarW<X> {
20 pub(crate) async fn compile(gx: GXHandle<X>, source: Value) -> Result<GuiW<X>> {
21 let [(_, height), (_, max), (_, min), (_, value), (_, width)] =
22 source.cast_to::<[(ArcStr, u64); 5]>().context("progress_bar flds")?;
23 let (height, max, min, value, width) = try_join! {
24 gx.compile_ref(height),
25 gx.compile_ref(max),
26 gx.compile_ref(min),
27 gx.compile_ref(value),
28 gx.compile_ref(width),
29 }?;
30 Ok(Box::new(Self {
31 value: TRef::new(value).context("progress_bar tref value")?,
32 min: TRef::new(min).context("progress_bar tref min")?,
33 max: TRef::new(max).context("progress_bar tref max")?,
34 width: TRef::new(width).context("progress_bar tref width")?,
35 height: TRef::new(height).context("progress_bar tref height")?,
36 }))
37 }
38}
39
40impl<X: GXExt> GuiWidget<X> for ProgressBarW<X> {
41 fn handle_update(
42 &mut self,
43 _rt: &tokio::runtime::Handle,
44 id: ExprId,
45 v: &Value,
46 ) -> Result<bool> {
47 let mut changed = false;
48 changed |=
49 self.value.update(id, v).context("progress_bar update value")?.is_some();
50 changed |= self.min.update(id, v).context("progress_bar update min")?.is_some();
51 changed |= self.max.update(id, v).context("progress_bar update max")?.is_some();
52 changed |=
53 self.width.update(id, v).context("progress_bar update width")?.is_some();
54 changed |=
55 self.height.update(id, v).context("progress_bar update height")?.is_some();
56 Ok(changed)
57 }
58
59 fn view(&self) -> IcedElement<'_> {
60 let val = self.value.t.unwrap_or(0.0) as f32;
61 let min = self.min.t.unwrap_or(0.0) as f32;
62 let max = self.max.t.unwrap_or(100.0) as f32;
63 let mut pb = widget::ProgressBar::new(min..=max, val);
64 if let Some(w) = self.width.t.as_ref() {
65 pb = pb.length(w.0);
66 }
67 if let Some(Some(h)) = self.height.t {
68 pb = pb.girth(h as f32);
69 }
70 pb.into()
71 }
72}