use jellyflow_core::{CanvasSize, NodeId};
use serde::{Deserialize, Serialize};
use crate::engine::{
LayoutDirection, LayoutEngineId, LayoutEngineRequest, LayoutOptions, LayoutRequest,
LayoutScope, LayoutSpacing,
};
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct LayoutPresetBuilder {
request: LayoutEngineRequest,
}
impl Default for LayoutPresetBuilder {
fn default() -> Self {
Self::workflow()
}
}
impl LayoutPresetBuilder {
pub fn workflow() -> Self {
Self::new(LayoutEngineId::dugong(), LayoutRequest::all())
}
pub fn tree() -> Self {
Self::new(LayoutEngineId::tidy_tree(), LayoutRequest::all()).with_options(LayoutOptions {
direction: LayoutDirection::TopToBottom,
spacing: LayoutSpacing {
nodesep: 32.0,
ranksep: 72.0,
edgesep: 16.0,
},
..LayoutOptions::default()
})
}
pub fn mind_map() -> Self {
Self::new(LayoutEngineId::mind_map_radial(), LayoutRequest::all())
}
pub fn freeform() -> Self {
Self::new(LayoutEngineId::mind_map_freeform(), LayoutRequest::all()).with_options(
LayoutOptions {
spacing: LayoutSpacing {
nodesep: 24.0,
ranksep: 24.0,
edgesep: 24.0,
},
..LayoutOptions::default()
},
)
}
pub fn new(engine: impl Into<LayoutEngineId>, layout: LayoutRequest) -> Self {
Self {
request: LayoutEngineRequest::new(engine, layout),
}
}
pub fn with_engine(mut self, engine: impl Into<LayoutEngineId>) -> Self {
self.request.engine = engine.into();
self
}
pub fn with_layout(mut self, layout: LayoutRequest) -> Self {
self.request.layout = layout;
self
}
pub fn with_options(mut self, options: LayoutOptions) -> Self {
self.request.layout.options = options;
self
}
pub fn with_direction(mut self, direction: LayoutDirection) -> Self {
self.request.layout.options.direction = direction;
self
}
pub fn with_spacing(mut self, spacing: LayoutSpacing) -> Self {
self.request.layout.options.spacing = spacing;
self
}
pub fn with_margin(mut self, margin: CanvasSize) -> Self {
self.request.layout.options.margin = margin;
self
}
pub fn with_default_node_size(mut self, size: CanvasSize) -> Self {
self.request.layout.options.default_node_size = size;
self
}
pub fn with_node_origin(mut self, node_origin: (f32, f32)) -> Self {
self.request.layout.options.node_origin = node_origin;
self
}
pub fn all(mut self) -> Self {
self.request.layout.scope = LayoutScope::All;
self
}
pub fn nodes(mut self, nodes: impl IntoIterator<Item = NodeId>) -> Self {
self.request.layout.scope = LayoutScope::Nodes {
nodes: nodes.into_iter().collect(),
};
self
}
pub fn with_scope(mut self, scope: LayoutScope) -> Self {
self.request.layout.scope = scope;
self
}
pub fn with_measured_node_sizes(
mut self,
sizes: impl IntoIterator<Item = (NodeId, CanvasSize)>,
) -> Self {
self.request.layout.measured_node_sizes.extend(sizes);
self
}
pub fn build(self) -> LayoutEngineRequest {
self.request
}
pub fn layout_request(&self) -> LayoutRequest {
self.request.layout.clone()
}
pub fn engine_request(&self) -> LayoutEngineRequest {
self.request.clone()
}
}
impl From<LayoutPresetBuilder> for LayoutEngineRequest {
fn from(value: LayoutPresetBuilder) -> Self {
value.build()
}
}