Esempio n. 1
0
    def start(self, file_path=None):
        self._want_document = False
        self.playpath = os.path.dirname(file_path)
        if not file_path:
            return False
        self.playlist.append('file://' + os.path.abspath(file_path))
        if not self.player:
            # Lazy init the player so that videowidget is realized
            # and has a valid widget allocation.
            self.player = GstPlayer(self.videowidget, self.running_sugar)
            self.player.connect('eos', self._player_eos_cb)
            self.player.connect('error', self._player_error_cb)
            self.player.connect('stream-info', self._player_stream_info_cb)

        try:
            if not self.currentplaying:
                debug_output('Playing: %s' % (self.playlist[0]),
                             self.running_sugar)
                self.player.set_uri(self.playlist[0])
                self.currentplaying = 0
                self.play_toggled()
        except Exception as e:
            error_output('Error playing %s: %s' % (self.playlist[0], e),
                         self.running_sugar)
        return False
Esempio n. 2
0
    def setxy(self, x, y, share=True, pendown=True):
        ''' Move turtle to position x,y '''
        oldx, oldy = self.xcor, self.ycor
        x *= self.tw.coord_scale
        y *= self.tw.coord_scale
        try:
            self.xcor, self.ycor = x, y
        except (TypeError, ValueError):
            debug_output('bad value sent to %s' % (__name__),
                         self.tw.running_sugar)
            return

        if self.pendown and pendown:
            self.canvas.set_source_rgb(self.fgrgb[0] / 255.,
                                       self.fgrgb[1] / 255.,
                                       self.fgrgb[2] / 255.)
            if self.cr_svg is not None:
                self.cr_svg.set_source_rgb(self.fgrgb[0] / 255.,
                                           self.fgrgb[1] / 255.,
                                           self.fgrgb[2] / 255.)
            self.draw_line(oldx, oldy, self.xcor, self.ycor)
            self.inval()
        self.move_turtle()

        if self.tw.sharing() and share:
            event = 'x|%s' % (data_to_string([self._get_my_nick(),
                                              [round_int(x), round_int(y)]]))
            self.tw.send_event(event)
Esempio n. 3
0
    def __call__(self, *runtime_args, **runtime_kwargs):
        """ Execute the function, passing it the arguments received at
        runtime. Also call the function in self.call_afterwards and pass it
        all runtime_args and runtime_kwargs.
        If the very first argument is a LogoCode instance, it is removed.
        The active turtle, the Turtles object, the canvas, the LogoCode
        object, or the TurtleArtWindow object will be prepended to the
        arguments (depending on what this Primitive wants). """

        # remove the first argument if it is a LogoCode instance
        if runtime_args and isinstance(runtime_args[0], LogoCode):
            runtime_args = runtime_args[1:]

        if Primitive._DEBUG:
            debug_output(repr(self))
            debug_output("  runtime_args: " + repr(runtime_args))
        # fill the ArgSlots with the runtime arguments
        new_prim = self.fill_slots(runtime_args, runtime_kwargs,
                                   convert_to_ast=False)
        if not new_prim.are_slots_filled():
            raise logoerror("#syntaxerror")
        if Primitive._DEBUG:
            debug_output("  new_prim.arg_descs: " + repr(new_prim.arg_descs))

        # extract the actual values from the (now constant) arguments
        (new_args, new_kwargs) = new_prim.get_values_of_filled_slots()
        if Primitive._DEBUG:
            debug_output("  new_args: " + repr(new_args))
            debug_output("end " + repr(self))

        # what does this primitive want as its first argument?
        first_arg = None
        if not is_bound_method(new_prim.func):
            if new_prim.wants_turtle():
                first_arg = global_objects["turtles"].get_active_turtle()
            elif new_prim.wants_turtles():
                first_arg = global_objects["turtles"]
            elif new_prim.wants_canvas():
                first_arg = global_objects["canvas"]
            elif new_prim.wants_logocode():
                first_arg = global_objects["logo"]
            elif new_prim.wants_heap():
                first_arg = global_objects["logo"].heap
            elif new_prim.wants_tawindow():
                first_arg = global_objects["window"]
            else:
                result, plugin = new_prim.wants_plugin()
                if result:
                    first_arg = plugin

        # execute the actual function
        if first_arg is None:
            return_value = new_prim.func(*new_args, **new_kwargs)
        else:
            return_value = new_prim.func(first_arg, *new_args, **new_kwargs)

        if new_prim.call_afterwards is not None:
            new_prim.call_afterwards(*new_args, **new_kwargs)

        return return_value
