druid_widget_nursery/
widget_ext.rs1use druid::widget::prelude::*;
2use druid::widget::{ControllerHost, LabelText};
3use druid::{Point, Selector, WidgetExt as _, WindowHandle};
4
5use crate::on_cmd::OnCmd;
6use crate::stack_tooltip::{PlainOrRich, StackTooltip, ADVISE_TOOLTIP_SHOW, CANCEL_TOOLTIP_SHOW};
7use crate::tooltip::TooltipState;
8use crate::{OnChange, OnMonitor, TooltipController};
9
10pub trait WidgetExt<T: Data>: Widget<T> + Sized + 'static {
11 fn on_command<CT: 'static>(
12 self,
13 selector: Selector<CT>,
14 handler: impl Fn(&mut EventCtx, &CT, &mut T) + 'static,
15 ) -> ControllerHost<Self, OnCmd<CT, T>> {
16 self.controller(OnCmd::new(selector, handler))
17 }
18
19 fn on_change(
23 self,
24 f: impl Fn(&mut EventCtx, &T, &mut T, &Env) + 'static,
25 ) -> ControllerHost<Self, OnChange<T>> {
26 self.controller(OnChange::new(f))
27 }
28
29 fn tooltip<LT: Into<LabelText<T>>>(
31 self,
32 text: LT,
33 ) -> ControllerHost<Self, TooltipController<T>> {
34 self.controller(TooltipController {
35 text: text.into(),
36 state: TooltipState::Off,
37 })
38 }
39
40 fn on_monitor(self, parent: &WindowHandle) -> OnMonitor<Self> {
43 OnMonitor {
44 inner: self,
45 parent: parent.clone(),
46 }
47 }
48
49 fn cancel_stack_tooltip(self) -> ControllerHost<Self, OnCmd<Point, T>> {
51 self.controller(OnCmd::new(ADVISE_TOOLTIP_SHOW, move |ctx, point, _| {
52 let window_rect = ctx.size().to_rect().with_origin(ctx.window_origin());
53 if window_rect.contains(*point) {
54 ctx.submit_notification(CANCEL_TOOLTIP_SHOW)
55 }
56 }))
57 }
58
59 fn stack_tooltip(self, label: impl Into<PlainOrRich>) -> StackTooltip<T> {
61 StackTooltip::new(self, label)
62 }
63}
64
65impl<T: Data, W: Widget<T> + 'static> WidgetExt<T> for W {}