zng_wgt_input/
touch_props.rs
1use zng_ext_input::touch::{TOUCH_TRANSFORM_EVENT, TouchTransformMode};
2use zng_view_api::touch::TouchPhase;
3use zng_wgt::prelude::*;
4
5#[property(LAYOUT, default(false))]
7pub fn touch_transform(child: impl UiNode, mode: impl IntoVar<TouchTransformMode>) -> impl UiNode {
8 let mode = mode.into_var();
9 let mut handle = EventHandle::dummy();
10 let mut transform_committed = PxTransform::identity();
11 let mut transform = PxTransform::identity();
12 match_node(child, move |c, op| match op {
13 UiNodeOp::Init => {
14 WIDGET.sub_var(&mode);
15 if !mode.get().is_empty() {
16 handle = TOUCH_TRANSFORM_EVENT.subscribe(WIDGET.id());
17 }
18 }
19 UiNodeOp::Deinit => {
20 handle = EventHandle::dummy();
21 }
22 UiNodeOp::Event { update } => {
23 if let Some(args) = TOUCH_TRANSFORM_EVENT.on(update) {
24 if args.propagation().is_stopped() {
25 return;
26 }
27
28 let t = transform_committed.then(&args.local_transform(mode.get()));
29 if transform != t {
30 transform = t;
31 WIDGET.render_update();
32 }
33
34 match args.phase {
35 TouchPhase::Start | TouchPhase::Move => {}
36 TouchPhase::End => {
37 transform_committed = transform;
38 }
39 TouchPhase::Cancel => {
40 transform = transform_committed;
41 WIDGET.render_update();
42 }
43 }
44 }
45 }
46 UiNodeOp::Update { .. } => {
47 if let Some(mode) = mode.get_new() {
48 if handle.is_dummy() {
49 if !mode.is_empty() {
50 handle = TOUCH_TRANSFORM_EVENT.subscribe(WIDGET.id());
51 }
52 } else if mode.is_empty() {
53 handle = EventHandle::dummy();
54 }
55 }
56 }
57 UiNodeOp::Render { frame } => {
58 frame.push_inner_transform(&transform, |f| c.render(f));
59 }
60 UiNodeOp::RenderUpdate { update } => {
61 update.with_inner_transform(&transform, |u| c.render_update(u));
62 }
63 _ => {}
64 })
65}