Add basic artboard snapping (#1734)

* Initial vector modify node

* Initial extraction of data from monitor nodes

* Migrate to point id

* Start converting to modify node

* Non destructive spline tool (tout le reste est cassé)

* Fix unconnected modify node

* Fix freehand tool

* Pen tool

* Migrate demo art

* Select points

* Fix the demo artwork

* Fix the X and Y inputs for path tool

* G1 continous toggle

* Delete points

* Fix test

* Insert point

* Improve robustness of handles

* Fix GRS shortcuts on path

* Dragging points

* Fix build

* Preserve opposing handle lengths

* Update demo art and snapping

* Fix polygon tool

* Double click end anchor

* Improve dragging

* Fix text shifting

* Select only connected verts

* Colinear alt

* Cleanup

* Fix imports

* first commit

* changes in SnapData::ignore()

* Bug fixes and cleanup

* Code review

---------

Co-authored-by: 0hypercube <0hypercube@gmail.com>
Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
Sahil gill
2024-07-05 16:14:47 -07:00
committed by GitHub
co-authored by 0hypercube Keavon Chambers
parent 176ce314c7
commit e66620dc5c
4 changed files with 199 additions and 109 deletions
@@ -1,15 +1,15 @@
use super::*;
use crate::consts::HIDE_HANDLE_DISTANCE;
use crate::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier;
use crate::messages::portfolio::document::utility_types::misc::{
BoardSnapSource, BoardSnapTarget, BoundingBoxSnapSource, BoundingBoxSnapTarget, GeometrySnapSource, GeometrySnapTarget, SnapSource, SnapTarget,
};
use crate::messages::portfolio::document::utility_types::misc::*;
use crate::messages::prelude::*;
use bezier_rs::{Bezier, Identifier, Subpath, TValue};
use glam::{DAffine2, DVec2};
use graphene_core::renderer::Quad;
use graphene_core::vector::PointId;
use glam::{DAffine2, DVec2};
#[derive(Clone, Debug, Default)]
pub struct LayerSnapper {
points_to_snap: Vec<SnapCandidatePoint>,
@@ -21,13 +21,21 @@ impl LayerSnapper {
if !document.snapping_state.target_enabled(target) {
return;
}
let Some(bounds) = document.metadata.bounding_box_with_transform(layer, DAffine2::IDENTITY) else {
return;
let bounds = if document.metadata.is_artboard(layer) {
document.metadata.bounding_box_with_transform(layer, document.metadata.transform_to_document(layer)).map(Quad::from_box)
} else {
document
.metadata
.bounding_box_with_transform(layer, DAffine2::IDENTITY)
.map(|bounds| document.metadata.transform_to_document(layer) * Quad::from_box(bounds))
};
let bounds = document.metadata.transform_to_document(layer) * Quad::from_box(bounds);
let Some(bounds) = bounds else { return };
if bounds.0.iter().any(|point| !point.is_finite()) {
return;
}
for document_curve in bounds.bezier_lines() {
self.paths_to_snap.push(SnapCandidatePath {
document_curve,
@@ -46,7 +54,7 @@ impl LayerSnapper {
self.paths_to_snap.clear();
for layer in document.metadata.all_layers() {
if !document.metadata.is_artboard(layer) {
if !document.metadata.is_artboard(layer) || snap_data.ignore.contains(&layer) {
continue;
}
self.add_layer_bounds(document, layer, SnapTarget::Board(BoardSnapTarget::Edge));
@@ -168,22 +176,16 @@ impl LayerSnapper {
self.points_to_snap.clear();
for layer in document.metadata.all_layers() {
if !document.metadata.is_artboard(layer) {
if !document.metadata.is_artboard(layer) || snap_data.ignore.contains(&layer) {
continue;
}
if document.snapping_state.target_enabled(SnapTarget::Board(BoardSnapTarget::Corner)) {
let Some(bounds) = document.metadata.bounding_box_with_transform(layer, DAffine2::IDENTITY) else {
let Some(bounds) = document.metadata.bounding_box_with_transform(layer, document.metadata.transform_to_document(layer)) else {
continue;
};
let quad = document.metadata.transform_to_document(layer) * Quad::from_box(bounds);
let values = BBoxSnapValues {
corner_source: SnapSource::Board(BoardSnapSource::Corner),
corner_target: SnapTarget::Board(BoardSnapTarget::Corner),
center_source: SnapSource::Board(BoardSnapSource::Center),
center_target: SnapTarget::Board(BoardSnapTarget::Center),
..Default::default()
};
get_bbox_points(quad, &mut self.points_to_snap, values, document);
get_bbox_points(Quad::from_box(bounds), &mut self.points_to_snap, BBoxSnapValues::ARTBOARD, document);
}
}
for &layer in snap_data.get_candidates() {
@@ -351,6 +353,15 @@ impl BBoxSnapValues {
center_source: SnapSource::BoundingBox(BoundingBoxSnapSource::Center),
center_target: SnapTarget::BoundingBox(BoundingBoxSnapTarget::Center),
};
pub const ARTBOARD: Self = Self {
corner_source: SnapSource::Board(BoardSnapSource::Corner),
corner_target: SnapTarget::Board(BoardSnapTarget::Corner),
edge_source: SnapSource::None,
edge_target: SnapTarget::None,
center_source: SnapSource::Board(BoardSnapSource::Center),
center_target: SnapTarget::Board(BoardSnapTarget::Center),
};
}
pub fn get_bbox_points(quad: Quad, points: &mut Vec<SnapCandidatePoint>, values: BBoxSnapValues, document: &DocumentMessageHandler) {
for index in 0..4 {