Snapping improvements (#1567)
This commit is contained in:
parent
456ca170a4
commit
bf0ec2c9c8
|
|
@ -77,7 +77,7 @@ impl Default for SnappingState {
|
||||||
edges: true,
|
edges: true,
|
||||||
corners: true,
|
corners: true,
|
||||||
edge_midpoints: false,
|
edge_midpoints: false,
|
||||||
centres: false,
|
centres: true,
|
||||||
},
|
},
|
||||||
nodes: NodeSnapping {
|
nodes: NodeSnapping {
|
||||||
paths: true,
|
paths: true,
|
||||||
|
|
@ -245,6 +245,9 @@ impl SnapSource {
|
||||||
pub fn is_some(&self) -> bool {
|
pub fn is_some(&self) -> bool {
|
||||||
self != &Self::None
|
self != &Self::None
|
||||||
}
|
}
|
||||||
|
pub fn bounding_box(&self) -> bool {
|
||||||
|
matches!(self, Self::BoundingBox(_) | Self::Board(_))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
pub enum BoundingBoxSnapTarget {
|
pub enum BoundingBoxSnapTarget {
|
||||||
|
|
|
||||||
|
|
@ -98,7 +98,28 @@ impl ShapeState {
|
||||||
SnapSource::Geometry(GeometrySnapSource::Sharp)
|
SnapSource::Geometry(GeometrySnapSource::Sharp)
|
||||||
};
|
};
|
||||||
let Some(position) = handle.get_position(&group) else { continue };
|
let Some(position) = handle.get_position(&group) else { continue };
|
||||||
let point = SnapCandidatePoint::new_source(to_document.transform_point2(position) + mouse_delta, source);
|
let mut point = SnapCandidatePoint::new_source(to_document.transform_point2(position) + mouse_delta, source);
|
||||||
|
|
||||||
|
let mut push_neighbour = |group: ManipulatorGroup<ManipulatorGroupId>| {
|
||||||
|
if !state.is_selected(ManipulatorPointId::new(group.id, SelectedType::Anchor)) {
|
||||||
|
point.neighbors.push(group.anchor)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if handle == SelectedType::Anchor {
|
||||||
|
// Previous anchor (looping if closed)
|
||||||
|
if index > 0 {
|
||||||
|
push_neighbour(subpath.manipulator_groups()[index - 1]);
|
||||||
|
} else if subpath.closed() {
|
||||||
|
push_neighbour(subpath.manipulator_groups()[subpath.len() - 1]);
|
||||||
|
}
|
||||||
|
// Next anchor (looping if closed)
|
||||||
|
if index + 1 < subpath.len() {
|
||||||
|
push_neighbour(subpath.manipulator_groups()[index + 1]);
|
||||||
|
} else if subpath.closed() {
|
||||||
|
push_neighbour(subpath.manipulator_groups()[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let snapped = snap_manager.free_snap(&snap_data, &point, None, false);
|
let snapped = snap_manager.free_snap(&snap_data, &point, None, false);
|
||||||
if best_snapped.other_snap_better(&snapped) {
|
if best_snapped.other_snap_better(&snapped) {
|
||||||
offset = snapped.snapped_point_document - point.document_point + mouse_delta;
|
offset = snapped.snapped_point_document - point.document_point + mouse_delta;
|
||||||
|
|
|
||||||
|
|
@ -64,9 +64,9 @@ pub fn snap_tolerance(document: &DocumentMessageHandler) -> f64 {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compare_points(a: &&SnappedPoint, b: &&SnappedPoint) -> Ordering {
|
fn compare_points(a: &&SnappedPoint, b: &&SnappedPoint) -> Ordering {
|
||||||
if (a.target.bounding_box() && !b.target.bounding_box()) || (a.at_intersection && !b.at_intersection) {
|
if (a.target.bounding_box() && !b.target.bounding_box()) || (a.at_intersection && !b.at_intersection) || (a.source.bounding_box() && !b.source.bounding_box()) {
|
||||||
Ordering::Greater
|
Ordering::Greater
|
||||||
} else if (!a.target.bounding_box() && b.target.bounding_box()) || (!a.at_intersection && b.at_intersection) {
|
} else if (!a.target.bounding_box() && b.target.bounding_box()) || (!a.at_intersection && b.at_intersection) || (!a.source.bounding_box() && b.source.bounding_box()) {
|
||||||
Ordering::Less
|
Ordering::Less
|
||||||
} else {
|
} else {
|
||||||
a.distance.partial_cmp(&b.distance).unwrap()
|
a.distance.partial_cmp(&b.distance).unwrap()
|
||||||
|
|
|
||||||
|
|
@ -330,7 +330,7 @@ impl SnapCandidatePoint {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
struct BBoxSnapValues {
|
pub struct BBoxSnapValues {
|
||||||
corner_source: SnapSource,
|
corner_source: SnapSource,
|
||||||
corner_target: SnapTarget,
|
corner_target: SnapTarget,
|
||||||
edge_source: SnapSource,
|
edge_source: SnapSource,
|
||||||
|
|
@ -348,7 +348,7 @@ impl BBoxSnapValues {
|
||||||
centre_target: SnapTarget::BoundingBox(BoundingBoxSnapTarget::Centre),
|
centre_target: SnapTarget::BoundingBox(BoundingBoxSnapTarget::Centre),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
fn get_bbox_points(quad: Quad, points: &mut Vec<SnapCandidatePoint>, values: BBoxSnapValues, document: &DocumentMessageHandler) {
|
pub fn get_bbox_points(quad: Quad, points: &mut Vec<SnapCandidatePoint>, values: BBoxSnapValues, document: &DocumentMessageHandler) {
|
||||||
for index in 0..4 {
|
for index in 0..4 {
|
||||||
let start = quad.0[index];
|
let start = quad.0[index];
|
||||||
let end = quad.0[(index + 1) % 4];
|
let end = quad.0[(index + 1) % 4];
|
||||||
|
|
|
||||||
|
|
@ -281,6 +281,10 @@ impl SelectToolData {
|
||||||
self.snap_candidates.clear();
|
self.snap_candidates.clear();
|
||||||
for &layer in &self.layers_dragging {
|
for &layer in &self.layers_dragging {
|
||||||
snapping::get_layer_snap_points(layer, &SnapData::new(document, input), &mut self.snap_candidates);
|
snapping::get_layer_snap_points(layer, &SnapData::new(document, input), &mut self.snap_candidates);
|
||||||
|
if let Some(bounds) = document.metadata.bounding_box_with_transform(layer, DAffine2::IDENTITY) {
|
||||||
|
let quad = document.metadata.transform_to_document(layer) * Quad::from_box(bounds);
|
||||||
|
snapping::get_bbox_points(quad, &mut self.snap_candidates, snapping::BBoxSnapValues::BOUNDING_BOX, document);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue