mirror of
https://github.com/piskelapp/piskel.git
synced 2023-08-10 21:12:52 +03:00
Palette creator can save palettes to local storage
This commit is contained in:
parent
e8db80a0ec
commit
8441f28ac1
@ -33,7 +33,7 @@
|
||||
"karma": "0.12.17",
|
||||
"karma-chrome-launcher": "^0.1.4",
|
||||
"karma-phantomjs-launcher": "^0.1.4",
|
||||
"karma-jasmine": "^0.1.5",
|
||||
"karma-jasmine": "^0.2.0",
|
||||
"nodewebkit": "~0.10.1"
|
||||
},
|
||||
"window": {
|
||||
|
@ -1,21 +0,0 @@
|
||||
#dialog-container.create-palette-method {
|
||||
width: 500px;
|
||||
height: 200px;
|
||||
top : 50%;
|
||||
left : 50%;
|
||||
position : absolute;
|
||||
margin-left: -250px;
|
||||
}
|
||||
|
||||
.show #dialog-container.create-palette-method {
|
||||
margin-top: -100px;
|
||||
}
|
||||
|
||||
.create-palette-method-item {
|
||||
line-height : 24px;
|
||||
}
|
||||
|
||||
.create-palette-method-item label{
|
||||
margin-top: 3px;
|
||||
margin-left: 5px;
|
||||
}
|
@ -51,6 +51,84 @@
|
||||
margin: 11px;
|
||||
}
|
||||
|
||||
.colors-list {
|
||||
overflow : hidden;
|
||||
width : 280px;
|
||||
}
|
||||
|
||||
.create-palette-color, .create-palette-new-color, .colors-list-drop-proxy{
|
||||
position:relative;
|
||||
float : left;
|
||||
|
||||
width : 44px;
|
||||
height : 44px;
|
||||
margin : 10px 0 0 10px;
|
||||
|
||||
box-sizing : border-box;
|
||||
|
||||
cursor : pointer;
|
||||
}
|
||||
|
||||
.create-palette-color {
|
||||
border:1px solid #2c2c2c;
|
||||
transition : border-color 0.2s;
|
||||
}
|
||||
.create-palette-color:hover {
|
||||
border:1px solid gold;
|
||||
}
|
||||
|
||||
.colors-list-drop-proxy {
|
||||
border:2px dotted #eee;
|
||||
}
|
||||
|
||||
.create-palette-new-color {
|
||||
border:2px dotted gold;
|
||||
|
||||
border-radius: 2px;
|
||||
line-height: 40px;
|
||||
text-align: center;
|
||||
font-size: 20px;
|
||||
color: gold;
|
||||
}
|
||||
|
||||
.create-palette-color.selected {
|
||||
border:2px solid gold;
|
||||
}
|
||||
|
||||
.create-palette-remove-color {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
padding: 2px 4px;
|
||||
opacity : 0.2;
|
||||
|
||||
font-weight: bold;
|
||||
color: rgb(255,255,255);
|
||||
text-shadow : 0 0 1px rgb(0,0,0);
|
||||
|
||||
transition : opacity 0.3s, color 0.1s;
|
||||
}
|
||||
|
||||
.light-color .create-palette-remove-color {
|
||||
color: rgb(0,0,0);
|
||||
text-shadow : 0 0 1px rgb(255,255,255);
|
||||
}
|
||||
|
||||
.selected .create-palette-remove-color {
|
||||
top: -1px;
|
||||
right: -1px;
|
||||
}
|
||||
|
||||
.create-palette-color:hover .create-palette-remove-color {
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.create-palette-color .create-palette-remove-color:hover {
|
||||
opacity: 1;
|
||||
color: rgb(240,80,80);
|
||||
text-shadow : 0 0 1px rgb(0,0,0);
|
||||
}
|
||||
|
||||
/*SPECTRUM OVERRIDES*/
|
||||
|
||||
.create-palette .sp-container{
|
||||
|
@ -1,212 +0,0 @@
|
||||
.palette-manager-wrapper {
|
||||
height: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.palette-manager-body {
|
||||
position: absolute;
|
||||
top: 45px;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.palette-manager-head {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
background: gold;
|
||||
margin: 0;
|
||||
padding: 10px;
|
||||
color: black;
|
||||
font-size: 1.8em;
|
||||
box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
}
|
||||
|
||||
.palette-manager-drawer {
|
||||
width: 200px;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.palette-manager-list {
|
||||
position: absolute;
|
||||
top:40px;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.palette-manager-actions {
|
||||
position: absolute;
|
||||
height:40px;
|
||||
line-height:40px;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.palette-manager-actions-button {
|
||||
width: 80px;
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.palette-manager-palette-button,
|
||||
.palette-manager-actions-button {
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.palette-manager-list li {
|
||||
height: 48px;
|
||||
line-height: 48px;
|
||||
padding-left:10px;
|
||||
|
||||
font-size: 1.4em;
|
||||
|
||||
box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
|
||||
border-bottom: 1px solid #666;
|
||||
cursor:pointer;
|
||||
}
|
||||
|
||||
.palette-manager-list li:hover {
|
||||
background : #222;
|
||||
}
|
||||
|
||||
.palette-manager-list li.selected {
|
||||
color : gold;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.palette-manager-list li:nth-child(1) {
|
||||
border-top: 1px solid #666;
|
||||
}
|
||||
|
||||
.palette-manager-details {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 200px;
|
||||
|
||||
box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
|
||||
border-left:1px solid #666;
|
||||
}
|
||||
|
||||
.palette-manager-details-head {
|
||||
position: absolute;
|
||||
height:40px;
|
||||
line-height:40px;
|
||||
width: 100%;
|
||||
|
||||
box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
}
|
||||
|
||||
.palette-manager-details-head-name {
|
||||
padding: 0 10px 0 20px;
|
||||
font-size: 1.5em;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.palette-manager-details-head .edit-icon {
|
||||
width: 24px;
|
||||
display: inline-block;
|
||||
background-size: 16px;
|
||||
}
|
||||
|
||||
.palette-manager-details-head-actions {
|
||||
float: right;
|
||||
line-height: 40px;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
.palette-manager-details-body {
|
||||
position: absolute;
|
||||
top:40px;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
overflow: auto;
|
||||
|
||||
box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.palette-manager-color-card {
|
||||
width: 120px;
|
||||
height: 180px;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
margin: 20px 0 20px 20px;
|
||||
box-shadow: 0 0 0px 0px gold;
|
||||
transition: box-shadow 0.3s;
|
||||
}
|
||||
|
||||
.palette-manager-color-card:hover {
|
||||
box-shadow: 0 0 4px 1px gold;
|
||||
}
|
||||
|
||||
.palette-manager-delete-card {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 20px;
|
||||
|
||||
text-align: center;
|
||||
font-size: 1.6em;
|
||||
font-weight: bold;
|
||||
color: rgb(255,255,255);
|
||||
text-shadow : 0 0 2px rgb(0,0,0);
|
||||
cursor: pointer;
|
||||
|
||||
opacity : 0.2;
|
||||
transition : opacity 0.3s, color 0.1s;
|
||||
}
|
||||
|
||||
.palette-manager-color-card:hover .palette-manager-delete-card {
|
||||
opacity : 0.6;
|
||||
}
|
||||
|
||||
.palette-manager-color-card .palette-manager-delete-card:hover {
|
||||
opacity : 1;
|
||||
color: rgb(240,80,80);
|
||||
}
|
||||
|
||||
.palette-manager-new-color .palette-manager-color-square {
|
||||
border: 3px dotted #888;
|
||||
border-bottom-width: 0;
|
||||
box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
border-radius: 3px 3px 0 0;
|
||||
cursor: pointer;
|
||||
text-align: center;
|
||||
font-size: 24px;
|
||||
color: #888;
|
||||
line-height: 120px;
|
||||
}
|
||||
|
||||
.palette-manager-color-square {
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
cursor: pointer;
|
||||
/*background-image:url(../img/tools/eyedropper.png);*/
|
||||
}
|
||||
|
||||
.palette-manager-color-details {
|
||||
color : #666;
|
||||
background: #eee;
|
||||
height: 60px;
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
.palette-manager-color-details li{
|
||||
line-height: 20px;
|
||||
font-weight: bold;
|
||||
}
|
@ -55,8 +55,28 @@
|
||||
border-right-color: transparent;
|
||||
}
|
||||
|
||||
|
||||
.palettes-list-secondary-color:before {
|
||||
right: 1px;
|
||||
border-left-color: transparent;
|
||||
}
|
||||
|
||||
.palette-action {
|
||||
width : 18px;
|
||||
height : 18px;
|
||||
line-height : 16px;
|
||||
|
||||
text-align:center;
|
||||
float : right;
|
||||
font-size : 12px;
|
||||
border: 1px solid gold;
|
||||
border-radius : 2px;
|
||||
box-sizing : border-box;
|
||||
margin : 3px 3px 3px 0;
|
||||
|
||||
cursor : pointer;
|
||||
transition : color 0.3s;
|
||||
}
|
||||
|
||||
.palette-action:hover {
|
||||
color : gold;
|
||||
}
|
@ -68,7 +68,6 @@
|
||||
<div id="dialog-container-wrapper">
|
||||
<div id="dialog-container">
|
||||
<iframe src="templates/dialogs/create-palette.html" onload="iframeloader.onLoad(event)" data-iframe-loader="store"></iframe>
|
||||
<iframe src="templates/dialogs/create-palette-method.html" onload="iframeloader.onLoad(event)" data-iframe-loader="store"></iframe>
|
||||
<iframe src="templates/dialogs/import-image.html" onload="iframeloader.onLoad(event)" data-iframe-loader="store"></iframe>
|
||||
<iframe src="templates/dialogs/browse-local.html" onload="iframeloader.onLoad(event)" data-iframe-loader="store"></iframe>
|
||||
</div>
|
||||
|
@ -27,7 +27,6 @@ var Constants = {
|
||||
|
||||
NO_PALETTE_ID : '__no-palette',
|
||||
CURRENT_COLORS_PALETTE_ID : '__current-colors',
|
||||
MANAGE_PALETTE_ID : '__manage-palettes',
|
||||
|
||||
// Used for Spectrum input
|
||||
PREFERRED_COLOR_FORMAT : 'rgb',
|
||||
|
@ -39,6 +39,9 @@
|
||||
this.piskelController = new pskl.controller.piskel.PublicPiskelController(this.corePiskelController);
|
||||
this.piskelController.init();
|
||||
|
||||
this.paletteService = new pskl.service.PaletteService();
|
||||
this.paletteService.init();
|
||||
|
||||
this.paletteController = new pskl.controller.PaletteController();
|
||||
this.paletteController.init();
|
||||
|
||||
@ -129,9 +132,6 @@
|
||||
if (pskl.devtools) {
|
||||
pskl.devtools.init();
|
||||
}
|
||||
|
||||
// FIXME : remove
|
||||
$.publish(Events.DIALOG_DISPLAY, 'create-palette');
|
||||
},
|
||||
|
||||
loadPiskel_ : function (serializedPiskel, descriptor, fps) {
|
||||
|
@ -13,19 +13,26 @@
|
||||
|
||||
ns.PalettesListController = function (paletteController, usedColorService) {
|
||||
this.usedColorService = usedColorService;
|
||||
this.paletteService = pskl.app.paletteService;
|
||||
this.paletteController = paletteController;
|
||||
};
|
||||
|
||||
ns.PalettesListController.prototype.init = function () {
|
||||
this.paletteColorTemplate_ = pskl.utils.Template.get('palette-color-template');
|
||||
|
||||
this.colorListContainer_ = document.querySelector('.palettes-list-colors');
|
||||
this.colorPaletteSelect_ = document.querySelector('.palettes-list-select');
|
||||
this.createPaletteButton_ = document.querySelector('.create-palette-button');
|
||||
|
||||
var createPaletteButton_ = document.querySelector('.create-palette-button');
|
||||
var paletteActions = document.querySelector('.palette-actions');
|
||||
|
||||
this.colorPaletteSelect_.addEventListener('change', this.onPaletteSelected_.bind(this));
|
||||
this.colorListContainer_.addEventListener('mouseup', this.onColorContainerMouseup.bind(this));
|
||||
this.colorListContainer_.addEventListener('contextmenu', this.onColorContainerContextMenu.bind(this));
|
||||
this.createPaletteButton_.addEventListener('click', this.onCreatePaletteClick_.bind(this));
|
||||
|
||||
createPaletteButton_.addEventListener('click', this.onCreatePaletteClick_.bind(this));
|
||||
paletteActions.addEventListener('click', this.onPaletteActionsClick_.bind(this));
|
||||
|
||||
|
||||
$.subscribe(Events.PALETTE_LIST_UPDATED, this.onPaletteListUpdated.bind(this));
|
||||
$.subscribe(Events.CURRENT_COLORS_UPDATED, this.fillColorListContainer.bind(this));
|
||||
@ -42,7 +49,7 @@
|
||||
id : Constants.CURRENT_COLORS_PALETTE_ID,
|
||||
name : 'Current colors'
|
||||
}];
|
||||
palettes = palettes.concat(this.retrievePalettes());
|
||||
palettes = palettes.concat(this.paletteService.getPalettes());
|
||||
|
||||
var html = palettes.map(function (palette) {
|
||||
return pskl.utils.Template.replace('<option value="{{id}}">{{name}}</option>', palette);
|
||||
@ -74,7 +81,7 @@
|
||||
if (paletteId === Constants.CURRENT_COLORS_PALETTE_ID) {
|
||||
colors = this.usedColorService.getCurrentColors();
|
||||
} else {
|
||||
var palette = this.getPaletteById(paletteId, this.retrievePalettes());
|
||||
var palette = this.paletteService.getPaletteById(paletteId);
|
||||
if (palette) {
|
||||
colors = palette.colors;
|
||||
}
|
||||
@ -87,14 +94,14 @@
|
||||
return colors;
|
||||
};
|
||||
|
||||
ns.PalettesListController.prototype.selectPalette = function (paletteId) {
|
||||
this.colorPaletteSelect_.value = paletteId;
|
||||
};
|
||||
|
||||
ns.PalettesListController.prototype.selectPaletteFromUserSettings = function () {
|
||||
this.selectPalette(pskl.UserSettings.get(pskl.UserSettings.SELECTED_PALETTE));
|
||||
};
|
||||
|
||||
ns.PalettesListController.prototype.selectPalette = function (paletteId) {
|
||||
this.colorPaletteSelect_.value = paletteId;
|
||||
};
|
||||
|
||||
ns.PalettesListController.prototype.onPaletteSelected_ = function (evt) {
|
||||
var paletteId = this.colorPaletteSelect_.value;
|
||||
pskl.UserSettings.set(pskl.UserSettings.SELECTED_PALETTE, paletteId);
|
||||
@ -102,7 +109,39 @@
|
||||
};
|
||||
|
||||
ns.PalettesListController.prototype.onCreatePaletteClick_ = function (evt) {
|
||||
$.publish(Events.DIALOG_DISPLAY, 'create-palette-method');
|
||||
$.publish(Events.DIALOG_DISPLAY, 'create-palette');
|
||||
};
|
||||
|
||||
ns.PalettesListController.prototype.onPaletteActionsClick_ = function (evt) {
|
||||
var classList = evt.target.classList;
|
||||
if (classList.contains('palette-action-edit')) {
|
||||
this.editSelectedPalette_();
|
||||
} else if (classList.contains('palette-action-delete')) {
|
||||
this.deleteSelectedPalette_();
|
||||
} else if (classList.contains('palette-action-download')) {
|
||||
this.downloadSelectedPalette_();
|
||||
}
|
||||
};
|
||||
|
||||
ns.PalettesListController.prototype.editSelectedPalette_ = function () {
|
||||
var paletteId = this.colorPaletteSelect_.value;
|
||||
$.publish(Events.DIALOG_DISPLAY, {
|
||||
dialogId : 'create-palette',
|
||||
initArgs : paletteId
|
||||
});
|
||||
};
|
||||
|
||||
ns.PalettesListController.prototype.deleteSelectedPalette_ = function () {
|
||||
var paletteId = this.colorPaletteSelect_.value;
|
||||
var palette = this.paletteService.getPaletteById(paletteId);
|
||||
if (window.confirm('Are you sure you want to delete palette ' + palette.name)) {
|
||||
this.paletteService.deletePaletteById(palette.id);
|
||||
this.selectPalette(Constants.CURRENT_COLORS_PALETTE_ID);
|
||||
}
|
||||
};
|
||||
|
||||
ns.PalettesListController.prototype.downloadSelectedPalette_ = function () {
|
||||
window.alert('not implemented yet');
|
||||
};
|
||||
|
||||
ns.PalettesListController.prototype.onColorContainerContextMenu = function (event) {
|
||||
@ -155,21 +194,4 @@
|
||||
this.selectPaletteFromUserSettings();
|
||||
this.fillColorListContainer();
|
||||
};
|
||||
|
||||
ns.PalettesListController.prototype.getPaletteById = function (paletteId, palettes) {
|
||||
var match = null;
|
||||
|
||||
palettes.forEach(function (palette) {
|
||||
if (palette.id === paletteId) {
|
||||
match = palette;
|
||||
}
|
||||
});
|
||||
|
||||
return match;
|
||||
};
|
||||
|
||||
ns.PalettesListController.prototype.retrievePalettes = function () {
|
||||
var palettesString = window.localStorage.getItem('piskel.palettes');
|
||||
return JSON.parse(palettesString) || [];
|
||||
};
|
||||
})();
|
@ -2,22 +2,34 @@
|
||||
var ns = $.namespace('pskl.controller.dialogs');
|
||||
|
||||
ns.CreatePaletteController = function (piskelController) {
|
||||
this.tinyColor = null;
|
||||
this.hsvColor = {h:0,s:0,v:0};
|
||||
this.palette = [];
|
||||
this.paletteService = pskl.app.paletteService;
|
||||
this.selectedIndex = -1;
|
||||
};
|
||||
|
||||
pskl.utils.inherit(ns.CreatePaletteController, ns.AbstractDialogController);
|
||||
|
||||
ns.CreatePaletteController.prototype.init = function () {
|
||||
ns.CreatePaletteController.prototype.init = function (paletteId) {
|
||||
this.superclass.init.call(this);
|
||||
console.log(paletteId);
|
||||
if (paletteId) {
|
||||
var palette = this.paletteService.getPaletteById(paletteId);
|
||||
this.palette = pskl.model.Palette.fromObject(palette);
|
||||
} else {
|
||||
paletteId = pskl.utils.Uuid.generate();
|
||||
this.palette = new pskl.model.Palette(paletteId, 'New palette', []);
|
||||
}
|
||||
|
||||
this.colorsList = document.querySelector('.colors-list');
|
||||
this.colorPickerContainer = document.querySelector('.color-picker-container');
|
||||
this.colorPreviewEl = document.querySelector('.color-preview');
|
||||
|
||||
this.submitButton = document.querySelector('.create-palette-submit');
|
||||
this.nameInput = document.querySelector('input[name="palette-name"]');
|
||||
this.nameInput.value = this.palette.name;
|
||||
|
||||
this.colorsList.addEventListener('click', this.onColorContainerClick_.bind(this));
|
||||
this.submitButton.addEventListener('click', this.onSubmitButtonClick_.bind(this));
|
||||
this.nameInput.addEventListener('input', this.onNameInputChange_.bind(this));
|
||||
|
||||
this.hslRgbColorPicker = new pskl.controller.widgets.HslRgbColorPicker(this.colorPickerContainer, this.onColorUpdated_.bind(this));
|
||||
this.hslRgbColorPicker.init();
|
||||
@ -26,45 +38,114 @@
|
||||
};
|
||||
|
||||
ns.CreatePaletteController.prototype.onColorUpdated_ = function (color) {
|
||||
this.colorPreviewEl.style.background = color.toRgbString();
|
||||
this.palette[this.selectedIndex] = color.toRgbString();
|
||||
this.refresh_();
|
||||
var rgbColor = color.toRgbString();
|
||||
this.colorPreviewEl.style.background = rgbColor;
|
||||
this.palette.set(this.selectedIndex, rgbColor);
|
||||
|
||||
this.refreshColorElement_(this.selectedIndex);
|
||||
};
|
||||
|
||||
/**
|
||||
* Lightweight refresh only changing the color of one element of the palette color list
|
||||
*/
|
||||
ns.CreatePaletteController.prototype.refreshColorElement_ = function (index) {
|
||||
var color = this.palette.get(this.selectedIndex);
|
||||
var element = document.querySelector('[data-palette-index="'+index+'"]');
|
||||
if (element) {
|
||||
element.style.background = color;
|
||||
element.classList.toggle('light-color', this.isLight_(color));
|
||||
}
|
||||
};
|
||||
|
||||
ns.CreatePaletteController.prototype.onColorContainerClick_ = function (evt) {
|
||||
var target = evt.target;
|
||||
if (target.dataset.paletteIndex) {
|
||||
this.selectColor_(target.dataset.paletteIndex);
|
||||
} else if (target.classList.contains('add-color-button')) {
|
||||
this.palette.push(this.palette[this.selectedIndex] || "#000000");
|
||||
this.refresh_();
|
||||
this.selectColor_(this.palette.length-1);
|
||||
if (target.classList.contains('create-palette-color')) {
|
||||
this.onPaletteColorClick_(evt, target);
|
||||
} else if (target.classList.contains('create-palette-new-color')) {
|
||||
this.onNewColorClick_(evt, target);
|
||||
} else if (target.classList.contains('create-palette-remove-color')) {
|
||||
this.onRemoveColorClick_(evt, target);
|
||||
}
|
||||
this.refresh_();
|
||||
};
|
||||
|
||||
ns.CreatePaletteController.prototype.onPaletteColorClick_ = function (evt, target) {
|
||||
var index = parseInt(target.dataset.paletteIndex,10);
|
||||
this.selectColor_(index);
|
||||
};
|
||||
|
||||
ns.CreatePaletteController.prototype.onRemoveColorClick_ = function (evt, target) {
|
||||
var colorElement = target.parentNode;
|
||||
var index = parseInt(colorElement.dataset.paletteIndex,10);
|
||||
this.removeColor_(index);
|
||||
};
|
||||
|
||||
ns.CreatePaletteController.prototype.onNewColorClick_ = function (evt, target) {
|
||||
var newColor = this.palette.get(this.selectedIndex) || '#000000';
|
||||
this.palette.add(newColor);
|
||||
this.selectColor_(this.palette.size()-1);
|
||||
};
|
||||
|
||||
ns.CreatePaletteController.prototype.onSubmitButtonClick_ = function (evt) {
|
||||
this.paletteService.savePalette(this.palette);
|
||||
this.closeDialog();
|
||||
};
|
||||
|
||||
ns.CreatePaletteController.prototype.onNameInputChange_ = function (evt) {
|
||||
this.palette.name = this.nameInput.value;
|
||||
};
|
||||
|
||||
ns.CreatePaletteController.prototype.selectColor_ = function (index) {
|
||||
this.selectedIndex = index;
|
||||
this.hslRgbColorPicker.setColor(this.palette.get(index));
|
||||
};
|
||||
|
||||
var previous = this.colorsList.querySelector('.selectedColor');
|
||||
if (previous) {
|
||||
previous.classList.remove('selected');
|
||||
}
|
||||
|
||||
var next = this.colorsList.querySelector('[data-palette-index="'+index+'"]');
|
||||
next.classList.add('selected');
|
||||
|
||||
this.hslRgbColorPicker.setColor(this.palette[index]);
|
||||
ns.CreatePaletteController.prototype.removeColor_ = function (index) {
|
||||
this.palette.removeAt(index);
|
||||
this.refresh_();
|
||||
};
|
||||
|
||||
ns.CreatePaletteController.prototype.refresh_ = function () {
|
||||
var html = "";
|
||||
var tpl = '<div data-palette-index="{{index}}" data-palette-color="{{color}}" style="height:40px;width:40px;float:left; margin:10px;background:{{color}}"></div>';
|
||||
this.palette.forEach(function (color, index) {
|
||||
html += pskl.utils.Template.replace(tpl, {color:color, index:index});
|
||||
});
|
||||
var tpl = pskl.utils.Template.get('create-palette-color-template');
|
||||
var colors = this.palette.colors;
|
||||
|
||||
html += '<div class=add-color-button style="height:40px;width:40px;margin:10px;float:left; background:gold">ADD</div>';
|
||||
colors.forEach(function (color, index) {
|
||||
var isSelected = (index === this.selectedIndex);
|
||||
|
||||
html += pskl.utils.Template.replace(tpl, {
|
||||
color:color, index:index,
|
||||
':selected':isSelected,
|
||||
':light-color':this.isLight_(color)
|
||||
});
|
||||
}.bind(this));
|
||||
|
||||
html += '<li class="create-palette-new-color">+</li>';
|
||||
|
||||
this.colorsList.innerHTML = html;
|
||||
|
||||
$('.colors-list').sortable({
|
||||
placeholder: 'colors-list-drop-proxy',
|
||||
update: this.onDrop_.bind(this),
|
||||
items: '.create-palette-color'
|
||||
});
|
||||
};
|
||||
|
||||
ns.CreatePaletteController.prototype.isLight_ = function (color) {
|
||||
var rgb = window.tinycolor(color).toRgb();
|
||||
return rgb.r+rgb.b+rgb.g > 128*3;
|
||||
};
|
||||
|
||||
|
||||
ns.CreatePaletteController.prototype.onDrop_ = function (evt, drop) {
|
||||
var colorElement = drop.item.get(0);
|
||||
|
||||
var oldIndex = parseInt(colorElement.dataset.paletteIndex, 10);
|
||||
var newIndex = $('.create-palette-color').index(drop.item);
|
||||
this.palette.move(oldIndex, newIndex);
|
||||
|
||||
this.selectedIndex = newIndex;
|
||||
|
||||
this.refresh_();
|
||||
};
|
||||
})();
|
@ -1,63 +0,0 @@
|
||||
(function () {
|
||||
var ns = $.namespace('pskl.controller.dialogs');
|
||||
|
||||
ns.CreatePaletteMethodController = function (piskelController) {
|
||||
};
|
||||
|
||||
pskl.utils.inherit(ns.CreatePaletteMethodController, ns.AbstractDialogController);
|
||||
|
||||
ns.CreatePaletteMethodController.prototype.init = function () {
|
||||
this.superclass.init.call(this);
|
||||
|
||||
this.createButton = document.querySelector('.create-palette-method-continue');
|
||||
this.cancelButton = document.querySelector('.create-palette-method-cancel');
|
||||
|
||||
this.createButton.addEventListener('click', this.onCreateButtonClick_.bind(this));
|
||||
|
||||
this.cancelButton.addEventListener('click', function () {
|
||||
$.publish(Events.DIALOG_HIDE);
|
||||
});
|
||||
};
|
||||
|
||||
ns.CreatePaletteMethodController.prototype.onCreateButtonClick_ = function (evt) {
|
||||
var method = this.getSelectedMethod_();
|
||||
|
||||
var initArgs = {
|
||||
method : method
|
||||
};
|
||||
|
||||
if (method === 'palette') {
|
||||
initArgs.paletteId = this.getSelectedPaletteId_();
|
||||
}
|
||||
|
||||
this.closeDialog();
|
||||
|
||||
window.setTimeout(function () {
|
||||
$.publish(Events.DIALOG_DISPLAY, {
|
||||
dialogId : 'create-palette',
|
||||
initArgs : initArgs
|
||||
});
|
||||
},500);
|
||||
};
|
||||
|
||||
ns.CreatePaletteMethodController.prototype.getSelectedMethod_ = function (evt) {
|
||||
var options = document.querySelectorAll('.create-palette-method-list input[type="radio"]');
|
||||
|
||||
var method;
|
||||
for (var i = 0 ; i < options.length ; i++) {
|
||||
console.log(options[i]);
|
||||
if (options[i].checked) {
|
||||
method = options[i].value;
|
||||
}
|
||||
}
|
||||
|
||||
return method;
|
||||
};
|
||||
|
||||
ns.CreatePaletteMethodController.prototype.getSelectedPaletteId_ = function (evt) {
|
||||
var select = document.querySelector('.palettes-list-select');
|
||||
return select.value;
|
||||
};
|
||||
|
||||
|
||||
})();
|
@ -2,14 +2,6 @@
|
||||
var ns = $.namespace('pskl.controller.dialogs');
|
||||
|
||||
var dialogs = {
|
||||
'manage-palettes' : {
|
||||
template : 'templates/dialogs/manage-palettes.html',
|
||||
controller : ns.PaletteManagerController
|
||||
},
|
||||
'create-palette-method' : {
|
||||
template : 'templates/dialogs/create-palette-method.html',
|
||||
controller : ns.CreatePaletteMethodController
|
||||
},
|
||||
'create-palette' : {
|
||||
template : 'templates/dialogs/create-palette.html',
|
||||
controller : ns.CreatePaletteController
|
||||
@ -35,7 +27,7 @@
|
||||
$.subscribe(Events.DIALOG_DISPLAY, this.onDialogDisplayEvent_.bind(this));
|
||||
$.subscribe(Events.DIALOG_HIDE, this.onDialogHideEvent_.bind(this));
|
||||
|
||||
pskl.app.shortcutService.addShortcut('alt+P', this.onDialogDisplayEvent_.bind(this, null, 'manage-palettes'));
|
||||
pskl.app.shortcutService.addShortcut('alt+P', this.onDialogDisplayEvent_.bind(this, null, 'create-palettes'));
|
||||
this.dialogWrapper_.classList.add('animated');
|
||||
};
|
||||
|
||||
|
@ -1,382 +0,0 @@
|
||||
(function () {
|
||||
var ns = $.namespace('pskl.controller.dialogs');
|
||||
|
||||
var tinycolor = window.tinycolor;
|
||||
|
||||
var SELECTED_CLASSNAME = 'selected';
|
||||
var NEW_COLOR_CLASS = 'palette-manager-new-color';
|
||||
var CLOSE_ICON_CLASS = 'palette-manager-delete-card';
|
||||
var EDIT_NAME_CLASS = 'edit-icon';
|
||||
|
||||
ns.PaletteManagerController = function (piskelController) {
|
||||
this.piskelController = piskelController;
|
||||
this.palettes = this.retrieveUserPalettes();
|
||||
this.originalPalettes = this.retrieveUserPalettes();
|
||||
this.selectedPaletteId = null;
|
||||
|
||||
// Keep track of all spectrum instances created, to dispose them when closing the popup
|
||||
this.spectrumContainers = [];
|
||||
};
|
||||
|
||||
pskl.utils.inherit(ns.PaletteManagerController, ns.AbstractDialogController);
|
||||
|
||||
ns.PaletteManagerController.prototype.init = function () {
|
||||
this.superclass.init.call(this);
|
||||
|
||||
this.palettesList = document.querySelector('.palette-manager-list');
|
||||
this.paletteBody = document.querySelector('.palette-manager-details-body');
|
||||
this.paletteHead = document.querySelector('.palette-manager-details-head');
|
||||
this.createButton = document.querySelector('.palette-manager-actions-button[data-action="create"]');
|
||||
this.saveAllButton = document.querySelector('.palette-manager-actions-button[data-action="save-all"]');
|
||||
|
||||
this.colorCardTemplate = pskl.utils.Template.get('palette-color-card-template');
|
||||
this.newColorTemplate = pskl.utils.Template.get('palette-new-color-template');
|
||||
this.paletteHeadTemplate = pskl.utils.Template.get('palette-details-head-template');
|
||||
|
||||
// Events
|
||||
this.palettesList.addEventListener('click', this.onPaletteListClick.bind(this));
|
||||
// Delegated event listener for events repeated on all cards
|
||||
this.paletteBody.addEventListener('click', this.delegatedPaletteBodyClick.bind(this));
|
||||
this.paletteHead.addEventListener('click', this.delegatedPaletteHeadClick.bind(this));
|
||||
this.createButton.addEventListener('click', this.onCreateClick_.bind(this));
|
||||
this.saveAllButton.addEventListener('click', this.saveAll.bind(this));
|
||||
|
||||
// Init markup
|
||||
this.createPaletteListMarkup();
|
||||
if (this.palettes.length > 0) {
|
||||
this.selectPalette(this.palettes[0].id);
|
||||
} else {
|
||||
this.createPalette('New palette');
|
||||
}
|
||||
};
|
||||
|
||||
ns.PaletteManagerController.prototype.destroy = function () {
|
||||
this.destroySpectrumPickers();
|
||||
};
|
||||
|
||||
ns.PaletteManagerController.prototype.onCreateClick_ = function (evt) {
|
||||
this.createPalette();
|
||||
};
|
||||
|
||||
ns.PaletteManagerController.prototype.createPalette = function (name) {
|
||||
if (!name) {
|
||||
name = window.prompt('Please enter a name for your palette', 'New palette');
|
||||
}
|
||||
if (name) {
|
||||
var palette = this.createPaletteObject(name);
|
||||
this.palettes.push(palette);
|
||||
this.createPaletteListMarkup();
|
||||
this.selectPalette(palette.id);
|
||||
}
|
||||
};
|
||||
|
||||
ns.PaletteManagerController.prototype.createPaletteObject = function (name) {
|
||||
return {
|
||||
id : 'palette-' + Date.now() + '-' + Math.floor(Math.random()*1000),
|
||||
name : name,
|
||||
colors : []
|
||||
};
|
||||
};
|
||||
|
||||
ns.PaletteManagerController.prototype.redraw = function () {
|
||||
this.createPaletteListMarkup();
|
||||
this.selectPalette(this.selectedPaletteId);
|
||||
};
|
||||
|
||||
ns.PaletteManagerController.prototype.selectPalette = function (paletteId) {
|
||||
this.deselectCurrentPalette();
|
||||
var paletteListItem = this.palettesList.querySelector('[data-palette-id='+paletteId+']');
|
||||
if (paletteListItem) {
|
||||
this.selectedPaletteId = paletteId;
|
||||
paletteListItem.classList.add(SELECTED_CLASSNAME);
|
||||
this.refreshPaletteDetails();
|
||||
}
|
||||
};
|
||||
|
||||
ns.PaletteManagerController.prototype.refreshPaletteDetails = function () {
|
||||
this.createPaletteHeadMarkup();
|
||||
this.createPaletteBodyMarkup();
|
||||
this.initPaletteDetailsEvents();
|
||||
this.initPaletteCardsSpectrum();
|
||||
};
|
||||
|
||||
ns.PaletteManagerController.prototype.createPaletteListMarkup = function () {
|
||||
var html = this.palettes.map(function (palette) {
|
||||
var paletteCopy = {
|
||||
id : palette.id,
|
||||
name : this.isPaletteModified(palette) ? palette.name + " *" : palette.name
|
||||
};
|
||||
return pskl.utils.Template.replace('<li data-palette-id="{{id}}">{{name}}</li>', paletteCopy);
|
||||
}.bind(this)).join('');
|
||||
this.palettesList.innerHTML = html;
|
||||
};
|
||||
|
||||
/**
|
||||
* Fill the palette body container with color cards for the selected palette
|
||||
*/
|
||||
ns.PaletteManagerController.prototype.createPaletteHeadMarkup = function () {
|
||||
var palette = this.getSelectedPalette();
|
||||
var dict = {
|
||||
'name' : palette.name,
|
||||
'save:disabled' : !this.isPaletteModified(palette),
|
||||
'revert:disabled' : !this.isPaletteModified(palette),
|
||||
'delete:disabled' : this.palettes.length < 2
|
||||
};
|
||||
var html = pskl.utils.Template.replace(this.paletteHeadTemplate, dict);
|
||||
|
||||
this.paletteHead.innerHTML = html;
|
||||
};
|
||||
|
||||
ns.PaletteManagerController.prototype.isPaletteModified = function (palette) {
|
||||
var isModified = false;
|
||||
var originalPalette = this.getPaletteById(palette.id, this.originalPalettes);
|
||||
if (originalPalette) {
|
||||
var differentName = originalPalette.name !== palette.name;
|
||||
var differentColors = palette.colors.join('') !== originalPalette.colors.join('');
|
||||
isModified = differentName || differentColors;
|
||||
} else {
|
||||
isModified = true;
|
||||
}
|
||||
return isModified;
|
||||
};
|
||||
|
||||
/**
|
||||
* Fill the palette body container with color cards for the selected palette
|
||||
*/
|
||||
ns.PaletteManagerController.prototype.createPaletteBodyMarkup = function () {
|
||||
var palette = this.getSelectedPalette();
|
||||
|
||||
var html = this.getColorCardsMarkup(palette.colors);
|
||||
html += pskl.utils.Template.replace(this.newColorTemplate, {classname : NEW_COLOR_CLASS});
|
||||
|
||||
this.paletteBody.innerHTML = html;
|
||||
};
|
||||
|
||||
ns.PaletteManagerController.prototype.initPaletteDetailsEvents = function () {
|
||||
// New Card click event
|
||||
var newCard = this.paletteBody.querySelector('.' + NEW_COLOR_CLASS);
|
||||
newCard.addEventListener('click', this.onNewCardClick.bind(this));
|
||||
|
||||
if (this.palettes.length < 2) {
|
||||
var deleteButton = this.paletteHead.querySelector('.palette-manager-palette-button[data-action="delete"]');
|
||||
deleteButton.setAttribute("disabled", "disabled");
|
||||
}
|
||||
};
|
||||
|
||||
ns.PaletteManagerController.prototype.onNewCardClick = function () {
|
||||
var color;
|
||||
var palette = this.getSelectedPalette();
|
||||
if (palette && palette.colors.length > 0) {
|
||||
color = palette.colors[palette.colors.length-1];
|
||||
} else {
|
||||
color = '#FFFFFF';
|
||||
}
|
||||
this.addColorInSelectedPalette(color);
|
||||
};
|
||||
|
||||
ns.PaletteManagerController.prototype.delegatedPaletteBodyClick = function (event) {
|
||||
var target = event.target;
|
||||
if (target.classList.contains(CLOSE_ICON_CLASS)) {
|
||||
var colorId = parseInt(target.parentNode.dataset.colorId, 10);
|
||||
this.removeColorInSelectedPalette(colorId);
|
||||
}
|
||||
};
|
||||
|
||||
ns.PaletteManagerController.prototype.delegatedPaletteHeadClick = function (event) {
|
||||
var target = event.target;
|
||||
if (target.classList.contains(EDIT_NAME_CLASS)) {
|
||||
this.renameSelectedPalette();
|
||||
} else if (target.classList.contains('palette-manager-palette-button')) {
|
||||
var action = target.dataset.action;
|
||||
if (action === 'save') {
|
||||
this.savePalette(this.getSelectedPalette().id);
|
||||
this.redraw();
|
||||
} else if (action === 'revert') {
|
||||
this.revertChanges();
|
||||
} else if (action === 'delete') {
|
||||
this.deleteSelectedPalette();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
ns.PaletteManagerController.prototype.getSpectrumSelector_ = function () {
|
||||
return ':not(.' + NEW_COLOR_CLASS + ')>.palette-manager-color-square';
|
||||
};
|
||||
|
||||
ns.PaletteManagerController.prototype.initPaletteCardsSpectrum = function () {
|
||||
var oSelf = this;
|
||||
var container = $(this.getSpectrumSelector_());
|
||||
container.spectrum({
|
||||
clickoutFiresChange : true,
|
||||
showInput: true,
|
||||
showButtons: false,
|
||||
change : function (color) {
|
||||
var target = this;
|
||||
var colorId = parseInt(target.parentNode.dataset.colorId, 10);
|
||||
oSelf.updateColorInSelectedPalette(colorId, color);
|
||||
},
|
||||
beforeShow : function() {
|
||||
var target = this;
|
||||
var colorId = parseInt(target.parentNode.dataset.colorId, 10);
|
||||
var palette = oSelf.getSelectedPalette();
|
||||
var color = palette.colors[colorId];
|
||||
container.spectrum("set", color);
|
||||
}
|
||||
});
|
||||
|
||||
this.spectrumContainers.push(container);
|
||||
};
|
||||
|
||||
/**
|
||||
* Destroy all spectrum instances generated by the palette manager
|
||||
*/
|
||||
ns.PaletteManagerController.prototype.destroySpectrumPickers = function () {
|
||||
this.spectrumContainers.forEach(function (container) {
|
||||
container.spectrum("destroy");
|
||||
});
|
||||
this.spectrumContainers = [];
|
||||
};
|
||||
|
||||
ns.PaletteManagerController.prototype.updateColorInSelectedPalette = function (colorId, color) {
|
||||
var palette = this.getSelectedPalette();
|
||||
var hexColor = '#' + (color.toHex().toUpperCase());
|
||||
palette.colors.splice(colorId, 1, hexColor);
|
||||
|
||||
this.redraw();
|
||||
};
|
||||
|
||||
ns.PaletteManagerController.prototype.addColorInSelectedPalette = function (color) {
|
||||
var selectedPalette = this.getSelectedPalette();
|
||||
selectedPalette.colors.push(color);
|
||||
|
||||
this.redraw();
|
||||
};
|
||||
|
||||
ns.PaletteManagerController.prototype.removeColorInSelectedPalette = function (colorId) {
|
||||
var palette = this.getSelectedPalette();
|
||||
palette.colors.splice(colorId, 1);
|
||||
|
||||
this.redraw();
|
||||
};
|
||||
|
||||
ns.PaletteManagerController.prototype.renameSelectedPalette = function () {
|
||||
var palette = this.getSelectedPalette();
|
||||
var name = window.prompt('Please enter a new name for palette "' + palette.name + '"', palette.name);
|
||||
if (name) {
|
||||
palette.name = name;
|
||||
this.redraw();
|
||||
}
|
||||
};
|
||||
|
||||
ns.PaletteManagerController.prototype.getSelectedPalette = function () {
|
||||
return this.getPaletteById(this.selectedPaletteId, this.palettes);
|
||||
};
|
||||
|
||||
ns.PaletteManagerController.prototype.getColorCardsMarkup = function (colors) {
|
||||
var html = colors.map(function (color, index) {
|
||||
var dict = {
|
||||
colorId : index,
|
||||
hex : color,
|
||||
rgb : tinycolor(color).toRgbString(),
|
||||
hsl : tinycolor(color).toHslString()
|
||||
};
|
||||
return pskl.utils.Template.replace(this.colorCardTemplate, dict);
|
||||
}.bind(this)).join('');
|
||||
return html;
|
||||
};
|
||||
|
||||
ns.PaletteManagerController.prototype.getPaletteById = function (paletteId, palettes) {
|
||||
var match = null;
|
||||
|
||||
palettes.forEach(function (palette) {
|
||||
if (palette.id === paletteId) {
|
||||
match = palette;
|
||||
}
|
||||
});
|
||||
|
||||
return match;
|
||||
};
|
||||
|
||||
ns.PaletteManagerController.prototype.removePaletteById = function (paletteId, palettes) {
|
||||
var palette = this.getPaletteById(paletteId, palettes);
|
||||
if (palette) {
|
||||
var index = palettes.indexOf(palette);
|
||||
palettes.splice(index, 1);
|
||||
}
|
||||
};
|
||||
|
||||
ns.PaletteManagerController.prototype.deselectCurrentPalette = function () {
|
||||
var selectedItem = this.palettesList.querySelector('.' + SELECTED_CLASSNAME);
|
||||
if (selectedItem) {
|
||||
this.selectedPaletteId = null;
|
||||
selectedItem.classList.remove(SELECTED_CLASSNAME);
|
||||
}
|
||||
};
|
||||
|
||||
ns.PaletteManagerController.prototype.revertChanges = function () {
|
||||
var palette = this.getSelectedPalette();
|
||||
var originalPalette = this.getPaletteById(palette.id, this.originalPalettes);
|
||||
palette.name = originalPalette.name;
|
||||
palette.colors = originalPalette.colors.slice(0);
|
||||
|
||||
this.redraw();
|
||||
};
|
||||
|
||||
ns.PaletteManagerController.prototype.deleteSelectedPalette = function () {
|
||||
var palette = this.getSelectedPalette();
|
||||
if (this.palettes.length > 1) {
|
||||
if (window.confirm('Are you sure you want to delete "' + palette.name + '" ?')) {
|
||||
this.removePaletteById(palette.id, this.palettes);
|
||||
this.removePaletteById(palette.id, this.originalPalettes);
|
||||
|
||||
this.persistToLocalStorage();
|
||||
|
||||
this.createPaletteListMarkup();
|
||||
this.selectPalette(this.palettes[0].id);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
ns.PaletteManagerController.prototype.onPaletteListClick = function (event) {
|
||||
var target = event.target;
|
||||
if (target.dataset.paletteId) {
|
||||
this.selectPalette(target.dataset.paletteId);
|
||||
}
|
||||
};
|
||||
|
||||
ns.PaletteManagerController.prototype.saveAll = function () {
|
||||
this.palettes.forEach(function (palette) {
|
||||
this.savePalette(palette.id);
|
||||
}.bind(this));
|
||||
|
||||
this.redraw();
|
||||
};
|
||||
|
||||
ns.PaletteManagerController.prototype.savePalette = function (paletteId) {
|
||||
var palette = this.getPaletteById(paletteId, this.palettes);
|
||||
var originalPalette = this.getPaletteById(paletteId, this.originalPalettes);
|
||||
if (originalPalette) {
|
||||
originalPalette.name = palette.name;
|
||||
originalPalette.colors = palette.colors;
|
||||
} else {
|
||||
this.originalPalettes.push(palette);
|
||||
}
|
||||
|
||||
this.persistToLocalStorage();
|
||||
|
||||
$.publish(Events.SHOW_NOTIFICATION, [{"content": "Palette " + palette.name + " successfully saved !"}]);
|
||||
window.setTimeout($.publish.bind($, Events.HIDE_NOTIFICATION), 2000);
|
||||
};
|
||||
|
||||
ns.PaletteManagerController.prototype.persistToLocalStorage = function () {
|
||||
window.localStorage.setItem('piskel.palettes', JSON.stringify(this.originalPalettes));
|
||||
this.originalPalettes = this.retrieveUserPalettes();
|
||||
$.publish(Events.PALETTE_LIST_UPDATED);
|
||||
};
|
||||
|
||||
ns.PaletteManagerController.prototype.retrieveUserPalettes = function () {
|
||||
var palettesString = window.localStorage.getItem('piskel.palettes');
|
||||
return JSON.parse(palettesString) || [];
|
||||
};
|
||||
|
||||
})();
|
38
src/js/model/Palette.js
Normal file
38
src/js/model/Palette.js
Normal file
@ -0,0 +1,38 @@
|
||||
(function () {
|
||||
var ns = $.namespace('pskl.model');
|
||||
|
||||
ns.Palette = function (id, name, colors) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.colors = colors;
|
||||
};
|
||||
|
||||
ns.Palette.fromObject = function (paletteObj) {
|
||||
var colors = paletteObj.colors.slice(0 , paletteObj.colors.length);
|
||||
return new ns.Palette(paletteObj.id, paletteObj.name, colors);
|
||||
};
|
||||
|
||||
ns.Palette.prototype.get = function (index) {
|
||||
return this.colors[index];
|
||||
};
|
||||
|
||||
ns.Palette.prototype.set = function (index, color) {
|
||||
this.colors[index] = color;
|
||||
};
|
||||
|
||||
ns.Palette.prototype.add = function (color) {
|
||||
this.colors.push(color);
|
||||
};
|
||||
|
||||
ns.Palette.prototype.size = function () {
|
||||
return this.colors.length;
|
||||
};
|
||||
|
||||
ns.Palette.prototype.removeAt = function (index) {
|
||||
this.colors.splice(index, 1);
|
||||
};
|
||||
|
||||
ns.Palette.prototype.move = function (oldIndex, newIndex) {
|
||||
this.colors.splice(newIndex, 0, this.colors.splice(oldIndex, 1)[0]);
|
||||
};
|
||||
})();
|
61
src/js/service/PaletteService.js
Normal file
61
src/js/service/PaletteService.js
Normal file
@ -0,0 +1,61 @@
|
||||
(function () {
|
||||
var ns = $.namespace('pskl.service');
|
||||
ns.PaletteService = function () {
|
||||
this.palettes = [];
|
||||
this.localStorageService = window.localStorage;
|
||||
};
|
||||
|
||||
ns.PaletteService.prototype.init = function () {};
|
||||
|
||||
ns.PaletteService.prototype.getPalettes = function () {
|
||||
var palettesString = this.localStorageService.getItem('piskel.palettes');
|
||||
return JSON.parse(palettesString) || [];
|
||||
};
|
||||
|
||||
ns.PaletteService.prototype.getPaletteById = function (paletteId) {
|
||||
var palettes = this.getPalettes();
|
||||
return this.findPaletteInArray_(paletteId, palettes);
|
||||
};
|
||||
|
||||
ns.PaletteService.prototype.savePalette = function (palette) {
|
||||
var palettes = this.getPalettes();
|
||||
var existingPalette = this.findPaletteInArray_(palette.id, palettes);
|
||||
if (existingPalette) {
|
||||
var currentIndex = palettes.indexOf(existingPalette);
|
||||
palettes.splice(currentIndex, 1, palette);
|
||||
} else {
|
||||
palettes.push(palette);
|
||||
}
|
||||
|
||||
this.savePalettes_(palettes);
|
||||
|
||||
$.publish(Events.SHOW_NOTIFICATION, [{"content": "Palette " + palette.name + " successfully saved !"}]);
|
||||
window.setTimeout($.publish.bind($, Events.HIDE_NOTIFICATION), 2000);
|
||||
};
|
||||
|
||||
ns.PaletteService.prototype.deletePaletteById = function (id) {
|
||||
var palettes = this.getPalettes();
|
||||
var filteredPalettes = palettes.filter(function (palette) {
|
||||
return palette.id !== id;
|
||||
});
|
||||
|
||||
this.savePalettes_(filteredPalettes);
|
||||
};
|
||||
|
||||
ns.PaletteService.prototype.savePalettes_ = function (palettes) {
|
||||
this.localStorageService.setItem('piskel.palettes', JSON.stringify(palettes));
|
||||
$.publish(Events.PALETTE_LIST_UPDATED);
|
||||
};
|
||||
|
||||
ns.PaletteService.prototype.findPaletteInArray_ = function (paletteId, palettes) {
|
||||
var match = null;
|
||||
|
||||
palettes.forEach(function (palette) {
|
||||
if (palette.id === paletteId) {
|
||||
match = palette;
|
||||
}
|
||||
});
|
||||
|
||||
return match;
|
||||
};
|
||||
})();
|
17
src/js/utils/Uuid.js
Normal file
17
src/js/utils/Uuid.js
Normal file
@ -0,0 +1,17 @@
|
||||
(function(){
|
||||
var ns = $.namespace('pskl.utils');
|
||||
|
||||
var s4 = function () {
|
||||
return Math.floor((1 + Math.random()) * 0x10000)
|
||||
.toString(16)
|
||||
.substring(1);
|
||||
};
|
||||
|
||||
ns.Uuid = {
|
||||
generate : function () {
|
||||
return 'ss-s-s-s-sss'.replace(/s/g, function () {
|
||||
return s4();
|
||||
});
|
||||
}
|
||||
};
|
||||
})();
|
@ -25,6 +25,7 @@
|
||||
"js/utils/PiskelFileUtils.js",
|
||||
"js/utils/Template.js",
|
||||
"js/utils/UserSettings.js",
|
||||
"js/utils/Uuid.js",
|
||||
"js/utils/Xhr.js",
|
||||
"js/utils/serialization/Serializer.js",
|
||||
"js/utils/serialization/Deserializer.js",
|
||||
@ -50,6 +51,7 @@
|
||||
"js/model/Layer.js",
|
||||
"js/model/piskel/Descriptor.js",
|
||||
"js/model/frame/CachedFrameProcessor.js",
|
||||
"js/model/Palette.js",
|
||||
"js/model/Piskel.js",
|
||||
|
||||
// Selection
|
||||
@ -99,9 +101,7 @@
|
||||
|
||||
// Dialogs sub-controllers
|
||||
"js/controller/dialogs/AbstractDialogController.js",
|
||||
"js/controller/dialogs/PaletteManagerController.js",
|
||||
"js/controller/dialogs/CreatePaletteController.js",
|
||||
"js/controller/dialogs/CreatePaletteMethodController.js",
|
||||
"js/controller/dialogs/ImportImageController.js",
|
||||
"js/controller/dialogs/BrowseLocalController.js",
|
||||
|
||||
@ -119,6 +119,7 @@
|
||||
"js/service/BackupService.js",
|
||||
"js/service/BeforeUnloadService.js",
|
||||
"js/service/HistoryService.js",
|
||||
"js/service/PaletteService.js",
|
||||
"js/service/SavedStatusService.js",
|
||||
"js/service/keyboard/ShortcutService.js",
|
||||
"js/service/keyboard/KeycodeTranslator.js",
|
||||
|
@ -14,10 +14,8 @@
|
||||
"css/color-picker-slider.css",
|
||||
"css/dialogs.css",
|
||||
"css/dialogs-import-image.css",
|
||||
"css/dialogs-manage-palettes.css",
|
||||
"css/dialogs-browse-local.css",
|
||||
"css/dialogs-create-palette.css",
|
||||
"css/dialogs-create-palette-method.css",
|
||||
"css/toolbox.css",
|
||||
"css/toolbox-layers-list.css",
|
||||
"css/toolbox-palettes-list.css",
|
||||
|
@ -1,28 +0,0 @@
|
||||
<div class="dialog-wrapper">
|
||||
<h3 class="dialog-head">
|
||||
Create palette
|
||||
<span class="palette-manager-close dialog-close">X</span>
|
||||
</h3>
|
||||
<div style="padding:10px 20px; font-size:1.3em">
|
||||
Select your creation method :
|
||||
<ul style="margin:10px 0" class="create-palette-method-list">
|
||||
<li class="create-palette-method-item">
|
||||
<input type="radio" name="palette-creation-mode" id="palette-creation-mode-manual" value="manual" checked="checked">
|
||||
<label for="palette-creation-mode-manual">Manual</label>
|
||||
</li>
|
||||
<li class="create-palette-method-item">
|
||||
<input type="radio" name="palette-creation-mode" id="palette-creation-mode-import" value="import">
|
||||
<label for="palette-creation-mode-import">Import from existing file or image</label><br>
|
||||
</li>
|
||||
<li class="create-palette-method-item">
|
||||
<input type="radio" name="palette-creation-mode" id="palette-creation-mode-palette" value="palette">
|
||||
<label for="palette-creation-mode-palette">Clone existing palette</label>
|
||||
<select class="palettes-list-select" style="margin:3px 0;">
|
||||
<option value="current-colors">Current colors</option>
|
||||
</select>
|
||||
</li>
|
||||
</ul>
|
||||
<button class="button button-primary create-palette-method-continue" style="float:right">Continue</button>
|
||||
<button class="button create-palette-method-cancel" style="float:right">Cancel</button>
|
||||
</div>
|
||||
</div>
|
@ -4,12 +4,11 @@
|
||||
<span class="dialog-close">X</span>
|
||||
</h3>
|
||||
<div class="dialog-create-palette" style="font-size:1.3em">
|
||||
<form action="" method="POST" name="create-palette-form">
|
||||
<div class="create-palette-section form-section">
|
||||
<span class="dialog-create-palette-name">Name :</span><input type="text" class="textfield" name="palette-name" placeholder="New palette"/>
|
||||
<span class="dialog-create-palette-name">Name :</span><input type="text" class="textfield" name="palette-name" placeholder="palette name ..."/>
|
||||
</div>
|
||||
<div class="colors-container">
|
||||
<div class="colors-list"></div>
|
||||
<ul class="colors-list"></ul>
|
||||
<div class="color-picker-container">
|
||||
<div class="color-picker-spectrum"></div>
|
||||
<div class="color-picker-slider">
|
||||
@ -46,8 +45,7 @@
|
||||
<div class="color-preview"></div>
|
||||
</div>
|
||||
</div>
|
||||
<input type="submit" name="create-palette-submit" class="button button-primary create-palette-submit" value="Save" />
|
||||
</form>
|
||||
<button type="button" name="create-palette-submit" class="button button-primary create-palette-submit">Save</button>
|
||||
</div>
|
||||
|
||||
<script type="text/template" id="color-picker-slider-template">
|
||||
@ -58,4 +56,14 @@
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="create-palette-color-template">
|
||||
<li
|
||||
class="create-palette-color {{:selected}} {{:light-color}}"
|
||||
style="background:{{color}}"
|
||||
data-palette-index="{{index}}"
|
||||
data-palette-color="{{color}}">
|
||||
<div class="create-palette-remove-color">X</div>
|
||||
</li>
|
||||
</script>
|
||||
|
||||
</div>
|
@ -1,57 +0,0 @@
|
||||
<div class="palette-manager-wrapper">
|
||||
<h3 class="palette-manager-head dialog-head">
|
||||
Palette manager
|
||||
<span class="dialog-close">X</span>
|
||||
</h3>
|
||||
<div class="palette-manager-body">
|
||||
<div class="palette-manager-drawer">
|
||||
<div class="palette-manager-actions">
|
||||
<button type="button" class="palette-manager-actions-button button " data-action="create">Create</button>
|
||||
<button type="button" class="palette-manager-actions-button button " data-action="save-all">Save all</button>
|
||||
</div>
|
||||
<ul class="palette-manager-list">
|
||||
</ul>
|
||||
</div>
|
||||
<div class="palette-manager-details">
|
||||
<div class="palette-manager-details-head"></div>
|
||||
<div class="palette-manager-details-body"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/template" id="palette-details-head-template">
|
||||
<span class="palette-manager-details-head-name">{{name}}</span>
|
||||
<span class="action-icon edit-icon" title="edit name"> </span>
|
||||
<div class="palette-manager-details-head-actions">
|
||||
<button class="palette-manager-palette-button button button-primary" {{save:disabled}} data-action="save" type="button">Save</button>
|
||||
<button class="palette-manager-palette-button button " {{revert:disabled}} data-action="revert" type="button">Revert</button>
|
||||
<button class="palette-manager-palette-button button " {{delete:disabled}} data-action="delete" type="button">Delete</button>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="palette-color-card-template">
|
||||
<div class="palette-manager-color-card" data-color-id="{{colorId}}">
|
||||
<span class="palette-manager-delete-card" title="remove this color">X</span>
|
||||
<div class="palette-manager-color-square" style="background-color:{{hex}}"></div>
|
||||
<div class="palette-manager-color-details allow-user-select">
|
||||
<ul>
|
||||
<li>{{hex}}</li>
|
||||
<li>{{rgb}}</li>
|
||||
<li>{{hsl}}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="palette-new-color-template">
|
||||
<div class="palette-manager-color-card {{classname}}">
|
||||
<div class="palette-manager-color-square">Add</div>
|
||||
<div class="palette-manager-color-details">
|
||||
<ul>
|
||||
<li>Hex</li>
|
||||
<li>RGB</li>
|
||||
<li>HSL</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
@ -1,18 +1,30 @@
|
||||
<div class="toolbox-container palettes-list-container">
|
||||
<h3 class="toolbox-title palettes-title"
|
||||
<h3 class="toolbox-title palettes-title"
|
||||
style="overflow: hidden;height: 36px;box-sizing: border-box;border-bottom: 1px solid #444;">
|
||||
<span style="line-height:20px ">Palettes</span>
|
||||
<div
|
||||
class="button button-primary create-palette-button"
|
||||
<div
|
||||
class="button button-primary create-palette-button"
|
||||
title="Create new palette"
|
||||
rel="tooltip"
|
||||
data-placement="top"
|
||||
style="width:20px; height:20px; float:right; font-size:1.1em">+</div>
|
||||
</h3>
|
||||
<div
|
||||
class="palettes-actions"
|
||||
<div
|
||||
class="palette-actions"
|
||||
style="background-color:#3f3f3f; border-bottom:#222; height:24px; padding:0 3px;">
|
||||
<select class="palettes-list-select" style="margin:3px 0;"></select>
|
||||
<div class="palette-action palette-action-download"
|
||||
title="Download palette"
|
||||
rel="tooltip"
|
||||
data-placement="top">dl</div>
|
||||
<div class="palette-action palette-action-delete"
|
||||
title="Delete palette"
|
||||
rel="tooltip"
|
||||
data-placement="top">d</div>
|
||||
<div class="palette-action palette-action-edit"
|
||||
title="Edit palette"
|
||||
rel="tooltip"
|
||||
data-placement="top">e</div>
|
||||
</div>
|
||||
<div class="palettes-list-colors"></div>
|
||||
<script type="text/template" id="palette-color-template">
|
||||
|
23
test/js/model/PaletteTest.js
Normal file
23
test/js/model/PaletteTest.js
Normal file
@ -0,0 +1,23 @@
|
||||
describe("Palette", function() {
|
||||
|
||||
beforeEach(function() {});
|
||||
afterEach(function() {});
|
||||
|
||||
it("moves colors correctly", function() {
|
||||
// when
|
||||
var colors = [
|
||||
'#000000',
|
||||
'#111111',
|
||||
'#222222'
|
||||
];
|
||||
var palette = new pskl.model.Palette('id', 'name', colors);
|
||||
|
||||
// then
|
||||
palette.move(2,0);
|
||||
|
||||
// verify
|
||||
expect(palette.get(0)).toBe('#222222');
|
||||
expect(palette.get(1)).toBe('#000000');
|
||||
expect(palette.get(2)).toBe('#111111');
|
||||
});
|
||||
});
|
144
test/js/service/PaletteServiceTest.js
Normal file
144
test/js/service/PaletteServiceTest.js
Normal file
@ -0,0 +1,144 @@
|
||||
describe("Palette Service", function() {
|
||||
var paletteService = null;
|
||||
var localStorage = {};
|
||||
|
||||
var localStorageService;
|
||||
|
||||
|
||||
var addPalette = function (id, name, color) {
|
||||
var palette = new pskl.model.Palette(id, name, [color]);
|
||||
paletteService.savePalette(palette);
|
||||
};
|
||||
|
||||
var verifyPaletteIsStored = function (paletteId) {
|
||||
var palette = paletteService.getPaletteById(paletteId);
|
||||
expect(palette).not.toBeNull();
|
||||
return palette;
|
||||
};
|
||||
|
||||
var verifyPaletteIsNotStored = function (paletteId) {
|
||||
var palette = paletteService.getPaletteById(paletteId);
|
||||
expect(palette).toBeNull();
|
||||
};
|
||||
|
||||
beforeEach(function() {
|
||||
localStorage = {};
|
||||
|
||||
localStorageService = {
|
||||
getItem : function (key) {
|
||||
if (localStorage.hasOwnProperty(key)) {
|
||||
return localStorage[key];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
},
|
||||
setItem : function (key, item) {
|
||||
localStorage[key] = item;
|
||||
}
|
||||
};
|
||||
|
||||
paletteService = new pskl.service.PaletteService();
|
||||
paletteService.localStorageService = localStorageService;
|
||||
});
|
||||
|
||||
it("returns an empty array when no palette is stored", function() {
|
||||
spyOn(localStorageService, 'getItem').and.callThrough();
|
||||
|
||||
var palettes = paletteService.getPalettes();
|
||||
expect(Array.isArray(palettes)).toBe(true);
|
||||
expect(palettes.length).toBe(0);
|
||||
expect(localStorageService.getItem).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("can store a palette", function() {
|
||||
// when
|
||||
spyOn(localStorageService, 'setItem').and.callThrough();
|
||||
|
||||
var paletteId = 'palette-id';
|
||||
var paletteName = 'palette-name';
|
||||
var paletteColor = '#001122';
|
||||
|
||||
// then
|
||||
addPalette(paletteId, paletteName, paletteColor);
|
||||
var palettes = paletteService.getPalettes();
|
||||
|
||||
// verify
|
||||
expect(localStorageService.setItem).toHaveBeenCalled();
|
||||
|
||||
expect(Array.isArray(palettes)).toBe(true);
|
||||
expect(palettes.length).toBe(1);
|
||||
|
||||
var retrievedPalette = paletteService.getPaletteById(paletteId);
|
||||
expect(retrievedPalette).toBeDefined();
|
||||
expect(retrievedPalette.id).toBe(paletteId);
|
||||
expect(retrievedPalette.name).toBe(paletteName);
|
||||
|
||||
var colors = retrievedPalette.colors;
|
||||
expect(Array.isArray(colors)).toBe(true);
|
||||
expect(colors.length).toBe(1);
|
||||
|
||||
var color = colors[0];
|
||||
expect(color).toBe(paletteColor);
|
||||
});
|
||||
|
||||
it("updates a palette", function() {
|
||||
// when
|
||||
var paletteId = 'palette-id';
|
||||
var paletteName = 'palette-name';
|
||||
var paletteColor1 = '#001122';
|
||||
var paletteColor2 = '#334455';
|
||||
|
||||
// then
|
||||
addPalette(paletteId, paletteName, paletteColor1);
|
||||
addPalette(paletteId, paletteName, paletteColor2);
|
||||
|
||||
// verify
|
||||
var palettes = paletteService.getPalettes();
|
||||
expect(palettes.length).toBe(1);
|
||||
|
||||
var retrievedPalette = paletteService.getPaletteById(paletteId);
|
||||
var color = retrievedPalette.colors[0];
|
||||
expect(color).toBe(paletteColor2);
|
||||
});
|
||||
|
||||
it("can delete a palette", function() {
|
||||
// when
|
||||
addPalette('palette-id', 'palette-name', ['#001122']);
|
||||
|
||||
// then
|
||||
paletteService.deletePaletteById('palette-id');
|
||||
|
||||
// verify
|
||||
var palettes = paletteService.getPalettes();
|
||||
expect(palettes.length).toBe(0);
|
||||
});
|
||||
|
||||
it("attempts to delete unexisting palette without side effect", function() {
|
||||
// when
|
||||
addPalette('palette-id', 'palette-name', ['#001122']);
|
||||
|
||||
// then
|
||||
var palettes = paletteService.getPalettes();
|
||||
paletteService.deletePaletteById('some-other-palette-id');
|
||||
|
||||
// verify
|
||||
expect(palettes.length).toBe(1);
|
||||
});
|
||||
|
||||
it("deletes the correct palette when several palettes are stored", function() {
|
||||
// when
|
||||
addPalette('palette-id-0', 'palette-name-0', ['#000000']);
|
||||
addPalette('palette-id-1', 'palette-name-1', ['#111111']);
|
||||
addPalette('palette-id-2', 'palette-name-2', ['#222222']);
|
||||
|
||||
// then
|
||||
paletteService.deletePaletteById('palette-id-1');
|
||||
|
||||
// verify
|
||||
var palettes = paletteService.getPalettes();
|
||||
expect(palettes.length).toBe(2);
|
||||
verifyPaletteIsStored('palette-id-0');
|
||||
verifyPaletteIsNotStored('palette-id-1');
|
||||
verifyPaletteIsStored('palette-id-2');
|
||||
});
|
||||
});
|
27
test/js/utils/UuidTest.js
Normal file
27
test/js/utils/UuidTest.js
Normal file
@ -0,0 +1,27 @@
|
||||
describe("UUID Generator", function() {
|
||||
|
||||
beforeEach(function() {});
|
||||
afterEach(function() {});
|
||||
|
||||
it("returns valid uuids", function() {
|
||||
// when
|
||||
|
||||
// then
|
||||
var uuid1 = pskl.utils.Uuid.generate();
|
||||
var uuid2 = pskl.utils.Uuid.generate();
|
||||
|
||||
// verify
|
||||
expect(typeof uuid1).toBe("string");
|
||||
expect(uuid1.length).toBe(36);
|
||||
var splits = uuid1.split('-');
|
||||
expect(splits.length).toBe(5);
|
||||
|
||||
expect(splits[0].length).toBe(8);
|
||||
expect(splits[1].length).toBe(4);
|
||||
expect(splits[2].length).toBe(4);
|
||||
expect(splits[3].length).toBe(4);
|
||||
expect(splits[4].length).toBe(12);
|
||||
|
||||
expect(uuid1).not.toBe(uuid2);
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue
Block a user