zng_wgt_input/
touch_props.rs1use 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 IntoUiNode, mode: impl IntoVar<TouchTransformMode>) -> UiNode {
8 let mode = mode.into_var();
9 let mut handle = VarHandle::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(UpdateOp::Update, WIDGET.id());
17 }
18 }
19 UiNodeOp::Deinit => {
20 handle = VarHandle::dummy();
21 }
22 UiNodeOp::Update { .. } => {
23 TOUCH_TRANSFORM_EVENT.each_update(false, |args| {
24 let t = transform_committed.then(&args.local_transform(mode.get(), (WINDOW.id(), WIDGET.id())));
25 if transform != t {
26 transform = t;
27 WIDGET.render_update();
28 }
29
30 match args.phase {
31 TouchPhase::Start | TouchPhase::Move => {}
32 TouchPhase::End => {
33 transform_committed = transform;
34 }
35 TouchPhase::Cancel => {
36 transform = transform_committed;
37 WIDGET.render_update();
38 }
39 }
40 });
41
42 if let Some(mode) = mode.get_new() {
43 if handle.is_dummy() {
44 if !mode.is_empty() {
45 handle = TOUCH_TRANSFORM_EVENT.subscribe(UpdateOp::Update, WIDGET.id());
46 }
47 } else if mode.is_empty() {
48 handle = VarHandle::dummy();
49 }
50 }
51 }
52 UiNodeOp::Render { frame } => {
53 frame.push_inner_transform(&transform, |f| c.render(f));
54 }
55 UiNodeOp::RenderUpdate { update } => {
56 update.with_inner_transform(&transform, |u| c.render_update(u));
57 }
58 _ => {}
59 })
60}