Fix the Shift-drag alignment guide anchoring to the prior selection instead of the dragged layer (#4278)

This commit is contained in:
Keavon Chambers
2026-06-23 02:28:06 -07:00
committed by GitHub
parent 03c33dc784
commit ebbbb6bd1b

View File

@@ -512,7 +512,6 @@ struct SelectToolData {
selected_layers_changed: bool,
snap_candidates: Vec<SnapCandidatePoint>,
auto_panning: AutoPanning,
drag_start_center: ViewportPosition,
}
impl SelectToolData {
@@ -529,6 +528,15 @@ impl SelectToolData {
}
}
/// The center of the combined viewport-space bounding box of the layers currently being dragged.
fn dragging_layers_center(&self, document: &DocumentMessageHandler) -> Option<ViewportPosition> {
self.layers_dragging
.iter()
.filter_map(|&layer| document.metadata().bounding_box_viewport(layer).map(Rect::from_box))
.reduce(Rect::combine_bounds)
.map(|bounds| bounds.center())
}
pub fn selection_quad(&self) -> Quad {
let bbox = self.selection_box();
Quad::from_box(bbox)
@@ -1021,7 +1029,18 @@ impl Fsm for SelectToolFsmState {
let angle = -mouse_position.angle_to(DVec2::X);
let snapped_angle = (angle / snap_resolution).round() * snap_resolution;
let origin = tool_data.drag_start_center;
// Anchor the guide to the dragged layers' center at the moment the drag began. It's computed live (rather than
// snapshotted at drag start) so it stays correct as the layers move and the viewport auto-pans: their current
// center minus the drag displacement recovers the start center in the present viewport frame. Sourcing it from
// the layers being dragged (not the prior selection's pivot) is what keeps it on the layer actually grabbed.
let origin = if matches!(self, Self::Dragging { .. }) {
tool_data
.dragging_layers_center(document)
.map(|center| center - (tool_data.drag_current - tool_data.drag_start))
.unwrap_or_else(|| tool_data.pivot_gizmo().position(document))
} else {
tool_data.pivot_gizmo().position(document)
};
let viewport_diagonal = viewport.size().into_dvec2().length();
let edge = DVec2::from_angle(snapped_angle).normalize_or(DVec2::X);
@@ -1132,8 +1151,6 @@ impl Fsm for SelectToolFsmState {
let position = tool_data.pivot_gizmo().position(document);
let (resize, rotate, skew) = transforming_transform_cage(document, &mut tool_data.bounding_box_manager, input, responses, &mut tool_data.layers_dragging, Some(position));
tool_data.drag_start_center = position;
// If the user is dragging the bounding box bounds, go into ResizingBounds mode.
// If the user is dragging the rotate trigger, go into RotatingBounds mode.
// If the user clicks on a layer that is in their current selection, go into the dragging mode.