///|
/// A data-point anchor and its intrinsic drawing coordinates.
/// Indices identify a point within this frame's panel and artist ordering.
pub struct HitPoint {
panel_index : Int32
artist_index : Int32
point_index : Int32
data_x : Double
data_y : Double
screen_x : Double
screen_y : Double
} derive(Eq, Debug)
///|
pub extend HitPoint with Eq::{equal, not_equal}
///|
pub extend HitPoint with @debug.Debug::{to_repr}
///|
pub fn hit_point(
panel_index : Int32,
artist_index : Int32,
point_index : Int32,
data_x : Double,
data_y : Double,
screen_x : Double,
screen_y : Double,
) -> HitPoint {
{
panel_index,
artist_index,
point_index,
data_x,
data_y,
screen_x,
screen_y,
}
}
///|
/// A prepared SVG snapshot with immutable semantic hit targets and no UI types.
pub struct Drawing {
priv width : Int32
priv height : Int32
priv svg : String
priv points : Array[HitPoint]
priv targets : Array[HitTarget]
priv exclusions : Array[(Int32, (Double, Double, Double, Double))]
}
///|
/// Capture independent copies of point, semantic-target and exclusion arrays.
/// Exclusions are (panel index, intrinsic left/top/width/height) overlay rectangles.
pub fn drawing(
width : Int32,
height : Int32,
svg : String,
points : Array[HitPoint],
targets~ : Array[HitTarget] = [],
exclusions~ : Array[(Int32, (Double, Double, Double, Double))] = [],
) -> Drawing {
{
width,
height,
svg,
points: points.copy(),
targets: targets.copy(),
exclusions: exclusions.copy(),
}
}
///|
pub fn Drawing::width(self : Drawing) -> Int32 {
self.width
}
///|
pub fn Drawing::height(self : Drawing) -> Int32 {
self.height
}
///|
pub fn Drawing::svg(self : Drawing) -> String {
self.svg
}
///|
/// Return a copy; mutating it cannot change this drawing's hit targets.
pub fn Drawing::points(self : Drawing) -> Array[HitPoint] {
self.points.copy()
}
///|
/// Return an independent array; target values contain no mutable collections.
pub fn Drawing::targets(self : Drawing) -> Array[HitTarget] {
self.targets.copy()
}
///|
/// Look up metadata by exact point equality within this prepared frame.
pub fn Drawing::hit_info(self : Drawing, point : HitPoint) -> HitInfo? {
for target in self.targets {
if target.info.point == point {
return Some(target.info)
}
}
None
}