From ac74bd99039bc7414f0ad295710176a195808892 Mon Sep 17 00:00:00 2001 From: Keavon Chambers Date: Wed, 12 Nov 2025 01:14:17 -0800 Subject: [PATCH] Allow the Stroke node to receive "Dash Lengths" values from the node graph --- .../document/graph_operation/utility_types.rs | 2 +- .../document/node_graph/node_properties.rs | 7 +++-- node-graph/gcore/src/vector/vector_nodes.rs | 28 ++++++++++++++++--- 3 files changed, 30 insertions(+), 7 deletions(-) diff --git a/editor/src/messages/portfolio/document/graph_operation/utility_types.rs b/editor/src/messages/portfolio/document/graph_operation/utility_types.rs index 4079fefd..80e00544 100644 --- a/editor/src/messages/portfolio/document/graph_operation/utility_types.rs +++ b/editor/src/messages/portfolio/document/graph_operation/utility_types.rs @@ -388,7 +388,7 @@ impl<'a> ModifyInputsContext<'a> { self.set_input_with_refresh(input_connector, NodeInput::value(TaggedValue::F64(stroke.join_miter_limit), false), false); let input_connector = InputConnector::node(stroke_node_id, graphene_std::vector::stroke::PaintOrderInput::INDEX); self.set_input_with_refresh(input_connector, NodeInput::value(TaggedValue::PaintOrder(stroke.paint_order), false), false); - let input_connector = InputConnector::node(stroke_node_id, graphene_std::vector::stroke::DashLengthsInput::INDEX); + let input_connector = InputConnector::node(stroke_node_id, graphene_std::vector::stroke::DashLengthsInput::>::INDEX); self.set_input_with_refresh(input_connector, NodeInput::value(TaggedValue::VecF64(stroke.dash_lengths), false), true); let input_connector = InputConnector::node(stroke_node_id, graphene_std::vector::stroke::DashOffsetInput::INDEX); self.set_input_with_refresh(input_connector, NodeInput::value(TaggedValue::F64(stroke.dash_offset), false), true); diff --git a/editor/src/messages/portfolio/document/node_graph/node_properties.rs b/editor/src/messages/portfolio/document/node_graph/node_properties.rs index 0dd2d590..184df8bf 100644 --- a/editor/src/messages/portfolio/document/node_graph/node_properties.rs +++ b/editor/src/messages/portfolio/document/node_graph/node_properties.rs @@ -1849,7 +1849,7 @@ pub fn stroke_properties(node_id: NodeId, context: &mut NodePropertiesContext) - _ => &StrokeJoin::Miter, }; - let dash_lengths_val = match &document_node.inputs[DashLengthsInput::INDEX].as_value() { + let dash_lengths_val = match &document_node.inputs[DashLengthsInput::>::INDEX].as_value() { Some(TaggedValue::VecF64(x)) => x, _ => &vec![], }; @@ -1877,7 +1877,10 @@ pub fn stroke_properties(node_id: NodeId, context: &mut NodePropertiesContext) - .for_socket(ParameterWidgetsInfo::new(node_id, PaintOrderInput::INDEX, true, context)) .property_row(); let disabled_number_input = NumberInput::default().unit(" px").disabled(has_dash_lengths); - let dash_lengths = array_of_number_widget(ParameterWidgetsInfo::new(node_id, DashLengthsInput::INDEX, true, context), TextInput::default().centered(true)); + let dash_lengths = array_of_number_widget( + ParameterWidgetsInfo::new(node_id, DashLengthsInput::>::INDEX, true, context), + TextInput::default().centered(true), + ); let number_input = disabled_number_input; let dash_offset = number_widget(ParameterWidgetsInfo::new(node_id, DashOffsetInput::INDEX, true, context), number_input); diff --git a/node-graph/gcore/src/vector/vector_nodes.rs b/node-graph/gcore/src/vector/vector_nodes.rs index 97168b82..cff73a6e 100644 --- a/node-graph/gcore/src/vector/vector_nodes.rs +++ b/node-graph/gcore/src/vector/vector_nodes.rs @@ -146,12 +146,31 @@ async fn fill + 'n + Send, V: VectorTableIterMut + 'n + Send>( content } +trait IntoF64Vec { + fn into_vec(self) -> Vec; +} +impl IntoF64Vec for f64 { + fn into_vec(self) -> Vec { + vec![self] + } +} +impl IntoF64Vec for Vec { + fn into_vec(self) -> Vec { + self + } +} +impl IntoF64Vec for String { + fn into_vec(self) -> Vec { + self.split(&[',', ' ']).filter(|s| !s.is_empty()).filter_map(|s| s.parse::().ok()).collect() + } +} + /// Applies a stroke style to the vector content, giving an appearance to the area within the outline of the geometry. #[node_macro::node(category("Vector: Style"), path(graphene_core::vector), properties("stroke_properties"))] -async fn stroke( +async fn stroke( _: impl Ctx, /// The content with vector paths to apply the stroke style to. - #[implementations(Table, Table)] + #[implementations(Table, Table, Table, Table, Table, Table)] mut content: Table, /// The stroke color. #[default(Color::BLACK)] @@ -173,7 +192,8 @@ async fn stroke( /// paint_order: PaintOrder, /// The stroke dash lengths. Each length forms a distance in a pattern where the first length is a dash, the second is a gap, and so on. If the list is an odd length, the pattern repeats with solid-gap roles reversed. - dash_lengths: Vec, + #[implementations(Vec, f64, String, Vec, f64, String)] + dash_lengths: L, /// The phase offset distance from the starting point of the dash pattern. #[unit(" px")] dash_offset: f64, @@ -184,7 +204,7 @@ where let stroke = Stroke { color: color.into(), weight, - dash_lengths, + dash_lengths: dash_lengths.into_vec(), dash_offset, cap, join,