use azul_core::dom::{DomId, DomNodeId, NodeId, OptionDomNodeId};
use azul_core::drag::{ActiveDragType, DragContext};
use azul_css::{impl_option, impl_option_inner, AzString, OptionString};
pub use azul_core::drag::DragData;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(C)]
pub enum DragType {
Node,
File,
}
#[derive(Debug, Clone, PartialEq)]
#[repr(C)]
pub struct DragState {
pub drag_type: DragType,
pub source_node: OptionDomNodeId,
pub current_drop_target: OptionDomNodeId,
pub file_path: OptionString,
}
impl DragState {
pub fn from_context(ctx: &DragContext) -> Option<Self> {
match &ctx.drag_type {
ActiveDragType::Node(node_drag) => Some(DragState {
drag_type: DragType::Node,
source_node: OptionDomNodeId::Some(DomNodeId {
dom: node_drag.dom_id,
node: azul_core::styled_dom::NodeHierarchyItemId::from_crate_internal(Some(node_drag.node_id)),
}),
current_drop_target: node_drag.current_drop_target,
file_path: OptionString::None,
}),
ActiveDragType::FileDrop(file_drop) => Some(DragState {
drag_type: DragType::File,
source_node: OptionDomNodeId::None,
current_drop_target: file_drop.drop_target,
file_path: file_drop.files.as_ref().first().cloned().into(),
}),
_ => None, }
}
}
impl_option!(
DragState,
OptionDragState,
copy = false,
[Debug, Clone, PartialEq]
);
#[derive(Debug, Clone, PartialEq, Default)]
pub struct DragDropManager {
pub active_drag: Option<DragContext>,
}
impl DragDropManager {
pub fn new() -> Self {
Self { active_drag: None }
}
pub fn start_node_drag(&mut self, source_node: DomNodeId) {
self.active_drag = Some(DragContext::node_drag(
source_node.dom,
source_node.node.into_crate_internal().unwrap_or(NodeId::ZERO),
azul_core::geom::LogicalPosition::zero(),
DragData::default(),
0,
));
}
pub fn start_file_drag(&mut self, file_path: AzString) {
self.active_drag = Some(DragContext::file_drop(
vec![file_path],
azul_core::geom::LogicalPosition::zero(),
0,
));
}
pub fn set_drop_target(&mut self, target: Option<DomNodeId>) {
if let Some(ref mut drag) = self.active_drag {
if let Some(node_drag) = drag.as_node_drag_mut() {
node_drag.current_drop_target = target.into();
}
}
}
pub fn end_drag(&mut self) -> Option<DragContext> {
self.active_drag.take()
}
pub fn is_dragging(&self) -> bool {
self.active_drag.is_some()
}
pub fn is_dragging_node(&self) -> bool {
self.active_drag.as_ref().is_some_and(|d| d.is_node_drag())
}
pub fn is_dragging_file(&self) -> bool {
self.active_drag.as_ref().is_some_and(|d| d.is_file_drop())
}
pub fn get_drag_context(&self) -> Option<&DragContext> {
self.active_drag.as_ref()
}
pub fn get_drag_state(&self) -> Option<DragState> {
self.active_drag.as_ref().and_then(DragState::from_context)
}
pub fn cancel_drag(&mut self) {
self.active_drag = None;
}
}