1
+ use glam:: DAffine2 ;
2
+
1
3
use crate :: {
2
- layers:: { self , Folder , Layer , LayerData , LayerDataTypes , Line , PolyLine , Rect , Shape } ,
4
+ layers:: { self , style :: PathStyle , Folder , Layer , LayerDataTypes , Line , PolyLine , Rect , Shape } ,
3
5
DocumentError , DocumentResponse , LayerId , Operation ,
4
6
} ;
5
7
6
8
#[ derive( Debug , Clone , PartialEq ) ]
7
9
pub struct Document {
8
- pub root : layers :: Folder ,
9
- pub work : Folder ,
10
+ pub root : Layer ,
11
+ pub work : Layer ,
10
12
pub work_mount_path : Vec < LayerId > ,
11
13
pub work_operations : Vec < Operation > ,
12
14
pub work_mounted : bool ,
@@ -15,8 +17,8 @@ pub struct Document {
15
17
impl Default for Document {
16
18
fn default ( ) -> Self {
17
19
Self {
18
- root : Folder :: default ( ) ,
19
- work : Folder :: default ( ) ,
20
+ root : Layer :: new ( LayerDataTypes :: Folder ( Folder :: default ( ) ) , DAffine2 :: IDENTITY . to_cols_array ( ) , PathStyle :: default ( ) ) ,
21
+ work : Layer :: new ( LayerDataTypes :: Folder ( Folder :: default ( ) ) , DAffine2 :: IDENTITY . to_cols_array ( ) , PathStyle :: default ( ) ) ,
20
22
work_mount_path : Vec :: new ( ) ,
21
23
work_operations : Vec :: new ( ) ,
22
24
work_mounted : false ,
@@ -41,8 +43,11 @@ impl Document {
41
43
return ;
42
44
}
43
45
if path. as_slice ( ) == self . work_mount_path {
44
- self . document_folder_mut ( path) . unwrap ( ) . render ( svg) ;
45
- self . work . render ( svg) ;
46
+ // TODO: Handle if mounted in nested folders
47
+ let transform = self . document_folder ( path) . unwrap ( ) . transform ;
48
+ self . document_folder_mut ( path) . unwrap ( ) . render_as_folder ( svg) ;
49
+ self . work . transform = transform;
50
+ self . work . render_as_folder ( svg) ;
46
51
path. pop ( ) ;
47
52
}
48
53
let ids = self . folder ( path) . unwrap ( ) . layer_ids . clone ( ) ;
@@ -68,10 +73,10 @@ impl Document {
68
73
/// This function respects mounted folders and will thus not contain the layers already
69
74
/// present in the document if a temporary folder is mounted on top.
70
75
pub fn folder ( & self , mut path : & [ LayerId ] ) -> Result < & Folder , DocumentError > {
71
- let mut root = & self . root ;
76
+ let mut root = self . root . as_folder ( ) ? ;
72
77
if self . is_mounted ( self . work_mount_path . as_slice ( ) , path) {
73
78
path = & path[ self . work_mount_path . len ( ) ..] ;
74
- root = & self . work ;
79
+ root = self . work . as_folder ( ) ? ;
75
80
}
76
81
for id in path {
77
82
root = root. folder ( * id) . ok_or ( DocumentError :: LayerNotFound ) ?;
@@ -87,9 +92,9 @@ impl Document {
87
92
pub fn folder_mut ( & mut self , mut path : & [ LayerId ] ) -> Result < & mut Folder , DocumentError > {
88
93
let mut root = if self . is_mounted ( self . work_mount_path . as_slice ( ) , path) {
89
94
path = & path[ self . work_mount_path . len ( ) ..] ;
90
- & mut self . work
95
+ self . work . as_folder_mut ( ) ?
91
96
} else {
92
- & mut self . root
97
+ self . root . as_folder_mut ( ) ?
93
98
} ;
94
99
for id in path {
95
100
root = root. folder_mut ( * id) . ok_or ( DocumentError :: LayerNotFound ) ?;
@@ -101,10 +106,10 @@ impl Document {
101
106
/// or if the requested layer is not of type folder.
102
107
/// This function does **not** respect mounted folders and will always return the current
103
108
/// state of the document, disregarding any temporary modifications.
104
- pub fn document_folder ( & self , path : & [ LayerId ] ) -> Result < & Folder , DocumentError > {
109
+ pub fn document_folder ( & self , path : & [ LayerId ] ) -> Result < & Layer , DocumentError > {
105
110
let mut root = & self . root ;
106
111
for id in path {
107
- root = root. folder ( * id) . ok_or ( DocumentError :: LayerNotFound ) ?;
112
+ root = root. as_folder ( ) ? . layer ( * id) . ok_or ( DocumentError :: LayerNotFound ) ?;
108
113
}
109
114
Ok ( root)
110
115
}
@@ -114,10 +119,10 @@ impl Document {
114
119
/// This function does **not** respect mounted folders and will always return the current
115
120
/// state of the document, disregarding any temporary modifications.
116
121
/// If you manually edit the folder you have to set the cache_dirty flag yourself.
117
- pub fn document_folder_mut ( & mut self , path : & [ LayerId ] ) -> Result < & mut Folder , DocumentError > {
122
+ pub fn document_folder_mut ( & mut self , path : & [ LayerId ] ) -> Result < & mut Layer , DocumentError > {
118
123
let mut root = & mut self . root ;
119
124
for id in path {
120
- root = root. folder_mut ( * id) . ok_or ( DocumentError :: LayerNotFound ) ?;
125
+ root = root. as_folder_mut ( ) ? . layer_mut ( * id) . ok_or ( DocumentError :: LayerNotFound ) ?;
121
126
}
122
127
Ok ( root)
123
128
}
@@ -137,7 +142,7 @@ impl Document {
137
142
138
143
/// Replaces the layer at the specified `path` with `layer`.
139
144
pub fn set_layer ( & mut self , path : & [ LayerId ] , layer : Layer ) -> Result < ( ) , DocumentError > {
140
- let mut folder = & mut self . root ;
145
+ let mut folder = self . root . as_folder_mut ( ) ? ;
141
146
if let Ok ( ( path, id) ) = split_path ( path) {
142
147
self . layer_mut ( path) ?. cache_dirty = true ;
143
148
folder = self . folder_mut ( path) ?;
@@ -163,81 +168,54 @@ impl Document {
163
168
pub fn delete ( & mut self , path : & [ LayerId ] ) -> Result < ( ) , DocumentError > {
164
169
let ( path, id) = split_path ( path) ?;
165
170
let _ = self . layer_mut ( path) . map ( |x| x. cache_dirty = true ) ;
166
- self . document_folder_mut ( path) ?. remove_layer ( id) ?;
171
+ self . document_folder_mut ( path) ?. as_folder_mut ( ) ? . remove_layer ( id) ?;
167
172
Ok ( ( ) )
168
173
}
169
174
170
175
/// Mutate the document by applying the `operation` to it. If the operation necessitates a
171
176
/// reaction from the frontend, responses may be returned.
172
177
pub fn handle_operation ( & mut self , operation : Operation ) -> Result < Option < Vec < DocumentResponse > > , DocumentError > {
173
178
let responses = match & operation {
174
- Operation :: AddCircle { path, insert_index, cx , cy , r , style } => {
175
- let id = self . add_layer ( & path, Layer :: new ( LayerDataTypes :: Circle ( layers:: Circle :: new ( ( * cx , * cy ) , * r , * style) ) ) , * insert_index) ?;
179
+ Operation :: AddEllipse { path, insert_index, transform , style } => {
180
+ let id = self . add_layer ( & path, Layer :: new ( LayerDataTypes :: Ellipse ( layers:: Ellipse :: new ( ) ) , * transform , * style) , * insert_index) ?;
176
181
let path = [ path. clone ( ) , vec ! [ id] ] . concat ( ) ;
177
182
178
183
Some ( vec ! [ DocumentResponse :: DocumentChanged , DocumentResponse :: SelectLayer { path } ] )
179
184
}
180
- Operation :: AddEllipse {
181
- path,
182
- insert_index,
183
- cx,
184
- cy,
185
- rx,
186
- ry,
187
- rot,
188
- style,
189
- } => {
190
- let id = self . add_layer ( & path, Layer :: new ( LayerDataTypes :: Ellipse ( layers:: Ellipse :: new ( ( * cx, * cy) , ( * rx, * ry) , * rot, * style) ) ) , * insert_index) ?;
185
+ Operation :: AddRect { path, insert_index, transform, style } => {
186
+ let id = self . add_layer ( & path, Layer :: new ( LayerDataTypes :: Rect ( Rect :: new ( ) ) , * transform, * style) , * insert_index) ?;
191
187
let path = [ path. clone ( ) , vec ! [ id] ] . concat ( ) ;
192
188
193
189
Some ( vec ! [ DocumentResponse :: DocumentChanged , DocumentResponse :: SelectLayer { path } ] )
194
190
}
195
- Operation :: AddRect {
196
- path,
197
- insert_index,
198
- x0,
199
- y0,
200
- x1,
201
- y1,
202
- style,
203
- } => {
204
- let id = self . add_layer ( & path, Layer :: new ( LayerDataTypes :: Rect ( Rect :: new ( ( * x0, * y0) , ( * x1, * y1) , * style) ) ) , * insert_index) ?;
191
+ Operation :: AddLine { path, insert_index, transform, style } => {
192
+ let id = self . add_layer ( & path, Layer :: new ( LayerDataTypes :: Line ( Line :: new ( ) ) , * transform, * style) , * insert_index) ?;
205
193
let path = [ path. clone ( ) , vec ! [ id] ] . concat ( ) ;
206
194
207
195
Some ( vec ! [ DocumentResponse :: DocumentChanged , DocumentResponse :: SelectLayer { path } ] )
208
196
}
209
- Operation :: AddLine {
197
+ Operation :: AddPen {
210
198
path,
211
199
insert_index,
212
- x0,
213
- y0,
214
- x1,
215
- y1,
200
+ points,
201
+ transform,
216
202
style,
217
203
} => {
218
- let id = self . add_layer ( & path, Layer :: new ( LayerDataTypes :: Line ( Line :: new ( ( * x0, * y0) , ( * x1, * y1) , * style) ) ) , * insert_index) ?;
219
- let path = [ path. clone ( ) , vec ! [ id] ] . concat ( ) ;
220
-
221
- Some ( vec ! [ DocumentResponse :: DocumentChanged , DocumentResponse :: SelectLayer { path } ] )
222
- }
223
- Operation :: AddPen { path, insert_index, points, style } => {
224
- let points: Vec < kurbo:: Point > = points. iter ( ) . map ( |& it| it. into ( ) ) . collect ( ) ;
225
- let polyline = PolyLine :: new ( points, * style) ;
226
- self . add_layer ( & path, Layer :: new ( LayerDataTypes :: PolyLine ( polyline) ) , * insert_index) ?;
204
+ let points: Vec < glam:: DVec2 > = points. iter ( ) . map ( |& it| it. into ( ) ) . collect ( ) ;
205
+ let polyline = PolyLine :: new ( points) ;
206
+ self . add_layer ( & path, Layer :: new ( LayerDataTypes :: PolyLine ( polyline) , * transform, * style) , * insert_index) ?;
227
207
Some ( vec ! [ DocumentResponse :: DocumentChanged ] )
228
208
}
229
209
Operation :: AddShape {
230
210
path,
231
211
insert_index,
232
- x0,
233
- y0,
234
- x1,
235
- y1,
212
+ transform,
213
+ equal_sides,
236
214
sides,
237
215
style,
238
216
} => {
239
- let s = Shape :: new ( ( * x0 , * y0 ) , ( * x1 , * y1 ) , * sides, * style ) ;
240
- let id = self . add_layer ( & path, Layer :: new ( LayerDataTypes :: Shape ( s) ) , * insert_index) ?;
217
+ let s = Shape :: new ( * equal_sides , * sides) ;
218
+ let id = self . add_layer ( & path, Layer :: new ( LayerDataTypes :: Shape ( s) , * transform , * style ) , * insert_index) ?;
241
219
let path = [ path. clone ( ) , vec ! [ id] ] . concat ( ) ;
242
220
243
221
Some ( vec ! [ DocumentResponse :: DocumentChanged , DocumentResponse :: SelectLayer { path } ] )
@@ -256,27 +234,34 @@ impl Document {
256
234
Some ( vec ! [ DocumentResponse :: DocumentChanged , DocumentResponse :: FolderChanged { path: folder_path. to_vec( ) } ] )
257
235
}
258
236
Operation :: AddFolder { path } => {
259
- self . set_layer ( & path, Layer :: new ( LayerDataTypes :: Folder ( Folder :: default ( ) ) ) ) ?;
237
+ self . set_layer ( & path, Layer :: new ( LayerDataTypes :: Folder ( Folder :: default ( ) ) , DAffine2 :: IDENTITY . to_cols_array ( ) , PathStyle :: default ( ) ) ) ?;
260
238
261
239
Some ( vec ! [ DocumentResponse :: DocumentChanged , DocumentResponse :: FolderChanged { path: path. clone( ) } ] )
262
240
}
263
241
Operation :: MountWorkingFolder { path } => {
264
242
self . work_mount_path = path. clone ( ) ;
265
243
self . work_operations . clear ( ) ;
266
- self . work = Folder :: default ( ) ;
244
+ self . work = Layer :: new ( LayerDataTypes :: Folder ( Folder :: default ( ) ) , DAffine2 :: IDENTITY . to_cols_array ( ) , PathStyle :: default ( ) ) ;
267
245
self . work_mounted = true ;
268
246
None
269
247
}
248
+ Operation :: TransformLayer { path, transform } => {
249
+ let transform = self . root . transform * DAffine2 :: from_cols_array ( & transform) ;
250
+ let layer = self . document_folder_mut ( path) . unwrap ( ) ;
251
+ layer. transform = transform;
252
+ layer. cache_dirty = true ;
253
+ Some ( vec ! [ DocumentResponse :: DocumentChanged ] )
254
+ }
270
255
Operation :: DiscardWorkingFolder => {
271
256
self . work_operations . clear ( ) ;
272
257
self . work_mount_path = vec ! [ ] ;
273
- self . work = Folder :: default ( ) ;
258
+ self . work = Layer :: new ( LayerDataTypes :: Folder ( Folder :: default ( ) ) , DAffine2 :: IDENTITY . to_cols_array ( ) , PathStyle :: default ( ) ) ;
274
259
self . work_mounted = false ;
275
260
Some ( vec ! [ DocumentResponse :: DocumentChanged ] )
276
261
}
277
262
Operation :: ClearWorkingFolder => {
278
263
self . work_operations . clear ( ) ;
279
- self . work = Folder :: default ( ) ;
264
+ self . work = Layer :: new ( LayerDataTypes :: Folder ( Folder :: default ( ) ) , DAffine2 :: IDENTITY . to_cols_array ( ) , PathStyle :: default ( ) ) ;
280
265
Some ( vec ! [ DocumentResponse :: DocumentChanged ] )
281
266
}
282
267
Operation :: CommitTransaction => {
@@ -286,7 +271,7 @@ impl Document {
286
271
std:: mem:: swap ( & mut ops, & mut self . work_operations ) ;
287
272
self . work_mounted = false ;
288
273
self . work_mount_path = vec ! [ ] ;
289
- self . work = Folder :: default ( ) ;
274
+ self . work = Layer :: new ( LayerDataTypes :: Folder ( Folder :: default ( ) ) , DAffine2 :: IDENTITY . to_cols_array ( ) , PathStyle :: default ( ) ) ;
290
275
let mut responses = vec ! [ ] ;
291
276
for operation in ops. into_iter ( ) {
292
277
if let Some ( mut op_responses) = self . handle_operation ( operation) ? {
0 commit comments