Add keyboard shortcut to duplicate layers (#214)

* Add keyboard shortcut to duplicate layers

* Avoid heap allocation in DuplicateSelectedLayers
This commit is contained in:
Till Arnold 2021-06-16 11:15:02 +02:00 committed by Keavon Chambers
parent 310db82ab4
commit ff232bd722
5 changed files with 20 additions and 1 deletions

View File

@ -202,10 +202,12 @@ export default defineComponent({
on_mouse_move(e.offsetX, e.offsetY); on_mouse_move(e.offsetX, e.offsetY);
}, },
async keyDown(e: KeyboardEvent) { async keyDown(e: KeyboardEvent) {
e.preventDefault();
const { on_key_down } = await wasm; const { on_key_down } = await wasm;
on_key_down(e.key); on_key_down(e.key);
}, },
async keyUp(e: KeyboardEvent) { async keyUp(e: KeyboardEvent) {
e.preventDefault();
const { on_key_up } = await wasm; const { on_key_up } = await wasm;
on_key_up(e.key); on_key_up(e.key);
}, },

View File

@ -248,6 +248,13 @@ impl Document {
let (path, _) = split_path(path.as_slice()).unwrap_or_else(|_| (&[], 0)); let (path, _) = split_path(path.as_slice()).unwrap_or_else(|_| (&[], 0));
Some(vec![DocumentResponse::DocumentChanged, DocumentResponse::FolderChanged { path: path.to_vec() }]) Some(vec![DocumentResponse::DocumentChanged, DocumentResponse::FolderChanged { path: path.to_vec() }])
} }
Operation::DuplicateLayer { path } => {
let layer = self.layer(&path)?.clone();
let (folder_path, _) = split_path(path.as_slice()).unwrap_or_else(|_| (&[], 0));
let folder = self.folder_mut(folder_path)?;
folder.add_layer(layer, -1).ok_or(DocumentError::IndexOutOfBounds)?;
Some(vec![DocumentResponse::DocumentChanged, DocumentResponse::FolderChanged { path: folder_path.to_vec() }])
}
Operation::AddFolder { path } => { Operation::AddFolder { path } => {
self.set_layer(&path, Layer::new(LayerDataTypes::Folder(Folder::default())))?; self.set_layer(&path, Layer::new(LayerDataTypes::Folder(Folder::default())))?;

View File

@ -60,6 +60,9 @@ pub enum Operation {
DeleteLayer { DeleteLayer {
path: Vec<LayerId>, path: Vec<LayerId>,
}, },
DuplicateLayer {
path: Vec<LayerId>,
},
AddFolder { AddFolder {
path: Vec<LayerId>, path: Vec<LayerId>,
}, },

View File

@ -11,6 +11,7 @@ pub enum DocumentMessage {
SelectLayers(Vec<Vec<LayerId>>), SelectLayers(Vec<Vec<LayerId>>),
DeleteLayer(Vec<LayerId>), DeleteLayer(Vec<LayerId>),
DeleteSelectedLayers, DeleteSelectedLayers,
DuplicateSelectedLayers,
AddFolder(Vec<LayerId>), AddFolder(Vec<LayerId>),
RenameLayer(Vec<LayerId>, String), RenameLayer(Vec<LayerId>, String),
ToggleLayerVisibility(Vec<LayerId>), ToggleLayerVisibility(Vec<LayerId>),
@ -160,6 +161,11 @@ impl MessageHandler<DocumentMessage, ()> for DocumentMessageHandler {
responses.push_back(DocumentOperation::DeleteLayer { path }.into()) responses.push_back(DocumentOperation::DeleteLayer { path }.into())
} }
} }
DuplicateSelectedLayers => {
for path in self.active_document().layer_data.iter().filter_map(|(path, data)| data.selected.then(|| path.clone())) {
responses.push_back(DocumentOperation::DuplicateLayer { path }.into())
}
}
SelectLayers(paths) => { SelectLayers(paths) => {
self.clear_selection(); self.clear_selection();
for path in paths { for path in paths {
@ -208,7 +214,7 @@ impl MessageHandler<DocumentMessage, ()> for DocumentMessageHandler {
} }
fn actions(&self) -> ActionList { fn actions(&self) -> ActionList {
if self.active_document().layer_data.values().any(|data| data.selected) { if self.active_document().layer_data.values().any(|data| data.selected) {
actions!(DocumentMessageDiscriminant; Undo, DeleteSelectedLayers, RenderDocument, ExportDocument, NewDocument, NextDocument, PrevDocument) actions!(DocumentMessageDiscriminant; Undo, DeleteSelectedLayers, DuplicateSelectedLayers, RenderDocument, ExportDocument, NewDocument, NextDocument, PrevDocument)
} else { } else {
actions!(DocumentMessageDiscriminant; Undo, RenderDocument, ExportDocument, NewDocument, NextDocument, PrevDocument) actions!(DocumentMessageDiscriminant; Undo, RenderDocument, ExportDocument, NewDocument, NextDocument, PrevDocument)
} }

View File

@ -167,6 +167,7 @@ impl Default for Mapping {
entry! {action=GlobalMessage::LogInfo, key_down=Key1}, entry! {action=GlobalMessage::LogInfo, key_down=Key1},
entry! {action=GlobalMessage::LogDebug, key_down=Key2}, entry! {action=GlobalMessage::LogDebug, key_down=Key2},
entry! {action=GlobalMessage::LogTrace, key_down=Key3}, entry! {action=GlobalMessage::LogTrace, key_down=Key3},
entry! {action=DocumentMessage::DuplicateSelectedLayers, key_down=KeyD, modifiers=[KeyControl]},
]; ];
Self { up, down, pointer_move } Self { up, down, pointer_move }
} }