mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-10-03 11:18:11 +08:00
Fix quick measuring of skewed and rotated layers by using the viewport space AABB (#2396)
* Make sure that quick measure overlays are based on AABBs drawn in the viewport local space * Draw overlays to visualise AABBs of selected and hovered shapes * use pre-existing functions to render dashed lines * Redraw selected bounds using existing BoundingBoxManager * remove unused variables * Render transform cage after overlay is drawn * Bring overlay and transform cage render calls above(before) other gizmos * Add line length tolerance and render single line for singal edge alignment with one axis overlap * Comments --------- Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
co-authored by
Keavon Chambers
parent
2bcfe5ea0c
commit
927d7dd9b2
@@ -544,13 +544,56 @@ impl Fsm for SelectToolFsmState {
|
||||
})
|
||||
.reduce(graphene_core::renderer::Quad::combine_bounds);
|
||||
|
||||
// When not in Drawing State
|
||||
// Only highlight layers if the viewport is not being panned (middle mouse button is pressed)
|
||||
// TODO: Don't use `Key::MouseMiddle` directly, instead take it as a variable from the input mappings list like in all other places; or find a better way than checking the key state
|
||||
if !matches!(self, Self::Drawing { .. }) && !input.keyboard.get(Key::MouseMiddle as usize) {
|
||||
// Get the layer the user is hovering over
|
||||
let click = document.click(input);
|
||||
let not_selected_click = click.filter(|&hovered_layer| !document.network_interface.selected_nodes().selected_layers_contains(hovered_layer, document.metadata()));
|
||||
if let Some(layer) = not_selected_click {
|
||||
overlay_context.outline(document.metadata().layer_outline(layer), document.metadata().transform_to_viewport(layer));
|
||||
|
||||
// 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 !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
|
||||
.network_interface
|
||||
.selected_nodes()
|
||||
.selected_visible_and_unlocked_layers(&document.network_interface)
|
||||
.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()))
|
||||
})
|
||||
.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())
|
||||
});
|
||||
|
||||
// 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 let Some(bounds) = bounds {
|
||||
let bounding_box_manager = tool_data.bounding_box_manager.get_or_insert(BoundingBoxManager::default());
|
||||
|
||||
bounding_box_manager.bounds = bounds;
|
||||
bounding_box_manager.transform = transform;
|
||||
bounding_box_manager.transform_tampered = transform_tampered;
|
||||
|
||||
bounding_box_manager.render_overlays(&mut overlay_context);
|
||||
} else {
|
||||
tool_data.bounding_box_manager.take();
|
||||
@@ -722,29 +765,6 @@ impl Fsm for SelectToolFsmState {
|
||||
(SelectionShapeType::Lasso, _) => overlay_context.polygon(polygon, fill_color),
|
||||
}
|
||||
}
|
||||
// Only highlight layers if the viewport is not being panned (middle mouse button is pressed)
|
||||
// TODO: Don't use `Key::Mmb` directly, instead take it as a variable from the input mappings list like in all other places
|
||||
else if !input.keyboard.get(Key::MouseMiddle as usize) {
|
||||
// Get the layer the user is hovering over
|
||||
let click = document.click(input);
|
||||
let not_selected_click = click.filter(|&hovered_layer| !document.network_interface.selected_nodes().selected_layers_contains(hovered_layer, document.metadata()));
|
||||
if let Some(layer) = not_selected_click {
|
||||
overlay_context.outline(document.metadata().layer_outline(layer), document.metadata().transform_to_viewport(layer));
|
||||
|
||||
// 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 !matches!(self, Self::ResizingBounds { .. }) && input.keyboard.get(Key::Alt as usize) {
|
||||
let hovered_bounds = document
|
||||
.metadata()
|
||||
.bounding_box_with_transform(layer, transform.inverse() * document.metadata().transform_to_viewport(layer));
|
||||
|
||||
if let [Some(selected_bounds), Some(hovered_bounds)] = [bounds, hovered_bounds].map(|rect| rect.map(Rect::from_box)) {
|
||||
measure::overlay(selected_bounds, hovered_bounds, transform, document.metadata().document_to_viewport, &mut overlay_context);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self
|
||||
}
|
||||
(_, SelectToolMessage::EditLayer) => {
|
||||
|
||||
Reference in New Issue
Block a user