Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 21 additions & 4 deletions editor/src/messages/tool/tool_messages/select_tool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -512,7 +512,6 @@ struct SelectToolData {
selected_layers_changed: bool,
snap_candidates: Vec<SnapCandidatePoint>,
auto_panning: AutoPanning,
drag_start_center: ViewportPosition,
}

impl SelectToolData {
Expand All @@ -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)
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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.
Expand Down
Loading