zng_wgt_dialog/
backdrop.rs1use zng_ext_window::WINDOWS;
4use zng_wgt::{prelude::*, *};
5use zng_wgt_container::Container;
6use zng_wgt_fill::background_color;
7use zng_wgt_input::gesture::on_click;
8use zng_wgt_layer::popup::{POPUP_CLOSE_REQUESTED_EVENT, PopupCloseRequestedArgs};
9use zng_wgt_style::{Style, StyleMix, impl_style_fn};
10
11use crate::DIALOG;
12
13#[widget($crate::backdrop::DialogBackdrop {
21 ($child:expr) => {
22 child = $child;
23 }
24})]
25pub struct DialogBackdrop(StyleMix<Container>);
26impl DialogBackdrop {
27 fn widget_intrinsic(&mut self) {
28 self.style_intrinsic(STYLE_FN_VAR, property_id!(self::style_fn));
29
30 self.widget_builder()
32 .push_build_action(|b| b.push_intrinsic(NestGroup::EVENT, "popup-pump", backdrop_node));
33
34 widget_set! {
35 self;
36 modal = true;
37
38 on_click = hn!(|args| {
39 args.propagation.stop();
40 DIALOG.respond_default();
41 });
42 }
43 }
44}
45impl_style_fn!(DialogBackdrop, DefaultStyle);
46
47fn backdrop_node(child: impl IntoUiNode) -> UiNode {
49 match_node(child, |_, op| {
50 if let UiNodeOp::Init = op {
51 let win_id = WINDOW.id();
52 let id = WIDGET.id();
53 WIDGET.push_var_handle(POPUP_CLOSE_REQUESTED_EVENT.hook(move |args| {
54 if args.popup.widget_id() == id
55 && let Some(tree) = WINDOWS.widget_tree(win_id)
56 && let Some(info) = tree.get(id)
57 {
58 for child in info.children() {
59 POPUP_CLOSE_REQUESTED_EVENT.notify(PopupCloseRequestedArgs::new(
60 args.timestamp,
61 args.propagation.clone(),
62 child.path(),
63 ));
64 }
65 }
66 true
67 }));
68 WIDGET.sub_event(&POPUP_CLOSE_REQUESTED_EVENT);
69 }
70 })
71}
72
73#[widget($crate::backdrop::DefaultStyle)]
75pub struct DefaultStyle(Style);
76impl DefaultStyle {
77 fn widget_intrinsic(&mut self) {
78 widget_set! {
79 self;
80
81 #[easing(250.ms())]
82 background_color = colors::BLACK.transparent();
83 zng_wgt_layer::popup::close_delay = 250.ms();
84 when *#is_inited && !*#zng_wgt_layer::popup::is_close_delaying {
85 background_color = colors::BLACK.with_alpha(20.pct());
86 }
87 }
88 }
89}