Add keyboard shortcut to duplicate layers (#214)
* Add keyboard shortcut to duplicate layers * Avoid heap allocation in DuplicateSelectedLayers
This commit is contained in:
parent
310db82ab4
commit
ff232bd722
|
|
@ -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);
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -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())))?;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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>,
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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 }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue