fix quick drags of control points
This commit is contained in:
parent
ffb53884b0
commit
f1df85baa2
|
|
@ -449,15 +449,25 @@ pub fn hit_test_vector_editing(
|
||||||
let inverse_transform = combined_transform.inverse();
|
let inverse_transform = combined_transform.inverse();
|
||||||
let local_point = inverse_transform * point;
|
let local_point = inverse_transform * point;
|
||||||
|
|
||||||
|
// Calculate the scale factor to transform screen-space tolerances to local space
|
||||||
|
// We need the inverse scale because we're in local space
|
||||||
|
// Affine coefficients are [a, b, c, d, e, f] representing matrix [[a, c, e], [b, d, f]]
|
||||||
|
let coeffs = combined_transform.as_coeffs();
|
||||||
|
let scale_x = (coeffs[0].powi(2) + coeffs[1].powi(2)).sqrt();
|
||||||
|
let scale_y = (coeffs[2].powi(2) + coeffs[3].powi(2)).sqrt();
|
||||||
|
let avg_scale = (scale_x + scale_y) / 2.0;
|
||||||
|
let local_tolerance_factor = 1.0 / avg_scale.max(0.001); // Avoid division by zero
|
||||||
|
|
||||||
// Extract editable curves and vertices from the shape's path
|
// Extract editable curves and vertices from the shape's path
|
||||||
let editable = extract_editable_curves(shape.path());
|
let editable = extract_editable_curves(shape.path());
|
||||||
|
|
||||||
// Priority 1: Control points (only in BezierEdit mode)
|
// Priority 1: Control points (only in BezierEdit mode)
|
||||||
if show_control_points {
|
if show_control_points {
|
||||||
|
let local_cp_tolerance = tolerance.control_point * local_tolerance_factor;
|
||||||
for (i, curve) in editable.curves.iter().enumerate() {
|
for (i, curve) in editable.curves.iter().enumerate() {
|
||||||
// Test p1 (first control point)
|
// Test p1 (first control point)
|
||||||
let dist_p1 = (curve.p1 - local_point).hypot();
|
let dist_p1 = (curve.p1 - local_point).hypot();
|
||||||
if dist_p1 < tolerance.control_point {
|
if dist_p1 < local_cp_tolerance {
|
||||||
return Some(VectorEditHit::ControlPoint {
|
return Some(VectorEditHit::ControlPoint {
|
||||||
shape_instance_id: object.id,
|
shape_instance_id: object.id,
|
||||||
curve_index: i,
|
curve_index: i,
|
||||||
|
|
@ -467,7 +477,7 @@ pub fn hit_test_vector_editing(
|
||||||
|
|
||||||
// Test p2 (second control point)
|
// Test p2 (second control point)
|
||||||
let dist_p2 = (curve.p2 - local_point).hypot();
|
let dist_p2 = (curve.p2 - local_point).hypot();
|
||||||
if dist_p2 < tolerance.control_point {
|
if dist_p2 < local_cp_tolerance {
|
||||||
return Some(VectorEditHit::ControlPoint {
|
return Some(VectorEditHit::ControlPoint {
|
||||||
shape_instance_id: object.id,
|
shape_instance_id: object.id,
|
||||||
curve_index: i,
|
curve_index: i,
|
||||||
|
|
@ -478,9 +488,10 @@ pub fn hit_test_vector_editing(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Priority 2: Vertices (anchor points)
|
// Priority 2: Vertices (anchor points)
|
||||||
|
let local_vertex_tolerance = tolerance.vertex * local_tolerance_factor;
|
||||||
for (i, vertex) in editable.vertices.iter().enumerate() {
|
for (i, vertex) in editable.vertices.iter().enumerate() {
|
||||||
let dist = (vertex.point - local_point).hypot();
|
let dist = (vertex.point - local_point).hypot();
|
||||||
if dist < tolerance.vertex {
|
if dist < local_vertex_tolerance {
|
||||||
return Some(VectorEditHit::Vertex {
|
return Some(VectorEditHit::Vertex {
|
||||||
shape_instance_id: object.id,
|
shape_instance_id: object.id,
|
||||||
vertex_index: i,
|
vertex_index: i,
|
||||||
|
|
@ -489,11 +500,12 @@ pub fn hit_test_vector_editing(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Priority 3: Curves
|
// Priority 3: Curves
|
||||||
|
let local_curve_tolerance = tolerance.curve * local_tolerance_factor;
|
||||||
for (i, curve) in editable.curves.iter().enumerate() {
|
for (i, curve) in editable.curves.iter().enumerate() {
|
||||||
let nearest = curve.nearest(local_point, 1e-6);
|
let nearest = curve.nearest(local_point, 1e-6);
|
||||||
let nearest_point = curve.eval(nearest.t);
|
let nearest_point = curve.eval(nearest.t);
|
||||||
let dist = (nearest_point - local_point).hypot();
|
let dist = (nearest_point - local_point).hypot();
|
||||||
if dist < tolerance.curve {
|
if dist < local_curve_tolerance {
|
||||||
return Some(VectorEditHit::Curve {
|
return Some(VectorEditHit::Curve {
|
||||||
shape_instance_id: object.id,
|
shape_instance_id: object.id,
|
||||||
curve_index: i,
|
curve_index: i,
|
||||||
|
|
|
||||||
|
|
@ -2063,9 +2063,10 @@ impl StagePane {
|
||||||
|
|
||||||
let point = Point::new(world_pos.x as f64, world_pos.y as f64);
|
let point = Point::new(world_pos.x as f64, world_pos.y as f64);
|
||||||
|
|
||||||
// Mouse down: start interaction (use drag_started for immediate feedback)
|
// Mouse down: start interaction (check on initial press, not after drag starts)
|
||||||
// Scope this section to drop vector_layer borrow before drag handling
|
// Scope this section to drop vector_layer borrow before drag handling
|
||||||
if response.drag_started() || response.clicked() {
|
let mouse_pressed = ui.input(|i| i.pointer.primary_pressed());
|
||||||
|
if mouse_pressed {
|
||||||
// VECTOR EDITING: Check for vertex/curve editing first (higher priority than selection)
|
// VECTOR EDITING: Check for vertex/curve editing first (higher priority than selection)
|
||||||
let tolerance = EditingHitTolerance::scaled_by_zoom(self.zoom as f64);
|
let tolerance = EditingHitTolerance::scaled_by_zoom(self.zoom as f64);
|
||||||
let vector_hit = hit_test_vector_editing(
|
let vector_hit = hit_test_vector_editing(
|
||||||
|
|
@ -2746,8 +2747,9 @@ impl StagePane {
|
||||||
true, // BezierEdit tool shows control points
|
true, // BezierEdit tool shows control points
|
||||||
);
|
);
|
||||||
|
|
||||||
// Mouse down: start interaction
|
// Mouse down: start interaction (check on initial press, not after drag starts)
|
||||||
if response.drag_started() || response.clicked() {
|
let mouse_pressed = ui.input(|i| i.pointer.primary_pressed());
|
||||||
|
if mouse_pressed {
|
||||||
// Priority 1: Vector editing (control points, vertices, and curves)
|
// Priority 1: Vector editing (control points, vertices, and curves)
|
||||||
if let Some(hit) = vector_hit {
|
if let Some(hit) = vector_hit {
|
||||||
match hit {
|
match hit {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue