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
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)
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 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 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)
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()
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 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)
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
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()
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)
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)
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)
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] = ''
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
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
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
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
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
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()
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)
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)
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)
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
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()
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
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
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
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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]
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)
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)
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)
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()