From de0317b7d8a78f15bcc1fdbc9f3ab78b0174077a Mon Sep 17 00:00:00 2001 From: krVatsal Date: Sat, 17 Jan 2026 12:46:54 +0530 Subject: [PATCH 1/2] fixed the arrow's parameters Signed-off-by: krVatsal --- .../shapes/arrow_shape.rs | 9 +- .../messages/tool/tool_messages/shape_tool.rs | 85 ++++++++++++++++++- 2 files changed, 88 insertions(+), 6 deletions(-) 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 bf398f1515..33ff5648db 100644 --- a/editor/src/messages/tool/common_functionality/shapes/arrow_shape.rs +++ b/editor/src/messages/tool/common_functionality/shapes/arrow_shape.rs @@ -35,6 +35,9 @@ impl Arrow { layer: LayerNodeIdentifier, tool_data: &mut ShapeToolData, _modifier: ShapeToolModifierKey, + shaft_width: f64, + head_width: f64, + head_length: f64, responses: &mut VecDeque, ) { // Track current mouse position in viewport space @@ -56,11 +59,7 @@ impl Arrow { return; }; - // Calculate proportional dimensions based on arrow length - let shaft_width = length_document * 0.1; - let head_width = length_document * 0.3; - let head_length = length_document * 0.2; - + // Use fixed dimensions from tool options - only length changes during drag // Update Arrow node parameters with document space coordinates (like Line tool) responses.add(NodeGraphMessage::SetInput { input_connector: InputConnector::node(node_id, 1), diff --git a/editor/src/messages/tool/tool_messages/shape_tool.rs b/editor/src/messages/tool/tool_messages/shape_tool.rs index e459c9cb11..43b3dda38f 100644 --- a/editor/src/messages/tool/tool_messages/shape_tool.rs +++ b/editor/src/messages/tool/tool_messages/shape_tool.rs @@ -44,6 +44,9 @@ pub struct ShapeToolOptions { grid_type: GridType, spiral_type: SpiralType, turns: f64, + arrow_shaft_width: f64, + arrow_head_width: f64, + arrow_head_length: f64, } impl Default for ShapeToolOptions { @@ -58,6 +61,9 @@ impl Default for ShapeToolOptions { spiral_type: SpiralType::Archimedean, turns: 5., grid_type: GridType::Rectangular, + arrow_shaft_width: 14.0, + arrow_head_width: 32.0, + arrow_head_length: 28.0, } } } @@ -76,6 +82,9 @@ pub enum ShapeOptionsUpdate { SpiralType(SpiralType), Turns(f64), GridType(GridType), + ArrowShaftWidth(f64), + ArrowHeadWidth(f64), + ArrowHeadLength(f64), } #[impl_message(Message, ToolMessage, Shape)] @@ -236,6 +245,51 @@ fn create_weight_widget(line_weight: f64) -> WidgetInstance { .widget_instance() } +fn create_arrow_shaft_width_widget(shaft_width: f64) -> WidgetInstance { + NumberInput::new(Some(shaft_width)) + .unit(" px") + .label("Shaft") + .min(0.1) + .max(1000.) + .on_update(|number_input: &NumberInput| { + ShapeToolMessage::UpdateOptions { + options: ShapeOptionsUpdate::ArrowShaftWidth(number_input.value.unwrap()), + } + .into() + }) + .widget_instance() +} + +fn create_arrow_head_width_widget(head_width: f64) -> WidgetInstance { + NumberInput::new(Some(head_width)) + .unit(" px") + .label("Head W") + .min(0.1) + .max(1000.) + .on_update(|number_input: &NumberInput| { + ShapeToolMessage::UpdateOptions { + options: ShapeOptionsUpdate::ArrowHeadWidth(number_input.value.unwrap()), + } + .into() + }) + .widget_instance() +} + +fn create_arrow_head_length_widget(head_length: f64) -> WidgetInstance { + NumberInput::new(Some(head_length)) + .unit(" px") + .label("Head L") + .min(0.1) + .max(1000.) + .on_update(|number_input: &NumberInput| { + ShapeToolMessage::UpdateOptions { + options: ShapeOptionsUpdate::ArrowHeadLength(number_input.value.unwrap()), + } + .into() + }) + .widget_instance() +} + fn create_spiral_type_widget(spiral_type: SpiralType) -> WidgetInstance { let entries = vec![vec![ MenuListEntry::new("Archimedean").label("Archimedean").on_commit(move |_| { @@ -304,6 +358,15 @@ impl LayoutHolder for ShapeTool { widgets.push(Separator::new(SeparatorStyle::Unrelated).widget_instance()); } + if self.options.shape_type == ShapeType::Arrow { + widgets.push(create_arrow_shaft_width_widget(self.options.arrow_shaft_width)); + widgets.push(Separator::new(SeparatorStyle::Related).widget_instance()); + widgets.push(create_arrow_head_width_widget(self.options.arrow_head_width)); + widgets.push(Separator::new(SeparatorStyle::Related).widget_instance()); + widgets.push(create_arrow_head_length_widget(self.options.arrow_head_length)); + widgets.push(Separator::new(SeparatorStyle::Unrelated).widget_instance()); + } + if self.options.shape_type != ShapeType::Line { widgets.append(&mut self.options.fill.create_widgets( "Fill", @@ -414,6 +477,15 @@ impl<'a> MessageHandler> for Shap ShapeOptionsUpdate::GridType(grid_type) => { self.options.grid_type = grid_type; } + ShapeOptionsUpdate::ArrowShaftWidth(shaft_width) => { + self.options.arrow_shaft_width = shaft_width; + } + ShapeOptionsUpdate::ArrowHeadWidth(head_width) => { + self.options.arrow_head_width = head_width; + } + ShapeOptionsUpdate::ArrowHeadLength(head_length) => { + self.options.arrow_head_length = head_length; + } } update_dynamic_hints(&self.fsm_state, responses, &self.tool_data); @@ -905,7 +977,18 @@ impl Fsm for ShapeToolFsmState { ShapeType::Star => Star::update_shape(document, input, viewport, layer, tool_data, modifier, responses), ShapeType::Circle => Circle::update_shape(document, input, viewport, layer, tool_data, modifier, responses), ShapeType::Arc => Arc::update_shape(document, input, viewport, layer, tool_data, modifier, responses), - ShapeType::Arrow => Arrow::update_shape(document, input, viewport, layer, tool_data, modifier, responses), + ShapeType::Arrow => Arrow::update_shape( + document, + input, + viewport, + layer, + tool_data, + modifier, + tool_options.arrow_shaft_width, + tool_options.arrow_head_width, + tool_options.arrow_head_length, + responses, + ), ShapeType::Spiral => Spiral::update_shape(document, input, viewport, layer, tool_data, responses), ShapeType::Grid => Grid::update_shape(document, input, layer, tool_options.grid_type, tool_data, modifier, responses), ShapeType::Rectangle => Rectangle::update_shape(document, input, viewport, layer, tool_data, modifier, responses), From 0c9306c2ef7c77b8d66f7177d6b828c35d193c0f Mon Sep 17 00:00:00 2001 From: krVatsal Date: Sat, 17 Jan 2026 17:21:32 +0530 Subject: [PATCH 2/2] shifted the arrow's origin to its tail Signed-off-by: krVatsal --- .../libraries/vector-types/src/subpath/core.rs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/node-graph/libraries/vector-types/src/subpath/core.rs b/node-graph/libraries/vector-types/src/subpath/core.rs index ae1922c233..d589d45e31 100644 --- a/node-graph/libraries/vector-types/src/subpath/core.rs +++ b/node-graph/libraries/vector-types/src/subpath/core.rs @@ -330,14 +330,16 @@ impl Subpath { let head_base_distance = (length - head_length).max(0.); let head_base = start + direction * head_base_distance; + // Arrow path starts at the tail (origin), traces around the shape, and returns to tail let anchors = [ - start - perpendicular * half_shaft, // Tail bottom - head_base - perpendicular * half_shaft, // Head base bottom (shaft) - head_base - perpendicular * half_head, // Head base bottom (wide) - end, // Tip - head_base + perpendicular * half_head, // Head base top (wide) - head_base + perpendicular * half_shaft, // Head base top (shaft) + start, // Tail center (origin) start + perpendicular * half_shaft, // Tail top + head_base + perpendicular * half_shaft, // Head base top (shaft) + head_base + perpendicular * half_head, // Head base top (wide) + end, // Tip + head_base - perpendicular * half_head, // Head base bottom (wide) + head_base - perpendicular * half_shaft, // Head base bottom (shaft) + start - perpendicular * half_shaft, // Tail bottom ]; Self::from_anchors(anchors, true)