diff options
author | Walter Bender <walter@sugarlabs.org> | 2013-06-23 23:49:17 (GMT) |
---|---|---|
committer | Walter Bender <walter@sugarlabs.org> | 2013-06-23 23:49:17 (GMT) |
commit | 9486dd411e22ffdf900dd5b51b72f4a8d3631f0f (patch) | |
tree | 1c13aca47629827549fcbba8e026f742274456ae | |
parent | 4fededf1be849b0026f8d864a1d4fa071597e01e (diff) |
turtle-centric
-rw-r--r-- | TurtleArt/tabasics.py | 113 | ||||
-rw-r--r-- | TurtleArt/tacanvas.py | 432 | ||||
-rw-r--r-- | TurtleArt/taturtle.py | 339 | ||||
-rw-r--r-- | TurtleArt/tawindow.py | 89 |
4 files changed, 495 insertions, 478 deletions
diff --git a/TurtleArt/tabasics.py b/TurtleArt/tabasics.py index 3f960da..6ed08dc 100644 --- a/TurtleArt/tabasics.py +++ b/TurtleArt/tabasics.py @@ -43,9 +43,13 @@ add_block method in the Palette class. # Next, you need to define what your block will do: # def_prim takes 3 arguments: the primitive name, the number of # arguments -- 0 in this case -- and the function to call -- in this - # case, the canvas.seth function to set the heading. - self.tw.lc.def_prim('uturn', 0, - lambda self: self.tw.canvas.seth(self.tw.canvas.heading + 180)) + # case, we define the _prim_uturn function to set heading += 180. + self.tw.lc.def_prim('uturn', 0, lambda self: self._prim_uturn) + def _prim_uturn(self): + value = self.tw.active_turtle.get_heading() + 180 + self.tw.active_turtle.set_heading(value) + if self.tw.lc.update_values: + self.tw.lc.update_label_value('heading', value) That's it. When you next run Turtle Art, you will have a 'uturn' block on the 'mypalette' palette. @@ -130,7 +134,7 @@ class Palettes(): self.tw.lc.def_prim('forward', 1, lambda self, x: primitive_dictionary['move'] - (self.tw.canvas.forward, x)) + (self.tw.active_turtle.forward, x)) palette.add_block('back', style='basic-style-1arg', @@ -142,9 +146,9 @@ class Palettes(): self.tw.lc.def_prim('back', 1, lambda self, x: primitive_dictionary['move'] - (self.tw.canvas.forward, x, reverse=True)) + (self.tw.active_turtle.forward, x, reverse=True)) - primitive_dictionary['clean'] = self.tw.lc.prim_clear + primitive_dictionary['clean'] = self._prim_clear palette.add_block('clean', style='basic-style-extended-vertical', label=_('clean'), @@ -190,7 +194,7 @@ degrees)')) self.tw.lc.def_prim('arc', 2, lambda self, x, y: primitive_dictionary['arc'] - (self.tw.canvas.arc, x, y)) + (self.tw.active_turtle.arc, x, y)) define_logo_function('taarc', 'to taarc :a :r\nrepeat round :a \ [right 1 forward (0.0175 * :r)]\nend\n') @@ -205,7 +209,7 @@ degrees)')) self.tw.lc.def_prim('setxy2', 2, lambda self, x, y: primitive_dictionary['move'] - (self.tw.canvas.setxy, x, y)) + (self.tw.active_turtle.set_xy, x, y)) define_logo_function('tasetxy', 'to tasetxy :x :y\nsetxy :x :y\nend\n') primitive_dictionary['set'] = self._prim_set @@ -220,7 +224,7 @@ towards the top of the screen.)')) self.tw.lc.def_prim('seth', 1, lambda self, x: primitive_dictionary['set'] - ('heading', self.tw.canvas.seth, x)) + ('heading', self.tw.active_turtle.set_heading, x)) palette.add_block('xcor', style='box-style', @@ -231,7 +235,8 @@ the turtle (can be used in place of a number block)'), prim_name='xcor', logo_command='xcor') self.tw.lc.def_prim( - 'xcor', 0, lambda self: self.tw.canvas.xcor / self.tw.coord_scale) + 'xcor', 0, lambda self: + self.tw.active_turtle.get_xy()[0] / self.tw.coord_scale) palette.add_block('ycor', style='box-style', @@ -242,7 +247,8 @@ the turtle (can be used in place of a number block)'), prim_name='ycor', logo_command='ycor') self.tw.lc.def_prim( - 'ycor', 0, lambda self: self.tw.canvas.ycor / self.tw.coord_scale) + 'ycor', 0, lambda self: + self.tw.active_turtle.get_xy() / self.tw.coord_scale) palette.add_block('heading', style='box-style', @@ -253,7 +259,7 @@ turtle (can be used in place of a number block)'), prim_name='heading', logo_command='heading') self.tw.lc.def_prim( - 'heading', 0, lambda self: self.tw.canvas.heading) + 'heading', 0, lambda self: self.tw.active_turtle.get_heading) palette.add_block('turtle-label', hidden=True, @@ -273,7 +279,8 @@ turtle (can be used in place of a number block)'), self.tw.lc.def_prim('setxy', 2, lambda self, x, y: primitive_dictionary['move'] - (self.tw.canvas.setxy, x, y, pendown=False)) + (self.tw.active_turtle.set_xy, x, y, + pendown=False)) define_logo_function('tasetxypenup', 'to tasetxypenup :x :y\npenup\n\ setxy :x :y\npendown\nend\n') @@ -323,7 +330,7 @@ turtle')) self.tw.lc.def_prim('setcolor', 1, lambda self, x: primitive_dictionary['set'] - ('color', self.tw.canvas.setcolor, x)) + ('color', self.tw.active_turtle.set_color, x)) palette.add_block('setshade', style='basic-style-1arg', @@ -336,7 +343,7 @@ turtle')) self.tw.lc.def_prim('setshade', 1, lambda self, x: primitive_dictionary['set'] - ('shade', self.tw.canvas.setshade, x)) + ('shade', self.tw.active_turtle.set_shade, x)) palette.add_block('setgray', style='basic-style-1arg', @@ -348,7 +355,7 @@ the turtle')) self.tw.lc.def_prim('setgray', 1, lambda self, x: primitive_dictionary['set'] - ('gray', self.tw.canvas.setgray, x)) + ('gray', self.tw.active_turtle.set_gray, x)) palette.add_block('color', style='box-style', @@ -358,7 +365,8 @@ in place of a number block)'), value_block=True, prim_name='color', logo_command='pencolor') - self.tw.lc.def_prim('color', 0, lambda self: self.tw.canvas.color) + self.tw.lc.def_prim('color', 0, lambda self: + self.tw.active_turtle.get_color) palette.add_block('shade', style='box-style', @@ -367,7 +375,8 @@ in place of a number block)'), value_block=True, prim_name='shade', logo_command=':shade') - self.tw.lc.def_prim('shade', 0, lambda self: self.tw.canvas.shade) + self.tw.lc.def_prim('shade', 0, lambda self: + self.tw.active_turtle.get_shade) palette.add_block('gray', style='box-style', @@ -376,7 +385,8 @@ in place of a number block)'), used in place of a number block)'), value_block=True, prim_name='gray') - self.tw.lc.def_prim('gray', 0, lambda self: self.tw.canvas.gray) + self.tw.lc.def_prim('gray', 0, lambda self: + self.tw.active_turtle.get_gray) palette.add_block('penup', style='basic-style-extended-vertical', @@ -385,7 +395,7 @@ used in place of a number block)'), logo_command='penup', help_string=_('Turtle will not draw when moved.')) self.tw.lc.def_prim('penup', 0, - lambda self: self.tw.canvas.setpen(False)) + lambda self: self.tw.active_turtle.set_pen(False)) palette.add_block('pendown', style='basic-style-extended-vertical', @@ -394,7 +404,7 @@ used in place of a number block)'), logo_command='pendown', help_string=_('Turtle will draw when moved.')) self.tw.lc.def_prim('pendown', 0, - lambda self: self.tw.canvas.setpen(True)) + lambda self: self.tw.active_turtle.set_pen(True)) palette.add_block('setpensize', style='basic-style-1arg', @@ -407,9 +417,9 @@ turtle')) self.tw.lc.def_prim('setpensize', 1, lambda self, x: primitive_dictionary['set'] - ('pensize', self.tw.canvas.setpensize, x)) - define_logo_function('tasetpensize', 'to tasetpensize :a\nsetpensize \ -round :a\nend\n') + ('pensize', self.tw.active_turtle.set_pen_size, x)) + define_logo_function('tasetpensize', + 'to tasetpensize :a\nsetpensize round :a\nend\n') palette.add_block('startfill', style='basic-style-extended-vertical', @@ -418,7 +428,7 @@ round :a\nend\n') help_string=_('starts filled polygon (used with end \ fill block)')) self.tw.lc.def_prim('startfill', 0, - lambda self: self.tw.canvas.start_fill()) + lambda self: self.tw.active_turtle.start_fill()) palette.add_block('stopfill', style='basic-style-extended-vertical', @@ -427,7 +437,7 @@ fill block)')) help_string=_('completes filled polygon (used with \ start fill block)')) self.tw.lc.def_prim('stopfill', 0, - lambda self: self.tw.canvas.stop_fill()) + lambda self: self.tw.active_turtle.stop_fill()) palette.add_block('pensize', style='box-style', @@ -437,7 +447,7 @@ in place of a number block)'), value_block=True, prim_name='pensize', logo_command='pensize') - self.tw.lc.def_prim('pensize', 0, lambda self: self.tw.canvas.pensize) + self.tw.lc.def_prim('pensize', 0, lambda self: self.tw.active_turtle.get_pen_size) define_logo_function('tapensize', 'to tapensize\noutput first round \ pensize\nend\n') @@ -461,29 +471,6 @@ pensize\nend\n') self._make_constant(palette, 'white', _('white'), CONSTANTS['white']) self._make_constant(palette, 'black', _('black'), CONSTANTS['black']) - # deprecated blocks - palette.add_block('settextcolor', - hidden=True, - style='basic-style-1arg', - label=_('set text color'), - prim_name='settextcolor', - default=0, - help_string=_('sets color of text drawn by the \ -turtle')) - self.tw.lc.def_prim('settextcolor', 1, - lambda self, x: self.tw.canvas.settextcolor(x)) - - palette.add_block('settextsize', - hidden=True, - style='basic-style-1arg', - label=_('set text size'), - prim_name='settextsize', - default=0, - help_string=_('sets size of text drawn by the \ -turtle')) - self.tw.lc.def_prim('settextsize', 1, - lambda self, x: self.tw.canvas.settextsize(x)) - # In order to map Turtle Art colors to the standard UCB Logo palette, # we need to define a somewhat complex set of functions. define_logo_function('tacolor', '\ @@ -1025,6 +1012,10 @@ variable')) # Block primitives + def _prim_clear(self): + self.tw.lc.prim_clear() + self.tw.reset_turtles() + def _prim_and(self, x, y): """ Logical and """ return x & y @@ -1034,10 +1025,13 @@ variable')) cmd(float(value1), float(value2)) if self.tw.lc.update_values: self.tw.lc.update_label_value( - 'xcor', self.tw.canvas.xcor / self.tw.coord_scale) + 'xcor', + self.tw.active_turtle.get_xy()[0] / self.tw.coord_scale) self.tw.lc.update_label_value( - 'ycor', self.tw.canvas.ycor / self.tw.coord_scale) - self.tw.lc.update_label_value('heading', self.tw.canvas.heading) + 'ycor', + self.tw.active_turtle.get_xy()[1] / self.tw.coord_scale) + self.tw.lc.update_label_value('heading', + self.tw.active_turtle.get_heading) def _prim_box(self, x): """ Retrieve value from named box """ @@ -1092,9 +1086,11 @@ variable')) cmd(float(value1), float(value2), pendown=pendown) if self.tw.lc.update_values: self.tw.lc.update_label_value( - 'xcor', self.tw.canvas.xcor / self.tw.coord_scale) + 'xcor', + self.tw.active_turtle.get_xy()[0] / self.tw.coord_scale) self.tw.lc.update_label_value( - 'ycor', self.tw.canvas.ycor / self.tw.coord_scale) + 'ycor', + self.tw.active_turtle.get_xy()[1] / self.tw.coord_scale) def _prim_or(self, x, y): """ Logical or """ @@ -1118,11 +1114,12 @@ variable')) if not _num_type(value): raise logoerror("#notanumber") if reverse: - self.tw.canvas.right(float(-value)) + self.tw.active_turtle.right(float(-value)) else: - self.tw.canvas.right(float(value)) + self.tw.active_turtle.right(float(value)) if self.tw.lc.update_values: - self.tw.lc.update_label_value('heading', self.tw.canvas.heading) + self.tw.lc.update_label_value('heading', + self.tw.active_turtle.get_heading) def _prim_set(self, name, cmd, value=None): """ Set a value and update the associated value blocks """ diff --git a/TurtleArt/tacanvas.py b/TurtleArt/tacanvas.py index 5eaa4a8..1b02a31 100644 --- a/TurtleArt/tacanvas.py +++ b/TurtleArt/tacanvas.py @@ -118,11 +118,11 @@ class TurtleGraphics: self.bgrgb = [255, 248, 222] self.textsize = 48 # deprecated self.shade = 0 - self.pendown = False + self.pen_down = False self.xcor = 0 self.ycor = 0 self.heading = 0 - self.pensize = 5 + self.pen_size = 5 self.color = 0 self.gray = 100 self.fill = False @@ -141,27 +141,6 @@ class TurtleGraphics: self.cr_svg = cairo.Context(svg_surface) self.cr_svg.set_line_cap(1) # Set the line cap to be round - def start_fill(self): - ''' Start accumulating points of a polygon to fill. ''' - self.fill = True - self.poly_points = [] - - def stop_fill(self): - ''' Fill the polygon. ''' - self.fill = False - if len(self.poly_points) == 0: - return - self.fill_polygon(self.poly_points) - if self.tw.sharing(): - shared_poly_points = [] - for p in self.poly_points: - shared_poly_points.append((self.screen_to_turtle_coordinates - (p[0], p[1]))) - event = 'F|%s' % (data_to_string([self._get_my_nick(), - shared_poly_points])) - self.tw.send_event(event) - self.poly_points = [] - def fill_polygon(self, poly_points): ''' Draw the polygon... ''' def _fill_polygon(cr, poly_points): @@ -200,320 +179,59 @@ class TurtleGraphics: if self.cr_svg is not None: _clearscreen(self.cr_svg) - self.setpensize(5, share) - self.setgray(100, share) - self.setcolor(0, share) - self.setshade(50, share) - self.fill = False - self.poly_points = [] - for turtle_key in iter(self.tw.turtles.dict): - # Don't reset remote turtles - if not self.tw.remote_turtle(turtle_key): - self.set_turtle(turtle_key) - self.tw.active_turtle.set_color(0) - self.tw.active_turtle.set_shade(50) - self.tw.active_turtle.set_gray(100) - self.tw.active_turtle.set_pen_size(5) - self.tw.active_turtle.reset_shapes() - self.seth(0.0, share) - self.setpen(False, share) - self.setxy(0.0, 0.0, share) - self.setpen(True, share) - self.tw.active_turtle.hide() - self.set_turtle(self.tw.default_turtle_name) - - 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() + def rarc(self, x, y, r, a, heading): + ''' draw a clockwise arc ''' + def _rarc(cr, x, y, r, a, h): + cr.arc(x, y, r, (h - 180) * DEGTOR, (h - 180 + a) * DEGTOR) + cr.stroke() - if self.tw.sharing() and share: - event = 'f|%s' % (data_to_string([self._get_my_nick(), int(n)])) - self.tw.send_event(event) + _rarc(self.canvas, x, y, r, a, heading) self.inval() - 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 - 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, 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 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) + _rarc(self.cr_svg, x, y, r, a, heading) - def rarc(self, a, r): - ''' draw a clockwise arc ''' - r *= self.tw.coord_scale - if r < 0: - r = -r - a = -a - oldx, oldy = self.xcor, self.ycor - cx = self.xcor + r * cos(self.heading * DEGTOR) - cy = self.ycor - r * sin(self.heading * DEGTOR) - if self.pendown: - x, y = self.turtle_to_screen_coordinates(cx, cy) - - def _rarc(cr, x, y, r, a, h): - cr.arc(x, y, r, (h - 180) * DEGTOR, (h - 180 + a) * DEGTOR) - cr.stroke() - - _rarc(self.canvas, x, y, r, a, self.heading) - self.inval() - if self.cr_svg is not None: - _rarc(self.cr_svg, x, y, r, a, self.heading) - - if self.fill: - if self.poly_points == []: - self.poly_points.append(('move', x, y)) - self.poly_points.append(('rarc', x, y, r, - (self.heading - 180) * DEGTOR, - (self.heading - 180 + a) * DEGTOR)) - - self.right(a, False) - self.xcor = cx - r * cos(self.heading * DEGTOR) - self.ycor = cy + r * sin(self.heading * DEGTOR) - - def larc(self, a, r): + def larc(self, x, y, r, a, heading): ''' draw a counter-clockwise arc ''' - r *= self.tw.coord_scale - if r < 0: - r = -r - a = -a - oldx, oldy = self.xcor, self.ycor - cx = self.xcor - r * cos(self.heading * DEGTOR) - cy = self.ycor + r * sin(self.heading * DEGTOR) - if self.pendown: - x, y = self.turtle_to_screen_coordinates(cx, cy) - - def _larc(cr, x, y, r, a, h): - cr.arc_negative(x, y, r, h * DEGTOR, (h - a) * DEGTOR) - cr.stroke() - - _larc(self.canvas, x, y, r, a, self.heading) - self.inval() - if self.cr_svg is not None: - _larc(self.cr_svg, x, y, r, a, self.heading) - - if self.fill: - if self.poly_points == []: - self.poly_points.append(('move', x, y)) - self.poly_points.append(('larc', x, y, r, - (self.heading) * DEGTOR, - (self.heading - a) * DEGTOR)) - - self.right(-a, False) - self.xcor = cx + r * cos(self.heading * DEGTOR) - self.ycor = cy - r * sin(self.heading * DEGTOR) - - 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() + def _larc(cr, x, y, r, a, h): + cr.arc_negative(x, y, r, h * DEGTOR, (h - a) * DEGTOR) + cr.stroke() - 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) + _larc(self.canvas, x, y, r, a, self.heading) + self.inval() + if self.cr_svg is not None: + _larc(self.cr_svg, x, y, r, a, self.heading) - def setpensize(self, ps, share=True): + def set_pen_size(self, pen_size): ''' 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) + self.canvas.set_line_width(pen_size) 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) + self.cr_svg.set_line_width(pen_size) - def setcolor(self, c, share=True): - ''' Set the pen color ''' + def fillscreen(self, c, s): + ''' Deprecated method: Fill screen with color/shade ''' + self.fillscreen_with_gray(c, s, self.gray) + + def fillscreen_with_gray(self, color, shade, gray): + ''' Fill screen with color/shade/gray and reset to defaults ''' # 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] + if color in COLORDICT: + if COLORDICT[color][0] is None: + self.shade = COLORDICT[color][1] 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) + self.color = COLORDICT[color][0] + if shade in COLORDICT: + self.shade = COLORDICT[shade][1] + if gray in COLORDICT: + self.gray = COLORDICT[gray][2] - 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 set_textcolor(self): - ''' Deprecated: Set the text color to foreground color. ''' - return - - def settextcolor(self, c): # deprecated - ''' Set the text color ''' - return - - 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 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 fillscreen(self, c, s): - ''' Deprecated method: Fill screen with color/shade ''' - self.fillscreen_with_gray(c, s, self.gray) - - def fillscreen_with_gray(self, c, s, g): - ''' Fill screen with color/shade/gray and reset to defaults ''' - oldc, olds, oldg = self.color, self.shade, self.gray - # Special case for color blocks - if c in COLORDICT: - if COLORDICT[c][0] is None: - s = COLORDICT[c][1] - c = self.color - else: - c = COLORDICT[c][0] - if s in COLORDICT: - s = COLORDICT[s][1] - if g in COLORDICT: - g = COLORDICT[g][2] - - self.setcolor(c, False) - self.setshade(s, False) - self.setgray(g, False) + self.set_fgcolor(self) self.bgrgb = self.fgrgb[:] def _fillscreen(cr, rgb, w, h): @@ -525,14 +243,17 @@ class TurtleGraphics: self.inval() if self.cr_svg is not None: _fillscreen(self.cr_svg, self.fgrgb, self.width, self.height) - self.setcolor(oldc, False) - self.setshade(olds, False) - self.setgray(oldg, False) - self.fill = False - self.poly_points = [] - def set_fgcolor(self): + # self.tw.active_turtle.set_fill(state=False) + + def set_fgcolor(self, shade=None, gray=None, color=None): ''' Set the foreground color ''' + if shade is not None: + self.shade=shade + if gray is not None: + self.gray=gray + if color is not None: + self.color=color sh = (wrap100(self.shade) - 50) / 50.0 rgb = COLOR_TABLE[wrap100(self.color)] r = (rgb >> 8) & 0xff00 @@ -546,13 +267,9 @@ class TurtleGraphics: b = calc_shade(b, sh) self.fgrgb = [r >> 8, g >> 8, b >> 8] - def setpen(self, bool, share=True): + def set_pen(self, state): ''' Lower or raise the pen ''' - self.pendown = bool - self.tw.active_turtle.set_pen_state(bool) - if self.tw.sharing() and share: - event = 'p|%s' % (data_to_string([self._get_my_nick(), bool])) - self.tw.send_event(event) + self.pen_down = state def draw_surface(self, surface, x, y, w, h): ''' Draw a surface ''' @@ -662,6 +379,18 @@ class TurtleGraphics: coordinates ''' return self.height / 2. - y + def set_rgb(self, r, g, b): + self.canvas.set_source_rgb(r, g, b) + if self.cr_svg is not None: + self.cr_svg.set_source_rgb(r, g, b) + + def set_xy(self, x, y): + self.xcor = x + self.ycor = y + + def get_xy(self): + return self.xcor, self.ycor + def draw_line(self, x1, y1, x2, y2): ''' Draw a line ''' x1, y1 = self.turtle_to_screen_coordinates(x1, y1) @@ -675,24 +404,7 @@ class TurtleGraphics: _draw_line(self.canvas, x1, y1, x2, y2) if self.cr_svg is not None: _draw_line(self.cr_svg, x1, y1, x2, y2) - if self.fill: - if self.poly_points == []: - self.poly_points.append(('move', x1, y1)) - self.poly_points.append(('line', x2, y2)) - - def turn_turtle(self): - ''' Change the orientation of the turtle ''' - self.tw.active_turtle.set_heading(self.heading) - - def move_turtle(self): - ''' Move the turtle ''' - x, y = self.turtle_to_screen_coordinates(self.xcor, self.ycor) - if self.tw.interactive_mode: - self.tw.active_turtle.move( - (self.cx + x - self.tw.active_turtle.spr.rect.width / 2., - self.cy + y - self.tw.active_turtle.spr.rect.height / 2.)) - else: - self.tw.active_turtle.move((self.cx + x, self.cy + y)) + self.inval() def get_color_index(self, r, g, b, a=0): ''' Find the closest palette entry to the rgb triplet ''' @@ -750,32 +462,6 @@ class TurtleGraphics: else: return(-1, -1, -1, -1) - def set_turtle(self, k, colors=None): - ''' Select the current turtle and associated pen status ''' - if k not in self.tw.turtles.dict: - # if it is a new turtle, start it in the center of the screen - self.tw.active_turtle = self.tw.turtles.get_turtle(k, True, colors) - self.seth(0.0, False) - self.setxy(0.0, 0.0, False, pendown=False) - self.tw.active_turtle.set_pen_state(True) - elif colors is not None: - self.tw.active_turtle = self.tw.turtles.get_turtle(k, False) - self.tw.active_turtle.set_turtle_colors(colors) - else: - self.tw.active_turtle = self.tw.turtles.get_turtle(k, False) - self.tw.active_turtle.show() - tx, ty = self.tw.active_turtle.get_xy() - self.xcor, self.ycor = self.screen_to_turtle_coordinates(tx, ty) - if self.tw.interactive_mode: - self.xcor += self.tw.active_turtle.spr.rect.width / 2. - self.ycor -= self.tw.active_turtle.spr.rect.height / 2. - self.heading = self.tw.active_turtle.get_heading() - self.setcolor(self.tw.active_turtle.get_color(), False) - self.setgray(self.tw.active_turtle.get_gray(), False) - self.setshade(self.tw.active_turtle.get_shade(), False) - self.setpensize(self.tw.active_turtle.get_pen_size(), False) - self.setpen(self.tw.active_turtle.get_pen_state(), False) - def svg_close(self): ''' Close current SVG graphic ''' self.cr_svg.show_page() diff --git a/TurtleArt/taturtle.py b/TurtleArt/taturtle.py index 7db72e6..992af95 100644 --- a/TurtleArt/taturtle.py +++ b/TurtleArt/taturtle.py @@ -26,11 +26,13 @@ import cairo from taconstants import (TURTLE_LAYER, DEFAULT_TURTLE_COLORS) from tasprite_factory import (SVG, svg_str_to_pixbuf) -from tacanvas import (wrap100, COLOR_TABLE) +from tacanvas import (wrap100, COLOR_TABLE, COLORDICT) from sprites import Sprite -from tautils import debug_output +from tautils import debug_output, data_to_string, round_int SHAPES = 36 +DEGTOR = pi / 180. +RTODEG = 180. / pi def generate_turtle_pixbufs(colors): @@ -109,8 +111,9 @@ class Turtles: class Turtle: - def __init__(self, turtles, key, turtle_colors=None): + def __init__(self, turtle_window, turtles, key, turtle_colors=None): """ The turtle is not a block, just a sprite with an orientation """ + self.tw = turtle_window self.x = 0.0 self.y = 0.0 self.hidden = False @@ -124,6 +127,8 @@ class Turtle: self.pen_gray = 100 self.pen_size = 5 self.pen_state = True + self.pen_fill = False + self.pen_poly_points = [] self.label_block = None self._prep_shapes(key, turtles, turtle_colors) @@ -175,7 +180,7 @@ class Turtle: if turtle_colors is not None: self.colors = turtle_colors[:] self.shapes = generate_turtle_pixbufs(self.colors) - self.set_heading(self.heading) + self.set_heading(self.heading, share=False) def set_shapes(self, shapes, i=0): """ Reskin the turtle """ @@ -218,9 +223,16 @@ class Turtle: self.shapes = generate_turtle_pixbufs(self.colors) self.custom_shapes = False - def set_heading(self, heading): + def set_heading(self, heading, share=True): """ Set the turtle heading (one shape per 360/SHAPES degrees) """ - self.heading = heading + try: + self.heading = heading + except (TypeError, ValueError): + debug_output('bad value sent to %s' % (__name__), + self.tw.running_sugar) + return + self.heading %= 360 + i = (int(self.heading + 5) % 360) / (360 / SHAPES) if not self.hidden and self.spr is not None: try: @@ -228,28 +240,142 @@ class Turtle: except IndexError: self.spr.set_shape(self.shapes[0]) - def set_color(self, color): + if self.tw.sharing() and share: + event = 'r|%s' % (data_to_string([self.tw.nick, + round_int(self.heading)])) + self.tw.send_event(event) + + def set_color(self, color=None, share=True): """ Set the pen color for this turtle. """ - self.pen_color = color + # 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 + + try: + self.pen_color = color + except (TypeError, ValueError): + debug_output('bad value sent to %s' % (__name__), + self.tw.running_sugar) + return + + self.tw.canvas.set_fgcolor(shade=self.pen_shade, + gray=self.pen_gray, + color=self.pen_color) + + if self.tw.sharing() and share: + event = 'c|%s' % (data_to_string([self.tw.nick, + round_int(self.pen_color)])) + self.tw.send_event(event) - def set_gray(self, gray): + def set_gray(self, gray=None, share=True): """ Set the pen gray level for this turtle. """ - self.pen_gray = gray + if gray is not None: + try: + self.pen_gray = gray + except (TypeError, ValueError): + debug_output('bad value sent to %s' % (__name__), + self.tw.running_sugar) + return + + if self.pen_gray < 0: + self.pen_gray = 0 + if self.pen_gray > 100: + self.pen_gray = 100 + + self.tw.canvas.set_fgcolor(shade=self.pen_shade, + gray=self.pen_gray, + color=self.pen_color) - def set_shade(self, shade): + if self.tw.sharing() and share: + event = 'g|%s' % (data_to_string([self.tw.nick, + round_int(self.pen_gray)])) + self.tw.send_event(event) + + def set_shade(self, shade=None, share=True): """ Set the pen shade for this turtle. """ - self.pen_shade = shade + if shade is not None: + try: + self.pen_shade = shade + except (TypeError, ValueError): + debug_output('bad value sent to %s' % (__name__), + self.tw.running_sugar) + return + + self.tw.canvas.set_fgcolor(shade=self.pen_shade, + gray=self.pen_gray, + color=self.pen_color) - def set_pen_size(self, pen_size): + if self.tw.sharing() and share: + event = 's|%s' % (data_to_string([self.tw.nick, + round_int(self.pen_shade)])) + self.tw.send_event(event) + + def set_pen_size(self, pen_size=None, share=True): """ Set the pen size for this turtle. """ - self.pen_size = pen_size + 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.tw.running_sugar) + return + + self.tw.canvas.set_pen_size(self.pen_size) - def set_pen_state(self, pen_state): + if self.tw.sharing() and share: + event = 'w|%s' % (data_to_string([self.tw.nick, + round_int(self.pen_size)])) + self.tw.send_event(event) + + def set_pen_state(self, pen_state=None, share=True): """ Set the pen state (down==True) for this turtle. """ - self.pen_state = pen_state + if pen_state is not None: + self.pen_state = pen_state + + self.tw.canvas.set_pen(self.pen_state) + + if self.tw.sharing() and share: + event = 'p|%s' % (data_to_string([self.tw.nick, + self._pen_state])) + self.tw.send_event(event) + + def set_fill(self, state=False): + self.pen_fill = state + if not self.pen_fill: + self.poly_points = [] + + def set_poly_points(self, poly_points=None): + if poly_points is not None: + self.poly_points = poly_points[:] + + def start_fill(self): + self.pen_fill = True + self.poly_points = [] + + def stop_fill(self, share=True): + self.pen_fill = False + if len(self.poly_points) == 0: + return + + self.tw.canvas.fill_polygon(self.poly_points) + + if self.tw.sharing() and share: + shared_poly_points = [] + for p in self.poly_points: + shared_poly_points.append( + (self.tw.canvas.screen_to_turtle_coordinates(p[0], p[1]))) + event = 'F|%s' % (data_to_string([self.tw.nick, + shared_poly_points])) + self.tw.send_event(event) + self.poly_points = [] def hide(self): - """ Hide the turtle. """ if self.spr is not None: self.spr.hide() if self.label_block is not None: @@ -257,7 +383,6 @@ class Turtle: self.hidden = True def show(self): - """ Show the turtle. """ if self.spr is not None: self.spr.set_layer(TURTLE_LAYER) self.hidden = False @@ -266,8 +391,18 @@ class Turtle: if self.label_block is not None: self.label_block.spr.set_layer(TURTLE_LAYER + 1) + def move_turtle(self, pos=None): + if pos is None: + x, y = self.tw.canvas.get_xy() + else: + x, y = self.tw.canvas.turtle_to_screen_coordinates(pos[0], pos[1]) + if self.tw.interactive_mode: + self.move((self.tw.canvas.cx + x - self.spr.rect.width / 2., + self.tw.canvas.cy + y - self.spr.rect.height / 2.)) + else: + self.move((self.tw.canvas.cx + x, self.tw.canvas.cy + y)) + def move(self, pos): - """ Move the turtle. """ self.x, self.y = pos[0], pos[1] if not self.hidden and self.spr is not None: self.spr.move((int(pos[0]), int(pos[1]))) @@ -277,33 +412,183 @@ class Turtle: return(self.x, self.y) def get_name(self): - ''' return turtle name (key) ''' return self.name def get_xy(self): - """ Return the turtle's x, y coordinates. """ return(self.x, self.y) def get_heading(self): - """ Return the turtle's heading. """ return(self.heading) def get_color(self): - """ Return the turtle's color. """ return(self.pen_color) def get_gray(self): - """ Return the turtle's gray level. """ return(self.pen_gray) def get_shade(self): - """ Return the turtle's shade. """ return(self.pen_shade) def get_pen_size(self): - """ Return the turtle's pen size. """ return(self.pen_size) def get_pen_state(self): - """ Return the turtle's pen state. """ return(self.pen_state) + + def get_fill(self): + return(self.pen_fill) + + def get_poly_points(self): + return(self.poly_points) + + 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.tw.running_sugar) + return + self.heading %= 360 + + if self.tw.sharing() and share: + event = 'r|%s' % (data_to_string([self.tw.nick, + round_int(self.heading)])) + self.tw.send_event(event) + + def forward(self, distance, share=True): + scaled_distance = distance * self.tw.coord_scale + + self.tw.canvas.set_rgb(self.tw.canvas.fgrgb[0] / 255., + self.tw.canvas.fgrgb[1] / 255., + self.tw.canvas.fgrgb[2] / 255.) + + oldx, oldy = self.tw.canvas.get_xy() + try: + xcor = oldx + scaled_distance * sin(self.heading * DEGTOR) + ycor = oldy + scaled_distance * cos(self.heading * DEGTOR) + except (TypeError, ValueError): + debug_output('bad value sent to %s' % (__name__), + self.tw.running_sugar) + return + + self.tw.canvas.set_xy(xcor, ycor) + if self.pen_state: + self.tw.canvas.draw_line(oldx, oldy, xcor, ycor) + if self.pen_fill: + if self.poly_points == []: + x, y = self.tw.canvas.turtle_to_screen_coordinates(oldx, oldy) + self.poly_points.append(('move', x, y)) + x, y = self.tw.canvas.turtle_to_screen_coordinates(xcor, ycor) + self.poly_points.append(('line', x, y)) + + self.move_turtle((xcor, ycor)) + + if self.tw.sharing() and share: + event = 'f|%s' % (data_to_string([self.tw.nick, + int(distance)])) + self.tw.send_event(event) + + def set_xy(self, x, y, share=True, pendown=True): + oldx, oldy = self.tw.canvas.get_xy() + try: + xcor = x * self.tw.coord_scale + ycor = y * self.tw.coord_scale + self.tw.canvas.set_xy(x, y) + except (TypeError, ValueError): + debug_output('bad value sent to %s' % (__name__), + self.tw.running_sugar) + return + + if self.pen_state and pendown: + self.tw.canvas.set_rgb(self.tw.canvas.fgrgb[0] / 255., + self.tw.canvas.fgrgb[1] / 255., + self.tw.canvas.fgrgb[2] / 255.) + self.tw.canvas.draw_line(oldx, oldy, xcor, ycor) + if self.pen_fill: + if self.poly_points == []: + x, y = self.tw.canvas.turtle_to_screen_coordinates(oldx, oldy) + self.poly_points.append(('move', x, y)) + x, y = self.tw.canvas.turtle_to_screen_coordinates(xcor, ycor) + self.poly_points.append(('line', x, y)) + + self.move_turtle((xcor, ycor)) + + if self.tw.sharing() and share: + event = 'x|%s' % (data_to_string([self.tw.nick, + [round_int(x), round_int(y)]])) + self.tw.send_event(event) + + def arc(self, a, r, share=True): + ''' Draw an arc ''' + if self.pen_state: + self.tw.canvas.set_rgb(self.tw.canvas.fgrgb[0] / 255., + self.tw.canvas.fgrgb[1] / 255., + self.tw.canvas.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 + + xcor, ycor = self.tw.canvas.get_xy() + self.move_turtle((xcor, ycor)) + + if self.tw.sharing() and share: + event = 'a|%s' % (data_to_string([self.tw.nick, + [round_int(a), round_int(r)]])) + self.tw.send_event(event) + + def rarc(self, a, r): + ''' draw a clockwise arc ''' + r *= self.tw.coord_scale + if r < 0: + r = -r + a = -a + xcor, ycor = self.tw.canvas.get_xy() + cx = xcor + r * cos(self.heading * DEGTOR) + cy = ycor - r * sin(self.heading * DEGTOR) + if self.pen_state: + x, y = self.tw.canvas.turtle_to_screen_coordinates(cx, cy) + self.tw.canvas.rarc(x, y, r, a, self.heading) + + if self.pen_fill: + x, y = self.tw.canvas.turtle_to_screen_coordinates(x, y) + if self.poly_points == []: + self.poly_points.append(('move', x, y)) + self.poly_points.append(('rarc', x, y, r, + (self.heading - 180) * DEGTOR, + (self.heading - 180 + a) * DEGTOR)) + + self.right(a, False) + self.tw.canvas.set_xy(cx - r * cos(self.heading * DEGTOR), + cy + r * sin(self.heading * DEGTOR)) + + def larc(self, a, r): + ''' draw a counter-clockwise arc ''' + r *= self.tw.coord_scale + if r < 0: + r = -r + a = -a + xcor, ycor = self.tw.canvas.get_xy() + cx = xcor - r * cos(self.heading * DEGTOR) + cy = ycor + r * sin(self.heading * DEGTOR) + if self.pen_state: + x, y = self.tw.canvas.turtle_to_screen_coordinates(cx, cy) + self.tw.canvas.larc(x, y, r, a, self.heading) + + if self.pen_fill: + x, y = self.tw.canvas.turtle_to_screen_coordinates(x, y) + if self.poly_points == []: + self.poly_points.append(('move', x, y)) + self.poly_points.append(('larc', x, y, r, + (self.heading) * DEGTOR, + (self.heading - a) * DEGTOR)) + + self.right(-a, False) + self.tw.canvas.set_xy(cx + r * cos(self.heading * DEGTOR), + cy - r * sin(self.heading * DEGTOR)) diff --git a/TurtleArt/tawindow.py b/TurtleArt/tawindow.py index 731260f..79a8db2 100644 --- a/TurtleArt/tawindow.py +++ b/TurtleArt/tawindow.py @@ -266,9 +266,10 @@ class TurtleArtWindow(): else: self.default_turtle_name = self.nick if mycolors is None: - Turtle(self.turtles, self.default_turtle_name) + Turtle(self, self.turtles, self.default_turtle_name) else: - Turtle(self.turtles, self.default_turtle_name, mycolors.split(',')) + Turtle(self, self.turtles, self.default_turtle_name, + mycolors.split(',')) self.active_turtle = self.turtles.get_turtle(self.default_turtle_name) self.active_turtle.show() @@ -743,7 +744,7 @@ class TurtleArtWindow(): self.metric = False self.canvas.width = self.width self.canvas.height = self.height - self.canvas.move_turtle() + self.active_turtle.move_turtle() def hideshow_button(self): ''' Hide/show button ''' @@ -1716,7 +1717,7 @@ before making changes to your Turtle Blocks program')) if self.remote_turtle(t.get_name()): return True self.selected_turtle = t - self.canvas.set_turtle(self.turtles.get_turtle_key(t)) + self.set_turtle(self.turtles.get_turtle_key(t)) self._turtle_pressed(x, y) self.update_counter = 0 return True @@ -2458,7 +2459,7 @@ before making changes to your Turtle Blocks program')) self.send_event("r|%s" % (data_to_string([nick, round_int(self.canvas.heading)]))) - if self.canvas.pendown: + if self.canvas.pen_down: self.send_event('p|%s' % (data_to_string([nick, False]))) put_pen_back_down = True else: @@ -2495,7 +2496,7 @@ before making changes to your Turtle Blocks program')) if self.selected_turtle is not None: dtype, dragx, dragy = self.drag_turtle (sx, sy) = self.selected_turtle.get_xy() - # self.canvas.set_turtle(self.selected_turtle.get_name()) + # self.set_turtle(self.selected_turtle.get_name()) self.update_counter += 1 if dtype == 'move': dx = x - dragx - sx + self.selected_turtle.spr.rect.width / 2 @@ -2503,12 +2504,12 @@ before making changes to your Turtle Blocks program')) self.selected_turtle.spr.set_layer(TOP_LAYER) tx, ty = self.canvas.screen_to_turtle_coordinates(sx + dx, sy + dy) - if self.canvas.pendown: - self.canvas.setpen(False) - self.canvas.setxy(tx, ty, share=False) - self.canvas.setpen(True) + if self.active_turtle.get_pen_state(): + self.active_turtle.set_pen_state(False) + self.active_turtle.set_xy(tx, ty, share=False) + self.active_turtle.set_pen_state(True) else: - self.canvas.setxy(tx, ty, share=False) + self.active_turtle.set_xy(tx, ty, share=False) if self.update_counter % 5: self.lc.update_label_value( 'xcor', self.canvas.xcor / self.coord_scale) @@ -2700,7 +2701,7 @@ before making changes to your Turtle Blocks program')) self.active_turtle.spr.rect.height / 2.) self.selected_turtle = None if self.active_turtle is None: - self.canvas.set_turtle(self.default_turtle_name) + self.set_turtle(self.default_turtle_name) self.display_coordinates() return @@ -2782,7 +2783,7 @@ before making changes to your Turtle Blocks program')) ''' Move the selected turtle to (x, y). ''' self.canvas.xcor = x self.canvas.ycor = y - self.canvas.move_turtle() + self.active_turtle.move_turtle() if self.interactive_mode: self.display_coordinates() if self.running_sugar: @@ -3551,7 +3552,7 @@ before making changes to your Turtle Blocks program')) self.canvas.xcor += dx self.canvas.ycor += dy self.active_turtle = self.turtles.spr_to_turtle(self.selected_spr) - self.canvas.move_turtle() + self.active_turtle.move_turtle() self.display_coordinates() self.selected_turtle = None @@ -3844,12 +3845,13 @@ before making changes to your Turtle Blocks program')) def load_turtle(self, blk, key=1): ''' Restore a turtle from its saved state ''' tid, name, xcor, ycor, heading, color, shade, pensize = blk - self.canvas.set_turtle(key) - self.canvas.setxy(xcor, ycor, pendown=False) - self.canvas.seth(heading) - self.canvas.setcolor(color) - self.canvas.setshade(shade) - self.canvas.setpensize(pensize) + self.set_turtle(key) + self.active_turtle.setxy(xcor, ycor, pendown=False) + self.active_turtle.set_heading(heading) + self.active_turtle.set_color(color) + self.active_turtle.set_shade(shade) + self.active_turtle.set_gray(100) + self.active_turtle.set_pen_size(pensize) def load_block(self, b, offset=0): ''' Restore individual blocks from saved state ''' @@ -4657,3 +4659,50 @@ variable')) (b1x, b1y) = block1.spr.get_xy() (b2x, b2y) = block2.spr.get_xy() return ((b1x + d1x) - (b2x + d2x), (b1y + d1y) - (b2y + d2y)) + + def reset_turtles(self): + for turtle_key in iter(self.turtles.dict): + # Don't reset remote turtles + if not self.remote_turtle(turtle_key): + self.set_turtle(turtle_key) + self.active_turtle.set_color(0) + self.active_turtle.set_shade(50) + self.active_turtle.set_gray(100) + self.active_turtle.set_pen_size(5) + self.active_turtle.reset_shapes() + self.active_turtle.set_heading(0.0) + self.active_turtle.set_pen_state(False) + self.active_turtle.move((0.0, 0.0)) + self.active_turtle.set_pen_state(True) + self.active_turtle.set_fill(False) + self.active_turtle.hide() + self.set_turtle(self.default_turtle_name) + + def set_turtle(self, key, colors=None): + ''' Select the current turtle and associated pen status ''' + if key not in self.turtles.dict: + # if it is a new turtle, start it in the center of the screen + self.active_turtle = self.turtles.get_turtle(k, True, colors) + self.active_turtle.set_heading(0.0, False) + self.active_turtle.set_xy(0.0, 0.0, False, pendown=False) + self.active_turtle.set_pen_state(True) + elif colors is not None: + self.active_turtle = self.turtles.get_turtle(key, False) + self.active_turtle.set_turtle_colors(colors) + else: + self.active_turtle = self.turtles.get_turtle(key, False) + self.active_turtle.show() + tx, ty = self.active_turtle.get_xy() + x, y = self.canvas.screen_to_turtle_coordinates(tx, ty) + self.canvas.set_xy(x, y) + if self.interactive_mode: + x, y = self.canvas.get_xy() + debug_output('%f %f' % (x, y), self.running_sugar) + self.canvas.set_xy(x + self.active_turtle.spr.rect.width / 2., + y - self.active_turtle.spr.rect.height / 2.) + self.heading = self.active_turtle.get_heading() + self.active_turtle.set_color(share=False) + self.active_turtle.set_gray(share=False) + self.active_turtle.set_shade(share=False) + self.active_turtle.set_pen_size(share=False) + self.active_turtle.set_pen_state(share=False) |