Skip to main content

devpage_design/display/
hit.rs

1//! Hit testing: a click answered from the index — the topmost chunk at the
2//! point whose node has an interaction and whose clipping frames show it.
3
4use kurbo::Rect as KRect;
5
6use super::*;
7
8impl Chunk {
9    /// Where its node can be clicked, in its space's coordinates.
10    pub fn hit(&self) -> Option<Hit> {
11        let (action, area) = self.action.as_ref()?;
12        let area = *area + self.origin;
13        let area = self.cut.map_or(area, |c| area.intersect(c));
14        Some(Hit {
15            action: action.clone(),
16            area,
17        })
18    }
19}
20
21impl List {
22    /// The interaction of the topmost node at `(x, y)`, in the design's
23    /// coordinates, that has one and whose clipping frames show it there.
24    pub fn action_at(&self, x: f64, y: f64) -> Option<&str> {
25        let point = KRect::new(x, y, x, y);
26        self.found(point, 0.0).into_iter().rev().find_map(|f| {
27            let chunk = &self.chunks[f.order];
28            let (action, _) = chunk.action.as_ref()?;
29            let a = chunk.hit()?.area + f.at;
30            let a = f.cut.map_or(a, |c| a.intersect(c));
31            (x >= a.x0 && y >= a.y0 && x < a.x1 && y < a.y1).then_some(action.as_str())
32        })
33    }
34}