예제 #1
0
    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
예제 #2
0
    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()
예제 #3
0
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