Repository: GraphiteEditor/Graphite (language: rust)

Issue:
Pen tool clicking an anchor to turn it sharp or close a path shouldn't rely on snapping
In the Pen tool, clicking to turn a point sharp relies on snapping being enabled to work, which is bad: 

https://github.com/user-attachments/assets/70c74839-2519-42a5-8d40-af4a459da912

It should be able to do that irrespective of the snapping system. Essentially, the tool should have its own self-contained implementation of snapping just for the actively being-drawn-from segment endpoint, which is always active even when the snapping system is disabled, and the real snapping system shouldn't interfere with it.


Discussion / hints:

Fix patch:
diff --git a/editor/src/messages/tool/tool_messages/pen_tool.rs b/editor/src/messages/tool/tool_messages/pen_tool.rs
index 7dbbc9bdfb..484b3c29f3 100644
--- a/editor/src/messages/tool/tool_messages/pen_tool.rs
+++ b/editor/src/messages/tool/tool_messages/pen_tool.rs
@@ -359,8 +359,24 @@ impl PenToolData {
 	}
 
 	fn place_anchor(&mut self, snap_data: SnapData, transform: DAffine2, mouse: DVec2, responses: &mut VecDeque<Message>) -> Option<PenToolFsmState> {
+		let document = snap_data.document;
+
 		let relative = self.latest_point().map(|point| point.pos);
 		self.next_point = self.compute_snapped_angle(snap_data, transform, false, mouse, relative, true);
+
+		let selected_nodes = document.network_interface.selected_nodes(&[]).unwrap();
+		let mut selected_layers = selected_nodes.selected_layers(document.metadata());
+		let layer = selected_layers.next().filter(|_| selected_layers.next().is_none())?;
+		let vector_data = document.network_interface.compute_modified_vector(layer)?;
+		let transform = document.metadata().document_to_viewport * transform;
+		for point in vector_data.single_connected_points() {
+			let Some(pos) = vector_data.point_domain.position_from_id(point) else { continue };
+			let transformed_distance_between_squared = transform.transform_point2(pos).distance_squared(transform.transform_point2(self.next_point));
+			let snap_point_tolerance_squared = crate::consts::SNAP_POINT_TOLERANCE.powi(2);
+			if transformed_distance_between_squared < snap_point_tolerance_squared {
+				self.next_point = pos;
+			}
+		}
 		if let Some(handle_end) = self.handle_end.as_mut() {
 			*handle_end = self.next_point;
 			self.next_handle_start = self.next_point;


Test patch: