diff --git a/src/css/font-icon.css b/src/css/font-icon.css
index f771603a2..61a3e0969 100644
--- a/src/css/font-icon.css
+++ b/src/css/font-icon.css
@@ -94,3 +94,11 @@
.piskel-icon-arrow-down-thin:before {
content: "\e60f";
}
+
+.piskel-icon-lock-locked:before {
+ content: "\e98f";
+}
+
+.piskel-icon-lock-unlocked:before {
+ content: "\e990";
+}
diff --git a/src/css/fonts/icomoon.eot b/src/css/fonts/icomoon.eot
index f5314adf7..a700c4ddb 100644
Binary files a/src/css/fonts/icomoon.eot and b/src/css/fonts/icomoon.eot differ
diff --git a/src/css/fonts/icomoon.svg b/src/css/fonts/icomoon.svg
index bafc0feee..0a487cd22 100644
--- a/src/css/fonts/icomoon.svg
+++ b/src/css/fonts/icomoon.svg
@@ -6,23 +6,25 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/css/fonts/icomoon.ttf b/src/css/fonts/icomoon.ttf
index 5ae72b63d..03c369e3d 100644
Binary files a/src/css/fonts/icomoon.ttf and b/src/css/fonts/icomoon.ttf differ
diff --git a/src/css/fonts/icomoon.woff b/src/css/fonts/icomoon.woff
index a9d1e6c25..a0b6f0134 100644
Binary files a/src/css/fonts/icomoon.woff and b/src/css/fonts/icomoon.woff differ
diff --git a/src/css/toolbox-layers-list.css b/src/css/toolbox-layers-list.css
index bcd06b8fe..3f7be438e 100644
--- a/src/css/toolbox-layers-list.css
+++ b/src/css/toolbox-layers-list.css
@@ -86,6 +86,10 @@
background : #222;
}
+.layer-lock {
+ padding: 6px 0;
+}
+
.layer-item-opacity {
padding: 0 8px 0 8px;
flex: 0 auto;
diff --git a/src/js/controller/DrawingController.js b/src/js/controller/DrawingController.js
index 0ed1f055c..e18aa244a 100644
--- a/src/js/controller/DrawingController.js
+++ b/src/js/controller/DrawingController.js
@@ -137,6 +137,11 @@
};
ns.DrawingController.prototype.onTouchstart_ = function (event) {
+ var index = this.piskelController.getCurrentLayerIndex();
+ var layer = this.piskelController.getLayerByIndex(index);
+ if (layer.locked) {
+ return;
+ }
this.onMousedown_(event);
};
@@ -153,6 +158,11 @@
* @private
*/
ns.DrawingController.prototype.onMousedown_ = function (event) {
+ var index = this.piskelController.getCurrentLayerIndex();
+ var layer = this.piskelController.getLayerByIndex(index);
+ if (layer.locked) {
+ return;
+ }
$.publish(Events.MOUSE_EVENT, [event, this]);
var frame = this.piskelController.getCurrentFrame();
var coords = this.getSpriteCoordinates(event.clientX, event.clientY);
diff --git a/src/js/controller/LayersListController.js b/src/js/controller/LayersListController.js
index 96e32be4e..bcdebce14 100644
--- a/src/js/controller/LayersListController.js
+++ b/src/js/controller/LayersListController.js
@@ -125,7 +125,8 @@
'layername' : layer.getName(),
'layerindex' : index,
'isselected:current-layer-item' : isSelected,
- 'opacity' : layer.getOpacity()
+ 'opacity' : layer.getOpacity(),
+ 'locked' : layer.locked ? 'locked' : 'unlocked'
});
var layerItem = pskl.utils.Template.createFromHTML(layerItemHtml);
this.layersListEl.insertBefore(layerItem, this.layersListEl.firstChild);
@@ -181,6 +182,10 @@
var layer = this.piskelController.getLayerAt(parseInt(index, 10));
var opacity = window.prompt('Set layer opacity (value between 0 and 1)', layer.getOpacity());
this.piskelController.setLayerOpacityAt(index, opacity);
+ } else if (el.classList.contains('layer-lock')) {
+ index = pskl.utils.Dom.getData(el, 'layerIndex');
+ var layer = this.piskelController.getLayerAt(parseInt(index, 10));
+ this.piskelController.setLayerLockedAt(index, layer.getLocked());
}
};
diff --git a/src/js/controller/drawing/DragHandler.js b/src/js/controller/drawing/DragHandler.js
index f3b134d7b..7f9a90ec3 100644
--- a/src/js/controller/drawing/DragHandler.js
+++ b/src/js/controller/drawing/DragHandler.js
@@ -25,6 +25,11 @@
* @param {Number} y : y coordinate of the mouse event that initiated the drag
*/
ns.DragHandler.prototype.startDrag = function (x, y) {
+ var index = this.piskelController.getCurrentLayerIndex();
+ var layer = this.piskelController.getLayerByIndex(index);
+ if (layer.locked) {
+ return;
+ }
var coords = this.drawingController.getSpriteCoordinates(x, y);
this.updateOrigin_(coords.x, coords.y);
};
diff --git a/src/js/controller/piskel/PiskelController.js b/src/js/controller/piskel/PiskelController.js
index 3e2fe4198..fd8ab3d56 100644
--- a/src/js/controller/piskel/PiskelController.js
+++ b/src/js/controller/piskel/PiskelController.js
@@ -284,9 +284,20 @@
}
};
+ ns.PiskelController.prototype.setLayerLockedAt = function (index, locked) {
+ var layer = this.getLayerByIndex(index);
+ if (layer) {
+ layer.setLocked(!locked);
+ }
+ };
+
ns.PiskelController.prototype.mergeDownLayerAt = function (index) {
var layer = this.getLayerByIndex(index);
var downLayer = this.getLayerByIndex(index - 1);
+ if (layer.locked || downLayer.locked) {
+ window.console.error('Could not merge with later below. One of the layers is locked.');
+ return;
+ }
if (layer && downLayer) {
var mergedLayer = pskl.utils.LayerUtils.mergeLayers(layer, downLayer);
this.removeLayerAt(index);
diff --git a/src/js/controller/piskel/PublicPiskelController.js b/src/js/controller/piskel/PublicPiskelController.js
index a3a86cfee..4187d5070 100644
--- a/src/js/controller/piskel/PublicPiskelController.js
+++ b/src/js/controller/piskel/PublicPiskelController.js
@@ -37,6 +37,7 @@
this.saveWrap_('moveLayerDown', true);
this.saveWrap_('removeCurrentLayer', true);
this.saveWrap_('setLayerOpacityAt', true);
+ this.saveWrap_('setLayerLockedAt', true);
this.saveWrap_('toggleFrameVisibilityAt', true);
var shortcuts = pskl.service.keyboard.Shortcuts;
diff --git a/src/js/model/Layer.js b/src/js/model/Layer.js
index 0dba53407..90f38a8b7 100644
--- a/src/js/model/Layer.js
+++ b/src/js/model/Layer.js
@@ -8,6 +8,7 @@
this.name = name;
this.frames = [];
this.opacity = 1;
+ this.locked = false;
}
};
@@ -46,6 +47,17 @@
this.opacity = +opacity.toFixed(3);
};
+ ns.Layer.prototype.getLocked = function () {
+ return this.locked;
+ };
+
+ ns.Layer.prototype.setLocked = function (locked) {
+ if (typeof locked !== 'boolean') {
+ locked = false;
+ }
+ this.locked = locked;
+ };
+
ns.Layer.prototype.isTransparent = function () {
return this.opacity < 1;
};
diff --git a/src/js/tools/ToolsHelper.js b/src/js/tools/ToolsHelper.js
index 8f9766a60..ac4f66a46 100644
--- a/src/js/tools/ToolsHelper.js
+++ b/src/js/tools/ToolsHelper.js
@@ -16,6 +16,9 @@ ns.ToolsHelper = {
var currentFrameIndex = pskl.app.piskelController.getCurrentFrameIndex();
var layers = useAllLayers ? pskl.app.piskelController.getLayers() : [pskl.app.piskelController.getCurrentLayer()];
return layers.reduce(function (previous, layer) {
+ if (layer.locked) {
+ return previous;
+ }
var frames = useAllFrames ? layer.getFrames() : [layer.getFrameAt(currentFrameIndex)];
return previous.concat(frames);
}, []);
diff --git a/src/js/utils/serialization/arraybuffer/ArrayBufferDeserializer.js b/src/js/utils/serialization/arraybuffer/ArrayBufferDeserializer.js
index 2ba9bd8b8..41745aca0 100644
--- a/src/js/utils/serialization/arraybuffer/ArrayBufferDeserializer.js
+++ b/src/js/utils/serialization/arraybuffer/ArrayBufferDeserializer.js
@@ -79,6 +79,7 @@
var dataUriLengthFirstHalf = arr16[currentIndex + 3];
var dataUriLengthSecondHalf = arr16[currentIndex + 4];
var dataUriLength = (dataUriLengthSecondHalf >>> 0) | (dataUriLengthFirstHalf << 16 >>> 0);
+ var locked = false;
// Name
var layerName = '';
@@ -97,6 +98,7 @@
layer.name = layerName;
layer.opacity = opacity;
+ layer.locked = locked;
layer.frameCount = frameCount;
layer.dataUri = dataUri;
layers.push(layer);
@@ -128,6 +130,7 @@
var nlayer = new pskl.model.Layer(layer.name);
layer.model = nlayer;
nlayer.setOpacity(layer.opacity);
+ nlayer.setLocked(layer.locked);
piskel.addLayer(nlayer);
loadLayerImage.bind(this, layer, callback)();
diff --git a/src/templates/layers-list.html b/src/templates/layers-list.html
index e66280769..11e6c8b85 100644
--- a/src/templates/layers-list.html
+++ b/src/templates/layers-list.html
@@ -37,6 +37,9 @@
{{layername}}
+
+
α