piskel/dev/js/selection/SelectionManager.js
2017-05-22 09:56:42 +02:00

179 lines
5.6 KiB
JavaScript

(function () {
var ns = $.namespace('pskl.selection');
var SELECTION_REPLAY = {
PASTE : 'REPLAY_PASTE',
ERASE : 'REPLAY_ERASE'
};
ns.SelectionManager = function (piskelController) {
this.piskelController = piskelController;
this.currentSelection = null;
};
ns.SelectionManager.prototype.init = function () {
$.subscribe(Events.SELECTION_CREATED, $.proxy(this.onSelectionCreated_, this));
$.subscribe(Events.SELECTION_DISMISSED, $.proxy(this.onSelectionDismissed_, this));
$.subscribe(Events.SELECTION_MOVE_REQUEST, $.proxy(this.onSelectionMoved_, this));
$.subscribe(Events.SELECTION_COPY, this.copy.bind(this));
$.subscribe(Events.SELECTION_CUT, this.cut.bind(this));
$.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));
$.subscribe(Events.TOOL_SELECTED, $.proxy(this.onToolSelected_, this));
};
/**
* @private
*/
ns.SelectionManager.prototype.cleanSelection_ = function() {
if (this.currentSelection) {
this.currentSelection.reset();
this.currentSelection = null;
}
};
/**
* @private
*/
ns.SelectionManager.prototype.onToolSelected_ = function(evt, tool) {
var isSelectionTool = tool instanceof pskl.tools.drawing.selection.BaseSelect;
if (!isSelectionTool) {
this.cleanSelection_();
}
};
/**
* @private
*/
ns.SelectionManager.prototype.onSelectionDismissed_ = function(evt) {
this.cleanSelection_();
};
ns.SelectionManager.prototype.onDeleteShortcut_ = function(evt) {
if (this.currentSelection) {
this.erase();
} else {
return true; // bubble
}
};
ns.SelectionManager.prototype.erase = function () {
var pixels = this.currentSelection.pixels;
var currentFrame = this.piskelController.getCurrentFrame();
for (var i = 0, l = pixels.length ; i < l ; i++) {
currentFrame.setPixel(pixels[i].col, pixels[i].row, Constants.TRANSPARENT_COLOR);
}
$.publish(Events.PISKEL_SAVE_STATE, {
type : pskl.service.HistoryService.REPLAY,
scope : this,
replay : {
type : SELECTION_REPLAY.ERASE,
pixels : JSON.parse(JSON.stringify(pixels.slice(0)))
}
});
};
ns.SelectionManager.prototype.cut = function() {
if (this.currentSelection) {
// Put cut target into the selection:
this.currentSelection.fillSelectionFromFrame(this.piskelController.getCurrentFrame());
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 pixels = this.currentSelection.pixels;
var frame = this.piskelController.getCurrentFrame();
this.pastePixels_(frame, pixels);
$.publish(Events.PISKEL_SAVE_STATE, {
type : pskl.service.HistoryService.REPLAY,
scope : this,
replay : {
type : SELECTION_REPLAY.PASTE,
pixels : JSON.parse(JSON.stringify(pixels.slice(0)))
}
});
};
/**
* If the currently selected tool is a selection tool, call commitSelection handler on
* the current tool instance.
*/
ns.SelectionManager.prototype.commit = function() {
var tool = pskl.app.drawingController.currentToolBehavior;
var isSelectionTool = tool instanceof pskl.tools.drawing.selection.BaseSelect;
if (isSelectionTool) {
var overlay = pskl.app.drawingController.overlayFrame;
tool.commitSelection(overlay);
}
};
ns.SelectionManager.prototype.replay = function (frame, replayData) {
if (replayData.type === SELECTION_REPLAY.PASTE) {
this.pastePixels_(frame, replayData.pixels);
} else if (replayData.type === SELECTION_REPLAY.ERASE) {
replayData.pixels.forEach(function (pixel) {
frame.setPixel(pixel.col, pixel.row, Constants.TRANSPARENT_COLOR);
});
}
};
ns.SelectionManager.prototype.pastePixels_ = function(frame, pixels) {
pixels.forEach(function (pixel) {
if (pixel.color === Constants.TRANSPARENT_COLOR || pixel.color === null) {
return;
}
frame.setPixel(pixel.col, pixel.row, pixel.color);
});
};
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
*/
ns.SelectionManager.prototype.onSelectionCreated_ = function(evt, selection) {
if (selection) {
this.currentSelection = selection;
} else {
console.error('No selection provided to SelectionManager');
}
};
/**
* @private
*/
ns.SelectionManager.prototype.onSelectionMoved_ = function(evt, colDiff, rowDiff) {
if (this.currentSelection) {
this.currentSelection.move(colDiff, rowDiff);
} else {
console.error('Bad state: No currentSelection set when trying to move it in SelectionManager');
}
};
})();