zng_wgt_input/
drag_drop.rs1#![cfg(feature = "drag_drop")]
2
3use zng_ext_input::drag_drop::{
6 DRAG_END_EVENT, DRAG_HOVERED_EVENT, DRAG_START_EVENT, DROP_EVENT, DragEndArgs, DragHoveredArgs, DragStartArgs, DropArgs,
7 WidgetInfoBuilderDragDropExt as _,
8};
9use zng_wgt::{node::bind_state_init, prelude::*};
10
11#[property(CONTEXT, default(false))]
19pub fn draggable(child: impl IntoUiNode, input: impl IntoVar<bool>) -> UiNode {
20 let input = input.into_var();
21 match_node(child, move |_c, op| match op {
22 UiNodeOp::Init => {
23 WIDGET.sub_var_info(&input);
24 }
25 UiNodeOp::Info { info } if input.get() => {
26 info.draggable();
27 }
28 _ => {}
29 })
30}
31
32event_property! {
33 #[property(EVENT)]
39 pub fn on_drag_start<on_pre_drag_start>(child: impl IntoUiNode, handler: Handler<DragStartArgs>) -> UiNode {
40 const PRE: bool;
41 EventNodeBuilder::new(DRAG_START_EVENT).build::<PRE>(child, handler)
42 }
43
44 #[property(EVENT)]
50 pub fn on_drag_end<on_pre_drag_end>(child: impl IntoUiNode, handler: Handler<DragEndArgs>) -> UiNode {
51 const PRE: bool;
52 EventNodeBuilder::new(DRAG_END_EVENT).build::<PRE>(child, handler)
53 }
54
55 #[property(EVENT)]
57 pub fn on_drag_hovered<on_pre_drag_hovered>(child: impl IntoUiNode, handler: Handler<DragHoveredArgs>) -> UiNode {
58 const PRE: bool;
59 EventNodeBuilder::new(DRAG_HOVERED_EVENT)
60 .filter(|| {
61 let id = WIDGET.id();
62 move |args| args.is_drag_enter_enabled(id) || args.is_drag_leave_enabled(id)
63 })
64 .build::<PRE>(child, handler)
65 }
66 #[property(EVENT)]
68 pub fn on_drag_enter<on_pre_drag_enter>(child: impl IntoUiNode, handler: Handler<DragHoveredArgs>) -> UiNode {
69 const PRE: bool;
70 EventNodeBuilder::new(DRAG_HOVERED_EVENT)
71 .filter(|| {
72 let id = WIDGET.id();
73 move |args| args.is_drag_enter_enabled(id)
74 })
75 .build::<PRE>(child, handler)
76 }
77 #[property(EVENT)]
79 pub fn on_drag_leave<on_pre_drag_leave>(child: impl IntoUiNode, handler: Handler<DragHoveredArgs>) -> UiNode {
80 const PRE: bool;
81 EventNodeBuilder::new(DRAG_HOVERED_EVENT)
82 .filter(|| {
83 let id = WIDGET.id();
84 move |args| args.is_drag_leave_enabled(id)
85 })
86 .build::<PRE>(child, handler)
87 }
88
89 #[property(EVENT)]
91 pub fn on_drop<on_pre_drop>(child: impl IntoUiNode, handler: Handler<DropArgs>) -> UiNode {
92 const PRE: bool;
93 EventNodeBuilder::new(DROP_EVENT)
94 .filter(|| {
95 let id = WIDGET.id();
96 move |args| args.target.contains_enabled(id)
97 })
98 .build::<PRE>(child, handler)
99 }
100}
101
102#[property(EVENT)]
109pub fn is_drag_hovered(child: impl IntoUiNode, state: impl IntoVar<bool>) -> UiNode {
110 bind_state_init(child, state, |s| {
111 let id = WIDGET.id();
112 DRAG_HOVERED_EVENT.var_bind(s, move |args| {
113 if args.is_drag_enter_enabled(id) {
114 Some(true)
115 } else if args.is_drag_leave_enabled(id) {
116 Some(false)
117 } else {
118 None
119 }
120 })
121 })
122}
123
124#[property(EVENT)]
126pub fn is_drag_hovered_disabled(child: impl IntoUiNode, state: impl IntoVar<bool>) -> UiNode {
127 bind_state_init(child, state, |s| {
128 let id = WIDGET.id();
129 DRAG_HOVERED_EVENT.var_bind(s, move |args| {
130 if args.is_drag_enter_disabled(id) {
131 Some(true)
132 } else if args.is_drag_leave_disabled(id) {
133 Some(false)
134 } else {
135 None
136 }
137 })
138 })
139}
140
141#[property(EVENT)]
143pub fn is_dragging(child: impl IntoUiNode, state: impl IntoVar<bool>) -> UiNode {
144 bind_state_init(child, state, |s| {
145 let id = WIDGET.id();
146 let handle = DRAG_START_EVENT.var_bind(s, move |args| if args.target.contains(id) { Some(true) } else { None });
147 DRAG_END_EVENT.var_bind(s, move |args| {
148 let _hold = &handle;
149 if args.target.contains(id) { Some(false) } else { None }
150 })
151 })
152}