graphix_package_gui/widgets/
tooltip.rs1use 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}