Add nondestructive vector editing (#1676)

* 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

* Improve pen tool avoiding handle placement

* Improve disolve

* Remove pivot widget from Transform node properties

* Fix demo art

* Fix bugs

* Re-save demo artwork

* Code review

* Serialize hashmap as tuple vec to enable deserialize_inputs

* Fix migrate

* Add document upgrade function to editor_api.rs

* Finalize document upgrading

* Rename to the Path node

* Remove smoothing from Freehand tool

* Upgrade demo artwork

* Propertly disable raw-rs tests

---------

Co-authored-by: Keavon Chambers <keavon@keavon.com>
Co-authored-by: Adam <adamgerhant@gmail.com>
Co-authored-by: Dennis Kobert <dennis@kobert.dev>
This commit is contained in:
James Lindsay
2024-07-05 13:42:40 -07:00
committed by GitHub
co-authored by Keavon Chambers Adam Dennis Kobert
parent fd3613018a
commit 1652c713a6
96 changed files with 3343 additions and 2622 deletions
@@ -1,17 +1,20 @@
mod grid_snapper;
mod layer_snapper;
mod snap_results;
pub use {grid_snapper::*, layer_snapper::*, snap_results::*};
use crate::consts::COLOR_OVERLAY_BLUE;
use crate::messages::portfolio::document::overlays::utility_types::OverlayContext;
use crate::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier;
use crate::messages::portfolio::document::utility_types::misc::{BoundingBoxSnapTarget, GeometrySnapTarget, GridSnapTarget, SnapTarget};
use crate::messages::prelude::*;
use bezier_rs::{Subpath, TValue};
use glam::{DAffine2, DVec2};
use graphene_core::renderer::Quad;
use graphene_core::uuid::ManipulatorGroupId;
use graphene_core::vector::PointId;
use glam::{DAffine2, DVec2};
use std::cmp::Ordering;
pub use {grid_snapper::*, layer_snapper::*, snap_results::*};
/// Handles snapping and snap overlays
#[derive(Debug, Clone, Default)]
@@ -150,7 +153,7 @@ pub struct SnapData<'a> {
pub document: &'a DocumentMessageHandler,
pub input: &'a InputPreprocessorMessageHandler,
pub ignore: &'a [LayerNodeIdentifier],
pub manipulators: Vec<(LayerNodeIdentifier, ManipulatorGroupId)>,
pub manipulators: Vec<(LayerNodeIdentifier, PointId)>,
pub candidates: Option<&'a Vec<LayerNodeIdentifier>>,
}
impl<'a> SnapData<'a> {
@@ -172,7 +175,7 @@ impl<'a> SnapData<'a> {
fn ignore_bounds(&self, layer: LayerNodeIdentifier) -> bool {
self.manipulators.iter().any(|&(ignore, _)| ignore == layer)
}
fn ignore_manipulator(&self, layer: LayerNodeIdentifier, manipulator: impl Into<ManipulatorGroupId>) -> bool {
fn ignore_manipulator(&self, layer: LayerNodeIdentifier, manipulator: impl Into<PointId>) -> bool {
self.manipulators.contains(&(layer, manipulator.into()))
}
}
@@ -277,10 +280,8 @@ impl SnapManager {
}
}
if let Some(root) = snap_data.document.network.get_root_node() {
if snap_data.document.network.nodes.get(&root.id).expect("Root should always be a node in find_candidates").is_layer {
add_candidates(LayerNodeIdentifier::new(root.id, &snap_data.document.network), snap_data, quad, &mut candidates);
}
for layer in LayerNodeIdentifier::ROOT_PARENT.children(&document.metadata) {
add_candidates(layer, snap_data, quad, &mut candidates);
}
if candidates.len() > 10 {
@@ -333,7 +334,7 @@ impl SnapManager {
if let Some(ind) = &self.indicator {
for curve in &ind.curves {
let Some(curve) = curve else { continue };
overlay_context.outline::<ManipulatorGroupId>([Subpath::from_bezier(curve)].iter(), to_viewport);
overlay_context.outline([Subpath::from_bezier(curve)].iter(), to_viewport);
}
if let Some(quad) = ind.target_bounds {
overlay_context.quad(to_viewport * quad);