Esempio n. 4
0
 def doevalstep(self):
     """ evaluate one step """
     starttime = _millisecond()
     try:
         while (_millisecond() - starttime) < 120:
             try:
                 if self.step is not None:
                     try:
                         self.step.next()
                     except ValueError:
                         debug_output('generator already executing',
                                      self.tw.running_sugar)
                         self.tw.running_blocks = False
                         return False
                 else:
                     return False
             except StopIteration:
                 # self.tw.turtles.show_all()
                 if self.hidden_turtle is not None:
                     self.hidden_turtle.show()
                     self.hidden_turtle = None
                 else:
                     self.tw.turtles.get_active_turtle().show()
                 self.tw.running_blocks = False
                 return False
     except logoerror, e:
         self.tw.showblocks()
         self.tw.display_coordinates()
         self.tw.showlabel('syntaxerror', str(e))
         self.tw.turtles.show_all()
         self.tw.running_blocks = False
         return False
    def __call__(self, *runtime_args, **runtime_kwargs):
        """ Execute the function, passing it the arguments received at
        runtime. Also call the function in self.call_afterwards and pass it
        all runtime_args and runtime_kwargs.
        If the very first argument is a LogoCode instance, it is removed.
        The active turtle, the Turtles object, the canvas, the LogoCode
        object, or the TurtleArtWindow object will be prepended to the
        arguments (depending on what this Primitive wants). """

        # remove the first argument if it is a LogoCode instance
        if runtime_args and isinstance(runtime_args[0], LogoCode):
            runtime_args = runtime_args[1:]

        if Primitive._DEBUG:
            debug_output(repr(self))
            debug_output("  runtime_args: " + repr(runtime_args))
        # fill the ArgSlots with the runtime arguments
        new_prim = self.fill_slots(runtime_args, runtime_kwargs,
                                   convert_to_ast=False)
        if not new_prim.are_slots_filled():
            raise logoerror("#syntaxerror")
        if Primitive._DEBUG:
            debug_output("  new_prim.arg_descs: " + repr(new_prim.arg_descs))

        # extract the actual values from the (now constant) arguments
        (new_args, new_kwargs) = new_prim.get_values_of_filled_slots()
        if Primitive._DEBUG:
            debug_output("  new_args: " + repr(new_args))
            debug_output("end " + repr(self))

        # what does this primitive want as its first argument?
        first_arg = None
        if not is_bound_method(new_prim.func):
            if new_prim.wants_turtle():
                first_arg = global_objects["turtles"].get_active_turtle()
            elif new_prim.wants_turtles():
                first_arg = global_objects["turtles"]
            elif new_prim.wants_canvas():
                first_arg = global_objects["canvas"]
            elif new_prim.wants_logocode():
                first_arg = global_objects["logo"]
            elif new_prim.wants_heap():
                first_arg = global_objects["logo"].heap
            elif new_prim.wants_tawindow():
                first_arg = global_objects["window"]
            else:
                result, plugin = new_prim.wants_plugin()
                if result:
                    first_arg = plugin

        # execute the actual function
        if first_arg is None:
            return_value = new_prim.func(*new_args, **new_kwargs)
        else:
            return_value = new_prim.func(first_arg, *new_args, **new_kwargs)

        if new_prim.call_afterwards is not None:
            new_prim.call_afterwards(*new_args, **new_kwargs)

        return return_value
 def set_shapes(self, shapes, i=0):
     ''' Reskin the turtle '''
     n = len(shapes)
     if n == 1 and i > 0:  # set shape[i]
         if i < len(self._shapes):
             self._shapes[i] = shapes[0]
     elif n == SHAPES:  # all shapes have been precomputed
         self._shapes = shapes[:]
     else:  # rotate shapes
         if n != 1:
             debug_output("%d images passed to set_shapes: ignoring" % (n),
                          self._turtles.turtle_window.running_sugar)
         if self._heading == 0.0:  # rotate the shapes
             images = []
             w, h = shapes[0].get_width(), shapes[0].get_height()
             nw = nh = int(sqrt(w * w + h * h))
             for i in range(SHAPES):
                 surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, nw, nh)
                 context = cairo.Context(surface)
                 context = gtk.gdk.CairoContext(context)
                 context.translate(nw / 2.0, nh / 2.0)
                 context.rotate(i * 10 * pi / 180.)
                 context.translate(-nw / 2.0, -nh / 2.0)
                 context.set_source_pixbuf(shapes[0], (nw - w) / 2.0,
                                           (nh - h) / 2.0)
                 context.rectangle(0, 0, nw, nh)
                 context.fill()
                 images.append(surface)
             self._shapes = images[:]
         else:  # associate shape with image at current heading
             j = int(self._heading + 5) % 360 / (360 / SHAPES)
             self._shapes[j] = shapes[0]
     self._custom_shapes = True
     self.show()
     self._calculate_sizes()
    def set_color(self, color=None, share=True):
        ''' Set the pen color for this turtle. '''
        # Special case for color blocks
        if color is not None and color in COLORDICT:
            self.set_shade(COLORDICT[color][1], share)
            self.set_gray(COLORDICT[color][2], share)
            if COLORDICT[color][0] is not None:
                self.set_color(COLORDICT[color][0], share)
                color = COLORDICT[color][0]
            else:
                color = self._pen_color
        elif color is None:
            color = self._pen_color

        try:
            self._pen_color = color
        except (TypeError, ValueError):
            debug_output('bad value sent to %s' % (__name__),
                         self._turtles.turtle_window.running_sugar)
            return

        self._turtles.turtle_window.canvas.set_fgcolor(shade=self._pen_shade,
                                                       gray=self._pen_gray,
                                                       color=self._pen_color)

        if self._turtles.turtle_window.sharing() and share:
            event = 'c|%s' % (data_to_string([self._turtles.turtle_window.nick,
                                              round_int(self._pen_color)]))
            self._turtles.turtle_window.send_event(event)
Esempio n. 8
0
    def forward(self, n, share=True):
        ''' Move the turtle forward.'''
        nn = n * self.tw.coord_scale
        self.canvas.set_source_rgb(self.fgrgb[0] / 255., self.fgrgb[1] / 255.,
                                   self.fgrgb[2] / 255.)
        if self.cr_svg is not None:
            debug_output('in forward', True)
            self.cr_svg.set_source_rgb(self.fgrgb[0] / 255.,
                                       self.fgrgb[1] / 255.,
                                       self.fgrgb[2] / 255.)
        oldx, oldy = self.xcor, self.ycor
        try:
            self.xcor += nn * sin(self.heading * DEGTOR)
            self.ycor += nn * cos(self.heading * DEGTOR)
        except (TypeError, ValueError):
            debug_output('bad value sent to %s' % (__name__),
                         self.tw.running_sugar)
            return
        if self.pendown:
            self.draw_line(oldx, oldy, self.xcor, self.ycor)

        self.move_turtle()

        if self.tw.sharing() and share:
            event = 'f|%s' % (data_to_string([self._get_my_nick(), int(n)]))
            self.tw.send_event(event)
        self.inval()
Esempio n. 9
0
 def settextsize(self, c):  # deprecated
     ''' Set the text size '''
     try:
         self.tw.textsize = c
     except (TypeError, ValueError):
         debug_output('bad value sent to %s' % (__name__),
                      self.tw.running_sugar)
    def start(self, file_path=None):
        self._want_document = False
        self.playpath = os.path.dirname(file_path)
        if not file_path:
            return False
        self.playlist.append('file://' + os.path.abspath(file_path))
        if not self.player:
            # Lazy init the player so that videowidget is realized
            # and has a valid widget allocation.
            self.player = GstPlayer(self.videowidget, self.running_sugar)
            self.player.connect('eos', self._player_eos_cb)
            self.player.connect('error', self._player_error_cb)
            self.player.connect('stream-info', self._player_stream_info_cb)

        try:
            if not self.currentplaying:
                debug_output('Playing: %s' % (self.playlist[0]),
                             self.running_sugar)
                self.player.set_uri(self.playlist[0])
                self.currentplaying = 0
                self.play_toggled()
        except Exception as e:
            error_output('Error playing %s: %s' % (self.playlist[0], e),
                         self.running_sugar)
        return False
Esempio n. 11
0
 def insert_desc(self, mimetype=None, description=None):
     """ Description text only (at current x, y) """
     w = self.wpercent()
     if w < 1:
         return
     text = None
     if text_media_type(self.filepath):
         if RTFPARSE and (
             mimetype == 'application/rtf' or
                 self.filepath.endswith(('rtf'))):
             text_only = RtfTextOnly()
             for line in open(self.filepath, 'r'):
                 text_only.feed(line)
                 text = text_only.output
         else:
             try:
                 f = open(self.filepath, 'r')
                 text = f.read()
                 f.close()
             except IOError:
                 self.tw.showlabel('nojournal', self.filepath)
                 debug_output("Couldn't open %s" % (self.filepath),
                              self.tw.running_sugar)
     else:
         if description is not None:
             text = str(description)
         else:
             text = self.filepath
     if text is not None:
         self.tw.turtles.get_active_turtle().draw_text(
             text, self.x2tx(), self.y2ty(), self.body_height, w)
