def set_defaults(self): BaseMorph.set_defaults(self) self.scripts = ScriptCollection() self.media = [] self.costume = None # defaults to first Image in self.media on save self.variables = {} self.lists = {} self.isClone = False self.volume = 100 self.tempoBPM = 60
def built(self): UserObject.built(self) scripts = [Script.from_array(self, script) for script in self.scripts] self.scripts = ScriptCollection(scripts) comments = [] for script in self.scripts: if isinstance(script, Comment): comments.append(script) for comment in comments: self.scripts.remove(comment) blocks_by_id = list(self.blocks_by_id()) for comment in comments: comment.attach_scripts(blocks_by_id) self.build_media()
class ScriptableScratchMorph(BaseMorph): _fields = Morph._fields + ("name", "variables", "scripts", "isClone", "media", "costume") def __init__(self, *args, **kwargs): UserObject.__init__(self, *args, **kwargs) self.images = [] self.sounds = [] self.build_media() # returns silently if self.media is still a Ref def set_defaults(self): BaseMorph.set_defaults(self) self.scripts = ScriptCollection() self.media = [] self.costume = None # defaults to first Image in self.media on save self.variables = {} self.lists = {} self.isClone = False self.volume = 100 self.tempoBPM = 60 def built(self): UserObject.built(self) scripts = [Script.from_array(self, script) for script in self.scripts] self.scripts = ScriptCollection(scripts) comments = [] for script in self.scripts: if isinstance(script, Comment): comments.append(script) for comment in comments: self.scripts.remove(comment) blocks_by_id = list(self.blocks_by_id()) for comment in comments: comment.attach_scripts(blocks_by_id) self.build_media() def build_media(self): if isinstance(self.media, Ref): return # Don't run this yet! media = self.media self.media = [] for media in media: if isinstance(media, Sound): self.sounds.append(media) elif isinstance(media, Image): self.images.append(media) else: self.media.append(media) def blocks_by_id(self): """Return a list of all the blocks in script order but reverse script blocks order. Used to determine which block a Comment is anchored to. Note that Squeak arrays are 1-based, so index with: blocks_by_id[index - 1] """ for script in self.scripts: for block in reversed(list(script.to_block_list())): yield block def normalize(self): """Called before saving""" if not self.costume: for media in self.media + self.images: if isinstance(media, Image): self.costume = media break else: raise ValueError("%r does not have a costume" % self) self.lists = dict( (unicode(name), list) for (name, list) in self.lists.items() ) for list_name in self.lists: scratch_list = self.lists[list_name] if not isinstance(scratch_list, ScratchListMorph): scratch_list = ScratchListMorph(items=scratch_list) self.lists[list_name] = scratch_list scratch_list.name = list_name # This would show the list watcher on the stage: #scratch_list.target = self #if isinstance(self, Stage): # scratch_list.owner = self #else: # scratch_list.owner = self.owner scratch_list.normalize() def _encode_field(self, name, value): if name == 'scripts': scripts = [script.to_array() for script in value] blocks_by_id = list(self.blocks_by_id()) for block in blocks_by_id: if block.comment: scripts.append(block.comment.to_array(blocks_by_id)) return scripts elif name == 'media': return OrderedCollection(self.sounds + self.images + self.media) else: return value