use gantz_core::node;
pub trait EdgeStyle {
fn edge_styling(&self, ctx: &EdgeStyleCtx) -> Option<EdgeStyling>;
}
#[non_exhaustive]
pub struct EdgeStyleCtx<'a> {
pub head: &'a gantz_ca::Head,
pub src: (node::Id, usize),
pub dst: (node::Id, usize),
}
impl<'a> EdgeStyleCtx<'a> {
pub fn new(head: &'a gantz_ca::Head, src: (node::Id, usize), dst: (node::Id, usize)) -> Self {
Self { head, src, dst }
}
}
#[derive(Clone, Debug)]
#[non_exhaustive]
pub struct EdgeStyling {
pub color: Option<egui::Color32>,
pub width_scale: f32,
pub dash: Option<(f32, f32)>,
pub strands: usize,
pub notch: Option<f32>,
pub hover_text: Option<String>,
}
impl Default for EdgeStyling {
fn default() -> Self {
Self {
color: None,
width_scale: 1.0,
dash: None,
strands: 1,
notch: None,
hover_text: None,
}
}
}
pub fn edge_styling(styles: &[&dyn EdgeStyle], ctx: &EdgeStyleCtx) -> Option<EdgeStyling> {
styles.iter().find_map(|s| s.edge_styling(ctx))
}
#[cfg(test)]
mod tests {
use super::*;
struct StubStyle {
src_node: node::Id,
color: egui::Color32,
}
impl EdgeStyle for StubStyle {
fn edge_styling(&self, ctx: &EdgeStyleCtx) -> Option<EdgeStyling> {
(ctx.src.0 == self.src_node).then(|| EdgeStyling {
color: Some(self.color),
..Default::default()
})
}
}
#[test]
fn first_claiming_styler_wins() {
let red = egui::Color32::RED;
let blue = egui::Color32::BLUE;
let a = StubStyle {
src_node: 0,
color: red,
};
let b = StubStyle {
src_node: 0,
color: blue,
};
let c = StubStyle {
src_node: 1,
color: blue,
};
let styles: [&dyn EdgeStyle; 3] = [&a, &b, &c];
let head = gantz_ca::Head::Branch("test".parse().unwrap());
let ctx = |src_node| EdgeStyleCtx {
head: &head,
src: (src_node, 0),
dst: (2, 0),
};
assert_eq!(edge_styling(&styles, &ctx(0)).unwrap().color, Some(red));
assert_eq!(edge_styling(&styles, &ctx(1)).unwrap().color, Some(blue));
assert!(edge_styling(&styles, &ctx(2)).is_none());
}
}