1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
//! Drag-and-drop state and messages for [`crate::DirectoryTree`].
//!
//! The widget tracks mouse press → hover → release and emits
//! [`DragOutcome::Completed`] on a valid drop. **No filesystem operations
//! are ever performed** — moving, copying, or rejecting the drop is the
//! application's decision (S7.5).
//!
//! ## Flow
//!
//! ```text
//! onmousedown → DragMsg::Pressed → drag becomes active
//! onmouseenter → DragMsg::Entered → hovered_target set iff valid
//! onmouseleave → DragMsg::Exited → hovered_target cleared
//! onmouseup → DragMsg::Released → click (S7.2) or DragCompleted
//! Escape key → DragMsg::Cancelled → drag cleared
//! ```
//!
//! The view crate calls [`crate::DirectoryTree::on_drag_msg`] with each
//! message and handles the returned [`DragOutcome`].
use PathBuf;
/// Active drag session.
/// A drag gesture event sent by the view to
/// [`crate::DirectoryTree::on_drag_msg`].
/// The side effect produced by [`crate::DirectoryTree::on_drag_msg`].
// ── Target validity ───────────────────────────────────────────────────────────
/// `true` iff `path` is a valid drop target given the current drag state
/// and the tree's node graph (S7.3).
///
/// A path is valid iff:
/// 1. It is a directory currently present in the tree.
/// 2. It is not a drag source.
/// 3. It is not a descendant of any drag source (component-wise prefix,
/// never a bare string prefix).
pub