ferroui_base/input/
drag_drop.rs1use super::platform::IPlatformDragSource;
2use super::{DragDropEffects, DragEventArgs, IDataTransfer, LocalBoxFuture, PointerPressedEventArgs};
3use crate::interactivity::{Interactive, RoutedEvent, RoutedEventHandlerToken, RoutingStrategies};
4use crate::{
5 ferro_property, ferro_routed_event, AttachedProperty, FerroLocator, FerroProperty, LocatorExtensions,
6 StyledPropertyOptions,
7};
8use std::rc::Rc;
9
10pub struct DragDrop;
13
14crate::ferro_static_type!(DragDrop);
15
16impl DragDrop {
17 ferro_routed_event!(
18 pub fn drag_enter_event() -> RoutedEvent<DragEventArgs> {
21 RoutedEvent::register::<DragDrop, _>("DragEnter", RoutingStrategies::BUBBLE)
22 }
23 );
24
25 ferro_routed_event!(
26 pub fn drag_leave_event() -> RoutedEvent<DragEventArgs> {
29 RoutedEvent::register::<DragDrop, _>("DragLeave", RoutingStrategies::BUBBLE)
30 }
31 );
32
33 ferro_routed_event!(
34 pub fn drag_over_event() -> RoutedEvent<DragEventArgs> {
37 RoutedEvent::register::<DragDrop, _>("DragOver", RoutingStrategies::BUBBLE)
38 }
39 );
40
41 ferro_routed_event!(
42 pub fn drop_event() -> RoutedEvent<DragEventArgs> {
45 RoutedEvent::register::<DragDrop, _>("Drop", RoutingStrategies::BUBBLE)
46 }
47 );
48
49}
50
51crate::ferro_properties! { impl DragDrop {
52 ferro_property!(
53 pub fn allow_drop_property() -> AttachedProperty<bool> {
56 FerroProperty::register_attached_with::<DragDrop, Interactive, _>(
57 "AllowDrop",
58 StyledPropertyOptions::new(false).inherits(true),
59 )
60 }
61 );
62} }
63
64impl DragDrop {
65 pub fn get_allow_drop(interactive: &Interactive) -> bool {
68 interactive.get_value(Self::allow_drop_property())
69 }
70
71 pub fn set_allow_drop(interactive: &Interactive, value: bool) {
74 interactive.set_value(Self::allow_drop_property(), value)
75 }
76
77 pub fn add_drag_enter_handler(
79 element: &Interactive,
80 handler: impl Fn(&Interactive, &DragEventArgs) + 'static,
81 ) -> RoutedEventHandlerToken {
82 element.add_handler(Self::drag_enter_event(), handler)
83 }
84
85 pub fn remove_drag_enter_handler(element: &Interactive, handler: RoutedEventHandlerToken) {
87 element.remove_handler(Self::drag_enter_event(), handler);
88 }
89
90 pub fn add_drag_leave_handler(
92 element: &Interactive,
93 handler: impl Fn(&Interactive, &DragEventArgs) + 'static,
94 ) -> RoutedEventHandlerToken {
95 element.add_handler(Self::drag_leave_event(), handler)
96 }
97
98 pub fn remove_drag_leave_handler(element: &Interactive, handler: RoutedEventHandlerToken) {
100 element.remove_handler(Self::drag_leave_event(), handler);
101 }
102
103 pub fn add_drag_over_handler(
105 element: &Interactive,
106 handler: impl Fn(&Interactive, &DragEventArgs) + 'static,
107 ) -> RoutedEventHandlerToken {
108 element.add_handler(Self::drag_over_event(), handler)
109 }
110
111 pub fn remove_drag_over_handler(element: &Interactive, handler: RoutedEventHandlerToken) {
113 element.remove_handler(Self::drag_over_event(), handler);
114 }
115
116 pub fn add_drop_handler(
118 element: &Interactive,
119 handler: impl Fn(&Interactive, &DragEventArgs) + 'static,
120 ) -> RoutedEventHandlerToken {
121 element.add_handler(Self::drop_event(), handler)
122 }
123
124 pub fn remove_drop_handler(element: &Interactive, handler: RoutedEventHandlerToken) {
126 element.remove_handler(Self::drop_event(), handler);
127 }
128
129 pub fn do_drag_drop_async(
137 trigger_event: &PointerPressedEventArgs,
138 data_transfer: Rc<dyn IDataTransfer>,
139 allowed_effects: DragDropEffects,
140 ) -> LocalBoxFuture<DragDropEffects> {
141 let Some(drag_source) = FerroLocator::current().get_service::<dyn IPlatformDragSource>() else {
142 data_transfer.dispose();
143 return Box::pin(std::future::ready(DragDropEffects::NONE));
144 };
145
146 drag_source.do_drag_drop_async(trigger_event, data_transfer, allowed_effects)
147 }
148}