zng_wgt/
hit_test_props.rs

1use zng_app::widget::base::HIT_TEST_MODE_VAR;
2pub use zng_app::widget::base::HitTestMode;
3
4use crate::prelude::*;
5
6/// Defines if and how the widget is hit-tested.
7///
8/// See [`HitTestMode`] for more details.
9#[property(CONTEXT, default(HIT_TEST_MODE_VAR))]
10pub fn hit_test_mode(child: impl UiNode, mode: impl IntoVar<HitTestMode>) -> impl UiNode {
11    let child = match_node(child, |child, op| match op {
12        UiNodeOp::Init => {
13            WIDGET.sub_var_render(&HIT_TEST_MODE_VAR);
14        }
15        UiNodeOp::Render { frame } => match HIT_TEST_MODE_VAR.get() {
16            HitTestMode::Disabled => {
17                frame.with_hit_tests_disabled(|frame| child.render(frame));
18            }
19            HitTestMode::Detailed => frame.with_auto_hit_test(true, |frame| child.render(frame)),
20            _ => frame.with_auto_hit_test(false, |frame| child.render(frame)),
21        },
22        UiNodeOp::RenderUpdate { update } => {
23            update.with_auto_hit_test(matches!(HIT_TEST_MODE_VAR.get(), HitTestMode::Detailed), |update| {
24                child.render_update(update)
25            });
26        }
27        _ => {}
28    });
29
30    with_context_var(
31        child,
32        HIT_TEST_MODE_VAR,
33        merge_var!(HIT_TEST_MODE_VAR, mode.into_var(), |&a, &b| match (a, b) {
34            (HitTestMode::Disabled, _) | (_, HitTestMode::Disabled) => HitTestMode::Disabled,
35            (_, b) => b,
36        }),
37    )
38}
39
40/// If the widget is visible for hit-tests.
41///
42/// This property is used only for probing the state. You can set the state using
43/// the [`hit_test_mode`] property.
44///
45/// [`hit_test_mode`]: fn@hit_test_mode
46#[property(EVENT)]
47pub fn is_hit_testable(child: impl UiNode, state: impl IntoVar<bool>) -> impl UiNode {
48    bind_state(child, HIT_TEST_MODE_VAR.map(|m| m.is_hit_testable()), state)
49}