The copy paste system is built out of three things, ICopyable
objects, ICopyData
representing copied objects, and
IPaster
objects which can turn copy data back into copyable
objects. Every type of ICopyable
needs an associated IPaster
that can paste
that data.
These systems are surfaced to the user through context menu options and keyboard shortcuts.
There are very few circumstances where you would want to implement a custom copyable or a custom paster (e.g. the multiselect plugin, or the cross-tab copy paste plugin), because usually copyable objects are rendered, and you can't add new rendered objects to Blockly. The only rendered objects that can exist within a workspace are blocks, bubbles, and workspace comments.
Implement a copyable
To create a copyable object, you need to implement the ICopyable
interface.
Selectable
The ICopyable
interface extends the ISelectable
interface,
which means you need to implement those methods and properties as well.
Being selectable is required because keyboard shortcuts look at the selected object to figure out what to copy.
class MyCopyable implements ISelectable {
constructor(workspace) {
this.id = Blockly.utils.idGenerator.genUid();
this.workspace = workspace;
}
select() {
// Visually indicate this draggable is selected.
}
unselect() {
// Visually indicate this draggable is not selected.
}
}
Copyable
The ICopyable
interface itself has only one method, toCopyData
, which
returns a JSON-serializable representation of the copyable object's state, which
can be used to recreate the copyable object.
The copy data must also include a paster
property, which holds the registered
string-name associated with the paster that should paste this copy data. For
more information about pasters, see Implement a paster.
class MyCopyable implements ICopyable {
constructor(workspace, state) {
this.workspace = workspace;
this.myState = state;
}
toCopyData() {
return {
// This string matches the string used to register the paster.
paster: 'MY_PASTER',
state: this.myState,
};
}
}
Implement a paster
To create a paster, you need to implement the IPaster
interface. It only has
one method paste
which takes in the copy data of the thing it pastes, the
workspace to paste the thing into, and an optional coordinate, which is the
location to paste the thing at.
class MyPaster implements IPaster {
paste(copyData, workspace, coordinate) {
return new MyCopyable(workspace, copyData.state);
// Optionally position the copyable at the passed coordinate.
// Optionally select the copyable after it is pasted.
}
}
Registration
After you have implemented a paster, you need to register it so that you can
find the paster associated with a given copy data from its paster
property.
// This string matches the string assigned to the 'paster' property.
Blockly.clipboard.registry.register('MY_PASTER', new MyPaster());