Esempio n. 12
0
 def doevalstep(self):
     """ evaluate one step """
     starttime = _millisecond()
     try:
         while (_millisecond() - starttime) < 120:
             try:
                 if self.step is not None:
                     try:
                         self.step.next()
                     except ValueError:
                         debug_output('generator already executing',
                                      self.tw.running_sugar)
                         self.tw.running_blocks = False
                         return False
                 else:
                     return False
             except StopIteration:
                 # self.tw.turtles.show_all()
                 if self.hidden_turtle is not None:
                     self.hidden_turtle.show()
                     self.hidden_turtle = None
                 else:
                     self.tw.active_turtle.show()
                 self.tw.running_blocks = False
                 return False
     except logoerror, e:
         self.tw.showblocks()
         self.tw.display_coordinates()
         self.tw.showlabel('syntaxerror', str(e))
         self.tw.turtles.show_all()
         self.tw.running_blocks = False
         return False
Esempio n. 13
0
 def set_shapes(self, shapes, i=0):
     ''' Reskin the turtle '''
     n = len(shapes)
     if n == 1 and i > 0:  # set shape[i]
         if i < len(self._shapes):
             self._shapes[i] = shapes[0]
     elif n == SHAPES:  # all shapes have been precomputed
         self._shapes = shapes[:]
     else:  # rotate shapes
         if n != 1:
             debug_output("%d images passed to set_shapes: ignoring" % (n),
                          self._turtles.turtle_window.running_sugar)
         if self._heading == 0.0:  # rotate the shapes
             images = []
             w, h = shapes[0].get_width(), shapes[0].get_height()
             nw = nh = int(sqrt(w * w + h * h))
             for i in range(SHAPES):
                 surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, nw, nh)
                 context = cairo.Context(surface)
                 context = gtk.gdk.CairoContext(context)
                 context.translate(nw / 2.0, nh / 2.0)
                 context.rotate(i * 10 * pi / 180.)
                 context.translate(-nw / 2.0, -nh / 2.0)
                 context.set_source_pixbuf(shapes[0], (nw - w) / 2.0,
                                           (nh - h) / 2.0)
                 context.rectangle(0, 0, nw, nh)
                 context.fill()
                 images.append(surface)
             self._shapes = images[:]
         else:  # associate shape with image at current heading
             j = int(self._heading + 5) % 360 / (360 / SHAPES)
             self._shapes[j] = shapes[0]
     self._custom_shapes = True
     self.show()
     self._calculate_sizes()
Esempio n. 14
0
 def get_turtle_heading(self, turtle_name):
     #print 'taturtle.py: def get_turtle_heading'
     if turtle_name not in self.dict:
         debug_output('%s not found in turtle dictionary' % (turtle_name),
                      self.turtle_window.running_sugar)
         raise logoerror("#syntaxerror")
     return self.dict[turtle_name].get_heading()
Esempio n. 15
0
    def set_color(self, color=None, share=True):
        ''' Set the pen color for this turtle. '''
        # Special case for color blocks
        if color is not None and color in COLORDICT:
            self.set_shade(COLORDICT[color][1], share)
            self.set_gray(COLORDICT[color][2], share)
            if COLORDICT[color][0] is not None:
                self.set_color(COLORDICT[color][0], share)
                color = COLORDICT[color][0]
            else:
                color = self._pen_color
        elif color is None:
            color = self._pen_color

        try:
            self._pen_color = color
        except (TypeError, ValueError):
            debug_output('bad value sent to %s' % (__name__),
                         self._turtles.turtle_window.running_sugar)
            return

        self._turtles.turtle_window.canvas.set_fgcolor(shade=self._pen_shade,
                                                       gray=self._pen_gray,
                                                       color=self._pen_color)

        if self._turtles.turtle_window.sharing() and share:
            event = 'c|%s' % (data_to_string(
                [self._turtles.turtle_window.nick,
                 round_int(self._pen_color)]))
            self._turtles.turtle_window.send_event(event)
Esempio n. 16
0
    def setcolor(self, c, share=True):
        ''' Set the pen color '''

        # Special case for color blocks
        if c in COLORDICT:
            self.setshade(COLORDICT[c][1], share)
            self.setgray(COLORDICT[c][2], share)
            if COLORDICT[c][0] is not None:
                self.setcolor(COLORDICT[c][0], share)
                c = COLORDICT[c][0]
            else:
                c = self.color

        try:
            self.color = c
        except (TypeError, ValueError):
            debug_output('bad value sent to %s' % (__name__),
                         self.tw.running_sugar)
            return
        self.tw.active_turtle.set_color(c)
        self.set_fgcolor()
        if self.tw.sharing() and share:
            event = 'c|%s' % (data_to_string([self._get_my_nick(),
                                              round_int(c)]))
            self.tw.send_event(event)
Esempio n. 17
0
 def get_turtle_heading(self, turtle_name):
     #print 'taturtle.py: def get_turtle_heading'
     if turtle_name not in self.dict:
         debug_output('%s not found in turtle dictionary' % (turtle_name),
                      self.turtle_window.running_sugar)
         raise logoerror("#syntaxerror")
     return self.dict[turtle_name].get_heading()
Esempio n. 18
0
 def insert_desc(self, mimetype=None, description=None):
     """ Description text only (at current x, y) """
     w = self.wpercent()
     if w < 1:
         return
     text = None
     if text_media_type(self.filepath):
         if RTFPARSE and (mimetype == 'application/rtf'
                          or self.filepath.endswith(('rtf'))):
             text_only = RtfTextOnly()
             for line in open(self.filepath, 'r'):
                 text_only.feed(line)
                 text = text_only.output
         else:
             try:
                 f = open(self.filepath, 'r')
                 text = f.read()
                 f.close()
             except IOError:
                 self.tw.showlabel('nojournal', self.filepath)
                 debug_output("Couldn't open %s" % (self.filepath),
                              self.tw.running_sugar)
     else:
         if description is not None:
             text = str(description)
         else:
             text = self.filepath
     if text is not None:
         self.tw.canvas.draw_text(text, self.x2tx(), self.y2ty(),
                                  self.body_height, w)
Esempio n. 19
0
    def add_palette(self, position=None):
        if self._name is None:
            debug_output('You must specify a name for your palette')
            return

        # Insert new palette just before the trash
        if 'trash' in palette_names:
            i = palette_names.index('trash')
        else:
            i = len(palette_names)

        if position is not None and type(position) is int and position < i:
            i = position

        if self._name not in palette_names:
            palette_names.insert(i, self._name)
            palette_blocks.insert(i, [])
            block_colors.insert(i, self._colors)
        else:
            return

        # Special name entry is needed for help hover mechanism
        special_names[self._name] = self._special_name
        if self._help is not None:
            help_strings[self._name] = self._help
        else:
            help_strings[self._name] = ''
