Promote vector meshes from experimental by removing it from preferences

This commit is contained in:
Keavon Chambers
2025-12-21 19:33:42 -08:00
parent e73e524f3d
commit 123108c813
12 changed files with 71 additions and 133 deletions
@@ -421,7 +421,7 @@ impl ShapeState {
(point.as_handle().is_some() && self.ignore_handles) || (point.as_anchor().is_some() && self.ignore_anchors)
}
pub fn close_selected_path(&self, document: &DocumentMessageHandler, responses: &mut VecDeque<Message>, vector_meshes: bool) {
pub fn close_selected_path(&self, document: &DocumentMessageHandler, responses: &mut VecDeque<Message>) {
// First collect all selected anchor points across all layers
let all_selected_points: Vec<(LayerNodeIdentifier, PointId)> = self
.selected_shape_state
@@ -446,14 +446,6 @@ impl ShapeState {
let (layer1, start_point) = all_selected_points[0];
let (layer2, end_point) = all_selected_points[1];
let Some(vector1) = document.network_interface.compute_modified_vector(layer1) else { return };
let Some(vector2) = document.network_interface.compute_modified_vector(layer2) else { return };
// If vector meshes is not selected then only for endpoints, otherwise normally applicable
if !vector_meshes && (vector1.all_connected(start_point).count() != 1 || vector2.all_connected(end_point).count() != 1) {
return;
}
if layer1 == layer2 {
if start_point == end_point {
return;
@@ -22,14 +22,8 @@ use graphene_std::vector::{HandleExt, PointId, SegmentId, Vector, VectorModifica
use kurbo::{CubicBez, DEFAULT_ACCURACY, Line, ParamCurve, PathSeg, Point, QuadBez, Shape};
/// 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<Item = LayerNodeIdentifier>,
preferences: &PreferencesMessageHandler,
) -> Option<(LayerNodeIdentifier, PointId, DVec2)> {
closest_point(document, goal, tolerance, layers, |_| false, preferences)
pub fn should_extend(document: &DocumentMessageHandler, goal: DVec2, tolerance: f64, layers: impl Iterator<Item = LayerNodeIdentifier>) -> Option<(LayerNodeIdentifier, PointId, DVec2)> {
closest_point(document, goal, tolerance, layers, |_| false)
}
/// Determine the closest point to the goal point under max_distance.
@@ -40,7 +34,6 @@ pub fn closest_point<T>(
max_distance: f64,
layers: impl Iterator<Item = LayerNodeIdentifier>,
exclude: T,
preferences: &PreferencesMessageHandler,
) -> Option<(LayerNodeIdentifier, PointId, DVec2)>
where
T: Fn(PointId) -> bool,
@@ -50,7 +43,7 @@ where
for layer in layers {
let viewspace = document.metadata().transform_to_viewport(layer);
let Some(vector) = document.network_interface.compute_modified_vector(layer) else { continue };
for id in vector.extendable_points(preferences.vector_meshes) {
for id in vector.extendable_points() {
if exclude(id) {
continue;
}
@@ -236,7 +236,6 @@ impl Fsm for FreehandToolFsmState {
global_tool_data,
input,
shape_editor,
preferences,
viewport,
..
} = tool_action_data;
@@ -244,7 +243,7 @@ impl Fsm for FreehandToolFsmState {
let ToolMessage::Freehand(event) = event else { return self };
match (self, event) {
(_, FreehandToolMessage::Overlays { context: mut overlay_context }) => {
path_endpoint_overlays(document, shape_editor, &mut overlay_context, tool_action_data.preferences);
path_endpoint_overlays(document, shape_editor, &mut overlay_context);
self
}
@@ -258,7 +257,7 @@ impl Fsm for FreehandToolFsmState {
// Extend an endpoint of the selected path
let selected_nodes = document.network_interface.selected_nodes();
let tolerance = crate::consts::SNAP_POINT_TOLERANCE;
if let Some((layer, point, position)) = should_extend(document, input.mouse.position, tolerance, selected_nodes.selected_layers(document.metadata()), preferences) {
if let Some((layer, point, position)) = should_extend(document, input.mouse.position, tolerance, selected_nodes.selected_layers(document.metadata())) {
tool_data.layer = Some(layer);
tool_data.end_point = Some((position, point));
@@ -519,7 +518,7 @@ mod test_freehand {
initial_segment_count
);
let extendable_points = initial_vector.extendable_points(false).collect::<Vec<_>>();
let extendable_points = initial_vector.extendable_points().collect::<Vec<_>>();
assert!(!extendable_points.is_empty(), "No extendable points found in the path");
let endpoint_id = extendable_points[0];
@@ -823,7 +823,7 @@ impl PathToolData {
.filter(|handle| handle.length(&vector) < 1e-6)
.map(|handle| handle.to_manipulator_point())
.collect::<Vec<_>>();
let endpoint = vector.extendable_points(false).any(|anchor| point == anchor);
let endpoint = vector.extendable_points_no_vector_meshes().any(|anchor| point == anchor);
if drag_zero_handle && (handles.len() == 1 && !endpoint) {
shape_editor.deselect_all_points();
@@ -2662,7 +2662,7 @@ impl Fsm for PathToolFsmState {
}
(_, PathToolMessage::ClosePath) => {
responses.add(DocumentMessage::AddTransaction);
shape_editor.close_selected_path(document, responses, tool_action_data.preferences.vector_meshes);
shape_editor.close_selected_path(document, responses);
responses.add(DocumentMessage::EndTransaction);
responses.add(OverlaysMessage::Draw);
@@ -589,15 +589,7 @@ impl PenToolData {
}
/// If the user places the anchor on top of the previous anchor, it becomes sharp and the outgoing handle may be dragged.
fn bend_from_previous_point(
&mut self,
snap_data: SnapData,
transform: DAffine2,
layer: LayerNodeIdentifier,
preferences: &PreferencesMessageHandler,
shape_editor: &mut ShapeState,
responses: &mut VecDeque<Message>,
) {
fn bend_from_previous_point(&mut self, snap_data: SnapData, transform: DAffine2, layer: LayerNodeIdentifier, shape_editor: &mut ShapeState, responses: &mut VecDeque<Message>) {
self.g1_continuous = true;
let document = snap_data.document;
self.next_handle_start = self.next_point;
@@ -614,7 +606,7 @@ impl PenToolData {
self.handle_end = None;
self.handle_mode = HandleMode::Free;
self.store_clicked_endpoint(document, &transform, snap_data.input, snap_data.viewport, preferences);
self.store_clicked_endpoint(document, &transform, snap_data.input, snap_data.viewport);
if self.modifiers.lock_angle {
self.set_lock_angle(&vector, id, self.prior_segment);
@@ -631,8 +623,8 @@ impl PenToolData {
}
// Closing path
let closing_path_on_point = self.close_path_on_point(snap_data, &vector, document, preferences, id, &transform);
if !closing_path_on_point && preferences.vector_meshes {
let closing_path_on_point = self.close_path_on_point(snap_data, &vector, document, id, &transform);
if !closing_path_on_point {
// Attempt to find nearest segment and close path on segment by creating an anchor point on it
let tolerance = crate::consts::SNAP_POINT_TOLERANCE;
if let Some(closest_segment) = shape_editor.upper_closest_segment(&document.network_interface, transform.transform_point2(self.next_point), tolerance) {
@@ -659,8 +651,8 @@ impl PenToolData {
}
}
fn close_path_on_point(&mut self, snap_data: SnapData, vector: &Vector, document: &DocumentMessageHandler, preferences: &PreferencesMessageHandler, id: PointId, transform: &DAffine2) -> bool {
for id in vector.extendable_points(preferences.vector_meshes).filter(|&point| point != id) {
fn close_path_on_point(&mut self, snap_data: SnapData, vector: &Vector, document: &DocumentMessageHandler, id: PointId, transform: &DAffine2) -> bool {
for id in vector.extendable_points().filter(|&point| point != id) {
let Some(pos) = vector.point_domain.position_from_id(id) 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);
@@ -670,7 +662,7 @@ impl PenToolData {
self.handle_end_offset = None;
self.path_closed = true;
self.next_handle_start = self.next_point;
self.store_clicked_endpoint(document, transform, snap_data.input, snap_data.viewport, preferences);
self.store_clicked_endpoint(document, transform, snap_data.input, snap_data.viewport);
self.handle_mode = HandleMode::Free;
if let (true, Some(prior_endpoint)) = (self.modifiers.lock_angle, self.prior_segment_endpoint) {
self.set_lock_angle(vector, prior_endpoint, self.prior_segment);
@@ -682,7 +674,7 @@ impl PenToolData {
false
}
fn finish_placing_handle(&mut self, snap_data: SnapData, transform: DAffine2, preferences: &PreferencesMessageHandler, responses: &mut VecDeque<Message>) -> Option<PenToolFsmState> {
fn finish_placing_handle(&mut self, snap_data: SnapData, transform: DAffine2, responses: &mut VecDeque<Message>) -> Option<PenToolFsmState> {
let document = snap_data.document;
let next_handle_start = self.next_handle_start;
let handle_start = self.latest_point()?.handle_start;
@@ -693,12 +685,12 @@ impl PenToolData {
let Some(handle_end) = self.handle_end else {
responses.add(DocumentMessage::EndTransaction);
self.handle_end = Some(next_handle_start);
self.place_anchor(snap_data, transform, mouse, preferences, responses);
self.place_anchor(snap_data, transform, mouse, responses);
self.latest_point_mut()?.handle_start = next_handle_start;
return None;
};
let next_point = self.next_point;
self.place_anchor(snap_data, transform, mouse, preferences, responses);
self.place_anchor(snap_data, transform, mouse, responses);
let handles = [handle_start - self.latest_point()?.pos, handle_end - next_point].map(Some);
// Get close path
@@ -709,7 +701,7 @@ impl PenToolData {
let vector = document.network_interface.compute_modified_vector(layer)?;
let start = self.latest_point()?.id;
let transform = document.metadata().document_to_viewport * transform;
for id in vector.extendable_points(preferences.vector_meshes).filter(|&point| point != start) {
for id in vector.extendable_points().filter(|&point| point != start) {
let Some(pos) = vector.point_domain.position_from_id(id) else { continue };
let transformed_distance_between_squared = transform.transform_point2(pos).distance_squared(transform.transform_point2(next_point));
let snap_point_tolerance_squared = crate::consts::SNAP_POINT_TOLERANCE.powi(2);
@@ -1123,7 +1115,7 @@ impl PenToolData {
self.update_target_handle_pos(opposite_handle, self.next_point, responses, new_handle_position, layer);
}
fn place_anchor(&mut self, snap_data: SnapData, transform: DAffine2, mouse: DVec2, preferences: &PreferencesMessageHandler, responses: &mut VecDeque<Message>) -> Option<PenToolFsmState> {
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 = if self.path_closed { None } else { self.latest_point().map(|point| point.pos) };
@@ -1134,7 +1126,7 @@ impl PenToolData {
let layer = selected_layers.next().filter(|_| selected_layers.next().is_none()).or(self.current_layer)?;
let vector = document.network_interface.compute_modified_vector(layer)?;
let transform = document.metadata().document_to_viewport * transform;
for point in vector.extendable_points(preferences.vector_meshes) {
for point in vector.extendable_points() {
let Some(pos) = vector.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);
@@ -1230,7 +1222,6 @@ impl PenToolData {
responses: &mut VecDeque<Message>,
tool_options: &PenOptions,
append: bool,
preferences: &PreferencesMessageHandler,
shape_editor: &mut ShapeState,
) {
let point = SnapCandidatePoint::handle(document.metadata().document_to_viewport.inverse().transform_point2(input.mouse.position));
@@ -1242,14 +1233,12 @@ impl PenToolData {
self.handle_end = None;
let tolerance = crate::consts::SNAP_POINT_TOLERANCE;
let extension_choice = should_extend(document, viewport_vec, tolerance, selected_nodes.selected_layers(document.metadata()), preferences);
let extension_choice = should_extend(document, viewport_vec, tolerance, selected_nodes.selected_layers(document.metadata()));
if let Some((layer, point, position)) = extension_choice {
self.current_layer = Some(layer);
self.extend_existing_path(document, layer, point, position);
return;
} else if preferences.vector_meshes
&& let Some(closest_segment) = shape_editor.upper_closest_segment(&document.network_interface, viewport_vec, tolerance)
{
} else if let Some(closest_segment) = shape_editor.upper_closest_segment(&document.network_interface, viewport_vec, tolerance) {
let (point, segments) = closest_segment.adjusted_insert(responses);
let layer = closest_segment.layer();
let position = closest_segment.closest_point_document();
@@ -1264,7 +1253,7 @@ impl PenToolData {
}
if append {
if let Some((layer, point, _)) = closest_point(document, viewport_vec, tolerance, document.metadata().all_layers(), |_| false, preferences) {
if let Some((layer, point, _)) = closest_point(document, viewport_vec, tolerance, document.metadata().all_layers(), |_| false) {
let vector = document.network_interface.compute_modified_vector(layer).unwrap();
let segment = vector.all_connected(point).collect::<Vec<_>>().first().map(|s| s.segment);
@@ -1282,7 +1271,7 @@ impl PenToolData {
}
}
if let Some((layer, point, _position)) = closest_point(document, viewport_vec, tolerance, document.metadata().all_layers(), |_| false, preferences) {
if let Some((layer, point, _position)) = closest_point(document, viewport_vec, tolerance, document.metadata().all_layers(), |_| false) {
let vector = document.network_interface.compute_modified_vector(layer).unwrap();
let segment = vector.all_connected(point).collect::<Vec<_>>().first().map(|s| s.segment);
self.handle_mode = HandleMode::Free;
@@ -1366,14 +1355,7 @@ impl PenToolData {
}
// Stores the segment and point ID of the clicked endpoint
fn store_clicked_endpoint(
&mut self,
document: &DocumentMessageHandler,
transform: &DAffine2,
input: &InputPreprocessorMessageHandler,
viewport: &ViewportMessageHandler,
preferences: &PreferencesMessageHandler,
) {
fn store_clicked_endpoint(&mut self, document: &DocumentMessageHandler, transform: &DAffine2, input: &InputPreprocessorMessageHandler, viewport: &ViewportMessageHandler) {
let mut manipulators = HashMap::with_hasher(NoHashBuilder);
let mut unselected = Vec::new();
let mut layer_manipulators = HashSet::with_hasher(NoHashBuilder);
@@ -1389,7 +1371,7 @@ impl PenToolData {
self.prior_segment_layer = None;
self.prior_segments = None;
if let Some((layer, point, _position)) = closest_point(document, viewport, tolerance, document.metadata().all_layers(), |_| false, preferences) {
if let Some((layer, point, _position)) = closest_point(document, viewport, tolerance, document.metadata().all_layers(), |_| false) {
self.prior_segment_endpoint = Some(point);
self.prior_segment_layer = Some(layer);
let vector = document.network_interface.compute_modified_vector(layer).unwrap();
@@ -1468,7 +1450,6 @@ impl Fsm for PenToolFsmState {
global_tool_data,
input,
shape_editor,
preferences,
viewport,
..
} = tool_action_data;
@@ -1630,11 +1611,8 @@ impl Fsm for PenToolFsmState {
let snapped = tool_data.snap_manager.free_snap(&SnapData::new(document, input, viewport), &point, SnapTypeConfiguration::default());
let viewport_vec = document.metadata().document_to_viewport.transform_point2(snapped.snapped_point_document);
let close_to_point = closest_point(document, viewport_vec, tolerance, document.metadata().all_layers(), |_| false, preferences).is_some();
if preferences.vector_meshes
&& !close_to_point
&& let Some(closest_segment) = shape_editor.upper_closest_segment(&document.network_interface, viewport_vec, tolerance)
{
let close_to_point = closest_point(document, viewport_vec, tolerance, document.metadata().all_layers(), |_| false).is_some();
if !close_to_point && let Some(closest_segment) = shape_editor.upper_closest_segment(&document.network_interface, viewport_vec, tolerance) {
let pos = closest_segment.closest_point_to_viewport();
let perp = closest_segment.calculate_perp(document);
overlay_context.manipulator_anchor(pos, true, None);
@@ -1689,10 +1667,8 @@ impl Fsm for PenToolFsmState {
}
// If a vector mesh then there can be more than one prior segments
else if let Some(segments) = tool_data.prior_segments.clone() {
if preferences.vector_meshes {
let selected_anchors_data = HashMap::from([(layer, segments)]);
path_overlays(document, DrawHandles::SelectedAnchors(selected_anchors_data), shape_editor, &mut overlay_context);
}
let selected_anchors_data = HashMap::from([(layer, segments)]);
path_overlays(document, DrawHandles::SelectedAnchors(selected_anchors_data), shape_editor, &mut overlay_context);
} else {
path_overlays(document, DrawHandles::None, shape_editor, &mut overlay_context);
};
@@ -1755,12 +1731,12 @@ impl Fsm for PenToolFsmState {
overlay_context.manipulator_anchor(next_anchor, false, None);
}
if self == PenToolFsmState::PlacingAnchor && preferences.vector_meshes {
if self == PenToolFsmState::PlacingAnchor {
let tolerance = crate::consts::SNAP_POINT_TOLERANCE;
let point = SnapCandidatePoint::handle(document.metadata().document_to_viewport.inverse().transform_point2(input.mouse.position));
let snapped = tool_data.snap_manager.free_snap(&SnapData::new(document, input, viewport), &point, SnapTypeConfiguration::default());
let viewport = document.metadata().document_to_viewport.transform_point2(snapped.snapped_point_document);
let close_to_point = closest_point(document, viewport, tolerance, document.metadata().all_layers(), |_| false, preferences).is_some();
let close_to_point = closest_point(document, viewport, tolerance, document.metadata().all_layers(), |_| false).is_some();
if !close_to_point && let Some(closest_segment) = shape_editor.upper_closest_segment(&document.network_interface, viewport, tolerance) {
let pos = closest_segment.closest_point_to_viewport();
let perp = closest_segment.calculate_perp(document);
@@ -1779,7 +1755,7 @@ impl Fsm for PenToolFsmState {
if let Some(layer) = layer
&& let Some(mut vector) = document.network_interface.compute_modified_vector(layer)
{
let closest_point = vector.extendable_points(preferences.vector_meshes).filter(|&id| id != start).find(|&id| {
let closest_point = vector.extendable_points().filter(|&id| id != start).find(|&id| {
vector.point_domain.position_from_id(id).is_some_and(|pos| {
let dist_sq = transform.transform_point2(pos).distance_squared(transform.transform_point2(next_point));
dist_sq < crate::consts::SNAP_POINT_TOLERANCE.powi(2)
@@ -1835,8 +1811,8 @@ impl Fsm for PenToolFsmState {
// Get the closest point and the segment it is on
let append = input.keyboard.key(append_to_selected);
tool_data.store_clicked_endpoint(document, &transform, input, viewport, preferences);
tool_data.create_initial_point(document, input, viewport, responses, tool_options, append, preferences, shape_editor);
tool_data.store_clicked_endpoint(document, &transform, input, viewport);
tool_data.create_initial_point(document, input, viewport, responses, tool_options, append, shape_editor);
// Enter the dragging handle state while the mouse is held down, allowing the user to move the mouse and position the handle
PenToolFsmState::DraggingHandle(tool_data.handle_mode)
@@ -1860,8 +1836,8 @@ impl Fsm for PenToolFsmState {
if let Some(layer) = layer {
tool_data.buffering_merged_vector = false;
tool_data.handle_mode = HandleMode::ColinearLocked;
tool_data.bend_from_previous_point(SnapData::new(document, input, viewport), transform, layer, preferences, shape_editor, responses);
tool_data.place_anchor(SnapData::new(document, input, viewport), transform, input.mouse.position, preferences, responses);
tool_data.bend_from_previous_point(SnapData::new(document, input, viewport), transform, layer, shape_editor, responses);
tool_data.place_anchor(SnapData::new(document, input, viewport), transform, input.mouse.position, responses);
}
tool_data.buffering_merged_vector = false;
PenToolFsmState::DraggingHandle(tool_data.handle_mode)
@@ -1876,7 +1852,7 @@ impl Fsm for PenToolFsmState {
let layers = LayerNodeIdentifier::ROOT_PARENT
.descendants(document.metadata())
.filter(|layer| !document.network_interface.is_artboard(&layer.to_node(), &[]));
if let Some((other_layer, _, _)) = should_extend(document, viewport_vec, crate::consts::SNAP_POINT_TOLERANCE, layers, preferences) {
if let Some((other_layer, _, _)) = should_extend(document, viewport_vec, crate::consts::SNAP_POINT_TOLERANCE, layers) {
let selected_nodes = document.network_interface.selected_nodes();
let mut selected_layers = selected_nodes.selected_layers(document.metadata());
if let Some(current_layer) = selected_layers
@@ -1906,7 +1882,7 @@ impl Fsm for PenToolFsmState {
(PenToolFsmState::DraggingHandle(_), PenToolMessage::DragStop) => {
tool_data.cleanup_target_selections(shape_editor, layer, document, responses);
tool_data
.finish_placing_handle(SnapData::new(document, input, viewport), transform, preferences, responses)
.finish_placing_handle(SnapData::new(document, input, viewport), transform, responses)
.unwrap_or(PenToolFsmState::PlacingAnchor)
}
(
@@ -2025,7 +2001,7 @@ impl Fsm for PenToolFsmState {
move_anchor_with_handles: input.keyboard.key(move_anchor_with_handles),
};
let state = tool_data
.place_anchor(SnapData::new(document, input, viewport), transform, input.mouse.position, preferences, responses)
.place_anchor(SnapData::new(document, input, viewport), transform, input.mouse.position, responses)
.unwrap_or(PenToolFsmState::Ready);
// Auto-panning
@@ -2132,7 +2108,7 @@ impl Fsm for PenToolFsmState {
// Confirm to end path
if let Some((vector, layer)) = layer.and_then(|layer| document.network_interface.compute_modified_vector(layer)).zip(layer) {
let single_point_in_layer = vector.point_domain.ids().len() == 1;
tool_data.finish_placing_handle(SnapData::new(document, input, viewport), transform, preferences, responses);
tool_data.finish_placing_handle(SnapData::new(document, input, viewport), transform, responses);
let latest_points = tool_data.latest_points.len() == 1;
if latest_points && single_point_in_layer {
@@ -2179,7 +2155,7 @@ impl Fsm for PenToolFsmState {
PenToolFsmState::Ready
} else {
tool_data
.place_anchor(SnapData::new(document, input, viewport), transform, input.mouse.position, preferences, responses)
.place_anchor(SnapData::new(document, input, viewport), transform, input.mouse.position, responses)
.unwrap_or(PenToolFsmState::Ready)
}
}
@@ -2210,7 +2186,7 @@ impl Fsm for PenToolFsmState {
if tool_data.point_index > 0 {
tool_data.point_index -= 1;
tool_data
.place_anchor(SnapData::new(document, input, viewport), transform, input.mouse.position, preferences, responses)
.place_anchor(SnapData::new(document, input, viewport), transform, input.mouse.position, responses)
.unwrap_or(PenToolFsmState::PlacingAnchor)
} else {
responses.add(PenToolMessage::Abort);
@@ -2219,7 +2195,7 @@ impl Fsm for PenToolFsmState {
}
(_, PenToolMessage::Redo) => {
tool_data.point_index = (tool_data.point_index + 1).min(tool_data.latest_points.len().saturating_sub(1));
tool_data.place_anchor(SnapData::new(document, input, viewport), transform, input.mouse.position, preferences, responses);
tool_data.place_anchor(SnapData::new(document, input, viewport), transform, input.mouse.position, responses);
match tool_data.point_index {
0 => PenToolFsmState::Ready,
_ => PenToolFsmState::PlacingAnchor,
@@ -556,7 +556,6 @@ impl Fsm for ShapeToolFsmState {
document,
global_tool_data,
input,
preferences,
shape_editor,
viewport,
..
@@ -762,7 +761,6 @@ impl Fsm for ShapeToolFsmState {
SNAP_POINT_TOLERANCE,
document.network_interface.selected_nodes().selected_visible_and_unlocked_layers(&document.network_interface),
|_| false,
preferences,
) && clicked_on_line_endpoints(layer, document, input, tool_data)
&& !input.keyboard.key(Key::Control)
{
@@ -294,7 +294,6 @@ impl Fsm for SplineToolFsmState {
global_tool_data,
input,
shape_editor,
preferences,
viewport,
..
} = tool_action_data;
@@ -303,7 +302,7 @@ impl Fsm for SplineToolFsmState {
match (self, event) {
(_, SplineToolMessage::CanvasTransformed) => self,
(_, SplineToolMessage::Overlays { context: mut overlay_context }) => {
path_endpoint_overlays(document, shape_editor, &mut overlay_context, preferences);
path_endpoint_overlays(document, shape_editor, &mut overlay_context);
tool_data.snap_manager.draw_overlays(SnapData::new(document, input, viewport), &mut overlay_context);
self
}
@@ -351,7 +350,7 @@ impl Fsm for SplineToolFsmState {
.filter(|layer| !document.network_interface.is_artboard(&layer.to_node(), &[]));
// Extend an endpoint of the selected path
if let Some((layer, point, position)) = should_extend(document, viewport_vec, SNAP_POINT_TOLERANCE, layers, preferences) {
if let Some((layer, point, position)) = should_extend(document, viewport_vec, SNAP_POINT_TOLERANCE, layers) {
if find_spline(document, layer).is_some() {
// If the point is the part of Spline then we extend it.
tool_data.current_layer = Some(layer);
@@ -417,7 +416,7 @@ impl Fsm for SplineToolFsmState {
extend_spline(tool_data, false, responses);
tool_data.preview_point = preview_point;
if try_merging_lastest_endpoint(document, tool_data, preferences).is_some() {
if try_merging_lastest_endpoint(document, tool_data).is_some() {
responses.add(SplineToolMessage::Confirm);
}
}
@@ -427,7 +426,7 @@ impl Fsm for SplineToolFsmState {
(SplineToolFsmState::Drawing, SplineToolMessage::PointerMove) => {
let Some(layer) = tool_data.current_layer else { return SplineToolFsmState::Ready };
let ignore = |cp: PointId| tool_data.preview_point.is_some_and(|pp| pp == cp) || tool_data.points.last().is_some_and(|(ep, _)| *ep == cp);
let join_point = closest_point(document, input.mouse.position, PATH_JOIN_THRESHOLD, vec![layer].into_iter(), ignore, preferences);
let join_point = closest_point(document, input.mouse.position, PATH_JOIN_THRESHOLD, vec![layer].into_iter(), ignore);
// Endpoints snapping
if let Some((_, _, point)) = join_point {
@@ -511,7 +510,7 @@ impl Fsm for SplineToolFsmState {
}
}
fn try_merging_lastest_endpoint(document: &DocumentMessageHandler, tool_data: &mut SplineToolData, preferences: &PreferencesMessageHandler) -> Option<()> {
fn try_merging_lastest_endpoint(document: &DocumentMessageHandler, tool_data: &mut SplineToolData) -> Option<()> {
if tool_data.points.len() < 2 {
return None;
};
@@ -526,7 +525,7 @@ fn try_merging_lastest_endpoint(document: &DocumentMessageHandler, tool_data: &m
let exclude = |p: PointId| preview_point.is_some_and(|pp| pp == p) || *last_endpoint == p;
let position = document.metadata().transform_to_viewport(current_layer).transform_point2(*last_endpoint_position);
let (layer, endpoint, _) = closest_point(document, position, PATH_JOIN_THRESHOLD, layers, exclude, preferences)?;
let (layer, endpoint, _) = closest_point(document, position, PATH_JOIN_THRESHOLD, layers, exclude)?;
tool_data.merge_layers.insert(layer);
tool_data.merge_endpoints.push((EndpointPosition::End, endpoint));
@@ -647,7 +646,7 @@ mod test_spline_tool {
let layer_to_viewport = document.metadata().transform_to_viewport(spline_layer);
let endpoints: Vec<(PointId, DVec2)> = first_vector
.extendable_points(false)
.extendable_points_no_vector_meshes()
.filter_map(|point_id| first_vector.point_domain.position_from_id(point_id).map(|pos| (point_id, layer_to_viewport.transform_point2(pos))))
.collect();