use iced_widget::core::Theme;
use super::{
AnchorStatus, AnchorStyle, CuttingToolStyle, EdgeStatus, EdgeStyle, GraphStyle, MinimapStyle,
NodeStatus, NodeStyle, ParticleStyle, PinStatus, PinStyle, SelectionBoxStyle,
default_anchor_style, default_cutting_tool_style, default_edge_style, default_graph_style,
default_minimap_style, default_node_style, default_particle_style, default_pin_style,
default_selection_box_style,
};
use crate::ids::Ids;
use crate::node_pin::PinInfo;
pub type NodeStyleFn<'a, Theme> = Box<dyn Fn(&Theme, NodeStatus) -> NodeStyle + 'a>;
pub type PinStyleFn<'a, Theme, I> =
Box<dyn Fn(&Theme, &PinInfo<'_, I>, Option<&PinInfo<'_, I>>, PinStatus) -> PinStyle + 'a>;
pub type EdgeStyleFn<'a, Theme, I> =
Box<dyn Fn(&Theme, EdgeStatus, PinInfo<'_, I>, PinInfo<'_, I>) -> EdgeStyle + 'a>;
pub type DragEdgeStyleFn<'a, Theme, I> = Box<dyn Fn(&Theme, PinInfo<'_, I>) -> EdgeStyle + 'a>;
pub type AnchorStyleFn<'a, Theme> = Box<dyn Fn(&Theme, AnchorStatus) -> AnchorStyle + 'a>;
pub type GraphStyleFn<'a, Theme> = Box<dyn Fn(&Theme) -> GraphStyle + 'a>;
pub type SelectionBoxStyleFn<'a, Theme> = Box<dyn Fn(&Theme) -> SelectionBoxStyle + 'a>;
pub type CuttingToolStyleFn<'a, Theme> = Box<dyn Fn(&Theme) -> CuttingToolStyle + 'a>;
pub type ParticleStyleFn<'a, Theme> = Box<dyn Fn(&Theme) -> ParticleStyle + 'a>;
pub type MinimapStyleFn<'a, Theme> = Box<dyn Fn(&Theme) -> MinimapStyle + 'a>;
pub trait Catalog {
type NodeClass<'a>;
type PinClass<'a, I: Ids>;
type EdgeClass<'a, I: Ids>;
type DragEdgeClass<'a, I: Ids>;
type AnchorClass<'a>;
type GraphClass<'a>;
type SelectionBoxClass<'a>;
type CuttingToolClass<'a>;
type ParticleClass<'a>;
type MinimapClass<'a>;
fn default_node<'a>() -> Self::NodeClass<'a>;
fn node(&self, class: &Self::NodeClass<'_>, status: NodeStatus) -> NodeStyle;
fn default_pin<'a, I: Ids>() -> Self::PinClass<'a, I>;
fn pin<I: Ids>(
&self,
class: &Self::PinClass<'_, I>,
pin: &PinInfo<'_, I>,
other: Option<&PinInfo<'_, I>>,
status: PinStatus,
) -> PinStyle;
fn default_edge<'a, I: Ids>() -> Self::EdgeClass<'a, I>;
fn edge<I: Ids>(
&self,
class: &Self::EdgeClass<'_, I>,
status: EdgeStatus,
from: PinInfo<'_, I>,
to: PinInfo<'_, I>,
) -> EdgeStyle;
fn default_drag_edge<'a, I: Ids>() -> Self::DragEdgeClass<'a, I>;
fn drag_edge<I: Ids>(
&self,
class: &Self::DragEdgeClass<'_, I>,
source: PinInfo<'_, I>,
) -> EdgeStyle;
fn default_anchor<'a>() -> Self::AnchorClass<'a>;
fn anchor(&self, class: &Self::AnchorClass<'_>, status: AnchorStatus) -> AnchorStyle;
fn default_graph<'a>() -> Self::GraphClass<'a>;
fn graph(&self, class: &Self::GraphClass<'_>) -> GraphStyle;
fn default_selection_box<'a>() -> Self::SelectionBoxClass<'a>;
fn selection_box(&self, class: &Self::SelectionBoxClass<'_>) -> SelectionBoxStyle;
fn default_cutting_tool<'a>() -> Self::CuttingToolClass<'a>;
fn cutting_tool(&self, class: &Self::CuttingToolClass<'_>) -> CuttingToolStyle;
fn default_particle<'a>() -> Self::ParticleClass<'a>;
fn particle(&self, class: &Self::ParticleClass<'_>) -> ParticleStyle;
fn default_minimap<'a>() -> Self::MinimapClass<'a>;
fn minimap(&self, class: &Self::MinimapClass<'_>) -> MinimapStyle;
}
impl Catalog for Theme {
type NodeClass<'a> = NodeStyleFn<'a, Self>;
type PinClass<'a, I: Ids> = PinStyleFn<'a, Self, I>;
type EdgeClass<'a, I: Ids> = EdgeStyleFn<'a, Self, I>;
type DragEdgeClass<'a, I: Ids> = DragEdgeStyleFn<'a, Self, I>;
type AnchorClass<'a> = AnchorStyleFn<'a, Self>;
type GraphClass<'a> = GraphStyleFn<'a, Self>;
type SelectionBoxClass<'a> = SelectionBoxStyleFn<'a, Self>;
type CuttingToolClass<'a> = CuttingToolStyleFn<'a, Self>;
type ParticleClass<'a> = ParticleStyleFn<'a, Self>;
type MinimapClass<'a> = MinimapStyleFn<'a, Self>;
fn default_node<'a>() -> Self::NodeClass<'a> {
Box::new(default_node_style)
}
fn node(&self, class: &Self::NodeClass<'_>, status: NodeStatus) -> NodeStyle {
class(self, status)
}
fn default_pin<'a, I: Ids>() -> Self::PinClass<'a, I> {
Box::new(|theme, _pin, _other, status| default_pin_style(theme, status))
}
fn pin<I: Ids>(
&self,
class: &Self::PinClass<'_, I>,
pin: &PinInfo<'_, I>,
other: Option<&PinInfo<'_, I>>,
status: PinStatus,
) -> PinStyle {
class(self, pin, other, status)
}
fn default_edge<'a, I: Ids>() -> Self::EdgeClass<'a, I> {
Box::new(|theme, status, _from, _to| default_edge_style(theme, status))
}
fn edge<I: Ids>(
&self,
class: &Self::EdgeClass<'_, I>,
status: EdgeStatus,
from: PinInfo<'_, I>,
to: PinInfo<'_, I>,
) -> EdgeStyle {
class(self, status, from, to)
}
fn default_drag_edge<'a, I: Ids>() -> Self::DragEdgeClass<'a, I> {
Box::new(|theme, _source| default_edge_style(theme, EdgeStatus::Idle))
}
fn drag_edge<I: Ids>(
&self,
class: &Self::DragEdgeClass<'_, I>,
source: PinInfo<'_, I>,
) -> EdgeStyle {
class(self, source)
}
fn default_anchor<'a>() -> Self::AnchorClass<'a> {
Box::new(default_anchor_style)
}
fn anchor(&self, class: &Self::AnchorClass<'_>, status: AnchorStatus) -> AnchorStyle {
class(self, status)
}
fn default_graph<'a>() -> Self::GraphClass<'a> {
Box::new(default_graph_style)
}
fn graph(&self, class: &Self::GraphClass<'_>) -> GraphStyle {
class(self)
}
fn default_selection_box<'a>() -> Self::SelectionBoxClass<'a> {
Box::new(default_selection_box_style)
}
fn selection_box(&self, class: &Self::SelectionBoxClass<'_>) -> SelectionBoxStyle {
class(self)
}
fn default_cutting_tool<'a>() -> Self::CuttingToolClass<'a> {
Box::new(default_cutting_tool_style)
}
fn cutting_tool(&self, class: &Self::CuttingToolClass<'_>) -> CuttingToolStyle {
class(self)
}
fn default_particle<'a>() -> Self::ParticleClass<'a> {
Box::new(default_particle_style)
}
fn particle(&self, class: &Self::ParticleClass<'_>) -> ParticleStyle {
class(self)
}
fn default_minimap<'a>() -> Self::MinimapClass<'a> {
Box::new(default_minimap_style)
}
fn minimap(&self, class: &Self::MinimapClass<'_>) -> MinimapStyle {
class(self)
}
}