Esempio n. 20
0
 def setcolor(self, c, share=True):
     ''' Set the pen color '''
     try:
         self.color = c
     except TypeError, ValueError:
         debug_output('bad value sent to %s' % (__name__),
                      self.tw.running_sugar)
         return
Esempio n. 21
0
 def setgray(self, g, share=True):
     ''' Set the gray level '''
     try:
         self.gray = g
     except TypeError, ValueError:
         debug_output('bad value sent to %s' % (__name__),
                      self.tw.running_sugar)
         return
Esempio n. 22
0
 def setshade(self, s, share=True):
     ''' Set the color shade '''
     try:
         self.shade = s
     except TypeError, ValueError:
         debug_output('bad value sent to %s' % (__name__),
                      self.tw.running_sugar)
         return
Esempio n. 23
0
 def right(self, n, share=True):
     ''' Rotate turtle clockwise '''
     try:
         self.heading += n
     except TypeError, ValueError:
         debug_output('bad value sent to %s' % (__name__),
                      self.tw.running_sugar)
         return
Esempio n. 24
0
 def seth(self, n, share=True):
     ''' Set the turtle heading. '''
     try:
         self.heading = n
     except TypeError, ValueError:
         debug_output('bad value sent to %s' % (__name__),
                      self.tw.running_sugar)
         return
Esempio n. 25
0
    def __init__(self, turtle_window, n):
        '''This class handles the display of palette selectors (Only relevant
        to GNOME version and very old versions of Sugar).
        '''

        self.shapes = []
        self.spr = None
        self._turtle_window = turtle_window
        self._index = n

        if not n < len(palette_names):
            # Shouldn't happen, but hey...
            debug_output('palette index %d is out of range' % n,
                         self._turtle_window.running_sugar)
            self._name = 'extras'
        else:
            self._name = palette_names[n]

        icon_pathname = None
        for path in self._turtle_window.icon_paths:
            if os.path.exists(os.path.join(path, '%soff.svg' % (self._name))):
                icon_pathname = os.path.join(path, '%soff.svg' % (self._name))
                break

        if icon_pathname is not None:
            off_shape = svg_str_to_pixbuf(svg_from_file(icon_pathname))
        else:
            off_shape = svg_str_to_pixbuf(
                svg_from_file(
                    os.path.join(self._turtle_window.icon_paths[0],
                                 'extrasoff.svg')))
            error_output('Unable to open %soff.svg' % (self._name),
                         self._turtle_window.running_sugar)

        icon_pathname = None
        for path in self._turtle_window.icon_paths:
            if os.path.exists(os.path.join(path, '%son.svg' % (self._name))):
                icon_pathname = os.path.join(path, '%son.svg' % (self._name))
                break

        if icon_pathname is not None:
            on_shape = svg_str_to_pixbuf(svg_from_file(icon_pathname))
        else:
            on_shape = svg_str_to_pixbuf(
                svg_from_file(
                    os.path.join(self._turtle_window.icon_paths[0],
                                 'extrason.svg')))
            error_output('Unable to open %son.svg' % (self._name),
                         self._turtle_window.running_sugar)

        self.shapes.append(off_shape)
        self.shapes.append(on_shape)

        x = int(ICON_SIZE * self._index)
        self.spr = Sprite(self._turtle_window.sprite_list, x, 0, off_shape)
        self.spr.type = 'selector'
        self.spr.name = self._name
        self.set_layer()
Esempio n. 26
0
 def insert_image(self,
                  center=False,
                  filepath=None,
                  resize=True,
                  offset=False,
                  pixbuf=False):
     """ Image only (at current x, y) """
     if filepath is not None:
         self.filepath = filepath
     if not pixbuf:
         self.pixbuf = None
     w, h = self.wpercent(), self.hpercent()
     if w < 1 or h < 1:
         return
     if pixbuf:  # We may have to rescale the picture
         if w != self.pixbuf.get_width() or h != self.pixbuf.get_height():
             self.pixbuf = self.pixbuf.scale_simple(w, h,
                                                    gtk.gdk.INTERP_BILINEAR)
     elif self.dsobject is not None:
         try:
             self.pixbuf = get_pixbuf_from_journal(self.dsobject, w, h)
         except:
             debug_output("Couldn't open dsobject %s" % (self.dsobject),
                          self.tw.running_sugar)
     if self.pixbuf is None and \
        self.filepath is not None and \
        self.filepath != '':
         try:
             if not resize:
                 self.pixbuf = gtk.gdk.pixbuf_new_from_file(self.filepath)
                 w = self.pixbuf.get_width()
                 h = self.pixbuf.get_height()
             else:
                 self.pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(
                     self.filepath, w, h)
         except:
             self.tw.showlabel('nojournal', self.filepath)
             debug_output("Couldn't open filepath %s" % (self.filepath),
                          self.tw.running_sugar)
     if self.pixbuf is not None:
         x = self.tw.canvas.xcor
         y = self.tw.canvas.ycor
         w *= self.tw.coord_scale
         h *= self.tw.coord_scale
         if center:
             self.tw.canvas.draw_pixbuf(self.pixbuf, 0, 0,
                                        self.x2tx() - int(w / 2),
                                        self.y2ty() - int(h / 2), w, h,
                                        self.filepath)
         elif offset:
             self.tw.canvas.draw_pixbuf(self.pixbuf, 0, 0, self.x2tx(),
                                        self.y2ty() - h, w, h,
                                        self.filepath)
         else:
             self.tw.canvas.draw_pixbuf(self.pixbuf, 0, 0, self.x2tx(),
                                        self.y2ty(), w, h, self.filepath)
Esempio n. 27
0
 def _set_label_attributes(self):
     if self.spr is None:
         return
     if isinstance(self.name, unicode):
         self.name = self.name.encode('ascii', 'replace')
     if self.name in content_blocks:
         n = len(self.values)
         if n == 0:
             n = 1  # Force a scale to be set, even if there is no value.
     else:
         if self.name in block_names:
             n = len(block_names[self.name])
         else:
             debug_output('WARNING: unknown block name %s' % (self.name))
             n = 0
     for i in range(n):
         if i > 0:
             size = int(self.font_size[1] + 0.5)
         else:
             size = int(self.font_size[0] + 0.5)
         if self.name in block_styles['compare-porch-style']:
             self.spr.set_label_attributes(size,
                                           True,
                                           'center',
                                           'bottom',
                                           i=i)
         elif self.name in block_styles['number-style-porch']:
             self.spr.set_label_attributes(size,
                                           True,
                                           'right',
                                           'bottom',
                                           i=i)
         elif self.name in EXPANDABLE_FLOW:
             self._calc_moving_labels(i)
         elif self.name == 'string':
             self.spr.set_label_attributes(size, False, 'center', 'middle')
         elif i == 1:  # top
             self.spr.set_label_attributes(size, True, 'right', 'top', i=i)
         elif i > 0 and i == n - 1:  # bottom
             self.spr.set_label_attributes(size,
                                           True,
                                           'right',
                                           'bottom',
                                           i=i)
         elif i > 0:
             self.spr.set_label_attributes(size,
                                           True,
                                           'right',
                                           'middle',
                                           i=i)
         else:
             self.spr.set_label_attributes(size,
                                           True,
                                           'center',
                                           'middle',
                                           i=i)
