use serde::Deserialize;
use crate::layout::strategies::LayoutStrategy;
#[derive(Clone, Debug, Deserialize)]
pub enum ArrowStyle {
Triangle,
Dot,
}
#[derive(Clone, Debug, Deserialize)]
pub enum FanoutMode {
Symmetric,
Offset,
Random,
}
#[derive(Clone, Debug, Deserialize)]
#[serde(default)]
pub struct RenderProfile {
pub name: String,
pub title: Option<String>,
pub tool: Option<String>,
pub show_debug_overlay: bool,
pub no_arrows: bool,
pub arrow_size: f32,
pub arrow_style: ArrowStyle,
pub loop_radius: f32,
pub loop_angle: f32,
pub fanout_max_bend: f32,
pub fanout_mode: FanoutMode,
pub no_fanout: bool,
pub spacing: f32,
pub font_size: f32,
pub layout: LayoutStrategy,
pub draw_order: Vec<String>,
pub stroke_width: f32,
}
impl Default for RenderProfile {
fn default() -> Self {
Self {
name: "default".into(),
title: None,
tool: None,
show_debug_overlay: false,
no_arrows: false,
arrow_size: 6.0,
arrow_style: ArrowStyle::Triangle,
loop_radius: 10.0,
loop_angle: 45.0,
fanout_max_bend: 40.0,
fanout_mode: FanoutMode::Symmetric,
no_fanout: false,
spacing: 80.0,
font_size: 14.0,
layout: LayoutStrategy::TreeTopDown,
draw_order: vec!["edges".into(), "nodes".into()],
stroke_width: 1.0,
}
}
}
impl RenderProfile {
pub fn preset(name: &str) -> Self {
match name {
"compact" | "default" => Self {
name: "compact".into(),
title: None,
tool: None,
show_debug_overlay: false,
no_arrows: false,
arrow_size: 6.0,
arrow_style: ArrowStyle::Triangle,
loop_radius: 10.0,
loop_angle: 45.0,
fanout_max_bend: 40.0,
fanout_mode: FanoutMode::Symmetric,
no_fanout: false,
spacing: 80.0,
font_size: 10.0,
stroke_width: 1.0,
layout: LayoutStrategy::TreeTopDown,
draw_order: vec!["edges".into(), "nodes".into()],
},
"debug" => Self {
name: "debug".into(),
title: None,
tool: None,
show_debug_overlay: true,
no_arrows: false,
arrow_size: 6.0,
arrow_style: ArrowStyle::Triangle,
loop_radius: 10.0,
loop_angle: 45.0,
fanout_max_bend: 40.0,
fanout_mode: FanoutMode::Symmetric,
no_fanout: false,
spacing: 80.0,
font_size: 12.0,
stroke_width: 1.0,
layout: LayoutStrategy::TreeTopDown,
draw_order: vec!["edges".into(), "nodes".into()],
},
_ => Self::default(),
}
}
}
#[derive(Clone, Debug, Deserialize, Default)]
#[serde(default)]
pub struct ProfileConfig {
pub title: Option<String>,
pub show_debug_overlay: Option<bool>,
pub layout_strategy: Option<LayoutStrategy>,
pub draw_order: Option<Vec<String>>,
pub no_arrows: Option<bool>,
pub arrow_size: Option<f32>,
pub arrow_style: Option<ArrowStyle>,
pub loop_radius: Option<f32>,
pub loop_angle: Option<f32>,
pub fanout_max_bend: Option<f32>,
pub fanout_mode: Option<FanoutMode>,
pub no_fanout: Option<bool>,
pub stroke_width: Option<f32>,
}
impl ProfileConfig {
pub fn apply_to(&self, profile: &mut RenderProfile) {
if let Some(t) = &self.title {
profile.title = Some(t.clone());
}
if let Some(d) = self.show_debug_overlay {
profile.show_debug_overlay = d;
}
if let Some(ls) = &self.layout_strategy {
profile.layout = ls.clone();
}
if let Some(order) = &self.draw_order {
profile.draw_order = order.clone();
}
if let Some(n) = self.no_arrows {
profile.no_arrows = n;
}
if let Some(sz) = self.arrow_size {
profile.arrow_size = sz;
}
if let Some(st) = &self.arrow_style {
profile.arrow_style = st.clone();
}
if let Some(r) = self.loop_radius {
profile.loop_radius = r;
}
if let Some(a) = self.loop_angle {
profile.loop_angle = a;
}
if let Some(m) = self.fanout_max_bend {
profile.fanout_max_bend = m;
}
if let Some(mode) = &self.fanout_mode {
profile.fanout_mode = mode.clone();
}
if let Some(off) = self.no_fanout {
profile.no_fanout = off;
}
if let Some(sw) = self.stroke_width {
profile.stroke_width = sw;
}
}
}