diff --git a/editor/src/messages/tool/common_functionality/shape_editor.rs b/editor/src/messages/tool/common_functionality/shape_editor.rs index 6723db92e9..937322b360 100644 --- a/editor/src/messages/tool/common_functionality/shape_editor.rs +++ b/editor/src/messages/tool/common_functionality/shape_editor.rs @@ -447,6 +447,7 @@ impl ShapeState { let (layer2, end_point) = all_selected_points[1]; if layer1 == layer2 { + // Same layer: create segment directly if start_point == end_point { return; } @@ -459,16 +460,31 @@ impl ShapeState { }; responses.add(GraphOperationMessage::Vector { layer: layer1, modification_type }); } else { - // Merge the layers - merge_layers(document, layer1, layer2, responses); - // Create segment between the two points - let segment_id = SegmentId::generate(); - let modification_type = VectorModificationType::InsertSegment { - id: segment_id, - points: [end_point, start_point], - handles: [None, None], - }; - responses.add(GraphOperationMessage::Vector { layer: layer1, modification_type }); + // Different layers: merge first, then create segment + + // Get the indices of the selected points in their respective vectors + let start_index = document.network_interface.compute_modified_vector(layer1) + .and_then(|v| v.point_domain.resolve_id(start_point)); + let end_index = document.network_interface.compute_modified_vector(layer2) + .and_then(|v| v.point_domain.resolve_id(end_point)); + + // Get the number of points in layer1 (this will be the offset for layer2 points after merge) + let layer1_point_count = document.network_interface.compute_modified_vector(layer1) + .map(|v| v.point_domain.ids().len()); + + if let (Some(start_idx), Some(end_idx), Some(point_offset)) = (start_index, end_index, layer1_point_count) { + // Merge the layers + merge_layers(document, layer1, layer2, responses); + + // After the graph runs and the merge is complete, restore selection and close path + responses.add(DeferMessage::AfterGraphRun { + messages: vec![ToolMessage::Path(PathToolMessage::RestoreSelectionAndClosePath { + layer: layer1, + start_index: start_idx, + end_index: end_idx + point_offset, + }).into()], + }); + } } return; } diff --git a/editor/src/messages/tool/tool_messages/path_tool.rs b/editor/src/messages/tool/tool_messages/path_tool.rs index 35fd18e940..c063373b76 100644 --- a/editor/src/messages/tool/tool_messages/path_tool.rs +++ b/editor/src/messages/tool/tool_messages/path_tool.rs @@ -73,6 +73,11 @@ pub enum PathToolMessage { }, Escape, ClosePath, + RestoreSelectionAndClosePath { + layer: LayerNodeIdentifier, + start_index: usize, + end_index: usize, + }, DoubleClick { extend_selection: Key, shrink_selection: Key, @@ -2669,6 +2674,35 @@ impl Fsm for PathToolFsmState { self } + (_, PathToolMessage::RestoreSelectionAndClosePath { layer, start_index, end_index }) => { + // Get the merged vector + let Some(vector) = document.network_interface.compute_modified_vector(layer) else { + return self; + }; + + // Get the point IDs at the calculated indices + let point_ids = vector.point_domain.ids(); + + if start_index >= point_ids.len() || end_index >= point_ids.len() { + return self; + } + + let start_point_id = point_ids[start_index]; + let end_point_id = point_ids[end_index]; + + // Clear existing selection and select the merged layer + shape_editor.deselect_all_points(); + shape_editor.set_selected_layers(vec![layer]); + + // Select the two points + shape_editor.select_point_by_layer_and_id(ManipulatorPointId::Anchor(start_point_id), layer); + shape_editor.select_point_by_layer_and_id(ManipulatorPointId::Anchor(end_point_id), layer); + + // Now call ClosePath which will see the selection and create the segment + responses.add(PathToolMessage::ClosePath); + + self + } (_, PathToolMessage::StartSlidingPoint) => { responses.add(DocumentMessage::StartTransaction); if tool_data.start_sliding_point(shape_editor, document) {