mirror of
https://github.com/scratchfoundation/scratch-vm.git
synced 2024-12-23 14:32:59 -05:00
commit
e8ccc1a123
5 changed files with 55 additions and 10 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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();
|
||||||
|
|
Loading…
Reference in a new issue