Issue #645: Support clipboard to paste images
This commit is contained in:
parent
5e6280301d
commit
b9423bc831
2 changed files with 92 additions and 19 deletions
|
@ -5,9 +5,23 @@
|
|||
this.reset();
|
||||
};
|
||||
|
||||
ns.BaseSelection.prototype.stringify = function () {
|
||||
return JSON.stringify({
|
||||
pixels: this.pixels,
|
||||
time: this.time
|
||||
});
|
||||
};
|
||||
|
||||
ns.BaseSelection.prototype.parse = function (str) {
|
||||
var selectionData = JSON.parse(str);
|
||||
this.pixels = selectionData.pixels;
|
||||
this.time = selectionData.time;
|
||||
};
|
||||
|
||||
ns.BaseSelection.prototype.reset = function () {
|
||||
this.pixels = [];
|
||||
this.hasPastedContent = false;
|
||||
this.time = -1;
|
||||
};
|
||||
|
||||
ns.BaseSelection.prototype.move = function (colDiff, rowDiff) {
|
||||
|
@ -30,5 +44,8 @@
|
|||
});
|
||||
|
||||
this.hasPastedContent = true;
|
||||
// Keep track of the selection time to compare between local selection and
|
||||
// paste event selections.
|
||||
this.time = Date.now();
|
||||
};
|
||||
})();
|
||||
|
|
|
@ -22,12 +22,14 @@
|
|||
$.subscribe(Events.SELECTION_PASTE, this.paste.bind(this));
|
||||
|
||||
var shortcuts = pskl.service.keyboard.Shortcuts;
|
||||
pskl.app.shortcutService.registerShortcut(shortcuts.SELECTION.PASTE, this.paste.bind(this));
|
||||
pskl.app.shortcutService.registerShortcut(shortcuts.SELECTION.CUT, this.cut.bind(this));
|
||||
pskl.app.shortcutService.registerShortcut(shortcuts.SELECTION.COPY, this.copy.bind(this));
|
||||
pskl.app.shortcutService.registerShortcut(shortcuts.SELECTION.DELETE, this.onDeleteShortcut_.bind(this));
|
||||
pskl.app.shortcutService.registerShortcut(shortcuts.SELECTION.COMMIT, this.commit.bind(this));
|
||||
|
||||
// These 3 events should be handled by a new separated service
|
||||
window.addEventListener('cut', this.cut.bind(this), true);
|
||||
window.addEventListener('copy', this.copy.bind(this), true);
|
||||
window.addEventListener('paste', this.paste.bind(this), true);
|
||||
|
||||
$.subscribe(Events.TOOL_SELECTED, $.proxy(this.onToolSelected_, this));
|
||||
};
|
||||
|
||||
|
@ -78,29 +80,90 @@
|
|||
scope : this,
|
||||
replay : {
|
||||
type : SELECTION_REPLAY.ERASE,
|
||||
pixels : JSON.parse(JSON.stringify(pixels.slice(0)))
|
||||
pixels : JSON.parse(JSON.stringify(pixels))
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
ns.SelectionManager.prototype.cut = function() {
|
||||
if (this.currentSelection) {
|
||||
ns.SelectionManager.prototype.copy = function(event) {
|
||||
if (this.currentSelection && this.piskelController.getCurrentFrame()) {
|
||||
this.currentSelection.fillSelectionFromFrame(this.piskelController.getCurrentFrame());
|
||||
event.clipboardData.setData('text/plain', this.currentSelection.stringify());
|
||||
event.preventDefault();
|
||||
}
|
||||
};
|
||||
|
||||
ns.SelectionManager.prototype.cut = function(event) {
|
||||
if (this.currentSelection && this.piskelController.getCurrentFrame()) {
|
||||
// Put cut target into the selection:
|
||||
this.currentSelection.fillSelectionFromFrame(this.piskelController.getCurrentFrame());
|
||||
event.clipboardData.setData('text/plain', JSON.stringify(this.currentSelection));
|
||||
event.preventDefault();
|
||||
this.erase();
|
||||
}
|
||||
};
|
||||
|
||||
ns.SelectionManager.prototype.paste = function() {
|
||||
if (!this.currentSelection || !this.currentSelection.hasPastedContent) {
|
||||
if (window.localStorage.getItem('piskel.clipboard')) {
|
||||
this.currentSelection = JSON.parse(window.localStorage.getItem('piskel.clipboard'));
|
||||
} else {
|
||||
return;
|
||||
var items = event.clipboardData.items;
|
||||
|
||||
try {
|
||||
for (var i = 0 ; i < items.length ; i++) {
|
||||
var item = items[i];
|
||||
|
||||
if (/^image/i.test(item.type)) {
|
||||
this.pasteImage_(item);
|
||||
event.stopPropagation();
|
||||
return;
|
||||
}
|
||||
|
||||
if (/^text\/plain/i.test(item.type)) {
|
||||
this.pasteText_(item);
|
||||
event.stopPropagation();
|
||||
return;
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
// Some of the clipboard APIs are not available on Safari/IE
|
||||
// Allow Piskel to fallback on local currentSelection pasting.
|
||||
}
|
||||
|
||||
var pixels = this.currentSelection.pixels;
|
||||
// temporarily keeping this code path for tests and fallbacks.
|
||||
if (this.currentSelection && this.currentSelection.hasPastedContent) {
|
||||
this.pastePixelsOnCurrentFrame_(this.currentSelection.pixels);
|
||||
}
|
||||
};
|
||||
|
||||
ns.SelectionManager.prototype.pasteImage_ = function(clipboardItem) {
|
||||
var blob = clipboardItem.getAsFile();
|
||||
pskl.utils.FileUtils.readImageFile(blob, function (image) {
|
||||
pskl.app.fileDropperService.dropPosition_ = {x: 0, y: 0};
|
||||
pskl.app.fileDropperService.onImageLoaded_(image, blob);
|
||||
}.bind(this));
|
||||
};
|
||||
|
||||
ns.SelectionManager.prototype.pasteText_ = function(clipboardItem) {
|
||||
var blob = clipboardItem.getAsString(function (selectionString) {
|
||||
var selectionData = JSON.parse(selectionString);
|
||||
var time = selectionData.time;
|
||||
var pixels = selectionData.pixels;
|
||||
|
||||
if (this.currentSelection && this.currentSelection.time >= time) {
|
||||
// If the local selection is newer or equal to the one coming from the clipboard event
|
||||
// use the local one. The reason is that the "move" information is only updated locally
|
||||
// without synchronizing it to the clipboard.
|
||||
// TODO: the selection should store the origin of the selection and the selection itself
|
||||
// separately.
|
||||
pixels = this.currentSelection.pixels;
|
||||
}
|
||||
|
||||
if (pixels) {
|
||||
// If the current clipboard data is some random text, pixels will not be defined.
|
||||
this.pastePixelsOnCurrentFrame_(pixels);
|
||||
}
|
||||
}.bind(this));
|
||||
};
|
||||
|
||||
ns.SelectionManager.prototype.pastePixelsOnCurrentFrame_ = function (pixels) {
|
||||
var frame = this.piskelController.getCurrentFrame();
|
||||
|
||||
this.pastePixels_(frame, pixels);
|
||||
|
@ -146,13 +209,6 @@
|
|||
});
|
||||
};
|
||||
|
||||
ns.SelectionManager.prototype.copy = function() {
|
||||
if (this.currentSelection && this.piskelController.getCurrentFrame()) {
|
||||
this.currentSelection.fillSelectionFromFrame(this.piskelController.getCurrentFrame());
|
||||
window.localStorage.setItem('piskel.clipboard', JSON.stringify(this.currentSelection));
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
|
|
Loading…
Reference in a new issue