Skip to main content

graphix_package_gui/widgets/
text.rs

1use super::{GuiW, IcedElement};
2use crate::types::{ColorV, FontV, HAlignV, LengthV, VAlignV};
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 TextW<X: GXExt> {
12    content: TRef<X, String>,
13    size: TRef<X, Option<f64>>,
14    color: TRef<X, Option<ColorV>>,
15    font: TRef<X, Option<FontV>>,
16    width: TRef<X, LengthV>,
17    height: TRef<X, LengthV>,
18    halign: TRef<X, HAlignV>,
19    valign: TRef<X, VAlignV>,
20}
21
22impl<X: GXExt> TextW<X> {
23    pub(crate) async fn compile(gx: GXHandle<X>, source: Value) -> Result<GuiW<X>> {
24        let [(_, color), (_, content), (_, font), (_, halign), (_, height), (_, size), (_, valign), (_, width)] =
25            source.cast_to::<[(ArcStr, u64); 8]>().context("text flds")?;
26        let (color, content, font, halign, height, size, valign, width) = try_join! {
27            gx.compile_ref(color),
28            gx.compile_ref(content),
29            gx.compile_ref(font),
30            gx.compile_ref(halign),
31            gx.compile_ref(height),
32            gx.compile_ref(size),
33            gx.compile_ref(valign),
34            gx.compile_ref(width),
35        }?;
36        Ok(Box::new(Self {
37            content: TRef::new(content).context("text tref content")?,
38            size: TRef::new(size).context("text tref size")?,
39            color: TRef::new(color).context("text tref color")?,
40            font: TRef::new(font).context("text tref font")?,
41            width: TRef::new(width).context("text tref width")?,
42            height: TRef::new(height).context("text tref height")?,
43            halign: TRef::new(halign).context("text tref halign")?,
44            valign: TRef::new(valign).context("text tref valign")?,
45        }))
46    }
47}
48
49impl<X: GXExt> super::GuiWidget<X> for TextW<X> {
50    fn handle_update(
51        &mut self,
52        _rt: &tokio::runtime::Handle,
53        id: ExprId,
54        v: &Value,
55    ) -> Result<bool> {
56        let mut changed = false;
57        changed |= self.content.update(id, v).context("text update content")?.is_some();
58        changed |= self.size.update(id, v).context("text update size")?.is_some();
59        changed |= self.color.update(id, v).context("text update color")?.is_some();
60        changed |= self.font.update(id, v).context("text update font")?.is_some();
61        changed |= self.width.update(id, v).context("text update width")?.is_some();
62        changed |= self.height.update(id, v).context("text update height")?.is_some();
63        changed |= self.halign.update(id, v).context("text update halign")?.is_some();
64        changed |= self.valign.update(id, v).context("text update valign")?.is_some();
65        Ok(changed)
66    }
67
68    fn view(&self) -> IcedElement<'_> {
69        let content = self.content.t.as_deref().unwrap_or("");
70        let mut t = widget::Text::new(content);
71        if let Some(Some(sz)) = self.size.t {
72            t = t.size(sz as f32);
73        }
74        if let Some(Some(c)) = self.color.t.as_ref() {
75            t = t.color(c.0);
76        }
77        if let Some(Some(f)) = self.font.t.as_ref() {
78            t = t.font(f.0);
79        }
80        if let Some(w) = self.width.t.as_ref() {
81            t = t.width(w.0);
82        }
83        if let Some(h) = self.height.t.as_ref() {
84            t = t.height(h.0);
85        }
86        if let Some(a) = self.halign.t.as_ref() {
87            t = t.align_x(a.0);
88        }
89        if let Some(a) = self.valign.t.as_ref() {
90            t = t.align_y(a.0);
91        }
92        t.into()
93    }
94}