1use zng_app::shortcut::Shortcuts;
7use zng_ext_input::gesture::{CLICK_EVENT, GESTURES, ShortcutClick};
8use zng_view_api::access::AccessCmdName;
9use zng_wgt::prelude::*;
10
11pub use zng_ext_input::gesture::ClickArgs;
12
13event_property! {
14 #[property(EVENT)]
22 pub fn on_any_click<on_pre_any_click>(child: impl IntoUiNode, handler: Handler<ClickArgs>) -> UiNode {
23 const PRE: bool;
24 let child = EventNodeBuilder::new(CLICK_EVENT)
25 .filter(|| {
26 let id = WIDGET.id();
27 move |args| args.target.contains_enabled(id)
28 })
29 .build::<PRE>(child, handler);
30 access_click(child)
31 }
32
33 #[property(EVENT)]
35 pub fn on_disabled_click<on_pre_disabled_click>(child: impl IntoUiNode, handler: Handler<ClickArgs>) -> UiNode {
36 const PRE: bool;
37 let child = EventNodeBuilder::new(CLICK_EVENT)
38 .filter(|| {
39 let id = WIDGET.id();
40 move |args| args.target.contains_disabled(id)
41 })
42 .build::<PRE>(child, handler);
43 access_click(child)
44 }
45
46 #[property(EVENT)]
53 pub fn on_any_single_click<on_pre_any_single_click>(child: impl IntoUiNode, handler: Handler<ClickArgs>) -> UiNode {
54 const PRE: bool;
55 let child = EventNodeBuilder::new(CLICK_EVENT)
56 .filter(|| {
57 let id = WIDGET.id();
58 move |args| args.is_single() && args.target.contains_enabled(id)
59 })
60 .build::<PRE>(child, handler);
61 access_click(child)
62 }
63
64 #[property(EVENT)]
71 pub fn on_any_double_click<on_pre_any_double_click>(child: impl IntoUiNode, handler: Handler<ClickArgs>) -> UiNode {
72 const PRE: bool;
73 EventNodeBuilder::new(CLICK_EVENT)
74 .filter(|| {
75 let id = WIDGET.id();
76 move |args| args.is_double() && args.target.contains_enabled(id)
77 })
78 .build::<PRE>(child, handler)
79 }
80
81 #[property(EVENT)]
88 pub fn on_any_triple_click<on_pre_any_triple_click>(child: impl IntoUiNode, handler: Handler<ClickArgs>) -> UiNode {
89 const PRE: bool;
90 EventNodeBuilder::new(CLICK_EVENT)
91 .filter(|| {
92 let id = WIDGET.id();
93 move |args| args.is_triple() && args.target.contains_enabled(id)
94 })
95 .build::<PRE>(child, handler)
96 }
97
98 #[property(EVENT)]
104 pub fn on_click<on_pre_click>(child: impl IntoUiNode, handler: Handler<ClickArgs>) -> UiNode {
105 const PRE: bool;
106 let child = EventNodeBuilder::new(CLICK_EVENT)
107 .filter(|| {
108 let id = WIDGET.id();
109 move |args| args.is_primary() && args.target.contains_enabled(id)
110 })
111 .build::<PRE>(child, handler);
112 access_click(child)
113 }
114
115 #[property(EVENT)]
120 pub fn on_single_click<on_pre_single_click>(child: impl IntoUiNode, handler: Handler<ClickArgs>) -> UiNode {
121 const PRE: bool;
122 let child = EventNodeBuilder::new(CLICK_EVENT)
123 .filter(|| {
124 let id = WIDGET.id();
125 move |args| args.is_primary() && args.is_single() && args.target.contains_enabled(id)
126 })
127 .build::<PRE>(child, handler);
128 access_click(child)
129 }
130
131 #[property(EVENT)]
136 pub fn on_double_click<on_pre_double_click>(child: impl IntoUiNode, handler: Handler<ClickArgs>) -> UiNode {
137 const PRE: bool;
138 EventNodeBuilder::new(CLICK_EVENT)
139 .filter(|| {
140 let id = WIDGET.id();
141 move |args| args.is_primary() && args.is_double() && args.target.contains_enabled(id)
142 })
143 .build::<PRE>(child, handler)
144 }
145
146 #[property(EVENT)]
151 pub fn on_triple_click<on_pre_triple_click>(child: impl IntoUiNode, handler: Handler<ClickArgs>) -> UiNode {
152 const PRE: bool;
153 EventNodeBuilder::new(CLICK_EVENT)
154 .filter(|| {
155 let id = WIDGET.id();
156 move |args| args.is_primary() && args.is_triple() && args.target.contains_enabled(id)
157 })
158 .build::<PRE>(child, handler)
159 }
160
161 #[property(EVENT)]
165 pub fn on_context_click<on_pre_context_click>(child: impl IntoUiNode, handler: Handler<ClickArgs>) -> UiNode {
166 const PRE: bool;
167 let child = EventNodeBuilder::new(CLICK_EVENT)
168 .filter(|| {
169 let id = WIDGET.id();
170 move |args| args.is_context() && args.target.contains_enabled(id)
171 })
172 .build::<PRE>(child, handler);
173 access_click(child)
174 }
175}
176
177#[property(CONTEXT)]
181pub fn click_shortcut(child: impl IntoUiNode, shortcuts: impl IntoVar<Shortcuts>) -> UiNode {
182 click_shortcut_node(child, shortcuts, ShortcutClick::Primary)
183}
184#[property(CONTEXT)]
188pub fn context_click_shortcut(child: impl IntoUiNode, shortcuts: impl IntoVar<Shortcuts>) -> UiNode {
189 click_shortcut_node(child, shortcuts, ShortcutClick::Context)
190}
191
192fn click_shortcut_node(child: impl IntoUiNode, shortcuts: impl IntoVar<Shortcuts>, kind: ShortcutClick) -> UiNode {
193 let shortcuts = shortcuts.into_var();
194 let mut _handle = None;
195
196 match_node(child, move |_, op| {
197 let new = match op {
198 UiNodeOp::Init => {
199 WIDGET.sub_var(&shortcuts);
200 Some(shortcuts.get())
201 }
202 UiNodeOp::Deinit => {
203 _handle = None;
204 None
205 }
206 UiNodeOp::Update { .. } => shortcuts.get_new(),
207 _ => None,
208 };
209 if let Some(s) = new {
210 _handle = Some(GESTURES.click_shortcut(s, kind, WIDGET.id()));
211 }
212 })
213}
214
215pub(crate) fn access_click(child: impl IntoUiNode) -> UiNode {
216 access_capable(child, AccessCmdName::Click)
217}
218fn access_capable(child: impl IntoUiNode, cmd: AccessCmdName) -> UiNode {
219 match_node(child, move |_, op| {
220 if let UiNodeOp::Info { info } = op
221 && let Some(mut access) = info.access()
222 {
223 access.push_command(cmd)
224 }
225 })
226}