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