Repository: GraphiteEditor/Graphite
File: editor/src/messages/tool/tool_messages/gradient_tool.rs (Rust)

Code before:
						}
					}

					// Check dragging start or end handle
					for (pos, dragging_target) in [(gradient.start, GradientDragTarget::Start), (gradient.end, GradientDragTarget::End)] {
						let pos = transform.transform_point2(pos);
						if pos.distance_squared(mouse) < tolerance {
							dragging = true;
							tool_data.selected_gradient = Some(SelectedGradient {
								layer: Some(layer),
								transform,
								gradient: gradient.clone(),
								dragging: dragging_target,
								initial_gradient: gradient.clone(),
							})
						}
					}

					// Insert stop if clicking on line
					if !dragging {
						let (start, end) = (transform.transform_point2(gradient.start), transform.transform_point2(gradient.end));
						let distance = (end - start).angle_to(mouse - start).sin() * (mouse - start).length();
						let projection = ((end - start).angle_to(mouse - start)).cos() * start.distance(mouse) / start.distance(end);

						if distance.abs() < SEGMENT_INSERTION_DISTANCE && (0. ..=1.).contains(&projection) {
							if let Some(index) = gradient.clone().insert_stop(mouse, transform) {
								responses.add(DocumentMessage::StartTransaction);
								transaction_started = true;
								let mut new_gradient = gradient.clone();
								new_gradient.insert_stop(mouse, transform);

								let mut selected_gradient = SelectedGradient::new(new_gradient, layer, document);
								selected_gradient.dragging = GradientDragTarget::Step(index);
								// No offset when inserting a new stop, it should be exactly under the mouse
								selected_gradient.render_gradient(responses);
								tool_data.selected_gradient = Some(selected_gradient);
								dragging = true;
							}
						}
					}
				}

				let gradient_state = if dragging {
					GradientToolFsmState::Drawing
				} else {
					let selected_layer = document.click(input, viewport);

					// Apply the gradient to the selected layer
					if let Some(layer) = selected_layer {
						// Add check for raster layer
						if NodeGraphLayer::is_raster_layer(layer, &mut document.network_interface) {

Review comment (suggestion):
`gradient.clone()` is called twice and `insert_stop` is called twice. This can be simplified:


```
let mut new_gradient = gradient.clone();
if let Some(index) = new_gradient.insert_stop(mouse, transform) {
    responses.add(DocumentMessage::StartTransaction);
    transaction_started = true;

    let mut selected_gradient = SelectedGradient::new(new_gradient, layer, document);
    selected_gradient.dragging = GradientDragTarget::Step(index);
    // No offset when inserting a new stop, it should be exactly under the mouse
    selected_gradient.render_gradient(responses);
    tool_data.selected_gradient = Some(selected_gradient);
    dragging = true;
}
```


Code after:
				let transform = selected_gradient.transform;
				let (start, end) = (transform.transform_point2(selected_gradient.gradient.start), transform.transform_point2(selected_gradient.gradient.end));
				let (new_start, new_end) = (start.lerp(end, min_position), start.lerp(end, max_position));
				selected_gradient.gradient.start = transform.inverse().transform_point2(new_start);
				selected_gradient.gradient.end = transform.inverse().transform_point2(new_end);

				// Remap the positions
				for position in selected_gradient.gradient.stops.position.iter_mut() {
					*position = (*position - min_position) / (max_position - min_position);
				}

				// Render the new gradient
				selected_gradient.render_gradient(responses);
				responses.add(DocumentMessage::CommitTransaction);
				responses.add(PropertiesPanelMessage::Refresh);
				tool_data.selected_gradient = None;

				self
			}
			(_, GradientToolMessage::InsertStop) => {
				for layer in document.network_interface.selected_nodes().selected_visible_layers(&document.network_interface) {
					let Some(mut gradient) = get_gradient(layer, &document.network_interface) else { continue };
					// TODO: This transform is incorrect. I think this is since it is based on the Footprint which has not been updated yet
					let transform = gradient_space_transform(layer, document);
					let mouse = input.mouse.position;
					let (start, end) = (transform.transform_point2(gradient.start), transform.transform_point2(gradient.end));

					// Compute the distance from the mouse to the gradient line in viewport space
					let distance = (end - start).angle_to(mouse - start).sin() * (mouse - start).length();

					// If click is on the line then insert point
					if distance < (SELECTION_THRESHOLD * 2.) {
						// Try and insert the new stop
						if let Some(index) = gradient.insert_stop(mouse, transform) {
							responses.add(DocumentMessage::StartTransaction);

							let mut selected_gradient = SelectedGradient::new(gradient, layer, document);

							// Select the new point
							selected_gradient.dragging = GradientDragTarget::Step(index);

							// Update the layer fill
							selected_gradient.render_gradient(responses);

							tool_data.selected_gradient = Some(selected_gradient);
							responses.add(DocumentMessage::CommitTransaction);
							break;
						}
					}
				}