diff --git a/Gruntfile.js b/Gruntfile.js
index 6872f830..ffa321b8 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -36,7 +36,7 @@ module.exports = function(grunt) {
},
'travis' : {
suite : './test/casperjs/TravisTestSuite.js',
- delay : 5000
+ delay : 10000
}
};
diff --git a/src/css/icons.css b/src/css/icons.css
index dc1ddc1e..809ce976 100644
--- a/src/css/icons.css
+++ b/src/css/icons.css
@@ -7,4 +7,8 @@
.action-icon.edit-icon {
background-image: url('../img/tools/pen.png');
+}
+
+.action-icon.merge-icon {
+ background-image: url('../img/merge-icon.png');
}
\ No newline at end of file
diff --git a/src/css/toolbox-layers-list.css b/src/css/toolbox-layers-list.css
index 052a5013..1b43b338 100644
--- a/src/css/toolbox-layers-list.css
+++ b/src/css/toolbox-layers-list.css
@@ -46,22 +46,34 @@
cursor : pointer;
}
-.layer-item .edit-icon {
+.layer-item .edit-icon, .layer-item .merge-icon {
float: right;
- width: 30px;
- background-size: 12px;
opacity: 0;
transition : opacity 0.2s;
}
-.layer-item:hover .edit-icon {
+.layer-item:hover .edit-icon, .layer-item:hover .merge-icon {
opacity : 0.6;
}
-.layer-item:hover .edit-icon:hover {
+.layer-item:hover .edit-icon:hover, .layer-item:hover .merge-icon:hover {
opacity : 1;
}
+.layer-item .edit-icon {
+ width: 25px;
+ background-size: 12px;
+}
+
+.layer-item .merge-icon {
+ width: 18px;
+ background-size: 16px;
+}
+
+.layer-item:last-child .merge-icon {
+ display : none;
+}
+
.layer-item:hover {
background : #222;
}
diff --git a/src/img/merge-icon.png b/src/img/merge-icon.png
new file mode 100644
index 00000000..3210c100
Binary files /dev/null and b/src/img/merge-icon.png differ
diff --git a/src/js/controller/LayersListController.js b/src/js/controller/LayersListController.js
index 48b6e3e7..b33c36a3 100644
--- a/src/js/controller/LayersListController.js
+++ b/src/js/controller/LayersListController.js
@@ -67,6 +67,9 @@
} else if (el.classList.contains('edit-icon')) {
index = el.parentNode.dataset.layerIndex;
this.renameLayerAt_(index);
+ } else if (el.classList.contains('merge-icon')) {
+ index = el.parentNode.dataset.layerIndex;
+ this.mergeDownLayerAt_(index);
}
};
@@ -79,6 +82,11 @@
}
};
+ ns.LayersListController.prototype.mergeDownLayerAt_ = function (index) {
+ this.piskelController.mergeDownLayerAt(index);
+ this.renderLayerList_();
+ };
+
ns.LayersListController.prototype.onButtonClick_ = function (button) {
var action = button.getAttribute('data-action');
if (action == 'up') {
diff --git a/src/js/controller/piskel/PiskelController.js b/src/js/controller/piskel/PiskelController.js
index ed03a303..4226807b 100644
--- a/src/js/controller/piskel/PiskelController.js
+++ b/src/js/controller/piskel/PiskelController.js
@@ -205,6 +205,18 @@
}
};
+ ns.PiskelController.prototype.mergeDownLayerAt = function (index) {
+ var layer = this.getLayerByIndex(index);
+ var downLayer = this.getLayerByIndex(index-1);
+ if (layer && downLayer) {
+ var mergedLayer = pskl.utils.LayerUtils.mergeLayers(layer, downLayer);
+ this.removeLayerAt(index);
+ this.piskel.addLayerAt(mergedLayer, index);
+ this.removeLayerAt(index-1);
+ this.selectLayer(mergedLayer);
+ }
+ };
+
ns.PiskelController.prototype.generateLayerName_ = function () {
var name = "Layer " + this.layerIdCounter;
while (this.hasLayerForName_(name)) {
diff --git a/src/js/controller/piskel/PublicPiskelController.js b/src/js/controller/piskel/PublicPiskelController.js
index 39264cef..e5da46bf 100644
--- a/src/js/controller/piskel/PublicPiskelController.js
+++ b/src/js/controller/piskel/PublicPiskelController.js
@@ -99,6 +99,12 @@
$.publish(Events.PISKEL_RESET);
};
+ ns.PublicPiskelController.prototype.mergeDownLayerAt = function (index) {
+ this.raiseSaveStateEvent_(this.piskelController.mergeDownLayerAt, [index]);
+ this.piskelController.mergeDownLayerAt(index);
+ $.publish(Events.PISKEL_RESET);
+ };
+
ns.PublicPiskelController.prototype.moveLayerUp = function () {
this.raiseSaveStateEvent_(this.piskelController.moveLayerUp, []);
this.piskelController.moveLayerUp();
diff --git a/src/js/devtools/DrawingTestPlayer.js b/src/js/devtools/DrawingTestPlayer.js
index 82dfbf3c..7f72ab80 100644
--- a/src/js/devtools/DrawingTestPlayer.js
+++ b/src/js/devtools/DrawingTestPlayer.js
@@ -101,6 +101,10 @@
var screenCoordinates = pskl.app.drawingController.getScreenCoordinates(recordEvent.coords.x, recordEvent.coords.y);
event.clientX = screenCoordinates.x;
event.clientY = screenCoordinates.y;
+ if (pskl.utils.UserAgent.isMac && event.ctrlKey) {
+ event.metaKey = true;
+ }
+
if (event.type == 'mousedown') {
pskl.app.drawingController.onMousedown_(event);
} else if (event.type == 'mouseup') {
diff --git a/src/js/model/Piskel.js b/src/js/model/Piskel.js
index ab28ec14..a59593a3 100644
--- a/src/js/model/Piskel.js
+++ b/src/js/model/Piskel.js
@@ -73,6 +73,10 @@
this.layers.push(layer);
};
+ ns.Piskel.prototype.addLayerAt = function (layer, index) {
+ this.layers.splice(index, 0, layer);
+ };
+
ns.Piskel.prototype.moveLayerUp = function (layer) {
var index = this.layers.indexOf(layer);
if (index > -1 && index < this.layers.length-1) {
diff --git a/src/js/utils/LayerUtils.js b/src/js/utils/LayerUtils.js
index 38a08e5a..d551e505 100644
--- a/src/js/utils/LayerUtils.js
+++ b/src/js/utils/LayerUtils.js
@@ -25,6 +25,18 @@
frames.push(frame);
}
return frames;
+ },
+
+ mergeLayers : function (layerA, layerB) {
+ var framesA = layerA.getFrames();
+ var framesB = layerB.getFrames();
+ var mergedFrames = [];
+ framesA.forEach(function (frame, index) {
+ var otherFrame = framesB[index];
+ mergedFrames.push(pskl.utils.FrameUtils.merge([otherFrame, frame]));
+ });
+ var mergedLayer = pskl.model.Layer.fromFrames(layerA.getName(), mergedFrames);
+ return mergedLayer;
}
};
diff --git a/src/templates/layers-list.html b/src/templates/layers-list.html
index 7208e10d..35f599f7 100644
--- a/src/templates/layers-list.html
+++ b/src/templates/layers-list.html
@@ -13,7 +13,8 @@
diff --git a/test/drawing/DrawingTests.browser.js b/test/drawing/DrawingTests.browser.js
index fa7a32d7..7db7ef2b 100644
--- a/test/drawing/DrawingTests.browser.js
+++ b/test/drawing/DrawingTests.browser.js
@@ -4,6 +4,7 @@
"color.picker.json",
"frames.fun.json",
"layers.fun.json",
+ "layers.merge.json",
"lighten.darken.json",
"move.json",
"pen.secondary.color.json",
diff --git a/test/drawing/DrawingTests.casper.js b/test/drawing/DrawingTests.casper.js
index 68e8b83f..6dd57335 100644
--- a/test/drawing/DrawingTests.casper.js
+++ b/test/drawing/DrawingTests.casper.js
@@ -3,6 +3,7 @@
"color.picker.json",
"frames.fun.json",
"layers.fun.json",
+ "layers.merge.json",
"move.json",
"pen.secondary.color.json",
"squares.circles.json",
diff --git a/test/drawing/tests/layers.merge.json b/test/drawing/tests/layers.merge.json
new file mode 100644
index 00000000..5262e828
--- /dev/null
+++ b/test/drawing/tests/layers.merge.json
@@ -0,0 +1 @@
+{"events":[{"event":{"type":"mousedown","button":0,"shiftKey":false,"altKey":false,"ctrlKey":false},"coords":{"x":0,"y":0},"type":"mouse-event"},{"event":{"type":"mousemove","button":0,"shiftKey":false,"altKey":false,"ctrlKey":false},"coords":{"x":0,"y":0},"type":"mouse-event"},{"event":{"type":"mousemove","button":0,"shiftKey":false,"altKey":false,"ctrlKey":false},"coords":{"x":0,"y":1},"type":"mouse-event"},{"event":{"type":"mousemove","button":0,"shiftKey":false,"altKey":false,"ctrlKey":false},"coords":{"x":1,"y":1},"type":"mouse-event"},{"event":{"type":"mousemove","button":0,"shiftKey":false,"altKey":false,"ctrlKey":false},"coords":{"x":1,"y":2},"type":"mouse-event"},{"event":{"type":"mousemove","button":0,"shiftKey":false,"altKey":false,"ctrlKey":false},"coords":{"x":1,"y":1},"type":"mouse-event"},{"event":{"type":"mousemove","button":0,"shiftKey":false,"altKey":false,"ctrlKey":false},"coords":{"x":1,"y":0},"type":"mouse-event"},{"event":{"type":"mousemove","button":0,"shiftKey":false,"altKey":false,"ctrlKey":false},"coords":{"x":1,"y":1},"type":"mouse-event"},{"event":{"type":"mousemove","button":0,"shiftKey":false,"altKey":false,"ctrlKey":false},"coords":{"x":0,"y":1},"type":"mouse-event"},{"event":{"type":"mousemove","button":0,"shiftKey":false,"altKey":false,"ctrlKey":false},"coords":{"x":0,"y":2},"type":"mouse-event"},{"event":{"type":"mousemove","button":0,"shiftKey":false,"altKey":false,"ctrlKey":false},"coords":{"x":1,"y":2},"type":"mouse-event"},{"event":{"type":"mousemove","button":0,"shiftKey":false,"altKey":false,"ctrlKey":false},"coords":{"x":2,"y":2},"type":"mouse-event"},{"event":{"type":"mousemove","button":0,"shiftKey":false,"altKey":false,"ctrlKey":false},"coords":{"x":2,"y":1},"type":"mouse-event"},{"event":{"type":"mousemove","button":0,"shiftKey":false,"altKey":false,"ctrlKey":false},"coords":{"x":2,"y":0},"type":"mouse-event"},{"event":{"type":"mouseup","button":0,"shiftKey":false,"altKey":false,"ctrlKey":false},"coords":{"x":2,"y":0},"type":"mouse-event"},{"type":"instrumented-event","methodName":"createLayer","args":[]},{"type":"color-event","color":"#942d2d","isPrimary":true},{"event":{"type":"mousedown","button":0,"shiftKey":false,"altKey":false,"ctrlKey":false},"coords":{"x":1,"y":1},"type":"mouse-event"},{"event":{"type":"mousemove","button":0,"shiftKey":false,"altKey":false,"ctrlKey":false},"coords":{"x":1,"y":1},"type":"mouse-event"},{"event":{"type":"mousemove","button":0,"shiftKey":false,"altKey":false,"ctrlKey":false},"coords":{"x":1,"y":2},"type":"mouse-event"},{"event":{"type":"mousemove","button":0,"shiftKey":false,"altKey":false,"ctrlKey":false},"coords":{"x":1,"y":3},"type":"mouse-event"},{"event":{"type":"mousemove","button":0,"shiftKey":false,"altKey":false,"ctrlKey":false},"coords":{"x":2,"y":3},"type":"mouse-event"},{"event":{"type":"mousemove","button":0,"shiftKey":false,"altKey":false,"ctrlKey":false},"coords":{"x":3,"y":3},"type":"mouse-event"},{"event":{"type":"mousemove","button":0,"shiftKey":false,"altKey":false,"ctrlKey":false},"coords":{"x":3,"y":2},"type":"mouse-event"},{"event":{"type":"mousemove","button":0,"shiftKey":false,"altKey":false,"ctrlKey":false},"coords":{"x":3,"y":1},"type":"mouse-event"},{"event":{"type":"mousemove","button":0,"shiftKey":false,"altKey":false,"ctrlKey":false},"coords":{"x":2,"y":1},"type":"mouse-event"},{"event":{"type":"mousemove","button":0,"shiftKey":false,"altKey":false,"ctrlKey":false},"coords":{"x":2,"y":2},"type":"mouse-event"},{"event":{"type":"mouseup","button":0,"shiftKey":false,"altKey":false,"ctrlKey":false},"coords":{"x":2,"y":2},"type":"mouse-event"},{"type":"instrumented-event","methodName":"createLayer","args":[]},{"type":"color-event","color":"#2d9430","isPrimary":true},{"event":{"type":"mousedown","button":0,"shiftKey":false,"altKey":false,"ctrlKey":false},"coords":{"x":2,"y":2},"type":"mouse-event"},{"event":{"type":"mousemove","button":0,"shiftKey":false,"altKey":false,"ctrlKey":false},"coords":{"x":2,"y":2},"type":"mouse-event"},{"event":{"type":"mousemove","button":0,"shiftKey":false,"altKey":false,"ctrlKey":false},"coords":{"x":2,"y":3},"type":"mouse-event"},{"event":{"type":"mousemove","button":0,"shiftKey":false,"altKey":false,"ctrlKey":false},"coords":{"x":2,"y":4},"type":"mouse-event"},{"event":{"type":"mousemove","button":0,"shiftKey":false,"altKey":false,"ctrlKey":false},"coords":{"x":3,"y":4},"type":"mouse-event"},{"event":{"type":"mousemove","button":0,"shiftKey":false,"altKey":false,"ctrlKey":false},"coords":{"x":4,"y":4},"type":"mouse-event"},{"event":{"type":"mousemove","button":0,"shiftKey":false,"altKey":false,"ctrlKey":false},"coords":{"x":4,"y":3},"type":"mouse-event"},{"event":{"type":"mousemove","button":0,"shiftKey":false,"altKey":false,"ctrlKey":false},"coords":{"x":4,"y":2},"type":"mouse-event"},{"event":{"type":"mousemove","button":0,"shiftKey":false,"altKey":false,"ctrlKey":false},"coords":{"x":3,"y":2},"type":"mouse-event"},{"event":{"type":"mousemove","button":0,"shiftKey":false,"altKey":false,"ctrlKey":false},"coords":{"x":3,"y":3},"type":"mouse-event"},{"event":{"type":"mouseup","button":0,"shiftKey":false,"altKey":false,"ctrlKey":false},"coords":{"x":3,"y":3},"type":"mouse-event"},{"type":"instrumented-event","methodName":"moveLayerDown","args":[]},{"type":"instrumented-event","methodName":"mergeDownLayerAt","args":["2"]},{"type":"instrumented-event","methodName":"mergeDownLayerAt","args":["1"]},{"type":"tool-event","toolId":"tool-paint-bucket"},{"type":"color-event","color":"#2d5994","isPrimary":true},{"event":{"type":"mousedown","button":0,"shiftKey":false,"altKey":false,"ctrlKey":false},"coords":{"x":0,"y":4},"type":"mouse-event"},{"event":{"type":"mouseup","button":0,"shiftKey":false,"altKey":false,"ctrlKey":false},"coords":{"x":0,"y":4},"type":"mouse-event"},{"event":{"type":"mousedown","button":0,"shiftKey":false,"altKey":false,"ctrlKey":false},"coords":{"x":4,"y":0},"type":"mouse-event"},{"event":{"type":"mouseup","button":0,"shiftKey":false,"altKey":false,"ctrlKey":false},"coords":{"x":4,"y":0},"type":"mouse-event"}],"initialState":{"size":{"width":5,"height":5},"primaryColor":"#000000","secondaryColor":"rgba(0, 0, 0, 0)","selectedTool":"tool-pen"},"png":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAN0lEQVQIW2NkYGD4D8RgoBs5BUwzggSn6OrCxBlm6qRjEUxnZmAEavmffmUmQiVMECxiPQcuAQAoxRAISNM8EgAAAABJRU5ErkJggg=="}
\ No newline at end of file