Skip to content

Commit 2595662

Browse files
tillarnoldKeavon
authored andcommitted
Copy and paste layers MVP (#220)
* Initial implementation of copy and paste for layers * Sort layers on copy and add tests * Fix logger init for test * Fix `copy_paste_deleted_layers` test * Readd erroneously removed svg * Make Layer serializable and cleanup * Add test for copy and pasting folders * Cleanup * Rename left_mouseup * Cleanup * Add length check to test * Fix typo * Make mouseup, mousedown more consistent
1 parent b2064c7 commit 2595662

17 files changed

+568
-32
lines changed

Cargo.lock

Lines changed: 131 additions & 11 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

core/document/Cargo.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ license = "Apache-2.0"
1010

1111
[dependencies]
1212
log = "0.4"
13-
kurbo = "0.8"
13+
14+
kurbo = {version="0.8", features = ["serde"]}
1415
serde = { version = "1.0", features = ["derive"] }
15-
glam = "0.16"
16+
glam = { version = "0.16", features = ["serde"] }

core/document/src/document.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,30 @@ impl Document {
133133
self.folder(path)?.layer(id).ok_or(DocumentError::LayerNotFound)
134134
}
135135

136+
/// Given a path to a layer, returns a vector of the indices in the layer tree
137+
/// These indices can be used to order a list of layers
138+
pub fn indices_for_path(&self, mut path: &[LayerId]) -> Result<Vec<usize>, DocumentError> {
139+
let mut root = if self.is_mounted(self.work_mount_path.as_slice(), path) {
140+
path = &path[self.work_mount_path.len()..];
141+
&self.work
142+
} else {
143+
&self.root
144+
}
145+
.as_folder()?;
146+
let mut indices = vec![];
147+
let (path, layer_id) = split_path(path)?;
148+
149+
for id in path {
150+
let pos = root.layer_ids.iter().position(|x| *x == *id).ok_or(DocumentError::LayerNotFound)?;
151+
indices.push(pos);
152+
root = root.folder(*id).ok_or(DocumentError::LayerNotFound)?;
153+
}
154+
155+
indices.push(root.layer_ids.iter().position(|x| *x == layer_id).ok_or(DocumentError::LayerNotFound)?);
156+
157+
Ok(indices)
158+
}
159+
136160
/// Returns a mutable reference to the layer struct at the specified `path`.
137161
/// If you manually edit the layer you have to set the cache_dirty flag yourself.
138162
pub fn layer_mut(&mut self, path: &[LayerId]) -> Result<&mut Layer, DocumentError> {
@@ -227,6 +251,13 @@ impl Document {
227251
let (path, _) = split_path(path.as_slice()).unwrap_or_else(|_| (&[], 0));
228252
Some(vec![DocumentResponse::DocumentChanged, DocumentResponse::FolderChanged { path: path.to_vec() }])
229253
}
254+
Operation::PasteLayer { path, layer } => {
255+
let folder = self.folder_mut(path)?;
256+
//FIXME: This clone of layer should be avoided somehow
257+
folder.add_layer(layer.clone(), -1).ok_or(DocumentError::IndexOutOfBounds)?;
258+
259+
Some(vec![DocumentResponse::DocumentChanged, DocumentResponse::FolderChanged { path: path.clone() }])
260+
}
230261
Operation::DuplicateLayer { path } => {
231262
let layer = self.layer(&path)?.clone();
232263
let (folder_path, _) = split_path(path.as_slice()).unwrap_or_else(|_| (&[], 0));

core/document/src/layers/ellipse.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@ use kurbo::Shape;
33
use super::style;
44
use super::LayerData;
55

6+
use serde::{Deserialize, Serialize};
67
use std::fmt::Write;
78

8-
#[derive(Debug, Clone, Copy, PartialEq, Default)]
9+
#[derive(Debug, Clone, Copy, PartialEq, Default, Deserialize, Serialize)]
910
pub struct Ellipse {}
1011

1112
impl Ellipse {

core/document/src/layers/folder.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@ use crate::{DocumentError, LayerId};
22

33
use super::{style, Layer, LayerData, LayerDataTypes};
44

5+
use serde::{Deserialize, Serialize};
56
use std::fmt::Write;
67

7-
#[derive(Debug, Clone, PartialEq)]
8+
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
89
pub struct Folder {
910
next_assignment_id: LayerId,
1011
pub layer_ids: Vec<LayerId>,

core/document/src/layers/line.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@ use kurbo::Point;
44
use super::style;
55
use super::LayerData;
66

7+
use serde::{Deserialize, Serialize};
78
use std::fmt::Write;
89

9-
#[derive(Debug, Clone, Copy, PartialEq)]
10+
#[derive(Debug, Clone, Copy, PartialEq, Deserialize, Serialize)]
1011
pub struct Line {}
1112

1213
impl Line {

core/document/src/layers/mod.rs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ pub mod ellipse;
44
pub use ellipse::Ellipse;
55

66
pub mod line;
7+
use glam::{DMat2, DVec2};
78
use kurbo::BezPath;
89
pub use line::Line;
910

@@ -17,16 +18,16 @@ pub mod shape;
1718
pub use shape::Shape;
1819

1920
pub mod folder;
20-
pub use folder::Folder;
21-
2221
use crate::DocumentError;
22+
pub use folder::Folder;
23+
use serde::{Deserialize, Serialize};
2324

2425
pub trait LayerData {
2526
fn render(&mut self, svg: &mut String, transform: glam::DAffine2, style: style::PathStyle);
2627
fn to_kurbo_path(&mut self, transform: glam::DAffine2, style: style::PathStyle) -> BezPath;
2728
}
2829

29-
#[derive(Debug, Clone, PartialEq)]
30+
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
3031
pub enum LayerDataTypes {
3132
Folder(Folder),
3233
Ellipse(Ellipse),
@@ -77,11 +78,19 @@ impl LayerDataTypes {
7778
}
7879
}
7980

80-
#[derive(Debug, Clone, PartialEq)]
81+
#[derive(Serialize, Deserialize)]
82+
#[serde(remote = "glam::DAffine2")]
83+
struct DAffine2Ref {
84+
pub matrix2: DMat2,
85+
pub translation: DVec2,
86+
}
87+
88+
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
8189
pub struct Layer {
8290
pub visible: bool,
8391
pub name: Option<String>,
8492
pub data: LayerDataTypes,
93+
#[serde(with = "DAffine2Ref")]
8594
pub transform: glam::DAffine2,
8695
pub style: style::PathStyle,
8796
pub cache: String,

core/document/src/layers/polyline.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1+
use serde::{Deserialize, Serialize};
12
use std::fmt::Write;
23

34
use super::{style, LayerData};
45

5-
#[derive(Debug, Clone, PartialEq)]
6+
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
67
pub struct PolyLine {
78
points: Vec<glam::DVec2>,
89
}

0 commit comments

Comments
 (0)