mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-17 15:28:04 +08:00
Path Tool: Implement anchor point dragging (#451)
* #82 path-tool: WIP selecting control point working * Fix bug where duplication with Ctrl+D doesn't properly duplicate (#423) * bug fix: duplication didn't properly duplicate * cargo fmt * changed the formatting slightly for readability * Small cleanups, changed color of handles upon selection * Fix changes from merge * Remove duplicate anchor points on top of one another * Fix possible issues with thumbnails not being updated from Graphene operations * path-tool: attempt to move control points on click * Add dragging for control points * Editing shape anchors functional. Handles next. * Comment cleanup & slight cleanup of closest_anchor(..) * Removing conflict with master * Tiny code tweaks Co-authored-by: Keavon Chambers <keavon@keavon.com> Co-authored-by: caleb <56044292+caleb-ad@users.noreply.github.com> Co-authored-by: otdavies <oliver@psyfer.io> Co-authored-by: Dennis <dennis@kobert.dev>
This commit is contained in:
committed by
Keavon Chambers
parent
ddebaddd5d
commit
3f3ffbc82c
@@ -448,8 +448,8 @@ impl Document {
|
||||
|
||||
Some([vec![DocumentChanged, CreatedLayer { path: path.clone() }], update_thumbnails_upstream(path)].concat())
|
||||
}
|
||||
Operation::AddOverlayShape { path, style, bez_path } => {
|
||||
let mut shape = Shape::from_bez_path(bez_path.clone(), *style, false);
|
||||
Operation::AddOverlayShape { path, style, bez_path, closed } => {
|
||||
let mut shape = Shape::from_bez_path(bez_path.clone(), *style, *closed);
|
||||
shape.render_index = -1;
|
||||
|
||||
let layer = Layer::new(LayerDataType::Shape(shape), DAffine2::IDENTITY.to_cols_array());
|
||||
@@ -546,14 +546,14 @@ impl Document {
|
||||
self.set_layer(path, Layer::new(LayerDataType::Folder(Folder::default()), DAffine2::IDENTITY.to_cols_array()), -1)?;
|
||||
self.mark_as_dirty(path)?;
|
||||
|
||||
Some(vec![DocumentChanged, CreatedLayer { path: path.clone() }])
|
||||
Some([vec![DocumentChanged, CreatedLayer { path: path.clone() }], update_thumbnails_upstream(path)].concat())
|
||||
}
|
||||
Operation::TransformLayer { path, transform } => {
|
||||
let layer = self.layer_mut(path).unwrap();
|
||||
let transform = DAffine2::from_cols_array(transform) * layer.transform;
|
||||
layer.transform = transform;
|
||||
self.mark_as_dirty(path)?;
|
||||
Some(vec![DocumentChanged])
|
||||
Some([vec![DocumentChanged], update_thumbnails_upstream(path)].concat())
|
||||
}
|
||||
Operation::TransformLayerInViewport { path, transform } => {
|
||||
let transform = DAffine2::from_cols_array(transform);
|
||||
@@ -567,6 +567,17 @@ impl Document {
|
||||
self.mark_as_dirty(path)?;
|
||||
Some([vec![DocumentChanged], update_thumbnails_upstream(path)].concat())
|
||||
}
|
||||
Operation::SetShapePath { path, bez_path } => {
|
||||
self.mark_as_dirty(path)?;
|
||||
|
||||
match &mut self.layer_mut(path)?.data {
|
||||
LayerDataType::Shape(shape) => {
|
||||
shape.path = bez_path.clone();
|
||||
}
|
||||
LayerDataType::Folder(_) => (),
|
||||
}
|
||||
Some(vec![DocumentChanged, LayerChanged { path: path.clone() }])
|
||||
}
|
||||
Operation::SetShapePathInViewport { path, bez_path, transform } => {
|
||||
let transform = DAffine2::from_cols_array(transform);
|
||||
self.set_transform_relative_to_viewport(path, transform)?;
|
||||
@@ -578,7 +589,7 @@ impl Document {
|
||||
}
|
||||
LayerDataType::Folder(_) => (),
|
||||
}
|
||||
Some(vec![DocumentChanged, LayerChanged { path: path.clone() }])
|
||||
Some([vec![DocumentChanged, LayerChanged { path: path.clone() }], update_thumbnails_upstream(path)].concat())
|
||||
}
|
||||
Operation::TransformLayerInScope { path, transform, scope } => {
|
||||
let transform = DAffine2::from_cols_array(transform);
|
||||
@@ -632,7 +643,7 @@ impl Document {
|
||||
_ => return Err(DocumentError::NotAShape),
|
||||
}
|
||||
self.mark_as_dirty(path)?;
|
||||
Some(vec![DocumentChanged, LayerChanged { path: path.clone() }])
|
||||
Some([vec![DocumentChanged, LayerChanged { path: path.clone() }], update_thumbnails_upstream(path)].concat())
|
||||
}
|
||||
Operation::SetLayerFill { path, color } => {
|
||||
let layer = self.layer_mut(path)?;
|
||||
|
||||
@@ -26,7 +26,7 @@ pub struct Shape {
|
||||
pub path: BezPath,
|
||||
pub style: style::PathStyle,
|
||||
pub render_index: i32,
|
||||
pub solid: bool,
|
||||
pub closed: bool,
|
||||
}
|
||||
|
||||
impl LayerData for Shape {
|
||||
@@ -62,7 +62,7 @@ impl LayerData for Shape {
|
||||
}
|
||||
|
||||
fn intersects_quad(&self, quad: Quad, path: &mut Vec<LayerId>, intersections: &mut Vec<Vec<LayerId>>) {
|
||||
if intersect_quad_bez_path(quad, &self.path, self.solid) {
|
||||
if intersect_quad_bez_path(quad, &self.path, self.closed) {
|
||||
intersections.push(path.clone());
|
||||
}
|
||||
}
|
||||
@@ -78,12 +78,12 @@ impl Shape {
|
||||
transforms.iter().skip(start).cloned().reduce(|a, b| a * b).unwrap_or(DAffine2::IDENTITY)
|
||||
}
|
||||
|
||||
pub fn from_bez_path(bez_path: BezPath, style: PathStyle, solid: bool) -> Self {
|
||||
pub fn from_bez_path(bez_path: BezPath, style: PathStyle, closed: bool) -> Self {
|
||||
Self {
|
||||
path: bez_path,
|
||||
style,
|
||||
render_index: 1,
|
||||
solid,
|
||||
closed,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,7 +111,7 @@ impl Shape {
|
||||
path,
|
||||
style,
|
||||
render_index: 1,
|
||||
solid: true,
|
||||
closed: true,
|
||||
}
|
||||
}
|
||||
pub fn rectangle(style: PathStyle) -> Self {
|
||||
@@ -119,7 +119,7 @@ impl Shape {
|
||||
path: kurbo::Rect::new(0., 0., 1., 1.).to_path(0.01),
|
||||
style,
|
||||
render_index: 1,
|
||||
solid: true,
|
||||
closed: true,
|
||||
}
|
||||
}
|
||||
pub fn ellipse(style: PathStyle) -> Self {
|
||||
@@ -127,7 +127,7 @@ impl Shape {
|
||||
path: kurbo::Ellipse::from_rect(kurbo::Rect::new(0., 0., 1., 1.)).to_path(0.01),
|
||||
style,
|
||||
render_index: 1,
|
||||
solid: true,
|
||||
closed: true,
|
||||
}
|
||||
}
|
||||
pub fn line(style: PathStyle) -> Self {
|
||||
@@ -135,7 +135,7 @@ impl Shape {
|
||||
path: kurbo::Line::new((0., 0.), (1., 0.)).to_path(0.01),
|
||||
style,
|
||||
render_index: 1,
|
||||
solid: true,
|
||||
closed: false,
|
||||
}
|
||||
}
|
||||
pub fn poly_line(points: Vec<impl Into<glam::DVec2>>, style: PathStyle) -> Self {
|
||||
@@ -150,7 +150,7 @@ impl Shape {
|
||||
path,
|
||||
style,
|
||||
render_index: 0,
|
||||
solid: false,
|
||||
closed: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,6 +65,7 @@ pub enum Operation {
|
||||
path: Vec<LayerId>,
|
||||
bez_path: kurbo::BezPath,
|
||||
style: style::PathStyle,
|
||||
closed: bool,
|
||||
},
|
||||
DeleteLayer {
|
||||
path: Vec<LayerId>,
|
||||
@@ -96,6 +97,10 @@ pub enum Operation {
|
||||
path: Vec<LayerId>,
|
||||
transform: [f64; 6],
|
||||
},
|
||||
SetShapePath {
|
||||
path: Vec<LayerId>,
|
||||
bez_path: kurbo::BezPath,
|
||||
},
|
||||
SetShapePathInViewport {
|
||||
path: Vec<LayerId>,
|
||||
bez_path: kurbo::BezPath,
|
||||
|
||||
Reference in New Issue
Block a user