Skip to content

Commit ed0a0c4

Browse files
TrueDoctorKeavon
authored andcommitted
Rearrange layers refactor (#281)
* Keep selection during reordering * Fix paste layer selection * Remove junk from layer matadata * Add function to get non_selected_layers * Cleanup * Add tests
1 parent 988dd7b commit ed0a0c4

File tree

12 files changed

+156
-300
lines changed

12 files changed

+156
-300
lines changed

core/document/src/document.rs

Lines changed: 44 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,8 @@ impl Default for Document {
2727
}
2828

2929
fn split_path(path: &[LayerId]) -> Result<(&[LayerId], LayerId), DocumentError> {
30-
let id = path.last().ok_or(DocumentError::InvalidPath)?;
31-
let folder_path = &path[0..path.len() - 1];
32-
Ok((folder_path, *id))
30+
let (id, path) = path.split_last().ok_or(DocumentError::InvalidPath)?;
31+
Ok((path, *id))
3332
}
3433

3534
impl Document {
@@ -221,24 +220,8 @@ impl Document {
221220
/// Deletes the layer specified by `path`.
222221
pub fn delete(&mut self, path: &[LayerId]) -> Result<(), DocumentError> {
223222
let (path, id) = split_path(path)?;
224-
if let Ok(layer) = self.layer_mut(path) {
225-
layer.cache_dirty = true;
226-
}
227-
self.document_folder_mut(path)?.as_folder_mut()?.remove_layer(id)?;
228-
Ok(())
229-
}
230-
231-
pub fn reorder_layers(&mut self, source_paths: &[Vec<LayerId>], target_path: &[LayerId]) -> Result<(), DocumentError> {
232-
// TODO: Detect when moving between folders and handle properly
233-
234-
let source_layer_ids = source_paths
235-
.iter()
236-
.map(|x| x.last().cloned().ok_or(DocumentError::LayerNotFound))
237-
.collect::<Result<Vec<LayerId>, DocumentError>>()?;
238-
239-
self.root.as_folder_mut()?.reorder_layers(source_layer_ids, *target_path.last().ok_or(DocumentError::LayerNotFound)?)?;
240-
241-
Ok(())
223+
let _ = self.layer_mut(path).map(|x| x.cache_dirty = true);
224+
self.document_folder_mut(path)?.as_folder_mut()?.remove_layer(id)
242225
}
243226

244227
pub fn layer_axis_aligned_bounding_box(&self, path: &[LayerId]) -> Result<Option<[DVec2; 2]>, DocumentError> {
@@ -268,6 +251,16 @@ impl Document {
268251
Ok(())
269252
}
270253

254+
fn working_paths(&mut self) -> Vec<Vec<LayerId>> {
255+
self.work
256+
.as_folder()
257+
.unwrap()
258+
.layer_ids
259+
.iter()
260+
.map(|id| self.work_mount_path.iter().chain([*id].iter()).cloned().collect())
261+
.collect()
262+
}
263+
271264
/// Mutate the document by applying the `operation` to it. If the operation necessitates a
272265
/// reaction from the frontend, responses may be returned.
273266
pub fn handle_operation(&mut self, operation: Operation) -> Result<Option<Vec<DocumentResponse>>, DocumentError> {
@@ -276,19 +269,19 @@ impl Document {
276269
let id = self.add_layer(&path, Layer::new(LayerDataTypes::Ellipse(layers::Ellipse::new()), *transform, *style), *insert_index)?;
277270
let path = [path.clone(), vec![id]].concat();
278271

279-
Some(vec![DocumentResponse::DocumentChanged, DocumentResponse::SelectLayer { path }])
272+
Some(vec![DocumentResponse::DocumentChanged, DocumentResponse::CreatedLayer { path }])
280273
}
281274
Operation::AddRect { path, insert_index, transform, style } => {
282275
let id = self.add_layer(&path, Layer::new(LayerDataTypes::Rect(Rect), *transform, *style), *insert_index)?;
283276
let path = [path.clone(), vec![id]].concat();
284277

285-
Some(vec![DocumentResponse::DocumentChanged, DocumentResponse::SelectLayer { path }])
278+
Some(vec![DocumentResponse::DocumentChanged, DocumentResponse::CreatedLayer { path }])
286279
}
287280
Operation::AddLine { path, insert_index, transform, style } => {
288281
let id = self.add_layer(&path, Layer::new(LayerDataTypes::Line(Line), *transform, *style), *insert_index)?;
289282
let path = [path.clone(), vec![id]].concat();
290283

291-
Some(vec![DocumentResponse::DocumentChanged, DocumentResponse::SelectLayer { path }])
284+
Some(vec![DocumentResponse::DocumentChanged, DocumentResponse::CreatedLayer { path }])
292285
}
293286
Operation::AddPen {
294287
path,
@@ -301,7 +294,7 @@ impl Document {
301294
let polyline = PolyLine::new(points);
302295
let id = self.add_layer(&path, Layer::new(LayerDataTypes::PolyLine(polyline), *transform, *style), *insert_index)?;
303296
let path = [path.clone(), vec![id]].concat();
304-
Some(vec![DocumentResponse::DocumentChanged, DocumentResponse::SelectLayer { path }])
297+
Some(vec![DocumentResponse::DocumentChanged, DocumentResponse::CreatedLayer { path }])
305298
}
306299
Operation::AddShape {
307300
path,
@@ -315,20 +308,29 @@ impl Document {
315308
let id = self.add_layer(&path, Layer::new(LayerDataTypes::Shape(s), *transform, *style), *insert_index)?;
316309
let path = [path.clone(), vec![id]].concat();
317310

318-
Some(vec![DocumentResponse::DocumentChanged, DocumentResponse::SelectLayer { path }])
311+
Some(vec![DocumentResponse::DocumentChanged, DocumentResponse::CreatedLayer { path }])
319312
}
320313
Operation::DeleteLayer { path } => {
321314
self.delete(&path)?;
322315

323-
let (path, _) = split_path(path.as_slice()).unwrap_or_else(|_| (&[], 0));
324-
Some(vec![DocumentResponse::DocumentChanged, DocumentResponse::FolderChanged { path: path.to_vec() }])
316+
let (folder, _) = split_path(path.as_slice()).unwrap_or_else(|_| (&[], 0));
317+
Some(vec![
318+
DocumentResponse::DocumentChanged,
319+
DocumentResponse::DeletedLayer { path: path.clone() },
320+
DocumentResponse::FolderChanged { path: folder.to_vec() },
321+
])
325322
}
326-
Operation::PasteLayer { path, layer } => {
323+
Operation::PasteLayer { path, layer, insert_index } => {
327324
let folder = self.folder_mut(path)?;
328325
//FIXME: This clone of layer should be avoided somehow
329-
folder.add_layer(layer.clone(), -1).ok_or(DocumentError::IndexOutOfBounds)?;
330-
331-
Some(vec![DocumentResponse::DocumentChanged, DocumentResponse::FolderChanged { path: path.clone() }])
326+
let id = folder.add_layer(layer.clone(), *insert_index).ok_or(DocumentError::IndexOutOfBounds)?;
327+
let full_path = [path.clone(), vec![id]].concat();
328+
329+
Some(vec![
330+
DocumentResponse::DocumentChanged,
331+
DocumentResponse::CreatedLayer { path: full_path },
332+
DocumentResponse::FolderChanged { path: path.clone() },
333+
])
332334
}
333335
Operation::DuplicateLayer { path } => {
334336
let layer = self.layer(&path)?.clone();
@@ -343,11 +345,13 @@ impl Document {
343345
Some(vec![DocumentResponse::DocumentChanged, DocumentResponse::FolderChanged { path: path.clone() }])
344346
}
345347
Operation::MountWorkingFolder { path } => {
348+
let mut responses: Vec<_> = self.working_paths().into_iter().map(|path| DocumentResponse::DeletedLayer { path }).collect();
346349
self.work_mount_path = path.clone();
347350
self.work_operations.clear();
348351
self.work = Layer::new(LayerDataTypes::Folder(Folder::default()), DAffine2::IDENTITY.to_cols_array(), PathStyle::default());
349352
self.work_mounted = true;
350-
None
353+
responses.push(DocumentResponse::DocumentChanged);
354+
Some(responses)
351355
}
352356
Operation::TransformLayer { path, transform } => {
353357
let layer = self.document_layer_mut(path).unwrap();
@@ -365,26 +369,30 @@ impl Document {
365369
Some(vec![DocumentResponse::DocumentChanged])
366370
}
367371
Operation::DiscardWorkingFolder => {
372+
let mut responses: Vec<_> = self.working_paths().into_iter().map(|path| DocumentResponse::DeletedLayer { path }).collect();
368373
self.work_operations.clear();
369374
self.work_mount_path = vec![];
370375
self.work = Layer::new(LayerDataTypes::Folder(Folder::default()), DAffine2::IDENTITY.to_cols_array(), PathStyle::default());
371376
self.work_mounted = false;
372-
Some(vec![DocumentResponse::DocumentChanged])
377+
responses.push(DocumentResponse::DocumentChanged);
378+
Some(responses)
373379
}
374380
Operation::ClearWorkingFolder => {
381+
let mut responses: Vec<_> = self.working_paths().into_iter().map(|path| DocumentResponse::DeletedLayer { path }).collect();
375382
self.work_operations.clear();
376383
self.work = Layer::new(LayerDataTypes::Folder(Folder::default()), DAffine2::IDENTITY.to_cols_array(), PathStyle::default());
377-
Some(vec![DocumentResponse::DocumentChanged])
384+
responses.push(DocumentResponse::DocumentChanged);
385+
Some(responses)
378386
}
379387
Operation::CommitTransaction => {
388+
let mut responses: Vec<_> = self.working_paths().into_iter().map(|path| DocumentResponse::DeletedLayer { path }).collect();
380389
let mut ops = Vec::new();
381390
let mut path: Vec<LayerId> = vec![];
382391
std::mem::swap(&mut path, &mut self.work_mount_path);
383392
std::mem::swap(&mut ops, &mut self.work_operations);
384393
self.work_mounted = false;
385394
self.work_mount_path = vec![];
386395
self.work = Layer::new(LayerDataTypes::Folder(Folder::default()), DAffine2::IDENTITY.to_cols_array(), PathStyle::default());
387-
let mut responses = vec![];
388396
for operation in ops.into_iter() {
389397
if let Some(mut op_responses) = self.handle_operation(operation)? {
390398
responses.append(&mut op_responses);
@@ -416,11 +424,6 @@ impl Document {
416424
self.mark_as_dirty(path)?;
417425
Some(vec![DocumentResponse::DocumentChanged])
418426
}
419-
Operation::ReorderLayers { source_paths, target_path } => {
420-
self.reorder_layers(source_paths, target_path)?;
421-
422-
Some(vec![DocumentResponse::DocumentChanged])
423-
}
424427
};
425428
if !matches!(
426429
operation,

0 commit comments

Comments
 (0)