Esempio n. 28
0
 def insert_image(self, center=False, filepath=None, resize=True,
                  offset=False, pixbuf=False):
     """ Image only (at current x, y) """
     if filepath is not None:
         self.filepath = filepath
     if not pixbuf:
         self.pixbuf = None
     w, h = self.wpercent(), self.hpercent()
     if w < 1 or h < 1:
         return
     if pixbuf:  # We may have to rescale the picture
         if w != self.pixbuf.get_width() or h != self.pixbuf.get_height():
             self.pixbuf = self.pixbuf.scale_simple(
                 w, h, gtk.gdk.INTERP_BILINEAR)
     elif self.dsobject is not None:
         try:
             self.pixbuf = get_pixbuf_from_journal(self.dsobject, w, h)
         except:
             debug_output("Couldn't open dsobject %s" % (self.dsobject),
                          self.tw.running_sugar)
     if self.pixbuf is None and \
        self.filepath is not None and \
        self.filepath != '':
         try:
             if not resize:
                 self.pixbuf = gtk.gdk.pixbuf_new_from_file(self.filepath)
                 w = self.pixbuf.get_width()
                 h = self.pixbuf.get_height()
             else:
                 self.pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(
                     self.filepath, w, h)
         except:
             self.tw.showlabel('nojournal', self.filepath)
             debug_output("Couldn't open filepath %s" % (self.filepath),
                          self.tw.running_sugar)
     if self.pixbuf is not None:
         w *= self.tw.coord_scale
         h *= self.tw.coord_scale
         if center:
             self.tw.turtles.get_active_turtle().draw_pixbuf(
                 self.pixbuf, 0, 0,
                 self.x2tx() - int(w / 2),
                 self.y2ty() - int(h / 2), w, h,
                 self.filepath)
         elif offset:
             self.tw.turtles.get_active_turtle().draw_pixbuf(
                 self.pixbuf, 0, 0,
                 self.x2tx(),
                 self.y2ty() - h,
                 w, h, self.filepath)
         else:
             self.tw.turtles.get_active_turtle().draw_pixbuf(
                 self.pixbuf, 0, 0,
                 self.x2tx(),
                 self.y2ty(),
                 w, h, self.filepath)
Esempio n. 29
0
 def setpensize(self, ps, share=True):
     ''' Set the pen size '''
     try:
         if ps < 0:
             ps = 0
         self.pensize = ps
     except TypeError, ValueError:
         debug_output('bad value sent to %s' % (__name__),
                      self.tw.running_sugar)
         return
Esempio n. 30
0
    def __init__(self, turtle_window, n):
        '''This class handles the display of palette selectors (Only relevant
        to GNOME version and very old versions of Sugar).
        '''

        self.shapes = []
        self.spr = None
        self._turtle_window = turtle_window
        self._index = n

        if not n < len(palette_names):
            # Shouldn't happen, but hey...
            debug_output('palette index %d is out of range' % n,
                         self._turtle_window.running_sugar)
            self._name = 'extras'
        else:
            self._name = palette_names[n]

        icon_pathname = None
        for path in self._turtle_window.icon_paths:
            if os.path.exists(os.path.join(path, '%soff.svg' % (self._name))):
                icon_pathname = os.path.join(path, '%soff.svg' % (self._name))
                break

        if icon_pathname is not None:
            off_shape = svg_str_to_pixbuf(svg_from_file(icon_pathname))
        else:
            off_shape = svg_str_to_pixbuf(svg_from_file(os.path.join(
                self._turtle_window.icon_paths[0], 'extrasoff.svg')))
            error_output('Unable to open %soff.svg' % (self._name),
                         self._turtle_window.running_sugar)

        icon_pathname = None
        for path in self._turtle_window.icon_paths:
            if os.path.exists(os.path.join(path, '%son.svg' % (self._name))):
                icon_pathname = os.path.join(path, '%son.svg' % (self._name))
                break

        if icon_pathname is not None:
            on_shape = svg_str_to_pixbuf(svg_from_file(icon_pathname))
        else:
            on_shape = svg_str_to_pixbuf(svg_from_file(os.path.join(
                self._turtle_window.icon_paths[0], 'extrason.svg')))
            error_output('Unable to open %son.svg' % (self._name),
                         self._turtle_window.running_sugar)

        self.shapes.append(off_shape)
        self.shapes.append(on_shape)

        x = int(ICON_SIZE * self._index)
        self.spr = Sprite(self._turtle_window.sprite_list, x, 0, off_shape)
        self.spr.type = 'selector'
        self.spr.name = self._name
        self.set_layer()
Esempio n. 31
0
 def setxy(self, x, y, share=True, pendown=True):
     ''' Move turtle to position x,y '''
     oldx, oldy = self.xcor, self.ycor
     x *= self.tw.coord_scale
     y *= self.tw.coord_scale
     try:
         self.xcor, self.ycor = x, y
     except TypeError, ValueError:
         debug_output('bad value sent to %s' % (__name__),
                      self.tw.running_sugar)
         return
Esempio n. 32
0
 def arc(self, a, r, share=True):
     ''' Draw an arc '''
     self.canvas.set_source_rgb(self.fgrgb[0] / 255., self.fgrgb[1] / 255.,
                                self.fgrgb[2] / 255.)
     try:
         if a < 0:
             self.larc(-a, r)
         else:
             self.rarc(a, r)
     except TypeError, ValueError:
         debug_output('bad value sent to %s' % (__name__),
                      self.tw.running_sugar)
         return
Esempio n. 33
0
 def forward(self, n, share=True):
     ''' Move the turtle forward.'''
     nn = n * self.tw.coord_scale
     self.canvas.set_source_rgb(self.fgrgb[0] / 255., self.fgrgb[1] / 255.,
                                self.fgrgb[2] / 255.)
     oldx, oldy = self.xcor, self.ycor
     try:
         self.xcor += nn * sin(self.heading * DEGTOR)
         self.ycor += nn * cos(self.heading * DEGTOR)
     except TypeError, ValueError:
         debug_output('bad value sent to %s' % (__name__),
                      self.tw.running_sugar)
         return
