Skip to content

Commit 1b39e71

Browse files
4adexKeavon
andauthored
Fix the Path tool's segment insertion line overlay having hysteresis with distance away from the cursor (#2677)
* Fix hysteresis in segment insertion * Update editor/src/messages/tool/common_functionality/shape_editor.rs * Update editor/src/messages/tool/common_functionality/shape_editor.rs * Fix insert point overlay --------- Co-authored-by: Keavon Chambers <keavon@keavon.com>
1 parent 26eac6b commit 1b39e71

3 files changed

Lines changed: 12 additions & 16 deletions

File tree

editor/src/consts.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ pub const MANIPULATOR_GROUP_MARKER_SIZE: f64 = 6.;
102102
pub const SELECTION_THRESHOLD: f64 = 10.;
103103
pub const HIDE_HANDLE_DISTANCE: f64 = 3.;
104104
pub const HANDLE_ROTATE_SNAP_ANGLE: f64 = 15.;
105-
pub const SEGMENT_INSERTION_DISTANCE: f64 = 7.5;
105+
pub const SEGMENT_INSERTION_DISTANCE: f64 = 8.;
106106
pub const SEGMENT_OVERLAY_SIZE: f64 = 10.;
107107
pub const HANDLE_LENGTH_FACTOR: f64 = 0.5;
108108

editor/src/messages/tool/common_functionality/shape_editor.rs

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use super::graph_modification_utils::{self, merge_layers};
1+
use super::graph_modification_utils::merge_layers;
22
use super::snapping::{SnapCache, SnapCandidatePoint, SnapData, SnapManager, SnappedPoint};
33
use super::utility_functions::calculate_segment_angle;
44
use crate::consts::HANDLE_LENGTH_FACTOR;
@@ -12,7 +12,6 @@ use crate::messages::tool::common_functionality::utility_functions::is_visible_p
1212
use crate::messages::tool::tool_messages::path_tool::{PathOverlayMode, PointSelectState};
1313
use bezier_rs::{Bezier, BezierHandles, Subpath, TValue};
1414
use glam::{DAffine2, DVec2};
15-
use graphene_core::transform::Transform;
1615
use graphene_core::vector::{ManipulatorPointId, PointId, VectorData, VectorModificationType};
1716
use graphene_std::vector::{HandleId, SegmentId};
1817

@@ -149,7 +148,6 @@ pub struct ClosestSegment {
149148
colinear: [Option<HandleId>; 2],
150149
t: f64,
151150
bezier_point_to_viewport: DVec2,
152-
stroke_width: f64,
153151
}
154152

155153
impl ClosestSegment {
@@ -169,6 +167,12 @@ impl ClosestSegment {
169167
self.bezier_point_to_viewport
170168
}
171169

170+
pub fn closest_point(&self, document_metadata: &DocumentMetadata) -> DVec2 {
171+
let transform = document_metadata.transform_to_viewport(self.layer);
172+
let bezier_point = self.bezier.evaluate(TValue::Parametric(self.t));
173+
transform.transform_point2(bezier_point)
174+
}
175+
172176
/// Updates this [`ClosestSegment`] with the viewport-space location of the closest point on the segment to the given mouse position.
173177
pub fn update_closest_point(&mut self, document_metadata: &DocumentMetadata, mouse_position: DVec2) {
174178
let transform = document_metadata.transform_to_viewport(self.layer);
@@ -186,10 +190,8 @@ impl ClosestSegment {
186190
self.bezier_point_to_viewport.distance_squared(mouse_position)
187191
}
188192

189-
pub fn too_far(&self, mouse_position: DVec2, tolerance: f64, document_metadata: &DocumentMetadata) -> bool {
190-
let dist_sq = self.distance_squared(mouse_position);
191-
let stroke_width = document_metadata.document_to_viewport.decompose_scale().x.max(1.) * self.stroke_width;
192-
(stroke_width + tolerance).powi(2) < dist_sq
193+
pub fn too_far(&self, mouse_position: DVec2, tolerance: f64) -> bool {
194+
tolerance.powi(2) < self.distance_squared(mouse_position)
193195
}
194196

195197
pub fn handle_positions(&self, document_metadata: &DocumentMetadata) -> (Option<DVec2>, Option<DVec2>) {
@@ -1449,11 +1451,6 @@ impl ShapeState {
14491451
if distance_squared < closest_distance_squared {
14501452
closest_distance_squared = distance_squared;
14511453

1452-
// 0.5 is half the line (center to side) but it's convenient to allow targeting slightly more than half the line width
1453-
const STROKE_WIDTH_PERCENT: f64 = 0.7;
1454-
1455-
let stroke_width = graph_modification_utils::get_stroke_width(layer, network_interface).unwrap_or(1.) as f64 * STROKE_WIDTH_PERCENT;
1456-
14571454
// Convert to linear if handes are on top of control points
14581455
if let bezier_rs::BezierHandles::Cubic { handle_start, handle_end } = bezier.handles {
14591456
if handle_start.abs_diff_eq(bezier.start(), f64::EPSILON * 100.) && handle_end.abs_diff_eq(bezier.end(), f64::EPSILON * 100.) {
@@ -1474,7 +1471,6 @@ impl ShapeState {
14741471
t,
14751472
bezier_point_to_viewport: screenspace,
14761473
layer,
1477-
stroke_width,
14781474
});
14791475
}
14801476
}

editor/src/messages/tool/tool_messages/path_tool.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1129,7 +1129,7 @@ impl Fsm for PathToolFsmState {
11291129
Self::Ready => {
11301130
if let Some(closest_segment) = &tool_data.segment {
11311131
let perp = closest_segment.calculate_perp(document);
1132-
let point = closest_segment.closest_point_to_viewport();
1132+
let point = closest_segment.closest_point(document.metadata());
11331133

11341134
// Draw an X on the segment
11351135
if tool_data.delete_segment_pressed {
@@ -1400,7 +1400,7 @@ impl Fsm for PathToolFsmState {
14001400
// If already hovering on a segment, then recalculate its closest point
14011401
else if let Some(closest_segment) = &mut tool_data.segment {
14021402
closest_segment.update_closest_point(document.metadata(), input.mouse.position);
1403-
if closest_segment.too_far(input.mouse.position, SEGMENT_INSERTION_DISTANCE, document.metadata()) {
1403+
if closest_segment.too_far(input.mouse.position, SEGMENT_INSERTION_DISTANCE) {
14041404
tool_data.segment = None;
14051405
}
14061406
responses.add(OverlaysMessage::Draw)

0 commit comments

Comments
 (0)