azul_layout/managers/
drag_drop.rs1use azul_core::dom::{DomId, DomNodeId, NodeId, OptionDomNodeId};
7use azul_core::drag::{ActiveDragType, DragContext};
8use azul_css::{impl_option, impl_option_inner, AzString, OptionString};
9
10pub use azul_core::drag::DragData;
12
13#[derive(Debug, Clone, Copy, PartialEq, Eq)]
15#[repr(C)]
16pub enum DragType {
17 Node,
19 File,
21}
22
23#[derive(Debug, Clone, PartialEq)]
25#[repr(C)]
26pub struct DragState {
27 pub drag_type: DragType,
29 pub source_node: OptionDomNodeId,
31 pub current_drop_target: OptionDomNodeId,
33 pub file_path: OptionString,
35}
36
37impl DragState {
38 pub fn from_context(ctx: &DragContext) -> Option<Self> {
40 match &ctx.drag_type {
41 ActiveDragType::Node(node_drag) => Some(DragState {
42 drag_type: DragType::Node,
43 source_node: OptionDomNodeId::Some(DomNodeId {
44 dom: node_drag.dom_id,
45 node: azul_core::styled_dom::NodeHierarchyItemId::from_crate_internal(Some(node_drag.node_id)),
46 }),
47 current_drop_target: node_drag.current_drop_target,
48 file_path: OptionString::None,
49 }),
50 ActiveDragType::FileDrop(file_drop) => Some(DragState {
51 drag_type: DragType::File,
52 source_node: OptionDomNodeId::None,
53 current_drop_target: file_drop.drop_target,
54 file_path: file_drop.files.as_ref().first().cloned().into(),
55 }),
56 _ => None, }
58 }
59}
60
61impl_option!(
62 DragState,
63 OptionDragState,
64 copy = false,
65 [Debug, Clone, PartialEq]
66);
67
68#[derive(Debug, Clone, PartialEq, Default)]
73pub struct DragDropManager {
74 pub active_drag: Option<DragContext>,
76}
77
78impl DragDropManager {
79 pub fn new() -> Self {
81 Self { active_drag: None }
82 }
83
84 pub fn start_node_drag(&mut self, source_node: DomNodeId) {
86 self.active_drag = Some(DragContext::node_drag(
87 source_node.dom,
88 source_node.node.into_crate_internal().unwrap_or(NodeId::ZERO),
89 azul_core::geom::LogicalPosition::zero(),
90 DragData::default(),
91 0,
92 ));
93 }
94
95 pub fn start_file_drag(&mut self, file_path: AzString) {
97 self.active_drag = Some(DragContext::file_drop(
98 vec![file_path],
99 azul_core::geom::LogicalPosition::zero(),
100 0,
101 ));
102 }
103
104 pub fn set_drop_target(&mut self, target: Option<DomNodeId>) {
106 if let Some(ref mut drag) = self.active_drag {
107 if let Some(node_drag) = drag.as_node_drag_mut() {
108 node_drag.current_drop_target = target.into();
109 }
110 }
111 }
112
113 pub fn end_drag(&mut self) -> Option<DragContext> {
115 self.active_drag.take()
116 }
117
118 pub fn is_dragging(&self) -> bool {
120 self.active_drag.is_some()
121 }
122
123 pub fn is_dragging_node(&self) -> bool {
125 self.active_drag.as_ref().is_some_and(|d| d.is_node_drag())
126 }
127
128 pub fn is_dragging_file(&self) -> bool {
130 self.active_drag.as_ref().is_some_and(|d| d.is_file_drop())
131 }
132
133 pub fn get_drag_context(&self) -> Option<&DragContext> {
135 self.active_drag.as_ref()
136 }
137
138 pub fn get_drag_state(&self) -> Option<DragState> {
140 self.active_drag.as_ref().and_then(DragState::from_context)
141 }
142
143 pub fn cancel_drag(&mut self) {
145 self.active_drag = None;
146 }
147}