Skip to main content

graphix_package_gui/widgets/
tooltip.rs

1use super::{compile, GuiW, GuiWidget, IcedElement};
2use crate::types::TooltipPositionV;
3use anyhow::{Context, Result};
4use arcstr::ArcStr;
5use graphix_compiler::expr::ExprId;
6use graphix_rt::{CallableId, GXExt, GXHandle, Ref, TRef};
7use iced_widget as widget;
8use netidx::publisher::Value;
9use tokio::try_join;
10
11pub(crate) struct TooltipW<X: GXExt> {
12    gx: GXHandle<X>,
13    child_ref: Ref<X>,
14    child: GuiW<X>,
15    tip_ref: Ref<X>,
16    tip: GuiW<X>,
17    position: TRef<X, TooltipPositionV>,
18    gap: TRef<X, Option<f64>>,
19}
20
21impl<X: GXExt> TooltipW<X> {
22    pub(crate) async fn compile(gx: GXHandle<X>, source: Value) -> Result<GuiW<X>> {
23        let [(_, child), (_, gap), (_, position), (_, tip)] =
24            source.cast_to::<[(ArcStr, u64); 4]>().context("tooltip flds")?;
25        let (child_ref, gap, position, tip_ref) = try_join! {
26            gx.compile_ref(child),
27            gx.compile_ref(gap),
28            gx.compile_ref(position),
29            gx.compile_ref(tip),
30        }?;
31        let compiled_child = compile_child!(gx, child_ref, "tooltip child");
32        let compiled_tip = compile_child!(gx, tip_ref, "tooltip tip");
33        Ok(Box::new(Self {
34            gx: gx.clone(),
35            child_ref,
36            child: compiled_child,
37            tip_ref,
38            tip: compiled_tip,
39            position: TRef::new(position).context("tooltip tref position")?,
40            gap: TRef::new(gap).context("tooltip tref gap")?,
41        }))
42    }
43}
44
45impl<X: GXExt> GuiWidget<X> for TooltipW<X> {
46    fn handle_update(
47        &mut self,
48        rt: &tokio::runtime::Handle,
49        id: ExprId,
50        v: &Value,
51    ) -> Result<bool> {
52        let mut changed = false;
53        changed |=
54            self.position.update(id, v).context("tooltip update position")?.is_some();
55        changed |= self.gap.update(id, v).context("tooltip update gap")?.is_some();
56        update_child!(self, rt, id, v, changed, child_ref, child, "tooltip child recompile");
57        update_child!(self, rt, id, v, changed, tip_ref, tip, "tooltip tip recompile");
58        Ok(changed)
59    }
60
61    fn editor_action(
62        &mut self,
63        id: ExprId,
64        action: &iced_widget::text_editor::Action,
65    ) -> Option<(CallableId, Value)> {
66        if let some @ Some(_) = self.child.editor_action(id, action) {
67            return some;
68        }
69        self.tip.editor_action(id, action)
70    }
71
72    fn view(&self) -> IcedElement<'_> {
73        let pos = self
74            .position
75            .t
76            .as_ref()
77            .map(|p| p.0)
78            .unwrap_or(widget::tooltip::Position::Bottom);
79        let mut tt = widget::Tooltip::new(self.child.view(), self.tip.view(), pos);
80        if let Some(Some(g)) = self.gap.t {
81            tt = tt.gap(g as f32);
82        }
83        tt.into()
84    }
85}