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 @@

Layers
  • {{layername}} + + α