mirror of
https://github.com/piskelapp/piskel.git
synced 2023-08-10 21:12:52 +03:00
deploy dev version
This commit is contained in:
29
dev/js/controller/dialogs/AbstractDialogController.js
Normal file
29
dev/js/controller/dialogs/AbstractDialogController.js
Normal file
@@ -0,0 +1,29 @@
|
||||
(function () {
|
||||
var ns = $.namespace('pskl.controller.dialogs');
|
||||
|
||||
ns.AbstractDialogController = function () {};
|
||||
|
||||
ns.AbstractDialogController.prototype.init = function () {
|
||||
var closeButton = document.querySelector('.dialog-close');
|
||||
this.addEventListener(closeButton, 'click', this.closeDialog);
|
||||
};
|
||||
|
||||
ns.AbstractDialogController.prototype.addEventListener = function (el, type, cb) {
|
||||
pskl.utils.Event.addEventListener(el, type, cb, this);
|
||||
};
|
||||
|
||||
ns.AbstractDialogController.prototype.destroy = function () {
|
||||
pskl.utils.Event.removeAllEventListeners(this);
|
||||
};
|
||||
|
||||
ns.AbstractDialogController.prototype.closeDialog = function () {
|
||||
$.publish(Events.DIALOG_HIDE);
|
||||
};
|
||||
|
||||
ns.AbstractDialogController.prototype.setTitle = function (title) {
|
||||
var dialogTitle = document.querySelector('.dialog-title');
|
||||
if (dialogTitle) {
|
||||
dialogTitle.innerText = title;
|
||||
}
|
||||
};
|
||||
})();
|
||||
59
dev/js/controller/dialogs/BrowseLocalController.js
Normal file
59
dev/js/controller/dialogs/BrowseLocalController.js
Normal file
@@ -0,0 +1,59 @@
|
||||
(function () {
|
||||
var ns = $.namespace('pskl.controller.dialogs');
|
||||
|
||||
ns.BrowseLocalController = function (piskelController) {};
|
||||
|
||||
pskl.utils.inherit(ns.BrowseLocalController, ns.AbstractDialogController);
|
||||
|
||||
ns.BrowseLocalController.prototype.init = function () {
|
||||
this.superclass.init.call(this);
|
||||
|
||||
this.localStorageItemTemplate_ = pskl.utils.Template.get('local-storage-item-template');
|
||||
|
||||
this.service_ = pskl.app.localStorageService;
|
||||
this.piskelList = $('.local-piskel-list');
|
||||
this.prevSessionContainer = $('.previous-session');
|
||||
|
||||
this.fillLocalPiskelsList_();
|
||||
|
||||
this.piskelList.click(this.onPiskelsListClick_.bind(this));
|
||||
};
|
||||
|
||||
ns.BrowseLocalController.prototype.onPiskelsListClick_ = function (evt) {
|
||||
var action = evt.target.getAttribute('data-action');
|
||||
var name = evt.target.getAttribute('data-name');
|
||||
if (action === 'load') {
|
||||
if (window.confirm('This will erase your current piskel. Continue ?')) {
|
||||
this.service_.load(name);
|
||||
this.closeDialog();
|
||||
}
|
||||
} else if (action === 'delete') {
|
||||
if (window.confirm('This will permanently DELETE this piskel from your computer. Continue ?')) {
|
||||
this.service_.remove(name);
|
||||
this.fillLocalPiskelsList_();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
ns.BrowseLocalController.prototype.fillLocalPiskelsList_ = function () {
|
||||
var html = '';
|
||||
var keys = this.service_.getKeys();
|
||||
|
||||
keys.sort(function (k1, k2) {
|
||||
if (k1.date < k2.date) {return 1;}
|
||||
if (k1.date > k2.date) {return -1;}
|
||||
return 0;
|
||||
});
|
||||
|
||||
keys.forEach((function (key) {
|
||||
var date = pskl.utils.DateUtils.format(key.date, '{{Y}}/{{M}}/{{D}} {{H}}:{{m}}');
|
||||
html += pskl.utils.Template.replace(this.localStorageItemTemplate_, {
|
||||
name : key.name,
|
||||
date : date
|
||||
});
|
||||
}).bind(this));
|
||||
|
||||
var tableBody_ = this.piskelList.get(0).tBodies[0];
|
||||
tableBody_.innerHTML = html;
|
||||
};
|
||||
})();
|
||||
185
dev/js/controller/dialogs/CheatsheetController.js
Normal file
185
dev/js/controller/dialogs/CheatsheetController.js
Normal file
@@ -0,0 +1,185 @@
|
||||
(function () {
|
||||
var ns = $.namespace('pskl.controller.dialogs');
|
||||
|
||||
var SHORTCUT_EDITING_CLASSNAME = 'cheatsheet-shortcut-editing';
|
||||
|
||||
ns.CheatsheetController = function () {};
|
||||
|
||||
pskl.utils.inherit(ns.CheatsheetController, ns.AbstractDialogController);
|
||||
|
||||
ns.CheatsheetController.prototype.init = function () {
|
||||
this.superclass.init.call(this);
|
||||
|
||||
this.cheatsheetEl = document.getElementById('cheatsheetContainer');
|
||||
this.eventTrapInput = document.getElementById('cheatsheetEventTrap');
|
||||
|
||||
this.addEventListener('.cheatsheet-restore-defaults', 'click', this.onRestoreDefaultsClick_);
|
||||
this.addEventListener(this.cheatsheetEl, 'click', this.onCheatsheetClick_);
|
||||
this.addEventListener(this.eventTrapInput, 'keydown', this.onEventTrapKeydown_);
|
||||
|
||||
this.onShortcutsChanged_ = this.onShortcutsChanged_.bind(this);
|
||||
$.subscribe(Events.SHORTCUTS_CHANGED, this.onShortcutsChanged_);
|
||||
|
||||
this.initMarkup_();
|
||||
document.querySelector('.cheatsheet-helptext').setAttribute('title', this.getHelptextTitle_());
|
||||
};
|
||||
|
||||
ns.CheatsheetController.prototype.destroy = function () {
|
||||
this.eventTrapInput.blur();
|
||||
|
||||
$.unsubscribe(Events.SHORTCUTS_CHANGED, this.onShortcutsChanged_);
|
||||
this.cheatsheetEl = null;
|
||||
|
||||
this.superclass.destroy.call(this);
|
||||
};
|
||||
|
||||
ns.CheatsheetController.prototype.onRestoreDefaultsClick_ = function () {
|
||||
if (window.confirm('Replace all custom shortcuts by the default Piskel shortcuts ?')) {
|
||||
pskl.app.shortcutService.restoreDefaultShortcuts();
|
||||
}
|
||||
};
|
||||
|
||||
ns.CheatsheetController.prototype.onShortcutsChanged_ = function () {
|
||||
this.initMarkup_();
|
||||
};
|
||||
|
||||
ns.CheatsheetController.prototype.onCheatsheetClick_ = function (evt) {
|
||||
var shortcutEl = pskl.utils.Dom.getParentWithData(evt.target, 'shortcutId');
|
||||
if (!shortcutEl) {
|
||||
pskl.utils.Dom.removeClass(SHORTCUT_EDITING_CLASSNAME);
|
||||
return;
|
||||
}
|
||||
|
||||
var shortcutId = shortcutEl.dataset.shortcutId;
|
||||
var shortcut = pskl.app.shortcutService.getShortcutById(shortcutId);
|
||||
|
||||
if (shortcutEl.classList.contains(SHORTCUT_EDITING_CLASSNAME)) {
|
||||
pskl.utils.Dom.removeClass(SHORTCUT_EDITING_CLASSNAME);
|
||||
this.eventTrapInput.blur();
|
||||
} else if (shortcut.isEditable()) {
|
||||
pskl.utils.Dom.removeClass(SHORTCUT_EDITING_CLASSNAME);
|
||||
shortcutEl.classList.add(SHORTCUT_EDITING_CLASSNAME);
|
||||
this.eventTrapInput.focus();
|
||||
}
|
||||
};
|
||||
|
||||
ns.CheatsheetController.prototype.onEventTrapKeydown_ = function (evt) {
|
||||
var shortcutEl = document.querySelector('.' + SHORTCUT_EDITING_CLASSNAME);
|
||||
if (!shortcutEl) {
|
||||
return;
|
||||
}
|
||||
|
||||
var shortcutKeyObject = pskl.service.keyboard.KeyUtils.createKeyFromEvent(evt);
|
||||
if (!shortcutKeyObject) {
|
||||
return;
|
||||
}
|
||||
|
||||
var shortcutKeyString = pskl.service.keyboard.KeyUtils.stringify(shortcutKeyObject);
|
||||
var shortcutId = shortcutEl.dataset.shortcutId;
|
||||
var shortcut = pskl.app.shortcutService.getShortcutById(shortcutId);
|
||||
pskl.app.shortcutService.updateShortcut(shortcut, shortcutKeyString);
|
||||
|
||||
shortcutEl.classList.remove(SHORTCUT_EDITING_CLASSNAME);
|
||||
this.eventTrapInput.blur();
|
||||
|
||||
evt.preventDefault();
|
||||
};
|
||||
|
||||
ns.CheatsheetController.prototype.initMarkup_ = function () {
|
||||
this.initMarkupForCategory_('TOOL', '.cheatsheet-tool-shortcuts', this.getToolIconClass_);
|
||||
this.initMarkupForCategory_('MISC', '.cheatsheet-misc-shortcuts');
|
||||
this.initMarkupForCategory_('COLOR', '.cheatsheet-color-shortcuts');
|
||||
this.initMarkupForCategory_('SELECTION', '.cheatsheet-selection-shortcuts');
|
||||
this.initMarkupForCategory_('STORAGE', '.cheatsheet-storage-shortcuts');
|
||||
};
|
||||
|
||||
ns.CheatsheetController.prototype.getToolIconClass_ = function (shortcut) {
|
||||
return 'tool-icon cheatsheet-icon-' + shortcut.getId();
|
||||
};
|
||||
|
||||
ns.CheatsheetController.prototype.initMarkupForCategory_ = function (category, container, iconClassProvider) {
|
||||
var shortcutMap = pskl.service.keyboard.Shortcuts[category];
|
||||
|
||||
var descriptors = Object.keys(shortcutMap).map(function (shortcutKey) {
|
||||
return this.toDescriptor_(shortcutMap[shortcutKey], iconClassProvider);
|
||||
}.bind(this));
|
||||
|
||||
this.initMarkupForDescriptors_(descriptors, container);
|
||||
};
|
||||
|
||||
ns.CheatsheetController.prototype.toDescriptor_ = function (shortcut, iconClassProvider) {
|
||||
var iconClass = typeof iconClassProvider == 'function' ? iconClassProvider(shortcut) : '';
|
||||
return {
|
||||
'shortcut' : shortcut,
|
||||
'iconClass' : iconClass
|
||||
};
|
||||
};
|
||||
|
||||
ns.CheatsheetController.prototype.initMarkupForDescriptors_ = function (descriptors, containerSelector) {
|
||||
var container = document.querySelector(containerSelector);
|
||||
if (!container) {
|
||||
return;
|
||||
}
|
||||
var markupArray = descriptors.map(this.getMarkupForDescriptor_.bind(this));
|
||||
container.innerHTML = markupArray.join('');
|
||||
};
|
||||
|
||||
ns.CheatsheetController.prototype.getMarkupForDescriptor_ = function (descriptor) {
|
||||
var shortcutTemplate = pskl.utils.Template.get('cheatsheet-shortcut-template');
|
||||
var shortcut = descriptor.shortcut;
|
||||
var description = shortcut.isCustom() ? shortcut.getDescription() + ' *' : shortcut.getDescription();
|
||||
|
||||
var shortcutClasses = [];
|
||||
if (shortcut.isUndefined()) {
|
||||
shortcutClasses.push('cheatsheet-shortcut-undefined');
|
||||
}
|
||||
if (shortcut.isEditable()) {
|
||||
shortcutClasses.push('cheatsheet-shortcut-editable');
|
||||
}
|
||||
|
||||
var title = shortcut.isEditable() ? 'Click to edit the key' : 'Shortcut cannot be remapped';
|
||||
|
||||
var markup = pskl.utils.Template.replace(shortcutTemplate, {
|
||||
id : shortcut.getId(),
|
||||
title : title,
|
||||
icon : descriptor.iconClass,
|
||||
description : description,
|
||||
// Avoid sanitization
|
||||
'!key!' : this.formatKey_(shortcut.getDisplayKey()),
|
||||
className : shortcutClasses.join(' ')
|
||||
});
|
||||
|
||||
return markup;
|
||||
};
|
||||
|
||||
ns.CheatsheetController.prototype.formatKey_ = function (key) {
|
||||
if (pskl.utils.UserAgent.isMac) {
|
||||
key = key.replace('ctrl', 'cmd');
|
||||
key = key.replace('alt', 'option');
|
||||
}
|
||||
key = key.replace(/left/i, '←');
|
||||
key = key.replace(/up/i, '↑');
|
||||
key = key.replace(/right/i, '→');
|
||||
key = key.replace(/down/i, '↓');
|
||||
key = key.replace(/>/g, '>');
|
||||
key = key.replace(/</g, '<');
|
||||
// add spaces around '+' delimiters
|
||||
key = key.replace(/([^ ])\+([^ ])/g, '$1 + $2');
|
||||
return key;
|
||||
};
|
||||
|
||||
ns.CheatsheetController.prototype.getHelptextTitle_ = function () {
|
||||
var helpItems = [
|
||||
'Click on a shortcut to change the key.',
|
||||
'When the shortcut blinks, press the key on your keyboard to assign it.',
|
||||
'White shortcuts can not be edited.',
|
||||
'Click on \'Restore default shortcuts\' to erase all custom shortcuts.'
|
||||
];
|
||||
|
||||
var helptextTitle = helpItems.reduce(function (p, n) {
|
||||
return p + '<div class="cheatsheet-helptext-tooltip-item">' + n + '</div>';
|
||||
}, '');
|
||||
helptextTitle = '<div class="cheatsheet-helptext-tooltip">' + helptextTitle + '</div>';
|
||||
return helptextTitle;
|
||||
};
|
||||
})();
|
||||
132
dev/js/controller/dialogs/CreatePaletteController.js
Normal file
132
dev/js/controller/dialogs/CreatePaletteController.js
Normal file
@@ -0,0 +1,132 @@
|
||||
(function () {
|
||||
var ns = $.namespace('pskl.controller.dialogs');
|
||||
|
||||
ns.CreatePaletteController = function (piskelController) {
|
||||
this.paletteService = pskl.app.paletteService;
|
||||
this.paletteImportService = pskl.app.paletteImportService;
|
||||
};
|
||||
|
||||
pskl.utils.inherit(ns.CreatePaletteController, ns.AbstractDialogController);
|
||||
|
||||
ns.CreatePaletteController.prototype.init = function (paletteId) {
|
||||
this.superclass.init.call(this);
|
||||
|
||||
this.hiddenFileInput = document.querySelector('.create-palette-import-input');
|
||||
this.nameInput = document.querySelector('input[name="palette-name"]');
|
||||
|
||||
var buttonsContainer = document.querySelector('.create-palette-actions');
|
||||
var deleteButton = document.querySelector('.create-palette-delete');
|
||||
var downloadButton = document.querySelector('.create-palette-download-button');
|
||||
var importFileButton = document.querySelector('.create-palette-import-button');
|
||||
|
||||
this.addEventListener(this.nameInput, 'input', this.onNameInputChange_);
|
||||
this.addEventListener(this.hiddenFileInput, 'change', this.onFileInputChange_);
|
||||
|
||||
this.addEventListener(buttonsContainer, 'click', this.onButtonClick_);
|
||||
this.addEventListener(downloadButton, 'click', this.onDownloadButtonClick_);
|
||||
this.addEventListener(importFileButton, 'click', this.onImportFileButtonClick_);
|
||||
|
||||
var colorsListContainer = document.querySelector('.colors-container');
|
||||
this.colorsListWidget = new pskl.widgets.ColorsList(colorsListContainer);
|
||||
|
||||
var palette;
|
||||
var isCurrentColorsPalette = paletteId == Constants.CURRENT_COLORS_PALETTE_ID;
|
||||
if (paletteId && !isCurrentColorsPalette) {
|
||||
importFileButton.style.display = 'none';
|
||||
this.setTitle('Edit Palette');
|
||||
|
||||
var paletteObject = this.paletteService.getPaletteById(paletteId);
|
||||
palette = pskl.model.Palette.fromObject(paletteObject);
|
||||
} else {
|
||||
downloadButton.style.display = 'none';
|
||||
deleteButton.style.display = 'none';
|
||||
this.setTitle('Create Palette');
|
||||
|
||||
var uuid = pskl.utils.Uuid.generate();
|
||||
if (isCurrentColorsPalette) {
|
||||
palette = new pskl.model.Palette(uuid, 'Current colors clone', this.getCurrentColors_());
|
||||
} else {
|
||||
palette = new pskl.model.Palette(uuid, 'New palette', []);
|
||||
}
|
||||
}
|
||||
|
||||
this.setPalette_(palette);
|
||||
};
|
||||
|
||||
ns.CreatePaletteController.prototype.getCurrentColors_ = function () {
|
||||
var palette = this.paletteService.getPaletteById(Constants.CURRENT_COLORS_PALETTE_ID);
|
||||
return palette.getColors();
|
||||
};
|
||||
|
||||
ns.CreatePaletteController.prototype.setPalette_ = function (palette) {
|
||||
this.palette = palette;
|
||||
this.nameInput.value = pskl.utils.unescapeHtml(palette.name);
|
||||
this.colorsListWidget.setColors(palette.getColors());
|
||||
};
|
||||
|
||||
ns.CreatePaletteController.prototype.destroy = function () {
|
||||
this.colorsListWidget.destroy();
|
||||
this.superclass.destroy.call(this);
|
||||
|
||||
this.nameInput = null;
|
||||
this.hiddenFileInput = null;
|
||||
};
|
||||
|
||||
ns.CreatePaletteController.prototype.onButtonClick_ = function (evt) {
|
||||
var target = evt.target;
|
||||
if (target.dataset.action === 'submit') {
|
||||
this.saveAndSelectPalette_();
|
||||
} else if (target.dataset.action === 'cancel') {
|
||||
this.closeDialog();
|
||||
} else if (target.dataset.action === 'delete') {
|
||||
this.deletePalette_();
|
||||
}
|
||||
};
|
||||
|
||||
ns.CreatePaletteController.prototype.saveAndSelectPalette_ = function () {
|
||||
this.palette.setColors(this.colorsListWidget.getColors());
|
||||
this.paletteService.savePalette(this.palette);
|
||||
pskl.UserSettings.set(pskl.UserSettings.SELECTED_PALETTE, this.palette.id);
|
||||
this.closeDialog();
|
||||
};
|
||||
|
||||
ns.CreatePaletteController.prototype.deletePalette_ = function () {
|
||||
if (window.confirm('Are you sure you want to delete palette ' + this.palette.name)) {
|
||||
this.paletteService.deletePaletteById(this.palette.id);
|
||||
pskl.UserSettings.set(pskl.UserSettings.SELECTED_PALETTE, Constants.CURRENT_COLORS_PALETTE_ID);
|
||||
this.closeDialog();
|
||||
}
|
||||
};
|
||||
|
||||
ns.CreatePaletteController.prototype.onDownloadButtonClick_ = function () {
|
||||
var paletteWriter = new pskl.service.palette.PaletteGplWriter(this.palette);
|
||||
var paletteAsString = paletteWriter.write();
|
||||
|
||||
pskl.utils.BlobUtils.stringToBlob(paletteAsString, function(blob) {
|
||||
pskl.utils.FileUtils.downloadAsFile(blob, this.palette.name + '.gpl');
|
||||
}.bind(this), 'application/json');
|
||||
};
|
||||
|
||||
ns.CreatePaletteController.prototype.onImportFileButtonClick_ = function () {
|
||||
this.hiddenFileInput.click();
|
||||
};
|
||||
|
||||
ns.CreatePaletteController.prototype.onFileInputChange_ = function (evt) {
|
||||
var files = this.hiddenFileInput.files;
|
||||
if (files.length == 1) {
|
||||
this.paletteImportService.read(files[0], this.setPalette_.bind(this), this.displayErrorMessage_.bind(this));
|
||||
}
|
||||
};
|
||||
|
||||
ns.CreatePaletteController.prototype.displayErrorMessage_ = function (message) {
|
||||
message = 'Could not import palette : ' + message;
|
||||
$.publish(Events.SHOW_NOTIFICATION, [{
|
||||
'content' : message
|
||||
}]);
|
||||
window.setTimeout($.publish.bind($, Events.HIDE_NOTIFICATION), 2000);
|
||||
};
|
||||
|
||||
ns.CreatePaletteController.prototype.onNameInputChange_ = function (evt) {
|
||||
this.palette.name = pskl.utils.escapeHtml(this.nameInput.value);
|
||||
};
|
||||
})();
|
||||
144
dev/js/controller/dialogs/DialogsController.js
Normal file
144
dev/js/controller/dialogs/DialogsController.js
Normal file
@@ -0,0 +1,144 @@
|
||||
(function () {
|
||||
var ns = $.namespace('pskl.controller.dialogs');
|
||||
|
||||
var dialogs = {
|
||||
'cheatsheet' : {
|
||||
template : 'templates/dialogs/cheatsheet.html',
|
||||
controller : ns.CheatsheetController
|
||||
},
|
||||
'create-palette' : {
|
||||
template : 'templates/dialogs/create-palette.html',
|
||||
controller : ns.CreatePaletteController
|
||||
},
|
||||
'browse-local' : {
|
||||
template : 'templates/dialogs/browse-local.html',
|
||||
controller : ns.BrowseLocalController
|
||||
},
|
||||
'import' : {
|
||||
template : 'templates/dialogs/import.html',
|
||||
controller : ns.importwizard.ImportWizard
|
||||
},
|
||||
'performance-info' : {
|
||||
template : 'templates/dialogs/performance-info.html',
|
||||
controller : ns.PerformanceInfoController
|
||||
},
|
||||
'unsupported-browser' : {
|
||||
template : 'templates/dialogs/unsupported-browser.html',
|
||||
controller : ns.UnsupportedBrowserController
|
||||
}
|
||||
};
|
||||
|
||||
ns.DialogsController = function (piskelController) {
|
||||
this.piskelController = piskelController;
|
||||
this.closePopupShortcut = pskl.service.keyboard.Shortcuts.MISC.CLOSE_POPUP;
|
||||
this.currentDialog_ = null;
|
||||
};
|
||||
|
||||
ns.DialogsController.prototype.init = function () {
|
||||
this.dialogContainer_ = document.getElementById('dialog-container');
|
||||
this.dialogWrapper_ = document.getElementById('dialog-container-wrapper');
|
||||
|
||||
$.subscribe(Events.DIALOG_SHOW, this.onDialogDisplayEvent_.bind(this));
|
||||
$.subscribe(Events.DIALOG_HIDE, this.hideDialog.bind(this));
|
||||
|
||||
var createPaletteShortcut = pskl.service.keyboard.Shortcuts.COLOR.CREATE_PALETTE;
|
||||
pskl.app.shortcutService.registerShortcut(createPaletteShortcut, this.onCreatePaletteShortcut_.bind(this));
|
||||
|
||||
var cheatsheetShortcut = pskl.service.keyboard.Shortcuts.MISC.CHEATSHEET;
|
||||
pskl.app.shortcutService.registerShortcut(cheatsheetShortcut, this.onCheatsheetShortcut_.bind(this));
|
||||
pskl.utils.Event.addEventListener('.cheatsheet-link', 'click', this.onCheatsheetShortcut_, this);
|
||||
|
||||
// adding the .animated class here instead of in the markup to avoid an animation during app startup
|
||||
this.dialogWrapper_.classList.add('animated');
|
||||
pskl.utils.Event.addEventListener(this.dialogWrapper_, 'click', this.onWrapperClicked_, this);
|
||||
};
|
||||
|
||||
ns.DialogsController.prototype.onCreatePaletteShortcut_ = function () {
|
||||
this.toggleDialog_('create-palette');
|
||||
};
|
||||
|
||||
ns.DialogsController.prototype.onCheatsheetShortcut_ = function () {
|
||||
this.toggleDialog_('cheatsheet');
|
||||
};
|
||||
|
||||
/**
|
||||
* If no dialog is currently displayed, the dialog with the provided id will be displayed.
|
||||
* If a dialog is displayed and has the same id as the provided id, hide it.
|
||||
* Otherwise, no-op.
|
||||
*/
|
||||
ns.DialogsController.prototype.toggleDialog_ = function (dialogId) {
|
||||
if (!this.isDisplayingDialog_()) {
|
||||
this.showDialog(dialogId);
|
||||
} else if (this.getCurrentDialogId_() === dialogId) {
|
||||
this.hideDialog();
|
||||
}
|
||||
};
|
||||
|
||||
ns.DialogsController.prototype.onDialogDisplayEvent_ = function (evt, args) {
|
||||
this.showDialog(args.dialogId, args.initArgs);
|
||||
};
|
||||
|
||||
ns.DialogsController.prototype.onWrapperClicked_ = function (evt) {
|
||||
if (evt.target === this.dialogWrapper_) {
|
||||
this.hideDialog();
|
||||
}
|
||||
};
|
||||
|
||||
ns.DialogsController.prototype.showDialog = function (dialogId, initArgs) {
|
||||
if (this.isDisplayingDialog_()) {
|
||||
return;
|
||||
}
|
||||
|
||||
var config = dialogs[dialogId];
|
||||
if (!config) {
|
||||
console.error('Could not find dialog configuration for dialogId : ' + dialogId);
|
||||
return;
|
||||
}
|
||||
|
||||
this.dialogContainer_.classList.add(dialogId);
|
||||
|
||||
this.dialogContainer_.innerHTML = pskl.utils.Template.get(config.template);
|
||||
var controller = new config.controller(this.piskelController);
|
||||
controller.init(initArgs);
|
||||
|
||||
this.currentDialog_ = {
|
||||
id : dialogId,
|
||||
controller : controller
|
||||
};
|
||||
|
||||
pskl.app.shortcutService.registerShortcut(this.closePopupShortcut, this.hideDialog.bind(this));
|
||||
this.dialogWrapper_.classList.add('show');
|
||||
};
|
||||
|
||||
ns.DialogsController.prototype.hideDialog = function () {
|
||||
if (this.isHiding_ || !this.isDisplayingDialog_()) {
|
||||
return;
|
||||
}
|
||||
|
||||
pskl.app.shortcutService.unregisterShortcut(this.closePopupShortcut);
|
||||
this.dialogWrapper_.classList.remove('show');
|
||||
window.setTimeout(this.cleanupDialogContainer_.bind(this), 500);
|
||||
this.isHiding_ = true;
|
||||
};
|
||||
|
||||
ns.DialogsController.prototype.cleanupDialogContainer_ = function () {
|
||||
this.dialogContainer_.classList.remove(this.currentDialog_.id);
|
||||
this.currentDialog_.controller.destroy();
|
||||
this.currentDialog_ = null;
|
||||
|
||||
this.dialogContainer_.innerHTML = '';
|
||||
this.isHiding_ = false;
|
||||
};
|
||||
|
||||
ns.DialogsController.prototype.isDisplayingDialog_ = function () {
|
||||
return this.currentDialog_ !== null;
|
||||
};
|
||||
|
||||
ns.DialogsController.prototype.getCurrentDialogId_ = function () {
|
||||
if (this.currentDialog_) {
|
||||
return this.currentDialog_.id;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
})();
|
||||
11
dev/js/controller/dialogs/PerformanceInfoController.js
Normal file
11
dev/js/controller/dialogs/PerformanceInfoController.js
Normal file
@@ -0,0 +1,11 @@
|
||||
(function () {
|
||||
var ns = $.namespace('pskl.controller.dialogs');
|
||||
|
||||
ns.PerformanceInfoController = function () {};
|
||||
|
||||
pskl.utils.inherit(ns.PerformanceInfoController, ns.AbstractDialogController);
|
||||
|
||||
ns.PerformanceInfoController.prototype.init = function () {
|
||||
this.superclass.init.call(this);
|
||||
};
|
||||
})();
|
||||
13
dev/js/controller/dialogs/UnsupportedBrowserController.js
Normal file
13
dev/js/controller/dialogs/UnsupportedBrowserController.js
Normal file
@@ -0,0 +1,13 @@
|
||||
(function () {
|
||||
var ns = $.namespace('pskl.controller.dialogs');
|
||||
|
||||
ns.UnsupportedBrowserController = function () {};
|
||||
|
||||
pskl.utils.inherit(ns.UnsupportedBrowserController, ns.AbstractDialogController);
|
||||
|
||||
ns.UnsupportedBrowserController.prototype.init = function () {
|
||||
this.superclass.init.call(this);
|
||||
var currentUserAgentElement = document.querySelector('#current-user-agent');
|
||||
currentUserAgentElement.innerText = pskl.utils.UserAgent.getDisplayName();
|
||||
};
|
||||
})();
|
||||
198
dev/js/controller/dialogs/importwizard/ImportWizard.js
Normal file
198
dev/js/controller/dialogs/importwizard/ImportWizard.js
Normal file
@@ -0,0 +1,198 @@
|
||||
(function () {
|
||||
var ns = $.namespace('pskl.controller.dialogs.importwizard');
|
||||
|
||||
var stepDefinitions = {
|
||||
'IMAGE_IMPORT' : {
|
||||
controller : ns.steps.ImageImport,
|
||||
template : 'import-image-import'
|
||||
},
|
||||
'ADJUST_SIZE' : {
|
||||
controller : ns.steps.AdjustSize,
|
||||
template : 'import-adjust-size'
|
||||
},
|
||||
'INSERT_LOCATION' : {
|
||||
controller : ns.steps.InsertLocation,
|
||||
template : 'import-insert-location'
|
||||
},
|
||||
'SELECT_MODE' : {
|
||||
controller : ns.steps.SelectMode,
|
||||
template : 'import-select-mode'
|
||||
}
|
||||
};
|
||||
|
||||
ns.ImportWizard = function (piskelController, args) {
|
||||
this.piskelController = piskelController;
|
||||
|
||||
// Merge data object used by steps to communicate and share their
|
||||
// results.
|
||||
this.mergeData = {
|
||||
rawFiles : [],
|
||||
mergePiskel: null,
|
||||
origin: null,
|
||||
resize: null,
|
||||
insertIndex: null,
|
||||
insertMode: null
|
||||
};
|
||||
};
|
||||
|
||||
pskl.utils.inherit(ns.ImportWizard, pskl.controller.dialogs.AbstractDialogController);
|
||||
|
||||
ns.ImportWizard.prototype.init = function (initArgs) {
|
||||
this.superclass.init.call(this);
|
||||
|
||||
// Prepare mergeData object and wizard steps.
|
||||
this.mergeData.rawFiles = initArgs.rawFiles;
|
||||
this.steps = this.createSteps_();
|
||||
|
||||
// Start wizard widget.
|
||||
var wizardContainer = document.querySelector('.import-wizard-container');
|
||||
this.wizard = new pskl.widgets.Wizard(this.steps, wizardContainer);
|
||||
this.wizard.init();
|
||||
|
||||
if (this.hasSingleImage_()) {
|
||||
this.wizard.goTo('IMAGE_IMPORT');
|
||||
} else if (this.hasSinglePiskelFile_()) {
|
||||
// If a piskel file was provided we can directly go to
|
||||
pskl.utils.PiskelFileUtils.loadFromFile(this.mergeData.rawFiles[0],
|
||||
// onSuccess
|
||||
function (piskel) {
|
||||
this.mergeData.mergePiskel = piskel;
|
||||
this.wizard.goTo('SELECT_MODE');
|
||||
}.bind(this),
|
||||
// onError
|
||||
function (reason) {
|
||||
this.closeDialog();
|
||||
$.publish(Events.PISKEL_FILE_IMPORT_FAILED, [reason]);
|
||||
}.bind(this)
|
||||
);
|
||||
} else {
|
||||
console.error('Unsupported import. Only single piskel or single image are supported at the moment.');
|
||||
this.closeDialog();
|
||||
}
|
||||
};
|
||||
|
||||
ns.ImportWizard.prototype.back = function () {
|
||||
this.wizard.back();
|
||||
this.wizard.getCurrentStep().instance.onShow();
|
||||
};
|
||||
|
||||
ns.ImportWizard.prototype.next = function () {
|
||||
var step = this.wizard.getCurrentStep();
|
||||
|
||||
if (step.name === 'IMAGE_IMPORT') {
|
||||
this.wizard.goTo('SELECT_MODE');
|
||||
} else if (step.name === 'SELECT_MODE') {
|
||||
if (this.mergeData.importMode === ns.steps.SelectMode.MODES.REPLACE) {
|
||||
this.finalizeImport_();
|
||||
} else if (this.hasSameSize_()) {
|
||||
this.wizard.goTo('INSERT_LOCATION');
|
||||
} else {
|
||||
this.wizard.goTo('ADJUST_SIZE');
|
||||
}
|
||||
} else if (step.name === 'ADJUST_SIZE') {
|
||||
this.wizard.goTo('INSERT_LOCATION');
|
||||
} else if (step.name === 'INSERT_LOCATION') {
|
||||
this.finalizeImport_();
|
||||
}
|
||||
};
|
||||
|
||||
ns.ImportWizard.prototype.destroy = function (file) {
|
||||
Object.keys(this.steps).forEach(function (stepName) {
|
||||
var step = this.steps[stepName];
|
||||
step.instance.destroy();
|
||||
step.instance = null;
|
||||
step.el = null;
|
||||
}.bind(this));
|
||||
|
||||
this.superclass.destroy.call(this);
|
||||
};
|
||||
|
||||
ns.ImportWizard.prototype.createSteps_ = function () {
|
||||
// The IMAGE_IMPORT step is used only if there is a single image file
|
||||
// being imported.
|
||||
var hasSingleImage = this.hasSingleImage_();
|
||||
|
||||
var steps = {};
|
||||
Object.keys(stepDefinitions).forEach(function (stepName) {
|
||||
if (stepName === 'IMAGE_IMPORT' && !hasSingleImage) {
|
||||
return;
|
||||
}
|
||||
|
||||
var definition = stepDefinitions[stepName];
|
||||
var el = pskl.utils.Template.getAsHTML(definition.template);
|
||||
var instance = new definition.controller(this.piskelController, this, el);
|
||||
instance.init();
|
||||
steps[stepName] = {
|
||||
name: stepName,
|
||||
el: el,
|
||||
instance: instance
|
||||
};
|
||||
}.bind(this));
|
||||
|
||||
if (hasSingleImage) {
|
||||
steps.IMAGE_IMPORT.el.classList.add('import-first-step');
|
||||
} else {
|
||||
steps.SELECT_MODE.el.classList.add('import-first-step');
|
||||
}
|
||||
|
||||
return steps;
|
||||
};
|
||||
|
||||
ns.ImportWizard.prototype.finalizeImport_ = function () {
|
||||
var piskel = this.mergeData.mergePiskel;
|
||||
var mode = this.mergeData.importMode;
|
||||
|
||||
if (mode === ns.steps.SelectMode.MODES.REPLACE) {
|
||||
// Replace the current piskel and close the dialog.
|
||||
var message = 'This will replace your current animation,' +
|
||||
' are you sure you want to continue?';
|
||||
if (window.confirm(message)) {
|
||||
this.piskelController.setPiskel(piskel);
|
||||
this.closeDialog();
|
||||
}
|
||||
} else if (mode === ns.steps.SelectMode.MODES.MERGE) {
|
||||
var merge = pskl.utils.MergeUtils.merge(this.piskelController.getPiskel(), piskel, {
|
||||
insertIndex: this.mergeData.insertIndex,
|
||||
insertMode: this.mergeData.insertMode,
|
||||
origin: this.mergeData.origin,
|
||||
resize: this.mergeData.resize
|
||||
});
|
||||
this.piskelController.setPiskel(merge);
|
||||
|
||||
// Set the first imported layer as selected.
|
||||
var importedLayers = piskel.getLayers().length;
|
||||
var currentLayers = this.piskelController.getLayers().length;
|
||||
this.piskelController.setCurrentLayerIndex(currentLayers - importedLayers);
|
||||
|
||||
this.closeDialog();
|
||||
}
|
||||
};
|
||||
|
||||
ns.ImportWizard.prototype.hasSameSize_ = function () {
|
||||
var piskel = this.mergeData.mergePiskel;
|
||||
if (!piskel) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return piskel.width === this.piskelController.getWidth() &&
|
||||
piskel.height === this.piskelController.getHeight();
|
||||
};
|
||||
|
||||
ns.ImportWizard.prototype.hasSingleImage_ = function () {
|
||||
if (this.mergeData.rawFiles.length !== 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var file = this.mergeData.rawFiles[0];
|
||||
return file.type.indexOf('image') === 0;
|
||||
};
|
||||
|
||||
ns.ImportWizard.prototype.hasSinglePiskelFile_ = function () {
|
||||
if (this.mergeData.rawFiles.length !== 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var file = this.mergeData.rawFiles[0];
|
||||
return (/\.piskel$/).test(file.name);
|
||||
};
|
||||
})();
|
||||
@@ -0,0 +1,65 @@
|
||||
(function () {
|
||||
var ns = $.namespace('pskl.controller.dialogs.importwizard.steps');
|
||||
|
||||
ns.AbstractImportStep = function (piskelController, importController, container) {
|
||||
this.piskelController = piskelController;
|
||||
this.container = container;
|
||||
this.importController = importController;
|
||||
this.mergeData = this.importController.mergeData;
|
||||
};
|
||||
|
||||
ns.AbstractImportStep.prototype.init = function () {
|
||||
this.nextButton = this.container.querySelector('.import-next-button');
|
||||
this.backButton = this.container.querySelector('.import-back-button');
|
||||
|
||||
this.addEventListener(this.nextButton, 'click', this.onNextClick);
|
||||
this.addEventListener(this.backButton, 'click', this.onBackClick);
|
||||
};
|
||||
|
||||
ns.AbstractImportStep.prototype.addEventListener = function (el, type, cb) {
|
||||
pskl.utils.Event.addEventListener(el, type, cb, this);
|
||||
};
|
||||
|
||||
ns.AbstractImportStep.prototype.destroy = function () {
|
||||
if (this.framePickerWidget) {
|
||||
this.framePickerWidget.destroy();
|
||||
}
|
||||
|
||||
pskl.utils.Event.removeAllEventListeners(this);
|
||||
};
|
||||
|
||||
ns.AbstractImportStep.prototype.onNextClick = function () {
|
||||
this.importController.next(this);
|
||||
};
|
||||
|
||||
ns.AbstractImportStep.prototype.onBackClick = function () {
|
||||
this.importController.back(this);
|
||||
};
|
||||
|
||||
ns.AbstractImportStep.prototype.onShow = function () {
|
||||
var mergePiskel = this.mergeData.mergePiskel;
|
||||
if (!mergePiskel) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.framePickerWidget) {
|
||||
var framePickerContainer = this.container.querySelector('.import-preview');
|
||||
this.framePickerWidget = new pskl.widgets.FramePicker(mergePiskel, framePickerContainer);
|
||||
this.framePickerWidget.init();
|
||||
} else if (this.framePickerWidget.piskel != mergePiskel) {
|
||||
// If the piskel displayed by the frame picker is different from the previous one,
|
||||
// refresh the widget.
|
||||
this.framePickerWidget.piskel = mergePiskel;
|
||||
this.framePickerWidget.setFrameIndex(1);
|
||||
}
|
||||
|
||||
var metaHtml = pskl.utils.Template.getAndReplace('import-meta-content', {
|
||||
name : mergePiskel.getDescriptor().name,
|
||||
dimensions : pskl.utils.StringUtils.formatSize(mergePiskel.getWidth(), mergePiskel.getHeight()),
|
||||
frames : mergePiskel.getFrameCount(),
|
||||
layers : mergePiskel.getLayers().length
|
||||
});
|
||||
this.container.querySelector('.import-meta').innerHTML = metaHtml;
|
||||
};
|
||||
|
||||
})();
|
||||
110
dev/js/controller/dialogs/importwizard/steps/AdjustSize.js
Normal file
110
dev/js/controller/dialogs/importwizard/steps/AdjustSize.js
Normal file
@@ -0,0 +1,110 @@
|
||||
(function () {
|
||||
var ns = $.namespace('pskl.controller.dialogs.importwizard.steps');
|
||||
|
||||
ns.AdjustSize = function (piskelController, importController, container) {
|
||||
this.superclass.constructor.apply(this, arguments);
|
||||
};
|
||||
|
||||
ns.AdjustSize.OPTIONS = {
|
||||
KEEP: 'keep',
|
||||
EXPAND: 'expand'
|
||||
};
|
||||
|
||||
pskl.utils.inherit(ns.AdjustSize, ns.AbstractImportStep);
|
||||
|
||||
ns.AdjustSize.prototype.init = function () {
|
||||
this.superclass.init.call(this);
|
||||
|
||||
// Create anchor widget
|
||||
var anchorContainer = this.container.querySelector('.import-resize-anchor-container');
|
||||
this.anchorWidget = new pskl.widgets.AnchorWidget(anchorContainer, this.onAnchorChange_.bind(this));
|
||||
this.anchorWidget.setOrigin('TOPLEFT');
|
||||
|
||||
this.resizeInfoContainer = this.container.querySelector('.import-resize-info');
|
||||
this.addEventListener(this.resizeInfoContainer, 'change', this.onResizeOptionChange_);
|
||||
|
||||
// By default, set the mode to expand to avoid losing any image content.
|
||||
this.mergeData.resize = ns.AdjustSize.OPTIONS.EXPAND;
|
||||
};
|
||||
|
||||
ns.AdjustSize.prototype.destroy = function () {
|
||||
this.anchorWidget.destroy();
|
||||
this.superclass.destroy.call(this);
|
||||
};
|
||||
|
||||
ns.AdjustSize.prototype.onShow = function () {
|
||||
this.refresh_();
|
||||
this.superclass.onShow.call(this);
|
||||
};
|
||||
|
||||
ns.AdjustSize.prototype.refresh_ = function () {
|
||||
var isBigger = this.isImportedPiskelBigger_();
|
||||
var keep = this.mergeData.resize === ns.AdjustSize.OPTIONS.KEEP;
|
||||
|
||||
// Refresh resize partial
|
||||
var size = this.formatPiskelSize_(this.piskelController.getPiskel());
|
||||
var newSize = this.formatPiskelSize_(this.mergeData.mergePiskel);
|
||||
var markup;
|
||||
if (isBigger) {
|
||||
markup = pskl.utils.Template.getAndReplace('import-resize-bigger-partial', {
|
||||
size : size,
|
||||
newSize : newSize,
|
||||
keepChecked : keep ? 'checked="checked"' : '',
|
||||
expandChecked : keep ? '' : 'checked="checked"'
|
||||
});
|
||||
} else {
|
||||
markup = pskl.utils.Template.getAndReplace('import-resize-smaller-partial', {
|
||||
size : size,
|
||||
newSize : newSize
|
||||
});
|
||||
}
|
||||
this.resizeInfoContainer.innerHTML = markup;
|
||||
|
||||
// Update anchor widget
|
||||
if (this.mergeData.origin) {
|
||||
this.anchorWidget.setOrigin(this.mergeData.origin);
|
||||
}
|
||||
|
||||
// Update anchor widget info
|
||||
var anchorInfo = this.container.querySelector('.import-resize-anchor-info');
|
||||
if (isBigger && keep) {
|
||||
anchorInfo.innerHTML = [
|
||||
'<span class="import-resize-warning">',
|
||||
'Imported content will be cropped!',
|
||||
'</span>',
|
||||
' ',
|
||||
'Select crop origin'
|
||||
].join('');
|
||||
} else if (isBigger) {
|
||||
anchorInfo.innerHTML = 'Select the anchor for resizing the canvas';
|
||||
} else {
|
||||
anchorInfo.innerHTML = 'Select where the import should be positioned';
|
||||
}
|
||||
};
|
||||
|
||||
ns.AdjustSize.prototype.onAnchorChange_ = function (origin) {
|
||||
this.mergeData.origin = origin;
|
||||
};
|
||||
|
||||
ns.AdjustSize.prototype.onResizeOptionChange_ = function () {
|
||||
var value = this.resizeInfoContainer.querySelector(':checked').value;
|
||||
if (this.mergeData.resize != value) {
|
||||
this.mergeData.resize = value;
|
||||
this.refresh_();
|
||||
}
|
||||
};
|
||||
|
||||
ns.AdjustSize.prototype.isImportedPiskelBigger_ = function () {
|
||||
var piskel = this.mergeData.mergePiskel;
|
||||
if (!piskel) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return piskel.width > this.piskelController.getWidth() ||
|
||||
piskel.height > this.piskelController.getHeight();
|
||||
};
|
||||
|
||||
ns.AdjustSize.prototype.formatPiskelSize_ = function (piskel) {
|
||||
return pskl.utils.StringUtils.formatSize(piskel.width, piskel.height);
|
||||
};
|
||||
})();
|
||||
279
dev/js/controller/dialogs/importwizard/steps/ImageImport.js
Normal file
279
dev/js/controller/dialogs/importwizard/steps/ImageImport.js
Normal file
@@ -0,0 +1,279 @@
|
||||
(function () {
|
||||
var ns = $.namespace('pskl.controller.dialogs.importwizard.steps');
|
||||
|
||||
ns.ImageImport = function (piskelController, importController, container) {
|
||||
this.superclass.constructor.apply(this, arguments);
|
||||
this.importedImage_ = null;
|
||||
this.file_ = null;
|
||||
};
|
||||
|
||||
pskl.utils.inherit(ns.ImageImport, ns.AbstractImportStep);
|
||||
|
||||
ns.ImageImport.prototype.init = function (file) {
|
||||
this.superclass.init.call(this);
|
||||
|
||||
// This step is only used if rawFiles contains a single image.
|
||||
this.file_ = this.mergeData.rawFiles[0];
|
||||
|
||||
this.importPreview = this.container.querySelector('.import-section-preview');
|
||||
|
||||
this.fileNameContainer = this.container.querySelector('.import-image-file-name');
|
||||
|
||||
this.singleImportType = this.container.querySelector('[name=import-type][value=single]');
|
||||
this.sheetImportType = this.container.querySelector('[name=import-type][value=sheet]');
|
||||
|
||||
this.resizeWidth = this.container.querySelector('[name=resize-width]');
|
||||
this.resizeHeight = this.container.querySelector('[name=resize-height]');
|
||||
this.smoothResize = this.container.querySelector('[name=smooth-resize-checkbox]');
|
||||
|
||||
this.frameSizeX = this.container.querySelector('[name=frame-size-x]');
|
||||
this.frameSizeY = this.container.querySelector('[name=frame-size-y]');
|
||||
this.frameOffsetX = this.container.querySelector('[name=frame-offset-x]');
|
||||
this.frameOffsetY = this.container.querySelector('[name=frame-offset-y]');
|
||||
|
||||
this.addEventListener(this.singleImportType, 'change', this.onImportTypeChange_);
|
||||
this.addEventListener(this.sheetImportType, 'change', this.onImportTypeChange_);
|
||||
|
||||
this.addEventListener(this.resizeWidth, 'keyup', this.onResizeInputKeyUp_);
|
||||
this.addEventListener(this.resizeHeight, 'keyup', this.onResizeInputKeyUp_);
|
||||
this.addEventListener(this.frameSizeX, 'keyup', this.onFrameInputKeyUp_);
|
||||
this.addEventListener(this.frameSizeY, 'keyup', this.onFrameInputKeyUp_);
|
||||
this.addEventListener(this.frameOffsetX, 'keyup', this.onFrameInputKeyUp_);
|
||||
this.addEventListener(this.frameOffsetY, 'keyup', this.onFrameInputKeyUp_);
|
||||
|
||||
pskl.utils.FileUtils.readImageFile(this.file_, this.onImageLoaded_.bind(this));
|
||||
};
|
||||
|
||||
ns.ImageImport.prototype.onNextClick = function () {
|
||||
this.container.classList.add('import-image-loading');
|
||||
this.createPiskelFromImage().then(function (piskel) {
|
||||
this.mergeData.mergePiskel = piskel;
|
||||
this.superclass.onNextClick.call(this);
|
||||
}.bind(this)).catch(function (e) {
|
||||
console.error(e);
|
||||
});
|
||||
};
|
||||
|
||||
ns.ImageImport.prototype.onShow = function () {
|
||||
this.container.classList.remove('import-image-loading');
|
||||
};
|
||||
|
||||
ns.ImageImport.prototype.createPiskelFromImage = function () {
|
||||
var name = this.extractFileNameFromPath_(this.file_.name);
|
||||
// Remove extension from filename.
|
||||
name = name.replace(/\.[a-zA-Z]+$/, '');
|
||||
|
||||
var deferred = Q.defer();
|
||||
pskl.app.importService.newPiskelFromImage(
|
||||
this.importedImage_,
|
||||
{
|
||||
importType: this.getImportType_(),
|
||||
frameSizeX: this.getImportType_() === 'single' ?
|
||||
this.resizeWidth.value : this.sanitizeInputValue_(this.frameSizeX, 1),
|
||||
frameSizeY: this.getImportType_() === 'single' ?
|
||||
this.resizeHeight.value : this.sanitizeInputValue_(this.frameSizeY, 1),
|
||||
frameOffsetX: this.sanitizeInputValue_(this.frameOffsetX, 0),
|
||||
frameOffsetY: this.sanitizeInputValue_(this.frameOffsetY, 0),
|
||||
smoothing: !!this.smoothResize.checked,
|
||||
name: name
|
||||
},
|
||||
deferred.resolve
|
||||
);
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
ns.ImageImport.prototype.onImportTypeChange_ = function (evt) {
|
||||
if (this.getImportType_() === 'single') {
|
||||
// Using single image, so remove the frame grid
|
||||
this.hideFrameGrid_();
|
||||
} else {
|
||||
// Using spritesheet import, so draw the frame grid in the preview
|
||||
var x = this.sanitizeInputValue_(this.frameOffsetX, 0);
|
||||
var y = this.sanitizeInputValue_(this.frameOffsetY, 0);
|
||||
var w = this.sanitizeInputValue_(this.frameSizeX, 1);
|
||||
var h = this.sanitizeInputValue_(this.frameSizeY, 1);
|
||||
this.drawFrameGrid_(x, y, w, h);
|
||||
}
|
||||
};
|
||||
|
||||
ns.ImageImport.prototype.onResizeInputKeyUp_ = function (evt) {
|
||||
var from = evt.target.getAttribute('name');
|
||||
if (this.importedImage_) {
|
||||
this.synchronizeResizeFields_(evt.target.value, from);
|
||||
}
|
||||
};
|
||||
|
||||
ns.ImageImport.prototype.onFrameInputKeyUp_ = function (evt) {
|
||||
if (this.importedImage_) {
|
||||
this.synchronizeFrameFields_(evt.target.value);
|
||||
}
|
||||
};
|
||||
|
||||
ns.ImageImport.prototype.synchronizeResizeFields_ = function (value, from) {
|
||||
value = parseInt(value, 10);
|
||||
if (isNaN(value)) {
|
||||
value = 0;
|
||||
}
|
||||
var height = this.importedImage_.height;
|
||||
var width = this.importedImage_.width;
|
||||
|
||||
// Select single image import type since the user changed a value here
|
||||
this.singleImportType.checked = true;
|
||||
|
||||
if (from === 'resize-width') {
|
||||
this.resizeHeight.value = Math.round(value * height / width);
|
||||
} else {
|
||||
this.resizeWidth.value = Math.round(value * width / height);
|
||||
}
|
||||
};
|
||||
|
||||
ns.ImageImport.prototype.synchronizeFrameFields_ = function (value) {
|
||||
value = parseInt(value, 10);
|
||||
if (isNaN(value)) {
|
||||
value = 0;
|
||||
}
|
||||
|
||||
// Parse the frame input values
|
||||
var frameSizeX = this.sanitizeInputValue_(this.frameSizeX, 1);
|
||||
var frameSizeY = this.sanitizeInputValue_(this.frameSizeY, 1);
|
||||
var frameOffsetX = this.sanitizeInputValue_(this.frameOffsetX, 0);
|
||||
var frameOffsetY = this.sanitizeInputValue_(this.frameOffsetY, 0);
|
||||
|
||||
// Select spritesheet import type since the user changed a value here
|
||||
this.sheetImportType.checked = true;
|
||||
|
||||
// Draw the grid
|
||||
this.drawFrameGrid_(frameOffsetX, frameOffsetY, frameSizeX, frameSizeY);
|
||||
};
|
||||
|
||||
ns.ImageImport.prototype.sanitizeInputValue_ = function(input, minValue) {
|
||||
var value = parseInt(input.value, 10);
|
||||
if (value <= minValue || isNaN(value)) {
|
||||
input.value = minValue;
|
||||
value = minValue;
|
||||
}
|
||||
return value;
|
||||
};
|
||||
|
||||
ns.ImageImport.prototype.getImportType_ = function () {
|
||||
if (this.singleImportType.checked) {
|
||||
return this.singleImportType.value;
|
||||
} else if (this.sheetImportType.checked) {
|
||||
return this.sheetImportType.value;
|
||||
} else {
|
||||
throw 'Could not find the currently selected import type';
|
||||
}
|
||||
};
|
||||
|
||||
ns.ImageImport.prototype.onImageLoaded_ = function (image) {
|
||||
this.importedImage_ = image;
|
||||
|
||||
var w = this.importedImage_.width;
|
||||
var h = this.importedImage_.height;
|
||||
|
||||
// FIXME : We remove the onload callback here because JsGif will insert
|
||||
// the image again and we want to avoid retriggering the image onload
|
||||
this.importedImage_.onload = function () {};
|
||||
|
||||
var fileName = this.extractFileNameFromPath_(this.file_.name);
|
||||
this.fileNameContainer.textContent = fileName;
|
||||
this.fileNameContainer.setAttribute('title', fileName);
|
||||
|
||||
this.resizeWidth.value = w;
|
||||
this.resizeHeight.value = h;
|
||||
|
||||
this.frameSizeX.value = w;
|
||||
this.frameSizeY.value = h;
|
||||
this.frameOffsetX.value = 0;
|
||||
this.frameOffsetY.value = 0;
|
||||
|
||||
this.importPreview.innerHTML = '';
|
||||
this.importPreview.appendChild(this.createImagePreview_());
|
||||
};
|
||||
|
||||
ns.ImageImport.prototype.createImagePreview_ = function () {
|
||||
var image = document.createElement('IMG');
|
||||
image.src = this.importedImage_.src;
|
||||
return image;
|
||||
};
|
||||
|
||||
ns.ImageImport.prototype.extractFileNameFromPath_ = function (path) {
|
||||
var parts = [];
|
||||
if (path.indexOf('/') !== -1) {
|
||||
parts = path.split('/');
|
||||
} else if (path.indexOf('\\') !== -1) {
|
||||
parts = path.split('\\');
|
||||
} else {
|
||||
parts = [path];
|
||||
}
|
||||
return parts[parts.length - 1];
|
||||
};
|
||||
|
||||
ns.ImageImport.prototype.drawFrameGrid_ = function (frameX, frameY, frameW, frameH) {
|
||||
if (!this.importedImage_) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Grab the sizes of the source and preview images
|
||||
var width = this.importedImage_.width;
|
||||
var height = this.importedImage_.height;
|
||||
|
||||
var image = this.importPreview.querySelector('img');
|
||||
var previewWidth = image.offsetWidth;
|
||||
var previewHeight = image.offsetHeight;
|
||||
|
||||
var canvas = this.importPreview.querySelector('canvas');
|
||||
if (!canvas) {
|
||||
// Create a new canvas for the grid
|
||||
canvas = pskl.utils.CanvasUtils.createCanvas(
|
||||
previewWidth + 1,
|
||||
previewHeight + 1);
|
||||
this.importPreview.appendChild(canvas);
|
||||
}
|
||||
|
||||
var context = canvas.getContext('2d');
|
||||
context.clearRect(0, 0, canvas.width, canvas.height);
|
||||
context.beginPath();
|
||||
|
||||
// Calculate the number of whole frames
|
||||
var countX = Math.floor((width - frameX) / frameW);
|
||||
var countY = Math.floor((height - frameY) / frameH);
|
||||
|
||||
if (countX > 0 && countY > 0) {
|
||||
var scaleX = previewWidth / width;
|
||||
var scaleY = previewHeight / height;
|
||||
var maxWidth = countX * frameW + frameX;
|
||||
var maxHeight = countY * frameH + frameY;
|
||||
|
||||
// Draw the vertical lines
|
||||
for (var x = frameX + 0.5; x < maxWidth + 1 && x < width + 1; x += frameW) {
|
||||
context.moveTo(x * scaleX, frameY * scaleY);
|
||||
context.lineTo(x * scaleX, maxHeight * scaleY);
|
||||
}
|
||||
|
||||
// Draw the horizontal lines
|
||||
for (var y = frameY + 0.5; y < maxHeight + 1 && y < height + 1; y += frameH) {
|
||||
context.moveTo(frameX * scaleX, y * scaleY);
|
||||
context.lineTo(maxWidth * scaleX, y * scaleY);
|
||||
}
|
||||
|
||||
// Set the line style to dashed
|
||||
context.lineWidth = 1;
|
||||
// context.setLineDash([2, 1]);
|
||||
context.strokeStyle = 'gold';
|
||||
context.stroke();
|
||||
|
||||
// Show the canvas
|
||||
canvas.style.display = 'block';
|
||||
} else {
|
||||
this.hideFrameGrid_();
|
||||
}
|
||||
};
|
||||
|
||||
ns.ImageImport.prototype.hideFrameGrid_ = function() {
|
||||
var canvas = this.importPreview.querySelector('canvas');
|
||||
if (canvas) {
|
||||
canvas.style.display = 'none';
|
||||
}
|
||||
};
|
||||
})();
|
||||
@@ -0,0 +1,59 @@
|
||||
(function () {
|
||||
var ns = $.namespace('pskl.controller.dialogs.importwizard.steps');
|
||||
|
||||
ns.InsertLocation = function () {
|
||||
this.superclass.constructor.apply(this, arguments);
|
||||
};
|
||||
|
||||
ns.InsertLocation.MODES = {
|
||||
ADD : 'add',
|
||||
INSERT : 'insert'
|
||||
};
|
||||
|
||||
pskl.utils.inherit(ns.InsertLocation, ns.AbstractImportStep);
|
||||
|
||||
ns.InsertLocation.prototype.init = function () {
|
||||
this.superclass.init.call(this);
|
||||
this.framePreview = this.container.querySelector('.insert-frame-preview');
|
||||
this.currentPiskelFramePickerWidget = new pskl.widgets.FramePicker(
|
||||
this.piskelController.getPiskel(), this.framePreview);
|
||||
|
||||
this.insertModeContainer = this.container.querySelector('.insert-mode-container');
|
||||
this.addEventListener(this.insertModeContainer, 'change', this.onInsertModeChange_);
|
||||
this.mergeData.insertMode = ns.InsertLocation.MODES.ADD;
|
||||
};
|
||||
|
||||
ns.InsertLocation.prototype.onInsertModeChange_ = function () {
|
||||
var value = this.insertModeContainer.querySelector(':checked').value;
|
||||
this.mergeData.insertMode = value;
|
||||
|
||||
if (this.mergeData.insertMode === ns.InsertLocation.MODES.ADD) {
|
||||
this.currentPiskelFramePickerWidget.setFirstFrameIndex(0);
|
||||
} else {
|
||||
this.currentPiskelFramePickerWidget.setFirstFrameIndex(1);
|
||||
}
|
||||
};
|
||||
|
||||
ns.InsertLocation.prototype.onShow = function () {
|
||||
// Initialize the frame picker on show, to be able to calculate correctly the
|
||||
// container's offsetWidth and offsetHeight.
|
||||
this.currentPiskelFramePickerWidget.init();
|
||||
|
||||
var currentFrameIndex = this.piskelController.getCurrentFrameIndex();
|
||||
this.currentPiskelFramePickerWidget.setFrameIndex(currentFrameIndex + 1);
|
||||
this.currentPiskelFramePickerWidget.setFirstFrameIndex(0);
|
||||
|
||||
this.superclass.onShow.call(this);
|
||||
};
|
||||
|
||||
ns.InsertLocation.prototype.onNextClick = function () {
|
||||
var insertIndex = this.currentPiskelFramePickerWidget.getFrameIndex();
|
||||
this.mergeData.insertIndex = insertIndex;
|
||||
this.superclass.onNextClick.call(this);
|
||||
};
|
||||
|
||||
ns.InsertLocation.prototype.destroy = function () {
|
||||
this.currentPiskelFramePickerWidget.destroy();
|
||||
this.superclass.destroy.call(this);
|
||||
};
|
||||
})();
|
||||
42
dev/js/controller/dialogs/importwizard/steps/SelectMode.js
Normal file
42
dev/js/controller/dialogs/importwizard/steps/SelectMode.js
Normal file
@@ -0,0 +1,42 @@
|
||||
(function () {
|
||||
var ns = $.namespace('pskl.controller.dialogs.importwizard.steps');
|
||||
|
||||
ns.SelectMode = function (piskelController, importController, container) {
|
||||
this.superclass.constructor.apply(this, arguments);
|
||||
};
|
||||
|
||||
ns.SelectMode.MODES = {
|
||||
REPLACE : 'replace',
|
||||
MERGE : 'merge'
|
||||
};
|
||||
|
||||
pskl.utils.inherit(ns.SelectMode, ns.AbstractImportStep);
|
||||
|
||||
ns.SelectMode.prototype.init = function () {
|
||||
this.superclass.init.call(this);
|
||||
|
||||
var replaceButton = this.container.querySelector('.import-mode-replace-button');
|
||||
var mergeButton = this.container.querySelector('.import-mode-merge-button');
|
||||
|
||||
this.addEventListener(replaceButton, 'click', this.onReplaceButtonClick_);
|
||||
this.addEventListener(mergeButton, 'click', this.onMergeButtonClick_);
|
||||
};
|
||||
|
||||
ns.SelectMode.prototype.onShow = function () {
|
||||
this.superclass.onShow.call(this);
|
||||
};
|
||||
|
||||
ns.SelectMode.prototype.destroy = function () {
|
||||
this.superclass.destroy.call(this);
|
||||
};
|
||||
|
||||
ns.SelectMode.prototype.onReplaceButtonClick_ = function () {
|
||||
this.mergeData.importMode = ns.SelectMode.MODES.REPLACE;
|
||||
this.onNextClick();
|
||||
};
|
||||
|
||||
ns.SelectMode.prototype.onMergeButtonClick_ = function () {
|
||||
this.mergeData.importMode = ns.SelectMode.MODES.MERGE;
|
||||
this.onNextClick();
|
||||
};
|
||||
})();
|
||||
Reference in New Issue
Block a user