makepad_platform/event/
drag_drop.rs

1use {
2    std::cell::Cell,
3    std::rc::Rc,
4    crate::{
5        makepad_live_id::*,
6        makepad_math::*,
7        event::{
8            KeyModifiers,
9            finger::{HitOptions, Margin},
10            event::{Event, DragHit}
11        },
12        cx::Cx,
13        area::Area,
14    },
15};
16
17
18#[derive(Clone, Debug)]
19pub struct DragEvent {
20    pub modifiers: KeyModifiers,
21    pub handled: Cell<bool>,
22    pub abs: DVec2,
23    pub items: Rc<Vec<DragItem >>,
24    pub response: Rc<Cell<DragResponse >>,
25}
26
27#[derive(Clone, Debug)]
28pub struct DropEvent {
29    pub modifiers: KeyModifiers,
30    pub handled: Cell<bool>,
31    pub abs: DVec2,
32    pub items: Rc<Vec<DragItem >>,
33}
34
35#[derive(Clone, Debug, PartialEq)]
36pub struct DragHitEvent {
37    pub modifiers: KeyModifiers,
38    pub abs: DVec2,
39    pub rect: Rect,
40    pub state: DragState,
41    pub items: Rc<Vec<DragItem >>,
42    pub response: Rc<Cell<DragResponse >>,
43}
44
45#[derive(Clone, Debug, PartialEq)]
46pub struct DropHitEvent {
47    pub modifiers: KeyModifiers,
48    pub abs: DVec2,
49    pub rect: Rect,
50    pub items: Rc<Vec<DragItem >>,
51}
52
53#[derive(Clone, Debug, PartialEq)]
54pub enum DragState {
55    In,
56    Over,
57    Out,
58}
59
60#[derive(Clone, Copy, Debug, PartialEq)]
61pub enum DragResponse {
62    None,
63    Copy,
64    Link,
65    Move,
66}
67
68#[derive(Clone, Debug, PartialEq)]
69pub enum DragItem {
70    FilePath {path: String, internal_id: Option<LiveId>},
71    String {value: String, internal_id: Option<LiveId>}
72}
73
74/*
75pub enum HitTouch {
76    Single,
77    Multi
78}*/
79
80
81// Status
82
83
84#[derive(Default)]
85pub struct CxDragDrop {
86    drag_area: Area,
87    next_drag_area: Area,
88}
89
90impl CxDragDrop {
91    #[allow(dead_code)]
92    pub (crate) fn cycle_drag(&mut self) {
93        self.drag_area = self.next_drag_area;
94        self.next_drag_area = Area::Empty;
95    }
96    
97    pub (crate) fn update_area(&mut self, old_area: Area, new_area: Area) {
98        if self.drag_area == old_area {
99            self.drag_area = new_area;
100        }
101    }
102}
103
104impl Event {
105    
106    pub fn drag_hits(&self, cx: &mut Cx, area: Area) -> DragHit {
107        self.drag_hits_with_options(cx, area, HitOptions::default())
108    }
109    
110    pub fn drag_hits_with_options(&self, cx: &mut Cx, area: Area, options: HitOptions) -> DragHit {
111        match self {
112            Event::Drag(event) => {
113                let rect = area.get_clipped_rect(cx);
114                if area == cx.drag_drop.drag_area {
115                    if !event.handled.get() && Margin::rect_contains_with_margin(&rect, event.abs, &options.margin) {
116                        //log!("drag_hist_with_options: Drag, in drag area, event handled and rect ({:?}) contains ({},{}) with margin {:?}",rect,event.abs.x,event.abs.y,options.margin);
117                        cx.drag_drop.next_drag_area = area;
118                        event.handled.set(true);
119                        DragHit::Drag(DragHitEvent {
120                            rect,
121                            modifiers: event.modifiers,
122                            abs: event.abs,
123                            items: event.items.clone(),
124                            state: DragState::Over,
125                            response: event.response.clone()
126                        })
127                    } else {
128                        //log!("drag_hist_with_options: Drag, in drag area, event not handled or rect ({:?}) doesn't contain ({},{}) with margin {:?}",rect,event.abs.x,event.abs.y,options.margin);
129                        DragHit::Drag(DragHitEvent {
130                            rect,
131                            modifiers: event.modifiers,
132                            state: DragState::Out,
133                            items: event.items.clone(),
134                            abs: event.abs,
135                            response: event.response.clone()
136                        })
137                    }
138                } else {
139                    if !event.handled.get() && Margin::rect_contains_with_margin(&rect, event.abs, &options.margin) {
140                        //log!("drag_hits_with_options: Drag, not in drag_area, event not handled and rect ({:?}) contains ({},{}) with margin {:?}",rect,event.abs.x,event.abs.y,options.margin);
141                        cx.drag_drop.next_drag_area = area;
142                        event.handled.set(true);
143                        DragHit::Drag(DragHitEvent {
144                            modifiers: event.modifiers,
145                            rect,
146                            state: DragState::In,
147                            items: event.items.clone(),
148                            abs: event.abs,
149                            response: event.response.clone()
150                        })
151                    } else {
152                        //log!("drag_hits_with_options: Drag, not in drag_area, event handled or rect ({:?}) doesn't contain ({},{}) with margin {:?}",rect,event.abs.x,event.abs.y,options.margin);
153                        DragHit::NoHit
154                    }
155                }
156            }
157            Event::Drop(event) => {
158                let rect = area.get_clipped_rect(cx);
159                if !event.handled.get() && Margin::rect_contains_with_margin(&rect, event.abs, &options.margin) {
160                    //log!("drag_hits_with_options: Drop, event not handled and rect {:?} contains ({},{}) in margin {:?}",rect,event.abs.x,event.abs.y,options.margin);
161                    cx.drag_drop.next_drag_area = Area::default();
162                    event.handled.set(true);
163                    DragHit::Drop(DropHitEvent {
164                        modifiers: event.modifiers,
165                        rect,
166                        abs: event.abs,
167                        items: event.items.clone()
168                    })
169                } else {
170                    //log!("drag_hits_with_options: Drop, event handled or rect {:?} doesn't contain ({},{}) in margin {:?}",rect,event.abs.x,event.abs.y,options.margin);
171                    DragHit::NoHit
172                }
173            }
174            _ => DragHit::NoHit,
175        }
176    }
177    
178}