Esempio n. 34
0
 def setshade(self, s, share=True):
     ''' Set the color shade '''
     try:
         self.shade = s
     except (TypeError, ValueError):
         debug_output('bad value sent to %s' % (__name__),
                      self.tw.running_sugar)
         return
     self.tw.active_turtle.set_shade(s)
     self.set_fgcolor()
     if self.tw.sharing() and share:
         event = 's|%s' % (data_to_string([self._get_my_nick(),
                                           round_int(s)]))
         self.tw.send_event(event)
Esempio n. 35
0
 def right(self, n, share=True):
     ''' Rotate turtle clockwise '''
     try:
         self.heading += n
     except (TypeError, ValueError):
         debug_output('bad value sent to %s' % (__name__),
                      self.tw.running_sugar)
         return
     self.heading %= 360
     self.turn_turtle()
     if self.tw.sharing() and share:
         event = 'r|%s' % (data_to_string([self._get_my_nick(),
                                           round_int(self.heading)]))
         self.tw.send_event(event)
Esempio n. 36
0
    def right(self, degrees, share=True):
        ''' Rotate turtle clockwise '''
        try:
            self._heading += degrees
        except (TypeError, ValueError):
            debug_output('bad value sent to %s' % (__name__),
                         self._turtles.turtle_window.running_sugar)
            return
        self._heading %= 360

        self._update_sprite_heading()

        if self._turtles.turtle_window.sharing() and share:
            event = 'r|%s' % (data_to_string([self._turtles.turtle_window.nick,
                                              round_int(self._heading)]))
            self._turtles.turtle_window.send_event(event)
Esempio n. 37
0
    def set_heading(self, heading, share=True):
        ''' Set the turtle heading (one shape per 360/SHAPES degrees) '''
        try:
            self._heading = heading
        except (TypeError, ValueError):
            debug_output('bad value sent to %s' % (__name__),
                         self._turtles.turtle_window.running_sugar)
            return
        self._heading %= 360

        self._update_sprite_heading()

        if self._turtles.turtle_window.sharing() and share:
            event = 'r|%s' % (data_to_string([self._turtles.turtle_window.nick,
                                              round_int(self._heading)]))
            self._turtles.turtle_window.send_event(event)
Esempio n. 38
0
    def set_heading(self, heading, share=True):
        ''' Set the turtle heading (one shape per 360/SHAPES degrees) '''
        try:
            self._heading = heading
        except (TypeError, ValueError):
            debug_output('bad value sent to %s' % (__name__),
                         self._turtles.turtle_window.running_sugar)
            return
        self._heading %= 360

        self._update_sprite_heading()

        if self._turtles.turtle_window.sharing() and share:
            event = 'r|%s' % (data_to_string(
                [self._turtles.turtle_window.nick,
                 round_int(self._heading)]))
            self._turtles.turtle_window.send_event(event)
Esempio n. 39
0
    def set_pen_size(self, pen_size=None, share=True):
        ''' Set the pen size for this turtle. '''
        if pen_size is not None:
            try:
                self._pen_size = max(0, pen_size)
            except (TypeError, ValueError):
                debug_output('bad value sent to %s' % (__name__),
                             self._turtles.turtle_window.running_sugar)
                return

        self._turtles.turtle_window.canvas.set_pen_size(
            self._pen_size * self._turtles.turtle_window.coord_scale)

        if self._turtles.turtle_window.sharing() and share:
            event = 'w|%s' % (data_to_string([self._turtles.turtle_window.nick,
                                              round_int(self._pen_size)]))
            self._turtles.turtle_window.send_event(event)
Esempio n. 40
0
    def right(self, degrees, share=True):
        ''' Rotate turtle clockwise '''
        try:
            self._heading += degrees
        except (TypeError, ValueError):
            debug_output('bad value sent to %s' % (__name__),
                         self._turtles.turtle_window.running_sugar)
            return
        self._heading %= 360

        self._update_sprite_heading()

        if self._turtles.turtle_window.sharing() and share:
            event = 'r|%s' % (data_to_string(
                [self._turtles.turtle_window.nick,
                 round_int(self._heading)]))
            self._turtles.turtle_window.send_event(event)
Esempio n. 41
0
 def setpensize(self, ps, share=True):
     ''' Set the pen size '''
     try:
         if ps < 0:
             ps = 0
         self.pensize = ps
     except (TypeError, ValueError):
         debug_output('bad value sent to %s' % (__name__),
                      self.tw.running_sugar)
         return
     self.tw.active_turtle.set_pen_size(ps)
     self.canvas.set_line_width(ps)
     if self.cr_svg is not None:
         self.cr_svg.set_line_width(ps)
     if self.tw.sharing() and share:
         event = 'w|%s' % (data_to_string([self._get_my_nick(),
                                           round_int(ps)]))
         self.tw.send_event(event)
Esempio n. 42
0
    def set_shade(self, shade=None, share=True):
        ''' Set the pen shade for this turtle. '''
        if shade is not None:
            try:
                self._pen_shade = shade
            except (TypeError, ValueError):
                debug_output('bad value sent to %s' % (__name__),
                             self._turtles.turtle_window.running_sugar)
                return

        self._turtles.turtle_window.canvas.set_fgcolor(shade=self._pen_shade,
                                                       gray=self._pen_gray,
                                                       color=self._pen_color)

        if self._turtles.turtle_window.sharing() and share:
            event = 's|%s' % (data_to_string([self._turtles.turtle_window.nick,
                                              round_int(self._pen_shade)]))
            self._turtles.turtle_window.send_event(event)
Esempio n. 43
0
 def setgray(self, g, share=True):
     ''' Set the gray level '''
     try:
         self.gray = g
     except (TypeError, ValueError):
         debug_output('bad value sent to %s' % (__name__),
                      self.tw.running_sugar)
         return
     if self.gray < 0:
         self.gray = 0
     if self.gray > 100:
         self.gray = 100
     self.set_fgcolor()
     self.tw.active_turtle.set_gray(self.gray)
     if self.tw.sharing() and share:
         event = 'g|%s' % (data_to_string([self._get_my_nick(),
                                           round_int(self.gray)]))
         self.tw.send_event(event)
Esempio n. 44
0
    def forward(self, distance, share=True):
        scaled_distance = distance * self._turtles.turtle_window.coord_scale

        old = self.get_xy()
        try:
            xcor = old[0] + scaled_distance * sin(self._heading * DEGTOR)
            ycor = old[1] + scaled_distance * cos(self._heading * DEGTOR)
        except (TypeError, ValueError):
            debug_output('bad value sent to %s' % (__name__),
                         self._turtles.turtle_window.running_sugar)
            return

        self._draw_line(old, (xcor, ycor), True)
        self.move_turtle((xcor, ycor))

        if self._turtles.turtle_window.sharing() and share:
            event = 'f|%s' % (data_to_string([self._turtles.turtle_window.nick,
                                              int(distance)]))
            self._turtles.turtle_window.send_event(event)
