Skip to content

Commit 0a4a822

Browse files
Fix Alt-based quick measurement to show document space coordinates instead of viewport space (#2995)
Co-authored-by: Keavon Chambers <[email protected]>
1 parent 4da732d commit 0a4a822

File tree

2 files changed

+23
-26
lines changed

2 files changed

+23
-26
lines changed

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

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,18 +43,19 @@ fn draw_line_with_length(line_start: DVec2, line_end: DVec2, transform: DAffine2
4343
}
4444
}
4545

46-
/// Draws a dashed outline around a rectangle to visualize the AABB
46+
/// Draws a dashed outline around the given rectangle (assumed to be in document space).
47+
/// The provided transform is applied to convert coordinates (e.g., to viewport space) during rendering.
4748
fn draw_dashed_rect_outline(rect: Rect, transform: DAffine2, overlay_context: &mut OverlayContext) {
4849
let min = rect.min();
4950
let max = rect.max();
5051

51-
// Create the four corners of the rectangle
52-
let top_left = transform.transform_point2(DVec2::new(min.x, min.y));
53-
let top_right = transform.transform_point2(DVec2::new(max.x, min.y));
54-
let bottom_right = transform.transform_point2(DVec2::new(max.x, max.y));
55-
let bottom_left = transform.transform_point2(DVec2::new(min.x, max.y));
52+
// Define corners in document space
53+
let top_left = DVec2::new(min.x, min.y);
54+
let top_right = DVec2::new(max.x, min.y);
55+
let bottom_right = DVec2::new(max.x, max.y);
56+
let bottom_left = DVec2::new(min.x, max.y);
5657

57-
// Draw the four sides as dashed lines
58+
// Draw each edge using document-space coordinates; transform is applied inside draw_dashed_line
5859
draw_dashed_line(top_left, top_right, transform, overlay_context);
5960
draw_dashed_line(top_right, bottom_right, transform, overlay_context);
6061
draw_dashed_line(bottom_right, bottom_left, transform, overlay_context);

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

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -691,32 +691,28 @@ impl Fsm for SelectToolFsmState {
691691
// Measure with Alt held down
692692
// TODO: Don't use `Key::Alt` directly, instead take it as a variable from the input mappings list like in all other places
693693
if overlay_context.visibility_settings.quick_measurement() && !matches!(self, Self::ResizingBounds { .. }) && input.keyboard.get(Key::Alt as usize) {
694-
// Get all selected layers and compute their viewport-aligned AABB
695-
let selected_bounds_viewport = document
694+
// Compute document-space bounding box (AABB) of all selected visible & unlocked layers
695+
let selected_bounds_doc_space = document
696696
.network_interface
697697
.selected_nodes()
698698
.selected_visible_and_unlocked_layers(&document.network_interface)
699+
// Exclude layers that are artboards
699700
.filter(|layer| !document.network_interface.is_artboard(&layer.to_node(), &[]))
700-
.filter_map(|layer| {
701-
// Get the layer's bounding box in its local space
702-
let local_bounds = document.metadata().bounding_box_with_transform(layer, DAffine2::IDENTITY)?;
703-
// Transform the bounds directly to viewport space
704-
let viewport_quad = document.metadata().transform_to_viewport(layer) * Quad::from_box(local_bounds);
705-
// Convert the quad to an AABB in viewport space
706-
Some(Rect::from_box(viewport_quad.bounding_box()))
707-
})
701+
// For each remaining layer, try to get its document-space bounding box and convert it to a Rect
702+
.filter_map(|layer| document.metadata().bounding_box_document(layer).map(Rect::from_box))
703+
// Combine all individual bounding boxes into one overall bounding box that contains all selected layers
708704
.reduce(Rect::combine_bounds);
709705

710-
// Get the hovered layer's viewport-aligned AABB
711-
let hovered_bounds_viewport = document.metadata().bounding_box_with_transform(layer, DAffine2::IDENTITY).map(|bounds| {
712-
let viewport_quad = document.metadata().transform_to_viewport(layer) * Quad::from_box(bounds);
713-
Rect::from_box(viewport_quad.bounding_box())
714-
});
706+
// Compute document-space bounding box (AABB) of the currently hovered layer
707+
let hovered_bounds_doc_space = document.metadata().bounding_box_document(layer);
715708

716-
// Use the viewport-aligned AABBs for measurement
717-
if let (Some(selected_bounds), Some(hovered_bounds)) = (selected_bounds_viewport, hovered_bounds_viewport) {
718-
// Since we're already in viewport space, use identity transform
719-
measure::overlay(selected_bounds, hovered_bounds, DAffine2::IDENTITY, DAffine2::IDENTITY, &mut overlay_context);
709+
// If both selected and hovered bounds exist, overlay measurement lines
710+
if let (Some(selected_bounds), Some(hovered_bounds)) = (selected_bounds_doc_space, hovered_bounds_doc_space.map(Rect::from_box)) {
711+
// Both `selected_bounds` and `hovered_bounds` are in document space.
712+
// To correctly render overlay lines in the UI (which is in viewport space), we need to transform both rectangles from document to viewport space.
713+
// Therefore, we pass `document_to_viewport` as both the `transform` and `document_to_viewport` parameters.
714+
let document_to_viewport = document.metadata().document_to_viewport;
715+
measure::overlay(selected_bounds, hovered_bounds, document_to_viewport, document_to_viewport, &mut overlay_context);
720716
}
721717
}
722718
}

0 commit comments

Comments
 (0)