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#[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 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 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 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 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 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 DragHit::NoHit
172 }
173 }
174 _ => DragHit::NoHit,
175 }
176 }
177
178}