Merge pull request #1511 from kchadha/restore-costume

Restore costume
This commit is contained in:
Karishma Chadha 2018-08-21 19:53:22 -04:00 committed by GitHub
commit e8ccc1a123
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 55 additions and 10 deletions

View file

@ -534,12 +534,19 @@ class RenderedTarget extends Target {
/** /**
* Delete a costume by index. * Delete a costume by index.
* @param {number} index Costume index to be deleted * @param {number} index Costume index to be deleted
* @return {?object} The costume that was deleted or null
* if the index was out of bounds of the costumes list or
* this target only has one costume.
*/ */
deleteCostume (index) { deleteCostume (index) {
const originalCostumeCount = this.sprite.costumes.length; const originalCostumeCount = this.sprite.costumes.length;
if (originalCostumeCount === 1) return; if (originalCostumeCount === 1) return null;
this.sprite.deleteCostumeAt(index); if (index < 0 || index >= originalCostumeCount) {
return null;
}
const deletedCostume = this.sprite.deleteCostumeAt(index);
if (index === this.currentCostume && index === originalCostumeCount - 1) { if (index === this.currentCostume && index === originalCostumeCount - 1) {
this.setCostume(index - 1); this.setCostume(index - 1);
@ -550,6 +557,7 @@ class RenderedTarget extends Target {
} }
this.runtime.requestTargetsUpdate(this); this.runtime.requestTargetsUpdate(this);
return deletedCostume;
} }
/** /**

View file

@ -93,11 +93,10 @@ class Sprite {
/** /**
* Delete a costume by index. * Delete a costume by index.
* @param {number} index Costume index to be deleted * @param {number} index Costume index to be deleted
* @return {?object} The deleted costume
*/ */
deleteCostumeAt (index) { deleteCostumeAt (index) {
this.costumes_ = this.costumes_ return this.costumes.splice(index, 1)[0];
.slice(0, index)
.concat(this.costumes_.slice(index + 1));
} }
/** /**

View file

@ -589,9 +589,19 @@ class VirtualMachine extends EventEmitter {
/** /**
* Delete a costume from the current editing target. * Delete a costume from the current editing target.
* @param {int} costumeIndex - the index of the costume to be removed. * @param {int} costumeIndex - the index of the costume to be removed.
* @return {?function} A function to restore the deleted costume, or null,
* if no costume was deleted.
*/ */
deleteCostume (costumeIndex) { deleteCostume (costumeIndex) {
this.editingTarget.deleteCostume(costumeIndex); const deletedCostume = this.editingTarget.deleteCostume(costumeIndex);
if (deletedCostume) {
const target = this.editingTarget;
return () => {
target.addCostume(deletedCostume);
this.emitTargetsUpdate();
};
}
return null;
} }
/** /**

View file

@ -116,41 +116,45 @@ test('deleteCostume', t => {
// Costume 2 => Costume 3 // Costume 2 => Costume 3
// Costume 3 // Costume 3
a.setCostume(0); a.setCostume(0);
a.deleteCostume(0); const deletedCostume = a.deleteCostume(0);
t.equals(a.sprite.costumes.length, 2); t.equals(a.sprite.costumes.length, 2);
t.equals(a.sprite.costumes[0].id, 2); t.equals(a.sprite.costumes[0].id, 2);
t.equals(a.sprite.costumes[1].id, 3); t.equals(a.sprite.costumes[1].id, 3);
t.equals(a.currentCostume, 0); t.equals(a.currentCostume, 0);
t.deepEqual(deletedCostume, o1);
// Costume 1 Costume 1 // Costume 1 Costume 1
// x* Costume 2 => * Costume 3 // x* Costume 2 => * Costume 3
// Costume 3 // Costume 3
a.sprite.costumes = [o1, o2, o3]; a.sprite.costumes = [o1, o2, o3];
a.setCostume(1); a.setCostume(1);
a.deleteCostume(1); const deletedCostume2 = a.deleteCostume(1);
t.equals(a.sprite.costumes.length, 2); t.equals(a.sprite.costumes.length, 2);
t.equals(a.sprite.costumes[0].id, 1); t.equals(a.sprite.costumes[0].id, 1);
t.equals(a.sprite.costumes[1].id, 3); t.equals(a.sprite.costumes[1].id, 3);
t.equals(a.currentCostume, 1); t.equals(a.currentCostume, 1);
t.deepEqual(deletedCostume2, o2);
// Costume 1 Costume 1 // Costume 1 Costume 1
// Costume 2 => * Costume 2 // Costume 2 => * Costume 2
// x* Costume 3 // x* Costume 3
a.sprite.costumes = [o1, o2, o3]; a.sprite.costumes = [o1, o2, o3];
a.setCostume(2); a.setCostume(2);
a.deleteCostume(2); const deletedCostume3 = a.deleteCostume(2);
t.equals(a.sprite.costumes.length, 2); t.equals(a.sprite.costumes.length, 2);
t.equals(a.sprite.costumes[0].id, 1); t.equals(a.sprite.costumes[0].id, 1);
t.equals(a.sprite.costumes[1].id, 2); t.equals(a.sprite.costumes[1].id, 2);
t.equals(a.currentCostume, 1); t.equals(a.currentCostume, 1);
t.deepEqual(deletedCostume3, o3);
// Refuses to delete only costume // Refuses to delete only costume
a.sprite.costumes = [o1]; a.sprite.costumes = [o1];
a.setCostume(0); a.setCostume(0);
a.deleteCostume(0); const noDeletedCostume = a.deleteCostume(0);
t.equals(a.sprite.costumes.length, 1); t.equals(a.sprite.costumes.length, 1);
t.equals(a.sprite.costumes[0].id, 1); t.equals(a.sprite.costumes[0].id, 1);
t.equals(a.currentCostume, 0); t.equals(a.currentCostume, 0);
t.equal(noDeletedCostume, null);
// Costume 1 Costume 1 // Costume 1 Costume 1
// x Costume 2 Costume 3 // x Costume 2 Costume 3

View file

@ -30,6 +30,30 @@ test('deleteSound returns function after deleting or null if nothing was deleted
t.end(); t.end();
}); });
test('deleteCostume returns function after deleting or null if nothing was deleted', t => {
const vm = new VirtualMachine();
const sprite = new Sprite();
sprite.costumes = [{id: 1}, {id: 2}, {id: 3}];
sprite.currentCostume = 0;
const rt = new Runtime();
const target = new RenderedTarget(sprite, rt);
vm.editingTarget = target;
const addFun = vm.deleteCostume(1);
t.equal(sprite.costumes.length, 2);
t.equal(sprite.costumes[0].id, 1);
t.equal(sprite.costumes[1].id, 3);
t.type(addFun, 'function');
const noAddFun = vm.deleteCostume(2);
t.equal(sprite.costumes.length, 2);
t.equal(sprite.costumes[0].id, 1);
t.equal(sprite.costumes[1].id, 3);
t.equal(noAddFun, null);
t.end();
});
test('addSprite throws on invalid string', t => { test('addSprite throws on invalid string', t => {
const vm = new VirtualMachine(); const vm = new VirtualMachine();