mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2025-08-04 13:30:48 +00:00
Make duplicating folders also duplicate its children (#1178)
* Latest changes * Add layer attempt * layer tree is now correct after duplicating layers * Latest changes * Latest Changes * Recursive idea * Moving Layers to Dup Folder - not done * latest changes * latest progress * Latest Changes * Latest Changes * Latest Changes * Latest * Latest * Latest * Duplicating Folders works * Initial Refactoring * Ready for QA * Doesn't select all the children after duplicate anymore * First pass code review with major cleanup * Removed unused next_asssignment_id function and updated FolderLayer struct * Removed unused logic * First iteration of cleaning up the code * Added Ollie's suggestions * Code review cleanup --------- Co-authored-by: Ollie Dolan <olliedolan10@gmail.com> Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
parent
6400953af5
commit
bb1e7c44cf
7 changed files with 250 additions and 33 deletions
|
@ -10,7 +10,9 @@ use glam::{DAffine2, DVec2};
|
|||
use serde::{Deserialize, Serialize};
|
||||
use std::cmp::max;
|
||||
use std::collections::hash_map::DefaultHasher;
|
||||
use std::collections::HashMap;
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::vec;
|
||||
|
||||
/// A number that identifies a layer.
|
||||
/// This does not technically need to be unique globally, only within a folder.
|
||||
|
@ -477,21 +479,48 @@ impl Document {
|
|||
|
||||
self.set_layer(&path, layer, insert_index)?;
|
||||
|
||||
Some([vec![DocumentChanged, CreatedLayer { path: path.clone() }], update_thumbnails_upstream(&path)].concat())
|
||||
let mut responses = vec![
|
||||
DocumentChanged,
|
||||
CreatedLayer {
|
||||
path: path.clone(),
|
||||
is_selected: true,
|
||||
},
|
||||
];
|
||||
responses.extend(update_thumbnails_upstream(&path));
|
||||
|
||||
Some(responses)
|
||||
}
|
||||
Operation::AddRect { path, insert_index, transform, style } => {
|
||||
let layer = Layer::new(LayerDataType::Shape(ShapeLayer::rectangle(style)), transform);
|
||||
|
||||
self.set_layer(&path, layer, insert_index)?;
|
||||
|
||||
Some([vec![DocumentChanged, CreatedLayer { path: path.clone() }], update_thumbnails_upstream(&path)].concat())
|
||||
let mut responses = vec![
|
||||
DocumentChanged,
|
||||
CreatedLayer {
|
||||
path: path.clone(),
|
||||
is_selected: true,
|
||||
},
|
||||
];
|
||||
responses.extend(update_thumbnails_upstream(&path));
|
||||
|
||||
Some(responses)
|
||||
}
|
||||
Operation::AddLine { path, insert_index, transform, style } => {
|
||||
let layer = Layer::new(LayerDataType::Shape(ShapeLayer::line(style)), transform);
|
||||
|
||||
self.set_layer(&path, layer, insert_index)?;
|
||||
|
||||
Some([vec![DocumentChanged, CreatedLayer { path: path.clone() }], update_thumbnails_upstream(&path)].concat())
|
||||
let mut responses = vec![
|
||||
DocumentChanged,
|
||||
CreatedLayer {
|
||||
path: path.clone(),
|
||||
is_selected: true,
|
||||
},
|
||||
];
|
||||
responses.extend(update_thumbnails_upstream(&path));
|
||||
|
||||
Some(responses)
|
||||
}
|
||||
Operation::AddFrame {
|
||||
path,
|
||||
|
@ -503,7 +532,16 @@ impl Document {
|
|||
|
||||
self.set_layer(&path, layer, insert_index)?;
|
||||
|
||||
Some([vec![DocumentChanged, CreatedLayer { path: path.clone() }], update_thumbnails_upstream(&path)].concat())
|
||||
let mut responses = vec![
|
||||
DocumentChanged,
|
||||
CreatedLayer {
|
||||
path: path.clone(),
|
||||
is_selected: true,
|
||||
},
|
||||
];
|
||||
responses.extend(update_thumbnails_upstream(&path));
|
||||
|
||||
Some(responses)
|
||||
}
|
||||
Operation::SetLayerPreserveAspect { layer_path, preserve_aspect } => {
|
||||
if let Ok(layer) = self.layer_mut(&layer_path) {
|
||||
|
@ -520,7 +558,7 @@ impl Document {
|
|||
} => {
|
||||
let shape = ShapeLayer::new(subpath, style);
|
||||
self.set_layer(&path, Layer::new(LayerDataType::Shape(shape), transform), insert_index)?;
|
||||
Some([vec![DocumentChanged, CreatedLayer { path }]].concat())
|
||||
Some(vec![DocumentChanged, CreatedLayer { path, is_selected: true }])
|
||||
}
|
||||
Operation::AddPolyline {
|
||||
path,
|
||||
|
@ -531,7 +569,17 @@ impl Document {
|
|||
} => {
|
||||
let points: Vec<glam::DVec2> = points.iter().map(|&it| it.into()).collect();
|
||||
self.set_layer(&path, Layer::new(LayerDataType::Shape(ShapeLayer::poly_line(points, style)), transform), insert_index)?;
|
||||
Some([vec![DocumentChanged, CreatedLayer { path: path.clone() }], update_thumbnails_upstream(&path)].concat())
|
||||
|
||||
let mut responses = vec![
|
||||
DocumentChanged,
|
||||
CreatedLayer {
|
||||
path: path.clone(),
|
||||
is_selected: true,
|
||||
},
|
||||
];
|
||||
responses.extend(update_thumbnails_upstream(&path));
|
||||
|
||||
Some(responses)
|
||||
}
|
||||
Operation::DeleteLayer { path } => {
|
||||
fn aggregate_deletions(folder: &FolderLayer, path: &mut Vec<LayerId>, responses: &mut Vec<DocumentResponse>) {
|
||||
|
@ -559,35 +607,94 @@ impl Document {
|
|||
destination_path,
|
||||
layer,
|
||||
insert_index,
|
||||
duplicating,
|
||||
} => {
|
||||
let (folder_path, layer_id) = split_path(&destination_path)?;
|
||||
let folder = self.folder_mut(folder_path)?;
|
||||
folder.add_layer(*layer, Some(layer_id), insert_index).ok_or(DocumentError::IndexOutOfBounds)?;
|
||||
let mut responses = vec![DocumentChanged];
|
||||
|
||||
// If we are duplicating, use the parent layer path as the folder we insert to
|
||||
let (created_layer_path, folder_changed_path) = if duplicating {
|
||||
let folder = self.folder_mut(&destination_path)?;
|
||||
let new_layer_id = folder.add_layer(*layer, None, insert_index).ok_or(DocumentError::IndexOutOfBounds)?;
|
||||
|
||||
([destination_path.as_slice(), &[new_layer_id]].concat(), destination_path.clone())
|
||||
} else {
|
||||
let folder = self.folder_mut(folder_path)?;
|
||||
folder.add_layer(*layer, Some(layer_id), insert_index).ok_or(DocumentError::IndexOutOfBounds)?;
|
||||
|
||||
(destination_path.clone(), folder_path.to_vec())
|
||||
};
|
||||
|
||||
responses.push(CreatedLayer {
|
||||
path: created_layer_path,
|
||||
is_selected: !duplicating,
|
||||
});
|
||||
responses.push(FolderChanged { path: folder_changed_path.to_vec() });
|
||||
responses.extend(update_thumbnails_upstream(&destination_path));
|
||||
|
||||
self.mark_as_dirty(&destination_path)?;
|
||||
|
||||
fn aggregate_insertions(folder: &FolderLayer, path: &mut Vec<LayerId>, responses: &mut Vec<DocumentResponse>) {
|
||||
// Recursively iterate through each layer in a folder and add it to the responses vector
|
||||
fn aggregate_insertions(folder: &FolderLayer, path: &mut Vec<LayerId>, responses: &mut Vec<DocumentResponse>, duplicating: bool) {
|
||||
for (id, layer) in folder.layer_ids.iter().zip(folder.layers()) {
|
||||
path.push(*id);
|
||||
responses.push(DocumentResponse::CreatedLayer { path: path.clone() });
|
||||
|
||||
responses.push(DocumentResponse::CreatedLayer {
|
||||
path: path.clone(),
|
||||
is_selected: !duplicating,
|
||||
});
|
||||
if let LayerDataType::Folder(f) = &layer.data {
|
||||
aggregate_insertions(f, path, responses);
|
||||
aggregate_insertions(f, path, responses, duplicating);
|
||||
}
|
||||
|
||||
path.pop();
|
||||
}
|
||||
}
|
||||
|
||||
let mut responses = Vec::new();
|
||||
if let Ok(folder) = self.folder(&destination_path) {
|
||||
aggregate_insertions(folder, &mut destination_path.as_slice().to_vec(), &mut responses)
|
||||
aggregate_insertions(folder, &mut destination_path.as_slice().to_vec(), &mut responses, duplicating);
|
||||
};
|
||||
|
||||
responses.extend([DocumentChanged, CreatedLayer { path: destination_path.clone() }, FolderChanged { path: folder_path.to_vec() }]);
|
||||
responses.extend(update_thumbnails_upstream(&destination_path));
|
||||
Some(responses)
|
||||
}
|
||||
Operation::DuplicateLayer { path } => {
|
||||
// Notes for review: I wasn't sure on how to apply unwrap_or() to lines of code that use the function self.layer()
|
||||
|
||||
let layer = self.layer(&path)?.clone();
|
||||
let layer_is_folder = layer.as_folder().is_ok();
|
||||
let (folder_path, _) = split_path(path.as_slice()).unwrap_or((&[], 0));
|
||||
|
||||
// Recursively collect each of the nested folders and shapes if the layer is a folder
|
||||
fn recursive_collect(document: &mut Document, layer_path: &[u64]) -> Vec<Vec<u64>> {
|
||||
let mut duplicated_layers_so_far = Vec::new();
|
||||
|
||||
let children = document.folder_children_paths(layer_path);
|
||||
for child in children {
|
||||
if document.is_folder(&child) {
|
||||
duplicated_layers_so_far.push(child.to_vec());
|
||||
duplicated_layers_so_far.append(&mut recursive_collect(document, &child));
|
||||
} else {
|
||||
duplicated_layers_so_far.push(child);
|
||||
}
|
||||
}
|
||||
|
||||
duplicated_layers_so_far
|
||||
}
|
||||
let mut duplicated_layers = if layer_is_folder { recursive_collect(self, &path) } else { Vec::new() };
|
||||
|
||||
// Iterate through each layer path and collect the corresponding Layer objects into one vector
|
||||
let duplicated_layers_objects = duplicated_layers
|
||||
.iter()
|
||||
.map(|layer_path| self.layer(layer_path.as_slice()).cloned().ok())
|
||||
.collect::<Option<Vec<_>>>()
|
||||
.ok_or(DocumentError::InvalidPath)?;
|
||||
|
||||
// Sort both vectors by the layer path depth, from shallowest (fewest) to deepest (most)
|
||||
let mut indices: Vec<usize> = (0..duplicated_layers.len()).collect();
|
||||
indices.sort_by_key(|&i| duplicated_layers[i].len());
|
||||
duplicated_layers.sort_by_key(|a| a.len());
|
||||
let duplicate_layer_objects_sorted: Vec<&Layer> = indices.iter().map(|&i| &duplicated_layers_objects[i]).collect();
|
||||
|
||||
let folder = self.folder_mut(folder_path)?;
|
||||
|
||||
let selected_id = path.last().copied().unwrap_or_default();
|
||||
|
@ -595,14 +702,73 @@ impl Document {
|
|||
|
||||
if let Some(new_layer_id) = folder.add_layer(layer, None, insert_index) {
|
||||
let new_path = [folder_path, &[new_layer_id]].concat();
|
||||
|
||||
let mut responses = vec![
|
||||
DocumentChanged,
|
||||
CreatedLayer {
|
||||
path: new_path.clone(),
|
||||
is_selected: true,
|
||||
},
|
||||
FolderChanged { path: folder_path.to_vec() },
|
||||
];
|
||||
responses.extend(update_thumbnails_upstream(path.as_slice()));
|
||||
|
||||
if layer_is_folder {
|
||||
let new_folder = self.folder_mut(&new_path)?;
|
||||
// Clear the new folders layer_ids/layers because they contain the layer_ids/layers of the layers that were duplicated
|
||||
new_folder.layer_ids = vec![];
|
||||
new_folder.layers = vec![];
|
||||
// Generate a new next assignment ID to avoid collision
|
||||
new_folder.generate_new_folder_ids();
|
||||
|
||||
let mut old_to_new_layer_id: HashMap<LayerId, LayerId> = HashMap::new();
|
||||
|
||||
for (i, duplicate_layer) in duplicated_layers.into_iter().enumerate() {
|
||||
let Some(old_layer_id) = duplicate_layer.last().cloned() else { continue; };
|
||||
|
||||
// Iterate through each ID of the current duplicate layer
|
||||
// If the dictionary contains the ID, we know the duplicate folder has been created already. Use the existing layer ID instead of creating a new one
|
||||
let sub_layer = &duplicate_layer[new_path.len()..];
|
||||
let new_sub_path: Vec<u64> = sub_layer.iter().filter_map(|id| old_to_new_layer_id.get(id).cloned()).collect();
|
||||
|
||||
// Combine the new path with the IDs of the duplicate layer path to create the path where we insert the duplicate layer
|
||||
let mut updated_layer = duplicate_layer_objects_sorted.get(i).unwrap().to_owned().clone();
|
||||
let updated_layer_path_parent = [new_path.clone(), new_sub_path].concat();
|
||||
|
||||
// Clear the new folder's layer_ids and layers because they contain the layer_ids/layers of the layer were duplicated
|
||||
if self.is_folder(duplicate_layer) {
|
||||
let updated_layer_as_folder: &mut FolderLayer = updated_layer.as_folder_mut()?;
|
||||
updated_layer_as_folder.layer_ids = vec![];
|
||||
updated_layer_as_folder.layers = vec![];
|
||||
updated_layer_as_folder.generate_new_folder_ids()
|
||||
}
|
||||
|
||||
let result = self
|
||||
.handle_operation(Operation::InsertLayer {
|
||||
layer: Box::new(updated_layer),
|
||||
destination_path: updated_layer_path_parent,
|
||||
insert_index: -1,
|
||||
duplicating: true,
|
||||
})
|
||||
.ok()
|
||||
.flatten()
|
||||
.unwrap_or_default();
|
||||
|
||||
// Collect the new ID of the duplicated layer from the InsertLayer Operation
|
||||
// Map the layer ID of the layer we're duplicating to the new ID
|
||||
if let DocumentResponse::CreatedLayer { path, .. } = result.get(1).unwrap() {
|
||||
if let Some(new_layer_id) = path.last() {
|
||||
old_to_new_layer_id.entry(old_layer_id).or_insert(*new_layer_id);
|
||||
}
|
||||
}
|
||||
|
||||
responses.extend(result);
|
||||
}
|
||||
}
|
||||
|
||||
self.mark_as_dirty(folder_path)?;
|
||||
Some(
|
||||
[
|
||||
vec![DocumentChanged, CreatedLayer { path: new_path }, FolderChanged { path: folder_path.to_vec() }],
|
||||
update_thumbnails_upstream(path.as_slice()),
|
||||
]
|
||||
.concat(),
|
||||
)
|
||||
|
||||
Some(responses)
|
||||
} else {
|
||||
return Err(DocumentError::IndexOutOfBounds);
|
||||
}
|
||||
|
@ -611,11 +777,20 @@ impl Document {
|
|||
self.layer_mut(&path)?.name = Some(name);
|
||||
Some(vec![LayerChanged { path }])
|
||||
}
|
||||
Operation::CreateFolder { path } => {
|
||||
self.set_layer(&path, Layer::new(LayerDataType::Folder(FolderLayer::default()), DAffine2::IDENTITY.to_cols_array()), -1)?;
|
||||
Operation::CreateFolder { path, insert_index } => {
|
||||
self.set_layer(&path, Layer::new(LayerDataType::Folder(FolderLayer::default()), DAffine2::IDENTITY.to_cols_array()), insert_index)?;
|
||||
self.mark_as_dirty(&path)?;
|
||||
|
||||
Some([vec![DocumentChanged, CreatedLayer { path: path.clone() }], update_thumbnails_upstream(&path)].concat())
|
||||
let mut responses = vec![
|
||||
DocumentChanged,
|
||||
CreatedLayer {
|
||||
path: path.clone(),
|
||||
is_selected: true,
|
||||
},
|
||||
];
|
||||
responses.extend(update_thumbnails_upstream(&path));
|
||||
|
||||
Some(responses)
|
||||
}
|
||||
Operation::TransformLayer { path, transform } => {
|
||||
let layer = self.layer_mut(&path).unwrap();
|
||||
|
|
|
@ -3,6 +3,8 @@ use super::style::RenderData;
|
|||
use crate::intersection::Quad;
|
||||
use crate::{DocumentError, LayerId};
|
||||
|
||||
use graphene_core::uuid::generate_uuid;
|
||||
|
||||
use glam::DVec2;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
|
@ -147,6 +149,10 @@ impl FolderLayer {
|
|||
Some(&mut self.layers[pos])
|
||||
}
|
||||
|
||||
pub fn generate_new_folder_ids(&mut self) {
|
||||
self.next_assignment_id = generate_uuid();
|
||||
}
|
||||
|
||||
/// Returns `true` if the folder contains a layer with the given [LayerId].
|
||||
///
|
||||
/// # Example
|
||||
|
|
|
@ -50,9 +50,11 @@ pub enum Operation {
|
|||
layer: Box<Layer>,
|
||||
destination_path: Vec<LayerId>,
|
||||
insert_index: isize,
|
||||
duplicating: bool,
|
||||
},
|
||||
CreateFolder {
|
||||
path: Vec<LayerId>,
|
||||
insert_index: isize,
|
||||
},
|
||||
TransformLayer {
|
||||
path: Vec<LayerId>,
|
||||
|
|
|
@ -11,8 +11,12 @@ pub enum DocumentResponse {
|
|||
FolderChanged {
|
||||
path: Vec<LayerId>,
|
||||
},
|
||||
AddSelectedLayer {
|
||||
additional_layers: Vec<Vec<LayerId>>,
|
||||
},
|
||||
CreatedLayer {
|
||||
path: Vec<LayerId>,
|
||||
is_selected: bool,
|
||||
},
|
||||
DeletedLayer {
|
||||
path: Vec<LayerId>,
|
||||
|
@ -21,6 +25,11 @@ pub enum DocumentResponse {
|
|||
LayerChanged {
|
||||
path: Vec<LayerId>,
|
||||
},
|
||||
MoveSelectedLayersTo {
|
||||
folder_path: Vec<LayerId>,
|
||||
insert_index: isize,
|
||||
reverse_index: bool,
|
||||
},
|
||||
DeletedSelectedManipulatorPoints,
|
||||
}
|
||||
|
||||
|
@ -29,10 +38,12 @@ impl fmt::Display for DocumentResponse {
|
|||
match self {
|
||||
DocumentResponse::DocumentChanged { .. } => write!(f, "DocumentChanged"),
|
||||
DocumentResponse::FolderChanged { .. } => write!(f, "FolderChanged"),
|
||||
DocumentResponse::AddSelectedLayer { .. } => write!(f, "AddSelectedLayer"),
|
||||
DocumentResponse::CreatedLayer { .. } => write!(f, "CreatedLayer"),
|
||||
DocumentResponse::LayerChanged { .. } => write!(f, "LayerChanged"),
|
||||
DocumentResponse::DeletedLayer { .. } => write!(f, "DeleteLayer"),
|
||||
DocumentResponse::DeletedSelectedManipulatorPoints { .. } => write!(f, "DeletedSelectedManipulatorPoints"),
|
||||
DocumentResponse::MoveSelectedLayersTo { .. } => write!(f, "MoveSelectedLayersTo"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -124,11 +124,23 @@ impl MessageHandler<DocumentMessage, (u64, &InputPreprocessorMessageHandler, &Pe
|
|||
for response in document_responses {
|
||||
match &response {
|
||||
DocumentResponse::FolderChanged { path } => responses.add(FolderChanged { affected_folder_path: path.clone() }),
|
||||
DocumentResponse::AddSelectedLayer { additional_layers } => responses.add(AddSelectedLayers {
|
||||
additional_layers: additional_layers.clone(),
|
||||
}),
|
||||
DocumentResponse::DeletedLayer { path } => {
|
||||
self.layer_metadata.remove(path);
|
||||
}
|
||||
DocumentResponse::LayerChanged { path } => responses.add(LayerChanged { affected_layer_path: path.clone() }),
|
||||
DocumentResponse::CreatedLayer { path } => {
|
||||
DocumentResponse::MoveSelectedLayersTo {
|
||||
folder_path,
|
||||
insert_index,
|
||||
reverse_index,
|
||||
} => responses.add(MoveSelectedLayersTo {
|
||||
folder_path: folder_path.clone(),
|
||||
insert_index: insert_index.clone(),
|
||||
reverse_index: reverse_index.clone(),
|
||||
}),
|
||||
DocumentResponse::CreatedLayer { path, is_selected } => {
|
||||
if self.layer_metadata.contains_key(path) {
|
||||
warn!("CreatedLayer overrides existing layer metadata.");
|
||||
}
|
||||
|
@ -136,9 +148,12 @@ impl MessageHandler<DocumentMessage, (u64, &InputPreprocessorMessageHandler, &Pe
|
|||
|
||||
responses.add(LayerChanged { affected_layer_path: path.clone() });
|
||||
self.layer_range_selection_reference = path.clone();
|
||||
responses.add(AddSelectedLayers {
|
||||
additional_layers: vec![path.clone()],
|
||||
});
|
||||
|
||||
if *is_selected {
|
||||
responses.add(AddSelectedLayers {
|
||||
additional_layers: vec![path.clone()],
|
||||
});
|
||||
}
|
||||
}
|
||||
DocumentResponse::DocumentChanged => responses.add(RenderDocument),
|
||||
DocumentResponse::DeletedSelectedManipulatorPoints => {
|
||||
|
@ -272,7 +287,10 @@ impl MessageHandler<DocumentMessage, (u64, &InputPreprocessorMessageHandler, &Pe
|
|||
let id = generate_uuid();
|
||||
container_path.push(id);
|
||||
responses.add(DocumentMessage::DeselectAllLayers);
|
||||
responses.add(DocumentOperation::CreateFolder { path: container_path.clone() });
|
||||
responses.add(DocumentOperation::CreateFolder {
|
||||
path: container_path.clone(),
|
||||
insert_index: -1,
|
||||
});
|
||||
responses.add(DocumentMessage::SetLayerExpansion {
|
||||
layer_path: container_path,
|
||||
set_expanded: true,
|
||||
|
@ -417,6 +435,7 @@ impl MessageHandler<DocumentMessage, (u64, &InputPreprocessorMessageHandler, &Pe
|
|||
responses.add(DocumentOperation::ClearBlobURL { path: layer_path.into() });
|
||||
}
|
||||
GroupSelectedLayers => {
|
||||
// TODO: Add code that changes the insert index of the new folder based on the selected layer
|
||||
let mut new_folder_path = self.document_legacy.shallowest_common_folder(self.selected_layers()).unwrap_or(&[]).to_vec();
|
||||
|
||||
// Required for grouping parent folders with their own children
|
||||
|
@ -428,7 +447,10 @@ impl MessageHandler<DocumentMessage, (u64, &InputPreprocessorMessageHandler, &Pe
|
|||
|
||||
responses.add(PortfolioMessage::Copy { clipboard: Clipboard::Internal });
|
||||
responses.add(DocumentMessage::DeleteSelectedLayers);
|
||||
responses.add(DocumentOperation::CreateFolder { path: new_folder_path.clone() });
|
||||
responses.add(DocumentOperation::CreateFolder {
|
||||
path: new_folder_path.clone(),
|
||||
insert_index: -1,
|
||||
});
|
||||
responses.add(DocumentMessage::ToggleLayerExpansion { layer_path: new_folder_path.clone() });
|
||||
responses.add(PortfolioMessage::PasteIntoFolder {
|
||||
clipboard: Clipboard::Internal,
|
||||
|
|
|
@ -395,6 +395,7 @@ impl MessageHandler<PortfolioMessage, (&InputPreprocessorMessageHandler, &Prefer
|
|||
layer: Box::new(entry.layer.clone()),
|
||||
destination_path,
|
||||
insert_index,
|
||||
duplicating: false,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
@ -431,6 +432,7 @@ impl MessageHandler<PortfolioMessage, (&InputPreprocessorMessageHandler, &Prefer
|
|||
layer: Box::new(entry.layer.clone()),
|
||||
destination_path,
|
||||
insert_index: -1,
|
||||
duplicating: false,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -368,6 +368,7 @@ impl SelectToolData {
|
|||
layer: Box::new(layer),
|
||||
destination_path: layer_path.clone(),
|
||||
insert_index: -1,
|
||||
duplicating: false,
|
||||
});
|
||||
responses.add(DocumentMessage::UpdateLayerMetadata {
|
||||
layer_path: layer_path.clone(),
|
||||
|
@ -1219,8 +1220,6 @@ fn edit_layer_deepest_manipulation(intersect: &Layer, responses: &mut VecDeque<M
|
|||
}
|
||||
|
||||
fn recursive_search(document: &DocumentMessageHandler, layer_path: &Vec<u64>, incoming_layer_path_vector: &Vec<u64>) -> bool {
|
||||
// TODO: fix below, then QA
|
||||
// DOUBLE CLICK BROKEN
|
||||
let layer_paths = document.document_legacy.folder_children_paths(layer_path);
|
||||
for path in layer_paths {
|
||||
if path == *incoming_layer_path_vector {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue