diff --git a/blocks.js b/blocks.js index 90df75d8..6d5715e3 100644 --- a/blocks.js +++ b/blocks.js @@ -730,10 +730,11 @@ SyntaxElementMorph.prototype.definesScriptVariable = function (name) { // SyntaxElementMorph copy-on-write support: SyntaxElementMorph.prototype.selectForEdit = function () { - var ide = this.parentThatIsA(IDE_Morph), + var scripts = this.parentThatIsA(ScriptsMorph), + ide = this.parentThatIsA(IDE_Morph), rcvr = ide ? ide.currentSprite : null, selected; - if (rcvr && rcvr.inheritsAttribute('scripts')) { + if (scripts && rcvr && rcvr.inheritsAttribute('scripts')) { // copy on write: this.selectionID = true; rcvr.shadowAttribute('scripts'); diff --git a/gui.js b/gui.js index d28ed780..0bc5c830 100644 --- a/gui.js +++ b/gui.js @@ -7761,6 +7761,7 @@ SoundIconMorph.prototype.renameSound = function () { var sound = this.object, ide = this.parentThatIsA(IDE_Morph), myself = this; + this.disinherit(); (new DialogBoxMorph( null, function (answer) { @@ -7791,9 +7792,21 @@ SoundIconMorph.prototype.createBackgrounds SoundIconMorph.prototype.createLabel = SpriteIconMorph.prototype.createLabel; +// SoundIconMorph inheritance + +SoundIconMorph.prototype.disinherit = function () { + var jukebox = this.parentThatIsA(JukeboxMorph), + idx = this.parent.children.indexOf(this); + if (jukebox.sprite.inheritsAttribute('sounds')) { + jukebox.sprite.shadowAttribute('sounds'); + this.object = jukebox.sprite.sounds.at(idx); + } +}; + // SoundIconMorph drag & drop SoundIconMorph.prototype.prepareToBeGrabbed = function () { + this.disinherit(); this.removeSound(); }; @@ -7816,7 +7829,7 @@ function JukeboxMorph(aSprite, sliderColor) { JukeboxMorph.prototype.init = function (aSprite, sliderColor) { // additional properties this.sprite = aSprite || new SpriteMorph(); - this.costumesVersion = null; + this.soundsVersion = null; this.spriteVersion = null; // initialize inherited properties @@ -7867,6 +7880,7 @@ JukeboxMorph.prototype.updateList = function () { myself.addContents(icon); y = icon.bottom() + padding; }); + this.soundsVersion = this.sprite.costumes.lastChanged; Morph.prototype.trackChanges = oldFlag; this.changed(); @@ -7883,13 +7897,14 @@ JukeboxMorph.prototype.updateSelection = function () { // Jukebox stepping -/* JukeboxMorph.prototype.step = function () { + if (this.soundsVersion !== this.sprite.sounds.lastChanged) { + this.updateList(); + } if (this.spriteVersion !== this.sprite.version) { this.updateSelection(); } }; -*/ // Jukebox ops @@ -7915,6 +7930,8 @@ JukeboxMorph.prototype.reactToDropOf = function (icon) { idx += 1; } }); + + this.sprite.shadowAttribute('sounds'); this.sprite.sounds.add(costume, idx); this.updateList(); }; diff --git a/history.txt b/history.txt index ed31c809..625c1568 100755 --- a/history.txt +++ b/history.txt @@ -3476,12 +3476,13 @@ Fixes: ------ * Objects, Blocks, Threads, Tables, Store: First-Class Sounds * Block: new musical “notes” symbol +* Objects, Blocks, Threads, GUI: inheritance support for sounds Features: * polymorphic sprite-local custom blocks * inheritance of sprite-local custom blocks -* inheritance of sprite attributes (x, y, direction, size, costumes, costume #, scripts) +* inheritance of sprite attributes (x, y, direction, size, costumes, costume #, sounds, scripts) * first-class costumes and sounds * localization support when typing expressions * support for user-forced line-breaks in custom block labels diff --git a/objects.js b/objects.js index c63d4874..9c4821e0 100644 --- a/objects.js +++ b/objects.js @@ -122,6 +122,7 @@ SpriteMorph.prototype.attributes = 'size', 'costumes', 'costume #', + 'sounds', 'scripts' ]; @@ -3030,6 +3031,7 @@ SpriteMorph.prototype.reportCostumes = function () { // SpriteMorph sound management SpriteMorph.prototype.addSound = function (audio, name) { + this.shadowAttribute('sounds'); this.sounds.add(new Sound(audio, name)); }; @@ -5185,7 +5187,7 @@ SpriteMorph.prototype.shadowedAttributes = function () { }; SpriteMorph.prototype.shadowAttribute = function (aName) { - var ide, wardrobe, + var ide, wardrobe, jukebox, myself = this, pos; if (!this.inheritsAttribute(aName)) { @@ -5205,6 +5207,12 @@ SpriteMorph.prototype.shadowAttribute = function (aName) { } }); this.costumes = wardrobe; + } else if (aName === 'sounds') { + jukebox = new List(); + this.sounds.asArray().forEach(function (sound) { + jukebox.add(sound.copy()); + }); + this.sounds = jukebox; } else if (aName === 'scripts') { ide.stage.threads.stopAllForReceiver(this); pos = this.scripts.position(); @@ -5236,6 +5244,8 @@ SpriteMorph.prototype.inheritAttribute = function (aName) { this.inheritedAttributes.push(aName); if (aName === 'costumes') { this.costumes = this.exemplar.costumes; + } else if (aName === 'sounds') { + this.sounds = this.exemplar.sounds; } else { this.refreshInheritedAttribute(aName); if (ide) {