dioxus_mind_elixir/plugins/
gesture.rs1use crate::{LayoutDirection, MindMapError, Placement, Point};
3
4#[derive(Clone, Copy, Debug, PartialEq)]
6pub struct HitRect {
7 pub x: f64,
9 pub y: f64,
11 pub width: f64,
13 pub height: f64,
15}
16impl HitRect {
17 pub fn validate(self) -> Result<(), MindMapError> {
19 if [self.x, self.y, self.width, self.height]
20 .iter()
21 .all(|v| v.is_finite())
22 && self.width > 0.0
23 && self.height > 0.0
24 {
25 Ok(())
26 } else {
27 Err(MindMapError::InvalidGeometry)
28 }
29 }
30 pub fn contains(self, point: Point) -> bool {
32 point.x >= self.x
33 && point.x <= self.x + self.width
34 && point.y >= self.y
35 && point.y <= self.y + self.height
36 }
37 pub fn intersects(self, start: Point, end: Point) -> bool {
39 self.x <= start.x.max(end.x)
40 && self.x + self.width >= start.x.min(end.x)
41 && self.y <= start.y.max(end.y)
42 && self.y + self.height >= start.y.min(end.y)
43 }
44}
45pub fn is_drag(start: Point, current: Point) -> bool {
47 (current.x - start.x).hypot(current.y - start.y) >= 5.0
48}
49pub fn drop_placement(
52 id: &str,
53 rect: HitRect,
54 at: Point,
55 layout: LayoutDirection,
56 scale: f64,
57) -> Result<Placement, MindMapError> {
58 rect.validate()?;
59 if !scale.is_finite() || scale <= 0.0 || !at.x.is_finite() || !at.y.is_finite() {
60 return Err(MindMapError::InvalidGeometry);
61 }
62 let (offset, length) = if layout == LayoutDirection::Down {
63 (at.x - rect.x, rect.width)
64 } else {
65 (at.y - rect.y, rect.height)
66 };
67 let band = (12.0 * scale).min(length / 3.0);
68 Ok(if offset < band {
69 Placement::Before(id.into())
70 } else if offset > length - band {
71 Placement::After(id.into())
72 } else {
73 Placement::In(id.into())
74 })
75}
76pub fn edge_pan(bounds: HitRect, at: Point) -> Result<Point, MindMapError> {
78 bounds.validate()?;
79 if !at.x.is_finite() || !at.y.is_finite() {
80 return Err(MindMapError::InvalidGeometry);
81 }
82 let axis = |v: f64, low: f64, length: f64| {
83 if v < low + 50.0 {
84 ((low + 50.0 - v) / 50.0).clamp(0.0, 1.0) * 10.0
85 } else if v > low + length - 50.0 {
86 -((v - (low + length - 50.0)) / 50.0).clamp(0.0, 1.0) * 10.0
87 } else {
88 0.0
89 }
90 };
91 Ok(Point {
92 x: axis(at.x, bounds.x, bounds.width),
93 y: axis(at.y, bounds.y, bounds.height),
94 })
95}