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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
//! Data model for the snap engine.
//!
//! Defines the [`Snappable`] trait that movable types implement, the
//! input enums that select snap behaviour ([`SnapMode`],
//! [`ResizeEdge`]), and the result types ([`SnapResult`],
//! [`SnapGuide`]).
//!
//! Kept free of widget / event dependencies so the engine can be
//! re-used from any drag handler (window manager, node graph,
//! diagram editor, etc.).
use crateRect;
/// Opaque identifier for a snappable rect. Used by [`compute_snap`]
/// to skip self-matches when the moving rect is also present in the
/// target list. The `u64` payload is opaque to the engine; callers
/// pick a scheme that makes their rects distinguishable — pointer
/// values cast to `u64`, monotonic ids, hash of a name, anything that
/// is unique per logical entity.
///
/// [`compute_snap`]: crate::snap::compute_snap
;
/// What kind of drag operation produced the candidate rect. Moving
/// snaps treat the whole rect; resize snaps only consider edges that
/// the active resize handle actually controls, so a resize from the
/// right edge can't snap the LEFT side of the moving rect to a
/// target.
/// Which edge (or corner) is currently driving a resize. Eight
/// compass directions cover the standard handle layout.
/// Trait implemented by anything that wants to participate in the
/// snap layout system. Rust's equivalent of a C# interface: callers
/// take `&dyn Snappable` (or `&mut dyn Snappable`) and the engine
/// reads / writes the rect through these accessors without caring
/// about the underlying concrete type.
///
/// The two opt-in flags ([`is_snap_source`], [`is_snap_target`])
/// default to `true` — implementors only override when an instance
/// should sit out (e.g., a window is hidden / minimised and shouldn't
/// pull other windows toward an off-screen edge).
///
/// [`is_snap_source`]: Snappable::is_snap_source
/// [`is_snap_target`]: Snappable::is_snap_target
/// Output of [`compute_snap`]. The engine returns BOTH the corrected
/// rect (with any snap adjustments applied) AND the visual guides the
/// drag UI should render — alignment lines, equal-spacing dimension
/// markers, etc. The dragger persists the rect; the guide overlay
/// reads `guides` and paints them on top.
///
/// [`compute_snap`]: crate::snap::compute_snap
/// One visual guide. Vertical / horizontal lines come from
/// edge-alignment snaps; spacing markers come from equal-gap
/// detection. Coordinates are in the same space as the input rects
/// — typically the scene's root space.