Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add custom pin drawing functionality to PinInfo struct #48

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions examples/demo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ impl DemoNode {
struct DemoViewer;

impl SnarlViewer<DemoNode> for DemoViewer {
type Drawer = egui_snarl::ui::PinShape;

#[inline]
fn connect(&mut self, from: &OutPin, to: &InPin, snarl: &mut Snarl<DemoNode>) {
// Validate connection
Expand Down Expand Up @@ -179,7 +181,7 @@ impl SnarlViewer<DemoNode> for DemoViewer {
ui: &mut Ui,
scale: f32,
snarl: &mut Snarl<DemoNode>,
) -> PinInfo {
) -> PinInfo<Self::Drawer> {
match snarl[pin.id.node] {
DemoNode::Sink => {
assert_eq!(pin.id.input, 0, "Sink node has only one input");
Expand Down Expand Up @@ -394,7 +396,7 @@ impl SnarlViewer<DemoNode> for DemoViewer {
ui: &mut Ui,
_scale: f32,
snarl: &mut Snarl<DemoNode>,
) -> PinInfo {
) -> PinInfo<Self::Drawer> {
match snarl[pin.id.node] {
DemoNode::Sink => {
unreachable!("Sink node has no outputs")
Expand Down
2 changes: 1 addition & 1 deletion src/ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use self::{

pub use self::{
background_pattern::{BackgroundPattern, Grid, Viewport},
pin::{AnyPins, PinInfo, PinShape},
pin::{AnyPins, PinDrawer, PinInfo, PinShape},
viewer::SnarlViewer,
wire::{WireLayer, WireStyle},
};
Expand Down
68 changes: 53 additions & 15 deletions src/ui/pin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,9 @@ pub enum PinShape {
/// All fields are optional.
/// If a field is `None`, the default value is used derived from the graph style.
#[derive(Default)]
pub struct PinInfo {
pub struct PinInfo<T: PinDrawer> {
/// Shape of the pin.
pub shape: Option<PinShape>,
pub shape: Option<T>,

/// Size of the pin.
pub size: Option<f32>,
Expand All @@ -61,10 +61,17 @@ pub struct PinInfo {
pub wire_style: Option<WireStyle>,
}

impl PinInfo {
/// Customization for the pin.
/// This trait is used to customize the appearance of the pin.
pub trait PinDrawer: Sync + Send + From<PinShape> + Clone {
/// Draws the pin.
fn draw(&self, painter: &Painter, fill: Color32, stroke: Stroke, pos: Pos2, size: f32);
}

impl<T: PinDrawer> PinInfo<T> {
/// Sets the shape of the pin.
#[must_use]
pub const fn with_shape(mut self, shape: PinShape) -> Self {
pub fn with_shape(mut self, shape: T) -> Self {
self.shape = Some(shape);
self
}
Expand Down Expand Up @@ -101,42 +108,66 @@ impl PinInfo {
#[must_use]
pub fn circle() -> Self {
PinInfo {
shape: Some(PinShape::Circle),
..Default::default()
shape: Some(PinShape::Circle.into()),
size: Default::default(),
fill: Default::default(),
stroke: Default::default(),
wire_style: Default::default(),
}
}

/// Creates a triangle pin.
#[must_use]
pub fn triangle() -> Self {
PinInfo {
shape: Some(PinShape::Triangle),
..Default::default()
shape: Some(PinShape::Triangle.into()),
size: Default::default(),
fill: Default::default(),
stroke: Default::default(),
wire_style: Default::default(),
}
}

/// Creates a square pin.
#[must_use]
pub fn square() -> Self {
PinInfo {
shape: Some(PinShape::Square),
..Default::default()
shape: Some(PinShape::Square.into()),
size: Default::default(),
fill: Default::default(),
stroke: Default::default(),
wire_style: Default::default(),
}
}

/// Creates a star pin.
#[must_use]
pub fn star() -> Self {
PinInfo {
shape: Some(PinShape::Star),
..Default::default()
shape: Some(PinShape::Star.into()),
size: Default::default(),
fill: Default::default(),
stroke: Default::default(),
wire_style: Default::default(),
}
}

/// Creates a pin with the custom drawer.
#[must_use]
pub fn shape(drawer: T) -> PinInfo<T> {
PinInfo {
shape: Some(drawer),
size: Default::default(),
fill: Default::default(),
stroke: Default::default(),
wire_style: Default::default(),
}
}

/// Returns the shape of the pin.
#[must_use]
pub fn get_shape(&self, snarl_style: &SnarlStyle) -> PinShape {
self.shape.unwrap_or_else(|| snarl_style.get_pin_shape())
pub fn get_shape(&self, snarl_style: &SnarlStyle) -> T {
self.shape.clone().unwrap_or_else(|| Into::<T>::into(snarl_style.get_pin_shape()))
}

/// Returns fill color of the pin.
Expand Down Expand Up @@ -170,12 +201,19 @@ impl PinInfo {
let fill = self.get_fill(snarl_style, style);
let stroke = self.get_stroke(snarl_style, style, scale);
let size = self.size.zoomed(scale).unwrap_or(size);
draw_pin(painter, shape, fill, stroke, pos, size);

shape.draw(painter, fill, stroke, pos, size);

fill
}
}

impl PinDrawer for PinShape {
fn draw(&self, painter: &Painter, fill: Color32, stroke: Stroke, pos: Pos2, size: f32) {
draw_pin(painter, *self, fill, stroke, pos, size);
}
}

pub fn draw_pin(
painter: &Painter,
shape: PinShape,
Expand Down
23 changes: 17 additions & 6 deletions src/ui/viewer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,19 @@ use egui::{Color32, Painter, Pos2, Rect, Style, Ui};

use crate::{InPin, InPinId, NodeId, OutPin, OutPinId, Snarl};

use super::{pin::AnyPins, BackgroundPattern, NodeLayout, PinInfo, SnarlStyle, Viewport};
use super::{
pin::AnyPins, BackgroundPattern, NodeLayout, PinDrawer, PinInfo, SnarlStyle, Viewport,
};

/// `SnarlViewer` is a trait for viewing a Snarl.
///
/// It can extract necessary data from the nodes and controls their
/// response to certain events.
pub trait SnarlViewer<T> {
/// The drawer type for the pins.
/// If you use the default pin drawer, you can use `PinShape` as the drawer type.
type Drawer: PinDrawer;

/// Returns title of the node.
fn title(&mut self, node: &T) -> String;

Expand Down Expand Up @@ -76,8 +82,13 @@ pub trait SnarlViewer<T> {
fn inputs(&mut self, node: &T) -> usize;

/// Renders the node's input.
fn show_input(&mut self, pin: &InPin, ui: &mut Ui, scale: f32, snarl: &mut Snarl<T>)
-> PinInfo;
fn show_input(
&mut self,
pin: &InPin,
ui: &mut Ui,
scale: f32,
snarl: &mut Snarl<T>,
) -> PinInfo<Self::Drawer>;

/// Returns number of output pins of the node.
///
Expand All @@ -91,7 +102,7 @@ pub trait SnarlViewer<T> {
ui: &mut Ui,
scale: f32,
snarl: &mut Snarl<T>,
) -> PinInfo;
) -> PinInfo<Self::Drawer>;

/// Checks if node has something to show in body - between input and output pins.
#[inline]
Expand Down Expand Up @@ -298,7 +309,7 @@ pub trait SnarlViewer<T> {
fn draw_input_pin(
&mut self,
pin: &InPin,
pin_info: &PinInfo,
pin_info: &PinInfo<Self::Drawer>,
pos: Pos2,
size: f32,
snarl_style: &SnarlStyle,
Expand All @@ -322,7 +333,7 @@ pub trait SnarlViewer<T> {
fn draw_output_pin(
&mut self,
pin: &OutPin,
pin_info: &PinInfo,
pin_info: &PinInfo<Self::Drawer>,
pos: Pos2,
size: f32,
snarl_style: &SnarlStyle,
Expand Down