Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWalter Bender <walter@sugarlabs.org>2013-06-23 23:49:17 (GMT)
committer Walter Bender <walter@sugarlabs.org>2013-06-23 23:49:17 (GMT)
commit9486dd411e22ffdf900dd5b51b72f4a8d3631f0f (patch)
tree1c13aca47629827549fcbba8e026f742274456ae
parent4fededf1be849b0026f8d864a1d4fa071597e01e (diff)
turtle-centric
-rw-r--r--TurtleArt/tabasics.py113
-rw-r--r--TurtleArt/tacanvas.py432
-rw-r--r--TurtleArt/taturtle.py339
-rw-r--r--TurtleArt/tawindow.py89
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)