Esempio n. 45
0
    def __init__(self, turtle_window, n):
        '''
        This class handles the display of block palettes
        '''
        self.blocks = []
        self.backgrounds = [None, None]
        self.visible = False
        self.populated = False

        self._turtle_window = turtle_window
        self._palette_index = n

        if not n < len(palette_names):
            # Shouldn't happen, but hey...
            debug_output('palette index %d is out of range' % n,
                         self._turtle_window.running_sugar)
            self._name = 'undefined'
        else:
            self._name = palette_names[n]
Esempio n. 46
0
    def arc(self, a, r, share=True):
        ''' Draw an arc '''
        if self._pen_state:
            self._turtles.turtle_window.canvas.set_source_rgb()
        try:
            if a < 0:
                pos = self.larc(-a, r)
            else:
                pos = self.rarc(a, r)
        except (TypeError, ValueError):
            debug_output('bad value sent to %s' % (__name__),
                         self._turtles.turtle_window.running_sugar)
            return

        self.move_turtle(pos)

        if self._turtles.turtle_window.sharing() and share:
            event = 'a|%s' % (data_to_string([self._turtles.turtle_window.nick,
                                              [round_int(a), round_int(r)]]))
            self._turtles.turtle_window.send_event(event)
Esempio n. 47
0
 def _set_label_attributes(self):
     if self.spr is None:
         return
     if isinstance(self.name, unicode):
         self.name = self.name.encode('utf-8')
     if self.name in content_blocks:
         n = len(self.values)
         if n == 0:
             n = 1  # Force a scale to be set, even if there is no value.
     else:
         if self.name in block_names:
             n = len(block_names[self.name])
         else:
             debug_output('WARNING: unknown block name %s' % (self.name))
             n = 0
     for i in range(n):
         if i > 0:
             size = int(self.font_size[1] + 0.5)
         else:
             size = int(self.font_size[0] + 0.5)
         if self.name in block_styles['compare-porch-style']:
             self.spr.set_label_attributes(size, True, 'center', 'bottom',
                                           i=i)
         elif self.name in block_styles['number-style-porch']:
             self.spr.set_label_attributes(size, True, 'right', 'bottom',
                                           i=i)
         elif self.name in EXPANDABLE_FLOW:
             self._calc_moving_labels(i)
         elif self.name == 'string':
             self.spr.set_label_attributes(size, False, 'center', 'middle')
         elif i == 1:  # top
             self.spr.set_label_attributes(size, True, 'right', 'top', i=i)
         elif i > 0 and i == n - 1:  # bottom
             self.spr.set_label_attributes(size, True, 'right', 'bottom',
                                           i=i)
         elif i > 0:
             self.spr.set_label_attributes(size, True, 'right', 'middle',
                                           i=i)
         else:
             self.spr.set_label_attributes(size, True, 'center', 'middle',
                                           i=i)
Esempio n. 48
0
    def set_xy(self, x, y, share=True, pendown=True, dragging=False):
        old = self.get_xy()
        try:
            if dragging:
                xcor = x
                ycor = y
            else:
                xcor = x * self._turtles.turtle_window.coord_scale
                ycor = y * self._turtles.turtle_window.coord_scale
        except (TypeError, ValueError):
            debug_output('bad value sent to %s' % (__name__),
                         self._turtles.turtle_window.running_sugar)
            return

        self._draw_line(old, (xcor, ycor), pendown)
        self.move_turtle((xcor, ycor))

        if self._turtles.turtle_window.sharing() and share:
            event = 'x|%s' % (data_to_string([self._turtles.turtle_window.nick,
                                              [round_int(xcor),
                                               round_int(ycor)]]))
            self._turtles.turtle_window.send_event(event)
