Fix Alt-based quick measurement to show document space coordinates instead of viewport space (#2995)
Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
parent
4da732dcc3
commit
0a4a822837
|
|
@ -43,18 +43,19 @@ fn draw_line_with_length(line_start: DVec2, line_end: DVec2, transform: DAffine2
|
|||
}
|
||||
}
|
||||
|
||||
/// Draws a dashed outline around a rectangle to visualize the AABB
|
||||
/// Draws a dashed outline around the given rectangle (assumed to be in document space).
|
||||
/// The provided transform is applied to convert coordinates (e.g., to viewport space) during rendering.
|
||||
fn draw_dashed_rect_outline(rect: Rect, transform: DAffine2, overlay_context: &mut OverlayContext) {
|
||||
let min = rect.min();
|
||||
let max = rect.max();
|
||||
|
||||
// Create the four corners of the rectangle
|
||||
let top_left = transform.transform_point2(DVec2::new(min.x, min.y));
|
||||
let top_right = transform.transform_point2(DVec2::new(max.x, min.y));
|
||||
let bottom_right = transform.transform_point2(DVec2::new(max.x, max.y));
|
||||
let bottom_left = transform.transform_point2(DVec2::new(min.x, max.y));
|
||||
// Define corners in document space
|
||||
let top_left = DVec2::new(min.x, min.y);
|
||||
let top_right = DVec2::new(max.x, min.y);
|
||||
let bottom_right = DVec2::new(max.x, max.y);
|
||||
let bottom_left = DVec2::new(min.x, max.y);
|
||||
|
||||
// Draw the four sides as dashed lines
|
||||
// Draw each edge using document-space coordinates; transform is applied inside draw_dashed_line
|
||||
draw_dashed_line(top_left, top_right, transform, overlay_context);
|
||||
draw_dashed_line(top_right, bottom_right, transform, overlay_context);
|
||||
draw_dashed_line(bottom_right, bottom_left, transform, overlay_context);
|
||||
|
|
|
|||
|
|
@ -691,32 +691,28 @@ impl Fsm for SelectToolFsmState {
|
|||
// Measure with Alt held down
|
||||
// TODO: Don't use `Key::Alt` directly, instead take it as a variable from the input mappings list like in all other places
|
||||
if overlay_context.visibility_settings.quick_measurement() && !matches!(self, Self::ResizingBounds { .. }) && input.keyboard.get(Key::Alt as usize) {
|
||||
// Get all selected layers and compute their viewport-aligned AABB
|
||||
let selected_bounds_viewport = document
|
||||
// Compute document-space bounding box (AABB) of all selected visible & unlocked layers
|
||||
let selected_bounds_doc_space = document
|
||||
.network_interface
|
||||
.selected_nodes()
|
||||
.selected_visible_and_unlocked_layers(&document.network_interface)
|
||||
// Exclude layers that are artboards
|
||||
.filter(|layer| !document.network_interface.is_artboard(&layer.to_node(), &[]))
|
||||
.filter_map(|layer| {
|
||||
// Get the layer's bounding box in its local space
|
||||
let local_bounds = document.metadata().bounding_box_with_transform(layer, DAffine2::IDENTITY)?;
|
||||
// Transform the bounds directly to viewport space
|
||||
let viewport_quad = document.metadata().transform_to_viewport(layer) * Quad::from_box(local_bounds);
|
||||
// Convert the quad to an AABB in viewport space
|
||||
Some(Rect::from_box(viewport_quad.bounding_box()))
|
||||
})
|
||||
// For each remaining layer, try to get its document-space bounding box and convert it to a Rect
|
||||
.filter_map(|layer| document.metadata().bounding_box_document(layer).map(Rect::from_box))
|
||||
// Combine all individual bounding boxes into one overall bounding box that contains all selected layers
|
||||
.reduce(Rect::combine_bounds);
|
||||
|
||||
// Get the hovered layer's viewport-aligned AABB
|
||||
let hovered_bounds_viewport = document.metadata().bounding_box_with_transform(layer, DAffine2::IDENTITY).map(|bounds| {
|
||||
let viewport_quad = document.metadata().transform_to_viewport(layer) * Quad::from_box(bounds);
|
||||
Rect::from_box(viewport_quad.bounding_box())
|
||||
});
|
||||
// Compute document-space bounding box (AABB) of the currently hovered layer
|
||||
let hovered_bounds_doc_space = document.metadata().bounding_box_document(layer);
|
||||
|
||||
// Use the viewport-aligned AABBs for measurement
|
||||
if let (Some(selected_bounds), Some(hovered_bounds)) = (selected_bounds_viewport, hovered_bounds_viewport) {
|
||||
// Since we're already in viewport space, use identity transform
|
||||
measure::overlay(selected_bounds, hovered_bounds, DAffine2::IDENTITY, DAffine2::IDENTITY, &mut overlay_context);
|
||||
// If both selected and hovered bounds exist, overlay measurement lines
|
||||
if let (Some(selected_bounds), Some(hovered_bounds)) = (selected_bounds_doc_space, hovered_bounds_doc_space.map(Rect::from_box)) {
|
||||
// Both `selected_bounds` and `hovered_bounds` are in document space.
|
||||
// To correctly render overlay lines in the UI (which is in viewport space), we need to transform both rectangles from document to viewport space.
|
||||
// Therefore, we pass `document_to_viewport` as both the `transform` and `document_to_viewport` parameters.
|
||||
let document_to_viewport = document.metadata().document_to_viewport;
|
||||
measure::overlay(selected_bounds, hovered_bounds, document_to_viewport, document_to_viewport, &mut overlay_context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue