From 64be2d3d957b4f58111c8b1436aea38295d601fe Mon Sep 17 00:00:00 2001 From: Tyooughtul Date: Wed, 25 Feb 2026 10:10:58 +0800 Subject: [PATCH 1/7] fix: replace hardcoded input indices with ::INDEX constants Fixes #1490 (fix conflicts) Conflicts: editor/src/messages/tool/common_functionality/shapes/arrow_shape.rs editor/src/messages/tool/common_functionality/shapes/line_shape.rs --- .../graph_operation/transform_utils.rs | 43 +++++++++++++++---- .../document/graph_operation/utility_types.rs | 8 ++-- .../shape_gizmos/circle_arc_radius_handle.rs | 3 +- .../shape_gizmos/number_of_points_dial.rs | 3 +- .../gizmos/shape_gizmos/sweep_angle_gizmo.rs | 6 ++- .../common_functionality/shapes/arc_shape.rs | 4 +- .../shapes/arrow_shape.rs | 4 +- .../shapes/circle_shape.rs | 3 +- .../shapes/ellipse_shape.rs | 6 ++- .../common_functionality/shapes/line_shape.rs | 4 +- .../shapes/polygon_shape.rs | 6 ++- .../shapes/rectangle_shape.rs | 6 ++- .../shapes/shape_utility.rs | 6 +-- .../common_functionality/shapes/star_shape.rs | 6 ++- 14 files changed, 76 insertions(+), 32 deletions(-) diff --git a/editor/src/messages/portfolio/document/graph_operation/transform_utils.rs b/editor/src/messages/portfolio/document/graph_operation/transform_utils.rs index db4e110e77..ca3976cea0 100644 --- a/editor/src/messages/portfolio/document/graph_operation/transform_utils.rs +++ b/editor/src/messages/portfolio/document/graph_operation/transform_utils.rs @@ -2,7 +2,9 @@ use crate::messages::portfolio::document::utility_types::network_interface::{Inp use glam::{DAffine2, DVec2}; use graph_craft::document::value::TaggedValue; use graph_craft::document::{NodeId, NodeInput}; +use graphene_std::NodeInputDecleration; use graphene_std::subpath::Subpath; +use graphene_std::transform_nodes::transform::*; use graphene_std::vector::PointId; /// Convert an affine transform into the tuple `(scale, angle, translation, shear)` assuming `shear.y = 0`. @@ -37,10 +39,10 @@ pub fn update_transform(network_interface: &mut NodeNetworkInterface, node_id: & let rotation = rotation.to_degrees(); let shear = DVec2::new(shear.x.atan().to_degrees(), shear.y.atan().to_degrees()); - network_interface.set_input(&InputConnector::node(*node_id, 1), NodeInput::value(TaggedValue::DVec2(translation), false), &[]); - network_interface.set_input(&InputConnector::node(*node_id, 2), NodeInput::value(TaggedValue::F64(rotation), false), &[]); - network_interface.set_input(&InputConnector::node(*node_id, 3), NodeInput::value(TaggedValue::DVec2(scale), false), &[]); - network_interface.set_input(&InputConnector::node(*node_id, 4), NodeInput::value(TaggedValue::DVec2(shear), false), &[]); + network_interface.set_input(&InputConnector::node(*node_id, TranslationInput::INDEX), NodeInput::value(TaggedValue::DVec2(translation), false), &[]); + network_interface.set_input(&InputConnector::node(*node_id, RotationInput::INDEX), NodeInput::value(TaggedValue::F64(rotation), false), &[]); + network_interface.set_input(&InputConnector::node(*node_id, ScaleInput::INDEX), NodeInput::value(TaggedValue::DVec2(scale), false), &[]); + network_interface.set_input(&InputConnector::node(*node_id, SkewInput::INDEX), NodeInput::value(TaggedValue::DVec2(shear), false), &[]); } // TODO: This should be extracted from the graph at the location of the transform node. @@ -74,14 +76,31 @@ impl LayerBounds { /// Get the current affine transform from the transform node's inputs pub fn get_current_transform(inputs: &[NodeInput]) -> DAffine2 { - let translation = if let Some(&TaggedValue::DVec2(translation)) = inputs[1].as_value() { + const TRANSLATION_INDEX: usize = 1; + const ROTATION_INDEX: usize = 2; + const SCALE_INDEX: usize = 3; + const SKEW_INDEX: usize = 4; + + let translation = if let Some(&TaggedValue::DVec2(translation)) = inputs[TRANSLATION_INDEX].as_value() { translation } else { DVec2::ZERO }; - let rotation = if let Some(&TaggedValue::F64(rotation)) = inputs[2].as_value() { rotation } else { 0. }; - let scale = if let Some(&TaggedValue::DVec2(scale)) = inputs[3].as_value() { scale } else { DVec2::ONE }; - let shear = if let Some(&TaggedValue::DVec2(shear)) = inputs[4].as_value() { shear } else { DVec2::ZERO }; + let rotation = if let Some(&TaggedValue::F64(rotation)) = inputs[ROTATION_INDEX].as_value() { + rotation + } else { + 0. + }; + let scale = if let Some(&TaggedValue::DVec2(scale)) = inputs[SCALE_INDEX].as_value() { + scale + } else { + DVec2::ONE + }; + let shear = if let Some(&TaggedValue::DVec2(shear)) = inputs[SKEW_INDEX].as_value() { + shear + } else { + DVec2::ZERO + }; let rotation = rotation.to_radians(); let shear = DVec2::new(shear.x.to_radians().tan(), shear.y.to_radians().tan()); @@ -91,7 +110,13 @@ pub fn get_current_transform(inputs: &[NodeInput]) -> DAffine2 { /// Extract the current normalized pivot from the layer pub fn get_current_normalized_pivot(inputs: &[NodeInput]) -> DVec2 { - if let Some(&TaggedValue::DVec2(pivot)) = inputs[5].as_value() { pivot } else { DVec2::splat(0.5) } + const ORIGIN_OFFSET_INDEX: usize = 5; + + if let Some(&TaggedValue::DVec2(pivot)) = inputs[ORIGIN_OFFSET_INDEX].as_value() { + pivot + } else { + DVec2::splat(0.5) + } } /// Expand a bounds to avoid div zero errors 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 16c70b119b..9ac6c9d7ed 100644 --- a/editor/src/messages/portfolio/document/graph_operation/utility_types.rs +++ b/editor/src/messages/portfolio/document/graph_operation/utility_types.rs @@ -367,7 +367,7 @@ impl<'a> ModifyInputsContext<'a> { let Some(blend_node_id) = self.existing_proto_node_id(graphene_std::blending_nodes::blending::IDENTIFIER, true) else { return; }; - let input_connector = InputConnector::node(blend_node_id, 1); + let input_connector = InputConnector::node(blend_node_id, graphene_std::blending_nodes::blending::BlendModeInput::INDEX); self.set_input_with_refresh(input_connector, NodeInput::value(TaggedValue::BlendMode(blend_mode), false), false); } @@ -375,7 +375,7 @@ impl<'a> ModifyInputsContext<'a> { let Some(blend_node_id) = self.existing_proto_node_id(graphene_std::blending_nodes::blending::IDENTIFIER, true) else { return; }; - let input_connector = InputConnector::node(blend_node_id, 2); + let input_connector = InputConnector::node(blend_node_id, graphene_std::blending_nodes::blending::OpacityInput::INDEX); self.set_input_with_refresh(input_connector, NodeInput::value(TaggedValue::F64(opacity * 100.), false), false); } @@ -383,7 +383,7 @@ impl<'a> ModifyInputsContext<'a> { let Some(blend_node_id) = self.existing_proto_node_id(graphene_std::blending_nodes::blending::IDENTIFIER, true) else { return; }; - let input_connector = InputConnector::node(blend_node_id, 3); + let input_connector = InputConnector::node(blend_node_id, graphene_std::blending_nodes::blending::FillInput::INDEX); self.set_input_with_refresh(input_connector, NodeInput::value(TaggedValue::F64(fill * 100.), false), false); } @@ -392,7 +392,7 @@ impl<'a> ModifyInputsContext<'a> { let Some(clip_node_id) = self.existing_proto_node_id(graphene_std::blending_nodes::blending::IDENTIFIER, true) else { return; }; - let input_connector = InputConnector::node(clip_node_id, 4); + let input_connector = InputConnector::node(clip_node_id, graphene_std::blending_nodes::blending::ClipInput::INDEX); self.set_input_with_refresh(input_connector, NodeInput::value(TaggedValue::Bool(clip), false), false); } diff --git a/editor/src/messages/tool/common_functionality/gizmos/shape_gizmos/circle_arc_radius_handle.rs b/editor/src/messages/tool/common_functionality/gizmos/shape_gizmos/circle_arc_radius_handle.rs index 6152a6a5dd..9a50889ffc 100644 --- a/editor/src/messages/tool/common_functionality/gizmos/shape_gizmos/circle_arc_radius_handle.rs +++ b/editor/src/messages/tool/common_functionality/gizmos/shape_gizmos/circle_arc_radius_handle.rs @@ -11,6 +11,7 @@ use crate::messages::tool::common_functionality::shapes::shape_utility::{extract use glam::{DAffine2, DVec2}; use graph_craft::document::NodeInput; use graph_craft::document::value::TaggedValue; +use graphene_std::NodeInputDecleration; use std::collections::VecDeque; use std::f64::consts::FRAC_PI_2; @@ -165,7 +166,7 @@ impl RadiusHandle { self.previous_mouse_position = input.mouse.position; responses.add(NodeGraphMessage::SetInput { - input_connector: InputConnector::node(node_id, 1), + input_connector: InputConnector::node(node_id, graphene_std::vector::generator_nodes::circle::RadiusInput::INDEX), input: NodeInput::value(TaggedValue::F64(current_radius + net_delta), false), }); responses.add(NodeGraphMessage::RunDocumentGraph); diff --git a/editor/src/messages/tool/common_functionality/gizmos/shape_gizmos/number_of_points_dial.rs b/editor/src/messages/tool/common_functionality/gizmos/shape_gizmos/number_of_points_dial.rs index c6fef1fbda..679da36244 100644 --- a/editor/src/messages/tool/common_functionality/gizmos/shape_gizmos/number_of_points_dial.rs +++ b/editor/src/messages/tool/common_functionality/gizmos/shape_gizmos/number_of_points_dial.rs @@ -13,6 +13,7 @@ use crate::messages::tool::common_functionality::shapes::shape_utility::{extract use glam::{DAffine2, DVec2}; use graph_craft::document::NodeInput; use graph_craft::document::value::TaggedValue; +use graphene_std::NodeInputDecleration; use std::collections::VecDeque; use std::f64::consts::TAU; @@ -201,7 +202,7 @@ impl NumberOfPointsDial { let new_point_count = ((self.initial_points as i32) + (net_delta as i32)).max(3); responses.add(NodeGraphMessage::SetInput { - input_connector: InputConnector::node(node_id, 1), + input_connector: InputConnector::node(node_id, graphene_std::vector::generator_nodes::star::SidesInput::::INDEX), input: NodeInput::value(TaggedValue::U32(new_point_count as u32), false), }); responses.add(NodeGraphMessage::RunDocumentGraph); diff --git a/editor/src/messages/tool/common_functionality/gizmos/shape_gizmos/sweep_angle_gizmo.rs b/editor/src/messages/tool/common_functionality/gizmos/shape_gizmos/sweep_angle_gizmo.rs index efa4b18351..6b03b6f8ac 100644 --- a/editor/src/messages/tool/common_functionality/gizmos/shape_gizmos/sweep_angle_gizmo.rs +++ b/editor/src/messages/tool/common_functionality/gizmos/shape_gizmos/sweep_angle_gizmo.rs @@ -11,6 +11,8 @@ use crate::messages::tool::tool_messages::tool_prelude::*; use glam::DVec2; use graph_craft::document::value::TaggedValue; use graph_craft::document::{NodeId, NodeInput}; +use graphene_std::NodeInputDecleration; +use graphene_std::vector::generator_nodes::arc::*; use std::collections::VecDeque; use std::f64::consts::FRAC_PI_4; @@ -332,11 +334,11 @@ impl SweepAngleGizmo { self.snap_angles = Self::calculate_snap_angles(); responses.add(NodeGraphMessage::SetInput { - input_connector: InputConnector::node(node_id, 2), + input_connector: InputConnector::node(node_id, StartAngleInput::INDEX), input: NodeInput::value(TaggedValue::F64(start_angle), false), }); responses.add(NodeGraphMessage::SetInput { - input_connector: InputConnector::node(node_id, 3), + input_connector: InputConnector::node(node_id, SweepAngleInput::INDEX), input: NodeInput::value(TaggedValue::F64(sweep_angle), false), }); diff --git a/editor/src/messages/tool/common_functionality/shapes/arc_shape.rs b/editor/src/messages/tool/common_functionality/shapes/arc_shape.rs index 7eabb3c619..027a58fe30 100644 --- a/editor/src/messages/tool/common_functionality/shapes/arc_shape.rs +++ b/editor/src/messages/tool/common_functionality/shapes/arc_shape.rs @@ -12,6 +12,8 @@ use crate::messages::tool::tool_messages::tool_prelude::*; use glam::DAffine2; use graph_craft::document::NodeInput; use graph_craft::document::value::TaggedValue; +use graphene_std::NodeInputDecleration; +use graphene_std::vector::generator_nodes::arc::*; use graphene_std::vector::misc::ArcType; use std::collections::VecDeque; @@ -172,7 +174,7 @@ impl Arc { } responses.add(NodeGraphMessage::SetInput { - input_connector: InputConnector::node(node_id, 1), + input_connector: InputConnector::node(node_id, RadiusInput::INDEX), input: NodeInput::value(TaggedValue::F64(radius), false), }); diff --git a/editor/src/messages/tool/common_functionality/shapes/arrow_shape.rs b/editor/src/messages/tool/common_functionality/shapes/arrow_shape.rs index df04b578ff..cce19bb1e6 100644 --- a/editor/src/messages/tool/common_functionality/shapes/arrow_shape.rs +++ b/editor/src/messages/tool/common_functionality/shapes/arrow_shape.rs @@ -14,6 +14,8 @@ use crate::messages::tool::common_functionality::snapping::SnapData; use glam::{DAffine2, DVec2}; use graph_craft::document::NodeInput; use graph_craft::document::value::TaggedValue; +use graphene_std::NodeInputDecleration; +use graphene_std::vector::generator_nodes::arrow::*; use std::collections::VecDeque; #[derive(Default)] @@ -67,7 +69,7 @@ impl Arrow { let document_to_viewport = document.metadata().document_to_viewport; responses.add(NodeGraphMessage::SetInput { - input_connector: InputConnector::node(node_id, 1), + input_connector: InputConnector::node(node_id, StartInput::INDEX), input: NodeInput::value(TaggedValue::DVec2(arrow_to), false), }); let downstream = document.metadata().downstream_transform_to_viewport(layer); diff --git a/editor/src/messages/tool/common_functionality/shapes/circle_shape.rs b/editor/src/messages/tool/common_functionality/shapes/circle_shape.rs index 836f50f9e6..466d293a43 100644 --- a/editor/src/messages/tool/common_functionality/shapes/circle_shape.rs +++ b/editor/src/messages/tool/common_functionality/shapes/circle_shape.rs @@ -12,6 +12,7 @@ use crate::messages::tool::tool_messages::tool_prelude::*; use glam::DAffine2; use graph_craft::document::NodeInput; use graph_craft::document::value::TaggedValue; +use graphene_std::NodeInputDecleration; #[derive(Clone, Debug, Default)] pub struct CircleGizmoHandler { @@ -107,7 +108,7 @@ impl Circle { let radius: f64 = if dimensions.x > dimensions.y { dimensions.y / 2. } else { dimensions.x / 2. }; responses.add(NodeGraphMessage::SetInput { - input_connector: InputConnector::node(node_id, 1), + input_connector: InputConnector::node(node_id, graphene_std::vector::generator_nodes::circle::RadiusInput::INDEX), input: NodeInput::value(TaggedValue::F64(radius), false), }); diff --git a/editor/src/messages/tool/common_functionality/shapes/ellipse_shape.rs b/editor/src/messages/tool/common_functionality/shapes/ellipse_shape.rs index eb33a08427..be796a3bce 100644 --- a/editor/src/messages/tool/common_functionality/shapes/ellipse_shape.rs +++ b/editor/src/messages/tool/common_functionality/shapes/ellipse_shape.rs @@ -9,6 +9,8 @@ use crate::messages::tool::tool_messages::tool_prelude::*; use glam::DAffine2; use graph_craft::document::NodeInput; use graph_craft::document::value::TaggedValue; +use graphene_std::NodeInputDecleration; +use graphene_std::vector::generator_nodes::ellipse::*; use std::collections::VecDeque; #[derive(Default)] @@ -37,11 +39,11 @@ impl Ellipse { }; responses.add(NodeGraphMessage::SetInput { - input_connector: InputConnector::node(node_id, 1), + input_connector: InputConnector::node(node_id, RadiusXInput::INDEX), input: NodeInput::value(TaggedValue::F64(((start.x - end.x) / 2.).abs()), false), }); responses.add(NodeGraphMessage::SetInput { - input_connector: InputConnector::node(node_id, 2), + input_connector: InputConnector::node(node_id, RadiusYInput::INDEX), input: NodeInput::value(TaggedValue::F64(((start.y - end.y) / 2.).abs()), false), }); responses.add(GraphOperationMessage::TransformSet { diff --git a/editor/src/messages/tool/common_functionality/shapes/line_shape.rs b/editor/src/messages/tool/common_functionality/shapes/line_shape.rs index 397dc02a5e..aebb159a33 100644 --- a/editor/src/messages/tool/common_functionality/shapes/line_shape.rs +++ b/editor/src/messages/tool/common_functionality/shapes/line_shape.rs @@ -13,6 +13,8 @@ use crate::messages::tool::tool_messages::tool_prelude::*; use glam::{DAffine2, DVec2}; use graph_craft::document::NodeInput; use graph_craft::document::value::TaggedValue; +use graphene_std::NodeInputDecleration; +use graphene_std::vector::generator_nodes::line::*; use std::collections::VecDeque; #[derive(Clone, PartialEq, Debug, Default)] @@ -73,7 +75,7 @@ impl Line { let line_to = document_points[1] - document_points[0]; responses.add(NodeGraphMessage::SetInput { - input_connector: InputConnector::node(node_id, 1), + input_connector: InputConnector::node(node_id, StartInput::INDEX), input: NodeInput::value(TaggedValue::DVec2(line_to), false), }); let document_to_viewport = document.metadata().document_to_viewport; diff --git a/editor/src/messages/tool/common_functionality/shapes/polygon_shape.rs b/editor/src/messages/tool/common_functionality/shapes/polygon_shape.rs index 7b22144a71..47b42a38a6 100644 --- a/editor/src/messages/tool/common_functionality/shapes/polygon_shape.rs +++ b/editor/src/messages/tool/common_functionality/shapes/polygon_shape.rs @@ -15,6 +15,8 @@ use crate::messages::tool::tool_messages::tool_prelude::*; use glam::DAffine2; use graph_craft::document::NodeInput; use graph_craft::document::value::TaggedValue; +use graphene_std::NodeInputDecleration; +use graphene_std::vector::generator_nodes::regular_polygon::*; use std::collections::VecDeque; #[derive(Clone, Debug, Default)] @@ -147,7 +149,7 @@ impl Polygon { }; responses.add(NodeGraphMessage::SetInput { - input_connector: InputConnector::node(node_id, 2), + input_connector: InputConnector::node(node_id, RadiusInput::INDEX), input: NodeInput::value(TaggedValue::F64(radius), false), }); @@ -185,7 +187,7 @@ impl Polygon { }); responses.add(NodeGraphMessage::SetInput { - input_connector: InputConnector::node(node_id, 1), + input_connector: InputConnector::node(node_id, SidesInput::::INDEX), input: NodeInput::value(TaggedValue::U32(new_dimension), false), }); responses.add(NodeGraphMessage::RunDocumentGraph); diff --git a/editor/src/messages/tool/common_functionality/shapes/rectangle_shape.rs b/editor/src/messages/tool/common_functionality/shapes/rectangle_shape.rs index 787684a8fa..a98efd2216 100644 --- a/editor/src/messages/tool/common_functionality/shapes/rectangle_shape.rs +++ b/editor/src/messages/tool/common_functionality/shapes/rectangle_shape.rs @@ -9,6 +9,8 @@ use crate::messages::tool::tool_messages::tool_prelude::*; use glam::DAffine2; use graph_craft::document::NodeInput; use graph_craft::document::value::TaggedValue; +use graphene_std::NodeInputDecleration; +use graphene_std::vector::generator_nodes::rectangle::*; use std::collections::VecDeque; #[derive(Default)] @@ -37,11 +39,11 @@ impl Rectangle { }; responses.add(NodeGraphMessage::SetInput { - input_connector: InputConnector::node(node_id, 1), + input_connector: InputConnector::node(node_id, WidthInput::INDEX), input: NodeInput::value(TaggedValue::F64((start.x - end.x).abs()), false), }); responses.add(NodeGraphMessage::SetInput { - input_connector: InputConnector::node(node_id, 2), + input_connector: InputConnector::node(node_id, HeightInput::INDEX), input: NodeInput::value(TaggedValue::F64((start.y - end.y).abs()), false), }); responses.add(GraphOperationMessage::TransformSet { diff --git a/editor/src/messages/tool/common_functionality/shapes/shape_utility.rs b/editor/src/messages/tool/common_functionality/shapes/shape_utility.rs index 96dbdd5165..5d7f42d045 100644 --- a/editor/src/messages/tool/common_functionality/shapes/shape_utility.rs +++ b/editor/src/messages/tool/common_functionality/shapes/shape_utility.rs @@ -204,7 +204,7 @@ pub fn update_radius_sign(end: DVec2, start: DVec2, layer: LayerNodeIdentifier, }; responses.add(NodeGraphMessage::SetInput { - input_connector: InputConnector::node(polygon_node_id, 2), + input_connector: InputConnector::node(polygon_node_id, graphene_std::vector::generator_nodes::regular_polygon::RadiusInput::INDEX), input: NodeInput::value(TaggedValue::F64(sign_num * 0.5), false), }); return; @@ -221,11 +221,11 @@ pub fn update_radius_sign(end: DVec2, start: DVec2, layer: LayerNodeIdentifier, }; responses.add(NodeGraphMessage::SetInput { - input_connector: InputConnector::node(star_node_id, 2), + input_connector: InputConnector::node(star_node_id, graphene_std::vector::generator_nodes::star::Radius1Input::INDEX), input: NodeInput::value(TaggedValue::F64(sign_num * 0.5), false), }); responses.add(NodeGraphMessage::SetInput { - input_connector: InputConnector::node(star_node_id, 3), + input_connector: InputConnector::node(star_node_id, graphene_std::vector::generator_nodes::star::Radius2Input::INDEX), input: NodeInput::value(TaggedValue::F64(sign_num * 0.25), false), }); } diff --git a/editor/src/messages/tool/common_functionality/shapes/star_shape.rs b/editor/src/messages/tool/common_functionality/shapes/star_shape.rs index acdde2c286..85bf964e34 100644 --- a/editor/src/messages/tool/common_functionality/shapes/star_shape.rs +++ b/editor/src/messages/tool/common_functionality/shapes/star_shape.rs @@ -15,6 +15,8 @@ use core::f64; use glam::DAffine2; use graph_craft::document::NodeInput; use graph_craft::document::value::TaggedValue; +use graphene_std::NodeInputDecleration; +use graphene_std::vector::generator_nodes::star::*; use std::collections::VecDeque; #[derive(Clone, Debug, Default)] @@ -152,12 +154,12 @@ impl Star { }; responses.add(NodeGraphMessage::SetInput { - input_connector: InputConnector::node(node_id, 2), + input_connector: InputConnector::node(node_id, Radius1Input::INDEX), input: NodeInput::value(TaggedValue::F64(radius), false), }); responses.add(NodeGraphMessage::SetInput { - input_connector: InputConnector::node(node_id, 3), + input_connector: InputConnector::node(node_id, Radius2Input::INDEX), input: NodeInput::value(TaggedValue::F64(radius / 2.), false), }); From cd00f3e1571a717cd5944dd8207daa59864f8842 Mon Sep 17 00:00:00 2001 From: Tyooughtul Date: Wed, 25 Feb 2026 13:34:06 +0800 Subject: [PATCH 2/7] fix: restore the debug information of the master branch --- .../document/graph_operation/transform_utils.rs | 13 ++++--------- .../no-std-types/src/color/discrete_srgb.rs | 5 +++++ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/editor/src/messages/portfolio/document/graph_operation/transform_utils.rs b/editor/src/messages/portfolio/document/graph_operation/transform_utils.rs index ca3976cea0..0db30b675f 100644 --- a/editor/src/messages/portfolio/document/graph_operation/transform_utils.rs +++ b/editor/src/messages/portfolio/document/graph_operation/transform_utils.rs @@ -76,27 +76,22 @@ impl LayerBounds { /// Get the current affine transform from the transform node's inputs pub fn get_current_transform(inputs: &[NodeInput]) -> DAffine2 { - const TRANSLATION_INDEX: usize = 1; - const ROTATION_INDEX: usize = 2; - const SCALE_INDEX: usize = 3; - const SKEW_INDEX: usize = 4; - - let translation = if let Some(&TaggedValue::DVec2(translation)) = inputs[TRANSLATION_INDEX].as_value() { + let translation = if let Some(&TaggedValue::DVec2(translation)) = inputs[TranslationInput::INDEX].as_value() { translation } else { DVec2::ZERO }; - let rotation = if let Some(&TaggedValue::F64(rotation)) = inputs[ROTATION_INDEX].as_value() { + let rotation = if let Some(&TaggedValue::F64(rotation)) = inputs[RotationInput::INDEX].as_value() { rotation } else { 0. }; - let scale = if let Some(&TaggedValue::DVec2(scale)) = inputs[SCALE_INDEX].as_value() { + let scale = if let Some(&TaggedValue::DVec2(scale)) = inputs[ScaleInput::INDEX].as_value() { scale } else { DVec2::ONE }; - let shear = if let Some(&TaggedValue::DVec2(shear)) = inputs[SKEW_INDEX].as_value() { + let shear = if let Some(&TaggedValue::DVec2(shear)) = inputs[SkewInput::INDEX].as_value() { shear } else { DVec2::ZERO diff --git a/node-graph/libraries/no-std-types/src/color/discrete_srgb.rs b/node-graph/libraries/no-std-types/src/color/discrete_srgb.rs index 13a06e30ab..2cf6dbb32b 100644 --- a/node-graph/libraries/no-std-types/src/color/discrete_srgb.rs +++ b/node-graph/libraries/no-std-types/src/color/discrete_srgb.rs @@ -162,6 +162,11 @@ mod tests { #[test] fn test_float_to_srgb_u8() { for u in 0..=u8::MAX { + // let a = srgb_u8_to_float(u); + // let b = srgb_u8_to_float_ref(u); + // if a != b { + // panic!("Mismatch at u={}: {} != {}", u, a, b); + // } assert!(srgb_u8_to_float(u) == srgb_u8_to_float_ref(u)); } } From 951637bc5cf7ae09dba8138fe800276e9e2c45e7 Mon Sep 17 00:00:00 2001 From: Tyooughtul Date: Tue, 3 Mar 2026 23:41:25 +0800 Subject: [PATCH 3/7] fix: replace remaining hardcoded input indices - replace remaining hardcoded input indices with named constants - resolve the errors caused by the accuracy issue --- .../document/document_message_handler.rs | 10 +- .../graph_operation_message_handler.rs | 31 +++-- .../document/graph_operation/utility_types.rs | 28 ++++- .../node_graph/node_graph_message_handler.rs | 3 +- .../utility_types/network_interface.rs | 22 ++-- .../network_interface/resolved_types.rs | 5 +- .../shape_gizmos/point_radius_handle.rs | 7 +- .../graph_modification_utils.rs | 18 +-- .../common_functionality/shapes/line_shape.rs | 4 +- .../shapes/polygon_shape.rs | 2 +- .../shapes/shape_utility.rs | 26 +++-- .../messages/tool/tool_messages/brush_tool.rs | 3 +- .../no-std-types/src/color/discrete_srgb.rs | 107 +++++++++++------- 13 files changed, 176 insertions(+), 90 deletions(-) diff --git a/editor/src/messages/portfolio/document/document_message_handler.rs b/editor/src/messages/portfolio/document/document_message_handler.rs index 0e6e02043c..092eab3fbf 100644 --- a/editor/src/messages/portfolio/document/document_message_handler.rs +++ b/editor/src/messages/portfolio/document/document_message_handler.rs @@ -1897,7 +1897,12 @@ impl DocumentMessageHandler { // If there's already a boolean operation on the selected layer, update it with the new operation if let (Some(upstream_boolean_op), Some(only_selected_layer)) = (upstream_boolean_op, only_selected_layer) { - network_interface.set_input(&InputConnector::node(upstream_boolean_op, 1), NodeInput::value(TaggedValue::BooleanOperation(operation), false), &[]); + const BOOLEAN_OPERATION_INDEX: usize = 1; + network_interface.set_input( + &InputConnector::node(upstream_boolean_op, BOOLEAN_OPERATION_INDEX), + NodeInput::value(TaggedValue::BooleanOperation(operation), false), + &[], + ); responses.add(NodeGraphMessage::RunDocumentGraph); @@ -2785,8 +2790,9 @@ impl DocumentMessageHandler { .popover_layout({ // Showing only compatible types for the layer based on the output type of the node upstream from its horizontal input let compatible_type = selected_layer.and_then(|layer| { + const LAYER_SECONDARY_INPUT_INDEX: usize = 1; self.network_interface - .upstream_output_connector(&InputConnector::node(layer.to_node(), 1), &[]) + .upstream_output_connector(&InputConnector::node(layer.to_node(), LAYER_SECONDARY_INPUT_INDEX), &[]) .and_then(|upstream_output| self.network_interface.output_type(&upstream_output, &[]).add_node_string()) }); diff --git a/editor/src/messages/portfolio/document/graph_operation/graph_operation_message_handler.rs b/editor/src/messages/portfolio/document/graph_operation/graph_operation_message_handler.rs index 1f6ed6fad1..4620efed78 100644 --- a/editor/src/messages/portfolio/document/graph_operation/graph_operation_message_handler.rs +++ b/editor/src/messages/portfolio/document/graph_operation/graph_operation_message_handler.rs @@ -101,7 +101,8 @@ impl MessageHandler> for } } GraphOperationMessage::SetUpstreamToChain { layer } => { - let Some(OutputConnector::Node { node_id: first_chain_node, .. }) = network_interface.upstream_output_connector(&InputConnector::node(layer.to_node(), 1), &[]) else { + const LAYER_SECONDARY_INPUT_INDEX: usize = 1; + let Some(OutputConnector::Node { node_id: first_chain_node, .. }) = network_interface.upstream_output_connector(&InputConnector::node(layer.to_node(), LAYER_SECONDARY_INPUT_INDEX), &[]) else { return; }; @@ -145,15 +146,18 @@ impl MessageHandler> for // Set the bottom input of the artboard back to artboard let bottom_input = NodeInput::value(TaggedValue::Artboard(Table::new()), true); - network_interface.set_input(&InputConnector::node(artboard_layer.to_node(), 0), bottom_input, &[]); + const ARTBOARD_BASE_INDEX: usize = 0; + network_interface.set_input(&InputConnector::node(artboard_layer.to_node(), ARTBOARD_BASE_INDEX), bottom_input, &[]); } else { // We have some non layers (e.g. just a rectangle node). We disconnect the bottom input and connect it to the left input. - network_interface.disconnect_input(&InputConnector::node(artboard_layer.to_node(), 0), &[]); - network_interface.set_input(&InputConnector::node(artboard_layer.to_node(), 1), primary_input, &[]); + const ARTBOARD_BASE_INDEX: usize = 0; + const ARTBOARD_CONTENT_INDEX: usize = 1; + network_interface.disconnect_input(&InputConnector::node(artboard_layer.to_node(), ARTBOARD_BASE_INDEX), &[]); + network_interface.set_input(&InputConnector::node(artboard_layer.to_node(), ARTBOARD_CONTENT_INDEX), primary_input, &[]); // Set the bottom input of the artboard back to artboard let bottom_input = NodeInput::value(TaggedValue::Artboard(Table::new()), true); - network_interface.set_input(&InputConnector::node(artboard_layer.to_node(), 0), bottom_input, &[]); + network_interface.set_input(&InputConnector::node(artboard_layer.to_node(), ARTBOARD_BASE_INDEX), bottom_input, &[]); } } responses.add_front(NodeGraphMessage::SelectedNodesSet { nodes: vec![id] }); @@ -193,8 +197,9 @@ impl MessageHandler> for let first_new_node_id = new_ids[&NodeId(0)]; responses.add(NodeGraphMessage::AddNodes { nodes, new_ids }); + const LAYER_SECONDARY_INPUT_INDEX: usize = 1; responses.add(NodeGraphMessage::SetInput { - input_connector: InputConnector::node(layer.to_node(), 1), + input_connector: InputConnector::node(layer.to_node(), LAYER_SECONDARY_INPUT_INDEX), input: NodeInput::node(first_new_node_id, 0), }); } @@ -251,10 +256,11 @@ impl MessageHandler> for return; }; - artboard_data.insert( - artboard.to_node(), - ArtboardInfo { - input_node: NodeInput::node(document_node.inputs[1].as_node().unwrap_or_default(), 0), + const ARTBOARD_CONTENT_INDEX: usize = 1; + artboard_data.insert( + artboard.to_node(), + ArtboardInfo { + input_node: NodeInput::node(document_node.inputs[ARTBOARD_CONTENT_INDEX].as_node().unwrap_or_default(), 0), output_nodes: network_interface .outward_wires(&[]) .and_then(|outward_wires| outward_wires.get(&OutputConnector::node(artboard.to_node(), 0))) @@ -281,8 +287,9 @@ impl MessageHandler> for // Go through all artboards and connect them to the merge nodes for artboard in &artboard_data { // Modify downstream connections - responses.add(NodeGraphMessage::SetInput { - input_connector: InputConnector::node(artboard.1.merge_node, 1), + const MERGE_CONTENT_INDEX: usize = 1; + responses.add(NodeGraphMessage::SetInput { + input_connector: InputConnector::node(artboard.1.merge_node, MERGE_CONTENT_INDEX), input: NodeInput::node(artboard.1.input_node.as_node().unwrap_or_default(), 0), }); 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 9ac6c9d7ed..dbe7399cc2 100644 --- a/editor/src/messages/portfolio/document/graph_operation/utility_types.rs +++ b/editor/src/messages/portfolio/document/graph_operation/utility_types.rs @@ -71,7 +71,8 @@ impl<'a> ModifyInputsContext<'a> { let mut post_node_input_connector = if parent == LayerNodeIdentifier::ROOT_PARENT { InputConnector::Export(0) } else { - InputConnector::node(parent.to_node(), 1) + const LAYER_SECONDARY_INPUT_INDEX: usize = 1; + InputConnector::node(parent.to_node(), LAYER_SECONDARY_INPUT_INDEX) }; // Skip layers based on skip_layer_nodes, which inserts the new layer at a certain index of the layer stack. let mut current_index = 0; @@ -320,7 +321,8 @@ impl<'a> ModifyInputsContext<'a> { // If inserting a 'Path' node, insert a 'Flatten Path' node if the type is `Graphic`. // TODO: Allow the 'Path' node to operate on table data by utilizing the reference (index or ID?) for each row. if node_definition.identifier == "Path" { - let layer_input_type = self.network_interface.input_type(&InputConnector::node(output_layer.to_node(), 1), &[]); + const LAYER_SECONDARY_INPUT_INDEX: usize = 1; + let layer_input_type = self.network_interface.input_type(&InputConnector::node(output_layer.to_node(), LAYER_SECONDARY_INPUT_INDEX), &[]); if layer_input_type.compiled_nested_type() == Some(&concrete!(Table)) { let Some(flatten_path_definition) = resolve_proto_node_type(graphene_std::vector_nodes::flatten_path::IDENTIFIER) else { log::error!("Flatten Path does not exist in ModifyInputsContext::existing_node_id"); @@ -505,10 +507,18 @@ impl<'a> ModifyInputsContext<'a> { let Some(brush_node_id) = self.existing_network_node_id("Brush", true) else { return; }; - self.set_input_with_refresh(InputConnector::node(brush_node_id, 1), NodeInput::value(TaggedValue::BrushStrokes(strokes), false), false); + const BRUSH_STROKES_INDEX: usize = 1; + self.set_input_with_refresh( + InputConnector::node(brush_node_id, BRUSH_STROKES_INDEX), + NodeInput::value(TaggedValue::BrushStrokes(strokes), false), + false, + ); } pub fn resize_artboard(&mut self, location: IVec2, dimensions: IVec2) { + const ARTBOARD_LOCATION_INDEX: usize = 2; + const ARTBOARD_DIMENSIONS_INDEX: usize = 3; + let Some(artboard_node_id) = self.existing_network_node_id("Artboard", true) else { return; }; @@ -524,8 +534,16 @@ impl<'a> ModifyInputsContext<'a> { dimensions.y *= -1; location.y -= dimensions.y; } - self.set_input_with_refresh(InputConnector::node(artboard_node_id, 2), NodeInput::value(TaggedValue::DVec2(location.into()), false), false); - self.set_input_with_refresh(InputConnector::node(artboard_node_id, 3), NodeInput::value(TaggedValue::DVec2(dimensions.into()), false), false); + self.set_input_with_refresh( + InputConnector::node(artboard_node_id, ARTBOARD_LOCATION_INDEX), + NodeInput::value(TaggedValue::DVec2(location.into()), false), + false, + ); + self.set_input_with_refresh( + InputConnector::node(artboard_node_id, ARTBOARD_DIMENSIONS_INDEX), + NodeInput::value(TaggedValue::DVec2(dimensions.into()), false), + false, + ); } /// Set the input, refresh the properties panel, and run the document graph if skip_rerender is false diff --git a/editor/src/messages/portfolio/document/node_graph/node_graph_message_handler.rs b/editor/src/messages/portfolio/document/node_graph/node_graph_message_handler.rs index b7f6992fc5..34e8a0eba8 100644 --- a/editor/src/messages/portfolio/document/node_graph/node_graph_message_handler.rs +++ b/editor/src/messages/portfolio/document/node_graph/node_graph_message_handler.rs @@ -1324,7 +1324,8 @@ impl<'a> MessageHandler> for NodeG .cloned() .collect::>() { - network_interface.try_set_upstream_to_chain(&InputConnector::node(layer, 1), selection_network_path); + const LAYER_SECONDARY_INPUT_INDEX: usize = 1; + network_interface.try_set_upstream_to_chain(&InputConnector::node(layer, LAYER_SECONDARY_INPUT_INDEX), selection_network_path); } responses.add(NodeGraphMessage::SendGraph); diff --git a/editor/src/messages/portfolio/document/utility_types/network_interface.rs b/editor/src/messages/portfolio/document/utility_types/network_interface.rs index ac95dfce84..212a31cd8c 100644 --- a/editor/src/messages/portfolio/document/utility_types/network_interface.rs +++ b/editor/src/messages/portfolio/document/utility_types/network_interface.rs @@ -419,7 +419,8 @@ impl NodeNetworkInterface { for old_id in new_nodes.iter().map(|(_, old_id, _)| *old_id).collect::>() { // Try set all selected nodes upstream of a layer to be chain nodes if self.is_layer(&old_id, network_path) { - for valid_upstream_chain_node in self.valid_upstream_chain_nodes(&InputConnector::node(old_id, 1), network_path) { + const LAYER_SECONDARY_INPUT_INDEX: usize = 1; + for valid_upstream_chain_node in self.valid_upstream_chain_nodes(&InputConnector::node(old_id, LAYER_SECONDARY_INPUT_INDEX), network_path) { if let Some(node_template) = new_nodes.iter_mut().find_map(|(_, old_id, template)| (*old_id == valid_upstream_chain_node).then_some(template)) { match &mut node_template.persistent_node_metadata.node_type_metadata { NodeTypePersistentMetadata::Node(node_metadata) => node_metadata.position = NodePosition::Chain, @@ -1195,7 +1196,8 @@ impl NodeNetworkInterface { .find(|ancestor| *ancestor != LayerNodeIdentifier::ROOT_PARENT && self.is_artboard(&ancestor.to_node(), &[])) { let artboard = self.document_node(&artboard_node_identifier.to_node(), &[]); - let clip_input = artboard.unwrap().inputs.get(5).unwrap(); + const ARTBOARD_CLIP_INDEX: usize = 5; + let clip_input = artboard.unwrap().inputs.get(ARTBOARD_CLIP_INDEX).unwrap(); if let NodeInput::Value { tagged_value, .. } = clip_input && tagged_value.clone().deref() == &TaggedValue::Bool(true) { @@ -1312,7 +1314,8 @@ impl NodeNetworkInterface { .iter() .filter_map(move |node_id| { if self.is_layer(node_id, network_path) { - network.nodes.get(node_id).and_then(|node| node.inputs.get(1)).and_then(|input| input.as_node()) + const LAYER_SECONDARY_INPUT_INDEX: usize = 1; + network.nodes.get(node_id).and_then(|node| node.inputs.get(LAYER_SECONDARY_INPUT_INDEX)).and_then(|input| input.as_node()) } else { Some(*node_id) } @@ -3097,7 +3100,8 @@ impl NodeNetworkInterface { let mut modified = vector.clone(); let path_node = self.document_network().nodes.get(&path_node); - let modification_input = path_node.and_then(|node: &DocumentNode| node.inputs.get(1)).and_then(|input| input.as_value()); + const PATH_MODIFICATION_INDEX: usize = 1; + let modification_input = path_node.and_then(|node: &DocumentNode| node.inputs.get(PATH_MODIFICATION_INDEX)).and_then(|input| input.as_value()); if let Some(TaggedValue::VectorModification(modification)) = modification_input { modification.apply(&mut modified); } @@ -4604,7 +4608,8 @@ impl NodeNetworkInterface { // Try build the chain if is_layer { - self.try_set_upstream_to_chain(&InputConnector::node(*node_id, 1), network_path); + const LAYER_SECONDARY_INPUT_INDEX: usize = 1; + self.try_set_upstream_to_chain(&InputConnector::node(*node_id, LAYER_SECONDARY_INPUT_INDEX), network_path); } else { self.try_set_node_to_chain(node_id, network_path); } @@ -5655,16 +5660,17 @@ impl NodeNetworkInterface { // Moves a node and to the start of a layer chain (feeding into the secondary input of the layer) pub fn move_node_to_chain_start(&mut self, node_id: &NodeId, parent: LayerNodeIdentifier, network_path: &[NodeId]) { - let Some(current_input) = self.input_from_connector(&InputConnector::node(parent.to_node(), 1), network_path) else { + const LAYER_SECONDARY_INPUT_INDEX: usize = 1; + let Some(current_input) = self.input_from_connector(&InputConnector::node(parent.to_node(), LAYER_SECONDARY_INPUT_INDEX), network_path) else { log::error!("Could not get input for node {node_id}"); return; }; if matches!(current_input, NodeInput::Value { .. }) { - self.create_wire(&OutputConnector::node(*node_id, 0), &InputConnector::node(parent.to_node(), 1), network_path); + self.create_wire(&OutputConnector::node(*node_id, 0), &InputConnector::node(parent.to_node(), LAYER_SECONDARY_INPUT_INDEX), network_path); self.set_chain_position(node_id, network_path); } else { // Insert the node in the gap and set the upstream to a chain - self.insert_node_between(node_id, &InputConnector::node(parent.to_node(), 1), 0, network_path); + self.insert_node_between(node_id, &InputConnector::node(parent.to_node(), LAYER_SECONDARY_INPUT_INDEX), 0, network_path); self.force_set_upstream_to_chain(node_id, network_path); } } diff --git a/editor/src/messages/portfolio/document/utility_types/network_interface/resolved_types.rs b/editor/src/messages/portfolio/document/utility_types/network_interface/resolved_types.rs index 2d285f7e89..e7d724d76b 100644 --- a/editor/src/messages/portfolio/document/utility_types/network_interface/resolved_types.rs +++ b/editor/src/messages/portfolio/document/utility_types/network_interface/resolved_types.rs @@ -12,6 +12,9 @@ use crate::messages::portfolio::document::node_graph::utility_types::FrontendGra use crate::messages::portfolio::document::utility_types::network_interface::{InputConnector, NodeNetworkInterface, OutputConnector}; // This file contains utility methods for interfacing with the resolved types returned from the compiler + +/// Index of the `editor_api` parameter in the render node (second parameter after the primary context input). +const RENDER_NODE_EDITOR_API_INDEX: usize = 1; #[derive(Debug, Default)] pub struct ResolvedDocumentNodeTypes { pub types: HashMap, NodeTypes>, @@ -317,7 +320,7 @@ impl NodeNetworkInterface { log::error!("Protonode {render_node:?} not found in registry"); return Vec::new(); }; - implementations.keys().map(|types| types.inputs[1].clone()).collect() + implementations.keys().map(|types| types.inputs[RENDER_NODE_EDITOR_API_INDEX].clone()).collect() } } } diff --git a/editor/src/messages/tool/common_functionality/gizmos/shape_gizmos/point_radius_handle.rs b/editor/src/messages/tool/common_functionality/gizmos/shape_gizmos/point_radius_handle.rs index d72414f48a..b09817600a 100644 --- a/editor/src/messages/tool/common_functionality/gizmos/shape_gizmos/point_radius_handle.rs +++ b/editor/src/messages/tool/common_functionality/gizmos/shape_gizmos/point_radius_handle.rs @@ -14,6 +14,7 @@ use crate::messages::tool::common_functionality::shapes::shape_utility::{extract use glam::DVec2; use graph_craft::document::NodeInput; use graph_craft::document::value::TaggedValue; +use graphene_std::vector::generator_nodes::star::*; use std::collections::VecDeque; use std::f64::consts::{FRAC_1_SQRT_2, FRAC_PI_4, PI, SQRT_2}; @@ -337,13 +338,13 @@ impl PointRadiusHandle { return snap_radii; }; - let (Some(&TaggedValue::F64(radius_1)), Some(&TaggedValue::F64(radius_2))) = (node_inputs[2].as_value(), node_inputs[3].as_value()) else { + let (Some(&TaggedValue::F64(radius_1)), Some(&TaggedValue::F64(radius_2))) = (node_inputs[Radius1Input::INDEX].as_value(), node_inputs[Radius2Input::INDEX].as_value()) else { return snap_radii; }; let other_radius = if radius_index == 3 { radius_1 } else { radius_2 }; - let Some(&TaggedValue::U32(sides)) = node_inputs[1].as_value() else { + let Some(&TaggedValue::U32(sides)) = node_inputs[SidesInput::::INDEX].as_value() else { return snap_radii; }; @@ -456,7 +457,7 @@ impl PointRadiusHandle { return; }; - let (Some(&TaggedValue::F64(radius_1)), Some(&TaggedValue::F64(radius_2))) = (node_inputs[2].as_value(), node_inputs[3].as_value()) else { + let (Some(&TaggedValue::F64(radius_1)), Some(&TaggedValue::F64(radius_2))) = (node_inputs[Radius1Input::INDEX].as_value(), node_inputs[Radius2Input::INDEX].as_value()) else { return; }; diff --git a/editor/src/messages/tool/common_functionality/graph_modification_utils.rs b/editor/src/messages/tool/common_functionality/graph_modification_utils.rs index c71f199078..8b910fb4de 100644 --- a/editor/src/messages/tool/common_functionality/graph_modification_utils.rs +++ b/editor/src/messages/tool/common_functionality/graph_modification_utils.rs @@ -9,6 +9,7 @@ use graph_craft::document::{NodeId, NodeInput}; use graph_craft::{ProtoNodeIdentifier, concrete}; use graphene_std::Color; use graphene_std::NodeInputDecleration; +use graphene_std::blending_nodes::blending::*; use graphene_std::raster::BlendMode; use graphene_std::raster_types::{CPU, GPU, Raster}; use graphene_std::subpath::Subpath; @@ -92,9 +93,11 @@ pub fn merge_layers(document: &DocumentMessageHandler, first_layer: LayerNodeIde node_id: merge_node_id, parent: first_layer, }); + const LAYER_SECONDARY_INPUT_INDEX: usize = 1; + const MERGE_CONTENT_INDEX: usize = 1; responses.add(NodeGraphMessage::ConnectUpstreamOutputToInput { - downstream_input: InputConnector::node(second_layer.to_node(), 1), - input_connector: InputConnector::node(merge_node_id, 1), + downstream_input: InputConnector::node(second_layer.to_node(), LAYER_SECONDARY_INPUT_INDEX), + input_connector: InputConnector::node(merge_node_id, MERGE_CONTENT_INDEX), }); responses.add(NodeGraphMessage::DeleteNodes { node_ids: vec![second_layer.to_node()], @@ -298,7 +301,7 @@ pub fn get_fill_color(layer: LayerNodeIdentifier, network_interface: &NodeNetwor /// Get the current blend mode of a layer from the closest "Blending" node. pub fn get_blend_mode(layer: LayerNodeIdentifier, network_interface: &NodeNetworkInterface) -> Option { let inputs = NodeGraphLayer::new(layer, network_interface).find_node_inputs(&DefinitionIdentifier::ProtoNode(graphene_std::blending_nodes::blending::IDENTIFIER))?; - let TaggedValue::BlendMode(blend_mode) = inputs.get(1)?.as_value()? else { + let TaggedValue::BlendMode(blend_mode) = inputs.get(BlendModeInput::INDEX)?.as_value()? else { return None; }; Some(*blend_mode) @@ -314,7 +317,7 @@ pub fn get_blend_mode(layer: LayerNodeIdentifier, network_interface: &NodeNetwor /// With those limitations in mind, the intention of this function is to show just the value already present in an upstream Opacity node so that value can be directly edited. pub fn get_opacity(layer: LayerNodeIdentifier, network_interface: &NodeNetworkInterface) -> Option { let inputs = NodeGraphLayer::new(layer, network_interface).find_node_inputs(&DefinitionIdentifier::ProtoNode(graphene_std::blending_nodes::blending::IDENTIFIER))?; - let TaggedValue::F64(opacity) = inputs.get(2)?.as_value()? else { + let TaggedValue::F64(opacity) = inputs.get(OpacityInput::INDEX)?.as_value()? else { return None; }; Some(*opacity) @@ -322,7 +325,7 @@ pub fn get_opacity(layer: LayerNodeIdentifier, network_interface: &NodeNetworkIn pub fn get_clip_mode(layer: LayerNodeIdentifier, network_interface: &NodeNetworkInterface) -> Option { let inputs = NodeGraphLayer::new(layer, network_interface).find_node_inputs(&DefinitionIdentifier::ProtoNode(graphene_std::blending_nodes::blending::IDENTIFIER))?; - let TaggedValue::Bool(clip) = inputs.get(4)?.as_value()? else { + let TaggedValue::Bool(clip) = inputs.get(ClipInput::INDEX)?.as_value()? else { return None; }; Some(*clip) @@ -330,7 +333,7 @@ pub fn get_clip_mode(layer: LayerNodeIdentifier, network_interface: &NodeNetwork pub fn get_fill(layer: LayerNodeIdentifier, network_interface: &NodeNetworkInterface) -> Option { let inputs = NodeGraphLayer::new(layer, network_interface).find_node_inputs(&DefinitionIdentifier::ProtoNode(graphene_std::blending_nodes::blending::IDENTIFIER))?; - let TaggedValue::F64(fill) = inputs.get(3)?.as_value()? else { + let TaggedValue::F64(fill) = inputs.get(FillInput::INDEX)?.as_value()? else { return None; }; Some(*fill) @@ -518,7 +521,8 @@ impl<'a> NodeGraphLayer<'a> { /// Check if a layer is a raster layer pub fn is_raster_layer(layer: LayerNodeIdentifier, network_interface: &mut NodeNetworkInterface) -> bool { - let layer_input_type = network_interface.input_type(&InputConnector::node(layer.to_node(), 1), &[]); + const LAYER_SECONDARY_INPUT_INDEX: usize = 1; + let layer_input_type = network_interface.input_type(&InputConnector::node(layer.to_node(), LAYER_SECONDARY_INPUT_INDEX), &[]); layer_input_type.compiled_nested_type() == Some(&concrete!(Table>)) || layer_input_type.compiled_nested_type() == Some(&concrete!(Table>)) } diff --git a/editor/src/messages/tool/common_functionality/shapes/line_shape.rs b/editor/src/messages/tool/common_functionality/shapes/line_shape.rs index aebb159a33..3e739b58ea 100644 --- a/editor/src/messages/tool/common_functionality/shapes/line_shape.rs +++ b/editor/src/messages/tool/common_functionality/shapes/line_shape.rs @@ -98,7 +98,7 @@ impl Line { let node_inputs = NodeGraphLayer::new(layer, &document.network_interface).find_node_inputs(&DefinitionIdentifier::ProtoNode(graphene_std::vector::generator_nodes::line::IDENTIFIER))?; - let Some(&TaggedValue::DVec2(line_to)) = node_inputs[1].as_value() else { + let Some(&TaggedValue::DVec2(line_to)) = node_inputs[StartInput::INDEX].as_value() else { return None; }; @@ -208,7 +208,7 @@ mod test_line_tool { .selected_visible_and_unlocked_layers(network_interface) .filter_map(|layer| { let node_inputs = NodeGraphLayer::new(layer, network_interface).find_node_inputs(&DefinitionIdentifier::ProtoNode(graphene_std::vector::generator_nodes::line::IDENTIFIER))?; - let Some(&TaggedValue::DVec2(line_to)) = node_inputs[1].as_value() else { + let Some(&TaggedValue::DVec2(line_to)) = node_inputs[StartInput::INDEX].as_value() else { return None; }; diff --git a/editor/src/messages/tool/common_functionality/shapes/polygon_shape.rs b/editor/src/messages/tool/common_functionality/shapes/polygon_shape.rs index 47b42a38a6..24808e37e2 100644 --- a/editor/src/messages/tool/common_functionality/shapes/polygon_shape.rs +++ b/editor/src/messages/tool/common_functionality/shapes/polygon_shape.rs @@ -176,7 +176,7 @@ impl Polygon { return; }; - let Some(&TaggedValue::U32(n)) = node_inputs.get(1).unwrap().as_value() else { + let Some(&TaggedValue::U32(n)) = node_inputs.get(SidesInput::::INDEX).unwrap().as_value() else { return; }; diff --git a/editor/src/messages/tool/common_functionality/shapes/shape_utility.rs b/editor/src/messages/tool/common_functionality/shapes/shape_utility.rs index 5d7f42d045..3224583bde 100644 --- a/editor/src/messages/tool/common_functionality/shapes/shape_utility.rs +++ b/editor/src/messages/tool/common_functionality/shapes/shape_utility.rs @@ -287,11 +287,15 @@ pub fn anchor_overlays(document: &DocumentMessageHandler, overlay_context: &mut /// Extract the node input values of Star. /// Returns an option of (sides, radius1, radius2). pub fn extract_star_parameters(layer: Option, document: &DocumentMessageHandler) -> Option<(u32, f64, f64)> { + use graphene_std::vector::generator_nodes::star::*; + let node_inputs = NodeGraphLayer::new(layer?, &document.network_interface).find_node_inputs(&DefinitionIdentifier::ProtoNode(graphene_std::vector::generator_nodes::star::IDENTIFIER))?; - let (Some(&TaggedValue::U32(sides)), Some(&TaggedValue::F64(radius_1)), Some(&TaggedValue::F64(radius_2))) = - (node_inputs.get(1)?.as_value(), node_inputs.get(2)?.as_value(), node_inputs.get(3)?.as_value()) - else { + let (Some(&TaggedValue::U32(sides)), Some(&TaggedValue::F64(radius_1)), Some(&TaggedValue::F64(radius_2))) = ( + node_inputs.get(SidesInput::::INDEX)?.as_value(), + node_inputs.get(Radius1Input::INDEX)?.as_value(), + node_inputs.get(Radius2Input::INDEX)?.as_value(), + ) else { return None; }; @@ -301,10 +305,12 @@ pub fn extract_star_parameters(layer: Option, document: &Do /// Extract the node input values of Polygon. /// Returns an option of (sides, radius). pub fn extract_polygon_parameters(layer: Option, document: &DocumentMessageHandler) -> Option<(u32, f64)> { + use graphene_std::vector::generator_nodes::regular_polygon::*; + let node_inputs = NodeGraphLayer::new(layer?, &document.network_interface).find_node_inputs(&DefinitionIdentifier::ProtoNode(graphene_std::vector::generator_nodes::regular_polygon::IDENTIFIER))?; - let (Some(&TaggedValue::U32(n)), Some(&TaggedValue::F64(radius))) = (node_inputs.get(1)?.as_value(), node_inputs.get(2)?.as_value()) else { + let (Some(&TaggedValue::U32(n)), Some(&TaggedValue::F64(radius))) = (node_inputs.get(SidesInput::::INDEX)?.as_value(), node_inputs.get(RadiusInput::INDEX)?.as_value()) else { return None; }; @@ -314,13 +320,15 @@ pub fn extract_polygon_parameters(layer: Option, document: /// Extract the node input values of an arc. /// Returns an option of (radius, start angle, sweep angle, arc type). pub fn extract_arc_parameters(layer: Option, document: &DocumentMessageHandler) -> Option<(f64, f64, f64, ArcType)> { + use graphene_std::vector::generator_nodes::arc::*; + let node_inputs = NodeGraphLayer::new(layer?, &document.network_interface).find_node_inputs(&DefinitionIdentifier::ProtoNode(graphene_std::vector::generator_nodes::arc::IDENTIFIER))?; let (Some(&TaggedValue::F64(radius)), Some(&TaggedValue::F64(start_angle)), Some(&TaggedValue::F64(sweep_angle)), Some(&TaggedValue::ArcType(arc_type))) = ( - node_inputs.get(1)?.as_value(), - node_inputs.get(2)?.as_value(), - node_inputs.get(3)?.as_value(), - node_inputs.get(4)?.as_value(), + node_inputs.get(RadiusInput::INDEX)?.as_value(), + node_inputs.get(StartAngleInput::INDEX)?.as_value(), + node_inputs.get(SweepAngleInput::INDEX)?.as_value(), + node_inputs.get(ArcTypeInput::INDEX)?.as_value(), ) else { return None; }; @@ -385,7 +393,7 @@ pub fn arc_end_points_ignore_layer(radius: f64, start_angle: f64, sweep_angle: f pub fn extract_circle_radius(layer: LayerNodeIdentifier, document: &DocumentMessageHandler) -> Option { let node_inputs = NodeGraphLayer::new(layer, &document.network_interface).find_node_inputs(&DefinitionIdentifier::ProtoNode(graphene_std::vector::generator_nodes::circle::IDENTIFIER))?; - let Some(&TaggedValue::F64(radius)) = node_inputs.get(1)?.as_value() else { + let Some(&TaggedValue::F64(radius)) = node_inputs.get(graphene_std::vector::generator_nodes::circle::RadiusInput::INDEX)?.as_value() else { return None; }; diff --git a/editor/src/messages/tool/tool_messages/brush_tool.rs b/editor/src/messages/tool/tool_messages/brush_tool.rs index 5319e21aa4..acfe5c5f5f 100644 --- a/editor/src/messages/tool/tool_messages/brush_tool.rs +++ b/editor/src/messages/tool/tool_messages/brush_tool.rs @@ -320,7 +320,8 @@ impl BrushToolData { }; if reference == DefinitionIdentifier::Network("Brush".into()) && node_id != layer.to_node() { - let points_input = node.inputs.get(1)?; + const BRUSH_STROKES_INDEX: usize = 1; + let points_input = node.inputs.get(BRUSH_STROKES_INDEX)?; let Some(TaggedValue::BrushStrokes(strokes)) = points_input.as_value() else { continue }; self.strokes.clone_from(strokes); diff --git a/node-graph/libraries/no-std-types/src/color/discrete_srgb.rs b/node-graph/libraries/no-std-types/src/color/discrete_srgb.rs index 2cf6dbb32b..1a31683c6a 100644 --- a/node-graph/libraries/no-std-types/src/color/discrete_srgb.rs +++ b/node-graph/libraries/no-std-types/src/color/discrete_srgb.rs @@ -90,38 +90,70 @@ pub fn float_to_srgb_u8(mut f: f32) -> u8 { #[rustfmt::skip] const FROM_SRGB_U8: [f32; 256] = [ - 0., 0.000303527, 0.000607054, 0.00091058103, 0.001214108, 0.001517635, 0.0018211621, 0.002124689, - 0.002428216, 0.002731743, 0.00303527, 0.0033465356, 0.003676507, 0.004024717, 0.004391442, - 0.0047769533, 0.005181517, 0.0056053917, 0.0060488326, 0.006512091, 0.00699541, 0.0074990317, - 0.008023192, 0.008568125, 0.009134057, 0.009721218, 0.010329823, 0.010960094, 0.011612245, - 0.012286487, 0.012983031, 0.013702081, 0.014443844, 0.015208514, 0.015996292, 0.016807375, - 0.017641952, 0.018500218, 0.019382361, 0.020288562, 0.02121901, 0.022173883, 0.023153365, - 0.02415763, 0.025186857, 0.026241222, 0.027320892, 0.028426038, 0.029556843, 0.03071345, 0.03189604, - 0.033104774, 0.03433981, 0.035601325, 0.036889452, 0.038204376, 0.039546248, 0.04091521, 0.042311423, - 0.043735042, 0.045186214, 0.046665095, 0.048171833, 0.049706575, 0.051269468, 0.052860655, 0.05448028, - 0.056128494, 0.057805434, 0.05951124, 0.06124607, 0.06301003, 0.06480328, 0.06662595, 0.06847818, - 0.07036011, 0.07227186, 0.07421358, 0.07618539, 0.07818743, 0.08021983, 0.082282715, 0.084376216, - 0.086500466, 0.088655606, 0.09084173, 0.09305898, 0.095307484, 0.09758736, 0.09989874, 0.10224175, - 0.10461649, 0.10702311, 0.10946172, 0.111932434, 0.11443538, 0.116970696, 0.11953845, 0.12213881, - 0.12477186, 0.12743773, 0.13013652, 0.13286836, 0.13563336, 0.13843165, 0.14126332, 0.1441285, - 0.1470273, 0.14995982, 0.15292618, 0.1559265, 0.15896086, 0.16202943, 0.16513224, 0.16826946, - 0.17144115, 0.17464745, 0.17788847, 0.1811643, 0.18447503, 0.1878208, 0.19120172, 0.19461787, - 0.19806935, 0.2015563, 0.20507877, 0.2086369, 0.21223079, 0.21586053, 0.21952623, 0.22322798, - 0.22696589, 0.23074007, 0.23455065, 0.23839766, 0.2422812, 0.2462014, 0.25015837, 0.25415218, - 0.2581829, 0.26225072, 0.26635566, 0.27049786, 0.27467737, 0.27889434, 0.2831488, 0.2874409, - 0.2917707, 0.29613832, 0.30054384, 0.30498737, 0.30946895, 0.31398875, 0.31854683, 0.32314324, - 0.32777813, 0.33245158, 0.33716366, 0.34191445, 0.3467041, 0.3515327, 0.35640025, 0.36130688, - 0.3662527, 0.37123778, 0.37626222, 0.3813261, 0.38642952, 0.39157256, 0.3967553, 0.40197787, - 0.4072403, 0.4125427, 0.41788515, 0.42326775, 0.42869055, 0.4341537, 0.43965724, 0.44520125, - 0.45078585, 0.45641106, 0.46207705, 0.46778384, 0.47353154, 0.47932023, 0.48514998, 0.4910209, - 0.49693304, 0.5028866, 0.50888145, 0.5149178, 0.5209957, 0.52711535, 0.5332766, 0.5394797, - 0.5457247, 0.5520116, 0.5583406, 0.5647117, 0.57112503, 0.57758063, 0.5840786, 0.590619, 0.597202, - 0.60382754, 0.61049575, 0.61720675, 0.62396055, 0.63075733, 0.637597, 0.6444799, 0.6514058, - 0.65837497, 0.66538745, 0.67244333, 0.6795426, 0.68668544, 0.69387203, 0.70110214, 0.70837605, - 0.7156938, 0.72305536, 0.730461, 0.7379107, 0.7454045, 0.75294244, 0.76052475, 0.7681514, 0.77582246, - 0.78353804, 0.79129815, 0.79910296, 0.8069525, 0.8148468, 0.822786, 0.8307701, 0.83879924, 0.84687346, - 0.8549928, 0.8631574, 0.87136734, 0.8796226, 0.8879232, 0.89626956, 0.90466136, 0.913099, 0.92158204, - 0.93011117, 0.9386859, 0.9473069, 0.9559735, 0.9646866, 0.9734455, 0.98225087, 0.9911022, 1., + f32::from_bits(0x00000000), f32::from_bits(0x399f22b4), f32::from_bits(0x3a1f22b4), f32::from_bits(0x3a6eb40f), + f32::from_bits(0x3a9f22b4), f32::from_bits(0x3ac6eb61), f32::from_bits(0x3aeeb40f), f32::from_bits(0x3b0b3e5e), + f32::from_bits(0x3b1f22b4), f32::from_bits(0x3b33070b), f32::from_bits(0x3b46eb61), f32::from_bits(0x3b5b518d), + f32::from_bits(0x3b70f18d), f32::from_bits(0x3b83e1c6), f32::from_bits(0x3b8fe616), f32::from_bits(0x3b9c87fd), + f32::from_bits(0x3ba9c9b7), f32::from_bits(0x3bb7ad6f), f32::from_bits(0x3bc63549), f32::from_bits(0x3bd56361), + f32::from_bits(0x3be539c1), f32::from_bits(0x3bf5ba70), f32::from_bits(0x3c0373b5), f32::from_bits(0x3c0c6152), + f32::from_bits(0x3c15a703), f32::from_bits(0x3c1f45be), f32::from_bits(0x3c293e6b), f32::from_bits(0x3c3391f7), + f32::from_bits(0x3c3e4149), f32::from_bits(0x3c494d43), f32::from_bits(0x3c54b6c7), f32::from_bits(0x3c607eb1), + f32::from_bits(0x3c6ca5df), f32::from_bits(0x3c792d22), f32::from_bits(0x3c830aa8), f32::from_bits(0x3c89af9f), + f32::from_bits(0x3c9085db), f32::from_bits(0x3c978dc5), f32::from_bits(0x3c9ec7c2), f32::from_bits(0x3ca63433), + f32::from_bits(0x3cadd37d), f32::from_bits(0x3cb5a601), f32::from_bits(0x3cbdac20), f32::from_bits(0x3cc5e639), + f32::from_bits(0x3cce54ab), f32::from_bits(0x3cd6f7d5), f32::from_bits(0x3cdfd010), f32::from_bits(0x3ce8ddb9), + f32::from_bits(0x3cf22131), f32::from_bits(0x3cfb9ac6), f32::from_bits(0x3d02a56c), f32::from_bits(0x3d0798df), + f32::from_bits(0x3d0ca7e7), f32::from_bits(0x3d11d2b2), f32::from_bits(0x3d171965), f32::from_bits(0x3d1c7c31), + f32::from_bits(0x3d21fb3f), f32::from_bits(0x3d2796b5), f32::from_bits(0x3d2d4ebe), f32::from_bits(0x3d332384), + f32::from_bits(0x3d39152e), f32::from_bits(0x3d3f23e6), f32::from_bits(0x3d454fd4), f32::from_bits(0x3d4b991f), + f32::from_bits(0x3d51ffef), f32::from_bits(0x3d58846a), f32::from_bits(0x3d5f26b7), f32::from_bits(0x3d65e6fe), + f32::from_bits(0x3d6cc564), f32::from_bits(0x3d73c20f), f32::from_bits(0x3d7add29), f32::from_bits(0x3d810b68), + f32::from_bits(0x3d84b795), f32::from_bits(0x3d887330), f32::from_bits(0x3d8c3e4a), f32::from_bits(0x3d9018f6), + f32::from_bits(0x3d940345), f32::from_bits(0x3d97fd4a), f32::from_bits(0x3d9c0716), f32::from_bits(0x3da020bb), + f32::from_bits(0x3da44a4b), f32::from_bits(0x3da883d7), f32::from_bits(0x3daccd70), f32::from_bits(0x3db12728), f32::from_bits(0x3db59112), + f32::from_bits(0x3dba0b3b), f32::from_bits(0x3dbe95b5), f32::from_bits(0x3dc33092), f32::from_bits(0x3dc7dbe2), + f32::from_bits(0x3dcc97b6), f32::from_bits(0x3dd1641f), f32::from_bits(0x3dd6412c), f32::from_bits(0x3ddb2eef), + f32::from_bits(0x3de02d77), f32::from_bits(0x3de53cd5), f32::from_bits(0x3dea5d19), f32::from_bits(0x3def8e55), + f32::from_bits(0x3df4d093), f32::from_bits(0x3dfa23ea), f32::from_bits(0x3dff8864), f32::from_bits(0x3e027f09), + f32::from_bits(0x3e054282), f32::from_bits(0x3e080ea5), f32::from_bits(0x3e0ae379), f32::from_bits(0x3e0dc107), + f32::from_bits(0x3e10a755), f32::from_bits(0x3e13966c), f32::from_bits(0x3e168e53), f32::from_bits(0x3e198f11), + f32::from_bits(0x3e1c98ae), f32::from_bits(0x3e1fab32), f32::from_bits(0x3e22c6a3), f32::from_bits(0x3e25eb0b), + f32::from_bits(0x3e29186d), f32::from_bits(0x3e2c4ed4), f32::from_bits(0x3e2f8e45), f32::from_bits(0x3e32d6c8), + f32::from_bits(0x3e362865), f32::from_bits(0x3e398322), f32::from_bits(0x3e3ce706), f32::from_bits(0x3e405419), + f32::from_bits(0x3e43ca62), f32::from_bits(0x3e4749e8), f32::from_bits(0x3e4ad2b1), f32::from_bits(0x3e4e64c6), + f32::from_bits(0x3e52002b), f32::from_bits(0x3e55a4e9), f32::from_bits(0x3e595307), f32::from_bits(0x3e5d0a8b), + f32::from_bits(0x3e60cb7c), f32::from_bits(0x3e6495e0), f32::from_bits(0x3e6869bf), f32::from_bits(0x3e6c4720), + f32::from_bits(0x3e702e0c), f32::from_bits(0x3e741e84), f32::from_bits(0x3e781890), f32::from_bits(0x3e7c1c38), + f32::from_bits(0x3e8014c2), f32::from_bits(0x3e82203c), f32::from_bits(0x3e84308d), f32::from_bits(0x3e8645ba), + f32::from_bits(0x3e885fc5), f32::from_bits(0x3e8a7eb2), f32::from_bits(0x3e8ca283), f32::from_bits(0x3e8ecb3d), + f32::from_bits(0x3e90f8e1), f32::from_bits(0x3e932b74), f32::from_bits(0x3e9562f8), f32::from_bits(0x3e979f71), + f32::from_bits(0x3e99e0e2), f32::from_bits(0x3e9c274e), f32::from_bits(0x3e9e72b7), f32::from_bits(0x3ea0c322), + f32::from_bits(0x3ea31892), f32::from_bits(0x3ea57308), f32::from_bits(0x3ea7d289), f32::from_bits(0x3eaa3718), + f32::from_bits(0x3eaca0b7), f32::from_bits(0x3eaf0f69), f32::from_bits(0x3eb18333), f32::from_bits(0x3eb3fc18), + f32::from_bits(0x3eb67a18), f32::from_bits(0x3eb8fd37), f32::from_bits(0x3ebb8579), f32::from_bits(0x3ebe12e1), + f32::from_bits(0x3ec0a571), f32::from_bits(0x3ec33d2d), f32::from_bits(0x3ec5da17), f32::from_bits(0x3ec87c33), + f32::from_bits(0x3ecb2383), f32::from_bits(0x3ecdd00b), f32::from_bits(0x3ed081cd), f32::from_bits(0x3ed338cc), + f32::from_bits(0x3ed5f50b), f32::from_bits(0x3ed8b68d), f32::from_bits(0x3edb7d54), f32::from_bits(0x3ede4965), + f32::from_bits(0x3ee11ac1), f32::from_bits(0x3ee3f16b), f32::from_bits(0x3ee6cd67), f32::from_bits(0x3ee9aeb7), + f32::from_bits(0x3eec955d), f32::from_bits(0x3eef815d), f32::from_bits(0x3ef272ba), f32::from_bits(0x3ef56976), + f32::from_bits(0x3ef86594), f32::from_bits(0x3efb6717), f32::from_bits(0x3efe6e02), f32::from_bits(0x3f00bd2d), + f32::from_bits(0x3f02460e), f32::from_bits(0x3f03d1a7), f32::from_bits(0x3f055ff9), f32::from_bits(0x3f06f108), + f32::from_bits(0x3f0884d1), f32::from_bits(0x3f0a1b57), f32::from_bits(0x3f0bb49d), f32::from_bits(0x3f0d50a2), + f32::from_bits(0x3f0eef69), f32::from_bits(0x3f1090f2), f32::from_bits(0x3f123540), f32::from_bits(0x3f13dc53), + f32::from_bits(0x3f15862d), f32::from_bits(0x3f1732cf), f32::from_bits(0x3f18e23b), f32::from_bits(0x3f1a9471), + f32::from_bits(0x3f1c4973), f32::from_bits(0x3f1e0143), f32::from_bits(0x3f1fbbe1), f32::from_bits(0x3f217950), + f32::from_bits(0x3f23398f), f32::from_bits(0x3f24fca2), f32::from_bits(0x3f26c288), f32::from_bits(0x3f288b43), + f32::from_bits(0x3f2a56d5), f32::from_bits(0x3f2c253f), f32::from_bits(0x3f2df681), f32::from_bits(0x3f2fca9e), + f32::from_bits(0x3f31a199), f32::from_bits(0x3f337b6e), f32::from_bits(0x3f355822), f32::from_bits(0x3f3737b5), + f32::from_bits(0x3f391a28), f32::from_bits(0x3f3aff7e), f32::from_bits(0x3f3ce7b7), f32::from_bits(0x3f3ed2d4), f32::from_bits(0x3f40c0d6), + f32::from_bits(0x3f42b1c0), f32::from_bits(0x3f44a592), f32::from_bits(0x3f469c4d), f32::from_bits(0x3f4895f3), + f32::from_bits(0x3f4a9284), f32::from_bits(0x3f4c9203), f32::from_bits(0x3f4e9470), f32::from_bits(0x3f5099cd), + f32::from_bits(0x3f52a21a), f32::from_bits(0x3f54ad59), f32::from_bits(0x3f56bb8c), f32::from_bits(0x3f58ccb3), + f32::from_bits(0x3f5ae0cf), f32::from_bits(0x3f5cf7e2), f32::from_bits(0x3f5f11ee), f32::from_bits(0x3f612ef2), f32::from_bits(0x3f634eef), + f32::from_bits(0x3f6571ec), f32::from_bits(0x3f6797e3), f32::from_bits(0x3f69c0db), f32::from_bits(0x3f6beccd), + f32::from_bits(0x3f6e1bc4), f32::from_bits(0x3f704db8), f32::from_bits(0x3f7282b4), f32::from_bits(0x3f74baae), + f32::from_bits(0x3f76f5b3), f32::from_bits(0x3f7933b9), f32::from_bits(0x3f7b74cb), f32::from_bits(0x3f7db8e0), + f32::from_bits(0x3f800000), ]; #[inline] @@ -162,12 +194,11 @@ mod tests { #[test] fn test_float_to_srgb_u8() { for u in 0..=u8::MAX { - // let a = srgb_u8_to_float(u); - // let b = srgb_u8_to_float_ref(u); - // if a != b { - // panic!("Mismatch at u={}: {} != {}", u, a, b); - // } - assert!(srgb_u8_to_float(u) == srgb_u8_to_float_ref(u)); + let a = srgb_u8_to_float(u); + let b = srgb_u8_to_float_ref(u); + if a != b { + panic!("Mismatch at u={}: {} != {}", u, a, b); + } } } From ab83b34a5ecfd5ec337ebddaba6288a3a4d003b1 Mon Sep 17 00:00:00 2001 From: Tyooughtul Date: Wed, 4 Mar 2026 14:38:25 +0800 Subject: [PATCH 4/7] fix: - replace hardcoded primary input/output indices with named constants - adds PRIMARY_INPUT_INDEX and PRIMARY_OUTPUT_INDEX constants to InputConnector, OutputConnector, and NodeInput, replaces hardcoded 0 indices with these constants. --- .../graph_operation_message_handler.rs | 10 +-- .../document/graph_operation/utility_types.rs | 4 +- .../node_graph/node_graph_message_handler.rs | 20 +++--- .../utility_types/network_interface.rs | 66 ++++++++++--------- .../network_interface/resolved_types.rs | 2 +- .../portfolio/portfolio_message_handler.rs | 2 +- .../shape_gizmos/point_radius_handle.rs | 1 + .../common_functionality/utility_functions.rs | 2 +- .../tool/tool_messages/spline_tool.rs | 2 +- .../messages/tool/tool_messages/text_tool.rs | 10 ++- editor/src/node_graph_executor.rs | 2 +- editor/src/node_graph_executor/runtime.rs | 2 +- node-graph/graph-craft/src/document.rs | 38 ++++++----- node-graph/interpreted-executor/src/lib.rs | 4 +- node-graph/interpreted-executor/src/util.rs | 16 ++--- node-graph/preprocessor/src/lib.rs | 4 +- 16 files changed, 99 insertions(+), 86 deletions(-) diff --git a/editor/src/messages/portfolio/document/graph_operation/graph_operation_message_handler.rs b/editor/src/messages/portfolio/document/graph_operation/graph_operation_message_handler.rs index 4620efed78..726d58ee4d 100644 --- a/editor/src/messages/portfolio/document/graph_operation/graph_operation_message_handler.rs +++ b/editor/src/messages/portfolio/document/graph_operation/graph_operation_message_handler.rs @@ -200,7 +200,7 @@ impl MessageHandler> for const LAYER_SECONDARY_INPUT_INDEX: usize = 1; responses.add(NodeGraphMessage::SetInput { input_connector: InputConnector::node(layer.to_node(), LAYER_SECONDARY_INPUT_INDEX), - input: NodeInput::node(first_new_node_id, 0), + input: NodeInput::node(first_new_node_id, NodeInput::PRIMARY_OUTPUT_INDEX), }); } // Move the layer and all nodes to the correct position in the network @@ -260,10 +260,10 @@ impl MessageHandler> for artboard_data.insert( artboard.to_node(), ArtboardInfo { - input_node: NodeInput::node(document_node.inputs[ARTBOARD_CONTENT_INDEX].as_node().unwrap_or_default(), 0), + input_node: NodeInput::node(document_node.inputs[ARTBOARD_CONTENT_INDEX].as_node().unwrap_or_default(), NodeInput::PRIMARY_OUTPUT_INDEX), output_nodes: network_interface .outward_wires(&[]) - .and_then(|outward_wires| outward_wires.get(&OutputConnector::node(artboard.to_node(), 0))) + .and_then(|outward_wires| outward_wires.get(&OutputConnector::node(artboard.to_node(), OutputConnector::PRIMARY_OUTPUT_INDEX))) .cloned() .unwrap_or_default(), merge_node: node_id, @@ -290,12 +290,12 @@ impl MessageHandler> for const MERGE_CONTENT_INDEX: usize = 1; responses.add(NodeGraphMessage::SetInput { input_connector: InputConnector::node(artboard.1.merge_node, MERGE_CONTENT_INDEX), - input: NodeInput::node(artboard.1.input_node.as_node().unwrap_or_default(), 0), + input: NodeInput::node(artboard.1.input_node.as_node().unwrap_or_default(), NodeInput::PRIMARY_OUTPUT_INDEX), }); // Modify upstream connections for outward_wire in &artboard.1.output_nodes { - let input = NodeInput::node(artboard_data[artboard.0].merge_node, 0); + let input = NodeInput::node(artboard_data[artboard.0].merge_node, NodeInput::PRIMARY_OUTPUT_INDEX); let input_connector = match artboard_data.get(&outward_wire.node_id().unwrap_or_default()) { Some(artboard_info) => InputConnector::node(artboard_info.merge_node, outward_wire.input_index()), _ => *outward_wire, 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 dbe7399cc2..4cf4c70830 100644 --- a/editor/src/messages/portfolio/document/graph_operation/utility_types.rs +++ b/editor/src/messages/portfolio/document/graph_operation/utility_types.rs @@ -92,7 +92,7 @@ impl<'a> ModifyInputsContext<'a> { current_index += 1; } // Input as a sibling to the Layer node above - post_node_input_connector = InputConnector::node(*next_node_in_stack_id, 0); + post_node_input_connector = InputConnector::node(*next_node_in_stack_id, InputConnector::PRIMARY_INPUT_INDEX); } else { log::error!("Error getting post node: insert_index out of bounds"); break; @@ -108,7 +108,7 @@ impl<'a> ModifyInputsContext<'a> { match pre_node_output_connector { Some(OutputConnector::Node { node_id: pre_node_id, .. }) if !network_interface.is_layer(&pre_node_id, &[]) => { // Update post_node_input_connector for the next iteration - post_node_input_connector = InputConnector::node(pre_node_id, 0); + post_node_input_connector = InputConnector::node(pre_node_id, InputConnector::PRIMARY_INPUT_INDEX); // Insert directly under layer if moving to the end of a layer stack that ends with a non layer node that does not have an exposed primary input let primary_is_exposed = network_interface.input_from_connector(&post_node_input_connector, &[]).is_some_and(|input| input.is_exposed()); if !primary_is_exposed { diff --git a/editor/src/messages/portfolio/document/node_graph/node_graph_message_handler.rs b/editor/src/messages/portfolio/document/node_graph/node_graph_message_handler.rs index 34e8a0eba8..68a815a47b 100644 --- a/editor/src/messages/portfolio/document/node_graph/node_graph_message_handler.rs +++ b/editor/src/messages/portfolio/document/node_graph/node_graph_message_handler.rs @@ -223,8 +223,8 @@ impl<'a> MessageHandler> for NodeG x: (mid_point.x / 24.) as i32, y: (mid_point.y / 24.) as i32, }); - let node_input_connector = InputConnector::node(node_id, 0); - let node_output_connector = OutputConnector::node(node_id, 0); + let node_input_connector = InputConnector::node(node_id, InputConnector::PRIMARY_INPUT_INDEX); + let node_output_connector = OutputConnector::node(node_id, OutputConnector::PRIMARY_OUTPUT_INDEX); responses.add(NodeGraphMessage::CreateWire { output_connector, input_connector: node_input_connector, @@ -473,7 +473,7 @@ impl<'a> MessageHandler> for NodeG return; }; - let encapsulating_connector = InputConnector::node(*node_id, 0); + let encapsulating_connector = InputConnector::node(*node_id, InputConnector::PRIMARY_INPUT_INDEX); if !exposed { network_interface.disconnect_input(&encapsulating_connector, network_path); } @@ -527,7 +527,7 @@ impl<'a> MessageHandler> for NodeG log::error!("Could not get outward wires in remove_import"); return; }; - let Some(downstream_connections) = outward_wires.get(&OutputConnector::node(*encapsulating_node, 0)).cloned() else { + let Some(downstream_connections) = outward_wires.get(&OutputConnector::node(*encapsulating_node, OutputConnector::PRIMARY_OUTPUT_INDEX)).cloned() else { log::error!("Could not get outward wires for import in remove_import"); return; }; @@ -1338,7 +1338,7 @@ impl<'a> MessageHandler> for NodeG let selected_node_id = selected_nodes.selected_nodes_ref()[0]; let has_primary_output_connection = network_interface .outward_wires(selection_network_path) - .is_some_and(|outward_wires| outward_wires.get(&OutputConnector::node(selected_node_id, 0)).is_some_and(|outward_wires| !outward_wires.is_empty())); + .is_some_and(|outward_wires| outward_wires.get(&OutputConnector::node(selected_node_id, OutputConnector::PRIMARY_OUTPUT_INDEX)).is_some_and(|outward_wires| !outward_wires.is_empty())); if !has_primary_output_connection { let Some(network) = network_interface.nested_network(selection_network_path) else { return; @@ -1532,13 +1532,13 @@ impl<'a> MessageHandler> for NodeG } let number_of_outputs = network_interface.number_of_outputs(selected_node, selection_network_path); - let mut first_deselected_upstream_output = network_interface.upstream_output_connector(&InputConnector::node(*selected_node, 0), selection_network_path); + let mut first_deselected_upstream_output = network_interface.upstream_output_connector(&InputConnector::node(*selected_node, InputConnector::PRIMARY_INPUT_INDEX), selection_network_path); while let Some(OutputConnector::Node { node_id, .. }) = &first_deselected_upstream_output { if !all_selected_nodes.contains(node_id) { break; } - first_deselected_upstream_output = network_interface.upstream_output_connector(&InputConnector::node(*node_id, 0), selection_network_path); + first_deselected_upstream_output = network_interface.upstream_output_connector(&InputConnector::node(*node_id, InputConnector::PRIMARY_INPUT_INDEX), selection_network_path); } let Some(outward_wires) = network_interface.outward_wires(selection_network_path) else { @@ -1561,7 +1561,7 @@ impl<'a> MessageHandler> for NodeG // Handle reconnection // Find first non selected upstream node by primary flow if let Some(first_deselected_upstream_output) = first_deselected_upstream_output { - let Some(downstream_connections_to_first_output) = outward_wires.get(&OutputConnector::node(*selected_node, 0)).cloned() else { + let Some(downstream_connections_to_first_output) = outward_wires.get(&OutputConnector::node(*selected_node, OutputConnector::PRIMARY_OUTPUT_INDEX)).cloned() else { log::error!("Could not get downstream_connections_to_first_output in shake node"); return; }; @@ -2590,7 +2590,7 @@ impl NodeGraphMessageHandler { }; let mut nodes = Vec::new(); for (node_id, visible) in network.nodes.iter().map(|(node_id, node)| (*node_id, node.visible)).collect::>() { - let primary_input_connector = InputConnector::node(node_id, 0); + let primary_input_connector = InputConnector::node(node_id, InputConnector::PRIMARY_INPUT_INDEX); let primary_input = if network_interface .input_from_connector(&primary_input_connector, breadcrumb_network_path) @@ -2604,7 +2604,7 @@ impl NodeGraphMessageHandler { .filter_map(|input_index| network_interface.frontend_input_from_connector(&InputConnector::node(node_id, input_index), breadcrumb_network_path)) .collect(); - let primary_output = network_interface.frontend_output_from_connector(&OutputConnector::node(node_id, 0), breadcrumb_network_path); + let primary_output = network_interface.frontend_output_from_connector(&OutputConnector::node(node_id, OutputConnector::PRIMARY_OUTPUT_INDEX), breadcrumb_network_path); let exposed_outputs = (1..network_interface.number_of_outputs(&node_id, breadcrumb_network_path)) .filter_map(|output_index| network_interface.frontend_output_from_connector(&OutputConnector::node(node_id, output_index), breadcrumb_network_path)) diff --git a/editor/src/messages/portfolio/document/utility_types/network_interface.rs b/editor/src/messages/portfolio/document/utility_types/network_interface.rs index 212a31cd8c..ef451271b4 100644 --- a/editor/src/messages/portfolio/document/utility_types/network_interface.rs +++ b/editor/src/messages/portfolio/document/utility_types/network_interface.rs @@ -216,7 +216,7 @@ impl NodeNetworkInterface { pub fn downstream_layer_for_chain_node(&mut self, node_id: &NodeId, network_path: &[NodeId]) -> Option { let mut id = *node_id; while !self.is_layer(&id, network_path) { - id = self.outward_wires(network_path)?.get(&OutputConnector::node(id, 0))?.first()?.node_id()?; + id = self.outward_wires(network_path)?.get(&OutputConnector::node(id, OutputConnector::PRIMARY_OUTPUT_INDEX))?.first()?.node_id()?; } Some(id) } @@ -229,7 +229,7 @@ impl NodeNetworkInterface { if self.is_layer(¤t_node, network_path) { layers.push(current_node); } else { - let Some(outward_wires) = self.outward_wires(network_path).and_then(|outward_wires| outward_wires.get(&OutputConnector::node(current_node, 0))) else { + let Some(outward_wires) = self.outward_wires(network_path).and_then(|outward_wires| outward_wires.get(&OutputConnector::node(current_node, OutputConnector::PRIMARY_OUTPUT_INDEX))) else { log::error!("Could not get outward wires in downstream_layer"); return Vec::new(); }; @@ -370,7 +370,7 @@ impl NodeNetworkInterface { return None; }; // TODO: Get downstream connections from all outputs - let mut downstream_connections = outward_wires.get(&OutputConnector::node(*node_id, 0)).map_or([].iter(), |outputs| outputs.iter()); + let mut downstream_connections = outward_wires.get(&OutputConnector::node(*node_id, OutputConnector::PRIMARY_OUTPUT_INDEX)).map_or([].iter(), |outputs| outputs.iter()); let has_selected_node_downstream = downstream_connections.any(|input_connector| input_connector.node_id().is_some_and(|upstream_id| new_ids.keys().any(|key| *key == upstream_id))); // If the copied node does not have a downstream connection to another copied node, then set the position to absolute if !has_selected_node_downstream { @@ -1066,7 +1066,7 @@ impl NodeNetworkInterface { log::error!("Could not get outward_wires in primary_output_connected_to_layer"); return false; }; - let Some(downstream_connectors) = outward_wires.get(&OutputConnector::node(*node_id, 0)) else { + let Some(downstream_connectors) = outward_wires.get(&OutputConnector::node(*node_id, OutputConnector::PRIMARY_OUTPUT_INDEX)) else { log::error!("Could not get downstream_connectors in primary_output_connected_to_layer"); return false; }; @@ -1079,7 +1079,7 @@ impl NodeNetworkInterface { } pub fn primary_input_connected_to_layer(&mut self, node_id: &NodeId, network_path: &[NodeId]) -> bool { - self.input_from_connector(&InputConnector::node(*node_id, 0), network_path) + self.input_from_connector(&InputConnector::node(*node_id, InputConnector::PRIMARY_INPUT_INDEX), network_path) .and_then(|input| input.as_node()) .is_some_and(|node_id| self.is_layer(&node_id, network_path)) } @@ -1103,7 +1103,7 @@ impl NodeNetworkInterface { let Some((encapsulating_node_id, encapsulating_path)) = network_path.split_last() else { return false; }; - self.input_from_connector(&InputConnector::node(*encapsulating_node_id, 0), encapsulating_path) + self.input_from_connector(&InputConnector::node(*encapsulating_node_id, InputConnector::PRIMARY_INPUT_INDEX), encapsulating_path) .is_some_and(|input| !input.is_exposed()) } @@ -1616,7 +1616,7 @@ impl NodeNetworkInterface { log::error!("Cannot load outward wires in load_stack_dependents"); return; }; - let Some(layer_outward_wires) = outward_wires.get(&OutputConnector::node(current_node, 0)) else { + let Some(layer_outward_wires) = outward_wires.get(&OutputConnector::node(current_node, OutputConnector::PRIMARY_OUTPUT_INDEX)) else { log::error!("Could not get outward_wires for layer {current_node}"); break; }; @@ -2613,7 +2613,7 @@ impl NodeNetworkInterface { LayerPosition::Stack(y_offset) => { let Some(downstream_node_connectors) = self .outward_wires(network_path) - .and_then(|outward_wires| outward_wires.get(&OutputConnector::node(*node_id, 0))) + .and_then(|outward_wires| outward_wires.get(&OutputConnector::node(*node_id, OutputConnector::PRIMARY_OUTPUT_INDEX))) .cloned() else { log::error!("Could not get downstream node in position_from_downstream_node"); @@ -2648,7 +2648,7 @@ impl NodeNetworkInterface { // TODO: Use root node to restore if previewing let Some(downstream_node_connectors) = self .outward_wires(network_path) - .and_then(|outward_wires| outward_wires.get(&OutputConnector::node(current_node_id, 0))) + .and_then(|outward_wires| outward_wires.get(&OutputConnector::node(current_node_id, OutputConnector::PRIMARY_OUTPUT_INDEX))) .cloned() else { log::error!("Could not get downstream node for node {node_id} with Position::Chain"); @@ -3985,7 +3985,7 @@ impl NodeNetworkInterface { // If the layer feeds into the bottom input of layer, and has no other outputs, set its position to stack at its previous y position let multiple_outward_wires = self .outward_wires(network_path) - .and_then(|all_outward_wires| all_outward_wires.get(&OutputConnector::node(*upstream_node_id, 0))) + .and_then(|all_outward_wires| all_outward_wires.get(&OutputConnector::node(*upstream_node_id, OutputConnector::PRIMARY_OUTPUT_INDEX))) .is_some_and(|outward_wires| outward_wires.len() > 1); if *input_index == 0 && !multiple_outward_wires { self.set_stack_position_calculated_offset(upstream_node_id, downstream_node_id, network_path); @@ -4026,7 +4026,7 @@ impl NodeNetworkInterface { let old_upstream_node_is_layer = self.is_layer(&old_upstream_node_id, network_path); let Some(outward_wires) = self .outward_wires(network_path) - .and_then(|outward_wires| outward_wires.get(&OutputConnector::node(old_upstream_node_id, 0))) + .and_then(|outward_wires| outward_wires.get(&OutputConnector::node(old_upstream_node_id, OutputConnector::PRIMARY_OUTPUT_INDEX))) else { log::error!("Could not get outward wires in set_input"); return; @@ -4347,7 +4347,7 @@ impl NodeNetworkInterface { && let Some(reconnect_input) = &reconnect_to_input { reconnect_node = reconnect_input.as_node().and_then(|node_id| if self.is_stack(&node_id, network_path) { Some(node_id) } else { None }); - self.disconnect_input(&InputConnector::node(*node_id, 0), network_path); + self.disconnect_input(&InputConnector::node(*node_id, InputConnector::PRIMARY_INPUT_INDEX), network_path); self.set_input(downstream_input, reconnect_input.clone(), network_path); } } @@ -4561,7 +4561,7 @@ impl NodeNetworkInterface { if self.is_layer(&upstream_sibling_id, network_path) && self .outward_wires(network_path) - .and_then(|outward_wires| outward_wires.get(&OutputConnector::node(upstream_sibling_id, 0))) + .and_then(|outward_wires| outward_wires.get(&OutputConnector::node(upstream_sibling_id, OutputConnector::PRIMARY_OUTPUT_INDEX))) .is_some_and(|outward_wires| outward_wires.len() == 1) { self.set_stack_position_calculated_offset(&upstream_sibling_id, node_id, network_path); @@ -4582,7 +4582,7 @@ impl NodeNetworkInterface { .outward_wires(network_path) .and_then(|outward_wires| { outward_wires - .get(&OutputConnector::node(*node_id, 0)) + .get(&OutputConnector::node(*node_id, OutputConnector::PRIMARY_OUTPUT_INDEX)) .and_then(|outward_wires| (outward_wires.len() == 1).then(|| outward_wires[0])) .and_then(|downstream_connector| if downstream_connector.input_index() == 0 { downstream_connector.node_id() } else { None }) }) @@ -4673,7 +4673,7 @@ impl NodeNetworkInterface { } // The export is not clicked else { - new_export = Some(OutputConnector::node(toggle_id, 0)); + new_export = Some(OutputConnector::node(toggle_id, OutputConnector::PRIMARY_OUTPUT_INDEX)); // There is currently a dashed line being drawn if let Previewing::Yes { root_node_to_restore } = self.previewing(network_path) { @@ -4681,7 +4681,7 @@ impl NodeNetworkInterface { if let Some(root_node_to_restore) = root_node_to_restore { // If the node with the solid line is clicked, then start previewing that node without restore if root_node_to_restore.node_id == toggle_id { - new_export = Some(OutputConnector::node(toggle_id, 0)); + new_export = Some(OutputConnector::node(toggle_id, OutputConnector::PRIMARY_OUTPUT_INDEX)); new_previewing_state = Previewing::Yes { root_node_to_restore: None }; } else { // Root node to restore does not change @@ -4697,7 +4697,7 @@ impl NodeNetworkInterface { } // Not previewing, there is no dashed line being drawn else { - new_export = Some(OutputConnector::node(toggle_id, 0)); + new_export = Some(OutputConnector::node(toggle_id, OutputConnector::PRIMARY_OUTPUT_INDEX)); new_previewing_state = Previewing::Yes { root_node_to_restore: Some(RootNode { node_id: previous_export_id, @@ -4710,7 +4710,7 @@ impl NodeNetworkInterface { // The primary export is disconnected else { // Set node as export and cancel any preview - new_export = Some(OutputConnector::node(toggle_id, 0)); + new_export = Some(OutputConnector::node(toggle_id, OutputConnector::PRIMARY_OUTPUT_INDEX)); self.start_previewing_without_restore(network_path); } } @@ -4803,7 +4803,7 @@ impl NodeNetworkInterface { else { log::error!("Could not set chain position for layer node {node_id}"); } - // let previous_upstream_node = self.upstream_output_connector(&InputConnector::node(*node_id, 0), network_path).and_then(|output| output.node_id()); + // let previous_upstream_node = self.upstream_output_connector(&InputConnector::node(*node_id, InputConnector::PRIMARY_INPUT_INDEX), network_path).and_then(|output| output.node_id()); // let Some(previous_upstream_node_position) = previous_upstream_node.and_then(|upstream| self.position_from_downstream_node(&upstream, network_path)) else { // log::error!("Could not get previous_upstream_node_position"); // return; @@ -4863,7 +4863,7 @@ impl NodeNetworkInterface { if self.is_layer(&upstream_node, network_path) || self.hidden_primary_output(&upstream_node, network_path) { break; } - let Some(outward_wires) = self.outward_wires(network_path).and_then(|outward_wires| outward_wires.get(&OutputConnector::node(upstream_node, 0))) else { + let Some(outward_wires) = self.outward_wires(network_path).and_then(|outward_wires| outward_wires.get(&OutputConnector::node(upstream_node, OutputConnector::PRIMARY_OUTPUT_INDEX))) else { log::error!("Could not get outward wires in try_set_upstream_to_chain"); break; }; @@ -4910,7 +4910,7 @@ impl NodeNetworkInterface { break; }; downstream_layer = outward_wires - .get(&OutputConnector::node(downstream_layer_id, 0)) + .get(&OutputConnector::node(downstream_layer_id, OutputConnector::PRIMARY_OUTPUT_INDEX)) .and_then(|outward_wires| if outward_wires.len() == 1 { outward_wires[0].node_id() } else { None }); } else { break; @@ -4925,7 +4925,7 @@ impl NodeNetworkInterface { fn try_set_node_to_chain(&mut self, node_id: &NodeId, network_path: &[NodeId]) { if let Some(outward_wires) = self .outward_wires(network_path) - .and_then(|outward_wires| outward_wires.get(&OutputConnector::node(*node_id, 0))) + .and_then(|outward_wires| outward_wires.get(&OutputConnector::node(*node_id, OutputConnector::PRIMARY_OUTPUT_INDEX))) .cloned() && outward_wires.len() == 1 { self.try_set_upstream_to_chain(&outward_wires[0], network_path) @@ -4937,7 +4937,7 @@ impl NodeNetworkInterface { if !self.is_layer(upstream_id, network_path) && self .outward_wires(network_path) - .is_some_and(|outward_wires| outward_wires.get(&OutputConnector::node(*upstream_id, 0)).is_some_and(|outward_wires| outward_wires.len() == 1)) + .is_some_and(|outward_wires| outward_wires.get(&OutputConnector::node(*upstream_id, OutputConnector::PRIMARY_OUTPUT_INDEX)).is_some_and(|outward_wires| outward_wires.len() == 1)) { self.set_chain_position(upstream_id, network_path); } @@ -5060,7 +5060,7 @@ impl NodeNetworkInterface { && let LayerPosition::Stack(offset) = layer_metadata.position { // If the upstream layer is selected, then skip - let Some(outward_wires) = self.outward_wires(network_path).and_then(|outward_wires| outward_wires.get(&OutputConnector::node(*node_id, 0))) else { + let Some(outward_wires) = self.outward_wires(network_path).and_then(|outward_wires| outward_wires.get(&OutputConnector::node(*node_id, OutputConnector::PRIMARY_OUTPUT_INDEX))) else { log::error!("Could not get outward wires in shift_selected_nodes"); return; }; @@ -5113,7 +5113,7 @@ impl NodeNetworkInterface { } let Some(downstream_node) = self .outward_wires(network_path) - .and_then(|outward_wires| outward_wires.get(&OutputConnector::node(downstream_absolute_layer, 0))) + .and_then(|outward_wires| outward_wires.get(&OutputConnector::node(downstream_absolute_layer, OutputConnector::PRIMARY_OUTPUT_INDEX))) .and_then(|downstream_nodes| downstream_nodes.first()) .and_then(|downstream_node| downstream_node.node_id()) else { @@ -5567,7 +5567,7 @@ impl NodeNetworkInterface { match post_node_input { // Create a new stack NodeInput::Value { .. } | NodeInput::Scope(_) | NodeInput::Inline(_) | NodeInput::Reflection(_) => { - self.create_wire(&OutputConnector::node(layer.to_node(), 0), &post_node, network_path); + self.create_wire(&OutputConnector::node(layer.to_node(), OutputConnector::PRIMARY_OUTPUT_INDEX), &post_node, network_path); let final_layer_position = after_move_post_layer_position + IVec2::new(-8, 3); let shift = final_layer_position - previous_layer_position; @@ -5595,7 +5595,7 @@ impl NodeNetworkInterface { NodeInput::Value { .. } | NodeInput::Scope(_) | NodeInput::Inline(_) | NodeInput::Reflection(_) => { let offset = after_move_post_layer_position - previous_layer_position + IVec2::new(0, 3 + height_above_layer); self.shift_absolute_node_position(&layer.to_node(), offset, network_path); - self.create_wire(&OutputConnector::node(layer.to_node(), 0), &post_node, network_path); + self.create_wire(&OutputConnector::node(layer.to_node(), OutputConnector::PRIMARY_OUTPUT_INDEX), &post_node, network_path); } // Insert into the stack NodeInput::Node { .. } => { @@ -5614,7 +5614,7 @@ impl NodeNetworkInterface { self.insert_node_between(&layer.to_node(), &post_node, 0, network_path); // Get the other wires which need to be moved to the output of the moved layer - let layer_input_connector = InputConnector::node(layer.to_node(), 0); + let layer_input_connector = InputConnector::node(layer.to_node(), InputConnector::PRIMARY_INPUT_INDEX); let other_outward_wires = self .upstream_output_connector(&layer_input_connector, network_path) .and_then(|pre_node_output| self.outward_wires(network_path).and_then(|wires| wires.get(&pre_node_output))) @@ -5630,7 +5630,7 @@ impl NodeNetworkInterface { // Disconnect and reconnect for other_outward_wire in &other_outward_wires { self.disconnect_input(other_outward_wire, network_path); - self.create_wire(&OutputConnector::node(layer.to_node(), 0), other_outward_wire, network_path); + self.create_wire(&OutputConnector::node(layer.to_node(), OutputConnector::PRIMARY_OUTPUT_INDEX), other_outward_wire, network_path); } } self.unload_upstream_node_click_targets(vec![layer.to_node()], network_path); @@ -5652,7 +5652,7 @@ impl NodeNetworkInterface { self.disconnect_input(input_connector, network_path); // Connect the input connector to the new node - self.create_wire(&OutputConnector::node(*node_id, 0), input_connector, network_path); + self.create_wire(&OutputConnector::node(*node_id, OutputConnector::PRIMARY_OUTPUT_INDEX), input_connector, network_path); // Connect the new node to the previous node self.create_wire(&upstream_output, &InputConnector::node(*node_id, insert_node_input_index), network_path); @@ -5666,7 +5666,7 @@ impl NodeNetworkInterface { return; }; if matches!(current_input, NodeInput::Value { .. }) { - self.create_wire(&OutputConnector::node(*node_id, 0), &InputConnector::node(parent.to_node(), LAYER_SECONDARY_INPUT_INDEX), network_path); + self.create_wire(&OutputConnector::node(*node_id, OutputConnector::PRIMARY_OUTPUT_INDEX), &InputConnector::node(parent.to_node(), LAYER_SECONDARY_INPUT_INDEX), network_path); self.set_chain_position(node_id, network_path); } else { // Insert the node in the gap and set the upstream to a chain @@ -5758,6 +5758,8 @@ impl Default for InputConnector { } impl InputConnector { + pub const PRIMARY_INPUT_INDEX: usize = 0; + pub fn node(node_id: NodeId, input_index: usize) -> Self { InputConnector::Node { node_id, input_index } } @@ -5799,6 +5801,8 @@ impl Default for OutputConnector { } impl OutputConnector { + pub const PRIMARY_OUTPUT_INDEX: usize = 0; + pub fn node(node_id: NodeId, output_index: usize) -> Self { OutputConnector::Node { node_id, output_index } } diff --git a/editor/src/messages/portfolio/document/utility_types/network_interface/resolved_types.rs b/editor/src/messages/portfolio/document/utility_types/network_interface/resolved_types.rs index e7d724d76b..c2e1646579 100644 --- a/editor/src/messages/portfolio/document/utility_types/network_interface/resolved_types.rs +++ b/editor/src/messages/portfolio/document/utility_types/network_interface/resolved_types.rs @@ -287,7 +287,7 @@ impl NodeNetworkInterface { log::error!("Protonode {proto_node_identifier:?} not found in registry in complete_valid_input_types"); return Vec::new(); }; - let valid_output_types = self.valid_output_types(&OutputConnector::node(*node_id, 0), network_path); + let valid_output_types = self.valid_output_types(&OutputConnector::node(*node_id, OutputConnector::PRIMARY_OUTPUT_INDEX), network_path); implementations .iter() diff --git a/editor/src/messages/portfolio/portfolio_message_handler.rs b/editor/src/messages/portfolio/portfolio_message_handler.rs index d45f832f82..05f2f5a478 100644 --- a/editor/src/messages/portfolio/portfolio_message_handler.rs +++ b/editor/src/messages/portfolio/portfolio_message_handler.rs @@ -612,7 +612,7 @@ impl MessageHandler> for Portfolio let Some((downstream_node, input_index)) = document .network_interface .outward_wires(&[]) - .and_then(|outward_wires| outward_wires.get(&OutputConnector::node(layer.to_node(), 0))) + .and_then(|outward_wires| outward_wires.get(&OutputConnector::node(layer.to_node(), OutputConnector::PRIMARY_OUTPUT_INDEX))) .and_then(|outward_wires| outward_wires.first()) .and_then(|input_connector| input_connector.node_id().map(|node_id| (node_id, input_connector.input_index()))) else { diff --git a/editor/src/messages/tool/common_functionality/gizmos/shape_gizmos/point_radius_handle.rs b/editor/src/messages/tool/common_functionality/gizmos/shape_gizmos/point_radius_handle.rs index b09817600a..daf91a0cba 100644 --- a/editor/src/messages/tool/common_functionality/gizmos/shape_gizmos/point_radius_handle.rs +++ b/editor/src/messages/tool/common_functionality/gizmos/shape_gizmos/point_radius_handle.rs @@ -14,6 +14,7 @@ use crate::messages::tool::common_functionality::shapes::shape_utility::{extract use glam::DVec2; use graph_craft::document::NodeInput; use graph_craft::document::value::TaggedValue; +use graphene_std::NodeInputDecleration; use graphene_std::vector::generator_nodes::star::*; use std::collections::VecDeque; use std::f64::consts::{FRAC_1_SQRT_2, FRAC_PI_4, PI, SQRT_2}; diff --git a/editor/src/messages/tool/common_functionality/utility_functions.rs b/editor/src/messages/tool/common_functionality/utility_functions.rs index e8d4293721..accf27dc96 100644 --- a/editor/src/messages/tool/common_functionality/utility_functions.rs +++ b/editor/src/messages/tool/common_functionality/utility_functions.rs @@ -575,7 +575,7 @@ pub fn make_path_editable_is_allowed(network_interface: &mut NodeNetworkInterfac // Must be a layer of type Table let node_id = NodeGraphLayer::new(first_layer, network_interface).horizontal_layer_flow().nth(1)?; - let output_type = network_interface.output_type(&OutputConnector::node(node_id, 0), &[]); + let output_type = network_interface.output_type(&OutputConnector::node(node_id, OutputConnector::PRIMARY_OUTPUT_INDEX), &[]); if output_type.compiled_nested_type() != Some(&concrete!(Table)) { return None; } diff --git a/editor/src/messages/tool/tool_messages/spline_tool.rs b/editor/src/messages/tool/tool_messages/spline_tool.rs index 62e9b8e600..6cc9e5ad07 100644 --- a/editor/src/messages/tool/tool_messages/spline_tool.rs +++ b/editor/src/messages/tool/tool_messages/spline_tool.rs @@ -396,7 +396,7 @@ impl Fsm for SplineToolFsmState { let path_node_type = resolve_network_node_type("Path").expect("Path node does not exist"); let path_node = path_node_type.default_node_template(); let spline_node_type = resolve_proto_node_type(graphene_std::vector::spline::IDENTIFIER).expect("Spline node does not exist"); - let spline_node = spline_node_type.node_template_input_override([Some(NodeInput::node(NodeId(1), 0))]); + let spline_node = spline_node_type.node_template_input_override([Some(NodeInput::node(NodeId(1), NodeInput::PRIMARY_OUTPUT_INDEX))]); let nodes = vec![(NodeId(1), path_node), (NodeId(0), spline_node)]; let layer = graph_modification_utils::new_custom(NodeId::new(), nodes, parent, responses); diff --git a/editor/src/messages/tool/tool_messages/text_tool.rs b/editor/src/messages/tool/tool_messages/text_tool.rs index c5471f0bff..01c7d1508d 100644 --- a/editor/src/messages/tool/tool_messages/text_tool.rs +++ b/editor/src/messages/tool/tool_messages/text_tool.rs @@ -465,7 +465,10 @@ impl TextToolData { responses.add(NodeGraphMessage::SelectedNodesSet { nodes: vec![self.layer.to_node()] }); // Make the rendered text invisible while editing responses.add(NodeGraphMessage::SetInput { - input_connector: InputConnector::node(graph_modification_utils::get_text_id(self.layer, &document.network_interface).unwrap(), 1), + input_connector: InputConnector::node( + graph_modification_utils::get_text_id(self.layer, &document.network_interface).unwrap(), + graphene_std::text::text::TextInput::INDEX, + ), input: NodeInput::value(TaggedValue::String("".to_string()), false), }); responses.add(NodeGraphMessage::RunDocumentGraph); @@ -945,7 +948,10 @@ impl Fsm for TextToolFsmState { tool_data.set_editing(false, font_cache, responses); responses.add(NodeGraphMessage::SetInput { - input_connector: InputConnector::node(graph_modification_utils::get_text_id(tool_data.layer, &document.network_interface).unwrap(), 1), + input_connector: InputConnector::node( + graph_modification_utils::get_text_id(tool_data.layer, &document.network_interface).unwrap(), + graphene_std::text::text::TextInput::INDEX, + ), input: NodeInput::value(TaggedValue::String(tool_data.new_text.clone()), false), }); responses.add(NodeGraphMessage::RunDocumentGraph); diff --git a/editor/src/node_graph_executor.rs b/editor/src/node_graph_executor.rs index 8fe138be44..c119e8369f 100644 --- a/editor/src/node_graph_executor.rs +++ b/editor/src/node_graph_executor.rs @@ -553,7 +553,7 @@ mod test { let mut monitor_node_ids = Vec::with_capacity(node.inputs.len()); for input in &mut node.inputs { let node_id = NodeId::new(); - let old_input = std::mem::replace(input, NodeInput::node(node_id, 0)); + let old_input = std::mem::replace(input, NodeInput::node(node_id, NodeInput::PRIMARY_OUTPUT_INDEX)); monitor_nodes.push((old_input, node_id)); path.push(node_id); monitor_node_ids.push(path.clone()); diff --git a/editor/src/node_graph_executor/runtime.rs b/editor/src/node_graph_executor/runtime.rs index 9b7a8de4d6..7e7b599778 100644 --- a/editor/src/node_graph_executor/runtime.rs +++ b/editor/src/node_graph_executor/runtime.rs @@ -630,7 +630,7 @@ impl InspectState { } let monitor_node = DocumentNode { - inputs: vec![NodeInput::node(inspect_node, 0)], // Connect to the primary output of the inspect node + inputs: vec![NodeInput::node(inspect_node, NodeInput::PRIMARY_OUTPUT_INDEX)], // Connect to the primary output of the inspect node implementation: DocumentNodeImplementation::ProtoNode(graphene_std::memo::monitor::IDENTIFIER), call_argument: graph_craft::generic!(T), skip_deduplication: true, diff --git a/node-graph/graph-craft/src/document.rs b/node-graph/graph-craft/src/document.rs index 0cb33bf3ff..6368e3bc0c 100644 --- a/node-graph/graph-craft/src/document.rs +++ b/node-graph/graph-craft/src/document.rs @@ -222,6 +222,8 @@ impl DocumentNodeMetadata { } impl NodeInput { + pub const PRIMARY_OUTPUT_INDEX: usize = 0; + pub const fn node(node_id: NodeId, output_index: usize) -> Self { Self::Node { node_id, output_index } } @@ -573,7 +575,7 @@ impl NodeNetwork { pub fn value_network(node: DocumentNode) -> Self { Self { - exports: vec![NodeInput::node(NodeId(0), 0)], + exports: vec![NodeInput::node(NodeId(0), NodeInput::PRIMARY_OUTPUT_INDEX)], nodes: [(NodeId(0), node)].into_iter().collect(), ..Default::default() } @@ -767,7 +769,7 @@ impl NodeNetwork { if let NodeInput::Scope(key) = input { let (import_id, _ty) = self.scope_injections.get(key.as_ref()).expect("Tried to import a non existent key from scope"); // TODO use correct output index - *input = NodeInput::node(*import_id, 0); + *input = NodeInput::node(*import_id, NodeInput::PRIMARY_OUTPUT_INDEX); } } } @@ -866,7 +868,7 @@ impl NodeNetwork { NodeInput::Scope(ref key) => { let (import_id, _ty) = self.scope_injections.get(key.as_ref()).expect("Tried to import a non existent key from scope"); // TODO use correct output index - nested_node.inputs[nested_input_index] = NodeInput::node(*import_id, 0); + nested_node.inputs[nested_input_index] = NodeInput::node(*import_id, NodeInput::PRIMARY_OUTPUT_INDEX); } NodeInput::Reflection(_) => unreachable!("Reflection inputs should have been replaced with value nodes"), } @@ -946,7 +948,7 @@ impl NodeNetwork { ); *export = NodeInput::Node { node_id: merged_node_id, - output_index: 0, + output_index: NodeInput::PRIMARY_OUTPUT_INDEX, }; } } @@ -1149,7 +1151,7 @@ mod test { fn add_network() -> NodeNetwork { NodeNetwork { - exports: vec![NodeInput::node(NodeId(1), 0)], + exports: vec![NodeInput::node(NodeId(1), NodeInput::PRIMARY_OUTPUT_INDEX)], nodes: [ ( NodeId(0), @@ -1162,7 +1164,7 @@ mod test { ( NodeId(1), DocumentNode { - inputs: vec![NodeInput::node(NodeId(0), 0)], + inputs: vec![NodeInput::node(NodeId(0), NodeInput::PRIMARY_OUTPUT_INDEX)], implementation: DocumentNodeImplementation::ProtoNode(ProtoNodeIdentifier::new("core_types::ops::AddPairNode")), ..Default::default() }, @@ -1179,7 +1181,7 @@ mod test { let mut network = add_network(); network.map_ids(|id| NodeId(id.0 + 1)); let mapped_add = NodeNetwork { - exports: vec![NodeInput::node(NodeId(2), 0)], + exports: vec![NodeInput::node(NodeId(2), NodeInput::PRIMARY_OUTPUT_INDEX)], nodes: [ ( NodeId(1), @@ -1192,7 +1194,7 @@ mod test { ( NodeId(2), DocumentNode { - inputs: vec![NodeInput::node(NodeId(1), 0)], + inputs: vec![NodeInput::node(NodeId(1), NodeInput::PRIMARY_OUTPUT_INDEX)], implementation: DocumentNodeImplementation::ProtoNode(ProtoNodeIdentifier::new("core_types::ops::AddPairNode")), ..Default::default() }, @@ -1214,11 +1216,11 @@ mod test { }; // TODO: Extend test cases to test nested network let mut extraction_network = NodeNetwork { - exports: vec![NodeInput::node(NodeId(1), 0)], + exports: vec![NodeInput::node(NodeId(1), NodeInput::PRIMARY_OUTPUT_INDEX)], nodes: [ id_node.clone(), DocumentNode { - inputs: vec![NodeInput::node(NodeId(0), 0)], + inputs: vec![NodeInput::node(NodeId(0), NodeInput::PRIMARY_OUTPUT_INDEX)], implementation: DocumentNodeImplementation::Extract, ..Default::default() }, @@ -1239,7 +1241,7 @@ mod test { #[test] fn flatten_add() { let mut network = NodeNetwork { - exports: vec![NodeInput::node(NodeId(1), 0)], + exports: vec![NodeInput::node(NodeId(1), NodeInput::PRIMARY_OUTPUT_INDEX)], nodes: [( NodeId(1), DocumentNode { @@ -1264,7 +1266,7 @@ mod test { #[test] fn resolve_proto_node_add() { let document_node = DocumentNode { - inputs: vec![NodeInput::node(NodeId(0), 0)], + inputs: vec![NodeInput::node(NodeId(0), NodeInput::PRIMARY_OUTPUT_INDEX)], call_argument: concrete!(u32), implementation: DocumentNodeImplementation::ProtoNode(ProtoNodeIdentifier::new("core_types::structural::ConsNode")), ..Default::default() @@ -1347,12 +1349,12 @@ mod test { fn flat_network() -> NodeNetwork { NodeNetwork { - exports: vec![NodeInput::node(NodeId(11), 0)], + exports: vec![NodeInput::node(NodeId(11), NodeInput::PRIMARY_OUTPUT_INDEX)], nodes: [ ( NodeId(10), DocumentNode { - inputs: vec![NodeInput::node(NodeId(14), 0)], + inputs: vec![NodeInput::node(NodeId(14), NodeInput::PRIMARY_OUTPUT_INDEX)], call_argument: concrete!(u32), implementation: DocumentNodeImplementation::ProtoNode(ProtoNodeIdentifier::new("core_types::structural::ConsNode")), original_location: OriginalLocation { @@ -1381,7 +1383,7 @@ mod test { ( NodeId(11), DocumentNode { - inputs: vec![NodeInput::node(NodeId(10), 0)], + inputs: vec![NodeInput::node(NodeId(10), NodeInput::PRIMARY_OUTPUT_INDEX)], implementation: DocumentNodeImplementation::ProtoNode(ProtoNodeIdentifier::new("core_types::ops::AddPairNode")), original_location: OriginalLocation { path: Some(vec![NodeId(1), NodeId(1)]), @@ -1401,7 +1403,7 @@ mod test { fn two_node_identity() -> NodeNetwork { NodeNetwork { - exports: vec![NodeInput::node(NodeId(1), 0), NodeInput::node(NodeId(2), 0)], + exports: vec![NodeInput::node(NodeId(1), NodeInput::PRIMARY_OUTPUT_INDEX), NodeInput::node(NodeId(2), NodeInput::PRIMARY_OUTPUT_INDEX)], nodes: [ ( NodeId(1), @@ -1461,10 +1463,10 @@ mod test { #[test] fn simple_duplicate() { - let result = output_duplicate(vec![NodeInput::node(NodeId(1), 0)], NodeInput::node(NodeId(1), 0)); + let result = output_duplicate(vec![NodeInput::node(NodeId(1), NodeInput::PRIMARY_OUTPUT_INDEX)], NodeInput::node(NodeId(1), NodeInput::PRIMARY_OUTPUT_INDEX)); println!("{result:#?}"); assert_eq!(result.exports.len(), 1, "The number of outputs should remain as 1"); - assert_eq!(result.exports[0], NodeInput::node(NodeId(11), 0), "The outer network output should be from a duplicated inner network"); + assert_eq!(result.exports[0], NodeInput::node(NodeId(11), NodeInput::PRIMARY_OUTPUT_INDEX), "The outer network output should be from a duplicated inner network"); let mut ids = result.nodes.keys().copied().collect::>(); ids.sort(); assert_eq!(ids, vec![NodeId(11), NodeId(10010)], "Should only contain identity and values"); diff --git a/node-graph/interpreted-executor/src/lib.rs b/node-graph/interpreted-executor/src/lib.rs index be3c3a7d6a..a0683431ba 100644 --- a/node-graph/interpreted-executor/src/lib.rs +++ b/node-graph/interpreted-executor/src/lib.rs @@ -14,7 +14,7 @@ mod tests { use graph_craft::*; let network = NodeNetwork { - exports: vec![NodeInput::node(NodeId(1), 0)], + exports: vec![NodeInput::node(NodeId(1), NodeInput::PRIMARY_OUTPUT_INDEX)], nodes: [ // Simple identity node taking a number as input from outside the graph ( @@ -30,7 +30,7 @@ mod tests { ( NodeId(1), DocumentNode { - inputs: vec![NodeInput::node(NodeId(0), 0), NodeInput::node(NodeId(0), 0)], + inputs: vec![NodeInput::node(NodeId(0), NodeInput::PRIMARY_OUTPUT_INDEX), NodeInput::node(NodeId(0), NodeInput::PRIMARY_OUTPUT_INDEX)], implementation: DocumentNodeImplementation::ProtoNode(graphene_std::math_nodes::add::IDENTIFIER), ..Default::default() }, diff --git a/node-graph/interpreted-executor/src/util.rs b/node-graph/interpreted-executor/src/util.rs index 8ecf5bf18e..20302379e3 100644 --- a/node-graph/interpreted-executor/src/util.rs +++ b/node-graph/interpreted-executor/src/util.rs @@ -22,13 +22,13 @@ pub fn wrap_network_in_scope(mut network: NodeNetwork, editor_api: Arc")), - inputs: vec![NodeInput::node(NodeId(2), 0)], + inputs: vec![NodeInput::node(NodeId(2), NodeInput::PRIMARY_OUTPUT_INDEX)], ..Default::default() }); scope_injections.push(("wgpu-executor".to_string(), (NodeId(3), concrete!(&WgpuExecutor)))); } NodeNetwork { - exports: vec![NodeInput::node(NodeId(1), 0)], + exports: vec![NodeInput::node(NodeId(1), NodeInput::PRIMARY_OUTPUT_INDEX)], nodes: nodes.into_iter().enumerate().map(|(id, node)| (NodeId(id as u64), node)).collect(), scope_injections: scope_injections.into_iter().collect(), // TODO(TrueDoctor): check if it makes sense to set `generated` to `true` diff --git a/node-graph/preprocessor/src/lib.rs b/node-graph/preprocessor/src/lib.rs index 0f9bf398e4..7db2a23acd 100644 --- a/node-graph/preprocessor/src/lib.rs +++ b/node-graph/preprocessor/src/lib.rs @@ -52,7 +52,7 @@ pub fn generate_node_substitutions() -> HashMap = node_inputs(fields, first_node_io); let input_count = inputs.len(); - let network_inputs = (0..input_count).map(|i| NodeInput::node(NodeId(i as u64), 0)).collect(); + let network_inputs = (0..input_count).map(|i| NodeInput::node(NodeId(i as u64), NodeInput::PRIMARY_OUTPUT_INDEX)).collect(); let identity_node = ops::identity::IDENTIFIER; @@ -125,7 +125,7 @@ pub fn generate_node_substitutions() -> HashMap Date: Thu, 5 Mar 2026 15:46:35 +0800 Subject: [PATCH 5/7] fix: revert unrelated float constant changes --- .../no-std-types/src/color/discrete_srgb.rs | 102 ++++++------------ 1 file changed, 33 insertions(+), 69 deletions(-) diff --git a/node-graph/libraries/no-std-types/src/color/discrete_srgb.rs b/node-graph/libraries/no-std-types/src/color/discrete_srgb.rs index 1a31683c6a..13a06e30ab 100644 --- a/node-graph/libraries/no-std-types/src/color/discrete_srgb.rs +++ b/node-graph/libraries/no-std-types/src/color/discrete_srgb.rs @@ -90,70 +90,38 @@ pub fn float_to_srgb_u8(mut f: f32) -> u8 { #[rustfmt::skip] const FROM_SRGB_U8: [f32; 256] = [ - f32::from_bits(0x00000000), f32::from_bits(0x399f22b4), f32::from_bits(0x3a1f22b4), f32::from_bits(0x3a6eb40f), - f32::from_bits(0x3a9f22b4), f32::from_bits(0x3ac6eb61), f32::from_bits(0x3aeeb40f), f32::from_bits(0x3b0b3e5e), - f32::from_bits(0x3b1f22b4), f32::from_bits(0x3b33070b), f32::from_bits(0x3b46eb61), f32::from_bits(0x3b5b518d), - f32::from_bits(0x3b70f18d), f32::from_bits(0x3b83e1c6), f32::from_bits(0x3b8fe616), f32::from_bits(0x3b9c87fd), - f32::from_bits(0x3ba9c9b7), f32::from_bits(0x3bb7ad6f), f32::from_bits(0x3bc63549), f32::from_bits(0x3bd56361), - f32::from_bits(0x3be539c1), f32::from_bits(0x3bf5ba70), f32::from_bits(0x3c0373b5), f32::from_bits(0x3c0c6152), - f32::from_bits(0x3c15a703), f32::from_bits(0x3c1f45be), f32::from_bits(0x3c293e6b), f32::from_bits(0x3c3391f7), - f32::from_bits(0x3c3e4149), f32::from_bits(0x3c494d43), f32::from_bits(0x3c54b6c7), f32::from_bits(0x3c607eb1), - f32::from_bits(0x3c6ca5df), f32::from_bits(0x3c792d22), f32::from_bits(0x3c830aa8), f32::from_bits(0x3c89af9f), - f32::from_bits(0x3c9085db), f32::from_bits(0x3c978dc5), f32::from_bits(0x3c9ec7c2), f32::from_bits(0x3ca63433), - f32::from_bits(0x3cadd37d), f32::from_bits(0x3cb5a601), f32::from_bits(0x3cbdac20), f32::from_bits(0x3cc5e639), - f32::from_bits(0x3cce54ab), f32::from_bits(0x3cd6f7d5), f32::from_bits(0x3cdfd010), f32::from_bits(0x3ce8ddb9), - f32::from_bits(0x3cf22131), f32::from_bits(0x3cfb9ac6), f32::from_bits(0x3d02a56c), f32::from_bits(0x3d0798df), - f32::from_bits(0x3d0ca7e7), f32::from_bits(0x3d11d2b2), f32::from_bits(0x3d171965), f32::from_bits(0x3d1c7c31), - f32::from_bits(0x3d21fb3f), f32::from_bits(0x3d2796b5), f32::from_bits(0x3d2d4ebe), f32::from_bits(0x3d332384), - f32::from_bits(0x3d39152e), f32::from_bits(0x3d3f23e6), f32::from_bits(0x3d454fd4), f32::from_bits(0x3d4b991f), - f32::from_bits(0x3d51ffef), f32::from_bits(0x3d58846a), f32::from_bits(0x3d5f26b7), f32::from_bits(0x3d65e6fe), - f32::from_bits(0x3d6cc564), f32::from_bits(0x3d73c20f), f32::from_bits(0x3d7add29), f32::from_bits(0x3d810b68), - f32::from_bits(0x3d84b795), f32::from_bits(0x3d887330), f32::from_bits(0x3d8c3e4a), f32::from_bits(0x3d9018f6), - f32::from_bits(0x3d940345), f32::from_bits(0x3d97fd4a), f32::from_bits(0x3d9c0716), f32::from_bits(0x3da020bb), - f32::from_bits(0x3da44a4b), f32::from_bits(0x3da883d7), f32::from_bits(0x3daccd70), f32::from_bits(0x3db12728), f32::from_bits(0x3db59112), - f32::from_bits(0x3dba0b3b), f32::from_bits(0x3dbe95b5), f32::from_bits(0x3dc33092), f32::from_bits(0x3dc7dbe2), - f32::from_bits(0x3dcc97b6), f32::from_bits(0x3dd1641f), f32::from_bits(0x3dd6412c), f32::from_bits(0x3ddb2eef), - f32::from_bits(0x3de02d77), f32::from_bits(0x3de53cd5), f32::from_bits(0x3dea5d19), f32::from_bits(0x3def8e55), - f32::from_bits(0x3df4d093), f32::from_bits(0x3dfa23ea), f32::from_bits(0x3dff8864), f32::from_bits(0x3e027f09), - f32::from_bits(0x3e054282), f32::from_bits(0x3e080ea5), f32::from_bits(0x3e0ae379), f32::from_bits(0x3e0dc107), - f32::from_bits(0x3e10a755), f32::from_bits(0x3e13966c), f32::from_bits(0x3e168e53), f32::from_bits(0x3e198f11), - f32::from_bits(0x3e1c98ae), f32::from_bits(0x3e1fab32), f32::from_bits(0x3e22c6a3), f32::from_bits(0x3e25eb0b), - f32::from_bits(0x3e29186d), f32::from_bits(0x3e2c4ed4), f32::from_bits(0x3e2f8e45), f32::from_bits(0x3e32d6c8), - f32::from_bits(0x3e362865), f32::from_bits(0x3e398322), f32::from_bits(0x3e3ce706), f32::from_bits(0x3e405419), - f32::from_bits(0x3e43ca62), f32::from_bits(0x3e4749e8), f32::from_bits(0x3e4ad2b1), f32::from_bits(0x3e4e64c6), - f32::from_bits(0x3e52002b), f32::from_bits(0x3e55a4e9), f32::from_bits(0x3e595307), f32::from_bits(0x3e5d0a8b), - f32::from_bits(0x3e60cb7c), f32::from_bits(0x3e6495e0), f32::from_bits(0x3e6869bf), f32::from_bits(0x3e6c4720), - f32::from_bits(0x3e702e0c), f32::from_bits(0x3e741e84), f32::from_bits(0x3e781890), f32::from_bits(0x3e7c1c38), - f32::from_bits(0x3e8014c2), f32::from_bits(0x3e82203c), f32::from_bits(0x3e84308d), f32::from_bits(0x3e8645ba), - f32::from_bits(0x3e885fc5), f32::from_bits(0x3e8a7eb2), f32::from_bits(0x3e8ca283), f32::from_bits(0x3e8ecb3d), - f32::from_bits(0x3e90f8e1), f32::from_bits(0x3e932b74), f32::from_bits(0x3e9562f8), f32::from_bits(0x3e979f71), - f32::from_bits(0x3e99e0e2), f32::from_bits(0x3e9c274e), f32::from_bits(0x3e9e72b7), f32::from_bits(0x3ea0c322), - f32::from_bits(0x3ea31892), f32::from_bits(0x3ea57308), f32::from_bits(0x3ea7d289), f32::from_bits(0x3eaa3718), - f32::from_bits(0x3eaca0b7), f32::from_bits(0x3eaf0f69), f32::from_bits(0x3eb18333), f32::from_bits(0x3eb3fc18), - f32::from_bits(0x3eb67a18), f32::from_bits(0x3eb8fd37), f32::from_bits(0x3ebb8579), f32::from_bits(0x3ebe12e1), - f32::from_bits(0x3ec0a571), f32::from_bits(0x3ec33d2d), f32::from_bits(0x3ec5da17), f32::from_bits(0x3ec87c33), - f32::from_bits(0x3ecb2383), f32::from_bits(0x3ecdd00b), f32::from_bits(0x3ed081cd), f32::from_bits(0x3ed338cc), - f32::from_bits(0x3ed5f50b), f32::from_bits(0x3ed8b68d), f32::from_bits(0x3edb7d54), f32::from_bits(0x3ede4965), - f32::from_bits(0x3ee11ac1), f32::from_bits(0x3ee3f16b), f32::from_bits(0x3ee6cd67), f32::from_bits(0x3ee9aeb7), - f32::from_bits(0x3eec955d), f32::from_bits(0x3eef815d), f32::from_bits(0x3ef272ba), f32::from_bits(0x3ef56976), - f32::from_bits(0x3ef86594), f32::from_bits(0x3efb6717), f32::from_bits(0x3efe6e02), f32::from_bits(0x3f00bd2d), - f32::from_bits(0x3f02460e), f32::from_bits(0x3f03d1a7), f32::from_bits(0x3f055ff9), f32::from_bits(0x3f06f108), - f32::from_bits(0x3f0884d1), f32::from_bits(0x3f0a1b57), f32::from_bits(0x3f0bb49d), f32::from_bits(0x3f0d50a2), - f32::from_bits(0x3f0eef69), f32::from_bits(0x3f1090f2), f32::from_bits(0x3f123540), f32::from_bits(0x3f13dc53), - f32::from_bits(0x3f15862d), f32::from_bits(0x3f1732cf), f32::from_bits(0x3f18e23b), f32::from_bits(0x3f1a9471), - f32::from_bits(0x3f1c4973), f32::from_bits(0x3f1e0143), f32::from_bits(0x3f1fbbe1), f32::from_bits(0x3f217950), - f32::from_bits(0x3f23398f), f32::from_bits(0x3f24fca2), f32::from_bits(0x3f26c288), f32::from_bits(0x3f288b43), - f32::from_bits(0x3f2a56d5), f32::from_bits(0x3f2c253f), f32::from_bits(0x3f2df681), f32::from_bits(0x3f2fca9e), - f32::from_bits(0x3f31a199), f32::from_bits(0x3f337b6e), f32::from_bits(0x3f355822), f32::from_bits(0x3f3737b5), - f32::from_bits(0x3f391a28), f32::from_bits(0x3f3aff7e), f32::from_bits(0x3f3ce7b7), f32::from_bits(0x3f3ed2d4), f32::from_bits(0x3f40c0d6), - f32::from_bits(0x3f42b1c0), f32::from_bits(0x3f44a592), f32::from_bits(0x3f469c4d), f32::from_bits(0x3f4895f3), - f32::from_bits(0x3f4a9284), f32::from_bits(0x3f4c9203), f32::from_bits(0x3f4e9470), f32::from_bits(0x3f5099cd), - f32::from_bits(0x3f52a21a), f32::from_bits(0x3f54ad59), f32::from_bits(0x3f56bb8c), f32::from_bits(0x3f58ccb3), - f32::from_bits(0x3f5ae0cf), f32::from_bits(0x3f5cf7e2), f32::from_bits(0x3f5f11ee), f32::from_bits(0x3f612ef2), f32::from_bits(0x3f634eef), - f32::from_bits(0x3f6571ec), f32::from_bits(0x3f6797e3), f32::from_bits(0x3f69c0db), f32::from_bits(0x3f6beccd), - f32::from_bits(0x3f6e1bc4), f32::from_bits(0x3f704db8), f32::from_bits(0x3f7282b4), f32::from_bits(0x3f74baae), - f32::from_bits(0x3f76f5b3), f32::from_bits(0x3f7933b9), f32::from_bits(0x3f7b74cb), f32::from_bits(0x3f7db8e0), - f32::from_bits(0x3f800000), + 0., 0.000303527, 0.000607054, 0.00091058103, 0.001214108, 0.001517635, 0.0018211621, 0.002124689, + 0.002428216, 0.002731743, 0.00303527, 0.0033465356, 0.003676507, 0.004024717, 0.004391442, + 0.0047769533, 0.005181517, 0.0056053917, 0.0060488326, 0.006512091, 0.00699541, 0.0074990317, + 0.008023192, 0.008568125, 0.009134057, 0.009721218, 0.010329823, 0.010960094, 0.011612245, + 0.012286487, 0.012983031, 0.013702081, 0.014443844, 0.015208514, 0.015996292, 0.016807375, + 0.017641952, 0.018500218, 0.019382361, 0.020288562, 0.02121901, 0.022173883, 0.023153365, + 0.02415763, 0.025186857, 0.026241222, 0.027320892, 0.028426038, 0.029556843, 0.03071345, 0.03189604, + 0.033104774, 0.03433981, 0.035601325, 0.036889452, 0.038204376, 0.039546248, 0.04091521, 0.042311423, + 0.043735042, 0.045186214, 0.046665095, 0.048171833, 0.049706575, 0.051269468, 0.052860655, 0.05448028, + 0.056128494, 0.057805434, 0.05951124, 0.06124607, 0.06301003, 0.06480328, 0.06662595, 0.06847818, + 0.07036011, 0.07227186, 0.07421358, 0.07618539, 0.07818743, 0.08021983, 0.082282715, 0.084376216, + 0.086500466, 0.088655606, 0.09084173, 0.09305898, 0.095307484, 0.09758736, 0.09989874, 0.10224175, + 0.10461649, 0.10702311, 0.10946172, 0.111932434, 0.11443538, 0.116970696, 0.11953845, 0.12213881, + 0.12477186, 0.12743773, 0.13013652, 0.13286836, 0.13563336, 0.13843165, 0.14126332, 0.1441285, + 0.1470273, 0.14995982, 0.15292618, 0.1559265, 0.15896086, 0.16202943, 0.16513224, 0.16826946, + 0.17144115, 0.17464745, 0.17788847, 0.1811643, 0.18447503, 0.1878208, 0.19120172, 0.19461787, + 0.19806935, 0.2015563, 0.20507877, 0.2086369, 0.21223079, 0.21586053, 0.21952623, 0.22322798, + 0.22696589, 0.23074007, 0.23455065, 0.23839766, 0.2422812, 0.2462014, 0.25015837, 0.25415218, + 0.2581829, 0.26225072, 0.26635566, 0.27049786, 0.27467737, 0.27889434, 0.2831488, 0.2874409, + 0.2917707, 0.29613832, 0.30054384, 0.30498737, 0.30946895, 0.31398875, 0.31854683, 0.32314324, + 0.32777813, 0.33245158, 0.33716366, 0.34191445, 0.3467041, 0.3515327, 0.35640025, 0.36130688, + 0.3662527, 0.37123778, 0.37626222, 0.3813261, 0.38642952, 0.39157256, 0.3967553, 0.40197787, + 0.4072403, 0.4125427, 0.41788515, 0.42326775, 0.42869055, 0.4341537, 0.43965724, 0.44520125, + 0.45078585, 0.45641106, 0.46207705, 0.46778384, 0.47353154, 0.47932023, 0.48514998, 0.4910209, + 0.49693304, 0.5028866, 0.50888145, 0.5149178, 0.5209957, 0.52711535, 0.5332766, 0.5394797, + 0.5457247, 0.5520116, 0.5583406, 0.5647117, 0.57112503, 0.57758063, 0.5840786, 0.590619, 0.597202, + 0.60382754, 0.61049575, 0.61720675, 0.62396055, 0.63075733, 0.637597, 0.6444799, 0.6514058, + 0.65837497, 0.66538745, 0.67244333, 0.6795426, 0.68668544, 0.69387203, 0.70110214, 0.70837605, + 0.7156938, 0.72305536, 0.730461, 0.7379107, 0.7454045, 0.75294244, 0.76052475, 0.7681514, 0.77582246, + 0.78353804, 0.79129815, 0.79910296, 0.8069525, 0.8148468, 0.822786, 0.8307701, 0.83879924, 0.84687346, + 0.8549928, 0.8631574, 0.87136734, 0.8796226, 0.8879232, 0.89626956, 0.90466136, 0.913099, 0.92158204, + 0.93011117, 0.9386859, 0.9473069, 0.9559735, 0.9646866, 0.9734455, 0.98225087, 0.9911022, 1., ]; #[inline] @@ -194,11 +162,7 @@ mod tests { #[test] fn test_float_to_srgb_u8() { for u in 0..=u8::MAX { - let a = srgb_u8_to_float(u); - let b = srgb_u8_to_float_ref(u); - if a != b { - panic!("Mismatch at u={}: {} != {}", u, a, b); - } + assert!(srgb_u8_to_float(u) == srgb_u8_to_float_ref(u)); } } From f842072ba6c4109c62a62907e15558b4ed8ee2c4 Mon Sep 17 00:00:00 2001 From: Tyooughtul Date: Mon, 9 Mar 2026 11:05:50 +0800 Subject: [PATCH 6/7] fix: add more replacements for magic number indexes - Replace literal 0 with InputConnector::PRIMARY_INPUT_INDEX / OutputConnector::PRIMARY_OUTPUT_INDEX - Add module-level constants for node input indices (e.g. LAYER_SECONDARY_INPUT_INDEX=1, FILL_NODE_BACKUP_COLOR_INPUT_INDEX=2, ARTBOARD_LOCATION_INDEX=2, etc. - Use proto-node generated constants SidesInput, RadiusInput instead of magic numbers - Fix InputConnector::Export() to use PRIMARY_INPUT_INDEX instead of hardcoded 0 --- .../document/document_message_handler.rs | 9 +- .../graph_operation_message_handler.rs | 16 ++-- .../graph_operation/transform_utils.rs | 4 +- .../document/graph_operation/utility_types.rs | 28 +++--- .../node_graph/node_graph_message_handler.rs | 34 +++---- .../utility_types/network_interface.rs | 88 +++++++++---------- .../portfolio/portfolio_message_handler.rs | 4 +- .../shape_gizmos/number_of_points_dial.rs | 10 ++- .../shape_gizmos/point_radius_handle.rs | 21 +++-- .../graph_modification_utils.rs | 19 ++-- .../common_functionality/shapes/line_shape.rs | 2 + .../shapes/polygon_shape.rs | 35 +++++--- .../shapes/shape_utility.rs | 6 +- .../common_functionality/utility_functions.rs | 5 +- .../messages/tool/tool_messages/brush_tool.rs | 2 +- 15 files changed, 154 insertions(+), 129 deletions(-) diff --git a/editor/src/messages/portfolio/document/document_message_handler.rs b/editor/src/messages/portfolio/document/document_message_handler.rs index 092eab3fbf..f2960cd16d 100644 --- a/editor/src/messages/portfolio/document/document_message_handler.rs +++ b/editor/src/messages/portfolio/document/document_message_handler.rs @@ -1371,7 +1371,7 @@ impl MessageHandler> for DocumentMes // Connect the current output data to the artboard's input data, and the artboard's output to the document output responses.add(NodeGraphMessage::InsertNodeBetween { node_id, - input_connector: network_interface::InputConnector::Export(0), + input_connector: network_interface::InputConnector::Export(network_interface::InputConnector::PRIMARY_INPUT_INDEX), insert_node_input_index: 1, }); @@ -1896,10 +1896,10 @@ impl DocumentMessageHandler { }); // If there's already a boolean operation on the selected layer, update it with the new operation + const BOOLEAN_OPERATION_INPUT_INDEX: usize = 1; if let (Some(upstream_boolean_op), Some(only_selected_layer)) = (upstream_boolean_op, only_selected_layer) { - const BOOLEAN_OPERATION_INDEX: usize = 1; network_interface.set_input( - &InputConnector::node(upstream_boolean_op, BOOLEAN_OPERATION_INDEX), + &InputConnector::node(upstream_boolean_op, BOOLEAN_OPERATION_INPUT_INDEX), NodeInput::value(TaggedValue::BooleanOperation(operation), false), &[], ); @@ -2790,9 +2790,8 @@ impl DocumentMessageHandler { .popover_layout({ // Showing only compatible types for the layer based on the output type of the node upstream from its horizontal input let compatible_type = selected_layer.and_then(|layer| { - const LAYER_SECONDARY_INPUT_INDEX: usize = 1; self.network_interface - .upstream_output_connector(&InputConnector::node(layer.to_node(), LAYER_SECONDARY_INPUT_INDEX), &[]) + .upstream_output_connector(&InputConnector::node(layer.to_node(), InputConnector::PRIMARY_INPUT_INDEX + 1), &[]) .and_then(|upstream_output| self.network_interface.output_type(&upstream_output, &[]).add_node_string()) }); diff --git a/editor/src/messages/portfolio/document/graph_operation/graph_operation_message_handler.rs b/editor/src/messages/portfolio/document/graph_operation/graph_operation_message_handler.rs index 726d58ee4d..37e3d687f4 100644 --- a/editor/src/messages/portfolio/document/graph_operation/graph_operation_message_handler.rs +++ b/editor/src/messages/portfolio/document/graph_operation/graph_operation_message_handler.rs @@ -16,6 +16,11 @@ use graphene_std::table::Table; use graphene_std::text::{Font, TypesettingConfig}; use graphene_std::vector::style::{Fill, Gradient, GradientStop, GradientStops, GradientType, PaintOrder, Stroke, StrokeAlign, StrokeCap, StrokeJoin}; +const ARTBOARD_BASE_INDEX: usize = 0; +const ARTBOARD_CONTENT_INDEX: usize = 1; +const LAYER_SECONDARY_INPUT_INDEX: usize = 1; +const MERGE_CONTENT_INPUT_INDEX: usize = 1; + #[derive(ExtractField)] pub struct GraphOperationMessageContext<'a> { pub network_interface: &'a mut NodeNetworkInterface, @@ -101,7 +106,6 @@ impl MessageHandler> for } } GraphOperationMessage::SetUpstreamToChain { layer } => { - const LAYER_SECONDARY_INPUT_INDEX: usize = 1; let Some(OutputConnector::Node { node_id: first_chain_node, .. }) = network_interface.upstream_output_connector(&InputConnector::node(layer.to_node(), LAYER_SECONDARY_INPUT_INDEX), &[]) else { return; }; @@ -146,12 +150,9 @@ impl MessageHandler> for // Set the bottom input of the artboard back to artboard let bottom_input = NodeInput::value(TaggedValue::Artboard(Table::new()), true); - const ARTBOARD_BASE_INDEX: usize = 0; network_interface.set_input(&InputConnector::node(artboard_layer.to_node(), ARTBOARD_BASE_INDEX), bottom_input, &[]); } else { // We have some non layers (e.g. just a rectangle node). We disconnect the bottom input and connect it to the left input. - const ARTBOARD_BASE_INDEX: usize = 0; - const ARTBOARD_CONTENT_INDEX: usize = 1; network_interface.disconnect_input(&InputConnector::node(artboard_layer.to_node(), ARTBOARD_BASE_INDEX), &[]); network_interface.set_input(&InputConnector::node(artboard_layer.to_node(), ARTBOARD_CONTENT_INDEX), primary_input, &[]); @@ -197,7 +198,6 @@ impl MessageHandler> for let first_new_node_id = new_ids[&NodeId(0)]; responses.add(NodeGraphMessage::AddNodes { nodes, new_ids }); - const LAYER_SECONDARY_INPUT_INDEX: usize = 1; responses.add(NodeGraphMessage::SetInput { input_connector: InputConnector::node(layer.to_node(), LAYER_SECONDARY_INPUT_INDEX), input: NodeInput::node(first_new_node_id, NodeInput::PRIMARY_OUTPUT_INDEX), @@ -256,7 +256,6 @@ impl MessageHandler> for return; }; - const ARTBOARD_CONTENT_INDEX: usize = 1; artboard_data.insert( artboard.to_node(), ArtboardInfo { @@ -287,9 +286,8 @@ impl MessageHandler> for // Go through all artboards and connect them to the merge nodes for artboard in &artboard_data { // Modify downstream connections - const MERGE_CONTENT_INDEX: usize = 1; - responses.add(NodeGraphMessage::SetInput { - input_connector: InputConnector::node(artboard.1.merge_node, MERGE_CONTENT_INDEX), + responses.add(NodeGraphMessage::SetInput { + input_connector: InputConnector::node(artboard.1.merge_node, MERGE_CONTENT_INPUT_INDEX), input: NodeInput::node(artboard.1.input_node.as_node().unwrap_or_default(), NodeInput::PRIMARY_OUTPUT_INDEX), }); diff --git a/editor/src/messages/portfolio/document/graph_operation/transform_utils.rs b/editor/src/messages/portfolio/document/graph_operation/transform_utils.rs index 0db30b675f..ebf21a75e2 100644 --- a/editor/src/messages/portfolio/document/graph_operation/transform_utils.rs +++ b/editor/src/messages/portfolio/document/graph_operation/transform_utils.rs @@ -103,10 +103,10 @@ pub fn get_current_transform(inputs: &[NodeInput]) -> DAffine2 { DAffine2::from_scale_angle_translation(scale, rotation, translation) * DAffine2::from_cols_array(&[1., shear.y, shear.x, 1., 0., 0.]) } +const ORIGIN_OFFSET_INDEX: usize = 5; + /// Extract the current normalized pivot from the layer pub fn get_current_normalized_pivot(inputs: &[NodeInput]) -> DVec2 { - const ORIGIN_OFFSET_INDEX: usize = 5; - if let Some(&TaggedValue::DVec2(pivot)) = inputs[ORIGIN_OFFSET_INDEX].as_value() { pivot } else { 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 4cf4c70830..d6b02e98c4 100644 --- a/editor/src/messages/portfolio/document/graph_operation/utility_types.rs +++ b/editor/src/messages/portfolio/document/graph_operation/utility_types.rs @@ -35,6 +35,14 @@ pub struct ModifyInputsContext<'a> { pub layer_node: Option, } +const LAYER_SECONDARY_INPUT_INDEX: usize = 1; +const BRUSH_STROKES_INDEX: usize = 1; +const ARTBOARD_LOCATION_INDEX: usize = 2; +const ARTBOARD_DIMENSIONS_INDEX: usize = 3; +const FILL_NODE_FILL_INPUT_INDEX: usize = 1; +const FILL_NODE_BACKUP_COLOR_INPUT_INDEX: usize = 2; +const FILL_NODE_BACKUP_GRADIENT_INPUT_INDEX: usize = 3; + impl<'a> ModifyInputsContext<'a> { /// Get the node network from the document pub fn new(network_interface: &'a mut NodeNetworkInterface, responses: &'a mut VecDeque) -> Self { @@ -69,9 +77,8 @@ impl<'a> ModifyInputsContext<'a> { /// if insert_index == 3, return (Layer3, None) pub fn get_post_node_with_index(network_interface: &NodeNetworkInterface, parent: LayerNodeIdentifier, insert_index: usize) -> InputConnector { let mut post_node_input_connector = if parent == LayerNodeIdentifier::ROOT_PARENT { - InputConnector::Export(0) + InputConnector::Export(InputConnector::PRIMARY_INPUT_INDEX) } else { - const LAYER_SECONDARY_INPUT_INDEX: usize = 1; InputConnector::node(parent.to_node(), LAYER_SECONDARY_INPUT_INDEX) }; // Skip layers based on skip_layer_nodes, which inserts the new layer at a certain index of the layer stack. @@ -321,7 +328,6 @@ impl<'a> ModifyInputsContext<'a> { // If inserting a 'Path' node, insert a 'Flatten Path' node if the type is `Graphic`. // TODO: Allow the 'Path' node to operate on table data by utilizing the reference (index or ID?) for each row. if node_definition.identifier == "Path" { - const LAYER_SECONDARY_INPUT_INDEX: usize = 1; let layer_input_type = self.network_interface.input_type(&InputConnector::node(output_layer.to_node(), LAYER_SECONDARY_INPUT_INDEX), &[]); if layer_input_type.compiled_nested_type() == Some(&concrete!(Table)) { let Some(flatten_path_definition) = resolve_proto_node_type(graphene_std::vector_nodes::flatten_path::IDENTIFIER) else { @@ -340,28 +346,24 @@ impl<'a> ModifyInputsContext<'a> { } pub fn fill_set(&mut self, fill: Fill) { - let fill_index = 1; - let backup_color_index = 2; - let backup_gradient_index = 3; - let Some(fill_node_id) = self.existing_proto_node_id(graphene_std::vector_nodes::fill::IDENTIFIER, true) else { return; }; match &fill { Fill::None => { - let input_connector = InputConnector::node(fill_node_id, backup_color_index); + let input_connector = InputConnector::node(fill_node_id, FILL_NODE_BACKUP_COLOR_INPUT_INDEX); self.set_input_with_refresh(input_connector, NodeInput::value(TaggedValue::Color(Table::new()), false), true); } Fill::Solid(color) => { - let input_connector = InputConnector::node(fill_node_id, backup_color_index); + let input_connector = InputConnector::node(fill_node_id, FILL_NODE_BACKUP_COLOR_INPUT_INDEX); self.set_input_with_refresh(input_connector, NodeInput::value(TaggedValue::Color(Table::new_from_element(*color)), false), true); } Fill::Gradient(gradient) => { - let input_connector = InputConnector::node(fill_node_id, backup_gradient_index); + let input_connector = InputConnector::node(fill_node_id, FILL_NODE_BACKUP_GRADIENT_INPUT_INDEX); self.set_input_with_refresh(input_connector, NodeInput::value(TaggedValue::Gradient(gradient.clone()), false), true); } } - let input_connector = InputConnector::node(fill_node_id, fill_index); + let input_connector = InputConnector::node(fill_node_id, FILL_NODE_FILL_INPUT_INDEX); self.set_input_with_refresh(input_connector, NodeInput::value(TaggedValue::Fill(fill), false), false); } @@ -507,7 +509,6 @@ impl<'a> ModifyInputsContext<'a> { let Some(brush_node_id) = self.existing_network_node_id("Brush", true) else { return; }; - const BRUSH_STROKES_INDEX: usize = 1; self.set_input_with_refresh( InputConnector::node(brush_node_id, BRUSH_STROKES_INDEX), NodeInput::value(TaggedValue::BrushStrokes(strokes), false), @@ -516,9 +517,6 @@ impl<'a> ModifyInputsContext<'a> { } pub fn resize_artboard(&mut self, location: IVec2, dimensions: IVec2) { - const ARTBOARD_LOCATION_INDEX: usize = 2; - const ARTBOARD_DIMENSIONS_INDEX: usize = 3; - let Some(artboard_node_id) = self.existing_network_node_id("Artboard", true) else { return; }; diff --git a/editor/src/messages/portfolio/document/node_graph/node_graph_message_handler.rs b/editor/src/messages/portfolio/document/node_graph/node_graph_message_handler.rs index 68a815a47b..07b60823f8 100644 --- a/editor/src/messages/portfolio/document/node_graph/node_graph_message_handler.rs +++ b/editor/src/messages/portfolio/document/node_graph/node_graph_message_handler.rs @@ -492,7 +492,7 @@ impl<'a> MessageHandler> for NodeG log::error!("Could not get outward wires in remove_import"); return; }; - let Some(downstream_connections) = outward_wires.get(&OutputConnector::Import(0)).cloned() else { + let Some(downstream_connections) = outward_wires.get(&OutputConnector::Import(OutputConnector::PRIMARY_OUTPUT_INDEX)).cloned() else { log::error!("Could not get outward wires for import in remove_import"); return; }; @@ -506,7 +506,7 @@ impl<'a> MessageHandler> for NodeG responses.add(NodeGraphMessage::SendWires); } NodeGraphMessage::ExposePrimaryExport { exposed } => { - let export_connector: InputConnector = InputConnector::Export(0); + let export_connector: InputConnector = InputConnector::Export(InputConnector::PRIMARY_INPUT_INDEX); if !exposed { network_interface.disconnect_input(&export_connector, breadcrumb_network_path); } @@ -865,7 +865,7 @@ impl<'a> MessageHandler> for NodeG if let Some(remove_import_index) = modify_import_export.remove_imports_exports.clicked_output_port_from_point(node_graph_point) { responses.add(DocumentMessage::AddTransaction); - if remove_import_index == 0 { + if remove_import_index == InputConnector::PRIMARY_INPUT_INDEX { responses.add(NodeGraphMessage::ExposeEncapsulatingPrimaryInput { exposed: false }) } else { responses.add(NodeGraphMessage::RemoveImport { import_index: remove_import_index }); @@ -873,7 +873,7 @@ impl<'a> MessageHandler> for NodeG return; } else if let Some(remove_export_index) = modify_import_export.remove_imports_exports.clicked_input_port_from_point(node_graph_point) { responses.add(DocumentMessage::AddTransaction); - if remove_export_index == 0 { + if remove_export_index == InputConnector::PRIMARY_INPUT_INDEX { responses.add(NodeGraphMessage::ExposePrimaryExport { exposed: false }) } else { responses.add(NodeGraphMessage::RemoveExport { export_index: remove_export_index }); @@ -930,7 +930,7 @@ impl<'a> MessageHandler> for NodeG self.initial_disconnecting = true; self.disconnecting = Some(*clicked_input); - let output_connector = if *clicked_input == InputConnector::Export(0) { + let output_connector = if *clicked_input == InputConnector::Export(InputConnector::PRIMARY_INPUT_INDEX) { network_interface.root_node(breadcrumb_network_path).map(|root_node| root_node.to_connector()) } else { network_interface.upstream_output_connector(clicked_input, breadcrumb_network_path) @@ -1070,7 +1070,7 @@ impl<'a> MessageHandler> for NodeG let mut disconnect_root_node = false; if let Previewing::Yes { root_node_to_restore } = network_interface.previewing(selection_network_path) && root_node_to_restore.is_some() - && *disconnecting == InputConnector::Export(0) + && *disconnecting == InputConnector::Export(InputConnector::PRIMARY_INPUT_INDEX) { disconnect_root_node = true; } @@ -1107,7 +1107,7 @@ impl<'a> MessageHandler> for NodeG }); let to_connector_is_layer = to_connector.is_some_and(|to_connector| { if let InputConnector::Node { node_id, input_index } = to_connector { - input_index == 0 && network_interface.is_layer(&node_id, selection_network_path) + input_index == InputConnector::PRIMARY_INPUT_INDEX && network_interface.is_layer(&node_id, selection_network_path) } else { false } @@ -1324,8 +1324,7 @@ impl<'a> MessageHandler> for NodeG .cloned() .collect::>() { - const LAYER_SECONDARY_INPUT_INDEX: usize = 1; - network_interface.try_set_upstream_to_chain(&InputConnector::node(layer, LAYER_SECONDARY_INPUT_INDEX), selection_network_path); + network_interface.try_set_upstream_to_chain(&InputConnector::node(layer, InputConnector::PRIMARY_INPUT_INDEX + 1), selection_network_path); } responses.add(NodeGraphMessage::SendGraph); @@ -1336,9 +1335,11 @@ impl<'a> MessageHandler> for NodeG // Check if a single node was dragged onto a wire and that the node was dragged onto the wire if selected_nodes.selected_nodes_ref().len() == 1 && !self.begin_dragging { let selected_node_id = selected_nodes.selected_nodes_ref()[0]; - let has_primary_output_connection = network_interface - .outward_wires(selection_network_path) - .is_some_and(|outward_wires| outward_wires.get(&OutputConnector::node(selected_node_id, OutputConnector::PRIMARY_OUTPUT_INDEX)).is_some_and(|outward_wires| !outward_wires.is_empty())); + let has_primary_output_connection = network_interface.outward_wires(selection_network_path).is_some_and(|outward_wires| { + outward_wires + .get(&OutputConnector::node(selected_node_id, OutputConnector::PRIMARY_OUTPUT_INDEX)) + .is_some_and(|outward_wires| !outward_wires.is_empty()) + }); if !has_primary_output_connection { let Some(network) = network_interface.nested_network(selection_network_path) else { return; @@ -1532,7 +1533,8 @@ impl<'a> MessageHandler> for NodeG } let number_of_outputs = network_interface.number_of_outputs(selected_node, selection_network_path); - let mut first_deselected_upstream_output = network_interface.upstream_output_connector(&InputConnector::node(*selected_node, InputConnector::PRIMARY_INPUT_INDEX), selection_network_path); + let mut first_deselected_upstream_output = + network_interface.upstream_output_connector(&InputConnector::node(*selected_node, InputConnector::PRIMARY_INPUT_INDEX), selection_network_path); while let Some(OutputConnector::Node { node_id, .. }) = &first_deselected_upstream_output { if !all_selected_nodes.contains(node_id) { break; @@ -2189,7 +2191,9 @@ impl NodeGraphMessageHandler { .popover_layout({ // Showing only compatible types let compatible_type = match (selection_includes_layers, has_multiple_selection, selected_layer) { - (true, false, Some(layer)) => network_interface.output_type(&OutputConnector::node(layer.to_node(), 1), &[]).add_node_string(), + (true, false, Some(layer)) => network_interface + .output_type(&OutputConnector::node(layer.to_node(), OutputConnector::PRIMARY_OUTPUT_INDEX + 1), &[]) + .add_node_string(), _ => None, }; @@ -2619,7 +2623,7 @@ impl NodeGraphMessageHandler { }; let is_export = network_interface - .input_from_connector(&InputConnector::Export(0), breadcrumb_network_path) + .input_from_connector(&InputConnector::Export(InputConnector::PRIMARY_INPUT_INDEX), breadcrumb_network_path) .is_some_and(|export| export.as_node().is_some_and(|export_node_id| node_id == export_node_id)); let is_root_node = network_interface.root_node(breadcrumb_network_path).is_some_and(|root_node| root_node.node_id == node_id); diff --git a/editor/src/messages/portfolio/document/utility_types/network_interface.rs b/editor/src/messages/portfolio/document/utility_types/network_interface.rs index ef451271b4..226502d4a1 100644 --- a/editor/src/messages/portfolio/document/utility_types/network_interface.rs +++ b/editor/src/messages/portfolio/document/utility_types/network_interface.rs @@ -417,10 +417,9 @@ impl NodeNetworkInterface { .collect::>(); for old_id in new_nodes.iter().map(|(_, old_id, _)| *old_id).collect::>() { - // Try set all selected nodes upstream of a layer to be chain nodes + // Try set all selected nodes upstream of a layer to be chain nodes if self.is_layer(&old_id, network_path) { - const LAYER_SECONDARY_INPUT_INDEX: usize = 1; - for valid_upstream_chain_node in self.valid_upstream_chain_nodes(&InputConnector::node(old_id, LAYER_SECONDARY_INPUT_INDEX), network_path) { + for valid_upstream_chain_node in self.valid_upstream_chain_nodes(&InputConnector::node(old_id, InputConnector::PRIMARY_INPUT_INDEX + 1), network_path) { if let Some(node_template) = new_nodes.iter_mut().find_map(|(_, old_id, template)| (*old_id == valid_upstream_chain_node).then_some(template)) { match &mut node_template.persistent_node_metadata.node_type_metadata { NodeTypePersistentMetadata::Node(node_metadata) => node_metadata.position = NodePosition::Chain, @@ -683,7 +682,7 @@ impl NodeNetworkInterface { let (name, description) = match output_connector { OutputConnector::Node { node_id, output_index } => { // Do not display the primary output port for a node if it is a network node with a hidden primary export - if *output_index == 0 && self.hidden_primary_output(node_id, network_path) { + if *output_index == OutputConnector::PRIMARY_OUTPUT_INDEX && self.hidden_primary_output(node_id, network_path) { return None; }; // Get the output name from the interior network export name @@ -700,7 +699,7 @@ impl NodeNetworkInterface { return None; }; // Return None if the primary input is hidden and this is the primary import - if *import_index == 0 && self.hidden_primary_import(network_path) { + if *import_index == InputConnector::PRIMARY_INPUT_INDEX && self.hidden_primary_import(network_path) { return None; }; let (import_name, description) = self.displayed_input_name_and_description(encapsulating_node_id, *import_index, encapsulating_path); @@ -840,7 +839,7 @@ impl NodeNetworkInterface { input_index, } => { // Stop iterating once the downstream node is the left input to the chain or a sole dependent - if !(sole_dependents.contains(downstream_node_id) || downstream_node_id == node_id && *input_index == 1) { + if !(sole_dependents.contains(downstream_node_id) || downstream_node_id == node_id && *input_index == InputConnector::PRIMARY_INPUT_INDEX + 1) { // Continue iterating downstream for the downstream node let number_of_outputs = self.number_of_outputs(downstream_node_id, network_path); let Some(outward_wires) = self.outward_wires(network_path) else { @@ -1073,7 +1072,7 @@ impl NodeNetworkInterface { let downstream_nodes = downstream_connectors .iter() - .filter_map(|connector| connector.node_id().filter(|_| connector.input_index() == 0)) + .filter_map(|connector| connector.node_id().filter(|_| connector.input_index() == InputConnector::PRIMARY_INPUT_INDEX)) .collect::>(); downstream_nodes.iter().any(|node_id| self.is_layer(node_id, network_path)) } @@ -1196,8 +1195,9 @@ impl NodeNetworkInterface { .find(|ancestor| *ancestor != LayerNodeIdentifier::ROOT_PARENT && self.is_artboard(&ancestor.to_node(), &[])) { let artboard = self.document_node(&artboard_node_identifier.to_node(), &[]); - const ARTBOARD_CLIP_INDEX: usize = 5; - let clip_input = artboard.unwrap().inputs.get(ARTBOARD_CLIP_INDEX).unwrap(); + // Artboard node: [0]=base, [1]=content, [2]=location, [3]=dimensions, [4]=background, [5]=clip + const ARTBOARD_CLIP_INPUT_INDEX: usize = 5; + let clip_input = artboard.unwrap().inputs.get(ARTBOARD_CLIP_INPUT_INDEX).unwrap(); if let NodeInput::Value { tagged_value, .. } = clip_input && tagged_value.clone().deref() == &TaggedValue::Bool(true) { @@ -1314,8 +1314,7 @@ impl NodeNetworkInterface { .iter() .filter_map(move |node_id| { if self.is_layer(node_id, network_path) { - const LAYER_SECONDARY_INPUT_INDEX: usize = 1; - network.nodes.get(node_id).and_then(|node| node.inputs.get(LAYER_SECONDARY_INPUT_INDEX)).and_then(|input| input.as_node()) + network.nodes.get(node_id).and_then(|node| node.inputs.get(InputConnector::PRIMARY_INPUT_INDEX + 1)).and_then(|input| input.as_node()) } else { Some(*node_id) } @@ -1868,7 +1867,7 @@ impl NodeNetworkInterface { }; let reorder_import_center = (import_bounding_box[0] + import_bounding_box[1]) / 2. + DVec2::new(-12., 0.); - if *import_index == 0 { + if *import_index == InputConnector::PRIMARY_INPUT_INDEX { let remove_import_center = reorder_import_center + DVec2::new(-4., 0.); let remove_import = ClickTarget::new_with_subpath(Subpath::new_rectangle(remove_import_center - DVec2::new(8., 8.), remove_import_center + DVec2::new(8., 8.)), 0.); remove_imports_exports.insert_custom_output_port(*import_index, remove_import); @@ -1888,7 +1887,7 @@ impl NodeNetworkInterface { }; let reorder_export_center = (export_bounding_box[0] + export_bounding_box[1]) / 2. + DVec2::new(12., 0.); - if *export_index == 0 { + if *export_index == InputConnector::PRIMARY_INPUT_INDEX { let remove_export_center = reorder_export_center + DVec2::new(4., 0.); let remove_export = ClickTarget::new_with_subpath(Subpath::new_rectangle(remove_export_center - DVec2::new(8., 8.), remove_export_center + DVec2::new(8., 8.)), 0.); remove_imports_exports.insert_custom_input_port(*export_index, remove_export); @@ -2238,7 +2237,7 @@ impl NodeNetworkInterface { let dashed = match self.previewing(network_path) { Previewing::Yes { .. } => match input { InputConnector::Node { .. } => false, - InputConnector::Export(export_index) => *export_index == 0, + InputConnector::Export(export_index) => *export_index == InputConnector::PRIMARY_INPUT_INDEX, }, Previewing::No => false, }; @@ -2364,7 +2363,7 @@ impl NodeNetworkInterface { /// When previewing, there may be a second path to the root node. pub fn wire_to_root(&mut self, graph_wire_style: GraphWireStyle, network_path: &[NodeId]) -> Option { - let input = InputConnector::Export(0); + let input = InputConnector::Export(InputConnector::PRIMARY_INPUT_INDEX); let current_export = self.upstream_output_connector(&input, network_path)?; let root_node = match self.previewing(network_path) { @@ -2384,7 +2383,7 @@ impl NodeNetworkInterface { log::error!("Could not get output position for wire start in root node: {upstream_output:?}"); return None; }; - let vertical_end = input.node_id().is_some_and(|node_id| self.is_layer(&node_id, network_path) && input.input_index() == 0); + let vertical_end = input.node_id().is_some_and(|node_id| self.is_layer(&node_id, network_path) && input.input_index() == InputConnector::PRIMARY_INPUT_INDEX); let vertical_start: bool = upstream_output.node_id().is_some_and(|node_id| self.is_layer(&node_id, network_path)); let thick = vertical_end && vertical_start; let vector_wire = build_vector_wire(output_position, input_position, vertical_start, vertical_end, graph_wire_style); @@ -2419,7 +2418,7 @@ impl NodeNetworkInterface { log::error!("Could not get output port for wire start: {:?}", upstream_output); return None; }; - let vertical_end = input.node_id().is_some_and(|node_id| self.is_layer(&node_id, network_path) && input.input_index() == 0); + let vertical_end = input.node_id().is_some_and(|node_id| self.is_layer(&node_id, network_path) && input.input_index() == InputConnector::PRIMARY_INPUT_INDEX); let vertical_start = upstream_output.node_id().is_some_and(|node_id| self.is_layer(&node_id, network_path)); let thick = vertical_end && vertical_start; Some((build_vector_wire(output_position, input_position, vertical_start, vertical_end, wire_style), thick)) @@ -2488,7 +2487,7 @@ impl NodeNetworkInterface { port_click_targets.insert_node_input(input_index, input_row_count, node_top_left); } // Primary input row is always displayed, even if the input is not exposed - if input_index == 0 || input.is_exposed() { + if input_index == InputConnector::PRIMARY_INPUT_INDEX || input.is_exposed() { input_row_count += 1; } } @@ -3945,11 +3944,11 @@ impl NodeNetworkInterface { (_, NodeInput::Node { node_id: upstream_node_id, .. }) => { // Load structure if the change is to the document network and to the first or second if network_path.is_empty() { - if matches!(input_connector, InputConnector::Export(0)) { + if matches!(input_connector, InputConnector::Export(InputConnector::PRIMARY_INPUT_INDEX)) { self.load_structure(); } else if let InputConnector::Node { node_id, input_index } = &input_connector { // If the connection is made to the first or second input of a node connected to the output, then load the structure - if self.connected_to_output(node_id, network_path) && (*input_index == 0 || *input_index == 1) { + if self.connected_to_output(node_id, network_path) && (*input_index == InputConnector::PRIMARY_INPUT_INDEX || *input_index == InputConnector::PRIMARY_INPUT_INDEX + 1) { self.load_structure(); } } @@ -3987,7 +3986,7 @@ impl NodeNetworkInterface { .outward_wires(network_path) .and_then(|all_outward_wires| all_outward_wires.get(&OutputConnector::node(*upstream_node_id, OutputConnector::PRIMARY_OUTPUT_INDEX))) .is_some_and(|outward_wires| outward_wires.len() > 1); - if *input_index == 0 && !multiple_outward_wires { + if *input_index == InputConnector::PRIMARY_INPUT_INDEX && !multiple_outward_wires { self.set_stack_position_calculated_offset(upstream_node_id, downstream_node_id, network_path); } else { self.set_absolute_position(upstream_node_id, current_node_position, network_path); @@ -4032,7 +4031,7 @@ impl NodeNetworkInterface { return; }; // If it is a layer and is connected to a single layer, set its position to stack at its previous y position - if old_upstream_node_is_layer && outward_wires.len() == 1 && outward_wires[0].input_index() == 0 { + if old_upstream_node_is_layer && outward_wires.len() == 1 && outward_wires[0].input_index() == InputConnector::PRIMARY_INPUT_INDEX { if let Some(downstream_node_id) = outward_wires[0].node_id() && self.is_layer(&downstream_node_id, network_path) { @@ -4051,11 +4050,11 @@ impl NodeNetworkInterface { } // Load structure if the change is to the document network and to the first or second if network_path.is_empty() { - if matches!(input_connector, InputConnector::Export(0)) { + if matches!(input_connector, InputConnector::Export(InputConnector::PRIMARY_INPUT_INDEX)) { self.load_structure(); } else if let InputConnector::Node { node_id, input_index } = &input_connector { // If the connection is made to the first or second input of a node connected to the output, then load the structure - if self.connected_to_output(node_id, network_path) && (*input_index == 0 || *input_index == 1) { + if self.connected_to_output(node_id, network_path) && (*input_index == InputConnector::PRIMARY_INPUT_INDEX || *input_index == InputConnector::PRIMARY_INPUT_INDEX + 1) { self.load_structure(); } } @@ -4104,7 +4103,7 @@ impl NodeNetworkInterface { input_index, } = other_outward_wire && self.is_layer(&downstream_node_id, network_path) - && input_index == 0 + && input_index == InputConnector::PRIMARY_INPUT_INDEX { self.set_stack_position_calculated_offset(upstream_node_id, &downstream_node_id, network_path); } @@ -4238,11 +4237,11 @@ impl NodeNetworkInterface { if let InputConnector::Node { node_id: downstream_id, input_index } = downstream_node { // If the downstream node is not in the delete nodes set, then continue iterating // If the downstream node is the bottom input of a layer then continue iterating - if !delete_nodes.contains(downstream_id) || (*input_index == 0 && self.is_layer(downstream_id, network_path)) { + if !delete_nodes.contains(downstream_id) || (*input_index == InputConnector::PRIMARY_INPUT_INDEX && self.is_layer(downstream_id, network_path)) { stack.push(*downstream_id); } // If the traversal reaches the primary input of the node to delete then do not delete it - if node_id == downstream_id && *input_index == 0 { + if node_id == downstream_id && *input_index == InputConnector::PRIMARY_INPUT_INDEX { can_delete = false; stack = Vec::new(); break; @@ -4402,7 +4401,7 @@ impl NodeNetworkInterface { } = self.previewing(network_path) { self.set_input( - &InputConnector::Export(0), + &InputConnector::Export(InputConnector::PRIMARY_INPUT_INDEX), NodeInput::node(root_node_to_restore.node_id, root_node_to_restore.output_index), network_path, ); @@ -4461,10 +4460,11 @@ impl NodeNetworkInterface { return; }; - let label_index = 1; + // Artboard node internal structure: inputs[0]=content, inputs[1]=label(name) + const ARTBOARD_LABEL_INPUT_INDEX: usize = 1; let label = if !display_name.is_empty() { display_name } else { "Artboard".to_string() }; let label_input = NodeInput::value(TaggedValue::String(label), false); - to_artboard.inputs[label_index] = label_input; + to_artboard.inputs[ARTBOARD_LABEL_INPUT_INDEX] = label_input; } self.transaction_modified(); @@ -4584,7 +4584,7 @@ impl NodeNetworkInterface { outward_wires .get(&OutputConnector::node(*node_id, OutputConnector::PRIMARY_OUTPUT_INDEX)) .and_then(|outward_wires| (outward_wires.len() == 1).then(|| outward_wires[0])) - .and_then(|downstream_connector| if downstream_connector.input_index() == 0 { downstream_connector.node_id() } else { None }) + .and_then(|downstream_connector| if downstream_connector.input_index() == InputConnector::PRIMARY_INPUT_INDEX { downstream_connector.node_id() } else { None }) }) .filter(|downstream_node_id| self.is_layer(downstream_node_id, network_path)) .and_then(|downstream_layer| self.position(&downstream_layer, network_path)); @@ -4608,8 +4608,7 @@ impl NodeNetworkInterface { // Try build the chain if is_layer { - const LAYER_SECONDARY_INPUT_INDEX: usize = 1; - self.try_set_upstream_to_chain(&InputConnector::node(*node_id, LAYER_SECONDARY_INPUT_INDEX), network_path); + self.try_set_upstream_to_chain(&InputConnector::node(*node_id, InputConnector::PRIMARY_INPUT_INDEX + 1), network_path); } else { self.try_set_node_to_chain(node_id, network_path); } @@ -4716,10 +4715,10 @@ impl NodeNetworkInterface { } match new_export { Some(new_export) => { - self.create_wire(&new_export, &InputConnector::Export(0), network_path); + self.create_wire(&new_export, &InputConnector::Export(InputConnector::PRIMARY_INPUT_INDEX), network_path); } None => { - self.disconnect_input(&InputConnector::Export(0), network_path); + self.disconnect_input(&InputConnector::Export(InputConnector::PRIMARY_INPUT_INDEX), network_path); } } let Some(network_metadata) = self.network_metadata_mut(network_path) else { @@ -4853,7 +4852,7 @@ impl NodeNetworkInterface { return Vec::new(); }; let mut set_position_to_chain = Vec::new(); - if self.is_layer(input_connector_node_id, network_path) && *input_index == 1 || self.is_chain(input_connector_node_id, network_path) && *input_index == 0 { + if self.is_layer(input_connector_node_id, network_path) && *input_index == InputConnector::PRIMARY_INPUT_INDEX + 1 || self.is_chain(input_connector_node_id, network_path) && *input_index == InputConnector::PRIMARY_INPUT_INDEX { let mut downstream_id = *input_connector_node_id; for upstream_node in self .upstream_flow_back_from_nodes(vec![*input_connector_node_id], network_path, FlowType::HorizontalFlow) @@ -5498,7 +5497,7 @@ impl NodeNetworkInterface { // Get the height of the downstream node if inserting into a stack let mut downstream_height = 0; let inserting_into_stack = - !(post_node.input_index() == 1 || matches!(post_node, InputConnector::Export(_)) || !post_node.node_id().is_some_and(|post_node_id| self.is_layer(&post_node_id, network_path))); + !(post_node.input_index() == InputConnector::PRIMARY_INPUT_INDEX + 1 || matches!(post_node, InputConnector::Export(_)) || !post_node.node_id().is_some_and(|post_node_id| self.is_layer(&post_node_id, network_path))); if inserting_into_stack && let Some(downstream_node) = post_node.node_id() { let Some(downstream_node_position) = self.position(&downstream_node, network_path) else { log::error!("Could not get downstream node position in move_layer_to_stack"); @@ -5660,17 +5659,16 @@ impl NodeNetworkInterface { // Moves a node and to the start of a layer chain (feeding into the secondary input of the layer) pub fn move_node_to_chain_start(&mut self, node_id: &NodeId, parent: LayerNodeIdentifier, network_path: &[NodeId]) { - const LAYER_SECONDARY_INPUT_INDEX: usize = 1; - let Some(current_input) = self.input_from_connector(&InputConnector::node(parent.to_node(), LAYER_SECONDARY_INPUT_INDEX), network_path) else { + let Some(current_input) = self.input_from_connector(&InputConnector::node(parent.to_node(), InputConnector::PRIMARY_INPUT_INDEX + 1), network_path) else { log::error!("Could not get input for node {node_id}"); return; }; if matches!(current_input, NodeInput::Value { .. }) { - self.create_wire(&OutputConnector::node(*node_id, OutputConnector::PRIMARY_OUTPUT_INDEX), &InputConnector::node(parent.to_node(), LAYER_SECONDARY_INPUT_INDEX), network_path); + self.create_wire(&OutputConnector::node(*node_id, OutputConnector::PRIMARY_OUTPUT_INDEX), &InputConnector::node(parent.to_node(), InputConnector::PRIMARY_INPUT_INDEX + 1), network_path); self.set_chain_position(node_id, network_path); } else { // Insert the node in the gap and set the upstream to a chain - self.insert_node_between(node_id, &InputConnector::node(parent.to_node(), LAYER_SECONDARY_INPUT_INDEX), 0, network_path); + self.insert_node_between(node_id, &InputConnector::node(parent.to_node(), InputConnector::PRIMARY_INPUT_INDEX + 1), 0, network_path); self.force_set_upstream_to_chain(node_id, network_path); } } @@ -5716,7 +5714,7 @@ impl Iterator for FlowIter<'_> { let inputs = document_node.inputs.iter().skip(skip).take(take); let node_ids = inputs.filter_map(|input| match input { - NodeInput::Node { output_index, .. } if self.flow_type == FlowType::HorizontalPrimaryOutputFlow && *output_index != 0 => None, + NodeInput::Node { output_index, .. } if self.flow_type == FlowType::HorizontalPrimaryOutputFlow && *output_index != OutputConnector::PRIMARY_OUTPUT_INDEX => None, NodeInput::Node { node_id, .. } => Some(node_id), _ => None, }); @@ -5753,7 +5751,7 @@ pub enum InputConnector { impl Default for InputConnector { fn default() -> Self { - InputConnector::Export(0) + InputConnector::Export(InputConnector::PRIMARY_INPUT_INDEX) } } @@ -5796,7 +5794,7 @@ pub enum OutputConnector { impl Default for OutputConnector { fn default() -> Self { - OutputConnector::Import(0) + OutputConnector::Import(OutputConnector::PRIMARY_OUTPUT_INDEX) } } @@ -5896,7 +5894,7 @@ impl Ports { } fn insert_layer_input(&mut self, input_index: usize, node_top_left: DVec2) { - let center = if input_index == 0 { + let center = if input_index == InputConnector::PRIMARY_INPUT_INDEX { node_top_left + DVec2::new(2. * 24., 24. * 2. + 8.) } else { node_top_left + DVec2::new(0., 24. * 1.) diff --git a/editor/src/messages/portfolio/portfolio_message_handler.rs b/editor/src/messages/portfolio/portfolio_message_handler.rs index 05f2f5a478..8ce8064200 100644 --- a/editor/src/messages/portfolio/portfolio_message_handler.rs +++ b/editor/src/messages/portfolio/portfolio_message_handler.rs @@ -14,7 +14,7 @@ use crate::messages::portfolio::document::DocumentMessageContext; use crate::messages::portfolio::document::graph_operation::utility_types::TransformIn; use crate::messages::portfolio::document::node_graph::document_node_definitions::{self, resolve_network_node_type}; use crate::messages::portfolio::document::utility_types::clipboards::{Clipboard, CopyBufferEntry, INTERNAL_CLIPBOARD_COUNT}; -use crate::messages::portfolio::document::utility_types::network_interface::OutputConnector; +use crate::messages::portfolio::document::utility_types::network_interface::{InputConnector, OutputConnector}; use crate::messages::portfolio::document::utility_types::nodes::SelectedNodes; use crate::messages::portfolio::document_migration::*; use crate::messages::portfolio::utility_types::FileContent; @@ -620,7 +620,7 @@ impl MessageHandler> for Portfolio }; // If the downstream node is a layer and the input is the first input and the current layer is not in a stack - if input_index == 0 && document.network_interface.is_layer(&downstream_node, &[]) && !document.network_interface.is_stack(&layer.to_node(), &[]) { + if input_index == InputConnector::PRIMARY_INPUT_INDEX && document.network_interface.is_layer(&downstream_node, &[]) && !document.network_interface.is_stack(&layer.to_node(), &[]) { // Ensure the layer is horizontally aligned with the downstream layer to prevent changing the layout of old files let (Some(layer_position), Some(downstream_position)) = (document.network_interface.position(&layer.to_node(), &[]), document.network_interface.position(&downstream_node, &[])) diff --git a/editor/src/messages/tool/common_functionality/gizmos/shape_gizmos/number_of_points_dial.rs b/editor/src/messages/tool/common_functionality/gizmos/shape_gizmos/number_of_points_dial.rs index 679da36244..e2f9651117 100644 --- a/editor/src/messages/tool/common_functionality/gizmos/shape_gizmos/number_of_points_dial.rs +++ b/editor/src/messages/tool/common_functionality/gizmos/shape_gizmos/number_of_points_dial.rs @@ -14,6 +14,8 @@ use glam::{DAffine2, DVec2}; use graph_craft::document::NodeInput; use graph_craft::document::value::TaggedValue; use graphene_std::NodeInputDecleration; +use graphene_std::vector::generator_nodes::regular_polygon; +use graphene_std::vector::generator_nodes::star; use std::collections::VecDeque; use std::f64::consts::TAU; @@ -195,14 +197,18 @@ impl NumberOfPointsDial { let net_delta = (delta.length() / 25.).round() * sign; let Some(layer) = self.layer else { return }; - let Some(node_id) = graph_modification_utils::get_star_id(layer, &document.network_interface).or(graph_modification_utils::get_polygon_id(layer, &document.network_interface)) else { + let (node_id, sides_input_index) = if let Some(id) = graph_modification_utils::get_star_id(layer, &document.network_interface) { + (id, star::SidesInput::::INDEX) + } else if let Some(id) = graph_modification_utils::get_polygon_id(layer, &document.network_interface) { + (id, regular_polygon::SidesInput::::INDEX) + } else { return; }; let new_point_count = ((self.initial_points as i32) + (net_delta as i32)).max(3); responses.add(NodeGraphMessage::SetInput { - input_connector: InputConnector::node(node_id, graphene_std::vector::generator_nodes::star::SidesInput::::INDEX), + input_connector: InputConnector::node(node_id, sides_input_index), input: NodeInput::value(TaggedValue::U32(new_point_count as u32), false), }); responses.add(NodeGraphMessage::RunDocumentGraph); diff --git a/editor/src/messages/tool/common_functionality/gizmos/shape_gizmos/point_radius_handle.rs b/editor/src/messages/tool/common_functionality/gizmos/shape_gizmos/point_radius_handle.rs index daf91a0cba..efead9c19e 100644 --- a/editor/src/messages/tool/common_functionality/gizmos/shape_gizmos/point_radius_handle.rs +++ b/editor/src/messages/tool/common_functionality/gizmos/shape_gizmos/point_radius_handle.rs @@ -15,6 +15,7 @@ use glam::DVec2; use graph_craft::document::NodeInput; use graph_craft::document::value::TaggedValue; use graphene_std::NodeInputDecleration; +use graphene_std::vector::generator_nodes::regular_polygon; use graphene_std::vector::generator_nodes::star::*; use std::collections::VecDeque; use std::f64::consts::{FRAC_1_SQRT_2, FRAC_PI_4, PI, SQRT_2}; @@ -65,7 +66,7 @@ impl PointRadiusHandle { let viewport = document.metadata().transform_to_viewport(layer); for i in 0..2 * sides { - let (radius, radius_index) = if i % 2 == 0 { (radius1, 2) } else { (radius2, 3) }; + let (radius, radius_index) = if i % 2 == 0 { (radius1, Radius1Input::INDEX) } else { (radius2, Radius2Input::INDEX) }; let point = star_vertex_position(viewport, i as i32, sides, radius1, radius2); let center = viewport.transform_point2(DVec2::ZERO); @@ -102,7 +103,7 @@ impl PointRadiusHandle { } if point.distance(mouse_position) < 5. { - self.radius_index = 2; + self.radius_index = regular_polygon::RadiusInput::INDEX; self.layer = Some(layer); self.point = i; self.snap_radii.clear(); @@ -343,7 +344,7 @@ impl PointRadiusHandle { return snap_radii; }; - let other_radius = if radius_index == 3 { radius_1 } else { radius_2 }; + let other_radius = if radius_index == Radius2Input::INDEX { radius_1 } else { radius_2 }; let Some(&TaggedValue::U32(sides)) = node_inputs[SidesInput::::INDEX].as_value() else { return snap_radii; @@ -418,13 +419,21 @@ impl PointRadiusHandle { pub fn update_inner_radius(&mut self, document: &DocumentMessageHandler, input: &InputPreprocessorMessageHandler, responses: &mut VecDeque, drag_start: DVec2) { let Some(layer) = self.layer else { return }; - let Some(node_id) = graph_modification_utils::get_star_id(layer, &document.network_interface).or(graph_modification_utils::get_polygon_id(layer, &document.network_interface)) else { + let radius_index = self.radius_index; + + // Radius2Input (index 3) only exists in star nodes + // RadiusInput (index 2) exists in both star (as Radius1Input) and polygon nodes + let node_id = if radius_index == Radius2Input::INDEX { + graph_modification_utils::get_star_id(layer, &document.network_interface) + } else { + graph_modification_utils::get_star_id(layer, &document.network_interface).or(graph_modification_utils::get_polygon_id(layer, &document.network_interface)) + }; + let Some(node_id) = node_id else { return; }; let viewport_transform = document.network_interface.document_metadata().transform_to_viewport(layer); let center = viewport_transform.transform_point2(DVec2::ZERO); - let radius_index = self.radius_index; let original_radius = self.initial_radius; @@ -462,7 +471,7 @@ impl PointRadiusHandle { return; }; - let other_radius = if radius_index == 3 { radius_1 } else { radius_2 }; + let other_radius = if radius_index == Radius2Input::INDEX { radius_1 } else { radius_2 }; let flipped = (other_radius.is_sign_positive() && original_radius.is_sign_negative() && new_radius.is_sign_positive()) || (other_radius.is_sign_negative() && original_radius.is_sign_positive() && new_radius.is_sign_negative()); diff --git a/editor/src/messages/tool/common_functionality/graph_modification_utils.rs b/editor/src/messages/tool/common_functionality/graph_modification_utils.rs index 8b910fb4de..95c806528c 100644 --- a/editor/src/messages/tool/common_functionality/graph_modification_utils.rs +++ b/editor/src/messages/tool/common_functionality/graph_modification_utils.rs @@ -20,6 +20,10 @@ use graphene_std::vector::style::{Fill, Gradient}; use graphene_std::vector::{PointId, SegmentId, VectorModificationType}; use std::collections::VecDeque; +const LAYER_SECONDARY_INPUT_INDEX: usize = 1; +const MERGE_CONTENT_INPUT_INDEX: usize = 1; +const FILL_NODE_FILL_INPUT_INDEX: usize = 1; + /// Returns the ID of the first Spline node in the horizontal flow which is not followed by a `Path` node, or `None` if none exists. pub fn find_spline(document: &DocumentMessageHandler, layer: LayerNodeIdentifier) -> Option { document @@ -93,11 +97,9 @@ pub fn merge_layers(document: &DocumentMessageHandler, first_layer: LayerNodeIde node_id: merge_node_id, parent: first_layer, }); - const LAYER_SECONDARY_INPUT_INDEX: usize = 1; - const MERGE_CONTENT_INDEX: usize = 1; responses.add(NodeGraphMessage::ConnectUpstreamOutputToInput { downstream_input: InputConnector::node(second_layer.to_node(), LAYER_SECONDARY_INPUT_INDEX), - input_connector: InputConnector::node(merge_node_id, MERGE_CONTENT_INDEX), + input_connector: InputConnector::node(merge_node_id, MERGE_CONTENT_INPUT_INDEX), }); responses.add(NodeGraphMessage::DeleteNodes { node_ids: vec![second_layer.to_node()], @@ -278,10 +280,8 @@ pub fn get_viewport_center(layer: LayerNodeIdentifier, network_interface: &NodeN /// Get the current gradient of a layer from the closest "Fill" node. pub fn get_gradient(layer: LayerNodeIdentifier, network_interface: &NodeNetworkInterface) -> Option { - let fill_index = 1; - let inputs = NodeGraphLayer::new(layer, network_interface).find_node_inputs(&DefinitionIdentifier::ProtoNode(graphene_std::vector::fill::IDENTIFIER))?; - let TaggedValue::Fill(Fill::Gradient(gradient)) = inputs.get(fill_index)?.as_value()? else { + let TaggedValue::Fill(Fill::Gradient(gradient)) = inputs.get(FILL_NODE_FILL_INPUT_INDEX)?.as_value()? else { return None; }; Some(gradient.clone()) @@ -289,10 +289,8 @@ pub fn get_gradient(layer: LayerNodeIdentifier, network_interface: &NodeNetworkI /// Get the current fill of a layer from the closest "Fill" node. pub fn get_fill_color(layer: LayerNodeIdentifier, network_interface: &NodeNetworkInterface) -> Option { - let fill_index = 1; - let inputs = NodeGraphLayer::new(layer, network_interface).find_node_inputs(&DefinitionIdentifier::ProtoNode(graphene_std::vector::fill::IDENTIFIER))?; - let TaggedValue::Fill(Fill::Solid(color)) = inputs.get(fill_index)?.as_value()? else { + let TaggedValue::Fill(Fill::Solid(color)) = inputs.get(FILL_NODE_FILL_INPUT_INDEX)?.as_value()? else { return None; }; Some(color.to_linear_srgb()) @@ -521,8 +519,7 @@ impl<'a> NodeGraphLayer<'a> { /// Check if a layer is a raster layer pub fn is_raster_layer(layer: LayerNodeIdentifier, network_interface: &mut NodeNetworkInterface) -> bool { - const LAYER_SECONDARY_INPUT_INDEX: usize = 1; - let layer_input_type = network_interface.input_type(&InputConnector::node(layer.to_node(), LAYER_SECONDARY_INPUT_INDEX), &[]); + let layer_input_type = network_interface.input_type(&InputConnector::node(layer.to_node(), InputConnector::PRIMARY_INPUT_INDEX + 1), &[]); layer_input_type.compiled_nested_type() == Some(&concrete!(Table>)) || layer_input_type.compiled_nested_type() == Some(&concrete!(Table>)) } diff --git a/editor/src/messages/tool/common_functionality/shapes/line_shape.rs b/editor/src/messages/tool/common_functionality/shapes/line_shape.rs index 3e739b58ea..7287f6afa1 100644 --- a/editor/src/messages/tool/common_functionality/shapes/line_shape.rs +++ b/editor/src/messages/tool/common_functionality/shapes/line_shape.rs @@ -196,6 +196,8 @@ mod test_line_tool { use crate::test_utils::test_prelude::*; use glam::DAffine2; use graph_craft::document::value::TaggedValue; + use graphene_std::NodeInputDecleration; + use graphene_std::vector::generator_nodes::line::{StartInput, EndInput}; /// Get the line's document-space start and end points by reading line_to from the node /// and computing the actual positions via the layer's transform. diff --git a/editor/src/messages/tool/common_functionality/shapes/polygon_shape.rs b/editor/src/messages/tool/common_functionality/shapes/polygon_shape.rs index 24808e37e2..e9e0fd9b75 100644 --- a/editor/src/messages/tool/common_functionality/shapes/polygon_shape.rs +++ b/editor/src/messages/tool/common_functionality/shapes/polygon_shape.rs @@ -17,6 +17,7 @@ use graph_craft::document::NodeInput; use graph_craft::document::value::TaggedValue; use graphene_std::NodeInputDecleration; use graphene_std::vector::generator_nodes::regular_polygon::*; +use graphene_std::vector::generator_nodes::star; use std::collections::VecDeque; #[derive(Clone, Debug, Default)] @@ -165,18 +166,26 @@ impl Polygon { /// Updates the number of sides of a polygon or star node and syncs the Shape tool UI widget accordingly. /// Increases or decreases the side count based on user input, clamped to a minimum of 3. pub fn decrease_or_increase_sides(decrease: bool, layer: LayerNodeIdentifier, document: &DocumentMessageHandler, responses: &mut VecDeque) { - let Some(node_id) = graph_modification_utils::get_polygon_id(layer, &document.network_interface).or(graph_modification_utils::get_star_id(layer, &document.network_interface)) else { - return; - }; - - let Some(node_inputs) = NodeGraphLayer::new(layer, &document.network_interface) - .find_node_inputs(&DefinitionIdentifier::ProtoNode(graphene_std::vector::generator_nodes::regular_polygon::IDENTIFIER)) - .or(NodeGraphLayer::new(layer, &document.network_interface).find_node_inputs(&DefinitionIdentifier::ProtoNode(graphene_std::vector::generator_nodes::star::IDENTIFIER))) - else { - return; - }; - - let Some(&TaggedValue::U32(n)) = node_inputs.get(SidesInput::::INDEX).unwrap().as_value() else { + let (node_id, sides_input_index, n) = if let Some(id) = graph_modification_utils::get_polygon_id(layer, &document.network_interface) { + let Some(node_inputs) = + NodeGraphLayer::new(layer, &document.network_interface).find_node_inputs(&DefinitionIdentifier::ProtoNode(graphene_std::vector::generator_nodes::regular_polygon::IDENTIFIER)) + else { + return; + }; + let Some(&TaggedValue::U32(n)) = node_inputs.get(SidesInput::::INDEX).unwrap().as_value() else { + return; + }; + (id, SidesInput::::INDEX, n) + } else if let Some(id) = graph_modification_utils::get_star_id(layer, &document.network_interface) { + let Some(node_inputs) = NodeGraphLayer::new(layer, &document.network_interface).find_node_inputs(&DefinitionIdentifier::ProtoNode(graphene_std::vector::generator_nodes::star::IDENTIFIER)) + else { + return; + }; + let Some(&TaggedValue::U32(n)) = node_inputs.get(star::SidesInput::::INDEX).unwrap().as_value() else { + return; + }; + (id, star::SidesInput::::INDEX, n) + } else { return; }; @@ -187,7 +196,7 @@ impl Polygon { }); responses.add(NodeGraphMessage::SetInput { - input_connector: InputConnector::node(node_id, SidesInput::::INDEX), + input_connector: InputConnector::node(node_id, sides_input_index), input: NodeInput::value(TaggedValue::U32(new_dimension), false), }); responses.add(NodeGraphMessage::RunDocumentGraph); diff --git a/editor/src/messages/tool/common_functionality/shapes/shape_utility.rs b/editor/src/messages/tool/common_functionality/shapes/shape_utility.rs index 3224583bde..7cae6cc752 100644 --- a/editor/src/messages/tool/common_functionality/shapes/shape_utility.rs +++ b/editor/src/messages/tool/common_functionality/shapes/shape_utility.rs @@ -19,6 +19,8 @@ use graph_craft::document::value::TaggedValue; use graphene_std::NodeInputDecleration; use graphene_std::subpath::{self, Subpath}; use graphene_std::vector::click_target::ClickTargetType; +use graphene_std::vector::generator_nodes::regular_polygon::SidesInput as PolygonSidesInput; +use graphene_std::vector::generator_nodes::star::SidesInput as StarSidesInput; use graphene_std::vector::misc::{ArcType, GridType, SpiralType, dvec2_to_point}; use kurbo::{BezPath, PathEl, Shape}; use std::collections::VecDeque; @@ -194,7 +196,7 @@ pub fn update_radius_sign(end: DVec2, start: DVec2, layer: LayerNodeIdentifier, let new_layer = NodeGraphLayer::new(layer, &document.network_interface); if new_layer - .find_input(&DefinitionIdentifier::ProtoNode(graphene_std::vector::generator_nodes::regular_polygon::IDENTIFIER), 1) + .find_input(&DefinitionIdentifier::ProtoNode(graphene_std::vector::generator_nodes::regular_polygon::IDENTIFIER), PolygonSidesInput::::INDEX) .unwrap_or(&TaggedValue::U32(0)) .to_u32() % 2 == 1 @@ -211,7 +213,7 @@ pub fn update_radius_sign(end: DVec2, start: DVec2, layer: LayerNodeIdentifier, } if new_layer - .find_input(&DefinitionIdentifier::ProtoNode(graphene_std::vector::generator_nodes::star::IDENTIFIER), 1) + .find_input(&DefinitionIdentifier::ProtoNode(graphene_std::vector::generator_nodes::star::IDENTIFIER), StarSidesInput::::INDEX) .unwrap_or(&TaggedValue::U32(0)) .to_u32() % 2 == 1 diff --git a/editor/src/messages/tool/common_functionality/utility_functions.rs b/editor/src/messages/tool/common_functionality/utility_functions.rs index accf27dc96..83a2e2d21f 100644 --- a/editor/src/messages/tool/common_functionality/utility_functions.rs +++ b/editor/src/messages/tool/common_functionality/utility_functions.rs @@ -22,6 +22,8 @@ use graphene_std::vector::misc::{HandleId, ManipulatorPointId, dvec2_to_point}; use graphene_std::vector::{HandleExt, PointId, SegmentId, Vector, VectorModification, VectorModificationType}; use kurbo::{CubicBez, DEFAULT_ACCURACY, Line, ParamCurve, PathSeg, Point, QuadBez, Shape}; +const PATH_MODIFICATION_INPUT_INDEX: usize = 1; + /// Determines if a path should be extended. Goal in viewport space. Returns the path and if it is extending from the start, if applicable. pub fn should_extend(document: &DocumentMessageHandler, goal: DVec2, tolerance: f64, layers: impl Iterator) -> Option<(LayerNodeIdentifier, PointId, DVec2)> { closest_point(document, goal, tolerance, layers, |_| false) @@ -582,7 +584,8 @@ pub fn make_path_editable_is_allowed(network_interface: &mut NodeNetworkInterfac // Must not already have an existing Path node, in the right-most part of the layer chain, which has an empty set of modifications // (otherwise users could repeatedly keep running this command and stacking up empty Path nodes) - if let Some(TaggedValue::VectorModification(modifications)) = NodeGraphLayer::new(first_layer, network_interface).find_input(&DefinitionIdentifier::Network("Path".into()), 1) + if let Some(TaggedValue::VectorModification(modifications)) = + NodeGraphLayer::new(first_layer, network_interface).find_input(&DefinitionIdentifier::Network("Path".into()), PATH_MODIFICATION_INPUT_INDEX) && modifications.as_ref() == &VectorModification::default() { return None; diff --git a/editor/src/messages/tool/tool_messages/brush_tool.rs b/editor/src/messages/tool/tool_messages/brush_tool.rs index acfe5c5f5f..186f0d87c9 100644 --- a/editor/src/messages/tool/tool_messages/brush_tool.rs +++ b/editor/src/messages/tool/tool_messages/brush_tool.rs @@ -12,6 +12,7 @@ use graphene_std::brush::brush_stroke::{BrushInputSample, BrushStroke, BrushStyl use graphene_std::raster::BlendMode; const BRUSH_MAX_SIZE: f64 = 5000.; +const BRUSH_STROKES_INDEX: usize = 1; #[cfg_attr(feature = "wasm", derive(tsify::Tsify))] #[derive(PartialEq, Copy, Clone, Debug, serde::Serialize, serde::Deserialize)] @@ -320,7 +321,6 @@ impl BrushToolData { }; if reference == DefinitionIdentifier::Network("Brush".into()) && node_id != layer.to_node() { - const BRUSH_STROKES_INDEX: usize = 1; let points_input = node.inputs.get(BRUSH_STROKES_INDEX)?; let Some(TaggedValue::BrushStrokes(strokes)) = points_input.as_value() else { continue }; self.strokes.clone_from(strokes); From 066aed6073b2e6d1682de77d6fe267b071f74758 Mon Sep 17 00:00:00 2001 From: Tyooughtul Date: Tue, 10 Mar 2026 23:48:44 +0800 Subject: [PATCH 7/7] fix: replace.unwrap() with.and_then(|input|input.as_value()) --- .../tool/common_functionality/shapes/polygon_shape.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/editor/src/messages/tool/common_functionality/shapes/polygon_shape.rs b/editor/src/messages/tool/common_functionality/shapes/polygon_shape.rs index e9e0fd9b75..0f291c87ff 100644 --- a/editor/src/messages/tool/common_functionality/shapes/polygon_shape.rs +++ b/editor/src/messages/tool/common_functionality/shapes/polygon_shape.rs @@ -172,7 +172,7 @@ impl Polygon { else { return; }; - let Some(&TaggedValue::U32(n)) = node_inputs.get(SidesInput::::INDEX).unwrap().as_value() else { + let Some(&TaggedValue::U32(n)) = node_inputs.get(SidesInput::::INDEX).and_then(|input| input.as_value()) else { return; }; (id, SidesInput::::INDEX, n) @@ -181,7 +181,7 @@ impl Polygon { else { return; }; - let Some(&TaggedValue::U32(n)) = node_inputs.get(star::SidesInput::::INDEX).unwrap().as_value() else { + let Some(&TaggedValue::U32(n)) = node_inputs.get(star::SidesInput::::INDEX).and_then(|input| input.as_value()) else { return; }; (id, star::SidesInput::::INDEX, n)