Esempio n. 49
0
 def arc(self, a, r, share=True):
     ''' Draw an arc '''
     self.canvas.set_source_rgb(self.fgrgb[0] / 255., self.fgrgb[1] / 255.,
                                self.fgrgb[2] / 255.)
     if self.cr_svg is not None:
         self.cr_svg.set_source_rgb(self.fgrgb[0] / 255.,
                                    self.fgrgb[1] / 255.,
                                    self.fgrgb[2] / 255.)
     try:
         if a < 0:
             self.larc(-a, r)
         else:
             self.rarc(a, r)
     except (TypeError, ValueError):
         debug_output('bad value sent to %s' % (__name__),
                      self.tw.running_sugar)
         return
     self.move_turtle()
     if self.tw.sharing() and share:
         event = 'a|%s' % (data_to_string([self._get_my_nick(),
                                           [round_int(a), round_int(r)]]))
         self.tw.send_event(event)
    def get_ast(self, *arg_asts, **kwarg_asts):
        """Transform this object into a Python AST. When serialized and
        executed, the AST will do exactly the same as calling this
        object."""

        if Primitive._DEBUG:
            debug_output(repr(self))
            debug_output("  arg_asts: " + repr(arg_asts))
        new_prim = self.fill_slots(arg_asts, kwarg_asts, convert_to_ast=True)
        if not new_prim.are_slots_filled():
            raise PyExportError("not enough arguments")
        if Primitive._DEBUG:
            debug_output("  new_prim.arg_descs: " + repr(new_prim.arg_descs))

        # extract the actual values from the (now constant) arguments
        (new_arg_asts, new_kwarg_asts) = new_prim.get_values_of_filled_slots(
            exportable_only=True)
        if Primitive._DEBUG:
            debug_output("  new_arg_asts: " + repr(new_arg_asts))
            debug_output("end " + repr(self))

        # SPECIAL HANDLING #

        # loops
        if self == LogoCode.prim_loop:
            controller = self._get_loop_controller()
            if controller == Primitive.controller_repeat:
                # 'repeat' loop
                num_repetitions = new_arg_asts[0]
                if num_repetitions.func.id == 'controller_repeat':
                    num_repetitions = num_repetitions.args[0]
                repeat_iter = get_call_ast("range", [num_repetitions])
                # TODO use new variable name in nested loops
                loop_ast = ast.For(target=ast.Name(id="i", ctx=ast.Store),
                                   iter=repeat_iter,
                                   body=new_arg_asts[1],
                                   orelse=[])
                return loop_ast
            else:
                if controller == Primitive.controller_forever:
                    condition_ast = ast.Name(id="True", ctx=ast.Load)
                elif controller == Primitive.controller_while:
                    condition_ast = new_arg_asts[0].args[0]
                elif controller == Primitive.controller_until:
                    pos_cond_ast = new_arg_asts[0].args[0]
                    condition_ast = ast.UnaryOp(op=ast.Not,
                                                operand=pos_cond_ast)
                else:
                    raise PyExportError("unknown loop controller: " +
                                        repr(controller))
                loop_ast = ast.While(test=condition_ast,
                                     body=new_arg_asts[1],
                                     orelse=[])
                # Until always executes its body once.
                if controller == Primitive.controller_until:
                    loop_list = []
                    for arg_ast in new_arg_asts[1]:
                        loop_list.append(arg_ast)
                    loop_list.append(loop_ast)
                    return loop_list
                else:
                    return loop_ast

        # conditionals
        elif self in (LogoCode.prim_if, LogoCode.prim_ifelse):
            test = new_arg_asts[0]
            body = new_arg_asts[1]
            if len(new_arg_asts) > 2:
                orelse = new_arg_asts[2]
            else:
                orelse = []
            if_ast = ast.If(test=test, body=body, orelse=orelse)
            return if_ast

        # boxes
        elif self == LogoCode.prim_set_box:
            target_ast = ast.Subscript(value=BOX_AST,
                                       slice=ast.Index(value=new_arg_asts[0]),
                                       ctx=ast.Store)
            return ast.Assign(targets=[target_ast], value=new_arg_asts[1])
        elif self == LogoCode.prim_get_box:
            return ast.Subscript(value=BOX_AST,
                                 slice=ast.Index(value=new_arg_asts[0]),
                                 ctx=ast.Load)

        # action stacks
        elif self == LogoCode.prim_define_stack:
            return
        elif self == LogoCode.prim_invoke_stack:
            stack_func = ast.Subscript(
                value=ACTION_AST,
                slice=ast.Index(value=new_arg_asts[0]), ctx=ast.Load)
            call_ast = get_call_ast('logo.icall', [stack_func])
            return [call_ast, ast_yield_true()]
        elif self == LogoCode.prim_invoke_return_stack:
            # FIXME: Need to return value
            stack_func = ast.Subscript(
                value=ACTION_AST,
                slice=ast.Index(value=new_arg_asts[0]), ctx=ast.Load)
            call_ast = get_call_ast('logo.icall', [stack_func])
            return [call_ast, ast_yield_true()]

        # stop stack
        elif self == LogoCode.prim_stop_stack:
            return ast.Return()

        # sleep/ wait
        elif self == LogoCode.prim_wait:
            return [get_call_ast('sleep', new_arg_asts), ast_yield_true()]

        # standard operators
        elif self.func.__name__ in Primitive.STANDARD_OPERATORS:
            op = Primitive.STANDARD_OPERATORS[self.func.__name__]
            # 'divide': prevent unwanted integer division
            if self == Primitive.divide:
                def _is_float(x):
                    return get_type(x)[0] == TYPE_FLOAT
                if (not _is_float(new_arg_asts[0]) and
                        not _is_float(new_arg_asts[1])):
                    new_arg_asts[0] = get_call_ast('float', [new_arg_asts[0]],
                                                   return_type=TYPE_FLOAT)
            if len(new_arg_asts) == 1:
                if isinstance(op, tuple):
                    op = op[0]
                return ast.UnaryOp(op=op, operand=new_arg_asts[0])
            elif len(new_arg_asts) == 2:
                if isinstance(op, tuple):
                    op = op[1]
                (left, right) = new_arg_asts
                if issubclass(op, ast.boolop):
                    return ast.BoolOp(op=op, values=[left, right])
                elif issubclass(op, ast.cmpop):
                    return ast.Compare(left=left, ops=[op],
                                       comparators=[right])
                else:
                    return ast.BinOp(op=op, left=left, right=right)

        # f(x)
        elif self == LogoCode.prim_myfunction:
            param_asts = []
            for id_ in ['x', 'y', 'z'][:len(new_arg_asts) - 1]:
                param_asts.append(ast.Name(id=id_, ctx=ast.Param))
            func_ast = ast_extensions.LambdaWithStrBody(
                body_str=new_arg_asts[0].s, args=param_asts)
            return get_call_ast(func_ast, new_arg_asts[1:],
                                return_type=self.return_type)

        # square root
        elif self == Primitive.square_root:
            return get_call_ast('sqrt', new_arg_asts, new_kwarg_asts,
                                return_type=self.return_type)

        # random
        elif self in (Primitive.random_char, Primitive.random_int):
            uniform_ast = get_call_ast('uniform', new_arg_asts)
            round_ast = get_call_ast('round', [uniform_ast, ast.Num(n=0)])
            int_ast = get_call_ast('int', [round_ast], return_type=TYPE_INT)
            if self == Primitive.random_char:
                chr_ast = get_call_ast('chr', [int_ast], return_type=TYPE_CHAR)
                return chr_ast
            else:
                return int_ast

        # identity
        elif self == Primitive.identity:
            return new_arg_asts[0]

        # constant
        elif self == CONSTANTS.get:
            return TypedSubscript(value=ast.Name(id='CONSTANTS', ctx=ast.Load),
                                  slice_=ast.Index(value=new_arg_asts[0]),
                                  return_type=self.return_type)

        # group of Primitives or sandwich-clamp block
        elif self in (Primitive.group, LogoCode.prim_clamp):
            ast_list = []
            for prim in new_arg_asts[0]:
                if export_me(prim):
                    new_ast = value_to_ast(prim)
                    if isinstance(new_ast, ast.AST):
                        ast_list.append(new_ast)
            return ast_list

        # set turtle
        elif self == LogoCode.prim_turtle:
            text = 'turtle = turtles.get_active_turtle()'
            return [get_call_ast('logo.prim_turtle', new_arg_asts),
                    ast_extensions.ExtraCode(text)]

        elif self == LogoCode.active_turtle:
            text = 'turtle = turtles.get_active_turtle()'
            return ast_extensions.ExtraCode(text)

        # comment
        elif self == Primitive.comment:
            if isinstance(new_arg_asts[0], ast.Str):
                text = ' ' + str(new_arg_asts[0].s)
            else:
                text = ' ' + str(new_arg_asts[0])
            return ast_extensions.Comment(text)

        # print
        elif self == TurtleArtWindow.print_:
            func_name = self.get_name_for_export()
            call_ast = get_call_ast(func_name, new_arg_asts)
            print_ast = ast.Print(values=new_arg_asts[:1], dest=None, nl=True)
            return [call_ast, print_ast]

        # heap
        elif self == LogoCode.get_heap:
            return TypedName(id_='logo.heap', return_type=self.return_type)
        elif self == LogoCode.reset_heap:
            target_ast = ast.Name(id='logo.heap', ctx=ast.Store)
            value_ast = ast.List(elts=[], ctx=ast.Load)
            return ast.Assign(targets=[target_ast], value=value_ast)

        # NORMAL FUNCTION CALL #

        else:
            func_name = self.get_name_for_export()
            return get_call_ast(func_name, new_arg_asts, new_kwarg_asts,
                                return_type=self.return_type)
 def _player_eos_cb(self, widget):
     debug_output('end of stream', self.running_sugar)
     # Make sure player is stopped after EOS
     self.player.stop()