Skip to content

Commit 1eb83d9

Browse files
TrueDoctor0HyperCube
authored andcommitted
Implement multiple clipboards (#425)
* Imeplement multiple Clipboards * Cargo fmt * Fix unit tests * Fix console error caused by the Pen Tool (#432) * Fix error in pen tool * Cleanup * Split make operation and remove preview Co-authored-by: Keavon Chambers <[email protected]> * Fix line centering (#431) * cargo fmt Co-authored-by: 0HyperCube <[email protected]>
1 parent e09a606 commit 1eb83d9

File tree

5 files changed

+80
-29
lines changed

5 files changed

+80
-29
lines changed

editor/src/communication/dispatcher.rs

Lines changed: 41 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,13 @@ impl Dispatcher {
9696

9797
#[cfg(test)]
9898
mod test {
99-
use crate::{communication::set_uuid_seed, document::DocumentMessageHandler, message_prelude::*, misc::test_utils::EditorTestUtils, Editor};
99+
use crate::{
100+
communication::set_uuid_seed,
101+
document::{Clipboard::*, DocumentMessageHandler},
102+
message_prelude::*,
103+
misc::test_utils::EditorTestUtils,
104+
Editor,
105+
};
100106
use graphene::{color::Color, Operation};
101107

102108
fn init_logger() {
@@ -131,8 +137,12 @@ mod test {
131137
let mut editor = create_editor_with_three_layers();
132138

133139
let document_before_copy = editor.dispatcher.documents_message_handler.active_document().graphene_document.clone();
134-
editor.handle_message(DocumentsMessage::Copy);
135-
editor.handle_message(DocumentsMessage::PasteIntoFolder { path: vec![], insert_index: -1 });
140+
editor.handle_message(DocumentsMessage::Copy(User));
141+
editor.handle_message(DocumentsMessage::PasteIntoFolder {
142+
clipboard: User,
143+
path: vec![],
144+
insert_index: -1,
145+
});
136146
let document_after_copy = editor.dispatcher.documents_message_handler.active_document().graphene_document.clone();
137147

138148
let layers_before_copy = document_before_copy.root.as_folder().unwrap().layers();
@@ -164,8 +174,12 @@ mod test {
164174
let shape_id = document_before_copy.root.as_folder().unwrap().layer_ids[1];
165175

166176
editor.handle_message(DocumentMessage::SetSelectedLayers(vec![vec![shape_id]]));
167-
editor.handle_message(DocumentsMessage::Copy);
168-
editor.handle_message(DocumentsMessage::PasteIntoFolder { path: vec![], insert_index: -1 });
177+
editor.handle_message(DocumentsMessage::Copy(User));
178+
editor.handle_message(DocumentsMessage::PasteIntoFolder {
179+
clipboard: User,
180+
path: vec![],
181+
insert_index: -1,
182+
});
169183

170184
let document_after_copy = editor.dispatcher.documents_message_handler.active_document().graphene_document.clone();
171185

@@ -223,10 +237,18 @@ mod test {
223237

224238
let document_before_copy = editor.dispatcher.documents_message_handler.active_document().graphene_document.clone();
225239

226-
editor.handle_message(DocumentsMessage::Copy);
240+
editor.handle_message(DocumentsMessage::Copy(User));
227241
editor.handle_message(DocumentMessage::DeleteSelectedLayers);
228-
editor.handle_message(DocumentsMessage::PasteIntoFolder { path: vec![], insert_index: -1 });
229-
editor.handle_message(DocumentsMessage::PasteIntoFolder { path: vec![], insert_index: -1 });
242+
editor.handle_message(DocumentsMessage::PasteIntoFolder {
243+
clipboard: User,
244+
path: vec![],
245+
insert_index: -1,
246+
});
247+
editor.handle_message(DocumentsMessage::PasteIntoFolder {
248+
clipboard: User,
249+
path: vec![],
250+
insert_index: -1,
251+
});
230252

231253
let document_after_copy = editor.dispatcher.documents_message_handler.active_document().graphene_document.clone();
232254

@@ -284,11 +306,19 @@ mod test {
284306
let ellipse_id = document_before_copy.root.as_folder().unwrap().layer_ids[ELLIPSE_INDEX];
285307

286308
editor.handle_message(DocumentMessage::SetSelectedLayers(vec![vec![rect_id], vec![ellipse_id]]));
287-
editor.handle_message(DocumentsMessage::Copy);
309+
editor.handle_message(DocumentsMessage::Copy(User));
288310
editor.handle_message(DocumentMessage::DeleteSelectedLayers);
289311
editor.draw_rect(0., 800., 12., 200.);
290-
editor.handle_message(DocumentsMessage::PasteIntoFolder { path: vec![], insert_index: -1 });
291-
editor.handle_message(DocumentsMessage::PasteIntoFolder { path: vec![], insert_index: -1 });
312+
editor.handle_message(DocumentsMessage::PasteIntoFolder {
313+
clipboard: User,
314+
path: vec![],
315+
insert_index: -1,
316+
});
317+
editor.handle_message(DocumentsMessage::PasteIntoFolder {
318+
clipboard: User,
319+
path: vec![],
320+
insert_index: -1,
321+
});
292322

293323
let document_after_copy = editor.dispatcher.documents_message_handler.active_document().graphene_document.clone();
294324

editor/src/document/document_file.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use super::transform_layer_handler::{TransformLayerMessage, TransformLayerMessag
77

88
use crate::consts::DEFAULT_DOCUMENT_NAME;
99
use crate::consts::{ASYMPTOTIC_EFFECT, FILE_EXPORT_SUFFIX, FILE_SAVE_SUFFIX, SCALE_EFFECT, SCROLLBAR_SPACING};
10+
use crate::document::Clipboard;
1011
use crate::input::InputPreprocessor;
1112
use crate::message_prelude::*;
1213
use crate::EditorError;
@@ -541,12 +542,13 @@ impl MessageHandler<DocumentMessage, &InputPreprocessor> for DocumentMessageHand
541542
let mut new_folder_path = common_prefix.to_vec();
542543
new_folder_path.push(generate_uuid());
543544

544-
responses.push_back(DocumentsMessage::Copy.into());
545+
responses.push_back(DocumentsMessage::Copy(Clipboard::System).into());
545546
responses.push_back(DocumentMessage::DeleteSelectedLayers.into());
546547
responses.push_back(DocumentOperation::CreateFolder { path: new_folder_path.clone() }.into());
547548
responses.push_back(DocumentMessage::ToggleLayerExpansion(new_folder_path.clone()).into());
548549
responses.push_back(
549550
DocumentsMessage::PasteIntoFolder {
551+
clipboard: Clipboard::System,
550552
path: new_folder_path.clone(),
551553
insert_index: -1,
552554
}
@@ -792,9 +794,16 @@ impl MessageHandler<DocumentMessage, &InputPreprocessor> for DocumentMessageHand
792794
responses.push_back(ToolMessage::SelectedLayersChanged.into());
793795
}
794796
MoveSelectedLayersTo { path, insert_index } => {
795-
responses.push_back(DocumentsMessage::Copy.into());
797+
responses.push_back(DocumentsMessage::Copy(Clipboard::System).into());
796798
responses.push_back(DocumentMessage::DeleteSelectedLayers.into());
797-
responses.push_back(DocumentsMessage::PasteIntoFolder { path, insert_index }.into());
799+
responses.push_back(
800+
DocumentsMessage::PasteIntoFolder {
801+
clipboard: Clipboard::System,
802+
path,
803+
insert_index,
804+
}
805+
.into(),
806+
);
798807
}
799808
ReorderSelectedLayers(relative_position) => {
800809
self.backup(responses);

editor/src/document/document_message_handler.rs

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,25 @@ use std::collections::{HashMap, VecDeque};
1010
use super::DocumentMessageHandler;
1111
use crate::consts::DEFAULT_DOCUMENT_NAME;
1212

13+
#[repr(u8)]
14+
#[derive(Serialize, Deserialize, Clone, Copy, PartialEq, Eq, Debug)]
15+
pub enum Clipboard {
16+
System,
17+
User,
18+
_ClipboardCount,
19+
}
20+
static CLIPBOARD_COUNT: u8 = Clipboard::_ClipboardCount as u8;
21+
1322
#[impl_message(Message, Documents)]
1423
#[derive(PartialEq, Clone, Debug, Serialize, Deserialize)]
1524
pub enum DocumentsMessage {
16-
Copy,
25+
Copy(Clipboard),
1726
PasteIntoFolder {
27+
clipboard: Clipboard,
1828
path: Vec<LayerId>,
1929
insert_index: isize,
2030
},
21-
Paste,
31+
Paste(Clipboard),
2232
SelectDocument(u64),
2333
CloseDocument(u64),
2434
#[child]
@@ -49,7 +59,7 @@ pub struct DocumentsMessageHandler {
4959
documents: HashMap<u64, DocumentMessageHandler>,
5060
document_ids: Vec<u64>,
5161
active_document_id: u64,
52-
copy_buffer: Vec<Layer>,
62+
copy_buffer: Vec<Vec<Layer>>,
5363
}
5464

5565
impl DocumentsMessageHandler {
@@ -139,7 +149,7 @@ impl Default for DocumentsMessageHandler {
139149
Self {
140150
documents: documents_map,
141151
document_ids: vec![starting_key],
142-
copy_buffer: vec![],
152+
copy_buffer: vec![vec![]; CLIPBOARD_COUNT as usize],
143153
active_document_id: starting_key,
144154
}
145155
}
@@ -319,19 +329,19 @@ impl MessageHandler<DocumentsMessage, &InputPreprocessor> for DocumentsMessageHa
319329
let prev_id = self.document_ids[prev_index];
320330
responses.push_back(DocumentsMessage::SelectDocument(prev_id).into());
321331
}
322-
Copy => {
332+
Copy(clipboard) => {
323333
let paths = self.active_document().selected_layers_sorted();
324-
self.copy_buffer.clear();
334+
self.copy_buffer[clipboard as usize].clear();
325335
for path in paths {
326336
match self.active_document().graphene_document.layer(&path).map(|t| t.clone()) {
327337
Ok(layer) => {
328-
self.copy_buffer.push(layer);
338+
self.copy_buffer[clipboard as usize].push(layer);
329339
}
330340
Err(e) => warn!("Could not access selected layer {:?}: {:?}", path, e),
331341
}
332342
}
333343
}
334-
Paste => {
344+
Paste(clipboard) => {
335345
let document = self.active_document();
336346
let shallowest_common_folder = document
337347
.graphene_document
@@ -340,13 +350,14 @@ impl MessageHandler<DocumentsMessage, &InputPreprocessor> for DocumentsMessageHa
340350

341351
responses.push_back(
342352
PasteIntoFolder {
353+
clipboard,
343354
path: shallowest_common_folder.to_vec(),
344355
insert_index: -1,
345356
}
346357
.into(),
347358
);
348359
}
349-
PasteIntoFolder { path, insert_index } => {
360+
PasteIntoFolder { clipboard, path, insert_index } => {
350361
let paste = |layer: &Layer, responses: &mut VecDeque<_>| {
351362
log::trace!("Pasting into folder {:?} as index: {}", path, insert_index);
352363
responses.push_back(
@@ -359,11 +370,11 @@ impl MessageHandler<DocumentsMessage, &InputPreprocessor> for DocumentsMessageHa
359370
)
360371
};
361372
if insert_index == -1 {
362-
for layer in self.copy_buffer.iter() {
373+
for layer in self.copy_buffer[clipboard as usize].iter() {
363374
paste(layer, responses)
364375
}
365376
} else {
366-
for layer in self.copy_buffer.iter().rev() {
377+
for layer in self.copy_buffer[clipboard as usize].iter().rev() {
367378
paste(layer, responses)
368379
}
369380
}

editor/src/document/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ pub use document_file::LayerData;
1010
#[doc(inline)]
1111
pub use document_file::{AlignAggregate, AlignAxis, DocumentMessage, DocumentMessageDiscriminant, DocumentMessageHandler, FlipAxis, VectorManipulatorSegment, VectorManipulatorShape};
1212
#[doc(inline)]
13-
pub use document_message_handler::{DocumentsMessage, DocumentsMessageDiscriminant, DocumentsMessageHandler};
13+
pub use document_message_handler::{Clipboard, DocumentsMessage, DocumentsMessageDiscriminant, DocumentsMessageHandler};
1414
#[doc(inline)]
1515
pub use movement_handler::{MovementMessage, MovementMessageDiscriminant};
1616
#[doc(inline)]

editor/src/input/input_mapper.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use super::{
44
keyboard::{Key, KeyStates, NUMBER_OF_KEYS},
55
InputPreprocessor,
66
};
7+
use crate::document::Clipboard::*;
78
use crate::message_prelude::*;
89
use crate::tool::ToolType;
910

@@ -133,7 +134,7 @@ impl Default for Mapping {
133134
// it as an available action in the respective message handler file (such as the bottom of `document_message_handler.rs`)
134135
let mappings = mapping![
135136
// Higher priority than entries in sections below
136-
entry! {action=DocumentsMessage::Paste, key_down=KeyV, modifiers=[KeyControl]},
137+
entry! {action=DocumentsMessage::Paste(User), key_down=KeyV, modifiers=[KeyControl]},
137138
entry! {action=MovementMessage::EnableSnapping, key_down=KeyShift},
138139
entry! {action=MovementMessage::DisableSnapping, key_up=KeyShift},
139140
// Transform layers
@@ -207,7 +208,7 @@ impl Default for Mapping {
207208
// Editor Actions
208209
entry! {action=FrontendMessage::OpenDocumentBrowse, key_down=KeyO, modifiers=[KeyControl]},
209210
// Document Actions
210-
entry! {action=DocumentsMessage::Paste, key_down=KeyV, modifiers=[KeyControl]},
211+
entry! {action=DocumentsMessage::Paste(User), key_down=KeyV, modifiers=[KeyControl]},
211212
entry! {action=DocumentMessage::Redo, key_down=KeyZ, modifiers=[KeyControl, KeyShift]},
212213
entry! {action=DocumentMessage::Undo, key_down=KeyZ, modifiers=[KeyControl]},
213214
entry! {action=DocumentMessage::DeselectAllLayers, key_down=KeyA, modifiers=[KeyControl, KeyAlt]},
@@ -252,7 +253,7 @@ impl Default for Mapping {
252253
entry! {action=DocumentsMessage::CloseAllDocumentsWithConfirmation, key_down=KeyW, modifiers=[KeyControl, KeyAlt]},
253254
entry! {action=DocumentsMessage::CloseActiveDocumentWithConfirmation, key_down=KeyW, modifiers=[KeyControl]},
254255
entry! {action=DocumentMessage::DuplicateSelectedLayers, key_down=KeyD, modifiers=[KeyControl]},
255-
entry! {action=DocumentsMessage::Copy, key_down=KeyC, modifiers=[KeyControl]},
256+
entry! {action=DocumentsMessage::Copy(User), key_down=KeyC, modifiers=[KeyControl]},
256257
entry! {action=DocumentMessage::GroupSelectedLayers, key_down=KeyG, modifiers=[KeyControl]},
257258
// Nudging
258259
entry! {action=DocumentMessage::NudgeSelectedLayers(-SHIFT_NUDGE_AMOUNT, -SHIFT_NUDGE_AMOUNT), key_down=KeyArrowUp, modifiers=[KeyShift, KeyArrowLeft]},

0 commit comments

Comments
 (0)